入門NLP,找空再來糾正並且補全相關代碼示例。

reference:

1.blog.csdn.net/qq_222385

2.wiki.jikexueyuan.com/pr

3.cnblogs.com/qniguoym/p/

w2v參考文章1

另外一篇是關於Skip-Gram和CBow的介紹。

Skip-Gram&CBOW

邏輯比較清晰的綜述文章:

綜述文章

數學原理很清晰很短的一篇文章(也有關於負採樣的簡單說明)

參考文章

在這些互聯網服務裏,我們經常要比較兩個詞或者兩段文本之間的相關性。為了做這樣的比較,我們往往先要把詞表示成計算機適合處理的方式。詞的向量表徵也稱為word embedding。將word進行向量化,我們最自然的會想到將每個詞被表示成一個實數向量(one-hot vector),其長度為字典大小,每個維度對應一個字典裏的每個詞,除了這個詞對應維度上的值是1,其他元素都是0。One-hot vector雖然自然,但是用處有限。

我們先來看一個問題,假如有一個句子 " the dog bark at the mailman"。用one hot 編碼的方式來表達每個單詞,具體來說。

the : [1,0,0,0,0]

dog : [0,1,0,0,0]

bark: [0,0,1,0,0]

at : [0,0,0,1,0]

mailman:[0,0,0,0,1]

通過one-hot的表達,我們可以將每個單詞用一個向量來表示。但以上表達存在幾個問題:

(1)每個向量之間相互正交的(內積為0)。向量正交意味著無相關性,這也正交意味著詞與詞之間是沒有任何關係的。

(2)每個詞的向量維度和不同詞的個數有關。比方說,在上面的這個句子裏,有5個不同的詞,所以向量的維度是5。然而往往實際應用中,一篇文章的中不同的詞的個數是很多的。這樣,向量的維度會非常的高。

補充:除one-hot模型外,詞向量模型可以是概率模型、共生矩陣(co-occurrence matrix)模型或神經元網路模型。在用神經網路求詞向量之前,傳統做法是統計一個詞語的共生矩陣XX是一個|V|×|V| 大小的矩陣,Xij表示在所有語料中,辭彙表V(vocabulary)中第i個詞和第j個詞同時出現的詞數,|V|為辭彙表的大小。對X做矩陣分解(如奇異值分解,Singular Value Decomposition [5]),得到的U即視為所有詞的詞向量:

但這樣的傳統做法有很多問題:

(1) 由於很多詞沒有出現,導致矩陣極其稀疏,因此需要對詞頻做額外處理來達到好的矩陣分解效果;

(2) 矩陣非常大,維度太高(通常達到10^6?10^6的數量級);

(3) 需要手動去掉停用詞(如although, a,...),不然這些頻繁出現的詞也會影響矩陣分解的效果。

基於神經網路的模型不需要計算存儲一個在全語料上統計的大表,而是通過學習語義信息得到詞向量,因此能很好地解決以上問題。

1.什麼是word2vector?

以one-hot方式將word進行vector化的方法忽略了詞與詞之間的關係(比如說,dog和cat都是動物,並非完全無關係)。維度太高的向量作為模型輸入會導致模型變的複雜(模型複雜需要更多的訓練樣本纔能夠收斂)。那麼是否存在一種更加合理的對詞的用向量的表達方式呢?有的,其實就是word embedding。word embedding簡單來講就是將高維稀疏的向量降維成稠密的低維向量。(一種高維到低維的映射)。

Word2vec是一個用於處理文本的雙層神經網路。它的輸入是文本語料,輸出則是一組向量:該語料中詞語的特徵向量。雖然Word2vec並不是深度神經網路,但它可以將文本轉換為深度神經網路能夠理解的數值形式

2.word2vector怎麼做?

下面總結一下word2vector主要的思想

2.1 Skip-Gram& CBOW

在介紹w2v模型之前,先介紹兩個模型。一個是Skip-Gram和CBOW(Continuous Bag-of-Words)。首先看CBOW,它的做法是,將一個詞所在的上下文中的詞作為輸入,而那個詞本身作為輸出。

再來看Skip-Gram,它的做法和CBOW相反,將一個詞所在的上下文中的詞作為輸出,而詞本身作為輸入。

(下面有例子說明)另外,我們介紹這兩個模型都會涉及到的一個重要參數。

