Как определить квадратичную взвешенную каппу в качестве метрики оценки в классификаторе CatBoost

Вопрос или проблема

Я использую catboost для задачи многоклассовой классификации. Я хочу использовать квадратный взвешенный каппа в качестве метрики оценки.

Catboost уже имеет WKappa в качестве eval_metric, но это линейная взвешенная версия, а не квадратичная.

clf = CatBoostClassifier(objective="MultiClass",
eval_metric=q_weighted_kappa(),
learning_rate=0.01,
n_estimators=750,
od_type="Iter",
depth=35,
early_stopping_rounds=500,
random_seed=42,

)

Мне нужна помощь в определении функции q_weighted_kappa(), которую я могу использовать, как указано выше.

Каппа в Sklearn имеет 2 варианта: простая и взвешенная. Похоже, что WKappa относится к взвешенной (квадратной) каппе в терминах sklearn, а Каппа – к простой.

Ответ или решение

Чтобы задать квадратичный взвешенный коэффициент каппы (quadratic weighted kappa) в качестве метрики оценки для классификатора CatBoost в задаче многоклассовой классификации, необходимо определить собственную функцию оценки. Вот как это можно сделать.

Параметры задачи

Ваша задача состоит в том, чтобы использовать метрику квадратичного взвешенного коэффициента каппы во время обучения классификатора CatBoost. У CatBoost уже есть метрика WKappa, которая является линейно взвешенной, но нам нужна именно квадратичная версия.

Определение функции q_weighted_kappa()

Для начала, мы создадим функцию, которая будет возвращать значение квадратичного взвешенного коэффициента каппы. Эта метрика оценивает согласованность между предсказанными и фактическими классами, где штраф за неправильное предсказание увеличивается с увеличением расстояния между классами.

import numpy as np
from sklearn.metrics import cohen_kappa_score

def q_weighted_kappa(y_true, y_pred):
    """
    Функция для вычисления квадратичного взвешенного коэффициента каппы.

    :param y_true: Массив целевых классов (истинные значения).
    :param y_pred: Массив предсказанных классов (прогнозы модели).
    :returns: Значение квадратичного взвешенного коэффициента каппы.
    """
    labels = np.unique(np.concatenate((y_true, y_pred)))
    n_labels = len(labels)

    # Создание матрицы частот
    confusion_matrix = np.zeros((n_labels, n_labels), dtype=np.int)

    for true, pred in zip(y_true, y_pred):
        confusion_matrix[true, pred] += 1

    # Получение числового представления классов
    weights = np.zeros((n_labels, n_labels))
    for i in range(n_labels):
        for j in range(n_labels):
            weights[i, j] = (i - j) ** 2

    # Вычисление вероятностей
    total = confusion_matrix.sum()
    prob = confusion_matrix / total if total > 0 else confusion_matrix

    # Ожидаемое значение
    expected_prob = np.outer(prob.sum(axis=1), prob.sum(axis=0))

    # Kappa
    kappa = 1 - (np.sum(weights * prob) / np.sum(weights * expected_prob))

    return kappa

Включение q_weighted_kappa в CatBoost

Следующим шагом станет интеграция этой функции в процесс обучения модели CatBoost. Для этого вам необходимо будет использовать параметр custom_metric для добавить свою метрику, так как параметр eval_metric не принимает функции.

from catboost import CatBoostClassifier

# Создайте экземпляр модели CatBoostClassifier
clf = CatBoostClassifier(
    objective="MultiClass",
    learning_rate=0.01,
    n_estimators=750,
    od_type="Iter",
    depth=35,
    early_stopping_rounds=500,
    random_seed=42
)

# Обучите модель на ваших данных
clf.fit(X_train, y_train, eval_set=(X_valid, y_valid), custom_metric=[q_weighted_kappa])

Заключение

Теперь вы можете использовать квадратичный взвешенный коэффициент каппы для оценки вашей модели. Эта метрика будет отражать не только точность предсказаний, но и степень, в которой неверные классы совпадают между собой.

При необходимости вы можете адаптировать функцию q_weighted_kappa для работы с вашими конкретными данными и задачами. Экспериментируя с различными параметрами и оценками, вы сможете оптимизировать свою модель для достижения наилучших результатов.

Оцените материал
Добавить комментарий

Капча загружается...