gensim w2v

使用迭代器进行语料传输

gensim word2vec输入是句子序列。每个句子是由单词组成的list。

支持逐条处理,因此可以迭代器来减少内存损耗:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class mysentences(object):
def __init__(self,dirname):
self.dirname = dirname

def __iter__(self):
for subdir in os.listdir(self.dirname):
if subdir[0] == '.':
continue
for fname in os.listdir(os.path.join(self.dirname,subdir)):
with open(os.path.join(self.dirname,subdir,fname)) as f:
ft = f.read()
try:
ft = ft.split('【 正 文 】\n',2)[1]
except:
pass
for line in ft.split('。'):
l = ' '.join(jieba.cut(line))
l = ''.join(re.findall(u'[\u4e00-\u9fff ]+', l))
yield l.strip().split()

注意,必须使用class的_iter__方法来形成迭代器,不然即使用yield也只是生成器,传进w2v中会报错。

匹配词向量和相对应的单词

1
2
3
4
5
6
#zip the two lists containing vectors and words
zipped = zip(model.wv.index2word, model.wv.syn0)

#the resulting list contains `(word, wordvector)` tuples. We can extract the entry for any `word` or `vector` (replace with the word/vector you're looking for) using a list comprehension:
wordresult = [i for i in zipped if i[0] == word]
vecresult = [i for i in zipped if i[1] == vector]

model.wv.index2word(词列表) 和 model.wv.syn0(词向量矩阵)在位置上已经是一一对应的了。

增量训练

如果已经有一个训练好的词向量模型,那么在读取之后可以使用train方法进行进一步训练,但是如果新语料中出现了新词,无法被训练到,只是能够进一步修改已存在词的词向量。以及,train方法需要指定一些参数,不然会报错。具体需要制定的参数看函数说明。

1
2
3
4
5
6
7
8
9
model = gensim.models.Word2Vec(corpus, min_count=1)
model.save('/home/muzhen/mymodel')
new_model = gensim.models.Word2Vec.load('/home/muzhen/mymodel')
matrix = model.wv.syn0

new_model.train(new_corpus, total_examples=len(new_tl), epochs=10)
new_matrix = new_model.wv.syn0

(matrix == new_matrix).all()

另外,new_model.build_vocab(new_tl, update=True)方法我实验后发现无效,并不能增加新词。另外,有看到model.update_vocab(new_sentences)方法,至少在gensim 2.3.1版本中没有这个方法。

references:

Gensim Word2vec 使用教程

Gensim进阶教程:训练word2vec与doc2vec模型

Matching words and vectors in gensim Word2Vec model