RFM2

RFM

1. 导入数据

import pandas as pd
import numpy as np
trad_flow = pd.read_csv('RFM_TRAD_FLOW.csv', encoding='gbk')
trad_flow.head()
transIDcumidtimeamounttype_labeltype
0233511000627SEP09:20:10:2258.0特价Special_offer
1233723003127SEP09:21:33:3569.0特价Special_offer
2234474010228SEP09:21:12:3469.0特价Special_offer
3234482017328SEP09:21:12:3469.0特价Special_offer
4234494001728SEP09:21:13:4869.0特价Special_offer

2.计算 RFM

import time

# 先将非标准字符串时间格式化为时间数组,再转换为时间戳便于计算
trad_flow['time'] = trad_flow['time'].map(lambda x: time.mktime(time.strptime(x, '%d%b%y:%H:%M:%S')))

# 查找每个购物ID每个销售类型下的最近时间
R=trad_flow.groupby(['cumid','type'])[['time']].max()

# 转化为透视表
R_trans=pd.pivot_table(R,index='cumid',columns='type',values='time')

# 用最久远的购物时间替换缺失值
R_trans[['Special_offer','returned_goods']] = R_trans[['Special_offer','returned_goods']].apply(lambda x: x.replace(np.nan, min(x)), 
                                                                                                axis = 0)
R_trans['R_max'] = R_trans[['Normal','Presented','Special_offer']].apply(lambda x: max(x), axis =1)

R_trans.head()
typeNormalPresentedSpecial_offerreturned_goodsR_max
cumid
100011.284699e+091.284197e+091.255316e+091.278766e+091.284699e+09
100021.276953e+091.278129e+091.250297e+091.252047e+091.278129e+09
100031.282983e+091.280805e+091.262435e+091.275806e+091.282983e+09
100041.279534e+091.283057e+091.254833e+091.275571e+091.283057e+09
100051.277448e+091.282127e+091.250297e+091.270728e+091.282127e+09
# 对购物频率按照购物ID和购物类型进行汇总统计
F=trad_flow.groupby(['cumid','type'])[['transID']].count()

# 转化为透视表
F_trans=pd.pivot_table(F,index='cumid',columns='type',values='transID')

# 用0填补缺失值
F_trans[['Special_offer','returned_goods']] = F_trans[['Special_offer','returned_goods']].fillna(0)

# 将退货的频数转化为负数
F_trans['returned_goods'] = F_trans['returned_goods'].map(lambda x: -x)

# 求每个购物ID的购物总次数
F_trans["F_total"] = F_trans.apply(lambda x: sum(x), axis = 1)

F_trans.head()
typeNormalPresentedSpecial_offerreturned_goodsF_total
cumid
1000115.08.02.0-2.023.0
1000212.05.00.0-1.016.0
1000315.08.01.0-1.023.0
1000415.012.02.0-1.028.0
100058.05.00.0-1.012.0
# 对购物金额按照购物ID和购物类型进行汇总统计
M=trad_flow.groupby(['cumid','type'])[['amount']].sum()

# 转化为透视表
M_trans=pd.pivot_table(M,index='cumid',columns='type',values='amount')

# 用0填补缺失值
M_trans[['Special_offer','returned_goods']] = M_trans[['Special_offer','returned_goods']].fillna(0)

# 求每个购物ID的购物总金额
M_trans["M_total"] = M_trans.apply(lambda x: sum(x), axis = 1)

M_trans.head()
typeNormalPresentedSpecial_offerreturned_goodsM_total
cumid
100013608.00.0420.0-694.03334.0
100021894.00.00.0-242.01652.0
100033503.00.0156.0-224.03435.0
100042979.00.0373.0-40.03312.0
100052368.00.00.0-249.02119.0
# 合并表
RFM = pd.concat([R_trans['R_max'],F_trans['F_total'],M_trans['M_total']], axis = 1)
# RFM三个维度等宽分箱打分
RFM['R_score'] = pd.cut(RFM.R_max,3,labels = [1,2,3], precision = 2)
RFM['F_score'] = pd.cut(RFM.F_total,3,labels = [1,2,3], precision = 2)
RFM['M_score'] = pd.cut(RFM.M_total,3,labels = [1,2,3], precision = 2)

# RFM各三类,总共有27种组合,为方便营销简化分类为8种
def score_label(a,b,c):
    '''
    a: 'R_score'
    b: 'F_score'
    c: 'M_score'
    '''
    if a == 3 and b == 3 and c == 3:
        return '重要价值客户'
    elif a == 3 and (b in [1,2]) and c == 3:
        return '重要发展客户'
    elif (a in [1,2]) and b == 3 and c == 3:
        return '重要保持客户'
    elif (a in [1,2]) and (b in [1,2]) and c == 3:
        return '重要挽留客户'
    elif a == 3 and b == 3 and (c in [1,2]):
        return '一般价值客户'
    elif a == 3 and (b in [1,2]) and (c in [1,2]):
        return '一般发展客户'
    elif (a in [1,2]) and b == 3 and (c in [1,2]):
        return '一般保持客户'
    elif (a in [1,2]) and (b in [1,2]) and (c in [1,2]):
        return '一般挽留客户'    
# 为每个购物ID贴标签
RFM['Label'] = RFM[['R_score', 'F_score', 'M_score']].apply(lambda x: score_label(x[0],x[1],x[2]), axis = 1)

RFM.head()
R_maxF_totalM_totalR_scoreF_scoreM_scoreLabel
cumid
100011.284699e+0923.03334.0322一般发展客户
100021.278129e+0916.01652.0111一般挽留客户
100031.282983e+0923.03435.0322一般发展客户
100041.283057e+0928.03312.0332一般价值客户
100051.282127e+0912.02119.0211一般挽留客户
  • ‘重要价值客户’:消费额度高,购物频率高,最近购物时间也较近——该类客户是重要且忠实的大客户,要细心维护。

  • ‘重要发展客户’:消费额度高,购物频率不高,最近购物时间较近——该类客户只是购物频率不高,有巨大的挖掘潜力,可根据该客户以往购物信息,进行个性 化推荐,并发放购物优惠券刺激消费,增加客户粘性。

  • ‘重要保持客户’:消费额度高,购物频率高,但最近购物时间较远——该类客户最近一次购物时间较久远,可能是快要流失的重要客户,可以让客户沟通了解其 是不是哪项环节不够人性化体验不好,导致购物频率过低。

  • ‘重要挽留客户’:消费额度高,购物频率不高,最近购物时间也较远——该类客户可能是已经流失的重要客户,如果还能联系上,可跟进了解其流失原因,对有 相似客户特征的群体进行预警,针对性改进。

  • ‘一般价值客户’:消费额度不高,购物频率高,最近购物时间也较近——该类客户对我们的产品感兴趣,很活跃,但购物金额过低,可能是价格敏感性客户,可 对其组合金融产品增加其购买力。

  • ‘一般发展客户’:消费额度不高,购物频率不高,最近购物时间较近——该类客户可能是我们的新晋客户,对我们的服务和产品进行试探性体验,可多留意此类 客户,进行邮件短信关怀及时发送优惠信息。

  • ‘一般保持客户’:消费额度不高,购物频率高,最近购物时间较远——该类客户可能是快要流失的一般客户,可进行一般性低成本营销。

  • ‘一般挽留客户’:消费额度不高,购物频率不高,最近购物时间也较远——该类客户不是我们的目标客户,经费有限可忽略此类客户。

3.衡量客户对打折商品的偏好

M_trans['Special_offer']= M_trans['Special_offer'].fillna(0)
M_trans['spe_ratio']=M_trans['Special_offer']/(M_trans['Special_offer']+M_trans['Normal'])
M_rank=M_trans.sort_values('spe_ratio',ascending=False,na_position='last').head()
M_rank['spe_ratio_group'] = pd.qcut(M_rank['spe_ratio'], 4) # 这里以age_oldest_tr字段等宽分为4段
M_rank.head()
typeNormalPresentedSpecial_offerreturned_goodsM_totalspe_ratiospe_ratio_group
cumid
10151765.00.0870.00.01635.00.532110(0.387, 0.532]
400331206.00.0761.0-848.01119.00.386884(0.374, 0.387]
402361155.00.0691.0-793.01053.00.374323(0.333, 0.374]
302251475.00.0738.0-301.01912.00.333484(0.308, 0.333]
200681631.00.0731.0-239.02123.00.309483(0.308, 0.333]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值