为什么 LDA 模型的准确率总是在变化并且还很高

数据挖掘 scikit-学习 支持向量机 多类分类 主题模型 低密度脂蛋白
2022-02-20 03:29:59

让我们先解释整个目标,然后解决问题。

我正在使用 LAtent Dirichlet Allocation 和 NMF 等主题建模从文档集合中提取主题。

我的数据集是 PubMed,我使用了这个集合的大约三个类别并浏览了摘要部分(每个类别中有 10 个摘要文件,所以我总共有 30 个摘要)

在对我的数据应用 LDA 之后,为了评估过程,为了查看为每个文档生成的主题的准确性,我使用 sklearn 中的 OneVsRestClassifier 对其进行了评估。

由于 OneVsRestClassifier 是一种分类方法,它需要数据有标签,所以我将解释我是如何为 LDA 模型的输出生成标签的。

在 LDA 中,我使用了文档主题矩阵,这个矩阵就像每个文档都有一些主题一样。对于主题,有概率显示该主题属于该文档的概率。

所以每一行的标签是主题的最高概率(显示主题的索引,例如第一列中的概率显示主题0的概率)。

希望解释清楚,如果没有,请告诉我,我会用例子详细说明。

这是执行上述方法的代码:

import os

from nltk.tokenize import RegexpTokenizer
from nltk.stem.porter import PorterStemmer
from sklearn.cross_validation import train_test_split
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import LinearSVC
import numpy as np
from sklearn import metrics

tokenizer = RegexpTokenizer(r'\w+')

# Create p_stemmer of class PorterStemmer
lines=[]
p_stemmer = PorterStemmer()
lisOfFiles=[x[2] for x in os.walk("data")]

fullPath = [x[0] for x in os.walk("data")]

for j in lisOfFiles[2]:
    with open(os.path.join(fullPath[2],j)) as f:
                    a=f.read()
                    lines.append(a)


for j in lisOfFiles[3]:
    with open(os.path.join(fullPath[3],j)) as f:
                    a=f.read()
                    lines.append(a)

for j in lisOfFiles[4]:
    with open(os.path.join(fullPath[4],j)) as f:
                    a=f.read()
                    lines.append(a)

# compile sample documents into a list
doc_set = lines

tf_vectorizer = CountVectorizer(max_features=1000,
                                stop_words='english')

tf = tf_vectorizer.fit_transform(doc_set)

# Trains the LDA models.
lda = LatentDirichletAllocation(n_topics=10, max_iter=5,
                                learning_method='online',
                                learning_offset=50.,
                                random_state=0)

lda_x=lda.fit_transform(tf)

#creating the labels

new_y = np.argmax(lda_x, axis=1)

Xtrain, Xvalidate, ytrain, yvalidate = train_test_split(lda_x, new_y, test_size=.3)

predictclass=OneVsRestClassifier(LinearSVC(random_state=0)).fit(Xtrain, ytrain).predict(Xvalidate)
yacc=metrics.accuracy_score(yvalidate,predictclass)
print (yacc)

现在我的问题:

当我运行这段代码时,似乎大部分时间都给了我 100 的准确度:|

当我运行它几次时,精度正在变化,并且永远不会低于 66,但它在 66 和 100 之间变化,并且大部分时间是 100。

我知道这些变化是因为 LDA 的随机抽样。首先,我相信我的代码有问题,我得到了很好的准确性。

其次,如果精度像这样变化,哪一个是可靠的,有没有办法在一个输出中修复它?

我的 NMF 模型也发生了同样的过程。

我的怀疑

我唯一的疑问是我正在处理的数据。正如我在第一段中解释的那样,它包含30个摘要文件,我已经转移到一个列表中,所以我有一个逗号分隔的列表,但是如果摘要文件已经有逗号,它如何实现正确的文档?! !!

但我通过迭代列表并获取列表的大小来测试它,它是 30**

更新 2

当我将数据从 300 摘要更改为 3000 摘要时,准确性仍在变化,但仅从 93 更改为 97,我的意思是差异已经减小

0个回答
没有发现任何回复~