損失函數分為經驗風險損失函數和結構風險損失函數。經驗風險損失函數指預測結果和實際結果的差別,結構風險損失函數是指經驗風險損失函數加上正則項。通常表示為如下:(整個式子表示的意思是找到使目標函數最小時的θ值。)

$$\lambda = \frac{1}{C}$$
一、分類損失函數
1.二分類損失函數
$y \in \{-1,+1\}$
| Loss$l(h_w(X_i,yi))$ | 代表算法 | 說明 |
| 1.Hing-Loss $$max\left[1-h_{\mathbf{w}}(\mathbf{x}_{i})y_{i},0\right]^{p}$$ |
|
當用於標准SVM時,損失函數表示線性分隔符與其中任一類中的最近點之間的邊距長度。 只有在p = 2時處處可導。 |
| 2.Log-Loss $$log(1+e^{-h_{\mathbf{w}}(\mathbf{x}_{i})y_{i}})$$ |
Logistic回歸 |
|
| 3.Exponential Loss $$e^{-h_{\mathbf{w}}(\mathbf{x}_{i})y_i}$$ |
Adaboost | 錯誤預測的丟失隨着值的增加呈指數增長$$-h_w(x_i)y_i$$ |
| 4.Zero-One Loss $$\delta(\textrm{sign}(h_{\mathbf{w}}(\mathbf{x}_{i}))\neq y_{i})$$ |
實際分類損失 | 不連續,不容易優化 |

橫坐標:$h(X_i)y_i$ | 縱坐標:損失值
關於損失函數的補充說明:
- 當$z\rightarrow-\infty$,log-loss和hinge loss會逐漸平行
- 指數損失和hinge損失大於Zero-one 損失的上界
- Zero-one 損失當預測正確的時候為0,預測錯誤時為1
1.1 hinge loss
1.2 log loss
損失函數:$y\ln\left(p\right)+\left(1-y\right)\ln\left(1-p\right)$
$p = \dfrac{1}{(1 + e^{-x})}$
$\frac{\partial f}{\partial p}=\frac{p-y}{\left(1-p\right)p}$
$\frac{\partial p}{\partial x}=p(1-p)$
$\frac{\partial f}{\partial x}=\frac{\partial f}{\partial p}\frac{\partial p}{\partial x}=p-y$
$\frac{\partial^2 f}{\partial x^2}=\frac{\partial}{\partial x}(\frac{\partial f}{\partial x})=\frac{\partial}{\partial x}(p-y)=\frac{\partial p}{\partial x}=p(1-p)$
1.3 exponential loss
1.4 zero-one loss
二、回歸損失函數
| Loss $\ell(h_{\mathbf{w}}(\mathbf{x}_i,y_i))$ | 說明 |
| 1.Squared Loss $$(h(\mathbf{x}_{i})-y_{i})^{2}$$ | 也被稱為均分誤差| 二次損失 | L2損失 | 普通最小二乘法(OLS) | Mean Square Error, Quadratic Loss, L2 Loss 優點:處處可導 缺點:對異常值敏感 |
| 2.Absolut Loss $$|h(\mathbf{x}_{i})-y_{i}|$$ | 優點:對噪音不敏感 缺點:0點不可導 |
| 3.Huber Loss
|
平滑絕對損失 優點:結合了平方損失和絕對損失;一階可導 當損失很小時采用平方損失,當損失很大時采用絕對損失 |
| 4.fair loss $$c^2(\frac{|x|}{c}-ln(\frac{|x|}{c}+1))$$ |
|
| 5.Log-Cosh Loss $$log(cosh(h(\mathbf{x}_{i})-y_{i}))$$ $$cosh(x)=\frac{e^{x}+e^{-x}}{2}$$ |
優點:與Huber損失類似,但處處二階可導 缺點:對於誤差很大的預測,其梯度和hessian是恆定的 |
| 6.Quantile Loss(分位數損失)
|
優點:基於Quantile Loss的回歸模型可以提供合理的預測區間,即使是對於具有非常數方差或非正態分布的殘差
|

