机器学习(四)之参数选择:交叉验证、网格搜索

0 本文简介

主要介绍了在调参时用到的交叉验证、网格搜索。网格搜索是一种调节监督模型参数以获得最佳泛化性能的有效方法。
相关笔记:
机器学习(一)之 2万多字的监督学习模型总结V1.0:K近邻、线性回归、岭回归、朴素贝叶斯模型、决策树、随机森林、梯度提升回归树、SVM、神经网络
机器学习(二)之无监督学习:数据变换、聚类分析
机器学习(三)之数据表示和特征工程:One-Hot编码、分箱处理、交互特征、多项式特征、单变量非线性变换、自动化特征选择
机器学习(四)之参数选择:交叉验证、网格搜索
机器学习(五)之评价指标:二分类指标、多分类指标、混淆矩阵、不确定性、ROC曲线、AUC、回归指标

1 交叉验证

1.1 思想和实现

交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。在交叉验证中,数据被多次划分,并且需要训练多个模型。最常用的交叉验证是k 折交叉验证(k-fold cross-validation),其中k 是由用户指定的数字,通常取5 或10。将数据划分为(大致)相等的k部分,每一部分叫作折(fold)。如下5折交叉验证,使用第1 折作为测试集、其他折(2~5)作为训练集来训练第一个模型。对于将数据划分为训练集和测试集的这5 次划分,每一次都要计算精度。最后我们得到了5 个精度值。总结交叉验证精度的一种常用方法是计算平均值
在这里插入图片描述
scikit-learn 是利用model_selection 模块中的cross_val_score 函数来实现交叉验证的。cross_val_score 函数的参数是我们想要评估的模型、训练数据与真实标签。

1.2 优缺点

1)、使用交叉验证,每个样例都会刚好在测试集中出现一次:每个样例位于一个折中,而每个折都在测试集中出现一次。因此,模型需要对数据集中所有样本的泛化能力都很好,才能让所有的交叉验证得分(及其平均值)都很高。

2)、对数据进行多次划分,还可以提供我们的模型对训练集选择的敏感性信息。由于构建多个模型,所以它告诉我们将模型应用于新数据时在最坏情况和最好情况下的可能表现。

3)、对数据的使用更加高效,更多的数据通常可以得到更为精确的模型。

4)、主要缺点是增加了计算成本。要训练k 个模型而不是单个模型,所以交叉验证的速度要比数据的单次划分大约慢k 倍。

要注意:交叉验证不是一种构建可应用于新数据的模型的方法。交叉验证不会返回一个模型。在调用cross_val_score 时,内部会构建多个模型,但交叉验证的目的只是评估给定算法在特定数据集上训练后的泛化性能好坏

1.3 分层k折交叉验证

如果我们的标签是下面的形式,那么k折交叉验证就不适用了,可以使用分层k折交叉验证(stratified k-fold cross-validation)。

labels:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

数据的前三分之一是类别0,中间三分之一是类别1,最后三分之一是类别2。如果在这个数据集上进行3 折交叉验证。第1 折将只包含类别0,所以在数据的第一次划分中,测试集将只包含类别0,而训练集只包含类别1 和2。由于在3 次划分中训练集和测试集中的类别都不相同,因此这个数据集上的3 折交叉验证精度为0

在分层交叉验证中,我们划分数据,使每个折中类别之间的比例与整个数据集中的比例相同,如下图所示。
在这里插入图片描述解决这个问题的另一种方法是将数据打乱来代替分层,以打乱样本按标签的排序。可以通过将KFold 的shuffle 参数设为True 来实现这一点。如果我们将数据打乱,那么还需要固定random_state 以获得可重复的打乱结果。

1.4 留一法交叉验证

将留一法交叉验证(leave-one-out)看作是每折只包含单个样本的k 折交叉验证。对于每次划分,我们可以选择单个数据点作为测试集。这种方法可能非常耗时,特别是对于大型数据集来说,但在小型数据集上有时可以给出更好的估计结果。

from sklearn.model_selection import LeaveOneOut
loo = LeaveOneOut()
scores = cross_val_score(logreg, data, target, cv=loo)
print("Number of cv iterations: ", len(scores))
print("Mean accuracy: {:.2f}".format(scores.mean()))

