Sessi 13: Text Mining dan Natural Language Processing (NLP) Sederhana
Fokus: Memahami bagaimana data teks (unstructured data) dari Big Data diubah menjadi format numerik (vektor) agar dapat diproses oleh model Machine Learning. Kita akan fokus pada teknik Tokenization dan Bag-of-Words (BoW).
A. Tantangan Data Teks dan NLP
Dalam skenario Big Data, data tidak hanya berupa angka (numerik) atau kategori (kategorikal), tetapi juga dalam bentuk teks, seperti ulasan pelanggan, *log* server, atau artikel ilmiah. Natural Language Processing (NLP) adalah cabang dari Data Sains yang berfokus pada interaksi antara komputer dan bahasa manusia.
1. Mengapa Teks Sulit Diproses?
Model Machine Learning membutuhkan input dalam bentuk angka. Teks memiliki masalah kompleks:
- Ambiguitas: Satu kata dapat memiliki banyak arti (*polysemy*).
- Variasi Tata Bahasa: Kata yang sama bisa memiliki banyak bentuk (*run, running, ran*).
- Struktur Tidak Rapi: Data teks (*unstructured*) tidak memiliki baris dan kolom yang terdefinisi jelas seperti data tabel.
Tujuan utama *Text Mining* adalah mengubah teks (sekuens kata) menjadi **vektor fitur** (barisan angka) yang dapat dimasukkan ke dalam model klasifikasi (Regresi Logistik, Decision Tree, dll.).
B. Tahapan Preprocessing Teks Kunci
Sebelum teks diubah menjadi vektor, ia harus dibersihkan dan disiapkan. Kita akan menggunakan library **NLTK (Natural Language Toolkit)** di Python.
1. Tokenization
Tokenization adalah proses memecah suatu teks menjadi unit-unit yang lebih kecil, yang disebut **token**. Biasanya, token adalah kata, tetapi bisa juga berupa kalimat atau karakter.
import nltk
from nltk.tokenize import word_tokenize
# Unduh tokenizer yang diperlukan (hanya perlu sekali)
nltk.download('punkt')
teks = "Data Science sangat menarik dan penuh tantangan."
tokens = word_tokenize(teks)
print(f"Teks asli: {teks}")
print(f"Tokens: {tokens}")
# Output: ['Data', 'Science', 'sangat', 'menarik', 'dan', 'penuh', 'tantangan', '.']
2. Filtering (Stopwords)
**Stopwords** adalah kata-kata umum yang tidak memberikan makna kontekstual yang signifikan (e.g., *dan, yang, di, a, the*). Kata-kata ini dihilangkan untuk mengurangi dimensi data dan meningkatkan efisiensi model.
from nltk.corpus import stopwords
# Unduh daftar stopwords
nltk.download('stopwords')
# Contoh untuk bahasa Inggris (gunakan 'indonesian' untuk bahasa Indonesia)
stop_words_id = set(stopwords.words('indonesian'))
# Contoh teks (setelah tokenization)
tokens_filtered = [
word for word in tokens if word.lower() not in stop_words_id
]
print(f"Tokens setelah filtering stopwords: {tokens_filtered}")
# Output (setelah filtering): ['Data', 'Science', 'menarik', 'penuh', 'tantangan', '.']
3. Stemming atau Lemmatization
Kedua proses ini bertujuan untuk mengurangi kata-kata menjadi bentuk dasarnya (akar) untuk mengatasi variasi tata bahasa.
- Stemming: Mengambil akar kata secara kasar (e.g., *running* menjadi *run*, *menarik* menjadi *tarik*).
- Lemmatization: Lebih kompleks, menggunakan kosakata untuk mengembalikan kata ke bentuk leksikalnya (e.g., *better* menjadi *good*).
C. Merepresentasikan Teks sebagai Vektor (Bag-of-Words)
Setelah teks dibersihkan, langkah selanjutnya adalah mengubahnya menjadi matriks angka. Bag-of-Words (BoW) adalah model sederhana yang merepresentasikan teks sebagai kantong kata (*bag*) tanpa memperhatikan urutan kata, hanya frekuensi kemunculannya.
1. Konsep Dasar BoW
- Buat Vokabulari (Kamus) dari semua kata unik di seluruh dataset.
- Untuk setiap dokumen (baris data), hitung frekuensi kemunculan setiap kata dari Vokabulari.
- Hasilnya adalah matriks di mana barisnya adalah dokumen dan kolomnya adalah kata-kata unik (fitur).
2. Implementasi dengan CountVectorizer
Kita menggunakan CountVectorizer dari Scikit-learn untuk mengotomatisasi proses BoW.
from sklearn.feature_extraction.text import CountVectorizer
documents = [
"Pelayanan toko ini sangat buruk dan mengecewakan.",
"Produknya bagus, tetapi pengiriman sangat lama.",
"Sains data adalah bidang yang menarik.",
"Analisis data fisika membutuhkan akurasi tinggi.",
]
# Inisialisasi CountVectorizer
vectorizer = CountVectorizer()
X_bow = vectorizer.fit_transform(documents)
# Tampilkan Matriks BoW (sebagai DataFrame untuk visualisasi)
df_bow = pd.DataFrame(X_bow.toarray(), columns=vectorizer.get_feature_names_out())
print("--- Matriks Bag-of-Words ---")
print(df_bow)
# Interpretasi Matriks:
# Setiap kolom adalah fitur (kata unik).
# Setiap nilai adalah frekuensi kemunculan kata tersebut di dokumen (baris) terkait.
# Contoh: Kata 'sangat' muncul 1 kali di dokumen 0 dan 1 kali di dokumen 1.
D. Studi Kasus: Analisis Sentimen Sederhana
Dengan representasi BoW, kita dapat melakukan klasifikasi sentimen (Positif vs Negatif) menggunakan model yang sudah dipelajari (misalnya, Regresi Logistik atau Decision Tree).
Langkah 1: Data dan Pelabelan
# Data dokumen (X) dan Target Sentimen (y): 1=Positif, 0=Negatif
texts = [
"Saya benar-benar menyukai hasil eksperimen ini, sangat akurat.", # Positif
"Simulasi berjalan lambat dan banyak error, sangat mengecewakan.", # Negatif
"Model prediksi ini memiliki nilai R2 yang sangat tinggi, bagus.", # Positif
"Saya tidak puas dengan hasil analisis statistik yang keluar.", # Negatif
"Pelayanan laboratorium sangat profesional dan cepat." # Positif
]
sentiments = [1, 0, 1, 0, 1]
# Split Data (untuk demonstrasi, kita langsung ke pemodelan)
vectorizer_final = CountVectorizer()
X_vec = vectorizer_final.fit_transform(texts)
y = np.array(sentiments)
X_train, X_test, y_train, y_test = train_test_split(
X_vec, y, test_size=0.4, random_state=42
)
Langkah 2: Pelatihan dan Prediksi Model Klasifikasi
Kita menggunakan Regresi Logistik (dari Sessi 10) untuk memprediksi sentimen berdasarkan vektor BoW.
# Latih Regresi Logistik
model_sentimen = LogisticRegression(random_state=42)
model_sentimen.fit(X_train, y_train)
# Prediksi pada data uji
y_pred_sentimen = model_sentimen.predict(X_test)
# Evaluasi
acc_sentimen = accuracy_score(y_test, y_pred_sentimen)
print(f"Akurasi Model Sentimen: {acc_sentimen:.2f}")
# Hasil Akurasi akan bervariasi tergantung pada split, tapi ini menunjukkan pipeline bekerja.
# Contoh Prediksi Kalimat Baru
new_text = ["Hasil pengujian ini sangat buruk"]
new_vec = vectorizer_final.transform(new_text)
prediction = model_sentimen.predict(new_vec)
print(f"\nPrediksi untuk '{new_text[0]}': {prediction[0]} (0=Negatif, 1=Positif)")