数据蛙强化课程第二期数据分析数据分析

CDNOW用户购买行为分析

2019-03-31  本文已影响13人  LucasOoo

数据来源于CDNOW网站的用户购买记录,包括用户ID,购买日期,购买产品数,购买金额等四项基本数据,以下通过Python对用户消费行为进行分析
数据来源:链接:https://pan.baidu.com/s/1P01mMF9PM6B1P7M1VhWGdg 提取码:2weg

阅读路线:

0、数据准备
1、对用户消费趋势的分析(按月)
2、用户的个体消费分析
3、消费行为分析
4、复购率和回购率分析

0、数据准备

导入常用数据库:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

导入数据

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

导入数据后检查数据的完整性

df.head()
image.png
df.info()

数据中无缺失值,无需对缺失值处理,但是购买日期的数据类型是int,为方便后面数据处理,在这先将其转化成datetime格式。

df.order_dt=pd.to_datetime(df.order_dt,format='%Y%m%d')
image.png

数据预处理好后,先看下数据的基本情况:

df.describe()
image.png
  1. 用户平均每笔订单的购买数是2.4,中位数为2,数据右偏;此外,购买数量最大值达到了99,说明数据存在一定的极值干扰;
    2.用户每笔订单的购买金额也存在同样的情况,平均消费35.89元,中位数25.98元,消费最大金额达到了1286元。

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

对用户消费趋势总共分成以下四个部分进行:

month_grouped = df.resample('m').agg({'user_id':'count',
                    'order_products':'sum',
                    'order_amount':'sum'})
month_grouped['user_sum'] = df.resample('m')['user_id'].nunique()

通过resample函数对数据进行按月分组,分别求出每月的消费频次,购买量、每月消费的总金额以及每月的消费人数:

image.png

对每项数据做直方图:

import pylab
%pylab inline
pylab.rcParams['figure.figsize']=(16,20)
fig,axes = plt.subplots(4,1)
axes0,axes1,axes2,axes3 = axes.flatten()
axes0.bar(month_grouped.index,month_grouped.user_id,width=20)
axes0.set_title('每月的消费频次')
axes1.bar(month_grouped.index,month_grouped.order_products,width=20)
axes1.set_title('每月的产品购买量')
axes2.bar(month_grouped.index,month_grouped.order_amount,width=20)
axes2.set_title('每月消费的总金额')
axes3.bar(month_grouped.index,month_grouped.user_sum,width=20)
axes3.set_title('每月的消费人数')
每月的消费频次,购买量、每月消费的总金额、每月的消费人数分布直方图

对user_id进行去重处理,再统计每月的消费人数:

df.drop_duplicates('user_id')['user_id'].resample('m').count()
image.png

通过以上数据发现:

每月用户平均消费金额分析:

pylab.rcParams['figure.figsize']=(16,6)
user_avgamount = month_grouped['order_amount']/month_grouped['user_sum']
plt.bar(user_avgamount.index,user_avgamount,width=20)
用户每月的平均消费金额

每月用户平均消费次数分析:

user_avgorder = month_grouped['order_products']/month_grouped['user_sum']
plt.bar(user_avgorder.index,user_avgamount,width=20)
plt.title('用户每月的平均消费次数',size=20)
用户每月的平均消费次数

2、用户的个体消费分析

分为以下几个方面分析:

2.1 用户消费金额、消费次数的描述统计:

user_grouped = df.groupby('user_id').agg({'user_id':'count',
                                          'order_products':'sum',
                                          'order_amount':'sum'})
user_grouped.describe()
用户消费金额、消费次数的描述

2.2绘制用户消费金额和消费次数的散点图:

user_grouped.plot.scatter(x='order_products',y='order_amount')
用户消费金额和消费次数的散点图

大部分数据都集中在在左下角区域,数据最后两个极值拉大了图形区域,通过query函数过滤极值:


滤除异常值后用户消费金额和消费次数的散点图

2.3 用户消费金额的分布图:

pylab.rcParams['figure.figsize']=(16,9)
user_grouped['order_amount'].hist(bins=30)
用户消费金额的分布图

大部分购买金额集中在0-2500之间,由于一些极值的影响使得数据分布收到了干扰。
根据切比雪夫定理,距离平均值有三个标准差的值均为异常值,根据2.1的描述值,用户的消费金额应该在106+241*3=829的范围内

user_grouped.query('order_amount<829')['order_amount'].hist(bins=30)

