Python综合数据分析_RFM用户分组模型

文章目录

  • 1.导入数据
  • 2.月度订单数据可视化
  • 3.数据清洗
  • 4.特征工程
  • 5.构建User用户表
  • 6.求R值
  • 7.求F值
  • 8.求M值
  • 9.显示R、F、M值的分布情况
  • 10.显示手肘图辅助确定K值
  • 11.创建和训练模型
  • 12.给R值聚类
  • 13.给聚类后的层级排序
  • 14.继续给F、M值聚类,并排序
  • 15.为用户整体分组画像


1.导入数据

import pandas as pd #导入Pandas
df_sales = pd.read_csv('data.csv') #载入数据
df_sales.head() #显示头几行数据 

在这里插入图片描述

2.月度订单数据可视化

import matplotlib.pyplot as plt #导入Matplotlib的pyplot模块
#构建月度的订单数的DataFrame
df_sales['消费日期'] = pd.to_datetime(df_sales['消费日期']) #转化日期格式
df_orders_monthly = df_sales.set_index('消费日期')['订单号'].resample('M').nunique()
#设定绘图的画布
ax = pd.DataFrame(df_orders_monthly.values).plot(grid=True,figsize=(12,6),legend=False)
ax.set_xlabel('月份') # X轴label
ax.set_ylabel('订单数') # Y轴Label
ax.set_title('月度订单数') # 图题
#设定X轴月份显示格式
plt.xticks(range(len(df_orders_monthly.index)), [x.strftime('%m.%Y') for x in df_orders_monthly.index], rotation=45)
plt.show() # 绘图

在这里插入图片描述

3.数据清洗

df_sales = df_sales.drop_duplicates() #删除重复的数据行
df_sales.isna().sum() # NaN出现的次数

在这里插入图片描述

df_sales.describe() #df_sales的统计信息

在这里插入图片描述

df_sales = df_sales.loc[df_sales['数量'] > 0] #清洗掉数量小于等于0的数据
df_sales.describe() #df_sales的统计信息

在这里插入图片描述

4.特征工程

df_sales['总价'] = df_sales['数量'] * df_sales['单价'] #计算每单的总价
df_sales.head() #显示头几行数据  

在这里插入图片描述

5.构建User用户表

df_user = pd.DataFrame(df_sales['用户码'].unique()) #生成以用户码为主键的结构df_user
df_user.columns = ['用户码'] #设定字段名
df_user = df_user.sort_values(by='用户码',ascending=True).reset_index(drop=True) #按用户码排序
df_user #显示df_user

在这里插入图片描述

6.求R值

df_sales['消费日期'] = pd.to_datetime(df_sales['消费日期']) #转化日期格式
df_recent_buy = df_sales.groupby('用户码').消费日期.max().reset_index() #构建消费日期信息
df_recent_buy.columns = ['用户码','最近日期'] #设定字段名
df_recent_buy['R值'] = (df_recent_buy['最近日期'].max() - df_recent_buy['最近日期']).dt.days #计算最新日期与上次消费日期的天数
df_user = pd.merge(df_user, df_recent_buy[['用户码','R值']], on='用户码') #把上次消费距最新日期的天数(R值)合并至df_user结构
df_user.head() #显示df_user头几行数据

在这里插入图片描述

7.求F值

df_frequency = df_sales.groupby('用户码').消费日期.count().reset_index() #计算每个用户消费次数,构建df_frequency对象
df_frequency.columns = ['用户码','F值'] #设定字段名称
df_user = pd.merge(df_user, df_frequency, on='用户码') #把消费频率整合至df_user结构
df_user.head() #显示头几行数据

在这里插入图片描述

8.求M值

df_revenue = df_sales.groupby('用户码').总价.sum().reset_index() #根据消费总额,构建df_revenue对象
df_revenue.columns = ['用户码','M值'] #设定字段名称
df_user = pd.merge(df_user, df_revenue, on='用户码') #把消费金额整合至df_user结构
df_user.head() #显示头几行数据

在这里插入图片描述

9.显示R、F、M值的分布情况

df_user['R值'].plot(kind='hist', bins=20, title = '新进度分布直方图') #R值直方图

在这里插入图片描述

df_user.query('F值 < 800')['F值'].plot(kind='hist', bins=50, title = '消费频率分布直方图') #F值直方图

在这里插入图片描述

df_user.query('M值 < 20000')['M值'].plot(kind='hist', bins=50, title = '消费金额分布直方图') #M值直方图

在这里插入图片描述

10.显示手肘图辅助确定K值

