Python NLTK 自然语言处理入门与例程

  • 在这篇文章中,我们将基于 Python 讨论自然语言处理(NLP)。本教程将会使用 Python NLTK 库。NLTK 是一个当下流行的,用于自然语言处理的 Python 库。

那么 NLP 到底是什么?学习 NLP 能带来什么好处?

简单的说,自然语言处理( NLP )就是开发能够理解人类语言的应用程序和服务。

我们生活中经常会接触的自然语言处理的应用,包括语音识别,语音翻译,理解句意,理解特定词语的同义词,以及写出语法正确,句意通畅的句子和段落。

NLP的作用

正如大家所知,每天博客,社交网站和网页会产生数亿字节的海量数据。

有很多公司热衷收集所有这些数据,以便更好地了解他们的用户和用户对产品的热情,并对他们的产品或者服务进行合适的调整。

这些海量数据可以揭示很多现象,打个比方说,巴西人对产品 A 感到满意,而美国人却对产品 B 更感兴趣。通过NLP,这类的信息可以即时获得(即实时结果)。例如,搜索引擎正是一种 NLP,可以在正确的时间给合适的人提供适当的结果。

但是搜索引擎并不是自然语言处理(NLP)的唯一应用。还有更好更加精彩的应用。

NLP的应用

以下都是自然语言处理(NLP)的一些成功应用:

  • 搜索引擎,比如谷歌,雅虎等等。谷歌等搜索引擎会通过NLP了解到你是一个科技发烧友,所以它会返回科技相关的结果。
  • 社交网站信息流,比如 Facebook 的信息流。新闻馈送算法通过自然语言处理了解到你的兴趣,并向你展示相关的广告以及消息,而不是一些无关的信息。
  • 语音助手,诸如苹果 Siri。
  • 垃圾邮件程序,比如 Google 的垃圾邮件过滤程序 ,这不仅仅是通常会用到的普通的垃圾邮件过滤,现在,垃圾邮件过滤器会对电子邮件的内容进行分析,看看该邮件是否是垃圾邮件。

NLP库

现在有许多开源的自然语言处理(NLP)库。比如:

  • Natural language toolkit (NLTK)
  • Apache OpenNLP
  • Stanford NLP suite
  • Gate NLP library

自然语言工具包(NLTK)是最受欢迎的自然语言处理(NLP)库。它是用 Python 语言编写的,背后有强大的社区支持。

NLTK 也很容易入门,实际上,它将是你用到的最简单的自然语言处理(NLP)库。

在这个 NLP 教程中,我们将使用 Python NLTK 库。在开始安装 NLTK 之前,我假设你知道一些 Python入门知识。

安装 NLTK

如果你使用的是 Windows , Linux 或 Mac,你可以 使用PIP 安装NLTK: # pip install nltk。

在本文撰写之时,你可以在 Python 2.7 , 3.4 和 3.5 上都可以使用NLTK。或者可以通过获取tar 进行源码安装。

要检查 NLTK 是否正确地安装完成,可以打开你的Python终端并输入以下内容:Import nltk。如果一切顺利,这意味着你已经成功安装了 NLTK 库。

一旦你安装了 NLTK,你可以运行下面的代码来安装 NLTK 包:

import nltk
nltk.download()

这将打开 NLTK 下载器来选择需要安装的软件包。

你可以选择安装所有的软件包,因为它们的容量不大,所以没有什么问题。现在,我们开始学习吧!

使用原生 Python 来对文本进行分词

首先,我们将抓取一些网页内容。然后来分析网页文本,看看爬下来的网页的主题是关于什么。我们将使用 urllib模块来抓取网页:

import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
print (html)

从打印输出中可以看到,结果中包含许多需要清理的HTML标记。我们可以用这个 BeautifulSoup 库来对抓取的文本进行处理:

from bs4 import BeautifulSoup
import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
print (text)

现在,我们能将抓取的网页转换为干净的文本。这很棒,不是么?

最后,让我们通过以下方法将文本分词:

from bs4 import BeautifulSoup
import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
print (tokens)

词频统计

现在的文本相比之前的 html 文本好多了。我们再使用 Python NLTK 来计算每个词的出现频率。NLTK 中的FreqDist( ) 函数可以实现词频统计的功能 :

from bs4 import BeautifulSoup
import urllib.request
import nltk
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
freq = nltk.FreqDist(tokens)
for key,val in freq.items(): print (str(key) + ':' + str(val))

如果你查看输出结果,会发现最常用的词语是PHP。

你可以用绘图函数为这些词频绘制一个图形: freq.plot(20, cumulative=False)。

从图中,你可以肯定这篇文章正在谈论 PHP。这很棒!有一些词,如"the," "of," "a," "an," 等等。这些词是停止词。一般来说,停止词语应该被删除,以防止它们影响我们的结果。

