XGBoost、LightGBM的詳細對比介紹


sklearn集成方法

集成方法的目的是結合一些基於某些算法訓練得到的基學習器來改進其泛化能力和魯棒性(相對單個的基學習器而言)
主流的兩種做法分別是:

bagging

基本思想

獨立的訓練一些基學習器(一般傾向於強大而復雜的模型比如完全生長的決策樹),然后綜合他們的預測結果,通常集成模型的效果會優於基學習器,因為模型的方差有所降低。

常見變體(按照樣本采樣方式的不同划分)

  • Pasting:直接從樣本集里隨機抽取的到訓練樣本子集
  • Bagging:自助采樣(有放回的抽樣)得到訓練子集
  • Random Subspaces:列采樣,按照特征進行樣本子集的切分
  • Random Patches:同時進行行采樣、列采樣得到樣本子集

sklearn-bagging

學習器

  • BaggingClassifier
  • BaggingRegressor

參數

  • 可自定義基學習器
  • max_samples,max_features控制樣本子集的大小
  • bootstrap,bootstrap_features控制是否使用自主采樣法
    • 當使用自助采樣法時,可以設置參數oob_score=True來通過包外估計來估計模型的泛化誤差(也就不需要進行交叉驗證了)

Note:方差的產生主要是不同的樣本訓練得到的學習器對於同一組測試集做出分類、預測結果的波動性,究其原因是基學習器可能學到了所供學習的訓練樣本中的局部特征或者說是擬合了部分噪聲數據,這樣綜合不同的學習器的結果,采取多數表決(分類)或者平均(回歸)的方法可以有效改善這一狀況

sklearn-forests of randomized trees

學習器

  • RandomForest: 采取自主采樣法構造多個基學習器,並且在學習基學習器時,不是使用全部的特征來選擇最優切分點,而是先隨機選取一個特征子集隨后在特征子集里挑選最優特征進行切分;這種做法會使得各個基學習器的偏差略微提升,但在整體上降低了集成模型的方差,所以會得到整體上不錯的模型
    • RandomForestClassifier
    • RandomForestRegressor

Notes:

  • 不同於原始的模型實現(讓各個基學習器對樣本的分類進行投票),sklearn里隨機森林的實現是通過將各個基學習器的預測概率值取平均來得到最終分類
  • 隨機森林的行采樣(bagging)和列采樣(feature bagging)都是為了減小模型之間的相關性使基學習器變得不同從而減小集成模型的方差

  • Extra-Trees(extremely randomized trees):相較於rf進一步增強了隨機性,rf是對各個基學習器隨機挑選了部分特征來做維特征子集從中挑選最佳的特征切分,而Extra-Trees更進一步,在特征子集里挑選最佳特征時不是選擇最有區分度的特征值,而是隨機選擇這一划分的閾值(該閾值在子特征集里的特征對應的采樣后的樣本取值范圍里隨機選取),而不同的隨機閾值下的特征中表現最佳的作為划分特征,這樣其實增強了隨機性,更進一步整大了基學習器的偏差但降低了整體的方差

    • ExtraTreesClassifier
    • ExtraTreesRegressor

調參

  • 最重要的兩個參數
    • n_estimators:森林中樹的數量,初始越多越好,但是會增加訓練時間,到達一定數量后模型的表現不會再有顯著的提升
    • max_features:各個基學習器進行切分時隨機挑選的特征子集中的特征數目,數目越小模型整體的方差會越小,但是單模型的偏差也會上升,經驗性的設置回歸問題的max_features為整體特征數目,而分類問題則設為整體特征數目開方的結果
  • 其他參數
    • max_depth:樹的最大深度,經驗性的設置為None(即不設限,完全生長)
    • min_samples_split,節點最小分割的樣本數,表示當前樹節點還可以被進一步切割的含有的最少樣本數;經驗性的設置為1,原因同上
    • bootstrap,rf里默認是True也就是采取自助采樣,而Extra-Trees則是默認關閉的,是用整個數據集的樣本,當bootstrap開啟時,同樣可以設置oob_score為True進行包外估計測試模型的泛化能力
    • n_jobs,並行化,可以在機器的多個核上並行的構造樹以及計算預測值,不過受限於通信成本,可能效率並不會說分為k個線程就得到k倍的提升,不過整體而言相對需要構造大量的樹或者構建一棵復雜的樹而言還是高效的
    • criterion:切分策略:gini或者entropy,默認是gini,與樹相關
    • min_impurity_split–>min_impurity_decrease:用來進行早停止的參數,判斷樹是否進一步分支,原先是比較不純度是否仍高於某一閾值,0.19后是判斷不純度的降低是否超過某一閾值
    • warm_start:若設為True則可以再次使用訓練好的模型並向其中添加更多的基學習器
    • class_weight:設置數據集中不同類別樣本的權重,默認為None,也就是所有類別的樣本權重均為1,數據類型為字典或者字典列表(多類別)
      • balanced:根據數據集中的類別的占比來按照比例進行權重設置n_samples/(n_classes*np.bincount(y))
      • balanced_subsamples:類似balanced,不過權重是根據自助采樣后的樣本來計算

方法

  • predict(X):返回輸入樣本的預測類別,返回類別為各個樹預測概率均值的最大值
  • predict_log_proba(X):
  • predict_proba(X):返回輸入樣本X屬於某一類別的概率,通過計算隨機森林中各樹對於輸入樣本的平均預測概率得到,每棵樹輸出的概率由葉節點中類別的占比得到
  • score(X,y):返回預測的平均准確率

特征選擇

特征重要性評估:一棵樹中的特征的排序(比如深度)可以用來作為特征相對重要性的一個評估,居於樹頂端的特征相對而言對於最終樣本的划分貢獻最大(經過該特征划分所涉及的樣本比重最大),這樣可以通過對比各個特征所划分的樣本比重的一個期望值來評估特征的相對重要性,而在隨機森林中,通過對於不同樹的特征的期望取一個平均可以減小評估結果的方差,以供特征選擇;在sklearn中這些評估最后被保存在訓練好的模型的參數featureimportances里,是各個特征的重要性值經過歸一化的結果,越高代表特征越匹配預測函數

Notes:

  • 此外sklearn還有一種RandomTreesEmbedding的實現,不是很清楚有何特殊用途

隨機森林與KNN

  • 相似之處:均屬於所謂的權重近鄰策略(weighted neighborhoods schemes):指的是,模型通過訓練集來通過輸入樣本的近鄰樣本點對輸入樣本作出預測,通過一個帶權重的函數關系

boosting

基本思想

一個接一個的(串行)訓練基學習器,每一個基學習器主要用來修正前面學習器的偏差。

sklearn-AdaBoost

  • AdaBoost可用於分類和回歸
    • AdaBoostClassifier
    • AdaBoostRegressor
  • 參數
    • n_estimators:基學習器數目
    • learning_rate:學習率,對應在最終的繼承模型中各個基學習器的權重
    • base_estimator:基學習器默認是使用決策樹樁

_Notes:調參的關鍵參數是基學習器的數量n_estimators以及基學習器本身的復雜性比如深度max_depth或者葉節點所需的最少樣本數min_samples_leaf_

sklearn-GBRT

概述

Gradient Tree Boosting或者說GBRT是boosting的一種推廣,是的可以應用一般的損失函數,可以處理分類問題和回歸問題,應用廣泛,常見應用場景比如網頁搜索排序和社會生態學

優缺點

  • 優點:
    • 能夠直接處理混合類型的特征
    • 對輸出空間的異常值的魯棒性(通過魯棒的損失函數)
  • 缺點:
    • 難以並行,因為本身boosting的思想是一個接一個的訓練基學習器

學習器

  • GradientBoostingClassifier

    • 支持二分類和多分類
    • 參數控制:
      • 基學習器的數量n_estimators
      • 每棵樹的大小可以通過樹深max_depth或者葉節點數目max_leaf_nodes來控制(注意兩種樹的生長方式不同,max_leaf_nodes是針對葉節點優先挑選不純度下降最多的葉節點,這里有點LightGBM的’leaf-wise’的意味,而按樹深分裂則更類似於原始的以及XGBoost的分裂方式)
      • 學習率learning_rate對應取值范圍在(0,1]之間的超參數對應GBRT里的shrinkage來避免過擬合(是sklearn里的GBDT用來進行正則化的一種策略);
      • 對於需要多分類的問題需要設置參數n_classes對應每輪迭代的回歸樹,這樣總體樹的數目是n_classes*n_estimators
      • criterion用來設置回歸樹的切分策略
        • friedman_mse,對應的最小平方誤差的近似,加入了Friedman的一些改進
        • mse對應最小平方誤差
        • mae對應平均絕對值誤差
      • subsample:行采樣,對樣本采樣,即訓練每個基學習器時不再使用原始的全部數據集,而是使用一部分,並且使用隨機梯度上升法來做集成模型的訓練
      • 列采樣:max_features在訓練基學習器時使用一個特征子集來訓練,類似隨機森林的做法
      • early stopping:通過參數min_impurity_split(原始)以及min_impurity_decrease來實現,前者的是根據節點的不純度是否高於閾值,若不是則停止增長樹,作為葉節點;后者則根據分裂不純度下降值是否超過某一閾值來決定是否分裂(此外這里的early stopping似乎與XGBoost里顯示設置的early stopping不同,這里是控制樹的切分生長,而XGBoost則是控制基學習器的數目)
        另外一點,有說這里的early_stopping起到了一種正則化的效果,因為控制了葉節點的切分閾值從而控制了模型的復雜度(可參考李航《統計學習方法》P213底部提升方法沒有顯式的正則化項,通常通過早停止的方法達到正則化的效果)
      • 基學習器的初始化:init,用來計算初始基學習器的預測,需要具備fitpredict方法,若未設置則默認為loss.init_estimator
      • 模型的重復使用(熱啟動):warm_start,若設置為True則可以使用已經訓練好的學習器,並且在其上添加更多的基學習器
      • 預排序:presort,默認設置為自動,對樣本按特征值進行預排序從而提高尋找最優切分點的效率,自動模式下對稠密數據會使用預排序,而對稀疏數據則不會
      • 損失函數(loss)
        • 二分類的對數損失函數(Binomial deviance,’deviance’),提供概率估計,模型初值設為對數幾率
        • 多分類的對數損失(Multinomial deviance,’deviance’),針對n_classes互斥的多分類,提供概率估計,初始模型值設為各類別的先驗概率,每一輪迭代需要構建n類回歸樹可能會使得模型對於多類別的大數據集不太高效
        • 指數損失函數(Exponential loss),與AdaBoostClassifier的損失函數一致,相對對數損失來說對錯誤標簽的樣本不夠魯棒,只能夠被用來作二分類
    • 常用方法
      • 特征重要性(feature_importances_):進行特征重要性的評估
      • 包外估計(oob_improvement_),使用包外樣本來計算每一輪訓練后模型的表現提升
      • 訓練誤差(train_score_)
      • 訓練好的基學習器集合(estimators_)
      • fit方法里可以設置樣本權重sample_weight,monitor可以用來回調一些方法比如包外估計、早停止等
  • GradientBoostingRegressor

    • 支持不同的損失函數,通過參數loss設置,默認的損失函數是最小均方誤差ls
    • 通過屬性train_score_可獲得每輪訓練的訓練誤差,通過方法staged_predict可以獲得每一階段的測試誤差,通過屬性feature_importances_可以輸出模型判斷的特征相對重要性
    • 損失函數:
      • 最小均方誤差(Least squares,’ls’),計算方便,一般初始模型為目標均值
      • 最小絕對值誤差(Least absolute deviation,’lad’),初始模型為目標中位值
      • Huber,一種結合了最小均方誤差和最小絕對值誤差的方法,使用參數alpha來控制對異常點的敏感情況

正則化

  • Shrinkage,對應參數learning rate一種簡單的正則化的策略,通過控制每一個基學習器的貢獻,會影響到基學習器的數目即n_estimators,經驗性的設置為一個較小的值,比如不超過0.1的常數值,然后使用early stopping來控制基學習器的數目
  • 行采樣,使用隨機梯度上升,將gradient boosting與bagging相結合,每一次迭代通過采樣的樣本子集來訓練基學習器(對應參數subsample),一般設置shrinkage比不設置要好,而加上行采樣會進一步提升效果,而僅使用行采樣可能效果反而不佳;而且進行行采樣后可使用包外估計來計算模型每一輪訓練的效果提升,保存在屬性oob_improvement_里,可以用來做模型選擇,但是包外預估的結果通常比較悲觀,所以除非交叉驗證太過耗時,否則建議結合交叉驗證一起進行模型選擇
  • 列采樣,類似隨機森林的做法,通過設置參數max_features來實現

可解釋性

單一的決策樹可以通過將樹結構可視化來分析和解釋,而梯度上升模型因為由上百課回歸樹組成因此他們很難像單獨的決策樹一樣被可視化,不過也有一些技術來輔助解釋模型

  • 特征重要性(featureimportances屬性),決策樹在選擇最佳分割點時間接地進行了特征的選擇,而這一信息可以用來評估每一個特征的重要性,基本思想是一個特征越經常地被用來作為樹的切分特征(更加說明使用的是CART樹或其變體,因為ID3,C4.5都是特征用過一次后就不再用了),那么這個特征就越重要,而對於基於樹的集成模型而言可以通過對各個樹判斷的特征重要性做一個平均來表示特征的重要性
  • PDP(Partial dependence plots),可以用來繪制目標響應與目標特征集的依賴關系(控制其他的特征的值),受限於人類的感知,目標特征集合一般設置為1或2才能繪制對應的圖形(plot_partial_dependence),也可以通過函數partial_dependence來輸出原始的值

Notes:

  • GradientBoostingClassifier和GradientBoostingRegressor均支持對訓練好的學習器的復用,通過設置warm_start=True可以在已經訓練好的模型上添加更多的基學習器

VotingClassifier

Voting的基本思想是將不同學習器的結果進行硬投票(多數表決)或者軟投票(對預測概率加權平均)來對樣本類別做出預估,其目的是用來平衡一些表現相當且都還不錯的學習器的表現,以消除它們各自的缺陷

  • 硬投票(voting=’hard’):按照多數表決原則,根據分類結果中多數預測結果作為輸入樣本的預測類別,如果出現類別數目相同的情況,會按照預測類別的升序排序取前一個預測類別(比如模型一預測為類別‘2’,模型二預測為類別‘1’則樣本會被判為類別1)
  • 軟投票:對不同基學習器的預測概率進行加權平均(因此使用軟投票的基學習器需要能夠預測概率),需設置參數wights為一個列表表示各個基學習器的權重值

XGBoost

過擬合

XGBoost里可以使用兩種方式防止過擬合

  • 直接控制模型復雜度
    • max_depth,基學習器的深度,增加該值會使基學習器變得更加復雜,榮易過擬合,設為0表示不設限制,對於depth-wise的基學習器學習方法需要控制深度
    • min_child_weight,子節點所需的樣本權重和(hessian)的最小閾值,若是基學習器切分后得到的葉節點中樣本權重和低於該閾值則不會進一步切分,在線性模型中該值就對應每個節點的最小樣本數,該值越大模型的學習約保守,同樣用於防止模型過擬合
    • gamma,葉節點進一步切分的最小損失下降的閾值(超過該值才進一步切分),越大則模型學習越保守,用來控制基學習器的復雜度(有點LightGBM里的leaf-wise切分的意味)
  • 給模型訓練增加隨機性使其對噪聲數據更加魯棒
    • 行采樣:subsample
    • 列采樣:colsample_bytree
    • 步長:eta即shrinkage

數據類別分布不均

對於XGBoost來說同樣是兩種方式

  • 若只關注預測的排序表現(auc)
    • 調整正負樣本的權重,使用scale_pos_weight
    • 使用auc作為評價指標
  • 若關注預測出正確的概率值,這種情況下不能調整數據集的權重,可以通過設置參數max_delta_step為一個有限值比如1來加速模型訓練的收斂

調參

一般參數

主要用於設置基學習器的類型

  • 設置基學習器booster
    • 基於樹的模型
      • gbtree
      • dart
    • 線性模型
      • gblinear
  • 線程數nthread,設置並行的線程數,默認是最大線程數

基學習器參數

在基學習器確定后,根據基學習器來設置的一些個性化的參數

  • eta,步長、學習率,每一輪boosting訓練后可以得到新特征的權重,可以通過eta來適量縮小權重,使模型的學習過程更加保守一點,以防止過擬合
  • gamma,葉節點進一步切分的最小損失下降的閾值(超過該值才進一步切分),越大則模型學習越保守,用來控制基學習器的復雜度(有點LightGBM里的leaf-wise切分的意味)
  • max_depth,基學習器的深度,增加該值會使基學習器變得更加復雜,榮易過擬合,設為0表示不設限制,對於depth-wise的基學習器學習方法需要控制深度
  • min_child_weight,子節點所需的樣本權重和(hessian)的最小閾值,若是基學習器切分后得到的葉節點中樣本權重和低於該閾值則不會進一步切分,在線性模型中該值就對應每個節點的最小樣本數,該值越大模型的學習約保守,同樣用於防止模型過擬合
  • max_delta_step,樹的權重的最大估計值,設為0則表示不設限,設為整數會是模型學習相對保守,一般該參數不必設置,但是對於基學習器是LR時,在針對樣本分布極為不均的情況控制其值在1~10之間可以控制模型的更新
  • 行采樣:subsample,基學習器使用樣本的比重
  • 列采樣:
    • colsample_bytree,用於每棵樹划分的特征比重
    • colsample_bylevel,用於每層划分的特征比重
  • 顯式正則化,增加該值是模型學習更為保守
    • L1:alpha
    • L2:lambda
  • tree_method,樹的構建方法,准確的說應該是切分點的選擇算法,包括原始的貪心、近似貪心、直方圖算法(可見LightGBM這里並不是一個區別)
    • auto,啟發式地選擇分割方法,近似貪心或者貪心
    • exact,原始的貪心算法,既針對每一個特征值切分一次
    • approx,近似的貪心算法選取某些分位點進行切分,使用sketching和histogram
    • hist,直方圖優化的貪心算法,對應的參數有grow_policy,max_bin
    • gpu_exact
    • gpu_hist
  • scale_pos_weight,針對數據集類別分布不均,典型的值可設置為
    sum(negativecases)sum(positivecases)sum(negativecases)sum(positivecases)
  • grow_policy,控制樹的生長方式,目前只有當樹的構建方法tree_method設置為hist時才可以使用所謂的leaf-wise生長方式
    • depthwise,按照離根節點最近的節點進行分裂
    • lossguide,優先分裂損失變化大的節點,對應的一個參數還有max_leaves,表示可增加的最大的節點數
  • max_bin,同樣針對直方圖算法tree_method設置為hist時用來控制將連續特征離散化為多個直方圖的直方圖數目
  • predictor,選擇使用GPU或者CPU
    • cpu_predictor
    • gpu_predictor

任務參數

根據任務、目的設置的參數,比如回歸任務與排序任務的目的是不同的

  • objective,訓練目標,分類還是回歸
    • reg:linear,線性回歸
    • reg:logistic,邏輯回歸
    • binary:logistic,使用LR二分類,輸出概率
    • binary:logitraw,使用LR二分類,但在進行logistic轉換之前直接輸出分類得分
    • count:poisson,泊松回歸
    • multi:softmax,使用softmax進行多分類,需要設置類別數num_class
    • multi:softprob
    • rank:pairwise,進行排序任務,最小化pairwise損失
    • reg:gamma,gamma回歸
    • reg:tweedie,tweedie回歸
  • 評價指標eval_metric,默認根據目標函數設置,針對驗證集,默認情況下,最小均方誤差用於回歸,錯分用於分類,平均精確率用於排序等,可以同時使用多個評估指標,在python里使用列表來放置
    • 均方誤差rmse
    • 平均絕對值誤差mae
    • 對數損失logloss,負的對數似然
    • 錯誤率error,根據0.5作為閾值判斷的錯分率
    • 自定義閾值錯分率error@t
    • 多分類錯分率merror
    • 多分類對數損失mlogloss
    • auc主要用來排序
    • ndcg,normalized discounted cumulative gain及其他的一些針對泊松回歸等問題的評價指標

命令行參數

  • num_round迭代次數,也對應基學習器數目
  • task當前對模型的任務,包括
    • 訓練train
    • 預測pred
    • 評估/驗證eval
    • 導出模型dump
  • 導入導出模型的路徑model_inmodel_out
  • fmap,feature map用來導出模型

LightGBM

特點

效率和內存上的提升

直方圖算法,LightGBM提供一種數據類型的封裝相對Numpy,Pandas,Array等數據對象而言節省了內存的使用,原因在於他只需要保存離散的直方圖,LightGBM里默認的訓練決策樹時使用直方圖算法,XGBoost里現在也提供了這一選項,不過默認的方法是對特征預排序,直方圖算法是一種犧牲了一定的切分准確性而換取訓練速度以及節省內存空間消耗的算法

  • 在訓練決策樹計算切分點的增益時,預排序需要對每個樣本的切分位置計算,所以時間復雜度是O(#data)而LightGBM則是計算將樣本離散化為直方圖后的直方圖切割位置的增益即可,時間復雜度為O(#bins),時間效率上大大提高了(初始構造直方圖是需要一次O(#data)的時間復雜度,不過這里只涉及到加和操作)
  • 直方圖做差進一步提高效率,計算某一節點的葉節點的直方圖可以通過將該節點的直方圖與另一子節點的直方圖做差得到,所以每次分裂只需計算分裂后樣本數較少的子節點的直方圖然后通過做差的方式獲得另一個子節點的直方圖,進一步提高效率
  • 節省內存
    • 將連續數據離散化為直方圖的形式,對於數據量較小的情形可以使用小型的數據類型來保存訓練數據
    • 不必像預排序一樣保留額外的對特征值進行預排序的信息
  • 減少了並行訓練的通信代價

稀疏特征優化

對稀疏特征構建直方圖時的時間復雜度為O(2*#非零數據)

准確率上的優化

LEAF-WISE(BEST-FIRST)樹生長策略

相對於level-wise的生長策略而言,這種策略每次都是選取當前損失下降最多的葉節點進行分割使得整體模型的損失下降得更多,但是容易過擬合(特別當數據量較小的時候),可以通過設置參數max_depth來控制樹身防止出現過擬合

Notes:XGBoost現在兩種方式都是支持的

直接支持類別特征

對於類別類型特征我們原始的做法是進行獨熱編碼,但是這種做法對於基於樹的模型而言不是很好,對於基數較大的類別特征,可能會生成非常不平衡的樹並且需要一顆很深的樹才能達到較好的准確率;比較好的做法是將類別特征划分為兩個子集,直接划分方法眾多(2^(k-1)-1),對於回歸樹而言有一種較高效的方法只需要O(klogk)的時間復雜度,基本思想是對類別按照與目標標簽的相關性進行重排序,具體一點是對於保存了類別特征的直方圖根據其累計值(sum_gradient/sum_hessian)重排序,在排序好的直方圖上選取最佳切分位置

網絡通信優化

使用collective communication算法替代了point-to-point communication算法提升了效率

並行學習優化

特征並行

特征並行是為了將尋找決策樹的最佳切分點這一過程並行化

  • 傳統做法
    • 對數據列采樣,即不同的機器上保留不同的特征子集
    • 各個機器上的worker根據所分配的特征子集尋找到局部的最優切分點(特征、閾值)
    • 互相通信來從局部最佳切分點里得到最佳切分點
    • 擁有最佳切分點的worker執行切分操作,然后將切分結果傳送給其他的worker
    • 其他的worker根據接收到的數據來切分數據
    • 傳統做法的缺點
      • 計算量太大,並沒有提升切分的效率,時間復雜度為O(#data)(因為每個worker持有所有行,需要處理全部的記錄),當數據量較大時特征並行並不能提升速度
      • 切分結果的通信代價,大約為O(#data/8)(若一個數據樣本為1bit)
  • LightGBM的做法
    讓每個機器保留整個完整的數據集(並不是經過列采樣的數據),這樣就不必在切分后傳輸切分結果數據,因為每個機器已經持有完整的數據集
    • 各個機器上的worker根據所分配的特征子集尋找到局部的最優切分點(特征、閾值)
    • 互相通信來從局部最佳切分點里得到最佳切分點
    • 執行最優切分操作

Notes:典型的空間換時間,差別就是減少了傳輸切分結果的步驟,節省了這里的通信消耗

數據並行

上述特征並行的方法並沒有根本解決尋找切分點的計算效率問題,當記錄數過大時需要考慮數據並行的方法

  • 傳統做法
    • 行采樣,對數據進行橫向切分
    • worker使用分配到的局部數據構建局部的直方圖
    • 合並局部直方圖得到全局的直方圖
    • 對全局直方圖尋找最優切分點,然后進行切分
    • 缺點:通信代價過高,若使用point-to-point的通信算法,每個機器的通信代價時間復雜度為O(#machine*#feature*#bin),若使用collective通信算法則通信代價為O(2*#feature*#bin)
  • LightGBM的做法(依然是降低通信代價)
    • 不同於合並所有的局部直方圖獲得全局的直方圖,LightGBM通過Reduce Scatter方法來合並不同worker的無交叉的不同特征的直方圖,這樣找到該直方圖的局部最優切分點,最后同步到全局最優切分點
    • 基於直方圖做差的方法,在通信的過程中可以只傳輸某一葉節點的直方圖,而對於其鄰居可通過做差的方式得到
    • 通信的時間復雜度為O(0.5*#feature*#bin)

並行投票

進一步減小了數據並行中的通信代價,通過兩輪的投票來減小特征直方圖中的通信消耗

其他特點

直接支持類別(標稱)特征

LightGBM可以直接用類別特征進行訓練,不必預先進行獨熱編碼,速度會提升不少,參數設置categorical_feature來指定數據中的類別特征列

早停止

sklearn-GBDT,XGBoost,LightGBM都支持早停止,不過在細節上略有不同

  • sklearn-GBDT中的early stopping是用來控制基學習器的生長的:通過參數min_impurity_split(原始)以及min_impurity_decrease來實現,前者的是根據節點的不純度是否高於閾值,若不是則停止增長樹,作為葉節點;后者則根據分裂不純度下降值是否超過某一閾值來決定是否分裂(此外這里的early stopping似乎與XGBoost里顯示設置的early stopping不同,這里是控制樹的切分生長,而XGBoost則是控制基學習器的數目)
  • XGBoost和LightGBM里的early_stopping則都是用來控制基學習器的數目的
    • 兩者都可以使用多組評價指標,但是不同之處在於XGBoost會根據指標列表中的最后一項指標控制模型的早停止,而LightGBM則會受到所有的評估指標的影響
    • 在使用early stopping控制迭代次數后,模型直接返回的是最后一輪迭代的學習器不一定是最佳學習器,而在做出預測時可以設置參數選擇某一輪的學習器作出預測
      • XGBoost里保存了三種狀態的學習器,分別是bst.best_score, bst.best_iteration, bst.best_ntree_limit,官方的建議是在做預測時設置為bst.best_ntree_limit,實際使用時感覺bst.best_iteration和 bst.best_ntree_limit的表現上區別不大
      • LightGBM則僅提供了bst.best_iteration這一種方式

實踐上

  • 內置cv
  • 支持帶權重的數據輸入
  • 可以保留模型
  • DART
  • L1/L2回歸
  • 保存模型進行進一步訓練
  • 多組驗證集

支持的任務

  • 回歸任務
  • 分類(二分類、多分類)
  • 排序

支持的評價指標METRIC

  • 絕對值誤差l1
  • 平方誤差l2
  • 均方誤差l2_root
  • 對數損失binary_logloss,multi_logloss
  • 分類誤差率binary_error,multi_error
  • auc
  • ndcg
  • 多分類對數損失
  • 多分類分類誤差率

調參

核心參數

  • 葉節點數num_leaves,與模型復雜度直接相關(leaf-wise)
  • 任務目標
    • 回歸regression,對應的損失函數如下
      • regression_l1,加了l1正則的回歸,等同於絕對值誤差
      • regression_l2,等同於均方誤差
      • huber,Huber Loss
      • fair,Fair Loss
      • poisson,泊松回歸
    • 分類
      • binary,二分類
      • multiclass,多分類
    • 排序
      • lambdarank
  • 模型
    • boosting
      • gbdt,傳統的梯度提升決策樹
      • rf,隨機森林
      • dart,Dropouts meet Multiple Additive Regression Trees
      • goss,Gradient-based One-Side Sampling
  • 迭代次數num_iterations,對於多分類問題,LightGBM會構建num_class*num_iterations的樹
  • 學習率/步長learning_rate,即shrinkage
  • 樹的訓練方式tree_learner,主要用來控制樹是否並行化訓練
    • serial,單機的樹學習器
    • feature,特征並行的樹學習器
    • data,數據並行的樹學習器
  • 線程數num_threads
  • 設備device,使用cpu還是gpu
    • cpu
    • gpu

訓練控制參數

防止過擬合

  • 樹的最大深度max_depth,主要用來避免模型的過擬合,設為負數值則表明不限制
  • 葉節點的最少樣本數min_data_in_leaf
  • 葉節點的最小海森值之和min_sum_hessian_in_leaf
  • 列采樣feature_fraction,每棵樹的特征子集占比,設置在0~1之間,可以加快訓練速度,避免過擬合
  • 行采樣bagging_fraction,不進行重采樣的隨機選取部分樣本數據,此外需要設置參數bagging_freq來作為采樣的頻率,即多少輪迭代做一次bagging;
  • 早停止early_stopping_roung,在某一驗證數據的某一驗證指標當前最后一輪迭代沒有提升時停止迭代
  • 正則化
    • lambda_l1
    • lambda_l2
  • 切分的最小收益min_gain_to_split

IO參數

直方圖相關

  • 最大直方圖數max_bin,特征值裝載的最大直方圖數目,一般較小的直方圖數目會降低訓練的准確性但會提升整體的表現,處理過擬合
  • 直方圖中最少樣本數min_data_in_bin,設置每個直方圖中樣本數的最小值,同樣防止過擬合

特征相關

  • 是否預排序is_pre_partition
  • 是否稀疏is_sparse
  • 類別特征列categorical_feature,聲明類別特征對應的列(通過索引標記),僅支持int類型
  • 聲明權重列weight,指定一列作為權重列

內存相關

  • 分階段加載數據two_round,一般LightGBM將數據載入內存進行處理,這樣會提升數據的加載速度,但是對於數據量較大時會造成內存溢出,所以此時需要分階段載入
  • 保存數據為二進制save_binary,將數據文件導出為二進制文件,下次加載數據時就會更快一些

缺失值

  • 是否處理缺失值use_missing
  • 是否將0值作為缺失值zeros_as_missing

目標參數

  • sigmoid,sigmoid函數中的參數,用於二分類和排序任務
  • scale_pos_weight,設置正例在二分類任務中的樣本占比
  • 初始化為均值boost_from_average,調整初始的分數為標簽的均值,加速模型訓練的收斂速度,僅用於回歸任務
  • 樣本類別是否不平衡is_unbalance
  • num_class,用於多分類

調參小結

LEAF-WISE

  • num_leaves,對於leaf-wise的模型而言該參數是用來控制模型復雜度的主要參數,理論上可以通過設置num_leaves=2^(max_depth)來設置該參數值,實際是不可取的,因為在節點數目相同的前提下,對於leaf-wise的模型會傾向於生成深度更深的模型,如果生硬的設置為2^(max_depth)可能會造成模型的過擬合,一般設置的值小於2^(max_depth),
  • min_data_in_leaf,在設置了葉節點數后,該值會對模型復雜度造成影響,若設的較大則樹不會生長的很深,但可能造成模型的欠擬合
  • max_depth

效率

  • bagging_fractionbagging_freq,使用bagging進行行采樣提升訓練速度(減小了數據集)
  • feature_fraction,列采樣
  • 設置較少的直方圖數目,max_bin
  • 保存數據為二進制文件以便於未來訓練時能快速加載,save_binary
  • 通過並行訓練來提速

准確率

  • 設置較大的直方圖數目max_bin,當然這樣會犧牲訓練速度
  • 使用較小的學習率learning_rate,這樣會增加迭代次數
  • 設置較大的葉節點數num_leaves,可能造成模型過擬合
  • 使用較大的訓練數據
  • 嘗試dart模型

過擬合

  • 設置較少的直方圖數目,max_bin
  • 設置較小的葉節點數num_leaves
  • 設置參數min_data_in_leafmin_sum__hessian_in_leaf
  • 使用bagging進行行采樣bagging_fractionbagging_freq
  • feature_fraction,列采樣
  • 使用較大的訓練數據
  • 正則化
    • lambda_l1
    • lambda_l2
    • 切分的最小收益min_gain_to_split
  • 控制樹深max_depth

總結

GBDT vs. XGBoost vs. LightGBM(論文層面)

GBDT vs. XGBoost

  • GBDT無顯式正則化
  • GBDT僅使用了目標函數一階泰勒展開,而XGBoost使用了二階的泰勒展開值
    • 為什么二階展開?
      • 一說加快收斂速度
      • 另外有說本身模型訓練的學習率shrinkage可以通過二階導數做一個逼近,而原始的GBDT沒有計算這個,所以一般是通過預設的超參數eta人為指定
  • XGBoost加入了列采樣
  • XGBoost對缺失值的處理
  • XGBoost通過預排序的方法來實現特征並行,提高模型訓練效率
  • XGBoost支持分布式計算

XGBoost vs. LightGBM

  • 樹的切分策略不同
    • XGBoost是level-wise而LightGBM是leaf-wise
  • 實現並行的方式不同
    • XGBoost是通過預排序的方式
    • LightGBM則是通過直方圖算法
  • LightGBM直接支持類別特征,對類別特征不必進行獨熱編碼處理

sklearn GBDT vs. XGBoost vs. LightGBM(實現層面)

實際在庫的實現層面原始論文里的很多區別是不存在的,差異更多在一些工程上的性能優化

sklearn GBDT vs. XGBoost

  • 正則化方式不同
    • sklearn GBDT中僅僅通過學習率來做一個正則化(影響到基學習器的數目),此外gbdt里的early stopping也達到了一個正則化的效果,對應的主要參數是min_impurity_split即控制了判斷葉節點是否進一步切分的不純度的閾值,若超過該閾值則可以進一步切分,否則不行,故而控制了樹的深度即控制了基學習器的復雜度
    • XGBoost除了學習率以外還有顯示的設置正則化項l1,l2以及對應論文里的葉節點數(對應參數gamma)以及節點權重和(參數min_child_weight)來控制模型復雜度
  • GBDT僅使用了目標函數一階泰勒展開,而XGBoost使用了二階的泰勒展開值
  • XGBoost自有一套對缺失值的處理方法
  • early-stopping意義不同
    • sklearn GBDT中控制基學習器進一步切分、生長
    • XGBoost控制基學習器的數目
  • 特征重要性的判斷標准
    • sklearn GBDT是根據樹的節點特征對應的深度來判斷
    • XGBoost則有三種方法(get_score)
      • weight:特征用來作為切分特征的次數
      • gain:使用特征進行切分的平均增益
      • cover:各個樹中該特征平均覆蓋情況(根據樣本?)
  • 樹的切分算法
    • XGBoost存在三種切分方法,
      • 原始的貪心算法(每個特征值切分)
      • 近似貪心(分位點切分)(使得對於大量的特征取值尤其是連續變量時XGBoost會比sklearn-gbdt快很多)
      • 直方圖算法
  • XGBoost支持level-wise和leaf-wise兩種樹的生長方式
  • XGBoost支持GPU
  • XGBoost支持多種評價標准、支持多種任務(回歸、分類、排序)

XGBoost vs. LightGBM

XGBoost目前已經實現了LightGBM之前不同的一些方法比如直方圖算法,兩者的區別更多的在與LightGBM優化通信的的一些處理上

    • LightGBM直接支持類別特征,可以不必預先進行獨熱編碼,提高效率(categorical_feature)
    • 優化通信代價
      • 特征並行
      • 數據並行
      • point to point communication–>collective communication
    • 使用多項評價指標同時評價時兩者的早停止策略不同,XGBoost是根據評價指標列表中的最后一項來作為停止標准,而LightGBM則受到所有評價指標的影響

轉載自:懶死駱駝: http://izhaoyi.top/2017/09/23/sklearn-xgboost/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM