我尝试构建一个简单的程序来测试我对Doc2Vec
的理解,但在了解之前,我还有很长的路要走。
我知道文档中的每个句子都首先被标记了自己的标签,对于doc2vec
,它将学习这些标签的向量。例如,据我所知,可以说我们有一个包含3个句子的列表。
[["I have a pet"], ["They have a pet"], ["she has no pet"]]
然后我们将其分为3个句子
["I have a pet"]
["They have a pet"]
["she has no pet"]
并使用gensim TaggedDocument或您构建的任何方法来为每个句子加上标签。
["I", "have", "a", "pet"] Tag= positive
["They", "have", "a", "pet"] Tag= positive
["she", "has", "no", "pet"] Tag= negative
然后,我们使用Doc2Vec
gensim
库来构建模型,build_vocab并对其进行训练。
我期望的是,每个句子的每个标签都基于另一个句子标签学习向量;然后像Word2Vec
中那样为每个标签指定向量,但是在word2vec
中,向量针对每个单词。
如果我没有误会,它应该是这样的:
["I have a pet"] Vectors = [-0.13150065 -0.13182896 -0.1564866 ]
["They have a pet"] Vectors = [-0.13150065 -0.13182896 -0.1564866 ]
["she has no pet"] Vectors = [ 0.14937358 -0.06767108 0.14668389]
但是,当我训练模型时,我只得到正负两个向量,总共是2个,而不是上面的3个。向量仅针对每个标签构建吗?负数和正数,这就是为什么它有2个稀疏向量?如果是,那么我们如何比较第一句话,第二句话和第三句话?当我收到这样的输出时,我感到非常困惑。
***有没有一种方法可以检查哪个句子的正标签?例如,如何打印标签+打印句子?
示例
tag: positive sentence: ["They have a pet"]
我的代码:
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
file = [["I have a pet"], ["They have a pet"], ["she has no pet"]]
positiveFile = file[0:2]
negativeFile = file[2]
positive = [word.split() for sentence in positiveFile for word in sentence]
negative = [word.split() for sentence in [negativeFile] for word in sentence]
total = positive + negative
taggedPositiveFiles = [TaggedDocument(sentence, ["positive"])for i, sentence in enumerate(positive)]
taggedNegativeFiles = [TaggedDocument(sentence, ["negative"])for i, sentence in enumerate(negative)]
totalTagged = taggedNegativeFiles + taggedPositiveFiles
model = Doc2Vec(totalTagged, min_count = 1, workers=1, vector_size=3)
model.build_vocab(totalTagged, update=True)
model.train(totalTagged,total_examples=1, epochs=1)
print(model.docvecs["negative"])
print(model.docvecs["positive"])
当前输出:
[-0.13150065 -0.13182896 -0.1564866 ]
[ 0.14937358 -0.06767108 0.14668389]
预期输出:
[-0.13150065 -0.13182896 -0.1564866 ]
[-0.13150065 -0.13182896 -0.1564866 ]
[ 0.14937358 -0.06767108 0.14668389]
我在哪里误解了?请帮我。非常感谢。
答案 0 :(得分:2)
您可以选择如何tag
编写文本。 Doc2Vec
模型仅学习您提供的确切标签的文档向量。
在Paragraph Vectors
所基于的原始Doc2Vec
论文中(以及之后的许多公开示例),每个文档都有其自己的唯一ID标签,因此每个文档都有一个唯一的doc-vector。您可以通过查询模型中文档的唯一标记来获取文档的文档向量。
使用可能在许多示例中重复出现的类别标签(例如“正”和“负”)是可能的,有时甚至是有效的-但与原始概念不同。如果您所有的 N 文本仅在其中包含2个唯一标签(跨文本重复),则在训练结束时将仅学习2个文档向量。
(也可以给文本添加多个标签-因此它们可以具有唯一的ID 和其他一些标签。例如:tags=['id001', 'positive']
。但是,最好考虑一下我只会在您采用较为简单的方法后才能推荐的先进/实验技术,并从这些较简单的方法中了解您设置的各种质量(例如参数,语料库大小和质量等)如何影响结果。从相同数量的数据中训练更多具有唯一标记的doc矢量,实际上意味着每个doc矢量的实用性都“弱化了”。实质上,数据中的相同源信息和“信号”被散布开来因此,您只想做一些花哨的事情,例如,如果您有大量数据,则每个文档中有多个标签-甚至可能需要进行更多的培训通行证。)
有关设置的其他说明:
update=True
的{{1}}功能仅受build_vocab()
正式支持,这是一项高级功能,需要进行大量实验才能使用权利,甚至应该在模型上使用了Word2Vec
的第二次或更多次,而不是第一次。
玩具大小的数据集通常不会在build_vocab()
/ Word2Vec
中给出有用或直观的结果-充其量只能用来理解参数类型/合法性/输出大小(如这里)。
已发布结果中的Doc2Vec
模型的典型训练通过(epochs
)为10-20。 (如果您试图从微小的数据集中挤出一些有用性,则使用更多的方法可能会有所帮助,但是寻找更大的数据集总是更好。)