“Python数据化会员运营分析”小组学习的Task02-学习日志


前言

本文章为天池“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))# 展示数据前4print('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组合计分为分组行标签,计算不同标准下用户占比,从而对用户进行划分制定不同的策略。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值