Word2Vec是一种广泛使用的自然语言处理技术,它可以将文本转换为向量形式,并且可以在向量空间中对这些向量进行操作,例如计算相似性、聚类等。在这篇文章中,将讲述更新Word2Vec模型的多种尝试。
Word2Vec简介
Word2Vec是一种由Google于2013年发布的自然语言处理工具包。它可以将文本中的单词转换为向量形式,并且可以在向量空间中对这些向量进行操作。Word2Vec包括两种模型:CBOW和Skip-gram。
CBOW(Continuous Bag-of-Words)模型会尝试根据上下文单词来预测中心单词。Skip-gram模型则相反,它会尝试根据中心单词来预测上下文单词。在实践中,Skip-gram模型通常比CBOW模型更好。
训练Word2Vec模型
要训练Word2Vec模型,需要一个大型的文本语料库。可以使用Python中的gensim库来训练Word2Vec模型。首先,需要将文本分成单词,然后将单词列表传递给gensim.models.Word2Vec类的构造函数。
以下是一个简单的例子:
1 | from gensim.models import Word2Vec |
上面的代码将创建一个Word2Vec模型,用于训练由两个句子组成的语料库。min_count参数设置单词出现的最小次数。如果一个单词在语料库中出现的次数小于这个值,那么这个单词将被忽略。
可以使用以下代码来查看单词向量:
1 | vector = model.wv["cat"] |
也可以使用以下代码来查找与给定单词最相似的单词:
1 | similar_words = model.wv.most_similar("cat") |
更新Word2Vec模型
在某些情况下,希望在不重新训练整个Word2Vec模型的情况下更新它。gensim库提供了两种更新Word2Vec模型的方法。
第一种方法是使用gensim.models.Word2Vec类的build_vocab()方法来构建新的单词表。然后,可以使用train()方法来更新模型。以下是一个简单的例子:
1 | model.build_vocab([["bird", "fly", "high"]], update=True) |
上面的代码将向模型添加一个新的句子,然后更新模型。注意,这里需要设置update参数为True。
第二种方法是使用gensim.models.Word2Vec类的build_vocab()方法来构建新的单词表。然后,就可以使用gensim.models.KeyedVectors类的add_vectors()方法来添加新的单词向量。以下是一个简单的例子:
1 | model.build_vocab([["bird", "fly", "high"]], update=True) |
上面的代码将添加一个新的单词向量,然后更新模型。
Google 预训练的 Word2Vec 模型
Google 发布了一款基于 Google News 数据集的预训练 Word2Vec 模型,包含了 300 维向量,覆盖了 300 万个单词和短语。该模型可从此链接下载,二进制文件(GoogleNews-vectors-negative300.bin)解压后大小为 3.4 GB。
在 Python 代码中使用预训练模型需要使用 gensim
库中的 KeyedVectors
类:
1 | from gensim.models import KeyedVectors |
使用预训练好的模型可以快速构建起权威的语料库,但在深入使用之后,经常会碰到词汇表缺失的问题,连”forgot”这种常用词,都不在词汇表中,无法进行匹配。
这是因为为了保证效率,Google 预训练的 Word2Vec 模型中并不会保留全部词汇,而是选择性的存储高频词汇,若需要将其用到不同的领域之中,需要对模型的词汇进行更新与微调。
一开始先尝试了手动地往Google 预训练的 Word2Vec 模型中补充缺失的词向量,但遇到了许多错误,查询资料后才发现:
预训练模型的一个缺点是,由于缺少隐藏权重、词汇频率和二叉树,无法继续训练,因此无法在预训练模型上进行迁移学习。
后来又顺着逆向的思维来看,既然预训练模型缺少信息,无法更新,那反过来可不可以用预训练模型来更新自己新建的模型呢?于是尝试使用 intersect_word2vec_format
方法替换自己模型中的词向量与预训练模型中的词向量:
1 | your_word2vec_model.intersect_word2vec_format('GoogleNews-vectors-negative300.bin', lockf=1.0, binary=True) |
虽然此方法不是迁移学习,但它非常类似。如果有一个小的自定义数据集,并想使用 Google 的预训练模型进行迁移学习,可以使用以下代码:
1 | from gensim.models import Word2Vec |
此代码将词向量分配给 Google 预训练模型中的词汇表和上面定义的句子,然后使用自己的数据继续训练。 size
选项需要设置为 300,以与 Google 的预训练模型相同。 lockf
选项需要设置为 1.0 才能允许继续训练。
因为我使用 gensim
是 4.0.1 版本的 Word2Vec
模型时,还遇到以下错误:
1 | IndexError: index 0 is out of bounds for axis 0 with size 0 |
在插入向量之前,还需要手动设定一下lockf
值:
1 | model.wv.vectors_lockf = np.ones(len(model.wv), dtype=REAL) |
结论
在这篇文章中,尝试了多种训练和更新Word2Vec模型的方法。虽然最后以新训练模型成功补上了缺失的词汇,并利用Google News的预训练模型进行了迁移学习,但还是达不到词汇量与准确度上的两全其美。
查资料的过程中发现了Doc2vec,说是支持在线训练,并能自动推断未知词汇,倒是能满足需求的样子,下一步可能会去看看它的使用。
参考资料:
Gensin教程:https://rutumulkar.com/blog/2015/word2vec/
Google预训练模型代码:https://code.google.com/archive/p/word2vec/
更新W2V模型:https://phdstatsphys.wordpress.com/2018/12/27/word2vec-how-to-train-and-update-it/