SlideShare a Scribd company logo
PyCon Korea 2019
한국어 띄어쓰기 프로그램 도전기
Taekyoon Choi
(tgchoi03@gmail.com)
Contents
• 서론
• 띄어쓰기 프로그램
• 띄어쓰기 모델 개발
• Korean BERT 적용
• 결론
서론
자연어처리에서 띄어쓰기
• 자연어처리에서는 텍스트를 토큰 단위로 구분하여 다룸
• 쉽게 토크나이징을 할 수 있는 방법은 띄어 쓴 단어를 구분하는 것
• 한국어에서 띄어쓰기는 텍스트 의미를 구분하는데 큰 영향을 줄 수 있음
띄어쓰기로 인한 문제
• 문맥 없이 띄어쓰기로 의미 구분을 명확히 하기 어려움
>>> text = '학교종이 땡땡땡’
>>> print(text.split())
[‘학교종이’, ‘땡땡땡’]
# [‘학교종이’] or [‘학교’,‘종이’]?
띄어쓰기로 인한 문제
• 띄어쓰기를 잘못하면 전처리 분석에서 어려워짐
# 형태소 분석 Case
>>> import konlpy
>>> morph_analyzer = konlpy.tag.Okt()
>>> morph_analyzer.pos('너무기대안하고갔나 재밌게봤다’)
[('너', 'Modifier'), ('무기', 'Noun'), ('대안', 'Noun’),
('하고', 'Josa’), ('갔나', 'Verb'), ('재밌게', 'Adjective'), … ]
# 띄어쓰기에 따라 분석이 제대로 안 될 수도 있음
참고링크: https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/05/10/postag/
띄어쓰기 알고리즘 개발의 한계
• 대체로 띄어쓰기 오픈소스는 이미 수집한 데이터에 학습된 알고리즘으로 구성
• 코퍼스 도메인에 따라 띄어쓰기 성능이 달라질 수 있음
• 목적 도메인에 맞는 띄어쓰기 문제를 해결하기에 한계가 있음
>>> from pykospacing import spacing
>>> spacing('너는나의원수야').replace(' ', '_’)
'너는_나_의원수야’
띄어쓰기 프로그램
띄어쓰기 프로그램 실행 구조
“오늘서울 날씨 어때” “오늘서울날씨어때” “오늘 서울 날씨 어때”
1.입력 텍스트에
모든 공백을 없앰
2. 모델에 입력하여
띄어쓰기가 된
문장을 출력
전처리 문장입력 문장 띄어 쓴 문장
띄어쓰기 모델 학습 구조
Candidate Models
Train
Test
&
Update
Training Data
N-Iteration
works
1. 학습 데이터 구성 2. 모델 학습
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
DataManager
Object
Trainer
Object
Evaluator
Object
Model
Tokenizer
Vocabulary
Configs.json
띄어쓰기 프로그램 구조 설계
Agent
Object
Model
Tokenizer
Vocabulary
Configs.json
1. 띄어쓰기 프로그램 설정을
Configs.json으로 정의하여
Agent 객체에 등록
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
Model
Tokenizer
Vocabulary
2. Agent 객체를 활용하여
학습과 평가, 실행 기능을
수행하도록 함
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
DataManager
Object
Trainer
Object
Evaluator
Object
Model
Tokenizer
Vocabulary
3. 기능 수행하기 위해
학습, 데이터 관리, 평가 객체를
통해 수행하도록 함
띄어쓰기 프로그램 실행 구현
>>> from takos.agents.word_segment import WordSegmentAgent
>>> spacing_agent = WordSegmentAgent('your_config.json’) # 설정파일 등록
>>> spacing_agent.train() # 학습
>>> spacing_agent.eval() # 평가
>>> spacing_agent('학교종이땡땡땡’) # 실행
'학교종이 땡땡땡’
{ .......
"dataset": {
"name": "your_dataset",
"train": {
"input":"./samples/train.txt"
},
"test": {
"input": "./samples/test.txt"
}
} .......
}
띄어쓰기 모델 개발
Baseline 모델 설계
• 시퀀스 분류 모델: CRF, RNN, RNN-CRF 등
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
오 늘 서 울 날 씨
B I B I B I
띄어쓰는 지점에 대해
‘B’ 태그로 예측 하도록 학습
BiLSTM-CRF
• BiLSTM을 통해 입력한 토큰과 앞뒤 시퀀스
정보를 토대로 띄어쓰기 지점을 예측
• Conditional Random Field (CRF) 를 통해
시퀀스 태그의 순서를 보정
BiLSTM-CRF 모델 예시
Embedding
BiLSTM
CRF
참고링크: https://towardsdatascience.com/implementing-a-linear-chain-conditional-random-field-crf-in-pytorch-16b0b9c4b4ea
BiLSTM-CRF 구현 - Initialize
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
Word
Embedding
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
BiLSTM-CRF 구현 - Initialize
BiLSTM
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
BiLSTM-CRF 구현 - Initialize
CRF
BiLSTM-CRF 구현 - Loss
class BilstmCRF(nn.Module):
def loss(self, x: torch.Tensor, y: torch.Tensor):
masking = x.ne(self._pad_idx).float()
fmap = self._embedding(x)
hiddens, _ = self._bilstm(fmap, masking)
emissions = self._fc(hiddens)
nll = self._crf(emissions, y, mask=masking)
return nll
CRF Layer에서 loss
값을 출력
Pad 정보를
없애기 위한
Masking 처리
모델 연산
BiLSTM-CRF 구현 - Inference
class BilstmCRF(nn.Module):
def forward(self, x: torch.Tensor):
masking = x.ne(self._pad_idx).float()
fmap = self._embedding(x)
hiddens, _ = self._bilstm(fmap, masking)
emissions = self._fc(hiddens)
_, path = self._crf.decode(emissions, mask=masking)
return path
Viterbi 디코딩을 통해
최적의 시퀀스를 출력
세종 코퍼스 데이터셋 수집
• Github에 coolengineer/sejong-corpus
프로젝트를 다운로드
• 커멘드를 통해 문장 추출
# bash command
$ cd sejong-corpus
$ make
$ bash 50.sent_extract.sh corpus-utf8
$ cat tmp/s/* > corpus.txt
Sejong-corpus Github 프로젝트
세종 코퍼스 데이터셋 구성
• 전체 코퍼스 수 (str.split() 기준): 1,664,458 개 (문어 92.5%, 구어 7.5%)
• Unique 코퍼스 수: 1,537,741 개
• 전체 문장 수 (str.split(‘n’) 기준): 1,038,087 개 (문어 79.3%, 구어 20.7%)
세종 코퍼스 문장 길이 분석
• 어절 토큰 길이는 100이 가장 긴 경우
• 음절의 경우 대부분의 토큰 길이가 130 미만
토큰 단위 별 문장 길이 분포
세종 코퍼스 어절 단어 분포 분석
• 동사와 관련된 어휘가 많이 분포
• ‘하다’와 관련된 파생어들도 많이 보임
• ‘이’나 ‘그’ 와 같은 지칭 대명사와 같은 단어가 많이
발생
세종 데이터 어절 분포
Self Supervised Learning
• 데이터 자체만으로 학습하는 방법
• 입력 데이터에 의해 Labeling 이 가능
• 띄어쓰기의 경우 단어의 시작 지점 또는 끝 지점으로 Label 생성
학습 labeling 방식
• 기존 띄어쓰기 모델은 띄어쓰기 경계를 예측하는 `경계 인식 방식`으로 함
• 경계 인식 방식의 경우 입력한 토큰이 경계 지점인지 판별하는 학습만 함
• 단어 영역을 예측하는 `영역 인식 방식`을 통해 경계 지점 외에 띄어쓰기에 필요한 정보를
학습하도록 함
V
학습 labeling 방식
• 경계 인식 방식
VVV
나 는 오 늘 학 교 에 갈 수 있 다
B I B I B I I B B B I
띄어 쓰는 경계 지점을 학습하는 방식
- B: Begin
- I : Inside
VV
학습 Labeling 방식
• 영역 인식 방식
- B: Begin
- I : Inside
- E: End
- S: Single
단어 영역을 학습하는 방식
나 는 오 늘 학 교 에 갈 수 있 다
B E B E B I E S S B E
참고논문: Universal Word Segmentation: Implementation and Interpretation Shao et al. [ACL 2018]
학습 데이터셋 구성
• 학습 데이터셋: 934,278 (전체 90%)
• 평가 데이터셋: 103,809 (전체 10%)
**검증 데이터셋 은 학습 데이터셋에 10%를 무작위 추출 함
모델 학습 하이퍼파라메터
• Vocab Size & Embedding Dim: 3710 개, 32
• BiLSTM Feature Dim: 64 * 2
• Optimizer: torch.optim.Adam(3e-4)
• Batch size: 128
• Limit Sequence Length: 100
• Validation F1 Score가 수렴 될 때까지 학습
Baseline 성능 평가 기준
• F1 Score (띄어쓰기 경계 인식 기준)
• WER (Word Error Rate) Score
• SER (Sentence Error Rate) Score
WER 계산 방식
Baseline 성능 평가
KoSpacing 경계 인식 방식 영역 인식 방식
F1 Score - 97.71 97.83
WER Score 18.05 12.47 11.91
SER Score 49.77 40.84 39.11
False Case 분석
• 복합 명사의 띄어쓰기 문제
예측 문장 정답 문장
초고액 상품권이 빚어낼 사회 심리적 영향을
짚어봐야 한다.
초고액 상품권이 빚어낼 사회심리적 영향을
짚어봐야 한다.
물론 이 일이 실현되려면 과학기술의 측면에서
수많은 장벽을 넘어서야 한다.
물론 이 일이 실현되려면 과학 기술의 측면에서
수많은 장벽을 넘어서야 한다.
False Case 분석
• 한 글자 어절의 띄어쓰기 문제
예측 문장 정답 문장
방랑시인 김입은 때 마침 길에서
가난한 농부에게 식사를 대접받았다.
방랑시인 김입은 때마침 길에서
가난한 농부에게 식사를 대접받았다.
승리의 기쁨에 도취된 트로이군은 성안으로
목마를 들여놓고 축제를 벌인다.
승리의 기쁨에 도취된 트로이군은 성 안으로
목마를 들여놓고 축제를 벌인다.
경계 인식 방식 VS 영역 인식 방식
• False Case 를 통해서 두 방식의 차이가 무엇인지 파악하기 어려움
• Labeling 방식 차이가 모델 띄어쓰기 예측에 어떤 영향을 주는가?
• 띄어쓰기를 판별하는데 어떤 입력 정보가 가장 영향력이 있는가?
Local Interpretable Model-agnostic
Explanations (LIME) 알고리즘 분석
• 모델 예측을 할 때 크게 영향을 주는 입력 요소를 찾는 알고리즘
• 모델이 어떻게 예측 했는지 입력 데이터를 통해 시각적으로 표현
LIME 알고리즘 분석 예시
참고링크: https://dreamgonfly.github.io/2017/11/05/LIME.html
안 녕 하 세 요 저 _ 홍 길 동 입 니 다
안 녕 하 세 요 _ 는 홍 길 _ 입 니 다
안 녕 하 _ 요 저 는 홍 길 동 입 니 다
안 녕 _ _ 요 저 는 홍 _ _ 입 니 다
띄어쓰기 모델에서 LIME 알고리즘 활용
• ‘홍’ 이란 어절을 띄어쓰기를 하는데 어느 음절 토큰이 얼마나 기여하는가?
안녕하세요저는홍길동입니다 ➔ 안녕하세요 저는 홍길동입니다
띄어쓰기: 0.2
띄어쓰기: 0.5
띄어쓰기: 0.8
띄어쓰기: 0.7
LIME을 통한 띄어쓰기 모델 분석
• 경계 인식 모델
띄어 쓰기 전 토큰의 영향을 많이 받음
• 영역 인식 모델
띄어 쓰는 지점 주변 토큰의 영향을 고르게 받음
• 상대적으로 “입력 정보를 편향적으로 받지 않는”
점이 좋은 띄어쓰기 예측하는 것으로 보임
경계 인식 모델 분석 영역 인식 모델 분석
입력: 안녕하세요저는홍길동입니다
출력: 안녕하세요 저는 홍길동입니다
Korean BERT 모델 적용
Transformer Network
• Self Attention 기법으로 시퀀스 정보들 간의 관계를 학습
• Multi-head Attention 으로 다양한 관점에서 시퀀스 관계를 볼 수 있도록 함
Transformer EncoderSelf Attention
참고링크: http://jalammar.github.io/illustrated-transformer/
Korean BERT (ETRI ver.)
• Transformer Encoder로 구성된 모델
• 한국어 텍스트 데이터를 Semi-Unsupervised
Learning 하여 언어 모델로 학습
• Fine-tuning 만으로 여러 NLP Task에서 좋은 성능을
보임
ETRI Korean BERT
참고링크: http://jalammar.github.io/illustrated-bert/
Korean BERT 구현 - Initialize
import torch.nn as nn
from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel
class BertTagger(BertPreTrainedModel):
def __init__(self, config, tag_size, pad_idx=0, cls_idx=2):
super(BertTagger, self).__init__(config)
self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size
self.bert = BertModel(config)
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
self.activation = nn.Tanh()
self.dense_2 = nn.Linear(config.hidden_size, tag_size)
self.ce_loss = nn.CrossEntropyLoss(reduction='none')
BERT Layer
Korean BERT 구현 - Initialize
import torch.nn as nn
from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel
class BertTagger(BertPreTrainedModel):
def __init__(self, config, tag_size, pad_idx=0, cls_idx=2):
super(BertTagger, self).__init__(config)
self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size
self.bert = BertModel(config)
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
self.activation = nn.Tanh()
self.dense_2 = nn.Linear(config.hidden_size, tag_size)
self.ce_loss = nn.CrossEntropyLoss(reduction='none')
Dense Layer
Korean BERT 구현 - Inference
class BertTagger(BertPreTrainedModel):
def forward(self, x: torch.Tensor):
batch_size = x.size(0)
cls_mark = torch.full((batch_size, 1), self._cls_idx).to(self.device)
x = torch.cat([x, cls_mark], dim=-1)
masking = x.ne(self._pad_idx)
encoder_layer, _ = self.bert(x, attention_mask=masking,
output_all_encoded_layers=False)
dense_layer = self.activation(self.dense(encoder_layer [:, 1:]))
emissions = nn.functional.softmax(self.dense_2(dense_layer),
dim=-1)
path = torch.argmax(emissions, dim=-1)
return path
BERT 모델
입력값 준비
Masking
Korean BERT 성능 결과
KoSpacing BiLSTM-CRF (영역)
KoBERT
(3 Layers)
KoBERT
(6 Layers)
F1 Score - 97.83 98.62 98.70
WER Score 18.05 11.91 8.08 7.63
SER Score 49.77 39.11 30.24 28.65
Korean BERT 처리 속도 비교
length BiLSTM-CRF (영역)
15 0.004 (± 0.001)
50 0.014 (± 0.001)
100 0.03 (± 0.001)
KoBERT (3 Layers)
0.018 (± 0.003)
0.038 (± 0.002)
0.073 (± 0.003)
KoBERT (6 Layers)
0.035 (± 0.003)
0.076 (± 0.003)
0.141 (± 0.003)
*처리속도 (1건 당 sec)
- CPU model: AMD Ryzen 7 1700 8-core. - RAM: 64GB
결론
정리
• 수집 데이터를 활용한 띄어쓰기 프로그램 개발 (세종 코퍼스 데이터셋으로 검증)
• 학습한 모델이 모든 범주에 대한 띄어쓰기를 잘 할 수 있지는 않음
• 띄어 쓴 정보를 수용할 수 있는 공백 정보 반영 학습을 적용해 볼 필요 있음
• 가급적 띄어쓰기가 잘 된 데이터를 많이 학습해 볼 것
TaKos Project
TaKos(Train-able Korean spacing) Project
• 데이터 학습 가능한 띄어쓰기 알고리즘을
만들기 위한 프로젝트
• Github에서 TaKos 프로젝트를 다운로드
• 프로젝트 내에서 명령어 실행
pip install -r requirements
python setup.py install
TaKos Project Repo:
github.com/Taekyoon/takos-alpha
TaKos(Train-able Korean spacing) Project
• 띄어쓰기 데이터만 주어지면 모델 학습하여 제공
# 간단하게 띄어쓰기 모델을 만들어 봅시다
from takos.agents.word_segment import WordSegmentAgent
spacing_agent = WordSegmentAgent('your_config.json’)
spacing_agent.train()
spacing_agent.eval()
spacing_agent('학교종이땡땡땡')
{ .......
"dataset": {
"name": "your_dataset",
"train": {
"input":"./samples/train.txt"
},
"test": {
"input": "./samples/test.txt"
}
} .......
}
Q & A
Appendix
띄어쓰기로 인한 문제 (추가-1)
• 띄어쓰기를 잘못하면 토큰 인덱싱에서 어려워짐
# BertTokenizer or WordPiece case (ETRI Bert)
tokenizer = BertTokenizer.from_pretrained('vocab.korean.rawtext.list’)
tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무 기대 안하고 갔나’)
>>> [1051, 5132, 129, 58, 1976, 230]
tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무기대 안하고갔나’))
>>> [567, 69, 5132, 129, 660, 1976, 230]
# 띄어쓰기에 따라 변환된 인덱스 값이 다름
띄어쓰기가 필요한 문제 (추가-2)
• Speech to Text Case (Google Speech API)
“콜라는_하나만_가져_주_셔도_될_것_같_아요_여기_위치는_올림픽_공원_평화의
문_부분이고요 _만나서_결제할게요”
• configs.json
{
"type": "word_segment",
"gpu_device": 0,
"dataset": {
"name": "sejong_spacing",
"train": {
"bi_tags_only": false,
"vocab_min_freq": 10,
"input": "train.txt"},
"test": {
"limit_len": 150,
"input": "test.txt"}
},
"deploy": {
"path": "./tmp/test_model"},
"model": {
"type": "bilstm_crf",
"parameters": {
"word_embedding_dims": 32,
"hidden_dims": 64}
},
"train": {
"epochs": 50,
"eval_steps": 1000,
"eval_batch_size": 512,
"batch_size": 128,
"sequence_length": 100
}
띄어쓰기 프로그램 설정 구성
띄어쓰기 프로그램 실행 구현
def run(self, query):
prepro_query = self.preprocess(query)
tokenized_query = self.tokenizer.tokenize(prepro_query).split()
model_inputs = torch.Tensor([self.vocab.to_indices(tokenized_query)])
pred_score, tag_seq = self.model(model_inputs)
labeled_tag_seq = self.label.to_tokens(tag_seq[0].tolist())
post_processed = self.postprocess(prepro_query, labeled_tag_seq)
outputs = {'output': post_processed}
return outputs
입력 텍스트 전처리
띄어쓰기 처리
띄어쓰기 모델 학습 구현
def train(self):
train_configs = self.configs['train']
train_dataset_configs = self.configs['dataset']['train']
data_builder = create_builder(self.task_type, train_dataset_configs)
model = create_model(self.task_type, tag_to_idx, self.model_configs)
trainer = create_trainer(self.task_type, model, data_builder,
train_configs)
trainer.train()
기능 수행을 위한 객체 생성
띄어쓰기 모델 평가 구현
def eval(self):
test_dataset_configs = self.configs['dataset']['test']
train_dataset_configs = self.configs['dataset']['train']
data_builder = create_builder(self.task_type, train_dataset_configs)
evaluator = create_evaluator(self.task_type, self.model, data_builder,
test_dataset_configs, limit_len)
evaluator.eval()
logger.info(evaluator.summary()) 기능 수행을 위한 객체 생성
모델 개발에 활용한 리서치 자료
• PyKoSpacing
• 2018년 HCLT 학술대회에 나온 논문들
• 문장 정보를 고려한 딥러닝 기반 자동 띄어쓰기의 개념 및 활용
• 띄어쓰기 및 문장 경계 인식을 위한 다중 손실 선형 결합 기반의 다중 클래스 분류 시스템
• CRFs와 Bi-LSTM/CRFs의 비교 분석: 자동 띄어쓰기 관점에서
• 자동띄어쓰기 오류 수정 및 복합명사 분해 개요: 2018 차세정 언어처리 경진대회
False Case 분석 (추가)
• 그 외 띄어쓰기 문제
예측 문장 정답 문장
소독용에 탄 올 스프레이를 수시로 뿌린다. 소독용 에탄올 스프레이를 수시로 뿌린다.
주말쯤 작전이 시작될 것이라고
미국 방부 및 나토 의미 관계자들이 23일 밝혔다.
주말쯤 작전이 시작될 것이라고
미 국방부 및 나토의 미 관계자들이 23일 밝혔다.
LIME을 통한 띄어쓰기 모델 분석 (추가)
경계 인식 모델 분석
영역 인식 모델 분석
입력: 세종대왕께서한글을창조하셨다
출력: 세종대왕께서 한글을 창조하셨다
경계 인식 모델 분석
영역 인식 모델 분석
입력: 세종대왕께서한글을창조하셨다
출력: 세종대왕께서 한글을 창조하셨다

More Related Content

PDF
한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기
PDF
Dependency Parser, 의존 구조 분석기
ODP
Hunspell 한국어 맞춤법 검사의 원리
PDF
AtCoder Beginner Contest 007 解説
PDF
2019年度チュートリアルBPE
PDF
[224] 번역 모델 기반_질의_교정_시스템
PPTX
強化学習6章
PDF
카카오톡으로 여친 만들기 2013.06.29
한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기
Dependency Parser, 의존 구조 분석기
Hunspell 한국어 맞춤법 검사의 원리
AtCoder Beginner Contest 007 解説
2019年度チュートリアルBPE
[224] 번역 모델 기반_질의_교정_시스템
強化学習6章
카카오톡으로 여친 만들기 2013.06.29

What's hot (20)

PDF
第21回アルゴリズム勉強会
PDF
(2018.3) 分子のグラフ表現と機械学習
PPTX
テストを書こう!!
PPTX
東京大学2020年度深層学習(Deep learning基礎講座) 第9回「深層学習と自然言語処理」
PDF
실시간 게임 서버 최적화 전략
PPTX
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
PDF
技術者が知るべき Gröbner 基底
PDF
[DL輪読会]Addressing Failure Prediction by Learning Model Confidence
PPTX
配送最適化
PDF
闇魔術を触ってみた
PPTX
単語分散表現のアライメントに基づく文間類似度を用いたテキスト平易化のための単言語パラレルコーパスの構築
PDF
PHP の GC の話
PPTX
[研究室論文紹介用スライド] Adversarial Contrastive Estimation
PDF
충돌 알고리즘(collision detection algorithms)
PDF
[DL輪読会]Parallel WaveNet: Fast High-Fidelity Speech Synthesis
PDF
R実践 機械学習による異常検知 01
PPTX
連続変量を含む条件付相互情報量の推定
PDF
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
PPTX
Rでのtry関数によるエラー処理
PPTX
NLPにおけるAttention~Seq2Seq から BERTまで~
第21回アルゴリズム勉強会
(2018.3) 分子のグラフ表現と機械学習
テストを書こう!!
東京大学2020年度深層学習(Deep learning基礎講座) 第9回「深層学習と自然言語処理」
실시간 게임 서버 최적화 전략
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
技術者が知るべき Gröbner 基底
[DL輪読会]Addressing Failure Prediction by Learning Model Confidence
配送最適化
闇魔術を触ってみた
単語分散表現のアライメントに基づく文間類似度を用いたテキスト平易化のための単言語パラレルコーパスの構築
PHP の GC の話
[研究室論文紹介用スライド] Adversarial Contrastive Estimation
충돌 알고리즘(collision detection algorithms)
[DL輪読会]Parallel WaveNet: Fast High-Fidelity Speech Synthesis
R実践 機械学習による異常検知 01
連続変量を含む条件付相互情報量の推定
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
Rでのtry関数によるエラー処理
NLPにおけるAttention~Seq2Seq から BERTまで~
Ad

Similar to 한국어 띄어쓰기 프로그램 도전기 (20)

PDF
댓글 감성 분석 상용화 개발기(Ver. 2)
PPTX
단어 의미 중의성 해소, Word Sense Disambiguation(WSD)
PDF
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
PDF
소프트웨어 2.0을 활용한 게임 어뷰징 검출
PPTX
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
PDF
Phrase Tagger, 구문 태거
PDF
Context2Vec 기반 단어 의미 중의성 해소, Word Sense Disambiguation
PDF
Pycon Korea 2020
PPTX
2206 Modupop!
PPTX
제3장 색인어 추출을 위한 언어학적 처리
PDF
파이썬을 활용한 자연어분석 기초
PDF
Sharing development experience of educational apps for the hard of hearing (P...
PDF
Open domain dialogue Chatbot(잡담봇 삽질기)
PDF
파이썬을 활용한 자연어 분석
PDF
[224] backend 개발자의 neural machine translation 개발기 김상경
PPT
영어 말하기 자동채점 프로그램의 현재와 미래
PDF
Python을 활용한 챗봇 서비스 개발 1일차
PDF
[2D2]다국어음성합성시스템(NVOICE)개발
PDF
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
PDF
C 언어 스터디 01 - 기초
댓글 감성 분석 상용화 개발기(Ver. 2)
단어 의미 중의성 해소, Word Sense Disambiguation(WSD)
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
소프트웨어 2.0을 활용한 게임 어뷰징 검출
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Phrase Tagger, 구문 태거
Context2Vec 기반 단어 의미 중의성 해소, Word Sense Disambiguation
Pycon Korea 2020
2206 Modupop!
제3장 색인어 추출을 위한 언어학적 처리
파이썬을 활용한 자연어분석 기초
Sharing development experience of educational apps for the hard of hearing (P...
Open domain dialogue Chatbot(잡담봇 삽질기)
파이썬을 활용한 자연어 분석
[224] backend 개발자의 neural machine translation 개발기 김상경
영어 말하기 자동채점 프로그램의 현재와 미래
Python을 활용한 챗봇 서비스 개발 1일차
[2D2]다국어음성합성시스템(NVOICE)개발
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
C 언어 스터디 01 - 기초
Ad

한국어 띄어쓰기 프로그램 도전기

  • 1. PyCon Korea 2019 한국어 띄어쓰기 프로그램 도전기 Taekyoon Choi (tgchoi03@gmail.com)
  • 2. Contents • 서론 • 띄어쓰기 프로그램 • 띄어쓰기 모델 개발 • Korean BERT 적용 • 결론
  • 4. 자연어처리에서 띄어쓰기 • 자연어처리에서는 텍스트를 토큰 단위로 구분하여 다룸 • 쉽게 토크나이징을 할 수 있는 방법은 띄어 쓴 단어를 구분하는 것 • 한국어에서 띄어쓰기는 텍스트 의미를 구분하는데 큰 영향을 줄 수 있음
  • 5. 띄어쓰기로 인한 문제 • 문맥 없이 띄어쓰기로 의미 구분을 명확히 하기 어려움 >>> text = '학교종이 땡땡땡’ >>> print(text.split()) [‘학교종이’, ‘땡땡땡’] # [‘학교종이’] or [‘학교’,‘종이’]?
  • 6. 띄어쓰기로 인한 문제 • 띄어쓰기를 잘못하면 전처리 분석에서 어려워짐 # 형태소 분석 Case >>> import konlpy >>> morph_analyzer = konlpy.tag.Okt() >>> morph_analyzer.pos('너무기대안하고갔나 재밌게봤다’) [('너', 'Modifier'), ('무기', 'Noun'), ('대안', 'Noun’), ('하고', 'Josa’), ('갔나', 'Verb'), ('재밌게', 'Adjective'), … ] # 띄어쓰기에 따라 분석이 제대로 안 될 수도 있음 참고링크: https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/05/10/postag/
  • 7. 띄어쓰기 알고리즘 개발의 한계 • 대체로 띄어쓰기 오픈소스는 이미 수집한 데이터에 학습된 알고리즘으로 구성 • 코퍼스 도메인에 따라 띄어쓰기 성능이 달라질 수 있음 • 목적 도메인에 맞는 띄어쓰기 문제를 해결하기에 한계가 있음 >>> from pykospacing import spacing >>> spacing('너는나의원수야').replace(' ', '_’) '너는_나_의원수야’
  • 9. 띄어쓰기 프로그램 실행 구조 “오늘서울 날씨 어때” “오늘서울날씨어때” “오늘 서울 날씨 어때” 1.입력 텍스트에 모든 공백을 없앰 2. 모델에 입력하여 띄어쓰기가 된 문장을 출력 전처리 문장입력 문장 띄어 쓴 문장
  • 10. 띄어쓰기 모델 학습 구조 Candidate Models Train Test & Update Training Data N-Iteration works 1. 학습 데이터 구성 2. 모델 학습
  • 11. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() DataManager Object Trainer Object Evaluator Object Model Tokenizer Vocabulary Configs.json
  • 12. 띄어쓰기 프로그램 구조 설계 Agent Object Model Tokenizer Vocabulary Configs.json 1. 띄어쓰기 프로그램 설정을 Configs.json으로 정의하여 Agent 객체에 등록
  • 13. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() Model Tokenizer Vocabulary 2. Agent 객체를 활용하여 학습과 평가, 실행 기능을 수행하도록 함
  • 14. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() DataManager Object Trainer Object Evaluator Object Model Tokenizer Vocabulary 3. 기능 수행하기 위해 학습, 데이터 관리, 평가 객체를 통해 수행하도록 함
  • 15. 띄어쓰기 프로그램 실행 구현 >>> from takos.agents.word_segment import WordSegmentAgent >>> spacing_agent = WordSegmentAgent('your_config.json’) # 설정파일 등록 >>> spacing_agent.train() # 학습 >>> spacing_agent.eval() # 평가 >>> spacing_agent('학교종이땡땡땡’) # 실행 '학교종이 땡땡땡’ { ....... "dataset": { "name": "your_dataset", "train": { "input":"./samples/train.txt" }, "test": { "input": "./samples/test.txt" } } ....... }
  • 17. Baseline 모델 설계 • 시퀀스 분류 모델: CRF, RNN, RNN-CRF 등 BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF 오 늘 서 울 날 씨 B I B I B I 띄어쓰는 지점에 대해 ‘B’ 태그로 예측 하도록 학습
  • 18. BiLSTM-CRF • BiLSTM을 통해 입력한 토큰과 앞뒤 시퀀스 정보를 토대로 띄어쓰기 지점을 예측 • Conditional Random Field (CRF) 를 통해 시퀀스 태그의 순서를 보정 BiLSTM-CRF 모델 예시 Embedding BiLSTM CRF 참고링크: https://towardsdatascience.com/implementing-a-linear-chain-conditional-random-field-crf-in-pytorch-16b0b9c4b4ea
  • 19. BiLSTM-CRF 구현 - Initialize import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) Word Embedding
  • 20. import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) BiLSTM-CRF 구현 - Initialize BiLSTM
  • 21. import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) BiLSTM-CRF 구현 - Initialize CRF
  • 22. BiLSTM-CRF 구현 - Loss class BilstmCRF(nn.Module): def loss(self, x: torch.Tensor, y: torch.Tensor): masking = x.ne(self._pad_idx).float() fmap = self._embedding(x) hiddens, _ = self._bilstm(fmap, masking) emissions = self._fc(hiddens) nll = self._crf(emissions, y, mask=masking) return nll CRF Layer에서 loss 값을 출력 Pad 정보를 없애기 위한 Masking 처리 모델 연산
  • 23. BiLSTM-CRF 구현 - Inference class BilstmCRF(nn.Module): def forward(self, x: torch.Tensor): masking = x.ne(self._pad_idx).float() fmap = self._embedding(x) hiddens, _ = self._bilstm(fmap, masking) emissions = self._fc(hiddens) _, path = self._crf.decode(emissions, mask=masking) return path Viterbi 디코딩을 통해 최적의 시퀀스를 출력
  • 24. 세종 코퍼스 데이터셋 수집 • Github에 coolengineer/sejong-corpus 프로젝트를 다운로드 • 커멘드를 통해 문장 추출 # bash command $ cd sejong-corpus $ make $ bash 50.sent_extract.sh corpus-utf8 $ cat tmp/s/* > corpus.txt Sejong-corpus Github 프로젝트
  • 25. 세종 코퍼스 데이터셋 구성 • 전체 코퍼스 수 (str.split() 기준): 1,664,458 개 (문어 92.5%, 구어 7.5%) • Unique 코퍼스 수: 1,537,741 개 • 전체 문장 수 (str.split(‘n’) 기준): 1,038,087 개 (문어 79.3%, 구어 20.7%)
  • 26. 세종 코퍼스 문장 길이 분석 • 어절 토큰 길이는 100이 가장 긴 경우 • 음절의 경우 대부분의 토큰 길이가 130 미만 토큰 단위 별 문장 길이 분포
  • 27. 세종 코퍼스 어절 단어 분포 분석 • 동사와 관련된 어휘가 많이 분포 • ‘하다’와 관련된 파생어들도 많이 보임 • ‘이’나 ‘그’ 와 같은 지칭 대명사와 같은 단어가 많이 발생 세종 데이터 어절 분포
  • 28. Self Supervised Learning • 데이터 자체만으로 학습하는 방법 • 입력 데이터에 의해 Labeling 이 가능 • 띄어쓰기의 경우 단어의 시작 지점 또는 끝 지점으로 Label 생성
  • 29. 학습 labeling 방식 • 기존 띄어쓰기 모델은 띄어쓰기 경계를 예측하는 `경계 인식 방식`으로 함 • 경계 인식 방식의 경우 입력한 토큰이 경계 지점인지 판별하는 학습만 함 • 단어 영역을 예측하는 `영역 인식 방식`을 통해 경계 지점 외에 띄어쓰기에 필요한 정보를 학습하도록 함
  • 30. V 학습 labeling 방식 • 경계 인식 방식 VVV 나 는 오 늘 학 교 에 갈 수 있 다 B I B I B I I B B B I 띄어 쓰는 경계 지점을 학습하는 방식 - B: Begin - I : Inside VV
  • 31. 학습 Labeling 방식 • 영역 인식 방식 - B: Begin - I : Inside - E: End - S: Single 단어 영역을 학습하는 방식 나 는 오 늘 학 교 에 갈 수 있 다 B E B E B I E S S B E 참고논문: Universal Word Segmentation: Implementation and Interpretation Shao et al. [ACL 2018]
  • 32. 학습 데이터셋 구성 • 학습 데이터셋: 934,278 (전체 90%) • 평가 데이터셋: 103,809 (전체 10%) **검증 데이터셋 은 학습 데이터셋에 10%를 무작위 추출 함
  • 33. 모델 학습 하이퍼파라메터 • Vocab Size & Embedding Dim: 3710 개, 32 • BiLSTM Feature Dim: 64 * 2 • Optimizer: torch.optim.Adam(3e-4) • Batch size: 128 • Limit Sequence Length: 100 • Validation F1 Score가 수렴 될 때까지 학습
  • 34. Baseline 성능 평가 기준 • F1 Score (띄어쓰기 경계 인식 기준) • WER (Word Error Rate) Score • SER (Sentence Error Rate) Score WER 계산 방식
  • 35. Baseline 성능 평가 KoSpacing 경계 인식 방식 영역 인식 방식 F1 Score - 97.71 97.83 WER Score 18.05 12.47 11.91 SER Score 49.77 40.84 39.11
  • 36. False Case 분석 • 복합 명사의 띄어쓰기 문제 예측 문장 정답 문장 초고액 상품권이 빚어낼 사회 심리적 영향을 짚어봐야 한다. 초고액 상품권이 빚어낼 사회심리적 영향을 짚어봐야 한다. 물론 이 일이 실현되려면 과학기술의 측면에서 수많은 장벽을 넘어서야 한다. 물론 이 일이 실현되려면 과학 기술의 측면에서 수많은 장벽을 넘어서야 한다.
  • 37. False Case 분석 • 한 글자 어절의 띄어쓰기 문제 예측 문장 정답 문장 방랑시인 김입은 때 마침 길에서 가난한 농부에게 식사를 대접받았다. 방랑시인 김입은 때마침 길에서 가난한 농부에게 식사를 대접받았다. 승리의 기쁨에 도취된 트로이군은 성안으로 목마를 들여놓고 축제를 벌인다. 승리의 기쁨에 도취된 트로이군은 성 안으로 목마를 들여놓고 축제를 벌인다.
  • 38. 경계 인식 방식 VS 영역 인식 방식 • False Case 를 통해서 두 방식의 차이가 무엇인지 파악하기 어려움 • Labeling 방식 차이가 모델 띄어쓰기 예측에 어떤 영향을 주는가? • 띄어쓰기를 판별하는데 어떤 입력 정보가 가장 영향력이 있는가?
  • 39. Local Interpretable Model-agnostic Explanations (LIME) 알고리즘 분석 • 모델 예측을 할 때 크게 영향을 주는 입력 요소를 찾는 알고리즘 • 모델이 어떻게 예측 했는지 입력 데이터를 통해 시각적으로 표현 LIME 알고리즘 분석 예시 참고링크: https://dreamgonfly.github.io/2017/11/05/LIME.html
  • 40. 안 녕 하 세 요 저 _ 홍 길 동 입 니 다 안 녕 하 세 요 _ 는 홍 길 _ 입 니 다 안 녕 하 _ 요 저 는 홍 길 동 입 니 다 안 녕 _ _ 요 저 는 홍 _ _ 입 니 다 띄어쓰기 모델에서 LIME 알고리즘 활용 • ‘홍’ 이란 어절을 띄어쓰기를 하는데 어느 음절 토큰이 얼마나 기여하는가? 안녕하세요저는홍길동입니다 ➔ 안녕하세요 저는 홍길동입니다 띄어쓰기: 0.2 띄어쓰기: 0.5 띄어쓰기: 0.8 띄어쓰기: 0.7
  • 41. LIME을 통한 띄어쓰기 모델 분석 • 경계 인식 모델 띄어 쓰기 전 토큰의 영향을 많이 받음 • 영역 인식 모델 띄어 쓰는 지점 주변 토큰의 영향을 고르게 받음 • 상대적으로 “입력 정보를 편향적으로 받지 않는” 점이 좋은 띄어쓰기 예측하는 것으로 보임 경계 인식 모델 분석 영역 인식 모델 분석 입력: 안녕하세요저는홍길동입니다 출력: 안녕하세요 저는 홍길동입니다
  • 43. Transformer Network • Self Attention 기법으로 시퀀스 정보들 간의 관계를 학습 • Multi-head Attention 으로 다양한 관점에서 시퀀스 관계를 볼 수 있도록 함 Transformer EncoderSelf Attention 참고링크: http://jalammar.github.io/illustrated-transformer/
  • 44. Korean BERT (ETRI ver.) • Transformer Encoder로 구성된 모델 • 한국어 텍스트 데이터를 Semi-Unsupervised Learning 하여 언어 모델로 학습 • Fine-tuning 만으로 여러 NLP Task에서 좋은 성능을 보임 ETRI Korean BERT 참고링크: http://jalammar.github.io/illustrated-bert/
  • 45. Korean BERT 구현 - Initialize import torch.nn as nn from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel class BertTagger(BertPreTrainedModel): def __init__(self, config, tag_size, pad_idx=0, cls_idx=2): super(BertTagger, self).__init__(config) self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size self.bert = BertModel(config) self.dense = nn.Linear(config.hidden_size, config.hidden_size) self.activation = nn.Tanh() self.dense_2 = nn.Linear(config.hidden_size, tag_size) self.ce_loss = nn.CrossEntropyLoss(reduction='none') BERT Layer
  • 46. Korean BERT 구현 - Initialize import torch.nn as nn from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel class BertTagger(BertPreTrainedModel): def __init__(self, config, tag_size, pad_idx=0, cls_idx=2): super(BertTagger, self).__init__(config) self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size self.bert = BertModel(config) self.dense = nn.Linear(config.hidden_size, config.hidden_size) self.activation = nn.Tanh() self.dense_2 = nn.Linear(config.hidden_size, tag_size) self.ce_loss = nn.CrossEntropyLoss(reduction='none') Dense Layer
  • 47. Korean BERT 구현 - Inference class BertTagger(BertPreTrainedModel): def forward(self, x: torch.Tensor): batch_size = x.size(0) cls_mark = torch.full((batch_size, 1), self._cls_idx).to(self.device) x = torch.cat([x, cls_mark], dim=-1) masking = x.ne(self._pad_idx) encoder_layer, _ = self.bert(x, attention_mask=masking, output_all_encoded_layers=False) dense_layer = self.activation(self.dense(encoder_layer [:, 1:])) emissions = nn.functional.softmax(self.dense_2(dense_layer), dim=-1) path = torch.argmax(emissions, dim=-1) return path BERT 모델 입력값 준비 Masking
  • 48. Korean BERT 성능 결과 KoSpacing BiLSTM-CRF (영역) KoBERT (3 Layers) KoBERT (6 Layers) F1 Score - 97.83 98.62 98.70 WER Score 18.05 11.91 8.08 7.63 SER Score 49.77 39.11 30.24 28.65
  • 49. Korean BERT 처리 속도 비교 length BiLSTM-CRF (영역) 15 0.004 (± 0.001) 50 0.014 (± 0.001) 100 0.03 (± 0.001) KoBERT (3 Layers) 0.018 (± 0.003) 0.038 (± 0.002) 0.073 (± 0.003) KoBERT (6 Layers) 0.035 (± 0.003) 0.076 (± 0.003) 0.141 (± 0.003) *처리속도 (1건 당 sec) - CPU model: AMD Ryzen 7 1700 8-core. - RAM: 64GB
  • 51. 정리 • 수집 데이터를 활용한 띄어쓰기 프로그램 개발 (세종 코퍼스 데이터셋으로 검증) • 학습한 모델이 모든 범주에 대한 띄어쓰기를 잘 할 수 있지는 않음 • 띄어 쓴 정보를 수용할 수 있는 공백 정보 반영 학습을 적용해 볼 필요 있음 • 가급적 띄어쓰기가 잘 된 데이터를 많이 학습해 볼 것
  • 53. TaKos(Train-able Korean spacing) Project • 데이터 학습 가능한 띄어쓰기 알고리즘을 만들기 위한 프로젝트 • Github에서 TaKos 프로젝트를 다운로드 • 프로젝트 내에서 명령어 실행 pip install -r requirements python setup.py install TaKos Project Repo: github.com/Taekyoon/takos-alpha
  • 54. TaKos(Train-able Korean spacing) Project • 띄어쓰기 데이터만 주어지면 모델 학습하여 제공 # 간단하게 띄어쓰기 모델을 만들어 봅시다 from takos.agents.word_segment import WordSegmentAgent spacing_agent = WordSegmentAgent('your_config.json’) spacing_agent.train() spacing_agent.eval() spacing_agent('학교종이땡땡땡') { ....... "dataset": { "name": "your_dataset", "train": { "input":"./samples/train.txt" }, "test": { "input": "./samples/test.txt" } } ....... }
  • 55. Q & A
  • 57. 띄어쓰기로 인한 문제 (추가-1) • 띄어쓰기를 잘못하면 토큰 인덱싱에서 어려워짐 # BertTokenizer or WordPiece case (ETRI Bert) tokenizer = BertTokenizer.from_pretrained('vocab.korean.rawtext.list’) tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무 기대 안하고 갔나’) >>> [1051, 5132, 129, 58, 1976, 230] tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무기대 안하고갔나’)) >>> [567, 69, 5132, 129, 660, 1976, 230] # 띄어쓰기에 따라 변환된 인덱스 값이 다름
  • 58. 띄어쓰기가 필요한 문제 (추가-2) • Speech to Text Case (Google Speech API) “콜라는_하나만_가져_주_셔도_될_것_같_아요_여기_위치는_올림픽_공원_평화의 문_부분이고요 _만나서_결제할게요”
  • 59. • configs.json { "type": "word_segment", "gpu_device": 0, "dataset": { "name": "sejong_spacing", "train": { "bi_tags_only": false, "vocab_min_freq": 10, "input": "train.txt"}, "test": { "limit_len": 150, "input": "test.txt"} }, "deploy": { "path": "./tmp/test_model"}, "model": { "type": "bilstm_crf", "parameters": { "word_embedding_dims": 32, "hidden_dims": 64} }, "train": { "epochs": 50, "eval_steps": 1000, "eval_batch_size": 512, "batch_size": 128, "sequence_length": 100 } 띄어쓰기 프로그램 설정 구성
  • 60. 띄어쓰기 프로그램 실행 구현 def run(self, query): prepro_query = self.preprocess(query) tokenized_query = self.tokenizer.tokenize(prepro_query).split() model_inputs = torch.Tensor([self.vocab.to_indices(tokenized_query)]) pred_score, tag_seq = self.model(model_inputs) labeled_tag_seq = self.label.to_tokens(tag_seq[0].tolist()) post_processed = self.postprocess(prepro_query, labeled_tag_seq) outputs = {'output': post_processed} return outputs 입력 텍스트 전처리 띄어쓰기 처리
  • 61. 띄어쓰기 모델 학습 구현 def train(self): train_configs = self.configs['train'] train_dataset_configs = self.configs['dataset']['train'] data_builder = create_builder(self.task_type, train_dataset_configs) model = create_model(self.task_type, tag_to_idx, self.model_configs) trainer = create_trainer(self.task_type, model, data_builder, train_configs) trainer.train() 기능 수행을 위한 객체 생성
  • 62. 띄어쓰기 모델 평가 구현 def eval(self): test_dataset_configs = self.configs['dataset']['test'] train_dataset_configs = self.configs['dataset']['train'] data_builder = create_builder(self.task_type, train_dataset_configs) evaluator = create_evaluator(self.task_type, self.model, data_builder, test_dataset_configs, limit_len) evaluator.eval() logger.info(evaluator.summary()) 기능 수행을 위한 객체 생성
  • 63. 모델 개발에 활용한 리서치 자료 • PyKoSpacing • 2018년 HCLT 학술대회에 나온 논문들 • 문장 정보를 고려한 딥러닝 기반 자동 띄어쓰기의 개념 및 활용 • 띄어쓰기 및 문장 경계 인식을 위한 다중 손실 선형 결합 기반의 다중 클래스 분류 시스템 • CRFs와 Bi-LSTM/CRFs의 비교 분석: 자동 띄어쓰기 관점에서 • 자동띄어쓰기 오류 수정 및 복합명사 분해 개요: 2018 차세정 언어처리 경진대회
  • 64. False Case 분석 (추가) • 그 외 띄어쓰기 문제 예측 문장 정답 문장 소독용에 탄 올 스프레이를 수시로 뿌린다. 소독용 에탄올 스프레이를 수시로 뿌린다. 주말쯤 작전이 시작될 것이라고 미국 방부 및 나토 의미 관계자들이 23일 밝혔다. 주말쯤 작전이 시작될 것이라고 미 국방부 및 나토의 미 관계자들이 23일 밝혔다.
  • 65. LIME을 통한 띄어쓰기 모델 분석 (추가) 경계 인식 모델 분석 영역 인식 모델 분석 입력: 세종대왕께서한글을창조하셨다 출력: 세종대왕께서 한글을 창조하셨다 경계 인식 모델 분석 영역 인식 모델 분석 입력: 세종대왕께서한글을창조하셨다 출력: 세종대왕께서 한글을 창조하셨다