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

2024-02-20 22:12

本文主要是介绍数据分析 — 电商用户分析和用户 RFM 模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、电商用户分析
    • 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()

在这里插入图片描述

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

这篇关于数据分析 — 电商用户分析和用户 RFM 模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/729687

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA