從 0 開始機器學習 - 正則化技術原理與編程!

之前學習了線性迴歸,邏輯迴歸和梯度下降法,今天學習的這個技術能夠幫助我們訓練的模型對未知的數據進行更好的預測 - 正則化技術!

快來一起學習學習,學習使我快樂 ()!

一、正則化是什麼?

正則化(Regulariation)這 3 個字聽起來挺高大上的,其實就是一種解決機器學習過擬合問題的技術,使用這項技術可以讓我們在訓練集上訓練的模型對未知的數據也能很好地擬合。

機器學習模型對未知數據的擬合能力又稱爲泛化能力,泛化能力比較好的模型,對未知數據擬合的也比較不錯,如果對訓練數據產生過擬合(over-fitting)問題,那泛化能力也會變差。

當出現過擬合問題後,處理的方式有 2 種:

  • 降維:減少特徵數量,把模型多項式階數降低,這樣高階項就少了,模型曲線就不會那麼複雜
  • 正則化:不直接減少特徵,而是增大代價函數中特徵參數的係數

我們今天要介紹的就是正則化技術,下面用個例子先來說明什麼是過擬合與欠擬合。

二、過擬合 VS 欠擬合

2.1 線性迴歸例子

這裏還以預測房價爲例,分別解釋以下 3 種情況:

  • 欠擬合:模型選擇的特徵數量太少(2 個),不能對訓練數據很好地擬合,會產生高偏差
  • 正常擬合:模型選擇的特徵數量合適(3 個),能對訓練數據擬合較好
  • 過擬合:模型選擇的特徵數量過多(5 個),對訓練數據過度擬合,會導致高方差

在實際應用中,通常選擇的特徵會比較多,很容易出現過擬合,所以解決這個問題很有必要。

2.2 邏輯迴歸例子

邏輯迴歸問題同樣會產生過擬合與欠擬合問題,比如這個分類問題:

這裏忘記註釋類型了,不過原理一樣:

  • 欠擬合:用直線分類,一看就不合適,因爲直觀來看決策邊界是圓弧形狀
  • 正常擬合:決策邊界是圓弧形狀,擬合的效果比較好
  • 過擬合:決策邊界分類的太嚴格了,在未知樣本上的預測效果很差

簡單總結下:模型的參數越多,使用的多項式次數(xnx^n)就越大,模型曲線就越複雜,這些高階次的項會導致過擬合問題。

這個正則化技術要解決過擬合問題的實質就是:減小高階次項對模型整體的影響,以此來提高模型對未知樣本的預測能力。

因爲我們在訓練數據上訓練出的模型,最終是要用到未知的樣本中的,不然就失去工程應用的意義了。OK,那下面就來正式學習下這個技術的原理,其實很容易,就是在代價函數後面加上一個正則化項公式。

三、正則化原理

3.1 在假設函數中理解正則化

我還以預測房價的例子來說明正則化技術的原理,模型的假設函數如下:

hθ(x)=θ0+θ1x1+θ2x22+θ3x33+θ4x44 h_\theta( x )=\theta_0 + \theta_1 x_1 + \theta_2 x_{2}^2 + \theta_3 x_{3}^3 + \theta_4 x_{4}^4

假如 θ3\theta_3 表示房屋廚房面積,θ4\theta_4 表示房屋的地理位置,這兩個特徵導致模型階次太高(x33,x44x_3^3, x_4^4),我想減少它倆對假設函數的影響,也就是說我想在代價函數求得最優值後,得到的最優特徵向量中這 2 個參數儘可能趨向於 0,這樣上面的模型就變成:

hθ(x)=θ0+θ1x1+θ2x22+0x33+0x44 h_\theta( x )=\theta_0 + \theta_1 x_1 + \theta_2 x_{2}^2 + 0 * x_{3}^3 + 0 * x_{4}^4

注意了:這裏只是將 θ3>0\theta_3 -> 0θ4>0\theta_4 -> 0,而並不是讓他們直接等於 0,因爲我們是正則化不是降維,通過將這 2 個參數趨向於 0 使得他們的高階次項可以忽略不計,就能得到減少 x3,x4x_3, x_4 對原模型的影響了。

用個機器學習的術語來說就是:通過正則化技術來懲罰 θ3\theta_3θ4\theta_4 這 2 個特徵!讓他們對模型預測產生的影響降低!

3.2 在代價函數中理解正則化

在應用中要懲罰參數需要通過對代價函數進行正則化,也就是在代價函數最小化的同時,將要懲罰的參數儘可能的設置爲 0。

這裏以線性迴歸代價函數爲例,看下如何正則化 θ3,θ4\theta_3, \theta_4

J(θ)=12m[i=1m(hθ(x(i))y(i))2+1000θ32+10000θ42] J(\theta) = \frac{1}{2m}[\sum\limits_{i=1}^m ( h_{\theta}(x^{(i)})-y^{(i)})^{2} + 1000\theta _3^2 + 10000\theta _4^2]

我們在代價函數後面加了 2 項 1000θ32,10000θ421000\theta_3^2, 10000\theta_4^2,因爲我們最後要將代價函數最小化,因此也需要對添加的這兩項最小化,然而因爲 10000 係數比較大,這就導致爲了將 10000θ4210000\theta_4^2 整體優化變小,就需要把參數 θ4\theta_4 設置的足夠小,這樣兩者相乘的結果才能變的足夠小,以此就完成了對 θ42\theta_4^2 的正則化,比如:

10000(0.001)2=0.01 10000 * (0.001)^2 = 0.01

需要正則化的參數前的係數需要根據實際情況來合適的選擇,這裏舉的例子設置的 1000 和 10000。

上面的例子指定了需要正則化的參數爲 θ3,θ4\theta_3, \theta_4,但是在實際的應用中,因爲訓練集的特徵非常多,我們不知道需要對哪些參數正則化,所以就對所有的參數進行正則化,然後讓優化算法來幫我們確定每個正則化參數前的係數,這樣的代價函數如下:

J(θ)=12m[i=1m(hθ(x(i))y(i))2+λj=1nθj2] J(\theta) = \frac{1}{2m}[\sum\limits_{i=1}^m ( h_{\theta}(x^{(i)})-y^{(i)})^{2} + \lambda \sum\limits_{j=1}^{n}{\theta_j^2}]

代碼如下:

# 線性迴歸正則化代價函數
# 正則化係數 lambda 設置爲 1
def regularized_cost(theta, X, y, lamd = 1):
    # 不對 theta_0 正則化
    theta_one2n = theta[1:]

    # 正則化項, power 求平方,sum 求和
    regularized_term = (lamd / 2 * len(X)) * np.power(theta_one2n, 2).sum()
    
    # cost_function 是未加正則化的代價函數
    return cost_function(theta, X, y) + regularized_term

這就是最終的對代價函數進行正則化的公式,可以看出就是增加一個正則化項,其中係數 λ\lambda 稱爲正則化係數,要注意j=1j = 1 ,即沒有對 θ0\theta_0 正則化,因爲 θ0\theta_0 對應的特徵是 x0x_0 ,而 x0=1x_0 = 1 是我們人爲加上的,所以沒必要對 θ0\theta_0 正則化。

3.3 正則化係數的影響

在正則化過程中,係數 λ\lambda 的選擇非常重要,它會對整體產生如下影響:

  • λ\lambda 過大:所有的參數都被過度正則化了,導致特徵參數都幾乎爲 0,假設函數就會變爲 hθ(x)=θ0h_\theta(x) = \theta_0 直線,即欠擬合
  • λ\lambda 過小:對參數的正則化程度不夠,當參數較多時,仍然會導致過擬合
  • λ\lambda 合適:減少高次項的影響,正常擬合

OK!正則化的原理就學習完了,下面來實際使用下正則化技術。

四、正則化代碼實戰

這部分我打算分別跟大家分享下如何在線性迴歸和邏輯迴歸中使用正則化編程。

4.1 線性迴歸正則化

因爲我們在代價函數中增加了正則化項:

λ2mj=1nθj2 \frac{\lambda}{2m} \sum\limits_{j=1}^{n}{\theta_j^2}

所以梯度下降的計算也多了一項正則化梯度(直接對正則化部分求導):

λmj=1nθj \frac{\lambda}{m} \sum\limits_{j=1}^{n}{\theta_j}

因爲不需要對 θ0\theta_0 正則化,所以梯度迭代的計算分爲如下 2 部分:

θ0:=θ0α1mi=1m((hθ(x(i))y(i))x0(i)) \theta_0:= \theta_0 - \alpha \frac{1}{m} \sum\limits_{i=1}^{m}{((h_\theta({x^{(i)}})-{y^{(i)}})x_0^{(i)}})

