Token adalah satuan data paling dasar dalam pengolahan teks, dan topik ini membahas cara komputer memotong teks menjadi satuan tersebut. Pemotongan yang tampak sederhana sesungguhnya berisi banyak keputusan, karena tanda baca, kontraksi, singkatan, dan angka tidak selalu terpisah oleh spasi. Tiga cara tokenisasi, yaitu str.split(), word_tokenize dari NLTK, dan tokenizer spaCy, dijalankan pada satu kalimat yang sama sehingga perbedaannya terbaca langsung dari keluaran asli. Setelah membaca topik ini, pemilihan tokenizer dapat dilandasi perilaku yang terukur, bukan kebiasaan.
Token sebagai satuan teks terkecil#
Tokenizer adalah program yang membaca teks mentah dan mengeluarkan deretan token, yaitu potongan teks terkecil yang digunakan oleh tahap-tahap berikutnya. Satu token dapat berupa kata, tanda baca, angka, atau bagian kata seperti n't pada didn't. Teks dipandang berstruktur berlapis, yakni korpus berisi dokumen, dokumen berisi kalimat, dan kalimat berisi token, sehingga token menjadi baris data yang dihitung, disaring, dan diubah menjadi fitur.
Token tidak sama dengan kata. Kalimat yang sama dapat menghasilkan lebih banyak token daripada kata, karena koma, titik, dan tanda tanya dihitung sebagai token tersendiri oleh tokenizer bahasa. Perbedaan ini bukan detail kosmetik, karena model klasik seperti bag of words membaca teks sebagai hitungan token, sehingga keputusan pemotongan menentukan nilai setiap fitur.
Diagram berikut menempatkan tokenisasi sebagai tahap pertama dalam alur mengubah teks menjadi data, sebelum normalisasi dan pembentukan fitur.
Alur pada diagram menjadi kerangka seluruh modul ini, sehingga keputusan tokenisasi yang diambil di sini berdampak pada setiap tahap di belakangnya. Kesalahan pemotongan tidak dapat diperbaiki oleh tahap berikutnya, karena tahap-tahap tersebut hanya melihat token yang diberikan.
Mengapa pemotongan teks tidak sepele#
Batas antarkata tidak selalu ditandai spasi, sehingga pemotongan berbasis spasi gagal pada kasus yang muncul di hampir setiap teks nyata. Kontraksi seperti didn't menggabungkan kata kerja dan kata ganti dalam satu rangkaian huruf. Singkatan gelar seperti Dr. menggunakan titik yang sama dengan tanda akhir kalimat. Angka desimal seperti 3.14 menggunakan titik sebagai pemisah bagian, sedangkan rangkaian seperti 3.14-mile menyambungkan angka dan kata melalui hyphen.
Keempat kasus itu menuntut keputusan yang berbeda. Kontraksi lebih informatif bila dipecah menjadi did dan n't, sedangkan titik pada Dr. justru bagian dari singkatannya, bukan akhir kalimat. Titik pada 3.14 harus tetap menempel agar angka terbaca utuh, sedangkan hyphen pada 3.14-mile dapat diperlakukan sebagai pemisah atau sebagai penghubung, tergantung kebutuhan. Pemotongan yang keliru menggeser hitungan token, dan hitungan yang bergeser membuat bobot fitur menyimpang dari isi teks.
Kalimat uji yang digunakan sepanjang topik ini memuat keempat kasus tersebut sekaligus, sehingga setiap tokenizer dibandingkan pada teks yang menantang bagi ketiganya. Kalimat ujinya adalah Dr. Ada didn't finish the 3.14-mile route on time, did she?
Kalimat uji dan tiga cara memotongnya#
Cara paling sederhana memotong teks adalah membaginya pada karakter spasi. Dua pustaka di sandbox menawarkan tokenizer yang lebih sadar bahasa, yaitu word_tokenize pada NLTK dan tokenizer bawaan model spaCy. Ketiganya dijalankan terhadap kalimat uji yang sama, dan keluarannya dibandingkan satu per satu agar perbedaan aturannya terlihat jelas.
Pemotongan dengan str.split()#
Metode split() pada Python memotong string pada setiap rangkaian spasi (whitespace) dan mengembalikan daftar string. Hasilnya diperoleh cepat, tetapi pemotongannya tidak sadar bahasa sama sekali. Jalankan potongan berikut untuk melihat keluaran aslinya.
kalimat = "Dr. Ada didn't finish the 3.14-mile route on time, did she?"
token_spasi = kalimat.split()
print(token_spasi)
print("jumlah token:", len(token_spasi))['Dr.', 'Ada', "didn't", 'finish', 'the', '3.14-mile', 'route', 'on', 'time,', 'did', 'she?']
jumlah token: 11Tiga keputusan pemotongan gagal di sini. Koma pada time, dan tanda tanya pada she? masih menempel pada katanya, sehingga keduanya dihitung sebagai bagian dari kata. Kontraksi didn't dan rangkaian 3.14-mile tidak pernah dipecah. Jumlah token yang tercatat adalah 11, padahal kalimat membawa lebih banyak informasi daripada yang dapat terbaca oleh model dari token-token itu.
Pemotongan dengan NLTK#
Fungsi word_tokenize dari modul nltk.tokenize menerapkan aturan tokenisasi yang mengenali tanda baca dan kontraksi. Fungsi ini digunakan luas pada eksperimen NLP klasik karena cepat dan deterministik.
from nltk.tokenize import word_tokenize
kalimat = "Dr. Ada didn't finish the 3.14-mile route on time, did she?"
token_nltk = word_tokenize(kalimat)
print(token_nltk)
print("jumlah token:", len(token_nltk))['Dr.', 'Ada', 'did', "n't", 'finish', 'the', '3.14-mile', 'route', 'on', 'time', ',', 'did', 'she', '?']
jumlah token: 14Tanda koma dan tanda tanya kini menjadi token tersendiri, sehingga jumlah token naik menjadi 14. Kontraksi didn't dipecah menjadi did dan n't sesuai aturan khusus NLTK. Rangkaian 3.14-mile tetap satu token karena tokenizer NLTK menganggap hyphen yang menyambungkan angka dan huruf bukan pemisah.
Pemotongan dengan spaCy#
spaCy memuat tokenizer sebagai bagian dari pipeline model. Panggilan spacy.load("en_core_web_sm") mengembalikan objek nlp, dan kalimat yang dilewatkan ke objek tersebut menghasilkan objek Doc yang berisi token-token. Jalankan potongan berikut dan bandingkan keluarannya dengan NLTK.
import spacy
nlp = spacy.load("en_core_web_sm")
kalimat = "Dr. Ada didn't finish the 3.14-mile route on time, did she?"
doc = nlp(kalimat)
token_spacy = [token.text for token in doc]
print(token_spacy)
print("jumlah token:", len(token_spacy))['Dr.', 'Ada', 'did', "n't", 'finish', 'the', '3.14', '-', 'mile', 'route', 'on', 'time', ',', 'did', 'she', '?']
jumlah token: 16Keluaran spaCy paling rinci dengan 16 token, karena hyphen dianggap token terpisah sehingga 3.14-mile terpecah menjadi 3.14, -, dan mile. Tanda baca dan kontraksi diperlakukan sama seperti NLTK. Perbedaan pada hyphen menunjukkan bahwa dua tokenizer yang sama-sama sadar bahasa tetap berbeda pada aturan tepinya.
Tabel berikut merangkum perbedaannya pada potongan kalimat yang menentukan.
| Bagian kalimat | str.split() | NLTK | spaCy |
|---|---|---|---|
didn't | satu token utuh | did + n't | did + n't |
3.14-mile | satu token utuh | satu token utuh | 3.14 + - + mile |
time, | satu token dengan koma | time + , | time + , |
| Jumlah token | 11 | 14 | 16 |
Tidak ada satu pun keluaran di atas yang keliru secara mutlak. Ketiganya menerapkan definisi token yang berbeda, dan pilihan yang tepat bergantung pada tahap berikutnya. Pemrosesan berbasis hitungan biasanya memilih tokenizer pustaka, sedangkan pemisahan spasi cukup untuk kebutuhan penghitungan kasar yang tidak memerlukan tanda baca terpisah.
Informasi bawaan dari token spaCy#
Token pada spaCy bukan string biasa, melainkan objek yang membawa atribut turunan. Atribut seperti is_alpha, is_punct, dan like_num menjawab pertanyaan yang sering muncul pada pemfilteran token, misalnya membuang tanda baca atau mengambil angka. Atribut ini dihitung sekali saat tokenisasi dan tersedia tanpa pemrosesan tambahan.
import spacy
nlp = spacy.load("en_core_web_sm")
kalimat = "Dr. Ada didn't finish the 3.14-mile route on time, did she?"
doc = nlp(kalimat)
for token in doc:
if token.text in ("Dr.", "Ada", "3.14", "-"):
print(token.text, "| is_alpha:", token.is_alpha, "| is_punct:", token.is_punct, "| like_num:", token.like_num)Dr. | is_alpha: False | is_punct: False | like_num: False
Ada | is_alpha: True | is_punct: False | like_num: False
3.14 | is_alpha: False | is_punct: False | like_num: True
- | is_alpha: False | is_punct: True | like_num: FalseBaris pertama menunjukkan bahwa Dr. tidak murni berupa huruf karena titiknya, tetapi juga bukan tanda baca, sehingga singkatan gelar memang terklasifikasi tersendiri. Token Ada seluruhnya berupa huruf, token 3.14 dikenali sebagai angka melalui like_num, dan token - tercatat sebagai tanda baca. Pemfilteran seperti if not token.is_punct menjadi mungkin tanpa membaca ulang teks aslinya.
Kesalahan umum#
- Menghitung kata dengan
split()untuk analisis berbasis fitur. Pemisahan spasi menyisakan tanda baca pada token, sehingga hitungan fitur menyimpang. Gunakan tokenizer pustaka ketika hasil pemotongan menjadi fitur. - Menganggap
print(doc)menampilkan token. ObjekDocpada spaCy mencetak ulang seluruh teks aslinya. Iterasi token secara eksplisit, misalnyafor token in doc, lalu bacatoken.text. - Mengganti tokenizer di tengah pipeline tanpa mencatatnya. Jumlah dan isi token berubah antartokenizer, sehingga fitur yang dihitung tidak dapat direproduksi. Catat tokenizer dan versi pustakanya bersama kode pemrosesan.
Ringkasan#
- Token adalah potongan teks terkecil yang dihasilkan tokenizer, dan seluruh tahap pengolahan teks bekerja di atas deretan token tersebut.
- Pemisahan spasi bukan batas kata, karena kontraksi, singkatan bertitik, angka desimal, dan hyphen menuntut keputusan pemotongan yang berbeda.
- Pada kalimat uji yang sama,
str.split()menghasilkan 11 token, NLTK menghasilkan 14, dan spaCy menghasilkan 16, dengan perbedaan pada tanda baca, kontraksi, dan hyphen. - Token spaCy membawa atribut
is_alpha,is_punct, danlike_numyang siap digunakan untuk pemfilteran.
Referensi#
- Speech and Language Processing, draf edisi ke-3 — Jurafsky & Martin, Stanford — Bab tentang tokenisasi menguraikan kasus-kasus pemotongan teks yang sulit dan keputusannya.
- Natural Language Processing with Python — Bird, Klein & Loper, O’Reilly/NLTK
— Bab 3 memperkenalkan
word_tokenizedan cara token mewakili teks. - spaCy Usage Documentation — Explosion
— Dokumentasi resmi tokenizer dan atribut Token seperti
is_punctdanlike_num.