• 《集体智慧编程学习笔记》——Chapter2:提供推荐


    知识点:

    1. 协作型过滤——Collaboraive Filtering

      通常的做法是对一群人进行搜索,并从中找出与我们品味相近的一小群人,算法会对这些人的偏好进行考察,并将它们组合起来构造出一个经过排名的推荐列表

    2.搜索偏好——Collecting Preferences

    3.寻找相近的用户——Finding Similar Users

      3.1 通过相似度评价值来寻找相近的用户

      3.2 相似度评价值体系:欧几里得距离(Euclidean Distance ),皮尔逊相关度(Pearson Collelation)曼哈顿距离和Jaccard系数等

    代码实现:

      1 # !/usr/bin/local/python3
      2 # -*- coding utf-8 -*-
      3 from math import sqrt
      4 
      5 # prepare data
      6 critics = {'Lisa Rose':{'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
      7                         'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You,Me and Dupree': 2.5,
      8                         'The Night Listener': 3.0},
      9            'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5,
     10                             'Superman Returns': 5.0, 'The Night Listener': 3.0, 'You,Me and Dupree': 3.5},
     11            'Michale Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5,
     12                                 'The Night Listener': 4.0},
     13            'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5,
     14                             'Superman Returns': 4.0,'You,Me and Dupree': 2.5},
     15            'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0,
     16                             'Superman Returns': 3.0, 'The Night Listener': 3.0,'You,Me and Dupree': 2.0},
     17            'Jack Mattews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 5.0, 'The Night Listener': '3.0',
     18                             'Superman Returns': 5.0, 'You,Me and Dupree': 3.5},
     19            'Toby': {'Snakes on a Plane': 4.5, 'You,Me and Dupree': 1.0, 'Superman Returns': 4.0}}
     20 
     21 
     22 # 测试数据
     23 #data =critics['Lisa Rose']['Lady in the Water']
     24 #print(data)
     25 
     26 # 返回一个有关P1和P2的基于欧几里得距离的相似度评价
     27 def sim_distance(prefs, p1, p2):
     28     # 得到共同评价的电影列表
     29     si = {}
     30     for item in prefs[p1]:
     31         if item in prefs[p2]:
     32             si[item] = 1
     33     # 如果两人没有共同之处,则返回0
     34     if len(si) ==0: return 0
     35     # 计算所有差值的的平方和
     36     sum_of_squares = sum([pow(prefs[p1][item]-prefs[p2][item], 2) for item in prefs[p1]
     37                           if item in prefs[p2]])
     38    # 表示偏好越相近,返回的值越大,(避免被零整除的错误,当返回为1表示两人具有一样的偏好)
     39     return 1/(1+sqrt(sum_of_squares))
     40 
     41 
     42 # 返回p1和p2的皮尔逊相关系数
     43 def sim_pearson(prefs, p1, p2):
     44     si={}
     45     for item in prefs[p1]:
     46         if item in prefs[p2]:
     47             si[item] = 1
     48 
     49     n = len(si)
     50 
     51     if n == 0: return 1
     52     # 求所有偏好之和
     53     sum1 = sum([prefs[p1][it] for it in si])
     54     sum2 = sum([prefs[p2][it] for it in si])
     55 
     56     # 求偏好平方和
     57     sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
     58     sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
     59 
     60     # 求两人偏好乘积之和
     61     pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
     62 
     63     # 计算皮尔逊评价值
     64     num = pSum - (sum1*sum2/n)
     65     den = sqrt((sum1Sq-pow(sum1, 2)/n)*(sum2Sq-pow(sum2, 2)/n))
     66     if den == 0: return 0
     67    # 返回值介于-1和1之间,值为1则表示两个人对每一样物品均有着完全一致的评价
     68     r = num/den
     69     return r
     70 
     71 
     72 #   从反映偏好的字典中返回最为匹配者
     73 #  返回结果的个数和相似度函数均为可选参数
     74 def topMatches(prefs, person, n=5, similarity=sim_pearson):
     75     scores = [(similarity(prefs, person, other), other) for other in prefs if other != person]
     76 
     77     # 对表进行排序,评价值最高的排在最前面
     78     scores.sort()
     79     scores.reverse()
     80     return scores[0:n]
     81 
     82 
     83 # 利用所有他人评价值的加权平均,为某人提供建议
     84 def getRecommendations(prefs, person, similarity=sim_pearson):
     85     totals = {}
     86     simSum = {}
     87     for other in prefs:
     88         # 不和自己作比较
     89         if other == person: continue
     90         # 获取两人之间的相似度
     91         sim = similarity(prefs, person, other)
     92 
     93         # 忽略评价值小于零或者为零的情况
     94         if sim <= 0: continue
     95         for item in prefs[other]:
     96             # 只对自己未看过的电影进行评价
     97             if item not in prefs[person] or prefs[person][item] == 0:
     98                 # 相似度*评价值
     99                 totals.setdefault(item, 0)
    100                 totals[item] += sim * float(prefs[other][item])
    101                 # 相似度之和(多人评价对于特定电影的相似度之和)
    102                 simSum.setdefault(item, 0)
    103                 simSum[item] += sim
    104 
    105     # 建立一个归一化的列表
    106     rankings = [(total/simSum[item], item) for item, total in totals.items()]
    107     print(simSum)
    108     # 返回经过排序的列表
    109     rankings.sort()
    110     rankings.reverse()
    111     return rankings
    112 
    113 
    114 # 将人名和物品进行对调
    115 def transforPrefs(prefs):
    116     result = {}
    117     for person in prefs:
    118         for item in prefs[person]:
    119             result.setdefault(item,{})
    120             result[item][person] = prefs[person][item]
    121     return result

    总结:

    1.相似性度量方法的选择问题:

      1.1  当采用Pearson方法进行评价时,它修正了‘夸大分值’的情况

      1.2 当采用Euclidean Distance方法进行评价时,适用于存在一定共性的数据之间

    2.基于用户过滤和基于物品过滤的选择:
      2.1 基于用户过滤方法更容易实现,而且无需额外步骤,更适用于规模较小的变化非常频繁的内存数据集

      2.2 基于物品过滤明显比基于用户的过滤更快,不过在维护物品相似度表有额外的开销,更适用于稀疏数据集

  • 相关阅读:
    Nginx查看错误日志
    Centos 安装PHP5.5
    Mysql 数据库 远程连接
    使用scrapy框架做武林中文网的爬虫
    pycharm 使用black
    django使用pyecharts(6)----django加入echarts_增量更新_定长_坐标轴定长
    django使用pyecharts(5)----django加入echarts_增量更新_定长
    django使用pyecharts(4)----django加入echarts_增量更新
    django使用pyecharts(3)----django加入echarts_定时全量更新
    django使用pyecharts(2)----django加入echarts_前后台分离
  • 原文地址:https://www.cnblogs.com/maria-ld/p/8514805.html
Copyright © 2020-2023  润新知