Natural Language Processing with PyTorch
  • 소개글
  • 서문
  • Index
  • 딥러닝을 활용한 자연어 처리 개요
    • 자연어 처리란 무엇일까?
    • 딥러닝 소개
    • 왜 자연어 처리는 어려울까?
    • 무엇이 한국어 자연어 처리를 더욱 어렵게 만들까?
    • 자연어 처리의 최근 추세
  • 기초 수학
    • 서문
    • 랜덤 변수와 확률 분포
    • 쉬어가기: 몬티 홀 문제
    • 기대값과 샘플링
    • Maximum Likelihood Estimation
    • 정보 이론
    • 쉬어가기: MSE 손실 함수와 확률 분포 함수
    • 마치며
  • Hello 파이토치
    • 딥러닝을 시작하기 전에
    • 설치 방법
    • 짧은 튜토리얼
    • 쉬어가기: 윈도우즈 개발 환경 구축
  • 전처리
    • 전처리란
    • 코퍼스 수집
    • 코퍼스 정제
    • 분절
    • 병렬 코퍼스 정렬
    • 서브워드 분절
    • 분절 복원
    • 토치텍스트
  • 유사성과 모호성
    • 단어의 의미
    • One-hot 인코딩
    • 시소러스를 활용한 단어 의미 파악
    • 특징
    • 특징 추출하기: TF-IDF
    • 특징 벡터 만들기
    • 특징 유사도 구하기
    • 단어 중의성 해소
    • Selectional Preference
    • 마치며
  • 단어 임베딩
    • 들어가며
    • 차원 축소
    • 흔한 오해 1
    • Word2Vec
    • GloVe
    • Word2Vec 예제
    • 마치며
  • 시퀀스 모델링
    • 들어가며
    • Recurrent Neural Network
    • Long Short Term Memory
    • Gated Recurrent Unit
    • 그래디언트 클리핑
    • 마치며
  • 텍스트 분류
    • 들어가기
    • 나이브 베이즈를 활용하기
    • 흔한 오해 2
    • RNN을 활용하기
    • CNN을 활용하기
    • 쉬어가기: 멀티 레이블 분류
    • 마치며
  • 언어 모델링
    • 들어가며
    • n-gram
    • 언어 모델의 평가 방법
    • SRILM을 활용한 n-gram 실습
    • NNLM
    • 언어 모델의 활용
    • 마치며
  • 신경망 기계번역
    • 들어가며
    • Sequence-to-Sequence
    • Attention
    • Input Feeding
    • 자기회귀 속성과 Teacher Forcing 훈련 방법
    • 탐색(추론)
    • 성능 평가
    • 마치며
  • 신경망 기계번역 심화 주제
    • 다국어 신경망 번역
    • 단일 언어 코퍼스를 활용하기
    • 트랜스포머
    • 마치며
  • 강화학습을 활용한 자연어 생성
    • 들어가며
    • 강화학습 기초
    • 정책 기반 강화학습
    • 자연어 생성에 강화학습 적용하기
    • 강화학습을 활용한 지도학습
    • 강화학습을 활용한 비지도학습
    • 마치며
  • 듀얼리티 활용
    • 들어가며
    • 듀얼리티를 활용한 지도학습
    • 듀얼리티를 활용한 비지도학습
    • 쉬어가기: Back-translation을 재해석하기
    • 마치며
  • NMT 시스템 구축
    • 파이프라인
    • 구글의 NMT
    • 에딘버러 대학의 NMT
    • MS의 NMT
  • 전이학습
    • 전이학습이란?
    • 기존의 사전 훈련 방식
    • ELMo
    • BERT
    • GPT-2
    • XLNet
    • 마치며
  • 이 책을 마치며
  • 참고문헌
Powered by GitBook
On this page
  • 분절 후처리
  • 분절 복원 예제
  1. 전처리

분절 복원

다음은 전처리 과정에서 분절을 수행하고, 다시 분절 복원detokenization하는 과정을 설명한 것입니다. 하나씩 따라가보겠습니다. 다음과 같은 영어 원문이 주어졌다고 가정합니다.

Natural language processing is one of biggest streams in artificial intelligence, and it becomes very popular after seq2seq's invention.

언어별 분절기 모듈(영어의 경우 NLTK)을 통해 분절을 수행하고, 기존 띄어쓰기와 새롭게 분절기에 의해 만들어진 공백을 구분하기 위해 특수 문자 ''를 원래의 공백 위치에 삽입합니다. 다만 이 '' 문자는 기존의 '_'와 다른 문자로 특수기호입니다.

▁Natural ▁language ▁processing ▁is ▁one ▁of ▁biggest ▁streams ▁in ▁artificial ▁intelligence , ▁and ▁it ▁becomes ▁very ▁popular ▁after ▁seq2seq 's ▁invention .

여기에 서브워드 단위 분절을 수행하며 이전 과정까지의 공백과 서브워드 단위 분절로 인한 공백을 구분하기 위한 특수 문자 '_'를 삽입합니다.

▁▁Natural ▁▁language ▁▁processing ▁▁is ▁▁one ▁▁of ▁▁biggest ▁▁streams ▁▁in ▁▁artificial ▁▁intelligence ▁, ▁▁and ▁▁it ▁▁becomes ▁▁very ▁▁popular ▁▁after ▁▁se q 2 se q ▁'s ▁▁invention ▁.

이렇게 전처리 과정이 종료되었습니다. 이런 형태의 분절된 문장을 자연어 처리 모델에 훈련시키면 똑같은 형태로 분절된 문장을 생성해낼 것입니다. 그럼 이런 문장을 분절 복원하여 사람이 읽기 좋은 형태로 만들어주어야 합니다.

먼저 공백을 제거합니다.

▁▁Natural▁▁language▁▁processing▁▁is▁▁one▁▁of▁▁biggest▁▁streams▁▁in▁▁artificial▁▁intelligence▁,▁▁and▁▁it▁▁becomes▁▁very▁▁popular▁▁after▁▁seq2seq▁'s▁▁invention▁.

그리고 특수 문자 ''가 2개가 동시에 있는 문자열 '__'을 공백으로 치환합니다. 그럼 한 개 짜리 ''만 남습니다.

 Natural language processing is one of biggest streams in artificial intelligence▁, and it becomes very popular after seq2seq▁'s invention▁.

마지막 남은 특수 문자 '_'를 제거합니다. 그럼 문장 복원이 완성됩니다.

Natural language processing is one of biggest streams in artificial intelligence, and it becomes very popular after seq2seq's invention.

분절 후처리

앞의 예제에서처럼 분절에 대한 복원을 수월하게 하기 위해, 분절 이후에는 특수 문자를 분절 과정에서 새롭게 생긴 공백 다음에 삽입해야 합니다. 다음은 기존의 공백과 전처리 단계에서 생성된 공백을 서로 구분하기 위한 특수 문자 '_'을 삽입하는 파이썬 스크립트 예제입니다.

import sys

STR = '▁'

if __name__ == "__main__":
    ref_fn = sys.argv[1]

    f = open(ref_fn, 'r')

    for ref in f:
        ref_tokens = ref.strip().split(' ')
        input_line = sys.stdin.readline().strip()

        if input_line != "":
            tokens = input_line.split(' ')

            idx = 0
            buf = []

            # We assume that stdin has more tokens than reference input.
            for ref_token in ref_tokens:
                tmp_buf = []

                while idx < len(tokens):
                    if tokens[idx].strip() == '':
                        idx += 1
                        continue

                    tmp_buf += [tokens[idx]]
                    idx += 1

                    if ''.join(tmp_buf) == ref_token:
                        break

                if len(tmp_buf) > 0:
                    buf += [STR + tmp_buf[0].strip()] + tmp_buf[1:]

            sys.stdout.write(' '.join(buf) + '\n')
        else:
            sys.stdout.write('\n')

    f.close()

이 스크립트의 사용 방법은 다음과 같습니다. 주로 다른 분절 모듈의 수행 후에 파이프pipe를 사용하여 붙여서 사용합니다.

$ cat [before filename] | python tokenizer.py | python post_tokenize.py [before filename]

분절 복원 예제

다음은 앞서 설명한 분절 복원을 sed 명령어를 통해 수행할 경우의 예제입니다.

sed "s/ //g" | sed "s/▁▁/ /g" | sed "s/▁//g" | sed "s/^\s//g"

또는 다음의 파이썬 스크립트 예제처럼 처리할 수도 있습니다.

import sys

if __name__ == "__main__":
    for line in sys.stdin:
        if line.strip() != "":
            if '▁▁' in line:
                line = line.strip().replace(' ', '').replace('▁▁', ' ').replace('▁', '').strip()
            else:
                line = line.strip().replace(' ', '').replace('▁', ' ').strip()

            sys.stdout.write(line + '\n')
        else:
            sys.stdout.write('\n')
Previous서브워드 분절Next토치텍스트

Last updated 5 years ago