数据挖掘—网格搜索2

1、分析交叉验证的结果

将交叉验证的结果可视化通常有助于理解模型泛化能力对所搜索参数的依赖关系。由于运行网格搜索的计算成本相当高,所以通常最好从相对比较稀疏且较小的网格开始搜索。然后我们可以检查交叉验证网格搜索的结果,可能也会扩展搜索范围。网格搜索的结果可以在 cv_results_ 属性中找到,它是一个字典,其中保存了搜索的所有内容。你可以在下面的输出中看到,它里面包含许多细节,最好将其转换成 pandas 数据框后再查看:

import pandas as pd
results=pd.DataFrame(grid_search.cv_results_)
display(results[:5])

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

results 中每一行对应一种特定的参数设置。对于每种参数设置,交叉验证所有划分的结果都被记录下来,所有划分的平均值和标准差也被记录下来。由于我们搜索的是一个二维参数网格( C 和 gamma ),所以最适合用热图可视化(见图 5-8)。我们首先提取平均验证分数,然后改变分数数组的形状,使其坐标轴分别对``应于 C 和 gamma :

import numpy as np
scores=np.array(results.mean_test_score).reshape(6,6)
import seaborn as sns
import matplotlib.pyplot as plt 
sns.heatmap(scores,xticklabels=param_grid['gamma'],yticklabels=param_grid['C'],annot=True)

在这里插入图片描述
你可以看到, SVC 对参数设置非常敏感。对于许多种参数设置,精度都在 40% 左右,这是非常糟糕的;对于其他参数设置,精度约为 96%。我们可以从这张图中看出以下几点。首先,我们调的参数对于获得良好的性能非常重要。这两个参数( C 和 gamma)都很重要,因为调节它们可以将精度从 40% 提高到96%。此外,在我们选择的参数范围中也可以看到输出发生了显著的变化。样重要的是要注意,参数的范围要足够大:每个参数的最佳取值能位于图像的边界上。

2、网格的条件参数

在某些情况下,尝试所有参数的所有可能组合(正如GridSearchCV 所做的那样)并不是一个好主意。例如, SVC 有一个 kernel 参数,根据所选择的 kernel (内核),其他参数也是与之相关的。如果kernel=‘linear’ ,那么模型是线性的,只用到 C 参数。如果kernel=‘rbf’ ,则需要使用 C 和 gamma 两个参(但用不到类似 degree 的其他参数)。在这种情况下,搜索 C 、 gamma 和 kernel 所有可能的组合没有意义:如果kernel=‘linear’ ,那么 gamma 是用不到的,尝试 gamma 的不同取值将会浪费时间。为了处理这种**“条件”(conditional)参数**, GridSearchCV 的 param_grid 可以是字典组成的列表(a list of dictionaries)。列表中的每个字典可扩展为一个独立的网格。包含内核与参数的网格搜索可能如下所示。

param_grid=[{'kernel':['rbf'],
            'C':[0.001,0.01,0.1,1,10,100],
            'gamma':[0.001,0.01,0.1,1,10,100]},
           {'kernel':['linear'],
           'C':[0.001,0.01,0.1,1,10,100]}]
grid_search=GridSearchCV(SVC(),param_grid,cv=5)
grid_search.fit(X_train,y_train)
grid_search.score(X_test,y_test)

0.9736842105263158

grid_search.best_score_

0.9732142857142857

grid_search.best_params_

{‘C’: 100, ‘gamma’: 0.01}

results=pd.DataFrame(grid_search.cv_results_)
display(results.T)

在这里插入图片描述

3、使用不同的交叉验证策略进行网格搜索

(1) 传入交叉验证分离器

与 cross_val_score 类似, GridSearchCV 对分类问题默认使用分层 k 折交叉验证StratifiedKFold ,对回归问题默认使用 k 折交叉验证KFold
但是,你可以传入任何交叉验证分离器作为 GridSearchCV 的cv 参数:
cv=loo 留一
SuffleSplit
StratifiedShuffleSplit
GroupKFold:每个组都整体的出现在训练集或者测试集中

(2)嵌套交叉验证

在前面的例子中,我们先介绍了将数据单次划分为训练集、验证集与测试集,然后介绍了先将数据划分为训练集和测试集,再在训练集上进行交叉验证。但前面在使用GridSearchCV 时,我们仍然将数据单次划分为训练集和测试集这可能会导致结果不稳定,也让我们过于依赖数据的此次划分。我们可以再深入一点不是只将原始数据一次划分为训练集和测试集,而是使用交叉验证进行多次划分,这就是所谓的嵌套交叉验证(nested cross validation)。在嵌套交叉验证中,有一个外层循环,遍历将数据划分为训练集和测试集的所有划分。对于每种划分都运行一次网格搜索(对于外层循环的每种划分可能会得到不同的最佳参数)。然后,对于每种外层划分,利用最佳参数设置计算得到测试集分数。

这一过程的结果是由分数组成的列表——不是一个模型,也不是一种参数设置这些分数告诉我们在网格找到的最佳参数下模型的泛化能力好坏。由于嵌套交叉验证不提供可用于新数据的模型,所以在寻找可用于未来数据的预测模型时很少用到它。但是,它对于评估给定模型在特定数据集上的效果很有用。

scores = cross_val_score(GridSearchCV(SVC(), param_grid, cv=5),iris.data, iris.target, cv=5)
print("Cross-validation scores: ", scores)
print("Mean cross-validation score: ", scores.mean())

Cross-validation scores: [ 0.967 1. 0.967 0.967 1. ]
Mean cross-validation score: 0.98

嵌套交叉验证的结果可以总结为“ SVC 在 iris 数据集上的交叉验证平均精度为 98%”——不多也不少。

这里我们在内层循环和外层循环中都使用了分层 5 折交叉验证。由于 param_grid 包含 36种参数组合,所以需要构建 36×5×5 = 900 个模型,导致嵌套交叉验证过程的代价很高。

(3)交叉验证与网格搜索并行

虽然在许多参数上运行网格搜索和在大型数据集上运行网格搜索的计算量可能很大,但令人尴尬的是,这些计算都是并行的(parallel)。这也就是说,在一种交叉验证划分下使用特定参数设置来构建一个模型,与利用其他参数的模型是完全独立的。这使得网格搜索与交叉验证成为多个 CPU 内核或集群上并行化的理想选择。你可以将 n_jobs 参数设置为你想使用的 CPU 内核数量,从而在 GridSearchCV 和 cross_val_score 中使用多个内核。你可以设置 n_jobs=-1 来使用所有可用的内核。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值