为了能够训练自己的Word2vec模型,你需要有一些数据,这里用Lee Evaluation 语料库来进行训练。
这个语料库足够小(一共300条数据),而且可以完全加载进内存当中,但是!在实际的应用中你往往不能够直接加载很大的语料库进内存,所以首先来实现一个迭代器来逐行的读取文件:
from gensim.test.utils import datapath
from gensim import utils
class MyCorpus:
def __iter__(self):
corpus_path = datapath('lee_background.cor')
for line in open(corpus_path):
#对读取的句子进行简单的处理
yield utils.simple_preprocess(line)
sentences = MyCorpus()
这里的sentences就是得到了一个经过简单处理的句子组成的列表,当然,你可以在for循环里面进行自己的处理。
接下来可以进行训练,那么需要引入gensim.model来做
import gensim.models
model = gensim.models.Word2Vec(sentences=sentences)
恭喜你,现在已经拥有了一个训练好的模型
不信?来我们来试一下,先看一下能不能得到“king”的向量
vec_king = model.wv['king']
print(vec_king)
你将得到一个向量:
[-0.02358022 -0.01961599 -0.00139271 -0.05510962 0.00294285 -0.00853481 -0.05957844 -0.04168227 -0.00846175 -0.02649316 0.01622383 0.01140004
0.00060386 -0.02601025 0.02205477 -0.02732388 0.01936879 0.047723 -0.06851483 -0.02320203 -0.00837262 -0.03829869 -0.00307029 -0.00264714
0.02370911 -0.05599895 -0.05200971 0.00733679 -0.00020037 0.02888935 0.02459002 0.01178179 -0.03889398 0.00082152 -0.01142673 -0.01249802
-0.0460892 -0.05402889 -0.01610627 0.05480611 0.00929705 0.05078919 -0.10389426 -0.078765 0.04261794 0.03915099 0.02897199 -0.04528579
-0.00610147 -0.06752459 -0.01624303 -0.00028024 0.0536734 -0.00837825 0.04030742 -0.05145243 0.03172397 0.05080702 0.0358872 -0.04948008
-0.01018649 -0.04389209 -0.01549766 0.00885961 -0.00399141 0.004901 0.02601369 0.04642579 -0.03019009 0.02526439 0.00062573 0.04625718
-0.04111696 -0.05535169 0.00018219 -0.03083905 0.05379871 -0.04979923-0.01030279 -0.05733781 0.01102394 -0.01693691 0.00895766 0.03222418-0.01516426 0.01628239 -0.03296118 0.01790296 -0.02671471 -0.08221665
0.01137402 -0.02240016 0.02553035 -0.05492717 -0.02355297 0.00911765-0.0913882 -0.00732729 0.02453462 -0.00781731]
不要误会,这里我为了方便显示进行了分行,但是实际上这个向量是一个1行100列的向量,可以看出来,模型的默认向量长度是100,因为我们没有特别指定维度。
接下来,我们再试试别的,我们来看一下词典里面都有什么,就打印一下前十个好了:
for index, word in enumerate(model.wv.index2word):
if index == 10:
break
print(f"word #{index}/{len(model.wv.index2word)} is {word}")
注意!这里官方教程有错误,现在这么写才是对的,得到的结果如下:
word #0/1750 is the
word #1/1750 is to
word #2/1750 is of
word #3/1750 is in
word #4/1750 is and
word #5/1750 is he
word #6/1750 is is
word #7/1750 is for
word #8/1750 is on
word #9/1750 is said
既然你相信你已经训练好了模型,那么你可以把它存储起来,方便以后的时候直接使用,就不再需要花时间去在训练模型了,因为训练模型很花时间。
那么,怎么去存储模型呢?
官方教程里是这样做的,这里用到了tempfile库,这个库是用来生成临时文件和临时目录的,你可以打印一下看看路径:
import tempfile
with tempfile.NamedTemporaryFile(prefix='gensim-model-',delete=False) as tmp:
temporary_filepath = tmp.name
print(temporary_filepath)
model.save(temporary_filepath)
C:\Users\ADMINI~1\AppData\Local\Temp\gensim-model-wohv4_tq
这样就可以把模型保存到相应的目录下了,这里我也不是很能理解为什么要用tempfile来做,但是我觉得在平时的使用中,只需要在save的参数里面传入文件的路径就可以保存,比如说:
model.save('./myModel')
可以看到,在当前目录文件夹下面就有了这样一个文件:
那么如何去加载这个模型?再来举个例子:
new_model = gensim.models.Word2Vec.load('./myModel')
此外,还可以使用原始的C工具的文本以及二进制格式来加载模型:
model = gensim.models.KeyedVectors.load_word2vec_format('/tmp/vectors.txt', binary=False)
# using gzipped/bz2 input works too, no need to unzip
model = gensim.models.KeyedVectors.load_word2vec_format('/tmp/vectors.bin.gz', binary=True)
接下来介绍一些训练模型的参数
min_count(default = 5)
min_count这个参数是用来修建内部的字典的,是不是不好理解,举个例子来说,在实际的应用中,一个大型的语料库里面存在只出现一两次的单词,这些单词可能是没有意义甚至是拼写错误的单词,对于这种单词最好忽略,那么你可以通过设置模型的min_count参数来指定字典中存在的词至少要在语料库里面出现多少次:
model = gensim.models.Word2Vec(sentences, min_count=10)
vector_size(default = 100)
vector_size这个参数是用来指定模型将单词映射到向量的维数,还记得我们之前的例子么,它的默认值是100,更大的尺寸需要有更多的训练数据的支持,一般可以从几十到几百不等,在论文里面往往都是设置为300
model = gensim.models.Word2Vec(sentences, vector_size=200)
workers(default = 3)
workers是模型用来进行训练并行化的一个参数,来加快训练的速度!
model = gensim.models.Word2Vec(sentences, workers=4)
注意!workers参数只有在安装了Cython以后才有用,如果没有安装的话,你只能使用一个核心!(似乎在Anaconda里面已经有了?反正我这里有)
在模型的核心中,word2vec模型的参数是以Numpy array的形式进行存储的,每个矩阵都是词汇表的大小(#vocabulary)乘以向量的大小(#vector_size),其中的元素是float类型的(单精度 4个字节)
在RAM中保存了3个这么大的矩阵(似乎这个矩阵的数量正在减少),所以举个例子来说,如果说有100000个不重复的单词,并且要求向量的大小为200维,那么占用的存储空间就是:
100,000*200*4*3 bytes = ~229MB
除了存储模型的参数以外,还要有一些额外的内存来存储词汇表树(通常只需要几兆字节)