文章目录
相关文章:
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]:
# f