网易云音乐用户消费行为分析

背景

网易云音乐大家都被大家所熟知 , 数据脱敏之后,形成了文本数据。
本节主要通过分析网易云音乐的用户购买明细来分析该网站的用户消费行为,使运营业务部门在营销时更加具有针对性,从而节省成本,提升效率。

提出问题

对用户进行消费特征分析。分析框架如下:
在这里插入图片描述

数据处理

导入数据

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

plt.style.use(‘ggplot’) #更改设计风格,使用自带的形式进行美化
plt.rcParams[“font.sans-serif”] = [“SimHei”] # 用来显示中文
plt.rcParams[“axes.unicode_minus”] = False # 用来显示负号

seq标识分隔符,分隔符为\t ,即制表符,表示列与列之间用\t分开

df = pd.read_table(“./wangyiyun.txt”, sep = ‘\s+’)

df
在这里插入图片描述

columns = [‘用户ID’,‘购买日期’,‘订单数’,‘订单金额’]
df = pd.read_table(“./wangyiyun.txt”,names= columns, sep = ‘\s+’)

\f -> 匹配一个换页
\n -> 匹配一个换行符
\r -> 匹配一个回车符
\t -> 匹配一个制表符
而"\s+"则表示匹配任意多个上面的字符
df
在这里插入图片描述

总结

  • 加载包和数据,文件是txt,用read_table方法打开,因为原始数据不包含表头,所以有names参数 。字符串是空格分割,用\s+表示匹配任意空白符。
  • 一般csv的数据分隔是以逗号的形式,但是这份数据它是通过多个空格来进行分隔
  • 消费行业或者是电商行业一般是通过订单数,订单额,购买日期,用户ID这四个字段来分析的。基本上这四个字段就可以进行很丰富的分析。

#看看详细信息
df.info()
<class ‘pandas.core.frame.DataFrame’>
RangeIndex: 69659 entries, 0 to 69658
Data columns (total 4 columns):
#Column Non-Null Count Dtype


0 用户ID 69659 non-null int64
1 购买日期 69659 non-null int64
2 订单数 69659 non-null int64
3 订单金额 69659 non-null float64
dtypes: float64(1), int64(3)
memory usage: 2.1 MB
#默认输出前五行
df.head()
在这里插入图片描述

  • 观察数据,购买日期列表示时间,是int类型,数据不是时间类型,需要转换。购买金额是float类型
  • 没有缺失值,这个比较不错
  • 数据中存在一个用户在同一天或不同天下多次订单的情况,如用户ID为2的用户就在1月12日买了两次。

描述性统计

#数值列的汇总统计信息
df.describe()
在这里插入图片描述

describe是描述统计,对用户数据特征进行整体性判断:

  • 从数据的统计描述信息中可以看出,用户每个订单平均购买2.41个商品,每个订单平均消费35.89元。
  • 购买商品数量的标准差为2.33,平均数是 2.4 std/mean 小于0.5(统计学经验来看) 说明 mean更有代表性
  • 中位数为2个商品,75%分位数为3个商品,说明大部分订单的购买数量都不多。最大值在99个,数字比较高。订单金额的情况差不多,大部分订单都集中在小额。
  • 一般而言,消费类的数据分布,都是长尾形态。大部分用户都是小额,然而小部分用户贡献了收入的大头,俗称二八。

数据处理

#索引,数据类型和内存信息
df.info()
<class ‘pandas.core.frame.DataFrame’>
RangeIndex: 69659 entries, 0 to 69658
Data columns (total 4 columns):
#Column Non-Null Count Dtype


0 用户ID 69659 non-null int64
1 购买日期 69659 non-null int64
2 订单数 69659 non-null int64
3 订单金额 69659 non-null float64
dtypes: float64(1), int64(3)
memory usage: 2.1 MB

  • 没有缺失值 , 接下来我们要将时间的数据类型转化。

pd.to_datetime(df[‘购买日期’])
在这里插入图片描述

#将购买日期列进行数据类型转换
df[‘购买日期’] = pd.to_datetime(df[‘购买日期’],format = ‘%Y%m%d’)
df[‘购买日期’] # 发现excel导入的时间格式均为datetime64[ns],毫秒格式。
在这里插入图片描述

