邏輯回歸(Logistic Regression, LR)
邏輯回歸是一種廣義線性模型,通過對數概率函數,將線性函數的結果進行映射,從而將目標函數的取值空間從\((- \infty ,+\infty )\)映射到了\((0,1)\),從而可以處理分類問題。注意:邏輯回歸是一種分類算法。
-
前置知識
-
對數概率函數
又稱
對數幾率函數,sigmoid函數等。函數表達式:\[g(z)=\frac{1}{1+e^{-z}} \]s形曲線,值域:\((0,1)\)
且其導數滿足:
\[g'(z)=g(z)(1-g(z)) \] -
梯度
梯度的本質是一個向量(矢量),表示某一函數在該點處的方向導數沿着該方向能夠取得最大值,即函數在該點處沿着梯度的方向變化最快,變化率最大。
參見:梯度-百度百科
-
指數運算法則
\[log_a\prod_{i=0}^m h(x)=\sum_{i=0}^m log_ah(x)\\ log_aM^n=nlog_aM \]
-
-
定義
二項邏輯回歸模型的條件概率分布:
\[P(Y=1|X)=\frac{1}{1+e^{-\theta ^Tx}}\\ P(Y=0|X)=1-\frac{1}{1+e^{-\theta ^Tx}} \]其中,\(x\in R^n\)是輸入,\(Y\in \{0,1\}\)是輸出,\(\theta ^T\)是待學習參數。對於給定的輸入實例\(X\),將樣本\(X\)輸入到上述公式中求得\(P(Y=1|X)\)和\(P(Y=0|X)\),比較兩個條件概率值,將樣本歸到條件概率值較大的那一類。
-
梯度下降法求解邏輯回歸
\[h_\theta=\frac{1}{1+e^{-\theta^Tx}} \]即:
\[h_\theta=g(\theta^Tx) \]其中,\(g(z)\)為上述的對數概率函數或稱
sigmoid函數構造對應的最大似然:
\[L(\theta)=\prod_{i=1}^mP(y_i|x_i;\theta)=\prod_{i=1}^{m}(h_{\theta}(x_i))^{y_i}(1-h_{\theta}(x_i))^{1-y_i} \]兩端取對數:
\[l(\theta)=logL(\theta)=\sum_{i=1}^{m}(y_ilogh_{\theta}(x_i)+(1-y_i)log(1-h_{\theta}(x_i))) \]為簡化問題,現在以只有一個訓練樣本的情況為例(實際這種情形就是隨機梯度下降):
\[l(\theta)=ylogh_{\theta}(x)+(1-y)log(1-h_\theta(x))\\ \]對參數\(\theta\)求偏導:
\[\frac{\partial}{\partial \theta_j} l(\theta)=(y\frac{1}{g(\theta^Tx)}-(1-y)\frac{1}{1-g(\theta^Tx)})\frac{\partial}{\partial \theta_j}g(\theta^Tx)\\ \frac{\partial}{\partial \theta_j} l(\theta)=(y\frac{1}{g(\theta^Tx)}-(1-y)\frac{1}{1-g(\theta^Tx)})g(\theta^Tx)(1-g(\theta^Tx))\frac{\partial}{\partial\theta_j}\theta^Tx\\ 該步使用g'(z)=g(z)(1-g(z))\\ \frac{\partial}{\partial \theta_j} l(\theta)=(y(1-g(\theta^Tx))-(1-y)g(\theta^Tx))x_j\\ 注意:\frac{\partial}{\partial \theta_j}\theta^Tx=x_j,x_j為樣本x的第j個特征\\ \frac{\partial}{\partial \theta_j} l(\theta)=(y-h_{\theta}(x))x_j\qquad 整理結果 \]求得參數梯度,現在希望最大化似然函數,因此梯度上升,迭代參數。參數\(\theta\)的迭代公式:
\[\theta_{j+1}:=\theta_j+\alpha(y-h_{\theta}(x))x_j \]其中,\(\alpha\)為學習率,\((y-h_{\theta}(x))x_j\)為上述所求得的梯度
推廣至m個樣本:
\[\theta_{j+1}:=\theta_j+\alpha\frac{1}{m}\sum_{i=1}^m(y^i-h_{\theta}(x^i))x^{i}_j \] -
邏輯回歸算法流程
輸入:訓練數據集$T={(x_1,y_1),(x_2,y_2),...,(x_m,y_m)},x_1\in X \subseteq R^n,y_1\in Y \subseteq R^n $
輸出:邏輯回歸模型\(\hat f(x)\)
- 隨機初始化參數\(\theta\);
- 對樣本\(i=1,2,...,m\),計算\(\theta_{j+1}:=\theta_j+\alpha\frac{1}{m}\sum_{i=1}^m(y^i-h_{\theta}(x^i))x^{i}_j\),其中:\(j=1,2,...,n\)為樣本的特征數
- 迭代獲得邏輯回歸模型
-
邏輯回歸算法的快速迭代
在實際應用中,為了提高算法收斂速度和節省內存,在迭代求解時往往采用高效的優化算法如LBFGS、信賴域算法,這些算法是基於批量處理的,無法高效處理超大規模數據集,也無法對線上模型進行快速實時更新。隨機梯度下降是相對批處理的另一種優化算法,每次只用一個樣本更新模型權重。谷歌的FTRL就是基於隨機梯度下降的一種邏輯回歸優化算法。
FTRL算法參見:各大公司廣泛使用的在線學習算法FTRL詳解
-
邏輯回歸應用
邏輯回歸適合用來學習需要大規模訓練的樣本和特征,對於計算廣告等有天然優勢。其缺點是:1.模型表達能力弱,需要大量的特征組合提高特征的表達;2.模型簡單,容易欠擬合。
對邏輯回歸的求解有很多優化方法,如
BFGS、LBFGS、共軛梯度法、信賴域法,其中前兩種是牛頓法的變種,LBFGS算法是BFGS在內存受限情況下的近似優化;針對邏輯回歸在線學習的稀疏性和准確性,邏輯回歸又有FOBOS、RDA和FTRL等變種。邏輯回歸需要注意正則化問題,\(L_1\)正則(又稱
LASSO)假設模型參數滿足拉普拉斯分布,\(L_2\)正則(又稱RIDGE)假設模型參數滿足高斯分布。參見:變量的選擇——Lasso&Ridge&ElasticNet,線性回歸中的抗過擬 -
邏輯回歸練習題,參見:10道題帶你了解邏輯回歸模型
-
邏輯回歸是有監督機器學習算法,訓練時需要輸入變量X和目標變量Y。
-
邏輯回歸是分類算法。
-
能否用神經網絡設計一個邏輯回歸算法?
答:可以,神經網絡是一個通用的逼近算法,所以它可以實現邏輯回歸。
-
邏輯回歸中可以用哪種方法來調整數據?
答:邏輯回歸使用最大似然估計來訓練回歸模型。
-
類似於線性回歸的R-squared,判斷邏輯回歸表現的一個方法是AIC,那么AIC的值是越大越好還是越小越好?
答:AIC最小的邏輯回歸模型最佳。
-
在訓練邏輯回歸模型之前,對特征進行標准化是必須的嗎?
答:非必須,特征標准化的主要目的是實現模型的最優化。
-
哪種算法可以用於邏輯回歸的變量選擇?
答:LASSO,RIDGE等。
-
因子分解機(Factorization Machine, FM)
邏輯回歸無法學習到特征間的組合關系,而特征組合關系在推薦中是比較常見的。例如,同一個用戶在不同時間或地點感興趣的廣告是不同的,在這里就需要對表征用戶的特征,表征時間的特征,表征地點的特征進行組合,以獲得較好的預測。利用模型做特征組合,可以使用支持向量機的核函數來實現特征之間的交叉,但是多項式核函數的問題在於二次參數過多,設特征維數為\(n\),則二次項的參數數目為\(\frac{n(n+1)}{2}\),增加模型復雜度並且獲得的特征矩陣十分稀疏,降低模型表現。因子分解機及場感知因子分解機能夠自動做特征組合,並且算法效率較高。
-
前置知識
-
向量點乘
向量點乘輸出標量,運算的數學表示:\(<·,·>\)
\[<v_i,v_j>=\sum_{f=1}^kv_{i,f}·v_{j,f} \]
-
-
因子分解機原理
因子分解機要求二次項參數矩陣是低秩的,並且能夠分解為低秩矩陣的乘積。所有二次項參數矩陣\(W\)可分解為\(W=V^TV\),\(V\)的第j列對應\(X\)的第j維特征為二次項參數矩陣貢獻的向量,換言之,\(w_{ij}=<v_i,v_j>\)就是因子分解機的核心思想,其將巨大的二次項參數矩陣分解為較小的矩陣:\[\phi_{FM}(w,x)=w_0+\sum_{i=0}^nw_ix_i+\sum_{i=1}^n\sum_{j=i+1}^n<v_i,v_j>x_ix_j \]其中,n是樣本維度(對離散特征進行onehot等操作后的特征維度);\(x_i\)表示第i個特征(如果是離散特征,那么onehot后只有一個維度值為1,其余維度為0,在這種情況下\(x_i\)的值通常是0或1;而對於一般的連續型特征,\(x_i\)是經過歸一化或離散后的數值),注意到:在數據稀疏情況下,同時滿足\(x_i\)和\(x_j\)都不為0的情況很少,如果不進行矩陣分解,\(x_ix_j\)的系數很難訓練;參數\(w_0\in \mathbb{R},w\in \mathbb{R}^n,V\in \mathbb{R}^{n×k}\),\(v_i\)是i維特征的權重向量,該隱向量長度為k,\(k\in \mathbb{N}^+\)是因子分解機的超參數(一般設置在100以內,且\(k\ll n\)) ,\(v_i=(v_{i1},v_{i2},...,v_{ik})\),用內積結果\(<v_i,v_j>\)來表示\(x_ix_j\)的系數:
\[V=\begin{pmatrix} v_{11} & v_{12} & ... & v_{1k}\\ v_{21} & v_{22} & ... & v_{2k}\\ ... & ... & ... & ...\\ v_{n1} & v_{n2} & ... & v_{nk} \end{pmatrix}_{n×k}= \begin{pmatrix} v_1\\ v_2\\ ...\\ v_n \end{pmatrix} \]實際上,\(v_i\)可以理解為特征分量\(x_i\)的另一種表示形式,類似於詞向量的表示形式。詞向量中將一個單詞轉化為向量表示形式,單詞是固定的,因此一個單詞對應一個詞向量;而在因子分解機中,將一個類別特征(onehot之前的特征)轉化為一個向量,由於該類別特征可以有多個取值,並且每種取值對應一個向量,也即上述將類別特征進行onehot之后,每一個特征分量\(x_i\)會對應一個\(v_i\)。因此,因子分解機確實將類別特征轉化為向量形式,只不過向量會根據特征的取值發生變化。
此時,二次項組合參數就可以被分解為:
\[W=VV^T=\begin{pmatrix} v_1\\ v_2\\ ...\\ v_n \end{pmatrix}\begin{pmatrix} v_1^T ,v_2^T, ..., v_n^T \end{pmatrix} \]將組合參數進行分解的優勢:
- 從原先要求的\(\frac{n(n-1)}{2}\)個組合參數變成了求矩陣\(V\),參數數量降低為\(nk\),其中k一般遠小於n
- 削弱高階參數間的獨立性。k越大,對特征分量的表征能力越強,高階參數間獨立性越強,模型越精細;k越小,模型泛化能力越強
參數因子化使得組合特征\(x_hx_i\)和\(x_ix_j\)不再相互獨立,\(x_hx_i\)和\(x_ix_j\)的系數分別為\(<v_h,v_i>\)和\(<v_i,v_j>\),它們有共同項\(v_i\)。通常,由於數據稀疏,特征分量\(x_i\)很多樣本值是0,組合參數很難學習到,但是可以通過特征i與所有其它特征的組合,學習到特征i對應的隱向量\(v_i\),因此所有包含特征\(x_i\)的非零組合特征的樣本都可以用來學習隱向量\(v_i\),這很大程度上避免了數據稀疏性造成的影響,而在支持向量機的多項式模型中,\(w_{hi}\)和\(w_{ij}\)就是相互獨立學習的。
上述因子分子機公式是一個通用的擬合方程,可以采用不同的損失函數解決分類、回歸問題,如采用均方差損失函數,就可以使用該擬合方程求解回歸問題。
-
因子分解機化簡
因子分解機的計算復雜度,考慮計算量最大的二次項:
\[\sum_{i=1}^n\sum_{j=i+1}^n<v_i,v_j>x_ix_j \]計算復雜度為\(O(kn^2)\)。
可以先把標量\(x_i\)和對應的隱向量\(v_i\)相乘,並存儲下來,即:
\[u_i=x_iv_i \]則上式變為:
\[\sum_{i=1}^n\sum_{j=i+1}^n<v_i,v_j>x_ix_j=\sum_{i=1}^{n}\sum_{j=i+1}^{n}<u_i,u_j>=\sum_{f=1}^k(\sum_{i=1}^n\sum_{j=i+1}^nu_{i,f}u_{j,f}) \]考慮到:
\[(a+b+c)^2=a^2+b^2+c^2+2ab+2ac+2bc \]左側只需要1次乘法,右側需要6次乘法。因此將二次項湊成和的平方可以節約計算。
因此二次項可變為:
\[\begin{split} \sum_{f=1}^k(\sum_{i=1}^n\sum_{j=i+1}^nu_{i,f}u_{j,f})&=\frac{1}{2}\sum_{f=1}^{k}(\sum_{i=1}^n\sum_{j=1}^nu_{i,f}u_{j,f}-\sum_{i=1}^nu_{i,f}^2)\\ &=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nu_{i,f}^2)-\sum_{i=1}^nu_{i,f}^2) \end{split} \]完整的變換:
\[\begin{split} \sum_{i=1}^n\sum_{j=i+1}^n<v_i,v_j>x_ix_j &=\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}<v_i,v_j>x_ix_j-\frac{1}{2}\sum_{i=1}^{n}<v_i,v_i>x_ix_i\\ &=\frac{1}{2}(\sum_{i=1}^n\sum_{j=1}^n\sum_{f=1}^kv_{i,f}v_{j,f}x_{i}x_j-\sum_{i=1}^n\sum_{f=1}^kv_{i,f}v_{i,f}x_ix_i)\\ &=\frac{1}{2}\sum_{f=1}^k((\sum_{i=1}^nv_{i,f}x_i)(\sum_{j=1}^nv_{j,f}x_j)-\sum_{i=1}^{n}v_{i,f}^2x_i^2) \\ & \sum_{i=1}^nv_{i,f}x_i和\sum_{j=1}^nv_{j,f}x_j地位等價\\ &=\frac{1}{2}\sum_{f=1}^{k}((\sum_{i=1}^{n}v_{i,f})^2-\sum_{i=1}^{n}v_{i,f}^2x_i^2) \end{split} \]因子分解機的復雜度被優化到\(O(kn)\)。
-
場感知因子分解機(Field Factorization Machine, FFM)
因子分解機任意兩組特征交叉的隱向量都是相關的,這實際上限制了模型的復雜度。但如果任意兩組特征組合是完全獨立的,這與支持向量機核函數來計算特征交叉類似,有着極高的復雜性和自由度,模型計算過於復雜。場感知因子分解機是兩者的折中。
場感知因子分解機把具有相同性質的特征都歸於同一個“場”,按照場級別分別計算當前特征與其它場里特征組合時的特征向量。即認為不同場的特征是相互獨立的,同一場內的特征是不獨立的。
在場感知因子分解機中,每一維的特征\(x_ix_j\),針對其它特征的每一種場\(f_if_j\)組合,都會學習一個隱變量\(v_{i,f_j}v_{j,f_i}\),每個特征屬於某個特定的場。每個特征將映射出多個隱向量,每個隱向量對應一個場,這也就是說,一個特征在不同場中對應的隱向量是不同的。當兩個特征組合時,它們分別使用這兩個特征對應場的隱向量做內積。場感知因子分解機的模型方程為:
\[\phi _{FFM}(w,x)=\sum_{i=1}^{n}\sum_{j=i+1}^n<v_{i,f_j},v_{j,f_i}>x_i·x_j \]其中,\(v_{j,f_i}\)是第j個特征所屬的場。若隱向量長度為k,則場感知因子分解機的二次參數有nfk個,遠多於因子分解機的nk個。場感知因子分解機對每個樣本的預測的時間復雜度為\(O(kn^2)\),但場感知因子分解機的k值一般遠小於因子分解機的k值。
在因子分解機中,每一維特征的隱向量只有一個,因此因子分解機可以看作是場感知因子分解機的特例,即因子分解機是把所有特征都歸屬到一個場時的場感知因子分解機。
-
場感知因子分解機的應用
場感知因子分解機可以自動做特征組合和處理高維稀疏特征,因此它在處理大量離散特征的問題上往往有比較好的效果。使用場感知因子分解機時要注意對連續特征做歸一化或離散化。
因子分解機、場感知因子分解機和其它模型的對比關系:
- 因子分解機和場感知因子分解機。場感知因子分解機對因子分解機引入場的概念,增加了模型復雜度和模型的表達能力。
- 因子分解機和神經網絡。神經網絡難以直接處理高維稀疏的離散特征,因為這導致了神經元的連接參數太多,而因子分解機可以看作對高維稀疏特征的離散特征做嵌入。
- 因子分解機和梯度提升樹。因子分解機與梯度提升樹都可以做特征組合,當數據不是高度稀疏時,梯度提升樹可以有效的學習到比較復雜的特征組合,但在高度稀疏的數據中,特征二階組合就足以讓絕大多數組合特征找不到樣本。
- 因子分解機和其它模型。因子分解機是一種比較靈活的模型,通過合適的特征變換方式,因子分解機可以模擬二階多項式核的支持向量機模型、MF模型、SVD++模型等。但SVD++與MF擴展性不如因子分解機,支持向量機核函數計算復雜度較高。(MF、SVD++均為矩陣分解模型,參見:推薦系統總結MF->PMF->CTR->CDL->CNN,矩陣分解之SVD和SVD++)
-
DeepFM
因子分解機由於計算復雜度的限制,只用到了二階特征組合。對於高階特征組合,可以通過多層的神經網絡即DNN解決。但對於稀疏高維特征,直接輸入DNN中,將導致網絡參數過多:
類似於場感知因子分解機的思想,將特征分為不同的“場”:
然后再加兩層全連接層,那么就可以把特征組合出來了。但是這樣,低階特征和高階特征的組合隱含地體現在隱層中,將低階特征組合單獨建模,然后融合高階特征組合,能夠更為充分的保留信息。也就是說,將DNN和因子分解機進行合理的融合:
這里有一個子問題:傳統的機器學習算法和深度學習的結合。二者的融合總的來說有兩種方式:一是並行結構,二是串行結構:
而DeepFM是並行結構的典型代表。
-
DeepFM模型
對照上述的網絡融合中的並行結構,DeepFM的模型結構:

