多クラス分類の GridSearchCV で multiclass_log_loss を使う

lightgbm の多クラス分類のパラメータチューニングで GridSearchCV を使うときに、multiclass_log_loss を scoring として使う方法です。

ググってもなかなか見つからなかったので、今後のためにメモしておきます。

Custom scoring function for grid search classification

Multi Class Log Loss Function

以下の関数を scoring に渡します。

import numpy as np
from sklearn.metrics import make_scorer


@make_scorer
def multiclass_log_loss(y_true, y_pred, eps=1e-15):
    """Multi class version of Logarithmic Loss metric.
    https://www.kaggle.com/wiki/MultiClassLogLoss

    idea from this post:
    http://www.kaggle.com/c/emc-data-science/forums/t/2149/is-anyone-noticing-difference-betwen-validation-and-leaderboard-error/12209#post12209

    Parameters
    ----------
    y_true : array, shape = [n_samples]
    y_pred : array, shape = [n_samples, n_classes]

    Returns
    -------
    loss : float
    """
    predictions = np.clip(y_pred, eps, 1 - eps)

    # normalize row sums to 1
    predictions /= predictions.sum(axis=1)[:, np.newaxis]

    actual = np.zeros(y_pred.shape)
    rows = actual.shape[0]
    actual[np.arange(rows), y_true.astype(int)] = 1
    vsota = np.sum(actual * np.log(predictions))
    
   # For GridSearchCV, need neg value.
    return -1.0 / rows * vsota
    # return -1.0 / rows * vsota

ちなみに、GridSearchCV へ渡す estimatorlightgbm.LGBMClassifier を使うと、確率ではなく正解予測を返すのでエラーが出ます。

lightgbm.LGBMModel を使えば確率で普通に返してくれるのでそのまま使えます。

とてもくだらないミスですが、気づいたら2時間も使ってしまった!