基于RFM模型用户价值分析(K-Means聚类)

1  项目背景

本次分析数据来源CDNow网站的用户在1997年1月1日至1998年6月30日期间内购买CD订单明细,对订单明细进行RFM模型的K-Means聚类分析并提出运营策略建议

2  数据探索

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

#读取数据
columns = ['用户ID','订单时间','订单数量','订单金额']
#命名表头
data = pd.read_table("CDNOW.txt",names = columns,sep = '\s+')
data.head()

#查看数据形状
data.shape
#数据类型和结构
data.info()

-- 每个数据一共4列,分别是用户ID、订单时间、订单数量、订单金额,数据类型都是数值型

3  数据预处理

3.1  重复值、缺失值、异常值

# 重复值查看
data.duplicated().value_counts()
#删除重复值
data=data.drop_duplicates()

-- 删除255个重复值

# 观察订单金额为0的值
data[data['订单金额']==0].describe()

-- 共有80个,订单数均为1,可能是未付款订单或免费活动,没有明显价值,可以剔除

data=data.drop(index=data[data['订单金额']==0].index)

3.2  数据类型调整

# 将订单时间转换为日期格式
data.订单时间=pd.to_datetime(data.订单时间,format = '%Y%m%d')
data.info()

3.3  数据准备

data.订单时间.describe(include='all')

-- 数据集的时间在1997-01-01到1998-06-30日,因此将此次观察日期定义为1998年6月30日

3.3.1  关键字段提取

RFM模型的定义:R为最近一次下单时间,F为购买频次,M为购买金额。提取所需要的字段信息:

#R
data['时间间隔']=pd.to_datetime('1998-06-30')-data.订单时间
data['时间间隔'] = data['时间间隔'].apply(lambda x:x.days) #去掉days
rfm = data.groupby(['用户ID']).agg({'时间间隔':'min','订单数量':'count','订单金额':'sum'})
rfm.head()

3.3.2  标准化处理

rfm = (rfm - rfm.mean(axis = 0))/(rfm.std(axis = 0)) # 处理后的数据均值为0,标准差为1
rfm.head()

#重置索引
rfm.reset_index(inplace=True)
#重命名列
rfm.columns = ['用户ID','R','F','M']
rfm.head()

-- 完成数据预处理

4  模型搭建和评估

利用K-means算法对客户进行聚类

结合业务,分析客户特征,分析客户价值

4.1  客户聚类

4.1.1  手肘法和轮廓系数找最优K

#手肘法,通过学习曲线看SSE的变化,找到一个明显的拐点,在该位置后SSE曲线趋于平缓
from sklearn.cluster import KMeans
sse = []
for i in range(2,10):  # 不同簇的个数
    km = KMeans(n_clusters=i).fit(rfm.loc[:,['R','F','M']])
    sse.append(km.inertia_)
plt.plot(range(2,10),sse,marker='o')

-- 在K=4、5的时候SSE曲线趋于平缓,再用轮廓系数看一下

from sklearn.metrics import silhouette_score
#轮廓系数:簇内差异小,簇外差异大
#越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似
score=[]
for i in range(2,10):
    km = KMeans(n_clusters=i).fit(rfm.loc[:,['R','F','M']])
    score.append(silhouette_score(rfm.loc[:,['R','F','M']],km.labels_))
plt.plot(range(2,10),score,marker='o') 

-- 选择最高点K=4进行聚类

4.1.2  数据聚类

n_clusters=4
#进行K=4的聚类
kmodel=KMeans(n_clusters=n_clusters).fit(rfm.loc[:,['R','F','M']])
kmodel

#查看质心
centroid=kmodel.cluster_centers_
centroid

#查看每个样本对应的类别
y_pred=kmodel.labels_
y_pred

#把类别添加到rfm表中
rfm['类别']=y_pred
rfm.head()

#查看各类别人数
rfm['类别'].value_counts()

4.2  客户分类可视化

#把类别人数和质心转换成表格形式,拼接在一起
r1 = pd.Series(y_pred).value_counts() #类别人数
r2 = pd.DataFrame(centroid) # 聚类中心
r = pd.concat([r2,r1],axis=1)
r.columns = list(rfm.loc[:,['R','F','M']]) + ['聚类个数']
r

# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['font.size'] = 12.0
plt.rcParams['axes.unicode_minus'] = False
# 所有簇中心坐标值中最大值和最小值
max = r2.values.max()
min = r2.values.min()
# 绘图
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, polar=True)
center_num = r.values
feature = ['最近一次消费时间-R',"消费频次-F", "消费金额-M"]
N = len(feature)
for i, v in enumerate(center_num):
    # 设置雷达图的角度,用于平分切开一个圆面
    angles = np.linspace(0, 2 * np.pi, N, endpoint=False)
    # 为了使雷达图一圈封闭起来,需要下面的步骤
    center = np.concatenate((v[:-1], [v[0]]))
    angles = np.concatenate((angles, [angles[0]]))
    # 绘制折线图
    ax.plot(angles, center, 'o-', linewidth=2, label="第%d类人群,%d人" % (i + 1, v[-1]))
    # 填充颜色
    ax.fill(angles, center, alpha=0.25)
    # 添加每个特征的标签
    ax.set_thetagrids(angles * 180 / np.pi, feature, fontsize=15)
    # 设置雷达图的范围
    ax.set_ylim(min - 0.1, max + 0.1)
    # 添加标题
    plt.title('客户群特征分析图', fontsize=20)
    # 添加网格线
    ax.grid(True)
    # 设置图例
    plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0), ncol=1, fancybox=True, shadow=True)

# 显示图形
plt.show()

5  客户价值分析

R:最近消费时间 F:消费频次 M:消费金额

经分析,把客户群体分为以下4类:

第1类人群:占比28.73%,RMF三个值都比较低,属于低价值用户

第2类人群:占比3.6%,F和M较高,R低,属于重要保持用户

第3类人群:占比67.52%(最多),R值较高,属于一般发展用户

第4类人群:只有22人,F和M特别高,R低,属于高价值的重要保持用户

用户特点及策略:

(1)重要保持用户:

消费次数(F)和消费金额(M)高,最近消费时间(R)低

是公司的高价值用户,对公司贡献最大,所占比例小,主要目标是促进提高满意度,延长用户生命周期。可采取个性化营销,如设计VIP服务、提供高质量产品、与客户互动了解情况等,促进用户回流。

(2)重要发展用户: 消费次数(F)和消费金额(M)低,最近消费时间(R)高

此类客户当前价值不高,但是所在比例最大,有发展潜力,主要目标是提升其购买频次和金额,可采取交叉销售、个性化推荐、组合优惠券等策略,提升单次购买的订单金额及促进重复购买。

(3)低价值用户:

消费次数(F)、消费金额(M)和最近消费时间(R)三个值都低

此类用户优先级最低,可能在打折促销、打造爆款时会进行购买。

小结:各类别用户都明显出现R值低的情况,说明用户留存较低,结合业务场景(CDNow在线CD零售平台),属于用户消费频次高的场景,应引起重视,找到产品问题,提高用户留存,培养用户忠诚度

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342