1.11. Ансамблевые методы

Цель ансамблевых методов — объединить прогнозы нескольких базовых оценок, построенных с заданным алгоритмом обучения, чтобы улучшить обобщаемость / надежность по сравнению с одной оценкой.

Обычно выделяют два семейства ансамблевых методов:

  • В методах усреднения главный принцип состоит в том, чтобы построить несколько оценщиков независимо, а затем усреднить их прогнозы. В среднем, комбинированная оценка обычно лучше, чем любая из оценок с одной базой, потому что ее дисперсия уменьшается. Примеры: методы упаковки , леса из рандомизированных деревьев ,…
  • Напротив, в методах повышения базовые оценки строятся последовательно, и каждый пытается уменьшить смещение комбинированной оценки. Мотивация состоит в том, чтобы объединить несколько слабых моделей для создания мощного ансамбля.

Примеры: AdaBoost , Gradient Tree Boosting ,…

1.11.1. Мета-оценка пакетов

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

Методы упаковки бывают разных видов, но в основном отличаются друг от друга тем, как они рисуют случайные подмножества обучающего набора:

  • Когда случайные подмножества набора данных рисуются как случайные подмножества выборок, этот алгоритм известен как Вставка [B1999] .
  • Когда образцы отбираются с заменой, этот метод известен как Bagging [B1996] .
  • Когда случайные подмножества набора данных рисуются как случайные подмножества признаков, этот метод известен как случайные подпространства [H1998] .
  • Наконец, когда базовые оценки строятся на подмножествах как выборок, так и функций, тогда метод известен как случайные исправления [LG2012] .

В scikit-learn методы пакетирования предлагаются как унифицированная BaggingClassifier метаоценка (соответственно BaggingRegressor), принимающая в качестве входных данных определяемую пользователем базовую оценку вместе с параметрами, определяющими стратегию рисования случайных подмножеств. В частности, max_samples и max_features контролировать размер подмножеств (с точки зрения образцов и функций), bootstrap а также bootstrap_features контролировать, будут ли образцы и элементы отображаться с заменой или без нее. При использовании подмножества доступных образцов точность обобщения можно оценить с помощью нестандартных образцов путем настройки oob_score=True. В качестве примера приведенный ниже фрагмент иллюстрирует, как создать экземпляр ансамбля KNeighborsClassifier базовых оценок, каждая из которых построена на случайных подмножествах из 50% выборок и 50% функций.

>>> from sklearn.ensemble import BaggingClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> bagging = BaggingClassifier(KNeighborsClassifier(),
...                             max_samples=0.5, max_features=0.5)

Рекомендации

1.11.2. Леса рандомизированных деревьев

Модуль sklearn.ensemble включает в себя два алгоритма усреднения , основанные на рандомизированных деревьев решений : в RandomForest алгоритм и метод Extra-Trees. Оба алгоритма представляют собой методы «возмущать и комбинировать» [B1998], специально разработанные для деревьев. Это означает, что разнообразный набор классификаторов создается путем введения случайности в конструкцию классификатора. Прогноз для ансамбля дается как усредненный прогноз отдельных классификаторов.

Как и другие классификаторы, лесные классификаторы должны быть оснащены двумя массивами: разреженным или плотным массивом X формы (n_samples, n_features), содержащим обучающие образцы, и массивом Y формы (n_samples,), содержащим целевые значения (метки классов) для обучающих образцов:

>>> from sklearn.ensemble import RandomForestClassifier
>>> X = [[0, 0], [1, 1]]
>>> Y = [0, 1]
>>> clf = RandomForestClassifier(n_estimators=10)
>>> clf = clf.fit(X, Y)

Подобно деревьям решений , леса деревьев также распространяются на задачи с несколькими выходами (если Y — это массив формы (n_samples, n_outputs)).

1.11.2.1. Случайные леса

В случайных лесах (см. RandomForestClassifier и RandomForestRegressor классы) каждое дерево в ансамбле строится из выборки, взятой с заменой (то есть выборкой начальной загрузки) из обучающего набора.

Кроме того, при разбиении каждого узла во время построения дерева наилучшее разбиение находится либо по всем входным характеристикам, либо по случайному подмножеству размера max_features. (Подробнее см. В руководстве по настройке параметров ).

Назначение этих двух источников случайности — уменьшить дисперсию оценки леса. В самом деле, отдельные деревья решений обычно демонстрируют высокую дисперсию и имеют тенденцию переоснащаться. Внедренная случайность в лесах дает деревья решений с несколько несвязанными ошибками прогнозирования. Если взять среднее значение этих прогнозов, некоторые ошибки могут быть устранены. Случайные леса уменьшают дисперсию за счет комбинирования разных деревьев, иногда за счет небольшого увеличения смещения. На практике уменьшение дисперсии часто бывает значительным, что дает в целом лучшую модель.

В отличие от исходной публикации [B2001] , реализация scikit-learn объединяет классификаторы путем усреднения их вероятностного прогноза вместо того, чтобы позволить каждому классификатору голосовать за один класс.

1.11.2.2. Чрезвычайно рандомизированные деревья

В чрезвычайно рандомизированных деревьях (см. ExtraTreesClassifier и ExtraTreesRegressor классы) случайность идет на один шаг дальше в способе вычисления разбиений. Как и в случайных лесах, используется случайное подмножество функций-кандидатов, но вместо поиска наиболее отличительных пороговых значений пороги выбираются случайным образом для каждой функции-кандидата, и в качестве правила разделения выбирается лучший из этих случайно сгенерированных пороговых значений. Обычно это позволяет немного уменьшить дисперсию модели за счет немного большего увеличения смещения:

>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.datasets import make_blobs
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.tree import DecisionTreeClassifier

>>> X, y = make_blobs(n_samples=10000, n_features=10, centers=100,
...     random_state=0)

>>> clf = DecisionTreeClassifier(max_depth=None, min_samples_split=2,
...     random_state=0)
>>> scores = cross_val_score(clf, X, y, cv=5)
>>> scores.mean()
0.98...

>>> clf = RandomForestClassifier(n_estimators=10, max_depth=None,
...     min_samples_split=2, random_state=0)
>>> scores = cross_val_score(clf, X, y, cv=5)
>>> scores.mean()
0.999...

>>> clf = ExtraTreesClassifier(n_estimators=10, max_depth=None,
...     min_samples_split=2, random_state=0)
>>> scores = cross_val_score(clf, X, y, cv=5)
>>> scores.mean() > 0.999
True

1.11.2.3. Параметры

