4种主流超参数调优技术

时间:2022-07-25
本文章向大家介绍4种主流超参数调优技术,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

每个算法工程师都应该了解的流行超参数调优技术。 作者:Sivasai Yadav Mudugandla 编译:McGL

引言

维基百科上说“超参数优化(optimization)或调优(tuning)是为学习算法选择一组最优超参数的问题”

机器学习工作流中最难的部分之一是为模型寻找最佳的超参数。机器学习模型的性能与超参数直接相关。超参数调优越多,得到的模型就越好。调整超参数真的很难又乏味,更是一门艺术而不是科学。

超参数(Hyper-parameter)

超参数是在建立模型时用来控制算法行为的参数。这些参数不能从正常的训练过程中学习。他们需要在训练模型之前被分配。

Dr.Mukesh Rao的超参数样本清单

目录

1. 传统或手动调参

2. 网格搜索

3. 随机搜索

4. 贝叶斯搜索

1. 传统或手动调参

在传统的调优中,我们通过手动检查随机超参数集来训练算法,并选择最适合我们目标的参数集。 让我们看看代码:

#importing required libraries
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold , cross_val_score
from sklearn.datasets import load_wine

wine = load_wine()
X = wine.data
y = wine.target

#splitting the data into train and test set
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3,random_state = 14)

#declaring parameters grid
k_value = list(range(2,11))
algorithm = ['auto','ball_tree','kd_tree','brute']
scores = []
best_comb = []
kfold = KFold(n_splits=5)

#hyperparameter tunning
for algo in algorithm:
  for k in k_value:
    knn = KNeighborsClassifier(n_neighbors=k,algorithm=algo)
    results = cross_val_score(knn,X_train,y_train,cv = kfold)

    print(f'Score:{round(results.mean(),4)} with algo = {algo} , K = {k}')
    scores.append(results.mean())
    best_comb.append((k,algo))

best_param = best_comb[scores.index(max(scores))]
print(f'nThe Best Score : {max(scores)}')
print(f"['algorithm': {best_param[1]} ,'n_neighbors': {best_param[0]}]")

缺点:

1. 不能保证得到最佳的参数组合。

2. 这是一种反复试验的方法,因此会消耗更多的时间。

2. 网格搜索

网格搜索是一种基本的超参数调整技术。它类似于手动调优,为网格中指定的所有给定超参数值的每个排列建立模型,并评估和选择最佳模型。考虑上面的例子,它有两个超参数 k_value =[2,3,4,5,6,7,8,9,10] 和 algorithm = [‘auto’ , ’ball_tree’ , ’kd_tree’ , ’brute’],在这种情况下,它总共构建了9 * 4 = 36个不同的模型。

让我们来了解一下 sklearn 的 GridSearchCV 是如何工作的,

from sklearn.model_selection import GridSearchCV

knn = KNeighborsClassifier()
grid_param = { 'n_neighbors' : list(range(2,11)) , 
              'algorithm' : ['auto','ball_tree','kd_tree','brute'] }
              
grid = GridSearchCV(knn,grid_param,cv = 5)
grid.fit(X_train,y_train)

#best parameter combination
grid.best_params_

#Score achieved with best parameter combination
grid.best_score_

#all combinations of hyperparameters
grid.cv_results_['params']

#average scores of cross-validation
grid.cv_results_['mean_test_score']

缺点:

由于它尝试每一种超参数组合,并根据交叉验证分数选择最佳组合,这使得 GridsearchCV 极其缓慢。

3. 随机搜索

使用随机搜索代替网格搜索的动机是,在许多情况下,所有的超参数可能并非同等重要。随机搜索从超参数空间中随机选择参数组合,参数按 n_iter 给定的迭代次数进行选择。随机搜索已经被实践证明比网格搜索得到的结果更好。

让我们了解一下 sklearn 的 RandomizedSearchCV 是如何工作的,

from sklearn.model_selection import RandomizedSearchCV

knn = KNeighborsClassifier()

grid_param = { 'n_neighbors' : list(range(2,11)) , 
              'algorithm' : ['auto','ball_tree','kd_tree','brute'] }

rand_ser = RandomizedSearchCV(knn,grid_param,n_iter=10)
rand_ser.fit(X_train,y_train)

#best parameter combination
rand_ser.best_params_

#score achieved with best parameter combination
rand_ser.best_score_

#all combinations of hyperparameters
rand_ser.cv_results_['params']

#average scores of cross-validation
rand_ser.cv_results_['mean_test_score']

缺点:

随机搜索的问题是它不能保证给出最佳的参数组合。

4. 贝叶斯优化

贝叶斯优化属于一类被称为sequential model-based optimization(SMBO)的优化算法。这些算法使用先前对损失 f 的观测,来确定下一个(最佳)点来取样 f。该算法大致可以概括如下。

1. 使用先前计算过的点 X1: n,计算损失 f 的后验期望值。

2. 在一个新的点 Xnew取样损失 f ,它最大化了 f 的期望的某些效用函数。该函数指定 f 域的哪些区域是最适合采样的。

重复这些步骤,直到达到某种收敛准则。

让我们用 scikit-optimize 的BayesSearchCV来理解这一点 安装: pip install scikit-optimize

from skopt import BayesSearchCV

import warnings
warnings.filterwarnings("ignore")

# parameter ranges are specified by one of below
from skopt.space import Real, Categorical, Integer

knn = KNeighborsClassifier()
#defining hyper-parameter grid
grid_param = { 'n_neighbors' : list(range(2,11)) , 
              'algorithm' : ['auto','ball_tree','kd_tree','brute'] }

#initializing Bayesian Search
Bayes = BayesSearchCV(knn , grid_param , n_iter=30 , random_state=14)
Bayes.fit(X_train,y_train)

#best parameter combination
Bayes.best_params_

#score achieved with best parameter combination
Bayes.best_score_

#all combinations of hyperparameters
Bayes.cv_results_['params']

#average scores of cross-validation
Bayes.cv_results_['mean_test_score']

实现贝叶斯搜索的另一个类似的库是 bayesian-optimization

安装 : pip install bayesian-optimization 缺点: 在2维或3维搜索空间中,需要十几个样本才能得到一个良好的替代曲面(surrogate surface); 增加搜索空间的维数需要更多的样本。


总结

在找到参数的最佳组合的保证和计算时间之间总是有一个权衡。如果你的超参数空间(超参数个数)非常大,那么使用随机搜索找到超参数的潜在组合,然后使用该局部的网格搜索(超参数的潜在组合)来选择最优特征。

References

1. https://thuijskens.github.io/2016/12/29/bayesian-optimisation/

2. https://scikit-optimize.github.io/stable/modules/generated/skopt.BayesSearchCV.html

3. https://github.com/fmfn/BayesianOptimization

原文:https://medium.com/swlh/4-hyper-parameter-tuning-techniques-924cb188d199