2014-12-14 72 views
22

Gần đây tôi đã xem qua phần bổ sung doc2vec cho Gensim. Làm cách nào để tôi có thể sử dụng các vectơ từ được đào tạo trước (ví dụ: được tìm thấy trong trang web gốc word2vec) với doc2vec?Làm thế nào để sử dụng Gensim doc2vec với vectơ từ được đào tạo trước?

Hoặc doc2vec có nhận được vectơ từ từ cùng một câu mà nó sử dụng cho đào tạo đoạn-vector không?

Cảm ơn.

Trả lời

2

Radim vừa đăng một số tutorial trên các tính năng doc2vec của gensim (hôm qua, tôi tin - câu hỏi của bạn là kịp thời!).

Gensim hỗ trợ tải vectơ đã được đào tạo từ the C implementation, như được mô tả trong the gensim models.word2vec API documentation.

+1

Cảm ơn Aaron .. Thực tế câu hỏi kịp thời :) Điều này được viết trong hướng dẫn: "... nếu bạn chỉ muốn học đại diện cho nhãn và để biểu diễn từ cố định, mô hình cũng có cờ train_words = False" .. Tôi biết rằng bạn có thể sử dụng các vectơ đã được đào tạo cho word2vec .. Câu hỏi đặt ra là, làm cách nào để gọi doc2vec với các vectơ được đào tạo trước đó? – Stergios

+1

@Stergios: Có lẽ tôi hiểu nhầm câu hỏi (và tôi vẫn đang vấp phải điều này). Nhưng có vẻ như suy luận vẫn chưa thực sự được triển khai - hãy xem https://groups.google.com/forum/#!topic/gensim/EFy1f0QwkKI. Rất may, có ít nhất một vài người tích cực làm việc trên nó. Tôi đoán chuỗi sẽ là một cái gì đó như 1) Nạp véc tơ được đào tạo trước; 2) Tạo một vectơ cho câu không nhìn thấy của bạn với một nhãn mới; 3) Gọi most_similar ("NEW_LABEL"). Ngoài ra, hãy tạo các vectơ cho nhiều câu chưa nhìn thấy và tính khoảng cách giữa các vectơ đó. Nhưng đó chỉ là một phỏng đoán. – AaronD

+1

@AaronD FYI, suy luận hoạt động ngay bây giờ – Renaud

9

Vâng, tôi gần đây đang sử dụng Doc2Vec. Và tôi đã nghĩ đến việc sử dụng kết quả LDA làm vector từ và sửa các vectơ từ đó để lấy một vectơ tài liệu. Kết quả không phải là rất thú vị mặc dù. Có lẽ nó chỉ là bộ dữ liệu của tôi không tốt. Mã dưới đây. Doc2Vec lưu các vectơ từ và các vectơ tài liệu với nhau trong từ điển doc2vecmodel.syn0. Bạn có thể trực tiếp thay đổi các giá trị vector. Vấn đề duy nhất có thể là bạn cần phải tìm ra vị trí nào trong syn0 đại diện cho từ hoặc tài liệu nào. Các vectơ được lưu trữ theo thứ tự ngẫu nhiên trong từ điển syn0.

import logging 
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) 
from gensim import corpora, models, similarities 
import gensim 
from sklearn import svm, metrics 
import numpy 

#Read in texts into div_texts(for LDA and Doc2Vec) 
div_texts = [] 
f = open("clean_ad_nonad.txt") 
lines = f.readlines() 
f.close() 
for line in lines: 
    div_texts.append(line.strip().split(" ")) 

#Set up dictionary and MMcorpus 
dictionary = corpora.Dictionary(div_texts) 
dictionary.save("ad_nonad_lda_deeplearning.dict") 
#dictionary = corpora.Dictionary.load("ad_nonad_lda_deeplearning.dict") 
print dictionary.token2id["junk"] 
corpus = [dictionary.doc2bow(text) for text in div_texts] 
corpora.MmCorpus.serialize("ad_nonad_lda_deeplearning.mm", corpus) 

#LDA training 
id2token = {} 
token2id = dictionary.token2id 
for onemap in dictionary.token2id: 
    id2token[token2id[onemap]] = onemap 
#ldamodel = models.LdaModel(corpus, num_topics = 100, passes = 1000, id2word = id2token) 
#ldamodel.save("ldamodel1000pass.lda") 
#ldamodel = models.LdaModel(corpus, num_topics = 100, id2word = id2token) 
ldamodel = models.LdaModel.load("ldamodel1000pass.lda") 
ldatopics = ldamodel.show_topics(num_topics = 100, num_words = len(dictionary), formatted = False) 
print ldatopics[10][1] 
print ldatopics[10][1][1] 
ldawordindex = {} 
for i in range(len(dictionary)): 
    ldawordindex[ldatopics[0][i][1]] = i 

#Doc2Vec initialize 
sentences = [] 
for i in range(len(div_texts)): 
    string = "SENT_" + str(i) 
    sentence = models.doc2vec.LabeledSentence(div_texts[i], labels = [string]) 
    sentences.append(sentence) 
doc2vecmodel = models.Doc2Vec(sentences, size = 100, window = 5, min_count = 0, dm = 1) 
print "Initial word vector for word junk:" 
print doc2vecmodel["junk"] 

#Replace the word vector with word vectors from LDA 
print len(doc2vecmodel.syn0) 
index2wordcollection = doc2vecmodel.index2word 
print index2wordcollection 
for i in range(len(doc2vecmodel.syn0)): 
    if index2wordcollection[i].startswith("SENT_"): 
     continue 
    wordindex = ldawordindex[index2wordcollection[i]] 
    wordvectorfromlda = [ldatopics[j][wordindex][0] for j in range(100)] 
    doc2vecmodel.syn0[i] = wordvectorfromlda 
