Sunday, November 13, 2022

Bridging Course 2022: University of Sheffield


Setelah sekian lama tidak ada artikel di blog ini, kali ini saya akan share salah satu pengalaman mendapatkan kesempatan Bridging Course 2022 (BC2022) ke University of Sheffield, United Kingdom. Bridging Course adalah salah satu beasiswa dari DIKTI yang dikhususkan untuk dosen di Indonesia yang telah diselenggarakan setiap tahunnya mulai dari tahun 2016. Kegiatan ini adalah sebagai persiapan bagi para dosen untuk melanjutkan study S3 ke Luar Negeri, dimana fokus nya adalah match-making antara calon supervisor dan calon siswa yang akan studi.

Pada tahun ini peserta BC2022 ke University of Sheffield berjumlah 14 dosen dari berbagai perguruan tinggi negeri dan swasta Indonesia. Selain ke ke Sheffield, ada beberapa kampus dan negara lain di tahun ini, yaitu ke University of Sopron, Hungary; National Taiwan University (NTU); dan University of New England, Australia. 

Perjalanan ini dimulai pada bulan April yaitu dengan dibukanya pengumuman pendaftaran dengan submit berkas maksimal 13 Mei 2022. Beberapa berkas yang harus di submit pada aplikasi yaitu: CV, Proposal penelitian S3, Sertifikat IELTS dan Surat ijin dari perguruan tinggi/LLDIKTI. Qodarullah, mendekati hari-H dateline submit berkas, anak ke-3 saya, Aydin (3 tahun) harus menjalani operasi usus buntu. Berkas ijin dari LLDIKTI dan surat pengantar dari dekan belum selesai saya urus, hal ini sangat menguras pikiran dan waktu. Alhamdulillah rekan saya, bu Rhisa membantu mengurus semua berkas, sampai mengantar surat ijin ke LLDIKTI. Semoga Allah SWT membalas semua kebaikannya bu 😊

Selanjutnya, sekitar minggu pertama bulan Juni 2022, DIKTI mengumumkan kandidat BC2022 yang lolos tahap pertama. Tahap berikutnya adalah tes interview untuk bisa lolos dan menjadi awardee BC2022 ini. Disini terdapat 110 kandidat dosen yang terjadwal pada sesi interview online. Pada sesi interview tersebut, saya memilih dari rumah, karena di kampus kurang kondusif environment-nya. Terdapat 2 interviewer dan 1 admin dalam sesi tersebut. Berbagai pertanyaan diajukan dalam bahasa Inggris oleh ke-2 interviewer terkait proposal penelitian yang sudah kita submit, seperti: background penelitian, keterbaharuan, metode dan juga pengalaman penelitian yang telah kita lakukan.  Alhamdulillah 40 menit berakhir juga sesi yang menegangkan tersebut. Saya merasa kurang maksimal dalam menjawab pertanyaa-pertanyaan dari interviewer, tentunya ikhtiar yang terbaik sudah saya lakukan, apapun hasilnya serahkan hanya ke Allah SWT.

Tanggal 4 Juli 2022, rekan dosen di Fisipol UGM, awardee Bridging Course tahun 2021, mengirim WA menginformasikan saya lolos sabagai awardee BC2022. Setelah membalas dengan ucapan terima kasih, saya segera mencari informasi resmi tersebut di website DIKTI. Alhamdulillah surat resmi tersebut menunjukan nama saya masuk kedalam 50 awardee BC2022. Pastinya ini semua karena Allah SWT memudahkan semua urusan saya.

Setelah 1 bulan tidak ada info terkait BC2022, akhirnya pada bulan Agustus diinfomasikan bahwa saya mendapatkan kampus tujuan di University of Sheffield, UK. Bersama dengan 14 dosen lain, kami mulai mengurus persiapan keberangkatan, yaitu VISA, Surat tugas negara (Satneg), Tiket dan akomodasi. Terjadwal kegiatan di Sheffield dimulai tanggal 10 Oktober 2022, tapi sampai dengan tanggal tersebut tidak semua Sheffiled's awardee terbit VISAnya. 

Aydin, see you on Dec. I will miss you..

Akhirnya, keberangkatan defer menjadi tanggal 26 Oktober 2022. Kegiatan ini dilaksanakan selama 7 Minggu, yaitu berakhir pada tanggal 17 Desember 2022. Perjalanan kali ini kita akan menggunakan maskapai Emirates yang akan berangkat dari Soekarno Hatta tanggal 27 Okt jam 00:40, transit di Dubai International Airport dan diperkirakan sampai Bandara Manchester, UK tanggal 27 Okt jam 12:40. Perjalanan Manchester ke Sheffield berkisar 1 jam menggunakan coach (mini bus) yang sudah disiapkan tim dari University of Sheffield. 

Rombongan 14 dosen tiba di Manchester Airport

Finally, sekitar jam 15:00 kita telah sampai di St Vincent's Place yang merupakan flat tempat kita stay selama di Sheffield. InshaAllah akan saya update cerita kehidupan di Sheffield dan beberapa info kegiatan Bridging Course ini. Semoga bermanfaat dan menambah motivasi teman-teman yang ingin melanjutkan mimpinya study abroad. Wassalam..

St Vincent's Place

Wednesday, July 27, 2022

Panen data di twitter menggunakan python

Tidak sedikit penelitian di bidang text mining dan NLP (Natural Language Processing) memanfaatkan data dari platform populer twitter. Pada artikel kali, saya akan share bagaimana membuat dataset dari twitter menggunakan library tweepy di python.

Twitter adalah social media, dimana pengguna memungkinkan share pesan singkat sebanyak maksimal 140 karakter yang biasa disebut dengan tweet. Karena tweet dikirim terus menerus, Twitter merupakan cara yang tepat untuk mengetahui peristiwa/tren terkini. Biasanya pengguna menggunakan hashtag (#) dengan keyword tertentu dalam mengkategorikan topik apa yang mereka share.

Disini saya dibahas bagaimana mendapatkan data dari twitter yang akan disimpan ke dalam file csv dan database MySQL. Sebelumnya anda perlu membaca dokumentasi library tweepy disini: https://docs.tweepy.org/en/stable/. Selanjutnya kita perlu mendaftar sebagai developer di Twitter API untuk mendapatkan Api key dan Secret key. 

Mendapatkan API key Twitter

  1. Buka halaman https://developer.twitter.com/en,
  2. Login atau registrasi jika belum mempunyai akun developer,
  3. Buka menu Application Console dan create new Twitter application,
  4. Isi semua form dan check Developer agreement.
  5. Selanjutnya anda akan mendapat credential berupa Api key, Api Secret, Access token dan Access token secret

Setup Tweepy

Jika environment di python anda belum terinstall tweepy, bisa anda lakukan instalasi library tersebut dengan perintah: pip install tweepy

Untuk melakukan koneksi dan autentifikasi ke twitter, gunakan code berikut ini dimana variabel consumer_key, consumer_secret, access_token dan access_token_secret yang sudah anda isikan dengan data dari application yang sudah anda create diatas:


auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)


Berikutnya kita perlu siapkan listerner untuk menangkap tweet yang di posting saat ini oleh pengguna berdasarkan keyword yang kita definisikan, sebagai contoh kita gunakan "jogja" dan "jogja istimewa". Pertama buat class StreamListener() selanjutnya jalankan class tersebut untuk mulai menarik data. Berikut code di python:

class StreamListener(tweepy.StreamListener):
def on_connect(self):
print("You are now connected to stream API")

def on_error(self, status_code):
print("An error has occured: " + repr(status_code))
return false

def on_status(self, status):
print(status.text)

stream_listener = StreamListener()
stream = tweepy.Stream(auth=auth, listener=stream_listener)
stream.filter(languages=['in'], track=["jogja", "jogja istimewa"])


Simpan file tersbut ke dengan nama "stream.py". Berikutnya bisa kita jalankan dari terminal atau command dengan perintah: python stream.py Bisa dilihat output di terminal tweet yang ditangkap oleh program tersebut. Untuk mengakhiri proses streamming tweet bisa menggunakan Ctrl + C atau close terminal / command aktif anda.

Menyimpan ke format CSV

Untuk menyimpan output tweet ke dalam csv, kita gunakan library csv dari python. Kemudian pada method on_status( ) di class StreamListener( ) perlu kita update dengan menambahkan kode untuk menulis ke file csv berikut ini:

with open('tweet_output.csv', 'a') as f:
    writer = csv.writer(f)
    writer.writerow([date, loc, name, desc, text, status.entities.get('hashtags')])
    time.sleep(10)


Pada kode diatas akan menulis output di file "tweet_output.csv" dengan kolom date, loc, name, desc, text, dan hashtags dari tweet yang dipisahkan dengan separator koma (,).

Berikut ini kode lengkap nya

import time
import tweepy
import csv

consumer_key = "<consumer key anda>"
consumer_secret = "<consumer secret anda>"
access_token = "<access token anda>"
access_token_secret = "<access token secret anda>"

class StreamListener(tweepy.StreamListener):
def on_connect(self):
print("You are now connected to stream API")

def on_error(self, status_code):
print("An error has occured: " + repr(status_code))
return false

def on_status(self, status):
text = status.text

# Menghilangkan karakter yg mungkin membuat error separator csv
remove_characters = [",", "\n"]
for c in remove_characters:
text.replace(c, " ")

try:
name = status.user.screen_name
desc = status.user.description
loc = status.user.location
date = status.created_at

with open('tweet_output.csv', 'a') as f:
writer = csv.writer(f)
writer.writerow([date, loc, name, desc, text, status.entities.get('hashtags')])
time.sleep(10)


except Exception as e:
print(e)

with open('tweet_output.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(['Date', 'Location','Name', 'Desc', 'Text', 'Hashtag'])


auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

listener = StreamListener(api=tweepy.API(wait_on_rate_limit=True))
streamer = tweepy.Stream(auth=auth, listener=listener)

print("Tracking data twitter on progress..")
streamer.filter(languages=['in'], track=['jogja','#jogja'])


Pada kode diatas di bagian stream.filter( ) ditambahkan parameter languages=['in'] untuk mengambil tweet yang menggunakan bahasa indonesia saja. Sedangkan untuk parameter track, bisa digunakan lebih dari 2 keyword.

Menyimpan ke database MySQL

Sedangkan untuk menyimpan data output tweet ke database MySQL, digunakan library pymysql. Selanjutnya kita membutuhkan satu method untuk melakukan koneksi dan penyimpanan ke tabel MySQL. Berikut ini kode dari method store_data( ) yang digunakan untuk menyimpan ke tabel di database:

def store_data(id, name, date, txt):
connection = pymysql.connect(host=host, user=user, password=password,
db=db, charset=charset, cursorclass=cursorclass)

try:
with connection.cursor() as cursor:
sql_save = "insert into tweet (tweet_id, screen_name, created_at, text) "
            sql_save += "values(%s, %s, %s, %s)"
cursor.execute(sql_save, (id, name, date, txt))
connection.commit()

cursor.close()
return
finally:
connection.close()


Dari kode diatas terlihat variabel connection digunakan untuk membuat koneksi ke database, variabel sql_save untuk menyimpan perintah query insert dan cursor.execute() untuk menjalankan perintah query tersebut. Untuk menerapkan di Streamer, pada method on_status() kita tambahkan pemanggilan method store_data() ini.

Sebelum menjalankan kode python tersebut di terminal, kita perlu membuat tabel di database MySQL terlebih dahulu. Berikut ini DDL untuk membuat kode di database dengan nama tabel "tweets".

CREATE TABLE `tweets` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `tweet_id` varchar(250) DEFAULT NULL,

  `screen_name` varchar(128) DEFAULT NULL,

  `created_at` timestamp NULL DEFAULT NULL,

  `text` text DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8


Berikut ini kode lengkap pada file "stream-db.py" yang bisa anda jalankan.

import pymysql.cursors
import tweepy

host = 'localhost'
user = 'root'
password = ''
db = 'tweet'
charset = 'utf8'
cursorclass = pymysql.cursors.DictCursor

consumer_key = "<consumer key anda>"
consumer_secret = "<consumer secret anda>"
access_token = "<access token anda>"
access_token_secret = "<access token secret anda>"

def store_data(id, name, date, txt):
connection = pymysql.connect(host=host, user=user, password=password,
db=db, charset=charset, cursorclass=cursorclass)

try:
with connection.cursor() as cursor:
sql_save = "insert into tweets (tweet_id, screen_name, created_at, text) "
            sql_save += "values(%s, %s, %s, %s)"
cursor.execute(sql_save, (id, name, date, txt))
connection.commit()

cursor.close()
return
finally:
connection.close()

class StreamListener(tweepy.StreamListener):
def on_connect(self):
print("You are now connected to stream API")

def on_error(self, status_code):
print("An error has occured: " + repr(status_code))
return false

def on_status(self, status):
text = status.text
remove_characters = [",", "\n"]
for c in remove_characters:
text.replace(c, " ")

try:
name = status.user.screen_name
tid = status.id
date = status.created_at

store_data(tid, name, date, text)

except Exception as e:
print(e)

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

listener = StreamListener(api=tweepy.API(wait_on_rate_limit=True))
streamer = tweepy.Stream(auth=auth, listener=listener)

print("Tracking data twitter on progress..")
streamer.filter(languages=['in'], track=['jogja', '#jogja'])


Selanjutnya bisa anda jalankan kode diatas dengan perintah python stream-db.py

Saat proses streamming berjalan, kemungkinan terdapat bebeapa warning message di terminal / command dikarenakan terdapat beberapa karekter yang tidak sesuai.  Hal ini bisa kita atasi dengan menambahkan beberapa filter di kode sebelum menyimpan di database.

Untuk mendapatkan data dalam jumlah besar, kita harus menjalankan stream tersebut secara terus-menerus. Pada artikel berikutnya inshaAllah akan saya bahas bagaimana membuat service stream tweepy di server Amazon AWS.


Tuesday, July 12, 2022

Sistem rekomendasi Content-based Filtering menggunakan PHP - MySQL (part 2)

Artikel berikut ini merupakan kelanjutan dari posting sebelumnya tentang implementasi sistem rekomendasi berbasis konten (Content-based filtering Recommender System) pada PHP. Silahkan bisa menyimak terlebih dahulu artikel bagian pertama disini: Sistem rekomendasi Content-based Filtering menggunakan PHP - MySQL (part 1).

Pada project ini, saya menggunakan library Sastrawi untuk melakukan pre-processing data, dan menggunakan library Nette/Database untuk akses ke database mysql, bisa anda cek dokumentasi lengkap di sini: https://doc.nette.org/en/database/core. Dengan menggunakan composer, kita bisa tambahkan code berikut di file composer.json:

{
"require": {
"sastrawi/sastrawi": "^1.2",
"nette/database": "^3.1"
}
}


Kemudian bisa dijalankan perintah composer update pada terminal untuk mendownload beberapa library diatas ke project kita.

Pertama kita siapkan class di PHP untuk menghitung TF-IDF dan Cosine similarity seperti yang sudah dibahas di artikel bagian 1. Kali ini, saya menggunakan nama class Cbrs dan nama file disesuaikan menjadi Cbrs.php. Berikut ini kode lengkap dari class tersebut.

Selanjutnya, kita siapkan file index.php untuk menampilkan daftar list hotel secara random dari tabel di database. Untuk tampilan HTML digunakan Bootstrap CSS supaya lebih rapi. Dan pada bagian akhir, kita buat file detail.php dimana akan menampilkan 1 hotel yang dipilih, dan kemudian akan di cari similarity/kesamaan dari sejumlah hotel dengan score paling besar berdasarkan id hotel yang dipilih tersebut.

Pada kode diatas, terdapat function pre_process() dan get_hotel_detail(), dimana kegunaan fungsi pertama untuk melakukan pembersihan data sebelum masuk ke class perhitungan TF-IDF dan cosine similarity di class Cbrs dan fungsi kedua untuk menampilkan detail hotel berdasarkan parameter id. Variabel $n digunakan untuk menyimpan jumlah item rekomendasi yang akan ditampilkan (top-n). Dan pada bagian perulangan variabel $r ditambahkan keyword continue; untuk menghilangkan item kunci, dimana nilainya = 1 dikarenakan menghitung similarity dari item yang sama. Selain itu, digunakan juga keyword break; untuk keluar dari perulangan jika jumlah n rekomendasi sesuai dengan variabel $n.

Tampilan antar muka detail hotel dan rekomendasi 8 item (beserta score similarity)

Jika anda membutuhkan kode lengkap dari project diatas beserta file database sql, silahkan tuliskan alamat email di bagian komentar. InshaAllah akan segera saya kirimkan ke email anda.


Friday, July 8, 2022

Sistem rekomendasi Content-based Filtering menggunakan PHP - MySQL (part 1)

Sebelum menyimak dan mengikuti tutorial dalam membangun sistem rekomendasi berbasis konten (content-based filtering) di artikel ini, sebaiknya membaca terlebih dahulu 2 artikel yang saya tulis sebelumnya, karena hal tersebut berkaitan dan saya menggunakan case/domain yang sama seperti sebelumnya.

Berikut artikel yang berkaitan dengan posting ini:

  1. Preprocessing text Bahasa Indonesia di PHP dengan Sastrawi
  2. Menghitung TF-IDF menggunakan kode PHP
Domain item yang akan saya bahas disini adalah data hotel, seperti pada artikel-artikel sebelumnya. Tahapan dalam membangun aplikasi sistem rekomendasi ini diawali dengan melakukan preprocesisng menggunakan library Sastrawi yang ada di PHP, dilanjutkan dengan melakukan pembobotan kata menggunakan metode TF-IDF dan terakhir adalah mengukur jarak kedekatan(similarty) dari 1 item ke item lainnya.

Pada artikel ini akan saya bahas bagian terakhir, yaitu menghitung similarity antar item menggunakan metode cosine similarity dan membuat top-n rekomendasi berdasarkan item yang dipilih. Kedua tahapan sebelumnya sudah ada di artikel yang saya sertakan link diatas 👆.

Cosine similarity

Untuk memudahkan pemahaman cara kerja cosine similarity, saya akan gunakan Spreadsheet untuk perhitungan nya dengan menggunakan contoh data hotel seperti pada case di artikel sebelumnya. Pada contoh data ini terdapat 3 dokumen dan 10 terms/kata yang akan kita ujicoba untuk perhitungan dan sudah kita beri bobot untuk masing-masing terms. Selanjutnya untuk menghitung similarity 2 item kita gunakan rumus berikut:

Pertama kita akan hitung terlebih dahulu sumproduct dari item A dan B, selanutnya kita bagian dengan perkalian panjang vektor A dan B. Pada Spreadsheet kita bisa gunakan formula SUMPRODUCT() sendangkan panjang vektor kita gunakan rumus SQRT(SUMSQ()).

Hasil dari pembobotan kata pada setiap dokumen

Berikut ini contoh rumus dari file Spreadsheet diatas untuk mencari similarity dari item d1 dan d2:

=SUMPRODUCT(C17:L17,C18:L18)/(SQRT(SUMSQ(C17:L17))*SQRT(SUMSQ(C18:L18)))

Selanjutnya kita bisa buat matrix untuk menghitung setiap dokumen. Score cosine similarity mempunyai rentang dari 0 - 1, yang artinya nilai mendekati 1 bearti kedua item tersebut sangat mirip, sedangkan mendekati 0 artinya kedua item tidak mirip. Perhitungan kedua item yang sama akan menghasilkan nilai 1.

Matrix perhitungan similaity antar item

Silahkan tuliskan alamat email anda di bagian komentar jika ingin mendapatkan file Spreadsheet untuk perhitungan seperti pada gambar diatas.

Cosine similarity di PHP

Berdasarkan perhitungan dari Spreadsheet dan rumus diatas, di PHP kita dapat membuat fungsi baru untuk mencari similarity antara 2 item dan mengurutkan hasil kemiripan score dari yang paling besar.

# Fungsi menghitung similarity ke semua dokumen
# parameter input = id dari item
public function similarity($d1){
    $score = [];
    foreach($this->doc_weight as $ndw => $w){
        $score[$ndw] = $this->cosim($d1, $ndw);
    }
    
    arsort($score);
    return $score;
}

private function cosim($d1, $d2){
    $dw = $this->doc_weight;
    
    # sum square dari 2 doc
    $dw1 = $dw[$d1];
    $dw2 = $dw[$d2];
    
    $dx = 0;
    $dx1 = 0;
    $dx2 = 0;
    
    foreach($this->corpus_terms as $t => $terms){
        $dx += $dw1[$t] * $dw2[$t];
        $dx1 += $dw1[$t]*$dw1[$t];
        $dx2 += $dw2[$t]*$dw2[$t]; 
    }
    
    return round($dx / (sqrt($dx1) * sqrt($dx2)), 4);
    
}

Kedua fungsi diatas merupakan kelanjutan kode dari Tfidf.php pada artikel berikut ini: Menghitung TFIDF menggunakan kode PHP, yang perlu anda tambahkan di class Tfidf. Selanjutnya pada file index.php anda bisa menjalankan fungsi tersebut dengan menggunakan parameter index array sebagai dokumen kunci yang akan dicari kemiripannya.

$hotel = array();
$hotel[1] = "Hotel Modern yang Terjangkau";
$hotel[2] = "Akomodasi modern, nyaman, dan tenang";
$hotel[3] = "Hotel bintang 3 yang mewah namun dengan harga yang terjangkau";

foreach($hotel as $key=>$item){
    $hotel[$key] = pre_process($item);
}

$cbrs = new Tfidf();
$cbrs->create_index($hotel);
$cbrs->idf();
$w = $cbrs->weight();  
$r = $cbrs->similarity(1);

print '<pre>';
print_r($r);
print '</pre>';

Dari kode diatas akan menghasilkan score kemiripan dari dokumen kunci(index array) sesuai dengan parameter yang di inputkan pada fungsi similarity.

Array
(
    [1] => 1
    [3] => 0.2062
    [2] => 0.1203
)

Pada posting berikutnya akan saya bahas detail bagaimana menggunakan dataset yang sudah tersimpan di tabel pada database MySQL untuk menampilkan item rekomendasi dari dokumen yang kita pilih.



Friday, July 1, 2022

Menghitung TF-IDF menggunakan kode PHP


Term Frequency, Inverse Document Frequency (TFIDF), merupakan sub-area dari Natural Language Processing(NLP) yang digunakan dalam information retrievel dengan tujuan untuk ekstrasi data. Sederhananya, bagaimana menghitung kemunculan setiap kata dalam dokumen dan memberi bobot pada setiap kata, dan menghitung skor untuk dokumen tersebut.

Sebelum kita bahas code di PHP, saya akan share penjelasan perhitungan manual TF-IDF menggunakan Spreadsheet atau Excel untuk memudahkan memahami cara kerjanya. Harapannya, anda bisa melakukan improvisasi code di bahasa pemrograman yang lainnya.

Pastikan sebelum mulai proses pembobotan kata dengan metode ini, text yang anda gunakan sudah melalui tahap preprocessing. Untuk preprocessing text di bahasa indonesia anda bisa menggunakan library sastrawi yang sudah saya bahas di artikel berikut ini: https://blog.ariflaksito.net/2022/04/preprocessing-text-bahasa-indonesia-di.html.

Berikut ini perhitungan di Spreadsheet menggunakan 3 dokumen seperti yang saya gunakan pada artikel preprocessing pada link artikel diatas.


Kolom token/term merupakan kata unique dari semua dokumen yang ada. Selanjutnya pada kolom tf, dibagi menjadi 3 dokumen untuk menghitung jumlah setiap kata yang ada di masing-masing dokumen. Pada kolom df akan menghitung jumlah kata yang muncul pada semua dokumen. Pada bagian ini kita hitung jumlah kemunculan, bukan jumlah total kata (digunakan rumus countif bukan sum). Kolom D/df merupakan pembagian dari jumlah dokumen (n) dan df. Jumlah dokumen yang kita gunakan untuk contoh perhitungan ini adalah 3.

Kolom IDF merupakan nilai log dari D/df, dan terkahir score tf-idf merupakan perkalian dari tf masing-masing dokumen dan token dengan nilai IDF. Hasilnya akan berupa matrix bobot dari dokumen dan term seperti pada gambar diatas.

Bisa anda tuliskan email di komentar jika menghendaki file Spreadsheet/Excel untuk contoh perhitungan  TF-IDF diatas.

Selanjutnya kita masuk pada inti pembahasan, yaitu membuat script PHP untuk perhitungan bobot kata seperti cara di Excel diatas. Pertama siapkan class dan beberapa fungsi di PHP, yaitu:

  • fungsi untuk mebuat index dari setiap kata
  • fungsi untuk menghitung idf
  • fungsi untuk menghitung weight/tf-idf

Terdapat 2 file pada code diatas, index.php dan Tfidf.php. Dimana fungsi-fungsi TF-IDF berada pada class Tfidf() di file Tfidf.php. Sedangkan file index.php digunakan sebagai input dokumen untuk menjalankan perhitungan tersebut.

Pada fungsi create_index() di class Tidf menjalankan proses untuk melakukan split setiap kata dan memberi informasi posisi dari setiap dokumen. Hasilnya bisa di lihat menggunakan fungsi show_index(). Fungsi idf() digunakan untuk menghitung menggunakan rumus log(D/df). Dan fungsi weight() untuk menghitung score/nilai dari tf-idf dari setiap kata/term di dokumen. Hasilnya berupa matrix/array dengan bobot pada setiap term di dokumen.

Berikut ini hasil dari kode tersebut, sama seperti pada perhitungan di excel diatas pastinya..

Array
(
    [1] => Array
        (
            [hotel] => 0.1761
            [modern] => 0.1761
            [jangkau] => 0.1761
            [akomodasi] => 0
            [nyaman] => 0
            [tenang] => 0
            [bintang] => 0
            [3] => 0
            [mewah] => 0
            [harga] => 0
        )

    [2] => Array
        (
            [hotel] => 0
            [modern] => 0.1761
            [jangkau] => 0
            [akomodasi] => 0.4771
            [nyaman] => 0.4771
            [tenang] => 0.4771
            [bintang] => 0
            [3] => 0
            [mewah] => 0
            [harga] => 0
        )

    [3] => Array
        (
            [hotel] => 0.1761
            [modern] => 0
            [jangkau] => 0.1761
            [akomodasi] => 0
            [nyaman] => 0
            [tenang] => 0
            [bintang] => 0.4771
            [3] => 0.4771
            [mewah] => 0.4771
            [harga] => 0.4771
        )

)

Referensi

  1. https://khozaimi.wordpress.com/2010/06/26/menghitung-tf-idf-engan-php/
  2. https://www.youtube.com/watch?v=B3UZ8DxHocQ&t=1s

Preprocessing text bahasa Indonesia di PHP dengan Sastrawi

 

the image was taken from https://www.analyticsvidhya.com

Bismillah.. setelah sekian lama belum ada artikel lagi, semoga bisa kembali produktif menulis di blog ini lagi dan terus konsisten  ✌.

Pada beberapa artikel sebelumnya terkait content-based filtering di Sistem rekomendasi, saya menggunakan salah satu library untuk preprocessing text yaitu Sastrawi di Python. Ternyata beberapa mahasiswa menanyakan penggunaan library tersebut di pemrograman PHP. Inilah salah satu alasan adanya artikel ini.

Source code dari Sastrawi bisa anda temukan disini: https://github.com/sastrawi/sastrawi. Library ini sudah ada pada beberapa bahasa pemrograman, seperti: Java, C, Python, Go, Rudy dan tentunya di PHP. Untuk menggunakan di PHP anda bisa melakukan instalasi menggunakan Composer. Apa itu composer? Silahkan beca artikel berikut ini: https://blog.ariflaksito.net/2018/08/berkenalan-dengan-composer.html

Pada terminal atau command line anda bisa menjalankan perintah berikut ini:
php composer.phar require sastrawi/sastrawi:^1

Library ini dapat digunakan untuk melakukan stemming di bahasa Indonesia, yaitu proses untuk menemukan kata dasar dari sebuat kata, dengan menghilangkan semua imbuhan termasuk dari awalan, sisipan, akhiran dan kombinasi dari awalan dan akhiran pada kata turunan.

Contohnya:

  • Menghilang = hilang
  • Terjangkau = jangkau
Selain itu, Sastrawi dapat juga digunakan untuk menghilangkan kata-kata yang memiliki arti tidak penting(stop-words) dalam proses pengolahan text, seperti: dan, atau, yang, dll.

Berikut ini code di PHP berupa fungsi untuk melakukan stemming dan menghapus stop-words:

Output dari code diatas sebagai berikut:

Array
(
    [1] => hotel modern jangkau
    [2] => akomodasi modern nyaman tenang
    [3] => hotel bintang 3 mewah harga jangkau
)

Dari output tersebut terlihat bahwa beberapa kata stop-words dan tanda koma (,) berhasil di hapus dan kata "terjangkau" diubah menjadi bentuk kata dasar "jangkau". Tahapan ini berguna untuk beberapa case berikutnya seperti: text classification, sentiment analysis atau yang akan saya bahas berikutnya yaitu menghitung pembobotan kata dengan TF-IDF untuk sistem rekomendasi berbasis content (content-based filtering).

Selamat mencoba..

Referensi

  1. https://adinyahya.com/cara-penerapan-stemming-dengan-menggunakan-library-sastrawi/
  2. https://github.com/sastrawi/sastrawi

Tuesday, December 7, 2021

Bedah kode Aplikasi Storage di Android

Storage/Media penyimpanan merupakan hal yang penting pada aplikasi berbasis mobile, salah satunya di Android. Berdasarkan data penyimpanan, di Android terdapat 2 jenis yaitu: data temporary dan data persistence. Data temporary umumnya diproses melalui internal storage dalam bentuk cache, sedangkan data persistence disimpan secara permanen dalam suatu file.

Pada artikel ini akan kita bahas jenis yang kedua yaitu data persistence. Android menyediakan beberapa solusi untuk menangani data persistence, tergantung dari sifatnya apakah private atau public. Beberapa solusi yang dipilih harus sesuai dengan kebutuhan spesifiknya, seperti apakah data yang disimpan akan bersifat private atau boleh diakses secara bebas (public) serta berapa banyak space yang dibutuhkannya. Selain itu, Android juga menyediakan cara untuk membuka data private ke aplikasi lain (apabila diperlukan), melalui Content Provider (inshaAllah akan dibahas di posting lainnya).

Images are taken from flaticon

Storage data persistence ini terbagi lagi menjadi 2 yaitu: 
  • Internal storage: direktori private yang hanya diakses pada aplikasi itu sendiri.
  • External storage: direktori public dapat diakses secara lebih luas pada aplikasi itu sendiri dan aplikasi lainnya.
Karakteristik internal storage:
  • Selalu tersedia/dapat diakses.
  • Menggunakan file sistem dari device.
  • Hanya bisa diakses pada aplikasi itu sendiri, kecuali secara eksplisit diatur agar dapat dibaca/tulis.
  • Saat aplikasi di-uninstall/clear data, sistem akan menghapus data di internal strorage.
Karakteristik exsternal storage:
  • Tidak selalu tersedia/dapat dihapus.
  • Menggunakan file sistem dari device atau external seperti SdCard.
  • World-readable, semua aplikasi dapat membaca.
  • Saat aplikasi di-uninstall, sistem tidak menghapus file tersebut.

Bedah kode aplikasi MyStorage

Langkah awal dengan membuat project baru di Android Studio, disini saya menggunakan nama aplikasi MyStorage dengan nama package net.ariflaksito.mystorage, minimal SDK adalah Android 5.0. Setelah itu di kita akan membuat contoh penggunaan internal dan external storage, pada MainActivity akan saya buat dua tombol untuk menuju ke activity InStorageActivity dan ExStorageActivity menggunakan Intent.

Jika anda ingin memahami lebih detail tentang Intent bisa disimak video berikut ini:


Silahkan anda siapkan layout seperti pada tampilan dibawah ini:

Tampilan awal MainActivity

Setelah itu kita bisa membuat 2 activity baru (Empty Activity) dengan nama : InStorageActivity dan ExStorageActivity. Untuk layout kedua activity tersebut, kita siapkan 4 Button dan 1 TextView seperti pada tampilan berikut :

Tampilan layout editor file

Untuk kode dari layout tersebut seperti dibawah ini:

Pada kode xml diatas kita perlu tambahkan beberapa resource di file strings.xml karena data-data text kita simpan di file res/values/strings.xml. Jika nanti diperlukan localize resource seperti aplikasi yang support multi bahasa lebih mudah dalam me-manage string tersebut.

Kode Activity Internal Storage

Selanjutnya kita edit bagian inStorageActivity. Pertama kita tambahkan class attribut nama-file, button dan textview seperti ini:

public static final String FILENAME = "myfile.txt";
Button btnCreate, btnEdit, btnRead, btnDelete;
TextView tvRead;

Selanjutnya kita set masing-masing komponen tersebut dan kita tambahkan label untuk ActionBar pada method onCreate( ) seperti berikut:

String title = getResources().getString(R.string.title_in_storage);
getSupportActionBar().setTitle(title);

btnCreate = findViewById(R.id.btn_create_file);
btnEdit = findViewById(R.id.btn_edit_file);
btnRead = findViewById(R.id.btn_read_file);
btnDelete = findViewById(R.id.btn_del_file);
tvRead = findViewById(R.id.tv_read);

Selanjutnya kita buat 4 method baru untuk menjalankan masing-masing fungsi, yaitu: createFile( ), editFile( ), readFile( ) dan deleteFile( ). Pada model internal storage kita gunakan fungsi getFilesDir( ) untuk meng-akses path dari storage. Untuk kode method createFile( ) seperti berikut:

void createFile() {
String isiFile = "Hello world!";
File file = new File(getFilesDir(), FILENAME);

FileOutputStream outputStream = null;
try {
file.createNewFile();
outputStream = new FileOutputStream(file, true);
outputStream.write(isiFile.getBytes());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Secara lengkap kode fungsi-fungsi yang lain dalam Activity tersebut seperti berikut:

Lokasi/path dari myfile.txt tersebut pada device berada di /data/data/(package-name)/files/myfile.txt. Kita dapat melihat melalui device file explorer di Android Studio untuk lokasi file tersebut. Sedangkan dari device file explorer akses ke path tersebut tidak bisa kecuali device anda sudah di root.

Lokasi file di internal storage

Kode Activity External Storage

Pada metode penyimpanan external, kita perlu tambahkan beberapa kode untuk melakukan cek perijinan dari Android API 23 keatas. Selain mendefinisikan nama file, kita perlu mendefinisikan code request untuk kembalian dari cek perijinan tersebut. Selanjutnya kita siapkan method baru yaitu checkPermission( ) dan onRequestPermissionsResult( ).

Pada method tersebut aplikasi akan menampilkan alert/pop-up ke pengguna apakah pengguna memberikan ijin aplikasi untuk merubah data-data di storage. Jika pengguna menekan tombol allow maka akan dilanjutkan ke proses selanjutnya, jika tidak maka akses ke storage tidak bisa dilakukan oleh aplikasi.

Alert pada device untuk perijinan akses storage

Selain itu, untuk external storage ini perlu menambahkan code permission di AndroidManifest.xml yaitu sebagai berikut:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Pada element <application> di file manifest juga perlu ditambahkan atribut berikut: 

android:requestLegacyExternalStorage="true"

Untuk akses lokasi/path dari file tersebut, disni kita menggunakan method yang berada di class Environment, yaitu: Environment.getExternalStorageDirectory(). Pada method createFile( ) dan editFile( ) juga perlu ditambahkan validasi untuk cek apakah media storage tersebut sudah di mount atau belum dengan kode berikut:

String state = Environment.getExternalStorageState();

if (!Environment.MEDIA_MOUNTED.equals(state)) {
return;
}

Layout di activity ExStorageActivity menggunakan file yang sama pada activity sebelumnya. Untuk kode lengkap nya seperti dibawah ini:

Anda bisa ujicoba aplikasi tersebut dengan membuat file baru, melihat isi datanya, kemudian cek di device explorer, apakah sudah ada nama file tersebut. Selain itu anda bisa coba edit isi file dan hapus file.

Kesimpulan

Kapan kita perlu menggunakan internal dan external storage? Internal storage paling baik digunakan jika tidak ada yang boleh mengakses file selain aplikasi itu sendiri. Sebaliknya, external storage paling baik digunakan jika file tidak memerlukan batasan akses, file dapat di share ke aplikasi lain atau user diperbolehkan akses file melalui usb atau pc.

Sunday, September 12, 2021

Mengenal Regresi linear dan perhitungannya

Disini kita akan bahas salah satu model statistik yang umum digunakan untuk Machine Learning untuk melakukan prediksi dengan cara supervised learning, yaitu regresi linear. Metode ini melibatkan 2 variabel dimana salah satunya adalah variabel independen (x) dan satu lagi adalah variabel dependen (y)

  • Independen berarti variabel ini sebagai variabel utama yang mungkin akan mempengaruhi nilai variabel kedua (dependen). 
  • Dependen berarti nilai variabel ini akan tergantung dari nilai variabel independennya, jika korelasi tinggi maka dependensi juga tinggi.

Untuk memudahkan pemahaman, kita gunakan data sample berat dan tinggi badan dari 10 orang sebagai berikut ini:

Data Tinggi Badan(cm) : 151,174,138,186,128,136,179,163,152,131
Data Berat Badan (Kg) : 63, 81, 56, 91, 47, 57, 76, 72, 62, 48

Regresi Linear adalah proses mencari garis linear yang menujukkan korelasi antara kedua variabel tersebut, garis linear itu akan didapat dengan sebuah persamaan :

y = ax + b atau y = w1x + w0

dimana: 
a atau w1 adalah slope / gradient / coefficient
b atau w0 adalah intercept / bias

Ciri dari problem regresi ini adalah kasusnya diminta menebak angka. Jenis outputnya bersifat continuous. Contoh lain dari regresi ini misalnya menebak curah hujan, harga rumah, jumlah kendaraan pemudik, dsb.

Perhitungan Manual

Untuk mendapatkan nilai coef(A) dan intercept/bias(B) digunakan rumus:


Gambar diatas menjelaskan detail perhitungan dari rumus tersebut kedalam excel. Dalam mencari nilai coef A dan intercept/bias B di excel digunakan formula pada sheet berikut:

A =((C25*C24)-(C23*C21))/((C25*C22)-(C23*C23))
B =((C21*C22)-(C23*C24))/((C25*C22)-(C23*C23))

Menggunakan Python

Perhitungan di python lebih sederhana, dimana kita bisa menggunakan library sklearn, seperti pada contoh kode dibawah ini:

Nilai coef dan intercept didapatkan dari kode baris ke-19 dan-20 diatas, sehingga akan didapatkan persamaan linear sebagai berikut:

y = 0.674 * x + (-38.455)

Sedangkan hasil dari plot data seperti pada gambar dibawah, dimana garis merah merupakan nilai prediksi dari model linear regresi dan titik-titik biru adalah 10 data training yang digunakan.

Regresi Linear Berganda

Regresi Linear Berganda adalah model regresi linear dengan melibatkan lebih dari satu variable bebas/independen dan persamaannya adalah

y = a1x1 + a2x2 + .. + anxn + b

Untuk pembahasan prediksi menggunakan regresi liner berganda kali ini akan diambil dari paper yang telah dipublish oleh mas Ervan Triyanto di jurnal Rabit, Juli 2019. Kasus ini adalah prediksi jumlah produksi padi di kabupaten Bantul dengan data yang digunakan dari tahun 2009 sampai dengan 2017. Di penelitian tersebut perhitungan nya diimplementasikan ke dalam aplikasi web menggunana PHP sebagai bahasa pemrogramannya. Di artikel ini akan digunakan python untuk perhitungannya dengan alasan kemudahannya.

Downlod pada link ini untuk mendapatkan artikelnya.  

Terdapat 1 variabel dependen yaitu jumlah produksi padi (dalam ton), sedangkan terdapat 3 variabel independen yaitu: curah hujan, luas lahan dan tingkat serangan hama. 

Berikut contoh code di Python untuk menghitung kasus produksi padi diatas:

Dari data diatas, didapatkan persamaan untuk prediksi sebagai berikut:

y = 5.929528x1 + 118.27991767x2 -175.71483753x3 + 8306.792151921123
dimana: luas lahan(x1), curah hujan(x2) dan hama(x3)

Evaluasi

Evaluasi untuk model linear regresi dapat dilakukan dengan beberapa metrik evaluasi seperti: MAE (Mean Absolute Error), MSE (Mean Squared Error) atau RMSE (Root Mean Squared Erorr).

RMSE merupakan salah satu cara untuk mengevaluasi model regresi linear dengan mengukur tingkat akurasi hasil perkiraan suatu model. RMSE dihitung dengan mengkuadratkan error (prediksi – observasi) dibagi dengan jumlah data (rata-rata), lalu diakarkan. RMSE tidak memiliki persamaan:

Pada kode python diatas, evaluasi model dituliskan pada baris kode ke-50 dengan menggunakan library metrics dari sklearn dan didapatkan score RMSE yaitu: 3.5045

Kesimpulan

Meskipun Linear regresi mudah diimplementasikan untuk melakukan prediksi pada data yang bersifat continuous, tetapi terdapat juga kekurangannya yaitu mudah terjadi overfitting dan sulit dilakukan prediksi jika relasi antara variabel dipenden dan independen tidak linear atau korelasi sangat rendah.

Jika membutuhkan dataset tersebut bisa tulis email pada komentar ya.. Bisa anda gunakan untuk penelitian dengan metode machine learning lainya dan silahkan dibandingkan nilai errornya dengan penelitian ini.

Referensi

  1. Jimy, Regresi Linier dengan R dan Python, https://medium.com/@jrendz/regresi-linier-dengan-r-dan-python-ebb80662c6da
  2. Jasme Moody,What does RMSE really mean?, https://towardsdatascience.com/what-does-rmse-really-mean-806b65f2e48e
  3. Triyanto, E., Sismoro, H., & Laksito, A. (2019). Implementasi Algoritma Regresi Linear Berganda untuk Memprediksi Produksi Padi di Kabupaten Bantul. Rabit : Jurnal Teknologi Dan Sistem Informasi Univrab, 4(2), 73-86. https://doi.org/10.36341/rabit.v4i2.666

Friday, August 20, 2021

Menghitung Similarity dan Prediksi rating pada Collaborative filtering menggunakan Python

Melanjutkan artikel sebelumnya, bagaimana menghitung similarity antara user di sistem rekomendasi collaborative filtering(CF) dengan menggunakan excel, pada artikel ini saya akan share menghitung similarity user dan prediksi rating dengan menggunakan bahasa python di jupyter notebook.

Prediksi rating

Pada eksperimen ini akan digunakan sample data yang sama seperti pada artikel sebelumnya, lebih detail bisa anda simak disini: "Memahami Collaborative filtering di Sistem rekomendasi". Untuk pembahasan notebook tersebut saya bagi kedalam 2 bagian yaitu: User-based dan Item-based.

User-based CF Notebook

Pertama diperlukan membuat sample data dari library pandas yang kemudian kita susun menjadi matrix untuk user, item, dan rating. Pada matrix tersebut, nilai Nan/kosong di ubah menjadi rating dengan nilai 0.


Matrix user-based rating

Selanjutnya kita akan buat nilai rerata dari tiap user dan membuat matrix baru dengan nilai rating diambil dari selisih rerata dan rating asli.


Untuk menghitung similarity, dapat menggunakan library dari sklearn yaitu cosine_similarity. Disini kita perlu membuat suatu fungsi dengan parameter yaitu matrix rating, user aktif (yang akan kita cari nilai rating kosongnya) dan nilai k (jumlah tetangga/neighbor).


Output dari fungsi diatas akan menghasilkan nilai similarity dari user: Arif ke user lainnya berdasar dari matrix yang kita inputkan di parameter.

(['Don', 'Bob'], [0.7071067811865476, 0.30151134457776363])
Langkah terakhir adalah kita buat fungsi predict( ) untuk menghitung prediksi nilai kosong dari matrix tersebut pada user Arif di item-4.


Output dari fungsi tersebut adalah prediksi rating pada kolom item-4 seperti berikut:

array([[4.42526623],
       [1.93594684],
       [3.42953847]])

Item-based CF Notebook

Sedikit berbeda dengan code sebelumnya, pada code item-based ini kita akan melakukan prediksi pada beberapa rating kosong. Mari kita bedah code tersebut dari awal. Dimulai dari membuat matrix rating data sample data seperti pada postingan ini: "Memahami Collaborative filtering di Sistem rekomendasi".


Matrix item-based rating

Berikutnya kita bisa buat fungsi untuk menghitung similarity antara 2 item


Sedangkan fungsi predict( ) untuk item-based ini sedikit lebih complicated, berikut langkah-langkah penjelasannya:
  1. Perulangan pertama adalah menjadikan nilai setiap item menjadi list
  2. Perulangan ke-2 kita gunakan untuk memfilter rating 0 dari tiap user
  3. Didalam perulangan ke-2, terdapat perulangan lagi untuk menghitung nilai prediksi dengan membaca per-baris dari rating item.

Setelah kita running fungsi diatas, maka akan menghasilkan output dalam bentuk list beberapa rating prediksi dari rating 0 di matrix yang kita inputkan pada parameter.

[2.4899844588770113, 3.4286096052067627, 2.0]
Sebagai informasi, pada kedua kode diatas belum ada fungsi untuk mengenerate item rekomendasi, disini hanya fokus pada bagaimana menghitung nilai similarity dan prediksi saja. Jika anda ingin mendapatkan kode lengkap di file python notebook (*.ipynb), silahkan isi pada kolom komentar dengan email anda, inshaAllah akan saya share kode lengkap tersebut.

Referensi

  1. Gambar diambil dari https://www.formstack.com/resources/blog-new-rating-field
  2. User-based collaborative filtering, https://www.geeksforgeeks.org/user-based-collaborative-filtering/
  3. Item-based collaborative filtering, https://www.geeksforgeeks.org/item-to-item-based-collaborative-filtering/