Основные параметры, которые необходимо настроить при использовании этих методов, — это n_estimators и max_features. Первое — это количество деревьев в лесу. Чем больше, тем лучше, но также тем дольше потребуется вычисление. Кроме того, обратите внимание, что после критического количества деревьев результаты перестанут улучшаться. Последний — это размер случайных подмножеств функций, которые следует учитывать при разделении узла. Чем ниже, тем больше сокращение дисперсии, но также и больше увеличение смещения. Эмпирические хорошие значения по умолчанию: max_features=None (всегда учитываются все функции, а не случайное подмножество) для задач регрессии и max_features="sqrt" (с использованием случайного подмножества размера sqrt(n_features)) для задач классификации (где n_features— количество функций в данных). Хорошие результаты часто достигаются при настройке max_depth=None в сочетании с min_samples_split=2 (т. е. при полном развитии деревьев). Однако имейте в виду, что эти значения обычно не оптимальны и могут привести к моделям, потребляющим много оперативной памяти. Лучшие значения параметров всегда должны подвергаться перекрестной проверке. Кроме того, обратите внимание, что в случайных лесах образцы начальной загрузки используются по умолчанию ( bootstrap=True), в то время как стратегия по умолчанию для дополнительных деревьев заключается в использовании всего набора данных ( bootstrap=False). При использовании бутстраповой выборки точность обобщения может быть оценена на выборках, оставленных или вне пакета. Это можно включить, установив oob_score=True.

Примечание

Размер модели с параметрами по умолчанию составляет $O( M * N * log (N) )$, где $M$ это количество деревьев и $N$ количество образцов. Для того , чтобы уменьшить размер модели, вы можете изменить эти параметры: min_samples_splitmax_leaf_nodesmax_depthи min_samples_leaf.

1.11.2.4. Распараллеливание

Наконец, этот модуль также имеет параллельное построение деревьев и параллельное вычисление прогнозов с помощью n_jobs параметра. Если n_jobs=k тогда вычисления разделяются на k задания и выполняются на k ядрах машины. Если n_jobs=-1 тогда используются все ядра, имеющиеся на машине. Обратите внимание, что из-за накладных расходов на межпроцессное взаимодействие ускорение может быть нелинейным (т.е. использование k заданий, к сожалению, не будет в k разы быстрее). Тем не менее, значительное ускорение может быть достигнуто при построении большого количества деревьев или когда построение одного дерева требует значительного количества времени (например, для больших наборов данных).

Рекомендации

  • B2001 Брейман, «Случайные леса», Машинное обучение, 45 (1), 5-32, 2001.
  • B1998 Брейман, «Классификаторы дугового разряда», Annals of Statistics 1998.
  • П. Геуртс, Д. Эрнст. И Л. Вехенкель, «Чрезвычайно рандомизированные деревья», Машинное обучение, 63 (1), 3-42, 2006.

1.11.2.5. Оценка важности функции

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

Путем усреднения оценок прогнозирующей способности в течение нескольких рандомизированных деревьев можно уменьшить дисперсию такой оценки и использовать его для отбора признаков. Это известно как среднее уменьшение примесей или MDI. См. [L2014] для получения дополнительной информации о MDI и оценке важности функций с помощью случайных лесов.

Предупреждение

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

В следующем примере показано цветовое представление относительной важности каждого отдельного пикселя для задачи распознавания лиц с использованием ExtraTreesClassifier модели.

На практике эти оценки сохраняются как атрибут, названный feature_importances_ в подобранной модели. Это массив формы (n_features,), значения которого положительны и в сумме равны 1,0. Чем выше значение, тем важнее вклад функции сопоставления в функцию прогнозирования.

Рекомендации

L2014 Г. Луппе, «Понимание случайных лесов: от теории к практике», докторская диссертация, Льежский университет, 2014 г.

1.11.2.6. Вложение полностью случайных деревьев

RandomTreesEmbedding реализует неконтролируемое преобразование данных. Используя лес полностью случайных деревьев, RandomTreesEmbedding кодирует данные по индексам листьев, на которых заканчивается точка данных. Затем этот индекс кодируется одним из K способом, что приводит к высокоразмерному разреженному двоичному кодированию. Это кодирование может быть вычислено очень эффективно и затем может быть использовано в качестве основы для других учебных задач. На размер и разреженность кода можно повлиять, выбрав количество деревьев и максимальную глубину для каждого дерева. Для каждого дерева в ансамбле кодирование содержит одну запись из одного. Размер кодировки — максимум n_estimators * 2 ** max_depth, максимальное количество листьев в лесу.

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

Примеры:

Смотрите также

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

1.11.3. AdaBoost

Модуль sklearn.ensemble включает популярный алгоритм повышения AdaBoost, представленный в 1995 году Фройндом и Шапиром [FS1995] .

Основной принцип AdaBoost состоит в том, чтобы подогнать последовательность слабых учеников (т. e. Моделей, которые лишь немного лучше, чем случайное предположение, например, небольшие деревья решений) на многократно изменяемых версиях данных. Прогнозы от всех из них затем объединяются посредством взвешенного большинства голосов (или суммы) для получения окончательного прогноза. Модификации данных на каждой так называемой итерации повышения состоят в применении весов $w_1, w_2,…, w_N$ к каждой из обучающих выборок. Первоначально все веса установлены на $w_i=1/N$, так что первый шаг просто обучает слабого обучаемого на исходных данных. Для каждой последующей итерации веса выборки индивидуально изменяются, и алгоритм обучения повторно применяется к повторно взвешенным данным. На данном этапе те обучающие примеры, которые были неправильно предсказаны усиленной моделью, созданной на предыдущем шаге, имеют увеличенные веса, тогда как веса уменьшаются для тех, которые были предсказаны правильно. По мере продолжения итераций, примеры, которые трудно предсказать, получают все большее влияние. Таким образом, каждый последующий слабый ученик вынужден концентрироваться на примерах, которые упускают предыдущие в последовательности [HTF] .

AdaBoost можно использовать как для задач классификации, так и для задач регрессии:

1.11.3.1. Использование

В следующем примере показано, как приспособить классификатор AdaBoost к 100 слабым ученикам:

>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.datasets import load_iris
>>> from sklearn.ensemble import AdaBoostClassifier

>>> X, y = load_iris(return_X_y=True)
>>> clf = AdaBoostClassifier(n_estimators=100)
>>> scores = cross_val_score(clf, X, y, cv=5)
>>> scores.mean()
0.9...

Количество слабых учеников контролируется параметром n_estimators. Параметр learning_rate управляет вклад слабых учеников в конечной комбинации. По умолчанию слабые ученики становятся препятствием для принятия решения. С помощью параметра base_estimator можно указать разных слабых учеников . Основными параметрами, которые необходимо настроить для получения хороших результатов, являются n_estimators и сложность базовых оценок (например, ее глубина max_depth или минимально необходимое количество выборок для рассмотрения разделения min_samples_split).

