本文主要是介绍数学建模~~描述性分析---RFM用户分层模型聚类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1.RFM用户分层模型介绍
2.获取数据,标准化处理
2.1获取数据
2.2时间类型转换
2.3计算时间间隔
3.对于R,F,M的描述性分析
3.1代码分析
3.2分析结果说明
3.3对于F的描述性分析
3.4对于M的描述性分析
4.数据分箱--等级划分
4.1分箱概念
4.3分箱特点
4.3分箱方式
4.4总结分析
5.综合评价
6.K中心聚类分析
1.1数据的标准化处理
1.2标准化处理的结果
1.3K均值聚类分析
1.4分析结果说明
1.RFM用户分层模型介绍
简单讲就是:recency:最近一次消费的时间间隔
frequency消费的频率
money消费的花钱多少
这个我们会根据一个电商的表单数据,进行这个RFM分别的描述性分析,我们可以知道这个:
R越大,就是这个最近一次消费到截止时间的间隔很大,说明这个用户活跃度越高;
F越大,说明这个用户消费次数很多,也可以去证明这个用户的活跃度很高;
M越大,说明这个用户每一次消费的钱很多,进而可以去说明这个用户的这个活跃度很高;
上面这个是对于这个模型的基本的认识,我们根据这三个指标的活跃与否,每一个指标都是有两个情况,那么三个指标通过排列组合就会有8个可能的情况,这个RFM模型就是把这个所有的用户划分为8种类型(不理解的可以使用树状图画出来);
2.获取数据,标准化处理
2.1获取数据
我们首先对于这个电商的数据进行筛选出来我们想要的,
就是这个截止时间里面最近购买的时间间隔,这个表单里面使用的last_order_date进行表示的;
购买的频率就是我们这个地方的order_count就是订单的数量;
购买的金额就是这个地方的total_amount,我们的标准化处理就是基于这个表格里面的这三列的数据
2.2时间类型转换
==标准化处理==就是把这个表单里面的数据处理为我们容易使用python进行分析的,这个处理过程分为两个步骤:
第一个就是对于这个==时间类型==的转换,把这个字符串类型的数据转换为时间类型的数据,这个过程会使用到的函数就是to_datetime函数,这个函数的参数就是需要进行转换的这一列或者是这一行的数据;
# 导入pandas模块,简写为pdimport pandas as pd# 读取文件,赋值给dfdf = pd.read_csv("/Users/user_info/user_info.csv")# 将"last_order_date"这一列,转为时间类型df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 输出dfprint(df)
2.3计算时间间隔
###对于这个时间价格的计算,我们的这个电商订单里面显示的是这个产品的下单时间,我们需要引进来一个参照的时间进行做减法,求出来这个时间的间隔;
###这个需要导入一个datetime模块;
###我们使用的就是这个datetime函数创建一个参照的时间,进行一个初始时间的设置,后续的这个时间间隔都是根据这个进行计算的;
###中间的时间间隔就是做减法,dt表示把这个时间间隔转换成为一个时间对象,方便我们进行后续的操作,days获得天数的信息,这个时候我们得到的就是一个整形的数据;
# 导入pandas模块
import pandas as pd '''读取并处理数据集'''
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])'''获取描绘R、F、M的数据'''
# 1. 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
# 将结果添加为df的"time_gap"列
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days# 输出df["time_gap"]
print(df["time_gap"])
3.对于R,F,M的描述性分析
3.1代码分析
###首先就是对于R的描述性分析,groupby是对于这个处理后的数据进行分类,这个分类的依据就是这个函数的参数--也就是我们上面积算出来的时间间隔;
###因为我们的这个结果、一个总人数,我们想要得到的就是不同区间的人数的占比情况;
###代码里面还是对于这个编码进行设置,调用了可视化函数进行绘图,绘图函数的横纵坐标就是这个时间间隔比例的索引和对应的数值;
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1.1 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 1.2 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''对R、F、M进行描述性分析'''
# 2.1 对R进行描述性分析
# 根据time_gap分组聚合,赋值给R
R = df["time_gap"].groupby(df["time_gap"]).count()# 计算各部分人数,对应的比例
R_percent = R / 51394# 导入matplotlib.pyplot模块,简写为plt
import matplotlib.pyplot as plt# 通过给 plt.rcParams["font.sans-serif"] 赋值
# 将字体设置为 Arial Unicode MS
plt.rcParams["font.sans-serif"] = "Arial Unicode MS"# 使用plt.bar()函数
# 以R_percent的index为x轴的值,R_percent的values为y轴的值
plt.bar(R_percent.index, R_percent.values)# 展示图像
plt.show()
3.2分析结果说明
这个横轴表示的就是这个最近一次购买时间到这个参照时间的时间差值,我们可以看到这个函数的图形是一个下降的趋势,刚开始很快,后来变得很慢;
3.3对于F的描述性分析
这个和上面的完全一样,就是把这个对应的参数换成了订单的数量count;l
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1.1 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 1.2 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''对R、F、M进行描述性分析'''
# 2.2 对F进行描述性分析
# TODO 根据order_count分组聚合,赋值给F
F = df["order_count"].groupby(df["order_count"]).count()# TODO 计算各部分人数,对应的比例,赋值给F_percent
F_percent=F/51394# 导入matplotlib.pyplot模块,简写为plt
import matplotlib.pyplot as plt# 通过给 plt.rcParams["font.sans-serif"] 赋值
# 将字体设置为 Arial Unicode MS
plt.rcParams["font.sans-serif"] = "Arial Unicode MS"# TODO 使用plt.bar()函数
# 以F_percent的index为x轴的值,F_percent的values为y轴的值
plt.bar(F_percent.index, F_percent.values)# 展示图像
plt.show()
这个我们就可以看出来,count越大,这个对应的人数越少,这个存在一个长尾的现象,因为大部分的人的购买次数都很少;
3.4对于M的描述性分析
如果这个M我们依然使用上面的方法去进行分析,这个时候绘图的效果就不是很好,如下所示:
###因此这个我们调整绘图策略,把这个结果绘制成为直方图:
###直方图的绘制使用的就是hist函数,这个bins参数表示的就是这个对应的横轴上面的标度情况
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1.1 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 1.2 获取描绘R的数据
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''对R、F、M进行描述性分析'''
# 2.3 对M进行描述性分析
# 导入matplotlib.pyplot模块,简写为plt
import matplotlib.pyplot as plt# 通过给 plt.rcParams["font.sans-serif"] 赋值
# 将字体设置为 Arial Unicode MS
plt.rcParams["font.sans-serif"] = "Arial Unicode MS"# TODO 使用plt.hist()函数
# 将df["total_amount"]这一列数据传入,并传入参数bins =100
plt.hist(df["total_amount"], bins =100)# 用show()函数展示图像
plt.show()
可以看出来这个消费的总金额越少,人数就会越多,金额越多,对应的消费人数就会越少;
4.数据分箱--等级划分
4.1分箱概念
4.3分箱特点
###相同的数值一定会在一个箱子里面;
###区间的特点是左开右闭的情况;
###相邻两个箱子的临界值是一样的(类似于这个数学上面分段函数的衔接点)
4.3分箱方式
按照数据进行分箱:例如这个分数90-100,80-90等等之类的----cut函数
###这个函数的参数有两个,第一个就是等待进行分箱的数据集,第二个就是分箱的边界数值,这个结果就是按照我们的参数把这个区间划分出来;
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1.1 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 1.2 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 1.1 划分R
# TODO 使用cut()函数,对"time_gap"进行数据分箱
# 以0,50,100,200,300,365为边界分为5组
# 将结果添加为df的"R"列
df["R"] = pd.cut(df["time_gap"], [0,50,100,200,300,365])# TODO 使用value_counts()函数
# 计算df["R"]每个区间的值,赋值给R_value
R_value = df["R"].value_counts()# 使用print输出R_value
print(R_value)
按照比例进行分箱:例如分数段里面的前10%,10%-20%之类的这样的分数段的划分---qcut函数
###这个函数的第二个参数是需要把这个数据集划分的区间的个数;
###我们也可以使用下面的labels参数进行这个区间的命名;
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1.1 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 1.2 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 使用qcut()函数,对"time_gap"进行数据分箱
# 均分为5组,将结果添加为df的"R"列
df["R"] = pd.qcut(df["time_gap"], q=5)# 使用print输出df["R"]
print(df["R"])
对于FM的划分:
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1. 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 2. 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime
# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)
# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]
# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 1. 划分R
# 使用qcut()函数,将"time_gap"的数据分箱
# 均分为5组,区间标记命名为5-1,赋值给df["R"]
df["R"] = pd.qcut(df["time_gap"],q=5,labels=[5,4,3,2,1])# 2. 划分F
# TODO 使用qcut()函数,将"order_count"的数据分箱
# 均分为5组,区间标记命名为1-5,赋值给df["F"]
df["F"] = pd.qcut(df["order_count"],q=5,labels=[1,2,3,4,5])# 输出此时的df["F"]
print(df["F"])
对于M的划分:
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1. 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 2. 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime
# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)
# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]
# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 1. 划分R
# 使用qcut()函数,将"time_gap"的数据分箱
# 均分为5组,区间标记命名为5-1,赋值给df["R"]
df["R"] = pd.qcut(df["time_gap"],q=5,labels=[5,4,3,2,1])# 2. 划分F
# 使用qcut()函数,将"order_count"的数据分箱
# 均分为5组,区间标记命名为1-5,赋值给df["F"]
df["F"] = pd.qcut(df["order_count"],q=5,labels=[1,2,3,4,5])# 3. 划分M
# 使用qcut()函数,将"total_amount"的数据分箱
# 均分为5组,赋值给df["M"]
df["M"] = pd.qcut(df["total_amount"],q=5)# 使用value_counts()函数
# 计算df["M"]每个区间的值,赋值给M_value
M_value = df["M"].value_counts()# 计算各部分人数,对应的比例,赋值给M_percent
M_percent = M_value / 51394# 输出M_value
print(M_value)# 输出M_percent
print(M_percent)
4.4总结分析
为什么这个地方进行分箱的时候,这个第一个R是label=54321,后面的两个的labels是12345,这个和我们的相关性有关,R是越小越好,FM都是越大越好,因此这个参数是不一样的,我们在最开始的时候就说明了这个问题;
5.综合评价
###这个地方的划分都是0、1划分,因此我们定一个函数,然后把这个函数的划分方式全部应用于这三个分箱结果上面;
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1. 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 2. 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime
# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)
# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]
# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 1. 划分R
# 使用qcut()函数,将"time_gap"的数据分箱
# 均分为5组,区间标记命名为5-1,赋值给df["R"]
df["R"] = pd.qcut(df["time_gap"],q=5,labels=[5,4,3,2,1])# 2. 划分F
# 使用qcut()函数,将"order_count"的数据分箱
# 均分为5组,区间标记命名为1-5,赋值给df["F"]
df["F"] = pd.qcut(df["order_count"],q=5,labels=[1,2,3,4,5])# 3. 划分M
# 使用qcut()函数,将"total_amount"的数据分箱
# 均分为5组,区间标记命名为1-5分,赋值给df["M"]
df["M"] = pd.qcut(df["total_amount"],q=5,labels=[1,2,3,4,5])'''对用户标记分层结果'''
# 1. 简化分值
# 定义一个函数rfmTrans,如果参数x>3,就返回1;否则,就返回0
def rfmTrans(x):if x>3:return 1else:return 0# 对R、F、M这三列数据,分别使用apply()函数
# 将函数名rfmTrans作为参数传入,并分别重新赋值给R、F、M这三列
df["R"] = df["R"].apply(rfmTrans)
df["F"] = df["F"].apply(rfmTrans)
df["M"] = df["M"].apply(rfmTrans)# 使用print输出R、F、M这三列
print(df[["R","F","M"]])
接下俩的这个操作就是对于这个RFM各自的结果进行组合astype加起来,类似于这个二进制位一样的组合,然后把这个对应的评价用户评价类型进行匹配;
# 导入pandas模块
import pandas as pd '''获取描绘R、F、M的数据'''
# 1. 读取并处理数据集
# 读取文件
df = pd.read_csv("/Users/user_info/user_info.csv")
# 数据类型转换
df["last_order_date"] = pd.to_datetime(df["last_order_date"])# 2. 获取描绘R的数据
# 导入datetime模块中的datetime
from datetime import datetime
# 使用datetime()函数,构建2019年4月1日的时间,赋值给endTime
endTime = datetime(2019,4,1)
# 计算endTime和"last_order_date"这一列的时间间隔
df["time_gap"] = endTime - df["last_order_date"]
# 通过.dt.days,将"time_gap"列的天数提取出来
df["time_gap"] = df["time_gap"].dt.days'''依次划分R、F、M'''
# 1. 划分R
# 使用qcut()函数,将"time_gap"的数据分箱
# 均分为5组,区间标记命名为5-1,赋值给df["R"]
df["R"] = pd.qcut(df["time_gap"],q=5,labels=[5,4,3,2,1])# 2. 划分F
# 使用qcut()函数,将"order_count"的数据分箱
# 均分为5组,区间标记命名为1-5,赋值给df["F"]
df["F"] = pd.qcut(df["order_count"],q=5,labels=[1,2,3,4,5])# 3. 划分M
# 使用qcut()函数,将"total_amount"的数据分箱
# 均分为5组,区间标记命名为1-5分,赋值给df["M"]
df["M"] = pd.qcut(df["total_amount"],q=5,labels=[1,2,3,4,5])'''对用户标记分层结果'''
# 1. 简化分值
# 定义一个函数rfmTrans,如果参数x>3,就返回1;否则,就返回0
def rfmTrans(x):if x>3:return 1else:return 0# 对R、F、M这三列数据,分别使用apply()函数
# 将函数名rfmTrans作为参数传入,并分别重新赋值给R、F、M这三列
df["R"] = df["R"].apply(rfmTrans)
df["F"] = df["F"].apply(rfmTrans)
df["M"] = df["M"].apply(rfmTrans)# 2. 获取数值标签
# 用astype()函数将R、F、M这三列转化为字符串格式
# 再用"+"把字符串拼接在一起,组成一个新的列"mark"
df["mark"] = df["R"].astype(str)+df["F"].astype(str)+df["M"].astype(str)# 3. 标记用户层级
# 定义一个函数rfmType,将数据标签,转化为对应的用户分层
def rfmType(x):if x=="111":return "高价值用户"elif x=="101":return "重点发展用户"elif x=="011":return "重点唤回用户"elif x=="001":return "重点潜力用户"elif x=="110":return "一般潜力用户"elif x=="100":return "一般发展用户"elif x=="010":return "一般维系用户"else:return "低价值用户"# TODO 对"mark"列,使用apply()函数
# 将函数名rfmType作为参数传入,并将结果赋值给df["customer_type"]
df["customer_type"] = df["mark"].apply(rfmType)# 输出"customer_type"这一列
print(df["customer_type"])
6.K中心聚类分析
1.1数据的标准化处理
我们对于拿到的这个数据,可以看到一共是三类数据,一类是这个煤炭的消耗量,一类是这个电的消耗量,一类是这个单位工业增加值煤的消耗量,他们的数量级有很大的差异,不便于我们进行计算,我们首先使用描述性分析对于这个数据进行标准化处理;
我们勾选下面的这个把标准化另存为变量,这个就是我们的描述性分析想要达到的结果;
1.2标准化处理的结果
在原来的指标上面,标准化处理之后成为新的变量,方便我们后续的操作;
1.3K均值聚类分析
变量使用的就是我们标准化之后的变量,标注依据就是我们不同的地区,这个聚类数量可以从默认的2更改为3;
1.4分析结果说明
可以看到这个分析之后是被划分为三类,这个第一类就是三个指标都很低,第三类就是三个指标都很高,如何查看这个分类结果呢,在不关闭这个窗口的前提下,我们切换到原来的窗口,也就是数据窗口,就可以看到这个表格里多了一列QCL,这一类就是显示每一个城市对应的1,2,3类的结果
这篇关于数学建模~~描述性分析---RFM用户分层模型聚类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!