# -*- coding: utf-8 -*- #1. 概念:RFM分析是根据客户活跃程度和交易金额贡献,进行客户价值细分的一种方法. #R(Recency):近度,客户最近一次交易时间的间隔。R越大,表示客户越久未发生交易,R越小,表示客户越近有交易发生 #F(Frequency):频度,客户在最近一段时间内交易的次数。F越大,表示客户交易越平凡,F越小,表示客户不够活跃 #M(Monetary):额度,客户在最近一段时间内交易的金额。M越大,表示客户价值越高,M越小,表示客户价值越低
#2. RFM分析过程 #2.1 计算RFM各项分值 #R_S,距离当前日期越近,得分越高,最高5分,最低1分 #F_S,交易频率越高,得分越高,最高5分,最低1分 #M_S,交易金额越高,得分越高,最高5分,最低1分
#2.2 汇总RFM分值 #RFM = 100*R_S + 10*F_S + 1*M_S (业务专家得出的结论,可以看出不同项的权重不一样)
#2.3 根据RFM分值对客户分类
#3. RFM分析前提 #3.1 最近有过交易行为的客户,再次发生交易的可能性要高于最近没有交易行为的客户; #3.2 交易频率较高的客户比交易频率较低的客户,更有可能再次发生交易行为; #3.3 过去所有交易总金额较多的客户,比交易总金额较少的客户,更有消费积极性
#python中没有计算RFM的包,因为我们需要手工实现
import numpy import pandas
data = pandas.read_csv("D:/workspaces/python/pythonStudy/30.csv")
#30.csv包括列:OrderID、CustomerID、DealDateTime成交日期、Sales订单金额,下载地址:pan.baidu.com/s/1vIFHvVRH… #计算最近一次消费距离今天的距离: data['DealDateTime'] = pandas.to_datetime( data.DealDateTime, format='%Y/%m/%d' )
data['DateDiff'] = pandas.to_datetime( 'today' ) - data['DealDateTime']
#得到每笔交易记录距离当前日期的天数 data['DateDiff'] = data['DateDiff'].dt.days
#得到每个用户的最近一笔交易距离今天的日期天数(使用用户id进行分组,然后得到订单距离当前日期的最小值) R_Agg = data.groupby( by=['CustomerID'] )['DateDiff'].agg({ 'RecencyAgg':numpy.min }) #距离计算结束
#计算每个用户的交易订单数量(使用用户id进行分组,然后得到每个分组的记录数量) F_Agg = data.groupby( by=['CustomerID'] )['OrderID'].agg({ 'FrequencyAgg':numpy.size })
#计算每个用户的消费总额(使用用户id进行分组,然后对订单金额进行求和) M_Agg = data.groupby( by=['CustomerID'] )['Sales'].agg({ 'MonetaryAgg':numpy.sum })
#将三个数据整合起来: aggData = R_Agg.join(F_Agg).join(M_Agg) #得到了一个新的数据框,包含三列
#对aggData的每个列都需要进行对应的排序分组,为每个组给一个得分值(1-5分)
#计算R得分情况: #计算各分位值,用于确定分组界限 bins = aggData.RecencyAgg.quantile( q = [0,0.2,0.4,0.6,0.8,1],#将0-1分位5部分 interpolation='nearest' )
bins[0] = 0 #避免最小值不闭合的错误,将最小值设置为0 labels = [5,4,3,2,1] #定义每个区间的得分,以标签的形式实现。近度越小,得分越高 R_S = pandas.cut( aggData.RecencyAgg, bins, labels = labels ) #计算F得分情况: bins = aggData.FrequencyAgg.quantile( q = [0,0.2,0.4,0.6,0.8,1],#将0-1分位5部分 interpolation='nearest' ) bins[0] = 0 labels = [1,2,3,4,5] #频率越高,得分越高 F_S = pandas.cut( aggData.FrequencyAgg, bins, labels = labels )
#计算M得分情况: bins = aggData.MonetaryAgg.quantile( q = [0,0.2,0.4,0.6,0.8,1],#将0-1分位5部分 interpolation='nearest' ) bins[0] = 0 labels = [1,2,3,4,5] #额度越高,得分越高 M_S = pandas.cut( aggData.MonetaryAgg, bins, labels = labels )
#将各得分值作为新的列赋值回去 aggData['R_S'] = R_S aggData['F_S'] = F_S aggData['M_S'] = M_S
#根据RFM的经验公式计算RFM的值 aggData['RFM'] = 100*R_S.astype(int) + 10*F_S.astype(int)+1*M_S.astype(int)
#将用户分为8类 #计算分位值,值越大,表示用户越重要 bins = aggData.RFM.quantile( q = [0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1], interpolation='nearest' ) bins[0] = 0 labels = [1,2,3,4,5,6,7,8] aggData['level'] = pandas.cut( aggData.RFM, bins, labels = labels )
#验证每种用户大概是如何分布的: aggData = aggData.reset_index() #重置行索引(从0开始),之前的索引列变为CustomerID
aggData.sort( ['level','RFM'], ascending=[1,1] )
#观察每个level的用户的数量: aggData.groupby( by = ['level'] )['CustomerID'].agg({ 'size':numpy.size })
|
|