如何简单地训练词向量


词向量即是把自然语言数学化,是机器处理自然语言的基础。本文基于维基百科语料,使用 gensim 的 word2vec 来训练词向量。

相关 Github 源码

版权声明:本文为 frendy 原创文章,可以随意转载,但请务必在明确位置注明出处。


环境准备


1. 安装 gensim 工具包:

这里主要会用到里面的 WikiCorpus 和 Word2Vec。

pip install gensim
2. 安装 opencc:

用于语料处理,繁体转简体。

apt install opencc
3. 安装 jieba:

这里用于中文切词。

pip install jieba

语料获取


本文的 Demo 使用了维基百科 20170501 的文章包 zhwiki-20170501-pages-articles.xml.bz2,共 2943168 篇文章,大家可以在下面的地址选择自己需要的语料:

https://dumps.wikimedia.org/zhwiki/

语料预处理


1. 提取语料:

把 zhwiki-20170501-pages-articles.xml.bz2 解压后发现是个 xml 文件,尴尬了,怎么处理?所幸的是 gensim 的 WikiCorpus 已经预置了部分处理,其实不用解压,执行 Demo 里的脚本即可:

python wiki_to_txt.py zhwiki-20170501-pages-articles.xml.bz2

我们来看看相关语句:

wiki_corpus = WikiCorpus(sys.argv[1], dictionary={})
texts_num = 0

with io.open("wiki_texts.txt",'w',encoding='utf-8') as output:
	for text in wiki_corpus.get_texts():
		output.write(b' '.join(text).decode('utf-8') + '\n')

image

2. 通过 opencc 将繁体转换成简体:
opencc -i wiki_texts.txt -o wiki_texts_zh.txt -c zht2zhs.ini

切词


这里采用的是 jieba 分词。执行 Demo 里的脚本如下:

python segment.py

我们来看看相关语句:

# 添加停止词,过滤一些频繁但无意义的词
stopwordset = set()
with io.open('jieba_dict/stopwords_zh.txt','r',encoding='utf-8') as sw:
	for line in sw:
		stopwordset.add(line.strip('\n'))
...
# 切词
with io.open('wiki_texts_zh.txt','r',encoding='utf-8') as content :
	for line in content:
		words = jieba.cut(line, cut_all=False)
		for word in words:
			if word not in stopwordset:
				output.write(word +' ')

image


词向量训练


这里使用 gensim 的 word2vec 训练模型。执行 Demo 里的脚本如下所示。想了解更多关于 gensim word2vec 的用法可以点这里

python train.py

我们来看看相关语句:

sentences = word2vec.Text8Corpus("wiki_seg.txt")
# sentences 为前面处理后的语句集合,size 是维度。这里实际上会对数据执行两次迭代操作,第一轮操作会统计词频来构建内部的词典数结构,第二轮操作会进行神经网络训练
model = word2vec.Word2Vec(sentences, size=260)

# 保存模型,以便后续使用
# ## save model 方法一,似乎不能进行二次训练,因此这里采用方法二
# model.save_word2vec_format(u"wiki.zh.model.bin", binary=True)
# ## save model 方法二,
model.save('wiki.zh.model')

# 二次训练
model = word2vec.Word2Vec.load('wiki.zh.model')
model.train(sentences, total_examples = model.corpus_count, epochs=model.iter)

然而估计是阿里云免费套餐云服务器内存资源不够吧,刚跑起来就进程被 killed 了,于是只好把 wiki_seg.txt 传到本地跑:

image


验证效果


1. 输入一个词,输出前二十个该词的相似词:
res = model.most_similar(q_list[0],topn = 20)

image

2. 输入两个词,输出两个词的余弦相似度:
res = model.similarity(q_list[0], q_list[1])

image

3. 输入三个词,进行类比推理:
res = model.most_similar([q_list[0], q_list[1]], [q_list[2]], topn= 20)

如下图示,效果不太理想,需要调参或进一步训练?

image


欢迎来撩

frendy

It will shine for us...