电影推荐引擎核心算法

'''
    推荐引擎 (用户画像):把最需要的推荐给用户。
        在不同的机器学习场景中通常需要分析相似样本。而统计相似样本的方式可以基于欧氏距离分数,也可基于皮氏距离分数。
            欧氏距离分数 :
                欧氏距离分数 = 1/(1+欧式距离)
                            ----计算所得欧氏距离分数区间处于:(0, 1],越趋于0样本间的欧氏距离越远,样本越不相似;
                                越趋于1,样本间的欧氏距离越近,越相似。

            皮尔逊相关系数:
                    A = [1,2,3,1,2]
                    B = [3,4,5,3,4]
                    m = np.corrcoef(A, B)
                    皮尔逊相关系数 = 协方差 / 标准差之积
                    相关系数处于[-1, 1]区间。越靠近-1代表两组样本反相关,越靠近1代表两组样本正相关

            生成推荐清单:
                    1.找到所有皮尔逊系数正相关的用户
                    2.遍历当前用户的每个相似用户,拿到相似用户看过但是当前用户没有看过的电影作为推荐电影
                    3.多个相似用户有可能推荐同一部电影,则取每个相似用户对该电影的评分得均值作为推荐度。


    案例:解析ratings.json,根据每个用户对已观看电影的打分计算样本间的欧氏距离,输出欧氏距离得分矩阵。
'''
import json
import numpy as np

with open('./ml_data/ratings.json', 'r') as f:
    ratings = json.loads(f.read())

print(ratings)

# 整理用户之的相似度得分矩阵
users, scmat = list(ratings.keys()), []
for user1 in users:
    scrow = []
    for user2 in users:
        # 计算user1与user2的相似度 添加到scrow
        movies = set()
        for movie in ratings[user1]:
            if movie in ratings[user2]:
                movies.add(movie)
        if len(movies) == 0:
            score = 0
        else:
            A, B = [], []
            for movie in movies:
                A.append(ratings[user1][movie])
                B.append(ratings[user2][movie])
            A = np.array(A)
            B = np.array(B)
            # 计算A与B的相似度---欧式距离
            # score = 1 / (1 + np.sqrt(((A - B) ** 2)).sum())
            # 计算A与B的相似度---皮尔逊相关系数
            score = np.corrcoef(A, B)[0, 1]
        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]))

# 按照相似度从高到低排列每个用户的相似用户
for i, user in enumerate(users):
    # 获取所有相似用户得分,去掉自己,排序
    sorted_indices = scmat[i].argsort()[::-1]
    sorted_indices = sorted_indices[sorted_indices != i]  # 剔除自己
    # user的所有相似用户
    sim_users = users[sorted_indices]
    # user所有相似用户的相似度得分
    sim_scores = scmat[i, sorted_indices]
    # print(user, sim_users, sim_scores, sep='\n')

    # 生成推荐清单
    # 正相关得分的掩码
    positive_mask = sim_scores > 0
    # 获取所有正相关用户的用户名
    sim_users = sim_users[positive_mask]
    # 为user构建推荐清单,找到每个sim_user看过,但是当前用户没有看过的电影,存入字典结构
    # 存储推荐清单:{'电影1':[4.0,5.0],'电影2':[3.0,4.0]}
    reco_movies = {}
    for j, sim_user in enumerate(sim_users):
        for movie, score in ratings[sim_user].items():
            # 相似用户看过但是当前用户没有看过
            if movie not in ratings[user].keys():
                if movie not in reco_movies:
                    reco_movies[movie] = [score]
                else:
                    reco_movies[movie].append(score)
    # print(user, reco_movies, sep='  ')

    # 对推荐清单进行排序
    movie_list = sorted(reco_movies.items(), key=lambda x: np.average(x[1]), reverse=True)
    print(user, movie_list, sep=' ')


输出结果:

{'John Carson': {'Inception': 2.5, 'Pulp Fiction': 3.5, 'Anger Management': 3.0, 'Fracture': 3.5, 'Serendipity': 2.5, 'Jerry Maguire': 3.0}, 'Michelle Peterson': {'Inception': 3.0, 'Pulp Fiction': 3.5, 'Anger Management': 1.5, 'Fracture': 5.0, 'Jerry Maguire': 3.0, 'Serendipity': 3.5}, 'William Reynolds': {'Inception': 2.5, 'Pulp Fiction': 3.0, 'Fracture': 3.5, 'Jerry Maguire': 4.0}, 'Jillian Hobart': {'Pulp Fiction': 3.5, 'Anger Management': 3.0, 'Jerry Maguire': 4.5, 'Fracture': 4.0, 'Serendipity': 2.5}, 'Melissa Jones': {'Inception': 3.0, 'Pulp Fiction': 4.0, 'Anger Management': 2.0, 'Fracture': 3.0, 'Jerry Maguire': 3.0, 'Serendipity': 2.0}, 'Alex Roberts': {'Inception': 3.0, 'Pulp Fiction': 4.0, 'Jerry Maguire': 3.0, 'Fracture': 5.0, 'Serendipity': 3.5}, 'Michael Henry': {'Pulp Fiction': 4.5, 'Serendipity': 1.0, 'Fracture': 4.0}}
1.00 0.40 0.40 0.57 0.59 0.75 0.99
0.40 1.00 0.20 0.31 0.41 0.96 0.38
0.40 0.20 1.00 1.00 -0.26 0.13 -1.00
0.57 0.31 1.00 1.00 0.57 0.03 0.89
0.59 0.41 -0.26 0.57 1.00 0.21 0.92
0.75 0.96 0.13 0.03 0.21 1.00 0.66
0.99 0.38 -1.00 0.89 0.92 0.66 1.00
John Carson []
Michelle Peterson []
William Reynolds [('Serendipity', [2.5, 2.5, 3.5, 3.5]), ('Anger Management', [3.0, 3.0, 1.5])]
Jillian Hobart [('Inception', [2.5, 3.0, 2.5, 3.0, 3.0])]
Melissa Jones []
Alex Roberts [('Anger Management', [1.5, 3.0, 2.0, 3.0])]
Michael Henry [('Jerry Maguire', [3.0, 3.0, 4.5, 3.0, 3.0]), ('Inception', [2.5, 3.0, 3.0, 3.0]), ('Anger Management', [3.0, 2.0, 3.0, 1.5])]

 

posted @ 2019-07-23 08:39  一如年少模样  阅读(875)  评论(0编辑  收藏  举报