数据分析项目:用户消费行为分析

用户消费行为分析实战

利用pandas进行数据处理,分析用户消费行为。
数据来源CDNow网站的用户购买明细,一共有用户ID,购买日期,购买数量,购买金额四个字段。

1、导入常用需要的库

# 导入常用需要的库
import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime 

首先我们对数据进行读取,观察数据、理解数据如有异常数据的话,需要对数据做相应数据的转换。

2、读取数据,数据文件是txt,用read_table方法打开,因为原始数据不包含表头,所以需要赋予。

3、字符串是空格分割,用**\s+**表示匹配任意空白符。 一般csv的数据分隔是以逗号的形式,但是这份来源于网上的数据比价特殊,它是通过多个空格来进行分隔。

4、定义列字段:
user_id:用户ID
order_dt:购买日期
order_products:购买产品数
order_amount:购买金额

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

5、查看数据信息

df.head()

数据分析项目:用户消费行为分析_第1张图片
观察数据,判断数据是否正常识别。
值得注意的是一个用户可能在一天内购买多次,用户ID为2的用户在1月12日买了两次

df.info()

数据分析项目:用户消费行为分析_第2张图片
查看数据类型、数据是否存在空值
1)原数据没有空值,很干净的数据。
2)我们用info的函数方法看到数据类型,日期的格式需要进行转换;
3)当利用pandas进行数据处理的时候,经常会遇见数据类型的问题, 当拿到数据的时候,首先要确定拿到的是正确的数据类型, 如果数据类型不正确需要进行数据类型的转化,再进行数据处理。

df.describe()

数据分析项目:用户消费行为分析_第3张图片
如上图:观察到用户平均每笔订单购买2.4个商品,标准差在2.3,稍稍具有波动性。中位数在2个商品,75分位数在3个商品,说明绝大部分订单的购买量都不多。最大值在99个,数字比较高。购买金额的情况差不多,大部分订单都集中在小额。

一般而言,消费类的数据分布,都是长尾形态。大部分用户都是小额,然而小部分用户贡献了收入的大头,俗称二八法则。

一:数据预处理

  • 数据类型的转化

6、数据类型的转化

  • Y四位数的日期部分
  • y表示两位数的日期部分
# 数据类型的转化
df['order_dt'] = pd.to_datetime(df.order_dt,format = '%Y%m%d') 
df['month'] = df.order_dt.values.astype('datetime64[M]')  
# 查看时间序列的变化。
df['order_dt']

数据分析项目:用户消费行为分析_第4张图片数据分析项目:用户消费行为分析_第5张图片
到目前为止,我们已经把数据类型处理成我们想要的类型了。

接下来我们通过四个字段及衍生字段就可以进行后续的分析了。

二:按月分析

  • 每月的消费总金额
  • 每月的消费次数
  • 每月的产品购买量
  • 每月的消费人数

从用户方向、订单方向、消费趋势等进行分析。
1)消费趋势的分析
目的:了解这批数据的波动形式。

#解决中文显示参数设置
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
# 设置图的大小,添加子图
plt.figure(figsize=(20,15))
# 每月的总销售额
plt.subplot(221)
df.groupby('month')['order_amount'].sum().plot(fontsize=24) 
#用groupby创建对month分组。这里要观察消费总金额,需要将order_amount求和
plt.title('总销售额',fontsize=24) 
 
#每月的消费次数
plt.subplot(222)
df.groupby('month')['order_dt'].count().plot(fontsize=24)
plt.title('消费次数',fontsize=24) 

#每月的销量
plt.subplot(223)
df.groupby('month')['order_products'].sum().plot(fontsize=24)
plt.title('总销量',fontsize=24)

#每月的消费人数
plt.subplot(224)
df.groupby('month')['user_id'].apply(lambda x:len(x.unique())).plot(fontsize=24)
plt.title('消费人数',fontsize=24)
plt.tight_layout() # 设置子图的间距
plt.show()

数据分析项目:用户消费行为分析_第6张图片
①、四个折线图的整体趋势基本一致,可以看出在1997年前3个月的销量特别高,随之而来的销售额也是暴涨,在3月份之后骤然下降,接近平稳。

②、为什么会呈现这个原因呢?我们假设是用户身上出了问题,早期时间段的用户中有异常值,第二假设是各类促销营销,但这里只有消费数据,所以无法判断。

