广告系统价格指标计算
价格指标计算
本文整理程序化广告里 eCPM、CPM、CPC 的计算口径。仓库当前出价代码只读取计划上的 bid_cpm / max_bid_cpm,没有按计费方式换算;下面的公式来自公开的 DSP 出价与广告报表定义,供后续实现和报表对齐。
金额在公式里用同一币种即可。落到本仓库时,金额字段单位是分,点击率按万分比存储(50 表示 0.5%)。
1. 三个指标分别算什么
| 指标 | 全称 | 回答的问题 | 计算时机 |
|---|---|---|---|
| CPM | Cost Per Mille,千次展示成本 | 每一千次曝光花多少钱 | 计划出价,或按展示结算后的报表 |
| CPC | Cost Per Click,单次点击成本 | 每一次点击花多少钱 | 计划出价,或按点击结算后的报表 |
| eCPM | effective / expected Cost Per Mille,有效(或预估)千次展示成本 | 不管原来按 CPM 还是 CPC 卖,折成每一千次曝光值多少钱 | 竞价前用预估点击率算出价;投放后用真实消耗和曝光回算 |
ADX 的竞价单位是 CPM。CPC 计划不能直接拿「单次点击价」去和别人的「千次曝光价」比,要先折成 eCPM,再参与排序和回价。
2. 报表口径(投放之后)
报表用真实消耗、曝光、点击,不依赖预估模型。Google Ad Manager / AdMob 的定义是:收入(或消耗)除以曝光再乘 1000 得到 eCPM,CPC 等于收入(或消耗)除以点击。
记:
Cost:该维度下的广告消耗Impressions:曝光次数Clicks:点击次数
1 | CTR = Clicks / Impressions |
几点对齐方式:
- 只按 CPM 结算时,报表 CPM 与 eCPM 相同,都是千次曝光的实际花费。
- 只按 CPC 结算时,消耗来自点击:
Cost = Clicks × 成交 CPC。此时没有单独的「展示单价」,用来和 CPM 计划对比的是 eCPM。 - 把上面的 CPC、CTR 代回去,CPC 计划的事后 eCPM 可以写成:
1 | eCPM = CPC × CTR × 1000 |
- 曝光为 0 时不算 CPM / eCPM;点击为 0 时不算 CPC。
例:消耗 90 元,曝光 10,000,点击 90。
- CTR = 90 / 10000 = 0.9%
- CPM 或 eCPM = 90 / 10000 × 1000 = 9 元
- CPC = 90 / 90 = 1 元
- 用 CPC 回算:1 × 0.009 × 1000 = 9 元,与 eCPM 一致
3. 竞价口径(请求进来时)
竞价时还没有这次曝光的真实点击,用预估点击率 pCTR(predicted CTR,0~1 的小数)代替 CTR。DSP 内部把不同计费方式都折成 eCPM,按 eCPM 从高到低选一条,再把这个价格以 CPM 单位返回给 ADX。
3.1 CPM:出价就是 eCPM
固定 CPM(计划上直接填千次曝光价)时:
1 | eCPM = CPM |
目标 CPM(TCPM)会按这条流量的点击率相对计划均值上下浮动,点击率更高的流量出更高的 CPM:
1 | Bid = Target_CPM × (pCTR / AVG_CTR) |
AVG_CTR 是该计划历史平均点击率。比值需要封顶,避免异常高的 pCTR 把出价打得过高。
3.2 CPC:先折成 eCPM 再出价
广告主填写的是目标点击价 Target_CPC。行业里 DSP 的换算是:
1 | eCPM = pCTR × Target_CPC × 1000 |
含义:若每一千次曝光里预期会点 pCTR × 1000 次,每次点击值 Target_CPC,则这一千次曝光的预期成本就是上面的 eCPM。
例:CPC 出价 0.9 元,pCTR = 0.9% = 0.009。
1 | eCPM = 0.009 × 0.9 × 1000 = 8.1 元 |
同一 CPC,pCTR 从 0.9% 降到 0.45%,eCPM 降到 4.05 元,出价跟着下降。CPC 本身不变。
若先用平均点击率得到基准 CPM,再按当前流量相对均值缩放,结果与上式相同:
1 | 基准 CPM = Target_CPC × AVG_CTR × 1000 |
3.3 返回给 ADX 之前的约束
内部胜出的 eCPM 还要落在广告位底价和计划上限之间,才作为 bid.price(分/CPM)返回:
1 | Bid > 0 |
底价或上限不满足则这条计划不出价。多条计划同时可投时,按 eCPM 取最高的一条(本仓库当前实现按 priority、weight 排序,尚未按 eCPM 排序)。
更完整的在线调价会在基础 eCPM 上再乘预算节奏、一价拍卖的压价、以及目标成本纠偏:
1 | Final_Bid = Base_eCPM × Pacing × Shading × Correction |
Pacing:预算花得过快则小于 1,花得过慢则大于 1。Shading:一价拍卖里通常取 0.7~0.95,避免按预估价值全额出价。Correction:实际 CPC(或 CPM)高于目标时压价,低于目标时放价。
这三项目前都没有进 dl-rtb,实现第一版时可以先只做第 3.1、3.2 节的基础 eCPM。
4. 和本仓库字段怎么对齐
计划表(campaigns)与 Redis 快照里已有这些字段,单位见 schema.sql:
| 字段 | 单位 | 用在 |
|---|---|---|
billing_type |
CPM / CPC |
选择下面哪条公式 |
bid_cpm |
分 / 千次曝光 | CPM 计划的出价 |
max_bid_cpm |
分 / 千次曝光 | 出价上限 |
target_cpc |
分 / 次点击 | CPC 计划的目标点击价 |
default_pctr |
万分比,50 = 0.5% | 没有实时 pCTR 时的默认点击率 |
万分比换成公式里的小数:
1 | pCTR = default_pctr / 10000 |
金额保持「分」时,CPC 折 eCPM(整数,向下取整):
1 | eCPM_分 = target_cpc × default_pctr / 10 |
推导:target_cpc × (default_pctr / 10000) × 1000 = target_cpc × default_pctr / 10。
例:target_cpc = 90(0.9 元),default_pctr = 90(0.9%)。
1 | eCPM_分 = 90 × 90 / 10 = 810 (8.10 元 / 千次曝光) |
建议的出价伪代码(尚未实现,当前 effectiveBidCPM 只在 bid_cpm > 0 时用 bid_cpm,否则用 max_bid_cpm,不看 billing_type):
1 | 若 billing_type = CPM: |
5. 对照例
| 场景 | 输入 | 计算 | 结果 |
|---|---|---|---|
| CPM 出价 | bid_cpm = 300 分 |
eCPM = CPM | 出价 300 分(3 元/千次) |
| CPC 出价 | CPC = 200 分,pCTR = 50(0.5%) | 200 × 50 / 10 | 出价 1000 分(10 元/千次) |
| CPC 报表 | 消耗 2000 分,曝光 10000,点击 20 | CPC = 2000/20;eCPM = 2000/10000×1000 | CPC = 100 分;eCPM = 200 分 |
| 同一 CPC 不同点击率 | CPC = 100 分;pCTR 1% 与 0.2% | 100×0.01×1000 与 100×0.002×1000 | eCPM 分别为 1000 分、200 分 |
参考
- 互联网广告:CPM 和 eCPM 有什么不同(人人都是产品经理):CPM 时 eCPM = CPM;CPC 时 eCPM = CTR × CPC × 1000。
- Price Model in DSP System(LeadsWORK):固定 CPM、TCPM、TCPC 的线性出价;TCPC 的基准 CPM = TCPC × AVG_CTR × 1000。
- DSP Bidding Strategies:eCPM = 1000 × p(click) × Target CPC;最终出价再乘 Pacing、Shading、Correction。
- Google AdMob:eCPM:eCPM = (Total Earnings / Impressions) × 1000。
- Google Ad Manager report metrics:eCPM = (Revenue / impressions) × 1000;CPC = Estimated revenue / Clicks。