资讯专栏INFORMATION COLUMN

Cross Validation交叉验证

Near_Li / 2181人阅读

摘要:常见的交叉验证方法如下将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此分类器的性能指标。

训练集 vs. 测试集

在模式识别(pattern recognition)与机器学习(machine learning)的相关研究中,经常会将数据集(dataset)分为训练集(training set)跟测试集(testing set)这两个子集,前者用以建立模型(model),后者则用来评估该模型对未知样本进行预测时的精确度,正规的说法是泛化能力(generalization ability)。
怎么将完整的数据集分为训练集跟测试集,必须遵守如下要点:

1、只有训练集才可以用在模型的训练过程中,测试集则必须在模型完成之后才被用来评估模型优劣的依据。

2、训练集中样本数量必须够多,一般至少大于总样本数的50%。

3、两组子集必须从完整集合中均匀取样。

其中最后一点特别重要,均匀取样的目的是希望减少训练集/测试集与完整集合之间的偏差(bias),但却也不易做到。一般的作法是随机取样,当样本数量足够时,便可达到均匀取样的效果,然而随机也正是此作法的盲点,也是经常是可以在数据上做手脚的地方。举例来说,当辨识率不理想时,便重新取样一组训练集/测试集,直到测试集的识别率满意为止,但严格来说这样便算是作弊了。# 交叉验证(Cross Validation)

交叉验证(Cross Validation)是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(training set),另一部分做为验证集(validation set),首先用训练集对分类器进行训练,在利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标。常见的交叉验证方法如下:

Hold-Out Method

将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此分类器的性能指标。此种方法的好处的处理简单,只需随机把原始数据分为两组即可,其实严格意义来说Hold-Out Method并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性。

Double Cross Validation(2-fold Cross Validation,记为2-CV)

做法是将数据集分成两个相等大小的子集,进行两回合的分类器训练。在第一回合中,一个子集作为training set,另一个便作为testing set;在第二回合中,则将training set与testing set对换后,再次训练分类器,而其中我们比较关心的是两次testing sets的辨识率。不过在实务上2-CV并不常用,主要原因是training set样本数太少,通常不足以代表母体样本的分布,导致testing阶段辨识率容易出现明显落差。此外,2-CV中分子集的变异度大,往往无法达到“实验过程必须可以被复制”的要求。

K-fold Cross Validation(K-折交叉验证,记为K-CV)

将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标。K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2。K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性。

K-fold cross-validation (k-CV)则是double cross-validation的延伸,作法是将dataset切成k个大小相等的subsets,每个subset皆分别作为一次test set,其余样本则作为training set,因此一次k-CV的实验共需要建立k个models,并计算k次test sets的平均辨识率。在实作上,k要够大才能使各回合中的training set样本数够多,一般而言k=10算是相当足够了。

Leave-One-Out Cross Validation(记为LOO-CV)

如果设原始数据有N个样本,那么LOO-CV就是N-CV,即每个样本多带带作为验证集,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标。相比于前面的K-CV,LOO-CV有两个明显的优点:

(1)每一回合中几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得的结果比较可靠。

(2)实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。
但LOO-CV的缺点则是计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,LOO-CV在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间。

使用Cross-Validation时常犯的错误

由于实验室许多研究都有用到 evolutionary algorithms(EA)与 classifiers,所使用的 fitness function 中通常都有用到 classifier 的辨识率,然而把cross-validation 用错的案例还不少。前面说过,只有 training data 才可以用于 model 的建构,所以只有 training data 的辨识率才可以用在 fitness function 中。而 EA 是训练过程用来调整 model 最佳参数的方法,所以只有在 EA结束演化后,model 参数已经固定了,这时候才可以使用 test data。那 EA 跟 cross-validation 要如何搭配呢?Cross-validation 的本质是用来估测(estimate)某个 classification method 对一组 dataset 的 generalization error,不是用来设计 classifier 的方法,所以 cross-validation 不能用在 EA的 fitness function 中,因为与 fitness function 有关的样本都属于 training set,那试问哪些样本才是 test set 呢?如果某个 fitness function 中用了cross-validation 的 training 或 test 辨识率,那么这样的实验方法已经不能称为 cross-validation 了。

EA 与 k-CV 正确的搭配方法,是将 dataset 分成 k 等份的 subsets 后,每次取 1份 subset 作为 test set,其余 k-1 份作为 training set,并且将该组 training set 套用到 EA 的 fitness function 计算中(至于该 training set 如何进一步利用则没有限制)。因此,正确的 k-CV 会进行共 k 次的 EA 演化,建立 k 个classifiers。而 k-CV 的 test 辨识率,则是 k 组 test sets 对应到 EA 训练所得的 k 个 classifiers 辨识率之平均值。

示例
import numpy as np
from sklearn import cross_validation
from sklearn import datasets
from sklearn import svm

iris = datasets.load_iris()
iris.data.shape, iris.target.shape
((150, 4), (150,))

We can now quickly sample a training set while holding out 40% of the data for testing (evaluating) our classifier:

X_train, X_test, y_train, y_test = cross_validation.train_test_split(
...     iris.data, iris.target, test_size=0.4, random_state=0)
X_train.shape, y_train.shape

((90, 4), (90,))

X_test.shape, y_test.shape

((60, 4), (60,))

clf = svm.SVC(kernel="linear", C=1).fit(X_train, y_train)
clf.score(X_test, y_test)   