1.5 打乱划分交叉验证

在打乱划分交叉验证(shuffle-split cross-validation)中,每次划分为训练集取样train_size 个点,为测试集取样test_size 个(不相交的)点。将这一划分方法重复n_iter 次。

from sklearn.model_selection import ShuffleSplit
shuffle_split = ShuffleSplit(test_size=.5, train_size=.5, n_splits=10)
scores = cross_val_score(logreg, data, target, cv=shuffle_split)
print("Cross-validation scores:\n{}".format(scores))

train_size和test_size 设为整数来表示这两个集合的绝对大小,也可以设为浮点数来表示占整个数
据集的比例。

打乱划分交叉验证可以在训练集和测试集大小之外独立控制迭代次数,这有时是很有帮助的。它还允许在每次迭代中仅使用部分数据,这可以通过设置train_size 与test_size 之和不等于1 来实现。用这种方法对数据进行二次采样可能对大型数据上的试验很有用。

此外,ShuffleSplit 还有一种分层的形式,其名称为StratifiedShuffleSplit,它可以为分类任务提供更可靠的结果。

1.6 分组交叉验证

分组交叉验证适用于数据中的分组高度相关时的情况。比如识别人脸表情时,要保证训练集和测试集的不能有交叉的同一个人。同样的在医疗诊断、语音识别等领域也可以使用。

可以使用GroupKFold,它以groups 数组作为参数,可以用来说明照片中对应的是哪个人。这里的groups 数组表示数据中的分组,在创建训练集和测试集的时候不应该将其分开,也不应该与类别标签弄混。

如下所示,对于每次划分,每个分组都是整体出现在训练集或测试集中:
在这里插入图片描述

2 网格搜索

找到一个模型的重要参数(提供最佳泛化性能的参数)的取值是一项棘手的任务,但对于几乎所有模型和数据集来说都是必要的。scikit-learn 中有一些标准方法,最常用的方法就是网格搜索(grid search),它主要是指尝试我们关心的参数的所有可能组合。

2.1 简单网格搜索

在进行参数搜索时,我们应该将数据集分成训练集、验证集和测试集,其中,训练集用于构建模型,验证集(开发集)用于选择模型参数,测试集用于评估所选参数性能。

利用验证集选定最佳参数之后,我们可以利用找到的参数设置重新构建一个模型,但是要同时在训练数据和验证数据上进行训练。这样我们可以利用尽可能多的数据来构建模型
在这里插入图片描述

2.2 带交叉验证的网格搜索

虽然将数据划分为训练集、验证集和测试集的方法是可行的,也相对常用,但这种方法对数据的划分方法相当敏感。为了得到对泛化性能的更好估计,我们可以使用交叉验证来评估每种参数组合的性能,而不是仅将数据单次划分为训练集与验证集。使用交叉验证的主要缺点就是训练所有这些模型所需花费的时间。

scikit-learn 提供了GridSearchCV 类,它以估计器(estimator)的形式实现了带交叉验证的网格搜索。其过程概述如下所示:
在这里插入图片描述
在使用GridSearchCV 类时,我们需要建立字典。字典的键是我们要调节的参数名称,字典的值是我们想要尝试的参数设置。虽然GridSearchCV 使用了交叉验证,但是,我们仍需要将数据划分为训练集和测试集,以避免参数过拟合。这样我们分离出来的训练集X_train就可以作为GridSearchCV 的搜索数据了。拟合GridSearchCV 对象不仅会搜索最佳参数,还会利用得到最佳交叉验证性能的参数在整个训练数据集上自动拟合一个新模型

我们还可以分析交叉验证的结果,这有助于理解模型泛化能力对所搜索参数的依赖关系。此外在非网格的空间中搜索时,我们可以创建字典组成的列表(a list ofdictionaries)。列表中的每个字典可扩展为一个独立的网格。还可以使用不同的交叉验证策略进行网格搜索,比如嵌套交叉验证(计算量大)、交叉验证与网格搜索并行。

索时,我们可以创建字典组成的列表(a list ofdictionaries)。列表中的每个字典可扩展为一个独立的网格。还可以使用不同的交叉验证策略进行网格搜索,比如嵌套交叉验证(计算量大)、交叉验证与网格搜索并行。

  • 13
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值