本文始发于公众号: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模型搞懂再说

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的表达式,大家一看就明白了。

\[\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
\]

从这个公式当中,我们可以看出来当我们进行预测的时候,我们需要遍历所有的交叉项,最终得到预测值。这里又有了一个很大的问题,就是计算的复杂度。由于我们使用了所有特征的二阶交叉项,那么我们需要累加的项的数量就是\(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)\),所以我们先把这两项忽略,单独来看第三项,也就是困扰我们的这一项。

对于这个式子,我们可以进行化简:

\[\begin{aligned}\sum_{i=1}^n\sum_{j=i+1}^n v_i^T v_j x_i x_j &= \frac{1}{2}\sum_{i=1}^n\sum_{j=1}^n v_i^Tv_jx_i x_j - \frac{1}{2}\sum_{i=1}^nv_i^Tv_jx_ix_j\\&=\frac{1}{2}(\sum_{i=1}^n\sum_{j=1}^n\sum_{f=1}^kv_{i, f}v_{j, f}x_ix_j-\sum_{i=1}^n\sum_{f=1}^kv_{i,f}v_{i,f}x_ix_i)\\&=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nv_{i, f}x_i)(\sum_{j=1}^nv_{j, f}x_j)-\sum_{i=1}^nv_{i,f}^2x_i^2)\\&=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nv_{i,f}x_i)^2 - \sum_{i=1}^nv_{i, f}^2 x_i^2)\end{aligned}
\]

简单来解释一下这个推导过程,第一行我想大家应该都能看懂,第二行也很好理解,其实就是把\(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模型效果好在哪里?的更多相关文章

  1. 巨经典论文!推荐系统经典模型Wide & Deep

    今天我们剖析的也是推荐领域的经典论文,叫做Wide & Deep Learning for Recommender Systems.它发表于2016年,作者是Google App Store的 ...

  2. 图像Resize方式对深度学习模型效果的影响

    在基于卷积神经网络的应用过程中,图像Resize是必不可少的一个步骤.通常原始图像尺寸比较大,比如常见监控摄像机出来的是1080P高清或者720P准高清画面,而网络模型输入一般没有这么大,像Yolo系 ...

  3. 聊聊五大IO模型

    IO模型介绍 IO模型不是用来开启并发效果的,而是用来接收并发效果的. 比较了五种IO Model:    * blocking IO           阻塞IO    * nonblocking ...

  4. 聊聊css盒子模型

    css盒子模型原理: 在网页设计中常听的属性名:内容(content).填充/内边距(padding).边框(border).外边距(margin), CSS盒子模式都具备这些属性. 这些属性我们可以 ...

  5. 【Android界面实现】可旋转的汽车3D模型效果的实现

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 今天要给大家介绍的是怎样实现可旋转的汽车3D模型. 先看实现效果 这仅仅是静态图,实际上,这个模型是能够依据 ...

  6. 回归模型效果评估系列1-QQ图

    (erbqi)导语 QQ图全称 Quantile-Quantile图,也就是分位数-分位数图,简单理解就是把两个分布相同分位数的值,构成点(x,y)绘图:如果两个分布很接近,那个点(x,y)会分布在y ...

  7. 聊聊Java内存模型

    一.Java内存模型 硬件处理 电脑硬件,我们知道有用于计算的cpu.辅助运算的内存.以及硬盘还有进行数据传输的数据总线.在程序执行中很多都是内存计算,cpu为了更快的进行计算会有高速缓存,最后同步至 ...

  8. 再谈Cognos利用FM模型来做同比环比

    很早之前已经讲过 <Cognos利用DMR模型开发同比环比>这篇文章里说的是不利用过滤器,而是采用 except (lastPeriods (-9000,[订单数据分析].[日期维度].[ ...

  9. 深度学习原理与框架-卷积网络细节-图像分类与图像位置回归任务 1.模型加载 2.串接新的全连接层 3.使用SGD梯度对参数更新 4.模型结果测试 5.各个模型效果对比

    对于图像的目标检测任务:通常分为目标的类别检测和目标的位置检测 目标的类别检测使用的指标:准确率, 预测的结果是类别值,即cat 目标的位置检测使用的指标:欧式距离,预测的结果是(x, y, w, h ...

随机推荐

  1. SpringMVC中<mvc:default-servlet-handler/>的作用

    问题所在:DispatcherServlet请求映射配置为"/",则Spring MVC将捕获Web容器所有的请求,包括静态资源的请求,Spring MVC会将它们当成一个普通请求 ...

  2. @RequestParam、@PathVariable、 @RequestBody用法

    Get和Post请求 get方式的请求是没有请求体的.但是get有query string parameter .比如url?name=zhangsan post请求发现了两种请求体.一种是FromD ...

  3. tp 创建文件并写入数据

    代码:1.$url = Env::get('root_path').'application/admin/test.txt'; //定义创建路径 $file = fopen($url,"w& ...

  4. 异常检测算法Robust Random Cut Forest(RRCF)关键定理引理证明

    摘要:RRCF是亚马逊发表的一篇异常检测算法,是对周志华孤立森林的改进.但是相比孤立森林,具有更为扎实的理论基础.文章的理论论证相对较为晦涩,且没给出详细的证明过程.本文不对该算法进行详尽的描述,仅对 ...

  5. c++逆向分析----返回对象

    对象不使用默认析构函数 class Test { public: char cNum1; int iNum2; int* pInt; }; Test _ReturnObject() { Test st ...

  6. 关于Redis哨兵机制,7张图详解!

    写在前面 之前有位朋友去面试被问到Redis哨兵机制,这道题其实很多小伙伴都应该有被问到过!本文将跟大家一起来探讨如何回答这个问题!同时用XMind画了一张导图记录Redis的学习笔记和一些面试解析( ...

  7. rabbitmq介绍以及初步使用

    什么是MQ? ​ MQ(Message Queue):翻译为消息队列,通过典型的生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断地从队列中获取消息.因为消息的生产和消费都是异步的,而且只 ...

  8. 使用小记:Zookeeper中动态改变节点的功能

    Zookeeper 3.5+提供了reconfig功能实现动态配置节点,官方的说明是,"你再也不需要进行全部节点重启"就可以应用所有的修改: http://zookeeper.ap ...

  9. [bug] sqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1054, "Unknown column 'recevie_name' in 'field list'")

    Python Flask 开发购物网站,提交订单时报错 根据提示,检查代码,发现是字段名拼写错误导致,数据库对应的字段是receive_name,误写成了recevie_name 另外要注意,灰色字和 ...

  10. [bug] Nginx:src/os/unix/ngx_user.c:36:7: 错误:‘struct crypt_data’没有名为‘current_salt’的成员

    参考 https://blog.csdn.net/yu_pan_love_cat/article/details/103035513 https://www.cnblogs.com/hxlinux/p ...