如何用statsmodels的Holt-Winters实现时间序列拟合与未来预测
搞定Holt-Winters未来时间序列预测问题
嘿,咱们来解决你用Holt-Winters预测2015-2017年数据的问题!看了你的现有代码,我发现几个小细节阻碍了你生成未来区间的预测,咱们一步步调整:
现有代码的核心问题
- 你把
train和test都赋值成了整个数据集(虽然你说已经完成拟合验证,但这里明显是笔误) - 你用
model.predict(start=period[0], end=period[1])只是在回测历史区间的数据,并没有指向未来的日期范围
修改后的完整代码
import pandas as pd from statsmodels.tsa.holtwinters import ExponentialSmoothing import matplotlib.pyplot as plt # 1. 数据加载与预处理 data = pd.read_csv('setpoints.csv', parse_dates=['date'], index_col=['date']) # 修正你代码里的`datos_matric`笔误,应该是data['Data'] df_data = pd.DataFrame(data['Data'], columns=['Data']) # 明确设置月度起始频率(MS),这对时间序列模型很重要 df_data.index.freq = 'MS' # 2. 用全部历史数据拟合Holt-Winters模型 model = ExponentialSmoothing( df_data['Data'], trend='add', # 加法趋势,你可以根据拟合效果换成'mul' seasonal='add', # 加法季节性,同理可调整为'mul' seasonal_periods=12 # 月度数据,周期为12个月 ).fit() # 3. 生成2015年1月至2017年12月的预测(共36个月) # 方法1:用forecast指定预测期数,简单直接 future_forecast = model.forecast(steps=36) # 方法2:用predict指定具体起止日期,更灵活(和方法1结果一致) # future_start = pd.to_datetime('2015-01-01') # future_end = pd.to_datetime('2017-12-01') # future_forecast = model.predict(start=future_start, end=future_end) # 4. 可视化历史数据与预测结果 plt.figure(figsize=(12, 6)) df_data['Data'].plot(label='历史数据(2012-2014)') future_forecast.plot(label='Holt-Winters预测(2015-2017)', color='#ff4444') plt.title('时间序列历史数据与未来预测') plt.xlabel('日期') plt.ylabel('数值') plt.legend(loc='upper left') plt.grid(axis='y', linestyle='--') plt.show() # 可选:把预测结果保存为CSV文件 future_df = pd.DataFrame(future_forecast, columns=['预测数据']) future_df.to_csv('holt_winters_future_forecast.csv')
关键知识点解释
forecast(steps=36):因为要预测3年共36个月,指定steps=36后,statsmodels会自动沿用你设置的MS频率,生成连续的未来日期索引,不用手动写日期。- 如果你更习惯明确指定日期范围,用
predict()方法搭配具体的datetime起止点也完全可以,注意日期格式要和你的数据索引一致(必须是datetime类型)。 - 关于模型参数:你选了加法趋势和加法季节性,这适合波动幅度不随数值大小变化的数据;如果你的季节性波动随数值增大而变大,建议换成乘法模型(
trend='mul'、seasonal='mul'),可以根据历史拟合的残差或可视化效果调整。
另外提一句:如果之前做拟合验证时拆分了训练集和测试集,记得先只用训练集训练模型、用测试集验证效果,确认模型靠谱后,再用全部历史数据重新训练模型做未来预测,这样预测结果会更准确哦~
内容的提问来源于stack exchange,提问作者srgam
相关产品推荐
相关产品推荐

