在这篇文章中,将使用基于热门电视剧《生活大爆炸》的数据集,进行基础的数据探索性分析(EDA),并构建一个推荐系统。这篇文章是基于项目的,可以通过下载数据集来跟随步骤。数据集可以在priyankad0993/big-band-theory-information | Workspace | data.world上免费获取,并且文件是.xlsx格式的,可以通过保存为.csv格式来转换它。
很少会遇到可以直接使用的原始数据集,通常需要进行一些转换。首先,导入所需的库并上传数据集。可以开始一个新的Jupyter笔记本或者使用Google Colab笔记本来完成这个任务。
# 安装并导入Pandas和Numpy库
!pip install pandas — upgrade — quiet
!pip install numpy — upgrade — quiet
# 导入Pandas和Numpy
import pandas as pd
import numpy as np
导入Pandas作为pd和Numpy作为np是一个好的实践,因为这样使用起来更方便。现在使用保存的csv文件名来读取数据集。需要先将数据集文件上传到Jupyter笔记本或Google Colab的文件部分。
# 读取数据集
df = pd.read_csv('BigBangTheoryIMDB.csv')
将文件命名为df,因为Pandas将文件存储为DataFrame,这是一种数据类型,就像字符串、整数等。现在使用head()查看数据的前几行。
df.head()
现在使用shape()查看数据集中有多少行和列。
df.shape()
现在查看数据的基本信息,比如每列的类型等。
df.info()
如果在想是否需要记住所有这些函数,如head、shape等,答案是不需要,将通过实践知道何时使用它们。目前,只需在互联网上搜索想要实现的数据操作,肯定能找到答案。
在清洗数据时,通常需要检查空值并用适当的值替换它们,以及查找重复值并消除它们。
df.duplicated().sum()
df.isna().sum()
可能已经看到,数据集中季和集数只是单独的数字,将在季和集数编号中添加“S”和“E”,只是为了让它们看起来更美观一些。
df['Season'] = 'S' + df['Season'].astype(str)
df['Episode Number'] = 'E' + df['Episode Number'].astype(str)
让看看它看起来如何。
df.head()
完美!数据集看起来相当干净,让做一些EDA。
还将生成一些图表和图形,因此让导入matplotlib和seaborn库。
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
sns.set_style('darkgrid')
matplotlib.rcParams['font.size'] = 14
matplotlib.rcParams['figure.figsize'] = (9, 5)
matplotlib.rcParams['figure.facecolor'] = '#00000000'
不用担心上述代码的每一行,它只是设置了一些基本的东西,比如图表大小、字体大小等。只需要使用代码的前三行来导入库。
让看看每个季节有多少集,将使用value_counts()。它返回根据指定列(本例中为Season)的总值。排序设置为false,因为想要按季节的结果,而不是默认的降序。
episode_per_season = df.Season.value_counts(sort=False)
episode_per_season
现在使用seaborn为此创建一个条形图。
sns.barplot(x=episode_per_season.index, y=episode_per_season);
再次,可以简单地在互联网上搜索它的语法,直到熟悉它。让看看根据评分排名前10和后10的剧集名称。
top_10_rated_episodes = df.sort_values('Rating', ascending=False).head(10)
top_10_rated_episodes.Title
来做一件事,将季数、集数和标题合并到一个列中,这样在观看时更容易导航。
df['SE_Title'] = df['Season'] + " " + df['Episode Number'] + " " + df['Title']
df['SE_Title']
现在看起来好多了。让看看每个季节的平均评分。
Rating_by_season = df.groupby('Season', as_index=False, sort=False).agg({'Rating': ['mean']})
由于这是计算的结果,这个DataFrame没有列名。但可以使用以下方式给列命名。
Rating_by_season.columns = ['season', 'Rating']
Rating_by_season
并在折线图中绘制它。
sns.lineplot(x='Season', y='Rating', data=Rating_by_season);
整个节目的评分
Averge_rating_of_the_show = df.agg({'Rating': ['mean']})
Averge_rating_of_the_show
推荐系统有两种类型:基于内容的和基于协同的,可以在这里了解更多。但在本模型中,将使用基于内容的,这意味着如果观看了电影“A”,并且根据情节电影“B”与“A”相似,那么“B”将被推荐给观看。
在数据集中,给出了每一集的情节,所以将使用它来检查剧集之间的相似性。
将为此导入所需的scikit库。
from sklearn.feature_extraction.text import CountVectorizer
# stop_words属性将跳过所有在英语中出现的辅助词,例如:in, the, they等。
cv_fvector = CountVectorizer(stop_words='english')
vector = cv_fvector.fit_transform(df['Plot']).toarray()
在这里导入了计数向量化器。由于机器不能像一样理解文本,这个库将文本转换为数值数据(在本例中是向量)。它通过计算每个句子中每个独特单词的频率来实现这一点。例如:
Sample = ["This is cat", "This is dog"]
然后使用fit_transform来自动缩放数据。
from sklearn.metrics.pairwise import cosine_similarity
similarity_array = cosine_similarity(vector)
similarity_array
它将给一个数组,计算每个向量与其他向量的余弦距离。让测试模型。
episode = 'S12 E5 The Planetarium Collision'
# 这给出了数据集中剧集的索引号
eps_index = df[df['SE_Title'] == episode].index[0]
现在将找到与剧集相似度最高的前五集的索引和相似度。
similar_eps = sorted(list(enumerate(similarity[eps_index])), reverse=True, key=lambda x: x[1])
similar_eps[0:6]
最后,使用一个非常简单的for循环来获取结果的名称。
for i in similar_eps[1:6]:
print(df.iloc[i[0]].SE_Title)