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ı:

R'de Karar Ağaçları Modeli Oluşturma

Kök düğümden başlarsınız (derinlik 0/3, grafiğin üst kısmı):

  1. 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ı.
  2. 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.
  3. İkinci düğümde erkek yolcunun 3.5 yaş üstü olup olmadığını soruyorsunuz. Eğer evet ise, hayatta kalma şansı yüzde 19'dur.
  4. 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.

R'de Karar Ağaçlarının Performansını Ölçme

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:

R'de Karar Ağaçlarının Performansını Ölçme

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:

  1. tahmin: tahmin_unseen <- tahmin(uygun, veri_testi, tür = 'sınıf')
  2. Tablo üretin: table_mat <- table(data_test$survived, tahmin_unseen)
  3. 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.