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

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

Итак, начнем без лишних слов.

Что такое случайный лес?

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

Случайные леса следуют аналогии с тем, что огромное количество деревьев может собраться вместе и создать лес. Термин «случайный» указывает на то, что деревья выбираются случайным образом, чтобы составить лес.

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

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

Если говорить кратко:

· Создано N подмножеств с использованием исходного набора данных

· На основе этих подмножеств построено N деревьев решений.

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

Обобщим эту информацию в виде диаграммы:

Перейдем к реализации алгоритма с нуля.

Реализация случайного леса с нуля

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

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

1. Узел

2. Дерево решений

3. RandomForest

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

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

Начнем с первого класса. Класс Node будет хранить всю информацию о конкретном узле в дереве. Данные, идущие влево и вправо, порог разделения и прирост информации упаковывают все красиво.

Вот как мы можем это закодировать:

https://gist.github.com/muneebhashmi7712/680f55ad53f25a596bc74486a04e1014

Это было довольно просто. Давайте перейдем к классу DecisionTree, чтобы реализовать классификатор, который мы будем использовать. Вот краткий обзор методов, которые мы будем использовать в классе перед кодированием.

__init__() — функция-конструктор. Это инициализирует значения наших гиперпараметров min_samples_split и max_depth. Первый определяет, сколько образцов нам потребуется для дальнейшего разделения узла, а последний определяет глубину решения. дерево, которое мы строим. Эти гиперпараметры действуют как условия нарушения рекурсивной функции построения дерева.

_entropy(s) –определяет нечистоту конкретного вектора.

_information_gain(parent, left_child, right_child) чтобы найти прирост информации при разделении узла на дочерние узлы.

_best_split(X, y)самая важная функция; тот, который определяет наилучшие параметры разделения. Он использует входные функции X и целевую переменную y для поиска оптимальных значений.

_build(X, y, depth) — основной метод. Он создает дерево с рекурсивными вызовами узлов разделения до тех пор, пока не будут выполнены условия останова, как описано в гиперпараметрах.

fit(X, y) — используется для вызова метода _build() для сохранения обновленного дерева в конструкторе после каждой итерации.

_predict(x) — для прогнозирования тестового набора данных путем обхода всего дерева и преобразования входных данных в выходные.

predict(X) — при наличии матрицы входных признаков X эта функция применяет _predict() для каждой записи в этой матрице.

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

https://gist.github.com/muneebhashmi7712/1a3ab4ab9dac2fccf75cac3d71d7c046

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

Наконец, пришло время реализовать наш класс RandomForest. Этот класс будет основан на классе DecisionTree, точно так же, как класс DecisionTree был основан на классе Node. Вот методы, которые мы будем использовать, вместе с их описанием.

__init__() — конструктор гиперпараметров. Содержит значения количества деревьев в лесу, максимальной глубины, на которую он может уйти, и минимального разделения выборки. И последнее, но не менее важное: он также будет содержать отдельные деревья при обучении модели.

_sample(X, y) — метод начальной загрузки функций.

fit(X, y) — для обучения модели классификатора.

Predict(X) — для получения окончательного результата с использованием правила большинства.

Вот как мы можем закодировать это на Python.

https://gist.github.com/muneebhashmi7712/0d0bc8661914fe9db2a0f06028d95ff4

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

Оценка модели

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

https://gist.github.com/muneebhashmi7712/fbb24d15cc95c8932b34c57e00188e1a

Вам может быть интересно, как выглядит набор данных; Ну вот.

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

https://gist.github.com/muneebhashmi7712/86dae1d13ab8fbab36f53211a9fef972

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

https://gist.github.com/muneebhashmi7712/25dd6813795629c63c721e6e347862ed

Как вы знаете, 1 означает мошенничество, а 0 говорит нам, что транзакция не была отмечена как мошенничество. Давайте воспользуемся нашим тестовым набором данных, чтобы распечатать точность нашей модели, чтобы увидеть, как она себя показала.

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

Еда на вынос

Сегодня мы успешно создали классификатор случайного леса с нуля на Python. Я уверен, что это было проще, чем многие из вас представляли. К счастью, в настоящее время случайные леса являются одними из наиболее широко используемых классификаторов в отрасли из-за их фантастической производительности.

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

Вот и все на сегодня! Увидимся в следующей статье.