前面我们简单介绍了基于内容的推荐系统CB和基于协同过滤的推荐系统CF,让我们看一下CF的一些实际例子。
让我们看一下元数据。数据很简单:userId(用户ID)、itemId(商品ID)、score(用户得分),用\’,\’分隔。
计算时,使用以下相似度计算公式。这个公式其实和cos相似度的公式是一样的。
在:
Wi,j 表示标记为i 和j 的两个项目的相似度
U(i,j) 表示同时评估i 和j 的用户集合
ruj 表示用户u 对项目i 的评分
是平滑参数
事实上,使用这个你可以将分子和分母乘法的后半部分作为常数丢弃,并且不会影响结果。那么计算的时候只能看到前半部分。分析表明,每个用户的分母相同,是i的所有用户得分的平方和乘以所有用户的得分。对于j i 的评估的平方和,分子是i 和j 的乘积。如果我们将分母分开,我们可以看到它实际上是所有用户评分的平方和除以i。将所有用户对i 的评分平方和(相当于统一标准化)乘以您对i 的评分,再乘以对i 的所有用户评分的平方和。由此看来,代码的实现就非常容易了。
这是一个简单的例子来解释如何应用这个公式。
假设我们要计算item1 和item2 之间的相似度。现在我们已经知道了同时对两个项目进行评分的所有用户A、B 和C 的相似度计算过程。首先,我们对分数进行标准化并求出平方和:所有用户对item1 的评分为2^2+1^2+4^2=20,所有用户对item2 的评分平方和为5^2+3^2+2^2=38 。将所有分数归一化、相乘、求和,最终相似度为:
所以我们首先对所有分数进行归一化,然后找到i 和j 的所有分数的集合并计算i 和j 之间的相似度。
下面是基于这个思想的代码实现。此代码是用Python 编写的MapReduce 任务。
标准化和成对匹配过程map1.py#! /usr/bin/env python # -*-coding: utf-8 -*-import sysimport math item_score_dic={}user_item_score_list=[]for line in stdin: ss=line .strip( ) .split(\’,\’) if len(ss) !=3: 继续user=ss[0].strip() item=ss[1].strip() 分数=float(ss[ 2].strip ()) user_item_score_list .append((user,item,score)) 分数=pow(score,2) if item_score_dic.has_key(item): item_score_dic[item] +=分数else: item_score_dic[item]=user_item_score_list: UI 分数user, item, Score=uis if item_score_dic.has_key(item): Score_sqr=math.sqrt(item_score_dic[item]) print (\’\\t\’.join([user,item,score/score_sqr]))reduce1.py
#! /usr/bin/env python# -*-coding: utf-8 -*-import sys current_user=Noneitem_score_list=[] sys.stdin: line ss=line.strip().split(\’\\t\’ ) if len ( ss) !=3: 继续user=ss[0].strip() item=ss[1].strip() 分数=float(ss[2].strip()) 如果不是current_user: current_user=user 如果current_user !=user:对于i 在范围内(0,len(item_score_list) – 1): 对于j 在范围(i + 1,len(item_score_list)): item_a,score_a=item_score_list [i] item_b,score_b=item_score_list [j] print(\’ \\ t\’.join([item_a, item_b, Score_a * Score_b])) print(\’\\t\’.join([item_b, item_a, Score_a * Score_b])) item_score_list=[] current_user=用户item_score_list 附加((item, Score)) for i in range(0, len(item_score_list) – 1): for j in range(i + 1, len(item_score_list)): item_a, Score_a=item_score_list[ i] item_b, Score_b=item_score_list[j] 打印(\’\\t\’.join([item_a, item_b, Score_a * Score_b])) print(\’\\t\’.join([item_b, item_a, Score_a * Score_b])) item1 和item2 相似配对map2 的总相位.py#! /usr/bin/env python# -*-coding: utf-8 -*-import sys for line in sys .stdin: ss=line.strip().split(\’\\t\’) if len(ss) !=3: 继续item_a=ss[0].strip() item_b=ss[1].strip() Score=ss[ 2].strip() print(\’%s#%s\\t%% item_a, item_b,分数)reduce2.py
#! /usr/bin/env python# -*-coding: utf-8 -*-import sys current_items=Nonesum=0.0 for line in sys.stdin: ss=line.strip().split(\’\\t\’) if len (ss) !=2: 继续item_item=ss[0].strip() 分数=float(ss[1].strip()) if current_items: current_items=item_item if current_items !=item_item: item_a, item_b=current_items.split (\’ # \’) print(\’\\t\’.join(item_a, item_b, sum)) sum=0.0 current_items=item_item sum +=得分item_a, item_b=current_items.split(\’#\’)print(\’\\t\’ .join( item_a , item_b, sum)) 以上是该算法的代码实现过程。该算法的一个缺点是当数据量非常大时,项目对的数量变得非常大。由于很容易耗尽内存,因此实际应用需要随机选择一定量的数据进行计算,而不是将所有数据添加到计算中。如果您觉得有用,请推荐给您的朋友并分享。 “努力提升自己。”
本文和图片来自网络,不代表火豚游戏立场,如若侵权请联系我们删除:https://www.huotun.com/game/664257.html