数据蛙强化课程第一期

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

2019-02-17  本文已影响2人  0级懒猫

数据背景:用户在一家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.用户消费行为

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%所有,前一个月因为有大量新用户涌入,而这批用户只购买了一次,所以导致复购率降低

上一篇下一篇

猜你喜欢

热点阅读