TİTANİK PROJESİ

A) Spaceship Titanic ve Kaggle

1. Giriş

  • Bu derste, veri bilimi ve makine öğrenmesi sürecini baştan sona uygulayacağız.

  • Çalışma için Kaggle’daki Spaceship Titanic yarışması kullanılacak.

2. Amaç

  • Gerçek hayata benzer bir veri bilimi sürecini sistematik ve şeffaf şekilde deneyimlemek.

  • R programlama dilinde veri analizi ve makine öğrenmesi uygulama becerisi kazanmak.

3. Senaryo

  • Veri seti: Uzay gemisindeki yolculara ait bilgiler (yaş, kabin konumu, harcamalar, aile yapısı vb.).

  • Hedef değişken: Yolcunun “anomali sonucunda alternatif bir boyuta taşınıp taşınmadığı”.

  • Görev: Bu bilgileri kullanarak taşınma durumunu tahmin eden bir sınıflandırma modeli kurmak.

4. Karşılaşılacak Problemler

  • Eksik veriler ve veri temizleme

  • Değişken seçimi ve özellik mühendisliği

  • Farklı modellerin kurulması ve karşılaştırılması

  • Uygun değerlendirme ölçütlerinin seçilmesi (Accuracy, F1, ROC-AUC vb.)

5. Beklenen Çıktılar

  • Uçtan uca bir veri bilimi sürecinin deneyimlenmesi

  • R dilinde modelleme ve analiz becerilerinin gelişmesi

  • Kaggle yarışmasına uygun bir tahmin modeli ve submission dosyası hazırlanması

Bu yapı sayesinde dersin neden yapıldığını, nasıl ilerleyeceğini ve hangi çıktıları hedeflediğini çok net görebilirsin.

Kaggle Nedir?

Kaggle, veri bilimi ve makine öğrenmesi alanında dünyanın en çok kullanılan çevrimiçi platformlarından biridir. Bu platform, hem öğrenme hem de uygulama için geniş bir ekosistem sunar.

Kullanıcıların Yapabilecekleri

  • Yarışmalara Katılmak: Farklı zorluk seviyelerinde düzenlenen yarışmalarda gerçek veya kurgusal veri setleriyle çalışarak tahmin modelleri geliştirebilirler. Bu yarışmalar, hem rekabet hem de öğrenme fırsatı sağlar.

  • Veri Setlerini İncelemek: Kaggle, binlerce açık veri seti barındırır. Kullanıcılar bu verileri indirip analiz ederek kendi projelerini geliştirebilir.

  • Not Defterlerini (Notebooks) Kullanmak: Diğer katılımcıların paylaştığı kod örneklerini ve çözümleri inceleyerek yeni teknikler öğrenebilir, kendi çalışmalarına uyarlayabilirler.

  • Topluluk ve Forumlar: Tartışma bölümlerinde sorular sorabilir, deneyim paylaşabilir ve veri bilimi topluluğundan destek alabilirler.

  • Eğitim Materyalleri: Kaggle Learn gibi bölümler sayesinde kısa ve pratik derslerle veri bilimi, makine öğrenmesi ve yapay zekâ konularında kendini geliştirebilirler.

Neden Önemli?

Kaggle, kullanıcıların:

  • Becerilerini geliştirmesine (örneğin R veya Python’da model kurma),

  • Yeni teknikler öğrenmesine (örneğin derin öğrenme, feature engineering),

  • Gerçek dünya problemlerini çözmesine olanak tanır.

Kısacası Kaggle, hem öğrenme ortamı hem de uygulama sahası sunarak veri bilimi yolculuğunu daha eğlenceli ve öğretici hale getirir.

Spaceship Titanic Yarışması Açıklaması

Spaceship Titanic, Kaggle platformunda düzenlenen bir sınıflandırma yarışmasıdır. Bu yarışmada amaç, kurgusal bir uzay gemisindeki yolcuların yaşanan bir anomali sonucunda alternatif bir boyuta taşınıp taşınmadığını tahmin etmektir.

Veri Seti

Yarışmada verilen veri seti, yolculara ait birçok farklı bilgiyi içerir:

  • Demografik özellikler: Yaş, cinsiyet vb.

  • Seyahat detayları: Kabin konumu, hangi güvertede oldukları, aile yapısı.

  • Harcama alışkanlıkları: Yemek, alışveriş, spa, VR gibi hizmetlere yapılan harcamalar.

Bu özellikler, yolcunun taşınıp taşınmadığını belirleyen hedef değişken ile ilişkilendirilir.

Yarışmanın Amacı

Katılımcılar, bu verileri kullanarak makine öğrenmesi modelleri geliştirir.

  • Eğitim (train) veri seti → Modeli kurmak ve öğrenmek için kullanılır.

  • Test veri seti → Modelin performansını ölçmek için kullanılır.

Amaç, hangi yolcuların taşındığını en doğru şekilde tahmin eden modeli geliştirmektir.

Katılımcıların Deneyimleyeceği Adımlar

Bu yarışma, veri bilimi sürecinin tüm kritik aşamalarını deneyimleme fırsatı sunar:

  • Veri ön işleme: Eksik verileri doldurma, veriyi temizleme.

  • Özellik mühendisliği: Yeni değişkenler üretme, önemli özellikleri seçme.

  • Model seçimi: Lojistik regresyon, Random Forest, XGBoost gibi farklı algoritmaları deneme.

  • Model değerlendirme: Accuracy, F1-score, ROC-AUC gibi ölçütlerle performansı karşılaştırma.

Neden Önemli?

Spaceship Titanic yarışması, hem eğlenceli bir senaryo sunar hem de gerçek dünyadaki veri bilimi projelerinde karşılaşılan zorlukları birebir simüle eder. Bu sayede katılımcılar, teoriyi pratiğe dökme ve R veya Python gibi dillerde becerilerini geliştirme fırsatı bulur.

B) 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.

C) Dosya ve Veri Alanı Açıklamaları

train.csv : Yolcuların yaklaşık üçte ikisinin (~8700) kişisel kayıtları, eğitim verisi olarak kullanılacak.

PassengerId: Her yolcu için benzersiz bir kimlik. Her kimlik, yolcunun seyahat ettiği grubu ve gruptaki numarasını belirtir gggg_pp . Gruptaki kişiler genellikle aile üyeleridir, ancak her zaman değil. ggggpp

HomePlanet: Yolcunun ayrıldığı gezegen, genellikle daimi ikamet ettiği gezegen.

CryoSleep: Yolcunun yolculuk süresince askıya alınmış animasyona geçmeyi seçip seçmediğini belirtir. Kriyo uykudaki yolcular kabinlerine kapatılır.

Cabin: Yolcunun kaldığı kabin numarası. Şeklinde olup deck/num/side , İskele veya Sancak için side olabilir .PS

Destination :Yolcunun ineceği gezegen.

Age: Yolcunun yaşı.

VIP: Yolcunun seyahat sırasında özel VIP hizmeti için ödeme yapıp yapmadığı. RoomService, FoodCourt, ShoppingMall, Spa, - Uzay Gemisi Titanic’in birçok lüks olanağından VRDeckher birinde yolcunun faturalandırdığı tutar .

Name: Yolcunun adı ve soyadı.

Transported: Yolcunun başka bir boyuta taşınıp taşınmadığı. Bu, tahmin etmeye çalıştığınız hedef, yani sütun.

test.csv Transported :Test verisi olarak kullanılacak, yolcuların kalan üçte birine (yaklaşık 4300) ait kişisel kayıtlar. Göreviniz, bu kümedeki yolcular için değerini tahmin etmektir .

sample_submission.csv : Doğru formatta bir gönderim dosyası. PassengerId : Test setindeki her yolcunun kimliği. Transported : Hedef. Her yolcu için, ya True da tahmin edin False.

D) Veri Setini Anlama (Açıklama)

Bir veri bilimi projesine başlamadan önce yapılması gereken ilk adım, veri setini tanımak ve anlamaktır. Çünkü elimizdeki veriyi doğru şekilde kavramadan, modelleme sürecine geçmek sağlıklı olmaz.

library(tidyverse)
Warning: package 'tidyverse' was built under R version 4.4.3
Warning: package 'ggplot2' was built under R version 4.4.3
Warning: package 'tibble' was built under R version 4.4.3
Warning: package 'tidyr' was built under R version 4.4.3
Warning: package 'readr' was built under R version 4.4.3
Warning: package 'purrr' was built under R version 4.4.3
Warning: package 'dplyr' was built under R version 4.4.3
Warning: package 'forcats' was built under R version 4.4.3
Warning: package 'lubridate' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.5.1
✔ ggplot2   4.0.0     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.1.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readr)
library(rmarkdown)
Warning: package 'rmarkdown' was built under R version 4.4.3
# Veri setini R ortamına alalım
train <- read_csv("C:/Users/DELL/Downloads/train.csv")
Rows: 8693 Columns: 14
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (5): PassengerId, HomePlanet, Cabin, Destination, Name
dbl (6): Age, RoomService, FoodCourt, ShoppingMall, Spa, VRDeck
lgl (3): CryoSleep, VIP, Transported

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(train)
test <- read_csv("C:/Users/DELL/Downloads/test.csv")
Rows: 4277 Columns: 13
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (5): PassengerId, HomePlanet, Cabin, Destination, Name
dbl (6): Age, RoomService, FoodCourt, ShoppingMall, Spa, VRDeck
lgl (2): CryoSleep, VIP

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(test)
# Veri setini inceleyelim
paged_table(train)
paged_table(test)
  • Eğitim seti → Hem yolcu bilgilerini hem de taşınıp taşınmadığını içerir. Modeli öğrenmek için kullanılır.

  • Test seti → Sadece yolcu bilgilerini içerir, taşınıp taşınma bilgisi yoktur. Modelin tahmin gücünü ölçmek için kullanılır.

