使用深度學習建立電影推薦系統,不到10分鐘即可進行DIY!

  • 2020 年 11 月 5 日
  • AI

譯者:AI研習社(季一帆

雙語原文鏈接://www.yanxishe.com/TextTranslation/2968



一個基於深度學習的電影推薦系統

你看過《盜夢空間》嗎?是否被影片中的夢中夢燒腦,或是想像現實世界中物品能否像電影中那樣漂浮在空中?至少目前我們沒有辦法使物體懸浮在空中,但是,數據科學家可以將python向量映射到多維空間。

本文將為介紹一個電影推薦系統,在推薦系統中,有許多電影向量懸浮於多維空間。同時,本文介紹的推薦系統無需租用伺服器、編寫程式碼、抓取數據或網頁維護等繁雜的工作,非常容易上手。此外,你還可以將其擴展到社交網路、股票、運動員、電視節目、書籍等領域。想像一下,眾多實例都會被映射到多維矢量空間,一覽無餘,那時多麼直觀啊。

你可以點擊該鏈接預覽我們的電影推薦系統。

學習本文需要滿足以下條件:對新概念的好奇心,渴望部署自己的Web應用程式。

同時,你最好對這些知識有所了解:word2vec嵌入,神經網路,Tensorflow,Github和推薦系統。

工具/概念:

1.Embedding:將高維向量投射到低維稠密向量空間。由於表示影像/單詞的像素或標記特徵可能需要數百萬個參數,因此我們需要定義一種受限統一結構,以此作為ML模型的輸入。在對高維或大量特徵進行建模以導出受限數據大小模式時,通常會遇到維數災難,即模型無法從輸入數據中提取相關模式。通常我們會使用主成分分析(PCA),TSNE或L1正則化等方法進行降維,但是對於極高維度和稀疏數據集(如Wikipedia語料庫中的數百萬個標記),基於神經網路的嵌入可以很好的提取相關屬性。

嵌入能夠捕獲標記或像素之間的語義相似性,並將其投影到向量空間中。例如,我們知道「費德勒」和「網球」之間存在密切關聯,那麼在100維嵌入空間中,「費德勒」比「川普」更接近「網球」。

圖示如下:

word2vec向量相似性

2. Tensorboard Projector:Tensorflow開源的Web應用,可以接收模型嵌入並在低維空間進行渲染,實現可視化交互。在tensorboard主頁上可以查看Wikipedia和MNIST語料庫的示例投影。建議讀者花時間具體了解下映射、濾波、嵌入空間以及各種降維演算法

Wikipedia的Tensorboard項目示例

3.降維演算法儘管模型嵌入維度為100,但人眼只能看到3維物品,為此,我們需要將矢量壓縮為2維或3維形式。

方法a:主成分分析PCA。一種常用的降維演算法,可提高模型的可解釋性,同時最大程度地減少資訊丟失。其主要思想是,構建新的互不相關的主成分,最大程度地提高方差,即將包含最大資訊的特徵轉化為低維主成分。根據主成分增量方差(如90%的方差)確定截止值。

方法bt分布隨機鄰域嵌入TSNE。一種用於探索高維數據的非線性降維演算法,將多維數據映射到適合於人類觀察的兩個或多個維度。該演算法的關鍵在於最小化兩個分布之間的差異,即測量輸入對象的成對相似性的分布以及相應低維嵌入點的成對相似性的分布。

PCA和TSNE之間的主要區別為:一是PCA為線性降維,而TSNE是非線性度降維;二是目標函數不同,PCA試圖保留全局數據結構,而TSNE保留局部結構。

Geeks For Geeks更詳細的指出了TSNE和PCA之間的八項區別,為人們提供了很好的參考。

4.MovieLens數據集:作為電影推薦系統的標準數據集,該數據集提供[userid-movieid]數據,包含58,000電影和2,600萬評分。自1997年以來,該數據對於推動推薦系統的發展起著重要作用。在Google books搜索「 movielens」得到2,750個結果,在Google Scholar搜索得到7,580個結果,MovieLens數據集的影響可見一斑。應用該數據集可基於SVD矩陣或神經網路構建面向電影條目或是用戶的推薦系統,並根據過去的偏好預測新用戶評分。

根據上述這些概念,我們可以創建一個電影推薦的Web應用,使用的電影數據包括3700Netflix電影和上述數據集中的58k電影。(數據源見此)

就像word2vec嵌入將相近單詞映射到向量空間後距離較小,我們在100維向量空間中對電影進行嵌入,這樣就將數據維度從58k(類似one-hot表示)減少到100k(嵌入表示)。

輸入MovieLens數據集,該數據集包含用戶對電影的評分,分值從0到5。為避免雜訊,MovieLens剔除了評分次數低於20且統計不準確的用戶。同時,該數據集有諸多版本,範圍從[1k用戶* 1.7k電影]到[280k用戶* 58k電影],使用時請注意查看。對基於用戶的協同過濾,可以忽略分級品質,以0/1表示用戶是否對電影進行評分。 

根據之前的介紹,電影推薦可分為以下三種類型:

1.基於流行度:標識過去X時段內最受歡迎(觀看最多)的電影,將這些電影推薦給所有用戶。

2.基於電影屬性:根據電影的元標記(如演員,導演,語言,發行年份等)進行推薦。但這樣的缺點是,電影的屬性不會隨時間改變,無法考慮用戶行為進行實時推薦。

3.基於用戶:根據用戶的觀看模式和喜好,對用戶進行分組,為用戶推薦同組內其他用戶觀看的電影。例如,如果我觀看了Inception和Dark Knight,其他看過這兩部電影的人也喜歡看Prestige,那麼推薦給我Prestige是較好的選擇。

關於基於電影的協同過濾創建推薦系統,我之前寫過一篇詳細的部落格。感興趣的讀者可以點此查看,並將推薦結果與基於用戶的推薦結果進行比較。

對於新興的OTT平台,由於沒有資源生成元標籤和標註電影,同時希望用戶與平台進行隱式交互,因此基於用戶的協同過濾(CF)方法是最適合的。至於像Netflix,Youtube這樣的大公司,實際上使用Prime-Video混合推薦方法。在本文中,我們僅討論基於用戶的協同過濾,即通過用戶矢量表徵電影。數據集結構如下:

MovieLens輸入數據格式

與word2vec嵌入類似,我們通過用戶ID訓練淺層神經網路。經過訓練,我們在用戶ID嵌入中實現類似「網球-費德勒」的關係。至此,我們可以找到相似的用戶,並可以將用戶分為幾類,通過推送或電子郵件發送有針對性的訊息。除了基於相似用戶的推薦方法,我們還可以根據電影進行推薦,這就需要對電影資訊進行類似操作了。

接下來是句子嵌入,即將用戶視為句子,捕獲句子的語義相似性。通過BERT,Elmo,Doc2Vec和Universal Sentence Encoder等方式均可方便的實現句子嵌入,具體選擇哪種方式主要取決於模型的速度,根據我的測試,Fast_Sentence_Embeddings(FSE)是我比較推薦的方法,該方法直接根據各詞的word2vec生成複合向量。對於BERT這樣的SOTA系統而言,用戶ID很難表現出語義相似性,因此,即使使用經過Wikipedia或GoogleNews預訓練的模型,也不會有太大差異,這樣,模型的速度就成為唯一的衡量標準。FSE每秒可處理約500K句子,而預訓練編碼模型低於每秒100句。

之後,將句子向量投影到多維空間中。例如,”Obama speaks to the media in Illinois” 和”The President greets the press in Chicago”表達的意思相近,在多維空間中距離就比較近。

基於上下文的句子相似性

Movielens數據的電影嵌入程式碼:

base=[]        
for i in range(0,size):            
#print(kw[0][i].split(” “))            
string=kw[i].split(“,”)            
#print(string)            
base=base+string                
if(len(base)>2):            
base = ‘,’.join(base)        
return base
s_test=links
s_test=s_test[[‘userId’,’movieId’]].drop_duplicates()
s_test[‘keywords_comb’]=s_test.groupby([‘movieId’])[‘userId’].transform(combine)
print(“Start of Word2Vec”,datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’))
data=s_test[[‘movieId’,’keywords_comb’]].drop_duplicates()
data[‘word_count’] = data.keywords_comb.str.count(‘,’)+1
data=data[data[‘word_count’]>5]
data[‘tokenise’] = data[‘keywords_comb’].astype(‘str’).apply(lambda x: [x for x in x.split(‘,’)])
a1=data[‘tokenise’].tolist()
model_items = Word2Vec(a1, size=100)
#data=data.dropna()
print(“Start of Sentence To vec”,datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’))
sent=data[‘keywords_comb’].astype(‘str’).apply(lambda x: [x for x in x.split(‘,’)]).tolist()
s = IndexedList(sent)
from fse.models import uSIF
model = uSIF(model_items, lang_freq=”en”)

