上篇文章介绍了基于用户的协同过滤算法,该算法在一些网站(如 Facebook)中得到了应用,但该算法有一些缺点。首先,随着网站的用户数目越来越大,计算用户兴趣相似度矩阵将越来越困难,其运算时间复杂度和空间复杂度的增长和用户数的增长近似于平方关系。其次,基于用户的协同过滤很难对推荐结果作出解释。因此,著名的电子商务公司亚马逊提出了另一个算法一基于内容的协同过滤算法。

什么是基于内容的协同过滤算法

在进入本文的正题之前,先打开网易云音乐看下今天的日推:

看了上述的标记,是不是瞬间理解了为啥用网易云听音乐的时候会有上瘾的感觉,因为他给你听的都是你爱听的啊。就跟小时候我妈给我做菜是一样的,今天知道我喜欢吃红烧肉,明天为了照顾我的喜好又为了保证不重样,第二天就给我做了糖醋排骨,久而久之产生了依赖性,体重也开始飙升了。

上述就是 基于内容的协同过滤算法(Item-based collaborative filtering,简称 ItemCF) 在生活中常见的案例,该算法给用户推荐那些和他们之前喜欢的内容相似的内容。比如,该算法会因为你购买过《数据挖掘导论》而给你推荐《机器学习》。不过,ItemCF 算法并不利用内容的内容属性计算内容之间的相似度,它主要通过分析用户的行为记录计算内容之间的相似度。该算法认为,内容 A 和内容 B 具有很大的相似度是因为喜欢内容 A 的用户大都也喜欢内容 B。

事实上,由于人和人之间的差异性远大于内容和内容之间的差异(不然怎么会说你女朋友翻脸比翻书还快呢 🙈),ItemCF 算法算是目前业界应用最多的算法。无论是淘宝首页猜你喜欢,还是网易云音乐、哔哩哔哩、YouTube,其推荐算法的基础都是该算法。

Tips:基于内容的协同过滤算法可以利用用户的历史行为给推荐结果提供推荐解释,比如上图中网易云日推的标签,会告诉你是根据你收藏的某某单曲推荐的。

基于内容的协同过滤算法

如果你理解了我的上一篇文章《从网易云日推浅谈个性化推荐系统(1)–基于用户的协同过滤算法》,那你也很容易就可以联想到想要实现一个基于内容的协同过滤需要有以下两步:

  1. 计算内容之间的相似度。

  2. 根据内容的相似度和用户的历史行为给用户生成推荐列表。

计算内容之间的相似度

1.确定计算相似度的公式

很显然,步骤(1)的关键就是计算两个内容之间的相似度,亚马逊显示相关内容推荐时的标题是 “Customers Who Bought This Item Also Bought” (购买了该商品的用户也经常购买的其他商品) ,相当于就下了一个定义,根据这个定义,我们可以用下面的公式定义内容的相似度:

$$W_{ij}=\frac{\left | N(i)\cap N(j) \right |}{\left | N(i) \right |}$$

这里,分母$\left | N(i) \right |$是喜欢物品$i$的用户数,而分子$\left | N(i)\cap N(j) \right |$是同时喜欢物品$i$和物品$j$的用户数。因此,上述公式可以理解为喜欢物品$i$的用户中有多少比例的用户也喜欢物品$j$。

上述公式虽然看起来很有道理,但是却存在一个问题。如果物品$j$很热门,很多人都喜欢, 那么$W_{ij}$就会很大,接近 1。因此,该公式会造成任何物品都会和热门的物品有很大的相似度,这对于致力于挖掘长尾信息的推荐系统来说显然不是一个好的特性。为了避免推荐出热门的物品, 可以用下面的公式:

$$W_{ij}=\frac{\left | N(i)\cap N(j) \right |}{\sqrt{\left | N(i)\left | \right |N(j) \right |}}$$

是不是似曾相识?没错,我们又碰到了熟悉的余弦相似性,为什么说这个公式相对公平呢?因为在该公式中,$N(j)$对于整个式子的影响会比上一个式子小,即该公式公式惩罚了物品$j$的权重,因此减轻了热门物品会和很多物品相似的可能性。

从上面的定义可以看到,在协同过滤中两个物品产生相似度是因为它们共同被很多用户喜欢,也就是说每个用户都可以通过他们的历史兴趣列表给物品“贡献”相似度。这里面蕴涵着一个假设,就是每个用户的兴趣都局限在某几个方面,因此如果两个物品属于一个用户的兴趣列表,那么这两个物品可能就属于有限的几个领域,而如果两个物品属于很多用户的兴趣列表,那么它们就可能属于同一个领域,因而有很大的相似度。

2.建立相似度矩阵并计算相似度

和 UserCF 算法类似,用 ItemCF 算法计算物品相似度时也可以首先建立用户-物品倒排表(即对每个用户建立一个包含他喜欢的物品的列表),然后对于每个用户,将他物品列表中的物品两两在共现矩阵 C 中加 1。

