数据分析 — 电商用户分析和用户 RFM 模型

news2024/10/7 8:23:31

目录

  • 一、电商用户分析
    • 1、数据字段信息
    • 2、数据读取
    • 3、数据清洗
    • 4、可视化分析
      • 1、每年销售额的增长情况
      • 2、各个地区分店的销售额
      • 3、每个分店每一年的销售额
      • 4、销售淡旺季
      • 5、新增用户
  • 二、RFM 模型
    • 1、RFM 模型的三个维度
    • 2、RFM 的客户类型标签
    • 3、RFM 模型的二分法思想
    • 4、代码

一、电商用户分析

1、数据字段信息

字段说明
RowID行编号
OrderID订单 ID
OrderDate订单日期
ShipDate发货日期
ShipMode发货模式
CustomerID客户 ID
CustomerName客户姓名
Segment客户类别
City客户所在城市
State客户所在州
Country客户所在国家
PostalCode邮编
Market商店所属区域
Region商店所属州
ProductID产品 ID
Category产品类别
Sub-Category产品子类别
ProductName产品名称
Sales售价
Quantity销售量
Discount折扣
Profit利润
ShippingCost发货成本
OrderPriority订单优先级

2、数据读取

import pandas as pd  # 导入 Pandas 库并使用别名 pd
# 读取 CSV 文件,使用 gbk 编码
data = pd.read_csv(r'F:\data\dataset.csv', encoding='gbk')
print(data)

在这里插入图片描述

# 打印数据的列名
print(data.columns)

在这里插入图片描述

# 重新命名数据的列名
data.columns = ['行编号', '订单ID', '订单日期', '发货日期', '发货模式', '客户ID', '客户姓名', '客户类别', '客户所在城市', '客户所在州', '客户所在国家', '邮编', '商店所属区域', '商店所属州', '产品ID', '产品类别', '产品子类别', '产品名称', '售价', '销售量', '折扣', '利润', '发货成本', '订单优先级']
print(data.head())

在这里插入图片描述

3、数据清洗

在这里插入图片描述

# 打印数据的基本信息
data.info()

在这里插入图片描述

# 1、发货日期 - 订单日期 >= 0,异常的数据 < 0
# 将 '发货日期' 和 '订单日期' 列的数据类型转换为 datetime
data['发货日期'] = pd.to_datetime(data['发货日期'])
data['订单日期'] = pd.to_datetime(data['订单日期'])
# 计算 '发货秒数' 列,表示发货日期与订单日期的时间差(秒)
data['发货秒数'] = (data['发货日期'] - data['订单日期']).dt.total_seconds()

# 删除发货日期早于订单日期的
data.drop(index=data[data['发货秒数'] < 0].index, inplace=True)  # drop() 这里是按索引删除
print(data.head())

在这里插入图片描述

# 打印数据的形状
print(data.shape)  # (51097, 25)
# 2、删除售价为负数据(异常数据)
# 查找 '售价' 列小于 0 的行
print(data[data['售价'] < 0])
# 没有售价为负的,不用处理

在这里插入图片描述

# 打印数据的信息
data.info()

在这里插入图片描述

# 3、查看空值,重复值
# 打印每列的缺失值数量
print(data.isnull().sum())

在这里插入图片描述

# 计算 '行编号' 列的唯一值数量
print(data['行编号'].unique().size)  # 51094
# 删除重复的 '行编号' 行(去重)
data.drop_duplicates('行编号', inplace=True)
data.info()

在这里插入图片描述

# 清洗 '发货模式' 
# 打印 '发货模式' 列的缺失值数量
print(data['发货模式'].isnull().sum())  # 11
# 打印 '发货模式' 列的众数(出现次数最多的)
print(data['发货模式'].mode())
# 0    Standard Class
# dtype: object
# 打印 '发货模式' 列的类型
print(type(data['发货模式'].mode()))
# <class 'pandas.core.series.Series'>

# 用众数填充 '发货模式' 列的缺失值
data['发货模式'].fillna(value=data['发货模式'].mode()[0], inplace=True)
# 打印 '发货模式' 列的缺失值数量
print(data['发货模式'].isnull().sum())  # 0
# 删除 '邮编' 列(缺失多且对本次分析无用)
data.drop(columns=['邮编'], inplace=True)
data.info()

在这里插入图片描述

# 打印数据的描述统计信息
print(data.describe())

在这里插入图片描述

# 清洗 '折扣' 
# 查找 '折扣' 列大于 1 的行
print(data[data['折扣'] > 1])

在这里插入图片描述

# 将 '折扣' 列大于 1 的值替换为 None
data['折扣'] = data['折扣'].mask(data['折扣'] > 1, None)
# 用 '折扣' 列的均值填充缺失值
data['折扣'].fillna(value=round(data['折扣'].mean(), 2), inplace=True)
# 打印数据的描述统计信息
print(data.describe())

在这里插入图片描述

# 清洗 '订单日期'
# 添加 '下订单年'、'下订单月' 和 '下订单季度' 列
data['下订单年'] = data['订单日期'].dt.year
data['下订单月'] = data['订单日期'].dt.month
data['下订单季度'] = data['订单日期'].dt.to_period('Q')
print(data.head())

在这里插入图片描述

# 查找重复的行数
print(data.duplicated().sum())  # 0

4、可视化分析

1、每年销售额的增长情况

# 创建一个新的列'销售额',计算售价与销售量的乘积,表示销售额
data['销售额'] = data['售价']*data['销售量']
# 打印数据的前几行,用于查看新增的销售额列
print(data.head())

在这里插入图片描述

# 根据'下订单年'列分组,计算每年的销售额总和
sales_year = data.groupby('下订单年')['销售额'].sum()
# 打印每年的销售额总和
print(sales_year)
# 下订单年
# 2011    1.110551e+07
# 2012    1.290868e+07
# 2013    1.667801e+07
# 2014    2.090141e+07
# Name: 销售额, dtype: float64
# 计算每年的销售额增长率,分别以2012年、2013年、2014年为基准年
sales_year_12 = (sales_year[2012]/sales_year[2011]) -1
sales_year_13 = (sales_year[2013]/sales_year[2012]) -1
sales_year_14 = (sales_year[2014]/sales_year[2013]) -1
# 打印销售额增长率
print(sales_year_12, sales_year_13, sales_year_14)
# 0.16236705386979122 0.29200004761249243 0.2532315853953533
# 创建一个包含年销售额和订单增长率的数据框
sales_rate = pd.DataFrame({
    '年销售额':sales_year,
    '订单增长率':[0, sales_year_12, sales_year_13, sales_year_14]
})
# 打印包含销售额和增长率的数据框
print(sales_rate)

在这里插入图片描述

import matplotlib.pyplot as plt  # 导入 Matplotlib 库
# 设置字体为中文黑体
plt.rcParams['font.family'] = 'SimSun'

# 准备绘图所需的数据
x = [str(value) for value in sales_rate.index.tolist()]  # 把数值转成字符串
# 两个 y 轴数据差距很大,但又要画在同一个图里.可以使用双 y 轴
y1 = sales_rate['年销售额']
y2 = sales_rate['订单增长率']

# 创建一个包含两个子图的图表,并设置图表大小
fig = plt.figure(figsize=(10,6))
# 新建子图1 
ax1 = fig.add_subplot(1,1,1)
# ax2 与 ax1 共享 x 轴
ax2 = ax1.twinx()

# 绘制柱状图表示年销售额
ax1.bar(x, y1, color='blue', label='年销售额')

# 绘制折线图表示年增长率
ax2.plot(x, y2, marker='*', color='r', linewidth=3, markersize='10', label='年增长率')

# 添加x轴标签
ax1.set_xlabel('年份', fontsize=20)
ax1.set_ylabel('年销售额', fontsize=20)
ax2.set_ylabel('年增长率', fontsize=20)

