Artificial Neural Network (ANN) atau jaringan saraf tiruan merupakan salah satu metode dalam pembelajaran mesin yang terinspirasi dari cara kerja jaringan saraf biologis. ANN terdiri atas unit pemroses sederhana yang disebut neuron dan saling terhubung untuk mempelajari pola dari sekumpulan data. Model ini memungkinkan komputer mengenali hubungan antarvariabel melalui proses pembelajaran berdasarkan data yang diberikan (Haykin, 2009).
Perkembangan ANN diawali dengan pengenalan model matematis neuron buatan oleh McCulloch dan Pitts (1943), yang kemudian dikembangkan menjadi perceptron oleh Rosenblatt (1958). Kemampuan ANN semakin berkembang setelah algoritma backpropagation diperkenalkan secara luas oleh Rumelhart dkk. (1986). Algoritma tersebut memungkinkan jaringan dengan lapisan tersembunyi (hidden layer) dilatih secara lebih efisien untuk mempelajari pola data yang kompleks.
Dalam penerapannya, ANN dapat digunakan untuk menyelesaikan permasalahan regresi maupun klasifikasi. Pada kasus klasifikasi, ANN mempelajari hubungan antara variabel prediktor dan variabel respons kategorik melalui proses penyesuaian bobot antar-neuron berdasarkan data training. Selain itu, ANN mampu menangkap hubungan nonlinear antara variabel tanpa harus menentukan bentuk fungsi hubungan terlebih dahulu (Bishop, 2006; Hastie dkk., 2009). Oleh karena itu pada praktikum kali ini dibahas mengenai “Artificial Neural Network (ANN) untuk regresi dan klasifikasi”.
Berdasarkan latar belakang, rumusan masalah pada penelitian ini, yaitu:
Bagaimana konsep dan cara mengimplementasikan model Artificial Neural Network (ANN) untuk regresi dan klasifikasi menggunakan bahasa pemrograman R?
Bagaimana mengevaluasi performa model ANN menggunakan metrik evaluasi MSE dan MAPE untuk regresi, serta akurasi dan presisi untuk klasifikasi?
Berdasarkan rumusan masalah di atas, tujuan pada penelitian ini, yaitu:
Memahami konsep dan mengimplementasikan model Artificial Neural Network (ANN) untuk regresi dan klasifikasi menggunakan bahasa pemrograman R.
Mengevaluasi performa model ANN menggunakan metrik evaluasi MSE dan MAPE untuk regresi, serta akurasi dan presisi untuk klasifikasi.
Adapun manfaat pada penelitian ini, yaitu:
Dapat memberikan informasi serta pengetahuan tentang Artificial Neural Network (ANN) untuk regresi dan klasifikasi menggunakan program RStudio.
Mengembangkan dan menerapkan wawasan ilmu yang telah diperoleh khususnya tentang Artificial Neural Network (ANN) untuk regresi dan klasifikasi di RStudio.
Lakukan ANN Klasifikasi dengan hidden neuron=c(10, 20, 30) dengan data training 80% dan testing 20% serta data training 60% dan testing 40%, kemudian insterpretasikan masing masing ouput dengan jelas!.
Adapun sistematika penulisan dari praktikum ini adalah:
BAB I PENDAHULUAN
Bab I terdiri dari latar belakang, rumusan masalah, batasan masalah, tujuan penelitian, manfaat penelitian, dan sistematika penulisan.
BAB II TINJAUAN PUSTAKA
Bab ini berisi tentang kajian pustaka yang terdiri dari jurnal-jurnal, buku-buku, dan informasi pendukung tentang Machine Learning pada program R.
BAB III METODE PENELITIAN
Bab ini terdiri dari analisis jenis dan sumber data, variabel penelitian, algoritma penelitian, dan diagram alur.
BAB IV HASIL DAN PEMBAHASAN
Bab ini merupakan tahapan pencapaian hasil yang diperoleh dari analisis data yang dilakukan serta penjelasan dari hasil tersebut di bagian pembahasan.
BAB V KESIMPULAN DAN SARAN
Bab ini merupakan bagian penutup dalam laporan ini berupa penarikan kesimpulan mengenai hasil analisis dari penelitian serta penyampaian saran oleh penulis.
DAFTAR PUSTAKA
LAMPIRAN
Artificial Neural Network (ANN) atau jaringan saraf tiruan adalah model komputasi yang terinspirasi dari cara kerja jaringan saraf biologis, yaitu kumpulan unit pemroses sederhana (neuron) yang saling terhubung dan mampu mempelajari pola dari data (Haykin, 2009). Model matematis neuron buatan pertama kali diperkenalkan oleh McCulloch dan Pitts (1943), kemudian dikembangkan menjadi perceptron oleh Rosenblatt (1958). Kemampuan ANN meningkat secara signifikan setelah algoritma backpropagation dipopulerkan oleh Rumelhart dkk. (1986) sehingga jaringan dengan lapisan tersembunyi (hidden layer) dapat dilatih secara efisien.
ANN dapat digunakan untuk kasus regresi maupun klasifikasi. Pada kasus klasifikasi, ANN mempelajari hubungan antara sekumpulan variabel prediktor dan variabel respon kategorik melalui penyesuaian bobot-bobot koneksi antar-neuron berdasarkan data training (Bishop, 2006; Hastie dkk., 2009). Salah satu keunggulan ANN adalah kemampuannya menangkap hubungan nonlinear antara prediktor dan respon tanpa perlu menetapkan bentuk fungsi hubungan terlebih dahulu. Namun, ANN sering disebut sebagai model black box karena bobot yang dihasilkan sulit ditafsirkan secara langsung (Olden & Jackson, 2002).
Arsitektur ANN yang paling umum digunakan adalah Multilayer Perceptron (MLP) dengan jenis feedforward, yaitu informasi mengalir satu arah dari lapisan masukan (input layer), melalui satu atau lebih hidden layer, menuju lapisan keluaran (output layer) tanpa adanya siklus (Haykin, 2009). Pada penelitian ini digunakan MLP dengan satu hidden layer sebagaimana yang disediakan oleh package nnet (Venables & Ripley, 2002). Misalkan terdapat \(p\) prediktor, \(H\) hidden neuron, dan \(K\) kelas respon, maka struktur jaringan dinyatakan sebagai \(p\)-\(H\)-\(K\).
Setiap hidden neuron ke-\(j\) menerima kombinasi linear dari seluruh prediktor, kemudian mentransformasikannya dengan fungsi aktivasi \(f(\cdot)\) (Bishop, 2006):
\[ a_j = w_{j0} + \sum_{m=1}^{p} w_{jm}\, x_m, \qquad z_j = f(a_j), \qquad j = 1, 2, \dots, H \]
dengan \(x_m\) adalah prediktor ke-\(m\), \(w_{jm}\) adalah bobot dari prediktor ke-\(m\) menuju hidden neuron ke-\(j\), dan \(w_{j0}\) adalah bias. Selanjutnya, setiap output neuron ke-\(k\) menerima kombinasi linear dari seluruh keluaran hidden neuron:
\[ a_k = v_{k0} + \sum_{j=1}^{H} v_{kj}\, z_j, \qquad k = 1, 2, \dots, K \]
dengan \(v_{kj}\) adalah bobot dari hidden neuron ke-\(j\) menuju output neuron ke-\(k\) dan \(v_{k0}\) adalah bias. Pada kasus klasifikasi dengan \(K\) kelas, jumlah output neuron sama dengan jumlah kelas, dan nilai keluaran \(a_k\) ditransformasikan menjadi peluang kelas menggunakan fungsi softmax (Bishop, 2006). Banyaknya parameter (bobot dan bias) yang harus diestimasi pada jaringan ini adalah:
\[ n_w = H\,(p+1) + K\,(H+1) \]
Jumlah parameter bertambah seiring bertambahnya jumlah hidden neuron, sehingga kompleksitas model juga meningkat. Secara teoretis, MLP dengan satu hidden layer dan jumlah hidden neuron yang cukup dapat mendekati fungsi kontinu apa pun dengan ketelitian yang diinginkan (Cybenko, 1989; Hornik dkk., 1989), sehingga satu hidden layer sudah memadai untuk banyak kasus.
Fungsi aktivasi menentukan keluaran suatu neuron dari masukan yang diterimanya, dan fungsi yang bersifat nonlinear memungkinkan jaringan mempelajari hubungan yang kompleks (Goodfellow dkk., 2016). Fungsi aktivasi yang digunakan pada penelitian ini adalah sebagai berikut (Bishop, 2006; Venables & Ripley, 2002).
\[ f(a) = \frac{1}{1+e^{-a}}, \qquad f'(a) = f(a)\,\bigl(1 - f(a)\bigr) \]
Fungsi ini memetakan masukan ke interval \((0,1)\) dan turunannya mudah dihitung sehingga mempermudah proses pelatihan.
\[ y_k = \frac{\exp(a_k)}{\sum_{l=1}^{K}\exp(a_l)}, \qquad \sum_{k=1}^{K} y_k = 1 \]
Nilai \(y_k\) dapat ditafsirkan sebagai peluang bahwa suatu observasi termasuk dalam kelas ke-\(k\). Kelas prediksi ditentukan sebagai kelas dengan peluang terbesar, yaitu \(\hat{c} = \arg\max_k\, y_k\).
Pada klasifikasi dengan fungsi softmax, bobot jaringan diestimasi dengan meminimumkan fungsi cross-entropy (negative log-likelihood) yang setara dengan memaksimumkan likelihood bersyarat (Bishop, 2006; Venables & Ripley, 2002). Misalkan \(t_{ik} = 1\) jika observasi ke-\(i\) berasal dari kelas ke-\(k\) dan \(t_{ik} = 0\) untuk lainnya, maka:
\[ E(\mathbf{w}) = -\sum_{i=1}^{n}\sum_{k=1}^{K} t_{ik}\,\ln y_{ik} \]
dengan \(n\) adalah jumlah observasi training dan \(y_{ik}\) adalah peluang kelas ke-\(k\) untuk observasi ke-\(i\) yang dihasilkan jaringan.
Jaringan dengan banyak parameter dapat menghasilkan bobot yang sangat besar dan menyesuaikan diri terlalu jauh terhadap data training. Salah satu cara mengendalikannya adalah regularisasi berupa penalti bobot (weight decay), yaitu menambahkan penalti jumlah kuadrat bobot pada fungsi error (Krogh & Hertz, 1992; Venables & Ripley, 2002):
\[ E_{\lambda}(\mathbf{w}) = E(\mathbf{w}) + \lambda \sum_{r} w_r^{2} \]
dengan \(\lambda \geq 0\) adalah parameter penalti dan \(w_r\) adalah seluruh bobot jaringan. Nilai \(\lambda = 0\) berarti tidak ada penalti, sedangkan nilai \(\lambda\) yang lebih besar mendorong bobot menjadi lebih kecil sehingga fungsi yang dihasilkan lebih halus (Krogh & Hertz, 1992).
Pelatihan jaringan bertujuan menemukan bobot yang meminimumkan fungsi error. Karena fungsi error bersifat nonlinear terhadap bobot, solusi tidak dapat diperoleh secara analitik sehingga digunakan metode optimasi iteratif. Pada pendekatan gradien turun (gradient descent), bobot diperbarui searah dengan negatif gradien fungsi error (Bishop, 2006):
\[ \mathbf{w}^{(t+1)} = \mathbf{w}^{(t)} - \eta\, \nabla E\bigl(\mathbf{w}^{(t)}\bigr) \]
dengan \(\eta\) adalah learning rate. Gradien dihitung secara efisien menggunakan algoritma backpropagation (Rumelhart dkk., 1986). Untuk fungsi softmax dengan cross-entropy, galat pada output neuron ke-\(k\) dan hidden neuron ke-\(j\) untuk satu observasi berturut-turut adalah:
\[ \delta_k = y_k - t_k, \qquad \delta_j = f'(a_j)\sum_{k=1}^{K} v_{kj}\,\delta_k \]
sehingga turunan parsial fungsi error terhadap bobot menjadi:
\[ \frac{\partial E}{\partial v_{kj}} = \delta_k\, z_j, \qquad \frac{\partial E}{\partial w_{jm}} = \delta_j\, x_m \]
Galat dihitung dari output layer kemudian dirambatkan mundur
ke hidden layer, sehingga algoritma ini disebut
backpropagation (Rumelhart dkk., 1986). Fungsi
nnet pada R tidak menggunakan gradient descent
sederhana, melainkan metode quasi-Newton BFGS
(Broyden-Fletcher-Goldfarb-Shanno) yang menggunakan gradien hasil
backpropagation (Venables & Ripley, 2002). Pembaruan bobot
pada metode ini adalah:
\[ \mathbf{w}^{(t+1)} = \mathbf{w}^{(t)} - \alpha_t\, \mathbf{B}_t\, \nabla E\bigl(\mathbf{w}^{(t)}\bigr) \]
dengan \(\alpha_t\) adalah ukuran langkah yang ditentukan melalui pencarian garis (line search) dan \(\mathbf{B}_t\) adalah hampiran invers matriks Hessian yang diperbarui pada setiap iterasi (Nocedal & Wright, 2006). Metode ini umumnya konvergen lebih cepat dibandingkan gradient descent. Karena fungsi error tidak konveks, hasil pelatihan bergantung pada bobot awal sehingga solusi yang diperoleh dapat berupa minimum lokal dan berbeda pada setiap pelatihan (Bishop, 2006).
Algoritma ANN dengan satu hidden layer untuk klasifikasi adalah sebagai berikut (Bishop, 2006; Venables & Ripley, 2002).
Tentukan arsitektur jaringan, yaitu jumlah hidden neuron (\(H\)), fungsi aktivasi, jumlah iterasi maksimum, dan parameter penalti (\(\lambda\)).
Inisialisasi seluruh bobot dan bias secara acak dari sebaran uniform pada interval \([-r, r]\), dengan \(r = 0{,}5\) sebagai nilai bawaan package nnet.
Untuk setiap iterasi \(t = 1, 2, \dots\) hingga konvergen atau mencapai iterasi maksimum:
Lakukan perambatan maju (forward propagation) untuk menghitung \(z_j\) dan \(y_{ik}\) pada seluruh observasi training.
Hitung fungsi error \(E(\mathbf{w})\) beserta penalti bobot apabila digunakan.
Hitung gradien \(\nabla E(\mathbf{w})\) dengan backpropagation.
Perbarui bobot menggunakan metode optimasi (BFGS pada nnet).
Keluarkan bobot akhir jaringan.
Prediksi kelas untuk observasi baru \(\mathbf{x}\) ditentukan sebagai:
\[ \hat{c}(\mathbf{x}) = \arg\max_{k}\; y_k(\mathbf{x}) \]
Proses pelatihan berhenti apabila perubahan nilai fungsi error sudah sangat kecil atau jumlah iterasi telah mencapai batas maksimum (maxit).
Kinerja ANN dipengaruhi oleh beberapa parameter berikut (Haykin, 2009; Venables & Ripley, 2002).
Jumlah hidden neuron (\(H\)) menentukan kapasitas atau kompleksitas model. Jumlah hidden neuron yang terlalu sedikit membuat model tidak mampu menangkap pola data (underfitting), sedangkan jumlah yang terlalu banyak membuat model terlalu menyesuaikan diri dengan data training (overfitting) (Hastie dkk., 2009). Tidak ada aturan baku untuk menentukan nilai \(H\) yang optimal sehingga umumnya dilakukan dengan membandingkan beberapa nilai, seperti \(H = 10;\ 20;\ 30\) pada penelitian ini.
Jumlah iterasi maksimum (\(maxit\)) membatasi banyaknya iterasi pada proses optimasi. Nilai yang terlalu kecil dapat menghentikan pelatihan sebelum konvergen, sedangkan nilai yang terlalu besar memperpanjang waktu komputasi.
Penalti bobot (\(decay\) atau \(\lambda\)) mengendalikan besarnya bobot jaringan. Nilai bawaan pada package nnet adalah 0 sehingga tidak ada regularisasi kecuali ditentukan oleh pengguna (Venables & Ripley, 2002).
Bobot awal dibangkitkan secara acak sehingga hasil pelatihan dapat berbeda pada setiap eksekusi. Agar hasil dapat direproduksi, digunakan penetapan seed pada pembangkitan bilangan acak.
Skala prediktor memengaruhi proses pelatihan. Prediktor dengan rentang nilai yang sangat berbeda sebaiknya diskalakan terlebih dahulu agar optimasi lebih stabil (Haykin, 2009; Venables & Ripley, 2002).
Untuk menilai kemampuan model memprediksi data baru, data dibagi menjadi data training untuk membangun model dan data testing untuk mengevaluasi model (James dkk., 2021). Proporsi pembagian data memengaruhi hasil evaluasi. Data training yang lebih besar memberikan informasi yang lebih banyak bagi model, sedangkan data testing yang lebih besar membuat penilaian kinerja model lebih andal (Hastie dkk., 2009). Pada penelitian ini dibandingkan dua proporsi, yaitu 80:20 dan 60:40.
Overfitting terjadi ketika model memiliki kinerja yang sangat baik pada data training tetapi menurun pada data testing, karena model mempelajari noise pada data training (Hastie dkk., 2009). Risiko ini meningkat apabila jumlah parameter \(n_w\) besar dibandingkan jumlah observasi training \(n\). Penalti bobot, pembatasan jumlah hidden neuron, dan evaluasi pada data testing merupakan cara untuk mendeteksi dan mengendalikan overfitting (Bishop, 2006).
Package NeuralNetTools menyediakan fungsi untuk memvisualisasikan dan menganalisis ANN yang dibangun dengan nnet (Beck, 2018). Fungsi plotnet() menampilkan diagram jaringan dengan ketebalan garis yang menunjukkan besarnya bobot dan warna garis yang menunjukkan tanda bobot, sedangkan fungsi neuralweights() menampilkan struktur jaringan dan seluruh bobot koneksi (Beck, 2018).
Kepentingan variabel pada ANN dapat dihitung menggunakan algoritma Olden, yang dikenal sebagai metode bobot koneksi (connection weights) (Olden dkk., 2004). Kepentingan prediktor ke-\(m\) terhadap output neuron ke-\(k\) dihitung dengan menjumlahkan hasil kali bobot dari prediktor menuju hidden neuron dan bobot dari hidden neuron menuju output neuron pada seluruh hidden neuron:
\[ VI_{mk} = \sum_{j=1}^{H} w_{jm}\, v_{kj} \]
Berbeda dengan ukuran kepentingan yang menggunakan nilai mutlak bobot, metode ini mempertahankan tanda bobot sehingga arah pengaruh prediktor dapat ditafsirkan (Olden dkk., 2004). Nilai \(VI_{mk}\) yang positif menunjukkan bahwa peningkatan prediktor cenderung meningkatkan keluaran kelas ke-\(k\), sedangkan nilai negatif menunjukkan sebaliknya. Semakin besar nilai mutlak \(VI_{mk}\), semakin besar pengaruh prediktor tersebut. Nilai ini tidak memiliki satuan baku dan bergantung pada bobot yang dihasilkan dari inisialisasi acak, sehingga yang ditafsirkan adalah arah dan urutan kepentingannya (Olden & Jackson, 2002). Karena dihitung untuk satu output neuron dalam satu waktu, pada kasus klasifikasi dengan tiga kelas perlu dilakukan perhitungan terpisah untuk masing-masing kelas.
Kinerja model klasifikasi pada data testing dievaluasi menggunakan tabel klasifikasi (confusion matrix) yang membandingkan kelas aktual dengan kelas prediksi (Sokolova & Lapalme, 2009). Misalkan \(n_{kl}\) adalah banyaknya observasi dengan kelas aktual ke-\(k\) yang diprediksi sebagai kelas ke-\(l\), maka tabel klasifikasi untuk \(K = 3\) kelas disajikan sebagai berikut.
| Kelas Aktual | Prediksi Kelas 1 | Prediksi Kelas 2 | Prediksi Kelas 3 |
|---|---|---|---|
| Kelas 1 | \(n_{11}\) | \(n_{12}\) | \(n_{13}\) |
| Kelas 2 | \(n_{21}\) | \(n_{22}\) | \(n_{23}\) |
| Kelas 3 | \(n_{31}\) | \(n_{32}\) | \(n_{33}\) |
Observasi yang terklasifikasi dengan benar berada pada diagonal tabel. Ukuran evaluasi yang digunakan adalah classification rate atau akurasi, yaitu proporsi observasi yang terklasifikasi dengan benar, serta kebalikannya yaitu laju kesalahan klasifikasi (misclassification rate) (Hastie dkk., 2009; James dkk., 2021):
\[ Akurasi = \frac{\sum_{k=1}^{K} n_{kk}}{\sum_{k=1}^{K}\sum_{l=1}^{K} n_{kl}}, \qquad Laju\ Kesalahan = 1 - Akurasi \]
Nilai akurasi yang lebih besar menunjukkan kinerja model yang lebih baik. Selain akurasi secara keseluruhan, tabel klasifikasi memungkinkan identifikasi kelas yang sering tertukar, sehingga dapat diketahui kelas mana yang sulit dibedakan oleh model (Sokolova & Lapalme, 2009).
Jenis data pada penelitian ini adalah data kuantitatif. Data kuantitatif adalah jenis data yang berbentuk angka atau bilangan dan dapat diukur atau dihitung secara langsung. Laporan ini memiliki satu batasan masalah yang menggunakan sumber data sekunder. Data sekunder adalah data yang diperoleh secara tidak langsung melalui media perantara. Data didapatkan dari program R secara langsung.
Variabel penelitian adalah karakter atau segala sesuatu yang menjadi perhatian dalam suatu penelitian. Pada batasan masalah terdapat 5 variabel. Variabel tersebut terdiri dari 1 variabel kategorik dan 4 variabel numerik.
Package yang digunakan terdiri atas nnet untuk membangun model Artificial Neural Network (ANN) dengan satu hidden layer melalui fungsi nnet.formula(), serta NeuralNetTools untuk mengeksplorasi model melalui fungsi plotnet() (diagram jaringan), neuralweights() (bobot jaringan), dan olden() (kepentingan variabel).
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
Data yang digunakan adalah data iris yang terdiri atas 150 observasi, empat variabel prediktor numerik (Sepal.Length, Sepal.Width, Petal.Length, dan Petal.Width), serta satu variabel respon kategorik Species dengan tiga kelas, yaitu setosa, versicolor, dan virginica. Setiap kelas terdiri atas 50 observasi sehingga data seimbang. Berdasarkan output, Sepal.Length berkisar antara 4,3 sampai 7,9, Sepal.Width antara 2,0 sampai 4,4, Petal.Length antara 1,0 sampai 6,9, dan Petal.Width antara 0,1 sampai 2,5. Variabel Species diubah menjadi factor agar fungsi nnet membentuk tiga neuron keluaran (satu untuk setiap kelas) dengan fungsi aktivasi softmax.
set.seed(917)
index <- sample(1:nrow(iris), round(0.8*nrow(iris)))
train <- iris[index, ]
test <- iris[-index, ]
nrow(train)## [1] 120
## [1] 30
Pembagian data dilakukan dengan proporsi 80% untuk data training dan 20% untuk data testing. Berdasarkan output, data training terdiri atas 120 observasi, sedangkan data testing terdiri atas 30 observasi. Data training digunakan untuk membangun model ANN, sedangkan data testing digunakan untuk mengevaluasi kemampuan model mengklasifikasikan data baru.
# Membentuk formula ANN
i <- names(train)
form <- as.formula(paste("Species ~",
paste(i[!i %in% "Species"],
collapse = " + ")))
form## Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
# Hidden Neuron = 10
nn10_80 <- nnet.formula(form, size=10, data=train,
maxit=500, trace=FALSE)
# Hidden Neuron = 20
nn20_80 <- nnet.formula(form, size=20, data=train,
maxit=500, trace=FALSE)
# Hidden Neuron = 30
nn30_80 <- nnet.formula(form, size=30, data=train,
maxit=500, trace=FALSE)Formula Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width dibentuk secara otomatis dari nama kolom data training. Model ANN dibangun dengan satu hidden layer dan tiga variasi jumlah hidden neuron, yaitu 10, 20, dan 30. Parameter lain dibuat sama pada seluruh model, yaitu iterasi maksimum (maxit) sebesar 500 dan trace = FALSE untuk menyembunyikan proses iterasi. Karena bobot awal pada nnet dibangkitkan secara acak, hasil model dapat direproduksi hanya jika set.seed(917) dan urutan eksekusi sintaks dijaga sama.
# Hasil Prediksi
pred10_80 <- predict(nn10_80, newdata=test, type="class")
pred20_80 <- predict(nn20_80, newdata=test, type="class")
pred30_80 <- predict(nn30_80, newdata=test, type="class")
# Classification Table
tab10_80 <- table(test$Species, pred10_80)
tab20_80 <- table(test$Species, pred20_80)
tab30_80 <- table(test$Species, pred30_80)
tab10_80## pred10_80
## setosa versicolor virginica
## setosa 8 0 0
## versicolor 0 9 1
## virginica 0 1 11
## pred20_80
## setosa versicolor virginica
## setosa 8 0 0
## versicolor 0 10 0
## virginica 0 1 11
## pred30_80
## setosa versicolor virginica
## setosa 8 0 0
## versicolor 0 9 1
## virginica 0 3 9
Classification table membandingkan kelas aktual (baris) dengan kelas prediksi (kolom). Data testing terdiri atas 8 observasi setosa, 10 versicolor, dan 12 virginica. Kelas setosa diklasifikasikan dengan benar seluruhnya (8 dari 8) oleh ketiga model, sehingga kelas ini mudah dipisahkan dari dua kelas lainnya. Kesalahan hanya terjadi antara versicolor dan virginica. Model dengan 10 hidden neuron melakukan dua kesalahan, yaitu satu versicolor diprediksi virginica dan satu virginica diprediksi versicolor. Model dengan 20 hidden neuron hanya melakukan satu kesalahan, yaitu satu virginica diprediksi versicolor. Model dengan 30 hidden neuron melakukan empat kesalahan, yaitu satu versicolor diprediksi virginica dan tiga virginica diprediksi versicolor.
akurasi10_80 <- sum(diag(tab10_80))/sum(tab10_80)
akurasi20_80 <- sum(diag(tab20_80))/sum(tab20_80)
akurasi30_80 <- sum(diag(tab30_80))/sum(tab30_80)
akurasi10_80## [1] 0.9333333
## [1] 0.9666667
## [1] 0.8666667
Classification rate atau akurasi dihitung dari jumlah observasi yang terklasifikasi benar (diagonal tabel) dibagi total observasi testing. Akurasi model dengan 10 hidden neuron sebesar 0,9333 (28 dari 30 benar), model dengan 20 hidden neuron sebesar 0,9667 (29 dari 30 benar), dan model dengan 30 hidden neuron sebesar 0,8667 (26 dari 30 benar). Akurasi tertinggi pada pembagian 80:20 dicapai oleh model dengan 20 hidden neuron. Penambahan hidden neuron dari 10 ke 20 meningkatkan akurasi, tetapi penambahan lebih lanjut menjadi 30 justru menurunkan akurasi. Penurunan ini mengindikasikan bahwa model yang terlalu kompleks cenderung mengalami overfitting, yaitu terlalu menyesuaikan diri dengan data training sehingga kurang baik pada data testing.
## $struct
## [1] 4 10 3
##
## $wts
## $wts$`hidden 1 1`
## [1] 1.06726456 6.02579879 3.58435581 2.61722607 0.09302509
##
## $wts$`hidden 1 2`
## [1] -23.78216 -129.96791 -73.75457 -65.87689 -16.89498
##
## $wts$`hidden 1 3`
## [1] -10.09659 -70.80396 -18.24671 -70.32151 -20.79378
##
## $wts$`hidden 1 4`
## [1] 0.9298016 0.8899109 -60.6840487 35.2464407 -11.3297577
##
## $wts$`hidden 1 5`
## [1] -0.3751915 -4.5239318 -2.5665981 -1.2674637 -0.4049578
##
## $wts$`hidden 1 6`
## [1] -17.70898 -103.58446 -32.52888 -80.20567 -15.75251
##
## $wts$`hidden 1 7`
## [1] -4.234945 -30.613543 -11.858623 -27.454230 -10.246427
##
## $wts$`hidden 1 8`
## [1] -1.1071129 -2.0080092 -2.0655861 -0.2676582 0.6936009
##
## $wts$`hidden 1 9`
## [1] 3.0310913 12.7068149 9.2031997 0.3577667 -2.5222209
##
## $wts$`hidden 1 10`
## [1] -1.9925299 -0.2205364 -1.7837034 1.4805142 1.2841008
##
## $wts$`out 1`
## [1] 27.4356094 27.1113932 -108.6239714 18.9781002 0.7722167
## [6] 3.4412599 48.3884224 8.2315168 -1.8355795 26.2234363
## [11] -223.3416504
##
## $wts$`out 2`
## [1] 22.928419 21.903611 30.538796 13.841246 35.972000 -1.334019
## [7] 104.710738 1.365742 1.056413 20.706990 -55.921760
##
## $wts$`out 3`
## [1] -51.5408366 -49.9309003 77.8802653 -33.0628153 -36.5352752
## [6] -2.2183761 -153.9532606 -9.5698635 -0.6958858 -46.6576486
## [11] 279.3123189
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning: `label` cannot be a <ggplot2::element_blank> object.
## $struct
## [1] 4 20 3
##
## $wts
## $wts$`hidden 1 1`
## [1] 0.1034536 -13.2452559 -5.9004354 -8.9292308 -5.3818404
##
## $wts$`hidden 1 2`
## [1] 28.72969 54.73490 163.35544 -117.30840 -167.42736
##
## $wts$`hidden 1 3`
## [1] -4.724197 -34.000518 -15.652907 -30.558396 -10.981999
##
## $wts$`hidden 1 4`
## [1] -0.6664453 -2.3048541 -1.2839978 -2.4593526 -1.4293265
##
## $wts$`hidden 1 5`
## [1] -5.708173 -9.563393 -20.144039 36.550237 17.522380
##
## $wts$`hidden 1 6`
## [1] 3.578248 -4.073421 20.926904 -28.238772 -14.391359
##
## $wts$`hidden 1 7`
## [1] -10.82587 -14.11446 -28.72789 -28.78039 -16.60569
##
## $wts$`hidden 1 8`
## [1] 0.4144843 -1.6158224 0.8268860 -0.4088463 1.5667785
##
## $wts$`hidden 1 9`
## [1] 0.9989025 11.4481109 3.7763263 18.5683737 10.1266755
##
## $wts$`hidden 1 10`
## [1] -5.602341 -31.279779 -20.538810 -11.865092 -2.734102
##
## $wts$`hidden 1 11`
## [1] 18.70283208 2.03083123 -0.08884399 -5.47610222 -2.60448443
##
## $wts$`hidden 1 12`
## [1] -5.209863 -34.796128 -14.070210 -38.114588 -16.305293
##
## $wts$`hidden 1 13`
## [1] 5.064016 28.568713 14.097918 19.340234 5.869643
##
## $wts$`hidden 1 14`
## [1] -8.158099 -37.782436 -21.534474 38.483479 32.752964
##
## $wts$`hidden 1 15`
## [1] -4.633493 -7.218354 31.991676 -38.506502 89.205302
##
## $wts$`hidden 1 16`
## [1] -2.676142 -18.384412 -8.484254 -13.352505 -4.338376
##
## $wts$`hidden 1 17`
## [1] 0.149920 -8.576454 -6.412283 -4.005952 -2.924393
##
## $wts$`hidden 1 18`
## [1] -3.432004 -34.783132 -14.471563 -49.837734 -25.099377
##
## $wts$`hidden 1 19`
## [1] -0.2747915 -0.8567218 -0.1596983 -0.4473712 0.2456173
##
## $wts$`hidden 1 20`
## [1] 2.010438 20.201407 25.249829 -42.619311 12.996722
##
## $wts$`out 1`
## [1] 10.8968324 2.7626567 20.9108245 -17.0986722 -0.3796533 -41.2688132
## [7] 67.2575064 -2.6673525 0.7843240 4.8243378 -19.4130989 23.8442385
## [13] -19.6264755 -16.5368526 -9.8135037 12.5220527 0.4147327 -1.8539304
## [19] -14.8109471 -0.7871256 25.5569636
##
## $wts$`out 2`
## [1] -2.32068306 -2.42110913 87.29853388 0.52687341 0.08157332
## [6] 42.12083034 -1.49575918 12.47090647 -2.65973589 -33.21236770
## [11] -0.82605880 63.63626269 -10.62690726 4.38555652 -13.32984496
## [16] -34.05630682 4.58778058 -0.90895303 2.50373521 0.21673796
## [21] -38.63017851
##
## $wts$`out 3`
## [1] -8.9624994 -0.3694159 -108.9891852 16.9804728 0.7802141
## [6] -1.6582082 -66.0539788 -10.9381961 1.3538604 28.8650283
## [11] 20.4367703 -88.6141655 31.0147526 11.5663892 22.6761286
## [16] 21.0389942 -5.0998305 3.4088207 13.4006520 0.7859415
## [21] 13.9811220
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## `label` cannot be a <ggplot2::element_blank> object.
## $struct
## [1] 4 30 3
##
## $wts
## $wts$`hidden 1 1`
## [1] -0.2315508 -0.1306067 -1.0161073 0.7353925 0.2207270
##
## $wts$`hidden 1 2`
## [1] -2.005898 4.554942 -2.085613 21.897357 14.235021
##
## $wts$`hidden 1 3`
## [1] 0.6336213 3.0813647 1.4296814 1.2151953 -0.5916313
##
## $wts$`hidden 1 4`
## [1] -0.5566874 -1.2361570 -0.6194176 -0.7488378 -0.5890168
##
## $wts$`hidden 1 5`
## [1] -1.102689 -3.927922 -4.615044 1.311047 1.378031
##
## $wts$`hidden 1 6`
## [1] 0.6612499 0.8216009 0.4276704 1.3113028 0.5430076
##
## $wts$`hidden 1 7`
## [1] 2.096716 2.920463 7.985564 -11.618752 -6.962408
##
## $wts$`hidden 1 8`
## [1] 0.02747873 0.62281921 1.11380414 -0.04279990 0.41909714
##
## $wts$`hidden 1 9`
## [1] 0.7157666 10.1414926 4.8989459 8.8719416 3.9535415
##
## $wts$`hidden 1 10`
## [1] 1.43488516 0.05854698 -1.00586264 -2.29899976 -3.21131592
##
## $wts$`hidden 1 11`
## [1] -5.3759729 -1.7054565 1.9669109 5.2574670 -0.1989798
##
## $wts$`hidden 1 12`
## [1] 80.593239 8.396406 42.625856 -52.751153 -3.191807
##
## $wts$`hidden 1 13`
## [1] 0.6331914 3.3088309 2.7344170 1.3429829 0.8646302
##
## $wts$`hidden 1 14`
## [1] -0.6303463 -2.5211278 -1.6242312 -1.7524379 -1.9356748
##
## $wts$`hidden 1 15`
## [1] -1.537248 6.438024 0.624004 -7.443508 -5.447682
##
## $wts$`hidden 1 16`
## [1] -0.55300928 -3.60449775 -1.80704741 -2.31511524 0.02832629
##
## $wts$`hidden 1 17`
## [1] 3.985550 4.409821 11.028031 -13.640669 -7.346844
##
## $wts$`hidden 1 18`
## [1] 47.270966 2.955718 -32.949430 -4.760636 31.461740
##
## $wts$`hidden 1 19`
## [1] -2.763830 -11.723549 -7.382773 3.153461 6.206939
##
## $wts$`hidden 1 20`
## [1] -0.4827200 -1.7124542 -0.8563124 -0.6300419 -0.5901004
##
## $wts$`hidden 1 21`
## [1] -5.497302 -13.001951 -5.234048 -10.963722 -1.475288
##
## $wts$`hidden 1 22`
## [1] -1.5094789 -9.1537530 -6.5266978 -3.6447741 -0.9688703
##
## $wts$`hidden 1 23`
## [1] 88.165018 -2.932504 -3.360723 13.740776 -77.427213
##
## $wts$`hidden 1 24`
## [1] 0.09458406 0.83821505 0.16202623 2.04566634 -0.06761230
##
## $wts$`hidden 1 25`
## [1] -3.23784567 -1.58310750 13.07428280 -0.03234521 -13.01968325
##
## $wts$`hidden 1 26`
## [1] -2.005148 -3.890138 9.288910 2.963918 -7.013086
##
## $wts$`hidden 1 27`
## [1] 2.128784 3.494954 11.127202 -16.186604 -7.759024
##
## $wts$`hidden 1 28`
## [1] -0.6053425 -0.1776375 -0.3384153 -0.3095718 -0.2284379
##
## $wts$`hidden 1 29`
## [1] 1.397995 2.283818 6.800293 -13.076329 -6.490727
##
## $wts$`hidden 1 30`
## [1] 3.398831 5.799557 7.110578 -10.915549 -8.988586
##
## $wts$`out 1`
## [1] -2.54224157 -3.85385134 -5.05047707 -3.68235964 0.04701691
## [6] -10.92312953 -2.83974071 6.37557033 -3.10605430 1.91025893
## [11] 6.69138738 -4.23767539 21.53359582 7.41146370 -1.49139667
## [16] 5.80759418 -0.28790286 14.94422004 3.70283539 -0.33964279
## [21] 0.55734717 -4.23473702 -6.96626743 -21.96352694 -2.51948307
## [26] -6.10006526 -2.96615743 20.69301913 0.31609250 16.70082345
## [31] 16.71929746
##
## $wts$`out 2`
## [1] 0.94653039 1.98100608 -11.78988402 2.37707214 -0.38835920
## [6] 2.76009891 2.06080402 0.18344583 1.25848104 -0.11853482
## [11] -1.67065678 -6.50294420 30.79916874 -0.69775503 -0.10826000
## [16] 4.14535293 0.02126707 -12.11964665 14.10563285 0.14250716
## [21] 1.10947976 -3.39987809 1.25695822 34.19413485 -1.56418861
## [26] -5.98988107 -1.13622746 -17.40625859 -0.10666824 -14.87442831
## [31] 4.52389856
##
## $wts$`out 3`
## [1] 1.3665979 1.3926632 17.8474825 1.8029866 0.1198027 9.1824070
## [7] 0.7751408 -5.5422612 2.2523142 -1.4977884 -3.8223263 9.2990593
## [13] -52.5821713 -6.7715319 1.4029850 -10.4007165 -0.3264561 -2.2837892
## [19] -17.0674699 0.5029944 -0.7488545 7.7086929 5.5908474 -12.1582405
## [25] 2.9749935 13.3311448 5.1287284 -3.1209311 -0.6657830 -0.5580284
## [31] -20.7042361
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## `label` cannot be a <ggplot2::element_blank> object.
Fungsi plotnet() menampilkan arsitektur jaringan, sedangkan neuralweights() menampilkan struktur dan bobot jaringan. Berdasarkan output, struktur jaringan berturut-turut adalah 4-10-3, 4-20-3, dan 4-30-3, artinya terdapat empat neuron masukan (keempat prediktor), satu hidden layer dengan 10, 20, atau 30 neuron, dan tiga neuron keluaran (tiga kelas Species). Setiap hidden neuron memiliki lima bobot (satu bias dan empat bobot dari prediktor), sedangkan setiap neuron keluaran memiliki bobot sebanyak jumlah hidden neuron ditambah satu bias. Dengan demikian, banyaknya parameter adalah 83 pada model 10 neuron, 163 pada model 20 neuron, dan 243 pada model 30 neuron. Jumlah parameter pada model 20 dan 30 neuron telah melebihi jumlah observasi training (120), sehingga risiko overfitting meningkat. Beberapa bobot bernilai sangat besar, misalnya sekitar -223 sampai 279 pada bobot keluaran model 10 neuron, karena tidak digunakan penalti bobot (decay) pada model. Fungsi olden() menghitung kepentingan variabel dari hasil kali bobot masukan-hidden dan bobot hidden-keluaran yang dijumlahkan pada seluruh hidden neuron. Peringatan Results for first response variable only muncul karena olden() secara default hanya menampilkan kepentingan variabel untuk neuron keluaran pertama, yaitu kelas setosa, sedangkan peringatan label cannot be a ggplot2::element_blank object berkaitan dengan versi ggplot2 dan tidak memengaruhi hasil perhitungan.
set.seed(917)
index <- sample(1:nrow(iris), round(0.6*nrow(iris)))
train <- iris[index, ]
test <- iris[-index, ]
nrow(train)## [1] 90
## [1] 60
Pembagian data berikutnya dilakukan dengan proporsi 60% untuk data training dan 40% untuk data testing. Berdasarkan output, data training terdiri atas 90 observasi, sedangkan data testing terdiri atas 60 observasi. Pembagian ini bertujuan melihat pengaruh ukuran data training terhadap kinerja model ANN.
# Membentuk formula ANN
i <- names(train)
form <- as.formula(paste("Species ~",
paste(i[!i %in% "Species"],
collapse = " + ")))
# Hidden Neuron = 10
nn10_60 <- nnet.formula(form, size=10, data=train,
maxit=500, trace=FALSE)
# Hidden Neuron = 20
nn20_60 <- nnet.formula(form, size=20, data=train,
maxit=500, trace=FALSE)
# Hidden Neuron = 30
nn30_60 <- nnet.formula(form, size=30, data=train,
maxit=500, trace=FALSE)Model ANN dibangun kembali dengan formula dan parameter yang sama seperti pada pembagian 80:20, yaitu hidden neuron sebanyak 10, 20, dan 30 serta maxit = 500, tetapi menggunakan data training yang lebih sedikit (90 observasi). Dengan jumlah parameter yang tetap (83, 163, dan 243), rasio parameter terhadap observasi menjadi lebih besar sehingga model dengan hidden neuron banyak lebih rentan terhadap overfitting.
# Hasil Prediksi
pred10_60 <- predict(nn10_60, newdata=test, type="class")
pred20_60 <- predict(nn20_60, newdata=test, type="class")
pred30_60 <- predict(nn30_60, newdata=test, type="class")
# Classification Table
tab10_60 <- table(test$Species, pred10_60)
tab20_60 <- table(test$Species, pred20_60)
tab30_60 <- table(test$Species, pred30_60)
tab10_60## pred10_60
## setosa versicolor virginica
## setosa 16 1 0
## versicolor 0 24 0
## virginica 0 3 16
## pred20_60
## setosa versicolor virginica
## setosa 17 0 0
## versicolor 0 23 1
## virginica 0 2 17
## pred30_60
## setosa versicolor virginica
## setosa 17 0 0
## versicolor 0 23 1
## virginica 0 2 17
Data testing terdiri atas 17 observasi setosa, 24 versicolor, dan 19 virginica. Model dengan 10 hidden neuron melakukan empat kesalahan, yaitu satu setosa diprediksi versicolor dan tiga virginica diprediksi versicolor. Model dengan 20 hidden neuron melakukan tiga kesalahan, yaitu satu versicolor diprediksi virginica dan dua virginica diprediksi versicolor. Model dengan 30 hidden neuron menghasilkan tabel yang identik dengan model 20 neuron. Seperti pada pembagian 80:20, kesalahan terbanyak terjadi pada kelas virginica yang diprediksi sebagai versicolor, sehingga kedua kelas ini memiliki karakteristik yang saling berdekatan.
akurasi10_60 <- sum(diag(tab10_60))/sum(tab10_60)
akurasi20_60 <- sum(diag(tab20_60))/sum(tab20_60)
akurasi30_60 <- sum(diag(tab30_60))/sum(tab30_60)
akurasi10_60## [1] 0.9333333
## [1] 0.95
## [1] 0.95
Akurasi model dengan 10 hidden neuron sebesar 0,9333 (56 dari 60 benar), sedangkan model dengan 20 dan 30 hidden neuron sama-sama sebesar 0,9500 (57 dari 60 benar). Pada pembagian 60:40, penambahan hidden neuron dari 10 ke 20 meningkatkan akurasi, sedangkan penambahan dari 20 ke 30 tidak mengubah akurasi. Akurasi pada pembagian ini relatif stabil dan tidak mengalami penurunan pada model 30 neuron seperti yang terjadi pada pembagian 80:20.
## $struct
## [1] 4 10 3
##
## $wts
## $wts$`hidden 1 1`
## [1] 1.203493 9.414182 3.515218 10.657027 4.816662
##
## $wts$`hidden 1 2`
## [1] -4.8869663 -20.6119343 -17.4716780 0.6434631 2.6853660
##
## $wts$`hidden 1 3`
## [1] 7.411466 8.552731 5.951421 -35.098857 -12.225097
##
## $wts$`hidden 1 4`
## [1] -1.386121 -1.339577 -4.966590 12.666866 5.632550
##
## $wts$`hidden 1 5`
## [1] 5.905675 24.081235 18.351724 2.861652 -1.539982
##
## $wts$`hidden 1 6`
## [1] -2.230806 -27.979701 1.131239 -51.602027 -20.316893
##
## $wts$`hidden 1 7`
## [1] -104.581158 -4.910726 -12.015638 18.625894 44.700775
##
## $wts$`hidden 1 8`
## [1] 3.12357769 13.12492723 7.86160848 3.52157393 -0.09624379
##
## $wts$`hidden 1 9`
## [1] -7.796906 -28.162567 -29.142293 15.594295 8.668683
##
## $wts$`hidden 1 10`
## [1] -1.351943 -6.766175 -1.094571 -7.826235 -1.675374
##
## $wts$`out 1`
## [1] 3.2977675 8.8308736 7.5292554 45.3815610 -10.0117653 -1.6682448
## [7] 32.7460988 -37.1577625 -6.6294563 -18.7637055 -0.6045921
##
## $wts$`out 2`
## [1] 13.01262872 1.02097803 -2.51273425 -14.25363791 -1.97079662
## [6] 14.23227471 0.97535690 -43.72876190 16.11797829 12.73900597
## [11] -0.05438727
##
## $wts$`out 3`
## [1] -16.2566975 -10.0080205 -4.7890226 -30.4359227 12.4632460 -13.0154830
## [7] -35.5167346 80.2848124 -9.5644252 6.0119681 0.7373056
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning: `label` cannot be a <ggplot2::element_blank> object.
## $struct
## [1] 4 20 3
##
## $wts
## $wts$`hidden 1 1`
## [1] -0.6287465 -0.8128035 -0.5090926 -0.7408763 -0.2224575
##
## $wts$`hidden 1 2`
## [1] -0.8433706 -5.5519096 -0.6260888 -8.0133605 -2.9345405
##
## $wts$`hidden 1 3`
## [1] -1.433128 -7.099139 -1.742364 -6.685698 -2.390470
##
## $wts$`hidden 1 4`
## [1] 66.222536 3.134495 9.509297 -11.997918 -31.239258
##
## $wts$`hidden 1 5`
## [1] -0.8720629 -6.2046596 -3.9680845 -5.3505402 -2.0293932
##
## $wts$`hidden 1 6`
## [1] -0.2042945 -5.1235475 -1.2420356 -8.1798256 -3.6472442
##
## $wts$`hidden 1 7`
## [1] -1.945201 -7.469006 -4.339010 -2.932525 -1.417402
##
## $wts$`hidden 1 8`
## [1] 2.894669 11.372657 10.152773 -3.657671 -3.750334
##
## $wts$`hidden 1 9`
## [1] -130.9359009 -8.1637541 0.6183632 21.2318286 43.6963702
##
## $wts$`hidden 1 10`
## [1] -0.06725856 -2.97296298 -0.67059399 -2.91565252 -1.93052895
##
## $wts$`hidden 1 11`
## [1] -2.0522140 -8.1141355 -6.5082797 -0.5756315 1.1108201
##
## $wts$`hidden 1 12`
## [1] -3.811892 -20.633785 -11.397285 -12.310170 -2.570651
##
## $wts$`hidden 1 13`
## [1] -0.87875761 -6.07181184 0.03883027 -7.63838012 -3.21700007
##
## $wts$`hidden 1 14`
## [1] -0.5194477 -1.1364342 -1.4261768 0.3772092 -1.5962996
##
## $wts$`hidden 1 15`
## [1] -1.845431 -7.787446 -6.885939 2.954011 2.047225
##
## $wts$`hidden 1 16`
## [1] -2.593323 -9.150229 -7.493117 1.262034 2.298269
##
## $wts$`hidden 1 17`
## [1] -0.3792038 -3.5494215 4.0859437 -12.6849308 -4.1284954
##
## $wts$`hidden 1 18`
## [1] 0.4172708 -0.3417595 -0.6706728 0.1462065 0.3212825
##
## $wts$`hidden 1 19`
## [1] -0.5964533 -6.9855053 -2.4955457 -5.7027534 -1.9807243
##
## $wts$`hidden 1 20`
## [1] 2.822296 4.432399 9.824383 -18.624955 -9.527275
##
## $wts$`out 1`
## [1] -14.27146584 0.52332707 5.39584246 0.13060116 8.30521610
## [6] -0.91297871 0.29904582 -7.07070050 4.69396200 -19.92516681
## [11] 1.89792983 1.56848179 -4.60644620 2.06938526 3.67031567
## [16] -8.64450705 -18.58043728 13.85047609 0.08381386 -2.13507539
## [21] 51.30846810
##
## $wts$`out 2`
## [1] 21.6591647 0.4373488 7.9282345 3.0165338 29.4142897 1.6115240
## [7] -3.3674594 8.5763886 -4.8649451 -30.9627738 -1.5613408 -1.2751313
## [13] 1.7650630 0.7563924 -1.8270569 -3.0743987 8.2378039 -5.6649628
## [19] 0.2771054 -0.6849680 -44.1304905
##
## $wts$`out 3`
## [1] -8.4846375 -0.2237447 -14.0907648 -3.8636483 -38.2276355 -1.2286426
## [7] 3.4851676 -1.5929094 1.0807604 51.2104113 -1.1723413 -0.6266511
## [13] 1.9105490 -2.5290856 -2.6195506 10.9313006 10.1177481 -7.9160355
## [19] -0.7359874 2.1088895 -7.0493154
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## `label` cannot be a <ggplot2::element_blank> object.
## $struct
## [1] 4 30 3
##
## $wts
## $wts$`hidden 1 1`
## [1] -4.631233 -19.915214 -10.800243 -1.657430 5.754285
##
## $wts$`hidden 1 2`
## [1] -0.25537763 0.04253309 -0.36812006 -3.76351448 -2.54697496
##
## $wts$`hidden 1 3`
## [1] 67.765366 4.540968 2.359403 -11.781779 -25.996143
##
## $wts$`hidden 1 4`
## [1] 0.8188641 -7.3382456 -8.8245824 -8.4651392 -11.0965362
##
## $wts$`hidden 1 5`
## [1] -9.5484984 0.4991055 -2.0837332 4.7983936 -0.9079915
##
## $wts$`hidden 1 6`
## [1] 0.05406194 0.66396314 -0.46424653 1.64023848 0.76813566
##
## $wts$`hidden 1 7`
## [1] 0.07655632 0.09565882 0.31971347 0.18524102 0.23911776
##
## $wts$`hidden 1 8`
## [1] 5.874799 1.247557 10.183654 -9.665221 -11.930367
##
## $wts$`hidden 1 9`
## [1] 0.04185895 -4.56456643 -2.37036027 -3.73433228 -1.97842278
##
## $wts$`hidden 1 10`
## [1] 55.8259147 -0.6640155 3.6328639 -6.3637184 -17.5909100
##
## $wts$`hidden 1 11`
## [1] 2.20550407 0.08797341 -0.92181940 -0.06198390 -0.70162385
##
## $wts$`hidden 1 12`
## [1] 1.709272 17.070380 8.284099 17.712700 8.332383
##
## $wts$`hidden 1 13`
## [1] 6.311847 13.740818 7.038694 -14.910816 -18.952259
##
## $wts$`hidden 1 14`
## [1] -2.057892 -0.821072 -4.409593 3.294697 4.664600
##
## $wts$`hidden 1 15`
## [1] 0.87514193 1.96981139 2.01131222 -0.08093905 0.42269857
##
## $wts$`hidden 1 16`
## [1] 2.6750212 -2.4387062 -1.2150427 -0.2671418 1.7904840
##
## $wts$`hidden 1 17`
## [1] 1.51692164 -0.94217856 -1.21847751 0.02209224 -1.62893167
##
## $wts$`hidden 1 18`
## [1] 3.2535508 2.6104356 1.5101930 1.0165645 -0.8310034
##
## $wts$`hidden 1 19`
## [1] 0.6513032 -2.1513904 -10.7611161 9.9649218 -4.2917525
##
## $wts$`hidden 1 20`
## [1] 0.8250099 0.2129248 1.1106362 -0.6375225 -0.7133911
##
## $wts$`hidden 1 21`
## [1] 1.24864811 1.00001870 0.05880687 -5.08731091 -5.84454319
##
## $wts$`hidden 1 22`
## [1] -0.4326851 -12.3422322 -8.0782252 -14.8014021 -11.4868772
##
## $wts$`hidden 1 23`
## [1] -0.2307815 1.7121388 1.2289920 1.2775451 0.1299119
##
## $wts$`hidden 1 24`
## [1] -0.8953310 -1.4542690 -0.9952448 -0.8831344 0.3980916
##
## $wts$`hidden 1 25`
## [1] -1.738973 -6.599601 -2.975026 -1.587027 -0.521345
##
## $wts$`hidden 1 26`
## [1] 8.99072995 4.76546276 0.09868662 -2.26220393 -21.86621733
##
## $wts$`hidden 1 27`
## [1] -1.596447 -2.198319 -5.105516 7.095601 3.797876
##
## $wts$`hidden 1 28`
## [1] 4.5726910 0.7958263 -3.8745578 -0.8402561 1.4660442
##
## $wts$`hidden 1 29`
## [1] -1.5626490 0.1880945 0.1659845 0.3311872 1.0567544
##
## $wts$`hidden 1 30`
## [1] 11.6653620 -0.6572963 2.2301569 -3.2693068 -11.8364297
##
## $wts$`out 1`
## [1] 1.10710351 -10.38178754 -3.36040739 15.05004627 -0.75066997
## [6] 0.42233638 2.26221169 0.76141738 14.91769137 -3.82150042
## [11] 8.02669596 0.53674722 0.95796811 8.28710113 -18.84359340
## [16] -3.76675179 -8.75156649 0.87187773 -2.32916123 -8.39798835
## [21] -0.59057689 2.64566081 -1.10420045 1.30489290 -0.39638694
## [26] 0.06343324 17.95360761 -26.82473266 -3.43465605 3.89442194
## [31] 14.19951788
##
## $wts$`out 2`
## [1] -2.13651485 -2.30107135 -9.20098297 32.21463975 13.22991962
## [6] -11.66591323 -3.74901009 -2.66401736 -3.51568645 8.86306123
## [11] 21.23104193 3.90166469 -25.59557989 16.25828544 6.96359373
## [16] 0.48833777 16.19675401 2.70077381 3.56471096 6.66728833
## [21] 0.04594048 -1.43653266 6.45665404 -2.40467662 0.14385323
## [26] 2.00087786 23.54572509 16.33188987 15.18362131 -7.14240432
## [31] 5.66525552
##
## $wts$`out 3`
## [1] 1.68427364 13.64131218 12.08513978 -47.55599600 -11.45633377
## [6] 12.82724330 1.39489293 2.48524239 -10.89653474 -3.87613222
## [11] -28.72195108 -4.48674949 25.29857105 -25.61616983 11.43416570
## [16] 4.26404984 -7.33928939 -3.52009730 -2.49094312 1.22631779
## [21] 0.61609121 -1.98771611 -5.24763918 1.21889420 -0.09169205
## [26] -0.97992641 -41.53697379 10.70209955 -10.75439882 4.00608492
## [31] -19.33456681
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## Results for first response variable only, use out_var argument to change
## Warning in olden.default(wts_in, x_names, y_names, skip_wts = skip_wts, :
## `label` cannot be a <ggplot2::element_blank> object.
Output olden() pada gambar merupakan hasil untuk model dengan 30 hidden neuron pada pembagian 60:40 (nn30_60). Karena hanya menampilkan neuron keluaran pertama, grafik ini menunjukkan pengaruh setiap prediktor terhadap kelas setosa. Berdasarkan grafik, Petal.Width memiliki kepentingan negatif terbesar (sekitar -1600), diikuti Petal.Length (sekitar -850), sedangkan Sepal.Width (sekitar 780) dan Sepal.Length (sekitar 640) memiliki kepentingan positif. Nilai negatif berarti semakin besar nilai variabel tersebut, semakin kecil peluang suatu observasi diklasifikasikan sebagai setosa, sedangkan nilai positif berarti sebaliknya. Hasil ini sesuai dengan karakteristik data iris, yaitu setosa memiliki ukuran kelopak (petal) yang jauh lebih kecil dibandingkan dua spesies lainnya. Dari sisi besarnya nilai mutlak, variabel petal (Petal.Width dan Petal.Length) lebih berpengaruh dibandingkan variabel sepal, sehingga ukuran petal menjadi pembeda utama antarspesies. Nilai olden bersifat relatif dan skalanya bergantung pada bobot model yang dibangkitkan secara acak, sehingga yang dibaca adalah arah dan urutan kepentingannya, bukan nilai mutlaknya. Grafik ini juga hanya mewakili kelas setosa, sehingga pengaruh variabel terhadap kelas versicolor dan virginica perlu dilihat dengan mengubah argumen out_var pada fungsi olden().
perbandingan <- data.frame(
Pembagian_Data = c("80:20", "80:20", "80:20",
"60:40", "60:40", "60:40"),
Hidden_Neuron = c(10, 20, 30, 10, 20, 30),
Akurasi = c(akurasi10_80, akurasi20_80, akurasi30_80,
akurasi10_60, akurasi20_60, akurasi30_60)
)
perbandingan## Pembagian_Data Hidden_Neuron Akurasi
## 1 80:20 10 0.9333333
## 2 80:20 20 0.9666667
## 3 80:20 30 0.8666667
## 4 60:40 10 0.9333333
## 5 60:40 20 0.9500000
## 6 60:40 30 0.9500000
Tabel ini merangkum akurasi enam model ANN dari dua pembagian data dan tiga jumlah hidden neuron. Akurasi seluruh model berkisar antara 0,8667 sampai 0,9667. Pada pembagian 80:20, akurasi berkisar antara 0,8667 sampai 0,9667 dengan rata-rata 0,9222, sedangkan pada pembagian 60:40 akurasi berkisar antara 0,9333 sampai 0,9500 dengan rata-rata 0,9444. Pembagian 60:40 menghasilkan akurasi yang lebih stabil terhadap perubahan jumlah hidden neuron, sedangkan pembagian 80:20 memberikan akurasi tertinggi sekaligus terendah. Jumlah hidden neuron sebesar 20 menghasilkan akurasi terbaik atau setara terbaik pada kedua pembagian data.
## Pembagian_Data Hidden_Neuron Akurasi
## 2 80:20 20 0.9666667
Pemilihan model terbaik dilakukan berdasarkan akurasi tertinggi pada data testing. Berdasarkan output, model terbaik adalah ANN dengan pembagian data 80:20 dan 20 hidden neuron (nn20_80) dengan akurasi 0,9667, yaitu hanya satu dari 30 observasi testing yang salah diklasifikasikan. Namun, selisih akurasi antarmodel relatif kecil dan setiap satu observasi pada data testing 80:20 setara dengan 3,33% akurasi, sehingga keunggulan model ini dapat dipengaruhi oleh pembagian data dan bobot awal yang dibangkitkan secara acak. Model pada pembagian 60:40 dengan 20 atau 30 hidden neuron (akurasi 0,9500) menggunakan data testing yang lebih banyak (60 observasi) sehingga penilaiannya lebih andal, dan selisihnya dengan model terbaik hanya satu observasi. Secara keseluruhan, ANN dengan 20 hidden neuron sudah cukup untuk mengklasifikasikan data iris dengan baik, sedangkan penambahan menjadi 30 hidden neuron tidak meningkatkan akurasi dan pada pembagian 80:20 justru menurunkannya.
neuron <- c(10, 20, 30)
akurasi.mat <- cbind(
"80:20" = perbandingan$Akurasi[perbandingan$Pembagian_Data == "80:20"],
"60:40" = perbandingan$Akurasi[perbandingan$Pembagian_Data == "60:40"])
matplot(
x = neuron,
y = akurasi.mat,
type = "b",
pch = 1:2,
col = 1:2,
lty = 1,
xaxt = "n",
xlab = "Jumlah Hidden Neuron",
ylab = "Akurasi",
main = "Perbandingan Akurasi ANN")
axis(1, at = neuron)
legend("bottomleft",
legend = colnames(akurasi.mat),
col = 1:2, pch = 1:2, lty = 1)Grafik garis membandingkan akurasi ANN dengan sumbu-x berupa jumlah hidden neuron dan setiap garis mewakili satu pembagian data. Garis 80:20 naik dari 0,9333 (10 neuron) ke 0,9667 (20 neuron), kemudian turun tajam menjadi 0,8667 (30 neuron). Garis 60:40 naik dari 0,9333 ke 0,9500 pada 20 neuron dan tetap datar pada 30 neuron. Kedua garis mencapai nilai tertinggi pada 20 hidden neuron, sehingga jumlah ini menjadi pilihan yang paling seimbang antara kemampuan model dan risiko overfitting. Fluktuasi pada pembagian 80:20 lebih besar karena data testing hanya 30 observasi sehingga satu kesalahan prediksi berdampak besar terhadap akurasi.
Berdasarkan praktikum yang telah dilakukan, dapat disimpulkan bahwa Artificial Neural Network (ANN) merupakan metode pembelajaran mesin yang meniru cara kerja jaringan saraf manusia melalui hubungan antar-neuron untuk mempelajari pola data. Implementasi ANN menggunakan bahasa pemrograman R dapat dilakukan dengan library nnet, baik untuk regresi maupun klasifikasi. Model regresi digunakan untuk memprediksi nilai numerik, sedangkan model klasifikasi digunakan untuk mengelompokkan data ke dalam kategori tertentu. Proses implementasinya meliputi pembagian data training dan testing, penentuan jumlah hidden neuron, pembentukan model, serta melakukan prediksi berdasarkan model yang telah dibangun.
Evaluasi performa model ANN dilakukan menggunakan metrik yang disesuaikan dengan jenis pemodelannya. Pada ANN regresi, MSE digunakan untuk mengukur rata-rata kuadrat kesalahan prediksi, sedangkan MAPE mengukur rata-rata persentase kesalahan prediksi. Sementara itu, pada ANN klasifikasi, akurasi digunakan untuk mengetahui proporsi prediksi yang benar dari seluruh data pengujian, sedangkan presisi mengukur ketepatan model dalam memprediksi suatu kelas. Semakin kecil nilai MSE dan MAPE serta semakin besar nilai akurasi dan presisi, maka semakin baik performa model dalam melakukan prediksi dan klasifikasi.
Model artificial neural network dengan 10, 20, dan 30 hidden neuron pada pembagian data 80:20 dan 60:40 menghasilkan akurasi yang baik pada data testing, yaitu berkisar antara 0,8667 sampai 0,9667. Model dengan pembagian 80:20 dan 20 hidden neuron memberikan akurasi tertinggi sebesar 0,9667, sedangkan penambahan menjadi 30 hidden neuron tidak meningkatkan akurasi dan justru menurunkannya pada pembagian 80:20 menjadi 0,8667, yang mengindikasikan overfitting. Kesalahan klasifikasi terbanyak terjadi antara versicolor dan virginica, sedangkan setosa hampir selalu terklasifikasi dengan benar. Analisis olden menunjukkan bahwa variabel petal (Petal.Width dan Petal.Length) paling berpengaruh dalam membedakan setosa. Dengan demikian, ANN dengan pembagian 80:20 dan 20 hidden neuron dipilih sebagai model terbaik karena memberikan akurasi tertinggi pada data testing.
Ketika menjalankan suatu fungsi pada program R diharapkan untuk teliti saat mengoperasikannya. Penulisan syntax sangat perlu diperhatikan karena apabila terdapat kesalahan penulisan akan membuat program error. Selain itu, perlu untuk memperhatikan tatacara penulisan yang sesuai dengan KBBI, sehingga dapat menghasilkan laporan yang baik.
Beck, M. W. (2018). NeuralNetTools: Visualization and analysis tools for neural networks. Journal of Statistical Software, 85(11), 1–20. https://doi.org/10.18637/jss.v085.i11
Bishop, C. M. (2006). Pattern recognition and machine learning. Springer.
Cybenko, G. (1989). Approximation by superpositions of a sigmoidal function. Mathematics of Control, Signals and Systems, 2(4), 303–314.
Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep learning. MIT Press.
Hastie, T., Tibshirani, R., & Friedman, J. (2009). The elements of statistical learning: Data mining, inference, and prediction (2nd ed.). Springer.
Haykin, S. (2009). Neural networks and learning machines (3rd ed.). Pearson.
Hornik, K., Stinchcombe, M., & White, H. (1989). Multilayer feedforward networks are universal approximators. Neural Networks, 2(5), 359–366.
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). An introduction to statistical learning: With applications in R (2nd ed.). Springer.
Krogh, A., & Hertz, J. A. (1992). A simple weight decay can improve generalization. In J. E. Moody, S. J. Hanson, & R. P. Lippmann (Eds.), Advances in neural information processing systems 4 (pp. 950–957). Morgan Kaufmann.
McCulloch, W. S., & Pitts, W. (1943). A logical calculus of the ideas immanent in nervous activity. The Bulletin of Mathematical Biophysics, 5(4), 115–133.
Nocedal, J., & Wright, S. J. (2006). Numerical optimization (2nd ed.). Springer.
Olden, J. D., & Jackson, D. A. (2002). Illuminating the “black box”: A randomization approach for understanding variable contributions in artificial neural networks. Ecological Modelling, 154(1–2), 135–150.
Olden, J. D., Joy, M. K., & Death, R. G. (2004). An accurate comparison of methods for quantifying variable importance in artificial neural networks using simulated data. Ecological Modelling, 178(3–4), 389–397.
Rosenblatt, F. (1958). The perceptron: A probabilistic model for information storage and organization in the brain. Psychological Review, 65(6), 386–408.
Rumelhart, D. E., Hinton, G. E., & Williams, R. J. (1986). Learning representations by back-propagating errors. Nature, 323(6088), 533–536.
Sokolova, M., & Lapalme, G. (2009). A systematic analysis of performance measures for classification tasks. Information Processing & Management, 45(4), 427–437.
Venables, W. N., & Ripley, B. D. (2002). Modern applied statistics with S (4th ed.). Springer.