回歸損失函式 L1和L2比較

2021-09-21 13:57:17 字數 2034 閱讀 4446

簡而言之,使用平方誤差更容易解決問題,但使用絕對誤差對於異常值更魯棒。我們來看一下為什麼。

不管我們什麼時候訓練機器學習模型,我們的目標都是想找到乙個點將損失函式最小化。當然,當**值正好等於真值時,這兩個函式都會達到最小值。

我們快速瀏覽一下這兩種函式的python**。我們可以自己寫函式,也可以用sklearn的內助度量函式:

**:

# true: 真目標變數的陣列# pred: **值的陣列

defmse

(true, pred)

:return np.

sum(

(true - pred)**2

)def

mae(true, pred)

:return np.

sum(np.

abs(true - pred)

)# 在 sklearn 中同樣適用

from sklearn.metrics import mean_squared_error

from sklearn.metrics import mean_absolute_error

我們來看看兩種情況下mae和均方根誤差(rmse,和mae相同尺度下mse的平方根)。在第一種情況下,**值和真值非常接近,誤差在眾多觀測值中變化很小。在第二種情況下,出現了乙個異常觀測值,誤差就很高。

我們從中可以觀察到什麼?這怎樣能幫我們選擇使用哪種損失函式?

因為mse是誤差的平方值(y — y_predicted = e),那麼誤差(e)的值在e > 1時會增加很多。如果我們的資料中有異常值,e的值會非常高,e²會》 |e|。這會讓存在mse誤差的模型比存在mae誤差的模型向異常值賦予更多的權重。在上面第2種情況中,存在rmse誤差的模型為了能將該單個異常值最小化會犧牲其它常見情況,這降低模型的整體效能。

如果訓練資料被異常值破壞的話(也就是我們在訓練環境中錯誤地接收到巨大的不切實際的正/負值,但在測試環境中卻沒有),mae會很有用。

我們可以這樣思考:如果我們必須為所有的觀測值賦予乙個**值,以最小化mse,那麼該**值應當為所有目標值的平均值。但是如果我們想將mae最小化,那麼**值應當為所有觀測值的中間值。我們知道中間值比起平均值,對異常值有更好的魯棒性,這樣就會讓mae比mse對異常值更加魯棒。

使用mae損失(特別是對於神經網路來說)的乙個大問題就是,其梯度始終一樣,這意味著梯度即便是對於很小的損失值來說,也還會非常大。這對於機器學習可不是件好事。為了修正這一點,我們可以使用動態學習率,它會隨著我們越來越接近最小值而逐漸變小。在這種情況下,mse會表現的很好,即便學習率固定,也會收斂。mse損失的梯度對於更大的損失值來說非常高,當損失值趨向於0時會逐漸降低,從而讓它在模型訓練收尾時更加準確(見下圖)。

決定使用哪種損失函式?

如果異常值表示的反常現象對於業務非常重要,且應當被檢測到,那麼我們就應當使用mse。另一方面,如果我們認為異常值僅表示損壞資料而已,那麼我們應當選擇mae作為損失函式。

注:l1和l2損失分別是mae和mse的別名。

l1損失對異常值更魯棒,但它的導數是不連續的,從而讓它無法有效的求解。l2損失對異常值很敏感,但會求出更穩定和更接近的解(通過將導數設為0)。

這兩者存在的問題:可能會出現兩種損失函式都無法給出理想**值的情況。例如,如果我們的資料中90% 的觀測值的目標真值為150, 剩餘10%的目標值在0-30之間。那麼存在mae損失的模型可能會**全部觀測值的目標值為150,而忽略了那10%的異常情況,因為它會試圖趨向於中間值。在同一種情況下,使用mse損失的模型會給出大量值範圍在0到30之間的**值,因為它會偏向於異常值。在很多業務情況中,這兩種結果都不夠理想。

摘錄:注:博眾家之所長,集群英之薈萃。

L1和L2正則化

l1和l2正則化 l1與l2正則化都是防止模型過擬合,其方式略有不同。具體請見下文。1 l1 正則化l1正則化 1範數 是指,各權值 變數 特徵 絕對值之和。其作用是產生權值的稀疏模型,也就是讓大部分權值為0.為什麼能產生權值稀疏模型?因為如下圖所示,各權值絕對值之和後得到乙個矩陣,很容易在矩陣的頂...

關於L1和L2正則

l0範數表示向量中非零元素的個數 也就是如果我們使用l0範數,即希望 w的大部分元素都是0 w是稀疏的 所以可以用於ml中做 稀疏編碼 特徵選擇。通過最小化l0範數,來尋找 最少最優的稀疏特徵項 但不幸的是,l0範數的最優化問題是乙個np hard問題,而且理論上有證明,l1範數是l0範數的最優凸近...

l1和l2正則化

import tensorflow as tf import tensorflow.contrib as contrib weight tf.constant 1.0,2.0 3.0,4.0 with tf.session as sess print sess.run contrib.layers....