Bu ayrım, makine öğrenmesi projelerinin temel mantığını gösterir: önce bilinen etiketlerle (train) öğrenme yapılır, sonra bilinmeyen etiketler (test) tahmin edilir.

# 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 paketinde bulunan ve bir veri çerçevesinin (data frame veya tibble) yapısını hızlı, özet ve okunabilir şekilde incelememizi sağlayan bir fonksiyondur.

Ne yapar?

  • Veri setindeki tüm sütunların adlarını listeler.

  • Her sütunun veri tipini (örneğin: numeric, character, factor) gösterir.

  • Her sütunun ilk birkaç değerini ekrana yansıtır.

Neden kullanılır?

  • Veri setinin genel yapısını hızlıca görmek için.

  • Hangi değişkenlerin hangi türde olduğunu anlamak için.

  • Veri setini detaylı incelemeden önce ilk bakışta fikir edinmek için.

D.1) Değişken Türleri

Bir veri setiyle çalışırken, her sütunun hangi türde olduğunu bilmek çok önemlidir. Çünkü veri türü, hem veriyi nasıl işleyeceğimizi hem de hangi makine öğrenmesi modellerini kullanabileceğimizi belirler. glimpse() fonksiyonu bize bu türleri hızlıca gösterir.

  • dbl (Numeric / Sayısal): Ondalıklı sayıları ifade eder. Örnek: 23.7, 0.45, 117.0. Spaceship Titanic örneği: Age, RoomService, FoodCourt gibi harcama miktarları.

  • chr (Character / Karakter): Metin veya kategorik verileri içerir. Başlangıçta metin olarak gelir, ama modelleme için genellikle faktöre dönüştürülmesi gerekir. Örnek: PassengerId, HomePlanet, Cabin.

  • lgl (Logical / Mantıksal): Sadece TRUE veya FALSE değerleri alır. Örnek: Hedef değişkenimiz Transported (taşındı mı, taşınmadı mı).

  • int (Integer / Tam Sayı): Ondalıklı olmayan tam sayıları gösterir. Örnek: 1, 42, -7. Örnek: Age değişkeni bazen tam sayılar halinde olabilir.

  • fct (Factor / Kategori): Kategorik verilerin R’deki özel türüdür. chr türündeki değişkenler, modelleme için as.factor() ile dönüştürülür. Bu sayede kategoriler daha etkin şekilde kullanılır. Örnek: HomePlanet, Cabin gibi sınıflandırmaya uygun değişkenler.

Özetle:

  • Sayısal veriler → hesaplamalar için kullanılır.

  • Karakter veriler → kategorilere dönüştürülmelidir.

  • Mantıksal veriler → ikili sınıflandırma için idealdir.

  • Faktörler → kategorik değişkenleri modellemede en uygun formdur.

E) 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 

Bir veri setinde eksik değerler (NA), modelin doğruluğunu ve güvenilirliğini doğrudan etkileyebilir. Bu yüzden veri bilimi sürecinde ilk adımlardan biri, hangi sütunlarda ne kadar eksik veri olduğunu tespit etmektir.

  • Eğitim veri setindeki her sütun için eksik değerlerin sayısını hesaplar.

  • Çıktı, hangi değişkenlerde eksik verilerin yoğunlaştığını gösterir.

  • Bu sayede, veri ön işleme aşamasında hangi değişkenlere özel müdahale gerektiğini görürüz.

E.1) Veri Setindeki Değişkenlerin Türlerine Göre Değerlendirilmesi

Veri bilimi projelerinde, her değişkenin türünü doğru anlamak çok önemlidir. Çünkü sayısal, kategorik, mantıksal veya tarihsel değişkenler için uygulanacak işlemler birbirinden farklıdır. Bu adım, modelin başarısını doğrudan etkiler.

🔹 Sayısal Değişkenler (Numeric – dbl, int)

  • Eksik Değerler: Ortalama, medyan veya mod ile doldurulabilir. Alternatif olarak eksik kayıtlar çıkarılabilir.

  • Ölçeklendirme: Bazı algoritmalar (ör. lojistik regresyon, kNN, SVM) için normalizasyon veya standardizasyon gerekebilir.

  • Aykırı Değerler: Uç değerler tespit edilip düzeltilmeli veya gerekirse veri setinden çıkarılmalıdır.

🔹 Kategorik Değişkenler (chr, factor)

  • Eksik Değerler: En sık görülen kategori ile doldurulabilir veya “Bilinmiyor” gibi yeni bir kategori eklenebilir.

  • Dönüştürme: Karakter türündeki değişkenler, modelleme için faktöre (as.factor()) dönüştürülmelidir.

  • Kodlama: Bazı algoritmalar için one-hot encoding (dummy değişkenler) uygulanabilir.

🔹 Mantıksal Değişkenler (logical)

  • Eksik Değerler: TRUE veya FALSE ile doldurulabilir.

  • Dönüştürme: Modelleme aşamasında 0 ve 1 şeklinde sayısal değerlere dönüştürülebilir.

🔹 Tarih ve Zaman Değişkenleri

  • Dönüştürme: Yıl, ay, gün, saat gibi bileşenlere ayrılabilir. Zaman serisi analizlerinde uygun formatlara dönüştürülmelidir.

  • Eksik Değerler: Uygun yöntemlerle doldurulabilir (ör. ortalama tarih, en yakın gözlem).

🔹 Hedef Değişken (Dependent Variable)

  • Türüne Göre İşlem:

    • Sınıflandırma problemlerinde → kategorik olmalı.

    • Regresyon problemlerinde → sayısal olmalı.

  • Gerekirse uygun dönüşümler yapılmalıdır.

# 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>

Eğitim veri setindeki her sütun için benzersiz değerlerin sayısını hesaplamak, veri ön işleme sürecinde kritik bir adımdır çünkü bu analiz bize her değişkenin kaç farklı kategori veya değer içerdiğini gösterir; özellikle kategorik değişkenlerde çok fazla benzersiz değer bulunması modelin karmaşıklığını artırarak aşırı öğrenme (overfitting) riskini yükseltebilir, bu nedenle hangi değişkenlerin doğrudan kullanılabileceğini, hangilerinin dönüştürülmesi veya gruplanması gerektiğini anlamamıza yardımcı olur ve böylece daha dengeli, verimli ve güçlü makine öğrenmesi modelleri geliştirmemizi sağlar.

# 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 (HomePlanetCryoSleepDestinationVIP, ve Transported eğitim setinde; HomePlanetCryoSleepDestination, 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               
                                
                                
                                
                                

summary() fonksiyonu, eğitim veri setindeki her bir değişken için hızlı ve kapsamlı bir özet sunar; sayısal değişkenlerde minimum, maksimum, ortalama, medyan ve çeyrek değerler gibi temel istatistikleri, kategorik değişkenlerde ise her kategoriye ait frekans dağılımını gösterir. Bu özet çıktılar sayesinde veri setinin genel yapısı ve özellikleri kolayca anlaşılır, eksik değerlerin varlığı, aykırı gözlemler veya dengesiz kategorik dağılımlar gibi sorunlar tespit edilerek veri ön işleme sürecinde hangi adımların atılması gerektiğine dair önemli ipuçları elde edilir.

E.2) Faktöre Dönüştürülmeyen Kategorik Değişkenlerin İncelenmesi

PassengerId değişkeni, doğrudan bir kategorik değişken olarak kullanıldığında binlerce farklı kategori üretir ve bu durum modelin öğrenmesine katkı sağlamaz. Ancak bu değişkenin yapısı, aslında önemli bilgiler barındırır. Kaggle’ın tanımına göre PassengerId her yolcu için benzersizdir ve gggg_pp biçimindedir: burada gggg yolcunun birlikte seyahat ettiği grubu, pp ise grubun içindeki kişi sırasını gösterir. Bu gruplar çoğunlukla aile üyelerinden oluşsa da her zaman böyle olmak zorunda değildir. Dolayısıyla PassengerId’nin kendisini doğrudan modele sokmak yerine, içindeki bu alt bilgileri ayıklayarak yeni açıklayıcı değişkenler (örneğin “grup büyüklüğü”, “gruptaki kişi sırası”, “yalnız mı seyahat ediyor?” gibi) türetmek çok daha anlamlıdır. Bu yaklaşım, veri ön işleme sürecinde PassengerId’yi verimli bir şekilde kullanmamızı sağlar.

