电影推荐-基于用户的协同过滤推荐

推荐引擎

推荐引擎意在把最需要的推荐给用户。

在不同的机器学习场景中通常需要分析相似样本。而统计相似样本的方式可以基于欧氏距离分数,也可基于皮氏距离分数。

欧氏距离分数
= 1 1 + 欧氏距离分数 = \frac{1}{1+欧氏距离}
计算所得欧氏距离分数区间处于:[0, 1],越趋于0样本间的欧氏距离越远,样本越不相似;越趋于1,样本间的欧氏距离越近,越相似。

构建样本之间的欧氏距离得分矩阵:
在这里插入图片描述

案例:解析ratings.json,根据每个用户对已观看电影的打分计算样本间的欧氏距离,输出欧氏距离得分矩阵。
部分数据如下:
在这里插入图片描述

import json
import numpy as np

with open('../data/ratings.json', 'r') as f:
    ratings = json.loads(f.read())
users, scmat = list(ratings.keys()), []
for user1 in users:#外层for循环存储打分矩阵
    scrow = []
    #计算user1与user2的欧氏距离得分
    for user2 in users:#内层for循环存储一行
        movies = set()#整理两个人都看过的电影
        for movie in ratings[user1]:
            if movie in ratings[user2]:
                movies.add(movie)       
        if len(movies) == 0:#两人没有相同的电影
            score = 0
        else:#有相同的电影
            x, y = [], []#存储两人对相同电影的打分
            for movie in movies:
                x.append(ratings[user1][movie])
                y.append(ratings[user2][movie])
            x = np.array(x)
            y = np.array(y)
            score = 1 / (1 + np.sqrt(((x - y) ** 2).sum()))
        scrow.append(score)
    scmat.append(scrow)
users = np.array(users)
scmat = np.array(scmat)

for scrow in scmat:
    print('  '.join('{:.2f}'.format(score) for score in scrow)) 
    
要拿到01位置的相关系数

**按照相似度从高到低排列每个用户的相似用户**

```python
# scmat矩阵中每一行为 每一个用户对所有用户的皮尔逊相关系数
for i, user in enumerate(users):
    # 拿到所有相似用户与相似用户所对应的皮尔逊相关系数
    sorted_indices = scmat[i].argsort()[::-1]
    sorted_indices = sorted_indices[sorted_indices != i]
    similar_users = users[sorted_indices]
    similar_scores = scmat[i, sorted_indices]
    print(user, similar_scores,similar_users,  sep='\n')

生成推荐清单

  1. 找到所有皮尔逊系数正相关的用户
  2. 遍历当前用户的每个相似用户,拿到相似用户看过但是当前用户没有看过的电影作为推荐电影
  3. 多个相似用户有可能推荐同一部电影,则取每个相似用户对该电影的评分得均值作为推荐度。
  4. 可以把相似用户的皮尔逊系数作为权重,皮尔逊系数越大,推荐度越高。
    # 找到所有皮尔逊系数正相关的用户
    positive_mask = similar_scores > 0
    similar_users = similar_users[positive_mask]
    # 相似用户对应的皮尔逊相关系数
    similar_scores = similar_scores[positive_mask]
    #存储对于当前用户所推荐的电影以及电影的推荐度(推荐电影的平均分)
    recomm_movies = {}
    #遍历当前用户的每个相似用户
    for i, similar_user in enumerate(similar_users):
        #拿到相似用户看过但是当前用户没有看过的电影
        for movie, score in ratings[similar_user].items():
            if (movie not in ratings[user].keys()):
                #存入推荐列表
                #查看推荐字典是否已经有该电影
                if movie not in recomm_movies:
                    #存电影
                    recomm_movies[movie] = [score]
                else:
                    #存分数
                    recomm_movies[movie].append(score)
                    
    print(user)
    print(recomm_movies)
John Carson
{}
Michelle Peterson
{}
William Reynolds
{'Anger Management': [3.0, 1.5], 'Serendipity': [2.5, 3.5, 3.5]}
Jillian Hobart
{'Inception': [3.0, 2.5, 3.0, 3.0]}
Melissa Jones
{}
Alex Roberts
{'Anger Management': [3.0, 2.0, 3.0]}
Michael Henry
{'Inception': [3.0, 3.0, 3.0], 'Anger Management': [2.0, 3.0
    #排序算法   对字典排序
    movie_list = sorted(recomm_movies.items(), key=lambda x:np.average(x[1]), reverse=True)
    print(movie_list)

发布了27 篇原创文章 · 获赞 112 · 访问量 3255

猜你喜欢

转载自blog.csdn.net/jaffe507/article/details/105660342