[推荐]基于内容的召回(CB: content-based)

1,625 阅读17分钟

参考网址

感谢大佬分享

blog.csdn.net/luanfenlian…

完全基于item,跟其他的用户user没有关系。
核心思想:给目标用户推荐他之前喜欢的item类似的item.
在一个推荐系统的初期,或者是冷启动阶段,首选基于内容的推荐cb.
因为它搭建比较快,而且可以很快的见效。
并且在推荐系统的初期,用户的行为数据很少,而且新的item也需要被推荐出去,首选cb.

在cb中,item的标签挖掘很重要,可以说是cb的基础。
我们只有搞定了user profile和item profile的标签体系,才可以推荐。
也可以是user embeding 和 item embedding 低维稠密向量

优点:
   user之间的独立性,给目标用户推荐的时候,不需要考虑其他的user
   可解释性强
   新的item可以立即得到推荐,也就是新的item和老的item被推荐的概率是一样大的。

缺点:
   item的标签体系构建比较难
   不能挖掘用户的新的兴趣点,及是根据用户的历史行为偏好来进行推荐,而不是根据用户的实时行为偏好来推荐。
   对新的用户不友好,不能对新的用户进行推荐。
  

1/前言

image.png

image.png

上图给出了一个基于内容推荐的一个典型的例子,就是电影推荐系统。
首先我们需要对电影的元数据进行建模,这里的元数据就是对电影的一些描述和概括。
上图中,我们只是对简单概括了电影的类型。然后通过电影的元数据我们发现电影之间的相似度,
a和c电影是类似的,因为都是爱情/浪漫类的电影。
当然我们不能只根据电影的类型,如果想要把推荐系统做得更好的话,还可以考虑电影的导演和主要演员等。
最后实现推荐,对于用于a,我们可以把c电影推荐给他。

2/概述

基于内容的召回又被称为Content Based,使用item之间的相似性来推荐与用户喜欢的item相似的item。
例如:老张在腾讯视频看了一部恐怖片,之后他就会发现腾讯视频给他推送其他的恐怖片。

在一款推荐系统的`早期`,基于内容推荐的地位举重若轻,它可以很快的搭建,也可以很快的见效。
其中`item标签挖掘`是内容推荐中最重要的一个环节。
在产品的`冷启动阶段`没有用户行为(或者用户行为数据特别少),另外新的物品也需要被推荐出去,首选内容推荐(因为在cb中,新的item可以立即得到推荐,和老的item得到推荐的概率是一样的)。
然而想做好基于内容的推荐也并非想象中的那么简单,具体做法分为以下几步:
  <1>为每个item抽取出一些特征(也就是item的content了)来表示此item;
  <2>利用一个用户过去喜欢(及不喜欢)的item的特征数据,来学习出此用户的喜好特征(profile);
  <3>通过比较上一步得到的用户profile与候选item的特征,为此用户推荐一组相   关性最大的item。


举个例子说明前面的三个步骤。
对于个性化阅读来说,一个item就是一篇文章。
根据上面的第一步,我们首先要对每一篇文章抽取特征,来表示这片文章。
常用的方法就是利用出现在一篇文章中的词来代表这篇文章,而每个词对应的权重往往使用信息检索中的tf-idf算法来计算。
比如对于本文来说,词“CB”、“推荐”和“喜好”的权重会比较大,而“烤肉”这个词的权重会比较低。
利用这种方法,一篇抽象的文章就可以使用具体的一个向量来表示了。
第二步就是根据用户过去喜欢什么文章来产生刻画此用户喜好的profile了,最简单的方法可以把用户所有喜欢的文章对应的向量的平均值作为此用户的profile。
比如某个用户经常关注与推荐系统有关的文章,那么他的profile中“CB”、“CF”和“推荐”对应的权重值就会较高。
在获得了一个用户的profile后,CB就可以利用所有item与此用户profile的相关度对他进行推荐文章了。
一个常用的相关度计算方法是余弦相似度(cosine)。最终把候选item里与此用户最相关(cosine值最大)的N个item作为推荐返回给此用户。

image.png

介绍一下上图的流程和基本元素。
在内容这一端,内容源经过内容分析,得到结构化的内容库和内容模型。
在用户这一端,用户看过推荐列表后,会产生用户行为数据,结合内容库并经过用户分析可以得到用户画像。
对于那些没有给用户推荐过的新内容,经过相同的内容分析过程就可以通过推荐算法加以匹配,再将计算得到的新的推荐列表推给用户。如此周而复始,永不停息。

其实,基于内容的推荐,最重要的不是推荐算法,而是内容挖掘和分析(标签体系)。
只要内容挖掘的足够深入,哪怕早期推荐算法采用非常硬的规则,也能去的不俗的效果。

3/基于内容推荐步骤的详细介绍

 我们已经知道,基于内容推荐有3大步骤,分为是:
    <1>item标签(特征/属性)的挖掘(抽取),也就是item embedding的构建
    <2>user profile的构建,也就是user embedding的构建
    <3>基于user的profile和item的特征
    

<1>对于item的特征抽取

真实应用中的item往往都会有一些可以描述它的属性。
这些属性通常可以分为两种:结构化的(structured)属性与非结构化的(unstructured)属性。
所谓结构化的属性就是这个属性的意义比较明确,其取值限定在某个范围;
而非结构化的属性往往其意义不太明确,取值也没什么限制,不好直接使用。
比如在交友网站上,item就是人,一个item会有结构化属性如身高、学历、籍贯等,
也会有非结构化属性(如item自己写的交友宣言,博客内容等等)。
对于结构化数据,我们自然可以拿来就用;但对于非结构化数据(如文章),我们往往要先把它转化为结构化数据后才能在模型里加以使用。
真实场景中碰到最多的非结构化数据可能就是文章了(如个性化阅读中)。

<2>对于user的喜好的概括(user profile)

假设用户user已经对一些item给出了他的喜好判断,喜欢其中的一部分item,不喜欢其中的另一部分。
那么,这一步要做的就是通过用户user过去的这些喜好判断,为他产生一个模型。
有了这个模型,我们就可以根据此模型来判断用户u是否会喜欢一个新的item。
所以,我们要解决的是一个典型的有监督分类问题,理论上机器学习里的分类算法都可以照搬进这里。

下面我们简单介绍下CB里常用的一些机器学习算法:

 (1)k最近邻方法(k-Nearest Neighbor,简称kNN)
    对于一个新的item,最近邻方法首先找用户u已经评判过并与此新item最相似的k个item,然后依据用户u对这k个item的喜好程度来判断其对此新item的喜好程度。
    这种做法和CF中的item-based很相似,差别在于这里的item相似度是根据item的属性向量计算得到,而CF中是根据所有用户对item的评分计算得到。

 对于这个方法,比较关键的可能就是如何通过item的属性向量计算item之间的两两相似度。
 建议对于结构化数据,相似度计算使用欧几里得距离;而如果使用向量空间模型(VSM)来表示item的话,则相似度计算可以使用cosine。

 (2)Rocchio算法
  Rocchio算法是信息检索中处理相关反馈(Relevance Feedback)的一个著名算法。比如你在搜索引擎里搜“苹果”,当你最开始搜这个词时,搜索引擎不知道你到底是要能吃的水果,还是要不能吃的苹果,所以它往往会尽量呈现给你各种结果。当你看到这些结果后,你会点一些你觉得相关的结果(这就是所谓的相关反馈了)。然后如果你翻页查看第二页的结果时,搜索引擎可以通过你刚才给的相关反馈,修改你的查询向量取值,重新计算网页得分,把跟你刚才点击的结果相似的结果排前面。比如你最开始搜索“苹果”时,对应的查询向量是{“苹果” : 1}。而当你点击了一些与Mac、iPhone相关的结果后,搜索引擎会把你的查询向量修改为{“苹果” : 1, “Mac” : 0.8, “iPhone” : 0.7},通过这个新的查询向量,搜索引擎就能比较明确地知道你要找的是不能吃的苹果了。Rocchio算法的作用就是用来修改你的查询向量的:{“苹果” : 1} --> {“苹果” : 1, “Mac” : 0.8, “iPhone” : 0.7}。

(3)决策树算法(Decision Tree,简称DT)
   当item的属性较少而且是结构化属性时,决策树一般会是个好的选择。
   这种情况下决策树可以产生简单直观、容易让人理解的结果。
   而且我们可以把决策树的决策过程展示给用户u,告诉他为什么这些item会被推荐。
   但是如果item的属性较多,且都来源于非结构化数据(如item是文章),那么决策树的效果可能并不会很好。

(4)线性分类算法(Linear Classifer,简称LC)
  对于我们这里的二类问题,线性分类器(LC)尝试在高维空间找一个平面,使得这个平面尽量分开两类点。
  也就是说,一类点尽可能在平面的某一边,而另一类点尽可能在平面的另一边。


(5)朴素贝叶斯算法(Naive Bayes,简称NB)
  NB算法就像它的简称一样,牛逼!
  NB经常被用来来进行`文本分类`,
  为什么叫`朴素`,因为它假设在给定一篇文章的类别后,其中各个词出现的概率`相互独立`。
  它的假设虽然很不靠谱,但是它的结果往往惊人地好。
  再加上NB的代码实现比较简单,所以它往往是很多分类问题里最先被尝试的算法。
  我们现在的profile learning问题中包括两个类别:用户u喜欢的item,以及他不喜欢的item。
  在给定一个item的类别后,其各个属性的取值概率互相独立。我们可以利用用户的历史喜好数据训练NB模型,
  之后再用训练好的NB模型对给定的新的item做分类。

<3>基于user的profile和item的特征

 如果上一步Profile Learning中使用的是分类模型(如DT、LC和NB),那么我们只要把模型预测的用户最可能感兴趣的n个item作为推荐返回给用户即可。
 而如果Profile Learning中使用的直接学习用户属性的方法(如Rocchio算法),那么我们只要把与用户属性最相关的n个item作为推荐返回给用户即可。
 其中的用户属性与item属性的相关性可以使用如cos余弦距离等相似度度量获得。

4/CB的优缺点

<1>优点

(1)user之间的独立性
   既然每个user的profile都是依据user本身对item的喜好获得的,自然就与其他人的行为无关。
   而CF刚好相反,CF需要利用很多其他人的数据,因为cf是协同过滤额,是需要item和user之间共同合作。
   CB的这种用户独立性带来的一个显著好处是别人不管对item如何作弊(比如利用多个账号把某个产品的排名刷上去)都不会影响到自己。
   这个有点可以大规模的应用在user上

(2)可解释性强
   如果需要向用户解释为什么推荐了这些产品给他,你只要告诉他这些产品有某某属性,这些属性跟你的品味很匹配等等。

(3)新的item可以立刻得到推荐
   只要一个新item加进item库,它就马上可以被推荐,被推荐的机会和老的item是一致的。
   因为新的item进入item库,说明它本身的特征是已经构建完毕的,比如它是
   而CF对于新item就很无奈,只有当此新item被某些用户喜欢过(或打过分),它才可能被推荐给其他用户。
   所以,如果一个纯CF的推荐系统,新加进来的item就永远不会被推荐

<2>缺点

(1)item的特征抽取一般很难(及item的标签体系很难建设)
   如果系统中的item是文档(如个性化阅读中),那么我们现在可以比较容易地使用信息检索里的方法来“比较精确地”抽取出item的特征。
   但很多情况下我们很难从item中抽取出准确刻画item的特征,比如电影推荐中item是电影,社会化网络推荐中item是人,这些item属性都不好抽。
   其实,几乎在所有实际情况中我们抽取的item特征都仅能代表item的一些方面,不可能代表item的所有方面。
   这样带来的一个问题就是可能从两个item抽取出来的特征完全相同,这种情况下CB就完全无法区分这两个item了。比如如果只能从电影里抽取出演员、导演,那么两部有相同演员和导演的电影对于CB来说就完全不可区分了。

(2)无法挖掘出用户的潜在兴趣
   CB的推荐只依赖于用户过去对某些item的喜好,它产生的推荐也都会和用户过去喜欢的item相似。
   如果一个人以前只看与NBA有关的文章,那CB只会给他推荐更多NBA相关的文章,
   它不会知道用户可能还喜欢足球。
   所以cb召回对扩展用户的兴趣点上能力不足。

