04 GloVe詞向量使用介紹及思考

04 GloVe詞向量使用介紹及思考

來自專欄 用PyTorch進行自然語言處理

本文開始兩段和末尾「思考」部分屬於原創,其餘部分為對網路內容的翻譯。

在上一講的最後我們提到了一個應用循環神經網路進行字元處理時遇到大字符集時one-hot詞向量技術會碰到的特徵數過多的災難。其實基於one-hot技術的詞向量表示方法還有一個缺點就是,詞與詞之間的關係不能通過向量值來體現,這對於非常講究特徵提取的神經網路技術而來無異於是一個不和諧因素。

本文我們將介紹另外一類較先進的詞向量表示方式,這種表示方式下表示每一個詞的特徵數不在隨著詞語集的增大而增大,可以限定為一個特定大小,同時通過計算向量關係可以判斷詞與詞之間的關係,得到一些有趣也有實際意義的結果。通過這種技術得到的關於某一辭彙集中所有詞語的向量表達則稱為基於某技術產生的詞向量,其本質是一個矩陣,每一行代表一個詞,每一列代表的關於詞語的某一個特徵值。詞向量可以替代one-hot向量作為神經網路的輸入。詞向量有好壞之分,好的詞向量能夠更準確的反映詞與詞之間實際的關係;而一個不是很好的詞向量則在這方面可能表現不盡如人意。在PyTorch中,nn.Embedding模塊充當著把一個one-hot詞向量轉化為指定特徵數詞向量的任務,但是為完成特定任務搭建的網路中所包含的nn.Embedding模塊代表的詞向量僅適用於網路碰到過的輸入辭彙,不具備全局普適性,同時也有很大的偏倚。要得到一個基於某一語言所有辭彙的好的詞向量則是一個非常耗時的過程,他同樣需要使用神經網路來訓練。如果手上有一個已經訓練好的基於全局辭彙的詞向量的話,那麼將會是非常美好的一件事情,GloVe就是這樣的一個詞向量。

GloVe的全稱是:Global Vectors for Word Representation,字面翻譯為:全局的詞向量表示。此處有關於此詳細的介紹和大量資源。本文將不介紹該詞向量是如何具體得到的,僅簡單描述下如何使用此詞向量,以及展示它的一些有趣的現象後本人的思考。

推薦閱讀

  • blog.acolyer.org/2016/0
  • blog.acolyer.org/2016/0
  • levyomer.wordpress.com/

安裝torchtext

我們仍然使用PyTorch庫,使用下面的命令來安裝詞向量。

git clone https://github.com/pytorch/text pytorch-textcd pytorch-textpython setup.py install

載入詞向量

通過下面的代碼載入詞向量,該方法將從nlp.stanford.edu/data/ 直接下載和解壓詞向量:

import torchfrom torchtext.vocab import load_word_vectorswv_dict, wv_arr, wv_size = load_word_vectors(., glove.6B, 100)print(Loaded, len(wv_arr), words)

如果您在執行此段代碼中發生錯誤,請留一下錯誤類型,大多數為缺乏一些庫,在您的Python環境中安裝對應的庫應該能解決問題。正確運行此段代碼會輸出:

loading word vectors from ./glove.6B.100d.ptLoaded 400000 wordsload_word_vectors returns a dictionary of words to indexes, and an array of actual vectors. To get a word vector get the index to get the vector:

顯示了下載的詞向量類型,該詞向量里一共有多少單詞,詞向量是一個從單詞到向量映射的字典。

下面的方法獲取一個單詞的向量值:

def get_word(word): return wv_arr[wv_dict[word]]

尋找與指定單詞關係最近的若干個單詞

通過計算兩個向量之間的歐氏距離或者兩個向量的夾角,我們可以發現一些有趣且符合常理的現象。下面的方法給出了與某一個單詞關係最近的若干單詞:

def closest(d, n=10): all_dists = [(w, torch.dist(d, get_word(w))) for w in wv_dict] return sorted(all_dists, key=lambda t: t[1])[:n]def print_tuples(tuples): for tuple in tuples: print((%.4f) %s % (tuple[1], tuple[0]))print_tuples(closest(get_word(google)))

輸出如下:

(0.0000) google(3.0772) yahoo(3.8836) microsoft(4.1048) web(4.1082) aol(4.1165) facebook(4.3917) ebay(4.4122) msn(4.4540) internet(4.4651) netscape

上段代碼表明,在GloVe詞向量里,與單詞「google」關係最近的幾個辭彙,左側的數字顯示是對應單詞與「google」之間的距離。需要指出的是,這個距離的具體數值與是用什麼語料庫訓練得到的詞向量有密切關係。不同的語料庫訓練得到的詞向量得到的結果可以是差別很大的。

使用向量計算進行辭彙推理

另一個有趣的現象是,對一些詞的向量進行簡單的運算產生的結果對應了一個新的詞,舉例如下:

如果我把單詞」king「對應的向量與單詞」man」對應的向量相減,再加上「woman"對應的向量,則得到的數值會代表單詞「queen」。可以通過如下代碼來具體演示:

# In the form w1 : w2 :: w3 : ?def analogy(w1, w2, w3, n=5, filter_given=True): print(
[%s : %s :: %s : ?] % (w1, w2, w3)) # w2 - w1 + w3 = w4 closest_words = closest(get_word(w2) - get_word(w1) + get_word(w3)) # Optionally filter out given words if filter_given: closest_words = [t for t in closest_words if t[0] not in [w1, w2, w3]] print_tuples(closest_words[:n])analogy(king, man, queen)

輸出如下:

[king : man :: queen : ?](4.0811) woman(4.6916) girl(5.2703) she(5.2788) teenager(5.3084) boy

該例子表明,「一個國王如果不是男性而是女性,那麼她很可能是王后「。這可以認為是知識的推理,使用的是簡單的向量加減。

總算翻譯了一片短文。至於詞向量是如何生成的,有興趣的讀者可以閱讀相關文獻,知乎上也有人對此做了詳細的解釋。

思考

有沒有人把這個簡單向量加減的方法推廣到矩陣變換呢?也就是說如果我們不是使用的簡單的向量加減,而是使用一個經過訓練過的矩陣變換其得到的結果怎樣?會不會產生更有意思的結果呢?個人對此持樂觀態度,這很有可能是推理(基於知識的決策)的網路表示。不過這裡知識不是表示在詞向量中,而是表示在變換矩陣中,變換矩陣就是神經網路中層的概念,也可以以一個單獨的簡單神經網路來表示,詞向量(乃至一個時序數據張量)則是這個訓練好的網路的輸入,這樣的一個變換矩陣(層,或網路)代表著一個決策功能,而大腦複雜綜合的決策很有可能就基於許許多多這樣的基本的變換矩陣(層,甚至是一個小網路)的。如何訓練這樣一個矩陣(層、或網路)?個人認為可以使用類似訓練生成詞向量的網路的模式來訓練得到這樣的知識推理矩陣(層,或網路)。如果沒有人對此進行研究,這是一個非常值得研究的課題,在此立下這個idea;如果已經有人知道已有相關研究,可否在評論區貼上論文鏈接。


推薦閱讀:

本周知乎熱門視頻 | 教你48小時製作一條旅行短片
怎麼做好知識類的選題?
不靠美女,3天100萬個付費用戶,有一個顛覆性的黑魔法
老中醫是咋知道姑娘有喜的?
鹽源南紅知識大全!速來搜羅!

TAG:知識 | PyTorch | 自然語言處理 |