Настройка порогов с методом один против всех для многоклассовой классификации на Python

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

В настоящее время я использую алгоритм случайного леса One vs Rest для задачи многоклассовой классификации на Python и хочу найти оптимальный порог для каждого класса. Как я могу сделать это с помощью подхода OVR (One-Vs-Rest)?

В общем, невозможно настроить какой-либо порог в многоклассовой классификации:

  • В бинарной классификации изменение порога означает прогнозирование большего или меньшего числа экземпляров как положительных, так как два класса являются дополнением друг друга (любой экземпляр, который не является положительным, отрицателен, и наоборот).
  • Это не работает в многоклассовой настройке: например, экземпляр предсказывается как 55% класс A. Если порог, скажем, 60%, что тогда следует предсказать? Класс B, предсказанный на 30%, или класс C, предсказанный на 15%?

Единственный способ вновь ввести пороги в значимом виде – это перейти к мульти-меточной классификации, т.е. предсказывать каждый класс как ‘да’ или ‘нет’ независимо от других классов (т.е. N независимых бинарных задач). Но это совершенно другой способ проектирования проблемы, так как это означает, что экземпляр может иметь ноль или несколько классов.

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

Для решения задачи оптимизации порогов в многоклассовой классификации с использованием подхода "Один против всех" (One vs. Rest, OVR) в Python можно воспользоваться следующими шагами:

1. Подготовка данных

Импортируйте необходимые библиотеки и загрузите ваши данные:

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_recall_curve
import matplotlib.pyplot as plt

# Загрузите ваши данные
data = pd.read_csv('data.csv')  # Укажите путь к вашему файлу
X = data.drop('target', axis=1)  # Признаки
y = data['target']  # Целевая переменная

2. Деление данных на обучающую и тестовую выборки

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

3. Обучение классификатора OVR

В данном случае мы будем использовать Random Forest с OVR:

from sklearn.multiclass import OneVsRestClassifier

# Создаем классификатор и обучаем его
rf_classifier = OneVsRestClassifier(RandomForestClassifier(n_estimators=100, random_state=42))
rf_classifier.fit(X_train, y_train)

4. Получение вероятностей

Для каждой из классов получим вероятности:

y_prob = rf_classifier.predict_proba(X_test)

5. Оптимизация порогов

Теперь мы можем оптимизировать пороги для каждого класса. Одним из распространенных методов является использование кривой Precision-Recall. Для этого мы можем написать функцию для нахождения оптимального порога:

def find_optimal_threshold(y_true, y_probs, target_class):
    precision, recall, thresholds = precision_recall_curve(y_true == target_class, y_probs[:, target_class])
    fscore = 2 * (precision * recall) / (precision + recall)
    optimal_idx = np.argmax(fscore)
    optimal_threshold = thresholds[optimal_idx]
    return optimal_threshold

6. Применение функции для каждой категории

Теперь найдем оптимальные пороги для каждого класса:

optimal_thresholds = {}
for class_index in range(y_prob.shape[1]):
    optimal_threshold = find_optimal_threshold(y_test, y_prob, class_index)
    optimal_thresholds[class_index] = optimal_threshold

print("Оптимальные пороги для каждого класса:", optimal_thresholds)

7. Применение найденных порогов

После нахождения порогов, вы можете сделать предсказания с использованием этих порогов:

def custom_predict(y_probs, thresholds):
    return np.array([np.where(prob >= thresholds[i], 1, 0) for i, prob in enumerate(y_probs.T)]).T

y_pred = custom_predict(y_prob, np.array(list(optimal_thresholds.values())))

8. Оценка результатов

Наконец, оцените качество ваших предсказаний:

from sklearn.metrics import classification_report

print(classification_report(y_test, y_pred))

Заключение

Таким образом, благодаря методу "Один против всех" и оптимизации порогов, вы можете улучшить результаты многоклассовой классификации, что позволяет более точно определять класс для каждого примера. Не забывайте, что для корректного выбора порогов необходимо анализировать данные и результативность модели с учетом специфики вашей задачи.

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

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