【问题标题】:Scikitlearn - score dataset after cross-validationScikit Learn - 交叉验证后的评分数据集
【发布时间】:2017-06-23 21:05:36
【问题描述】:

我正在学习使用 scikit-learn (http://scikit-learn.org/stable/modules/cross_validation.html) 进行交叉验证

我的代码:

from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import cross_val_score
from sklearn import datasets
from sklearn import svm

iris = datasets.load_iris()

# prepare sets
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=0)

# create model
clf1 = svm.SVC(kernel='linear', C=1)

# train model
scores = cross_val_score(clf1, x_train, y_train, cv=5)

# accuracy on train data
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))

# accuracy on yet-unseen data
print clf1.score(x_test, y_test)

我知道通过交叉验证,我们可以使用整个数据集来训练和验证,如 scikit doc 中的示例。如果我想在交叉验证后对数据进行评分怎么办?我假设我的模型是在通过交叉验证学习后进行训练的。在使用score() 时,我得到了

raise NotFittedError(msg % {'name': type(estimator).__name__})
sklearn.utils.validation.NotFittedError: This SVC instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.

在文档中有方法第 3.1.1.1 段,其中提到了cross_val_predict,我可以使用它,但为什么我需要 cv 参数(即折叠数)而我只想检查训练模型的准确性?

如有任何提示,我将不胜感激。

【问题讨论】:

  • 有多种类型的分数供您决定您想要哪一种。您可以查看 sci kit 学习文档但是对于这种情况您可以查看交叉验证指标:scikit-learn.org/stable/modules/cross_validation.html,希望这会有所帮助!@PawelPawel
  • cross_val_score 不适合作为参数传递的模型对象,但会创建副本以保持每个折叠独立。您现在必须手动实际拟合模型。此外,将数据传递给cross_val_score 之前,不要将数据拆分为训练集和测试集,这对你来说是...
  • 您需要了解交叉验证的目的是什么——它是为了获得一个通用指标的估计,也就是说,您的模型将如何处理看不见的数据。您不会“使用交叉验证训练模型”,
  • 但是你为什么想要一个分数?想知道交叉验证的准确性?
  • @juanpa.arrivillaga 好点,但为什么交叉验证在小数据集的情况下如此有用?它提供了指标,还有什么?

标签: python machine-learning scikit-learn


【解决方案1】:

这是一个完成工作的代码,并逐步解释了它的工作原理。

首先,让我们导入必要的模块:

In [204]: from sklearn.model_selection import cross_val_score, StratifiedKFold

In [205]: from sklearn import datasets

In [206]: from sklearn import svm

你应该确定你已经安装了scikit-learn 0.18,否则下面的代码可能无法运行。请注意,我使用的是 sklearn.model_selection 而不是 sklearn.cross_validation,因为后者在 0.18 版中已被弃用。

然后我们加载 iris 数据集并分别使用特征和标签创建数组 Xy

In [207]: iris = datasets.load_iris()

In [208]: X, y = iris.data, iris.target

在下一步中,我们创建 C 支持向量分类类的实例:

In [209]: clf = svm.SVC(kernel='linear', C=1)

现在我们创建一个分层的 K-Folds 验证器,它将数据集分成 5 个不相交的子集,即 A、B、C、D 和 E。这五个折叠是分层的,这意味着 A 中每个类的样本比例, B, C, D 和 E 与整个数据集中的相同。

In [210]: skf = StratifiedKFold(n_splits=5, random_state=0)

最后,我们通过 5 次分类试验来估计泛化精度:

In [211]: scores = cross_val_score(clf, X, y, cv=skf)

In [212]: scores
Out[212]: array([ 0.9667,  1.    ,  0.9667,  0.9667,  1.    ])

In [213]: scores.mean()
Out[213]: 0.98000000000000009

5-Folds 交叉验证可以总结如下:

Classification No.   Training Samples   Test Samples   Accuracy
1                    A + B + C + D      E              0.9667
2                    A + B + C + E      D              1.
3                    A + B + D + E      C              0.9667
4                    A + C + D + E      B              0.9667
5                    B + C + D + E      A              1.

从上表可以清楚地看出,每个样本用于训练四次,只测试一次。

回复您的其他 cmets:

  1. 交叉验证的主要优点是所有样本都用于训练和测试,即交叉验证为您提供最大的建模和测试能力,这在数据集较小时尤其重要。
  2. 避免过度拟合的一种方法是使用不同的样本进行训练和测试。
  3. 选择模型参数的一种常用方法是针对不同的参数集验证模型并选择能够最大限度提高分类准确度的值。

【讨论】:

  • 感谢您提供如此详细的回答。我从 cmets 那里得到了关于它是如何工作的想法。这是我的误解,因为我认为交叉验证实际上是一种学习方式。我现在的问题是,如何使用交叉验证?为什么它在小数据集的情况下有帮助?因为我们可以使用整个数据集进行训练?交叉验证用于为模型选择正确的参数以避免过度拟合?读完这个例子后我觉得是这样的:scikit-learn.org/stable/auto_examples/exercises/…谢谢你的回答!
猜你喜欢
  • 2014-07-30
  • 1970-01-01
  • 2018-04-02
  • 2016-02-11
  • 2016-04-25
  • 2017-09-02
  • 1970-01-01
  • 2015-12-11
  • 2019-06-09
相关资源
最近更新 更多