【Python 实战】基于 K-Means+LRFM 模型实现电商用户价值分群与精准营销分
文章标签
#Python 数据分析 #KMeans 聚类 #LRFM 模型 #电商用户分析 #数据挖掘 #精准营销
前言
在电商行业流量见顶的当下,精细化用户运营已经取代粗放式拉新,成为平台提升营收、降低流失的核心手段。面对海量的订单、付款、用户行为数据,如何快速区分高价值核心用户、沉睡流失用户以及潜力新用户,是数据分析师和电商运营必备的技能。
本文结合LRFM 用户价值模型与K-Means 聚类算法,使用 Python 完成从数据加载、清洗预处理、探索性可视化、特征工程、数据标准化、K 值选取、聚类建模到结果解读、商业策略输出的全流程实战。代码可直接运行,思路贴合真实电商业务场景,适合数据分析初学者、电商运营、大数据相关专业学生学习参考。
一、项目背景与分析思路
1.1 项目背景
随着电子商务飞速发展,平台积累了海量用户交易数据,单纯依靠人工无法完成用户分层。传统 RFM 模型是电商用户分层的经典模型,本次项目在 RFM 基础上增加L(用户生命周期) 维度,构建LRFM 模型,结合无监督学习 K-Means 聚类算法,自动将全网用户划分为不同价值群体,帮助企业针对性制定营销、留存、召回策略,最大化利用营销资源。
1.2 核心模型介绍
本次采用LRFM 四维度用户价值模型,各指标业务含义如下:
表格
| 指标 | 英文全称 | 业务解释 | 价值判断标准 |
|---|---|---|---|
| L | LifeCycle | 用户生命周期,用户首次购买至最后一次购买的时间差 | 数值越大,用户平台陪伴时长越久,忠诚度越高 |
| R | Recency | 最近消费间隔,用户最后一次消费距离数据集最晚时间的天数 | 数值越小,用户越活跃,流失风险越低 |
| F | Frequency | 消费频次,用户在统计周期内的下单总次数 | 数值越大,用户复购意愿越强 |
| M | Monetary | 消费总金额,用户累计付款总额 | 数值越大,用户消费能力越强,价值越高 |
1.3 整体分析流程
- 数据探索与预处理:缺失值、异常值、时间格式转换
- 探索性可视化分析:渠道、月份、时段收益、退款数据统计
- 特征工程:基于业务逻辑计算 LRFM 四大核心特征
- 数据标准化:消除量纲差异,适配 K-Means 算法
- K-Means 建模:手肘法确定最优聚类 K 值,完成用户分群
- 结果可视化与解读:饼图、雷达图展示分群特征
- 业务总结:针对不同用户群体输出精准运营策略
二、数据集说明
2.1 数据来源与字段
本次使用某电商平台真实订单数据集(order2021kmeans.xlsx),共计104557 条订单数据,核心字段如下:
- 基础字段:订单顺序编号、订单号、用户名、商品编号
- 金额字段:订单金额、付款金额
- 渠道与平台:渠道编号、平台类型(APP / 微信公众号)
- 时间字段:下单时间、付款时间(时间戳格式)
- 状态字段:是否退款
2.2 运行环境
- Python 3.7+
- 核心库:
pandas(数据处理)、numpy(数值计算)、matplotlib(可视化)、sklearn(K-Means、标准化)、pyecharts(交互式图表)
三、完整代码实现(分步讲解)
3.1 环境初始化与库导入
统一配置中文字体、屏蔽警告,解决 Matplotlib 中文乱码问题:
python
运行
# 导入所需库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from pyecharts.charts import Pie, Line, Radar
from pyecharts import options as opts
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
import warnings
# 配置全局参数
warnings.filterwarnings('ignore') # 忽略无关警告
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
mpl.rcParams['axes.unicode_minus'] = False # 负号显示
plt.rcParams['figure.figsize'] = (10, 6) # 画布大小
3.2 数据加载、探索与预处理(核心基础)
数据预处理是数据分析的重中之重,主要完成查看数据、去重、缺失值、异常值、时间格式转换五大操作。
python
运行
# 1. 读取Excel数据集
data = pd.read_excel(r'order2021kmeans.xlsx')
# 2. 基础数据探索
print("数据前5行:")
print(data.head())
print("\n数据基本信息:")
print(data.info())
print("\n数据描述性统计:")
print(data.describe())
# 3. 数据预处理
## 3.1 去除重复值
print(f"\n重复数据条数:{data.duplicated().sum()}")
data.drop_duplicates(inplace=True)
## 3.2 处理异常值:付款金额存在负数,取绝对值修正
data['付款金额'] = data['付款金额'].abs()
## 3.3 处理缺失值:渠道编号存在少量缺失,直接删除
print(f"缺失值统计:\n{data.isnull().sum()}")
data.dropna(inplace=True)
## 3.4 时间格式转换(关键:后续提取时间特征)
data['下单时间'] = pd.to_datetime(data['下单时间'])
data['付款时间'] = pd.to_datetime(data['付款时间'])
预处理结论:数据集无重复值;仅渠道编号存在少量缺失值,删除后不影响整体分析;付款金额存在负数异常值,通过绝对值修正;时间字段统一转为datetime格式,为时间特征提取做准备。
3.3 探索性可视化分析(业务初步洞察)
从渠道、月份、消费时段、退款数据四个维度分析平台整体营收规律,为后续运营提供基础参考。
3.3.1 按渠道划分收益
python
运行
# 按渠道分组统计总收益
channel_revenue = data.groupby('渠道编号')['付款金额'].sum().sort_values(ascending=False)
# 绘制柱状图
channel_revenue.plot(kind='bar', title='各渠道总收益分布')
plt.xlabel('渠道编号')
plt.ylabel('总收益')
plt.xticks(rotation=45)
plt.show()
业务解读:渠道 13、渠道 15、渠道 9 为平台核心营收渠道,营销资源可重点倾斜;尾部渠道收益偏低,可评估渠道投入性价比。
3.3.2 按月份划分收益
python
运行
# 提取付款月份
data['月份'] = data['付款时间'].dt.month
# 按月统计收益
month_revenue = data.groupby('月份')['付款金额'].sum().reset_index()
# 绘制折线图
plt.plot(month_revenue['月份'], month_revenue['付款金额'], marker='o')
plt.title('月度收益变化趋势')
plt.xlabel('月份')
plt.ylabel('总收益')
plt.xticks(range(1, 13))
plt.grid(True)
plt.show()
3.3.3 按每日小时划分收益(消费时段分析)
python
运行
# 筛选未退款订单,统计正常交易
data_no_refund = data[data['是否退款'] == '否']
# 提取小时、日期特征
data_no_refund['付款小时'] = data_no_refund['付款时间'].dt.hour
data_no_refund['付款天数名称'] = data_no_refund['付款时间'].dt.day_name()
# 按星期+小时分组统计收益
hourly_sales = data_no_refund.groupby(['付款天数名称', '付款小时'])['付款金额'].sum().reset_index()
hourly_sales.rename(columns={'付款金额': 'TotalValue'}, inplace=True)
# 使用Pyecharts绘制交互式小时收益图
line = (
Line()
.add_xaxis([str(i) for i in range(24)])
.set_global_opts(
title_opts=opts.TitleOpts(title="每日24小时收益分布"),
legend_opts=opts.LegendOpts(pos_top="5%")
)
)
# 按星期循环添加数据(简化展示)
week_list = hourly_sales['付款天数名称'].unique()
for week in week_list:
week_data = hourly_sales[hourly_sales['付款天数名称'] == week]['TotalValue'].tolist()
line.add_yaxis(week, week_data)
# 生成HTML交互式图表
line.render("每日小时收益图.html")
print("小时收益图表已生成:每日小时收益图.html")
业务解读:平台消费高峰集中在12 点、19-21 点(午间、晚间休闲时段),可在高峰时段投放广告、推送活动,提升转化。
3.3.4 月度退款金额分析
python
运行
# 筛选退款订单
data_refund = data[data['是否退款'] == '是']
# 按月统计退款金额
refund_month = data_refund.groupby('月份')['付款金额'].sum()
# 绘制折线图
refund_month.plot(kind='line', title='月度退款金额趋势')
plt.xlabel('月份')
plt.ylabel('退款金额')
plt.show()
3.4 特征工程:构建 LRFM 核心特征(项目难点)
基于用户维度聚合数据,计算L、R、F、M四大特征,将订单数据转化为用户级特征矩阵,用于聚类建模。
python
运行
# 1. 计算L:用户生命周期(最后一次付款时间 - 首次付款时间,单位:天)
user_last_time = data.groupby('用户名')['付款时间'].max()
user_first_time = data.groupby('用户名')['付款时间'].min()
L = (user_last_time - user_first_time).dt.days.reset_index()
# 2. 计算R:最近消费间隔(数据集最晚时间 - 用户最后付款时间,单位:天)
max_pay_time = data['付款时间'].max()
data['time_diff'] = (max_pay_time - data['付款时间']).dt.days
R = data.groupby('用户名')['time_diff'].min().reset_index()
# 3. 计算F:消费频次(用户下单总次数)
F = data.groupby('用户名')['订单号'].count().reset_index()
# 4. 计算M:累计消费金额(用户总付款金额)
M = data.groupby('用户名')['付款金额'].sum().reset_index()
# 5. 合并四大特征,生成LRFM数据集
LRFM_data = L.merge(R, on='用户名').merge(F, on='用户名').merge(M, on='用户名')
# 重命名列名
LRFM_data.columns = ['用户名', 'L', 'R', 'F', 'M']
print("LRFM用户特征矩阵(前5行):")
print(LRFM_data.head())
print(f"\n用户总数量:{len(LRFM_data)}")
运行后得到71258 条用户数据,每条数据对应一个用户的四大价值指标,完成从 “订单粒度” 到 “用户粒度” 的转换。
3.5 数据标准化
LRFM 四个特征量级差异极大(天数、金额、次数),直接用于 K-Means 聚类会导致量级大的特征主导聚类结果,因此必须做归一化处理:
python
运行
# 提取建模特征(剔除用户名字段)
model_feature = LRFM_data.iloc[:, 1:]
# 初始化归一化模型(MinMaxScaler 归一至0-1区间)
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(model_feature)
print("标准化后的数据(前5行):")
print(np.round(data_scaled, 3))
3.6 手肘法确定 K-Means 最优聚类数
K-Means 算法需要手动指定聚类数 K,使用手肘法计算不同 K 值下的 SSE(误差平方和),拐点处即为最优 K 值:
python
运行
# 手肘法计算SSE
SSE = []
# 遍历K=1~9,计算误差平方和
for k in range(1, 10):
kmeans = KMeans(n_clusters=k, random_state=10)
kmeans.fit(data_scaled)
SSE.append(kmeans.inertia_)
# 绘制手肘图
plt.plot(range(1, 10), SSE, marker='o', color='red')
plt.title('手肘法确定最优K值')
plt.xlabel('聚类数量 K')
plt.ylabel('SSE(误差平方和)')
plt.grid(True)
plt.show()
结论:图像拐点出现在 K=3,因此本次将用户划分为3 个群体。
3.7 K-Means 模型训练与标签合并
基于最优 K 值完成聚类,将聚类标签回写到原始 LRFM 数据中,实现用户分群:
python
运行
# 初始化K-Means模型,设置聚类数为3
kmeans_model = KMeans(n_clusters=3, random_state=10)
# 模型训练并获取每个用户的聚类标签
cluster_label = kmeans_model.fit_predict(data_scaled)
# 将聚类标签转为DataFrame并合并到原数据
label_df = pd.DataFrame(cluster_label, columns=['Cluster_Id'])
final_data = pd.concat([LRFM_data, label_df], axis=1)
print("聚类后用户数据(前5行):")
print(final_data.head())
3.8 聚类结果可视化与统计分析
3.8.1 各群体人数占比(饼图)
python
运行
# 统计每个聚类的人数、各指标均值
cluster_stat = final_data.groupby('Cluster_Id')[['L', 'R', 'F', 'M']].mean().reset_index()
cluster_count = final_data['Cluster_Id'].value_counts().sort_index()
cluster_stat['用户数量'] = cluster_count.values
# 饼图数据准备
pie_data = [(f'群体{i}', count) for i, count in zip(cluster_stat['Cluster_Id'], cluster_stat['用户数量'])]
# 绘制饼图
pie = (
Pie()
.add("", pie_data, radius=["30%", "60%"])
.set_global_opts(title_opts=opts.TitleOpts(title="各用户群体人数占比"))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
)
pie.render("用户群体占比饼图.html")
print("饼图已生成:用户群体占比饼图.html")
3.8.2 用户分群特征雷达图(核心可视化)
雷达图直观展示三个群体在 L/R/F/M 四个维度的特征差异:
python
运行
# 定义雷达图指标
indicators = [
opts.RadarIndicatorItem(name="L(生命周期)", max_=cluster_stat['L'].max()*1.1),
opts.RadarIndicatorItem(name="R(最近消费间隔)", max_=cluster_stat['R'].max()*1.1),
opts.RadarIndicatorItem(name="F(消费频次)", max_=cluster_stat['F'].max()*1.1),
opts.RadarIndicatorItem(name="M(消费金额)", max_=cluster_stat['M'].max()*1.1)
]
# 提取三个群体的特征数据
group0 = cluster_stat[cluster_stat['Cluster_Id']==0][['L','R','F','M']].values[0].tolist()
group1 = cluster_stat[cluster_stat['Cluster_Id']==1][['L','R','F','M']].values[0].tolist()
group2 = cluster_stat[cluster_stat['Cluster_Id']==2][['L','R','F','M']].values[0].tolist()
# 绘制雷达图
radar = (
Radar(init_opts=opts.InitOpts(width="800px", height="600px"))
.add_schema(schema=indicators)
.add("群体0", [group0], color="#FF0000")
.add("群体1", [group1], color="#0000FF")
.add("群体2", [group2], color="#008000")
.set_global_opts(title_opts=opts.TitleOpts(title="三大用户群体LRFM特征雷达图"))
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
)
radar.render("用户特征雷达图.html")
print("雷达图已生成:用户特征雷达图.html")

四、聚类结果深度解读 & 商业运营策略
结合 LRFM 指标含义、统计数据与雷达图,将 3 类用户分别定义为高价值核心用户、高风险沉睡用户、普通潜力新用户,并针对性输出运营方案。
4.1 群体 1(蓝色):高价值核心 VIP 用户
群体特征
- M(消费金额):数值遥遥领先,是平台主要营收来源;
- L(生命周期):极高,用户在平台活跃周期长,品牌忠诚度极强;
- F(消费频次):三大群体中最高,复购意愿强烈;
- R(最近消费间隔):数值偏小,近期持续活跃,无流失迹象。
定位
重要保持客户 / 平台核心 VIP
运营策略
- 专属权益:开通 VIP 专属客服、下单绿色通道、生日礼遇、积分加倍等尊享服务,强化用户归属感;
- 新品优先:将该群体作为新品首发体验人群,优先推送限量商品、独家活动;
- 流失监控:建立动态监控机制,一旦 R 值持续增大(长时间未消费),第一时间触发预警并主动关怀。
4.2 群体 0(红色):高风险沉睡挽留用户
群体特征
- R(最近消费间隔):数值最大,用户平均数百天未产生消费,流失风险极高;
- M(消费金额):中等水平,历史消费能力不俗,属于 “曾经的高价值用户”;
- L、F:数值偏低,当前活跃度、复购率极差。
定位
重要挽留客户 / 即将流失的沉睡用户
运营策略
- 定向召回:推送大额优惠券、限时回归礼包、专属满减活动,搭配情感营销短信唤醒用户;
- 原因调研:抽样回访流失用户,分析流失原因(价格、服务、竞品分流等),针对性优化平台短板;
- 成本管控:若召回成本过高、用户响应率极低,可适当降低营销投入,接受自然流失。
4.3 群体 2(绿色):普通潜力新用户
群体特征
- 四大指标整体偏低且均衡,消费金额、频次、生命周期均处于下游;
- R(最近消费间隔):中等水平,近期有过消费行为,属于新晋用户或低频尝试用户。
定位
一般发展客户 / 平台潜力新用户
运营策略
- 提升复购:推出 “多件折扣、满减活动、新人二次购福利”,引导用户完成第二次、第三次下单,提升 F 值;
- 增强粘性:引导用户关注公众号、加入用户社群、开启消息推送,延长用户生命周期 L;
- 交叉销售:基于历史下单商品,智能推荐关联产品,挖掘消费潜力,尝试转化为核心用户。
五、项目总结与知识点复盘
5.1 项目总结
- 技术层面:完整实现了
数据清洗→特征工程→标准化→K-Means聚类→可视化的机器学习数据分析全流程,验证了LRFM+K-Means组合在电商用户分层场景的有效性; - 业务层面:成功将数万用户划分为三类价值群体,打破 “一刀切” 的营销模式,实现用户分层、精准运营;
- 落地价值:分析结论可直接指导电商平台的渠道投放、时段营销、用户召回、会员体系搭建等实际工作。
5.2 核心知识点复盘
- LRFM 模型:在传统 RFM 基础上增加生命周期 L,更全面衡量用户忠诚度;
- K-Means 聚类:无监督学习经典算法,手肘法是选取 K 值最常用的方法;
- 数据标准化:K-Means 对特征量级敏感,归一化 / 标准化是建模前的必要步骤;
- 业务结合:数据分析最终要落地业务,所有指标、模型、图表都需要结合行业逻辑解读。
5.3 拓展优化方向
- 结合用户性别、地域、商品品类等特征,做更细粒度的用户画像;
- 对比 K-Means、DBSCAN 等多种聚类算法,优选效果最佳模型;
- 基于分群结果,搭建自动化用户分层与营销推送系统。
六、完整源码获取
本文所有代码均经过实测可运行,数据集为模拟电商订单数据。大家可以替换自己的电商订单数据,快速复用这套分析流程。
更多推荐





所有评论(0)