Примеры:

Рекомендации

  • FS1995 Ю. Фройнд и Р. Шапайр, «Теоретико-решающее обобщение онлайн-обучения и приложение для повышения эффективности», 1997.
  • ZZRH2009 Дж. Чжу, Х. Цзоу, С. Россет, Т. Хасти. «Мульти-класс AdaBoost», 2009 г.
  • D1997 Друкер. «Улучшение регрессоров с помощью методов повышения», 1997.
  • HTF Т. Хасти, Р. Тибширани и Дж. Фридман, «Элементы статистического обучения. Ред. 2 ”, Springer, 2009.

1.11.4. Повышение градиента дерева (GBDT)

Gradient Tree Boosting или Gradient Boosted Decision Trees (GBDT) — это обобщение повышения до произвольных дифференцируемых функций потерь. GBDT — это точная и эффективная стандартная процедура, которую можно использовать как для решения задач регрессии, так и для классификации в различных областях, включая ранжирование в веб-поиске и экологию.

Модуль sklearn.ensemble предоставляет методы как для классификации, так и для регрессии с помощью деревьев решений с градиентным усилением.

Примечание

Scikit-learn 0.21 представляет две новые экспериментальные реализации деревьев повышения градиента, а именно HistGradientBoostingClassifier и HistGradientBoostingRegressor, вдохновленные LightGBM (см. [LightGBM] ).
Эти гистограммы на основе оценок могут быть порядка быстрее , чем GradientBoostingClassifier и GradientBoostingRegressor когда число выборок больше , чем десятки тысяч образцов.
У них также есть встроенная поддержка пропущенных значений, что позволяет избежать использования импутера.
Эти средства оценки более подробно описаны ниже в разделе «Повышение градиента на основе гистограммы» .
Следующее руководство фокусируется на GradientBoostingClassifier и GradientBoostingRegressor, что может быть предпочтительнее для небольших размеров выборки, так как разбиение может привести к точкам разделения, которые являются слишком приблизительными в этой настройке.

Использование и параметры GradientBoostingClassifier и GradientBoostingRegressor описаны ниже. Двумя наиболее важными параметрами этих оценщиков являются n_estimatorsи learning_rate.

1.11.4.1. Классификация

GradientBoostingClassifier поддерживает как двоичную, так и мультиклассовую классификацию. В следующем примере показано, как приспособить классификатор повышения градиента к 100 пням принятия решений в качестве слабых учеников:

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier

>>> X, y = make_hastie_10_2(random_state=0)
>>> X_train, X_test = X[:2000], X[2000:]
>>> y_train, y_test = y[:2000], y[2000:]

>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
...     max_depth=1, random_state=0).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.913...

Количество слабых учеников (т. Е. Деревьев регрессии) контролируется параметром n_estimatorsРазмер каждого дерева можно контролировать либо путем установки глубины дерева через, max_depthлибо путем установки количества конечных узлов через max_leaf_nodes. Это learning_rate гиперпараметр в диапазоне (0,0, 1,0), который контролирует переоснащение посредством усадки .

Примечание

Классификация с более чем двумя классами требует индукции n_classes деревьев регрессии на каждой итерации, таким образом, общее количество индуцированных деревьев равно n_classes * n_estimators. Для наборов данных с большим количеством классов мы настоятельно рекомендуем использовать HistGradientBoostingClassifier в качестве альтернативы GradientBoostingClassifier.

1.11.4.2. Регрессия

GradientBoostingRegressor поддерживает ряд различных функций потерь для регрессии, которые можно указать с помощью аргумента loss; функция потерь по умолчанию для регрессии — метод наименьших квадратов ( 'ls').

>>> import numpy as np
>>> from sklearn.metrics import mean_squared_error
>>> from sklearn.datasets import make_friedman1
>>> from sklearn.ensemble import GradientBoostingRegressor

>>> X, y = make_friedman1(n_samples=1200, random_state=0, noise=1.0)
>>> X_train, X_test = X[:200], X[200:]
>>> y_train, y_test = y[:200], y[200:]
>>> est = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1,
...     max_depth=1, random_state=0, loss='ls').fit(X_train, y_train)
>>> mean_squared_error(y_test, est.predict(X_test))
5.00...

На рисунке ниже показаны результаты применения метода GradientBoostingRegressor наименьших квадратов потерь и 500 базовых учащихся к набору данных о диабете ( sklearn.datasets.load_diabetes). На графике слева показан поезд и ошибка теста на каждой итерации. Ошибка поезда на каждой итерации сохраняется в train_score_ атрибуте модели повышения градиента. Ошибка теста на каждой итерации может быть получена с помощью staged_predict метода, который возвращает генератор, который дает прогнозы на каждом этапе. Подобные графики можно использовать для определения оптимального количества деревьев (т. е. n_estimators) Путем ранней остановки.

1.11.4.3. Подбор дополнительных слабых учеников

И GradientBoostingRegressor и GradientBoostingClassifier поддерживают warm_start=True, позволяющая добавлять дополнительные оценщики к уже подогнанной модели.

>>> _ = est.set_params(n_estimators=200, warm_start=True)  # set warm_start and new nr of trees
>>> _ = est.fit(X_train, y_train) # fit additional 100 trees to est
>>> mean_squared_error(y_test, est.predict(X_test))
3.84...

1.11.4.4. Управление размером дерева

Размер учащихся основы дерева регрессии определяет уровень взаимодействия переменных, который может быть зафиксирован моделью повышения градиента. В общем, дерево глубины h может фиксировать взаимодействия порядка h. Существует два способа управления размером отдельных деревьев регрессии.

Если вы укажете, max_depth=h то h будут выращиваться полные двоичные деревья глубины h. Такие деревья будут иметь (не более) 2**h листовые узлы и 2**h — 1 разделенные узлы.

В качестве альтернативы вы можете управлять размером дерева, указав количество конечных узлов с помощью параметра max_leaf_nodes. В этом случае деревья будут расти с использованием поиска по первому наилучшему, при этом узлы с наибольшим улучшением примесей будут расширяться первыми. Дерево с max_leaf_nodes=k имеет k — 1 расщепленные узлов и , таким образом , может моделировать взаимодействия до порядка max_leaf_nodes - 1.

Мы обнаружили, что это max_leaf_nodes=k дает сопоставимые результаты, max_depth=k-1 но значительно быстрее тренируется за счет немного большей ошибки обучения. Параметр max_leaf_nodes соответствует переменной J в главе о повышении градиента в [F2001] и связан с параметром interaction.depth в пакете R gbm, где max_leaf_nodes == interaction.depth + 1.

1.11.4.5. Математическая постановка

Сначала мы представляем GBRT для регрессии, а затем детализируем случай классификации.

1.11.4.5.1. Регрессия

Регрессоры GBRT — это аддитивные модели, предсказание которых $y_i$ для данного входа $x_i$ имеет следующий вид:
$$\hat{y_i} = F_M(x_i) = \sum_{m=1}^{M} h_m(x_i)$$

где $h_m$ являются оценщиками, называемыми слабыми учениками в контексте повышения. Gradient Tree Boosting использует регрессоры дерева решений фиксированного размера в качестве слабых учеников. Константа M соответствует n_estimators параметру.

Подобно другим алгоритмам повышения, GBRT построен жадным образом:
$$F_m(x) = F_{m-1}(x) + h_m(x),$$

где только что добавленное дерево $h_m$ приспособлен для минимизации суммы потерь $L_m$, учитывая предыдущий ансамбль $F_{m−1}$:
$$h_m = \arg\min_{h} L_m = \arg\min_{h} \sum_{i=1}^{n} l(y_i, F_{m-1}(x_i) + h(x_i)),$$

где $l(y_i, F(x_i))$ определяется loss параметром, подробно описанным в следующем разделе.

По умолчанию исходная модель $F_0$ выбирается как константа, которая минимизирует потери: для потерь методом наименьших квадратов это эмпирическое среднее целевых значений. Исходную модель также можно указать с помощью init аргумента.

Используя приближение Тейлора первого порядка, значение l можно аппроксимировать следующим образом:
$$l(y_i, F_{m-1}(x_i) + h_m(x_i)) \approx l(y_i, F_{m-1}(x_i)) + h_m(x_i) \left[ \frac{\partial l(y_i, F(x_i))}{\partial F(x_i)} \right]{F=F{m — 1}}.$$

Примечание

Вкратце, приближение Тейлора первого порядка говорит, что $l(z) \approx l(a) + (z — a) \frac{\partial l(a)}{\partial a}$. Здесь, $z$ соответствует $F_{m — 1}(x_i) + h_m(x_i)$, а также $a$ соответствует  $F_{m-1}(x_i)$

Количество $\left[ \frac{\partial l(y_i, F(x_i))}{\partial F(x_i)}\right]{F=F{m — 1}}$ — производная потерь по второму параметру, оцениваемая при $F_{m-1}(x)$. Легко вычислить для любого заданного $F_{m — 1}(x_i)$ в закрытом виде, так как потеря дифференцируема. Обозначим его через $g_i$.

Убрав постоянные члены, получим:
$$h_m \approx \arg\min_{h} \sum_{i=1}^{n} h(x_i) g_i$$

Это сводится к минимуму, если $h(x_i)$ приспособлен для прогнозирования значения, пропорционального отрицательному градиенту $−g_i$. Следовательно, на каждой итерации оценщик $h_m$ приспособлен для прогнозирования отрицательных градиентов образцов . Градиенты обновляются на каждой итерации. Это можно рассматривать как своего рода градиентный спуск в функциональном пространстве.

Примечание

Для некоторых потерь, например, наименьшего абсолютного отклонения (LAD), когда градиенты равны $\pm 1$, значения, предсказанные подобранной $h_m$ недостаточно точны: дерево может выводить только целые числа. В результате значения листьев дерева $h_m$ изменяются после того, как дерево подогнано, так что значения листьев минимизируют потери $L_m$. Обновление зависит от потерь: для потери LAD значение листа обновляется до медианы выборок в этом листе.

1.11.4.5.2. Классификация

Повышение градиента для классификации очень похоже на случай регрессии. Однако сумма деревьев $F_M(x_i) = \sum_m h_m(x_i)$ не однороден по отношению к предсказанию: он не может быть классом, поскольку деревья предсказывают непрерывные значения.

Отображение значения $F_M(x_i)$ классу или вероятность зависит от потерь. Для отклонения (или логарифма потерь) вероятность того, чтоxi принадлежит к положительному классу, моделируется как $p(y_i = 1 | x_i) = \sigma(F_M(x_i))$ где σ сигмовидная функция.

Для мультиклассовой классификации K деревьев (для K классов) строятся на каждом из $M$ итераций. Вероятность того, чтоxi принадлежит классу $k$ моделируется как softmax $F_{M,k}(x_i)$ значения.

Обратите внимание, что даже для задачи классификации $h_m$ субоценка по-прежнему является регрессором, а не классификатором. Это связано с тем, что субоценщики обучены предсказывать (отрицательные) градиенты , которые всегда являются непрерывными величинами.

1.11.4.6. Функции потерь

Поддерживаются следующие функции потерь, которые можно указать с помощью параметра loss:

  • Регресс
    • Метод наименьших квадратов ( ‘ls’): естественный выбор для регрессии из-за его превосходных вычислительных свойств. Исходная модель представлена ​​средним целевым значением.
    • Наименьшее абсолютное отклонение ( 'lad'): надежная функция потерь для регрессии. Исходная модель задается медианой целевых значений.
    • Huber ( 'huber'): еще одна надежная функция потерь, которая сочетает в себе наименьшие квадраты и наименьшее абсолютное отклонение; используйте alphaдля управления чувствительностью к выбросам (подробнее см. [F2001] ).
    • Quantile ( 'quantile'): функция потерь для квантильной регрессии. Используйте 0 < alpha < 1 для указания квантиля. Эту функцию потерь можно использовать для создания интервалов прогнозирования (см. Интервалы прогнозирования для регрессии с повышением градиента).
  • Классификация
    • Биномиальное отклонение ('deviance'): функция потерь с отрицательным биномиальным логарифмическим правдоподобием для двоичной классификации (предоставляет оценки вероятности). Исходная модель дается логарифмическим отношением шансов.
    • Полиномиальное отклонение ('deviance'): отрицательная полиномиальная функция потерь логарифма правдоподобия для мультиклассовой классификации с n_classes взаимоисключающими классами. Он предоставляет оценки вероятности. Исходная модель задается априорной вероятностью каждого класса. На каждой итерации n_classes необходимо строить деревья регрессии, что делает GBRT довольно неэффективным для наборов данных с большим количеством классов.
    • Exponential loss ('exponential'): та же функция потерь, что и AdaBoostClassifier. Менее устойчивые к ошибочно маркированным примерам, чем 'deviance'; может использоваться только для двоичной классификации.

1.11.4.7. Усадка через скорость обучения

