大型文本数据集编码出现内存错误,求适配神经网络的编码方案
解决方案
1. 替换全量词频统计方式,避免生成超大中间对象
你当前的写法会先把所有文本拼接成一个超大字符串、再展开成包含所有词的长列表,大文本量下中间对象会占用数倍于原始数据的内存,是触发OOM的核心原因。改用迭代式逐行统计词频,内存占用可降低90%以上:
from collections import defaultdict vocab_count = defaultdict(int) # 逐行遍历,无需一次性加载全量数据到内存 for _, row in df.iloc[:, :4].iterrows(): for col_val in row.dropna(): for word in col_val.split(): vocab_count[word] += 1 # 生成词表,预留特殊token位置,可根据需求调整排序逻辑 vocab = ["<PAD>", "<UNK>"] + sorted(vocab_count.keys(), key=lambda x: -vocab_count[x]) word2idx = {word: idx for idx, word in enumerate(vocab)}
2. 分批次编码,不要一次性转换全量数据集
编码时不需要把整个数据集一次性转成数字索引,根据可用内存调整批次大小,处理完的批次直接喂给模型或者存到本地硬盘,内存中仅保留当前批次数据:
def encode_text(text, word2idx, max_seq_len=50): words = text.split() # 超出长度截断,不足补PAD indices = [word2idx.get(word, word2idx["<UNK>"]) for word in words[:max_seq_len]] indices += [word2idx["<PAD>"]] * (max_seq_len - len(indices)) return indices # 批次大小可根据实际内存情况调整,1000-10000条都是合理区间 batch_size = 1000 for idx in range(0, len(df), batch_size): batch = df.iloc[idx:idx+batch_size] encoded_batch = [] for _, row in batch.iterrows(): # 可根据需求选择拼接多字段编码或者分别编码 title_enc = encode_text(row["TITLE"], word2idx) desc_enc = encode_text(row["DESCRIPTION"], word2idx) encoded_batch.append(title_enc + desc_enc) # 此处可直接将encoded_batch传入模型训练,或存入本地npy文件后续使用 # np.save(f"batch_{idx//batch_size}.npy", np.array(encoded_batch))
3. 额外优化建议
你当前服务器可用内存有12G左右,正常处理百万级文本完全足够,还可以通过以下操作进一步降低内存开销:
- 统计词表时过滤出现次数低于2的低频词,这类词对模型效果提升极小,还会占用大量词表空间
- 处理完对应字段后可直接删除df中的原始文本列,及时释放内存
- 无需自行实现编码逻辑的话,也可以直接用
sklearn.feature_extraction.text.CountVectorizer,设置max_features限制词表大小,自带内存优化,输出的向量可直接输入神经网络
内容的提问来源于stack exchange,提问作者Atharva Gundawar
相关产品推荐
相关产品推荐

