一、FM算法背景

在计算广告和推荐系统中,CTR预估是非常重要的一个环节,判断一个商品的是否进行推荐需要根据CTR预估的点击率来进行。

在进行CTR预估时,除了单特征外,往往要对特征进行组合,对于特征组合来说,业界现在通用的做法主要有两大类:FM系列与Tree系列。实际工程中通常是高维稀疏矩,直接特征交叉会导致计算量过大,特征权值更新缓慢。

而FM的优势就是对这两方面问题的处理:首先是特征组合,通过对两两特征组合,引入交叉项特征,提高模型特征能力;其次是维度灾难,通过引入对参数矩阵进行矩阵分解,对参数的计算节省资源。

FM是在逻辑回归上面衍生出来的,如果对逻辑回归最朴素的特征组合就是二阶笛卡尔乘积,这样暴力组合的问题:

  1. 两两组合导致特征维度灾难
  2. 组合后的特征不见得都有效,事实上大部分可能无效
  3. 组合后的特征样本非常稀疏,即组合容易,但是并不能在样本中找到对应的组合出现,也就没办法在训练时更更新参数。

二、FM算法原理

包含了特征两两组合的逻辑回归线性部分就是:ω0+∑i=1nωixi+∑i=1n∑j=i+1nwijxixj\omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n}\sum_{j=i+1}^{n}w_{ij}x_ix_jω0​+∑i=1n​ωi​xi​+∑i=1n​∑j=i+1n​wij​xi​xj​。

与线性模型相比,FM的模型就多了后面特征组合的部分。和原始的逻辑回归相比,就多出来了特征两两组合部分,也需要去学习对应的参数权重。

因为逻辑回归在做特征组合时样本稀疏,从而无法学到很多特征组合的权重,所以FM的思想就是对特征两两组合的逻辑回归线性部分公式中的wijw_{ij}wij​做解耦,让每一个特征学习一个隐因子向量出来。如果学习wijw_{ij}wij​的话,需要学习n+(n−1)+...+1=n2+n2n+(n-1)+...+1=\frac{n^2+n}{2}n+(n−1)+...+1=2n2+n​个参数,使用隐因子向量代替后只需学习n∗kn*kn∗k个参数。并且如果使用前者直接训练,只有当i,j特征都命中时,才会更新wijw_{ij}wij​参数,但数据十分稀疏,在训练时有效地更新参数也十分困难。而使用隐因子向量后,只要和i特征有关的交叉,都会更新i特征对应的向量。
就像矩阵分解,为每一个用户和每一个物品各自都学习一个隐因子向量一样,当任何两个特征在实际使用时需要组合,那么两者各自隐因子变量做一个向量点积,就是两者组合特征的权重。因此,对每一个特征分量xix_ixi​引入辅助向量Vi=(vi1,vi2,⋯,vik)V_i=(v_{i1},v_{i2},⋯,v_{ik})Vi​=(vi1​,vi2​,⋯,vik​)。然后,利用vivjTv_iv_j^Tvi​vjT​对ωijω_{ij}ωij​进行求解。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VGxJp9QX-1570666412267)(img/V.png)]

FM模型表达式:ω0+∑i=1nωixi+∑i=1n∑i=j+1n<Vi,Vj>xixj\omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n}\sum_{i=j+1}^{n}<V_i,V_j>x_ix_jω0​+∑i=1n​ωi​xi​+∑i=1n​∑i=j+1n​<Vi​,Vj​>xi​xj​。

三、FM求解

具体求解viv_ivi​和vjv_jvj​:FM中二阶特征组合部分在实际计算时,复杂度有点高,如果隐因子向量的维度是k,特征维度是n,那这个复杂度就是O(kn2)O(kn^2)O(kn2)。其中n2n^2n2是特征要两两组合,k是每次组合都要对k维向量计算点积。需要进行改造:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uy36RnxK-1570666412269)(img/求解.png)]

第一步到第二步可用矩阵展开,容易理解。

简化后计算过程:

loop1 begin: 循环k次,k就是隐因子向量的维度,其中,循环到第f次时:loop2 begin: 循环n个特征,第i次循环时:
​       1. 从第i个特征的隐因子向量中拿出第f维的值
​       2. 计算两个值:A是特征值和f维的值相乘,B是A的平方
​   loop2 end把n个A累加起来,并平方得到C,把n个B也累加起来,得到D,用C减D,得到E
loop1 end
把k次循环得到的k个E累加起来,除以2。

这是FM中二阶组合部分的实际计算方法,这样做的复杂度只是O(kn)O(kn)O(kn)。

四、FM算法模型训练

FM的目标函数,在这里是把它当作融合模型来看的,用来做CTR预估,因此预测目标是一个二分类,FM的输出还需要经过sigmoid函数变换:σ(y^)=11+e(−y^)\sigma(\hat{y})=\frac{1}{1+e^{(-\hat{y})}}σ(y^​)=1+e(−y^​)1​。

因此,损失目标函数也就是常用的logistic loss:loss⁡(θ)=−1m∑i=1m[y(i)log⁡(σ(y^))+(1−y(i))log⁡(1−σ(y^))]\operatorname{loss}(\theta)=-\frac{1}{m}\sum_{i=1}^m\left[y^{(i)} \log (\sigma(\hat{y}))+(1-y^{(i)}) \log (1-\sigma(\hat{y}))\right]loss(θ)=−m1​∑i=1m​[y(i)log(σ(y^​))+(1−y(i))log(1−σ(y^​))],公式中σ(y^)\sigma(\hat{y})σ(y^​)是因子分解机FM的预测输出结果,经过sigmoid函数变换得到的预估CTR。损失函数实际上还需要加上正则项,对这个损失目标函数使用梯度下降或者随机梯度下降就可以得到模型的参数。

五、FM和矩阵分解的关系

FM是把常规矩阵分解,SVD,SVD++,time-SVD全部囊括了,顺便还进行了逻辑回归的工作,也正因如此,FM常用来做模型融合,在推荐系统的排序阶段对召回结果做重排序

参考:

推荐系统三十六式

推荐系统遇上深度学习(一)–FM模型理论和实践

推荐系统算法系列(一):FM算法相关推荐

  1. 查找算法系列之复杂算法:哈希查找

    查找算法系列之复杂算法:哈希查找 眼下为止已经介绍了顺序查找.二分查找.分块查找.二叉排序树.见作者之前的文章: http://blog.csdn.net/u010025211/article/det ...

  2. 【算法系列】卡尔曼滤波算法

    系列文章目录 ·[算法系列]卡尔曼滤波算法 ·[算法系列]非线性最小二乘求解-直接求解法 ·[算法系列]非线性最小二乘求解-梯度下降法 ·[算法系列]非线性最小二乘-高斯牛顿法 ·[算法系列]非线性最 ...

  3. 排序算法系列:归并排序算法

    概述 上一篇我们说了一个非常简单的排序算法--选择排序.其复杂程序完全是冒泡级的,甚至比冒泡还要简单.今天要说的是一个相对比较复杂的排序算法--归并排序.复杂的原因不仅在于归并排序分成了两个部分进行解 ...

  4. 分治法的关键特征_算法系列之常用算法之一----分治算法

    一.基本概念 在计算机科学中,分治法是一种很重要的算法.分治算法,字面上的解释是"分而治之",分治算法主要是三点: 1.将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问 ...

  5. 算法系列教程04 - 算法相关的基础概念

    本系列前面两篇讲的都是一些背景知识,从这一篇开始我们正式讲算法,从算法的一些基本概念讲起. 什么是算法 通过上一篇对图灵机原理的讲解,我们知道,一个计算问题描述的是输入/输出之间的关系,如果根据给定的 ...

  6. 排序算法系列:插入排序算法

    概述 直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表. – <大话数据结构> 版权说明 ...

  7. 排序算法系列:快速排序算法

    概述 在前面说到了两个关于交换排序的算法:冒泡排序与奇偶排序. 本文就来说说交换排序的最后一拍:快速排序算法.之所以说它是快速的原因,不是因为它比其他的排序算法都要快.而是从实践中证明了快速排序在平均 ...

  8. 【匈牙利算法】【二分图匹配】【转载】趣写算法系列之--匈牙利算法

    转载自:http://blog.csdn.net/dark_scope/article/details/8880547 [书本上的算法往往讲得非常复杂,我和我的朋友计划用一些简单通俗的例子来描述算法的 ...

  9. oracle快速排序法,经典算法系列之快速排序算法

    快速排序(Quicksort)是对冒泡排序的一种改进.由C. A. R. Hoare在1962年提出.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但 ...

  10. 带父节点的平衡二叉树_Python算法系列—深度优先遍历算法【二叉树】

    一.什么是深度优先遍历 深度优先遍历算法是经典的图论算法.从某个节点v出发开始进行搜索.不断搜索直到该节点所有的边都被遍历完,当节点v所有的边都被遍历完以后,深度优先遍历算法则需要回溯到v以前驱节点来 ...

最新文章

  1. ACM入门之【单调栈】
  2. ajax 最大链接数_leetcode之第三大的数
  3. windows复制文件路径_如何在Windows 10上复制文件的完整路径
  4. public protect private继承
  5. python怎么读写文件-python怎么读取文件内容
  6. element-UI中table表格的row-click事件怎么获取一行数据的id
  7. 小说阅读器未能连接服务器怎么办,小强小说阅读器无法加载小说章节的解决方法...
  8. java freepascal_Free Pascal
  9. python将多个pdf合并并保存书签
  10. java语音api_java – 语音识别Api
  11. Linux数据结构之radix-tree
  12. 基于区块链的自动抽奖系统从0到1实现探析预言机与跨链技术的融合发展
  13. Word及Autocad中中文字号与字体大小的关系
  14. EasyExcel工具类(开箱即用)
  15. iOS 控制任务执行顺序
  16. 学PHP时,端口被占用,怎么找端口的占用情况。
  17. Star CCM+ 案例 - 旋风分离器 (cyclone separator)-2 生成网格
  18. Java Web基础入门第八十二讲 Listener(监听器)——监听器在开发中的应用(一)
  19. Module named ‘XXX’ already exists 错误解决
  20. 2013年最忧伤的句子

热门文章

  1. keilc51下载安装
  2. 怎么给iPhone手机上的待办事项软件加上密码锁
  3. 3、解读中台 -- 中台的发展与进化
  4. java对称加密AES加入偏移量
  5. 零售互联网化“革命”从改造收银台开始
  6. 电动汽车入网技术(V2G)调度优化(Matlab代码实现)
  7. iOS/Android开发地图SDK列表
  8. python爬虫学习之模拟登录淘宝
  9. python中的变量名只能由数字字母下划线组成_密码只能包含数字字母和下划线
  10. 使用R语言获得16S物种丰度