# 设置刻度 
ax1.tick_params(axis='x', labelsize=15)
ax1.tick_params(axis='y', labelsize=15)
ax2.tick_params(axis='y', labelsize=15)

# 设置图例位置和外边界框
ax1.legend(loc='upper right', bbox_to_anchor=(1.25, 1))
ax2.legend(loc='upper right', bbox_to_anchor=(1.25, 1.08))

# 显示图表
plt.show()

在这里插入图片描述

结论:

年销售额逐年递增。

2、各个地区分店的销售额

# 打印数据的前几行,用于查看数据的整体情况
print(data.head())

在这里插入图片描述

# 打印数据的基本信息,包括列的数据类型和非空值数量
data.info()

在这里插入图片描述

# 根据'商店所属区域'列分组,计算各区域的销售额总和
sales_area = data.groupby('商店所属区域')['销售额'].sum()
# 打印各区域的销售额总和
print(sales_area)

在这里插入图片描述

# 绘制销售额占比的饼图,以百分比形式显示,设置标题和字体大小,以及图表大小
sales_area.plot(kind='pie', autopct='%1.1f%%', title='2011年-2014各分店销售额占比', fontsize=15, figsize=(10,10))
# 显示图表
plt.show()

在这里插入图片描述

结论:

APAC 分店销售额占比最高,近1/3。

3、每个分店每一年的销售额

# 打印数据的基本信息,包括列的数据类型和非空值数量
data.info()

在这里插入图片描述

# 使用数据透视表,根据'商店所属区域'和'下订单年',计算不同地区每年的销售额总和
sales_area2 = pd.pivot_table(data, index='商店所属区域', columns='下订单年', values='销售额', aggfunc='sum')
# 打印不同地区每年销售额的数据透视表
print(sales_area2)

在这里插入图片描述

# 绘制柱状图,对比2011年-2014年不同地区每年的销售额
sales_area2.plot(kind='bar', title='2011年-2014年不同地区每年销售额对比', figsize=(10, 6), fontsize=15)
# 显示图表
plt.show()

在这里插入图片描述

结论:

销售额逐年增长。

4、销售淡旺季

# 使用数据透视表,根据'下订单月'和'下订单年',计算每年每月的销售额总和
sales_year_month = pd.pivot_table(data, index='下订单月', columns='下订单年', values='销售额', aggfunc='sum')
# 打印每年每月销售额的数据透视表
print(sales_year_month)

在这里插入图片描述

# 绘制折线图,显示每年每月的销售额趋势,并添加图例
sales_year_month.plot(fontsize=15, figsize=(10, 6)).legend(fontsize=15)
# 显示图表
plt.show()

在这里插入图片描述

结论:

旺季 6月和11月,淡季 2月 4月 7月。

5、新增用户

# 求每年每月的新增用户数
# 复制原始数据,以便后续分析客户相关信息
data_customer = data.copy()
# print(data_customer)

# 新用户,第一次购买,对用户进行去重
# 根据'客户ID'去重,保留第一次出现的记录
data_customer = data_customer.drop_duplicates(subset='客户ID')
# print(data_customer)

# 按年按月分组聚合
# 使用数据透视表,根据'下订单月'和'下订单年',计算每年每月不同客户的数量
customer_year_month = pd.pivot_table(data_customer, index='下订单月', columns='下订单年', values='客户ID', fill_value=0, aggfunc='count')
# 打印每年每月不同客户的数量的数据透视表
print(customer_year_month)

在这里插入图片描述

二、RFM 模型

1、RFM 模型的三个维度

Recency(最近购买时间):

这个维度衡量客户最近一次购买的时间,通常以天数来表示。较短的 Recency 值表示客户最近有过购买行为,而较⻓的 Recency 值则表示客户离上次购买较远。Recency 的分析有助于识别哪些客户是“活跃客户”。

Frequency(购买频率):

这个维度衡量客户在一定时间内的购买次数。购买频率高的客户可能更容易进行再营销活动,因为他们已经展现出对产品或服务的兴趣和忠诚度。

Monetary(购买金额):

