推荐系统实践读书笔记

推荐系统实战

好的推荐系统

个性化推荐系统需要依赖用户的行为数据。几乎所有的推荐系统应用都是由**前台的展示页面、后台的日志系统以及推荐算法系统**3部分构成的。

个性化推荐的两个条件:

  • 第一是存在信息过载,因为如果用户可以很容易地从所有物品中找到喜欢的物品,就不需要个性化推荐了。
  • 第二是用户大部分时候没有特别明确的需求,因为用户如果有明确的需求,可以直接通过搜索引擎找到感兴趣的物品。

预测准确度是推荐系统领域的重要指标。但是好的推荐系统不仅仅能够准确预测用户的行为,而且能够扩展用户的视野,帮助用户发现那些他们可能会感兴趣,但却不那么容易发现的东西。

利用用户行为数据

基于用户行为分析的推荐算法是个性化推荐系统的重要算法,学术界一般将这种类型的算法
称为==协同过滤算法==。

用户行为在个性化推荐系统中一般分两种——显性反馈行为(explicit feedback)隐性反馈行为(implicit feedback)。显性反馈行为包括用户明确表示对物品喜好的行为。隐性反馈行为指的是那些不能明确反应用户喜好的行为,隐性反馈虽然不明确,但数据量更大

学术界对协同过滤算法进行了深入研究,提出了很多方法,比如基于邻域的方法(neighborhood-based)、隐语义模型(latent factor model)、基于图的随机游走算法(random walk on graph)等。

业界得到最广泛应用的算法是基于邻域的方法,分为:

  • 基于用户的协同过滤算法 这种算法给用户推荐和他兴趣相似的其他用户喜欢的物品。
  • 基于物品的协同过滤算法 这种算法给用户推荐和他之前喜欢的物品相似的物品。

评测指标

对用户u推荐N个物品(记为R(u)),令用户u在测试集上喜欢的物品集合为T(u)

精确率

精确率(precision)是针对我们预测结果而言的,它表示的是预测为正的样本中有多少是真正的正样本。那么预测为正就有两种可能了,一种就是把正类预测为正类(TP),另一种就是把负类预测为正类(FP),也就是

由此,得到

Precision=u|R(u)T(u)|u|T(u)|

召回率

召回率(recall)是针对我们原来的样本而言的,它表示的是样本中的正例有多少被预测正确了。那也有两种可能,一种是把原来的正类预测成正类(TP),另一种就是把原来的正类预测为负类(FN)。

由此得到:

Recall=u|R(u)T(u)|u|R(u)|

==召回率描述有多少比例的用户—物品评分记录包含在最终的推荐列表中,而准确率描述最终的推荐列表中有多少比例是发生过的用户—物品评分记录==

==其实就是分母不同,一个分母是预测为正的样本数,另一个是原来样本中所有的正样本数。==

推荐系统实践读书笔记_第1张图片

在信息检索领域,精确率和召回率又被称为查准率查全率

查准率=检索出的相关信息量 / 检索出的信息总量

查全率=检索出的相关信息量 / 系统中的相关信息总量

覆盖率

覆盖率反映了推荐算法发掘长尾的能力,覆盖率越高,说明推荐算法越能够将长尾中的物品推荐给用户。用简单定义如下:

Coverage=|uUR(u)||I|

该覆盖率表示最终的推荐列表中包含多大比例的物品。如果所有的物品都被推荐给至少一个
用户,那么覆盖率就是100%。

新颖度

新颖度,这里用推荐列表中物品的平均流行度度量推荐结果的新颖度。如果推荐出的物品都很热门,说明推荐的新颖度较低,否则说明推荐结果比较新颖。

基于邻域的算法

基于用户的协同过滤(UserCF)

两个步骤:

  • 找到和目标用户兴趣相似的用户集合。
  • 找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户。

给定用户u和用户v,令 N(u) 表示用户u曾经有过正反馈的物品集合,令 N(v) 为用户v曾经有过正反馈的物品集合,那么可以用如下==Jaccard公式==简单计算u和v的兴趣相似度。

Wuv=|N(u)N(v)||N(u)N(v)|

或者使用==余弦系数==公式:
Wuv=|N(u)N(v)||N(u)||N(v)|

如下的公式度量了UserCF算法中用户u对物品i的感兴趣程度:
p(u,i)=vS(u,K)N(i)Wuvrvi

其中, S(u,K) 包含和用户u兴趣最接近的K个用户, N(i) 是对物品i有过行为的用户集合, Wuv
是用户u和用户v的兴趣相似度, rvi 代表用户v对物品i的兴趣,因为使用的是单一行为的隐反馈数
据,所以所有的 rvi=1


