機器學習 - 算法模型 - 推薦引擎

推薦引擎

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

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

歐氏距離分數

=11+ 歐氏距離分數 = \frac{1}{1+歐氏距離}
計算所得歐氏距離分數區間處於:[0, 1],越趨於0樣本間的歐氏距離越遠,樣本越不相似;越趨於1,樣本間的歐氏距離越近,越相似。

構建樣本之間的歐氏距離得分矩陣:
[abcd..a10.20.30.4..b0.21xx..c0.3x1x..d0.4xx1..............] \left[ \begin{array}{c} & a & b & c & d & .. \\ a & 1 & 0.2 & 0.3 & 0.4 & .. \\ b & 0.2 & 1 & x & x & .. \\ c & 0.3 & x & 1 & x & .. \\ d & 0.4 & x & x & 1 & .. \\ .. & .. & .. & .. & .. & .. \\ \end{array} \right]
案例:解析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:
    scrow = []
    for user2 in users:
        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)) 

皮爾遜相關係數

A = [1,2,3,1,2] 
B = [3,4,5,3,4] 
m = np.corrcoef(A, B)

皮爾遜相關係數 = 協方差 / 標準差之積

相關係數處於[-1, 1]區間。越靠近-1代表兩組樣本反相關,越靠近1代表兩組樣本正相關。

案例:使用皮爾遜相關係數計算兩用戶對一組電影評分的相關性。

score = np.corrcoef(x, y)[0, 1]

按照相似度從高到低排列每個用戶的相似用戶

# 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_users, similar_scores, 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] = []
                else:
                    recomm_movies[movie].append(score)
                    
    print(user)
    movie_list = sorted(recomm_movies.items(), key=lambda x:np.average(x[1]), reverse=True)
    print(movie_list)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章