R'deki Karar Ağacı: Örnekli Sınıflandırma Ağacı
Karar Ağaçları Nedir?
Karar ağaçları hem sınıflandırma hem de regresyon görevlerini gerçekleştirebilen çok yönlü Makine Öğrenme algoritmalarıdır. Karmaşık veri kümelerine uyum sağlayabilen çok güçlü algoritmalardır. Ayrıca, karar ağaçları günümüzde mevcut en etkili Makine Öğrenme algoritmaları arasında yer alan rastgele ormanların temel bileşenleridir.
R'de karar ağaçlarının eğitimi ve görselleştirilmesi
R örneğinde ilk karar ağacınızı oluşturmak için bu Karar Ağacı eğitiminde aşağıdaki gibi ilerleyeceğiz:
- 1. Adım: Verileri içe aktarın
- 2. Adım: Veri kümesini temizleyin
- 3. Adım: Eğitim/test seti oluşturun
- 4. Adım: Modeli oluşturun
- 5. Adım: Tahminde bulunun
- 6. Adım: Performansı ölçün
- Adım 7: Hiper parametreleri ayarlayın
Adım 1) Verileri içe aktarın
Titanik'in akıbetini merak ediyorsanız bu videoyu izleyebilirsiniz. Youtube. Bu veri setinin amacı, buzdağıyla çarpışma sonrasında hangi insanların hayatta kalma olasılığının daha yüksek olduğunu tahmin etmektir. Veri seti 13 değişken ve 1309 gözlem içermektedir. Veri seti X değişkenine göre sıralanır.
set.seed(678) path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv' titanic <-read.csv(path) head(titanic)
Çıktı:
## 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)
Çıktı:
## 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
Baş ve kuyruk çıktısından verilerin karıştırılmadığını fark edebilirsiniz. Bu büyük bir sorun! Verilerinizi bir tren seti ve test seti arasında böleceğinizde, bir tek 1. ve 2. sınıftan yolcu (gözlemlerin en üst yüzde 3'inde 80. sınıftan hiçbir yolcu yok), bu da algoritmanın 3. sınıftaki yolcunun özelliklerini hiçbir zaman göremeyeceği anlamına geliyor. Bu hata kötü tahmin yapılmasına yol açacaktır.
Bu sorunun üstesinden gelmek için sample() fonksiyonunu kullanabilirsiniz.
shuffle_index <- sample(1:nrow(titanic)) head(shuffle_index)
Karar ağacı R kodu Açıklama
- sample(1:nrow(titanic)): 1'den 1309'a kadar (yani maksimum satır sayısı) rastgele bir dizin listesi oluşturun.
Çıktı:
## [1] 288 874 1078 633 887 992
Titanik veri kümesini karıştırmak için bu dizini kullanacaksınız.
titanic <- titanic[shuffle_index, ] head(titanic)
Çıktı:
## 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
Adım 2) Veri kümesini temizleyin
Verilerin yapısı bazı değişkenlerin NA'ya sahip olduğunu göstermektedir. Veri temizliği aşağıdaki gibi yapılmalıdır
- home.dest,cabin, name, X ve ticket değişkenlerini bırakın
- Pclass için faktör değişkenleri oluşturun ve hayatta kalın
- NA'yı bırak
library(dplyr) # Drop variables clean_titanic <- titanic % > % select(-c(home.dest, cabin, name, X, ticket)) % > % #Convert to factor level mutate(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)
Kod Açıklama
- select(-c(home.dest, kabin, isim, X, bilet))): Gereksiz değişkenleri bırakın
- pclass = faktör(pclass, düzeyler = c(1,2,3), labels= c('Üst', 'Orta', 'Alt'))): pclass değişkenine etiket ekleyin. 1 Üst, 2 Orta ve 3 alt olur
- faktör(hayatta kaldı, düzeyler = c(0,1), etiketler = c('Hayır', 'Evet'))): Hayatta kalan değişkene etiket ekleyin. 1 Hayır olur ve 2 Evet olur
- na.omit(): NA gözlemlerini kaldırır
Çıktı:
## Observations: 1,045 ## Variables: 8 ## $ pclass <fctr> Upper, Lower, Lower, Upper, Middle, Upper, Middle, U... ## $ survived <fctr> No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y... ## $ sex <fctr> male, male, female, female, male, male, female, male... ## $ age <dbl> 61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0, ... ## $ sibsp <int> 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,... ## $ parch <int> 0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,... ## $ fare <dbl> 32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542, ... ## $ embarked <fctr> S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C...
Adım 3) Eğitim/test seti oluşturun
Modelinizi eğitmeden önce iki adımı uygulamanız gerekir:
- Bir eğitim ve test seti oluşturun: Modeli tren setinde eğitirsiniz ve tahminleri test setinde (yani görünmeyen veriler) test edersiniz.
- Rpart.plot'u konsoldan yükleyin
Yaygın uygulama, verileri 80/20'ye bölmektir; verilerin yüzde 80'i modeli eğitmeye ve yüzde 20'si tahminlerde bulunmaya hizmet eder. İki ayrı veri çerçevesi oluşturmanız gerekir. Modelinizi oluşturmayı bitirene kadar test setine dokunmak istemezsiniz. Üç bağımsız değişken alan create_train_test() işlev adını oluşturabilirsiniz.
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_row train_sample < - 1: total_row if (train == TRUE) { return (data[train_sample, ]) } else { return (data[-train_sample, ]) } }
Kod Açıklama
- function(data, size=0.8, train = TRUE): Fonksiyondaki argümanları ekleyin
- n_row = dar(veri): Veri kümesindeki satır sayısını sayın
- total_row = size*n_row: Tren setini oluşturmak için n'inci satırı döndürür
- train_sample <- 1:total_row: İlk satırdan n'inci satıra kadar seç
- if (train ==TRUE){ } else { }: Koşul doğru olarak ayarlanırsa tren setini, aksi takdirde test setini döndürün.
Fonksiyonunuzu test edebilir ve boyutu kontrol edebilirsiniz.
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)
Çıktı:
## [1] 836 8
dim(data_test)
Çıktı:
## [1] 209 8
Tren veri kümesinde 1046 satır bulunurken test veri kümesinde 262 satır bulunur.
Rastgeleleştirme işleminin doğru olup olmadığını doğrulamak için prop.table() işlevini table() ile birlikte kullanırsınız.
prop.table(table(data_train$survived))
Çıktı:
## ## No Yes ## 0.5944976 0.4055024
prop.table(table(data_test$survived))
Çıktı:
## ## No Yes ## 0.5789474 0.4210526
Her iki veri setinde de hayatta kalanların sayısı aynı, yaklaşık yüzde 40.
rpart.plot'u yükleyin
rpart.plot conda kitaplıklarında mevcut değildir. Konsoldan yükleyebilirsiniz:
install.packages("rpart.plot")
Adım 4) Modeli oluşturun
Modeli oluşturmaya hazırsınız. Rpart karar ağacı fonksiyonunun sözdizimi şöyledir:
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
Bir sınıfı tahmin ettiğiniz için sınıf yöntemini kullanırsınız.
library(rpart) library(rpart.plot) fit <- rpart(survived~., data = data_train, method = 'class') rpart.plot(fit, extra = 106
Kod Açıklama
- rpart(): Modele uyacak işlev. Argümanlar şunlardır:
- hayatta kaldı ~.: Karar Ağaçlarının Formülü
- veri = data_train: Veri kümesi
- method = 'sınıf': İkili bir modele uyun
- rpart.plot(fit, extra= 106): Ağacı çizin. Ekstra özellikler 101. sınıfın olasılığını görüntülemek için 2'e ayarlanmıştır (ikili yanıtlar için kullanışlıdır). Şuraya başvurabilirsiniz: skeç Diğer seçenekler hakkında daha fazla bilgi için.
Çıktı:
Kök düğümden başlarsınız (derinlik 0/3, grafiğin üst kısmı):
- En üstte genel hayatta kalma olasılığı yer alır. Kazadan sağ kurtulan yolcuların oranını gösteriyor. Yolcuların yüzde 41'i hayatta kaldı.
- Bu düğüm yolcunun cinsiyetinin erkek olup olmadığını soruyor. Cevabınız evet ise, kökün sol alt düğümüne (derinlik 2) inersiniz. Yüzde 63'ü erkeklerden oluşuyor ve hayatta kalma olasılığı yüzde 21.
- İkinci düğümde erkek yolcunun 3.5 yaş üstü olup olmadığını soruyorsunuz. Eğer evet ise, hayatta kalma şansı yüzde 19'dur.
- Hangi özelliklerin hayatta kalma olasılığını etkilediğini anlamak için böyle devam edersiniz.
Karar Ağaçlarının birçok özelliğinden birinin çok az veri hazırlığı gerektirmesi olduğunu unutmayın. Özellikle özellik ölçeklendirme veya ortalama gerektirmezler.
Varsayılan olarak rpart() işlevi şunu kullanır: Gini notayı bölmek için safsızlık ölçüsü. Gini katsayısı ne kadar yüksek olursa, düğüm içindeki örnekler o kadar farklı olur.
Adım 5) Bir tahminde bulunun
Test veri kümenizi tahmin edebilirsiniz. Tahmin yapmak için tahmin() fonksiyonunu kullanabilirsiniz. R karar ağacı için tahminin temel sözdizimi şöyledir:
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
Test setinden çarpışma sonrasında hangi yolcuların hayatta kalma ihtimalinin daha yüksek olduğunu tahmin etmek istiyorsunuz. Yani 209 yolcudan hangisinin hayatta kalacağını bileceksiniz.
predict_unseen <-predict(fit, data_test, type = 'class')
Kod Açıklama
- tahmin(fit, data_test, type = 'sınıf'): Test kümesinin sınıfını (0/1) tahmin edin
Yapamayan yolcuyu ve başaranları test ediyoruz.
table_mat <- table(data_test$survived, predict_unseen) table_mat
Kod Açıklama
- table(data_test$survived, tahmin_unseen): R'deki doğru karar ağacı sınıflandırmasıyla karşılaştırıldığında kaç yolcunun hayatta kalan olarak sınıflandırıldığını ve vefat ettiğini saymak için bir tablo oluşturun
Çıktı:
## predict_unseen ## No Yes ## No 106 15 ## Yes 30 58
Model, 106 ölü yolcuyu doğru bir şekilde tahmin etti ancak hayatta kalan 15 kişiyi ölü olarak sınıflandırdı. Benzer şekilde, model 30 yolcuyu yanlışlıkla hayatta kalanlar olarak sınıflandırmış, ancak bu yolcuların öldüğü ortaya çıkmıştır.
Adım 6) Performansı ölçün
Sınıflandırma görevi için bir doğruluk ölçüsünü şu şekilde hesaplayabilirsiniz: karışıklık matrisi:
The karışıklık matrisi sınıflandırma performansını değerlendirmek için daha iyi bir seçimdir. Genel fikir, True örneklerinin kaç kez Yanlış olarak sınıflandırıldığını saymaktır.
Karışıklık matrisindeki her satır gerçek bir hedefi temsil ederken, her sütun tahmin edilen bir hedefi temsil eder. Bu matrisin ilk satırı ölü yolcuları (Yanlış sınıfı) dikkate alır: 106 tanesi doğru şekilde ölü olarak sınıflandırılmıştır (Gerçek negatif), geri kalan ise yanlışlıkla hayatta kalan olarak sınıflandırıldı (Yanlış pozitif). İkinci sıra hayatta kalanları ele alıyor, pozitif sınıf 58'di (gerçek pozitif) iken Gerçek negatif 30 idi.
Hesaplayabilirsiniz doğruluk testi karışıklık matrisinden:
Matris toplamına göre gerçek pozitif ve gerçek negatifin oranıdır. R ile aşağıdaki gibi kodlayabilirsiniz:
accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
Kod Açıklama
- toplam(diag(table_mat))): Köşegenin toplamı
- sum(table_mat): Matrisin toplamı.
Test setinin doğruluğunu yazdırabilirsiniz:
print(paste('Accuracy for test', accuracy_Test))
Çıktı:
## [1] "Accuracy for test 0.784688995215311"
Test seti için yüzde 78 puanınız var. Aynı alıştırmayı eğitim veri kümesiyle çoğaltabilirsiniz.
Adım 7) Hiper parametreleri ayarlayın
R'deki karar ağacı, uyumun yönlerini kontrol eden çeşitli parametrelere sahiptir. Rpart karar ağacı kütüphanesinde, rpart.control() işlevini kullanarak parametreleri kontrol edebilirsiniz. Aşağıdaki kodda, ayarlayacağınız parametreleri tanıtıyorsunuz. Şuraya başvurabilirsiniz: skeç diğer parametreler için.
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
Aşağıdaki gibi ilerleyeceğiz:
- Doğruluğu döndürmek için işlev oluşturun
- Maksimum derinliği ayarlayın
- Bir düğümün bölünebilmesi için sahip olması gereken minimum örnek sayısını ayarlayın
- Bir yaprak düğümün sahip olması gereken minimum örnek sayısını ayarlayın
Doğruluğu görüntülemek için bir fonksiyon yazabilirsiniz. Daha önce kullandığınız kodu kaydırmanız yeterlidir:
- tahmin: tahmin_unseen <- tahmin(uygun, veri_testi, tür = 'sınıf')
- Tablo üretin: table_mat <- table(data_test$survived, tahmin_unseen)
- Hesaplama doğruluğu: doğruluk_Test <- toplam(diag(table_mat))/sum(table_mat)
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 }
Parametreleri ayarlamayı deneyebilir ve modeli varsayılan değerin üzerinde geliştirip iyileştiremeyeceğinizi görebilirsiniz. Bir hatırlatma olarak, 0.78'den daha yüksek bir doğruluk elde etmeniz gerekiyor
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)
Çıktı:
## [1] 0.7990431
Aşağıdaki parametre ile:
minsplit = 4 minbucket= round(5/3) maxdepth = 3cp=0
Önceki modele göre daha yüksek performans elde edersiniz. Tebrikler!
ÖZET
Bir karar ağacı algoritmasını eğitmek için işlevleri şu şekilde özetleyebiliriz: R
Kütüphane | Nesnel | işlev | Sınıf | parametreler | - Detaylar |
---|---|---|---|---|---|
bölüm | R'deki tren sınıflandırma ağacı | rpart() | sınıf | formül, df, yöntem | |
bölüm | Tren regresyon ağacı | rpart() | anova | formül, df, yöntem | |
bölüm | Ağaçların grafiğini çizin | rpart.plot() | takılı model | ||
baz | tahmin | ) (Tahmin | sınıf | takılı model, tip | |
baz | tahmin | ) (Tahmin | prob | takılı model, tip | |
baz | tahmin | ) (Tahmin | vektör | takılı model, tip | |
bölüm | kontrol parametreleri | rpart.control() | minimum bölünmüş | Algoritma bölme işlemini gerçekleştirmeden önce düğümdeki minimum gözlem sayısını ayarlayın | |
küçük kova | Son notta, yani yaprakta minimum gözlem sayısını ayarlayın | ||||
Maksimum derinlik | Son ağacın herhangi bir düğümünün maksimum derinliğini ayarlayın. Kök düğüme 0 derinliğinde işlem yapılır | ||||
bölüm | Kontrol parametreli tren modeli | rpart() | formül, df, yöntem, kontrol |
Not: Modeli bir eğitim verisi üzerinde eğitin ve performansı görünmeyen bir veri kümesinde, yani test kümesinde test edin.