Ансамбли и случайный лес: пример на Python¶
Автор: Максим Банцевич
Сравним дерево и лес на 300 синтетических заказах 3D-печати. Признаки известны до печати: высота, число цветов, объём пластика. Ответ — время в минутах.
Запускайте ноутбук сверху вниз из папки 09-random-forest в копии репозитория. Нужен соседний файл ../07-features-regularization/data/train.csv. Данные придуманы для учебника.
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import KFold, cross_val_score
from sklearn.tree import DecisionTreeRegressor
data = pd.read_csv("../07-features-regularization/data/train.csv")
X = data[["height_cm", "colors", "plastic_cm3"]]
y = data["minutes"]
Случайный лес в scikit-learn¶
Для предсказания времени печати используем RandomForestRegressor. Его основные настройки связаны с понятиями из статьи:
Таблица 1 — Основные параметры случайного леса
| Параметр | За что отвечает | В нашем примере |
|---|---|---|
max_depth |
Максимальная глубина каждого дерева. Небольшая глубина ограничивает сложность модели. | По умолчанию None: явного ограничения глубины нет. |
min_samples_leaf |
Минимальное число обучающих объектов в листе. Чем оно больше, тем меньше дерево подстраивается под отдельные примеры. | По умолчанию 1. |
max_features |
Сколько признаков можно рассматривать при поиске разбиения в каждой вершине. | 2: случайно выбираются два из трёх признаков. |
n_estimators |
Число деревьев в лесу. | 100. |
bootstrap |
Обучать ли каждое дерево на выборке с возвращением. | True. |
random_state |
Фиксирует случайный выбор для воспроизводимости опыта. | 0. |
У RandomForestRegressor значение max_features по умолчанию равно 1.0: при каждом разбиении доступны все признаки. Поэтому мы явно задаём целое число 2, чтобы использовать только часть признаков. Их набор выбирается заново в каждой вершине. Если среди выбранных признаков нет допустимого разбиения, библиотека может рассмотреть дополнительные признаки.
max_depth=None не означает, что дерево растёт бесконечно: оно останавливается, когда дальнейшее разбиение невозможно или срабатывают другие условия остановки. В этом примере мы не ограничиваем глубину явно. Для подбора настроек можно сравнивать разные значения max_depth, min_samples_leaf, max_features и n_estimators на одинаковых проверочных разбиениях.
Для задачи классификации в библиотеке есть RandomForestClassifier. Он усредняет оценки вероятностей классов, полученные от деревьев, и выбирает класс с наибольшей средней вероятностью. Это может дать другой результат, чем простое голосование по готовым ответам деревьев.
Описание классов: RandomForestRegressor и RandomForestClassifier.
Сравнение моделей¶
Каждая треть таблицы по очереди служит для проверки, остальные две — для обучения. Обе модели получают одинаковые разбиения. Бутстрап-выборки леса строятся только из обучающей части.
cross_val_score возвращает отрицательную MAE; меняем знак, чтобы получить обычную ошибку в минутах.
folds = KFold(n_splits=3, shuffle=True, random_state=42)
models = {
"Дерево": DecisionTreeRegressor(random_state=0),
"Лес": RandomForestRegressor(
n_estimators=100, max_features=2,
bootstrap=True, random_state=0,
),
}
for name, model in models.items():
errors = -cross_val_score(
model, X, y, cv=folds, scoring="neg_mean_absolute_error"
)
print(name, [round(error, 2) for error in errors],
round(errors.mean(), 2))
При указанных настройках дерево даёт ошибки 3,02; 2,97; 2,69 минуты, лес — 2,76; 2,48; 2,55 минуты. Средние MAE равны 2,89 и 2,60 минуты соответственно.
Это сравнение двух моделей на одном учебном наборе. Если выбирать настройки по этим результатам, для независимой итоговой оценки понадобятся отдельные данные.
Самостоятельный эксперимент: разнообразие деревьев¶
Сначала предположите, что произойдёт со средней MAE, если разрешить дереву в каждой вершине один, два или все три признака. Сохраняйте те же три разделения. Запишите три результата, затем объясните разницу. Эти данные используются для выбора настройки и потому не дают независимой итоговой оценки.
for count in [1, 2, 3]:
forest = RandomForestRegressor(n_estimators=100, max_features=count,
bootstrap=True, random_state=0)
errors = -cross_val_score(forest, X, y, cv=folds,
scoring='neg_mean_absolute_error')
print('max_features =', count, 'MAE =', round(errors.mean(), 2), 'мин')
Теперь сравните 10, 30 и 100 деревьев при max_features=2. Проверьте, обязана ли измеренная ошибка монотонно убывать. Дополнительно засеките время выполнения каждой строки.
for count in [10, 30, 100]:
forest = RandomForestRegressor(n_estimators=count, max_features=2,
bootstrap=True, random_state=0)
errors = -cross_val_score(forest, X, y, cv=folds,
scoring='neg_mean_absolute_error')
print('деревьев =', count, 'MAE =', round(errors.mean(), 2), 'мин')
Самопроверка. Во всех опытах должны оставаться те же X, y и folds; меняется только одна настройка за раз. minutes не входит в признаки, а order_id не описывает будущий заказ. Небольшое колебание MAE при увеличении числа деревьев возможно. Для оценки выбранного варианта нужна отдельная таблица с ответами, которую не использовали при выборе параметров.
Вопрос для отчёта. Какая настройка выиграла на этих трёх разделениях? Насколько велика разница с исходным лесом? Достаточна ли она, чтобы объявить настройку универсальной?
Самопроверка¶
1. Что означает «ансамбль» в этом занятии?¶
A. Один особенно глубокий алгоритм.
B. Несколько моделей, ответы которых объединяют.
C. Только таблица с большим числом признаков.
D. Отдельная итоговая выборка.
2. Три дерева предсказали 24, 30 и 36 минут. Каков средний прогноз?¶
A. 24 минуты.
B. 30 минут.
C. 31 минута.
D. 90 минут.
3. Почему три одинаковых дерева не обязательно улучшат прогноз при усреднении?¶
A. Их среднее совпадёт с каждым отдельным ответом.
B. Среднее всегда равно нулю.
C. Такие деревья нельзя обучить на таблице.
D. Придётся удалить все признаки.
4. Что означает выборка с возвращением?¶
A. После выбора строку удаляют навсегда.
B. Каждую строку берут ровно один раз.
C. Выбранная строка остаётся доступной и может встретиться снова.
D. Выбирают только новые итоговые заказы.
5. Что копируют, когда заказ попал в бутстрап-выборку для обучения дерева?¶
A. Только его номер.
B. Признаки и известный ответ вместе.
C. Только ответ без признаков.
D. Ответ из итогового теста.
6. Что случайно выбирают при поиске каждого вопроса дерева в лесу?¶
A. Часть признаков, среди которых ищут разбиение.
B. Настоящее время нового заказа.
C. Готовый класс без данных.
D. Одну и ту же глубину для всех деревьев.
7. Как лес регрессии объединяет ответы деревьев?¶
A. Берёт ответ только первого дерева.
B. Усредняет числовые прогнозы.
C. Умножает их все друг на друга.
D. Заменяет их номерами заказов.
8. Почему дерево и лес сравнивают на одинаковых трёх разделениях?¶
A. Чтобы модель получила доступ к проверочным ответам при обучении.
B. Чтобы различие ошибок не объяснялось разными наборами для проверки.
C. Чтобы все деревья леса стали одинаковыми.
D. Чтобы не считать MAE.
9. Что показывает средняя MAE 2,60 минуты у леса в этой статье?¶
A. Ошибку ровно 2,60 минуты на каждом заказе.
B. Среднюю проверочную ошибку на трёх разделениях синтетической таблицы.
C. Ошибку на настоящем принтере.
D. Число листьев каждого дерева.
10. Что нужно после выбора max_features по тем же трём проверкам?¶
A. Назвать их среднюю ошибку независимой итоговой оценкой.
B. Открыть новые, ещё не использованные итоговые ответы один раз.
C. Передать номер заказа как новый признак.
D. Убрать обучение и оставить только рисунок.
Подсказки и решения¶
Вопрос 1¶
Подсказка
Посмотрите на три прогноза времени одной фигурки.
Решение
B. Ансамбль состоит из нескольких базовых моделей и правила объединения их ответов.
Вопрос 2¶
Подсказка
Сложите три числа и разделите на три.
Решение
B. $(24+30+36)/3=30$ минут. Настоящее время 31 минута не входит в вычисление прогноза.
Вопрос 3¶
Подсказка
Найдите среднее трёх чисел 24, 24 и 24.
Решение
A. Среднее одинаковых ответов ничего не меняет; полезно, когда ошибки деревьев различаются.
Вопрос 4¶
Подсказка
В примере заказ В выпал дважды.
Решение
C. Возвращение позволяет строке повторяться в бутстрап-выборке; другие строки могут не попасть в неё.
Вопрос 5¶
Подсказка
Дереву нужны и сведения об объекте, и то, что оно должно предсказать.
Решение
B. Копируется вся обучающая строка. Итоговые ответы в обучение не включают.
Вопрос 6¶
Подсказка
Вспомните пример с высотой, цветами и объёмом.
Решение
A. Случайным становится набор доступных признаков в каждой вершине; лучший вопрос среди них выбирают по обучающим данным.
Вопрос 7¶
Подсказка
Вернитесь к примеру 24, 30 и 36 минут.
Решение
B. Среднее числовых прогнозов и есть ответ леса в задаче регрессии.
Вопрос 8¶
Подсказка
Что ещё могло бы измениться, кроме модели?
Решение
B. Одинаковые части делают сравнение яснее: проверочные строки не меняются между вариантами.
Вопрос 9¶
Подсказка
Посмотрите на три строки таблицы ошибок и их среднее.
Решение
B. Это среднее трёх проверок на учебных заказах, а не гарантия для каждого объекта или реальной мастерской.
Вопрос 10¶
Подсказка
Проверочные ответы уже повлияли на выбор настройки.
Решение
B. Для независимой итоговой оценки нужен другой набор, не участвовавший в подборе параметров.