提供推荐——学习笔记

推荐系统实例 

# -*- coding: utf-8 -*-
from math import sqrt

# 一个涉及影评者及其对几部影片评分情况的字典
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,
                     'You, Me and Dupree': 3.0, 'The Night Listener': 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.0},
    '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}}


def sim_distance(prefs, person1, person2):
    """
    返回一个有关person1和person2的基于距离的相似度评价
    得到shared_items的列表
    """
    si = {}
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item] = 1
    # 如果两者没有共同之处,则返回0
    if len(si) == 0: return 0
    # 计算所有差值的平方和
    sum_of_squares = sum(
        [pow(prefs[person1][item] - prefs[person2][item], 2) for item in prefs[person1] if item in prefs[person2]])
    return 1 / (1 + sqrt(sum_of_squares))


def sim_pearson(prefs, p1, p2):
    """
    返回p1和p2的皮尔逊相关系数
    得到双方都曾评价过的物品列表
    """
    si = {}
    for item in prefs[p1]:
        if item in prefs[p2]: si[item] = 1
    # 得到列表元素的个数
    n = len(si)
    # 如果两者没有共同之处,则返回1
    if n == 0: return 1
    # 对所有偏好求和
    sum1 = sum([prefs[p1][it] for it in si])
    sum2 = sum([prefs[p2][it] for it in si])
    # 求平方和
    sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
    sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
    # 求乘积之和
    pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
    # 计算皮尔逊评价值
    num = pSum - (sum1 * sum2 / n)
    den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
    if den == 0: return 0
    r = num / den
    return r


def topMatches(prefs, person, n=5, similarity=sim_pearson):
    """
    从反映偏好的字典中返回最为匹配者
    返回结果的个数和相似度函数均为可选参数
    """
    scores = [(similarity(prefs, person, other), other)
              for other in prefs if other != person]
    # 对列表进行排序,评价值最高者排在最前面
    scores.sort()
    scores.reverse()
    return scores[0:n]


def getRecommendations(prefs, person, similarity=sim_pearson):
    """利用所有他人评价值的加权平均,为某人提供建议"""
    totals = {}
    simSums = {}
    for other in prefs:
        # 不要和自己做比较
        if other == person: continue
        sim = similarity(prefs, person, other)
        # 忽略评价值为零或小于零的情况
        if sim <= 0: continue
        for item in prefs[other]:
            # 只对自己还未曾看到过的影片进行评价
            if item not in prefs[person] or prefs[person][item] == 0:
                # 相似度*评价值
                totals.setdefault(item, 0)
                totals[item] += prefs[other][item] * sim
                # 相似度之和
                simSums.setdefault(item, 0)
                # setdefault(keyname, value) keyname 您要从中返回值的项目的键名。 value 如果键存在,则此参数无效。如果键不存在,则此值将成为键的值。
                simSums[item] += sim
    # 建立一个归一化的列表
    rankings = [(total / simSums[item], item) for item, total in totals.items()]
    # 返回经过排序的列表
    rankings.sort()
    rankings.reverse()
    return rankings


def transformPrefs(prefs):
    result = {}
    for person in prefs:
        for item in prefs[person]:
            result.setdefault(item, {})
            # 将物品和人员对调
            result[item][person] = prefs[person][item]
    return result


def main():
    print(sim_distance(critics, 'Lisa Rose', 'Gene Seymour'))
    print(sim_pearson(critics, 'Lisa Rose', 'Gene Seymour'))
    print(topMatches(critics, 'Toby', n=5))
    print(getRecommendations(critics, 'Toby'))
    print(getRecommendations(critics, 'Toby', similarity=sim_distance))
    movies = transformPrefs(critics)
    print(topMatches(movies, 'Superman Returns'))


if __name__ == '__main__':
    main()

参考资料

[1] Programming Colllective Intelligence by Toby Segaran.Copyright 2007 Toby Segaran, 978-0-596-52932-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值