一份完備的集成學習手冊!(附Python代碼)

引言:

試想一下,當你想買一輛新車時,你會直接走到第一家汽車商店,並根據經銷商的建議購買一輛車嗎?這顯然不太可能。

你可能會瀏覽一些門戶網站,在那裡查看人們對於不同車型的比較和評論,瞭解它們的特點和價格。你也可能會向朋友和同事徵求一下他們的意見。簡而言之,你不會直接給出一個結論,而是會綜合考慮其他人的意見再做出決定。

機器學習中的集成模型(Ensemble Models)採用了類似的思想。集成模型結合多個模型的決策,以提高整體性能。這可以通過多種方式來實現,本文將一一介紹。

本文的目的是介紹集成學習的概念,並理解使用這種技術的算法。為了加強您對不同算法的理解,我們將對實際問題的案例使用 Python 來解釋這些高級算法。

注意:弄懂本文需要對機器學習算法有一個基本的瞭解,我建議你通過這篇文章來熟悉一些基本概念:

一份機器學習的自白書

目錄:

  1. 集成學習簡介
  2. 基本的集成技術
  3. 2.1 最大化
  4. 2.2 平均化
  5. 2.3 加權平均

3. 高級集成技術

3.1 Stacking

3.2 Blending

3.3 Bagging

3.4 Boosting

4. 基於 Bagging 和 Boosting 的算法

4.1 Bagging meta-estimator

4.2 Random Forest

4.3 AdaBoost

4.4 GBM

4.5 XGB

4.6 Light GBM

4.7 CatBoost

1. 集成學習簡介

讓我們通過一個例子來理解集成學習的概念。假設你是一個電影導演,你對一個非常重要和有趣的話題都創作了一部電影短片。現在,你想在公映之前對這部電影進行初步的反饋(打分)。該怎麼做呢?

A: 你可以諮詢一個好朋友來對電影進行打分

這種方法完全有可能會出現一種情況,就是電影很糟糕,但是你的好朋友不忍心傷你的心,因此不會打一星。

B: 你可以諮詢 5 位同事來對電影進行打分

這種方法要好些,可以為你的電影提供較誠實的評價。但問題依然存在,這 5 個人可能不是該電影主題的專家,雖然他們可能知道攝影、鏡頭、音頻等一些電影知識。

C: 你可以諮詢 50 個人來對電影進行打分

其中一些可能是你的朋友,有些可能是你的同事,有些甚至可能是陌生人。

這種打分方法,反應會更加普遍和多樣化,因為打分的人更多更多樣了。事實證明,相比 A 和 B,C 更加科學。

通過這些例子,你可以推斷出相比一個人的意見,綜合多個人的意見可能做出更好的決定。這個例子對於多模型和單模型的比較也是成立的。機器學習中的這種多樣化是通過一種稱為集成學習的技術實現的。

現在,你已經掌握了集成學習的要點。接下來讓我們看看集成學習中的各種技術及其實現方法。

2. 基本的集成技術

在本節中,我們將介紹一些簡單但功能強大的技術:

  • 最大化
  • 平均化
  • 加權平均

2.1 最大化

最大化通常用於分類問題。這種技術,所有模型都對該實例進行預測,每個模型的預測都可以看成是一次投票。獲得投票數最多的那一類別就是最終的預測結果。

例如剛才的例子,5 個同事給你的電影打分,其中 3 人打了 5 星,2 人打了 4 星。則根據最大化原則,打 5 星的人數更多,最終判斷電影評分為 5 星。

示例代碼:

model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
pred1=model1.predict(x_test)
pred2=model2.predict(x_test)
pred3=model3.predict(x_test)
final_pred = np.array([])
for i in range(0,len(x_test)):
final_pred = np.append(final_pred, mode([pred1[i], pred2[i], pred3[i]]))

或者,你也可以使用 sklearn 庫中的 VotingClassifier:

from sklearn.ensemble import VotingClassifier
model1 = LogisticRegression(random_state=1)
model2 = tree.DecisionTreeClassifier(random_state=1)
model = VotingClassifier(estimators=[('lr', model1), ('dt', model2)], voting='hard')
model.fit(x_train,y_train)
model.score(x_test,y_test)

2.2 平均化

類似於最大化投票方法,平均化的做法就是對所有的預測結果求平均值,平均值作為最後的預測結果。平均化可以應用於迴歸問題的預測或者在分類問題中計算概率值。

還是剛才的例子,5 個同事給你的電影打分,其中 3 人打了 5 星,2 人打了 4 星。則根據平均化原則,計算最終打分為:

(5 + 5 + 5 + 4 + 4) / 5 = 4.6

示例代碼:

model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
pred1=model1.predict_proba(x_test)
pred2=model2.predict_proba(x_test)
pred3=model3.predict_proba(x_test)
finalpred=(pred1+pred2+pred3)/3

2.3 加權平均

這是平均化方法的一個擴展,所有的模型被賦予不同的權重(定義為在預測中不同模型所佔的重要性)。例如,如果你的兩個同事在這方面比較專業,那麼他們兩人的意見所佔的比重就更大一些。假設這兩人佔的比重均為 0.23,其他三人佔的比重均為 0.18,則加權平均後的結果為:

5*0.23 + 4*0.23 + 5*0.18 + 4*0.18 + 4*0.18 = 4.41

示例代碼:

model1 = tree.DecisionTreeClassifier()
model2 = KNeighborsClassifier()
model3= LogisticRegression()
model1.fit(x_train,y_train)
model2.fit(x_train,y_train)
model3.fit(x_train,y_train)
pred1=model1.predict_proba(x_test)
pred2=model2.predict_proba(x_test)
pred3=model3.predict_proba(x_test)
finalpred=(pred1*0.3+pred2*0.3+pred3*0.4)

3. 高級集成技術

上文我們已經瞭解了基本的集成技術,接下來將介紹一下高級的集成技術。

3.1 Stacking

Stacking 是使用多個模型(例如決策樹、KNN、SVM)來構建新的模型的集成技術。該模型在測試集上進行預測。下面是一個簡單的 Stacking 集成的詳細步驟解釋。

1)將訓練集劃分為 10 個子集。

2)在其中 9 個子集上訓練一個基本模型(例如決策樹模型),在第 10 個子集上進行測試。遍歷每個子集,重複進行 10 次。得到的 DT 長度與 Train set 相同。

一份完備的集成學習手冊!(附Python代碼)

3)在整個訓練集上使用該模型(決策樹)進行建模。

4)使用建模的模型在測試集上進行測試。

一份完備的集成學習手冊!(附Python代碼)

5)使用另一種算法(例如 knn),重複步驟 2~4,作用在 Train set 和 Test set 上,得到另一組值。

一份完備的集成學習手冊!(附Python代碼)

6)使用得到的 DT 和 knn 組合作為新的特徵 TRAIN PREDICTION SET,訓練新的模型(例如邏輯迴歸)。

一份完備的集成學習手冊!(附Python代碼)

7)使用訓練好的模型對 TEST PREDICTION SET 進行預測。

示例代碼:

首先,我們需要定義一個函數對 n 折訓練集和測試集進行預測,該函數返回每個模型對訓練集和測試集的預測結果。

def Stacking(model,train,y,test,n_fold):
folds=StratifiedKFold(n_splits=n_fold,random_state=1)
test_pred=np.empty((test.shape[0],1),float)
train_pred=np.empty((0,1),float)
for train_indices,val_indices in folds.split(train,y.values):
x_train,x_val=train.iloc[train_indices],train.iloc[val_indices]
y_train,y_val=y.iloc[train_indices],y.iloc[val_indices]
model.fit(X=x_train,y=y_train)
train_pred=np.append(train_pred,model.predict(x_val))
test_pred=np.append(test_pred,model.predict(test))
return test_pred.reshape(-1,1),train_pred


然後,我們構建兩個基本模型:決策樹和 knn。

model1 = tree.DecisionTreeClassifier(random_state=1)
test_pred1 ,train_pred1=Stacking(model=model1,n_fold=10, train=x_train,test=x_test,y=y_train)
train_pred1=pd.DataFrame(train_pred1)
test_pred1=pd.DataFrame(test_pred1)


model2 = KNeighborsClassifier()
test_pred2,train_pred2=Stacking(model=model2,n_fold=10,train=x_train,test=x_test,y=y_train)
train_pred2=pd.DataFrame(train_pred2)
test_pred2=pd.DataFrame(test_pred2)

最後,使用邏輯迴歸,進行訓練和預測。

df = pd.concat([train_pred1, train_pred2], axis=1)
df_test = pd.concat([test_pred1, test_pred2], axis=1)
model = LogisticRegression(random_state=1)
model.fit(df,y_train)
model.score(df_test, y_test)

為了將問題簡單化,我們所創建的 Stacking 模型只有兩層。第一層是建立決策樹和 knn 模型,第二層是建立邏輯迴歸模型。實際應用中可以使用多個層次的複雜結構。

3.2 Blending

Blending 與 Stacking 類似,但是僅從訓練集上劃分一部分作為 holdout(驗證集),沒有使用 k 折驗證。Holdout 集結果作為下一層的訓練數據。下面是 Blending 的詳細步驟解釋。

1)將所有的訓練數據劃分為訓練集和驗證集。

一份完備的集成學習手冊!(附Python代碼)

2)在訓練集上訓練模型。

3)在驗證集和整體測試集上進行模型測試。

4)驗證集和測試結果作為元特徵,進行第二層的模型訓練。

5)使用該模型在整體測試集的元特徵上進行模型驗證。

示例代碼:

首先,我們在訓練集上訓練兩個模型:決策樹和 knn,以便在驗證集上作出預測。

model1 = tree.DecisionTreeClassifier()
model1.fit(x_train, y_train)
val_pred1=model1.predict(x_val)
test_pred1=model1.predict(x_test)
val_pred1=pd.DataFrame(val_pred1)
test_pred1=pd.DataFrame(test_pred1)
model2 = KNeighborsClassifier()
model2.fit(x_train,y_train)
val_pred2=model2.predict(x_val)
test_pred2=model2.predict(x_test)
val_pred2=pd.DataFrame(val_pred2)
test_pred2=pd.DataFrame(test_pred2)

然後,結合驗證集的元特徵,訓練邏輯迴歸模型,在測試集上進行驗證。

df_val=pd.concat([x_val, val_pred1,val_pred2],axis=1)
df_test=pd.concat([x_test, test_pred1,test_pred2],axis=1)
model = LogisticRegression()

model.fit(df_val,y_val)
model.score(df_test,y_test)

3.3 Bagging

Bagging 背後的思想就是將多個模型(例如決策樹)的結果結合得到泛化的結果。這裡有一個問題:在同樣的數據集上訓練得到不同的模型有用嗎?有很大幾率這些模型將給出同樣的結果,因為它們的輸入都是一致的。因此,如何解決這一問題呢?常用的方法就是 Bootstrapping。

Bootstrapping 是一種採樣技術,從原始數據集中有放回地採樣,創建觀測子集。子集的大小與原始集合的大小相同。

Bagging(Bootstrap Aggregating)技術使用這些子集(bags)來得到一個相對公平的分佈(完全集)。子集的大小也可能少於原始集。

一份完備的集成學習手冊!(附Python代碼)

1)從原始數據集中創建多個子集,有放回地進行採樣。

2)在每個子集上訓練一個基本模型(弱模型)。

3)這些模型相互平行且獨立。

4)最後的預測結果由所有模型共同決定。

一份完備的集成學習手冊!(附Python代碼)

3.4 Boosting

在我們進一步討論之前,還有一個問題:如果一個數據點被第一個模型預測錯誤,那麼下一個模型(可能是所有的模型)組合預測會預測正確嗎?這樣的情況可以通過 boosting 來處理。

