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

完整代码:github——提供推荐

编译环境:Python3.6

一、协作型过滤

      1、思想:对一大群人进行搜索,并从中找出与我们品味相近的一小群人,对这些人所偏爱的其他内容进行考查,并将它们组合起来构成一个经过排名的推荐列表。

     2、算法步骤

            1)搜集偏好

                    用嵌套的字典表示不同人的偏好,偏好有等级之分。

            2)寻找相近的用户

                     (1)相似度评价的体系

                                ①欧几里德距离

                                                   

                                            相似度越大,sim(x,y)越接近1。

#欧几里德距离计算相似度
def EuclideanDistanceScore(critics, person1, person2):
    si = {}
    #搜集两人共同评价过的电影
    for item in critics[person1]:
        if item in critics[person2]:
            si[item] = 1

    if len(si) == 0:
        return 0

    #计算两人的欧几里德距离,和书上的例子相比,修改了item的索引方式,直接利用了已经获得的共同评价过的电影的字典
    distance = sqrt(sum(pow(critics[person1][item] - critics[person2][item], 2) for item in si))
    sim = 1/(1+distance)
    return sim

                                ②皮尔逊相关度(最常用)

                                          

                                         a、协方差(衡量变化趋势是否一致,-1表示负相关,+1表示正相关)

                                                

                                         b、皮尔逊相关系数

                                                

                                       Pearson相关系数是协方差除以两个变量的标准差得到的,除以标准差是为了消除自身的差异,规则化自身。 p(x,y)越趋于0,越不相关。趋于-1,负相关,趋于1,正相关。

#皮尔逊相关度评价
def PearsonCorrelationScore(critics, person1, person2):
    si = {}
    for item in critics[person1]:
        if item in critics[person2]:
            si[item] = 1

    n = len(si)
    #书上是返回1,但是1不就是正相关了吗?所以我选择返回0
    if n == 0:
        return 0

    #书上没有说明皮尔逊系数的数学表达,我按照数学表达进行计算
    #计算两者的协方差
    cov = sum(critics[person1][item] * critics[person2][item] for item in si)\
          - (sum(critics[person1][item] for item in si) * sum(critics[person2][item] for item in si) / n)
    #计算两者的方差
    variance1 = sqrt(sum(pow(critics[person1][item], 2) for item in si)\
                     - pow(sum(critics[person1][item] for item in si), 2) / n)
    variance2 = sqrt(sum(pow(critics[person2][item], 2) for item in si)\
                     - pow(sum(critics[person2][item] for item in si), 2) / n)
    variance = variance1 * variance2
    if variance == 0:
        return 0

    #皮尔逊相关度 = 两者协方差 / 两者方差的积
    pearson = cov / variance
    return pearson

                                 ③Cosine相似度

                                           

                    (2)邻居的选择

                                ①固定数量的邻居

#基于固定数目的邻居
def TopMatches(critics, person, n, similarity):
    #从字典中计算每一个与指定目标的相似度,并存入列表中。
    #n为指定相似度的前n个人,similarity是选择的相似度评价准则
    scores = [(similarity(critics, person, other), other) for other in critics if other != person]

    scores.sort()
    scores.reverse()
    return scores[:n]

                                ②基于相似度门槛的邻居(best)

#基于相似度门槛的邻居
def ThresholdMatches(critics, person, threshold, similarity):
    #threshold是设定的相关度门限
    #因为下面需要索引相似度值,所以将()改为内嵌的列表
    scores = [[similarity(critics, person, other), other] for other in critics if other != person]

    scores.sort()
    scores.reverse()

    thresholdScores = []
    for i in range(len(scores)):
        if scores[i][0] >= threshold:
            thresholdScores.append(scores[i])

    return thresholdScores

                           (3)推荐物品

                                   考虑到与指定目标相似度越高的人对整体评价拥有更高的权限,所以利用相似度对评价值进行加权。若利用总计值计算排名,应该将其除以相似度之和,以修复受更多人评价的电影会对结果产生更大的影响的问题。

#推荐物品
def getRecommendations(critics, person, similarity):
    totals = {}
    simSum = {}

    for other in critics:
        if other != person:
            sim = similarity(critics, person, other)

        #忽略评价值为0或者小于零的情况
        if sim <= 0:
            continue

        for item in critics[other]:

            #只选择指定目标未看过的电影
            if item not in critics[person] or critics[person][item] == 0:
                totals.setdefault(item, 0)
                #计算加权评价值之和,加权评价值 = 评价值*相似度
                totals[item] += critics[other][item] * sim

                #计算相似度之和
                simSum.setdefault(item, 0)
                simSum[item] += sim

    #建立归一化的列表
    rankings = [(total / simSum[item], item) for item, total in totals.items()]

    rankings.sort()
    rankings.reverse()
    return rankings

       3、基于用户的协同过滤

               1)思想: 先计算不同的用户的相似度,再从最大相似度的用户中进行推荐给目标用户。

               2)要解决的问题

                            (1)已知用户评分矩阵Matrix R(一般都是非常稀疏的)

                            (2)推断矩阵中空格empty cells处的值

              3)存在的问题

                           (1)对于一个新用户,很难找到邻居用户

                           (2)对于一个物品,所有最近的邻居都在其上没有打分

             4)基础解决方案

                            (1)相似度计算最好使用皮尔逊相似度

                            (2)考虑共同打分物品的数目,如乘上min(n,N)/N n:共同打分数 N:指定阈值

                            (3)对打分进行归一化处理

                            (4)设置一个相似度阈值

             5)不流行的原因

                            (1)稀疏问题

                            (2)数百万的用户计算

                            (3)人是善变的

            6)应用场景:实时新闻、突然情况

    4、基于物品的协同过滤

           1)  思想:计算物品的相似度,推荐给客户。

                   (1)将物品和人进行对换

def transformPrefs(critics):
    result = {}
    #统计有多少个物品
    for person in critics:
        for item in critics[person]:
            result.setdefault(item, {})
            #将物品和人员对调
            result[item][person] = critics[person][item]
    return result

                   (2)使用MoviesLen数据集

#用来加载下载的数据
def loadMoviesLens(path = './moviesdata'):

    #获取影片的标题
    movies = {}
    #Python2 和 Python3差别很大,书上的原程序读文件显示错误,可能是文件中含特殊的中文或者无法识别的文字,必须改变编码形式忽略错误编码
    for line in open(path + '/u.item', 'r', encoding='gb18030', errors='ignore'):
        (id, title) = line.split('|')[0:2]
        movies[id] = title

    #加载数据
    prefs = {}
    for line in open(path + '/u.data'):
        (user, movieid, rating, ts) = line.split('\t')
        prefs.setdefault(user, {})
        prefs[user][movies[movieid]] = float(rating)
    return prefs

           2)优势

                 (1)计算性能高,通常用户数量远大于物品数量

                 (2)可预先计算保留,物品并不善变

           3)用户冷启动问题

                   (1)引导用户把自己的一些属性表达出来

                   (2)利用现有的开放数据平台

                   (3)根据用户注册属性

                   (4)推荐排行榜单(最常用)

           4)物品冷启动问题

                   (1)文本分析

                   (2)主题模型

                   (3)打标签

                   (4)推荐排行榜单

          5)应用场景:图书、电子商务、电影.......

   5、推荐系统评估指标

         1)评估标准

                (1)准确度:

                (2)召回率:


                        R(u)是根据用户在训练集上的行为给用户做出的推荐列表,T(u)是用户在测试集上的行为列表。    

               (3)覆盖率:          

               (4) 多样性:


你可能感兴趣的:(机器学习)