使用 nltk 从文本文件中提取所有名词

Extracting all Nouns from a text file using nltk

有没有更有效的方法? 我的代码读取一个文本文件并提取所有名词。

import nltk

File = open(fileName) #open file
lines = File.read() #read all lines
sentences = nltk.sent_tokenize(lines) #tokenize sentences
nouns = [] #empty to array to hold all nouns

for sentence in sentences:
     for word,pos in nltk.pos_tag(nltk.word_tokenize(str(sentence))):
         if (pos == 'NN' or pos == 'NNP' or pos == 'NNS' or pos == 'NNPS'):
             nouns.append(word)

如何降低这段代码的时间复杂度?有没有办法避免使用嵌套的 for 循环?

提前致谢!

我不是 NLP 专家,但我认为您已经很接近了,并且在这些外部循环中可能没有比二次时间复杂度更好的方法了。

NLTK 的最新版本有一个内置函数,可以手动完成您正在做的事情,nltk.tag.pos_tag_sents,它 returns 也是一个标记词列表。

import nltk

lines = 'lines is some string of words'
# function to test if something is a noun
is_noun = lambda pos: pos[:2] == 'NN'
# do the nlp stuff
tokenized = nltk.word_tokenize(lines)
nouns = [word for (word, pos) in nltk.pos_tag(tokenized) if is_noun(pos)] 

print nouns
>>> ['lines', 'string', 'words']

有用的提示:在 'for' 循环中,列表推导通常是一种比使用 .insert() 或 append() 方法向列表添加元素更快的构建列表的方法.

如果您对 NLTK 以外的选项持开放态度,请查看 TextBlob。它可以轻松提取所有名词和名词短语:

>>> from textblob import TextBlob
>>> txt = """Natural language processing (NLP) is a field of computer science, artificial intelligence, and computational linguistics concerned with the inter
actions between computers and human (natural) languages."""
>>> blob = TextBlob(txt)
>>> print(blob.noun_phrases)
[u'natural language processing', 'nlp', u'computer science', u'artificial intelligence', u'computational linguistics']

您的代码没有冗余:您读取文件一次并访问每个句子和每个标记词,恰好一次。无论您如何编写代码(例如,使用理解),您都只会隐藏嵌套循环,而不会跳过任何处理。

唯一的改进潜力在于它的 space 复杂性:您可以逐步读取它,而不是一次读取整个文件。但是由于您需要一次处理一个完整的句子,所以它不像一次阅读和处理一行那么简单;所以我不会打扰,除非你的文件是整个千兆字节长;对于短文件,它不会产生任何影响。

简而言之,你的循环没问题。您的代码中有一两件事可以清理(例如 if 与 POS 标签匹配的子句),但它不会改变任何效率方面的事情。

您可以使用 nltkTextblobSpaCy 或其他许多库中的任何一个来获得良好的结果。这些库都可以完成这项工作,但效率不同。

import nltk
from textblob import TextBlob
import spacy
nlp = spacy.load('en')
nlp1 = spacy.load('en_core_web_lg')

txt = """Natural language processing (NLP) is a field of computer science, artificial intelligence, and computational linguistics concerned with the interactions between computers and human (natural) languages."""

在我的 windows 10 2 核,4 处理器,8GB 内存 i5 hp 笔记本电脑上,在 jupyter 笔记本中,我 运行 进行了一些比较,这里是结果。

对于 TextBlob:

%%time
print([w for (w, pos) in TextBlob(txt).pos_tags if pos[0] == 'N'])

输出为

>>> ['language', 'processing', 'NLP', 'field', 'computer', 'science', 'intelligence', 'linguistics', 'inter', 'actions', 'computers', 'languages']
    Wall time: 8.01 ms #average over 20 iterations

对于 nltk:

%%time
print([word for (word, pos) in nltk.pos_tag(nltk.word_tokenize(txt)) if pos[0] == 'N'])

输出为

>>> ['language', 'processing', 'NLP', 'field', 'computer', 'science', 'intelligence', 'linguistics', 'inter', 'actions', 'computers', 'languages']
    Wall time: 7.09 ms #average over 20 iterations

对于spacy:

%%time
print([ent.text for ent in nlp(txt) if ent.pos_ == 'NOUN'])

输出为

>>> ['language', 'processing', 'field', 'computer', 'science', 'intelligence', 'linguistics', 'inter', 'actions', 'computers', 'languages']
    Wall time: 30.19 ms #average over 20 iterations

似乎 nltkTextBlob 相当快,这是可以预料的,因为没有存储关于输入文本的其他内容,txt。 Spacy 要慢得多。还有一件事。 SpaCy 错过了名词 NLPnltkTextBlob 得到了。我会拍摄 nltkTextBlob 除非我想从输入 txt.

中提取其他内容


查看 spacy here 的快速入门。
查看一些关于 TextBlob here.
Check out nltk HowTos here

的基础知识
import nltk
lines = 'lines is some string of words'
tokenized = nltk.word_tokenize(lines)
nouns = [word for (word, pos) in nltk.pos_tag(tokenized) if(pos[:2] == 'NN')]
print (nouns)

再简单一点。