前言
本文章为天池“Python数据化会员运营分析”小组学习的Task02-学习日志,旨在对会员运营基础知识运用到实例中。
一、数据信息简介
1.数据信息
1.案例数据是某企业从2015年到2018年共4年的用户订单抽样数据 2.sales.xlsx-2015~2018表中表数字特征如下: * 会员ID:每个会员的ID唯一,由纯数字组成。 * 提交日期:订单日提交日期。 * 订单号:订单ID,每个订单的ID唯一,由纯数字组成。 * 订单金额:订单金额,浮点型数据。 3.sales.xlsx-会员等级表数字特征如下: 会员ID:该ID可与前面的订单表中的会员ID关联。 会员等级:会员等级以数字区分,数字越大,级别越高。
2.实验目标
1. 对数据进行清洗 2.确定RFM划分区间 3.计算RFM因子权重 4.对RFM分箱并计算得分 5.对以上数据保存为新表格,进行后期EXCEL处理
二、导入库和数据
1.引入库
代码如下:
import time #用来记录插入数据库时的当前日期
import numpy as np #用来做基本数据处理
import pandas as pd #有关日期转换、数据格式化处理、主要RFM计算过程等
#引入机器学习包sklearn
from sklearn.ensemble import RandomForestClassifier #随机森林库
2.读入数据
代码如下:
#创建sheet_names列表,与表格数据相对应,方便后续处理
sheet_names = ['2015','2016','2017','2018','会员等级']
#利用pandas库中的read_excel()函数,根据每一列的sheet_names,从第一行到最后一行依次读取每一行的数据作为sheet_datas
sheet_datas = [pd.read_excel('D:/python/ITEM/Data-operation-of-member/DATA/sales.xlsx',sheet_name=i) for i in sheet_names]
三、数据清洗
1.主要步骤
1.查阅数据基本信息,是否存在缺失值,异常值 2.查阅数据类型确定是否需要转变数据类型
2.查阅数据
代码如下:
for each_name,each_data in zip(sheet_names,sheet_datas):#zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
print('[data summary for {0:=^50}]'.format(each_name))#显示各年份之间的分割线
print('Overview:','\n',each_data.head(4))# 展示数据前4条
print('DESC:','\n',each_data.describe())# 数据描述性信息
print('NA records',each_data.isnull().any(axis=1).sum()) # 缺失值记录数
print('Dtypes',each_data.dtypes) # 获取数据类型
isnull().any(axis=1)来判断含有缺失值的记录,后用sum计数
部分结果如下:
[data summary for =======================2015=======================]
Overview:
会员ID 订单号 提交日期 订单金额
0 15278002468 3000304681 2015-01-01 499.0
1 39236378972 3000305791 2015-01-01 2588.0
2 38722039578 3000641787 2015-01-01 498.0
3 11049640063 3000798913 2015-01-01 1572.0
DESC:
会员ID 订单号 订单金额
count 3.077400e+04 3.077400e+04 30774.000000
mean 2.918779e+10 4.020414e+09 960.991161
std 1.385333e+10 2.630510e+08 2068.107231
min 2.670000e+02 3.000305e+09 0.500000
25% 1.944122e+10 3.885510e+09 59.000000
50% 3.746545e+10 4.117491e+09 139.000000
75% 3.923593e+10 4.234882e+09 899.000000
max 3.954613e+10 4.282025e+09 111750.000000
NA records 0
Dtypes 会员ID int64
订单号 int64
提交日期 datetime64[ns]
订单金额 float64
dtype: object
[data summary for =======================2016=======================]
Overview:
会员ID 订单号 提交日期 订单金额
0 39288120141 4282025766 2016-01-01 76.0
1 39293812118 4282037929 2016-01-01 7599.0
2 27596340905 4282038740 2016-01-01 802.0
3 15111475509 4282043819 2016-01-01 65.0
DESC:
会员ID 订单号 订单金额
count 4.127800e+04 4.127800e+04 41277.000000
mean 2.908415e+10 4.313583e+09 957.106694
std 1.389468e+10 1.094572e+07 2478.560036
min 8.100000e+01 4.282026e+09 0.100000
25% 1.934990e+10 4.309457e+09 59.000000
50% 3.730339e+10 4.317545e+09 147.000000
75% 3.923182e+10 4.321132e+09 888.000000
max 3.954554e+10 4.324911e+09 174900.000000
NA records 1
Dtypes 会员ID int64
订单号 int64
提交日期 datetime64[ns]
订单金额 float64
dtype: object
数据分析: 1.存在空值但控制较少 2.标准差较大,数据较分散存在极大值 3.最小值有0.1,最大值为174900需要了解这些特殊值原因
3.缺失值处理
代码如下:
for ind,each_data in enumerate(sheet_datas[:-1]):#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
sheet_datas[ind] = each_data.dropna()# 丢弃缺失值记录
sheet_datas[ind] = each_data[each_data['订单金额'] > 1]# 丢弃订单金额<=1的记录
sheet_datas[ind]['max_year_date'] = each_data['提交日期'].max() # 增加一列最大日期值
注:最后一行代码的目的是在每个年份的数据中新增一列max_year_date,通过each_data[‘提交日期’].max()获取一年中日期的最大值,这样方便后续针对每年的数据分别做RFM计算,而不是针对4年的数据统一做RFM计算。
四、汇总数据
1.汇总信息
代码如下:
# 汇总所有数据
data_merge = pd.concat(sheet_datas[:-1],axis=0)
#将4年的数据使用pd.concat方法合并为一个完整数据框data_merge
data_merge['date_interval'] = data_merge['max_year_date'] - data_merge['提交日期']#计算各自年份的最大日期与每个行的日期的差,得到日期间隔
data_merge['year'] = data_merge['提交日期'].dt.year#增加一段新的字段,为每个记录行发生的年份
2.将日期间隔转化成文字
data_merge['date_interval'] = data_merge['date_interval'].apply(lambda x: x.days)
3.按会员ID做汇总
代码如下:
rfm_gb = data_merge.groupby(['year','会员ID'], as_index=False).agg({'date_interval':'min', #计算最近一次的订单时间
'提交日期':'count', #计算订单的频率
'订单金额':'sum'}) #计算订单的总金额
该代码实现的是基于年份和会员ID,分别做RFM原始值的聚合计算。 这里的分类汇总使用的是groupby方法,以year和会员ID为联合主键,设置as_index=False意味着year和会员ID不作为index列,而是普通的数据框结果列。后面的agg方法实际上是一个“批量”聚合功能的函数,实现了对data_interval、提交日期、订单金额三列分别以min、count、sum做聚合计算的功能。否则,我们需要分别写3条groupby来实现3个聚合计算。
4.重命名列名
代码如下:
rfm_gb.columns = ['year','会员ID','r','f','m']
五、确定RFM划分区间&计算RFM因子权重
1.查看数据分布
代码如下:
desc_pd = rfm_gb.iloc[:,2:].describe().T#由于只针对rfm三列,因此使用iloc方法,选择从第3列(索引值为2)开始的字段,调用describe方法
print(desc_pd)
结果如下:
count mean std min 25% 50% 75% max
r 148591.0 165.524043 101.988472 0.0 79.0 156.0 255.0 365.0
f 148591.0 1.365002 2.626953 1.0 1.0 1.0 1.0 130.0
m 148591.0 1323.741329 3753.906883 1.5 69.0 189.0 1199.0 206251.8
结果分析:r和m的数据分布相对较为离散,f标准差较小向1聚集,但是仍然存在较大离群值;从分为数来看r/m较好区分特征,而f不好区分。
2.定义区间边界
代码如下:
r_bins = [-1,79,255,365] # 注意起始边界小于最小值
f_bins = [0,2,5,130]
m_bins = [0,69,1199,206252]
注:分段的选取主要参考分位数,r取到-1是因为分区左闭右开,r需要包含入0值。
3计算RFM因子权重
代码如下:
# 匹配会员等级和rfm得分
rfm_merge = pd.merge(rfm_gb,sheet_datas[-1],on='会员ID',how='inner')#使用merge方法合并两个数据框,关联主键是会员ID,匹配方式是内部匹配
# rf获得rfm因子得分
clf = RandomForestClassifier()#调用随机森林分类起模型
clf = clf.fit(rfm_merge[['r','f','m']],rfm_merge['会员等级'])#使用随机森林分类器模型在我们的数据上进行拟合
weights = clf.feature_importances_ #返回'r','f','m'三部分权重
print('feature importance:',weights)
六、RFM分箱
1.RFM分箱得分
代码如下:
rfm_gb['r_score'] = pd.cut(rfm_gb['r'], r_bins, labels=[i for i in range(len(r_bins)-1,0,-1)])# 计算R得分
rfm_gb['f_score'] = pd.cut(rfm_gb['f'], f_bins, labels=[i+1 for i in range(len(f_bins)-1)])# 计算F得分
rfm_gb['m_score'] = pd.cut(rfm_gb['m'], m_bins, labels=[i+1 for i in range(len(m_bins)-1)])# 计算M得分
2.方法一:加权计分
代码如下:
rfm_gb = rfm_gb.apply(np.int32) # cate转数值
rfm_gb['rfm_score'] = rfm_gb['r_score'] * weights[0] + rfm_gb['f_score'] * weights[1] + rfm_gb['m_score'] * weights[2]
3.方法二:RFM组合计分
代码如下:
rfm_gb['r_score'] = rfm_gb['r_score'].astype(np.str)#3列使用astype方法将数值型转换为字符串类型,然后使用pandas的字符串处理库中str的cat方法做字符串合并
rfm_gb['f_score'] = rfm_gb['f_score'].astype(np.str)
rfm_gb['m_score'] = rfm_gb['m_score'].astype(np.str)
rfm_gb['rfm_group'] = rfm_gb['r_score'].str.cat(rfm_gb['f_score']).str.cat(rfm_gb['m_score'])
注:str库中cat方法 参数介绍: others:要合并的另外一个对象(右侧对象),如果为空,则将左侧对象进行组合。 sep:合并的分隔符,默认为空,可自定义,例如“,”、“;”等。 na_rep:如果遇到NA(缺失值)时如何处理,默认为忽略。
4.保存RFM结果到Excel
代码如下:
rfm_gb.to_excel('D:/python/ITEM/Data-operation-of-member/DATA/sales_rfm_score1.xlsx')# 保存数据为Excel
七、对分箱后EXCLE透视
以RFM组合计分为分组行标签,计算不同标准下用户占比,从而对用户进行划分制定不同的策略。
|