百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

影迷速来!建立属于自己的电影推荐系统吧

toyiye 2024-06-21 12:21 9 浏览 0 评论

全文共5860字,预计学习时长20分钟或更长


图片来源:unsplash.com/Myke Simon


通过学习本教程,你将会达到下面的目标:


· 掌握什么是推荐系统,系统如何运作,以及它们之间不同的特点。


· 使用Python以及TMDB 5000部电影数据库来执行几个推荐系统。



什么是推荐系统?

推荐系统(也常被称为推荐引擎/推荐平台),旨在预测用户对可获取物品的兴趣(例如Spotify上的歌曲)并给出相应的推荐。以下是两种主要的推荐系统:


· 基于内容的过滤系统,会基于物品本身的特性给出推荐。因此,如果一名网飞用户热衷于科幻影片,网飞就能更迅速地给其推荐另一部科幻电影,而非浪漫爱情喜剧。我们接下来就将在Python上执行这一推荐系统。


· 协同过滤系统会基于用户的反应给出推荐。比如说,有两位用户都在亚马逊上购买了电子吉他,其中一位用户同时还购买了放大器。那么,亚马逊就会预测另一位用户也对该放大器感兴趣,然后将这款产品推荐给该用户。


感谢Ibtesam Ahmed为这个数据库提供的 Kaggle核函数。本文旨在用中等程序化格式遵循她的教程。


建立一个基础推荐系统

启动


和往常一样,首先要导入必需的工具包和数据库:

import pandas as pd
import numpy as np
 
# Dataset:
# https://www.kaggle.com/tmdb/tmdb-movie-metadata/downloads/tmdb-5000-movie-dataset.zip/2
 
from google.colab import files
uploaded = files.upload()
 
credits = pd.read_csv("tmdb_5000_credits.csv")
 
movies_incomplete = pd.read_csv("tmdb_5000_movies.csv")
 
# Shapes of dataframes
print("credits:", credits.shape)
print("movies_incomplete:", movies_incomplete.shape)


这两个输入语句提供了以下输出结果:

· credits: (4803, 4)

· movies_incomplete: (4803, 20)

现在我们就用4803部电影的数据进行操作。注意数据现在会被分成两类数据帧。

遵循本教程时,始终对照此要点会让操作变得十分简单。

先从创建两个最基础的推荐系统开始,目的是要给用户推荐评分最高的电影列表和最受欢迎的电影列表。但首先要计算出每部电影平均评分(投票平均值)的加权平均值。依照Ibtesam的做法,使用IMDB(前称)的公式来计算电影的加权评级。


http://trailerpark.weebly.com/imdb-rating.html


以下是如何得出加权平均值的例子:

V = movies_clean['vote_count']
R = movies_clean['vote_average']
C = movies_clean['vote_average'].mean()
m = movies_clean['vote_count'].quantile(0.70)
 
movies_clean['weighted_average'] = (V/(V+m) * R) + (m/(m+V) * C)


选定0.70作为 quantile()的参数,以表明我们只关注数据库中获得至少70%投票的电影。选择m的数值就比较随意,因此需要做一些实验。

推荐系统模型1:

准备开始建立第一个推荐系统。让我们一起推荐加权评分值最高的10部电影。

import matplotlib.pyplot as plt
import seaborn as sns
 
wavg = movies_ranked.sort_values('weighted_average', ascending=False)
 
plt.figure(figsize=(16,6))
 
ax = sns.barplot(x=wavg['weighted_average'].head(10), y=wavg['original_title'].head(10), data=wavg, palette='deep')
 
plt.xlim(6.75, 8.35)
plt.title('"Best" Movies by TMDB Votes', weight='bold')
plt.xlabel('Weighted Average Score', weight='bold')
plt.ylabel('Movie Title', weight='bold')
 
plt.savefig('best_movies.png')


接下来就能获得评分最高的电影的图表:




可以看到,运行系统推荐的大都是经典影片。但如果想要推荐在TMDB用户中流行的电影呢?

推荐系统模型2:

可以利用数据库中的流行性特点,从而基于流行度来推荐电影。

popular = movies_ranked.sort_values('popularity', ascending=False)
 
plt.figure(figsize=(16,6))
 
ax = sns.barplot(x=popular['popularity'].head(10), y=popular['original_title'].head(10), data=popular, palette='deep')
 
plt.title('"Most Popular" Movies by TMDB Votes', weight='bold')
plt.xlabel('Popularity Score', weight='bold')
plt.ylabel('Movie Title', weight='bold')
 
plt.savefig('popular_movies.png')


现在就能看到基于流行度评分的推荐:


正如此前预计的一样:《小黄人大眼萌》在众多影片中脱颖而出。那么,如果想要基于加权平均值和流行度来推荐电影呢?

推荐系统模型3:

为了避免《小黄人大眼萌》超高的人气分数对评分系统产生影响,我们对加权平均值和受欢迎度的数据进行了标准化调整:加权平均值和欢迎度评分各分得50%的比例。但同时,不要害怕用这一平分比例做做试验。


# My own recommender system
# half/half recommendation based on scaled weighted average & popularity score
 
from sklearn import preprocessing
 
min_max_scaler = preprocessing.MinMaxScaler()
movies_scaled = min_max_scaler.fit_transform(movies_clean[['weighted_average', 'popularity']])
movies_norm = pd.DataFrame(movies_scaled, columns=['weighted_average', 'popularity'])
movies_norm.head()
 
