再讀線性迴歸 Linear Regression (過擬合問題)

1. 過擬合問題

在前一篇文章(《再讀線性迴歸》)中,我回顧了線性迴歸的問題和基本的解決思路。線性迴歸主要通過構建含參數的多項式方程 fθ(x)f_{\theta}(x) 來對新的樣本進行預測。 爲了構建這樣的方程,線性迴歸算法中利用梯度下降更新參數組合 θ\theta來不斷減少代價函數 J(θ)J(\theta) 的值,直至達到最優。

不可否認的是,雖然線性迴歸模型在很多領域的應用都很強勢,但是它也有一些自身固有的缺點,如參數初始化問題,參數項過多問題,過擬合問題等,科學家們也在原有的線性迴歸模型上做了一些改進,這裏主要討論一下過擬合問題(Overfiting)

過擬合的一般理解是在訓練集上擬合的很好,但是在測試集上預測結果很差。總的來講,過擬合問題反映出模型的泛化能力的不足。這個泛化能力對機器學習模型來講可是很要命的,要知道機器學習就是讓機器去自助探測未知世界的,泛化能力的強弱決定了模型的取捨。換句話說,我們更希望提升出來的模型在測試集上的性能(泛化能力),而不是一味的擬合現有的訓練集。

在這裏插入圖片描述
一般來講,模型過擬合的本質原因可以歸咎爲模型過於複雜,如上圖所示,(a) 表示了一個正常的線性模型(可能是簡單的 y=θ0+θ1xy=\theta_0+\theta_1x),(b) 表示了一個複雜的過擬合模型 y=θ0+θ1x+θ2x2+...+θnxny=\theta_0 + \theta_1x+\theta_2x^2+...+\theta_nx^n。直觀的來講,當新的點加進來時,我們利用 (a) 中的模型預測其 yy 值會更加的準確。而使用過擬合預測的趨勢明顯不對,其效果甚至還不如 c) 中欠擬合的參數模型。

2. 正則化

正則化(Regularization) 是緩解過擬合現象的通用解決方案。它的做法就是在正常代價函數 J(θ)J(\theta) 的後方添加一個關於參數 θ\theta 的懲罰項。簡單的來講,正則化之後的代價函數可以寫成,

J(θ)=12m[i=1m(fθ(x(i))y(i))2+λj=1n(θj)2] J(\theta) = \frac{1}{2m} [\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda \sum_{j=1}^{n}(\theta_j)^2]

這與我們之前的代價函數僅僅多了一個末尾的一個 λj=1n(θj)2\lambda \sum_{j=1}^{n}(\theta_j)^2,這個多出來的乘法項就是用來緩解過擬合現象的。試想一下前面的正則化參數 λ\lambda 取值非常大,如100,1000,那麼更新參數的結果往往會導致較小的 θj\theta_j 的取值,這樣較小的 θj\theta_j 值就會讓該參數項對整體的迴歸函數的影響變得微弱。一個極端的例子,當除 θ0\theta_0 以外的參數全都爲 0 後,我們的迴歸函數就變成了 fθ(x)=θf_{\theta}(x)=\theta。這就是一條直線。

總而言之,正則化通過添加額外懲罰項的方式使參數的分佈變得稀疏(更接近於零),進而促使模型變得更加簡單。正則化就是用這種方法來緩解過擬合帶來的危害。針對於正則化的代價函數,我們按如下方式更新參數向量 θ\theta

θj=θjαm[i=1m(fθ(x(i))y(i))xj(i)+λθj]j[1,n] \theta_j = \theta_j - \frac{\alpha}{m}[\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j + \lambda\theta_j],j\in [1,n]

我們化簡一下,得到如下的式子,

θj=(1αm)θjαmi=1m(fθ(x(i))y(i))xj(i)j[1,n] \theta_j= (1-\frac{\alpha}{m})\theta_j - \frac{\alpha}{m}\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j,j\in [1,n]

根據最小二乘法,讓所有的偏導數均等於零。我們可以直接求出最終參數向量爲:

θ=(XTX+λ(011...1))1XTY \theta = (X^TX+\lambda \begin{pmatrix} 0 \\ & 1 \\ & & 1 \\ & & & ...\\ & & & & 1\\ \end{pmatrix} )^{-1}X^TY

注意,上式中的的 XXYY 分別表示特徵矩陣(m×nm\times n 維)和標籤矩陣(m×1m \times 1 維),這個可能與有些文章講解的公式不一樣,這是因爲我們沒有對 θ0\theta_0 進行正則化。如果對 θ0\theta_0 也正則化,那麼相應的 θ\theta 可寫成,

θ=(XTX+λI)1XTY \theta = (X^TX+\lambda I)^{-1}X^TY

這裏的 II 表示 (n+1)(n+1) 的單位矩陣。

3. 幾種正則化方法

目前爲止,提到的比較多的正則方法就是 L1L1L2L2 正則化了,使用這兩種正則化的迴歸方法分別稱爲 套索迴歸(Lasso Regression)嶺迴歸(Ridge Regression)。他們的代價函數分別爲,

L1J(θ)=12mi=1m(fθ(x(i))y(i))2+λθ1 L1正則化:J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ||\theta||_1

L2J(θ)=12mi=1m(fθ(x(i))y(i))2+λθ22 L2正則化:J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ||\theta||_2^2

上式中的 θ1||\theta||_1θ22||\theta||_2^2 表示參數向量的一維範式和二維範式,直觀的理解就是一維範式就是 θ\theta 中項的絕對值相加,二維範式就是 θ\theta 中項的平方和相加。類推到 pp 維範式有,

θpp=1p×(i=0mθp)p=1,2,... ||\theta||_p^p = \frac{1}{p} \times (\sum_{i=0}^{m} |\theta|^p),p=1,2,...

一般來講,L1L1 正則化要比 L2L2正則化更能得到一個稀疏的參數解(即參數爲極小值且均接近於0)。下面兩幅圖展示了等高線圖中兩種正則化的過程。由圖可知,L1L1 正則化找到的最優解往往是座標軸上的點,這樣 θ0\theta_0 就很有可能等於 0。L2L2 正則化找到的最優解往往是切點,θ0\theta_0θ1\theta_1 更難等於0。這個只是一個簡單的演示。

因此,記住 L1L1 正則化要比 L2L2正則化更能得到一個稀疏的參數解 就對了。

在這裏插入圖片描述

有的人甚至提出了 L1L1L2L2 的綜合正則化方法(用這種綜合的正則化方法構建的線性迴歸模型我們稱之爲 彈性網絡(Elastic Net))。簡單的說,綜合的正則化方法在計算代價的時候添加了 L1L1L2L2 的兩個懲罰項,如下所示,

J(θ)=12mi=1m(fθ(x(i))y(i))2+λ(L1ratioθ1+(1L1ratio)θ22) J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ( L1_{ratio} ||\theta||_1 + (1 - L1_{ratio}) ||\theta||_2^2)

上式中的 L1ratioL1_{ratio} 參數表示使用 L1L1 進行正則化的懲罰項所佔的比例。同理,(1L1ratio)(1-L1_{ratio}) 表示使用 L2L2 進行正則化的懲罰項所佔的比例。可以想見,這個比例 L1ratioL1_{ratio} 會極大的影響着迴歸結果。

4. 總結

需要說明的是,即使使用了不同的正則化方法,過擬合現象只是比之前稍稍 緩解 了,並沒有被完全解除。另外,線性迴歸的另一個問題就是參數項過多,當特徵數量巨大時,訓練一個線性迴歸模型耗費巨大。

在這裏插入圖片描述

在圖像識別中,一張 500×500500 \times 500 像素的圖片,構造出來的線性迴歸模型會有有 750,000 個參數項(即 500×500×3500\times500\times3),這個計算量將十分巨大(特別涉及到矩陣計算時)。

fθ(x)=θ0+θ1x1+θ2x2+...+θ750,000x750,000 f_{\theta}(x) = \theta_0 + \theta_1x_1 + \theta_2x_2 + ... + \theta_{750,000}x_{750,000}

並且,一旦我們的訓練樣本個數 m<750,000m<750,000 時,極有可能產生過擬合。這麼一來,處理起來更加的不方便。我們需要一種新的算法來解決圖像的問題,這就是 神經網絡(Neural Network)。隨着硬件技術的發展,神經網絡逐漸發揮出自己的優勢,在圖形圖像處理,自然語言處理領域大放異彩,我後續會繼續介紹。


附: 用 sk-learn 包實現不同的線性迴歸模型

在 sk-learn 包裏1,也提供了正則化的接口,相關使用代碼爲,

from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet

def test_norm(train_x, train_y):
	# 使用 L1 正則化建立線性迴歸模型
	reg_l1 = Lasso(alpha=1.0) # 正則化參數爲 1.0
	reg_l1.fit(train_x, train_y)

	# 使用 L2 正則化建立線性迴歸模型
	reg_l2 = Ridge(aplha=2.5) # 正則化參數爲 2.5
	reg_l2.fit(train_x, train_y)

	# 同時使用 L1 和 L2 正則化建立線性迴歸模型
	reg_l2 = ElasticNet(aplha=1.0, l1_ratio=0.5) # 正則化參數爲 1.0,正則化比例爲 1:1 
	reg_l2.fit(train_x, train_y)
	...

  1. Sklearn. 各種形式的線性迴歸模型. Link ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章