Дерево рішень у R - Дерево класифікації & Код на R із прикладом

Зміст:

Anonim

Що таке дерева прийняття рішень?

Дерева рішень - це універсальний алгоритм машинного навчання, який може виконувати як класифікаційні, так і регресійні завдання. Це дуже потужні алгоритми, здатні вмістити складні набори даних. Крім того, дерева рішень є фундаментальними компонентами випадкових лісів, які є одними з найпотужніших алгоритмів машинного навчання, доступних сьогодні.

Навчання та візуалізація дерев рішень

Щоб створити своє перше дерево рішень у прикладі R, ми будемо діяти, як зазначено в цьому посібнику з дерева рішень:

  • Крок 1: Імпортуйте дані
  • Крок 2: Очистіть набір даних
  • Крок 3: Створіть набір поїздів / тестів
  • Крок 4: Створіть модель
  • Крок 5: Зробіть прогноз
  • Крок 6: Виміряйте ефективність
  • Крок 7: Налаштуйте гіперпараметри

Крок 1) Імпортуйте дані

Якщо вам цікаво доля титаніка, ви можете переглянути це відео на Youtube. Метою цього набору даних є прогнозування того, які люди частіше виживають після зіткнення з айсбергом. Набір даних містить 13 змінних та 1309 спостережень. Набір даних упорядковується за змінною X.

set.seed(678)path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv'titanic <-read.csv(path)head(titanic)

Вихід:

## X pclass survived name sex## 1 1 1 1 Allen, Miss. Elisabeth Walton female## 2 2 1 1 Allison, Master. Hudson Trevor male## 3 3 1 0 Allison, Miss. Helen Loraine female## 4 4 1 0 Allison, Mr. Hudson Joshua Creighton male## 5 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female## 6 6 1 1 Anderson, Mr. Harry male## age sibsp parch ticket fare cabin embarked## 1 29.0000 0 0 24160 211.3375 B5 S## 2 0.9167 1 2 113781 151.5500 C22 C26 S## 3 2.0000 1 2 113781 151.5500 C22 C26 S## 4 30.0000 1 2 113781 151.5500 C22 C26 S## 5 25.0000 1 2 113781 151.5500 C22 C26 S## 6 48.0000 0 0 19952 26.5500 E12 S## home.dest## 1 St Louis, MO## 2 Montreal, PQ / Chesterville, ON## 3 Montreal, PQ / Chesterville, ON## 4 Montreal, PQ / Chesterville, ON## 5 Montreal, PQ / Chesterville, ON## 6 New York, NY
tail(titanic)

Вихід:

## X pclass survived name sex age sibsp## 1304 1304 3 0 Yousseff, Mr. Gerious male NA 0## 1305 1305 3 0 Zabour, Miss. Hileni female 14.5 1## 1306 1306 3 0 Zabour, Miss. Thamine female NA 1## 1307 1307 3 0 Zakarian, Mr. Mapriededer male 26.5 0## 1308 1308 3 0 Zakarian, Mr. Ortin male 27.0 0## 1309 1309 3 0 Zimmerman, Mr. Leo male 29.0 0## parch ticket fare cabin embarked home.dest## 1304 0 2627 14.4583 C## 1305 0 2665 14.4542 C## 1306 0 2665 14.4542 C## 1307 0 2656 7.2250 C## 1308 0 2670 7.2250 C## 1309 0 315082 7.8750 S

З виходу на голову та хвіст ви можете помітити, що дані не перемішуються. Це велике питання! Коли ви розділите свої дані між залізничним набором і тестовим набором, ви оберете лише пасажира з класу 1 і 2 (жоден пасажир з класу 3 не входить у топ-80 відсотків спостережень), що означає, що алгоритм ніколи не побачить особливості пасажира класу 3. Ця помилка призведе до поганого прогнозування.

Щоб подолати цю проблему, ви можете використовувати функцію sample ().

shuffle_index <- sample(1:nrow(titanic))head(shuffle_index)

Дерево рішень R код Пояснення

  • зразок (1: nrow (титанічний)): Створіть випадковий список індексу від 1 до 1309 (тобто максимальну кількість рядків).

Вихід:

## [1] 288 874 1078 633 887 992 

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

titanic <- titanic[shuffle_index, ]head(titanic)

Вихід:

## X pclass survived## 288 288 1 0## 874 874 3 0## 1078 1078 3 1## 633 633 3 0## 887 887 3 1## 992 992 3 1## name sex age## 288 Sutton, Mr. Frederick male 61## 874 Humblen, Mr. Adolf Mathias Nicolai Olsen male 42## 1078 O'Driscoll, Miss. Bridget female NA## 633 Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren) female 39## 887 Jermyn, Miss. Annie female NA## 992 Mamee, Mr. Hanna male NA## sibsp parch ticket fare cabin embarked home.dest## 288 0 0 36963 32.3208 D50 S Haddenfield, NJ## 874 0 0 348121 7.6500 F G63 S## 1078 0 0 14311 7.7500 Q## 633 1 5 347082 31.2750 S Sweden Winnipeg, MN## 887 0 0 14313 7.7500 Q## 992 0 0 2677 7.2292 C

Крок 2) Очистіть набір даних

Структура даних показує, що деякі змінні мають НС. Очищення даних здійснюється наступним чином

  • Викиньте змінні додому. Найстаріше, кабінка, ім'я, X та квиток
  • Створення змінних факторів для pclass та залишилися
  • Киньте НС
library(dplyr)# Drop variablesclean_titanic <- titanic % > %select(-c(home.dest, cabin, name, X, ticket)) % > %#Convert to factor levelmutate(pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')),survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes'))) % > %na.omit()glimpse(clean_titanic)

Пояснення коду

  • select (-c (home.dest, Cabin, name, X, квиток)): Видаліть непотрібні змінні
  • pclass = коефіцієнт (pclass, рівні = c (1,2,3), labels = c ('Upper', 'Middle', 'Lower')): Додайте мітку до змінної pclass 1 стає Верхнім, 2 стає MIddle, а 3 стає нижчим
  • коефіцієнт (вижив, рівні = c (0,1), мітки = c ('Ні', 'Так')): Додайте мітку до змінної "Вижив". 1 стає Ні, а 2 стає Так
  • na.omit (): Видалити спостереження НС

Вихід:

## Observations: 1,045## Variables: 8## $ pclass  Upper, Lower, Lower, Upper, Middle, Upper, Middle, U… ## $ survived  No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y… ## $ sex  male, male, female, female, male, male, female, male… ## $ age  61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0,… ## $ sibsp  0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,… ## $ parch  0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,… ## $ fare  32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542,… ## $ embarked  S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C… 

Крок 3) Створіть набір поїздів / тестів

Перш ніж тренувати свою модель, потрібно виконати два кроки:

  • Створіть поїзд і тест-комплект: Ви тренуєте модель на поїзді та перевіряєте прогноз на тестовому комплекті (тобто невидимі дані)
  • Встановіть rpart.plot із консолі

Типовою практикою є поділ даних на 80/20, 80 відсотків даних служить для навчання моделі, а 20 відсотків - для прогнозування. Вам потрібно створити два окремих кадри даних. Ви не хочете торкатися тестового набору, поки не закінчите побудову своєї моделі. Ви можете створити назву функції create_train_test (), яка приймає три аргументи.

create_train_test(df, size = 0.8, train = TRUE)arguments:-df: Dataset used to train the model.-size: Size of the split. By default, 0.8. Numerical value-train: If set to `TRUE`, the function creates the train set, otherwise the test set. Default value sets to `TRUE`. Boolean value.You need to add a Boolean parameter because R does not allow to return two data frames simultaneously.
create_train_test <- function(data, size = 0.8, train = TRUE) {n_row = nrow(data)total_row = size * n_rowtrain_sample < - 1: total_rowif (train == TRUE) {return (data[train_sample, ])} else {return (data[-train_sample, ])}}

Пояснення коду

  • функція (дані, розмір = 0,8, поїзд = ІСТИНА): Додайте аргументи у функцію
  • n_row = nrow (дані): підрахувати кількість рядків у наборі даних
  • total_row = size * n_row: Поверніть n-й рядок для побудови набору поїздів
  • train_sample <- 1: total_row: Виберіть перший рядок до n-их рядків
  • if (train == TRUE) {} else {}: Якщо умова має значення true, поверніть комплект поїздів, інакше тестовий набір.

Ви можете перевірити свою функцію та перевірити розмірність.

data_train <- create_train_test(clean_titanic, 0.8, train = TRUE)data_test <- create_train_test(clean_titanic, 0.8, train = FALSE)dim(data_train)

Вихід:

## [1] 836 8
dim(data_test)

Вихід:

## [1] 209 8 