这个维度衡量客户在一定时间内的总购买金额。购买金额高的客户可能是企业的高价值客户,因此在市场营销活动中可能需要特别关注和激励这一群体。

2、RFM 的客户类型标签

RFM客户类型
011重要价值客户
111重要唤回客户
001重要深耕客户
101重要挽留客户
010潜力客户
110一般维持客户
000新客户
100流失客户

3、RFM 模型的二分法思想

Recency(最近购买时间):

  • R1:最近购买时间较短的客户
  • R2:最近购买时间较⻓的客户

Frequency(购买频率):

  • F1:购买频率较高的客户
  • F2:购买频率较低的客户

Monetary(购买金额):

  • M1:购买金额较高的客户
  • M2:购买金额较低的客户

界定某一数据被分在哪个区间,这里采用平均值来实现,即大于平均值,被分为一类,小于平均值被分为另一类。至于等于平均值,被归于哪一类,实际归到哪一类都可以,只需保证所有数据使用相同的规则即可。

4、代码

# 打印数据集的形状
print(data.shape)  # (51094, 28)
# 输出数据集的信息
data.info()

在这里插入图片描述

# 筛选出 '下订单年' 列为 2014 年的数据
data_14 = data[data['下订单年'] == 2014]
# 打印筛选后的数据集
print(data_14)

在这里插入图片描述

# 复制筛选后的数据集
customerdf = data_14.copy()
# 打印复制后的数据集
print(customerdf)

在这里插入图片描述

# 在复制的数据集中新增一列 '订单数',并将其初始化为 1
customerdf['订单数'] = 1
# 打印修改后的数据集的前几行
print(customerdf.head())

在这里插入图片描述

# 使用 pivot_table 计算 RFM 指标,包括最近购买日期、总订单数和总销售额
rfmdf = customerdf.pivot_table(index='客户ID',
                               values=['订单日期', '订单数', '销售额'],
                               aggfunc={'订单日期': 'max', '订单数': 'sum', '销售额': 'sum'})
# 打印 RFM 指标表
print(rfmdf)

在这里插入图片描述

# 计算最近购买日期距离当前日期的天数,添加一列 'R'
# 把所有交易记录数据里最晚的交易时间看成是现在当前时间
rfmdf['R'] = (rfmdf['订单日期'].max() - rfmdf['订单日期']).dt.days
# 打印添加 'R' 列后的 RFM 指标表
print(rfmdf)

在这里插入图片描述

# 重命名列名为 'R'、'F' 和 'M'
rfmdf.rename(columns={'订单数': 'F', '销售额': 'M'}, inplace=True)
# 打印重命名后的 RFM 指标表
print(rfmdf)

在这里插入图片描述

# 仅保留 'R'、'F'、'M' 列
rfmdf = rfmdf[['R', 'F', 'M']]
# 打印最终的 RFM 指标表
print(rfmdf)

在这里插入图片描述

# 定义函数 rfm_func,根据 RFM 的值给客户打标签,并创建新列 '用户标签'
def rfm_func(x):
    level = x.apply(lambda x: '1' if x > 0 else '0')
    label = level['R'] + level['F'] + level['M']
    d = {
        '011': '重要价值客户',
        '111': '重要唤回客户',
        '001': '重要深耕客户',
        '101': '重要挽留客户',
        '010': '潜力客户',
        '110': '一般维持客户',
        '000': '新客户',
        '100': '流失客户'
    }
    return d[label]
# 应用 rfm_func 函数,创建 '用户标签' 列
rfmdf['用户标签'] = rfmdf.apply(lambda x: x - x.mean()).apply(rfm_func, axis=1)
# 打印添加 '用户标签' 列后的 RFM 指标表
print(rfmdf)

在这里插入图片描述

import matplotlib.pyplot as plt  # 导入 Matplotlib 库
# 设置字体为中文黑体
plt.rcParams['font.family'] = 'SimSun'
plt.style.use('fivethirtyeight')
rfmdf['用户标签'].value_counts().plot.bar(figsize=(20, 9), fontsize=15)
plt.show()

