bigram计算-内存错误、大文件问题

问题描述 投票:0回答:1

以下是文本语料库中二元组计算的代码:

import sys
import csv
import string

import nltk
from nltk import word_tokenize
from nltk.tokenize import RegexpTokenizer
from nltk.util import ngrams
from collections import Counter

tokenizer   = RegexpTokenizer(r'\w+')

with open('hugefile.csv', 'r') as file:
    
            text  = file.read()
                
            token = tokenizer.tokenize(text)
            trigrams = ngrams(token,3)
            count = Counter(trigrams)

            with open('out.csv','w') as csvfile:
                
                for tag, count in count.items():  
                
                    csvfile.write('{},{},{},{}\n'.format(tag[0], tag[1], tag[2], count)) 

错误:

    Traceback (most recent call last):
  File "C:\OSPanel\domains\vad\freq.py", line 17, in <module>
    text = file.read();
           ^^^^^^^^^^^
  File "<frozen codecs>", line 322, in decode
MemoryError

在巨大文件.csv 相对论较小的情况下,代码可以正确工作。 当文件非常大(几 GB)时,问题就开始了,脚本停止工作。

如何解决这个问题? 谢谢。

python nltk n-gram
1个回答
0
投票

假设我正确理解 n 元语法,您可以制作以下迭代器,从技术上避免一次加载整个文件。如果 n-gram 之间的重复不足,您可能仍然会遇到过大的

Counter
,但这是一个单独的问题(您可以通过将中间 n-gram 数据写入磁盘并排序以模拟磁盘的行为来解决该问题)基于计数器)。

from collections import deque

def ngram_iter(it, n=3):
    """
    it: any iterator of strings, be it file, list, generator, or whatever
    """
    fifo = deque(maxlen=3)
    for line in it:
        for token in tokenizer.tokenize(line):
            fifo.append(token)
            if len(fifo) == n:
                yield list(fifo)

现在您可以创建计数器而无需一次加载整个文件:

Counter(ngram_iter(file, 3))
© www.soinside.com 2019 - 2024. All rights reserved.