使用 NLTK 删除停止词

NLTK 具有大多数语言的停止词表。要获得英文停止词,你可以使用以下代码:

from nltk.corpus import stopwords
stopwords.words('english')

现在,让我们修改我们的代码,并在绘制图形之前清理标记。首先,我们复制一个列表。然后,我们通过对列表中的标记进行遍历并删除其中的停止词:

clean_tokens = tokens[:]
sr = stopwords.words('english')
for token in tokens:if token in stopwords.words('english'):clean_tokens.remove(token)

你可以在这里查看Python List 函数, 了解如何处理列表。

最终的代码应该是这样的:

from bs4 import BeautifulSoup
import urllib.request
import nltk
from nltk.corpus import stopwords
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
clean_tokens = tokens[:]
sr = stopwords.words('english')
for token in tokens: if token in stopwords.words('english'): clean_tokens.remove(token)
freq = nltk.FreqDist(clean_tokens)
for key,val in freq.items(): print (str(key) + ':' + str(val))

如果你现在检查图表,会感觉比之前那张图标更加清晰,因为没有了停止词的干扰。

freq.plot(20,cumulative=False)

使用 NLTK 对文本分词

我们刚刚了解了如何使用 split( ) 函数将文本分割为标记 。现在,我们将看到如何使用 NLTK 对文本进行标记化。对文本进行标记化是很重要的,因为文本无法在没有进行标记化的情况下被处理。标记化意味着将较大的部分分隔成更小的单元。

你可以将段落分割为句子,并根据你的需要将句子分割为单词。NLTK 具有内置的句子标记器和词语标记器。

假设我们有如下的示例文本:

Hello Adam, how are you? I hope everything is going well.  Today is a good day, see you dude.

为了将这个文本标记化为句子,我们可以使用句子标记器:

from nltk.tokenize import sent_tokenize
mytext = "Hello Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(sent_tokenize(mytext))

输出如下:

['Hello Adam, how are you?', 'I hope everything is going well.', 'Today is a good day, see you dude.']

你可能会说,这是一件容易的事情。我不需要使用 NLTK 标记器,并且我可以使用正则表达式来分割句子,因为每个句子前后都有标点符号或者空格。

那么,看看下面的文字:

Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude.

呃!Mr. 是一个词,虽然带有一个符号。让我们来试试使用 NLTK 进行分词:

from nltk.tokenize import sent_tokenize
mytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(sent_tokenize(mytext))

输出如下所示:

['Hello Mr. Adam, how are you?', 'I hope everything is going well.', 'Today is a good day, see you dude.']

Great!结果棒极了。然后我们尝试使用词语标记器来看看它是如何工作的:

from nltk.tokenize import word_tokenize
mytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(word_tokenize(mytext))

输出如下:

['Hello', 'Mr.', 'Adam', ',', 'how', 'are', 'you', '?', 'I', 'hope', 'everything', 'is', 'going', 'well', '.', 'Today', 'is', 'a', 'good', 'day', ',', 'see', 'you', 'dude', '.']

正如所料,Mr. 是一个词,也确实被 NLTK 当做一个词。NLTK使用 nltk.tokenize.punkt module 中的 PunktSentenceTokenizer 进行文本分词。这个标记器经过了良好的训练,可以对多种语言进行分词 。

标记非英语语言文本

为了标记其他语言,可以像这样指定语言:

from nltk.tokenize import sent_tokenize
mytext = "Bonjour M. Adam, comment allez-vous? J'espère que tout va bien. Aujourd'hui est un bon jour."
print(sent_tokenize(mytext,"french"))

结果将是这样的:

['Bonjour M. Adam, comment allez-vous?', "J'espère que tout va bien.", "Aujourd'hui est un bon jour."]

NLTk 对其他非英语语言的支持也非常好!

从 WordNet 获取同义词

如果你还记得我们使用 nltk.download( ) 安装 NLTK 的扩展包时。其中一个扩展包名为 WordNet。WordNet 是为自然语言处理构建的数据库。它包括部分词语的一个同义词组和一个简短的定义。

通过 NLTK 你可以得到给定词的定义和例句:

from nltk.corpus import wordnet
syn = wordnet.synsets("pain")
print(syn[0].definition())
print(syn[0].examples())

结果是:

a symptom of some physical hurt or disorder
['the patient developed severe pain and distension']

WordNet 包含了很多词的定义:

from nltk.corpus import wordnet
syn = wordnet.synsets("NLP")
print(syn[0].definition())
syn = wordnet.synsets("Python")
print(syn[0].definition())

结果是:

the branch of information science that deals with natural language information
large Old World boas

您可以使用 WordNet 来获得同义词:

from nltk.corpus import wordnet
synonyms = []
for syn in wordnet.synsets('Computer'):for lemma in syn.lemmas():synonyms.append(lemma.name())
print(synonyms)

输出是:

['computer', 'computing_machine', 'computing_device', 'data_processor', 'electronic_computer', 'information_processing_system', 'calculator', 'reckoner', 'figurer', 'estimator', 'computer']

Cool!

从 WordNet 获取反义词

你可以用同样的方法得到单词的反义词。你唯一要做的是在将 lemmas 的结果加入数组之前,检查结果是否确实是一个正确的反义词。

from nltk.corpus import wordnet
antonyms = []
for syn in wordnet.synsets("small"):for l in syn.lemmas():if l.antonyms():antonyms.append(l.antonyms()[0].name())
print(antonyms)

输出是:

['large', 'big', 'big']

这就是 NLTK 在自然语言处理中的力量。

NLTK词干提取

单词词干提取就是从单词中去除词缀并返回词根。(比方说 working 的词干是 work。)搜索引擎在索引页面的时候使用这种技术,所以很多人通过同一个单词的不同形式进行搜索,返回的都是相同的,有关这个词干的页面。

词干提取的算法有很多,但最常用的算法是 Porter 提取算法。NLTK 有一个 PorterStemmer 类,使用的就是 Porter 提取算法。

from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem('working'))

结果是: work

结果很清楚。

还有其他一些提取算法,如 Lancaster 提取算法。这个算法的输出同 Porter 算法的结果在几个单词上不同。你可以尝试他们两个算法来查看有哪些不同结果。

提取非英语单词词干

SnowballStemmer 类,除了英语外,还可以适用于其他 13 种语言。支持的语言如下:

from nltk.stem import SnowballStemmer
print(SnowballStemmer.languages)
'danish', 'dutch', 'english', 'finnish', 'french', 'german', 'hungarian', 'italian', 'norwegian', 'porter', 'portuguese', 'romanian', 'russian', 'spanish', 'swedish'

你可以使用 SnowballStemmer 类的 stem( )函数来提取非英语单词,如下所示:

from nltk.stem import SnowballStemmer
french_stemmer = SnowballStemmer('french')
print(french_stemmer.stem("French word"))

来自法国的朋友欢迎在评论区 poll 出你们测试的结果!

使用 WordNet 引入词汇

词汇的词汇化与提取词干类似,但不同之处在于词汇化的结果是一个真正的词汇。与词干提取不同,当你试图提取一些词干时,有可能会导致这样的情况:

from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem('increases'))

结果是:increas。

现在,如果我们试图用NLTK WordNet来还原同一个词,结果会是正确的:

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('increases'))

结果是 increase。

结果可能是同义词或具有相同含义的不同词语。有时,如果你试图还原一个词,比如 playing,还原的结果还是 playing。这是因为默认还原的结果是名词,如果你想得到动词,可以通过以下的方式指定。

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('playing', pos="v"))

结果是: play。

实际上,这是一个非常好的文本压缩水平。最终压缩到原文本的 50% 到 60% 左右。结果可能是动词,名词,形容词或副词:

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('playing', pos="v"))
print(lemmatizer.lemmatize('playing', pos="n"))
print(lemmatizer.lemmatize('playing', pos="a"))
print(lemmatizer.lemmatize('playing', pos="r"))

结果是:

play
playing
playing
playing

词干化和词化差异

好吧,让我们分别尝试一些单词的词干提取和词形还原:

from nltk.stem import WordNetLemmatizer
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
print(stemmer.stem('stones'))
print(stemmer.stem('speaking'))
print(stemmer.stem('bedroom'))
print(stemmer.stem('jokes'))
print(stemmer.stem('lisa'))
print(stemmer.stem('purple'))
print('----------------------')
print(lemmatizer.lemmatize('stones'))
print(lemmatizer.lemmatize('speaking'))
print(lemmatizer.lemmatize('bedroom'))
print(lemmatizer.lemmatize('jokes'))
print(lemmatizer.lemmatize('lisa'))
print(lemmatizer.lemmatize('purple'))

结果是:

stone
speak
bedroom
joke
lisa
purpl
----------------------
stone
speaking
bedroom
joke
lisa
purple

词干提取的方法可以在不知道语境的情况下对词汇使用,这就是为什么它相较词形还原方法速度更快但准确率更低。

在我看来,词形还原比提取词干的方法更好。词形还原,如果实在无法返回这个词的变形,也会返回另一个真正的单词;这个单词可能是一个同义词,但不管怎样这是一个真正的单词。当有时候,你不关心准确度,需要的只是速度。在这种情况下,词干提取的方法更好。

我们在本 NLP 教程中讨论的所有步骤都涉及到文本预处理。在以后的文章中,我们将讨论使用Python NLTK进行文本分析。