window_size:窗口大小。舉一個例子,還是上面那句話:" the dog bark at the mailman"。假設window_size取1時,利用CBOW模型可以得到:

([the,bark],dog)

([dog,at],bark)

([bark,the],at)

([at,mailman],the)

一共4組數據。同樣的,假設window_size還是1,利用Skip-Gram模型可以得到:

(dog,[the,bark])

(bark,[dog,at])

(at,[bark,the])

(the,[at,mailman])

對於每組數據會稍微做一下處理。比如對於第一組 (dog,[the,bark])一般處理成

(dog,the),(dog,bark)。

類似有:

(bark,dog),(bark,at),(at,bark),(at,the),(the,at),(the,mailman)共8組數據。

2.2 word2vector

下面就可以直接介紹如何進行w2v,上面提到w2v可以看作是一個將高維空間映射到低維空間的過程,用一個單層神經網路就可以實現這種功能(和自編碼器有點類似其實)。對於CBOW,假如還是上面的句子" the dog bark at the mailman",訓練數據是([the,brak],dog)那麼網路的輸入輸出如下圖所示:

這裡有幾個細節:

(1).上面介紹CBOW模型的時有一個模型的結構圖,其中的SUM意思其實就是把各個上下文的詞one-hot後的向量相加。比如對於the的向量是[1,0,0,0,0]。bark向量是[0,0,1,0,0],SUM之後就是[1,0,1,0,0]這就是網路的輸入。輸出就是[0,1,0,0,0],對應-dog

(2).我們所謂的embedding vetcor其實就第二個紅框裏的線,每一根線其實就是一個權值。

(3).第二個框裏的紅線其實就是dog這個單詞的embedding結果(由5維變成3維)

(4).這個單層NN訓練完畢之後有用的部分就是embedding martrix這部分,其大小為 輸入個數(辭彙表長度)×embedding後的維度。

類似對於Skip-Gram模型有:

當取訓練數據(dog,bark)時,網路結構如上圖,對比上面的CBOW最大的不同其實就是在於輸入數據。

2.3 word2vec的大概流程

至此,word2vec中的主要組件都大概提到過一遍,現在應該把它們串起來,大概瞭解一下word2vec的運行流程。

(1) 分詞 / 詞幹提取和詞形還原。 中文和英文的nlp各有各的難點,中文的難點在於需要進行分詞,將一個個句子分解成一個單詞數組。而英文雖然不需要分詞,但是要處理各種各樣的時態,所以要進行詞幹提取和詞形還原。

(2) 構造詞典,統計詞頻。這一步需要遍歷一遍所有文本,找出所有出現過的詞,並統計各詞的出現頻率。

(3) 構造樹形結構。依照出現概率構造Huffman樹。如果是完全二叉樹,則簡單很多,後面會仔細解釋。需要注意的是,所有分類都應該處於葉節點,像下圖顯示的那樣[4]

(4)生成節點所在的二進位碼。拿上圖舉例,22對應的二進位碼為00,而17對應的是100。也就是說,這個二進位碼反映了節點在樹中的位置,就像門牌號一樣,能按照編碼從根節點一步步找到對應的葉節點。

(5) 初始化各非葉節點的中間向量和葉節點中的詞向量。樹中的各個節點,都存儲著一個長為m的向量,但葉節點和非葉結點中的向量的含義不同。葉節點中存儲的是各詞的詞向量,是作為神經網路的輸入的。而非葉結點中存儲的是中間向量,對應於神經網路中隱含層的參數,與輸入一起決定分類結果。

(6) 訓練中間向量和詞向量。對於CBOW模型,首先將詞A附近的n-1個詞的詞向量相加作為系統的輸入,並且按照詞A在步驟4中生成的二進位碼,一步步的進行分類並按照分類結果訓練中間向量和詞向量。舉個栗子,對於綠17節點,我們已經知道其二進位碼是100。那麼在第一個中間節點應該將對應的輸入分類到右邊。如果分類到左邊,則表明分類錯誤,需要對向量進行修正。第二個,第三個節點也是這樣,以此類推,直到達到葉節點。因此對於單個單詞來說,最多隻會改動其路徑上的節點的中間向量,而不會改動其他節點。


推薦閱讀:
相關文章