在现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法。它以其方法模型简单,数据依赖性低,数据方便采集 , 推荐效果较优等多个优点成为大众眼里的推荐算法“No.1”。本文将带你深入了解协同过滤的秘密,后续将给出基于 Apache Mahout 的协同过滤算法的高效实现。
推荐中的协同过滤算法简单说明下:
首先,通过分析用户的偏好行为,来挖掘出里面物品与物品、或人与人之间的关联。
其次,通过对这些关联的关系做一定的运算,得出人与物品间喜欢程度的猜测,即推荐值。
最后,将推荐值高的物品推送给特定的人,以完成一次推荐。
协同过滤算法大致可分为两类,基于物品的与基于用户的;区分很简单,根据上面的逻辑,若你挖掘的关系是物品与物品间的,就是基于物品的协同过滤算法,若 你挖掘的关系是用户与用户间的,就是基于用户的协同过滤算法;由于它们实现是有所不同,所以我分开整理,先来看看基于物品的协同过滤实现,我自己画了一幅 图:
我通过数字的顺序,来标示数据变化的方向(由小到大);下面分析下每一个步骤的功能以及实现。
首先,说明下两个大的数据源,用户偏好数据:UserID、ItemID、Preference:表示一个对一个物品的喜好程度;关系数据:ItemIDA(UserIDA)、ItemIDB(UserIDB)、Similarity:表示两个人或物品间的相似程度;接着一个用户来了,我们需要为其推荐,得拿到他的身份标示,一般是UserID,于是:
①. 查找这个用户喜欢过的物品(即偏好的产品,并查出偏好值后面会用),以及还没有喜欢过的商品,前者是推荐运算的根据,后者作为一个产生推荐的一个集合;如② 画的那样。
②. 这里是一个可扩展的地方(我自己理解);因为这两部分的数据的作用非常明显,修改这两个集合对后面产生的推荐结果可产生非常直观的影响,比如清洗过滤,或根据用户属性缩小集合;不仅使后面推荐效果更优,运算性能也可以大幅度提高。
③. 查找这两个集合之间的关系,这是一对多的关系:一个没有偏好过的物品与该用户所有偏好过的物品间的关系,有一个值来衡量这个关系叫相似度Similarity;这个关系怎么来的,看蓝色箭头的指向。步骤⑥
④. 得到这个一对多的关系后,就可以计算这个物品对于这个用户的推荐值了,图中similarity_i-x表示Item_i 与 Item_x 之间的相似度,Item_x是该用户偏好过得,该用户对其偏好值记为 value_x ,相乘;Item_i 与 该用户偏好过的所有物品以此做以上运算后,得到的值取平均值 便是 Item_i的推荐值了。注:有可能Item_i 不是与所有 该用户偏好过的物品都都存在相似性,不存在的,不计算即可;另外这里方便理解介绍的都是最简单的实现;你也可以考一些复杂的数学元素,比如方差来判断离散 性等。
⑤. 这步就简单多了,刚才对该用户没有偏好过的集合中的所有Item都计算了推荐值,这里就会得到一个list,按推荐值由大到小排序,返回前面的一个子集即可。
⑥。 前面已经提到,关系数据时怎么来的,也是根据用户的偏好数据;你把其看成一个矩阵,横着看过来,参考两个Item间的共同用户,以及共同用户的偏好的值的接近度;这里的可选择的相似度算法很多,不一一介绍了,前面提到的IBM博客也详细讲解了。
基于物品的协同过滤算法分析完了,下面是基于用户的协同过滤算法,还是自己画了一幅图:
①. 同样也是查询,只是查询的对象不一样了,查询的是与该用户相似的用户,所以一来直接查了关系数据源。以及相似用户与该用户的相似度。
②. 与刚才类似,也是对数据集的一个优化,不过作用可能没那么大。(个人感觉)
③. 查询关系数据源,得到相似用户即邻居偏好过的物品;如步骤④;图中由于空间小,没有把所有邻居的偏好关系都列出来,用……表示。其次还要得到该用户偏好过的物品集合。
④. 被推荐的Item集合是由该用户的所有邻居的偏好过的物品的并集,同时再去掉该用户自己偏好过的物品。作用就是得到你的相似用户喜欢的物品,而你还没喜欢过的。
⑤. 集合优化同基于物品的协同过滤算法的步骤②。
⑥. 也是对应类似的,依次计算被推荐集合中Item_i 的推荐值,计算的方式略有不同,Value_1_i表示邻居1对,Item_i的偏好值,乘以该用户与邻居1的相似度 Similarity1;若某个邻居对Item_i偏好过,就重复上述运算,然后取平均值;得到Item_i的推荐值。
⑦、⑧. 与上一个算法的最后两部完全类似,只是步骤 ⑧你竖着看,判断两个用户相似的法子和判断两个物品相似的法子一样。