python数据分析-基于RFM的用户价值度分析

1 会员价值度评价指标

会员价值是以用户价值为出发点,通过模型或者方法将会员划分成几个群体或者层级,比如:支付宝将会员划分为钻石、黄金、白银等,又或者将会员价值评定为高、中和低。
通常,不同公司会采用不同的指标来判断会员的价值大小,常用的指标有如下几个:

  1. 复购率
    复购率是一定周期内购买2次或者2次以上的会员比例.不同公司对复购率的定义有所差异,基本定义分为三种,以1个月为周期说明复购的定义:
    (1)1个月内购买了2次或两次以上的会员
    (2)1个月内购买2次或2次以上,以及1个月之前有购买行为,在1个月内又产生购买行为(可能是1次)的会员。
    (3)1个月之前有购买行为,1个月之后又有购买行为的会员。
    以上三种定义可根据公司不同的情况进行调整,同时1个月的时间周期也可根据商品或服务销售频次进行重新定义。
  2. 消费频次
    消费频次和复购率相关,二者都是重复消费指标。消费频次是指将用户的消费频率,按照次数做出统计,统计结果是在一定周期内消费的不同次数,例如2次,3-5次,6-10次,11次以上。该指标用于分析用户对于企业的消费黏性。
  3. 最近一次购买时间
    该指标作为会员消费价值黏性的评估因素之一。如果会员距离上次购买或消费时间过长,那么意味着用户在沉默或将要流失甚至已经流失的阶段,此时应该采取措施挽回用户。
  4. 最近一次购买金额
    最近一次购买金额和最近一次购买时间类似,该指标衡量的是用户最近一次购买或消费时的订单,该金额越大说明用户最近一次的消费能力越高。根据二八法则,20%的老会员会贡献80%的消费金额。

2 会员价值度模型

价值度模型一般基于交易行为产生,衡量的是有实体转化价值的行为。常用的价值度模型是RFM。
RFM模型是根据会员最近一次购买时间R(Recency)、购买频率(Frequency)、购买金额(Monetary)计算得出RFM得分,通过这三个维度衡量客户的订单活跃价值,常用来做客户分群和价值区分。该模型常用于电子商务(即交易类)企业的会员分析。
RFM模型基于一个固定的时间点来做模型分析,因此今天做的RFM得分跟7天前做的结果可能不一样,原因是每个客户在不同的时间节点所得到的数据不同。

3 模型建立

  1. 数据来源
    数据为某企业2016年份的部分抽样数据,数据来源于销售系统,主要是用户订单记录。
    数据来自《python 数据分析与数据化运营》第五章的sales.csv。
    以下是数据概况:
    ~特征变量数:4
    ~数据记录数:86135
    ~是否有NA值:有
    ~是否有异常值:有
    以下是本数据集的4个特征变量,包括:
    ~USERID:用户ID,每个用户的ID唯一,由纯数字组成
    ~ORDERDATE:订单日期,格式为YYYY-MM-DD,例如2016-01-01
    ~ORDERID:订单ID,每个订单ID唯一,由纯数字组成
    ~AMOUNTINFO:订单金额,浮点型数据
  2. 模型建立
    2.1 相关库导入
    模型的建立要用到四个库,分别是:numpy,time,pandas和pymysql
import pandas as pd
import numpy as np
import time
import pymysql

2.2 导入相关数据
在导入数据时,可直接对各列的数据类型进行定义,也可在导入数据之后,对各列的数据类型进行转换。这里选择读取数据时自定义数据库数据类型。同时将索引值设置为用户ID。

dtypes={'ORDERDATE':object,'ORDERID':object,'AMOUNTINFO':float}
data=pd.read_csv('sales.csv',dtype=dtypes,index_col='USERID')

2.3 数据审查和校验,主要包括数据概览、缺失值审查等
(1)数据概览
pandas的describe()方法可以很好的实现对数值型数据的分布做一个很好的描述,同时,还可查看数据的长度、组成规律、类型等信息。

print('DATA Overview:')
print(data.head())
print('\n')
print('Data desc:')
print(data.describe())

(2)缺失值审查
缺失值处理是数据预处理的重要步骤之一,缺失值对后续的计算会产生重大的影响。

#缺失值判断
na_cols=data.isnull().any(axis=0)
na_rows=data.isnull().any(axis=1)
print('总共缺失的行数(任意一列的缺失):',na_rows.sum())
print(data[na_rows])

以下为数据审查和校验结果:
DATA Overview:
ORDERDATE ORDERID AMOUNTINFO
USERID
142074 2016-01-01 4196439032 9399.0
56927 2016-01-01 4198324983 8799.0
87058 2016-01-01 4191287379 6899.0
136104 2016-01-01 4198508313 5999.0
117831 2016-01-01 4202238313 5399.0

Data desc:
AMOUNTINFO
count 86127.000000
mean 744.705249
std 1425.211176
min 0.500000
25% 13.000000
50% 59.000000
75% 629.000000
max 30999.000000
总共缺失的行数(任意一列的缺失): 10
ORDERDATE ORDERID AMOUNTINFO
USERID
75849 2016-01-01 4197103430 NaN
103714 NaN 4136159682 189.0
155209 2016-01-01 4177940815 NaN
139877 NaN 4111956196 6.3
54599 2016-01-01 4119525205 NaN
65456 2016-01-02 4195643356 NaN
122134 2016-09-21 3826649773 NaN
116995 2016-10-24 3981569421 NaN
98888 2016-12-06 3814398698 NaN
145951 2016-12-29 4139830098 NaN
由返回结果可知,ORDERDATE列和AMOUNTINFO列均有数据缺失,且缺失记录共有10行。由于10行在总共的86135中占比较小,这里可以直接删除。
2.4. 数据预处理准备工作,包括数据异常、格式转换和处理
(1)异常值处理
由于订单金额为0.5的订单是属于促销优惠券生成的订单,这些订单用来为用户消费时提供优惠券,没有实际意义,因此需要去除。除了0.5元的订单,所以低于1元的订单均有问题。

#删除异常数据,包括缺失值数据和非正常数据
sales_data=data.dropna()
sales_data=sales_data[sales_data['AMOUNTINFO']>1]
print('经过数据预处理后的记录数总共为:',sales_data.shape[0])

(2)日期格式转换
日期格式转换的目的是基于时间间隔的计算,这样才能算出R距离指定日期的天数。

#日期格式转换
sales_data['ORDERDATE']=pd.to_datetime(sales_data['ORDERDATE'],format='%Y-%m-%d')
print("数据的格式:",sales_data.dtypes)

2.5 计算RFM得分
(1)分别计算R,F,M的得分

deadline_date=pd.datetime(2017,1,1)
#计算间隔天数,以及R\F\M的得分
interval_days=(deadline_date-recency_value).dt.days
r_score=pd.cut(interval_days,5,labels=[5,4,3,2,1])
f_score=pd.cut(frequency_value,5,labels=[1,2,3,4,5])
m_score=pd.cut(monetary_value,5,labels=[1,2,3,4,5])

首先,指定一个时间节点,用于计算其他时间与该时间的间隔。对R、F、M三个变量使用分位数法做区间划分,使用了pd.cut方法,默认设置为5份,同时通过labels标签指定区间标志。主要是对于R而言,数值越大,意味着离指定日期越远,因此其区间划分后的值应该越小,所以该标签列顺序与其他相反。
(2)R、F、M数据合并

rfm_data=pd.DataFrame({'r_score':r_score,'f_score':f_score,'m_score':m_score},index=frequency_value.index,dtype=np.int32)
print('RFM Score overview:',rfm_data.head())

