是否曾经想象过亚马逊Prime、Netflix和谷歌如何轻松预测对电影的喜好?这不是什么高深的科学,当在这些平台上完成一部喜欢的电影/系列的观看并对其进行评分后,几秒钟内就会有更多的推荐添加到“可能喜欢”的部分!这就是机器学习。推荐系统通过学习用户过去的选择来预测和过滤用户偏好。就是这么简单!
一般来说,有两种类型的推荐系统:
在本文中,将开发一个基于IMDB前250部英文电影数据集的内容基础电影推荐系统。让简要了解一下将要涵盖的内容:
注意:在开始本节之前,请检查是否已安装依赖项!如果没有,请创建一个名为‘requirements.txt’的文件(与数据处理和代码在同一目录下),然后粘贴以下依赖项。然后打开一个新的终端,导航到目标目录,并输入‘pip install requirements.txt’。就这样!已经准备好开始项目了。
首先,让导入必要的库!
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
warnings.simplefilter(action='ignore', category=DeprecationWarning)
import pandas as pd
import numpy as np
from rake_nltk import Rake
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer
现在让加载并打印出DataFrame。
df = pd.read_csv('IMDB_Top250Engmovies2_OMDB_Detailed.csv')
df.head()
让快速了解一下数据集:
print('Rows x Columns : ', df.shape[0], 'x', df.shape[1])
print('Features: ', df.columns.tolist())
print('nUnique values:')
print(df.nunique())
输出:
行 x 列:250 x 5
特征:['Title', 'Director', 'Actors', 'Plot', 'Genre']
唯一值:
Title 250
Director 155
Actors 248
Plot 250
Genre 110
自然语言处理技术是处理文本数据的救星。由于数据不能直接输入到任何机器学习模型中,除非先清理它,这就是NLP发挥作用的地方!
让清理文本数据——
首先,让在DataFrame中创建一个新的列,它将包含模型所需的所有关键词。将其命名为‘Key_words’。进一步,使用一个非常特别的NLP库,称为RAKE(Rapid Automatic Keyword Extraction algorithm的缩写)。RAKE是一个关键词提取算法,通过确定词的频率及其在语料库中与其他词的相对出现频率来提取文本语料库中的关键词短语。
df['Plot'] = df['Plot'].str.replace('[^ws]','')
df['Key_words'] = '' # 初始化一个新列
r = Rake() # 使用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()) # 分配给新列
让看看生成的关键词:
BoW或词袋模型是一个信息检索(IR)模型,它对于创建文本的表示非常有用,描述了文档中词的出现情况,或者简单地意味着否经常在文本语料库中看到特定的词。
它对于创建语料库中频繁词的向量表示非常有用,然后计算相似度分数(很快就会看到的‘相似度矩阵’)。
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['Bag_of_words'] = df['Bag_of_words'].str.strip().str.replace(' ', ' ').str.replace(' ', ' ')
df = df[['Title','Bag_of_words']]
让看看新列‘Bag_of_words’:
在这里,将使用一个非常流行的工具名为Count Vectorizer将BoW转换为向量表示。Count Vectorizer,由自己的Scikit Learn库提供,根据每个词的频率计数将词转换为它们各自的向量形式。因此,一旦Count Vectorizer完成了它的工作,有了所有词计数的矩阵,将使用余弦相似度来生成相似度矩阵。
count = CountVectorizer()
count_matrix = count.fit_transform(df['Bag_of_words'])
cosine_sim = cosine_similarity(count_matrix, count_matrix)
print(cosine_sim)
让检查输出:
已经成功计算了250行x250列的相似度矩阵!
现在,所有的文本预处理和其他NLP责任都结束了,将创建一个最终的方法,它接受一个电影标题作为输入,并返回前5个相似的电影。
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_5_indices = list(score_series.iloc[1:6].index) # 获取前6个最相似电影的索引
for i in top_5_indices: # 将前10个相似电影的标题添加到recommended_movies列表
recommended_movies.append(list(df['Title'])[i])
return recommended_movies
recommend('The Avengers')