Boostcamp week11 day1

Dae Hee Lee·2021년 10월 12일
0

MRC(Machine Reading Comprehension)

: 주어진 지문 (Context)를 이해하고, 주어진 질의 (Query/Question)의 답변을 추론하는 문제

MRC의 종류

1) Extractive Answer Datasets

: 질의 (question)에 대한 답이 항상 주어진 지문 (context)의 segment (or span)으로 존재

2)Descriptive/Narrative Answer Datasets

: 답이 지문 내에서 추출한 span이 아니라, 질의를 보고 생성 된 sentence (or free-form)의 형태

3) Multiple-choice Datasets

: 질의에 대한 답을 여러 개의 answer candidates 중 하나로 고르는 형태

Challenges in MRC

  • 단어들의 구성이 유사하지는 않지만 동일한 의미의 문장을 이해
    Dataset example: DuoRC (paraphrased paragraph) / QuoRef (coreference resolution)

  • Unanswerable questions
    No Answer 문제에서 답을 내는 문제

  • Multi-hop reasoning
    여러 개의 document에서 질의에 대한 supporting fact를 찾아야지만 답을 찾을 수 있음 Ex. HotpotQA, QAngaroo

MRC의 평가 방법

1) Exact Match / F1 score
: For extractive answer and multiple-choice answer datasets

  • EM
    예측한 답과 ground-truth이 정확히 일치하는 샘플의 비율
  • F1
    예측한 답과 ground-truth 사이의 token overlap을 F1으로 계산

2) ROUGE-L / BLEU
: For descriptive answer datasets
Ground-truth과 예측한 답 사이의 overlap을 계산

  • ROUGE-L Score
    예측한 값과 ground-truth 사이의 overlap recall (ROUGE-L ⇒ LCS (Longest common subsequence)기반)

  • BLEU (Bilingual Evaluation Understudy)
    예측한 답과 ground-truth 사이의 precision (BLEU-n ⇒ uniform n-gram weight)

Unicode & Tokenization

Unicode

전 세계의 모든 문자를 일관되게 표현하고 다룰 수 있도록 만들어진 문자셋 각 문자마다 숫자 하나에 매핑한다.

인코딩, UTF-8

  • 인코딩
    문자를 컴퓨터에서 저장 및 처리할 수 있게 이진수로 바꾸는 것

-UTF-8(Unicode Transformation Format)
UTF-8 는 현재 가장 많이 쓰는 인코딩 방식으로, 문자 타입에 따라 다른 길이의 바이트를 할당한다.
1 byte: Standard ASCII
2 bytes: Arabic, Hebrew, most European scripts
3 bytes: BMP(Basic Multilingual Plane) - 대부분의 현대 글자 (한글 포함) 4 bytes: All Unicode characters - 이모지 등

Python에서 Unicode 다루기

String 타입은 유니코드 표준을 사용한다.

  • ord : 문자를 유니코드 code point로 변환한다
  • chr : Code point를 문자로 변환한다

Unicode와 한국어

  • 완성형
    현대 한국어의 자모 조합으로 나타낼 수 있는
    모든 완성형 한글 11,172자(가, 각, ...,힢,힣) (U+AC00 ~ U+D7A3)

  • 조합형
    조합하여 글자를 만들 수 있는 초·중·종성
    (U+1100 ~ U+11FF, U+A960 ~ U+A97F, U+D7B0 ~ U+D7FF)

Tokenizing

텍스트를 토큰 단위로 나누는 것
단어(띄어쓰기 기준), 형태소, subword 등 여러 토큰 기준이 사용

Subword 토크나이징
자주 쓰이는 글자 조합은 한 단위로 취급하고, 자주 쓰이지 않는 조합은 subword로 쪼갠다.
"##"은 디코딩 (토크나이징의 반대 과정)을 할 때 해당 토큰을 앞 토큰에 띄어쓰기 없이 붙인다는 것을 뜻한다.

BPE(Byte-Pair Encoding)

데이터 압축용으로 제안된 알고리즘.(Data-Driven)
NLP에서 토크나이징용으로 활발하게 사용되고 있다.
1. 가장 자주 나오는 글자 단위 Bigram (or Byte pair) 를 다른 글자로 치환한다.
2. 치환된 글자를 저장해둔다.
3. 1~2번을 반복한다.

Looking into the Dataset

KorQuAD

LG CNS가 AI 언어지능 연구를 위해 공개한 질의응답/기계독해 한국어 데이터셋 인공지능이 한국어 질문에 대한 답변을 하도록 필요한 학습 데이터셋.