滤除异常值后用户消费金额的分布图
2.4 用户产品购买量的分布图
同样的,使用切比雪夫定理过滤掉异常值:
user_grouped.query('order_products<58.12')['order_products'].hist(bins=30)
用户产品购买量的分布图
2.5 用户累计消费金额占比
user_cumsum = user_grouped.sort_values('order_amount').apply(lambda x : x.cumsum()/x.sum())
user_cumsum.reset_index(drop=True).order_amount.plot()
plt.grid()
用户累计消费占比分布情况

3、消费行为分析

主要分为以下几个方面分析:

  • 用户第一次消费(首购)
  • 用户最后一次消费
  • 新老客户消费比
    • 多少用户仅消费了一次?
    • 每月新客占比?
  • 用户分层
    • RFM
    • 新、老、活跃、回流、流失
  • 用户购买周期(按订单)
    • 用户消费周期描述
    • 用户消费周期分布
  • 用户生命周期(按第一次&最后一次消费)
    • 用户生命周期描述
    • 用户生命周期分布

3.1 用户第一次消费(首购)
提取用户第一次消费的日期并作图:

df.groupby('user_id')['order_dt'].min().value_counts().plot()
用户第一次消费趋势图

3.2 用户最后一次消费

df.groupby('user_id')['order_dt'].max().value_counts().plot()
用户最后消费趋势图

3.3 新老客户消费比
求出用户购买产品日期的最大值和最小值,若该日期的最大值等于其最小值,说明这个用户只消费了一次。

user_dt = df.groupby('user_id').order_dt.agg(['min','max'])
pylab.rcParams['figure.figsize']=(8,8)
rate = (user_dt['min'] == user_dt['max']).value_counts()
labels = ['只消费一次用户','多次消费用户']
patches,l_text,p_text = plt.pie(rate,labels=labels,
                                explode=(0,0.15),
                                autopct='%2.1f%%',
                                startangle=90,
                               )
for t in l_text: #调整标签字体大小
    t.set_size(15)
for t in p_text: #调整百分数字体大小
    t.set_size(15)
新老客户消费比

对用户按月分组,计算新用户人数占总消费人数的比例:

pylab.rcParams['figure.figsize']=(10,6)
user_new = df.drop_duplicates('user_id')['user_id'].resample('m').count()#计算每月首次购买产品的用户数
user_sum = df.resample('m')['user_id'].nunique()#计算每月购买产品的用户总数
(user_new/user_sum).fillna(0).plot()
每月新客占比趋势图

3.4 用户分层
3.4.1 RFM分层
RFM模型,通过对用户在R(Recency,最近一次消费)F(Frequency,消费频率)M(Monetary,消费金额)三方面的表现进行分类,然后对分类分组进行定性描述的,分层模型如下:

RFM用户分层模型

先对数据做预处理,让每个日期减去最大日期获得间隔天数(该数为负数),当数值越大时,说明日期越近。

df.reset_index(inplace=True)
df['period']=(df.order_dt - df.order_dt.max())/np.timedelta64(1,'D')#计算时间差,并转换为float类型
image.png

使用数据透视表功能,求出各用户的最近消费时间(间隔天数),消费频次,消费总金额。

user_rfm = df.pivot_table(values=['period','order_products','order_amount'],
                          index='user_id',aggfunc={'period':'max',
                                                  'order_products':'count',
                                                    'order_amount':'sum' })
user_rfm = user_rfm.rename(columns = {'order_amount':'M','order_products':'F','period':'R'})
RFM预处理后的数据

将用户在R、F、M
三个维度上按照高于平均值和低于平均值进行划分(划分标准可根据不同业务设计也不同),高于平均值则赋值为1,低于平均值则赋值为0,最后根据RFM分层模型给所有用户分层:

def level_label(data):#定义分层函数
    level = data.apply(lambda x :'1' if x>=0 else '0')
    label = level['R']+level['F']+level['M']
    d = {
        '111':"高价值客户",
        '011':"重点保持客户",
        '101':"重点发展客户",
        '001':"重点挽留客户",
        '110':"一般价值客户",
        '010':"一般保持客户",
        '100':"一般发展客户",
        '000':"潜在客户"
    }
    result = d[label]
    return result


user_rfm['label'] = (user_rfm - user_rfm.mean()).apply(level_label,axis=1)
RFM用户分层结果

对用户分层结果计数:


image.png

作饼状图:

label_count = user_rfm.groupby('label').count()
pylab.rcParams['figure.figsize']=(10,10)
labels = ['一般价值客户','一般保持客户','一般发展客户','潜在客户','重点保持客户','重点发展客户','重点挽留客户','高价值客户']

plt.pie(label_count['M'],labels=labels,autopct = '%3.1f%%',startangle = 90)
用户分层结果饼状图

