本文首發自集智專欄
機器學習中的所有演算法都依靠最小化或最大化函式,我們將其稱為“目標函式”。被最小化的函式就被稱為“損失函式”。損失函式也能衡量預測模型在預測期望結果方面的效能。找到函式的最小值點的最常用方法是“梯度下降”。如果把損失函式比作連綿起伏的山巒,那麼梯度下降就好比愚公一樣盡力削低山脈,讓山達到最低點。
損失函式,並非只有一種。根據不同的因素,包括是否存在異常值,所選機器學習演算法,梯度下降的的時效,找到預測的置信度和導數的難易度,我們可以選擇不同的損失函式。本文就帶領大家學習不同的損失函式,以及它們如何在資料科學和機器學習中幫助我們。
損失函式可以大體分為兩種型別:分類損失和迴歸損失。
在本文,我們先重點看看回歸損失函式,在後面的文章會繼續分享其它的損失函式型別。
本文所有程式碼地址見文末。
(迴歸函式預測數量,分類函式預測標籤)迴歸損失
- 均方誤差(MSE),二次損失,L2損失
均方誤差是最常用的迴歸損失函式,它是我們的目標變數和預測值的差值平方和。
下圖是均方誤差函式圖,其中目標真值為100,預測值範圍在-10000到10000之間。均方誤差損失(Y軸)在預測值(X軸)=100處達到最小值。範圍為0到∞。- 平均絕對誤差,L1損失
平均絕對誤差(MAE)是另一種用於迴歸模型的損失函式。MAE是目標變數和預測變數之間絕對差值之和。因此它衡量的是一組預測值中的平均誤差大小,而不考慮它們的方向(如果我們考慮方向的話,那就是均值誤差(MBE)了,即誤差之和)。範圍為0到∞。
MSE vs MAE (L2損失 vs L1損失)
簡而言之,使用平方誤差更容易解決問題,但使用絕對誤差對於異常值更魯棒。我們來看一下為什麼。
不管我們什麼時候訓練機器學習模型,我們的目標都是想找到一個點將損失函式最小化。當然,當預測值正好等於真值時,這兩個函式都會達到最小值。
我們快速瀏覽一下這兩種函式的Python程式碼。我們可以自己寫函式,也可以用sklearn的內助度量函式:
# true: 真目標變數的陣列
# pred: 預測值的陣列
def mse(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損失函式時迴歸模型的效能,建議讀讀這篇不錯的研究。記住,L1和L2損失分別是MAE和MSE的別名。
L1損失對異常值更魯棒,但它的導數是不連續的,從而讓它無法有效的求解。L2損失對異常值很敏感,但會求出更穩定和更接近的解(通過將導數設為0)。
這兩者存在的問題:可能會出現兩種損失函式都無法給出理想預測值的情況。例如,如果我們的資料中90% 的觀測值的目標真值為150, 剩餘10%的目標值在0-30之間。那麼存在MAE損失的模型可能會預測全部觀測值的目標值為150,而忽略了那10%的異常情況,因為它會試圖趨向於中間值。在同一種情況下,使用MSE損失的模型會給出大量值範圍在0到30之間的預測值,因為它會偏向於異常值。在很多業務情況中,這兩種結果都不夠理想。
那麼在這種情況下該怎麼辦?一個比較容易的修正方法是轉換目標變數。另一種方法是試試不同的損失函式。這就引出了我們要講的下一部分:Huber損失函式。
- Huber損失函式,平滑平均絕對誤差 相比平方誤差損失,Huber損失對於資料中異常值的敏感性要差一些。在值為0時,它也是可微分的。它基本上是絕對值,在誤差很小時會變為平方值。誤差使其平方值的大小如何取決於一個超引數δ,該引數可以調整。當δ~ 0時,Huber損失會趨向於MAE;當δ~ ∞(很大的數字),Huber損失會趨向於MSE。
δ的選擇非常關鍵,因為它決定了你如何看待異常值。殘差大於δ,就用L1(它對很大的異常值敏感性較差)最小化,而殘差小於δ,就用L2“適當地”最小化。
為何使用Huber損失函式?
使用MAE用於訓練神經網路的一個大問題就是,它的梯度始終很大,這會導致使用梯度下降訓練模型時,在結束時遺漏最小值。對於MSE,梯度會隨著損失值接近其最小值逐漸減少,從而使其更準確。
在這些情況下,Huber損失函式真的會非常有幫助,因為它圍繞的最小值會減小梯度。而且相比MSE,它對異常值更具魯棒性。因此,它同時具備MSE和MAE這兩種損失函式的優點。不過,Huber損失函式也存在一個問題,我們可能需要訓練超引數δ,而且這個過程需要不斷迭代。
- Log-Cosh損失函式
Log-Cosh是應用於迴歸任務中的另一種損失函式,它比L2損失更平滑。Log-cosh是預測誤差的雙曲餘弦的對數。
優點:
對於較小的X值,log(cosh(x))約等於(x ** 2) / 2;對於較大的X值,則約等於abs(x) - log(2)。這意味著Log-cosh很大程度上工作原理和平均方誤差很像,但偶爾出現錯的離譜的預測時對它影響又不是很大。它具備了Huber損失函式的所有優點,但不像Huber損失,它在所有地方都二次可微。
我們為何需要二階導數?很多機器學習模型,比如XGBoost,使用牛頓法來尋找最好結果,因此需要二階導數(海塞函式)。對於像XGBoost這樣的機器學習框架,二次可微函式更為有利。
但Log-cosh也不是完美無缺。如果始終出現非常大的偏離目標的預測值時,它就會遭受梯度問題,因此會導致XGboost的節點不能充分分裂。Huber損失函式和Log-cosh損失函式的Python程式碼:
# huber 損失
def huber(true, pred, delta):
loss = np.where(np.abs(true-pred) < delta , 0.5*((true-pred)**2), delta*np.abs(true - pred) - 0.5*(delta**2))
return np.sum(loss)
# log cosh 損失
def logcosh(true, pred):
loss = np.log(np.cosh(pred - true))
return np.sum(loss)
複製程式碼
- Quantile損失函式 在大多數現實預測問題中,我們常常很想知道我們的預測值的不確定性。對於很多業務問題而言,相對於知道某個預測點,瞭解預測值範圍能夠大幅優化決策過程。最小二乘迴歸的預測區間基於我們假設殘差值(y — y_hat)在所有獨立變數值上的變化保持一致。
如果我們是想預測某個區間而非某個點,Quantile損失函式會非常有用。違背此假設的迴歸模型是不可信的。當然我們也不能認為這種情況下用非線性函式或基於樹的模型能更好的建模,把擬合線性模型作為基準的理念扔在一邊就完了。這時,我們就可以用到Quantile損失和Quantile迴歸,因為基於Quantile損失的迴歸能夠提供更明智的預測區間,即便是有非常量方差和非正常分佈的誤差來說,效果同樣不錯。
我們來看一些案例,更好的理解為何基於Quantile損失的迴歸能對異方差問題效果良好。
- Quantile迴歸 VS 普通最小乘二回歸
以上圖片所示的 Quantile 迴歸的程式碼地址: github
理解 Quantile 損失函式
基於 Quantile 的迴歸模型目的是根據預測變數的特定值,預測反應變數的條件分位數。 Quantile 損失實際上就是 MAE 的延伸(當分位數為第50個百分位數時,它就是MAE)。
其理念就是根據我們是否想增加正誤差或負誤差的分量選擇合適的分位數值。損失函式會根據所選分位數(γ)的值,為估計過高或估計不足做出不同的處罰。例如,γ=0.25的Quantile損失函式會向估計過高做出更多的懲罰,將預測值保持在略微低於平均值的狀態。
γ就是所需的分位數,值範圍在0和1之間。 我們也能用該損失函式計算神經網路或基於樹的模型的預測區間。下面是用Sklearn實現梯度漸進迴歸樹模型的示例。 上圖展示了用Sklearn和Quantile損失函式計算出的梯度漸進迴歸樹中90%的預測區間。以γ=0.95構建上界,以γ=0.05構建下界。比較研究
在文章《Gradient Boosting Machines, a Tutorial》中,很好的比較了這幾種損失函式。為了展示以上所有損失函式的屬性,文章作者模擬了一個取樣於sinc(x)函式的資料集,以及兩個人工模擬噪聲資料集:高斯噪聲分量ε ~ N(0, σ2),以及脈衝噪聲分量ξ ~ Bern(p)。作者新增了脈衝噪聲項來說明魯棒影響。下圖是用不同損失函式擬合GBM迴歸模型的結果。
圖中依次為(A)MSE損失函式 (B)MAE損失函式(C)Huber損失函式(D)Quantile損失函式(E)原始sinc(x) 函式(F)擬合了MSE和MAE損失的平滑GBM(G)擬合了huber損失為 δ = {4, 2, 1}的平滑GBM(H)擬合了Quantile損失為α = {0.5, 0.1, 0.9}的平滑GBM
從以上模擬中我們可以觀察到:
- 有MAE損失的模型預測值受脈衝噪聲的影響較小,而有MSE損失的模型預測值由於噪聲資料導致的偏差,則出現輕微偏差。
- 有Huber損失的模型預測值對於所選超引數的值敏感度較小。
- Quantile損失在對應置信度水平上做出了很好的預測。
最後我們把以上所有損失函式繪製在一張圖中:
參考資料:看這裡!
限時折扣中:0806期《人工智慧-從零開始到精通》(前25位同學可領取¥200優惠券)