为什么数据清理会降低准确性?

时间:2019-11-27 10:45:46

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

使用scikit中的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

1 个答案:

答案 0 :(得分: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应该是包含

的任何子集的元组

总结:

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