使用带有交叉验证的网格搜索进行参数估计

此案例显示了如何通过交叉验证来优化分类器。交叉验证是通过在开发集上(development set)使用sklearn.model_selection.GridSearchCV对象完成的,开发集是已有标签的数据集的一半数据。

然后,在模型选择步骤中未使用的是评估集(evalution set),我们在评估集上测量所选超参数和训练后模型的性能。

之后,在模型选择步骤中未使用的数据是评估集evalutiaon上测量所选超参数和训练后模型的性能。

有关可用于模型选择的工具的更多详细信息,请参见交叉验证:评估估计器性能调整估计器的超参数部分。

输出:

# Tuning hyper-parameters for precision

Best parameters set found on development set:

{'C'10'gamma'0.001'kernel''rbf'}

Grid scores on development set:

0.986 (+/-0.016for {'C'1'gamma'0.001'kernel''rbf'}
0.959 (+/-0.028for {'C'1'gamma'0.0001'kernel''rbf'}
0.988 (+/-0.017for {'C'10'gamma'0.001'kernel''rbf'}
0.982 (+/-0.026for {'C'10'gamma'0.0001'kernel''rbf'}
0.988 (+/-0.017for {'C'100'gamma'0.001'kernel''rbf'}
0.983 (+/-0.026for {'C'100'gamma'0.0001'kernel''rbf'}
0.988 (+/-0.017for {'C'1000'gamma'0.001'kernel''rbf'}
0.983 (+/-0.026for {'C'1000'gamma'0.0001'kernel''rbf'}
0.974 (+/-0.012for {'C'1'kernel''linear'}
0.974 (+/-0.012for {'C'10'kernel''linear'}
0.974 (+/-0.012for {'C'100'kernel''linear'}
0.974 (+/-0.012for {'C'1000'kernel''linear'}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

              precision    recall  f1-score   support

           0       1.00      1.00      1.00        89
           1       0.97      1.00      0.98        90
           2       0.99      0.98      0.98        92
           3       1.00      0.99      0.99        93
           4       1.00      1.00      1.00        76
           5       0.99      0.98      0.99       108
           6       0.99      1.00      0.99        89
           7       0.99      1.00      0.99        78
           8       1.00      0.98      0.99        92
           9       0.99      0.99      0.99        92

    accuracy                           0.99       899
   macro avg       0.99      0.99      0.99       899
weighted avg       0.99      0.99      0.99       899


# Tuning hyper-parameters for recall

Best parameters set found on development set:

{'C'10'gamma'0.001'kernel''rbf'}

Grid scores on development set:

0.986 (+/-0.019for {'C'1'gamma'0.001'kernel''rbf'}
0.957 (+/-0.028for {'C'1'gamma'0.0001'kernel''rbf'}
0.987 (+/-0.019for {'C'10'gamma'0.001'kernel''rbf'}
0.981 (+/-0.028for {'C'10'gamma'0.0001'kernel''rbf'}
0.987 (+/-0.019for {'C'100'gamma'0.001'kernel''rbf'}
0.982 (+/-0.026for {'C'100'gamma'0.0001'kernel''rbf'}
0.987 (+/-0.019for {'C'1000'gamma'0.001'kernel''rbf'}
0.982 (+/-0.026for {'C'1000'gamma'0.0001'kernel''rbf'}
0.971 (+/-0.010for {'C'1'kernel''linear'}
0.971 (+/-0.010for {'C'10'kernel''linear'}
0.971 (+/-0.010for {'C'100'kernel''linear'}
0.971 (+/-0.010for {'C'1000'kernel''linear'}

Detailed classification report:

The model is trained on the full development set.
The scores are computed on the full evaluation set.

              precision    recall  f1-score   support

           0       1.00      1.00      1.00        89
           1       0.97      1.00      0.98        90
           2       0.99      0.98      0.98        92
           3       1.00      0.99      0.99        93
           4       1.00      1.00      1.00        76
           5       0.99      0.98      0.99       108
           6       0.99      1.00      0.99        89
           7       0.99      1.00      0.99        78
           8       1.00      0.98      0.99        92
           9       0.99      0.99      0.99        92

    accuracy                           0.99       899
   macro avg       0.99      0.99      0.99       899
weighted avg       0.99      0.99      0.99       899

(译者注:输出中的英文为打印内容,是由代码中打印的英文所致,故不进行翻译)

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC

print(__doc__)

# 导入数据集
digits = datasets.load_digits()

# 要将分类器应用于此数据,我们需要将图像拉平(译者注:即降维),以将数据转换为(样本,特征)结构的矩阵:
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))
y = digits.target

# 将数据集分割为两个等大的部分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.5, random_state=0)

# 使用交叉验证设置参数
tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-31e-4],
                     'C': [1101001000]},
                    {'kernel': ['linear'], 'C': [1101001000]}]

scores = ['precision''recall']

for score in scores:
    print("# Tuning hyper-parameters for %s" % score)
    print()

    clf = GridSearchCV(
        SVC(), tuned_parameters, scoring='%s_macro' % score
    )
    clf.fit(X_train, y_train)

    print("Best parameters set found on development set:")
    print()
    print(clf.best_params_)
    print()
    print("Grid scores on development set:")
    print()
    means = clf.cv_results_['mean_test_score']
    stds = clf.cv_results_['std_test_score']
    for mean, std, params in zip(means, stds, clf.cv_results_['params']):
        print("%0.3f (+/-%0.03f) for %r"
              % (mean, std * 2, params))
    print()

    print("Detailed classification report:")
    print()
    print("The model is trained on the full development set.")
    print("The scores are computed on the full evaluation set.")
    print()
    y_true, y_pred = y_test, clf.predict(X_test)
    print(classification_report(y_true, y_pred))
    print()

# 请注意,这个问题太容易了:超参数平稳段太平坦了,并且输出模型对于精度和召回率都具有相同的预测质量。

脚本的总运行时间:(0分钟5.437秒)