(3)RFM总得分计算
方法一:直接乘以特定权重得到总得分。根据业务方的需求建立模型。如果业务方更关注活跃度,认为访问的邻近度更为重要,认为访问的邻近度最重要,因此R的权重更高。其次是访问频率,最后是金额。假定权重分别为0.6,0.3,0.1(可由专家打分得到)
方法二:直接将RFM以字符串形式组合,组合的顺序根据RFM的重要程度排名。

#方法一:加权得分
rfm_data['total_score']=rfm_data['r_score']*0.6+rfm_data['f_score']*0.3+rfm_data['m_score']*0.1

#方法二:组合得分
rfm_data_tmp=rfm_data.copy()
rfm_data_tmp['r_score']=rfm_data_tmp['r_score'].astype('str')
rfm_data_tmp['f_score']=rfm_data_tmp['f_score'].astype('str')
rfm_data_tmp['m_score']=rfm_data_tmp['m_score'].astype('str')
rfm_data['final_score']=rfm_data_tmp['r_score'].str.cat(rfm_data_tmp['f_score']).str.cat(rfm_data_tmp['m_score'])

最后的RFM得分的结果如下:

print('final RFM Score overview:')
print(rfm_data.head())
print('\n')
#结果主要验证数据输出是否符合预期,主要是R、F、M的组合和加权计算,使用描述性统计简单看下数据型得分的区间分布是否在预计的[1,5]分之间
print('Final rfm score desc:')
print(rfm_data.describe())

final RFM Score overview:
f_score m_score r_score total_score final_score
USERID
51220 1 1 4 2.8 411
51221 1 1 2 1.6 211
51224 1 1 3 2.2 311
51225 1 1 4 2.8 411
51226 1 1 1 1.0 111

2.6 结果保存
(1)方法一:直接保存到本地csv文件

rfm_data.to_csv('rfm_model_data.csv')

(2)方法二:保存到Mysql数据库中
首先,需要实现数据库的连接,可用到pymysql中的connect()方法

import pymysql
conn=pymysql.connect(host='localhost',user='root',password='******',port=3306,db='employee',charset='utf8')
cursor=conn.cursor()

在将数据写入数据库之前,需要判断数据库中是否存在要写入的表,如果不存在需要新建数据库。

cursor.execute('show tables')
#采用游标的fetchall方法抓取全部数据
table_object=cursor.fetchall()
table_list=[]
for table in table_object:
    table_list.append(table)
if not "sales_rfm_data" in table_list:
    sql='Create table sales_rfm_data (\
    userid varchar(20),\
    r_score int(2),\
    f_score int(2),\
    m_score int(2),\
    total_score decimal(10,2),\
    final_score varchar(20),\
    insert_data varchar(20))ENGINE=InnoDB DEFAULT CHARSET=utf8'
    cursor.execute(sql)

经过上述步骤,能保证要写入的数据表已存在,接下来将数据插入数据库中。

user_id=rfm_data.index.astype('str')
total_score=rfm_data['total_score']
final_score=rfm_data['final_score']
#写库日期
timestamp=time.strftime('%Y-%m-%d',time.localtime(time.time()))
print('begin to insert data into table')
#依此循环将数据插入
for i in range(rfm_data.shape[0]):
    insert_sql='insert into sales_rfm_data (userid,r_score,f_score,m_score,total_score,final_score,insert_data) values (%s,%s,%s,%s,%s,%s,%s)'
    cursor.execute(insert_sql,(user_id[i],int(r_score.iloc[i]),int(f_score.iloc[i]),int(m_score.iloc[i]),float(total_score.iloc[i]),final_score.iloc[i],timestamp))  
    #由于需要批量写入操作,因此需要采用conn.commit方法提交命令
    conn.commit()

完成数据库的插入操作之后,关闭游标和数据库。

cursor.close()
conn.close()
print('finish insertinng')

以上的数据分析案例摘自《Python数据分析与数据化运营》

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值