在這個教程中,我們将實作一個基于電影内容本身相似性的推薦系統。我們将利用自然語言處理/ NLP 技術來提取每個電影的特征,然後建立不同電影之間的餘弦相似性矩陣,最後利用相似矩陣來推薦指定電影的10個最相似電影。

快速掌握Python開發技能,推薦彙智網的 Python線上課程 。
當我們評價網際網路上的産品和服務時,我們表達并分享出來的傾向性,被推薦系統用來生成個性化推薦。最常見的例子就是亞馬遜的商品推薦、谷歌的搜尋結果推薦和Netflix上的視訊推薦。
有兩種類型的推薦系統:
- 協同過濾 - 基于使用者的評價和消費行為來分組相似的使用者,然後向使用者推薦可能感興趣的産品或服務
- 基于内容的過濾 - 基于産品/服務本身的相似性向使用者推薦
在這個教程中,我們将利用電影的特征,例如風格、劇情、導演和主要演員等,來計算不同電影之間的餘弦相似度。我們使用從data.world下載下傳的IMDB前250部英文電影作為我們的
資料集1、導入Python庫和資料集
確定已經安裝了RAKE庫,或者參考以下指令安裝:
pip install rake_nltk
然後使用以下代碼讀入資料集:
from rake_nltk import Rake
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizerdf = pd.read_csv('IMDB_Top250Engmovies2_OMDB_Detailed.csv')
df.head()
資料集中有250部電影(行),每部電影包含38個屬性(列)。不過我們隻需要
用到其中的5個屬性: ‘Title’, ’Director’, ’Actors’, ’Plot’, and ’Genre’。
下面的代碼顯示10個流行的導演的作品數量直方圖:
df['Director'].value_counts()[0:10].plot('barh', figsize=[8,5], fontsize=15, color='navy').invert_yaxis()
2、資料預處理
首先使用NLP對資料進行預處理,将屬性合并為一列,然後進行矢量化,每個單詞對應一個得分,最後計算餘弦相似性得分。
我們使用Rake函數來提取劇情列中整句話的最相關單詞,并将提取結果放入一個新的‘Key_words’:
df['Key_words'] = ''
r = Rake()for index, row in df.iterrows():
r.extract_keywords_from_text(row['Plot'])
key_words_dict_scores = r.get_word_degrees()
row['Key_words'] = list(key_words_dict_scores.keys())
演員和導演的名字被小寫并轉換為唯一辨別值。我們将姓、名合并,這樣Chris Evans和Chris Hemsworth就不會有相似性,否則的話,這兩個名字就會有50%的相似性,因為都包含了Chris:
df['Genre'] = df['Genre'].map(lambda x: x.split(','))
df['Actors'] = df['Actors'].map(lambda x: x.split(',')[:3])
df['Director'] = df['Director'].map(lambda x: x.split(','))for index, row in df.iterrows():
row['Genre'] = [x.lower().replace(' ','') for x in row['Genre']]
row['Actors'] = [x.lower().replace(' ','') for x in row['Actors']]
row['Director'] = [x.lower().replace(' ','') for x in row['Director']]
3、建立單詞的表示
在資料預處理之後,這四個列‘Genre’, ‘Director’, ‘Actors’ 和 ‘Key_words’ 合并為一個新
的列‘Bag_of_words’,這樣最終的資料幀隻有2列:
df['Bag_of_words'] = ''
columns = ['Genre', 'Director', 'Actors', 'Key_words']for index, row in df.iterrows():
words = ''
for col in columns:
words += ' '.join(row[col]) + ' '
row['Bag_of_words'] = words
df = df[['Title','Bag_of_words']]
4、建立相似性矩陣
推薦模型隻能讀取并比較向量,是以我們需要将
Bag_of_words
列使用
CountVectorizer
轉換為向量表示,這是一個簡單的頻率計數器。一旦我們得到了所有單詞的計數矩陣,就可以利用
cosine_similarity
函數來比較電影的相似性。
count = CountVectorizer()
count_matrix = count.fit_transform(df['Bag_of_words'])cosine_sim = cosine_similarity(count_matrix, count_matrix)
print(cosine_sim)
接下來是建立電影标題序列,序列的索引對應相似矩陣的行和列。
indices = pd.Series(df['Title'])
5、運作測試推薦模型
最後一步是建立一個函數,以電影标題為輸入,傳回其最相似的10個電影。這個函數将輸入電影标題與相似矩陣進行比較,以降序提取相似的電影:
def recommend(title, cosine_sim = cosine_sim):
recommended_movies = []
idx = indices[indices == title].index[0]
score_series = pd.Series(cosine_sim[idx]).sort_values(ascending = False)
top_10_indices = list(score_series.iloc[1:11].index)
for i in top_10_indices:
recommended_movies.append(list(df['Title'])[i])
return recommended_movies
現在我們可以測試模型了。輸入“The Avengers” 看看推薦結果:
recommend('The Avengers')
6、源代碼
你可以在
這裡下載下傳源代碼。
原文連結:
用NLP實作基于内容的電影推薦系統 - 彙智網