入門|神經網絡詞嵌入:如何將《戰爭與和平》表示成一個向量?

選自 Towards Data Science

作者:

William Koehrsen

機器之心編譯

參與:Panda

深度學習可以怎樣將《戰爭與和平》表示成一個向量?藉助神經網絡嵌入就能實現。神經網絡嵌入是很多機器學習語言處理應用的基礎性技術之一,Feature Labs 的數據科學家 William Koehrsen 通過一個基於維基百科的書籍推薦項目對詞嵌入進行了介紹。

項目地址:https://github.com/WillKoehrsen/wikipedia-data-science/blob/master/notebooks/Book%20Recommendation%20System.ipynb

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

最近幾年,神經網絡的應用範圍已經從圖像分割顯著擴展到了自然語言處理以及時間序列預測領域。深度學習一大顯著成功的用途是嵌入(embedding),這是一種可用於將離散變量表示成連續向量的方法。這項技術的實際應用包括用於機器翻譯的詞嵌入和用於類別變量的實體嵌入。

在這篇文章中,我將解釋神經網絡嵌入的定義,我們使用它們的原因,以及它們的學習方式。我將在我正在研究的一個真實問題的背景中介紹這些概念:將維基百科上的所有書籍都表示成向量以創建一個書籍推薦系統。

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

維基百科上所有書籍的神經網絡嵌入

嵌入

嵌入是離散的(類別化的)變量向連續數值向量的映射。在神經網絡語境中,嵌入是離散變量的低維度的學習得到的連續向量表示。神經網絡嵌入很有用,因為它們可以降低類別化變量的維度以及能夠在變換後的空間中有意義地表示類別。

神經網絡嵌入有三個主要用途:

  1. 尋找嵌入空間中的最近鄰。這可被用於基於用戶興趣或聚類類別來進行推薦;

  2. 可作為機器學習模型的輸入來學習監督式任務;

  3. 可實現概念和類別之間的關係的可視化。

對於我們的書籍項目,這就意味著我們可以使用神經網絡嵌入將維基百科上的 37000 篇書籍文章都各自表示成一個僅具有 50 個數字的向量。此外,因為嵌入是學習得到的,所以對於我們的學習問題而言,更相似的書籍在這個嵌入空間中具有更接近的位置。

神經網絡嵌入能夠克服常用的類別變量表示方法 one-hot 編碼的兩大侷限。

one-hot 編碼的侷限

one-hot 編碼的類別變量的操作實際上是一種簡單的嵌入,其中每個類別都被映射成了不同的向量。其過程是將離散的實體的每個觀察都映射成由一定數量的 0 和單個 1 構成的向量,這個 1 指示了特定的類別。

one-hot 編碼技術具有兩大主要缺陷:

  1. 對於高基數變量(即有很多特有類別的變量),變換得到的向量的維度將難以掌控。

  2. 這種映射方式信息完全不充分:「近似」的類別在嵌入空間中並不處於相近的位置。

第一個問題很容易理解:每增加一個類別(成為實體),我們都必須為 one-hot 編碼的向量增加一個數。如果我們有維基百科上的 37000 本書,那麼表示它們就將需要 37000 維的向量,基於這種表示方式訓練任何機器學習模型都難以實現。

第二個問題具有同等的侷限性:one-hot 編碼並不會將相似的實體放在向量空間中相近的位置。如果使用餘弦距離來衡量向量之間的相似性,那麼在經過 one-hot 編碼後,每一對比較的實體之間的相似度都是零。

這意味著,如果我們使用 one-hot 編碼,《戰爭與和平》與《安娜·卡列尼娜》這樣的實體(都是列夫·托爾斯泰的經典著作)不會比《戰爭與和平》與《銀河系漫遊指南》之間的距離更近。

