统计n元组的频率

4

我使用这个Python脚本,将文本拆分成连续的单词:

from nltk.util import ngrams

sentence = open('text.txt', "r")
n = 2
sixgrams = ngrams(sentence.read().split(), n)

for grams in sixgrams:
      print (grams)

现在我面临以下两个问题。
1. 我的结果看起来像这样:
('\xd1\x8e\xd0\xbc', '\xd0\xb1\xd0\xb0\xd0\xb9\xd0\xb3\xd0\xb0\xd0\xb0\xd0\xbd')

可能是因为text.txt文件包含俄语西里尔字符且编码为UTF-8。有没有一种方法在Python中以人类可读的格式查看我的结果?

2. 我试图使用Collections.Counter获取每个后续单词组合的频率计数,并打印出出现超过2次的所有ngram(按值排序)。我试了几个小时,无法使它按我想要的方式显示。

输入示例:

Diddle  diddle  dumpling  my son Diddle  diddle my son

输出示例:
Diddle diddle  2
diddle dumpling 2
dumpling my 1
my son 2
son Diddle 1
Diddle my 1
my son 1

输出示例,限制为2个:

Diddle diddle  2
diddle dumpling 2
my son 2

你正在使用Python 2.7吗? - Saleem
最好使用Python 3来处理自然语言处理任务,因为Python 3具有更强大的文本处理能力。:/ - Antti Haapala -- Слава Україні
在Python 3中,你已经看到了юм байгаан - Antti Haapala -- Слава Україні
我正在使用Enthought Canopy,但是由于数据量过大,Canopy出现了故障。 - Cameroon P
  1. --> 将输出写入一个文件(utf-8格式),并使用能够良好处理utf-8的编辑器打开该文件。
  2. --> 请查看我对你其他问题的完整回答将Python中的打印输出重定向到.txt文件
- return42
至少需要: Python 2和Python 3。字符串处理完全不同(打印命令也是如此)!如果你是Python的新手,应该使用Python 3,它的字符串处理对新手来说更容易一些。 - return42
1个回答

3
对于你问题的第一部分,据我所见,你正在读取一个以UTF-8编码的文件。你可以在结果数据上调用decode('utf8')来解码它。为了打印结果,假设你的终端可以处理它,再次使用encode('utf8')将其转换为可读字符串。
至于你问题的第二部分,我已经扩展了你的代码并包含了一个Counter
from nltk.util import ngrams
import collections

with open("text.txt", "rU") as f:
    sixgrams = ngrams(f.read().decode('utf8').split(), 2)

result = collections.Counter(sixgrams)
print result
with open("output.txt", "w") as f:
    for item, count in sorted(result.iteritems()):
        if count >= 2:
            text = "{} {}".format(" ".join(item).encode('utf8'), count)
            print text
            print >>f, text

对于您的示例文本文件,输出结果如下:
Counter({('Diddle', 'diddle'): 2, ('my', 'son'): 2, ('dumpling', 'my'): 1, ('son', 'Diddle'): 1, ('diddle', 'dumpling'): 1, ('diddle', 'my'): 1})
Diddle diddle 2
my son 2

这也适用于包含umlauts的文件:

Counter({(u'D\xf6ddle', u'diddle'): 2, (u'my', u'son'): 2, (u'dumpling',u'my'): 1, (u'diddle', u'dumpling'): 1, (u'son', u'D\xf6ddle'): 1, (u'diddle', u'my'): 1})
Döddle diddle 2
my son 2

编辑: 我增加了保存输出到文件output.txt的代码。


据我所见,most-common函数有其他规则来决定在输出中包含什么。由于他的要求是按排序顺序列出所有出现超过一次的内容,我认为这就是解决方案。你会做出哪些改变? - hochl
啊,确实,我没有注意到这些值已经排序了。 - Antti Haapala -- Слава Україні
它运行得非常好。非常感谢。最后一个问题,如何将结果保存到 .txt 文件中?我在结尾添加了以下代码,但没有起作用:output = open("output.txt", "w") output.write(result) output.close() - Cameroon P
你不能简单地将一个对象写入文件中。你可以使用pickle模块,或者将打印输出重定向到文件中。你想要实现什么目的? - hochl
如何将打印输出重定向到文件? - Cameroon P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接