我正在使用gensim和doc2vec进行文本分类。我使用两个数据集进行测试,一个是堆栈交换数据集,另一个是Reddit数据集。我试图在一个subreddit/stackexchange站点的帖子之间对特定主题进行分类,然后使用其他无关的subreddit/stackexchange站点的帖子作为负面示例。
我正在使用一个数据集10k的岗位来训练模型和测试集5k分为50%的阳性例子和50%的阴性。然后,我使用infer_vector和most_similar函数将条目分类为正或负。在训练模型之前,我会对数据进行预处理,删除任何单词、符号、链接等,只留下最有意义的单词来训练模型。下面是用来训练模型的代码。
df = pd.read_csv("fulltrainingset.csv")
df.columns.values[0] = "A"
tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(df["A"])]
epoch_list = [1,5,10,15,25,50,100,200,300,400]
size_list = [1,5,10,15,25,50,100,200,300]
for x in epoch_list:
for y in size_list:
vec_size = y
max_epochs = x
minimum_count = 1
mode = 0
window_ = 15
negative_sampling = 5
subsampling = 1e-5
alpha = 0.025
minalpha = 0.00025
model = Doc2Vec(alpha=alpha, min_alpha=minalpha, vector_size=vec_size, dm=mode, min_count=minimum_count, window =window_, sample=subsampling ,hs =negative_sampling)
model.build_vocab(tagged_data)
for epoch in range(max_epochs):
print('iteration {0}'.format(epoch))
model.train(tagged_data,
total_examples=model.corpus_count,
epochs=model.epochs)#self.epochs
model.alpha -= 0.0002
model.min_alpha = model.alpha
model.save(str(y)+"s_"+str(x)+"e.model")这种方法是有效的,我可以从中得到结果,但我想知道是否有一种不同的培训方式,以取得更好的效果。目前,我只是训练了许多不同时代和不同vector_sizes的模型,然后使用infer_vector和most_similar函数来查看从most_similar条目返回的向量分数是否大于某个数字,但是在模型的训练方面有什么改进的方法吗?
另外,为了获得更好的结果,我用更大的数据集(100k+条目)以同样的方式训练了另一个模型。当我在相同的数据集上使用这个模型时,它产生的结果与在较小数据集上训练的模型相似,但效果更差。我认为,更多的培训数据会改善结果,而不是使其更糟,有人知道原因吗?
另外,为了进一步测试,我创建了一个新的但更大的测试集(15k条目),这比原来的测试集更糟糕。虽然这个测试集中的数据是唯一的,但原始测试集中使用的数据类型却会产生更糟糕的结果,但原因可能是什么呢?
df = pd.read_csv("all_sec_tweets.csv")
df.columns.values[0] = "A"
tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(df["A"])]
epoch_list = [1,5,10,15,25,50,100]
size_list = [1,5,10,15,25,50,100]
for x in epoch_list:
for y in size_list:
vec_size = y
max_epochs = x
mode = 0
window_ = 5
subsampling = 1e-5
model = Doc2Vec(vector_size=vec_size, dm=mode, window =window_, sample=subsampling,epochs=max_epochs)
model.build_vocab(tagged_data)
model.train(tagged_data,total_examples=model.corpus_count,epochs=model.epochs)
model.save(str(y)+"s_"+str(x)+"e.model")发布于 2019-10-02 21:09:55
听起来,您似乎在为每个论坛的"in"/"out“决策训练一个单独的Doc2Vec模型,然后使用一组临时的infer_vector()/most_similar()操作来做出决定。
这是一种非常粗糙的、临时的方法,您应该考虑更正式的文本分类方法,其中有一个明确的特征发现步骤(可能包括为您的文本创建Doc2Vec向量或其他技术),然后是分类器的明确步骤--培训,然后是评估。
(到那时,你可能还会训练更大的模型,其中包括所有论坛的标注培训示例,以及选择多个可能的类中的一个的分类器。)
另外,在您的Doc2Vec培训中,有几件事情是错误的或不理想的,包括:
train()或更改默认的alpha/min_alpha值几乎总是被误导的。实际上,当前的代码正在使model.epochs (5)为每个调用传递数据,并且经常将alpha减少数百次(变为无意义的负值)。只调用train()一次,使用所需的epochs数,并使用默认的alpha/min_alpha值,它将做正确的事情。(而且:不要相信任何在线教程/示例中的上述循环调用。)hs=5将严格地打开/关闭分层软turn模式,但保留默认的negative=5参数--因此您的模型将使用负采样和分级-softmax培训的(非标准的、可能没有帮助的和缓慢的)组合。最好是使用一些negative值和hs=0 (用于纯负采样),或者使用negative=0, hs=1 (用于纯层次-softmax)。或者坚持默认(negative=5, hs=0),除非/直到一切都已经正常运行,并且您想深入到更深层次的negative=5, hs=0,才是最好的选择:这些模型通常受益于丢弃罕见的单词。在纠正了这些问题之后,您可能会发现更多的数据会带来通常预期的改进结果。(如果当时没有,那就反复检查所有的文本预处理/标记化是否正确,在培训、推理和评估中都是正确的--如果你仍然有问题,也许会发布一个新的问题,并给出更多的细节/数字,说明哪些地方的预期改进会更糟。)
https://stackoverflow.com/questions/58195364
复制相似问题