如何在Python中为22GB大型语料库实现Word2Vec加权平均表示?
TF-IDF与Word2Vec结合实现句子加权平均的解决方案
一、解决HashDictionary维度过大的问题
你当前使用HashDictionary导致维度冗余,是因为它预先分配了固定大小的ID范围(DEFAULT_DICT_SIZE),即便过滤了低频/高频词,维度仍不会自动缩小。推荐直接替换为普通Dictionary,过滤后字典大小即为实际保留的词数,维度会大幅降低:
# 替换HashDictionary为普通Dictionary from gensim.corpora import Dictionary dictionary = Dictionary() text_corpus = LogCorpus(inp_dir, dictionary=dictionary, metadata=False) # 后续过滤、保存步骤与原代码一致 dictionary.filter_extremes(no_below=20, no_above=0.1, keep_n=DEFAULT_DICT_SIZE) # 此时len(dictionary)就是实际保留的词数,维度合理
如果必须保留HashDictionary,可在过滤后构建新的小字典重新映射:
# 提取过滤后保留的词 filtered_words = [dictionary[id] for id in dictionary.token2id if id in dictionary] # 构建仅包含有效词的新字典 new_dict = Dictionary([filtered_words]) # 后续TF-IDF向量需重新映射到新字典维度(此步骤较繁琐,优先推荐普通Dictionary方案)
二、结合TF-IDF与Word2Vec计算句子加权平均向量
假设你已训练好适配自身语料的Word2Vec模型(记为w2v_model),按以下步骤实现:
1. 加载预处理资源
import numpy as np from gensim.corpora import MmCorpus, Dictionary from gensim.models import TfidfModel, Word2Vec # 加载之前保存的字典、TF-IDF模型和语料 dictionary = Dictionary.load_from_text(str(inp_dir)+'wordids.txt.bz2') tfidf = TfidfModel.load(str(inp_dir)+'tfidf.tfidf_model') mm = MmCorpus(str(inp_dir)+'bow.mm') # 加载训练好的Word2Vec模型 w2v_model = Word2Vec.load("your_word2vec_model_path") vec_dim = w2v_model.vector_size
2. 逐句生成加权向量(内存友好版)
无需将TF-IDF转为稠密矩阵(大语料下会直接爆内存),直接迭代处理稀疏向量:
sentence_vectors = [] # 分批次处理避免内存溢出,可根据内存调整批次大小 batch_size = 10000 current_batch = [] for idx, bow in enumerate(mm): tfidf_vec = tfidf[bow] total_weight = 0.0 weighted_sum = np.zeros(vec_dim) for word_id, weight in tfidf_vec: word = dictionary[word_id] # 仅处理Word2Vec中存在的词 if word in w2v_model.wv: weighted_sum += weight * w2v_model.wv[word] total_weight += weight # 处理无有效词的情况 if total_weight > 0: sentence_vec = weighted_sum / total_weight else: sentence_vec = np.zeros(vec_dim) current_batch.append(sentence_vec) # 批次满则保存到磁盘并清空 if (idx + 1) % batch_size == 0: np.savez(f"{inp_dir}/sentence_vec_batch_{idx//batch_size}.npz", vecs=current_batch) current_batch = [] # 保存剩余批次 if current_batch: np.savez(f"{inp_dir}/sentence_vec_batch_final.npz", vecs=current_batch)
3. 实用优化建议
- Word2Vec适配性:优先用你的22GB语料训练Word2Vec,词向量与语料的匹配度更高,效果更好。
- OOV词处理:代码中直接跳过不在Word2Vec中的词,也可选择用所有词向量的平均值代替,但跳过OOV词的方案更稳妥。
- 内存控制:大语料下务必分批次处理并保存,避免一次性加载所有数据导致内存溢出。
内容的提问来源于stack exchange,提问作者dobrowol
相关产品推荐
相关产品推荐

