| ID | GPA | Interview | Decision |
|---|---|---|---|
| 1 | <3.0 | Düşük | Red |
| 2 | <3.0 | Yüksek | Onay |
| 3 | <3.0 | Yüksek | Onay |
| 4 | >3.0 | Düşük | Red |
| 5 | >3.0 | Yüksek | Onay |
| 6 | >3.0 | Normal | Onay |
| 7 | <3.0 | Normal | Red |
## Hesaplanan Entropi Değeri: 0.985
## Hesaplanan Gini Değeri: 0.4898
## Gain Interview = 0.5216406
## [1] 0.02024421
## Gain GPA = 0.02024421
Şekil: Hangi Değişken Daha Çok Bilgi Kazandırıyor?
Şekil: Kredi Onayı İçin Oluşturulan Karar Ağacı
## Confusion Matrix and Statistics
##
## Reference
## Prediction neg pos
## neg 71 19
## pos 7 20
##
## Accuracy : 0.7778
## 95% CI : (0.6916, 0.8494)
## No Information Rate : 0.6667
## P-Value [Acc > NIR] : 0.005846
##
## Kappa : 0.4583
##
## Mcnemar's Test P-Value : 0.030984
##
## Sensitivity : 0.9103
## Specificity : 0.5128
## Pos Pred Value : 0.7889
## Neg Pred Value : 0.7407
## Prevalence : 0.6667
## Detection Rate : 0.6068
## Detection Prevalence : 0.7692
## Balanced Accuracy : 0.7115
##
## 'Positive' Class : neg
##
Şekil: Diyabet Risk Ağacı
## Modelin Teşhisi: neg
## Diyabet Olma İhtimali: % 15.38
Eğer tahmin etmeye çalıştığımız hedef değişken bir kategori (Örn: Onay/Red) değil de sayısal bir değerse (Örn: Burs Miktarı, Maaş, Ev Fiyatı), sınıflandırma ağaçlarında kullandığımız Entropy veya Gini indeksleri işlevsiz kalır.
Bu durumda devreye Varyans Azaltımı (Variance Reduction) yöntemi girer.
Sınıflandırma problemlerinde temel amaç düğümleri “saf” (homojen) hale getirmek iken, regresyon problemlerinde amaç “birbirine yakın değerleri” aynı düğümde toplamaktır.
Düşük Varyans: Bir yaprağa düşen değerler sayısal olarak birbirine ne kadar yakınsa, o grubun varyansı o kadar düşük olur.
Tahmin: O yaprağa düşen yeni bir veri için üretilen tahmin değeri, yapraktaki tüm eğitim verilerinin ortalamasıdır.
Optimizasyon: Algoritma, verideki tüm olası bölme noktalarını tek tek dener ve varyansı (hatayı) matematiksel olarak en çok düşüren noktayı seçer.
Bölme işleminin başarısını ölçmek için MSE (Mean Squared Error) veya Varyans kullanılır. Temel formül şöyledir:
\[ \text{Varyans Azaltımı} = \text{Var}_{root} - \sum \left( \text{Ağırlık} \cdot \text{Var}_{child} \right) \]
Burada:
Amaç, bu çıkarma işleminin sonucunu (Varyans Azaltımını) maksimize etmektir.
Veri setimiz, öğrencilerin not ortalamaları (GPA) ve aldıkları burs miktarlarını içermektedir. Amacımız, GPA’yı kullanarak burs miktarını en az hatayla tahmin etmektir.
df_burs <- data.frame(
ID = 1:7,
GPA = c(2.5, 2.7, 3.0, 3.2, 3.5, 3.7, 4.0),
Burs = c(10, 12, 18, 22, 30, 35, 40)
)
df_burs %>%
kbl(caption = "Tablo 2: GPA ve Burs Miktarı (bin TL)") %>%
kable_styling(bootstrap_options = "bordered", full_width = F)
| ID | GPA | Burs |
|---|---|---|
| 1 | 2.5 | 10 |
| 2 | 2.7 | 12 |
| 3 | 3.0 | 18 |
| 4 | 3.2 | 22 |
| 5 | 3.5 | 30 |
| 6 | 3.7 | 35 |
| 7 | 4.0 | 40 |
Karar ağaçları bölme işlemi yaparken rastgele sayı seçmezler. Veri setindeki değerleri sıraya dizer ve yan yana duran her iki değerin ortalamasını bir “Bölme Adayı” (Threshold) olarak belirler.
Verimizdeki adaylar şu şekilde oluşur:
| Sıralı GPA Değerleri | İşlem (Ortalama) | Aday Bölme Noktası (Threshold) |
|---|---|---|
| 2.5, 2.7 | (2.5 + 2.7) / 2 | 2.60 |
| 2.7, 3.0 | (2.7 + 3.0) / 2 | 2.85 |
| 3.0, 3.2 | (3.0 + 3.2) / 2 | 3.10 |
| 3.2, 3.5 | (3.2 + 3.5) / 2 | 3.35 |
| 3.5, 3.7 | (3.5 + 3.7) / 2 | 3.60 |
| 3.7, 4.0 | (3.7 + 4.0) / 2 | 3.85 |
| … | … | … |
Algoritma bu 6 adayın hepsini tek tek dener. Hangi aday varyansı en çok düşürüyorsa (grupları en homojen hale getiriyorsa), o noktayı seçer.
Hangi noktanın matematiksel olarak en iyi olduğunu gözle tahmin etmek yerine R’a hesaplatalım ve grafiğini çizelim.
# 1. Aday Bölme Noktalarını Belirle
gpa_sirali <- sort(df_burs$GPA)
adaylar <- (gpa_sirali[1:6] + gpa_sirali[2:7]) / 2
# 2. Her Aday İçin Varyans Azaltımını Hesapla
sonuclar <- data.frame()
kok_varyans <- var(df_burs$Burs) * (6/7) # Popülasyon varyansı düzeltmesi
for(split in adaylar) {
# Veriyi böl
sol_grup <- df_burs$Burs[df_burs$GPA < split]
sag_grup <- df_burs$Burs[df_burs$GPA > split]
# Ağırlıklar
w_sol <- length(sol_grup) / nrow(df_burs)
w_sag <- length(sag_grup) / nrow(df_burs)
# Varyanslar (Tek eleman varsa varyans 0 kabul edilir)
var_sol <- if(length(sol_grup) > 1) var(sol_grup) * (length(sol_grup)-1)/length(sol_grup) else 0
var_sag <- if(length(sag_grup) > 1) var(sag_grup) * (length(sag_grup)-1)/length(sag_grup) else 0
# Varyans Azaltımı Formülü
azaltim <- kok_varyans - ((w_sol * var_sol) + (w_sag * var_sag))
sonuclar <- rbind(sonuclar, data.frame(Eşik = split, Kazanc = azaltim))
}
# 3. Sonuçları Görselleştir
ggplot(sonuclar, aes(x = as.factor(Eşik), y = Kazanc)) +
geom_col(aes(fill = Kazanc == max(Kazanc))) +
geom_text(aes(label = round(Kazanc, 2)), vjust = -0.5, fontface = "bold") +
scale_fill_manual(values = c("gray70", "#27AE60")) +
labs(title = "Hangi Eşik Değeri En İyisi?",
subtitle = "3.35 noktası matematiksel olarak en yüksek varyans azaltımını sağlamıştır.",
x = "Aday Bölme Noktaları (Thresholds)",
y = "Varyans Azaltımı") +
theme_minimal() +
theme(legend.position = "none")
Şekil: Hangi Bölme Noktası Varyansı En Çok Düşürüyor?
Analiz Sonucu:
Grafikte açıkça görüldüğü üzere, 3.35 eşik değeri 93.12 puan ile en yüksek varyans azaltımını sağlamaktadır.
3.10 noktası da iyi bir adaydır (94.6’ya yakın ama hesaplama yöntemine göre 3.35 daha baskın çıkmıştır).
3.35’in Sırrı: Verideki en büyük sıçrama 22 (GPA 3.2) ile 30 (GPA 3.5) arasındadır. Algoritma bu büyük farkı yakalayarak en homojen grupları oluşturmuştur.
Bu nedenle, birazdan kuracağımız modelin 3.35 noktasından (veya ona en yakın veri noktasından) bölme yapmasını bekliyoruz.
Bir önceki bölümde (3.2.2), matematiksel olarak varyansı en çok
düşüren noktanın 3.35 olduğunu hesaplamıştık. Şimdi
R’ın rpart algoritmasını çalıştırarak bu hesaplamayı
doğrulayıp doğrulamadığını görelim.
(Not: Ağacın çok derinleşip veriyi ezberlemesini önlemek ve temel
mantığı görmek için derinliği 1 ile sınırlandırıyoruz:
maxdepth=1)
# maxdepth = 1 ekleyerek ağacı tek seviyede donduruyoruz
reg_tree <- rpart(Burs ~ GPA,
data = df_burs,
method = "anova",
control = rpart.control(minsplit = 2, cp = 0.001, maxdepth = 1))
rpart.plot(reg_tree,
type = 4,
digits = 4,
box.palette = "Oranges",
main = "Burs Tahmin Ağacı (Derinlik: 1)")
Şekil: Burs Tahmin Ağacı
Model Yorumu:
Grafikte görüldüğü üzere, R algoritması da bizim hesaplamamızı doğrulamış ve ağacı GPA < 3.35 noktasından bölmüştür.
Sol Dal (GPA < 3.35): Ortalama Burs 15.5 Bin TL.
Sağ Dal (GPA >= 3.35): Ortalama Burs 35 Bin TL.
Şimdi modelimizi test edelim. Sisteme GPA = 3.3 olan yeni bir öğrenci geldiğinde model nasıl karar verir?
Adım Adım Karar Süreci:
-Soru: Öğrencinin notu (3.3), eşik değeri olan 3.35’ten küçük mü?
-Cevap: Evet (3.3<3.35).
-Yön: Sol Dal.
-Sonuç: Sol daldaki öğrencilerin (Notu 2.5, 2.7, 3.0, 3.2 olanlar) burs ortalaması alınır:
-Hesap: Sol daldaki öğrenciler \(\{10, 12, 18, 22\}\).
\[ \text{Tahmin} = \frac{10 + 12 + 18 +
22}{4} = 15.5 \text{ Bin TL} \]
Bunu R koduyla doğrulayalım:
# Yeni öğrenci
test_ogrenci <- data.frame(GPA = 3.3)
# Modelin Tahmini
tahmin_model <- predict(reg_tree, test_ogrenci)
cat(sprintf("Modelin Tahmini: %.2f Bin TL", tahmin_model))
## Modelin Tahmini: 15.50 Bin TL
Sonuç 15.50 Bin TL çıktı. Oysa manuel incelemede (sezgisel olarak) 3.3 notunun yüksek gruba daha yakın olduğunu düşünebilirdik. Model neden “cimri” davrandı?
Bu durum, Karar Ağaçlarının çalışma prensibini anlamak için harika bir örnektir:
Veri setimizde 3.2 ile 3.5 arasında hiç öğrenci yoktur.
GPA 3.3, tam bu boşluğun (gap) ortasındadır.
Algoritma, varyansı en aza indirmek için sınır çizgisini 3.35’e çektiği için, 3.3 notu matematiksel olarak “Düşük Grup” (Sol taraf) içinde kalmıştır.
Karar ağaçları duygusal davranmaz, sadece Varyans Azaltımına (Homojenliğe) bakar.
Sol grubu (10, 12, 18, 22) bir arada tutmak, varyansı en çok düşüren seçenektir.
Eğer 3.3 için yüksek tahmin yapsaydı, eğitim verisindeki genel hatası (Error) artacaktı. Model, geneli korumak için tekil bir noktada sezgimize ters düşen bir karar verdi.
İşte bu nokta, neden tek bir ağaçla yetinmememiz gerektiğinin ispatıdır. Verideki tek bir satır değişseydi veya sınır 3.25 olsaydı, sonuç tamamen değişebilirdi (Yüksek Varyans Problemi).
Çözüm Nedir?
Bu kararsızlığı yenmek için, sınır çizgilerini farklı yerlerden çeken yüzlerce ağacın ortak kararını kullanmalıyız. Bu bizi bir sonraki konumuz olan Rastgele Ormanlar (Random Forests) algoritmasına götürür.
Karar ağaçlarının en büyük zaafı, veriyi “öğrenmek” yerine “ezberlemeye” (Overfitting) meyilli olmalarıdır. Eğer bir durdurma kuralı koymazsak, ağaç eğitim setindeki her bir örneği ayrı bir yaprak yapana kadar büyüyebilir.
Bunu engellemek için Pruning (Budama) işlemi uygulanır.
Bir öğrencinin sınava hazırlandığını düşünelim:
Öğrenme (Genelleme): Konunun mantığını kavrar. Sorular değişse de çözer. (İdeal Model)
Ezberleme (Overfitting): Çıkmış soruların cevap şıklarını ezberler. Soru biraz değişirse çözemez. (Aşırı Öğrenmiş Model)
Karar ağaçlarında da, ağaç çok derinleşirse verideki genel kuralları değil, o veriye özgü tesadüfi gürültüleri (noise) modellemeye başlar.
Bu durumu göstermek için, elimizdeki 7 satırlık veri setini kullanarak, parametreleri zorlayıp “aşırı öğrenmiş” (karmaşık) bir ağaç oluşturalım.
Ağaca şu emri veriyoruz: “Hiçbir kural tanımana gerek yok, hatayı
sıfıra indirene kadar böl!” (cp = -1,
minsplit = 1)
# Parametreleri zorlayarak aşırı karmaşık bir ağaç kuralım
overfit_tree <- rpart(Burs ~ GPA,
data = df_burs,
method = "anova",
control = rpart.control(minsplit = 1, minbucket = 1, cp = -1))
# Bu ağacın görüntüsü
rpart.plot(overfit_tree,
main = "Budanmamış (Ezberci) Ağaç",
box.palette = "Reds",
type = 4)
Şekil 3: Aşırı Öğrenmiş (Overfit) Ağaç
Görsel Yorumu:
Yukarıdaki ağaç, verideki her ufak fark için yeni bir kural uydurmuştur. Model genel trendi yakalamak yerine, her bir öğrenciye özel kural yazmıştır. Bu ağaç eğitim verisinde hatasızdır (varyans sıfırdır) ama yeni bir veri geldiğinde çok kötü tahmin yapacaktır.
Budama işlemi, ağacın karmaşıklığını kontrol altına almak için Cost Complexity Pruning yöntemini kullanır. Burada kilit oyuncu cp (Complexity Parameter) değeridir.
Mantık: Her yeni dal açmanın bir “maliyeti” vardır. Eğer yeni bir dal açmak, modelin hatasını cp değeri kadar düşürmüyorsa, o dal açılmaz (veya sonradan kesilir).
# Ağacın karmaşıklık tablosu
printcp(overfit_tree)
##
## Regression tree:
## rpart(formula = Burs ~ GPA, data = df_burs, method = "anova",
## control = rpart.control(minsplit = 1, minbucket = 1, cp = -1))
##
## Variables actually used in tree construction:
## [1] GPA
##
## Root node error: 792.86/7 = 113.27
##
## n= 7
##
## CP nsplit rel error xerror xstd
## 1 0.8221622 0 1.0000000 1.36111 0.394367
## 2 0.1021622 1 0.1778378 0.34594 0.086584
## 3 0.0472973 2 0.0756757 0.36121 0.080186
## 4 0.0157658 3 0.0283784 0.22387 0.069039
## 5 0.0100901 4 0.0126126 0.14505 0.029029
## 6 0.0025225 5 0.0025225 0.14505 0.029029
## 7 -1.0000000 6 0.0000000 0.14505 0.029029
# En düşük hatayı veren cp değerini otomatik bulalım
best_cp <- overfit_tree$cptable[which.min(overfit_tree$cptable[,"xerror"]),"CP"]
cat("En iyi cp=",best_cp)
## En iyi cp= 0.01009009
# Ağacı bu en iyi cp değerine göre budayalım
pruned_tree <- prune(overfit_tree, cp = best_cp)
Budama işleminden sonra ağacımız sadeleşir ve sadece gerçekten önemli ayrımları (Splitleri) tutar.
rpart.plot(pruned_tree,
main = "Budanmış (Genelleyici) Ağaç",
box.palette = "Greens",
type = 4)
Şekil 4: Budanmış (Optimize) Ağaç
Sonuç: Budanmış ağaç, gereksiz detaylardan arınmıştır. Verideki küçük dalgalanmaları göz ardı eder ve ana eğilimi (trend) yakalar. Bu, Bölüm 3.3’te gördüğümüz (GPA < 3.35) ağacın aynısıdır.
Analizimiz boyunca gördüğümüz üzere Karar Ağaçları güçlüdür ancak her yöntem gibi kusursuz değildir. Modelin karakteristiğini anlamak için varsayımlarını, güçlü ve zayıf yönlerini masaya yatırmalıyız.
İstatistiksel yöntemlerin (Lineer Regresyon vb.) aksine, Karar Ağaçları “Non-Parametrik” yöntemlerdir. Yani veri hakkında katı varsayımları yoktur:
Dağılım Bağımsızlığı: Verinin Normal dağılıma (Gaussian) uyması gerekmez.
Doğrusallık Yoktur: Değişkenler arasında lineer (\(y = ax + b\)) bir ilişki kurmaya çalışmaz. Lineer olmayan karmaşık ilişkileri modelleyebilir.
Ölçekleme Gerektirmez: Veriyi normalize etmeye (Scaling/Standardization) gerek yoktur. Çünkü algoritma matematiksel mesafeye değil, sıralamaya (büyüklük/küçüklük) bakar.
Beyaz Kutu (White Box) Modeli: Sinir ağları gibi “kara kutu” değildir. Modelin neden o kararı verdiği, çizilen ağaç diyagramı üzerinden %100 şeffaflıkla açıklanabilir.
Veri Hazırlığı Kolaylığı: Eksik verilerle (Missing Values) veya aykırı değerlerle (Outliers) başa çıkabilir.
Karma Veri Tipleri: Hem sayısal hem de kategorik verileri aynı anda kullanabilir.
Yüksek Varyans (Kararsızlık): En büyük problemidir. Veri setindeki tek bir satırın değişmesi, bambaşka bir ağaç oluşturabilir.
Overfitting (Aşırı Öğrenme): Budama yapılmazsa veriyi ezberler. Genelleme yeteneği düşüktür.
Baskın Sınıf Sorunu: Dengesiz veri setlerinde (Imbalanced Data), çoğunluk sınıfı ağacı domine edebilir.
Karar ağaçlarının “Yüksek Varyans” ve “Kararsızlık” problemini nasıl çözeriz? Cevap, istatistikten değil, sosyolojiden gelir: “Kalabalıkların Bilgeliği” (Wisdom of Crowds).
Tek bir doktorun teşhis koyması hata riskini barındırır. Ancak farklı uzmanlıklara sahip 100 doktordan oluşan bir konseyin ortak kararı (konsensus), hatayı minimize eder. Makine öğrenmesinde bu yaklaşıma Ensemble Learning denir.
Ensemble yöntemlerinin temel felsefesi şudur:
“Tek başına zayıf veya hatalı olabilen birden fazla modeli (Weak Learners) bir araya getirerek, daha güçlü ve kararlı tek bir model (Strong Learner) oluşturmak.”
Bu kurguda Karar Ağaçları genellikle “Zayıf Öğrenici” olarak kullanılır. İki ana strateji vardır:
Bagging (Bootstrap Aggregating):
Boosting:
Bu çalışmada incelediğimiz Tek Karar Ağacı (Single Decision Tree), anlaşılır olması açısından mükemmeldir ancak hassas yapısı nedeniyle tek başına karmaşık problemler için yeterli değildir.
GPA örneğimizde modelin sınır çizgisini veri boşluğundan dolayı 3.35 seçmesi sonucu, 3.3 not ortalaması “düşük gruba” dahil olmuştu. Ancak elimizde verinin farklı parçalarıyla eğitilmiş 100 farklı ağaç olsaydı:
Kimi 3.1’den bölecekti,
Kimi 3.2’den,
Kimi 3.4’ten.
Bu 100 ağacın ortalamasını aldığımızda, 3.3 GPA puanı için çok daha dengeli ve güvenilir bir tahmin elde edecektik.
İşte bu mantık bizi bir sonraki dersimizin konusu olan Rastgele Ormanlar (Random Forest) algoritmasına götürür. Random Forest, Bagging yöntemini kullanarak yüzlerce karar ağacını birleştirir ve varyansı düşürerek “ezberlemeyen”, kararlı bir yapı oluşturur.
Son Söz: Karar ağaçları, modern makine öğrenmesinin yapı taşlarıdır (building blocks). Onları anlamak, Random Forest, XGBoost ve LightGBM gibi son teknoloji modelleri anlamanın anahtarıdır.