接手过一个零售连锁的数据分析需求,对方运营负责人拉出来几千张小票,开门见山问我:哪些商品放在一起会互相带动?这问题背后就是关联分析。想把关联分析做扎实,绕不开三个指标:支持度、置信度、提升度。说句实在话,网上聊关联规则的文章,十个有八个拿"啤酒与尿布"当开场,段子是好记,可真到项目里你会发现,故事只能帮你理解"大概是怎么回事",完全没法指导你定阈值、筛规则、给业务解释结论。这篇文章就围绕这三个指标,把关联规则从公式含义、手算过程、踩坑经验到落地姿势完整讲一遍,适合刚接触数据挖掘、或者已经在做购物篮分析但总觉得"指标算出来了却不会用"的读者。
1. 一张小票藏着的"购物篮":关联分析到底在回答什么问题
1.1 把"一起买"翻译成数学规则
先说清楚关联分析在整个数据分析体系里的位置。它不是预测模型,不回答"下个月销量多少""这个顾客会不会流失"这类问题,它回答的是"什么东西经常一起出现"。这个"经常一起出现"的模式,在零售场景里就是购物篮:一张小票对应的是一次购买行为,小票里所有商品的集合就是一个"事务",全部小票汇总起来,就构成了一个事务数据库。关联分析要做的,就是在这个事务数据库里找出高频共现的商品组合,并用"规则"的形式表达出来。
一条关联规则长这样:A → B,读作"买了A的人也倾向于买B"。比如"咖啡 → 鲜奶",意思是买咖啡的顾客里,有相当比例的人同时买了鲜奶。注意这里箭头不代表因果,只代表"共现层面的前后关联"。这个区分很重要,后面讲提升度的时候你还会感受到它的分量。
为了能严谨地讨论这个问题,需要先统一几个术语。"项集"就是商品的集合,{咖啡, 鲜奶}是一个2-项集;"事务"就是单张小票里的商品集合;"事务数据库"就是全体小票。一条规则 A → B 里,A 叫前件,B 叫后件。接下来所有计算,都是在这几个概念上展开的。
1.2 三个指标的分工逻辑:先圈范围、再看强度、最后定方向
假设你在海量的商品组合里找"值得看"的规则。直接看结论会让你眼花缭乱,因为"咖啡和鲜奶一起出现"和"咖啡和保险单一起出现"完全是两码事,前者一年发生几千次,后者可能只是某个大客户的一次巧合。所以需要一道一道过滤。
支持度负责第一道过滤:它衡量一个组合在全部事务里占多大比例。比例太低,说明这个组合只是零星巧合,不值得投入分析资源。置信度负责第二道过滤:它衡量"当前件出现时,后件跟着出现的概率"。这个概率高,说明规则"靠得住"。但光靠这两道还不够——一种商品本身就可能是个高频商品,买什么都可能带上它,这时候置信度高是"沾光",不是规则本身有价值。这就需要提升度出场:它把"后件的全局购买率"作为基准,看当前件出现时后件的概率是明显高于、持平还是低于这个基准,从而判断这条规则是正向拉动、无关还是反向抑制。
打个比方,三个指标就像筛选合作伙伴:支持度看"候选人池子够不够大",置信度看"合作后的成功率",提升度看"跟你合作是不是真的比跟别人合作强"。只看前两个,可能选中一个本来就自带流量的人;提升度才是判断"你对他有增量贡献"的关键。
2. 三个指标逐个拆解:公式、含义与常见误区
2.1 支持度:这个组合到底多常见
支持度的定义式:
support(A → B) = 同时包含A和B的事务数 / 事务总数 = count({A, B}) / N
用一个具体的场景说话。假设一家店有1000笔小票,其中180笔同时包含咖啡和鲜奶,那么规则"咖啡 → 鲜奶"的支持度就是180/1000=18%。直观理解:每100笔交易里,有18笔会出现这两个商品同时结账的情况。
这里有个符号上的坑要先拆掉。公式里那个 count({A, B}) 或者写成 count(A∪B),指的是"同时包含A和B的小票数"。不少资料为了书写方便会写成 A∪B,但它跟集合论里的并集不是一回事。你只要记住它是把一个项集 {A, B} 当作整体去事务里匹配就行;用概率论的语言说,它对应的是 P(A∩B)。符号上容易绕,实际含义很朴素:数一数哪些小票里两样东西都出现了。
支持度的作用在于过滤。最小支持度是挖掘时第一个参数,低于它的组合直接淘汰。为什么?因为支持度太低意味着支撑规则的样本太少,哪怕置信度算出99%,也可能只是三张小票里的巧合,经不起波动。
2.2 置信度:前件出现时,后件有多大概率跟着出现
置信度的定义是条件概率:
confidence(A → B) = count({A, B}) / count(A) = P(B | A)
还是用上面的数据:买咖啡的小票有400笔,其中180笔同时买了鲜奶,那么"咖啡 → 鲜奶"的置信度是180/400=45%。换句话说,买了咖啡的顾客里,接近一半的人也会买鲜奶。这个数字直接回答了业务上最关心的一个问题:"如果我想给买咖啡的人推荐鲜奶,成功率大概多少"。
注意置信度的不对称性。反过来看"鲜奶 → 咖啡":买鲜奶的小票有300笔,其中180笔同时买了咖啡,置信度是60%。也就是说,从鲜奶导流到咖啡的成功率反而更高。同一个共现事实,换个方向,置信度就变了。这在推荐动作设计里非常关键:你应该把顾客从"置信度更高的前件"往"后件"方向引导。后面3.3会专门演示这个方向差异。
但置信度有个结构性的盲区:它没有参照"后件的自然发生率"。假设店里60%的小票都有面包,那么随便找一条规则"什么X → 面包",置信度都可能接近60%。看起来"买了X的人也买面包"很稳,可这跟X根本没关系,顾客本来就大概率会买面包。要识别这种"沾光"规则,必须引入提升度。
2.3 提升度:判断正向拉动、彼此独立还是反向抑制
提升度的公式有两种等价写法:
lift(A → B) = confidence(A → B) / support(B)
lift(A → B) = count({A, B}) × N / (count(A) × count(B))
第一种写法最好记,也最能体现三个指标的关系:提升度就是置信度除以"后件在整个数据库里的支持度"。它本质上是把"买A的前提下买B的概率"和"不讲究前提时买B的概率"做比较。
还是用数据说话。"咖啡 → 鲜奶"置信度45%,鲜奶的整体支持度是300/1000=30%,提升度=45%/30%=1.5。意思是:买了咖啡的人购买鲜奶的概率,是全体顾客平均水平的1.5倍,相当于"多出了50%的购买概率"。这是明确的正向拉动。
提升度的判读规则:
- lift > 1:前件出现时后件概率高于全局水平,正向拉动
- lift ≈ 1:前件对后件没影响,两者独立,规则没有增量价值
- lift < 1:前件出现时后件概率反而低于全局水平,反向抑制
提升度还有一个容易被忽略的性质——它是对称的。lift(A→B) 和 lift(B→A) 永远相等,因为公式分母是 count(A)×count(B),分子是 count({A,B})×N,A和B对调后数值不变。这与置信度的不对称形成鲜明对比。很多刚入门的同学会疑惑"为什么同一个提升度,不同方向都能用",其实就是这两个性质叠加的结果。
2.4 一张表把三个指标的关系钉死
| 指标 | 公式 | 取值范围 | 回答的问题 | 最小阈值一般怎么设 |
|---|---|---|---|---|
| 支持度 | count({A,B})/N | 0~1 | 这个组合常见吗 | 1%~10%,看商品总数和数据量 |
| 置信度 | count({A,B})/count(A) | 0~1 | 前提出现时结论有多稳 | 20%~60% |
| 提升度 | confidence/support(B) | 0到+∞,1为基准 | 是拉动、独立还是拖累 | >1,实践中常取1.1~1.5 |
表格最后一行是重点:三个指标不是并列关系,而是递进关系。支持度筛掉"太罕见"的组合,置信度筛掉"不稳定"的规则,提升度筛掉"没增量"的伪规则。任何一个环节不过关,规则都算不上好用。
3. 手工演算一组交易数据:把三个指标算到能背下来
3.1 示例数据:把1000笔交易压缩成几张计数表
为了让你能跟着算一遍,我构造一份模拟的便利店交易数据,总共1000张小票,先从单品的购买频次看起。
| 商品 | 购买次数 | 购买率 |
|---|---|---|
| 咖啡 | 400 | 40% |
| 鲜奶 | 300 | 30% |
| 面包 | 600 | 60% |
| 薯片 | 250 | 25% |
这张表告诉你四件商品的"基本盘"。面包是店里最热门的商品,60%的小票都会出现;薯片和鲜奶是中等偏下的频率;咖啡的购买率是40%,其实也不算低。接下来看两两同时出现的频次。注意,"咖啡+鲜奶"的180笔是已经包含在咖啡400笔和鲜奶300笔之内的,千万不要把单品的计数加起来再用。
| 商品组合 | 同购次数 |
|---|---|
| 咖啡+鲜奶 | 180 |
| 咖啡+面包 | 240 |
| 咖啡+薯片 | 120 |
| 鲜奶+面包 | 150 |
| 鲜奶+薯片 | 40 |
| 面包+薯片 | 150 |
为什么不直接甩出1000行原始小票?因为关联规则的核心计算依赖的是这些聚合计数。只要事务数据库够大,你完全可以先通过数据库查询或者清洗脚本统计出单品频次和组合频次,再在这个基础上计算所有指标。这也是后面第5节代码实现的基本思路。
3.2 三个典型规则的手算全过程
先算第一条,"咖啡 → 鲜奶":
- 支持度 = 180 / 1000 = 18%
- 置信度 = 180 / 400 = 45%
- 提升度 = 45% / 30% = 1.5
这条规则三个指标全部过关:18%的支持度说明组合不算罕见,45%的置信度说明导流成功率接近一半,提升度1.5说明咖啡对鲜奶有明确的正向拉动。如果做交叉销售,"买咖啡时推荐鲜奶"会是第一批上线的高潜规则。
再看第二条,"咖啡 → 面包":
- 支持度 = 240 / 1000 = 24%
- 置信度 = 240 / 400 = 60%
- 提升度 = 60% / 60% = 1.0
这条最容易让人误判。置信度60%,比"咖啡 → 鲜奶"还高,猛一看是好规则。但面包本身的购买率就是60%,买不买咖啡,买面包的概率都是60%。提升度1.0说明咖啡和面包只是"在同一家店共存的独立高频商品",互相没有增量。如果把这条规则交给运营,让他们给买咖啡的人推荐面包,效果约等于随机推荐——因为面包本来就会出现在六成小票里。
再看第三条,"鲜奶 → 薯片":
- 支持度 = 40 / 1000 = 4%
- 置信度 = 40 / 300 ≈ 13.3%
- 提升度 = 13.3% / 25% ≈ 0.53
这条是反向抑制的典型。买鲜奶的顾客里只有13.3%会买薯片,而整体顾客里有25%会买薯片。提升度0.53说明鲜奶顾客买薯片的倾向被明显压低。这个信息对货架设计很有用:鲜奶和薯片不适合放在一起做"凑单"推荐,它们更像是替代型或场景冲突型商品。
3.3 箭头方向不是摆设:置信度不对称,提升度对称
把"咖啡 → 鲜奶"翻个方向,算"鲜奶 → 咖啡":
- 支持度 = 180 / 1000 = 18%(不变)
- 置信度 = 180 / 300 = 60%
- 提升度 = 60% / 40% = 1.5(和刚才完全一样)
看到差异了:支持度不变好理解,因为"同时包含咖啡和鲜奶"的小票数量没变;提升度不变,是因为提升度本质是度量两个商品的关联强度,和谁当前件无关;但置信度从45%变成了60%,原因只是把分母从"买咖啡的人数"换成了"买鲜奶的人数"。
这个性质在落地时特别有用。如果你要给某个场景设计推荐链路,比如收银台扫码后推荐,你肯定希望从"置信度更高的方向"去引导。数据里鲜奶 → 咖啡的置信度60%高于咖啡 → 鲜奶的45%,那就优先考虑"买鲜奶后给咖啡券",而不是反过来。而判断两个商品到底有没有关联、关联强度多大,就直接看提升度,不用分方向。
4. 阈值设定最容易踩的坑:指标够高,结论却可能完全相反
4.1 最小支持度一刀切:低频高价值组合被误杀
很多人做关联分析,第一件事就是设一个全局最小支持度,比如5%。这在小而全的超市或许行得通,但放到SKU过万的大型零售里,问题立刻就来了:绝大多数商品的支持度都不到1%,你设5%等于直接把大部分商品都排除在外,最后挖出来的规则永远集中在少数爆款之间。
更要命的是,低频商品里往往藏着高毛利、高客单的"利润型"商品。举个例子,高端咖啡机一个月只出现在2%的小票里,但它和精选咖啡豆的共现可能非常稳定,置信度70%,提升度3.0。如果按5%的最小支持度一刀切,这条高价值规则根本进不了候选集。
我现在的习惯做法是分层级、分类目地设阈值:先把商品按类目拆开,比如"咖啡设备""零食""日用品",在各个类目内部计算支持度分布,再按各自的分位数设最低支持度。另一种更省事的方案是"多最小支持度"——给高利润商品单独一个更低的支持度门槛。总之,支持度是过滤工具,不是道德标准,"低频"不等于"没价值"。
4.2 高置信度低提升度:最典型的伪强规则
前面说的"咖啡 → 面包"就是这类坑的活教材。置信度60%,看起来很强,但提升度只有1.0,说明没有增量。类似的情况在热门商品上特别普遍:店里最畅销的十款商品,天然会出现在大量规则的后件里,把任何前件搭配上去,置信度都不会太低。
这个坑为什么常见?因为很多分析工具默认只展示支持度和置信度,报表里排在前面的规则往往就是这种"伪强规则"。业务方不懂提升度的话,会误以为热门商品规则都是宝贝。要避开它,规则很简单:设最小提升度,而且不要只设1.0。建议设1.1甚至1.5,具体看数据噪声水平。更严格一点的做法是要求置信度必须明显高于后件的自然支持度,也就是 confidence(A→B) / support(B) ≥ 1.1,这个条件等价于 lift ≥ 1.1。这比单独看置信度放在报表里直观得多。
4.3 提升度远小于1的负相关规则,可能是金矿
大家习惯性地认为只有提升度大于1的规则才有价值,其实小于1的"反向规则"在不少场景里同样重要,甚至更稀缺。
还是用"鲜奶 → 薯片"举例。提升度0.53意味着:鲜奶顾客里买薯片的人,只有随机顾客的一半。如果你在做促销套餐设计,这个信息能帮你避开雷区——别再给"鲜奶+薯片"做捆绑折扣了,优惠只会被用来买本来就是刚需的鲜奶。如果你在做替代品分析,负相关则直接指向"这两种商品服务的场景互斥",可以顺势去排查:是不是鲜奶偏好人群更注重健康,从而主动避开膨化食品?
判断负相关规则是否值得看,不能只看是不是小于1。样本量小的时候,提升度0.9、0.8基本都是噪声。我更关注的阈值是0.7以下,而且要结合支持度:如果支持度只有0.5%,那就算提升度0.4也没意义,样本太少经不起复购验证。"低支持度的方向性结论"是统计上最站不住脚的一类。
4.4 样本量不够时,三个指标都会失真
最后补一个很多人忽视的前提:三个指标都是基于历史事务的统计量,样本量直接决定它们的可信度。
举个例子,某小店月销售只有500张小票,其中"养生壶 → 花茶"出现了40次,支持度8%,置信度50%,提升度2.0,看起来很漂亮。但如果这40笔里,有20笔来自同一个企业客户的单次团购,这条规则就完全是虚假繁荣。零售分析里的大单、团购、补货单都会污染计数,第一道预处理一定是把"异常大单"单独拎出来或剔除,分析"正常零售小票"。
另外,1000笔和100万笔数据量下,支持度1%的含义完全不同。1000笔里支持度1%只是10笔,100万笔里是10000笔,后者做出来的规则稳定得多。所以小样本场景建议把最小支持度适当调高,或者干脆不设固定值,而是约定"组合至少要出现50次以上"这种绝对频次门槛,保证每条规则背后都有足够多真实顾客行为支撑。
5. 从三个指标到完整挖掘流程:频繁项集、剪枝与代码落地
5.1 为什么不能把商品组合全都枚举一遍
如果只有4个商品,两两组合只有6个,手算就行。但现实里一家超市几千个SKU,三三组合、四四组合的数量会爆炸。直接枚举所有规则再计算指标,计算量是不可接受的。
这里有一个重要的剪枝性质,叫向下闭包性:如果一个项集不频繁(支持度低于最小支持度),那么包含它的所有超集也一定不频繁。原因很简单,{咖啡, 鲜奶, 面包} 同时出现的小票数量,不可能超过 {咖啡, 鲜奶} 的小票数量,所以超集的支持度只可能更低。基于这个性质,标准的挖掘流程分两步:
- 找频繁项集:从1-项集开始,保留支持度达标的,再用频繁k-项集拼接候选(k+1)-项集,逐层扩展,直到找不到新的频繁项集为止。
- 生成规则:对每个频繁项集,枚举所有"前件+后件"的切分,计算置信度和提升度,留下过滤后仍达标的规则。
第一个阶段的过滤依据是支持度,第二个阶段的过滤依据是置信度和提升度。三个指标正好各管一段,这也解释了为什么它们是关联分析的三大核心概念。
5.2 用Python手写一个三指标筛选流程
这里给一个极简的实现思路,不依赖重量级框架,核心就是前面两张计数表。实际项目里,这些计数可以从数据库里按条件聚合出来,思路完全一致。
N = 1000 item_counts = {"咖啡": 400, "鲜奶": 300, "面包": 600, "薯片": 250} pair_counts = { ("咖啡", "鲜奶"): 180, ("咖啡", "面包"): 240, ("咖啡", "薯片"): 120, ("鲜奶", "面包"): 150, ("鲜奶", "薯片"): 40, ("面包", "薯片"): 150, } min_support = 0.10 min_confidence = 0.40 min_lift = 1.05 for (a, b), cnt_ab in pair_counts.items(): sup_ab = cnt_ab / N if sup_ab < min_support: continue conf_ab = cnt_ab / item_counts[a] if conf_ab < min_confidence: continue lift_ab = conf_ab / (item_counts[b] / N) if lift_ab < min_lift: continue print(f"规则 {a} -> {b}: 支持度={sup_ab:.1%}, 置信度={conf_ab:.1%}, 提升度={lift_ab:.2f}")按代码里的阈值跑一遍,你会发现只有"咖啡 → 鲜奶"通过:支持度18%达标,置信度45%达标,提升度1.5达标。"咖啡 → 面包"和"面包 → 薯片"死在提升度小于1.05,"咖啡 → 薯片"死在置信度30%低于40%,"鲜奶 → 薯片"死在支持度4%低于10%。这个结果很能说明问题:三个阈值同时过滤,会把候选规则压到一个很小的范围,留下来的才是真正值得业务投入验证的。
如果你要扩展到三商品、四商品的规则,只需要把 pair_counts 换成更大项集的计数表,再对每个频繁项集枚举所有前后件切分。数学原理没有任何变化,变化的是候选集膨胀的速度,这时候才需要认真用向下闭包性做剪枝,或者直接用现成的频繁项集算法。
5.3 三个指标在业务场景里的落地姿势
指标算出来之后,不同业务动作对指标的偏好不一样,我说三个最常见的。
交叉销售。做"买了A之后推荐B"的场景,首先要求规则满足最小支持度(保证样本量)和较高置信度(保证推荐成功率),用提升度排序决定优先级。给业务解释的时候就把提升度翻成人话:"与咖啡同购概率提升50%"。
捆绑套餐。设计"A+B组合优惠"时,更看重支持度和提升度的乘积。高支持度意味着目标人群大,高提升度意味着两者确实存在协同,套餐才能带动原本不会买B的人下单。如果只是两个本来就都卖得好的商品拼在一起,那只是让利,不是捆绑。
货架与陈列。高提升度的商品尽量近场陈列,比如咖啡和鲜奶放在一条动线上;低提升度甚至负相关的商品保持距离,避免一个商品的促销流量被另一个商品"抢走"。这类调整通常先在小范围试点,再看销量变化是否与提升度方向一致。
最后再强调一遍:提升度只证明统计共现,不证明因果。咖啡和鲜奶如果都在早餐时段被购买,真正的驱动因素是"早餐场景",把它们放在一起也许能提高顺带购买率,但这不代表咖啡"导致"了鲜奶的购买。验证因果,只能靠线下实验:选几家店调整陈列,拉同期对照组,用销量差说话。
6. 项目里真正决定成败的,是阈值调法和规则筛选口径
6.1 阈值是"试"出来的,不是拍出来的
很多教程会给你一个默认配置,比如支持度0.5%、置信度50%、提升度1。这只适合练手,不适合真实数据。我的做法分三步走。
先理解数据形状。跑一下所有商品的单品支持度分布,看看中位数在哪里、长尾有多长。如果90%的商品支持度都低于1%,你就知道最低支持度绝对不能按"感觉随便定个5%"。
再定规则数量目标。跟业务方确认他们希望最终看多少条规则——一般50到200条是运营消化的极限。然后反向调参:先把支持度定到某个值,统计生成的频繁项集数量;再调置信度和提升度,控制规则总量。
最后小步验证。任何阈值组合产生的规则,先挑排名前20的给业务看,问一句"这些规则里有没有明显不符合常识的"。如果多数规则业务一眼就能解释通,说明阈值方向对了;如果频繁出现"咖啡 → 卫生纸"这种莫名组合,大概率是阈值太低或者数据里有异常单。
6.2 规则数量爆炸时的收敛策略
真实数据里,随便跑一下就可能生成几十万条规则。绝大多数规则没有业务价值,如何收口有几个实用手段。
限制规则的形态。比如只保留单前件规则,或者前件最多两个商品,这会大幅压缩规则空间。对零售来说,"两件商品的关联"已经覆盖了绝大多数可执行的销售动作,三件以上的规则很难变成一句话的营销话术。
去掉冗余规则。如果 "A → B" 和 "A, C → B" 同时具有相近的置信度和提升度,保留更短的那条。判断标准可以约定为:加入C之后置信度没有显著提升(比如提升不超过5个百分点),就认为C没有贡献。否则,规则列表会被同一组事实的各种花式切分刷屏。
按业务权重排序。光按提升度排序也有问题,提升度容易被低频商品带飞。我常用一个综合口径:先按提升度降序取Top,然后看支持度是否达到业务最低销量要求,最后人工复核前50条。如果想让排序更稳健,可以把置信度也纳入,比如按提升度乘以置信度排序,兼顾强度和可靠性。再进阶一点,还可以用杠杆率、确信度这类衍生指标做二次排序,它们本质上都是对三个核心指标的组合应用。
6.3 我的一点项目经验和习惯
最后聊几个我在项目里反复遇到、但文档里很少写的点。
第一,一定先清洗异常大单。一键过滤单笔超过50件商品的订单,能替你挡掉一大半虚假规则。之前在某零售项目里,一条"香薰机 → 精油"的规则支持度异常高,排查后发现是公司采购团购刷出来的,真实散客根本没这个习惯。
第二,关联关系会随时间漂移。节假日、季节、促销周期都会改变共现结构。今天挖出来的规则,下个月可能完全失效。所以关联分析最好是周期性重跑,而不是做一次就存档。
第三,规则要跟着业务口径走。同样是"咖啡 → 鲜奶",在"新品上市""会员日""晚市打折"这几个场景下的表现可能完全不同。更合理的做法是按场景切片数据分别跑规则,而不是把一年的事务混在一起出一个"大锅饭"结果。
第四,落到动作之前先做小范围验证。挖规则只完成了分析的一半,另一半是设计实验:选8到10家门店,一半调整陈列或推荐,一半维持原样,跑两到四周看增量。数据上说提升度高的规则,只有经过这一关,才真正有资格进入运营手册。
结构和指标其实都不难,难的是把这三件套用进真实业务时的那份谨慎。我自己这几年最大的感受是:支持度、置信度、提升度帮你把几百万条候选压到几十条,但真正决定规则价值的,是清洗数据的那点耐心、验证实验的那点投入,还有把规则讲给业务听时的那点人话。希望这篇能让你少走我走过的弯路。