Gensim是一个可以用于主题模型抽取,词向量生成的python的库。
像是一些NLP的预处理,可以先用这个库简单快捷的进行生成。
比如像是Word2Vec,我们通过简单的几行代码就可以实现词向量的生成,如下所示:
import gensim
from numpy import float32 as REAL
import numpy as np
word_list = ["I", "love", "you", "."]
model = gensim.models.Word2Vec(sentences=word_list, vector_size=200, window=10, min_count=1, workers=4)
# 打印词向量
print(model.wv["I"])
# 保存模型
model.save("w2v.out")
笔者使用Gensim进行词向量的生成,但是遇到一个需求,就是已有一个词向量模型,我们现在想要扩增原本的词汇表,但是又不想要修改已有词的词向量。
Gensim本身是没有文档描述如何进行词向量冻结,但是我们通过查阅其源代码,发现其中有一个实验性质的变量可以帮助我们。
# EXPERIMENTAL lockf feature; create minimal no-op lockf arrays (1 element of 1.0)
# advanced users should directly resize/adjust as desired after any vocab growth
self.wv.vectors_lockf = np.ones(1, dtype=REAL)
# 0.0 values suppress word-backprop-updates; 1.0 allows
这一段代码可以在gensim的word2vec.py文件中可以找到
于是,我们可以利用这个vectos_lockf实现我们的需求,这里直接给出对应的代码
# 读取老的词向量模型
model = gensim.models.Word2Vec.load("w2v.out")
old_key = set(model.wv.index_to_key)
new_word_list = ["You", "are", "a", "good", "man", "."]
model.build_vocab(new_word_list, update=True)
# 获得更新后的词汇表的长度
length = len(model.wv.index_to_key)
# 将前面的词都冻结掉
model.wv.vectors_lockf = np.zeros(length, dtype=REAL)
for i, k in enumerate(model.wv.index_to_key):
if k not in old_key:
model.wv.vectors_lockf[i] = 1.
model.train(new_word_list, total_examples=model.corpus_count, epochs=model.epochs)
model.save("w2v-new.out")
这样就实现了词向量的冻结,就不会影响已有的一些模型(我们可能会基于老的词向量训练了一些模型)。