从python中的Counter中删除一个停用词列表

时间:2013-12-21 20:15:59

标签: python dictionary counter nltk

我在NLTK中有一个函数来生成一个一致的列表,看起来像

concordanceList = ["this is a concordance string something", 
               "this is another concordance string blah"] 

我有另一个函数返回一个Counter字典,其中包含concordanceList

中每个单词的计数
def mostCommonWords(concordanceList):
  finalCount = Counter()
  for line in concordanceList:
    words = line.split(" ")
    currentCount = Counter(words)
    finalCount.update(currentCount)
  return finalCount

我遇到的问题是如何最好地从结果计数器中删除停用词,这样,当我打电话

mostCommonWords(concordanceList).most_common(10)

结果不只是{“the”:100,“is”:78,“that”:57}。

我认为预处理文本以删除停用词是不合适的,因为我仍然需要将索引字符串作为语法语言的实例。基本上,我问是否有一种更简单的方法来做到这一点,而不是为停用词创建一个停用词计数器,将值设置为低,然后再制作另一个计数器:

stopWordCounter = Counter(the=1, that=1, so=1, and=1)
processedWordCounter = mostCommonWords(concordanceList) & stopWordCounter

应该将所有停用词的计数值设置为1,但它看起来很黑。

编辑:另外,我实际上在制作这样的stopWordCounter时遇到了麻烦,因为如果我想要包含像“和”这样的保留字,我会收到无效的语法错误。计数器具有易于使用的联合和交集方法,这将使任务相当简单;是否有相同的词典方法?

6 个答案:

答案 0 :(得分:2)

您可以在标记化期间删除停用词......

stop_words = frozenset(['the', 'a', 'is'])
def mostCommonWords(concordanceList):
    finalCount = Counter()
    for line in concordanceList:
        words = [w for w in line.split(" ") if w not in stop_words]
        finalCount.update(words)  # update final count using the words list
    return finalCount

答案 1 :(得分:1)

首先,您不需要在函数内创建所有新的Counter;你可以这样做:

for line in concordanceList:
    finalCount.update(line.split(" "))

代替。

其次,Counter是一种字典,因此您可以直接删除项目:

for sword in stopwords:
    del yourCounter[sword]

sword中是否Counter并不重要 - 无论如何都不会引发异常。

答案 2 :(得分:1)

我会把项目拼成单词,忽略任何停用单词,并将其作为输入提供给单个Counter

from collections import Counter
from itertools import chain

lines = [
    "this is a concordance string something", 
    "this is another concordance string blah"
]

stops = {'this', 'that', 'a', 'is'}    
words = chain.from_iterable(line.split() for line in lines)
count = Counter(word for word in words if word not in stops)

或者,最后一位可以完成:

from itertools import ifilterfalse
count = Counter(ifilterfalse(stops.__contains__, words))

答案 3 :(得分:0)

你有几个选择。

其一,在更新Counter时不要计算停用词 - 您可以更简洁地做,因为Counter对象可以接受迭代以及update的另一个映射:

def mostCommonWords(concordanceList):
    finalCount = Counter()
    stopwords = frozenset(['the', 'that', 'so'])
    for line in concordanceList:
        words = line.strip().split(' ')
        finalCount.update([word for word in words if word not in stopwords])
    return finalCount

或者,您可以使用del在完成后将其从Counter中删除。

我还在strip之前在line上添加了split来电。如果您使用split()以及在所有空格上拆分的默认行为,则不需要这样做,但split(' ')不会将换行视为要拆分的内容,因此每个空格的最后一个单词line将具有尾随\n并且将被视为与任何其他外观不同。 strip摆脱了这一点。

答案 4 :(得分:0)

怎么样:

if 'the' in counter:
    del counter['the']

答案 5 :(得分:0)

就个人而言,我认为@JonClements的回答是最优雅的。顺便说一句,NLTK中已经有stopwords的列表,以防万一OP不知道,请参阅NLTK stopword removal issue

from collections import Counter
from itertools import chain
from nltk.corpus import stopwords

lines = [
    "this is a concordance string something", 
    "this is another concordance string blah"
]

stops = stopwords.words('english')
words = chain.from_iterable(line.split() for line in lines)
count = Counter(word for word in words if word not in stops)
count = Counter(ifilterfalse(stops.__contains__, words))

此外,与FreqDist相比,NLTK中的collections.Counter模块具有更多与NLP相关的功能。 http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability.FreqDist-class.html