You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CountVectorizer生成二元/三元组时遇内存不足问题求助

内存高效的N-gram提取方案

核心问题根源

你遇到的内存错误完全是因为ngrams.toarray()把稀疏矩阵(csr_matrix)强制转成了稠密数组——稀疏矩阵只存非零值,而稠密数组要存所有84891×12780210个元素,这显然超出了内存极限。下面是几个直接可行的优化方案:

1. 直接在稀疏矩阵上计算词频(最有效)

不用把稀疏矩阵转成稠密数组,直接调用稀疏矩阵的sum方法,再转成一维数组即可:

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

lemmatized = dat_clean['lemmatized']

c_vec = CountVectorizer(ngram_range=(2,3), lowercase=False)
ngrams = c_vec.fit_transform(lemmatized)

# 直接在稀疏矩阵上按列求和,A1转成一维数组
count_values = ngrams.sum(axis=0).A1
vocab = c_vec.vocabulary_

# 按词频排序构建DataFrame
df_ngram = pd.DataFrame(
    sorted([(count_values[i], k) for k, i in vocab.items()], reverse=True),
    columns=['frequency', 'bigram/trigram']
)

这个操作全程基于稀疏矩阵,内存占用只和非零元素数相关,不会出现几十TiB的内存需求。

2. 提前过滤低频率N-gram(减少特征数)

如果特征数还是太大,可以通过CountVectorizer的参数提前过滤掉出现次数极少的N-gram,大幅压缩特征空间:

# 示例:只保留至少出现2次、最多在80%文档中出现的N-gram
c_vec = CountVectorizer(
    ngram_range=(2,3), 
    lowercase=False,
    min_df=2,  # 至少在2个文档中出现
    max_df=0.8,  # 不在超过80%的文档中出现
    max_features=100000  # 可选:限制最多保留10万个特征
)

min_df是最有效的过滤参数,大部分低频N-gram都是噪声,过滤后特征数会骤降。

3. 分块处理大规模语料(极端情况)

如果语料规模极大,连稀疏矩阵都存不下,可以分块加载语料,逐步累加N-gram计数:

from collections import defaultdict
import pandas as pd

# 初始化CountVectorizer的分析器
c_vec = CountVectorizer(ngram_range=(2,3), lowercase=False)
analyzer = c_vec.build_analyzer()

# 遍历语料,逐个统计N-gram出现次数
ngram_counter = defaultdict(int)
for text in lemmatized:
    ngrams = analyzer(text)
    for ngram in ngrams:
        ngram_counter[ngram] += 1

# 转成DataFrame并排序
df_ngram = pd.DataFrame(
    sorted(ngram_counter.items(), key=lambda x: x[1], reverse=True),
    columns=['bigram/trigram', 'frequency']
)

这种方法不需要一次性构建整个文档-词矩阵,内存占用只和所有唯一N-gram的数量相关。

内容的提问来源于stack exchange,提问作者Kaitlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:09:55