めも

メモ.

エラー解決:PythonのXGBoostで目的関数を変更する

これまでの場合

過去のバージョン(以下)では確か custom_objective パラメータにてgradientとhessian matrixを返すような関数を渡せばよかった。

paper.hatenadiary.jp

xgboost-0.4a30では objective がこれに該当する。が…custom objectiveで検索してもkaggleの優勝者のブログしか出てこない。

エラー内容

コード

def logregobj(dtrain, preds):
    grad = preds
    hess = preds * (1.0-preds)
    return grad, hess

model = XGBRegressor(objective=xgb_quantile_obj)
model.fit(X_train, y_train)

エラーメッセージ

XGBoostError: b'unknown objective function type: <function logregobj at 0x11608c9d8>'

解決

解決法:xgboost-0.6a2にアップデートする。

ドキュメントより引用すると

Note: A custom objective function can be provided for the objective parameter. In this case, it should have the signature objective(y_true, y_pred) -> grad, hess:

y_true: array_like of shape [n_samples] The target values

y_pred: array_like of shape [n_samples] The predicted values grad: array_like of shape [n_samples] The value of the gradient for each sample point.

hess: array_like of shape [n_samples] The value of the second derivative for each sample point

引用元:

Python API Reference — xgboost 0.6 documentation

正しいように思う…と思ってバージョンを xgboost-0.6a2 にアップデートしたらエラーがなくなりました。ただのバグだったようです。ただ、確か何か理由があって xgboost-0.4a30にしていたはずなのでまたどこかでつまづくかもしれません。

実装例・参考

openになっているので実装してコミットしたほうがいいかもしれない。あと problems with custom objective function for mean absolute percentage error(MAPE) · Issue #1818 · dmlc/xgboost · GitHub

def mspe(y, dtrain):
    yhat = dtrain.get_label()
    grad = 2.0/yhat * (y * 1.0 / yhat - 1)
    hess = 2.0/(yhat**2)
    return grad, hess

grad-1 をかける必要があると思った。

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。