from sklearn.cluster import KMeans #导入KMeans模块
def show_elbow(df): #定义手肘函数distance_list = [] #聚质心的距离(损失)K = range(1,9) #K值范围for k in K:kmeans = KMeans(n_clusters=k, max_iter=100) #创建KMeans模型kmeans = kmeans.fit(df) #拟合模型distance_list.append(kmeans.inertia_) #创建每个K值的损失plt.plot(K, distance_list, 'bx-') #绘图plt.xlabel('k') #X轴plt.ylabel('距离均方误差') #Y轴plt.title('k值手肘图') #标题
show_elbow(df_user[['R值']]) #显示R值聚类K值手肘图

在这里插入图片描述

show_elbow(df_user[['F值']]) #显示F值聚类K值手肘图

在这里插入图片描述

show_elbow(df_user[['M值']]) #显示M值聚类K值手肘图

在这里插入图片描述

11.创建和训练模型

from sklearn.cluster import KMeans #导入KMeans模块
kmeans_R = KMeans(n_clusters=3) #设定K=3
kmeans_F = KMeans(n_clusters=4) #设定K=4
kmeans_M = KMeans(n_clusters=4) #设定K=4
kmeans_R.fit(df_user[['R值']]) #拟合模型
kmeans_F.fit(df_user[['F值']]) #拟合模型
kmeans_M.fit(df_user[['M值']]) #拟合模型

在这里插入图片描述

12.给R值聚类

df_user['R值层级'] = kmeans_R.predict(df_user[['R值']]) #通过聚类模型求出R值的层级
df_user.head() #显示头几行数据

在这里插入图片描述

df_user.groupby('R值层级')['R值'].describe() #R值层级分组统计信息

在这里插入图片描述

13.给聚类后的层级排序

#定义一个order_cluster函数为聚类排序
def order_cluster(cluster_name, target_name,df,ascending=False):new_cluster_name = 'new_' + cluster_name #新的聚类名称df_new = df.groupby(cluster_name)[target_name].mean().reset_index() #按聚类结果分组,创建df_new对象df_new = df_new.sort_values(by=target_name,ascending=ascending).reset_index(drop=True) #排序df_new['index'] = df_new.index #创建索引字段df_new = pd.merge(df,df_new[[cluster_name,'index']], on=cluster_name) #基于聚类名称把df_new还原为df对象,并添加索引字段df_new = df_new.drop([cluster_name],axis=1) #删除聚类名称df_new = df_new.rename(columns={"index":cluster_name}) #将索引字段重命名为聚类名称字段return df_new #返回排序后的df_new对象
df_user = order_cluster('R值层级', 'R值', df_user, False) #调用簇排序函数
df_user = df_user.sort_values(by='用户码',ascending=True).reset_index(drop=True) #根据用户码排序
df_user.head() #显示头几行数据

在这里插入图片描述

df_user.groupby('R值层级')['R值'].describe() #R值层级分组统计信息

在这里插入图片描述

14.继续给F、M值聚类,并排序

df_user['F值层级'] = kmeans_F.predict(df_user[['F值']]) #通过聚类模型求出F值的层级
df_user = order_cluster('F值层级', 'F值',df_user,True) #调用簇排序函数
df_user.groupby('F值层级')['F值'].describe() #F值层级分组统计信息

在这里插入图片描述

df_user = df_user.sort_values(by='用户码',ascending=True).reset_index(drop=True) #根据用户码排序
df_user.head()

在这里插入图片描述

df_user['M值层级'] = kmeans_M.predict(df_user[['M值']]) #通过聚类模型求出M值的层级
df_user = order_cluster('M值层级', 'M值',df_user,True) #调用簇排序函数
df_user.groupby('M值层级')['M值'].describe() #M值层级分组统计信息
df_user = df_user.sort_values(by='用户码',ascending=True).reset_index(drop=True) #根据用户码排序
df_user.head() #显示头几行数据

在这里插入图片描述

15.为用户整体分组画像

df_user['总分'] = df_user['R值层级'] + df_user['F值层级'] + df_user['M值层级'] #求出每个用户RFM总分
#在df_user对象中添加总体价值这个字段
df_user.loc[(df_user['总分']<=2) & (df_user['总分']>=0), '总体价值'] = '低价值' 
df_user.loc[(df_user['总分']<=4) & (df_user['总分']>=3), '总体价值'] = '中价值' 
df_user.loc[(df_user['总分']<=8) & (df_user['总分']>=5), '总体价值'] = '高价值'
df_user #显示df_user

在这里插入图片描述

#显示高、中、低价值组分布散点图(F值与M值)
plt.scatter(df_user.query("总体价值 == '高价值'")['F值'],df_user.query("总体价值 == '高价值'")['M值'],c='g',marker='*')
plt.scatter(df_user.query("总体价值 == '中价值'")['F值'],df_user.query("总体价值 == '中价值'")['M值'],marker=8)
plt.scatter(df_user.query("总体价值 == '低价值'")['F值'],df_user.query("总体价值 == '低价值'")['M值'],c='r')

在这里插入图片描述


参考资料:极客时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/335938.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库连接池配置生成、读取二维码集成多数据源入参字段定义为Date类型,支持时间戳及年-月-日

数据库连接池配置 # 数据源配置 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主库数据源master:url: jdbc:mysql://localhost:3306/database?useUnicodetrue&characterEncodingutf8&zeroDateT…

数据库:如何取消mysql的密码

因为调试MySQL数据接口&#xff0c;总是需要输入密码很烦&#xff0c;所以决定取消mysql的root密码&#xff0c; 网上推荐的有两种方法&#xff1a; 1、mysql命令 SET PASSWORD FOR rootlocalhostPASSWORD(); 2、运行 mysqladmin 命令 mysqladmin -u root -p password …

Docker与微服务实战(基础篇)

Docker与微服务实战&#xff08;基础篇&#xff09; 1、Docker简介2、Docker安装步骤1.Centos7及以上的版本2.卸载旧版本3.yum安装gcc相关4.安装需要的软件包5.设置stable镜像仓库【国内aliyun】6.更新yum软件包索引--以后安装更快捷7.安装Docker-Ce8.启动Docker9.测试10.卸载1…

2024.01.09.Apple_UI_BUG

我是软件行业的&#xff0c;虽然不是手机设计的&#xff0c;但是这个设计真的导致经常看信息不完整&#xff0c;要下拉的。 特别读取文本或者其他文件的时候&#xff0c;上面有个抬头就是看不到&#xff0c;烦&#xff0c;体验感很差

解决在eclipse2021中,用mysql-connector-java-8.0.18.jar不兼容,导致无法访问数据库问题

1.环境场景 组件版本mysql5.7.44mysql-connector-java80.18 2. 问题描述 报mysql-connector-java 驱动连不上mysql数据库。 3. 可能的原因分析 查看数据库连接句柄是否对 如果数据库连接句柄中没有 useSSLfalse 的话可能会导致这样的问题。 就像下面这样&#xff1a; jdb…

MySQL的导入导出及备份

一.准备导入之前 二.navicat导入导出 ​编辑 三.MySQLdump命令导入导出 四.load data file命令的导入导出 五.远程备份 六. 思维导图 一.准备导入之前 需要注意&#xff1a; 在导出和导入之前&#xff0c;确保你有足够的权限。在进行导入操作之前&#xff0c;确保目标数据…

【npm link】Node命令中的npm link命令的使用,还有CLI全局命令的使用,开发命令行工具必不可少的部分

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;NodeJs &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继续前进的勇气…

【服务器数据恢复】FreeNAS+ESXi数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器&#xff0c;虚拟化系统为esxi&#xff0c;上层使用iSCSI的方式实现FC SAN功能&#xff0c;iSCSI通过FreeNAS构建。 FreeNAS采用了UFS2文件系统&#xff0c;esxi虚拟化系统里有3台虚拟机&#xff1a;其中一台虚拟机安装FreeBSD系统&a…

spring模块(二)IOC容器之BeanFactory

在Spring中实现控制反转的是IoC容器 &#xff08;1&#xff09;IoC 不是一种技术&#xff0c;只是一种思想&#xff0c;一个重要的面向对象编程的法则&#xff0c;它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象&#xff0c;从…

C++协程操作

什么是C++协程 C++中的协程是一种用户态轻量级线程,它拥有自己的上下文和栈,并且协程的切换和调度由用户定义,不需要陷入内核。如同一个进程可以拥有多个线程,一个线程也可以拥有多个协程。协程的优点在于极高的执行效率,因为协程切换不需要陷入内核,而是由用户程序定义切…

ta-lib安装问题

l解决error: command ‘x86_64-linux-gnu-gcc‘ failed with exit status 1_raise compileerror(msg) distutils.errors.compileer-CSDN博客u文章浏览阅读7.8k次&#xff0c;点赞2次&#xff0c;收藏5次。查看自己python的版本&#xff0c;然后下载自己版本Python的devel&#…

shp格式样本转微软COCO格式样本标注

在做影像识别时&#xff0c;需要大量的样本&#xff0c;对于从事GIS和遥感专业的人员来说&#xff0c;可能使用ArcGIS对着影像&#xff0c;绘制样本效率更高。但是很多框架和开源的代码都是基于PASCAL VOC格式和微软COCO格式的样本。这里我分享一下如何将栅格和shp数据转换微软…