超参数调优:GridSearchCV 和 RandomizedSearchCV 解释 - KDnuggets

超参数调优:GridSearchCV 和 RandomizedSearchCV,解释 – KDnuggets

源节点: 2365310

超参数调优:GridSearchCV 和 RandomizedSearchCV 解释
图片作者
 

您训练的每个机器学习模型都有一组参数或模型系数。 机器学习算法(表述为优化问题)的目标是学习这些参数的最优值。 

此外,机器学习模型还有一组超参数。 比如K-Nearest Neighbors算法中的K值,即邻居的数量。 或者训练深度神经网络时的批量大小等等。

模型不会学习这些超参数。 而是由开发商指定的。 它们影响模型性能并且是可调的。 那么如何找到这些超参数的最佳值呢? 这个过程称为 超参数优化 or 超参数调整.

两种最常见的超参数调整技术包括:

  • 网格搜索
  • 随机搜索

在本指南中,我们将了解这些技术的工作原理及其 scikit-learn 实现。

让我们从训练一个简单的 支持向量机 (SVM) 分类器 在葡萄酒数据集上。 

首先,导入所需的模块和类: 

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score

 

wine 数据集是 scikit-learn 中内置数据集的一部分。 因此,让我们阅读如下所示的功能和目标标签:

# Load the Wine dataset
wine = datasets.load_wine()
X = wine.data
y = wine.target

 

葡萄酒数据集是一个简单的数据集,具有 13 个数字特征和三个输出类标签。 这是一个很好的候选数据集,可以帮助您了解多类分类问题。 你可以运行 wine.DESCR 获取数据集的描述。

 

超参数调优:GridSearchCV 和 RandomizedSearchCV 解释
wine.DESCR 的输出 
 

接下来,将数据集分为训练集和测试集。 这里我们使用了一个 test_size 0.2。 因此,80% 的数据进入训练数据集,20% 进入测试数据集。

# Split the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=24)

 

现在实例化一个支持向量分类器并将模型拟合到训练数据集。 然后评估其在测试集上的性能。

# Create a baseline SVM classifier
baseline_svm = SVC()
baseline_svm.fit(X_train, y_train)
y_pred = baseline_svm.predict(X_test)

 

因为这是一个简单的多分类问题,我们可以看看模型的准确率。

# Evaluate the baseline model
accuracy = accuracy_score(y_test, y_pred)
print(f"Baseline SVM Accuracy: {accuracy:.2f}")

 

我们看到该模型在超参数默认值下的准确度得分约为 0.78。 

Output >>>
Baseline SVM Accuracy: 0.78

 

这里我们使用了一个 random_state 24。对于不同的随机状态,您将获得不同的训练测试分组,以及随后不同的准确度分数。

因此,我们需要一种比单一训练-测试分割更好的方法来评估模型的性能。 也许,在许多这样的分割上训练模型并考虑平均准确度。 同时还尝试不同的超参数组合? 是的,这就是我们在模型评估和超参数搜索中使用交叉验证的原因。 我们将在以下部分中了解更多信息。

接下来,让我们确定可以为此支持向量机分类器调整的超参数。

在超参数调整中,我们的目标是为 SVM 分类器找到超参数值的最佳组合。 支持向量分类器的常用调整超参数包括:

  • C:正则化参数,控制最大化边际和最小化分类误差之间的权衡。
  • 核心:指定要使用的核函数的类型(例如,“线性”、“rbf”、“聚”)。
  • 伽玛:“rbf”和“poly”内核的内核系数。

交叉验证 有助于评估模型的效果 概括 并降低了对单个训练测试分割过度拟合的风险。 常用的 k 折交叉验证涉及将数据集分为 k 相同大小的折叠。 模型已训练完毕 k 次,每次折叠作为验证集 一旦 剩余的折叠作为训练集。 因此,对于每次折叠,我们都会获得交叉验证的准确性。

当我们运行网格和随机搜索来寻找最佳超参数时,我们将根据最佳平均交叉验证分数来选择超参数。

网格搜索 是一种超参数调整技术,执行 对指定超参数空间的穷举搜索 找到产生最佳模型性能的超参数组合。

网格搜索的工作原理

我们将超参数搜索空间定义为参数网格。 这 参数网格 是一个字典,您可以在其中指定要调整的每个超参数以及要探索的值列表。 

然后,网格搜索系统地探索参数网格中超参数的每种可能的组合。 它使用交叉验证来拟合和评估每个组合的模型,并选择产生最佳性能的组合。

接下来,我们在 scikit-learn 中实现网格搜索。

首先,导入 GridSearchCV scikit-learn 的课程 型号选择 模块:

from sklearn.model_selection import GridSearchCV

 

让我们定义 SVM 分类器的参数网格:

# Define the hyperparameter grid
param_grid = { 'C': [0.1, 1, 10], 'kernel': ['linear', 'rbf', 'poly'], 'gamma': [0.1, 1, 'scale', 'auto']
}

 

然后,网格搜索系统地探索参数网格中超参数的每种可能的组合。 对于此示例,它通过以下方式评估模型的性能:

  • C 设置为 0.1、1 和 10,
  • kernel 设置为“线性”、“rbf”和“多边形”,并且
  • gamma 设置为 0.1、1、“缩放”和“自动”。

这导致总共有 3 * 3 * 4 = 36 种不同的组合需要评估。 网格搜索使用交叉验证来拟合和评估每个组合的模型,并选择产生最佳性能的组合。

然后我们实例化 GridSearchCV 调整超参数 baseline_svm:

# Create the GridSearchCV object
grid_search = GridSearchCV(estimator=baseline_svm, param_grid=param_grid, cv=5) # Fit the model with the grid of hyperparameters
grid_search.fit(X_train, y_train)

 

请注意,我们使用了 5 折交叉验证。 

最后,我们使用通过网格搜索找到的最佳超参数在测试数据上评估最佳模型的性能:

# Get the best hyperparameters and model
best_params = grid_search.best_params_
best_model = grid_search.best_estimator_ # Evaluate the best model
y_pred_best = best_model.predict(X_test)
accuracy_best = accuracy_score(y_test, y_pred_best)
print(f"Best SVM Accuracy: {accuracy_best:.2f}")
print(f"Best Hyperparameters: {best_params}")

 

如图所示,该模型在以下超参数上的准确度得分为 0.94:

Output >>>
Best SVM Accuracy: 0.94
Best Hyperparameters: {'C': 0.1, 'gamma': 0.1, 'kernel': 'poly'}

使用网格搜索进行超参数调优有以下优点:

  • 网格搜索探索所有指定的组合,确保您不会错过定义的搜索空间内的最佳超参数。
  • 它是探索较小的超参数空间的不错选择。

然而,另一方面:

  • 网格搜索的计算成本可能很高,尤其是在处理大量超参数及其值时。 对于非常复杂的模型或广泛的超参数搜索可能不可行。

现在让我们了解随机搜索。

随机搜索 是另一种超参数调整技术 探索指定分布或范围内的超参数的随机组合。 在处理大型超参数搜索空间时,它特别有用。

随机搜索的工作原理 

在随机搜索中,您可以定义每个超参数的概率分布或范围,而不是指定值网格。 这将成为一个更大的超参数搜索空间。

然后随机搜索 随机抽样 这些分布中固定数量的超参数组合。 这使得随机搜索能够有效地探索一组不同的超参数组合。

现在让我们使用随机搜索来调整基线 SVM 分类器的参数。

我们进口 RandomizedSearchCV 类和定义 param_dist,更大的超参数搜索空间:

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform param_dist = { 'C': uniform(0.1, 10), # Uniform distribution between 0.1 and 10 'kernel': ['linear', 'rbf', 'poly'], 'gamma': ['scale', 'auto'] + list(np.logspace(-3, 3, 50))
}

 

与网格搜索类似,我们实例化随机搜索模型来搜索最佳超参数。 在这里,我们设置 n_iter 至 20; 因此将采样 20 个随机超参数组合。

# Create the RandomizedSearchCV object
randomized_search = RandomizedSearchCV(estimator=baseline_svm, param_distributions=param_dist, n_iter=20, cv=5) randomized_search.fit(X_train, y_train)

 

然后,我们使用通过随机搜索找到的最佳超参数来评估模型的性能:

# Get the best hyperparameters and model
best_params_rand = randomized_search.best_params_
best_model_rand = randomized_search.best_estimator_ # Evaluate the best model
y_pred_best_rand = best_model_rand.predict(X_test)
accuracy_best_rand = accuracy_score(y_test, y_pred_best_rand)
print(f"Best SVM Accuracy: {accuracy_best_rand:.2f}")
print(f"Best Hyperparameters: {best_params_rand}")

 

最佳精度和最佳超参数是:

Output >>>
Best SVM Accuracy: 0.94
Best Hyperparameters: {'C': 9.66495227534876, 'gamma': 6.25055192527397, 'kernel': 'poly'}

 

通过随机搜索找到的参数与通过网格搜索找到的参数不同。 具有这些超参数的模型也达到了 0.94 的准确度得分。

我们总结一下随机搜索的优点:

  • 在处理大量超参数或大范围值时,随机搜索非常有效,因为它不需要穷举搜索。
  • 它可以处理各种参数类型,包括连续值和离散值。

以下是随机搜索的一些限制:

  • 由于其随机性,它可能并不总能找到最佳的超参数。 但它往往很快就能找到好的。
  • 与网格搜索不同,它不能保证所有可能的组合都会被探索。

我们学习了如何执行超参数调整 RandomizedSearchCVGridSearchCV 在 scikit-learn 中。 然后,我们使用最佳超参数评估模型的性能。 

总之,网格搜索详尽地搜索参数网格中所有可能的组合。 而随机搜索则随机采样超参数组合。

这两种技术都可以帮助您确定机器学习模型的最佳超参数,同时降低过度拟合特定训练-测试分割的风险。
 
 

巴拉普里亚 C 是来自印度的开发人员和技术作家。 她喜欢在数学、编程、数据科学和内容创作的交叉领域工作。 她的兴趣和专长领域包括 DevOps、数据科学和自然语言处理。 她喜欢阅读、写作、编码和咖啡! 目前,她致力于通过编写教程、操作指南、评论文章等方式学习并与开发人员社区分享她的知识。

时间戳记:

更多来自 掘金队