关于doc2vec
原文地址:https://blog.csdn.net/john_xyz/article/details/79208564
?
1.“句向量”簡介
word2vec提供了高質量的詞向量,并在一些任務中表現良好。?
關于word2vec的原理可以參考這幾篇論文:
- https://arxiv.org/pdf/1310.4546.pdf
- https://arxiv.org/pdf/1301.3781.pdf
關于如何使用第三方庫gensim訓練word2vec可以參考這篇博客:
- http://blog.csdn.net/john_xyz/article/details/54706807
盡管word2vec提供了高質量的詞匯向量,仍然沒有有效的方法將它們結合成一個高質量的文檔向量。對于一個句子、文檔或者說一個段落,怎么把這些數據投影到向量空間中,并具有豐富的語義表達呢?過去人們常常使用以下幾種方法:
- bag of words
- LDA
- average word vectors
- tfidf-weighting word vectors
就bag of words而言,有如下缺點:1.沒有考慮到單詞的順序,2.忽略了單詞的語義信息。因此這種方法對于短文本效果很差,對于長文本效果一般,通常在科研中用來做baseline。
average word vectors就是簡單的對句子中的所有詞向量取平均。是一種簡單有效的方法,但缺點也是沒有考慮到單詞的順序
tfidf-weighting word vectors是指對句子中的所有詞向量根據tfidf權重加權求和,是常用的一種計算sentence embedding的方法,在某些問題上表現很好,相比于簡單的對所有詞向量求平均,考慮到了tfidf權重,因此句子中更重要的詞占得比重就更大。但缺點也是沒有考慮到單詞的順序
LDA模型當然就是計算出一片文檔或者句子的主題分布。也常常用于文本分類任務,后面會專門寫一篇文章介紹LDA模型和doc2vec的本質不同
2. doc2vec原理
doc2vec是google的兩位大牛Quoc Le和Tomas Mikolov在2014年提出的,原始論文地址如下:https://cs.stanford.edu/~quocle/paragraph_vector.pdf
Doc2Vec?或者叫做 paragraph2vec, sentence embeddings,是一種非監督式算法,可以獲得 sentences/paragraphs/documents 的向量表達,是 word2vec 的拓展。學出來的向量可以通過計算距離來找 sentences/paragraphs/documents 之間的相似性,可以用于文本聚類,對于有標簽的數據,還可以用監督學習的方法進行文本分類,例如經典的情感分析問題。
在介紹doc2vec原理之前,先簡單回顧下word2vec的原理
word2vec基本原理
熟悉word2vec的同學都知道,下圖是學習詞向量表達最經典的一幅圖。在下圖中,任務就是給定上下文,預測上下文的其他單詞。
其中,每個單詞都被映射到向量空間中,將上下文的詞向量級聯或者求和作為特征,預測句子中的下一個單詞。一般地:給定如下訓練單詞序列, 目標函數是
當然,預測的任務是一個多分類問題,分類器最后一層使用softmax,計算公式如下:?
這里的每一個可以理解為預測出每個的概率。因為在該任務中,每個詞就可以看成一個類別。計算的公式如下:
這里U和b都是參數,h是將級聯或者求平均。?
因為每個單詞都是一類,所以類別眾多,在計算softmax歸一化的時候,效率很低。因此使用hierarical softmax加快計算速度,其實就是huffman樹,這個不再贅述,有興趣的同學可以看word2vec的paper。
doc2vec基本原理
1. A distributed memory model
訓練句向量的方法和詞向量的方法非常類似。訓練詞向量的核心思想就是說可以根據每個單詞的上下文預測,也就是說上下文的單詞對是有影響的。那么同理,可以用同樣的方法訓練doc2vec。例如對于一個句子i want to drink water,如果要去預測句子中的單詞want,那么不僅可以根據其他單詞生成feature, 也可以根據其他單詞和句子來生成feature進行預測。因此doc2vec的框架如下所示:
每個段落/句子都被映射到向量空間中,可以用矩陣的一列來表示。每個單詞同樣被映射到向量空間,可以用矩陣的一列來表示。然后將段落向量和詞向量級聯或者求平均得到特征,預測句子中的下一個單詞。
這個段落向量/句向量也可以認為是一個單詞,它的作用相當于是上下文的記憶單元或者是這個段落的主題,所以我們一般叫這種訓練方法為Distributed Memory Model of Paragraph Vectors(PV-DM)
在訓練的時候我們固定上下文的長度,用滑動窗口的方法產生訓練集。段落向量/句向量 在該上下文中共享。
總結doc2vec的過程, 主要有兩步:
- 訓練模型,在已知的訓練數據中得到詞向量, softmax的參數和,以及段落向量/句向量
- 推斷過程(inference stage),對于新的段落,得到其向量表達。具體地,在矩陣中添加更多的列,在固定,,的情況下,利用上述方法進行訓練,使用梯度下降的方法得到新的D,從而得到新段落的向量表達
2. Paragraph Vector without word ordering: Distributed bag of words
還有一種訓練方法是忽略輸入的上下文,讓模型去預測段落中的隨機一個單詞。就是在每次迭代的時候,從文本中采樣得到一個窗口,再從這個窗口中隨機采樣一個單詞作為預測任務,讓模型去預測,輸入就是段落向量。如下所示:
我們稱這種模型為 Distributed Bag of Words version of Paragraph Vector(PV-DBOW)
在上述兩種方法中,我們可以使用PV-DM或者PV-DBOW得到段落向量/句向量。對于大多數任務,PV-DM的方法表現很好,但我們也強烈推薦兩種方法相結合。
3. 基于gensim的doc2vec實踐
我們使用第三方庫gensim進行doc2vec模型的訓練
# -*- coding: utf-8 -*-
import sys
import logging
import os
import gensim
# 引入doc2vec
from gensim.models import Doc2Vec
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
from utilties import ko_title2words
# 引入日志配置
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 加載數據
documents = []
# 使用count當做每個句子的“標簽”,標簽和每個句子是一一對應的
count = 0
with open('../data/titles/ko.video.corpus','r') as f:
for line in f:
title = unicode(line, 'utf-8')
# 切詞,返回的結果是列表類型
words = ko_title2words(title)
# 這里documents里的每個元素是二元組,具體可以查看函數文檔
documents.append(gensim.models.doc2vec.TaggedDocument(words, [str(count)]))
count += 1
if count % 10000 == 0:
logging.info('{} has loaded...'.format(count))
# 模型訓練
model = Doc2Vec(documents, dm=1, size=100, window=8, min_count=5, workers=4)
# 保存模型
model.save('models/ko_d2v.model')
?
接下來看看訓練好的模型可以做什么
def test_doc2vec():
# 加載模型
model = doc2vec.Doc2Vec.load('models/ko_d2v.model')
# 與標簽‘0’最相似的
print(model.docvecs.most_similar('0'))
# 進行相關性比較
print(model.docvecs.similarity('0','1'))
# 輸出標簽為‘10’句子的向量
print(model.docvecs['10'])
# 也可以推斷一個句向量(未出現在語料中)
words = u"?? ??? ? ? ??"
print(model.infer_vector(words.split()))
# 也可以輸出詞向量
print(model[u'??'])
?
以上都是一些比較常見的用法,更多的用法請參https://radimrehurek.com/gensim/models/doc2vec.html
總結
- 上一篇: 外媒称中国人工智能应用全球领先,杭州是中
- 下一篇: “村村响”,应急广播的物联网出路在何方?