推荐算法之—FM

Python023

推荐算法之—FM,第1张

FM即Factor Machine,因子分解机

1)、特征组合是许多机器学习建模过程中遇到的问题,如果对特征直接建模,很有可能忽略掉特征与特征之间的关联信息,一次可以通过构建新的交叉特征这一特征组合方式提高模型的效果。

2)、高维的稀疏矩阵是实际工程中常见的问题,并且直接导致计算量过大,特征权值更新缓慢。试想一个10000 100的表,每一列都有8中元素,经过one-hot编码之后,会产生一个10000 800的表。因此表中每一元素只有100个值为1,700个值为0

而FM的优势就在于对这两方面问题的处理。首先是特征组合,通过两两特征组合,引入交叉项特征(二阶特征),提高模型得分;其次是高维灾难,通过引入隐向量(对参数矩阵进行分解),完成特征参数的估计

我们已经知道FM可以解决特征组合以及高维稀疏矩阵问题,而实际业务场景中,电商、豆瓣等推荐系统的场景是使用最广泛的领域,打个比方,小王只在豆瓣上浏览过20部电影,而豆瓣上面有20000部电影,如果构建一个基于小王的电影矩阵,毫无疑问,里面讲有199980个元素全为0.而类似这样的问题就可以通过FM来解决

在展示FM算法之前,我们先回顾一下最常见的线性表达式:

其中[图片上传失败W0为初始权重值,或者理解为偏置项,Wi为每个特征 xi 对应的权重值,可以看到,这种线性表达式只描述了每个特征和输出的关系。

FM的表达式如下,可观察到,只是在线性表达式后面加入了新的交叉项特征及对应的权值。

1)寻找交叉项

FM表达式的求解核心在于对交叉项的求解。下面是很多人用来求解交叉项的展开式,对于第一次接触FM算法的人来说可能会有疑惑,不知道公式怎么展开的,接下来笔者会手动推导一遍。

设有3个变量(特征)x1,x2,x3,每个特征的隐变量分别为v1=(1,2,3)、v2=(4,5,6)、v3=(1,2,1)即:

设交叉项所组成的权矩阵W为对称矩阵,之所以设为对称矩阵是因为对称矩阵可以用向量乘以向量的转置代替的性质。

那么W=VVT ,即

所以:

2)交叉项权值转换

对交叉项有了基本了解后,下面将进行公式的分解,还是以n=3为例,

3)交叉项展开式

上面的例子是对3个特征做的交叉项推导,因此对具有n个特征,FM的交叉项公式就可推广为:

我们还可以进一步分解:

所以FM算法的交叉项最终展开为:

利用梯度下降法,通过求损失函数对特征(输入项)的导数计算出梯度,从而更新权值。设m为样本个数θ为权值。

如果是回归问题,损失函数一般是均方误差(MSE)即,最小二乘:

所以回归问题的损失函数对权值的梯度(导数)为:

其中,σ表示是阶跃函数sigmoid。

所以分类问题的损失函数对权值的梯度(导数)为:

        网上关于FM算法的介绍很多,我写这篇文章的目的是详细地推一遍FM算法中交叉组合项的简化计算(其是就是验证一下为什么公式中的每个等号是成立的,而不是探究这种思路是怎么得出的),方便自己以后查看,也可以帮助一下对这个算法有些许疑惑的朋友。本文主要参考了 https://www.cnblogs.com/AndyJee/p/7879765.html 这篇文章,FM算法的原文出处则是在这里S. Rendle, "Factorization Machines,"  2010 IEEE International Conference on Data Mining , Sydney, NSW, 2010, pp. 995-1000, doi: 10.1109/ICDM.2010.127.

        FM即因式分解机。在传统的线性模型中,每个特征都是独立的,如果需要考虑特征与特征之间的交互作用,可能需要人工对特征进行交叉组合;非线性SVM可以对特征进行Kernel映射,但是在特征高度稀疏的情况下,并不能很好地进行学习;现在也有很多分解模型如矩阵分解MF、SVD++等,这些模型可以学习到特征之间的交互隐藏关系,但基本上每个模型都只适用于特定的输入和场景。为此,在高度稀疏的数据场景如推荐系统下,FM出现了。

        二元交叉的FM目标函数如下:

其中,

另外, 是 维向量,即矩阵 的某一行; 运算符则表示两个 维向量的点积 :

公式(1)中,前两项就是常规的线性模型,最后一项就是FM提出的交叉组合特征。

        交叉组合项乍一看复杂度是 ,但经过一定的化简后,可以将复杂度降低为 。下面我会将完整的公式先放出来,然后逐步分析。

上面这个公式用的是latex的split模块,打不了tag,就按照四个等号的顺序从上到下1-4好了。

        先是第1步的推导,这一步可以先不管 这一项,因此在推导过程中我就省略了。令 , , , ,那么要验证的就是 。首先把 拆开,得到:

然后把 拆开,得到:

所以 ,而

进行简单的移项后,即可得到 。

        下面的2-4步如果仔细观察就会发现,只是把向量 拆开了而已,我写这篇文章之前是没想到这一点的...那这篇文章到这里就结束了,告辞。

        更新一波,在用梯度下降更新权值时,分别对三个权重的偏导是这样的: