NLTK包的常用总结

NLTK

NLTK的全称是natural language toolkit,是一套基于python的自然语言处理工具集。
NLTK是Python很强大的第三方库,可以很方便的完成很多自然语言处理(NLP)的任务,包括分词、词性标注、命名实体识别(NER)及句法分析。

NLTK的安装

nltk的安装十分便捷,只需要pip就可以。

pip install nltk

在nltk中集成了语料与模型等的包管理器,通过在python解释器中执行

import nltk
nltk.download()

from nltk.corpus import brown
brown.words()
['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...]

一、NLTK进行分词

nltk.sent_tokenize(text) #对文本按照句子进行分割
nltk.word_tokenize(sent) #对句子进行分词

在这里插入图片描述
假设我们有如下的示例文本:

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']

从 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进行词性标注

用到的函数:
nltk.pos_tag(tokens)#tokens是句子分词后的结果,同样是句子级的标注
在这里插入图片描述

三、NLTK进行命名实体识别(NER)

用到的函数:
nltk.ne_chunk(tags)#tags是句子词性标注后的结果,同样是句子级
在这里插入图片描述
上例中,有两个命名实体,一个是Xi,这个应该是PER,被错误识别为GPE了; 另一个事China,被正确识别为GPE。

四、句法分析

nltk没有好的parser,推荐使用stanfordparser
但是nltk有很好的树类,该类用list实现
可以利用stanfordparser的输出构建一棵python的句法树
在这里插入图片描述

五、词干提取(stemming)

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

词干提取的算法有很多,但最常用的算法是 Porter 提取算法。NLTK 有一个 PorterStemmer 类,使用的就是 Porter 提取算法。
解释一下,Stemming 是抽取词的词干或词根形式(不一定能够表达完整语义)。NLTK中提供了三种最常用的词干提取器接口,即 Porter stemmer, Lancaster Stemmer 和 Snowball Stemmer。
Porter Stemmer基于Porter词干提取算法,来看例子:

    >>> from nltk.stem.porter import PorterStemmer  
    >>> porter_stemmer = PorterStemmer()  
    >>> porter_stemmer.stem(‘maximum’)  
    u’maximum’  
    >>> porter_stemmer.stem(‘presumably’)  
    u’presum’  
    >>> porter_stemmer.stem(‘multiply’)  
    u’multipli’  
    >>> porter_stemmer.stem(‘provision’)  
    u’provis’  
    >>> porter_stemmer.stem(‘owed’)  
    u’owe’  

Lancaster Stemmer 基于Lancaster 词干提取算法,来看例子

    >>> from nltk.stem.lancaster import LancasterStemmer  
    >>> lancaster_stemmer = LancasterStemmer()  
    >>> lancaster_stemmer.stem(‘maximum’)  
    ‘maxim’  
    >>> lancaster_stemmer.stem(‘presumably’)  
    ‘presum’  
    >>> lancaster_stemmer.stem(‘presumably’)  
    ‘presum’  
    >>> lancaster_stemmer.stem(‘multiply’)  
    ‘multiply’  
    >>> lancaster_stemmer.stem(‘provision’)  
    u’provid’  
    >>> lancaster_stemmer.stem(‘owed’)  
    ‘ow’  

Snowball Stemmer基于Snowball 词干提取算法,来看例子

    >>> from nltk.stem import SnowballStemmer  
    >>> snowball_stemmer = SnowballStemmer(“english”)  
    >>> snowball_stemmer.stem(‘maximum’)  
    u’maximum’  
    >>> snowball_stemmer.stem(‘presumably’)  
    u’presum’  
    >>> snowball_stemmer.stem(‘multiply’)  
    u’multipli’  
    >>> snowball_stemmer.stem(‘provision’)  
    u’provis’  
    >>> snowball_stemmer.stem(‘owed’)  
    u’owe’  

使用 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

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

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

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值