网格搜索时应用最广泛的超参数搜素算法,网格搜索通过查找搜索范围内的所有点,来确定最优值。一般是通过给出较大的搜索范围以及较小的步长,网格搜索时一定可以找到全局最大值或全局最小值的。
但是网格搜索有一个较大的问题时:它十分消耗计算资源,特别是需要调优的超参数比较多的时候。因此在实践比赛中,需要调参的模型数量与对应的超参数比较多,而设计的数据量又比较大,因此相当消耗时间。此外,由于给出的超参数的组合比较多,因此一般都会固定多数参数,分布对1~2个超参数进行调节,这样能够减少时间但是难以自动进行。而且由于目标参数一般是非凸的,因此容易陷入局部最小值。
from sklearn.model_selection import GridSearchCV #定义自己的网格搜索函数 def GridSearch(clf, params, X, y): gscv = GridSearchCV(clf, params, scoring='neg_mean_squared_error', n_jobs=1, cv=5) gscv.fit(X, y) print("The best result: ", gscv.cv_results_) print("The best params: ", gscv.best_params_) #实验 params_sklearn = { "boosting_type" : 'gbdt', 'max_depth':3, "learning_rate" : 0.1, "objective" : "binary", "min_child_samples" : 20, "metric" : ['binary_logloss','auc'], "verbose" : -1, 'reg_lambda': 0.1, 'reg_alpha': 0.2, "random_state": 420, } gbm = lgb.LGBMClassifier(**params_sklearn) #网格搜索的参数 params_grid = { 'num_leaves':range(30,50), 'max_depth': range(4,8), } gscv = GridSearch(gbm, params_grid, train, y_train) #The best params: {'max_depth': 6, 'num_leaves': 40} #Timing 16.8s随机搜索
与网格搜索相比,随机搜索并未尝试所有参数值,而是从指定的分布中采样固定数量的参数设置。它的理论依据是,如果随即样本点集足够大,那么也可以找到全局的最大或最小值,或它们的近似值。通过对搜索范围的随机取样,随机搜索一般会比网格搜索要快一些。但是和网格搜索的快速版(非自动版)相似,结果也是没法保证的。
当超参数的搜索空间很大时,最好使用RandomizedSearchCV 。这个类的使用方法和类 GridSearchCV 很相似,但它不是尝试所有可能的组合,而是通过选择每个超参数的一个随机值的特定数量的随机组合。
#随机搜索,和网格搜索代码一致,除了更改GridSearchCV为RandomizedSearchCV from sklearn.model_selection import RandomizedSearchCV #定义自己的网格搜索函数 def RandomizedSearch(clf, params, X, y): rscv = RandomizedSearchCV(clf, params, scoring='neg_mean_squared_error', n_jobs=1, cv=5) rscv.fit(X, y) print("The best result: ", rscv.cv_results_) print("The best params: ", rscv.best_params_) #实验 params_sklearn = { "boosting_type" : 'gbdt', 'max_depth':3, "learning_rate" : 0.1, "objective" : "binary", "min_child_samples" : 20, "metric" : ['binary_logloss','auc'], "verbose" : -1, 'reg_lambda': 0.1, 'reg_alpha': 0.2, "random_state": 420, } gbm = lgb.LGBMClassifier(**params_sklearn) #网格搜索的参数 params_randm = { 'num_leaves':range(30,50), 'max_depth': range(4,8), } rscv = RandomizedSearch(gbm, params_randm, train, y_train) #The best params: {'num_leaves': 49, 'max_depth': 7} #Timing:2.8s贝叶斯优化
主要思想是:给定优化的目标函数(广义的函数,只需要指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数地后验分布。简单来说,就是考虑和上一次参数地信息,从而更好地调整当前地参数。
贝叶斯优化与常规的网格搜索或者随机搜索的区别是:
贝叶斯调参采用高斯过程,考虑之前的参数信息,不断地更新先验;网格搜索未考虑之前地参数信息贝叶斯调参迭代次数少,速度快,网格搜索速度慢,参数多时容易导致维度爆炸。贝叶斯调参针对非凸问题依旧稳健,网格搜索针对非凸问题容易陷入局部最小值。
#设定贝叶斯优化的黑盒函数LGB_bayesian def LGB_bayesian( num_leaves, # int min_data_in_leaf, # int learning_rate, min_sum_hessian_in_leaf, # int feature_fraction, lambda_l1, lambda_l2, min_gain_to_split, max_depth): # LightGBM expects next three parameters need to be integer. So we make them integer num_leaves = int(num_leaves) min_data_in_leaf = int(min_data_in_leaf) max_depth = int(max_depth) assert type(num_leaves) == int assert type(min_data_in_leaf) == int assert type(max_depth) == int param = { 'num_leaves': num_leaves, 'max_bin': 63, 'min_data_in_leaf': min_data_in_leaf, 'learning_rate': learning_rate, 'min_sum_hessian_in_leaf': min_sum_hessian_in_leaf, 'bagging_fraction': 1.0, 'bagging_freq': 5, 'feature_fraction': feature_fraction, 'lambda_l1': lambda_l1, 'lambda_l2': lambda_l2, 'min_gain_to_split': min_gain_to_split, 'max_depth': max_depth, 'save_binary': True, 'seed': 1337, 'feature_fraction_seed': 1337, 'bagging_seed': 1337, 'drop_seed': 1337, 'data_random_seed': 1337, 'objective': 'binary', 'boosting_type': 'gbdt', 'verbose': 1, 'metric': 'auc', 'is_unbalance': True, 'boost_from_average': False, "verbosity":-1 } lgb_train = lgb.Dataset(train, label=y_train) lgb_valid = lgb.Dataset(test,label=y_test,reference=lgb_train) num_round = 500 gbm= lgb.train(param, lgb_train, num_round, valid_sets = [lgb_valid],callbacks=[lgb.early_stopping(stopping_rounds=5)]) predictions = gbm.predict(test,num_iteration=gbm.best_iteration) score = roc_auc_score(y_test, predictions) return score
bounds_LGB = { 'num_leaves': (5, 20), 'min_data_in_leaf': (5, 20), 'learning_rate': (0.01, 0.3), 'min_sum_hessian_in_leaf': (0.00001, 0.01), 'feature_fraction': (0.05, 0.5), 'lambda_l1': (0, 5.0), 'lambda_l2': (0, 5.0), 'min_gain_to_split': (0, 1.0), 'max_depth':(3,15), } #将它们全部放在BayesianOptimization对象中 from bayes_opt import BayesianOptimization LGB_BO = BayesianOptimization(LGB_bayesian, bounds_LGB, random_state=13) print(LGB_BO.space.keys)#显示要优化的参数
import warnings import gc pd.set_option('display.max_columns', 200) init_points = 5 n_iter = 5 print('-' * 130) with warnings.catch_warnings(): warnings.filterwarnings('ignore') LGB_BO.maximize(init_points=init_points, n_iter=n_iter, acq='ucb', xi=0.0, alpha=1e-6)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)