Tutorial spaCy: NLP Berskala Industri dengan Python

# spaCy: NLP Kelas Industri di Python spaCy adalah pustaka open-source untuk pemrosesan bahasa alami (NLP) yang dirancang untuk penggunaan produksi. Jika large language model unggul dalam menghasilka...

By Ruby Abdullah · · tutorial
spaCyNLPNamed Entity RecognitionText ProcessingPythonMachine Learning

spaCy: NLP Kelas Industri di Python

spaCy adalah pustaka open-source untuk pemrosesan bahasa alami (NLP) yang dirancang untuk penggunaan produksi. Jika large language model unggul dalam menghasilkan teks bebas, spaCy berfokus pada analisis teks yang cepat, deterministik, dan terstruktur: tokenisasi, penandaan kelas kata, dependency parsing, dan pengenalan entitas bernama. Tutorial ini membahas spaCy mulai dari instalasi hingga melatih model kustom, dengan satu contoh teks bisnis yang konsisten sepanjang pembahasan.

Apa Itu spaCy dan Posisinya

spaCy adalah pustaka Python yang mengubah teks mentah menjadi data linguistik terstruktur. Pustaka ini menyertakan model statistik terlatih untuk banyak bahasa dan menyediakan model objek yang rapi (Doc, Token, Span) untuk mengolah hasilnya. Pustaka ini ditulis dengan mempertimbangkan kinerja, sehingga mampu memproses teks dalam jumlah besar secara cepat di CPU.

spaCy vs. Large Language Model

LLM dan spaCy menyelesaikan masalah yang berbeda, dan dalam praktiknya keduanya sering digabungkan.

  • Deterministik: spaCy menghasilkan keluaran yang sama untuk masukan yang sama setiap kali. Hal ini penting untuk pipeline yang memberi makan sistem hilir atau yang harus dapat diaudit.
  • Kecepatan dan biaya: spaCy berjalan di CPU biasa dan memproses ribuan dokumen per detik untuk banyak tugas. Tidak ada biaya API per token.
  • Struktur: spaCy mengembalikan anotasi bertipe pada level span (entitas, token, dependensi), bukan teks bebas yang harus diurai kembali.
  • Privasi: teks tidak perlu keluar dari infrastruktur Anda.

Pola yang umum adalah menggunakan spaCy untuk ekstraksi dan perutean bervolume tinggi, lalu menyisakan LLM untuk sebagian kecil kasus yang benar-benar memerlukan penalaran terbuka. spaCy juga dapat mengintegrasikan prompt LLM sebagai komponen pipeline melalui paket spacy-llm bila Anda ingin keduanya dalam satu alur kerja.

Instalasi dan Mengunduh Model

Pasang spaCy dengan pip. Disarankan menggunakan virtual environment agar versi model tetap terkunci pada proyek Anda.

python -m venv .venv

source .venv/bin/activate # di Windows: .venv\Scripts\activate

pip install spacy

Model didistribusikan terpisah dari pustaka. Unduh model bahasa Inggris berukuran kecil untuk memulai:

python -m spacy download encorewebsm

Model bahasa Inggris mengikuti konvensi penamaan: en (bahasa), core (pipeline serbaguna), web (dilatih pada teks web), dan sufiks ukuran:

  • encorewebsm — kecil, cepat, tanpa word vector.
  • encorewebmd — sedang, menyertakan word vector.
  • encoreweblg — besar, lebih banyak vector.
  • encorewebtrf — berbasis transformer, akurasi tertinggi, butuh komputasi lebih besar.

Anda dapat memeriksa apa yang terpasang dan memvalidasi kompatibilitasnya:

python -m spacy info

python -m spacy validate

Pipeline nlp dan Objek Inti

Memuat model memberi Anda objek nlp. Memanggilnya pada sebuah string akan menjalankan seluruh pipeline dan mengembalikan sebuah Doc.

import spacy

nlp = spacy.load("encorewebsm")

text = "Acme Corp acquired Globex Ltd for $4.5 billion in March 2023."

doc = nlp(text)

print(type(doc)) #

print(len(doc)) # jumlah token

print([token.text for token in doc])

Sebuah Doc adalah urutan objek Token. Potongan token yang berurutan adalah sebuah Span. Tiga objek inilah yang menjadi fondasi untuk segala hal lainnya.

# Token: satu kata, tanda baca, atau simbol

first = doc[0]

print(first.text, first.idx) # "Acme" 0