[F2001] предложил простую стратегию регуляризации, которая масштабирует вклад каждого слабого ученика с постоянным коэффициентом.ν:
$$F_m(x) = F_{m-1}(x) + \nu h_m(x)$$

Параметр νтакже называется скоростью обучения, потому что он масштабирует длину шага процедуры градиентного спуска; его можно установить с помощью learning_rate параметра.

Параметр learning_rate сильно взаимодействует с параметром n_estimators — количеством подходящих слабых учеников. Меньшие значения learning_rate требуют большего количества слабых учеников для поддержания постоянной ошибки обучения. Эмпирические данные свидетельствуют о том, что небольшие значения указывают на learning_rate лучшую ошибку теста. [HTF] рекомендует установить скорость обучения на небольшую константу (например, .learning_rate <= 0.1) и выбрать n_estimators раннюю остановку. Более подробное обсуждение взаимодействия learning_rate и n_estimators см. В [R2007] 

1.11.4.8. Субдискретизация

[F1999] предложил стохастическое усиление градиента, которое сочетает в себе повышение градиента с усреднением начальной загрузки (бэггинг). На каждой итерации базовый классификатор обучается на subsample части доступных обучающих данных. Подвыборка рисуется без замены. Типичное значение subsample — 0,5.

На рисунке ниже показано влияние усадки и субдискретизации на точность соответствия модели. Мы ясно видим, что усадка превосходит усадку без усадки. Подвыборка с усадкой может еще больше повысить точность модели. С другой стороны, субдискретизация без усадки работает плохо.

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

Примечание

Использование небольшого max_features значения может значительно сократить время выполнения.

Стохастическое повышение градиента позволяет вычислять нестандартные оценки отклонения теста путем вычисления улучшения отклонения на примерах, которые не включены в выборку начальной загрузки (т. е. В нестандартных примерах). Улучшения хранятся в атрибуте oob_improvement_oob_improvement_[i]содержит улучшение с точки зрения потерь на выборках OOB, если вы добавите i-й этап к текущим прогнозам. Оценки вне пакета можно использовать для выбора модели, например, для определения оптимального количества итераций. Оценки OOB обычно очень пессимистичны, поэтому мы рекомендуем вместо этого использовать перекрестную проверку и использовать OOB только в том случае, если перекрестная проверка занимает слишком много времени.

1.11.4.9. Интерпретация с важностью характеристик

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

Часто функции не в равной степени способствуют предсказанию целевой реакции; во многих ситуациях большинство функций фактически не имеют значения. При интерпретации модели первым вопросом обычно является: каковы эти важные особенности и как они влияют на прогнозирование целевого ответа?

Отдельные деревья решений по сути выполняют выбор функций, выбирая соответствующие точки разделения. Эта информация может использоваться для измерения важности каждой функции; основная идея такова: чем чаще функция используется в точках разделения дерева, тем важнее эта функция. Это понятие важности может быть распространено на ансамбли деревьев решений путем простого усреднения важности характеристик каждого дерева на основе примесей ( более подробную информацию см. В разделе Оценка важности характеристик).

Оценки важности функций подходящей модели повышения градиента можно получить через feature_importances_ свойство:

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier

>>> X, y = make_hastie_10_2(random_state=0)
>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
...     max_depth=1, random_state=0).fit(X, y)
>>> clf.feature_importances_
array([0.10..., 0.10..., 0.11..., ...

Обратите внимание, что это вычисление важности характеристик основано на энтропии и отличается от того, sklearn.inspection.permutation_importance которое основано на перестановке признаков.

1.11.5. Повышение градиента на основе гистограммы

Scikit-learn 0.21 представил две новые экспериментальные реализации деревьев повышения градиента, а именно HistGradientBoostingClassifier и HistGradientBoostingRegressor, вдохновленные LightGBM (см. [LightGBM] ).

Эти гистограммы на основе оценок могут быть порядка быстрее , чем GradientBoostingClassifier и GradientBoostingRegressor когда число выборок больше , чем десятки тысяч образцов.

У них также есть встроенная поддержка пропущенных значений, что позволяет избежать использования импутера.

Эти быстрые оценщики сначала разделяют входные выборки X на целочисленные ячейки (обычно 256 ячеек), что значительно сокращает количество точек разделения, которые необходимо учитывать, и позволяет алгоритму использовать целочисленные структуры данных (гистограммы) вместо того, чтобы полагаться на отсортированные непрерывные значения. при строительстве деревьев. API этих оценщиков немного отличается, а некоторые функции из GradientBoostingClassifier и GradientBoostingRegressor еще не поддерживаются, например, некоторые функции потерь.

Эти оценщики все еще являются экспериментальными : их прогнозы и их API могут измениться без какого-либо цикла устаревания. Чтобы использовать их, вам необходимо явно импортировать enable_hist_gradient_boosting:

>>> # explicitly require this experimental feature
>>> from sklearn.experimental import enable_hist_gradient_boosting  # noqa
>>> # now you can import normally from ensemble
>>> from sklearn.ensemble import HistGradientBoostingClassifier

1.11.5.1. Использование

Большинство параметров не изменились с GradientBoostingClassifier и GradientBoostingRegressor. Единственным исключением является max_iter параметр, который заменяет n_estimators и контролирует количество итераций процесса повышения:

>>> from sklearn.experimental import enable_hist_gradient_boosting
>>> from sklearn.ensemble import HistGradientBoostingClassifier
>>> from sklearn.datasets import make_hastie_10_2

>>> X, y = make_hastie_10_2(random_state=0)
>>> X_train, X_test = X[:2000], X[2000:]
>>> y_train, y_test = y[:2000], y[2000:]

>>> clf = HistGradientBoostingClassifier(max_iter=100).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.8965

Доступные потери для регрессии: «наименьшие_квадраты», «наименьшее_абсолютное_отклонение», которое менее чувствительно к выбросам, и «Пуассон», которое хорошо подходит для моделирования подсчетов и частот. Для классификации «binary_crossentropy» используется для двоичной классификации, а «category_crossentropy» — для мультиклассовой классификации. По умолчанию потери «авто» и выбрать соответствующую потерю в зависимости от у передается fit.

Размер деревьев можно контролировать через max_leaf_nodesmax_depth и min_samples_leaf параметров.

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

Параметр l2_regularization регуляризатором на функции потерь и соответствует $\lambda$ в уравнении (2) [XGBoost] .

Обратите внимание, что ранняя остановка включена по умолчанию, если количество выборок превышает 10 000 . Ранняя остановка поведение контролируется с помощью early-stoppingscoringvalidation_fractionn_iter_no_change и tol параметров. Можно досрочно прекратить использование произвольного счетчика , либо просто проигрыш при обучении или проверке. Обратите внимание, что по техническим причинам использование счетчика очков значительно медленнее, чем использование проигрыша. По умолчанию ранняя остановка выполняется, если в обучающем наборе есть не менее 10 000 выборок, с использованием потери проверки.

1.11.5.2. Поддержка отсутствующих значений

HistGradientBoostingClassifier и HistGradientBoostingRegressor имеют встроенную поддержку пропущенных значений (NaN).

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

>>> from sklearn.experimental import enable_hist_gradient_boosting  # noqa
>>> from sklearn.ensemble import HistGradientBoostingClassifier
>>> import numpy as np

>>> X = np.array([0, 1, 2, np.nan]).reshape(-1, 1)
>>> y = [0, 0, 1, 1]

>>> gbdt = HistGradientBoostingClassifier(min_samples_leaf=1).fit(X, y)
>>> gbdt.predict(X)
array([0, 0, 1, 1])

Когда шаблон отсутствия является прогнозируемым, разбиение может выполняться на основании того, отсутствует значение признака или нет:

>>> X = np.array([0, np.nan, 1, 2, np.nan]).reshape(-1, 1)
>>> y = [0, 1, 0, 0, 1]
>>> gbdt = HistGradientBoostingClassifier(min_samples_leaf=1,
...                                       max_depth=2,
...                                       learning_rate=1,
...                                       max_iter=1).fit(X, y)
>>> gbdt.predict(X)
array([0, 1, 0, 0, 1])

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

1.11.5.3. Образец опоры для груза

HistGradientBoostingClassifier и HistGradientBoostingRegressor образцы поддерживающих веса во время fit .

В следующем игрушечном примере показано, как модель игнорирует образцы с нулевым весом:

>>> X = [[1, 0],
...      [1, 0],
...      [1, 0],
...      [0, 1]]
>>> y = [0, 0, 1, 0]
>>> # ignore the first 2 training samples by setting their weight to 0
>>> sample_weight = [0, 0, 1, 1]
>>> gb = HistGradientBoostingClassifier(min_samples_leaf=1)
>>> gb.fit(X, y, sample_weight=sample_weight)
HistGradientBoostingClassifier(...)
>>> gb.predict([[1, 0]])
array([1])
>>> gb.predict_proba([[1, 0]])[0, 1]
0.99...

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

Детали реализации: учет весов выборки означает умножение градиентов (и гессиан) на веса выборки. Обратите внимание, что этап бинирования (в частности, вычисление квантилей) не принимает во внимание веса.

1.11.5.4. Поддержка категориальных функций

HistGradientBoostingClassifier и HistGradientBoostingRegressor имеют встроенную поддержку категориальных функций: они могут рассматривать разбиение неупорядоченных категориальных данных.

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

Чтобы включить поддержку категорий, categorical_features параметру можно передать логическую маску , указывающую, какая функция является категориальной. В дальнейшем первый признак будет рассматриваться как категориальный, а второй признак — как числовой:

>>> gbdt = HistGradientBoostingClassifier(categorical_features=[True, False])

Точно так же можно передать список целых чисел, указывающих индексы категориальных признаков:

>>> gbdt = HistGradientBoostingClassifier(categorical_features=[0])

Количество элементов каждой категориальной функции должно быть меньше max_bins параметра, и ожидается, что каждая категориальная функция будет закодирована [0, max_bins — 1]. С этой целью может быть полезно предварительно обработать данные c OrdinalEncoder, как это сделано в разделе « Поддержка категориальных функций в повышении градиента»

Если во время обучения есть пропущенные значения, пропущенные значения будут рассматриваться как правильная категория. Если во время обучения отсутствуют пропущенные значения, то во время прогнозирования отсутствующие значения отображаются на дочерний узел, который имеет наибольшее количество выборок (как и для непрерывных функций). При прогнозировании категории, которые не были просмотрены во время соответствия, будут рассматриваться как пропущенные значения.

Разделение нахождения с категориальными признаками : канонический способ рассмотрения категориальных разбиений в дереве состоит в том, чтобы рассмотреть все $2^{K — 1} — 1$ перегородки, где $K$ количество категорий. Это может быстро стать недопустимым, если $K$ большой. К счастью, поскольку деревья повышения градиента всегда являются деревьями регрессии (даже для задач классификации), существует более быстрая стратегия, которая может давать эквивалентные разбиения. Во-первых, категории функции сортируются в соответствии с дисперсией цели для каждой категории k. После того, как категории отсортированы, можно рассматривать непрерывные разбиения , то есть рассматривать категории, как если бы они были упорядоченными непрерывными значениями (см. Fisher [Fisher1958] для формального доказательства). В результате только $K−1$ расщепления необходимо рассматривать вместо $2^{K — 1} — 1$. Начальная сортировка — это $\mathcal{O}(K \log(K))$ операция, приводящая к общей сложности $\mathcal{O}(K \log(K) + K)$, вместо $\mathcal{O}(2^K)$.

1.11.5.5. Монотонные ограничения

В зависимости от решаемой проблемы у вас могут быть предварительные знания, указывающие на то, что данная функция в целом должна иметь положительный (или отрицательный) эффект на целевое значение. Например, при прочих равных условиях более высокий кредитный рейтинг должен увеличить вероятность получения одобрения на получение ссуды. Монотонные ограничения позволяют вам включить такие предварительные знания в модель.

Положительное монотонное ограничение — это ограничение вида:

$x_1 \leq x_1′ \implies F(x_1, x_2) \leq F(x_1′, x_2)$, где $F$ является предсказателем с двумя функциями.

Точно так же отрицательное монотонное ограничение имеет вид:
$$x_1 \leq x_1′ \implies F(x_1, x_2) \geq F(x_1′, x_2)$$

Обратите внимание, что монотонные ограничения только ограничивают вывод «при прочих равных». В самом деле, следующее отношение не поддерживается положительным ограничением: $x_1 \leq x_1′ \implies F(x_1, x_2) \leq F(x_1′, x_2′)$.

Вы можете указать монотонное ограничение для каждого объекта с помощью monotonic_cst параметра. Для каждой функции значение 0 указывает на отсутствие ограничений, в то время как -1 и 1 указывают на отрицательное и положительное ограничение соответственно:

>>> from sklearn.experimental import enable_hist_gradient_boosting  # noqa
>>> from sklearn.ensemble import HistGradientBoostingRegressor

... # positive, negative, and no constraint on the 3 features
>>> gbdt = HistGradientBoostingRegressor(monotonic_cst=[1, -1, 0])

В контексте бинарной классификации наложение монотонного ограничения означает, что функция должна иметь положительное / отрицательное влияние на вероятность принадлежности к положительному классу. Монотонные ограничения не поддерживаются для мультиклассового контекста.

Примечание

Поскольку категории являются неупорядоченными величинами, невозможно наложить монотонные ограничения на категориальные признаки.

1.11.5.6. Низкоуровневый параллелизм

HistGradientBoostingClassifier и HistGradientBoostingRegressor имеют реализации, использующие OpenMP для распараллеливания через Cython. Дополнительные сведения о том, как контролировать количество потоков, см. В наших заметках о параллелизме .

Распараллеливаются следующие части:

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

1.11.5.7. Почему это быстрее

Узким местом процедуры повышения градиента является построение деревьев решений. Построение традиционного дерева решений (как и в других GBDT GradientBoostingClassifier и GradientBoostingRegressor) требует сортировки выборок в каждом узле (для каждой функции). Сортировка необходима, чтобы можно было эффективно вычислить потенциальный выигрыш точки разделения. Таким образом, разделение одного узла имеет сложность $\mathcal{O}(n_\text{features} \times n \log(n))$ где $n$ — количество выборок в узле.

HistGradientBoostingClassifier и HistGradientBoostingRegressor, напротив, не требуют сортировки значений функций и вместо этого используют структуру данных, называемую гистограммой, где выборки неявно упорядочены. Построение гистограммы имеет $\mathcal{O}(n)$ сложность, поэтому процедура разделения узла имеет $\mathcal{O}(n_\text{features} \times n)$ сложность, намного меньше, чем у предыдущего. Кроме того, вместо того, чтобы рассматриватьnточки разделения, здесь мы рассматриваем только max_bins точки разделения, которые намного меньше.

Для построения гистограмм входные данные X должны быть разделены на целочисленные ячейки. Эта процедура объединения требует сортировки значений функций, но это происходит только один раз в самом начале процесса повышения (не на каждом узле, как в GradientBoostingClassifier и GradientBoostingRegressor).

Наконец, многие части реализации HistGradientBoostingClassifier и HistGradientBoostingRegressor распараллеливаются.

Рекомендации

1.11.6. Классификатор голосования

Идея VotingClassifier состоит в том, чтобы объединить концептуально разные классификаторы машинного обучения и использовать большинство голосов или средние предсказанные вероятности (мягкое голосование) для прогнозирования меток классов. Такой классификатор может быть полезен для набора одинаково хорошо работающих моделей, чтобы уравновесить их индивидуальные недостатки.

1.11.6.1. Ярлыки класса большинства (большинство / жесткое голосование)

При голосовании большинством прогнозируемая метка класса для конкретной выборки является меткой класса, которая представляет большинство (режим) меток класса, предсказываемых каждым отдельным классификатором.

Например, если прогноз для данной выборки

  • классификатор 1 -> класс 1
  • классификатор 2 -> класс 1
  • классификатор 3 -> класс 2

Классификатор VotingClassifier (с voting='hard') классифицирует образец как «класс 1» на основе метки класса большинства.

В случае совпадения VotingClassifier класс будет выбран в соответствии с возрастающим порядком сортировки. Например, в следующем сценарии

  • классификатор 1 -> класс 2
  • классификатор 2 -> класс 1

метка класса 1 будет присвоена образцу.

1.11.6.2. Использование

В следующем примере показано, как соответствовать классификатору правил большинства:

>>> from sklearn import datasets
>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.naive_bayes import GaussianNB
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import VotingClassifier

>>> iris = datasets.load_iris()
>>> X, y = iris.data[:, 1:3], iris.target

>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(n_estimators=50, random_state=1)
>>> clf3 = GaussianNB()

>>> eclf = VotingClassifier(
...     estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)],
...     voting='hard')

