🧩 Ödev 2: Simpson Paradoksunu Keşfetmek – Palmer Penguins Örneği

🎯 Ödevin Amacı

Bu ödevin amacı, Simpson Paradoksu keşfetmektir. Bu bağlamda Palmer Penguins veri seti kullanılarak veri hem toplam düzeyde hem de alt gruplar bazında incelenmiş; bu iki analiz düzeyi arasındaki farkın neden oluştuğunu tartışılmıştır.

Veri Setinin İncelenmesi ve Düzenlenmesi

1. paketlerin etkinleştirilmesi

Öncelikle veri setinin yer aldığı paket de dahil olmak üzere tidyverse, broom ve palmerpenguins paketlerini etkinleştirdik.

# paketleri etkinleştirme
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.2
## ✔ 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(palmerpenguins)
## 
## Attaching package: 'palmerpenguins'
## 
## The following objects are masked from 'package:datasets':
## 
##     penguins, penguins_raw
library(broom)
head(penguins)
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 2 more variables: sex <fct>, year <int>

2. veri setinin incelenmesi

Veri setini (data), veri setinin boyutunu (dim) ve eksik verileri (summary) inceledik.

data("penguins")

dim(penguins)
## [1] 344   8
summary(penguins)
##       species          island    bill_length_mm  bill_depth_mm  
##  Adelie   :152   Biscoe   :168   Min.   :32.10   Min.   :13.10  
##  Chinstrap: 68   Dream    :124   1st Qu.:39.23   1st Qu.:15.60  
##  Gentoo   :124   Torgersen: 52   Median :44.45   Median :17.30  
##                                  Mean   :43.92   Mean   :17.15  
##                                  3rd Qu.:48.50   3rd Qu.:18.70  
##                                  Max.   :59.60   Max.   :21.50  
##                                  NA's   :2       NA's   :2      
##  flipper_length_mm  body_mass_g       sex           year     
##  Min.   :172.0     Min.   :2700   female:165   Min.   :2007  
##  1st Qu.:190.0     1st Qu.:3550   male  :168   1st Qu.:2007  
##  Median :197.0     Median :4050   NA's  : 11   Median :2008  
##  Mean   :200.9     Mean   :4202                Mean   :2008  
##  3rd Qu.:213.0     3rd Qu.:4750                3rd Qu.:2009  
##  Max.   :231.0     Max.   :6300                Max.   :2009  
##  NA's   :2         NA's   :2

3. değişken isimlerinin Türkçeleştirilmesi

Değişken isimlerini rename() ile Türkçe yaptık.

penguenler <- penguins %>%
  rename(
    gaga_uzunlugu = bill_length_mm,
    gaga_derinligi = bill_depth_mm,
    yuzgec_uzunlugu = flipper_length_mm,
    vucut_kutlesi = body_mass_g,
    ada = island,
    yıl = year,
    tur = species,
    cinsiyet = sex)

4. eksik verilerin sayılması, eksik verilerin boyutlarına bakılması ve eksik verilerin silinmesi

Her sütundaki eksik gözlem sayısını colSums(is.na(penguenler)) ile bulduk. Gaga uzunluğu, gaga derinliği, yüzgeç uzunluğu ve vücut kütlesinde ikişer gözlem eksikken, cinsiyet sütununda 11 gözlem eksiktir.

#eksik veri sayısının değişken bazında görme
colSums(is.na(penguenler))
##             tur             ada   gaga_uzunlugu  gaga_derinligi yuzgec_uzunlugu 
##               0               0               2               2               2 
##   vucut_kutlesi        cinsiyet             yıl 
##               2              11               0

Silme işlemi öncesinde veri seti 344 gözlem ve 8 değişken içermektedir. na.omit() fonksiyonu kullanılarak eksik gözlemler veri setinden çıkarılmıştır. Bu işlem sonrasında veri seti 333 gözlem ve 8 değişkenden oluşmaktadır.

#eksik verilerden önce
dim(penguenler)
## [1] 344   8
#eksik verileri silme
penguenler_son <- na.omit(penguenler)

#eksik verilerden sonra
dim(penguenler_son)
## [1] 333   8

5. yeni bir değişken oluşturulması (bmi)

penguenler_son <- penguenler_son %>%
  mutate(bmi = vucut_kutlesi / yuzgec_uzunlugu)

6. türlere göre özet tablo oluşturulması

Türlere göre penguenlerin ortalama, standart sapma, minimum ve maksimum bmi değerleri hesaplanmış ve bmi_ozet adlı veri seti olarak görüntülenmiştir.

bmi_ozet <- penguenler_son %>%
  group_by(tur) %>%
  summarise(
    Ortalama = mean(bmi, na.rm = TRUE),
    Standart_Sapma = sd(bmi, na.rm = TRUE),
    Minimum = min(bmi, na.rm = TRUE),
    Maksimum = max(bmi, na.rm = TRUE))

bmi_ozet
## # A tibble: 3 × 5
##   tur       Ortalama Standart_Sapma Minimum Maksimum
##   <fct>        <dbl>          <dbl>   <dbl>    <dbl>
## 1 Adelie        19.5           2.18    15.2     25.3
## 2 Chinstrap     19.0           1.60    14.1     22.9
## 3 Gentoo        23.4           1.88    19.0     28.5

7. kutu grafiği oluşturulması

Türler arasında bmi değerlerinde fark görülmektedir. Özellikle Gentoo türünün ortalaması diğer türlere göre daha yüksektir.

Not: Bu kısımda grafiği görsel olarak düzenlemek için de çeşitli adımlar uygulanabilir.

# boxplot oluşturulması
ggplot(penguenler_son, aes(x = tur, y = bmi, fill = tur)) +
  geom_boxplot() +
  labs(title = "Penguen Türlerine Göre bmi Dağılımı",
       x = "Tür",
       y = "Vucut Kitle İndeksi (bmi)") +
  scale_fill_manual(values = c("Adelie" = "#c6e2ff", 
                             "Chinstrap" = "#ffde66", 
                             "Gentoo" = "#008080")) +
  theme_minimal(base_family = "helvetica") +
  theme(
  axis.title.x = element_text(margin = margin(t = 10)),
  axis.title.y = element_text(margin = margin(r = 10)))

🔍Toplam Düzeyde Analiz

1. toplam düzey scatter plot + regresyon doğrusu

Bu aşamada scatter + lm çizgisi ekledik. geom_point() ile noktaları ekledik. geom_smooth(method=“lm”) doğrusal regresyon çizgisini ve se = TRUE güven aralığını verir. Bu da toplam verideki eğilimi gösterir.

Not: Noktaların saydamlığını (alpha), şeklini (shape), boyutunu (size), yazı tipini ve diğer biçimlendirmeleri ayarladık.

# Scatter + lm fit (toplam veri)
p_total <- ggplot(penguenler_son, aes(x = gaga_uzunlugu, y = gaga_derinligi)) +
  geom_point(alpha = 0.7, shape = 16, size = 1.1) +
  geom_smooth(method = "lm", se = TRUE, linetype = "solid") +
  labs(
    title = "Toplam Düzey: Gaga Uzunluğu vs Gaga Derinliği",
    x = "Gaga Uzunluğu (mm)",
    y = "Gaga Derinliği (mm)"
  ) +
  theme_minimal(base_family = "Helvetica") +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.title.y = element_text(margin = margin(r = 10)))

print(p_total)
## `geom_smooth()` using formula = 'y ~ x'

2. basit doğrusal regresyon

#basit doğrusal model
model_toplam <- lm(gaga_derinligi ~ gaga_uzunlugu, data = penguenler_son)

#model özeti
summary(model_toplam)
## 
## Call:
## lm(formula = gaga_derinligi ~ gaga_uzunlugu, data = penguenler_son)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.1548 -1.4291  0.0122  1.3994  4.5004 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   20.78665    0.85417  24.335  < 2e-16 ***
## gaga_uzunlugu -0.08233    0.01927  -4.273 2.53e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.92 on 331 degrees of freedom
## Multiple R-squared:  0.05227,    Adjusted R-squared:  0.04941 
## F-statistic: 18.26 on 1 and 331 DF,  p-value: 2.528e-05
  • Veri analizinde gaga uzunluğu ile gaga derinliği arasında negatif bir ilişki gözlendi.

  • Doğrusal regresyon modelinin eğimi estimate = -0.08233 ve p-değeri p = 2.53e-05 olarak bulundu; bu anlamlı bir ilişkiyi işaret etmektedir.

  • Modelin R² değeri R² = 0.05227 olup, gaga uzunluğunun gaga derinliği üzerindeki açıklayıcılığı sınırlıdır.

  • Görsel olarak scatter plot ve regresyon doğrusu bu sonucu desteklemektedir.

Bulguların raporlanması:

Doğrusal regresyon analizine göre, gaga uzunluğu ile gaga derinliği arasında negatif ve anlamlı bir ilişki bulunmuştur (β = -0.082, p < .001). Modelin R² değeri .05 olup, gaga uzunluğunun gaga derinliğindeki varyansın yaklaşık %5’ini açıkladığı görülmüştür. Bu sonuç genel olarak daha uzun gagaya sahip penguenlerin daha sığ gagalara eğilimli olduğunu göstermektedir.

🐧 Tür Bazında Analiz

1. tür bazında scatter plot + regresyon

Türleri renklerle ayırıp her tür için ayrı bir regresyon doğrusu çizdik. Bu grafik toplam veriyle karşılaştırıldığında eğimlerin yönü tersine görünmektedir.

ggplot(penguenler_son, aes(x = gaga_uzunlugu, y = gaga_derinligi, color = tur)) +
  geom_point(alpha = 0.7, size = 1.1) +
  geom_smooth(method = "lm", se = FALSE) +  
  labs(
    title = "Tür Bazında Gaga Uzunluğu vs Gaga Derinliği",
    x = "Gaga Uzunluğu (mm)",
    y = "Gaga Derinliği (mm)",
    color = "Tür") +
  scale_color_manual(values = c("Adelie" = "#c6e2ff", 
                             "Chinstrap" = "#ffde66", 
                             "Gentoo" = "#008080")) +
  theme_minimal(base_family = "Helvetica") +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.title.y = element_text(margin = margin(r = 10)))
## `geom_smooth()` using formula = 'y ~ x'

2. tür bazında regresyon modelleri

Her türü filtreleyip ayrı lm modeli kurduk ve sonuçları broom::tidy() ile tablo olarak gösterdik.

#liste oluşturduk ve modelleri kaydettik
turlar <- unique(penguenler_son$tur)
modeller <- list()

for (t in turlar) {
  data_tur <- filter(penguenler_son, tur == t)
  modeller[[t]] <- lm(gaga_derinligi ~ gaga_uzunlugu, data = data_tur)
}

# Modelleri özetledik ve tablo oluşturduk
tur_sonuclari <- lapply(modeller, broom::tidy)
tur_sonuclari
## $Adelie
## # A tibble: 2 × 5
##   term          estimate std.error statistic  p.value
##   <chr>            <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)     11.5      1.37        8.38 4.23e-14
## 2 gaga_uzunlugu    0.177    0.0352      5.02 1.51e- 6
## 
## $Gentoo
## # A tibble: 2 × 5
##   term          estimate std.error statistic  p.value
##   <chr>            <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)      5.12     1.06        4.84 4.02e- 6
## 2 gaga_uzunlugu    0.208    0.0222      9.35 7.34e-16
## 
## $Chinstrap
## # A tibble: 2 × 5
##   term          estimate std.error statistic       p.value
##   <chr>            <dbl>     <dbl>     <dbl>         <dbl>
## 1 (Intercept)      7.57     1.55        4.88 0.00000699   
## 2 gaga_uzunlugu    0.222    0.0317      7.01 0.00000000153

Toplam veri analizinde yön negatif görünürken, alt gruplara ayırınca ilişkilerin pozitif olduğu görülmektedir. Bu sonuç toplam veri düzeyinde gözlenen negatif ilişki ile çelişmektedir. Bu çelişki verinin alt gruplara ayrıldığında ilişki yönünün değişebileceğini gösteren Simpson Paradoksuna örnektir.

Bulguların raporlanması:

Tür bazında yapılan analizlerde, her üç penguen türünde de gaga uzunluğu ile gaga derinliği arasında pozitif ve anlamlı bir ilişki gözlenmiştir. Eğim değerleri sırasıyla Adelie (β = 0.177, p < .001), Chinstrap (β = 0.208, p < .001) ve Gentoo (β = 0.222, p < .001) olarak bulunmuştur. Bu sonuç toplam veri düzeyinde gözlenen negatif ilişkiyle çelişmektedir ve verinin alt gruplara ayrıldığında ilişki yönünün değişebileceğini gösteren Simpson Paradoksunu ortaya koymaktadır.

🧠 Yorum ve Tartışma

1.Toplam veri setinde neden negatif ilişki gözlemlediniz?

Toplam veri setinde gaga uzunluğu ile gaga derinliği arasında negatif bir eğim çıktı. Bunun nedeni farklı türlerin ortalama gaga uzunluğu ve derinliğinin farklı değerlerde olmasıdır. Örneğin Gentoo penguenleri diğer türlere göre hem daha uzun hem daha derin gagaya sahiptir. Toplam veri analizinde türler karıştığı için türler arası farklar toplam ilişkinin yönünü değiştirmektedir. Diğer bir deyişle toplam veri türler arası farklılıklar nedeniyle yanıltıcı bir ilişki göstermektedir.

2. Tür bilgisi eklendiğinde ilişki neden yön değiştirdi?

Tür bazında incelendiğinde her tür için eğim pozitif çıktı. Bu da daha uzun gagalı penguenlerin tür içinde genellikle daha derin gagaya sahip olduğunu göstermektedir. Türlere göre alt grup analizi yapıldığında türler arası farklar kontrol edilerek gerçeğe yakın bir ilişki ortaya çıkmaktadır. Dolayısıyla toplam veri analizinin gösterdiği yanlış negatif ilişki düzelmektedir.

3. Bu durumu Simpson Paradoksu çerçevesinde nasıl açıklarsınız?

Toplam veri analizinde gözlenen negatif ilişki, aslında istatistik biliminin en ünlü olgularından biri olan Simpson Paradoksu ile açıklanabilir. Simpson Paradoksu, bir ana veri kümesinde iki değişken arasındaki ilişki incelendiğinde elde edilen sonucun, veri kümesi bu ilişkiye etkisi olan bir karıştırıcı değişken kullanılarak alt gruplara ayrıldığında ters yönlü bir sonuç verebileceğini belirtir (Ameringer vd., 2009; Özdemir, 2021). Diğer bir deyişle bir veri kümesinden elde edilen sonuç, aynı veri kümesi alt gruplara ayrıldığında farklı olabilir. Penguen örneğinde, toplam veri setinde gaga uzunluğu ile gaga derinliği arasında negatif bir ilişki gözlenmişken, tür bazında yapılan analizde her üç türde de pozitif ve anlamlı ilişkiler ortaya çıkmıştır. Bu durum alt grup analizinin önemini ve Simpson Paradoksu’nun klasik bir örneğini göstermektedir.

4. Bu örnek, verileri alt gruplara göre incelemenin neden önemli olduğunu nasıl göstermektedir?

Toplam veri analizinde gaga uzunluğu ile gaga derinliği arasında negatif bir ilişki gözlendi; bu, türler arası farklılıkların toplam ilişkide maskelenmesinden kaynaklanmaktadır. Tür bazında yapılan analizlerde ise her tür için pozitif ve anlamlı ilişkiler gözlendi. Bu durum verilerin alt gruplara ayrılmasının neden önemli olduğunu göstermektedir. Alt grup analizi, toplam veri analizinin verebileceği yanıltıcı sonuçları düzeltmekte ve gerçek ilişkileri ortaya çıkarmaktadır.

Kaynaklar

Ameringer, S., Serlin, R. C., & Ward, S. (2009). Simpson’s paradox and experimental research. Nursing Research, 58(2), 123–127. https://doi.org/10.1097/NNR.0b013e318199b517

Özdemir, O. (2021). Covid-19 aşıları ve Simpson Paradoksu. Sarkaç. https://sarkac.org/2021/09/covid-19-asilari-ve-simpson-paradoksu/amp/

👩🏻‍💻 R Markdown Günlüğü

  • R Markdown’da yaptığım her adımı açıklamak için # kullanarak yorumlar eklemeyi öğrendim. Aynı zamanda başlıklandırma için de bu sembolü kullandım. #, ##, ### biçiminde başlık düzeylerini oluşturdum.

  • Uzun bir rapor oluşturduğumda gezinmeyi kolaylaştırmak için YAML header’da

#output:

   #html_document:

      #toc: true

      #toc_float: true

şeklinde içindekiler tablosu oluşturmayı öğrendim.

  • toc: true ve toc_float: true aynı hizada olmadığında hata veriyor.

  • Veri setinden eksik verileri çıkarmak için na.omit(), değişken adlarını Türkçeleştirmek için rename(), türlere göre özet almak için group_by() ve summarise() fonksiyonlarını kullandım.

  • ggplot2 ile scatter plot, regresyon doğrusu ve kutu grafikleri çizdim, renkleri ve yazı tiplerini özelleştirmeyi öğrendim.

  • Doğrusal regresyon modelleri (lm()) ile hem toplam veri hem de tür bazında eğim, p-değeri ve R² değerlerini hesaplayarak ilişkileri yorumladım. Böylece hem veriyi görselleştirme hem de istatistiksel modelleme süreçlerini birleştirmeyi öğrenmiş oldum.

  • Formüller yazmayı ve Latex format kullanarak formül yazmayı öğrendim. Örnek verecek olursam:

  • Tek satır formül için

# $y = 3 + 0.5x$
  • Alt satırda, blok hâlinde göstermek için: [] kullanılır.
#\\overline{x}
#sd\_{\overline{x}}
# cor\_{xy}

yukarıdaki formüller sırayla x’in ortalamasını, x’in standart sapmasını, x ve y arasındaki korelasyonu göstermektedir.

#evrensel çekim yasası

\(F = G \frac{m_1 m_2}{r^2}\)

#enerji-kütle eşdeğerliği

\[ E = mc^2 \]