토근화란?
- 문장을 토큰 시퀸스로 나누는 과정
- 토큰화를 수행하는 프로그램: 토크나이저
- 꼬꼬마, 은전한닢 등 존재.
- 각 토큰에 품사를 붙여주는 품사 부착도 수행.
- 자세한 라이브러리를 보고 싶다면 클릭
단어단위 토큰화
- 어절 단위로 문자를 쪼개는 방법
- 어휘 집합의 크기가 커질 수 있다는 단점이 존재
문자단위 토큰화
- 어휘 집합의 크기가 작아짐.
- 미등록 토큰(어휘집합에 없는 토큰) 문제에서 자유로움
그러나, 다음과 같은 단점도 존재함.
- 토큰 시퀸스의 길이 자체가 길어짐
- 각 문자 토큰이 형태소보다 작아질 수 있음.
- 의미가 사라져 버림.
서브워드 단위 토큰화
- 단어단위와 문자단위의 중간
- ex) 바이트 페어 인코딩
바이트 페어 인코딩
- 원래 정보를 압축하던 알고리즘. 최근에는 NLP에 자주 쓰임
- GPT → BPE 기법
- BERT → 워드피스 기법
BPE 기법
- 문자열을 병합해서 압축하는 기법
- ex) “aaabdaaabac” → “ZabdAabac” → “ZYdZYac” → “XdXac”
- aa를 병합해 Z로 표현했다.
- ab를 병합해 Y로 표현했다.
- ZY를 병합해 X로 표현했다.
- 단어 길이 : 11개 → 5개 / 사전 길이 : 4개 → 7개
- 사전의 크기가 지나치게 늘어나지 않으면서도 단어 길이를 줄임.
어휘 집합 구축
- 말뭉치 준비하고 공백으로 나눠주기
- 공백으로 나눠주기를 프리토크나이즈 라고 한다.
- ex.
cookie → [‘c’, ‘o’, ‘o’, ‘k’, ‘i’, ‘e’]
- 바이그램 쌍을 생성
- 이를 토대로 어휘 집합을 구축한다.
- vocab.json 생성
- 병합 우선순위 생성
- merge.txt
토큰화
어휘집합과 병합 우선순위를 기반으로 시행.
- 문자를 공백 단위로 쪼개기
- 병합 우선순위 부여
- 우선순위가 높은 순대로 먼저 합쳐줌
- 다시 병합 우선순위 부여
- 병합 대상이 없다면 어휘집합에 있는지 검사
- 어휘 집합에 없으면 미등록 토큰으로 처리
워드피스 기법
문자열을 토큰으로 인식한다는 점에서는 동일
단, 어휘 집합 구축 시 문자열을 병합하는 기준이 다름
병합 시 말뭉치의 우도를 가장 높이는 쌍을 병합.
ex. 병합후보가 a, b일때
\frac {\dfrac{\#ab}{n}}
{\dfrac{\#a}{n} \times
\dfrac{\#b}{n} }
수식의 값이 커지려면 a와 b가 독립임을 가정했을 때보다 둘이 자주 동시에 등장해야 함.
즉, 워드피스는 병합 후보에 오른 쌍들을 미리 병합해 보고 잃는 것과 가치 등을 판단한 후 병합.
토큰화
- 분석 대상 어절에 어휘 집합에 있는 서브워드가 포함돼 있을 때 해당 서브워드를 어절에서 분리.
- 단, 서브워드가 여러 개면 가장 긴 것 선택
- 이후 나머지 어절 중에서 서브워드를 다시 찾고, 분리
- 서브워드 후보가 하나도 없으면 해당 문자열 전체를 미등록 단어로 취급
어휘 집합 구축
- 여기서부터는 코딩.
- Google colab을 사용하자.
ratsnlp, Korpora 준비
python
!pip install ratsnlp
python
from Korpora import Korpora
nsmc = Korpora.load("nsmc", force_download=True)
NSMC 전처리
python
import os
def write_lines(path, lines):
with open(path, 'w', encoding='utf-8') as f:
for line in lines:
f.write(f'{line}\n')
write_lines("/content/train.txt", nsmc.train.get_all_texts())
write_lines("/content/test.txt", nsmc.train.get_all_texts())
디렉터리 만들기
python
import os
os.makedirs("/gdrive/My Drive/nlpbook/bbpe", exist_ok = True)
바이트 수준 BPE 어휘 집합 구축
python
from tokenizers import ByteLevelBPETokenizer
bytebpe_tokenzier = ByteLevelBPETokenizer()
bytebpe_tokenzier.train(
files = ["/content/train.txt", "/content/test.txt"],
vocab_size = 10000,
special_tokens = ["[PAD]"]
)
bytebpe_tokenzier.save_model("/gdrive/My Drive/nlpbook/bbpe")
디렉토리 만들기
python
import os
os.makedirs("/gdrive/My Drive/nlpbook/wordpiece", exist_ok=True)
워드피스 어휘집합 구축
python
from tokenizers import BertWordPieceTokenizer
wordpiece_tokenizer = BertWordPieceTokenizer(lowercase=False)
wordpiece_tokenizer.train(
files = ["/content/train.txt", "/content/test.txt"],
vocab_size = 10000
)
wordpiece_tokenizer.save_model("/gdrive/My Drive/nlpbook/wordpiece")
토근화하기
준비코드
python
!pip install ratsnlp
python
from google.colab import drive
drive.mount("/gdrive", force_remount=True)
GPT 입력값 설정
python
from transformers import GPT2Tokenizer
tokenizer_gpt = GPT2Tokenizer.from_pretrained("/gdrive/My Drive/nlpbook/bbpe")
tokenizer_gpt.pad_token = "[PAD]"
python
Sentences = [
"아 더빙...진짜 짜증나네요 목소리",
"연기가 별로 답이 없는 것 같다.",
"별루였다..."
]
tokenized_sentences = [tokenizer_gpt.tokenize(sen) for sen in Sentences]
tokenized_sentences
python
batch_inputs = tokenizer_gpt(
Sentences,
padding = "max_length",
max_length = 12,
truncation = True
)
BERT 입력값 만들기
python
from transformers import BertTokenizer
tokenizer_bert = BertTokenizer.from_pretrained(
"/gdrive/My Drive/nlpbook/wordpiece",
do_lower_case = False
)
python
batch_inputs = tokenizer_bert(
Sentences,
padding = "max_length",
max_length = 12,
truncation = True
)
python
batch_inputs["input_ids"]
""" 결과
[[2, 623, 2639, 16, 16, 16, 1993, 3682, 1990, 3467, 3, 0],
[2, 2347, 2092, 6184, 2062, 128, 2278, 16, 3, 0, 0, 0],
[2, 3341, 2183, 16, 16, 16, 3, 0, 0, 0, 0, 0]]
"""
문장 1과 문장 3에는 뒤에 패딩 토큰 0이 붙음.
- 패딩 토큰이란? 더미토큰으로써 길이를 맞춰주는 역할을 함.