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

本文涉及的产品
NLP自然语言处理_高级版,每接口累计50万次
NLP自然语言处理_基础版,每接口每天50万次
NLP 自学习平台,3个模型定制额度 1个月
简介: 本文教你如何构建属于你自己的推荐系统,不容错过。

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,审校:袁虎。

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

相关文章
|
26天前
|
人工智能 自然语言处理 前端开发
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务
Director 是一个构建视频智能体的 AI 框架,用户可以通过自然语言命令执行复杂的视频任务,如搜索、编辑、合成和生成视频内容。该框架基于 VideoDB 的“视频即数据”基础设施,集成了多个预构建的视频代理和 AI API,支持高度定制化,适用于开发者和创作者。
87 9
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务
|
2月前
|
机器学习/深度学习 数据采集 搜索推荐
利用Python和机器学习构建电影推荐系统
利用Python和机器学习构建电影推荐系统
125 1
|
2月前
|
机器学习/深度学习 自然语言处理 PyTorch
从零开始构建nlp情感分析模型!
本教程介绍了如何使用PyTorch和Hugging Face的Transformers库构建一个情感分析模型。主要内容包括导入所需库、读取训练数据集、加载预训练的BERT模型和分词器、定义情感数据集类、划分训练集和验证集、创建数据加载器、设置训练参数、训练模型、评估模型性能以及定义和测试预测函数。通过这些步骤,可以实现一个简单而有效的情感分析模型。
236 2
|
3月前
|
搜索推荐 关系型数据库 数据库
#646253#基于django/neo4j的电影打分推荐系统
#646253#基于django/neo4j的电影打分推荐系统
26 0
|
3月前
|
机器学习/深度学习 数据采集 自然语言处理
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
|
4月前
|
机器学习/深度学习 自然语言处理 搜索推荐
探索深度学习与自然语言处理(NLP)在智能客服系统中的创新应用
探索深度学习与自然语言处理(NLP)在智能客服系统中的创新应用
335 0
|
5月前
|
机器学习/深度学习 自然语言处理 PyTorch
PyTorch与Hugging Face Transformers:快速构建先进的NLP模型
【8月更文第27天】随着自然语言处理(NLP)技术的快速发展,深度学习模型已经成为了构建高质量NLP应用程序的关键。PyTorch 作为一种强大的深度学习框架,提供了灵活的 API 和高效的性能,非常适合于构建复杂的 NLP 模型。Hugging Face Transformers 库则是目前最流行的预训练模型库之一,它为 PyTorch 提供了大量的预训练模型和工具,极大地简化了模型训练和部署的过程。
281 2
|
5月前
|
存储 自然语言处理 算法
使用面向对象方法优化自然语言处理系统
【8月更文第11天】自然语言处理(NLP)是计算机科学领域的一个分支,专注于让计算机能够理解、解释和生成人类语言。NLP系统通常需要处理大量不同的任务,如文本分类、情感分析、机器翻译等。这些任务往往涉及复杂的算法和技术栈,而面向对象编程(OOP)可以作为一种强大的工具来组织这些复杂的逻辑,使得代码更加模块化、可扩展且易于维护。
52 3
|
5月前
|
存储 人工智能 搜索推荐
【2023年第十一届泰迪杯数据挖掘挑战赛】C题:泰迪内推平台招聘与求职双向推荐系统构建 27页论文及实现代码
本文介绍了2023年第十一届泰迪杯数据挖掘挑战赛C题的解决方案,详细阐述了如何构建泰迪内推平台的招聘与求职双向推荐系统,包括数据收集、分析、画像构建、岗位匹配度和求职者满意度模型的建立,以及履约率最优化的推荐模型,提供了27页的论文和实现代码。
108 0
【2023年第十一届泰迪杯数据挖掘挑战赛】C题:泰迪内推平台招聘与求职双向推荐系统构建 27页论文及实现代码
|
5月前
|
Apache UED 数据安全/隐私保护
揭秘开发效率提升秘籍:如何通过Apache Wicket组件重用技巧大翻新用户体验
【8月更文挑战第31天】张先生在开发基于Apache Wicket的企业应用时,发现重复的UI组件增加了维护难度并影响加载速度。为优化体验,他提出并通过面板和组件重用策略解决了这一问题。例如,通过创建`ReusableLoginPanel`类封装登录逻辑,使得其他页面可以轻松复用此功能,从而减少代码冗余、提高开发效率及页面加载速度。这一策略还增强了应用的可维护性和扩展性,展示了良好组件设计的重要性。
63 0