Pengantar Pemrosesan Teks dengan Keras (Bagian 1: Tensor, Batch, Layer dan Learning)

Deep learning saat ini sudah umum digunakan dalam berbagai task NLP.  Materi posting ini saya ambil dari buku Chollet “Deep Learning with Python” dan berbagai sumber lain.  Perlu dibagi menjadi beberapa bagian karena berdasarkan pengalaman saya jika langsung loncat ke source code tanpa paham dasar-dasarnya  nanti malah jadi  bingung sendiri. Posting ini masih membahas Keras secara umum.

Keras adalah library yang ditujukan untuk memudahkan pembuatan model NN (Neural Network). Keras menyediakan fasilitas untuk membuat berbagai arsitektur NN seperti  convolutional, recurrent, multi input-multi output, layer sharing dan model sharing.  Keras menggunakan backend Tensorflow atau CNTK (Microsoft Cognitive Toolkit). Lisensi keras adalah MIT yang longgar sehingga mudah digunakan untuk kepentingan komersial.

Urutan pembuatan NN di Keras adalah:

  1. Mendefinisikan data training  berupa input tensor dan target tensor.
  2. Mendefinisikan layer yang akan memetakan antara input ke target.
  3. Konfigurasi proses learning dengan memilih loss function, optimizer dan metric yang harus dimonitor.
  4. Lakukan training dengan memanggil method fit()

Instalasi Keras sangat mudah: pip install tensorflow lalu pip install keras

Konsep dasar yang penting dalam Keras adalah Tensor.  Tensor adalah struktur data berupa matrix atau multidimensional array yang menjadi dasar penyusun NN. Tensorflow dan library deep NN lainnya adalah library yang dapat memproses secara efisien komputasi pada tensor.

Ukuran dimensi yang umum pada tensor adalah 0D sampai 5D, contoh:

  1. 0D yang berisi satu nilai;
  2. 1D, satu dimensi atau vektor. Misalnya  x = np.array([10,12,13,14]).  Variabel x ini karena memiliki empat nilai disebut 4-dimensional vector tetapi tetap tensor 1 dimensi karena hanya memiliki satu axis. Jadi perlu dibedakan antara 4D vector dan 4D tensor.
  3. 2D, matrix.  Contoh:  x = np.array( [[10,12,13,14], [11,21,32,41]] ).  Variabel x ini dapat dianggap sebagai dua instance yang memiliki 4 fitur.

Tensor didefinisikan oleh tiga atribut,  jumlah axis, shape dan tipe datanya.

  1. Tensor 3D akan memiliki jumlah axis (rank) =3, tensor 2D rank-nya = 2 dst.
  2. Tipe data (dtype): float32, uint9, float64 dan char.
  3. Shape memperlihatkan dimensi yang dimiliki untuk setiap axis. Contoh untuk  tensor 3D ini, shapenya adalah (2,3,4). Axis nol terdiri atas 2 dimensi, axis ke-1 tiga dimensi dan axis ke-3  4 dimensi:

x = np.array(
[[[10,12,13,11],
[11,21,32,15],
[30,21,31,22]],
[[10,12,13,4],
[11,31,52,5],
[21,51,12,9]]]
)
print(x.shape) # hasilnya (2,3,4)

Contoh lain untuk tensor 2D berikut,  shape adalah (2,4)
x = np.array([[10,12,13,14],[11,21,32,41]])

Vector dengan elemen tunggal ini akan memiliki shape (4,)
x = np.array([10,12,13,14])

Scalar akan memiliki shape ()

Batch: Axis & Dimension

Umumnya axis yang pertama (axis 0) disebut sample axis atau sample dimension. Sebagai contoh untuk pengenalan karakter yang terdiri atas 1000 gambar dengan 30×30 pixel grayscale, akan menggunakan tensor 3D dengan shape (1000, 30, 30) yang berisi nilai 0..255 (grayscale). Axis ke-0 (1000) adalah jumlah instances atau samples. Pada tensor 2D dengan shape (10000, 20) artinya ada 10000 samples dengan 20 fitur. Dapat dianggap  shape adalah (samples, feature).

Tensor 3D sering digunakan untuk merepresentasikan time series (samples, timesteps, features). Tensor 4D untuk image (sample, height, width, channel) atau (sample, channels, height, width). Tensor 5D untuk video (samples, frames, height, width, channel) atau (samples, frames, channels, height, width).

Dokumen teks dapat direpresentasikan dengan frekuensi kemunculan kata atau tf-idf. Dengan asumsi jumlah kosakata 20000, maka tiap dokumen dapat direpresentasikan dengan vektor 20000 elemen. Jika terdapat 500 dokumen, data dapat direpresentasikan dengan tensor 2D dengan shape (500, 20000) .

Contoh lain adalah tweet, asumsikan tweet akan direpresentasikan di level karakter. Panjang setiap tweet maksimal adalah 280 karakter dengan jumlah karakter yang mungkin adalah 128 (a-z, A-Z, 0-9 dst). Setiap karakter dapat di-encode sebagai binary vector berukuran 128, contohnya karakter “a” menjadi [1,0,0,0 ….0], karakter “b” [0,1,0,0… 0] dan seterusnya. Jadi setiap tweet dapat di-encode menjadi tensor 2D (280, 128) dengan isi 0 dan 1. Jika terdapat 1 juta tweet, maka akan disimpan dalam tensor 3D (1000000, 280, 128).

Model DL umumnya tidak memproses data secara sekaligus tetapi dibagi-bagi menjadi batch yang lebih kecil. Itu sebabnya axis 0 sering juga disebut batch axis atau batch dimension.

Layer

Layer adalah bagian yang menerima input satu atau lebih tensor dan mengeluarkan output satu atau lebih tensor. Ada layer yang stateless, tetapi umumnya layer memiliki state yaitu bobotnya.

Terdapat berbagai jenis layer untuk berbagai jenis pemrosesan data. Keras menyediakan layer standar yang umum digunakan dalam deep learning. Misalnya dense connected layer (kelas Dense di Keras), recurrent layer (kelas LSTM) dan convolutional layer (kelas Conv2D). Membangun deep NN di Keras adalah menyusun berbagai layer seperti membangun mainan LEGO.

Setiap layer menerima input tensor dan mengeluarkan output tensor dalam ukuran (shape) yang sudah ditentukan. Ini disebut layer compatibility.

Sebagai contoh, code berikut membuat model dengan dua layer berukuran 32 neuron dan menerima 500 fitur pada layer input. Layer kedua adalah layer output.

from keras import models
from keras import layers

#definisikan model sebagai urutan layer
model = models.Sequential()
#model menerima input dengan jumlah fitur 500 dan output 32
#jumlah instance tidak perlu dituliskan dalam input_shape
model.add(layers.Dense(32, input_shape=(500,)))
#input layer ini otomatis 32 (output layer sebelumnya)
model.add(layers.Dense(32))

Sebagai contoh, code berikut membuat model dengan dua layer berukuran 32 neuron dan menerima 500 fitur pada layer input. Layer kedua adalah layer output.

Learning

Pada Keras, tahapan learning dikonfigurasi di bagian kompilasi. Konfigurasi yang perlu didefinisikan adalah optimizer dan loss function yang akan digunakan model dan metric yang akan dipantau  saat training. Loss merupakan jarak antara nilai target dan prediksi untuk setiap sample, sedangkan metric mengukur kinerja keseluruhan model.

Loss function mengukur kinerja NN terhadap data training yang  digunakan untuk mengarahkan atau memperbaiki network ke arah yang tepat. Keras menyediakan beberapa loss function standar yang dapat dipilih sesuai task, misalnya untuk klasifikasi biner, dapat digunakan binary cross entropy; untuk klasifikasi multi kelas dapat digunakan categorical cross entropy; mean-squared error untuk regresi dan connectionist temporal classification (CTC) untuk sequence labeling.

Optimizer adalah mekanisme yang digunakan  untuk mengupdate bobot jaringan berdasarkan loss function. Berbagai jenis class optimizer di Keras yang dapat digunakan adalah RMSprop, Adagrad, Adadelta, Adam, Adamax, Nadam.

Contoh proses compile dan training dapat dilihat pada kode berikut

from keras import optimizers
model.compile(optimizer=optimizers.RMSprop(lr=0.001),loss='mse',metrics=['accuracy'])

Setelah itu, input dan target diberikan pada method fit() seperti pada Scikit-Learn

model.fit(input_tensor, target_tensor, batch_size=128, epochs=10)

Contoh lebih rinci dapat dilihat pada posting berikutnya, klasifikasi teks [bersambung].  

Iklan

Pos Tagger dan Dependency Parser dengan StanfordNLP Python

Sebelumnya saya sudah buat tulisan tentang pos tagger & dependency parser Bahasa Indonesia dengan lib CRFTagger, UUParser dan Syntaxnet.  Hanya Syntaxnet yang menyediakan pretrained model. Saat ini ada satu lagi library yang menyediakan pretrained model untuk Bahasa Indonesia: StanfordNLP (https://github.com/stanfordnlp/stanfordnlp).

StanfordNLP sudah ada cukup lama, tapi awalnya menggunakan Java dan lisensinya GPL (kita perlu bayar lisensi terpisah jika buat sistem yang tidak open source).  Sejalan dengan dominasi Python dan lisensi yang lebih longgar seperti MIT dan Apache, maka dikembangkan lib baru, dan StanfordNLP yang lama diubah namanya menjadi CoreNLP.

StanfordNLP  ini sudah native python (bisa diinstall dengan pip install stanfordnlp),  menggunakan deep learning (pytorch) dan sudah menyediakan pretrained model untuk bahasa Indonesia.

Saat saya coba, ternyata lib ini memerlukan Python 3.6 dan 3.7.   Saya install saja versi yang terakhir, yaitu versi  3.7.2, sayangnya untuk versi ini Python harus dicompile manual. Langkah-langkahnya saya tiru dari: https://tecadmin.net/install-python-3-7-on-ubuntu-linuxmint/  tapi dengan modifikasi sedikit karena di artikel itu kurang dua library yaitu libffi dan liblzma (saya menggunakan Ubuntu 16).

sudo apt-get install build-essential checkinstall
sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
    libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev liblzma-dev
cd /usr/src
sudo wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
sudo tar xzf Python-3.7.2.tgz
cd Python-3.7.2
sudo ./configure --enable-optimizations
sudo make altinstall

Catatan: interpreter hasil compile  disimpan di /usr/local/bin/python3.7

Setelah pip install stanfordnlp, kode berikut adalah contoh penggunaannya. HATI-HATI, perlu satu jam untuk menjalankan kode ini, entah karena harus menggunakan GPU atau ada optimasi yang belum saya lakukan. Update: running berikutnya hanya perlu 1-2 menit, tetap lebih lama dibandingkan lib lain.

import stanfordnlp
stanfordnlp.download('id')   # download 1.4GB model
nlp = stanfordnlp.Pipeline(lang="id",use_gpu=False)
doc = nlp("Budi makan nasi enak sekali.")
print("token:")
doc.sentences[0].print_tokens()
print("dependency parse:")
doc.sentences[0].print_dependencies()

Hasilnya adalah sebagai berikut:


token:
Token index=1;words=[Word index=1;text=budi;lemma=budi;upos=NOUN;xpos=NSD;feats=Number=Sing;governor=2;dependency_relation=nsubj]
Token index=2;words=[Word index=2;text=makan;lemma=makan;upos=VERB;xpos=VSA;feats=Number=Sing|Voice=Act;governor=0;dependency_relation=root]
Token index=3;words=[Word index=3;text=nasi;lemma=nasi;upos=NOUN;xpos=NSD;feats=Number=Sing;governor=2;dependency_relation=obj]
Token index=4;words=[Word index=4;text=enak;lemma=enak;upos=ADJ;xpos=ASP;feats=Degree=Pos|Number=Sing;governor=3;dependency_relation=amod]
Token index=5;words=[Word index=5;text=sekali;lemma=sekali;upos=ADV;xpos=D--;feats=_;governor=2;dependency_relation=punct]

dependency parse:
('Budi', '2', 'nsubj')
('makan', '0', 'root')
('nasi', '2', 'obj')
('enak', '3', 'amod')
('sekali', '4','advmod')
('.', '2', 'punct') 

 

Belajar Investasi Saham

Update Jan 2019:
Perlu berhati-hati, terlepas sentimen negatif dan prediksi kuat terjadinya resesi 2019-2020, pasar saham Indonesia sepertinya tidak terpengaruh. Investor (retail) kita sepertinya masih bersemangat sekali. Ini justru yang buat saya khawatir.  Sekarang sulit cari saham yang  bagus (bagi saya) tapi dengan harga yang murah. Lebih baik jangan dipaksakan beli.
–end update–

Posting yang agak berbeda dengan biasa 🙂  tapi sebenarnya nanti berhubungan juga dengan NLP dan  machine learning.  Posting ini akan diupdate sejalan dengan perjalanan saya belajar tentang investasi di pasar saham, jadi mungkin posting ini nantinya akan sangat panjang.  Posting ini adalah sudut pandang saya yang awam.

Saya sudah lama tertarik untuk berinvestasi di pasar saham, tapi baru bisa mulai sekarang. Masalahnya, investasi saham walaupun dapat menghasilkan return tinggi, tetapi resikonya juga tinggi. Dalam kasus terburuk uang bisa berkurang atau bahkan hilang.  Itu sebabnya uang untuk investasi saham menunggu  antrian yang urutannya sebagai berikut: tabungan, dana pendidikan anak, deposito syariah, dana pensiun (diluar taspen PNS), investasi yang relatif aman baru terakhir saham. Ini yang saya lihat sering dilupakan orang, saya pernah baca pertanyaan  “Saya punya banyak hutang, saya tertarik bermain saham, bagaimana caranya?”, gawat kalau seperti itu.

Tadinya saya berminat untuk memulai dari reksadana dulu, tetapi melihat fee yang lumayan lalu banyak analis  yang rekomendasinya aneh, sepertinya lebih baik saya pilih sendiri saham yang mau saya koleksi. Rugi atau untung semua tanggung jawab saya 🙂

Banyak yang bingung mulai dari mana? untuk langkah pertama menurut saya adalah membaca sebanyak mungkin informasi. Hati-hati banyak informasi di internet, khususnya video Youtube yang hanya menyampaikan bahwa   investasi saham itu bisa untung besar tapi tidak  membahas kemungkinan rugi (yang bisa besar juga) dan tidak membahas bahwa tingkat kesulitannya cukup tinggi.  Banyak yang terlalu menyederhanakan seperti “Beli saham bluechip saja!”.

Mendapatkan keuntungan dari saham itu  bisa dengan dua cara: harga sahamnya naik (contoh beli 100/share lalu sebulan kemudian menjadi 300/share) dan melalui dividen (bagi hasil keuntungan perusahaan). Masalah utamanya adalah memilih saham yang mana dan kapan.

Saya lihat ada dua pendekatan: pendekatan pertama adalah berdagang saham jangka pendek.   Saat melihat potensi harga  naik, maka saham akan dibeli dan pada saat titik yang dianggap menguntungkan maka saham tersebut dijual, untung dapat diperoleh dari selisihnya. Ini bisa berlangsung dalam hitungan jam atau hari. Pendekatan ini mirip berselancar (mengikuti harga yang naik). Masalahnya sama dengan berselancar, salah pemilihan waktu sedikit saja, maka akan kehilangan ombak. Informasi yang digunakan umumnya hanya sejarah harga saham dan volume penjualan. Teknik yang perlu dipelajari untuk pendekatan ini disebut analisis teknikal.

Pendekatan kedua adalah jangka panjang (6 bulan sampai tahunan).  Pada pendekatan ini perlu dicari perusahaan yang bagus tapi sahamnya relatif dihargai murah. Saham milik perusahaan yang fundamentalnya bagus, walaupun saat ini dihargai murah,  nantinya akan naik juga dan kenaikannya bisa besar (berkali-kali lipat) sejalan dengan semakin besarnya perusahaan. Keuntungan juga bisa didapat dari dividen.  Masalahnya bagaimana menentukan perusahaan ini bagus? jangan-jangan murah karena memang mau bangkrut.  Informasi yang digunakan mulai dari laporan keuangan (tahunan, triwulan), analisis kemampuan manajemen, analisis sektor yang terkait dan sebagainya.  Pendekatan ini disebut value investing dan teknik yang perlu dipelajari adalah analisis fundamental.

Di Indonesia, yang saya lihat mayoritas yang digunakan adalah pendekatan pertama (trading).  Menurut saya karena alasan berikut:  1) lebih sederhana karena variabel yang digunakan lebih sedikit dan kuantitatif.  2) Perusahaan sekuritas mendapat fee jika ada transaksi, jadi mereka mendorong pelanggan melakukan transaksi sebanyak-banyaknya 3) lebih seru, seperti menonton film aksi atau balapan, ada keasyikan sendiri menyaksikan harga naik (atau turun) menit demi menit sebelum memutuskan beli atau jual. Walaupun saat ini sudah ada  mekanisme otomatis beli dan jual berdasarkan kriteria tertentu, tetapi tetap saja seru.

Saya pribadi lebih suka pendekatan kedua (value investing), karena tujuannya memang untuk jangka panjang (20 tahunan). Saya suka membaca, mencari dan menganalisis data dan  informasi. Wajar karena berkecimpung di bidang machine learning dan datamining 🙂 Membaca laporan tahunan adalah kegiatan menarik bagi saya. Saya juga tidak terlalu suka lagi nonton pertandingan dan bermain game (mungkin faktor umur?) jadi memonitor pergerakan harga saham jam demi jam (apalagi menit demi menit) bukan lagi hal yang terlalu menyenangkan. Lebih baik waktunya digunakan untuk hal yang lain. Sebagai bonus, biaya transaksi untuk sekuritas juga akan lebih murah.

Menurut saya memilih pendekatan trading atau value investing (atau gabungan) tergantung dengan minat, bakat dan tujuan tiap individunya. Yang penting bekali diri dengan ilmu sebelum masuk.  Tanpa ilmu,  sama saja dengan judi.  Banyak yang malas belajar dan ingin jalan pintas: “Udah, pokoknya apa saham yang harus saya beli besok?”, “Saham X bagus nggak gan?”.  Kadang bergidik,   mau beli barang 500 ribu saja kita  harus pikir-pikir dan banding-bandingkan dulu,  ini  jutaan rupiah dipertaruhkan  seperti dengan lempar dadu saja.

Karena saya memilih value investing, tentu saya lebih mendalami materi-materi yang terkait analisis fundamental. Video tutorial yang bagus adalah: https://www.youtube.com/watch?v=KfDB9e_cO4k&list=PLECECA66C0CE68B1E