③、可以看出网站的流失在增加,网站运营需开源节流,即需拉新并对老客户进行留存,主要是需要拉新,增加新用户,增加销售收入。

附加:上面消费趋势的分析可以通过数据透视表分析

# ** 附加:上面消费趋势的分析可以通过数据透视表分析 **
df.pivot_table(index = 'month',
              values = ['order_products','order_amount','user_id'],
              aggfunc = {'order_products':'sum','order_amount':'sum','user_id':'count'})

数据分析项目:用户消费行为分析_第7张图片
数据透视表是更简单的方法,有了这个之后大家用里面的数据进行作图也是OK的,而且更加的快捷,所以pandas到后面的话解决一个问题会想到两到三个方法。具体看那个方便,那个简单。

总结:按月数据分析主要用group by简单了解了消费趋势

三:用户个体消费分析

  • 用户消费金额和消费次数的描述统计
  • 用户消费金额和消费次数的散点图
  • 用户消费金额的分布图(二八法则)
  • 用户消费次数的分布图
  • 用户累计消费金额的占比

1)用户个体消费数据分析
之前我们的维度都是月来看的是趋势,有时候我们也需要从个体来看这个人的消费能力如何。

# 01-用户消费金额和消费次数的描述统计
group_user = df.groupby('user_id')
group_user.sum().describe()

数据分析项目:用户消费行为分析_第8张图片
从上如用户角度数据看基本上都符合二八法则,小部分的用户占了消费的大头。

# 02-用户消费金额和消费次数的散点图
group_user.sum().query('order_amount < 4000').plot.scatter(x = 'order_amount' , y = 'order_products')
#query后面只支持string形式的值

数据分析项目:用户消费行为分析_第9张图片
从上图散点图来看,用户比较健康而且规律性很强。
因为这是CD网站的销售数据,商品比较单一,金额和商品量的关系也因此呈线性,也比较集中。

# 03-用户消费金额的分布图(二八法则)
group_user.sum().order_amount. plot.hist(bins = 20)
#bins = 20,就是分成20块,最高金额是14000,每个项就是700

从上图直方图可知,大部分用户的消费能力确实不高,绝大部分呈现集中在很低的消费档次。高消费用户在图上几乎看不到,这也确实符合消费行为的行业规律。 虽然有极致干扰了我们的数据,但是大部分的用户还是集中在比较低的而消费档次。

# 04-用户消费次数的分布图(二八法则)
group_user.sum().query('order_products < 100').order_products.hist(bins = 40)

到目前为止,关于用户的消费行为我们有了大概的了解

# 05-用户累计消费金额的占比(百分之多少的用户占了百分之多少的消费额)
user_cumsum = group_user.sum().sort_values('order_amount').apply(lambda x: x.cumsum() / x.sum())
user_cumsum
  • axis = 0:按列计算
  • cumsum:滚动累加求和
  • sort_values:排序,升序
  • apply(lambda x: x.cumsum() / x.sum()) ,应用函数
    数据分析项目:用户消费行为分析_第10张图片
# 06-重置索引
user_cumsum.reset_index()

数据分析项目:用户消费行为分析_第11张图片

# 07-对消费金额占比进行绘制图
user_cumsum.reset_index().order_amount.plot()

数据分析项目:用户消费行为分析_第12张图片
按用户消费金额进行升序排序,由图可知50%的用户仅贡献了15%的销售额度,排名前5000的用户贡献了60%的消费额。

由此消费数据看出,这少部分的客户贡献了大部分的收入,需对top客户进行维护管理,对新用户进行留存转化,形成用户运营体系的生态圈。

四:用户消费行为分析

  • 首购(第一次消费)
  • 最后一次消费
  • 新老用户占比
  • 用户分层
  • 用户生命周期

①、首购(第一次消费)
首次购买可以区分出不同渠道的首次购买用户量,可看出渠道的差异性,对渠道的贡献数据化,为后期渠道的优化改进提供依据。

# 计算第一次购买时间分布
group_user.min().order_dt.value_counts().plot(figsize=(12,5))

#等同于df['order_dt'].groupby(df['user_id']).min().value_counts().plot(figsize=(12,5))
# 2月发生较大下跌  渠道发生变化或者其他

数据分析项目:用户消费行为分析_第13张图片
可以看出客户首次购买基本分布在1-3月,是网站新开起始阶段的首购用户;4月后续无新用户产生首购,需对用户渠道进行细化分析。

②、最后一次消费

group_user.max().order_dt.value_counts().plot()
plt.title('最后一次消费时间分布')

数据分析项目:用户消费行为分析_第14张图片
用户最后一次购买的分布比第一次大部分最后一次购买集中在前三月,说明前三月有很多用户购买了一次后就不再进行购买(即前三个月很多客户首购即他们的最后一次购买)

后续随着时间递增,最后一次购买数也在递增;到98年消费呈现流失上升的情况(用户最后一次购买数增加,意味着用户不再购买,用户流失)

③、新老用户占比
通过用户的购买时间来辨别是否是新用户或老客户,若首购时间与最后一次购买时间一样,则是新用户,否则为老用户

# 计算只消费了一次的用户人数(结果为:11908)
user_file = group_user.order_dt.agg(["min","max"])
(user_file["min"] == user_file["max"]).value_counts()

在这里插入图片描述
新用户12054,老用户11516,基本各占50%,有一半用户首购后就再无消费,应对此部分用户进行召回,通过制定相应的营销活动等方式刺激用户消费。

④ 用户分层

  • 通过RFM模型进行分析,则需要得到用户的RFM;
    R:消费最后一次消费时间的度量,数值越小越好
    F:消费的总商品数,数值越大越好
    M:消费的总金额,数值越大越好
  • 通过数据透视,得到用户的消费金额、最近一次消费时间、消费购买产品数。
#  (用户分层)RFM  
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()

数据分析项目:用户消费行为分析_第15张图片

# 计算每位用户最后一次消费时间与全部用户最后一次消费时间的差值
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.head()

数据分析项目:用户消费行为分析_第16张图片

# /np.timedelta64(1,'D')  消除单位   进行重命名
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.head()

数据分析项目:用户消费行为分析_第17张图片

#应用匿名函数,判断每一行值与平均值大小关系
rfm[['R','F','M']].apply(lambda x:x-x.mean()).head()

数据分析项目:用户消费行为分析_第18张图片
针对用户的RFM,把用户分为8个类别,分别给用户打标签。

  • R>0,是距离平均消费时间要久,R越大 说明没有消费时间越久;
  • F >0 M>0,消费次数和金额也是较高的,重要价值客户,依次类推
# 客户层次的定义,RFM得分可根据业务定义打分
# 得出不同相似程度的数据集,并且根据每一个数据集的特点进行客户定义
def rfm_func(x):
    level = x.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

rfm['label'] = rfm[['R', 'F', 'M']].apply(lambda x: x-x.mean()).apply(rfm_func, axis=1)
rfm.head()

数据分析项目:用户消费行为分析_第19张图片

# 计算每层客户的R、F、M的和
rfm.groupby('label').sum()

数据分析项目:用户消费行为分析_第20张图片
可以看出,重要保持客户对于消费总金额的占比远大于其他客户的占比,这说明绝大部分收益是由重要保持客户贡献的,只要能保证这部分客户不流失和增加,那么公司收益将得到有力保障。

rfm.groupby('label').count()

数据分析项目:用户消费行为分析_第21张图片

# 各类型用户占比
use_c = rfm.groupby('label').count()
plt.axis('equal')
labels = ['一般价值客户','一般保持客户','一般发展客户'
          ,'一般挽留客户','重要价值客户','重要保持客户'
          ,'重要发展客户','重要挽留客户']
plt.pie(use_c['M'],
       autopct='%3.1f%%',
        labels = labels,
        pctdistance=0.9,
       labeldistance = 1.2,
       radius=3,
       startangle = 15)
plt.show()

数据分析项目:用户消费行为分析_第22张图片
从RFM分层可知,大部分用户为重要保持客户。

⑤ 用户生命周期

pivoted_counts = df.pivot_table(index = 'user_id',
                                  columns = 'month',
                                  values = 'order_dt',
                                  aggfunc = 'count').fillna(0)
# pivoted_counts.head()
pivoted_counts.head()
# 按月份进行对比,1月份哪些是购买的,再去对比二月份哪些是购买的

数据分析项目:用户消费行为分析_第23张图片

# 消费过的为1 ,没消费过的为0
df_purchase = pivoted_counts.applymap(lambda x: 1 if x > 0 else 0)
df_purchase.tail()

数据分析项目:用户消费行为分析_第24张图片
1)通过定义一个函数来对用户进行生命周期的划分分层。
将用户状态分为:

  • unreg(未注册)
  • new(新客)
  • active(活跃用户)
  • return(回流用户)
  • unactive(不活跃用户)

思路:
①、若本月没有消费
若之前是未注册,则依旧为未注册;
若之前有消费,则为流失/不活跃 ;
其他情况,为未注册 。

②、若本月有消费
若是第一次消费,则为新用户;
若之前有过消费,则上个月为不活跃,则为回流;
若上个月为未注册,则为新用户 除此之外,为活跃。

# 用户状态
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')
# 这里需要对返回的值进行转换,将列表转为Series
    return pd.Series(status, index = pivoted_counts.columns)

purchase_stats = df_purchase.apply(active_status,axis=1)
purchase_stats.head()

数据分析项目:用户消费行为分析_第25张图片
数据分析项目:用户消费行为分析_第26张图片

# 用户状态分层面积图
purchase_stats_ct=purchase_status_ct.fillna(0).T
purchase_stats_ct.plot.area(figsize=(12,5))
plt.title('用户分层')

数据分析项目:用户消费行为分析_第27张图片
由上可知不同客户活跃状态,根据业务需求采取不同的运营策略,如:拉新、引流、促活、召回等运营策略。

⑥、复购率和回购率分析

  • 复购率:自然月内,购买多次的用户占比
  • 回购率:曾今购买过的用户在某一时期内的再次购买占比
    注:指标的定义和标准是根据不同公司的业务形态而变化

针对复购率、回购率,可找到较高的月份,细化分析,看较高的产品(产品特征),看较高的用户(用户特征),可根据这些细化的数据做产品的爆款营销、推广、个性化营销等。

# 用透视表计算客户每个月的消费次数
pivoted_counts=df.pivot_table(index='user_id',
                              columns='month',
                              values='order_dt',
                              aggfunc='count').fillna(0)
pivoted_counts.head()

数据分析项目:用户消费行为分析_第28张图片
以上透视表记录了每位用户每月消费次数的记录,是一份消费明细表
数据分析项目:用户消费行为分析_第29张图片
1)复购率

#计算复购率
(purchase_r.sum()/purchase_r.count()).plot(figsize=(10,4))
plt.title('复购率')

数据分析项目:用户消费行为分析_第30张图片
复购率稳定在20%左右,前三个月因为有大量新用户涌入,而这些用户只购买了一次,所以导致复购率降低。

2)回购率
定义一个函数,将消费两次以上记为1,消费一次记为0,没有消费记为空值。

def purchase_back(data):
    status = []
    for i in range(17):
        if data[i] == 1: # 本月进行过消费
            if data[i+1] == 1: # 下一月是否进行消费
                status.append(1) #消费为1 回购了
            if data[i+1] == 0:
                status.append(0) # 未消费则为0 没有回购
        else:
            status.append(np.NaN) # 之前没消费则不计
    status.append(np.NaN) # 最后一个月没有判断需要补上
    return pd.Series(status,df_purchase.columns)
#对透视表应用函数purchase_back:
purchase_b = df_purchase.apply(purchase_back, axis =1)
purchase_b.head()

数据分析项目:用户消费行为分析_第31张图片

  • 0 表示上个月购买了,下个月没有进行消费,则是没有回购;
  • 1 代表当月消费过次月依旧消费,表示回购了;
  • NAN表示当月没有消费(不进行计算)。
# 计算回购率:
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))
plt.title('回购率')

数据分析项目:用户消费行为分析_第32张图片

五、总结

1、通过数据获取导入、数据规整、数据探索、网站消费数据分析及用户消费行为分析,对网站的经营情况进行了探索分析,对销售情况有了了解。
2、通过对用户消费行为的分析,可简单地为网站后续的运营、营销等方面制定策略,网站可根据策略执行对应策略。
3、最后也可以通过数据化对执行效果进行追踪复盘分析,进一步优化,以此循环。通过数据化、可视化对用户数据进行分析,可有效地提升运营管理有效性。

你可能感兴趣的:(案例分析)