基於Doc2vec訓練句子向量

基於Doc2vec訓練句子向量

一. Doc2vec原理

前文總結了Word2vec訓練詞向量的細節,講解了一個詞是如何通過word2vec模型訓練出唯一的向量來表示的。那接著可能就會想到,有沒有什麼辦法能夠將一個句子甚至一篇短文也用一個向量來表示呢?答案是肯定有的,構建一個句子向量有很多種方法,今天我們接著word2vec來介紹下Doc2vec,看下Doc2vec是怎麼訓練一個句子向量的。

許多機器學習算法需要的輸入是一個固定長度的向量,當涉及到短文時,最常用的固定長度的向量方法是詞袋模型(bag-of-words)。儘管它很流行,但是詞袋模型存在兩個主要的缺點:一個是詞袋模型忽略詞序,如果兩個不同的句子由相同的詞但是順序不同組成,詞袋模型會將這兩句話定義為同一個表達;另一個是詞袋模型忽略了句法,這樣訓練出來的模型會造成類似'powerful','strong'和'Paris'的距離是相同的,而其實'powerful'應該相對於'Paris'距離'strong'更近才對。

Doc2vec又叫Paragraph Vector是Tomas Mikolov基於word2vec模型提出的,其具有一些優點,比如不用固定句子長度,接受不同長度的句子做訓練樣本,Doc2vec是一個無監督學習算法,該算法用於預測一個向量來表示不同的文檔,該模型的結構潛在的克服了詞袋模型的缺點。

Doc2vec模型是受到了word2vec模型的啟發,word2vec裡預測詞向量時,預測出來的詞是含有詞義的,比如上文提到的詞向量'powerful'會相對於'Paris'離'strong'距離更近,在Doc2vec中也構建了相同的結構。所以Doc2vec克服了詞袋模型中沒有語義的去缺點。假設現在存在訓練樣本,每個句子是訓練樣本。和word2vec一樣,Doc2vec也有兩種訓練方式,一種是PV-DM(Distributed Memory Model of paragraphvectors)類似於word2vec中的CBOW模型,如圖一:

基於Doc2vec訓練句子向量

圖一

另一種是PV-DBOW(Distributed Bag of Words of paragraph vector)類似於word2vec中的skip-gram模型,如圖二:


基於Doc2vec訓練句子向量

圖二

在Doc2vec中,每一句話用唯一的向量來表示,用矩陣D的某一列來代表。每一個詞也用唯一的向量來表示,用矩陣W的某一列來表示。以PV-DM模型為例,如圖三:

基於Doc2vec訓練句子向量

圖三

每次從一句話中滑動採樣固定長度的詞,取其中一個詞作預測詞,其他的作輸入詞。輸入詞對應的詞向量word vector和本句話對應的句子向量Paragraph vector作為輸入層的輸入,將本句話的向量和本次採樣的詞向量相加求平均或者累加構成一個新的向量X,進而使用這個向量X預測此次窗口內的預測詞。

Doc2vec相對於word2vec不同之處在於,在輸入層,增添了一個新句子向量Paragraph vector,Paragraph vector可以被看作是另一個詞向量,它扮演了一個記憶,詞袋模型中,因為每次訓練只會截取句子中一小部分詞訓練,而忽略了除了本次訓練詞以外該句子中的其他詞,這樣僅僅訓練出來每個詞的向量表達,句子只是每個詞的向量累加在一起表達的。正如上文所說的詞袋模型的缺點,忽略了文本的詞序問題。而Doc2vec中的Paragraph vector則彌補了這方面的不足,它每次訓練也是滑動截取句子中一小部分詞來訓練,

Paragraph Vector在同一個句子的若干次訓練中是共享的,所以同一句話會有多次訓練,每次訓練中輸入都包含Paragraph vector。它可以被看作是句子的主旨,有了它,該句子的主旨每次都會被放入作為輸入的一部分來訓練。這樣每次訓練過程中,不光是訓練了詞,得到了詞向量。同時隨著一句話每次滑動取若干詞訓練的過程中,作為每次訓練的輸入層一部分的共享Paragraph vector,該向量表達的主旨會越來越準確。Doc2vec中PV-DM模型具體的訓練過程和word2vec中的CBOW模型訓練方式相同,在之前我寫的基於Word2vec訓練詞向量(一)裡有詳細介紹,這裡就不在重複。

