模型融合---CatBoost總結

1、Catboost簡介

2、Catboost的特色

  通常來講,Gradient Boosting(GB)方法適用於異質化數據。即,若你的數據集全由圖片數據構成或者全由視頻數據構成之類的,咱們稱其爲同質化數據,這時使用神經網絡每每會有更好的表現。但對於異質化數據,好比說數據集中有user gender,user age,也有content data等等的狀況,GB方法的表現每每更好。GB方法比神經網絡的入門門檻更低,使用起來也更簡單。html

  NN和GB方法能夠結合起來使用,並經常有很好的表現。咱們可使用NN方法學習embedding feature,而且和其餘一些特徵結合起來,再過GBDT。python

  Catboost具備一些和其餘相似的庫不一樣的特徵:git

1.類別型特徵

  對於可取值的數量比獨熱最大量還要大的分類變量,CatBoost 使用了一個很是有效的編碼方法,這種方法和均值編碼相似,但能夠下降過擬合狀況。它的具體實現方法以下:github

  • 將輸入樣本集隨機排序,並生成多組隨機排列的狀況。
  • 將浮點型或屬性值標記轉化爲整數。
  • 將全部的分類特徵值結果都根據如下公式,轉化爲數值結果。

  其中 CountInClass 表示在當前分類特徵值中,有多少樣本的標記值是「1」;Prior 是分子的初始值,根據初始參數肯定。TotalCount 是在全部樣本中(包含當前樣本),和當前樣本具備相同的分類特徵值的樣本數量。能夠用下面的數學公式表示:算法

特徵組合

其次,它用特殊的方式處理categorical features。首先他們會計算一些數據的statistics。計算某個category出現的頻率,加上超參數,生成新的numerical features。這一策略要求同一標籤數據不能排列在一塊兒(即先全是0以後全是1這種方式),訓練以前須要打亂數據集。第二,使用數據的不一樣排列(其實是4個)。在每一輪創建樹以前,先扔一輪骰子,決定使用哪一個排列來生成樹。第三,考慮使用categorical features的不一樣組合。例如顏色和種類組合起來,能夠構成相似於blue dog這樣的feature。當須要組合的categorical features變多時,catboost只考慮一部分combinations。在選擇第一個節點時,只考慮選擇一個feature,例如A。在生成第二個節點時,考慮A和任意一個categorical feature的組合,選擇其中最好的。就這樣使用貪心算法生成combinations。第四,除非向gender這種維數很小的狀況,不建議本身生成one-hot vectors,最好交給算法來處理。

網絡

2.克服梯度誤差

catboost和其餘算法計算leaf-value的方法不一樣。傳統的boosting使用平均數,但這個估計是有偏的,會致使過擬合。而Catboost則採用另外的計算方法。dom

  CatBoost,和全部標準梯度提高算法同樣,都是經過構建新樹來擬合當前模型的梯度。然而,全部經典的提高算法都存在由有偏的點態梯度估計引發的過擬合問題。許多利用GBDT技術的算法(例如,XGBoost、LightGBM),構建一棵樹分爲兩個階段:選擇樹結構和在樹結構固定後計算葉子節點的值。爲了選擇最佳的樹結構,算法經過枚舉不一樣的分割,用這些分割構建樹,對獲得的葉子節點中計算值,而後對獲得的樹計算評分,最後選擇最佳的分割。兩個階段葉子節點的值都是被當作梯度[8]或牛頓步長的近似值來計算。CatBoost第一階段採用梯度步長的無偏估計,第二階段使用傳統的GBDT方案執行。

3.快速評分

Catboost使用對稱樹。XGboost一層一層地創建節點,lightGBM一個一個地創建節點,而Catboost老是使用徹底二叉樹。它的節點是鏡像的。Catboost稱對稱樹有利於避免overfit,增長可靠性,而且能大大加速預測等等。機器學習

  CatBoost使用oblivious樹做爲基本預測器,這種樹是平衡的,不太容易過擬合。oblivious樹中,每一個葉子節點的索引能夠被編碼爲長度等於樹深度的二進制向量。CatBoost首先將全部浮點特徵、統計信息和獨熱編碼特徵進行二值化,而後使用二進制特徵來計算模型預測值。分佈式

4.基於GPU實現快速學習

  • 密集的數值特徵

  任何GBDT算法,對於密集的數值特徵數據集來講,搜索最佳分割是創建決策樹時的主要計算負擔。CatBoost利用oblivious決策樹做爲基礎模型,並將特徵離散化到固定數量的箱子中以減小內存使用。就GPU內存使用而言,CatBoost至少與LightGBM同樣有效。主要改進之處就是利用了一種不依賴於原子操做的直方圖計算方法。函數

  • 類別型特徵

  CatBoost使用完美哈希來存儲類別特徵的值,以減小內存使用。因爲GPU內存的限制,在CPU RAM中存儲按位壓縮的完美哈希,以及要求的數據流、重疊計算和內存等操做。經過哈希來分組觀察。在每一個組中,咱們須要計算一些統計量的前綴和。該統計量的計算使用分段掃描GPU圖元實現。

  • 多GPU支持

  CatBoost中的GPU實現可支持多個GPU。分佈式樹學習能夠經過數據或特徵進行並行化。CatBoost採用多個學習數據集排列的計算方案,在訓練期間計算分類特徵的統計數據。

