news 2026/4/18 12:47:12

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到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'], axis=1) return df

2.2 行为特征聚合

用户日志中包含四种行为类型:

  • 0:点击
  • 1:加购
  • 2:购买
  • 3:收藏

我设计了三级聚合策略:

  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(axis=1) 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_iter=1000), 'Decision Tree': DecisionTreeClassifier(max_depth=5), 'Random Forest': RandomForestClassifier(n_estimators=100) } 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.6332

3.2 逻辑回归的逆袭

虽然随机森林表现最好,但考虑到比赛后期的模型融合需求,我决定优化逻辑回归作为基础学习器。关键改进点:

  1. 特征标准化:对连续型特征进行RobustScaler处理
  2. 类别特征编码:对年龄分段等有序变量采用Target Encoding
  3. 正则化调优:通过网格搜索确定最佳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(C=0.3, solver='saga')) ]) # 五折交叉验证 cv_scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='roc_auc') print(f"平均AUC: {np.mean(cv_scores):.4f} (±{np.std(cv_scores):.4f})")

优化后的逻辑回归AUC提升至0.6287,且训练速度比随机森林快20倍。

4. 比赛技巧与经验总结

4.1 有效特征筛选

通过特征重要性分析,我发现三个被低估但实际有效的特征:

  1. 行为集中度:用户在该商家行为占其总行为的比例

    df['merchant_action_ratio'] = df['total_actions'] / df.groupby('user_id')['total_actions'].transform('sum')
  2. 时间衰减权重:越接近双十一的行为权重越高

    df['weighted_actions'] = df['clicks']*(1 + 0.1*df['time_stamp'])
  3. 跨商家对比:用户在该商家的行为次数与平均值的比值

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参数的时间,或许更应该花在深入理解业务逻辑上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 12:45:15

BilldDesk Pro:如何用开源方案实现企业级跨平台远程控制

BilldDesk Pro:如何用开源方案实现企业级跨平台远程控制 【免费下载链接】billd-desk 基于Vue3 WebRTC Nodejs Flutter搭建的远程桌面控制、游戏串流 项目地址: https://gitcode.com/gh_mirrors/bi/billd-desk 在当今数字化工作环境中,远程控制…

作者头像 李华
网站建设 2026/4/18 12:42:31

Hermes Agent + RAG知识库:5分钟搭建AI智能问答系统(教程)

前言:为什么你的AI总在"胡说八道"? 你有没有遇到过这种情况: “问AI我们公司年假有几天,它瞎编一个答案” “问AI产品退换货流程,它说的和官网完全不一样” 这不是AI的错,是AI不知道你的企业内…

作者头像 李华
网站建设 2026/4/18 12:42:02

STM32实战 | 基于移远EC200N-CN模组的物联网数据透传系统开发

1. 硬件连接与模块初始化 第一次拿到EC200N-CN模组时,看着密密麻麻的引脚确实有点懵。不过别担心,我花了三天时间实测,总结出最实用的接线方案。这个4G Cat.1模组需要连接的主要是电源、串口和SIM卡三部分。 电源部分要特别注意,模…

作者头像 李华
网站建设 2026/4/18 12:42:01

如何快速掌握Redux DevTools:终极调试指南

如何快速掌握Redux DevTools:终极调试指南 【免费下载链接】redux-devtools DevTools for Redux with hot reloading, action replay, and customizable UI 项目地址: https://gitcode.com/gh_mirrors/re/redux-devtools Redux DevTools是一套功能强大的Redu…

作者头像 李华