Untuk buku:

  1. “Stock Market Investing for Beginner”, Tycho Press.
  2.  Peter Lynch (ada tiga buku, dengan urutan baca “One Up On Wall Street”, “Learn to Earn”,  “Beating the Street”).  Kalau tidak sempat cukup baca yang “One Up On Wall Street” saja, dua yang lain hanya pelengkap. Peter Lynch ini menarik karena dia termasuk fund manager yang fokus pada pemilihan saham dan sukses (rata-rata return 29.2% per tahun selama 13 tahun). Tapi perlu hati-hati untuk mengikuti petunjuk dia. Gaya investasinya  lebih agresif dan dia kerja gila-gilaan (mulai dari jam 6 pagi sampai malam termasuk sabtu). Aktivitasnya termasuk mendatangi secara langsung atau menelepon calon emiten yang dia incar, jadi salah satu kunci keberhasilannya adalah punya informasi yang mendalam. Mungkin aktivitas seperti ini yang bisa diganti dengan datamining? Saya paling hanya googling saja untuk informasi, tapi untuk sampai menelepon apalagi mendatangi perusahaan ya berat.
  3. “The Intelligent Investor”, Graham. Ini yang paling berat, sebaiknya dibaca terakhir.
  4. Update Jan 2019. Karena tertarik dengan video Youtubenya, saya beli buku Phil Town (Rule #1). Buku ini lebih pragmatis dengan aturan yang lebih jelas. Tapi perlu hati-hati karena  Phill Town sendiri tidak memperlihatkan kinerja portofolionya. Saya lebih cocok dengan Lynch yang lebih fleksibel, tapi ada beberapa hal yang bermanfaat juga. Intinya aturan dari buku ini: hanya beli saham dengan kondisi: 1) ROIC >10% (kenapa bukan ROE ya?)  2) Equity growth >10%  3) EPS growth >10%   4) Sales growth >10%   5) Free cashflow >10%.  Setelah itu hitung nilai intrinsik saham dengan cara hitung nilai 10 tahun ke depan berdasarkan PER, EPS growth, mundurkan ke harga saat ini berdasarkan target pertumbuhan 15% (Indonesia mungkin  harus lebih tinggi),  ini yang jadi harga intrinsik.  Lalu hanya beli yang harganya 50% dari harga intrinsik (margin of safety).

Perlu juga baca yang terkait pasar Indonesia, sayang judulnya agak  berlebihan:

  1. “Value Investing beat the market in 5 minutes”, Teguh Hidayat.  Lebih untuk pengantar, menggunakan bahasa non formal, cocok untuk orang muda.
  2. “Investasi Saham ala Fundamentalis Dunia”, Ryan Filbert, William Prasetya. Sisi dasar-dasar akuntasi, untuk membaca laporan keuangan.

Lumayan capek ya 🙂  Tapi saat investasi kita bisa hilang jadi nol rupiah menurut saya wajar perlu persiapan ekstra, itupun tetap tidak menjamin, tapi setidaknya jauh mengurangi resiko.

Selanjutnya bisa dimulai melihat-lihat laporan keuangan perusahaan incaran. Semua laporan emiten bisa dilihat di: https://www.idx.co.id/perusahaan-tercatat/laporan-keuangan-dan-tahunan/   Bisa juga mencari saham yang sesuai kritera yang diinginkan melalui stock screener: https://www.indopremier.com/ipotgo/marketanalysis.php?page=stockscreener

Untuk informasi tentang saham, berikut dua situs bagus dan ada app Android-nya juga:

  1. www.indopremier.com/ipotgo   Tapi hati-hati, tidak memperhitungkan stock split (contoh EPS ULTJ yang terlihat jadi drop drastis dari 16-17).
  2. rti.co.id (klik free trial)

Setelah punya gambaran saham yang mau dibeli, pilihan ini dapat diujicoba (disimulasikan) secara virtual pada situs stockbit.com sekalian belajar mekanisme beli-jual. Selanjutnya kita sudah siap untuk terjun membeli saham sesungguhnya.

Memilih dan Mendaftar pada Perusahaan Sekuritas

Transaksi saham harus dilakukan melalui perusahaan sekuritas sebagai perantara.  Mereka mendapat fee setiap transaksi  (untuk BNI sekuritas, fee-nya adalah 0.15% untuk beli dan 0.25% untuk jual). Ada banyak perusahaan sekuritas, tapi karena saya sudah punya rekening BNI dan ingin perusahaan sekuritas yang masih ada sampai 20 tahun lagi maka saya memilih BNI Sekuritas. Saya tanya-tanya via Twitter cepat dijawab (marketing), tapi untuk yang teknis, harus tanya via WA, dan responnya lambat (bisa 1jam) plus kurang ramah. Tapi yang penting dijawab sih bagi saya.

Saya buka rekening syariah, proses pendaftarannya: kita ke situs BNI sekuritas, isi berbagai formulir,  download formulir, print, beri paraf, beri materai, tandatangan lalu kirimkan via pos. Tunggu sampai 5 hari kerja. Total waktu yang diperlukan kira-kira 2 minggu. Nanti otomatis akan dibuatkan dua  RDI (Rekening Dana Investasi),  satu untuk syariah, satunya untuk yang biasa. Rekening ini yang digunakan untuk menampung dana untuk membeli, menjual atau dividen saham. Tidak ada info rekening syariah yang mana, tapi saran saya isi saja dua rekening itu masing-masing dengan 1 jt (nilai minimum). Walaupun punya dana banyak, sebaiknya mulai dari kecil dulu.

Ternyata yang disebut rekening syariah itu hanya sekedar membatasi saham apa yang bisa dibeli (misal saham bank, saham minuman keras tidak boleh dibeli). Jadi rekening yang non syariah saya gunakan juga,  yang penting jangan beli saham non syariah.  Bisa saja satu rekening untuk investasi jangka pendek satunya untuk jangka panjang. Setelah digunakan tidak perlu ada uang mengendap pada  rekening itu (semuanya bisa dibelikan saham). Saat membeli, nanti akan ada isian rekening mana yang akan digunakan, yang syariah ujungnya ada “S”.  Nanti akan dapat email dari sekuritas dan kita bisa tahu rekening syariah yang mana.

Kita juga akan diberikan user dan password untuk masuk ke aplikasi trading milik BNI (esmart) dan pin untuk bertransaksi. Saya tidak terlalu peduli dengan fitur-fitur trading, biasanya saya hanya buka sebentar dan langsung beli dengan harga yang ada.  Setelah transaksi, tidak otomatis uang di rekening didebet, ini dilakukan dua hari kemudian. Santai saja, BNI sekuritas akan mengirimkan email tentang transaksi, dividen dsb.

Selanjutnya tinggal memonitor fundamental emiten yang sahamnya kita miliki atau calon yang menarik untuk dikoleksi. Selama fundamentalnya bagus, saham jangan dijual. Perlu pembahasan terpisah untuk itu, dan saya masih belajar 🙂

Mengenai penerapan machine learning khususnya NLP pada pasar saham: saya belum mendalami, tapi umumnya ditujukan untuk fast trading (misalnya saat ada berita negatif tentang sektor X, maka semua saham terkait X dijual dalam waktu sekian milidetik). Istilah yang digunakan adalah algorithmic trading dan orang yang membuat algo-nya disebut  quant.  Salah satu tutorial  tentang algo trading ini dapat dilihat di https://www.youtube.com/watch?v=GlV_QO5B2eU  Sayangnya untuk pasar saham Indonesia sepertinya belum ada platform untuk backtest.

Pemanfaatan NLP untuk analisis fundamental sudah ada, tapi sepertinya tidak terlalu banyak.  Saya pernah baca paper yang memproses  laporan tahunan untuk memprediksi kinerja emiten. Menarik, karena memang setelah saya baca laporan tahunan,  dapat dilihat dirut yang isi tulisannya hanya normatif biasa-biasa saja, tapi ada juga yang kelihatan menguasai bidangnya dan bersemangat.  Bagusnya semua laporan tahunan ada versi bahasa Inggris-nya, jadi kita bisa menggunakan resources bahasa Inggris.  Mungkin ini yang paling dekat yang akan saya coba.

Memberikan Pelatihan Machine Learning & NLP

Dalam 4 bulan terakhir ini kami (saya dan istri) memberikan pelatihan machine learning untuk calon data analisis PT Pos dan NLP+Deep learning untuk sebuah perusahaan software.  Saya suka karena hal ini menjadi kesempatan untuk berdiskusi dengan pihak industri tentang apa yang mereka perlukan dari lulusan, dan bisa digunakan untuk memperbaiki proses pendidikan di kampus.

Di kampus saya mengajar kuliah pilihan datamining dan NLP sedangkan Lia mengajar machine learning, jadi dari sisi materi sebenarnya tidak terlalu masalah. Masalah utama adalah bagaimana memadatkan materi yang belasan SKS menjadi hanya beberapa hari saja.

Selection_181

Berdasarkan evaluasi saat pelatihan, menurut saya bentuk pelatihan ideal untuk machine learning  adalah:

  • Perlu profil rinci peserta pelatihan. Latar belakang peserta akan sangat berpengaruh, misalnya banyak calon data analis latar belakangnya adalah dari prodi Matematika atau Statistika.
  • Secara rinci perlu dibuat dan disepakati kompetensi yang ingin didapat, seperti “Peserta memahami X”, “Peserta dapat melakukan Y” dst.  Perlu disesuakan dengan jumlah jam pelatihan. Jangan terlalu memaksakan terlalu banyak materi jika waktunya terbatas.
  • Proporsi teori dan praktek sekitar 40:60 atau 50:50.  Mengapa teori mendapat porsi yang cukup besar? karena  saat ini sudah banyak tutorial dan lib untuk machine learning tetapi tanpa pembahasan konsep yang cukup, misalnya seputar rancangan eksperimen, evaluasi model.
  • Pretest – Posttest. Mengukur sejauh mana peningkatkan pengetahuan peserta.
  • Tugas berbentuk kasus yang dikerjakan berkelompok. Idealnya minimal ada dua sesi pelatihan dengan waktu yang terpisah sekitar 1-2 minggu. Di akhir sesi  ada   PR berbentuk analisis kasus yang setelah diolah harus dipresentasikan pada sesi berikutnya.
  • Evaluasi berbentuk ujian teori dan praktek dalam bentuk kasus.

Memang tahapan seperti test dan presentasi akan memerlukan waktu lama,  padahal seringkali  pelatihan  dirancang memberikan materi sebanyak-banyaknya dalam  waktu sesingkat-singkatnya. Tapi menurut saya kalau mau hasil optimal memang perlu  waktu yang cukup.

Deteksi Kesamaan (plagiarisme) Dokumen MS-Word dengan Python

Saya ditugasi prodi untuk mengecek kemiripan borang akreditasi prodi ilmu komputer dibandingkan dengan borang prodi pendidikan ilmu komputer yang sudah disubmit sebelumnya. Prodi ilmu komputer dan pendidikan ilmu komputer memang berbagi dosen, ruangan dan resource lainnya, jadi wajar kalau borangnya mirip. Tapi tentu jika dikti menggunakan software deteksi plagiarisme bisa saja nanti borang ditolak bahkan prodi kena penalti.

Saya sudah pernah membuat program yang mirip dengan Java, tetapi dengan library python, harusnya bisa dibuat lebih cepat, dan memang bisa dibuat hanya dalam beberapa jam saja 🙂

Bagian yang terlama adalah mencari dan mencoba-coba library,  tetapi akhirnya saya menggunakan dua: python-docx dan strsim.     Python-docx untuk membaca file MS Word dan strmsim untuk kemiripan string-nya. Setelah dicoba, ternyata pemrosesan teks di dalam tabel harus ditangani terpisah. Teks yang di dalam texbox juga tidak bisa dibaca oleh python-docx. Untuk kasus ini, terpaksa semua teks yang berada di dalam textbox dikeluarkan secara manual.

Kodenya adalah sebagai berikut:

from docx import Document
from similarity.ngram import NGram

jum_huruf_min = 20 #kalimat terlalu pendek diabaikan

#load file dan pindahkan ke memory

def doc_to_text(nama_file):
    doc = Document(nama_file)
    fullText = []
    for para in doc.paragraphs:
        par = para.text.lower().strip()
        if par != "" and len(par) > jum_huruf_min:
            fullText.append(par)

    #proses isi tabel
    print("=======================")
    tables = doc.tables
    for table in tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    par = paragraph.text.lower().strip()
                    if par != "" and len(par) > jum_huruf_min:
                        fullText.append(par)

    fullTextNoDup = list(set(fullText)) #buang duplikasi
    fullTextNoDup.sort()  # sort supaya lebih mudah dicek
    return fullTextNoDup 

jum_gram = 4
batas = 0.4 #threshold
gram = NGram(jum_gram)

dir = "C:\\yudiwbs\\dataset\\deteksi_plagiat\\"
file1 = 'borang_nondik_standard_4.docx'
file2 = 'borang_dik_standard_4.docx'
file_out = "kesamaan_standard4.txt"

list_par_doc1 = doc_to_text(dir+file1)
list_par_doc2 = doc_to_text(dir+file2)

file = open(dir+file_out, "w")

for par1 in list_par_doc1:
     for par2 in list_par_doc2:
         jarak = gram.distance(par1, par2)
         if ( jarak <=batas):
             print(par1)
             file.write(par1+"\n")
             print(par2)
             file.write(par2+"\n")
             print(jarak)
             file.write(str(jarak)+"\n")
             print("--")
             file.write("--\n")
             file.flush()

file.close()
print("Selesai===") 

Contoh hasilnya (semakin kecil nilainya maka semakin mirip):

--
sedangkan strategi pencapaian yang akan dilakukan oleh program studi ilmu komputer adalah:
strategi pencapaian yang dilakukan oleh program studi pendidikan ilmu komputer adalah:
0.30833333333333335
--
verifikasi dan validasi draft rumusan visi, misi, tujuan dan sasaran dengan cara melakukan rapat yang diikuti oleh tim penyusun internal, para perwakilan dosen dan pihak eksternal (alumni atau pengguna lulusan). dari hasil rapat tersebut terdapat beberapa saran dan masukan diantaranya:
validasi draft rumusan visi, misi, tujuan dan sasaran dengan cara melakukan rapat yang diikuti oleh tim internal, para dosen dan pihak eksternal. dari hasil rapat tersebut terdapat beberapa saran dan masukan diantaranya
0.24388111888111888
--

 

Dataset Klasifikasi Bahasa Indonesia (SMS Spam) & Klasifikasi Teks dengan Scikit-Learn

Setelah saya cari-cari, sepertinya  belum ada dataset klasifikasi Bahasa Indonesia yang bisa didownload dengan gampang dan berlisensi bebas (mirip seperti 20NewsGroup untuk Bahasa Inggris). Aneh juga kan kalau untuk kuliah atau pelatihan NLP Bahasa Indonesia malah menggunakan dataset Bahasa Inggris. Oleh karena itu berdasarkan dataset yang dibuat mahasiswa saya (dan dengan ijin dia), saya publish dataset untuk domain SMS spam dengan lisensi creative commons. Ada tiga kelas: SMS  normal, SMS penipuan, SMS promosi. Dua yang terakhir ini dapat dianggap spam. Jumlah instances ada 1143. Download di: nlp.yuliadi.pro/dataset 

Sekalian saya buat tutorial singkat untuk membuat classifier berdasarkan dataset tersebut dengan lib scikit-learn. Caranya: Install lib scikit-learn, download dataset, sesuaikan namaFile dengan lokasi data. (Catatan: ada spasi di nama file, nanti saya perbaiki). Akurasinya 0.90 dengan MultinomialNB seperti code di bawah dan 0.92 jika menggunakan linear SVM.


#%%
#load data
from collections import Counter
import csv
namaFile = "/home/yudiwbs/dataset_sms_spam _v1.zip"
data = []
label = []
with open(namaFile, 'r', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    next(reader) #skip header
    for row in reader:
        data.append(row[0])
        label.append(row[1])

print("jumlah data:{}".format(len(data)))
print(Counter(label))

#%%
#random urutan dan split ke data training dan test
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split( data, label, test_size=0.2, random_state=123)

print("Data training:")
print(len(X_train))
print(Counter(y_train))

print("Data testing:")
print(len(X_test))
print(Counter(y_test))

#%%
#transform ke tfidf dan train dengan naive bayes
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB
text_clf = Pipeline([('vect', CountVectorizer()),
                     ('tfidf', TfidfTransformer()),
                      ('clf', MultinomialNB())])
text_clf.fit(X_train, y_train)
#%%
# coba prediksi data baru
sms_baru = ['Anda mendapatkan hadiah mobil','nanti ketemu dimana?']
pred = text_clf.predict(sms_baru)
print("Hasil prediksi {}".format(pred))
#%%
#hitung akurasi data test
import numpy as np
pred = text_clf.predict(X_test)
akurasi = np.mean(pred==y_test)
print("Akurasi: {}".format(akurasi))

Mempercepat Tensorflow tanpa GPU

Kebanyakan orang sudah tahu bahwa GPU akan mempercepat proses pembuatan model dengan Tensorflow, masalahnya tidak semua mempunyai akses komputer dengan GPU. Laptop saya misalnya,  tidak memiliki GPU yang dapat digunakan oleh Tensorflow.

Saat menjalankan Tensorflow  mungkin ada yang terkena  warning seperti ini “The TensorFlow library wasn’t compiled to use SSE4.1 instructionn … SSE4.2 instructions .. AVX instructions “.  Itu adalah fitur-fitur CPU yang dapat mempercepat proses komputasi.  Default installer binary Tensorflow tidak menggunakan ini agar dapat men-support  CPU lama.

Solusi untuk meng-enable fitur ini adalah dengan mengcompile sendiri source code TensorFlow.  Saya pernah bahas tentang ini di https://yudiwbs.wordpress.com/2017/02/26/mencoba-tensorflow/    Tapi compile perlu waktu lama dan ribet.  Saya sekarang biasanya langsung install saja, praktis,  asal ada koneksi internet.

Saat ini ada alternatif lain, saya menemukan repo yang sudah meng-compile-kan Tensorflow dengan opsi AVX, FMA, SSE. https://github.com/lakshayg/tensorflow-build  Jadi tidak perlu compile sendiri dari source code 🙂

Saya menggunakan Pycharm, sayangnya tidak ada opsi install whl langsung dari IDE-nya, jadi perlu via terminal. Langkah-langkahnya (dengan virt-env) sbb:

Masuk ke directory project atau di mana virtenv berada dan aktifkan.

 source venv/bin/activate 

Pastikan (venv) muncul, soalnya saat percobaan pertama saya malah install di global. Cek versi python di virt-env ini, karena bahkan versi 3.5 dan 3.6 tidak compatible.  Cek juga versi gcc.

python --version
gcc -v

Download binary yang cocok di https://github.com/lakshayg/tensorflow-build, pastikan versinya sudah benar (ubuntu, python, gcc). Lalu install dengan pip biasa

pip install --ignore-installed --upgrade [lokasi .whl yang didownload]

Kembali ke Pycharm dan otomatis akan diindeks.

Penasaran tentang berapa peningkatan kecepatannya, saya coba dengan Keras untuk klasifikasi teks dataset review IMDB. Hasilnya ada peningkatan  27%  untuk  proses training (26 detik vs 36 detik).  Sangat lumayan  🙂