<audio id="audio" title="076 | 基于深度学习的推荐模型之一：受限波兹曼机" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b5/f5/b5d1ca12f67fc04ba2e4e32429e103f5.mp3"></audio>

这几周我们进入专栏里一个比较大的模块，那就是推荐系统。

上周，我们谈了现代推荐系统的架构体系，帮助你在宏观上对推荐系统的构建有一个更加完整的认识。这周，我们主要来看在推荐系统研究领域里一个比较前沿的话题，那就是**如何利用深度学习来提升推荐系统的精度**。

今天，我们首先来看一篇经典的文章《受限波兹曼机进行协同过滤》（[Restricted Boltzmann machines for collaborative filtering](https://www.cs.toronto.edu/~rsalakhu/papers/rbmcf.pdf)）[1]，这篇文章尝试使用**受限波兹曼机**（Restricted Boltzmann Machines），简称 **RBM**，来对推荐系统进行建模。这应该是最早把深度学习应用到推荐建模的典范。

## 受限波兹曼机（RBM）

从严格意义上讲，RBM自身并不是深度模型，在早期对于RBM的使用上，也并没有将其“累加”到很多层从而形成“深度RBM”（Deep RBM）。但是从建模思路上来说，由一层RBM到多层RBM的扩展其实是非常直接的，因此了解RBM的基本思路，对后面理解推荐系统中如何利用深度学习模型进行建模是很有帮助的。

今天我们要介绍的文章发表于2007年的ICML（International Conference on Machine Learning，国际机器学习大会）上。作者群是鲁斯兰·萨拉胡特蒂诺夫（Ruslan Salakhutdinov）、安德烈·尼哈（ Andriy Mnih）以及杰弗里·辛顿（Geoffrey Hinton）。

辛顿在近日常常被称作深度学习之父。他不仅算是波兹曼机（Boltzmann Machines）的重要发明人和推动者之一，也和其学生一起把RBM应用到各类数据上，比如RBM在推荐领域的尝试。

2007年的时候，Netflix大赛如火如荼，很多学者都希望把各种模型和思路应用到这个比赛中。而在这个大赛中，有三个重要的思想脱颖而出，影响了后来推荐系统的研究发展。这三个思想分别是：

<li>
基于矩阵分解的模型；
</li>
<li>
基于RBM的模型；
</li>
<li>
利用集成学习（Ensemble Learning）把大量不同的模型整合起来。
</li>

由此可见，RBM对于推荐系统的尝试在当时是非常有新意的。

第一作者鲁斯兰当时在多伦多大学攻读计算机博士，跟随辛顿研究深度学习模型。另外一篇他当时做的工作，是把贝叶斯矩阵分解利用到Netflix大赛中，和我们今天讨论的这篇论文一起，都是他在博士阶段对于推荐系统这个领域所做的重要贡献。目前鲁斯兰在卡内基梅隆大学任教，并兼任苹果公司的人工智能总监一职。

那什么是RBM呢？简单说来，RBM就是由一层**隐单元**（Hidden Unit）和一层**显单元**（Visible Unit）组成的神经网络结构。通常情况下，显单元和隐单元这两层之间是完全连通的。也就是说，对于每一个显单元来说，它都和所有的隐单元联系到一起。

**每个隐单元和显单元自身都有一个权重（Weight），并且在每对隐单元和显单元之间的连接上还有一个权重**。所有这些权重都是需要通过训练学习的未知参数。举例来说，如果我们有3个显单元（用于描述3个数据点），5个隐单元。那么我们就有3个权重对应3个显单元，有5个权重对应5个隐单元，然后有15（3*5）个连接权重，这样算下来一共是23个权重。RBM可以针对高斯信号，也就是实数信息，以及伯努利或者二项分布（Binomial Distribution）信号，也就是离散信息，进行建模。

## 受限波兹曼机在推荐上的应用

当我们对RBM有了一个基本的了解之后，我们来看RBM是怎么应用到推荐系统上的。为了讲解方便，我们这里使用Netflix的例子，也就是对“用户为电影打分”进行建模。

首先，对于每一个用户，我们使用一个单独的RBM来对这个用户进行建模，只不过，每一个RBM都有一样的隐单元数量。在建模的时候，每一个RBM仅仅对当前这个用户曾经打过分的数据进行建模。也就是说，每一个RBM需要建模的数据是不一样的，有的用户对三个电影打过分，有的对十个电影打过分。你可以设想一下，在这样的情况下，整个模型是什么意思。

每个用户有一个独立的RBM，这个RBM负责对这个用户的电影集合进行建模。很显然，这些RBM互相没有关联。那怎么把每个用户的RBM给联系起来呢？作者们做了这样的假设，也就是每个RBM的隐单元是不一样的，这其实可以代表学习到的“用户的偏好”。但是，如果两个用户都对同一个电影打过分，那么，针对这个电影，两个不同的RBM会共享一样的权重。这就是联系两个RBM的核心思想，也就是说，**利用RBM对用户电影推荐的核心是“共享相同电影的权重”**。

具体说来，每一个显单元都是用户对于某个电影的评价。这里每个显单元都是一个K维的数组，其中只有一个元素是1，其他都是0。这种**二元的数组表达**，帮助模型来对“用户对于有K种可能的输出”进行建模。隐单元在这篇论文中，也是二元的，只不过，我们事先并不知道隐单元的取值。和刚才介绍的一样，在这样的模型里，需要学习的参数包括显单元的权重、隐单元的权重以及他们之间关系的权重，同一个电影的权重是共享的。

每一个用户都有一个单独的RBM，并且我们在RBM里只对已经评过分的电影进行了建模，因此这个模型并不能直接对未知的电影评分进行预测。需要预测的时候，我们其实是先拿到这个电影的权重，然后看，我们把那个K维的评分数组设置成哪种情况的时候，产生的概率是最大的。也就是说，我们尝试把对于未知的电影评分设置成不同情况，取出现可能性最大的那种评分作为预测结果。很明显，这样做的计算效率并不高。文章中也介绍了如何加速，我们这里就不复述了。

**RBM对于推荐系统的建模看上去很简单，但是难点却是如何学习这些未知的权重**。总体说来，RBM无法直接使用类似“最大似然法”或者“递归下降”的方法来对参数进行学习。这其实也是阻碍这类方法广泛使用的一个重要障碍。在最初的论文里，作者们提出了一种CD（Contrastive Divergence，对比散度）方法，这种方法其实是一种简化的MCMC（Markov chain Monte Carlo，马尔科夫蒙特卡洛）方法，用于对RBM进行采样。CD方法具体是如何实现的，我们这里就不展开了。

在Netflix的数据集上，RBM展现了惊人的效果，不仅能够很轻松地击败Netflix自身的算法基线，还比当时提出的单纯的矩阵分解方法要更加优秀。基于此，后来就有了很多RBM的扩展工作。

## 小结

这周我来为你讲解利用推荐系统的一个重要的问题，就是如何利用深度学习模型来对推荐系统进行建模。今天我们聊了一个最基本的深度学习模型，受限波兹曼机，讨论了如何将其应用在推荐系统中。

一起来回顾下要点：第一，我们介绍了什么是受限波兹曼机；第二，我们讨论了如何把受限波兹曼机应用到推荐场景中。

最后，给你留一个思考题，如果希望在受限波兹曼机里增加其他信息，比如各种用户信息或者电影信息，我们该如何做呢？

欢迎你给我留言，和我一起讨论。

**参考文献**

1. Ruslan Salakhutdinov, Andriy Mnih, and Geoffrey Hinton. **Restricted Boltzmann machines for collaborative filtering**. Proceedings of the 24th international conference on Machine learning (ICML '07), Zoubin Ghahramani (Ed.). ACM, New York, NY, USA, 791-798, 2007.


