本文概述
本周初, 我在会议上做了一个Facebook Live Code。在其中, 我们使用了一些基本的自然语言处理功能来绘制小说《白鲸》中最频繁出现的单词。这样一来, 我们还可以从以下数据科学流水线中看到思考的有效性, 并始终关注流程:
- 陈述你的问题;
- 获取你的数据;
- 整理数据以回答你的问题;
- 回答你的问题;
- 介绍你的解决方案, 以便其他人可以理解。
在本文中, 你将学习如何建立数据科学管道以绘制Moby Dick等许多小说中单词的频率分布。
提示:如果你想重新观看Facebook Live, 请观看以下视频;你可以跳到Hugo出现并开始会话的第12分钟。
我们不会为你提供小说:你将学习使用Python软件包请求从网站Gutenberg项目(基本上包含大量书籍)中抓取它们, 以及如何使用BeautifulSoup从此网络数据中提取小说。然后, 你将深入研究使用自然语言工具包(nltk)的小说。在此过程中, 你将学习自然语言处理(NLP)的重要方面, 例如标记化和停用词。
你将能够可视化在古腾堡计划中找到的任何小说的词频分布。但是, 你开发的NLP技能将适用于数据科学家遇到的许多数据, 因为世界数据的大部分是非结构化数据, 并且包含大量文本。
例如, 以下单词的频率分布将是什么?
该帖子来自Jupyter Notebook;你可以在此存储库中找到它。如果你有任何想法, 回应和/或反省, 请随时在Twitter上与我联系:@hugobowne。
预先步骤
按照README.md中的说明进行系统设置并准备就绪。
1.陈述你的问题
小说《白鲸记》中最常用的词是什么?它们出现的频率是多少?
2.获取你的数据
你的原始数据是梅尔维尔的小说《白鲸记》的文本。你将如何将这本约800本书的文本输入Python?
嗯, 有几种方法可以做到这一点, 但首先要意识到, 该文本可在Project Gutenberg在线免费获得。让我们去那里, 尝试找到Moby Dick, 然后将相关的URL存储在你的Python名称空间中:
# Store url
url = 'https://www.gutenberg.org/files/2701/2701-h/2701-h.htm'
现在你有了URL, 你需要获取网站的HTML。
请注意, HTML代表超文本标记语言, 并且是Web的标准标记语言。
你将使用请求来执行此操作, 这是那里最受欢迎的实用软件包之一。你可以在srcmini的Python导入数据(第2部分)课程中找到更多信息。
根据请求包的网站:
通过请求, 你可以发送有机的草稿HTTP / 1.1请求, 而无需进行人工操作。
并且以下组织声称在内部使用请求:
Ma下政府, 亚马逊, 谷歌, 特威里奥, NPR, 美国奥巴马, 推特, 索尼和美国联邦机构, 这些机构不愿透露姓名。
此外,
Requests是有史以来下载次数最多的Python软件包之一, 每个月的下载量超过13, 000, 000。所有时尚的年轻人都这样做!
你将从网站发出GET请求, 这意味着你正在从中获取数据。这是你使用浏览器访问网页时通过浏览器执行的操作。还有其他类型的请求, 例如POST请求, 但在这里我们不再关注它们。
请求通过其get函数使此操作变得容易。在此处提出请求, 并检查返回的对象类型。
# Import `requests`
import requests
# Make the request and check object type
r = requests.get(url)
type(r)
requests.models.Response
这是一个Response对象。你可以在请求启动指南中看到Response对象具有一个属性文本, 该属性文本使你可以从中获取HTML!让我们执行此操作并打印HTML以将其检出:
# Extract HTML from Response object and print
html = r.text
#print(html)
好!该HTML并不是你想要的。但是, 它确实包含你想要的内容:Moby Dick的文本。你现在需要做的是缠绕此HTML以提取小说。
3.整理数据以回答问题
第1部分:从HTML获取文本
在这里, 你将使用包BeautifulSoup。包裹网站说:
这看起来很有希望!
首先, 在包装名称上写一个字:Beautiful Soup?在Web开发中, 术语”标签汤”是指为网页编写的结构上或语法上不正确的HTML代码。 Beautiful Soup最能做的是使标签汤再次变得美丽, 并轻松地从中提取信息!实际上, 使用此程序包时创建并查询的主要对象称为BeautifulSoup。创建汤后, 我们可以使用其.get_text()方法提取文本。
# Import BeautifulSoup from bs4
from bs4 import BeautifulSoup
# Create a BeautifulSoup object from the HTML
soup = BeautifulSoup(html, "html5lib")
type(soup)
bs4.BeautifulSoup
从这些汤对象中, 你可以提取有关正在抓取的网站的所有类型的有趣信息, 例如标题:
# Get soup title
soup.title
<title>
Moby Dick; Or the Whale, by Herman Melville
</title>
或标题作为字符串:
# Get soup title as string
soup.title.string
'\n Moby Dick; Or the Whale, by Herman Melville\n '
或在页面的<a>标记(超链接)中找到的所有URL:
# Get hyperlinks from soup and check out first several
soup.findAll('a')[:8]
[<a href="#link2H_4_0002"> ETYMOLOGY. </a>, <a href="#link2H_4_0003"> EXTRACTS (Supplied by a Sub-Sub-Librarian).
</a>, <a href="#link2HCH0001"> CHAPTER 1. Loomings. </a>, <a href="#link2HCH0002"> CHAPTER 2. The Carpet-Bag. </a>, <a href="#link2HCH0003"> CHAPTER 3. The Spouter-Inn. </a>, <a href="#link2HCH0004"> CHAPTER 4. The Counterpane. </a>, <a href="#link2HCH0005"> CHAPTER 5. Breakfast. </a>, <a href="#link2HCH0006"> CHAPTER 6. The Street. </a>]
你要做的是从汤中提取文本, 并且为此提供了一个非常有用的.get_text()方法。
得到文本, 打印出来看看。是你想要的吗?
# Get the text out of the soup and print it
text = soup.get_text()
#print(text)
请注意, 这几乎是你想要的。
这是小说的文本, 开头有一些不需要的东西, 结尾有一些不需要的东西。如果需要, 可以将其删除。但是, 此内容的数量要比Moby Dick的文本小得多, 以至于初步近似, 可以忽略不计, 这就是这里的方法。为了获得可靠的结果, 建议删除它。
现在你已经有了感兴趣的文本, 是时候该计算每个单词出现的次数并绘制所需的频率直方图了:自然语言处理助你一臂之力!
第2部分:使用NLP从文本中提取单词
现在, 你将使用自然语言工具包nltk来
- 对文本进行标记(用于分割成标记(例如单词)的花哨术语);
- 删除停用词(在几乎所有英语文本中都经常出现的停用词(例如” a”和” the”)。
步骤1:标记化
你要标记文本, 即将其拆分为单词列表。本质上, 你希望将由空格分隔的文本分开。
为此, 你将使用称为正则表达式的强大工具。正则表达式或简称regex是定义搜索模式的一系列字符。众所周知, 它们令人困惑, 最好以身作则。
- 你有字符串” peter piper采摘了一批腌制的胡椒”, 并且想要从列表中以” p”开头的所有单词中提取。
与所有以’p’开头的单词匹配的正则表达式为’p \ w +’。让我们解压缩:
- 正则表达式开头的’p’意味着你将只匹配以’p’开头的字符序列;
- ‘\ w’是一个特殊字符, 它将与任何字母数字A-z, a-z, 0-9以及下划线匹配;
- ” +”告诉你正则表达式中的前一个字符可以在想要匹配的字符串中显示任意多次。这意味着” \ w +”将匹配字母数字字符和下划线的任意序列。
将所有内容放在一起, 正则表达式’p \ w +’将匹配所有以’p’开头, 后跟字母数字字符和下划线的子字符串。在大多数有意义的英语文本中, 这将对应于以” p”开头的单词。
现在, 你将使用内置的Python包re从句子” peter piper picked a picked Peppered Peppers”中提取所有以” p”开头的单词作为热身。
# Import regex package
import re
# Define sentence
sentence = 'peter piper pick a peck of pickled peppers'
# Define regex
ps = 'p\w+'
# Find all words in sentence that match the regex and print them
re.findall(ps, sentence)
['peter', 'piper', 'pick', 'peck', 'pickled', 'peppers']
看起来不错。现在, 如果’p \ w +’是匹配以’p’开头的单词的正则表达式, 那么匹配所有单词的正则表达式是什么?
现在, 你要为上面的玩具彼得·派珀(Peter Piper)一句话执行此操作。
# Find all words and print them
re.findall('\w+', sentence)
['peter', 'piper', 'pick', 'a', 'peck', 'of', 'pickled', 'peppers']
现在, 你可以对包含Moby Dick的字符串的文本执行相同的操作:
# Find all words in Moby Dick and print several
tokens = re.findall('\w+', text)
tokens[:8]
['Moby', 'Dick', 'Or', 'the', 'Whale', 'by', 'Herman', 'Melville']
请注意, 还可以使用自然语言工具包nltk来执行此操作:
# Import RegexpTokenizer from nltk.tokenize
from nltk.tokenize import RegexpTokenizer
# Create tokenizer
tokenizer = RegexpTokenizer('\w+')
# Create tokens
tokens = tokenizer.tokenize(text)
tokens[:8]
['Moby', 'Dick', 'Or', 'the', 'Whale', 'by', 'Herman', 'Melville']
好!你快到了。但是请注意, 在上面, “或”的大写字母为” O”, 而在其他地方, 可能不是, 但”或”和”或”都希望算作同一个词。因此, 你将需要在Moby Dick中构建所有单词的列表, 其中所有大写字母都被设置为小写。你会发现方便的字符串方法.lower():
# Initialize new list
words = []
# Loop through list tokens and make lower case
for word in tokens:
words.append(word.lower())
# Print several items from list as sanity check
words[:8]
['moby', 'dick', 'or', 'the', 'whale', 'by', 'herman', 'melville']
步骤2:移除停用词
通常的做法是删除英文中出现的很多单词, 例如” the”, ” of”和” a”(称为停用词), 因为它们不太有趣。有关所有这些技术的更多信息, 请查看我们的Python自然语言处理基础知识课程。
nltk软件包中有一个英文停用词列表, 你现在将它们存储为sw, 并打印其中的前几个元素。
如果你在此处遇到错误, 请运行命令nltk.download(‘stopwords’)在系统上安装停用词。
# Import nltk
import nltk
# Get English stopwords and print some of them
sw = nltk.corpus.stopwords.words('english')
sw[:5]
['i', 'me', 'my', 'myself', 'we']
你想要不在sw中的所有单词的列表。获取此列表的一种方法是遍历单词的所有元素, 如果没有在sw中, 则将它们添加到新列表中:
# Initialize new list
words_ns = []
# Add to words_ns all words that are in words but not in sw
for word in words:
if word not in sw:
words_ns.append(word)
# Print several list items as sanity check
words_ns[:5]
['moby', 'dick', 'whale', 'herman', 'melville']
4.回答你的问题
我们的问题是”小说《白鲸记》中最常用的词是什么?它们出现的频率是多少?”
现在, 你可以使用nltk在两行代码中绘制Moby Dick中单词的频率直方图。去做这个,
- 使用函数nltk.FreqDist();创建一个频率分布对象。
- 你使用结果对象的plot()方法。
#Import datavis libraries
import matplotlib.pyplot as plt
import seaborn as sns
# Figures inline and set visualization style
%matplotlib inline
sns.set()
# Create freq dist and plot
freqdist1 = nltk.FreqDist(words_ns)
freqdist1.plot(25)
5.介绍你的解决方案
很酷的事情是, 在使用nltk回答我们的问题时, 我们实际上已经以一种可以传达给其他人的方式展示了我们的解决方案:频率分布图!你可以阅读最常见的单词及其频率。例如, “鲸鱼”是小说中最常见的单词(去形像), 除了停用词外, 它的出现次数高达1200次!
奖励材料
如你所见, 古腾堡计划(Project Gutenberg)上有很多小说, 我们可以制作这些词频的直方图, 编写自己的函数来完成所有这些工作是很有意义的:
def plot_word_freq(url):
"""Takes a url (from Project Gutenberg) and plots a word frequency
distribution"""
# Make the request and check object type
r = requests.get(url)
# Extract HTML from Response object and print
html = r.text
# Create a BeautifulSoup object from the HTML
soup = BeautifulSoup(html, "html5lib")
# Get the text out of the soup and print it
text = soup.get_text()
# Create tokenizer
tokenizer = RegexpTokenizer('\w+')
# Create tokens
tokens = tokenizer.tokenize(text)
# Initialize new list
words = []
# Loop through list tokens and make lower case
for word in tokens:
words.append(word.lower())
# Get English stopwords and print some of them
sw = nltk.corpus.stopwords.words('english')
# Initialize new list
words_ns = []
# Add to words_ns all words that are in words but not in sw
for word in words:
if word not in sw:
words_ns.append(word)
# Create freq dist and plot
freqdist1 = nltk.FreqDist(words_ns)
freqdist1.plot(25)
现在使用该功能绘制古腾堡计划中其他文本的词频分布:
- 傲慢与偏见:
plot_word_freq('https://www.gutenberg.org/files/42671/42671-h/42671-h.htm')
- 鲁滨逊克鲁索
plot_word_freq('https://www.gutenberg.org/files/521/521-h/521-h.htm')
- 国王詹姆斯圣经
plot_word_freq('https://www.gutenberg.org/files/10/10-h/10-h.htm')
总结
在本文中, 你学习了如何建立数据科学管道以绘制Moby Dick等许多小说中单词的频率分布。你学习了使用Python软件包请求从网站Gutenberg项目(大型书籍)中抓取它们的方法, 以及如何使用BeautifulSoup从此网络数据中提取小说。然后, 你使用自然语言工具包(nltk)来分析小说。在此过程中, 你了解了自然语言处理(NLP)的重要方面, 例如标记化和停用词。现在, 你可以可视化在古腾堡计划中找到的任何小说的词频分布。你开发的NLP技能也适用于数据科学家遇到的许多数据, 因为世界数据的绝大部分都是非结构化数据, 并且包含大量文本。
该帖子来自Jupyter Notebook;你可以在此存储库中找到它。如果你有任何想法, 回应和/或反省, 请随时通过twitter @ hugobowne与我联系。让我知道你构建了哪些很棒的项目。
评论前必须登录!
注册