Huber Loss

中級

Huber Loss

最終更新 2026-03-03 読了時間 2 分
まとめ
  • Huber 損失は誤差が小さい領域で二乗誤差(MSE)、大きい領域で絶対誤差(MAE)として振る舞う。
  • 閾値パラメータ δ で切り替え点を制御し、外れ値の影響を制限しつつ微小誤差では滑らかな勾配を得る。
  • scikit-learn の HuberRegressor や XGBoost / LightGBM の objective="huber" で利用可能。
  • MAE・RMSE — Huber 損失が橋渡しする 2 つの基本指標

直感 #

MSE は大きな誤差を二乗で罰するので外れ値に引っ張られる。MAE は外れ値に頑健だが、原点付近で微分不可能で最適化しにくい。Huber 損失は「誤差が δ 以下なら MSE、δ を超えたら MAE」と切り替えることで、両方の長所を得る。

詳細な解説 #

数式 #

$$ L_\delta(r) = \begin{cases} \frac{1}{2} r^2 & \text{if } |r| \le \delta \\ \delta \cdot (|r| - \frac{1}{2}\delta) & \text{if } |r| > \delta \end{cases} $$

可視化 #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt

def huber_loss(r, delta=1.0):
    return np.where(np.abs(r) <= delta, 0.5 * r**2, delta * (np.abs(r) - 0.5 * delta))

r = np.linspace(-4, 4, 200)
plt.figure(figsize=(8, 4))
for d in [0.5, 1.0, 2.0]:
    plt.plot(r, huber_loss(r, d), label=f"δ = {d}")
plt.plot(r, r**2, "--", label="MSE", alpha=0.5)
plt.plot(r, np.abs(r), "--", label="MAE", alpha=0.5)
plt.legend()
plt.xlabel("Residual")
plt.ylabel("Loss")
plt.title("Huber Loss vs MSE vs MAE")
plt.grid(True, alpha=0.3)
plt.show()

scikit-learn での利用 #

1
2
3
4
5
6
7
8
9
from sklearn.linear_model import HuberRegressor
from sklearn.datasets import make_regression

X, y = make_regression(n_samples=200, n_features=1, noise=10, random_state=42)
y[0], y[1], y[2] = 300, -250, 400  # 外れ値を追加

huber = HuberRegressor(epsilon=1.35)
huber.fit(X, y)
print(f"Huber 係数: {huber.coef_[0]:.2f}")

損失関数の比較 #

損失外れ値耐性微分可能性主な用途
MSE弱い○(全域)標準的な回帰
MAE強い△(原点で不可)ロバスト回帰
Huber中間(δで制御)○(全域)外れ値がある回帰
Pinball方向性あり分位予測