Теперь предположим, что вы выбрали наилучшую возможную модель для конкретной задачи и работаете над дальнейшим повышением ее точности. В этом случае вам нужно будет применить более продвинутые методы машинного обучения, которые в совокупности называются ансамблевым обучением.
Набор — это совокупность элементов, которые вместе составляют единое целое. Известным примером является музыкальный ансамбль, в котором звуки нескольких музыкальных инструментов смешиваются для создания красивой гармонии, или архитектурные ансамбли, представляющие собой набор зданий, спроектированных как единое целое. В ансамблях гармоничный (целостный) результат важнее, чем исполнение какой-либо отдельной части.
Теорема Кондорсе о жюри (1784 г.) в некотором смысле касается множества. Он гласит, что если каждый член жюри выносит независимое суждение и вероятность правильного решения каждого присяжного больше 0,5, то вероятность правильного решения всего жюри возрастает с увеличением общего числа присяжных и стремится к а. С другой стороны, если вероятность оказаться правым для каждого присяжного меньше 0,5, то вероятность правильного решения жюри в целом уменьшается с увеличением числа присяжных и стремится к нулю.
Рассмотрим еще один пример множеств: наблюдение, известное как «Мудрость толпы». В 1906 году Фрэнсис Гальтон посетил сельскую ярмарку в Плимуте, где увидел соревнование, проводившееся среди фермеров. 800 участников пытались оценить вес убитого быка. Фактический вес быка составлял 1198 фунтов. Хотя ни один из фермеров не мог угадать точный вес животного, средний их прогноз составил 1197 фунтов.
Аналогичная идея уменьшения ошибок была принята в области машинного обучения.
Грунтовка (упаковка и бутстрэппинг)
Бэггинг (также известный как агрегация Bootstrap) — один из самых ранних и основных методов ансамбля. Он был предложен Лео Брейманом в 1994 году. Бэггинг основан на статистическом методе начальной загрузки, который позволяет оценивать многие статистические данные сложных моделей.
Метод бутстрапа работает следующим образом. Рассмотрим выборку X размера N. Новую выборку можно составить из исходной выборки, взяв из нее N элементов случайным и равномерным образом с заменой. Другими словами, мы выбираем случайный элемент из исходной выборки размера N и делаем это N раз. Вероятность выбора всех элементов одинакова, поэтому каждый элемент выбирается с равной вероятностью 1/N.
Допустим, мы вытаскиваем шарики из мешка по одному. На каждом этапе выбранный шар кладется обратно в мешок, так что следующий выбор производится равновероятным образом, т. е. из того же числа шаров N. Заметим, что, поскольку шары кладутся обратно, может быть дубликатов в новом образце. Назовем этот новый образец X1.
Повторив эту процедуру M раз, мы создадим M бутстрап-выборок X1, …, XM. В итоге мы имеем достаточное количество выборок и можем вычислять различную статистику из исходного распределения.
В нашем примере мы будем использовать знакомый набор данных telecom_churn. Ранее, когда мы обсуждали важность функций, мы увидели, что одной из наиболее важных функций в этом наборе данных является количество обращений в службу поддержки клиентов. Давайте визуализируем данные и посмотрим на распределение этой функции.
импорт панда туз пд | |
из matplotlib импорт сюжет туз пожалуйста | |
пожалуйста.стиль.изношенный('ggplot') | |
пожалуйста.rcParams['figure.figsize'] = 10, 6 | |
импорт рожденный морем туз сонс | |
%matplotlib в соответствии | |
телеком_данные = пд.read_csv('../../data/telecom_churn.csv') | |
Рис = сонс.kdeplot(телеком_данные[телеком_данные['взбалтывать'] == ЛОЖЬ][«Обслуживание клиентов звонит»], | |
этикетка = 'Верный') | |
Рис = сонс.kdeplot(телеком_данные[телеком_данные['взбалтывать'] == Истинный][«Обслуживание клиентов звонит»], | |
этикетка = 'взбалтывать') | |
Рис.установлен(xметка=«Количество звонков», ylabel='Плотность') | |
пожалуйста.показывать() |

импорт пустышка туз н.п. | |
деф get_bootstrap_samples(данные, n_samples): | |
«»»Создайте образцы начальной загрузки, используя метод начальной загрузки. » » » | |
подсказки = н.п..случайный.рэндинт(0, тогда(данные), (n_samples, тогда(данные))) | |
образцы = данные[подсказки] | |
возвращаться образцы | |
деф stat_intervals(статус, альфа): | |
"""Производит интервальную оценку. » » » | |
границы = н.п..процентиль(статус, [100 * альфа / 2., 100 * (1 – альфа / 2.)]) | |
возвращаться границы | |
# Сохраняйте данные о лояльных и формирующих клиентах, чтобы разделить набор данных | |
верные_звонки = телеком_данные[телеком_данные['взбалтывать'] | |
== ЛОЖЬ][«Обслуживание клиентов звонит»].ценности | |
churn_calls= телеком_данные[телеком_данные['взбалтывать'] | |
== Истинный][«Обслуживание клиентов звонит»].ценности | |
# Установите начальное значение для воспроизводимости результатов. | |
н.п..случайный.семя(0) | |
# Сгенерируйте выборки с помощью начальной загрузки и рассчитайте среднее значение для каждой из них. | |
верноподданные_средние_оценки = [н.п..иметь в виду(образец) | |
за образец в get_bootstrap_samples(верные_звонки, 1000)] | |
churn_mean_scores = [н.п..иметь в виду(образец) | |
за образец в get_bootstrap_samples(churn_calls, 1000)] | |
# Распечатать полученные оценки интервалов | |
Распечатать(«Сервисные звонки от лояльных: средний интервал», | |
stat_intervals(верноподданные_средние_оценки, 0.05)) | |
Распечатать(«Вызовы службы от оттока: средний интервал», | |
stat_intervals(churn_mean_scores, 0.05)) |
Вызовы службы от лояльных: средний интервал [1,4077193 1,49473684] # Вызовы службы от оттока: средний интервал [2,0621118 2,39761905]
В итоге мы находим, что с вероятностью 95 % среднее количество звонков в службу поддержки от лояльных клиентов составляет от 1,4 до 1,49, в то время как отозванные клиенты звонили в среднем от 2,06 до 2,40 раз. Также обратите внимание, что интервал для лояльных клиентов уже, что разумно, поскольку они делают меньше звонков (0, 1 или 2) по сравнению с разочарованными клиентами, которые звонили до тех пор, пока не устали и не сменили поставщика.
расфасовка
Теперь, когда вы поняли идею начальной загрузки, мы можем перейти к бэггингу. В проблеме регрессия, усредняя отдельные ответы, бэггинг уменьшает среднеквадратичную ошибку на коэффициент M, количество регрессоров.
Из нашего предыдущего урока давайте вспомним компоненты, составляющие общую ошибку вне выборки:
Пакетирование уменьшает дисперсию классификатора за счет уменьшения разницы ошибок при обучении модели на разных наборах данных. Другими словами, бэггинг предотвращает переоснащение. Эффективность бэггинга заключается в том, что отдельные модели сильно различаются из-за разных данных обучения, и их ошибки компенсируют друг друга при голосовании. Кроме того, выбросы, вероятно, опущены в некоторых начальных образцах обучения.
Библиотека scikit-learn поддерживает бэггинг с помощью метаоценщиков BaggingRegressor и BaggingClassifier. Вы можете использовать большинство алгоритмов в качестве базы.
Давайте посмотрим, как бэггинг работает на практике, и сравним его с деревом решений. Для этого воспользуемся примером из документации sklearn.
Ошибка для дерева решений:
0,0255 = 0,0003 (смещение²) + 0,0152 (дисперсия) + 0,0098 (σ²)
Ошибка при использовании бэггинга:
0,0196 = 0,0004 (смещение²) + 0,0092 (дисперсия) + 0,0098 (σ²)
Как вы можете видеть на графике выше, дисперсия ошибок намного ниже для бэггинга. Помните, что мы уже доказали это теоретически.
Пакетирование эффективно для небольших наборов данных. Удаление даже небольшой части обучающих данных приводит к построению существенно отличающихся базовых классификаторов. Если у вас есть большой набор данных, вы будете генерировать образцы начальной загрузки гораздо меньшего размера.
Приведенный выше пример вряд ли применим к реальной работе. Это потому, что мы сделали сильное предположение, что наши индивидуальные ошибки не коррелированы. Чаще всего это слишком оптимистично для реальных приложений. Когда это предположение неверно, уменьшение ошибки будет не таким большим. В последующих лекциях мы обсудим более сложные ансамблевые методы, которые позволяют делать более точные прогнозы в реальных задачах.
Ошибка «вне упаковки»
В дальнейшем, в случае случайного леса, нет необходимости использовать выборки перекрестной проверки или исключения для получения объективной оценки ошибки. Почему? Потому что в методах ансамбля оценка ошибки происходит внутри.
Случайные деревья строятся с использованием различных бутстреп-выборок из исходного набора данных. Около 37 % входов исключены из конкретной бутстрепной выборки и не используются при построении K-го дерево.
Давайте посмотрим, как работает оценка ошибок Out-of-Bag (или OOBE):
Верхняя часть рисунка выше представляет наш исходный набор данных. Мы разделили его на практические (слева) и тестовые (справа) наборы. На изображении слева мы рисуем сетку, аккуратно разделяющую наш набор данных по классам. Теперь мы используем ту же сетку для оценки доли правильных ответов в нашем тестовом наборе. Мы видим, что наш классификатор дал неверные ответы в этих 4 случаях, которые не использовались во время обучения (слева). Следовательно, точность нашего классификатора составляет 11/15*100 % = 73,33 %.
Подводя итог, каждый алгоритм база обучена на ~63 % оригинальных примерах. Это можно проверить на оставшихся ~37%. Оценка Out-of-Bag — это не что иное, как средняя оценка базовых алгоритмов по ~37 % входных данных, которые не были обучены.
Случайный лес
Лео Брейману удалось применить бутстрап не только в статистике, но и в машинном обучении. Вместе с Аделем Катлером он расширил и улучшил алгоритм Random Forest, предложенный Тином Камом Хо.Они объединили построение некоррелированных деревьев с использованием CART, мешков и метода случайных подпространств.
Деревья решений — хороший выбор для базового классификатора при бэггинге, потому что они довольно сложные и могут обеспечить нулевые ошибки классификации для любой выборки. Метод случайных подпространств уменьшает корреляция между валами, что позволяет избежать переоснащения. При бэггинге основные алгоритмы обучаются на различных случайных подмножествах исходного набора функций.
Следующий алгоритм строит набор моделей методом случайных подпространств:
- Предположим, что количество экземпляров равно n, а количество измерений объекта равно d.
- Выберите M как количество отдельных моделей в наборе.
- Для каждой модели m выберите количество признаков dm < d. Как правило, для всех моделей используется одно и то же значение dm.
- Для каждой модели m создайте обучающий набор, случайным образом выбрав функции dm из набора функций d.
- Тренируйте каждую модель.
- Примените полученный шаблон сборки к новой записи, объединив полученные результаты всех моделей M. Вы можете использовать либо голосование по большинству, либо агрегацию апостериорной вероятности.
Алгоритм следующий:
Последний классификатор является средним значением деревьев.
Для задач классификации рекомендуется установить m равным квадратному корню из d. Для задач регрессии мы обычно берем m = d/3, где d — количество признаков. Каждое дерево рекомендуется строить до тех пор, пока все его листья не будут содержать только 1 экземпляр для классификации и 5 экземпляров для регрессии.
Вы можете думать о случайном лесу как о кластеризации деревьев решений с изменяющимся выбором случайного подмножества признаков при каждом разделении.
Сравнение
Вот результаты для трех алгоритмов:
Как видно из наших графиков и приведенных выше значений MSE, случайный лес из 10 деревьев дает лучший результат, чем одно дерево решений, и сравним с пакетированием с 10 деревьями. Основное различие между случайным лесом и бэггингом заключается в том, что в случайном лесу лучшая функция для разделения выбирается из случайного подмножества доступных функций, в то время как при бэггинге все функции рассматриваются для следующего лучшего разделения.
Мы также можем рассмотреть преимущества случайных лесов и проблемы классификации.
На приведенных выше рисунках показано, что граница решения дерева решений довольно нерегулярна и имеет много острых углов, что предполагает переобучение и плохую способность к обобщению. Нам будет сложно делать надежные прогнозы на основе новых тестовых данных. Напротив, алгоритм мешков имеет довольно гладкую границу и не показывает явных признаков переобучения.
Теперь давайте посмотрим на некоторые параметры, которые могут помочь нам повысить точность модели.
Параметры для повышения точности
Библиотека scikit-learn реализует случайные леса, предоставляя два оценщика: RandomForestClassifier и RandomForestRegressor.
Ниже приведены параметры, на которые необходимо обратить внимание при построении новой модели:
- n_estimators — количество деревьев в лесу;
- критерий — функция, используемая для измерения качества разделения;
- max_features — количество функций, которые необходимо учитывать при поиске наилучшего распределения;
- min_samples_leaf — минимальное количество выборок, необходимое для конечного узла;
- max_depth — максимальная глубина дерева.
Самый важный факт о случайных лесах заключается в том, что их точность не уменьшается, когда мы добавляем деревья, поэтому количество деревьев не является гиперпараметром сложность в отличие от max_depth и min_samples_leaf. Это означает, что вы можете настроить гиперпараметры, скажем, с 10 деревьями, затем увеличить количество деревьев до 500 и быть уверенным, что точность будет только улучшаться.
Чрезвычайно случайные деревья используют большую степень рандомизации для выбора точки отсечения при разделении узла дерева. Как и в случайных лесах, используется случайное подмножество признаков. Но вместо поиска оптимальных порогов их значения выбираются случайным образом для каждого возможного признака, и лучший из этих случайно сгенерированных порогов используется как наилучшее правило для разделения узла. Обычно это компенсирует небольшое снижение дисперсии модели небольшим увеличением систематической ошибки.
В библиотеке scikit-learn есть 2 чрезвычайно случайные реализации дерева: ExtraTreesClassifier и ExtraTreesRegressor.
Этот метод следует использовать, если вы переборщили со случайными лесами или повышением градиента.
Заключение по случайному лесу
Преимущества:
- Высокая точность предсказания; будет работать лучше, чем линейные алгоритмы в большинстве задач; точность сравнима с бустингом;
- Устойчивость к выбросам благодаря случайной выборке;
- Нечувствителен к масштабированию признаков, а также к любому другому монотонному преобразованию из-за случайного выбора подпространства;
- Не требует тонкой настройки настроек, работает достаточно хорошо из коробки. При настройке может быть достигнуто увеличение точности от 0,5 до 3 %, в зависимости от настройки проблемы и данных;
- Эффективен для наборов данных с большим количеством признаков и классов;
- Обрабатывает как непрерывные, так и дискретные переменные;
- Редко крупная. На практике увеличение количества деревьев почти всегда улучшает композицию. Но после достижения определенного количества деревьев кривая обучения очень близка к асимптоте;
- Существуют методы, разработанные для оценки важности признаков;
- Хорошо работает с отсутствующими данными и поддерживает хороший уровень точности, даже если большая часть данных отсутствует;
- Предоставляет средства для взвешивания классов по набору данных, а также для каждого выборочного дерева;
- Под капотом вычисляет близость между парами экземпляров, которые затем можно использовать для кластеризации, обнаружения выбросов или представления интересных данных;
- Вышеупомянутые функциональные возможности и свойства могут быть расширены на немаркированные данные, чтобы обеспечить неконтролируемую группировку, визуализация данных и обнаружение выбросов;
- Легко распараллеливается и хорошо масштабируется.
Неудобства:
- По сравнению с одним деревом решений вывод Random Forest труднее интерпретировать.
- Не существует формальных p-значений для оценки важности признаков.
- Работает хуже, чем линейные методы, в случае разреженных данных: текстовые записи, набор слов и т. д. ;
- В отличие от линейной регрессии, Random Forest не может экстраполировать. Но это также можно рассматривать как преимущество, поскольку выбросы не вызывают выбросы в случайных лесах;
- Склонен к переоснащению в некоторых задачах, особенно при работе с зашумленными данными;
- В случае категориальных переменных с разным количеством уровней случайные леса отдают предпочтение переменным с большим количеством уровней. Древовидная структура будет больше адаптироваться к многоуровневой функциональности, поскольку она станет более точной;
- Если набор данных содержит группы коррелированных признаков с одинаковой важностью для прогнозируемых классов, предпочтение будет отдано меньшим группам;
- Полученная модель имеет большой размер и требует много оперативной памяти.