【NLP】Doc2vec原理解析及代码实践
本文概覽:
1. 句子向量簡介
Word2Vec提供了高質量的詞向量,并在一些任務中表現良好。雖然Word2Vec提供了高質量的詞匯向量,但是仍然沒有有效的方法將它們結合成一個高質量的文檔向量。對于一個句子、文檔或者說一個段落,怎么把這些數據投影到向量空間中,并具有豐富的語義表達呢?過去人們常常使用以下幾種方法:
Bag of Words
LDA
Average Word Vectors
TF-IDF Weighted Word Vectors
就Bag of Words而言,有如下缺點:
沒有考慮到單詞的順序;
忽略了單詞的語義信息;
因此這種方法對于短文本效果很差,對于長文本效果一般,通常在科研中用來做Baseline。
Average Word Vectors就是簡單的對句子中的所有詞向量取平均。是一種簡單有效的方法,但缺點也是沒有考慮到單詞的順序。
TF-IDF Weighted word vectors是指對句子中的所有詞向量根據TF-IDF權重加權求和,是常用的一種計算sentence embedding的方法,在某些問題上表現很好,相比于簡單的對所有詞向量求平均,考慮到了TF-IDF權重,因此句子中更重要的詞占得比重就更大。但缺點也是沒有考慮到單詞的順序。
LDA模型就是計算出一篇文檔或者句子的主題分布,也常常用于文本分類任務。
2. Doc2vec原理
Doc2vec方法是一種無監督算法,能從變長的文本(例如:句子、段落或文檔)中學習得到固定長度的特征表示。Doc2vec也可以叫做 Paragraph Vector、Sentence Embeddings,它可以獲得句子、段落和文檔的向量表達,是Word2Vec的拓展,其具有一些優點,比如不用固定句子長度,接受不同長度的句子做訓練樣本。Doc2vec算法用于預測一個向量來表示不同的文檔 ,該模型的結構潛在的克服了詞袋模型的缺點。
Doc2vec模型是受到了Word2Vec模型的啟發。Word2Vec預測詞向量時,預測出來的詞是含有詞義的,Doc2vec中也是構建了相同的結構,所以Doc2vec克服了詞袋模型中沒有語義的缺點。假設現在存在訓練樣本,每個句子是訓練樣本,和Word2Vec一樣,Doc2vec也有兩種訓練方式,一種是分布記憶的段落向量(Distributed Memory Model of Paragraph Vectors , PV-DM)類似于Word2Vec中的CBOW模型,另一種是分布詞袋版本的段落向量(Distributed Bag of Words version of Paragraph Vector,PV-DBOW)類似于Word2Vec中的Skip-gram模型。
2.1 Distributed Memory Model of Paragraph Vectors
訓練句向量的方法和詞向量的方法非常類似。訓練詞向量的核心思想就是可以根據每個單詞的上下文預測,也就是說上下文的單詞對是有影響的。那么同理,可以用同樣的方法訓練Doc2vec。例如對于一個句子s: i want to drink water,如果要去預測句子中的單詞want,那么不僅可以根據其它單詞生成feature,也可以根據其它單詞和句子s來生成feature進行預測。因此Doc2vec的框架如下圖所示:
在Doc2vec中,每一句話用唯一的向量來表示,用矩陣的某一列來代表。每一個詞也用唯一的向量來表示,用矩陣的某一列來表示。每次從一句話中滑動采樣固定長度的詞,取其中一個詞作預測詞,其他的作為輸入詞。輸入詞對應的詞向量Word Vector和本句話對應的句子向量Paragraph vector作為輸入層的輸入,將本句話的向量和本次采樣的詞向量相加求平均或者累加構成一個新的向量,進而使用這個向量預測此次窗口內的預測詞。
Doc2vec相對于Word2vec不同之處在于,在輸入層增添了一個新的句子向量Paragraph vector,Paragraph vector可以被看作是另一個詞向量,它扮演了一個記憶角色。Average Word Vectors中,使用Word2Vec訓練詞向量,因為每次訓練只會截取句子中一小部分詞訓練,而忽略了除了本次訓練詞以外該句子中的其他詞,這樣僅僅訓練出來每個詞的向量表達,句子只是每個詞的向量累加在一起取平均的一種表達。正如上面所說的Average Word Vectors的缺點,忽略了文本的詞序問題。而Doc2vec中的Paragraph vector則彌補了這方面的不足,它每次訓練也是滑動截取句子中一小部分詞來訓練,Paragraph Vector在同一個句子的若干次訓練中是共享的,所以同一句話會有多次訓練,每次訓練中輸入都包含Paragraph vector。它可以被看作是句子的主旨,有了它,該句子的主旨每次都會被作為輸入的一部分來訓練。這樣每次訓練過程中,不光是訓練了詞,得到了詞向量。同時隨著一句話每次滑動取若干詞訓練的過程中,作為每次訓練的輸入層一部分的共享Paragraph vector,該向量表達的主旨會越來越準確。Doc2vec中PV-DM模型具體的訓練過程和Word2Vec中的CBOW模型訓練方式相同,這里就不在重復講解了,不明白Word2Vec原理可以看我的這篇文章:深入理解Word2Vec原理解析。
這個段落向量或句向量也可以認為是一個單詞,它的作用相當于是上下文的記憶單元或者是這個段落的主題,所以我們一般叫這種訓練方法為Distributed Memory Model of Paragraph Vectors(PV-DM)。在訓練的時候我們固定上下文的長度,用滑動窗口的方法產生訓練集。段落向量或句向量在該上下文中共享。
訓練完了以后,就會得到訓練樣本中所有的詞向量和每句話對應的句子向量,那么Doc2vec是怎么預測新的句子Paragraph vector呢?其實在預測新的句子的時候,還是會將該Paragraph vector隨機初始化,放入模型中再重新根據隨機梯度下降不斷迭代求得最終穩定下來的句子向量。不過在預測過程中,模型里的詞向量、投影層到輸出層的softmax weights參數是不會變的,這樣在不斷迭代中只會更新Paragraph vector,其它參數均已固定,只需很少的時間就能計算出待預測的Paragraph vector。
總結PV-DM的過程, 主要有兩步:
訓練模型,在已知的訓練數據中得到詞向量, softmax的參數和,以及段落向量或句向量。
推斷過程(inference stage),對于新的段落,得到其向量表達。具體地,在矩陣中添加更多的列,在固定,,的情況下,利用上述方法進行訓練,使用梯度下降的方法得到新的,從而得到新段落的向量表達。
2.2 Distributed Bag of Words version of Paragraph Vector
另外一種訓練方法是忽略輸入的上下文,讓模型去預測段落中的隨機一個單詞。就是在每次迭代的時候,從文本中采樣得到一個窗口,再從這個窗口中隨機采樣一個單詞作為預測任務,讓模型去預測,輸入就是段落向量。我們稱這種模型為 Distributed Bag of Words version of Paragraph Vector(PV-DBOW),如下圖所示:
在上述兩種方法中,我們可以使用PV-DM或者PV-DBOW得到段落向量或者句向量。對于大多數任務,PV-DM的方法表現很好,但論文中的作者也強烈推薦兩種方法相結合。
3. 代碼實踐
現在,我們對NLP中Doc2vec算法進行簡單地實現。這個案例是使用gensim 3.4和python3實現Doc2vec模型的訓練和預測,gensim庫使Doc2vec的實現更加容易。本文的所有代碼已經放在我的GitHub中,地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/blob/master/NLP/Doc2vec/Doc2vec.py
# -------------Let’s start implementing---------------------- # Import all the dependencies from gensim.models.doc2vec import Doc2Vec, TaggedDocument from nltk.tokenize import word_tokenize import nltknltk.download()# -------------Let’s prepare data for training our doc2vec model---------------------- data = ["I love machine learning. Its awesome.","I love coding in python","I love building chatbots","they chat amagingly well"]tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(data)]# -------------Lets start training our model---------------------- max_epochs = 100 vec_size = 20 alpha = 0.025model = Doc2Vec(size=vec_size,alpha=alpha,min_alpha=0.00025,min_count=1,dm=1)''' Note: dm defines the training algorithm. If dm=1 means‘distributed memory’(PV-DM) and dm =0 means‘distributed bag of words’(PV-DBOW). Distributed Memory model preserves the word order in a document whereas Distributed Bag of words just uses the bag of words approach, which doesn’t preserve any word order. '''model.build_vocab(tagged_data)for epoch in range(max_epochs):print('iteration {0}'.format(epoch))model.train(tagged_data,total_examples=model.corpus_count,epochs=model.iter)# decrease the learning ratemodel.alpha -= 0.0002# fix the learning rate, no decaymodel.min_alpha = model.alphamodel.save("d2v.model") print("Model Saved")# -------------Lets play with it---------------------- from gensim.models.doc2vec import Doc2Vecmodel = Doc2Vec.load("d2v.model") # to find the vector of a document which is not in training data test_data = word_tokenize("I love chatbots".lower()) v1 = model.infer_vector(test_data) print("V1_infer", v1)# to find most similar doc using tags similar_doc = model.docvecs.most_similar('1') print(similar_doc)# to find vector of doc in training data using tags or in other words, printing the vector of document at index 1 in training data print(model.docvecs['1'])實踐總結:
使用gensim的Doc2vec進行句子、段落或文章的向量表示時,不需要進行分詞;
使用TaggedDocument進行語料預處理;
train訓練模型,save 和 load 加載訓練好的模型;
docvecs.most_similar( )計算相似度;
4. Reference
【1】Le Q, Mikolov T. Distributed representations of sentences and documents[C]// International conference on machine learning. 2014: 1188-1196.
【2】基于Doc2vec訓練句子向量 - 灰灰的文章 - 知乎 https://zhuanlan.zhihu.com/p/36886191
【3】doc2vec原理及實踐,地址:https://blog.csdn.net/John_xyz/article/details/79208564
【4】https://medium.com/@mishra.thedeepak/doc2vec-simple-implementation-example-df2afbbfbad5
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am喜歡文章,點個在看
總結
以上是生活随笔為你收集整理的【NLP】Doc2vec原理解析及代码实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kaggle知识点:数据分布不一致的验证
- 下一篇: 我感觉这是目前讲得最明白的线性回归的文章