本文從理論基礎、代碼實踐、內容總結三個方面來展示預測的三大基礎模型與手動調參自動調參內容細節。
一、理論基礎
ridgeRegression
圖片: https://uploader.shimo.im/f/uX43BitluzbQeqht.jpg!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
Ridge Regression(嶺回歸)是一種用于線性回歸分析的正則化方法,旨在解決多重共線性問題并降低模型的方差。其原理在于通過在損失函數中加入一個正則化項來約束模型參數的大小,從而避免過擬合。嶺回歸的損失函數是普通最小二乘損失與參數的L2范數(即參數平方和)的加權和,公式可以表示為:
圖片: https://uploader.shimo.im/f/ldC4DitA6nxZkZKC.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
ridgeRegression自動調參方法
自動調參是尋找模型最佳超參數的過程,對于嶺回歸而言,最重要的超參數就是正則化強度αα。常見的自動調參方法有:
網格搜索(Grid Search):預先設定一系列候選的α值,然后在這些值組成的網格上遍歷,對每個值訓練模型并評估性能,選擇性能最優的α值。
隨機搜索(Randomized Search):與網格搜索相比,隨機搜索不是遍歷所有預設值,而是從參數的定義域中隨機抽取一組值進行評估,這種方法在參數空間較大時更為高效。
交叉驗證(Cross-Validation):通常與上述搜索方法結合使用,用來評估模型在不同劃分的數據集上的性能,以減少因數據劃分造成的偶然性,常用的有k折交叉驗證。
在實踐中,選擇哪種自動調參方法取決于問題的復雜性、計算資源的可用性以及對調參效率和精度的要求。許多機器學習庫,如Python的Scikit-learn,提供了實現這些自動調參方法的工具和接口,方便用戶進行模型優化。
如果數據的特征比樣本點還多應該怎么辦?是否還可以使用線性回歸和之前的方法來做預測?答案是否定的,即不能再使用前面介紹的方法。這是因為輸入數據的矩陣X不是滿秩矩陣。非滿秩矩陣在求逆時會出現問題。為了解決這個問題,統計學家引入了嶺回歸(ridge regression)的概念。
圖片: https://uploader.shimo.im/f/ngcH8ymNVmMbp3Lf.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
縮減 : 嶺回歸最先用來處理特征數多于樣本數的情況,現在也用于在估計中加入偏差,從而得到更好的估計,這里通過引入數學公式: $ \lambda $ 來限制了所有w之和,通過引入該懲罰項,能減少不重要的參數,這個技術在統計學中也叫縮減。
作用:1.嶺回歸可以解決特征數量比樣本量多的問題
2.嶺回歸作為一種縮減算法可以判斷哪些特征重要或者不重要,有點類似于降維的效果
3.縮減算法可以看作是對一個模型增加偏差的同時減少方差
適用范圍:1.數據點少于變量個數
2.變量間存在共線性(最小二乘回歸得到的系數不穩定,方差很大
偏差(Bias):預測值和真實值之間的誤差
方差(Variance):預測值之間的離散程度,也就是離其期望值的距離。方差越大,數據的分布越分散。
圖片: https://uploader.shimo.im/f/7ZSM8TmqqFJGNaFQ.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
lightgbm
決策樹與CART
1976年-1986年,J.R.Quinlan給出ID3算法原型并進行了總結,確定了決策樹學習的理論。這可以看做是決策樹算法的起點。1993,Quinlan將ID3算法改進成C4.5算法,稱為機器學習的十大算法之一。ID3算法的另一個分支是CART(Classification adn Regression Tree, 分類回歸決策樹),用于預測。這樣,決策樹理論完全覆蓋了機器學習中的分類和回歸兩個領域。
決策樹(decision tree)一般都是自上而下的來生成的。每個決策或事件(即自然狀態)都可能引出兩個或多個事件,導致不同的結果,把這種決策分支畫成圖形很像一棵樹的枝干,故稱決策樹。
決策樹利用樹結構進行決策,每一個非葉子節點是一個判斷條件,每一個葉子節點是結論。從跟節點開始,經過多次判斷得出結論。
決策樹的構建是數據逐步分裂的過程,構建的步驟如下:
步驟1:將所有的數據看成是一個節點,進入步驟2;
步驟2:從所有的數據特征中挑選一個數據特征對節點進行分割,進入步驟3;
步驟3:生成若干孩子節點,對每一個孩子節點進行判斷,如果滿足停止分裂的條件,進入步驟4;否則,進入步驟2;
步驟4:設置該節點是子節點,其輸出的結果為該節點數量占比最大的類別。
從上述步驟可以看出,決策生成過程中有三個重要的問題:
(1)數據如何分割
(2)如何選擇分裂的屬性
(3)什么時候停止分裂
決策樹(decision tree)算法基于特征屬性進行分類,其主要的優點:模型具有可讀性,計算量小,分類速度快。
集成學習
集成學習就是將多個弱的學習器結合起來組成一個強的學習器。
這就涉及到,先產生一組‘個體學習器’,再用一個策略將它們結合起來。
個體學習器可以選擇:決策樹,神經網絡。
集成時可以所有個體學習器屬于同一類算法:全是決策樹,或全是神經網絡;也可以來自不同的算法。
結合策略:例如分類問題,可以用投票法,少數服從多數。
之所以用這種集成的思想,是因為單獨用一個算法時,效果往往不容易達到很好,但如果多個個體算法結合在一起,取長補短,整體效果就會比單獨一個要強。
當然集成并不是不管怎么選擇學習器,怎么組合都一定會獲得更好的效果,最好的情況是,每個學習器都不是特別差,并且要具有一定的多樣性,否則可能集成后的會沒有效果,或者起負作用。
這就是集成學習的一個核心問題:如何生成準確性又不是很差,并且還能保證多樣性的個體學習器呢
目前主要有兩種生成方式:
Boosting:個體學習器間存在強依賴關系,必須串行生成。
Bagging,隨機森林:個體之間不存在強依賴關系,可并行生成。
Boosting
Boosting 的思想,三個臭皮匠頂一個諸葛亮:
給定初始訓練數據,由此訓練出第一個基學習器;
根據基學習器的表現對樣本進行調整,在之前學習器做錯的樣本上投入更多關注;
用調整后的樣本,訓練下一個基學習器;
重復上述過程 T 次,將 T 個學習器加權結合。
簡單講,就是每次訓練單個弱學習器時,都將上一次分錯的數據權重提高一點再進行當前單個弱學習器的學習。這樣越往后執行,訓練出的單個弱學習器就會越在意那些容易分錯(權重高)的點。當執行 M 次后,通過加權求和的方式組合成一個最終的學習器。
Boosting模型可以抽象為一個前向加法模型(additive model):
根據 Boosting 的定義,它有三個基本要素:
基學習器
組合方式
目標函數
AdaBoost
Boosting 的代表是 Adaboost。
? 第 1 行,初始化樣本權重分布,此時每個數據的權重是一樣的,所以是 1/m;
以分類問題為例,最初令每個樣本的權重都相等,對于第 t 次迭代操作,我們就根據這些權重來選取樣本點,進而訓練分類器 C_t。
? 第 2 行,進入 for 循環 T 次,即基學習器的個數為 T 個;
? 第 3 行,根據具有當前權重分布 D_t 的數據集,學習出 h_t;
前一個分類器分錯的樣本會被用來訓練下一個分類器。
h_t 是分量分類器 C_t 給出的對任一樣本點 xi 的標記(+1或-1),h_t(xi) = yi 時,樣本被正確分類。
? 第 4 行,計算當前學習器的誤差;
? 第 5 行,如果誤差大于 0.5,就停止;
AdaBoost 方法中使用的分類器可能很弱(比如出現很大錯誤率),但只要它的分類效果比隨機好一點(比如兩類問題分類錯誤率略小于0.5),就能夠改善最終得到的模型。
? 第 6 行,計算當前學習器的權重 α_t;
權值是關于誤差的表達式,當下一次分類器再次錯分這些點之后,會提高整體的錯誤率,這樣就導致分類器權值變小,進而導致這個分類器在最終的混合分類器中的權值變小,也就是說,Adaboost算法讓正確率高的分類器占整體的權值更高,讓正確率低的分類器權值更低,從而提高最終分類器的正確率。
? 第 7 行,得到下一時刻的權重分布 D_t+1.
如果某個樣本點已經被準確地分類,那么在構造下一個訓練集中,它被選中的概率就被降低;相反,如果某個樣本點沒有被準確地分類,那么它的權重就得到提高。通過這樣的方式,AdaBoost 方法能“聚焦于”那些較難分(更富信息)的樣本上。
機器學習神經網絡——Adaboost分離器算法
Gradient Boosting
AdaBoost每一輪基學習器訓練過后都會更新樣本權重,再訓練下一個學習器,最后將所有的基學習器加權組合。AdaBoost使用的是指數損失,這個損失函數的缺點是對于異常點非常敏感,因而通常在噪音比較多的數據集上表現不佳。Gradient Boosting在這方面進行了改進,使得可以使用任何損失函數 (只要損失函數是連續可導的),這樣一些比較robust的損失函數就能得以應用,使模型抗噪音能力更強。
和Adaboost不同,Gradient Boosting 在迭代的時候選擇梯度下降的方向來保證最后的結果最好。
算法將負梯度作為殘差值來學習基本模型h(x).
GBDT(Gradient Boosting Decision Tree) 梯度提升決策樹
DT-Decision Tree決策樹,GB是Gradient Boosting,是一種學習策略,GBDT的含義就是用Gradient Boosting的策略訓練出來的DT模型。在前幾年深度學習還沒有大行其道之前,GBDT在各種競賽是大放異彩。一是效果確實挺不錯。二是即可以用于分類也可以用于回歸。三是可以篩選特征。
LightGBM = XGBoost + Histogram + GOSS + EFB。
XGBoost,全稱eXtreme Gradient Boosting ,簡稱XGB,是GBDT算法的一種變種,是一種監督算法;它是boost算法的一種,也屬于集成算法,是一種伸縮性強、便捷的可并行構建模型的Gradient Boosting算法。其高效地實現了GBDT算法并進行了算法和工程上的許多改進,被廣泛應用在Kaggle競賽及其他許多機器學習競賽中。并取得了不錯的成績。它可用于分類,回歸,排序問題。
XGBoost與GBDT比較大的不同就是目標函數的定義,基本思想是一致的,同樣是利用加法模型與前向分步算法實現學習的優化過程。預測過程如下:
圖片: https://uploader.shimo.im/f/GzNmjKVOrTOKvk7W.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
其中,f_k表示回歸X樹,K為回歸樹的數量。
圖片: https://uploader.shimo.im/f/CMIJgBveOTXWWJ5i.jpg!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
XGBoost是由GBDT發展而來,同樣是利用加法模型與前向分步算法實現學習的優化過程,但與GBDT是有區別的。主要區別包括以下幾點:
1、傳統的GBDT以CART樹作為基學習器,XGBoost還支持線性分類器(線性回歸、邏輯回歸),這個時候XGBoost相當于L1和L2正則化的邏輯斯蒂回歸(分類)或者線性回歸(回歸);
2、傳統的GBDT在優化的時候只用到一階導數信息,XGBoost則對代價函數進行了二階泰勒展開,得到一階和二階導數==;
3、XGBoost在代價函數中加入了正則項,用于控制模型的復雜度。從權衡方差偏差來看,它降低了模型的方差,使學習出來的模型更加簡單,防止過擬合,這也是XGBoost優于傳統GBDT的一個特性;
4、shrinkage(縮減或者學習速率),相當于學習速率(XGBoost中的eta)。XGBoost在進行完一次迭代時,會將葉子節點的權值乘上該系數,主要是為了削弱每棵樹的影響,讓后面有更大的學習空間。(GBDT也有學習速率);
5、列抽樣。XGBoost借鑒了隨機森林的做法,支持列抽樣,不僅防止過擬合,還能減少計算;對缺失值的處理。對于特征的值有缺失的樣本,XGBoost還可以自動學習出它的分裂方向;
6、XGBoost工具支持并行。Boosting不是一種串行的結構嗎?怎么并行的?注意XGBoost的并行不是tree粒度的并行,XGBoost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數里包含了前面t-1次迭代的預測值)。XGBoost的并行是在特征粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特征的值進行排序(因為要確定最佳分割點),XGBoost在訓練之前,預先對數據進行了排序,然后保存為block結構,后面的迭代中重復地使用這個結構,大大減小計算量。這個block結構也使得并行成為了可能,在進行節點的分裂時,需要計算每個特征的增益,最終選增益最大的那個特征去做分裂,那么各個特征的增益計算就可以開多線程進行。
性質 有監督,分類,回歸,排序
與GBDT區別
目標函數:XGBoost的損失函數添加了正則化項,使用正則用以控制模型的復雜度,正則項里包含了樹的葉子節點個數、每個葉子節點權重(葉結點的socre值)的平方和。
優化方法:GBDT在優化時只使用了一階導數信息,XGBoost在優化時使用了一、二階導數信息。
缺失值處理:XBGoost對缺失值進行了處理,通過學習模型自動選擇最優的缺失值默認切分方向,分別對左右側計算損失值,那個小就劃分到那一側,并記錄下來額,預測試也按這個標準來,否則默認左側。
防止過擬合: XGBoost除了增加了正則項來防止過擬合,還支持行列采樣的方式來防止過擬合。
結果:它可以在最短時間內用更少的計算資源得到更好的結果。
回歸
圖片: https://uploader.shimo.im/f/ETZmvfHI25yM1104.jpg!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
分類
圖片: https://uploader.shimo.im/f/5MVDfk0UpwiIIBXc.jpg!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
LightGBM在XGBoost上主要有3方面的優化。
1,Histogram算法:直方圖算法。
2,GOSS算法:基于梯度的單邊采樣算法。
3,EFB算法:互斥特征捆綁算法。
XGBoost生成一片葉子的復雜度可以粗略估計為 = 特征數量候選分裂點數量樣本的數量。
Histogram算法的主要作用是減少候選分裂點數量,
GOSS算法的作用是減少樣本的數量,
EFB算法的作用是減少特征的數量。
通過這3個算法的引入,LightGBM生成一片葉子需要的復雜度大大降低了,從而極大節約了計算時間。 同時Histogram算法還將特征由浮點數轉換成0~255位的整數進行存儲,從而極大節約了內存存儲。
Histogram直方圖算法
直方圖算法是替代XGBoost的預排序(pre-sorted)算法的。預排序算法首先將樣本按照特征取值排序,然后從全部特征取值中找到最優的分裂點位,該算法的候選分裂點數量與樣本數量成正比。而直方圖算法通過將連續特征值離散化到固定數量(如255個)的bins上,使得候選分為點位為常數個(num_bins -1)。
此外,直方圖算法還能夠作直方圖差加速。當節點分裂成兩個時,右邊葉子節點的直方圖等于其父節點的直方圖減去左邊葉子節點的直方圖。從而大大減少構建直方圖的計算量。
利用直方圖對于每個特征的所有候選分割點按照其范圍分成N個箱子,累加箱子內的梯度提升值,對于箱子里的每個候選分割點都計算 帶來的梯度增益,對于每個箱子分別保存其累計梯度、箱子內的樣本數量。之后再分裂節點時直接對直方圖遍歷進行分割點的候選即可,通過直方圖的方式,雖然分割的精度變差了,但是對最后的結果影響不大,一方面能夠提升計算效率,另一方面這種較粗的分割點可以起到一種正則化的效果。之后進行結點分裂時候,只需要根據梯度之和計算loss即可。對Gain增益的計算在梯度計算中。
GOSS基于梯度的單邊采樣算法
GOSS算法全稱為Gradient-based One-Side Sampling,即基于梯度的單邊采樣算法。 樣本的梯度越小,則樣本的訓練誤差越小,表示樣本已經訓練的很好了。最直接的做法就是丟掉這部分樣本,然而直接扔掉會影響數據的分布,因此lightGBM采用了one-side 采樣
EFB互斥特征捆綁算法
EFB算法全稱是Exclusive Feature Bundling,即互斥特征綁定算法。(將多個特征捆綁到一起)
EFB是通過特征捆綁的方式減少特征維度(其實是降維技術)的方式,來提升計算效率。通常被捆綁的特征都是互斥的(一個特征值為零,一個特征值不為零),這樣兩個特征捆綁起來才不會丟失信息。如果兩個特征并不是完全互斥(部分情況下兩個特征都是非零值),可以用一個指標對特征不互斥程度進行衡量,稱之為沖突比率,當這個值較小時,我們可以選擇把不完全互斥的兩個特征捆綁,而不影響最后的精度。
EFB的算法步驟如下:
將特征按照非零值的個數進行排序
計算不同特征之間的沖突比率
遍歷每個特征并嘗試合并特征,使沖突比率最小化
LightGBM是一種基于梯度提升決策樹(Gradient Boosting Decision Tree, GBDT)的機器學習算法,由Microsoft開發,因其高效的訓練速度和優秀的預測性能而受到廣泛關注。它的核心改進在于以下幾個方面:
- 基于 Leaf-Wise 生長策略的樹結構:與傳統的 Level-Wise 策略(如XGBoost中使用的)不同,LightGBM采用按葉子節點分裂的策略,每次從當前所有葉子節點中找到增益最大的一個進行分裂,這樣可以更快地減小損失函數,但也可能帶來過擬合的風險,因此需要合適的正則化控制。
- 直方圖算法:LightGBM在訓練過程中使用了直方圖近似方法來加速特征分桶和計算信息增益,減少了計算特征值和分割點之間增益所需的計算量,顯著提升了訓練效率。
- 單邊梯度算法(GOSS, Gradient-based One-Side Sampling)和獨家特征捆綁(EFB, Exclusive Feature Bundling):這兩種算法進一步提高了訓練速度和模型的內存效率,GOSS通過只使用一部分數據來估計梯度,而EFB則通過捆綁互斥特征減少特征的數量。
對于LightGBM的自動調參,常用的有以下幾種方法: - Hyperopt:這是一個Python庫,能夠進行分布式異步超參數優化。通過定義搜索空間、目標函數(通常是交叉驗證得分)和優化算法(如TPE),Hyperopt可以自動探索參數空間,找到最優配置。
- Optuna:另一個流行的超參數優化庫,提供了簡潔的API來定義和執行超參數搜索。Optuna支持多種采樣策略,并能自動適應地優化參數。
- Grid Search:盡管效率較低,但在參數空間較小或預先有較好參數范圍的情況下,網格搜索仍然是一種可行的選擇,它會遍歷所有預設的參數組合。
- Random Search:隨機選擇參數組合進行嘗試,比網格搜索更高效,尤其在參數空間較大時,通常能得到較好的結果。
LightGBM有許多參數,以下是一些關鍵參數及其作用:
num_leaves:控制樹的最大葉子節點數,直接影響模型的復雜度和過擬合風險。
learning_rate:學習率,每次迭代更新權重的步長,較小的學習率需要更多的迭代次數,但通常能有更好的泛化能力。
max_depth:在Leaf-Wise策略中,這個參數的意義不如num_leaves明顯,但在某些情況下仍可作為限制樹深度的手段。
min_child_samples(min_data_in_leaf):葉子節點上所需的最小樣本數,用于防止過擬合。
colsample_bytree(feature_fraction):每棵樹隨機選取特征的比例,用于特征的隨機子抽樣。
subsample(bagging_fraction):訓練數據的子采樣比例,用于行的隨機子抽樣,減少過擬合風險。
lambda_l1和lambda_l2:L1和L2正則化項的權重,用于防止模型過擬合。
objective:目標函數,根據任務類型(如二分類、多分類、回歸)選擇。
metric:評價模型性能的指標,應與目標函數相匹配。
合理選擇和調優這些參數對于達到模型的最佳性能至關重要。實踐中,通常結合交叉驗證和上述自動調參方法來確定最優參數配置。
catboost
catboost=Gradient Boosting(梯度提升) + Categorical Features(類別型特征)
CatBoost 與 XGBoost 、LightGBM是主流的三大Boosting框架,都是高效的GBDT算法工程化實現框架。CatBoost 則因長于處理類別特征而取名為CatBoost(Categorical + Boosting)。算法的理論特色,包括用于處理類別變量的目標變量統計和排序提升算法。
CatBoost是一種基于對稱決策樹(oblivious trees)為基學習器實現的參數較少、支持類別型變量和高準確性的GBDT框架,主要解決的痛點是高效合理地處理類別型特征,這一點從它的名字中可以看出來,CatBoost是由Categorical和Boosting組成。此外,CatBoost還解決了梯度偏差(Gradient Bias)以及預測偏移(Prediction shift)的問題,從而減少過擬合的發生,進而提高算法的準確性和泛化能力。
與XGBoost、LightGBM相比,CatBoost的創新點有:
嵌入了自動將類別型特征處理為數值型特征的創新算法。首先對categorical features做一些統計,計算某個類別特征(category)出現的頻率,之后加上超參數,生成新的數值型特征(numerical features)。
Catboost還使用了組合類別特征,可以利用到特征之間的聯系,這極大的豐富了特征維度。
采用排序提升的方法對抗訓練集中的噪聲點,從而避免梯度估計的偏差,進而解決預測偏移的問題。
采用了完全對稱樹作為基模型。
XGBoost被廣泛的應用于工業界,LightGBM有效的提升了GBDT的計算效率,而Yandex的CatBoost號稱是比XGBoost和LightGBM在算法準確率等方面表現更為優秀的算法。
CatBoost是一種基于對稱決策樹(oblivious trees)為基學習器實現的參數較少、支持類別型變量和高準確性的GBDT框架,主要解決的痛點是高效合理地處理類別型特征,CatBoost是由Categorical和Boosting組成。此外,CatBoost還解決了梯度偏差(Gradient Bias)及預測偏移(Prediction shift)的問題,從而減少過擬合的發生,進而提高算法的準確性和泛化能力
它自動采用特殊的方式處理類別型特征(categorical features)。首先對categorical features做一些統計,計算某個類別特征(category)出現的頻率,之后加上超參數,生成新的數值型特征(numerical features)。這也是我在這里介紹這個算法最大的motivtion,有了catboost,再也不用手動處理類別型特征了。
catboost還使用了組合類別特征,可以利用到特征之間的聯系,這極大的豐富了特征維度。
采用ordered boost的方法避免梯度估計的偏差,進而解決預測偏移的問題。
catboost的基模型采用的是對稱樹,同時計算leaf-value方式和傳統的boosting算法也不一樣,傳統的boosting算法計算的是平均數,而catboost在這方面做了優化采用了其他的算法,這些改進都能防止模型過擬合。
Categorical features
所謂類別型特征,即這類特征不是數值型特征,而是離散的集合,比如省份名(山東、山西、河北等),城市名(北京、上海、深圳等),學歷(本科、碩士、博士等)。在梯度提升算法中,最常用的是將這些類別型特征轉為數值型來處理,一般類別型特征會轉化為一個或多個數值型特征。
如果某個類別型特征基數比較低(low-cardinality features),即該特征的所有值去重后構成的集合元素個數比較少,一般利用One-hot編碼方法將特征轉為數值型。One-hot編碼可以在數據預處理時完成,也可以在模型訓練的時候完成,從訓練時間的角度,后一種方法的實現更為高效,CatBoost對于基數較低的類別型特征也是采用后一種實現。
在高基數類別型特征(high cardinality features) 當中,比如 user ID,這種編碼方式會產生大量新的特征,造成維度災難。一種折中的辦法是可以將類別分組成有限個的群體再進行 One-hot encoding。一種常被使用的方法是根據目標變量統計(Target Statistics,以下簡稱TS)進行分組,目標變量統計用于估算每個類別的目標變量期望值。甚至有人直接用TS作為一個新的數值型變量來代替原來的類別型變量。重要的是,可以通過對TS數值型特征的閾值設置,基于對數損失、基尼系數或者均方差,得到一個對于訓練集而言將類別一分為二的所有可能劃分當中最優的那個。在LightGBM當中,類別型特征用每一步梯度提升時的梯度統計(Gradient Statistics,以下簡稱GS)來表示。雖然為建樹提供了重要的信息,但是這種方法有以下兩個缺點:
增加計算時間,因為需要對每一個類別型特征,在迭代的每一步,都需要對GS進行計算;
增加存儲需求,對于一個類別型變量,需要存儲每一次分離每個節點的類別。
為了克服這些缺點,LightGBM以損失部分信息為代價將所有的長尾類別歸位一類,作者聲稱這樣處理高勢特征時比起 One-hot encoding還是好不少。不過如果采用TS特征,那么對于每個類別只需要計算和存儲一個數字。如此看到,采用TS作為一個新的數值型特征是最有效、信息損失最小的處理類別型特征的方法。TS也被廣泛采用,在點擊預測任務當中,這個場景當中的類別特征有用戶、地區、廣告、廣告發布者等。接下來我們著重討論TS,暫時將One-hot encoding和GS放一邊。
Target Statistics
CatBoost算法的設計初衷是為了更好的處理GBDT特征中的categorical features。在處理 GBDT特征中的categorical features的時候,最簡單的方法是用 categorical feature 對應的標簽的平均值來替換。在決策樹中,標簽平均值將作為節點分裂的標準。這種方法被稱為 Greedy Target-based Statistics , 簡稱 Greedy TS,用公式來表達就是:
圖片: https://uploader.shimo.im/f/2AccCPphblky78Pe.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
這種方法有一個顯而易見的缺陷,就是通常特征比標簽包含更多的信息,如果強行用標簽的平均值來表示特征的話,當訓練數據集和測試數據集數據結構和分布不一樣的時候會出條件偏移問題。一個標準的改進 Greedy TS的方式是添加先驗分布項,這樣可以減少噪聲和低頻率類別型數據對于數據分布的影響
圖片: https://uploader.shimo.im/f/y4XMC5L0npEk4Hub.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
其中p是添加的先驗項,a通常是大于0的權重系數。添加先驗項是一個普遍做法,針對類別數較少的特征,它可以減少噪聲數據。。對于回歸問題,一般情況下,先驗項可取數據集label的均值。對于二分類,先驗項是正例的先驗概率。
當然,在論文《CatBoost: unbiased boosting with categorical features》中,還提到了其它幾種改進Greedy TS的方法,分別有:Holdout TS、Leave-one-out TS、Ordered TS。
Ordered TS
它是catboost的主要思想,依賴于排序,受online learning algorithms的啟發得到,對于某一個樣本,TS的值依賴于觀測歷史,為了在離線的數據上應用該思想,我們將數據隨機排序,對于每一個樣本,利用該樣本之前數據計算該樣本類別值的TS值。如果僅僅使用一個隨機序列,那么計算得到值會有較大的方差,因此我們使用不同的隨機序列來計算。
特征組合
CatBoost的另外一項重要實現是將不同類別型特征的組合作為新的特征,以獲得高階依賴(high-order dependencies),比如在廣告點擊預測當中用戶ID與廣告話題之間的聯合信息,又或者在音樂推薦引用當中,用戶ID和音樂流派,如果有些用戶更喜歡搖滾樂,那么將用戶ID和音樂流派分別轉換為數字特征時,這種用戶內在的喜好信息就會丟失。然而,組合的數量會隨著數據集中類別型特征的數量成指數增長,因此在算法中考慮所有組合是不現實的。為當前樹構造新的分割點時,CatBoost會采用貪婪的策略考慮組合。對于樹的第一次分割,不考慮任何組合。對于下一個分割,CatBoost將當前樹的所有組合、類別型特征與數據集中的所有類別型特征相結合,并將新的組合類別型特征動態地轉換為數值型特征。CatBoost還通過以下方式生成數值型特征和類別型特征的組合:樹中選定的所有分割點都被視為具有兩個值的類別型特征,并像類別型特征一樣地被進行組合考慮。
CatBoost處理Categorical features總結
首先會計算一些數據的statistics。計算某個category出現的頻率,加上超參數,生成新的numerical features。這一策略要求同一標簽數據不能排列在一起(即先全是之后全是這種方式),訓練之前需要打亂數據集。
第二,使用數據的不同排列。在每一輪建立樹之前,先扔一輪骰子,決定使用哪個排列來生成樹。
第三,考慮使用categorical features的不同組合。例如顏色和種類組合起來,可以構成類似于blue dog這樣的特征。當需要組合的categorical features變多時,CatBoost只考慮一部分combinations。在選擇第一個節點時,只考慮選擇一個特征,例如A。在生成第二個節點時,考慮A和任意一個categorical feature的組合,選擇其中最好的。就這樣使用貪心算法生成combinations。
第四,除非向gender這種維數很小的情況,不建議自己生成One-hot編碼向量,最好交給算法來處理。
梯度偏差/預測偏移
為什么會有梯度偏差?
梯度偏差造成了什么問題?
如何解決梯度偏差?
為什么會有梯度偏差?
CatBoost和所有標準梯度提升算法一樣,都是通過構建新樹來擬合當前模型的梯度。然而,所有經典的提升算法都存在由有偏的點態梯度估計引起的過擬合問題。在每個步驟中使用的梯度都使用當前模型中的相同的數據點來估計,這導致估計梯度在特征空間的任何域中的分布與該域中梯度的真實分布相比發生了偏移。
梯度偏差造成了什么問題?
模型過擬合,預測發生偏移。另外預測偏移還有當我們利用TS來處理類別特征時,引起的target leak的問題。
如何解決梯度偏差/預測偏移?
為了解決這個問題,CatBoost對經典的梯度提升算法進行了一些改進,簡要介紹如下:
許多利用GBDT技術的算法(例如,XGBoost、LightGBM),構建下一棵樹分為兩個階段:選擇樹結構和在樹結構固定后計算葉子節點的值。為了選擇最佳的樹結構,算法通過枚舉不同的分割,用這些分割構建樹,對得到的葉子節點計算值,然后對得到的樹計算評分,最后選擇最佳的分割。兩個階段葉子節點的值都是被當做梯度或牛頓步長的近似值來計算。
在CatBoost中,第一階段采用梯度步長的無偏估計,第二階段使用傳統的GBDT方案執行。既然原來的梯度估計是有偏的,那么怎么能改成無偏估計呢。
圖片: https://uploader.shimo.im/f/joBWEj0nvbNU2Ij3.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
快速評分
CatBoost使用對稱樹(oblivious trees)作為基預測器。在這類樹中,相同的分割準則在樹的整個一層上使用。這種樹是平衡的,不太容易過擬合。梯度提升對稱樹被成功地用于各種學習任務中。在對稱樹中,每個葉子節點的索引可以被編碼為長度等于樹深度的二進制向量。這在CatBoost模型評估器中得到了廣泛的應用:我們首先將所有浮點特征、統計信息和獨熱編碼特征進行二值化,然后使用二進制特征來計算模型預測值。
算法流程
圖片: https://uploader.shimo.im/f/7JoN7bwAMZAgPERr.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
圖片: https://uploader.shimo.im/f/oFo4l8FDENAz23lV.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
圖片: https://uploader.shimo.im/f/E84ZU1swvmvvalSz.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
優點
性能卓越: 在性能方面可以匹敵任何先進的機器學習算法;
魯棒性/強健性: 無需調參即可獲得較高的模型質量,采用默認參數就可以獲得非常好的結果,減少在調參上面花的時間,減少了對很多超參數調優的需求
易于使用: 提供與scikit集成的Python接口,以及R和命令行界面;
實用: 可以處理類別型、數值型特征,支持類別型變量,無需對非數值型特征進行預處理
可擴展: 支持自定義損失函數;
快速、可擴展的GPU版本,可以用基于GPU的梯度提升算法實現來訓練你的模型,支持多卡并行提高準確性,
快速預測:即便應對延時非常苛刻的任務也能夠快速高效部署模型
缺點
對于類別型特征的處理需要大量的內存和時間;
不同隨機數的設定對于模型預測結果有一定的影響;
CatBoost是俄羅斯Yandex公司開發的一種梯度提升決策樹算法,它在GBDT的基礎上進行了多項改進,尤其擅長處理類別特征和防止過擬合。其核心原理和特性包括:
- 自動處理類別特征:CatBoost無需手動編碼類別特征,自動對類別特征進行獨熱編碼前的統計處理,計算類別頻率并結合超參數生成數值特征,大大簡化了特征工程。
- 對稱決策樹(Oblivious Trees):CatBoost使用了對稱決策樹,即樹的所有內部節點都分裂到相同的深度,這減少了模型的復雜度,加快了訓練速度,并有助于防止過擬合。
- 防止梯度偏差和預測偏移:通過對目標變量分布進行修正,CatBoost在每一輪迭代中補償訓練數據和預測數據之間的差異,減少預測偏移。
- 提前計算分割:在訓練開始時,CatBoost預先計算了每個特征的最優分割點,減少了訓練過程中的計算量。
- 模型融合:CatBoost支持訓練多個模型并進行模型融合,以提高預測性能。
CatBoost提供了內置的自動調參功能,同時也可以結合第三方庫進行調參。常用的自動調參方法包括: - 內置Grid Search:CatBoost本身提供了基于網格搜索的超參數優化方法,用戶可以指定一系列候選值,讓算法在這些值中尋找最優組合。
- Optuna與Hyperopt:這兩個第三方庫通過貝葉斯優化等策略進行超參數調優,能夠在較大的參數空間中高效探索,找到較優參數配置。Optuna和Hyperopt均支持動態調整搜索策略,根據前期的評估結果智能地選擇后續待測試的參數組合。
- Custom Scripting:開發者可以編寫自定義腳本來實現更復雜的調參邏輯,結合交叉驗證等策略,手動或半自動地遍歷參數空間。
CatBoost的參數眾多,以下是一些重要的參數及其含義:
learning_rate:學習率,控制每一步梯度下降的幅度。
depth:決策樹的最大深度。
l2_leaf_reg:L2正則化項的權重,用于防止過擬合。
iterations:迭代次數,即構建的樹的數量。
loss_function:損失函數,根據任務類型選擇,如分類任務中的Logloss、多分類的MultiClass等。
eval_metric:評估模型性能的指標。
random_seed:隨機種子,用于確保實驗的可復現性。
cat_features:指定數據集中類別特征的列索引列表。
bootstrap_type:是否進行行采樣,以及采樣的類型,如‘Bernoulli’或‘MVS’。
實際操作中,結合交叉驗證和上述自動調參方法,可以有效地尋找模型的最佳超參數配置,提升預測性能。
交叉驗證
圖片: https://uploader.shimo.im/f/kYDL0jjlMMti8ani.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
回到交叉驗證,根據切分的方法不同,交叉驗證分為下面三種:
第一種是簡單交叉驗證,所謂的簡單,是和其他交叉驗證方法相對而言的。首先,我們隨機的將樣本數據分為兩部分(比如: 70%的訓練集,30%的測試集),然后用訓練集來訓練模型,在測試集上驗證模型及參數。接著,我們再把樣本打亂,重新選擇訓練集和測試集,繼續訓練數據和檢驗模型。最后我們選擇損失函數評估最優的模型和參數。
第二種是 S折交叉驗證( S-Folder Cross Validation),也是經常會用到的。和第一種方法不同, S折交叉驗證先將數據集 D隨機劃分為 S個大小相同的互斥子集,即 ,每次隨機的選擇 S-1份作為訓練集,剩下的1份做測試集。當這一輪完成后,重新隨機選擇 S份來訓練數據。若干輪(小于 S )之后,選擇損失函數評估最優的模型和參數。注意,交叉驗證法評估結果的穩定性和保真性在很大程度上取決于 S取值。
第三種是留一交叉驗證(Leave-one-out Cross Validation),它是第二種情況的特例,此時 S等于樣本數 N,這樣對于 N個樣本,每次選擇 N-1個樣本來訓練數據,留一個樣本來驗證模型預測的好壞。此方法主要用于樣本量非常少的情況,比如對于普通適中問題, N小于50時,我一般采用留一交叉驗證。
通過反復的交叉驗證,用損失函數來度量得到的模型的好壞,最終我們可以得到一個較好的模型。那這三種情況,到底我們應該選擇哪一種方法呢?一句話總結,如果我們只是對數據做一個初步的模型建立,不是要做深入分析的話,簡單交叉驗證就可以了。否則就用S折交叉驗證。在樣本量少的時候,使用S折交叉驗證的特例留一交叉驗證。
此外還有一種比較特殊的交叉驗證方式,也是用于樣本量少的時候。叫做自助法(bootstrapping)。比如我們有m個樣本(m較小),每次在這m個樣本中隨機采集一個樣本,放入訓練集,采樣完后把樣本放回。這樣重復采集m次,我們得到m個樣本組成的訓練集。當然,這m個樣本中很有可能有重復的樣本數據。同時,用原始的m個樣本做測試集。這樣接著進行交叉驗證。由于我們的訓練集有重復數據,這會改變數據的分布,因而訓練結果會有估計偏差,因此,此種方法不是很常用,除非數據量真的很少,比如小于20個。
保留交叉驗證 hand-out cross validation
首先隨機地將已給數據分為兩部分:訓練集和測試集 (例如,70% 訓練集,30% 測試集);
然后用訓練集在各種條件下 (比如,不同的參數個數) 訓練模型,從而得到不同的模型;
在測試集上評價各個模型的測試誤差,選出測試誤差最小的模型。
這種方式其實嚴格意義上并不能算是交叉驗證,因為訓練集的樣本數始終是那么多,模型并沒有看到更多的樣本,沒有體現交叉的思想。
由于是隨機的將原始數據分組,所以最后測試集上準確率的高低與原始數據的分組有很大的關系,所以這種方法得到的結果其實并不具有說服性。
k折交叉驗證 k-fold cross validation
首先隨機地將數據集切分為 k 個互不相交的大小相同的子集;
然后將 k-1 個子集當成訓練集訓練模型,剩下的 (held out) 一個子集當測試集測試模型;
將上一步對可能的 k 種選擇重復進行 (每次挑一個不同的子集做測試集);
這樣就訓練了 k 個模型,每個模型都在相應的測試集上計算測試誤差,得到了 k 個測試誤差,對這 k 次的測試誤差取平均便得到一個交叉驗證誤差。這便是交叉驗證的過程。
計算平均測試誤差 (交叉驗證誤差) 來評估當前參數下的模型性能。
在模型選擇時,假設模型有許多 tuning parameter 可供調參,一組 tuning parameter 便確定一個模型,計算其交叉驗證誤差,最后選擇使得交叉驗證誤差最小的那一組 tuning parameter。這便是模型選擇過程。
k 一般大于等于2,實際操作時一般從3開始取,只有在原始數據集樣本數量小的時候才會嘗試取2。
k折交叉驗證可以有效的避免過擬合以及欠擬合狀態的發生,最后得到的結果也比較具有說服性。
k折交叉驗證最大的優點:
? 所有數據都會參與到訓練和預測中,有效避免過擬合,充分體現了交叉的思想
交叉驗證可能存在 bias 或者 variance。如果我們提高切分的數量 k,variance 會上升但 bias 可能會下降。相反得,如果降低 k,bias 可能會上升但 variance 會下降。bias-variance tradeoff 是一個有趣的問題,我們希望模型的 bias 和 variance 都很低,但有時候做不到,只好權衡利弊,選取他們二者的平衡點。
通常使用10折交叉驗證,當然這也取決于訓練數據的樣本數量。
留一交叉驗證 leave-one-out cross validation
k折交叉驗證的特殊情況,k=N,N 是數據集的樣本數量,往往在數據缺乏的情況下使用。
留一交叉驗證的優點是:
? 每一回合中幾乎所有的樣本皆用于訓練模型,因此最接近原始樣本的分布,這樣評估所得的結果比較可靠。
? 實驗過程中沒有隨機因素會影響實驗數據,確保實驗過程是可以被復制的。
缺點是:
? 計算成本高,因為需要建立的模型數量和原始數據集樣本數量一致,尤其當樣本數量很大的時候。可以考慮并行化訓練模型減少訓練時間。
總之,交叉驗證對于我們選擇模型以及模型的參數都是很有幫助的。
但以上交叉驗證的方法都有一個問題,就是在數據分組的時候缺乏隨機性,以 k折交叉驗證 為例,每個數據樣本只能固定屬于 k 個子集中的一個,可能會造成對于最終結果的影響。于是有人提出了 bootstrapping。
Bootstrapping
cv 和 bootstrapping 都是重采樣 (resampling) 的方法。機器學習中常用的 bagging 和 boosting 都是 bootstrapping 思想的應用。
bootstrapping 的思想是依靠自己的資源,稱為自助法,它是一種有放回的抽樣方法。
bootstrapping 的過程如下:
數據假設要分成10組,則先設置一個采樣比例,比如采樣比例70%。則10組數據是每次從原始數據集中隨機采樣總數70%的數據構成訓練集1,沒有選中的樣本作為測試集1;然后把數據放回,再隨機采樣總數70%的數據構成訓練集2,沒選中的作為測試集2……以此類推,放回式采樣10組。
訓練生成10個模型
計算平均測試誤差來評估當前參數下的模型性能
除此之外,bootstrapping 在集成學習方法中也很有用。比如我們可以用經過bootstrapping 的多組數據集構建模型 (比如決策樹),然后將這些模型打包 (bag,就像隨機森林),最后使用這些模型的最大投票結果作為我們最終的輸出。
交叉驗證(Cross-validation)是一種統計學方法,廣泛應用于機器學習和統計建模中,旨在評估模型的泛化能力,即模型在未見過的數據上的表現。其核心思想是將數據集分成訓練集和測試集,通過多次迭代,輪流使用不同的數據子集進行訓練和測試,以此來估計模型在未知數據上的性能。
基本原理步驟如下: - 數據分割:首先,將數據集隨機分成k個大小相似的子集(或“折”),其中k-1個子集用于模型訓練,剩下的1個子集用于模型驗證或測試。這個過程重復k次,每次輪流選擇不同的子集作為驗證集,其余作為訓練集。
- 模型訓練與驗證:在每一次迭代中,使用選定的k-1個子集訓練模型,然后在保留的子集上評估模型性能。評估標準通常包括準確率、精確度、召回率、F1分數或AUC-ROC曲線等,具體取決于任務類型。
- 性能評估:所有k次迭代后,計算每個驗證集上的性能指標,并取這些指標的平均值作為模型整體性能的估計。這樣的平均值相比單一劃分的訓練/測試更能代表模型在新數據上的預期表現,因為它考慮到了模型在不同子集上的穩定性和一般性。
常見的交叉驗證類型包括:
簡單交叉驗證(Holdout method):最基礎的形式,數據被分為訓練集(如70%)和測試集(如30%)。
k折交叉驗證(k-fold Cross-validation):如上所述,是最常用的交叉驗證方法,k通常取5或10。
留一法交叉驗證(Leave-One-Out Cross-validation, LOOCV):極端情況下的k折交叉驗證,k等于數據集的樣本數,每個樣本單獨作為驗證集。
分層k折交叉驗證(Stratified k-fold Cross-validation):適用于分類問題,確保每個折疊中的類比例與原數據集相同。
時間序列交叉驗證(Time-Series Cross-validation):適用于時間序列數據,保持時間順序,確保訓練集在時間上早于測試集。
通過交叉驗證,不僅可以評估模型的性能,還可以用于模型選擇,即在多個模型或同一模型的不同超參數設置間比較,選擇最優模型。這種方法有助于減少過擬合的風險,提高模型的泛化能力。
hyperopt自動調參
圖片: https://uploader.shimo.im/f/91Fatq8IO1HYM0p9.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
貝葉斯優化是一種基于模型的用于尋找函數最小值的方法。近段時間以來,貝葉斯優化開始被用于機器學習超參數調優,結果表明,該方法在測試集上的表現更加優異,并且需要的迭代次數小于隨機搜索。
Python 環境下有一些貝葉斯優化程序庫,它們目標函數的代理算法有所區別。本部分主要介紹「Hyperopt」庫,它使用樹形 Parzen 評估器(TPE,https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf)作為搜索算法,其他的 Python 庫還包含「Spearmint」(高斯過程代理)和「SMAC」(隨即森林回歸)。
貝葉斯優化問題有四個組成部分:
1)目標函數:我們想要最小化的對象,這里指帶超參數的機器學習模型的驗證誤差
2)域空間:待搜索的超參數值
3)優化算法:構造代理模型和選擇接下來要評估的超參數值的方法
4)結果的歷史數據:存儲下來的目標函數評估結果,包含超參數和驗證損失
通過以上四個步驟,我們可以對任意實值函數進行優化(找到最小值)。
詳解:
1)目標函數
模型訓練目的是最小化目標函數,所以輸出為需要最小化的實值——交叉驗證損失。Hyperopt 將目標函數作為黑盒處理,因為這個庫只關心輸入和輸出是什么。為了找到使損失最小的輸入值。
cross_val_score
對衡量的estimator,它默認返回的是一個array,包含K folder情況下的各次的評分,一般采用mean()。 需要確定這個estimator默認的 scoring 是什么,它的值是越大越匹配還是越小越匹配。如果自己指定了scoring,一定要確定這個scoring值的意義,切記切記! 而如果用戶不指定,一般對于Classification類的estimator,使用accuracy,它是越大越好,那么,hyperopt里面的loss的值就應該是對這個值取負數,因為hyperopt通過loss最小取找最佳匹配。 可以把feature的normalize或者scale作為一個choice,然后看看是否更合適。如果更合適,best里面就會顯示 normalize 為1。
貝葉斯優化的一個實現,一個名為hyperopt的 Python 模塊。
使用貝葉斯優化進行調參可以讓我們獲得給定模型的最佳參數,例如邏輯回歸模型。這也使我們能夠執行最佳的模型選擇。通常機器學習工程師或數據科學家將為少數模型(如決策樹,支持向量機和 K 近鄰)執行某種形式(網格搜索或隨機搜索)的手動調參,然后比較準確率并選擇最佳的一個來使用。該方法可能比較的是次優模型。也許數據科學家找到了決策樹的最優參數,但卻錯過了 SVM 的最優參數。
這意味著他們的模型比較是有缺陷的。如果 SVM 參數調整得很差,K 近鄰可能每次都會擊敗 SVM。貝葉斯優化允許數據科學家找到所有模型的最佳參數,并因此比較最佳模型。這會得到更好的模型選擇,因為你比較的是最佳的 k 近鄰和最佳的決策樹。只有這樣你才能非常自信地進行模型選擇,確保選擇并使用的是實際最佳的模型。
什么是Hyperopt
Hyperopt是一個強大的python庫,用于超參數優化,由jamesbergstra開發。Hyperopt使用貝葉斯優化的形式進行參數調整,允許你為給定模型獲得最佳參數。它可以在大范圍內優化具有數百個參數的模型。
Hyperopt的特性
Hyperopt包含4個重要的特性,你需要知道,以便運行你的第一個優化。
搜索空間
hyperopt有不同的函數來指定輸入參數的范圍,這些是隨機搜索空間。選擇最常用的搜索選項:
hp.choice(label, options)-這可用于分類參數,它返回其中一個選項,它應該是一個列表或元組。示例:hp.choice(“criterion”, [“gini”,”entropy”,])
hp.randint(label, upper)-可用于整數參數,它返回范圍(0,upper)內的隨機整數。示例:hp.randint(“max_features”,50)
hp.uniform(label, low, high)-它返回一個介于low和high之間的值。示例:hp.uniform(“max_leaf_nodes”,1,10)
你可以使用的其他選項包括:
hp.normal(label, mu, sigma)-這將返回一個實際值,該值服從均值為mu和標準差為sigma的正態分布
hp.qnormal(label, mu, sigma, q)-返回一個類似round(normal(mu, sigma) / q) * q的值
hp.lognormal(label, mu, sigma)-返回exp(normal(mu, sigma))
hp.qlognormal(label, mu, sigma, q) -返回一個類似round(exp(normal(mu, sigma)) / q) * q的值
注:每個可優化的隨機表達式都有一個標簽(例如n_estimators)作為第一個參數。這些標簽用于在優化過程中將參數選擇返回給調用者。
目標函數
這是一個最小化函數,它從搜索空間接收超參數值作為輸入并返回損失。這意味著在優化過程中,我們使用選定的超參數值訓練模型并預測目標特征,然后評估預測誤差并將其返回給優化器。優化器將決定要檢查哪些值并再次迭代。你將在一個實際例子中學習如何創建一個目標函數。
Hyperopt是一個開源的Python庫,專門用于自動化地優化機器學習模型的超參數。它通過執行一個高效的搜索過程來尋找最佳的超參數組合,這一過程通常被稱為超參數優化或模型調優。Hyperopt的原理主要包括以下幾個關鍵方面: - 超參數空間定義
首先,用戶需要定義超參數的取值空間,這包括了超參數的類型(如連續、離散、分類等)及其可能的取值范圍。Hyperopt使用一個名為hp.choice、hp.uniform、hp.quniform、hp.loguniform、hp.qloguniform等的函數來定義這些空間。例如,你可以定義學習率在一定區間內的連續取值,或者從幾個特定的激活函數中選擇。 - 目標函數定義
接下來,需要定義一個目標函數,它衡量模型在給定超參數配置下的性能。這個函數通常會涉及訓練模型、在驗證集上評估,并返回一個度量值(如交叉驗證得分、損失函數值等),該值反映了模型在這個超參數配置下的表現。Hyperopt的目標是尋找使該目標函數值最優的超參數組合。 - 優化算法
Hyperopt的核心是其優化算法,最著名的是其采用的Tree-structured Parzen Estimator (TPE)算法。TPE是一種基于貝葉斯優化的方法,它通過構建兩個概率模型(一個用于好的配置,一個用于壞的配置)來指導超參數的搜索。TPE算法在每一步都會根據已有的評估結果來調整搜索方向,優先探索那些看起來更有可能導致高性能配置的區域。這使得搜索更加高效,尤其是在高維參數空間中。 - 分布式和異步特性
Hyperopt支持分布式和異步的超參數優化,這意味著它可以并行運行多個試驗(trials),每個試驗對應一種超參數配置。這在計算資源充足時能顯著加快調參過程。它可以通過隊列或更復雜的分布式計算框架來實現這一點。 - 早停機制
為了提高效率,Hyperopt支持自動在訓練的早期終止無望的試驗(trials),即當模型在初步評估中表現不佳時,系統會自動停止這個試驗,轉而嘗試其他更有可能成功的配置。這一機制稱為自動化的early-stopping,有助于節省計算資源。
綜上,Hyperopt通過靈活的超參數空間定義、高效的TPE優化算法、分布式異步執行能力以及早停機制,提供了一套強大的超參數優化解決方案,適用于多種機器學習模型和任務,幫助研究者和工程師自動發現最優模型配置。
optuna自動調參
Optuna是一款靈活、高效的超參數優化框架,特別設計用于機器學習模型的調參過程。它通過自動化地探索超參數空間,幫助用戶找到模型表現最優的參數組合。下面是Optuna自動調參的基本原理和流程: - 定義目標函數(Objective Function):
這是Optuna調參的核心,你需要定義一個函數,它接收超參數作為輸入,然后返回一個評估指標(如交叉驗證得分、損失函數值等),該指標反映了模型性能。目標是最大化或最小化這個指標。 - 配置超參數空間:
通過Optuna的建議函數(suggestion functions),如suggest_float, suggest_int, suggest_categorical等,定義超參數的取值范圍和類型(連續、整數、分類等)。 - 創建研究(Study):
創建一個Study對象來管理超參數優化的整個過程。在此過程中,你可以指定優化目標是最大化還是最小化目標函數。 - 定義優化方向:
設置優化目標的方向,即確定是尋找最大化還是最小化目標函數值的超參數組合。Optuna通過direction=minimize或direction=maximize來指定。 - 執行優化過程:
使用study.optimize()方法運行優化過程。Optuna會根據你定義的超參數空間和目標函數,自動嘗試不同的超參數組合。 - 采樣算法:
Optuna采用了多種采樣算法,如TPE(Tree-structured Parzen Estimator)、隨機搜索、網格搜索等,來智能地探索超參數空間。TPE是Optuna默認且最為推薦的算法,它通過貝葉斯優化原理,根據歷史試驗結果動態調整搜索策略,以高效找到最優解。 - 剪枝(Pruning):
Optuna支持早停機制,可以在訓練過程中根據一定的規則(如基于性能的閾值)提前終止表現不佳的試驗,以節省計算資源。 - 結果分析:
完成優化后,可以使用study.best_params獲取最佳超參數組合,study.best_value獲取最佳目標函數值,還可以進一步分析所有試驗的結果,了解超參數之間的關系和探索過程。
Optuna的優勢在于其簡潔的API設計、內置的并行化支持、以及對多種機器學習庫(如TensorFlow、PyTorch、LightGBM、XGBoost等)的兼容性,使得它成為機器學習項目中自動調參的有力工具。
Bayesian Optimization
貝葉斯優化其實就是基于模型的超參數優化,根據已有的采樣點預估函數,不斷迭代獲得最大值的一個算法
圖片: https://uploader.shimo.im/f/KTmrntEblVtFlk7I.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
圖片: https://uploader.shimo.im/f/spjjrKXZ0urascia.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3MTY0NzcwNzMsImZpbGVHVUlEIjoiWnprTE1ybTJyQlQwR3BBUSIsImlhdCI6MTcxNjQ3Njc3MywiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo3MzYwMzI4MH0.TMcJ3EETKk3DuZFGzcUMyRthfkf3GUVPSd6CKslcFBU
優點
貝葉樹優化和網格搜索相比,迭代次數少(節省時間),粒度可以到很小。
搜索方式自動化,不需要太多人工參與。
調參過程可以控制。
缺點
不容易找到全局最優解。
過程比較復雜。
randomsearch自動調參
超參數優化也就是常說的調參,python-sklearn里常用的有GridSearchCV和RandomizedSearchCV可以用。其中GridSearchCV的原理很簡明,就是程序去挨個嘗試每一組超參數,然后選取最好的那一組。可以想象,這個是比較費時間的,面臨著維度災難。因此James Bergstra和Yoshua Bengio在2012年提出了超參數優化的RandomSearch方法。
RandomizedSearchCV是在論文的基礎上加入了cross-validation
RandomSearchCV是如何"隨機搜索"的:
考察其源代碼,其搜索策略如下:
(a)對于搜索范圍是distribution的超參數,根據給定的distribution隨機采樣;
(b)對于搜索范圍是lit的超參數,在給定的list中等概率采樣;
(c)對a、b兩步中得到的n_iter組采樣結果,進行遍歷。
(補充)如果給定的搜索范圍均為list,則不放回抽樣n_iter次。
隨機搜索(Random Search)是一種簡單的超參數優化方法,它在超參數的定義范圍內隨機抽取值來進行模型的訓練和評估,以期找到性能較好的超參數組合。與網格搜索(Grid Search)相比,隨機搜索雖然放棄了對所有可能組合的窮舉,但能在更廣泛的參數空間里探索,尤其適用于參數空間較大時,能更高效地找到較好的參數配置。以下是隨機搜索自動調參的基本原理和步驟: - 定義超參數空間:首先明確各個超參數的取值范圍,例如學習率可以在[0.001, 0.1]之間,樹的深度可以是[3, 10]之間的整數等。
- 隨機抽樣:根據超參數空間的定義,隨機抽取超參數值的組合。每次抽取都是獨立的,且遵循各參數的分布規則(連續參數通常均勻或高斯分布抽取,離散參數則是從定義的集合中隨機選取)。
- 模型訓練與評估:使用抽取的超參數組合訓練模型,并在驗證集上評估模型性能。常用的評估指標包括準確率、AUC-ROC、LogLoss等,具體取決于任務類型。
- 重復過程:重復上述抽樣、訓練和評估步驟多次,以收集多組超參數性能數據。
- 選擇最優參數:所有嘗試結束后,選擇使得模型性能最佳的超參數組合作為最終的超參數設置。
優點:
效率高:特別是當超參數空間很大時,相比網格搜索,隨機搜索可以更高效地探索參數空間,因為不需要遍歷所有可能的組合。
簡單易實現:隨機搜索的實現相對簡單,不需要復雜的優化算法,容易集成到現有的機器學習管道中。
避免局部最優:由于搜索過程的隨機性,有助于跳出局部最優,發現全局或更優的超參數配置。
缺點:
可能錯過最優解:由于是隨機抽樣,即使最優解存在于定義的參數空間內,也可能因為抽樣次數有限而未能發現。
缺乏指導性:相比于貝葉斯優化等方法,隨機搜索沒有利用歷史試驗的信息來指導后續的搜索,可能不夠高效。
隨機搜索通常配合交叉驗證一起使用,以更穩健地評估模型性能,減少因數據劃分的隨機性導致的性能評估波動。此外,隨機搜索可以在并行計算環境中高效運行,進一步縮短總的調參時間。
gridsearch自動調參
GridSearchCV 是一個在 scikit-learn 庫中用于執行網格搜索(grid search)參數調優的方法。網格搜索是一種通過遍歷預定義的參數網格來確定機器學習模型最佳超參數組合的技術。
自動調參,適合小數據集。相當于寫一堆循環,自己設定參數列表,一個一個試,找到最合適的參數。數據量大可以使用快速調優的方法-----坐標下降【貪心,拿當前對模型影響最大的參數調優,直到最優,但可能獲得的是全局最優】。
GridSearchCV.fit(X, y[, groups]) 方法是 sklearn.model_selection.GridSearchCV 類的一個重要方法,用于執行網格搜索過程,即遍歷給定的參數網格,并針對每個參數組合利用交叉驗證策略訓練和評估模型。
調用 GridSearchCV.fit(X, y) 后,實例將保存以下屬性,供后續分析和使用:
best_params_: 最佳參數組合,即在交叉驗證過程中表現最好的參數設置。
best_estimator_: 使用最佳參數重新擬合得到的模型實例。
best_score_: 在交叉驗證過程中,最佳參數組合對應的平均得分(基于指定的 scoring 函數)。
cv_results_: 字典形式的詳細結果,包含了所有參數組合、得分、訓練時間等信息。
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise’, return_train_score=’warn’)
estimator:所使用的分類器,比如:estimator=RandomForestClassifier(min_samples_split=100, min_samples_leaf=20, max_depth=8, max_features=‘sqrt’, random_state=10),并且傳入除需要確定最佳的參數之外的其他參數。每個分類器都需要一個scoring參數或者score方法。
param_grid:值為字典或列表,即需要最優化的參數的取值,param_grid =param_test1,param_test1 = {‘n_estimators’:range(10,71,10)}
scoring:準確評價標準,默認為None(使用estimator的誤差估計函數),這時需要使用score函數;或者如scoring=‘roc_auc’,根據所選模型不同,評價準則不同。
cv:交叉驗證參數,默認為None
refit:默認為True,程序將會以交叉驗證訓練集得到的最佳參數,重新對所有可用的訓練集與測試集進行,作為最終用于性能評估的最佳模型參數。即在搜索參數結束后,用最佳參數結果再次fit一遍全部數據集。
iid:默認True,為True時,默認為各個樣本fold概率分布一致,誤差估計為所有樣本之和,而非各個fold的平均。
verbose:日志冗長度,int:冗長度,0:不輸出訓練過程,1:偶爾輸出,>1:對每個子模型都輸出。
n_jobs: 并行數,int:個數,-1:跟CPU核數一致, 1:默認值。
pre_dispatch:指定總共分發的并行任務數。當n_jobs大于1時,數據將在每個運行點進行復制,這可能導致OOM,而設置pre_dispatch參數,則可以預先劃分總共的job數量,使數據最多被復制pre_dispatch次,進行預測的常用方法和屬性
grid.fit():運行網格搜索
grid_scores_:給出不同參數情況下的評價結果
best_params_:描述了已取得最佳結果的參數的組合
best_score_:成員提供優化過程期間觀察到的最好的評分
參考:
https://blog.csdn.net/lccever/article/details/80535058
https://zhuanlan.zhihu.com/p/668817682
https://pip.pypa.io/en/latest/topics/configuration/
https://zhuanlan.zhihu.com/p/342297405
https://blog.csdn.net/weixin_43522665/article/details/132051894
https://www.cnblogs.com/wuzc/p/12798173.html
https://www.cnblogs.com/Lee-yl/p/9190192.html
https://www.zhihu.com/question/485089505
https://zhuanlan.zhihu.com/p/660468945
https://blog.csdn.net/m0_56006701/article/details/130832837
https://zhuanlan.zhihu.com/p/672975755
https://blog.51cto.com/u_16099176/10196681
https://www.jianshu.com/p/ded6abd50e5a
https://blog.csdn.net/weixin_42327752/article/details/121428875
https://blog.csdn.net/reept/article/details/135296762
https://zhuanlan.zhihu.com/p/485403000
https://www.cnblogs.com/cgmcoding/p/14447895.html
https://blog.csdn.net/weixin_42691585/article/details/113971857
https://cloud.tencent.com/developer/article/2009339
https://zhuanlan.zhihu.com/p/693674773
https://blog.csdn.net/qq_41076797/article/details/102941095