微信號:deep_intelligence(歡迎關注!)
http://weixin.qq.com/r/ry7r8xzEOEFHrViQ93u9 (二維碼自動識別)
當您想購買新車時,您會走到第一家車店並只根據經銷商的建議就馬上購買嗎?這不太可能。您可能會瀏覽一些門戶網站,人們發布評論並比較不同的車型,檢查其功能和價格。你也可能會問你的朋友和同事他們的意見。簡而言之,你不會直接得出結論,而是會考慮其他人的意見做出決定。
機器學習中的集成模型基於類似的想法。他們將來自多個模型的決策結合起來,以提高整體績效。這可以通過各種方式實現,您將在本文中發現。
本文的目的是介紹集成學習的概念,並理解使用該技術的演算法。為了鞏固您對這個多樣化主題的理解,我們將使用針對現實問題的實際案例研究來解釋Python中的高級演算法。
注意:本文假設您對機器學習演算法有基本的了解。
3.2混合(blending)
讓我們通過一個例子來理解集成學習的概念。假設你是一名電影導演,你已經創作了一部關於非常重要且有趣的話題的短片。現在,您希望在公開之前對電影進行初步反饋(評級)。你可以用這種方式做什麼?
A:您可以讓一位朋友為您評分電影。
B:另一種方法可以是讓你的5位同事評價這部電影。
C:要求50個人評價這部電影怎麼樣?
通過這些示例,您可以推斷出與個人相比,不同群體的人可能做出更好的決策。與單一模型相比,各種模型也是如此。機器學習的這種多樣化是通過一種稱為Ensemble Learning(集成學習)的技術實現的。現在您已經了解了集成學習的要點 - 讓我們看看集成學習中的各種技術及其實現。
在本節中,我們將介紹一些簡單但功能強大的技術,即:
最大投票方法通常用於分類問題。在該技術中,使用多個模型來對每個數據點進行預測。每個模型的預測被視為「投票」。我們從大多數模型得到的預測被用作最終預測。
例如,當你讓5位同事評價你的電影時(總分5分); 我們假設其中三個將它評為4,而其中兩個給它一個5.由於大多數評分為4,最終評級將被視為4. 您可以將此視為採用所有預測的眾數。
最大投票的結果將是這樣的:
示例代碼:
這裡x_train由訓練數據中的獨立變數組成,y_train是訓練數據的目標變數。驗證集是x_test(自變數)和y_test(目標變數)。
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)
與最大投票技術類似,對每個數據點的多次預測進行平均。在這種方法中,我們採用所有模型的平均預測值並使用它來進行最終預測。平均可用於在回歸問題中進行預測或在計算分類問題的概率時使用。
例如,在下面的情況中,平均方法將取所有值的平均值。
即(5 + 4 + 5 + 4 + 4)/ 5 = 4.4
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
這是平均方法的擴展。為每個模型分配不同的權重,定義每個模型的預測重要性。例如,如果你的兩個同事都是評論員,而另一些同事沒有這方面的經驗,那麼這兩個朋友的答案與其他人相比更為重要。
結果計算為[(5 * 0.23)+(4 * 0.23)+(5 * 0.18)+(4 * 0.18)+(4 * 0.18)] = 4.41。
finalpred =(PRED1 * 0.3 + PRED2 * 0.3 + pred3 * 0.4)
現在我們已經介紹了基本的集成技術,讓我們繼續理解高級技術。
堆疊是一種集成學習技術,它使用來自多個模型(例如決策樹,knn或svm)的預測來構建新模型。該模型用於對測試集進行預測。以下是簡單堆疊集成的逐步說明:
2. 基礎模型(例如決策樹)用訓練集中的9個組進行訓練,用第10個組進行預測。
3. 然後將基礎模型(例如決策樹)擬合到整個訓練數據集上。
4. 使用此模型,在測試集上進行預測。
5. 對另一個基本模型(比如knn)重複步驟2到4,產生對訓練集和測試集的另一組預測。
6. 訓練集的預測被用作構建新模型的特徵。
7. 該模型用於對測試預測集進行最終預測。
我們首先定義一個函數來對分成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)
在決策樹和knn模型的預測上創建第三個模型,邏輯回歸。
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)
為了簡化上述說明,我們創建的堆疊模型只有兩個級別。決策樹和knn模型建立在零級,而邏輯回歸模型建立在第一級。您可以在堆疊模型中創建多個級別。
混合遵循與堆疊相同的方法,但僅使用來自訓練集的保留/(驗證)集來進行預測。換句話說,與堆疊不同,預測僅在保留集上進行。保留集和它的預測用於構建模型,用測試集對這個模型進行測試。以下是混合過程的詳細說明:
2.把模型擬合到訓練集上。
3. 預測在驗證集和測試集上進行。
4. 驗證集及其預測用作構建新模型的特徵。
5. 該模型用於對測試集和元特徵(meta-features)進行最終預測。
我們將在訓練集上創建兩個模型,決策樹和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)
Bagging背後的思想是結合多個模型的結果(例如,所有決策樹)來獲得泛華的結果。問題是:如果您在同一組數據上創建所有模型並將其組合起來,它會有用嗎?這些模型很可能會得到相同的結果,因為它們獲得相同的輸入。那麼我們如何解決這個問題呢?其中一種方案是使用bootstrapping。
Bootstrapping是一種(有放回的)採樣技術,我們在其中創建來自原始數據集的觀察子集。子集的大小與原始集的大小相同。
Bagging(或Bootstrap Aggregating)技術使用這些子集(包)來獲得分布的完整概念(完整集)。為Bagging創建的子集的大小可能小於原始集。
在開始之前,請先思考一個問題:如果一個數據點被第一個模型錯誤地預測,然後下一個模型(可能是所有模型)的預測也是錯誤的,那麼結合預測會提供更好的結果嗎?通過提升來處理這種情況。
Boosting是一個順序過程,每個後續模型都會嘗試糾正先前模型的錯誤。隨後的模型取決於之前的模型。讓我們通過以下步驟了解提升的方式。
5. 使用實際值和預測值計算誤差。
6. 錯誤的預測的觀察結果具有更高的權重。
6. 創建另一個模型並對數據集進行預測。
7. 類似地,創建多個模型,每個模型校正先前模型的錯誤。
8. 最終模型(強學習器)是所有模型(弱學習器)的加權平均值。
因此,提升演算法結合了許多弱學習器以形成強大的學習器。單個模型在整個數據集上表現不佳,但它們適用於數據集的某些部分。因此,每個模型實際上提升了整體的性能。
Bagging和Boosting是機器學習中最常用的兩種技術。在本節中,我們將詳細介紹它們。以下是我們將關注的演算法:
Bagging演算法:
提升演算法:
對於本節中討論的所有演算法,我們將遵循以下過程:
對於本文,我使用了貸款預測問題。您可以從此處【1】下載數據集。請注意,對於每種演算法,一些代碼行(讀取數據,訓練集和測試集的分割等)將是相同的。為了避免重複,我在下面編寫了相同的代碼,並且僅對演算法相關的代碼進行進一步討論。
#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)
同樣,填充所有列的值。這裡跳過了EDA,缺失值和異常值處理。要了解這些主題,您可以閱讀這篇文章:使用NumPy,Matplotlib和Pandas在Python中進行數據探索的終極指南。【2】
#split數據集進入訓練和測試
#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 meta-estimator是一種集成演算法,可用於分類(BaggingClassifier)和回歸(BaggingRegressor)問題。它採用典型的Bagging技術進行預測。以下是Bagging meta-estimator演算法的步驟:
源碼:
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)
演算法中使用的參數:
隨機森林是另一種遵循Bagging技術的集成機器學習演算法。它是bagging估算演算法的擴展。隨機森林中的基礎估計量是決策樹。與Bagging meta-estimator不同,隨機森林隨機選擇一組特徵,這些特徵用於決定決策樹的每個節點處的最佳分割。
隨機森林模型的演算法如下:
注意:隨機林中的決策樹可以構建在數據和特徵的子集上。特別地,隨機森林的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)
參數
自適應提升或AdaBoost是最簡單的提升演算法之一。通常,決策樹用於建模。創建多個順序模型,每個模型都校正上一個模型的錯誤。AdaBoost為不正確預測的觀測值分配權重,後續模型用於正確預測這些值。
以下是執行AdaBoost演算法的步驟:
原碼:
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)
Gradient Boosting或GBM是另一種集成機器學習演算法,適用於回歸和分類問題。GBM使用boosting技術,結合了許多弱學習器,形成了一個強大的學習器。回歸樹用作基礎學習器,每個後續的樹都是基於前一樹計算的錯誤構建的。
我們將使用一個簡單的例子來理解GBM演算法。我們必須使用以下數據預測一群人的年齡:
3. 使用上面計算的誤差作為目標變數創建樹模型。我們的目標是找到最佳分割以最小化錯誤。4. 該模型的預測與預測1相結合。
5. 上面計算的這個值是新的預測。
6. 使用此預測值和實際值計算新誤差。
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)
XGBoost(extreme Gradient Boosting)是梯度提升演算法的高級實現。事實證明,XGBoost是一種高效的ML演算法,廣泛應用於機器學習競賽和黑客馬拉松。XGBoost具有很高的預測能力,幾乎比其他梯度提升技術快10倍。它還包括各種正規化,可減少過擬合併提高整體性能。因此,它也被稱為「 正則化提升 」技術。
讓我們看看XGBoost如何比其他技術更好:
2. 並行處理:
3. 高靈活性:
4. 處理缺失值:
5. 樹修剪:
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)
在討論Light GBM如何工作之前,讓我們首先理解為什麼在我們有這麼多其他演算法時(例如我們上面看到的演算法)我們需要這個演算法。當數據集非常大時,Light GBM會擊敗所有其他演算法。與其他演算法相比,Light GBM在較大的數據集上運行所需的時間較短。
LightGBM是一個梯度提升框架,它使用基於樹的演算法並遵循逐葉子方法,而其他演算法以逐層式工作。下面的圖片將幫助您以更好的方式理解差異。
逐葉子方式可能導致較小的數據集過擬合,但可以通過使用max_depth參數進行學習來避免這種情況。
將lightgbm導入為lgb train_data = lgb.Dataset(x_train,標記= y_train) 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
處理分類變數是一個繁瑣的過程,尤其是當您有大量此類變數時。當您的分類變數具有太多標籤(即它們是高度基數)時,對它們執行one-hot編碼會以指數方式增加維度,並且使用數據集變得非常困難。
CatBoost可以自動處理分類變數,並且不需要像其他機器學習演算法那樣進行大量數據預處理。
CatBoost演算法有效地處理分類變數。因此,您不應對分類變數執行one-hot編碼。只需載入文件,估算缺失的值,就可以了。
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)
參考資料:
本文翻譯自:A Comprehensive Guide to Ensemble Learning (with Python codes)