python sklearn:accuracy_score和learning_curve得分有什么区别?

ana*_*hbv 9 python scikit-learn

我正在使用Python sklearn(版本0.17)来选择数据集上的理想模型.为此,我按照以下步骤操作:

  1. 使用cross_validation.train_test_splitwith 拆分数据集test_size = 0.2.
  2. 用于GridSearchCV在训练集上选择理想的k近邻分类器.
  3. 通过返回的分类GridSearchCVplot_learning_curve.plot_learning_curve给出了如下所示的情节.
  4. 运行在GridSearchCV获得的测试集上返回的分类器.

从情节来看,我们可以看到最高分数.训练规模约为0.43.该分数是sklearn.learning_curve.learning_curve函数返回的分数.

但是当我在测试集上运行最佳分类器时,我得到的准确度分数为0.61,如sklearn.metrics.accuracy_score(正确预测的标签/标签数量)所返回

链接到图像: KNN分类器的图表

这是我正在使用的代码.我没有包含该plot_learning_curve功能,因为它需要占用大量空间.我plot_learning_curve这里拿走了

import pandas as pd
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from matplotlib import pyplot as plt
import sys
from sklearn import cross_validation
from sklearn.learning_curve import learning_curve
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import train_test_split


filename = sys.argv[1]
data =  np.loadtxt(fname = filename, delimiter = ',')
X = data[:, 0:-1]  
y = data[:, -1]   # last column is the label column


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2)

params = {'n_neighbors': [2, 3, 5, 7, 10, 20, 30, 40, 50], 
          'weights': ['uniform', 'distance']}

clf = GridSearchCV(KNeighborsClassifier(), param_grid=params)
clf.fit(X_train, y_train)
y_true, y_pred = y_test, clf.predict(X_test)
acc = accuracy_score(y_pred, y_test)
print 'accuracy on test set =', acc

print clf.best_params_
for params, mean_score, scores in clf.grid_scores_:
    print "%0.3f (+/-%0.03f) for %r" % (
        mean_score, scores.std() / 2, params)

y_true, y_pred = y_test, clf.predict(X_test)
#pred = clf.predict(np.array(features_test))
acc = accuracy_score(y_pred, y_test)
print classification_report(y_true, y_pred)
print 'accuracy last =', acc
print

plot_learning_curve(clf, "KNeighborsClassifier", 
                X, y, 
                train_sizes=np.linspace(.05, 1.0, 5))
Run Code Online (Sandbox Code Playgroud)

这是正常的吗?我可以理解得分可能会有所不同,但这是0.18的差异,转换为百分比时的差异为43%,而61%.classification_report还给出了平均0.61的召回率.

难道我做错了什么?learning_curve计算得分有何不同?我也试图通过scoring='accuracy'learning_curve功能,看它是否准确度得分相匹配,但它并没有任何区别.

任何建议都会有很大帮助.

我正在使用UCI的葡萄酒质量(白色)数据集,并在运行代码之前删除了标题.

Gui*_*sch 8

当您调用该learning_curve函数时,它会对您的整个数据执行交叉验证.当您将cv参数留空时,它是一个3倍交叉验证拆分策略.这里有一个棘手的部分,因为如文档中所述"如果估计器是分类器,或者如果y既不是二元也不是多类,则使用KFold ".而你的估算器是一个分类器.

那么,KFold和StratifiedKFold之间有什么区别?

KFold =将数据集拆分为k个连续折叠(默认情况下不进行洗牌)

StratifiedKFold ="折叠是通过保留每个类别的样本百分比来实现的."

我们举一个简单的例子:

  • 您的数据标签是[4.0,4.0,4.0,5.0,5.0,5.0,6.0,6.0,6.0]
  • 通过未分层3倍的子集划分:[4.0,4.0,4.0],[5.0,5.0,5.0],[6.0,6.0,6.0]
  • 然后每个折叠使用一次验证集,而k-1(3-2)剩余折叠形成训练集.因此,例如,将在[5.0,5.0,5.0,6.0,6.0,6.0]上进行培训并在[4.0,4.0,4.0]上进行验证

这解释了您的学习曲线的低精度(~0.43%).当然,这是一个极端的例子来说明这种情况,但是你的数据是以某种方式构建的,你需要对它进行改组.

但是当你获得~61%的准确度时,你通过方法分割数据train_test_split,默认情况下对数据进行混洗并保持比例.

看看这个,我做了一个简单的测试来支持我的假设:

X_train2, X_test2, y_train2, y_test2 = train_test_split(X, y, test_size=0., random_state=2)
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您learning_curve使用了所有数据X,y.我在这里做了一个小技巧,即分割数据,test_size=0.这意味着所有数据都在train变量中.这样我仍然可以保留所有数据,但现在它通过该train_test_split功能进行了随机播放.

然后我调用了你的绘图函数,但是随机数据被调整:

plot_learning_curve(clf, "KNeighborsClassifier",X_train2, y_train2, train_sizes=np.linspace(.05, 1.0, 5))
Run Code Online (Sandbox Code Playgroud)

现在,最大NUM训练样本的输出,而不是0.430.59这使得很多更有意义与GridSearch结果.

观察:我觉得绘制学习曲线的整点是确定阉增加更多的样本训练集我们估计能有更好的表现还是没有(这样你就可以决定,例如当没有必要添加更多的例子).正如train_sizes您只是提供值,np.linspace(.05, 1.0, 5) --> [ 0.05 , 0.2875, 0.525 , 0.7625, 1. ]我不完全确定这是您在此类测试中所使用的用法.