cf算法全称“Collaborative Filtering”,即协同过滤算法。协同过滤算法是非常强大与成熟(古老)的一套算法。它广泛应用于电子商务系统等领域。 协同过滤算法的出现标志着推荐系统的产生。
协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息。
关于协同过滤的一个最经典的例子就是看电影,有时候不知道哪一部电影是我们喜欢的或者评分比较高的,那么通常的做法就是问问周围的朋友,看看最近有什么好的电影推荐。在问的时候,都习惯于问跟自己口味差不 多的朋友,这就是协同过滤的核心思想。
协同过滤算法又分为基于用户的协同过滤算法和基于物品的协同过滤算法。
协同过滤是在海量数据中挖掘出小部分与你品味类似的用户,在协同过滤中,这些用户成为邻居,然后根据他们喜欢的东西组织成一个排序的目录推荐给你。所以就有如下两个核心问题:
(1)如何确定一个用户是否与你有相似的品味?
(2)如何将邻居们的喜好组织成一个排序目录?
问题一:如何确定一个用户是否与你有相似的品味
这个问题等同于如何计算用户(物品)相似度。在深度学习的相似性度量中,大体有十一个参数。
可参考:机器学习中的相似性度量。
在CF算法中,使用Jaccard系数、皮尔逊相关系数、欧几里得距离和余弦距离。在这里,我选择的是余弦距离来度量用户之间的相似度。
余弦系数计算公式如下:
其实这个公式代码实现起来并不难,难的是能将上图中的矩阵求出来。
这个矩阵对应的是每一个user的向量同时也对应着每一个item的向量。通过user的向量之间余弦的计算,我们就可以度量出user之间的相似度了。
理解User-CF典型的就是我想看电影的时候,一定是找我身边和我相似的人来推荐,我们就是一个相似的群体。
理解Item-CF典型的就是啤酒尿布,在内部两个没有关联关系,但是在用户行为上它们的余弦值就非常大(相似度非常高)。
同时,Item-CF也可以通过Item本身内部的属性出一个多维的向量值,即他们内部的关联关系,就比如《推荐系统实现》、《算法导论》两本书在内部就有很大的相似性。当用户买《推荐系统实现》这本书的时候,我们可以也有理由去推荐《算法导论》。如果完全根据用户行为维度来描述item,就可能出现我买《算法导论》的时候,会给我推荐《男人装》(随便举的例子)之类的。这有可能引起用户的极度反感。
问题二:如何将邻居们的喜好组织成一个排序目录
目前我们公司团队使用的是gbdt模型训练,将邻居们的喜好传入模型,训练得出一个score,根据score值进行排序。
暂时不对这一块进行整理了,暂时没有接触到,有兴趣的小伙伴可以自行查看。
下面我具体介绍一下我使用真实的用户日志数据进行用户cf策略计算的过程。
首先,我通过hadoop对最近十天的日志数据进行了提取,提取出了用户看过哪些新闻。数据样例如下:
其次,我去查找了这些新闻的特征(也可以直接用新闻作为坐标来生成矩阵,这个只是与力度有关,效果好坏后期探索)。
近6000条新闻涉及到的tags总共有2600多个,很大一部分tags是某条新闻专有的,所以只取涉及到的新闻多的tags来形成矩阵。
将user-doc转为user-tags,生成矩阵如下:
有了矩阵,就可以按照上述的余弦求解公式来求解了。
函数如下:
def cosine_similarity(vector1, vector2):
dot_product = 0.0
normA = 0.0
normB = 0.0
for a, b in zip(vector1, vector2):
dot_product += a * b
normA += a ** 2
normB += b ** 2
if normA == 0.0 or normB == 0.0:
return 0
else:
return round(dot_product / ((normA ** 0.5) * (normB ** 0.5)) * 100, 2)
传入的两个参数,就是各个用户针对于各个便签行为的向量。
取其中某一个用户,通过余弦值可以得出与他最为相似的一批用户。具体计算结果如下:
结果乘以100用于展示。