超参随机搜索原理及核心实现
文章目录
是什么
随机搜索是一种常用的机器学习超参优化的方法。随机搜索就是在给定的参数范围之类进行(伪)随机抽样产生参数值,然后对多个抽样值选取最优的参数组合。随机搜索方法是James Bergstra 和 Yoshua Bengio在2012年提出的一种超参搜索算法,在此之前,超参优化算法基本是人工手动搜索和网格搜索的占有绝对优势。
怎么用
sklearn中有RandomizedSearchCV的实现,其使用方法如下。
使用步骤
总结来讲使用步骤就是:
- 定义一个算法,比如LogisticRegression,包括自定义算法。
- 定义参数的分布,如果所有参数都是list,则等同于网格搜索。
- 定义RandomizedSearchCV对象,传入算法、参数分布、随机种子等参数。
- 进行模型训练,并进行参数调优。
代码示例
如下代码是摘自sklearn官方示例代码,
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform
iris = load_iris()
logistic = LogisticRegression(solver='saga', tol=1e-2, max_iter=200,
random_state=0)
distributions = dict(C=uniform(loc=0, scale=4),
penalty=['l2', 'l1'])
clf = RandomizedSearchCV(logistic, distributions, random_state=0)
search = clf.fit(iris.data, iris.target)
result = search.best_params_
什么原理
在随机搜索算法提出之前,基本都是采用人工调优和网格搜索。简单有效实现很简单,按照一定的网格划分,然后对参数进行评估,暴力求解所有的点,得到结果。优点是实现简单明了。缺点是,对于网格粗细的划分需要根据经验或者多次试验结果才能找到合适的网格大小。其次,如果参数过多,会导致需要需要搜索的点指数级增加,因此参数过多不适合采用网格搜索。
随机搜索往往可以用较少的搜索次数达到比价良好的效果,实现难度也不大。
随机搜索是随机从参数范围中采样参数点,从直觉上来讲,其效果可能会很不稳定,或者说并不能找到很好的解,为何会有效呢,甚至能找到比网格搜索更优的解呢?
为什么有效
如上图所示,假设目标函数为f(x,y) = g(x)+h(y),其中横轴为x,绿色部分为g(x), 纵轴为y,黄色部分是h(y)。
- 从图中也可以看出,随着x变化,g(x)的变化方差较大,而随着y变化,h(y)的变化方差很小。因此x是重要参数,y是非重要参数。
- 对于网格搜索,9组搜索参数在横轴g(x)上只测试了三个点。而对于随机搜索,9组搜索参数则在g(x)测试了9个不同的点(横轴和纵轴均是9个点)。
因此,随机搜索更有可能找到更优的解。
源码解析
对于sklearn的实现源码,主要就两个部分,一个是ParameterSampler类,该类主要职责是进行参数的采样,实现了_iter_方法进行参数采样;另外一个是RandomizedSearchCV的run_search方法,采用并行的方式对采样出来的参数,进行模型的求解。
随机搜索的策略和步骤:
- 对于搜索范围是distribution的超参数,在给定的distribution范围内随机采样;
- 对于搜索范围是list的超参数,在给定的list中等概率采样;如果所有参数全是list,则等类似于网格搜索。
- 对前两步中得到的n_iter组采样结果,进行遍历。
- 如果给定的搜索范围均为list,则不放回抽样n_iter次。
参考资料
- Random Search for Hyper-Parameter Optimization
- sklearn RandomizedSearchCV 源码