前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python中的NLP

Python中的NLP

作者头像
February
发布2018-11-30 14:33:31
3.9K1
发布2018-11-30 14:33:31
举报
文章被收录于专栏:技术翻译技术翻译

自然语言处理(NLP)是数据科学中最有趣的子领域之一,数据科学家越来越期望能够制定涉及利用非结构化文本数据的解决方案。尽管如此,许多应用数据科学家(来自STEM和社会科学背景)都缺乏NLP经验。

在这篇文章中,我将探讨一些基本的NLP概念,并展示如何使用Python中日益流行的spaCy包实现它们。这篇文章是针对绝对的NLP初学者,但是假设有Python的知识。

spaCy是什么?

spaCy是由Matt Honnibal在Explosion AI开发的“工业强度NLP in Python”的相对较新的软件包。它的设计考虑了应用数据科学家的意义,这意味着它不会影响用户对用于常见任务的深奥算法的决策,而且速度快 - 速度极快 - 它在Cython中实现。如果您熟悉Python数据科学堆栈,那么spaCy就是您numpy的NLP - 它相当低级但非常直观且高性能。

那么,它能做什么?

spaCy为任何NLP项目中常用的任务提供一站式服务,包括:

  • 符号化
  • 词形还原
  • 词性标注
  • 实体识别
  • 依赖解析
  • 句子识别
  • 单词到矢量转换
  • 许多方便的方法来清理和规范化文本

我将提供其中一些功能的高级概述,并展示如何使用spaCy访问它们。

让我们开始吧!

首先,我们加载spaCy的管道,按照惯例,它存储在一个名为的变量中nlp。声明此变量将需要几秒钟,因为spaCy会预先将模型和数据加载到其中,以便以后节省时间。实际上,这会使得早期的解决方案变得非常繁重,因此每次将nlp解析器应用到数据时都不会产生成本。请注意,在这里,我使用的是英语语言模型,但也有一个功能齐全的德语模型,在多种语言中实现了标记化(如下所述)。

我们在示例文本上调用NLP来创建Doc对象。该Doc对象现在是文本本身的NLP任务的容器,文本(Span对象)和文本的元素(Token对象)的切片。值得注意的是TokenSpan对象实际上没有数据。相反,它们包含指向Doc对象中包含的数据的指针,并且被懒惰地评估(即根据请求)。spaCy的大部分核心功能是通过Doc(n = 33),Span(n = 29)和Token(n = 78)对象上的方法访问的。

