天天看點

100行代碼實作電影推薦引擎系統

推薦引擎是一個能預測使用者興趣點的模型。将推薦引擎應用于電影情境,便成為一個電影推薦引擎,應用到購物中,則成為購物推薦引擎。

通過預測目前使用者可能會喜歡的内容,将相應的東西從資料庫中篩選出來,這樣有助于将使用者和資料集中的内容連接配接起來,通過推薦合适的内容,可以增加使用者消費。

推薦引擎通常用協同過濾(CF) 或基于内容的過濾來産生一組推薦。兩種過濾方法不同之處在于挖掘推薦方式。協同過濾從目前使用者過去的行為和其他使用者對目前使用者的評分來構模組化型,然後使用這個模型來預測使用者可能感興趣的内容。而基于内容的過濾從商品本身的特征來給使用者推薦更多商品,商品間的相似度是模型主要的關注點。本文内容的是基于協同過濾實作的。

接下來我們建構一個簡易電影推薦引擎。

定義相似度名額

推薦引擎建構需要定義相似度名額,以便找到與資料庫中特定使用者相似的使用者,一般使用歐氏距離分數或皮爾遜相關系數。

皮爾遜相關系數

在統計學中, 皮爾遜相關系數通常情況下通過以下取值範圍判斷變量的相關強度:

0.8-1.0 極強相關

0.6-0.8 強相關

0.4-0.6 中等程度相關

0.2-0.4 弱相關

0.0-0.2 極弱相關或無相關

皮爾遜相關系數定義為兩個變量之間的皮爾遜相關系數定義為兩個變量之間的協方差和标準差的商,用公式表示為:

ρx,y=x和y的協方差x的标準差∗y的标準差 ρ x , y = x 和 y 的 協 方 差 x 的 标 準 差 ∗ y 的 标 準 差

期望值分别為 E[X]和 E[Y]的兩個随機變量 X 與 Y 之間的**協方差**Cov(X, Y)定義為: Cov(X,Y) = E[XY] - E[X][Y]

标準差即為方差的開方。離散型随機變量的方差公式為:

D(X)=E(X2)−[E(X)]2 D ( X ) = E ( X 2 ) − [ E ( X ) ] 2

明确了以上概念,我們來實作計算兩個使用者之間的皮爾遜相關系數的函數。首先判斷使用者是否在資料庫中出現:若出現,則提取兩個使用者均評分的電影,如果沒有兩個使用者共同評過分的電影,則說明兩個使用者之間沒有相似度,此時傳回 0。否則,計算相皮爾遜相關系數。

import json
import numpy as np
def pearon_score(dataset, user1, user2):
    #判斷使用者是否在資料庫中
    if user1 not in dataset:
        raise TypeError('User' + user1 + 'not present in the dataset')
    if user2 not in dataset:
        raise TypeError('User' + user2 + 'not present in the dataset')
    #提取使用者均評過分的電影
    rated_both = {}

    for item in dataset[user1]:
        if item in dataset[user2]:
        rated_both[item] = 

    num_ratings =len(rated_both)
    if num_ratings == :
        return 

    #計算相同評分電影值的總和
    user1_sum = np.sum([dataset[user1][item] for item in rated_both])
    user2_sum = np.sum([dataset[user1][item] for item in rated_both])

    #計算所有相同評分電影的評分的平方和
    user1_squared_sum = np.sum([np.square(dataset[user1][item]) for item in rated_both])
    user2_squared_sum = np.sum([np.square(dataset[user2][item]) for item in rated_both])

    #計算相同評分電影資料集乘積之和
    total_sum = np.sum([dataset[user1][item] * dataset[user2][item] for item in rated_both])

    #根據皮爾遜公式計算
    #Cov(X,Y) = E[XY] - E[X]E[Y] 
    Sxy = total_sum - (user1_sum * user2_sum / num_ratings)
    # D(X) = E(X 的平方) - [E(X)]的平方
    Sxx = user1_squared_sum - np.square(user1_sum) / num_ratings
    Syy = user2_squared_sum - np.square(user2_sum) / num_ratings
    #考慮分母為 0 的情況
    if Sxx * Syy == :
        return 

    return Sxy / np.sqrt(Sxx * Syy)
           

尋找相似使用者

推薦引擎中一個非常重要的任務就是尋找相似的使用者,也就意味着,為某位使用者生成的推薦資訊可以同時推薦給其他與之相似的使用者。

首先定義一個函數,用于尋找與輸入使用者相似的使用者。先判斷使用者是否在資料庫中,如果已經存在,則計算該使用者與資料庫中其他使用者的皮爾遜相關系數。然後提取所有得分中 k 個最高分并傳回。代碼如下:

def find_similar_users(dataset, user, num_users):
    if user not in dataset:
        raise TypeError('User' + user1 + 'not present in the dataset')

    scores = np.array([[x, pearson_score(dataset, user, x)] for x in dataset if user != x])
    #評分按降序排列
    scores_sorted = np.argsort(scores[:, ])
    scored_sorted_dec = scores_sorted[::-]

    #提取 K 個最高分
    top_k = scored_sorted_dec[:num_users]
    return scores[top_k[
           

完成電影推薦引擎

根據前面完成的部分,我們可以生成一個簡單的電影推薦引擎系統了。簡要流程圖如下所示:

100行代碼實作電影推薦引擎系統

推薦系統簡要流程圖

首先定義一個為使用者生成電影推薦的函數,檢查使用者是否在資料庫中,如果找到則計算與其他使用者相關的皮爾遜相關系數,然後找到未被該使用者評分的電影,最終根據皮爾遜相關系數清單,提取出推薦的電影。僞代碼如下:

.  if 使用者不在資料庫中
            列印提示
        else:
            計算使用者與其他使用者皮爾遜相關系數
    .  找到尚未被該使用者評分的電影
         如果使用者看過所有電影,則無法推薦電影,傳回
    .  根據皮爾遜生成電影評分标準化清單
    .  提取推薦電影
           

最終将上述三部分代碼合并,運作可得下圖所示結果:

100行代碼實作電影推薦引擎系統

總結

至此,我們實作了一個簡單的電影推薦引擎,當然了在實際工作中,推薦引擎遠遠比上述的複雜得多,但是我們可以通過這個小項目了解推薦引擎大概的思路。

具體的項目代碼放在 github 上面,關注公衆号『機器學習Club』回複「MR」擷取源碼連結。

100行代碼實作電影推薦引擎系統