【问题标题】:Remove a list of stopwords from a Counter in python从python中的计数器中删除停用词列表
【发布时间】:2013-12-21 20:15:58
【问题描述】:

我在 NLTK 中有一个函数可以生成一个索引列表,它看起来像

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

我还有另一个函数,它返回一个计数器字典,其中包含 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 时遇到了麻烦,因为如果我想包含像“and”这样的保留字,我会收到一个无效的语法错误。计数器具有易于使用的联合和交集方法,这将使任务相当简单;字典有等效的方法吗?

【问题讨论】:

  • RE:您对无效语法错误的编辑。 and 是保留的,但 "and" 是一个字符串。您应该使用Counter(["and"]) 创建一个带有字符串"and" 的计数器。

标签: python dictionary counter nltk


【解决方案1】:

您可以在标记化过程中删除停用词...

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

【讨论】:

    【解决方案2】:

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

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

    改为。

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

    for sword in stopwords:
        del yourCounter[sword]
    

    sword 是否在 Counter 中无关紧要 - 无论如何这都不会引发异常。

    【讨论】:

      【解决方案3】:

      我会将项目扁平化为单词,忽略任何停用词并将其作为输入提供给单个 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))
      

      【讨论】:

        【解决方案4】:

        怎么样:

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

        【讨论】:

        • 这可行,但停用词列表将有 100 个左右的字长,因此我无法为要删除/忽略的每个单词输入条件。不过谢谢。
        【解决方案5】:

        你有几个选择。

        第一,更新 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 中实际删除。

        我还在split 之前添加了line 上的strip 调用。如果您要使用 split() 和在所有空格上拆分的默认行为,您将不需要它,但 split(' ') 不会认为换行符是要拆分的东西,因此每行的最后一个单词会有一个尾随\n 并且将被认为与任何其他外观不同。 strip 摆脱了它。

        【讨论】:

        • 太棒了,来自 Javascript,所以我不知道空的 split() 会这么有用...
        【解决方案6】:

        就个人而言,我认为@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))
        

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

        【讨论】:

          猜你喜欢
          • 2019-09-10
          • 1970-01-01
          • 2018-09-28
          • 2021-02-02
          • 2020-05-04
          • 2021-12-22
          • 2019-12-18
          • 2021-04-23
          • 2016-09-25
          相关资源
          最近更新 更多