两个用户对冷门物品采取过同样的行为更能说明他们兴趣的相似度。因此,John S. Breese在论文中提出了如下公式,根据用户行为计算用户的兴趣相似度:

Wuv=iN(u)N(v)1log(1+|N(i)|)|N(u)||N(v)|

该公式用 1log(1+|N(i)|) 惩罚了用户u和用户v共同兴趣列表中热门物品对他们相似度的影响。

基于物品的协同过滤(ItemCF)

基于物品的协同过滤(item-based collaborative filtering)算法是目前业界应用最多的算法。

基于用户的cf主要有以下缺点:

  1. 随着网站的用户数目越来越大,计算用户兴趣相似度矩阵将越来越困难,其运算时间复杂度和空间复杂度的增长和用户数的增长近似于平方关系。
  2. 基于用户的协同过滤很难对推荐结果作出解释。

基于物品的协同过滤算法(简称ItemCF)给用户推荐那些和他们之前喜欢的物品相似的物品

ItemCF算法并不利用物品的内容属性计算物品之间的相似度,它==主要通过分析用户的行为记录计算物品之间的相似度==。该算法认为,物品A和物品B具有很大的相似度是因为喜欢物品A的用户大都也喜欢物品B。

基于物品的协同过滤算法主要分为两步:

  • 计算物品之间的相似度。
  • 根据物品的相似度和用户的历史行为给用户生成推荐列表。

Wij=|N(i)N(j)||N(i)|

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

上述公式有一个问题,如果物品j很热门,很多人都喜欢,那么 Wij 就会很大,接近1。因此,该公式会造成任何物品都会和热门的物品有很大的相似度,这对于致力于挖掘长尾信息的推荐系统来说显然不是一个好的特性。

改进用了下面的公式:

Wij=|N(i)N(j)||N(i)||N(j)|

这个公式 惩罚了物品j的权重,因此减轻了热门物品会和很多物品相似的可能性

得到相似度矩阵后,ItemCF用以下公式计算用户u对物品j的兴趣:

puj=iN(u)S(j,K)Wjirui

