计算广告(一)Ad Click Prediction: a View from the Trenches

——工程实践视角下的广告点击率预估

这是谷歌发表于KDD2013的一篇文章,从年份来看,已经有些年头了,至今已经有800多次被引,这篇文章一出,对工业界做广告的互联网公司还是有比较深远的影响,比如我厂的经典深度学习框架abacus,就借鉴了其中很多重要的思想。从这篇论文的标题也能看出它的主旋律:工程实践。顺便提一下,因为是2013年,那会深度学习刚刚在CV上有点苗头,广告领域有条件的大公司基本还是大规模的LR,没条件的可能连模型都没有,整一些大盘后验统计数据也挺好用。今天再来重读一下经典,又去看这篇文章的原因是前面在写推荐系统(五)wide&deep时,因为wide&deep模型的wide侧使用的优化器为FTRL,虽然对FTRL早已有耳闻,但还没真正去看过原始论文,所以决定再去看一看。其实这篇文章也不是最原始的论文,最原始的论文为[1],这篇论文从理论上介绍了FTRL。而《Ad Click Prediction: a View from the Trenches》这篇论文则注重在把理论运用到实践中,因此这篇论文的作者数量高达15+个。这篇论文的motivation为:在线服务的内存是有限的,如何减少模型的体积,即如何能使得模型变得更加稀疏,减少特征数量。 论文原文为:

Because trained models are replicated to many data centers for serving (see Figure 1), we are much more concerned with sparsification at serving time rather than during training.

基于这个motivation,来看看谷歌提供了哪些可借鉴的经验,这篇文章最难能可贵的地方在于不仅介绍了成功的经验,还介绍了失败的经验,这与一般的吹逼学术论文不太一样。
这篇博客的目录大纲遵循论文的section顺序,如下所示:

  1. FTRL优化算法
  2. Per-Coordinate Learning Rates
  3. Probabilistic Feature Inclusion
  4. Encoding Values with Fewer Bits
  5. Training Many Similar Models
  6. A Single Value Structure
  7. Computing Learning Rates with Counts
  8. Subsampling Training Data
  9. 一些失败的方法

一、FTRL优化算法
为了减少特征的数量,增加模型参数的稀疏性,学术界及工业界提出了各种办法,比如L1正则,FOBOS、RDA等方法。谷歌在论文[1]中提出了FTRL算法,FTRL结合了FOBOS(Forwrad-Backward spliting,前向后向切分)和RDA(Regularized Dual Averaging,正则对偶平均,微软于2010年发表)的优势,同时拥有了更高的稀疏性及精度。
通常来说,梯度下降类算法在batch模式下,增加L1正则后,通常可以产出稀疏解,但是在online模式下,因为只过一次样本的原因,每次梯度方向并不是朝着全局最优解方向去的,因此即使使用了L1正则,也很难产生稀疏解。FOBOS通过直接截断梯度在无精度损失的情况下增加了稀疏解,而RDA直接摒弃了梯度下降,对凸函数直接求解,RDA在优化速度和稀疏性方面都要比FOBOS好,但是精度方面却有所下降。关于FOBOS和RDA这两种方法的原理,这里不多赘述了,有兴趣的可以去看一位大佬写的资料:在线最优化求解。
先来看下FOBOS和RDA的公式:

  • FOBOS
    wt+1=arg min⁡w{gt⋅w+λ∥w∥1+12σ1:t∥w−wt∥22}(1)w_{t+1} = \argmin_{w}\{g_t \cdot w + \lambda\left\|w\right\|_1 + \frac{1}{2}\sigma_{1:t}\left\|w-w_t \right\|_2^2\} \tag{1} wt+1​=wargmin​{gt​⋅w+λ∥w∥1​+21​σ1:t​∥w−wt​∥22​}(1)
  • RDA
    wt+1=arg min⁡w{g1:t⋅w+tλ∥w∥1+12σ1:t∥w−0∥22}(2)w_{t+1} = \argmin_{w}\{g_{1:t} \cdot w + t\lambda\left\|w\right\|_1 + \frac{1}{2}\sigma_{1:t}\left\|w-0 \right\|_2^2\} \tag{2} wt+1​=wargmin​{g1:t​⋅w+tλ∥w∥1​+21​σ1:t​∥w−0∥22​}(2)

