python自带超参调优包
一、bayesian-optimization
安裝
pip install bayesian-optimization前期準備
from sklearn.datasets import make_classification from sklearn.ensemble import RandomForestClassifier from sklearn.cross_validation import cross_val_score from bayes_opt import BayesianOptimization# 產生隨機分類數據集,10個特征, 2個類別 x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)我們先看看不調參的結果:
rf = RandomForestClassifier() print(np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')))>>> 0.965162可以看到,不調參的話模型20此交叉驗證AUC均值是0.965162,算是一個不錯的模型,那么如果用bayes調參結果會怎么樣呢
bayes調參初探
我們先定義一個目標函數,里面放入我們希望優化的函數。比如此時,函數輸入為隨機森林的所有參數,輸出為模型交叉驗證5次的AUC均值,作為我們的目標函數。因為bayes_opt庫只支持最大值,所以最后的輸出如果是越小越好,那么需要在前面加上負號,以轉為最大值。由于bayes優化只能優化連續超參數,因此要加上int()轉為離散超參數。
def rf_cv(n_estimators, min_samples_split, max_features, max_depth):val = cross_val_score(RandomForestClassifier(n_estimators=int(n_estimators),min_samples_split=int(min_samples_split),max_features=min(max_features, 0.999), # floatmax_depth=int(max_depth),random_state=2),x, y, scoring='roc_auc', cv=5).mean()return val然后我們就可以實例化一個bayes優化對象了:
rf_bo = BayesianOptimization(rf_cv,{'n_estimators': (10, 250),'min_samples_split': (2, 25),'max_features': (0.1, 0.999),'max_depth': (5, 15)})里面的第一個參數是我們的優化目標函數,第二個參數是我們所需要輸入的超參數名稱,以及其范圍。超參數名稱必須和目標函數的輸入名稱一一對應。
完成上面兩步之后,我們就可以運行bayes優化了!
rf_bo.maximize()完成的時候會不斷地輸出結果,如下圖所示:
等到程序結束,我們可以查看當前最優的參數和結果:
rf_bo.res['max']>>> {'max_params': {'max_depth': 5.819908283575526,'max_features': 0.4951745603509127,'min_samples_split': 2.3110014720414958,'n_estimators': 249.73529231990733},'max_val': 0.9774079407940794}bayes調參進階
上面bayes算法得到的參數并不一定最優,當然我們會遇到一種情況,就是我們已經知道有一組或是幾組參數是非常好的了,我們想知道其附近有沒有更好的。這個操作相當于上文bayes優化中的Explore操作,而bayes_opt庫給了我們實現此方法的函數:
rf_bo.explore({'n_estimators': [10, 100, 200],'min_samples_split': [2, 10, 20],'max_features': [0.1, 0.5, 0.9],'max_depth': [5, 10, 15]} )這里我們添加了三組較優的超參數,讓其在該參數基礎上進行explore,可能會得到更好的結果。
同時,我們還可以修改高斯過程的參數,高斯過程主要參數是核函數(kernel),還有其他參數可以參考sklearn.gaussianprocess
gp_param={'kernel':None} rf_bo.maximize(**gp_param)最終我們的到參數如下:
{'max_params': {'max_depth': 5.819908283575526,'max_features': 0.4951745603509127,'min_samples_split': 2.3110014720414958,'n_estimators': 249.73529231990733},'max_val': 0.9774079407940794}運行交叉驗證測試一下:
rf = RandomForestClassifier(max_depth=6, max_features=0.39517, min_samples_split=2, n_estimators=250) np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')) >>> 0.9754953得到最終結果是0.9755,比之前的0.9652提高了約0.01,做過kaggle的朋友都懂,這在后期已經是非常大的提高了!到后面想提高0.001都極其困難,因此bayes優化真的非常強大!
結束!
Reference
- [1] J. Snoek, H. Larochelle, and R. P. Adams, “Practical bayesianoptimization of machine learning algorithms,” in Advances in neural information processing systems, 2012, pp. 2951–2959.
- [2] 高斯過程:http://www.gaussianprocess.org/gpml/
- [3] 高斯過程:https://www.zhihu.com/question/46631426?sort=created
- [4] 高斯過程:http://www.360doc.com/content/17/0810/05/43535834_678049865.shtml
- [5] Brochu E, Cora V M, De Freitas N. A tutorial on Bayesian optimization of expensive cost functions, with application to active user modeling and hierarchical reinforcement learning[J]. arXiv preprint arXiv:1012.2599, 2010.
?二、Hyperopt
? 安裝:
Hyperopt提供了一個優化接口,這個接口接受一個評估函數和參數空間,能計算出參數空間內的一個點的損失函數值。用戶還要指定空間內參數的分布情況。?
Hyheropt四個重要的因素:指定需要最小化的函數,搜索的空間,采樣的數據集(trails database)(可選),搜索的算法(可選)。?
首先,定義一個目標函數,接受一個變量,計算后返回一個函數的損失值,比如要最小化函數q(x,y) = x**2 + y**2:
?
然后,定義一個參數空間,比如x在0-1區間內取值,y是實數,所以
第三,指定搜索的算法,算法也就是hyperopt的fmin函數的algo參數的取值。當前支持的算法由隨機搜索(對應是hyperopt.rand.suggest),模擬退火(對應是hyperopt.anneal.suggest),TPE算法。舉個栗子:
?
?搜索算法本身也有內置的參數決定如何去優化目標函數,我們可以指定搜索算法的參數,比如針對TPE,指定jobs:
?
關于參數空間的設置,比如優化函數q,輸入fmin(q,space=hp.uniform(‘a’,0,1)).hp.uniform函數的第一個參數是標簽,每個超參數在參數空間內必須具有獨一無二的標簽。hp.uniform指定了參數的分布。其他的參數分布比如?
hp.choice返回一個選項,選項可以是list或者tuple.options可以是嵌套的表達式,用于組成條件參數。?
hp.pchoice(label,p_options)以一定的概率返回一個p_options的一個選項。這個選項使得函數在搜索過程中對每個選項的可能性不均勻。?
hp.uniform(label,low,high)參數在low和high之間均勻分布。?
hp.quniform(label,low,high,q),參數的取值是round(uniform(low,high)/q)*q,適用于那些離散的取值。?
hp.loguniform(label,low,high)繪制exp(uniform(low,high)),變量的取值范圍是[exp(low),exp(high)]?
hp.randint(label,upper) 返回一個在[0,upper)前閉后開的區間內的隨機整數。?
搜索空間可以含有list和dictionary.
?
使用sample函數從參數空間內采樣:
?
在參數空間內使用函數:
?
—————–這是一條有點短的昏割線———————————–
在blog上發現了一段使用感知器判別鳶尾花數據的代碼,使用的學習率是0.1,迭代40次得到了一個測試集上正確率為82%的結果。使用hyperopt優化參數,將正確率提升到了91%。
from sklearn import datasets import numpy as np from sklearn.cross_validation import train_test_split from sklearn.metrics import accuracy_score iris = datasets.load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)from sklearn.preprocessing import StandardScaler sc = StandardScaler() sc.fit(X_train) X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test)from sklearn.linear_model import Perceptron ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0) ppn.fit(X_train_std, y_train)y_pred = ppn.predict(X_test_std) print accuracy_score(y_test, y_pred)def percept(args):global X_train_std,y_train,y_testppn = Perceptron(n_iter=int(args["n_iter"]),eta0=args["eta"]*0.01,random_state=0)ppn.fit(X_train_std, y_train)y_pred = ppn.predict(X_test_std)return -accuracy_score(y_test, y_pred)from hyperopt import fmin,tpe,hp,partial space = {"n_iter":hp.choice("n_iter",range(30,50)),"eta":hp.uniform("eta",0.05,0.5)} algo = partial(tpe.suggest,n_startup_jobs=10) best = fmin(percept,space,algo = algo,max_evals=100) print best print percept(best) #0.822222222222 #{'n_iter': 14, 'eta': 0.12877033763511717} #-0.911111111111xgboost具有很多的參數,把xgboost的代碼寫成一個函數,然后傳入fmin中進行參數優化,將交叉驗證的auc作為優化目標。auc越大越好,由于fmin是求最小值,因此求-auc的最小值。所用的數據集是202列的數據集,第一列樣本id,最后一列是label,中間200列是屬性。
?
?
總結
以上是生活随笔為你收集整理的python自带超参调优包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过正则表达式分句提取中文内容
- 下一篇: centos7.6成功安装nerdtre