我不确定如何使用Scikit Learn解释此分类的准确性



我正在尝试用Scikit Learn对文本数据进行分类,方法如下所示。(http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html)除非我正在加载我自己的数据集

我正在得到结果,但是我想找到分类结果的准确性。

    from sklearn.datasets import load_files
    text_data = load_files("C:/Users/USERNAME/projects/machine_learning/my_project/train", description=None, categories=None, load_content=True, shuffle=True, encoding='latin-1', decode_error='ignore', random_state=0)
    from sklearn.pipeline import Pipeline
    from sklearn.linear_model import SGDClassifier
    text_clf = Pipeline([('vect', CountVectorizer()),
                        ('tfidf', TfidfTransformer()),
                        ('clf', LinearSVC(loss='hinge', penalty='l2',
                                                random_state=42)),
    ])
    _ = text_clf.fit(text_data.data, text_data.target)
    docs_new = ["Some test sentence here.",]
    predicted = text_clf.predict(docs_new)
    print np.mean(predicted == text_data.target) 
    for doc, category in zip(docs_new, predicted):
        print('%r => %s' % (doc, text_data.target_names[predicted]))

这里,我得到了np。平均预测值为0.566。

如果我尝试:

twenty_test = load_files("C:/Users/USERNAME/projects/machine_learning/my_project/testing", description=None, categories=None, load_content=True, shuffle=True, encoding='latin-1', decode_error='ignore', random_state=0)
docs_test = twenty_test.data
predicted = text_clf.predict(docs_test)
np.mean(predicted == twenty_test.target)

现在它打印为1。

我不明白这是如何工作的,以及np到底是什么。均值是什么,以及为什么在相同的数据上训练时它会显示不同的结果。

"train"文件夹大约有15个文档,文本文件夹也大约有15个文档,以防万一。我对Scikit Learn和机器学习非常陌生,所以任何帮助都非常感谢。谢谢!

text_data = load_files("C:/Users/USERNAME/projects/machine_learning/my_project/train", ...)

根据文档,这一行将文件的内容从C:/Users/USERNAME/projects/machine_learning/my_project/train加载到text_data.data。它还将每个文档的目标标签(由它们的整数索引表示)加载到text_data.target中。所以text_data.data应该是一个字符串列表,text_data.target应该是一个整数列表。标签派生自文件所在的文件夹。你的解释听起来好像你在C:/.../train/C:/.../test/中没有任何子文件夹,这可能会产生问题(例如所有标签都是相同的)。

from sklearn.pipeline import Pipeline
from sklearn.linear_model import SGDClassifier
text_clf = Pipeline([('vect', CountVectorizer()),
                    ('tfidf', TfidfTransformer()),
                    ('clf', LinearSVC(loss='hinge', penalty='l2',
                                            random_state=42)),
])
_ = text_clf.fit(text_data.data, text_data.target)

上面的行是在示例文档上训练(在.fit()中)一个分类器。粗略地说,您告诉分类器(LinearSVC)哪些单词在哪些文档(CountVectorizerTfidfTransformer)中出现的频率,以及这些文档中的每个文档都有哪些标签(text_data.target)。然后你的分类器尝试学习一个基本将这些词频率(TF-IDF值)映射到标签的规则(例如dogcat强烈指示标签animal)。

docs_new = ["Some test sentence here.",]
predicted = text_clf.predict(docs_new)

在示例数据上训练分类器之后,您提供一个全新的文档,并让分类器根据所学内容预测该文档的最合适标签。然后predicted应该是一个只有一个元素的标签(索引)列表(因为你有一个文档),例如[5]

print np.mean(predicted == text_data.target)

在这里,您将预测列表(1个元素)与来自训练数据的标签列表(15个元素)进行比较,然后取结果的平均值。这没有多大意义,因为列表大小不同,而且你的新示例文档与训练标签没有任何关系。Numpy可能会将您预测的标签(例如5)与text_data.target中的每个元素进行比较。这将创建一个类似[False, False, False, True, False, True, ...]的列表,np.mean将其解释为[0, 0, 0, 1, 0, 1, ...],从而导致平均值为1/15 * (0+0+0+1+0+1+...)

你应该做的是,例如:

docs_new = ["Some test sentence here."]
docs_new_labels = [1] # correct label index of the document
predicted = text_clf.predict(docs_new)
print np.mean(predicted == docs_new_labels) 

至少你不应该比较你的训练标签。注意,如果np.mean返回1,则所有文档都被正确分类。在测试数据集的情况下,这种情况似乎发生了。确保您的测试和训练数据文件实际上是不同的,因为100%的准确性并不常见(然而,可能是您的训练文件数量少的产物)。顺便说一下,请注意我们目前没有使用标记化,所以对于您的分类器herehere.将是完全不同的单词。

precict()返回给定未知文本的预测类标签数组。

docs_new = ['God is love', 'OpenGL on the GPU is fast', 'java', '3D', 'Cinema 4D']
predicted = clf.predict(X_new_tfidf)
print predicted
for doc, category in zip(docs_new, predicted):
    print('%r => %s' % (doc, twenty_train.target_names[category]))
[3 1 2 1 1]
'God is love' => soc.religion.christian
'OpenGL on the GPU is fast' => comp.graphics
'java' => sci.med
'3D' => comp.graphics
'Cinema 4D' => comp.graphics

可以看到,predicted返回一个数组。数组中的数字对应于标签的索引,这些索引将在随后的for循环中访问。

当您执行np.mean时,这是为了确定分类器的准确性,并且不适用于您的第一个示例,因为文本"Some text here"没有标签。然而,这段文字可以用来预测它属于哪个标签。这可以在脚本中通过更改:

来实现:
for doc, category in zip(docs_new, predicted):
    print('%r => %s' % (doc, text_data.target_names[predicted]))

:

for doc, category in zip(docs_new, predicted):
    print('%r => %s' % (doc, text_data.target_names[category]))

当你对np.mean的第二次调用返回1时,这意味着分类器能够100%准确地预测未见过的文档到它们的正确标签。因为,twenty_test数据也有标签信息。

要获得关于分类器准确性的进一步信息,您可以:

from sklearn import metrics
print(metrics.classification_report(twenty_test.target, predicted,
    target_names=twenty_test.target_names)) 

                        precision    recall  f1-score   support
           alt.atheism       0.95      0.81      0.87       319
         comp.graphics       0.88      0.97      0.92       389
               sci.med       0.94      0.90      0.92       396
soc.religion.christian       0.90      0.95      0.93       398
           avg / total       0.92      0.91      0.91      1502

如果你想要一个混淆矩阵,你可以:

metrics.confusion_matrix(twenty_test.target, predicted)
array([[258,  11,  15,  35],
       [  4, 379,   3,   3],
       [  5,  33, 355,   3],
       [  5,  10,   4, 379]])

相关内容

  • 没有找到相关文章

最新更新