套餐实验室Bundle Lab
Method

方法与假设

这一页把公式写清楚、把假设标出来。看不懂的地方是我没写好,不是你的问题。

一、组合发现:关联规则

从订单里找「经常一起买」的商品组合。三个指标:

支持度  supp(A∪B) = 同时含 A、B 的订单数 / 总订单数
置信度  conf(A→B) = supp(A∪B) / supp(A)        买了 A 的人里多少也买了 B
提升度  lift(A→B) = conf(A→B) / supp(B)        这个概率是随机水平的几倍

lift = 1 是纯巧合;lift 越大,「一起买」越不是偶然。lift 对 A、B 对称,所以一个组合只算一次; 置信度不对称,页面上展示的是置信度更高的那个方向(「买了 A 的人更可能买 B」比反过来更有用)。

实现是标准 Apriori:先找频繁单品,再两两组合,再三三组合,每层用支持度剪枝。 数据量只有几千单、几十个 SKU,不需要更快的算法。代码在 lib/rules.js, 有 21 条手算断言(scripts/test-rules.mjs)。

排序不是纯按 lift。用 lift × log(1 + 命中订单数)。原因:支持度低的组合容易刷出虚高 lift —— 40 单里出现 30 次共现和 400 单里出现 300 次共现,lift 一样,可信度差十倍。

二、收益估算:套餐推出去会怎样

口径只在「组合涉及的这几件商品」上比较。一个人采纳套餐,变化的只是这几件的花费,整单其余的菜照点。

匹配订单     = 含组合中至少一件商品的订单(套餐能推给谁)
partialSpend = 匹配订单原本在这几件上的平均花费
套餐价       = 组合原价 × (1 − 折扣率)

Δ客单/单  = 采纳率 × (套餐价 − partialSpend)
原毛利    = partialSpend × (1 − 成本率)
套餐毛利  = 套餐价 − 原价 × 成本率
Δ毛利/单  = 采纳率 × (套餐毛利 − 原毛利)

三档采纳率(保守 5% / 中性 12% / 乐观 25%)给的是区间,不是点估计。这三个数是经验估计,没有数据支撑, 详见 docs/ASSUMPTIONS.md

第一版把基线用成了整单客单价(含套餐外的菜),结果 50 个组合 49 个算成「亏」。 不是假设太保守,是量纲错了。修正后只剩 1 个不可行,而且它是对的。

三、盈亏平衡:至少多少人接才不亏

h = 命中率:匹配订单里本来就买齐全套的比例(这些人吃折扣不产生增量)
d = 每单让利 = 原价 × 折扣率
g = 每单增量毛利 = 套餐毛利 − 未命中者原本的毛利

平衡条件  (1 − h) · a · g = h · d
平衡采纳率  a = h · d / ((1 − h) · g)

含义:h 越高,本来就成套买的人越多,白让的折扣越多,门槛越高。h 超过三成的组合(本数据里的「牛肉面+卤蛋」), 做折扣套餐是纯让利,更适合加价购。

已知弱点:假设未命中者「不采纳就什么都不多买」。如果他们本来也会加购,g 被高估、平衡点被低估。 这是全项目最该被人复核的公式。

四、默认参数一览

参数默认值来源
lift 下限1.2经验估计;阈值敏感度实测见校验页
支持度下限1%经验估计;与订单量绑定,2000 单以上才稳
置信度下限10%随手定的兜底,未做敏感性测试
套餐折扣率12%演示默认值,应按品类毛利结构调
成本率40%中式快餐通行区间 30-45% 取中位;对结果最敏感
采纳率 保守/中性/乐观5 / 12 / 25%经验估计;三个前提都偏乐观,当上限看
建议入选最低覆盖100 单经验估计;再小落地成本摊不平
建议去重重合度50%随手定;去重动作本身是必须的

五、不做什么