橫坐標:$h(\mathbf{x}_{i})y_{i}$ 或者預測的'error' | 縱坐標:損失值
(1)MSE與MAE
直觀來說,我們可以像這樣考慮:對所有的觀測數據,如果我們只給一個預測結果來最小化MSE,那么該預測值應該是所有目標值的均值。但是如果我們試圖最小化MAE,那么這個預測就是所有目標值的中位數。我們知道中位數對於離群點比平均值更魯棒,這使得MAE比MSE更加魯棒。 如果離群點是會影響業務、而且是應該被檢測到的異常值,那么我們應該使用MSE。另一方面,如果我們認為離群點僅僅代表數據損壞,那么我們應該選擇MAE作為損失。
具體實現:
mae和mse的損失值
# 1.調用sklearn
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
# 2.自定義
def mae_metric(y_true, y_pred):
return 'mae', np.mean(np.abs(y_true - y_pred)), False
def mse_metric(y_true, y_pred):
return 'mse', np.mean((y_true - y_pred) ** 2), False
mae和mse的一階導數和二階導數:
def mae_loss(y_true, y_pred):
x = y_pred - y_true
grad = np.sign(x)
hess = np.zeros_like(x)
return grad, hess # 一階,二階導數
def mse_loss(y_true, y_pred):
x = y_pred - y_true
grad = x
hess = np.ones_like(x)
return grad, hess # 一階,二階導數
mae和fair loss、huber loss結合
def mae_fair_metric(y_true, y_pred, fair_c):
# 損失值
x = y_pred - y_true
tmp = np.abs(x) / fair_c
fair = fair_c ** 2 * (tmp - np.log(tmp + 1))
mae = np.abs(x)
return 'mae_fair%d' % fair_c, np.mean(0.5 * fair + 0.5 * mae), False
def mae_huber_metric(y_true, y_pred, huber_delta):
# 損失值
x = y_pred - y_true
huber = pseudo_huber_metric(y_true, y_pred, huber_delta)[1]
mae = np.abs(x)
return 'mae_huber%d' % huber_delta, np.mean(0.5 * huber + 0.5 * mae), False
def mae_fair_loss(y_true, y_pred, fair_c):
# 返回一階、二階導數
grad_mae, hess_mae = mae_loss(y_true, y_pred)
grad_fair, hess_fair = fair_loss(y_true, y_pred, fair_c)
grad = 0.5 * grad_mae + 0.5 * grad_fair
hess = 0.5 * hess_mae + 0.5 * hess_fair
return grad, hess
def mae_huber_loss(y_true, y_pred, huber_delta):
# 返回一階、二階導數
grad_mae, hess_mae = mae_loss(y_true, y_pred)
grad_huber, hess_huber = pseudo_huber_loss(y_true, y_pred, huber_delta)
grad = 0.5 * grad_mae + 0.5 * grad_huber
hess = 0.5 * hess_mae + 0.5 * hess_huber
return grad, hess
(2)Huber loss 平滑的平均絕對誤差
可能會出現這樣的情況,即任何一種損失函數都不能給出理想的預測。例如,如果我們數據中90%的觀測數據的真實目標值是150,其余10%的真實目標值在0-30之間。那么,一個以MAE為損失的模型可能對所有觀測數據都預測為150,而忽略10%的離群情況,因為它會嘗試去接近中值。同樣地,以MSE為損失的模型會給出許多范圍在0到30的預測,因為它被離群點弄糊塗了。這兩種結果在許多業務中都是不可取的。
Huber Loss對數據離群點的敏感度低於平方誤差損失。它在0處也可導。基本上它是絕對誤差,當誤差很小時,誤差是二次形式的。誤差何時需要變成二次形式取決於一個超參數,(delta),該超參數可以進行微調。當 ? ~ 0時, Huber Loss接近MAE,當 ? ~ ∞(很大的數)時,Huber Loss接近MSE。


