Tenggelamnya kapal RMS Titanic pada 15 April 1912 adalah salah satu tragedi maritim paling terkenal dalam sejarah. Kapal yang sedang melakukan pelayaran perdananya dari Southampton menuju New York tersebut menabrak gunung es di Samudra Atlantik Utara pada malam 14 April 1912 dan tenggelam beberapa jam kemudian. Dari ribuan orang yang berada di kapal, diperkirakan lebih dari 1.500 jiwa meninggal dunia.
Peristiwa tersebut tidak hanya menjadi bagian penting dalam sejarah pelayaran, tetapi juga meninggalkan catatan mengenai para penumpang yang berada di dalam kapal. Catatan tersebut kemudian dikumpulkan menjadi data yang dapat digunakan untuk melihat karakteristik penumpang, seperti jenis kelamin, umur, dan kelas tiket, serta mengetahui pola yang berkaitan dengan peluang seseorang untuk selamat. Salah satu bentuk data tersebut adalah Titanic Dataset yang tersedia di Kaggle dan digunakan dalam laporan ini.
Dataset Titanic merupakan dataset yang berisi informasi mengenai penumpang kapal Titanic. Data mencatat berbagai karakteristik penumpang, seperti nama, jenis kelamin, umur, kelas tiket, jumlah saudara atau pasangan yang ikut dalam perjalanan, jumlah orang tua atau anak, harga tiket, kabin, pelabuhan keberangkatan, serta status keselamatan penumpang. Dataset yang digunakan dalam analisis ini diambil dari Kaggle dan terdiri atas 891 observasi dengan 12 variabel. Setiap baris merepresentasikan seorang penumpang, sedangkan setiap kolom menunjukkan karakteristik tertentu dari penumpang tersebut.
Sebelum data dianalisis lebih jauh atau dipakai untuk membangun model prediksi, data perlu dipahami terlebih dahulu. Pendekatan ini disebut analisis data eksploratif (Exploratory Data Analysis/EDA), yaitu serangkaian langkah untuk mengenali struktur data, memeriksa kualitas data, melihat bentuk sebaran, dan menemukan pola awal melalui ringkasan statistik dan visualisasi (Tukey, 1977). Tanpa EDA, analisis berisiko menghasilkan kesimpulan yang keliru, misalnya karena data kosong tidak ditangani, nilai ekstrem tidak dikenali, atau asumsi statistik seperti kenormalan dan kesamaan varians tidak diperiksa.
Dataset yang digunakan bernama Titanic Dataset, diunduh dari Kaggle (Elyamadad, n.d.). Data disimpan dalam bentuk tabel berformat CSV (structured data) yang terdiri atas 891 observasi dan 12 variabel. Satu baris mewakili satu penumpang.
library(knitr)
variabel <- data.frame(
Variabel = c("PassengerId", "Survived", "Pclass", "Name", "Sex", "Age",
"SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"),
Keterangan = c("ID penumpang", "Status keselamatan", "Kelas tiket", "Nama penumpang",
"Jenis kelamin", "Umur", "Jumlah saudara/pasangan", "Jumlah orang tua/anak",
"Nomor tiket", "Harga tiket", "Kode kabin", "Pelabuhan keberangkatan"),
Jenis = c("Kualitatif", "Kualitatif", "Kualitatif", "Kualitatif", "Kualitatif",
"Kuantitatif kontinu", "Kuantitatif diskrit", "Kuantitatif diskrit",
"Kualitatif", "Kuantitatif kontinu", "Kualitatif", "Kualitatif"),
Skala = c("Nominal", "Nominal", "Ordinal", "Nominal", "Nominal", "Rasio",
"Rasio", "Rasio", "Nominal", "Rasio", "Nominal", "Nominal")
)
knitr::kable(variabel,caption = "Tabel 1. Penjelasan VAriabel")
| Variabel | Keterangan | Jenis | Skala |
|---|---|---|---|
| PassengerId | ID penumpang | Kualitatif | Nominal |
| Survived | Status keselamatan | Kualitatif | Nominal |
| Pclass | Kelas tiket | Kualitatif | Ordinal |
| Name | Nama penumpang | Kualitatif | Nominal |
| Sex | Jenis kelamin | Kualitatif | Nominal |
| Age | Umur | Kuantitatif kontinu | Rasio |
| SibSp | Jumlah saudara/pasangan | Kuantitatif diskrit | Rasio |
| Parch | Jumlah orang tua/anak | Kuantitatif diskrit | Rasio |
| Ticket | Nomor tiket | Kualitatif | Nominal |
| Fare | Harga tiket | Kuantitatif kontinu | Rasio |
| Cabin | Kode kabin | Kualitatif | Nominal |
| Embarked | Pelabuhan keberangkatan | Kualitatif | Nominal |
Tipe dan skala pengukuran menentukan teknik analisis yang tepat untuk setiap variabel. Variabel kualitatif tidak dapat dihitung rata-ratanya, sedangkan variabel kuantitatif dapat diringkas dengan ukuran pemusatan dan penyebaran
library(readxl)
data <- read_excel("C:\\Users\\LENOVO\\Downloads\\data set titanicc_2.xlsx")
dim(data)
## [1] 891 12
str(data)
## tibble [891 × 12] (S3: tbl_df/tbl/data.frame)
## $ PassengerId: num [1:891] 1 2 3 4 5 6 7 8 9 10 ...
## $ Survived : num [1:891] 0 1 1 1 0 0 0 0 1 1 ...
## $ Pclass : num [1:891] 3 1 3 1 3 3 1 3 3 2 ...
## $ Name : chr [1:891] "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
## $ Sex : chr [1:891] "male" "female" "female" "female" ...
## $ Age : num [1:891] 22 38 26 35 35 NA 54 2 27 14 ...
## $ SibSp : num [1:891] 1 1 0 1 0 0 0 3 0 1 ...
## $ Parch : num [1:891] 0 0 0 0 0 0 0 1 2 0 ...
## $ Ticket : chr [1:891] "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
## $ Fare : num [1:891] 725 712833 7925 531 805 ...
## $ Cabin : chr [1:891] NA "C85" NA "C123" ...
## $ Embarked : chr [1:891] "S" "C" "S" "S" ...
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
colSums(is.na(data))
## PassengerId Survived Pclass Name Sex Age
## 0 0 0 0 0 177
## SibSp Parch Ticket Fare Cabin Embarked
## 0 0 0 0 687 2
summary(data$Fare)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0 161 2625 127661 78958 5123292
Q1 <- quantile(data$Fare, 0.25, na.rm = TRUE)
Q3 <- quantile(data$Fare, 0.75, na.rm = TRUE)
IQR_Fare <- Q3 - Q1
batas_bawah <- Q1 - 1.5 * IQR_Fare
batas_atas <- Q3 + 1.5 * IQR_Fare
outlier_fare <- data[
data$Fare < batas_bawah | data$Fare > batas_atas,
]
outlier_fare[, c("PassengerId", "Fare")]
## # A tibble: 122 × 2
## PassengerId Fare
## <dbl> <dbl>
## 1 2 712833
## 2 7 518625
## 3 10 300708
## 4 26 313875
## 5 31 277208
## 6 32 1465208
## 7 35 821708
## 8 44 415792
## 9 49 216792
## 10 51 396875
## # ℹ 112 more rows
sum(grepl("[A-Za-z]", data$Ticket))
## [1] 230
sum(grepl(" ", data$Ticket))
## [1] 226
Variabel Ticket memiliki variasi format. Sebanyak 230 data mengandung huruf dan 226 data mengandung spasi. Hal ini menunjukkan adanya keragaman dalam format penulisan Ticket.
masalah <- data.frame(
Jenis = c("Missing value", "Missing value", "Missing value", "Outlier", "Inkonsistensi"),
Variabel = c("Age", "Cabin", "Embarked", "Fare", "Ticket"),
Keterangan = c("177 data kosong",
"687 data kosong",
"2 data kosong (baris 63 dan 831)",
"Baris 259, 680, dan 738 bernilai sama, yaitu 512,3292",
"Penulisan tidak konsisten (campuran huruf, angka, dan spasi)")
)
knitr::kable(masalah,caption = "Tabel 2. Identifikasi Permasalahan")
| Jenis | Variabel | Keterangan |
|---|---|---|
| Missing value | Age | 177 data kosong |
| Missing value | Cabin | 687 data kosong |
| Missing value | Embarked | 2 data kosong (baris 63 dan 831) |
| Outlier | Fare | Baris 259, 680, dan 738 bernilai sama, yaitu 512,3292 |
| Inkonsistensi | Ticket | Penulisan tidak konsisten (campuran huruf, angka, dan spasi) |
w5h1 <- data.frame(
Pertanyaan = c("Dari mana data diperoleh?", "Siapa yang mengumpulkan?", "Mengapa data dikumpulkan?",
"Kapan data dikumpulkan?", "Dalam bentuk apa data disimpan?", "Bagaimana data disusun?",
"Apa yang direpresentasikan dalam satu baris?", "Hubungan data dengan sumber lain",
"Apakah tersedia metadata/data dictionary?", "Riwayat data hingga menjadi dataset yang digunakan"),
Jawaban = c(
"Kaggle.",
"Anonim; tidak diketahui berdasarkan informasi yang tersedia pada dataset.",
"Untuk memprediksi penumpang yang selamat dari bencana dengan menganalisis faktor seperti usia, jenis kelamin, kelas, dan tiket.",
"Peristiwa yang dicatat adalah tenggelamnya Titanic pada 15 April 1912. Data penumpang dikumpulkan melalui komite investigasi setelah kecelakaan; dataset yang diunggah ke Kaggle tidak mencantumkan tanggal tepatnya.",
"Tabel/CSV (structured data).",
"Setiap baris mewakili seorang penumpang, sedangkan kolom berisi variabel karakteristik penumpang (PassengerId, Survived, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, dan Embarked).",
"Karakteristik masing-masing penumpang. Dataset berisi 891 observasi/baris.",
"Titanic: Triumph and Tragedy karya Eaton & Haas (1994).",
"Ya, tersedia.",
"Data berasal dari berbagai sumber sejarah dan penelitian, kemudian diperbaiki serta dilengkapi menggunakan Encyclopedia Titanica. Data ini selanjutnya digunakan untuk analisis statistik dan machine learning, termasuk pada dataset Titanic di Kaggle."
)
)
knitr::kable(w5h1,caption = "Tabel 3. Identifikasi 5W1H")
| Pertanyaan | Jawaban |
|---|---|
| Dari mana data diperoleh? | Kaggle. |
| Siapa yang mengumpulkan? | Anonim; tidak diketahui berdasarkan informasi yang tersedia pada dataset. |
| Mengapa data dikumpulkan? | Untuk memprediksi penumpang yang selamat dari bencana dengan menganalisis faktor seperti usia, jenis kelamin, kelas, dan tiket. |
| Kapan data dikumpulkan? | Peristiwa yang dicatat adalah tenggelamnya Titanic pada 15 April 1912. Data penumpang dikumpulkan melalui komite investigasi setelah kecelakaan; dataset yang diunggah ke Kaggle tidak mencantumkan tanggal tepatnya. |
| Dalam bentuk apa data disimpan? | Tabel/CSV (structured data). |
| Bagaimana data disusun? | Setiap baris mewakili seorang penumpang, sedangkan kolom berisi variabel karakteristik penumpang (PassengerId, Survived, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, dan Embarked). |
| Apa yang direpresentasikan dalam satu baris? | Karakteristik masing-masing penumpang. Dataset berisi 891 observasi/baris. |
| Hubungan data dengan sumber lain | Titanic: Triumph and Tragedy karya Eaton & Haas (1994). |
| Apakah tersedia metadata/data dictionary? | Ya, tersedia. |
| Riwayat data hingga menjadi dataset yang digunakan | Data berasal dari berbagai sumber sejarah dan penelitian, kemudian diperbaiki serta dilengkapi menggunakan Encyclopedia Titanica. Data ini selanjutnya digunakan untuk analisis statistik dan machine learning, termasuk pada dataset Titanic di Kaggle. |
Tujuan analisis adalah mengeksplorasi dan mengetahui pola hubungan antara jenis kelamin dan umur dengan status keselamatan penumpang. Untuk mencapai tujuan tersebut, disusun lima pertanyaan analisis berikut. Variabel yang di analisis adalah PassengerId,Survived, Sex, Age. Analisis Pertanyaan:
Proses pembersihan data dilakukan melalui lima tahap:
Setelah Cleaning, variabel Age yang terdapat missing value sudah teratasi dan variabel yang digunakan hanya sebanyak 4, yaitu Passanger_Id, Age, Sex, dan Survived.
data_titanic <- read_excel("C:\\Users\\LENOVO\\Documents\\KULIAH\\Semester 3\\project titanic\\data set titanic ensiklopedia sudah cleaning.xlsx")
data_variabel <- data_titanic[, !(names(data_titanic) %in% c("Pclass", "Name", "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"))]
data_variabel
## # A tibble: 891 × 4
## PassengerId Survived Sex Age
## <dbl> <dbl> <chr> <dbl>
## 1 1 0 male 22
## 2 2 1 female 38
## 3 3 1 female 26
## 4 4 1 female 35
## 5 5 0 male 35
## 6 6 0 male 29
## 7 7 0 male 54
## 8 8 0 male 2
## 9 9 1 female 27
## 10 10 1 female 14
## # ℹ 881 more rows
sum(is.na(data_titanic$Age))
## [1] 0
Setelah data di cleaning, karakteristik variabel Age diperiksa melalui statistik deskriptif, bentuk distribusi, normalitas, dan kesamaan varians antarkelompok jenis kelamin. Pemeriksaan ini sesuai dengan prinsip EDA bahwa data diberi ruang untuk “berbicara” sebelum model atau asumsi tertentu diterapkan (Tukey, 1977).
data.frame(
Jumlah_Data = length(data_titanic$Age),
Mean = mean(data_titanic$Age),
Median = median(data_titanic$Age),
Standar_Deviasi = sd(data_titanic$Age),
Minimum = min(data_titanic$Age),
Maksimum = max(data_titanic$Age)
)
## Jumlah_Data Mean Median Standar_Deviasi Minimum Maksimum
## 1 891 29.60176 28 14.15357 0.42 80
summary(data_titanic$Age)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.42 20.00 28.00 29.60 38.00 80.00
Rata-rata usia penumpang adalah 29,60 tahun dengan median 28 tahun. Nilai mean yang sedikit lebih besar daripada median mengindikasikan adanya kemiringan ke arah usia yang lebih tinggi. Standar deviasi 14,15 tahun menunjukkan variasi usia yang cukup besar. Rentang usia 0,42 hingga 80 tahun menunjukkan bahwa penumpang mencakup bayi (usia kurang dari satu tahun) sampai lanjut usia.
library(ggplot2)
ggplot(data_titanic, aes(x = Age)) +
geom_histogram(bins = 20, fill = "steelblue", color = "white", alpha = 0.9) +
labs(
title = "Distribusi Usia Penumpang",
x = "Usia (Tahun)",
y = "Total Penumpang"
) +
theme_minimal()
Histogram digunakan untuk melihat bentuk distribusi usia secara visual. Dari histogram terlihat bahwa usia penumpang tersebar pada rentang sekitar 0 hingga 80 tahun. Frekuensi penumpang paling banyak berada pada usia sekitar 20–35 tahun, dengan frekuensi tertinggi berada di sekitar usia 20-an. Setelah usia sekitar 35 tahun, frekuensi penumpang cenderung menurun seiring bertambahnya usia.Distribusi juga terlihat memiliki ekor yang memanjang ke arah kanan, karena masih terdapat penumpang dengan usia yang lebih tinggi hingga sekitar 80 tahun. Dengan demikian, distribusi usia penumpang cenderung menceng ke kanan (positively skewed) dan tidak tampak simetris. dipengaruhi oleh imputasi median.
ggplot(data_titanic, aes(x = Age)) +
geom_density() +
labs(
title = "Density Plot Usia Penumpang",
x = "Usia",
y = "Density"
)
Density plot digunakan untuk melihat pola distribusi secara lebih halus. Density plot memperlihatkan pola yang serupa dengan histogram. Kepadatan data mencapai puncak pada usia sekitar 20–25 tahun, kemudian secara bertahap menurun ketika usia bertambah.Kurva tidak membentuk pola lonceng yang simetris. Bagian kanan kurva memiliki ekor yang lebih panjang hingga usia sekitar 80 tahun. Hal ini menunjukkan bahwa distribusi usia tidak sepenuhnya mengikuti pola distribusi normal dan cenderung menceng ke kanan.
ggplot(data_titanic, aes(sample = Age)) +
stat_qq() +
stat_qq_line() +
labs(
title = "Q-Q Plot Usia Penumpang"
)
Q-Q plot digunakan untuk melihat apakah data mendekati distribusi normal. Kalau data berdistribusi normal, titik-titik seharusnya berada di sekitar garis diagonal.Pada grafik kamu, titik-titik tidak mengikuti garis diagonal secara konsisten. Penyimpangan cukup terlihat terutama pada bagian ujung distribusi dan juga pada bagian sekitar usia rendah serta usia tinggi.Jadi, secara visual, Q-Q plot menunjukkan bahwa data usia tidak mengikuti distribusi normal dengan baik.
shapiro.test(data_titanic$Age)
##
## Shapiro-Wilk normality test
##
## data: data_titanic$Age
## W = 0.97916, p-value = 5.666e-10
Selain secara visual, normalitas Age diuji secara formal menggunakan uji Shapiro-Wilk dengan hipotesis berikut.
Berdasarkan uji Shapiro-Wilk diperoleh nilai statistik W sebesar 0,97916 dengan p-value sebesar 5,666 × 10⁻¹⁰. Karena p-value < 0,05, maka H₀ ditolak. Dengan demikian, dapat disimpulkan bahwa variabel Age tidak berdistribusi normal. Hasil pengujian ini konsisten dengan histogram, density plot, dan Q-Q plot yang menunjukkan adanya penyimpangan dari distribusi normal.
Selanjutnya diperiksa apakah penyebaran Age antara kelompok laki-laki dan perempuan relatif sama. Variabel Sex berperan sebagai kelompok, sedangkan Age adalah nilai yang dibandingkan.
data_titanic %>%
group_by(Sex) %>%
summarise(
Jumlah = n(),
Mean_Age = round(mean(Age), 1),
Median = median(Age),
Varians = round(var(Age))
)
## # A tibble: 2 × 5
## Sex Jumlah Mean_Age Median Varians
## <chr> <int> <dbl> <dbl> <dbl>
## 1 female 314 27.9 27 196
## 2 male 577 30.5 28 201
ggplot(data_titanic, aes(x = Sex, y = Age, fill = Sex)) +
geom_boxplot() +
scale_fill_manual(
values = c(
"male" = "skyblue",
"female" = "pink"
)
) +
labs(
title = "Boxplot Usia Berdasarkan Jenis Kelamin",
x = "Jenis Kelamin",
y = "Usia",
fill = "Jenis Kelamin"
)
Berdasarkan boxplot, median usia penumpang laki-laki sedikit lebih tinggi dibandingkan penumpang perempuan. Sebaran usia kedua kelompok relatif serupa, meskipun pada kelompok laki-laki terdapat beberapa pencilan pada usia yang lebih tinggi, yaitu sekitar 70–80 tahun. Secara umum, kedua kelompok menunjukkan penyebaran usia yang relatif berdekatan.
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
car::leveneTest(Age ~ Sex, data = data_variabel)
## Warning in leveneTest.default(y = y, group = group, ...): group coerced to
## factor.
## Levene's Test for Homogeneity of Variance (center = median)
## Df F value Pr(>F)
## group 1 0.2307 0.6311
## 889
Kesamaan varians usia antarkelompok jenis kelamin diuji menggunakan uji Levene. Uji ini dipilih karena lebih tahan terhadap pelanggaran asumsi normalitas, sementara data Age terbukti tidak berdistribusi normal. Hipotesis yang diuji adalah sebagai berikut.
Berdasarkan uji Levene’s Test, diperoleh p_value sebesar 0.6311. Karena p-value>0,05p, maka H₀ tidak ditolak. Artinya, tidak terdapat bukti yang cukup bahwa varians usia laki-laki dan perempuan berbeda secara statistik, sehingga varians dapat dianggap homogen.
tabel_pemeriksaan <- data.frame(
Aspek = c("Normalitas", "Homogenitas"),
Temuan = c(
"Histogram dan density plot menunjukkan bentuk distribusi usia yang tidak sepenuhnya normal. Q-Q plot menunjukkan penyimpangan titik dari garis acuan, terutama pada bagian ujung. Uji Shapiro-Wilk menghasilkan p < 0,05 sehingga Age tidak berdistribusi normal.",
"Boxplot menunjukkan penyebaran usia antara laki-laki dan perempuan relatif mirip. Uji Levene menghasilkan p = 0,6311 > 0,05, sehingga varians Age berdasarkan Sex dapat dianggap homogen."
)
)
knitr::kable(tabel_pemeriksaan,caption = "Tabel 4. Kesimpulan")
| Aspek | Temuan |
|---|---|
| Normalitas | Histogram dan density plot menunjukkan bentuk distribusi usia yang tidak sepenuhnya normal. Q-Q plot menunjukkan penyimpangan titik dari garis acuan, terutama pada bagian ujung. Uji Shapiro-Wilk menghasilkan p < 0,05 sehingga Age tidak berdistribusi normal. |
| Homogenitas | Boxplot menunjukkan penyebaran usia antara laki-laki dan perempuan relatif mirip. Uji Levene menghasilkan p = 0,6311 > 0,05, sehingga varians Age berdasarkan Sex dapat dianggap homogen. |
Integrasi data (data integration) adalah proses menggabungkan data dari beberapa sumber menjadi satu dataset yang utuh. Data karakteristik (Sex dan Age) dan data keselamatan (Survived) diintegrasikan menggunakan PassengerId sebagai key. Proses left_join() menggabungkan informasi Sex dan Age dengan Survived berdasarkan PassengerId yang sama, sehingga diperoleh satu dataset yang memuat karakteristik dan status keselamatan setiap penumpang. Dataset hasil integrasi selanjutnya digunakan untuk analisis.
library(dplyr)
tabel_karakteristik <- data_titanic %>%
select(PassengerId, Sex, Age)
tabel_karakteristik
## # A tibble: 891 × 3
## PassengerId Sex Age
## <dbl> <chr> <dbl>
## 1 1 male 22
## 2 2 female 38
## 3 3 female 26
## 4 4 female 35
## 5 5 male 35
## 6 6 male 29
## 7 7 male 54
## 8 8 male 2
## 9 9 female 27
## 10 10 female 14
## # ℹ 881 more rows
tabel_keselamatan <- data_titanic %>%
select(PassengerId, Survived)
tabel_keselamatan
## # A tibble: 891 × 2
## PassengerId Survived
## <dbl> <dbl>
## 1 1 0
## 2 2 1
## 3 3 1
## 4 4 1
## 5 5 0
## 6 6 0
## 7 7 0
## 8 8 0
## 9 9 1
## 10 10 1
## # ℹ 881 more rows
data_integrasi <- tabel_karakteristik %>%
left_join(tabel_keselamatan, by = "PassengerId")
data_integrasi
## # A tibble: 891 × 4
## PassengerId Sex Age Survived
## <dbl> <chr> <dbl> <dbl>
## 1 1 male 22 0
## 2 2 female 38 1
## 3 3 female 26 1
## 4 4 female 35 1
## 5 5 male 35 0
## 6 6 male 29 0
## 7 7 male 54 0
## 8 8 male 2 0
## 9 9 female 27 1
## 10 10 female 14 1
## # ℹ 881 more rows
nrow(data_integrasi)
## [1] 891
ncol(data_integrasi)
## [1] 4
Transformasi data kategorik mengubah nilai berupa teks menjadi bentuk numerik agar dapat digunakan dalam analisis atau pemodelan.Dari empat variabel dataset hasil integrasi, variabel kategorik yang perlu ditransformasi adalah Sex (skala nominal) dengan dua kategori, yaitu male dan female. Variabel PassengerId merupakan pengenal sehingga tidak ditransformasi, Survived sudah berbentuk kode 0/1, dan Age sudah numerik.
names(data_integrasi)
## [1] "PassengerId" "Sex" "Age" "Survived"
str(data_integrasi)
## tibble [891 × 4] (S3: tbl_df/tbl/data.frame)
## $ PassengerId: num [1:891] 1 2 3 4 5 6 7 8 9 10 ...
## $ Sex : chr [1:891] "male" "female" "female" "female" ...
## $ Age : num [1:891] 22 38 26 35 35 29 54 2 27 14 ...
## $ Survived : num [1:891] 0 1 1 1 0 0 0 0 1 1 ...
library(fastDummies)
library(dplyr)
titanic_onehot <- data_integrasi
titanic_sex <- dummy_cols(
data_integrasi,
select_columns = "Sex",
remove_first_dummy = FALSE,
remove_selected_columns = TRUE
)
tabel_sex <- titanic_sex %>%
select(PassengerId, Sex_male, Sex_female)
head(tabel_sex)
## # A tibble: 6 × 3
## PassengerId Sex_male Sex_female
## <dbl> <int> <int>
## 1 1 1 0
## 2 2 0 1
## 3 3 0 1
## 4 4 0 1
## 5 5 1 0
## 6 6 1 0
Sebelum encoding, variabel Sex berupa kategori male dan female. Setelah encoding, nilainya diubah menjadi angka: 1 = male dan 0 = female, sehingga data lebih mudah digunakan dalam proses analisis atau pemodelan.
One-hot encoding mengubah setiap kategori menjadi kolom indikator bernilai 0 atau 1. Nilai 1 menunjukkan bahwa observasi termasuk kategori tersebut, sedangkan 0 menunjukkan sebaliknya. Pada kondisi awal, variabel Sex masih berbentuk kategori teks (male dan female).
library(fastDummies)
library(dplyr)
titanic_onehot <- data_integrasi
titanic_sex <- dummy_cols(
data_integrasi,
select_columns = "Sex",
remove_first_dummy = FALSE,
remove_selected_columns = TRUE
)
tabel_sex <- titanic_sex %>%
select(PassengerId, Sex_male, Sex_female)
head(tabel_sex)
## # A tibble: 6 × 3
## PassengerId Sex_male Sex_female
## <dbl> <int> <int>
## 1 1 1 0
## 2 2 0 1
## 3 3 0 1
## 4 4 0 1
## 5 5 1 0
## 6 6 1 0
Setiap kategori Sex kini menjadi kolom indikator (0/1). Penumpang 1 bernilai Sex_male = 1 dan Sex_female = 0 sehingga ia laki-laki, sedangkan penumpang 2 bernilai Sex_male = 0 dan Sex_female = 1 sehingga ia perempuan. Berbeda dengan label encoding, pendekatan ini tidak menimbulkan urutan buatan antarkategori.
Transformasi data numerik mengubah skala atau bentuk sebaran variabel kuantitatif. Variabel yang ditransformasi adalah Age, yang memiliki rentang nilai luas. Setiap transformasi mengubah skala data, tetapi urutan nilai tetap dipertahankan.
library(dplyr)
statistik_awal <- data_integrasi %>%
summarise(
Min_Age = min(Age, na.rm = TRUE),
Max_Age = max(Age, na.rm = TRUE),
Mean_Age = mean(Age, na.rm = TRUE),
SD_Age = sd(Age, na.rm = TRUE)
)
statistik_awal
## # A tibble: 1 × 4
## Min_Age Max_Age Mean_Age SD_Age
## <dbl> <dbl> <dbl> <dbl>
## 1 0.42 80 29.6 14.2
Usia penumpang berkisar 0,42–80 tahun dengan rata-rata 29,60 tahun. Standar deviasi sebesar 14,2 menunjukkan variasi usia yang cukup besar. Karena Age memiliki rentang yang luas, transformasi numerik dapat dilakukan.
Normalisasi min-max mengubah nilai ke rentang 0–1 dengan rumus berikut.\[ Age_{MinMax} = \frac{Age - \min(Age)} {\max(Age) - \min(Age)} \]
min_max <- function(x) {
(x - min(x, na.rm = TRUE)) /
(max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
}
data_transformasi <- data_integrasi %>%
mutate(
Age_MinMax = min_max(Age)
)
head(
data_transformasi %>%
select(PassengerId, Age, Age_MinMax)
)
## # A tibble: 6 × 3
## PassengerId Age Age_MinMax
## <dbl> <dbl> <dbl>
## 1 1 22 0.271
## 2 2 38 0.472
## 3 3 26 0.321
## 4 4 35 0.435
## 5 5 35 0.435
## 6 6 29 0.359
data_transformasi %>%
summarise(
Min = min(Age_MinMax, na.rm = TRUE),
Max = max(Age_MinMax, na.rm = TRUE),
Mean = mean(Age_MinMax, na.rm = TRUE),
SD = sd(Age_MinMax, na.rm = TRUE)
)
## # A tibble: 1 × 4
## Min Max Mean SD
## <dbl> <dbl> <dbl> <dbl>
## 1 0 1 0.367 0.178
Nilai Age berhasil dinormalisasi ke rentang 0–1: nilai minimum menjadi 0 dan maksimum menjadi 1. Usia 22 tahun menjadi 0,271 dan usia 38 tahun menjadi 0,472. Rata-rata hasil transformasi 0,367 dan standar deviasinya 0,178. Min-max mengubah skala data, tetapi urutan nilai tetap dipertahankan.
Standardisasi z-score mengubah nilai menjadi selisihnya terhadap rata-rata dalam satuan standar deviasi. \[Age_{Z}=\frac{\left(Age-mean\left(Age\right)\right)}{sd\left(Age\right)}\]
data_transformasi <- data_transformasi %>%
mutate(
Age_Z = as.numeric(
scale(Age)
)
)
head(
data_transformasi %>%
select(PassengerId, Age, Age_Z)
)
## # A tibble: 6 × 3
## PassengerId Age Age_Z
## <dbl> <dbl> <dbl>
## 1 1 22 -0.537
## 2 2 38 0.593
## 3 3 26 -0.254
## 4 4 35 0.381
## 5 5 35 0.381
## 6 6 29 -0.0425
data_transformasi %>%
summarise(
Mean_Z = mean(Age_Z, na.rm = TRUE),
SD_Z = sd(Age_Z, na.rm = TRUE)
)
## # A tibble: 1 × 2
## Mean_Z SD_Z
## <dbl> <dbl>
## 1 -1.10e-16 1
Rata-rata z-score mendekati 0 (−1,10 × 10⁻¹⁶, yaitu nol secara praktis) dan standar deviasinya 1. Z-score menunjukkan posisi relatif usia terhadap rata-rata: nilai positif berarti usia di atas rata-rata (misalnya 38 tahun menjadi 0,593) dan nilai negatif berarti di bawah rata-rata (misalnya 22 tahun menjadi −0,537). Z-score bukan skala usia baru, melainkan ukuran jarak dari rata-rata.
Transformasi invers (1/x) memperbesar nilai kecil dan memperkecil nilai besar, tetapi tidak dapat dihitung pada nilai 0 dan menghasilkan nilai yang sangat besar untuk nilai yang sangat dekat dengan 0. Karena itu, sebelum transformasi invers diterapkan, dilakukan pemeriksaan keamanan fungsi invers.
data_transformasi %>%
summarise(
min_val = min(Age, na.rm = TRUE),
jumlah_nol = sum(Age == 0, na.rm = TRUE)
)
## # A tibble: 1 × 2
## min_val jumlah_nol
## <dbl> <int>
## 1 0.42 0
Nilai minimum Age adalah 0,42 dan tidak terdapat nilai Age = 0,
sehingga transformasi invers dapat dilakukan. Namun, nilai yang sangat
dekat dengan 0 tetap dapat menghasilkan nilai invers yang sangat besar.
Pada data ini, usia 0,42 tahun menghasilkan 1/0,42² ≈ 5,67.
## 7.5 Invers Square
data_transformasi <- data_transformasi %>%
mutate(
Age_Inv_Sq = 1 / (Age^2)
)
head(
data_transformasi %>%
select(
PassengerId,
Age,
Age_Inv_Sq
)
)
## # A tibble: 6 × 3
## PassengerId Age Age_Inv_Sq
## <dbl> <dbl> <dbl>
## 1 1 22 0.00207
## 2 2 38 0.000693
## 3 3 26 0.00148
## 4 4 35 0.000816
## 5 5 35 0.000816
## 6 6 29 0.00119
data_transformasi %>%
summarise(
Min = min(Age_Inv_Sq, na.rm = TRUE),
Max = max(Age_Inv_Sq, na.rm = TRUE),
Mean = mean(Age_Inv_Sq, na.rm = TRUE),
SD = sd(Age_Inv_Sq, na.rm = TRUE)
)
## # A tibble: 1 × 4
## Min Max Mean SD
## <dbl> <dbl> <dbl> <dbl>
## 1 0.000156 5.67 0.0321 0.251
Hasil transformasi inverse square pada variabel Age menunjukkan nilai minimum 0,000156, maksimum 5,67, rata-rata 0,0321, dan standar deviasi 0,251. Transformasi ini membuat nilai Age yang lebih besar menghasilkan nilai transformasi yang semakin kecil (urutan terbalik). Nilai maksimum 5,67 berasal dari usia 0,42 tahun, sehingga satu-dua bayi dapat mendominasi sebaran hasil transformasi.
data_transformasi <- data_transformasi %>%
mutate(
Age_Inv_Cubic = 1 / (Age^3)
)
head(
data_transformasi %>%
select(
PassengerId,
Age,
Age_Inv_Cubic
)
)
## # A tibble: 6 × 3
## PassengerId Age Age_Inv_Cubic
## <dbl> <dbl> <dbl>
## 1 1 22 0.0000939
## 2 2 38 0.0000182
## 3 3 26 0.0000569
## 4 4 35 0.0000233
## 5 5 35 0.0000233
## 6 6 29 0.0000410
Nilai umur diubah menjadi bentuk invers kubik, sehingga semakin besar umur penumpang, semakin kecil nilai Age_Inv_Cubic. Contohnya, umur 22 menghasilkan 0,0000939, sedangkan umur 38 menghasilkan 0,0000182.
library(ggplot2)
ggplot(data_transformasi, aes(x = Age)) +
geom_histogram(
bins = 20,
fill = "steelblue",
color = "white"
) +
labs(
title = "Distribusi Age Sebelum Transformasi",
x = "Age",
y = "Frekuensi"
) +
theme_minimal()
Sebelum dilakukan transformasi, distribusi Age menunjukkan konsentrasi pengamatan pada usia sekitar 20–35 tahun dan memiliki ekor yang memanjang ke arah kanan. Kondisi ini menunjukkan bahwa data Age cenderung menceng ke kanan dan tidak berbentuk simetris.
tabel_perbandingan <- data_transformasi %>%
summarise(
# Data asli
Age_Min = min(Age, na.rm = TRUE),
Age_Max = max(Age, na.rm = TRUE),
Age_Mean = mean(Age, na.rm = TRUE),
Age_SD = sd(Age, na.rm = TRUE),
# Min-Max
MinMax_Min = min(Age_MinMax, na.rm = TRUE),
MinMax_Max = max(Age_MinMax, na.rm = TRUE),
MinMax_Mean = mean(Age_MinMax, na.rm = TRUE),
MinMax_SD = sd(Age_MinMax, na.rm = TRUE),
# Z-Score
Z_Min = min(Age_Z, na.rm = TRUE),
Z_Max = max(Age_Z, na.rm = TRUE),
Z_Mean = mean(Age_Z, na.rm = TRUE),
Z_SD = sd(Age_Z, na.rm = TRUE),
# Inverse Square
InvSq_Min = min(Age_Inv_Sq, na.rm = TRUE),
InvSq_Max = max(Age_Inv_Sq, na.rm = TRUE),
InvSq_Mean = mean(Age_Inv_Sq, na.rm = TRUE),
InvSq_SD = sd(Age_Inv_Sq, na.rm = TRUE),
# Inverse Cubic
InvCubic_Min = min(Age_Inv_Cubic, na.rm = TRUE),
InvCubic_Max = max(Age_Inv_Cubic, na.rm = TRUE),
InvCubic_Mean = mean(Age_Inv_Cubic, na.rm = TRUE),
InvCubic_SD = sd(Age_Inv_Cubic, na.rm = TRUE)
)
tabel_perbandingan
## # A tibble: 1 × 20
## Age_Min Age_Max Age_Mean Age_SD MinMax_Min MinMax_Max MinMax_Mean MinMax_SD
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.42 80 29.6 14.2 0 1 0.367 0.178
## # ℹ 12 more variables: Z_Min <dbl>, Z_Max <dbl>, Z_Mean <dbl>, Z_SD <dbl>,
## # InvSq_Min <dbl>, InvSq_Max <dbl>, InvSq_Mean <dbl>, InvSq_SD <dbl>,
## # InvCubic_Min <dbl>, InvCubic_Max <dbl>, InvCubic_Mean <dbl>,
## # InvCubic_SD <dbl>
tabel_age <- data_transformasi %>%
select(
PassengerId,
Age,
Age_MinMax,
Age_Z,
Age_Inv_Sq,
Age_Inv_Cubic
)
head(tabel_age, 10)
## # A tibble: 10 × 6
## PassengerId Age Age_MinMax Age_Z Age_Inv_Sq Age_Inv_Cubic
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 22 0.271 -0.537 0.00207 0.0000939
## 2 2 38 0.472 0.593 0.000693 0.0000182
## 3 3 26 0.321 -0.254 0.00148 0.0000569
## 4 4 35 0.435 0.381 0.000816 0.0000233
## 5 5 35 0.435 0.381 0.000816 0.0000233
## 6 6 29 0.359 -0.0425 0.00119 0.0000410
## 7 7 54 0.673 1.72 0.000343 0.00000635
## 8 8 2 0.0199 -1.95 0.25 0.125
## 9 9 27 0.334 -0.184 0.00137 0.0000508
## 10 10 14 0.171 -1.10 0.00510 0.000364
Tabel menunjukkan beberapa hasil transformasi variabel Age, yaitu Min-Max, Z-Score, Inverse Square, dan Inverse Cubic. Age_Z menunjukkan posisi umur terhadap rata-rata, sedangkan pada transformasi invers, semakin besar umur maka nilai hasil transformasinya semakin kecil.
Berdasarkan pengelolaan Titanic Dataset yang terdiri atas 891 observasi dan 12 variabel, ditemukan beberapa permasalahan data berupa missing value pada Age, Cabin, dan Embarked, nilai ekstrem pada Fare, serta variasi penulisan Ticket. Berdasarkan tujuan analisis, data difokuskan pada variabel PassengerId, Survived, Sex, dan Age, kemudian dilakukan cleaning terutama melalui penanganan missing value pada Age sehingga diperoleh 891 observasi tanpa data yang hilang.
Hasil pemeriksaan menunjukkan bahwa Age memiliki rata-rata 29,60 tahun dan tidak berdistribusi normal berdasarkan visualisasi dan uji Shapiro-Wilk, sedangkan varians Age berdasarkan jenis kelamin dapat dianggap homogen berdasarkan uji Levene. Selanjutnya, data berhasil diintegrasikan menggunakan PassengerId sebagai key serta ditransformasikan melalui label encoding, one-hot encoding, min-max, z-score, dan inverse square. Dengan demikian, data telah melalui tahapan understand, identify, decide, process, dan validate sehingga siap digunakan untuk analisis mengenai pola keselamatan penumpang berdasarkan jenis kelamin dan umur.