在这里插入图片描述

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法】动态规划1,最小花费爬楼梯,解码方法

一、动态规划简介 动态规划 , 英文名称 Dynamic Programming , 简称 DP , 不是具体的某种算法 , 是一种算法思想 ; 动态规划 , 没有具体的步骤 , 只有一个核心思想 ; 动态规划 的 核心思想 是 由大化小 , 大规模问题 使用 小规模问题 计算结果 解决 , 类似于 分治算法 ; 二、…

ipad作为扩展屏的最简单方式(仅需在同一局域网下,无需数据线)

ipad和win都下载安装toDesk&#xff0c;并且都处于同一局域网下 连接ipad&#xff0c;在ipad中输入win设备的设备密码和临时密码&#xff0c;连接上后可以看到ipad会是win屏幕的镜像&#xff0c;此时退出连接&#xff0c;准备以扩展模式再次连接。 注意&#xff0c;如果直接从…

SOPHON算能科技新版SDK环境配置以及C++ demo使用过程

目录 1 SDK大包下载 2 获取SDK中的库文件和头文件 2.1 注意事项 2.2 交叉编译环境搭建 2.2.1 首先安装工具链 2.2.2 解压sophon-img包里的libsophon_soc__aarch64.tar.gz&#xff0c;将lib和include的所有内容拷贝到soc-sdk文件夹 2.2.3 解压sophon-mw包里的sophon-mw-s…

pyqt如何实现拖拽打开文件(通过windows的快捷方式打开文件)

桌面端的开发中如何通过windows的快捷方式打开文件&#xff0c;那么如何将需要打开的数据传递给qt程序呢&#xff1f; 研究了一下发现很简单 通过sys.argv可以轻松的实现传参 sys.argv import sys print(sys.argv)这个方法可以获取系统传递给程序的参数&#xff0c;默认是个列…

Android 12.0 systemui锁屏页面时钟显示样式的定制功能实现

1.前言 在12.0的系统ROM定制化开发中,在进行systemui的相关开发中,当开机完成后在锁屏页面就会显示时间日期的功能,由于 开发产品的需求要求时间显示周几上午下午接下来就需要对锁屏显示时间日期的相关布局进行分析,然后实现相关功能 效果图如图: 2.systemui锁屏页面时钟显…

Linux搭建JavaEE环境

Linux搭建JavaEE环境 需要在 Linux 下进行 JavaEE 的开发&#xff0c;我们需要安装如下软件 JDKtomcatmysqlidea 安装JDK 安装步骤 首先去官网下载jdk的linux版本 下载地址&#xff1a;https://www.oracle.com/cn/java/technologies/downloads/ 1) mkdir /opt/jdk 2) 通过 …

视频推拉流EasyDSS视频直播点播平台授权出现激活码无效并报错400是什么原因?

视频推拉流EasyDSS视频直播点播平台集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务&#xff0c;在应用场景上&#xff0c;平台可以运用在互联网教育、在线课堂、游戏…

向导式堆栈管理器Dockge

经过申诉&#xff0c;目前博客的几个域名都恢复了&#xff0c;时间也延长到了 2033 年&#xff0c;后面还会不会出问题&#xff0c;老苏就不知道了 什么是 Dockge ? Dockge 是一款时髦的、易于使用的、响应式的、自托管的 docker-compose.yaml 向导式堆栈管理器&#xff0c;可…

flink反压

flink反压&#xff08;backpressure&#xff09;&#xff0c;简单来说就是当接收方的接收速率低于发送方的发送速率&#xff0c;这时如果不做处理就会导致接收方的数据积压越来越多直到内存溢出&#xff0c;所以此时需要一个机制来根据接收方的状态反过来限制发送方的发送速率&…

10、内网安全-横向移动域控提权NetLogonADCSPACKDC永恒之蓝

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正&#xff01; 背景&#xff1a; 主要针对内网主机中的 域控提权漏洞&#xff0c;包含漏洞探针和漏洞复现利用。 1、横向移动-系统漏洞-CVE-2017-0146&#xff08;ms17-010&#xff0c;永恒之蓝&#xff0…

