Artificial Neural Network Untuk Memprediksi Pokemon Legend

Memanusiakan mesin dengan Keras

Satria Adi Putra
UNIKOM Codelabs
7 min readFeb 25, 2019

--

Photo by Frank Wang on Unsplash

Pembukaan

Pada artikel sebelumnya, saya pernah membagikan model machine learning yang saya buat dengan Scikit-Learn. Dengan menggunakan algoritma LinearSVC kita mendapatkan akurasi sekitar 98%.

Wow, keren kan? Tapi sepertinya ngga juga. Bisa aja terjadi overfitting atau bisa jadi hanya keberuntungan kan?

Sesuai dengan judul, saya akan melatih Artificial Neural Network (ANN) untuk melakukan tugas yang sama yaitu untuk memprediksi apakah seekor pokemon merupakan pokemon legendary atau bukan.

ANN memang bukan solusi ketika model yang kita bangun terjadi overfit. Pada artikel ini saya akan mengurangi jumlah data latih dan menambahkan jumlah data tes. Mungkin dengan langkah itu bisa lebih yakin kalau model yang dibangun tidak terjadi overfit dan bukan cuma kebetulan.

NOTE (MUST READ!)

Yang perlu dicatat sebelum mulai membangun ANN adalah saya tidak akan menjelaskan secara rinci apa itu ANN, bagaimana cara menghitungnya ataupun cara melatihnya. Disini saya menggunakan bantuan dari framework Keras agar proses menjadi lebih cepat dan mudah.

Jika kalian belum mengetahui ANN sama sekali, saya akan mencoba membantu dengan memberikan referensi untuk kata-kata yang mungkin terdengar sangat asing.

Oh iya untuk yang mungkin mau mencoba mengetahui dasar dari ANN sendiri, bisa coba untuk ambil Machine Learning course dari Andrew Ng di Coursera. Seriously worth your time.

Let’s Build It

Dataset yang akan digunakan dapat diunduh menggunakan link berikut: https://www.kaggle.com/alopez247/pokemon

Seperti sebelumnya, yang pertama harus kita lakukan yaitu import semua library yang akan kita gunakan

Selanjutnya kita akan membaca file csv dan menyimpannya ke variable data lalu menampilkan 5 data teratas.

Dan beginilah data kita

Wow, data yang akan kita olah ada terlalu banyak kolom. Ada beberapa kolom yang ga muat untuk ditampilin. Sebenernya kolomnya ada apa aja sih?

Dan itu dia kolom yang akan kita prediksi, isLegendary. Apa kita harus pake semua kolomnya buat melakukan prediksi? Ada beberapa kolom yang sepertinya ga ada hubungannya sama itu pokemon legend atau bukan deh. Kayak Number dan Name.

Kolom Number, hanya memberikan informasi nomer baris yang ga akan berguna untuk latihan ANN kita. Untuk kolom Name, misalnya aja ada pokemon namanya Retz dan dia adalah legend, terus ada pokemon namanya GoLok, apakah GoLok pokemon legend? Kita ga bisa ngukur GoLok itu Legend atau bukan karena nama ga menentukan dia kuat atau ngga kan?

Jadi kita ngga butuh 2 kolom itu. Kira-kira ada kolom lagi ga ya yang ga berguna? Hmmm untuk menjawab pertanyaan itu kita bisa pake code ini.

Fungsi di atas untuk menghitung korelasi setiap kolom dengan kolom isLegendary. Korelasi itu apa sih? Korelasi bisa digunakan untuk menghitung seberapa berpengaruh sih kolom satu dengan kolom lainnya. Korelasi nilainya antara -1 sampai 1. Semakin mendekati 0, maka semakin ga berpengaruh nilai satu kolom itu ke kolom lainnya.

Dari korelasi tersebut, kita bisa liat kolom mana aja sih yang ga penting dan ga ada hubungannya dengan kolom isLegendary. Kita hapus semua kolom yang punya korelasi lebih dari -0.1 dan kurang dari 0.1. Kolom tersebut adalah Pr_Male dan hasMegaEvolution.

Tunggu, kok ada beberapa kolom yang korelasinya ngga ada? Kayak Egg_Group_1 dan Type_1. Itu karena kolom tersebut merupakan Categorical Data. Untuk sekarang kita bisa anggap semua categorical data tersebut penting untuk membangun ANN kita.

Kita bisa liat kolom dari data kita sekarang jadi lebih sedikit sekarang.

Selanjutnya kita coba cek, apa ada data null di dataset kita ini.

Ternyata banyak data yang null di categorical data kita. Kita isi semua data null dengan kata “None”

Kalau kita liat lagi, categorical data kita semuanya punya nilai string. Padahal di balik ANN ada banyak komputasi matematika yang rumit, dan kalau kita ngomongin matematika berarti kita ngomongin angka dan bukan string.

Salah satu caranya adalah dengan mengubah string tersebut menjadi angka. Kita bisa melakukan ini dengan mudah berkat bantuan LabelEncoder.

Misal kita punya data cuaca yang nilainya adalah Cerah, Hujan, dan Berawan. Label Encoder akan mengganti ketiga nilai tersebut dengan angka. Nilai Cerah akan menjadi nilai 1, nilai Hujan akan bernilai 2 dan Berawan akan menjadi nilai 3.

Lah error, kenapa nih? Dari pesannya “y contains previously unseen labels: ‘None’”. Kalau kita balik lagi ke sebelumnya, nilai ‘None’ cuma ada di kolom Type_2 dan kolom Type_1 ngga ada nilai ‘None’. Karena type_encoder kita belajar dari kolom Type_1 yang ngga ada nilai ‘None’ dan disuruh buat ngubah kolom Type_2 yang punya nilai ‘None’ makannya ada error.

Kalau gitu kita tuker aja, jadi type_encoder belajar dari kolom Type_2.

Sekarang kolom Type_1 dan Type_2 udah jadi angka. Waktunya ubah kolom lainnya.

Sekarang errornya karena di Egg_Group_2 ngga ada yang nilainya ‘Undiscovered’. Kita ngga bisa tuker langsung kayak waktu di kolom sebelumnya, karena permasalahannya kalau kita tuker di Egg_Group_1 ngga ada yang nilainya ‘None’.

Kita harus buat variable baru buat nyimpel semua data yang ada di kolom ini. Jadi egg_encoder latihannya berdasarkan variable baru kita ini.

Berhasil yeyyy..

Kita lanjut encode categorical data sisanya.

Ok, selesai sama categorical data.

Kenapa isLegendary dan hasGender ngga di encode juga dengan LabelEncoder? Simple karena mereka bertipe Boolean. Jadi Python akan nganggap True == 1 dan False == 0.

Sekarang waktunya bangun ANN kita. Oh iya sebelum kita bangun, kita harus misahin datasetnya dulu antara data latih dan data test. Kalau di artikel sebelumnya kita prediksi pokemon di generasi ke 6, sekarang kita akan prediksi pokemon di genreasi ke 5 dan 6. Berarti data latih kita akan berisi pokemon generasi 1–4.

Langkah terakhir sebelum kita membangun neural network ini adalah melakukan Feature Scaling.

Jika kita liat ulang data kita, ada data yang memiliki rentang [180, 720]. Range yang sangat besar ini bisa menyebabkan proses perhitungan lebih lama dan juga bisa memperlambat terjadinya konvergen.

Untuk melakukan Feature Scaling kita bisa menggunakan StandardScaler dari Scikit Learn. StandardScaler akan membuat setiap kolom memiliki nilai mean sama dengan 0 dan nilai standard deviation menjadi 1.

Ketika menjalankan code diatas, akan muncul warning. Abaikan aja warningnya, tidak ada masalah.

Untuk mulai membangun ANN kita bisa dengan kode ini.

Kita buat dulu model ANN dengan class Sequential dari Keras. Lalu dengan function add kita menambahkan layer baru di ANN. Layer yang kita tambahkan merupakan sebuah Dense Layer.

Layer yang kita tambahkan pertama adalah input layer dengan 13 neuron sesuai dengan total kolom yang akan kita gunakan. Output dari layer ini merupakan sebuah Dense Layer sebanyak 10 neuron begitu seterusnya. Neural Network yang terbentuk memiliki 4 layer dengan masing-masing jumlah neuron 13–10–5–1.

Perlu diingat, pada saat membuat input layer, kita perlu mendefinisikan input_dim. Untuk hidden layer berikutnya, input_dim menjadi opsional karena Keras akan mengambil input_dim berdasarkan dari output dari layer sebelumnya.

Parameter activation merupakan nama Activation Function yang digunakan. Ada banyak Activation Function yang dapat digunakan, kita hanya menggunakan Rectified Linear Unit (relu) dan Sigmoid Function.

Dengan function compile kita mendefinisikan algoritma optimizer dan loss function yang akan digunakan dalam melatih Neural Network.

Kita menggunakan Binary Cross-Entropy untuk loss function dan Adam Optimizer untuk meminimalisasikan loss function.

Terakhir function fit akan melakukan training neural network dengan batch size sebanyak 32 dan epoch 100. Tentang Epochs dan Batch Size.

Setelah proses latihan selesai, kita bisa lihat bahwa loss dari model kita adalah 0.048. Ada perbedaan? Ya, perbedaan tersebut terjadi karena saat melakukan latihan, keras akan memberikan nilai weight random. Nilai random inilah yang menyebabkan terjadinya perbedaan pada nilai local optimum.

Terakhir, kita harus melakukan testing dengan data test yang telah kita siapkan.

Kita bisa melakukan prediksi dengan function predict. Untuk menghitung akurasi dari prediksi yang telah dilakukan, kita bisa menggunakan bantuan confusion_matrix dari Scikit Learn.

Masalahnya adalah pada y_test nilainya merupakan boolean. Sedangkan pada y_pred nilainya adalah rentang [0, 1]. Oleh karena itu kita melakukan perbandingan untuk merubah nilai y_pred menjadi boolean.

Keluarnya adalah sebuah matriks. Prediksi yang benar dapat dilihat pada baris ke-1 kolom ke-1 dan baris ke-2 kolom ke-2. Dengan begitu, prediksi benar pada model ini ada 209 + 11 = 220.

Untuk menghitung akurasinya, kita bisa menggunakan rumus sederhana (209 + 11) / (209 + 11 + 5 + 3) = 0.9649122807017544.

ANN ini dapat memprediksi apakah seekor pokemon merupakan pokemon legend atau bukan dengan akurasi sebesar 96%. Sangat akurat bukan?

Photo by Vasily Koloda on Unsplash

Mungkin akurasi bisa ditingkatkan lagi hingga 98% dengan melakukan Parameter Tuning. Tapi saya rasa, 96% pun sudah sangat memuaskan. Mengingat kali ini data test jauh lebih banyak dari artikel sebelumnya.

Dengan menggunakan Keras, membuat Artifical Neural Network menjadi lebih mudah kan? Dari sini bisa dikembangkan lagi menjadi CNN untuk mendeteksi gambar atau mungkin RNN untuk membuat Chatbot?

Anyway, masih banyak yang harus dipelajari. Jadikan ilmu seperti air laut, yang kalau diminum bukannya puas tapi malah makin haus. Tapi jangan sombong untuk ngeliat ke bawah kalau nanti udah di atas ya :)

Okay, see you next time :)

--

--