{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Word2vec 詞嵌入 (word embeddings) 的基本概念\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![word2vec](https://cdn-images-1.medium.com/max/2000/1*0roG7_LinNzvVm7Bfb8tkA.jpeg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 什麼是Word2vec?\n", "\n", "一般進行NLP(自然語言處理)時,資料最小的細粒度是語詞(word),語詞組成句子,句子再組成句子,篇章,文檔。所以很多處理NLP的問題的前處理程序,首先就要思考語詞(word)的處理。\n", "\n", "舉個簡單的例子,判斷一個詞的詞性,是動詞還是名詞。用機器學習的思路,我們有一系列樣本(x,y),這裡x是語詞,y是它們的詞性,我們要構建f(x) -> y的映射,但這裡的數學模型f(比如神經網絡,SVM)只接受數值型輸入,而NLP裡的語詞,是人類的語言抽象表示,是以符號形式來表現的(比如中文,英文,拉丁文等等),所以需要把他們轉換成數值形式,或者說\"嵌入\"到一個數學空間裡,這種嵌入方式,就叫\"詞嵌入(word embedding)\",而Word2vec,就是詞嵌入(word embedding)的一種作法。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在NLP中,把x看做一個句子裡的一個語詞,y是這個語詞的上下文(context)語詞,那麼這裡的f,便是NLP中經常出現的「語言模型」(language model),這個模型的目的,就是判斷(x,y)這個樣本,是否符合自然語言的法則,更通俗點說是:語詞x和語詞y放在一起時,像不像是人寫的話或寫的句子。\n", "\n", "Word2vec正是來自於這個想法,但它的最終目的,不是要把f訓練得多麼完美,而是關心模型訓練完後的副產物-\"模型參數\"(這里指的是神經網絡的權重),並將這些參數,作為輸入x的某種向量化的表示,這個向量便叫做\"詞向量(word vector)\"。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "我們來看個例子,如何用Word2vec尋找相似詞:\n", "\n", "對於一句話:「她們誇二哥帥到沒朋友」,如果輸入x是「二哥」,那麼y可以是「她們」,「誇」,「帥」,「沒朋友」這些詞。\n", "\n", "現有另一句話:「她們誇我帥到沒朋友」,如果輸入x是「我」,那麼不難發現,這裡的上下文y跟上面一句話一樣\n", "從而f(二哥) = f(我) = y,所以大數據告訴我們:我 = 二哥(完美的結論)。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Skip-gram 和 CBOW (Continuous Bag of Words) 模型\n", "\n", "上面我們提到了語言模型(Languate model):\n", "* 如果是用一個語詞作為輸入,來預測它周圍的上下文,那這個模型叫做「Skip-gram模型」, 比如: 二哥 [?][?]\n", "![](https://cdn-images-1.medium.com/max/1600/1*F25MNJGsg3MeYOAbhMWXgw.jpeg)\n", "![](https://cdn-images-1.medium.com/max/1600/1*zwZrTEzE_T_mp88qSZutAw.jpeg)\n", "\n", "* 如果是拿一個語詞的上下文作為輸入,來預測這個詞語本身,則是「CBOW模型」, 比如: 誇 [?] 帥\n", "\n", "![](https://cdn-images-1.medium.com/max/1600/1*IqB2yIU3GymmkFwoG-I23Q.jpeg)\n", "![](https://cdn-images-1.medium.com/max/1600/1*bJXCWnLjWrYz6m45EBxtYw.jpeg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "我們先來看個最簡單的例子。上面說到,y是x的上下文,所以y只取上下文裡一個語詞(word)的時候,語言模型就變成:\n", "\n", ">用當前語詞 x 預測它的下一個語詞 y\n", "\n", "但如上面所說,一般的數學模型只接受數值型輸入,這裡的x該怎麼表示呢?顯然不能用Word2vec,因為這是我們訓練完模型的產物,現在我們想要的是x的一個原始輸入形式。\n", "\n", "答案是:__one-hot encoder__\n", "\n", "OK,那我們接下來就可以看看Skip-gram的網絡結構了,x就是上面提到的one-hot encoder形式的輸入,y是在這V個詞上輸出的概率,我們希望跟真實的y的one-hot編碼結果一樣。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![skip-gram](https://pic4.zhimg.com/80/v2-a1a73c063b32036429fbd8f1ef59034b_hd.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "首先說明一點:隱藏層的激活函數(activation function)其實是\"線性\"的,相當於沒做任何處理(這也是Word2vec簡化之前其它語言模型的獨到之處),我們要訓練這個神經網絡,用反向傳播算法。\n", "\n", "當模型訓練完後,最後得到的其實是神經網絡的權重,比如現在輸入一個x的one-hot encoder:[1,0,0,...,0],對剛剛說的那個詞語「二哥」,則在輸入層到隱藏層的權重裡,只有對應1這個位置的權重被激活,這些權重的個數,跟隱藏層節點數是一致的,從而這些權重組成一個向量vx來表示x,而因為每個語詞的one-hot encoder裡面1的位置是不同的,所以,這個向量vx就可以用來唯一表示x。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "輸出y也是用V個節點表示的,對應V個語詞,所以其實,我們把輸出節點置成[1,0,0,…,0],它也能表示『二哥』這個單詞,但是激活的是隱含層到輸出層的權重,這些權重的個數,跟隱含層一樣,也可以組成一個向量vy,跟上面提到的vx 維度一樣,並且可以看做是語詞『二哥』的另一種詞向量。而這兩種詞向量 vx 和 vy,正是 Mikolov 在論文裡所提到的,『輸入向量』和『輸出向量』,一般我們用『輸入向量』。\n", "\n", "需要提到一點的是,這個詞向量的維度(與隱藏層節點數一致)一般情況下要遠遠小於語詞總數V的大小,所以Word2vec本質上是一種降維操作(把語詞從one-hot encoder形式的表示降維到Word2vec形式的表示)。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Skip-gram 更一般的情形\n", "\n", "上面討論的是最簡單情形,即y只有一個詞,如果y有多個詞的時候,網絡結構如下:\n", "\n", "![skip-gram2](https://pic2.zhimg.com/80/v2-ca81e19caa378cee6d4ba6d867f4fc7c_hd.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ">可以看成是 單個x -> 單個y 模型的並聯,cost function 是單個 cost function 的累加(取log之後)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CBOW 更一般的情形\n", "\n", "跟 Skip-gram 相似,只不過:\n", ">Skip-gram 是預測一個詞的上下文,而 CBOW 是用上下文預測這個詞\n", "\n", "網絡結構如下:\n", "\n", "![cbow](https://pic3.zhimg.com/80/v2-d1ca2547dfb91bf6a26c60782a26aa02_hd.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "與 Skip-gram 模型的並聯不同,這裡是輸入變成了多個單詞,所以要對輸入進行前處理(一般是求和然後平均)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "很多時候,當我們面對林林總總的模型與方法時,我們總希望總結出一些本質且共通性的東西,以構建我們的知識體系,比如在詞嵌入(word embeddings)的領域,除了Word2vec之外,還有基於共現矩陣分解的GloVe等等詞嵌入方法。\n", "\n", "深入進去我們會發現,神經網絡形式表示的模型(如Word2vec),跟共現矩陣分解模型(如GloVe),有理論上的相通性,所以在實際應用當中,這兩者的差別並不算很大,尤其是在其中高級別的NLP任務(如句子表示,命名體識別,文檔表示)當中,經常把\"詞向量\"作為原始輸入。\n", "\n", "鑑於語詞是NLP裡最細粒度的表達,所以\"詞向量\"的應用很廣泛,既可以執行詞語層面的任務,也可以作為很多模型的輸入,執行高級如句子,文檔層面的任務,包括但不限於:\n", "\n", "* 計算相似度\n", " * 尋找相似詞\n", " * 信息檢索\n", "\n", "\n", "* 作為SVM / LSTM等模型的輸入\n", " * 中文分詞\n", " * 命名體識別\n", "\n", "\n", "* 句子表示\n", " * 情感分析\n", "\n", "\n", "* 文檔表示\n", " * 文檔主題判別" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 參考:\n", "* [Distributed Representations of Sentences and Documents](https://arxiv.org/abs/1405.4053)\n", "* [Efficient Estimation of Word Representations in Vector Space](https://arxiv.org/abs/1301.3781)\n", "* [Xin Rong 的论文:『word2vec Parameter Learning Explained』](https://arxiv.org/abs/1411.2738)\n", "* [秒懂词向量Word2vec的本质](https://zhuanlan.zhihu.com/p/26306795)\n", "* [Word2Vec (Part 1)](https://hackernoon.com/word2vec-part-1-fe2ec6514d70)\n", "* [類神經網路 -- word2vec (part 1 : Overview)](http://cpmarkchang.logdown.com/posts/773062-neural-network-word2vec-part-1-overview)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.4" } }, "nbformat": 4, "nbformat_minor": 2 }