NLTK自然语言处理入门相关推荐

  1. Python NLTK 自然语言处理入门与例程

    Python NLTK 自然语言处理入门与例程 在这篇文章中,我们将基于 Python 讨论自然语言处理(NLP).本教程将会使用 Python NLTK 库.NLTK 是一个当下流行的,用于自然语言 ...

  2. python和nltk自然语言处理 脚本之家_想要入门自然语言处理,资料贫瘠,英语不好,大神推荐斯坦福的真的是搞不定,迷迷茫茫,不知从何下手?...

    不清楚题主定义的"入门"具体是什么层次.我认知中的入门一个领域有两种:第一种,知道核心概念大概含义并能调用工具,知其然而不知其所以然,这是知和用层面的入门:第二种,扎实掌握领域涉及 ...

  3. python和nltk自然语言处理书评_python自然语言处理_自然语言处理入门

    说明:本文是<Python数据分析与数据化运营>中的"3.12.4 自然语言文本预处理".下面是正文内容-与数据库 本文从概念和实际操作量方面,从零开始,介绍在Pyth ...

  4. 《自然语言处理入门》不是 NLP 学习路上的万能药

    <自然语言处理入门>是图灵 2019 年 10 月出版的一本 NLP 领域的入门图书,作者是何晗(网名 hankcs,HanLP 作者.「码农场」博客博主).图书上架之后得到了广大的读者的 ...

  5. python自然语言处理入门教程(一)

    1.NLTK自然语言处理工具包 1.1 NLTK简介 NLTK是构建Python程序与人类语言数据工作的主要平台.它提供了易于使用的界面,以超过50语料库和词汇资源,如WordNet的,连同一套文字处 ...

  6. 自然语言处理入门(何晗):第一章

    第一章 新手上路 **自然语言处理(NLP)**是一门融合了计算机科学.人工智能以 及语言学的交叉学科, 这门学科研究的是如何通过机器学习等技术, 让计算机学会处理人类语言,乃至实现终极目标--理解人 ...

  7. 自然语言处理入门读物

    自然语言处理入门读物 本文目前研二,已经接触自然语言处理有一年的时间(半路出家),下面写一点自己关于自然语言处理的心得(纯属个人见解),先从入门学习开始写吧. 书籍-理论篇 书籍是人类进步的阶梯,这个 ...

  8. 自然语言处理入门——新手上路

    目录 一.自然与语言与编程语言 二.自然语言处理的层次 三. 自然语言处理的流派 五.语料库 六.开源工具 七 总结 自然语言处理(NLP)是一门融合了计算机科学.人工智能以及语言学的交叉学科. 一. ...

  9. Python和NLTK自然语言处理

    作者:[印度] 尼天·哈登尼亚(Nitin Hardeniya)雅各布·帕金斯 出版社:人民邮电出版社 出版时间:2019年04月 Python和NLTK自然语言处理

最新文章

  1. 基于Html5的爱情主题网站–表白神器(第二版)
  2. jsonp解析 html
  3. gitlab的升级【二】旧数据的备份和新数据的恢复
  4. 进程初识和multiprocessing模块之Process
  5. Java并发教程–线程之间的可见性
  6. python与大数据的关系论文_python与大数据的关系图
  7. 更改后缀为.dex文件为.odex文件 让你的程序瘦身 运行更稳定
  8. TypeScript:初体验
  9. 199.二叉树的右视图
  10. SAP MM采购仓储入门视频教程——适合新手入门学习
  11. 博途v15程序监视无法使用_博途V15打开应用程序失败,应用程序的并行配置不正确-工业支持中心-西门子中国...
  12. Python数字转换中文大写
  13. 如何打造微信公众号管理系统
  14. Python Crash Course读书笔记 - 第18章:GETTING STARTED WITH DJANGO
  15. PDF如何删除页面?批量删除不连续页的方法
  16. GooglePlay提审警告(com.google.android.gms:play-services-safetynet:17.0.0)
  17. 二手交易平台/二手交易系统/闲置物品交易系统
  18. ubuntu 卡死安全重启
  19. 硬核FutureTask解析
  20. 【DA9739】基于射频DAC9739的任意波形产生的性能研究

热门文章

  1. 你还在焦虑?还在痛苦吗?几句肺腑之言帮你大彻大悟
  2. 2018考研计算机408经验详谈
  3. 外网访问OpenWrt
  4. OSI参考模型下电子邮件传输过程
  5. Script标签解析
  6. wordpress修改了站点地址导致无法打开网站的解决办法
  7. 传输指令ssh,sftp,scp
  8. 高中物理学运动公式实现js动画
  9. Github 的搭建和配置github中的SSH key值,android学习视频
  10. web安全测试之appscan – “X-XSS-Protection”头缺失或不安全 - 猿码设计师