當前位置:
首頁 > 科技 > 入門 | 神經網路詞嵌入:如何將《戰爭與和平》表示成一個向量?

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


選自 T

owards 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






本文為機器之心編譯,

轉載請聯繫本公眾號獲得授權



?------------------------------------------------


加入機器之心(全職記者 / 實習生):hr@jiqizhixin.com


投稿或尋求報道:

content

@jiqizhixin.com


廣告 & 商務合作:bd@jiqizhixin.com

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

「多巴胺」來襲!兼具易用性和復現性的新型強化學習框架Dopamine
業界 | 從語音到金融:鄧力的人工智慧30年

TAG:機器之心 |