指标异动归因:从贡献度公式到 CDN 毛利率的层层下钻

2812 字
14 分钟
指标异动归因:从贡献度公式到 CDN 毛利率的层层下钻

在字节做火山 CDN 经营分析时,看板每天都会出数,领导最常问的不是「毛利率是多少」,而是「毛利率为什么掉了?」。一张看板只能告诉你结果,回答「为什么」得靠归因。

这篇文章记录我当时学习归因分析的过程,以及最后落地到经营分析平台上的做法。方法主要参考了 CSDN 上一篇讲贡献度计算的文章(见文末参考),这里按我自己的理解重新梳理,例子都换成了 CDN 场景。文中数字均为示意,不是真实业务数据。

一、核心思路:顺着公式往下拆#

归因的出发点很简单:每个指标都有计算公式,指标变了,一定是公式里的某个子指标变了。

所以归因就是两步,反复递归:

  1. 把指标按公式拆成子指标;
  2. 算出每个子指标对这次变化的贡献度,找出贡献最大的那个,再对它继续拆。

难点在第 2 步:公式的形态不同,贡献度的算法也不同。按公式形态,指标可以分成三类。

二、加法型指标:直接看差值#

形态:总量 = 各部分之和。比如总成本 = 各客户成本之和,总带宽 = 各域名带宽之和。

贡献度:某部分的变化量 ÷ 总量的变化量。

Ci=ΔxiΔY,Y=∑ixiC_i = \frac{\Delta x_i}{\Delta Y},\quad Y=\sum_i x_i

例子:本月总成本比上月涨了 100 万,其中客户 A 涨了 80 万,客户 B 涨了 30 万,客户 C 降了 10 万。那么 A 的贡献度是 80%,B 是 30%,C 是 -10%,加起来正好 100%。

这是最直观的一类,注意贡献度可以是负数,也可以超过 100%(有正有负相互抵消时)。

三、乘法型指标:用对数拆开#

形态:指标 = 几个因子相乘。比如带宽成本 = 计费带宽 × 单价。

乘法的麻烦在于因子之间会「交叉影响」:带宽涨了 20%、单价降了 10%,总的变化里有一部分是两者叠加出来的,没法简单归给某一方。

常用的解法是 LMDI(对数平均迪氏指数分解)。思路是取对数,把乘法变成加法:

ln⁡Y1Y0=∑iln⁡xi1xi0\ln\frac{Y^1}{Y^0} = \sum_i \ln\frac{x_i^1}{x_i^0}

再乘上一个对数平均权重,把每个因子的贡献换算回绝对值:

ΔYxi=L(Y1,Y0)⋅ln⁡xi1xi0,L(a,b)=a−bln⁡a−ln⁡b\Delta Y_{x_i} = L(Y^1, Y^0)\cdot\ln\frac{x_i^1}{x_i^0},\quad L(a,b)=\frac{a-b}{\ln a-\ln b}

这种分解没有残差,各因子贡献加起来正好等于总变化。

例子:上月计费带宽 1000、单价 10,成本 10000;本月带宽 1200、单价 9,成本 10800,涨了 800。

  • 对数平均权重 L ≈ 10395
  • 带宽的贡献 ≈ 10395 × ln(1.2) ≈ +1895
  • 单价的贡献 ≈ 10395 × ln(0.9) ≈ -1095
  • 合计 = 800 ✓

结论很清楚:成本上涨是用量增长带来的,降价抵消了一部分。

四、比率型指标:要分清「自己变了」还是「结构变了」#

这是最容易算错、也最有价值的一类。

形态:指标 = 分子 / 分母。比如毛利率、命中率、单位带宽成本。整体比率可以写成各组比率按分母占比的加权平均:

r=∑iri pi,pi=第 i 组分母占比r = \sum_i r_i\, p_i,\quad p_i=\text{第 } i \text{ 组分母占比}

整体比率变化,可能有两种原因:

  • 组内变化:某个客户自己的毛利率变了;
  • 结构变化:各组本身没变,但低毛利客户的收入占比变大了,整体也会被拉低。

如果只看各客户自身的毛利率,会完全漏掉第二种原因。

三种算法#

1. 控制变量法:只让一组变化,其他组保持基期,看整体比率变了多少。直观,但各组贡献加起来通常不等于总变化,不推荐。

2. 综合占比法:把变化拆成「组内比率变化」和「占比变化」两部分。各组贡献可以相加,等于总变化。

3. 综合贡献法(推荐):在综合占比法基础上,再把结构项改成「该组比率与整体比率的差距 × 占比变化」:

Δr=∑i[Δri pi0⏟组内变化+Δri Δpi⏟交叉项+(ri0−r0) Δpi⏟结构变化]\Delta r = \sum_i \Big[\underbrace{\Delta r_i\, p_i^0}_{\text{组内变化}} + \underbrace{\Delta r_i\, \Delta p_i}_{\text{交叉项}} + \underbrace{(r_i^0 - r^0)\,\Delta p_i}_{\text{结构变化}}\Big]

推导的关键一步是:各组占比之和恒为 1,所以占比变化之和为 0,可以在结构项里减去一个 r⁰ × ΣΔpᵢ 而不改变总和。这样改写之后,结构项的含义变成了:一个比平均水平差的组占比变大,才会拉低整体,解释起来顺多了。

例子:毛利率掉了 3 个点#

客户上月收入占比上月毛利率本月收入占比本月毛利率
A60%40%50%40%
B40%20%50%18%
整体32%29%

按综合贡献法拆:

客户组内变化交叉项结构变化合计
A00-0.8 pp-0.8 pp
B-0.8 pp-0.2 pp-1.2 pp-2.2 pp
合计-0.8 pp-0.2 pp-2.0 pp-3.0 pp

结论:毛利率下降的 3 个点里,有 2 个点来自结构变化,也就是低毛利的客户 B 收入占比上升了;只有 1 个点是 B 自身毛利率下降。如果只盯着各客户的毛利率,会以为 A 完全没问题、B 只降了 2 个点,得出错误的结论。

五、在字节的应用:按指标公式逐层递归#

在火山 CDN 经营分析平台上,我把上面三类方法组合成了一套递归归因的逻辑。

1. 先建好指标公式树#

经营分析的核心指标之间,本来就有明确的公式关系。把它们整理成一棵树,每个节点标明公式类型:

  • 毛利率(比率)= 毛利 / 收入,可以按客户拆成加权平均
  • 收入(加法)= 新增客户收入 + 存量客户收入(流失客户记为负)
    • 客户收入(乘法)= 计费用量 × 平均单价
    • 平均单价(比率)= 各计费项、各区域单价按用量占比加权
  • 成本(加法)= 各客户成本之和 = 各域名成本之和
    • 客户成本(乘法)≈ 计费用量 × 单位成本

其中成本数据来自我设计的「95 区间」分摊算法,每天产出到客户、域名粒度,这是整套归因能落地的前提:没有细粒度的成本,就拆不下去。

2. 收入归因:客户、用量、价格#

收入是经营分析里被问得最多的指标,也是拆得最细的一棵子树。它的难点在于,同一个「收入变化」背后可能是完全不同的业务动作:新签了客户、老客户放量、续约降价、流量往海外迁移,这些对应的跟进人和应对方式都不一样。所以收入归因要分三层拆。

第一层:客户增减(加法)

先把收入变化按客户类型分开:

  • 新增客户:上期没有、本期有收入,全部算作新增贡献;
  • 流失客户:上期有、本期没有,全部算作流失贡献(负数);
  • 存量客户:两期都有收入,进入下一层继续拆。

例如本月收入环比 +50 万:新增客户 +30 万,流失客户 -40 万,存量客户 +60 万。单看总数是小幅增长,拆开才发现流失其实很严重,只是被存量增长盖住了。

第二层:用量 × 单价(乘法,LMDI)

存量客户的收入 = 计费用量 × 平均单价,用前面的 LMDI 拆成「用量变化」和「价格变化」两部分。

例如头部客户 C,上月收入 200 万,本月用量 +20%,续约后单价 -10%,收入变成 216 万:

  • 对数平均权重 L ≈ 207.9
  • 用量贡献 ≈ 207.9 × ln(1.2) ≈ +37.9 万
  • 价格贡献 ≈ 207.9 × ln(0.9) ≈ -21.9 万
  • 合计 = +16 万 ✓

这个结论对销售和运营很有用:C 的业务在增长,但降价吃掉了一半以上的增量。

第三层:单价变化的「真调价」与「结构变化」(比率)

拆到价格还没完。CDN 的平均单价本身是一个比率:不同计费区域(国内、海外各区域)、不同计费项的单价差别很大,平均单价 = 各项单价按用量占比加权。所以平均单价变了,可能根本没有调价,只是用量结构变了。

例如某客户国内单价 10、海外单价 30,两个月都没调价:

区域上月用量占比本月用量占比单价
国内90%80%10
海外10%20%30
平均单价12 → 14

用综合贡献法拆,组内变化(真调价)为 0,平均单价上涨的 2 全部来自结构变化:海外占比上升贡献 +1.8,国内占比下降贡献 +0.2。也就是说,这个客户的「涨价」其实是流量往海外迁移了。如果把它当成调价成功去汇报,就是错误的结论。

到这里,一次收入异动就能落到具体的业务动作上:是哪类客户、哪个客户,是用量还是价格,价格是真调价还是区域结构变化。

3. 递归下钻#

当某个指标出现异动(比如环比超过阈值),就从这个节点开始:

  1. 根据节点的公式类型,选择对应的贡献度算法;
  2. 算出各子节点的贡献度,取贡献最大的那个;
  3. 对这个子节点重复上面的过程,直到叶子节点,或者贡献度已经足够分散、无法再明显收敛。

最后输出一条归因路径,例如:

毛利率环比 -3pp → 主要来自结构变化(低毛利客户收入占比上升)→ 客户 B → 成本上涨 → 计费用量增长贡献最大 → 域名 x

收入环比 +50 万 → 存量客户 +60 万、流失客户 -40 万 → 存量中客户 C 贡献最大 → 用量 +37.9 万、价格 -21.9 万 → 价格下降来自续约调价

这样,看板上看到的不再只是一个变红的数字,而是一句可以直接拿去跟进的结论。

4. 实践里的几点体会#

  • 公式要和口径完全一致:归因拆出来的子指标,必须和看板上的计算口径一致,否则各部分加起来对不上总数,业务方第一眼就不信。
  • 比率指标一定要看结构:CDN 业务里客户结构变化非常常见,比如某个大客户放量、低价客户占比上升,只看组内变化很容易误判。
  • 新增和流失要单独处理:新客户上期为 0、流失客户本期为 0,取对数会出错,LMDI 也算不了,必须在乘法拆解之前先用加法把它们拆出去。
  • 递归要有停止条件:贡献度太分散时,继续下钻只会得到噪音;这时输出「多因素共同影响」比强行给出一个结论更可靠。
  • 归因只是定位,不是解释:它能告诉你「是 B 客户的用量涨了」,但「为什么涨」还需要运营去跟客户确认。

参考#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

指标异动归因:从贡献度公式到 CDN 毛利率的层层下钻
https://tracerzzz.cn/posts/metric-anomaly-attribution/
作者
tracerZzz
发布于
2026-10-25
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
CDN 新客户接入前的价格测算:用波形拟合算出最低成本价
工作火山 CDN 经营分析平台上的价格测算功能:销售拿到一个新客户的带宽打点,平台把它和大盘拟合,判断客户是否错峰、算出边际超卖倍数,再结合资源诉求的加权成本和包头系数,给出不同计费方式下的最低成本价。这篇讲它的输入、计算过程、示例和后续的优化方向。
2
CDN 是怎么收费的:从流量、95 峰值到日峰月均,厂商和客户两边看计费
工作我在百度云 CDN 做过客户账单,在字节做过火山 CDN 的计费推量,也做过融合 CDN 向多家厂商采购的对账和成本分摊,厂商和采购两边都经历过。这篇整理 CDN 常见的计费方式:流量、带宽峰值、95 峰值、日峰月均、月第四峰值、夜间减半、闲忙时、请求数,以及计费区域、包头系数这些容易忽略的细节,并用一个月的模拟数据对比不同方式算出来差多少。
3
CDN 的错峰与超卖:为什么厂商能把同一份带宽卖好几次
工作在 95 计费下,一个新客户接入后,大盘的 95 可能几乎不涨,这就是错峰客户。它让 CDN 厂商可以把同一份带宽卖给多个客户,也就是超卖。这篇用模拟数据讲清楚错峰和超卖,以及衡量它们的两个指标:单个客户的边际超卖倍数,和整个平台的超售比。
4
我的第一项专利:用「95 区间」把 CDN 带宽成本分得更准
工作白话解读我作为第一发明人的发明专利(中国 CN117061354B、美国 US12375742B2):为什么按 95 峰值时间点分摊 CDN 带宽成本会算不准,以及「95 区间」分摊法是怎么解决的。附专利原文 PDF。
5
一个接口管多家 CDN:多厂商刷新预热的适配层设计
工作我在字节负责火山多云 CDN 和融合 CDN 的多厂商内容管理(刷新、预热)。这篇讲怎么用适配器模式屏蔽厂商差异,怎么在多云层做配额和限频,怎么按每家厂商的限制拆分任务,怎么用 RocketMQ、Redis、MongoDB 实现分布式下发、共享配额、重试和进度汇总,以及后来如何借助 AI 把新厂商接入时间缩短到一两天。
随机文章随机推荐

评论区

Profile Image of the Author
tracerZzz
想当木匠的程序员!
分类
标签
站点统计
文章
19
分类
9
标签
48
总字数
79,096
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录