客户精准营销(RFM模型)

# ### 1. 导入数据
import os
import pandas as pd

trad_flow=pd.read_csv(r'RFM_TRAD_FLOW.csv',encoding='gbk')
trad_flow.head()

transIDcumidtimeamounttype_labeltype
094071000114JUN09:17:58:34199.0正常Normal
196251000116JUN09:15:09:13369.0正常Normal
2118371000101JUL09:14:50:36369.0正常Normal
3266291000114DEC09:18:05:32359.0正常Normal
4308501000112APR10:13:02:20399.0正常Normal

# ### 2.通过 RFM方法 建立 模型  R(Recency)购买的时间  F(Frequency)购买的次数  M(Monetary)购买的金额
#2.1 通过计算F反应客户对打折产品的偏好
F=trad_flow.groupby(['cumid','type'])[['transID']].count()
F.head(10)

transID
cumidtype 
10001Normal15
Presented8
Special_offer2
returned_goods2
10002Normal12
Presented5
returned_goods1
10003Normal15
Presented8
Special_offer1

#数据处理,空值填充为0。添加新列(兴趣度).做出交叉表的效果F_trans=pd.pivot_table(F,index='cumid',columns='type',values='transID')
F_trans['Special_offer']= F_trans['Special_offer'].fillna(0)
F_trans["interest"]=F_trans['Special_offer']/(F_trans['Special_offer']+F_trans['Normal'])
F_trans.head()

typeNormalPresentedSpecial_offerreturned_goodsinterest
cumid     
1000115.08.02.02.00.117647
1000212.05.00.01.00.000000
1000315.08.01.01.00.062500
1000415.012.02.01.00.117647
100058.05.00.01.00.000000

#help(pd.pivot_table) ,不会可以用help查看pivot_table的用法以及参数

#2.2 通过计算M反应客户的价值信息
M=trad_flow.groupby(['cumid','type']).sum()
M.head()

transIDamount
cumidtype  
10001Normal4569413608.0
Presented3304590.0
Special_offer49531420.0
returned_goods79927-694.0
10002Normal3151771894.0

M_trans=pd.pivot_table(M,index='cumid',columns='type',values='amount')

M_trans.head()

typeNormalPresentedSpecial_offerreturned_goods
cumid    
100013608.00.0420.0-694.0
100021894.00.0NaN-242.0
100033503.00.0156.0-224.0
100042979.00.0373.0-40.0
100052368.00.0NaN

-249.0

M_trans['Special_offer']= M_trans['Special_offer'].fillna(0)
M_trans['returned_goods']= M_trans['returned_goods'].fillna(0)
M_trans["value"]=M_trans['Normal']+M_trans['Special_offer']+M_trans['returned_goods']
M_trans.head()
typeNormalPresentedSpecial_offerreturned_goodsvalue
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

#2.3 通过计算R反应客户是否为沉默客户

from datetime import datetime
import time

#定义函数,用于将时间转化为需要的格式
def to_time(t):
    out_t=time.mktime(time.strptime(t, '%d%b%y:%H:%M:%S'))   ########此处修改为时间戳方便后面qcut函数分箱
    return out_t
a="14JUN09:17:58:34"
print(to_time(a))  #稍微查看一下函数

1244973514.0

trad_flow["time_new"]= trad_flow.time.apply(to_time)

trad_flow.head()

transIDcumidtimeamounttype_labeltypetime_new
094071000114JUN09:17:58:34199.0正常Normal1.244974e+09
196251000116JUN09:15:09:13369.0正常Normal1.245136e+09
2118371000101JUL09:14:50:36369.0正常Normal1.246431e+09
3266291000114DEC09:18:05:32359.0正常Normal1.260785e+09
4308501000112APR10:13:02:20399.0正常Normal1.271049e+09

R=trad_flow.groupby(['cumid'])[['time_new']].max()

R.head()

time_new
cumid 
100011.284699e+09
100021.278129e+09
100031.282983e+09
100041.283057e+09
100051.282127e+09

# ### 3.构建模型,筛选目标客户

from sklearn import preprocessing
threshold = pd.qcut(F_trans['interest'], 2, retbins=True)[1][1]
threshold
0.08333333333333333

pd.qcut 的用法:基于分位数的离散化函数。根据等级或样本分位数将变量分解为大小相等的桶。例如,10个分位数的1000个值将产生一个分类对象,指示每个数据点的分位数成员资格。  用于分类,分2类

binarizer = preprocessing.Binarizer(threshold=threshold)
binarizer

Binarizer(copy=True, threshold=0.08333333333333333)

preprocessing.Binarizer(threshold=threshold) 用法:根据大于阈值映射为1的阈值将数据(将特征值设置为0或1),而值小于或等于阈值映射为0。默认阈值为0时,只有正值映射为1。二进制化是对文本计数数据的一种常见操作,分析人员可以决定只考虑功能的存在与否,而不是量化的出现次数。它也可以作为考虑布尔随机变量的估计器的预处理步骤(例如,在贝叶斯设置中使用Bernoulli分布建模)。

interest_q = pd.DataFrame(binarizer.transform(F_trans['interest'].values.reshape(-1, 1)))
interest_q.head() #查看建模后的数据,已经分成了2类

0
01.0
10.0
20.0
31.0
40.0

interest_q.index=F_trans.index #将上面的数据添加index和column

interest_q.columns=["interest"]

interest_q.head()

interest
cumid 
100011.0
100020.0
100030.0
100041.0
100050.0

threshold = pd.qcut(M_trans['value'], 2, retbins=True)[1][1] #剩下的同上,全部分2类

binarizer = preprocessing.Binarizer(threshold=threshold)

value_q = pd.DataFrame(binarizer.transform(M_trans['value'].values.reshape(-1, 1)))
value_q.index=M_trans.index
value_q.columns=["value"]

threshold = pd.qcut(R["time_new"], 2, retbins=True)[1][1]
binarizer = preprocessing.Binarizer(threshold=threshold)
time_new_q = pd.DataFrame(binarizer.transform(R["time_new"].values.reshape(-1, 1)))
time_new_q.index=R.index
time_new_q.columns=["time"]

analysis=pd.concat([interest_q, value_q,time_new_q], axis=1) #将RFM建模形成的3个表连接
analysis = analysis[['interest','value','time']]
analysis.head()

#添加一列,将分类结果换成中文

label = {
    (0,0,0):'无兴趣-低价值-沉默',
    (1,0,0):'有兴趣-低价值-沉默',
    (1,0,1):'有兴趣-低价值-活跃',
    (0,0,1):'无兴趣-低价值-活跃',
    (0,1,0):'无兴趣-高价值-沉默',
    (1,1,0):'有兴趣-高价值-沉默',
    (1,1,1):'有兴趣-高价值-活跃',
    (0,1,1):'无兴趣-高价值-活跃'
}
analysis['label'] = analysis[['interest','value','time']].apply(lambda x: label[(x[0],x[1],x[2])], axis = 1)
analysis.head()

interestvaluetimelabel
cumid    
100011.01.01.0有兴趣-高价值-活跃
100020.00.00.0无兴趣-低价值-沉默
100030.01.00.0无兴趣-高价值-沉默
100041.01.00.0有兴趣-高价值-沉默
100050.00.00.0无兴趣-低价值-沉默
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值