Word Embedding Bahasa Indonesia menggunakan Fasttext (Part 1)

Mengenal Word Embedding

Word embedding mudahnya adalah istilah yang digunakan untuk teknik mengubah sebuah kata menjadi sebuah vektor atau array yang terdiri dari kumpulan angka.

Ketika kita akan membuat model machine learning yang menerima input sebuah teks, tentu machine learning tidak bisa langsung menerima mentah-mentah teks yang kita miliki. Cara “tradisional” untuk membaca teks tersebut adalah sebagai berikut:

  1. Buat kamus kata dengan cara mendaftar semua kata yang ada di dataset
  2. Setiap menerima sebuah string kata, string tersebut diubah menjadi sebuah integer dengan memberinya nomor. Penomoran ini bisa ditentukan berdasarkan urutan di kamus kata yang kita miliki. Misalnya pada ilustrasi di bawah, string “Makan” menjadi angka 3, string “Lari” menjadi angka 5, dst.
  3. Angka-angka tersebut kita ubah lagi menjadi sebuah vektor (array 1 dimensi) yang memiliki panjang sepanjang banyak kata yang kita miliki di kamus. Array tersebut hanya akan bernilai 1 atau 0 (disebut one hot encoding). Nilai 1 diposisikan pada indeks yang merupakan nomor kata tersebut sedangkan elemen lainnya bernilai 0. Contohnya untuk kata “makan”, dengan banyak kosakata yang kita miliki adalah 100 kata, maka dari kata tersebut kita akan memperoleh sebuah vektor dengan panjang 100 yang berisi 0 semua kecuali pada posisi ke 3 yang bernilai 1.
Ilustrasi mengubah string menjadi one-hot encoding

Nah coba saja bayangkan kamus kita ukurannya mencapai 10,000 kata, maka untuk setiap katanya akan di-convert menjadi vektor ukuran 10,000 yang hampir semua elemennya bernilai 0 semua. Metode ini selain kurang efisien dalam memori juga tidak memberikan banyak informasi.

Dengan metode word embedding kita dapat mengubah kata menjadi sebuah vektor yang berisi angka-angka dengan ukuran yang cukup kecil untuk mengandung informasi yang lebih banyak. Informasi yang diperoleh akan cukup banyak sampai-sampai vektor kita akan dapat mendeteksi makna, seperti kata “marah” dan “mengamuk” itu lebih memiliki kedekatan nilai ketimbang kata “marah” dengan “bahagia”.

Apa itu FastText?

FastText adalah library yang dikeluarkan oleh Facebook yang dapat digunakan untuk word embedding. Sebenarnya, FastText sendiri adalah pengembangan dari library Word2Vec yang telah lebih lama terkenal sebagai library untuk word embedding.

FastText memiliki keunggulan dibanding Word2Vec. Salah satunya adalah kemampuan FastText untuk menangani kata yang tidak pernah kita jumpai sebelumnya (Out Of Vocabulary word atau dikenal OOV). Misalnya kata-kata yang tidak baku seperti “Pengoptimalisasian” tetap akan diperoleh vektornya. Library Word2Vec ataupun teknik one hot encoding tradisional yang seperti dijelaskan sebelumnya akan menghasilkan eror ketika menerima kata yang tidak pernah ada di kamus.

FastText memberikan opsi untuk menggunakan salah satu dari dua algoritma utama, yakni CBOW dan Skipgram. Kedua algoritma tersebut menggunakan bantuan Neural network untuk mendapatkan model terbaik yang mampu merepresentasikan sebuah kata dalam vektor.

PreTrained FastText Bahasa Indonesa

Ada banyak cara menggunakan library FastText untuk kasus Bahasa Indonesia, cara paling mudah adalah dengan menggunakan Pretrained model, atau model yang telah dilatih oleh seseorang sehingga kita tinggal menggunakannya tanpa harus melatihnya terlebih dahulu.

Model resmi (terdapat lebih dari 150 bahasa) bisa di download di sini. Model tersebut dibuat berdasarkan paper oleh Edouard Grave, dkk yang berjudul Learning Word Vectors for 157 Languages. Bersyukurnya, bahasa Indonesia ada di antara 157 bahasa tersebut.

Saat akan mendownload, kalian akan sadar terdapat 2 jenis model yang disediakan oleh FastText, yakni cc.id.300.vec.gz dan cc.id.300.bin.gz. Jika diperhatikan sekilas dari nama filenya, tampak simbol id berarti itu adalah model bahasa Indonesia dan angka 300 menunjukkan besar dimensi vektornya.

Untuk bagian vec/bin menunjukkan tipe model tersebut, vec menunjukkan model tersebut hanyalah berupa text file yang berisi kamus daftar vector untuk setiap kata (perlu membuat program sendiri untuk mengatasi OOV), sedangkan bin menunjukkan file tersebut adalah file binary siap pakai dengan termasuk di dalamnya file .vec, algoritma untuk mengatasi OOV, catatan hyperparameter untuk melatih ulang, dsb.

Perlu diketahui, FastText hanya menyediakan pretrained model berupa model binary FastText (.bin) atau text file kumpulan kata beserta vektornya (.vec). Untuk menggunakan model atau text file tersebut pada proses word embedding kita akan menggunakan library lain lagi, yakni Gensim.

Menggunakan Gensim

Bagi pengguna Python, sebenarnya terdapat dua libray besar yang bisa kita gunakan untuk word embedding menggunakan FastText, yang pertama adalah library Python FastText bawaan asli, dan yang kedua adalah Gensim, library yang lebih umum untuk word embedding namun juga telah support FastText.

Di sini kita akan menggunakan Gensim untuk menggunakan model FastText. Install terlebih dahulu menggunakan perintah berikut:

Lalu import di program python menggunakan perintah:

Dalam Gensim saat ini cara paling mudah untuk me-load pretrained model FastText adalah menggunakan load_fasttext_format (lihat bagian Catatan). Fungsi tersebut membutuhkan file *.bin dari pretrained model. Kita bisa download terlebih dahulu file *.bin tersebut (~4-5GB) dari halaman resmi FastText.

Setelah berhasil terdownload, unzip file tersebut terlebih dahulu, lalu kita bisa memanggil model tersebut dengan perintah berikut:

Dan kita bisa uji model yang telah kita load dengan kode berikut:

Dapat dilihat pada program di atas kata “algoritmatik” tidak ada di kamus model yang kita gunakan (False), tetapi FastText tetap bisa menghasilkan nilai vektor untuk kata tersebut sehingga bisa dicari kata mirip terdekatnya (algoritma).

Untuk melihat nilai vektor dari kata “algoritmatik” kita bisa memunculkan dengan cara:

Penutup

Salah satu kekurangan menggunakan pretrained model adalah ukuran yang luar biasa besar (~7GB setelah di ekstrak), hal ini membuat kita pengguna komputer yang memiliki RAM kecil kesulitan untuk menggunakannya.

Kita bisa menggunakan Google Colab untuk menangani masalah tersebut, tetapi ada metode lain yang bisa kita gunakan, yakni kita coba melatih model kita sendiri. Dengan melatih sendiri kita bisa lebih mengatur ukuran model menyesuaikan kebutuhan. InsyaAllah proses melatih word embedding akan berlanjut di Part 2. Baca juga kelanjutan penggunaan Fasttext dengan library aslinya di Part 1.5

Catatan Seputar Gensim:

Di versi terbaru Gensim (> 3.7.2), kita disarankan menggunakan dua metode lain untuk me-load pretrained model, yakni menggunakan load_facebook_vectors atau load_facebook_model. Kedua fungsi tersebut merupakan fungsi yang telah diperbarui dari fungsi load_fasttext_format sehingga seharusnya lebih cepat.

Namun, ketika tulisan ini di tulis masih ada sebuah bug yang membuat belum bisa digunakannya fungsi tersebut. Jika bug ini sudah diperbaiki insyaAllah akan ada update untuk tulisan ini

Sumber featured image Pexels.com

Template Curriculum Vitae untuk LaTeX