0.96666666666666667

Computing cross-validated metrics

The simplest way to use cross-validation is to call the cross_val_score helper function on the estimator and the dataset.
The following example demonstrates how to estimate the accuracy of a linear kernel support vector machine on the iris dataset by splitting the data, fitting a model and computing the score 5 consecutive times (with different splits each time):

clf = svm.SVC(kernel="linear", C=1)
# 使用iris数据集对linear kernel的SVM模型做5折交叉验证
scores = cross_validation.cross_val_score(clf, iris.data, iris.target, cv=5)
scores  

array([ 0.96666667, 1. , 0.96666667, 0.96666667, 1. ])
The mean score and the 95% confidence interval of the score estimate are hence given by:

print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))

Accuracy: 0.98 (+/- 0.03)
By default, the score computed at each CV iteration is the score method of the estimator. It is possible to change this by using the scoring parameter:
See The scoring parameter: defining model evaluation rules for details. In the case of the Iris dataset, the samples are balanced across target classes hence the accuracy and the F1-score are almost equal.
When the cv argument is an integer, cross_val_score uses the KFold or StratifiedKFold strategies by default, the latter being used if the estimator derives from ClassifierMixin.

#用各类的f1平均值做为score
from sklearn import metrics
scores = cross_validation.cross_val_score(clf, iris.data, iris.target,cv=5, scoring="f1_weighted")
scores                 

array([ 0.96658312, 1. , 0.96658312, 0.96658312, 1. ])

用Crossvalidation做Gird Search
>>> from sklearn import svm, datasets
>>> from sklearn.model_selection import GridSearchCV
>>> iris = datasets.load_iris()
>>> parameters = {"kernel":("linear", "rbf"), "C":[1, 10]}
>>> svr = svm.SVC()
>>> clf = GridSearchCV(svr, parameters,cv=5,scoring="f1_weighted")
>>> clf.fit(iris.data, iris.target)
GridSearchCV(cv=5, error_score="raise",
       estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma="auto", kernel="rbf",
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False),
       fit_params={}, iid=True, n_jobs=1,
       param_grid={"C": [1, 10], "kernel": ("linear", "rbf")},
       pre_dispatch="2*n_jobs", refit=True, return_train_score=True,
       scoring="f1_weighted", verbose=0)
       
# View the accuracy score
print("Best score for data:", clf.best_score_)
# View the best parameters for the model found using grid search
print("Best C:",clf.best_estimator_.C)
print("Best Kernel:",clf.best_estimator_.kernel)
print("Best Gamma:",clf.best_estimator_.gamma)
Best score for data: 0.979949874687
Best C: 1
Best Kernel: linear
Best Gamma: auto           

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18199.html

相关文章

  • [林轩田]15-验证的方法

    摘要:的选择有当很小,接近时,才差不多。一般情况下,我们的选取总数据的即留法做交叉验证留一法留一个作为其余都作为循环次,再把个取平均交叉验证指的是同一笔资料有时候当验证有时候当训练样本,最后取平均。 模型选择 模型选择的因素 演算法选方面选择:PLA, pocket, linear regression, logistic regressioniteration的次数:100,1000每步大...

    tain335 评论0 收藏0
  • sklearn做交叉验证

    摘要:交叉验证是经常用到的验证方法使用可以很大程度上简化交叉验证的过程使用过程见下方这里以模型为例训练集标签交叉验证的倍数返回结果的类型,可以自定义,也有很多默认选项例如就是返回准确率都是可以的这就是简单的用法,只有比较复杂,其他都比较简单 交叉验证是经常用到的验证方法使用sklearn可以很大程度上简化交叉验证的过程使用过程见下方: from sklearn import cross_va...

    KitorinZero 评论0 收藏0
  • 机器学习面试基础知识 & 扩展-01

    摘要:偏差度量学习算法的期望预测与真实结果的偏离程度,也叫拟合能力。当这一轮完成后,重新随机选择份来训练数据。若干轮小于之后,选择损失函数评估最优的模型和参数。此方法主要用于样本量非常少的情况。 视频教程的总结和一些自行补充的内容,旨在尽可能的理解其原理。 showImg(https://segmentfault.com/img/remote/1460000012474417); 训练、开...

    lifefriend_007 评论0 收藏0
  • 【译】使用H2O进行集成学习【2】

    摘要:使用进行集成学习介绍集成学习就是组合多个机器学习算法,从而得到更好的预测性能。许多流行的现代机器学习算法实际上就是集成。比如说随机森林和都是个集成学习器。 使用H2O进行集成学习 介绍 集成学习就是组合多个机器学习算法,从而得到更好的预测性能。许多流行的现代机器学习算法实际上就是集成。比如说随机森林 和 Gradient Boosting Machine (GBM)都是2个集成学习器。...

    baukh789 评论0 收藏0
  • Scikit-Learn 备忘录

    摘要:备忘录整理自,归属于笔者的程序猿的数据科学与机器学习实战手册,前置阅读语法速览与机器学习开发环境搭建。是开源的机器学习库,提供了数据预处理交叉验证算法与可视化算法等一系列接口。 Scikit-Learn 备忘录整理自Scikit_Learn_Cheat_Sheet_Python,归属于笔者的程序猿的数据科学与机器学习实战手册,前置阅读 Python语法速览与机器学习开发环境搭建。 Sc...

    clasnake 评论0 收藏0

发表评论

0条评论

Near_Li

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<