我尝试使用ARIMA模型(用Python)进行预测。P, D, Q, p, d, q的值是通过ADF测试、plot_acf、plot_pacf确定的,如果需要可以分享这些值。
代码如下所示。
import pandas as pdfrom statsmodels.tsa.arima_model import ARIMAimport statsmodels.api as smdf = pd.read_csv(r'https://github.com/sreerajva5/ML/raw/master/sample_data_ts.csv')df['Date'] = pd.to_datetime(df['Date'])df.set_index('Date', inplace=True)model = sm.tsa.statespace.SARIMAX(df['sample_data'], order=(0,1,0), seasonal_order=(1,1,12,30))result = model.fit()future_dt = pd.Series(pd.date_range('2012-06-01', periods=60, freq='D'))future_dt_df = pd.DataFrame(index=future_dt, columns=df.columns)future_df = pd.concat([df, future_dt_df])future_df['forecast'] = result.predict()
我创建了模型并尝试预测接下来的60天(两个月)的数据。但是,只有第一个月和第二个月的前5天的值被预测出来,中间的值没有被预测出来。
得到的结果如下所示。
"2012-06-01 453.8150562012-06-02 298.56047672012-06-03 270.52698542012-06-04 203.4027022012-06-05 123.2703868没有从2012-06-06到2012-06-30的预测值(为空白) 2012-07-01 475.51370622012-07-02 257.92731242012-07-03 272.85641572012-07-04 218.33057992012-07-05 123.9411595再次没有从2012-07-06到2012-07-30的预测值(为空白)"
这是什么原因导致的?我怎样才能得到正确的预测?
回答:
fit: fit方法使用训练/给定数据来估计参数,以使误差最小化。
predict: 一旦模型参数被估计出来,该方法可以用来对训练数据进行预测,也可以对未见过的数据进行预测。使用predict方法而不指定开始和结束日期参数,将对训练数据进行预测。让我们测试一下
assert len(result.predict()) == len(df)ax = df.plot(figsize=(15,5))result.predict().plot(ax=ax, label="predicted")plt.legend()
输出:
您可以通过指定开始和结束索引来对样本外/未见过的数据进行预测。我们将通过使用(0,len(future_df)-1)
作为开始和结束索引来对完整数据集进行预测。
future_dt = pd.Series(pd.date_range('2012-06-01', periods=60, freq='D'))future_dt_df = pd.DataFrame(index=future_dt, columns=df.columns)future_df = pd.concat([df, future_dt_df])future_df['forecast'] = result.predict(0,len(future_df)-1).values# 让我们绘制它ax = future_df['sample_data'][len(df)-10:].plot(figsize=(15,5))future_df['forecast'][len(df)-10:].plot(ax=ax, label="predicted")plt.legend()
forecast: 这种方法只是predict方法的简化版本,可以用来对样本外/未见过的/未来数据进行预测,而不需要开始和结束值。让我们对接下来的60天进行预测
future_dt = pd.Series(pd.date_range('2012-06-01', periods=60, freq='D'))future_dt = pd.DataFrame(index=future_dt)future_dt['forecast'] = result.forecast(60).valuesax = future_df['sample_data'][len(df)-10:].plot(figsize=(15,5))future_dt['forecast'].plot(figsize=(15,5))plt.legend()