[英]Gensim's Doc2Vec - How to use pre-trained word2vec (word similarities)
我沒有大量的數據來訓練詞的相似性,例如“熱”更類似於“暖”而不是“冷”。 但是,我喜歡在一個相對較小的語料庫上訓練 doc2vec,大約 100 個文檔,以便它可以對我的領域特定文檔進行分類。
為了詳細說明,讓我使用這個玩具示例。 假設我只有 4 個由 4 個句子給出的培訓文檔——“我喜歡熱巧克力。”、“我討厭熱巧克力。”、“我喜歡熱茶。”和“我喜歡熱蛋糕。”。 給定一個測試文檔“我喜歡熱巧克力”,我希望 doc2vec 總是會返回“我喜歡熱巧克力”。 作為最接近的文件。 如果 word2vec 已經提供了“adore”與“love”非常相似的知識,那么這種期望將是正確的。 然而,我得到的文件與“我討厭熱巧克力”最相似——這太奇怪了!!
關於如何規避這一點的任何建議,即能夠使用預先訓練的詞嵌入,這樣我就不需要冒險訓練“愛”接近“愛”,“恨”接近“厭惡”,以及很快。
代碼(Jupyter Nodebook。Python 3.7。Jensim 3.8.1)
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
from nltk.tokenize import word_tokenize
data = ["I love hot chocolate.",
"I hate hot chocolate",
"I love hot tea.",
"I love hot cake."]
tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(data)]
print(tagged_data)
#Train and save
max_epochs = 10
vec_size = 5
alpha = 0.025
model = Doc2Vec(vector_size=vec_size, #it was size earlier
alpha=alpha,
min_alpha=0.00025,
min_count=1,
dm =1)
model.build_vocab(tagged_data)
for epoch in range(max_epochs):
if epoch % 10 == 0:
print('iteration {0}'.format(epoch))
model.train(tagged_data,
total_examples=model.corpus_count,
epochs=model.epochs) #It was model.iter earlier
# decrease the learning rate
model.alpha -= 0.0002
# fix the learning rate, no decay
model.min_alpha = model.alpha
print("Model Ready")
test_sentence="I adore hot chocolate"
test_data = word_tokenize(test_sentence.lower())
v1 = model.infer_vector(test_data)
#print("V1_infer", v1)
# to find most similar doc using tags
sims = model.docvecs.most_similar([v1])
print("\nTest: %s\n" %(test_sentence))
for indx, score in sims:
print("\t(score: %.4f) %s" %(score, data[int(indx)]))
僅約 100 個文檔太小,無法有意義地訓練Doc2Vec
(或Word2Vec
)模型。 已發布的Doc2Vec
工作往往使用數萬到數百萬個文檔。
如果您能夠從較小的數據集中獲得稍微有意義的結果,您通常需要大量減少向量大小——遠小於單詞/示例的數量——並增加訓練時期。 (您的玩具數據有 4 個文本和 6 個獨特的詞。即使要獲得 5 維向量,您也可能需要類似 5^2 的對比文檔。)
此外,gensim 的Doc2Vec
不提供任何官方選項來從其他地方導入詞向量。 內部Doc2Vec
訓練不是Doc2Vec
訓練詞向量,然后計算 doc-vectors 的過程。 相反,doc-vectors 和 word-vectors 在同時進行訓練,一起逐漸改進。 (某些模式,例如可以通過dm=0
啟用的快速且通常非常有效的DBOW
,根本不創建或使用詞向量。)
當我們像Doc2Vec
或Word2Vec
算法一樣查看數據時,您的 4 句結果並沒有什么奇怪的Doc2Vec
,它們沒有關於單詞的先驗知識,只有訓練數據中的內容。 在您的訓練數據中,標記'love'
和標記'hate'
的使用方式幾乎完全相同,周圍的詞也相同。 只有通過看到單詞的許多微妙變化的替代用法,以及許多對比鮮明的周圍單詞,這些“密集嵌入”模型才能將單詞向量移動到有用的相對位置,在那里它們更接近相關單詞並遠離其他單詞。 (而且,由於您沒有提供帶有標記'adore'
訓練數據,模型對該詞一無所知 - 如果它在測試文檔中提供,就像模型的infer_vector()
方法一樣,它將被忽略。所以它“看到”的測試文檔只是已知的單詞['i', 'hot', 'chocolate']
。)
而且,即使您確實設法在更大的數據集上進行了訓練,或者以某種方式從其他詞向量中注入了'love'
和'adore'
有點相似的知識,重要的是要注意反義詞在一組中通常非常相似詞向量也是如此——因為它們在相同的上下文中使用,並且通常在句法上可以互換,並且屬於相同的一般類別。 這些模型往往不在檢測從一個字的交換倒裝在人類感知的含義為它的反義詞(或單“而不是”或其他逆轉意圖的話插入)非常好。
最后,如果你想使用 gensim 的Doc2Vec
,你應該用更多的數據來訓練它。 (如果您願意獲取一些其他預先訓練好的詞向量,為什么不獲取一些類似的大量句子的其他來源?使用與您的實際問題不完全相同的數據的效果將是相似的,無論您是否利用它通過批量文本或預訓練模型獲取外部數據。)
最后:在您自己的循環中多次調用train()
並使用您自己的alpha
調整是一種糟糕的、容易出錯的模式。 您只需調用一次,使用正確數量的epochs
,模型將執行多次訓練並在正確數量的 epochs 內平滑地管理內部alpha
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.