#print doc2vecmodel.index2word[26841] 
#doc2vecmodel.syn0[0] = [0 for i in range(100)] 
print "Changed word vector for word junk:" 
print doc2vecmodel["junk"] 

#Train Doc2Vec 
doc2vecmodel.train_words = False 
print "Initial doc vector for 1st document" 
print doc2vecmodel["SENT_0"] 
for i in range(50): 
    print "Round: " + str(i) 
    doc2vecmodel.train(sentences) 
print "Trained doc vector for 1st document" 
print doc2vecmodel["SENT_0"] 

#Using SVM to do classification 
resultlist = [] 
for i in range(4143): 
    string = "SENT_" + str(i) 
    resultlist.append(doc2vecmodel[string]) 
svm_x_train = [] 
for i in range(1000): 
    svm_x_train.append(resultlist[i]) 
for i in range(2210,3210): 
    svm_x_train.append(resultlist[i]) 
print len(svm_x_train) 

svm_x_test = [] 
for i in range(1000,2210): 
    svm_x_test.append(resultlist[i]) 
for i in range(3210,4143): 
    svm_x_test.append(resultlist[i]) 
print len(svm_x_test) 

svm_y_train = numpy.array([0 for i in range(2000)]) 
for i in range(1000,2000): 
    svm_y_train[i] = 1 
print svm_y_train 

svm_y_test = numpy.array([0 for i in range(2143)]) 
for i in range(1210,2143): 
    svm_y_test[i] = 1 
print svm_y_test 


svc = svm.SVC(kernel='linear') 
svc.fit(svm_x_train, svm_y_train) 

expected = svm_y_test 
predicted = svc.predict(svm_x_test) 

print("Classification report for classifier %s:\n%s\n" 
     % (svc, metrics.classification_report(expected, predicted))) 
print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted)) 

print doc2vecmodel["junk"] 
17

Lưu ý rằng chế độ đào tạo "DBOW" (dm=0) không yêu cầu hoặc thậm chí tạo từ vectơ như một phần của khóa đào tạo. Nó chỉ đơn thuần là học các vectơ tài liệu có thể dự đoán tốt từng từ (giống như chế độ word2vec skip-gram).

(Trước gensim 0.12.0, có thông số train_words được đề cập trong một nhận xét khác, mà một số tài liệu được đề xuất sẽ đồng phát từ. Tuy nhiên, tôi không tin điều này thực sự hiệu quả. Bắt đầu từ gensim 0.12.0, có tham số dbow_words, hoạt động để bỏ qua các từ đào tạo đồng thời với các vectơ doc-DBOW. Lưu ý rằng điều này làm cho việc đào tạo mất nhiều thời gian hơn - bởi một yếu tố liên quan đến window.Vì vậy, nếu bạn không cần từ-vectơ, bạn vẫn có thể Để lại điều này.)

Trong phương pháp đào tạo "DM" (dm=1), vectơ từ vốn được đào tạo trong quá trình cùng với doc-vectơ và có khả năng cũng ảnh hưởng đến chất lượng của vectơ doc. Về mặt lý thuyết có thể khởi tạo trước các từ-vectơ từ dữ liệu trước đó. Nhưng tôi không biết bất kỳ lý do lý thuyết hoặc thực nghiệm mạnh mẽ nào để tin tưởng điều này sẽ cải thiện doc-vectơ.

Một thử nghiệm phân đoạn mà tôi chạy dọc theo các dòng này cho thấy việc đào tạo doc-vector đã khởi đầu nhanh hơn - chất lượng tiên đoán tốt hơn sau vài lần truyền đầu tiên - nhưng lợi thế này đã bị mờ đi với nhiều lượt truy cập hơn. Cho dù bạn giữ các vectơ từ không đổi hoặc để chúng tiếp tục điều chỉnh thì việc đào tạo mới cũng có thể là một cân nhắc quan trọng ... nhưng lựa chọn nào tốt hơn có thể phụ thuộc vào mục tiêu, tập dữ liệu và chất lượng/sự liên quan của các từ vectơ tồn tại từ trước .

(Bạn có thể lặp lại thử nghiệm của mình với phương pháp intersect_word2vec_format() có sẵn trong gensim 0.12.0 và thử các cấp độ khác nhau của việc tạo véc-tơ được tải trước mới được đào tạo qua các giá trị syn0_lockf.Nhưng hãy nhớ đây là lãnh thổ thử nghiệm: kết quả doc2vec không dựa vào, hoặc thậm chí nhất thiết phải cải thiện, vectơ từ được sử dụng lại.)

6

This forked version of gensim cho phép tải các vectơ từ được đào tạo trước để đào tạo doc2vec. Here bạn có một ví dụ về cách sử dụng nó.Các vectơ từ phải ở định dạng văn bản công cụ C-word2vec: một dòng cho mỗi vectơ từ trong đó đầu tiên có một chuỗi đại diện cho từ và sau đó là các giá trị float được phân cách bằng dấu cách, một cho mỗi thứ nguyên của nhúng.

Tác phẩm này thuộc về một số paper trong đó họ tuyên bố rằng việc sử dụng nhúng từ được đào tạo thực sự giúp xây dựng vectơ tài liệu. Tuy nhiên tôi nhận được gần như kết quả tương tự cho dù tôi có tải các bản nhúng đã được đào tạo hay không.

Chỉnh sửa: thực sự có một sự khác biệt đáng kể trong các thử nghiệm của tôi. Khi tôi tải các đoạn nhúng giả định, tôi đã đào tạo doc2vec cho một nửa số lần lặp lại để nhận được gần như kết quả tương tự (đào tạo lâu hơn kết quả tồi tệ hơn trong nhiệm vụ của tôi).

Các vấn đề liên quan