zoukankan      html  css  js  c++  java
  • 聊聊因子分解机模型的基本形式和一些变化

    因子分解机(Factorization Machine, 简称FM)是一种不错的CTR预估模型,也是我们现在在使用的广告点击率预估模型,比起著名的Logistic Regression, FM能够把握一些组合的高阶特征,因此拥有更强的表现力。

    在做点击率预估时,我们的特征往往来自于用户(user)、广告(item)和上下文环境(context),在线性模型中,这些特征不进行组合的话,就会发生一个很尴尬的情况,因为:

    $$score = f(w_{user} * x_{user} + w_{item} * x_{item} + w_{contex} * x_{contex})$$

    所以,对所有用户--我们将得到相同的排序。

    因此我们需要引入一些组合特征作为输入模型,然而仅二阶特征组合的可能性就是原始特征的平方之多,但是由于很多特征其实是相互独立的,他们的组合并没有什么价值。FM就是一种能够自动把握一些高阶特征的点击率预估模型,可以自动帮助使用者选择合适的高阶输入。

    我们先写出带有所有二阶组合特征的目标函数,其中矩阵W中有n^2个参数,求解非常复杂:

    $$y(x) = w_0 + sum_{i=1}^{n} w_i x_i + sum_{i=1}^{n} sum_{j=i+1}^{n} w_{ij} x_i x_j$$

    我们都知道在矩阵分解的协同过滤中中,我们认为每个用户可以表示成一个K维的特征向量$u_k$,每个物品也能表示成一个高维向量$i_k$,这样用户与物品的相关性就可以用两个向量的点击表示,所有用户与所有物品的相关性就可以用两个矩阵相乘的形式表示出来了。

    FM的模型参考了矩阵分解的思想,认为每个特征 $x_i$都可以用一个K维的特征向量$v_i$表示,那么所有特征之前的相关性就也就可以用两个矩阵的相乘进行表示了,模型表示如下:

    其中矩阵W中代表了特征的特征向量的內积,既:$w_{ij}=v_i v_j$,所以,公式可以改写为:

    $$y(x) = w_0 + sum_{i=1}^{n} w_i x_i + sum_{i=1}^{n} sum_{j=i+1}^{n} v_{i} v_{j} x_i x_j$$

    也就是:

    $$y(x) = w_0 + sum_{i=1}^{n} w_i x_i + sum_{i=1}^{n} sum_{j=i+1}^{n} sum_{h=i}^{k} v_{i,h} v_{j,h} x_i x_j$$

    可以看出,W中的参数现在只有nk个了,因为一般有k<<n,所以FM大大降低的目标函数的复杂度。推导可得梯度公式:

    $δy/δw_{0}=1$

    $δy/δw_{i}=x_{i},i=1...n$

    $δy/δv_{i,k}=x_{i}sum{j eq i} v_{j,k}x_{j}$

    FM的优化可以用SGD来做,不过这里推荐带动量(momentum)的min-batch SGD算法,试验中比普通的SGD效果似乎更好。带momentum的SGD模拟了物品运动中的惯性。

    在传统的SGD中:$x_{t+1}=x_t+Δx_t,Δx_t=-ŋg_t$ ,其中 $g_t$代表了梯度。而在momentum的SGD中:$Δx_t=px_{t-1}-ŋg_t$。

    不过比起LR, FM有一个缺点--目标函数是非凸的,虽然针对这个缺点也有一些研究比如一些凸函数形式的FM,不过在实践中似乎这并不是一个很严重的问题,合适的初始化方式和优化方法一般是能够给出一个可以接受的解的。

    FM的另外一个缺点是有点耗费内存,对于每个特征都要用一个K维的向量表示导致参数数量是LR的K倍,这方面也是有一些研究的,比如李沐针对这个问题提出的DiFacto就是一个很好的能够降低内存消耗的优化方案。

    最后,还有一种著名的策略是FFM模型,FFM模型被称为FM的升级版,把同一类的特征(比如一些用01向量编码的的离散特征)归到一个field里去,然后要求每个特征在每个field下都有一个不同的K维表示方式,这一下把参数的数量从K变成了FK(F是field的数量),模型复杂度变的更高了。不过这样做的效果确实不错。

  • 相关阅读:
    window系统中,解决Pycharm 文件更改目录后,执行路径未更新问题(转)
    yum安装软件报错–skip-broken(卸载的时候一直报错:未安装软件包)
    selenium之Chrome浏览器与chromedriver对应关系和下载
    Python 第三方库 批量下载安装包,离线批量安装Python第三方库
    UIpath 循环读取IMAP邮件,并保存附件
    UIpath 中如何使用 正则表达式
    用python实现队列,堆栈
    python-反射
    Python基础-父类对子类的约束
    Python基础-类的继承顺序
  • 原文地址:https://www.cnblogs.com/luosha/p/6146058.html
Copyright © 2011-2022 走看看