引言

在​​nltk的介绍文章​​中,前面几篇主要介绍了nltk自带的数据(书籍和语料),感觉系统学习意义不大,用到哪里看到那里就行(笑),所以这里会从一些常用功能开始,适当略过对于数据本体的介绍。

文本处理


词频提取

把切分好的词表进行词频排序(按照出现次数排序),

​​all_words ​​         ​​=​​          ​​nltk.FreqDist(w.lower() ​​         ​​for​​          ​​w ​​         ​​in​​          ​​nltk.word_tokenize(​​         ​​"I'm foolish foolish man"​​         ​​))​​        

​​print​​ ​​(all_words.keys())​​

​​all_words.plot()​​

dict_keys(["'m", 'man', 'i', 'foolish'])

nlp---Nltk 常用方法_词性标注

只考虑最高频率的两个词,并且绘制累积图,

​​all_words.plot(​​         ​​2​​         ​​, cumulative​​         ​​=​​         ​​True​​         ​​)​​

nlp---Nltk 常用方法_词性标注_02


英文词干提取器

​​import​​          ​​nltk​​        

​​porter ​​ ​​=​​ ​​nltk.PorterStemmer()​​

​​porter.stem(​​ ​​'lying'​​ ​​)​​

'lie'


英文分词

​​text ​​         ​​=​​          ​​nltk.word_tokenize(​​         ​​"And now for something completely different"​​         ​​)​​        

​​print​​ ​​(text)​​

['And', 'now', 'for', 'something', 'completely', 'different']

分词&词形还原&词根还原使用概览

​​import​​          ​​nltk​​        



​​sent ​​ ​​=​​ ​​"I'm super lying man"​​



​​'''​​

​​分词​​

​​'''​​

​​print​​ ​​(nltk.word_tokenize(sent))​​

​​print​​ ​​(nltk.tokenize.word_tokenize(sent))​​





​​'''​​

​​词根还原​​

​​'''​​

​​porter ​​ ​​=​​ ​​nltk.PorterStemmer()​​

​​print​​ ​​([porter.stem(x) ​​ ​​for​​ ​​x ​​ ​​in​​ ​​nltk.word_tokenize(sent)])​​





​​'''​​

​​词形还原(lemmatizer),即把一个任何形式的英语单词还原到一般形式,与词根还原不同(stemmer),​​

​​后者是抽取一个单词的词根。​​

​​'''​​

​​porter2 ​​ ​​=​​ ​​nltk.stem.WordNetLemmatizer()​​

​​print​​ ​​([porter2.lemmatize(x) ​​ ​​for​​ ​​x ​​ ​​in​​ ​​nltk.word_tokenize(sent)])​​

​​『TensorFlow』测试项目_对评论分类​​

词性标注

​​print​​         ​​(nltk.pos_tag(text))​​        

​​print​​ ​​(nltk.pos_tag([​​ ​​'i'​​ ​​,​​ ​​'love'​​ ​​,​​ ​​'you'​​ ​​]))​​

​​print​​ ​​( nltk.pos_tag([​​ ​​'love'​​ ​​,​​ ​​'and'​​ ​​,​​ ​​'hate'​​ ​​]))​​

[('And', 'CC'), ('now', 'RB'), ('for', 'IN'), ('something', 'NN'), ('completely', 'RB'), ('different', 'JJ')]
[('i', 'NN'), ('love', 'VBP'), ('you', 'PRP')]
[('love', 'NN'), ('and', 'CC'), ('hate', 'NN')]

厉害的地方在这里:第二局里面的love是动词,第三句里面的love是名词。

词性标注语料制作

​​tagged_token ​​         ​​=​​          ​​nltk.tag.str2tuple(​​         ​​'fly/NN'​​         ​​)​​        

​​print​​ ​​(tagged_token)​​

('fly', 'NN')

中文的也行,

​​sent ​​         ​​=​​          ​​'我/NN 是/IN 一个/AT 大/JJ 傻×/NN'​​        

​​[nltk.tag.str2tuple(t) ​​ ​​for​​ ​​t ​​ ​​in​​ ​​sent.split()] ​​ ​​# 中文语料词性标注(&分词)​​

[('我', 'NN'), ('是', 'IN'), ('一个', 'AT'), ('大', 'JJ'), ('傻×', 'NN')]

词性标注器

默认标注器:

不管什么词,都标注为频率最高的一种词性。比如经过分析,所有中文语料里的词是名次的概率是13%最大,那么我们的默认标注器就全部标注为名次。这种标注器一般作为其他标注器处理之后的最后一道门,即:不知道是什么词?那么他是名词。

​​raw ​​         ​​=​​          ​​'我 累 嗯个 e去?'​​        



​​tokens ​​ ​​=​​ ​​nltk.word_tokenize(raw)​​



