【问题标题】:How can I add items to collection.Counter? and then sort them into ASC?如何将项目添加到 collection.Counter?然后将它们分类到 ASC 中?
【发布时间】:2012-09-26 04:48:50
【问题描述】:

目前我正在尝试通过计算 600 个文件(400 封电子邮件和 200 封垃圾邮件)中单词的出现来处理 lingspam dataset。我已经用Porter Stemmer Aglorithm 使每个单词都通用了,我还希望我的结果在每个文件中都标准化,以便进一步处理。但我不确定如何才能做到这一点..

迄今为止的资源

为了获得下面的输出,我需要能够按升序添加文件中可能不存在的项目。

printing from ./../lingspam_results/spmsgb164.txt.out
[('money', 0, 'univers', 0,  'sales', 0)]
printing from ./../lingspam_results/spmsgb166.txt.out
[('money', 2, 'univers', 0,  'sales', 0)]
printing from ./../lingspam_results/spmsgb167.txt.out
[('money', 0, 'univers', 0,  'sales', 1)]

然后我计划使用numpy 转换为vectors

[0,0,0]
[2,0,0]
[0,0,0]

而不是..

printing from ./../lingspam_results/spmsgb165.txt.out
[]
printing from ./../lingspam_results/spmsgb166.txt.out
[('univers', 2)]
printing from ./../lingspam_results/spmsgb167.txt.out
[('sale', 1)]

如何将Counter 模块中的结果标准化为Ascending Order(同时将我的search_list 中可能不存在的项目添加到计数器结果中)?我已经在下面尝试了一些东西,它只是从每个文本文件中读取并根据search_list 创建一个列表。

import numpy as np, os
from collections import Counter

def parse_bag(directory, search_list):
    words = []
    for (dirpath, dirnames, filenames) in os.walk(directory):
        for f in filenames:
            path = directory + "/" + f
            count_words(path, search_list)
    return;

def count_words(filename, search_list):
    textwords = open(filename, 'r').read().split()
    filteredwords = [t for t in textwords if t in search_list]
    wordfreq = Counter(filteredwords).most_common(5)
    print "printing from " + filename
    print wordfreq

search_list = ['sale', 'univers', 'money']
parse_bag("./../lingspam_results", search_list)

谢谢

【问题讨论】:

  • “按升序”到底是什么意思?你不是在谈论search_list 单词的字母顺序,是吗?
  • 或者您希望每个文件的项目按它们在所有文件中的总体频率排序?
  • 我说的是wordfreq = Counter(filteredwords).most_common(5)ascending order 中的结果,而不是哪个单词出现次数最多的顺序。
  • 您想对整个(count, word) 值进行升序排序吗?我看不到您上面的第一个示例是如何按升序排列的。另外,它们都在一个大元组中是错字吗?我看不出您的代码如何产生该输出。
  • 是的,我注意到我自己在我的例子中,我已经编辑了它。而且我的代码无法产生该输出,这几乎就是我要问的原因,因为我想知道该输出是否可能。问候

标签: python collections preprocessor normalization spam-prevention


【解决方案1】:

根据您的问题,听起来您的要求是您希望所有文件中的相同单词具有一致的顺序,并带有计数。这应该为你做:

def count_words(filename, search_list):
    textwords = open(filename, 'r').read().split()
    filteredwords = [t for t in textwords if t in search_list]
    counter = Counter(filteredwords)
    for w in search_list:
        counter[w] += 0        # ensure exists
    wordfreq = sorted(counter.items())
    print "printing from " + filename
    print wordfreq

search_list = ['sale', 'univers', 'money']

样本输出:

printing from ./../lingspam_results/spmsgb164.txt.out
[('money', 0), ('sale', 0), ('univers', 0)]
printing from ./../lingspam_results/spmsgb166.txt.out
[('money', 2), ('sale', 0), ('univers', 0)]
printing from ./../lingspam_results/spmsgb167.txt.out
[('money', 0), ('sale', 1), ('univers', 0)]

我认为您根本不想使用 most_common,因为您特别不希望每个文件的内容影响排序或列表长度。

【讨论】:

  • 非常感谢! :) 你的答案与 jsbueno 的结合正是我想要的 :)
  • 我想我仍然对您的要求感到困惑,但很高兴我们能提供帮助!使用 jsbueno 的答案中的排序方法,我得到了 [u:0, s:0, m:0][m:2, u:0, s:0][s:1, u:0, m:0],我不知道如何将它们转换为标准化的矢量格式。
  • 例如,我添加了一个关于我如何进入[4,0,0] 的答案。再次感谢
【解决方案2】:

您在示例中使用的调用 Counter(filteredwords) 可以计算所有单词,就像您想要的那样 - 它不会给您最常用的单词 - 即,没有“most_common”方法 - 为此,您必须重新处理计数器中的所有项目,以获得包含(频率,单词)的元组序列,并对其进行排序:

def most_common(counter, n=5):
     freq = sorted (((value ,item) for item, value in counter.viewitems() ), reverse=True)
     return [item[1] for item in freq[:n]]

【讨论】:

  • 嗯?你是说这不对吗?:Counter.most_common
  • 谢谢 :) 它工作得很好,根据我想要的信息进行了一些调整。但它是一个开始。如何从filteredwordsCounter(x) 的结果添加项目(如果filterwords 仅包含来自search_list 的0、1 或2 个单词)?
【解决方案3】:

jsbueno 和 Mu Mind 的结合

def count_words_SO(filename, search_list):
    textwords = open(filename, 'r').read().split()
    filteredwords = [t for t in textwords if t in search_list]
    counter = Counter(filteredwords)
    for w in search_list:
        counter[w] += 0        # ensure exists
    wordfreq = number_parse(counter)
    print "printing from " + filename
    print wordfreq

def number_parse(counter, n=5):
     freq = sorted (((value ,item) for item, value in counter.viewitems() ),    reverse=True)
     return [item[0] for item in freq[:n]]

出来了,只需多做一点工作,我就可以准备好Neurel Network 谢谢大家:)

printing from ./../lingspam_results/spmsgb19.txt.out
[0, 0, 0]
printing from ./../lingspam_results/spmsgb2.txt.out
[4, 0, 0]
printing from ./../lingspam_results/spmsgb20.txt.out
[10, 0, 0]

【讨论】:

  • 所以你不希望你的神经网络为每个单词都有一个专用的输入?即,您希望一个包含 100 个“univers”、2 个“money”、0 个“sale”的文件完全等同于一个包含 100 个“money”、2 个“sale”、0 个“univers”的文件?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 2011-09-03
相关资源
最近更新 更多