一、簡介
貝葉斯優化用於機器學習調參由J. Snoek(2012)提出,主要思想是,給定優化的目標函數(廣義的函數,只需指定輸入和輸出即可,無需知道內部結構以及數學性質),通過不斷地添加樣本點來更新目標函數的後驗分佈(高斯過程,直到後驗分佈基本貼合於真實分佈。簡單的說,就是考慮了上一次參數的信息**,從而更好的調整當前的參數。
他與常規的網格搜索或者隨機搜索的區別是:
- 貝葉斯調參採用高斯過程,考慮之前的參數信息,不斷地更新先驗;網格搜索未考慮之前的參數信息
- 貝葉斯調參迭代次數少,速度快;網格搜索速度慢,參數多時易導致維度爆炸
- 貝葉斯調參針對非凸問題依然穩健;網格搜索針對非凸問題易得到局部優最
二、理論
介紹貝葉斯優化調參,必須要從兩個部分講起:
- 高斯過程,用以擬合優化目標函數
- 貝葉斯優化,包括了“開採”和“勘探”,用以花最少的代價找到最優值
2.1 高斯過程
高斯過程可以用於非線性迴歸、非線性分類、參數尋優等等。以往的建模需要對 p(y|X)p(y|X) 建模,當用於預測時,則是
p(yN+1|XN+1)p(yN+1|XN+1)
而高斯過程則, 還考慮了 yNyN 和 yN+1yN+1 之間的關係,即:
p(yN+1|XN+1,yN)p(yN+1|XN+1,yN)
高斯過程通過假設 YY 值服從聯合正態分佈,來考慮 yNyN 和 yN+1yN+1 之間的關係,因此需要給定參數包括:均值向量和協方差矩陣,即:
⎡⎣⎢⎢⎢y1y2...yn⎤⎦⎥⎥⎥∼N(0,⎡⎣⎢⎢⎢⎢k(x1,x1),k(x1,x2),...,k(x1,xn)k(x2,x1),k(x2,x2),...,k(x2,xn)...k(xn,x1),k(xn,x2),...,k(xn,xn)⎤⎦⎥⎥⎥⎥)[y1y2...yn]∼N(0,[k(x1,x1),k(x1,x2),...,k(x1,xn)k(x2,x1),k(x2,x2),...,k(x2,xn)...k(xn,x1),k(xn,x2),...,k(xn,xn)])
其中協方差矩陣又叫做 核矩陣, 記爲 KK ,僅和特徵 xx 有關,和 yy 無關。
高斯過程的思想是: 假設 YY 服從高維正態分佈(先驗),而根據訓練集可以得到最優的核矩陣 ,從而得到後驗以估計測試集 Y∗Y∗
我們有後驗:
p(y∗|y∼N(K∗K−1y, K∗∗−K∗K−1KT∗)p(y∗|y∼N(K∗K−1y, K∗∗−K∗K−1K∗T)
其中,K∗K∗ 爲訓練集的核向量,有如下關係:
[yy∗]∼N(0,[K,KT∗K∗,K∗∗])[yy∗]∼N(0,[K,K∗TK∗,K∗∗])
可以發現,在後驗公式中,只有均值和訓練集 YY 有關,方差則僅僅和核矩陣,也就是訓練集和測試集的 XX 有關,與訓練集 YY 無關
高斯過程的估計(訓練)方法
假設使用平方指數核(Squared Exponential Kernel),那麼有:
k(x1,x2)=σ2fexp(−(x1−x2)22l2)k(x1,x2)=σf2exp(−(x1−x2)22l2)
那麼所需要的確定的超參數 θ=[σ2f,l]θ=[σf2,l] ,由於 YY 服從多維正態分佈,因此似然函數爲:
L=logp(y|x,θ)=−12log|K|−12(y−μ)TK−1(y−μ)−n∗log(2π)/2L=logp(y|x,θ)=−12log|K|−12(y−μ)TK−1(y−μ)−n∗log(2π)/2
由於 KK 是由 θθ 決定的,所以通過梯度下降即可求出超參數 θθ ,而根據核矩陣的計算方式也可以進行預測。
上圖是一張高斯分佈擬合函數的示意圖,可以看到,它只需要九個點,就可以大致擬合出整個函數形狀(圖片來自:https://github.com/fmfn/BayesianOptimization)
2.2 貝葉斯優化理論
貝葉斯優化是一種逼近思想,當計算非常複雜、迭代次數較高時能起到很好的效果,多用於超參數確定
基本思想
是基於數據使用貝葉斯定理估計目標函數的後驗分佈,然後再根據分佈選擇下一個採樣的超參數組合。它充分利用了前一個採樣點的信息,其優化的工作方式是通過對目標函數形狀的學習,並找到使結果向全局最大提升的參數
高斯過程 用於在貝葉斯優化中對目標函數建模,得到其後驗分佈
通過高斯過程建模之後,我們嘗試抽樣進行樣本計算,而貝葉斯優化很容易在局部最優解上不斷採樣,這就涉及到了開發和探索之間的權衡。
- 開發 (exploitation): 根據後驗分佈,在最可能出現全局最優解的區域進行採樣, 開發高意味着均值高
- 探索 (exploration): 在還未取樣的區域獲取採樣點, 探索高意味着方差高
而如何高效的採樣,即開發和探索,我們需要用到 Acquisition Function, 它是用來尋找下一個 x 的函數。
Acquistion Function
一般形式的Acquisition Funtion是關於x的函數,映射到實數空間R,表示改點的目標函數值能夠比當前最優值大多少的概率,目前主要有以下幾種主流的Acquisition Function
POI(probability of improvement)
POI(X)=P(f(X)≥f(X+)+ξ)=Φ(μ(x)−f(X+)−ξσ(x))POI(X)=P(f(X)≥f(X+)+ξ)=Φ(μ(x)−f(X+)−ξσ(x))
其中, f(X)f(X) 爲X的目標函數值, f(X+)f(X+) 爲 到目前爲止 最優的X的目標函數值, μ(x),σ(x)μ(x),σ(x) 分別是高斯過程所得到的目標函數的均值和方差,即 f(X)f(X) 的後驗分佈。 ξξ 爲trade-off係數,如果沒有該係數,POI函數會傾向於取在 X+X+ 周圍的點,即傾向於exploit而不是explore,因此加入該項進行權衡。
而我們要做的,就是嘗試新的X,使得 POI(X)POI(X) 最大,則採取該XX (因爲f(X)f(X) 的計算代價非常大),通常我們使用 蒙特卡洛模擬 的方法進行。
詳細情況見下圖(圖片來自 Ref[5])
Expected Improvement
POI是一個概率函數,因此只考慮了f(x) 比 f(x+)f(x+) 大的概率,而EI則是一個期望函數,因此考慮了 f(x) 比 f(x+)f(x+) 大多少。我們通過下式獲取x
x=argmaxx E(max{0,ft+1(x)−f(X+)}|Dt)x=argmaxx E(max{0,ft+1(x)−f(X+)}|Dt)
其中 DtDt 爲前t個樣本,在正態分佈的假定下,最終得到:
EI(x)={(μ(x)−f(x+))Φ(Z)+σ(x)ϕ(Z),if σ(x)>00,if σ(x)=0EI(x)={(μ(x)−f(x+))Φ(Z)+σ(x)ϕ(Z),if σ(x)>00,if σ(x)=0
其中 Z=μ(x)−f(x+)σ(x)Z=μ(x)−f(x+)σ(x)
Confidence bound criteria
LCB(x)=μ(x)−κσ(x)LCB(x)=μ(x)−κσ(x)
UCB(x)=μ(x)+κσ(x)UCB(x)=μ(x)+κσ(x)
2.3 缺點和不足
- 高斯過程核矩陣不好選
三、例子
目前可以做貝葉斯優化的包非常多,光是python就有:
本文使用BayesianOptimization爲例,利用sklearn的隨機森林模型進行分類
安裝
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), # float
max_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.