【炼丹笔记】调参方法总结


网格搜索调参

网格搜索调参是最常见的一种调参方案,即在所有的候选的参数选项中进行遍历,尝试每一种可能性,表现最好的参数就是最终结果(暴力搜索)。缺点很明显,就是慢!指数级的慢!

原理:在一定的区间内,通过循环遍历,尝试每一种可能性,并计算其约束函数和目标函数的值。对满足约束条件的点,逐个比较其目标函数的值,抛弃坏的点,保留好的点,最后得到最优解的近似解。为了避免初始数据的划分对结果的影响,一 般情况下网格搜索需要和交叉验证结合使用。

网格搜索在sklearn中有具体的库函数,使用也非常方便。
下面讲述一下网格搜索的具体使用方法,以lightGBM模型为例:

from sklearn.model_selection import GridSearchCV

params = {
    'learning_rate': [0.001,0.01,0.1],
    'max_depth': [5, 10, 20],
    'min_split_gain': [0, 5, 10], 
    'num_leaves': [16, 64, 128],
}
model = lgb.LGBMRegressor(**params_g)
grid_search = GridSearchCV(model, params, cv=5)  # 自带交叉验证拆分策略,默认cv=5
grid_search.fit(X_train, y_train)

print('用网格搜索找到的最优超参数为:')
print(grid_search.best_params_)

基于贪心算法的调参

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
贪心算法没有固定的算法框架,贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。一般来说,选择的贪心策略必须具备无后效性(即某个状态以后的过程不会影响以前的状态,只与当前状态有关。)

贪心算法调参缺点很明显,即每一步调参后只会取得局部最优参数。虽然有一种“适度贪婪”的调参法,可以“缓解”这种局部最优。
贪心调参没有现成的库函数,因此需要手动实现。以lightGBM模型为例,接下来讲述贪心算法调参的常用方法步骤:

第1步,先拿出bagging_fractionfeature_fraction这两个参数来调参,因为只有两个参数参与网格调参,所以可以快速找出最优参数。

params_1 = {
    'bagging_fraction': [0.5, 0.8, 1],
    'feature_fraction': [0.5, 0.8, 1],
}
model = lgb.LGBMRegressor()  # 其余参数使用默认的
grid_search = GridSearchCV(model, params_1)
grid_search.fit(X_train,y_train)

print('第一轮找到的最优超参数为:')
print(grid_search.best_params_)

第2步,再拿出lambda_l1lambda_l2这两个参数来调参。当然,并不一定非得两个参数一起调,也可以一步调一参或者一步调3参。

params_2 = {
    'lambda_l1': [0.01, 0.1, 1],
    'lambda_l2': [0.01, 0.1, 1],
}
best_params = clf.best_params_
model = lgb.LGBMRegressor(**best_params)  # 加入第一步调好的最优参数
grid_search = GridSearchCV(model, params_2)
grid_search.fit(X_train,y_train)

print('第二轮找到的最优超参数为:')
print(grid_search.best_params_)

第3步,拿出learning_rate这个参数来调参

params_3 = {
    'learning_rate': [0.001, 0.01, 0.1],
}
best_params = dict(best_params, **clf.best_params_)
model = lgb.LGBMRegressor(**best_params)  # 加入前2步调好的最优参数
grid_search = GridSearchCV(model, params_3)
grid_search.fit(X_train,y_train)

print('第三轮找到的最优超参数为:')
print(grid_search.best_params_)

第4步,以此类推。。。

除此之外,我还看到了一位大佬写的“适度贪婪”调参法,比上述传统方法好一点,这里就不细讲了。
【参考资料】
https://blog.youkuaiyun.com/m0_37893230/article/details/104449166
https://tianchi.aliyun.com/notebook-ai/detail?spm=5176.12586969.1002.24.1cd8593aLNK3uJ&postId=95460

随机搜索调参

随机搜索是利用随机数去求函数近似最优解的方法,区别于网格搜索的暴力搜索。

原理:在一定的区间内,不断地、随机地而不是有倾向性地产生随机点,并计算其约束函数和目标函数的值。对满足约束条件的点,逐个比较其目标函数的值,抛弃坏的点,保留好的点,最后得到最优解的近似解。随机搜索建立在概率论的基础上,所取随机点越多,得到最优解的概率也就越大。这种方法存在精度较差的问题,但是找到近似最优解的效率高于网格搜索。随机搜索一般用于粗选或普查。

具体使用方法如下,还是以lightGBM模型为例:

from sklearn.model_selection import RandomizedSearchCV

params = {
    'learning_rate': [0.001,0.01,0.1],
    'max_depth': [5, 10, 20],
    'min_split_gain': [0, 5, 10], 
    'num_leaves': [16, 64, 128],
}
model = lgb.LGBMRegressor() 
random_search = RandomizedSearchCV(model, params, cv=5, verbose=2)
random_search.fit(X_train, y_train)

print('随机搜索调参得到的最优参数:')
print(random_search.best_estimator_)

【参考资料】
《阿里云天池大赛赛题解析》

贝叶斯调参

贝叶斯调参主要思想是,给定优化的目标函数(广义的函数,只需指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数的后验分布

说起来挺复杂的,具体原理这里不细讲了,只需知道如何使用即可:

首先需要安装用于贝叶斯调参的包:

pip install bayesian-optimization

接下来是具体使用:

# 定义要优化的函数,x,y是超参数,返回值是模型的loss
def black_box_function(**params):
    cv_result = ML_model.cv(params, X_train, y_train)  # 此处是伪代码,换成你模型验证的代码
    return cv_result
    # 贝叶斯调参默认求最大化数值,实战中若是要求最小化数值,那就在最后返回值前加个负号


# 开始贝叶斯优化
from bayes_opt import BayesianOptimization

params= {
	'p1': (2, 4),  # 意思是,超参数p1的搜索范围是从2到4
	'p1': (-3, 3)  # 注意,这是个实数区间,不同于网格搜索的离散数
} 

optimizer = BayesianOptimization(
    f = black_box_function,
    pbounds = params,
    random_state = 1,
)

optimizer.maximize(
	init_points=21,  # 执行贝叶斯优化的步骤,步骤越多,效果越好,也会越慢
	n_iter=90  # 代表迭代次数(即采样数)
) 

print('贝叶斯调参得到的最优参数:')
print(optimizer.max)

【参考资料】
https://github.com/fmfn/BayesianOptimization
https://zhuanlan.zhihu.com/p/54030031

启发式搜索调参

启发式搜索又称有信息搜索,是利用问题拥有的启发信息来引导搜索,以达到减少搜索范围、降低问题复杂度的目的。
原理:在状态空间中,对每一个搜索的位置进行评估得到最好的位置,再从这个位置进行搜索,直到目标。这样可以省略大量无谓的搜索路径,提高了搜索效率。在启发式搜索中,对位置的估价是十分重要的。
启发式搜索非常多样化,而且在sklear包中并没有现成的函数。如果有需要我们可以针对某一 种启发式算法的实现过程进行了解,然后用Python手动实现。

【参考资料】
《阿里云天池大赛赛题解析》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值