Создание дерева решений

В этом модуле вы будете использовать библиотеку YDF (Yggdrasil Decision Forest) для обучения и интерпретации дерева решений.

Этот блок создан на основе учебного пособия YDF Getting Started .

Предварительные данные

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

  1. Создайте новый блокнот Colab .
  2. Установите библиотеку YDF, поместив и выполнив следующую строку кода в новом блокноте Colab:
    !pip install ydf -U
  3. Импортируйте следующие библиотеки:
    import ydf
    import numpy as np
    import pandas as pd

Набор данных Palmer Penguins

В этом Colab используется набор данных Palmer Penguins , содержащий измерения размеров трех видов пингвинов:

  • Подбородочный ремень
  • Генту
  • Адели

Это задача классификации: цель — предсказать вид пингвина на основе данных из набора данных «Пингвины Палмера». Вот эти пингвины:

Three different penguin
species.

Рисунок 16. Три разных вида пингвинов. Изображение @allisonhorst.

Следующий код вызывает функцию pandas для загрузки набора данных Palmer Penguins в память:

path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"

# Display the first 3 examples.
dataset.head(3)

В следующей таблице представлены первые 3 примера из набора данных Palmer Penguins:

Таблица 3. Первые 3 примера в Palmer Penguins

разновидность остров длина_купюры_мм bill_length_mm длина_плавника_мм масса_тела_г секс год
0 Адели Торгерсен 39.1 18.7 181.0 3750.0 мужской 2007
1 Адели Торгерсен 39,5 17.4 186.0 3800.0 женский 2007
2 Адели Торгерсен 40.3 18.0 195.0 3250.0 женский 2007

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

Следующая ячейка кода разделяет набор данных на обучающий и тестовый наборы :

# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2

train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]

print("Training examples: ", len(train_dataset))
# >> Training examples: 272

print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72

Обучение деревьев решений с гиперпараметрами по умолчанию

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

model = ydf.CartLearner(label=label).train(train_dataset)

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

Вызовите model.plot_tree() , чтобы отобразить полученное дерево решений:

model.plot_tree()

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

A decision tree trained with default
hyperparameters.

Рисунок 17. Дерево решений, обученное с использованием гиперпараметров по умолчанию.

Colab показывает, что корневое условие содержит 243 примера. Однако, как вы, возможно, помните, обучающий набор данных содержал 272 примера. Оставшиеся 29 примеров были автоматически зарезервированы для проверки и обрезки дерева.

Первое условие проверяет значение bill_depth_mm . Таблицы 4 и 5 показывают вероятность появления различных видов в зависимости от результата первого условия.

Таблица 4. Вероятность различных видов, если bill_depth_mm ≥ 42.3

Разновидность Вероятность
Адели (красная) 8%
Генту (синий) 58%
Подбородочный ремень (зеленый) 36%

Таблица 5. Вероятность различных видов, если bill_depth_mm < 42.3

Разновидность Вероятность
Адели (красная) 97%
Генту (синий) 2%
Подбородочный ремень (зеленый) 0%

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

Если bill_depth_mm ≥ 42.3 имеет значение True, то дальнейшая проверка того, может ли значение flipper_length_mm ≥ 207.5 почти идеально отделить Gentoos от Gentoos+Adelie.

Следующий код обеспечивает точность обучения и тестирования модели:

train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy:  0.9338

test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy:  0.9167

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

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

Улучшение гиперпараметров модели

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

  1. Используйте более мощный алгоритм обучения, например, модель случайного леса или деревьев с градиентным бустом . Эти алгоритмы обучения будут описаны на следующей странице.

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

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

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

Дерево решений, показанное выше, небольшое, а лист с 61 примером содержит смесь меток Адели и Чинстрапа. Почему алгоритм не разделил этот лист дальше? Возможны две причины:

  • Возможно, достигнуто минимальное количество образцов на лист ( min_examples=5 по умолчанию).
  • Дерево могло быть разделено, а затем обрезано, чтобы избежать переобучения.

Уменьшите минимальное количество примеров до 1 и посмотрите на результаты:

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

A decision tree trained with
min_examples=1.

Рисунок 18. Дерево решений, обученное с min_examples=1.

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

Чтобы увидеть, имеет ли смысл дальнейшее разделение узла, мы оцениваем качество этой новой модели на тестовом наборе данных:

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

Качество модели повысилось: точность тестирования увеличилась с 0,9167 до 0,97222. Изменение гиперпараметра было удачным решением.

Предварительный просмотр лесов решений

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

model = ydf.RandomForestLearner(label=label).train(train_dataset)
print("Test accuracy: ", model.evaluate(test_dataset).accuracy)
# >> Test accuracy: 0.986111

Точность случайного леса выше, чем у нашего простого дерева. На следующих страницах вы узнаете, почему.

Использование и ограничения

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

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