# One Hot Encoding Categoricals
books = ["War and Peace", "Anna Karenina",
"The Hitchhiker's Guide to the Galaxy"]
books_encoded = [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
Similarity (dot product) between First and Second = 0
Similarity (dot product) between Second and Third = 0
Similarity (dot product) between First and Third = 0

考慮到這兩個問題,則表示類別變量的理想方案是數字量比特有類別的數量更少,而且相似的類別能具有更近的距離。

# Idealized Representation of Embedding
books = ["War and Peace", "Anna Karenina",
"The Hitchhiker's Guide to the Galaxy"]
books_encoded_ideal = [[0.53, 0.85],
[0.60, 0.80],
[-0.78, -0.62]]
Similarity (dot product) between First and Second = 0.99
Similarity (dot product) between Second and Third = -0.94
Similarity (dot product) between First and Third = -0.97

為了構建一種更好的類別實體表徵,我們可以使用嵌入神經網絡和學習嵌入的監督式網絡。

學習嵌入

one-hot 編碼的主要問題是其變換並不依賴於任何監督。通過在一個監督任務上使用神經網絡來學習它們,我們可以對嵌入實現極大的提升。這些嵌入會構成網絡的參數(權重),這些參數會得到調整以最小化在任務上的損失。所得到的嵌入向量是類別的表徵,其中相似的任務(相對任務而言)的距離更近。

舉個例子,如果我們有一個包含 50000 個詞的電影評論彙集的詞彙庫,我們可以使用一個嵌入神經網絡來為每個詞學習 100 維的嵌入,訓練目的是預測這些評論的情緒。(這個應用的詳情請參閱:https://goo.gl/6rxG11)在這個詞彙庫中,「出色」和「很贊」這樣積極的評論詞會處於嵌入空間中更近的位置,因為網絡已經學習到這些詞都與積極評論相關。

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

電影情緒詞嵌入

在上面提到的書籍案例中,我們的監督式任務會變成「識別一本書是否是列夫·托爾斯泰寫的」,而由列夫·托爾斯泰寫的書的嵌入會更近。找到如何創建監督式任務以得出相關表徵的方法是嵌入設計中最困難的部分。

實現

在維基百科書籍項目中,監督學習任務的目標是預測給定維基百科頁面的鏈接是否出現在了描述某本書的文章中。我們輸入的數據是包含正例和負例的訓練樣本對(書籍題目,鏈接)。這種設置方式基於這樣一個假設:鏈接到相似維基百科頁面的書籍彼此更加相似。因此所得到的嵌入也應該在向量空間中將相似的數據放置在更相近的位置。

我使用的網絡有兩個並行的嵌入層,它們會將書籍和維基鏈接分別映射成 50 維的向量,另外還有一個點積層將這些嵌入結合成單個數值以供預測。這些嵌入是網絡的參數,或者說權重,可以在訓練過程中調整以最小化在該監督式任務上的損失。

用 Keras 代碼表示就像是下面這樣(看不懂代碼也不要緊,可以直接跳過去看後面的圖片):

# Both inputs are 1-dimensional
book = Input(name = 'book', shape = [1])
link = Input(name = 'link', shape = [1])

# Embedding the book (shape will be (None, 1, 50))
book_embedding = Embedding(name = 'book_embedding',
input_dim = len(book_index),
output_dim = embedding_size)(book)

# Embedding the link (shape will be (None, 1, 50))
link_embedding = Embedding(name = 'link_embedding',
input_dim = len(link_index),
output_dim = embedding_size)(link)

# Merge the layers with a dot product along the second axis (shape will be (None, 1, 1))
merged = Dot(name = 'dot_product', normalize = True, axes = 2)([book_embedding, link_embedding])

# Reshape to be a single number (shape will be (None, 1))
merged = Reshape(target_shape = [1])(merged)

# Output neuron
out = Dense(1, activation = 'sigmoid')(merged)
model = Model(inputs = [book, link], outputs = out)

# Minimize binary cross entropy
model.compile(optimizer = 'Adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

儘管監督式機器學習任務的目標通常是訓練一個模型來在新數據上進行預測,但在這個嵌入模型中,預測本身僅僅是實現最終目的的一種方式。我們想要的是嵌入權重,即作為連續向量的書籍和鏈接表示。

嵌入本身並不是那麼有趣:它們都只是些數值的向量:

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

來自書籍推薦嵌入模型的嵌入示例

但是,這些嵌入也可被用於之前列出的三個目的;對於這個項目,我們主要感興趣的是基於最近鄰推薦書籍。為了計算相似度,我們取一個查詢書籍,然後得出其向量與所有其它書籍的向量之間的點積。(如果我們的嵌入經過了歸一化,那麼這個點積就是向量之間的餘弦距離,其範圍從最不相似的 -1 到最相似的 +1。我們也可以使用歐幾里德距離來衡量相似度。)

下面給出了我構建的書籍嵌入模型的輸出結果:

Books closest to War and Peace.
Book: War and Peace Similarity: 1.0
Book: Anna Karenina Similarity: 0.79
Book: The Master and Margarita Similarity: 0.77
Book: Doctor Zhivago (novel) Similarity: 0.76
Book: Dead Souls Similarity: 0.75

(一個向量與其自身的餘弦相似度肯定是 1.0)。經過一定的降維之後,我們可以得到下面的圖像:

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

與最近鄰一起的嵌入書籍

我們可以清楚地看到學習嵌入的價值!現在,對於維基百科上的每一本書,我們都有一個 50 數字的表示,其中更相似的書籍也彼此更接近。

嵌入可視化

嵌入最值得關注的一大優勢是它們可被用於概念的可視化,比如小說與非小說之間的相對性。這需要進一步的降維技術將維度降至二或三維。最流行的降維技術本身也是一種嵌入方法:t-分佈隨機近鄰嵌入(TSNE)。

我們可以使用神經網絡嵌入將維基百科上所有書籍的 37000 個原始維度映射成 50 維,然後再使用 TSNE 將其映射成二維。結果如下:

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

維基百科上所有 37000 本書的嵌入

(TSNE 是一種流形學習技術,也就是說它會試圖將高維數據映射成更低維度的流形,這個過程中會創建一個嵌入來維持數據中的局部結構。這基本上只在可視化時使用,因為其輸出是隨機的,不支持轉換成新數據。另一種正在迅猛發展的新方法是統一流形近似和投影/UMAP,它的速度要快得多,而且也支持轉換成嵌入空間中的新數據。)

這些可視化本身並不非常有用,但如果我們根據不同的書籍類型給它加上顏色,就能看出一些見解了。

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

根據書籍類型上色後的嵌入

可以清楚看到,書籍根據各自不同的類型聚集在了一起。這並不完美,但仍然讓人印象深刻,畢竟我們僅用 2 個數字就表示了維基百科上的所有書籍,而且這種表示方法還能展現出不同類型之間的差異。

這個書籍項目示例表明了神經網絡嵌入的價值:我們能得到分類目標的向量表示,這個向量表示是低維的,並且相似的實體在嵌入空間中處於相近的位置。

額外獎勵:交互式可視化

靜態圖表的問題是我們不能真正地探索數據以及研究變量之間的分組和關係。為了解決這個問題,TensorFlow 開發了 projector:https://projector.tensorflow.org/,這是一個讓我們可以可視化嵌入並與之交互的在線應用。我後面會寫一篇文章介紹使用這一工具的方法,但這裡我們看看結果就好:

入门|神经网络词嵌入:如何将《战争与和平》表示成一个向量?

使用 projector 實現對書籍嵌入的交互式探索

總結

神經網絡嵌入是學習到的離散數據的低維連續向量表示。這些嵌入克服了傳統編碼方法的侷限,並可被用於尋找最近鄰、作為另一個模型的輸入以及可視化等目的。

儘管本文用一些學術術語談到了很多深度學習概念,但神經網絡嵌入很直觀而且實現方法也相對簡單。我確信任何人都可以學會深度學習,並且使用 Keras 這樣的庫來構建深度學習解決方案。嵌入是一種能有效處理離散變量的工具,是深度學習的一個很有價值的應用。入門|神經網絡詞嵌入:如何將《戰爭與和平》表示成一個向量?

資源

  • 谷歌的嵌入教程:https://developers.google.com/machine-learning/crash-course/embeddings/video-lecture

  • TensorFlow 的嵌入指南:https://www.tensorflow.org/guide/embedding

  • 使用嵌入的書籍推薦系統:https://github.com/WillKoehrsen/wikipedia-data-science/blob/master/notebooks/Book%20Recommendation%20System.ipynb

  • Keras 詞嵌入教程:https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/

原文鏈接:https://towardsdatascience.com/neural-network-embeddings-explained-4d028e6f0526

✄------------------------------------------------

加入機器之心(全職記者 / 實習生):[email protected]

投稿或尋求報道:content@jiqizhixin.com

廣告 & 商務合作:[email protected]


分享到:


相關文章: