离回学校的日子又近了一天,用大四整整一年出来实习,仔细想想,2018年7月来的深圳,实习了三个月,然后就找工作找了一周多吧,在2018年10月多参加了培训,为期三个月,然后过年回家一个月,找工作一个多月,然后就开始工作,也差不多一个月,算一下,在毕业之前相当于实习了四个月,也还行吧。回到学校之后,就开始写论文,然后去见朋友,去玩,去吃,记得,每当学姐学长答辩完,就会在各自的宿舍楼下摆出自己大学四年的书,然后就开始卖,当时也想过,等我毕业的时候,我也要这样做,现在有机会了,心里五味杂陈,期待那天。
好像,现在最记忆犹新的还是第一份实习工作。
推荐算法———基于物品的协同过滤算法
算法的核心思想是:给用户推荐那些和他们之前喜欢的物品相似的物品。
比如,用户A之前买过《数据挖掘导论》,该算法会根据此行为给你推荐《机器学习》,但是ItemCF算法并不利用物品的内容属性计算物品之间的相似度,它主要通过分析用户的行为记录计算物品之间的相似度。
==>该算法认为,物品A和物品B具有很大的相似度是因为喜欢物品A的用户大都也喜欢物品B。
基于物品的协同过滤算法主要分为两步:
1.计算物品之间的相似度;
2.根据物品的相似度和用户的历史行为给用户生成推荐列表。
下面分别来看这两步如何计算:
1.计算物品之间的相似度:
我们使用下面的公式定义物品的相似度:
其中,|N(i)|是喜欢物品i的用户数,|N(j)|是喜欢物品j的用户数,|N(i)&N(j)|是同时喜欢物品i和物品j的用户数。分母是惩罚物品i和j的权重,因此惩罚了热门物品和很多物品相似的可能性。
从上面的定义看出,在协同过滤中两个物品产生相似度是因为它们共同被很多用户喜欢,两个物品相似度越高,说明这两个物品共同被很多人喜欢。
这里面蕴含着一个假设:就是假设每个用户的兴趣都局限在某几个方面,因此如果两个物品属于一个用户的兴趣列表,那么这两个物品可能就属于有限的几个领域,而如果两个物品属于很多用户的兴趣列表,那么它们就可能属于同一个领域,因而有很大的相似度。
举例,用户A对物品a、b、d有过行为,用户B对物品b、c、e有过行为,等等;
依次构建用户——物品倒排表:物品a被用户A、E有过行为,等等;
建立物品相似度矩阵C:
其中,C[i][j]记录了同时喜欢物品i和物品j的用户数,这样我们就可以得到物品之间的相似度矩阵W。
在得到物品之间的相似度后,进入第二步。
2.根据物品的相似度和用户的历史行为给用户生成推荐列表:
ItemCF通过如下公式计算用户u对一个物品j的兴趣:
这里N(u)是用户喜欢的物品的集合,S(j,K)是和物品j最相似的K个物品的集合,wji是物品j和i 的相似度,rui是用户u对物品i的兴趣。(对于隐反馈数据集,如果用户u对物品i有过行为,即可令 rui=1。)
该公式的含义是,和用户历史上感兴趣的物品越相似的物品,越有可能在用户的推荐列 表中获得比较高的排名。
下面是一个基于物品推荐的简单例子。
该例子中,用户喜欢《C++ Primer中文版》和《编 程之美》两本书。然后ItemCF会为这两本书分别找出和它们最相似的3本书,然后根据公式的定 义计算用户对每本书的感兴趣程度。比如,ItemCF给用户推荐《算法导论》,是因为这本书和《C++ Primer中文版》相似,相似度为0.4,而且这本书也和《编程之美》相似,相似度是0.5。考虑到 用户对《C++ Primer中文版》的兴趣度是1.3,对《编程之美》的兴趣度是0.9,那么用户对《算 法导论》的兴趣度就是1.3 × 0.4 + 0.9×0.5 = 0.97。
从这个例子可以看到,ItemCF的一个优势就是可以提供推荐解释,即利用用户历史上喜欢的 物品为现在的推荐结果进行解释。
推荐系统实践
下表给出了各项性能指标的评测结果,该表包括算法在不同k值(和用户喜欢的物品相似度高的前k个视频)下的性能。
数据集中itemCF算法离线实验的结果
K 准 确 率 召 回 率覆 盖 率 流 行 度
5 21.47% 10.37% 21.74%7.172411
10 22.28% 10.76% 18.84% 7.254526
20 22.24% 10.74% 16.93% 7.338615
40 21.68% 10.47% 15.31% 7.391163
80 20.64% 9.97% 13.64% 7.413358
160 19.37% 9.36% 11.77% 7.385278
精度(准确率和召回率) 可以看到ItemCF推荐结果的精度也是不和K成正相关或者负相 关的,因此选择合适的K对获得最高精度是非常重要的。
流行度 和UserCF不同,参数K对ItemCF推荐结果流行度的影响也不是完全正相关的。 随着K的增加,结果流行度会逐渐提高,但当K增加到一定程度,流行度就不会再有明显 变化。
覆盖率 K增加会降低系统的覆盖率。
下面是书中提到的几个优化方法:
(1)用户活跃度对物品相似度的影响
从前面的讨论可以看到,在协同过滤中两个物品产生相似度是因为它们共同出现在很多用户
的兴趣列表中。换句话说,每个用户的兴趣列表都对物品的相似度产生贡献。那么,是不是每个 用户的贡献都相同呢?
假设有这么一个用户,他是开书店的,并且买了当当网上80%的书准备用来自己卖。那么, 他的购物车里包含当当网80%的书。假设当当网有100万本书,也就是说他买了80万本。从前面 对ItemCF的讨论可以看到,这意味着因为存在这么一个用户,有80万本书两两之间就产生了相似 度,也就是说,内存里即将诞生一个80万乘80万的稠密矩阵。 另外可以看到,这个用户虽然活跃,但是买这些书并非都是出于自身的兴趣,而且这些书覆 盖了当当网图书的很多领域,所以这个用户对于他所购买书的两两相似度的贡献应该远远小于一 个只买了十几本自己喜欢的书的文学青年。 John S. Breese在论文①中提出了一个称为IUF(Inverse User Frequence),即用户活跃度对数的 倒数的参数,他也认为活跃用户对物品相似度的贡献应该小于不活跃的用户,他提出应该增加IUF 参数来修正物品相似度的计算公式:
用这种相似度计算的ItemCF被记为ItemCF-IUF。
ItemCF-IUF在准确率和召回率两个指标上和ItemCF相近,但它明显提高了推荐结果的覆盖率,降低了推荐结果的流行度,从这个意义上说,ItemCF-IUF确实改进了ItemCF的综合性能。
流行度: 基于流行度的算法非常简单粗暴,类似于各大新闻、微博热榜等,根据PV、UV、日均PV或分享率等数据来按某种热度排序来推荐给用户。 这种算法的优点是简单,适用于刚注册的新用户。缺点也很明显,它无法针对用户提供个性化的推荐。基于这种算法也可做一些优化,比如加入用户分群的流行度排序,例如把热榜上的体育内容优先推荐给体育迷,把政要热文推给热爱谈论政治的用户。
当然,上面的公式只是对活跃用户做了一种软性的惩罚,但对于很多过于活跃的用户,比如 上面那位买了当当网80%图书的用户,为了避免相似度矩阵过于稠密,我们在实际计算中一般直 接忽略他的兴趣列表,而不将其纳入到相似度计算的数据集中。
(2)物品相似度的归一化:
Karypis在研究中发现如果将ItemCF的相似度矩阵按最大值归一化,可以提高推荐的准确率。① 其研究表明,如果已经得到了物品相似度矩阵w,那么可以用如下公式得到归一化之后的相似度 矩阵w':
其实,归一化的好处不仅仅在于增加推荐的准确度,它还可以提高推荐的覆盖率和多样性。
一般来说,物品总是属于很多不同的类,每一类中的物品联系比较紧密。举一个例子,假设在一个电影网站中,有两种电影——纪录片和动画片。那么,ItemCF算出来的相似度一般是纪录片和 纪录片的相似度或者动画片和动画片的相似度大于纪录片和动画片的相似度。但是纪录片之间的 相似度和动画片之间的相似度却不一定相同。假设物品分为两类——A和B,A类物品之间的相似 度为0.5,B类物品之间的相似度为0.6,而A类物品和B类物品之间的相似度是0.2。在这种情况下, 如果一个用户喜欢了5个A类物品和5个B类物品,用ItemCF给他进行推荐,推荐的就都是B类物品, 因为B类物品之间的相似度大。但如果归一化之后,A类物品之间的相似度变成了1,B类物品之 间的相似度也是1,那么这种情况下,用户如果喜欢5个A类物品和5个B类物品,那么他的推荐列 表中A类物品和B类物品的数目也应该是大致相等的。从这个例子可以看出,相似度的归一化可 以提高推荐的多样性。 那么,对于两个不同的类,什么样的类其类内物品之间的相似度高,什么样的类其类内物品 相似度低呢?一般来说,热门的类其类内物品相似度一般比较大。如果不进行归一化,就会推荐 比较热门的类里面的物品,而这些物品也是比较热门的。因此,推荐的覆盖率就比较低。相反, 如果进行相似度的归一化,则可以提高推荐系统的覆盖率。