​​default_tagger ​​ ​​=​​ ​​nltk.DefaultTagger(​​ ​​'NN'​​ ​​)​​

​​tags ​​ ​​=​​ ​​default_tagger.tag(tokens)​​



​​print​​ ​​(tokens)​​

​​print​​ ​​(tags)​​

['我', '累', '嗯个', 'e去', '?']

[('我', 'NN'), ('累', 'NN'), ('嗯个', 'NN'), ('e去', 'NN'), ('?', 'NN')]

正则表达式标注器:

满足特定正则表达式的认为是某种词性,比如凡是带“们”的都认为是代词(PRO)。

​​pattern ​​         ​​=​​          ​​[(​​         ​​'.*们$'​​         ​​,​​         ​​'PRO'​​         ​​)]​​        



​​tagger ​​ ​​=​​ ​​nltk.RegexpTagger(pattern)​​



​​print​​ ​​(tagger.tag(nltk.word_tokenize(​​ ​​'我们 累 个 去 你们 和 他们 啊'​​ ​​)))​​

[('我们', 'PRO'), ('累', None), ('个', None), ('去', None), ('你们', 'PRO'), ('和', None), ('他们', 'PRO'), ('啊', None)]

查询标注器:

找出最频繁的n个词以及它的词性,然后用这个信息去查找语料库,匹配的就标记上,剩余的词使用默认标注器(回退)。这一般使用一元标注的方式,见下面。

一元标注:基于已经标注的语料库做训练,然后用训练好的模型来标注新的语料。

​​sents ​​         ​​=​​          ​​[[u​​         ​​'我'​​         ​​, u​​         ​​'你'​​         ​​, u​​         ​​'小兔'​​         ​​]]​​        



​​tagged_sents ​​ ​​=​​ ​​[[(u​​ ​​'我'​​ ​​, u​​ ​​'PRO'​​ ​​), (u​​ ​​'小兔'​​ ​​, u​​ ​​'NN'​​ ​​)]]​​

​​unigram_tagger ​​ ​​=​​ ​​nltk.UnigramTagger(tagged_sents)​​

​​tags ​​ ​​=​​ ​​unigram_tagger.tag(sents[​​ ​​0​​ ​​])​​



​​print​​ ​​(tags)​​

[('我', 'PRO'), ('你', None), ('小兔', 'NN')]

二元标注和多元标注:一元标注指的是只考虑当前这个词,不考虑上下文,二元标注器指的是考虑它前面的词的标注,用法只需要把上面的UnigramTagger换成BigramTagger,同理三元标注换成TrigramTagger(并未有示例)。

组合标注器:

为了提高精度和覆盖率,我们对多种标注器组合,比如组合二元标注器、一元标注器和默认标注器,如下,

​​t0 ​​         ​​=​​          ​​nltk.DefaultTagger(​​         ​​'NN'​​         ​​)​​        

​​t1 ​​ ​​=​​ ​​nltk.UnigramTagger(train_sents, backoff​​ ​​=​​ ​​t0) ​​

​​t2 ​​ ​​=​​ ​​nltk.BigramTagger(train_sents, backoff​​ ​​=​​ ​​t1)​​

直接调用t2即可。

持久化&较为完整的训练一个标注器:

​​sent ​​         ​​=​​          ​​'我/NN 是/IN 一个/AT 好的/JJ 人/NN'​​        

​​train_sents ​​ ​​=​​ ​​[[nltk.tag.str2tuple(t) ​​ ​​for​​ ​​t ​​ ​​in​​ ​​sent.split()]]​​



​​t0 ​​ ​​=​​ ​​nltk.DefaultTagger(​​ ​​'NN'​​ ​​)​​

​​t1 ​​ ​​=​​ ​​nltk.UnigramTagger(train_sents, backoff​​ ​​=​​ ​​t0) ​​

​​t2 ​​ ​​=​​ ​​nltk.BigramTagger(train_sents, backoff​​ ​​=​​ ​​t1) ​​



​​from​​ ​​pickle ​​ ​​import​​ ​​dump​​

​​output ​​ ​​=​​ ​​open​​ ​​(​​ ​​'t2.pkl'​​ ​​, ​​ ​​'wb'​​ ​​)​​

​​dump(t2, output, ​​ ​​-​​ ​​1​​ ​​)​​

​​output.close()  ​​

加载在这里,

​​from​​          ​​pickle ​​         ​​import​​          ​​load ​​        

​​input​​ ​​=​​ ​​open​​ ​​(​​ ​​'t2.pkl'​​ ​​, ​​ ​​'rb'​​ ​​) ​​

​​tagger ​​ ​​=​​ ​​load(​​ ​​input​​ ​​) ​​

​​input​​ ​​.close()​​