#把日期转化为月为单位
df[‘购买日期’].astype(‘datetime64[M]’)
在这里插入图片描述

#df[‘月份’] = df[‘购买日期’].values.astype(‘datetime64[M]’)
df[‘月份’] = df[‘购买日期’].astype(‘datetime64[M]’)

#df[‘购买日期’].dt.month # 可以类比 str访问器

df.head(30)
在这里插入图片描述

总结

  • pd.to_datetime可以将特定的字符串或者数字转换成时间格式,其中的format参数用于匹配。例如19970101,%Y匹配前四位数字1997
  • 另外,小时是%h,分钟是%M,注意和月的大小写不一致,秒是%s。若是1997-01-01这形式,则是%Y-%m-%d
  • astype也可以将时间格式进行转换,比如[M]转化成月份。我们将月份作为消费行为时间窗口,选择哪种时间窗口取决于消费频率。

用户总体消费趋势分析

df.groupby(‘月份’)[‘订单金额’].sum()
在这里插入图片描述

#设置图的大小,添加子图
plt.figure(figsize=(20,15))
#每月的总销售额
plt.subplot(221)
df.groupby(‘月份’)[‘订单金额’].sum().plot(fontsize=24)
plt.title(‘总销售额’,fontsize=24)

#每月的消费次数
plt.subplot(222)
df.groupby(‘月份’)[‘购买日期’].count().plot(fontsize=24)
plt.title(‘消费次数’,fontsize=24)

#每月的销量
plt.subplot(223)
df.groupby(‘月份’)[‘订单数’].sum().plot(fontsize=24)
plt.title(‘总销量’,fontsize=24)

#每月的消费人数
plt.subplot(224)
df.groupby(‘月份’)[‘用户ID’].apply(lambda x:len(x.unique())).plot(fontsize=24)
plt.title(‘消费人数’,fontsize=24)
plt.tight_layout() # 设置子图的间距
plt.show()
在这里插入图片描述

