《集体智慧编程》学习笔记(一)

第二章 提供推荐

1、搜集偏好

先构造一个简单的数据集:

#用户对不同电影的评分
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
 'The Night Listener': 3.0},

'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
 'You, Me and Dupree': 3.5}, 

'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
 'Superman Returns': 3.5, 'The Night Listener': 4.0},

'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
 'The Night Listener': 4.5, 'Superman Returns': 4.0, 
 'You, Me and Dupree': 2.5},

'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
 'You, Me and Dupree': 2.0}, 

'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},

'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

2、相似度评价值

评价值特点
欧几里德距离 多维空间中两点之间的距离,用来衡量二者的相似度。距离越小,相似度越高。
皮尔逊相关度评价 判断两组数据与某一直线拟合程度的一种度量。在数据不是很规范的时候(如影评者对影片的评价总是相对于平均水平偏离很大时),会给出更好的结果。相关系数越大,相似度越高。

 

#欧几里得距离
def disitance_simulation (critics, person1, person2):
    result = [name for name in critics[person1] if name in critics[person2]]
    if 0 == len(result):
        return 0
    #else:
    #    print (result)
    return (1 / (1 + sqrt(sum([pow(critics[person1][name] - critics[person2][name], 2) for name in result]))))
    
#皮尔逊相关度
#找出两位评论者都曾评价过的物品,然后计算两者的评分总和与平方和,并求出评分的乘积之和。
#利用上述计算结果计算出皮尔逊相关系数
def pearson_simulation (critics, person1, person2): result = [name for name in critics[person1] if name in critics[person2]] if 0 == len(result): return 0 #else: # print (result) #评分和 sum1 = sum([critics[person1][name] for name in result]) sum2 = sum([critics[person2][name] for name in result]) #平方和 sum1Sq = sum([pow(critics[person1][name], 2) for name in result]) sum2Sq = sum([pow(critics[person2][name], 2) for name in result]) #同一个电影的评分乘积之和 sumM = sum([critics[person1][name] * critics[person2][name] for name in result])
n
= len(result) num = sumM - (sum1 * sum2 / n) den = sqrt((sum1Sq - pow(sum1, 2)/n) * (sum2Sq - pow(sum2, 2)/n)) if 0 == den: return 0 return (num/den)

注:皮尔逊相关度的计算中,如果某人总是倾向于给出比另一个人更高的分值,而两者的分值之差又始终保持一致,则他们依然可能会存在很好的相关性。毕竟,这个方法认为最相关的时候就是“y=x”直线的时候。

3、提供推荐

①为评论者打分:

#为评论者打分
#计算其他用户与某一用户的相似度,并且排序
def sort_simulation (critics, person, simularity):
    result = [(simularity(critics, person, other), other) for other in critics if other != person]
    result.sort()
    result.reverse()
    return result

相似度越大,说明两个人越具有相近的品味

②推荐物品:通过一个经过加权的评价值来为影片打分,并推荐给对应的影评者

#提供推荐
#根据与其他用户的相似度,向用户推荐电影
def get_recommendations(critics, person, simularity):
    sum = {}
    sumS = {}
    #计算出与不同用户的相似度
    result = sort_simulation(critics, person, simularity) 
    #遍历每个其他用户的评分
    for i in range(0, len(result)):
        if 0 > result[i][0]: continue
        for movie in critics[result[i][1]]:
            #找到别人看过并且自己没有看过的电影
            if movie in critics[result[i][1]] and movie not in critics[person]:
                sum.setdefault(movie, 0)
                #相似度*评分
                sum[movie] = sum[movie] + result[i][0] * critics[result[i][1]][movie]
                sumS.setdefault(movie, 0)
                #相似度之和
                sumS[movie] += result[i][0]
    #建立归一化的表
    rank = [(sum[movie]/sumS[movie], movie) for movie in sum]
    rank.sort()
    rank.reverse()
    return (rank)

③匹配商品:通过将数据集中的人员和物品对换,构建新的数据集即可。

#将人名和电影名转换
def tranfer_name(critics):
    result = {}
    for name in critics:
        for movie in critics[name]:
            result.setdefault(movie, {})
            result[movie][name] = critics[name][movie]
    return result

4、基于用户进行过滤还是基于物品进行过滤?

协作型过滤:对一大群人进行搜索并给出与我们相近的人的排名列表。

密集数据集:在涉及电影的例子中,由于每个评论者几乎对他看过的每部影片都做过评价,所以数据集是密集的。

稀疏数据集:而每部电影并不会被所有的用户评价,只有看过的用户才会评价,这就形成了一个稀疏数据集。

基于用户进行过滤和基于物品进行过滤最显著的区别:物品间的比较不会像用户间的比较那么频繁变化。

在拥有大量数据集的情况下,基于物品的协作型过滤能够得出更好的结论,而且它允许我们将大量计算任务预先执行,从而使需要给予推荐的用户能够快速地得到他们所要的结果。

对于稀疏数据集,基于物品的过滤方法通常要优于基于用户的过滤方法,而对于密集数据集而言,两者的效果则几乎是一样的。

 

对商品推荐的一个通俗的解释:

基于用户的协同过滤基本思想非常简单,就是找到志同道合的朋友,并把朋友感兴趣的而用户没有接触过的商品推荐给用户。

但是这有一个问题,由于新用户的注册量非常高,基于用户的协同过滤推荐需要计算新用户和之前的用户之间的相似度,这会将数据稀疏,延展性差等问题暴露的非常明显。

所以基于商品的协同过滤方法被提出,相较于用户之间的相似度,商品之间的相似度相对是静态的,当新用户注册并有了一些自己感兴趣的商品信息时,无需再进行计算,直接根据之前存储的商品之间的相似度,将用户可能感兴趣的商品推荐给用户。

参考:

https://www.cnblogs.com/xiaoYu3328/p/5173854.html

https://blog.csdn.net/u014473918/article/details/79771558

posted @ 2018-12-23 16:24  小时候挺菜  阅读(331)  评论(0编辑  收藏  举报