gensim doc2vec嵌入向量中的差异

时间:2019-06-02 04:51:48

标签: gensim word-embedding doc2vec

我使用gensim Doc2Vec软件包来训练doc2vec嵌入。我希望使用相同参数和数据训练的两个模型将具有非常接近doc2vec向量的值。但是,以我的经验来看,只有在PV-DBOW中训练了doc2vec却没有训练单词嵌入(dbow_words = 0)的情况下,这才是正确的。 对于具有dbow_words = 1的PV-DM和PV-DBOW,即在每种情况下,单词嵌入都与doc2vec一起训练,相同训练模型的doc2vec嵌入向量是完全不同的。

这是我的代码

    from sklearn.datasets import fetch_20newsgroups
    from gensim import models
    import scipy.spatial.distance as distance
    import numpy as np
    from nltk.corpus import stopwords
    from string import punctuation
    def clean_text(texts,  min_length = 2):
        clean = []
        #don't remove apostrophes
        translator = str.maketrans(punctuation.replace('\'',' '), ' '*len(punctuation))
        for text in texts:
            text = text.translate(translator)
            tokens = text.split()
            # remove not alphabetic tokens
            tokens = [word.lower() for word in tokens if word.isalpha()]
            # filter out stop words
            stop_words = stopwords.words('english')
            tokens = [w for w in tokens if not w in stop_words]
            # filter out short tokens
            tokens = [word for word in tokens if len(word) >= min_length]
            tokens = ' '.join(tokens)
            clean.append(tokens)
        return clean
    def tag_text(all_text, tag_type =''):
        tagged_text = []
        for i, text in enumerate(all_text):
            tag = tag_type + '_' + str(i)
            tagged_text.append(models.doc2vec.TaggedDocument(text.split(), [tag]))
        return tagged_text

    def train_docvec(dm, dbow_words, min_count, epochs, training_data):
        model = models.Doc2Vec(dm=dm, dbow_words = dbow_words, min_count = min_count)
        model.build_vocab(tagged_data)
        model.train(training_data, total_examples=len(training_data), epochs=epochs)    
        return model

    def compare_vectors(vector1, vector2):
        cos_distances = []
        for i in range(len(vector1)):
            d = distance.cosine(vector1[i], vector2[i])
            cos_distances.append(d)
        print (np.median(cos_distances))
        print (np.std(cos_distances))    

    dataset = fetch_20newsgroups(shuffle=True, random_state=1,remove=('headers', 'footers', 'quotes'))
    n_samples = len(dataset.data)
    data = clean_text(dataset.data)
    tagged_data = tag_text(data)
    data_labels = dataset.target
    data_label_names = dataset.target_names

    model_dbow1 = train_docvec(0, 0, 4, 30, tagged_data)
    model_dbow2 = train_docvec(0, 0, 4, 30, tagged_data)
    model_dbow3 = train_docvec(0, 1, 4, 30, tagged_data)
    model_dbow4 = train_docvec(0, 1, 4, 30, tagged_data)
    model_dm1 = train_docvec(1, 0, 4, 30, tagged_data)
    model_dm2 = train_docvec(1, 0, 4, 30, tagged_data)

    compare_vectors(model_dbow1.docvecs, model_dbow2.docvecs)
    > 0.07795828580856323
    > 0.02610614028793008

    compare_vectors(model_dbow1.docvecs, model_dbow3.docvecs)
    > 0.6476179957389832
    > 0.14797587172616306

    compare_vectors(model_dbow3.docvecs, model_dbow4.docvecs)
    > 0.19878000020980835
    > 0.06362519480831186

    compare_vectors(model_dm1.docvecs, model_dm2.docvecs)
    > 0.13536489009857178
    > 0.045365127475424386

    compare_vectors(model_dbow1.docvecs, model_dm1.docvecs)
    > 0.6358324736356735
    > 0.15150255674571805

1 个答案:

答案 0 :(得分:1)

Doc2VecWord2Vec模型的doc矢量(或单词矢量)仅与在相同的交错训练会话中共同训练的其他矢量有意义地比较。

否则,算法(随机初始化和随机采样)以及训练顺序(来自多线程)中的细微差异所引入的随机性将导致各个向量的训练位置漂移到任意不同的位置。它们与其他共享交错训练的向量的相对距离/方向,从一个模型到下一个模型应该同样有用。

但是,没有这样的向量的正确位置,并且测量一个模型中文档“ 1”(或单词“ foo”)的向量与另一模型中相应向量之间的差并不反映训练过的模型/算法可以提供的任何内容。

Gensim常见问题解答中有更多信息:

Q11: I've trained my Word2Vec/Doc2Vec/etc model repeatedly using the exact same text corpus, but the vectors are different each time. Is there a bug or have I made a mistake?