Boosting 是一個循序漸進的過程,其中每一個後續模型都試圖糾正前一個模型的錯誤。後一個模型依賴於先前的模型。下面讓我們來了解 Boosting 的工作方式。

1)從原始數據集中創建一個子集。

2)起始狀態,所有數據點都賦予相同的權重。

3)在這個子集上訓練一個基本模型。

4)使用該模型在整個數據集上進行預測。

一份完備的集成學習手冊!(附Python代碼)

5)根據實際值和預測值計算誤差。

6)對預測錯誤的數據點給予更高的權重(如上圖中預測錯誤的藍色的“+”將賦予更大的權重)。

7)在此數據集上訓練一個新的模型並預測(該模型試圖糾正上一個模型中的錯誤點)。

一份完備的集成學習手冊!(附Python代碼)

8)類似地創建多個模型,每個模型校正前一個模型的錯誤。

9)最終的模型(強學習器)是所有模型(弱學習器)的加權平均。

一份完備的集成學習手冊!(附Python代碼)

因此,Boosting 算法結合了一些弱學習器,形成一個強大的學習器。單個模型在整個數據集上表現不好,但是它們在部分數據集上可能表現得很好。因此,每個模型實際上提升了集合的性能。

一份完備的集成學習手冊!(附Python代碼)

4. 基於 Bagging 和 Boosting 的算法

Bagging 和 Boosting 是機器學習中最常用的兩種技術。在這一節中,我們將詳細地研究它們。以下是我們將重點研究的算法:

Bagging 算法:

  • Bagging 元估計
  • 隨機森林

Boosting 算法:

  • AdaBoost
  • GBM
  • XGBM
  • Light
  • GBM
  • CatBoost

或者在本節中討論的所有算法,我們將遵循這個過程:

  • 算法介紹
  • 示例代碼
  • 參數

這篇文章中,我將討論貸款預測問題。您可以從這裡下載數據集:

https://datahack.analyticsvidhya.com/contest/practice-problem-loan-prediction-iii/

請注意,對於每個算法,一些代碼(讀取數據、分割訓練集、測試集等)是相同的。為了避免重複,我已經在下面寫下這些相同的代碼,之後只會深入討論算法的核心代碼。

#importing important packages
import pandas as pd
import numpy as np
#reading the dataset
df=pd.read_csv("/home/user/Desktop/train.csv")
#filling missing values
df['Gender'].fillna('Male', inplace=True)

類似地,關於數據填充、缺失值、異常值的處理,本文不做具體介紹。可參閱這篇文章瞭解相關內容:

https://www.analyticsvidhya.com/blog/2015/04/comprehensive-guide-data-exploration-sas-using-python-numpy-scipy-matplotlib-pandas/

#split dataset into train and test
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3, random_state=0)
x_train=train.drop('Loan_Status',axis=1)
y_train=train['Loan_Status']
x_test=test.drop('Loan_Status',axis=1)
y_test=test['Loan_Status']
#create dummies
x_train=pd.get_dummies(x_train)
x_test=pd.get_dummies(x_test)

接下來,讓我們開始 Bagging 和 Boosting 算法吧!

4.1 Bagging 元估計

Bagging 元估計是一種集成算法,可用於分類(BaggingClassifier)和迴歸(BaggingRegressor)問題。它遵循典型的 Bagging 技術進行預測。下面是 Bagging 元估計算法的步驟:

1)從原始數據集中創建隨機子集(Bootstrapping)。

2)子集包含所有特徵。

3)用戶指定的基本估計器在這些子集上進行訓練。

4)每個模型的預測結合形成最終的結果。

代碼:

from sklearn.ensemble import BaggingClassifier
from sklearn import tree
model = BaggingClassifier(tree.DecisionTreeClassifier(random_state=1))
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.75135135135135134

對於迴歸問題:

from sklearn.ensemble import BaggingRegressor
model = BaggingRegressor(tree.DecisionTreeRegressor(random_state=1))
model.fit(x_train, y_train)
model.score(x_test,y_test)

參數:

  • base_estimator:
  • 它定義了基本的學習器,缺失時默認使用決策樹。
  • n_estimators:
  • 它定義基本學習器的數量。學習器數量需要選擇合適的值,太大影響訓練速度,太小影響訓練精度。
  • max_samples:
  • 每個子集最大樣本數量。
  • max_features:
  • 每個子集最大特徵數量。
  • n_jobs:
  • 並行運行的任務數量。將該值設置為與系統中的內核相等。 如果設置為 -1,任務數量等於內核數。
  • random_state:
  • 它指定了隨機劃分的方法。當兩個模型的隨機狀態值相同時,它們的隨機選擇相同。比較不同的模型時,這個參數是有用的。

4.2 隨機森林

隨機森林遵循 Bagging 技術的另一種集成機器學習算法。它是 Bagging 估計算法的一個擴展。隨機森林中的基本學習器是決策樹。與 Bagging 元估計不同,隨機森林隨機選擇一組特徵,這些特徵用於在決策樹的每個節點處決定最佳分割。

隨機森林算法的詳細步驟如下:

1)從原始數據集中創建隨機子集(Bootstrapping)。

2)在決策樹中的每個節點,使用隨機特徵來決定最佳分割。

3)在每個子集上訓練一個決策樹模型。

4)最後的結果是對所有決策樹的預測計算平均值。

注:隨機森林中的決策樹可以建立在數據和特徵的子集上。特別地,sklearn 中的隨機森林模型將所有特徵用於決策樹,並且隨機選擇特徵子集用於在每個節點處分割。

總之,隨機森林隨機選擇數據點和特徵,並建立多個樹木(森林)。

代碼:

from sklearn.ensemble import RandomForestClassifier
model= RandomForestClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.77297297297297296

你可以使用 model.feature_importances_ 來查看特徵的重要性。

for i, j in sorted(zip(x_train.columns, model.feature_importances_)):
print(i, j)

結果如下:

ApplicantIncome 0.180924483743 CoapplicantIncome 0.135979758733 Credit_History 0.186436670523. . . Property_Area_Urban 0.0167025290557 Self_Employed_No 0.0165385567137 Self_Employed_Yes 0.0134763695267

迴歸問題的示例代碼:

from sklearn.ensemble import RandomForestRegressor
model= RandomForestRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)

參數:

  • n_estimators:
  • 它定義了在隨機森林中創建的決策樹的數量。一般來說,較多的決策樹使預測更強、更穩定,但是過多會導致更長的訓練時間。
  • criterion:
  • 它定義了用於分裂的函數。該函數測量每個特徵的分割質量,並選擇最佳分割。
  • max_features :
  • 它定義了每個決策樹中分割所允許的最大特徵數。增加其值通常會提高性能,但是過高會降低每顆樹的多樣性。
  • max_depth:
  • 隨機森林具有多個決策樹。此參數定義樹的最大深度。
  • min_samples_split:
  • 定義葉節點分裂所需的最小樣本數。如果樣本數量小於改值,則節點不被拆分。
  • min_samples_leaf:
  • 定義在葉節點上需要的最小樣本數。較小的值使得模型更容易捕獲訓練數據中的噪聲。
  • max_leaf_nodes:
  • 此參數指定每個樹的最大葉節點數。當葉節點的數量等於該值時,停止分裂。
  • n_jobs:
  • 這指示並行運行的任務數量。如果您希望它在系統中的所有內核上運行,則將值設置為 -1。
  • random_state:
  • 此參數用於定義隨機選擇。比較不同的模型時,這個參數是有用的。

4.3 AdaBoost

自適應 Boosting(AdaBoost)是最簡單的 Boosting 算法之一。通常,決策樹用於建模。順序創建多個模型,每個模型校正前一個模型的錯誤。AdaBoost 為上一個模型中預測錯誤的數據點分配更大的權重,在此模型工作以便能夠正確地預測。

下面是 AdaBoost 算法的步驟:

1)最初,對數據集中的所有數據點賦予相同的權重。