上图是一个根据上面的程序计算物品相似度的简单例子。图中最左边是输入的用户行为记录,每一行代表一个用户感兴趣的物品集合。然后,对于每个物品集合,我们将里面的物品两两加一,得到一个矩阵。最终将这些矩阵相加得到上面的$C$矩阵。其中$C[i][j]$记录了同时喜欢物品$i$和物品$j$的用户数。最后,将$C$矩阵归一化可以得到物品之间的余弦相似度矩阵$W$。然后再根据上一篇的余弦相似性的计算方法即可计算出不同物品之间的相似度了。

3.推荐物品

在得到物品之间的相似度后,ItemCF 通过如下公式计算用户$u$对一个物品$j$的兴趣:

$$P_{uj}=\sum_{i\in N(u)\cap S(j,K)}^{ }W_{ji}r_{ui}$$

这里$N(u)$是用户喜欢的物品的集合,$S(j,K)$是和物品$j$最相似的$K$个物品的集合,$W_{ji}$是物品$j$和$i$ 的相似度,$r_{ui}$是用户$u$对物品$i$的兴趣。

该公式的含义是,和用户历史上感兴趣的物品越相似的物品,越有可能在用户的推荐列表中获得比较高的排名。

举个栗子 🌰

上面一大段可能有点枯燥,不过没关系,相信举了下面的栗子之后,你们可能就会对该算法有个基本的了解了。

一个基于内容推荐的简单例子

上图是一个基于内容推荐的简单例子。该例子中,用户喜欢《晴天》和《江南》两首歌。然后 ItemCF 会为这两首歌分别找出和它们最相似的 3 首歌,然后根据公式的定义计算用户对每首歌的感兴趣程度。比如,ItemCF 给用户推荐《不能说的秘密》,是因为这首歌和《晴天》相似,相似度为 0.4,而且这首歌也和《江南》相似,相似度是 0.5。考虑到用户对《晴天》的兴趣度是 1.3,对《江南》的兴趣度是 0.9,那么用户对《不能说的秘密》的兴趣度就是 1.3 × 0.4 + 0.9×0.5 = 0.97。

从这个例子可以看到,ItemCF 的一个优势就是可以提供推荐解释,即利用用户历史上喜欢的

物品为现在的推荐结果进行解释。

UserCF V.S. ItemCFU

网上在比较这两个推荐算法的时候,往往都是先放上各种曲线比较图,例如召回率、覆盖率的比较等等,然而作为小白那样的图可能看的并不是十分的明白。倒不如直接进行这两个算法在实际使用中的对比情况:

UserCF 和 ItemCF 算法在现实中的应用

公司 算法 用途
腾讯 UserCF 微信 7.0 的看一看功能
GroupLens UserCF 个性化的新闻推荐
网易 ItemCF 网易云音乐的歌曲推荐
阿里巴巴 ItemCF 淘宝的首页猜你喜欢

那为什么新闻推荐使用 UserCF 算法,而购物网站使用 ItemCF 算法?

UserCF 算法的推荐结果着重于反映那些与目标用户兴趣相似的小群体的热点,而 ItemCF 算法的推荐结果着重于维护目标用户的历史兴趣。换句话说,UserCF 的推荐更加社会化,而 ItemCF 的推荐更加个性化。

UserCF 与 ItemCF 算法的比较

UseCF ItemCF
性能 适合于用户数量较小的场景,如果用户很多,则计算用户之间相似度矩阵的代价很大 适用于物品数量明显小于用户数量的场景,如果物品很多,则计算物品之间相似度矩阵的代价很大
领域 时效性较强,用户个性化兴趣不太明显的领域 长尾物品丰富,用户个性化需求强烈的领域
实时性 用户的新行为不一定导致推荐结果的立即变化 用户的新行为一定会导致推荐结果的实时变化
冷启动 当新用户对很少量的物品产生行为后,不能立即对他进行推荐,因为用户相似度表一般是每隔一段时间离线计算的。 当新物品上线后,一旦有某个用户对该物品产生行为,就可以将该物品推荐给与该用户相似的其他用户 新用户只要对一个物品产生行为,就可以向他推荐与该物品相似的其他物品 必须在更新了物品相似度表(离线)之后,才能将新的物品推荐给其他用户
推荐理由 很难提供令用户信服的推荐解释 利用用户的历史行为来作为推荐理由,容易令用户信服

总结

这篇文章紧接上文,介绍了什么是基于内容的协同过滤,当然,真正用到企业级产品时,其相似度也不可能只用简单的余弦相似性就能描述了,考虑到各种特殊情况,可能还需要将内容的相似度进行归一化,当然这就需要你深入了解了,本文就不详细展开了,推荐阅读相关的论文。文章最后比较了下 UCF 和 ICF,大家只需要知道在什么情况下哪种推荐算法更加实用即可,毕竟适合自己的才是最好的。下一篇我将会用 python 代码结合 tensorflow 来训练一个最简单的电影个性化推荐模型。