3、與xgboost、lightgbm的對比

參數對比:

數據集:

在這裏,我使用了 2015 年航班延誤的 Kaggle 數據集,其中同時包含分類變量和數值變量。這個數據集中一共有約 500 萬條記錄,所以很適合用來同時評估比較三種 boosting 算法的訓練速度和準確度。我使用了 1% 的數據:5 萬行記錄。

如下是建模使用的特徵:

月、日、星期:整型數據
航線或航班號:整型數據
出發、到達機場:數值數據
出發時間:浮點數據
到達延誤狀況:這個特徵做爲預測目標,並轉爲二值變量:航班是否延誤超過 10 分鐘
距離和飛行時間:浮點數據

import pandas as pd, numpy as np, time
from sklearn.model_selection import train_test_split

data = pd.read_csv("flight-delays/flights.csv")
data = data.sample(frac = 0.1, random_state=10)#500->50

data = data.sample(frac = 0.1, random_state=10)#50->5

data.shape#(58191, 31)

data = data[["MONTH","DAY","DAY_OF_WEEK","AIRLINE","FLIGHT_NUMBER","DESTINATION_AIRPORT",
                 "ORIGIN_AIRPORT","AIR_TIME", "DEPARTURE_TIME","DISTANCE","ARRIVAL_DELAY"]]
data.dropna(inplace=True)

data["ARRIVAL_DELAY"] = (data["ARRIVAL_DELAY"]>10)*1
#data.head()

cols = ["AIRLINE","FLIGHT_NUMBER","DESTINATION_AIRPORT","ORIGIN_AIRPORT"]
for item in cols:
    data[item] = data[item].astype("category").cat.codes +1

train, test, y_train, y_test = train_test_split(data.drop(["ARRIVAL_DELAY"], axis=1), data["ARRIVAL_DELAY"],
                                                random_state=10, test_size=0.25)

 最終的數據集大概長這個樣子:

1.xgboost

  和 CatBoost 以及 LGBM 算法不一樣,XGBoost 自己沒法處理分類變量,而是像隨機森林同樣,只接受數值數據。所以在將分類數據傳入 XGBoost 以前,必須經過各類編碼方式:例如標記編碼、均值編碼或獨熱編碼對數據進行處理。

import xgboost as xgb
from sklearn.grid_search import GridSearchCV
from sklearn import metrics

def auc(m, train, test): 
    return (metrics.roc_auc_score(y_train,m.predict_proba(train)[:,1]),
                            metrics.roc_auc_score(y_test,m.predict_proba(test)[:,1]))

Parameter Tuning
model = xgb.XGBClassifier()
param_dist = {"max_depth": [10,30,50],
              "min_child_weight" : [1],
              "n_estimators": [200],
              "learning_rate": [0.16],}
grid_search = GridSearchCV(model, param_grid=param_dist, cv = 3, 
                                   verbose=10, n_jobs=-1)
grid_search.fit(train, y_train)

grid_search.best_estimator_

model = xgb.XGBClassifier(max_depth=10, min_child_weight=1,  n_estimators=200,\
                          n_jobs=-1 , verbose=1,learning_rate=0.16)

train.shape,y_train.shape#((42855, 10), (42855,))

model.fit(train,y_train)

auc(model,train,test)#過擬合 (1.0, 0.6990888367179413)

  

2.Light GBM

  和 CatBoost 相似,LighGBM 也能夠經過使用特徵名稱的輸入來處理屬性數據;它沒有對數據進行獨熱編碼,所以速度比獨熱編碼快得多。LGBM 使用了一個特殊的算法來肯定屬性特徵的分割值。注意,在創建適用於 LGBM 的數據集以前,須要將分類變量轉化爲整型變量;此算法不容許將字符串數據傳給分類變量參數。

(1)不加categorical_feature 選項

import lightgbm as lgb
from sklearn import metrics

def auc2(m, train, test): 
    return (metrics.roc_auc_score(y_train,m.predict(train)),
                            metrics.roc_auc_score(y_test,m.predict(test)))

lg = lgb.LGBMClassifier(silent=False)
param_dist = {"max_depth": [25,50, 75],
              "learning_rate" : [0.01,0.05,0.1],
              "num_leaves": [300,900,1200],
              "n_estimators": [200]
             }
grid_search = GridSearchCV(lg, n_jobs=-1, param_grid=param_dist, cv = 3, scoring="roc_auc", verbose=5)
grid_search.fit(train,y_train)
grid_search.best_estimator_

d_train = lgb.Dataset(train, label=y_train)
params = {"max_depth": 50, "learning_rate" : 0.1, "num_leaves": 900,  "n_estimators": 300}

# Without Categorical Features
model2 = lgb.train(params, d_train)

auc2(model2, train, test)#(1.0, 0.6813950368358092)