#演示每月消费人数是怎么画的
list(df.groupby(‘月份’)[‘用户ID’])
[(Timestamp(‘1997-01-01 00:00:00’),
0 1
1 2
2 2
3 3
9 4

26010 8284
26012 8285
26013 8286
26014 8287
26020 8288
Name: 用户ID, Length: 8928, dtype: int64),
(Timestamp(‘1997-02-01 00:00:00’),
15 5
29 8
80 29
92 30
102 33

50673 16723
50674 16724
50676 16725
50677 16726
50678 16727
Name: 用户ID, Length: 11272, dtype: int64),
(Timestamp(‘1997-03-01 00:00:00’),
4 3
42 11
78 28
81 29
131 37

69652 23567
69653 23568
69656 23569
69657 23570
69658 23570
Name: 用户ID, Length: 11598, dtype: int64),
(Timestamp(‘1997-04-01 00:00:00’),
5 3
16 5
82 29
83 29
183 47

69595 23541
69604 23547
69615 23552
69654 23568
69655 23568
Name: 用户ID, Length: 3781, dtype: int64),
(Timestamp(‘1997-05-01 00:00:00’),
17 5
37 9
84 29
85 29
103 33

69577 23534
69599 23544
69634 23558
69638 23559
69648 23564
Name: 用户ID, Length: 2895, dtype: int64),
(Timestamp(‘1997-06-01 00:00:00’),
18 5
30 8
55 19
105 33
106 33

69571 23532
69609 23551
69626 23556
69635 23558
69639 23559
Name: 用户ID, Length: 3054, dtype: int64),
(Timestamp(‘1997-07-01 00:00:00’),
19 5
31 8
49 16
50 16
65 25

69497 23500
69572 23532
69578 23534
69627 23556
69628 23556
Name: 用户ID, Length: 2942, dtype: int64),
(Timestamp(‘1997-08-01 00:00:00’),
11 4
66 25
107 33
133 37
145 40

69536 23517
69557 23529
69591 23539
69610 23551
69611 23551
Name: 用户ID, Length: 2320, dtype: int64),
(Timestamp(‘1997-09-01 00:00:00’),
20 5
51 16
88 29
108 33
127 35

69581 23534
69582 23534
69612 23551
69613 23551
69629 23556
Name: 用户ID, Length: 2296, dtype: int64),
(Timestamp(‘1997-10-01 00:00:00’),
26 7
67 25
109 33
110 33
111 33

69475 23496
69499 23500
69516 23507
69621 23555
69646 23563
Name: 用户ID, Length: 2562, dtype: int64),
(Timestamp(‘1997-11-01 00:00:00’),
6 3
7 3
32 8
33 8
89 29

69527 23513
69558 23529
69573 23532
69574 23532
69649 23564
Name: 用户ID, Length: 2750, dtype: int64),
(Timestamp(‘1997-12-01 00:00:00’),
12 4
21 5
22 5
34 8
150 40

69484 23498
69517 23507
69528 23513
69538 23517
69622 23555
Name: 用户ID, Length: 2504, dtype: int64),
(Timestamp(‘1998-01-01 00:00:00’),
23 5
63 24
121 33
212 48
235 53

69540 23517
69559 23529
69600 23544
69630 23556
69642 23561
Name: 用户ID, Length: 2032, dtype: int64),
(Timestamp(‘1998-02-01 00:00:00’),
43 11
122 33
152 40
153 40
154 40

69549 23523
69587 23537
69593 23540
69619 23554
69636 23558
Name: 用户ID, Length: 2026, dtype: int64),
(Timestamp(‘1998-03-01 00:00:00’),
27 7
35 8
99 32
123 33
124 33

69456 23489
69508 23503
69541 23517
69560 23529
69588 23537
Name: 用户ID, Length: 2793, dtype: int64),
(Timestamp(‘1998-04-01 00:00:00’),
68 25
90 29
94 31
95 31
194 47

69461 23490
69462 23490
69477 23496
69490 23499
69561 23529
Name: 用户ID, Length: 1878, dtype: int64),
(Timestamp(‘1998-05-01 00:00:00’),
8 3
69 25
96 31
135 37
163 43

69486 23498
69529 23513
69583 23534
69623 23555
69643 23561
Name: 用户ID, Length: 1985, dtype: int64),
(Timestamp(‘1998-06-01 00:00:00’),
38 9
70 25
71 25
195 47
214 48

69342 23444
69458 23489
69530 23513
69624 23555
69631 23556
Name: 用户ID, Length: 2043, dtype: int64)]
def fun(x):
return len(x.unique())

df.groupby(‘月份’)[‘用户ID’].apply(fun).plot(fontsize=24)
在这里插入图片描述

df.groupby(‘月份’)[‘用户ID’].apply(lambda x:len(x.unique()))
月份
1997-01-01 7846
1997-02-01 9633
1997-03-01 9524
1997-04-01 2822
1997-05-01 2214
1997-06-01 2339
1997-07-01 2180
1997-08-01 1772
1997-09-01 1739
1997-10-01 1839
1997-11-01 2028
1997-12-01 1864
1998-01-01 1537
1998-02-01 1551
1998-03-01 2060
1998-04-01 1437
1998-05-01 1488
1998-06-01 1506
Name: 用户ID, dtype: int64

  • 四个折线图的整体趋势基本一致,可以看出来,1997年前3个月的销量特别高,随之而来的销售额也是暴涨,在3月份之后骤然下降,接近平稳。
  • 为什么会呈现这个原因呢?我们假设是用户身上出了问题,早期时间段的用户中有异常值,第二假设是各类促销营销,但这里只有消费数据,所以无法判断。
  • 另一方面,在2月到3月这段期间,可以发现消费人数稍有下降,但总销量与总销售额却依然上升,是不是说明3月份的用户中有我们需要重点发展的高价值客户呢?

用户个体消费数据分析

用户消费金额,消费次数的描述统计

#根据用户id进行分组,求和
group_user = df.groupby(‘用户ID’).sum()

group_user
在这里插入图片描述

group_user.describe()
在这里插入图片描述

  • 从用户角度看,每位用户平均购买7张单曲,最多的用户购买了1033张。用户的平均消费金额(客单价)106元,标准差是240, 106块的平均数不能代表整体水平.
  • 结合分位数和最大值看,平均值才和75分位接近,肯定存在小部分的高额消费用户,这也符合二八法则。

用户消费金额和消费次数的散点图

group_user[‘订单金额’]
用户ID
1 11.77
2 89.00
3 156.46
4 100.50
5 385.61

23566 36.00
23567 20.97
23568 121.70
23569 25.74
23570 94.08
Name: 订单金额, Length: 23570, dtype: float64
#看订单金额和订单数的关系
plt.figure(figsize=(10,8))
plt.scatter(group_user[‘订单金额’],group_user[‘订单数’])
plt.show()
在这里插入图片描述

#看看订单金额小于4000的
group_user.query(‘订单金额 < 4000’)[‘订单金额’]
用户ID
1 11.77
2 89.00
3 156.46
4 100.50
5 385.61

23566 36.00
23567 20.97
23568 121.70
23569 25.74
23570 94.08
Name: 订单金额, Length: 23558, dtype: float64
#看看订单金额小于4000的订单数
group_user.query(‘订单金额 < 4000’)[‘订单数’]
用户ID
1 1
2 6
3 16
4 7
5 29

23566 2
23567 1
23568 6
23569 2
23570 5
Name: 订单数, Length: 23558, dtype: int64
#看订单金额和订单数的关系
plt.figure(figsize=(10,8))
plt.scatter(group_user.query(‘订单金额 < 4000’)[‘订单金额’],group_user.query(‘订单金额 < 4000’)[‘订单数’])
plt.xlabel(“订单金额”)
plt.ylabel(“订单数”)
plt.show()
在这里插入图片描述

#查询条件:订单金额 < 4000 简便画图方式
group_user.query(‘订单金额 < 4000’).plot.scatter(x=‘订单金额’,y=‘订单数’)
在这里插入图片描述

  • 绘制用户的散点图,用户比较健康而且规律性很强,金额和商品量的关系也因此呈线性,没几个离群点。

用户消费金额的分布图(二八法则)

group_user[‘订单金额’].hist(bins = 20)
#bins = 20,就是分成20块,最高金额是14000,每个项就是700
plt.show()
在这里插入图片描述

  • 从图上看出,用户的消费呈集中趋势,可能是有个别的极大值干扰导致。
  • 可以排除极大值再看看分布情况

group_user.query(“订单金额< 800”)[‘订单金额’].hist(bins=20)
在这里插入图片描述

筛选出了消费金额小于800的用户,我们可以看到:

  • 大部分用户的消费能力并不高,将近半数的用户消费金额不超过40元,高消费用户( >200元 )不超过2000人。
  • 从上图直方图可知,大部分用户的消费能力确实不高,绝大部分呈现集中在很低的消费档次。高消费用户在图上几乎看不到,这也确实符合消费行为的行业规律。
  • 虽然有极端数据干扰,但是大部分的用户还是集中在比较低的消费档次。

用户消费次数的分布图(二八法则)

看看订单数小于100的直方分布图

group_user.query(‘订单数 < 100’)[‘订单数’].hist(bins = 40)
在这里插入图片描述

#看看购买订单小于100的订单直方分布图
group_user.query(‘订单数 < 100’)[‘订单数’].value_counts()
1 6809
2 3933
3 2425
4 1731
5 1314

84 1
91 1
93 1
80 1
94 1
Name: 订单数, Length: 96, dtype: int64

  • 大部分用户购买单曲的数量都是在3张以内,购买大量单曲的用户数量并不多。

用户消费周期分析

用户购买周期(按购买日期)

#list(df.groupby(‘用户ID’)[‘购买日期’]) 查看具体数据

userid_3_df = df.groupby(‘用户ID’).get_group(3) # size() get_group() groups

userid_3_df
在这里插入图片描述

