參考資料
- https://www.codenong.com/cs106234234/ CatBoost官方教程:調參
- https://cloud.tencent.com/developer/article/1547842 【ML】一文詳盡系列之CatBoost
- https://catboost.ai/docs/features/training-on-gpu.html?lang=en catboost支持GPU
- https://zhuanlan.zhihu.com/p/102570430 catboost完全指南
- https://www.zhihu.com/question/311641149/answer/593286799 oblivious tree在機器學習中有什么用? - 李大貓的回答 - 知乎
CatBoost簡介
- 屬於Boosting算法之一,GBDT的一種改進實現
- 是一種基於對稱決策樹(oblivious trees)算法的參數少、支持類別型變量和高准確性的GBDT框架,
- 痛點:高效合理地處理類別型特征,另外是處理梯度偏差(Gradient bias)以及預測偏移(Prediction shift)問題,提高算法的准確性和泛化能力。
CatBoost主要有以下五個特性:
- 無需調參即可獲得較高的模型質量
- 支持類別型變量,無需對非數值型特征進行預處理
- 快速、可擴展的GPU版本,可以用基於GPU的梯度提升算法實現來訓練你的模型,支持多卡並行
- 提高准確性,提出一種全新的梯度提升機制來構建模型以減少過擬合
- 預測速度快
了解類別型特征
類別型變量(Categorical features)
- 特征值是離散的集合並且相互比較並無意義的變量,比如用戶的ID、產品ID、顏色等。
- 無法在二叉決策樹中直接使用,需要onehot、labelencode等
低維的特征,One-hot encoding
目前廣泛用於低勢的類別特征的處理方法,適用於類別個數有限的特征。
在高勢特征當中,進行折中: 是可以將類別分組成有限個的群體再進行 One-hot encoding
- TS:目標變量統計進行分組,目標變量統計用於估算每個類別的目標變量期望值
- 甚至有人直接用TS作為一個新的數值型變量來代替原來的類別型變量。重要的是,可以通過對TS數值型特征的閾值設置,基於對數損失、基尼系數或者均方差,得到一個對於訓練集而言將類別一分為二的所有可能划分當中最優的那個。
- 在LightGBM當中,類別型特征用每一步梯度提升時的梯度統計(Gradient Statistics,以下簡稱GS)來表示。雖然為建樹提供了重要的信息,但是這種方法有以下兩個缺點:
- 增加計算時間,因為需要對每一個類別型特征,在迭代的每一步,都需要對GS進行計算;
- 增加存儲需求,對於一個類別型變量,需要存儲每一次分離每個節點的類別
為了克服這些缺點,LightGBM以損失部分信息為代價將所有的長尾類別歸位一類,作者聲稱這樣處理高勢特征時比起 One-hot encoding還是好不少。不過如果采用TS特征,那么對於每個類別只需要計算和存儲一個數字。
了解 Target statistics (目標變量統計)
主要學習文章: https://zhuanlan.zhihu.com/p/136174936( 目標編碼)
用類別對應的標簽的期望來代替原始的類別,所謂的期望,簡單理解為均值(編碼)即可。
簡稱為TS.
貪心TS(Target statistics)
最直接地用訓練樣本當中相同類別的數據對應目標變量y的平均值.
(舉個例子吧,比如有10個樣本,對應的某個類別特征是:A A A A A B B B B B,則A轉換為greedy ts的形式,則要先看A對應的標簽y是啥情況,假設A A A A A對應的標簽為 1 1 1 0 1,則按照上面的公式為 (1*1+1*1+1*1+1*0+1*1)/5=0.8 )。
當然這種方式容易過擬合與訓練集,極端的例子,假設某個類別特征為個數, 那么直接擬合為100%。又稱為標簽泄露了,因此這種編碼方式基本不用了。
留出 TS (holdout TS)
留出TS,就是將訓練集一分為二,采用新的計算公式,這樣能夠滿足同分布的問題。
留一法 TS
初看起來,留一TS(leave-one-out TS)能夠非常好地工作:
- 並沒有預防目標泄露。
打分函數和損失函數
打分函數是xgboost對損失函數的處理在樹的分裂過程中的表現,這也是后xgboost時代,gbdt算法的一個比較大的改變,基樹不再是單純的cart樹使用gini進行分裂而是使用上面的梯度信息進行分裂的指導。
打分函數:catboost實現了XGBoost的打分函數的形式,也實現了原始的打分函數,同時也創造了另外四種的啟發式的打分函數。
缺失值處理
catboost處理缺失值的方法很kaggle,其實就和平常比賽的時候把缺失值替換為9999,-9999一個意思,這里簡單使用max和min其實並不是很好,你在訓練集指定的max和min可能在測試集存在更大的max值或者更小的min值。
防止過擬合
Catoost除了增加了正則項來防止過擬合,還支持行列采樣的方式來防止過擬合。
- 列采樣: 正常的采樣,參數為colsample_bylevel
- 行采樣:
- 貝葉斯采樣:每一個樣本的權重按照[0, 1]區間內隨機生成一個數字a,然后權重w = a^t
- 這里t越大則每一個樣本的權重越小,相當於xgboost的subsample的程度越深。
- 隨機賦權模式: 這里catboost是針對每一個樣本進行隨機賦權;
- 貝葉斯采樣:每一個樣本的權重按照[0, 1]區間內隨機生成一個數字a,然后權重w = a^t
Catboost的基學習器
catboost與xgboost的level-wise以及lightgbm的leaf-wise不同,catboost的基學習器使用的是完全對稱二叉樹(實際上catboost實現了多種樹的生長方式):
- 完全對稱二叉樹: 逐level構建樹,直到達到指定的深度;在每次迭代中,選取每層中最優的一種分裂方式,以相同的該種方式進行分裂樹的所有葉子結點,保持完全二叉樹的結構。
- 深度(同xgb的level-wise):逐級構建,直至最大深度;在每次迭代中,將拆分樹的所有非終端的葉子,每片葉子按條件進行分割,損失改善最佳
- 損失指南(lossguide,同lgb的leaf-wise):逐葉構建一棵樹,直到達到指定的最大葉數;在每次迭代中,將損失最佳的非終端葉子結點進行拆分。
對比xbg、lgb
- xgb:按層分裂,待分裂層的所有節點各自按照自己的最大增益進行分裂,不統一
- lgb:按葉子分裂,計算所有待分裂的葉子節點,選取增益最大的一個進行分裂
- catboost:計算所有待分裂的葉子節點,選取增益最大的一個,葉子結點層統一進行分裂
catboost處理分類變量
默認來說,CatBoost會且僅會對所有取值nunique==2的特征進行onehot編碼。
CatBoost 可賦予分類變量指標,進而通過獨熱最大量得到獨熱編碼形式的結果(獨熱最大量:在所有特征上,對小於等於某個給定參數值的不同的數使用獨熱編碼)。
如果在 CatBoost 語句中沒有設置「跳過」,CatBoost 就會將所有列當作數值變量處理。
注意,如果某一列數據中包含字符串值,CatBoost 算法就會拋出錯誤。另外,帶有默認值的 int 型變量也會默認被當成數值數據處理。在 CatBoost 中,必須對變量進行聲明,才可以讓算法將其作為分類變量處理。
catboost類別特征的處理(ordered ts)
對比:
- lgb:直方圖
- catboost:主要使用統計特征對類別進行編碼
下面主要介紹catboost的一種ts編碼轉換方式——buckets (簡記為:加權累加和混合編碼)
首先,按行將數據隨機shuffle,並且標簽也跟着一起shuffle的;
(需要特別提到的是,catboost每次生成新樹的時候都會shuffle一下訓練數據然后重新計算類別特征的編碼值)
其次
one_hot_max_size 限制獨熱編碼
one_hot_max_size 來決定是否對類別特征進行編碼操作,當類別數量超過one_hot_max_size之后才進行編碼,否則默認是2以上不再onehot;
自帶特征組合,如顏色+種類組合成 “blue+dog”
CatBoost只考慮一部分combinations。在選擇第一個節點時,只考慮選擇一個特征,例如A。在生成第二個節點時,考慮A和任意一個categorical feature的組合,選擇其中最好的。就這樣使用貪心算法生成combinations。
梯度偏差的優化 (gradient bias)—— ordered boosting
原始的gbdt無行列采樣,所有的base tree都在同一個完整的訓練數據集上擬合,然而和rf不一樣的是,gbdt中的tree都不是獨立訓練的,而是用上一輪的tree計算得到的負梯度為標簽繼續訓練,這就導致了如果上一輪的tree計算產生了偏差,這個偏差會繼續在下一輪累計,那么假設訓練集和測試集的分布差異較大,則偏差會在base trees中瘋狂累計,從而使得整個gbdt過度擬合訓練集。
通過行列采樣可以在一定程度上緩解這個問題,catboost不僅僅學習xgboost引入行列采樣(子采樣)、引入樹的正則化這種從超參數層面控制過擬合程度的方面開發,更是在tree訓練的過程中采用ordered boosting的方式來緩解這種過擬合。
catboost實際上是支持兩種boosting模式的:
- 排序:根據這里的描述,在小型的數據集上能夠提供更好的結果,但是耗時。不支持GPU。(官網給的建議是樣本不超過5萬可以考慮ordered的boosting type。)
- 白板:plain表示常規的gbdt的boosting模式,支持GPU
ordered boosting詳細說明
https://pic2.zhimg.com/80/v2-a6681768f9e48d982552bae7e16109d5_720w.jpg
主要特點
- 在CatBoost中,我們生成訓練數據集的s個隨機排列。采用多個隨機排列是為了增強算法的魯棒性
- 在Odered TS中,針對每一個隨機排列,計算得到其梯度,為了與Ordered TS保持一致,這里ordered boosting的排列與用於計算Ordered TS時的排列相同。(也就是說,ordered ts和ordered boosting是使用的同樣的shuffle)
boosting計算流程圖舉例:(迭代中加入上一輪的負梯度+真實值,擬合殘差)
- catboost的ordered boosint type在一些地方被稱為引入了online learning的思路,啥意思呢,假設我們要計算x5的負梯度,則我們使用x1,x2,x3,x4訓練一棵樹,用這棵樹predict出x5的預測值然后和真實值帶入負梯度計算公式算出負梯度,從而作為x5的負梯度g作為下一輪的標簽。 如果要計算x6的負梯度,則使用x1,x2,x3,x4,x5按照上面的方法如法炮制。
- 顯然,這種計算方式將導致非常大的計算量,因此catboost內部做了一些改進,默認情況下,catboost只訓練log(num_of_datapoints)個模型,而不是為每個數據點訓練不同的模型。
訓練log個模型的例子:
- 在第一個數據點上訓練的模型用於計算第二個數據點的殘差。
- 在前兩個數據點上經過訓練的另一個模型用於計算第三和第四數據點的殘差
- 在前四個數據點上經過訓練的另一個模型用於計算第5,6,7,8個數據點的殘差
依次類推
其他 (調整參數bagging_temperature)
實際上,CatBoost將給定的數據集划分為隨機排列,並對這些隨機排列應用有序增強。
默認情況下,CatBoost創建四個隨機排列。有了這種隨機性,我們可以進一步停止過度擬合我們的模型。我們可以通過調整參數bagging_temperature來進一步控制這種隨機性。
為什么驗證集上的指標值會比訓練集上的指標值更好?(如auc)
原因是,針對訓練集和驗證集,基於分類特征的自動生成的數字特征特征(ts)的計算方式有所不同:
- 訓練數據集:隨機排列,對於數據集中的每個對象,計算方式都不同;對於第i個對象,依賴於第i-1個對象的數據來計算特征
- 驗證集:對數據集中的每個對象均等地計算特征,對於每個對象,使用訓練數據集中所有對象的數據計算特征;它使用的信息比僅在數據集的一部分上計算的特征要多,驗證集的計算的功能就更加強大,更強大帶來的是更好的損耗值。
綜上,由於驗證集具有更加強大的功能,因此驗證數據集上的損失值可能會比訓練集上的損失值更好。
還有測試集:
- 測試集的類別特征是用訓練集的同一個類別特征的多個編碼值(ts,Target statistics)進行平均所得。
調參
- cat_features: 傳入這個參數中的分類特征才能被CatBoost用他那迷人的方式處理,這個參數為空的話CatBoost和其他數據就沒區別了,所以是最重要的特征!
- one_hot_max_size:catboost將會對所有unique值<=one_hot_max_size的特征進行獨熱處理。這個參數的調整因人而異
- learning_rate & n_estimators:這個和其他gbdt算法一樣,學習率越小需要的學習器就越多。
- max_depth 的深度,這個沒啥好多說
- subsample 子采樣參數,在Bayesian Boosting Type不可用
- colsample_bylevel,colsample_bytree,colsample_bynode 列采樣,不多說
- l2_leaf_reg: l2正則化系數
- random_strength: 每一次分裂都會有一個分數,這個參數會給分數+一個隨機性,來進一步抵抗過擬合的問題。
GPU參數
- task_type
- devices (IDs of the GPU devices to use for training (indices are zero-based).)
model = CatBoostClassifier(iterations=1000,
task_type="GPU",
devices='0')
model.fit(train_data,
train_labels,
verbose=False)
安裝支持GPU示例
https://catboost.ai/docs/concepts/python-installation.html GPU system requirements
應用場景
作為GBDT框架內的算法,GBDT、XGBoost、LightGBM能夠應用的場景CatBoost也都適用,並且在處理類別型特征具備獨有的優勢,比如廣告推薦領域。
優缺點
優點
- 能夠處理類別特征
- 能夠有效防止過擬合
- 模型訓練精度高
缺點
- 對於類別特征的處理需要大量的內存和時間
- 不同隨機數的設定對於模型預測結果有一定的影響