时间:2023-02-07 09:48:08 | 栏目:Python代码 | 点击:次
本文实例讲述了Python pandas RFM模型应用。分享给大家供大家参考,具体如下:
根据美国数据库营销研究所Arthur Hughes的研究,客户数据库中有3个神奇的要素,这3个要素构成了数据分析最好的指标:
RFM模型的应用是有前提假设的,即R、F、M值越大价值越大,客户未来的为企业带来的价值越大。这个前提假
设其实已经经过大量的研究和实证,假设是成立的。不过为了更加严谨,确保RFM模型对于特殊案例是有效的,
本文还进行了前提假设验证:
ps:Frequency、Monetary均为近6个月内的数据,即1-6月数据;
利用相关性检验,验证假设:
简单的做法,RFM三个指标以均值来划分,高于均值的为高价值、低于均值的为低价值,如此可以将客户划分为8大类:
本文采取的方法是将三个指标进行标准化,然后按照分为数划分为5个等级,数值越大代表价值越高;当然最终划分的规则还是要结合业务来定。划分为5个等级后,客户可以细分为125种。
#读取数据 rfm<-read.csv('~/desktop/rfm1_7.csv',header=TRUE) summary(rfm) #数据分布 par(mfrow=c(1,3)) boxplot(rfm$rankR1) boxplot(rfm$rankF1) boxplot(rfm$rankM1) #rfm分级 breaks1<-quantile(rfm$Recency, probs = seq(0, 1, 0.2),names = FALSE) breaks1<-c(1,14,30,57,111,181) #以流失用户的定义来设置分级 30天以上为流失用户 breaks2<-quantile(rfm$Frequency, probs = seq(0, 1, 0.2),names = FALSE) breaks2<-c(1,2,3,6,14,164) breaks3<-quantile(rfm$Monetary, probs = seq(0, 1, 0.2),names = FALSE) rfm$rankR1<- cut(rfm$Recency,breaks1, 5,labels=F) rfm$rankR1<- 6-rfm$rankR1 rfm$rankF1<- cut(rfm$Frequency,breaks2, 5,labels=F) rfm$rankM1<- cut(rfm$Monetary,breaks3, 5,labels=F)
本文采用K-means聚类进行分类,聚类结果结合业务划分为4大类:
k值选择:
聚类结果:
#聚类 df<-rfm[,c(6,7,8)] p1<-fviz_nbclust(df, kmeans, method = "wss") p2<-p1 + geom_vline(xintercept = 5, linetype = 2) km_result <- kmeans(df, 5) dd <- cbind(rfm,df, cluster = km_result$cluster) ##查看每一类的数目 table(dd$cluster) picture<-fviz_cluster(km_result, df, geom = "point") ####聚类结果解释#### rfm_final <- within(dd,{Custom = NA Custom[cluster == 1] = '高价值客户' Custom[cluster == 2 ] = '无价值客户' Custom[ cluster == 3] = '无价值客户' Custom[cluster == 4] = '重点发展客户' Custom[cluster == 5] = '重点挽留客户' })
步骤3,我们将客户划分为四大类,其实如果一类客户中还有大量的客户,此时为了精细化营销,可以根据RFM进行加权打分,给出一个综合价值的分。这里,运用AHP层次分析法确定RFM各指标权重:
客户价值RFM_SCORE= 0.25rankR + 0.20rankF+0.55*rankM
AHP层次分析法(专家打分法)
上述客户分类其实比较粗旷,真正在面对千万级客户量时,如此划分为四大类是难以满足运营需求的。运营中,还需要综合CRM中其他指标、维度。
ps:后续作者利用RFM客户价值得分进行潜在客户挖掘,尝试利用决策树等模型挖掘平台潜在客户特征。
import pandas as pd import numpy as np import time #todo 读取数据 data = pd.read_csv('RFM_TRAD_FLOW.csv',encoding='gbk') # print(ret) # todo RFM------>R(最近一次消费) #todo 时间与字符串相互转换 data['time'] = data['time'].map(lambda x:time.mktime(time.strptime(x,'%d%b%y:%H:%M:%S'))) # print(data) # todo 分组 groupby_obj = data.groupby(['cumid','type']) # for name,data in groupby_obj: # print(name) # print(data) # todo 取值 R = groupby_obj[['time']].max() # print( # todo 转为透视表 r_trans = pd.pivot_table(R,index='cumid',columns='type',values='time') # print(data_trans) # todo 替换缺失值 有缺失值,替换成最远的值 r_trans[['Special_offer','returned_goods']] = r_trans[['Special_offer','returned_goods']].apply(lambda x:x.replace(np.nan,min(x)),axis = 0) # print(data_trans) r_trans['r_max'] = r_trans.apply(lambda x:sum(x),axis=1) # print(r_trans) # todo RFM------>F(消费频率) # 取值 F =groupby_obj[['transID']].count() # print(F) #转为透视表 f_trans = pd.pivot_table(F,index='cumid',columns='type',values='transID') # print(f_trans) #替换缺失值 f_trans[['Special_offer','returned_goods']]= f_trans[['Special_offer','returned_goods']].fillna(0) # print(f_trans) # f_trans['returned_goods'] = f_trans['returned_goods'].map(lambda x:-x) # print(f_trans) f_trans['f_total'] = f_trans.apply(lambda x:sum(x),axis=1) # print(f_trans) # todo RFM------>M(消费金额) # 取值 M =groupby_obj[['amount']].sum() # print(M) #转为透视表 m_trans = pd.pivot_table(M,index='cumid',columns='type',values='amount') # print(f_trans) #替换缺失值 m_trans[['Special_offer','returned_goods']]= m_trans[['Special_offer','returned_goods']].fillna(0) # print(f_trans) # m_trans['m_total'] = m_trans.apply(lambda x:sum(x),axis=1) # print(m_trans) # 合并 RFM=pd.concat([r_trans["r_max"],f_trans['f_total'],m_trans['m_total']],axis=1) print(RFM) r_score = pd.cut(RFM.r_max,3,labels=[0,1,2]) f_score = pd.cut(RFM.r_max,3,labels=[0,1,2]) m_score = pd.cut(RFM.r_max,3,labels=[0,1,2])
关于Python相关内容感兴趣的读者可查看本站专题:《Python函数使用技巧总结》、《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。