含日期列的数据集训练测试集划分方法(LightGBM场景)
时间序列数据拆分方案(避免未来数据泄露)
核心问题说明
你当前使用的train_test_split是随机拆分逻辑,会打乱时间顺序,导致训练集混入未来数据,这属于时间序列预测中的严重数据泄露,会让模型评估结果完全失真。必须严格按照时间顺序拆分,保证训练集的所有数据都早于测试集。
优先方案:滚动时间窗口拆分(2个月训练+1周测试)
这种拆分方式完全贴合真实业务的预测场景:用历史数据训练模型,预测近期未来,滚动迭代优化。
步骤1:数据预处理
首先要将日期列转为datetime类型,并按时间排序,这是时间拆分的基础:
import pandas as pd import lightgbm as lgb # 转换日期格式并按时间排序 df['date'] = pd.to_datetime(df['date']) df = df.sort_values(by='date').reset_index(drop=True) # 处理类别特征(LightGBM支持直接识别category类型) df['device'] = df['device'].astype('category') df['AM/PM'] = df['AM/PM'].astype('category')
步骤2:实现滚动拆分与模型训练
循环生成训练/测试窗口,每次用过去2个月的数据训练,预测接下来的1周:
# 获取数据集的时间边界 min_date = df['date'].min() max_date = df['date'].max() current_train_start = min_date while True: # 定义训练窗口:起始日期往后推2个月 current_train_end = current_train_start + pd.DateOffset(months=2) # 定义测试窗口:训练结束次日起的7天 current_test_start = current_train_end + pd.DateOffset(days=1) current_test_end = current_test_start + pd.DateOffset(days=6) # 当测试窗口超出数据集范围时停止循环 if current_test_end > max_date: break # 拆分训练/测试集 train_df = df[(df['date'] >= current_train_start) & (df['date'] <= current_train_end)] test_df = df[(df['date'] >= current_test_start) & (df['date'] <= current_test_end)] # 分离特征与目标变量(可根据需求保留date并提取时间特征,比如星期、月份等) X_train = train_df.drop(columns=['imp', 'date']) y_train = train_df['imp'] X_test = test_df.drop(columns=['imp', 'date']) y_test = test_df['imp'] # 构建LightGBM数据集 lgb_train = lgb.Dataset(X_train, y_train, categorical_feature=['device', 'AM/PM']) lgb_test = lgb.Dataset(X_test, y_test, reference=lgb_train) # 模型参数(针对回归任务调整,可根据实际需求修改) params = { 'objective': 'regression', 'metric': 'rmse', 'boosting_type': 'gbdt', 'seed': 42 } # 训练模型,启用早停避免过拟合 model = lgb.train( params, lgb_train, num_boost_round=100, valid_sets=[lgb_test], early_stopping_rounds=10 ) # 可在此记录模型性能、保存模型或生成预测结果 # ... # 滚动训练窗口起始点到测试窗口起始点,进入下一轮迭代 current_train_start = current_test_start
备选方案:时间比例拆分(8:2)
如果滚动拆分逻辑过于复杂,可直接按时间顺序取前80%数据为训练集,后20%为测试集:
# 按时间顺序划分8:2训练测试集 train_size = int(0.8 * len(df)) train_df = df.iloc[:train_size] test_df = df.iloc[train_size:] # 分离特征与目标变量 X_train = train_df.drop(columns=['imp', 'date']) y_train = train_df['imp'] X_test = test_df.drop(columns=['imp', 'date']) y_test = test_df['imp'] # 训练LightGBM模型(参数与滚动拆分一致) lgb_train = lgb.Dataset(X_train, y_train, categorical_feature=['device', 'AM/PM']) lgb_test = lgb.Dataset(X_test, y_test, reference=lgb_train) model = lgb.train( params, lgb_train, num_boost_round=100, valid_sets=[lgb_test], early_stopping_rounds=10 )
关键注意事项
- 时间特征工程:可从date列提取星期几、月份、是否工作日等特征,加入到输入特征中,能显著提升模型预测能力。
- 类别特征处理:确保所有类别特征转为
category类型,LightGBM会自动优化这类特征的处理逻辑。 - 避免隐性泄露:任何特征工程步骤(比如归一化、统计特征计算)都只能用训练集的数据,绝对不能用到测试集数据,否则会引入隐性数据泄露。
内容的提问来源于stack exchange,提问作者sam_sam
相关产品推荐
相关产品推荐