ts环境下如何解决第三方npm包类型报错的问题

在 TypeScript 环境下&#xff0c;当引入第三方 npm 包时出现类型报错的问题&#xff0c;可以尝试以下几种解决方法&#xff1a; 1、安装 types 包&#xff1a;许多流行的第三方 npm 包都有对应的 TypeScript 类型声明文件&#xff0c;这些声明文件通常以 types/包名 的形式发…

odoo16-API(Controller)带有验证访问的接口

odoo16-API&#xff08;Controller&#xff09;带有验证访问的接口 目前我使用odoo原生的登录token来验证登陆的有效性 废话不多说直接上代码 # 测试获取session_id import requests class GetOdooData(http.Controller):def getOdooToken(self):# http://localhost:8123访问…

蓝桥杯:C++素数、进制转换

素数 定义&#xff1a; 质数又称素数。一个大于1的自然数&#xff0c;除了1和它自身外&#xff0c;不能被其他自然数整除的数叫做质数&#xff1b;否则称为合数&#xff08;规定1既不是质数也不是合数&#xff09;。 代码&#xff1a; #include<bits/stdc.h> using n…

【flutter】环境安装

安装flutter sdk 下载sdk flutter sdk就包含dart&#xff0c;所以我们只用安装flutter sdk就可以了。 我们去清华大学开源软件镜像站下载&#xff0c;flutter开发中&#xff0c;版本对不上基本项目就跑步起来&#xff0c;如果是团队协同开发的话&#xff0c;建议统一下载指定版…

ubuntu22.04@Jetson OpenCV安装

ubuntu22.04Jetson OpenCV安装 1. 源由2. 分析3. 证实3.1 jtop安装3.2 jtop指令3.3 GPU支持情况 4. 安装OpenCV4.1 修改内容4.2 Python2环境【不需要】4.3 ubuntu22.04环境4.4 国内/本地环境问题4.5 cudnn版本问题 5. 总结6. 参考资料 1. 源由 昨天用Jetson跑demo程序发现帧率…

算法——排序算法

目录 1、冒泡排序 2、插入排序 3、选择排序 4、归并排序 5、快速排序 6、堆排序 7、计数排序 8、桶排序 9、基数排序 常见的排序算法包括&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;插入排序&#xff08;Insertion Sort&#xff09;选择排序&#xff08;Se…

Element UI 组件的安装及使用

Element UI 组件的安装及使用 Element UI 是一套基于 Vue.js 的桌面端 UI 组件库&#xff0c;提供了丰富的、高质量的 UI 组件&#xff0c;可以帮助开发者快速构建用户界面。 1、安装 Element UI 使用 npm 安装 npm install element-ui -S2、使用 CDN 安装 在 HTML 页面中引…

祖龙娱乐 x Incredibuild

关于祖龙娱乐 祖龙娱乐有限公司&#xff08;下文简称“祖龙娱乐”&#xff09;是一家总部位于北京的移动游戏开发公司&#xff0c;成立于 2014 年&#xff0c;拥有成功的大型多人在线角色扮演游戏移动游戏组合&#xff0c;如《六龙争霸》、《梦幻诛仙》和《万王之王 3D》。公司…

安宝特AR汽车行业解决方案系列1-远程培训

在汽车行业中&#xff0c;AR技术的应用正悄然改变着整个产业链的运作方式&#xff0c;应用涵盖培训、汽修、汽车售后、PDI交付、质检以及汽车装配等&#xff0c;AR技术为多个环节都带来了前所未有的便利与效率提升。 安宝特AR将以系列推文的形式为读者逐一介绍在汽车行业中安宝…

Kotlin基本语法 4 类

1.定义类 package classStudyclass Player {var name:String "jack"get() field.capitalize()set(value) {field value.trim()} }fun main() {val player Player()println(player.name)player.name " asdas "println(player.name)} 2.计算属性与防范…