[Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

1 集体智慧和协同过滤

1.1 什么是集体智慧(社会计算)?

  集体智慧 (Collective Intelligence) 并非 Web2.0 时代特有的,只是在 Web2.0 时代,你们在 Web 应用中利用集体智慧构建更加有趣的应用或者获得更好的用户体验。集体智慧是指在大量的人群的行为和数据中收集答案,帮助你对整我的群获得统计意义上的结论,这些结论是咱们在单个个体上没法获得的,它每每是某种趋势或者人群中共性的部分。html

  Wikipedia 和 Google 是两个典型的利用集体智慧的 Web 2.0 应用:java

  • Wikipedia 是一个知识管理的百科全书,相对于传统的由领域专家编辑的百科全书,Wikipedia 容许最终用户贡献知识,随着参与人数的增多,Wikipedia 变成了涵盖各个领域的一本无比全面的知识库。也许有人会质疑它的权威性,但若是你从另外一个侧面想这个问题,也许就能够迎刃而解。在发行一本书时,做者虽然是权威,但不免还有一些错误,而后经过一版一版的改版,书的内容愈来愈完善。而在 Wikipedia 上,这种改版和修正被变为每一个人均可以作的事情,任何人发现错误或者不完善均可以贡献他们的想法,即使某些信息是错误的,但它必定也会尽快的被其余人纠正过来。从一个宏观的角度看,整个系统在按照一个良性循环的轨迹不断完善,这也正是集体智慧的魅力。
  • Google:目前最流行的搜索引擎,与 Wikipedia 不一样,它没有要求用户显式的贡献,但仔细想一想 Google 最核心的 PageRank 的思想,它利用了 Web 页面之间的关系,将多少其余页面连接到当前页面的数目做为衡量当前页面重要与否的标准;若是这很差理解,那么你能够把它想象成一个选举的过程,每一个 Web 页面都是一个投票者同时也是一个被投票者,PageRank 经过必定数目的迭代获得一个相对稳定的评分。Google 其实利用了如今 Internet 上全部 Web 页面上连接的集体智慧,找到哪些页面是重要的。

1.2 什么是协同过滤?

  协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤 (Collaborative Filtering, 简称 CF),首先想一个简单的问题,若是你如今想看个电影,但你不知道具体看哪部,你会怎么作?大部分的人会问问周围的朋友,看看最近有什么好看的电影推荐,而咱们通常更倾向于从口味比较相似的朋友那里获得推荐。这就是协同过滤的核心思想。算法

  协同过滤通常是在海量的用户中发掘出一小部分和你品位比较相似的,在协同过滤中,这些用户成为邻居,而后根据他们喜欢的其余东西组织成一个排序的目录做为推荐给你。固然其中有一个核心的问题:apache

  • 如何肯定一个用户是否是和你有类似的品位?
  • 如何将邻居们的喜爱组织成一个排序的目录?

  协同过滤相对于集体智慧而言,它从必定程度上保留了个体的特征,就是你的品位偏好,因此它更多能够做为个性化推荐的算法思想。能够想象,这种推荐策略在 Web 2.0 的长尾中是很重要的,将大众流行的东西推荐给长尾中的人怎么可能获得好的效果,这也回到推荐系统的一个核心问题:了解你的用户,而后才能给出更好的推荐。网络

2 深刻协同过滤的核心

  前面做为背景知识,介绍了集体智慧和协同过滤的基本思想,这一节咱们将深刻分析协同过滤的原理,介绍基于协同过滤思想的多种推荐机制,优缺点和实用场景。框架

  首先,要实现协同过滤,须要一下几个步骤dom

  • 收集用户偏好
  • 找到类似的用户或物品
  • 计算推荐

2.1 收集用户偏好

  要从用户的行为和偏好中发现规律,并基于此给予推荐,如何收集用户的偏好信息成为系统推荐效果最基础的决定因素。用户有不少方式向系统提供本身的偏好信息,并且不一样的应用也可能大不相同,下面举例进行介绍:机器学习

表 1 用户行为和用户偏好
用户行为 类型 特征 做用
评分 显式 整数量化的偏好,可能的取值是 [0, n];n 通常取值为 5 或者是 10 经过用户对物品的评分,能够精确的获得用户的偏好
投票 显式 布尔量化的偏好,取值是 0 或 1 经过用户对物品的投票,能够较精确的获得用户的偏好
转发 显式 布尔量化的偏好,取值是 0 或 1 经过用户对物品的投票,能够精确的获得用户的偏好。
若是是站内,同时能够推理获得被转发人的偏好(不精确)
保存书签 显示 布尔量化的偏好,取值是 0 或 1 经过用户对物品的投票,能够精确的获得用户的偏好。
标记标签 
(Tag)
显示 一些单词,须要对单词进行分析,获得偏好 经过分析用户的标签,能够获得用户对项目的理解,同时能够分析出用户的情感:喜欢仍是讨厌
评论 显示 一段文字,须要进行文本分析,获得偏好 经过分析用户的评论,能够获得用户的情感:喜欢仍是讨厌
点击流 
( 查看 )
隐式 一组用户的点击,用户对物品感兴趣,须要进行分析,获得偏好 用户的点击必定程度上反映了用户的注意力,因此它也能够从必定程度上反映用户的喜爱。
页面停留时间 隐式 一组时间信息,噪音大,须要进行去噪,分析,获得偏好 用户的页面停留时间必定程度上反映了用户的注意力和喜爱,但噪音偏大,很差利用。
购买 隐式 布尔量化的偏好,取值是 0 或 1 用户的购买是很明确的说明这个项目它感兴趣。

  以上列举的用户行为都是比较通用的,推荐引擎设计人员能够根据本身应用的特色添加特殊的用户行为,并用他们表示用户对物品的喜爱。ide

  在通常应用中,咱们提取的用户行为通常都多于一种,关于如何组合这些不一样的用户行为,基本上有如下两种方式:函数

  • 将不一样的行为分组:通常能够分为“查看”和“购买”等等,而后基于不一样的行为,计算不一样的用户 / 物品类似度。相似于当当网或者 Amazon 给出的“购买了该图书的人还购买了 ...”,“查看了图书的人还查看了 ...”
  • 根据不一样行为反映用户喜爱的程度将它们进行加权,获得用户对于物品的整体喜爱。通常来讲,显式的用户反馈比隐式的权值大,但比较稀疏,毕竟进行显示反馈的用户是少数;同时相对于“查看”,“购买”行为反映用户喜爱的程度更大,但这也因应用而异。

收集了用户行为数据,咱们还须要对数据进行必定的预处理,其中最核心的工做就是:减噪和归一化。

  • 减噪:用户行为数据是用户在使用应用过程当中产生的,它可能存在大量的噪音和用户的误操做,咱们能够经过经典的数据挖掘算法过滤掉行为数据中的噪音,这样能够是咱们的分析更加精确。
  • 归一化:如前面讲到的,在计算用户对物品的喜爱程度时,可能须要对不一样的行为数据进行加权。但能够想象,不一样行为的数据取值可能相差很大,好比,用户的查看数据必然比购买数据大的多,如何将各个行为的数据统一在一个相同的取值范围中,从而使得加权求和获得的整体喜爱更加精确,就须要咱们进行归一化处理。最简单的归一化处理,就是将各种数据除以此类中的最大值,以保证归一化后的数据取值在 [0,1] 范围中。

  进行的预处理后,根据不一样应用的行为分析方法,能够选择分组或者加权处理,以后咱们能够获得一个用户偏好的二维矩阵,一维是用户列表,另外一维是物品列表,值是用户对物品的偏好,通常是 [0,1] 或者 [-1, 1] 的浮点数值。

2.2 找到类似的用户或物品

  当已经对用户行为进行分析获得用户喜爱后,咱们能够根据用户喜爱计算类似用户和物品,而后基于类似用户或者物品进行推荐,这就是最典型的 CF 的两个分支:基于用户的 CF 和基于物品的 CF。这两种方法都须要计算类似度,下面咱们先看看最基本的几种计算类似度的方法。

  类似度的计算

  关于类似度的计算,现有的几种基本方法都是基于向量(Vector)的,其实也就是计算两个向量的距离,距离越近类似度越大。在推荐的场景中,在用户 - 物品偏好的二维矩阵中,咱们能够将一个用户对全部物品的偏好做为一个向量来计算用户之间的类似度,或者将全部用户对某个物品的偏好做为一个向量来计算物品之间的类似度。下面咱们详细介绍几种经常使用的类似度计算方法:

  • 欧几里德距离(Euclidean Distance)

  最初用于计算欧几里德空间中两个点的距离,假设 x,y 是 n 维空间的两个点,它们之间的欧几里德距离是:

Figure xxx. Requires a heading

  能够看出,当 n=2 时,欧几里德距离就是平面上两个点的距离。

  当用欧几里德距离表示类似度,通常采用如下公式进行转换:距离越小,类似度越大

Figure xxx. Requires a heading

  • 皮尔逊相关系数(Pearson Correlation Coefficient)

  皮尔逊相关系数通常用于计算两个定距变量间联系的紧密程度,它的取值在 [-1,+1] 之间。

Figure xxx. Requires a heading

sx, sy是 x 和 y 的样品标准误差。

  • Cosine 类似度(Cosine Similarity)

  Cosine 类似度被普遍应用于计算文档数据的类似度:

Figure xxx. Requires a heading

  • Tanimoto 系数(Tanimoto Coefficient)

  Tanimoto 系数也称为 Jaccard 系数,是 Cosine 类似度的扩展,也多用于计算文档数据的类似度:

Figure xxx. Requires a heading

  类似邻居的计算

  介绍完类似度的计算方法,下面咱们看看如何根据类似度找到用户 - 物品的邻居,经常使用的挑选邻居的原则能够分为两类:图 1 给出了二维平面空间上点集的示意图。

  • 固定数量的邻居:K-neighborhoods 或者 Fix-size neighborhoods

  不论邻居的“远近”,只取最近的 K 个,做为其邻居。如图 1 中的 A,假设要计算点 1 的 5- 邻居,那么根据点之间的距离,咱们取最近的 5 个点,分别是点 2,点 3,点 4,点 7 和点 5。但很明显咱们能够看出,这种方法对于孤立点的计算效果很差,由于要取固定个数的邻居,当它附近没有足够多比较类似的点,就被迫取一些不太类似的点做为邻居,这样就影响了邻居类似的程度,好比图 1 中,点 1 和点 5 其实并非很类似。

  • 基于类似度门槛的邻居:Threshold-based neighborhoods

  与计算固定数量的邻居的原则不一样,基于类似度门槛的邻居计算是对邻居的远近进行最大值的限制,落在以当前点为中心,距离为 K 的区域中的全部点都做为当前点的邻居,这种方法计算获得的邻居个数不肯定,但类似度不会出现较大的偏差。如图 1 中的 B,从点 1 出发,计算类似度在 K 内的邻居,获得点 2,点 3,点 4 和点 7,这种方法计算出的邻居的类似度程度比前一种优,尤为是对孤立点的处理。

图 1.类似邻居计算示意图
图 1 类似邻居计算示意图

2.3 计算推荐

  通过前期的计算已经获得了相邻用户和相邻物品,下面介绍如何基于这些信息为用户进行推荐。本系列的上一篇综述文章已经简要介绍过基于协同过滤的推荐算法能够分为基于用户的 CF 和基于物品的 CF,下面咱们深刻这两种方法的计算方法,使用场景和优缺点。

  基于用户的 CF(User CF)

  基于用户的 CF 的基本思想至关简单,基于用户对物品的偏好找到相邻邻居用户,而后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对全部物品的偏好做为一个向量来计算用户之间的类似度,找到 K 邻居后,根据邻居的类似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算获得一个排序的物品列表做为推荐。图 2 给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算获得一个邻居 - 用户 C,而后将用户 C 喜欢的物品 D 推荐给用户 A。

图 2.基于用户的 CF 的基本原理
图 2 基于用户的 CF 的基本原理

  基于物品的 CF(Item CF)

  基于物品的 CF 的原理和基于用户的 CF 相似,只是在计算邻居时采用物品自己,而不是从用户的角度,即基于用户对物品的偏好找到类似的物品,而后根据用户的历史偏好,推荐类似的物品给他。从计算的角度看,就是将全部用户对某个物品的偏好做为一个向量来计算物品之间的类似度,获得物品的类似物品后,根据用户历史的偏好预测当前用户尚未表示偏好的物品,计算获得一个排序的物品列表做为推荐。图 3 给出了一个例子,对于物品 A,根据全部用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较类似,而用户 C 喜欢物品 A,那么能够推断出用户 C 可能也喜欢物品 C。

图 3.基于物品的 CF 的基本原理
图 3 基于物品的 CF 的基本原理

  User CF vs. Item CF

  前面介绍了 User CF 和 Item CF 的基本原理,下面咱们分几个不一样的角度深刻看看它们各自的优缺点和适用场景:

  • 计算复杂度

  Item CF 和 User CF 是基于协同过滤推荐的两个最基本的算法,User CF 是很早之前就提出来了,Item CF 是从 Amazon 的论文和专利发表以后(2001 年左右)开始流行,你们都以为 Item CF 从性能和复杂度上比 User CF 更优,其中的一个主要缘由就是对于一个在线网站,用户的数量每每大大超过物品的数量,同时物品的数据相对稳定,所以计算物品的类似度不但计算量较小,同时也没必要频繁更新。但咱们每每忽略了这种状况只适应于提供商品的电子商务网站,对于新闻,博客或者微内容的推荐系统,状况每每是相反的,物品的数量是海量的,同时也是更新频繁的,因此单从复杂度的角度,这两个算法在不一样的系统中各有优点,推荐引擎的设计者须要根据本身应用的特色选择更加合适的算法。

  • 适用场景

  在非社交网络的网站中,内容内在的联系是很重要的推荐原则,它比基于类似用户的推荐原则更加有效。好比在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关的书籍,这个推荐的重要性远远超过了网站首页对该用户的综合推荐。能够看到,在这种状况下,Item CF 的推荐成为了引导用户浏览的重要手段。同时 Item CF 便于为推荐作出解释,在一个非社交网络的网站中,给某个用户推荐一本书,同时给出的解释是某某和你有类似兴趣的人也看了这本书,这很难让用户信服,由于用户可能根本不认识那我的;但若是解释说是由于这本书和你之前看的某本书类似,用户可能就以为合理而采纳了此推荐。

  相反的,在现今很流行的社交网络站点中,User CF 是一个更不错的选择,User CF 加上社会网络信息,能够增长用户对推荐解释的信服程度。

  • 推荐多样性和精度

  研究推荐引擎的学者们在相同的数据集合上分别用 User CF 和 Item CF 计算推荐结果,发现推荐列表中,只有 50% 是同样的,还有 50% 彻底不一样。可是这两个算法确有类似的精度,因此能够说,这两个算法是很互补的。

关于推荐的多样性,有两种度量方法:

  第一种度量方法是从单个用户的角度度量,就是说给定一个用户,查看系统给出的推荐列表是否多样,也就是要比较推荐列表中的物品之间两两的类似度,不难想到,对这种度量方法,Item CF 的多样性显然不如 User CF 的好,由于 Item CF 的推荐就是和之前看的东西最类似的。

  第二种度量方法是考虑系统的多样性,也被称为覆盖率 (Coverage),它是指一个推荐系统是否可以提供给全部用户丰富的选择。在这种指标下,Item CF 的多样性要远远好于 User CF, 由于 User CF 老是倾向于推荐热门的,从另外一个侧面看,也就是说,Item CF 的推荐有很好的新颖性,很擅长推荐长尾里的物品。因此,尽管大多数状况,Item CF 的精度略小于 User CF, 但若是考虑多样性,Item CF 却比 User CF 好不少。

  若是你对推荐的多样性还心存疑惑,那么下面咱们再举个实例看看 User CF 和 Item CF 的多样性到底有什么差异。首先,假设每一个用户兴趣爱好都是普遍的,喜欢好几个领域的东西,不过每一个用户确定也有一个主要的领域,对这个领域会比其余领域更加关心。给定一个用户,假设他喜欢 3 个领域 A,B,C,A 是他喜欢的主要领域,这个时候咱们来看 User CF 和 Item CF 倾向于作出什么推荐:若是用 User CF, 它会将 A,B,C 三个领域中比较热门的东西推荐给用户;而若是用 ItemCF,它会基本上只推荐 A 领域的东西给用户。因此咱们看到由于 User CF 只推荐热门的,因此它在推荐长尾里项目方面的能力不足;而 Item CF 只推荐 A 领域给用户,这样他有限的推荐列表中就可能包含了必定数量的不热门的长尾物品,同时 Item CF 的推荐对这个用户而言,显然多样性不足。可是对整个系统而言,由于不一样的用户的主要兴趣点不一样,因此系统的覆盖率会比较好。

  从上面的分析,能够很清晰的看到,这两种推荐都有其合理性,但都不是最好的选择,所以他们的精度也会有损失。其实对这类系统的最好选择是,若是系统给这个用户推荐 30 个物品,既不是每一个领域挑选 10 个最热门的给他,也不是推荐 30 个 A 领域的给他,而是好比推荐 15 个 A 领域的给他,剩下的 15 个从 B,C 中选择。因此结合 User CF 和 Item CF 是最优的选择,结合的基本原则就是当采用 Item CF 致使系统对我的推荐的多样性不足时,咱们经过加入 User CF 增长我的推荐的多样性,从而提升精度,而当由于采用 User CF 而使系统的总体多样性不足时,咱们能够经过加入 Item CF 增长总体的多样性,一样一样能够提升推荐的精度。

  • 用户对推荐算法的适应度

  前面咱们大部分都是从推荐引擎的角度考虑哪一个算法更优,但其实咱们更多的应该考虑做为推荐引擎的最终使用者 -- 应用用户对推荐算法的适应度。

  对于 User CF,推荐的原则是假设用户会喜欢那些和他有相同喜爱的用户喜欢的东西,但若是一个用户没有相同喜爱的朋友,那 User CF 的算法的效果就会不好,因此一个用户对的 CF 算法的适应度是和他有多少共同喜爱用户成正比的。

  Item CF 算法也有一个基本假设,就是用户会喜欢和他之前喜欢的东西类似的东西,那么咱们能够计算一个用户喜欢的物品的自类似度。一个用户喜欢物品的自类似度大,就说明他喜欢的东西都是比较类似的,也就是说他比较符合 Item CF 方法的基本假设,那么他对 Item CF 的适应度天然比较好;反之,若是自类似度小,就说明这个用户的喜爱习惯并不知足 Item CF 方法的基本假设,那么对于这种用户,用 Item CF 方法作出好的推荐的可能性很是低。

3. 基于KNN的协同过滤推荐算法MATLAB实现

  邻居模型一般也被称为k-最近邻模型,或者简称为kNN。KNN 模型能够得到精确的推荐结果并为结果给出合理的解释,它们是CF 推荐系统中最先被使用也是直至目前最流行的一类模型。

  PS:如下公式和图片转自博主本身的CSDN博客。

  为了得到用户对产品的评分预测值,kNN 模型通常包括如下三步:

  1. 计算类似度
  这步中计算每对产品之间的类似度(similarity)。一些被普遍使用的类似度
  测度包括:
  Pearson correlation:

  其中¯rm 和¯rn 分别表示电影m 和n 得到的评分平均值,而Pmn 表示对电影m 和n 都提供了评分的用户集合,也即Pmn = Pm ∩ Pn 。
  Cosine:
  Adjusted Cosine:
  其中¯rv 表示用户v 的评分平均值。
  2. 选择邻居
  为了预测用户u 对电影m 的评分值,咱们首先从Pu 中选取与电影m有最高类似度的特定数量的电影,这些电影造成u−m 对的邻居(neighborhood),记为N(m; u) 。
  3. 产生预测值
  用户u 对电影m 的评分预测为上步得到的邻居N(m; u) 中评分的加权平均值:
  其中bu;n 为用户u 对电影n 的基准预测评分。这里的基准模型能够是任何能够产生预测评分的模型。
  按照上述过程,在MATLAB仿真环境下获得的RMSE=1.0776,这里取得邻居个数为10。
  下图为邻居个数的选取(0~20)对RMSE的影响曲线:
 
%% 载入训练数据
 load g:\matlab\协同过滤作推荐\dataset\Movielens\u1.base
%% 数据预处理 
%  提取数据的前三列,即用户序号、被该用户评价电影序号、评价分值
[m,n]=size(u1);
test=zeros(m,3);
for i=1:3
    test(:,i)=u1(:,i);
end
%% 创建评分矩阵
number_user=max(test(:,1));
number_movies=max(test(:,2));
score_matrix=zeros(number_user,number_movies);%评分矩阵943*1682维
for i=1:m
    score_matrix(test(i,1),test(i,2))=test(i,3);
end
Sim_matrix=zeros(number_movies,number_movies);%类似度矩阵1642*1642维
tic;
%计算评分矩阵
for i=1:number_movies-1
    for j=i+1:number_movies
        Sim_matrix(i,j)=Similarity_ab(score_matrix,i,j);
    end
end
toc;
%% 创建类似度矩阵
% function Neibor=neibor_select(Sim_matrix,a,n)
neibor_num=10;%邻居的大小
Sim_matrix=Sim_matrix'+Sim_matrix;%求完整的类似度矩阵
%neibor_sim_matrix_temp为排好序的类似度矩阵
%neibor_matrix_temp各个类似度所对应的电影,也就是咱们要找的邻居
value_1_index=find(Sim_matrix>=0.9999);%找出Sim_matrix矩阵中全部类似度为1的值,
                                       %由于多是错误值,后期选择邻居不该考虑。
%为何不是value_1_index=find(Sim_matrix==1)这样有部分1不能正确找出,能够试试看
Sim_matrix(value_1_index)=0;%将全部类似度为1的值用0代替
% [neibor_sim_matrix_temp,neibor_matrix_temp]=sort(Sim_matrix,2,'descend');
% neibor_sim_matrix=zeros(number_movies,neibor_num);
% neibor_matrix=zeros(number_movies,neibor_num);
% for i=1:neibor_num
%     neibor_sim_matrix(:,i)=neibor_sim_matrix_temp(:,i);%每一个邻居对应的类似度
%     neibor_matrix(:,i)=neibor_matrix_temp(:,i);%邻居
% end
%% 载入测试集
load g:\matlab\协同过滤作推荐\dataset\Movielens\u1.test
%% 做预测
[m,n]=size(u1);
test=zeros(m,3);
for i=1:3
    test(:,i)=u1(:,i);
end
Predict_score=zeros(m,1);
for j=1:m
P_u=find(score_matrix(test(j,1),:)~=0);%找出该用户评价的电影集合
[~,num]=size(P_u);%计算该用户评价的电影个数
%%%%%%%%%%%计算邻居%%%%%%%%%%%%
neibor_num=10;%最大为4
P_u_sim=Sim_matrix(test(j,2),P_u);
[temp,index]=sort(P_u_sim,2,'descend');
[~,num1]=size(index);
if num1>=neibor_num 
neibor=(P_u(index(1:neibor_num)));
else
    neibor=(P_u(index));
    neibor_num=num1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sum_score=sum(score_matrix(test(j,1),:),2);%该用户对全部电影的总评分
aver_score=sum_score/num;%该用户对电影的平均评分
sum1=0;
sum2=0;
for i=1:neibor_num
    sum1=sum1+Sim_matrix(test(j,2),neibor(i))*(score_matrix(test(j,1),neibor(i))-aver_score);
    sum2=sum2+Sim_matrix(test(j,2),neibor(i));
end
if sum2==0
    Predict_score(j,1)=round(aver_score);%排除分母为零的状况
else
Predict_score(j,1)=round(aver_score+sum1/sum2);
%确保预测值为1~5的评分数
if Predict_score(j,1)>5
    Predict_score(j,1)=5;
elseif Predict_score(j,1)<1
    Predict_score(j,1)=1;
end
end
end
%% 计算RMSE
Eval=zeros(m,3);
Eval(:,1)=test(:,3);
Eval(:,2)=Predict_score(:,1);
Eval(:,3)=abs(test(:,3)-Predict_score(:,1));
RMSE=sqrt(Eval(:,3)'*Eval(:,3)/m);

  Similarity_ab()函数的实现(PS:好久以前写的程序,发现有几位博友找我要相关代码看一下,我尽可能找了找,仅供感兴趣的同窗参考,不喜勿喷哈,更新时间 2016.07.11晚):

%利用Adjusted Cosine法计算电影a和b的类似度
%这个算法虽然能够求出类似度矩阵,可是有个问题就是,当共同评价电影a和b的用户
%只有一个的时候,结果只有两种可能,即1或者是-1。这就须要在找邻居时要避免选择
%这些状况的类似度电影。
function Sim_ab=Similarity_ab(score_matrix,a,b)
%找出全部评价所电影a和b的用户集合(标号)
%function P_ab=Rate_both_ab(score_matrix,a,b)
temp=score_matrix(:,a)&score_matrix(:,b);
P_ab=find(temp);
P_ab=P_ab';%用行向量存储全部评价电影a和b的用户
%end
%% 利用Adjusted Cosine法计算类似度
if isempty(P_ab)
    Sim_ab=0;
else
    [~,temp]=size(P_ab);%共同评价电影a和b的用户的数目
    %[~,number_movies]=size(score_matrix);
    sum1=0;
    sum2=0;
    sum3=0;
    for i=1:temp
        [~,m]=size(find(score_matrix(P_ab(i),:)~=0));%计算该用户评价的电影个数
        sum_score=sum(score_matrix(P_ab(i),:),2);%用户对全部电影的总评分
        aver_score=sum_score/m;
        sum1=sum1+(score_matrix(P_ab(i),a)-aver_score)*(score_matrix(P_ab(i),b)-aver_score);
        sum2=sum2+(score_matrix(P_ab(i),a)-aver_score)^2;
        sum3=sum3+(score_matrix(P_ab(i),b)-aver_score)^2;
    end
    if sum2==0||sum3==0
        Sim_ab=0;
    else
        Sim_ab=sum1/sqrt(sum2*sum3);
    end
end
  协同过滤的缺点是:
  (1)用户对商品的评价很是稀疏,这样基于用户的评价所获得的用户间的类似性可能不许确(即稀疏性问题);
  (2)随着用户和商品的增多,系统的性能会愈来愈低;
  (3)若是历来没有用户对某一商品加以评价,则这个商品就不可能被推荐(即最初评价问题)。

4. 总结

  Web2.0 的一个核心思想就是“集体智慧”,基于协同过滤的推荐策略的基本思想就是基于大众行为,为每一个用户提供个性化的推荐,从而使用户能更快速更准确的发现所须要的信息。从应用角度分析,现今比较成功的推荐引擎,好比 Amazon,豆瓣,当当等都采用了协同过滤的方式,它不须要对物品或者用户进行严格的建模,并且不要求物品的描述是机器可理解的,是中领域无关的推荐方法,同时这个方法计算出来的推荐是开放的,能够共用他人的经验,很好的支持用户发现潜在的兴趣偏好。基于协同过滤的推荐策略也有不一样的分支,它们有不一样的实用场景和推荐效果,用户能够根据本身应用的实际状况选择合适的方法,异或组合不一样的方法获得更好的推荐效果。

5. 参考资料

相关文章
相关标签/搜索