Beberapa waktu lalu saya penasaran dengan tampilan Curriculum Vitae / CV/ Resume yang baik. Di internet ada banyak tampilan dengan beragam format, tapi kali ini saya tertarik untuk membuat CV dengan LaTeX.

Pilihan pertama saya jatuh pada CV buatan Thomas Jansson. Templatenya (file resume.cls) bisa didownload langsung di halaman aslinya atau di daftar template Sharelatex.

Tampilan akhir CV dengan template oleh Thomas Jansson

Jika kalian perhatikan, desainnya sudah sangat baik, elegan, dan terkesan profesional. Cocok untuk CV para profesional yang panjang ataupun para freshgraduate yang belum banyak pengalaman. Hanya saja ada yang kurang menurut saya, yakni warna. Template aslinya hanya menghasilkan CV berwarna hitam putih.

Note: Bagian selanjutnya dari artikel ini akan menjelaskan pengalaman saya mengedit template LaTeX untuk menambahkan theme color pada template CV. Jika ingin langsung menggunakan template yang telah saya edit sehigga dapat berwarna, silakan download file resume.cls di repository berikut.

Mengedit LaTeX template

Berdasarkan banyak tips dalam pemberian warna di CV maka saya berusaha untuk tidak terlalu banyak mewarnai area CV, hanya meng-highlight bagian-bagian yang saya rasa penting untuk diberi warna, yakni teks judul dan teks subjudul pada sisi samping.

Untuk mengedit LaTeX template, kita akan mengedit file resume.cls yang tadi telah kita download. Pertama-tama, tambahkan package yang menyediakan pewarnaan teks pada bagian akhir:

Saya berikan parameter tambahan dvipsnames sehingga kita memperoleh lebih banyak pilihan warna yang memiliki “nama” (jadi tidak perlu menginputkan kode heksadesimal).

Selanjutnya utuk mempermudah penggunaan warna, saya membuat variabel yang menyimpan warna menggunakan perintah \colorlet:

Variabel themecolor adalah variabel yang akan kita gunakan untuk menyimpan warna template yang akan kita gunakan. Sedangkan MidnightBlue adalah warna tema yang saya gunakan untuk CV tersebut.

Note: Jika ingin mengganti warna template CV, ubah MidnightBlue menjadi warna lain sesuai selera

Selanjutnya kita cukup menyisipkan warna template kita ke bagian yang ingin kita beri warna, yakni judul dan subjudul di sisi samping. Di template, untuk mengedit kedua bagian tersebut kita dapat mengedit style yang digunakan, yakni mysidestyle dan mytitle.

Jika diperhatikan, di sini untuk mewarnai text saya menggunakan perintah textcolor{}. Sebenarnya ada dua cara yang dapat digunakan yakni dengan color{} atau textcolor{}, tetapi cara pertama akan membuat eror pada template (text tidak lagi teralinea dengan rapi)

Setelah selesai, template resume.cls sudah akan dapat memberikan warna pada bagian-bagian yang kita tentukan. Jika sebelumnya sudah pernah menggunakan template dari Thomas Janssen, perubahan ini seharusnya tidak akan mengubah apapun kecuali pemberian warna.

Hasil template CV dengan warna tema MidnightBlue

featured image credit: https://www.philippewiget.com


simple neural net

Neural Net in 4 lines! using Scikit-Learn MLPClassifier

See the code below:

That’s right, those 4 lines code can create a Neural Net with one hidden layer! 😐

Scikit-learn just released stable version 0.18. One of the new features is MLPClassifer and you can see in the code above, it’s powerful enough to create a simple neural net program.

That code just a snippet of my Iris Classifier Program that you can see on Github. Of course, in practice, you still need to create loader, pre-process, pre-training, or other modules. But, if you see other python libraries like Keras, Lasagne, or Theano, I think this is the easiest way to create a simple neural net. I said “simple” because when you need to create more complex model that need more complex algorithm or many addons, I think it’ll become difficult to use MLPClassifier. But, for some simple project, I think I’ll choose this scikit tool 🙂

