HMM / CRF: BiLSTM-CRF (Lample et al. 2016) — 신경망 시대 시작.
사전학습 Transformer: BERT/RoBERTa + token classification head — 표준.
LLM zero/few-shot: GPT-4, Claude 프롬프팅으로 스키마 정의.
GLiNER (2024): 임의의 엔티티 타입을 zero-shot 추출하는 generalist NER.
Nested NER / Flat NER
Flat: 한 토큰은 하나의 엔티티 — CRF 자연스러움.
Nested: "Bank of America" 안에 "America"(GPE)까지 — span-based 모델 필요.
도메인 변종
BioNER (BC5CDR, NCBI Disease).
LegalNER (사건명, 법조항).
FinancialNER (티커, 금액).
한국어 NER: KLUE-NER, KoBERT.
평가
Span-level F1 (token-level이 아닌 정확한 boundary+type 일치).
seqeval 라이브러리 표준.
응용
검색 엔진 enrichment.
지식 그래프 구축.
챗봇 슬롯 채우기.
의료 기록에서 약물·질환 추출.
컴플라이언스 (PII 탐지).
💻 패턴
# 1. spaCy — 즉시 사용 가능한 production NERimportspacynlp=spacy.load("en_core_web_trf")doc=nlp("Apple is opening a new office in Seoul next March.")forentindoc.ents:print(ent.text,ent.label_,ent.start_char,ent.end_char)# Apple ORG / Seoul GPE / next March DATE
# 2. HuggingFace transformers — BERT NER pipelinefromtransformersimportpipelinener=pipeline("ner",model="dslim/bert-large-NER",aggregation_strategy="simple")print(ner("Tim Cook visited Berlin yesterday."))
# 3. Fine-tune BERT for NER (CoNLL-2003)fromtransformersimportAutoTokenizer,AutoModelForTokenClassification,Trainermodel=AutoModelForTokenClassification.from_pretrained("bert-base-cased",num_labels=9)# tokens, labels을 BIO 스킴으로 정렬한 뒤 Trainer로 학습
# 4. GLiNER — zero-shot 임의 타입fromglinerimportGLiNERmodel=GLiNER.from_pretrained("urchade/gliner_medium-v2.1")text="Elon Musk founded SpaceX in 2002."labels=["person","company","year"]print(model.predict_entities(text,labels))
# 5. LLM JSON 추출 — Claude/GPTimportjsonprompt="""Extract entities. Return JSON list of {"text","type","start","end"}.
Types: PERSON, ORG, LOC, DATE, MONEY.
Text: Microsoft acquired Activision for $69 billion in October 2023."""# response → json.loads
# 7. 한국어 NER — KLUE-RoBERTafromtransformersimportpipelinekor_ner=pipeline("ner",model="klue/roberta-base-finetuned-ner",aggregation_strategy="simple")print(kor_ner("김철수는 서울대학교에서 공부한다."))
# 8. BioNER — BERN2 (의료)importrequeststext="Aspirin reduces the risk of stroke."r=requests.post("http://bern2.korea.ac.kr/plain",json={"text":text})print(r.json())# CHEMICAL: Aspirin, DISEASE: stroke
# 9. spaCy 사용자 정의 EntityRuler (규칙)ruler=nlp.add_pipe("entity_ruler",before="ner")patterns=[{"label":"PRODUCT","pattern":"iPhone 17 Pro"},{"label":"ORG","pattern":[{"LOWER":"openai"}]},]ruler.add_patterns(patterns)
# 10. Nested NER — span-based (Flair/SpanMarker)fromspan_markerimportSpanMarkerModelmodel=SpanMarkerModel.from_pretrained("tomaarsen/span-marker-mbert-base-multinerd")print(model.predict("Bank of America is headquartered in Charlotte."))# Bank of America (ORG) 와 America (LOC) 둘 다 추출
결정 기준
상황
추천
빠른 프로토타입
spaCy en_core_web_trf
최고 정확도 (영어)
BERT/RoBERTa fine-tune on OntoNotes
임의 타입 / few labeled
GLiNER, LLM zero-shot
한국어
KLUE-RoBERTa, KoBERT-NER
의료/생명과학
BioBERT, BERN2, SciSpaCy
규칙 강제 (회사 product 목록)
spaCy EntityRuler 우선 적용
Nested entities
SpanMarker, biaffine
Production 비용 민감
spaCy / 작은 BERT (distil)
기본값: spaCy + EntityRuler 보강, 도메인 적응 시 BERT fine-tune, 빠른 PoC는 GLiNER/LLM.