聊聊推荐系统,FM模型效果好在哪里?
本文始发于公众号:Coder梁
大家好,我们今天继续来聊聊推荐系统。
在上一回当中我们讨论了LR模型对于推荐系统的应用,以及它为什么适合推荐系统,并且对它的优点以及缺点进行了分析。最后我们得出了结论,对于LR模型来说它的作用其实更多的是记住了一些特征的组合,所以在一些样本当中表现非常好,但同样也带来了问题,就是需要人工生产大量的特征,带来的负担非常的大。
特征交叉
在我们讲述解决方案之前,我们还是先来分析一下特征。
分析什么呢,分析我们人工制作的特征的内容。我们都知道无论是item还是user的统计类型的特征都是很容易搞定的,只需要做一些统计分析,有些更是可以直接从数仓当中获取。真正麻烦的是什么呢,真正麻烦的是item和user相关联的特征,在算法领域这种关联称为交叉。
举个简单的例子,比如男士_游戏
,女士_护肤品
这样的特征,就是user和item进行交叉得出的。这里用到的是用户的性别和商品的类别进行的交叉,除此之外我们还可以产生出各种各样其他的交叉特征,本质上来说我们人工做的特征其实都是这些交叉特征。大家也可以想象得到,这些交叉特征对于能够覆盖到的样本表现出来的效果肯定是非常好的,但是对于不能覆盖的样本其实就是完全没有意义了。所以这就带来了另外一个问题,就是泛化能力的问题。
说具体一点就是当我们交叉特征做到后面,能够覆盖的样本的数量会非常非常少,尤其是一些本来就很小众的特征之间的交叉。举个例子,比如说高收入人群_房产
这个交叉特征。对于电商平台来说,房产本来就是很小众的领域,只有极少数人才会闲着没事在电商网站看房子。同样高收入人群可能也很小众,毕竟大部分人都是普通打工人,收入有限。这么一来,这样得到的交叉特征能够覆盖的样本就会非常非常稀疏。
大家可以简单计算一下,假设房产在电商平台的商品当中的占比是1%,高收入群体在总用户占比是10%的话,那么两者交叉之后的占比就成了千分之一。那这样稀疏的样本在训练模型的时候,我们是很难保证这个特征对应的权重已经训练到了最佳程度。
如果说只是脏活累活多对于大公司来说倒也不是不可以忍受,大不了多雇一点人手就是了。但现在摆明了做出来的特征很有可能因为覆盖率的问题没有效果,那么这就不是很能接受了。
特征交叉的稀疏性以及大量的人力成本,这两个问题是LR模型绕不开的硬伤,也是它被FM代替的直接原因。
Factorization Machines因子分解机
FM模型的英文全称是Factorization Machine,翻译过来就是因子分解机,一般业内都简称为FM。
FM是非常强大的模型虽然提出至今已经超过10年了,但目前仍然被很多中小型企业广泛使用。它直接针对了LR的问题进行了修正,大大地提升了模型的效果,甚至可以说是推荐领域效果最显著的一次大跃进。
我在之前的时候写过FM这篇paper的完整解析,有感兴趣的小伙伴可以通过下方的传送门回顾一下。
FM的思想很简单,就是强制特征之间做两两交叉。对于每一个交叉项都赋予一个权重,让模型自己来学所有交叉项的权重。相当于把一维的LR拓展到了二维。
把一维拓展成二维和LR后期人们大量制作的手动交叉特征是一样的,虽然是模型自动做了,但同样会有稀疏性的问题。针对这个问题,FM创造性地提出了向量表示法。这个想法非常天才,可以说是划时代的。
向量表示法其实就是现在常说的embedding,也就是把一个标量用一个向量来代替。FM针对每一个特征在交叉之前都会赋予一个向量,这个向量的长度一般不会很长,介于16到256之间。我做过实验,长度16和长度256效果上几乎没有差别。然后对于特征i和j,我们假设它们的向量分别是\(V_i, V_j\)。对于它们交叉项的权重,我们不是直接通过模型来赋予,而是用\(V_i \cdot V_j\)来计算得到。
这样一来,对于特征数量是n的模型来说,它就把原本\(n * n\)的参数数量下降到了\(n * k\),这里的k就是我们刚才提到的向量的长度,这是一个常数。学过算法的同学都应该知道,这样直接就把参数的数量级下降了一维。
我们写出FM的表达式,大家一看就明白了。
\]
从这个公式当中,我们可以看出来当我们进行预测的时候,我们需要遍历所有的交叉项,最终得到预测值。这里又有了一个很大的问题,就是计算的复杂度。由于我们使用了所有特征的二阶交叉项,那么我们需要累加的项的数量就是\(n^2\)。对于推荐场景来说,n是一个很大的值,动辄好几十万,显然二阶平方是我们无法接受的。
关于这个问题,FM模型有一段非常精彩的数学推导,完美地解决了这个问题。
复杂度优化
我们分析一下\(\hat{y} = w_0 + \sum_{i=1}^nw_ix_i+\sum_{i=1}^{n-1}\sum_{j=1}^nv_i^T v_jx_i, x_j\)这个式子,会发现前两项都是一阶项,复杂度都是\(O(n)\),所以我们先把这两项忽略,单独来看第三项,也就是困扰我们的这一项。
对于这个式子,我们可以进行化简:
\]
简单来解释一下这个推导过程,第一行我想大家应该都能看懂,第二行也很好理解,其实就是把\(v_i^Tv_j\)向量内积展开。第二行到第三行的转化也不难理解,这里有三个\(\Sigma\),我们提取出的是最里面的\(\Sigma\),因为是有限项求和,我们调换顺序并不会影响结果。提取出了公因式之后,得到的结果是两个平方项。
这两个平方项是精髓,因为它们都是\(O(n)\)的复杂度。正是因为把复杂的累加转化成了两个平方项的差,我们才完成了复杂度降维的工作。两个平方项的计算复杂度都是\(O(n)\),再加上外面一层\(O(k)\)的复杂度,整体的复杂度是\(O(kn)\)。但由于k是常数,所以可近似看成\(O(n)\)的复杂度。
这样我们就完成了FM模型预测的优化。
FM的优缺点
到这里,我们把FM的原理又过了一遍。
对于FM模型来说,它最大的优点就是拟合能力很强,因为引入了二阶交叉的特征项,所以对于样本的表达能力大大提升。并且由于通过数学公式,我们将\(O(n^2)\)的复杂度降到了\(O(n)\)。它的训练以及预测速度都是非常快的,和LR旗鼓相当。
我们再来回顾一下LR的两个问题,一个是需要人工制作大量的特征,第二个是样本稀疏对于模型的训练会有影响。
第一个问题已经没有了,因为FM引入了自动交叉的机制,相当于默认帮助我们把所有的二阶交叉特征都做了一遍。但对于第二个问题我们还需要分析一下,为什么FM模型可以解决样本稀疏的问题呢?二阶交叉项不还是会面临样本很少的情况吗?
原因很简单,因为FM把特征映射成了向量,在进行特征交叉的时候是通过向量的点乘来计算的交叉项的权重。对于特征i来说,它和其他所有特征交叉时使用的都是同一个向量\(V_i\)。这样即使特征i和j的组合在样本当中非常稀疏,但是由于\(V_i\)和\(V_j\)是单独训练的,所以我们仍然可以得到一个相对比较准确的权重。甚至即使i和j的组合在样本当中没有出现过,但是由于有了\(V_i\)和\(V_j\)向量,我们一样可以表达i和j的组合特征,这也是正是FM强大的地方。
FM虽然强大但也不是没有缺点,我们随便想想也能找出来不少。比如说虽然模型自动做了二阶交叉,但是二阶交叉真的能表达所有的特征信息吗?会不会有一些三阶交叉的特征,甚至是四阶交叉的特征会更有效果呢?而且所有的特征交叉都进行了学习,会不会当中有很多无用信息被包含进来了呢?再比如FM当中设定了每个特征和其他所有特征交叉的时候使用的向量是同一个,这样一刀切真的效果最好吗?再比如FM模型很难对连续性特征进行交叉,基本上只能交叉01离散型的特征,这样真的不会丢失信息吗?
我想这一系列问题问下来很难心里不大鼓,所以在FM时代的后期,针对FM模型的一些缺陷和不足进行了很多的实验和尝试,因此诞生了一系列各种各样添砖加瓦的模型。FM模型也从单个模型成了一个巨大的家族,下一期我将会来和大家盘点一下FM家族当中的模型,看看它们都有怎样的变化。
今天的文章就到这里,感谢阅读,如果喜欢的话,不要忘了三连。
聊聊推荐系统,FM模型效果好在哪里?的更多相关文章
- 巨经典论文!推荐系统经典模型Wide & Deep
今天我们剖析的也是推荐领域的经典论文,叫做Wide & Deep Learning for Recommender Systems.它发表于2016年,作者是Google App Store的 ...
- 图像Resize方式对深度学习模型效果的影响
在基于卷积神经网络的应用过程中,图像Resize是必不可少的一个步骤.通常原始图像尺寸比较大,比如常见监控摄像机出来的是1080P高清或者720P准高清画面,而网络模型输入一般没有这么大,像Yolo系 ...
- 聊聊五大IO模型
IO模型介绍 IO模型不是用来开启并发效果的,而是用来接收并发效果的. 比较了五种IO Model: * blocking IO 阻塞IO * nonblocking ...
- 聊聊css盒子模型
css盒子模型原理: 在网页设计中常听的属性名:内容(content).填充/内边距(padding).边框(border).外边距(margin), CSS盒子模式都具备这些属性. 这些属性我们可以 ...
- 【Android界面实现】可旋转的汽车3D模型效果的实现
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 今天要给大家介绍的是怎样实现可旋转的汽车3D模型. 先看实现效果 这仅仅是静态图,实际上,这个模型是能够依据 ...
- 回归模型效果评估系列1-QQ图
(erbqi)导语 QQ图全称 Quantile-Quantile图,也就是分位数-分位数图,简单理解就是把两个分布相同分位数的值,构成点(x,y)绘图:如果两个分布很接近,那个点(x,y)会分布在y ...
- 聊聊Java内存模型
一.Java内存模型 硬件处理 电脑硬件,我们知道有用于计算的cpu.辅助运算的内存.以及硬盘还有进行数据传输的数据总线.在程序执行中很多都是内存计算,cpu为了更快的进行计算会有高速缓存,最后同步至 ...
- 再谈Cognos利用FM模型来做同比环比
很早之前已经讲过 <Cognos利用DMR模型开发同比环比>这篇文章里说的是不利用过滤器,而是采用 except (lastPeriods (-9000,[订单数据分析].[日期维度].[ ...
- 深度学习原理与框架-卷积网络细节-图像分类与图像位置回归任务 1.模型加载 2.串接新的全连接层 3.使用SGD梯度对参数更新 4.模型结果测试 5.各个模型效果对比
对于图像的目标检测任务:通常分为目标的类别检测和目标的位置检测 目标的类别检测使用的指标:准确率, 预测的结果是类别值,即cat 目标的位置检测使用的指标:欧式距离,预测的结果是(x, y, w, h ...
随机推荐
- scrapy爬虫案例--爬取阳关热线问政平台
阳光热线问政平台:http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1 爬取最新问政帖子的编号.投诉标题.投诉内容以 ...
- Win10安装Ubuntu子系统(WSL)
一:设置子系统环境 关闭所有运行的程序,打开 控制面板→卸载程序→启用或关闭windows功能→勾选上适用于Linux的windows子系统 ,然后确定,完成会提示重启电脑,确定重启,等重启电脑后在操 ...
- Kafka源码分析系列-目录(收藏不迷路)
持续更新中,敬请关注! 目录 <Kafka源码分析>系列文章计划按"数据传递"的顺序写作,即:先分析生产者,其次分析Server端的数据处理,然后分析消费者,最后再补充 ...
- C# 多线程技术
这节讲一下多线程(Thread)技术. 在讲线程之前,先区分一下程序,进程,线程三者的区别,大体上说,一个程序可以分为多个进程,一个进程至少由一个线程去执行,它们是层层包含的关系.我们写的程序,就是一 ...
- Java 进行时间处理
Java 进行时间处理 一.Calendar (1).Calender介绍 Calendar的中文翻译是日历,实际上,在历史上有着许多种计时的方法.所以为了计时的统一,必需指定一个日历的选择.那现在最 ...
- Junit单元测试&反射&注解
内容索引 1. Junit单元测试 2. 反射 3. 注解 Junit单元测试: * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关 ...
- STL实现的底层数据结构简介
STL实现的底层数据结构简介 C++ STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque 底层数 ...
- 北航OO(2020)第四单元博客作业暨学期总结
一.第四单元架构设计 1.第一次作业 我在本次作业中设置了多个储存结构:Directory,ElementsInName,ElementsInId,Cache. Directory: 顾名思义,这是个 ...
- c语言常见编译问题
1 . warn.c:6:2: warning: implicit declaration of function 'strcpy' [-Wimplicit-function-declaration] ...
- 045.Python线程队列
线程队列 1 基本语法和用法 put 往线程队列里防止,超过队列长度,直接阻塞 get 从队列中取值,如果获取不到,直接阻塞 put_nowait: 如果放入的值超过队列长度,直接报错(linux) ...