Kategorisasi Artikel Saham

Pergerakan harga saham di pasar modal sangat ditentukan oleh sentimen yang berkembang. Sentimen yang berkembang mempengaruhi perilaku pelaku pasar modal (broker, investor) dalam melakukan aksi jual maupun beli saham. Diperlukan suatu cara untuk mendapatkan informasi yang lengkap, menyeluruh dan terkini tentang situasi yang menimbulkan sentimen tersebut. Proyek ini bertujuan melakukan pemilahan secara otomatis artikel-artikel di situs berita yang bermanfaat untuk analisa saham. Melalui otomatisasi perolehan berita diharapkan kekurangan yang terdapat dalam pemilahan berita secara manual dapat teratasi.

1. Pendahuluan

Pergerakan harga saham di pasar modal sangat ditentukan oleh sentimen yang berkembang. Misalnya, perubahan harga komoditas (minyak, kelapa sawit, emas), sentimen bursa regional (Dow Jones, Nikkei, Hang Seng), kebijakan pemerintah (BI Rate, The Fed), maupun terkait aktivitas perusahaan (laba, deviden, buyback). Sentimen yang berkembang mempengaruhi perilaku pelaku pasar modal (broker, investor) dalam melakukan aksi jual maupun beli saham. Dengan demikian diperlukan suatu cara untuk mendapatkan informasi yang lengkap, menyeluruh dan terkini tentang situasi yang menimbulkan sentimen tersebut.

Saat ini di situs-situs yang mengkhususkan diri dalam kegiatan jual/beli saham telah menyediakan fasilitas berita terkait aktivitas perusahaan publik atau emiten di bursa, misalnya etrading.co.id. Namun pemilahan berita ini masih bersifat manual. Pemilahan atau kategorisasi artikel secara manual memiliki kekurangan antara lain:

  • Membutuhkan bantuan manusia.
  • Lambat, tidak up-to-date atau up-to-minute.
  • Terbatas, mencakup sebagian kecil situs.

Proyek ini bertujuan melakukan kategorisasi secara otomatis pada artikel-artikel yang diperoleh di situs berita, terutama rubrik ekonomi atau bisnis, untuk mendapatkan artikel-artikel yang bermanfaat untuk analisa saham. Melalui otomatisasi perolehan berita diharapkan kekurangan yang terdapat dalam pemilahan berita secara manual dapat teratasi.

2. Klasifikasi Teks

Salah satu cara melakukan pemilahan artikel secara otomatis dengan menggunakan teknik machine learning, yaitu algoritma SVM (Support Vector Machine) [1]. Teknik ini termasuk supervised-learning, di mana diberikan panduan pengenalan pola dalam pemilahan, yang selanjutnya terbentuk model, dan model tersebut digunakan dalam proses klasifikasi.

Tahapan klasifikasi teks terbagi menjadi 3:

  1. Pemrosesan teks, terdiri dari tokenization (pemecahan teks menjadi token / kata), stopword (kata-kata yang dibuang dari artikel), stemming (pencarian kata dasar), dan feature extraction (pengambilan segi-segi klasifikasi).
  2. Pelatihan, yaitu mempelajari pola-pola teks menjadi model, sesuai acuan yang diberikan. Acuan berupa teks panduan yang berlabel negatif atau positif.
  3. Klasifikasi, yaitu menggunakan model untuk klasifikasi teks, menghasilkan perkiraan / prediksi dari klasifikasi. Hasil prediksi dapat mengandung bias maupun kesalahan.

3. SVM-Light

Proyek ini menggunakan implementasi SVM melalui program SVM-Light, terdapat dalam situs http://svmlight.joachims.org/ [2]. Program ini disebarkan dalam bentuk source-code dan bebas digunakan untuk kepentingan akademis.

SVM-Light terdiri dari 2 program:

  • svm_learn, untuk melatih acuan data yang diberikan menjadi model.
  • svm_classify, untuk proses klasifikasi teks dan menghasilkan prediksi.

Format file data yang digunakan kedua program terdiri dari 3 komponen:

  1. Label, yaitu pengolongan suatu data. Jenisnya adalah positif (bernilai 1, sesuai yang diinginkan), negatif (bernilai -1, tidak sesuai yang diinginkan), dan tidak berlabel (bernilai 0). Tidak berlabel dapat diartikan sebagai bahan testing atau klasifikasi, atau dapat dilakukan proses transduktif yaitu menentukan label sesuai pola sebelumnya [3].
  2. Feature, yaitu segi-segi yang digunakan sebagai bahan klasifikasi. Dalam hal ini digunakan nomor kata sebagai feature. Daftar kata diambil dari keseluruhan teks acuan, setelah membuang kata yang tergolong stopword dan dicari kata dasarnya. SVM-Light mengharuskan feature diurutkan menaik.
  3. Value, yaitu nilai dari feature. Dalam hal klasifikasi teks adalah bobot kata melalui penghitungan tf * idf (term frequency, inverse document frequency). Penghitungan ini dianggap mencukupi sebagai pembobotan kata. Pasangan Feature:Value misalnya 1:0.5, yang artinya nomor kata ke-1 dan bobotnya 0,5.

Contoh format data seperti berikut:

1 1:0.5 3:1 5:0.4  # positif
-1 2:0.9 3:0.1 4:2 # negatif
0 5:0.8 7:2.5 9:1  # tidak berlabel

4. Program dan Data

Sebagai pendukung dalam penerapan kategorisasi artikel, dibuat sejumlah program, modul, dan data pendukung. Seluruh program bekerja menggunakan antarmuka baris perintah (command line interface) pada masukan maupun keluaran. Seluruh program dapat dijalankan secara berurutan melalui batch-script hingga menghasilkan keluaran berupa file HTML.

image

Data dalam percobaan adalah artikel dari rubrik ekonomi / bisnis dari situs web.bisnis.com, detikfinance.com, dan economy.okezone.com. Tanggal pengambilan 1 Desember 2008 hingga 5 Desember 2008. Total terdapat 804 artikel. Sebagai bahan pelatihan, diberikan pelabelan untuk artikel bertanggal 1 Desember 2008, sejumlah 162 artikel. Selebihnya (804 – 162 = 642) artikel diberi label secara transduktif. Sebagai bahan testing diambil artikel bertanggal 8 Desember 2008, sebanyak 35 artikel, dengan disertai label sebagai bahan evaluasi ketepatan prediksi.

Korpus yang digunakan memiliki tag doc (pembatas dokumen), docid (nomor dokumen), label (label untuk klasifikasi), title (judul) dan text (isi dokumen). Contoh korpus sebagai berikut:

<DOC>
<DOCID>OKEZONE 08/12/2008 19:58</DOCID>
<LABEL>-1</LABEL>
<TITLE>Pemerintah Tetap Untung dengan Harga Premium & Solar Rp4.500</TITLE>
<TEXT>JAKARTA – Pemerintah diminta untuk kembali memberlakukan…</TEXT>
</DOC>

Berikut keterangan file program dan data yang terlibat dalam percobaan:

  1. http_get.php: Fungsi-fungsi untuk mengambil isi situs. Berbentuk script PHP untuk memudahkan proses penarikan, mengingat fasilitas di situ sangat lengkap.
  2. saham_ambil.php: Mengambil artikel dari situs web.bisnis.com, detikfinance.com, dan economy.okezone.com. Parameter program masih bersifat hard-coded.
  3. berita_saham.txt: Hasil dari pengambilan artikel sebagai bahan pelatihan.
  4. berita_saham_t.txt: Hasil pengambilan artikel untuk testing.
  5. indonesian.stp: Daftar stopword bahasa Indonesia.
  6. kamus.txt: Daftar kata dasar dalam bahasa Indonesia.
  7. svm_learn.exe: Program SVM-Light untuk pelatihan korpus data menjadi model.
  8. svm_classify.exe: Program SVM-Light untuk klasifikasi korpus berdasarkan model menjadi prediksi.
  9. kateg_idx.pl: Pra Proses Artikel (stopword, stemming, indexing). Input adalah file korpus dan hasil adalah file indeks.dat (format Perl Storable).
  10. Stemmer.pm: Module Perl untuk proses stemming bahasa Indonesia.
  11. kateg_svm.pl: Konversi file korpus ke format SVM-Light. Input adalah korpus dan adalah hasil file menggunakan nama sama ditambah akhiran ".dat".
  12. kateg_html.pl: Pembuatan file HTML dari file Prediksi. Input adalah file berita dan prediksi, dengan output file menggunakan nama sama ditambah akhiran ".html".

