使用MongoDB、Seaborn和Matplotlib分析API数据
介绍
软件开发职位通常要求的技能是使用NoSQL数据库(包括MongoDB)的经验。本教程将探索如何使用API收集数据,将数据存储在MongoDB数据库中,并对数据进行一些分析。
但是,在进入代码之前,让我们花点时间来复习一下MongoDB和API,以确保我们能理解我们是如何处理收集的数据的。
MongoDB和NoSQL
MongoDB是一种NoSQL数据库,支持以非关系形式存储数据。通过将NoSQL数据库与其前身/竞争对手—SQL数据库进行比较,我们就可以更好地理解NoSQL数据库。
SQL代表结构化查询语言,它是一种关系型数据库管理工具。关系型数据库是将数据存储为一系列键和值的数据库,数据表中的每一行都有自己惟一的键。可以通过查找相应的键来检索数据库中的值。这就是SQL数据库存储数据的方式,但是,NoSQL数据库可以以非关联的方式存储数据。
NoSQL代表“不仅仅是SQL”,它指的是这样一个事实:尽管SQL类型的查询可以使用NoSQL系统完成,但它们也可以完成SQL数据库难以完成的事情。NoSQL数据库为其处理的数据提供了更广泛的存储选项,而且由于数据的相关性较低,因此,数据可以以更多地方式进行检索,从而加快了一些操作的速度。与SQL数据库相比,NoSQL数据库可以使节点或字段的添加更简单。
有很多流行的NoSQL框架,包括MongoDB、OrientDB、InfinityDB、Aerospike和CosmosDB。MongoDB是一个特定的NoSQL框架,它以文档的形式存储数据,充当面向文档的数据库。
MongoDB之所以流行,是因为它的通用性和简单的云集成,并且能够用于各种各样的任务。MongoDB使用JSON格式存储数据。MongoDB数据库的查询也是以JSON格式进行,因为存储和检索命令都是基于JSON格式的,所以,MongoDB的命令很容易记住和编写。
API是什么?
API是应用程序编程接口,其功能是简化客户机和服务器之间的通信。创建API通常是为了方便那些对应用程序开发人员所使用的语言缺乏经验的人来收集信息。
API也可以是控制来自服务器的信息流的有用方法,鼓励那些对访问服务器信息感兴趣的人使用官方渠道来访问,而不是构建一个网络爬虫。网站中最常见的API是REST(表征状态转移)API,它利用标准的HTTP请求和响应来发送、接收、删除和修改数据。在本教程中,我们将访问REST API并以HTTP格式发送请求。
我们将使用什么API ?
我们将使用的API是GameSpot的API。GameSpot是网络上最大的视频游戏评论网站之一,您可以在这里访问它的API。(地址:https://www.gamespot.com/api/ )
进行设置
在开始之前,您应该确保自己获得了GameSpot的API密钥。您还应该确保已经安装了MongoDB及其Python库。Mongo的安装说明可以在这里找到。
安装PyMongo库只需运行以下命令:
您可能还希望安装MongoDB Compass程序,该程序允许您使用GUI轻松地可视化和编辑MongoDB数据库的各个方面。
创建MongoDB数据库
现在,我们可以通过创建MongoDB数据库来开始我们的项目。首先,我们将处理我们的导入项。我们将从PyMongo导入MongoClient,以及requests 和pandas:
当使用MongoDB创建了一个数据库之后,我们首先需要连接到客户端,然后使用客户端创建我们想要的数据库:
MongoDB可以在一个数据库中存储多个数据集合,所以我们还需要定义我们想要使用的集合的名称:
就是这样。我们的数据库和集合已经创建好了,可以开始向其中插入数据了。这很简单,不是吗?
使用该API
现在,我们已经准备好使用GameSpot API来收集数据。通过查看这里(地址:https://www.gamespot.com/api/documentation )的API文档,我们可以确定我们的请求所需的格式。
我们需要将请求发送到包含我们API密钥的基本URL。GameSpot的API有多个资源,我们可以从这些资源中获取数据。例如,他们有一个列出了游戏的发布日期和运行平台等数据的资源。
然而,我们对他们的游戏评论资源比较感兴趣,我们将从该API资源中获取一些特定的字段。此外,GameSpot要求您在发出请求时要指定一个唯一的用户代理标识符,我们将通过创建一个header来实现,我们将把此header传入requests函数:
我们将需要以下数据字段:id, title, score, deck, body, good, bad:
GameSpot一次只允许返回100个结果。出于这个原因,为了获得足够数量的评论进行分析,我们需要创建一个数字范围并循环遍历它们,一次检索100个结果。
您可以选择任何您想要的数字。我选择获取他们所有的评论,最高可达14900条:
我们将创建一个函数来连接基地址、要返回的字段列表、排序方案(升序或降序)和查询的偏移量。
我们将获得我们想要循环的页面数量,然后对每100个条目,我们将创建一个新的URL并请求数据:
回想一下,MongoDB将数据存储为JSON。因此,我们需要使用json()方法将我们的响应数据转换成JSON格式。
将数据转换为JSON后,我们将从响应中获得“results”属性,因为这部分实际上包含了我们感兴趣的数据。然后,我们将遍历100个不同的结果,并使用来自PyMongo的insert_one()命令将每个结果插入到我们的集合中。当然,您也可以使用insert_many()将它们全部放到一个列表中。
现在让我们调用该函数并让它收集数据:
为什么我们不检查一下,看看我们的数据是否已经像我们预期的那样插入到了我们的数据库?我们可以使用Compass程序直接查看数据库及其内容:
我们可以看到数据已经正确地插入了。
我们还可以进行一些数据库检索并打印它们。为此,我们将创建一个空列表来存储条目,并在“reviews”集合上使用.find()命令。
当使用PyMongo中的find函数时,检索也需要格式化为JSON。传入find函数的参数将有一个字段和值。
默认情况下,MongoDB总是返回_id字段(它自己唯一的ID字段,而不是我们从GameSpot中获取的ID),但是我们可以通过指定一个0值来告诉它禁止这种情况。我们想要返回的字段,比如本例中的score字段,应该被赋予一个1值:
以下是成功获取并打印的内容:
我们还可以通过使用Pandas轻松地将查询结果转换为数据帧:
以下是返回的结果:
在开始分析一些数据之前,让我们先花点时间看看如何将两个集合连接在一起。如前所述,GameSpot有多个资源来获取数据,我们可能希望从第二个数据库(如Games数据库)获取值。
MongoDB是一个NoSQL数据库,因此与SQL不同,它不打算处理数据库之间的关系和将数据字段连接在一起。但是,有一个函数可以近似于数据库连接,即lookup()函数。
lookup()函数作用类似于数据库连接,我们可以通过指定一个管道来完成此操作,该管道包含您想要从其中获取连接元素的数据库,以及您想要从输入文档(localField)和“from”文档(foreignField)中获得的字段。
最后,您选择一个名称来将外部文档转换为它,它们将显示在我们的查询响应表中的这个新名称下面。如果您有第二个名为games的数据库,并想要在一个查询中将它们连接在一起,您可以这样做:
分析数据
现在,我们可以开始分析和可视化在我们新创建的数据库中发现的一些数据。让我们确保我们有了分析所需的所有函数。
假设我们想对GameSpot的游戏评论中发现的单词进行一些分析。我们的数据库中有这些信息,我们只需要得到它。
我们可以像之前一样使用find()函数从我们的数据库中收集排名前40的评论(或者您想要的任何数字),但这次我们将指定我们希望根据score变量进行排序,并按降序排序:
我们将该响应变换为一个Pandas数据帧并将其转换进一个字符串。然后我们将提取<p> HTML标签中包含评论文本的所有值,我们将使用BeautifulSoup来完成:
查看print语句,我们可以看到评论文本已经被收集了:
现在我们已经得到了评论文本数据,我们想用几种不同的方法来分析它。让我们试着对排名前40位的评论中常用的单词进行一些直觉判断。我们有几种不同的方法:
- 我们可以创建一个词云
- 我们可以计数所有的单词并按它们的出现次数进行排序
- 我们可以进行命名实体识别
在我们对数据进行分析之前,我们必须对它进行预处理。
为了预处理数据,我们需要创建一个函数来过滤条目。此文本数据仍然充满了各种标记和非标准字符,我们希望通过获取评论的原始文本来删除这些标记和非标准字符。我们将使用正则表达式来将非标准字符替换为空格。
我们也会使用一些来自NTLK的停止词(不会对我们的文本添加意思的高度常用单词)并且通过创建一个列表来保存所有的单词,从而将它们从我们的文本中删除,然后只有在单词不在我们的停止词列表中时才将它们加入到其中。
词云
让我们获取评论单词的一个子集,将其可视化为一个语料库。如果它在生成时太大的话,可能会导致词云出现一些问题。
例如,我过滤出了前5000个单词:
现在,我们可以通过使用这里提供的预先创建好的WordCloud库来轻松地创建一个词云。
这个词云确实给我们提供了一些信息,关于什么类型的词在排名靠前的评论中经常使用:
不幸的是,它仍然充满了常见的单词,这就是为什么使用tf-idf过滤方案对评论单词进行过滤是一个好主意,但是对于这个简单的演示来说,这已经足够好了。
事实上,我们确实拥有一些关于游戏评论中所谈论的概念类型的信息:游戏玩法,故事,角色,射击,动作,地点等。
我们可以通过查看我们选择的前40名评论之一来确认这些词经常出现在游戏评论中:Mike Mahardy对《神秘海域4》的评论:
果然,这篇评论讨论了动作、游戏玩法、角色和故事。
单词的大小给了我们关于单词在这些评论中出现的频率的直观感觉,但是我们也可以计算某些单词出现的频率。
计数器
我们可以通过将单词分割开并将它们与其数目一起添加到一个单词字典中,从而获得一个最常见单词的列表,每次看到相同的单词时,这些单词计数就会增加。
然后我们只需要使用Counter和most_common()函数:
以下是一些最常见的单词的数目:
命名实体识别
我们还可以使用en_core_web_sm进行命名实体识别,这是spaCy中包含的一个语言模型。这里列出了可以检测到的各种概念和语言特征。
我们需要从文档(单词列表)中抓取检测到的命名实体和概念列表:
我们可以打印出找到的实体及其数目。
以下是打印的内容:
假设我们想要为不同的类别绘制最常见的识别词语,比如人员和组织。我们只需要创建一个函数来获得不同类别实体的计数,然后使用它来获得我们想要的实体。
我们将得到一个命名实体/人员、组织和GPEs(位置)的列表:
现在我们要做的就是用一个函数来对命名实体数目绘制图表:
我们来看看生成的图表。
正如命名实体所期望的那样,返回的大多数结果是视频游戏角色的名称。这并不是完美的,因为它将“Xbox”等词语错误地归类为一个命名实体,而不是一个组织,但这仍然让我们了解到排名靠前的评论中讨论了哪些角色。
该组织图为我们展示了一些正确的游戏开发者和发行商,如Playstation和Nintendo,但它也将“480p”这样的东西标记为一个组织。
以上是对GPEs(或地理位置)绘制的图。看起来“Hollywood”和“Miami”经常出现在游戏评论中。(是游戏设置吗?或者评论者可能是将游戏中的某些东西描述为Hollywood风格的?)
正如您所看到的,进行命名实体识别和概念识别并不完美,但它可以让您对正文中讨论的主题有一些直觉。
对数值绘制图表
最后,我们可以尝试从数据库绘制数值。让我们从评论集合中获取评分值,将它们加起来,然后对它们绘制图表:
上图是给出的评分的总数的分布图,从0到9.9。看起来最常给出的分数是7分和8分,这在直觉上是有道理的。7分通常被认为是10分评价量表的平均值。
结论
收集、存储、检索和分析数据是当今世界非常需要的技能,MongoDB是最常用的NoSQL数据库平台之一。
知道如何使用NoSQL数据库以及如何解释其中的数据将使您能够执行许多常见的数据分析任务。
英文原文:https://stackabuse.com/analyzing-api-data-with-mongodb-seaborn-and-matplotlib/
译者:浣熊君( ・᷄৺・᷅ )