私はxgboostに最初の勾配と2番目の勾配が必要であることを知っていますが、他の誰かがobj関数として「mae」を使用していますか?
最初にちょっとした理論、ごめんなさい! MAEの卒業生とヘシアンを求めましたが、MAEは 継続的に2階微分可能 ではないため、1次および2次導関数を計算しようとすると、注意が必要になります。 MAEが連続的に微分可能になるのを防ぐx=0
の "ねじれ"を参照してください。
さらに、二次導関数は、適切に動作するすべてのポイントでゼロです。 XGBoostでは、2次導関数は葉の重みの分母として使用され、ゼロの場合は深刻な数学エラーを作成します。
これらの複雑さを考えると、最善の策は、他の適切に機能する関数を使用してMAEを近似することです。見てみましょう。
上記のように、絶対値を近似する関数がいくつかあります。明らかに、非常に小さな値の場合、二乗誤差(MSE)はMAEのかなり良い近似値です。ただし、これはユースケースには不十分であると想定しています。
Huber損失はよく文書化された損失関数です。ただし、滑らかではないため、滑らかな微分を保証することはできません。 Psuedo-Huber関数を使用して近似できます。次のようにpython XGBoostで実装できます。
import xgboost as xgb
dtrain = xgb.DMatrix(x_train, label=y_train)
dtest = xgb.DMatrix(x_test, label=y_test)
param = {'max_depth': 5}
num_round = 10
def huber_approx_obj(preds, dtrain):
d = preds - dtrain.get_labels() #remove .get_labels() for sklearn
h = 1 #h is delta in the graphic
scale = 1 + (d / h) ** 2
scale_sqrt = np.sqrt(scale)
grad = d / scale_sqrt
hess = 1 / scale / scale_sqrt
return grad, hess
bst = xgb.train(param, dtrain, num_round, obj=huber_approx_obj)
obj=huber_approx_obj
を置き換えることにより、他の機能を使用できます。
Fair Lossはまったく文書化されていませんが、かなりうまく機能しているようです。公正損失関数は次のとおりです。
そのように実装できますが、
def fair_obj(preds, dtrain):
"""y = c * abs(x) - c**2 * np.log(abs(x)/c + 1)"""
x = preds - dtrain.get_labels()
c = 1
den = abs(x) + c
grad = c*x / den
hess = c*c / den ** 2
return grad, hess
このコードは、Kaggle Allstate Challengeの2番目の場所 solution から採用されています。
Log-Cosh損失関数。
def log_cosh_obj(preds, dtrain):
x = preds - dtrain.get_labels()
grad = np.tanh(x)
hess = 1 / np.cosh(x)**2
return grad, hess
最後に、上記の関数をテンプレートとして使用して、独自のカスタム損失関数を作成できます。
上記のフーバー損失の場合、勾配には負の符号が事前に欠落していると思います。としてする必要があります
grad = - d / scale_sqrt