2)在數據子集上建立模型。

3)使用該模型,對整個數據集進行預測。

4)通過比較預測值和實際值來計算誤差。

5)在創建下一個模型時,對預測不正確的數據點給出更高的權重。

6)可以使用誤差值確定權重。例如,誤差大的賦予更大的權重。

7)重複這個過程直到誤差函數不改變,或者達到學習器的最大數量。

代碼:

from sklearn.ensemble import AdaBoostClassifier
model = AdaBoostClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.81081081081081086

迴歸問題的示例代碼:

from sklearn.ensemble import AdaBoostRegressor
model = AdaBoostRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)

參數:

  • base_estimator:
  • 它有助於指定基本估計器的類型,也就是說,被用作基礎學習器的機器學習算法。
  • n_estimators:
  • 它定義了基本學習器的數量。默認值為10,但應設置更大的值以獲得更好的性能。
  • learning_rate:
  • 該參數控制最終組合中學習的貢獻率。learning_rate 和 n_estimators 之間需要權衡。
  • max_depth:
  • 定義單個估計器的最大深度。調整此參數以獲得最佳性能。
  • n_jobs:
  • 指定允許使用的處理器的數量。設置為 -1 時允許使用所有的處理器。
  • random_state:
  • 它指定了隨機劃分的方法。如果給定相同的參數和訓練數據,相同的 random_state 值總會產生相同的結果。

4.4 Gradient Boosting (GBM)

梯度提升(GBM)是另一種集成機器學習算法,它同時適用於迴歸和分類問題。GBM 使用提升技術,結合一些弱學習器形成一個強大的學習器。迴歸樹作為基礎學習器,每個後續的樹是建立在由前一棵樹計算的誤差上的。

我們將使用一個簡單的例子來理解 GBM 算法。使用以下數據來預測一組人的年齡:

一份完備的集成學習手冊!(附Python代碼)

1)平均年齡被假定為在數據集中的所有觀察值的預測值。

2)使用該平均預測值和實際年齡值計算誤差。

一份完備的集成學習手冊!(附Python代碼)

3)使用上面計算的誤差作為目標變量創建樹模型。我們的目標是找到最佳的分割,以儘量減少誤差。

4)該模型的預測結果與 predicion1 相結合。

一份完備的集成學習手冊!(附Python代碼)

5)上面計算的值就是新的預測值。

6)利用該預測值和實際值計算新的誤差。

一份完備的集成學習手冊!(附Python代碼)

7)重複步驟2到6直到達到最大迭代次數(或者誤差函數不改變)。

代碼:

from sklearn.ensemble import GradientBoostingClassifier
model= GradientBoostingClassifier(learning_rate=0.01,random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.81621621621621621

迴歸問題的示例代碼:

from sklearn.ensemble import GradientBoostingRegressor
model= GradientBoostingRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)

參數:

  • min_samples_split:
  • 定義在節點中用於分裂的樣本(或觀測)的最小數目,用於控制過擬合。更高的值可以阻止模型對樹選擇的特定樣本具有高度特異性的關係。
  • min_samples_leaf:
  • 定義終端或葉節點所需的最少樣本。一般來說,對於不平衡的類問題,應該選擇較小的值,因為少數類居多的區域將會比較小。
  • min_weight_fraction_leaf:
  • 類似於 min_samples_leaf,但定義為佔所有樣本點的分數大小,而不是整數。
  • max_depth:
  • 樹的最大深度。用於控制過擬合,因為更高的深度可能使得模型學習特定於某些樣本之間的關係。應該使用 CV 調試選擇最佳深度。
  • max_leaf_nodes:
  • 樹中的終端節點或葉子的最大數目。可以用 max_depth 定義。由於創建二叉樹,N 的深度會產生最多 2 的 N 次方的葉子。如果定義了這一參數,GBM 可以忽略 max_depth。
  • max_features:
  • 在尋找最佳分割時要考慮的特徵數量,一般是隨機選擇的。作為一個經驗法則,取特徵總數平方根數量的特徵效果不錯,但是我們一般選擇總特徵數的 30-40%。較高的值可能導致過擬合,但一般視情況而定。

