-
2021-03-16 13:24:03
引言
不同的超参数的值对于模型的性能有不同的影响,我们需要找到的就是使得模型性能最佳的超参数。
1.网格搜索GridSearchCV()
网格搜索的思想非常简单,比如你有2个超参数需要去选择,那你就把所有的超参数选择列出来分别做排列组合。举个例子: 𝜆=0.01,0.1,1.0 和 𝛼=0.01,0.1,1.0 ,你可以做一个排列组合,即:{[0.01,0.01],[0.01,0.1],[0.01,1],[0.1,0.01],[0.1,0.1],[0.1,1.0],[1,0.01],[1,0.1],[1,1]} ,然后针对每组超参数分别建立一个模型,然后选择测试误差最小的那组超参数。换句话说,我们需要从超参数空间中寻找最优的超参数,很像一个网格中找到一个最优的节点,因此叫网格搜索
import numpy as np from sklearn.svm import SVR # 引入SVR类 from sklearn.pipeline import make_pipeline # 引入管道简化学习流程 from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类 from sklearn.model_selection import GridSearchCV # 引入网格搜索调优 from sklearn.model_selection import cross_val_score # 引入K折交叉验证 from sklearn import datasets boston = datasets.load_boston() # 返回一个类似于字典的类 X = boston.data y = boston.target features = boston.feature_names pipe_SVR = make_pipeline(StandardScaler(), SVR()) score1 = cross_val_score(estimator=pipe_SVR, X=X, y=y, scoring='r2', cv=10) # 10折交叉验证 print("CV accuracy: %.3f +/- %.3f" % ((np.mean(score1)), np.std(score1)))
from sklearn.svm import SVR # 引入SVR类 from sklearn.pipeline import make_pipeline, Pipeline # 引入管道简化学习流程 from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类 from sklearn.model_selection import GridSearchCV # 引入网格搜索调优 from sklearn.model_selection import cross_val_score # 引入K折交叉验证 from sklearn import datasets boston = datasets.load_boston() # 返回一个类似于字典的类 X = boston.data y = boston.target features = boston.feature_names pipe_svr = Pipeline([("StandardScaler", StandardScaler()), ("svr", SVR())]) param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0] # 管道与网格搜索结合 param_grid = [{"svr__C": param_range, "svr__kernel": ["linear"]}, # 注意__是指两个下划线,一个下划线会报错的 {"svr__C": param_range, "svr__gamma": param_range, "svr__kernel": ["rbf"]}] gs = GridSearchCV(estimator=pipe_svr, param_grid=param_grid, scoring='r2', cv=10) # 10折交叉验证 gs = gs.fit(X, y) print("网格搜索最优得分:", gs.best_score_) print("网格搜索最优参数组合:\n", gs.best_params_)
网格搜索最优得分: 0.6081303070817127 网格搜索最优参数组合: {'svr__C': 1000.0, 'svr__gamma': 0.001, 'svr__kernel': 'rbf'}
2.随机搜索GridSearchCV()
网格搜索相当于暴力地从参数空间中每个都尝试一遍,然后选择最优的那组参数,这样的方法显然是不够高效的,因为随着参数类别个数的增加,需要尝试的次数呈指数级增长。有没有一种更加高效的调优方式呢?那就是使用随机搜索的方式,这种方式不仅仅高校,而且实验证明,随机搜索法结果比稀疏化网格法稍好(有时候也会极差,需要权衡)。参数的随机搜索中的每个参数都是从可能的参数值的分布中采样的。与网格搜索相比,这有两个主要优点:
-
可以独立于参数数量和可能的值来选择计算成本。
-
添加不影响性能的参数不会降低效率。
from sklearn.svm import SVR # 引入SVR类 from sklearn.pipeline import make_pipeline, Pipeline # 引入管道简化学习流程 from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类 from sklearn import datasets from sklearn.model_selection import RandomizedSearchCV from scipy.stats import uniform # 引入均匀分布设置参数 boston = datasets.load_boston() # 返回一个类似于字典的类 X = boston.data y = boston.target features = boston.feature_names pipe_svr = Pipeline([("StandardScaler", StandardScaler()), ("svr", SVR())]) # 利用参数loc和scale,可以得到[loc, loc + scale]上的均匀分布,在uniform中loc是最小值,scale是最大值。 distributions = dict(svr__C=uniform(loc=1.0, scale=4), # 构建连续参数的分布 svr__kernel=["linear", "rbf"], # 离散参数的集合 svr__gamma=uniform(loc=0, scale=4)) rs = RandomizedSearchCV(estimator=pipe_svr, param_distributions=distributions, scoring='r2', cv=10) # 10折交叉验证 rs = rs.fit(X, y) print("随机搜索最优得分:", rs.best_score_) print("随机搜索最优参数组合:\n", rs.best_params_)
随机搜索最优得分: 0.2988221516140073 随机搜索最优参数组合: {'svr__C': 4.503224088282858, 'svr__gamma': 3.1457760882766905, 'svr__kernel': 'linear'}
3.总结
数据量小使用网格搜索,当时间代价比较大时,可以多次使用随机搜索。
参考:
机器学习基础
如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论留言!
更多相关内容 -
-
超参数优化:随机搜索.zip
2020-06-08 20:21:19使用python进行随机搜索法在机器学习和深度学习的小案例,压缩包包括: (1)NHANES.xlsx; (2)随机搜索法.ipynb -
随机搜索和优化:支持随机搜索和优化简介一书的代码。-matlab开发
2021-05-31 03:32:10随机搜索和优化介绍概述了随机优化的原理、算法和实践方面,包括从工程、统计学和计算机科学中提取的应用程序。 这本书既可以作为研究人员和从业人员的参考书,也可以作为教科书,后者的使用由每章末尾的练习和附录... -
随机搜索算法:随机搜索属于随机优化和全局优化领域。-matlab开发
2021-05-30 16:10:31随机搜索属于随机优化和全局领域优化。 随机搜索是一种直接搜索方法,因为它不需要导数来搜索连续域。 这种基本方法是与提供小改进的技术相关,例如 Directed 随机搜索和自适应随机搜索。 -
matlab开发-随机搜索和优化
2019-08-23 14:51:03matlab开发-随机搜索和优化。支持随机搜索和优化书籍介绍的代码。 -
随机搜索 超参数调节
2018-05-09 20:41:47利用随机搜索法对深度学习进行超参数的调节优化算法实践 -
随机搜索:使用自适应随机搜索的无约束全局优化。-matlab开发
2021-06-01 19:34:16使用自适应随机搜索的无约束全局优化。 基于 1989 年 9 月 29 日用 C 语言编写的约束全局优化算法,并发布为: AR Secchi 和 CA Perlingeiro,“Busca Aleatoria Adaptativa”,在 Proc。 XII Congresso Nacional de... -
网格搜索、随机搜索机器学习实战
2022-04-02 16:07:44网格搜索 随机搜索网格搜索随机搜索 网格搜索 class sklearn.model_selection.GridSearchCV( estimator :考虑优化的估计器 param_grid : dict or list of dictionaries,希望进行搜索的参数阵 scoring = None : ...网格搜索
class sklearn.model_selection.GridSearchCV(
estimator :考虑优化的估计器
param_grid : dict or list of dictionaries,希望进行搜索的参数阵
scoring = None : string/callable/list/tuple/dict/None,模型评分方法
fit_params = None, n_jobs = 1, cv = None
iid = True :数据是否在各fold间均匀分布,此时将直接最小化总样本的损失函数refit = True :是否使用发现的最佳参数重新拟合估计器
verbose = 0, pre_dispatch = '2*n_jobs ', error_score = 'raise’return_train_score = True :是否返回训练集的评分
)
GridSearchCV类的属性:
cv_results_ :字典格式的参数列表,可被直接转换为pandas数据框 best_estimator_ :网格搜索得出的最佳模型 best_score_ :最佳模型的平均交互验证得分 best_params_ : dict,最佳模型的参数设定 best_index_ : int,最佳模型对应的索引值 scorer_ : function or a dict,用于选择最佳模型的评分函数 n_splits_ : int,交叉验证的拆分数
GridSearchCV类的方法:
decision_function ( *args,**kwargs) :调用筛选出的最佳模型并返回预测结果其余标准API接函数
decision_function返回数据点属于每个类别的判定系数,若为正数,则代表该点属于这一类,负数则表示该点不属于这一类。判定系数的绝对值越大,判断的可信度越高。
from sklearn import svm from sklearn import datasets from sklearn.model_selection import GridSearchCV import pandas as pd
iris = datasets.load_iris() parameters = {'kernel':('linear','rbf'),'C':[1.10]} #实例化 svc = svm.SVC(probability = True) clf = GridSearchCV(svc,parameters) clf.fit(iris.data,iris.target)
GridSearchCV(cv='warn', error_score='raise-deprecating', estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma='auto_deprecated', kernel='rbf', max_iter=-1, probability=True, random_state=None, shrinking=True, tol=0.001, verbose=False), iid='warn', n_jobs=None, param_grid={'C': [1.1], 'kernel': ('linear', 'rbf')}, pre_dispatch='2*n_jobs', refit=True, return_train_score=False, scoring=None, verbose=0)
from sklearn.svm import SVC
#显示所有拟合模型的参数设定 pd.DataFrame(clf.cv_results_)
mean_fit_time std_fit_time mean_score_time std_score_time param_C param_kernel params split0_test_score split1_test_score split2_test_score mean_test_score std_test_score rank_test_score 0 0.001341 0.000485 0.000000 0.00000 1.1 linear {'C': 1.1, 'kernel': 'linear'} 1.000000 0.960784 1.000000 0.986667 0.018577 1 1 0.005318 0.005421 0.000333 0.00047 1.1 rbf {'C': 1.1, 'kernel': 'rbf'} 0.980392 0.960784 0.979167 0.973333 0.009021 2 clf.best_params_
{'C': 1.1, 'kernel': 'linear'}
print(clf.decision_function(iris.data))#网格搜索
[[ 2.24627744 1.29829892 -0.30632837] [ 2.23781119 1.29693571 -0.30471538] [ 2.24548583 1.29718879 -0.30559412] [ 2.23591041 1.29589056 -0.30389728] [ 2.24795778 1.29822418 -0.3064484 ] [ 2.23752685 1.29735806 -0.30495212] [ 2.2434869 1.29624146 -0.30483534] [ 2.24100113 1.29748846 -0.30534443] [ 2.23661182 1.2953947 -0.30365738] [ 2.2375786 1.2973143 -0.30492944] [ 2.24558626 1.29895555 -0.30665596] [ 2.23718064 1.29655761 -0.3044249 ] [ 2.23997815 1.29729146 -0.30513039] [ 2.2512266 1.29724082 -0.30622266] [ 2.25842469 1.3013034 -0.30927775] [ 2.25245732 1.29965175 -0.30772804] [ 2.25194914 1.29891281 -0.3072508 ] [ 2.24452273 1.29771579 -0.30581239] [ 2.23723948 1.29851098 -0.30565066] [ 2.24582594 1.29783236 -0.30600783] [ 2.23172213 1.29768867 -0.30467686] [ 2.24234659 1.29705619 -0.30520883] [ 2.25994866 1.29879541 -0.30806837] [ 2.22220568 1.29476653 -0.30201257] [ 2.22238071 1.29523835 -0.30233811] [ 2.22837826 1.29635472 -0.30354531] [ 2.23246711 1.29580915 -0.30353915] [ 2.24249366 1.29815377 -0.30588644] [ 2.24452963 1.29837334 -0.30620727] [ 2.23329426 1.2959152 -0.30367832] [ 2.23097932 1.29600008 -0.30353221] [ 2.23636238 1.29729451 -0.30481098] [ 2.25330507 1.29966903 -0.30782355] [ 2.2557716 1.30030318 -0.30843809] [ 2.23545141 1.29669764 -0.30435806] [ 2.2485707 1.29833029 -0.30657146] [ 2.2491945 1.29959712 -0.30737741] [ 2.24969301 1.29855531 -0.30681499] [ 2.24251854 1.29603049 -0.30461341] [ 2.24086415 1.29773868 -0.30548479] [ 2.24814273 1.29786457 -0.3062567 ] [ 2.22578517 1.29425389 -0.30197265] [ 2.24585572 1.29640343 -0.30517211] [ 2.22992334 1.29464894 -0.30258346] [ 2.22639242 1.29551952 -0.3028421 ] [ 2.23584715 1.29603506 -0.30398092] [ 2.24398491 1.29802466 -0.30594642] [ 2.24190045 1.29650998 -0.30483816] [ 2.24570962 1.29872219 -0.30652718] [ 2.24310378 1.29771639 -0.30567798] [-0.25888157 2.27043006 0.84961887] [-0.25420288 2.26613432 0.85736765] [-0.26566202 2.26422889 1.03089525] [-0.24725457 2.26389816 0.83953777] [-0.26167944 2.26301954 0.97285293] [-0.2558817 2.26139866 0.91727953] [-0.25960377 2.26047526 0.98289875] [-0.19807268 2.27437013 0.7462427 ] [-0.25819096 2.26876747 0.85971716] [-0.23803641 2.26291864 0.81574102] [-0.22433167 2.27078106 0.76857795] [-0.24705163 2.26470632 0.8338466 ] [-0.24425962 2.27327002 0.78539706] [-0.26147994 2.26048024 1.01994941] [-0.21600922 2.27333011 0.75641414] [-0.25140742 2.2712808 0.81140066] [-0.2559883 2.25665492 0.98796188] [-0.23905423 2.273164 0.77761803] [-0.26533223 2.25720279 1.11452981] [-0.23621673 2.27128811 0.78004053] [-0.26495855 2.24680537 1.16854301] [-0.23955415 2.2718155 0.78305262] [-0.27060306 2.25321773 1.1785179 ] [-0.26019837 2.26448894 0.92626119] [-0.24921993 2.27097946 0.8065506 ] [-0.25268911 2.26997762 0.82331433] [-0.26531537 2.26507325 1.00569519] [-0.27032769 2.25456052 1.17143878] [-0.25759465 2.26029055 0.95342037] [-0.20874231 2.27830251 0.74273904] [-0.23361723 2.27122032 0.77690547] [-0.22625653 2.27409475 0.76152715] [-0.23467384 2.27203226 0.77563407] [-0.27318245 1.24299275 2.21645134] [-0.25579586 2.25427719 1.025428 ] [-0.25255831 2.26139138 0.88790408] [-0.2609764 2.26533568 0.92399971] [-0.25977858 2.26537697 0.90938447] [-0.23921988 2.26768065 0.79813843] [-0.24402523 2.26517928 0.82109608] [-0.2540305 2.26200534 0.89343164] [-0.25783181 2.26278911 0.92107182] [-0.24081212 2.27029624 0.79080786] [-0.20208621 2.27458063 0.74730352] [-0.2479946 2.26442341 0.83926823] [-0.24139608 2.26915346 0.7964656 ] [-0.24494709 2.26657115 0.81671407] [-0.24899229 2.26941618 0.81397179] [-0.16817711 2.27765932 0.73375002] [-0.24293044 2.26735753 0.80760147] [-0.28707384 1.14947354 2.28119096] [-0.27544166 1.22551722 2.24241259] [-0.28572654 1.21950229 2.26763227] [-0.28075419 1.22722381 2.253935 ] [-0.28496263 1.19919165 2.27167675] [-0.29221928 1.20120343 2.28271138] [-0.26350515 1.23390222 2.19566155] [-0.28872304 1.22449799 2.27171205] [-0.28536738 1.22270759 2.26580515] [-0.28702396 1.1962758 2.27552215] [-0.27295679 1.24123017 2.21846124] [-0.27867286 1.23154175 2.24615515] [-0.28099808 1.22753736 2.25431583] [-0.27600114 1.21779044 2.24849707] [-0.27838341 1.19196788 2.26253449] [-0.27824419 1.21747936 2.25346649] [-0.27892215 1.23592175 2.24334747] [-0.29050259 1.20935777 2.27863355] [-0.29632366 1.14630194 2.29280364] [-0.27446017 1.24383688 2.21985224] [-0.28353826 1.21366733 2.26542492] [-0.27210994 1.22438478 2.23485951] [-0.29332401 1.2025653 2.28418614] [-0.2716128 1.24523345 2.20596604] [-0.28175043 1.22264441 2.25843786] [-0.28427267 1.23661991 2.25666445] [-0.26887359 1.24715529 2.1886087 ] [-0.2689827 1.24534071 2.19396581] [-0.28314739 1.20961778 2.26596079] [-0.28185127 1.24735998 2.24067838] [-0.28776392 1.22705696 2.26896304] [-0.2869051 1.23657142 2.26293051] [-0.28371257 1.20202648 2.26897129] [-0.27174181 1.25176897 2.18997946] [-0.27988353 1.23805115 2.2441591 ] [-0.2888502 1.21427543 2.27478929] [-0.28160162 1.19629383 2.2668145 ] [-0.27824449 1.23534175 2.24198858] [-0.26693842 1.24624323 2.18133534] [-0.27913621 1.23429921 2.24525582] [-0.28339523 1.2030499 2.26818344] [-0.27624857 1.23436839 2.23730158] [-0.27544166 1.22551722 2.24241259] [-0.28569412 1.20057856 2.27257418] [-0.28405792 1.19376775 2.27133323] [-0.27826174 1.22537803 2.24926502] [-0.27556832 1.23623495 2.23346001] [-0.27601105 1.23598869 2.23502853] [-0.2782753 1.21132467 2.25621161] [-0.27247876 1.23666418 2.22329881]]
随机搜索
在不明确可能的参数候选值时,可以在指定的参数值分布中进行取样,实现对参数的随机搜索。class sklearn.model_selection.RandomizedSearchCV(
estimator : param_distributions : dict,希望进行搜索的参数字典 n_iter = 10 : int,考虑抽取出的参数组合数,该参数用于控制计算总量 scoring = None, fit _params = None, n_jobs = 1, iid = True refit = True :使用整个数据集重新fit搜索到的最佳参数组合模型 cv = None, verbose =0 pre_dispatch = '2*n_jobs ', random_state = Noneerror_score = 'raise', return_train_score = True )
RandomizedSearchCV类的属性(和GridSearchCV类相同):
cv_results_ :字典格式的参数列表,可被直接转换为pandas数据框 best_estimator_ : 网格搜索得出的最佳模型 best_score_ :最佳模型的平均交互验证得分 best_params_ : dict,最佳模型的参数设定 best_index_ : int,最佳模型对应的索引值 scorer_ : function or a dict,用于选择最佳模型的评分函数 n_splits_ : int,交叉验证的拆分数
RandomizedSearchCV类的方法(和GridSearchCV类相同)︰
decision_function (*args,**kwargs) :调用最佳模型,并返回预测结果其余标准API接函数
import scipy.stats as stats from sklearn import datasets from sklearn.model_selection import RandomizedSearchCV import pandas as pd from sklearn.svm import SVC
#导入数据集并设定参数 iris = datasets.load_iris() parameters2 = {"kernel":('linear','rbf'), 'C':stats.expon(scale=100), 'gamma':stats.expon(scale=1), 'class_weight':('balanced',None)}
svc = SVC()
clf = RandomizedSearchCV(svc,parameters2) clf.fit(iris.data,iris.target) pd.DataFrame(clf.cv_results_)
mean_fit_time std_fit_time mean_score_time std_score_time param_C param_class_weight param_gamma param_kernel params split0_test_score split1_test_score split2_test_score mean_test_score std_test_score rank_test_score 0 0.000998 8.142963e-04 0.000344 0.000486 133.412 balanced 1.61514 rbf {'C': 133.41183918245417, 'class_weight': 'bal... 1.000000 0.941176 0.958333 0.966667 0.024918 6 1 0.000000 0.000000e+00 0.000653 0.000462 15.8825 None 1.69397 linear {'C': 15.88249498314624, 'class_weight': None,... 1.000000 0.921569 1.000000 0.973333 0.037154 1 2 0.000665 4.710309e-04 0.000333 0.000470 37.7037 balanced 0.079273 linear {'C': 37.703742462767295, 'class_weight': 'bal... 1.000000 0.921569 1.000000 0.973333 0.037154 1 3 0.000997 4.052337e-07 0.000333 0.000471 25.3494 balanced 0.951097 rbf {'C': 25.34942982674127, 'class_weight': 'bala... 0.980392 0.941176 1.000000 0.973333 0.024415 1 4 0.000676 4.779710e-04 0.000343 0.000485 245.106 balanced 0.663588 linear {'C': 245.10614694204088, 'class_weight': 'bal... 1.000000 0.921569 1.000000 0.973333 0.037154 1 5 0.000661 4.685966e-04 0.000337 0.000476 22.3682 None 0.0174971 linear {'C': 22.368243827973412, 'class_weight': None... 1.000000 0.921569 1.000000 0.973333 0.037154 1 6 0.000333 4.703588e-04 0.000676 0.000478 227.165 None 0.318804 rbf {'C': 227.16515187404892, 'class_weight': None... 0.980392 0.901961 1.000000 0.960000 0.042411 10 7 0.000332 4.691225e-04 0.000000 0.000000 125.798 None 0.11144 rbf {'C': 125.79773872651727, 'class_weight': None... 1.000000 0.901961 1.000000 0.966667 0.046442 6 8 0.000000 0.000000e+00 0.000997 0.000027 3.60636 None 2.07116 linear {'C': 3.6063649298660225, 'class_weight': None... 0.980392 0.921569 1.000000 0.966667 0.033333 6 9 0.000665 4.705275e-04 0.000322 0.000455 61.6049 None 0.429071 rbf {'C': 61.60492358027872, 'class_weight': None,... 1.000000 0.901961 1.000000 0.966667 0.046442 6 clf.best_params_
{'C': 15.88249498314624, 'class_weight': None, 'gamma': 1.693966803275749, 'kernel': 'linear'}
-
【机器学习】网格搜索、随机搜索和贝叶斯搜索实用教程
2021-11-04 00:47:58在本文中,小编将和你一起研习 3 种最流行的超参数调整技术:网格搜索、随机搜索和贝叶斯搜索。其实还有第零种调参方法,就是手动调参,因为简单机械,就不在本文讨论范围内。为方便阅读,列出本文的结构如下: 1....在机器学习中,超参数是指无法从数据中学习而需要在训练前提供的参数。机器学习模型的性能在很大程度上依赖于寻找最佳超参数集。
超参数调整一般是指调整模型的超参数,这基本上是一个非常耗时的过程。在本文中,小编将和你一起研习 3 种最流行的超参数调整技术:网格搜索、随机搜索和贝叶斯搜索。其实还有第零种调参方法,就是手动调参,因为简单机械,就不在本文讨论范围内。为方便阅读,列出本文的结构如下:
1.获取和准备数据
2.网格搜索
3.随机搜索
4.贝叶斯搜索
5.写在最后
获取和准备数据
为演示方便,本文使用内置乳腺癌数据来训练支持向量分类(SVC)。可以通过
load_breast_cancer
函数获取数据。import pandas as pd from sklearn.datasets import load_breast_cancer cancer = load_breast_cancer() df_X = pd.DataFrame(cancer['data'], columns=cancer['feature_names']) df_X.head()
接下来为特征和目标标签创建
df_X
和df_y
,如下所示:df_y = pd.DataFrame(cancer['target'], columns=['Cancer']) df_y.head()
PS :如果想了解更多关于数据集的信息,可以运行
print(cancer['DESCR'])
打印出摘要和特征信息。接下来,使用
training_test_split()
方法将数据集拆分为训练集 (70%) 和测试集 (30%) :# train test split from sklearn.model_selection import train_test_split import numpy as np X_train, X_test, y_train, y_test = train_test_split(df_X, np.ravel(df_y), test_size=0.3)
我们将训练支持向量分类器(SVC) 模型。正则化参数
C
和核系数gamma
是 SVC 中最重要的两个超参数:正则化参数
C
决定了正则化的强度。核系数
gamma
控制核的宽度。SVC默认使用径向基函数 (RBF)核(也称为高斯核)。
我们将在以下教程中调整这两个参数。
网格搜索
最优值
C
和gamma
是比较难找得到的。最简单的解决方案是尝试一堆组合,看看哪种组合效果最好。这种创建参数“网格”并尝试所有可能组合的方法称为网格搜索。网格搜索——尝试所有可能的组合 这种方法非常常见,所以Scikit-learn在
GridSearchCV
中内置了这种功能。CV 代表交叉验证,这是另一种评估和改进机器学习模型的技术。GridSearchCV
需要一个描述准备尝试的参数和要训练的模型的字典。网格搜索的参数网格定义为字典,其中键是参数,值是要测试的一系列设置值。下面动手试试,首先定义候选参数C
和
gamma
,如下所示:param_grid = { 'C': [0.1, 1, 10, 100, 1000], 'gamma': [1, 0.1, 0.01, 0.001, 0.0001] }
接下来创建一个
GridSearchCV
对象,并使用训练数据进行训练模型。from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC grid = GridSearchCV( SVC(), param_grid, refit=True, verbose=3 )
一旦训练完成后,我们可以通过
GridSearchCV
的best_params_
属性查看搜索到的最佳参数,并使用best_estimator_
属性查看最佳模型:# 找到最好的参数 grid.best_params_
{'C': 1, 'gamma': 0.0001}
# 找到最好的模型 grid.best_estimator_
SVC(C=1, gamma=0.0001)
训练完成后,现在选择并采用该网格搜索到的最佳模型,并使用测试集进行预测并创建分类报告和混淆矩阵。
# 使用最好的估计器进行预测 grid_predictions = grid.predict(X_test) # 混淆矩阵 from sklearn.metrics import classification_report, confusion_matrix print(confusion_matrix(y_test, grid_predictions))
[[ 55 5] [ 1 110]]
# 分类模型报告 print(classification_report(y_test, grid_predictions))
precision recall f1-score support 0 0.98 0.92 0.95 60 1 0.96 0.99 0.97 111 accuracy 0.96 171 macro avg 0.97 0.95 0.96 171 weighted avg 0.97 0.96 0.96 171
随机搜索
网格搜索尝试超参数的所有组合,因此增加了计算的时间复杂度,在数据量较大,或者模型较为复杂等等情况下,可能导致不可行的计算成本,这样网格搜索调参方法就不适用了。然而,随机搜索提供更便利的替代方案,该方法只测试你选择的超参数组成的元组,并且超参数值的选择是完全随机的,如下图所示。
随机搜索尝试随机组合 这种方法也很常见,所以Scikit-learn在
RandomizedSearchCV
中内置了这种功能。函数 API 与GridSearchCV
类似。首先指定参数
C
和gamma
以及参数值的候选样本的分布,如下所示:import scipy.stats as stats from sklearn.utils.fixes import loguniform # 指定采样的参数和分布 param_dist = { 'C': stats.uniform(0.1, 1e4), 'gamma': loguniform(1e-6, 1e+1), }
接下来创建一个
RandomizedSearchCV
带参数n_iter_search
的对象,并将使用训练数据来训练模型。n_iter_search = 20 random_search = RandomizedSearchCV( SVC(), param_distributions=param_dist, n_iter=n_iter_search, refit=True, verbose=3) random_search.fit(X_train, y_train)
输出示例 同样,一旦训练完成后,我们可以通过
RandomizedSearchCV
的best_params_
属性查看搜索到的最佳参数,并使用best_estimator_
属性查看得到的最佳模型:>>> random_search.best_params_ {'C': 559.3412579902997, 'gamma': 0.00022332416796205752} >>> random_search.best_estimator_ SVC(C=559.3412579902997, gamma=0.00022332416796205752)
预测 RandomizedSearchCV 并创建报告。
最后,我们采用最终确定的最佳随机搜索模型,并使用测试集进行预测,并创建分类报告和混淆矩阵查看模型效果。
# 使用最好的估计器进行预测 random_predictions = random_search.predict(X_test) from sklearn.metrics import classification_report, confusion_matrix # Confusion matrics print(confusion_matrix(y_test, random_predictions))
[[ 57 3] [ 3 108]]
# 分类评价报告 print(classification_report(y_test, random_predictions))
precision recall f1-score support 0 0.95 0.95 0.95 60 1 0.97 0.97 0.97 111 accuracy 0.96 171 macro avg 0.96 0.96 0.96 171 weighted avg 0.96 0.96 0.96 171
贝叶斯搜索
贝叶斯搜索使用贝叶斯优化技术对搜索空间进行建模,以尽快获得优化的参数值。它使用搜索空间的结构来优化搜索时间。贝叶斯搜索方法使用过去的评估结果来采样最有可能提供更好结果的新候选参数(如下图所示)。
贝叶斯搜索 Scikit-Optimize[1]库带有 BayesSearchCV 实现。
首先指定参数C和gamma以及参数值的候选样本的分布,如下所示:
from skopt import BayesSearchCV # 参数范围由下面的一个指定 from skopt.space import Real, Categorical, Integer search_spaces = { 'C': Real(0.1, 1e+4), 'gamma': Real(1e-6, 1e+1, 'log-uniform'), }
接下来创建一个RandomizedSearchCV带参数n_iter_search的对象,并将使用训练数据来训练模型。
n_iter_search = 20 bayes_search = BayesSearchCV( SVC(), search_spaces, n_iter=n_iter_search, cv=5, verbose=3 ) bayes_search.fit(X_train, y_train)
同样,一旦训练完成后,我们可以通过检查发现的最佳参数
BayesSearchCV
的best_params_
属性,并在最佳估计best_estimator_
属性:bayes_search.best_params_
OrderedDict([('C', 0.25624177419852506), ('gamma', 0.00016576008531229226)])
bayes_search.best_estimator_
SVC(C=0.25624177419852506, gamma=0.00016576008531229226)
最后,我们采用贝叶斯搜索模型并使用测试集创建一些预测,并为它们创建分类报告和混淆矩阵。
bayes_predictions = bayes_search.predict(X_test) from sklearn.metrics import classification_report,confusion_matrix # 混淆矩阵 print(confusion_matrix(y_test, bayes_predictions))
[[ 51 9] [ 1 110]]
# 分类评价报告 print(classification_report(y_test, bayes_predictions))
precision recall f1-score support 0 0.98 0.85 0.91 60 1 0.92 0.99 0.96 111 accuracy 0.94 171 macro avg 0.95 0.92 0.93 171 weighted avg 0.94 0.94 0.94 171
写在最后
在本文中,我们介绍了 3 种最流行的超参数优化技术,这些技术用于获得最佳超参数集,从而训练稳健的机器学习模型。
一般来说,如果组合的数量足够有限,我们可以使用网格搜索技术。但是当组合数量增加时,我们应该尝试随机搜索或贝叶斯搜索,因为它们在计算上并不昂贵。
往期精彩回顾 适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑 AI基础下载黄海广老师《机器学习课程》视频课黄海广老师《机器学习课程》711页完整版课件
本站qq群554839127,加入微信群请扫码:
-
结合Sklearn的网格和随机搜索进行自动超参数调优
2021-03-06 09:28:57什么是超参数? 今天,隐藏着数学世界的算法只需要几行代码就可以训练出来。它们的成功首先取决于训练的数据,然后取决于用户使用的超参数。...今天将介绍两种自动超参数优化方法:随机搜索和网格搜索。给定一组模型什么是超参数?
今天,隐藏着数学世界的算法只需要几行代码就可以训练出来。它们的成功首先取决于训练的数据,然后取决于用户使用的超参数。这些超参数是什么?
超参数是用户定义的值,如kNN中的k和Ridge和Lasso回归中的alpha。它们严格控制模型的拟合,这意味着,对于每个数据集,都有一组唯一的最优超参数有待发现。最基本的方法便是根据直觉和经验随机尝试不同的值。然而,正如您可能猜到的那样,当有许多超参数需要调优时,这个方法很快就会变得无用。
今天将介绍两种自动超参数优化方法:随机搜索和网格搜索。给定一组模型的所有超参数的可能值,网格搜索使用这些超参数的每一个组合来匹配模型。更重要的是,在每个匹配中,网格搜索使用交叉验证来解释过拟合。在尝试了所有的组合之后,搜索将保留导致最佳分数的参数,以便您可以使用它们来构建最终的模型。
随机搜索采用的方法与网格稍有不同。它不是详尽地尝试超参数的每一个单独组合,这在计算上可能是昂贵和耗时的,它随机抽样超参数,并试图接近最好的集合。
如果人工编写这种测试方法,会非常的费力,幸好Scikit-learn提供了GridSearchCV和RandomizedSearchCV类,使这个过程变得轻而易举。今天,你将了解他们的一切!
准备数据
我们将对爱荷华州住房数据集(https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data)的随机森林回归模型进行调整。我之所以选择随机森林,是因为它有足够大的超参数,使本指南的信息更加丰富,但您将学习的过程可以应用于Sklearn API中的任何模型。所以,让我们开始:
houses_train = pd.read_csv("data/train.csv") houses_test = pd.read_csv("data/test.csv") houses_train.head()
目标是SalePrice。为简单起见,我将只选择数字特性:
X = houses_train.select_dtypes(include="number").drop("SalePrice", axis=1) y = houses_train.SalePrice X_test = houses_test.select_dtypes(include="number")
首先,训练集和测试集都包含缺失值。我们将使用SimpleImputer来处理它们:
from sklearn.impute import SimpleImputer # Impute both train and test sets imputer = SimpleImputer(strategy="mean") X = imputer.fit_transform(X) X_test = imputer.fit_transform(X_test)
现在,让我们用默认参数拟合一个基本的RandomForestRegressor。由于我们将只将测试集用于最终评估,我将使用训练数据创建一个单独的验证集:
%%time from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.3) # Fit a base model forest = RandomForestRegressor() _ = forest.fit(X_train, y_train) >>> print(f"R2 for training set: {forest.score(X_train, y_train)}") >>> print(f"R2 for validation set: {forest.score(X_valid, y_valid)}\n") R2 for training set: 0.9785951576271396 R2 for validation set: 0.832622375495487 Wall time: 1.71 s
注意:本文的主要重点是如何执行超参数调优。我们不会担心其他问题,如过拟合或特征工程,因为这里我们要说明的是:如何使用随机和网格搜索,以便您可以在现实生活中应用自动超参数调优。
我们在测试集上得到了R2的0.83。我们只使用默认参数来拟合回归变量,这些参数是:
>>> forest.get_params() {'bootstrap': True, 'ccp_alpha': 0.0, 'criterion': 'mse', 'max_depth': None, 'max_features': 'auto', 'max_leaf_nodes': None, 'max_samples': None, 'min_impurity_decrease': 0.0, 'min_impurity_split': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_estimators': 100, 'n_jobs': None, 'oob_score': False, 'random_state': None, 'verbose': 0, 'warm_start': False}
有很多超参数。我们不会调整所有的内容,而是只关注最重要的内容。具体地说:
n_esimators:要使用的树的数量
max_feauters:每个节点拆分时要使用的特性数量
max_depth:每棵树上的叶子数量
min_samples_split:分裂内部节点所需的最小样本数
min_samples_leaf:每个叶子中的最小样本数量
bootstrap:取样方法,是否替换。网格搜索和随机搜索都试图为每个超参数找到最优值。让我们先看看随机搜索的实际情况。
随机搜索Sklearn RandomizedSearchCV
Scikit-learn提供RandomizedSearchCV类实现随机搜索。它需要两个参数来建立:一个估计器和超参数的可能值集,称为参数网格或空间。让我们为我们的随机森林模型定义这个参数网格:
n_estimators = np.arange(100, 2000, step=100) max_features = ["auto", "sqrt", "log2"] max_depth = list(np.arange(10, 100, step=10)) + [None] min_samples_split = np.arange(2, 10, step=2) min_samples_leaf = [1, 2, 4] bootstrap = [True, False] param_grid = { "n_estimators": n_estimators, "max_features": max_features, "max_depth": max_depth, "min_samples_split": min_samples_split, "min_samples_leaf": min_samples_leaf, "bootstrap": bootstrap, } >>> param_grid {'n_estimators': array([ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900]), 'max_features': ['auto', 'sqrt', 'log2'], 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, None], 'min_samples_split': array([2, 4, 6, 8]), 'min_samples_leaf': [1, 2, 4], 'bootstrap': [True, False]}
这个参数网格字典应该在模型文档中出现的语法中有超参数作为键。可能的值可以以数组的形式给出。
现在,让我们最后从sklearn导入RandomizedSearchCV。model_selection并实例化它:
from sklearn.model_selection import RandomizedSearchCV forest = RandomForestRegressor() random_cv = RandomizedSearchCV( forest, param_grid, n_iter=100, cv=3, scoring="r2", n_jobs=-1 )
除可接受的估计量和参数网格外,还具有n_iter参数。它控制了我们在搜索中允许的超参数组合的随机选择的迭代次数。我们将其设置为100,因此它将随机抽样100个组合并返回最好的分数。我们也使用三折交叉验证与决定系数作为评分,这是默认的。你可以从sklearn.metrics.SCORERS.keys()中传递任何其他得分函数。现在让我们开始这个过程:
注意,因为随机搜索执行交叉验证,所以我们可以将它作为一个整体来适应训练数据。由于交叉验证的工作方式,它将为训练和验证创建单独的设置。另外,我将n_jobs设置为-1,以使用我的机器上的所有内核。
%%time _ = random_cv.fit(X, y) >>> print("Best params:\n") >>> print(random_cv.best_params_) Best params: {'n_estimators': 800, 'min_samples_split': 4, 'min_samples_leaf': 1, 'max_features': 'sqrt', 'max_depth': 20, 'bootstrap': False} Wall time: 16min 56s
经过~17分钟的训练后,可以使用.best_params_属性访问找到的最佳参数。我们也可以看到最好的分数:
>>> random_cv.best_score_ 0.8690868090696587
我们得到了87%左右的决定系数比基础模型提高了4%
Sklearn GridSearchCV
你永远不要根据RandomSearchCV的结果来选择你的超参数。只使用它来缩小每个超参数的值范围,以便您可以为GridSearchCV提供更好的参数网格。
你会问,为什么不从一开始就使用GridSearchCV呢?看看初始参数网格:
n_iterations = 1 for value in param_grid.values(): n_iterations *= len(value) >>> n_iterations 13680
有13680个可能的超参数组合和3倍CV, GridSearchCV将必须适合随机森林41040次。使用RandomizedGridSearchCV,我们得到了相当好的分数,并且只需要100 * 3 = 300 次训练。
现在,是时候在之前的基础上创建一个新的参数网格,并将其提供给GridSearchCV:
new_params = { "n_estimators": [650, 700, 750, 800, 850, 900, 950, 1000], "max_features": ['sqrt'], "max_depth": [10, 15, 20, 25, 30], "min_samples_split": [2, 4, 6], "min_samples_leaf": [1, 2], "bootstrap": [False], }
这次我们有:
n_iterations = 1 for value in new_params.values(): n_iterations *= len(value) >>> n_iterations 240
240种组合,这还是很多,但是比起之前的计算已经少很多了。让我们导入GridSearchCV并实例化它:
from sklearn.model_selection import GridSearchCV forest = RandomForestRegressor() grid_cv = GridSearchCV(forest, new_params, n_jobs=-1)
我不需要指定评分和CV,因为我们使用的是默认设置,所以不需要指定。让我们适应并等待:
%%time _ = grid_cv.fit(X, y) print('Best params:\n') print(grid_cv.best_params_, '\n') Best params: {'bootstrap': False, 'max_depth': 15, 'max_features': 'sqrt', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 950} Wall time: 35min 18s
35分钟后,我们得到了以上的分数,这一次——确实是最优的分数。让我们看看他们与RandomizedSearchCV有多少不同:
>>> grid_cv.best_score_ 0.8696576413066612
你感到惊讶吗?我也是。结果的差别很小。然而,这可能只是给定数据集的一个特定情况。
当您在实践中使用需要大量计算的模型时,最好得到随机搜索的结果,并在更小的范围内在网格搜索中验证它们。
结论
从上面看您可能会认为这一切都很棒。 如果我们使用了以上的方法对超参数进行调整就可以不必再去看超参数的实际用途,并且可以找到它们的最佳值。 但是这种自动化需要付出巨大的代价:计算量大且费时。
您可能会像我们在这里那样等待几分钟才能完成。 但是,我们的数据集只有1500个样本,如果您同时结合了网格搜索和随机搜索,找到最佳参数将花费我们近一个小时的时间。 想象一下,您要等待那里的大型数据集需要多少时间。
那么,网格搜索和随机搜索是否可用于较小的数据集?当然可以! 对于大型数据集,您需要采用其他方法。 幸运的是,Scikit学习已经涵盖了“不同的方法”……。 我们会在后面文章中介绍HalvingGridSearchCV和HalvingRandomizedSearchCV。 敬请关注!
作者:Bex T
deephub翻译组
-
2、机器学习中的调参:随机搜索和网格搜索
2021-07-19 10:15:01机器学习中的调参前言1、随机搜索和网格搜索2、 遗传算法 前言 超参数调优是机器学习中的重要一环,拿随机森林算法而言,树的个数,数的深度,剪枝参数等等需要找到最优的参数组合,超参数较少时,我们可以采用for... -
模型调参之网格搜索与随机搜索
2021-05-17 11:22:01模型调参之网格搜索与随机搜索 网格搜索法(GridSearchCV) GridSearchCV:GridSearchCV可以拆分成GridSearch和CV两部分,即网格搜素和交叉验证。GridSearch系统地遍历多种参数组合,通过交叉验证确定最佳效果参数... -
引入群体发现和加入行为的随机搜索算法 随机搜索算法.pdf
2022-04-19 11:06:10引入群体发现和加入行为的随机搜索算法 随机搜索算法.pdf -
随机启发式搜索算法的性能分析 随机搜索算法.doc
2022-04-19 11:05:44随机启发式搜索算法的性能分析 随机搜索算法.doc -
港口泊位分配决策的随机束搜索算法 随机搜索算法.pdf
2022-04-19 11:05:05港口泊位分配决策的随机束搜索算法 随机搜索算法.pdf -
java随机生成二进制数-java–随机二进制搜索算法 随机搜索算法.pdf
2022-04-19 11:04:38java随机生成二进制数-java–随机二进制搜索算法 随机搜索算法.pdf -
贪心随机自适应搜索算法在软件测试中的应用 随机搜索算法.doc
2022-04-19 11:05:54贪心随机自适应搜索算法在软件测试中的应用 随机搜索算法.doc -
快速随机搜索树(RRT)算法
2018-09-11 10:42:35用matlab编写的RRT算法,代码简单,可以完美运行,对初学者有所帮助 -
超参数优化:随机搜索
2020-06-08 20:48:44文章目录随机搜索在机器学习和深度学习的使用1.项目简介2.机器学习案例2.1导入相关库2.2导入数据2.3拆分数据集2.4随机搜索2.5使用最优参数重新训练模型3.深度学习案例3.1导入相关库3.2导入数据3.3拆分数据集3.4构造... -
自适应随机搜索算法在河网数学模型糙率反演中的应用.pdf
2022-04-18 14:58:54自适应随机搜索算法在河网数学模型糙率反演中的应用 -
Grid SearchCV(网格搜索)与RandomizedSearchCV (随机搜索)
2020-08-12 01:35:53比如随机森林中决策树的个数,人工神经网络模型中隐藏层层数和每层的节点个数,正则项中常数大小等等,他们都需要事先指定。超参数选择不恰当,就会出现欠拟合或者过拟合的问题。而在选择超参数的时候,有两个途径,... -
随机搜索(Random Searching)算法
2019-01-08 12:12:23个人理解,随机搜索是一种在巨大数据规模下执行一个耗时上无法接受的程序的优化方法。 它可以用以对一个搜索算法施展优化的前提是: 1、数据规模大,精确的结果难以在一定时间计算出。 2、结果的些许的不精确能够... -
基于模拟分析技术和随机搜索算法的化工过程能量集成方法研究 随机搜索算法.pdf
2022-04-19 11:05:17基于模拟分析技术和随机搜索算法的化工过程能量集成方法研究 随机搜索算法.pdf -
基于随机分形搜索算法的方向过电流保护整定优化研究 随机搜索算法.pdf
2022-04-19 11:05:32基于随机分形搜索算法的方向过电流保护整定优化研究 随机搜索算法.pdf -
最小化随机形状的周长/平方(面积)比率:使用随机搜索。 结果是因果循环。-matlab开发
2021-06-01 13:43:37在随机搜索的迭代中,它每次搜索最小周长/平方(面积)。 在每次迭代中,代码尝试在当前位置附近的顶点的随机位置。 随机搜索区域呈指数收缩。 收缩率为 0.99。 使用了 1000 次迭代。 所以它是 0.99^1000=0.000043 ... -
【超参搜索】模型自动超参数优化方法:网格搜索、随机搜索、遗传算法
2021-05-12 16:36:23文章目录一、超参二、网格搜索 GridSearchCV三、随机搜索 RandomizedSearchCV四、自动超参搜索:遗传算法(GA) 一、超参 学习器模型中一般有两类参数,一类是可以从数据中学习估计得到,我们称为参数(Parameter)... -
随机搜索(Random Searching)算法概述
2018-10-08 12:29:44个人理解,随机搜索是一种在巨大数据规模下执行一个耗时上无法接受的程序的优化方法。 它可以用以对一个搜索算法施展优化的前提是: 1、数据规模大,精确的结果难以在一定时间计算出。 2、结果的些许的不精确能够... -
随机搜索 /爬山法/模拟退火/遗传算法
2019-07-02 21:02:40我们只需要在值域范围内生成足够多的可行解,然后分别计算每个可行解的代价,根据代价选择一个最小的可行解作为随机搜索的最优解即可。 # 搜索方法1: 随机搜索算法 # 函数会作1000次随机猜测,记录总代价最低的... -
随机搜索RandomizedSearchCV原理
2019-01-30 10:34:03文章目录 一、问题描述及代码示例 二、RandomSearchCV是如何"随机搜索"的 三、RandomSearch为什么会有效 四、其他 ——内容整理自RandomizedSearchCV源代码和论文Random Search for Hyper-Parameter Optimization,... -
模型调参 | 网格搜索(GridSearchCV)与随机搜索(RandomizedSearchCV)
2020-07-19 13:45:551.网格搜索 微调的一种方法是手工调整超参数,直到找到一个好的超参数组合。这么做的话会非常冗长,你也可能没有时间探索多种组合。 你应该使用 Scikit-Learn 的 GridSearchCV 来做这项搜索工作。你所需要做的是告 ...