比较公式1和公式2能够发现,L1-FOBOS和L1-RDA的区别为(摘自在线最优化求解。):

  • FOBOS计算的是累加梯度及L1正则项只考虑当前模的贡献,而RDA采用了累加的方式
  • FOBOS第三项限制www的变化不能离上一次迭代过的解太远,而后者则限制www不能离0点太远。

而FTRL综合考虑了FOBOS和RDA对于正则项和www限制的区别,其公式为:
wt+1=arg min⁡w{g1:t⋅w+λ1∥w∥1+λ212∥w∥22+12∑s=1tσs∥w−ws∥22}(3)w_{t+1} = \argmin_{w}\{g_{1:t} \cdot w + \lambda_1\left\|w\right\|_1 + \lambda_2\frac{1}{2}\left\|w \right\|_2^2 + \frac{1}{2}\sum_{s=1}^t\sigma_s\left\|w-w_s \right\|_2^2\} \tag{3} wt+1​=wargmin​{g1:t​⋅w+λ1​∥w∥1​+λ2​21​∥w∥22​+21​s=1∑t​σs​∥w−ws​∥22​}(3)
公式3看起来很复杂,想要实现更新权重也比较困难,谷歌这篇论文对其重写了下(把公式3中最后一项展开):
wt+1=arg min⁡w{(g1:t−∑s=1t)⋅w+λ1∥w∥1+12(λ2+∑s=1tσs)∥w∥22+12∑s=1tσs∥ws∥22}=arg min⁡w{zt⋅w+λ1∥w∥1+12(λ2+∑s=1tσs)∥w∥22}(4)\begin{aligned} w_{t+1} &= \argmin_{w}\{(g_{1:t}-\sum_{s=1}^t )\cdot w + \lambda_1\left\|w\right\|_1 + \frac{1}{2}(\lambda_2 + \sum_{s=1}^t\sigma_s)\left\|w \right\|_2^2 + \frac{1}{2}\sum_{s=1}^t\sigma_s\left\|w_s \right\|_2^2\} \\ \tag{4} &=\argmin_w\{z_{t} \cdot w + \lambda_1\left\|w\right\|_1 + \frac{1}{2}(\lambda_2 + \sum_{s=1}^t\sigma_s)\left\|w \right\|_2^2\} \end{aligned} wt+1​​=wargmin​{(g1:t​−s=1∑t​)⋅w+λ1​∥w∥1​+21​(λ2​+s=1∑t​σs​)∥w∥22​+21​s=1∑t​σs​∥ws​∥22​}=wargmin​{zt​⋅w+λ1​∥w∥1​+21​(λ2​+s=1∑t​σs​)∥w∥22​}​(4)
上面公式4从第一步到第二步的推导为:12∑s=1tσs∥ws∥22\frac{1}{2}\sum_{s=1}^t\sigma_s\left\|w_s \right\|_2^221​∑s=1t​σs​∥ws​∥22​ 这一项相比较www其实就是个常数,所以直接扔掉对求导没影响。另外,另zt=g1:t−12∑s=1tσswsz_t =g_{1:t}- \frac{1}{2}\sum_{s=1}^t\sigma_sw_szt​=g1:t​−21​∑s=1t​σs​ws​。另外根据论文中的介绍,
针对各个特征拆解成NNN个独立的最小化问题:
min⁡wi∈R{zt,i⋅w+λ1∥w∥1+12(λ2+∑s=1tσs)∥w∥22}(5)\min_{w_i \in R}\{z_{t,i} \cdot w + \lambda_1\left\|w\right\|_1 + \frac{1}{2}(\lambda_2 + \sum_{s=1}^t\sigma_s)\left\|w \right\|_2^2\} \tag{5} wi​∈Rmin​{zt,i​⋅w+λ1​∥w∥1​+21​(λ2​+s=1∑t​σs​)∥w∥22​}(5)
因此,上式是一个典型的无约束最优化问题,直接一波求导并另导数等于0,我们可得下面的式子:
wt+1,i={0if∣zt,i∣<λ1−(λ2+∑s=1tσs)−1(zt,i−λ1sgn(zt,i))otherwise(6)w_{t+1,i}=\left\{\begin{matrix} \tag{6} 0 & if \left| z_{t,i} \right| < \lambda_1\\ -(\lambda_2 + \sum_{s=1}^t\sigma_s)^{-1}(z_{t,i} - \lambda_1sgn(z_{t,i})) & otherwise\\ \end{matrix}\right. wt+1,i​={0−(λ2​+∑s=1t​σs​)−1(zt,i​−λ1​sgn(zt,i​))​if∣zt,i​∣<λ1​otherwise​(6)
考虑到《二、Per-Coordinate Learning Rates》中公式x,设σ1:t=1nt\sigma_{1:t} = \frac{1}{n_t}σ1:t​=nt​1​,所以公式6中,∑s=1tσs=1nt,i=(β+(∑s=1tgs,i2)α)\sum_{s=1}^t\sigma_s= \frac{1}{n_{t,i}}=(\beta+\frac{\sqrt(\sum_{s=1}^tg_{s,i}^2)}{\alpha})∑s=1t​σs​=nt,i​1​=(β+α(​∑s=1t​gs,i2​)​)。
最后论文中也给出了伪代码:

paddlepaddle框架中也提供了该算法,参见文档:FtrlOptimizer

二、Per-Coordinate Learning Rates
在这这篇论文之前(2013年)通常优化器的学习率设置基本都是简单粗暴的设置一个全局固定的值,更高级一点的就是随着迭代加深,学习率做个衰减,比如:nt=1(t)n_t=\frac{1}{\sqrt(t)}nt​=(​t)1​。当然现在已经发展出了非常多的自适应学习率的优化算法,具体的可参见我的博客:深度学习中优化方法——momentum、Nesterov Momentum、AdaGrad、Adadelta、RMSprop、Adam。谷歌这篇论文提出了Per-Coordinate Learning Rates,其实就是对每个特征都有一个学习率,这个想法是很meaningful的,因为在真实场景里的样本中,每个特征出现的次数显然是不一样的,对于出现次数比较多的特征,说明它已经训练的比较充分了,学习到的参数已经比较置信了,这时候其实学习率就可以设置的比较小,防止跳出这种最优解。而对于出现次数比较少的特征,说明训练的不是很充分,参数也不置信,那么就需要比较大的学习率,尽快的寻找最优解。
直接来看谷歌这篇论文给出的公式吧:
nt,i=αβ+∑s=1tgs,i2(7)n_{t,i} = \frac{\alpha}{\beta + \sqrt{\sum_{s=1}^tg_{s,i}^2}} \tag{7} nt,i​=β+∑s=1t​gs,i2​​α​(7)
其中,gs,ig_{s,i}gs,i​表示第sss轮迭代时第iii个特征的梯度;nt,in_{t,i}nt,i​表示第t轮迭代时第iii个特征的学习率;α\alphaα和β\betaβ为两个超参数,β=1\beta=1β=1是一个比较好的取值,α\alphaα则需要根据具体的数据集和特征来决定。
从上面这个公式能够看出,第ttt轮迭代时第iii个特征的学习率由第iii个特征到目前第ttt为止所累积的梯度平方之和。所以,如果前面累积的梯度和越大,学习率则越小。
论文实验发现,相比家全局学习率,Per-Coordinate Learning Rates在AucLoss上下降了11.2%,在广告领域,如果能下降1%都是个很大的改进了。在我们自己平时业务中,发现使用Per-Coordinate Learning Rates在ACU上也有百分位的提升。

细心的同学能够发现,如果要实现这个公式,需要存储从第1次迭代到第ttt次的梯度,这无疑浪费存储(其实我个人感觉也还好),谷歌这篇文章给出了一个替代方法,比较节省内存,具体的方法我放到了 《七、Computing Learning Rates with Counts》里讲,大家可以直接跳到这一节。

下面【3-8】的方法都是为了节省内存。

三、Probabilistic Feature Inclusion
在大规模广告/推荐数据中,有很多特征出现的次数都很少,比如就出现1,2次,这些特征对于训练模型实际上是没啥帮助的,但反而这部分特征增加了模型体积,占用存储空间。因此,想要降低模型的尺寸,则需要减少模型中特征的数目。通常,我们离线时可以做个全局的统计,对于出现次数少于kkk次的特征取值直接删掉。但是对于online learning这种方法显然行不通,因此需要别的方法。谷歌这里使用了概率方法,即当遇到一个新的特征取值时,以一定的概率来动态决定某一个特征是否需要加入到模型中,论文给出了两种方法:

  • Poisson Inclusion:当遇到一个特征值时,如果它没在模型中出现过,那么以概率ppp将其加入到模型中。所以,出现次数较多的特征值,则有更大概率被加到模型中。
  • Bloom Filter Inclusion:使用布隆过滤器的方法,当一个特征值出现次数超过nnn次时,则加入到模型中。

实验表明(如下表),通过布隆过滤器调优之后,模型的 AUC 仅仅降低了 0.008%,但是内存的消耗却减少了 66% ,这是一个非常恐怖的数字。

四、Encoding Values with Fewer Bits
论文认为使用32位或者64位浮点数有点奢侈,谷歌这波人通过分析发现,在他们的场景下,模型大部分的参数的区间是在[-2,2]中的(这个地方不得不服,实践出真知,一切脱离业务场景的东西都是扯淡)。所以,为了节省内存,使用q2.13的encode方法。这个方法根据论文中的介绍是:1bit用来表示正负, 2bit用来表示整数部分,13bit用来表示小数部分,一共16bit。
实验表明,相对于64bit浮点数来说,使用q2.13浮点编码方法节省了75%的内存,而AucLoss几乎没有损失。
这个方法可能很难直接用到自己的业务场景下,但至少提供了一种压缩数据的思路。

五、Training Many Similar Models
这一块,在常见的业务中,我没怎么见过有这么操作的,所以这一块暂时不讲了。

六、A Single Value Structure
这一块和五一样,也不讲了,有兴趣的,或者等到需要用到的时候,再补充。

七、Computing Learning Rates with Counts
这里是和《二、Per-Coordinate Learning Rates》联系在一起的,目的是为了解决二中需要存储每个特征历史梯度浪费内存的问题,建议和第二节一起看。在这一节中,谷歌团队证明了不必存储历史梯度,只需要统计特征iii出现时正样本和负样本的个数即可。 假设特征iii出现时正样本和负样本的个数分别为PPP和NNN,则CTR,p=PN+Pp=\frac{P}{N+P}p=N+PP​,下面是公式证明:
∑gt,i2=∑positiveevents(1−pt)2+∑negativeeventspt2≈P(1−PN+P)2+N(PN+P)2=PNN+P(8)\begin{aligned} \sum{g_{t,i}^2} &= \sum_{positive \ events}{(1-p_t)}^2 + \sum_{negative \ events}{p_t}^2 \\ &\approx P(1-\frac{P}{N+P})^2 + N(\frac{P}{N+P})^2 \\ \tag{8} &=\frac{PN}{N+P} \end {aligned} ∑gt,i2​​=positive events∑​(1−pt​)2+negative events∑​pt​2≈P(1−N+PP​)2+N(N+PP​)2=N+PPN​​(8)

八、Subsampling Training Data
现在,对多数类样本进行下采样也是比较常见的了。例如在广告/推荐领域通常负样本(曝光未点击样本)的数量要远远大于正样本数量(点击样本),如果地主家机器资源充足,不在乎钱的话,并且能忍受长的训练时间,自然是用全部的样本进行训练得到的模型效果是最好的。但现在问题是:1. 长的训练时间无法忍受;2. 在动不动每天几亿甚至十几亿样本的情况下,但训练机器资源紧张。所以即使有一点点精读损失的情况下,如果能够大幅减少样本数量那也是很划算的。
在广告领域,通常来说,信息流广告的点击率也就2%-5%左右,开屏广告的点击率在10%-20%的样子,所以负样本数量远远大于正样本数量。这种情况下,显然正样本对我们是更有价值的,而负样本则可以采样减少数量,通常的做法基本都是:正样本全部保留,负样本以概率rrr进行随机采样。采样必然导致样本分布发生变化,所以一般都会对损失函数做一个修改,对采样的样本乘以一个权重www。这个权重会在bp时作用到梯度上。
这篇论文还从理论上证明了上面这种做法并没有改变原数据(采样前)的losslossloss损失,我这里写下证明过程:

  1. 假设正样本不做任何采样,负样本以概率rrr进行随机采样。
  2. 则正样本权重为1,采样得到的这部分负样本每个样本权重为wt=1rw_t = \frac{1}{r}wt​=r1​
  3. 令sts_tst​为每个样本被采样的概率,则显然sts_tst​为1(正样本时)或者rrr (负样本时)
  4. 对于LR模型的交叉熵损失函数:lt(wt)=−ytlogpt−(l−yt)log(1−pt)l_t(w_t)=-y_tlogp_t - (l-y_t)log(1 - p_t)lt​(wt​)=−yt​logpt​−(l−yt​)log(1−pt​),其中pt=δ(wt⋅xt)p_t=\delta(w_t \cdot x_t)pt​=δ(wt​⋅xt​)为样本的预测概率,则采样后的样本损失函数为:E[lt(wt)]=stwtlt(wt)+(1−st)0=st1stlt(wt)=lt(wt)E[l_t(w_t)] = s_tw_tl_t(w_t) + (1-s_t)0 = s_t\frac{1}{s_t}l_t(w_t) = l_t(w_t)E[lt​(wt​)]=st​wt​lt​(wt​)+(1−st​)0=st​st​1​lt​(wt​)=lt​(wt​)。这个推导过程稍微解释下,期望=被采样到的样本的损失+没被采样到的样本损失(被丢到的这部分样本损失自然为0)。能够看出与采样前的损失是等价的。

谷歌这篇论文也提到,他们通过实验验证这种方法是可行的,对模型精度影响很小。

九、一些失败的方法

这也是这篇论文的独到之处,不仅介绍了有用的trick,同样把一些尝试了但没效果的trick记录下来了,供后人参考。

论文里列举出的一些unsuccessful的方法如下:

  • feature hash
  • dropout
  • feature bagging
  • feature vector normalization

参考文献
[1]: McMahan B. Follow-the-regularized-leader and mirror descent: Equivalence theorems and l1 regularization[C] // Proceedings of the Fourteenth International Conference on Artificial Intelligence and Statistics. JMLR Workshop and Conference Proceedings, 2011: 525-533.
[2]: McMahan H B, Holt G, Sculley D, et al. Ad click prediction: a view from the trenches[C] // Proceedings of the 19th ACM SIGKDD international conference on Knowledge discovery and data mining. 2013: 1222-1230.
[3]: 冯扬,在线最优化求解

计算广告(一)【Ad Click Prediction: a View from the Trenches】工程实践视角下的广告点击率预估相关推荐

  1. 论文阅读:《Ad Click Prediction: a View from the Trenches》

    https://time.geekbang.org/column/article/370 广告是很多互联网公司的重要收入来源,比如 Google.Facebook.微软.阿里巴巴.百度.腾讯等.以 F ...

  2. #Paper Reading# Ad Click Prediction: a View from the Trenches

    论文题目: Ad Click Prediction: a View from the Trenches 论文地址: https://dl.acm.org/citation.cfm?id=2488200 ...

  3. 论文笔记:Ad Click Prediction: a View from the Trenches

    参考列表: https://blog.csdn.net/fangqingan_java/article/details/51020653 https://www.cnblogs.com/yaoyaoh ...

  4. 【每周一文】Ad Click Prediction: a View from the Trenches(2013)

    概述 该文是GoogleFTRL在点击率模型上的应用,从技术实现的角度介绍了在线学习算法FTRL的工程实现,并且给出一些内存优化.特征选择等工程细节.从此FTRL算法才大规模推广使用. 该笔记主要介绍 ...

  5. Ad Click Prediction: a View from the Trenches 阅读

    目录 摘要 关键词 1.引言 2.系统概述 3.在线学习与稀疏性 https://www.eecs.tufts.edu/~dsculley/papers/ad-click-prediction.pdf ...

  6. Ad Click Prediction: a View from the Trenches (2013)论文阅读

    文章链接: https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/41159.pdf 补 ...

  7. 【论文】Ad Click Prediction: a View from the Trenches

    作者主要展示了CTR预估系统中最近的研究和实验.包括了improvements in the context of traditional supervised learning,这是基于FTRL-P ...

  8. 效果广告点击率预估实践:在线学习

    效果广告点击率预估实践:在线学习 原创 2016-03-24 腾讯大数据 腾讯大数据 1.引言 技术钻研如逆水行舟,不进则退.公司的广告业务发展非常迅猛,有目共睹,激烈的外部竞争和客户越来越高的期望, ...

  9. 广告点击率预估中的特征选择

    一.互联网广告特征project 博文<互联网广告综述之点击率系统>论述了互联网广告的点击率系统,能够看到,当中的logistic regression模型是比較简单并且有用的,其训练方法 ...

最新文章

  1. 正则表达式之IP地址检验
  2. jQuery获取元素内容
  3. 密码学系列之:加密货币中的scrypt算法
  4. [BZOJ2655] calc
  5. 基于JAVA+SpringMVC+Mybatis+MYSQL的汽车维修管理平台
  6. 1.2.1 计算机网络的分层结构、协议、服务和接口(转载)
  7. html 中的特殊字符转义,html拼接字符串中特殊字符(‘ “ 等的转义问题)
  8. 创新企业如何“跨越鸿沟”?
  9. Windows: VC编程操作注册表键值
  10. 身份证实名认证API接口介绍
  11. 孤荷凌寒自学python第二十一天初识python的类
  12. vue中transition动画实现淡入淡出
  13. [高数][高昆轮][高等数学上][第一章-函数与极限]10.闭区间上连续函数的性质
  14. Teach repeat replan 安装中遇到的问题记录
  15. 时间戳计算获取今天起始本周每天起止本月每天起止本周起止本月每周起始时间本年每月起止时间本年每个季度的起止时间
  16. 用python编写一个篮球计分系统_毕业设计(3)基于MicroPython的篮球计时计分器模型的设计与实现...
  17. 【开发必备】快来收藏!涵盖日常开发中所需要的60多个正则验证!!
  18. vs2017或vs2019或vs2022安装中Microsoft.VisualStudio.MinShell.Msi出错的问题
  19. 熊掌号渠道购买 熊掌号账户类型选择注意事项
  20. flowci php,我和flow.ci的第一次亲密接触

热门文章

  1. mysql限制root用户指定ip登录
  2. 化妆品电商供应链系统解决方案:打造智慧型化妆品wms仓储管理系统
  3. 做网络必须知道的几个定律
  4. HBase 在爱奇艺的应用实践
  5. 计算机中cmd的指令如何停下,怎么样用CMD命令实现电脑倒计时和快捷键关机操作...
  6. 落月星辰:做自己的孤勇者,也做鸡蛋的终结者
  7. 如何利用MuLogin使用tinder软件?
  8. VSCode中Emmet使用
  9. 男人的腰:理性之下欲望之上
  10. hdu 2717 Catch That Cow