使用sktime ARIMA模型预测时出现无效频率报错及asfreq处理后值全为NaN的技术求助
解决sktime ARIMA预测时的频率错误问题
我之前也踩过这个坑!你遇到的ValueError: Invalid frequency本质是因为你的时间序列索引没有明确的规则频率,而sktime的ForecastingHorizon需要索引能转换为pd.PeriodIndex才能正确计算预测时间点与训练数据的时间差。
问题根源分析
- 你用的GitHub数据集,读取后索引是
DatetimeIndex,但pandas没有自动识别出它的月度频率(可以通过print(df.index.freq)验证,结果是None)。 - 你尝试用
.asfreq("M")时出错,是因为原数据的日期是每月1号(月初),而"M"是月末频率,两者日期不匹配,导致所有值变成NaN。 - sktime自带的
load_airline数据集,索引是天生带有'M'频率的PeriodIndex,所以不会触发这个错误。
两种可行的解决方案
方案1:设置匹配的DatetimeIndex频率
针对原数据的月初日期,我们用'MS'(月初)频率来对齐,这样不会产生NaN:
from sktime.forecasting.base import ForecastingHorizon from sktime.forecasting.model_selection import temporal_train_test_split from sktime.forecasting.arima import ARIMA import numpy as np, pandas as pd # 正确读取并设置匹配的频率 df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date']) df = df.set_index('date')['a10'] # 原数据日期是每月1号,用'MS'(月初)频率,完美匹配无NaN df = df.asfreq('MS') p, d, q = 3, 1, 2 y_train, y_test = temporal_train_test_split(df, test_size=24) model = ARIMA((p, d, q)) results = model.fit(y_train) # 现在创建ForecastingHorizon不再报错 fh = ForecastingHorizon(y_test.index, is_relative=False) y_pred_vals, y_pred_int = results.predict(fh, return_pred_int=True)
方案2:转换为PeriodIndex
直接把DatetimeIndex转成PeriodIndex,它天生带有明确的月度频率,不需要纠结日期是月初还是月末:
from sktime.forecasting.base import ForecastingHorizon from sktime.forecasting.model_selection import temporal_train_test_split from sktime.forecasting.arima import ARIMA import numpy as np, pandas as pd # 读取数据并转换为PeriodIndex df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date']) df = df.set_index('date')['a10'] # 转换为月度PeriodIndex df.index = df.index.to_period('M') p, d, q = 3, 1, 2 y_train, y_test = temporal_train_test_split(df, test_size=24) model = ARIMA((p, d, q)) results = model.fit(y_train) fh = ForecastingHorizon(y_test.index, is_relative=False) y_pred_vals, y_pred_int = results.predict(fh, return_pred_int=True)
验证方法
处理完数据后,可以用以下代码确认频率是否正确设置:
print(df.index.freq) # 方案1输出<MonthBegin>,方案2输出M
内容的提问来源于stack exchange,提问作者student
相关产品推荐
相关产品推荐