# 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))

Bu kod, PassengerId sütununu daha anlamlı hale getirmek için parçalayarak yeni değişkenler üretir. separate() fonksiyonu sayesinde, PassengerId’nin “gggg_pp” biçimindeki yapısı ikiye ayrılır: Grup_No yolcunun hangi gruba ait olduğunu, Kisi_No ise o grubun içindeki sırasını gösterir. Ardından mutate() ile Grup_No kategorik bir değişken (factor) haline getirilir, Kisi_No ise tam sayı (integer) türüne dönüştürülür. Böylece PassengerId’nin kendisini doğrudan kullanmak yerine, içindeki bilgiyi çıkarıp modelleme için daha açıklayıcı ve anlamlı özellikler elde etmiş oluruz. Bu yeni değişkenler, yolcuların aile veya grup ilişkilerini ve grup içindeki konumlarını yansıtarak tahmin modellerine ek değer kazandırır.

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 eden gruplara ait olup olmadıklarını ve grup içindeki sıralarını ortaya koyarak veri setine ek anlam kazandırır. Böylece, yalnız seyahat eden yolcular ile grup halinde seyahat edenler arasında farklı davranış kalıpları olup olmadığını inceleyebiliriz. Bu tür bilgiler, modelin yolcuların taşınıp taşınmadığını tahmin etme gücünü artırabilir; çünkü aile veya grup ilişkileri, harcama alışkanlıkları ve taşınma olasılığı üzerinde etkili olabilecek önemli bir faktördür.

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

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

Bu kod, Grup_No değişkenini kullanarak yolcuları gruplar ve her grubun kaç kişiden oluştuğunu hesaplayarak Grup_Buyuklugu adlı yeni bir sütun ekler. group_by(Grup_No) ile yolcular aynı gruplar altında toplanır, mutate(Grup_Buyuklugu = n()) ifadesiyle her grubun yolcu sayısı belirlenir ve ungroup() ile gruplama işlemi sonlandırılır. Böylece her yolcu için ait olduğu grubun büyüklüğü bilgisi elde edilir. Bu yeni değişken, modelleme sürecinde önemli bir açıklayıcı özellik olarak kullanılabilir; çünkü grup büyüklüğü, yolcuların taşınma olasılığı üzerinde etkili olabilir. Örneğin, büyük gruplar genellikle birlikte hareket etme eğiliminde olduklarından, taşınma kararları da bu dinamikten etkilenebilir.

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))

Bu kod, yolcuların tek başına mı yoksa bir grup içinde mi seyahat ettiklerini göstermek için yeni bir değişken üretir. mutate() fonksiyonu ile Grup_Buyuklugu kontrol edilir; eğer grup büyüklüğü 1 ise yolcu yalnız seyahat ediyor demektir ve Yalniz_Seyahat sütununa 1 atanır, aksi durumda 0 atanır. Böylece her yolcu için “yalnız mı seyahat ediyor?” bilgisi elde edilir. Bu değişken, modelleme sürecinde önemli bir açıklayıcı özellik olarak kullanılabilir; çünkü yalnız seyahat eden yolcular ile grup halinde seyahat edenlerin taşınma olasılıkları farklılık gösterebilir ve bu fark, modelin tahmin gücünü artırabilir.

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 

Bu kod, Grup_Buyuklugu değişkenini daha anlamlı hale getirmek için kategorik bir forma dönüştürür. case_when() fonksiyonu ile grup büyüklüğü 1, 2 veya 3 olan yolcular için bu değerler aynen korunur, ancak 4 ve üzeri yolcular için tek bir kategori olan “4+” atanır. Ardından mutate() ile bu yeni sütun Grup_Buyuklugu_Kat adıyla eklenir ve faktör (factor) türüne dönüştürülür. Böylece grup büyüklükleri sınıflandırılmış bir değişken haline gelir. Bu yaklaşım, modelleme sürecinde daha açıklayıcı bir özellik sağlar; çünkü farklı grup büyüklüklerinin taşınma olasılığı üzerinde farklı etkiler yaratıp yaratmadığı incelenebilir. Son adımda table() fonksiyonu kullanılarak bu kategorilerin frekans dağılımı görüntülenir ve veri setinde hangi grup büyüklüklerinin daha yaygın olduğu kolayca anlaşılır.

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))

Cabin değişkeni, yolcuların gemideki konumlarını ifade eden önemli bir bilgidir ve genellikle “Deck/Numara/Side” formatında kodlanmıştır. Burada:

  • Deck → Yolcunun bulunduğu güverteyi (katı) gösterir.

  • Numara → Kabinin sıra numarasını belirtir.

  • Side → Kabinin geminin hangi tarafında (örneğin “P” = Port, “S” = Starboard) olduğunu gösterir.

Bu yapı sayesinde yolcuların gemideki fiziksel konumları hakkında detaylı bilgi elde edilebilir. Modelleme sürecinde Cabin değişkeni doğrudan kullanılabileceği gibi, içindeki alt bileşenler ayrı sütunlara ayrılarak daha açıklayıcı özellikler (örneğin “güverte”, “taraf”, “yakınlık ilişkileri”) üretilebilir. Böylece yolcuların konumlarının taşınma olasılığı üzerindeki etkisi incelenebilir ve modelin performansı artırılabilir.

Kısacası, Cabin değişkeni yalnızca bir metin değil; doğru şekilde parçalandığında yolcuların gruplar halinde mi yoksa belirli bölgelerde mi yoğunlaştığını anlamamıza yardımcı olan güçlü bir açıklayıcı değişkendir.

# 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))

Bu kod, Cabin sütununu daha anlamlı hale getirmek için parçalayarak üç ayrı değişkene dönüştürür: Deck, Numara ve Side. separate() fonksiyonu ile Cabin’in “Deck/Numara/Side” formatı ayrıştırılır; ardından mutate() kullanılarak Deck ve Side kategorik (factor) türüne, Numara ise tam sayı (integer) türüne çevrilir. Böylece yolcuların gemideki konumları daha açık şekilde temsil edilir. Bu yeni değişkenler, modelleme sürecinde güçlü açıklayıcı özellikler olarak kullanılabilir; çünkü yolcuların bulunduğu güverte veya geminin hangi tarafında oldukları, taşınma olasılıklarını etkileyebilecek önemli faktörlerdir.

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ı daha ayrıntılı şekilde anlamamızı sağlar ve modelin tahmin gücünü artırabilecek önemli ipuçları sunar. Örneğin, bazı güverteler veya geminin belirli tarafları anomaliye karşı daha savunmasız olabilir; bu da yolcuların taşınma olasılığını farklılaştırabilir. Benzer şekilde, kabin numarası yolcunun gemideki fiziksel konumunu gösterdiği için, bulunduğu bölgeye bağlı olarak taşınma ihtimali üzerinde etkili olabilir. Dolayısıyla Deck, Numara ve Side gibi ayrıştırılmış değişkenler, modelleme sürecinde güçlü açıklayıcı özellikler olarak kullanılabilir ve yolcuların taşınma davranışlarını daha doğru şekilde tahmin etmeye katkı sağlar.

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,
                             Diger = c("A", "D", "T")))
test <- test %>%
  mutate(Deck = fct_collapse(Deck,
                             Diger = c("A", "D", "T")))

Bu kod, Deck değişkeninde çok az gözleme sahip olan “A”, “D” ve “T” kategorilerini tek bir grup altında toplayarak “Diğer” adlı yeni bir kategori oluşturur. Bu işlem fct_collapse() fonksiyonu ile yapılır ve nadir görülen kategorilerin model üzerindeki olumsuz etkisini azaltmayı amaçlar. Çünkü az sayıda örneğe sahip kategoriler, modelin öğrenme sürecinde gürültü yaratabilir ve genelleme yeteneğini düşürebilir. Bu nedenle, veri ön işleme aşamasında bu tür kategorilerin birleştirilmesi sık kullanılan bir yöntemdir. Sonuç olarak, Deck değişkeni daha dengeli bir dağılıma kavuşur ve modelin performansı ile genelleme gücü artırılabilir.

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

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)

Bu kod, Name sütununu daha anlamlı hale getirmek için parçalayarak iki ayrı değişken üretir: Soyad ve Ad. separate() fonksiyonu kullanılarak isimler boşluk karakterine göre ayrıştırılır; böylece her yolcunun soyadı ve adı ayrı sütunlarda tutulur. Bu yeni değişkenler, modelleme sürecinde açıklayıcı özellikler olarak değerlendirilebilir. Örneğin, belirli soyadlara sahip yolcuların taşınma olasılıkları farklılık gösterebilir ya da bazı adlar demografik özellikler hakkında ipuçları verebilir. Kısacası, Name sütununun parçalanması yolcuların kimlik bilgilerini daha detaylı incelememizi sağlar ve modelin tahmin gücünü artırabilecek ek bilgiler sunar.

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 isimlerinden ek anlam çıkarmamıza olanak tanır ve modelin performansını güçlendirebilir. Soyadlar, belirli demografik gruplarla veya aile bağlarıyla ilişkilendirilebilirken, adlar kültürel ya da coğrafi kökenler hakkında ipuçları verebilir. Böylece isimlerden türetilen bilgiler, yolcuların sosyal veya kültürel özelliklerini yansıtarak taşınma olasılıklarını etkileyebilecek ek açıklayıcı değişkenler sağlar. Kısacası, Name sütununun parçalanması yalnızca kimlik bilgilerini ayırmakla kalmaz, aynı zamanda modelin daha doğru ve kapsamlı tahminler yapmasına katkıda bulunur.

E.3) Boş Değerlerin Doldurulması

Eksik (NA) değerlerin doldurulması, veri ön işleme sürecinde modelin güvenilirliğini ve performansını doğrudan etkileyen kritik bir adımdır. Eksik veriler, hem istatistiksel analizlerde hem de makine öğrenmesi modellerinde hatalı veya yanıltıcı sonuçlara yol açabilir. Bu nedenle, uygun yöntemlerle doldurulmaları gerekir. Sayısal değişkenlerde ortalama, medyan veya regresyon temelli yöntemlerle doldurma yapılabilirken; kategorik değişkenlerde en sık görülen kategori veya “Bilinmiyor” gibi yeni bir kategori ekleme tercih edilebilir. Zaman serisi verilerinde ise ileri/geri doldurma (forward/backward fill) veya interpolasyon yöntemleri kullanılabilir. Eksik değerlerin doğru şekilde ele alınması, veri setinin bütünlüğünü korur ve modelin genelleme yeteneğini artırarak daha sağlıklı tahminler yapılmasına olanak tanır.

HomePlanet değişkenindeki eksik değerlerin doldurulması, veri ön işleme sürecinde kritik bir adımdır çünkü yolcuların gezegen bilgisi modelin tahmin gücünü doğrudan etkileyebilir. Bu eksik değerleri doldururken basitçe en sık görülen kategoriyi atamak yerine, yolcuların diğer özelliklerinden yararlanmak daha anlamlıdır. Örneğin:

  • Cabin bilgisi: Belirli güverteler veya taraflar, genellikle belirli gezegenlerden gelen yolcularla ilişkilidir.

  • Destination bilgisi: Yolcuların gitmek istedikleri hedefler, geldikleri gezegen hakkında ipuçları verebilir.

  • Grup bilgisi (PassengerId’den türetilen): Aynı gruptaki yolcuların çoğu aynı gezegenden geliyor olabilir, bu da eksik değeri doldurmak için güçlü bir ipucu sağlar.

Bu tür ilişkilerden yararlanarak eksik HomePlanet değerleri için en olası gezegen atanabilir. Böylece doldurma işlemi daha tutarlı olur ve modelin genelleme yeteneği artar.

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>

Bu kod, Grup_No değişkenine göre yolcuları gruplandırarak her grup için özet istatistikler üretir. summarize() fonksiyonu ile 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 grupta kaç farklı HomePlanet bulunduğu (Grup_kac_farkli_HP) hesaplanır. Ardından ungroup() ile gruplama kaldırılır. Bu özet bilgiler, özellikle HomePlanet değişkenindeki eksik değerleri doldurmak için yol gösterici olabilir; çünkü aynı gruptaki yolcuların çoğunlukla aynı gezegenden gelmesi beklenir. Böylece eksik değerler, grubun baskın gezegen bilgisine göre daha güvenilir şekilde doldurulabilir ve veri setinin bütünlüğü korunarak modelin performansı artırılabilir.

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

Bu adım, Home_Planet_GrupNO_bilgi veri setinde Grup_kac_farkli_HP = 0 olan grupları filtreleyerek grup_0 adlı yeni bir veri seti oluşturur. Bu filtreleme sonucunda elde edilen 110 grup, gerçekten hiç HomePlanet kaydı bulunmayan grupları temsil eder.

Bunun anlamı:

  • Bu gruplarda hiçbir yolcu için HomePlanet bilgisi mevcut değildir.

  • Dolayısıyla, eksik değer doldurma sürecinde bu gruplar için doğrudan grup içi çoğunluk veya baskın gezegen bilgisine dayanarak doldurma yapmak mümkün değildir.

  • Bu tür gruplar için alternatif stratejiler gerekir: örneğin Destination, Cabin veya benzer yolcuların özelliklerinden faydalanarak en olası gezegenin atanması.

Kısacası, bu analiz bize hangi grupların tamamen eksik olduğunu net biçimde gösterir ve eksik değer doldurma stratejisini daha bilinçli şekilde tasarlamamıza yardımcı olur.

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

Bu adım, Home_Planet_GrupNO_bilgi veri setinde Grup_kac_farkli_HP = 1 olan grupları filtreleyerek grup_1 adlı yeni bir veri seti oluşturur. Bu gruplar, şu yapıyı temsil eder:

  • Grup içinde bazı yolcuların HomePlanet bilgisi eksiktir (NA).

  • Ancak aynı grupta en az bir yolcunun HomePlanet bilgisi doludur.

  • Dahası, grupta yalnızca tek bir farklı HomePlanet gözlenmiştir.

📌 Bu durum, eksik değer doldurma sürecinde çok güçlü bir ipucu sağlar:

  • Aynı gruptaki yolcuların büyük olasılıkla aynı gezegenden geldiği varsayılabilir.

  • Dolayısıyla eksik HomePlanet değerleri, gruptaki dolu olan gezegen bilgisine göre doldurulabilir.

  • Bu yöntem, hem veri bütünlüğünü korur hem de modelin daha doğru tahminler yapmasına katkı sağlar.

# 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.

# Doldurmadan önce/sonra kaç NA vardı görmek istersen:
sum(is.na(train$HomePlanet))  # şu anki NA sayısı
[1] 201
#  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  

Bu işlemde yolcular Grup_No değişkenine göre gruplandırılır ve her grup için eksik olmayan ilk HomePlanet değeri çıkarılarak hp_referans_train veri seti oluşturulur; böylece her grup için güvenilir bir “referans gezegen” bilgisi elde edilir. summarise() fonksiyonu bu değeri belirlerken .groups = "drop" parametresi gruplama yapısını kaldırır ve sonuç düz bir tablo haline gelir. Bu referans gezegen bilgisi, aynı grupta eksik HomePlanet değeri bulunan yolcular için doldurma sürecinde kullanılabilir; çünkü aynı gruptaki yolcuların genellikle aynı gezegenden geldiği varsayılır ve bu yöntem eksik verilerin tutarlı şekilde tamamlanmasına yardımcı olur.

# 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  

Bu adımda amaç, her yolcunun ait olduğu grubun referans HomePlanet bilgisini orijinal veri setine eklemektir. Bunun için left_join() fonksiyonu kullanılarak train ve test veri setleri, sırasıyla hp_referans_train ve hp_referans_test ile Grup_No üzerinden birleştirilir. Böylece her yolcuya, grubundaki dolu HomePlanet değerinden türetilen Grup_HP bilgisi atanır. Bu ek bilgi, özellikle eksik HomePlanet değerlerini doldurmak için güçlü bir kaynak sağlar; çünkü aynı gruptaki yolcuların genellikle aynı gezegenden geldiği varsayılır. Sonuç olarak, veri setleri daha bütünlüklü hale gelir ve modelleme sürecinde daha güvenilir tahminler yapılmasına katkı sağlanır.

# 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

Bu adımda yapılan işlem, train ve test veri setlerindeki eksik HomePlanet değerlerini sistematik biçimde doldurmaktır. mutate() fonksiyonu içinde kullanılan ifelse() sayesinde, HomePlanet bilgisi eksik olan yolcular için gruplarından gelen referans HomePlanet (Grup_HP) değeri atanır; eğer yolcunun HomePlanet bilgisi zaten doluysa mevcut değer korunur. Böylece her yolcu için eksik gezegen bilgisi güvenilir bir şekilde tamamlanmış olur. Sonrasında select(-Grup_HP) ile artık yalnızca doldurma sürecinde kullanılan geçici sütun veri setinden çıkarılır. Bu yaklaşım, veri setinin bütünlüğünü korur ve modelleme aşamasında eksik verilerin oluşturabileceği hataları önleyerek daha sağlam tahminler yapılmasına katkı sağlar.

sum(is.na(train$HomePlanet))  
[1] 111
# doldurduktan sonraki NA sayısı
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 ""      

Bu kod, yolcuları Soyad değişkenine göre gruplandırarak her soyad için özet istatistikler üretir. summarise() fonksiyonu sayesinde, aynı soyada sahip yolcuların toplam sayısı (soyad_kac_kisi), grupta görülen farklı HomePlanet sayısı (kac_farkli_HP) ve eksik değerler hariç tutulmak üzere dolu HomePlanet kayıtlarının birleşik listesi (hangi_HP) hesaplanır. na.rm = TRUE parametresi, eksik (NA) değerlerin bu hesaplamalara dahil edilmemesini sağlar. Son olarak .groups = "drop" ile gruplama kaldırılarak sonuç düz bir tabloya dönüştürülür.

table(soyad_planet_analizi$kac_farkli_HP)

   0    1    3 
   7 2210    1 

Soyad bazında yapılan analizde 2210 farklı soyadın her birinin yalnızca tek bir gezegene ait olduğu görülmüş, bu da soyadın aile yapısını doğru şekilde temsil ettiğini ve eksik HomePlanet değerlerini doldurmak için güvenilir bir değişken olduğunu göstermiştir. Tek istisna, Soyad = NA olan yolcuların bulunduğu gruptur; bu grup üç farklı gezegenden gelen kişileri içerdiği için aslında bir aileyi temsil etmez. Dolayısıyla gerçek soyadı olan yolcular arasında herhangi bir tutarsızlık bulunmamaktadı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  
rain <- train %>%
  left_join(hp_referans_soyad, by = "Soyad")
test <- test %>%
  left_join(hp_referans_soyad, by = "Soyad")
# Train için temiz ve garantili işlem
train <- train %>%
  # Varsa eski hatalı sütunları temizleyelim (hata vermemesi için select(any_of...))
  select(-any_of(c("Soyad_HP", "Soyad_HP.x", "Soyad_HP.y"))) %>%
  # Yeniden temiz bir join yapalım
  left_join(hp_referans_soyad, by = "Soyad") %>%
  # HomePlanet'i güncelle (Soyad_HP sütunu join'den sonra gelecektir)
  mutate(HomePlanet = coalesce(as.character(HomePlanet), as.character(Soyad_HP))) %>%
  # Yardımcı sütunu siliyoruz
  select(-Soyad_HP)

# Test için de aynısını yapalım
test <- test %>%
  select(-any_of(c("Soyad_HP", "Soyad_HP.x", "Soyad_HP.y"))) %>%
  left_join(hp_referans_soyad, by = "Soyad") %>%
  mutate(HomePlanet = coalesce(as.character(HomePlanet), as.character(Soyad_HP))) %>%
  select(-Soyad_HP)

Bu kod, hem train hem de test veri setlerinde eksik HomePlanet değerlerini soyad bazlı referans bilgisiyle doldurmak için uygulanır; önce olası hatalı sütunlar temizlenir, ardından left_join() ile her yolcunun soyadına karşılık gelen referans gezegen bilgisi (Soyad_HP) veri setine eklenir, mutate() ve coalesce() kullanılarak eksik HomePlanet değerleri bu referansla tamamlanır, dolu olanlar ise korunur, son adımda ise geçici Soyad_HP sütunu silinerek veri seti sadeleştirilir; böylece eksik veriler güvenilir şekilde doldurulmuş ve veri seti modelleme için tutarlı hale getirilmiş olur.

# Doldurduktan sonra kaç NA kaldığını görelim.
sum(is.na(train$HomePlanet)) 
[1] 12
sum(is.na(test$HomePlanet)) 
[1] 7
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 Diger           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>

Bu kod, yolcuları Deck değişkenine göre gruplandırarak her güverte için özet istatistikler çıkarır. summarize() fonksiyonu ile her güvertede toplam yolcu sayısı, HomePlanet bilgisi eksik olanların ve dolu olanların sayısı, farklı gezegen sayısı ve dolu gezegenlerin birleşik listesi hesaplanır; na.rm = TRUE eksik değerlerin bu hesaplamalara dahil edilmemesini sağlar. Sonrasında ungroup() ile gruplama kaldırılarak sonuç düz bir tabloya dönüştürülür. Bu analiz, güverte bazında HomePlanet dağılımını anlamamıza yardımcı olur. Örneğin, B ve C güvertelerinde yolcuların tamamı Europa gezegeninden gelirken, G güvertesinde yolcuların tamamı Earth gezegenindendir. Bu tutarlılık, eksik HomePlanet değerlerini doldururken güverte bilgisini güvenilir bir referans olarak kullanmamızı sağlar.

# 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
# Doldurduktan sonra kaç NA kaldığını görelim.
sum(is.na(train$HomePlanet)) 
[1] 9
sum(is.na(test$HomePlanet))
[1] 5
table(train$HomePlanet)

 Earth Europa   Mars 
  4707   2173   1804 
train <- train %>%
  mutate(HomePlanet = coalesce(HomePlanet, "Earth"))
test <- test %>%
  mutate(HomePlanet = coalesce(HomePlanet, "Earth"))

Bu kod, train ve test veri setlerinde eksik olan HomePlanet değerlerini sistematik biçimde doldurmak için kullanılır. mutate() fonksiyonu içinde coalesce() sayesinde, eğer bir yolcunun HomePlanet bilgisi boşsa ona varsayılan olarak “Earth” değeri atanır; eğer zaten doluysa mevcut değer korunur. Böylece tüm eksik kayıtlar tamamlanmış olur ve veri setlerinde HomePlanet değişkeni eksiksiz hale getirilir. Bu işlem, modelleme sürecinde eksik verilerin yaratabileceği sorunları ortadan kaldırarak daha tutarlı ve güvenilir sonuçlar elde edilmesine yardımcı 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)

Destination değişkeni yolcuların varış noktalarını ifade eder ve bazı eksik değerlere sahiptir; bu eksik değerleri doldururken basitçe en sık görülen destinasyonu atamak yerine yolcuların diğer özelliklerinden yararlanmak daha anlamlıdır. Örneğin, bir yolcunun geldiği HomePlanet ile gitmek istediği destinasyon arasında güçlü bir ilişki bulunabilir veya bulunduğu Cabin bilgisi belirli varış noktalarıyla daha sık eşleşebilir. Bu tür ipuçları kullanılarak eksik Destination değerleri en olası seçenekle doldurulabilir, böylece veri seti daha tutarlı hale gelir ve modelleme sürecinde daha güvenilir sonuçlar elde edilir.

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 

Bu kod, yolcuları Grup_No değişkenine göre gruplandırarak her grup için Destination bilgisine dair özet istatistikler üretir: toplam yolcu sayısı, eksik ve dolu kayıtların sayısı, farklı destinasyonların sayısı ve dolu değerlerin listesi. na.rm = TRUE ile eksik değerler hesaplamalardan çıkarılır, ungroup() ile gruplama kaldırılır. Ancak bu özet bilgiler yalnızca mevcut durumun fotoğrafını verir; hangi yolcunun eksik değerinin hangi destinasyonla doldurulması gerektiğini doğrudan çözmez. Çünkü bazı gruplarda birden fazla farklı destinasyon bulunabilir veya eksik değerlerin hangi destinasyona ait olduğu belirsiz kalabilir. Dolayısıyla bu analiz, veri setindeki eksiklikleri anlamak için faydalı olsa da, eksik Destination değerlerini güvenilir şekilde doldurmak için tek başına yeterli değildir; bunun için ek değişkenler (örneğin HomePlanet, Cabin, Soyad) veya grup içi baskın destinasyon bilgisi gibi daha güçlü ipuçlarına ihtiyaç vardır.

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)
Warning: package 'rpart' was built under R version 4.4.3
library(rpart.plot)
Warning: package 'rpart.plot' was built under R version 4.4.3
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
)

Bu kod, rpart paketini kullanarak yolcuların Destination (varış noktası) değişkenini tahmin etmeye yönelik bir karar ağacı modeli kurar. 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 yer alır. Eğitim süreci yalnızca Destination bilgisi eksik olmayan yolcular üzerinde gerçekleştirilir (filter(!is.na(Destination))), böylece model eksik değerlerden etkilenmez. method = "class" parametresi bunun bir sınıflandırma problemi olduğunu belirtirken, cp = 0.00221 parametresi karar ağacının karmaşıklığını kontrol ederek aşırı dallanmayı (overfitting) önler. Sonuçta elde edilen model, yolcuların diğer özelliklerine dayanarak eksik Destination değerlerini doldurmak veya yeni yolcular için varış noktası tahmini yapmak amacıyla kullanılabilir.

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

Bu kod, oluşturulan karar ağacı (dt_model) yardımıyla train veri setindeki yolcular için eksik Destination değerlerini tahmin etmeyi amaçlar. predict() fonksiyonu kullanılarak her yolcu için modelin öngördüğü varış noktası hesaplanır ve type = "class" parametresi sayesinde sınıflandırma problemine uygun olarak doğrudan sınıf etiketleri döndürülür. Elde edilen tahminler, veri setine Destination_tree_pred adlı yeni bir sütun olarak eklenir. Böylece eksik Destination bilgisi olan yolcular için modelin tahmin ettiği değerler kullanılabilir ve veri seti daha eksiksiz, tutarlı hale getirilerek sonraki analiz ve modelleme adımlarında güvenilirlik artırılır.

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

Bu kod, karar ağacı modeliyle test veri setindeki yolcular için Destination tahminleri üretir; predict() fonksiyonu type = "class" parametresiyle sınıf etiketlerini döndürür ve sonuçlar Destination_tree_pred sütunu olarak veri setine eklenir. Böylece eksik Destination değerleri model tahminleriyle doldurulabilir.

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 Diger 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 Diger 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 Diger 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 Diger 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 Diger 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 Diger 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"
    )
  )
