机器学习:协同过滤推荐算法

题目:使用协同过滤(基于用户)构建简单的电影推荐系统

1.1.1 实验目的

1.了解协同过滤理论基础
2.平台实现算法
3. 编程实现协同过滤算法

1.1.2 实验内容及步骤

假设我们以字典形式保存用户关于电影的评分数据,请构建一个电影推荐程序。

STEP1:编写函数计算欧式距离字典数据中两两用户的欧式距离。
STEP2:编写函数依据欧式距离大小以及协同过滤算法(用户)实现电影的推荐。

1.1.3 程序运行过程、方法和运行结果

此处采用欧氏距离计算相似性

在这里插入图片描述

# 自定义数据集  电影及其最低评分
# A dictionary of movie critics and their ratings of a small#
critics = {
    
    
    'A': {
    
    '老炮儿':3.5,'唐人街探案': 1.0},
    'B': {
    
    '老炮儿':2.5,'唐人街探案': 3.5,'星球大战': 3.0, '寻龙诀': 3.5,
                  '神探夏洛克': 2.5, '小门神': 3.0},
    'C': {
    
    '老炮儿':3.0,'唐人街探案': 3.5,'星球大战': 1.5, '寻龙诀': 5.0,
                     '神探夏洛克': 3.0, '小门神': 3.5},
    'D': {
    
    '老炮儿':2.5,'唐人街探案': 3.5,'寻龙诀': 3.5, '神探夏洛克': 4.0},
    'E': {
    
    '老炮儿':3.5,'唐人街探案': 2.0,'星球大战': 4.5, '神探夏洛克': 3.5,
                     '小门神': 2.0},
    'F': {
    
    '老炮儿':3.0,'唐人街探案': 4.0,'星球大战': 2.0, '寻龙诀': 3.0,
                     '神探夏洛克': 3.0, '小门神': 2.0},
    'G': {
    
    '老炮儿':4.5,'唐人街探案': 1.5,'星球大战': 3.0, '寻龙诀': 5.0,
                      '神探夏洛克': 3.5}
    }

print(critics['B']['星球大战'])
3.0
# STEP1:编写函数计算欧式距离  字典数据中两两用户的欧式距离。
from math import sqrt

# Returns a distance-based similarity score for person1 and person2
def sim_distance(prefs, person1, person2):
    # Get the list of shared_items
    si = {
    
    }
    # 判断person1和person2是否有相同同的观影经历,“是”将si[item]结果置为1,“否”则返回0
    for item in prefs[person1]:
        if item in prefs[person2]: 
            si[item] = 1
            #print(item)
    # if they have no ratings in common, return 0
    if len(si) == 0: 
        return 0
    # Add up the squares of all the differences
    # 列表推导式 :如果A用户和B用户有相同同的观影经历,则求它们距离的平方和
    sum_of_squares = sum([pow(prefs[person1][item] - prefs[person2][item], 2) for item in prefs[person1] if item in prefs[person2]])
    #在欧氏距离公式中,取值范围会很大,一般通过如下方式归一化:sim = 1 / (1 + 欧氏距离)
    return 1 / (1 + sqrt(sum_of_squares))

print("A用户和B用户之间的欧氏距离:",sim_distance(critics, 'A', 'B'))
A用户和B用户之间的欧氏距离: 0.2708131845707603
# STEP2:编写函数依据欧式距离大小以及协同过滤算法(用户)实现电影的推荐。
# Gets recommendations for a person by using a weighted average
# of every other user's rankings   similarity=sim_distance重命名计算欧几里得距离函数
def getRecommendations(prefs, person, similarity=sim_distance):
    totals = {
    
    }
    simSums = {
    
    }
    for other in prefs:
        # don't compare me to myself
        if other == person: 
            continue
        #计算相似度
        sim = similarity(prefs, person, other)
        # ignore scores of zero or lower
        if sim <= 0: 
            continue
        for item in prefs[other]:
            # only score movies I haven't seen yet
            if item not in prefs[person] or prefs[person][item] == 0:
                # Similarity * Score
                totals.setdefault(item, 0)
                #求该用户没看过的电影的加权分的和  把相似性和对于每个电影的实际评分相乘,就是电影的加权分
                totals[item] += prefs[other][item] * sim
                # Sum of similarities
                simSums.setdefault(item, 0)
                #求这些电影的相似度之和
                simSums[item] += sim
    # Create the normalized list
    #标准化 推荐度 = 总相似度之和(总分/加权分的和)/相似性
    rankings = [(total / simSums[item], item) for item, total in totals.items()]
    # Return the sorted list
    rankings.sort()
    # 对列表的元素进行反向排序
    rankings.reverse()
    return rankings

print("给A用户推荐以下电影:\n",getRecommendations(critics, 'A'))
给A用户推荐以下电影:
 [(4.152703901679927, '寻龙诀'), (3.304207244554503, '神探夏洛克'), (3.045124682040546, '星球大战'), (2.5333970389243956, '小门神')]

1.1.4 实验小结

基于用户的协同过滤算法
思想:
寻找相似用户邻居,用相似邻居偏好来推荐物品

步骤:
一、使用欧氏距离(或其它方法)计算相似性;
二、把相似性和对于每个电影的实际评分相乘,就是电影的加权分;
三、计算推荐度=加权分之和/相似性;
四、将推荐度最高的电影推荐给用户。

猜你喜欢

转载自blog.csdn.net/m0_52331159/article/details/130483476
今日推荐