为什么嵌入矩阵中有所有值为 0 的行?

问题描述

我为情感分析创建了词嵌入向量。但我不确定我写的代码。如果您在创建 Word2vec 或嵌入矩阵时发现我的错误,请告诉我。

EMbedDING_DIM=100 
review_lines = [sub.split() for sub in reviews]    
model = gensim.models.Word2Vec(sentences=review_lines,size=EMbedDING_DIM,window=6,workers=6,min_count=3,sg=1) 
print('Words close to the given word:',model.wv.most_similar('film'))    
words=list(model.wv.vocab) 
print('Words:',words)

file_name='embedding_word2vec.txt'
model.wv.save_word2vec_format(file_name,binary=False)     
embeddings_index = {}    
f=open(os.path.join('','embedding_word2vec.txt'),encoding="utf-8")    
for line in f:    
  values =line.split()    
  word=values[0]   
  coefs=np.asarray(values[1:],dtype='float32')   
  embeddings_index[word]=coefs    
f.close()  
print("Number of word vectors found:",len(embeddings_index))
  
embedding_matrix = np.zeros((len(word_index)+1,EMbedDING_DIM))
for word,i in word_index.items():
  embedding_vector= embeddings_index.get(word)
  if embedding_vector is not None:
    embedding_matrix[i]=embedding_vector

OUTPUT:
array([[ 0.,0.,...,0.        ],[ 0.1029947,0.07595579,-0.06583303,0.10382118,-0.56950015,-0.17402627],[ 0.13758609,0.05489254,0.0969701,0.18532865,-0.49845088,-0.23407038],[ 0.,0.        ]])

解决方法

很可能存在零行,因为您将 embedding_matrix 初始化为全零,但随后您的循环并未为每一行替换这些零。

如果 word_index 中的任何单词不在您构建的 embeddings_index dict 中(或之前的 model,那将是预期的结果。

请注意,虽然保存的词向量格式不是很复杂,但您仍然不需要编写自己的代码来解析它。KeyedVectors.load_word2vec_format() 方法可以解决这个问题,为您提供允许通过其词键对每个向量进行类似 dict 访问的对象。 (而且,向量存储在一个密集数组中,因此它比使用单独的 ndarray 向量作为每个值的真正 dict 的内存效率要高一些。)

您的 word_index 列出未经过模型训练的词的问题仍然存在。也许它们没有出现在您的训练文本中,或者没有出现至少 min_count(默认值:5)次,这是模型注意到它们所必需的。 (您可以考虑降低 min_count,但请注意,丢弃此类非常罕见的词通常是个好主意 - 它们不会从少数示例中创建非常好的向量,甚至包括此类代表性不足的词也会恶化周围词的向量。)

如果你在训练数据中绝对需要单词 no 的向量,word2vec 算法的 FastText 变体可以在相似单词经常共享相似字符运行的语言中,为未知单词提供比随机更好的合成向量/大多数下游应用程序的空向量。但是你真的应该更喜欢有足够的真实例子来说明每个有趣的词在不同的上下文中的用法。