Statsmodels ARIMA气体时序预测精度提升方法咨询
Statsmodels ARIMA气体监测值预测优化方案
现有数据集结构
| Date | T | RH | Gas | Value |
|---|---|---|---|---|
| 6/2/2017 | 6.62 | 51.73 | CO | 845.23 |
| 6/2/2017 | 6.62 | 51.73 | HC | 626.34 |
现有实现代码
#Initialising ARIMA model from statsmodels.tsa.arima_model import ARIMA arima_model = ARIMA(scaled_df.Value, order=(2,0,1)).fit() arima_model.summary() start = len(df) end = len(df) + len(test) -1 test['Date'] = pd.to_datetime(test['Date'],format='%d/%m/%Y') test.set_index('Date', inplace=True) pred = arima_model.predict(start=start, end=end,typ='levels')
当前问题表现
预测结果输出为直线,无波动,精度达不到预期:
核心问题原因
- 未按
Gas字段拆分不同气体的时序,将CO、HC等监测基线、变化规律完全不同的序列混为单个序列训练,模型无法学到有效时序规律 - 手动固定
order=(2,0,1)参数未做寻优,参数和数据的自相关特征不匹配时,ARIMA长期预测会快速收敛到序列均值,呈现直线效果 - 预测索引计算逻辑错误:建模使用
scaled_df序列,预测索引用原始df的长度计算,两个数据集长度不一致时会出现索引错位,输出无效预测 - 未利用数据集中已有的温度
T、相对湿度RH特征,气体监测值和温湿度强相关,纯单变量ARIMA遗漏关键解释变量,预测精度上限低 - 调用的
statsmodels.tsa.arima_model.ARIMA是已弃用的旧版接口,存在版本兼容导致的预测异常问题
分步优化方案
- 数据拆分对齐
- 按
Gas字段分组,每类气体单独构建时序、单独训练模型,不要混合不同气体的监测值 - 对单类气体的数据按时间升序排序,设置时间索引,按固定比例拆分训练/测试集,保证索引连续无断层
- 按
- 参数自动寻优
- 已通过ADF检验确认序列平稳,差分阶数d固定为0,对p、q参数在0~3范围内做网格搜索,以AIC值最小为标准选最优参数组合,不要手动固定阶数
- 若监测值存在固定周期波动,换用SARIMA模型添加季节项参数,普通ARIMA无法捕捉周期规律时也会输出平线预测
- 引入外生变量提效
- 换用支持外生变量的ARIMA/SARIMAX接口,将
T、RH作为外生变量传入模型,预测时同步传入测试集对应的温湿度数据,可大幅提升预测精度
- 换用支持外生变量的ARIMA/SARIMAX接口,将
- 修正预测逻辑
- 预测起止索引严格和训练时输入的序列长度对齐,不要跨DataFrame计算长度
- 替换旧版弃用的ARIMA接口为新版
statsmodels.tsa.arima.model.ARIMA,避免兼容问题
修正后参考代码
import pandas as pd from statsmodels.tsa.arima.model import ARIMA from itertools import product import warnings warnings.filterwarnings("ignore") # 统一解析时间格式 df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y') gas_pred_result = {} # 按气体类型循环分组建模 for gas_name, sub_df in df.groupby('Gas'): # 按时间排序设置索引 sub_df = sub_df.sort_values('Date').set_index('Date') # 8:2拆分训练测试集 train_len = int(len(sub_df) * 0.8) train_set = sub_df.iloc[:train_len] test_set = sub_df.iloc[train_len:] # 网格搜索最优(p,d,q)参数 min_aic = float('inf') optimal_order = (0,0,0) for p, q in product(range(0, 4), range(0, 4)): try: temp_model = ARIMA( endog=train_set['Value'], exog=train_set[['T', 'RH']], order=(p, 0, q) ).fit() if temp_model.aic < min_aic: min_aic = temp_model.aic optimal_order = (p, 0, q) except: continue # 最优参数训练最终模型 final_model = ARIMA( endog=train_set['Value'], exog=train_set[['T', 'RH']], order=optimal_order ).fit() # 生成预测结果 pred_res = final_model.predict( start=train_len, end=len(sub_df)-1, exog=test_set[['T', 'RH']] ) gas_pred_result[gas_name] = { "model": final_model, "best_order": optimal_order, "true_value": test_set['Value'], "pred_value": pred_res }
补充说明:如果完成以上调整后预测仍然无法捕捉波动,说明气体监测值的非线性特征较强,ARIMA的线性假设适配性差,可以替换为Prophet、时序集成树类模型做进一步优化。
内容的提问来源于stack exchange,提问作者Dylariant
相关产品推荐
相关产品推荐

