Введение
Недавно я читал свою копию Введение в статистическое обучение (моя партнерская ссылка на Amazon) и получил главу о различных методах на основе дерева. Я довольно хорошо знаком со случайным лесом, но некоторые другие методы для меня новы. Давайте рассмотрим эти различные техники.
Для этих примеров я буду исследовать набор данных Glass с сайта openml. Этот набор данных имеет 9 различных функций, используемых для прогнозирования типа стекла. Набор данных содержит 214 наблюдений.
Набор данных загружается с помощью следующего кода. Для этого требуется, чтобы пакет farff
открывал файлы arff, используемые на сайте openml.
library(tidyverse) download.file("https://www.openml.org/data/download/41/dataset_41_glass.arff", "data.arff") df <- farff::readARFF("data.arff")
Оттуда мы можем начать исследовать набор данных и настроить разделение обучения и тестирования для данных.
df %>% str() df <- droplevels(df) set.seed(1234) test <- sample(1:nrow(df), floor(nrow(df)*0.2)) testdf <- df[test,] traindf <- df[-test,] 'data.frame': 214 obs. of 10 variables: $ RI : num 1.52 1.52 1.52 1.51 1.53 ... $ Na : num 12.8 12.2 13.2 14.4 12.3 ... $ Mg : num 3.5 3.52 3.48 1.74 0 2.85 3.65 2.84 0 3.9 ... $ Al : num 1.12 1.35 1.41 1.54 1 1.44 0.65 1.28 2.68 1.3 ... $ Si : num 73 72.9 72.6 74.5 70.2 ... $ K : num 0.64 0.57 0.59 0 0.12 0.57 0.06 0.55 0.08 0.55 ... $ Ca : num 8.77 8.53 8.43 7.59 16.19 ... $ Ba : num 0 0 0 0 0 0.11 0 0 0.61 0 ... $ Fe : num 0 0 0 0 0.24 0.22 0 0 0.05 0.28 ... $ Type: Factor w/ 7 levels "build wind float",..: 1 3 1 6 2 2 3 1 7 2 ...
Древо решений
Наиболее простой моделью является дерево решений. В этой модели все классы хранятся в контейнере в корне дерева. Корень разделен определенными значениями функций на два меньших контейнера. Эти меньшие контейнеры называются листьями. После этих начальных двух листьев мы выполняем дополнительное разделение, в результате чего получается 4 новых листа. На этом этапе должна быть улучшена сортировка значения ответа в новых листах. Разделение и создание новых листьев продолжается до тех пор, пока не будут получены желаемые результаты.
Основным недостатком деревьев решений является то, что они очень склонны к переобучению. Довольно легко представить себе дерево, которое расщеплялось столько раз, что теперь каждый лист представляет собой одно наблюдение. Это дерево будет иметь 100% точность на тренировочном наборе, но не будет хорошо работать на тестовом наборе. Мы предотвращаем чрезмерную подгонку, отрезая или сокращая количество листьев до определенного значения.
В нашем примере дерево решений создается с помощью пакета tree
. Он довольно прост в использовании, вы просто предоставляете ему функцию и данные.
mdltree <- tree::tree(Type ~., data = traindf)
Визуализация дерева легко создается с помощью команды печати. С помощью дополнительной строки мы можем добавить текст, показывающий, где разделяется каждый лист. Трудно понять расщепления при переходе к листам нижнего уровня.
Теперь мы можем проверить производительность дерева решений на тестовых данных. Поскольку ответ является фактором, результирующий прогноз представляет собой матрицу с вероятностью, присвоенной каждому ответу для каждого наблюдения. Мы можем обобщить наиболее вероятный ответ с помощью функции max.col
.
treevalues <- predict(mdltree, newdata = testdf) treepred <- colnames(treevalues)[max.col(treevalues)] Acctree <- mean(treepred == testdf$Type) Acctree [1] 0.5
Из этого прогноза видно, что дерево решений не обеспечивает высокого уровня точности (точность 50%). Для более высокого уровня точности давайте рассмотрим некоторые дополнительные методы.
Бэгинг
Начальная загрузка — полезный метод, когда у нас есть ограниченное количество наблюдений. Обычно мы берем каждое тренировочное наблюдение из сумки и обучаем с его помощью нашу модель. При начальной загрузке после того, как мы обучим нашу модель с помощью наблюдения, мы кладем наблюдение обратно в корзину, позволяя повторять выборку. Повторный выбор создает более плавное распределение наблюдений.
Бэггинг продвигает этот процесс еще на один шаг вперед. Мы берем несколько моделей из загруженных обучающих данных и усредняем их значения. Каждая загруженная модель уникальна, поскольку обучающие наблюдения выбираются случайным образом.
Упаковку можно выполнить с помощью функции randomForest
. По умолчанию функция создает деревья из подмножества функций, но мы можем создавать деревья в мешках, используя все функции. Поведение по умолчанию для случайного леса состоит в том, чтобы получить большинство голосов за построенные деревья или усреднить их прогноз.
library(randomForest) mdlbag <- randomForest(Type ~., data = droplevels(traindf), mtry = ncol(df)-1, n.trees = 500) bagpreds <- predict(mdlbag, newdata = testdf) Accbag <- mean(bagpreds == testdf$Type) Accbag [1] 0.6666667
Случайный лес
Случайный лес — это ансамблевая модель, то есть прогноз создается путем объединения нескольких моделей. Это очень похоже на предыдущий пример с бэггингом. Основное отличие состоит в том, что случайный лес выбирает случайный набор признаков при создании каждого дерева.
Обоснованием случайного выбора признаков является создание более уникальных деревьев. Если в бэггинге есть сильная особенность, то большинство деревьев будут использовать ее для создания своего первого разделения. Это создает очень похожие деревья.
mdlforest <- randomForest(Type ~., data = droplevels(traindf), n.trees = 500) rfpreds <- predict(mdlforest, newdata = testdf) Accrf <- mean(rfpreds == testdf$Type) Accrf [1] 0.6666667
Повышение
Бустирование — еще одна техника многократного использования, очень похожая на бэггинг. Вместо того, чтобы воздействовать на обучающие данные для создания разных деревьев, бустинг строит деревья в последовательном порядке с обучающим набором по умолчанию. Вместо того, чтобы подгонять деревья к ответу, деревья подгоняют к своим остаткам. Затем каждое дерево медленно учится на остатках предыдущего дерева.
Для этой модели мы будем использовать две библиотеки, caret
и gbm
. Пакет gbm
— это пакет, предоставляющий фактическую модель, но при использовании функции gbm
отображается предупреждение. Чтобы обойти эту проблему, мы можем использовать пакет caret
с функцией train
. Эта функция может принимать множество различных моделей и автоматически проходит через параметры настройки.
library(caret) library(gbm) mdlboost <- caret::train(Type ~., data = traindf, method = 'gbm', verbose = FALSE) boostpreds <- predict(mdlboost, newdata = testdf) Accboost <- mean(boostpreds == testdf$Type) Accboost [1] 0.7142857
Байесовская аддитивная регрессия
Деревья байесовской аддитивной регрессии (BART) аналогичны ранее упомянутым моделям, создавая деревья с некоторыми случайными элементами, которые моделируют сигнал, не захваченный в предыдущих деревьях.
В первой итерации модели все деревья инициализируются одним и тем же корневым узлом. После очередной итерации поочередно обновляется каждое из k-х деревьев. Во время b-й итерации мы вычитаем предсказанные значения из каждого ответа, чтобы получить частичный остаток. i представляет каждую итерацию.
Вместо того, чтобы подгонять новое дерево к этому остатку, BART случайным образом выбирает дерево из предыдущей итерации (f^b-1), отдавая предпочтение деревьям, которые лучше подходят.
К сожалению, мне не удалось заставить какую-либо модель BART работать для этого примера классификации нескольких классов. Пакет bartMachine
не имеет реализации, а реализация пакета BART
мне не подходит. Все значения для меня возвращали NA. В пакете BART
также очень мало ресурсов для устранения неполадок.
Дерево решений как простая для понимания модель, но оно склонно к переподгонке данных. Сокращение требуется, чтобы уменьшить это, но также снизит точность (точность 50% для этого примера).
Затем модели ансамбля вводятся с помощью бэггинга, который усредняет группу деревьев, созданных на основе набора различных наблюдений. Это увеличивает нашу точность (66,67%). Это очень похоже на модель случайного леса, но вместо этого мы увеличиваем случайный элемент, чтобы включить выбранные функции (66,67%).
Окончательные модели создают деревья, которые строятся из ранее сгенерированных деревьев с повышением и деревом байесовской аддитивной регрессии. К сожалению, для модели BART результатов нет, но бустинг дает хорошие результаты (69,05%).
Таким образом, нет однозначного ответа, какая модель лучше, они используют очень похожие методы и дают схожие результаты. Я бы порекомендовал обучить их всех и определить, какие из них лучше всего работают с вашими данными.
Первоначально опубликовано на https://datasandbox.netlify.app 15 ноября 2022 г.