Python使用Gensim Fasttext构建词对相似度矩阵内存报错咨询
问题根源
内存报错和词表规模、FastText模型加载无关,核心是代码里的数组变形操作完全错误:
- cc.en.300.bin输出的每个词向量是300维,若词表长度为N,正确的词向量矩阵形状应为
(N, 300) - 你写的
.reshape(-1, 1)会把所有词向量的所有维度值拉平为单列数组,总长度为N*300,对应报错里的368700维度,此时计算两两距离会生成368700×368700的巨型矩阵,自然需要TB级内存,触发溢出。
另外你的代码还有一个逻辑错误:model.similarity的入参是两个字符串格式的词,不是数值型向量,不能直接传给pairwise_distances作为距离计算函数。
实现方案
Gensim没有提供直接生成指定词表相似度矩阵的原生函数,但实现逻辑非常简单,1000量级的词表计算全程内存占用不到10MB,完全不会有性能问题。
方案1:基于sklearn计算(和你原有代码逻辑最贴近)
删掉错误的reshape操作,直接用内置的余弦距离度量,再转换为相似度即可:
import numpy as np from gensim.models import fasttext as ft from sklearn.metrics import pairwise_distances path = 'cc.en.300.bin' model = ft.load_facebook_vectors(path, encoding='utf-8') wordlist = df_['word'].tolist() # 直接堆叠词向量,不做多余变形 word_vecs = np.array([model[word] for word in wordlist]) # 余弦相似度 = 1 - 余弦距离 cosine_distance_matrix = pairwise_distances(word_vecs, word_vecs, metric='cosine') similarity_matrix = 1 - cosine_distance_matrix
方案2:纯numpy实现(速度更快)
余弦相似度等价于L2归一化后向量的点积,直接用矩阵乘法计算,不需要依赖sklearn,小数据量下速度更快:
# 承接上面的word_vecs变量 # 对所有词向量做L2归一化 vec_norms = np.linalg.norm(word_vecs, axis=1, keepdims=True) normalized_vecs = word_vecs / vec_norms # 矩阵乘法直接得到两两余弦相似度 similarity_matrix = normalized_vecs @ normalized_vecs.T
注意事项
- 不要尝试给
pairwise_distances传入model.similarity作为自定义metric,该函数接收的参数是词字符串,和pairwise_distances传入的向量切片不匹配,会触发类型错误。 - 最终输出的
similarity_matrix是一个形状为(len(wordlist), len(wordlist))的方阵,similarity_matrix[i][j]就是wordlist里第i个词和第j个词的余弦相似度,值域为[-1,1]。
内容的提问来源于stack exchange,提问作者sato
相关产品推荐
相关产品推荐

