【问题标题】:Why data cleaning decreases accuracy?为什么数据清洗会降低准确性?
【发布时间】:2020-03-22 21:39:16
【问题描述】:

使用 scikit learn 中的 20 个新闻组来获得可重复性。当我训练一个 svm 模型,然后通过删除页眉、页脚和引号来执行数据清理时,准确性会降低。不是应该通过数据清理来改进吗?做所有这些然后获得更差的准确性有什么意义?

我创建了这个带有数据清理的示例,以帮助您理解我所指的内容:

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import accuracy_score
categories = ['alt.atheism', 'comp.graphics']
newsgroups_train = fetch_20newsgroups(subset='train', categories=categories, shuffle=True, random_state=2017, 
                                    remove=('headers', 'footers', 'quotes')  )
newsgroups_test = fetch_20newsgroups(subset='test', categories=categories,shuffle=True, random_state=2017, 
                                    remove=('headers', 'footers', 'quotes') )
y_train = newsgroups_train.target
y_test = newsgroups_test.target

vectorizer = TfidfVectorizer(sublinear_tf=True, smooth_idf = True, max_df=0.5,  ngram_range=(1, 2),stop_words='english')
X_train = vectorizer.fit_transform(newsgroups_train.data)
X_test = vectorizer.transform(newsgroups_test.data)


from sklearn.svm import SVC
from sklearn import metrics

clf = SVC(C=10, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma=1, kernel='rbf', max_iter=-1,
    probability=False, random_state=None, shrinking=True, tol=0.001,
    verbose=False)
clf = clf.fit(X_train, y_train)
y_train_pred = clf.predict(X_train)
y_test_pred = clf.predict(X_test)
print('Train accuracy_score: ', metrics.accuracy_score(y_train, y_train_pred))
print('Test accuracy_score: ',metrics.accuracy_score(newsgroups_test.target, y_test_pred))
print("-"*12)
print("Train Metrics: ", metrics.classification_report(y_train, y_train_pred))
print("-"*12)
print("Test Metrics: ", metrics.classification_report(newsgroups_test.target, y_test_pred))

数据清洗前的结果:

Train accuracy_score:  1.0
Test accuracy_score:  0.9731638418079096

数据清洗后的结果:

Train accuracy_score:  0.9887218045112782
Test accuracy_score:  0.9209039548022598

【问题讨论】:

    标签: python machine-learning scikit-learn statistics cross-validation


    【解决方案1】:

    不一定是你的数据清理,我假设你运行脚本两次?

    问题出在这行代码:

    clf = SVC(C=10, cache_size=200, class_weight=None, coef0=0.0,
        decision_function_shape='ovr', degree=3, gamma=1, kernel='rbf', max_iter=-1,
        probability=False, random_state=None, shrinking=True, tol=0.001,
        verbose=False)
    

    random_state=None您应该将随机状态固定为例如random_state=42,否则你无法产生相同的结果,如果你现在再次运行这段代码,你将再次得到不同的结果。

    编辑:

    解释在dataset 网站本身: 如果你实施:

    import numpy as np
    def show_top10(classifier, vectorizer, categories):
     feature_names = np.asarray(vectorizer.get_feature_names())
     for i, category in enumerate(categories):
       top10 = np.argsort(classifier.coef_[i])[-10:]
       print("%s: %s" % (category, " ".join(feature_names[top10])))
    

    您现在可以看到这些功能已经过拟合的许多东西:

    几乎每个组都通过诸如 NNTP-Posting-Host: 和 Distribution: 之类的标头是否经常出现来区分。

    另一个重要特征涉及发件人是否隶属于大学,如其标题或签名所示。

    “文章”这个词是一个重要的特征,基于人们引用以前帖子的频率是这样的:“在文章 [文章 ID],[名称] 写道:”

    其他功能与当时发帖的特定人员的姓名和电子邮件地址相匹配。

    有了如此丰富的区分新闻组的线索,分类器几乎不需要从文本中识别出主题,而且它们的性能都一样高。

    因此,加载 20 个新闻组数据的函数提供了一个名为 remove 的参数,告诉它要从每个文件中删除哪些类型的信息。 remove 应该是一个包含

    的任何子集的元组

    总结:

    删除的东西可以防止你的数据泄露,这意味着你的训练数据中有你在预测阶段没有的信息,所以你必须删除它,否则你会得到更好的结果,但这将是没有新数据。

    【讨论】:

    • 实施建议后,没有任何改变。你得到不同的结果吗?您可以轻松地在您的电脑上运行此代码。如果您不想进行数据清理,只需从训练和测试变量中删除 remove=('headers', 'footers', 'quotes') 部分。
    • 谢谢,很棒的发现,这是 Bunch 类型。如果我将数据集作为数据框上传,但我该如何做相当于remove 来删除页眉页脚等?
    • 当你上传newsgroup_train你有它,没有得到你的问题,但如果这个问题不同,它不在我们这里的范围内
    猜你喜欢
    • 2020-11-19
    • 2020-06-22
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 2020-04-20
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多