1. Home
  2. Docs
  3. Kelas Privat Python – 01
  4. Materi [Penerapan Python]
  5. Sentiment Analysis – Naive Bayes

Sentiment Analysis – Naive Bayes

Pada saat kita mempelajari tentang pengambilan data pada twitter kita mengetahui bahwa data yang kita dapatkan merupakan data teks. Misalkan kita mengambil 5 buah tweet dan memasukkan ke dalam tabel maka hasilnya kan terlihat seperti gambar di bawah.

Itulah yang disebut dengan corpus. Corpus adalah perpustakaan/kumpulan data dalam bentuk teks. Pada umumnya saat kita melakukan pengambilan data untuk NLP data yang kita dapatkan adalah dalam bentuk corpus seperti terlihat di atas. Akan tetapi, seperti yang kita pelajari di dua hari kebelakang bahwa penggunaan machine learning atau EDA kedepannya membutuhkan data dalam bentuk numerik, karena akan lebih mudah untuk dianalisa. Maka dari itu kita akan menggunakan yang dinamakan document-term matrix.

Document Term Matrix adalah penggambaran suatu corpus yang dalam bentuk matriks yang berdasar pada frekuensi suatu kata keluar. Jika kita menggunakan data sebelumnya untuk membuat document term matriks maka akan terlihat seperti gambar di bawah

Seperti yang kita lihat, corpus yang kita miliki telah memiliki bentuk matriks seperti matriks matermatika pada umumnya. Nah, penggunaan matriks ini lebih lanjut adalah dengan melakukan pembobotan dari suatu dokumen atau dalam hal ini adalah kalimat/paragraf dari sebuah tweet. Untuk tugas ini kita akan menggunakan konsep TF-IDF

Apa itu TF-IDF?

TF-IDF adalah singkatan dari Term Frequency — Inverse Document Frequency, yaitu seperti namanya? menghitung seberapa sering sebuah kata atau bahasan keluar. Secara sederhana, TF-IDF adalah pembobotan terhadap kata.

sumber : https://medium.com/@cmukesh8688/tf-idf-vectorizer-scikit-learn-dbc0244a911a

Seperti pada gambar di atas TF-IDF bekerja dengan mencari dua nilai utama yaitu TF (Seberapa sering suatu nilai keluar) dan IDF (nilai pembobotan dilihat dari seberapa sering suatu kata keluar, invers karena semakin sering keluar maka dia semakin kecil nilai pembobotannya).

Kita akan contohkan seperti ini, misalkan kita punya dua data dalam corpus kita.

A = Andi bermain bola
B = Budi bermain basket

Kita akan ubah bentuk tersebut kedalam bentuk term document matrix nya

Setelah itu kita akan mencoba mencari nilai df dan D/df nya. df adalah seberapa sering kata tersebut keluar pada corpus dan D/df adalah seberapa jumlah data (pada kasus ini dua, A dan B) atau pada gambar diatas ditulis dengan n lalu dibagi nilai df.

Karena kita sudah mendapatkan nilai n/df nya maka kita sekarang tinggal mencari nilai idf dari data. Untuk penambahan satu pada n dan df pada gambar utama, itu merupakan hasil persetujuan. Ada yang melakukannya ataupun hanya penggunakan +1 di akhir logaritma.

Dari tabel di atas kita sudah bisa melihat nilai pembobotan dari tiap kata, dimana kata ‘bermain’ memiliki bobot yang lebih rendah dibanding kata yang lain dikarenakan kata bermain lebih dua kali disebut pada keseluruhan dokumen dan menjadi lebih tidak unik.
Untuk mendapatkan pembobotan dokumen bukan hanya kata, sekarang kita lakukan langkah terakhir dengan mengalikan tf dan idf, dimana tf adalah kolom kedua dan ketiga (A dan B).

Hasil akhirnya tinggal kita jumlah kan kolom A dan B di akhir tabel. Ini akan menghasilkan nilai pembobotan,

A = 3,6
B = 3,6

Selamat, kita berhasil mengubah dokumen pada corpus kita menjadi bentuk matriks dan mendapatkan nilai pembobotannya. Dari hal ini kita akan lebih mudah untuk menggunakan corpus kita untuk hal seperti EDA atau machine learning.

Sentiment Analysis

Sekarang kita akan mencoba untuk melakukan Analsis sentiment menggunakan salah satu metode Supervised Learning yaitu Naive Bayes. Seperti yang kita tahu bahwa pada supervised learning kita membutuhkan dataset agar mesin kita dapat belajar jadi pastika kita mempunyai dataset sudah memiliki dataset tersebut. Bisa dengan cara melakukan analisis sentiment terlebih dahulu dengan menggunakan perbandingan antara kata negatif-positif seperti kemarin, atau dengan mencari dataset yang sudah diberi label di internet.

Pada kesempatan ini kalian bisa menggunakan dataset tweet di bawah, untuk memperingan kinerja pada kesempatan pertama ini maka diberikan dataset dengan ukuran kecil

Mari kita coba baca dataset kita lalu membaginya kedalam dua atribut, yaitu tweet dan label.

import pandas as pd
import csv

file = 'dataset_tweet_2.csv'

token_data = open(file)
tokens = csv.reader(token_data, delimiter=';')
tweets = []
label = []
for row in tokens:
    tweets.append(row[0])
    label.append(int(row[1].replace(',','')))

df = pd.DataFrame(columns=['tweets','label'])
df['tweets'] = tweets
df['label'] = label

print (df)

Maka akan menghasilkan,

                                               tweets  label
0   rt @napqilla: no 1, 3 ambisinya menguasai raky...      1
1   rt @pandji: nah gue pikir sentimen petahana ok...      1
2   rt @pandji: urutan pertama best moment #debat2...      1
3   rt @pandji: ini artikel yg menjelaskan ternyat...      1
4   rt @mrtampi: agus makin santai.\nahok makin sa...      0
..                                                ...    ...
76  rt @pandji: nah gue pikir sentimen petahana ok...      0
77  rt @josua_tm: ibu sylvi adalah contoh bahwa wa...      1
78  besok saya ajak kesana saja, saya udah survei ...      1
79  benerr bgt.. dan tidak mengajak penonton ikut ...      1
80  rt @gandy_koz: pak anis,kl pas libur lebaran i...      1

[81 rows x 2 columns]

lalu selanjutnya kita akan melakukan pembersihan tweet di atas, kita akan memanfaatkan modul stemming pada sastrawi, jadi jangan lupa untuk menambahkan import pada bagian library. pertama kita akan melakukan case folding lalu kita akan melakukan stemming.

import re,string

clean_tweets = []
for tweet in tweets:
    def hapus_tanda(tweet): 
        tanda_baca = set(string.punctuation)
        tweet = ''.join(ch for ch in tweet if ch not in tanda_baca)
        return tweet
    
    tweet=tweet.lower()
    tweet = re.sub(r'\\u\w\w\w\w', '', tweet)
    tweet=re.sub(r'http\S+','',tweet)
    #hapus @username
    tweet=re.sub('@[^\s]+','',tweet)
    #hapus #tagger 
    tweet = re.sub(r'#([^\s]+)', r'\1', tweet)
    #hapus tanda baca
    tweet=hapus_tanda(tweet)
    #hapus angka dan angka yang berada dalam string 
    tweet=re.sub(r'\w*\d\w*', '',tweet).strip()
    
    #stemming
    factory = StemmerFactory()
    stemmer = factory.create_stemmer()
    tweet = stemmer.stem(tweet)
    clean_tweets.append(tweet)

df['clean'] = clean_tweets
print(df.head())

maka akan menghasilkan,

tampilan dataframe

Machine Learning & Data Teks

Seperti yang kita tahu untuk dapat menggunakan sebuah model machine learning maka kita membutuhkan data dengan tipe numerik atau integer, akan tetapi salah satu satu feature yang kita miliki merupakan data teks. Nah pada kesempatan ini kita akan memanfaatkan metode perubahan data teks – matriks yang sudah kita pelajari sebelumnya, yaitu TF-IDF

Mari kita mulai, kita akan memanfaatkan metode TfidVectorizer pada library sklearn dan gaussian Naive Bayes.

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import GaussianNB

vectorizer = TfidfVectorizer (max_features=2500)
model_g = GaussianNB()

Lalu kita ubah data clean_tweet kita ke dalam bentuk TFIDF Vectorizer

v_data = vectorizer.fit_transform(df['clean']).toarray()

print (v_data)

maka akan menghasilkan,

  (0, 10)       0.18913840804590096
  (0, 232)      0.27777504205235853
  (0, 262)      0.27777504205235853
  (0, 230)      0.23692725517145605
  (0, 170)      0.20394859337799942
  (0, 222)      0.27777504205235853
  (0, 338)      0.40789718675599884
  (0, 214)      0.27777504205235853
  (0, 15)       0.5555500841047171
  (0, 284)      0.27777504205235853
  (0, 345)      0.0754070869995221
  (1, 138)      0.28117693158765905
  (1, 45)       0.2624008048150012
  (1, 240)      0.2624008048150012
  (1, 327)      0.28117693158765905
  (1, 263)      0.28117693158765905
  (1, 402)      0.24783690942774547
  (1, 241)      0.28117693158765905
  (1, 110)      0.19637671509980026
...
...

(0, 10) 0.18913840804590096

angka 0 melambangkan kalimat/tweet pertama,

angka 10 melambangkan kata ke 10 pada urutan kata di penggabungan,

0.18…. melambangkan nilai pembobotan.

Jika masih bingung dengan (0,10) coba baca lagi materi terkait TF IDF pada beberapa hari sebelumnya.

Setelah ini mari kita lakukan pembagian data menjadi data train dan testing lalu fit kedalam model kita.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(v_data, df['label'], test_size=0.2, random_state=0)
model_g.fit(X_train,y_train)

Dan kita lakukan penghitungan confussion matrix, classification report, dan accuracy score

from sklearn.metrics import classification_report, confusion_matrix, accuracy_score

y_preds = model_g.predict(X_test)

print(confusion_matrix(y_test,y_preds))
print(classification_report(y_test,y_preds))
print('nilai akurasinya adalah ',accuracy_score(y_test, y_preds))

Hasilnya adalah,

[[8 4]
 [1 4]]
              precision    recall  f1-score   support

           0       0.89      0.67      0.76        12
           1       0.50      0.80      0.62         5

    accuracy                           0.71        17
   macro avg       0.69      0.73      0.69        17
weighted avg       0.77      0.71      0.72        17

nilai akurasinya adalah  0.7058823529411765

Untuk melakukan prediksi jangan lupa untuk mengubah 0 dan 1 menjadi sebuah parameter string pada akhir langkah.

tweet = ''
v_data = vectorizer.transform([tweet]).toarray()
y_preds = model_g.predict(v_data)

#dengan asumsi bahwa 1 merupakan label positif
if y_preds == 1:
    print('Positif')
else:
    print('Negatif')

Peningkatan nilai akurasi sendiri bisa dilakukan seperti saat melakukan penerapan metode-metode supervised learning sebelumnya. Mengubah Metode juga bisa dilakukan untuk melihat metode mana dengan parameter mana yang paling baik untuk diterapkan.