1.Spaceship Titanic ve Kaggle

Bu derste, veri bilimi ve makine öğrenmesi adımlarını baştan sona uygulayacağımız bir proje üzerinde çalışacağız. Uygulama için Kaggle platformundaki “Spaceship Titanic” adlı sınıflandırma yarışmasını kullanacağız. Amaç, gerçek hayata benzer bir veri bilimi sürecini, baştan sona, mümkün olduğunca sistematik ve şeffaf bir şekilde deneyimlemek ve R programlama dilinde uygulama becerisi kazanmaktır.

Spaceship Titanic yarışmasında elimizde, kurgusal bir uzay gemisindeki yolculara ait bilgiler (yaş, kabin konumu, harcama kalemleri, aile yapısı vb.) ve bu yolcuların “anomali sonucunda taşınıp taşınmadığını” gösteren bir hedef değişken bulunmaktadır. Görevimiz, bu kayıtları kullanarak hangi yolcuların alternatif bir boyuta taşındığını tahmin eden bir makine öğrenmesi modeli kurmaktır.

Bu proje, veri ve senaryo kurgusal olsa da, karşılaşacağımız problemler (eksik veri, veri temizleme, değişken seçimi, model karşılaştırma, değerlendirme ölçütleri, vb.) gerçek veri bilimi projelerine oldukça benzemektedir.

1.1 Kaggle Nedir?

Kaggle, veri bilimi ve makine öğrenmesi alanında kullanılan, yarışmaların, veri setlerinin ve örnek kodların paylaşıldığı bir çevrimiçi platformdur.

Kullanıcılar:

  • Farklı zorluk seviyelerinde yarışmalara katılabilir,

  • Açık veri setlerini inceleyip analiz edebilir,

  • Diğer katılımcıların paylaştığı not defterlerini (notebooks) ve çözümleri inceleyebilir,

  • Öğrenme materyallerine ve tartışma forumlarına erişebilir.

Kaggle, veri bilimi becerilerini geliştirmek, yeni teknikler öğrenmek ve gerçek dünya problemlerini çözmek için harika bir kaynaktır.

1.2 Spaceship Titanic Yarışması

Spaceship Titanic yarışması, Kaggle platformunda bulunan ve katılımcıların bir uzay gemisindeki yolcuların alternatif bir boyuta taşınıp taşınmadığını tahmin etmeye çalıştığı bir sınıflandırma problemidir. Yarışmada verilen veri seti, yolcuların demografik bilgileri, seyahat detayları ve harcama alışkanlıkları gibi çeşitli özellikleri içermektedir.

Yarışmanın amacı, bu özellikleri kullanarak hangi yolcuların taşındığını doğru bir şekilde tahmin eden bir makine öğrenmesi modeli geliştirmektir. Katılımcılar, modellerini eğitmek ve değerlendirmek için sağlanan eğitim train veri setini kullanabilir ve ardından test test veri seti üzerinde tahminler yaparak performanslarını ölçebilirler.

Yarışma, veri bilimi ve makine öğrenmesi becerilerini geliştirmek isteyenler için harika bir fırsat sunmaktadır. Katılımcılar, veri ön işleme, özellik mühendisliği, model seçimi ve değerlendirme gibi önemli adımları deneyimleyebilirler.

Daha fazla bilgi için yarışma sayfası:

Kaggle Spaceship Titanic:

https://www.kaggle.com/competitions/spaceship-titanic

1.3 Proje Adımları

Bu projede aşağıdaki adımları takip edeceğiz:

  1. Veri Setini Anlama: Veri setindeki değişkenleri ve hedef değişkeni inceleyerek, problemin doğasını anlayacağız.

  2. Veri Ön İşleme: Eksik verileri ele alacak, kategorik değişkenleri dönüştürecek ve gerekli veri temizleme işlemlerini yapacağız.

  3. Keşifsel Veri Analizi (EDA): Veriyi görselleştirerek ve istatistiksel özetler çıkararak, veri setindeki önemli desenleri ve ilişkileri keşfedeceğiz.

  4. Modelleme: Farklı makine öğrenmesi algoritmalarını kullanarak modeller oluşturacak ve performanslarını karşılaştıracağız.

  5. Model Değerlendirme: Modellerin doğruluk, hassasiyet, geri çağırma ve F1 skoru gibi değerlendirme metriklerini kullanarak performanslarını ölçeceğiz.

  6. Sonuçların Yorumlanması: Elde edilen sonuçları yorumlayacak ve modelin gerçek dünya uygulamalarındaki potansiyelini tartışacağız.

Bu adımları takip ederek, veri bilimi sürecini baştan sona deneyimlemiş olacağız ve R programlama dilinde uygulama becerilerimizi geliştireceğiz.

2.Veri Setini Anlama

Veri setini anlamak için öncelikle gerekli kütüphaneleri yükleyelim ve veri setini R ortamına alalım. Ardından, veri setindeki değişkenleri ve hedef değişkeni inceleyerek, problemin doğasını anlayacağız.

# Gerekli kütüphaneleri yükleyelim
library(tidyverse)
library(readr)
library(rmarkdown)
library(tidymodels)
library(knitr)
library(kableExtra)
# Veri setini R ortamına alalım
train <- read_csv("train.csv")
test <- read_csv("test.csv")
# Veri setini inceleyelim
paged_table(train)
paged_table(test)

Yukarıdaki tablolar, eğitim ve test veri setlerindeki değişkenleri ve örnek kayıtları göstermektedir. Eğitim veri setinde, yolcuların çeşitli özellikleri ve hedef değişken (Transported) bulunmaktadır. Test veri setinde ise hedef değişken bulunmamaktadır.

# Veri yapısını inceleme
glimpse(train)
## Rows: 8,693
## Columns: 14
## $ PassengerId  <chr> "0001_01", "0002_01", "0003_01", "0003_02", "0004_01", "0…
## $ HomePlanet   <chr> "Europa", "Earth", "Europa", "Europa", "Earth", "Earth", …
## $ CryoSleep    <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FA…
## $ Cabin        <chr> "B/0/P", "F/0/S", "A/0/S", "A/0/S", "F/1/S", "F/0/P", "F/…
## $ Destination  <chr> "TRAPPIST-1e", "TRAPPIST-1e", "TRAPPIST-1e", "TRAPPIST-1e…
## $ Age          <dbl> 39, 24, 58, 33, 16, 44, 26, 28, 35, 14, 34, 45, 32, 48, 2…
## $ VIP          <lgl> FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FA…
## $ RoomService  <dbl> 0, 109, 43, 0, 303, 0, 42, 0, 0, 0, 0, 39, 73, 719, 8, 32…
## $ FoodCourt    <dbl> 0, 9, 3576, 1283, 70, 483, 1539, 0, 785, 0, 0, 7295, 0, 1…
## $ ShoppingMall <dbl> 0, 25, 0, 371, 151, 0, 3, 0, 17, 0, NA, 589, 1123, 65, 12…
## $ Spa          <dbl> 0, 549, 6715, 3329, 565, 291, 0, 0, 216, 0, 0, 110, 0, 0,…
## $ VRDeck       <dbl> 0, 44, 49, 193, 2, 0, 0, NA, 0, 0, 0, 124, 113, 24, 7, 0,…
## $ Name         <chr> "Maham Ofracculy", "Juanna Vines", "Altark Susent", "Sola…
## $ Transported  <lgl> FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, …

glimpse(), dplyr/tidyverse paketinin sağladığı, bir veri çerçevesinin (data frame veya tibble) yapısını hızlı ve okunabilir bir şekilde görüntülemek için kullanılan bir fonksiyondur. Bu fonksiyon, veri setindeki her bir sütunun (değişkenin) adını, veri tipini ve ilk birkaç değerini gösterir. Böylece, veri setinin genel yapısını ve içeriğini hızlıca anlayabiliriz.

2.1 Değişken Türleri

Veriyi doğru işlemek ve uygun makine öğrenmesi modellerini kullanmak için değişken türlerini anlamak kritik öneme sahiptir. glimpse() çıktısında göreceğimiz temel veri türleri şunlardır:

  • dbl Numeric (Sayısal): Gerçek sayıları temsil eder (ör. 23.7, 0.45, 117.0). Spaceship Titanic Örnekleri, yaş (Age), harcama miktarları (RoomService, FoodCourt vb.) gibi.

  • chr Character (Karakter): Metin veya kategorik veriler içeren değişkenlerdir. Çoğu zaman kategorik değişkenler başlangıçta chr olarak gelir ve modelleme aşamasında faktöre dönüştürülmesi gerekebilir. Spaceship Titanic Örnekleri: PassengerId, HomePlanet, Cabin vb.

  • lgl Logical (Mantıksal): TRUE veya FALSE değerlerini alabilen değişkenlerdir. Örneğin, hedef değişkenimiz Transported bu türdedir. int Integer (Tam Sayı): Tam sayıları temsil eder (ör. 1, 42, -7). Örneğin, Age değişkeni tam sayılar içerebilir.

  • fct Factor (Kategori): Kategorik verilerin R’daki özel veri türüdür. chr türündeki değişkenler modelleme aşamasında as.factor() ile faktöre dönüştürülerek daha etkin şekilde kullanılabilir.

3.Veri Ön İşleme

# Eksik değer analizi
colSums(is.na(train))
##  PassengerId   HomePlanet    CryoSleep        Cabin  Destination          Age 
##            0          201          217          199          182          179 
##          VIP  RoomService    FoodCourt ShoppingMall          Spa       VRDeck 
##          203          181          183          208          183          188 
##         Name  Transported 
##          200            0

Yukarıdaki kod, eğitim veri setindeki her bir sütunda (değişkende) eksik (NA) değerlerin sayısını hesaplar ve görüntüler. Bu analiz, veri setindeki eksik verilerin hangi değişkenlerde yoğunlaştığını ve ne kadar eksik veri olduğunu anlamamıza yardımcı olur. Eksik veriler, veri ön işleme aşamasında ele alınması gereken önemli bir konudur, çünkü eksik veriler model performansını olumsuz etkileyebilir.

3.1 Veri Setindeki Değişkenlerin Türlerine Göre Değerlendirilmesi

Veri setindeki değişkenlerin türlerine göre değerlendirilmesi, veri ön işleme sürecinde önemli bir adımdır. Farklı türdeki değişkenler için farklı işlemler ve dönüşümler gerekebilir. Aşağıda, veri setindeki değişkenleri türlerine göre nasıl değerlendirebileceğimiz ve işleyebileceğimiz hakkında genel bir rehber bulunmaktadır:

  1. Sayısal Değişkenler (Numeric - dbl, int):
  • Eksik Değerler: Eksik sayısal değerler için ortalama, medyan veya mod gibi istatistiksel yöntemlerle doldurma (imputation) yapılabilir. Alternatif olarak, eksik değerler içeren kayıtlar çıkarılabilir.

  • Ölçeklendirme: Bazı makine öğrenmesi algoritmaları için sayısal değişkenlerin ölçeklendirilmesi (normalizasyon veya standardizasyon) gerekebilir.

  • Aykırı Değerler: Aykırı değerlerin tespiti ve gerektiğinde düzeltilmesi veya çıkarılması önemlidir.

  1. Kategorik Değişkenler (Character - chr, Factor - fct):
  • Eksik Değerler: Eksik kategorik değerler için en sık görülen kategori ile doldurma veya “Bilinmiyor” gibi yeni bir kategori ekleme yöntemleri kullanılabilir.

  • Dönüştürme: Kategorik değişkenler, modelleme aşamasında faktör (factor) türüne dönüştürülmelidir. Bu, R’da as.factor() fonksiyonu ile yapılabilir.

  • One-Hot Encoding: Bazı durumlarda, kategorik değişkenler için one-hot encoding (dummy değişkenler oluşturma) gerekebilir.

  1. Mantıksal Değişkenler (Logical - lgl):
  • Eksik Değerler: Eksik mantıksal değerler için TRUE veya FALSE ile doldurma yapılabilir.

  • Dönüştürme: Mantıksal değişkenler, modelleme aşamasında sayısal (0 ve 1) türüne dönüştürülebilir.

  1. Tarih ve Zaman Değişkenleri:
  • Dönüştürme: Tarih ve zaman değişkenleri, yıl, ay, gün, saat gibi bileşenlere ayrılabilir veya zaman serisi analizleri için uygun formatlara dönüştürülebilir.

  • Eksik Değerler: Eksik tarih ve zaman değerleri için uygun doldurma yöntemleri kullanılabilir.

  1. Hedef Değişken (Dependent Variable):
  • Hedef değişkenin türüne göre (sınıflandırma için kategorik, regresyon için sayısal) uygun dönüşümler ve işlemler yapılmalıdır. Veri setindeki değişkenlerin türlerine göre bu değerlendirmeleri yaparak, veri ön işleme sürecini daha etkili ve verimli hale getirebiliriz. Bu adımlar, modelleme aşamasında daha iyi performans elde etmek için kritik öneme sahiptir.
# Her değişken için unique değer sayısını gösterelim
train %>%
  summarise(across(everything(), ~ n_distinct(.)))
## # A tibble: 1 × 14
##   PassengerId HomePlanet CryoSleep Cabin Destination   Age   VIP RoomService
##         <int>      <int>     <int> <int>       <int> <int> <int>       <int>
## 1        8693          4         3  6561           4    81     3        1274
## # ℹ 6 more variables: FoodCourt <int>, ShoppingMall <int>, Spa <int>,
## #   VRDeck <int>, Name <int>, Transported <int>

Yukarıdaki kod, eğitim veri setindeki her bir sütun (değişken) için benzersiz (unique) değerlerin sayısını hesaplar ve görüntüler. Bu analiz, her değişkenin kaç farklı kategori veya değer içerdiğini anlamamıza yardımcı olur. Özellikle kategorik değişkenler için bu bilgi, modelleme aşamasında hangi değişkenlerin kullanılabileceği ve nasıl işleneceği konusunda önemli ipuçları sağlar. Örneğin, çok fazla benzersiz değere sahip kategorik değişkenler, modelin karmaşıklığını artırabilir ve overfitting riskini yükseltebilir. Bu nedenle, bu tür analizler veri ön işleme sürecinde kritik bir rol oynar.

# Kategorik değişkenleri faktöre dönüştürelim
train <- train %>%
  mutate(across(c(HomePlanet, CryoSleep, Destination, VIP, Transported), as.factor))
test <- test %>%
  mutate(across(c(HomePlanet, CryoSleep, Destination, VIP), as.factor))

Yukarıdaki kod, eğitim ve test veri setlerindeki belirli kategorik değişkenleri faktör (factor) türüne dönüştürür. mutate() fonksiyonu ile across() kullanılarak belirtilen sütunlar (HomePlanet, CryoSleep, Destination, VIP, ve Transported eğitim setinde; HomePlanet, CryoSleep, Destination, ve VIP test setinde) as.factor() fonksiyonu ile faktöre dönüştürülür. Bu dönüşüm, modelleme aşamasında bu değişkenlerin doğru şekilde işlenmesini sağlar, çünkü birçok makine öğrenmesi algoritması kategorik değişkenleri faktör olarak bekler.

summary(train)
##  PassengerId         HomePlanet   CryoSleep       Cabin          
##  Length:8693        Earth :4602   FALSE:5439   Length:8693       
##  Class :character   Europa:2131   TRUE :3037   Class :character  
##  Mode  :character   Mars  :1759   NA's : 217   Mode  :character  
##                     NA's  : 201                                  
##                                                                  
##                                                                  
##                                                                  
##         Destination        Age           VIP        RoomService     
##  55 Cancri e  :1800   Min.   : 0.00   FALSE:8291   Min.   :    0.0  
##  PSO J318.5-22: 796   1st Qu.:19.00   TRUE : 199   1st Qu.:    0.0  
##  TRAPPIST-1e  :5915   Median :27.00   NA's : 203   Median :    0.0  
##  NA's         : 182   Mean   :28.83                Mean   :  224.7  
##                       3rd Qu.:38.00                3rd Qu.:   47.0  
##                       Max.   :79.00                Max.   :14327.0  
##                       NA's   :179                  NA's   :181      
##    FoodCourt        ShoppingMall          Spa              VRDeck       
##  Min.   :    0.0   Min.   :    0.0   Min.   :    0.0   Min.   :    0.0  
##  1st Qu.:    0.0   1st Qu.:    0.0   1st Qu.:    0.0   1st Qu.:    0.0  
##  Median :    0.0   Median :    0.0   Median :    0.0   Median :    0.0  
##  Mean   :  458.1   Mean   :  173.7   Mean   :  311.1   Mean   :  304.9  
##  3rd Qu.:   76.0   3rd Qu.:   27.0   3rd Qu.:   59.0   3rd Qu.:   46.0  
##  Max.   :29813.0   Max.   :23492.0   Max.   :22408.0   Max.   :24133.0  
##  NA's   :183       NA's   :208       NA's   :183       NA's   :188      
##      Name           Transported 
##  Length:8693        FALSE:4315  
##  Class :character   TRUE :4378  
##  Mode  :character               
##                                 
##                                 
##                                 
## 

Yukarıdaki kod, eğitim veri setindeki her bir değişken için özet istatistikleri görüntüler. summary() fonksiyonu, sayısal değişkenler için minimum, maksimum, ortalama, medyan ve çeyrek değerler gibi temel istatistikleri sağlar. Kategorik değişkenler için ise her bir kategoriye ait frekans dağılımını gösterir. Bu özet bilgiler, veri setinin genel yapısını ve özelliklerini anlamamıza yardımcı olur ve veri ön işleme sürecinde hangi adımların atılması gerektiği konusunda önemli ipuçları sunar. Örneğin, eksik değerlerin varlığı, aykırı değerler veya dengesiz kategorik dağılımlar gibi konular bu özetler aracılığıyla tespit edilebilir.

3.2 Faktöre Dönüştürülmeyen Kategorik Değişkenlerin İncelenmesi

3.2.1 PassengerId

Faktöre dönüştürülmesi binlerce kategori yaratacağından model tarafından öğrenilebilecek bir yapıya katkı sağlamaz.Bu nedenle doğrudan bir kategorik değişken olarak kullanılması uygun değildir.

Ancak PassengerId, yapısı gereği önemli ve çıkarımlara elverişli bilgiler taşır.

Kaggle’ın tanımına göre: PassengerId her yolcu için benzersiz bir numaradır.Bu numara gggg_pp biçimindedir. Buradaki gggg, yolcunun birlikte seyahat ettiği grubu gösterir; pp ise grubun içindeki kişi sırasıdır. Grup içindeki kişiler çoğunlukla aile üyeleridir, ancak her zaman böyle olmak zorunda değildir.

Bu yapı sayesinde PassengerId’nin kendisini kategorik olarak kullanmasak bile, içindeki alt bilgileri çıkartarak yeni açıklayıcı değişkenler (features) oluşturabiliriz.

# PassengerId'den grup numarası ve kişi sırasını çıkaralım
train <- train %>%
  separate(PassengerId, into = c("Grup_No", "Kisi_No"), sep = "_", remove = FALSE) %>%
  mutate(Grup_No = as.factor(Grup_No),
         Kisi_No = as.integer(Kisi_No))
test <- test %>%
  separate(PassengerId, into = c("Grup_No", "Kisi_No"), sep = "_", remove = FALSE) %>%
  mutate(Grup_No = as.factor(Grup_No),
         Kisi_No = as.integer(Kisi_No))

Yukarıdaki kod, PassengerId sütununu iki yeni sütuna ayırır: Grup_No ve Kisi_No. separate() fonksiyonu kullanılarak, PassengerId içindeki “gggg_pp” formatına göre ayırma işlemi gerçekleştirilir. Ardından, mutate() fonksiyonu ile Grup_No faktör (factor) türüne dönüştürülürken, Kisi_No tam sayı (integer) türüne dönüştürülür. Bu yeni değişkenler, yolcuların birlikte seyahat ettiği grupları ve grup içindeki kişi sırasını temsil eder ve modelleme aşamasında açıklayıcı değişkenler olarak kullanılabilir.

head(train %>% select(PassengerId, Grup_No, Kisi_No))
## # A tibble: 6 × 3
##   PassengerId Grup_No Kisi_No
##   <chr>       <fct>     <int>
## 1 0001_01     0001          1
## 2 0002_01     0002          1
## 3 0003_01     0003          1
## 4 0003_02     0003          2
## 5 0004_01     0004          1
## 6 0005_01     0005          1

Bu sayede iki yeni değişken elde ettik:

•   Grup_No: Yolcunun ait olduğu seyahat grubunu gösterir.
•   Kisi_No: Grubun içindeki kişi sırasını gösterir.

Bu yeni değişkenler, yolcuların birlikte seyahat edip etmediklerini ve grup içindeki konumlarını anlamamıza yardımcı olabilir. Bu bilgiler, modelin performansını artırmak için kullanılabilir. Örneğin:

•   Tek başına seyahat edenlerin davranışları farklı olabilir.
•   Aile grupları benzer cabin, homeplanet ve destination bilgilerine sahiptir.
•   Grup içindeki kişi sayısı, taşınma olasılığı üzerinde etkili olabilir.
train <- train %>%
  group_by(Grup_No) %>%
  mutate(Grup_Buyuklugu = n()) %>%
  ungroup()

test <- test %>%
  group_by(Grup_No) %>%
  mutate(Grup_Buyuklugu= n()) %>%
  ungroup()

Yukarıdaki kod, Grup_No değişkenine göre gruplama yapar ve her grup içindeki yolcu sayısını hesaplayarak yeni bir sütun olan Grup_Buyuklugu oluşturur. group_by(Grup_No) ile yolcuları gruplar, ardından mutate(Grup_Buyuklugu = n()) ile her grup için yolcu sayısını belirler. Son olarak, ungroup() ile gruplamayı kaldırır. Bu yeni değişken, her yolcunun ait olduğu grubun büyüklüğünü temsil eder ve modelleme aşamasında açıklayıcı bir özellik olarak kullanılabilir. Grup büyüklüğü, taşınma olasılığı üzerinde etkili olabilir; örneğin, daha büyük gruplar birlikte hareket etme eğiliminde olabilir.

head(train %>% select(PassengerId, Grup_Buyuklugu), 10)
## # A tibble: 10 × 2
##    PassengerId Grup_Buyuklugu
##    <chr>                <int>
##  1 0001_01                  1
##  2 0002_01                  1
##  3 0003_01                  2
##  4 0003_02                  2
##  5 0004_01                  1
##  6 0005_01                  1
##  7 0006_01                  2
##  8 0006_02                  2
##  9 0007_01                  1
## 10 0008_01                  3
# Kişi yalnız mı seyahat ediyor?
train <- train %>%
  mutate(Yalniz_Seyahat = ifelse(Grup_Buyuklugu == 1, 1, 0))
test <- test %>%
  mutate(Yalniz_Seyahat = ifelse(Grup_Buyuklugu == 1, 1, 0))

Yukarıdaki kod, her yolcunun yalnız seyahat edip etmediğini belirten yeni bir sütun olan Yalniz_Seyahat oluşturur. mutate() fonksiyonu kullanılarak, Grup_Buyuklugu değişkeni kontrol edilir; eğer grup büyüklüğü 1 ise (yani yolcu tek başına seyahat ediyorsa), Yalniz_Seyahat değeri 1 olarak atanır, aksi takdirde 0 olarak atanır. Bu yeni değişken, modelleme aşamasında açıklayıcı bir özellik olarak kullanılabilir ve yalnız seyahat eden yolcuların taşınma olasılığı üzerindeki etkisini incelemek için faydalı olabilir.

table(train$Grup_Buyuklugu)
## 
##    1    2    3    4    5    6    7    8 
## 4805 1682 1020  412  265  174  231  104
train <- train %>%
  mutate(Grup_Buyuklugu_Kat = case_when(
    Grup_Buyuklugu %in% c(1, 2, 3) ~ as.character(Grup_Buyuklugu),
    Grup_Buyuklugu >= 4 ~ "4+"
  )) %>%
  mutate(Grup_Buyuklugu_Kat = factor(Grup_Buyuklugu_Kat))

table(train$Grup_Buyuklugu_Kat)
## 
##    1    2    3   4+ 
## 4805 1682 1020 1186

Yukarıdaki kod, Grup_Buyuklugu değişkenini kategorik bir değişkene dönüştürerek Grup_Buyuklugu_Kat adlı yeni bir sütun oluşturur. case_when() fonksiyonu kullanılarak, grup büyüklüğü 1, 2 veya 3 olan yolcular için bu değerler korunur; ancak grup büyüklüğü 4 veya daha fazla olan yolcular için “4+” kategorisi atanır. Ardından, mutate() ile Grup_Buyuklugu_Kat faktör (factor) türüne dönüştürülür. Bu yeni kategorik değişken, modelleme aşamasında açıklayıcı bir özellik olarak kullanılabilir ve farklı grup büyüklüklerinin taşınma olasılığı üzerindeki etkisini incelemek için faydalı olabilir. Son olarak, table() fonksiyonu ile bu yeni kategorik değişkenin frekans dağılımı görüntülenir.

test <- test %>%
  mutate(Grup_Buyuklugu_Kat = case_when(
    Grup_Buyuklugu %in% c(1, 2, 3) ~ as.character(Grup_Buyuklugu),
    Grup_Buyuklugu >= 4 ~ "4+"
  )) %>%
  mutate(Grup_Buyuklugu_Kat = factor(Grup_Buyuklugu_Kat))

3.2.2 Cabin

Cabin değişkeni, yolcuların kabin konumlarını temsil eder ve genellikle “Deck/Numara/Side” formatında kodlanmıştır. Bu değişken, yolcuların gemideki konumları hakkında önemli bilgiler içerebilir ve modelleme aşamasında açıklayıcı bir özellik olarak kullanılabilir.

# Cabin'den Deck, Numara ve Side bilgilerini çıkaralım
train <- train %>%
  separate(Cabin, into = c("Deck", "Numara", "Side"), sep = "/", remove = FALSE) %>%
  mutate(Deck = as.factor(Deck),
         Side = as.factor(Side),
         Numara = as.integer(Numara))
test <- test %>%
  separate(Cabin, into = c("Deck", "Numara", "Side"), sep = "/", remove = FALSE) %>%
  mutate(Deck = as.factor(Deck),
         Side = as.factor(Side),
         Numara = as.integer(Numara))

Yukarıdaki kod, Cabin sütununu üç yeni sütuna ayırır: Deck, Numara ve Side. separate() fonksiyonu kullanılarak, Cabin içindeki “Deck/Numara/Side” formatına göre ayırma işlemi gerçekleştirilir. Ardından, mutate() fonksiyonu ile Deck ve Side faktör (factor) türüne dönüştürülürken, Numara tam sayı (integer) türüne dönüştürülür. Bu yeni değişkenler, yolcuların gemideki konumlarını temsil eder ve modelleme aşamasında açıklayıcı değişkenler olarak kullanılabilir. Örneğin, belirli bir güvertede (deck) veya tarafta (side) seyahat eden yolcuların taşınma olasılıkları farklı olabilir.

head(train %>% select(Cabin, Deck, Numara, Side))
## # A tibble: 6 × 4
##   Cabin Deck  Numara Side 
##   <chr> <fct>  <int> <fct>
## 1 B/0/P B          0 P    
## 2 F/0/S F          0 S    
## 3 A/0/S A          0 S    
## 4 A/0/S A          0 S    
## 5 F/1/S F          1 S    
## 6 F/0/P F          0 P

Bu sayede üç yeni değişken elde ettik:

•   Deck: Yolcunun kabin güvertesini gösterir.
•   Numara: Kabin numarasını gösterir.
•   Side: Kabinin gemideki tarafını (sol/sağ) gösterir.

Bu yeni değişkenler, yolcuların gemideki konumlarını anlamamıza yardımcı olabilir. Bu bilgiler, modelin performansını artırmak için kullanılabilir. Örneğin:

•   Bazı güverteler veya taraflar, anomaliye karşı daha savunmasız olabilir.
•   Kabin numarası, yolcunun gemideki konumunu ve dolayısıyla taşınma olasılığını etkileyebilir.
summary(train %>% select(Deck, Numara, Side))
##       Deck          Numara         Side     
##  F      :2794   Min.   :   0.0   P   :4206  
##  G      :2559   1st Qu.: 167.2   S   :4288  
##  E      : 876   Median : 427.0   NA's: 199  
##  B      : 779   Mean   : 600.4              
##  C      : 747   3rd Qu.: 999.0              
##  (Other): 739   Max.   :1894.0              
##  NA's   : 199   NA's   :199
table(train$Deck)
## 
##    A    B    C    D    E    F    G    T 
##  256  779  747  478  876 2794 2559    5
# A, D ve T güvertelerinde çok az yolcu var, bunları "Diğer" kategorisine alalım
train <- train %>%
  mutate(Deck = fct_collapse(Deck,
                             Diğer = c("A", "D", "T")))
test <- test %>%
  mutate(Deck = fct_collapse(Deck,
                             Diğer = c("A", "D", "T")))

Yukarıdaki kod, Deck değişkenindeki az sayıda gözleme sahip olan “A”, “D” ve “T” kategorilerini “Diğer” adlı yeni bir kategori altında birleştirir. fct_collapse() fonksiyonu kullanılarak, belirtilen kategoriler tek bir kategoriye dönüştürülür. Bu işlem, modelleme aşamasında nadir kategorilerin etkisini azaltmak ve modelin genelleme yeteneğini artırmak için faydalı olabilir. Özellikle, az sayıda gözleme sahip kategoriler modelin öğrenme sürecini olumsuz etkileyebilir, bu nedenle bu tür kategorilerin birleştirilmesi yaygın bir uygulamadır.

summary(train$Deck)
## Diğer     B     C     E     F     G  NA's 
##   739   779   747   876  2794  2559   199

3.2.3 Name

Name değişkeni, yolcuların isimlerini içerir ve genellikle kişisel bilgileri temsil eder. Bu değişken, doğrudan modelleme aşamasında kullanılmaktan ziyade, içindeki bilgileri çıkartarak yeni açıklayıcı değişkenler (features) oluşturmak için kullanılabilir.

# Name ad ve soyad bilgilerini çıkaralım
train <- train %>%
  separate(Name, into = c("Ad", "Soyad"), sep = " ", remove = FALSE)
test <- test %>%
  separate(Name, into = c("Ad", "Soyad"), sep = " ", remove = FALSE)

Yukarıdaki kod, Name sütununu iki yeni sütuna ayırır: Soyad ve Ad. separate() fonksiyonu kullanılarak, Name içindeki boşluk karakterine göre ayırma işlemi gerçekleştirilir. Bu yeni değişkenler, yolcuların isimlerini temsil eder ve modelleme aşamasında açıklayıcı değişkenler olarak kullanılabilir. Örneğin, belirli bir soyada sahip yolcuların taşınma olasılıkları farklı olabilir veya belirli adlara sahip yolcuların demografik özellikleri üzerinde analizler yapılabilir.

head(train %>% select(Name, Soyad, Ad))
## # A tibble: 6 × 3
##   Name              Soyad       Ad    
##   <chr>             <chr>       <chr> 
## 1 Maham Ofracculy   Ofracculy   Maham 
## 2 Juanna Vines      Vines       Juanna
## 3 Altark Susent     Susent      Altark
## 4 Solam Susent      Susent      Solam 
## 5 Willy Santantines Santantines Willy 
## 6 Sandie Hinetthews Hinetthews  Sandie

Bu sayede iki yeni değişken elde ettik:

•   Soyad: Yolcunun soyadını gösterir.
•   Ad: Yolcunun adını gösterir.

Bu yeni değişkenler, yolcuların isimlerini anlamamıza yardımcı olabilir. Bu bilgiler, modelin performansını artırmak için kullanılabilir. Örneğin:

• Bazı soyadlar belirli demografik gruplarla ilişkilendirilebilir.

• Adlar, kültürel veya coğrafi kökenler hakkında ipuçları verebilir.

3.3 Boş Değerlerin Doldurulması

Veri setindeki eksik (NA) değerlerin doldurulması, veri ön işleme sürecinde kritik bir adımdır. Eksik veriler, model performansını olumsuz etkileyebilir, bu nedenle uygun yöntemlerle doldurulmaları önemlidir.

3.3.1 HomePlanet Değişkeni

Yolcuların gezegen bilgisi olan HomePlanet değişkeninde eksik değerler bulunmaktadır. Bu eksik değerleri doldurmak için, yolcuların diğer özelliklerine (örneğin, Cabin, Destination) dayanarak en olası gezegeni atayabiliriz.

Home_Planet_GrupNO_bilgi <- train %>%
  group_by(Grup_No) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_HP_bilgisi_bos       = sum(is.na(HomePlanet)),           
    kacinin_HP_bilgisi_dolu   = sum(!is.na(HomePlanet)),         
    Grup_kac_farkli_HP  = n_distinct(HomePlanet, na.rm = TRUE)
  ) %>%
  ungroup()

head(Home_Planet_GrupNO_bilgi)
## # A tibble: 6 × 5
##   Grup_No grup_kac_kisi kacinin_HP_bilgisi_bos kacinin_HP_bilgisi_dolu
##   <fct>           <int>                  <int>                   <int>
## 1 0001                1                      0                       1
## 2 0002                1                      0                       1
## 3 0003                2                      0                       2
## 4 0004                1                      0                       1
## 5 0005                1                      0                       1
## 6 0006                2                      0                       2
## # ℹ 1 more variable: Grup_kac_farkli_HP <int>

Yukarıdaki kod, train veri setindeki yolcuları Grup_No değişkenine göre gruplar ve her grup için çeşitli istatistikleri hesaplar. summarize() fonksiyonu kullanılarak, her grup içindeki toplam yolcu sayısı (grup_kac_kisi), HomePlanet bilgisi eksik olan yolcu sayısı (kacinin_HP_bilgisi_bos), HomePlanet bilgisi dolu olan yolcu sayısı (kacinin_HP_bilgisi_dolu) ve grup içindeki farklı HomePlanet sayısı (Grup_kac_farkli_HP) hesaplanır. Son olarak, ungroup() ile gruplama kaldırılır. Bu özet bilgiler, HomePlanet değişkenindeki eksik değerleri doldurmak için kullanılabilir ve her grubun gezegen bilgisi hakkında daha iyi bir anlayış sağlar.

table(Home_Planet_GrupNO_bilgi$Grup_kac_farkli_HP)
## 
##    0    1 
##  110 6107
grup_0 <- Home_Planet_GrupNO_bilgi %>%
  filter(Grup_kac_farkli_HP == 0)

# Bu gruplarda kaç tane dolu HP var?
sum(grup_0$kacinin_HP_bilgisi_dolu)
## [1] 0

Yukarıdaki kod, Home_Planet_GrupNO_bilgi veri setinden Grup_kac_farkli_HP değeri 0 olan grupları filtreler ve grup_0 adlı yeni bir veri seti oluşturur.

Bu, 0 farklı HomePlanet görülen 110 grubun tamamında gerçekten hiç HP kaydı olmadığını ispatlar.

grup_1 <- Home_Planet_GrupNO_bilgi %>%
  filter(Grup_kac_farkli_HP == 1)

Yukarıdaki kod, Home_Planet_GrupNO_bilgi veri setinden Grup_kac_farkli_HP değeri 1 olan grupları filtreler ve grup_1 adlı yeni bir veri seti oluşturur. Bu gruplar, HomePlanet bilgisi eksik olan yolcuların bulunduğu ancak grup içindeki diğer yolcuların HomePlanet bilgisi dolu olduğu gruplardır. Bu bilgi, eksik HomePlanet değerlerini doldurmak için kullanılabilir, çünkü aynı gruptaki diğer yolcuların gezegen bilgisi, eksik olan yolcular için en olası değeri belirlemeye yardımcı olabilir.

# Bu grupların içindeki HomePlanet değerlerini görelim
table(grup_1$Grup_kac_farkli_HP, useNA = "ifany")
## 
##    1 
## 6107

Yukarıdaki kod, grup_1 veri setindeki Grup_kac_farkli_HP değişkeninin frekans dağılımını görüntüler. table() fonksiyonu kullanılarak, bu grupların içindeki HomePlanet değerlerinin dağılımı ve eksik (NA) değerlerin varlığı hakkında bilgi edinilir. useNA = “ifany” parametresi, eğer varsa eksik değerlerin de tabloya dahil edilmesini sağlar. Bu analiz, eksik HomePlanet değerlerini doldurmak için kullanılabilecek en olası gezegenleri belirlemeye yardımcı olabilir.

Bir grupta dolu HomePlanet varsa tüm üyelerde aynıdır. Aynı grupta iki farklı gezegen asla görülmemiştir. Bu nedenle, eksik HomePlanet değerlerini doldurmak için grup içindeki dolu HomePlanet değerini kullanabiliriz.

# 1) Her grup için referans HomePlanet bilgisini çıkaralım
hp_referans_train <- train %>%
  group_by(Grup_No) %>%
  summarise(
    Grup_HP = HomePlanet[!is.na(HomePlanet)][1],  # gruptaki ilk dolu HomePlanet
    .groups = "drop"
  )

hp_referans_test <- test %>%
  group_by(Grup_No) %>%
  summarise(
    Grup_HP = HomePlanet[!is.na(HomePlanet)][1],  # gruptaki ilk dolu HomePlanet
    .groups = "drop"
  )
head(hp_referans_train)
## # A tibble: 6 × 2
##   Grup_No Grup_HP
##   <fct>   <fct>  
## 1 0001    Europa 
## 2 0002    Earth  
## 3 0003    Europa 
## 4 0004    Earth  
## 5 0005    Earth  
## 6 0006    Earth

Yukarıdaki kod, train veri setindeki yolcuları Grup_No değişkenine göre gruplar ve her grup için ilk dolu HomePlanet değerini çıkararak hp_referans_train adlı yeni bir veri seti oluşturur. summarise() fonksiyonu kullanılarak, her grup içindeki HomePlanet bilgisi eksik olmayan ilk değeri (Grup_HP) belirlenir. .groups = “drop” parametresi, gruplama işleminin ardından gruplama yapısını kaldırır. Bu referans HomePlanet bilgisi, eksik HomePlanet değerlerini doldurmak için kullanılabilir.

# 2) Orijinal train veri seti ile bu referans bilgiyi birleştirelim
train <- train %>%
  left_join(hp_referans_train, by = "Grup_No")
test <- test %>%
  left_join(hp_referans_test, by = "Grup_No")
head(train %>% select(PassengerId, HomePlanet, Grup_HP))
## # A tibble: 6 × 3
##   PassengerId HomePlanet Grup_HP
##   <chr>       <fct>      <fct>  
## 1 0001_01     Europa     Europa 
## 2 0002_01     Earth      Earth  
## 3 0003_01     Europa     Europa 
## 4 0003_02     Europa     Europa 
## 5 0004_01     Earth      Earth  
## 6 0005_01     Earth      Earth

Yukarıdaki kod, train ve test veri setlerine hp_referans_train ve hp_referans_test veri setlerinden elde edilen referans HomePlanet bilgilerini ekler. left_join() fonksiyonu kullanılarak, her iki veri seti Grup_No değişkeni üzerinden birleştirilir. Bu işlem sonucunda, her yolcunun ait olduğu grubun referans HomePlanet bilgisi (Grup_HP) orijinal veri setine eklenir. Bu yeni bilgi, eksik HomePlanet değerlerini doldurmak için kullanılabilir.

# 3) Eksik HomePlanet değerlerini dolduralım
train <- train %>%
  mutate(HomePlanet = coalesce(HomePlanet, Grup_HP)) %>%
  select(-Grup_HP)
test <- test %>%
  mutate(HomePlanet = coalesce(HomePlanet, Grup_HP)) %>%
  select(-Grup_HP)  # artık gerek yok, silebiliriz

Yukarıdaki kod, train ve test veri setlerindeki eksik (NA) HomePlanet değerlerini doldurur. mutate() fonksiyonu kullanılarak, ifelse() ile HomePlanet değeri eksik olan yolcular için Grup_HP (grup referans HomePlanet) değeri atanır; eğer HomePlanet değeri dolu ise mevcut değeri korunur. Ardından, select(-Grup_HP) ile artık ihtiyaç duyulmayan Grup_HP sütunu veri setinden kaldırılır. Bu işlem sonucunda, HomePlanet değişkenindeki eksik değerler uygun şekilde doldurulmuş olur.

soyad_planet_analizi <- train %>%
  group_by(Soyad) %>%
  summarise(
    soyad_kac_kisi = n(),
    kac_farkli_HP = n_distinct(HomePlanet, na.rm = TRUE),
    hangi_HP = paste(unique(HomePlanet[!is.na(HomePlanet)]), collapse = ", "),
    .groups = "drop"
  )
head(soyad_planet_analizi)
## # A tibble: 6 × 4
##   Soyad      soyad_kac_kisi kac_farkli_HP hangi_HP
##   <chr>               <int>         <int> <chr>   
## 1 Acobson                 4             1 "Earth" 
## 2 Acobsond                3             1 "Earth" 
## 3 Adavisons               9             1 "Earth" 
## 4 Adkinson                3             1 "Earth" 
## 5 Admingried              4             1 "Europa"
## 6 Ageurante               1             0 ""

Yukarıdaki kod, train veri setindeki yolcuları Soyad değişkenine göre gruplar ve her soyad için çeşitli istatistikleri hesaplar. summarise() fonksiyonu kullanılarak, her soyad içindeki toplam yolcu sayısı (soyad_kac_kisi), farklı HomePlanet sayısı (kac_farkli_HP) ve dolu HomePlanet değerlerinin birleşik bir listesini (hangi_HP) oluşturur. na.rm = TRUE parametresi, eksik (NA) değerlerin hesaplamalara dahil edilmemesini sağlar. Son olarak, .groups = “drop” ile gruplama kaldırılır. Bu özet bilgiler, soyad bazında HomePlanet dağılımını anlamamıza yardımcı olur ve eksik HomePlanet değerlerini doldurmak için kullanılabilir.

table(soyad_planet_analizi$kac_farkli_HP)
## 
##    0    1    3 
##    7 2210    1

Soyad bazında HomePlanet tutarlılığını incelediğimizde 2210 farklı soyadın tamamının yalnızca tek bir gezegenden geldiği görülmüştür. Bu, soyadın aile yapısını doğru şekilde temsil ettiğini ve eksik HomePlanet değerlerini soyad bazında doldurmanın mantıklı olduğunu destekler.

Ancak analizde yalnızca bir özel durum ortaya çıkmaktadır: Soyad = NA olan yolcuların bulunduğu tek grup, üç farklı gezegenden gelen kişiler içermektedir. Bu durum soyad bilgisi tamamen eksik olan bu kişilerin aslında bir soyadı paylaşmadıklarını, sadece soyadları bulunmadığı için aynı kategoriye düştüklerini göstermektedir. Bu nedenle bu grup, bir aileyi temsil etmez ve HomePlanet açısından tutarsız görünmesi tamamen beklenen bir durumdur.

Bu bulgu, gerçek soyadı olan yolcular arasında herhangi bir tutarsızlık olmadığını ve soyadının aile ilişkilerini temsil etmek için güvenilir bir değişken olduğunu doğrulamaktadır.

hp_referans_soyad <- soyad_planet_analizi %>%
filter(kac_farkli_HP == 1) %>%
  select(Soyad, Soyad_HP = hangi_HP)
head(hp_referans_soyad)
## # A tibble: 6 × 2
##   Soyad      Soyad_HP
##   <chr>      <chr>   
## 1 Acobson    Earth   
## 2 Acobsond   Earth   
## 3 Adavisons  Earth   
## 4 Adkinson   Earth   
## 5 Admingried Europa  
## 6 Aginge     Europa
# Orijinal train veri seti ile bu referans bilgiyi birleştirelim
train <- train %>%
  left_join(hp_referans_soyad, by = "Soyad")
test <- test %>%
  left_join(hp_referans_soyad, by = "Soyad")
# Dolduralım
train <- train %>%
  mutate(HomePlanet = coalesce(HomePlanet, Soyad_HP)) %>%
  select(-Soyad_HP)
test <- test %>%
  mutate(HomePlanet = coalesce(HomePlanet, Soyad_HP)) %>%
  select(-Soyad_HP)  # Soyad_HP gerek yok, silebiliriz

Yukarıdaki kod, train ve test veri setlerine hp_referans_soyad veri setinden elde edilen referans HomePlanet bilgilerini ekler. left_join() fonksiyonu kullanılarak, her iki veri seti Soyad değişkeni üzerinden birleştirilir. Bu işlem sonucunda, her yolcunun soyadına karşılık gelen referans HomePlanet bilgisi (Soyad_HP) orijinal veri setine eklenir. Ardından, mutate() fonksiyonu ile ifelse() kullanılarak HomePlanet değeri eksik olan yolcular için Soyad_HP değeri atanır; eğer HomePlanet değeri dolu ise mevcut değeri korunur. Son olarak, select(-Soyad_HP) ile artık ihtiyaç duyulmayan Soyad_HP sütunu veri setinden kaldırılır. Bu işlem sonucunda, HomePlanet değişkenindeki eksik değerler uygun şekilde doldurulmuş olur.

Home_Planet_Deck_bilgi <- train %>%
  group_by(Deck) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_HP_bilgisi_bos       = sum(is.na(HomePlanet)),           
    kacinin_HP_bilgisi_dolu   = sum(!is.na(HomePlanet)),         
    Grup_kac_farkli_HP  = n_distinct(HomePlanet, na.rm = TRUE),
    hangi_HP = paste(unique(HomePlanet[!is.na(HomePlanet)]), collapse = ", "),
  ) %>%
  ungroup()

Home_Planet_Deck_bilgi
## # A tibble: 7 × 6
##   Deck  grup_kac_kisi kacinin_HP_bilgisi_bos kacinin_HP_bilgisi_dolu
##   <fct>         <int>                  <int>                   <int>
## 1 Diğer           739                      2                     737
## 2 B               779                      0                     779
## 3 C               747                      1                     746
## 4 E               876                      1                     875
## 5 F              2794                      6                    2788
## 6 G              2559                      2                    2557
## 7 <NA>            199                      0                     199
## # ℹ 2 more variables: Grup_kac_farkli_HP <int>, hangi_HP <chr>

Yukarıdaki kod, train veri setindeki yolcuları Deck değişkenine göre gruplar ve her güverte için çeşitli istatistikleri hesaplar. summarize() fonksiyonu kullanılarak, her güverte içindeki toplam yolcu sayısı (grup_kac_kisi), HomePlanet bilgisi eksik olan yolcu sayısı (kacinin_HP_bilgisi_bos), HomePlanet bilgisi dolu olan yolcu sayısı (kacinin_HP_bilgisi_dolu), farklı HomePlanet sayısı (Grup_kac_farkli_HP) ve dolu HomePlanet değerlerinin birleşik bir listesini (hangi_HP) oluşturur. na.rm = TRUE parametresi, eksik (NA) değerlerin hesaplamalara dahil edilmemesini sağlar. Son olarak, ungroup() ile gruplama kaldırılır. Bu özet bilgiler, Deck değişkeni bazında HomePlanet dağılımını anlamamıza yardımcı olur ve eksik HomePlanet değerlerini doldurmak için kullanılabilir. B ve C, Europa gezegeninden yolcuların, G ise Earth yolcularının konakladığı Deckler.

# Deck bazında dolduralım
hp_referans_deck <- Home_Planet_Deck_bilgi %>%
  filter(Grup_kac_farkli_HP == 1) %>%
  select(Deck, Deck_HP = hangi_HP)
head(hp_referans_deck)
## # A tibble: 3 × 2
##   Deck  Deck_HP
##   <fct> <chr>  
## 1 B     Europa 
## 2 C     Europa 
## 3 G     Earth
# Orijinal train veri seti ile bu referans bilgiyi birleştirelim
train <- train %>%
  left_join(hp_referans_deck, by = "Deck")
test <- test %>%
  left_join(hp_referans_deck, by = "Deck")
# Dolduralım
train <- train %>%
  mutate(HomePlanet = coalesce(HomePlanet, Deck_HP)) %>%
  select(-Deck_HP)
test <- test %>%
  mutate(HomePlanet = coalesce(HomePlanet, Deck_HP)) %>%
  select(-Deck_HP)  # artık gerek yok, silebiliriz
train <- train %>%
  mutate(HomePlanet = coalesce(HomePlanet, "Earth"))
test <- test %>%
  mutate(HomePlanet = coalesce(HomePlanet, "Earth"))

Yukarıdaki kod, train ve test veri setlerindeki eksik (NA) HomePlanet değerlerini “Earth” olarak doldurur. mutate() fonksiyonu kullanılarak, coalesce() ile HomePlanet değeri eksik olan yolcular için “Earth” değeri atanır; eğer HomePlanet değeri dolu ise mevcut değeri korunur. Bu işlem sonucunda, HomePlanet değişkenindeki tüm eksik değerler uygun şekilde doldurulmuş olur.

sum(is.na(train$HomePlanet))
## [1] 0
sum(is.na(test$HomePlanet))
## [1] 0
train$HomePlanet <- as.factor(train$HomePlanet)
test$HomePlanet <- as.factor(test$HomePlanet)

3.3.2 Destination Değişkeni

Destination değişkeni, yolcuların varış noktalarını temsil eder ve bazı eksik değerlere sahiptir. Bu eksik değerleri doldurmak için, yolcuların diğer özelliklerine (örneğin, HomePlanet, Cabin) dayanarak en olası varış noktasını atayabiliriz.

Dest_deck_bilgi <- train %>%
  group_by(Deck) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_D_bilgisi_bos       = sum(is.na(Destination)),           
    kacinin_D_bilgisi_dolu   = sum(!is.na(Destination)),         
    Grup_kac_farkli_D = n_distinct(Destination, na.rm = TRUE),
    hangi_D = paste(unique(Destination[!is.na(Destination)]), collapse = ", "),
  ) %>%
  ungroup() 

table(Dest_deck_bilgi$Grup_kac_farkli_D)
## 
## 3 
## 7

Yukarıdaki kod, train veri setindeki yolcuları Grup_No değişkenine göre gruplar ve her grup için çeşitli istatistikleri hesaplar. summarize() fonksiyonu kullanılarak, her grup içindeki toplam yolcu sayısı (grup_kac_kisi), Destination bilgisi eksik olan yolcu sayısı (kacinin_D_bilgisi_bos), Destination bilgisi dolu olan yolcu sayısı (kacinin_D_bilgisi_dolu), farklı Destination sayısı (Grup_kac_farkli_D) ve dolu Destination değerlerinin birleşik bir listesini (hangi_D) oluşturur. na.rm = TRUE parametresi, eksik (NA) değerlerin hesaplamalara dahil edilmemesini sağlar. Son olarak, ungroup() ile gruplama kaldırılır. Bu özet bilgiler, Destination değişkenindeki eksik değerleri doldurmak için yeterli değil.

Dest_Ad_bilgi <- train %>%
  group_by(Ad) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_D_bilgisi_bos       = sum(is.na(Destination)),           
    kacinin_D_bilgisi_dolu   = sum(!is.na(Destination)),         
    Grup_kac_farkli_D = n_distinct(Destination, na.rm = TRUE),
    hangi_D = paste(unique(Destination[!is.na(Destination)]), collapse = ", "),
  ) %>%
  ungroup() %>%
  filter(grup_kac_kisi > 1) 

table(Dest_Ad_bilgi$Grup_kac_farkli_D)
## 
##    1    2    3 
##  770 1054  270
Dest_Soyad_bilgi <- train %>%
  group_by(Soyad) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_D_bilgisi_bos       = sum(is.na(Destination)),           
    kacinin_D_bilgisi_dolu   = sum(!is.na(Destination)),         
    Grup_kac_farkli_D = n_distinct(Destination, na.rm = TRUE),
    hangi_D = paste(unique(Destination[!is.na(Destination)]), collapse = ", "),
  ) %>%
  ungroup() %>%
  filter(grup_kac_kisi > 1) 

table(Dest_Soyad_bilgi$Grup_kac_farkli_D)
## 
##   1   2   3 
## 620 948 268

Belirli bir ada veya soyada sahip yolcuların varış noktaları genellikle tutarlı değil.

library(rpart)
## 
## Присоединяю пакет: 'rpart'
## Следующий объект скрыт от 'package:dials':
## 
##     prune
library(rpart.plot)
dt_model <- rpart(
  Destination ~ HomePlanet + Deck + Side + Age + CryoSleep + VIP + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train %>% filter(!is.na(Destination)),
  method = "class",
  cp = 0.00221
)
rpart.plot(
  dt_model
)

Yukarıdaki kod, karar ağacı (decision tree) modeli oluşturmak için rpart paketini kullanır. rpart() fonksiyonu ile Destination değişkenini tahmin etmek için bir model kurulur. Modelde açıklayıcı değişkenler olarak HomePlanet, Deck, Side, Age, CryoSleep, VIP, RoomService, FoodCourt, ShoppingMall, Spa, VRDeck, Grup_Buyuklugu_Kat ve Yalniz_Seyahat kullanılır. Model, yalnızca Destination değeri eksik olmayan yolcular üzerinde eğitilir (filter(!is.na(Destination))). method = "class" parametresi, sınıflandırma problemi olduğunu belirtir ve cp = 0.00221 parametresi, modelin karmaşıklığını kontrol eden bir kesme parametresidir.

# 1) Sadece Destination NA olanları tahmin edelim
train$Destination_tree_pred <- predict(
  dt_model,
  newdata = train,
  type   = "class"
)

Yukarıdaki kod, oluşturulan karar ağacı modelini kullanarak train veri setindeki yolcular için Destination tahminleri yapar. predict() fonksiyonu ile dt_model kullanılarak, train veri setindeki her yolcu için tahmin edilen Destination değerleri hesaplanır. type = "class" parametresi, sınıflandırma problemlerinde sınıf etiketlerinin döndürülmesini sağlar. Elde edilen tahminler, Destination_tree_pred adlı yeni bir sütun olarak train veri setine eklenir. Bu tahminler, eksik Destination değerlerini doldurmak için kullanılabilir.

test$Destination_tree_pred <- predict(
  dt_model,
  newdata = test,
  type   = "class"
)

Yukarıdaki kod, oluşturulan karar ağacı modelini kullanarak test veri setindeki yolcular için Destination tahminleri yapar. predict() fonksiyonu ile dt_model kullanılarak, test veri setindeki her yolcu için tahmin edilen Destination değerleri hesaplanır. type = “class” parametresi, sınıflandırma problemlerinde sınıf etiketlerinin döndürülmesini sağlar. Elde edilen tahminler, Destination_tree_pred adlı yeni bir sütun olarak test veri setine eklenir. Bu tahminler, eksik Destination değerlerini doldurmak için kullanılabilir.

