从零到Top 12%:我是如何用Python和基础模型搞定天池复购预测的(附完整代码)

张开发
2026/4/18 12:47:17 15 分钟阅读

分享文章

从零到Top 12%:我是如何用Python和基础模型搞定天池复购预测的(附完整代码)
从零到Top 12%我是如何用Python和基础模型搞定天池复购预测的附完整代码第一次参加天池大赛时面对5600多支队伍的激烈竞争我作为一个仅有Python基础的数据科学爱好者内心充满忐忑。但最终仅用逻辑回归和决策树这类基础模型我意外斩获前12%的排名。这篇文章将完整还原我的实战路径——从数据清洗的每个细节到特征工程的思考逻辑再到模型调优的踩坑记录。不同于复杂算法的堆砌这里只有可复现的代码和经过验证的有效策略。1. 赛题理解与数据初探复购预测本质上是一个二分类问题给定用户在双十一期间的新客行为数据预测其未来半年内是否会再次购买。评估指标采用AUC值这意味着模型需要准确排序用户的复购概率而非简单判断是与否。数据集包含四个关键文件train_format1.csv训练集用户ID与商家ID对应关系及标签user_info_format1.csv用户性别、年龄等静态信息user_log_format1.csv用户6个月内的详细行为日志test_format1.csv测试集数据初次加载数据时我发现了几个关键问题import pandas as pd user_log pd.read_csv(data_format1/user_log_format1.csv) print(f行为记录缺失比例{user_log.isnull().sum().sum()/len(user_log):.2%}) print(f时间跨度{user_log[time_stamp].nunique()}个离散时间点)输出显示约15%的行为记录存在缺失且时间戳被离散化为1-31的整数。这直接影响了后续的特征设计策略。提示天猫数据中的time_stamp字段并非真实日期而是经过脱敏的序列编号这要求我们放弃常规的时间序列分析方法。2. 特征工程实战从原始数据到模型输入2.1 用户基础特征构建面对用户信息表中的年龄和性别字段我采用了分层填充策略def process_user_info(df): # 性别处理-1→未知0→女1→男 df[gender] df[gender].replace(-1, np.nan) # 年龄分段将7和8合并为≥50岁 df[age_range] df[age_range].replace({7:8, -1:np.nan}) # 基于商家维度的众数填充 merchant_gender df.groupby(merchant_id)[gender].agg(lambda x: x.mode()[0]) df[gender] df.apply(lambda row: merchant_gender[row[merchant_id]] if pd.isna(row[gender]) else row[gender], axis1) return df2.2 行为特征聚合用户日志中包含四种行为类型0点击1加购2购买3收藏我设计了三级聚合策略用户-商家维度统计基础行为次数计算行为占比等衍生指标加入时间维度上的行为变化趋势def create_action_features(user_log): # 基础行为计数 action_counts user_log.groupby([user_id,seller_id,action_type])[item_id].count().unstack() action_counts.columns [clicks,add_to_cart,purchases,favorites] # 行为占比特征 action_counts[total_actions] action_counts.sum(axis1) for col in [clicks,add_to_cart,purchases,favorites]: action_counts[f{col}_ratio] action_counts[col]/action_counts[total_actions] return action_counts.reset_index()2.3 关键特征清单最终生成的核心特征包括特征类别示例特征生成方式用户属性年龄分段、性别原始数据清洗行为统计点击次数、加购率分组聚合计算时间模式最后行为间隔时间戳差分交叉特征品类偏好指数联合用户与商品类目3. 模型构建与优化3.1 基础模型对比我首先在相同特征集上测试了三种基础模型的表现from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier models { Logistic Regression: LogisticRegression(max_iter1000), Decision Tree: DecisionTreeClassifier(max_depth5), Random Forest: RandomForestClassifier(n_estimators100) } for name, model in models.items(): model.fit(X_train, y_train) pred model.predict_proba(X_val)[:,1] score roc_auc_score(y_val, pred) print(f{name} AUC: {score:.4f})初步结果显示逻辑回归0.6213决策树0.5987随机森林0.63323.2 逻辑回归的逆袭虽然随机森林表现最好但考虑到比赛后期的模型融合需求我决定优化逻辑回归作为基础学习器。关键改进点特征标准化对连续型特征进行RobustScaler处理类别特征编码对年龄分段等有序变量采用Target Encoding正则化调优通过网格搜索确定最佳L2惩罚系数from sklearn.preprocessing import RobustScaler from sklearn.compose import ColumnTransformer numeric_features [clicks,purchases_ratio,last_action_interval] categorical_features [age_range,gender] preprocessor ColumnTransformer( transformers[ (num, RobustScaler(), numeric_features), (cat, TargetEncoder(), categorical_features) ]) pipeline Pipeline([ (preprocessor, preprocessor), (classifier, LogisticRegression(C0.3, solversaga)) ]) # 五折交叉验证 cv_scores cross_val_score(pipeline, X_train, y_train, cv5, scoringroc_auc) print(f平均AUC: {np.mean(cv_scores):.4f} (±{np.std(cv_scores):.4f}))优化后的逻辑回归AUC提升至0.6287且训练速度比随机森林快20倍。4. 比赛技巧与经验总结4.1 有效特征筛选通过特征重要性分析我发现三个被低估但实际有效的特征行为集中度用户在该商家行为占其总行为的比例df[merchant_action_ratio] df[total_actions] / df.groupby(user_id)[total_actions].transform(sum)时间衰减权重越接近双十一的行为权重越高df[weighted_actions] df[clicks]*(1 0.1*df[time_stamp])跨商家对比用户在该商家的行为次数与平均值的比值4.2 避免过拟合的策略采用时间序列验证按时间划分训练/验证集限制决策树深度设置max_depth≤5早停机制监控验证集AUC不再提升时终止训练4.3 完整代码结构项目最终的文件组织如下/repo │── data/ # 原始数据 │── features/ # 特征工程输出 │── notebooks/ │ ├── 01_eda.ipynb # 数据探索 │ ├── 02_features.ipynb # 特征工程 │ └── 03_model.ipynb # 模型训练 │── utils/ # 工具函数 │── requirements.txt # 依赖库 │── submit.py # 生成提交文件在最终提交的版本中我融合了逻辑回归和随机森林的预测结果采用简单的加权平均lr_pred lr_model.predict_proba(test_features)[:,1] rf_pred rf_model.predict_proba(test_features)[:,1] final_pred 0.6*lr_pred 0.4*rf_pred这个看似简单的组合策略让我的成绩从Top 20%提升到了Top 12%。参赛过程中最大的体会是在数据竞赛中精心设计的特征往往比复杂的模型更能带来突破。现在回看那些熬夜调试XGBoost参数的时间或许更应该花在深入理解业务逻辑上。

更多文章