天天看點

基于Doc2vec訓練句子向量

目錄

一.Doc2vec原理

二.代碼實作

三.總結

前文總結了Word2vec訓練詞向量的細節,講解了一個詞是如何通過word2vec模型訓練出唯一的向量來表示的。那接着可能就會想到,有沒有什麼辦法能夠将一個句子甚至一篇短文也用一個向量來表示呢?答案是肯定有的,建構一個句子向量有很多種方法,今天我們接着word2vec來介紹下Doc2vc,看下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 paragraph vectors)類似于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裡infer_vector()預測新的句子,這裡根據經驗,alpha(學習步長)設定小一些,疊代次數設定大一些。找到訓練樣本中與這個句子最相近的10個句子。可以看到訓練出來的結果與測試的新句子是有關聯的。

基于Doc2vec訓練句子向量
基于Doc2vec訓練句子向量

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