python笔记30:数据分析之RFM分析

# -*- 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订单金额,下载地址:https://pan.baidu.com/s/1vIFHvVRHXNr_gCmOpns8Tg
#计算最近一次消费距离今天的距离:
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
                })

猜你喜欢

转载自blog.csdn.net/aiyo92/article/details/87181776