(2)加categorical_feature 選項

#With Catgeorical Features
cate_features_name = ["MONTH","DAY","DAY_OF_WEEK","AIRLINE","DESTINATION_AIRPORT",
                 "ORIGIN_AIRPORT"]

d_train = lgb.Dataset(train, label=y_train)

model2 = lgb.train(params, d_train, categorical_feature = cate_features_name)

auc2(model2, train, test)#(1.0, 0.6781812538027399)

  

3. CatBoost

  在對 CatBoost 調參時,很難對分類特徵賦予指標。所以,同時給出了不傳遞分類特徵時的調參結果,並評估了兩個模型:一個包含分類特徵,另外一個不包含。我單獨調整了獨熱最大量,由於它並不會影響其餘參數。

  若是未在cat_features參數中傳遞任何內容,CatBoost會將全部列視爲數值變量。注意,若是某一列數據中包含字符串值,CatBoost 算法就會拋出錯誤。另外,帶有默認值的 int 型變量也會默認被當成數值數據處理。在 CatBoost 中,必須對變量進行聲明,纔可讓算法將其做爲分類變量處理。

(1)不加Categorical features選項

import catboost as cb
cat_features_index = [0,1,2,3,4,5,6]

def auc(m, train, test): 
    return (metrics.roc_auc_score(y_train,m.predict_proba(train)[:,1]),
                            metrics.roc_auc_score(y_test,m.predict_proba(test)[:,1]))

params = {'depth': [4, 7, 10],
          'learning_rate' : [0.03, 0.1, 0.15],
         'l2_leaf_reg': [1,4,9],
         'iterations': [300]}
cb = cb.CatBoostClassifier()
cb_model = GridSearchCV(cb, params, scoring="roc_auc", cv = 3)
cb_model.fit(train, y_train)

# With Categorical features
clf = cb.CatBoostClassifier(eval_metric="AUC", depth=10, iterations= 500, l2_leaf_reg= 9, 
learning_rate= 0.15)
%timeit clf.fit(train,y_train)

auc(clf, train, test)#(0.7994405189483305, 0.7097991233818941)

 (2)有Categorical features選項

# With Categorical features
clf = cb.CatBoostClassifier(eval_metric="AUC",one_hot_max_size=31, \
                            depth=10, iterations= 500, l2_leaf_reg= 9, learning_rate= 0.15)
clf.fit(train,y_train, cat_features= cat_features_index)

auc(clf, train, test)#(0.7937591249216596, 0.7167802198229718)

  


   請記住,CatBoost 在測試集上表現得最好,測試集的準確度最高(0.716)、過擬合程度最小(在訓練集和測試集上的準確度很接近)以及最小的預測和調試時間。但這個表現僅僅在有分類特徵,並且調節了獨熱最大量時纔會出現。若是不利用 CatBoost 算法在這些特徵上的優點,它的表現效果就會變成最差的:僅有 0.709 的準確度。所以咱們認爲,只有在數據中包含分類變量,同時咱們適當地調節了這些變量時,CatBoost 纔會表現很好。

  第二個使用的是 XGBoost,它的表現也至關不錯。即便不考慮數據集包含有轉換成數值變量以後能使用的分類變量,它的準確率也和 CatBoost 很是接近了。可是,XGBoost 惟一的問題是:它太慢了。尤爲是對它進行調參,很是使人崩潰。更好的選擇是分別調參,而不是使用 GridSearchCV。

  最後一個模型是 LightGBM,這裏須要注意的一點是,在使用 CatBoost 特徵時,LightGBM 在訓練速度和準確度上的表現都很是差。我認爲這是由於它在分類數據中使用了一些修正的均值編碼方法,進而致使了過擬合(訓練集準確率很是高:1.0,尤爲是和測試集準確率相比之下)。但若是咱們像使用 XGBoost 同樣正常使用 LightGBM,它會比 XGBoost 更快地得到類似的準確度,若是不是更高的話(LGBM—0.681, XGBoost—0.699)。

  最後必須指出,這些結論在這個特定的數據集下成立,在其餘數據集中,它們可能正確,也可能並不正確。但在大多數狀況下,XGBoost 都比另外兩個算法慢。

4、優缺點

優勢:

  • 性能卓越:在性能方面能夠匹敵任何先進的機器學習算法;
  • 魯棒性/強健性:它減小了對不少超參數調優的需求,並下降了過分擬合的機會,這也使得模型變得更加具備通用性;
  • 易於使用:提供與scikit集成的Python接口,以及R和命令行界面;
  • 實用:能夠處理類別型、數值型特徵;可擴展:支持自定義損失函數



 

參考文獻:

【1】從結構到性能,一文概述XGBoost、Light GBM和CatBoost的同與不一樣

【2】CatBoost vs. Light GBM vs. XGBoost

【3】Catboost學習筆記

【4】機器學習算法之Catboost

【5】github:https://github.com/catboost/catboost/tree/master/catboost/tutorials

【6】Python3機器學習實踐:集成學習之CatBoost

相關文章
相關標籤/搜索