流量交易
现代计算广告中,最广泛的流量交易模式为实时竞价模式,即Real-Time-Bidding(RTB)。实时竞价顾名思义,就是在流量到达时被放到交易市场进行公开的,实时的竞拍,参与竞拍的广告主赢得竞拍后,即可获得对这个流量的投放权,整个流程如图示。 以新浪微博的信息流广告为例,当我们刷微博时,微博的信息流(或者timeline)中会夹杂着广告,假设微博将信息流的第4和第10位作为广告位,那么每次你刷新微博后,list中的第4和第10条微博总会是推广(广告)微博。于是当用户A进入微博的信息流界面时,除了从服务器请求微博内容之外,还会同时向RTB请求广告内容,这个请求称之为曝光请求。RTB接受到该曝光请求后,将此次曝光放入流量市场进行实时拍卖,诸多广告主的投放系统(DSP)接到拍卖的事件后,立即对该曝光请求进行出价,一般来说根据曝光质量和属性不同,各个广告主对其出价也不尽相同。例如信息流第4位的曝光出价就比信息流第10位出价高,因为排在前面的广告更能引起用户注意,再如篮球鞋销售商对男性微博用户的曝光请求出价要比女性微博用户的曝光出价要高,因为篮球鞋的受众群体主要是男性。在广告主出价完成后,RTB则向出价最高的广告主请求广告内容,并且将此内容返回到微博客户端,于是用户在刷微博时就看到了这个广告,完成了一次广告曝光。这整个请求、竞价、返回广告的过程会在毫秒级别内完成。
第二高价和底价问题
在RTB的流量竞拍中是按照第二高价 来计费的,这意味着如果第
t
t
t 次曝光n个广告主对其出价分别为
b
1
(
t
)
,
b
2
(
t
)
,
b
3
(
t
)
,
.
.
.
,
b
n
(
t
)
b_1(t),b_2(t),b_3(t),...,b_n(t)
b 1 ( t ) , b 2 ( t ) , b 3 ( t ) , . . . , b n ( t ) ,且有
b
1
(
t
)
>
b
2
(
t
)
>
b
3
(
t
)
>
.
.
.
>
b
n
(
t
)
b_1(t)>b_2(t)>b_3(t)>...>b_n(t)
b 1 ( t ) > b 2 ( t ) > b 3 ( t ) > . . . > b n ( t ) ,那么广告主1竞价胜出,但是媒体方只会向广告主1收费
b
2
b_2
b 2 元。这种计费方式主要可以让广告主失去调价的动力,否则在广告主竞价胜出之后,会立即调低出价,以期望使用更低的价格拿到曝光,从而提高自身收益。但是从媒体方的角度来说,第二高价的机制存在着
δ
=
b
1
(
t
)
−
b
2
(
t
)
\delta = b_1(t)-b_2(t)
δ = b 1 ( t ) − b 2 ( t ) 的利润空间没有充分利用,于是引出了底价机制。底价机制指的是RTB在竞价拍卖的过程中,设置一个最低价格
α
\alpha
α , 称之为底价。当
b
1
(
t
)
<
α
b_1(t)<\alpha
b 1 ( t ) < α 时则RTB则拒绝售卖该流量,或者将流量导入其它交易市场售卖。当
b
1
(
t
)
≥
α
>
b
2
(
t
)
b_1(t) \ge \alpha>b_2(t)
b 1 ( t ) ≥ α > b 2 ( t ) 时,按照
α
\alpha
α 向胜出的广告主收费,当
b
2
(
t
)
≥
α
b_2(t) \ge \alpha
b 2 ( t ) ≥ α 时,则按照
b
2
(
t
)
b_2(t)
b 2 ( t ) 向胜出的广告主收费。总结起来,在第
t
t
t 次竞价中,向竞价胜出的广告主收费
r
(
t
)
r(t)
r ( t ) 如式(1)所示。
(1)
r
(
t
)
=
{
α
,
b
1
(
t
)
≥
α
>
b
2
(
t
)
b
2
(
t
)
,
b
2
(
t
)
≥
α
0
,
α
>
b
1
(
t
)
r(t)=\left\{\begin{array}{ll}{\alpha,} & {b_{1}(t) \geq \alpha>b_{2}(t)} \\ {b_{2}(t),} & {b_{2}(t) \geq \alpha} \\ {0,} & {\alpha>b_{1}(t)}\end{array}\right. \tag{1}
r ( t ) = ⎩ ⎨ ⎧ α , b 2 ( t ) , 0 , b 1 ( t ) ≥ α > b 2 ( t ) b 2 ( t ) ≥ α α > b 1 ( t ) ( 1 ) 从
r
(
t
)
r(t)
r ( t ) 的表达式中可以看到,当满足
b
1
(
t
)
≥
α
>
b
2
(
t
)
b_1(t) \ge \alpha > b_2(t)
b 1 ( t ) ≥ α > b 2 ( t ) 时,媒体放可以比原来的纯二价计费方式多赚
β
(
t
)
=
α
−
b
2
(
t
)
\beta(t)=\alpha-b_2(t)
β ( t ) = α − b 2 ( t ) ,但也要注意到当
α
>
b
1
(
t
)
\alpha > b_1(t)
α > b 1 ( t ) 时也存在损失
b
2
(
t
)
b_2(t)
b 2 ( t ) 的风险。于是一个很自然的想法就是:
让
α
\alpha
α 能自动调整,让
α
\alpha
α 在
b
1
(
t
)
b_1(t)
b 1 ( t ) 较大时,
α
\alpha
α 也能随之增大,反之则减小。 – 原则[1]
这就是动态底价的概念,我们重新把这个可以变化的底价定义为
α
(
t
)
\alpha(t)
α ( t ) ,表示在第
t
t
t 次竞价中的底价。式子(1)重新表述为式(2)。
(2)
r
′
(
t
)
=
{
α
(
t
)
,
b
1
(
t
)
≥
α
(
t
)
>
b
2
(
t
)
b
2
(
t
)
,
b
2
(
t
)
≥
α
(
t
)
0
,
α
(
t
)
>
b
1
(
t
)
r^{\prime}(t)=\left\{\begin{array}{ll}{\alpha(t),} & {b_{1}(t) \geq \alpha(t)>b_{2}(t)} \\ {b_{2}(t),} & {b_{2}(t) \geq \alpha(t)} \\ {0,} & {\alpha(t)>b_{1}(t)}\end{array}\right. \tag{2}
r ′ ( t ) = ⎩ ⎨ ⎧ α ( t ) , b 2 ( t ) , 0 , b 1 ( t ) ≥ α ( t ) > b 2 ( t ) b 2 ( t ) ≥ α ( t ) α ( t ) > b 1 ( t ) ( 2 ) 目前动态底价的算法主要有三种:
基于贝叶斯推断的底价估计算法
基于均值统计的底价估计算法
基于经验的One-Shot底价调整算法
下面逐一介绍这三个算法。
基于贝叶斯推断的底价估计算法
该算法首先假设在一次RTB竞价的过程中,最高出价
B
1
B_1
B 1 为满足对数高斯分布的随机变量,并且假设其方差已知(可以当成超参数来调),而其均值的先验分布为高斯分布,即:
(3)
B
1
∼
lognorm
(
μ
,
σ
2
)
μ
(
t
)
∼
N
(
θ
(
t
)
,
δ
2
(
t
)
)
\begin{aligned} B_{1} & \sim \operatorname{lognorm}\left(\mu, \sigma^{2}\right) \\ \mu(t) & \sim \mathcal{N}\left(\theta(t), \delta^{2}(t)\right) \end{aligned} \tag{3}
B 1 μ ( t ) ∼ l o g n o r m ( μ , σ 2 ) ∼ N ( θ ( t ) , δ 2 ( t ) ) ( 3 ) 假设
μ
(
t
)
\mu(t)
μ ( t ) 的分布在系统上线前已经由历史时刻
[
0
,
t
]
[0,t]
[ 0 , t ] 的数据拟合得到了
θ
(
t
)
\theta(t)
θ ( t ) 和
δ
2
(
t
)
\delta^2(t)
δ 2 ( t ) ,当系统在线运行时,
t
+
1
t+1
t + 1 竞拍结束后得到一个最高出价的样本
b
1
(
t
+
1
)
b_1(t+1)
b 1 ( t + 1 ) ,这样由于对数高斯分布和高斯分布为共轭分布,可以直接后验分布
(4)
p
(
θ
(
t
)
∣
b
1
(
t
+
1
)
)
=
N
(
θ
(
t
+
1
)
∣
θ
(
t
)
,
δ
2
(
t
)
)
\begin{aligned} p(\theta(t) | b_1(t+1))=\mathcal{N}\left(\theta(t+1) | \theta(t), \delta^{2}(t)\right) \end{aligned} \tag{4}
p ( θ ( t ) ∣ b 1 ( t + 1 ) ) = N ( θ ( t + 1 ) ∣ θ ( t ) , δ 2 ( t ) ) ( 4 ) 其中
(5)
θ
(
t
+
1
)
=
θ
(
t
)
δ
2
(
t
)
+
σ
2
b
1
(
t
+
1
)
σ
2
+
δ
2
(
t
)
δ
2
(
t
+
1
)
=
δ
2
(
t
)
σ
2
σ
2
+
δ
2
(
t
)
\begin{aligned} \theta(t+1) &=\frac{\theta(t) \delta^{2}(t)+\sigma^{2} b_{1}(t+1)}{\sigma^{2}+\delta^{2}(t)} \\ \delta^{2}(t+1) &=\frac{\delta^{2}(t) \sigma^{2}}{\sigma^{2}+\delta^{2}(t)} \end{aligned} \tag{5}
θ ( t + 1 ) δ 2 ( t + 1 ) = σ 2 + δ 2 ( t ) θ ( t ) δ 2 ( t ) + σ 2 b 1 ( t + 1 ) = σ 2 + δ 2 ( t ) δ 2 ( t ) σ 2 ( 5 ) 这样根据最大后验估计的原则,我们可以使用
θ
(
t
)
\theta(t)
θ ( t ) 来作为
μ
\mu
μ 的估计,并且根据式(3)可知,可以将
l
o
g
(
θ
(
t
)
)
log(\theta(t))
l o g ( θ ( t ) ) 作为对
B
1
B_1
B 1 的估计。根据原则[1], 只要简单地设置:
(6)
α
(
t
+
1
)
=
l
o
g
(
θ
(
t
+
1
)
)
\alpha(t+1) = log(\theta(t+1)) \tag{6}
α ( t + 1 ) = l o g ( θ ( t + 1 ) ) ( 6 ) 可以看到基于贝叶斯推断的方法首先估计了
b
1
(
t
+
1
)
b_1(t+1)
b 1 ( t + 1 ) ,然后通过设置
α
(
t
+
1
)
\alpha(t+1)
α ( t + 1 ) 逼近
b
1
(
t
+
1
)
b_1(t+1)
b 1 ( t + 1 ) 的方式来最大化本次曝光的收益。
基于均值统计的底价估计算法
均值估计的想法其实十分朴素:本次曝光的收益应当不低于历史平均收益 。于是很直接的,使用
t
−
1
t-1
t − 1 时刻的历史平均收益来作为
α
(
t
)
\alpha(t)
α ( t ) 的估计:
(7)
α
(
t
)
=
1
M
∑
i
=
t
−
M
t
−
1
r
(
i
)
\alpha(t)=\frac{1}{M} \sum_{i=t-M}^{t-1} r(i) \tag{7}
α ( t ) = M 1 i = t − M ∑ t − 1 r ( i ) ( 7 ) 当然,线上系统的运行环境是会发生改变的,比如说流量分布,竞争环境,等等。所以收益分布应当也不是一个静态的分布,并且当样本越靠近当前时刻,则越有可能采样于当前的收益分布,所以计算平均收益时,应当使用加权平均的方式来进行,并且设置离当前时刻越近的数据,权重就越高:
(8)
α
(
t
)
=
1
M
∑
i
=
t
−
M
t
−
1
w
(
i
,
t
)
r
(
i
)
\alpha(t)=\frac{1}{M} \sum_{i=t-M}^{t-1} w(i, t) r(i) \tag{8}
α ( t ) = M 1 i = t − M ∑ t − 1 w ( i , t ) r ( i ) ( 8 ) 其中
w
(
i
,
t
)
w(i,t)
w ( i , t ) 的选择可以多种多样,只要满足当前时刻越近的数据,权重就越高 的原则即可。
ONE-SHOT底价调整算法
ONE-SHOT其实是一个调整算法而不是一个估计算法。其工作的流程是:
给定一个初始底价
α
(
t
)
\alpha(t)
α ( t )
根据一定规则在
α
(
t
)
\alpha(t)
α ( t ) 的基础上调整得到
α
(
t
+
1
)
\alpha(t+1)
α ( t + 1 )
初始底价可以根据经验直接指定,也可以通过式子(7)对历史数据统计给出。而调整的原则在于:
当底价低于
b
1
b_1
b 1 时,则应当缓慢提高底价,当底价高于
b
1
b_1
b 1 时应当迅速降低底价 --原则[2]
原则[2]提出的基本思想是:当底价低于
b
1
b_1
b 1 时,虽然此时收益并非是最大化的,但毕竟有
b
2
b_2
b 2 作为保证,收益不会太低,所以底价上涨探索最优的收费不必太过于急切,但如果底价高于
b
1
b1
b 1 时,收益将会直接变为0,所以需要快速降低底价,让
b
2
b_2
b 2 来保证收益。
根据原则[2],当然可以设置固定的小步伐
s
u
s_u
s u 和大步伐
s
l
s_l
s l 来调整底价。但是为了平滑和鲁棒性,可以根据式(9)来执行调整过程。
(9)
{
α
(
t
+
1
)
=
(
1
−
ϵ
t
λ
h
)
a
(
t
)
if
α
(
t
)
>
b
1
(
t
)
α
(
t
+
1
)
=
(
1
+
ϵ
t
λ
e
)
a
(
t
)
if
b
1
(
t
)
≥
α
(
t
)
≥
b
2
(
t
)
α
(
t
+
1
)
=
(
1
+
ϵ
t
λ
l
)
α
(
t
)
if
b
2
(
t
)
>
α
(
t
)
\left\{\begin{array}{ll}{\alpha(t+1)=\left(1-\epsilon^{t} \lambda_{h}\right) a(t)} & {\text { if } \alpha(t)>b_{1}(t)} \\ {\alpha(t+1)=\left(1+\epsilon^{t} \lambda_{e}\right) a(t)} & {\text { if } b_{1}(t) \geq \alpha(t) \geq b_{2}(t)} \\ {\alpha(t+1)=\left(1+\epsilon^{t} \lambda_{l}\right) \alpha(t)} & {\text { if } b_{2}(t)>\alpha(t)}\end{array}\right. \tag{9}
⎩ ⎨ ⎧ α ( t + 1 ) = ( 1 − ϵ t λ h ) a ( t ) α ( t + 1 ) = ( 1 + ϵ t λ e ) a ( t ) α ( t + 1 ) = ( 1 + ϵ t λ l ) α ( t ) if α ( t ) > b 1 ( t ) if b 1 ( t ) ≥ α ( t ) ≥ b 2 ( t ) if b 2 ( t ) > α ( t ) ( 9 ) 其中
ϵ
∈
(
0
,
1
]
\epsilon \in (0, 1]
ϵ ∈ ( 0 , 1 ] 且
λ
h
,
λ
e
,
λ
l
∈
[
0
,
1
]
\lambda_h, \lambda_e, \lambda_l \in [0, 1]
λ h , λ e , λ l ∈ [ 0 , 1 ] ,
ϵ
\epsilon
ϵ 是一个时间衰减系数,如果RTB只希望在启动后个某个时间段调整底价,并且最终收敛,则可以通过这个参数来调整。而
λ
h
\lambda_h
λ h 则用于调整当
α
(
t
)
>
b
1
(
t
)
\alpha(t) > b_1(t)
α ( t ) > b 1 ( t ) 时底价的降低速度。而同理
λ
l
\lambda_l
λ l 用来调整当
α
(
t
)
<
b
2
(
t
)
\alpha(t) < b_2(t)
α ( t ) < b 2 ( t ) 时底价的提升速度。
λ
e
\lambda_e
λ e 则用于调整探索最优收益的速度。从业务上来说,往往会设置
λ
h
>
λ
l
>
λ
e
\lambda_h>\lambda_l>\lambda_e
λ h > λ l > λ e ,即当前收益越高,调整速度越慢,这与原则[2]的基本思想是一致的。
其他讨论
上述三种底价算法里,基于贝叶斯推断的算法的数学理论是最完备的,但必须要考虑到这种算法存在最高出价符合对数高斯分布 这个假设前提的。这个假设并非放之四海而皆准的,各个广告系统的业务不一样,符合的分布也不一样,需要选择合适的分布,才能做出好的效果。并且需要注意的是,该算法优化的是单次曝光收益,并没有从全局的视角来考虑底价问题,不一定在整体收益上是最高的。
基于统计均值的算法是最朴素的,也是最容易实现的,不失为一个短平快的解决方案,它应当作为任何动态底价第一版本的最好选择,至少你能有一个Baseline去观察你的系统,判断动态底价对于你的广告系统来说是否是必要的,是否真的能提升收入。
而ONE-SHOT算法虽然没有数学理论支撑,但它作为一种博弈思维的产物,有从业务和全局的视角去考虑底价问题,从直觉上来看是最值得尝试的一种。当然,我想ONE-SHOT算法应当还有许多改进的空间,比如
λ
h
,
λ
e
,
λ
l
\lambda_h, \lambda_e,\lambda_l
λ h , λ e , λ l 参数的值可以跟贝叶斯推断来动态调整的值,也可以通过反馈控制的方法来动态调整。
但最终,无论如何,这里都没办法给哪一种算法的优劣性下一个断论,毕竟业务多种多样,只能认真做好A/B Test,好好调参,根据实际业务表现来选择算法了。