使用NLTK删除停用词

Gra*_*kar 71 python nlp nltk stop-words

我试图通过使用nltk工具包删除停用词来处理用户输入的文本,但是使用停用词删除时,会删除"and","或","not"等字样.我希望在禁用词删除过程之后出现这些单词,因为它们是稍后将文本作为查询处理所需的运算符.我不知道哪些是文本查询中可以成为运算符的单词,我还想从文本中删除不必要的单词.

alv*_*vas 140

有一个内置的禁用NLTK词汇表,由11种语言的2,400个停用词组成(Porter等),请参阅http://nltk.org/book/ch02.html

>>> from nltk import word_tokenize
>>> from nltk.corpus import stopwords
>>> stop = set(stopwords.words('english'))
>>> sentence = "this is a foo bar sentence"
>>> print([i for i in sentence.lower().split() if i not in stop])
['foo', 'bar', 'sentence']
>>> [i for i in word_tokenize(sentence.lower()) if i not in stop] 
['foo', 'bar', 'sentence']
Run Code Online (Sandbox Code Playgroud)

我建议使用tf-idf来删除停用词,请参阅词干对术语频率的影响?

  • 顺便说一句,使用stop作为`list`可能会很慢.我建议将它转换为`set`,以便`not in`会便宜得多. (4认同)
  • @alves我已经将上述方法用于我的任务.我只是想知道哪些可能是来自停用词列表的操作符. (2认同)
  • "理想"的禁用词列表取决于任务的性质.所以你必须问问自己,你的任务的最终目标是什么?然后问语言学家过滤什么来实现我的目标.否则你也可以坚持使用统计方法,例如tf-idf filter. (2认同)

otu*_*tus 69

我建议你创建自己的操作词单列表,你从禁用词列表中取出.可以方便地减去集合,因此:

operators = set(('and', 'or', 'not'))
stop = set(stopwords...) - operators
Run Code Online (Sandbox Code Playgroud)

然后,你可以简单地测试一个字innot in一组不依赖于你的运营商是否停止字列表的一部分.然后,您可以稍后切换到另一个禁用词列表或添加运算符.

if word.lower() not in stop:
    # use word
Run Code Online (Sandbox Code Playgroud)


Sal*_*ali 32

@ alvas的答案可以完成这项任务,但可以更快地完成.假设你有documents:一个字符串列表.

from nltk.corpus import stopwords
from nltk.tokenize import wordpunct_tokenize

stop_words = set(stopwords.words('english'))
stop_words.update(['.', ',', '"', "'", '?', '!', ':', ';', '(', ')', '[', ']', '{', '}']) # remove it if you need punctuation 

for doc in documents:
    list_of_words = [i.lower() for i in wordpunct_tokenize(doc) if i.lower() not in stop_words]
Run Code Online (Sandbox Code Playgroud)

请注意,由于这里您正在搜索集合(不在列表中),因此理论上速度 len(stop_words)/2快一些,如果您需要通过许多文档操作,则.

对于5000个大约300个单词的文档,我的例子为1.8秒,@ alvas为20秒.

PS在大多数情况下,您需要将文本划分为单词以执行其他使用tf-idf的分类任务.所以最有可能的是使用stemmer也会更好:

from nltk.stem.porter import PorterStemmer
porter = PorterStemmer()
Run Code Online (Sandbox Code Playgroud)

[porter.stem(i.lower()) for i in wordpunct_tokenize(doc) if i.lower() not in stop_words]在循环内部使用.


Aam*_*nan 14

@alvas有一个很好的答案.但同样取决于任务的性质,例如在你的应用程序中你想要考虑所有conjunction例如和,或者,但是,是否,同时和所有determiner例如a,a,some,most,every,no考虑所有的停止词其他词性是合法的,那么你可能想看看这个使用词性标注集来丢弃单词的解决方案,检查表5.1:

import nltk

STOP_TYPES = ['DET', 'CNJ']

text = "some data here "
tokens = nltk.pos_tag(nltk.word_tokenize(text))
good_words = [w for w, wtype in tokens if wtype not in STOP_TYPES]
Run Code Online (Sandbox Code Playgroud)


Usm*_*anZ 6

您可以将string.punctuation与内置的NLTK停用词列表结合使用:

from nltk.tokenize import word_tokenize, sent_tokenize
from nltk.corpus import stopwords
from string import punctuation

words = tokenize(text)
wordsWOStopwords = removeStopWords(words)

def tokenize(text):
        sents = sent_tokenize(text)
        return [word_tokenize(sent) for sent in sents]

def removeStopWords(words):
        customStopWords = set(stopwords.words('english')+list(punctuation))
        return [word for word in words if word not in customStopWords]
Run Code Online (Sandbox Code Playgroud)

NLTK停用词完整列表