토큰 분류 Token Classification
- 하나의 문장에서 각각의 토큰을 분류하는 과제
- 시퀀스 레이블링 sequence labeling이라고도 함
개체명 인식 Named Entity Recognition
- 텍스트에서 이름에 해당하는 부분을 인식하고 분류
- 일반적인 카테고리: 사람, 장소, 조직, 날짜 등
- 특수한 카테고리: 가격, 시간, 비율 등
- 특정 분야의 카테고리(화학물질, 단백질 명 등)을 사용하기도 함
- 텍스트에서 정보를 추출하는데 사용
- 예: 신문기사에서 기업, 제품 등의 이름을 추출
- 예: 주문에서 메뉴, 수량, 주소 등을 추출
- 대표적 데이터셋: CoNLL 2003 Named Entity Task
- 20만 단어
- Person, Organization, Location, Miscellaneous, Others
BIO 태깅
- 개체명 인식과 같이 토큰 분류 과제에서 토큰을 레이블링하는 방법
- 개체명은 하나 이상의 토큰으로 이뤄져 있을 수 있음(예: "올림픽 공원")
- 종류:
- Beginning: 레이블이 시작되는 토큰(예: B-LOC)
- Inside: 레이블이 계속되는 토큰(예: I-LOC)
- Outside: 레이블이 적용되지 않은 토큰(예: O)
- 예: 올림픽(B-LOC) 공원(I-LOC) 에서(O)
- BIOES 태깅: BIO 태깅의 확장
- End: 마지막 토큰 / Single: 하나의 토큰으로 된 단어
- BIO에 비해 쓰이는 경우가 적음
- BILOU라고도 함(End → Last, Single → Unit)
토크나이저와 모델
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("klue/bert-base")
from transformers import BertForTokenClassification
model = BertForTokenClassification.from_pretrained(
"klue/bert-base", num_labels=13, id2label={
0: 'B-DT', 1: 'I-DT', 2: 'B-LC', 3: 'I-LC', 4: 'B-OG',
5: 'I-OG', 6: 'B-PS', 7: 'I-PS', 8: 'B-QT', 9: 'I-QT',
10: 'B-TI', 11: 'I-TI', 12: 'O'})
KLUE의 NER 데이터셋
from datasets import load_dataset
ner_train = load_dataset('klue', 'ner', split='train')
ner_val = load_dataset('klue', 'ner', split='validation')
- KLUE NER 데이터셋은 글자 단위로 토큰화
next(iter(ner_train))
- BERT 모형은 준단어 토크화되어 있으므로 데이터를 그에 맞게 변환
- 데이터에 왜곡이 생길 가능성이 있으나 크게 문제 되지는 않음
- 변환 코드 다운로드
!git clone https://gist.github.com/220bdfde44d6fcdd78375877370a39f6.git preproc
!mv preproc/ner_preproc.py .
전처리
from tokenizers.pre_tokenizers import BertPreTokenizer
import ner_preproc
preproc = ner_preproc.TokenAlignPreprocessor(
tokenizer=tokenizer, pre_tokenizer=BertPreTokenizer(), outside_label_id=12)
train_ds = ner_train.map(preproc.convert_example)
eval_ds = ner_val.map(preproc.convert_example)
next(iter(train_ds))
훈련
from transformers import DataCollatorForTokenClassification
data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(output_dir="test_trainer", num_train_epochs=1,
eval_strategy="epoch")
trainer = Trainer(model=model, args=training_args, train_dataset=train_ds,
eval_dataset=eval_ds, data_collator=data_collator)
trainer.train()
파이프라인
from transformers import pipeline
ner = pipeline(
'token-classification',
model=model,
tokenizer=tokenizer,
device='cuda:0')
ner('''오늘 12시 서울특별시 성북구에 있는 국민대 경영대학원에서
유재명 교수가 1가지 주제로 수업을 한다.''')