使用SARIMA模型预测乘客数时遇迭代次数超限错误的解决方法
SARIMA模型迭代次数超限及相关错误的解决方法
错误原因分析
出现STOP: TOTAL NO. of ITERATIONS REACHED LIMIT和This problem is unconstrained错误,核心原因包括:
- 手动差分后重复设置SARIMA的
d参数,导致过度差分,数据平稳性过强,模型优化器难以找到最优解 - 参数设置不符合数据规律(如月度数据的季节周期设为6而非12、
p=5参数过大) - 模型拟合时未调整优化器参数,默认迭代次数不足以支持收敛
- 评估逻辑错误:用未来预测值匹配历史数据,完全不对应
具体解决步骤
1. 修正数据处理逻辑,避免过度差分
SARIMAX模型会自动根据d参数处理差分,无需手动提前做差分。针对AirPassengers这类带指数增长趋势的数据,建议先做对数转换消除趋势:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.statespace.sarimax import SARIMAX from sklearn.metrics import mean_absolute_error, mean_squared_error # 数据加载与预处理 df = pd.read_csv("AirPassengers.csv") df.index = pd.to_datetime(df['Month']) df = df.drop('Month', axis=1) # 对数转换消除指数趋势(可选但推荐) df['#Passengers_log'] = np.log(df['#Passengers'])
2. 调整SARIMA参数,贴合数据规律
月度航空乘客数据的季节周期S应为12(对应年周期),同时从简单参数组合开始尝试,避免参数过拟合:
# 初始参数设置(经典组合) p, d, q = 1, 1, 1 P, D, Q, S = 1, 1, 1, 12
3. 优化模型拟合参数,提升收敛性
在fit()方法中增加迭代次数,或更换优化器,解决迭代次数超限问题:
# 拟合模型时调整优化参数 model = SARIMAX(df['#Passengers_log'], order=(p, d, q), seasonal_order=(P, D, Q, S)) # 增加迭代次数,或使用powell优化器(适配非凸优化场景) results = model.fit(maxiter=500, method='powell')
4. 修正模型评估逻辑,匹配真实测试场景
划分训练集和测试集,用训练集拟合模型,预测测试集数据后计算误差:
# 划分训练集(前132个月)和测试集(最后12个月) train = df['#Passengers_log'].iloc[:-12] test = df['#Passengers_log'].iloc[-12:] # 重新拟合模型 model = SARIMAX(train, order=(p, d, q), seasonal_order=(P, D, Q, S)) results = model.fit(maxiter=500) # 预测测试集的12步数据 forecast_log = results.get_forecast(steps=12, alpha=0.2) forecast_mean_log = forecast_log.predicted_mean # 反转对数转换得到真实乘客数 forecast_mean = np.exp(forecast_mean_log) actual_values = np.exp(test) # 计算评估指标 mae = mean_absolute_error(actual_values, forecast_mean) mse = mean_squared_error(actual_values, forecast_mean) rmse = np.sqrt(mse) print(f'MAE: {mae:.2f}') print(f'MSE: {mse:.2f}') print(f'RMSE: {rmse:.2f}')
5. 修正绘图逻辑,正确展示预测结果
# 绘图 plt.figure(figsize=(12, 6)) plt.plot(df.index, df['#Passengers'], label='Observed', color='blue') # 生成预测值的时间索引 forecast_index = pd.date_range(start=df.index[-1], periods=13, freq='M')[1:] plt.plot(forecast_index, forecast_mean, label='Forecast', color='red') # 处理置信区间并反转对数转换 confidence_intervals_log = forecast_log.conf_int() confidence_intervals = np.exp(confidence_intervals_log) plt.fill_between(forecast_index, confidence_intervals.iloc[:, 0], confidence_intervals.iloc[:, 1], color='pink', label='80% Confidence Interval') plt.xlabel('Date') plt.ylabel('Passengers') plt.title('SARIMA Forecast') plt.legend() plt.grid(True) plt.show()
额外建议
- 如果仍出现收敛问题,可尝试降低参数复杂度(如
p=0、q=0),逐步增加参数 - 使用自动调参工具减少手动试错成本:
from pmdarima import auto_arima stepwise_fit = auto_arima(df['#Passengers_log'], seasonal=True, m=12, trace=True) print(stepwise_fit.summary())
内容的提问来源于stack exchange,提问作者Emine Nida Zenginoğlu
相关产品推荐
相关产品推荐