Program Explanation

Line 1: you need to load MLPClassifier

Line 2: we create an object called ‘mlp’ which is a MLPClassifier. We set hidden_layer_size to (10) which means we add one hidden layer with 10 neurons. Then we set solver as ‘sgd’ because we will use Stochastic Gradient Descent as optimizer. Then we set learning_rate_init to 0.01, this is a learning rate value (be careful, don’t confuse with alpha parameter in MLPClassifer). Then the last, we set 500 as the maximum number of training iteration.

Line 3: Train the model

Line 4: Test the model

That’s it! and my first run I got more than 90% accuration in Iris Dataset 🙂 try it!

And actually, you can create “Deeper” neural net with add more layers easily, just change hidden_layer_sizes. For example, hidden_layer_sizes=(10,10,10) will create 3 hidden layer with 10 neuron each.

source image: Flickr

Meng-custom Perintah/Command di Terminal Ubuntu

Beberapa waktu lalu saya mendapat kesempatan untuk ikut Grand Final Kode Indonesia di Jakarta. Kode Indonesia adalah sebuah kontes pemrograman yang diadakan oleh Kalibrr.

Berbeda dengan kontes pemrograman pada umumnya, pada kontes ini panitia tidak menyediakan komputer atau laptop untuk para finalis. Jadi para finalis dipersilakan untuk menggunakan komputernya masing-masing di Grand Final. Sebenarnya ini peraturan yang aneh karena ini membuat setiap peserta bisa jadi punya “starting-point” yang berbeda kan? misal kualitas komputer, file-file yang tersedia, dsb.

Tapi ya sudah, karena ini aturan panitia sendiri maka saya juga mencoba menyiapkan laptop saya. Hal sederhana yang saya pikirkan adalah:

Meng-custom perintah atau command di terminal Ubuntu: Coba buat perintah sederhana untuk meng-compile sekaligus menjalankan program C++!

Tujuan command tersebut tentu untuk mempersingkat proses compile. Karena saya sendiri biasa tidak menggunakan IDE yang bisa meng-compile program, maka cara saya biasanya untuk meng-compile file C++ adalah dengan menjalankan perintah (command) berikut:

Lalu setelah di-compile, dijalankan dengan perintah:

Nah, misi sederhana saya saat itu adalah menyederhanakan kedua perintah di atas menjadi sebuah perintah sederhana. Setelah browsing-browsing, berikut ini rangkuman langkah-langkahnya:

  1. Buat sebuah script file, misalnya kita beri nama customcpp.sh
  2. Pada baris pertama, tuliskan #!/bin/bash lalu tuliskan perintah yang ingin dijalankan di bawahnya seperti di bawah. Pada perintah di bawah CPPFILE adalah variabel yang menyimpan argumen yang akan diinputkan saat pemanggilan. Nantinya akan menerima nama file yang akan di-compile.
  3. Simpan file tersebut, lalu pindahkan ke /usr/local/bin, pemindahannya bisa menggunakan command di bawah. SCRIPTNAME adalah nama perintah yang akan dipanggil ketika script di atas di jalankan.
  4. Atur permission agar program bisa diakses

Dan… selesai!

Setelah selesai, sekarang untuk mengcompile sekaligus menjalankan program C++, saya cukup mengetikkan di terminal command berikut ini:

ya.. setidaknya sedikit lebih cepat dari sebelumnya kan 😉

Sumber:

Parser Kalimat Sederhana untuk Bahasa Indonesia

Beberapa waktu lalu saya mendapat tugas kerja untuk membuat sebuah text summarizer (perangkum bacaan) menjadi sebuah kalimat sederhana. Istri saya yang lebih mendalami bidang NLP menyarankan untuk menggunakan teknik yang sederhana:

Temukan kalimat utama, dan jadikan kalimat tersebut sebagai rangkuman.

Saya setuju ide itu, selain tidak serumit jika mengunakan machine learning yang kompleks, rasanya cara itu sudah cukup cocok untuk kasus saya. Istri saya memberi tahu saya beberapa algoritma yang bisa digunakan dan sebuah peringatan bahwa bagian paling sulit adalah nanti bagaimana membuat parser kalimat (program yang dapat mengekstrak kalimat-kalimat yang menyusuk sebuah dokumen teks).

