如何利用自然语言处理构建基于内容的电影推荐系统

简介: 本文教你如何构建属于你自己的推荐系统,不容错过。

1
“empty brown theater chairs” by Tyler Callahan on Unsplash

你是否有过这样的疑惑:为什么Netflix,Amazon,Google总能推荐到你比较感兴趣的产品?我们有时会对互联网上的产品进行评分,以此体现我们对产品的偏好,同时,推荐系统会利用我们分享的数据,生成推荐结果。主流的推荐系统算法大致分为两类:基于用户历史数据的协同过滤算法和基于内容数据的过滤算法。两者的区别其实从名称上便可看出,但接下来我们将以电影推荐为例进一步阐述二者之间的不同。

协同过滤(Collaborative filters)

协同过滤依赖用户的历史评分数据,为用户推荐自己未曾看过,而与自己相似的用户已经观看过的电影。为了确定两个用户之间是否相似,协同过滤会结合用户所看过的电影以及他们对电影的评分。

1
Collaborative-based filter.

协同过滤算法的准确性依赖于用户对产品的历史评分,但并非所有的用户都会持续不断的对产品进行评价,有一些用户甚至未曾评价过任何产品。协同过滤算法的另一个特点是能提供多样化的建议,根据应用场景的不同,对推荐系统的评价也不尽相同。举个例子,假设用户A非常喜欢反乌托邦电影和黑色喜剧,用户B也喜欢反乌托邦电影,但从来没有看过黑色喜剧。协同过滤算法将根据用户A和用户B对反乌托邦电影的喜爱,为用户B推荐黑色喜剧。这个推荐结果将会产生两种影响:用户B也非常喜欢黑色喜剧,则推荐成功;如若用户B喜欢轻喜剧,那么推荐是不成功的。

基于内容的过滤(Content-based filters)

1
Content-based filter.

基于内容的推荐不再涉及其他用户,只根据我们自身的喜爱,简单的选择内容相似的项目进行推荐。

相比协同过滤算法,基于内容的推荐减少了推荐的多样性,但用户是否对项目进行了评分便不再影响推荐结果。还是前一个例子,也许用户B潜意识里也喜欢黑色喜剧,但除非他自己决定主动尝试,否则他永远也不会知道自己的这个喜好,因为基于内容的推荐只会继续推荐反乌托邦或同种类型的电影。以电影为例,在计算相似度的时候,除了考虑片名,还可以考虑导演,主要演员等因素。

到目前为止,我已多次提及到相似度(similarity)这个词,但是它究竟是什么呢?相似度是我们在计算用户之间或者项目之间的相似性时可以使用的度量标准之一。它虽然不可量化,但却是可以通过计算得到。在构建基于内容的推荐系统之前,我将简明地对相似度的概念做一个讲解。

余弦相似度(Cosine similarity)

向量可以是二维,三维甚至n维的。让我们以二维向量为例回顾一下点积(dot product)。两个向量之间的点积等于其中一个向量在另一个向量上的投影。因此,两个相同向量(即相同分量)之间的点积等于该向量模的平方,而如果这两个向量垂直,则点积为零。通常,对于n维向量,点积的计算公式如下所示。

1
Dot product.

点积在计算相似度时非常重要,因为它与相似度直接相关。两个向量u和v之间相似度是由它们之间的点积和它们自身的模的比值定义的。

1
Similarity.

透过相似度的定义我们可以看出,如果两个向量相同,相似度为1,如果两个向量是正交的,相似度为0。换句话说,相似度是一个在0和1之间有界的数,它反应了这两个向量的相似程度。

下面进入实战阶段。

1. 数据收集

实验数据来自IMDB数据集,本次只选取了前250个高评分电影。数据集列表有250行(250部电影),38列。在构建模型的时候,我们只考虑了电影导演、主要演员、电影类型和电影情节这几类特征。

import pandas as pd
from rake_nltk import Rake
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer

df = pd.read_csv('https://query.data.world/s/uikepcpffyo2nhig52xxeevdialfl7')

df = df[['Title','Genre','Director','Actors','Plot']]
df.head()

部分数据如下图所示:

1

我们将每一部包含上述特征的电影作为一列,以便能更好的进行向量化。我们还会使用到自然语言处理,将文字转换为向量能帮助我们更好的计算余弦相似度。

接下来,我们将对数据进行清洗。

2. 数据清洗(Data cleaning)

nltk(natural language toolkit)是一套基于python的自然语言处理工具集,它能够帮助我们从文本中提取关键字,甚至可以为每个字打分。我们将使用Rake功能从Plot列中提取出关键字,相较于使用完整的句子对电影情节进行描述,我更青睐于使用一些与电影情节最相关的词语。为此,我在Plot列中,对每行都使用了Rake功能,将获取到的关键词独立作为新的一列,命名Key_words。

# initializing the new column
df['Key_words'] = ""
for index, row in df.iterrows():
    plot = row['Plot']
   
# instantiating Rake, by default it uses english stopwords from NLTK

# and discards all puntuation characters as well
    r = Rake()

# extracting the words by passing the text
    r.extract_keywords_from_text(plot)

# getting the dictionary whith key words as keys and their scores as values
    key_words_dict_scores = r.get_word_degrees()    

# assigning the key words to the new column for the corresponding movie
    row['Key_words'] = list(key_words_dict_scores.keys())
# dropping the Plot column
df.drop(columns = ['Plot'], inplace = True)

除了Plot列,还需要对其余列的数据进行清洗。同时,为了避免重复,需要对所有的内容进行小写转换,并且将所有的名和姓合并到一个单词中。试想:如果电影A的导演是Danny Boyle,而电影B的主要演员是Danny DeVito,那么电影A和B会因为Danny而拥有较高的相似度,但这并不是我们想要的。

在进行了所有的清理和合并之后,我将索引重新分配到movie title列,下图是为向量化准备的Dataframe。

1

3. 建模(Modeling)

为了充分利用NLP挖掘电影之间的相似性,我们需要将文字转为词向量。我更倾向于使用CountVecorizer而非TfIdfVecorizer,因为我只需要一个简单的频率计数器来统计bag_of_words列中的每个单词。Tf-Idf认为字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。这不适用于我们今天所讲的应用场景,毕竟每个单词对于相似度的衡量都非常重要。一旦我们得到了包含每个单词计数的矩阵,便可应用cosine_similarity函数对相似度进行计算。

# instantiating and generating the count matrix
count = CountVectorizer()
count_matrix = count.fit_transform(df['bag_of_words'])

# generating the cosine similarity matrix
cosine_sim = cosine_similarity(count_matrix, count_matrix)

相似度矩阵如下图所示:

1
Similarity matrix.

对角线上的值都为1,因为每部电影在和自己比较时是完全相似的。同时,这是一个对称矩阵,因为电影A和B与电影B与A之间的相似度是相同的。

接下来,我们将电影标题作为输入,返回前10个类似的电影作为推荐结果。此外,我们还给电影标题加上了数字索引,以匹配相似矩阵到实际电影标题的索引。实际上,函数一旦接收到输入,就会检测出与所输入的电影相对应的行中最大的10个数字,获取相应的索引并将其与电影标题系列匹配,以返回推荐的电影列表。当函数选取10个最高的相似度值时,丢弃了单位值,这样就不会返回与输入相同的电影标题。

# creating a Series for the movie titles so they are associated to an ordered numerical
# list I will use in the function to match the indexes
indices = pd.Series(df.index)

#  defining the function that takes in movie title 
# as input and returns the top 10 recommended movies
def recommendations(title, cosine_sim = cosine_sim):
    
# initializing the empty list of recommended movies
    recommended_movies = []
    
# gettin the index of the movie that matches the title
    idx = indices[indices == title].index[0]

# creating a Series with the similarity scores in descending order
    score_series = pd.Series(cosine_sim[idx]).sort_values(ascending = False)

# getting the indexes of the 10 most similar movies
    top_10_indexes = list(score_series.iloc[1:11].index)
    
# populating the list with the titles of the best 10 matching movies
    for i in top_10_indexes:
        recommended_movies.append(list(df.index)[i])
        
    return recommended_movies

4. 推荐系统测试(Testing the recommender)

由于我们只是用了包含250部电影的数据集,所构建的推荐系统性能有限。在测试的时候,输入了我喜爱的电影“Fargo”,下图为推荐的前10部电影。

1
Movies recommended because I like Fargo.

我对推荐结果是满意的,从导演和情节上可以看出它们与我喜爱的电影有一些相似之处。上面列表中有我已经看过的电影,我喜欢它们就像我喜欢“Fargo”一样,接下来我会去看列表中我还没有看过的那几部电影。

以上为译文

本文由阿里云云栖社区组织翻译。

文章原标题《How to build a content-based movie recommender system with Natural Language Processing》,作者:Emma Grimaldi,译者:Elaine,审校:袁虎。

文章为简译,更为详细的内容,请查看原文

相关文章
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
springboot基于人工智能和自然语言理解技术的医院智能导医系统源码
智能导诊系统可为患者提供线上挂号智能辅助服务,患者根据提示手动输入自己的基本症状,通过智能对话方式,该系统会依据大数据一步步帮助患者“诊断”,并最终推荐就医的科室和相关专家。患者可自主选择,实现“一键挂号”。这一模式将精确的导诊服务前置,从源头上让医疗服务更高效。
370 2
|
3月前
|
机器学习/深度学习 存储 人工智能
人工智能自然语言对话系统
人工智能自然语言对话系统
43 1
|
2月前
|
机器学习/深度学习 搜索推荐 算法
构建推荐系统:Python 与机器学习
推荐系统是一种利用机器学习算法和用户的历史行为数据来预测用户可能感兴趣的内容的技术。在当今的数字化时代,推荐系统已经成为许多互联网应用的核心组件,如电子商务、社交媒体和在线娱乐等。在 Python 中,我们可以使用各种机器学习库和工具来构建和实现推荐系统。
|
13天前
|
JavaScript 搜索推荐 前端开发
音乐发现平台:借助Python和Vue构建个性化音乐推荐系统
【4月更文挑战第11天】本文介绍了如何使用Python和Vue.js构建个性化音乐推荐系统。首先确保安装Python、Node.js、数据库系统和Git。后端可选择Flask或Django搭建RESTful API,处理歌曲数据。前端利用Vue.js创建用户界面,结合Vue CLI、Vuex和Vue Router实现功能丰富的SPA。通过Vuex管理状态,Axios与后端通信。这种前后端分离的架构利于协作和系统扩展,助力打造定制化音乐体验。
|
24天前
|
机器学习/深度学习 数据采集 算法
基于Apriori关联规则的电影推荐系统(附python代码)
这是一个基于Apriori算法的电影推荐系统概览。系统通过挖掘用户评分数据来发现关联规则,例如用户观看某部电影后可能感兴趣的其他电影。算法核心是逐层生成频繁项集并设定最小支持度阈值,之后计算规则的置信度。案例中展示了数据预处理、频繁项集生成以及规则提取的过程,具体包括用户评分电影的统计分析,如1-5部电影的评分组合。最后,通过Python代码展示了Apriori算法的实现,生成推荐规则,并给出了一个简单的推荐示例。整个过程旨在提高推荐的精准度,基于用户已评分的电影推测他们可能尚未评分但可能喜欢的电影。
基于Apriori关联规则的电影推荐系统(附python代码)
|
1月前
|
机器学习/深度学习 自然语言处理
基于深度学习的自然语言处理技术在智能客服系统中的应用
【2月更文挑战第21天】随着人工智能技术的不断发展,自然语言处理(NLP)技术在各个领域得到了广泛应用。本文主要探讨了基于深度学习的自然语言处理技术在智能客服系统中的应用。首先介绍了深度学习和自然语言处理的基本概念,然后分析了智能客服系统的工作原理和技术要求,接着详细阐述了基于深度学习的自然语言处理技术在智能客服系统中的具体应用,包括语义理解、情感分析和问答系统等。最后对基于深度学习的自然语言处理技术在智能客服系统中的优势和挑战进行了总结。
44 1
|
1月前
|
搜索推荐 算法 Java
基于springboot+vue协同过滤算法的电影推荐系统
基于springboot+vue协同过滤算法的电影推荐系统
|
1月前
|
设计模式 搜索推荐 测试技术
电影推荐系统的设计与实现(论文+系统)_kaic
电影推荐系统的设计与实现(论文+系统)_kaic
|
3月前
|
搜索推荐 前端开发 算法
协同过滤算法|电影推荐系统|基于用户偏好的电影推荐系统设计与开发
协同过滤算法|电影推荐系统|基于用户偏好的电影推荐系统设计与开发
|
4月前
|
机器学习/深度学习 搜索推荐 大数据
[机器学习]电影推荐系统设计(五)
[机器学习]电影推荐系统设计(五)
56 0