作者Pratik Shukla,Roberto Iriondo
由于原文是英文,且用英文NLP举例,一些例子在中文环境下会出现不适用。
这篇文章主要讨论NLP以及Python NLTK包。文章内所需要的文件和资源在github,自取
towardsai/tutorialsgithub.com
目录:
- 什么是自然语言处理(NLP)?
- 自然语言处理的应用
- 理解自然语言处理
- 基于规则的NLP(rule-based)与统计NLP(statistical)
- NLP的组成部分
- NLP现在面临的难题
- 易于使用的NLP库
- NLTK
- spaCy
- Gensim
- Pattern
- TextBlob
- 探索NLTK的特性
- 词云图
- Stemming
- Lemmatization
- 词性标记(Pos)
- Chunking
- Chinking
- 命名实体识别(NER)
- 词网(WordNet)
- Bag of Words,词袋
- TF-IDF
Natural Language Processing,自然语言处理
1 什么是NLP?
电脑很擅长处理表格式的数据或者数据表,但通常人的交流是以单词和句子进行,而不是表格,很多说出或写下的信息是非结构化的(unstructured)。自然语言处理的目的是让电脑理解非结构化(unstructured)的文本并且从中获取有价值的信息片段。自然语言处理是人工智能的子领域,涉及到人机交互。
2 NLP的应用
- 机器翻译
- 语音识别
- 情绪分析
- 问题回答
- 概括文章
- 聊天机器人
- 现在的Siri,微软小冰,小爱同学应该都是
- 早年(2011年左右)有个[1]白丝魔理沙,那个还可以让用户训练她,据说是新的地址:
白絲魔理沙 -已斷線-toy.reimu.ru
- 智能系统
- 文本分类
- 字符识别
- 拼写检查
- 检测垃圾邮件
- 联想输入
3 理解自然语言处理
图1:显示,倾听,并理解
作为人类,我们可以很好地执行自然语言处理,但即使是这样,我们做得也并不完美。我们经常把一件事误解为其他,也经常对同样的句子或单词有不同理解。
举个例子,想想下面这句话,我们可以尝试从不同方面理解它的意思:
示例1
图2: NLP示例句子,“I saw a man on a hill with a telescope”
对于上面句子的一些理解:
English | 中文 |
There is a man on the hill, and I watched him with my telescope. | 山坡上有个男人,我用望远镜看到了他。 |
There is a man on the hill, and he has a telescope. | 山坡上有个男人,他有个望远镜(这也是我理解的)。 |
I'm on a hill, and I saw a man using my telescope. | 我在山坡上,我用我的望远镜看到了一个男人(我第二个理解)。 |
I'm on a hill, and I saw a man who has a telescope. | 我在山坡上,我看到一个有望远镜的男人。 |
There is a man on a hill, and I saw him something with my telescope | 山坡上有个人,我用望远镜看见了他的东西(机翻)。 |
示例2
图3: NLP示例句子,“Can you help me with the can?”
在如上句子中,我们可以看到有两个“can”词,但是他们两个都有不同的意思。第一个“can”用来组成问题(question formation),第二个放在句尾的“can”表示能装食物或者液体的容器。
因此,通过上述两个例子,我们可以发现自然语言处理不是“确定性的/deterministic(同样的语言有同样的意思)”,并且对一个人合适的内容对另一个人可能并不合适。因此NLP使用了非确定性的方法。换而言之,NLP可以被用来创造一种能理解人是如何在不同情境下理解并推断语言的新的智能系统。
4 基于规则的NLP(rule-based)与统计NLP(statistical)
NLP被分为两个不同的方法:
基于规则的NP
使用常识来处理任务。比如,冰点能导致死亡,或是热咖啡可以烫伤肌肤,以及其他一些常识。但是,这种处理需要花费不少时间,并且需要投入人力。
统计NLP
使用大量数据并常识从中获取结论。统计NLP使用机器学习算法训练NLP模型,在成功训练大量数据后,训练过的模型可以产出有意义的结果并进行推论。
比较:
图4:基于规则的NLP(rule-based)与统计NLP(statistical)
基于规则的NLP | 统计NLP |
+1)灵活 | +1)易于扩展 |
+2)容易DEBUG | +2)自我学习 |
+3)不需要太多训练 | +3)发展速度快 |
+4)理解语言 | +4)覆盖面广 |
+5)精准度高 | |
(缺点) | |
-1)需要熟练的开发者 | -1)需要大量数据 |
-2)语法分析慢 | -2)很难debug |
-3)覆盖面中等 | -3)不理解文本 |
5 NLP的组成
图5:NLP的组成
a 词法分析:
通过词法分析,把一整块文章分为段落,句子和单词。这部分涉及识别并分析单词的结构。
b 句法分析:
句法分析涉及单词在句子中的语法分析和显示单词之间关系的单词排列。譬如,“The shop goes to the house(商店到房子去)”不成立。
c 语义分析:
语义分析抽取单词确切的意思,并且分析文本的意义。像“热冰淇淋”这样的句子不会通过。
d 发现整合:
发现整合会考虑文本的上下文,它会在句子结束之前思考句子的意思。比如,“He works at Google”,这个句子中的“He”必须在前面的句子里提到
e 语用分析:
语用分析处理语言中全部的交流和解释,涉及在各种情况下有意义地使用语言的问题。
6 NLP现在面临的难题
- 把句子分解为标记;
- 标记词性(Tagging parts of speech (POS))
- 建立适当的词库(vocabulary);
- 链接已创建词汇的组成部分;
- 理解上下文;
- 提取语义;
- 命名实体识别(Named Entity Recognition (NER));
- 把非结构化数据转化为结构化数据;
- 语言含糊。
7 易于使用的NLP库
a. NLTK (Natural Language Toolkit)
Python中的NLTK框架通常用做教育和研究工具,不用于生成应用程序。但是,由于它易于使用,它可以用来构建令人兴奋的程序。
特性:
- 标记化。
- 语音标记(POS)的一部分。
- 命名实体识别(NER)。
- 分类。
- 情绪分析。
- 聊天机器人程序包。
用例:
- 推荐系统。
- 情绪分析。
- 构建聊天机器人。
图6:使用NLTK框架的优缺点
优点 | 缺点 |
+1) 最全、最完善的NLP库 | -1)难学,难用 |
+2)支持语言数量最多 | -2)单词的上下文被无视 |
-3)慢 | |
-4)没有神经网络模型 |
b. spaCy:
spaCy是个开源NLP Python库,旨在快速且立刻能产出。SpaCy致力于提供于生产用途的软件。
特点:
- 标记化。
- 语音标记(POS)的一部分。
- 命名实体识别(NER)。
- 分类。
- 情绪分析。
- 依赖性解析。
- 词向量。
用例:
- 自动完成和自动更正。
- 分析评论。
- 摘要概括。
图7:spaCy框架的优缺点
优点 | 缺点 |
+1)快速 | -1)不够灵活 |
+2)易学易用 | |
+3)训练中使用了神经网络 |
c. Genism
ddff Genism是个用于话题构建(topic modeling)和相似度检测的Python NLP框架。它不是个通用NLP库,但它能很好处理分配的任务。
特点:
- 潜在语义分析。
- 非负矩阵分解。
- TF-IDF。
用例:
- 将文档转换为矢量。
- 查找文本相似性。
- 文字摘要。
图8:Genism框架的优缺点
优点 | 缺点 |
+1)直观的界面 | -1)为无监督文本模型设计 |
+2)可扩展的 | -2)必须和其他库一起使用 |
+3)算法移植 |
d. Pattern
Pattern是具有直截了当语法的Python NLP框架。它对于科研和非科研任务来说是个强大的工具,它对于学生来说也具有很高价值。
特征:
- 标记化。
- 语音标记的一部分。
- 命名实体识别。
- 解析。
- 情绪分析。
用例:
- 拼写校正。
- 搜索引擎优化。
- 情绪分析
图9:Pattern框架的优缺点
优点 | 缺点 |
+1)数据挖掘 | -1)没有对特定NLP任务进行优化 |
+2)网络分析和可视化 |
e. TextBlob
TextBlob是设计用于处理文本数据的Python库。特征:
- 词性标记。
- 名词短语提取。
- 情绪分析。
- 分类。
- 语言翻译。
- 解析。
- 词网集成。
用例:
- 情绪分析。
- 拼写校正。
- 翻译和语言检测。
图10:Pattern框架的优缺点
优点 | 缺点 |
+1)易于使用 | -1)太慢 |
+2)对NLTK有直观界面 | -2)没有神经网络模型 |
+3)提供语言翻译和检测 | -3)没有整合的词向量 |
在这个教程里,我们会主要关注NLTK库。让我们通过一些示例来更深入地研究自然语言。
8 探索NLTK的特性
所需代码均来自原作者给出的github
a. 打开text文本进行处理:
首先,我们要打开并读取想要分析的文件。
图11:打开并读取文件的代码
图12:文本字符串文件
字符串。在文本中一共有676个字符。
b. 载入所需的库
为了各种类型的NLP数据处理,我们需要载入一些库。在这个例子中,我们将载入NLTK进行自然语言处理。我们回把它运用在各种文本处理上。
图13:载入需要的库
c. 句子标记(Sentence tokenizing)
通过使用sent_tokenize()对文本中的句子划分,我们可以将文本转化为句子。
图14:使用sent_tokenize()把文本划分为句子
图15:文本示例数据
在如上例子中,我们可以看到整个文本已经被表示为了句子,并且句子的总数为9。
d. 标记词(Word tokenizing)
通过使用word_tokenize()对文本中的词进行标记,可以将以单词的方式获取文本。
图16:使用word_tokenize()标记文章
图17:示例文本数据
我们可以发现整个文章已经被表示为单词形式,并且现在单词的总数为144。
e. 找到词频分布:
查看文本中词频分布情况
图18:使用FreqDist()找到词频
图19:打印10个样本文章里的高频单词
可以发现,最常用的单词是标点和停用词。为了分析实际的文本内容,我们要移除这些词。
f. 画出频率图
画图,将文本中的单词分布可视化。
图20:可视化文本分布
在上图中,可以发现句号“.”在文本里使用了9次。从分析的角度说,标点符号对自然语言分析不那么重要。因此,在下一步中,我们将移除标点符号。
g. 移除标点符号
我们需要移除没有什么用处的标点符号。使用isalpha()函数将标点从文本中分离,同时创建一个新的list叫做words_no_punc,这个list存储了不含标点的小写单词。
图21: 使用isalpha()将标点分开,创建word_no_punc list存储不带标点的小写单词
图22:示例文本数据
如上所示,所有的标点符号已经从文本中移除。这也能检查文本的词数。
h. 画不带标点的分布图:
图23:打印10个样本文章里的高频单词
图20:可视化文本分布(无标点符号)
需要注意的是,文本里仍然有很多对分析帮助不大的词,比如“and”,“but”,“so”和其他一些词。下一步,我们需要移除这些连接词。
i. 停用词表:
图25:调用停用词
图26:示例文本
j. 移除停用词:
图27: 清理文本
图28:清理过后的数据
k. 最终词频分布:
图29: 最终词最常出现的词的分布
图30:可视化最常见的词
如上所示,最终图形中有许多有用的词,可帮助我们了解样本数据的含义,表明在NLP上执行数据清理的必要性。
接下来,我们将通过编码示例介绍NLP中的各个话题。
9 词云图
词云图是一种数据可视化技术,将给定文本李的单词展示在一张主表上。在这个工具里,更常出现或更重要的单词会用更大更粗的字体(字号),而更少出现、更不重要的单词会以小一些或是细一些的字体展示。这是NLP中有益的技术,让我们可以查看哪些文本应该被分析。
原文似乎有误,更常出现、更重要的单词应该对应不常出现、不重要的单词,但作者仍然使用了less frequent or essential words:
In this technique, more frequent or essential words display in a larger and bolder font, while less frequent or essential words display in smaller or thinner fonts.
属性:
- font_path: 设定想要使用的字体的路径。
- width: 设定画布长度。
- height: 设定画布宽度。
- min_font_size: 设定想要使用的最小字号。
- max_font_size:
- font_step: 设定字号间隔(step size)。
- max_words: 设定词云中最大单词个数。
- stopwords: 去掉停用词。
- background_color:
- normalize_plurals: 去掉单词结尾的s。
阅读词云图的全部文档。
词云图在Python中的实现:
图31:Python代码实现词云图
图32: 词云图示例.
如上襦所示,频率最高的单词用了更大的字体。词云图能以任何形状或图像展示。
列如,我们会用到下图这个圆圈图像。
原文此处并不通顺的感觉:
For instance: In this case, we are going to use the following circle image, but we can use any shape or any image.
图33:用于词云图的圆形图片
词云图在Python中的实现:
图34:Python代码实现词云图
图35: 圆形词云图
如上图所示,词云图呈现圆形。正如我们之前提到,我们可以用任何形状构成词云图。
词云图的优点:
- 很快
- 有趣(engaging)
- 容易理解
- 简单又美观(casual and visually appealing)
词云图的缺点:
- 对于脏数据,词云图是不完善的。
- 缺乏单词上下文。
10 Stemming
我们将使用Stemming标准化单词。在英语和其他语言中,一个单词在不同上下文中可以有多重形式。举例来说,根据上下文,动词“study”可以有像“studies”,“studying”,“studied”等好几种形式。当标记单词时,即使它们的基本含义相同,解释器也会将这些输入单词视为不同的单词。再者,正如我们知道NLP是分析上下文含义的,为了解决这个问题,我们要用到stemming。
Stemming通过把单词截断到词根来标准化单词。例如,studies”,“studying”,“studied”会被截断为“studi”,使所有单词形式指向一个标签。
a. Porter's Stemmer例1
在下面例子里,所有单词被截断至词根。但是要注意,stemmed word不是词典词(dictionary word)。
图36:stemming例子
b. Porter's Stemmer例2
下面的例子里,许多单词在stemming之后并没有变成可被识别的词典词。
图37:stemming 例子
c. SnowballStemmer:
Snowball stemmer和porter stemmer有同样的输出,但Snowball支持更多语言。
图38:stemming 例子
d. snowball stemmer支持的语言:
图39:NLP stemming例子
Stemming的多种算法
a. Porter's Stemmer:
图40:Porter's Stemmer NLP算法,优缺点
Porter's Stemmer |
优点 |
产出最好的结果,并且错误率最低 |
局限 |
删改的词并不总是实际存在的词 |
b. Lovin's Stemmer:
图41:Lovin's Stemmer NLP算法,优缺点
Lovin's Stemmer |
优点 |
快,且能处理不规则名词复数,例如foot→feet |
局限 |
耗时长,且错误率高 |
c. Dawson's Stemmer:
图42:Dawson's Stemmer NLP算法,优缺点
Dawson' s Stemmer |
优点 |
快,覆盖更多后缀 |
局限 |
实现比较复杂 |
d. Krovetz Stemmer:
图43:Krovetz Stemmer NLP算法,优缺点
Krovetz Stemmer |
优点 |
体积小(light in nature),是其他stemmer的pre-stemmer |
局限 |
对于大文件来说效率低下 |
注:light in nature不知道怎么翻译
e. Xerox Stemmer:
图43:Xerox Stemmer NLP算法,优缺点
Xerox Stemmer |
优点 |
能很好处理大文件,错误率低 |
局限 |
可能会导致overstemming和语言依赖(language dependent) |
f. Snowball Stemmer:
图43:Snowball Stemmer NLP算法,优缺点
Snowball Stemmer |
优点 |
支持更多语言 |
局限性 |
截断的词并不总是实际存在的词 |
11 Lemmatization
Lemmatization试图为单词找到相似的“根”。但是,它不同之处在于,lemmatization寻找字典单词(dictionary word)而不是截断原来的单词。Stemming不考虑单词的上下文,这是它能比lemmatization更快出结果,但精确度更低的原因。
如果准确性不是项目的最终目标,那么stemming是一种合适的方法。如果高精确度是至关重要的,且项目的deadline不那么紧张,那最好的选择是amortization(与stemming相比,lemmatization处理速度更慢)。
Lemmatization考虑了词性(Part-of-Speech, POS)。同时,lemmatization会根据POS值的不同生成不同的结果。通常POS有四种类型:
图46:lemmatization中POS值
Stemmer和Lemmatizer的不同:
a. Stemming:
在stemming中,单词"studies"被截断为"studi".
图47: 使用nltk stemming
b. Lemmatizing:
在lemmatization时,单词“studies”被表示为对应的字典单词“study”。
图47: 使用nltk lemmatization
Python实现
a. 举例说明lemmatizer如何工作
在下面的例子里,我们将PoS的标签设定为动词(verb),使用lemmatization,使其返回字典单词而不是截断原始单词:
图49
b. 使用Pos默认值的Lemmatizer
Lemmatization的默认PoS值是名词(noun(n))。下面的例子可以看到它是如何生成字典词的:
图50
c.另一个说明lemmatizer强大的例子
图51
d. 使用不同POS值的lemmatizer
12 词性标记(Pos)
13 Chunking
14 Chinking
15 命名实体识别(NER)
16 词网(WordNet)
17 Bag of Words,词袋
图114:词袋的表示形式
什么是词袋(bag-of-words)?
词袋是一种从原始文本里抽取基本信息,以用于机器学习模型的方法。我们称它为“袋”是因为我们舍弃了单词出现的顺序。词袋模型将原始文本转化为单词,并且计算单词在文章里的频率。总而言之,词袋是能代表句子的词和词频的集合,单词的出现顺序并不重要。
图115:词袋的结构
- 原始文本(Raw Text):我们想要分析的原始文本;
- 清理后的文本(Clean Text):由于原文本中包含了像标点或停用词之类不必要的数据,所以我们需要清理文本。清理后的文本就是移除这些词的文本。
- 标记化(Tokenize):标记化将句子表示为一组标记或单词。
- 构建词库(Building Vocab):包含了移除所有不必要数据后的单词
- 整理词库(Generate Vocab):包含了句子中的单词和单词频率
示例:
句子:
- Jim and Pam traveled by bus.
- The train was late.
- The flight was full. Traveling by flight is expensive.
a. 创建基本结构:
图116:词袋的基本结构示例
b. 单词和频率:
图117:单词和词频的基本结构示例
c. 合并所有单词:
图118:所有词的组合
d. 最终模型:
图119:词袋的最终模型
Python实现
图120:Python实现代码片段
图121:输出
图122:单词袋输出
应用:
- 自然语言处理
- 从文档里检索信息
- 文本分类
局限性:
- 语义:不考虑单词的语义,忽略单词的上下文
- 词向量:对于长文章,向量大小增加,可能导致更长的计算时间
- 预处理:在使用前需要清理数据
18 TF-IDF
参考
- ^白丝魔理沙git https://github.com/TohoOutsiders/web-marisa