# Named Entity Recognition (NER)
## 정의
개체명 인식(Named Entity Recognition, NER)은 **텍스트에서 사람, 조직, 장소, 날짜 등 의미 있는 개체를 자동으로 식별하고 분류하는 NLP 작업**이다. 정보 추출, 질의응답, 검색 등의 기초 기술이다.
## 개체 유형 (Entity Types)
### 기본 개체 (Basic Entities)
```
입력: "스티브 잡스는 1955년 2월 24일 샌프란시스코에서 태어났다"
출력:
스티브 잡스 [PERSON]
1955년 2월 24일 [DATE]
샌프란시스코 [LOCATION]
```
### 주요 개체 타입
| 타입 | 설명 | 예시 |
|------|------|------|
| **PER** | 사람 | John, Mary, 강감찬 |
| **ORG** | 조직 | Apple, OpenAI, 삼성 |
| **LOC** | 장소 | Paris, 서울, Amazon |
| **DATE** | 날짜 | 2024-01-15, January 15 |
| **TIME** | 시간 | 14:30, 오후 2시 |
| **MONEY** | 금액 | $100, 10,000원 |
| **PERCENT** | 퍼센트 | 5%, 80% |
| **PRODUCT** | 제품 | iPhone, Windows 11 |
| **EVENT** | 사건 | 2024 올림픽, 월드컵 |
| **LANGUAGE** | 언어 | English, 한국어 |
### 전문 분야별 개체
```
의료: 질병(DISEASE), 약물(DRUG), 증상(SYMPTOM)
금융: 주가(STOCK), 환율(CURRENCY), 기업명(COMPANY)
법률: 법률(LAW), 법원(COURT), 판례(JUDGMENT)
과학: 화학물질(CHEMICAL), 생물(SPECIES), 발견(DISCOVERY)
```
## 아키텍처: 시퀀스 레이블링
### 문제 정의
```
입력 (시퀀스):
[John, works, at, Apple, in, California]
출력 (각 토큰의 레이블):
[PER, O, O, ORG, O, LOC]
여기서 O = "Other" (개체 아님)
```
### BIO 태깅 (Tagging Scheme)
```
B-PER: 개체의 시작
I-PER: 개체의 내부 (계속)
O: 개체 아님
예시: "John Smith works"
John B-PER
Smith I-PER (같은 사람)
works O
```
**예시 2: "New York"**
```
New B-LOC
York I-LOC
```
**더 복잡한 예:**
```
"Apple Inc. is in California"
Apple B-ORG
Inc. I-ORG
is O
in O
California B-LOC
```
## 모델 아키텍처
### 1. CRF (Conditional Random Fields)
```
방법: 동적 프로그래밍으로 최적 레이블 시퀀스 찾기
입력: [John, works, at, Apple]
↓
BiLSTM (양방향 LSTM):
각 토큰의 벡터 표현 + 문맥 정보
↓
CRF Layer:
이전 레이블과 현재 레이블의 호환성 학습
예: [PER] → [O] (확률 높음)
[PER] → [PER] (확률 보통)
[PER] → [ORG] (확률 낮음)
↓
출력: 최적 레이블 시퀀스
```
**특징:**
- 구조화된 예측 (토큰 간 의존성 고려)
- 가장 확률 높은 시퀀스 보장
- 작은 데이터에서 좋음
### 2. BiLSTM + CRF
```
[John] → [LSTM→] [LSTM←] → 벡터
[works] → [LSTM→] [LSTM←] → 벡터
...
↓
각 벡터에 Classification 적용 + CRF 최적화
```
**장점:** 양방향 문맥, 시퀀스 제약
**단점:** 계산 복잡도, 메모리 사용
### 3. Transformer (BERT + Linear)
```
입력: [John, works, at, Apple, in, California]
↓
BERT (양방향 Encoder)
[각 토큰의 문맥 벡터]
↓
Linear Classification Head
각 토큰 → 개체 유형 확률
↓
출력: [PER, O, O, ORG, O, LOC]
```
**특징:**
- SOTA 성능
- 사전학습 활용
- 간단한 구조 (CRF 불필요)
## 평가 지표
### 토큰 레벨 vs 엔티티 레벨
```
실제: [B-PER, I-PER, O, B-ORG, O, B-LOC]
예측: [B-PER, O, O, B-ORG, B-ORG, B-LOC]
↑ 잘못됨
토큰 정확도: 5/6 = 83%
엔티티 레벨 (완벽하게 맞아야 함):
John Smith: 맞음 (B-PER, I-PER 모두 맞음)
Apple: 틀림 (B-ORG만 맞고, 뒤에 B-ORG 추가)
California: 맞음
엔티티 정확도: 2/3 = 67%
```
### F1 점수 (엔티티 레벨)
```
정밀도 (Precision): 찾은 개체 중 맞은 것
= 맞은 개체 / 찾은 모든 개체
재현율 (Recall): 실제 개체 중 찾은 것
= 맞은 개체 / 실제 개체
F1 = 2 × (정밀도 × 재현율) / (정밀도 + 재현율)
```
## 실전 구현
### Step 1: 데이터 준비
```python
# CoNLL 형식 (IOB 태깅)
example = {
'tokens': ['John', 'works', 'at', 'Apple', 'in', 'California'],
'ner_tags': ['B-PER', 'O', 'O', 'B-ORG', 'O', 'B-LOC']
}
```
### Step 2: 모델 로드 (BERT + Linear)
```python
from transformers import AutoTokenizer, AutoModelForTokenClassification
import torch
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')
model = AutoModelForTokenClassification.from_pretrained(
'bert-base-cased',
num_labels=9 # B-PER, I-PER, B-ORG, I-ORG, ... O
)
```
### Step 3: Fine-tuning
```python
from torch.optim import AdamW
optimizer = AdamW(model.parameters(), lr=2e-5)
for epoch in range(3):
# 배치 처리
tokens = ['John', 'works', 'at', 'Apple']
tags = ['B-PER', 'O', 'O', 'B-ORG']
# 토큰화 (서브토큰 처리)
inputs = tokenizer(
tokens,
truncation=True,
padding=True,
is_split_into_words=True,
return_tensors='pt'
)
# 라벨 정렬 (서브토큰에 맞춤)
labels = align_labels_with_tokens(tags, inputs)
# 포워드
outputs = model(**inputs, labels=torch.tensor([labels]))
loss = outputs.loss
# 역전파
loss.backward()
optimizer.step()
optimizer.zero_grad()
```
### Step 4: 추론
```python
model.eval()
text = "John works at Apple in California"
tokens = text.split()
inputs = tokenizer(
text,
return_tensors='pt',
return_offsets_mapping=True
)
with torch.no_grad():
outputs = model(**inputs)
# 각 토큰의 예측
logits = outputs.logits
predictions = torch.argmax(logits, dim=2)
# 레이블로 변환
id2label = {0: 'O', 1: 'B-PER', ...}
predicted_tags = [id2label[p.item()] for p in predictions[0]]
print(list(zip(tokens, predicted_tags)))
# [('John', 'B-PER'), ('works', 'O'), ...]
```
## 도전 과제
### 1. 모호한 경계
```
"Apple"는 회사(ORG)인가 과일(FRUIT)인가?
"Washington"은 장소(LOC)인가 사람(PER)인가?
해결: 문맥을 통한 양방향 모델 (BERT, Transformer)
```
### 2. 중첩 개체 (Nested Entities)
```
"European Union Commission"
European Union [ORG]
European Union Commission [ORG] (더 큰 개체)
표준 BIO는 중첩을 표현하지 못함
→ Span-based 모델 필요
```
### 3. 도메인 적응
```
의료 텍스트: "질병", "약물" 등 새로운 개체
금융 텍스트: "주식 코드", "환율" 등
해결: 도메인별 Fine-tuning, 전이학습
```
### 4. 다국어
```
한국어: 복합 명사, 조사 처리 어려움
일본어: 한자와 히라가나 혼합
중국어: 단어 경계 불명확
해결: 다국어 모델 (mBERT, XLM-RoBERTa)
```
## 응용 사례
### 1. 정보 추출 (Information Extraction)
```
입력 문서:
"Steve Jobs founded Apple in 1976 in Los Altos, California"
추출 결과:
- 창립자: Steve Jobs (PER)
- 회사: Apple (ORG)
- 년도: 1976 (DATE)
- 위치: Los Altos, California (LOC)
용도: 지식 그래프 구축, 데이터베이스 채우기
```
### 2. 질의응답 (Question Answering)
```
질문: "John은 어디서 일하나?"
문서: "John works at Apple in California"
NER 결과:
John: PER
Apple: ORG ← 조직이므로 답변 후보
California: LOC
답변: "Apple"
```
### 3. 검색 개선
```
검색어: "Apple CEO"
문서 1: "Steve Jobs is the founder of Apple"
(PER: Steve Jobs, ORG: Apple)
문서 2: "Tim Cook leads Apple"
(PER: Tim Cook, ORG: Apple)
개체 기반 인덱싱으로 더 정확한 검색
```
### 4. 텍스트 마이닝
```
소셜 미디어 분석:
"강감찬 장군은 귀주대첩에서 거란군을 격퇴했다"
추출:
- 인물: 강감찬 (PER)
- 사건: 귀주대첩 (EVENT)
- 적: 거란 (ORG/LOC)
추세 분석: 특정 인물/이벤트 언급 빈도
```
## 최신 접근법
### Zero-shot NER (프롬프트 기반)
```
LLM에 직접 요청:
"다음 텍스트에서 사람과 조직을 찾으세요:
John works at Apple"
LLM 응답:
- 사람: John
- 조직: Apple
장점: 학습 데이터 불필요
단점: 성능 변동, 비용
```
### 멀티모달 NER
```
텍스트: "The person in the image is John"
이미지: [사진]
텍스트 NER + 시각적 인식
→ 더 정확한 개체 인식
```
## 현대적 위치 (2024-2026)
### 성능 수렴
```
SOTA 모델들: F1 > 95% (대부분 작업)
→ 성능보다 효율성, 언어 지원, 도메인 적응 중요
```
### 트렌드
- **Few-shot NER**: 적은 데이터로 학습
- **도메인 NER**: 의료, 금융, 법률 특화
- **다국어 NER**: 100+ 언어 지원
- **실시간 NER**: 엣지 디바이스 배포
## 실무 가이드
### 좋은 선택
✅ **상황:**
- 구조화된 정보 추출 필요
- 명확한 개체 유형 정의
- 충분한 라벨링 데이터 (500+ 예시)
✅ **모델:**
- 소규모: BiLSTM-CRF
- 중규모: BERT (한국어: KoBERT)
- 대규모: mBERT, XLM-RoBERTa
### 피해야 할 때
❌ **상황:**
- 개체 정의 모호
- 데이터 매우 부족
- 매우 길거나 노이즈 많은 텍스트
## 관련 개념
- [[ai/nlp/concepts/bert|BERT]] — 기본 아키텍처
- [[ai/algorithms/rnn/concepts/lstm|LSTM]] — 고전 방법
- [[ai/nlp/concepts/text-classification|Text Classification]] — 비슷한 작업
- [[ai/algorithms/transformer/concepts/transformer|Transformer]] — 최신 기초
## 참고 자료
- **Devlin et al. (2018)**: BERT (토큰 분류)
- **CoNLL 2003**: 표준 영어 NER 벤치마크
- **Hugging Face**: Token Classification 튜토리얼
- **Spacy**: 산업 표준 NER 라이브러리