rpart.rules(
  dt_model,
  style = "tall",       # her kural alt alta, daha okunaklı
  cover = TRUE,         # her kuralın kaç gözlemi kapsadığını gösterir
  nn    = TRUE          # node numaralarını gösterir
)
##                                    55 C PSO  TRAP 
## [128]  Destination is 55 Cancri e [ .55  .02  .43] with cover 3% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 62
##            Deck is C
##            Grup_Buyuklugu_Kat is 1 or 2 or 4+
## 
## [260]  Destination is 55 Cancri e [ .61  .00  .39] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 36 to 47
##            Deck is Diğer or B or E
## 
## [4184] Destination is 55 Cancri e [ .62  .00  .38] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 27
##            Deck is Diğer or B
##            VIP is FALSE
##            Grup_Buyuklugu_Kat is 1 or 3 or 4+
## 
## [84]   Destination is 55 Cancri e [ .62  .11  .28] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            VIP is TRUE
##            FoodCourt is 16 to 9637
##            VRDeck >= 1110
## 
## [170]  Destination is 55 Cancri e [ .64  .00  .36] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            VIP is FALSE
##            FoodCourt is 16 to 9637
##            VRDeck >= 1110
##            RoomService >= 70
## 
## [342]  Destination is 55 Cancri e [ .68  .00  .32] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            VIP is FALSE
##            FoodCourt is 16 to 9637
##            VRDeck is 1110 to 1373
##            RoomService < 70
## 
## [20]   Destination is 55 Cancri e [ .71  .00  .29] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            FoodCourt >= 9637
## 
## [522]  Destination is 55 Cancri e [ .78  .00  .22] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 36
##            Deck is Diğer or B or E
##            VIP is TRUE
## 
## [2093] Destination is TRAPPIST-1e [ .43  .01  .57] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 27 to 36
##            Deck is Diğer or B or E
##            VIP is FALSE
##            Grup_Buyuklugu_Kat is 1 or 3 or 4+
## 
## [1047] Destination is TRAPPIST-1e [ .42  .01  .57] with cover 2% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 36
##            Deck is Diğer or B or E
##            VIP is FALSE
##            Grup_Buyuklugu_Kat is 2
## 
## [129]  Destination is TRAPPIST-1e [ .36  .06  .58] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 62
##            Deck is C
##            Grup_Buyuklugu_Kat is 3
## 
## [131]  Destination is TRAPPIST-1e [ .39  .00  .61] with cover 1% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 47 to 62
##            Deck is Diğer or B or E
## 
## [343]  Destination is TRAPPIST-1e [ .36  .00  .64] with cover 3% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            VIP is FALSE
##            FoodCourt is 16 to 9637
##            VRDeck >= 1373
##            RoomService < 70
## 
## [33]   Destination is TRAPPIST-1e [ .36  .00  .64] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 5 to 15
## 
## [43]   Destination is TRAPPIST-1e [ .33  .01  .66] with cover 7% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            FoodCourt is 16 to 9637
##            VRDeck < 1110
## 
## [3]    Destination is TRAPPIST-1e [ .14  .12  .74] with cover 75% when
##            HomePlanet is Earth or Mars
## 
## [4185] Destination is TRAPPIST-1e [ .25  .00  .75] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age is 15 to 27
##            Deck is E
##            VIP is FALSE
##            Grup_Buyuklugu_Kat is 1 or 3 or 4+
## 
## [17]   Destination is TRAPPIST-1e [ .23  .00  .77] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age >= 62
## 
## [11]   Destination is TRAPPIST-1e [ .16  .00  .84] with cover 2% when
##            HomePlanet is Europa
##            CryoSleep is FALSE
##            FoodCourt < 16
## 
## [9]    Destination is TRAPPIST-1e [ .00  .00 1.00] with cover 0% when
##            HomePlanet is Europa
##            CryoSleep is TRUE
##            Age < 5
train <- train %>%
  mutate(
    Destination_tree_pred2 = case_when(
      # [128] 55 Cancri e, cover 3%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 62 &
        Deck == "C" &
        Grup_Buyuklugu_Kat %in% c("1", "2", "4+") ~ "55 Cancri e",
      
      # [260] 55 Cancri e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 36 & Age <= 47 &
        Deck %in% c("Diğer", "B", "E") ~ "55 Cancri e",
      
      # [4184] 55 Cancri e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 27 &
        Deck %in% c("Diğer", "B") &
        VIP == FALSE &
        Grup_Buyuklugu_Kat %in% c("1", "3", "4+") ~ "55 Cancri e",
      
      # [84] 55 Cancri e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        VIP == TRUE &
        FoodCourt >= 16 & FoodCourt <= 9637 &
        VRDeck >= 1110 ~ "55 Cancri e",
      
      # [170] 55 Cancri e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        VIP == FALSE &
        FoodCourt >= 16 & FoodCourt <= 9637 &
        VRDeck >= 1110 &
        RoomService >= 70 ~ "55 Cancri e",
      
      # [342] 55 Cancri e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        VIP == FALSE &
        FoodCourt >= 16 & FoodCourt <= 9637 &
        VRDeck >= 1110 & VRDeck <= 1373 &
        RoomService < 70 ~ "55 Cancri e",
      
      # [20] 55 Cancri e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        FoodCourt >= 9637 ~ "55 Cancri e",
      
      # [522] 55 Cancri e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 36 &
        Deck %in% c("Diğer", "B", "E") &
        VIP == TRUE ~ "55 Cancri e",
      
      # [2093] TRAPPIST-1e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 27 & Age <= 36 &
        Deck %in% c("Diğer", "B", "E") &
        VIP == FALSE &
        Grup_Buyuklugu_Kat %in% c("1", "3", "4+") ~ "TRAPPIST-1e",
      
      # [1047] TRAPPIST-1e, cover 2%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 36 &
        Deck %in% c("Diğer", "B", "E") &
        VIP == FALSE &
        Grup_Buyuklugu_Kat %in% c("2") ~ "TRAPPIST-1e",
      
      # [129] TRAPPIST-1e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 62 &
        Deck == "C" &
        Grup_Buyuklugu_Kat %in% c("3") ~ "TRAPPIST-1e",
      
      # [131] TRAPPIST-1e, cover 1%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 47 & Age <= 62 &
        Deck %in% c("Diğer", "B", "E") ~ "TRAPPIST-1e",
      
      # [343] TRAPPIST-1e, cover 3%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        VIP == FALSE &
        FoodCourt >= 16 & FoodCourt <= 9637 &
        VRDeck >= 1373 &
        RoomService < 70 ~ "TRAPPIST-1e",
      
      # [33] TRAPPIST-1e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 5 & Age <= 15 ~ "TRAPPIST-1e",
      
      # [43] TRAPPIST-1e, cover 7%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        FoodCourt >= 16 & FoodCourt <= 9637 &
        VRDeck < 1110 ~ "TRAPPIST-1e",
      
      # [3] TRAPPIST-1e, cover 75% (Earth & Mars)
      HomePlanet %in% c("Earth", "Mars") ~ "TRAPPIST-1e",
      
      # [4185] TRAPPIST-1e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 15 & Age <= 27 &
        Deck == "E" &
        VIP == FALSE &
        Grup_Buyuklugu_Kat %in% c("1", "3", "4+") ~ "TRAPPIST-1e",
      
      # [17] TRAPPIST-1e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age >= 62 ~ "TRAPPIST-1e",
      
      # [11] TRAPPIST-1e, cover 2%
      HomePlanet == "Europa" &
        CryoSleep == FALSE &
        FoodCourt < 16 ~ "TRAPPIST-1e",
      
      # [9] TRAPPIST-1e, cover 0%
      HomePlanet == "Europa" &
        CryoSleep == TRUE &
        Age < 5 ~ "TRAPPIST-1e",
      
      # Hiçbir kurala girmeyen varsa (teorik olarak kalmamalı)
      TRUE ~ "TRAPPIST-1e"
    )
  )

Yukarıdaki kod, train veri setinde yolcuların olası varış noktalarını kural temelli bir yaklaşımla tahmin etmek için yeni bir değişken olan Destination_tree_pred2 oluşturur. mutate() fonksiyonu içerisine yerleştirilen case_when() ifadesi, HomePlanet, CryoSleep, Age, Deck, VIP, harcama değişkenleri ve Grup_Buyuklugu_Kat gibi özelliklere dayalı olarak bir dizi koşulu sırayla kontrol eder. Her koşul sağlandığında ilgili yolcuya “55 Cancri e” veya “TRAPPIST-1e” atanır.

Koşullar, karar ağacından elde edilen bölünmelere benzeyen mantıksal kurallar şeklinde yazılmıştır; böylece modelin bulguları elle kural setine dönüştürülmüş olur. Son satırdaki TRUE ~ "TRAPPIST-1e" ifadesi ise hiçbir kurala girmeyen gözlemler için varsayılan değeri belirler. Elde edilen Destination_tree_pred2 değişkeni, eksik varış bilgilerini doldurmak, model karşılaştırmaları yapmak veya tahmin performansını artırmak amacıyla açıklayıcı bir özellik olarak kullanılabilir.

train$Destination_tree_pred2 <- factor(
  train$Destination_tree_pred2,
  levels = levels(train$Destination)
)
mean(train$Destination_tree_pred == train$Destination_tree_pred2)
## [1] 0.990222

Yukarıdaki kod, train veri setindeki yolcular için Destination_tree_pred2 adlı yeni bir sütun oluşturur. mutate() fonksiyonu kullanılarak, case_when() ile belirli kurallara dayalı olarak her yolcunun tahmin edilen varış noktası (Destination) atanır. Kurallar, yolcuların özelliklerine (örneğin, HomePlanet, CryoSleep, Age, Deck, VIP, FoodCourt, VRDeck, RoomService, Grup_Buyuklugu_Kat) dayanır ve her kural belirli bir varış noktasını temsil eder. Eğer bir yolcu hiçbir kurala uymuyorsa, varsayılan olarak “TRAPPIST-1e” atanır. Bu işlem sonucunda, her yolcunun tahmin edilen varış noktası belirlenmiş olur.

# 2) Destination NA olan yerleri tree tahminiyle dolduralım
train <- train %>%
  mutate(
    Destination = ifelse(
      is.na(Destination),
      as.character(Destination_tree_pred),
      as.character(Destination)
    ),
    Destination = factor(Destination)
  )
test <- test %>%
  mutate(
    Destination = ifelse(
      is.na(Destination),
      as.character(Destination_tree_pred),
      as.character(Destination)
    ),
    Destination = factor(Destination)
  )

Yukarıdaki kod, train ve test veri setlerindeki eksik (NA) Destination değerlerini doldurur. mutate() fonksiyonu kullanılarak, ifelse() ile Destination değeri eksik olan yolcular için Destination_tree_pred (karar ağacı modeli tarafından tahmin edilen değer) atanır; eğer Destination değeri dolu ise mevcut değeri korunur. Ardından, factor() fonksiyonu ile Destination değişkeni faktör (categorical) veri tipine dönüştürülür ve orijinal seviyeleri korunur. Bu işlem sonucunda, Destination değişkenindeki tüm eksik değerler uygun şekilde doldurulmuş olur.

# Tahmin sütunlarını silelim
train <- train %>%
  select(-Destination_tree_pred, -Destination_tree_pred2)
test <- test %>%
  select(-Destination_tree_pred)
library(explore)
describe_all(train)
## # A tibble: 24 × 8
##    variable    type     na na_pct unique   min   mean   max
##    <chr>       <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId chr       0    0     8693    NA  NA       NA
##  2 Grup_No     fct       0    0     6217    NA  NA       NA
##  3 Kisi_No     int       0    0        8     1   1.52     8
##  4 HomePlanet  fct       0    0        3    NA  NA       NA
##  5 CryoSleep   fct     217    2.5      3    NA  NA       NA
##  6 Cabin       chr     199    2.3   6561    NA  NA       NA
##  7 Deck        fct     199    2.3      7    NA  NA       NA
##  8 Numara      int     199    2.3   1818     0 600.    1894
##  9 Side        fct     199    2.3      3    NA  NA       NA
## 10 Destination fct       0    0        3    NA  NA       NA
## # ℹ 14 more rows

3.3.3 CryoSleep Değişkeni

CryoSleep değişkeni, yolcuların kriyosit (dondurulmuş uyku) durumunu temsil eder ve bazı eksik değerlere sahiptir. Bu eksik değerleri doldurmak için, yolcuların diğer özelliklerine (örneğin, HomePlanet, Destination, Cabin) dayanarak en olası kriyosit durumunu atayabiliriz.

summary(train$CryoSleep)
## FALSE  TRUE  NA's 
##  5439  3037   217

Yukarıdaki kod, train veri setindeki CryoSleep değişkenine ait özet bilgileri elde eder. summary() fonksiyonu kullanılarak, değişkenin aldığı değerlerin dağılımı ve varsa eksik (NA) gözlemler raporlanır. CryoSleep mantıksal ya da kategorik bir değişken olduğundan, fonksiyon her bir kategori için kaç gözlem bulunduğunu ve kaç adet eksik değer olduğunu gösterir. Bu çıktı, CryoSleep değişkeninde veri yoğunluğunu, dengesizlik olup olmadığını ve eksik veri miktarını hızlıca görmemizi sağlayarak, veri temizleme ve modelleme aşamalarına temel oluşturur.

train %>%
  mutate(RS = ifelse(RoomService>0, "BZ", "Z")) %>%
  group_by(RS) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_CS_bilgisi_bos       = sum(is.na(CryoSleep)),           
    kacinin_CS_bilgisi_dolu   = sum(!is.na(CryoSleep)),         
    Grup_kac_farkli_CS  = n_distinct(CryoSleep, na.rm = TRUE)
  ) %>%
  ungroup()
## # A tibble: 3 × 5
##   RS    grup_kac_kisi kacinin_CS_bilgisi_bos kacinin_CS_bilgisi_dolu
##   <chr>         <int>                  <int>                   <int>
## 1 BZ             2935                     71                    2864
## 2 Z              5577                    144                    5433
## 3 <NA>            181                      2                     179
## # ℹ 1 more variable: Grup_kac_farkli_CS <int>

Yukarıdaki kod, önce RoomService değişkenine göre yeni bir RS değişkeni oluşturur. mutate() fonksiyonu kullanılarak, RoomService tutarı 0’dan büyük olan yolcular “BZ”, diğerleri ise “Z” olarak sınıflandırılır. Daha sonra group_by() fonksiyonu ile veri RS değişkenine göre gruplandırılır ve her grup için özet istatistikler hesaplanır. summarize() içinde, gruptaki toplam kişi sayısı (n), CryoSleep değişkeni eksik (NA) olanların sayısı, CryoSleep bilgisi dolu olanların sayısı ve grupta yer alan farklı CryoSleep değerlerinin sayısı elde edilir. Son olarak ungroup() fonksiyonu ile gruplama kaldırılır. Bu işlemler sayesinde, RoomService kullanımının CryoSleep değişkeni ile ilişkisi incelenebilir ve eksik veri yapısı hakkında bilgi edinilebilir.

train <- train %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & RoomService > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))
test <- test %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & RoomService > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))
train %>%
  mutate(FC = ifelse(FoodCourt>0, "BZ", "Z")) %>%
  group_by(FC) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_CS_bilgisi_bos       = sum(is.na(CryoSleep)),           
    kacinin_CS_bilgisi_dolu   = sum(!is.na(CryoSleep)),         
    Grup_kac_farkli_CS  = n_distinct(CryoSleep, na.rm = TRUE)
  ) %>%
  ungroup()
## # A tibble: 3 × 5
##   FC    grup_kac_kisi kacinin_CS_bilgisi_bos kacinin_CS_bilgisi_dolu
##   <chr>         <int>                  <int>                   <int>
## 1 BZ             3054                     37                    3017
## 2 Z              5456                    108                    5348
## 3 <NA>            183                      1                     182
## # ℹ 1 more variable: Grup_kac_farkli_CS <int>

Yukarıdaki kod, yolcuların FoodCourt harcamalarına göre CryoSleep değişkeninin durumunu incelemek amacıyla özet istatistikler üretir. mutate() fonksiyonu ile önce FoodCourt değişkeni kullanılarak yeni bir FC değişkeni oluşturulur; FoodCourt tutarı 0’dan büyük olan yolcular “BZ”, harcaması olmayanlar ise “Z” olarak sınıflandırılır. Daha sonra group_by() ile veri FC değişkenine göre gruplandırılır ve summarize() fonksiyonu aracılığıyla her grup için toplam kişi sayısı, CryoSleep bilgisi eksik olan yolcu sayısı, CryoSleep bilgisi dolu olan yolcu sayısı ve grupta bulunan farklı CryoSleep değerlerinin sayısı hesaplanır. Son olarak ungroup() fonksiyonu ile gruplama kaldırılır. Bu işlem, FoodCourt harcamalarının CryoSleep değişkeniyle ilişkisini değerlendirmeye ve eksik veri yapısını daha iyi anlamaya yardımcı olur.

train <- train %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & FoodCourt > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))
test <- test %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & FoodCourt > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))

Yukarıdaki kod, hem train hem de test veri setlerinde yer alan CryoSleep değişkenindeki bazı eksik değerleri, yolcuların FoodCourt harcamaları dikkate alınarak yeniden düzenler. mutate() ve case_when() fonksiyonları kullanılarak, CryoSleep değeri NA olan ve FoodCourt harcaması 0’dan büyük olan yolcular için CryoSleep değeri “FALSE” olarak atanır; diğer tüm gözlemlerde mevcut değer korunur. Bu yaklaşım, kriyo uykusunda bulunan yolcuların FoodCourt hizmeti kullanamayacağı varsayımına dayanarak eksik verilerin daha tutarlı bir şekilde doldurulmasını sağlar ve hem eğitim hem de test verilerinde modelleme öncesi veri bütünlüğünün artırılmasına katkıda bulunur.

 train %>%
  mutate(SM = ifelse(ShoppingMall>0, "BZ", "Z")) %>%
  group_by(SM) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_CS_bilgisi_bos       = sum(is.na(CryoSleep)),           
    kacinin_CS_bilgisi_dolu   = sum(!is.na(CryoSleep)),         
    Grup_kac_farkli_CS  = n_distinct(CryoSleep, na.rm = TRUE)
  ) %>%
  ungroup()
## # A tibble: 3 × 5
##   SM    grup_kac_kisi kacinin_CS_bilgisi_bos kacinin_CS_bilgisi_dolu
##   <chr>         <int>                  <int>                   <int>
## 1 BZ             2898                      7                    2891
## 2 Z              5587                     98                    5489
## 3 <NA>            208                      4                     204
## # ℹ 1 more variable: Grup_kac_farkli_CS <int>

Yukarıdaki kod, yolcuların ShoppingMall harcamaları ile CryoSleep değişkeni arasındaki ilişkiyi incelemek için özet istatistikler oluşturur. Önce mutate() fonksiyonu ile ShoppingMall değişkeni kullanılarak yeni bir SM değişkeni tanımlanır; alışveriş merkezi harcaması 0’dan büyük olan yolcular “BZ”, harcaması olmayanlar ise “Z” olarak sınıflandırılır. Ardından group_by() fonksiyonu ile veri SM değişkenine göre gruplandırılır ve summarize() kullanılarak her grup için toplam kişi sayısı, CryoSleep bilgisi eksik olan yolcu sayısı, CryoSleep bilgisi bulunan yolcu sayısı ve grupta yer alan farklı CryoSleep değerlerinin sayısı hesaplanır. Son aşamada ungroup() fonksiyonu uygulanarak gruplama kaldırılır. Bu süreç, ShoppingMall harcamalarının CryoSleep değişkeniyle nasıl birlikte davrandığını ve eksik verilerin dağılımını daha iyi değerlendirmeye olanak sağlar.

train <- train %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & ShoppingMall > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))
test <- test %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & ShoppingMall > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))

Yukarıdaki kod, hem train hem de test veri setlerinde yer alan CryoSleep değişkenindeki bazı eksik değerleri, yolcuların ShoppingMall harcamalarına bakarak günceller. mutate() ve case_when() fonksiyonları kullanılarak, CryoSleep değeri NA olan ve ShoppingMall harcaması 0’dan büyük olan yolcular için CryoSleep değeri “FALSE” olarak atanır; diğer gözlemlerde mevcut değer aynen korunur. Bu işlem, kriyo uykusunda bulunan yolcuların alışveriş yapamayacağı varsayımına dayanarak eksik verilerin daha mantıklı biçimde doldurulmasını sağlar ve hem eğitim hem de test verisinde modelleme öncesi veri tutarlılığını artırır.

 train %>%
  mutate(SP = ifelse(Spa>0, "BZ", "Z")) %>%
  group_by(SP) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_CS_bilgisi_bos       = sum(is.na(CryoSleep)),           
    kacinin_CS_bilgisi_dolu   = sum(!is.na(CryoSleep)),         
    Grup_kac_farkli_CS  = n_distinct(CryoSleep, na.rm = TRUE)
  ) %>%
  ungroup()
## # A tibble: 3 × 5
##   SP    grup_kac_kisi kacinin_CS_bilgisi_bos kacinin_CS_bilgisi_dolu
##   <chr>         <int>                  <int>                   <int>
## 1 BZ             3186                      4                    3182
## 2 Z              5324                     96                    5228
## 3 <NA>            183                      2                     181
## # ℹ 1 more variable: Grup_kac_farkli_CS <int>

Yukarıdaki kod, yolcuların Spa harcamalarına göre CryoSleep değişkeninin durumunu incelemek için özet istatistikler üretir. mutate() fonksiyonu ile önce Spa değişkenine bağlı olarak yeni bir SP değişkeni oluşturulur; Spa harcaması 0’dan büyük olan yolcular “BZ”, harcama yapmayanlar ise “Z” olarak sınıflandırılır. Daha sonra group_by() ile veri SP değişkenine göre gruplandırılır ve summarize() fonksiyonu kullanılarak her grup için toplam kişi sayısı, CryoSleep bilgisi eksik olan yolcu sayısı, CryoSleep bilgisi bulunan yolcu sayısı ve grupta yer alan farklı CryoSleep değerlerinin sayısı hesaplanır. Son aşamada ungroup() uygulanarak gruplama kaldırılır. Bu analiz, Spa hizmeti kullanımının CryoSleep değişkeniyle ilişkisini değerlendirmeye ve eksik verilerin dağılımını daha iyi anlamaya yardımcı olur.

train <- train %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & Spa > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))
test <- test %>%
  mutate(CryoSleep = case_when(
    is.na(CryoSleep) & Spa > 0 ~ "FALSE",
    TRUE ~ CryoSleep
  ))

Yukarıdaki kod, hem train hem de test veri setlerinde yer alan CryoSleep değişkenindeki bazı eksik değerleri, yolcuların Spa harcamaları dikkate alınarak yeniden düzenler. mutate() ve case_when() fonksiyonları kullanılarak, CryoSleep değeri NA olan ve Spa harcaması 0’dan büyük olan yolcular için CryoSleep değeri “FALSE” olarak atanır; diğer tüm gözlemlerde mevcut değer korunur. Bu yaklaşım, kriyo uykusunda bulunan yolcuların Spa hizmeti kullanamayacağı varsayımına dayandığından, eksik verilerin daha tutarlı bir şekilde doldurulmasını sağlar ve hem eğitim hem de test verilerinde modelleme öncesi veri bütünlüğünü artırır.

 train %>%
  mutate(VD = ifelse(VRDeck>0, "BZ", "Z")) %>%
  group_by(VD) %>%
  summarize(
    grup_kac_kisi       = n(),
    kacinin_CS_bilgisi_bos       = sum(is.na(CryoSleep)),           
    kacinin_CS_bilgisi_dolu   = sum(!is.na(CryoSleep)),         
    Grup_kac_farkli_CS  = n_distinct(CryoSleep, na.rm = TRUE)
  ) %>%
  ungroup()
## # A tibble: 3 × 5
##   VD    grup_kac_kisi kacinin_CS_bilgisi_bos kacinin_CS_bilgisi_dolu
##   <chr>         <int>                  <int>                   <int>
## 1 BZ             3010                      0                    3010
## 2 Z              5495                     93                    5402
## 3 <NA>            188                      5                     183
## # ℹ 1 more variable: Grup_kac_farkli_CS <int>

Yukarıdaki kod, yolcuların VRDeck harcamaları ile CryoSleep değişkeni arasındaki ilişkiyi incelemek amacıyla özet istatistikler üretir. mutate() fonksiyonu kullanılarak VRDeck değişkenine bağlı yeni bir VD değişkeni oluşturulur; VRDeck harcaması 0’dan büyük olan yolcular “BZ”, harcaması olmayanlar ise “Z” olarak sınıflandırılır. Ardından group_by() fonksiyonu ile veri VD değişkenine göre gruplandırılır ve summarize() kullanılarak her grup için toplam kişi sayısı, CryoSleep bilgisi eksik olan yolcu sayısı, CryoSleep bilgisi bulunan yolcu sayısı ve grupta yer alan farklı CryoSleep değerlerinin sayısı hesaplanır. Son aşamada ungroup() fonksiyonu uygulanarak gruplama kaldırılır. Bu işlemler, VRDeck hizmeti kullanımının CryoSleep değişkeniyle birlikte nasıl değiştiğini ve eksik verilerin dağılımını daha iyi değerlendirmeyi sağlar.

train <- train %>%
 mutate(CryoSleep = factor(CryoSleep))
test <- test %>% 
 mutate(CryoSleep = factor(CryoSleep))

Yukarıdaki kod, hem train hem de test veri setlerinde yer alan CryoSleep değişkeninin veri türünü düzenler. mutate() fonksiyonu kullanılarak CryoSleep değişkeni factor tipine dönüştürülür. Böylece CryoSleep artık sayısal bir değişken gibi değil, sınıflı/kategorik bir değişken olarak ele alınır. Bu dönüşüm, modelleme ve görselleştirme süreçlerinde CryoSleep’in kategorik bir özellik olarak doğru şekilde yorumlanmasını sağlar ve özellikle sınıflandırma modellerinde daha uygun sonuçlar elde edilmesine katkıda bulunur.

cs_model <- rpart(
  CryoSleep ~ HomePlanet + Deck + Side + Age + Destination + VIP + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train %>% filter(!is.na(Destination)),
  method = "class"
)
rpart.plot(
  cs_model
)

Yukarıdaki kod, CryoSleep değişkenini tahmin etmek amacıyla bir karar ağacı modeli kurar ve elde edilen modeli görselleştirir. rpart() fonksiyonu ile bağımlı değişken olarak CryoSleep, bağımsız değişkenler olarak ise HomePlanet, Deck, Side, Age, Destination, VIP, çeşitli harcama kalemleri ve grup değişkenleri modele dahil edilir. Model yalnızca Destination değişkeni eksik olmayan gözlemler kullanılarak eğitilir ve method = "class" ifadesi, modelin sınıflandırma amacıyla kurulduğunu belirtir. Daha sonra rpart.plot() fonksiyonu kullanılarak oluşturulan karar ağacı grafik şeklinde çizdirilir. Bu sayede CryoSleep’i belirleyen faktörlerin nasıl dallandığı ve hangi değişkenlerin karar sürecinde daha baskın olduğu görsel olarak incelenebilir.

train$CryoSleep_tree_pred <- predict(
  cs_model,
  newdata = train,
  type   = "class"
)
test$CryoSleep_tree_pred <- predict(
  cs_model,
  newdata = test,
  type   = "class"
)

Yukarıdaki kod, oluşturulan karar ağacı modeli kullanılarak hem train hem de test veri setleri için CryoSleep tahminleri üretir. predict() fonksiyonu, cs_model modeline yeni veri olarak sırasıyla train ve test veri setlerini verir ve type = "class" ifadesi sayesinde her gözlem için doğrudan sınıf tahmini (TRUE/FALSE gibi) elde edilir. Elde edilen tahminler, train veri setinde CryoSleep_tree_pred, test veri setinde ise CryoSleep_tree_pred adlı yeni sütunlara kaydedilir. Bu işlem, modelin eğitim verisinde nasıl davrandığını ve test verisi üzerinde hangi yolcuların kriyo uykusunda olacağını tahmin ettiğini incelemeye olanak sağlar.

train <- train %>%
  mutate(
    CryoSleep = ifelse(
      is.na(CryoSleep),
      as.character(CryoSleep_tree_pred),
      as.character(CryoSleep)
    ),
    CryoSleep = factor(CryoSleep)
  )
test <- test %>%
  mutate(
    CryoSleep = ifelse(
      is.na(CryoSleep),
      as.character(CryoSleep_tree_pred),
      as.character(CryoSleep)
    ),
    CryoSleep = factor(CryoSleep)
  )

Yukarıdaki kod, karar ağacı modeliyle üretilen tahminleri kullanarak hem train hem de test veri setlerindeki CryoSleep değişkenindeki eksik değerleri doldurur. mutate() içinde ifelse() fonksiyonu ile, CryoSleep değeri NA olan gözlemler için CryoSleep_tree_pred sütunundaki model tahminleri atanır; CryoSleep değeri dolu olan gözlemler ise olduğu gibi korunur. Daha sonra CryoSleep tekrar factor tipine dönüştürülür. Böylece eksik değerler, veri içindeki örüntülere dayanan bir model aracılığıyla tutarlı şekilde tamamlanmış olur ve CryoSleep değişkeni modelleme sürecinde kullanılmaya hazır hale gelir.

train <- train %>%
  select(-CryoSleep_tree_pred)
test <- test %>%
  select(-CryoSleep_tree_pred)

Yukarıdaki kod, hem train hem de test veri setlerinden artık ihtiyaç duyulmayan CryoSleep_tree_pred sütununu kaldırır. select() fonksiyonu içinde değişken adının başına “-” işareti getirilerek, ilgili sütunun veri setinden çıkarılması sağlanır. CryoSleep eksik değerlerini doldurma sürecinde yalnızca geçici olarak kullanılan bu değişken silinerek veri seti sadeleştirilir ve modelleme aşamasında gereksiz değişkenlerin yer alması engellenir.

describe_all(train)
## # A tibble: 24 × 8
##    variable    type     na na_pct unique   min   mean   max
##    <chr>       <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId chr       0    0     8693    NA  NA       NA
##  2 Grup_No     fct       0    0     6217    NA  NA       NA
##  3 Kisi_No     int       0    0        8     1   1.52     8
##  4 HomePlanet  fct       0    0        3    NA  NA       NA
##  5 CryoSleep   fct       0    0        2    NA  NA       NA
##  6 Cabin       chr     199    2.3   6561    NA  NA       NA
##  7 Deck        fct     199    2.3      7    NA  NA       NA
##  8 Numara      int     199    2.3   1818     0 600.    1894
##  9 Side        fct     199    2.3      3    NA  NA       NA
## 10 Destination fct       0    0        3    NA  NA       NA
## # ℹ 14 more rows

3.3.4 Deck Değişkeni

Deck değişkeni, yolcuların gemideki güvertesini temsil eder ve bazı eksik değerlere sahiptir. Bu eksik değerleri doldurmak için, yolcuların diğer özelliklerine (örneğin, HomePlanet, Aile) dayanarak en olası güverteyi atayabiliriz.

summary(train$Deck)
## Diğer     B     C     E     F     G  NA's 
##   739   779   747   876  2794  2559   199

Yukarıdaki kod, train veri setindeki Deck değişkenine ait özet dağılımı gösterir. summary() fonksiyonu her bir güverte kategorisinin kaç yolcudan oluştuğunu ve ayrıca eksik (NA) değerlerin sayısını raporlar. Çıktıya göre yolcuların önemli bir kısmı F ve G güvertelerinde yoğunlaşırken, B, C ve E güvertelerinde daha dengeli bir dağılım görülmektedir; ayrıca 199 gözlemde güverte bilgisi eksiktir. Bu özet sonuç, gemide yolcuların yerleşim yapısını anlamaya, olası dengesizlikleri görmeye ve gerekirse Deck değişkenine yönelik veri düzenleme veya modelleme stratejileri geliştirmeye yardımcı olur.

deck_model <- rpart(
  Deck ~ HomePlanet + CryoSleep + Side + Age + Destination + VIP + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train %>% filter(!is.na(Deck)),
  method = "class"
)
rpart.plot(
  deck_model
)

Yukarıdaki kod, Deck değişkenindeki eksik veya bilinmeyen değerleri tahmin edebilmek amacıyla bir karar ağacı modeli oluşturur ve bu modeli görselleştirir. rpart() fonksiyonu ile bağımlı değişken olarak Deck, bağımsız değişkenler olarak ise HomePlanet, CryoSleep, Side, Age, Destination, VIP ve çeşitli harcama değişkenleri ile grup bilgileri modele dahil edilir. Model yalnızca Deck bilgisi eksik olmayan gözlemler kullanılarak eğitilir ve method = "class" ifadesi, modelin sınıflandırma problemi için kurulduğunu belirtir. Daha sonra rpart.plot() fonksiyonu aracılığıyla oluşturulan karar ağacı grafik olarak çizdirilir. Bu sayede yolcuların hangi özelliklerinin güverte tahmini üzerinde daha etkili olduğu ve modelin karar mantığı görsel olarak incelenebilir.

train$deck_tree_pred <- predict(
  deck_model,
  newdata = train,
  type   = "class"
)
test$deck_tree_pred <- predict(
  deck_model,
  newdata = test,
  type   = "class"
)

Yukarıdaki kod, oluşturulan karar ağacı modelini kullanarak hem train hem de test veri setleri için Deck değişkenine ait tahminler üretir. predict() fonksiyonu, deck_model modeline yeni veri olarak sırasıyla train ve test veri setlerini verir ve type = "class" ifadesi sayesinde her gözlem için doğrudan güverte sınıfı tahmin edilir. Elde edilen tahminler, train veri setinde deck_tree_pred, test veri setinde ise deck_tree_pred adlı yeni sütunlarda saklanır. Bu sayede, modelin yolcuların hangi güvertede bulunabileceğine dair öngörüleri daha sonra eksik değerleri doldurma veya analiz amacıyla kullanılabilir hale gelir.

train <- train %>%
  mutate(
    Deck = ifelse(
      is.na(Deck),
      as.character(deck_tree_pred),
      as.character(Deck)
    ),
    Deck = factor(Deck)
  )
test <- test %>%
  mutate(
    Deck = ifelse(
      is.na(Deck),
      as.character(deck_tree_pred),
      as.character(Deck)
    ),
    Deck = factor(Deck)
  )

Yukarıdaki kod, karar ağacı modeliyle üretilen tahminleri kullanarak hem train hem de test veri setlerindeki Deck değişkeninde yer alan eksik değerleri doldurur. mutate() içinde ifelse() fonksiyonu ile, Deck değeri NA olan gözlemler için deck_tree_pred sütunundaki tahminler atanırken; Deck bilgisi mevcut olan gözlemler aynen korunur. Ardından Deck değişkeni yeniden factor tipine dönüştürülür. Böylece güverte bilgisi, veri içindeki örüntülere dayanan bir model aracılığıyla tamamlanmış olur ve Deck değişkeni sonraki analiz ve modelleme adımlarında kullanılmaya hazır hale gelir.

train <- train %>%
  select(-deck_tree_pred)
test <- test %>%
  select(-deck_tree_pred)
train <- train %>%
  select(-c(Cabin,Numara ))
test <- test %>%
  select(-c(Cabin,Numara ))
train <- train %>%
  select(-c(Name,Ad, Soyad, Grup_Buyuklugu ))
test <- test %>%
  select(-c(Name,Ad, Soyad, Grup_Buyuklugu ))

Yukarıdaki kod, veri setinde modelleme sürecinde kullanılmayacak veya tahmine doğrudan etki etmesi istenmeyen bazı değişkenleri hem train hem de test veri setlerinden kaldırır. Öncelikle, karar ağacı modeli tarafından üretilen geçici tahmin sütunları olan deck_tree_pred ve diğer türetilmiş değişkenler silinir. Ardından, kabin numarası ve yolcuya ait tanımlayıcı bilgiler içeren Cabin, Numara, Name, Ad, Soyad ve Grup_Buyuklugu gibi değişkenler veri setinden çıkarılır. Bu değişkenler, modelin aşırı öğrenmesine (overfitting) yol açabileceği veya doğrudan kimlik bilgisi taşıdığı için analize dahil edilmez. Böylece veri seti, yalnızca modelleme açısından anlamlı ve genellenebilir değişkenleri içerecek şekilde sadeleştirilmiş olur.

describe_all(train)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct     199    2.3      3    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl     179    2.1     81     0  28.8     79
## 10 VIP                fct     203    2.3      3    NA  NA       NA
## 11 RoomService        dbl     181    2.1   1274     0 225.   14327
## 12 FoodCourt          dbl     183    2.1   1508     0 458.   29813
## 13 ShoppingMall       dbl     208    2.4   1116     0 174.   23492
## 14 Spa                dbl     183    2.1   1328     0 311.   22408
## 15 VRDeck             dbl     188    2.2   1307     0 305.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA

3.3.5 Side Değişkeni

Side değişkeni, yolcuların gemideki tarafını (Port veya Starboard) temsil eder ve bazı eksik değerlere sahiptir. Bu eksik değerleri doldurmak için, yolcuların diğer özelliklerine dayanarak en olası tarafı atayabiliriz.

side_model <- rpart(
  Side ~ HomePlanet + CryoSleep + Deck + Age + Destination + VIP + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train %>% filter(!is.na(Side)),
  method = "class",
  cp = 0.002
)
rpart.plot(
  side_model
)

Yukarıdaki kod, veri setinde Side değişkenindeki eksik değerleri tahmin edebilmek için bir karar ağacı modeli oluşturur. Modelde bağımlı değişken olarak Side kullanılırken; yolcunun gezegeni, yaş bilgisi, seyahat özellikleri ve harcama kalemleri gibi birçok açıklayıcı değişken bağımsız değişken olarak modele dahil edilir. filter(!is.na(Side)) ifadesi ile yalnızca Side bilgisi eksik olmayan gözlemler modele alınır, böylece model gerçek değerler üzerinden öğrenir.Karar ağacı rpart() fonksiyonu ile, sınıflandırma yöntemi (method = "class") kullanılarak kurulmuştur. Ayrıca cp = 0.002 parametresi ile ağacın çok karmaşık hale gelmesi engellenmiş ve daha dengeli bir model elde edilmesi amaçlanmıştır. Son olarak rpart.plot() fonksiyonu yardımıyla kurulan karar ağacı görselleştirilerek, modelin hangi değişkenlere daha çok ağırlık verdiği grafik üzerinde incelenebilir hale getirilmiştir.

train$side_tree_pred <- predict(
  side_model,
  newdata = train,
  type   = "class"
)
test$side_tree_pred <- predict(
  side_model,
  newdata = test,
  type   = "class"
)

Yukarıdaki kod, oluşturulan karar ağacı modelini kullanarak hem train hem de test veri setlerinde bulunan yolcular için Side tahminleri üretir. predict() fonksiyonu, side_model aracılığıyla her gözlem için tahmin edilen Side değerlerini hesaplar. type = "class" argümanı, modelin olasılık yerine doğrudan sınıf etiketlerini döndürmesini sağlar.Elde edilen tahminler, train veri setinde side_tree_pred, test veri setinde ise yine side_tree_pred adlı yeni sütunlara eklenir. Bu tahminler, veri setlerinde eksik olan Side değerlerini doldurmak amacıyla kullanılacaktır.

train <- train %>%
  mutate(
    Side = ifelse(
      is.na(Side),
      as.character(side_tree_pred),
      as.character(Side)
    ),
    Side = factor(Side)
  )
test <- test %>%
    mutate(
    Side = ifelse(
      is.na(Side),
      as.character(side_tree_pred),
      as.character(Side)
    ),
    Side = factor(Side)
  )

Yukarıdaki kod, karar ağacı modeliyle üretilen tahminleri kullanarak hem train hem de test veri setlerindeki Side değişkeninde yer alan eksik değerleri doldurur. mutate() içinde kullanılan ifelse() fonksiyonu ile, Side değeri NA olan gözlemler için side_tree_pred sütunundaki tahminler atanırken; Side bilgisi mevcut olan gözlemler aynen korunur. Ardından Side değişkeni yeniden factor tipine dönüştürülür. Böylece gemide yolcunun hangi tarafta bulunduğuna ilişkin bilgi, veri içindeki örüntülere dayanan bir model aracılığıyla tamamlanmış olur ve Side değişkeni sonraki analiz ve modelleme adımlarında kullanılmaya hazır hale gelir.

train <- train %>%
  select(-side_tree_pred)
test <- test %>%
  select(-side_tree_pred)

Yukarıdaki kod, Side değişkenindeki eksik değerleri doldurmak için oluşturulan geçici tahmin sütununu veri setlerinden kaldırır. select(-side_tree_pred) ifadesi, hem train hem de test veri setlerinden side_tree_pred sütununu siler. Böylece yalnızca nihai, düzenlenmiş değişkenler veri setinde tutulur; modelleme sürecinde sadece gerekli değişkenlerle devam edilir ve veri seti gereksiz sütunlardan arındırılmış olur.

describe_all(train)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl     179    2.1     81     0  28.8     79
## 10 VIP                fct     203    2.3      3    NA  NA       NA
## 11 RoomService        dbl     181    2.1   1274     0 225.   14327
## 12 FoodCourt          dbl     183    2.1   1508     0 458.   29813
## 13 ShoppingMall       dbl     208    2.4   1116     0 174.   23492
## 14 Spa                dbl     183    2.1   1328     0 311.   22408
## 15 VRDeck             dbl     188    2.2   1307     0 305.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA
vip_model <- rpart(
  VIP ~ HomePlanet + CryoSleep + Deck + Age + Destination + Side + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train %>% filter(!is.na(VIP)),
  method = "class",
  cp = 0.002
)
rpart.plot(
  vip_model
)

Yukarıdaki kod, VIP değişkenindeki eksik değerleri tahmin etmek amacıyla bir karar ağacı modeli kurar. rpart() fonksiyonu ile kurulan modelde VIP bağımlı değişken, yolculara ait HomePlanet, CryoSleep, Deck, Age, Destination, Side ve harcama kalemleri gibi değişkenler ise açıklayıcı değişkenler olarak kullanılır. Model yalnızca VIP bilgisi eksik olmayan gözlemler üzerinde eğitilir (filter(!is.na(VIP))).method = "class" ifadesi, problemin bir sınıflandırma problemi olduğunu belirtirken; cp = 0.002 parametresi ağacın çok karmaşıklaşmasını engelleyerek daha dengeli bir model elde etmeyi hedefler.Son olarak, rpart.plot() komutu ile oluşturulan karar ağacı görselleştirilir ve modelin nasıl karar verdiği grafiksel olarak incelenebilir.

train$vip_tree_pred <- predict(
  vip_model,
  newdata = train,
  type   = "class"
)
test$vip_tree_pred <- predict(
  vip_model,
  newdata = test,
  type   = "class"
)

Yukarıdaki kod, kurulan VIP karar ağacı modelini kullanarak hem train hem de test veri setleri için VIP tahminleri üretir. predict() fonksiyonu, vip_model aracılığıyla her bir yolcuya ait değişkenleri kullanır ve olası VIP durumunu hesaplar.newdata = train ve newdata = test argümanları, modelin sırasıyla train ve test veri setleri üzerinde çalışmasını sağlar. type = "class" ifadesi ise, sınıflandırma problemine uygun olarak, olasılıklar yerine doğrudan sınıf etiketlerinin (TRUE/FALSE) döndürülmesini sağlar. Elde edilen tahminler, train veri setinde vip_tree_pred, test veri setinde ise yine vip_tree_pred isminde yeni bir sütun olarak kaydedilir. Bu tahminler, ilerleyen adımlarda VIP değişkenindeki eksik değerleri doldurmak amacıyla kullanılacaktır.

train <- train %>%
  mutate(
    VIP = ifelse(
      is.na(VIP),
      as.character(vip_tree_pred),
      as.character(VIP)
    ),
    VIP = factor(VIP)
  )
test <- test %>%
    mutate(
    VIP = ifelse(
      is.na(VIP),
      as.character(vip_tree_pred),
      as.character(VIP)
    ),
    VIP = factor(VIP)
  )

Yukarıdaki kod, karar ağacı modeliyle üretilen tahminleri kullanarak hem train hem de test veri setlerindeki VIP değişkeninde yer alan eksik değerleri doldurur.mutate() içerisinde yer alan ifelse() yapısı sayesinde, VIP değeri NA olan gözlemler için vip_tree_pred sütunundaki tahminler atanırken; VIP bilgisi zaten bulunan gözlemler aynen korunur. Daha sonra VIP değişkeni tekrar factor tipine dönüştürülür. Böylece VIP bilgisi, veri setindeki diğer değişkenlerle ilişkilerden öğrenilen örüntülere dayalı olarak tamamlanmış olur ve modelleme sürecinde kullanılmaya hazır hale gelir.

train <- train %>%
  select(-vip_tree_pred)
test <- test %>%
  select(-vip_tree_pred)

Yukarıdaki kod, VIP değişkenindeki eksik değerleri doldurmak için kullanılan geçici tahmin sütunu olan vip_tree_pred’i veri setlerinden kaldırır.select(-vip_tree_pred) ifadesi, hem train hem de test veri setlerinden bu sütunu siler. Böylece yalnızca son haliyle düzenlenmiş VIP değişkeni bırakılmış olur ve modelleme sürecinde gereksiz, tekrar bilgi içeren bir sütun kalmaz.

describe_all(train)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl     179    2.1     81     0  28.8     79
## 10 VIP                fct       0    0        2    NA  NA       NA
## 11 RoomService        dbl     181    2.1   1274     0 225.   14327
## 12 FoodCourt          dbl     183    2.1   1508     0 458.   29813
## 13 ShoppingMall       dbl     208    2.4   1116     0 174.   23492
## 14 Spa                dbl     183    2.1   1328     0 311.   22408
## 15 VRDeck             dbl     188    2.2   1307     0 305.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA

3.3.6 Age Değişkeni

Age değişkeni, yolcuların yaşını temsil eder.

age_model <- lm(
  Age ~ HomePlanet + CryoSleep + Deck + VIP + Destination + Side + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train)

Yukarıdaki kod, Age değişkenini açıklamak için bir doğrusal regresyon (lm) modeli kurar. Modelde bağımlı değişken olarak Age (yaş), bağımsız değişkenler olarak ise HomePlanet, CryoSleep, Deck, VIP, Destination, Side ve çeşitli harcama kalemleri (RoomService, FoodCourt, ShoppingMall, Spa, VRDeck) ile birlikte grup yapısını temsil eden değişkenler (Grup_Buyuklugu_Kat ve Yalniz_Seyahat) kullanılır. lm() fonksiyonu, bu değişkenler arasındaki doğrusal ilişkiyi tahmin ederek yaş için bir tahmin modeli oluşturur. Bu model, daha sonraki adımlarda eksik Age değerlerini tahmin etmek ve veri setini daha tutarlı hale getirmek amacıyla kullanılabilir.

train$age_tree_pred <- predict(
  age_model,
  newdata = train
)
test$age_tree_pred <- predict(
  age_model,
  newdata = test
)

Yukarıdaki kod, kurulan regresyon modelini kullanarak hem train hem de test veri setlerinde Age için tahminler üretir.predict() fonksiyonu, age_model’den yararlanarak her bir gözlem için beklenen yaş değerini hesaplar. Elde edilen tahminler, train ve test veri setinde age_tree_pred adlı yeni bir sütun olarak kaydedilir.

train <- train %>%
  mutate(
    Age = ifelse(
      is.na(Age),
      round(age_tree_pred), Age))
test <- test %>%
    mutate(
    Age = ifelse(
      is.na(Age),
      round(age_tree_pred), Age))

Yukarıdaki kod, regresyon modeliyle elde edilen tahminleri kullanarak hem train hem de test veri setlerindeki Age değişkeninde yer alan eksik değerleri doldurur.mutate() içinde kullanılan ifelse() yapısı, Age değeri NA olan gözlemler için age_tree_pred sütunundaki yaş tahminlerini atar; Age bilgisi zaten bulunan gözlemler ise aynen korunur. Tahmin edilen değerler round() fonksiyonu ile en yakın tam sayıya yuvarlanır, böylece yaş değişkeni daha anlamlı bir yapıda tutulur.Sonuç olarak Age değişkeni, veri setindeki diğer değişkenlerle kurulan modele dayalı olarak tamamlanmış olur ve sonraki analiz ve modelleme aşamalarında kullanılmaya hazır hale gelir.

train <- train %>%
  select(-age_tree_pred)
test <- test %>%
  select(-age_tree_pred)

Yukarıdaki kod, Age değişkenindeki eksik değerlerin doldurulmasında kullanılan geçici tahmin sütunu age_tree_pred’i hem train hem de test veri setlerinden kaldırır. Böylece veri setleri, yalnızca modelleme için gerekli nihai değişkenleri içerir ve gereksiz sütunlar temizlenmiş olur.

describe_all(train)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl      14    0.2     81     0  28.8     79
## 10 VIP                fct       0    0        2    NA  NA       NA
## 11 RoomService        dbl     181    2.1   1274     0 225.   14327
## 12 FoodCourt          dbl     183    2.1   1508     0 458.   29813
## 13 ShoppingMall       dbl     208    2.4   1116     0 174.   23492
## 14 Spa                dbl     183    2.1   1328     0 311.   22408
## 15 VRDeck             dbl     188    2.2   1307     0 305.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA
mean_age <- train %>%
  summarize(mean_age = mean(Age, na.rm=TRUE)) %>%
  pull(mean_age)
mean_age
## [1] 28.82844

Yukarıdaki kod, train veri setindeki Age değişkeninin ortalama değerini hesaplar. summarize() fonksiyonu ile Age sütunundaki eksik değerler (NA) göz ardı edilerek (na.rm = TRUE) ortalama yaş hesaplanır. pull() fonksiyonu ise hesaplanan bu ortalama değeri doğrudan mean_age adlı değişkene atar.

train <- train %>%
  mutate(
    Age = ifelse(
      is.na(Age),
      round(mean_age), Age))
test <- test %>%
  mutate(
    Age = ifelse(
      is.na(Age),
      round(mean_age), Age))

Yukarıdaki kod, train ve test veri setlerindeki Age değişkeninde hâlâ eksik (NA) olan değerleri, train veri setinden hesaplanan ortalama yaş (mean_age) ile doldurur. mutate() ve ifelse() fonksiyonları kullanılarak, Age değeri NA olan gözlemler için mean_age atanır; zaten dolu olan değerler korunur. Atanan ortalama değer round() ile tam sayıya yuvarlanır.

describe_all(train)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl       0    0       80     0  28.8     79
## 10 VIP                fct       0    0        2    NA  NA       NA
## 11 RoomService        dbl     181    2.1   1274     0 225.   14327
## 12 FoodCourt          dbl     183    2.1   1508     0 458.   29813
## 13 ShoppingMall       dbl     208    2.4   1116     0 174.   23492
## 14 Spa                dbl     183    2.1   1328     0 311.   22408
## 15 VRDeck             dbl     188    2.2   1307     0 305.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA

3.3.7 RoomService, FoodCourt, ShoppingMall, Spa, VRDeck Değişkenleri

Yolcunun Titanic Uzay Gemisi’nin birçok lüks olanağından her biri için ödediği fatura tutarı.

median_table <- train %>%
  mutate(Age_Group = cut(Age,
                         breaks = c(0, 12, 18, 30, 45, 60, Inf),
                         labels = c("Child", "Teen", "YoungAdult", "Adult", "MidAge", "Senior"),
                         right = FALSE)) %>%
  group_by(HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) %>%
  summarize(med = median(RoomService, na.rm = TRUE))
## `summarise()` has grouped output by 'HomePlanet', 'Deck', 'CryoSleep',
## 'Destination', 'VIP', 'Grup_Buyuklugu_Kat', 'Side'. You can override using the
## `.groups` argument.

Yukarıdaki kod, train veri setinde yolcuların farklı gruplara göre RoomService harcamalarının medyan değerlerini hesaplar.İlk olarak, mutate() ile Age değişkeni belli yaş aralıklarına göre kategorize edilir ve Age_Group adlı yeni bir faktör değişkeni oluşturulur. Bu yaş grupları sırasıyla “Child” (0-11), “Teen” (12-17), “YoungAdult” (18-29), “Adult” (30-44), “MidAge” (45-59) ve “Senior” (60 ve üzeri) olarak etiketlenir. Daha sonra, group_by() fonksiyonu ile yolcular HomePlanet, Deck, CryoSleep durumu, Destination, VIP statüsü, Grup_Buyuklugu_Kat, Side ve oluşturulan Age_Group değişkenlerine göre gruplanır.Son olarak summarize() kullanılarak her grup için RoomService harcamalarının medyan değeri (median) hesaplanır. Eksik değerler (NA) hesaplamaya dahil edilmez (na.rm = TRUE).

train <- train %>%
  mutate(Age_Group = cut(Age,
                         breaks = c(0, 12, 18, 30, 45, 60, Inf),
                         labels = c("Child", "Teen", "YoungAdult", "Adult", "MidAge", "Senior"),
                         right = FALSE)) %>%
  left_join(median_table, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, train veri setine önceden oluşturulan median_table tablosundaki medyan RoomService harcaması bilgisini ekler.İlk olarak, mutate() ile Age değişkeni belirlenen yaş aralıklarına göre kategorize edilip Age_Group adlı yeni bir sütun oluşturulur. Ardından, left_join() fonksiyonu kullanılarak train veri seti, median_table ile ortak olan değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden birleştirilir.Bu işlem sonucunda, her yolcuya ait ilgili grup bazında hesaplanmış RoomService harcaması medyan değeri (med sütunu) train veri setine eklenir.

train <- train %>%
  mutate(RoomService = ifelse(is.na(RoomService), med, RoomService)) %>%
  select(-med)

Yukarıdaki kod, train veri setindeki RoomService değişkeninde bulunan eksik (NA) değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() içinde ifelse() kullanılarak, RoomService değeri NA olan gözlemler için daha önce eklenen med sütunundaki medyan değer atanır; eksik olmayan değerler ise olduğu gibi korunur. Ardından, select(-med) ile medyan değerlerin bulunduğu geçici med sütunu veri setinden kaldırılır.

median_table_fc <- train %>%
  group_by(HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) %>%
  summarize(med = median(FoodCourt, na.rm = TRUE))
## `summarise()` has grouped output by 'HomePlanet', 'Deck', 'CryoSleep',
## 'Destination', 'VIP', 'Grup_Buyuklugu_Kat', 'Side'. You can override using the
## `.groups` argument.

Yukarıdaki kod, train veri setinde farklı yolcu gruplarına göre FoodCourt harcamalarının medyanını hesaplar.group_by() fonksiyonu ile yolcular HomePlanet, Deck, CryoSleep durumu, Destination, VIP durumu, Grup_Buyuklugu_Kat, Side ve önceden oluşturulan Age_Group değişkenlerine göre gruplanır.summary() ile her grubun FoodCourt harcamalarının medyan değeri (median) hesaplanır; eksik değerler (NA) hesaba katılmaz (na.rm = TRUE).

train <- train  %>%
  left_join(median_table_fc, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, train veri setine daha önce hesaplanmış olan FoodCourt harcama medyanı (median_table_fc) bilgisini ekler.left_join() fonksiyonu ile train veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_fc ile birleştirilir.

train <- train %>%
  mutate(FoodCourt = ifelse(is.na(FoodCourt), med, FoodCourt)) %>%
  select(-med)

Yukarıdaki kod, train veri setindeki FoodCourt değişkeninde eksik (NA) olan değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() fonksiyonu kullanılarak, FoodCourt değeri NA olan gözlemler için önceden eklenmiş olan med sütunundaki medyan değer atanırken; eksik olmayan değerler olduğu gibi korunur. Daha sonra select(-med) ifadesiyle, geçici olarak eklenen med sütunu veri setinden kaldırılır.

median_table_sm <- train %>%
  group_by(HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) %>%
  summarize(med = median(ShoppingMall, na.rm = TRUE))
## `summarise()` has grouped output by 'HomePlanet', 'Deck', 'CryoSleep',
## 'Destination', 'VIP', 'Grup_Buyuklugu_Kat', 'Side'. You can override using the
## `.groups` argument.

Yukarıdaki kod, train veri setinde yolcuların farklı gruplarına göre ShoppingMall harcamalarının medyan değerini hesaplar.group_by() fonksiyonu kullanılarak yolcular HomePlanet, Deck, CryoSleep durumu, Destination, VIP durumu, Grup_Buyuklugu_Kat, Side ve Age_Group değişkenlerine göre gruplanır.summarize() fonksiyonu ile her grubun ShoppingMall harcamalarının medyan değeri (median) hesaplanır; eksik değerler (NA) dikkate alınmaz (na.rm = TRUE).

train <- train %>%
  left_join(median_table_sm, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, train veri setine daha önce hesaplanmış ShoppingMall harcama medyanı (median_table_sm) bilgisini ekler.left_join() fonksiyonu ile train veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_sm tablosu ile birleştirilir.Bu sayede, her yolcunun ait olduğu grup bazında hesaplanmış ShoppingMall harcaması medyan değeri (med sütunu) train veri setine eklenmiş olur.

train <- train %>%
  mutate(ShoppingMall = ifelse(is.na(ShoppingMall), med, ShoppingMall)) %>%
  select(-med)

Yukarıdaki kod, train veri setindeki ShoppingMall değişkeninde bulunan eksik (NA) değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() fonksiyonu kullanılarak, ShoppingMall değeri NA olan gözlemler için önceden eklenmiş olan med sütunundaki medyan değer atanırken; dolu olan değerler korunur. Son olarak, select(-med) ile geçici olarak eklenen med sütunu veri setinden kaldırılır.

median_table_spa <- train %>%
  group_by(HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) %>%
  summarize(med = median(Spa, na.rm = TRUE))
## `summarise()` has grouped output by 'HomePlanet', 'Deck', 'CryoSleep',
## 'Destination', 'VIP', 'Grup_Buyuklugu_Kat', 'Side'. You can override using the
## `.groups` argument.

Yukarıdaki kod, train veri setinde farklı yolcu gruplarına göre Spa harcamalarının medyan değerini hesaplar.group_by() fonksiyonu ile yolcular HomePlanet, Deck, CryoSleep durumu, Destination, VIP durumu, Grup_Buyuklugu_Kat, Side ve Age_Group değişkenlerine göre gruplanır.summary() fonksiyonu kullanılarak her grup için Spa harcamalarının medyan değeri (median) hesaplanır; eksik değerler (NA) dikkate alınmaz (na.rm = TRUE).

train <- train %>%
  left_join(median_table_spa, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, train veri setine önceden hesaplanmış Spa harcama medyanı (median_table_spa) bilgisini ekler.left_join() fonksiyonu aracılığıyla train veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_spa tablosu ile birleştirilir. Böylece, her yolcunun ait olduğu grup bazında hesaplanmış Spa harcaması medyan değeri (med sütunu) train veri setine eklenmiş olur.

train <- train %>%
  mutate(Spa = ifelse(is.na(Spa), med, Spa)) %>%
  select(-med)

Yukarıdaki kod, train veri setindeki Spa değişkeninde bulunan eksik (NA) değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() fonksiyonu kullanılarak, Spa değeri NA olan gözlemler için önceden eklenen med sütunundaki medyan değer atanır; dolu olanlar ise korunur.Son olarak, select(-med) ile geçici olarak eklenen med sütunu veri setinden kaldırılır.

median_table_vrd <- train %>%
  group_by(HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) %>%
  summarize(med = median(VRDeck, na.rm = TRUE))
## `summarise()` has grouped output by 'HomePlanet', 'Deck', 'CryoSleep',
## 'Destination', 'VIP', 'Grup_Buyuklugu_Kat', 'Side'. You can override using the
## `.groups` argument.

Yukarıdaki kod, train veri setinde yolcuların farklı gruplarına göre VRDeck harcamalarının medyan değerini hesaplar.group_by() fonksiyonu kullanılarak yolcular HomePlanet, Deck, CryoSleep durumu, Destination, VIP durumu, Grup_Buyuklugu_Kat, Side ve Age_Group değişkenlerine göre gruplanır.summarize() ile her grup için VRDeck harcamalarının medyan değeri(median) hesaplanır; eksik değerler (NA) dikkate alınmaz (na.rm = TRUE).

train <- train %>%
  left_join(median_table_vrd, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, train veri setine önceden hesaplanmış VRDeck harcama medyanı (median_table_vrd) bilgisini ekler.left_join() fonksiyonu ile train veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_vrd tablosuyla birleştirilir.

train <- train %>%
  mutate(VRDeck = ifelse(is.na(VRDeck), med, VRDeck)) %>%
  select(-med)

Yukarıdaki kod, train veri setindeki VRDeck değişkeninde bulunan eksik (NA) değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() fonksiyonu, VRDeck değeri NA olan gözlemler için med sütunundaki medyan değeri atar; dolu olanlar ise korunur.Sonrasında, select(-med) ile geçici olarak eklenen med sütunu veri setinden kaldırılır.

describe_all(train)
## # A tibble: 19 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     8693    NA  NA       NA
##  2 Grup_No            fct       0    0     6217    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.52     8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl       0    0       80     0  28.8     79
## 10 VIP                fct       0    0        2    NA  NA       NA
## 11 RoomService        dbl      14    0.2   1285     0 222.   14327
## 12 FoodCourt          dbl      14    0.2   1522     0 454.   29813
## 13 ShoppingMall       dbl      13    0.1   1126     0 171.   23492
## 14 Spa                dbl       5    0.1   1342     0 307.   22408
## 15 VRDeck             dbl      13    0.1   1316     0 300.   24133
## 16 Transported        fct       0    0        2    NA  NA       NA
## 17 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 18 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA
## 19 Age_Group          fct       0    0        6    NA  NA       NA

Test veri seti

test <- test %>%
  mutate(Age_Group = cut(Age,
                         breaks = c(0, 12, 18, 30, 45, 60, Inf),
                         labels = c("Child", "Teen", "YoungAdult", "Adult", "MidAge", "Senior"),
                         right = FALSE)) %>%
  left_join(median_table, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))

Yukarıdaki kod, test veri setinde Age değişkenini belirli yaş aralıklarına göre kategorize eder ve Age_Group adlı yeni bir sütun oluşturur.Ardından, left_join() fonksiyonu kullanılarak test veri seti, train veri setinde daha önce hesaplanmış olan RoomService harcaması medyanını içeren median_table tablosu ile ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden birleştirilir. Bu sayede, test veri setindeki her yolcuya ait grup bazında hesaplanmış RoomService medyan değeri (med sütunu) eklenmiş olur.

test <- test %>%
  mutate(RoomService = ifelse(is.na(RoomService), med, RoomService)) %>%
  select(-med)

Yukarıdaki kod, test veri setindeki RoomService değişkeninde bulunan eksik (NA) değerleri, aynı gruba ait yolcular için hesaplanmış medyan değerle doldurur.mutate() ve ifelse() fonksiyonları kullanılarak, RoomService değeri NA olan gözlemler için önceden eklenen med sütunundaki medyan değer atanırken, dolu olan değerler korunur.Son olarak, select(-med) ile geçici olarak eklenen med sütunu test veri setinden kaldırılır.

test <- test  %>%
  left_join(median_table_fc, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
test <- test %>%
  mutate(FoodCourt = ifelse(is.na(FoodCourt), med, FoodCourt)) %>%
  select(-med)

Yukarıdaki kod, test veri setine daha önce train veri setinden hesaplanmış FoodCourt harcaması medyan değerini (median_table_fc) ekler.left_join() fonksiyonu ile test veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_fc tablosuyla birleştirilir.Ardından, mutate() kullanılarak FoodCourt değişkenindeki eksik (NA) değerler, ilgili grup için hesaplanmış medyan değer (med) ile doldurulur; dolu olanlar korunur.Son olarak, select(-med) ile geçici med sütunu veri setinden kaldırılır.

test <- test %>%
  left_join(median_table_sm, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
test <- test %>%
  mutate(ShoppingMall = ifelse(is.na(ShoppingMall), med, ShoppingMall)) %>%
  select(-med)

Yukarıdaki kod, test veri setine önceden train veri setinde hesaplanmış ShoppingMall harcaması medyan değerini (median_table_sm) ekler.left_join() fonksiyonu ile test veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_sm tablosu ile birleştirilir. Sonrasında, mutate() kullanılarak ShoppingMall değişkenindeki eksik (NA) değerler, ilgili grup için hesaplanmış medyan değer (med) ile doldurulur; dolu olanlar korunur.En son, select(-med) ile geçici med sütunu test veri setinden kaldırılır.

test <- test %>%
  left_join(median_table_spa, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
test <- test %>%
  mutate(Spa = ifelse(is.na(Spa), med, Spa)) %>%
  select(-med)

Yukarıdaki kod, test veri setine daha önce train veri setinde hesaplanmış Spa harcaması medyan değerini (median_table_spa) ekler.left_join() fonksiyonu kullanılarak test veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_spa tablosuyla birleştirilir. Daha sonra, mutate() kullanılarak Spa değişkenindeki eksik (NA) değerler, ait oldukları grup için hesaplanmış medyan değer (med) ile doldurulur; dolu olanlar korunur.Son adımda, select(-med) ile geçici olarak eklenen med sütunu test veri setinden kaldırılır.

test <- test %>%
  left_join(median_table_vrd, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
test <- test %>%
  mutate(VRDeck = ifelse(is.na(VRDeck), med, VRDeck)) %>%
  select(-med)

Yukarıdaki kod, test veri setine önceden train veri setinde hesaplanmış VRDeck harcaması medyan değerini (median_table_vrd) ekler.left_join() fonksiyonu ile test veri seti, ortak değişkenler (HomePlanet, Deck, CryoSleep, Destination, VIP, Grup_Buyuklugu_Kat, Side, Age_Group) üzerinden median_table_vrd tablosuyla birleştirilir.Ardından, mutate() kullanılarak VRDeck değişkenindeki eksik (NA) değerler, ilgili grup için hesaplanmış medyan değer (med) ile doldurulur; dolu olanlar korunur.Son olarak, select(-med) ile geçici olarak eklenen med sütunu test veri setinden kaldırılır.

describe_all(test)
## # A tibble: 18 × 8
##    variable           type     na na_pct unique   min   mean   max
##    <chr>              <chr> <int>  <dbl>  <int> <dbl>  <dbl> <dbl>
##  1 PassengerId        chr       0    0     4277    NA  NA       NA
##  2 Grup_No            fct       0    0     3063    NA  NA       NA
##  3 Kisi_No            int       0    0        8     1   1.5      8
##  4 HomePlanet         fct       0    0        3    NA  NA       NA
##  5 CryoSleep          fct       0    0        2    NA  NA       NA
##  6 Deck               fct       0    0        6    NA  NA       NA
##  7 Side               fct       0    0        2    NA  NA       NA
##  8 Destination        fct       0    0        3    NA  NA       NA
##  9 Age                dbl       0    0       79     0  28.7     79
## 10 VIP                fct       0    0        2    NA  NA       NA
## 11 RoomService        dbl       0    0      850     0 217.   11567
## 12 FoodCourt          dbl       3    0.1    916     0 435.   25273
## 13 ShoppingMall       dbl       8    0.2    728     0 175.    8292
## 14 Spa                dbl      10    0.2    840     0 298.   19844
## 15 VRDeck             dbl       4    0.1    807     0 308.   22272
## 16 Yalniz_Seyahat     dbl       0    0        2     0   0.55     1
## 17 Grup_Buyuklugu_Kat fct       0    0        4    NA  NA       NA
## 18 Age_Group          fct       0    0        6    NA  NA       NA
train <- train %>%
  mutate(RoomService = coalesce(RoomService, 0),
         FoodCourt   = coalesce(FoodCourt, 0),
         ShoppingMall= coalesce(ShoppingMall, 0),
         Spa         = coalesce(Spa, 0),
         VRDeck      = coalesce(VRDeck, 0)
  )
test <- test %>%
  mutate(RoomService = coalesce(RoomService, 0),
         FoodCourt   = coalesce(FoodCourt, 0),
         ShoppingMall= coalesce(ShoppingMall, 0),
         Spa         = coalesce(Spa, 0),
         VRDeck      = coalesce(VRDeck, 0)
  )

Yukarıdaki kod, hem train hem de test veri setlerinde bazı harcama değişkenlerinde (RoomService, FoodCourt, ShoppingMall, Spa, VRDeck) kalan eksik (NA) değerleri sıfır (0) ile doldurur.coalesce() fonksiyonu, belirtilen sütundaki ilk dolu değeri alır; burada, eğer ilgili değişkende NA varsa, onun yerine 0 atanır.

train <- train %>%
  select(-c(Grup_No, Kisi_No, Yalniz_Seyahat))
test <- test %>%
  select(-c(Grup_No, Kisi_No, Yalniz_Seyahat))

Yukarıdaki kod, hem train hem de test veri setlerinden Grup_No, Kisi_No ve Yalniz_Seyahat sütunlarını kaldırır.

3.4 Modelleme İçin Hazırlık

set.seed(123)

data_split <- initial_split(train, prop = 0.8, strata = Transported)
train_data  <- training(data_split)
test_data   <- testing(data_split)

Yukarıdaki kod, train veri setini eğitim ve test alt kümelerine böler.set.seed(123) ifadesi, rastgele bölme işleminin tekrarlanabilir olması için sabit bir başlangıç noktası belirler.initial_split() fonksiyonu, train veri setini %80 eğitim (train_data) ve %20 test (test_data) olarak ayırır. strata = Transported parametresi, bölme işleminin Transported değişkeninin sınıf dağılımını koruyarak yapılmasını sağlar, yani her iki alt kümede de Transported sınıflarının orantılı dağılımı korunur.Böylece model eğitimi ve değerlendirmesi için dengeli ve tutarlı alt kümeler oluşturulmuş olur.

rs_recipe <- recipe(Transported ~ ., data = train_data) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_normalize(all_numeric_predictors())

Yukarıdaki kod, train_data veri seti için bir modelleme tarifesi (recipe) oluşturur ve ön işleme adımlarını tanımlar.

  • recipe(Transported ~ ., data = train_data): Bağımlı değişken Transported olarak belirlenip, tüm diğer değişkenler bağımsız değişkenler olarak alınır.

  • update_role(PassengerId, Age, new_role = “ID”): PassengerId ve Age değişkenlerinin modelde açıklayıcı değişken olarak değil, tanımlayıcı (ID) rolünde kullanılacağını belirtir. Böylece bu değişkenler modelde özellik olarak işlenmez.

  • step_dummy(all_nominal_predictors(), one_hot = TRUE): Tüm kategorik (nominal) değişkenler için one-hot encoding işlemi yaparak, kategorik değişkenleri sayısal hale dönüştürür.

  • step_normalize(all_numeric_predictors()): Tüm sayısal değişkenleri normalize ederek (ortalama 0, standart sapma 1 olacak şekilde) ölçeklendirir. Bu, modelin değişkenler arasındaki farklı ölçeklerden etkilenmesini önler.

3.5 Lojistik Regresyon ve Random Forest

log_spec <- logistic_reg() %>%
  set_engine("glm")
log_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(log_spec)
log_fit <- log_workflow %>%
  fit(data = train_data)

Yukarıdaki kod, lojistik regresyon modeli oluşturma ve eğitme sürecini tanımlar:

  • logistic_reg() %>% set_engine(“glm”): Lojistik regresyon modeli glm motoru kullanılarak tanımlanır.

  • workflow() %>% add_recipe(rs_recipe) %>% add_model(log_spec): Model iş akışı (workflow) oluşturulur; bu iş akışına önceden tanımlanmış veri hazırlama tarifesi (rs_recipe) ve lojistik regresyon modeli (log_spec) eklenir.

  • fit(data = train_data): Belirlenen iş akışı, eğitim verisi (train_data) kullanılarak modele uygun şekilde eğitilir.

log_preds <- predict(log_fit, test_data, type = "prob")
head(log_preds)
## # A tibble: 6 × 2
##   .pred_FALSE .pred_TRUE
##         <dbl>      <dbl>
## 1       0.780    0.220  
## 2       0.207    0.793  
## 3       0.845    0.155  
## 4       0.302    0.698  
## 5       0.993    0.00705
## 6       0.222    0.778

Kurduğumuz lojistik regresyon modelinin her bir gözlem (her satır) için ürettiği olasılık tahminidir.

log_class <- predict(log_fit, test_data)
results <- test_data %>%
  select(Transported) %>%
  bind_cols(log_class)

Yukarıdaki kod, eğitilmiş lojistik regresyon modeli (log_fit) kullanılarak test_data üzerindeki sınıf tahminlerini yapar ve gerçek sonuçlarla birlikte karşılaştırma için bir tablo oluşturur.

  • predict(log_fit, test_data): Modelden her gözlem için sınıf tahmini (örneğin TRUE veya FALSE) elde edilir.

  • test_data %>% select(Transported): Test verisinden gerçek Transported sonuçları seçilir.bind_cols(log_class): Gerçek sonuçlar ile modelin tahmin ettiği sınıflar yan yana birleştirilir.

  • Sonuç olarak, results tablosu her gözlem için gerçek ve tahmin edilen Transported değerlerini içeren karşılaştırma tablosudur; model performansını değerlendirmek için kullanılır.

log_acc <- accuracy(data = results,
                    truth = Transported,
                    estimate = .pred_class)
log_acc %>%
  kable(digits = 3,
        col.names = c("Metrik", "Tahmin Türü", "Doğruluk")) %>%
  kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover"))
Metrik Tahmin Türü Doğruluk
accuracy binary 0.795

Yukarıdaki kod, oluşturulan lojistik regresyon modelinin test_data üzerindeki doğruluk (accuracy) performansını hesaplar.accuracy() fonksiyonu, results tablosundaki gerçek değerler (truth = Transported) ile modelin tahmin ettiği sınıflar (estimate = .pred_class) arasındaki uyumu değerlendirir.Çıktıda .estimate sütunu, modelin tahminlerinin %79.5 oranında doğru olduğunu gösterir.Bu metrik, modelin test verisi üzerindeki genel sınıflandırma başarısını özetler. %79.5 doğruluk, modelin tahminlerinin yaklaşık dörtte üçü doğru olduğu anlamına gelir.

conf_mat_log <- conf_mat(data = results,
                         truth = Transported,
                         estimate = .pred_class)
autoplot(conf_mat_log, type = "heatmap") +
  scale_fill_gradient(low = "white", high = "steelblue") +
  labs(title = "Confusion Matrix - Isı Haritası")

Yukarıdaki kod, lojistik regresyon modelinin test verisi üzerindeki tahmin sonuçları için bir karışıklık matrisi (confusion matrix) oluşturur.conf_mat() fonksiyonu, gerçek (truth = Transported) ve tahmin edilen (estimate = .pred_class) sınıf etiketlerini karşılaştırır. Çıktı matrisi, tahminlerin doğruluk ve hata türlerini gösterir:

  • TRUE POSITIVE: 719 — Model, gerçekten Transported = TRUE olanları doğru tahmin etmiş.

  • TRUE NEGATIVE: 664 — Model, gerçekten Transported = FALSE olanları doğru tahmin etmiş.

  • FALSE POSITIVE: 199 — Model, Transported = TRUE olmayanları yanlışlıkla TRUE tahmin etmiş.

  • FALSE NEGATIVE: 157 — Model, Transported = TRUE olanları yanlışlıkla FALSE tahmin etmiş.

pred_prob  <- predict(log_fit, test_data, type = "prob")
results <- results %>%
  bind_cols(pred_prob)
results <- results %>%
  mutate(Transported = relevel(Transported, ref = "TRUE"))

roc_data <- roc_curve(
  data  = results,
  truth = Transported,
  .pred_TRUE
)

autoplot(roc_data) +
  labs(title = "ROC Eğrisi", subtitle = "Lojistik Regresyon Modeli")

Yukarıdaki kod, lojistik regresyon modelinin ROC eğrisini (Receiver Operating Characteristic) oluşturur ve görselleştirir.

  • mutate(Transported = relevel(Transported, ref = “TRUE”)): Gerçek sınıf değişkeni Transported için referans seviyesi (pozitif sınıf) “TRUE” olarak ayarlanır. Bu, ROC analizinde pozitif sınıfın doğru tanımlanması için önemlidir.

  • roc_curve(): results verisinden gerçek etiketler (truth = Transported) ile modelin TRUE sınıfı için tahmin ettiği olasılıkları (.pred_TRUE) kullanarak ROC eğrisini hesaplar.

  • autoplot(roc_data): Hesaplanan ROC eğrisini grafik olarak çizer.

  • labs(title = “ROC Eğrisi”, subtitle = “Lojistik Regresyon Modeli”): Grafiğe başlık ve alt başlık ekler. ROC eğrisi, modelin sınıflandırma performansını farklı eşik değerlerinde gösterir; eğri ne kadar köşeye yakınsa, model o kadar başarılıdır.

logistic_recipe <- recipe(Transported ~ ., data = train) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_normalize(all_numeric_predictors())

Yukarıda, train veri seti üzerinde test yaparak modelimizin performansını değerlendirdik. Artık başlangıçtaki hedefimize dönüp, modeli test veri seti üzerinde kullanarak tahminler elde edeceğiz. Daha sonra bu tahminleri Kaggle’a gönderip ne kadar doğru olduğunu göreceğiz.

log_spec <- logistic_reg() %>%
  set_engine("glm")
log_workflow <- workflow() %>%
  add_recipe(logistic_recipe) %>%
  add_model(log_spec)
log_fit <- log_workflow %>%
  fit(data = train)

Yukarıdaki kod, lojistik regresyon modelinin oluşturulması ve train veri seti üzerinde eğitilmesini sağlar.logistic_reg() %>% set_engine(“glm”): Lojistik regresyon modeli tanımlanır ve glm motoru kullanılır.workflow() %>% add_recipe(logistic_recipe) %>% add_model(log_spec): Model iş akışı (workflow) oluşturulur; bu iş akışına daha önce tanımlanmış veri ön işleme tarifesi (logistic_recipe) ve lojistik regresyon modeli (log_spec) eklenir.fit(data = train): Belirlenen iş akışı, train veri seti üzerinde eğitilir ve sonuç log_fit nesnesinde saklanır.

tahminler <- log_fit %>%
  predict(new_data = test) %>%     
  bind_cols(test) 

Yukarıdaki kod, eğitilmiş lojistik regresyon modeli (log_fit) kullanılarak test veri setindeki gözlemler için sınıf tahminleri yapar ve bu tahminleri orijinal test verisiyle birleştirir.predict(new_data = test): Model, test verisindeki her gözlem için tahmin edilen sınıf değerlerini döndürür.bind_cols(test): Tahmin sonuçları ile test veri setindeki diğer değişkenler yan yana eklenir.

submission <- tahminler %>% 
  select(PassengerId = PassengerId, .pred_class = .pred_class) %>%  
  rename(Transported = .pred_class) 

Yukarıdaki kod, tahmin sonuçlarından sadece gönderim dosyasında kullanılacak sütunları seçer ve gerekli isimlendirmeleri yapar.select(PassengerId = PassengerId, .pred_class = .pred_class): PassengerId ve modelin tahmin ettiği sınıf (.pred_class) sütunlarını seçer. rename(Transported = .pred_class): Tahmin edilen sınıf sütununun adı Transported olarak değiştirilir.

submission <- as.data.frame(submission)
submission$Transported <- str_to_title(submission$Transported)
write.csv(submission, "logistic.csv", row.names = FALSE, quote = FALSE)

Yukarıdaki kod, gönderim (submission) veri setini uygun formata dönüştürür ve CSV dosyası olarak kaydeder.

3.5.1 Random Forest

library(randomForest)

Random Forest, denetimli makine öğrenmesi alanında yaygın olarak kullanılan, güçlü ve esnek bir topluluk (ensemble) yöntemidir. Algoritmanın temel prensibi, çok sayıda karar ağacı oluşturmak ve bu ağaçların ürettiği tahminleri birleştirerek daha güvenilir ve dengeli sonuçlar elde etmektir. Bu yaklaşım, tek bir karar ağacının aşırı öğrenme (overfitting) eğilimini azaltır ve modelin genellenebilirliğini artırır.

Random Forest, “bagging” (Bootstrap Aggregating) yöntemine dayanır. Eğitim sürecinde veri setinden rastgele örneklemeler yapılarak her bir ağaç farklı alt veri kümeleriyle eğitilir. Ayrıca her düğümde, tüm değişkenler yerine rastgele seçilen bir alt küme değerlendirilir. Bu iki tür rastgelelik; ağaçlar arasındaki korelasyonu düşürür, modelin çeşitliliğini artırır ve nihayetinde daha kararlı tahminler üretir.

Sınıflandırma problemlerinde, her ağacın yaptığı tahminler oylama yoluyla birleştirilir ve en sık görülen sınıf model çıktısı olarak belirlenir. Regresyon problemlerinde ise ağaçlardan elde edilen tahminlerin ortalaması alınır. Böylece tek bir model yerine, kolektif bir karar mekanizması oluşturulmuş olur.

Random Forest algoritmasının öne çıkan avantajları arasında yüksek doğruluk performansı, gürültülü verilere karşı dayanıklılık, eksik verilerle çalışabilme esnekliği ve değişken önemini değerlendirme yeteneği yer almaktadır. Bununla birlikte, çok sayıda ağacın kullanılması hesaplama maliyetini artırabilir ve modelin yorumlanabilirliğini zorlaştırabilir.

Sonuç olarak Random Forest, hem sınıflandırma hem de regresyon problemlerinde güvenilir ve güçlü bir alternatif sunmaktadır. Büyük veri setlerinde, karmaşık ilişkilerin bulunduğu durumlarda ve genellenebilirliğin kritik olduğu uygulamalarda yaygın biçimde tercih edilmektedir.

rf_spec <- rand_forest(
  trees = 500,
  mtry = NULL,
  min_n = 5
) %>%
  set_mode("classification") %>%
  set_engine("ranger")

Yukarıdaki kod, bir Random Forest (Rastgele Orman) sınıflandırma modeli tanımlar. rand_forest() fonksiyonu, modelin temel yapı taşlarını belirler:

trees = 500 → Model, 500 adet karar ağacından oluşur. Ağaç sayısı arttıkça model genelde daha kararlı olur, fakat hesaplama süresi de uzar.

mtry = NULL → Her düğümde kullanılacak değişken sayısı otomatik olarak belirlenir.

min_n = 5 → Bir yaprak düğümde (terminal node) en az 5 gözlem bulunmalıdır; bu, modelin aşırı öğrenmesini (overfitting) azaltmaya yardımcı olur.

Ardından:

set_mode(“classification”) → Modelin bir sınıflandırma problemi için kullanılacağını belirtir.

set_engine(“ranger”) → Random Forest algoritmasının R’daki ranger motoru ile çalıştırılacağını söyler. Ranger, hızlı ve verimli bir Random Forest implementasyonudur.

rf_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(rf_spec)

rf_fit <- rf_workflow %>%
  fit(data = train_data)

Yukarıdaki kod, Random Forest modelinin hem iş akışını (workflow) oluşturur hem de modeli eğitir. Önce workflow() fonksiyonu ile model ve veri ön işleme adımlarını tek bir yapı içinde toplar. add_recipe(rs_recipe) ifadesi, veriye uygulanacak tüm ön işlemleri (eksik değer temizleme, dönüştürmeler, kategorik değişkenlerin dummy’ye çevrilmesi gibi) workflow’a ekler. Ardından add_model(rf_spec) ile daha önce tanımlanan Random Forest modeli bu iş akışına bağlanır. Bu aşamaya kadar model henüz eğitilmemiştir; sadece “nasıl çalışacağı” tanımlanmıştır. Sonraki adımda fit(data = train_data) fonksiyonu çalıştırılarak, recipe önce train_data üzerinde uygulanır ve elde edilen işlenmiş veri Random Forest modeline verilerek model eğitilir. Böylece rf_fit nesnesi, hem kullanılan ön işleme adımlarını hem de eğitilmiş modeli birlikte saklar ve bundan sonraki tahmin, değerlendirme ve analiz işlemleri için hazır hale gelir.

rf_preds_prob <- predict(rf_fit, test_data, type = "prob")
head(rf_preds_prob)
## # A tibble: 6 × 2
##   .pred_FALSE .pred_TRUE
##         <dbl>      <dbl>
## 1      0.798      0.202 
## 2      0.0161     0.984 
## 3      0.880      0.120 
## 4      0.305      0.695 
## 5      0.948      0.0519
## 6      0.234      0.766
rf_class <- predict(rf_fit, test_data)

Kurduğumuz Random Forest modelinin her bir gözlem için ürettiği olasılık tahminidir.

rf_results <- test_data %>%
  select(Transported) %>%
  bind_cols(rf_class)

Yukarıdaki kod, test veri setindeki gerçek sınıf değerleri ile modelin tahmin ettiği sınıfları tek bir tablo içinde birleştirir. İlk olarak select(Transported) ifadesi, test_data içinden yalnızca hedef değişken olan Transported sütununu alır. Daha sonra bind_cols(rf_class) komutu kullanılarak, Random Forest modelinin test verisi için ürettiği sınıf tahminleri bu tabloya yan yana eklenir. Sonuçta oluşan rf_results nesnesi, hem gerçek değerleri hem de modelin tahmin ettiği sınıfları aynı veri çerçevesinde gösterir; bu da ilerleyen adımlarda doğruluk, karışıklık matrisi (confusion matrix) gibi performans ölçümlerinin kolayca hesaplanmasına imkan sağlar.

rf_acc <- accuracy(
  data = rf_results,
  truth = Transported,
  estimate = .pred_class
)

rf_acc %>%
  kable(digits = 3,
        col.names = c("Metrik", "Tahmin Türü", "Doğruluk")) %>%
  kable_styling(full_width = TRUE,
                bootstrap_options = c("striped", "hover"))
Metrik Tahmin Türü Doğruluk
accuracy binary 0.809

Yukarıdaki kod, Random Forest modeliyle elde edilen tahminlerin doğruluk (accuracy) performansını hesaplar. accuracy() fonksiyonu, rf_results tablosundaki gerçek sınıf değerleri (truth = Transported) ile modelin tahmin ettiği sınıflar (estimate = .pred_class) arasındaki uyumu ölçer. Çıktıda görülen 0.80 değeri, modelin test verisindeki gözlemlerin yaklaşık %80.9’unu doğru sınıflandırdığını gösterir. Başka bir ifadeyle, model tahminlerinin beş gözlemden dördü doğru, biri hatalıdır.

Confusion Matrix

conf_mat_rf <- conf_mat(
  data = rf_results,
  truth = Transported,
  estimate = .pred_class
)

autoplot(conf_mat_rf, type = "heatmap") +
  scale_fill_gradient(low = "white", high = "steelblue") +
  labs(title = "Random Forest — Confusion Matrix (Isı Haritası)")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

  • TRUE POSITIVE: 718 — Model, gerçekten Transported = TRUE olanları doğru tahmin etmiş.

  • TRUE NEGATIVE: 689 — Model, gerçekten Transported = FALSE olanları doğru tahmin etmiş.

  • FALSE POSITIVE: 174 — Model, Transported = TRUE olmayanları yanlışlıkla TRUE tahmin etmiş.

  • FALSE NEGATIVE: 158 — Model, Transported = TRUE olanları yanlışlıkla FALSE tahmin etmiş.

rf_pred_prob <- predict(rf_fit, test_data, type = "prob")

rf_results <- rf_results %>%
  bind_cols(rf_pred_prob) %>%
  mutate(Transported = relevel(Transported, ref = "TRUE"))

rf_roc <- roc_curve(
  data  = rf_results,
  truth = Transported,
  .pred_TRUE
)

autoplot(rf_roc) +
  labs(title = "ROC Eğrisi",
       subtitle = "Random Forest Modeli")

rf_workflow <- workflow() %>%
  add_recipe(logistic_recipe) %>%
  add_model(rf_spec)
rf_fit <- rf_workflow %>%
  fit(data = train)
rf_tahminler <- rf_fit %>%
  predict(new_data = test) %>%
  bind_cols(test)
rf_submission <- rf_tahminler %>%
  select(PassengerId, .pred_class) %>%
  rename(Transported = .pred_class)
rf_submission <- as.data.frame(rf_submission)
rf_submission$Transported <- str_to_title(rf_submission$Transported)

write.csv(rf_submission,
          "random_forest.csv",
          row.names = FALSE,
          quote = FALSE)

Yukarıdaki kod, Random Forest modeliyle elde edilen tahminleri Kaggle’a yüklenebilecek bir dosya haline getirir. İlk olarak yeni bir workflow kurulup logistic_recipe adlı veri ön işleme adımları ve rf_spec Random Forest modeli birlikte eklenir; ardından fit() fonksiyonu ile model train veri seti kullanılarak eğitilir. Sonrasında predict(new_data = test) ifadesi ile test veri seti için sınıf tahminleri üretilir ve bind_cols(test) ile bu tahminler test verisiyle yan yana birleştirilir. select(PassengerId, .pred_class) komutu yalnızca Kaggle’ın istediği iki sütunu bırakır ve rename(Transported = .pred_class) ile tahmin sütununun adı Transported olarak değiştirilir. Daha sonra veri çerçevesine dönüştürülür ve str_to_title() kullanılarak TRUE/FALSE değerleri Kaggle formatına uygun şekilde True/False biçimine çevrilir. Son adımda write.csv() fonksiyonu ile dosya “random_forest.csv” adıyla diske kaydedilir, satır isimleri eklenmez ve gereksiz tırnak işaretleri yazdırılmaz. Böylece oluşturulan CSV dosyası, doğrudan Kaggle’a yüklenmeye hazır hale gelir.

3.5.2 XGBoost

library(xgboost)

XGBoost (Extreme Gradient Boosting), gradyan artırmalı (gradient boosting) karar ağaçlarının optimize edilmiş ve yüksek performanslı bir uygulamasıdır. Özellikle büyük veri setleri ve karmaşık ilişkiler içeren problemler için geliştirilmiş olup; hız, esneklik ve tahmin doğruluğu açısından literatürde geniş kabul görmüştür. Kaggle gibi veri bilimi platformlarında yaygın biçimde tercih edilmesinin temel nedeni, düzenlileştirme (regularization) mekanizmaları ve güçlü genelleme kabiliyetidir.

XGBoost’un temelinde, hataları ardışık olarak azaltmayı hedefleyen “boosting” yaklaşımı bulunmaktadır. İlk model kurulduktan sonra, bir sonraki model önceki modelin yaptığı hatalara odaklanarak eğitilir. Bu süreç yinelenir ve her yeni ağaç, önceki ağaçların eksik kaldığı alanları iyileştirir. Böylece, zayıf öğrenicilerin (weak learners) birlikte çalışmasıyla güçlü bir topluluk modeli oluşturulur.

Algoritma, amaç fonksiyonuna eklenen L1 ve L2 düzenlileştirme terimleri sayesinde aşırı öğrenme (overfitting) riskini azaltır. Ayrıca kayıp fonksiyonunun ikinci türevine kadar (Newton yaklaşımı) dayanan optimizasyon süreci, modelin hem daha kararlı hem de daha hızlı öğrenmesini sağlar. Paralel hesaplama, eksik değerlere duyarlı bölme stratejileri ve ağaç budama teknikleri de XGBoost’un hesaplama verimliliğini artıran önemli özelliklerdir.

Sınıflandırma problemlerinde olasılık tahminleri üzerinden karar verirken, regresyon problemlerinde tahmin hatasını minimize etmeyi amaçlar. Esneklik açısından; log-loss, squared error, Poisson ve benzeri farklı amaç fonksiyonları ile çalışabilmektedir. Aynı zamanda, değişken önem ölçümleri aracılığıyla modelde etkili olan değişkenlerin değerlendirilmesine olanak sağlar.

Sonuç olarak XGBoost, hem doğruluk hem de performans açısından modern makine öğrenmesi uygulamalarında öne çıkan, güçlü ve ölçeklenebilir bir algoritmadır. Özellikle yüksek boyutlu veri setlerinde, karmaşık örüntülerin tahmin edilmesinde ve rekabetçi modelleme çalışmalarında etkili bir alternatif sunmaktadır.

xgb_spec <- boost_tree(
  trees = 500,
  learn_rate = 0.05,
  tree_depth = 6,
  min_n = 5,
  loss_reduction = 0
) %>%
  set_mode("classification") %>%
  set_engine("xgboost")

Yukarıdaki kod,bir XGBoost (gradient boosting) modeli tanımlar. boost_tree() fonksiyonu, modelin nasıl çalışacağını belirleyen temel ayarları oluşturur. Burada trees = 500 ifadesi, modelin 500 adet ağaç oluşturacağını gösterir; bu ağaçlar ardışık olarak kurulup hataları azaltmaya çalışır. learn_rate = 0.05, her yeni ağacın modele ne kadar “katkı” yapacağını belirler; düşük bir öğrenme oranı modeli daha yavaş ama daha kontrollü şekilde öğrenmeye zorlar. tree_depth = 6, her ağacın maksimum derinliğini belirleyerek modelin karmaşıklığını sınırlar. min_n = 5, bir yaprak düğümde en az 5 gözlem olması gerektiğini belirtir ve aşırı öğrenmeyi azaltmaya yardımcı olur. loss_reduction = 0 ise yeni bölünmelerin eklenmesi için minimum iyileşme gereksinimini tanımlar; burada sıfır olması, daha esnek bölünmelere izin verir. Ardından set_mode(“classification”) modelin bir sınıflandırma problemi için kullanılacağını, set_engine(“xgboost”) ise bu boosting modelinin XGBoost motoru ile çalıştırılacağını belirtir. Bu kod yalnızca modeli tanımlar; model henüz eğitilmez, sadece eğitim için hazır hale getirilir.

xgb_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(xgb_spec)

xgb_fit <- xgb_workflow %>%
  fit(data = train_data)

Yukarıdaki kod, oluşturulan XGBoost modelini veri ön işleme adımlarıyla birlikte bir workflow içine yerleştirir ve ardından modeli eğitir. İlk olarak workflow() fonksiyonu ile model ve recipe aynı yapı içinde toplanır; add_recipe(rs_recipe) ifadesi, eksik değer düzenleme, dönüştürme ve dummy değişken oluşturma gibi tüm ön işleme adımlarını bu workflow’a ekler. Daha sonra add_model(xgb_spec) komutu ile biraz önce tanımlanan XGBoost modeli bu iş akışına bağlanır. Bu noktaya kadar model yalnızca yapılandırılmış durumdadır. Sonraki adımda fit(data = train_data) çalıştırılarak recipe önce train_data üzerinde uygulanır, ardından elde edilen işlenmiş veriler kullanılarak XGBoost modeli eğitilir. Böylece oluşan xgb_fit nesnesi, hem ön işleme adımlarını hem de eğitilmiş modeli birlikte içerir ve bundan sonraki tahmin ve performans değerlendirme işlemleri için hazır hale gelir.

xgb_preds_prob <- predict(xgb_fit, test_data, type = "prob")
head(xgb_preds_prob)
## # A tibble: 6 × 2
##   .pred_FALSE .pred_TRUE
##         <dbl>      <dbl>
## 1      0.790     0.210  
## 2      0.0162    0.984  
## 3      0.903     0.0972 
## 4      0.250     0.750  
## 5      0.995     0.00519
## 6      0.154     0.846
xgb_class <- predict(xgb_fit, test_data)

Kurduğumuz XGBoost modelinin her bir gözlem için ürettiği olasılık tahminidir.

xgb_results <- test_data %>%
  select(Transported) %>%
  bind_cols(xgb_class)

Yukarıdaki kod, XGBoost modelinin tahminleri ile test veri setindeki gerçek değerleri tek bir tablo içinde birleştirir. İlk olarak select(Transported) ifadesi, test_data içinden yalnızca hedef değişken olan Transported sütununu alır. Ardından bind_cols(xgb_class) komutu, modelin test verisi için ürettiği sınıf tahminlerini bu tabloya yanına ekler. Sonuçta oluşan xgb_results nesnesi hem gerçek sınıfları hem de modelin tahmin ettiği sınıfları birlikte içerir. Bu yapı sayesinde bir sonraki adımda doğruluk hesabı, karışıklık matrisi gibi performans ölçümleri kolayca yapılabilir.

xgb_acc <- accuracy(
  data = xgb_results,
  truth = Transported,
  estimate = .pred_class
)

xgb_acc %>%
  kable(digits = 3,
        col.names = c("Metrik", "Tahmin Türü", "Doğruluk")) %>%
  kable_styling(full_width = TRUE,
                bootstrap_options = c("striped", "hover"))
Metrik Tahmin Türü Doğruluk
accuracy binary 0.809

Yukarıdaki kod, XGBoost modelinin test verisi üzerindeki doğruluk (accuracy) performansını hesaplar. accuracy() fonksiyonu, xgb_results tablosunda yer alan gerçek sınıf değerleri (truth = Transported) ile modelin tahmin ettiği sınıfları (estimate = .pred_class) karşılaştırır ve doğru tahmin edilen gözlemlerin toplam içindeki oranını verir. Çıktıda görülen 0.809 değeri, modelin gözlemlerin yaklaşık %80.9’unu doğru sınıflandırdığını gösterir. Başka bir ifadeyle, XGBoost modeli her beş gözlemden dört tanesini doğru tahmin etmektedir.

Confusion Matrix

conf_mat_xgb <- conf_mat(
  data = xgb_results,
  truth = Transported,
  estimate = .pred_class
)

autoplot(conf_mat_xgb, type = "heatmap") +
  scale_fill_gradient(low = "white", high = "steelblue") +
  labs(title = "XGBoost — Confusion Matrix (Isı Haritası)")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

  • TRUE POSITIVE: 716 — Model, gerçekten Transported = TRUE olanları doğru tahmin etmiş.

  • TRUE NEGATIVE: 690 — Model, gerçekten Transported = FALSE olanları doğru tahmin etmiş.

  • FALSE POSITIVE: 173 — Model, Transported = TRUE olmayanları yanlışlıkla TRUE tahmin etmiş.

  • FALSE NEGATIVE: 160 — Model, Transported = TRUE olanları yanlışlıkla FALSE tahmin etmiş.

xgb_pred_prob <- predict(xgb_fit, test_data, type = "prob")

xgb_results <- xgb_results %>%
  bind_cols(xgb_pred_prob) %>%
  mutate(Transported = relevel(Transported, ref = "TRUE"))

xgb_roc <- roc_curve(
  data  = xgb_results,
  truth = Transported,
  .pred_TRUE
)

autoplot(xgb_roc) +
  labs(title = "ROC Eğrisi",
       subtitle = "XGBoost Modeli")

Sonuç olarak lojistik regresyon, Random Forest ve XGBoost modellerini denedik. Bu modeller arasından en iyi performanslardan birini gösteren Random Forest’ı seçtik ve Kaggle’a yükledik. Sonuçlar aşağıda yer almaktadır.