movies_clean[['norm_weighted_average', 'norm_popularity']] = movies_norm
 
movies_clean['score'] = movies_clean['norm_weighted_average'] * 0.5 + movies_clean['norm_popularity'] * 0.5
movies_scored = movies_clean.sort_values(['score'], ascending=False)
movies_scored[['original_title', 'norm_weighted_average', 'norm_popularity', 'score']].head(20)


现在得到了一个新的评分系统,将电影的加权平均得分和欢迎度得分都计算在内。下面再来看看该推荐系统会推荐哪些电影:

scored = movies_clean.sort_values('score', ascending=False)
 
plt.figure(figsize=(16,6))
 
ax = sns.barplot(x=scored['score'].head(10), y=scored['original_title'].head(10), data=scored, palette='deep')
 
#plt.xlim(3.55, 5.25)
plt.title('Best Rated & Most Popular Blend', weight='bold')
plt.xlabel('Score', weight='bold')
plt.ylabel('Movie Title', weight='bold')
 
plt.savefig('scored_movies.png')


这就是基于各占50%比例得出的推荐影片:



以上的推荐系统都能依照设计运作,但显然还可以继续改进。现在我们就一起来看看基于内容的过滤系统。


基于内容的过滤系统


现在要利用某一电影的特点来给用户推荐其他电影。继续遵循Ibtesam的示例,现在来根据电影在概述栏给出的情节梗概来进行推荐。比方说,如果用户提供了一部电影的名字,我们的目标就是推荐其他与该电影情节梗概相似的影片。


字节矢量化和TF-IDF算法

在开始分析情节梗概之前,需要将概述栏中的文本转化为文字矢量,同时也要在概述中加入TF-IDF算法。


from sklearn.feature_extraction.text import TfidfVectorizer
 
# Using Abhishek Thakur's arguments for TF-IDF
tfv = TfidfVectorizer(min_df=3, max_features=None,
 strip_accents='unicode', analyzer='word',token_pattern=r'\w{1,}',
 ngram_range=(1, 3), use_idf=1,smooth_idf=1,sublinear_tf=1,
 stop_words = 'english')
 
# Filling NaNs with empty string
movies_clean['overview'] = movies_clean['overview'].fillna('')
 
# Fitting the TF-IDF on the 'overview' text
tfv_matrix = tfv.fit_transform(movies_clean['overview'])
 
tfv_matrix.shape


这样就得到了以下输出结果:

· (4803, 10417)

我们在情节梗概中用了约10000个不同的词语来描述5000部影片(注意该数据要小于Ibtesam的数据,因为我们通过 min_df=3公式将最小词频提高到3个)。


计算相似分数

现在有了词语矩阵,就可以开始计算相似分数了。这个矩阵有助于选出与由用户提交的电影情节梗概相似的影片。Ibtesam选用了线性核函数,但本文想用sigmoid核函数核做个有趣的实验。幸运的是,我们得到了类似的结果:

from sklearn.metrics.pairwise import sigmoid_kernel
 
# Compute the sigmoid kernel
sig = sigmoid_kernel(tfv_matrix, tfv_matrix)
 
# Reverse mapping of indices and movie titles
indices = pd.Series(movies_clean.index, index=movies_clean['original_title']).drop_duplicates()
 
# Credit to Ibtesam Ahmed for the skeleton code
def give_rec(title, sig=sig):
 # Get the index corresponding to original_title
 idx = indices[title]
 
 # Get the pairwsie similarity scores
 sig_scores = list(enumerate(sig[idx]))
 
 # Sort the movies
 sig_scores = sorted(sig_scores, key=lambda x: x[1], reverse=True)
 
 # Scores of the 10 most similar movies
 sig_scores = sig_scores[1:11]
 
 # Movie indices
 movie_indices = [i[0] for i in sig_scores]
 
 # Top 10 most similar movies
 return movies_clean['original_title'].iloc[movie_indices]


现在我们就用经久不衰的最爱影片:《非常小特务》来测试一下已经构建的基于内容的过滤系统。

# Testing our content-based recommendation system with the seminal film Spy Kids
give_rec('Spy Kids')


以下是每个基于内容的过滤系统给出的推荐:


推荐系统给出了一些和《非常小特务》相关的影片,但也出现了一些偏差,如《无法自拔》和《毒枭帝国》。


局限性

基于上述结果,可以看到基于内容的过滤系统也有一些局限:


图片来源:unsplash.com/@bockman


1. 在用户搜索与《非常小特务》相似的电影时,此推荐系统可能会选出用户认为不相似的影片。为了改进此系统,可以考虑用单词计数替换TF-IDF算法,同时计算其他的相似分数。


2. 此系统只会分析每部电影的情节梗概。如果想像Ibtesam一样分析其他特征,如演员、导演、电影流派等,就需要在寻找相似影片方面做出改进。


3. 目前此系统只能基于影片特点的相关性给出推荐。因此会遗漏用户也许会感兴趣的其他流派的电影。我们需要使用协同过滤系统来解决这个问题,但现在的数据库并未包含用户信息。

留言 点赞 关注

我们一起分享AI学习与发展的干货

欢迎关注全平台AI垂类自媒体 “读芯术”

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码