1. 程式人生 > 其它 >偏差方差分解Python示例

偏差方差分解Python示例

技術標籤:機器學習人工智慧機器學習python演算法決策樹

偏差方差分解是在機器學習中眾所周知的歸因損失的工具。通常,針對特定問題的模型誤差與該模型的穩定性和該模型的擬合能力有關。我們稱該模型的擬合能力為偏差,並稱該模型的穩定性為方差。

偏差方差分解為確定模型效能不佳的根源提供了一種有效的方法,可以進一步有效地指導我們設計高質量的機器學習模型。

首先,我們應該認識到,偏差方差分解不是分解特定模型的單個誤差值,而是著重於根據不同的訓練資料分解一組機器學習模型的預期誤差。例如,我們可以使用不同的訓練資料子集構建十個不同的決策樹。然後我們可以計算該演算法的預期誤差。然而,一個單一的值不能表明我們的方法是由於較差的擬合能力還是不穩定而導致效能不佳。此時,偏差方差分解提供了確定性能不佳根源的強大工具。

介紹了偏差方差分解的基本思想。接下來,我們用一份程式碼片段說明此方法。首先,我們使用波士頓房價預測資料集作為示例資料,然後將原始資料按1:1的比例分為訓練集和測試集。

import numpy as np
from sklearn.datasets import load_boston
from sklearn.ensemble import BaggingRegressor, AdaBoostRegressor, GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.
model_selection import train_test_split from sklearn.svm import SVR from sklearn.tree import DecisionTreeRegressor X, y = load_boston(return_X_y=True) x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

之後,我們需要定義分解函式。如下式所示,誤差被分解為兩個項,即偏差和方差。關於偏差,我們將其定義為預期預測值與實際值之差。至於方差,我們將其定義為期望的預測值與每個預測值之間的差異的期望。從直覺上講,對於給定的誤差項,我們可以將其歸結為以下根源:模型無法準確描述潛在的生成過程(高偏差)或模型高度不穩定(高方差)。不言而喻的是,如果我們的模型具有很高的偏差,那麼我們將有很高的誤差。而就高方差而言,這種情況對應於模型對訓練資料高度敏感的情況。

E D [ { y ( x ; D ) − h ( x ) } 2 ] = { E D [ y ( x ; D ) ] − h ( x ) } 2 ⏟ (bias) 2 + E D [ { y ( x ; D ) − E D [ y ( x ; D ) ] } 2 ] ⏟ variance \begin{array}{l} \mathbb{E}_{\mathcal{D}}\left[\{y(\mathbf{x} ; \mathcal{D})-h(\mathbf{x})\}^{2}\right] =\underbrace{\left\{\mathbb{E}_{\mathcal{D}}[y(\mathbf{x} ; \mathcal{D})]-h(\mathbf{x})\right\}^{2}}_{\text {(bias) }^{2}}+\underbrace{\mathbb{E}_{\mathcal{D}}\left[\left\{y(\mathbf{x} ; \mathcal{D})-\mathbb{E}_{\mathcal{D}}[y(\mathbf{x} ; \mathcal{D})]\right\}^{2}\right]}_{\text {variance }} \end{array} ED[{y(x;D)h(x)}2]=(bias)2 {ED[y(x;D)]h(x)}2+variance ED[{y(x;D)ED[y(x;D)]}2]

需要指出的一個陷阱是,偏差和方差只是表示擬合能力和穩定性的兩個機器學習演算法指標。過去,人們認為偏差和方差與模型的複雜性高度相關。模型越複雜,方差越大。但是,近年來的研究表明,過度引數化的模型可能會同時導致較低的偏差和方差,這與普遍的看法背道而馳。總而言之,我們不能將模型的複雜性與偏差和方差視為大致等同。

def bias_variance_decomposition(regr):
    print(regr)
    y_pred = []
    for i in range(200):
        sample_indices = np.arange(x_train.shape[0])
        bootstrap_indices = np.random.choice(sample_indices,
                                             size=sample_indices.shape[0],
                                             replace=True)
        regr.fit(x_train[bootstrap_indices], y_train[bootstrap_indices])
        y_pred.append(regr.predict(x_test))
    y_pred = np.array(y_pred)
    bias = (np.mean(y_pred, axis=0) - y_test) ** 2
    variance = np.mean((y_pred - np.mean(y_pred, axis=0)) ** 2, axis=0)
    error = np.mean((y_pred - y_test) ** 2, axis=0)
    print(np.mean(error), np.mean(bias), np.mean(variance))

最後,我們將偏差方差分解應用於一些經典的機器學習演算法,並計劃尋找這些機器學習演算法的錯誤根源。我們選擇了兩種經典演算法,決策樹和線性迴歸。

首先,在計算了決策樹和線性迴歸的相關損失項之後。我們發現,儘管決策樹和線性迴歸中的預期誤差相似,但線性迴歸中的大多數誤差源自偏差,而決策樹中的大多數誤差源自方差。根據觀察結果,我們可以推測,通過減少方差可以減少決策樹的誤差。因此,我們嘗試使用整合方法來減少方差。隨後,我們發現這種方法確實是有效的。此外,從分解誤差的結果,我們發現減少的誤差可以歸因於方差的減少而不是偏差。

for regr in [LinearRegression(), DecisionTreeRegressor(), BaggingRegressor(DecisionTreeRegressor(),n_estimators=10)]:
    bias_variance_decomposition(regr)
LinearRegression()
27.14027220569435 25.308338535726147 1.8319336699682045
DecisionTreeRegressor()
27.753457114624506 15.438913619565204 12.314543495059288
BaggingRegressor(base_estimator=DecisionTreeRegressor())
19.92063215612648 16.614601149357714 3.3060310067687744

總之,在本文中,我們提供一個示例來說明機器學習領域中的偏差方差分解。我們發現,在類似的測試誤差的情況下,該錯誤的根源仍然可能存在很多可能性。因此,當我們需要提高演算法效能時,將誤差分解為偏差和方差是一種有效提高模型效能的明智方法。