Вопрос или проблема
В настоящее время я использую алгоритм случайного леса 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))
Заключение
Таким образом, благодаря методу "Один против всех" и оптимизации порогов, вы можете улучшить результаты многоклассовой классификации, что позволяет более точно определять класс для каждого примера. Не забывайте, что для корректного выбора порогов необходимо анализировать данные и результативность модели с учетом специфики вашей задачи.