我正在使用gensim和doc2vec进行文本分类。我正在使用两个数据集对此进行测试,一个是堆栈交换数据集和Reddit数据集。我试图在一个特定主题的一个subreddit / stackexchange网站上的帖子之间进行分类,然后将其他不相关的subreddit / stackexchange网站上的帖子用作负面示例。
我正在使用10k帖子的数据集来训练模型,并使用5k的测试集划分为50%的正面示例和50%的负面示例。然后,我使用infer_vector和most_like函数将条目分类为肯定或否定。在训练模型之前,我会对数据进行预处理,以删除所有单词,符号,链接等,仅留下最重要的单词来训练模型。下面是用于训练模型的代码。
let
此方法有效,我可以从中获得结果,但是我想知道是否有其他训练方法来获得更好的结果。目前,我只是在训练许多具有不同历元和vector_sizes的模型,然后使用infer_vector和most_similar函数查看从most_like条目返回的矢量分数是否大于某个数值,但是有什么方法可以对此方面进行改进训练模型?
此外,为了获得更好的结果,我以较大的数据集(超过100k个条目)以相同的方式训练了另一个模型。当我在相同的数据集上使用该模型时,与在较小的数据集上训练的模型相比,产生的结果相似但更差。我认为更多的训练数据会改善结果,但又不会使结果更糟,有人知道原因吗?
此外,为了进一步测试,我创建了一个新的但更大的测试集(1.5万个条目),其效果甚至比原始测试集还要差。该测试集中的数据虽然唯一,但与原始测试集中使用的数据类型相同,但产生的结果却更糟,这可能是什么原因?
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")
答案 0 :(得分:0)
听起来好像您是在为每个论坛的“进” /“出”决策训练一个单独的Doc2Vec
模型,然后使用一组临时的infer_vector()
/ most_similar()
操作来做决定。
这是一种非常粗糙的临时方法,您应该查看更正式的文本分类方法的介绍,在此过程中,有一个明确的功能发现步骤(可能包括为您创建Doc2Vec
矢量)文字或其他技术),然后再进行清晰的分类器训练,然后进行评估。
(此时您可能还正在训练更大的模型,包括来自所有论坛的带有标签的训练示例,以及从多个可能的类别中选择一个的分类器。)
另外,在您的Doc2Vec
培训中,有几件事是错误的或非最佳的,包括:
在您自己的循环中多次调用train()
或更改默认alpha
/ min_alpha
几乎总是被误导。实际上,您当前的代码实际上是使model.epochs
(5)传递每次调用的数据,并且经常将alpha
递减0.0002
数百次(变为无意义的负值)。只需一次调用train()
,并以所需的epochs
数目,默认值alpha
/ min_alpha
调用hs=5
,它将做正确的事情。 (并且:不要相信上面的循环调用所建议的任何在线教程/示例。)
您的negative=5
将打开/关闭严格打开的分级-softmax模式,但保留默认的negative
参数-因此您的模型将使用(非标准否定采样和分层softmax训练的结合可能很无用和缓慢)。最好使用一些hs=0
值和negative=0, hs=1
(用于纯负采样),或者使用negative=5, hs=0
(用于纯分层softmax)。或者只是坚持使用默认值(min_count=1
),除非/直到所有事情都已经生效并且您想进行更深入的优化为止。
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
print("\(URLContexts.first!.url)")
}
很少是最佳选择:这些模型通常受益于丢弃稀有词。
更正了这些问题之后,您可能会发现,更多的数据将趋于带来通常预期的改进结果。 (如果那时还不行,请在培训,推理和评估时仔细检查所有文本预处理/标记是否正确完成;如果您仍然有问题,则可以再提出一个新问题,并提供更多详细信息/数字,指出预期的改进结果却差一些。)