代码语言:javascript
复制
In[1]: import spacy
...: nlp = spacy.load("en")
...: doc = nlp("The big grey dog ate all of the chocolate,
                but fortunately he wasn't sick!")

标记化

标记化是许多NLP任务的基础步骤。标记文本是将一段文本拆分为单词,符号,标点符号,空格和其他元素的过程,从而创建标记。一种天真的方法是简单地将字符串拆分为空格:

代码语言:javascript
复制
In[2]: doc.text.split()
 ...:
Out[2]:
['The',
 'big',
 'grey',
 'dog',
 'ate',
 'all',
 'of',
 'the',
 'chocolate,',
 'but',
 'fortunately',
 'he',
 "wasn't",
 'sick!']

从表面上看,这看起来很好。但请注意,它忽略了标点符号,并且不会分割动词和副词(“是”,“不是”)。换句话说,它是天真的,它无法识别帮助我们(和机器)理解其结构和意义的文本元素。让我们看看spaCy如何处理这个问题:

代码语言:javascript
复制
In[3]: [token.orth_ for token in doc]
 ...:
Out[3]:
['The',
 'big',
 'grey',
 'dog',
 'ate',
 'all',
 'of',
 'the',
 'chocolate',
 ',',
 'but',
 'fortunately',
 'he',
 'was',
 "n't",
 ' ',
 'sick',
 '!']

在这里,我们访问每个令牌的.orth_方法,该方法返回令牌的字符串表示,而不是SpaCy令牌对象。这可能并不总是可取的,但值得注意。SpaCy识别标点符号,并能够从单词标记中分割出这些标点符号。许多SpaCy的令牌方法提供了已处理文本的字符串和整数表示:带有下划线后缀的方法返回字符串和没有下划线后缀的方法返回整数。例如:

代码语言:javascript
复制
In[4]: [(token, token.orth_, token.orth) for token in doc]
 ...:
Out[4]:
[(The, 'The', 517),
 (big, 'big', 742),
 (grey, 'grey', 4623),
 (dog, 'dog', 1175),
 (ate, 'ate', 3469),
 (all, 'all', 516),
 (of, 'of', 471),
 (the, 'the', 466),
 (chocolate, 'chocolate', 3593),
 (,, ',', 416),
 (but, 'but', 494),
 (fortunately, 'fortunately', 15520),
 (he, 'he', 514),
 (was, 'was', 491),
 (n't, "n't", 479),
 ( , ' ', 483),
 (sick, 'sick', 1698),
 (!, '!', 495)]
In[5]: [token.orth_ for token in doc if not token.is_punct | token.is_space]
 ...:
Out[5]:
['The',
 'big',
 'grey',
 'dog',
 'ate',
 'all',
 'of',
 'the',
 'chocolate',
 'but',
 'fortunately',
 'he',
 'was',
 "n't",
 'sick']

很酷,对吗?

词形还原

标记化的相关任务是词形还原。词形还原是将单词缩减为基本形式的过程 - 如果你愿意的话,它的母语单词。单词的不同用法通常具有相同的根含义。例如,练习练习练习都基本上是指同一件事。通常希望标准化与其基本形式具有相似含义的单词。使用SpaCy,我们可以使用令牌的.lemma_方法访问每个单词的基本表单:

代码语言:javascript
复制
In[6]: practice = "practice practiced practicing"
 ...:  nlp_practice = nlp(practice)
 ...: [word.lemma_ for word in nlp_practice]
 ...:
Out[6]:
['practice', 'practice', 'practice']

为什么这有用?一个直接的用例是机器学习,特别是文本分类。例如,在创建“词袋”之前对文本进行词形避免可避免单词重复,因此,允许模型更清晰地描绘跨多个文档的单词使用模式。

POS标记

词性标注是将语法属性(即名词,动词,副词,形容词等)分配给单词的过程。共享相同POS标签的单词往往遵循类似的句法结构,并且在基于规则的过程中很有用。

例如,在事件的给定描述中,我们可能希望确定谁拥有什么。通过利用所有格,我们可以做到这一点(提供文本在语法上是合理的!)。SpaCy使用流行的Penn Treebank POS标签(见这里)。使用SpaCy,您可以分别使用.pos_.tag_方法访问粗粒度和细粒度POS标签。在这里,我访问细粒度的POS标签:

代码语言:javascript
复制
In[7]: doc2 = nlp("Conor's dog's toy was hidden under the man's sofa in the woman's house")
...: pos_tags = [(i, i.tag_) for i in doc2]
...: pos_tags
...:
Out[7]:
[(Conor, 'NNP'),
('s, 'POS'),
(dog, 'NN'),
('s, 'POS'),
(toy, 'NN'),
(was, 'VBD'),
(hidden, 'VBN'),
(under, 'IN'),
(the, 'DT'),
(man, 'NN'),
('s, 'POS'),
(sofa, 'NN'),
(in, 'IN'),
(the, 'DT'),
(woman, 'NN'),
('s, 'POS'),
(house, 'NN')]

我们可以看到's 令牌被标记为POS。我们可以利用此标记来提取所有者及其拥有的东西:

代码语言:javascript
复制
In[8]: owners_possessions = []
...: for i in pos_tags:
...:     if i[1] == "POS":
...:         owner = i[0].nbor(-1)
...:         possession = i[0].nbor(1)
...:         owners_possessions.append((owner, possession))
...:
...: owners_possessions
...:
Out[8]:
[(Conor, dog), (dog, toy), (man, sofa), (woman, house)]

这将返回所有者拥有元组的列表。如果你想成为关于它的超级Pythonic,你可以在列表综合中做到这一点(我认为这是更好的!):

代码语言:javascript
复制
In[9]: [(i[0].nbor(-1), i[0].nbor(+1)) for i in pos_tags if i[1] == "POS"]
...:
Out[9]:
[(Conor, dog), (dog, toy), (man, sofa), (woman, house)]

在这里,我们使用每个令牌的.nbor方法,该方法返回令牌的相邻令牌。

实体识别

实体识别是将文本中找到的命名实体分类为预定义类别(如人员,地点,组织,日期等)的过程.scaCy使用统计模型对广泛的实体进行分类,包括人员,事件,艺术作品和国籍/宗教(参见完整清单的文件)。

例如,让我们从巴拉克奥巴马的维基百科条目中获取前两句话。我们将解析此文本,然后使用Doc对象的.ents方法访问标识的实体。通过调用Doc方法,我们可以访问更多的Token方法,特别是.label_.label

代码语言:javascript
复制
在 [ 10 ]:wiki_obama = “”“巴拉克奥巴马是一位美国政治家,曾担任过

您可以看到模型已识别的实体以及它们的准确程度(在本例中)。 PERSON 不言自明, NORP 是民族或宗教团体,GPE识别位置(城市,国家等), DATE 识别特定日期或日期范围,ORDINAL 识别代表某种类型的订单的单词或数字。

虽然我们讨论Doc方法的主题,但值得一提的是spaCy的句子标识符。NLP任务想要将文档拆分成句子并不罕见。通过访问Doc's.sents方法,使用SpaCy执行此操作非常简单:

代码语言:javascript
复制
In[11]: for ix, sent in enumerate(nlp_obama.sents, 1):
...:       print("Sentence number {}: {}".format(ix, sent))
...:
Sentence number 1: Barack Obama is an American politician who served as
the 44th President of the United States from 2009 to 2017.
Sentence number 2: He is the first
African American to have served as president,
as well as the first born outside the contiguous United States.

就是这些了。在后面的文章中,我将展示如何在复杂的数据挖掘和ML任务中使用spaCy。

原文标题《NLP in Python》

作者:Jayesh Bapu Ahire

译者:February

不代表云加社区观点,更多详情请查看原文链接

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • spaCy是什么?
  • 那么,它能做什么?
  • 让我们开始吧!
  • 标记化
  • 词形还原
  • POS标记
  • 实体识别
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档