2025泰迪杯数据挖掘挑战赛B题技术解析:从数据预处理到模型优化的全流程实战

1次阅读
没有评论

共计 2777 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

赛题背景与数据特点分析

2025 泰迪杯数据挖掘挑战赛 B 题聚焦于一个典型的商业预测问题,要求参赛者基于历史销售数据、用户行为日志和外部环境因素,预测未来某段时间内的产品销量。数据集呈现以下显著特点:

2025 泰迪杯数据挖掘挑战赛 B 题技术解析:从数据预处理到模型优化的全流程实战

  1. 多源异构数据 :包含结构化交易记录(CSV)、非结构化的用户评论(JSON)以及天气等外部 API 数据
  2. 时空双重维度 :数据同时具有时间序列特性(日粒度)和空间维度(区域门店分布)
  3. 严重类别不平衡 :爆款商品与长尾商品的销量差异达 3 个数量级
  4. 数据质量问题突出 :约 15% 的字段存在缺失,部分传感器数据存在明显异常波动

技术选型对比

针对上述特点,我们对关键技术方案进行了对比评估:

  • 缺失值处理
  • 简单删除法(适用于缺失率 <5% 的非关键字段)
  • 多重插补(MICE)VS 均值 / 中位数填充(后者计算效率更高)
  • 最终选择基于随机森林的缺失值预测(对非线性关系建模更准确)

  • 特征工程

  • 传统统计特征(移动平均、同比环比)VS 深度学习自动特征提取(后者需要足够数据量支撑)
  • 最终采用混合策略:人工构造业务特征 + AutoFE 工具辅助

  • 建模算法

  • XGBoost:更适合处理结构化特征
  • LightGBM:训练速度更快,内存占用更低
  • 最终选择 LightGBM 作为基线模型,配合 CatBoost 处理类别型变量

核心实现细节

数据清洗流程

  1. 缺失值处理

    # 使用随机森林预测缺失的单价字段
    from sklearn.ensemble import RandomForestRegressor
    
    def impute_missing_values(df, target_col):
        # 分割完整数据与缺失数据
        known = df[df[target_col].notnull()]
        unknown = df[df[target_col].isnull()]
    
        # 准备特征(排除目标列和其他高缺失率列)features = [col for col in df.columns 
                   if col not in [target_col, 'high_missing_column']]
    
        # 训练预测模型
        rf = RandomForestRegressor(n_estimators=100, random_state=42)
        rf.fit(known[features], known[target_col])
    
        # 预测并填补缺失值
        predicted = rf.predict(unknown[features])
        df.loc[df[target_col].isnull(), target_col] = predicted
        return df

  2. 异常值检测

  3. 使用 IQR 方法识别数值型异常
  4. 对文本数据采用规则过滤(如评论长度 >500 字符视为垃圾内容)

特征工程方法

  1. 时序特征构造
  2. 滑动窗口统计量(7 天 /30 天均值)
  3. 日期特性(星期几、是否节假日)
  4. 季节分解(STL)得到的趋势 / 周期分量

  5. 文本特征提取

    # 使用 TF-IDF 提取评论关键词
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    tfidf = TfidfVectorizer(max_features=100, stop_words='english')
    comment_features = tfidf.fit_transform(df['user_comments'])
    df = pd.concat([df, pd.DataFrame(comment_features.toarray())], axis=1)

  6. 交叉特征生成

  7. 商品类别 × 促销标志
  8. 天气情况 × 门店位置

模型构建

采用分层抽样解决类别不平衡问题,LightGBM 关键参数配置:

params = {
    'boosting_type': 'gbdt',
    'objective': 'regression',
    'metric': 'rmse',
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.9,
    'bagging_fraction': 0.8,
    'bagging_freq': 5,
    'verbose': 0,
    'min_data_in_leaf': 20  # 防止过拟合
}

性能优化

  1. 特征选择
  2. 通过 SHAP 值评估特征重要性
  3. 递归特征消除(RFE)保留 Top50% 特征

  4. 超参数调优

    # 使用 Optuna 进行贝叶斯优化
    import optuna
    
    def objective(trial):
        params = {'num_leaves': trial.suggest_int('num_leaves', 20, 60),
            'max_depth': trial.suggest_int('max_depth', 3, 12),
            'min_child_samples': trial.suggest_int('min_child_samples', 10, 50),
            'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.1)
        }
    
        model = LGBMRegressor(**params)
        scores = cross_val_score(model, X, y, cv=5, scoring='neg_mean_squared_error')
        return np.mean(scores)
    
    study = optuna.create_study(direction='maximize')
    study.optimize(objective, n_trials=100)

避坑指南

  1. 时间泄漏问题
  2. 严禁使用未来数据(如用 2 月的统计量预测 1 月销量)
  3. 建议采用时间序列交叉验证(TimeSeriesSplit)

  4. 评估指标误解

  5. 比赛使用 RMSLE 而非 RMSE,需对预测值做 log1p 变换
  6. 自定义评估函数示例:

    def rmsle(y_true, y_pred):
        y_pred = np.clip(y_pred, 0, None)  # 确保非负
        return np.sqrt(np.mean(np.power(np.log1p(y_true) - np.log1p(y_pred), 2)))

  7. 内存优化

  8. 将 category 类型字段手动转换为 pandas 的 category 类型
  9. 对数值列使用 astype(np.float32) 降低精度

延伸思考

  1. 进阶方向
  2. 尝试时序深度学习模型(如 N -BEATS、TFT)
  3. 构建异构模型融合(RNN 处理时序 + GBDT 处理表格数据)

  4. 业务迁移

  5. 将比赛方案适配到零售行业的库存优化系统
  6. 考虑实时预测场景下的模型更新策略

结语

通过本次比赛实践,我们系统性地掌握了从原始数据到预测模型的完整 pipeline。特别值得注意的是,数据挖掘竞赛与实际业务场景的核心差异在于:比赛追求单一指标最大化,而业务场景更需要模型的稳定性和可解释性。建议读者在后续实践中,尝试将本文技术方案应用到自己的业务数据中,并持续关注模型在生产环境中的表现。

正文完
 0
评论(没有评论)