ourownstory / neural_prophet

NeuralProphet: A simple forecasting package
https://neuralprophet.com
MIT License
3.81k stars 472 forks source link

[bug] If the changepoints are not sorted, then trend will be discontinuous even when growth='linear' #918

Closed qiwei-li closed 1 year ago

qiwei-li commented 1 year ago

Using version 0.4.2

image

Expectation: growth=linear means linear trend no matter if the changespoints are sorted.

Reproducible code:

import pandas as pd
import matplotlib.pyplot as plt
path='https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv'
dataset=pd.read_csv(path,engine='python')
dataset=dataset.groupby('Country/Region').sum()
dataset=dataset.drop(columns=['Lat','Long'])

tmp1 = pd.DataFrame(dataset.loc['France', :].values, columns=['y'])
tmp1.loc[:, 'ds'] = dataset.columns
tmp1.loc[:, "ID"] = 'France'
tmp2 = pd.DataFrame(dataset.loc['United Kingdom', :].values, columns=['y'])
tmp2.loc[:, 'ds'] = dataset.columns
tmp2.loc[:, "ID"] = 'United Kingdom'

data=pd.concat([tmp1, tmp2])
data.reset_index(inplace=True, drop=True)
data.loc[:, "ds"] = [pd.Timestamp(x) for x in data.ds]
data = data.loc[data.isnull().sum(1) == 0, :]

model = NeuralProphet(
    growth="linear", 
    changepoints = ["2022-11-01", "2022-04-01"],
    trend_reg = 0.1,
    seasonality_mode = "multiplicative",
    yearly_seasonality = False,
    weekly_seasonality = False,
    daily_seasonality = False,
    unknown_data_normalization = True
)
perf = model.fit(data, freq="D")
res = model.predict(data)

flag = res.ID == 'France'
plt.figure(figsize=(10,3))
plt.plot(res.loc[flag, 'ds'], res.loc[flag, 'y'], label='ytrue')
plt.plot(res.loc[flag, 'ds'], res.loc[flag, 'trend'], label='trend')
plt.legend()
ourownstory commented 1 year ago

Thank you @qiwei-li for bringing this to our attention! Seems like this could be resolved by sorting the changepoint list after receiving it.