(3)无法为新用户产生推荐
   新用户没有喜好历史,自然无法获得他的profile,所以也就无法为他产生推荐了。
   当然,这个问题CF也有。
   
   

5/基于内容的推荐和协同过滤推荐的区别

<1>基于内容的推荐
   只考虑目标用户本身,不考虑别的user(user独立)
   把目标用户喜欢item以及类似的item构建成一个集合,
   如果目标用户消费了其中的一个item,则向其推荐集合中的其他item.
   

<2>协同过滤
   充分利用集体的智慧。
   user和item之间互相配合,这就是协同的含义,是user和item构成的一个二维矩阵
   
   有2个出发点:
      (1)相类似的用户,可能对同样的东西感兴趣 user based 
      (2)用户可能偏爱与其购买的东西相类似的东西。
         也就是说考虑了用户的历史习惯。,对象客观上可能不一定相似,但是由于用户的行为可以认可其主观上是形似的。(比如在购物网站上,有'看过该商品的人还看过'这样的推荐)
 

<3>一个简单的demo
    举个简单的小例子,我们已知道

    用户u1喜欢的电影是AB,C

    用户u2喜欢的电影是A, C, E, F

    用户u3喜欢的电影是B,D

    我们需要解决的问题是:决定对u1是不是应该推荐F这部电影

    基于内容的推荐的做法:要分析F电影的特征和u1所喜欢的AB、C的特征,需要知道的信息是A(战争片),B(战争片),C(剧情片),如果F(战争片),那么F很大程度上可以推荐给u1,这是基于内容的做法,你需要对item进行特征建立和建模。

    协同过滤的办法:那么你完全可以忽略item的建模,因为这种办法的决策是依赖user和item之间的关系,也就是这里的用户和电影之间的关系。我们不再需要知道ABCF哪些是战争片,哪些是剧情片,我们只需要知道用户u1和u2按照item向量表示,他们的相似度比较高,那么我们可以把u2所喜欢的F这部影片推荐给u1。

6/区别

1、协同过滤算法与基于内容推荐算法所使用的数据维度不同。

【协同过滤】侧重使用user对于item的历史交互记录,即user-item二维矩阵;
【基于内容推荐】侧重于对用户或者项目的属性信息建模,比如用户的性别、年龄,商品的颜色、大小等属性。
 对于同一用户而言:【基于内容推荐】需要利用用户的性别、年龄、爱好等组成特征向量来表示;
 而【协同过滤】需要根据该用户所在矩阵的某一行来进行表示,即利用用户对于所有商品的交互记录来表示。换句话说,协同过滤算法中的用户/商品表示可以看做特殊的基于内容的表示,只不过是把用户的具体内容属性换为了用户的历史行为特征。

2、协同过滤算法与基于内容推荐算法的核心思想不同。
【协同过滤】侧重于从大数据(集体智慧)中寻找某些隐含的模式,即通过用户对于商品的历史交互记录来寻找相似的用户;
而【基于内容推荐】则侧重于通过对象的属性信息来进行匹配建模进而寻找相似的用户或者商品。

3、协同过滤算法与基于内容推荐算法的实现技术不同。
【协同过滤】将用户-商品评分二维矩阵当做输入送入模型进行训练进而产生输出,典型的模型为矩阵分解、user-based,item-based;
而【基于内容推荐】侧重将用户或者商品的特征信息作为输入特征,进而送入分类器进行建模,典礼的模型为LR。

4、协同过滤算法与基于内容推荐算法好坏的决定因素不同。
【协同过滤】算法随着用户对于商品的交互记录增多会使得模型能够更精确的捕捉用户的行为习惯,
          进而使得模型能够不费用额外的人工的方式来提高精度(但他在初期会面临冷启动问题的困扰)。
          
【基于内容推荐】侧重于特征工程,算法的好坏由用户和商品的内容属性所决定,因此需要较强的领域知识,
           但他的好处是不存在冷启动的问题。