天猫用户重复购买预测赛题——赛题理解 + 数据探索

理论知识

  • 双十一进行促销,商家希望知道那些用户可能会成为重复购买其店铺商品的忠诚用户,从而精准营销

  • 可以用复购率来衡量店铺的用户忠诚程度

    • 复购率 = 重复购买用户数/用户样本数量
    • 复购率= 重复购买行为次数/用户样本数量
    • 100用户 20复购行为 10复购1次 10复购2次 方法1:20/100 方法2:(10x1+10x2)/100
  • 影响复购率的因素

    • 用户维度
      • 性别、身高、体重、月收入、喜好
      • 女性客户 品牌偏好
    • 商品维度
      • 手机类
      • 母婴类
  • 缺失值处理

    • count() 统计不为空数据的个数

    • shape() 统计数据样本的个数

    • dropna() 根据各标签的值 是否缺失数据对轴标签过滤,可通过阈值调节

    • fillna() 用定值或者插值 填充缺失值

    • 对于数据缺失比较严重一般将其删除

      • 数据缺失过大 所蕴含信息较少
      • 缺失率过大的数据 可能导致用户在建模中产生偏差 难以追溯
  • 缺失值较少的情况下,处理方法

处理方法说明
统计量填充连续值:中位数 排除异常值造成的影响
离散型:众数
特殊值填充填不在正常取值范围的树 -999、0 等表示
不处理XGB和LGB对缺失值不敏感
  • 缺失值填充方法
插补方法说明优点缺点使用环境
类均值插补数值型:均值
非数值型:众数
简单易行,被插补的值比较稳定不能反映缺失值的变异缺失率低首选
类随机插补聚类填充 使用所有可能的值进行填充能体现数据的变异性依赖于观测值低缺失率
回归插补基于完整的数据集 建立回归模型方差好估计稳定性依赖于辅助变量 抽样误差不易控制变量间的相关性强
Em插补通过观测数据的边际分布对未知参数进行极大似然估计考虑了缺失值的不确定性计算复杂高缺失率
多重插补MCMC估计出待插补的值,然后加上不同的噪声,形成多组可选插补值考虑了缺失值的不确定性计算复杂高缺失率首选
  • 不均衡样本
    • 很多真实场景中存在长尾效应,也就是二八原理一个事物20%的特性决定了事物80%的重要性
    • 如:在市场营销中即指"企业80%的业务来自20%的顾客"
    • 很多场景是假设数据基于多元的正态分布,但是在分类任务中,不同类别的训练样例数目常出现差异较大情况
    • 样本不均衡会造成模型对样本数较多的类别过拟合、对较少的类别欠拟合
    • 举例说明
      • 实际为负 预测为负 9700 预测为正150
      • 实际为正 预测为负 50 预测为正150
      • 准确率 (9700+150)/(9700+150+50+150) = 0.98
      • 如果全部预测为负
      • 实际为负 预测为负 9850 预测为正
      • 实际为正 预测为负 150 预测为正
      • 准确率 0.985 反而增加了 对不平衡样本过拟合了 所以 AUC作为评分
  • 解决不平衡样本的方法
    • 随机欠采样
      • 正50例 负950例 负样本中随机选10% 新训练集95+50
      • 平衡数据的同时减少了数据量,加速了训练
      • 数据减少影响模型的特征学习能力和泛化能力
    • 随机过采样
      • 正50例 负950例 正样本复制10次 新训练集500+950
      • 相对于欠采样 没有导致数据信息的损失
      • 对较少类别的复制 增加了过拟合的可能性
    • 基于聚类的过采样方法
      • 依据聚类中心进行过采样/欠采样 使原始类中每个集群样本数目相同
    • SMOTE算法
      • Synthetic Minority Oversampling Technique 合成少数类过采样技术
      • 随机复制少数样本 缺少泛化能力
      • SMOTE对少数样本进行人工合成
      • 参考 网址1 网址2 网址3
      • 步骤:
        • 对于少数类中每一个样本x,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其k近邻
        • 根据样本不平衡比例设置一个采样比例以确定采样倍率N,对于每一个少数类样本x,从其k近邻中随机选择若干个样本,假设选择的近邻为o
        • 对于每一个随机选出的近邻o,分别与原样本按照公式**o(new)=o+rand(0,1)*(x-o)**构建新的样本。
      • 会增大类别间的重叠
    • 基于数据清洗的SMOTE
      • 去掉一些重叠样本 Tomek Links
      • 对于一对样本( x i , x j x_i,x_j xi,xj) x i x_i xi来自minority classes x j x_j xj来自majority classes 。如果离 x i x_i xi最近的少量样本是 x j x_j xj,对 x j x_j xj来说是 x i x_i xi,称这一对是Tomek Link,移去所有Tomek Link 样本重叠减小 利于分类
  • 常见数据分布
    • 伯努利分布
      • 只有两种可能 1成功 0失败
      • P ( X = x ) = { 1 − p , x = 0 p , x = 1 P(X = x)= \begin{cases}1-p,x=0\\p ,x=1\end{cases} P(X=x)={1p,x=0p,x=1
    • 二项分布
      • n个独立的是/非中成功次数的离散概率分布
      • P ( X = x ) = n ! ( n − x ) ! x ! p x q n − x P(X=x) = {n!\over (n-x)!x!}p^xq^{n-x} P(X=x)=(nx)!x!n!pxqnx
    • 柏松分布
      • 任何一个成功的事件都不应该影响另一个成功的事件
      • 短时间内成功率等于在更长时间内成功的概率
      • P ( X = x ) = e − u u x x ! P(X=x)=e^{-u} {u^x \over x!} P(X=x)=eux!ux
    • 正态分布
      • f ( x ) = 1 2 π σ e − ( x − u ) 2 2 σ 2 f(x) = {1\over \sqrt{2\pi\sigma}}e^{-{(x-u)^2 \over 2\sigma^2}} f(x)=2πσ 1e2σ2(xu)2
    • 指数分布
      • f ( x ) = { λ e − λ x , x > 0 0 , x < = 0 f(x)= \begin{cases}\lambda e^{-\lambda x},x>0\\0 ,x<=0\end{cases} f(x)={λeλx,x>00,x<=0

1. 赛题信息

  • 用户行为表 user_info

    DataFieldsDefinition
    user_id用户ID
    item_id商品ID
    cat_id商品类别ID
    seller_id商家ID
    brand_id品牌ID
    time_tamp时间戳
    action_type取值范围{0,1,2,3}
    0:点击 1:加购物车 2:购买 3:收藏
  • 用户特征表 user_log

    DataFieldsDefinition
    user_id用户ID
    age_range用户年龄范围{0,1,2,3}
    <18 :1 [18,24] :2 [25,29] :3 [30,34] :4 [35,39] :5 [40,49 ] :6 >= 50 : 7和8
    0和NULL表示未知
    gender用户性别{0,1,2}
    0表示女性,1表示男性,2和NULL表示未知
  • 训练数据 train_data

    DataFieldsDefinition
    user_id用户ID
    merchant_id商家ID
    label取值范围{0,1,2}
    0表示非重复购买,1表示重复购买,测试集数据这个字段为Null

2. 评估指标 AUC

  • AUC作为评估指标 二分类评测指标
  • A U C = ∑ i ∈ p o s i t i v e C l a s s r a n k i − M ( 1 + M ) 2 M ∗ N AUC = {\sum_{i \in positive Class}rank_{i}-{M(1+M)\over 2} \over {M*N}} AUC=MNipositiveClassranki2M(1+M)
  • AUC 只反应模型对正负样本排序能力的强弱对score的大小和精度没有要求
  • AUC越高 说明模型排序的能力越强 模型把所有正样本都排在负样本之前时,AUC为1
  • from sklearn.metrics import roc_auc_score
  • 注意两种预测结果函数
    • predict() 返回的是标签值
    • predict_proba() 预测属于某标签的概率

3. 查看数据样例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

user_info = pd.read_csv('../datasets/data_format1/user_info_format1.csv')
user_log = pd.read_csv('../datasets/data_format1/user_log_format1.csv')

test_data = pd.read_csv('../datasets/data_format1/test_format1.csv')
train_data = pd.read_csv('../datasets/data_format1/train_format1.csv')

在这里插入图片描述
在这里插入图片描述

4. 缺失值查看

# 年龄缺失值查看
user_age_miss_pro = (user_info.shape[0]-user_info['age_range'].count())/user_info.shape[0]
print("年龄缺失率:{:.3}%".format(user_age_miss_pro*100))
# 年龄未知个数
user_age_un_count = user_info[user_info['age_range'].isna() |
                              (user_info['age_range']==0)]['age_range'].count()
print("年龄未知及缺失值个数:{},总样本数:{}".format(user_age_un_count,user_info.shape[0]))
# 每个年龄层个数
user_info.groupby(['age_range'])['user_id'].count()

'''
年龄缺失率:0.523%
年龄未知及缺失值个数:92914,总样本数:424170
age_range
0.0     92914
1.0        24
2.0     52871
3.0    111654
4.0     79991
5.0     40777
6.0     35464
7.0      6992
8.0      1266
Name: user_id, dtype: int64
'''


# 性别缺失值查看
user_age_miss_pro = (user_info.shape[0]-user_info['gender'].count())/user_info.shape[0]
print("性别缺失率:{:.3}%".format(user_age_miss_pro*100))
# 性别未知个数
user_age_un_count = user_info[user_info['gender'].isna() |
                              (user_info['gender']==2)]['gender'].count()
print("性别未知及缺失值个数:{},总样本数:{}".format(user_age_un_count,user_info.shape[0]))
# 每个性别个数
user_info.groupby(['gender'])['user_id'].count()

'''
性别缺失率:1.52%
性别未知及缺失值个数:10426,总样本数:424170
gender
0.0    285638
1.0    121670
2.0     10426
Name: user_id, dtype: int64
'''

# user_log缺失
user_log.isna().sum()

'''
user_id            0
item_id            0
cat_id             0
seller_id          0
brand_id       91015
time_stamp         0
action_type        0
dtype: int64
'''

5. 查看数据分布

# 数据分布
label = train_data.groupby('label')['user_id'].count()
print('正负样本的数量:\n',label)
plt.figure(figsize=(12,6))

plt.subplot(1,2,1)
# autopct 保留几位小数 shadow 阴影 explode 偏移量
# value_counts()
train_data.label.value_counts().plot(kind='pie',autopct='%1.2f%%',shadow=True,explode=[0,0.3])

plt.subplot(1,2,2)
# countplot()
sns.countplot('label',data=train_data)

在这里插入图片描述

6. 探究影响复购的各种因素

# 对店铺的分析 购买次数和是否购买图
print('选取top5店铺')
top_5_merchant = train_data.merchant_id.value_counts().head(5).index.tolist()
print(top_5_merchant)

train_data_merchant = train_data.copy()
train_data_merchant['Top'] = train_data_merchant['merchant_id'].apply(lambda x:1 if x in top_5_merchant else 0)
train_data_merchant = train_data_merchant[train_data_merchant['Top'] == 1]

plt.figure(figsize=(8,6))
plt.title('Merchant VS Label')
ax = sns.countplot('merchant_id',hue='label',data=train_data_merchant)

在这里插入图片描述

# 性别和复购的关系
train_data_user_info = train_data.merge(user_info,on=['user_id'],how='left')
plt.figure(figsize=(8,8))
plt.title('Gender VS Label')
ax = sns.countplot('gender',hue='label',data=train_data_user_info)

在这里插入图片描述

# 年龄和复购的关系 
plt.figure(figsize=(8,8))
plt.title('Age VS Label')
ax = sns.countplot('age_range',hue='label',data=train_data_user_info)

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值