完成影片嵌入後,我們將結合tensorboard和Github完成電影推薦系統的部署。特別感謝Google對tensorboard開源的工作。

使用嵌入結構構建web步驟如下:

1.將嵌入數據上傳到GitHub gist,並在config JSON中進行更新。對於初學者,可以直接使用我在此託管的嵌入數據。

2.將元數據上傳到Github gist上,以便圖示節點帶有標籤。

3.創建一個JSON文件並將URI提供給TensorflowL,見JSON配置示例

Github輸入配置文件

4.部署Web應用程式!

web應用包括以下兩種:a. Floating recommender without images and b. Floating recommender with images

Ratatouille示例

5.使用tensorboard可視化交互,單擊某一電影即可查找類似的電影,還提供TSNE或PCA降維操作。

總結:本文介紹了如何處理Movielens數據集,矢量嵌入(文中指用戶ID),基於FSE的句子相似度矩陣以及使用Google的TensorFlow部署web電影推薦應用。

帶有電影海報的推薦頁面

希望讀者自行在電影或其他相關數據集上DIY自己的Web應用程式。如果您遇到任何問題或有其他有趣的想法,歡迎交流。

其他可用於推薦的數據集:

1. 圖書 //www.kaggle.com/zygmunt/goodbooks-10k

2. 電子商務產品 //www.kaggle.com/c/instacart-market-basket-analysis

3. 餐廳 //towardsdatascience.com/how-to-build-a-restaurant-recommendation-system-using-latent-factor-collaborative-filtering-ffe08dd57dca

4. 美食 //github.com/hasan-kamal/Cuisine-Prediction


AI研習社是AI學術青年和AI開發者技術交流的在線社區。我們與高校、學術機構和產業界合作,通過提供學習、實戰和求職服務,為AI學術青年和開發者的交流互助和職業發展打造一站式平台,致力成為中國最大的科技創新人才聚集地。

如果,你也是位熱愛分享的AI愛好者。歡迎與譯站一起,學習新知,分享成長。