3.4.2 用户状态分析:注册、活跃、回流、流失(不活跃)统计
建立数据透视表,以user_id为横坐标,m月份为纵坐标,统计用户每月的消费情况:

pivoted_count = df.pivot_table(index = 'user_id',
                               columns='M',
                               values = 'order_products',
                               aggfunc={'order_products':'count'})
pivoted_count = pivoted_count.fillna(0)
image.png

进行多重判断,将用户状态分为unreg(未注册)、new(新客)、active(活跃用户)return(回流用户)和unactive(不活跃用户):

def status(data):
    state = []
    lenth = len(data)
    for i in range(18):
        if data[i]>0:
            if len(state) == 0:
                state.append('new')
            else:
                if state[i-1] == 'unreg':
                    state.append('new')
                elif state[i-1] == 'unactive':
                    state.append('return')
                else:
                    state.append('active')
                
        else:
            if len(state) == 0:
                state.append('unreg')
            else:
                if state[i-1] == 'unreg':
                    state.append('unreg')
                else:
                    state.append('unactive')
    return state
                    
pivoted_count.apply(status,axis=1)
                    
image.png

不同用户的计数统计,并做面积图:

pylab.rcParams['figure.figsize'] = (10,6)
pivoted_count.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x)).T.fillna(0).plot.area()
image.png

3.5 用户生命周期(按第一次&最后一次消费)
按用户进行分组,计算用户本次购买日期和下一次购买日期的时间间隔,并统计:

user_period = df.groupby('user_id').apply(lambda x:x.order_dt-x.order_dt.shift())
user_period.describe()
用户购买周期描述统计

对该数据做分布图:

(user_period/np.timedelta64(1,'D')).hist(bins=20)
plt.title('用户购买周期分布图')
用户购买周期分布图

用户的生命周期分布:

user_cycle = df.groupby('user_id').apply(lambda x:x.order_dt.max()-x.order_dt.min())
user_cycle.describe()
image.png
user_cycle = user_cycle/timedelta64(1,"D")
user_cycle[user_cycle>0].plot.hist(bins=20)
用户生命周期分布图

4、复购率和回购率分析

4.1 复购率计算
以月为单位,对3.4.2统计的每月用户消费情况进行预处理:
若消费次数大于1,则说明用户在本月进行了多次消费,对多次消费的情况取值为1;
若消费次数等于1,说明用户在本月只进行了1次消费,每月复购行为,取值为0;
若消费次数等于0,则说明用户在本月未消费。

pivoted_count = df.pivot_table(index = 'user_id',
                               columns='M',
                               values = 'order_products',
                               aggfunc={'order_products':'count'})
pivoted_count = pivoted_count.fillna(0)
df_purchase = pivoted_count.applymap(lambda x:1 if x>1 else np.nan if x==0 else 0)#清洗数据,消费超过两次为1,消费过1次为0,没有消费为nan
清洗后结果

计算每个月的复购率,多次消费人数/总消费人数,并对其做柱状图。

df_purchase.apply(lambda x:x.sum()/x.count()).plot.bar(
每月复购率分布图

4.1 回购率计算
计算用户的回购率主要以本月与上月的进行对比,假如上月进行过消费,本月再次消费了,说明该用户是回购用户。
对3.4.2统计的每月用户消费情况进行预处理:
若消费次数大于0说明在本月已消费,重新赋值为1;
若消费次数为0说明在本月未消费,重新赋值为np.nan;

df_purchase_back = pivoted_count.applymap(lambda x:1 if x>0 else np.nan)
df_purchase_back.head()
预处理后结果

编写筛选函数:
若本月未消费,则全部置np.nan;
若本月已消费,上月未消费全部置0;
若本月已消费,上月也消费,全部置1(回购用户)

def purchase_back(data):
    lenth = len(data)
    state = [0]
    for i in range(1,lenth):
        if data[i-1] == 1:
            if data[i]==1:
                state.append(1) #若上个月已消费,本月也消费置1
            else:
                state.append(np.nan) #本月未消费置np.nan
        else:
            if data[i] == 1:
                state.append(0) #本月消费但上个月未消费置0
            else:
                state.append(np.nan) #本月未消费置np.nan
    return state
df_purchase_back.apply(purchase_back,axis=1)
用户复购结果

计算用户的回购率(本月用户回购人数/本月消费总人数),并做柱状图:

df_purchase_b = df_purchase_back.apply(purchase_back,axis=1)
df_purchase_b.apply(lambda x:x.sum()/x.count()).plot.bar()
用户回购率分布图
上一篇 下一篇

猜你喜欢

热点阅读