这里 N(u) 是用户喜欢的物品的集合(注意区别和 N(i) ), S(j,K) 是和物品j最相似的K个物品的集合, Wji 是物品j和i
的相似度, rui 是用户u对物品i的兴趣。(对于隐反馈数据集,如果用户u对物品i有过行为,即可令 rui=1

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

John S. Breese认为活跃用户对物品相似度的贡献应该小于不活跃的用户,所以增加了IUF(Inverse User Frequence)参数来修正:

Wij=uN(i)N(j)1log(1+|N(u)|)|N(i)||N(j)|

物品相似度的归一化

Karypis在研究中发现如果将ItemCF的相似度矩阵按最大值归一化,可以提高推荐的准确率

Wij=WijmaxjWij

此外,它还可以提高推荐的覆盖率和多样性(一般来说,热门的类其类内物品相似度一般比较大。如果不进行归一化,就会推荐比较热门的类里面的物品,而这些物品也是比较热门的。因此,推荐的覆盖率就比较低)。

二者总结

UserCF给用户推荐那些和他有共同兴趣爱好的用户喜欢的物品,而ItemCF给用户推荐那些和他之前喜欢的物品类似的物品。

UserCF的推荐更社会化,反映了用户所在的小型兴趣群体中物品的热门程度,而ItemCF的推荐更加个性化,反映了用户自己的兴趣传承。

UserCF ItemCF
性能 适用于用户较少的场合
领域 时效性较强,用户个性化兴趣不太明显的领域
实时性 用户有新行为,不一定造成推荐结果的立即变化
冷启动 在新用户对很少的物品产生行为后,不能立即对他进行个性化推荐。因为用户相似度表是每隔一段时间计算的。新物品上线后一段时间,一旦有用户对物品产生行为,就可以将新物品推荐给和对它产生行为的用户兴趣相似的其它用户。
推荐理由 很难提供令用户信服的推荐解释。

为什么原始ItemCF算法的覆盖率和新颖度都不高?

哈利波特问题:因为《哈利波特》书太过于热门,购买任何一本书的人似乎都会购买它。

就像前面提到的公式:

Wij=|N(i)N(j)||N(i)||N(j)|

如果物品j真的极度热门,上面的分子就是无限接近于 |N(i)|

  1. 可以在分母上继续加大对热门物品的惩罚。比如加上指数 α
  2. 两个不同领域的最热门物品之间往往具有比较高的相似度。这个
    时候,仅仅靠用户行为数据是不能解决这个问题的,因为用户的行为表示这种物品之间应该似
    度很高。此时,我们只能依靠引入物品的内容数据解决这个问题,比如对不同领域的物品降低权重等。这些就不是协同过滤讨论的范畴了。

隐语义模型LFM(latent factor model)

隐语义模型是最近几年推荐系统领域最为热门的研究话题,它的核心思想是通过隐含特征(latent factor)联系用户兴趣和物品。和该技术相关且耳熟能详的名词有pLSA、LDA、隐含类别模型(latent class model)、隐含主题模型(latent topic model)、矩阵分解(matrix factorization)。

LFM通过如下公式计算用户u对物品i的兴趣:

Preference(u,i)=rui=pTuqi=f=1Fpu,kqi,k

pu,k qi,k 是该模型的参数,前者度量了用户u和第k个隐类的关系,后者度量了第k个隐类和物品i的关系。这两个参数从 训练集中计算而得。 F 表示隐特征的个数,也即聚类的个数。

我们从数学角度来理解隐语义模型。如下图所示,R矩阵是用户对物品的偏好信息(Rij表示的是user i对item j的兴趣度),P矩阵是用户对各物品类别的一个偏好信息(Pij表示的是user i对class j的兴趣度),Q矩阵是各物品所归属的的物品类别的信息(Qij表示的是item j在class i中的权重)。隐语义模型就是要将矩阵R分解为矩阵P和矩阵Q的乘积,即通过矩阵中的物品类别(class)将用户user和物品item联系起来。实际上我们需要根据用户当前的物品偏好信息R进行计算,从而得到对应的矩阵P和矩阵Q。

LFM模型在实际使用中有一个困难,那就是它很难实现实时的推荐。经典的LFM模型每次训练时都需要扫描所有的用户行为记录,这样才能计算出用户隐类向量( pu )和物品隐类向量( qi )。

基于图的模型

可以把基于邻域的模型看做基于图的模型的简单形式。

如果将个性化推荐算法放到二分图模型上,那么给用户u推荐物品的任务就可以转化为度量用户顶点 vu 和与 vu 没有边直接相连的物品节点在图上的相关性,相关性越高的物品在推荐列表中的权重就越高。

基于随机游走的PersonalRank算法:

假设要给用户u进行个性化推荐,可以从用户u对应的节点 vu 开始在用户物品二分图上进行随机游走。游走到任何一个节点时,首先按照概率α决定是继续游走,还是停止这次游走并从 vu 节点开始重新游走。如果决定继续游走,那么就从当前节点指向的节点中按照均匀分布随机选择一个节点作为游走下次经过的节点。这样,经过很多次随机游走后,每个物品节点被访问到的概率会收敛到一个数。最终的推荐列表中物品的权重就是物品节点的访问概率。

如图,

PersonalRank算法的具体过程如下(对用户A来说):

初始化:

PR(A)=1,PR(B)=0,,PR(d)=0

开始在图上游走,每次选择PR值不为0的节点开始,沿着边往前的概率为 α ,停在当前点的概率为 1α

首先从A开始,从A到a和c的概率为0.5,则此时a和c的PR值为:

PR(a)=PR(c)=α×PR(A)×0.5

A的PR值变成了1−α。此时PR值不为0的节点为A,a,c,则此时从这三点出发,继续上述的过程,直到收敛为止。

所以公式如下:

PR(v)=α×vin(v)PR(v)|out(v)|(1α)+α×vin(v)PR(v)|out(v)| if vvu if v=vu

虽然PersonalRank算法可以通过随机游走进行比较好的理论解释,但该算法在时间复杂度上有明显的缺点。因为在为每个用户进行推荐时,都需要在整个用户物品二分图上进行迭代,直到整个图上的每个顶点的PR值收敛。这一过程的时间复杂度非常高,不仅无法在线提供实时推荐,甚至离线生成推荐结果也很耗时。

冷启动问题

分类

  • 用户冷启动

    用户冷启动主要解决如何给新用户做个性化推荐的问题。当新用户到来时,我们没有他的行为数据,所以也无法根据他的历史行为预测其兴趣,从而无法借此给他做个性化推荐。

  • 物品冷启动

    物品冷启动主要解决如何将新的物品推荐给可能对它感兴趣的用户这一问题。

  • 系统冷启动

    系统冷启动主要解决如何在一个新开发的网站上(还没有用户,也没有用户行为,只有一些物品的信息)设计个性化推荐系统,从而在网站刚发布时就让用户体验到个性化推荐服务这一问题。

利用用户注册信息

用户的注册信息分为三种:

  1. 人口统计学信息

    包括用户的年龄、性别、职业、民族、学历和居住地。

  2. 用户兴趣的描述

    有一些网站会让用户用文字描述他们的兴趣。

  3. 从其他网站导入的用户站外行为数据

    比如用户通过豆瓣、新浪微博的账号登录,就可以在得到用户同意的情况下获取用户在豆瓣或者新浪微博的一些行为数据和社交网络数据。

基于注册信息的个性化推荐流程基本如下:

  • 获取用户的注册信息;
  • 根据用户的注册信息对用户分类;
  • 给用户推荐他所属分类中用户喜欢的物品。

基于用户注册信息的推荐算法其核心问题是计算每种特征的用户喜欢的物品。也就是说,对于每种特征 f ,计算具有这种特征的用户对各个物品的喜好程度 p(f,i) p(f,i) 可以简单地定义为物品i在具有 f 的特征的用户中的热门程度:

p(f,i)=|N(i)U(f)|

其中 N(i) 是喜欢物品i的用户集合, U(f) 是具有特征 f 的用户集合

但是,往往热门的物品会在各种特征的用户中都具有比较高的权重。也就是说具有比较高的 N(i)
的物品会在每一类用户中都有比较高的 p(f,i) ,==给用户推荐热门物品并不是推荐系统的主要任务,推荐系统应该帮助用户发现他们不容易发现的物品==。

我们可以将 p(f,i) 定义为喜欢物品i的用户中具有特征 f 的比例:

p(f,i)=|N(i)U(f)||N(i)|+α

这里分母中使用参数 α 的目的是 解决数据稀疏问题。比如有一个物品只被1个用户喜欢过,
而这个用户刚好就有特征 f ,那么就有 p(f,i)=1

选择合适的物品启动用户的兴趣

解决用户冷启动问题的另一个方法是在新用户第一次访问推荐系统时,不立即给用户展示推荐结果,而是给用户提供一些物品,让用户反馈他们对这些物品的兴趣,然后根据用户反馈给提供个性化推荐。

首要问题就是如何选择物品让用户进行反馈?

一般来讲,用来启动用户兴趣的物品需要具有以下特点:

  1. 比较热门

  2. 具有代表性和区分性

    启动用户兴趣的物品不能是大众化或老少咸宜的,因为这样的物品对用户的兴趣没有区分性。

  3. 启动物品集合需要有多样性

    在冷启动时,我们不知道用户的兴趣,而用户兴趣的可能性非常多,为了匹配多样的兴趣,我们需要提供具有很高覆盖率的启动物品集合,这些物品能覆盖几乎所有主流的用户兴趣。

如何设计一个选择启动物品集合的系统呢?

==决策树的方法==

给定一群用户,Nadav Golbandi用这群用户对物品评分的方差度量这群用户兴趣的一致程度。

基本思想是通过如下方式度量一个物品的区分度 D(i) :

D(i)=σuN+(i)+σuN(i)+σuN¯(i)

N+(i) 是喜欢物品i的用户集合, N(i) 是不喜欢物品i的用户集合, N¯(i) 是没有对物品i评分的用户集合。 σuN+(i) 是喜欢物品i的用户对其他物品评分的方差,其它类似。

Nadav Golbandi的算法首先会从所有用户中找到具有最高区分度的物品i,然后将用户分成3类。然后在每类用户中再找到最具区分度的物品,然后将每一类用户又各自分为3类,也就是将总用户分成9类,然后这样继续下去,最终可以通过对一系列物品的看法将用户进行分类。而在冷启动时,我们从根节点开始询问用户对该节点物品的看法,然后根据用户的选择将用户放到不同的分枝,直到进入最后的叶子节点,此时我们就已经对用户的兴趣有了比较清楚的了解,从而可以开始对用户进行比较准确地个性化推荐。

利用物品的内容信息

物品冷启动需要解决的问题是如何将新加入的物品推荐给对它感兴趣的用户。物品冷启动在新闻网站等时效性很强的网站中非常重要!

首先需要指出的是,UserCF算法对物品冷启动问题并不非常敏感。当一个新物品加入时,总会有用户从某些途径看到这些物品,对这些物品产生反馈。那么,当一个用户对某个物品产生反馈后,和他历史兴趣相似的其他用户的推荐列表中就有可能出现这一物品,从而更多的人就会对这个物品产生反馈,导致更多的人的推荐列表中会出现这一物品,因此该物品就能不断地扩散开来,从而逐步展示到对它感兴趣用户的推荐列表中。

对于ItemCF算法来说,物品冷启动就是一个严重的问题了。因为ItemCF算法的原理是给用户推荐和他之前喜欢的物品相似的物品。

一般来说,物品的内容可以通过向量空间模型表示,该模型会将物品表示成一个关键词向量。对物品d,它的内容表示成一个关键词向量如下:

di={(e1,w1),(e2,w2),}

ei 就是关键词, wi 是关键词对应的权重。

向量空间模型的优点是简单,缺点是丢失了一些信息,比如关键词之间的关系信息。

在给定物品内容的关键词向量后,物品的内容相似度可以通过向量之间的余弦相似度计算:

Wij=didjdidj

如果用户的行为强烈受某一内容属性的影响,那么内容过滤的算法还是可以在精度上超过协同过滤算法的。

但是,如果文本很短,关键词很少,向量空间模型就很难计算出准确的相似度。此时考虑话题模型(topic model)。代表性的话题模型就是LDA。

发挥专家的作用

很多推荐系统在建立时,既没有用户的行为数据,也没有充足的物品内容信息来计算准确的物品相似度。

那么,为了在推荐系统建立时就让用户得到比较好的体验,很多系统都利用专家进行标注。

利用用户标签数据

推荐系统的目的是联系用户的兴趣和物品,这种联系需要依赖不同的媒介。基本上通过3种方式联系用户兴趣和物品:

  1. 利用用户喜欢过的物品,给用户推荐与他喜欢过的物品相似的物品
  2. 利用和用户兴趣相似的其他用户,给用户推荐那些和他们兴趣爱好相似的其他用户喜欢的物品
  3. 通过一些特征(feature)联系用户和物品,给用户推荐那些具有用户喜欢的特征的物品

第三个中,特征有不同的表现形式,比如内容属性、隐语义向量(latent factor vector)和标签。

标签是一种无层次化结构的、用来描述信息的关键词,标签应用一般分为两种:一种是让作者或者专家给物品打标签;另一种是让普通用户给物品打标签,也就是UGC(User Generated Content,用户生成的内容)的标签应用。

一个简单的算法

  1. 统计每个用户最常用的标签。
  2. 对于每个标签,统计被打过这个标签次数最多的物品。
  3. 对于一个用户,首先找到他常用的标签,然后找到具有这些标签的最热门物品推荐给这个用户。

对于上面的算法,用户u对物品i的兴趣公式如下:

p(u,i)=bnu,bnb,i

B(u) 是用户u打过的标签集合, B(i) 是物品i被打过的标签集合, nu,b 是用户u打过标签b的次数, nb,i 是物品i被打过标签b的次数。

算法优化

前面这个公式倾向于给热门标签对应的热门物品很大的权重,因此会造成推荐热门的物品给用户,从而降低推荐结果的新颖性。所以,改进后为:

p(u,i)=bnu,blog(1+n(u)b)nb,ilog(1+n(u)i)

n(u)b 记录了标签b被多少个不同的用户使用过, n(u)i 记录了物品i被多少个不同的用户打过标签。

适当惩罚热门标签和热门物品,在增进推荐结果个性化的同时并不会降低推荐结果的离线精度。

冷启动问题标签拓展

在前面的算法中,用户兴趣和物品的联系是通过 B(u)B(i) 中的标签建立的。但是,对于新用户或者新物品,这个集合( B(u)B(i) )中的标签数量会很少。为了提高推荐的准确率,我们可能要对标签集合做扩展,比如若用户曾经用过“推荐系统”这个标签,我们可以将这个标签的相似标签也加入到用户标签集合中,比如“个性化”、“协同过滤”等标签。

标签扩展的本质是对每个标签找到和它相似的标签,也就是计算标签之间的相似度

标签清理

不是所有标签都能反应用户的兴趣。标签清理的另一个重要意义在于将标签作为推荐解释,此时对标签质量有所要求。

给用户推荐标签

为什么要给用户推荐标签?

  1. 方便用户输入标签
  2. 提高标签质量

如何给用户推荐标签?

  1. 推荐整个系统里最热门的标签
  2. 推荐物品i上最热门的标签
  3. 推荐他自己经常使用的标签
  4. 前面两种的融合,该方法通过一个系数将上面的推荐结果线性加权,然后生成最终的推荐结果

你可能感兴趣的:(推荐系统,推荐系统)