橫坐標:預測值 | 縱坐標:Huber loss
delta的選擇非常重要,因為它決定了你認為什么數據是離群點。大於delta的殘差用L1最小化(對較大的離群點較不敏感),而小於delta的殘差則可以“很合適地”用L2最小化。
為什么使用Huber Loss?
使用MAE訓練神經網絡的一個大問題是經常會遇到很大的梯度,使用梯度下降時可能導致訓練結束時錯過最小值。對於MSE,梯度會隨着損失接近最小值而降低,從而使其更加精確。
在這種情況下,Huber Loss可能會非常有用,因為它會使最小值附近彎曲,從而降低梯度。另外它比MSE對異常值更魯棒。因此,它結合了MSE和MAE的優良特性。但是,Huber Loss的問題是我們可能需要迭代地訓練超參數delta。
具體實現:
def sm_mae(true, pred, delta): """ true: array of true values pred: array of predicted values returns: smoothed mean absolute error loss """ 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)
pseudo huber loss:

def pseudo_huber_metric(y_true, y_pred, delta):
# 損失值
x = y_pred - y_true
return 'huber%d' % delta, np.mean(delta ** 2 * (np.sqrt((x / delta) ** 2 + 1) - 1)), False
def pseudo_huber_loss(y_true, y_pred, delta):
# 一階、二階導數 x = y_pred - y_true scale = 1 + (x / delta) ** 2 scale_sqrt = np.sqrt(scale) grad = x / scale_sqrt hess = 1 / (scale * scale_sqrt) return grad, hess
(3)fair loss
來自solution in the Kaggle Allstate Challenge.
def fair_loss(y_true, y_pred, faic_c):
x = y_pred - y_true
grad = faic_c * x / (np.abs(x) + faic_c)
hess = faic_c ** 2 / (np.abs(x) + faic_c) ** 2
return grad, hess
fair loss和huber loss結合
def fair_huber_loss(y_true, y_pred, fair_c, huber_delta):
grad_fair, hess_fair = fair_loss(y_true, y_pred, fair_c)
grad_huber, hess_huber = pseudo_huber_loss(y_true, y_pred, huber_delta)
grad = 0.5 * grad_fair + 0.5 * grad_huber
hess = 0.5 * hess_fair + 0.5 * hess_huber
return grad, hess
(4)Log-Cosh loss
Log-cosh是用於回歸任務的另一種損失函數,它比L2更加平滑。Log-cosh是預測誤差的雙曲余弦的對數。

優點: log(cosh(x))對於小的x來說,其大約等於 (x ** 2) / 2,而對於大的x來說,其大約等於 abs(x) - log(2)。這意味着'logcosh'的作用大部分與均方誤差一樣,但不會受到偶爾出現的極端不正確預測的強烈影響。它具有Huber Loss的所有優點,和Huber Loss不同之處在於,其處處二次可導。
為什么我們需要二階導數?
許多機器學習模型的實現(如XGBoost)使用牛頓方法來尋找最優解,這就是為什么需要二階導數(Hessian)的原因。對於像XGBoost這樣的機器學習框架,二階可導函數更有利。
但Log-chsh Loss並不完美。它仍然存在梯度和Hessian問題,對於誤差很大的預測,其梯度和hessian是恆定的。因此會導致XGBoost中沒有分裂。
具體實現:
def logcosh(true, pred): loss = np.log(np.cosh(pred - true)) return np.sum(loss)
(5)Quantile Loss(分位數損失)
當我們有興趣預測一個區間而不僅僅是預測一個點時,Quantile Loss函數就很有用。最小二乘回歸的預測區間是基於這樣一個假設:殘差(y - y_hat)在獨立變量的值之間具有不變的方差。我們不能相信線性回歸模型,因為它違反了這一假設。當然,我們也不能僅僅認為這種情況一般使用非線性函數或基於樹的模型就可以更好地建模,而簡單地拋棄擬合線性回歸模型作為基線的想法。這時,Quantile Loss就派上用場了。因為基於Quantile Loss的回歸模型可以提供合理的預測區間,即使是對於具有非常數方差或非正態分布的殘差亦是如此。
具體實現:參考這里
舉例:
Regression prediction intervals with XGBOOST 不考慮異常值帶來的損失,只考慮一定區間內數據的損失。
參考文獻:
【1】機器學習中的損失函數 (着重比較:hinge loss vs softmax loss)
【3】Empirical Risk Minimization
【4】到底該如何選擇損失函數?
