proje2_update

Genel Bilgi

2912 yılına hoş geldiniz. Veri bilimi becerilerinize kozmik bir gizemi çözmek için ihtiyaç duyuluyor. Dört ışık yılı uzaklıktan bir iletim aldık ve işler pek de iyi görünmüyor.

Spaceship Titanic, bir ay önce fırlatılan yıldızlararası bir yolcu gemisiydi. Neredeyse 13.000 yolcuyu taşıyan gemi, göçmenleri güneş sistemimizden, yakındaki yıldızların etrafında dönen üç yeni yaşanabilir ötegezegene götürmek üzere ilk yolculuğuna çıkmıştı.

İlk durağı olan kavurucu 55 Cancri E’ye giderken, gemi Alpha Centauri yakınlarında bir toz bulutunun içinde gizlenmiş bir uzay-zaman anomalisiyle çarpıştı. Ne yazık ki, bin yıl önceki adaşıyla benzer bir kaderi paylaştı. Gemi bütünlüğünü korumuş olsa da, yolcuların neredeyse yarısı alternatif bir boyuta taşındı!

Kurtarma ekiplerine yardımcı olmak ve kaybolan yolcuları geri getirmek için, uzay gemisinin hasar görmüş bilgisayar sisteminden kurtarılan kayıtları kullanarak hangi yolcuların anomali tarafından taşındığını tahmin etmeniz isteniyor.

Onları kurtarın ve tarihi değiştirin!

Kullanılacak kütüphaneler

library(readr)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ purrr     1.1.0
✔ forcats   1.0.1     ✔ stringr   1.5.1
✔ ggplot2   4.0.0     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
── 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(explore)
library(dplyr)
library(tidyr)
library(VIM)
Загрузка требуемого пакета: colorspace
Загрузка требуемого пакета: grid
VIM is ready to use.

Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues

Присоединяю пакет: 'VIM'

Следующий объект скрыт от 'package:datasets':

    sleep
library(ggplot2)
library(recipes)

Присоединяю пакет: 'recipes'

Следующий объект скрыт от 'package:VIM':

    prepare

Следующий объект скрыт от 'package:stringr':

    fixed

Следующий объект скрыт от 'package:stats':

    step

Dosya ve Veri indirimi

train <- read_csv("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.
test <- read_csv("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.

Dosya ve Veri Alanı Açıklamaları

  • train.csv - Eğitim verisi olarak kullanılacak yolcuların yaklaşık üçte ikisinin (yaklaşık 8700) kişisel kayıtları.

  • PassengerId - Her yolcu için benzersiz bir kimlik. Her kimlik, gggg_pp biçimini alır; burada gggg, yolcunun seyahat ettiği grubu, pp ise grup içindeki numarasını belirtir. Bir gruptaki kişiler genellikle aile üyeleridir, ancak her zaman değil.

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

  • CryoSleep - Yolcunun yolculuk süresince askıya alınmış animasyona alınmayı seçip seçmediğini belirtir. Cryosleep’teki yolcular kabinlerine kapatılır.

  • Cabin - Yolcunun kaldığı kabin numarası. deck/num/side biçimini alır; burada side, P (İskele) veya S (Sancak) olabilir.

  • Destination - Yolcunun ineceği gezegen.

  • Age - Yolcunun yaşı.

  • VIP - Yolcunun yolculuk sırasında özel VIP hizmeti için ödeme yapıp yapmadığı.

  • Room Service, FoodCourt, Shopping Mall, Spa, VRDeck - Yolcunun Titanic Uzay Gemisi’nin birçok lüks olanağından her biri için ödediği fatura 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 sütundur.

  • test.csv - Test verisi olarak kullanılacak kalan üçte bir yolcunun (~4300) kişisel kayıtları.

  • PassengerId - Test kümesindeki her yolcunun kimliği.

  • Transported - Hedef. Her yolcu için Doğru veya Yanlış tahmin edin.

Boş olan veri sütünü açıklamaları

train %>% is.na() %>% colSums()
 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 

PassengerId

train <- train %>%
  separate(PassengerId, sep = "_", into = c("Aile", "KisiNo"), remove = FALSE) 

HomePlanet

HomePlanet sütününde hangi farklı değerler var ve bunlar kaçtane

unique(train$HomePlanet)
[1] "Europa" "Earth"  "Mars"   NA      
table(train$HomePlanet)

 Earth Europa   Mars 
  4602   2131   1759 

Grup içinde olan insanların aynı gezegenden yola çıkıp-çıkmadığını öğrenmek için bir inceleme oluştururuz

inceleme <- train %>% group_by(Aile) %>%
  summarise(
    uye_s = n(),
    bos_sayisi = sum(is.na(HomePlanet)),
    bosolamyan_sayisi = sum(!is.na(HomePlanet)),
    farkli_gezegen = n_distinct(HomePlanet,na.rm = TRUE),
    gezegen_adi = unique(HomePlanet[!is.na(HomePlanet)])
  ) 
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in
dplyr 1.1.0.
ℹ Please use `reframe()` instead.
ℹ When switching from `summarise()` to `reframe()`, remember that `reframe()`
  always returns an ungrouped data frame and adjust accordingly.
`summarise()` has grouped output by 'Aile'. You can override using the
`.groups` argument.
train <- left_join(train,inceleme)
Joining with `by = join_by(Aile)`

Görüldüğü üzere aynı grup içinde olan insanlar aynı yerden yola çıkmışlardır.Buna dayanarak veri setindeki boşlukları doldururuz.

train <- train %>% group_by(Aile) %>% mutate(
  HomePlanet = ifelse(
    bos_sayisi != 0 & uye_s > 1,
    gezegen_adi,
    HomePlanet
  )
)

train <- train %>% group_by(Destination,CryoSleep,VIP) %>% mutate(
  HomePlanet = ifelse(
   is.na(HomePlanet),                     
      sample(HomePlanet[!is.na(HomePlanet)], 1), 
      HomePlanet
  )
)

CryoSleep

Eğer bir yolcunun tüm harcamaları (RoomService, FoodCourt, ShoppingMall, Spa, VRDeck) sıfırsa, bu kişi muhtemelen “uykudaydı” → CryoSleep = TRUE.

train <- train %>% mutate(
  CryoSleep = ifelse( is.na(CryoSleep) & RoomService == 0 & FoodCourt == 0 & ShoppingMall == 0 & Spa == 0 & VRDeck == 0, TRUE, CryoSleep)
)

Eğer bir yolcunun tüm harcamaları (RoomService, FoodCourt, ShoppingMall, Spa, VRDeck) sıfır değilse, bu kişi muhtemelen “uykuda değildi” → CryoSleep = FALSE.

train <- train %>% mutate(
  CryoSleep = ifelse( is.na(CryoSleep) & (RoomService > 0 | FoodCourt > 0 | ShoppingMall > 0 | Spa > 0 | VRDeck > 0), FALSE, CryoSleep)
)

Hangı gezegenden çıktığına göre uyku alışkanlıkları farklı olabilir buna dayanarak CryoSleep sütünündeki boşluları dolduralım.

train <- train %>% group_by(HomePlanet) %>% mutate(
   CryoSleep = ifelse(
     is.na(CryoSleep),                     
      sample(CryoSleep[!is.na(CryoSleep)], 1),  
      CryoSleep                             
   )
) %>%
  ungroup()

Cabin

Veri setini incelediğimizde aynı Grup üyeleri aynı kabinde kaldığı görülebilir

train <- train %>% group_by(Aile) %>% mutate(
   Cabin = ifelse(is.na(Cabin),
                 if(length(Cabin[!is.na(Cabin)]) > 0) sample(Cabin[!is.na(Cabin)], 1) else NA,
                 Cabin)
)

Hangi gezegenden çıktığına,VIP yolcu olup olmdığına göre Cabin sütünü değişiklik gösterebilir. Buna dayanarak Cabin veri sütününde boşluklar doldurulabilir

train <- train %>% group_by(HomePlanet,Destination,VIP) %>% mutate(
   Cabin = ifelse(
     is.na(Cabin),                     # Cabin boşsa
      sample(Cabin[!is.na(Cabin)], 1),  # Aynı HomePlanet içindeki dolu Cabin’lerden rastgele seç
      Cabin                             # Cabin doluysa olduğu gibi bırak
   )
) %>% ungroup()

Destination

Aynı grup üyeleri yüksek ihtimalle aynı yere gidiyorlardır

train <- train %>% group_by(uye_s) %>%          
  mutate(Destination = ifelse(is.na(Destination) & uye_s > 1, 
                      first(na.omit(Destination)),  
                      Destination),
         ) %>% ungroup() 

Diğer kalan boşlukları ise yola çıktığı gezegene dayanarak doldurabiliriz

train <- train %>% group_by(HomePlanet) %>% mutate(
   Destination = ifelse(
     is.na(Destination),                     
      sample(Destination[!is.na(Destination)], 1),  
      Destination                             
   )
) %>%
  ungroup()

Age

Ortalama yaş

mean(train$Age,na.rm = T)
[1] 28.82793
# train <- train %>% mutate(
#   Age = ifelse(
#     is.na(Age),
#     mean(train$Age,na.rm = T),
#     Age
#   )
# )

Aynı grup üyelerinin yaş ortlamaları bir birine yakın olabilir.Buna dayanarak boşluklar doldurulabilir.

train <- train %>%
  group_by(Aile) %>%
  mutate(
    Age = ifelse(
      is.na(Age), 
      round(mean(Age, na.rm = TRUE)),  # Ortalama ile doldur
      Age
    )
  ) %>%
  ungroup()

Hangi gezegenden yola çıktığına dayanarak yaş ortalamarı oluşturarak boş olan değerleri doldurabiliriz

train <- train %>%
  group_by(HomePlanet, Destination) %>%  # isteğe bağlı grup sütunları
  mutate(Age = ifelse(uye_s == 1 & is.na(Age), median(Age, na.rm = TRUE), Age)) %>%
  ungroup()

VIP

Aynı grup üyeleri aynı Cabin’de kaldığına göre bu Cabin VIP ise diğer üyelerde VIP’te kalıyordırlar.

train <- train %>% group_by(uye_s) %>%          # aynı gruptaki üyeleri birlikte ele al
  mutate(VIP = ifelse(is.na(VIP) & uye_s > 1, 
                      first(na.omit(VIP)),      # gruptaki boş olmayan ilk değeri al
                      VIP),
         ) 

VIP olup olmadığı hangi gezegenden çıktığına görede değişiklik gösterebilir.

train <- train %>% group_by(HomePlanet) %>% mutate(
   VIP = ifelse(
     is.na(VIP),                    
      sample(VIP[!is.na(VIP)], 1),  
      VIP                             
   )
) %>%
  ungroup()

Room Service, FoodCourt, Shopping Mall, Spa, VRDeck

##RoomService
library(ggplot2)

ggplot(train,aes(RoomService)) + 
  geom_histogram()
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
Warning: Removed 181 rows containing non-finite outside the scale range
(`stat_bin()`).

Servisleri kullanmak belli bir yaş gerektirebilir.Servirleri kullananlar muhtemelen uyumuyorladir.

train <- train %>%
  mutate(
    across(
      c(RoomService, FoodCourt, ShoppingMall, Spa, VRDeck),
      ~ ifelse((Age <= 12 | CryoSleep == TRUE) & is.na(.x), 0, .x)
    )
  )

Tek kişilik gruplar için ortlama değeri kullanabiliriz

train <- train %>%
  group_by(HomePlanet, Destination) %>%
  mutate(
    RoomService = ifelse(uye_s == 1 & is.na(RoomService), mean(RoomService, na.rm = TRUE), RoomService),
    FoodCourt   = ifelse(uye_s == 1 & is.na(FoodCourt), mean(FoodCourt, na.rm = TRUE), FoodCourt),
    ShoppingMall= ifelse(uye_s == 1 & is.na(ShoppingMall), mean(ShoppingMall, na.rm = TRUE), ShoppingMall),
    Spa         = ifelse(uye_s == 1 & is.na(Spa), mean(Spa, na.rm = TRUE), Spa),
    VRDeck      = ifelse(uye_s == 1 & is.na(VRDeck), mean(VRDeck, na.rm = TRUE), VRDeck)
  ) %>%
  ungroup()

Diğer boşluklarıda en çok tekrarlanan değer yani 0 değeriyle doldurucaz.

train <- train %>%
  mutate(
    RoomService  = ifelse(is.na(RoomService), 0, RoomService),
    FoodCourt    = ifelse(is.na(FoodCourt), 0, FoodCourt),
    ShoppingMall = ifelse(is.na(ShoppingMall), 0, ShoppingMall),
    Spa          = ifelse(is.na(Spa), 0, Spa),
    VRDeck       = ifelse(is.na(VRDeck), 0, VRDeck)
  )

Name

Name veri sütününde 20 tane tekrarlanan Ad-Soyad vardir.Bunları boşlukları doldurma için kullanabiliriz

names_pool <- unique(train$Name[!is.na(train$Name)])


train <- train %>%
  mutate(Name = ifelse(is.na(Name),
                       sample(names_pool, sum(is.na(Name)), replace = TRUE),
                       Name))

Yaptığımız değiştirmeler sonucunda her bir sütündeki boşluklar dolduruldu

uye_s,bos_sayisi,bosolamyan_sayisi,farkli_gezegen,gezegen_adi gibi değişkenler veri setinden silinecektir.O yüzden onları sıfır yapmayla uğraşmaya gerek yoktur,çünkü asıl lazım olan HomePlanet zaten doldurulmuştur.

train %>% is.na() %>% colSums()
      PassengerId              Aile            KisiNo        HomePlanet 
                0                 0                 0                 0 
        CryoSleep             Cabin       Destination               Age 
                0                 0                 0                 0 
              VIP       RoomService         FoodCourt      ShoppingMall 
                0                 0                 0                 0 
              Spa            VRDeck              Name       Transported 
                0                 0                 0                 0 
            uye_s        bos_sayisi bosolamyan_sayisi    farkli_gezegen 
              111               111               111               111 
      gezegen_adi 
              111 

Transported

Transported için bir Regresyon modeli oluştururuz

Öncelikle veri setinde oluşturduğumuz fazla değerleri ve Regreson modelimizde gerek olmayacak değerleri çikartırız.

train2 <- train %>% select( -Aile, -KisiNo, -Name, -uye_s, -gezegen_adi, -bos_sayisi, -bosolamyan_sayisi, -farkli_gezegen)


describe_all(train2)
# A tibble: 13 × 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 HomePlanet   chr       0      0      3    NA  NA       NA
 3 CryoSleep    lgl       0      0      2     0   0.36     1
 4 Cabin        chr       0      0   6560    NA  NA       NA
 5 Destination  chr       0      0      3    NA  NA       NA
 6 Age          dbl       0      0     80     0  28.8     79
 7 VIP          lgl       0      0      2     0   0.03     1
 8 RoomService  dbl       0      0   1280     0 222.   14327
 9 FoodCourt    dbl       0      0   1515     0 451.   29813
10 ShoppingMall dbl       0      0   1122     0 171.   23492
11 Spa          dbl       0      0   1333     0 306.   22408
12 VRDeck       dbl       0      0   1313     0 300.   24133
13 Transported  lgl       0      0      2     0   0.5      1

Regresyon modelimizi ve tahminimizi bir deneme üzerinde yapacağız

Train veri setini %75 ve %25 oranlarıyla ikiye bölüyoruz.Ve %75 veri setimizi kalan %25 tahmini için kullanırız.

set.seed(123)  # Sonuçların tekrar üretilebilir olması için

# Satır sayısı
n <- nrow(train2)

# 0.75 ve 0.25 oranında rastgele satır seçimi
train2_index <- sample(1:n, size = 0.75 * n)

# Sonuçları kontrol
length(train2_index)  # ~75
[1] 6519
train2_train <- train2[train2_index, ]
train2_test  <- train2[-train2_index, ]

nrow(train2_train)  # 75% satır
[1] 6519
rec <- recipe(Transported ~ . , data = train2_train) %>%
       step_other(all_nominal(), threshold = 0.01)  

rec_prep <- prep(rec, training = train2_train)

# Train ve Test setlerini dönüştür
train_transformed <- bake(rec_prep, new_data = train2_train)
test_transformed  <- bake(rec_prep, new_data = train2_test)

Basit Regresyon modeli

lm_model <- lm(Transported ~ . - PassengerId, train_transformed)
summary(lm_model)

Call:
lm(formula = Transported ~ . - PassengerId, data = train_transformed)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.31976 -0.30561  0.00262  0.28992  1.66112 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)               4.919e-01  8.349e-02   5.892 4.00e-09 ***
HomePlanetEuropa          2.501e-01  1.511e-02  16.552  < 2e-16 ***
HomePlanetMars            1.064e-01  1.392e-02   7.646 2.38e-14 ***
CryoSleepTRUE             3.762e-01  1.244e-02  30.253  < 2e-16 ***
Cabinother               -6.471e-02  8.208e-02  -0.788   0.4305    
DestinationPSO J318.5-22 -4.342e-02  2.104e-02  -2.064   0.0391 *  
DestinationTRAPPIST-1e   -5.557e-02  1.299e-02  -4.277 1.92e-05 ***
Age                      -2.081e-03  3.652e-04  -5.698 1.27e-08 ***
VIPTRUE                  -5.526e-02  3.170e-02  -1.743   0.0813 .  
RoomService              -1.165e-04  8.367e-06 -13.920  < 2e-16 ***
FoodCourt                 4.253e-05  3.543e-06  12.005  < 2e-16 ***
ShoppingMall              7.436e-05  8.356e-06   8.899  < 2e-16 ***
Spa                      -8.109e-05  4.665e-06 -17.382  < 2e-16 ***
VRDeck                   -8.170e-05  4.848e-06 -16.854  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.4084 on 6505 degrees of freedom
Multiple R-squared:  0.3341,    Adjusted R-squared:  0.3328 
F-statistic: 251.1 on 13 and 6505 DF,  p-value: < 2.2e-16

Genel Regresyon modeli

glm_model <- glm(Transported ~ ., 
                 data = train_transformed, 
                 family = binomial)
Warning: glm.fit: возникли подогнанные вероятности 0 или 1
summary(glm_model)

Call:
glm(formula = Transported ~ ., family = binomial, data = train_transformed)

Coefficients:
                           Estimate Std. Error z value Pr(>|z|)    
(Intercept)              -1.258e+01  1.970e+02  -0.064  0.94908    
PassengerIdother          1.318e+01  1.970e+02   0.067  0.94666    
HomePlanetEuropa          2.113e+00  1.302e-01  16.230  < 2e-16 ***
HomePlanetMars            6.677e-01  8.573e-02   7.788 6.79e-15 ***
CryoSleepTRUE             1.182e+00  8.196e-02  14.415  < 2e-16 ***
Cabinother               -3.441e-01  4.694e-01  -0.733  0.46352    
DestinationPSO J318.5-22 -3.839e-01  1.262e-01  -3.043  0.00234 ** 
DestinationTRAPPIST-1e   -4.596e-01  8.804e-02  -5.220 1.79e-07 ***
Age                      -7.593e-03  2.283e-03  -3.326  0.00088 ***
VIPTRUE                  -4.333e-01  2.413e-01  -1.795  0.07259 .  
RoomService              -1.448e-03  1.029e-04 -14.066  < 2e-16 ***
FoodCourt                 4.970e-04  4.186e-05  11.872  < 2e-16 ***
ShoppingMall              5.209e-04  7.396e-05   7.044 1.87e-12 ***
Spa                      -1.944e-03  1.197e-04 -16.248  < 2e-16 ***
VRDeck                   -1.857e-03  1.131e-04 -16.419  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 9037.3  on 6518  degrees of freedom
Residual deviance: 5885.4  on 6504  degrees of freedom
AIC: 5915.4

Number of Fisher Scoring iterations: 10

Görüldüğü üzere tahminimiz %78,47 civarında bir doğru tahmin oranı verdi

# Tahmin (probability)
train2_test$beta_pred <- predict(glm_model, newdata = test_transformed)


# 0.5 eşik ile TRUE/FALSE tahmini
beta_pred_class <- ifelse(train2_test$beta_pred > 0.5, TRUE, FALSE)


# Doğruluk
accuracy <- mean(beta_pred_class == train2_test$Transported)
accuracy_wrong = mean(beta_pred_class != train2_test$Transported)

sum(accuracy_wrong * 100)
[1] 21.34315
sum(accuracy * 100)
[1] 78.65685