В прошлый раз мы добились почти 98% точности с нашим деревом решений из пакета rpart. Давайте установим нашу отправную точку на основе предыдущей статьи с деревом с точностью 98%.

# data preparation
# Load the iris dataset
data(iris)
# Split the data into training and test sets
set.seed(20)
train_index <- sample(1:nrow(iris), nrow(iris)*0.7)
# train dataset formation
train_set <- iris[train_index, ]
str(train_set)
# test dataset formation
test_set <- iris[-train_index, ]
str(test_set)
# Growing trees
# Build the decision tree model
library(rpart)
iris_tree <- rpart(Species ~ ., data = train_set, method = "class")
iris_tree
# Predict on the test set
predictions <- predict(iris_tree, test_set, type = "class")
predictions

Теперь попробуем его улучшить.

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

Настройка гиперпараметров

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

В R мы можем использовать функцию rpart.control для настройки этих параметров при построении нашего дерева решений. Давайте посмотрим на пример с параметрами по умолчанию:

library(rpart)
control <- rpart.control(minsplit = 20, minbucket = 7, maxdepth=30)
fit <- rpart(Species ~ ., data=iris, method="class", control=control)

В этом примере параметр minsplit определяет минимальное количество наблюдений, которые должны существовать в узле, чтобы была предпринята попытка разделения, minbucket — это минимальное количество наблюдений в любом конечном узле, а maxdepth — максимальная глубина любого узла в узле. финальное дерево. Настраивая эти параметры, мы можем гарантировать, что наше дерево решений не будет переоснащено или недостаточно приспособлено.

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

Моя логика следующая:

  • Установка minbucket в 1 не приносит никакой дополнительной пользы, потому что по умолчанию каждый конечный узел (или лист) будет содержать по крайней мере одно наблюдение. Если вы настроите его на более высокое число, например, 3 или 7, это означает, что каждый конечный узел будет состоять как минимум из трех или семи наблюдений соответственно.
  • Чем ниже вы установите значение minbucket, тем выше специфичность вашей модели. Однако установка слишком низкого значения minbucket, например 1, потенциально может привести к проблеме переоснащения вашей модели.

Попытаюсь вымышленно максимизировать примерку. Я укажу minbucket в 5.

# NEW ADVANCED TREE with control component
control <- rpart.control(minsplit=20, minbucket=5, maxdepth=20)
iris_tree_advanced <- rpart(Species ~ ., data = train_set, method="class", control=control)

# Predict on the test set
predictions_advanced <- predict(iris_tree_advanced, test_set, type = "class")
predictions_advanced

# Evaluate the model with the same Confusion Matrix as we used before
library(caret)
cm <- confusionMatrix(predictions_advanced, test_set$Species)
print("Tuned model")
cm

Мы добились 100% точности на данных TEST, чего ранее не было в модели. Есть некоторые предостережения по поводу переобучения, но поскольку мы тестируем невидимый ранее набор данных — мы не делаем ничего плохого, мы просто повысили точность нашей модели с 98% до почти 100% (в основном, разница между этим и предыдущими выходными данными были в одном объекте, который ранее классифицировался как versicolor, а на самом деле был virginica; эта модельная «ошибка» теперь исправлена).

Обратите внимание, что мы пытались достичь 100% только для того, чтобы показать, что вы можете контролировать качество сгенерированного дерева с control компонентами, будьте осторожны со 100% точностью. Это достижимо в основном на игрушечных наборах данных.

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

Обрезка деревьев решений

Чтобы продемонстрировать обрезку, мы будем использовать ранее установленное дерево со 100% соответствием на основе тестовых данных. Давайте представим, что мы думаем, что есть переоснащение, или мы хотели бы упростить сложность дерева. Обрезка — это то, что нам нужно…

Обрезка — это еще один метод, используемый для повышения производительности деревьев решений путем удаления ветвей со слабой предсказательной силой. Это достигается с помощью параметра сложности (CP), который используется для управления размером дерева решений и, в конечном итоге, для предотвращения переобучения.

Функция printcp в R предоставляет таблицу CP для нашего подогнанного объекта rpart. Эта таблица может помочь нам определить оптимальную CP, которая приводит к наиболее точной модели.

# Quality of our "overfitted" model
printcp(iris_tree_advanced)

Что мы здесь видим?

  • CP (параметр сложности): этот параметр определяет порог, ниже которого разделение узла не стоит сложности. В этом случае у нас есть значения 0,548387, 0,370968, 0,016129 и 0,01.
  • nsplit: это количество расщеплений, выполненных до этой точки дерева. Например, строка с nsplit = 1 представляет дерево после первого разбиения.
  • rel error (относительная ошибка): это ошибка относительно корневого узла, она уменьшается с каждым разбиением.
  • xerror (ошибка перекрестной проверки): это оценка ошибки прогнозирования для каждого разделения (и каждого значения CP) при перекрестной проверке. Идея состоит в том, чтобы выбрать наименьшее дерево (т. е. с наименьшим количеством разбиений) так, чтобы ошибка перекрестной проверки находилась в пределах 1 стандартной ошибки минимума.
  • xstd: это стандартная ошибка перекрестной проверки.

Из таблицы видно, что xerror существенно не уменьшается после третьего разделения (xerror увеличивается после третьего разделения), что говорит о том, что отсечение может быть полезным при третьем разделении для предотвращения переобучения.

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

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

Глядя на таблицу, ошибка перекрестной проверки (xerror) увеличивается после третьего разделения (с 0.14516 до 0.16129), что позволяет предположить, что в этот момент модель может начать переобучать (И МЫ ЗНАЕМ, ЧТО МЫ ЭТО СДЕЛАЛИ). Следовательно, обрезка действительно может быть полезной, чтобы предотвратить переоснащение и упростить модель.

Чтобы выполнить сокращение, мы выбираем значение CP, которое уравновешивает сложность модели (количество разбиений) с точностью прогнозирования (xerror). Оптимальное значение CP обычно выбирается как значение, связанное с наименьшим деревом в пределах одной стандартной ошибки минимума xerror.

В этом случае может иметь смысл обрезать дерево при третьем разделении, соответствующем CP 0.02, потому что xerror не уменьшается значительно после 3-го разделения.

Давайте подрежем наше дерево с помощью функции prune:

pruned_tree <- prune(iris_tree_advanced, cp = 0.02)
printcp(pruned_tree)

predictions_pruned <- predict(pruned_tree, test_set, type = "class")
predictions_pruned

# Evaluate the model
cm_pruned <- confusionMatrix(predictions_pruned, test_set$Species)
print("Tuned model")
cm_pruned

Мы восстановили исходную производительность дерева 98% и избежали переобучения. Хорошая работа!👏

Заворачивать

Сегодня мы углубились в классификацию деревьев решений в R, сосредоточившись на передовых методах настройки гиперпараметров и обрезки деревьев. Начав с модели, построенной с использованием пакета rpart, который достиг почти 98% точности на наборе данных Iris, мы искали способы повысить производительность.

Используя функцию rpart.control для точной настройки таких параметров, как minsplit, minbucket и maxdepth, нам удалось добиться 100% точности набора тестовых данных. Тем не менее, важно помнить о риске переобучения, особенно когда модель демонстрирует такой высокий уровень точности.

Чтобы противостоять возможному переоснащению и упростить нашу модель, мы исследовали обрезку деревьев. С помощью параметра сложности (СР) мы контролировали размер дерева решений и повышали его производительность. Используя функцию printcp в R, мы определили оптимальную CP, а затем обрезали дерево решений с помощью функции prune. Усеченное дерево успешно избежало переобучения и сохранило производительность исходной модели, демонстрируя эффективность этих передовых методов в уточнении моделей дерева решений. Эти методы применимы к различным наборам данных и сценариям проблем, что делает их бесценными инструментами в обширной области машинного обучения.

Пожалуйста, похлопайте 👏 и подпишитесь, если хотите меня поддержать. Спасибо! ❤️‍🔥