# 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 라이브러리