web-dev-qa-db-ja.com

Xgboost-目的関数として「mae」を使用する方法

私はxgboostに最初の勾配と2番目の勾配が必要であることを知っていますが、他の誰かがobj関数として「mae」を使用していますか?

17
Sam Qian

最初にちょっとした理論、ごめんなさい! MAEの卒業生とヘシアンを求めましたが、MAEは 継続的に2階微分可能 ではないため、1次および2次導関数を計算しようとすると、注意が必要になります。 MAEが連続的に微分可能になるのを防ぐx=0の "ねじれ"を参照してください。

さらに、二次導関数は、適切に動作するすべてのポイントでゼロです。 XGBoostでは、2次導関数は葉の重みの分母として使用され、ゼロの場合は深刻な数学エラーを作成します。

これらの複雑さを考えると、最善の策は、他の適切に機能する関数を使用してMAEを近似することです。見てみましょう。

Some different loss functions

上記のように、絶対値を近似する関数がいくつかあります。明らかに、非常に小さな値の場合、二乗誤差(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はまったく文書化されていませんが、かなりうまく機能しているようです。公正損失関数は次のとおりです。

Fair Loss Function

そのように実装できますが、

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

最後に、上記の関数をテンプレートとして使用して、独自のカスタム損失関数を作成できます。

34

上記のフーバー損失の場合、勾配には負の符号が事前に欠落していると思います。としてする必要があります

grad = - d / scale_sqrt
0
hbar137