Вы подписаны на Машинное обучение доступно
Отлично! завершите оплату для полного доступа к Машинное обучение доступно
Снова приветствуем Вас! Вы успешно авторизовались
Успех! Аккаунт активирован, и Вы имеете полный доступ к контенту.
Случайный лес (Random Forest)

Случайный лес (Random Forest)

in

Случайный лес – метод Машинного обучения (ML), использующий Ансамбль (Ensemble) Деревьев решений (Decision Tree) для задач Классификации (Classification). Каждое отдельное дерево в таком лесу дает предсказание класса, и набравший наибольшее количество голосов Класс (Class), становится предсказанием Модели (Model). Он использует Бэггинг (Bagging) и случайность признаков при построении каждого отдельного дерева, чтобы создать некоррелированный лес из деревьев, прогноз которого "комитетом" более точен, чем прогноз любого отдельного дерева.

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

Наука о данных (Data Science) предоставляет множество Алгоритмов (Algorithm) классификации, таких как Логистическая регрессия (Logistic Regression), Метод опорных векторов (SVM), Наивный байесовский классификатор (Naive Bayes) и деревья решений. Но в верхней части иерархии классификаторов находится классификатор случайного леса.

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

Деревья решений

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

Наверное, гораздо легче понять, как работает дерево решений на примере.
Представьте, что наш набор данных состоит из списка чисел в верхней части рисунка [1, 1, 0, 0, 0, 0, 0]. У нас есть две единицы и пять нулей (1 и 0 – наши классы), и мы хотим разделить их, используя характеристики цвета и "подчеркнутости". Итак, как мы можем это сделать?

Цвет кажется довольно очевидной особенностью для разделения, поскольку все нули, кроме одного, белые. Таким образом, мы можем использовать вопрос: «Это розовый?» чтобы разделить числа в первом узле. Вы можете представить себе узел как разветвление дерева, где ветки разделяются на две части "да" и "нет".

Ветвь «нет» (белая) теперь имеет нулевые значения, и на ней дальнейшее деление невозможно. Но нашу ветвь «да» все еще можно разделить. Теперь мы можем использовать вторую характеристику и спросить: «Ряд подчеркнутый?» чтобы сделать второй раскол – "сплит".

Две подчеркнутые единицы отправляются вниз по ответвлению "да", а ноль, который не подчеркнут, идет по правой ветви. Наше дерево решений использовало эти две функции-характеристики для идеального разделения данных. Победа!

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

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

Классификатор случайного леса

Случайный лес, как следует из названия, состоит из большого количества отдельных деревьев решений.

5 деревьев решили, что класс 1, одно – 0. "Демократический" результат – 1.

Фундаментальная концепция случайного леса проста, но действенна – мудрость толпы. Говоря языком науки о данных, причина того, что модель случайного леса так хорошо работает, заключается в следующем:
Большое количество относительно некоррелированных моделей (деревьев), работающих как комитет, превзойдут любую из отдельных составляющих моделей.

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

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

Пример того, почему некоррелированные результаты так хороши

Замечательные эффекты некоррелированных моделей – это настолько важная концепция, что я хочу показать вам пример, который поможет ей по-настоящему проникнуться. Представьте, что мы играем в следующую игру:
я использую генератор случайных чисел от 0 до 100 для получения числа. Если полученное мной число больше или равно 40, вы выигрываете (так что у вас есть шанс на победу 60%), и я плачу вам немного денег. Если оно ниже 40, я выигрываю, и вы платите мне ту же сумму.

Теперь я предлагаю вам следующие варианты. Мы можем сыграть:

  • Игру 1: 100 генераций числа, ставка – $1
  • Игра 2: 10 – 10
  • Игра 3: 1 – 100

Какой вариант Вы предпочитаете? Ожидаемая ценность каждой игры одинакова:

  • 1: (0,60 * 1 + 0,40 * -1) * 100 = 20
  • 2: (0,60 * 10 + 0,40 * -10) * 10 = 20
  • 3: 0,60 * 100 + 0,40 * -100 = 20
Распределение результатов для 10 000 симуляций для каждой игры

А что насчет распределений? Давайте визуализируем результаты с помощью моделирования Монте-Карло (мы запустим 10 000 имитаций каждого типа игры; например, мы будем моделировать 10 тысяч раз 100 партий по схеме № 1. Взгляните на таблицу: какую игру Вы бы выбрали? Несмотря на то, что ожидаемые значения одинаковы, распределения результатов сильно различаются: от положительных и узких (синего цвета) до двоичных (розового).

Игра 1 (в которой мы играем 100 раз) дает лучший шанс заработать немного денег – из 10 000 симуляций, которые я провел, вы зарабатываете деньги в 97% из них! Для игры 2 (в которой мы играем 10 раз) вы зарабатываете деньги в 63% симуляций, резкое снижение вознаграждения за риск (и резкое увеличение вероятности потерять деньги). И в игре 3, в которую мы играем только один раз, вы, как и ожидалось, зарабатываете деньги на 60% симуляций.

Вероятность заработка на каждой игре

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

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

Обеспечение диверсификации моделей друг другом

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

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

Обратите внимание, что при бэггинге мы не разделяем обучающие данные на более мелкие фрагменты и не обучаем каждое дерево на разных фрагментах. Скорее, если у нас есть выборка размера N, мы по-прежнему скармливаем каждому дереву обучающий набор размера N (если не указано иное). Но вместо исходных обучающих данных мы берем случайную выборку размера N с заменой. Например, если наши обучающие данные были [1, 2, 3, 4, 5, 6], мы могли бы дать одному из наших деревьев следующий список [1, 2, 2, 3, 6, 6]. Обратите внимание, что оба списка имеют длину шесть и что «2» и «6» повторяются в случайно выбранных обучающих данных, которые мы передаем нашему дереву (потому что мы производим выборку с заменой).

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

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

Теперь давайте посмотрим на наш случайный лес. В этом примере мы рассмотрим только два дерева в нашем лесу. Когда мы проверяем случайное дерево леса 1, мы обнаруживаем, что оно может учитывать только функции 2 и 3 (выбранные случайным образом) для принятия решения о разделении узлов. Из нашего традиционного дерева решений (выделено синим цветом) мы знаем, что признак №1 – лучший способ разделения, но Дерево 1 не может видеть его, поэтому оно вынуждено использовать признак № 2 (черный и подчеркнутый). Дерево 2, с другой стороны, может видеть только характеристики 1 и 3, поэтому выбирает первый признак.

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

И это создает некоррелированные деревья, которые буферизируют и защищают друг друга от их ошибок.

Случайные леса – мой личный фаворит. Приходя из мира финансов и инвестиций, святым Граалем всегда было построение набора несогласованных моделей, каждая из которых имеет положительный ожидаемую доходность. Затем их объединяют в портфель, чтобы получить огромную рыночная доходность. Случайный лес – это эквивалент такого альфа-портфеля в науке о данных.

Случайный лес и scikit-learn

Давайте посмотрим, как метод реализована в SkLearn. Для начала импортируем необходимые библиотеки:

import sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification

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

Сразу же запустим RandomForestClassifier, причем зададим глубину дерева, равную двум. В ином случае, ветвей у каждого узла может быть очень много, вплоть до числа наблюдений.

X, y = make_classification(n_samples = 1000, n_features = 4,
                           n_informative = 2, n_redundant = 0,
                           random_state = 0, shuffle = False)
clf = RandomForestClassifier(max_depth = 2, random_state = 0)
clf.fit(X, y)

Система указывает стандартные настройки модели: мы не назначаем классам веса (class_weight=None), создаем 100 деревьев (n_estimators=100):

RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None, criterion='gini', max_depth=2, max_features = 'auto', max_leaf_nodes = None, max_samples=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=100, n_jobs=None, oob_score=False, random_state=0, verbose=0, warm_start=False)

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

print(clf.predict([[0, 0, 0, 0]]))

100 деревьев – это сила; модель относит это наблюдение к классу 1:

[1]

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

Автор оригинальной статьи: Tony Yiu

Фото: @lucabravo