>>> for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):
...     scores = cross_val_score(clf, X, y, scoring='accuracy', cv=5)
...     print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
Accuracy: 0.95 (+/- 0.04) [Logistic Regression]
Accuracy: 0.94 (+/- 0.04) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [naive Bayes]
Accuracy: 0.95 (+/- 0.04) [Ensemble]

1.11.6.3. Средневзвешенные вероятности (мягкое голосование)

В отличие от голосования большинством (жесткое голосование) мягкое голосование возвращает метку класса как argmax суммы предсказанных вероятностей.

Каждому классификатору можно присвоить определенные веса с помощью weights параметра. Когда веса предоставлены, прогнозируемые вероятности классов для каждого классификатора собираются, умножаются на вес классификатора и усредняются. Окончательная метка класса затем получается из метки класса с наивысшей средней вероятностью.

Чтобы проиллюстрировать это на простом примере, предположим, что у нас есть 3 классификатора и 3 задачи классификации, в которых мы присваиваем всем классификаторам одинаковые веса: w1 = 1, w2 = 1, w3 = 1.

Затем средневзвешенные вероятности для выборки будут рассчитаны следующим образом:

классификатор1 класс2 класс3 класс
классификатор 1w1 * 0,2w1 * 0,5w1 * 0,3
классификатор 2w2 * 0,6w2 * 0,3w2 * 0,1
классификатор 3w3 * 0,3w3 * 0,4w3 * 0,3
средневзвешенное0,370,40,23

Здесь метка предсказанного класса равна 2, так как она имеет самую высокую среднюю вероятность.

В следующем примере показано, как области решений могут измениться при использовании программного обеспечения VotingClassifier на основе линейной машины опорных векторов, дерева решений и классификатора K-ближайших соседей:

>>> from sklearn import datasets
>>> from sklearn.tree import DecisionTreeClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> from sklearn.svm import SVC
>>> from itertools import product
>>> from sklearn.ensemble import VotingClassifier

>>> # Loading some example data
>>> iris = datasets.load_iris()
>>> X = iris.data[:, [0, 2]]
>>> y = iris.target

>>> # Training classifiers
>>> clf1 = DecisionTreeClassifier(max_depth=4)
>>> clf2 = KNeighborsClassifier(n_neighbors=7)
>>> clf3 = SVC(kernel='rbf', probability=True)
>>> eclf = VotingClassifier(estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)],
...                         voting='soft', weights=[2, 1, 2])

>>> clf1 = clf1.fit(X, y)
>>> clf2 = clf2.fit(X, y)
>>> clf3 = clf3.fit(X, y)
>>> eclf = eclf.fit(X, y)

1.11.6.4. Использование VotingClassifierс GridSearchCV

VotingClassifier Также могут быть использованы вместе с GridSearchCV для того, чтобы настроиться на гиперпараметры индивидуальных оценок:

>>> from sklearn.model_selection import GridSearchCV
>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(random_state=1)
>>> clf3 = GaussianNB()
>>> eclf = VotingClassifier(
...     estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)],
...     voting='soft'
... )

>>> params = {'lr__C': [1.0, 100.0], 'rf__n_estimators': [20, 200]}

>>> grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5)
>>> grid = grid.fit(iris.data, iris.target)

1.11.6.5. Использование

Чтобы предсказать метки классов на основе предсказанных вероятностей классов (оценки scikit-learn в VotingClassifier должны поддерживать predict_proba метод):

>>> eclf = VotingClassifier(
...     estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)],
...     voting='soft'
... )

По желанию можно указать веса для отдельных классификаторов:

>>> eclf = VotingClassifier(
...     estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)],
...     voting='soft', weights=[2,5,1]
... )

1.11.7. Регрессор голосования

Идея VotingRegressor состоит в том, чтобы объединить концептуально разные регрессоры машинного обучения и вернуть средние предсказанные значения. Такой регрессор может быть полезен для набора одинаково хорошо работающих моделей, чтобы уравновесить их индивидуальные недостатки.

1.11.7.1. Использование

В следующем примере показано, как подогнать VotingRegressor:

>>> from sklearn.datasets import load_diabetes
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> from sklearn.ensemble import RandomForestRegressor
>>> from sklearn.linear_model import LinearRegression
>>> from sklearn.ensemble import VotingRegressor

>>> # Loading some example data
>>> X, y = load_diabetes(return_X_y=True)

>>> # Training classifiers
>>> reg1 = GradientBoostingRegressor(random_state=1)
>>> reg2 = RandomForestRegressor(random_state=1)
>>> reg3 = LinearRegression()
>>> ereg = VotingRegressor(estimators=[('gb', reg1), ('rf', reg2), ('lr', reg3)])
>>> ereg = ereg.fit(X, y)

1.11.8. Сложное обобщение

Суммарное обобщение — это метод комбинирования оценок для уменьшения их ошибок [W1992] [HTF] . Точнее, прогнозы каждого отдельного оценщика складываются вместе и используются в качестве входных данных для окончательного оценщика для вычисления прогноза. Этот окончательный оценщик обучается посредством перекрестной проверки.

Они StackingClassifier и StackingRegressor предоставляют такие стратегии, которые можно применять к задачам классификации и регрессии.

В estimators параметре соответствует списку оценок, которые сложены вместе параллельно на входных данных. Он должен быть представлен в виде списка имен и оценщиков:

>>> from sklearn.linear_model import RidgeCV, LassoCV
>>> from sklearn.neighbors import KNeighborsRegressor
>>> estimators = [('ridge', RidgeCV()),
...               ('lasso', LassoCV(random_state=42)),
...               ('knr', KNeighborsRegressor(n_neighbors=20,
...                                           metric='euclidean'))]

В качестве входных данных final_estimator будет использоваться прогноз estimators. При использовании StackingClassifier или StackingRegressor, соответственно, это должен быть классификатор или регрессор :

>>> from sklearn.ensemble import GradientBoostingRegressor
>>> from sklearn.ensemble import StackingRegressor
>>> final_estimator = GradientBoostingRegressor(
...     n_estimators=25, subsample=0.5, min_samples_leaf=25, max_features=1,
...     random_state=42)
>>> reg = StackingRegressor(
...     estimators=estimators,
...     final_estimator=final_estimator)

Чтобы обучить estimatorsи final_estimatorfit метод должен быть вызван для обучающих данных:

>>> from sklearn.datasets import load_diabetes
>>> X, y = load_diabetes(return_X_y=True)
>>> from sklearn.model_selection import train_test_split
>>> X_train, X_test, y_train, y_test = train_test_split(X, y,
...                                                     random_state=42)
>>> reg.fit(X_train, y_train)
StackingRegressor(...)

Во время обучения estimators подбираются все данные обучения X_train. Они будут использоваться при вызове predict или predict_proba. Чтобы обобщить и избежать чрезмерной подгонки, final_estimator тренируется на sklearn.model_selection.cross_val_predict внешних сэмплах с внутренним использованием .

Для получения StackingClassifier, отметим , что на выходе из estimators контролируется параметром stack_method и называется каждой оценки. Этот параметр является либо строкой, будучи имена методов оценщика, или 'auto' который будет автоматически идентифицировать доступный метод в зависимости от доступности, испытанный в порядке предпочтения: predict_probadecision_function и predict.

StackingRegressor и StackingClassifier может использоваться как любой другой регрессора или классификатором, обнажая predictpredict_proba и decision_function методы, например:

>>> y_pred = reg.predict(X_test)
>>> from sklearn.metrics import r2_score
>>> print('R2 score: {:.2f}'.format(r2_score(y_test, y_pred)))
R2 score: 0.53

Обратите внимание, что также можно получить вывод стека, estimatorsиспользуя transform метод:

>>> reg.transform(X_test[:5])
array([[142..., 138..., 146...],
       [179..., 182..., 151...],
       [139..., 132..., 158...],
       [286..., 292..., 225...],
       [126..., 124..., 164...]])

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

Примечание

Ведь StackingClassifier при использовании stack_method_='predict_proba' первый столбец опускается, когда проблема связана с двоичной классификацией. Действительно, оба столбца вероятности, предсказанные каждым оценщиком, идеально коллинеарны.

Примечание

Несколько слоев укладки может быть достигнуто путем присвоения final_estimator к StackingClassifier или StackingRegressor:

>>> final_layer_rfr = RandomForestRegressor(
...     n_estimators=10, max_features=1, max_leaf_nodes=5,random_state=42)
>>> final_layer_gbr = GradientBoostingRegressor(
...     n_estimators=10, max_features=1, max_leaf_nodes=5,random_state=42)
>>> final_layer = StackingRegressor(
...     estimators=[('rf', final_layer_rfr),
...                 ('gbrt', final_layer_gbr)],
...     final_estimator=RidgeCV()
...     )
>>> multi_layer_regressor = StackingRegressor(
...     estimators=[('ridge', RidgeCV()),
...                 ('lasso', LassoCV(random_state=42)),
...                 ('knr', KNeighborsRegressor(n_neighbors=20,
...                                             metric='euclidean'))],
...     final_estimator=final_layer
... )
>>> multi_layer_regressor.fit(X_train, y_train)
StackingRegressor(...)
>>> print('R2 score: {:.2f}'
...       .format(multi_layer_regressor.score(X_test, y_test)))
R2 score: 0.53

Рекомендации

  • W1992 Вольперт, Дэвид Х. «Сложное обобщение». Нейронные сети 5.2 (1992): 241-259.