天池实战——从用户行为日志到复购预测模型

张开发
2026/6/23 13:56:29 15 分钟阅读
天池实战——从用户行为日志到复购预测模型
1. 赛题理解与数据准备第一次接触天池大赛的复购预测题目时我盯着20万条用户行为数据发了半小时呆。这就像给你一仓库的零件却要组装出一台能预测未来的机器。但别慌我们先拆解问题本质通过用户双十一期间的行为日志预测他们未来半年是否会复购。这本质上是个二分类问题核心在于如何从杂乱的行为数据中提炼出有价值的特征。原始数据包含四个关键文件train_format1.csv训练集用户ID、商家ID和标签是否复购test_format1.csv测试集用户ID和商家IDuser_info_format1.csv用户性别、年龄等静态信息user_log_format1.csv用户行为日志点击、加购、购买等我建议先用这个代码快速查看数据全貌import pandas as pd train pd.read_csv(data_format1/train_format1.csv) print(f训练集形状{train.shape}\n列名{train.columns}) user_log pd.read_csv(data_format1/user_log_format1.csv) print(f行为日志示例\n{user_log.head(3)})2. 数据清洗实战技巧真实数据永远比教程里的脏得多。用户日志里藏着各种坑时间戳混乱有的记录是1111有的是20171111行为类型异常出现action_type4这种未定义值缺失值陷阱user_info里70%的年龄字段是-1我的清洗三板斧时间标准化把1111转换成20161111格式user_log[time_stamp] user_log[time_stamp].apply( lambda x: f2016{x} if len(str(x))4 else str(x))异常值过滤删除不在0-3范围内的action_typevalid_actions [0,1,2,3] user_log user_log[user_log[action_type].isin(valid_actions)]缺失值策略对年龄采用众数填充性别单独处理mode_age user_info[age_range].mode()[0] user_info[age_range] user_info[age_range].replace(-1, mode_age)3. 特征工程深度解析特征工程是模型效果的胜负手。我通过反复实验总结出这几类黄金特征3.1 基础统计特征行为频次用户对商家的总点击、加购次数时间分布用户在不同日期的活跃度click_count user_log.groupby([user_id,seller_id])[action_type]\ .apply(lambda x: (x0).sum()).reset_index()3.2 转化率特征计算点击到购买的转化率这类漏斗指标def get_conversion(df): clicks (df[action_type]0).sum() buys (df[action_type]2).sum() return buys/(clicks1e-6) # 避免除零 conversion user_log.groupby([user_id,seller_id]).apply(get_conversion)3.3 时间序列特征用滑动窗口统计近期行为变化趋势# 按周统计行为变化 user_log[week] pd.to_datetime(user_log[time_stamp]).dt.week weekly_act user_log.groupby([user_id,week])[action_type].count()4. 模型构建与调优经过多次尝试我发现XGBoost在这个问题上表现最好。关键配置如下4.1 基础模型搭建import xgboost as xgb params { max_depth: 5, learning_rate: 0.1, objective: binary:logistic, eval_metric: auc } dtrain xgb.DMatrix(X_train, labely_train) model xgb.train(params, dtrain, num_boost_round200)4.2 特征重要性分析通过这个可视化能发现哪些特征真正有用xgb.plot_importance(model) plt.show()4.3 超参数调优使用贝叶斯优化寻找最佳参数组合from bayes_opt import BayesianOptimization def xgb_eval(max_depth, gamma, min_child_weight): params { max_depth: int(max_depth), gamma: gamma, min_child_weight: min_child_weight } cv_result xgb.cv(params, dtrain, nfold5, metricsauc) return cv_result[test-auc-mean].iloc[-1] optimizer BayesianOptimization( fxgb_eval, pbounds{max_depth: (3,10), gamma: (0,1), min_child_weight: (0,10)} ) optimizer.maximize()5. 避坑指南与经验分享在三次提交失败后我总结了这些血泪教训内存管理原始日志1.2GB处理前先采样10%开发user_log_sample user_log.sample(frac0.1, random_state42)线上线下一致性本地验证AUC很高但线上得分低通常是数据泄露导致。确保测试集数据时间晚于训练集特征稳定性用sklearn.feature_selection.VarianceThreshold剔除方差过小的特征模型融合最终我用XGBoostLightGBM的加权融合线上提升了0.015lgb_pred lgb_model.predict_proba(X_test)[:,1] xgb_pred xgb_model.predict_proba(X_test)[:,1] ensemble_pred 0.6*xgb_pred 0.4*lgb_pred这个项目让我深刻体会到在真实业务场景中对业务逻辑的理解往往比模型本身更重要。比如发现双十一当天加购但未购买的用户后续复购率比直接购买者高23%这个insight直接让模型效果提升了一个档次。

更多文章