
AI 智能营销数据分析RFM 聚类 推荐的全链路方案一、营销数据分析的三个阶段做营销数据分析久了你会发现大部分公司的营销分析都停留在第一阶段——算算 ROI、看看转化率、出个周报。但实际上真正能驱动业务增长的营销分析应该走完三个阶段用户分层谁是你的高价值用户谁快流失了谁还有挖掘潜力精准推荐知道用户是谁之后给他推什么产品/活动最有效效果闭环推完之后用户有没有转化没转化的原因是什么这篇文章就把这三个阶段串起来用一套RFM 聚类 推荐的全链路方案从数据到决策到执行一气呵成。为什么大多数公司的营销分析都停留在第一阶段原因不是技术能力不够而是组织惯性。用户分层需要数据分析师跑 SQL精准推荐需要算法工程师训练模型效果闭环需要产品和运营配合设计 AB 测试。三个阶段涉及三个角色任何一个环节掉链子整个链路就断了。RFM 聚类的优势在于数据分析师或熟练的 Python 工程师一个人就能跑通全流程不需要专门的算法团队——K-Means 够用了。跑通一次链路后用数据结果去说服业务方配合做 AB 测试阻力会小得多。先用轻量方案快速出成果再用成果推动深度合作这是在资源有限情况下的最佳实践。二、RFM 模型经典但不过时RFMRecency 最近一次消费、Frequency 消费频率、Monetary 消费金额是用户分层的经典模型简单好用解释性极强。为什么 30 年前的 RFM 模型到今天仍然管用因为这三个维度直接对应了消费行为的三个底层驱动力Recency 衡量用户的记忆热度刚买过的人最容易再次购买Frequency 衡量习惯程度买得越多越容易接着买Monetary 衡量投入程度花得越多越不会轻易离开。这三件事不随行业变化电商、游戏、SaaS、金融都适用。RFM 的另一个巨大优势是可解释——你对着老板说这是一个 R5, F1, M5 的用户老板可能听不懂但你说这个用户最近花了大钱但只买了一次老板立刻知道该怎么运营。**import pandas as pd import numpy as np from datetime import datetime, timedelta from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans import warnings warnings.filterwarnings(ignore) # 第1步计算RFM指标 # 模拟交易数据 np.random.seed(42) n_users 1000 transactions pd.DataFrame({ user_id: np.random.choice([fU{i:04d} for i in range(1, n_users 1)], 5000), order_date: pd.to_datetime([ datetime(2026, 7, 1) - timedelta(daysnp.random.randint(0, 365)) for _ in range(5000) ]), order_amount: np.random.lognormal(mean4.0, sigma0.8, size5000), # 对数正态分布模拟交易金额 order_id: [fORD{i:06d} for i in range(1, 5001)] }) # 设置分析基准日期比如今天是2026-07-23 REFERENCE_DATE datetime(2026, 7, 23) # 计算每个用户的RFM指标 rfm transactions.groupby(user_id).agg( # Recency: 最近一次购买距离今天的天数越小越好 recency(order_date, lambda x: (REFERENCE_DATE - x.max()).days), # Frequency: 购买次数越多越好 frequency(order_id, count), # Monetary: 总消费金额越多越好 monetary(order_amount, sum) ).reset_index() print( RFM指标统计 ) print(rfm.describe()) # ---- 给RFM打分1-5分制 ---- # 按分位数将每个指标分为5个等级 def rfm_score(series: pd.Series, ascending: bool True) - pd.Series: 将连续值映射到1-5的评分 参数: series: 需要评分的序列 ascending: True表示值越小分数越高适用于Recency False表示值越大分数越高适用于Frequency和Monetary labels [5, 4, 3, 2, 1] if ascending else [1, 2, 3, 4, 5] return pd.qcut(series, q5, labelslabels, duplicatesdrop).astype(int) rfm[R_score] rfm_score(rfm[recency], ascendingTrue) # R: 越近分数越高 rfm[F_score] rfm_score(rfm[frequency], ascendingFalse) # F: 越多分数越高 rfm[M_score] rfm_score(rfm[monetary], ascendingFalse) # M: 越多分数越高 # RFM总分 rfm[RFM_score] rfm[R_score] rfm[F_score] rfm[M_score] print(f\n RFM评分分布 ) print(rfm[[R_score, F_score, M_score, RFM_score]].describe())三、K-Means 聚类从 RFM 到用户画像RFM 打分是一种粗分类想得到更精细的用户画像需要对 RFM 的原始值做聚类为什么不能直接用 RFM 打分还要做 K-MeansRFM 打分的本质是等分——把用户按 R/F/M 三个维度分别切成 5 等份然后组合出 125 种可能5×5×5。问题是等分不反映数据的真实分布。如果 80% 的用户 Frequency1只买过一次那你把买过一次的用户硬切成 5 组毫无意义。K-Means 的聚类是基于实际数据密度的——用户群在哪聚集边界就在哪不是人为硬分。另外K-Means 前必须做 StandardScaler 标准化原因是 recency0-365 天、frequency1-50 次、monetary10-100000 元这三个特征的量纲完全不同如果不标准化monetary 几乎会完全主导聚类结果recency 和 frequency 的信息被淹没。这一点 90% 的新手会忽略结果得出一个只有金额维度的分群。**# 第2步K-Means聚类 # 选择聚类特征使用RFM原始值 cluster_features rfm[[recency, frequency, monetary]].copy() # ---- 特征标准化K-Means对尺度敏感 ---- scaler StandardScaler() features_scaled scaler.fit_transform(cluster_features) # ---- 确定最佳聚类数手肘法 ---- # 计算不同K值下的SSE误差平方和 sse_list [] k_range range(1, 11) for k in k_range: kmeans KMeans(n_clustersk, random_state42, n_init10) kmeans.fit(features_scaled) sse_list.append(kmeans.inertia_) # 找到手肘点简化选择SSE下降变缓的位置 # 实际项目中建议用轮廓系数Silhouette Score更严谨 # ---- 使用K5进行聚类 ---- optimal_k 5 kmeans KMeans(n_clustersoptimal_k, random_state42, n_init10) rfm[cluster] kmeans.fit_predict(features_scaled) # ---- 分析每个聚类的特征给分群命名 ---- cluster_profile rfm.groupby(cluster).agg( avg_recency(recency, mean), avg_frequency(frequency, mean), avg_monetary(monetary, mean), user_count(user_id, count), avg_rfm_score(RFM_score, mean) ).round(1) print(\n 聚类特征画像 ) print(cluster_profile) # ---- 根据聚类特征自动打标签 ---- def label_cluster(row): 根据RFM均值给聚类打标签 判断逻辑 - 高Monetary 高Frequency → 高价值用户 - 高Monetary 低Frequency → 大单客户 - 低Monetary 高Frequency → 活跃小客户 - 低Recency 中低Frequency → 潜力用户最近活跃但频次不高 - 高Recency 低Frequency → 流失风险用户 r, f, m row[avg_recency], row[avg_frequency], row[avg_monetary] # 判断标准相对于整体均值的比较 r_median rfm[recency].median() f_median rfm[frequency].median() m_median rfm[monetary].median() if m m_median and f f_median: return 高价值用户 elif m m_median and f f_median: return 大单低频客户 elif m m_median and f f_median: return 高频小单客户 elif r r_median and f f_median: return 潜力新用户 else: return 流失风险用户 cluster_profile[segment_name] cluster_profile.apply(label_cluster, axis1) # 将标签映射回用户表 segment_map cluster_profile[segment_name].to_dict() rfm[user_segment] rfm[cluster].map(segment_map) print(\n 用户分群结果 ) print(rfm[user_segment].value_counts()) print(f\n各分群人数占比) for seg, count in rfm[user_segment].value_counts().items(): print(f {seg}: {count}人 ({count/len(rfm):.1%}))四、个性化推荐基于分群的协同过滤有了用户分群之后推荐就不再是盲目的了为什么分群推荐比全局统一推荐效果好得多全局推荐的问题是平均化——对所有用户推一样的东西结果是高价值用户觉得太 low、新用户觉得太贵、流失用户无感。分群推荐的核心逻辑是同群用户有相似的消费能力和偏好。高价值用户群里的用户 A 买了某款高端产品用户 B 很可能也会感兴趣——即使他们俩的历史行为完全不同。这就是分群协同过滤比全局协同过滤更精准的原因。更进一步不同群的推送文案也该不同高价值用户看到为您臻选会觉得被尊重流失用户看到好久不见送你一张优惠券才会点开。一句话总结精准的秘密不在算法复杂度而在谁收到什么的匹配度。# 第3步基于分群的推荐策略 class SegmentBasedRecommender: 基于用户分群的推荐引擎 根据不同用户群的特性采用差异化的推荐策略 # 各分群的推荐策略 SEGMENT_STRATEGIES { 高价值用户: { priority: vip_exclusive, # 优先推VIP专属/高客单价商品 price_range: (200, 10000), # 价格区间 discount_sensitivity: low, # 对折扣不敏感更关注品质 channel: push sms, # 推送渠道 message: 为您臻选的品质好物 # 文案风格 }, 大单低频客户: { priority: similar_upsell, # 推相似品类的高端款升单 price_range: (100, 5000), discount_sensitivity: medium, channel: sms in_app, message: 基于您的偏好这些好物值得一试 }, 高频小单客户: { priority: bundle_deal, # 推组合套餐/凑单优惠 price_range: (10, 200), discount_sensitivity: high, # 凑单敏感适合推满减 channel: in_app coupon, message: 凑单满99减20这些好物加购立减 }, 潜力新用户: { priority: new_user_bundle, # 推新人专享/入门爆款 price_range: (10, 300), discount_sensitivity: high, channel: push coupon, message: 新人专属福利首单立减30元 }, 流失风险用户: { priority: recall_coupon, # 推大额召回优惠券 price_range: (10, 500), discount_sensitivity: very_high, channel: sms push, message: 好久不见送你一张50元优惠券 }, } def get_strategy(self, user_segment: str) - dict: 根据用户分群获取推荐策略 return self.SEGMENT_STRATEGIES.get( user_segment, self.SEGMENT_STRATEGIES[潜力新用户] # 默认策略 ) def generate_recommendations(self, user_id: str, user_segment: str, user_history: list, top_n: int 5) - list: 生成个性化推荐列表 参数: user_id: 用户ID user_segment: 用户分群标签 user_history: 用户历史购买商品ID列表 top_n: 推荐数量 strategy self.get_strategy(user_segment) # 实际生产环境中这里会调用协同过滤或内容推荐算法 # 简化示意 recommendations [] priority strategy[priority] price_range strategy[price_range] # 根据策略筛选候选商品 # 实际会用向量检索或矩阵分解 # ... return { user_id: user_id, segment: user_segment, strategy: priority, message: strategy[message], channel: strategy[channel], candidates: recommendations # 推荐商品列表 } # ---- 使用示例 ---- recommender SegmentBasedRecommender() # 为不同分群的用户生成推荐 test_users [ (U0001, 高价值用户), (U0500, 流失风险用户), (U0800, 潜力新用户), ] print(\n 个性化推荐策略 ) for uid, seg in test_users: result recommender.generate_recommendations(uid, seg, user_history[]) print(f\n{uid} ({seg}):) print(f 推荐策略: {result[strategy]}) print(f 推送文案: {result[message]}) print(f 推送渠道: {result[channel]})踩坑提醒坑1RFM 基准日期选错导致用户分群全歪— 如果你用今天作为基准日期来计算 Recency但你的交易数据只到 3 天前数据延迟那么所有用户的 Recency 都会多了 3 天。高价值用户可能因此被错分到流失风险群。基准日期应该是数据的最新日期而不是代码的执行日期。坑2K-Means K 值拍脑袋选 5— 手肘法虽然简单但很多数据集的肘点并不明显。真正的金标准是轮廓系数Silhouette Score和业务可解释性的折中。K5 是一个经验值但如果轮廓系数在 K6 时明显更高就应该用 K6。坑3聚类标签生成后不验标直接推给运营— 自动打的标签如潜力新用户跑出来后必须人工抽样验标确认标签和实际用户画像一致。否则运营按错误标签发了错误优惠券效果为负还伤了用户体验。五、总结营销数据分析的三段论——用户分层、精准推荐、效果闭环——缺一不可。RFM 聚类是用户分层的黄金组合。RFM 提供可解释的业务标签K-Means 做精细化分群两者结合比单一方法效果好几倍。不同用户群要用不同的推荐策略。高价值用户推品质流失用户推优惠券新用户推爆款。千篇一律的推荐 没有推荐。推荐必须有反馈闭环。AB 测试是标配实验组和对照组的转化率差异才是衡量推荐策略有没有用的唯一标准。分群标签要定期更新。用户的行为模式会变上个月的高价值用户这个月可能就流失了。建议至少每周做一次 RFM 重算。不要只有标签还要有画像。标签告诉你用户属于哪个群画像告诉你这个群的用户喜欢什么后者才是推荐的基础。从拍脑袋做营销到数据驱动做营销这条路一旦走通ROI 的提升是肉眼可见的。