美文网首页数据蛙强化课程第一期
2019-02-17 CD网站 用户消费记录分析BY懒猫Leo

2019-02-17 CD网站 用户消费记录分析BY懒猫Leo

作者: 0级懒猫 | 来源:发表于2019-02-17 13:46 被阅读2次

    数据背景:用户在一家CD网站的消费记录,仅包含4列,不确定是具体是哪类数据
    使用工具:jupyter

    0、数据准备

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    

    导入所需包

    columns =['user_id','order_dt','order_products','order_amount']
    df = pd.read_table('CDNOW_master.txt',names=columns,sep='\s+')
    df.head()
    

    数据仅包含四列
    user_id:用户ID
    order_dt:购买日期
    order_prodects:购买产品数
    order_amount:购买金额


    df.describe()
    

    数据描述 根据数据面熟结果,75%的客户的购买量在3件以内,购买金额也较低,符合一个普通CD店的消费习惯分布

    df['order_dt'] = pd.to_datetime(df.order_dt,format='%Y%m%d')
    df['month'] = df.order_dt.values.astype('datetime64[M]')
    df.head()
    

    将购买日期列的格式更改为日期格式,并添加月份(month)列
    ![](https://upload-images.jia
    nshu.io/upload_images/14624538-62b90c62c24b829e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    1、进行用户消费趋势的分析(按月)

    • 每月的消费总金额
    • 每月的消费次数
    • 每月的产品购买量
    • 每月的消费人数
    grouped_month=df.groupby('month')
    order_month_amount=grouped_month.order_amount.sum()
    order_month_amount.head()
    
    plt.style.use('ggplot')
    order_month_amount.plot()
    

    消费金额前三个月最高,后续波动下降(原因?)



    user_id列不唯一,是用户消费次数数据,或与产品关联的订单数据(仅猜测)

    grouped_month.user_id.nunique().plot()
    
    购买用户数趋势
    grouped_month.order_products.sum().plot()
    
    购买数量趋势

    购买金额、用户数、数量高度关联,可知多数ID购买的金额、数量相差不大,主营CD价格相差不大(推测)

    df.pivot_table(index= 'month',
                  values = ['order_products','order_amount','user_id'],
                  aggfunc = {'order_products':'sum','order_amount':'sum','user_id':'count'})
    

    2.用户个体消费分析

    • 用户消费金额,消费次数的秒速统计
    • 用户消费金额和消费次数的散点图
    • 用户消费金额的分布图
    • 用户消费次数的分布图
    • 用户累计消费金额占比(百分之多少的用户占了百分之多少的消费额)
    grouped_user = df.groupby('user_id')
    grouped_user.sum().describe()
    

    用户平均购买了7张CD,中位数3,部分用户购买了较多数量的CD;用户平均消费106元,中位数43,可验证上条结论

    grouped_user.sum().query('order_amount<4000').plot.scatter(x= 'order_amount',y = 'order_products')
    

    去除极值(>=4000)


    grouped_user.sum().query('order_products<100').order_products.plot.hist(bins=40)
    

    去除极值(>=100)



    从直方图可知,用户消费金额,绝大部分呈现集中趋势,小部分异常值干扰了判断,使用过滤操作排除异常(利用切比雪夫定理过滤异常值,95%的数据都分布在5个标准差之内)

    user_cumsum =grouped_user.sum().sort_values('order_amount').apply(lambda x:x.cumsum() / x.sum())
    user_cumsum.reset_index().order_amount.plot()
    

    按照用户消费金额进行升序排序,由图可以知道50%的用户仅贡献了15%的消费额度,而排名前5000的用户就贡献了60%的消费额度

    3.用户消费行为

    • 用户第一次消费(首购)
    • 用户最后一次消费
    • 新老客户消费比
      • 多少用户仅消费一次
      • 每月新客占比
    • 用户分层
      • RFM模型
      • 新、老、活跃、回流、流失
    • 用户购买周期(按订单)
      • 用户消费周期描述
      • 用户消费周期分布
    • 用户生命周期(按第一次和最后一次消费) -用户生命周期描述
      • 用户生命周期分布
    grouped_user.min().order_dt.value_counts().plot()
    
    grouped_user.max().order_dt.value_counts().plot()
    

    断崖式下跌,看热闹人可能意味着前期活动引流效果明显,但未能留住客户
    大部分最后一次购买,集中在前三个月,说明很多用户购买了一次后就不再进行购买

    user_life = grouped_user.order_dt.agg(['min','max'])
    user_life.head()
    
    (user_life['min'] ==user_life['max']).value_counts()
    

    过半客户仅消费一次

    rfm = df.pivot_table(index ='user_id',
                        values = ['order_products','order_amount','order_dt'],
                        aggfunc ={'order_dt':'max','order_amount':'sum','order_products':'sum'})
    rfm.head()
    

    rfm['R'] = -(rfm.order_dt-rfm.order_dt.max())/np.timedelta64(1,'D')
    rfm.rename(columns = {'order_products':'F','order_amount':'M'},inplace = True)
    rfm[['R','F','M']].apply(lambda x:x-x.mean())


    def rfm_func(x):
        level = x.apply(lambda x:'1' if x>=1 else '0')
        label = level.R +level.F +level.M
        d = {
            '111':'重要价值客户',
            '011':'重要保持客户',
            '101':'重要发展客户',
            '001':'重要挽留客户',
            '110':'一般价值客户',
            '010':'一般保持客户',
            '100':'一般发展客户',
            '000':'一般挽留客户',
        }
        result = d[label]
        return result
    
    rfm['label'] = rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)
    rfm.groupby('label').sum()
    
    rfm.loc[rfm.label == '重要价值客户','color'] = 'g'
    rfm.loc[~(rfm.label == '重要价值客户'),'color'] = 'r'
    rfm.plot.scatter('F','R',c=rfm.color)
    

    RFM分析。将用户以三个维度分为8种进行区分,认为可能在一张图中对八种用户进行分类,需缩减坐标轴长度,划分更多颜色等
    从RFM 分层可知,大部分用户是重要保持客户,但是这是由于极值的影响,所以 RFM 的划分标准应该以业务为准,也可以通过切比雪夫去除极值后求均值,并且 RFM 的各个划分标准可以都不一样

    pivoted_counts = df.pivot_table(index='user_id',
                                 columns='month',
                                 values='order_dt',
                                 aggfunc='count').fillna(0)
    pivoted_counts
    
    df_purchase = pivoted_counts.applymap(lambda x :1 if x >0 else 0)
    df_purchase.tail()
    
    def active_status(data):
        status = []
        for i in range(18):
            if data[i]==0:
                if len(status) > 0:
                    if status[i-1] == 'unreg':
                        status.append('unreg')
                    else:
                        status.append('unactive')
                else:
                    status.append('unreg')
            else:
                if len(status) == 0:
                    status.append('new')
                else:
                    if status[i-1]=='unactive':
                        status.append('return')
                    elif status[i-1]=='unreg':
                        status.append('new')
                    else :
                        status.append('active')
        return status
    
    indexs=df['month'].sort_values().astype('str').unique()
    purchase_status = pivoted_counts.apply(lambda x:pd.Series(active_status(x),index=indexs),axis=1)
    purchase_status.head(5)
    

    这里遇到个麻烦,可能由于pandas版本是23.4的关系,导出的结果并非表格。所以需要对产生的数据再设置


    purchase_status_ct = purchase_status.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x))
    purchase_status_ct
    
    purchase_status_ct.fillna(0).T.plot.area()
    

    新用户仅前期存在。如果数据完整且正常,该网站长期未招新(?不合理)

    purchase_status_ct.fillna(0).T.apply(lambda x:x/x.sum(),axis =1)
    
    order_diff = grouped_user.apply(lambda x:x.order_dt - x.order_dt.shift())
    order_diff.head(10)
    
    order_diff.describe()
    

    订单周期呈指数分布
    用户的平均购买周期是68天
    绝大部分用户的购买周期都低于100天

    (order_diff / np.timedelta64(1,'D')).hist(bins=20)
    
    (user_life['max']-user_life['min']).describe()
    

    u_1=(user_life['max']-user_life['min'])/np.timedelta64(1,'D')
    u_1[u_1>0].hist(bins = 40)
    

    4.复购率和回购率分析

    • 复购率
      • 自然月内,购买多次的用户占比(即,购买了两次以上)
    pivoted_counts.head()
    
    purchase_r = pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x ==0 else 0)
    purchase_r.head()
    
    (purchase_r.sum()/purchase_r.count()).plot(figsize = (10,4))
    
    image.png

    复购率稳定在20%所有,前一个月因为有大量新用户涌入,而这批用户只购买了一次,所以导致复购率降低

    相关文章

      网友评论

        本文标题:2019-02-17 CD网站 用户消费记录分析BY懒猫Leo

        本文链接:https://www.haomeiwen.com/subject/sacgeqtx.html