LG CNS가 AI 언어지능 연구를 위해 공개한 질의응답/기계독해 한국어 데이터셋
• 인공지능이 한국어 질문에 대한 답변을 하도록 필요한 학습 데이터셋
1,550개의 위키피디아 문서에 대해서 10,649 건의 하위 문서들과 크라우드 소싱을 통해 제작한 63,952 개의 질의응답 쌍으로 구성되어 있음 (TRAIN 60,407 / DEV 5,774 / TEST 3,898)
• 누구나 데이터를 내려받고, 학습한 모델을 제출하고 공개된 리더보드에 평가를 받을 수 있음, 객관적인 기준을 가진 연구 결과 공유가 가능해짐
• v2.0은 보다 긴 분량의 문서가 포함되어 있으며, 단순 자연어 문장 뿐 아니라 복잡한 복잡한 표와 리스트 등을 포함하는 HTML 형태로 표현되어 있어 문서 전체 구조에 대한 이해가 필요 Natural Questions와 유사

KorQuAD 데이터 수집 과정

HuggingFace Datasets 라이브러리

  • HuggingFace 에서 만든 datasets 는 자연어처리에 사용되는 대부분의 데이터셋과 평가 지표를 접근하고 공유할 수 있게끔 만든 라이브러리
  • Numpy, Pandas, PyTorch, Tensorflow2 와 호환
  • 접근가능한 모든 데이터셋이 memory-mapped, cached 되어있어 데이터를 로드 하면서 생기는 메모리 공간 부족이나 전처리 과정 반복의 번거로움 등을 피할 수 있음
  • KorQuAD 데이터셋의 경우 squad_kor_v1, squad_kor_v2 로 불러올 수 있음

Strong Supervision / Distant Supervision
KorQuAD에서 Answer에 해당하는 답에는 Answer start 인덱스 번호가 존재한다. 이러한 인덱스 번호를 주는 이유는 문서 내에서 해당 단어가 질문에 대답을 하기위해 활용되는 부분이 있고 그렇지 않은 경우를 구분해서 생각하도록 만든 것인데, 이렇게 정보를 추가적으로 주는 방식을 Strong Supervision, 그렇지 않은 방법을 Distant Supervision이라 부른다.

HuggingFace Dataset활용

from datasets import load_dataset
dataset = load_dataset('squad_kor_v1', split='train')

dataset["train"]
{'answers': {'answer_start': [54], 'text': ['교향곡']},
 'context': '1839년 바그너는 괴테의 파우스트을 처음 읽고 그 내용에 마음이 끌려 이를 소재로 해서 하나의 교향곡을 쓰려는 뜻을 갖는다. ... 그 사이에 그는 리엔치와 방황하는 네덜란드인을 완성하고 탄호이저에도 착수하는 등 분주한 시간을 보냈는데, 그런 바쁜 생활이 이 곡을 잊게 한 것이 아닌가 하는 의견도 있다.',
 'id': '6566495-0-0',
 'question': '바그너는 괴테의 파우스트를 읽고 무엇을 쓰고자 했는가?',
 'title': '파우스트_서곡'}

Answers와 Text는 여러 개가 나올 수 있기 때문에 리스트 형태로 주어지며 아래와 같이 사용한다.

context = example['context']
answer_text = example['answers']['text'][0]
answer_start = example['answers']['answer_start'][0]
answer_end = answer_start + len(answer_text)

Cased vs Uncased

  1. lowercasing
    BERT uncased : OpenGenus -> opengenus
    BERT cased : OpenGenus
  1. accent striping
    BERT uncased : OpènGènus -> opengenus
    BERT cased : OpènGènus
  1. unicode normalization (NFD)
    BERT uncased : 안녕 -> ㅇ, ㅏ, ㄴ, ㄴ, ㅕ, ㅇ
    BERT cased : 안녕

토크나이징 된 단어를 다시 Decode하기

from transformers import AutoTokenizer

model_checkpoint = "bert-base-multilingual-cased"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
tokenizer.decode(tokenizer(example_text)['input_ids'])
[CLS] 바그너는 괴테의 파우스트를 읽고 무엇을 쓰고자 했는가? [SEP]

전처리

model_checkpoint = "bert-base-multilingual-cased"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)

tokenized_examples = tokenizer(
        examples["question"],
        examples["context"],
        truncation="only_second",  # Truncate to max_length. This will only truncate the second sequence of a pair.
        max_length=max_seq_length,
        stride=doc_stride,
        return_overflowing_tokens=True, # Whether or not to return overflowing token sequences.
        return_offsets_mapping=True,  # Whether or not to return (char_start, char_end) for each token.
        padding="max_length",
    )
  • max_seq_length : 질문과 컨텍스트, special token을 합한 문자열의 최대 길이
  • doc_stride : 컨텍스트가 너무 길어서 나눴을 때 오버랩되는 시퀀스 길이
  • overflowing_tokens : overflowing token sequences
  • offsets_mapping : (char_start, char_end) for each token
  • sequence_id(idx) : idx 번 input data의 시퀀스 구분, 0: question, 1: context
profile
Today is the day

0개의 댓글