Saya buat parser ini menggunakan bahasa pemrograman Python, dengan bantuan beberapa package (re untuk regex, dsb.).

Split berdasar penanda akhir kalimat

Percobaan pertama yang saya lakukan adalah menggunakan regex untuk men-split data teks berdasarkan beberapa karakter yang biasa menjadi penanda akhir dari sebuah kalimat. Karakter pemisah yang saya gunakan awalanya aadalah tanda titik (“.”), tanda tanya (“?”), dan tanda seru (“!”) yang setelahnya terdapat sebuah spasi atau sudah di akhir dokumen.

Setelah coba dijalankan, saya menemukan beberapa fakta menarik. Pertama, seharusnya saya tidak perlu memisahkan berdasarkan tanda tanya dan tanda seru karena kedua tanda tersebut hanya muncul di kalimat langsung yang tidak perlu di split. Jadi berikutnya kita cukup split di tanda titik.

Kedua, asumsi saya menggunakan tambahan “sebuah spasi setelah karakter” ternyata benar-benar bermanfaat karena parser akhirnya tidak men-split tanda titik yang bukan akhir kalimat, misalnya 6.700 korban.

Kalimat langsung

“Roses are red. Violets are Blue,” said Hugo.

Dalam kasus saya, kalimat di dalam kalimat langsung tidak boleh dipisah. Untuk menghindari pemisahan, perlu dibuat aturan khusus (saya rasa ini bisa di-handle menggunakan regex). Ide saya sementara ini dengan membuat variabel untuk mengecek sebuah simbol pemisah ada di dalam double quote atau tidak, lalu jika tanda titik misalnya ada di antara double quote, maka kita beri “tanda” agar tidak di split.

“Tanda” agar tidak di-split

Untuk menandai sebuah simbol tidak boleh di split, saya sisipkan simbol yang unik (yang saya yakin tidak akan muncul di dokumen saya) sebelum dan setelah tanda titik. Saya gunakan simbol @#...@#.

“Roses are red@#.@# Violets are Blue,” said Hugo.

Mengatasi Singkatan

Ini adalah bagian yang juga sulit, misalnya ada kalimat:

Tadi malam saya bertemu H. Akbar M. dan drs. Rian. Kami adalah sahabat dekat dulunya.

Jika diperhatikan tanda titik setelah huruf “H” dan huruf “M”, bukanlah tanda akhir dari kalimat, begitu juga tanda titik setelah “drs”. Tanda titik yang digunakan untuk memisah kalimat adalah setelah kata “Rian”.

Awalnya saya berpikir untuk tidak mensplit tanda titik yang sebelumnya hanya satu huruf, tapi “drs” lebih dari satu huruf dan juga merupakan singkatan. Kita harus menemukan sebuah kata adalah singkatan atau bukan.

Deteksi singkatan

Pada projek ini ada dua aturan yang gunakan:

  1. Jika kata sebelum tanda titik hanya terdiri dari satu huruf, maka itu adalah singkatan. Contoh: “M.”, “H.”
  2. Jika tidak, maka cek terlebih dahulu di kamus singkatan (saya buat sendiri), jika ditemukan, maka kata tersebut singkatan. Contoh: “Prof.”, “Dr.”, “Hj.”, “dll.”, “Moch.”

Secara tidak langsung, aturan ini juga menangani singkatan panjang seperti “S.W.A.T.”. Setelah berhasil mendeteksi singkatan, dengan ide yang sama kita kasih “tanda” pada tanda titiknya, lalu split dengan fungsi regex seperti sebelumnya.

Hapus “tanda”

Setelah berhasil split kalimat, jangan lupa untuk menghilangkan simbol yang tadi kita gunakan sebagai “tanda”. Caranya bisa dengan manual seach atau dengan regex.

Program

Program bisa diakses di Google Colab berikut

Image from: https://museafrica.com