如何在fbprophet交叉验证中指定k折数量?
FBProphet交叉验证折数控制方法
自动折数的生成逻辑
FBProphet的cross_validation不采用传统k折划分逻辑,而是通过三个核心参数控制验证窗口的生成:
initial:首次训练使用的初始数据时长period:每次滚动训练时,训练集向前推进的步长horizon:单轮预测的覆盖时长
自动生成的折数计算公式为:折数 = (总数据时间跨度 - initial时长 - horizon时长) // period时长 + 1
你看到的71折,就是根据你的数据时间范围和设置的initial='200 days'、period='180 days'、horizon='30 days'计算得出的。
如何间接控制折数
FBProphet不支持直接指定k折数,需要通过调整period参数间接实现:
- 先计算数据的总时间跨度(从数据集第一个时间戳到最后一个的天数)
- 根据目标折数反推
period值:period = (总时长 - initial时长 - horizon时长) // (目标折数 - 1) - 将计算出的
period传入cross_validation
示例代码:
import pandas as pd from prophet import Prophet from prophet.diagnostics import cross_validation, performance_metrics # 假设df是包含ds(时间列)和y(目标列)的时间序列数据 m = Prophet() m.fit(df) # 计算总数据时长(单位:天) total_days = (df['ds'].max() - df['ds'].min()).days initial_days = 200 horizon_days = 30 target_folds = 5 # 反推period值 period_days = (total_days - initial_days - horizon_days) // (target_folds - 1) period_str = f'{period_days} days' # 执行交叉验证 df_cv = cross_validation(m, initial=f'{initial_days} days', period=period_str, horizon=f'{horizon_days} days') pm = performance_metrics(df_cv)
手动实现固定k折交叉验证
如果需要更灵活的k折划分(比如不按滚动步长,直接拆分时间窗口),可以手动拆分数据集,循环完成训练和预测:
import numpy as np k = 5 # 计算每个验证段的时长 fold_duration = (total_days - initial_days) // k cv_results = [] for i in range(k): # 确定当前训练集结束时间与验证集时间范围 train_end = df['ds'].min() + pd.Timedelta(days=initial_days + i * fold_duration) val_start = train_end val_end = train_end + pd.Timedelta(days=horizon_days) # 拆分训练集与验证集 train_df = df[df['ds'] <= train_end] val_df = df[(df['ds'] > val_start) & (df['ds'] <= val_end)] # 训练模型并生成预测 m = Prophet() m.fit(train_df) future = m.make_future_dataframe(periods=horizon_days) forecast = m.predict(future) # 合并预测结果与真实值 val_forecast = forecast[(forecast['ds'] > val_start) & (forecast['ds'] <= val_end)] val_forecast['y'] = val_df['y'].values cv_results.append(val_forecast) # 合并所有交叉验证结果 df_cv = pd.concat(cv_results) pm = performance_metrics(df_cv)
内容的提问来源于stack exchange,提问作者sharp
相关产品推荐
相关产品推荐