θj:=θjα[1mi=1m((hθ(x(i))y(i))x0(i))+λmθj] \theta_j:= \theta_j - \alpha [\frac{1}{m} \sum\limits_{i=1}^{m}{((h_\theta({x^{(i)}})-{y^{(i)}})x_0^{(i)}}) + \frac{\lambda}{m} \theta_j]

j=1,2,...m j = 1, 2, ... m

我們發現上面第二個式子可以進一步合併 θj\theta_j

θj:=(1αλm)θjα[1mi=1m((hθ(x(i))y(i))x0(i))] \theta_j:= (1 - \alpha \frac{\lambda}{m})\theta_j - \alpha [\frac{1}{m} \sum\limits_{i=1}^{m}{((h_\theta({x^{(i)}})-{y^{(i)}})x_0^{(i)}})]

至此線性迴歸的正則化梯度公式就出來了,來用 Python 代碼把它寫出來:

# 添加正則化項的線性迴歸梯度下降
def regularized_gradient(theta, X, y, lamd = 1):
    # 不對 theta_0 正則化
    theta_one2n = theta[1:]
    
    # 正則化梯度:(lambda / m) * theta_j 
    regularized_theta = (lamd / len(X)) * theta_one2n
    
    # 合併 theta_0
    regularized_term = np.concatenate([np.array([0]), regularized_theta])
    
    # 返回梯度:原梯度 + 正則化梯度
    return gradient(theta, X, y) + regularized_term 

4.2 邏輯迴歸正則化

邏輯迴歸代價函數的正則化項與線性迴歸相同:

J(θ)=1mi=1m[y(i)log(hθ(x(i)))(1y(i))log(1hθ(x(i)))]+λ2mj=1nθj2 J(\theta) = \frac{1}{m}\sum\limits_{i = 1}^{m}{[-{y^{(i)}}\log ({h_\theta}({x^{(i)}}))-( 1-{y^{(i)}})\log ( 1 - h_\theta({x^{(i)}}))]} + \frac{\lambda}{2m} \sum\limits_{j=1}^{n}{\theta_j^2}

# 邏輯迴歸正則化代價函數
# lambda 設置爲 1
def regularized_cost(theta, X, y, lamd = 1):
    theta_one2n = theta[1:]
    # lambda / (2 * m)
    regularized_term = (lamd / (2 * len(X))) * np.power(theta_one2n, 2).sum()
    
    # 返回加上正則化的總代價
    return cost_function(theta, X, y) + regularized_term

邏輯迴歸正則化梯度(hθ(x)h_\theta(x) 不同):

θ0:=θ0α1mi=1m((hθ(x(i))y(i))x0(i)) \theta_0:= \theta_0 - \alpha \frac{1}{m} \sum\limits_{i=1}^{m}{((h_\theta({x^{(i)}})-{y^{(i)}})x_0^{(i)}})

θj:=(1αλm)θjα[1mi=1m((hθ(x(i))y(i))x0(i))] \theta_j:= (1 - \alpha \frac{\lambda}{m})\theta_j - \alpha [\frac{1}{m} \sum\limits_{i=1}^{m}{((h_\theta({x^{(i)}})-{y^{(i)}})x_0^{(i)}})]

j=1,2,...,m j = 1, 2, ..., m

# 添加正則化項的邏輯迴歸梯度下降
def regularized_gradient(theta, X, y, lamd = 1):
    # 不對 theta_0 正則化
    theta_one2n = theta[1:]
    
    # 計算正則化項
    regularized_theta = (lamd / len(X)) * theta_one2n
    
    # 加上 theta_0
    regularized_term = np.concatenate([np.array([0]), regularized_theta])
    
 		# 返回增加正則化後的總梯度
    return gradient(theta, X, y) + regularized_term 

上面代碼中的 lamb 就是正則化係數 λ\lambda ,在模型訓練你可以試着更改它,然後測試下這個係數對模型參數的影響,以此來更加深入地理解正則化技術。

文中完整可運行代碼鏈接:

https://github.com/DLonng/AI-Notes/blob/master/MachineLearning/code/ex2-logistic-regression/my_logistic_regular.ipynb

OK!今天就分享這些,大家下期見,記得持續關注我哦 :)

本文原創首發於微信公號「登龍」,分享機器學習、算法編程、Python、機器人技術等原創文章,掃碼關注回覆「1024」你懂的!

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