1.12. Многоклассовый и многозадачный алгоритмы¶
Этот раздел руководства пользователя охватывает функциональность, связанную с проблемами мультиобучения, включая multiclass, multilabel и multioutput классификацию и регрессию.
Модули в этом разделе реализуют мета-модели, которые требуют предоставления базовой модели в их конструкторе. Мета-модели расширяют функциональность базовой модели для поддержки задач с множественным обучением, что достигается путем преобразования задачи с множественным обучением в набор более простых задач, а затем подбора одной модели для каждой задачи.
Этот раздел охватывает два модуля: sklearn.multiclass
(Многоклассовая) и sklearn.multioutput
(Многозадачная).
На диаграмме ниже показаны типы задач, за которые отвечает каждый модуль, и соответствующие метамодели, которые предоставляет каждый модуль.
В таблице ниже приведена краткая справка о различиях между типами задач. Более подробные объяснения можно найти в последующих разделах этого руководства.
Количество целей |
Целевая мощность |
Валидация
|
|
---|---|---|---|
Многоклассовая классификаци |
1 |
>2 |
‘multiclass’ |
Классификаци с многими метками |
>1 |
2 (0 or 1) |
‘multilabel-indicator’ |
Многоклассовая-многозадачная классификаци |
>1 |
>2 |
‘multiclass-multioutput’ |
Многозадачная регрессия |
>1 |
Непрерывная |
‘continuous-multioutput’ |
Ниже приведена сводка моделей scikit-learn, в которые встроена поддержка мультиобучения, сгруппированных по стратегиям. Вам не нужны мета-модели, представленные в этом разделе, если вы используете одну из этих моделей. Однако метамодели могут предоставлять дополнительные стратегии, помимо встроенных:
Для многоклассовой классификации:.
svm.LinearSVC
(setting multi_class=”crammer_singer”)linear_model.LogisticRegression
(setting multi_class=”multinomial”)linear_model.LogisticRegressionCV
(setting multi_class=”multinomial”)
Многоклассовая классификация как Один против одного:
gaussian_process.GaussianProcessClassifier
(настройка multi_class = “one_vs_one”)
Многоклассовая классификация как Один против всех:
gaussian_process.GaussianProcessClassifier
(настройка multi_class = “one_vs_rest”)svm.LinearSVC
(настройка multi_class=”ovr”)linear_model.LogisticRegression
(настройка multi_class=”ovr”)linear_model.LogisticRegressionCV
(настройка multi_class=”ovr”)
Поддержка классификации с многими метками:
Поддержка Многоклассовая-многозадачная классификации:
1.12.1. Многоклассовая классификация¶
Предупреждение
Все классификаторы в scikit-learn делают многоклассовую классификацию из коробки. Вам не нужно использовать модуль sklearn.multiclass
, если вы не хотите экспериментировать с различными мультиклассовыми стратегиями.
Многоклассовая классификация - это задача классификации с более чем двумя классами. Каждый образец может быть отнесен только к одному классу.
Например, классификация с использованием признаков, извлеченных из набора изображений фруктов, где каждое изображение может быть либо апельсином, либо яблоком, либо грушей.
Каждое изображение - это один образец, и он помечен как один из 3 возможных классов.
Многоклассовая классификация предполагает, что каждому образцу присваивается одна и только одна метка - один образец не может быть, например, одновременно грушей и яблоком.
Хотя все классификаторы scikit-learn способны к многоклассовой классификации, метамодели, предлагаемые sklearn.multiclass
, не позволяют изменять способ обработки более чем двух классов, поскольку это может повлиять на производительность классификатора (либо в смысле ошибки обобщения, либо в смысле требуемых вычислительных ресурсов).
1.12.1.1. Формат цели¶
Валидация multiclass представлена в методе type_of_target
(y
):
1d- или столбцовый вектор, содержащий более двух дискретных значений. Пример вектора
y
для 4 образцов:>>> import numpy as np >>> y = np.array(['apple', 'pear', 'apple', 'orange']) >>> print(y) ['apple' 'pear' 'apple' 'orange']
Плотная или разреженная binary матрица формы
(n_samples, n_classes)
с одним образцом в строке, где каждый столбец представляет один класс. Пример плотной и разреженной binary матрицыy
для 4 образцов, где столбцы по порядку - яблоко, апельсин и груша:>>> import numpy as np >>> from sklearn.preprocessing import LabelBinarizer >>> y = np.array(['apple', 'pear', 'apple', 'orange']) >>> y_dense = LabelBinarizer().fit_transform(y) >>> print(y_dense) [[1 0 0] [0 0 1] [1 0 0] [0 1 0]] >>> from scipy import sparse >>> y_sparse = sparse.csr_matrix(y_dense) >>> print(y_sparse) (0, 0) 1 (1, 2) 1 (2, 0) 1 (3, 1) 1
Более подробную информацию о LabelBinarizer
см. в Преобразование цели прогнозирования (y).
1.12.1.2. OneVsRestClassifier¶
Стратегия one-vs-rest, также известная как one-vs-all, реализована в OneVsRestClassifier
.
Стратегия заключается в подборе одного классификатора для каждого класса.
Для каждого классификатора класс сравнивается со всеми остальными классами.
Помимо вычислительной эффективности (требуется всего n_classes
классификаторов), одним из преимуществ этого подхода является его интерпретируемость.
Поскольку каждый класс представлен одним и только одним классификатором, можно получить знания о классе, проанализировав соответствующий классификатор.
Это наиболее часто используемая стратегия, и она является справедливым выбором по умолчанию.
Ниже приведен пример многоклассового обучения с использованием OvR:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsRestClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> OneVsRestClassifier(LinearSVC(dual="auto", random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
OneVsRestClassifier
также поддерживает классификацию по нескольким меткам.
Чтобы использовать эту возможность, подайте классификатору матрицу индикаторов, в которой ячейка [i, j] указывает на наличие метки j в выборке i.
1.12.1.3. OneVsOneClassifier¶
OneVsOneClassifier
строит один классификатор на пару классов. Во время предсказания выбирается класс, получивший наибольшее количество голосов. В случае равенства голосов (среди двух классов с равным числом голосов) выбирается класс с наибольшим суммарным доверием к классификации путем суммирования уровней доверия к классификации в паре, вычисленных базовыми бинарными классификаторами.
Так как для этого требуется обучение n_classes * (n_classes - 1) / 2
классификаторов, этот метод обычно медленнее, чем метод “один против остальных”, из-за его сложности O(n_classes^2)
. Однако этот метод может быть полезен для таких алгоритмов, как ядерные алгоритмы, которые не очень хорошо масштабируются с увеличением n_classes
. Это происходит потому, что каждая отдельная задача обучения затрагивает лишь небольшое подмножество данных, в то время как при использовании метода “один против остальных” весь набор данных используется n_classes
раз.
Функция принятия решения является результатом монотонного преобразования классификации “один против одного”.
Ниже приведен пример многоклассового обучения с использованием OvO:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsOneClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> OneVsOneClassifier(LinearSVC(dual="auto", random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
1.12.1.4. OutputCodeClassifier¶
Стратегии, основанные на кодах с коррекцией ошибок на выходе, довольно сильно отличаются от стратегий “один против остальных” и “один против одного”. В этих стратегиях каждый класс представлен в евклидовом пространстве, где каждое измерение может быть только 0 или 1. По-другому можно сказать, что каждый класс представлен двоичным кодом (массивом из 0 и 1). Матрица, в которой хранится информация о местоположении/коде каждого класса, называется кодовой книгой. Размерность кода - это размерность вышеупомянутого пространства. Интуитивно понятно, что каждый класс должен быть представлен как можно более уникальным кодом, а хорошая кодовая книга должна быть разработана таким образом, чтобы оптимизировать точность классификации. В данной реализации мы просто используем случайно сгенерированную кодовую книгу, как это было предложено в [3], хотя в будущем могут быть добавлены более сложные методы.
В момент подбора на каждый бит кодовой книги устанавливается один двоичный классификатор. В момент предсказания классификаторы используются для проектирования новых точек в пространстве классов, и выбирается класс, наиболее близкий к этим точкам.
В OutputCodeClassifier
атрибут code_size
позволяет пользователю контролировать количество классификаторов, которые будут использоваться. Он представляет собой процент от общего числа классов.
Число между 0 и 1 потребует меньшего количества классификаторов, чем “один против остальных”. Теоретически, log2(n_classes) / n_classes
достаточно для однозначного представления каждого класса. Однако на практике это может не привести к хорошей точности, поскольку log2(n_classes)
намного меньше, чем n_classes
.
Число, большее 1, требует большего количества классификаторов, чем один против остальных. В этом случае одни классификаторы теоретически будут исправлять ошибки, допущенные другими классификаторами, отсюда и название “исправляющие ошибки”. На практике, однако, этого может не произойти, поскольку ошибки классификаторов обычно коррелируют. Выходные коды с исправлением ошибок имеют схожий эффект с мешками.
Ниже приведен пример многоклассового обучения с использованием выходных кодов:
>>> from sklearn import datasets
>>> from sklearn.multiclass import OutputCodeClassifier
>>> from sklearn.svm import LinearSVC
>>> X, y = datasets.load_iris(return_X_y=True)
>>> clf = OutputCodeClassifier(LinearSVC(dual="auto", random_state=0),
... code_size=2, random_state=0)
>>> clf.fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
1.12.2. Классификаци с многими метками¶
Классификаци с многими метками (Multilabel classification тесно связанная с многозадачной классификацией (multioutput)) - это задача классификации, в которой каждому образцу присваивается m
меток из n_classes
возможных классов, где m
может быть от 0 до n_classes
включительно. Это можно представить как предсказание свойств образца, которые не являются взаимоисключающими. Формально, каждому классу присваивается двоичный выход для каждого образца. Положительные классы обозначаются 1, а отрицательные - 0 или -1. Это сравнимо с выполнением задач бинарной классификации n_classes
, например, с помощью MultiOutputClassifier
. При таком подходе каждая метка обрабатывается независимо, в то время как классификаторы с многими метками могут обрабатывать несколько классов одновременно, учитывая коррелированное поведение между ними.
Например, предсказание тем, относящихся к текстовому документу или видео. Документ или видео могут быть посвящены одной из тем “религия”, “политика”, “финансы” или “образование”, нескольким тематическим классам или всем тематическим классам.
1.12.2.1. Формат цели¶
Правильным представлением multilabel y
является плотная или разреженная binary матрица формы (n_samples, n_classes)
.
Каждый столбец представляет класс. Строки 1
в каждой строке обозначают положительные классы, которыми был помечен образец.
Пример плотной матрицы y
для 3 образцов:
>>> y = np.array([[1, 0, 0, 1], [0, 0, 1, 1], [0, 0, 0, 0]])
>>> print(y)
[[1 0 0 1]
[0 0 1 1]
[0 0 0 0]]
Плотные бинарные матрицы также могут быть созданы с помощью MultiLabelBinarizer
.
Для получения дополнительной информации обратитесь к Преобразование цели прогнозирования (y).
Пример того же y
в виде разреженной матрицы:
>>> y_sparse = sparse.csr_matrix(y)
>>> print(y_sparse)
(0, 0) 1
(0, 3) 1
(1, 2) 1
(1, 3) 1
1.12.2.2. MultiOutputClassifier¶
Поддержка классификаци с многими метками может быть добавлена к любому классификатору с помощью MultiOutputClassifier
.
Эта стратегия заключается в подборе одного классификатора для каждой цели.
Это позволяет классифицировать несколько целевых переменных.
Целью этого класса является расширение оценочных средств для оценки ряда целевых функций (f1,f2,f3…,fn), которые обучаются на одной матрице предикторов X для предсказания ряда ответов (y1,y2,y3…,yn).
Пример использования MultiOutputClassifier
можно найти в разделе о Многоклассовая классификация с несколькими выходами (многозадачная классификация), так как это обобщение классификации с многими метками на многозадачные выходы вместо бинарных выходов.
1.12.2.3. ClassifierChain¶
Цепочки классификаторов (см. ClassifierChain
) - это способ объединения нескольких бинарных классификаторов в одну многоклассовую модель, которая способна использовать корреляции между целями.
Для задачи классификации с N классами N бинарным классификаторам присваивается целое число от 0 до N-1. Эти целые числа определяют порядок моделей в цепочке. Затем каждый классификатор подгоняется под имеющиеся обучающие данные плюс истинные метки классов, модели которых был присвоен меньший номер.
При прогнозировании истинные метки недоступны. Вместо этого предсказания каждой модели передаются последующим моделям в цепочке для использования в качестве признаков.
Очевидно, что порядок цепочки важен. Первая модель в цепочке не имеет информации о других метках, в то время как последняя модель в цепочке имеет признаки, указывающие на наличие всех других меток. В общем случае мы не знаем оптимального порядка следования моделей в цепочке, поэтому обычно подбирается множество случайно упорядоченных цепочек, и их предсказания усредняются.
Ссылки:
Jesse Read, Bernhard Pfahringer, Geoff Holmes, Eibe Frank, “Classifier Chains for Multi-label Classification”, 2009.
1.12.3. Многоклассовая классификация с несколькими выходами (многозадачная классификация)¶
Многоклассовая классификация (также известная как многозадачная классификация) - это задача классификации, которая маркирует каждый образец набором небинарных свойств. Как число свойств, так и число классов для каждого свойства больше 2. Таким образом, одна модель решает несколько совместных задач классификации. Это как обобщение задачи классификации с несколькими метками, в которой рассматриваются только бинарные атрибуты, так и обобщение задачи классификации с несколькими классами, в которой рассматривается только одно свойство.
Например, классификация свойств “тип фрукта” и “цвет” для набора изображений фруктов. Свойство “тип фрукта” имеет возможные классы: “яблоко”, “груша” и “апельсин”. Свойство “цвет” имеет возможные классы: “зеленый”, “красный”, “желтый” и “оранжевый”. Каждый образец - это изображение фрукта, для обоих свойств выводится метка, и каждая метка - это один из возможных классов соответствующего свойства.
Обратите внимание, что все классификаторы, работающие с задачами многоклассовой классификация с несколькими выходами (также известной как многозадачная классификация), поддерживают задачу классификации с несколькими метками как частный случай. Многозадачная классификация аналогична задаче многовыводной классификации с различными формулировками модели. Для получения дополнительной информации см. документацию по соответствующим моделям.
Ниже приведен пример многоклассовой классификация с несколькими выходами:
>>> from sklearn.datasets import make_classification
>>> from sklearn.multioutput import MultiOutputClassifier
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.utils import shuffle
>>> import numpy as np
>>> X, y1 = make_classification(n_samples=10, n_features=100,
... n_informative=30, n_classes=3,
... random_state=1)
>>> y2 = shuffle(y1, random_state=1)
>>> y3 = shuffle(y1, random_state=2)
>>> Y = np.vstack((y1, y2, y3)).T
>>> n_samples, n_features = X.shape # 10,100
>>> n_outputs = Y.shape[1] # 3
>>> n_classes = 3
>>> forest = RandomForestClassifier(random_state=1)
>>> multi_target_forest = MultiOutputClassifier(forest, n_jobs=2)
>>> multi_target_forest.fit(X, Y).predict(X)
array([[2, 2, 0],
[1, 2, 1],
[2, 1, 0],
[0, 0, 2],
[0, 2, 1],
[0, 0, 2],
[1, 1, 0],
[1, 1, 1],
[0, 0, 2],
[2, 0, 0]])
Предупреждение
В настоящее время ни одна метрика в sklearn.metrics
не поддерживает задачу многоклассовой классификация с несколькими выходами.
1.12.3.1. Формат цели¶
Правильное представление multioutput y
- это плотная матрица формы (n_samples, n_classes)
меток классов. Конкатенация по столбцам 1d переменных multiclass. Пример y
для 3 выборок:
>>> y = np.array([['apple', 'green'], ['orange', 'orange'], ['pear', 'green']])
>>> print(y)
[['apple' 'green']
['orange' 'orange']
['pear' 'green']]
1.12.4. Многозадачная регрессия¶
Многозадачная регрессия (Multioutput regression) предсказывает множество числовых свойств для каждого образца.
Каждое свойство является числовой переменной, а количество свойств, которые нужно предсказать для каждой выборки, больше или равно 2.
Некоторые модели, поддерживающие многозадачную регрессию, работают быстрее, чем просто модели с n_output
.
Например, предсказание скорости и направления ветра в градусах по данным, полученным в определенном месте. Каждая выборка будет представлять собой данные, полученные в одном месте, и для каждой выборки будут выводиться как скорость, так и направление ветра.
1.12.4.1. Формат цели¶
Правильным представлением multioutput y
является плотная матрица формы (n_samples, n_output)
из плавающих чисел.
Конкатенация по столбцам переменных continuous. Пример y
для 3 выборок:
>>> y = np.array([[31.4, 94], [40.5, 109], [25.0, 30]])
>>> print(y)
[[ 31.4 94. ]
[ 40.5 109. ]
[ 25. 30. ]]
1.12.4.2. MultiOutputRegressor¶
Поддержка многозадачной регрессии может быть добавлена к любому регрессору с помощью MultiOutputRegressor
.
Эта стратегия заключается в обучении одного регрессора для каждой цели.
Поскольку каждая цель представлена ровно одним регрессором, можно получить знания о цели, проанализировав соответствующий регрессор.
Поскольку MultiOutputRegressor
обучает один регрессор для каждой цели, он не может воспользоваться корреляциями между целями.
Ниже приведен пример многовыводной регрессии:
>>> from sklearn.datasets import make_regression
>>> from sklearn.multioutput import MultiOutputRegressor
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> X, y = make_regression(n_samples=10, n_targets=3, random_state=1)
>>> MultiOutputRegressor(GradientBoostingRegressor(random_state=0)).fit(X, y).predict(X)
array([[-154.75474165, -147.03498585, -50.03812219],
[ 7.12165031, 5.12914884, -81.46081961],
[-187.8948621 , -100.44373091, 13.88978285],
[-141.62745778, 95.02891072, -191.48204257],
[ 97.03260883, 165.34867495, 139.52003279],
[ 123.92529176, 21.25719016, -7.84253 ],
[-122.25193977, -85.16443186, -107.12274212],
[ -30.170388 , -94.80956739, 12.16979946],
[ 140.72667194, 176.50941682, -17.50447799],
[ 149.37967282, -81.15699552, -5.72850319]])
1.12.4.3. RegressorChain¶
Цепочки регрессоров (см. RegressorChain
) аналогичны ClassifierChain
как способ объединения нескольких регрессий в одну многоцелевую модель, способную использовать корреляции между целями.