您的位置:首页 > 其它

天池大赛-天猫重复购买用户预测

2019-04-18 22:47 651 查看

比赛项目介绍

当前电商会在双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)

五. 总结

本次项目实战中通过部分技巧提升了模型整体的预测精度,最终线上测试的成绩还不错。限于时间原因,后续仍有可改善的空间:

  1. 提取特征的进一步筛选,不断优化模型
  2. 缺失数据可用众数、中位数或均值进行替代,再训练模型对比

本文源码链接:https://github.com/cloudinwalk/tmall-repeat-buyer-prediction

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