Word2Vec在Tensorflow上的版本以及與Gensim之間的運行對比


接昨天的博客,這篇隨筆將會對本人運行Word2Vec算法時在Gensim以及Tensorflow的不同版本下的運行結果對比。在運行中,參數的調節以及迭代的決定本人並沒有很好的經驗,所以希望在展出運行的參數以及結果的同時大家可以批評指正,多謝大家的支持!

 

對比背景:

對比實驗所運用的corpus全部都是可免費下載的text8.txt。下載點這里。在訓練時,word embedding的維度被調節為200,除了word2vec_basic.py版本的step size為600001外,其余均為15個epoches。 運行結果除basic版本外其他的均運用了Mikolov所公開的questions-words.txt文件來計算其精確度。該精確度計算文件的格式為每行四個詞,在計算精度時,系統選取前三個詞的向量,計算詞2-詞1+詞3所得的向量並通過cosine similarity的方式搜尋最接近的詞,並選取top N個(N為自定義量,一般要么1要么4)來查看questions-words里每行的第四個詞是否存在於這top N個詞之中。另外,在運行結束后,我也根據Mikolov論文中的提示運用了幾個常見的向量算數測試來測驗各模型的准確度。我所運用的測試為:

  1. France, Paris, Beijing, China 或者 France, Paris, Rome, Greece

  2. man, king, woman, queen

  3. slow, slowly, quick, quickly

  等等......

 

對比結果:

TensorFlow框架:

1. Word2Vec_basic.py:

word2vec_baisc.py是Tensorflow官方版本的Sentence Embedding概念闡述的示例的代碼。該代碼用最簡單的方式實現了Word2Vec中的部分主要功能,即Skip-Gram模型以及Negative Samping加速分類算法。在設定word embedding維度為200以及num step為600001后,運行結果如下:

由上圖可見,詞向量是randomly init的,所以他認為six跟conjuring或者analogies相近。另外,在剛init的時機,loss數是302.11。在20萬此迭代后,average loss為4.96。此時的nearest測試結果如下:

我們可見此時,跟six相近的詞為seven, five, four和eight, 並且與has相似的有had, have等。這個結果已經初步證明系統已經學習到了一些特征,但是有的詞例如history,所對應的詞是reginae,這個連含義都不清楚的詞和明顯跟history的意義不相關。所以可見系統並不完善,只是簡單的詞兒比較容易先學到。另外,從20萬個到第40萬step,我們發現loss降低的並不明顯。在訓練的最后,結果展示如下:

history跟culture的北美的環境里有些許相似的成分,所以可見系統窮時變得更加的好了。同時,i本身作為羅馬數字的一面(即ii)和作為我的一面(即we)也被很好的展現了出來。這個結果是encouraging的,因為系統其實變得更好了。但是一直到60萬step, loss還停留在4.52左右,於20萬的4.96區別不大,由此可見學習進入smoothing區域。

但系統到底在詞義以及詞性上的結果到底如何呢?我們通過以下一些實驗為大家證明。具體的代碼如下:

# Testing final embedding
input_dictionary = dict([(v,k) for (k,v) in reverse_dictionary.iteritems()])

#找尋france, paris和rome的word index
test_word_idx_a = input_dictionary.get('france')
test_word_idx_b = input_dictionary.get('paris')
test_word_idx_c = input_dictionary.get('rome')

#在final_embeddings(也就是我們系統學到的embedding)里尋找上述詞
a = final_embeddings[test_word_idx_a,:]
b = final_embeddings[test_word_idx_b,:]
c = final_embeddings[test_word_idx_c,:]

#通過algebra的方式尋找預測詞
ans = c + (a - b)
similarity = final_embeddings.dot(ans)

print similarity.shape
print similarity[0:10]

#選取最近的4個詞展示出來
top_k = 4
nearest = (-similarity).argsort()[0:top_k+1]
print nearest
for k in xrange(top_k+1):
    close_word = reverse_dictionary[nearest[k]]
    print(close_word)

 所得結果如下:

當輸入a = france, b = paris, c = rome時,系統回答我詞匯近似於[rome, france, thibetanus, mnras, schwaben]。 當輸入為a = king, b = man, c = woman時,系統回答為[king, woman, philip, mayr, eulemur]。這里的結果並不理想。訓練時間上,60萬個step時間並不是很長,也不短,之前沒注意記時間,但是運算時間大體在1小時左右。

 

2. Word2Vec_Optimized.py:

這個模型是Tensorflow對word embedding的加強式示例,其默認迭代數為15次,運行結果如下:

15 epoches之后的正確率為36.7%。 在設定迭代數量為50次后,該結果為39%, 迭代數為100時,accuracy也沒超過40%,停留在39.7%。 當運行了200次迭代后,總算達到了40%,雖然耗時為大約7小時。至於系統於一些基礎問題上的運行結果,我們對15詞迭代的結果進行了測試,結果如下:

從以上簡單的測試中,我們已經發現其效果一般,但比較basic版本還是要好很多的。其中,有名的king, man, queen, woman問題系統並沒有回答正確。

 

Gensim的Word2Vec:

Gensim是一個很常用的深度學習topic modeling工具。在編寫,運用方式以及效果上肯定會優於Tensorflow的版本。Gensim的Word2Vec系統在網上有許多教程,這里提供一下兩個供大家參考,解釋的均很不錯,基本屬於可以直接運用的類型:1)http://rare-technologies.com/word2vec-tutorial/ 2)http://www.open-open.com/lib/view/open1420687622546.html

系統的運行結果如下:

在運行時,我們把word_embedding的size設為128, 運行迭代15次。訓練完成模型后,對模型用questions-words.txt文件進行評測:

這份不僅我們觀察到其效果如何,我們更是直觀的了解了gensim的系統在哪些地方表現的不錯,哪里有不足。比如在family這個大類中,所出現的問題為[grandfather grandmother grandpa grandma],系統在這方面正確率頗高,為82%,但是在預測省內的都市時,效果卻僅達到18.1%。 這個直觀的系統讓我們快速了解了word2vec的學習效率以及學習優缺點,但是對於我們常用的問題會做的如何呢?測試結果如下:

由此可見,系統答對了我們詢問的全部問題,雖然問題基數很小,但對比之前的系統,說明gensim做的可以很好,也能更好!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM