如何解决Python中BOW词袋模型的内存分配问题
解决词袋模型(BOW)批量处理的内存溢出问题
针对你遇到的BOW转换时内存不足的问题,给你几个实用的优化方案:
1. 优先使用稀疏矩阵存储
BOW结果里绝大多数元素都是0,用稠密数组存储完全是浪费内存。scikit-learn的CountVectorizer默认返回的就是稀疏矩阵(scipy的csr_matrix类型),不要调用toarray()转成稠密数组,直接用稀疏矩阵后续处理即可——绝大多数机器学习算法(比如逻辑回归、SVM)都支持稀疏输入。
示例代码:
from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer() # 直接得到稀疏矩阵,内存只存储非零元素 bow_sparse = vectorizer.fit_transform(your_text_corpus) print(f"稀疏矩阵形状: {bow_sparse.shape}, 非零元素占比: {bow_sparse.nnz / (bow_sparse.shape[0]*bow_sparse.shape[1])*100:.2f}%")
2. 削减特征维度
你的词汇表有32996个词,很多低频词对模型没什么贡献,可以通过以下参数过滤:
max_features: 只保留出现频率最高的N个词,比如设为10000或15000min_df: 过滤在少于N条文本中出现的词(比如min_df=5,去掉只在5条以下文本出现的词)max_df: 过滤在超过X%文本中出现的词(比如max_df=0.9,去掉在90%以上文本都出现的通用词)
示例代码:
vectorizer = CountVectorizer( max_features=15000, min_df=3, max_df=0.85, stop_words='english' # 还可以直接过滤内置停用词 ) bow_sparse = vectorizer.fit_transform(your_text_corpus)
3. 分批次处理(仅当必须用稠密数组时)
如果业务场景必须得到稠密数组,不要一次性转换所有数据,分批次处理后再按需保存或使用:
import numpy as np from sklearn.feature_extraction.text import CountVectorizer batch_size = 8000 vectorizer = CountVectorizer() # 先拟合所有文本得到完整词汇表 vectorizer.fit(your_text_corpus) # 分批次转换并处理 for start_idx in range(0, len(your_text_corpus), batch_size): end_idx = min(start_idx + batch_size, len(your_text_corpus)) batch_text = your_text_corpus[start_idx:end_idx] # 转换当前批次为稠密数组 bow_batch = vectorizer.transform(batch_text).toarray() # 这里做你需要的操作,比如保存到文件 np.save(f"bow_batch_{start_idx//batch_size}.npy", bow_batch) # 手动释放内存 del bow_batch
4. 降低数据类型精度
如果一定要用稠密数组,把数据类型从int64换成更小的类型:比如int32(最多存储21亿,完全够BOW计数),甚至uint16(最多65535,单条文本里一个词出现次数基本不会超过这个数),能直接把内存占用砍半或砍到1/4。
示例代码:
bow_dense = vectorizer.fit_transform(your_text_corpus).toarray().astype(np.uint16)
内容的提问来源于stack exchange,提问作者asmgx
相关产品推荐
相关产品推荐

