logo

[text-mining] 토큰 분류

토큰 분류 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가지 주제로 수업을 한다.''')
Previous
BERT