DeepFM包含兩個部分:神經網絡和因子分解機,這兩部分共享同樣的輸入。
-
神經網絡

神經網絡部分是一個前饋神經網絡,可以學習高階特征組合。注意:輸入是高維稀疏數據,如onehot處理后的數據,因此需要引入embedding layer將輸入向量壓縮到低維稠密向量:

其中,\(k\)即是embedding size。這里神經網絡做嵌入的過程,和因子分解機中二階特征組合的過程是一致的,因此在因子分解機中得到的隱向量\(v_{ij}\)現在作為了嵌入層的權重,參見論文精讀-DeepFM。另外,盡管不同“場”的輸入維度不同,經過嵌入后,向量長度均為\(k\)。
在嵌入層,因子分解機和神經網絡的參數是共享的。因子分解機中的參數會參與到梯度下降中,可以理解為直接用神經網絡做嵌入,無疑比因子分解機本身的嵌入能力更強。
共享嵌入帶來兩個好處:
- 從原始數據中同時學習到了低階和高階特征
- 不再需要特征工程。而Wide&Deep模型需要
-
因子分解機

和上述的因子分解機相同,可以觀察到上圖FM Layer中黑線表示的一階特征組合,紅線表示的二階特征組合。
-
模型輸出
DeepFM的預測結果由神經網絡和因子分解機共同決定:
\[y=sigmoid(y_{FM}+y_{DNN}) \]
另外,出現了DeepFM的升級版xDeepFM,參見:推薦系統遇上深度學習(二十二)--DeepFM升級版XDeepFM模型強勢來襲!
本部分代碼示例參見:
-
-
梯度提升樹(Gradient Boosting Decison Tree, GBDT)
梯度提升樹是一種基於回歸樹的集成學習方法,通過構造多個弱的回歸樹作為基學習器,並將這些樹的結果累加起來作為最終的預測輸出。
-
前置知識
-
機器學習的大致流程就是確定模型集合;定義經驗損失函數;利用給定的數據集\(\{(x_i,y_i)\}\)從模型集合中尋找最佳模型(一般就是尋找最佳的模型參數)。
-
決策樹是一種模型,它的主要思想是將輸入空間划分為不同的子區域,然后給每個子區域確定一個值,該子區域又稱為樹的葉子節點。如果是分類樹,這個值就是類別;如果是回歸樹,這個值就是實數值,該值又稱作葉子節點的權重值,分數等。
\[f(x)=\sum_{j=1}^Jc_jI(x\in R_j) \]其中,\(f(x)\)是決策樹表征的函數;\(c_j\)是子區域對應的值;\(J\)為子區域的個數;\(I\)是指示函數,若\(x\in R_j\)則\(I(x\in R_j)=1\),否則為0
-
加法模型
\[h(x)=\sum_{m=1}^M\beta_mf_m(x) \]\(f_m(x)\)稱作基學習器;\(\beta_m\)是基學習器的系數,一般假設大於0
-
梯度提升樹中的決策樹是回歸樹,不是分類樹,也就是說,只有回歸樹才有所謂的梯度提升。
-
泰勒公式
二階泰勒展開:
\[f(x+\Delta x)=f(x)+\frac{\partial f}{\partial x}\Delta x+\frac{1}{2}\frac{\partial ^2f}{\partial x^2}\Delta x^2+o(\Delta x) \]示例:對\(L(y,h_m(x)+\beta f(x))\)進行一階泰勒展開,令\((y,h_m(x))\)為\(x\),\(\beta f(x)\)為\(\Delta x\),則:
\[L(y,h_m(x)+\beta f(x))\approx L(y,h_m(x))+\beta f(x)\frac{\partial L(y,h_m(x))}{\partial h_m(x)} \]
-
-
梯度提升樹原理
梯度提升樹是集成學習Boosting家族的一員,在訓練時采用前向分步算法,首先確定第一棵樹擬合的值,然后基於之前所有樹的誤差來更新並訓練下一棵樹,一步一步迭代下去直到梯度提升樹構建完畢。
-
梯度提升樹
簡單起見,首先介紹與梯度提升樹相近的提升樹(
Boosting Tree)。-
提升樹算法(以回歸問題為例)
輸入:訓練數據集\(T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\},x_i\in X\subseteq \mathbb{R}^n,y\in Y\subseteq{R}\)
輸出:提升樹\(f_M(x)\)
-
初始化\(f_0(x)=0\)
-
對\(m=1,2,...,M\):
a. 計算殘差:\(r_{mi}=y_i-f_{m-1}(x_i),\quad i=1,2,...,N\)
其中,\(f_{m-1}(x)\)為第\(m-1\)步時回歸樹加和的模型
b. 擬合殘差\(r_{mi}\)學習一個回歸樹,獲得\(T(x;\Theta_m)\)
其中,\(T(x;\Theta_m)\)是第\(m\)步的訓練獲得的基學習器,通過經驗風險最小化確定這棵樹的參數:
\[\Theta_m=\mathop{argmin}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x;\Theta_m)) \]對於回歸問題而言,\(L(y,\hat{y})\)可采用平方損失誤差
c. 更新\(f_m(x)=f_{m-1}(x)+T(x;\Theta_m)\)
-
獲得回歸問題的提升樹:
\[f_M(x)=\sum_{m=1}^MT(x;\Theta_m) \]
在提升樹中,每一棵樹的生成采用的訓練數據都是上次預測結果與真實值的殘差,這個殘差會不斷減小。
這實際就是前置知識中
加法模型的典型應用。注意:由於這里基學習器是回歸樹,葉子節點的值是實數值,因此基學習器前的系數可省略。 -
-
梯度提升樹GBDT
梯度提升樹的算法流程與提升樹類似,只是不再使用殘差作為一棵樹的擬合目標,而是使用損失函數的梯度作為擬合目標。梯度提升算法利用最速下降法的近似方法,考慮經驗損失函數:
\[\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+\beta f(x_i)) \]其中,\(N\)為樣本數,\(f_{m-1}(x_i)\)為第\(m-1\)步時所有樹的累加,\(\beta\)為基學習器的系數,\(f(x_i)\)為本次要訓練的樹,即:
\[f(x)=\sum_{j=1}^Jc_jI(x\in R_j) \]簡單起見,考慮一個樣本,對損失函數進行一階泰勒展開:
\[L(y_i,f_{m-1}(x_i)+\beta f(x_i))=L(y_i,f_{m-1}(x_i))+\beta f(x_i)\frac{\partial L(y_i,f_{m-1}(x_i))}{\partial f_{m-1}(x_i)} \]由於\(\beta\)是大於0的,要使\(L(y_i,f_{m-1}(x_i)+\beta f(x_i))\leq L(y_i,f_{m-1}(x_i))\),令
\[f(x_i)=-\frac{\partial L(y_i,f_{m-1}(x_i))}{\partial f_{m-1}(x_i)} \]每一個樣本點上,上式盡可能成立的\(f(x_i)\)就是我們本次要構建的樹。
簡言之,對損失函數\(L(y,\hat{y})\)求關於\(f(x)\)的偏導,然后帶入\(f_{m-1}(x)\):
\[r_{mi}=-[\frac{\partial L(y_i,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)} \]就是每一步上,一棵樹需要擬合的目標。
梯度提升樹算法流程
輸入:訓練數據集\(T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)},x_i\in X \subseteq \mathbb{R}^n,y_i\in Y \subseteq \mathbb{R}\);損失函數\(L(y,f(x))\)
輸出:回歸樹\(\hat{f(x)}\)
-
初始化
\[f_0(x)=\mathop{argmin}_c\sum_{i=1}^NL(y_i,c) \] -
對\(m=1,2,...,M\):
a. 對\(i=1,2,...,N\),計算
\[r_{mi}=-[\frac{\partial L(y_i,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)} \]b. 對\(r_{mi}\)擬合一個回歸樹,得到第\(m\)棵樹的葉節點區域\(R_{mj},j=1,2,...,J\)
c. 對\(j=1,2,...,J\),計算
\[c_{mj}=\mathop{argmin}_c\sum_{x\in R_{mj}}L(y_i,f_{m-1}(x_i)+c) \]d. 更新\(f_m(x)=f_{m-1}(x)+\sum_{j=1}^Jc_{mj}I(x\in R_{mj})\)
-
獲得回歸樹:
\[\hat{f(x)}=f_M(x)=\sum_{m=1}^M\sum_{j=1}^Jc_{mj}I(x\in R_{mj}) \]
同樣,梯度提升樹的基學習器是回歸樹,加法模型中每個基學習器前的系數會內化到回歸樹內部,因此可省略。
注意到當使用\(r_{mi}\)擬合出一個回歸樹后,2-c進一步使用整體損失函數對這棵回歸樹的值進行了優化。這就是”先局部,后整體“的思想,就是先通過逐步的局部優化獲得一個結果,然后從全局的角度優化結果。決策樹的生成和剪枝也是這樣,先通過局部優化,如信息增益等指標選擇特征,得出一個決策樹;再從降低整體損失的角度,進行剪枝。
梯度提升樹和提升樹的關系:
提升樹每一次提升都是用上次的預測結果和訓練數據真實值的誤差作為新的訓練數據進行進一步學習,而梯度提升樹把對誤差的擬合替換為對損失函數梯度的擬合。提升樹主要缺點有:在回歸問題中,提升樹的平方損失目標函數對於異常值特別敏感;對於一些損失函數,不易優化,如絕對值損失函數等。
-
-
-
XGBoost
XGBoost是Boosting Tree的一種實現,相比於梯度提升樹,XGBoost對損失函數進行了二階泰勒展開,同時用到了一階和二階導數;並且引入了適用於樹模型的正則化項用於控制模型的復雜度,正則化項包含樹的葉子節點個數、葉子節點分數的\(L_2\)正則。
目標函數:
\[Obj(\Theta)=L(\Theta)+\Omega (\Theta)\\ Obj=\sum_{i=1}^nl(y_i,\hat{y_i})+\sum_{k=1}^K\Omega(f_k) \]可以看到,目標函數包含兩個部分:訓練誤差和樹的復雜度。其中,樹的復雜度包括:a.樹的深度;b.內部節點個數;c.葉子節點個數(T);d.葉子節點分數(w)
和梯度提升樹的思路一致,
\[\begin{split} Obj^{(t)}&=\sum_{i=1}^nl(y_i,\hat{y_{i}}^{(t)})+\Omega(f_t(x))\\ &=\sum_{i=1}^nl(y_i,\hat{y_{i}}^{(t-1)}+f_t(x_i))+\Omega(f_t)+constant \end{split} \]思考如何尋找一個\(f_t\)來優化這個目標函數。
這里和梯度提升樹不同,XGBoost進行了二階泰勒展開,令\(x=(y_i,\hat{y_i}^{(t-1)}),\Delta x=f_t(x_i)\):
\[Obj^{(t)}\approx \sum_{i=1}^n(l(y_i,\hat{y_i}^{(t-1)})+g_if_t(x)+\frac{1}{2}h_if_t^2(x_i))+\Omega(f_t)+constant \]其中,\(g_i\)為一階導,\(h_i\)為二階導
\[g_i=\frac{\partial l(y_i,\hat{y}^{(t-1)})}{\partial \hat{y}^{(t-1)}},\\ h_i=\frac{\partial ^2 l(y_i,\hat{y}^{(t-1)})}{{\partial \hat{y}^{(t-1)}}^2} \]\(l(y_i,\hat{y_i}^{(t-1)})\)為常數項;\(f_t(x)=W_{q_{(x)}}\)為決策樹表征的函數,\(w\in \mathbb{R}^T\)表示樹的葉子權重,\(q(x)\)表示樹結構,這是上述對決策樹\(f(x)=\sum_{j=1}^Jc_jI(x\in R_j)\)的另一種記法。
去除目標函數中的常數項:
\[Obj=\sum_{i=1}^n(g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i))+\Omega(f_t) \]

定義葉子\(j\):
\[I_j=\{i|q(x_i)=j\} \]表示第\(j\)個葉子中的樣本,其中\(q(x_i)\)表示樣本\(x_i\)所屬的葉節點
\[\begin{split} Obj^{(t-1)}&\approx \sum_{i=1}^n(g_if_t(x_i)+\frac{1}{2}h_if^2_t(x_i))+\Omega(f_t)\\ &=\sum_{i=1}^n(g_iw_{q(x_i)}+\frac{1}{2}h_iw^2_{q(x_i)})+\gamma T+\lambda \frac{1}{2}\sum_{j=1}^Tw_j^2\\ &=\sum_{j=1}^T((\sum_{i\in I_j}g_i)w_j+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)w_j^2)+\gamma T \end{split} \]現在希望將\(n\)個樣本組成的目標損失,轉化為\(T\)個葉子節點的目標損失,令:
\[G_j=\sum_{i\in I_j}g_i\\ H_j=\sum_{i\in I_j}h_i \]目標損失變為:
\[\begin{split} Obj^{(t)}&=\sum_{j=1}^T((\sum_{i\in I_j}g_i)w_j+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)w_j^2)+\lambda T\\ &=\sum_{j=1}^T(G_jw_j+\frac{1}{2}(H_j+\lambda)w_j^2)+\lambda T \end{split} \]求一個樹結構下能夠獲得的目標函數的最小值
求目標函數關於\(w_j\)的偏導,並令該偏導\(\frac{\partial Obj}{\partial w_j}=0\),可得:
\[w_j^*=-\frac{G_j}{H_j+\lambda} \]因此,對一個樹結構而言,能夠得到的目標函數的最小值:
\[Obj^*=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T \]其中,\(G_j\)為葉子節點\(j\)中樣本的一階導,\(H_j\)為葉子節點\(j\)中樣本的二階導,\(T\)為葉子節點數,\(\lambda\)為正則化系數。
在所有可能的樹結構中,\(Obj^*\)越小,該樹結構越好。因此,現在考慮如何尋找這個最優的樹結構。
求最優樹結構
最直白的方法就是列舉所有的樹結構,在其中選擇\(Obj^*\)最小的作為最佳樹結構,但是這實際是一個\(NP\)難問題。在實踐中,通常使用樹的精確貪婪學習:
- 貪婪:選分割點時,只考慮當前樹結構到下一步樹結構的loss變化,不考慮全局
- 精確:當前層所有特征值中的所有可能,進行遍歷,尋找最優分割點

類似於ID3的信息增益、C4.5的增益率、CART的基尼指數,定義XGBoost選擇最優特征的准則:
\[Gain=\frac{G_L^2}{H_L^2+\lambda}+\frac{G_R^2}{H_R^2+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}-\gamma \]遍歷所有的特征,計算
Gain值,選擇最大的特征進行分割\[\begin{split} &for\ k: 0\to K: \quad \#\ 對每個節點\\ &\quad for\ d:0\to D:\quad \#\ 對每個特征\\ &\qquad for\ n:0\to N:\quad \#\ 對每個實例\\ &\qquad\quad 在0\to N中,實例排序的時間復雜度為O(nlog(n)) \end{split} \]因此,深度為\(k\)的樹,總的時間復雜度為\(O(ndklog(n))\)
注意到,對於每個節點,也就是每一步構建子樹時,尋找最佳分裂點有兩層含義:a.尋找特征中最優的分裂值;b.尋找最優的特征
為了降低時間復雜度,可以采用一些近似算法:對於每個特征,只考慮分位點,

就是把一些樣本捆綁在一起,形成
bin,這樣就能降低最終要排序的樣本數量。實際上,XGBoost不是簡單的按照上圖那樣,按照樣本個數進行分位,而是以二階導數值作為權重:
之所以使用\(h_i\)加權,是因為目標函數可以被整理成下式:
\[Obj=\sum_{i=1}^n\frac{1}{2}h_i(f_t(x_i)-\frac{g_i}{h_i})^2+\Omega(f_t)+constant \]可以看到,\(h_i\)對loss有加權的作用。
另外,觀察XGBoost的最優特征准則:
\[Gain=\frac{G_L^2}{H_L^2+\lambda}+\frac{G_R^2}{H_R^2+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}-\gamma \]其中,等式右側前半部分表示訓練
loss的減少,\(\gamma\)為正則化。上式有可能是負的,也就是說,loss的減少比正則化力度還要小時,分裂的增益會是負的。因此類似於預剪枝和后剪枝,有兩種訓練策略:- 提前停止:如果最佳分裂點是負的,那么提前停止分裂。這種策略過於貪婪,該分裂有可能有益於后面的分裂。
- 后剪枝:將一棵樹生成到它的最大深度,遞歸剪枝,剪去葉子節點分裂是負增益的。
XGBoost的其它特性:
- 行抽樣
- 列抽樣
- 縮減學習率
- 支持自定義損失函數。當然,該損失函數需要二階可導
- 增加了對稀疏數據的支持。在計算分裂增益時,只利用沒有missing值的樣本
- 支持並行化。在分裂節點計算增益時,並行
XGBoost論文地址:XGBoost: A Scalable Tree Boosting System
XGBoost官網:XGBoost Documentation
-
LightGBM
與XGBoost的不同:
-
直方圖(Histogram)算法
把連續的浮點特征值離散化為k個整數,同時構造一個寬度為k的直方圖。在遍歷數據時,根據離散化后的值作為索引,在直方圖中計算統計量。當遍歷一次數據后,直方圖計算了需要的統計量,然后根據直方圖的離散值,遍歷尋找最優分割點。

優勢:減少了內存占用;減少了分裂點計算增益時的計算量
-
直方圖加速
一個葉子的直方圖可以由它的父節點的直方圖與它的兄弟節點的直方圖,做差而得,提升一倍速度。
-
建樹方法
XGBoost是
Level-wise,LightGBM是Leaf-wise
總而言之,LightGBM特性:
-
基於直方圖的決策樹算法
-
直方圖差加速
-
帶深度限制的Leaf-wise的葉子生長策略
-
直接支持類別特征(Categorical Feature)
-
Cache命中率優化
-
基於直方圖的稀疏特征優化
-
多線程優化
LightGBM論文地址:Lightgbm: A highly efficient gradient boosting decision tree
LightGBM官網:LightGBM Documentation
-








