基于doc2vec和gensim的文本分类模型

2024-04-18 03:24:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用gensim和doc2vec进行文本分类。我使用两个数据集来测试这个,一个是堆栈交换数据集,另一个是Reddit数据集。我试图对某个主题的subreddit/stackexchange站点的帖子进行分类,然后使用其他不相关subreddit/stackexchange站点的帖子作为反面例子。你知道吗

我正在使用一个由10k帖子组成的数据集来训练模型,一个由5k帖子组成的测试集被分成50%的正面例子和50%的负面例子。然后我使用推断向量和最相似的函数将条目分类为正或负。在训练模型之前,我先对数据进行预处理,去掉任何单词、符号、链接等,只留下最重要的单词来训练模型。下面是用来训练模型的代码。你知道吗

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")

这种方法是有效的,我可以从中得到结果,但我想知道是否有一种不同的培训方式,以达到更好的效果。目前我只是在训练很多不同年代和向量大小的模型,然后使用推断向量和最相似函数来查看最相似条目返回的向量得分是否大于某个数,但是在训练模型方面有没有改进的方法?你知道吗

另外,为了得到更好的结果,我用同样的方法训练了另一个模型,使用更大的数据集(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")

Tags: 数据in模型alphadffordatasize
1条回答
网友
1楼 · 发布于 2024-04-18 03:24:03

听起来好像你在为每个论坛的“入”/“出”决策训练一个独立的Doc2Vec模型,然后使用一组临时的infer_vector()/most_similar()操作来做出决策。你知道吗

这是一个非常粗糙的、特别的方法,您应该了解更多正式的文本分类方法的介绍,其中有一个明确的特征发现步骤(可能包括为您的文本创建Doc2Vec向量或其他技术),然后是一个明确的分类器训练步骤,然后是评估步骤。你知道吗

(此时,您还可以训练更大的模型,其中包括来自所有论坛的标记训练示例,以及从许多可能的类中选择一个的分类器。)

另外,在你的Doc2Vec训练中有几件事是错误的或非最佳的,包括:

  • 在自己的循环中多次调用train(),或者更改默认的alpha/min_alpha值,几乎总是被误导的。您当前的代码实际上是model.epochs(5)为每个调用传递数据,并且经常将alpha递减0.0002数百倍(变成无意义的负值)。只调用train()一次,使用所需的epochs数目,使用默认的alpha/min_alpha值,它将做正确的事情。(并且:不要相信任何在线教程/示例建议的上述循环调用。)

  • 您的hs=5将打开严格的开/关分层softmax模式,但保留默认的negative=5参数-因此您的模型将使用负采样和分层softmax训练的组合(非标准的,可能没有帮助和缓慢的)。最好使用一些negative值和hs=0(对于纯负采样),或者negative=0, hs=1(对于纯分层softmax)。或者只使用默认值(negative=5, hs=0),除非/直到一切都已经开始工作,并且您希望进入更深入的优化。

  • min_count=1很少是最好的选择:这些模型通常受益于丢弃稀有词。

在纠正这些问题之后,您可能会发现更多的数据往往会带来通常预期的改进结果。(如果当时没有,请再次检查所有的文本预处理/标记化是否在培训、推理和评估时正确完成——如果您仍然有问题,那么可以发布一个新的问题,并提供更多的细节/数字,说明预期的改进在何处得分更差。)

相关问题 更多 >