1 背景与目标
1.1 背景
在面向客户制定运营策略、营销策略时,我们希望能够针对不同的客户推行不同的策略,实现精准化运营,以期获取最大的转化率。精准化运营的前提是客户关系管理,而客户关系管理的核心是客户分类。通过客户分类,对客户群体进行细分,区别出低价值客户、高价值客户,对不同的客户群体开展不同的个性化服务,将有限的资源合理地分配给不同价值的客户,实现效益最大化。
在客户分类中,RFM模型是一个经典的分类模型,模型利用通用交易环节中最核心的三个维度——最近消费(Recency)、消费频率(Frequency)、消费金额(Monetary)细分客户群体,从而分析不同群体的客户价值。
1.2 目标
本实例借助Kaggle数据集,探讨如何利用KMeans算法对客户群体进行细分,以及细分后如何利用RFM模型对客户价值进行分析,并识别出高价值客户。
数据源:Online Retail Data Set from UCI ML repo
2 分析过程
2.1 分析思路
本实例的数据包含了2010年12月1日至2011年12月9日期间的客户数据,共有54万余条记录。分析中需要用到KMeans算法,且需要将数据分析的结果可视化,便于后期的结论分析,于是采用以下两种工具进行分析:
- jupyter notebook(Python 3.7 )
- Excel 2016
同时数据的属性定义见下表所示,可见维度非常丰富。
2.2 数据预处理
2.2.1 数据探索
#导入所需分析包
import numpy as np
import pandas as pd
import datetime as dt
from sklearn.cluster import KMeans
#导入数据集
df = pd.read_excel(r"C:UsersDesktopsaleinfo.xlsx")
df.info() #获取数据集信息
df.head() #预览数据集
由此可以看到本数据集存在重复值和缺失值,对此采取删除的方法去除。
2.2.2 数据清洗
#删除重复值
df_NoDup=df.drop_duplicates(subset=['InvoiceNo','StockCode','Description','Quantity','InvoiceDate','UnitPrice','CustomerID','Country'])
dup=df.shape[0]-df_NoDup.shape[0]
print('duplicates =',dup)
#删除缺失值
df_NoDupNA=df_NoDup.dropna(subset=['InvoiceNo','CustomerID'],how='any')
missing=df_NoDup.shape[0]-df_NoDupNA.shape[0]
print('missings =',missing)
#检查有无异常值
df_NoDupNA.describe()
从上图中可以发现,Quantity最小值为-80995,由常理可知,销量和售价应该都大于0,所以进行删除异常值的操作。
#删除异常值
df_NoDupNA=df_NoDupNA[(df_NoDupNA['Quantity']>0) & (df_NoDupNA['UnitPrice']>0)]
df_NoDupNA.describe()
此时,完成数据的预处理工作,原数据集还有392692条记录。
2.2.3 属性规约
根据RFM模型,选取与模型相关的字段'InvoiceNo','Quantity','InvoiceDate','UnitPrice','CustomerID',进行RFM计算。
- R = LAST_TO_END. (最后一次消费时间至观测窗口结束天数)
- F = FLIGHT_COUNT. (观测窗口内的购买次数)
- M = SEG_KM_SUM. (观测窗口的总消费)
#计算R和F
df = df_NoDupNA
df['TotalSum'] = df['UnitPrice']* df['Quantity']
print('Min Invoice Date:',df.InvoiceDate.dt.date.min(),'max Invoice Date:',
df.InvoiceDate.dt.date.max())
df.head()
snapshot_date = df['InvoiceDate'].max() + dt.timedelta(days=1)
snapshot_date
rfm = df.groupby(['CustomerID']).agg({'InvoiceDate': lambda x : (snapshot_date - x.max()).days,
'InvoiceNo':'count','TotalSum': 'sum'}).reset_index()
rfm.rename(columns={'InvoiceDate':'R','InvoiceNo':'F','TotalSum':'M'}
,inplace= True)
rfm = rfm.drop(["CustomerID"],axis=1)
rfm.head()
从表中可以发现,每个指标的数据取值范围分布较广,为提高后续聚类分析的准确性,还需要将R、F、M三类数据进行标准化处理。标准化方法有极大极小标准化、标准差标准化等方法,此处采用标准差标准化的方法对数据进行处理。
dataZscore = (rfm - rfm.mean(axis=0)) / rfm.std(axis=0)
dataZscore.columns = ['Z' + i for i in rfm.columns]
dataZscore.head()
2.3 数据建模
客户价值分析模型构建主要分为两个部分:
- 利用K-Means算法对客户进行聚类分析,得到细分的客户群
- 对细分的客户群进行特征分析,得到客户价值分析模型
2.3.1 聚类分析
采用K-Means聚类算法对客户数据进行分群,共分为3类。
from sklearn.cluster import KMeans
k = 3 # 共分为3类
kmodel = KMeans(n_clusters = k, n_jobs = 4)
kmodel.fit(dataZscore)
#转化为DataFrame对象
kmodel.cluster_centers_
kmodel.labels_
kmeansCenters = pd.DataFrame(kmodel.cluster_centers_, columns = dataZscore.columns)
labelsCounts = pd.DataFrame(kmodel.labels_)[0].value_counts()
kmeansLabels = pd.DataFrame(labelsCounts, index = None)
kmeansLabels.columns = ['Num']
kmeansResult = pd.concat([kmeansCenters, kmeansLabels], axis=1)
kmeansResult['Class'] = [1,2,3]
kmeansResult = kmeansResult[['Class','Num','ZR', 'ZF', 'ZM']]
2.3.2 特征分析
对2.3.2中的聚类结果进行特征分析,如下图所示。
分析:
- 群体1的R属性上最大
- 群体2的R、M、F属性均排在第二位
- 群体3的M、F属性最大,R属性最小
其中每项指标的实际业务意义为:
- R:最近一次消费时间,越大代表越久没消费
- F:消费次数,越大代表消费次数越多
- M:消费总额,越大代表消费总额越多
3 分析结果
由此,可以推断出群体3是我们所寻找的金牌客户,公司应优先将资源投放到他们身上,维持这类客户的忠诚度;群体2则是我们的大众客户,此类客户我们可以采取折扣促销等营销活动,促进他们的消费;群体3则是低价值客户,需要根据他们的收入以及生活习惯针对性的提供生活必需品类的商品。