userid_3_df[‘购买日期’]
3 1997-01-02
4 1997-03-30
5 1997-04-02
6 1997-11-15
7 1997-11-25
8 1998-05-28
Name: 购买日期, dtype: datetime64[ns]
userid_3_df[‘购买日期’].shift() # 新的知识点
3 NaT
4 1997-01-02
5 1997-03-30
6 1997-04-02
7 1997-11-15
8 1997-11-25
Name: 购买日期, dtype: datetime64[ns]
#通过shift方法进行移动 ,为了可以让两者相减 电商领域中一般计算时间的间隔非常有用
userid_3_df[‘购买日期’]- userid_3_df[‘购买日期’].shift()
3 NaT
4 87 days
5 3 days
6 227 days
7 10 days
8 184 days
Name: 购买日期, dtype: timedelta64[ns]

  • 可以理解为 , 1997-03-30 减去1997-01-02的天数 为 87天 , 1997-01-02也会去减 但是减掉的是 经过shift函数移动的nan值 , 所以就是NaT(时间类型的缺失值)

df.groupby(‘用户ID’).get_group(3)
在这里插入图片描述

#每个用户的每次购买时间间隔
def func(x):

return x['购买日期'] - x['购买日期'].shift()

order_diff = df.groupby(‘用户ID’).apply(func)

order_diff.head(10)
用户ID
1 0 NaT
2 1 NaT
2 0 days
3 3 NaT
4 87 days
5 3 days
6 227 days
7 10 days
8 184 days
4 9 NaT
Name: 购买日期, dtype: timedelta64[ns]
order_diff.describe()
count 46089
mean 68 days 23:22:13.567662
std 91 days 00:47:33.924168
min 0 days 00:00:00
25% 10 days 00:00:00
50% 31 days 00:00:00
75% 89 days 00:00:00
max 533 days 00:00:00
Name: 购买日期, dtype: object

  • 平均每个用户的购买时间间隔是68天,间隔最长的是533天。想要召回用户,在68天左右的消费间隔是比较好的。
  • 绝大部分用户的消费周期都低于100天(因为75%分位数)

用户消费周期分布

  • 删除缺失值(其实就是删除那些第一天购买的数据)

order_diff.dropna()
用户ID
2 2 0 days
3 4 87 days
5 3 days
6 227 days
7 10 days

23564 69648 57 days
69649 193 days
23568 69654 11 days
69655 17 days
23570 69658 1 days
Name: 购买日期, Length: 46089, dtype: timedelta64[ns]
#去除 days ******
(order_diff / np.timedelta64(1, ‘D’)).dropna()
用户ID
2 2 0.0
3 4 87.0
5 3.0
6 227.0
7 10.0

23564 69648 57.0
69649 193.0
23568 69654 11.0
69655 17.0
23570 69658 1.0
Name: 购买日期, Length: 46089, dtype: float64
plt.figure(figsize=(15,5))

绘制直方图

plt.hist((order_diff / np.timedelta64(1, ‘D’)).dropna(), bins = 50)

plt.xlabel(‘消费周期’,fontsize=24)
plt.ylabel(‘频数’,fontsize=24)
plt.title(‘用户消费周期分布图’,fontsize=24);
在这里插入图片描述

  • 大部分用户的消费间隔时间确实比较短。不妨将时间召回点设为消费后立即赠送优惠券,消费后10天询问用户礼品怎么样,消费后20天提醒优惠券到期,消费后30天短信推送。

用户生命周期(按第一次&最后一次消费)

orderdt_min=df.groupby(‘用户ID’)[‘购买日期’].min()#第一次消费
orderdt_max=df.groupby(‘用户ID’)[‘购买日期’].max()#最后一次消费

orderdt_max
用户ID
1 1997-01-01
2 1997-01-12
3 1998-05-28
4 1997-12-12
5 1998-01-03

23566 1997-03-25
23567 1997-03-25
23568 1997-04-22
23569 1997-03-25
23570 1997-03-26
Name: 购买日期, Length: 23570, dtype: datetime64[ns]
(orderdt_max-orderdt_min).head()
用户ID
1 0 days
2 0 days
3 511 days
4 345 days
5 367 days
Name: 购买日期, dtype: timedelta64[ns]
#计算用户的平均生命周期(用户平均134天会结束购买行为)
(orderdt_max-orderdt_min).mean()
Timedelta(‘134 days 20:55:36.987696’)

  • 所有用户的平均生命周期是134天,真的是这样吗 ? 接下来还是看一下分布情况。