Span: potongan dari Doc

span = doc[0:2]

print(span.text) # "Acme Corp"

Kalimat juga merupakan Span

for sent in doc.sents:

print(sent.text)

Memeriksa Pipeline

Objek nlp memuat daftar komponen yang terurut. Anda dapat memeriksanya dan memodifikasinya.

print(nlp.pipenames)

['tok2vec', 'tagger', 'parser', 'attributeruler', 'lemmatizer', 'ner']

Setiap komponen menambahkan anotasi pada Doc saat dokumen melewatinya.

Tokenisasi, POS Tagging, dan Lematisasi

Tokenisasi memecah teks menjadi token menggunakan aturan spesifik bahasa. spaCy menangani kontraksi, tanda baca, dan kasus khusus tanpa kehilangan offset karakter asli.

doc = nlp("Acme didn't expand into Europe until 2024.")

for token in doc:

print(f"{token.text:>10} | {token.lemma:>8} | {token.pos:>6} | {token.tag}")

Atribut token yang berguna:

  • token.text — teks aslinya.
  • token.lemma — bentuk dasar (misalnya "acquired" menjadi "acquire").
  • token.pos — kelas kata kasar (NOUN, VERB, PROPN).
  • token.tag — tag halus (VBD, NNP).
  • token.isstop — apakah ia kata henti (stop word).
  • token.isalpha, token.likenum, token.ispunct — flag boolean yang berguna.

contentwords = [t.lemma for t in doc if not t.isstop and not t.ispunct]

print(contentwords)

Dependency Parsing

Dependency parser menetapkan relasi sintaksis antar token, membentuk sebuah pohon. Inilah cara Anda menemukan nomina mana yang menjadi subjek sebuah verba, atau token mana yang menjadi tempat menempelnya sebuah pewatas.

doc = nlp("Acme Corp acquired Globex Ltd for $4.5 billion.")

for token in doc:

print(f"{token.text:>10} --{token.dep}--> {token.head.text}")

Setiap token memiliki head (induk sintaksisnya) dan label dep yang menjelaskan relasinya (nsubj, dobj, prep). Anda juga dapat menelusuri anak (children):

verb = [t for t in doc if t.lemma == "acquire"][0]

subjects = [child for child in verb.children if child.dep == "nsubj"]

objects = [child for child in verb.children if child.dep == "dobj"]

print("subjek:", subjects)

print("objek:", objects)

Ini memberi fondasi sederhana untuk ekstraksi relasi, yang akan kita bahas lagi nanti.

Pengenalan Entitas Bernama (NER)

NER mengidentifikasi objek dunia nyata seperti organisasi, orang, uang, dan tanggal. Entitas yang dikenali muncul di doc.ents sebagai objek Span dengan atribut label.

doc = nlp("Acme Corp acquired Globex Ltd for $4.5 billion in March 2023.")

for ent in doc.ents:

print(f"{ent.text:>15} | {ent.label:>10} | {ent.startchar}-{ent.endchar}")

Label keluaran yang umum mencakup ORG, MONEY, dan DATE. Untuk memahami sebuah label, tanyakan pada spaCy:

print(spacy.explain("ORG"))     # "Companies, agencies, institutions, etc."

Visualisasi dengan displaCy

spaCy menyertakan visualizer bawaan. Dalam sebuah skrip, ia menyajikan halaman web kecil; dalam notebook, ia menampilkan secara inline.

from spacy import displacy

doc = nlp("Acme Corp acquired Globex Ltd for $4.5 billion in March 2023.")

Penyorotan entitas

displacy.serve(doc, style="ent")

Pohon dependensi

displacy.serve(doc, style="dep")

Dalam notebook Jupyter, gunakan displacy.render(doc, style="ent") alih-alih serve. Anda juga dapat mengekspor SVG hasil render ke berkas untuk laporan.

Pencocokan Berbasis Aturan: Matcher dan PhraseMatcher

Model statistik memang andal, tetapi sebagian pola lebih baik diungkapkan sebagai aturan: kode produk, satuan, atau frasa tetap. spaCy menyediakan dua matcher untuk ini.

Matcher

Token Matcher mencocokkan urutan yang dijelaskan oleh atribut token. Setiap pola adalah daftar kamus, satu kamus per token.

from spacy.matcher import Matcher

matcher = Matcher(nlp.vocab)

Cocokkan " acquired "

pattern = [

{"POS": "PROPN", "OP": "+"},

{"LEMMA": "acquire"},

{"POS": "PROPN", "OP": "+"},

]

matcher.add("ACQUISITION", [pattern])

doc = nlp("Acme Corp acquired Globex Ltd last year.")

for matchid, start, end in matcher(doc):

span = doc[start:end]

print(nlp.vocab.strings[matchid], "->", span.text)

Kunci OP mengontrol kuantifier: ! (negasi), ? (opsional), + (satu atau lebih), * (nol atau lebih).

PhraseMatcher

Bila Anda sudah memiliki daftar istilah persis, seperti katalog produk atau daftar pantau nama perusahaan, PhraseMatcher lebih cepat dan lebih sederhana.

from spacy.matcher import PhraseMatcher

phrasematcher = PhraseMatcher(nlp.vocab, attr="LOWER")

terms = ["Acme Corp", "Globex Ltd", "Initech"]

patterns = [nlp.makedoc(t) for t in terms]

phrasematcher.add("COMPANIES", patterns)

doc = nlp("Both acme corp and Initech reported strong quarters.")

for matchid, start, end in phrasematcher(doc):

print(doc[start:end].text)

Entitas Kustom dengan EntityRuler

EntityRuler memungkinkan Anda menambahkan entitas melalui aturan dan menggabungkannya dengan NER statistik. Ini adalah alat yang tepat ketika Anda memiliki istilah domain yang tidak dikenal model.
ruler = nlp.addpipe("entityruler", before="ner")

patterns = [

{"label": "PRODUCT", "pattern": "Widget Pro"},

{"label": "PRODUCT", "pattern": [{"LOWER": "widget"}, {"LOWER": "lite"}]},

{"label": "ORG", "pattern": "Initech"},

]

ruler.addpatterns(patterns)

doc = nlp("Initech launched Widget Pro and widget lite this quarter.")

for ent in doc.ents:

print(ent.text, ent.label)

Menempatkan ruler before="ner" membuat aturan Anda diprioritaskan; menempatkannya setelah membuat model statistik yang menang saat terjadi konflik. Pilih berdasarkan seberapa besar Anda memercayai masing-masing sumber.

Word Vector dan Kemiripan

Model sedang dan besar menyertakan word vector, yang memungkinkan Anda mengukur kemiripan semantik. Model kecil tidak menyertakannya, jadi pasang encorewebmd untuk bagian ini.

python -m spacy download encorewebmd

nlpmd = spacy.load("encorewebmd")

doc = nlpmd("revenue profit lettuce")

tokens = [t for t in doc]

for t in tokens:

print(t.text, t.hasvector, round(t.vectornorm, 2))

print(tokens[0].similarity(tokens[1])) # revenue vs profit (lebih tinggi)

print(tokens[0].similarity(tokens[2])) # revenue vs lettuce (lebih rendah)

Objek Doc dan Span juga menyediakan .similarity, yang dihitung dari rata-rata vector tokennya. Vector ini bersifat statis (bebas konteks), jadi untuk kemiripan yang peka konteks Anda akan menggunakan model transformer atau model embedding khusus.

Pemrosesan Efisien dengan nlp.pipe

Memanggil nlp(text) di dalam loop cukup baik untuk segelintir dokumen, tetapi untuk satu korpus hal itu lambat. nlp.pipe memproses teks sebagai aliran, mengelompokkannya menjadi batch, dan dapat menggunakan banyak proses.

texts = [

"Acme Corp acquired Globex Ltd for $4.5 billion.",

"Initech hired 200 engineers in Berlin.",

"Umbrella Inc reported a loss in Q3 2024.",

]

for doc in nlp.pipe(texts, batchsize=50):

orgs = [ent.text for ent in doc.ents if ent.label == "ORG"]

print(orgs)

Dua opsi penting:

  • batchsize — berapa banyak teks yang disangga per batch. Sesuaikan dengan ukuran dokumen Anda.
  • nprocess — jumlah proses pekerja. Gunakan -1 untuk semua core, tetapi ukur dahulu; overhead-nya bisa melebihi manfaatnya untuk teks pendek.

Jika Anda hanya membutuhkan sebagian pipeline, nonaktifkan komponen yang tidak Anda pakai untuk menghemat waktu:

with nlp.selectpipes(enable=["tok2vec", "ner"]):

for doc in nlp.pipe(texts):

print(doc.ents)

