RFM模型是“R”--recency(最近一次消费时间)、“F”--frequency(一定时期内的消费频率)、“M”--(一定时期内的总消费)。这三个指标可以把我们的用户分成不同的档次和层次。目的是衡量他们的用户价值,让他们更精准地把成本和精力花在更精准的用户层面上。一个典型的例子就是,为一个明显不愿意流失的用户继续推送其核心产品,费时费力且成本高昂。
2.如何用Python建立RFM模型RFM模型,虽然有“模型”这个词在里面,但实际上它根本不需要任何算法支持,和数据建模中的逻辑回归、聚类分析是完全不同的概念。因此,实现RFM的工具和方法有很多:SQL、Excel、R等。都能做到,当然Python也不例外。RFM模型的核心是对三个指标进行标注,然后根据场景的实际业务需求进行分层。在下面的文章中,我将用一个简单的例子通过代码实现RFM模型的建立。
2.1数据导入链接:https://pan.baidu.com/s/1YbZrdsg2dOoe_5lylTwhQw提现代码:nf2f数据是某电商SKU2018年的一份销售表格。只有四个字段,但足以建立一个RFM模型。
importosimportnumpyasnpimportpandasaspdimportseabornassnsimportmatplotlib.pyplotasplt%matplotlibinlineplt.rcParams['font.serif']=['SimHei']plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsesns.set_style('ticks',{'font.sans-serif':['simhei','DroidSansFallback']}) 2.2数据清洗 df=pd.read_csv('sale.csv')df.drop_duplicates(subset=['ORDERID'],keep='first',inplace=True)df.dtypes dtypes.png您可以看到我们的字段的数据类型,并注意到ORDERDATE是一个字符串类型,而不是一个时间Datetime类型,它需要在以后进行转换。其他字段正常。
df[df.isna().values==True]df=df.dropna(how='any',axis=0) 查看空值.png可以看出,以上部分数据有空值。由于RFM不能通过空值计算,因此直接删除。
plt.figure(figsize=(10,5))sns.distplot(df.AMOUNTINFO) 数据整体分布.png通过直方图,我们可以清楚地看到数据的整体分布,呈偏态分布,但没有负值,所以不需要处理离群值。>:0的值是合理的。
df['ORDERDATE']=pd.to_datetime(df['ORDERDATE'])df['Datediff']=(pd.to_datetime('today')-df['ORDERDATE']).dt.daysdf 添加一列R.png数据的最终处理是将ORDERDATE转换为Datetime时间类型,并添加一个时差列表作为“R”的计算索引。
2.3数据分析 R_Agg=df.groupby(by=['USERID'])['Datediff']R_Agg=R_Agg.agg([('最近一次消费','min')])F_Agg=df.groupby(by=['USERID'])['ORDERID']F_Agg=F_Agg.agg([('2018年消费频次','count')])M_Agg=df.groupby(by=['USERID'])['AMOUNTINFO']M_Agg=M_Agg.agg([('2018年消费金额',sum)])rfm=R_Agg.join(F_Agg).join(M_Agg)rfm上面的步骤是计算R,F,M模型中的三个指标:R,F,M,并合并到一个新表中,如下图所示:
RFM表1.png然后就是最关键的一步。通过pd.cut的方法,对用户进行分层和标签化。我在这里使用的分层方法是python中的分位数函数。因为我们之前的直方图显示的是偏态分布,所以取平均值到层的误差会很大。这时候选择分位数分层比较好。
defrfm_convert(x):rfm_dict={0:'R',2:'M'}try:foriinrange(0,3,2):bins=x.iloc[:,i].quantile(q=np.linspace(0,1,num=6),interpolation='nearest')ifi==0:labels=np.arange(5,0,-1)else:labels=np.arange(1,6)x[rfm_dict[i]]=pd.cut(x.iloc[:,i],bins=bins,labels=labels,include_lowest=True)exceptExceptionase:print(e)rfm_convert(rfm)上述函数的目的是按照1-5的尺度对R和M进行标注,对用户进行分层。但由于F的值大多集中在1,即消费的频率只有一次,所以无法用分位数法来平均划分五个等级。因此,我会用其他方式给它贴标签:
bins=[1,3,5,12]labels=np.arange(1,4)rfm['F']=pd.cut(rfm['2018年消费频次'],bins=bins,labels=labels,include_lowest=True)rfm.insert(4,'F',rfm.pop('F'))rfmF的分层是我手动区分的。由于RFM模型本身是根据不同的场景和业务需求建立的,所以我在这里根据数据的实际分布情况手动分层F。
RFM表2.png好了,现在RFM模型有了原型,最后要做的就是给它贴上标签:
rfm_model=rfm.filter(items=['R','F','M'])defrfm(x):returnx.iloc[0]*3+x.iloc[1]+x.iloc[2]*3rfm_model['RFM']=rfm_model.apply(rfm,axis=1)bins=rfm_model.RFM.quantile(q=np.linspace(0,1,num=9),interpolation='nearest')labels=['流失客户','一般维持客户','新客户','潜力客户','重要挽留客户','重要深耕客户','重要唤回客户','重要价值客户']rfm_model['LabelofCustomer']=pd.cut(rfm_model.RFM,bins=bins,labels=labels,include_lowest=True)rfm_model RFM表3.png这里的R,F,M分数是根据具体的场景和业务来加权的。这里我给出的权重比是3:1:3,所以实际上没必要用这个加权分数,完全按照个体R,F,M来标注,比如R>;=4、F>1、M>=4,核心用户。
4.数据可视化以上是RFM模型,所以有了模型,我们可以直观的看到各个层面的用户分布和用户价值:
frompyecharts.chartsimportGrid,Pie,Barfrompyechartsimportoptionsasoptstmp=rfm_model.groupby('LabelofCustomer').size()t=[list(z)forzinzip(tmp.index.values,tmp.values)]#绘制饼图pie=(Pie().add('',t,radius=['30%','75%'],rosetype='radius',label_opts=opts.LabelOpts(is_show=True)).set_global_opts(title_opts=opts.TitleOpts(title='消费者分层结构',pos_left='center'),toolbox_opts=opts.ToolboxOpts(is_show=True),legend_opts=opts.LegendOpts(orient='vertical',pos_right='2%',pos_top='30%')).set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{d}%')))pie.render_notebook() 消费者分层结构.png可见,无价值的流失客户占了很大一部分,但同时也要注意,新客户的比例是相当大的。但是,只看比例是没有意义的,因为我们的最终目的是盈利。所以,我们来看看,基于消费金额的分布,我们实际上应该对哪些层次的用户进行精准投放:
consumer_r=df.groupby('USERID').AMOUNTINFO.agg([('消费总额',sum)])new_rfm=rfm_model.join(consumer_r)filter_list=['流失客户','新客户','重要挽留客户','重要价值客户']new_rfm=new_rfm[new_rfm['LabelofCustomer'].astype('<U').isin(filter_list)]new_rfm['LabelofCustomer']=new_rfm['LabelofCustomer'].astype('<U')tmp=new_rfm.groupby('LabelofCustomer').消费总额.sum()tmp=tmp.sort_values()frompyecharts.chartsimportBaryindex=[]foriinlist(tmp.values):yindex.append(int(i))#绘制柱状图bar=(Bar(init_opts=opts.InitOpts(theme='white',bg_color='papayawhip')).add_xaxis(list(tmp.index.values)).add_yaxis('消费者分层',yindex,color='lightcoral',category_gap='70%').set_global_opts(title_opts=opts.TitleOpts(title='不同分层消费者2018年消费总额',pos_left='center',title_textstyle_opts=opts.TextStyleOpts(color='lightcoral')),legend_opts=opts.LegendOpts(pos_top='bottom'),toolbox_opts=opts.ToolboxOpts(is_show=True),yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter='{value}'))))bar.render_notebook() 不同分层消费者2018年消费总额.png结合上面的饼状图,我们最终可以得出结论,虽然新客户占比最大,但是他们的实际贡献并不高,所以不需要在新业务上花费太多的心思和精力,而应该把重点放在“留住”和“变现”运营上。如何留住作为核心收入来源的“重要价值用户”,并通过用户达成的各种方式召回“重要留存客户”是关键问题。
5.总结通过上述RFM模型的建立和可视化,我们其实可以发现,通过对用户的精准分层,可以对用户价值有更直观的感受,从而对互联网产品的运营起到点对点的服务作用。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)