天池大赛-天猫重复购买用户预测
比赛项目介绍
当前电商会在双11、黑五或boxing day等进行大量促销活动来吸引买家,但很多被吸引的买家都是一次性交易,这些促销对长期销售的影响就大打折扣。为了便于商家识别哪些用户可以成为重复购买的忠实买家,从而降低促销成本,提高投资回报率(ROI),天猫提供了双11及过去6个月内用户的日志信息来预测未来6个月内用户是否会在同一商铺中重复购买。本次预测任务类似于在线广告的CTR预测,极具挑战性。
一. 项目分析
天猫官方提供了用户信息(年龄段、性别),用户日志包括用户名称、商铺名称、商品名称、商品种类、商品品牌、交互时间以及用户行为方式(点击、加购、收藏或购买)等信息。该项目是一个二分类任务,总体思路是:通过特征工程,根据官方提供的这些基础信息提取出有效特征形成训练数据集,再结合机器学习的建模融合,最终得到用户是否会重复购买的概率。
二. 数据预处理
对用户信息、用户日志进行加载,首先去除数据中的重复记录。然后去除数据中所有特征值全部缺失的记录。当然,我们发现仍存在基础信息数据少部分缺失的情况,我们先保存该用户记录的其他信息,后续会结合模型统一处理。
user_info = pd.read_csv('E:\\repeat buyer\\user_info_format1.csv', usecols=['user_id', 'age_range', 'gender']).drop_duplicates() user_info = user_info.dropna(axis=0,how='all') user_log = pd.read_csv('E:\\repeat buyer\\user_log_format1.csv', usecols=['user_id', 'item_id', 'cat_id', 'seller_id', 'brand_id', 'time_stamp', 'action_type']).rename(columns={'seller_id': 'merchant_id'}) user_log = user_log.dropna(axis=0,how='all') test = pd.read_csv('E:\\repeat buyer\\test_format1.csv', usecols=['user_id', 'merchant_id']) train = pd.read_csv('E:\\repeat buyer\\train_format1.csv', usecols=['user_id', 'merchant_id', 'label']) train = train.drop_duplicates(['user_id','merchant_id']) test = test.drop_duplicates(['user_id','merchant_id']) user_log = user_log.merge(user_info, on=['user_id'],how='left',copy=False)
为便于后续挖掘与时间相关的特征,我们在user_log中加入了month和day
user_log['month'] = user_log['time_stamp'] // 100 user_log['day'] = user_log['time_stamp'] % 100
三. 特征工程
以下通过用户、商铺、用户和商铺、比值和ID特征等多个维度完成特征数据的提取。
1. 用户特征
- 用户交互总次数
- 用户各种行为总次数统计(点击、加购、收藏和购买)
- 用户交互了多少商铺数
- 用户交互了多少种商品,多少商品类别和多少商品品牌数量
- 用户每天交互、购买的次数
- 用户每月交互、购买的次数
2. 商铺特征
- 商铺下所有交互总次数
- 商铺下各种行为总次数统计(点击、加购、收藏和购买)
- 商铺下交互的总用户数
- 商铺下有多少被交互的商品,商品类别和商品品牌数量
- 商铺每个月有多少用户交互
- 商铺下交互的用户按年龄段和性别分别统计
- 商铺在各个年龄段和性别组合的交互用户中交互的商品、商品类别和商品品牌总数
- 商铺在各个年龄段和性别组合的购买用户中购买的商品、商品类别和商品品牌总数
3. 用户-商铺特征
- 用户在某商铺中交互的次数
- 用户在某商铺中各种行为次数(点击、加购、收藏和购买)
- 用户在商铺中每月的交互次数
- 用户在商铺中每月的各种行为次数(点击、加购、收藏和购买)
- 用户在商铺中第一次和最后一次交互的时间差
- 用户在商铺中交互有几个月
- 用户在商铺中交互有多少天
- 用户在商铺中有交互的月份每个月交互次数的统计
- 用户在商铺中交互的商品、商品类别和商品品牌的总个数,以及与之交互总次数的均值、最值
4. 比值特征
在统计比值特征时,我们需要对比值进行平滑处理。这样可以避免不同用户由于统计次数有限导致较大的比例偏差。
- 用户交互次数在所有用户交互总次数的占比
- 用户购买次数在所有用户购买总次数的占比
- 商铺交互次数在所有商铺交互总次数的占比
- 商铺购买次数在所有商铺购买总次数的占比
- 商铺中购买的用户数在所有商铺购买用户数的占比
- 用户在某商铺的交互次数在该用户所有交互次数的占比
- 用户在某商铺的购买次数在该用户所有购买次数的占比
- 用户在某商铺的交互次数在该商铺所有交互次数中的占比
- 用户在某商铺的购买次数在该商铺所有购买次数中的占比
- 用户在商铺中各种行为次数在交互总次数中的占比
- 商铺中回购(购买次数>1)的用户数占总购买用户数的比例(用户回购率)
- 商铺中回购的总次数占用户总购买次数的比例
- 商铺中回购的商品类别总数在用户购买商品类别总数的占比
- 用户有回购的商铺数在该用户所有购买行为商铺数的占比
- 用户回购次数在该用户所有购买总次数的占比
- 用户每月购买的次数在当月总交互次数的占比
5. ID特征
用户、商铺、商品、商品类别以及商品品牌ID可以通过one-hot编码的方式形成稀疏向量加入数据特征训练,目的是进一步挖掘用户、商铺以及商品之间的关联和相似性。
四. 模型建立
鉴于训练数据中存在少量缺失的情况,为尽可能多的利用原始数据,建议采用树模型进行建模。本项目采用的是xgboost,catboost和lightgbm,不仅仅是由于他们可以直接处理缺失数据,更因为在多种预测项目中他们的出色表现。
本次项目中,计划以以上三种模型为基础,通过在不同训练集上训练多个子模型后进行融合后形成增强模型,从而得到最终预测结果
1. 训练/测试集的构造
将原始训练数据集按4:1的比例分出训练集和测试集,同时需要保证正负样本在训练集和测试集中比例一致。我们采用了StratifiedKFold函数,而没有用sklearn中的train_test_split。通过StratifiedKFold将数据进行5折交叉切分,即其中的任一一份作为测试集,这样就得到5个交叉训练集和测试集。
同时,我们对原始数据集统计发现正负样本的比例约为1:15.4,根据经验可以不对该数据集进行采样处理,可以直接进行训练。
2. 模型构建
根据得到的5个训练集和测试集,分别训练xgboost、catboost和lightgbm,通过参数调整优化,一共得到15个子模型。
xgboost
xgb = XGBClassifier(n_estimators=n_xgb, max_depth=depth_xgb, learning_rate=lr_xgb, min_child_weight=child_weight, eval_metric='auc', reg_lambda=reg, random_state=10, n_jobs=-1) xgb.fit(trainX[i],trainY[i],eval_set=[(testX[i],testY[i])], early_stopping_rounds=num_stop,eval_metric='auc') print(xgb.evals_result_)
catboost
catboost是基于gbdt专门对categorial feature进行了优化的优秀模型,这次训练中存在user_id,merchant_id等类别特征有待训练,这也是我们选取该模型的原因之一
cat = CatBoostClassifier(learning_rate=lr_cat, iterations=n_cat, eval_metric='AUC', od_wait=num_stop, od_type='Iter', random_state=10, depth=depth_cat, thread_count=8, l2_leaf_reg=reg) cat.fit(trainX[i], trainY[i], eval_set=[(testX[i], testY[i])], early_stopping_rounds=num_stop, use_best_model=True,cat_features=cat_features) print(cat.evals_result_)
lightgbm
lgbm = LGBMClassifier(n_estimators=n_lgbm,objective='binary',num_leaves=31, max_depth=depth_lgbm,learning_rate=lr_lgbm, reg_lambda=reg,metric=['auc'], random_state=10,n_jobs=-1) lgbm.fit(trainX[i],trainY[i],eval_set=[(testX[i],testY[i])],early_stopping_rounds=num_stop, eval_metric='auc', categorical_feature=cat_features) print(lgbm.evals_result_)
3. 模型融合
在完成所有模型的训练后,利用测试数据集得到预测概率值,之后我们利用逻辑回归二分类中sigmoid反函数先取得返还值,再求平均。最后再用sigmoid函数求得概率值得到最终融合结果。
def sigmoid_ver(x): return np.log(x/(1-x)) def sigmoid(x): return 1/(1 + np.e**(-x))
pred_t = np.zeros(len(predict)) for i in range(5): pred_t += (sigmoid_ver(pred_lgbms[i]) + sigmoid_ver(pred_cats[i]) + sigmoid_ver(pred_xgbs[i])) result = sigmoid(pred_t/15)
五. 总结
本次项目实战中通过部分技巧提升了模型整体的预测精度,最终线上测试的成绩还不错。限于时间原因,后续仍有可改善的空间:
- 提取特征的进一步筛选,不断优化模型
- 缺失数据可用众数、中位数或均值进行替代,再训练模型对比
本文源码链接:https://github.com/cloudinwalk/tmall-repeat-buyer-prediction
- 京东算法大赛-高潜用户购买意向预测(一) 资料整理
- 京东算法大赛-高潜用户购买意向预测(二)策略迭代
- 京东JData算法大赛——高潜用户购买意向预测
- 用户人品预测大赛--getmax队--竞赛分享
- 关于弱网络情况下,如何防止用户重复购买一个商品
- 用户人品预测大赛获奖团队分享
- 天池_阿里音乐流行趋势预测大赛(1) —— 赛题分析
- 比赛三两事-天池工业AI大赛-智能制造质量预测-初赛
- 天池工业AI大赛-智能制造质量预测 比赛历程和技术方案总结复赛48名
- 天池精准医疗大赛-血糖预测
- 天池阿里音乐流行趋势预测大赛--初赛
- 根据用户行为推荐商品问题的建模方法(也可以用来预测用户购买行为)
- 用户人品预测大赛--不得直视本王--冠军分享
- 用户人品预测大赛--就是gan队--竞赛分享
- 【Python学习系列二十四】scikit-learn库逻辑回归实现唯品会用户购买行为预测
- 阿里音乐流行趋势预测大赛一起做-(7)初赛总结之用户分类
- 用户人品预测大赛--数据大匠队--竞赛分享
- [天池竞赛系列]阿里音乐流行趋势预测大赛初赛三等奖思路
- 阿里音乐流行趋势预测大赛一起做-(7)初赛总结之用户分类
- 逻辑回归(Logistic Regression, LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,我们可以将购买的概率设置为因变量,将用户的