Anda juga dapat melampirkan metadata Anda sendiri pada setiap teks dan menerimanya kembali bersama Doc:

data = [("doc-1", "Acme Corp grew."), ("doc-2", "Initech shrank.")]

for doc, ctx in nlp.pipe(data, astuples=True):

print(ctx, "->", [t.text for t in doc])

Komponen Pipeline Kustom

Anda dapat menyisipkan logika Anda sendiri ke dalam pipeline dengan dekorator @Language.component. Sebuah komponen menerima Doc, memodifikasinya, lalu mengembalikannya. Contoh di bawah mengekstrak relasi pengakuisisi/target sederhana menggunakan hasil dependency parse dan menyimpannya sebagai atribut kustom.

from spacy.language import Language

from spacy.tokens import Doc

Daftarkan atribut ekstensi kustom pada Doc

if not Doc.hasextension("acquisitions"):

Doc.setextension("acquisitions", default=[])

@Language.component("acquisitionextractor")

def acquisitionextractor(doc):

results = []

for token in doc:

if token.lemma == "acquire" and token.pos == "VERB":

subj = [c for c in token.children if c.dep == "nsubj"]

obj = [c for c in token.children if c.dep == "dobj"]

if subj and obj:

results.append({

"acquirer": subj[0].text,

"target": obj[0].text,

})

doc..acquisitions = results

return doc

nlp.addpipe("acquisitionextractor", last=True)

doc = nlp("Acme acquired Globex. Initech acquired Hooli.")

print(doc..acquisitions)

Atribut ekstensi kustom diakses melalui namespace ., yang menjaganya tetap terpisah dari atribut bawaan spaCy. Komponen dapat diurutkan dengan first, last, before, atau after.

Melatih Model NER Kustom

Ketika entitas bawaan tidak mencukupi, Anda dapat melatih model sendiri. spaCy modern menggunakan alur kerja berbasis konfigurasi yang berpusat pada berkas config.cfg dan perintah spacy train, alih-alih loop pelatihan yang ditulis manual.

Langkah 1: Siapkan Data Pelatihan sebagai DocBin

Data pelatihan disimpan dalam format biner .spacy menggunakan DocBin. Setiap contoh adalah sebuah Doc dengan span entitas standar emas (gold).

import spacy

from spacy.tokens import DocBin

nlp = spacy.blank("en")

TRAINDATA = [

("Acme Corp launched Widget Pro.", {"entities": [(0, 9, "ORG"), (19, 29, "PRODUCT")]}),

("Initech ships Widget Lite today.", {"entities": [(0, 7, "ORG"), (14, 25, "PRODUCT")]}),

]

def makedocbin(data):

db = DocBin()

for text, ann in data:

doc = nlp.makedoc(text)

ents = []

for start, end, label in ann["entities"]:

span = doc.charspan(start, end, label=label, alignmentmode="contract")

if span is not None:

ents.append(span)

doc.ents = ents

db.add(doc)

return db

makedocbin(TRAINDATA).todisk("./train.spacy")

makedocbin(TRAINDATA).todisk("./dev.spacy") # dalam praktik gunakan set uji terpisah

Selalu periksa bahwa charspan mengembalikan sebuah span; offset yang tidak selaras secara diam-diam menghasilkan None dan akan membuang anotasi Anda.

Langkah 2: Buat Berkas Config

spaCy dapat menghasilkan config awal yang masuk akal untuk Anda, lalu mengisi nilai default.

python -m spacy init config config.cfg --lang en --pipeline ner

python -m spacy init fill-config config.cfg config.cfg

config.cfg yang dihasilkan mendeklarasikan pipeline, arsitektur model, dan hiperparameter pelatihan. Bagian utama yang perlu dikenali adalah [paths] (lokasi data Anda), [nlp] (definisi pipeline), dan [training] (optimizer, batching, evaluasi).

Langkah 3: Latih dan Evaluasi

Arahkan trainer ke data Anda dan ke direktori keluaran.

python -m spacy train config.cfg \

--output ./output \

--paths.train ./train.spacy \

--paths.dev ./dev.spacy

spaCy menulis model terbaik dan model terakhir ke ./output. Anda dapat mengevaluasi pada set uji terpisah lalu memuat pipeline terlatih seperti model lainnya.

python -m spacy evaluate ./output/model-best ./dev.spacy

trained = spacy.load("./output/model-best")

doc = trained("Globex Inc released Widget Pro.")

print([(e.text, e.label) for e in doc.ents])

Untuk proyek nyata, gunakan lebih banyak contoh (ratusan hingga ribuan per label), pertahankan set dev terpisah yang sesungguhnya, dan pertimbangkan spacy debug data untuk menangkap masalah anotasi sebelum pelatihan.

Model Berbasis Transformer

Untuk akurasi tertinggi, spaCy menyediakan pipeline transformer seperti encorewebtrf, yang menggunakan model seperti RoBERTa di belakang layar melalui paket spacy-transformers.

pip install spacy-transformers

python -m spacy download encorewebtrf

nlptrf = spacy.load("encorewebtrf")

doc = nlptrf("Acme Corp acquired Globex Ltd for $4.5 billion.")

print([(e.text, e.label) for e in doc.ents])

Pipeline transformer memberi representasi yang peka konteks dan biasanya akurasi lebih baik pada kasus sulit, dengan mengorbankan kecepatan dan memori. Pipeline ini sangat terbantu oleh GPU. Pendekatan praktisnya adalah membuat prototipe dengan model kecil, mengukur akurasi pada data Anda, lalu naik ke md/lg/trf hanya jika angka-angkanya membenarkan langkah itu.

Praktik Terbaik

  • Muat model sekali saja. spacy.load mahal; muat saat startup dan gunakan kembali objek nlp.
  • Gunakan nlp.pipe untuk batch. Inilah percepatan tunggal terbesar untuk pemrosesan korpus.
  • Nonaktifkan komponen yang tidak dipakai. Jika hanya butuh NER, jangan membayar parser.
  • Kunci versi model. Model terikat pada versi spaCy; catat dalam requirements agar hasil tetap dapat direproduksi.
  • Gabungkan aturan dan statistik. Gunakan EntityRuler dan matcher untuk pola yang sudah diketahui dan berpresisi tinggi, serta model statistik untuk kasus ekor panjang (long tail).
  • Validasi offset saat membangun data pelatihan. Selalu pastikan char_span bukan None.
  • Ukur sebelum meningkatkan skala. Mulai dengan sm, dan adopsi transformer hanya bila peningkatan akurasinya nyata dan membenarkan biayanya.
  • Pertahankan set evaluasi terpisah. Tanpa itu Anda tidak bisa tahu apakah perubahan benar-benar membantu.

Kesimpulan dan Poin Utama

spaCy adalah pilihan praktis ketika Anda membutuhkan pemrosesan teks yang cepat, terstruktur, dan dapat diulang di lingkungan produksi. spaCy melengkapi large language model alih-alih bersaing dengannya: spaCy menangani ekstraksi dan struktur bervolume tinggi, sementara LLM dapat mengambil sebagian kecil kasus yang membutuhkan penalaran terbuka.

Poin-poin utama:

  • Pipeline nlp mengubah teks menjadi Doc berisi objek Token dan Span yang membawa anotasi tokenisasi, POS, lemma, dependensi, dan entitas.
  • Alat berbasis aturan (Matcher, PhraseMatcher, EntityRuler) menambahkan perilaku berpresisi tinggi dan spesifik domain di samping model statistik.
  • Word vector pada model md/lg memungkinkan perbandingan kemiripan; transformer pada trf mendorong akurasi lebih jauh.
  • nlp.pipe dan pemilihan komponen adalah tuas utama untuk memproses korpus besar secara efisien.
  • Alur kerja pelatihan berbasis config (data DocBin, config.cfg, spacy train) memungkinkan Anda membangun model NER kustom secara dapat direproduksi.

Dengan blok-blok pembangun ini, Anda dapat menyusun pipeline NLP yang tangguh, cepat dijalankan, mudah diaudit, dan praktis untuk dikembangkan.

Artikel Terkait

Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management

Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management Dalam dunia machine learning mo...

Tutorial MLX: Framework Machine Learning Apple untuk Apple Silicon

Tutorial MLX: Framework Machine Learning Apple untuk Apple Silicon MLX adalah framework machine learning open-source dar...

Tutorial SHAP: Explainable AI dan Interpretasi Model

SHAP - Panduan Praktis Explainable AI dan Interpretabilitas Model Model machine learning makin sering dipakai untuk meng...

Tutorial PyOD: Deteksi Anomali dan Outlier dengan Python

Deteksi Anomali di Python dengan PyOD: Panduan Praktis Sebagian besar dataset di dunia nyata mengandung sebagian kecil d...