点击率预测算法:FTRL

版权声明:本文为博主原创文章,转载请注明来自http://blog.csdn.net/jediael_lu/ https://blog.csdn.net/jediael_lu/article/details/77772542

FTRL代码实现请参考:https://github.com/lujinhong/ftrl

1、逻辑回归

FTRL本质上是逻辑回归的一个变种,因此先简单介绍一下逻辑回归的内容。

1.1 sigmoid函数

由于二分类结果是1或者0,这与数学的阶跃函数很类似,但是阶跃函数在x=0的位置会发生突变,这个突变在数学上很难处理。所以一般使用sigmoid函数来拟合:

g(z)=11+ez(1)

具体应用到逻辑回归算法中:

z=ω0+ω1x1+ω2x2+......+ωnxn=i=0nωixiωTX(2)

其中 xi 表示样本属性(对于我们而言,就是标签IP)的值, ωi 表示这个属性对应的系数(也就是算法需要计算的内容)。注意这里将 x0 ω0 也代入了上述公式,其中前者恒为1。于是问题就变成了在训练样本中,已知属性x与最终分类结果y(1或者0)时,如何求得这些系数 ωi ,使得损失最小。

1.2 极大似然估计MLE与损失函数

在机器学习理论中,损失函数(loss function)是用来衡量模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,损失函数越小,模型越优(还需考虑过拟合等问题)。损失函数是经验风险函数的核心部分,也是结构风险函数重要组成部分。模型的结构风险函数包括了经验风险项和正则项,通常可以表示成如下式子

ω=argminω1mi=1mL(yi,f(xi;ω))+λ Φ(ω)(3)

其中m表示样本的数量。对于逻辑回归,其loss function是log损失,这可以通过极大似然估计进行推导得到。

首先,给定一个样本 x ,可以使用一个线性函数对自变量进行线性组合,即上述的(2)式子:

z=ω0+ω1x1+ω2x2+......+ωnxn=i=0nωixiωTX(4)

根据sigmoid函数,我们可以得出预测函数的表达式为:

hω(x)=g(ωTx)=11+eωTx(5)

上式表示 y=1 的预测函数为 hω(x) 。在这里,假设因变量 y 服从伯努利分布,取值为 0 1 ,那么可以得到下列两个式子:
p(y=1|x)=hω(x)(6)

p(y=0|x)=1hω(x)(7)

而对于上面的两个表达式,通过观察,我们发现,可以将其合并为以下表达式:
p(y|x)=hω(x)y(1hω(x))1y(8)

根据上面的式子,给定一定的样本之后,我们可以构造出似然函数,然后可以使用极大似然估计MLE的思想来求解参数。但是,为了满足最小化风险理论,我们可以将MLE的思想转化为最小化风险化理论,最大化似然函数其实就等价于最小化负的似然函数。对于MLE,就是利用已知的样本分布,找到最有可能(即最大概率)导致这种分布的参数值;或者说是什么样的参数才能使我们观测到目前这组数据的概率最大。使用MLE推导LR的loss function的过程如下。
首先,根据上面的假设,写出相应的极大似然函数(假定有 m 个样本):
L(ω)=i=1mp(yi|xi;ω)=i=1mhω(xi)yi(1hω(xi)1yi(9)

上述式子中的 ω xi 均为向量,并未显示其转置。

直接对上面的式子求导会不方便,因此,为了便于计算,我们可以对似然函数取对数,经过化简可以得到下式的推导结果:

logL(ω)=i=1mlog[(hω(xi)yi(1hω(xi))1yi)]=i=1m[yiloghω(xi)+(1yi)log(1hω(xi))](10)

因此,损失函数可以通过最小化负的似然函数得到,即下式:

J(ω)=1mi=1m[yiloghω(xi)+(1yi)log(1hω(xi)](11)

在周志华版的机器学习中,将sigmiod函数代入 hω(xi) ,并使用ln代替log,上述公式表示为:

J(ω)=1mi=1m[yilnhω(xi)+(1yi)ln(1hω(xi)]=1mi=1m[yiln11+eωxi+(1yi)lneωxi1+eωxi]=1mi=1m[ln11+eωxi+yiln1eωxi]=1mi=1m[yiwxi+ln(1+eωxi)](12)

在某些资料上,还有另一种损失函数的表达形式,但本质是一样的,如下【推导见下面1.4】:

J(ω)=1mi=1mlog(1+eyiωx)(13)

1.3 梯度下降

这里就以梯度下降为例对逻辑回归进行求解,其迭代公式的推导过程如下:

J(ω)ωj=1mim[yi(1hω(xi))(xi,j)+(1yi)hω(xi)(xi,j)]=1mim(yixi,j+hω(xi)xi,j)=1mim(hω(xi)yi)xi,j(12)

上述中 xi,j 表示第 i 个样本的第 j 个属性的取值。
于是, ω 的更新方式为:

ωj+1=ωjαi=1m(hω(xiyi)xx,j(13)

对于随机梯度下降,每次只取一个样本,则 ω 的更新方式为:

ωj+1=ωjα(hω(xy)xj(13)

其中 x 为这个样本的特征值, y 为这个样本的真实值, xj 为这个样本第 j 个属性的值。

这使用周志华版的损失函数更容易得出这个结论。

1.4 另一种形式的损失函数及其梯度

与上面相同,根据sigmoid函数,我们可以得出预测函数的表达式为:

hω(x)=g(ωTx)=11+eωTx(5)

上式表示 y=1 的预测函数为 hω(x)
但与上面不同,我们假设样本的分布为{-1,1},则
p(y=1|x)=hω(x)(14)

p(y=1|x)=1hω(x)(15)

对于sigmoid函数,有以下特性(简单推导一下就可以得到):
h(x)=1h(x)(14)

于是(14)(15)式可以表示为:

p(y|x)=hω(yx)(16)

同样,我们使用MLE作估计,

L(ω)=i=1mp(yi|xi;ω)=i=1mhω(yixi)=i=1m11+eyiwxi(17)

对上式取对数及负值,得到损失为:

logL(ω)=logi=1mp(yi|xi;ω)=i=1mlogp(yi|xi;ω)=i=1mlog11+eyiwxi=i=1mlog(1+eyiwxi)(18)

即对于每一个样本,损失函数为:
L(ω)=log(1+eyiwxi)(19)

对上式求梯度,容易得到:

J(ω)ωj=yixi1+eyiωxi(20)

2、FOBOS与RDA

2.1 FOBOS基本原理

FOBOS算法由John Duchi和Yoram Singer提出,是梯度下降的一个变种。
与梯度下降不同,它将权重的更新分为2个步骤:

Wt+12=WtηtGt

Wt+1=argmin{12WWt+122+η(t+12)ψ(W)}

从上面的2个步骤可以看出:
第一个步骤是一个标准的梯度下降。
第二个步骤是对梯度下降的结果进行微调。这里可以分为2部分:(1)前半部分保证了微调发生在第一个步骤结果(取梯度下降结果)的附近。(2)后半部分用于处理正则化,产生稀疏性。

* 根据次梯度理论的推断,可以得出 W(t+1) 不仅仅与迭代前的状态 Wt 有关,而且与迭代后的$$相关*

2.2 L1-FOBOS

FOBOS在L1正则化条件下,特征权重的更新方式为:(推导过程暂略)

ωt+1,i=sgn(ωt,iηtgt,i)max{0,|ωt,iηtgt,i|ηt+12λ}

其中 gt,i 为梯度在维度i上的取值

2.3 RDA基本原理

简单截断、TG、FOBOS都是建立在SGD基础上的一个变种,属于梯度下降类型的方法,这类方法的精度比较高,同时也能得到一定的稀疏性。而RDA是从另一个方面来求解,它的精度比FOBOS等略差,但它更有效的提升了稀疏性。

在RDA中,特征权重的更新策略为:

Wt+1=argmin{1tr=1t<Gr,W>+ψ(W)+βtth(W)}

其中 <Gr,W> 表示梯度 Gr 对W的积分平均值(积分中值); ψ(W) 为正则项; h(W) 为一个辅助的严格的凸函数; βt|t1 是一个非负且非自减序列。

2.4 L1-RDA

在L1正则化条件下,RDA的各个维度的权重更新方式为:

ωt+1,i={0,(tr(gt,iλsgn(gt,i)),if |gt,i|<λotherwise

亦即当某个维度上的累积梯度平均值的绝对值 |gt,i| 小于阈值 λ 时,该维度权重被置为0。

3、FTRL

理论及实验均证明,L1-FOBOS这类基于梯度下降的算法有比较高的精度,但L1-RDA却能在损失一定精度的情况下产生更好的稀疏性。
把这二者的优点结合成一个算法,这就是FTRL算法的来源。

3.1 从L1-FOBOS和L1-RDA推导FTRL

我们令 ηt+12=ηt=Θ(1t) 是一个非增正序列,同时代入L1正则项,得到L1-FOBOS的形式如下:

Wt+12=WtηtGt

Wt+1=argmin{12WWt+122+ηtλW1}

将这2个公式合并到一起,得到L1-FOBOS的形式如下:

Wt+1=argmin{12WWt+ηtGt2+ηtλW1}

将上式分解为N个独立的维度进行最优化求解:

wi=argmin{12wiwt,i+ηtgt,i2+ηtλ|wt,i|1}=argmin{12(wiwt,i)2+12(ηtgt,i)2+wiηtgt,iwt,iηtgt,i+ηtλ|wi|}=argmin{wigt,i+λ|wi|+12ηt(wiwt,i)2+|ηt2g2t,iwt,igt,i|}

  • 上述推导的最后一步是通过除以 ηt 得到的。
    由于上式中的最后一项 |ηt2g2t,iwt,igt,i| 是一个与 wi 无关的量,因此上式可简化为:
    wi=argmin{wigt,i+λ|wi|+12ηt(wiwt,i)2}

    把N个独立优化的维度重新合并,L1-FOBOS可写成以下形式:
    Wt+1=argmin{GtW+λW1+12ηtWWt22}

另一方面,L1-RDA可以表达为:

Wt+1=argmin{G(1:t)W+tλW1+12ηtW022}

其中 G(1:t)=s=1tGs
我们令 σs=1ηs1ηs1 ,可以得到 σ(1:t)=1ηt 。那么L1-FOBOS与L1-RDA可以写为以下格式:
Wt+1=argmin{GtW+λW1+12σ(1:t)WWt22}

Wt+1=argmin{G(1:t)W+tλW1+12σ(1:t)W022}

比较以上2式的区别:
* (1)L1-FOBOS考虑的是当前梯度的影响,L1-RDA则考虑了累积影响。
* (2)L1-FOBOS限制 Wt+1 不能离 Wt 太远,而L1-RDA的W则不能离0太远,因此后者更容易产生稀疏性。

3.2 FTRL权重更新的最终形式

在google2010公布的理论文章中并没有使用L2正则项,但在2013年公布工程实施方案时引入了L2。
因此,综合上述的L1-FOBOS及L1-RDA,FTRL算法的权重更新方式为:

Wt+1=argmin{G(1:t)W+λ1W1+λ2W22+12s=1t(σsWWs22)}

将上式展开,得到
Wt+1=argmin{(G(1:t)s=1tσsWs)W+λ1W1+12(λ2+s=1tσs)W2+12s=1tσsWs22}

由于上式的最后一项相对于W来说是一个常数,同时令 Zt=G(1:t)t(s=1)σsWs ,上式可表示为:
Wt+1=argmin{ZtW+λ1W1+12(λ2+s=1tσs)W2}

各个维度可以独立表示为:
wi+1=argmin{zt,iwi+λ1|wi|+12(λ2+s=1tσs)w2i}

使用与L1-FOBOS相同的分析方法可以得到:

ωt+1,i={0,(λ2+ts=1σs)1(zt,isgn(zt,i)λ1),if |zi|<λ1otherwise

根据上面的定义:

σ(1:t)=s=1tσs=1ηt

我们使用下面介绍的学习率,以及令 ni=g2i ,则可以得到FTRL的最终形式:

ωi={0,(β+nIα+λ2)1(zisgn(zi)λ1),if |zi|<λ1otherwise

3.3 学习率

1、per-coordinate learning rate
在FTRL中,学习率的定义如下:

ηt,i=αβ+ts=1g2s,i

其中 αβ 是自定义的参数。

在一般梯度下降算法中,使用的是一个全局的学习率策略: ηt=1t 。这个策略保证了学习率是一个正的非增序列,这个值对于每一个特征都是一样的。

考虑一个极端的情况,我们有多个稀疏特征,其中一个特征 x1 出现非常频繁,而另一个特征 x2 很少出现。比如第一个样本, x1 x2 同时出现了,但接下来的99个样本都只出现了 x1 ,然后第100个样本 x2 又出来了,由于此时的学习率为 1100 ,远小于第一个样的影响了。也就是说假如第一个样本是正样本,第10个样本是负样本,此时由于学习率的不同,模型会认为 x2 会是一个有用的正相关的特征,即 ω>0 。但事实上,这个特征只出现了2次,而且一正一负,因此这应该是一个无用的特征,即 ω0

在FTRL中,我们会使用一个特征的累积梯度,由于中间的99个数据没有这个特征,因此其对应的梯度为0,因此第二次的负样本对应的学习率只是略小于第一个正样本。

3.4 工程实现计算过程

3.4.1 一些定义

对于每一个样本,我们计算以下数值。

(1) pt
使用当前的 ω 代入sigmoid函数得出的预测值,即:

p=11+e(ni=1ωixi)

(2) gi
损失函数在某一个维度上的梯度,对于逻辑回归而言:

gi=(py)xi

其中y为当前样本的实际值,即0或者1。

(3) ni
这是该维度梯度 g2i 的累积值,即:

ni=ni+g2i

(4) ηi
这是该维度的学习率,它与累积梯度有关。定义为:

ηi=αβ+ts=1(gsi)2=αβ+ni

其中 αβ 为用户定义的2个参数。

(5) σi
σi 是一个中间计算值,没有实际含义,其定义为:

σi=1ηt,i1ηt1,i=1α(ni+g2ini)

(6) zi
zi 也是一个辅助计算的中间值,它的定义为:

zt,i=g(1:t)s=1tσs,iωs,i

于是 zi 的更新为:
ztzt1=gtσtωt

即:
zi=zi+gtσiωi

3.4.2 FTRL算法

(1)设定以下4个输入参数,这些参数根据经验而定,可以参考以下数据:

α=0.1,β=1,λ1=1,λ2=1

(2)初始化以下数值:

zi=0,ni=0

(3)对于每一个样本的所带的每一个维度,更新 ω

ωi={0,(β+nIα+λ2)1(zisgn(zi)λ1),if |zi|<λ1otherwise

(4)使用上面更新后的 ω ,预测这个样本的值,即代入sigmoid函数计算 pt

p=11+e(ni=1ωixi)

(5)对于每一个样本每一个维度,更新 gi,σi,zi,ni ,即上面所说的:

gi=(py)xi

σi=1α(ni+g2ini)

zi=zi+gtσiωi

ni=ni+g2i

4、FTRL的工程应用

这里只列出了google提供的一些建议,我们自身的工程应用并不包含在内。
(1)减少样本的数量
* Poisson Inclusion:以p的概率接受样本
* Bloom Filter Inclusion:只有当特征出现次数达到一定数量后,特征才会被加入模型

(2)使用更少的位来进行浮点数编码
一般而言,特征对应的 ω 在(-2,2)之间,所以我们可以将32,或者64位的浮点数编码规则改为q2.13编码方式,即2位整数,1位小数点,13位小数。

(3)多个类似的模型
把多个同类型/相似的模型放在一起保存,可以不需要记录多个key,只需要记录一次Key,以及各个模型中的 ω 。这可以节省内存、带宽、CPU、存储。

(4)只保存一个模型
在上面的基础上更进一步,所有模型共用一份 ω ,以及以一个bit来记录本模型有哪些特征。当模型更新某个 ω 后,取它与之前那个值的平均值。
与共用一个模型对比,好处是记录了这个模型有哪些有效特征,共用模型就无法区分了。

(5)近似计算学习率
只使用正样本P与负样本数据N来近似估计梯度的平方和,前提是假设特征有类似的分布。

g2i=PNP+N

(6)减少负样本数量
减少负样本数量,然后在训练时弥补其损失。

再说一次,代码在:https://github.com/lujinhong/ftrl

猜你喜欢

转载自blog.csdn.net/jediael_lu/article/details/77772542