Набір даних поїзда має 1046 рядків, тоді як тестовий набір даних має 262 рядки.

Ви використовуєте функцію prop.table () у поєднанні з таблицею (), щоб перевірити, чи правильний процес рандомізації.

prop.table(table(data_train$survived))

Вихід:

#### No Yes## 0.5944976 0.4055024
prop.table(table(data_test$survived))

Вихід:

#### No Yes## 0.5789474 0.4210526

В обох наборах даних кількість тих, хто вижив, однакова, приблизно 40 відсотків.

Встановіть rpart.plot

rpart.plot недоступний у бібліотеках conda. Ви можете встановити його з консолі:

install.packages("rpart.plot") 

Крок 4) Створення моделі

Ви готові побудувати модель. Синтаксис для функції дерева рішень Rpart є:

rpart(formula, data=, method='')arguments:- formula: The function to predict- data: Specifies the data frame- method:- "class" for a classification tree- "anova" for a regression tree

Ви використовуєте метод класу, оскільки передбачаєте клас.

library(rpart)library(rpart.plot)fit <- rpart(survived~., data = data_train, method = 'class')rpart.plot(fit, extra = 106

Пояснення коду

  • rpart (): Функція, яка відповідає моделі. Аргументи такі:
    • вижив ~ .: Формула дерев рішень
    • data = data_train: Набір даних
    • method = 'class': Підходить для двійкової моделі
  • rpart.plot (підходить, додатково = 106): Складіть дерево. Додаткові функції встановлені на 101 для відображення ймовірності 2-го класу (корисно для двійкових відповідей). Ви можете звернутися до віньєтки, щоб отримати додаткову інформацію про інші варіанти.

Вихід:

Ви починаєте з кореневого вузла (глибина від 0 до 3, верх графіку):

  1. У верхній частині це загальна ймовірність виживання. Це показує частку пасажирів, які пережили аварію. Вижив 41 відсоток пасажирів.
  2. Цей вузол запитує, чи є стать пасажира чоловічої статі. Якщо так, то ви спускаєтесь до лівого дочірнього вузла кореня (глибина 2). 63 відсотки - це чоловіки з вірогідністю виживання 21 відсоток.
  3. У другому вузлі ви запитаєте, чи пасажиру чоловічої старі більше 3,5 років. Якщо так, то шанс на виживання становить 19 відсотків.
  4. Ви продовжуєте рухатися так, щоб зрозуміти, які особливості впливають на ймовірність виживання.

Зауважте, що однією з багатьох якостей дерев рішень є те, що вони вимагають дуже мало підготовки даних. Зокрема, вони не вимагають масштабування чи центрування функцій.

За замовчуванням функція rpart () використовує міру домішки Джині для розділення ноти. Чим вище коефіцієнт Джині, тим більше різних випадків всередині вузла.

Крок 5) Зробіть прогноз

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

predict(fitted_model, df, type = 'class')arguments:- fitted_model: This is the object stored after model estimation.- df: Data frame used to make the prediction- type: Type of prediction- 'class': for classification- 'prob': to compute the probability of each class- 'vector': Predict the mean response at the node level

Ви хочете передбачити, які пасажири частіше виживають після зіткнення з тестового набору. Це означає, що серед тих 209 пасажирів ви знатимете, хто з них виживе чи ні.

predict_unseen <-predict(fit, data_test, type = 'class')

Пояснення коду

  • predict (fit, data_test, type = 'class'): передбачити клас (0/1) тестового набору

Тестування пасажира, який не встиг і тих, хто встиг.

table_mat <- table(data_test$survived, predict_unseen)table_mat

Пояснення коду

  • таблиця (data_test $ пережив, predict_unseen): Створіть таблицю, щоб підрахувати, скільки пасажирів класифіковано як вижили та померли порівняно з правильною класифікацією дерева рішень у R

Вихід:

## predict_unseen## No Yes## No 106 15## Yes 30 58

Модель правильно передбачила 106 загиблих пасажирів, але 15 вижилих класифікувала як мертвих. За аналогією, модель неправильно класифікувала 30 пасажирів як вижилих, поки вони виявились мертвими.

Крок 6) Виміряйте ефективність

Ви можете обчислити міру точності для завдання класифікації за допомогою матриці плутанини :

Матриця неточностей є кращим вибором для оцінки ефективності класифікації. Загальна ідея полягає в тому, щоб підрахувати, скільки разів справжні екземпляри класифікуються як False.

