Learn by Building 9: Neural Network & Deep Learning

Introduction

Definition

Neural Network merupakan kategori ilmu Soft Computing. Neural Network sebenarnya mengadopsi dari kemampuan otak manusia yang mampu memberikan stimulasi/rangsangan, melakukan proses, dan memberikan output. Output diperoleh dari variasi stimulasi dan proses yang terjadi di dalam otak manusia. Kemampuan manusia dalam memproses informasi merupakan hasil kompleksitas proses di dalam otak.

Fungsi dari Neural Network diantaranya adalah:

  1. Pengklasifikasian pola
  2. Memetakan pola yang didapat dari input ke dalam pola baru pada output
  3. Penyimpan pola yang akan dipanggil kembali
  4. Memetakan pola-pola yang sejenis
  5. Pengoptimasi permasalahan
  6. Prediksi

About Dataset

Kita akan menggunakan sign-language-mnist dataset yang dapat diunduh pada laman berikut. Data yang harus diunduh, yaitu sign-mnist-train.csv sebagai data train dan sign-mnist-test.csv sebagai data test. Kedua data tersebut menyimpan gambar bahasa isyarat (sign language) berukuran 28 x 28 pixel untuk 24 kategori yang berbeda.

Import Library

library(dplyr)
library(keras)
library(caret)

Read Data

sign_train <- read.csv("sign_mnist_train.csv")
sign_test <- read.csv("sign_mnist_test.csv")

Periksa dimensi data sign_train dengan menggunakan dim().

sign_train %>% 
  dim()
## [1] 27455   785

sign_train terdiri dari 27455 observasi dan 785 variabel (1 target and 784 prediktor). Setiap prediktor merepresentasikan pixel dari gambar.

Data Wrangling

Memperbaiki kategori pada target variabel

Periksa kategori pada target variabel baik pada data sign_train dan sign_test degan menggunakan fungsi unique()

sign_train$label %>% 
  unique()
##  [1]  3  6  2 13 16  8 22 18 10 20 17 19 21 23 24  1 12 11 15  4  0  5  7 14
sign_test$label %>% 
  unique()
##  [1]  6  5 10  0  3 21 14  7  8 12  4 22  2 15  1 13 19 18 23 17 20 16 11 24

Kita perlu memperbaiki kategori pada target variabel baik pada data sign_train dan sign_test. Karena label 9 dan 25 tidak ada, kita dapat mengurangkan dengan 1 semua label yang bernilai lebih besar dari 9. Dengan cara ini, label kita menjadi semua bilangan bulat dari 0 hingga 23. Kita dapat memanfaatkan fungsi mutate() dan ifelse() untuk memperbaiki kategori pada target variabel baik pada data sign_train dan sign_test.

Gunakan code di bawah ini untuk memperbaiki kategori target variabel pada data sign_train dan sign_test.

sign_train <- sign_train %>% 
  mutate(label = ifelse(label > 9, label-1, label))

sign_test <- sign_test %>% 
  mutate(label = ifelse(label > 9, label-1, label))
unique(sign_train$label)
##  [1]  3  6  2 12 15  8 21 17  9 19 16 18 20 22 23  1 11 10 14  4  0  5  7 13
unique(sign_test$label)
##  [1]  6  5  9  0  3 20 13  7  8 11  4 21  2 14  1 12 18 17 22 16 19 15 10 23

Cek proporsi nilai target data_train

sign_train$label %>% 
  table() %>% 
  prop.table()
## .
##          0          1          2          3          4          5          6 
## 0.04101257 0.03678747 0.04166818 0.04356219 0.03485704 0.04385358 0.03970133 
##          7          8          9         10         11         12         13 
## 0.03689674 0.04232380 0.04057549 0.04520124 0.03842652 0.04192315 0.04356219 
##         14         15         16         17         18         19         20 
## 0.03962848 0.04658532 0.04713167 0.04367146 0.04319796 0.04228738 0.03940994 
##         21         22         23 
## 0.04461847 0.04239665 0.04072118

Balance, karena perbedaannya tidak terlalu signifikan (datanya labelnya ada 25, sehingga balance nya adalah 100% / 25 = 4%. Terlihat masing-masing label memiliki proporsi kisaran 4%). Proporsi target variable yang kita miliki dapat dikategorikan sebagai data yang balance.

Range Nilai Prediktor

sign_train %>%
  dplyr::select(-label) %>% 
  range()
## [1]   0 255

Range value predictor: 0 - 255

Data Pre-Processing

Memisahkan prediktor dan target, mengubah data ke dalam matriks, dan features scaling

Data berisi nilai pixel yang disimpan dalam data frame. Namun, kita harus memisahkan prediktor dan target untuk data sign_train dan sign_test dan menyimpannya ke dalam train_x, train_y, test_x, dan test_y.

Kita dapat memanfaatkan fungsi select() untuk memisahkan prediktor dan target pada data sign_train dan sign_test.

Setelah itu, data train_x, train_y, test_x, dan test_y harus diubah menjadi matriks.

Mengubah data menjadi format matrix menggunakan fungsi data.matrix(). Khusus untuk prediktor variabel yang disimpan pada train_x dan test_x lakukan features scaling dengan cara membaginya dengan 255.

# Predictor variables in `sign_train`
train_x <- sign_train %>% 
  dplyr::select(-label) %>% 
  as.matrix() / 255 #scaling 0-255

# Predictor variables in `sign_test`
test_x <- sign_test %>% 
  dplyr::select(-label) %>% 
  as.matrix() / 255 #scaling 0-255

# Target variable in `sign_train`
train_y <- sign_train %>% 
  dplyr::select(label)

# Target variable in `sign_test`
test_y <- sign_test %>% 
  dplyr::select(label)

Mengubah matriks menjai array

Selanjutnya, kita harus mengubah matriks prediktor ke dalam bentuk array. Kita dapat menggunakan fungsi array_reshape(data, dim(data)) untuk mengubah matriks prediktor menjadi array.

# Predictor variables in `train_x`
train_x_array <- train_x %>% 
  array_reshape(dim = dim(train_x))

# Predictor variables in `test_x`
test_x_array <- test_x %>% 
  array_reshape(dim = dim(test_x))

Kita juga perlu melakukan one-hot encoding terhadap target variabel pada data train (train_y). Kita dapat menggunakan fungsi to_categorical() dari library Keras, kemudian simpan sebagai objek train_y_dummy.

# Target variable in `train_y`
train_y_dummy <- train_y %>% 
  as.matrix() %>% 
  to_categorical()
## Loaded Tensorflow version 2.0.0
# Target variable in `test_y`
test_y_dummy <- test_y %>% 
  as.matrix() %>% 
  to_categorical()

Modeling Neural Network

Membuat sebuah model dasar menggunakan keras_model_sequential()

Untuk mengatur layer, kita harus membuat model dasar, yaitu model sequential. Panggil fungsi keras_model_sequential(), dan gunakan operator pipe untuk membangun arsitektur model dari model dasar yang ada.

Membangun Arsitektur (menentukan layer, neuron, dan fungsi aktivasi)

Untuk membangun arsitektur tiap layer, kita akan membuat beberapa model dengan mengatur beberapa parameter. Sebelum membangun arsitekturnya, kita atur initializer untuk memastikan hasil yang kita dapat tidak akan berubah.

RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(100)
initializer <- initializer_random_normal(seed = 100)

Model Base

Pertama, buat model (simpan dalam model_base) dengan mendefinisikan parameter-parameter di bawah ini:

  • layer pertama berisi 64 nodes, fungsi aktivasi ReLu, 784 input shape
  • layer kedua berisi 32 nodes, fungsi aktivasi ReLu
  • layer output berisi 24 nodes, fungsi aktivasi softmax
model_base <- keras_model_sequential()

Define Architecture

model_base %>% 
  layer_dense(input_shape = 784, # membuat input layer
              units = 64, # hidden layer 1
              activation = "relu", #Activation function
              name = "Hid1") %>% 
  
  layer_dense(units = 32,
              activation = "relu",
              name = "Hid2") %>% 
  
  layer_dense(units = 24, # kita sesuaikan dengan jumlah target variable kita
              activation = "softmax",
              name = "Out_base")

# Untuk melihat hasil arsitektur yang sudah dibuat
summary(model_base)
## Model: "sequential"
## ________________________________________________________________________________
## Layer (type)                        Output Shape                    Param #     
## ================================================================================
## Hid1 (Dense)                        (None, 64)                      50240       
## ________________________________________________________________________________
## Hid2 (Dense)                        (None, 32)                      2080        
## ________________________________________________________________________________
## Out_base (Dense)                    (None, 24)                      792         
## ================================================================================
## Total params: 53,112
## Trainable params: 53,112
## Non-trainable params: 0
## ________________________________________________________________________________

Membangun arsitektur (menentukan cost function dan optimizer)

Kita masih perlu melakukan beberapa pengaturan sebelum melatih model_base. Kita harus menyusun model dengan menentukan loss function, jenis optimizer, dan metrik evaluasi. Kita dapat melakukan compile model terhadap model_base dengan menggunakan parameter berikut:

  • categorical_crossentropy sebagai loss function;
  • optimizer_adam sebagai optimizer dengan learning rate 0.001;
  • gunakan accuracy sebagai metrik evaluasi
model_base %>% 
  compile(loss= "categorical_crossentropy",
          optimizer = optimizer_adam(learning_rate = 0.001),
          metrics = "accuracy")

** Fitting model di data train (mengatur epoch dan ukuran batch)**

Pada tahap ini, kita fit model menggunakan epoch = 10, batch_size = 150, dan menambahkan parameter shuffle = F agar sampel pada tiap batch tidak diambil secara random melainkan terurut (sequence) untuk model_base. Simpan hasil fit model ke dalam history_base.

history_base <- model_base %>% 
           fit(x = train_x_array, #predictor
               y = train_y_dummy, #target variabel
               epochs = 10,
               validation_data = list(test_x_array, test_y_dummy),
               shuffle = F, 
               verbose = T, 
               batch_size = 150 
               )

Data Visualisasi

plot(history_base)

Prediction

Untuk mengevaluasi performa model terhadap data yang belum dilihat, kita akan memprediksi data test (test_x_array) menggunakan model yang sudah dilatih. Melakukan prediksi menggunakan fungsi predict_classes() dari package keras dan simpan sebagai pred_base.

# your code here
pred_base <- predict(model_base, #nama model
                      test_x_array) %>%  #prediktor data validasi
  k_argmax() %>%  #mengambil probabilitas yang paling tinggi
  as.array() %>%  #untuk mengubah dari bentuk TF -> array
  as.factor()     #untuk mengubah dari bentuk array -> factor

Evalution

Confusion Matrix (klasifikasi)

Kita dapat mengevaluasi model menggunakan beberapa metrics. Periksa akurasi dengan membuat confusion matrix. Menggunakan fungsi confusionMatrix() dari package caret.

Note: jangan lupa untuk melakukan explicit coercion as.factor bila data kita belum dalam bentuk faktor.

# your code here
caret::confusionMatrix(data = pred_base, 
                       reference = sign_test$label %>% as.factor()) 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
##         0  271   0   0   0  14   0   0   0   8   0   0   2  68   0   0   0   0
##         1    0 286   0   3  17   0   0   0   0   0   0   0   0   0   0   0   0
##         2    0   0 244   0   0  18   0   0   0   0   0   0   0   2   4   0   0
##         3    0  22   0 155   0   0  15   0  11   0   0   0   0   0   0   0   0
##         4    0   0   0   0 337   0   0   7   0   0   0  37  21   0   0   0   0
##         5    0   0  21   0   5 182   0   0   0   0   0   0   0  54   0  19   0
##         6    0   0   7   0   0   0 180  20   0   0   0   0   0  20   0   0   0
##         7    0   0   0   0   0   0  47 361  61   0   0  12   3   9   6   0  20
##         8    1  19   0   0   0   0   0   0 104   0   0   0   0   0  16   0   0
##         9    0  51   0   0   0  20   0   0   7 196   0   0   0   0  19   0   0
##         10   0   0  17   0   0  23  20   0  21   0 209   0   0   0  12   0  21
##         11   0   0   0   0  26   0   0   0   0   0   0 115   9   0   0  21   0
##         12   5   0   0   0   7   0   0   0   0   0   0  76  58   0   0   0   0
##         13  39   0   0   0   0   0   0  27   0   0   0  22   0 107   1   0   0
##         14   0   0   0   0   0   0   0   0   0   0   0   0   0   0 254   0   0
##         15   0   0   0   0   0   0  26   0   2   0   0  29  35  21  21 124   0
##         16   0   6   0  24   0   0   0   0  19 111   0   0   0   0   0   0  89
##         17  15   0   0   0  92   0   0   0   0   0   0  97  55   0   0   0   0
##         18   0   0   0   0   0   3  45  21  21   0   0   4  42  33   9   0   0
##         19   0   0   0  19   0   0   0   0   0   0   0   0   0   0   0   0   0
##         20   0   0   0   0   0   1   0   0   0   3   0   0   0   0   0   0   0
##         21   0  48   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##         22   0   0  21  44   0   0  15   0   0   0   0   0   0   0   5   0   0
##         23   0   0   0   0   0   0   0   0  34  21   0   0   0   0   0   0  14
##           Reference
## Prediction  17  18  19  20  21  22  23
##         0    4   0   0   0   0   0   0
##         1    0   0   0   0   0   0   0
##         2    0   0   0   0   0   0   0
##         3    0   0   5   5   0   0   0
##         4   35   0   0   0   0   0   0
##         5    0   0   0  20   1   0   0
##         6    0   7   0   0   0  12   0
##         7   18  14   0   0  21   0   0
##         8   41   0   0   0   0   0  41
##         9   21   0  49  29   1   0  21
##         10   0  20  34  24   0  30   5
##         11  36   0   0   0   0   0   0
##         12   6   0   0   0   0   0   0
##         13   0   0   0   0   0   0   0
##         14   0   1   0   4   0   0   0
##         15  14   0   0   0   0   0   0
##         16   0   0  68  95  39  13  51
##         17  50   0   0   0   0   5   0
##         18   0  62   0   0   0   2  21
##         19   0  16 103   7  15   0   0
##         20   0   3   7 142  21   1   0
##         21   0   0   0   0 108  55   0
##         22   0 104   0  20   0 149   0
##         23  21  21   0   0   0   0 193
## 
## Overall Statistics
##                                           
##                Accuracy : 0.5687          
##                  95% CI : (0.5572, 0.5802)
##     No Information Rate : 0.0694          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.5497          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
## Sensitivity           0.81873  0.66204  0.78710  0.63265  0.67671  0.73684
## Specificity           0.98597  0.99703  0.99650  0.99163  0.98502  0.98267
## Pos Pred Value        0.73842  0.93464  0.91045  0.72770  0.77117  0.60265
## Neg Pred Value        0.99118  0.97874  0.99044  0.98707  0.97610  0.99054
## Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
## Detection Rate        0.03779  0.03988  0.03402  0.02161  0.04699  0.02538
## Detection Prevalence  0.05117  0.04267  0.03737  0.02970  0.06093  0.04211
## Balanced Accuracy     0.90235  0.82953  0.89180  0.81214  0.83086  0.85976
##                      Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11
## Sensitivity           0.51724  0.82798  0.36111  0.59215   1.00000   0.29188
## Specificity           0.99033  0.96868  0.98286  0.96813   0.96740   0.98643
## Pos Pred Value        0.73171  0.63112  0.46847  0.47343   0.47936   0.55556
## Neg Pred Value        0.97574  0.98864  0.97353  0.98002   1.00000   0.95994
## Prevalence            0.04852  0.06079  0.04016  0.04615   0.02914   0.05494
## Detection Rate        0.02510  0.05033  0.01450  0.02733   0.02914   0.01603
## Detection Prevalence  0.03430  0.07975  0.03095  0.05772   0.06079   0.02886
## Balanced Accuracy     0.75378  0.89833  0.67198  0.78014   0.98370   0.63915
##                      Class: 12 Class: 13 Class: 14 Class: 15 Class: 16
## Sensitivity           0.199313   0.43496   0.73199   0.75610   0.61806
## Specificity           0.986339   0.98715   0.99927   0.97888   0.93939
## Pos Pred Value        0.381579   0.54592   0.98069   0.45588   0.17282
## Neg Pred Value        0.966809   0.98007   0.98655   0.99420   0.99174
## Prevalence            0.040574   0.03430   0.04838   0.02287   0.02008
## Detection Rate        0.008087   0.01492   0.03542   0.01729   0.01241
## Detection Prevalence  0.021194   0.02733   0.03611   0.03793   0.07181
## Balanced Accuracy     0.592826   0.71105   0.86563   0.86749   0.77872
##                      Class: 17 Class: 18 Class: 19 Class: 20 Class: 21
## Sensitivity           0.203252  0.250000   0.38722   0.41040   0.52427
## Specificity           0.961883  0.970971   0.99175   0.99473   0.98521
## Pos Pred Value        0.159236  0.235741   0.64375   0.79775   0.51185
## Neg Pred Value        0.971420  0.973079   0.97675   0.97083   0.98592
## Prevalence            0.034300  0.034579   0.03709   0.04824   0.02872
## Detection Rate        0.006972  0.008645   0.01436   0.01980   0.01506
## Detection Prevalence  0.043781  0.036670   0.02231   0.02482   0.02942
## Balanced Accuracy     0.582567  0.610485   0.68948   0.70257   0.75474
##                      Class: 22 Class: 23
## Sensitivity            0.55805   0.58133
## Specificity            0.96973   0.98377
## Pos Pred Value         0.41620   0.63487
## Neg Pred Value         0.98268   0.97976
## Prevalence             0.03723   0.04629
## Detection Rate         0.02078   0.02691
## Detection Prevalence   0.04992   0.04239
## Balanced Accuracy      0.76389   0.78255

Memiliki nilai Akurasi nya kisaran <60% (masih under-fitting)

Model Tuning

Karena model belum memberikan performa yang cukup baik (best fit) dimana model_base cenderung underfitting. Sekarang, mari kita coba membangun model_tuning dengan mengatur parameter sebagai berikut:

  • layer pertama berisi 1024 nodes, fungsi aktivasi ReLu, 784 input shape
  • layer kedua berisi 512 nodes, fungsi aktivasi ReLu
  • layer ketiga berisi 256 nodes, fungsi aktivasi ReLu
  • layer output berisi 24 nodes, fungsi aktivasi softmax
# your code here
model_tuning <- keras_model_sequential()

Define Architecture

# Please type your answer
model_tuning %>% 
  layer_dense(input_shape = 784, # membuat input layer
              units = 1024, # hidden layer 1
              activation = "relu", #Activation function
              name = "H_1") %>% 
  
  layer_dense(units = 512,
              activation = "relu",
              name = "H_2") %>%   
  
  layer_dense(units = 256,
              activation = "relu",
              name = "H_3") %>%   
  
  layer_dense(units = 24, 
              activation = "softmax", 
              name = "Out_tun")

# Untuk melihat hasil arsitektur yang sudah dibuat
summary(model_tuning)
## Model: "sequential_1"
## ________________________________________________________________________________
## Layer (type)                        Output Shape                    Param #     
## ================================================================================
## H_1 (Dense)                         (None, 1024)                    803840      
## ________________________________________________________________________________
## H_2 (Dense)                         (None, 512)                     524800      
## ________________________________________________________________________________
## H_3 (Dense)                         (None, 256)                     131328      
## ________________________________________________________________________________
## Out_tun (Dense)                     (None, 24)                      6168        
## ================================================================================
## Total params: 1,466,136
## Trainable params: 1,466,136
## Non-trainable params: 0
## ________________________________________________________________________________

Kemudian, lakukan compile model dengan menggunakan parameter berikut:

  • categorical_crossentropy sebagai loss function;
  • optimizer_adam sebagai optimizer dengan learning rate 0.001;
  • gunakan accuracy sebagai metrik evaluasi
model_tuning %>% 
  compile(loss= "categorical_crossentropy",
          optimizer = optimizer_adam(learning_rate = 0.001),
          metrics = "accuracy")

Terakhir, fit model menggunakan epoch = 10, batch_size = 150, dan menambahkan parameter shuffle = F agar sampel pada tiap batch tidak diambil secara random melainkan terurut (sequence)

history_tuning <- model_tuning %>% 
           fit(x = train_x_array, #predictor
               y = train_y_dummy, #target variabel
               epochs = 10,
               validation_data = list(test_x_array, test_y_dummy),
               shuffle = F, 
               verbose = T, 
               batch_size = 150
               )

Data Visualisasi

plot(history_tuning)

Setelah tuning model, kita prediksi test_x_array menggunakan model_tuning. Melakukan prediksi menggunakan fungsi predict_classes() dari package keras dan simpan sebagai pred_tuning

pred_tuning <- predict(model_tuning, # nama model
                       test_x_array) %>%  # prediktor data validasi
  k_argmax() %>%  
  as.array() %>%  
  as.factor() 

Evaluasi performa model menggunakan menggunakan metrik akurasi. Menggunakan fungsi confusionMatrix() dari package caret.

Note: jangan lupa untuk melakukan explicit coercion as.factor bila data kita belum dalam bentuk faktor.

# your code here
caret::confusionMatrix(data = pred_tuning, 
                       reference = sign_test$label %>% as.factor())
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
##         0  331   0   0   0   0   0   0   0   0   0   0   0  42   0   0   0   0
##         1    0 391   0   4   0   0   0   0   0   0   0   0   0   0   0   0   0
##         2    0   0 310   0   0  20   0   0   0   0   0   0   0   0   0   0   0
##         3    0   0   0 204   0   0   0   0   2   0   0   0   0   0   0   0   0
##         4    0   0   0   0 495   0   0   0   0   0   0  13   0  19   0   0   0
##         5    0   0   0   0   0 224   0   0   0  21   0   0   0  21   0   0   0
##         6    0   0   0   0   0   0 284  21   0   0   0   0   0   0   0   0   0
##         7    0   0   0   0   0   0   4 413   0   0   0   0   0   5   0   0   0
##         8    0   0   0   0   0   0   0   0 262   2   0   0   1   0   0   0   0
##         9    0  21   0   0   0   0   0   0   0 190   0   0   0   0   0   0   0
##         10   0   0   0   0   0   2   0   0   0   0 188   0   0   0   0   0   0
##         11   0   0   0   0   0   0  21   0   0   0   0 312   5   0   0  17   0
##         12   0   0   0   0   0   0   0   0   0   0   0  21 179   0   0   0   0
##         13   0   0   0   0   0   0   0   0   0   0   0   0  21 153   0   0   0
##         14   0   0   0   0   0   0   0   0   0   0   0   0   0   0 347   0   0
##         15   0   0   0   0   0   0  20   0   1   0   0   0  22  15   0 147   0
##         16   0   0   0   2   0   0   0   0   0  41   0   0   0   0   0   0 104
##         17   0   0   0   0   3   0   0   0   0   0   0  48   0   0   0   0   0
##         18   0   0   0   0   0   0  19   0   7   0   0   0  21  33   0   0   0
##         19   0  20   0   0   0   0   0   2   0  20   0   0   0   0   0   0  19
##         20   0   0   0   0   0   0   0   0   0  21   0   0   0   0   0   0  21
##         21   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0
##         22   0   0   0  35   0   0   0   0   0   0  21   0   0   0   0   0   0
##         23   0   0   0   0   0   0   0   0  16  36   0   0   0   0   0   0   0
##           Reference
## Prediction  17  18  19  20  21  22  23
##         0    0   0   0   0   0   0   0
##         1    0   0   0   0   0   0   0
##         2    0   0   0   0   0   0   0
##         3   21   0  18   0   0   0   0
##         4   21   0   0   0   0   0   0
##         5    0   0   0  20   0   0   0
##         6    0   0   0  16   0   0   0
##         7    0   0   0   0   0   0   0
##         8   21   0   0   0   0   0  19
##         9    0   0  21   0   0   0   0
##         10   0  20   0   0   0   0  21
##         11  55   0   0   0   0   0   0
##         12   0   0   0   0   0   0   0
##         13   0   0   0   0   0   0   0
##         14   0   0   0  20   0   0   0
##         15   1   0   0   0   0   0   0
##         16   0   0  21   0  18   0  27
##         17 127   0   0   0   0   0   4
##         18   0 166   0  19   0   0  21
##         19   0   0 179   0  20   0   0
##         20   0   0   5 222   0   0  18
##         21   0   0   0  49 168  20   0
##         22   0  62   0   0   0 247   0
##         23   0   0  22   0   0   0 222
## 
## Overall Statistics
##                                           
##                Accuracy : 0.8178          
##                  95% CI : (0.8086, 0.8266)
##     No Information Rate : 0.0694          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.8093          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
## Sensitivity           1.00000  0.90509  1.00000  0.83265  0.99398  0.90688
## Specificity           0.99386  0.99941  0.99709  0.99408  0.99206  0.99105
## Pos Pred Value        0.88740  0.98987  0.93939  0.83265  0.90328  0.78322
## Neg Pred Value        1.00000  0.99395  1.00000  0.99408  0.99955  0.99666
## Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
## Detection Rate        0.04615  0.05452  0.04322  0.02844  0.06902  0.03123
## Detection Prevalence  0.05201  0.05508  0.04601  0.03416  0.07641  0.03988
## Balanced Accuracy     0.99693  0.95225  0.99854  0.91337  0.99302  0.94896
##                      Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11
## Sensitivity           0.81609  0.94725  0.90972  0.57402   0.89952   0.79188
## Specificity           0.99458  0.99866  0.99375  0.99386   0.99382   0.98554
## Pos Pred Value        0.88474  0.97867  0.85902  0.81897   0.81385   0.76098
## Neg Pred Value        0.99066  0.99659  0.99621  0.97968   0.99697   0.98787
## Prevalence            0.04852  0.06079  0.04016  0.04615   0.02914   0.05494
## Detection Rate        0.03960  0.05759  0.03653  0.02649   0.02621   0.04350
## Detection Prevalence  0.04476  0.05884  0.04253  0.03235   0.03221   0.05717
## Balanced Accuracy     0.90533  0.97296  0.95174  0.78394   0.94667   0.88871
##                      Class: 12 Class: 13 Class: 14 Class: 15 Class: 16
## Sensitivity            0.61512   0.62195   1.00000   0.89634   0.72222
## Specificity            0.99695   0.99697   0.99707   0.99158   0.98449
## Pos Pred Value         0.89500   0.87931   0.94550   0.71359   0.48826
## Neg Pred Value         0.98394   0.98671   1.00000   0.99756   0.99425
## Prevalence             0.04057   0.03430   0.04838   0.02287   0.02008
## Detection Rate         0.02496   0.02133   0.04838   0.02050   0.01450
## Detection Prevalence   0.02789   0.02426   0.05117   0.02872   0.02970
## Balanced Accuracy      0.80603   0.80946   0.99853   0.94396   0.85336
##                      Class: 17 Class: 18 Class: 19 Class: 20 Class: 21
## Sensitivity            0.51626   0.66935   0.67293   0.64162   0.81553
## Specificity            0.99206   0.98267   0.98827   0.99048   0.98995
## Pos Pred Value         0.69780   0.58042   0.68846   0.77352   0.70588
## Neg Pred Value         0.98298   0.98809   0.98741   0.98199   0.99452
## Prevalence             0.03430   0.03458   0.03709   0.04824   0.02872
## Detection Rate         0.01771   0.02315   0.02496   0.03095   0.02342
## Detection Prevalence   0.02538   0.03988   0.03625   0.04002   0.03318
## Balanced Accuracy      0.75416   0.82601   0.83060   0.81605   0.90274
##                      Class: 22 Class: 23
## Sensitivity            0.92509   0.66867
## Specificity            0.98291   0.98918
## Pos Pred Value         0.67671   0.75000
## Neg Pred Value         0.99706   0.98400
## Prevalence             0.03723   0.04629
## Detection Rate         0.03444   0.03095
## Detection Prevalence   0.05089   0.04127
## Balanced Accuracy      0.95400   0.82893

Memiliki nilai Akurasi nya kisaran >75% (model sudah lebih baik). Model tuning bisa menjadi lebih baik, dikarenakan ditambahkan hidden layernya, dan jumlah nodes nya.

Conclusion

Dalam memilih model terbaik untuk Neural Network kita, kita harus mempertimbangkan beberapa hal:

  • memilih model yang paling sederhana
  • konsumsi waktu
  • model tidak overfit / underfit, karena kita membutuhkan model yang baik dalam kedua data (train & test)

Jadi model yang baik merupakan model_tuning, karena melakukan prediksi dan memiliki akurasinya kisaran >75%.