天天看點

在envi做随機森林_smac——基于随機森林的貝葉斯優化

個人感覺,相對于基于高斯過程的貝葉斯優化,基于随機森林的貝葉斯優化要好了解的多。

在envi做随機森林_smac——基于随機森林的貝葉斯優化
在envi做随機森林_smac——基于随機森林的貝葉斯優化
在envi做随機森林_smac——基于随機森林的貝葉斯優化

skopt裡面實作了基于随機森林的貝葉斯優化,是以這裡直接看看源碼:

在envi做随機森林_smac——基于随機森林的貝葉斯優化

可以看到,其代理模型就是直接使用sklearn中的回歸器;

基于随機森林的貝葉斯優化原理上要好了解的多,比如我們對xgboost進行調參,随機初始化了10組超參數,然後交叉驗證得到了10個auc,我們直接使用随機森林對其進行拟合,比如我們令随機森林的trees為100顆樹,然後我們訓練完畢之後會得到100棵獨立的tree,每一個tree都針對超參數和auc進行了拟合,那麼所有tree的預測結構就構成了一個關于f(x)(也就是超參數組合w到評價名額y的映射關系)的經驗近似高斯過程分布,這個分布的均值為所有tree的預測結果的均值,這個分布的方差為所有tree的葉子節點的impurity的方差。skopt中的實作是:

(impurity的概念下文補充)
在envi做随機森林_smac——基于随機森林的貝葉斯優化

做了一些微小的限制,不過整體思路是一樣的。

下面做個小測試看看具體是怎麼計算的:

from sklearn.ensemble import RandomForestRegressor as rf
from sklearn.datasets import load_boston
X=load_boston().data
y=load_boston().target
clf=rf(n_estimators = 5)
clf.fit(X,y)
           
在envi做随機森林_smac——基于随機森林的貝葉斯優化
trees=clf.estimators_
trees
           
在envi做随機森林_smac——基于随機森林的貝葉斯優化
tree=trees[0]
var_tree = tree.tree_.impurity[tree.apply(X)]
var_tree
           

這裡我們以第一棵樹為例,tree.apply是

tree=trees[0]
var_tree = tree.tree_.impurity[tree.apply(X)]
var_tree
           

tree.apply傳回樣本X在tree上的葉子節點的索引值,

impurity直接傳回對應的葉子節點上的評價準則——the value of criterion,因為這裡用的是回歸樹,是以傳回的是葉子節點上各個标簽和其均值的差的平方的求和

。不了解的可以自己做一個簡單的計算:

在envi做随機森林_smac——基于随機森林的貝葉斯優化
在envi做随機森林_smac——基于随機森林的貝葉斯優化

這裡我們就得到了506個樣本對應的葉子節點的impurity,

std = np.zeros(len(X))

    for tree in trees:
        var_tree = tree.tree_.impurity[tree.apply(X)]

        # This rounding off is done in accordance with the
        # adjustment done in section 4.3.3
        # of http://arxiv.org/pdf/1211.0906v2.pdf to account
        # for cases such as leaves with 1 sample in which there
        # is zero variance.
        var_tree[var_tree < min_variance] = min_variance
        mean_tree = tree.predict(X)
        std += var_tree + mean_tree ** 2
           

然後我們的mean_tree是單個tree預測的最終結果

在envi做随機森林_smac——基于随機森林的貝葉斯優化

最終:

std /= len(trees)
std -= predictions ** 2.0
std[std < 0.0] = 0.0
std = std ** 0.5
           

可以看到,還是假設超參數組合w和評價名額y之間服從某種高斯分布,隻不過這裡不是使用高斯過程來對超參數組合w和評價名額y進行模組化,而是使用随機森林來近似的建立一個經驗高斯模型,

具體的做法就是這個多元高斯分布的均值向量就是所有trees的預測結果的均值(平均計算在rf内部實作),而這個分布的協方差矩陣上的數值對應的就是每一顆tree對所有樣本的impurity的

std /= len(trees)
std -= predictions ** 2.0
std[std < 0.0] = 0.0 #避免标準差小于0的尴尬局面
std = std ** 0.5
           

通過這種類似于直接求标準差的形式(這裡我也很疑惑為什麼不直接計算标準差還要多一個

在envi做随機森林_smac——基于随機森林的貝葉斯優化

的步驟)。查閱了論文:

在envi做随機森林_smac——基于随機森林的貝葉斯優化
在envi做随機森林_smac——基于随機森林的貝葉斯優化

這是個很有意思的思路,原作者通過這種方式定義了回歸問題中,rf對每一個樣本的預測的期望和方差,方差可以了解為回歸問題中樣本的預測置信度,越高則樣本的預測越不穩定,這其實和前面的高斯過程的思路類似,最終都是得到關于n組超參數的多元高斯分布,然後當一組新的超參數誕生之後,通過高斯分布的邊緣機率分布公式直接得到新的超參數組服從的單高斯分布,并且将其均值作為其對應的模型效果的預測。上面公式的意思就是,

以單個樣本為例,假設有一個樣本A進入rf,假設樹有100棵,則我們去計算每一棵tree對A的預測結果,即ub,這裡涉及到回歸決策樹的基本的預測過程,假設某個葉子節點有10個樣本,每個樣本的真實的回歸标簽是不同的,而tree的預測則是直接對這10個樣本的回歸标簽取平均,是以,這裡的
在envi做随機森林_smac——基于随機森林的貝葉斯優化
實際上就是這10個樣本的真實标簽的标準差,其平方就是方差了。而整個rf對樣本A的預測均值就是每個樹的預測結果的平均,而方差則是每一棵樹的均值和方差之和的平均再減去整體預測均值的平方,通過這種方式來計算出樣本A的預測方差(也就是我們上面使用的api tree.impurity的核心實作原理)

簡單來說,仍舊是假設每一個超參數組合和y都服從高斯分布,所有超參數組合和y服從多元高斯分布,用rf去近似建立拟合這個多元高斯分布,進而解決問題,而标準差是作為預測的置信度用于後續的ac函數的計算裡的。