Примечание
Перейти к концу для загрузки полного примера кода. или для запуска этого примера в вашем браузере через JupyterLite или Binder
Обзор мета-эстиматоров для многоклассовой тренировки
В этом примере мы обсудим проблему классификации, когда целевая переменная состоит более чем из двух классов. Это называется многоклассовой классификацией.
Во всех эстиматорах scikit-learn по умолчанию поддерживается многоклассовая классификация: для конечного пользователя была реализована наиболее подходящая стратегия. Модуль sklearn.multiclass реализует различные стратегии, которые можно использовать для экспериментов или разработки сторонних эстиматоров, которые поддерживают только бинарную классификацию.
sklearn.multiclass включает стратегии OvO/OvR, используемые для обучения многоклассового классификатора путём подгонки набора бинарных классификаторов (мета-эстиматоры OneVsOneClassifier и OneVsRestClassifier). Этот пример рассмотрит их.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Набор данных Yeast UCI
В этом примере мы используем набор данных UCI [1], обычно называемый набором данных Yeast. Мы используем функцию sklearn.datasets.fetch_openml для загрузки набора данных из OpenML.
from sklearn.datasets import fetch_openml X, y = fetch_openml(data_id=181, as_frame=True, return_X_y=True)
Чтобы узнать, с каким типом задачи анализа данных мы имеем дело, мы можем проверить целевую переменную, для которой мы хотим построить предсказательную модель.
y.value_counts().sort_index()
class_protein_localization CYT 463 ERL 5 EXC 35 ME1 44 ME2 51 ME3 163 MIT 244 NUC 429 POX 20 VAC 30 Name: count, dtype: int64
Мы видим, что целевая переменная дискретная и состоит из 10 классов. Поэтому мы имеем дело с задачей многоклассовой классификации.
Сравнение стратегий
В следующем эксперименте мы используем DecisionTreeClassifier и RepeatedStratifiedKFold кросс-валидацию с 3 разбиениями и 5 повторениями.
Мы сравниваем следующие стратегии:
- :class:~sklearn.tree.DecisionTreeClassifier может обрабатывать многоклассовую классификацию без каких-либо специальных настроек. Она работает, разбивая обучающие данные на меньшие подмножества и фокусируясь на наиболее часто встречающемся классе в каждом подмножестве. Повторяя этот процесс, модель может точно классифицировать входные данные по множеству различных классов.
-
OneVsOneClassifierобучается на наборе бинарных классификаторов, где каждый классификатор обучен различать два класса. -
OneVsRestClassifier: обучается на наборе бинарных классификаторов, где каждый классификатор обучен различать один класс и все остальные классы. -
OutputCodeClassifier: обучается на наборе бинарных классификаторов, где каждый классификатор обучен различать набор классов от остальных классов. Набор классов определяется кодовой книгой, которая генерируется случайным образом в scikit-learn. Этот метод предоставляет параметрcode_sizeдля управления размером кодовой книги. Мы устанавливаем его больше единицы, так как нас не интересует сжатие представления классов.
import pandas as pd
from sklearn.model_selection import RepeatedStratifiedKFold, cross_validate
from sklearn.multiclass import (
OneVsOneClassifier,
OneVsRestClassifier,
OutputCodeClassifier,
)
from sklearn.tree import DecisionTreeClassifier
cv = RepeatedStratifiedKFold(n_splits=3, n_repeats=5, random_state=0)
tree = DecisionTreeClassifier(random_state=0)
ovo_tree = OneVsOneClassifier(tree)
ovr_tree = OneVsRestClassifier(tree)
ecoc = OutputCodeClassifier(tree, code_size=2)
cv_results_tree = cross_validate(tree, X, y, cv=cv, n_jobs=2)
cv_results_ovo = cross_validate(ovo_tree, X, y, cv=cv, n_jobs=2)
cv_results_ovr = cross_validate(ovr_tree, X, y, cv=cv, n_jobs=2)
cv_results_ecoc = cross_validate(ecoc, X, y, cv=cv, n_jobs=2)
Теперь мы можем сравнить статистическую эффективность различных стратегий. Мы отображаем распределение оценок различных стратегий.
from matplotlib import pyplot as plt
scores = pd.DataFrame(
{
"DecisionTreeClassifier": cv_results_tree["test_score"],
"OneVsOneClassifier": cv_results_ovo["test_score"],
"OneVsRestClassifier": cv_results_ovr["test_score"],
"OutputCodeClassifier": cv_results_ecoc["test_score"],
}
)
ax = scores.plot.kde(legend=True)
ax.set_xlabel("Accuracy score")
ax.set_xlim([0, 0.7])
_ = ax.set_title(
"Density of the accuracy scores for the different multiclass strategies"
)

На первый взгляд, встроенная стратегия классификатора дерева решений работает довольно хорошо. Стратегии один-против-одного и стратегии кодирования исправления ошибок работают даже лучше. Однако стратегия один-против-всех не работает так хорошо, как другие стратегии.
Действительно, эти результаты воспроизводят то, что сообщается в литературе, как в [2]. Однако история не так проста, как кажется.
Значение поиска гиперпараметров
Позже было показано в [3], что стратегии многоклассовой классификации покажут аналогичные оценки, если сначала оптимизированы гиперпараметры базовых классификаторов.
Здесь мы попытаемся воспроизвести такой результат, по крайней мере, оптимизируя глубину базового дерева решений.
from sklearn.model_selection import GridSearchCV
param_grid = {"max_depth": [3, 5, 8]}
tree_optimized = GridSearchCV(tree, param_grid=param_grid, cv=3)
ovo_tree = OneVsOneClassifier(tree_optimized)
ovr_tree = OneVsRestClassifier(tree_optimized)
ecoc = OutputCodeClassifier(tree_optimized, code_size=2)
cv_results_tree = cross_validate(tree_optimized, X, y, cv=cv, n_jobs=2)
cv_results_ovo = cross_validate(ovo_tree, X, y, cv=cv, n_jobs=2)
cv_results_ovr = cross_validate(ovr_tree, X, y, cv=cv, n_jobs=2)
cv_results_ecoc = cross_validate(ecoc, X, y, cv=cv, n_jobs=2)
scores = pd.DataFrame(
{
"DecisionTreeClassifier": cv_results_tree["test_score"],
"OneVsOneClassifier": cv_results_ovo["test_score"],
"OneVsRestClassifier": cv_results_ovr["test_score"],
"OutputCodeClassifier": cv_results_ecoc["test_score"],
}
)
ax = scores.plot.kde(legend=True)
ax.set_xlabel("Accuracy score")
ax.set_xlim([0, 0.7])
_ = ax.set_title(
"Density of the accuracy scores for the different multiclass strategies"
)
plt.show()

Мы можем видеть, что после оптимизации гиперпараметров все стратегии многоклассовой классификации имеют аналогичную производительность, как обсуждалось в [3].
Заключение
Мы можем получить некоторое понимание этих результатов.
Во-первых, причина, по которой стратегии один-против-одного и кодирование исправления ошибок превосходят дерево решений, когда гиперпараметры не оптимизированы, заключается в том, что они объединяют большее количество классификаторов. Объединение улучшает обобщающую способность. Это немного похоже на то, почему классификатор с бустингом обычно показывает лучшие результаты, чем отдельное дерево решений, если не уделяется внимания оптимизации гиперпараметров.
Затем мы видим важность оптимизации гиперпараметров. Действительно, это следует регулярно исследовать при разработке предсказательных моделей, даже если такие методы, как ансамблирование, помогают уменьшить это влияние.
Наконец, важно напомнить, что эстиматоры в scikit-learn разработаны со специфической стратегией для обработки многоклассовой классификации по умолчанию. Таким образом, для этих эстиматоров нет необходимости использовать разные стратегии. Эти стратегии в основном полезны для сторонних эстиматоров, поддерживающих только бинарную классификацию. В любом случае мы также показываем, что следует оптимизировать гиперпараметры.
Ссылки
Общее время выполнения скрипта: (0 минут 22.564 секунды)
Похожие примеры
© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/multiclass/plot_multiclass_overview.html