## Pendahuluan Exploratory Data Analysis (EDA) adalah bagian dari proses data science. EDA menjadi sangat penting sebelum melakukan feature engineering dan modeling karena dalam tahap ini kita harus memahami datanya terlebih dahulu.

Exploratory Data Analysis mengacu pada proses kritis dalam melakukan investigasi awal pada data untuk menemukan pola, untuk menemukan anomali, untuk menguji hipotesis dan untuk memeriksa asumsi dengan bantuan statistik ringkasan dan representasi grafis. Dengan melakukan EDA, kita dapat lebih memahami kondisi dataset yang kita miliki.

Import Library

library(heatmaply) #Untuk plot heatmap Missing Data
## Warning: package 'heatmaply' was built under R version 3.6.3
## Loading required package: plotly
## Warning: package 'plotly' was built under R version 3.6.3
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 3.6.3
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
## Loading required package: viridis
## Warning: package 'viridis' was built under R version 3.6.3
## Loading required package: viridisLite
## Warning: package 'viridisLite' was built under R version 3.6.3
## 
## ======================
## Welcome to heatmaply version 1.2.1
## 
## Type citation('heatmaply') for how to cite the package.
## Type ?heatmaply for the main documentation.
## 
## The github page is: https://github.com/talgalili/heatmaply/
## Please submit your suggestions and bug-reports at: https://github.com/talgalili/heatmaply/issues
## Or contact: <tal.galili@gmail.com>
## ======================
library(visdat) #Untuk plot Missing Data
## Warning: package 'visdat' was built under R version 3.6.3
library(reshape2) #Modifikasi DataFrame
## Warning: package 'reshape2' was built under R version 3.6.3
library(tidyr) #Modifikasi DataFrame
## Warning: package 'tidyr' was built under R version 3.6.3
## 
## Attaching package: 'tidyr'
## The following object is masked from 'package:reshape2':
## 
##     smiths
library(ggplot2) #Plot
library(psych) #Pair Plot
## Warning: package 'psych' was built under R version 3.6.3
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(DataExplorer) #Corelation Plot
## Warning: package 'DataExplorer' was built under R version 3.6.3

Mengakses Dataset

df  <- read.csv("https://raw.githubusercontent.com/millaoktavia/Kelas-Mahir-Pejuang-Data-2.0/main/titanic_modify.csv",sep=';', stringsAsFactors = T)
head(df)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket    Fare Cabin Embarked
## 1        A/5 21171    7.25              S
## 2         PC 17599 712.833   C85        C
## 3 STON/O2. 3101282   7.925              S
## 4           113803    53.1  C123        S
## 5           373450    8.05              S
## 6           330877  84.583              Q

Tujuan Analisis Data

Melakukan klasifikasi penumpang yang selamat dan tidak selamat pada kasus tenggelamnya kapal Titanic.

Memahami dataset

Dataset Titanic dibuat untuk membuat machine learning untuk melakukan klasifikasi biner(Selamat atau Tidak Selamat. Variabel-variabel yang terdapat pada dataset ini adalah sebagai berikut:

  1. PassengerId = Nomor Id Penumpang
  2. Survived = Keterangan Selamat(0=Tidak, 1=Ya)
  3. Pclass = Kelas Tiket (1=Kelas 1, 2=Kelas 2, dst)
  4. Name = Nama Penumpang
  5. Sex = Jenis kelamin
  6. Age = Usia dalam tahun
  7. SibSp = Jumlah saudara kandung / pasangan di kapal Titanic
  8. Parch = Jumlah orang tua / anak di kapal Titanic
  9. Ticket = Nomor Tiket
  10. Fare = Harga Tiket
  11. Cabin = Nama Kabin
  12. Embarked = Pelabuhan Asal (C = Cherbourg, Q = Queenstown, S = Southampton)

##Eksploratory Data Analysis

Dimensi Data

dim(df)
## [1] 707  12

Artinya kita memiliki data dengan 12 kolom dan 707 baris

Variabel Pada Dataset

Kita dapat mengetahui tipe-tipe data masing-masing variable dan nama-nama variable dalam dataset.

names(df)
##  [1] "PassengerId" "Survived"    "Pclass"      "Name"        "Sex"        
##  [6] "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"       
## [11] "Cabin"       "Embarked"
df$Fare=as.numeric(df$Fare)

Mengubah tipe data fare menjadi numerik.

str(df)
## 'data.frame':    707 obs. of  12 variables:
##  $ PassengerId: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : int  0 1 1 1 0 0 0 0 1 1 ...
##  $ Pclass     : int  3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : Factor w/ 707 levels "Abbott, Mrs. Stanton (Rosa Hunt)",..: 86 149 282 221 8 432 401 493 326 449 ...
##  $ Sex        : Factor w/ 2 levels "female","male": 2 1 1 1 2 2 2 2 1 1 ...
##  $ Age        : num  22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp      : int  1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch      : int  0 0 0 0 0 0 0 1 2 0 ...
##  $ Ticket     : Factor w/ 563 levels "110152","110413",..: 426 492 554 41 385 227 72 321 281 110 ...
##  $ Fare       : num  158 171 166 133 196 209 130 68 13 101 ...
##  $ Cabin      : Factor w/ 122 levels "","A10","A14",..: 1 70 1 49 1 1 109 1 1 1 ...
##  $ Embarked   : Factor w/ 4 levels "","C","Q","S": 4 2 4 4 4 3 4 4 4 2 ...

karena pada kolom Cabin terdapat elemen "" maka kita anggap itu termasuk data kosong, jadi diganti dengan NA

df[df== ""] <- NA
head(df)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket Fare Cabin Embarked
## 1        A/5 21171  158  <NA>        S
## 2         PC 17599  171   C85        C
## 3 STON/O2. 3101282  166  <NA>        S
## 4           113803  133  C123        S
## 5           373450  196  <NA>        S
## 6           330877  209  <NA>        Q

Kita dapat mengetahui tipe-tipe data masing-masing variabel dan nama-nama variabel dalam dataset.

Mengecek Missing Data

Missing data sangat mempengaruhi hasil analisis, pada nantinya akan kita isi atau hapus. Namun sebelumnya dicek keberadaanya terlebih dahulu dengan syntax berikut:

sapply(df, function(x) sum(is.na(x)))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0         145 
##       SibSp       Parch      Ticket        Fare       Cabin    Embarked 
##           0           0           0           0         548           1

Untuk lebih memudahkan dalam membaca missing data, dapat ditampilkan dalam visualisasi berikut:

heatmaply_na(
  df[1:20,],
  showticklabels = c(TRUE, FALSE)
)

Hasil plot di atas berupa tampilan interaktif, yang mana bagian dengan warna hitam adalah bagian data yang hilang. Hasil plot di atas efektif untuk data dengan jumlah baris yang sedikit, untuk jumlah data yang banyak dapat digunakan sytax berikut:

vis_miss(df)

Dari ketiga hasil di atas diketahui bahwa kolom dengan missing data adalah kolom Age dan Cabin. Kedua kolom ini perlu mendapat perlakuan khusus nantinya.

Mengecek Outlier

Outlier adalah data yang berbeda dengan data lainnya. Nilai ini kadang menjadi nilai yang penting untuk diamati, namun kadang juga menjadi gangguan pada penerapan metode Machine Learning. Pada modul ini, nantinya nilai ini akan dihapus dengan pertimbangan tertentu. Kemudian, untuk melihat apakah ada outlier atau tidak dalam suatu dataset dapat dilihat melalui boxplot berikut:

num_cols <- unlist(lapply(df, is.numeric)) #Memilih kolom bertipe numerik
df_num <- df[ , num_cols]  
boxplot(df_num)

Titik lingkaran di luar boxplot adalah outlier. Sehingga kolom yang mengandung outlier adalah Age, SibSp, Parch, dan Fare.

Melihat korelasi data

plot_correlation(df_num)
## Warning: Removed 12 rows containing missing values (geom_text).

Perlu dicatat bahwa, missing data membuat hasil plot di atas kurang maksimal. Namun demikian, pada notebook ini kita fokus pada EDA dan Pemodelan SVM jadi kita biarkan dulu. Nanti baru dihapus.

Melihat statistik data

summary(df)
##   PassengerId       Survived          Pclass     
##  Min.   :  1.0   Min.   :0.0000   Min.   :1.000  
##  1st Qu.:177.5   1st Qu.:0.0000   1st Qu.:2.000  
##  Median :354.0   Median :0.0000   Median :3.000  
##  Mean   :354.0   Mean   :0.3876   Mean   :2.308  
##  3rd Qu.:530.5   3rd Qu.:1.0000   3rd Qu.:3.000  
##  Max.   :707.0   Max.   :1.0000   Max.   :3.000  
##                                                  
##                                              Name         Sex     
##  Abbott, Mrs. Stanton (Rosa Hunt)              :  1   female:254  
##  Abelson, Mr. Samuel                           :  1   male  :453  
##  Adahl, Mr. Mauritz Nils Martin                :  1               
##  Adams, Mr. John                               :  1               
##  Ahlin, Mrs. Johan (Johanna Persdotter Larsson):  1               
##  Albimona, Mr. Nassef Cassem                   :  1               
##  (Other)                                       :701               
##       Age            SibSp            Parch                 Ticket   
##  Min.   : 0.75   Min.   :0.0000   Min.   :0.0000   CA 2144     :  6  
##  1st Qu.:21.00   1st Qu.:0.0000   1st Qu.:0.0000   1601        :  5  
##  Median :28.00   Median :0.0000   Median :0.0000   3101295     :  5  
##  Mean   :30.03   Mean   :0.5304   Mean   :0.3833   347082      :  5  
##  3rd Qu.:39.00   3rd Qu.:1.0000   3rd Qu.:0.0000   347088      :  5  
##  Max.   :80.00   Max.   :8.0000   Max.   :6.0000   S.O.C. 14879:  5  
##  NA's   :145                                       (Other)     :676  
##       Fare               Cabin     Embarked  
##  Min.   :  1.0   C23 C25 C27:  4       :  0  
##  1st Qu.: 57.5   G6         :  4   C   :136  
##  Median :119.0   C22 C26    :  3   Q   : 64  
##  Mean   :115.8   D          :  3   S   :506  
##  3rd Qu.:174.0   F2         :  3   NA's:  1  
##  Max.   :227.0   (Other)    :142             
##                  NA's       :548
d <- melt(df_num)
## No id variables; using all as measure variables
ggplot(d,aes(x = value)) + 
    facet_wrap(~variable,scales = "free_x") + 
    geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 145 rows containing non-finite values (stat_bin).

Plot ini untuk melihat apakah variabel-variabel pada dataset berdistribusi normal. Variabel-variabel Age, SibSp, Parch, dan Fare cenderung memiliki skewnes positif. Itu berarti berarti ekor distribusi berada di sebelah kanan nilai terbanyak.

Pairplot

pairs.panels(df_num, 
             method = "pearson", # correlation method
             hist.col = "#00AFBB",
             density = TRUE,  # show density plots
             ellipses = TRUE # show correlation ellipses
             )

##Data Preprocessing Data preprocessing ini digunakan guna menyiapkan data untuk diklasifikasi menggunakan metode SVM(Hanya Contoh).

Setelah mengetahui hasil EDA di atas maka untuk hasil yang baik diperlukan beberapa hal sebagai berikut:

  1. Menghapus kolom teks yang tidak diperlukan:Name dan Ticket
  2. Mengisi NaN pada kolom Cabin dengan salah satu nama kabin tertentu, mengisi NaN pada kolom *Age** dengan nilai rata-ratanya
  3. Melakukan pengkodean(Encoding) pada kolom Sex , Cabin, dan Embarked
  4. Menghapus outlier
  5. Karena nilai data ada yang sangat besar dan kecil maka perlu dilakukan normalisasi.

Setelah data diperbaiki dilakukan langkah sebagai berikut:

  1. Memilih variabel independent dan label
  2. Membagi data menjadi data training dan data testing

[Note] * Ini hanya contoh untuk melakukan pengisian data NaN(Kosong), nama kabin mungkin menjadi penting sehingga tidak segampang itu diganti

Seleksi Kolom

Bertujuan untuk menghapus kolom NAme dan kolom Ticket.

df=subset(df, select= -c(Name, Ticket))
head(df)
##   PassengerId Survived Pclass    Sex Age SibSp Parch Fare Cabin Embarked
## 1           1        0      3   male  22     1     0  158  <NA>        S
## 2           2        1      1 female  38     1     0  171   C85        C
## 3           3        1      3 female  26     0     0  166  <NA>        S
## 4           4        1      1 female  35     1     0  133  C123        S
## 5           5        0      3   male  35     0     0  196  <NA>        S
## 6           6        0      3   male  NA     0     0  209  <NA>        Q

Mengisi NAN

#Mengisi NA pada kolom Age dengan mean(Age)
df$Age[is.na(df$Age)] = 0
m<-mean(df$Age)
df$Age[df$Age==0]<-m

#Mengisi NA pada kolom Cabin dengan E49
df=df %>% replace_na(list(Cabin = "E49"))
## Warning in `[<-.factor`(`*tmp*`, !is_complete(data[[var]]), value = "E49"):
## invalid factor level, NA generated
#Mengisi NA pada kolom Embarked dengan C
df=df %>% replace_na(list(Embarked = "C"))

#Mengecek apakah NA sudah terganti
sapply(df, function(x) sum(is.na(x)))
## PassengerId    Survived      Pclass         Sex         Age       SibSp 
##           0           0           0           0           0           0 
##       Parch        Fare       Cabin    Embarked 
##           0           0         548           0
head(df)
##   PassengerId Survived Pclass    Sex      Age SibSp Parch Fare Cabin Embarked
## 1           1        0      3   male 22.00000     1     0  158  <NA>        S
## 2           2        1      1 female 38.00000     1     0  171   C85        C
## 3           3        1      3 female 26.00000     0     0  166  <NA>        S
## 4           4        1      1 female 35.00000     1     0  133  C123        S
## 5           5        0      3   male 35.00000     0     0  196  <NA>        S
## 6           6        0      3   male 23.87447     0     0  209  <NA>        Q

Melakukan Pengkodean(Encoding)

df$Sex<- unclass(df$Sex)
df$Embarked<- unclass(df$Embarked)
df$Cabin<- unclass(df$Cabin)
head(df)
##   PassengerId Survived Pclass Sex      Age SibSp Parch Fare Cabin Embarked
## 1           1        0      3   2 22.00000     1     0  158    NA        4
## 2           2        1      1   1 38.00000     1     0  171    70        2
## 3           3        1      3   1 26.00000     0     0  166    NA        4
## 4           4        1      1   1 35.00000     1     0  133    49        4
## 5           5        0      3   2 35.00000     0     0  196    NA        4
## 6           6        0      3   2 23.87447     0     0  209    NA        3

Diatas adalah proses konversi informasi dari objek menjadi data.

Menghapus Outlier

#' Detect outliers using IQR method
#' 
#' @param x A numeric vector
#' @param na.rm Whether to exclude NAs when computing quantiles
#' 
is_outlier <- function(x, na.rm = FALSE) {
  qs = quantile(x, probs = c(0.25, 0.75), na.rm = na.rm)

  lowerq <- qs[1]
  upperq <- qs[2]
  iqr = upperq - lowerq 

  extreme.threshold.upper = (iqr * 3) + upperq
  extreme.threshold.lower = lowerq - (iqr * 3)

  # Return logical vector
  x > extreme.threshold.upper | x < extreme.threshold.lower
}

#' Remove rows with outliers in given columns
#' 
#' Any row with at least 1 outlier will be removed
#' 
#' @param df A data.frame
#' @param cols Names of the columns of interest. Defaults to all columns.
#' 
#' 
remove_outliers <- function(df, cols = names(df)) {
  for (col in cols) {
    cat("Removing outliers in column: ", col, " \n")
    df <- df[!is_outlier(df[[col]]),]
  }
  df
}


vars_of_interest <- c("Age", "SibSp", "Parch", "Fare")


df_filtered <- remove_outliers(df, vars_of_interest)
## Removing outliers in column:  Age  
## Removing outliers in column:  SibSp  
## Removing outliers in column:  Parch  
## Removing outliers in column:  Fare
boxplot(df_filtered)

### Normalisasi Data

unit_length <- function(x) {
                            x / sqrt(sum(x^2))
                            }

unit_length_df <- as.data.frame(lapply(df, unit_length))

head(unit_length_df)
##    PassengerId   Survived     Pclass        Sex        Age      SibSp Parch
## 1 9.203883e-05 0.00000000 0.04596386 0.04400123 0.02611608 0.03157545     0
## 2 1.840777e-04 0.06041221 0.01532129 0.02200062 0.04510959 0.03157545     0
## 3 2.761165e-04 0.06041221 0.04596386 0.02200062 0.03086446 0.00000000     0
## 4 3.681553e-04 0.06041221 0.01532129 0.02200062 0.04154831 0.03157545     0
## 5 4.601941e-04 0.00000000 0.04596386 0.04400123 0.04154831 0.00000000     0
## 6 5.522330e-04 0.00000000 0.04596386 0.04400123 0.02834125 0.00000000     0
##         Fare Cabin   Embarked
## 1 0.04443788    NA 0.04165763
## 2 0.04809417    NA 0.02082881
## 3 0.04668790    NA 0.04165763
## 4 0.03740657    NA 0.04165763
## 5 0.05512548    NA 0.04165763
## 6 0.05878176    NA 0.03124322

Normalisasi Panjang Unit.Normalisasi Panjang Satuan mengubah x menjadi x ’dengan membagi setiap nilai vektor fitur dengan panjang vektor Euclidean.

Memilih Variable Target & Variabel Independent

y=df$Survived
x=data.matrix(df[-c(2)])

Membagi Data Menjadi Data Training dan Data Testing

x_train=x[1:7000]
x_test=x[7001:8019]
y_train=x[1:7000]
y_test=x[7001:8019]

Data training adalah data untuk melatih algoritma, sedangkan data testing dipakai untuk mengetahui performa algoritma yang sudah dilatih sebelumnya ketika menemukan data baru yang belum pernah dilihat sebelumnya.

##This is the end of Notebooks

Say: Alhamdulillah, panjang banget dah :)