簡介XGboost可以引出GBDT,引出bagging和boosting,引出隨機森林
集成學習是指用某種策略將多個分類器預測的結果集成起來,作為最終的預測結果,有boost和bagging兩種方法(boosting 各分類器之間有依賴關系,bagging各分類器之間沒有依賴關系,可並行),boosting分為兩種,一種是AdaBoost(自適應增強)(前一個分類器分錯/分對的樣本的權值會得到加強/降低,加權后的全體樣本再次被用來訓練下一個基本分類器),一種是GBDT,GBDT的每一次計算都為了減少上一次的殘差,進而在負梯度的方向上建立一個新的模型,而XGB采用的就是GBDT的形式,XGB的本質上還是一個GBDT,但是在速度和效率都發揮到了極致。XGB是GBDT工程版本的優化實現
XGB和GBDT比較大的不同就是目標函數的定義,XGB使用泰勒展開來近似目標函數;
xgboost類似於gbdt的優化版,不論是精度還是效率上都有了提升。與gbdt相比,具體的優點有:
1.損失函數是用泰勒展式二項逼近,而不是像gbdt里的就是一階導數
2.對樹的結構進行了正則化約束,防止模型過度復雜,降低了過擬合的可能性
3.節點分裂的方式不同,gbdt是用的平方差,xgboost是經過優化推導后的
1、Xgboost :分布式並行訓練,兩個方面
樹之間還是串行的,因為他是一個boosting模型
1)特征並行:並行計算特征的重要度,然后確定切分點,
2)樣本分在不同的存儲塊上,多個block可以並行計算
問題:(1)不能從本質上減少計算量;(2)通訊代價高。
2、XGBoost在什么地方做的剪枝,怎么做的?
(1) 目標函數中,使用葉子的數目和l2模的平方,控制模型的復雜度
(2) 在分裂節點的計算增益中,定義了一個閾值,當增益大於閾值才分裂
XGBoost 先從頂到底建立樹直到最大深度,再從底到頂反向檢查是否有不滿足分裂條件的結點,進行剪枝。
3. XGBoost為什么使用泰勒二階展開?為什么用二階信息不用一階?
(1) 由於之前求最優解的過程只是對平方損失函數進行的,一階殘差,二階常數,當損失函數是其它函數時,
展開就沒有這種形式了,為了能夠有個統一的形式,使用泰勒二階展開。為了統一損失函數求導的形式以支持自定義損失函數
(2) 二階信息本身能夠讓梯度收斂的更快更准確(優化算法中牛頓法證實)可以簡單認為一階導數引導梯度方向,二階導數引導梯度方向如何變化
4、缺失值的處理:
遇到缺失值,會分別將缺失值分配到左節點和右節點兩種情形,計算增益后懸着增益大的方向進行分裂。
如果訓練期間沒有缺失值,預測時候有,自動將缺失值划分到右子樹。
5. xgboost對預測模型特征重要性排序的原理?
由節點負責加權和記錄次數。一個屬性對分裂點改進性能度量越大(越靠近根節點),權值越大。
被越多提升樹所選擇,屬性越重要。最終將一個屬性在所有提升樹中的結果進行加權后求平均,得到重要性得分。
6. XGBoost如何尋找最優特征?是又放回還是無放回的呢?
XGB屬於boosting集成學習方法,樣本是不放回的,每輪計算樣本不重復。另外,XGB支持子采樣,每輪計算不使用全部樣本,減少過擬合。
XGB支持列采樣,提高計算速度又減少過擬合。
7. lightgbm和xgboost有什么區別?他們的loss一樣么? 算法層面有什么區別?
1、 XGB采用level-wise的分裂策略,LGB采用leaf-wise的策略,XGB對每一層所有節點做無差別分裂,但是可能有些節點增益非常小,對結果影響不大,帶來不必要的開銷。Leaf-wise是在所有葉子節點中選取分裂收益最大的節點進行的,但是很容易出現過擬合問題,所以需要對最大深度做限制
2、 XGB使用近似算法,LGB使用基於立方圖的決策算法,histogram算法在內存和計算代價上都有不小的優勢。
1)內存上:直方圖算法和xgboost的exact算法,大約1:8消耗,因為對特征分桶后只需保存特征離散化之后的值(1個字節),
而xgboost既要保存原始feature的值,也要保存這個值的順序索引,這些值需要32位的浮點數來保存(8個字節)。
2)XGBoost無法直接輸入類別型變量,因此需要事先對類別型變量進行編碼(例如獨熱編碼);LightGBM可以直接處理類別型變量。
特征並行:二者的區別就導致了LGB中worker間通信成本明顯降低,只需通信一個特征分裂點即可,而XGB中要廣播樣本索引
8. 比較一下LR和GBDT?GBDT在什么情況下比邏輯回歸算法要差?
1、 LR是線性模型,具有很好的解釋性,很容易並行化,處理億條訓練數據不是問題,但是學習能力有限,需要大量的特征工程;
GBDT可以處理線性和非線性的數據,具有天然優勢進行特征組合
2、 LR可以很好的利用正則化解決稀疏性問題(lr 等線性模型的正則項是對權重的懲罰,也就是 W1一旦過大,懲罰就會很大,進一步壓縮 W1的值,使他不至於過大,而樹模型則不一樣,樹模型的懲罰項通常為葉子節點數和深度等,而我們都知道,對於上面這種 case,樹只需要一個節點就可以完美分割9990和10個樣本,懲罰項極其之小)
9. RF和GBDT的區別;RF怎么解決的過擬合問題;
相同點:都是由多棵樹組成,最終的結果都是由多棵樹一起決定。
不同點:
組成隨機森林的樹可以分類樹也可以是回歸樹,而GBDT只由回歸樹組成
組成隨機森林的樹可以並行生成,而GBDT是串行生成
隨機森林的結果是多數表決表決的,而GBDT則是多棵樹累加之和
隨機森林對異常值不敏感,而GBDT對異常值比較敏感
隨機森林是減少模型的方差,而GBDT是減少模型的偏差
隨機森林不需要進行特征歸一化,而GBDT則需要進行特征歸一化
10. 怎么理解決策樹、xgboost能處理缺失值?而有的模型(svm)對缺失值比較敏感?
決策樹(隨機森林)
(1)使用對應類別中位數(數值)和出現次數最多的數(描述型變量)代替
(2)也是中位數和出現次數最多的數進行替換,引入了權重(替換數據和其它數據的相似度計算)
第二種效果好,但是費時,所以一般工具包不提供補全功能,影響工具包效率
涉及到距離度量的模型,當缺失值處理不當會導致效果很差(KNN,SVM)
1111111數據量和模型選擇
數據量很小,用朴素貝葉斯
數據量適中或者較大,用樹模型,優先 xgboost
數據量較大,也可以用神經網絡
避免使用距離度量相關的模型,如KNN和SVM
11. 隨機森林是怎樣避免ID3算法信息增益的缺點的?
首先說下信息增益的過程,決策樹算法本質上就是要找出每一列的最佳划分以及不同列划分的先后順序及排布。
信息增益的缺點是比較偏向選擇取值多的屬性。而gini系數每次都是二分,所以跟屬性多少沒有關系。
另外:CART為什么選擇基尼系數作為特征選擇標准 ?
基尼指數的意義是從數據集D中隨機抽取兩個樣本類別標識不一致的概率。
基尼指數越小,數據集的純度越高。相比於信息增益,信息增益比等作為特征選擇方法,基尼指數省略了對數計算,運算量比較小,也比較容易理解。
12.gbdt對標量特征要不要onehot編碼?
微軟在lightGBM的文檔里也說了,category特征可以直接輸入,不需要one-hot編碼,准確度差不多,速度快8倍。
而sklearn的tree方法在接口上不支持category輸入,所以只能用one-hot編碼。
13. GBDT 如何用於分類 ?
GBDT無論用於分類還是回歸一直使用的CART回歸樹。使用softmax來產生概率:
每樣本的標簽是分類到所屬的葉子節點所有值的平均值。
14、RF的隨機性體現在哪里?特征重要程度的計算?
樣本隨機性和特征隨機性
15. Bagging,Boosting二者之間的區別?
1)樣本選取:
Bagging訓練集有放回隨機抽取,每個樣本權重一樣
Boosting根據分類器的結果,分類錯誤的權重高
2)預測函數:
Bagging 每個分類器權重相等
Boosting根據分類器的效果,分類效果好權重高
3)並行:
Bagging 分類器並行訓練
Boosting串行訓練
16. 為什么決策樹之前用pca會好一點
決策樹的本質在於選取特征,然后分支。 pca解除了特征之間的耦合性(共線性),
並且按照貢獻度給特征拍了個序,這樣更加方便決策樹選取特征
17. 為什么隨機森林的樹比gbdt的要深一點?
隨機森林是通過投票的方式來降低方差,但是本質上需要每棵樹有較強的表達能力,所以單顆樹深點沒關系,通過投票的方式降低過擬合。
而GBDT是通過加強前一棵樹的表達能力,所以每顆樹不必有太強的表達能力。可以通過boosting的方式來提高,也能提高訓練速度
(gbdt害怕過擬合,rf不怕,通過投票的方式杜絕)
原文:https://blog.csdn.net/jamexfx/article/details/93780308
GBDT 面試總結:博客中關於,gbdt 如何用於分類,講解很詳細
https://www.cnblogs.com/ModifyRong/p/7744987.html
SVM常見問題:
https://zhuanlan.zhihu.com/p/76946313
LR常見問題:
https://zhuanlan.zhihu.com/p/76563562
xgboost對比gbdt/boosting Tree有了哪些方向上的優化?
- 顯示的把樹模型復雜度作為正則項加到優化目標中
- 優化目標計算中用到二階泰勒展開代替一階,更加准確
- 實現了分裂點尋找近似算法
- 暴力枚舉
- 近似算法(分桶)
- 更加高效和快速
- 數據事先排序並且以block形式存儲,有利於並行計算
- 基於分布式通信框架rabit,可以運行在MPI和yarn上
- 實現做了面向體系結構的優化,針對cache和內存做了性能優化
xgboost和gbdt的區別?
- 模型優化上:
- 基模型的優化:
- gbdt用的是cart回歸樹作為基模型,xgboost還可以用線性模型,加上天生的正則項,就是帶L1和L2邏輯回歸(分類)和線性回歸(回歸)
- 損失函數上的優化:
- gbdt對loss是泰勒一階展開,xgboost是泰勒二階展開
- gbdt沒有在loss中帶入結點個數和預測值的正則項
- 特征選擇上的優化:
- 實現了一種分裂節點尋找的近似算法,用於加速和減小內存消耗,而不是gbdt的暴力搜索
- 節點分裂算法解決了缺失值方向的問題,gbdt則是沿用了cart的方法進行加權
- 正則化的優化:
- 特征采樣
- 樣本采樣
- 基模型的優化:
- 工程優化上:
- xgboost在對特征進行了分block預排序,使得在做特征分裂的時候,最終選增益最大的那個特征去做分裂,那么各個特征的增益計算就可以開多線程進行
- cache-aware, out-of-core computation
- 支持分布式計算可以運行在MPI,YARN上,得益於底層支持容錯的分布式通信框架rabit
xgboost如何尋找分裂節點的候選集?
- 暴力枚舉
- 法嘗試所有特征和所有分裂位置,從而求得最優分裂點。當樣本太大且特征為連續值時,這種暴力做法的計算量太大
- 近似算法(approx)
- 近似算法尋找最優分裂點時不會枚舉所有的特征值,而是對特征值進行聚合統計,然后形成若干個桶。然后僅僅將桶邊界上的特征的值作為分裂點的候選,從而獲取計算性能的提升
- 離散值直接分桶
- 連續值分位數分桶
- 近似算法尋找最優分裂點時不會枚舉所有的特征值,而是對特征值進行聚合統計,然后形成若干個桶。然后僅僅將桶邊界上的特征的值作為分裂點的候選,從而獲取計算性能的提升
xgboost特征重要性是如何得到的?
- ’weight‘:代表着某個特征被選作分裂結點的次數;
- ’gain‘:使用該特征作為分類結點的信息增益;
- ’cover‘:某特征作為划分結點,覆蓋樣本總數的平均值;
xgboost如何調參數?
- 先確定learningrate和estimator
- 再確定每棵樹的基本信息,max_depth和 min_child_weight
- 再確定全局信息:比如最小分裂增益,子采樣參數,正則參數
- 重新降低learningrate,得到最優解
https://github.com/Allen15rg/Reflection_Summary/blob/master/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/%E9%9B%86%E6%88%90%E5%AD%A6%E4%B9%A0/Xgboost.md
LGB處理類別特征:
1、one-hot編碼弊端
one-hot編碼是處理類別特征的一個通用方法,然而在樹模型中,這可能並不一定是一個好的方法,尤其當類別特征中類別個數很多的情況下。主要的問題是:
①可能無法在這個類別特征上進行切分(即浪費了這個特征)。使用one-hot編碼的話,意味着在每一個決策節點上只能使用one vs rest(例如是不是狗,是不是貓等)的切分方式。當類別值很多時,每個類別上的數據可能會比較少,這時候切分會產生不平衡,這意味着切分增益也會很小(比較直觀的理解是,不平衡的切分和不切分沒有區別)。
②會影響決策樹的學習。因為就算可以在這個類別特征進行切分,也會把數據切分到很多零碎的小空間上,如圖1左邊所示。而決策樹學習時利用的是統計信息,在這些數據量小的空間上,統計信息不准確,學習會變差。但如果使用如圖1右邊的分裂方式,數據會被切分到兩個比較大的空間,進一步的學習也會更好。
2、LGBM處理分類特征
2.1 大致流程
為了解決one-hot編碼處理類別特征的不足。LGBM采用了Many vs many的切分方式,實現了類別特征的最優切分。用Lightgbm可以直接輸入類別特征,並產生如圖1右邊的效果。在1個k維的類別特征中尋找最優切分,朴素的枚舉算法的復雜度是,而LGBM采用了如參考文獻【1】的方法實現了的算法。
算法流程如圖2所示:在枚舉分割點之前,先把直方圖按每個類別的均值進行排序;然后按照均值的結果依次枚舉最優分割點。從圖2可以看到,Sum(y)/Count(y)為類別的均值。當然,這個方法很容易過擬合,所以在LGBM中加入了很多對這個方法的約束和正則化。
2.2 詳細流程
下面具體來講下在代碼中如何求解類別特征的最優切分的流程:
(feature_histogram.hpp文件中FindBestThresholdCategorical函數)
A. 離散特征建立直方圖的過程:
統計該特征下每一種離散值出現的次數,並從高到低排序,並過濾掉出現次數較少的特征值, 然后為每一個特征值,建立一個bin容器, 對於在bin容器內出現次數較少的特征值直接過濾掉,不建立bin容器。
B. 計算分裂閾值的過程:
B.1
先看該特征下划分出的bin容器的個數,如果bin容器的數量小於4,直接使用one vs other方式, 逐個掃描每一個bin容器,找出最佳分裂點;
B.2
對於bin容器較多的情況, 先進行過濾,只讓子集合較大的bin容器參加划分閾值計算, 對每一個符合條件的bin容器進行公式計算(公式如下: 該bin容器下所有樣本的一階梯度之和 / 該bin容器下所有樣本的二階梯度之和 + 正則項(參數cat_smooth),這里為什么不是label的均值呢?其實上例中只是為了便於理解,只針對了學習一棵樹且是回歸問題的情況, 這時候一階導數是Y, 二階導數是1),得到一個值,根據該值對bin容器從小到大進行排序,然后分從左到右、從右到左進行搜索,得到最優分裂閾值。但是有一點,沒有搜索所有的bin容器,而是設定了一個搜索bin容器數量的上限值,程序中設定是32,即參數max_num_cat。
LightGBM中對離散特征實行的是many vs many 策略,這32個bin中最優划分的閾值的左邊或者右邊所有的bin容器就是一個many集合,而其他的bin容器就是另一個many集合。
B.3
對於連續特征,划分閾值只有一個,對於離散值可能會有多個划分閾值,每一個划分閾值對應着一個bin容器編號,當使用離散特征進行分裂時,只要數據樣本對應的bin容器編號在這些閾值對應的bin集合之中,這條數據就加入分裂后的左子樹,否則加入分裂后的右子樹。
https://blog.csdn.net/anshuai_aw1/article/details/83275299