Кожен рядок у матриці плутанини представляє фактичну ціль, тоді як кожен стовпець - передбачену мету. Перший рядок цієї матриці розглядає мертвих пасажирів (клас False): 106 було правильно класифіковано як мертві ( справжнє негативне значення ), тоді як решта було помилково класифіковано як вижили ( помилково позитивне ). Другий ряд враховує тих, хто вижив, позитивний клас склав 58 ( справді позитивний ), тоді як справжній негативний - 30.

Ви можете обчислити тест на точність з матриці плутанини:

Це частка істинно позитивних та істинних негативних над сумою матриці. За допомогою R ви можете кодувати наступним чином:

accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)

Пояснення коду

  • sum (diag (table_mat)): Сума діагоналі
  • sum (table_mat): Сума матриці.

Ви можете роздрукувати точність тестового набору:

print(paste('Accuracy for test', accuracy_Test))

Вихід:

## [1] "Accuracy for test 0.784688995215311" 

У вас є 78 відсотків балів за тест. Ви можете повторити ту саму вправу за допомогою навчального набору даних.

Крок 7) Налаштуйте гіперпараметри

Дерево рішень у R має різні параметри, які контролюють аспекти підгонки. У бібліотеці дерева рішень rpart ви можете керувати параметрами за допомогою функції rpart.control (). У наступному коді ви вводите параметри, які ви налаштуєте. За іншими параметрами можна звернутися до віньєтки.

rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30)Arguments:-minsplit: Set the minimum number of observations in the node before the algorithm perform a split-minbucket: Set the minimum number of observations in the final note i.e. the leaf-maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0

Ми будемо діяти наступним чином:

  • Побудуйте функцію для повернення точності
  • Налаштуйте максимальну глибину
  • Налаштуйте мінімальну кількість вибірки, яку повинен мати вузол, перш ніж він може розділитися
  • Налаштуйте мінімальну кількість зразка, який повинен мати листовий вузол

Ви можете написати функцію для відображення точності. Ви просто обертаєте код, який використовували раніше:

  1. predict: predict_unseen <- predict (fit, data_test, type = 'class')
  2. Виробляти таблицю: table_mat <- таблиця (data_test $ пережито, predict_unseen)
  3. Точність обчислення: точність_Test <- сума (діагност (таблиця_мат)) / сума (таблиця_мат)
accuracy_tune <- function(fit) {predict_unseen <- predict(fit, data_test, type = 'class')table_mat <- table(data_test$survived, predict_unseen)accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)accuracy_Test}

Ви можете спробувати налаштувати параметри і подивитися, чи зможете ви покращити модель порівняно зі значенням за замовчуванням. Нагадуємо, вам потрібно отримати точність вище 0,78

control <- rpart.control(minsplit = 4,minbucket = round(5 / 3),maxdepth = 3,cp = 0)tune_fit <- rpart(survived~., data = data_train, method = 'class', control = control)accuracy_tune(tune_fit)

Вихід:

## [1] 0.7990431 

З наступним параметром:

minsplit = 4minbucket= round(5/3)maxdepth = 3cp=0 

Ви отримуєте вищу продуктивність, ніж попередня модель. Вітаємо!

Резюме

Ми можемо узагальнити функції для навчання алгоритму дерева рішень у R

Бібліотека

Об’єктивна

функція

клас

параметри

деталі

rpart

Дерево класифікації поїздів у R

rpart ()

клас

формула, df, метод

rpart

Тренуйте дерево регресії

rpart ()

anova

формула, df, метод

rpart

Побудувати ділянки дерев

rpart.plot ()

приталена модель

база

передбачити

передбачити ()

клас

приталена модель, тип

база

передбачити

передбачити ()

проб

приталена модель, тип

база

передбачити

передбачити ()

вектор

приталена модель, тип

rpart

Параметри управління

rpart.control ()

мінспліт

Встановіть мінімальну кількість спостережень у вузлі, перш ніж алгоритм виконуватиме розділення

minbucket

В кінцевій записці встановіть мінімальну кількість спостережень, тобто аркуша

максимальна глибина

Встановіть максимальну глибину будь-якого вузла остаточного дерева. Кореневий вузол обробляється глибиною 0

rpart

Модель поїзда з контрольним параметром

rpart ()

формула, df, метод, контроль

Примітка: Навчіть модель на навчальних даних та протестуйте ефективність на невидимому наборі даних, тобто наборі тестів.