4.5 XGBoost

XGBoost(extreme Gradient Boosting)是一種先進的梯度提升算法的實現。XGBoost 已被證明是一種高效的 ML 算法,廣泛應用於機器學習競賽中。XGBoost 具有較高的預測能力,比其他梯度提升技術速度快 10 倍。它還包括各種正則化技術減少過擬合來提高整體性能。因此,它也被稱為“regularized boosting”技術。

讓我們看看 XGBoost 是如何比其他技術更好的:

1)正則化

標準 GBM 沒有像 XGBoost 那樣的正則化。因此 XGBoost 有助於減少過擬合。

2)並行處理

XGBoost 實現並行處理,並且比 GBM 更快。XGBoost 還支持在 Hadoop 上實現。

3)高靈活性

XGBoost 允許用戶自定義優化目標和評價標準,為模型添加一個新的維度。

4)

處理缺失值

XGBoost 有一個內置功能來處理缺失值。

5)樹修剪

XGBoost 進行分割到最大深度後,然後開始由下到上修剪樹,移除沒有正增益的分割。

6)內建交叉驗證

XGBoost 允許用戶在提升過程的每次迭代中運行交叉驗證,因此很容易在一次運行中獲得最佳提升迭代次數。

代碼:

由於 XGBoost 可以處理缺失值,所以不必在預處理中對缺失值進行填充。你可以跳過上述代碼中缺失值的填補步驟。按照其餘的步驟進行:

import xgboost as xgb
model=xgb.XGBClassifier(random_state=1,learning_rate=0.01)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.82702702702702702

迴歸問題的示例代碼:

import xgboost as xgb
model=xgb.XGBRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)

參數:

  • nthread:
  • 用於並行處理和系統中的允許使用的內核數量。如果希望在所有內核上運行,請不要輸入此值,該算法將自動檢測。
  • eta:
  • 類似於 GBM 中的學習速率。通過縮小每個步驟的權重使模型更加健壯。
  • min_child_weight:
  • 定義子節點樣本點所需的最小加權和。用於控制過擬合。更高的值可以阻止模型對樹選擇的特定樣本具有高度特異性的關係。
  • max_depth:
  • 定義最大深度。更高的深度可能使得模型學習特定於某些樣本之間的關係。
  • max_leaf_nodes:
  • 樹中的終端節點或葉子的最大數目。可以用 max_depth 定義。由於創建二叉樹,N 的深度會產生最多 2 的 N 次方的葉子。如果定義了這一參數,GBM 可以忽略 max_depth。
  • gamma:
  • 只有當分裂節點能減小損失函數一定值的時候,才分裂一個節點。參數 gamma 指定了分裂所需的損失函數減少的最小值。使得算法保守,gamma 可以根據損失函數而變化,並且應該調試。
  • subsample:
  • 與 GBM 的 subsample 相同。表示每個樹隨機採樣的數據點的分數。較低的值使算法更保守,並防止過擬合,但值太小可能導致欠擬合。
  • colsample_bytree:
  • 它與 GBM 中的 max_features 特徵相似。表示要為每個樹隨機抽樣的列的分數。

4.6 LightGBM

在討論 LightGBM 如何工作之前,讓我們先了解為什麼需要這個算法。我們已經有這麼多 Boosting 算法了(如上面介紹的),當數據集非常大時,Light GBM 則優於其它所有的算法。與其他算法相比,Light GBM 在巨大的數據集上運行所消耗的時間更少。

LightGBM 是一個梯度增強框架,它使用基於樹的算法,並遵循 leaf-wise 方式,而其他算法以 level-wise 方式工作。下面的圖片將幫助你更好地理解差異。

一份完備的集成學習手冊!(附Python代碼)


一份完備的集成學習手冊!(附Python代碼)

level-wise 在數據量少的時候可能會導致過擬合,但是可以通過使用參數 max_depth 可以避免這種情況發生。你可以閱讀下面的文章瞭解更多 Light GBM 及其與 XGB 的比較:

https://www.analyticsvidhya.com/blog/2017/06/which-algorithm-takes-the-crown-light-gbm-vs-xgboost/

代碼:

import lightgbm as lgb 

train_data=lgb.Dataset(x_train,label=y_train)
#define parameters
params = {'learning_rate':0.001}
model= lgb.train(params, train_data, 100)
y_pred=model.predict(x_test)
for i in range(0,185):
if y_pred[i]>=0.5:
y_pred[i]=1
else:
y_pred[i]=0
0.81621621621621621

迴歸問題的示例代碼:

import lightgbm as lgb
train_data=lgb.Dataset(x_train,label=y_train)
params = {'learning_rate':0.001}
model= lgb.train(params, train_data, 100)
from sklearn.metrics import mean_squared_error
rmse=mean_squared_error(y_pred,y_test)**0.5

參數:

  • num_iterations:
  • 它定義要執行的 boosting 迭代數。
  • num_leaves:
  • 此參數用於設置樹中要形成的葉子的數量。對於 Light GBM,由於分裂發生在 level-wise 方向而不是 depth-wise 方向,所以num_leaft必須小於 2 的 max_depth 次方,否則可能導致過擬合。
  • min_data_in_leaf:
  • 該值過小可能導致過度擬合。它也是處理過擬合的最重要的參數之一。
  • max_depth:
  • 定義樹可以生長的最大深度或高度。這個參數過大會導致過擬合。
  • bagging_fraction:
  • 它用於指定每次迭代要使用的數據比例。這個參數通常用於加速訓練。
  • max_bin:
  • 定義特徵值將被插入的容器的最大數目。較小的 max_bin 值可以節省大量時間,因為它將特徵值存儲到離散的容器中,計算代價小。

4.7 CatBoost

處理分類變量是一個乏味的過程,尤其有大量這樣的變量。當分類變量的標籤太多(例如高度基數)時,對它們進行獨熱編碼會指數地增加維度,這讓數據處理非常困難。

CatBoost 可以自動處理分類變量,並且不需要像其他機器學習算法那樣進行額外的數據預處理。下面是一篇詳細介紹 CatBoost 的文章:

https://www.analyticsvidhya.com/blog/2017/08/catboost-automated-categorical-data/

代碼:

CatBoost 算法能有效地處理分類變量。因此,不需要對分類變量進行獨熱編碼。只需加載文件,填入缺失值,就可以了。

from catboost import CatBoostClassifier
model=CatBoostClassifier()
categorical_features_indices = np.where(df.dtypes != np.float)[0]
model.fit(x_train,y_train,cat_features=([ 0, 1, 2, 3, 4, 10]),eval_set=(x_test, y_test))
model.score(x_test,y_test)
0.80540540540540539

迴歸問題的示例代碼:

from catboost import CatBoostRegressor
model=CatBoostRegressor()
categorical_features_indices = np.where(df.dtypes != np.float)[0]
model.fit(x_train,y_train,cat_features=([ 0, 1, 2, 3, 4, 10]),eval_set=(x_test, y_test))
model.score(x_test,y_test)

參數:

  • loss_function:
  • 定義用於訓練的指標。
  • iterations:
  • 可以生成的樹的最大數量。最終樹的數量可以小於或等於這個數。
  • learning_rate:
  • 定義學習率,用於梯度下降優化中。
  • border_count:
  • 它指定了數值特徵的分裂數,類似於參數 max_bin。
  • depth:
  • 定義樹的深度。
  • random_seed:
  • 這個參數類似於我們先前看到的參數 random_state,它是一個整數,定義用於訓練的隨機種子。

結語

集合建模可以指數地提高模型的性能!在本文中,我們介紹了各種集成學習技術,並瞭解了這些技術在機器學習算法中的應用。此外,我們實現了我們的貸款預測數據集的算法。

如果覺得文章還可以的話,煩請關注、點贊、轉發,謝謝!


分享到:


相關文章: