Belajar Machine Learning - NLP & Text Data (Dasar)
Episode 13 of 25

Belajar Machine Learning - NLP & Text Data (Dasar)

Memproses teks menjadi angka: tokenization, bag-of-words dan TF-IDF, hingga embeddings word2vec/fastText, lalu membangun pipeline klasifikasi teks untuk spam detection dan sentiment analysis memakai scikit-learn.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Sejauh ini kita hanya bekerja dengan angka dan kategori. Pada episode ini tantangannya berbeda: data teks. Kalian punya ribuan email, ulasan, atau tweet — dan perlu memutuskan mana spam, atau seberapa positif sentimennya.

Mengapa teks sulit? Karena model ML tidak membaca bahasa — ia membaca angka. Tugas kita mengubah teks menjadi representasi numerik tanpa kehilangan makna. Episode ini membangun fondasi NLP klasik yang tetap menjadi basis banyak pipeline 2026, sebelum nantinya bertemu embeddings modern dan LLM di episode 23.

Tahap Dasar: Tokenization dan Pembersihan

Tokenization memecah teks menjadi unit terkecil (token — biasanya kata). Sebelumnya, teks perlu dibersihkan: lowercase, hilangkan tanda baca, dan buang stopwords (kata seperti "yang", "dan", "di" yang tidak bermakna).

Pembersihan teks sederhana
import re
 
def clean_text(text):
    text = text.lower()
    text = re.sub(r"[^a-z0-9\s]", "", text)
    return text.split()
 
tokens = clean_text("PENAWARAN MENARIK! Dapatkan diskon 50% hari ini!")
print(tokens)  # ['penawaran', 'menarik', 'dapatkan', 'diskon', '50', 'hari', 'ini']

Dengan scikit-learn, seluruh proses ini diotomatisasi TfidfVectorizer — ia melakukan tokenization, stopword removal, dan konversi ke angka sekaligus.

Bag-of-Words

Bag-of-Words (BoW) adalah representasi paling sederhana: setiap dokumen menjadi vektor berisi jumlah kemunculan tiap kata di kamus.

Dokumen"promo""makan""murah""enak"
"promo makan murah"1110
"makan enak enak"0102

Masalahnya: kata yang sering muncul di semua dokumen (misal "makan") tidak informatif, tapi bobotnya besar.

TF-IDF: Bobot Kata yang Lebih Cerdas

TF-IDF (Term Frequency - Inverse Document Frequency) memperbaiki kelemahan BoW: kata yang muncul di banyak dokumen mendapat bobot lebih kecil (kurang informatif), kata yang langka mendapat bobot lebih besar.

TF-IDF
from sklearn.feature_extraction.text import TfidfVectorizer
 
vectorizer = TfidfVectorizer(
    max_features=5000,
    stop_words="english",
    ngram_range=(1, 2),
)
 
X_train = vectorizer.fit_transform(corpus_train)
X_test = vectorizer.transform(corpus_test)
print(X_train.shape)  # (n_doc, 5000) matriks sparse
  • max_features=5000: batasi kamus agar tidak meledak.
  • ngram_range=(1, 2): selain kata tunggal, sertakan frasa 2 kata ("not good") yang maknanya berbeda dari kata terpisah.

Perhatikan pola fit_transform di train dan transform di test — vectorizer belajar kamus dari train saja, persis seperti scaler di episode 4.

Note

Output TfidfVectorizer adalah matriks sparse — hampir semua entrinya nol. Jangan konversi ke dense array untuk dataset besar; model seperti LogisticRegression dan tree-based menerima sparse secara langsung.

Pipeline Klasifikasi Teks

Gabungkan vectorizer + classifier dalam satu Pipeline (kebiasaan kita sejak episode 4):

Pipeline klasifikasi teks
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
 
text_pipeline = Pipeline([
    ("tfidf", TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),
    ("clf", LogisticRegression(max_iter=1000)),
])
 
text_pipeline.fit(X_train_text, y_train_text)
print(text_pipeline.score(X_test_text, y_test_text))

LogisticRegression + TF-IDF adalah baseline yang sangat kuat untuk klasifikasi teks — sering mengalahkan model rumit pada data teks pendek. Mulailah dari sini sebelum mempertimbangkan pendekatan lain.

Studi Kasus: Sentiment Analysis

Mari klasifikasikan ulasan menjadi positif/negatif:

Sentiment analysis
from sklearn.metrics import classification_report
 
pipeline = Pipeline([
    ("tfidf", TfidfVectorizer(max_features=10000, ngram_range=(1, 2))),
    ("clf", LogisticRegression(max_iter=1000, class_weight="balanced")),
])
 
pipeline.fit(ulasan_train, label_train)
print(classification_report(ulasan_test, label_test))

class_weight="balanced" membantu jika ulasan negatif jauh lebih sedikit dari positif — ingat pelajaran episode 6.

Kita juga bisa menginspeksi kata apa yang paling memengaruhi keputusan model:

Kata paling berpengaruh
import numpy as np
 
coef = pipeline.named_steps["clf"].coef_[0]
names = pipeline.named_steps["tfidf"].get_feature_names_out()
 
top_pos = names[np.argsort(coef)[-10:]]
top_neg = names[np.argsort(coef)[:10]]
 
print("Kata paling positif:", top_pos)
print("Kata paling negatif:", top_neg)

Ini bentuk awal interpretabilitas — kita akan membahas versi lanjutannya dengan SHAP di episode 20.

Embeddings: Representasi yang Mengerti Makna

Kelemahan TF-IDF: tidak menangkap kemiripan makna. Kata "bagus" dan "hebat" dianggap berbeda total karena tidak berbagi karakter. Word embeddings mengatasinya: setiap kata direpresentasikan sebagai vektor numerik (misal 100 dimensi) di mana kata bermakna serupa punya vektor berdekatan.

100%

Dua pendekatan embedding klasik:

  • word2vec: belajar dari konteks kata di korpus besar (Google, 2013).
  • fastText: memperlakukan kata sebagai kumpulan karakter subkata — lebih baik untuk kata baru/typo dan bahasa berimbuhan seperti Indonesia.

Untuk pipeline sklearn, embed dokumen dengan menggabungkan vektor kata (rata-rata) sehingga setiap dokumen punya satu vektor:

Dokumen vector dari fastText
import fasttext
import numpy as np
 
ft = fasttext.load_model("lid.176.bin")  # model multilingual ringan
 
def embed_doc(text):
    words = clean_text(text)
    vectors = [ft.get_word_vector(w) for w in words if w in ft]
    return np.mean(vectors, axis=0) if vectors else np.zeros(ft.get_dimension())
 
X_embed = np.array([embed_doc(doc) for doc in texts])

Setelah dokumen menjadi vektor, kalian bebas memakai classifier mana pun — LogisticRegression, tree-based, atau kNN. Untuk pilihan 2026, embeddings transformer modern (dari model seperti Sentence-BERT) menjadi standar — kita sentuh di episode 23 bersama LLM.

Common Pitfalls

  • Stopword removal berlebihan — di beberapa domain, kata "not" justru krusial; jangan hapus negasi.
  • Tokenisasi data test dengan kamus sendiri — selalu fit_transform di train, transform di test.
  • Dataset teks kecil dengan max_features besar — sparse dan rawan overfit; kurangi kamus.
  • Mengabaikan class_weight pada sentimen yang tidak seimbang.
  • Lupa baseline sederhana — TF-IDF + LogisticRegression sering cukup untuk teks pendek.

Penutup

Pada episode 13 ini, kalian telah menguasai dasar-dasar NLP.

Inti yang harus dibawa pulang:

  • TF-IDF mengubah teks menjadi angka dengan bobot kata yang cerdas.
  • Pipeline TF-IDF + LogisticRegression adalah baseline kuat untuk klasifikasi teks.
  • Word embeddings (word2vec/fastText) menangkap kemiripan makna, sesuatu yang tidak bisa dilakukan TF-IDF.
  • Selalu fit vectorizer di train set saja.

Di episode 14 selanjutnya kita akan membahas imbalanced data & anomaly detection — resampling dan cost-sensitive learning, metrik yang tepat (PR-AUC, F2), lalu Isolation Forest dan One-Class SVM untuk deteksi fraud dan anomaly. Sampai jumpa di episode 14!

Belajar Machine Learning - NLP & Text Data (Dasar) | Belajar Machine Learning