1. 程式人生 > 其它 >整合學習入門及程式碼實現

整合學習入門及程式碼實現

bagging原理

bagging的思路是訓練k個獨立的基學習器,對於每個基學習器的結果進行結合(加權或者多數投票)來獲得一個強學習器。

boostrap

boost最早用於經濟學,為了研究大樣本中的特徵值,通過有放回的多次取樣研究樣本的特徵。

  1. 在原有的樣本中通過重抽樣抽取一定數量(比如100)的新樣本,重抽樣(Re-sample)的意思就是有放回的抽取,即一個數據有可以被重複抽取超過一次。
  2. 基於產生的新樣本,計算我們需要估計的統計量。
  3. 重複上述步驟n次(一般是n>1000次)。
  4. 最後,我們可以計算被估計量的均值和方差

其中,均值為n次取樣的平均值的均值,方差為n次取樣方差/樣本數-1

類似於概統中的樣本分佈估計總體

在此bagging使用了boostrap的思想,從m個樣本的訓練集中有放回地抽取m次,獲得第一個樣本集,用於訓練第一個基學習器,以此類推可獲得k個樣本集供基學習器訓練。由於訓練資料不同,我們獲得的基學習器會有很大的差異。同時保證了資料儘可能被使用到。

由於使用了boostrap進行訓練集的抽取,由於其抽泣方法的特性,會有約0.368的樣本未被抽到,此部分樣本稱為包外樣本(記作oobs),可用作測試集,此部分的測試結果稱為“包外估計”,為真實誤差的無偏估計。

obbs估計等價於k折交叉驗證,使用obbs作為測試集能大幅減少計算。

基分類器選取

bagging要求基分類器對樣本分佈敏感,常用的基分類器為決策樹、神經網路。KNN、線性分類器由於過於“穩定”不適合作為基分類器。

  • 樹的節點分裂隨機選擇特徵子集帶來隨機性,設定層數來控制泛化;
  • 神經網路通過調整神經元數量、連線方式、網路層數、初始權值引入隨機性;

基分類器聚合

bagging的另一個重要步驟是模型聚合,我們通常使用比較簡單的方法來聚合多個模型,對於分類問題我們採用投票的方式,將出現最多的一個作為分類結果,對於迴歸問題取m個的平均值。

RandomForest

樣本集N,共N個樣本;特徵集M,共M個特徵

(1)樣本集N中以boostrap方法抽取k個訓練集,每個訓練集樣本個數為n(第一個隨機,隨機有放回抽取),且分類誤差取決於:

  • 每棵樹的分類能力:單棵樹分類能力越強,分類誤差越小
  • 樹之間的相關性:樹之間的相關性越小,分類誤差越小

(2)對每個訓練集,抽取M個特徵中的m個特徵(隨機無放回抽取):

  • M較大時: m=\(log_2\)M或\(m=log_2M+1\)
  • M較小時,在M中取L個特徵(L<k),用[-1, +1]上的均勻分佈來構建權重對L個特徵進行線性組合,構成k個特徵;
  • m越小,相關性越小、分類能力越差;
  • 是隨機森林唯一的超參(在不考慮樹本身的超參前提下),可以使用obb error(out of bag error)進行選擇

(3)對某n個樣本的訓練集,m個特徵的特徵集進行決策樹訓練

  • 只訓練二叉樹:減少計算量;方便模型構建
  • 無需剪枝:滿足差異性;減少計算量

m = n時,RF等價於CART樹

m越小,模型方差減小,偏差增大,趨近欠擬合;m越大,模型方差增大,偏差減小,趨近過擬合

bagging方法的程式碼實現——用於鳶尾花資料集

匯入相關的庫

from sklearn import neighbors
from sklearn import datasets
from sklearn.ensemble import BaggingClassifier
from sklearn import tree
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

資料載入

載入鳶尾花資料集進行demo實現

iris = datasets.load_iris()
x_data = pd.DataFrame(iris.data, columns=iris.feature_names)
y_data = iris.target # 標籤 
x_train,x_test,y_train,y_test, = train_test_split(x_data,y_data)

為了方便視覺化,我們選取兩列

x_data = x_data[['sepal width (cm)','petal length (cm)']]

分割資料集

X_train,X_test,y_train,y_test = train_test_split(x_data,y_data,
test_size = 1/3,random_state = 0)

我們利用KNN進行bagging實驗

knn = neighbors.KNeighborsClassifier()
knn.fit(X_train,y_train)
plot(knn)
plt.scatter(x_data.iloc[:,0],x_data.iloc[:,1],c = y_data)
plt.show()

此時的得分為0.94

使用整合學習 引數(一個模型,有返回的抽樣一百次) ,就是說進行一百次的knn分類器去分類,然後進行投票最高的那個模型

bagging_knn = BaggingClassifier(knn,n_estimators=60)
# 輸入資料建立模型
bagging_knn.fit(X_train,y_train)
plot(bagging_knn)
# 樣本散點圖
plt.scatter(x_data.iloc[:,0],x_data.iloc[:,1],c = y_data)
plt.show()
bagging_knn.score(X_test,y_test)

將KNN模型bagging的分類結果

得到結果為0.96

繪圖函式放在這裡,這種畫法可以較好地視覺化分類問題。

def plot(model):
    # 獲取資料所在的範圍
    x_min,x_max = x_data.iloc[:,0].min() - 1,x_data.iloc[:,0].max()+1
    y_min,y_max = x_data.iloc[:,1].min() - 1,x_data.iloc[:,1].max()+1
    #生成網格矩陣
    xx,yy = np.meshgrid(np.arange(x_min,x_max,0.02),
                       np.arange(y_min,y_max,0.02))
    z = model.predict(np.c_[xx.ravel(),yy.ravel()]) # ravel與flatten類似,多維資料轉一維.flatten不會改變原始資料,ravel會改變原始資料
    z = z.reshape(xx.shape)
    # 登高線圖
    cs = plt.contourf(xx,yy,z)

參考文章

【機器學習】Bootstrap詳解 - 知乎 (zhihu.com)

(32條訊息) bagging實現_Cx330( ͡ _ ͡°)的部落格-CSDN部落格_bagging實現

很喜歡聽到一個老師說的“半年理論”,現在做出的努力,一般要在半年的沉澱之後,才能出結果,所以在遇到瓶頸之時,不妨再努力半年