数据分析 — 电商用户分析和用户 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

相关文章

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

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应