Pendahuluan
Classification and Regression Tree (CART) adalah metode pembelajaran mesin yang digunakan untuk membuat model pembelajaran agar menghasilkan model prediksi. Pohonini dapat digunakan untuk pemodelan klasifikasi (memprediksi kategori atau label) dan pemodelan regresi (memprediksi nilai kontinu).
Dalam pohon klasifikasi, setiap node menunjukkan tes kondisi pada fitur, dan setiap cabang menunjukkan hasil dari tes tersebut. Leaf node atau daun pohon menunjukkan prediksi target.
Pohon klasifikasi adalah salah satu metode pembelajaran mesin yang mudah dipahami dan diterapkan, karena visualisasi pohonnya mempermudah pemahaman dan interpretasi model.
Kegunaan
Pohon klasifikasi memiliki beberapa kegunaan utama, di antaranya adalah:
Mudah dipahami: Pohon klasifikasi memiliki visualisasi yang jelas dan mudah dipahami, sehingga mempermudah pemahaman dan interpretasi model.
Diterapkan pada berbagai jenis data: Pohon klasifikasi dapat diterapkan pada berbagai jenis data, seperti data numerik, data kategorik, dan data mix, sehingga sangat versatile.
Efektif untuk memecahkan masalah klasifikasi: Dengan menggunakan metode pemutusan, pohon klasifikasi memecahkan masalah klasifikasi menjadi sub-masalah yang lebih kecil dan lebih mudah diterapkan.
Membuat model yang akurat: Pohon klasifikasi memiliki kemampuan untuk membuat model yang akurat dan berguna untuk memprediksi target.
Efisien: Pohon klasifikasi memiliki proses pembelajaran yang efisien dan cepat, sehingga cocok untuk data dengan jumlah variabel yang besar atau data dengan jumlah sampel yang besar.
Menghandle missing values: Pohon klasifikasi dapat menangani missing values dengan mengabaikan sample yang memiliki missing values atau dengan memberikan bobot pada sample yang memiliki missing values.
Dapat melakukan pruning: Pohon klasifikasi dapat dilakukan pruning atau pemangkasan untuk membuat model lebih sederhana dan akurat.
Komponen
Terdapat beberapa komponen utama dalam pohon klasifikasi, yaitu:
Root node: Node pertama dan node teratas dalam suatu pohon klasifikasi. Ini adalah titik awal dari alur klasifikasi dan memiliki beberapa cabang yang mengarah ke node lain dalam pohon. Root node menggambarkan kategori umum yang digunakan untuk memulai proses klasifikasi.
Intermediate node: Node ini adalah node yang berada di antara root node dan leaf node. Intermediate node berfungsi sebagai titik pemisahan untuk memisahkan data menjadi kelompok yang lebih kecil dan lebih spesifik. Masing-masing intermediate node memiliki atribut atau kriteria tertentu yang digunakan untuk memisahkan data yang berasal dari node sebelumnya. Intermediate node memainkan peran penting dalam pohon klasifikasi karena membantu untuk memperkecil skala data dan membuat alur klasifikasi lebih mudah dipahami dan diinterpretasikan. Ini juga memungkinkan untuk menentukan atribut yang paling penting dalam memprediksi label akhir dari suatu data.
Leaf node: Node ini adalah node yang berada di paling bawah pohon dan menunjukkan prediksi akhir. Leaf node merupakan node yang tidak memiliki cabang dan merupakan tempat dimana data diklasifikasikan ke dalam kelompok yang homogen. Setiap leaf node menggambarkan suatu label atau kategori akhir yang diterapkan pada set data yang diklasifikasikan ke dalam leaf node tersebut.
Branch: Branch adalah cabang atau jalur yang menghubungkan node satu dengan node lain dalam pohon. Setiap node dalam pohon memiliki beberapa cabang yang mengarah ke node lain dalam pohon, membantu untuk memisahkan data menjadi kelompok yang lebih kecil dan lebih spesifik. Branch menggambarkan pemisahan data berdasarkan atribut atau kriteria tertentu yang diterapkan pada setiap node.
Attribute: Fitur atau karakteristik dari suatu data yang digunakan dalam pohon klasifikasi untuk membuat pemisahan dan memprediksi label akhir. Attribute ini seringkali berupa variabel diskrit atau variabel kontinu dan digunakan untuk memisahkan data menjadi subkelompok yang lebih kecil. Pada setiap node dalam pohon klasifikasi, salah satu atribut dipilih untuk memisahkan data menjadi subkelompok yang lebih kecil. Attribute yang dipilih untuk setiap node ditentukan oleh kriteria pemisahan yang digunakan, seperti entropy, gain ratio, atau gain information.
Splitting criteria: Kriteria yang digunakan dalam pohon klasifikasi untuk memutuskan bagaimana data harus dibagi menjadi subkelompok yang lebih kecil pada setiap node. Kriteria ini menentukan atribut atau fitur mana yang digunakan untuk memisahkan data pada setiap node dan membantu untuk memperkecil skala data serta membuat alur klasifikasi lebih mudah dipahami dan diinterpretasikan. Beberapa kriteria pemisahan yang sering digunakan dalam pohon klasifikasi termasuk entropy, gain ratio, dan gain information. Kriteria ini menentukan kepentingan atribut dan membantu untuk menentukan atribut yang paling berguna dalam memprediksi label akhir dari suatu data.
Decision rules: Aturan atau prosedur yang digunakan untuk memprediksi label akhir suatu data berdasarkan fitur atau atribut data tersebut. Decision rules dapat diambil dari setiap cabang dalam pohon klasifikasi dan merupakan pernyataan logika yang menentukan apakah data akan diklasifikasikan ke dalam satu label atau label lain. Contoh decision rule pada pohon klasifikasi adalah: “Jika usia < 30 tahun dan pendapatan < $50,000, maka klasifikasikan sebagai ‘tidak memiliki cicilan rumah’. Jika tidak, maka klasifikasikan sebagai ‘memiliki cicilan rumah’.”
Pruning: Proses memangkas atau menghilangkan cabang yang tidak penting atau kurang berguna dari pohon klasifikasi. Ini membantu untuk menghindari overfitting, yaitu situasi di mana pohon klasifikasi menjadi terlalu kompleks dan terlalu menyesuaikan dengan data pelatihan, sehingga membuatnya kurang efektif untuk memprediksi data baru. Prinsip dasar dari pruning adalah bahwa pohon klasifikasi yang lebih sederhana seringkali memiliki tingkat akurasi yang lebih tinggi dibandingkan dengan pohon klasifikasi yang lebih kompleks. Dalam hal ini, cabang yang dihilangkan adalah cabang yang memiliki pengaruh minimal pada akurasi klasifikasi.
Algoritma Dasar Pohon Klasifikasi
Tahap 1: Mencari pemisahan/penyekatan (splitting) terbaik dari setiap variabel.
Tahap 2: Menentukan variabel terbaik untuk penyekatan.
Tahap 3: Melakukan penyekatan berdasarkan hasil dari Tahap 2, dan memeriksa apakah sudah waktunya menghentikan proses.
Ketiga tahapan tersebut dilakukan untuk setiap simpul (node) dan hasil sekatannya.
Proses pemisahan akan berhenti jika tercapai salah satu kriteria:
- Simpul berisi amatan yang berasal dari satu kelas variabel respon. Misalnya semuanya Yes atau semuanya No.
- Simpul berisi amatan yang seluruh variabel prediktornya identik. Misalnya semuanya usianya sama 20 tahun, jenis kelamin sama, pekerjaan sama.
- Simpul berisi amatan yang kurang dari ukuran simpul minimal yang
ditentukan di awal. Pada fungsi
rpart()ditentukan menggunakan opsiminsplitdanminbucket - Kedalaman pohon sudah mencapai kedalaman maksimal. Pada fungsi
rpart()ditentukan menggunakan fungsimaxdepth(berapa banyak level yang digunakan untuk membangun model).
Entropy dan Information Gain
Entropy dan Information Gain adalah dua konsep yang penting dalam pohon klasifikasi. Kedua konsep ini digunakan untuk mengukur ketidakpastian dan seberapa banyak informasi baru yang diperoleh setelah memisahkan data berdasarkan fitur tertentu.
Entropy: Ukuran ketidakpastian dalam set data. Nilai entropy berkisar antara 0 (data memiliki kepastian maksimal) dan 1 (data memiliki kepastian minimal). Entropy digunakan untuk menentukan seberapa efektif fitur tertentu dalam memisahkan data menjadi kelas yang berbeda.
Information Gain: Ukuran seberapa banyak informasi baru yang diperoleh setelah memisahkan data berdasarkan fitur tertentu. Nilai information gain berkisar antara 0 (tidak ada informasi baru yang diperoleh) dan 1 (informasi baru maksimal yang diperoleh). Fitur dengan information gain tertinggi dipilih sebagai fitur pemisahan pada node tertentu.
Kedua konsep ini digunakan bersama-sama dalam algoritma pohon klasifikasi untuk membuat aturan pemisahan yang membantu menentukan kelas dari data baru. Algoritma akan memilih fitur dengan entropy terendah atau information gain tertinggi sebagai fitur pemisahan pada setiap node, sehingga set data akan terpisah menjadi subsets yang lebih kecil dan lebih homogen dalam kelas target.
Andaikan sebuah gugus data D berisi individu-individu dengan dua kelas yaitu kelas YES dan NO, dengan proporsi YES sebesar p, dan NO sebesar (1-p).
Entropi dari gugus data tersebut adalah: \[E(D) = -p\ log_{2}(p)-(1-p)\log_{2}(1-p)\]Gugus data yang seluruh amatannya dari kelas YES akan memiliki E(D) = 0. Gugus data yang seluruh amatannya dari kelas NO juga akan memiliki E(D) = 0. Entropi ini adalah ukuran keheterogenan data (impurity).
Berikutnya andaikan sebuah gugus data D dibagi menjadi beberapa kelompik, misalnya D1, D2, …, Dk berdasarkan variabel prediktor V, maka setiap \(D_{i}\) bisa dihitung entropinya yaitu \(E(D_{i})\).
Information Gain: \[IG(D,V)=E(D)-\sum_{i=1}^{k} \frac{|D_{i}|}{|D|}E(D_{i})\] Pemisahan yang menghasilkan kelompok-kelompok yang homogen adalah yang memiliki information gain yang semakin besar.
Ilustrasi
pendidikan <- c("Rendah","Rendah","Sedang","Sedang","Tinggi","Tinggi","Sedang","Rendah","Tinggi","Sedang")
usia <- c(40,35,45,30,35,40,30,45,40,40)
membeli <- c("Ya","Tidak","Ya","Tidak","Tidak","Ya","Ya","Ya","Ya","Tidak")
ilustrasi <- data.frame(pendidikan,usia,membeli)
ilustrasi
#Fungsi Information Gain
InformationGain <- function(n.awal,n1.awal, n.bag1, n1.bag1){
p1.awal <- n1.awal/n.awal
p2.awal <- 1-p1.awal
ED.awal <- (-p1.awal*log2(p1.awal))-(p2.awal*log2(p2.awal))
p1.bag1 <- n1.bag1/n.bag1
p2.bag1 <- 1-p1.bag1
ED.bag1 <- (-p1.bag1*log2(p1.bag1))-(p2.bag1*log2(p2.bag1))
if (ED.bag1=="NaN") {
ED.bag1 = 0
}
n.bag2 <- n.awal- n.bag1
n1.bag2 <- n1.awal- n1.bag1
p1.bag2 <- n1.bag2/n.bag2
p2.bag2 <- 1-p1.bag2
ED.bag2 <- (-p1.bag2*log2(p1.bag2))-(p2.bag2*log2(p2.bag2))
if (ED.bag2=="NaN") {
ED.bag2 = 0
}
IG <- ED.awal - ((n.bag1/n.awal)*ED.bag1)-((n.bag2/n.awal)*ED.bag2)
return(IG)
}
Tahap 1:
Mencari pemisahan partisi terbaik untuk variable
pendidikan. Kemungkinan paritisi:
-
Rendah vs Sedang, Tinggi
#Rendah vs Sedang,Tinggi InformationGain(10, 6,3,2)## [1] 0.005802149 -
Rendah, Sedang vs Tinggi
#Rendah Sedang vs Tinggi InformationGain(10, 6,6,4)## [1] 0.01997309
Partisi terbaik adalah yang kedua karena mempunyai information gain yang lebih tinggi atau paling besar.
Berikutnya mencari pemisahan partisi terbaik untuk variabel
usia. Kemungkinan partisi:
-
Usia <= 30 vs Usia > 30
#Usia <= 30 vs Usia>30 InformationGain(10, 6,2,1)## [1] 0.007403392 -
Usia <= 35 vs Usia > 35
#Usia <= 35 vs Usia>35 InformationGain(10,6,4,1)## [1] 0.2564259 -
Usia <= 40 vs Usia > 40
#Usia <= 40 vs Usia>40 InformationGain(10,6,8,4)## [1] 0.1709506
Partisi terbaik adalah yang kedua karena mempunyai information gain yang lebih tinggi atau paling besar.
Tahap 2:
Membandingkan variabel pemisah antara pendidikan dan
usia .
Terbaik untuk pendidikan: Rendah, Sedang vs Tinggi
dengan IG = 0.01997309. Terbaik untuk usia: Usia <= 35
vs Usia > 35 dengan IG = 0.2564259. Information gain tertinggi adalah
usia sehingga dipilih variabel usia pada
partisi pertama.
Tahap 3:
Melakukan penyekatan simpul berdasarkan usia (dengan
batas 35 tahun). Akan ada simpul baru yang diperoleh berdasarkan
penyekatan tersebut. Selanjutnya tahap 1, 2, dan 3 diulang kembali.
Hiperparameter
Dalam membangun pohon klasifikasi, terdapat beberapa parameter atau hyperparameter yang perlu ditentukan untuk membuat model tersebut menjadi optimal. Berikut adalah beberapa hyperparameter penting pada pohon klasifikasi:
Maximum Depth: Ini adalah parameter yang menentukan maksimal kedalaman pohon. Nilai yang lebih besar akan menghasilkan pohon yang lebih kompleks, tetapi juga memiliki risiko overfitting.
Minimum Samples per Leaf: Ini adalah parameter yang menentukan jumlah minimum sampel data pada setiap daun. Nilai yang lebih besar akan membuat model lebih stabil, tetapi juga akan menghasilkan pohon yang lebih sederhana.
Minimum Samples per Split: Ini adalah parameter yang menentukan jumlah minimum sampel data yang diperlukan untuk membuat split pada pohon. Nilai yang lebih besar akan membuat model lebih stabil, tetapi juga akan menghasilkan pohon yang lebih sederhana.
Maximum Features: Ini adalah parameter yang menentukan jumlah maksimal fitur yang digunakan pada setiap split. Nilai yang lebih kecil akan membuat model lebih stabil, tetapi juga akan menghasilkan pohon yang lebih sederhana.
Maximum Leaf Nodes: Ini adalah parameter yang menentukan jumlah maksimal daun pada pohon. Nilai yang lebih besar akan menghasilkan pohon yang lebih kompleks, tetapi juga memiliki risiko overfitting.
Menilai Kemampuan Prediksi
Ada beberapa metrik yang dapat digunakan untuk menilai kemampuan prediksi dari suatu model pohon klasifikasi, di antaranya adalah:
Akurasi (Accuracy): Akurasi adalah salah satu ukuran yang digunakan untuk menilai kinerja dari sebuah model klasifikasi. Ini mengukur seberapa baik model tersebut mengklasifikasikan data baru dengan benar. Akurasi didefinisikan sebagai rasio jumlah prediksi yang benar terhadap jumlah total prediksi yang dibuat oleh model.
Precision: mengukur seberapa sering model membuat prediksi positif yang benar. Precision didefinisikan sebagai rasio jumlah prediksi positif yang benar terhadap jumlah total prediksi positif yang dibuat oleh model.
Recall/Sensitivity: Recall digunakan untuk mengukur seberapa baik model tersebut menemukan seluruh kelas positif yang ada. Recall didefinisikan sebagai rasio jumlah kelas positif yang benar terdeteksi oleh model terhadap jumlah total kelas positif dalam data.
Specificity: Digunakan untuk mengukur seberapa baik model tersebut membedakan antara kelas negatif dan kelas positif. Specificity didefinisikan sebagai rasio jumlah kelas negatif yang benar terdeteksi oleh model terhadap jumlah total kelas negatif dalam data.
F1 Score: mengukur keseimbangan antara precision dan recall. F1 Score dihitung sebagai rasio 2 * (precision * recall) / (precision + recall). Jika precision dan recall bernilai tinggi, maka F1-score juga akan tinggi, yang menunjukkan bahwa model memiliki kinerja yang baik dalam memprediksi kelas positif dan menemukan kelas positif yang sebenarnya.
Confusion Matrix: merupakan tabel yang menunjukkan jumlah instance yang diklasifikasikan dengan benar dan salah. Matrix ini menunjukkan jumlah True Positive (TP), False Positive (FP), False Negative (FN), dan True Negative (TN).
AUC (Area Under the Curve) ROC (Receiver Operating Characteristic): mengukur kemampuan model dalam membedakan antara instance positif dan negatif. AUC ROC adalah area di bawah kurva ROC.
Pemodelan
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyverse)
## ── Attaching packages
## ───────────────────────────────────────
## tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0 ✔ purrr 0.3.5
## ✔ tibble 3.1.8 ✔ stringr 1.4.1
## ✔ tidyr 1.2.1 ✔ forcats 0.5.2
## ✔ readr 2.1.3
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
# For decision tree model
library(rpart)
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
##
## The following object is masked from 'package:purrr':
##
## lift
# For data visualization
library(rpart.plot)
library(ROCR)
# Contains the data
library(ISLR)
# Get the list of data sets contained in package
d <- data(package = "ISLR")
d$results[, "Item"]
## [1] "Auto" "Caravan" "Carseats" "College" "Credit" "Default"
## [7] "Hitters" "Khan" "NCI60" "OJ" "Portfolio" "Smarket"
## [13] "Wage" "Weekly"
data(Carseats)
# Get the variable names
str(Carseats)
## 'data.frame': 400 obs. of 11 variables:
## $ Sales : num 9.5 11.22 10.06 7.4 4.15 ...
## $ CompPrice : num 138 111 113 117 141 124 115 136 132 132 ...
## $ Income : num 73 48 35 100 64 113 105 81 110 113 ...
## $ Advertising: num 11 16 10 4 3 13 0 15 0 0 ...
## $ Population : num 276 260 269 466 340 501 45 425 108 131 ...
## $ Price : num 120 83 80 97 128 72 108 120 124 124 ...
## $ ShelveLoc : Factor w/ 3 levels "Bad","Good","Medium": 1 2 3 3 1 1 3 2 3 3 ...
## $ Age : num 42 65 59 55 38 78 71 67 76 76 ...
## $ Education : num 17 10 12 14 13 16 15 10 10 17 ...
## $ Urban : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 2 2 1 1 ...
## $ US : Factor w/ 2 levels "No","Yes": 2 2 2 2 1 2 1 2 1 2 ...
Kita akan menggunakan pohon klasifikasi untuk menganalisis data kursi
mobil (Carseats). Kumpulan data merupakan simulasi dari
penjualan kursi mobil di 400 toko yang berbeda. ada 400 pengamatan dan
11 variabel dalam dataset. Kita akan memprediksi Sales
berdasarkan variabel lainnya. Namun, karena Sales merupakan
variabel kontinu, maka kita perlu mengodekannya kembali sebagai variabel
biner. Variabel baru diberi nama High yang berisi nilai Yes
jika variabel Sales melebihi $8 dan No kurang dari atau
sama dengan $8.
# Creates a new binary variable, High.
High = ifelse(Carseats$Sales <=8, "No", "Yes")
# Add High to the data set.
Carseats=data.frame(Carseats,High)
# Remove the Sales variable from the data.
Carseats.H <- Carseats[,-1]
# Code High as a factor variable
Carseats.H$High = as.factor(Carseats$High)
class(Carseats.H$High)
## [1] "factor"
Pengklasifikasian yang baik adalah yang memiliki tingkat kesalahan pengujian yang paling kecil. Untuk mengevaluasi kinerja pohon klasifikasi, maka dataset dibagi menjadi data latih (Carseats.train) sebesar 70% dan data uji (Carseats.test) sebesar 30%.
set.seed(234)
train <- createDataPartition(as.factor(Carseats.H$High), p=0.7, list=FALSE)
#train = sample(1:nrow(Carseats.H), 200)
Carseats.train=Carseats.H[train,]
Carseats.test=Carseats.H[-train,]
High.test=High[-train]
Kita akan membuat pohon klasifikasi menggunakan data latih untuk
memprediksi variabel High menggunakan semua variabel
kecuali Sales.
fit.tree = rpart(High ~ ., data=Carseats.train, method = "class", cp=0.008)
fit.tree
## n= 281
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 281 115 No (0.59074733 0.40925267)
## 2) ShelveLoc=Bad,Medium 220 67 No (0.69545455 0.30454545)
## 4) Price>=106.5 144 27 No (0.81250000 0.18750000)
## 8) CompPrice< 124.5 47 1 No (0.97872340 0.02127660) *
## 9) CompPrice>=124.5 97 26 No (0.73195876 0.26804124)
## 18) Price>=126.5 52 6 No (0.88461538 0.11538462) *
## 19) Price< 126.5 45 20 No (0.55555556 0.44444444)
## 38) Advertising< 5 26 5 No (0.80769231 0.19230769)
## 76) Age>=37.5 19 1 No (0.94736842 0.05263158) *
## 77) Age< 37.5 7 3 Yes (0.42857143 0.57142857) *
## 39) Advertising>=5 19 4 Yes (0.21052632 0.78947368) *
## 5) Price< 106.5 76 36 Yes (0.47368421 0.52631579)
## 10) CompPrice< 123.5 56 22 No (0.60714286 0.39285714)
## 20) Price>=92 35 8 No (0.77142857 0.22857143) *
## 21) Price< 92 21 7 Yes (0.33333333 0.66666667)
## 42) ShelveLoc=Bad 7 2 No (0.71428571 0.28571429) *
## 43) ShelveLoc=Medium 14 2 Yes (0.14285714 0.85714286) *
## 11) CompPrice>=123.5 20 2 Yes (0.10000000 0.90000000) *
## 3) ShelveLoc=Good 61 13 Yes (0.21311475 0.78688525)
## 6) Price>=135 10 2 No (0.80000000 0.20000000) *
## 7) Price< 135 51 5 Yes (0.09803922 0.90196078) *
Method merupakan argumen yang dapat dimodifikasi atau dipilih berdasarkan tipe data dari variable respon. Class digunakan untuk tipe kategorik/faktor, anova digunakan untuk tipe numerik, poisson untuk count, dan exp untuk survival data.
CP merupakan nilai numerik yang diberikan untuk menentukan seberapa dalam kita ingin menumbuhkan pohon. Semakin kecil nilainya (mendekati 0), maka akan semakin besar pohonnya. Nilai defaultnya adalah 0.01.
# Visualizing the unpruned tree
rpart.plot(fit.tree)
Plot pohon di atas menunjukkan variabel yang digunakan untuk
membangun pohon. Pohon yang dipilih berisi 5 variabel dengan 10
pemisahan. Variabel yang digunakan adalah ShelveLoc,
Price, CompPrice, Advertising,
dan Age.
Dari model tersebut dapat kita lihat bahwa indikator
Sales yang paling penting tampaknya adalah
ShelveLoc karena cabang pertama membedakan lokasi
Good versus lokasi Bad, Medium. Indikator penting berikutnya
adalah Price, karena cabang kedua membedakan harga
lebih besar dari sama dengan $106.5 versus harga kurang dari
$106.5.
Node 2 dan 3 dibentuk dengan memisahkan node 1, root node, pada
variabel prediktor ShelveLoc. Titik perpecahannya adalah
ShelveLoc=Bad,Medium; yaitu, simpul 2 terdiri dari semua amatan dengan
nilai ShelveLoc=Bad,Medium dan simpul 3 terdiri dari semua amatan dengan
ShelveLoc=Good. Kelas yang diprediksi untuk node 2 adalah No, di mana No
menunjukkan penjualan kurang dari sama dengan $8. Terdapat loss
sebesar 67 yang artinya akan ada sebanyak 67 amatan yang akan
salah diklasifikasi jika kelas yang diprediksi untuk node tersebut
diterapkan ke semua amatan. Secara khusus, dari total 220 amatan,
67 (30.45%) akan salah klasifikasi dan 153 (69.55%) akan
diklasifikasikan dengan benar.
Simpul 4 adalah amatan yang memiliki Price >= $106.5. Kelas yang diprediksi untuk simpul 4 adalah No yang menunjukkan penjualan kurang dari atau sama dengan $8. Terdapat loss sebesar 27 - yaitu, 27 baris akan salah diklasifikasi jika kelas prediksi untuk node tersebut diterapkan ke semua amatan. Dari total 144 amatan, 27 (18.75%) akan salah klasifikasi dan 117 (81.25%) akan diklasifikasikan dengan benar.
# Checking the order of variable importance
fit.tree$variable.importance
## Price ShelveLoc CompPrice Advertising Age US
## 32.606554 25.269580 19.567088 10.070289 5.965618 4.944953
## Population Education Income
## 4.303901 3.899715 2.426726
fit.tree$variable.importance %>%
data.frame() %>%
rownames_to_column(var = "Feature") %>%
rename(Overall = '.') %>%
ggplot(aes(x = fct_reorder(Feature, Overall), y = Overall)) +
geom_pointrange(aes(ymin = 0, ymax = Overall), color = "cadetblue", size = .3) +
theme_minimal() +
coord_flip() +
labs(x = "", y = "", title = "Variable Importance with Simple Classication")
Prediksi dengan Pohon Klasifikasi
Berikutnya kita akan menggunakan model pohon klasifikasi yang telah
didapat dari data latih kepada data uji. Kita akan menggunakan fungsi
predict() untuk memprediksi variabel High.
Meskipun model dapat menghasilkan prediksi yang baik pada data latih,
tetap akan ada kemungkinan model bisa menghasilkan prediksi atau kinerja
yang buruk pada data uji. Artinya, pohon yang dihasilkan mungkin terlalu
rumit.
Pohon yang lebih kecil dengan pemisahan yang lebih sedikit akan menghasilkan varians yang lebih rendah dan interpretasi yang lebih baik dengan bias yang kecil.
pred.tree = predict(fit.tree, Carseats.test, type = "class")
Evaluasi Performa Pohon Klasifikasi
table(pred.tree,High.test)
## High.test
## pred.tree No Yes
## No 60 18
## Yes 10 31
matriks_kesalahan <- confusionMatrix(pred.tree, Carseats.test$High)
matriks_kesalahan
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 60 18
## Yes 10 31
##
## Accuracy : 0.7647
## 95% CI : (0.6782, 0.8376)
## No Information Rate : 0.5882
## P-Value [Acc > NIR] : 4.053e-05
##
## Kappa : 0.5021
##
## Mcnemar's Test P-Value : 0.1859
##
## Sensitivity : 0.8571
## Specificity : 0.6327
## Pos Pred Value : 0.7692
## Neg Pred Value : 0.7561
## Prevalence : 0.5882
## Detection Rate : 0.5042
## Detection Prevalence : 0.6555
## Balanced Accuracy : 0.7449
##
## 'Positive' Class : No
##
Dapat dilihat bahwa tingkat kesalahan klasifikasi adalah 23.53%, dihitung dari (18+10)/119. Ini berarti bahwa model menghasilkan prediksi yang benar sebesar 76.47% pengamatan dalam data uji, atau bisa juga dilihat dari nilai accuracy.
Berikutnya kita dapat melakukan proses Pruning (pemangkasan) untuk melihat apakah dapat memberikan hasil yang lebih baik. Kita akan melihat apakah pemangkasan akan menghasilkan persentase kesalahan klasifikasi yang lebih rendah dan prediksi yang benar dengan persentase yang lebih tinggi. Pemangkasan memilih nilai cp (parameter kompleksitas) yang terkait dengan pohon yang lebih pendek yang meminimalkan tingkat kesalahan validasi silang (xerror). Dari tabel di bawah ini, kita dapat memilih nilai cp yang menghasilkan kesalahan validasi silang (xerror) terendah. Nilai cp terendah adalah 0,008695652 dan memiliki pohon dengan 9 split.
#plotcp(fit.tree)
printcp(fit.tree)
##
## Classification tree:
## rpart(formula = High ~ ., data = Carseats.train, method = "class",
## cp = 0.008)
##
## Variables actually used in tree construction:
## [1] Advertising Age CompPrice Price ShelveLoc
##
## Root node error: 115/281 = 0.40925
##
## n= 281
##
## CP nsplit rel error xerror xstd
## 1 0.3043478 0 1.00000 1.00000 0.071672
## 2 0.0695652 1 0.69565 0.69565 0.065780
## 3 0.0608696 3 0.55652 0.65217 0.064478
## 4 0.0521739 4 0.49565 0.65217 0.064478
## 5 0.0318841 5 0.44348 0.56522 0.061466
## 6 0.0260870 8 0.34783 0.53913 0.060446
## 7 0.0086957 9 0.32174 0.53043 0.060093
## 8 0.0080000 10 0.31304 0.53913 0.060446
# Explicitly request the lowest cp value
fit.tree$cptable[which.min(fit.tree$cptable[,"xerror"]),"CP"]
## [1] 0.008695652
plotcp(fit.tree, upper = "splits")
Berikutnya kita akan membuat pohon yang dipangkas dengan menggunakan
data latih. Model pohon yang dipangkas berisi 4 variabel yaitu
ShelveLoc, Price, CompPrice, dan
Advertising dengan 9 pemisahan.
bestcp <-fit.tree$cptable[which.min(fit.tree$cptable[,"xerror"]),"CP"]
pruned.tree <- prune(fit.tree, cp = bestcp)
rpart.plot(pruned.tree)
Menggunakan Pohon yang dipangkas untuk memprediksi data uji dan mengevaluasi performa pohon.
# Alternate specification
pred.prune = predict(pruned.tree, Carseats.test, type="class")
table(pred.prune, High.test)
## High.test
## pred.prune No Yes
## No 60 19
## Yes 10 30
matriks_kesalahan <- confusionMatrix(pred.prune, Carseats.test$High)
matriks_kesalahan
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 60 19
## Yes 10 30
##
## Accuracy : 0.7563
## 95% CI : (0.6691, 0.8303)
## No Information Rate : 0.5882
## P-Value [Acc > NIR] : 9.208e-05
##
## Kappa : 0.4827
##
## Mcnemar's Test P-Value : 0.1374
##
## Sensitivity : 0.8571
## Specificity : 0.6122
## Pos Pred Value : 0.7595
## Neg Pred Value : 0.7500
## Prevalence : 0.5882
## Detection Rate : 0.5042
## Detection Prevalence : 0.6639
## Balanced Accuracy : 0.7347
##
## 'Positive' Class : No
##
Berdasarkan pohon yang telah dipangkas, sekarang hanya 75.63% dari pengamatan uji yang diklasifikasikan dengan benar, sehingga tingkat kesalahan klasifikasi adalah 24.37%. Sedangkan pohon yang belum dipangkas memiliki tingkat kesalahan klasifikasi sebesar 23.53%. Oleh karena itu, model yang dipangkas menghasilkan peningkatan bias yang diukur dengan tingkat kesalahan pengujian. Akibatnya, kita akan memilih pohon yang lebih besar dan tidak dipangkas karena tingkat kesalahan pengujian lebih rendah daripada tingkat kesalahan pengujian pohon yang dipangkas. Ingatlah bahwa pengklasifikasi yang baik adalah yang kesalahan pengujiannya paling kecil. Contoh ini menunjukkan bahwa pemangkasan tidak selalu efektif dalam mengurangi bias. Penting untuk dicatat bahwa kita dapat memilih pohon yang dipangkas jika interpretabilitas lebih penting daripada bias yang lebih rendah.
carseat_preds_cart <- bind_cols(
predict(pruned.tree, newdata = Carseats.test, type = "prob"),
predicted = predict(pruned.tree, newdata = Carseats.test, type = "class"),
actual = Carseats.test$High
)
carseat_cm_cart <- confusionMatrix(carseat_preds_cart$predicted, reference = carseat_preds_cart$actual)
carseat_cm_cart
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 60 19
## Yes 10 30
##
## Accuracy : 0.7563
## 95% CI : (0.6691, 0.8303)
## No Information Rate : 0.5882
## P-Value [Acc > NIR] : 9.208e-05
##
## Kappa : 0.4827
##
## Mcnemar's Test P-Value : 0.1374
##
## Sensitivity : 0.8571
## Specificity : 0.6122
## Pos Pred Value : 0.7595
## Neg Pred Value : 0.7500
## Prevalence : 0.5882
## Detection Rate : 0.5042
## Detection Prevalence : 0.6639
## Balanced Accuracy : 0.7347
##
## 'Positive' Class : No
##
library(yardstick)
## For binary classification, the first factor level is assumed to be the event.
## Use the argument `event_level = "second"` to alter this as needed.
##
## Attaching package: 'yardstick'
## The following objects are masked from 'package:caret':
##
## precision, recall, sensitivity, specificity
## The following object is masked from 'package:readr':
##
## spec
mdl_auc <- Metrics::auc(actual = carseat_preds_cart$actual == "No", carseat_preds_cart$No)
yardstick::roc_curve(carseat_preds_cart, actual, No) %>%
autoplot() +
labs(
title = "ROC Curve",
subtitle = paste0("AUC = ", round(mdl_auc, 4))
)
Kelebihan dan Kekurangan Pohon Keputusan
Kelebihan:
- Jika ada non-linieritas yang tinggi & hubungan yang kompleks antara variabel dependen dan independen, maka model pohon akan mengungguli model regresi linier klasik lainnya (seperti, LM, GLM, atau GAM).
- Pohon sangat mudah dijelaskan dan bahkan lebih sederhana untuk ditafsirkan daripada regresi linier.
- Dipercayai bahwa pohon keputusan lebih mencerminkan pengambilan keputusan manusia daripada pendekatan regresi klasik.
- Pohon dapat ditampilkan secara grafis, dan mudah ditafsirkan bahkan oleh orang yang tidak ahli.
- Pohon dapat menangani data dari berbagai jenis, termasuk kontinu, kategorikal, ordinal, dan biner. Transformasi data tidak diperlukan. Misalnya, pohon dapat dengan mudah menangani prediktor kualitatif tanpa perlu membuat variabel dummy.
- Pohon dapat berguna untuk mendeteksi variabel penting, interaksi, dan mengidentifikasi outlier. Semakin besar jumlah variabel, semakin bernilai eksplorasi menggunakan pohon keputusan.
- Dapat menangani data yang hilang dengan mengidentifikasi pemisahan pengganti dalam proses pemodelan. Catatan: dengan nilai yang hilang dihilangkan secara default.
Kekurangan:
- Pohon umumnya tidak memiliki tingkat akurasi prediksi yang sama dengan beberapa pendekatan regresi dan klasifikasi lainnya.
- Model pohon memiliki kecenderungan untuk overfit, yaitu kesalahan disesuaikan dengan data, dan dengan demikian menyebabkan interpretasi yang berlebihan.
- Pohon bisa sangat tidak kuat. Artinya, perubahan kecil pada data dapat menyebabkan perubahan besar pada estimasi akhir pohon.
Catatan: Performa prediktif pohon dapat ditingkatkan secara substansial dengan menggabungkan banyak pohon menggunakan metode seperti bagging, random forest, dan boosting.
Reference
Foley, M. (July 26, 2020). Classification Tree. Retrieved from https://bookdown.org/mpfoley1973/data-sci/classification-tree.html
Guild, C. (August 28, 2021). Classification and Regression Trees (CART) in R. Retrieved from https://rpubs.com/camguild/803096
Tambahan referensi:
https://gerrydito.github.io/Algoritma-Pohon-Klasifikasi-dalam-R/
https://rpubs.com/gdito/pohon-klasifikasi-mlr3