如何通过Python的statsmodels.tsa.x13获取季节成分预测及d10、d11?
解决X13-ARIMA-SEATS季节成分与调整序列预测提取问题
一、从statsmodels x13_arima_analysis中提取预测的d10和d11
statsmodels的x13_arima_analysis默认确实不会直接返回季节成分(d10)和季节调整序列(d11)的预测值,但可以通过以下两种方式获取:
1. 利用X13输出文件手动提取
在调用x13_arima_analysis时,指定save_spec=True和out_dir参数,让X13将所有输出文件保存到指定目录:
from statsmodels.tsa.x13 import x13_arima_analysis import pandas as pd import os # 假设你的输入时间序列为ts result = x13_arima_analysis( endog=ts, forecast_period=60, save_spec=True, out_dir="./x13_output" # 指定输出目录 )
X13会在该目录下生成多个输出文件,其中:
{prefix}_d10fore.est:包含季节成分(d10)的预测值{prefix}_d11fore.est:包含季节调整序列(d11)的预测值
你可以用pandas读取这些文件:
# 获取自动生成的前缀(可从result.spec.name获取) prefix = result.spec.name # 读取d10预测 d10_forecast = pd.read_csv( os.path.join("./x13_output", f"{prefix}_d10fore.est"), delim_whitespace=True, parse_dates=[0], index_col=0 ) # 读取d11预测 d11_forecast = pd.read_csv( os.path.join("./x13_output", f"{prefix}_d11fore.est"), delim_whitespace=True, parse_dates=[0], index_col=0 )
2. 修改statsmodels源码自动返回预测值
如果你已经修改过x13.py,可以在x13_arima_analysis函数末尾添加代码,自动读取预测文件并添加到结果对象中:
# 在x13_arima_analysis函数的return语句前添加 import os import pandas as pd prefix = spec.name out_dir = out_dir or tempfile.mkdtemp() # 读取d10预测 d10_forecast_path = os.path.join(out_dir, f"{prefix}_d10fore.est") if os.path.exists(d10_forecast_path): d10_forecast = pd.read_csv( d10_forecast_path, delim_whitespace=True, parse_dates=[0], index_col=0 ) result.d10_forecast = d10_forecast # 读取d11预测 d11_forecast_path = os.path.join(out_dir, f"{prefix}_d11fore.est") if os.path.exists(d11_forecast_path): d11_forecast = pd.read_csv( d11_forecast_path, delim_whitespace=True, parse_dates=[0], index_col=0 ) result.d11_forecast = d11_forecast
之后调用x13_arima_analysis时,结果对象就会直接带有d10_forecast和d11_forecast属性。
二、其他获取带预测的季节成分与调整序列的方法
如果不想依赖X13,还可以尝试以下几种方案:
1. STL分解 + ARIMA预测季节成分
先用STL分解提取历史季节成分,再对季节成分拟合ARIMA模型进行预测,同时对趋势+残差部分建模得到季节调整序列的预测:
from statsmodels.tsa.seasonal import STL from statsmodels.tsa.arima.model import ARIMA # STL分解 stl = STL(ts, period=12) # 假设季节周期为12 result_stl = stl.fit() # 预测季节成分 seasonal_arima = ARIMA(result_stl.seasonal, order=(1,0,1), seasonal_order=(1,0,1,12)) seasonal_forecast = seasonal_arima.fit().get_forecast(steps=60).predicted_mean # 预测趋势+残差(即季节调整序列) trend_resid = result_stl.trend + result_stl.resid trend_resid_arima = ARIMA(trend_resid, order=(1,1,1)) trend_resid_forecast = trend_resid_arima.fit().get_forecast(steps=60).predicted_mean
2. 使用Prophet自动获取季节成分与调整序列
Prophet内置了季节分解功能,并且可以直接输出预测的季节成分和调整后序列:
from prophet import Prophet import pandas as pd # 转换为Prophet要求的格式 df = pd.DataFrame({"ds": ts.index, "y": ts.values}) # 拟合模型 model = Prophet(seasonality_mode="multiplicative") # 或加法模式"additive" model.fit(df) # 生成未来60期的预测 future = model.make_future_dataframe(periods=60) forecast = model.predict(future) # 提取季节成分(seasonal列)和季节调整序列(yhat - seasonal) seasonal_forecast = forecast[["ds", "seasonal"]].set_index("ds") seasonal_adjusted_forecast = forecast[["ds", "yhat"]].assign(seasonal_adjusted=lambda x: x.yhat - x.seasonal).set_index("ds")
3. SARIMA模型手动分解季节成分
SARIMA模型包含季节项,可以通过模型的预测值分解出季节成分(需要结合模型的季节参数计算,相对复杂),适合对建模细节有要求的场景。
内容的提问来源于stack exchange,提问作者MarTom




