让我们先解释整个目标,然后解决问题。
我正在使用 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,我的意思是差异已经减小