(orderdt_max-orderdt_min).std()
Timedelta(‘180 days 13:46:43.039788’)
180/134 # 可以看到 平均值不可信 ! 不具有代表性
1.3432835820895523
#查看中位数
(orderdt_max-orderdt_min).median()
Timedelta(‘0 days 00:00:00’)

  • 中位数0天说明一半的人都是一锤子买卖, 我们看直方图

((orderdt_max-orderdt_min)/np.timedelta64(1,‘D’)).hist(bins=15)
#换算的方式直接除timedelta函数即可,np.timedelta64(1, ‘D’),D表示天,1表示1天,作为单位使用的。
#因为max-min已经表示为天了,两者相除就是周期
在这里插入图片描述

((orderdt_max-orderdt_min)/np.timedelta64(1,‘D’)).value_counts()
0.0 12054
1.0 76
7.0 65
8.0 56
13.0 54

544.0 2
543.0 1
541.0 1
531.0 1
540.0 1
Name: 购买日期, Length: 545, dtype: int64

  • 大部分用户只消费了一次,所有生命周期的大头都集中在了0天(当天消费,之后再也没有消费过,一锤子买卖)
  • 但这不是我们想要的答案,不妨将只消费了一次的新客排除,来计算所有消费过两次以上的老客的生命周期

#做成df形式
life_time = pd.DataFrame((orderdt_max - orderdt_min))

life_time.head()
在这里插入图片描述

#去除days 以后 形成新的列 life_time
life_time[‘life_time’] = life_time[‘购买日期’] / np.timedelta64(1,‘D’)

life_time.head()
在这里插入图片描述

#用户生命周期分布图
plt.figure(figsize=(12,6))
life_time[life_time[‘life_time’] > 0][‘life_time’].hist(bins = 70)
在这里插入图片描述

  • 上图可见,购买过至少两次的用户的分布 , 用户生命周期呈现双峰趋势,购买的天数在25天内生命周期的用户是一个高峰,400至500天内生命周期的用户是另一个高峰。
  • 根据此情况,应该在25天内对客户进行引导,促进其再次消费并形成消费习惯,延长其生命周期;在100至400天的用户,也要根据其特点推出有针对性的营销活动,引导其持续消费。

#去掉0天生命周期的用户之后的用户生命周期的平均值
life_time[life_time[‘life_time’] > 0][‘购买日期’].mean()
Timedelta(‘276 days 01:04:31.344216’)

  • 可见,若在用户首次消费后,加强对其再次消费的引导,可将其生命周期延长至原来的两倍。

用户分层(RFM模型)

在这里插入图片描述

  • 按用户价值分层—RFM模型
  • 为了进行精细化运营,可以利用RMF模型对用户价值指数(衡量历史到当前用户贡献的收益)进行计算,其中
  • 最近一次消费-R:客户最近一次交易时间的间隔,上一次消费时间离现在越近。即 R 值越小,用户的活跃度越大,用户的价值就越高
  • 消费频率-F:客户在最近一段时间内交易的次数。购买频率越高,说明用户对品牌产生一定的信任和情感维系。即 F 值越大,用户的忠诚度就越大,用户的价值就越高;
  • 消费金额-M:客户在最近一段时间内交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。
  • 根据上述三个维度,对客户做细分

注意 : 3 个指标针对的业务不同,定义也会有所不同
在这里插入图片描述
在这里插入图片描述

RFM的作用
在这里插入图片描述

df.head()
在这里插入图片描述

df.groupby(by=‘用户ID’)[‘购买日期’].get_group(3) # drona shift #
3 1997-01-02
4 1997-03-30
5 1997-04-02
6 1997-11-15
7 1997-11-25
8 1998-05-28
Name: 购买日期, dtype: datetime64[ns]
now_date = df[‘购买日期’].max()

now_date
Timestamp(‘1998-06-30 00:00:00’)
#计算R
R = df.groupby(by=‘用户ID’)[‘购买日期’].apply(lambda x:now_date - x.max())

R.head()
用户ID
1 545 days
2 534 days
3 33 days
4 200 days
5 178 days
Name: 购买日期, dtype: timedelta64[ns]
R.tail()
用户ID
23566 462 days
23567 462 days
23568 434 days
23569 462 days
23570 461 days
Name: 购买日期, dtype: timedelta64[ns]
#计算F
F = df.groupby(by=‘用户ID’)[‘购买日期’].count()

F.head()
用户ID
1 1
2 2
3 6
4 4
5 11
Name: 购买日期, dtype: int64
#计算M

M = df.groupby(by=‘用户ID’)[‘订单金额’].sum()

M.head()
用户ID
1 11.77
2 89.00
3 156.46
4 100.50
5 385.61
Name: 订单金额, dtype: float64
rfm = pd.DataFrame(
{
“R” : R,
“F” : F,
“M” : M
}
)

rfm
在这里插入图片描述

recent_avg = rfm[‘R’].mean()
freq_avg = rfm[‘F’].mean()
money_avg = rfm[‘M’].mean()

#将各维度分成两个程度

#R应该是越小越好,则R小于均值返回1,否则返回0
def rec_value(x):
if x < recent_avg: # R avg
return ‘1’
else:
return ‘0’

#F应该是越大越好,则F大于均值返回1,否则返回0
def freq_value(x):
if x > freq_avg:
return ‘1’
else:
return ‘0’

#M应该是越大越好,则M大于均值返回1,否则返回0
def money_value(x):
if x > money_avg:
return ‘1’
else:
return ‘0’

rfm[‘R_value’] = rfm[‘R’].apply(rec_value)
rfm[‘F_value’] = rfm[‘F’].apply(freq_value)
rfm[‘M_value’] = rfm[‘M’].apply(money_value)

#将R和F和M拼接到一起
rfm[‘rfm’]=rfm[‘R_value’].str.cat(rfm[‘F_value’]).str.cat(rfm[‘M_value’])

rfm
在这里插入图片描述

d = {
    '111': '重要价值客户',
    '011': '重要保持客户',
    '001': '重要挽留客户',
    '101': '重要发展客户',
    '110': '一般价值客户',
    '010': '一般保持客户',
    '000': '一般挽留客户',
    '100': '一般发展客户'
}

rfm[‘user_type’] = rfm[‘rfm’].map(d)
rfm
在这里插入图片描述

rfm[‘user_type’].value_counts()
一般挽留客户 13608
重要价值客户 4617
一般价值客户 1974
一般发展客户 1532
重要挽留客户 579
一般保持客户 543
重要保持客户 449
重要发展客户 268
Name: user_type, dtype: int64
rfm[‘user_type’].value_counts().plot(kind = “bar”)
plt.xticks(rotation = 45)
plt.show()
在这里插入图片描述

  • 以上为不同层次用户的消费人数,一般挽留客户的消费人数排名第一,有13608人,重要价值客户排名第二,有4617人,
  • 可以根据rfm的8种用户分层进行不一样的营销手段

用户质量分析

a = df.groupby(‘用户ID’)[‘购买日期’].agg([‘min’])
b = df.groupby(‘用户ID’)[‘购买日期’].agg([‘max’])

a
在这里插入图片描述

b
在这里插入图片描述

#b[‘max’] == a[‘min’] T F T 是 一锤子买卖 F 非一一锤子买卖

user_once_many = b[‘max’] == a[‘min’]

user_once_many.value_counts()
True 12054
False 11516
dtype: int64
plt.pie(x=user_once_many.value_counts(),
autopct=‘%.1f%%’,
shadow=True,
explode=[0.08, 0],
textprops={‘fontsize’: 11})
plt.axis(‘equal’)
plt.legend([‘仅消费一次’, ‘多次消费’])
plt.show()
在这里插入图片描述

  • 有超过一半的用户仅消费了一次,这也说明了运营不利,留存效果不好。

内容来自大数据分析课程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ak2111

你的鼓励将是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值