首页 > 技术文章 > RFM客户价值分类

mschen 2019-10-06 20:50 原文

 

  1 # 自定义好的包,亲测可用 原数据和代码思想来自以下网址
  2 # https://github.com/joaolcorreia/RFM-analysis
  3 import datetime as dt
  4 import pandas as pd
  5 def RFM(data_,ri_qi,user_id,money,*time_):
  6     '''
  7     return:
  8         dataframe表格
  9         列有r,f,m,r_四分位分数,f_四分位分数,m_四分位分数,RFM,用户分类
 10         行为用户id,唯一,分类汇总后
 11     desc:
 12         如 : RFM(orders,'order_date','customer','grand_total',2018,1,2)
 13         返回df数据会复制到粘贴板
 14     params:
 15         data_ : 表格数据 pandas dataframe (表格中的字段名)
 16         ri_qi : 订单日期  (表格中的字段名)
 17         user_id : 用户id  (表格中的字段名)
 18         money : 消费金额  (表格中的字段名)
 19        *time_ : 不定长参数  不写默认当天
 20             
 21     '''
 22     
 23     # 设置参考时间点,无参数则默认为当天
 24     if time_ == ():
 25         NOW = dt.datetime.now()
 26     else:
 27         y,m,d = time_
 28         NOW = dt.datetime(y,m,d)
 29  
 30     # 日期列进行格式转换
 31     data_[ri_qi] = pd.to_datetime(data_[ri_qi])
 32  
 33     # 创建RFM标签
 34     rfmTable = data_.groupby(user_id).agg({ri_qi: lambda x: (NOW - x.max()).days, # Recency 顾客最近一次购买距今天数(days)
 35                                             'order_id': lambda x: len(x),      # Frequency 按顾客分组后次数,即顾客订单频次
 36                                             money: lambda x: x.sum()}) # Monetary Value 顾客消费金额总和
 37     # 日期列转换数据类型
 38     rfmTable[ri_qi] = rfmTable[ri_qi].astype(int)
 39     # 列名重命名
 40     rfmTable.rename(columns={ri_qi: 'recency', 
 41                              'order_id': 'frequency', 
 42                              money: 'monetary_value'}, inplace=True)
 43  
 44     # 确定RFM四分位数
 45     quantiles = rfmTable.quantile(q=[0.25,0.5,0.75])
 46     quantiles = quantiles.to_dict()
 47  
 48     # 创建RFM分割表
 49     rfmSegmentation = rfmTable.copy(deep=True)
 50     # Arguments (x = value, p = recency, monetary_value, frequency, k = quartiles dict)
 51     # 日期间隔越小越好
 52     def RClass(x,p,d):
 53         # p,d = args = ('recency',quantiles,)  
 54         # x即rfmSegmentation['recency'].apply(RClass) 日期间隔数据 
 55         if x <= d[p][0.25]:
 56             return 1
 57         elif x <= d[p][0.50]:
 58             return 2
 59         elif x <= d[p][0.75]: 
 60             return 3
 61         else:
 62             return 4
 63         
 64     # Arguments (x = value, p = recency, monetary_value, frequency, k = quartiles dict)
 65     # 消费频次和金额越大越好
 66     # 分数范围1-4
 67     def FMClass(x,p,d):
 68         if x <= d[p][0.25]:
 69             return 4
 70         elif x <= d[p][0.50]:
 71             return 3
 72         elif x <= d[p][0.75]: 
 73             return 2
 74         else:
 75             return 1
 76  
 77  
 78     # 评分应用 R F M
 79     rfmSegmentation['R_Quartile'] = rfmSegmentation['recency'].apply(RClass, args=('recency',quantiles,))
 80     rfmSegmentation['F_Quartile'] = rfmSegmentation['frequency'].apply(FMClass, args=('frequency',quantiles,))
 81     rfmSegmentation['M_Quartile'] = rfmSegmentation['monetary_value'].apply(FMClass, args=('monetary_value',quantiles,))
 82  
 83     # 评分应用 RFMClass 
 84     rfmSegmentation['RFMClass'] = rfmSegmentation.R_Quartile.map(str) \
 85                             + rfmSegmentation.F_Quartile.map(str) \
 86                             + rfmSegmentation.M_Quartile.map(str)
 87  
 88  
 89     def type_(x,R,F,M):
 90         '''
 91         r,f,m即每行的r,f,m分值
 92         '''
 93         r,f,m = x[R],x[F],x[M]
 94         if r > 2 and f > 2 and m > 2:
 95             return '高价值客户'
 96         elif r <= 2 and f > 2 and m > 2:
 97             return '高重点保护客户'
 98         elif r > 2 and f <= 2 and m > 2:
 99             return '重点发展客户'
100         elif r <= 2 and f <= 2 and m > 2:
101             return '重点挽留客户'
102         elif r > 2 and f > 2 and m <= 2:
103             return '一般价值客户'
104         elif r <= 2 and f > 2 and m <= 2:
105             return '一般保持客户'
106         elif r > 2 and f <= 2 and m <= 2:
107             return '一般发展客户'
108         elif r <= 2 and f <= 2 and m <= 2:
109             return '潜在客户'
110         else:
111             return 
112     
113     rfmSegmentation['type_'] = rfmSegmentation.apply(type_,args=('R_Quartile','F_Quartile','M_Quartile'),axis=1)
114     rfmSegmentation.to_clipboard() # 数据复制到  粘贴板
115     return rfmSegmentation

 

 

调用函数处理后:

推荐阅读