Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью 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. Для загрузки набора данных из OpenML используется функция sklearn.datasets.fetch_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 повторениями.

Мы сравним следующие стратегии:

  • 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"
)
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()
Density of the accuracy scores for the different multiclass strategies

Как видно, после оптимизации гиперпараметров все многоклассовые стратегии показывают схожую эффективность, как и обсуждается в работе [3].

Заключение

Эти результаты можно объяснить следующим образом.

Во-первых, причина, по которой стратегии «один против одного» и кодирования выходов с коррекцией ошибок превосходят дерево, когда гиперпараметры не оптимизированы, заключается в том, что они объединяют большее число классификаторов. Ансамблирование улучшает обобщающую способность. Это отчасти похоже на то, почему классификатор с бэггингом обычно работает лучше, чем отдельное дерево решений, если гиперпараметры не оптимизируются.

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

Наконец, важно помнить, что оцениватели scikit-learn разработаны с использованием определённой стратегии, позволяющей им поддерживать многоклассовую классификацию из коробки. Поэтому для таких оценивателей нет необходимости использовать другие стратегии. Эти стратегии главным образом полезны для сторонних оценивателей, поддерживающих только бинарную классификацию. В любом случае мы также показываем, что гиперпараметры следует оптимизировать.

Литература

[1]

https://archive.ics.uci.edu/ml/datasets/Yeast

[2]

«Сведение многоклассовой классификации к бинарной: единый подход к классификаторам с отступом». Allwein, Erin L., Robert E. Schapire и Yoram Singer. Journal of machine learning research. 1 декабря (2000): 113–141.

[3] (1,2)

«В защиту классификации “один против всех”». Journal of Machine Learning Research. 5 января (2004): 101–141.

Общее время выполнения скрипта: (0 минут 27.760 секунд)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_multiclass_overview.ipynb

Download Python source code: plot_multiclass_overview.py

Download zipped: plot_multiclass_overview.zip

Связанные примеры

Вложенная и невложенная кросс-валидация

Многометочная классификация с использованием цепочки классификаторов

Настройка порога функции принятия решения после обучения

Границы принятия решений мультиномиальной логистической регрессии и логистической регрессии «один против остальных»

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/multiclass/plot_multiclass_overview.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API