FM学习记录

摘要:

本文将要介绍一个在推荐、CTR中很常见的模型,FM(Factorization Machines)。

前言

我们首先回忆一下在推荐或者CTR预估的场景下我们经常用的模型是LR。具体来说我们熟悉的LR即如(0)式。
(0) y ^ = w 1 x 1 + w 2 x 2 + . . . w n x n = i = 1 n w i x i
接触过CTR或者推荐场景的可能很清楚,在这些场景下,我们通常会做一些交叉特征(cross feature)来增强LR的非线性以加强线性模型的表达能力。这种做法可以认为是在特征工程上下功夫。

而我们能否解放特征工程。从模型上下功夫来解决特征交叉的问题呢?
其实可以,比如说,我对(0)进行一点点修改,如(1)式子。
(1) y ^ = i = 1 n w i x i + i = 1 n j = i + 1 n w i j x i x j
非常的直观,我们直接在线性模型的基础上增加多各个特征的乘积项。其表达的含义就是两个特征之间做交叉的意思。(1)式增加了 n ( n + 1 ) 2 个参数。通常来说,会用到这种模型下的特征维度 n 都非常的大。所以这种如此暴力的方法(从式子(0)到式子(1)的变化)存在一定优化空间。

其实大量参数并非这种方法的最大问题,最大的问题在于由于推荐和CTR这两种场景下的特征非常的稀疏(sparse data),这会导致有大量的权重 w i j 将得不到训练。可以直观上理解:当且仅当 x i x j 同时不为0时,权重 w i j 在进行梯度下降时才会更新。否则每次梯度下降会保持不变。

为了解决这两个问题,第一个缩减参数的规模,第二个让交叉项的权重能够更好的学习,Steffen Rendle在提出了FM。

FM模型

上面提到FM是为了解决直接采用用多项式即式子(1)带来的几个问题所提出的模型。
那么FM到底是如何解决的呢?这里其实可以从多个角度来理解。这里采用一种个人比较理解的角度来说明。

假设我们给每个特征 x i 学习一个长度为 k 的向量表达 v i 。即向量 v i 为特征 x i k 维表达。
那么我们在做特征组合的时候,比如组合 x i x j 时,我们可以把学习的权重转化为学习 v i v j 的向量点积的结果, v i , v j ,也就是说(1)式改为:
(2) y ^ = i = 1 n w i x i + i = 1 n j = i + 1 n v i , v j x i x j

其中: v i , v j = f = 1 k v i , f v j , f

我们这样做之后能够改善上面所提到部分权重得到不学习的问题。
这里我举一个例子。


比如我们有一个训练集,训练集中只有三个特征。其中一条样本如下
() x 1 = 1 , x 2 = 0 , x 3 = 1
这个时候,我们如果采用式子(1)来学习时,我们需要学习其中的三个参数 w 12 w 13 w 23
由于:仅有 x 1 x 3 = 1 不为0,故仅有 w 13 这个权重在梯度下降时得到了学习。那么在进行预测的时候,我们就利用了根本没有经过学习的、非常不准确的参数 w 12 w 23

而如果我们采用式子(2)来学习,我们有如下(方便起见,向量长度为 k = 1

虽然我们只有 x 1 x 3 = 1 不为0,但是在梯度下降的时候, v 1 , v 3 都得到了学习。那么这个时候,我们在预测的时候,尽管 v 2 没有得到学习。但是由于 v 1 , v 2 v 2 , v 3
中包含了我们学习过的 v 1 , v 3 所以从模型最终的效果上来看,尽管部分交叉特征从来出现过,但是由于其中包含有已经学习过的权重,所以还是能够使得这些交叉特征的权重是一个相对合理的值,而不是一个从未经过训练的值。


上面的权重的学习得到了改善,另外在进行预测时候的复杂度,其实也从 O ( n 2 ) 降到了线性 O ( n k )
整个FM的复杂度其实来源于交叉特征部分。直观上看复杂度为 O ( n 2 k ) ,但是我们其实可以做一个简单的数学推导:
(这个推导直接摘论文里面的了,敲公式太累了- -!!!)
这里写图片描述

从式子(5)中可以看到,最外层的求和要计算 O ( k ) ,里面一共需要计算 O ( n ) 次。所以总的复杂度为 O ( n k ) 。所以整个复杂度变成了线性。

关于FM的训练

那么,我们对FM模型有了一定的认识之后,我们下一步需要考虑的就是如何进行训练,或者说如何求出上面所涉及到的一些参数。这里我们把式子(5)的推导结果带入式子(2)可以得到:

(3) y ^ = i = 1 n w i x i + 1 2 f = 1 k { ( i = 1 n v i , f x i ) 2 i = 1 n v i , f 2 x i 2 }

对于分类任务,一般我们可以选择logloss作为我们的损失函数。那么对于logloss我们有(对于第 m 条样本):
(6) L ( y ( m ) , y ( m ) ^ ) = { y ( m ) L n ( p ( m ) ) + ( 1 y ( m ) ) L n ( 1 p ( m ) ) }
其中: p ( m ) = 1 1 + e y ( m ) ^

把(3)式中的所有参数统一记为 θ (6)式对 θ 求导有:
(7) L ( y ( m ) , y ( m ) ^ ) θ = ( y ( m ) p ( m ) ) y ( m ) ^ θ

最后对于 (8) y ( m ) ^ θ = { 1 θ = w 0 x i θ = w i x i j = 1 n v j , f x j v i , f x i 2 θ = v i , f

有了每个参数的梯度之后,就可以利用SGD来对各个参数进行训练了。
可以看到,对于训练过程其复杂度也是线性的 O ( n k )

FM与多项式的SVM对比

在FM的论文里有FM和SVM的一个简单的对比,其实总结起来。主要想表达就是,当SVM的核函数选择多项式核时即 d = 2 的情况,SVM为下式:
这里写图片描述
可以看到这个式子大体上就和式子(1)类似。所以对比FM和多项式核下的SVM其实就是文中一开始讨论的内容。

总结

到这里,我们可以稍微整理一下前面的内容。其实我们无非做了以下几点事情。
首先,我们阐述通过做特征工程来使得LR非线性表达能力增强的想法。后面,我们希望通过模型本身来做特征的交叉,阐述了直接利用二阶多项式的方法所带来的问题。最后,我们利用FM来解决上述所带来的一些问题。

所以FM其实很好的解决了两个问题
第一,将需要交叉特征部分的参数从 n ( n + 1 ) 2 个降到了 n k 个。
第二,改善了交叉特征部分的权重的学习。

猜你喜欢

转载自blog.csdn.net/qq_22238533/article/details/79916265
FM