以下是文本语料库中二元组计算的代码:
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)时,问题就开始了,脚本停止工作。
如何解决这个问题? 谢谢。
假设我正确理解 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))