Bootstrap

机器学习 | 网络搜索及可视化


相关文章:

机器学习 | 目录

监督学习 | 决策树之网络搜索

监督学习 | SVM 之线性支持向量机原理

监督学习 | SVM 之非线性支持向量机原理

监督学习 | SVM 之支持向量机Sklearn实现

1. 网络搜索

网络搜索(Grid Search):一种调参方法,利用穷举搜索,在所有候选的参数选择中,通过循环便利,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数 a 有 3 种可能,参数 b 有 4 种可能,把所有可能性列出来,可以表示成一个 3 × 4 3\times 4 3×4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)[1]

1.1 简单网络搜索

考虑一个具有 RBF(径向基函数)核的核 SVM 的例子。

我们可以使用 Python 实现一个简单的网络搜索,在 2 个参数上使用 for 循环,对每种参数组合分别训练并评估一个分类器:

# naive grid search implementation
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target,
                                                    random_state=0)
print("Size of training set: {}   size of test set: {}".format(
      X_train.shape[0], X_test.shape[0]))

best_score = 0

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
    for C in [0.001, 0.01, 0.1, 1, 10, 100]:
        # for each combination of parameters, train an SVC
        svm = SVC(gamma=gamma, C=C)
        svm.fit(X_train, y_train)
        # evaluate the SVC on the test set
        score = svm.score(X_test, y_test)
        # if we got a better score, store the score and parameters
        if score > best_score:
            best_score = score
            best_parameters = {'C': C, 'gamma': gamma}

print("Best score: {:.2f}".format(best_score))
print("Best parameters: {}".format(best_parameters))
Size of training set: 112   size of test set: 38
Best score: 0.97
Best parameters: {'C': 100, 'gamma': 0.001}

1.2 参数过拟合的风险与验证集

看到这个结果,是否意味着我们找到了一个在数据集上精度达到 97% 的模型呢?答案是否定的,原因如下:

我们尝试了许多不同的参数,并选择了在测试集上精度最高的那个,但这个精度不一定能推广到新数据上。由于我们使用测试数据继续调参,所以不能再用它来评估模型的好坏。也就是说调参过程的模型得分不能作为最终得分。我们最开始需要将数据划分为训练集和测试集也是因为这个原因。我们需要一个独立的数据集来进行评估,一个在创建模型时没有用到的数据集。

为了解决这个问题,一个方法时再次划分数据,这样我们得到 3 个数据集:用于构建模型的训练集(Training Set),用于选择模型参数的验证集(Validation Set),用于评估所选参数性能的测试集(Testing Set)。如下图所示:

利用验证集选定最佳参数之后,我们可以利用找到的参数设置重新构建一个模型,但是要同时在训练数据和验证数据上进行训练,这样我们可以利用尽可能多的数据来构建模型。其实现如下所示:

from sklearn.svm import SVC
# split data into train+validation set and test set
X_trainval, X_test, y_trainval, y_test = train_test_split(
    iris.data, iris.target, random_state=0)
# split train+validation set into training and validation sets
X_train, X_valid, y_train, y_valid = train_test_split(
    X_trainval, y_trainval, random_state=1)
print("Size of training set: {}   size of validation set: {}   size of test set:"
      " {}\n".format(X_train.shape[0], X_valid.shape[0], X_test.shape[0]))

best_score = 0

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
    for C in [0.001, 0.01, 0.1, 1, 10, 100]:
        # for each combination of parameters train an SVC
        svm = SVC(gamma=gamma, C=C)
        svm.fit(X_train, y_train)
        # evaluate the SVC on the validation set
        score = svm.score(X_valid, y_valid)
        # if we got a better score, store the score and parameters
        if score > best_score:
            best_score = score
            best_parameters = {'C': C, 'gamma': gamma}

