您好,登錄后才能下訂單哦!
這篇文章主要講解了“算法模型自動超參數優化方法教程”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“算法模型自動超參數優化方法教程”吧!
學習器模型中一般有兩類參數,一類是可以從數據中學習估計得到,我們稱為參數(Parameter)。還有一類參數時無法從數據中估計,只能靠人的經驗進行設計指定,我們稱為超參數(Hyper parameter)。超參數是在開始學習過程之前設置值的參數。相反,其他參數的值通過訓練得出。
定義關于模型的更高層次的概念,如復雜性或學習能力 不能直接從標準模型培訓過程中的數據中學習,需要預先定義 可以通過設置不同的值,訓練不同的模型和選擇更好的測試值來決定 參數空間的搜索一般由以下幾個部分構成:
一個estimator(回歸器 or 分類器)
一個參數空間
一個搜索或采樣方法來獲得候選參數集合
一個交叉驗證機制
一個評分函數
在機器學習模型中,比如隨機森林中決策樹的個數,人工神經網絡模型中的隱藏層層數和每層的節點個數,正則項中常數大小等等,它們都需要事先指定。超參數選擇不恰當,就會出現欠擬合或者過擬合的問題。在Scikit-Learn中,超參數是在學習過程開始之前設置其值的參數。典型的例子包括支持向量機里的C、kernel、gamma等。
class sklearn.svm.SVC(*, C=1.0, kernel='rbf', degree=3, gamma='scale', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', break_ties=False, random_state=None)
使用過程中可以使用estimator.get_params() 獲得學習器模型的超參數列表和當前取值。
Sklearn提供了兩種通用的超參數優化方法:網格搜索與隨機搜索。
在機器學習里,通常來說我們不能將全部用于數據訓練模型,否則我們將沒有數據集對該模型進行驗證,從而評估我們的模型的預測效果。為了解決這一問題,有如下常用的方法:
這種是方法最簡單的,也是很容易就想到的。我們可以把整個數據集分成兩部分,一部分用于訓練,一部分用于驗證,這也就是我們經常提到的訓練集(training set)和測試集(test set)。
不過,這個簡單的方法存在兩個弊端:
最終模型與參數的選取將極大程度依賴于你對訓練集和測試集的劃分方法。在不同的劃分方法下,test MSE的變動是很大的,而且對應的最優degree也不一樣。所以如果我們的訓練集和測試集的劃分方法不夠好,很有可能無法選擇到最好的模型與參數。
該方法只用了部分數據進行模型的訓練。當用于模型訓練的數據量越大時,訓練出來的模型通常效果會越好。所以訓練集和測試集的劃分意味著我們無法充分利用我們手頭已有的數據,所以得到的模型效果也會受到一定的影響。
基于這樣的背景,有人就提出了Cross-Validation方法,也就是交叉驗證。
LOOCV即(Leave-one-out cross-validation)。像Test set approach一樣,LOOCV方法也包含將數據集分為訓練集和測試集這一步驟。但是不同的是,我們只用一個數據作為測試集,其他的數據都作為訓練集,并將此步驟重復N次(N為數據集的數據數量)。
假設我們現在有n個數據組成的數據集,那么LOOCV的方法就是每次取出一個數據作為測試集的唯一元素,而其他n-1個數據都作為訓練集用于訓練模型和調參。結果就是我們最終訓練了n個模型,每次都能得到一個MSE。而計算最終test MSE則就是將這n個MSE取平均。
比起test set approach,LOOCV有很多優點。首先它不受測試集合訓練集劃分方法的影響,因為每一個數據都單獨的做過測試集。同時,其用了n-1個數據訓練模型,也幾乎用到了所有的數據,保證了模型的bias更小。不過LOOCV的缺點也很明顯,那就是計算量過于大,是test set approach耗時的n-1倍。
K折交叉驗證,和LOOCV的不同在于,我們每次的測試集將不再只包含一個數據,而是多個,具體數目將根據K的選取決定。比如,如果K=5,那么我們利用五折交叉驗證的步驟就是:
將所有數據集分成5份
不重復地每次取其中一份做測試集,用其他四份做訓練集訓練模型,之后計算該模型在測試集上的MSE
將5次的MSE取平均作為最后而得到MSE
不難理解,其實LOOCV是一種特殊的K-fold Cross Validation(K=N)。最后K的選取是一個Bias和Variance的trade-off。K越大,每次投入的訓練集的數據越多,模型的Bias越小。但是K越大,又意味著每一次選取的訓練集之前的相關性越大(考慮最極端的例子,當k=N,也就是在LOOCV里,每次都訓練數據幾乎是一樣的)。而這種大相關性會導致最終的test error具有更大的Variance。一般K值選擇5或10。
我們在選擇超參數有兩個途徑:1)憑經驗;2)選擇不同大小的參數,帶入到模型中,挑選表現最好的參數。通過途徑2選擇超參數時,人力手動調節注意力成本太高,非常不值得。For循環或類似于for循環的方法受限于太過分明的層次,不夠簡潔與靈活,注意力成本高,易出錯。GridSearchCV 稱為網格搜索交叉驗證調參,它通過遍歷傳入的參數的所有排列組合,通過交叉驗證的方式,返回所有參數組合下的評價指標得分。
GridSearchCV聽起來很高大上,其實就是暴力搜索。注意的是,該方法在小數據集上很有用,數據集大了就不太適用了。數據量比較大的時候可以使用一個快速調優的方法——坐標下降。它其實是一種貪心算法:拿當前對模型影響最大的參數調優,直到最優化;再拿下一個影響最大的參數調優,如此下去,直到所有的參數調整完畢。這個方法的缺點就是可能會調到局部最優而不是全局最優,但是省時間省力。
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, refit=True, cv='warn', verbose=0, pre_dispatch='2*n_jobs', error_score='raise-deprecating', return_train_score='warn')
estimator:所使用的模型,傳入除需要確定最佳的參數之外的其他參數。模型都需要一個score方法,或傳入scoring參數。
param_grid:需要搜索調參的參數字典,參數值類型為字典(dict)或由字典組成的列表(list)。用于設置待評測參數和對應的參數值。
scoring:模型評價標準,默認None,這時需要使用score函數;或者如scoring=’roc_auc’,根據所選模型不同,評價準則不同。字符串(函數名),或是可調用對象,需要其函數簽名形如:scorer(estimator, X, y);如果是None,則使用estimator的誤差估計函數。下文表格中詳細指定了score可取的值和函數形式。
n_jobs:并行計算線程個數,1:默認值,可以設置為 -1(跟CPU核數一致),這樣可以充分使用機器的所有處理器。
refit:默認為True,程序將會以交叉驗證訓練集得到的最佳參數。即在搜索參數結束后,用最佳參數結果再次fit一遍全部數據集。
cv:交叉驗證參數,可接受的參數:
默認None,使用3折交叉驗證。
指定fold數量
CV splitter
yield訓練、測試數據的生成器。
verbose:日志冗長度
0:不輸出訓練過程
1:偶爾輸出
dayda'y'd1:對每個子模型都輸出
pre_dispatch:指定總共分發的并行任務數。當n_jobs大于1時,數據將在每個運行點進行復制,這可能導致內存問題,而設置pre_dispatch參數,則可以預先劃分總共的job數量,使數據最多被復制pre_dispatch次。
error_score:擬合中發生錯誤時分配的值,如果設置為’raise’則會引發錯誤。如果設置的是一個數字,則為引發FitFailedWarning的警告信息,默認值將在22版本其由原先的’raise’ 更改為np.nan。
return_train_score:如果“False”,cv_results_屬性將不包括訓練分數。
cv_results_:用來輸出cv結果的,可以是字典形式也可以是numpy形式,還可以轉換成DataFrame格式
best_estimator_:通過搜索參數得到的最好的估計器,當參數refit=False時該對象不可用
best_score_:float類型,輸出最好的成績
best_params_:通過網格搜索得到的score最好對應的參數
best_index_:對應于最佳候選參數設置的索引(cv_results_數組)。cv_results _ [‘params’] [search.best_index_]中的dict給出了最佳模型的參數設置,給出了最高的平均分數(best_score_)。
scorer_:評分函數
n_splits_:交叉驗證的數量
refit_time_:refit所用的時間,當參數refit=False時該對象不可用
decision_function(X):返回決策函數值(比如svm中的決策距離)
fit(X,y=None,groups=None,fit_params):在數據集上運行所有的參數組合
get_params(deep=True):返回估計器的參數
inverse_transform(Xt):Call inverse_transform on the estimator with the best found params.
predict(X):返回預測結果值(0/1)
predict_log_proba(X):Call predict_log_proba on the estimator with the best found parameters.
predict_proba(X):返回每個類別的概率值(有幾類就返回幾列值)
score(X, y=None):返回函數
set_params(**params):Set the parameters of this estimator.
transform(X):在X上使用訓練好的參數
from sklearn.model_selection import GridSearchCV from sklearn.svm import SVR from sklearn import datasets dataset = datasets.load_iris() X = dataset.data y = dataset.target grid = GridSearchCV( estimator=SVR(kernel='rbf'), param_grid={ 'C': [0.1, 1, 10, 100], 'epsilon': [0.0001, 0.001, 0.01, 0.1, 1, 10], 'gamma': [0.001, 0.01, 0.1, 1] }, cv=5, scoring='neg_mean_squared_error', verbose=0, n_jobs=-1) grid.fit(X, y) print(grid.best_score_) print(grid.best_params_)
我們在搜索超參數的時候,如果超參數個數較少(三四個或者更少),那么我們可以采用網格搜索,一種窮盡式的搜索方法。但是當超參數個數比較多的時候,我們仍然采用網格搜索,那么搜索所需時間將會指數級上升。所以有人就提出了隨機搜索的方法,隨機在超參數空間中搜索幾十幾百個點,其中就有可能有比較小的值。這種做法比上面稀疏化網格的做法快,而且實驗證明,隨機搜索法結果比稀疏網格法稍好。
RandomizedSearchCV使用方法和類GridSearchCV 很相似,但他不是嘗試所有可能的組合,而是通過選擇每一個超參數的一個隨機值的特定數量的隨機組合,這個方法有兩個優點:
相比于整體參數空間,可以選擇相對較少的參數組合數量。如果讓隨機搜索運行,它會探索每個超參數的不同的值 可以方便的通過設定搜索次數,控制超參數搜索的計算量。添加參數節點不會影響性能,不會降低效率。RandomizedSearchCV的使用方法其實是和GridSearchCV一致的,但它以隨機在參數空間中采樣的方式代替了GridSearchCV對于參數的網格搜索,在對于有連續變量的參數時,RandomizedSearchCV會將其當做一個分布進行采樣進行這是網格搜索做不到的,它的搜索能力取決于設定的n_iter參數。
class sklearn.model_selection.RandomizedSearchCV(estimator, param_distributions, *, n_iter=10, scoring=None, n_jobs=None , refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', random_state=None, error_score=nan, return_train_score=False)
param_distributions:參數分布,字典格式。將我們所傳入模型當中的參數組合為一個字典。其搜索策略如下:
對于搜索范圍是distribution的超參數,根據給定的distribution隨機采樣
對于搜索范圍是list的超參數,在給定的list中等概率采樣
n_iter:訓練300次,數值越大,獲得的參數精度越大,但是搜索時間越長 使用示例:
from scipy.stats import randint as sp_randint from sklearn.model_selection import RandomizedSearchCV from sklearn.datasets import load_digits from sklearn.ensemble import RandomForestClassifier # 載入數據 digits = load_digits() X, y = digits.data, digits.target # 建立一個分類器或者回歸器 clf = RandomForestClassifier(n_estimators=20) # 給定參數搜索范圍:list or distribution param_dist = {"max_depth": [3, None], # 給定list "max_features": sp_randint(1, 11), # 給定distribution "min_samples_split": sp_randint(2, 11), # 給定distribution "bootstrap": [True, False], # 給定list "criterion": ["gini", "entropy"]} # 給定list # 用RandomSearch+CV選取超參數 n_iter_search = 20 random_search = RandomizedSearchCV(clf, param_distributions=param_dist, n_iter=n_iter_search, cv=5, iid=False) random_search.fit(X, y) print(random_search.best_score_) print(random_search.best_params_)
貝葉斯優化用于機器學習調參由J. Snoek(2012)提出,主要思想是,給定優化的目標函數(廣義的函數,只需指定輸入和輸出即可,無需知道內部結構以及數學性質),通過不斷地添加樣本點來更新目標函數的后驗分布(高斯過程,直到后驗分布基本貼合于真實分布。簡單的說,就是考慮了上一次參數的信息,從而更好的調整當前的參數。
貝葉斯調參采用高斯過程,考慮之前的參數信息,不斷地更新先驗;網格搜索未考慮之前的參數信息
貝葉斯調參迭代次數少,速度快;網格搜索速度慢,參數多時易導致維度爆炸
貝葉斯調參針對非凸問題依然穩健;網格搜索針對非凸問題易得到局部最優
貝葉斯優化提供了一個優雅的框架來盡可能少的步驟中找到全局最小值。
讓我們構造一個函數c(x)或者一個接收輸入x的模型,如下圖所示為c(x)的形狀。當然,優化器并不知道該函數,稱之為“目標函數”。
貝葉斯優化通過代理優化的方式來完成任務。代理函數通過采樣點模擬構造(見下圖)。
根據代理函數,我們大致可以確定哪些點是可能的最小值。然后再這些點附近做更多的采樣,并隨之更新代理函數。
每一次迭代,我們都會繼續觀察當前的代用函數,通過采樣了解更多感興趣的區域,并更新函數。需要注意的是,代用函數在數學上的表達方式將大大降低評估成本。經過一定的迭代次數后,我們注定要到達一個全局最小值,除非函數的形狀非常詭異。
讓我們仔細看看代用函數,通常用高斯過程來表示,它可以被認為是擲骰子,返回與給定數據點(如sin、log)擬合的函數,而不是1到6的數字。這個過程會返回幾個函數,這些函數都附有概率。為什么用高斯過程,而不是其他的曲線擬合方法來模擬代用函數,有一個很好的理由:它是貝葉斯性質的。代用函數–表示為概率分布,即先驗–被更新為 “獲取函數”。這個函數負責在勘探和開發的權衡中提出新的測試點。
“開發”力求在代用模型預測的目標好的地方采樣。這就是利用已知的有希望的點。但是,如果我們已經對某一區域進行了足夠的探索,那么不斷地利用已知的信息就不會有什么收獲。
“探索”力求在不確定性較高的地點進行采樣。這就確保了空間的任何主要區域都不會未被探索–全局最小值可能恰好就在那里。
一個鼓勵過多的開發和過少探索的獲取函數將導致模型只停留在它首先發現的最小值(通常是局部的–“只去有光的地方”)。一個鼓勵相反的獲取函數將不會首先停留在一個最小值,本地或全球。在微妙的平衡中產生良好的結果。acquisition 函數,我們將其表示為a(x),必須同時考慮開發和探索。常見的獲取函數包括預期改進和最大改進概率,所有這些函數都是在給定先驗信息(高斯過程)的情況下,衡量特定投入在未來可能得到回報的概率。
鴻蒙官方戰略合作共建——HarmonyOS技術社區
初始化一個高斯過程 “代用函數 “的先驗分布。
選擇幾個數據點x,使在當前先驗分布上運行的獲取函數a(x)最大化。
評估目標成本函數c(x)中的數據點x,得到結果,y。
用新的數據更新高斯過程先驗分布,以產生一個后驗(它將成為下一步的先驗)。
重復步驟2-5進行多次迭代。
解釋當前的高斯過程分布(這是非常便宜的),以找到全局最小值。
代用優化利用代用函數或近似函數通過抽樣來估計目標函數。
貝葉斯優化將代用優化置于概率框架中,將代用函數表示為概率分布,可以根據新的信息進行更新。
獲取函數用于評估在當前已知的先驗條件下,探索空間中某一點會產生 “好 “收益的概率,平衡探索與開發
主要在目標函數評估成本很高的時候使用貝葉斯優化,常用于超參數調整。
Hyperopt是一個強大的Python庫,用于超參數優化,由jamesbergstra開發。Hyperopt使用貝葉斯優化的形式進行參數調整,允許你為給定模型獲得最佳參數。它可以在大范圍內優化具有數百個參數的模型。
hyperopt有不同的函數來指定輸入參數的范圍,這些是隨機搜索空間。選擇最常用的搜索選項:
choice(label, options)-這可用于分類參數,它返回其中一個選項,它應該是一個列表或元組。示例:hp.choice(“criterion”,[“gini”,”entropy”,])
randint(label, upper)-可用于整數參數,它返回范圍(0,upper)內的隨機整數。示例:hp.randint(“max_features”,50)
uniform(label, low, high)-它返回一個介于low和high之間的值。示例:hp.uniform(“max_leaf_nodes”,1,10)
你可以使用的其他選項包括:
normal(label, mu, sigma)-這將返回一個實際值,該值服從均值為mu和標準差為sigma的正態分布
qnormal(label, mu, sigma, q)-返回一個類似round(normal(mu, sigma) / q) * q的值
lognormal(label, mu, sigma)-返回exp(normal(mu, sigma))
qlognormal(label, mu, sigma, q) -返回一個類似round(exp(normal(mu, sigma)) / q) * q的值
這是一個最小化函數,它從搜索空間接收超參數值作為輸入并返回損失。這意味著在優化過程中,我們使用選定的超參數值訓練模型并預測目標特征,然后評估預測誤差并將其返回給優化器。優化器將決定要檢查哪些值并再次迭代。你將在一個實際例子中學習如何創建一個目標函數。
fmin函數是對不同的算法集及其超參數進行迭代,然后使目標函數最小化的優化函數。fmin有5個輸入是:
最小化的目標函數
定義的搜索空間
使用的搜索算法有隨機搜索、TPE(Tree-Parzen估計器)和自適應TPE。注意:rand.suggest以及hyperopt.tpe.suggest為超參數空間的順序搜索提供邏輯。
最大評估數
trials對象(可選)
Trials對象用于保存所有超參數、損失和其他信息,這意味著你可以在運行優化后訪問它們。此外,trials 可以幫助你保存和加載重要信息,然后繼續優化過程。
在理解了Hyperopt的重要特性之后,下面將介紹Hyperopt的使用方法。
初始化要搜索的空間
定義目標函數
選擇要使用的搜索算法
運行hyperopt函數
分析測試對象中存儲的評估輸出
from sklearn import datasets from hyperopt import fmin, tpe, hp, STATUS_OK, Trials from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import cross_val_score iris = datasets.load_iris() X = iris.data y = iris.target def hyperopt_train_test(params): clf = KNeighborsClassifier(**params) return cross_val_score(clf, X, y).mean() # 定義參數空間 space_knn = { 'n_neighbors': hp.choice('n_neighbors', range(1, 100)) } # 定義最小化函數(目標函數) def fn_knn(params): acc = hyperopt_train_test(params) return {'loss': -acc, 'status': STATUS_OK} # hyperopt最小化函數,所以在acc中添加了負號 # 實例化Trial 對象,對模型進行微調,然后用其超參數值打印出最佳損失 trials = Trials() best = fmin(fn_knn, space_knn, algo=tpe.suggest, max_evals=100, trials=trials) print("Best: {}".format(best)) print(trials.results) # 搜索期間“objective”返回的詞典列表。
隨機搜索(hyperopt.rand.suggest)
模擬退火(hyperopt.anneal.suggest)
TPE算法(tpe.suggest,算法全稱為Tree-structured Parzen Estimator Approach)
除了Hyperopt外,貝葉斯優化方法的Python包還有:
https://github.com/optuna/optuna
https://github.com/fmfn/BayesianOptimization
https://github.com/HIPS/Spearmint
遺傳算法試圖將自然選擇機制應用于機器學習環境。它受到達爾文自然選擇過程的啟發,因此通常也稱為進化算法。假設我們創建了具有一些預定義超參數的N個機器學習模型。然后,我們可以計算每個模型的準確性,并決定只保留一半模型(性能最好的模型)。現在,我們可以生成具有與最佳模型相似的超參數的后代,以便再次獲得N個模型的種群。在這一點上,我們可以再次計算每個模型的準確性,并在定義的世代中重復該循環。這樣,只有最佳模型才能在流程結束時生存下來。
TPOT是一種基于遺傳算法優化機器學習管道(pipeline)的Python自動機器學習工具。簡單來說,就是TPOT可以智能地探索數千個可能的pipeline,為數據集找到最好的pipeline,從而實現機器學習中最乏味的部分。
更重要地是,一旦TPOT完成搜索,TPOT同時也提供了Python代碼。通過這個代碼,我們可以具體地知道TPOT獲得最優性能時的具體pipeline的內容,這對于后續修改是十分方便的!
TPOT是在sklearn的基礎之上做的封裝庫。其主要封裝了sklearn的模型相關模塊、processesing模塊和feature_selection模塊,所以TPOT的主要功能是集中在使用pipeline的方式完成模型的數據預處理、特征選擇和模型選擇方面。此外,我們還發現了TPOT已經對xgboost進行了支持。
雖然TPOT使用遺傳算法代替了傳統的網格搜索進行超參數選擇,但由于默認初始值的隨機性,在少量的進化(迭代)次數下,TPOT最終選擇的模型往往并不相同。
計算效率問題。作者在代碼中寫道:進化(迭代)次數和每一代保留的個體數量值越多,最終得模型得分會越高。但這同樣也會導致耗時很長。如果使用相當復雜的數據集或運行TPOT短時間,不同的TPOT運行可能會導致不同的流水線推薦。TPOT的優化算法本質上是隨機的,這意味著它使用隨機性(部分地)來搜索可能的流水線空間。當兩個TPOT運行推薦不同的管道時,這意味著TPOT運行由于時間不夠而不收斂,或者多個管道在數據集上執行的次數大致相同。這實際上是一個優于固定網格搜索技術的優點:TPOT是一個助手,它通過探索您可能從未考慮過的流水線配置來提供解決如何解決特定機器學習問題的想法,然后將微調留給更受約束的參數調整技術,例如網格搜索。
使用TPOT(版本0.9.5)開發模型需要把握以下幾點:
在使用TPOT進行建模前需要對數據進行必要的清洗和特征工程操作。
TPOT目前只能做有監督學習。
TPOT目前支持的分類器主要有貝葉斯、決策樹、集成樹、SVM、KNN、線性模型、xgboost。
TPOT目前支持的回歸器主要有決策樹、集成樹、線性模型、xgboost。
TPOT會對輸入的數據做進一步處理操作,例如二值化、聚類、降維、標準化、正則化、獨熱編碼操作等。
根據模型效果,TPOT會對輸入特征做特征選擇操作,包括基于樹模型、基于方差、基于F-值的百分比。
可以通過export()方法把訓練過程導出為形式為sklearn pipeline的.py文件
示例代碼:
from tpot import TPOTClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split iris = load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) tpot = TPOTClassifier(generations=5, population_size=50, verbosity=2, n_jobs=-1) tpot.fit(X_train, y_train) print(tpot.score(X_test, y_test))
TPOT的主要參數:
generations – 確定創建子代(新個體)的迭代次數
population_size – 創建個體的初始數量(這些用于創建后代)
offspring_size – 每一代所需創造的新個體數
mutation_rate – 出現屬性值隨機更改的概率(包括新參數的方法,在初始群體中可能不可用)
crossover_rate –用于創造后代的個體所占的百分比
使用這個迭代過程,我們選出最佳配置。準備遺傳算法的結果一般取決于初始狀態。因此,它隨機產生的初始種群影響輸出,重新運行相同的設置可能會輸出不同的結果。
感謝各位的閱讀,以上就是“算法模型自動超參數優化方法教程”的內容了,經過本文的學習后,相信大家對算法模型自動超參數優化方法教程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。