数据与智能 出版了畅销书「构建企业级推荐系统:算法、工程实现与案例分析」。每周输出7篇推荐系统、数据分析、大数据、AI原创文章。「数据与智能」(同名视频号、知乎、头条、B站、快手、抖音、小红书等自媒体平台号) 社区,聚焦数据、智能领域的知识分享与传播。
来源 | Natural Language Processing with PyTorch
作者 | Rao,McMahan
译者 | Liangchu
校对 | gongyouliu
编辑 | auroral-L
全文共4243字,预计阅读时间35分钟。
第二章 快速回顾传统 NLP 应用
1. 语料库,标记和类型
2. 一元组,二元组,三元组,... ,N元组
3. 词形和词干
4. 分类句子和文档
5. 分类单词:词性标注
6. 分类短语:分块和命名实体识别
7. 句子结构
8. 单词意义和情感
9. 总结
❤ 参考资料
自然语言处理(NLP)和计算语言学(computational linguistics,CL)是人类语言计算研究的两个领域。NLP 旨在研究解决涉及语言的实际问题的方法,如信息提取(information extraction)、自动语音识别(automatic speech recognition)、机器翻译(machine translation)、情感分析(sentiment analysis)、问答(question answering)和总结(summarization)。另一方面,CL 使用计算方法来理解人类语言特性。那么我们何以理解语言?我们何以产生语言?我们何以学习语言?不同语言之间又有什么关联呢?
在文献中,我们经常看到从 CL 到 NLP领域中研究方法和研究人员的交叉,反之亦然。来自CL关于语言的教训和经验可以用于作为NLP的先验内容,而来自NLP的统计和机器学习方法可以用来回答 CL 想要回答的问题。实际上,这些问题中的一部分已经扩展成它们自己的学科,如音位学(phonology)、形态学(morphology)、句法学(syntax)、语义学(semantics)和语用学(pragmatics)。
在本书中,我们只关注 NLP,但我们也经常会根据需要从 CL 中借鉴思想。在将自己完全投身于 NLP 的神经网络方法之前,还有必要回顾一下一些传统的 NLP 概念和方法,这就是本章的学习目标。
如果你有 NLP 相关的的背景知识则可以跳过这一章,但你也可以再看一遍回忆一下,也便于为未来建立一个共享的词汇表。
1. 语料库,标记和类型所有的 NLP 方法,无论是经典的还是现代的,都以文本数据集开始,也称为语料库(corpora)。语料库通常包括原始文本(ASCII 或 UTF-8 格式)和与文本相关的所有元数据。原始文本是一个字符(字节)序列,但大多数情况下将字符分组成称为标记(token,也可以理解为词元 )的连续单元是有用的。在英语中,标记token对应于由空格字符或标点分隔的单词和数字序列。
元数据可以是任何与文本相关联的辅助信息,例如标识符,标签和时间戳。在机器学习术语中,文本及其元数据称为实例(instance)或数据点(data point)。下图(2-1)的语料库是一组实例,也称为一个数据集(dataset)。鉴于本书重点关注机器学习,我们可以自由地将语料库和数据集这两个术语交替使用。
将文本分解为标记token的过程称为分词(tokenization)。例如,世界语句子:Maria frapis la verda sorĉistino有六个token。分词可能比简单地基于非字母数字字符拆分文本更加复杂,如下图(2-2)所示。对于像土耳其语这样的粘合语言来说,仅仅分隔空格和标点符号可能是不够的,因此可能需要更专业的技术。你将在第四章和第六章中看到,通过将文本表示为字节流,我们能够在某些神经网络模型中完全规避分词问题,这对于粘合语言来说是很重要的。
最后,考虑一下下面这条推文:
将推文进行分词的过程涉及到保存话题标签和@handle,以及将表情符号(如:-))和URL按单元分隔的问题。#MakeAMovieCold标签应该是 1 个还是 4 个token呢?虽然大多数论文并不太关注这一问题,但是实际上,有关分词的决策可能十分随意,然而这些决策在实践中对于准确性的影响要比公认的大得多。分词通常被认为是预处理的一项繁琐工作,大多数开源 NLP 包为分词提供了合理支持。下例(2-1)展示了来自 NLTK 和 SpaCy 的示例,它们都是用于文本处理的常用包。
示例 2-1:文本分词
Input[0]:
import spacy
nlp = spacy.load('en')
text = "Mary, don't slap the green witch"
print([str(token) for token in nlp(text.lower())])
Output[0]:
['mary', ',', 'do', "n't", 'slap', 'the', 'green', 'witch', '.']
Input[1]:
from nltk.tokenize import TweetTokenizer
tweet=u"Snow White and the Seven Degrees
#MakeAMovieCold@midnight:-)"
tokenizer = TweetTokenizer()
print(tokenizer.tokenize(tweet.lower()))
Output[1]:
['snow', 'white', 'and', 'the', 'seven', 'degrees', '#makeamoviecold', '@midnight', ':-)']
类型(type)是语料库中唯一的标记。语料库中所有类型的集合就是它的词汇表(vocabulary)或词典(lexicon)。词可以区分为内容词(content words)和停用词(stopwords)。像冠词和介词这样的限定词主要是为了语法正确性,就像承载着内容词的填充物一样。
特征工程
这种理解语言的语言学并将其应用于解决NLP问题的过程称为特征工程(feature engineering)。为了模型在不同语言之间的方便和可移植性,我们将其保持在最低限度。但是在构建和部署真实的生产系统时,特性工程是必不可少的,尽管最近也有说法与此相悖。一般来说,要了解特征工程,可以阅读 Zheng和Casari(2016)的书。
2. 一元组,二元组,三元组,...,N 元组
N 元组(N-grams)是文本中出现的固定长度(n)的连续token序列。二元组(bigram)有两个token,一元组(unigram)只有一个token。如下例(2-2)所示,从文本生成 N 元组非常容易,SpaCy 和 NLTK 等包提供了方便的方法。
示例 2-2:生成 N 元组
Input[0]:
def n_grams(text, n):
'''
takes tokens or text, returns a list of n grams
'''
return [text[i:i n] for i in range(len(text)-n 1)]
cleaned = ['mary', ',', "n't", 'slap', green', 'witch', '.']
print(n_grams(cleaned, 3))
Output[0]:
[['mary', ',', "n't"],
[',', "n't", 'slap'],
["n't", 'slap', 'green'],
['slap', 'green', 'witch'],
['green', 'witch', '.']]
对于子词(subword)信息本身携带有用信息的某些情况,可能需要生成字符 N 元组。例如,methanol中的后缀-ol表示它是一种醇,如果任务涉及对有机化合物名称的分类,那么你能知道 N 元组捕获的子词(subword)信息是很有用的。在这种情况下,你可以重用代码,将每个字符 N 元组视为token。
3. 词形和词干词形(lemma)是单词的词根形式。考虑动词fly。它可以引申为许多不同单词——flow、flew、flies、flown、flowing等等——而fly是所有这些看似不同单词的词形。有时,为了保持向量表示的低维度,可以将token缩减为到它们的词形。这种简化称为词形还原(lemmatization),你可以在下例(2-3)中看到它的作用:
示例 2-3:词形还原
Input[0]
import spacy
nlp = spacy.load('en')
doc = nlp(u"he was running late")
for token in doc:
print('{} --> {}'.format(token, token.lemma_))
Output[0]
he --> he
was --> be
running --> run
late --> late
例如,SpaCy 使用一个预定义的字典 WordNet 来提取词形,但是词形还原可以构建为一个需要理解语言形态学的机器学习问题。
词干化(Stemming)是最常见的词形还原,它涉及使用人为制定的规则来去掉单词的结尾,从而将之简化为一种叫做词干的常见形式。通常在开源包中所实现的比较流行的词干分析器是 Porter 词干提取器和 Snowball 词干提取器。至于调用 SpaCy/NLTK API进行词干提取,就留给你自己去寻找和发现了。
4. 分类句子和文档对文档进行归类或分类可能是 NLP 最早的应用之一。我们在第一章中描述的TF表示和TF-IDF表示对于对较长的文本块(如文档或句子)进行分类是非常有用的。主题标签的分配、评论情感的预测、垃圾邮件的过滤、语言识别和邮件分类等问题都可以被定义为受监督的文档分类问题。(对于半监督版本,其中只使用了一个小的标签数据集,非常有用,但不在本书涉及范围之内。)
5. 分类单词:词性标注我们可以将标签的概念从文档扩展到单个单词或token。分类单词的一个常见示例是词性标注(categorizing words is part-of-speech,POS tagging),如下例(2-4)所示:
示例 2-4:词性标注
Input[0]
import spacy
nlp = spacy.load('en')
doc = nlp(u"Mary slapped the green witch.")
for token in doc:
print('{} - {}'.format(token, token.pos_))
Output[0]
Mary - PROPN
slapped - VERB
the - DET
green - ADJ
witch - NOUN
. - PUNCT
我们通常需要标记文本的范围,也即一个连续的多标记边界,例如句子Mary slapped the green witch.,我们可能需要识别其中的名词短语(noun phrase,NP)和动词短语(verb phrase,VP),如下所示:
[NP Mary] [VP slapped] [the green witch].
该操作称为分块(chunking)或浅层句法分析(shallow parsing)。浅层句法分析旨在推导出由名词、动词、形容词等语法原子组成的高阶单位。如果没有用于训练浅层句法分析模型的数据,可以在词性标注上编写正则表达式来近似浅层句法分析。幸运的是,对于英语等最广泛使用的语言来说,这样的数据和预训练模型是存在的。下例(2-5) 给出了一个使用 SpaCy 的浅层句法分析示例:
示例 2-5:NP分块
Input[0]:
import spacy
nlp = spacy.load('en')
doc = nlp(u"Mary slapped the green witch.")
for chunk in doc.noun_chunks:
print '{} - {}'.format(chunk, chunk.label_)
Output[0]:
Mary - NP
the green witch - NP
另一种有用的范围类型是命名实体(named entity)。命名实体是一个包括真实世界概念的字符串,如人员、位置、组织、药品名称等等。下面是例子:
7. 句子结构
浅层句法分析的作用是识别短语单元,而识别它们之间关系的任务称为解析(parsing)。你可能记得在上英语初级课程时有见过如下图(2-3)所示的图表来表示句子:
解析树(parse tree)表示句子中不同的语法单元在层次上是如何相关联的。上图(2-3)中的解析树显示了所谓的成分分析(constituent parse)。另一种可能更有用的用于显示关系的方法是使用依存句法分析(dependency parsing),如下图(2-4)所示:
要了解更多关于传统句子解析的信息,请参阅本章末尾的“参考资料”部分。
8. 单词意义和情感单词是有意义的,而且通常不止一个意义。一个词的不同含义称为它的意义(senses)。WordNet 是一个长久运行的词汇资源项目,它来自普林斯顿大学,旨在对所有(绝大部分)英文单词的含义以及其他词汇关系进行分类。例如,考虑像plane这样的单词。下图(2-5)展示了plane一词的不同用法:
即使是在有现代流行方法的情况下,为像 WordNet 这样的项目付出数十年的努力也是值得的。本书后面的章节给出了在神经网络和深度学习方法的背景下使用现有语言资源的例子。
词的意义也可以从上下文中归纳总结出来——从文本中自动发现词义实际上是半监督学习在NLP中的第一个应用,尽管我们在本书中并不介绍相关内容,但我们还是鼓励你阅读 Jurasky and Martin(2014),第十七章,以及Manning and Schutze(1999),第七章。
9. 总结在这一章中,我们回顾了 NLP 中一些基本的术语和思想,这些对于学习后续章节很有用。本章只涉及了有关传统 NLP 的部分内容,并忽略了传统NLP一些重要方面,因为我们想将本书的大部分笔墨用于 NLP 的深度学习。然而你得知道,其实存在大量不使用神经网络的 NLP 研究工作,并且仍然具有很大影响力(即,广泛用于构建生产系统)。在许多情况下,基于神经网络的方法应当被看作是传统方法的补充而非替代。有经验的实践者经常结合使用这两个方法的优点来构建最先进的系统。为了深入了解NLP传统方法,我们推荐以下参考资料。
❤参考资料1.Manning, Christopher D., and Hinrich Schütze. (1999). Foundations of Statistical Natural Language Processing. MIT press.
2.Bird, Steven, Ewan Klein, and Edward Loper. (2009). Natural Language Processing with Python: Analyzing Text with the Natural Language Toolkit. O'Reilly.
3.Smith, Noah A. (2011). Linguistic Structure prediction. Morgan and Clypool.
4.Jurafsky, Dan, and James H. Martin. (2014). Speech and Language Processing. Vol. 3. London: Pearson.
5.Russell, Stuart J., and Peter Norvig. (2016). Artificial Intelligence: A Modern Approach. Pearson.
6.Zheng, Alice, and Casari, Amanda. (2018). Feature Engineering for Machine Learning: Principles and Techniques for Data Scientists. O'Reilly.
,