# rebuild a model on the combined training and validation set,
# and evaluate it on the test set
svm = SVC(**best_parameters)
svm.fit(X_trainval, y_trainval)
test_score = svm.score(X_test, y_test)
print("Best score on validation set: {:.2f}".format(best_score))
print("Best parameters: ", best_parameters)
print("Test set score with best parameters: {:.2f}".format(test_score))
Size of training set: 84   size of validation set: 28   size of test set: 38

Best score on validation set: 0.96
Best parameters:  {'C': 10, 'gamma': 0.001}
Test set score with best parameters: 0.92

验证集上的最高分数时 96%,这比之前略低,可能是因为我们使用了更少的数据来训练模型(现在 X_train 更小,因为我们对数据集进行了两次划分)。但测试集上的分数(这个分数实际反映了模型的泛化能力)更低,为 92%。因此,我们只能声称对 92% 的新数据正确分类,而不是我们之前认为的 97%!

1.3 带交叉验证的网络搜索

虽然将数据划分为训练集、验证集和测试集的方法(如上所述)是可行的,也相对可用,但这种方法对数据的划分相当敏感。为了得到对泛化性能的更好估计,我们可以使用交叉验证(机器学习 | 模型选择)来评估每种参数组合的性能,而不是仅将数据单次划分为训练集与验证集。整个过程如下所示:

1.3.1 Python 实现

from sklearn.model_selection import cross_val_score

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
    for C in [0.001, 0.01, 0.1, 1, 10, 100]:
        # 对每种参数组合都训练一个 SVC
        svm = SVC(gamma=gamma, C=C)
        # 执行交叉验证
        scores = cross_val_score(svm, X_trainval, y_trainval, cv=5)
        # 计算交叉验证平均精度
        score = np.mean(scores)
        # 如果得到更高的分数,则保存该分数和对应的参数
        if score > best_score:
            best_score = score
            best_parameters = {'C': C, 'gamma': gamma}
# 利用训练集和验证集得到最优参数重新构建一个模型
svm = SVC(**best_parameters)
svm.fit(X_trainval, y_trainval)
SVC(C=100, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma=0.01, kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)

选择最优参数的过程如下所示:

交叉验证是在特定数据集上对给定算法进行评估的一种方法,但它通常与网络搜算等参数搜索方法结合使用。因此,许多人使用交叉验证(Cross-validation)这一术语来通俗地指代交叉验证的网络搜素。

1.3.2 Sklearn 实现

