尧图精选

K-Means结合RFM实现用户精准分群的Python实践

🕒 发布时间:2026/9/10 9:03:55 📁 来源:尧图网络
简介本资源是一份面向数据分析初学者与电商运营人员的实战型顾客价值分析方案聚焦于K-Means聚类与RFM模型在用户分群与消费行为挖掘中的联合应用。资源提供从原始订单数据清洗、时序趋势建模含SARIMA预测、消费者画像构建到RFM维度打分的全流程Python实现覆盖数据逻辑校验、多维可视化9张分析图表及可复用的聚类评估逻辑。压缩包共13个文件包含核心分析脚本main.py、原始订单CSV数据、5类用户对比分析结果图png、结构化说明文档md及配置文件json整体仅906KB轻量易部署。已有566人学习下载读者可直接运行代码复现完整分析链路获取含时间序列分解图、聚类轮廓系数曲线、RFM四象限矩阵等关键产出并参考readme.md快速理解各模块设计意图与参数调优思路。1. 为什么用 K-Means RFM 做顾客分群比单纯看“最近购买”更准某电商运营发现后台导出的“近30天活跃用户”名单里有大量下单金额不足50元、客单价极低的用户而真正贡献70%GMV的高价值客户反而因购买周期长如母婴类客户每2个月复购一次被系统自动过滤。这不是数据不准而是传统时间窗口法缺乏对用户行为维度的结构性刻画。本项目编号 500010102 提供了一套可落地的 Python 实现路径先用 RFM 模型将原始订单数据orders_data.csv转化为 R最近一次消费距今时长、F消费频次、M消费金额三个可量化的数值指标再通过 K-Means 聚类算法在三维空间中自动识别用户自然分群——不是按运营主观定义“高/中/低”而是让数据自己说话。整个流程封装在 main.py 中含完整数据清洗、RFM 标准化、肘部法则确定最优聚类数k5、聚类结果可视化Figure_*.png及五类用户画像对比表。适合有 Python 基础、正处理真实销售数据的分析师或数据工程师尤其适用于订单结构清晰但用户生命周期波动大的零售、SaaS 订阅类业务。2. RFM 指标构建与标准化从原始订单到可聚类的三维向量RFM 不是简单统计字段而是对用户行为逻辑的数学转译。本项目中 orders_data.csv 包含 order_id、customer_id、order_date、amount 四个核心字段需严格按时间粒度和业务语义生成 R、F、M。关键在于R 必须是“距今时长”而非“订单日期”F 是去重后的订单次数非商品件数M 是该用户所有订单金额总和非平均值。若直接使用原始数值进行 K-MeansR 的单位是“天”量级百位M 的单位是“元”量级千位会导致欧氏距离计算时 M 维度完全主导聚类结果——这正是本项目在 data_preprocessing 阶段必须做 MinMaxScaler 标准化的根本原因。2.1 数据加载与基础清洗import pandas as pd import numpy as np from datetime import datetime, timedelta # 加载原始订单数据 df pd.read_csv(data/orders_data.csv) # 强制转换日期格式避免字符串导致排序错误 df[order_date] pd.to_datetime(df[order_date], errorscoerce) # 删除无效日期行如 NaT df df.dropna(subset[order_date]) # 检查 customer_id 是否存在空值或异常字符 print(customer_id 缺失值数量:, df[customer_id].isnull().sum()) print(customer_id 唯一值数量:, df[customer_id].nunique())注意errorscoerce将无法解析的日期转为 NaT后续dropna可确保时间计算安全。若customer_id存在空值需确认是否为匿名访客订单——本项目默认剔除因 RFM 要求明确用户身份。2.2 RFM 三指标计算逻辑与代码实现RFM 的 R、F、M 并非独立计算而是强依赖分析截止点analysis_date。本项目采用数据集中最大订单日期作为截止点确保所有用户 R 值在同一基准下可比# 确定分析截止日期取数据中最新订单日期 analysis_date df[order_date].max() # 计算 R每个用户最后一次下单距 analysis_date 的天数 r_df df.groupby(customer_id)[order_date].max().reset_index(namelast_order_date) r_df[R] (analysis_date - r_df[last_order_date]).dt.days # 计算 F每个用户订单总数去重 order_id f_df df.groupby(customer_id)[order_id].nunique().reset_index(nameF) # 计算 M每个用户订单金额总和 m_df df.groupby(customer_id)[amount].sum().reset_index(nameM) # 合并为 RFM 表 rfm_table r_df.merge(f_df, oncustomer_id).merge(m_df, oncustomer_id) print(RFM 表维度:, rfm_table.shape) print(rfm_table.head())参数说明dt.days将timedelta转为整数天数避免浮点误差nunique()确保 F 统计的是订单笔数而非商品行数若数据含明细行需先按 order_id 去重merge顺序以r_df为主表保证所有有下单记录的用户均被保留。2.3 RFM 标准化解决量纲差异对 K-Means 的致命干扰K-Means 基于欧氏距离若 R0–365、F1–200、M0–50000不统一量纲聚类中心将严重偏向 M 维度。本项目采用 MinMaxScaler 将各指标压缩至 [0,1] 区间公式为$$x_{\text{scaled}} \frac{x - x_{\min}}{x_{\max} - x_{\min}}$$from sklearn.preprocessing import MinMaxScaler # 提取 RFM 数值列 rfm_features rfm_table[[R, F, M]].copy() # 初始化标准化器 scaler MinMaxScaler() rfm_scaled scaler.fit_transform(rfm_features) # 转为 DataFrame 便于后续操作 rfm_scaled_df pd.DataFrame(rfm_scaled, columns[R_scaled, F_scaled, M_scaled], indexrfm_table.index) rfm_final pd.concat([rfm_table[[customer_id]], rfm_scaled_df], axis1) print(标准化后 RFM 前5行:) print(rfm_final.head())提示MinMaxScaler比StandardScaler更适合 RFM因 R 值越小代表用户越活跃R0 是当天下单而 M、F 越大越好。Min-Max 保留了这种方向性且避免负值影响后续聚类解释。2.4 RFM 分箱与业务解读可选增强步骤虽然 K-Means 直接作用于连续值但为辅助业务理解项目在 readme.md 中提供了分箱建议R 分 5 档0–30 天高活跃、31–90 天、91–180 天、181–365 天、365 天流失风险F 分 5 档1 次、2–3 次、4–6 次、7–12 次、≥13 次M 分 5 档按金额四分位数切分。此分箱不参与聚类仅用于将聚类结果映射为“重要价值客户”“新客户”“流失预警客户”等业务标签。3. K-Means 聚类全流程从肘部法则选 k 到五类用户画像生成K-Means 在本项目中不是黑箱调用而是需验证其适用性、调试超参数、并确保结果可解释。核心挑战在于如何证明 k5 是最优解聚类后如何避免“数字正确但业务无感”本节基于 main.py 中的 clustering.py 模块拆解从距离计算到画像输出的完整链路。3.1 肘部法则Elbow Method确定最优聚类数 kK-Means 的 k 值选择直接影响分群质量。盲目设 k3 或 k8 会导致过拟合或欠拟合。肘部法则通过计算不同 k 值下的簇内平方和WCSS, Within-Cluster Sum of Squares绘制曲线拐点即为最优 k。本项目在 Figure_2.png 中展示了 k1 至 k10 的 WCSS 曲线明确显示 k5 处出现显著拐点。from sklearn.cluster import KMeans import matplotlib.pyplot as plt # 计算不同 k 值的 WCSS wcss [] K_range range(1, 11) for k in K_range: kmeans KMeans(n_clustersk, random_state42, n_init10) kmeans.fit(rfm_final[[R_scaled, F_scaled, M_scaled]]) wcss.append(kmeans.inertia_) # inertia_ 即 WCSS # 绘制肘部图 plt.figure(figsize(8, 5)) plt.plot(K_range, wcss, markero) plt.title(Elbow Method for Optimal k) plt.xlabel(Number of Clusters (k)) plt.ylabel(WCSS) plt.grid(True) plt.savefig(image/Figure_2.png, dpi300, bbox_inchestight) plt.show()关键参数说明n_init10K-Means 随机初始化 10 次取最优解避免局部最优random_state42保证结果可复现调试时必需inertia_模型训练后自动计算的 WCSS 值无需手动实现。3.2 执行 K-Means 聚类并分配标签选定 k5 后对标准化后的 RFM 数据执行聚类并将结果回写至原始 RFM 表# 使用最优 k5 运行 K-Means kmeans_final KMeans(n_clusters5, random_state42, n_init10) rfm_final[Cluster] kmeans_final.fit_predict(rfm_final[[R_scaled, F_scaled, M_scaled]]) # 查看各类别用户数量分布 cluster_dist rfm_final[Cluster].value_counts().sort_index() print(各聚类用户数量分布:) print(cluster_dist)注意fit_predict一步完成训练与预测比先fit再predict更简洁。value_counts().sort_index()确保 Cluster 0–4 按序输出方便后续关联画像。3.3 五类用户画像对比用原始 RFM 值而非标准化值解读聚类标签0–4本身无业务含义需结合原始 R、F、M 均值还原用户特征。例如Cluster 0 的 R 均值为 12 天、F 为 8 次、M 为 3200 元则可定义为“高价值常客”Cluster 4 的 R 均值为 210 天、F 为 1 次、M 为 85 元则为“低频低额流失用户”。本项目在 Figure_4.png 中用雷达图直观展示五类用户的 R/F/M 相对强度。# 按聚类分组计算原始 RFM 均值非标准化值 cluster_profile rfm_table.groupby(Cluster)[[R, F, M]].mean().round(2) print(五类用户原始 RFM 均值:) print(cluster_profile) # 保存为 CSV 供业务方查阅 cluster_profile.to_csv(data/cluster_profile.csv)输出示例模拟ClusterR天F次M元015.212.84250.6145.73.2890.32180.51.0120.838.31.0215.44220.11.075.2提示R 值越小越活跃故 Cluster 3R8.3是“新客”Cluster 0R15.2是“高价值常客”Cluster 2/4 是“流失风险户”Cluster 1 是“潜力客户”R 中等、F/M 适中。3.4 聚类结果可视化三维散点图与雷达图二维散点图无法展现三维 RFM 关系本项目采用主成分分析PCA降维至二维并用不同颜色标记聚类结果Figure_3.png同时用雷达图Figure_4.png直接对比五类在 R/F/M 上的相对位置避免 PCA 引入的信息损失。from sklearn.decomposition import PCA # 对标准化 RFM 数据做 PCA 降维 pca PCA(n_components2) rfm_pca pca.fit_transform(rfm_final[[R_scaled, F_scaled, M_scaled]]) # 绘制 PCA 散点图 plt.figure(figsize(10, 6)) scatter plt.scatter(rfm_pca[:, 0], rfm_pca[:, 1], crfm_final[Cluster], cmapviridis, alpha0.6) plt.colorbar(scatter) plt.title(PCA of Scaled RFM Data (2D Projection)) plt.xlabel(fPC1 ({pca.explained_variance_ratio_[0]:.2%} variance)) plt.ylabel(fPC2 ({pca.explained_variance_ratio_[1]:.2%} variance)) plt.savefig(image/Figure_3.png, dpi300, bbox_inchestight) plt.show()4. 聚类稳定性验证与业务落地技巧避免“伪科学分群”K-Means 结果易受初始质心、数据噪声影响。若直接将聚类标签用于精准营销可能因单次运行结果波动导致策略失效。本节提供两种低成本验证方法并给出将结果嵌入业务系统的实操技巧。4.1 用轮廓系数Silhouette Score量化聚类质量肘部法则判断“k 是否合适”轮廓系数则评估“当前 k 下各点聚类是否合理”。取值范围 [-1, 1]越接近 1 表示聚类越紧密。本项目在 main.py 中计算得 silhouette_score ≈ 0.42k5属中等偏上水平证明分群有效。from sklearn.metrics import silhouette_score # 计算轮廓系数 sil_score silhouette_score( rfm_final[[R_scaled, F_scaled, M_scaled]], rfm_final[Cluster] ) print(fSilhouette Score for k5: {sil_score:.3f}) # 若 score 0.25建议检查数据或尝试其他算法如 DBSCAN if sil_score 0.25: print(警告轮廓系数偏低聚类质量可能不佳)注意轮廓系数对 k 敏感需配合肘部法则使用。单独高分不保证业务意义但低分一定意味着分群失败。4.2 时间切片交叉验证检验聚类结果的时序鲁棒性真实业务中用户行为会随时间漂移。本项目提供validate_over_time.py脚本未在压缩包列出但可快速补充其逻辑是将 orders_data.csv 按时间分为训练集前80%订单和测试集后20%订单分别构建 RFM 并聚类计算两套 Cluster 标签的 Adjusted Rand IndexARI。ARI1 表示完全一致ARI0.5 则说明分群不稳定。# 示例用前80%数据训练聚类模型 cutoff_date df[order_date].quantile(0.8) train_df df[df[order_date] cutoff_date] # ...重复 RFM 构建与 K-Means 步骤... train_clusters kmeans_final.predict(train_rfm_scaled) # 用后20%数据预测不重新训练 test_df df[df[order_date] cutoff_date] test_rfm build_rfm_from_df(test_df) # 自定义函数 test_clusters kmeans_final.predict(test_rfm[[R_scaled,F_scaled,M_scaled]]) # 计算 ARI需安装 scikit-learn 1.0 from sklearn.metrics import adjusted_rand_score ari adjusted_rand_score(train_labels, test_labels) # 需对齐 customer_id4.3 业务落地将 Cluster 标签同步至数据库与 BI 工具聚类结果需脱离 Jupyter 环境进入生产系统。本项目在 readme.md 中明确给出 MySQL 同步方案-- 创建用户画像表 CREATE TABLE customer_segment ( customer_id VARCHAR(50) PRIMARY KEY, cluster_id TINYINT NOT NULL, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); -- 用 pandas 批量插入main.py 最后部分 rfm_final[[customer_id, Cluster]].to_sql( customer_segment, conengine, if_existsreplace, indexFalse );提示if_existsreplace确保每日全量更新避免增量同步的主键冲突。BI 工具如 Tableau、QuickSight可直连该表将cluster_id作为筛选器实现“针对 Cluster 0 用户推送高毛利新品”的自动化营销。4.4 关键参数速查表main.py 中可调整的核心配置参数名默认值说明修改建议ANALYSIS_DATEdf[order_date].max()RFM 计算截止日若需分析历史快照可设为固定日期如2023-12-31N_CLUSTERS5K-Means 的 k 值依据 Figure_2.png 肘部点调整勿硬编码SCALER_TYPEminmax标准化方法若数据含异常值可改用robust中位数四分位距RANDOM_STATE42随机种子调试时固定上线后可设为int(time.time())增加随机性最终五类用户画像已固化为data/cluster_profile.csv可直接导入 CRM 系统聚类过程生成的全部图表Figure_*.png均存于image/目录支持向管理层汇报。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →