Showing posts with label text processing. Show all posts
Showing posts with label text processing. Show all posts

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.


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