由于带交叉验证的网络搜索是一种常用的调参方法,因此 sickit-learn 提供了 GridSearchCV `类,它以评估其(estimator)的形式实现了这种方法。要使用 GridSerachCV 类,首先需要用一个字典指定要搜索的参数,然后 GridSearchCV 会执行所有必要的模型拟合。

sklearn.model_selection.GridSearchCV:Sklearn 官方文档

创建网络搜索器:GridSearchCV(estimator, param_grid, cv, return_train_score=False)

其中 estimator 为想要训练的模型,param_grid 为想要训练的参数字典,cv 为交叉验证的折数。

GridSearchCV 包含的方法

  1. fit、predict、score:分别进行拟合、预测和得出泛化性能分数

  2. best_params 、 best_score_、best_estimator_:查看最佳参数、所对应的交叉验证平均分数和其对于的最佳模型

  3. cv_results_:返回包含网络搜索的结果的字典

字典的键是我们想要尝试的参数设置。如 C 个 gamma 想要尝试的取值为 0.001、 0.01、 0.1、 1 、10 和 100,可以将其转化为下面的字典:

param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100],
              'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
print("Parameter grid:\n{}".format(param_grid))
Parameter grid:
{'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}

我们现在可以使用模型(SVC)、要搜索的参数网络(param_grid)与要使用的交叉验证策略(比如 5 折分层交叉验证)将 GridSearchCV 类实例化:

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
grid_search = GridSearchCV(SVC(), param_grid, cv=5, return_train_score=True)

GridSearchCV 将使用交叉验证来代替之前用过的划分训练集和验证集方法。但是,我们仍需要将数据划分为训练集和测试集,以避免参数过拟合:

X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)

我们创建的 grid_search 对象的行为就像是一个分类器,我们可以对它叫用标准的 fit、predict 和 score 方法。但我们在调用 fit 时,它会对 param_grid 指定的美中参数组合都运行交叉验证:

grid_search.fit(X_train, y_train)
GridSearchCV(cv=5, error_score='raise-deprecating',
             estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
                           decision_function_shape='ovr', degree=3,
                           gamma='auto_deprecated', kernel='rbf', max_iter=-1,
                           probability=False, random_state=None, shrinking=True,
                           tol=0.001, verbose=False),
             iid='warn', n_jobs=None,
             param_grid={'C': [0.001, 0.01, 0.1, 1, 10, 100],
                         'gamma': [0.001, 0.01, 0.1, 1, 10, 100]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,
             scoring=None, verbose=0)

拟合 GridSearchCV 对象不仅会搜索最佳参数,还会利用得到最佳交叉验证性能的参数在整个训练数据集上自动拟合一个新模型。因此,fit 完成的工作相当于 1.3.1 的代码结果。

GridSerachCV 类提供了一个非常方便的接口,可以用 predicscore 方法来访问重新训练过的模型。为了评估找到的最佳参数的泛化能力,我们可以在测试集上调用 score:

print("Test set score: {:.2f}".format(grid_search.score(X_test, y_test)))
Test set score: 0.97

从结果中看出,我们利用交叉验证选择的参数,找到了一个在测试集上精度为 97% 的模型。重要的是,我们没有使用测试集来选择参数。我们找到的参数保存在 best_params属性中,而交叉验证最佳精度(对于这种参数设置,不同划分的平均精度)保存在best_score_中:

print("Best parameters: {}".format(grid_search.best_params_))
print("Best cross-validation score: {:.2f}".format(grid_search.best_score_))
Best parameters: {'C': 100, 'gamma': 0.01}
Best cross-validation score: 0.97

同样,注意不要将 best_score_ 与模型在测试集上调用 score 方法计算得到的泛化性能弄混。使用 score 方法(或者对 predict 方法的输出进行评估)采用的是在整个训练集上训练的模型。而best_score_属性保存的是交叉验证的平均精度,是在训练集上进行交叉验证得到的。

能够访问实际找到的模型,这有时是很有帮助的,比如查看系数或特征重要性。可以使用 best_estimator_ 属性来访问最佳属性对于的模型,它是在整个训练集上训练得到的:

print("Best estimator:\n{}".format(grid_search.best_estimator_))
Best estimator:
SVC(C=100, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma=0.01, kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)

1.4 网络搜索可视化

1.4.1 在网络空间中的搜索

将交叉验证的结果可视化通常有助于理解模型泛化能力对所搜索参数的依赖关系。由于运行网络搜索的计算成本相当高,所以通常最好从比较稀疏且较小的网络开始搜索。然后我们可以检查交叉验证网络搜索的结果,可能也会扩展搜索范围。

网络搜索的结果可以在 cv_results_ 属性中找到,它是一个字典,其中保存了搜索的所有内容。

可以将其转换为 DataFrame 后再查看:

import pandas as pd
# convert to Dataframe
results = pd.DataFrame(grid_search.cv_results_)
# show the first 5 rows
display(results.head())
mean_fit_timestd_fit_timemean_score_timestd_score_timeparam_Cparam_gammaparamssplit0_test_scoresplit1_test_scoresplit2_test_score...mean_test_scorestd_test_scorerank_test_scoresplit0_train_scoresplit1_train_scoresplit2_train_scoresplit3_train_scoresplit4_train_scoremean_train_scorestd_train_score
00.0013170.0004580.0019430.0012430.0010.001{'C': 0.001, 'gamma': 0.001}0.3750.3478260.363636...0.3660710.011371220.3636360.3707870.3666670.3666670.3626370.3660790.002852
10.0012840.0005430.0013290.0010860.0010.01{'C': 0.001, 'gamma': 0.01}0.3750.3478260.363636...0.3660710.011371220.3636360.3707870.3666670.3666670.3626370.3660790.002852
20.0005820.0000240.0002720.0000200.0010.1{'C': 0.001, 'gamma': 0.1}0.3750.3478260.363636...0.3660710.011371220.3636360.3707870.3666670.3666670.3626370.3660790.002852
30.0006060.0000210.0002790.0000120.0011{'C': 0.001, 'gamma': 1}0.3750.3478260.363636...0.3660710.011371220.3636360.3707870.3666670.3666670.3626370.3660790.002852
40.0006610.0000320.0002940.0000330.00110{'C': 0.001, 'gamma': 10}0.3750.3478260.363636...0.3660710.011371220.3636360.3707870.3666670.3666670.3626370.3660790.002852

5 rows × 22 columns

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

import mglearn

scores = np.array(results.mean_test_score).reshape(6, 6)

# plot the mean cross-validation scores
mglearn.tools.heatmap(scores, xlabel='gamma', xticklabels=param_grid['gamma'],
                      ylabel='C', yticklabels=param_grid['C'], cmap="viridis")
<matplotlib.collections.PolyCollection at 0x1c1cc8aeb8>

热图中每个点对于运行一次交叉验证以及一种特定的参数设置。颜色表示交叉验证的精度:浅色表示高精度,深色表示低精度。

可以看到,SVC 对参数设置非常敏感。对于许多参数这只,精度都在 40% 左右,这是非常糟糕的;对于其他参数设置,精度约为 96%。

我们可以从这张图中看出一下两点:

首先,我们调整的参数对于获得良好的性能非常重要。这两个参数(C 和 gamma)都很重要,约为调节它们可以将精度从 40% 提高到 96%。

此外,在我们选择的参数范围中也可以看到输出发生了明显的变化。同样重要的是要注意,参数的范围要足够大:每个参数的最佳取值不能位于图像的边界上。

1.4.1.1 错误的参数设置和可视化

下面我们来看几张图,其结果不那么理想,因为选择的搜索范围不合适:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(13, 5))

param_grid_linear = {'C': np.linspace(1, 2, 6),
                     'gamma':  np.linspace(1, 2, 6)}

param_grid_one_log = {'C': np.linspace(1, 2, 6),
                      'gamma':  np.logspace(-3, 2, 6)}

param_grid_range = {'C': np.logspace(-3, 2, 6),
                    'gamma':  np.logspace(-7, -2, 6)}

for param_grid, ax in zip([param_grid_linear, param_grid_one_log,
                           param_grid_range], axes):
    grid_search = GridSearchCV(SVC(), param_grid, cv=5)
    grid_search.fit(X_train, y_train)
    scores = grid_search.cv_results_['mean_test_score'].reshape(6, 6)

    # plot the mean cross-validation scores
    scores_image = mglearn.tools.heatmap(
        scores, xlabel='gamma', ylabel='C', xticklabels=param_grid['gamma'],
        yticklabels=param_grid['C'], cmap="viridis", ax=ax)

plt.colorbar(scores_image, ax=axes.tolist())
<matplotlib.colorbar.Colorbar at 0x1c1d0a64a8>

第一张图没有任何变化,整个参数网络的颜色相同。这种情况,是由参数 C 和 gamma 不正确的缩放以及不正确的范围造成的。但如果对于不同的参数设置都看不到精度的变化,也可能是因为这个参数根本不重要。通常最好在开始时尝试非常极端的值,以观察参数是否会导致精度发生变化。

第二张图显示的是垂直条形模式。这表示只有 gamma 的设置对精度有影响。这可能意味着 gamma 参数的搜索范围是我们所关心的,而 C 参数并不是——也可能意味着 C 参数并不重要

第三章图中 C 和 gamma 对于的精度都有变化。但可以看到,在图像的整个左下角都没有发生什么有趣的事情。我们在后面的网络搜索中可以不考虑非常小的值。最佳参数设置出现在右上角。由于最佳参数位于图像的边界,所以我们可以认为,在这个边界之外可能还有更好的取值,我们可能希望改变搜索范围以包含这一区域内的更多参数

基于交叉验证分数来调节参数网络是非常好的,也是探索不同参数等莪重要性的好方法。但是,不应该在最终测试集上测试不同的参数范围——前面说过,只有确切知道了想要使用的模型,才能对测试集进行评估。

1.4.2 在非网络空间的搜索

在某些情况下,尝试所有参数的所有可能组合(正如 GridSearchCV 所做的那样)并不是一个好主意。

例如,SVC 有一个 kernel 参数,根据所选择的 kernel(内核),其他桉树也是与之相关的。如果 kernal=‘linear’,那么模型是线性的,只会用到 C 参数。如果 kernal=‘rbf’,则需要使用 C 和 gamma 两个参数(但用不到类似 degree 的其他参数)。在这种情况下,搜索 C、gamma 和 kernel 所有可能的组合没有意义:如果 kernal=‘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]}]
print("List of grids:\n{}".format(param_grid))
List of grids:
[{'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]}]

在第一个网络里,kernel 参数始终等于’rbf’(注意 kernel 是一个长度为1 的列表),而 C 和 gamma 都是变化的。在第二个网络里,kernel 参数始终等于’linear’,只有 C 是变化的。下面为来应用这个更加复杂的参数搜索:

grid_search = GridSearchCV(SVC(), param_grid, cv=5, return_train_score=True)
grid_search.fit(X_train, y_train)
print("Best parameters: {}".format(grid_search.best_params_))
print("Best cross-validation score: {:.2f}".format(grid_search.best_score_))
Best parameters: {'C': 100, 'gamma': 0.01, 'kernel': 'rbf'}
Best cross-validation score: 0.97


//anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_search.py:813: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.
  DeprecationWarning)

我们再次查看 cv_results_。正如所料,如果 kernel 等于’linear’,那么只有 C 是变化的:

results = pd.DataFrame(grid_search.cv_results_)
display(results.T)
0123456789...32333435363738394041
mean_fit_time0.002163270.0009754180.0008958340.0005861280.000680780.0006710050.0006855960.0006400590.0006077770.000593805...0.0003736020.0006645680.001531980.0008377080.0007662770.0004684930.0004350660.0004501340.0004383090.000494576
std_fit_time0.001406550.0004923190.0004024657.89536e-069.49278e-056.87857e-050.0001895892.10245e-054.78872e-053.52042e-05...1.16059e-050.0002577690.0003924931.99011e-050.0003228416.2482e-065.08608e-056.50786e-055.02317e-059.95536e-05
mean_score_time0.001203440.000669670.0005735870.0002676960.0003077980.0002876280.0003241540.0003692630.000287580.000271845...0.0002378460.0008203030.0005448340.0002935890.0003562930.0002449510.0002463340.000253010.0002808570.000261641
std_score_time0.0006996820.0007103820.0004035346.3643e-066.30153e-052.14702e-056.90788e-050.0001855533.8449e-051.27472e-05...1.7688e-060.001117570.0001109924.59797e-050.0001617591.7688e-068.52646e-063.69834e-058.52978e-052.57724e-05
param_C0.0010.0010.0010.0010.0010.0010.010.010.010.01...1001001001000.0010.010.1110100
param_gamma0.0010.010.11101000.0010.010.11...0.1110100NaNNaNNaNNaNNaNNaN
param_kernelrbfrbfrbfrbfrbfrbfrbfrbfrbfrbf...rbfrbfrbfrbflinearlinearlinearlinearlinearlinear
params{'C': 0.001, 'gamma': 0.001, 'kernel': 'rbf'}{'C': 0.001, 'gamma': 0.01, 'kernel': 'rbf'}{'C': 0.001, 'gamma': 0.1, 'kernel': 'rbf'}{'C': 0.001, 'gamma': 1, 'kernel': 'rbf'}{'C': 0.001, 'gamma': 10, 'kernel': 'rbf'}{'C': 0.001, 'gamma': 100, 'kernel': 'rbf'}{'C': 0.01, 'gamma': 0.001, 'kernel': 'rbf'}{'C': 0.01, 'gamma': 0.01, 'kernel': 'rbf'}{'C': 0.01, 'gamma': 0.1, 'kernel': 'rbf'}{'C': 0.01, 'gamma': 1, 'kernel': 'rbf'}...{'C': 100, 'gamma': 0.1, 'kernel': 'rbf'}{'C': 100, 'gamma': 1, 'kernel': 'rbf'}{'C': 100, 'gamma': 10, 'kernel': 'rbf'}{'C': 100, 'gamma': 100, 'kernel': 'rbf'}{'C': 0.001, 'kernel': 'linear'}{'C': 0.01, 'kernel': 'linear'}{'C': 0.1, 'kernel': 'linear'}{'C': 1, 'kernel': 'linear'}{'C': 10, 'kernel': 'linear'}{'C': 100, 'kernel': 'linear'}
split0_test_score0.3750.3750.3750.3750.3750.3750.3750.3750.3750.375...0.9583330.9166670.8750.5416670.3750.9166670.95833310.9583330.958333
split1_test_score0.3478260.3478260.3478260.3478260.3478260.3478260.3478260.3478260.3478260.347826...110.9565220.5217390.3478260.8260870.9130430.95652211
split2_test_score0.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.363636...1110.5909090.3636360.8181821111
split3_test_score0.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.363636...0.8636360.8636360.8181820.5909090.3636360.7727270.9090910.9545450.9090910.909091
split4_test_score0.3809520.3809520.3809520.3809520.3809520.3809520.3809520.3809520.3809520.380952...0.9523810.9523810.9523810.6190480.3809520.9047620.9523810.9523810.9523810.952381
mean_test_score0.3660710.3660710.3660710.3660710.3660710.3660710.3660710.3660710.3660710.366071...0.9553570.9464290.9196430.5714290.3660710.8482140.9464290.9732140.9642860.964286
std_test_score0.01137080.01137080.01137080.01137080.01137080.01137080.01137080.01137080.01137080.0113708...0.04956620.05192270.06479060.03565250.01137080.05477830.03321850.02239950.03383870.0338387
rank_test_score27272727272727272727...9111724272111133
split0_train_score0.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.3636360.363636...0.9886361110.3636360.8863640.9659090.9886360.9886360.988636
split1_train_score0.3707870.3707870.3707870.3707870.3707870.3707870.3707870.3707870.3707870.370787...0.9775281110.3707870.887640.9775280.9775280.9887640.988764
split2_train_score0.3666670.3666670.3666670.3666670.3666670.3666670.3666670.3666670.3666670.366667...0.9777781110.3666670.8666670.9444440.9777780.9777780.988889
split3_train_score0.3666670.3666670.3666670.3666670.3666670.3666670.3666670.3666670.3666670.366667...11110.3666670.7555560.9777780.9888890.9888891
split4_train_score0.3626370.3626370.3626370.3626370.3626370.3626370.3626370.3626370.3626370.362637...11110.3626370.8791210.9670330.98901111
mean_train_score0.3660790.3660790.3660790.3660790.3660790.3660790.3660790.3660790.3660790.366079...0.9887881110.3660790.8550690.9665380.9843680.9888130.993258
std_train_score0.002851760.002851760.002851760.002851760.002851760.002851760.002851760.002851760.002851760.00285176...0.009994510000.002851760.05031140.01213160.005485070.007028010.00550551

23 rows × 42 columns

参考资料

[1] April15 .调参必备—GridSearch网格搜索[EB/OL].https://www.cnblogs.com/ysugyl/p/8711205.html, 2018-04-03.

[2] Andreas C.Muller, Sarah Guido, 张亮. Python 机器学习基础教程[M]. 北京: 人民邮电出版社, 2018: 200-212.

;