電影推薦-基於用戶的協同過濾推薦

推薦引擎

推薦引擎意在把最需要的推薦給用戶。

在不同的機器學習場景中通常需要分析相似樣本。而統計相似樣本的方式可以基於歐氏距離分數,也可基於皮氏距離分數。

歐氏距離分數
=11+ 歐氏距離分數 = \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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章