訓練完了以後,就會得到訓練樣本中所有的詞向量和每句話對應的句子向量,那麼Doc2vec是怎麼預測新的句子Paragraph vector呢?其實在預測新的句子的時候,還是會將該Paragraph vector隨機初始化,放入模型中再重新根據隨機梯度下降不斷迭代求得最終穩定下來的句子向量。不過在預測過程中,模型裡的詞向量還有投影層到輸出層的softmax weights參數是不會變的,這樣在不斷迭代中只會更新Paragraph vector,其他參數均已固定,只需很少的時間就能計算出帶預測的Paragraph vector。

二. 代碼實現

在python中使用gensim包調用Doc2vec方便快捷,在這簡單演示下,gensim下Doc2vec詳細的參數不在此詳細闡述。本次的數據是之前比賽中公開的旅遊數據集,裡邊每一條都是遊客對於景點的評價。具體的Doc2vec訓練Paragraph vector步驟如下:

1) 導包:導入必要的包,其中的jieba是為了給文本進行分詞。

基於Doc2vec訓練句子向量

2) 導入數據集,提取Discuss列(該列是用戶評價的內容)。

基於Doc2vec訓練句子向量

基於Doc2vec訓練句子向量

3) 將提取好的Discuss列中的內容進行分詞,並去除停用詞。

基於Doc2vec訓練句子向量

4) 改變成Doc2vec所需要的輸入樣本格式,由於gensim裡Doc2vec模型需要的輸入為固定格式,輸入樣本為:[句子,句子序號],這裡需要用gensim中Doc2vec裡的TaggedDocument來包裝輸入的句子。

基於Doc2vec訓練句子向量


基於Doc2vec訓練句子向量

5) 加載Doc2vec模型,並開始訓練。

基於Doc2vec訓練句子向量

6) 模型訓練完畢以後,就可以預測新的句子的向量Paragraph vector了,這裡用gensim裡Doc2Vec.infer_vector()預測新的句子,這裡根據經驗,alpha(學習步長)設置小一些,迭代次數設置大一些。找到訓練樣本中與這個句子最相近的10個句子。可以看到訓練出來的結果與測試的新句子是有關聯的。

基於Doc2vec訓練句子向量


基於Doc2vec訓練句子向量

三. 總結

Doc2vec是基於Word2vec基礎上構建的,相比於Word2vec,Doc2vec不僅能訓練處詞向量還能訓練處句子向量並預測新的句子向量。Doc2vec模型結構相對於Word2vec,不同點在於在輸入層上多增加了一個Paragraph vector句子向量,該向量在同一句下的不同的訓練中是權值共享的,這樣訓練出來的Paragraph vector就會逐漸在每句子中的幾次訓練中不斷穩定下來,形成該句子的主旨。這樣就訓練出來了我們需要的句子向量。在預測新的句子向量時,是需要重新訓練的,此時該模型的詞向量和投影層到輸出層的soft weights參數固定,只剩下Paragraph vector用梯度下降法求得,所以預測新句子時雖然也要放入模型中不斷迭代求出,相比於訓練時,速度會快得多。本次使用的數據集為情感分析,且大多數樣本偏向於好評,樣本內容比較單一,所以訓練出來的結果都是偏向於哪裡好玩,好不好這類的意思,對於一些特定的問題之類的句子準確性還沒有驗證,目前用於情感分析還是可以的。下次會嘗試使用新的數據集,調試參數看是否會取得更好的結果。


對深度學習感興趣,熱愛Tensorflow的小夥伴,歡迎關注我們的網站http://www.panchuang.net 我們的公眾號:磐創AI。


分享到:


相關文章: