Gensim之Word2Vec使用手冊
1.介紹
一句話,Gensim中的Word2Vec
類就是用來訓練詞向量的,這個類實現了詞向量訓練的兩種基本模型skip-gram
和CBOW
,可以通過後面的引數設定來選擇。但是,在Gensim這個模組中訓練詞向量的方法還有很多:gensim.models.doc2vec.Doc2Vec
,gensim.models.fasttext.FastText
,gensim.models.wrappers.VarEmbed
等等都能得到詞向量。
2.Word2Vec類
2.1 Word2Vec類初始化引數
在下面介紹引數時,可能不會列舉完,完整的引數見word2vec.py
原始碼。
注:引數表這一列,等號右邊的值表示預設值
引數表 | 含義 |
---|---|
sentences=None | 語料句子,必須是一個可迭代的(參見後面例子) |
size=100 | 訓練後詞向量的維度 |
alpha=0.025 | 訓練網路的初始學習率,之後會線性降低 |
min_alpha=0.0001 | 降低到最小的學習率 |
window=5 | 當前詞和預測詞之間的最大間隔 |
min_count=5 | 忽略詞頻<5的詞語 |
max_vocab_size=None | 限制最大詞數,防止記憶體溢位 |
workers=3 | 設定執行緒數,越高訓練速度(前提是你有這麼多) |
sg=0 | 訓練模型的選擇,1表示skip-gram,0表示CBOW |
hs=0 | 訓練網路代價函式的選擇 |
iter=5 | 迭代次數 |
2.2 示例
2.2.1 訓練及儲存模型
# 示例1
from gensim.test.utils import common_texts
from gensim.models import Word2Vec
print(common_texts)
train_model = Word2Vec(common_texts, size=100, window=5, min_count=1, workers=4)
train_model.save('./MyModel')
train_model.wv.save_word2vec_format('./mymodel.txt' , binary=False)
訓練模型
只需要給Word2Vec
類賦上引數,就可以直接訓練了。其中common_texts
是一段內建的語料,如下:
[[‘human’, ‘interface’, ‘computer’], [‘survey’, ‘user’, ‘computer’, ‘system’, ‘response’, ‘time’], [‘eps’, ‘user’, ‘interface’, ‘system’], [‘system’, ‘human’, ‘system’, ‘eps’], [‘user’, ‘response’, ‘time’], [‘trees’], [‘graph’, ‘trees’], [‘graph’, ‘minors’, ‘trees’], [‘graph’, ‘minors’, ‘survey’]]
可以看到整體格式是[['A','B'],['C','D','E']]
,其中這個list表示所有的文字(此處表示2個文字,裡面的A,B等表示單詞,如果是中文則表示分詞的結果,後面也會用中文演示)
儲存模型
在示例1中,第8行和第10行都是用來儲存訓練模型的(簡稱save和format_save),而兩者之間的相同點就是:都可以複用,即載入之後可以得到對應單詞的詞向量;不同點是:save儲存的模型,載入之後可以繼續在此基礎上接著訓練(後文會介紹),而format_save儲存的模型不能,但有個好處就是如果s設定binary=False
則儲存後的結果可以直接開啟檢視(一共有12個詞向量,每個詞向量100維)
12 100
system -0.0027418726 -0.0029260677 0.0002653271 ......
user 0.000851792 -0.004782654 0.0017041893 ......
trees 6.689873e-05 0.0027949389 -0.002869004 ......
graph -0.0038760677 -0.0021227715 0.0029032128 ......
......
......
2.2.2 載入模型和使用(英文)
為了展示方便,下面我只用4個維度來表示詞向量。
#示例 2 檢視詞表相關資訊
from gensim.test.utils import common_texts
from gensim.models import Word2Vec
model = Word2Vec.load('./MyModel')
# 對於訓練好的模型,我們可以通過下面這前三行程式碼來檢視詞表中的詞,頻度,以及索引位置,
# 最關鍵的是可以通過第四行程式碼判斷模型中是否存在這個詞
for key in model.wv.vocab:
print(key)
print(model.wv.vocab[key])
print('human' in model.wv.vocab)
print(len(model.wv.vocab)) #獲取詞表中的總詞數
#結果:
trees
Vocab(count:3, index:2, sample_int:463795800)
graph
Vocab(count:3, index:3, sample_int:463795800)
minors
Vocab(count:2, index:11, sample_int:579459575)
True
12
# 示例3 獲取對應的詞向量及維度
model = Word2Vec.load('./MyModel')
print(model.wv.vector_size)
print(model['human'])
print(model['good'])
# 結果
4
[-0.06076013 -0.03567408 -0.07054472 -0.10322621]
KeyError: "word 'good' not in vocabulary"
Process finished with exit code 1
# 在取詞向量之前一定要先判斷
# 示例4 常用方法
#---------------4.1 計算兩個詞的相似度(餘弦距離)--------
model = Word2Vec.load('./MyModel')
print(model.wv.similarity('human', 'user'))
print(model.wv.similarity('human', 'survey'))
# 結果越大越相似(此處由於維度太小,所以結果好像不怎麼準確)
-0.6465453
0.55347687
#---------------4.2 計算兩個詞的距離--------
model = Word2Vec.load('./MyModel')
print(model.wv.distance('human', 'user'))
print(model.wv.distance('human', 'survey'))
# 結果越大越不相似
1.6465452909469604
0.44652312994003296
#---------------4.3 取與給定詞最相近的topn個詞--------
model = Word2Vec.load('./MyModel')
print(model.wv.most_similar(['human'],topn=3))
#結果
[('computer', 0.7984297871589661), ('response', 0.6434261798858643), ('survey', 0.5534768104553223)]
#---------------4.4 找出與其他詞差異最大的詞
model = Word2Vec.load('./MyModel')
print(model.wv.doesnt_match(['human','user','survey']))
#結果
user
其它的還有很多,如:
words_closer_than(),similar_by_word(),similar_by_vector(),similarity_matrix()
參見原始碼keyedvectors.py
2.2.3 載入模型並繼續訓練
載入模型並繼續訓練意思是,之前訓練好了一個詞向量模型,可能訓練時間不足,或者又有了新的資料,那麼此時就可以在原來的基礎上接著訓練而不用從頭再來。
#示例 5
model = Word2Vec(sentences=pos,size=50,min_count=5)
model.save('./vec.model_pos')
print('語料數:', model.corpus_count)
print('詞表長度:', len(model.wv.vocab))
# 結果
語料數: 5000
詞表長度: 6699
#-------------增量訓練
model = Word2Vec.load('./vec.model_pos ')
model.build_vocab(sentences=neg, update=True)
model.train(sentences=neg, total_examples=model.corpus_count, epochs=model.iter)
model.save('./vec.model')
print('語料數:', model.corpus_count)
print('詞表長度:', len(model.wv.vocab))
# 結果
語料數: 5001
詞表長度: 8296
可以看到,第一次訓練時用了5000個語料,訓練完成後詞表中一共有6699個詞;在追加訓練時,用了5001個語料,此時詞表中一共就有了8296個詞
2.2.4 載入模型和使用(中文)
我們用之前的訓練好的模型來演示:
# 示例 6
model = Word2Vec.load('./vec.model')
print('詞表長度:', len(model.wv.vocab))
print('愛 對應的詞向量為:',model['愛'])
print('喜歡 對應的詞向量為:',model['喜歡'])
print('愛 和 喜歡的距離(餘弦距離)',model.wv.similarity('愛','喜歡'))
print('愛 和 喜歡的距離(歐式距離)',model.wv.distance('愛','喜歡'))
print('與 愛 最相近的3個詞:',model.wv.similar_by_word('愛',topn=3))
print('與 喜歡 最相近的3個詞:',model.wv.similar_by_word('喜歡',topn=3))
print('愛,喜歡,恨 中最與眾不同的是:',model.wv.doesnt_match(['愛','喜歡','恨']))
#結果
詞表長度: 8296
愛 對應的詞向量為: [-1.0453074 -2.5688617 1.2240907 ...
喜歡 對應的詞向量為: [-0.5997423 -1.8003637 1.2935492 ...
愛 和 喜歡的距離(餘弦距離) 0.89702404
愛 和 喜歡的距離(歐式距離) 0.10297596454620361
與 愛 最相近的3個詞: [('喜歡', 0.89702), ('傷害', 0.88481), ('情感', 0.883626)]
與 喜歡 最相近的3個詞: [('青梅竹馬', 0.91182), ('輕浮', 0.91145), ('愛', 0.89702)]
愛,喜歡,恨 中最與眾不同的是: 恨