rueki

텍스트 전처리 - 단어 분리(Subword Segmentation) 본문

DL/NLP

텍스트 전처리 - 단어 분리(Subword Segmentation)

륵기 2019. 7. 1. 16:10

본문은 https://wikidocs.net/22592 를 참고해서 작성한 글입니다.

 

머신 러닝을 이용한 자연어 처리의 목표는 기계가 사람만큼, 또는 사람 이상의 성능을 내길 기대하는 것이다.

그러나 기계에게 모든 단어를 다 알려주고 원하는 결과를 기대하기에는 무리이다.

그래서 단어 분리는 기계가 아직 배운적 없는 단어라도 배운 것처럼 대처할 수 있도록 도와주는 방법이다.

기계 번역 등, 주요 전처리로 사용되고 있다.

 

기계가 알고있는 단어들의 집합을 Vocabulary(단어 집합)이라고 한다.

기계가 못 배운 단어들은 OOV(Out Of Vocabulary) 또는 UNK(Unknwon word)라고 한다.

 

왜 단어 분리를 하는가?

단어분리(Subword Segmentation)는 단어를 여러 단어로 분리하겠다라는 작업을 나타낸다.

하나의 단어는 여러 단어들의 조합으로 구성된 경우가 많기때문에, 어느정도 나누는 것이 괜찮다.


WPM(Word Piece model)

WPM은 하나의 단어를 내부 단어(Subword Unit)들로 분리하는 단어 분리 모델이다.

참고 논문 - 구글번역기에서 WPM이 어떻게 수행되는지

(Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation [Wo at el.2016])

 

WPM을 수행하기 이전의 문장: Jet makers feud over seat width with big orders at stake
WPM을 수행한 결과(wordpieces):_J et _makers _fe ud _over _seat _width _with _big _orders _at _stake

 

띄어쓰기는 언더바로 치환하고, 단어는 내부단어로 통계기반하여 띄어쓰기로 분리한다.

언더바 사용 이유는 차후의 문장 복원을 위함이다.

복원하는 방법은 띄어쓰기를 다없애고, 언더바는 띄어쓰기로 바꾸면 된다.


BPE(Byte Pair Encoding)

대표적인 단어 분리 방업으로서 구글의 WPM에는 BPE 알고리즘이 사용되었다.

참고 논문 - Neural Machine Translation of Rare Words with Subword Units [Sennrich at el.2015]

 

자연어 처리를 위한 주요 전처리 방법으로 사용되고 있다.

import re, collections

def get_stats(vocab):
    pairs = collections.defaultdict(int)
    for word, freq in vocab.items():
        symbols = word.split()
        for i in range(len(symbols)-1):
            pairs[symbols[i],symbols[i+1]] += freq
    return pairs

def merge_vocab(pair, v_in):
    v_out = {}
    bigram = re.escape(' '.join(pair))
    p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)')
    for word in v_in:
        w_out = p.sub(''.join(pair), word)
        v_out[w_out] = v_in[word]
    return v_out

vocab = {'l o w </w>' : 5,
         'l o w e r </w>' : 2,
         'n e w e s t </w>':6,
         'w i d e s t </w>':3
         }

num_merges = 10

for i in range(num_merges):
    pairs = get_stats(vocab)
    best = max(pairs, key=pairs.get)
    vocab = merge_vocab(best, vocab)
    print(best)

논문의 예제 코드이다.

BPE는 가장 많이 등장한 문자열에 대하여 병합하는 작업을 반복하며, 원하는 단어 집합의 크기,

즉 단어의 갯수가 될 때까지 반복한다.

Comments