使用skforecast回测时遇KeyError:索引不匹配问题求助
解决skforecast backtesting_forecaster索引不匹配的KeyError问题
问题重现
使用skforecast的backtesting_forecaster做时序回测时,触发如下KeyError:
KeyError: "None of [Int64Index([24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n ...\n 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],\n dtype='int64', length=720)] are in the [index]"
即使传入符合要求的pandas Series(而非数组),错误仍然存在。
核心代码片段
回测代码
metric, predictions = backtesting_forecaster( forecaster = forecaster, y = data['Count of Visits'], steps = 24, metric = 'mean_absolute_error', initial_train_size = len(data.loc[:end_validation]), refit = False, verbose = True, show_progress = True )
数据划分与模型初始化
# 数据划分 data = data.loc['2023-02-01 00:00:00': '2023-06-30 23:00:00'].copy() end_train = '30-04-2023 23:59' end_validation = '31-05-2023 23:59' # 模型初始化与训练 from skforecast.ForecasterAutoreg import ForecasterAutoreg from sklearn.linear_model import Ridge forecaster = ForecasterAutoreg( regressor = Ridge(random_state=123), lags = 24, transformer_y = StandardScaler() ) forecaster.fit(y=data.loc[:end_validation, 'Count of Visits'])
原因分析
报错根源是索引类型不匹配:
- 传入
backtesting_forecaster的y采用时间戳索引 - 当
refit=False时,模型基于预训练参数滚动预测,生成的predictions使用整数位置索引(从训练集长度开始递增) - 函数内部计算指标时,用预测结果的整数索引去匹配
y的时间戳索引,因索引类型完全不匹配,触发KeyError。
解决方案
方法1:启用refit=True(推荐,若业务允许)
如果允许每次回测迭代重新拟合模型,将refit设为True。此时模型会在每个回测窗口重新训练,生成的预测结果会自动匹配原数据的时间索引:
metric, predictions = backtesting_forecaster( forecaster = forecaster, y = data['Count of Visits'], steps = 24, metric = 'mean_absolute_error', initial_train_size = len(data.loc[:end_validation]), refit = True, # 修改此处 verbose = True, show_progress = True )
方法2:手动对齐索引(必须refit=False时)
若不能重新拟合模型,需手动修正预测结果的索引后再计算指标:
# 先获取预测结果,关闭自动指标计算 _, predictions = backtesting_forecaster( forecaster = forecaster, y = data['Count of Visits'], steps = 24, metric = None, # 不自动计算指标 initial_train_size = len(data.loc[:end_validation]), refit = False, verbose = True, show_progress = True ) # 获取回测对应的真实值及其时间索引 true_values = data['Count of Visits'].iloc[len(data.loc[:end_validation]):] # 将预测结果的索引替换为真实值的时间索引 predictions.index = true_values.index # 手动计算指标 from sklearn.metrics import mean_absolute_error metric = mean_absolute_error(true_values, predictions['pred'])
方法3:确保时间索引连续(前置检查)
若时间序列存在缺失值,可能导致索引逻辑混乱,先验证并修复:
# 检查索引是否单调递增且唯一 print(data.index.is_monotonic_increasing) print(data.index.is_unique) # 生成连续时间索引并重新对齐数据(假设是小时级频率) full_index = pd.date_range(start=data.index.min(), end=data.index.max(), freq='H') data = data.reindex(full_index)
内容的提问来源于stack exchange,提问作者TMK
相关产品推荐
相关产品推荐

