Buku Belajar Dasar Statistik dengan R – Split Dataset

By | July 30, 2024
2,052 Views

Split Dataset

Split dataset biasanya terkait dengan algoritma yang melibatkan proses training dan testing. Pembagian dataset mempunyai banyak proporsi seperti 70:30 atau 80:20, misalkan kita dataset terdiri dari 100 record maka 70 untuk dataset training dan 30 untuk dataset testing. Terlihat bahwa porsi dataset terbesar dialokasikan untuk sesi training. Biar gampang untuk contoh, misalkan kita dataset berikut (sengaja menggunakan huruf biar mudah)

huruf <-c('A','B','C','D','E','F','G','H','I','J','K','L')

Kita split dataset menjadi 70:30 saja

huruf <-c('A','B','C','D','E','F','G','H','I','J','K','L')
huruf <- data.frame(huruf)
print(huruf)
n_observasi = nrow(huruf)
ratio = 0.7
index_train <- sample(n_observasi, ratio*n_observasi)
index_test <- setdiff(seq_len(n_observasi), index_train)

df_train = huruf[index_train,]
df_test = huruf[index_test,]
print(data.frame(df_train))
print(data.frame(df_test))

mennghasilkan dataset training dan testing seperti berikut dibawah ini

   huruf
1      A
2      B
3      C
4      D
5      E
6      F
7      G
8      H
9      I
10     J
11     K
12     L

df_train
1        D
2        E
3        G
4        J
5        C
6        H
7        I
8        F

  df_test
1       A
2       B
3       K
4       L

Dari 12 records maka 70% atau 8 record dimasukan sebagai dataset training.

Setup Bilangan Random

Bila kalian run berkali-kali maka akan berubah-ubah nilai index nya. Untuk mencegah agar tetap sama, kalian bisa setup random seed nya, misalkan diberikan angka 101

set.seed(101)

Kalian bebas menggunakan nilai berapa pun yang merupakan nilai yang bersifat acak by system, misalkan dipicu oleh time yang ada dikomputer. Sehingga dengan menetapkan sedari awal maka generator random menjadi bisa dikontrol. Kita coba berikut ini untuk mencoba iterasi bilangan random sebanyak 10 kali

for (i in sequence(10))
{
  print(paste(i,rnorm(1),sep=': '))
  
}

Hasil nya akan berubah-ubah setiap kali di run

[1] "1: -2.18895197838708"
[1] "2: -0.451048062560023"
[1] "3: 1.6245184434387"
[1] "4: -0.972909060236263"
[1] "5: -0.716914282110798"
[1] "6: -0.558165374113052"
[1] "7: 0.178543267989125"
[1] "8: -0.623304537566837"
[1] "9: 0.487589531540085"
[1] "10: -0.699840528099548"

Ketika kalian memberikan perintah berikut

for (i in sequence(10))
{
  set.seed(10)
  print(paste(i,rnorm(1),sep=': '))
  
}

Maka nilainya akan senantiasa sama

[1] "1: 0.0187461709418264"
[1] "2: 0.0187461709418264"
[1] "3: 0.0187461709418264"
[1] "4: 0.0187461709418264"
[1] "5: 0.0187461709418264"
[1] "6: 0.0187461709418264"
[1] "7: 0.0187461709418264"
[1] "8: 0.0187461709418264"
[1] "9: 0.0187461709418264"
[1] "10: 0.0187461709418264"

Atau perintah set.seed(10) sebelum for-loop akan menghasilkan nilai yang sama terus-menerus setiap kalian run

set.seed(10)
for (i in sequence(10))
{
  
  print(paste(i,rnorm(1),sep=': '))
  
}

Hasil

[1] "1: 0.0187461709418264"
[1] "2: -0.184252542069064"
[1] "3: -1.37133054992251"
[1] "4: -0.599167715783718"
[1] "5: 0.294545126567508"
[1] "6: 0.389794300700167"
[1] "7: -1.20807617542949"
[1] "8: -0.363676017470862"
[1] "9: -1.62667268170309"
[1] "10: -0.256478394123992"

Kalian bisa coba kode berikut

set.seed(101)
huruf <-c('A','B','C','D','E','F','G','H','I','J','K','L')
huruf <- data.frame(huruf)
print(huruf)
n_observasi = nrow(huruf)
ratio = 0.7
index_train <- sample(n_observasi, ratio*n_observasi)
index_test <- setdiff(seq_len(n_observasi), index_train)

df_train = huruf[index_train,]
df_test = huruf[index_test,]
print(data.frame(df_train))
print(data.frame(df_test))

Nah pada tahap ini sudah paham cara split dataset secara random, selanjutnya akan dibahas mengenai dataset yang mengandung target/kelas. Case ini ditemui untuk kasus klasifikasi/kategorikal yang bisa saja terdiri dari lebih dari 2 kelas/target. Jangan lupa untuk menggunakan package dplyr

Split Dataset dengan banyak Kelas

Mari kita perhatikan dataset berikut yang berisi kelas/target sebanyak k=2

library(dplyr)
dat<-read.csv('Book1.csv')
print(dat)

hasil

  X KELAS
1  A     1
2  B     1
3  C     1
4  D     1
5  E     1
6  F     1
7  G     1
8  H     1
9  I     1
10 J     1
11 K     1
12 L     1
13 M     2
14 N     2
15 O     2
16 P     2
17 Q     2
18 R     2
19 S     2
20 T     2
21 U     2
22 V     2
23 W     2
24 X     2
25 Y     2
26 Z     2

Tentu split dataset dengan cara pertama tidak bisa kita lakukan karena kita harus membagi per kelas terlebih dahulu. Untuk dataset kelas==1 terdiri dari 12 record

anggota1<-filter(dat,KELAS==1)
print(anggota1)

hasil

   X KELAS
1  A     1
2  B     1
3  C     1
4  D     1
5  E     1
6  F     1
7  G     1
8  H     1
9  I     1
10 J     1
11 K     1
12 L     1

Sedangkan untuk kelas ==2 terdiri dari 14 record

anggota2<-filter(dat,KELAS==2)
print(anggota2)

hasil

   X KELAS
1  M     2
2  N     2
3  O     2
4  P     2
5  Q     2
6  R     2
7  S     2
8  T     2
9  U     2
10 V     2
11 W     2
12 X     2
13 Y     2
14 Z     2

Sehingga dengan informasi tersebut jika menggunakan ratio 70 akan didapatkan seperti berikut

  1. Kelas==1 terdiri dari 8 record training dan 4 record testing
  2. Kelas==2 terdiri dari 10 record training dan 4 record testing

Bila digabung menjadi satu maka dataset training terdiri dari 18 record dan testing terdiri dari 8 record

Membuat Function Split dataset

Kode yang telah kita buat harus diubah menjadi sebuah function dengan return multiple value

split_dataset<-function(dat,ratio)
{
  n_observasi = nrow(dat)
  
  index_train <- sample(n_observasi, ratio*n_observasi)
  index_test <- setdiff(seq_len(n_observasi), index_train)
  
  df_train = dat[index_train,]
  df_test = dat[index_test,]
  #untuk multiple return 
  result <- list('train' = df_train,'test' = df_test)
  return (result)
}

Selanjutnya kita akan melakukan looping dan filtering dataframe menggunakan dplyr

dat<-read.csv('Book1.csv')
print(dat)
jumlah_kelas = 2

header <-colnames(dat)
#buat empty data frame
df_train = data.frame(matrix(ncol=length(header),nrow=0, dimnames=list(NULL,header)))
df_test = data.frame(matrix(ncol=length(header),nrow=0, dimnames=list(NULL,header)))

for (k in sequence(jumlah_kelas))
{
  #filtering
  anggota <-filter(dat,KELAS==k)
  #split dataset
  hasil<-split_dataset(anggota,0.7)
  #append data frame
  df_train = rbind(df_train,hasil$train)
  df_test = rbind(df_test,hasil$test)
}
#reset index nya jangan lupa
rownames(df_train) <- 1:nrow(df_train)
rownames(df_test) <- 1:nrow(df_test)
print('Dataset training')
print(df_train)
print('Dataset testing')
print(df_test)

Hasilnya sebagai berikut

[1]"Dataset training">
[2] 
[3]X KELAS
1  A     1
2  D     1
3  B     1
4  E     1
5  I     1
6  G     1
7  C     1
8  J     1
9  N     2
10 V     2
11 R     2
12 M     2
13 U     2
14 Q     2
15 S     2
16 W     2
17 P     2

[1]"Dataset testing"
[2] X KELAS
1 F     1
2 H     1
3 K     1
4 L     1
5 O     2
6 T     2
7 X     2
8 Y     2
9 Z     2

Gimana menurut kalian untuk Split Dataset nya? Coba kalian yang sudah belajar cara membuat function di R, tentu bisa donk buat kode diatas menjadi sebuah function di R