5. Pemakaian Program

Setelah semua program dan data siap, tahap akhir adalah melakukan uji coba klasifikasi teks. Dalam proyek ini keluaran yang dihasilkan adalah file statis berformat HTML. Program dijalankan pada sistem operasi Microsoft Windows. Hasil dari pemakaian serangkaian program, melalui batch-script, seperti di bawah ini.

C:\>rem php saham_ambil.php ==> bila ingin mengambil file

C:\>perl kateg_idx.pl berita_saham.txt
Pra Proses Artikel (stopword, stemming, indexing)
Indeks 804 dokumen selesai.

C:\>perl kateg_svm.pl berita_saham.txt
Konversi file korpus ke format SVM-Light
Konversi 804 dokumen selesai [berita_saham.txt.dat]

C:\>svm_learn.exe -v 0 berita_saham.txt.dat berita_saham.mod

C:\>perl kateg_svm.pl berita_saham_t.txt
Konversi file korpus ke format SVM-Light
Konversi 35 dokumen selesai [berita_saham_t.txt.dat]

C:\>svm_classify berita_saham_t.txt.dat berita_saham.mod prediksi
Reading model…OK. (450 support vectors read)
Classifying test examples..done
Runtime (without IO) in cpu-seconds: 0.00
Accuracy on test set: 82.86% (29 correct, 6 incorrect, 35 total)
Precision/recall on test set: 44.44%/80.00%

C:\>perl kateg_html.pl berita_saham_t.txt prediksi
Pembuatan file HTML dari file Prediksi
Konversi 35 dokumen selesai [berita_saham_t.txt.html]

File hasil HTML menampilkan judul dan sebagian teks dari tiap-tiap artikel yang sesuai hasil prediksi. Dari hasil eksekusi di atas terlihat tingkat akurasi adalah 82,86%. Sesuai klaim pembuat SVM-Light dan contoh korpus dari artikel-artikel Reuters (sudah diklasifikasi), tingkat ketepatan dapat mencapai 98%. Kesalahan prediksi dalam percobaan ini dapat disebabkan pelabelan saat pelatihan yang salah, mengingat membedakan artikel-artikel yang memenuhi kategori analisa saham tidaklah mudah. Contoh file HTML seperti di bawah.

Daftar Artikel Saham

1. Tak Turunkan Suku Bunga Pinjaman, Bank Cari Penyakit

JAKARTA – Belum adanya respons dari dunia perbankan untuk ikut menurukan suku bunga pinjaman pascapenurunan suku bunga acuan Bank Indonesia (BI) rate, dinilai hanya …

2. BEI Pantau Sumalindo Lestari Jaya

JAKARTA – Bursa Efek Indonesia (BEI) menyatakan terjadi penurunan harga saham PT Sumalindo Lestari Jaya Tbk (SULI) di luar kebiasaan dibandingkan dengan periode …

3. Kenaikan Biaya Pencatatan Bebani Emiten

JAKARTA – Rencana Bursa Efek Indonesia (BEI) yang akan menaikkan biaya pencatatan saham dan biaya pencatatan tahun (annual listing fee) dinilai tidak tepat. Pasalnya, …

4. Bursa Asia & Eropa Gegap Gempita

Jakarta – Bursa-bursa Asia melonjak tajam setelah akhir pekan lalu Wall Street menguat tajam, berkat harapan bahwa krisis finansial akan segera berakhir. Bursa-bursa Eropa pun …

6. Penutup

Percobaan dari proyek ini menunjukkan kategorisasi artikel saham secara otomatis dapat dilakukan menggunakan algoritma SVM dengan tingkat ketepatan cukup tinggi. Bias dan kesalahan prediksi yang terjadi disebabkan konteks artikel cukup sulit untuk dibedakan oleh manusia, baik ketika pelabelan maupun hasil klasifikasi. Pengembangan lebih lanjut dapat dengan mengintegrasikannya pada situs dinamis / database dan diupdate secara berkala. Pada akhirnya, semoga program sederhana ini dapat bermanfaat sebagai pembelajaran lebih lanjut pada topik Pemrosesan Teks.

7. Referensi

  1. Vladimir N. Vapnik, The Nature of Statistical Learning Theory. Springer, 1995.
  2. T. Joachims, Text Categorization with Support Vector Machines: Learning with Many Relevant Features. Proceedings of the European Conference on Machine Learning, Springer, 1998.
  3. Thorsten Joachims, Transductive Inference for Text Classification using Support Vector Machines. International Conference on Machine Learning (ICML), 1999.

8. Lampiran

1. kateg_idx.pl


#!/usr/bin/perl
# Mengindeks artikel sebagai bahan training

use strict;
use Storable;
use Stemmer;

# file yg diproses dari argumen --
print "Pra Proses Artikel (stopword, stemming, indexing)\n";
die("Sintaks: $0 <file berita> [out: index.dat]\n") if !$ARGV[0];

# baca dari file file input; hasil file output: [input.svm] --
my $file = $ARGV[0];
open(FH, $file) or die($file. ": $!");
$/ = "</DOC>\n";

# struktur data untuk index.dat
my %rec = (         
  'N_dok'=>0,       # total dokumen
  'kata'=>{},       # hash frekuensi kata, kata: dok{frek}
  'pos_dok'=>()     # array posisi awal tiap record
  );

# simpan posisi 0 untuk dokumen ke-1
push @{$rec{'pos_dok'}}, 0;
my $N_dok = 0; my $no_kata = 1; my $text;
my ($kata, $tda, $str, $err, $no);

while (<FH>) {
  # tambah jumlah dokumen
  $N_dok++;
  # simpan posisi awal dokumen
  push @{$rec{'pos_dok'}}, tell FH;
  # ambil hanya title dan text
  while (m/<(TITLE|TEXT)>(.+)<\/\1>/gs) {
    # buang tanda baca (standar perl)
    ($text = $2) =~ s/[[:punct:]]+/ /gs;
    # tambahkan frekuensi kata dari tiap-tiap dokumen
    while ($text =~ m/\b([[:alpha:]]+)\b/gs) {
      $kata = lc $1;
      next if Stemmer::IyaStopword($kata);
      ($str, $tda) = Stemmer::BuangImbuhan($kata);
      next if Stemmer::IyaStopword($str);
      # nomor kata pada dok-0
      $rec{'kata'}{$str}{0} = $no_kata++ if !$rec{'kata'}{$str};
      $rec{'kata'}{$str}{$N_dok}++;
    }
  }
}

# simpan data ke file index.dat
$rec{'N_dok'} = $N_dok;
store \%rec, 'index.dat';

close(FH);
print "Indeks $N_dok dokumen selesai.\n";

2. kateg_svm.pl


# Konversi korpus ke format SVM-Light

use strict;
use Storable;
use Stemmer;

# file yg diproses dari argumen --
print "Konversi file korpus ke format SVM-Light\n";
die("Sintaks: $0 <file korpus> [out: <file korpus>.dat]\n")
  if !$ARGV[0];

# baca dari file file input; hasil file output: [input.svm] --
my $file = $ARGV[0];
open(FH, $file) or die($file. ": $!");
open(FO, ">". $file. ".dat") or die($file. ".dat". ": $!");
$/ = "</DOC>\n";

# ambil index + data dari file index.dat --
my $rec = retrieve('index.dat');
my %hkata; my %hashx; my $x;
my ($text, $kata, $tda, $str, $err, $no);
my $label; my $n_dok = 0;

while (<FH>) {
  %hkata = (); %hashx = ();
  $n_dok++;
  # ambil hanya title, text, label
  while (m/<(TITLE|TEXT|LABEL)>(.+)<\/\1>/gs) {
    # bila label
    if ($1 eq 'LABEL') { $label = $2. " "; next; }
    # buang tanda baca (standar perl)
    ($text = $2) =~ s/[[:punct:]]+/ /gs;
    # tambahkan frekuensi kata dari tiap-tiap dokumen
    while ($text =~ m/\b([[:alpha:]]+)\b/gs) {
      $kata = lc $1;
      next if Stemmer::IyaStopword($kata);
      ($str, $tda) = Stemmer::BuangImbuhan($kata);
      next if Stemmer::IyaStopword($str);
      next if !$rec->{'kata'}{$str};
      if (!$hkata{$str}++) {
        $hashx{$str} = $rec->{'kata'}{$str}{0};
      }
    }
  }
  # urutkan kata / feature menaik --
  next if !%hkata;
  my @keys_k = sort { $hashx{$a} <=> $hashx{$b} } keys %hashx;  

  # setelah terbentuk array kata, hitung satu per satu --
  for (@keys_k) {
    $str = $_;
    my %hash = %{ $rec->{'kata'}{$str} };
    my @key = keys %hash;
    # hitung idf per kata untuk bobot dokumen --
    my $idf = log($rec->{'N_dok'} / scalar @key) / log(2);
    # hitung bobot tf x idf --
    $label = $label. " ". $hash{0}. ":". sprintf("%.2f", 
      $hkata{$str} * $idf);
  }
  # simpan per baris sesuai format --
  print FO $label, "\n";
}

close(FH);
close(FO);

print "Konversi $n_dok dokumen selesai [$file.dat]\n";

3. kateg_html.pl


# Memproses file korpus dan prediksi menjadi HTML

use strict;

# file yg diproses dari argumen --
print "Pembuatan file HTML dari file Prediksi\n";
die("Sintaks: $0 <korpus> <prediksi> [out: <korpus>.html]\n") 
  if !$ARGV[0] || !$ARGV[1];

my @hasil = (); my $idx = 0;

# baca dari file prediksi; hasil file output: [input.svm] --
open(FH, $ARGV[1]) or die($ARGV[1]. ": $!");
push @hasil, $1 while (<FH> =~ m/(\S+)/);
close(FH);

# baca dari file artikel input; hasilkan html --
my $file = $ARGV[0];
open(FH, $file) or die("$file: $!");
$/ = "</DOC>\n";
open(FO, ">$file.html") or die("$file.html: $!");

print FO <<END;

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title> Daftar Artikel Saham </title>
 </head>

 <body>
  <h2> <center>Daftar Artikel Saham</center> </h2>
  <hr>

  <ol>

END

while (<FH>) {
  next if @hasil[$idx++] < 0;
  # ambil hanya title, text
  while (m/<(TITLE|TEXT)>(.+)<\/\1>/gs) {
    print FO "<li><b>$2</b><br>\n" if $1 eq "TITLE";
    print FO substr($2, 0, 400), "...</li>\n" if $1 eq "TEXT";
  }
}

my @tgl = localtime(time);
my $tgs = $tgl[3]. "-". ($tgl[4]+1). "-". ($tgl[5]+1900);

print FO <<END;

  </ol>
  <hr>
  Last updated: $tgs
 </body>
</html>

END

print "Konversi $idx dokumen selesai [$file.html]\n";

3 Komentar »

  1. aang nahrowi said

    Asslkm.Boleh minta emailnya mpu gondrong ngak??coz mau nanya program ttg PERL.Please

  2. anak ilkom said

    Ah lu mah ang, bisanya minta source code mulu, mikir dikit napa?!!!

  3. alim said

    Pak…saya ingin tau stemmer yang digunakan diprogram bisa didownload dimana ya?Kalau Bapak ada, boleh gak saya minta, saya sedang Tugas Akhir tentang SVM dan melibatkan stemming juga untuk bahasa Indonesia…
    Terimakasih…🙂

RSS feed for comments on this post · TrackBack URI

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s