train$Destination_tree_pred2 <- factor(
  train$Destination_tree_pred2,
  levels = levels(train$Destination)
)
mean(train$Destination_tree_pred2 == train$Destination_tree_pred2)
[1] 1

Bu kod, yolcuların özelliklerine göre kurallar tanımlayarak train veri setinde yeni bir sütun (Destination_tree_pred2) oluşturur; case_when() ile uygun kuralı sağlayan yolculara ilgili Destination atanır, hiçbir kurala uymayanlara ise varsayılan olarak “TRAPPIST-1e” verilir.

train <- train %>%
  mutate(
    Destination = ifelse(
      is.na(Destination),
      as.character(Destination_tree_pred2), 
      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)
  )

Bu kod, hem train hem de test veri setlerinde eksik olan Destination değerlerini karar ağacı modelinden elde edilen tahminlerle doldurur. mutate() içinde kullanılan ifelse() sayesinde, Destination bilgisi boş olan yolculara Destination_tree_pred atanır; dolu olanlarda ise mevcut değer korunur. Ardından factor() fonksiyonu ile Destination değişkeni kategorik veri tipine dönüştürülür ve orijinal seviyeler korunur. Böylece tüm eksik Destination değerleri tamamlanmış ve değişken modelleme için eksiksiz, tutarlı hale getirilmiş olur.

# Train seti için
train <- train %>% 
  select(-any_of(c("Destination_tree_pred", "Destination_tree_pred2")))

# Test seti için
test <- test %>% 
  select(-any_of("Destination_tree_pred"))
library(explore)
Warning: package 'explore' was built under R version 4.4.3
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

CryoSleep değişkeni yolcuların dondurulmuş uyku durumunu gösterir ve bazı eksik değerlere sahiptir. Bu eksik değerleri doldururken basitçe rastgele atama yapmak yerine yolcuların diğer özelliklerinden yararlanmak daha anlamlıdır. Örneğin, bir yolcunun HomePlanet bilgisi, bulunduğu Cabin veya gitmek istediği Destination ile CryoSleep arasında güçlü ilişkiler olabilir; belirli gezegenlerden gelen yolcuların daha sık CryoSleep tercih etmesi ya da bazı güvertelerdeki yolcuların bu durumda bulunması gibi. Bu tür ipuçları kullanılarak eksik CryoSleep değerleri en olası durumla doldurulabilir, böylece veri seti daha tutarlı hale gelir ve sonraki modelleme adımlarında daha güvenilir sonuçlar elde edilir.

summary(train$CryoSleep)
FALSE  TRUE  NA's 
 5439  3037   217 
 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>
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>
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
  ))
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>
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
  ))
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>
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
  ))
 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>
train <- train %>%
 mutate(CryoSleep = factor(CryoSleep))
test <- test %>% 
 mutate(CryoSleep = factor(CryoSleep))
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
)

train$CryoSleep_tree_pred <- predict(
  cs_model,
  newdata = train,
  type   = "class"
)
test$CryoSleep_tree_pred <- predict(
  cs_model,
  newdata = test,
  type   = "class"
)
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)
  )
library(dplyr)

# Train için
train <- train %>% 
  select(-any_of("CryoSleep_tree_pred"))

# Test için
test <- test %>% 
  select(-any_of("CryoSleep_tree_pred"))
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

Deck değişkeni yolcuların gemideki güvertesini gösterir ve bazı eksik değerler içerir. Bu eksiklikleri doldururken, yolcuların diğer özelliklerinden yararlanmak mantıklıdır. Örneğin, bir yolcunun geldiği HomePlanet ile bulunduğu güverte arasında güçlü bir ilişki olabilir; aynı şekilde aynı aileye (soyad veya grup numarası) ait yolcuların genellikle aynı güvertede konakladığı gözlenir. Bu tür ipuçları kullanılarak eksik Deck değerleri en olası güverteyle doldurulabilir, böylece veri seti daha tutarlı hale gelir ve sonraki analiz veya modelleme adımlarında daha güvenilir sonuçlar elde edilir.

summary(train$Deck)
Diger     B     C     E     F     G  NA's 
  739   779   747   876  2794  2559   199 
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
)

train$deck_tree_pred <- predict(
  deck_model,
  newdata = train,
  type   = "class"
)
test$deck_tree_pred <- predict(
  deck_model,
  newdata = test,
  type   = "class"
)
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)
  )
library(dplyr)

train <- train %>%
  select(-any_of("deck_tree_pred"))

test <- test %>%
  select(-any_of("deck_tree_pred"))
# Hem train hem test için toplu silme
cols_to_remove <- c("deck_tree_pred", "Cabin", "Numara", "Name", "Ad", "Soyad", "Grup_Buyuklugu")

train <- train %>% select(-any_of(cols_to_remove))
test <- test %>% select(-any_of(cols_to_remove))
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

Side değişkeni yolcuların gemide hangi tarafta (Port veya Starboard) bulunduğunu gösterir ve bazı eksik değerler içerir. Bu eksiklikleri doldururken, yolcuların diğer özelliklerinden yararlanmak mantıklıdır. Örneğin, aynı Cabin veya Deck üzerinde bulunan yolcuların genellikle aynı tarafı paylaşması, aynı aile/grup içindeki yolcuların aynı tarafta yer alması veya belirli HomePlanet–Destination kombinasyonlarının belirli taraflarla daha sık eşleşmesi gibi ilişkiler kullanılabilir. Bu ipuçları sayesinde eksik Side değerleri en olası tarafla doldurularak veri seti daha tutarlı hale getirilebilir ve sonraki analizlerde güvenilirlik artırılır.

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
)

train$side_tree_pred <- predict(
  side_model,
  newdata = train,
  type   = "class"
)
test$side_tree_pred <- predict(
  side_model,
  newdata = test,
  type   = "class"
)
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)
  )
train <- train %>%
  select(-side_tree_pred)
test <- test %>%
  select(-side_tree_pred)
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
)

train$vip_tree_pred <- predict(
  vip_model,
  newdata = train,
  type   = "class"
)
test$vip_tree_pred <- predict(
  vip_model,
  newdata = test,
  type   = "class"
)
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)
  )
train <- train %>%
  select(-vip_tree_pred)
test <- test %>%
  select(-vip_tree_pred)
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

Age değişkeni, yolcuların yaş bilgisini ifade eder ve her yolcunun kaç yaşında olduğunu gösterir. Bu değişken, demografik bir özellik olarak yolcuların davranışlarını, tercihlerini veya diğer değişkenlerle olan ilişkilerini anlamada kullanılabilir. Örneğin, yaş ile CryoSleep durumu, Destination seçimi veya harcama kalemleri (RoomService, FoodCourt vb.) arasında anlamlı ilişkiler bulunabilir. Ayrıca eksik yaş değerleri varsa, bunlar grup, aile veya benzer özelliklere sahip yolcuların yaş ortalamaları kullanılarak doldurulabilir.

age_model <- lm(
  Age ~ HomePlanet + CryoSleep + Deck + VIP + Destination + Side + RoomService + 
    FoodCourt + ShoppingMall + Spa + VRDeck + Grup_Buyuklugu_Kat+ Yalniz_Seyahat,
  data = train)
train$age_tree_pred <- predict(
  age_model,
  newdata = train
)
test$age_tree_pred <- predict(
  age_model,
  newdata = test
)
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))
train <- train %>%
  select(-age_tree_pred)
test <- test %>%
  select(-age_tree_pred)
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
train <- train %>%
  mutate(
    Age = ifelse(
      is.na(Age),
      round(mean_age), Age))
test <- test %>%
  mutate(
    Age = ifelse(
      is.na(Age),
      round(mean_age), Age))
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

RoomService, FoodCourt, ShoppingMall, Spa ve VRDeck değişkenleri, yolcuların gemide yaptığı harcamaları temsil eden sayısal (numeric) değişkenlerdir.

  • RoomService: Yolcunun oda servisine yaptığı harcama tutarı.

  • FoodCourt: Gemideki yemek alanında (food court) yaptığı harcama tutarı.

  • ShoppingMall: Alışveriş merkezinde yaptığı harcama tutarı.

  • Spa: Spa hizmetlerine yaptığı harcama tutarı.

  • VRDeck: Sanal gerçeklik güvertesinde yaptığı harcama tutarı.

Bu değişkenler genellikle yolcuların yaşam tarzı, sosyoekonomik durumu veya CryoSleep durumuyla ilişkili olabilir. Örneğin, CryoSleep’te olan yolcuların bu harcamaları genellikle 0 olur çünkü hizmetlerden faydalanmazlar. Ayrıca toplam harcama miktarı, yolcuların davranışlarını ve tercihlerini anlamak için kullanılabilir.

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.
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"))
train <- train %>%
  mutate(RoomService = ifelse(is.na(RoomService), med, RoomService)) %>%
  select(-med)
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.
train <- train  %>%
  left_join(median_table_fc, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
train <- train %>%
  mutate(FoodCourt = ifelse(is.na(FoodCourt), med, FoodCourt)) %>%
  select(-med)
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.
train <- train %>%
  left_join(median_table_sm, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
train <- train %>%
  mutate(ShoppingMall = ifelse(is.na(ShoppingMall), med, ShoppingMall)) %>%
  select(-med)
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.
train <- train %>%
  left_join(median_table_spa, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
train <- train %>%
  mutate(Spa = ifelse(is.na(Spa), med, Spa)) %>%
  select(-med)
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.
train <- train %>%
  left_join(median_table_vrd, by = c("HomePlanet", "Deck", "CryoSleep", "Destination", "VIP", "Grup_Buyuklugu_Kat", "Side", "Age_Group"))
train <- train %>%
  mutate(VRDeck = ifelse(is.na(VRDeck), med, VRDeck)) %>%
  select(-med)
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 <- 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"))
test <- test %>%
  mutate(RoomService = ifelse(is.na(RoomService), med, RoomService)) %>%
  select(-med)
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)
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)
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)
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)
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)
  )
train <- train %>%
  select(-c(Grup_No, Kisi_No, Yalniz_Seyahat))
test <- test %>%
  select(-c(Grup_No, Kisi_No, Yalniz_Seyahat))

E.4) Modelleme İçin Hazırlık

library(tidymodels)
Warning: package 'tidymodels' was built under R version 4.4.3
── Attaching packages ────────────────────────────────────── tidymodels 1.4.1 ──
✔ broom        1.0.10     ✔ rsample      1.3.1 
✔ dials        1.4.2      ✔ tailor       0.1.0 
✔ infer        1.1.0      ✔ tune         2.0.1 
✔ modeldata    1.5.1      ✔ workflows    1.3.0 
✔ parsnip      1.4.0      ✔ workflowsets 1.1.1 
✔ recipes      1.3.1      ✔ yardstick    1.3.2 
Warning: package 'broom' was built under R version 4.4.3
Warning: package 'dials' was built under R version 4.4.3
Warning: package 'scales' was built under R version 4.4.3
Warning: package 'infer' was built under R version 4.4.3
Warning: package 'modeldata' was built under R version 4.4.3
Warning: package 'parsnip' was built under R version 4.4.3
Warning: package 'recipes' was built under R version 4.4.3
Warning: package 'rsample' was built under R version 4.4.3
Warning: package 'tailor' was built under R version 4.4.3
Warning: package 'tune' was built under R version 4.4.3
Warning: package 'workflows' was built under R version 4.4.3
Warning: package 'workflowsets' was built under R version 4.4.3
Warning: package 'yardstick' was built under R version 4.4.3
── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
✖ scales::discard() masks purrr::discard()
✖ dplyr::filter()   masks stats::filter()
✖ recipes::fixed()  masks stringr::fixed()
✖ dplyr::lag()      masks stats::lag()
✖ dials::prune()    masks rpart::prune()
✖ yardstick::spec() masks readr::spec()
✖ recipes::step()   masks stats::step()
install.packages("rsample")
Warning: package 'rsample' is in use and will not be installed
library(rsample)
rsample::initial_split(train, prop = 0.8, strata = Transported)
<Training/Testing/Total>
<6954/1739/8693>
set.seed(123)

# Fonksiyonun önüne rsample:: ekleyerek doğrudan paketten çağırıyoruz
data_split <- rsample::initial_split(train, prop = 0.8, strata = Transported)

train_data  <- rsample::training(data_split)
test_data   <- rsample::testing(data_split)
set.seed(123)

# Fonksiyonun önüne rsample:: ekleyerek doğrudan paketten çağırıyoruz
data_split <- rsample::initial_split(train, prop = 0.8, strata = Transported)

train_data  <- rsample::training(data_split)
test_data   <- rsample::testing(data_split)
library(rsample)
# Now this will work:
data_split <- initial_split(train, prop = 0.8, strata = Transported)
data_split <- rsample::initial_split(train, prop = 0.8, strata = Transported)
set.seed(123)

data_split <- initial_split(train, prop = 0.8, strata = Transported)
train_data  <- training(data_split)
test_data   <- testing(data_split)
library(magrittr)   # %>% pipe operatörünü yükler

Attaching package: 'magrittr'
The following object is masked from 'package:purrr':

    set_names
The following object is masked from 'package:tidyr':

    extract
install.packages("dplyr")
Warning: package 'dplyr' is in use and will not be installed
library(dplyr)      # veri işleme için gerekli
install.packages("tidymodels")
Warning: package 'tidymodels' is in use and will not be installed
library(tidymodels) # recipe fonksiyonu için gerekli

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())
install.packages("recipes")
Warning: package 'recipes' is in use and will not be installed
library(recipes)
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())
install.packages("parsnip")   # eğer yüklü değilse
Warning: package 'parsnip' is in use and will not be installed
library(parsnip)
install.packages("workflows")   # eğer yüklü değilse
Warning: package 'workflows' is in use and will not be installed
library(workflows)
log_spec <- logistic_reg() %>%
  set_engine("glm")
log_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(log_spec)
rs_recipe <- recipe(Transported ~ ., data = train_data) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_unknown(all_nominal_predictors()) %>%   # eksik kategoriler için
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_normalize(all_numeric_predictors())
rs_recipe <- recipe(Transported ~ ., data = train_data) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_unknown(all_nominal_predictors()) %>%   # NA değerleri "unknown" yapar
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_normalize(all_numeric_predictors())
log_spec <- logistic_reg(penalty = 0.01, mixture = 1) %>%
  set_engine("glmnet")
install.packages("tidymodels")
Warning: package 'tidymodels' is in use and will not be installed
library(tidymodels)
remove.packages("cli")
Removing package from 'C:/Users/DELL/AppData/Local/R/win-library/4.4'
(as 'lib' is unspecified)
remove.packages("rlang")
Removing package from 'C:/Users/DELL/AppData/Local/R/win-library/4.4'
(as 'lib' is unspecified)
# Gerekli paketleri yükle
library(tidymodels)   # recipes, parsnip, workflows, dplyr, magrittr hepsi burada

# Recipe: NA kategorileri "unknown" yap, dummy kodlama ve normalize et
rs_recipe <- recipe(Transported ~ ., data = train_data) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_normalize(all_numeric_predictors())

# Düzenlileştirilmiş lojistik regresyon (glmnet motoru ile)
log_spec <- logistic_reg(penalty = 0.01, mixture = 1) %>%
  set_engine("glmnet")

# Workflow: recipe + model
log_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(log_spec)
# Gerekli paketleri yükle
library(tidymodels)
library(glmnet)
Warning: package 'glmnet' was built under R version 4.4.3
Zorunlu paket yükleniyor: Matrix

Attaching package: 'Matrix'
The following objects are masked from 'package:tidyr':

    expand, pack, unpack
Loaded glmnet 4.1-10
# Recipe: NA kategorileri "unknown" yap, dummy kodlama, varyansı sıfır olanları sil, normalize et
rs_recipe <- recipe(Transported ~ ., data = train_data) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_unknown(all_nominal_predictors()) %>%
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_zv(all_predictors()) %>%
  step_normalize(all_numeric_predictors())

# Düzenlileştirilmiş lojistik regresyon (glmnet motoru ile)
log_spec <- logistic_reg(penalty = 0.01, mixture = 1) %>%
  set_engine("glmnet")

# Workflow: recipe + model
log_workflow <- workflow() %>%
  add_recipe(rs_recipe) %>%
  add_model(log_spec)

# Fit et
log_fit <- log_workflow %>%
  fit(data = train_data)
log_fit <- log_workflow %>% fit(data = train_data)
log_fit <- log_workflow %>%
  fit(data = train_data)

Genelde bu tip ödev ve projelerde kod hataları ve düzeltme adımları olmaz ama ben pojemi her şeyiyle ele alanlardanım.

log_preds <- predict(log_fit, test_data, type = "prob")
head(log_preds)
# A tibble: 6 × 2
  .pred_FALSE .pred_TRUE
        <dbl>      <dbl>
1       0.761     0.239 
2       0.225     0.775 
3       0.763     0.237 
4       0.291     0.709 
5       0.924     0.0762
6       0.382     0.618 
log_class <- predict(log_fit, test_data)
results <- test_data %>%
  select(Transported) %>%
  bind_cols(log_class)
log_acc <- accuracy(data = results,
                    truth = Transported,
                    estimate = .pred_class)
log_acc
# A tibble: 1 × 3
  .metric  .estimator .estimate
  <chr>    <chr>          <dbl>
1 accuracy binary         0.794
conf_mat_log <- conf_mat(data = results,
                         truth = Transported,
                         estimate = .pred_class)
conf_mat_log
          Truth
Prediction FALSE TRUE
     FALSE   697  193
     TRUE    166  683
pred_prob  <- predict(log_fit, test_data, type = "prob")
results <- results %>%
  bind_cols(pred_prob)
autoplot(conf_mat_log, type = "heatmap") +
  scale_fill_gradient(low = "white", high = "steelblue") +
  labs(title = "Confusion Matrix - Isı Haritası")
Scale for fill is already present.
Adding another scale for fill, which will replace the existing scale.

# Test verisi üzerinde olasılık tahminleri al
results <- predict(log_fit, new_data = test_data, type = "prob") %>%
  bind_cols(test_data %>% select(Transported)) %>%
  mutate(Transported = relevel(factor(Transported), ref = "TRUE"))

# ROC eğrisi verisi
roc_data <- roc_curve(
  data  = results,
  truth = Transported,
  .pred_TRUE
)

# ROC eğrisini çiz
autoplot(roc_data) +
  labs(title = "ROC Eğrisi", subtitle = "Lojistik Regresyon Modeli")

Kaggle yarışmasına submission dosyası hazırlama süreci :

# Gerekli paketleri yükle
install.packages("tidymodels")
Warning: package 'tidymodels' is in use and will not be installed
install.packages("glmnet")
Warning: package 'glmnet' is in use and will not be installed
library(tidymodels)
library(glmnet)

# Tek recipe + model + workflow + fit
log_fit <- workflow() %>%
  add_recipe(
    recipe(Transported ~ ., data = train) %>%
      update_role(PassengerId, Age, new_role = "ID") %>%
      step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
      step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
      step_zv(all_predictors()) %>%                # varyansı sıfır olanları siler
      step_normalize(all_numeric_predictors())
  ) %>%
  add_model(
    logistic_reg(penalty = 0.01, mixture = 1) %>%  # düzenlileştirilmiş lojistik regresyon
      set_engine("glmnet")
  ) %>%
  fit(data = train)
library(tidymodels)
library(glmnet)

log_fit <- workflow() %>%
  add_recipe(
    recipe(Transported ~ ., data = train) %>%
      update_role(PassengerId, Age, new_role = "ID") %>%
      step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
      step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
      step_zv(all_predictors()) %>%                # varyansı sıfır olanları siler
      step_normalize(all_numeric_predictors())
  ) %>%
  add_model(
    logistic_reg(penalty = 0.01, mixture = 1) %>%  # düzenlileştirilmiş lojistik regresyon
      set_engine("glmnet")
  ) %>%
  fit(data = train)
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())
log_spec <- logistic_reg() %>%
  set_engine("glm")
log_workflow <- workflow() %>%
  add_recipe(logistic_recipe) %>%
  add_model(log_spec)
library(tidymodels)
library(glmnet)

log_fit <- workflow() %>%
  add_recipe(
    recipe(Transported ~ ., data = train) %>%
      update_role(PassengerId, Age, new_role = "ID") %>%
      step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
      step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
      step_zv(all_predictors()) %>%                # varyansı sıfır olanları siler
      step_normalize(all_numeric_predictors())
  ) %>%
  add_model(
    logistic_reg(penalty = 0.01, mixture = 1) %>%  # düzenlileştirilmiş lojistik regresyon
      set_engine("glmnet")
  ) %>%
  fit(data = train)
# Paketleri yükle
install.packages("tidymodels")
Warning: package 'tidymodels' is in use and will not be installed
install.packages("glmnet")
Warning: package 'glmnet' is in use and will not be installed
library(tidymodels)
library(glmnet)

# Workflow + Recipe + Model + Fit
log_fit <- workflow() %>%
  add_recipe(
    recipe(Transported ~ ., data = train) %>%
      update_role(PassengerId, Age, new_role = "ID") %>%
      step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
      step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
      step_zv(all_predictors()) %>%                # varyansı sıfır olanları siler
      step_normalize(all_numeric_predictors())
  ) %>%
  add_model(
    logistic_reg(penalty = 0.01, mixture = 1) %>%  # düzenlileştirilmiş lojistik regresyon
      set_engine("glmnet")
  ) %>%
  fit(data = train)
# Paketleri yükle
install.packages("tidymodels")
Warning: package 'tidymodels' is in use and will not be installed
install.packages("glmnet")
Warning: package 'glmnet' is in use and will not be installed
library(tidymodels)
library(glmnet)

# Tek kodda recipe + model + workflow + fit
log_fit <- workflow() %>%
  add_recipe(
    recipe(Transported ~ ., data = train) %>%
      update_role(PassengerId, Age, new_role = "ID") %>%
      step_unknown(all_nominal_predictors()) %>%   # NA kategoriler için
      step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
      step_zv(all_predictors()) %>%                # varyansı sıfır olanları siler
      step_normalize(all_numeric_predictors())
  ) %>%
  add_model(
    logistic_reg(penalty = 0.01, mixture = 1) %>%  # düzenlileştirilmiş lojistik regresyon
      set_engine("glmnet")
  ) %>%
  fit(data = train)
log_fit <- log_workflow %>%
  fit(data = train)
Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
install.packages("tidyverse")   # veya install.packages("magrittr")
Warning: package 'tidyverse' is in use and will not be installed
library(tidyverse)              # veya library(magrittr)
library(tidymodels)             # tidymodels fonksiyonları için
log_workflow <- workflow()
log_workflow <- add_recipe(log_workflow,
  recipe(Transported ~ ., data = train) %>%
    update_role(PassengerId, Age, new_role = "ID") %>%
    step_unknown(all_nominal_predictors()) %>%
    step_novel(all_nominal_predictors()) %>%
    step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
    step_zv(all_predictors()) %>%
    step_normalize(all_numeric_predictors())
)
log_workflow <- add_model(log_workflow,
  logistic_reg(penalty = 0.01, mixture = 1) %>%
    set_engine("glmnet")
)
log_fit <- fit(log_workflow, data = train)
library(tidymodels)
library(glmnet)
library(stringr)

# Recipe tanımı
log_recipe <- recipe(Transported ~ ., data = train) %>%
  update_role(PassengerId, Age, new_role = "ID") %>%
  step_unknown(all_nominal_predictors()) %>%
  step_novel(all_nominal_predictors()) %>%
  step_dummy(all_nominal_predictors(), one_hot = TRUE) %>%
  step_zv(all_predictors()) %>%
  step_normalize(all_numeric_predictors())

# Recipe'i hazırla
log_prep <- prep(log_recipe)
# 1. GEREKLİ KÜTÜPHANELER
library(tidymodels)
library(glmnet)

# 2. SÜTUN İSİMLERİNİ VE VERİ SETLERİNİ SABİTLEME
# İsimlerdeki .x, .x.x gibi karmaşayı "Grup_HP_X" formatına getiriyoruz
prepare_data <- function(df) {
  names(df)[names(df) %in% c("Grup_HP.x", "Grup_HP.x.x")] <- "Grup_HP_X"
  names(df)[names(df) %in% c("Grup_HP.y", "Grup_HP.y.y")] <- "Grup_HP_Y"
  # Eğer başka Grup_HP sütunları varsa onları da standartlaştırıyoruz
  names(df)[grepl("Grup_HP", names(df)) & !names(df) %in% c("Grup_HP_X", "Grup_HP_Y")] <- 
    paste0("Grup_HP_", seq_len(sum(grepl("Grup_HP", names(df)) & !names(df) %in% c("Grup_HP_X", "Grup_HP_Y"))))
  return(df)
}

train_final <- prepare_data(train)
test_final <- prepare_data(test)

# 3. MODEL TANIMI
# 'log_model' nesnesi bulunamadı hatasını önlemek için burada tanımlıyoruz
log_model <- logistic_reg(penalty = 0.01, mixture = 1) %>%
  set_engine("glmnet") %>%
  set_mode("classification")

# 4. GELİŞTİRİLMİŞ TARİF (RECIPE)
# step_unknown ve step_impute_median ile NA (boş değer) hatalarını çözüyoruz
log_prep <- recipe(Transported ~ ., data = train_final) %>%
  update_role(PassengerId, new_role = "ID") %>%
  # Kategorik NA değerlerini "Unknown" olarak işaretle
  step_unknown(all_nominal_predictors(), -all_outcomes()) %>%
  # Sayısal NA değerlerini doldur
  step_impute_median(all_numeric_predictors()) %>%
  # Kategorik değişkenleri dummy (0-1) formatına çevir
  step_dummy(all_nominal_predictors(), -all_outcomes()) %>%
  # Hiç varyansı olmayan (sabit) sütunları temizle
  step_zv(all_predictors())

# 5. İŞ AKIŞI (WORKFLOW) OLUŞTURMA VE EĞİTME
# 'bake' hatasından kurtulmak için en güvenli yol budur
spaceship_wf <- workflow() %>%
  add_recipe(log_prep) %>%
  add_model(log_model)

# Modeli eğit (Bu adım otomatik olarak Prep yapar)
spaceship_fit <- fit(spaceship_wf, data = train_final)

# 6. TAHMİN VE DOSYA KAYDETME
# Workflow sayesinde predict komutu test verisini otomatik hazırlar
tahminler <- predict(spaceship_fit, new_data = test_final)

submission <- test_final %>%
  select(PassengerId) %>%
  bind_cols(tahminler) %>%
  rename(Transported = .pred_class) %>%
  mutate(Transported = str_to_title(as.character(Transported)))

# Sonuç dosyasını oluştur
write.csv(submission, "submission_final_v4.csv", row.names = FALSE)

print("İşlem başarıyla tamamlandı! 'submission_final_v4.csv' dosyası hazır.")
[1] "İşlem başarıyla tamamlandı! 'submission_final_v4.csv' dosyası hazır."