使用auto_arima(SARIMAX)结合傅里叶项做多季节性时间序列预测问题咨询
问题原因分析
- 傅里叶项阶数设置过低:你当前使用K=2生成年度季节性的傅里叶特征,仅能捕捉最粗粒度的年度波动,完全无法还原零售日度数据的年度季节性细节,建议将K调整到5~10的常用区间。
- auto_arima默认参数限制了周度季节性的捕捉:你虽然设置了
seasonal=True, m=7来匹配周度周期,但pmdarima默认对季节性AR/MA项的罚分权重较高,很大概率拟合出的模型季节性项阶数为0,相当于完全没有用到周度季节性特征,需要手动放宽季节性项的搜索范围。 - 时序频率设置不完整:你仅给外生变量exog设置了日度频率,训练集的目标序列没有显式指定
freq='D',部分场景下pmdarima会识别不到时序的周期属性,导致季节性拟合失效。 - 预测索引冗余操作:你手动指定预测结果的日期索引,和predict方法自动返回的索引本质一致,冗余操作反而可能出现日期错位问题。
修正后代码
import pandas as pd from pmdarima.preprocessing import FourierFeaturizer from pmdarima import auto_arima import matplotlib.pyplot as plt # 读取数据 train_data = pd.read_csv('train.csv', index_col='date', parse_dates=True) # 筛选门店1、商品1的序列,显式设置日度频率 train_data = train_data.query('store == 1 and item == 1').sales.asfreq('D') # 生成年度季节性傅里叶特征,K调整为7 four_terms = FourierFeaturizer(365.25, 7) y_prime, exog = four_terms.fit_transform(train_data) exog = exog.asfreq('D') # 拆分训练测试集 split_point = len(y_prime) - 365 y_to_train = y_prime.iloc[:split_point] y_to_test = y_prime.iloc[split_point:] exog_to_train = exog.iloc[:split_point] exog_to_test = exog.iloc[split_point:] # 拟合模型,放宽季节性项搜索范围 arima_exog_model = auto_arima( y=y_to_train, exogenous=exog_to_train, seasonal=True, m=7, start_P=1, start_Q=1, max_P=2, max_Q=2, suppress_warnings=True, trace=True ) # 预测 y_arima_exog_forecast = arima_exog_model.predict(n_periods=365, exogenous=exog_to_test) # 绘图 plt.plot(y_to_test, label='Actual data') plt.plot(y_arima_exog_forecast, label='Forecast') plt.legend() plt.show()
效果说明
调整后模型会同时捕捉到周度的周期性波动和年度的销售高低峰变化,不会再出现预测结果过于平滑的问题,你也可以根据实际拟合效果调整傅里叶项的K值,K值越大能捕捉的季节性波动越细,但也要注意过拟合风险。
内容的提问来源于stack exchange,提问作者Downforu
相关产品推荐
相关产品推荐

