Part of speech tagging, Tokenization, and Out of vocabulary problem

텍스트 데이터 분석을 위하여 우리는 문장을 단어나 토큰으로 분리합니다. 텍스트 분석의 단위는 단어, 구문, 문장, 문서가 될 수 있습니다. 문서/문장은 분리된 토큰을 이용하여 tf 나 tfidf 와 같은 one hot representation 과 doc2vec 과 같은 distributed representation 의 벡터로 표현합니다. 연관어 분석이나 토픽모델링은 문장에서 나뉘어진 단어의 co-occurrence 정보를 이용합니다. 이들은 모두 모두 문장을 단어나 토큰으로 잘 분리되었다고 가정합니다. 여기서 잘 분리된 토큰은 분석의 대상과 목적에 따라 정의가 다릅니다. 이번 포스트에서는 한국어 텍스트 데이터를 단어나 토큰으로 만드는 과정에 대하여 논의합니다. 미등록단어 (out of vocabulary) 문제의 원인과 해결 방향에 대해 이야기합니다.

Tokenization, Part of speech tagging, Morphological analysis?

토크나이징 (tokenization) 은 주어진 문장을 토큰 (tokens) 으로 나누는 과정입니다. 토큰은 상황에 따라 다르게 정의할 수 있습니다. 띄어쓰기를 기준으로 문장을 나눌 수도 있습니다. 영어는 띄어쓰기를 기준으로 문장을 나눠도 단어열로 나뉘어집니다.

sent = '너무너무너무는 아이오아이의 노래입니다'
tokens = ['너무너무너무는', '아이오아이의', '노래입니다']

sent = 'Very-very-very is song of I.O.I'
tokens = ['Very-very-very', 'is', 'song', 'of', 'I.O.I']

한국어에서 띄어쓰기 기준으로 나뉘어지는 단위는 ‘어절’ 입니다. 어절은 한 개 이상의 단어, 혹은 형태소로 구성될 수 있습니다. 그렇기 때문에 ‘너무너무너무는’, ‘너무너무너무가’ 처럼 같은 단어를 포함함에도 서로 다른 형태의 어절이 등장할 수 있습니다. 또한 띄어쓰기 기준으로 토큰을 나누면 띄어쓰기 오류에 취약합니다. 핸드폰으로 입력되는 텍스트들에서는 띄어쓰기가 잘 지켜지지 않는 경우들이 많습니다. 여러 이유로 한국어 텍스트를 띄어쓰기 기준으로 나누는 것은 좋지 않습니다.

품사 판별 (part of speech tagging)은 토큰을 (단어, 품사)로 정의합니다. 아래처럼 각 단어가 품사와 함께 분리되야 합니다.

tokens = [
    ('너무너무너무', '명사'),
    ('는', '조사'),
    ('아이오아이', '명사'),
    ('의', '조사'),
    ('노래', '명사'),
    ('입니다', '형용사')
]

한국어의 품사 체계는 5언 9품사로 구성되어 있습니다. 다른 단어들은 형태가 변하지 않습니다. 하지만 동사, 형용사인 용언은 형태가 변합니다. 이를 ‘용언의 활용’ 이라 합니다. ‘이다’ 라는 형용사는 ‘이고, 이니까, 이었다’ 처럼 본래의 의미는 같지만 형태가 변합니다. 이때 의미를 지니는 부분을 어근 (root), 형태가 변하는 부분을 어미 (ending) 이라 합니다. ‘이었다 = 이/어근 + 었다/어미’ 입니다. ‘이었다’는 형용사로 단어이지만, ‘이/어근’, ‘었다/어미’는 단어가 아닙니다. 이들을 형태소라 합니다.

품사
체언 명사, 대명사, 수사
수식언 관형사, 부사
관계언 조사
독립언 감탄사
용언 동사, 형용사

형태소 분석은 (morphological analysis) 품사 판별과 자주 혼동되는 개념입니다. 형태소란 의미를 지니는 최소 단위로, (1) 자립형태소 / 의존형태소 로 나뉘기도 하며, (2) 실질형태소와 형식형태소로 나뉘기도 합니다.

자립성을 기준으로 형태소를 분리할 때에는 체언, 수식언, 독립언처럼 그 자체로 단어로 이용될 수 있는 모든 단어는 단어이면서 자립형태소입니다. 하지만 어근, 어미, 조사처럼 다른 형태소와 함께 하나의 단어를 형성하는 형태소를 의존형태소라 합니다.

실질형태소는 그 자체가 의미를 지니는 것이며, 형식형태소는 문법기능을 하는 형태소입니다. 어미, 조사가 이에 해당합니다.

저는 형태소와 단어를 구분할 때 가장 햇갈렸던 것이 조사였습니다. 조사는 독립적이지도 못하고 의미도 지니지 않는 문법기능을 하는 단위이지만, 단어에 포함됩니다. 그래서 그 경계를 받아들이는데 힘들었습니다. 물론 이 정의는 국문법의 정의입니다. 데이터처리의 관점에서는 의미 부분과 문법기능 부분만 분리하면 됩니다. 이것만 제대로 된다면 의미부분만을 추릴 수 있고 (어절에서 명사+조사를 분리), 같은 의미를 지니는 단어들을 하나의 형태로 통합 (어근+어미를 원형으로 복원: 이었다 -> 이다) 할 수 있기 때문입니다.

형태소 분석은 품사 판별의 수단이 될 수 있습니다. 하지만 반드시 품사 판별을 위하여 형태소 분석을 해야하는 것은 아닙니다. ‘이었다’ 의 경우, ‘-었다’가 어미이고, ‘이-‘가 어근임을 파악한 뒤, ‘이었다/형용사’로 판단할 수도 있습니다. 하지만 형용사 사전에 ‘이었다/형용사’가 포함되어 있으면 사전기반으로 이를 인식할 수 있습니다.

Out of vocabulary problem

형태소 분석이나 품사 판별을 위해서는 사전과 문법이 필요합니다. ‘아이오아이는’ 이라는 어절이 ‘아이오아이는 = 아이오아이/명사 + 는/조사’ 라는 규칙을 알고 있지 않더라도 다음과 같은 사전과 문법 규칙을 지니고 있다면, ‘아이오아이는’ 이라는 어절을 인식할 수 있습니다.

dictionary = {
	'명사': {'아이오아이', '아이', '오'},
	'조사': {'는'}
}

pattern = [('명사', '조사'), ('명사',)]

그러나 말은 언제나 변화합니다. 새로운 개념을 설명하기 위해 새로운 단어가 만들어지기 때문에 모든 단어를 포함하는 사전은 존재할 수 없습니다. KoNLPy (ver 0.4.4) 의 트위터 분석기를 이용하여 다음 문장의 품사 판별을 수행하였습니다.

from konlpy.tag import Twitter

twitter = Twitter()
twitter.pos('너무너무너무는 아이오아이의 노래입니다')

일단 두 가지 큰 문제가 보입니다. ‘너무너무너무’가 ‘너무 + 너무 + 너무’로 나뉘어졌습니다. ‘아이오아이’는 ‘아이오 + 아이’로 나뉘어졌습니다. 트위터분석기에 ‘너무’, ‘아이오’, ‘아이’는 명사 사전에 등록이 되었지만, ‘너무너무너무’, ‘아이오아이’는 명사 사전에 존재하지 않기 때문입니다. KoNLPy 에 Twitter 분석기가 포함될 때에는 아이오아이라는 그룹이 존재하지 않았거든요.

[('너무', 'Noun'),
 ('너무', 'Noun'),
 ('너무', 'Noun'),
 ('는', 'Josa'),
 ('아이오', 'Noun'),
 ('아이', 'Noun'),
 ('의', 'Josa'),
 ('노래', 'Noun'),
 ('입니', 'Adjective'),
 ('다', 'Eomi')]

또한 미등록단어 문제들은 주로 하나의 단어가 여러 개의 잘못된 단어로 나뉘어지는 형태로 발생합니다. 형태소 분석기, 품사 판별기는 학습 데이터를 바탕으로 주어진 문장을 이해합니다. 위와 같은 결과가 나온 이유는 학습 데이터를 이용한 모델에서 score(‘너무너무너무/unknown’ + ‘는/Josa’) < score(‘너무/Noun + 너무/Noun + 너무/Noun + 는/Josa’) 이기 때문입니다. 즉 학습데이터에서 보지 못했던 단어를 모르는 단어로 인식하는 것보다 아는 단어의 조합으로 나누는 것을 더 선호하기 떄문입니다.

이렇게 설계된 이유 중 하나는, KoNLPy 에 등록된 방법론들이 대부분 품사 판별기가 아닌 형태소 분석기이기 때문입니다. 각 엔진의 full name 입니다. 트위터 외의 모든 엔진은 분석기 입니다. Twitter 의 경우, 트위터의 hash tag 와 같은 국문법이 정의한 단어 이외의 다른 종류의 단어들을 포함하기 때문에 한국어 처리기라고 이름을 붙이지 않았을까 생각했습니다 (사견입니다).

Hannanum: 한나눔 형태소 분석기
Kkma: 꼬꼬마 형태소 분석기 (Kind Korean Moorpheme Analyzer)
Komoran: 코모란 한국어 형태소 분석기
Mecab: mecab-ko 형태소 분석기
Twitter: 트위터 한국어 처리기

형태소 분석기의 목표는 단어를 형태소로 분해하는 것입니다. 그리고 형태소 분석을 통하여 품사 판별을 할 때의 가정 중 하나는 이전에 없던 형태소의 결합으로 신조어도 만들 수 있다는 점입니다. 예를 들어 ‘신/관형사’, ‘메뉴/명사’ 를 사전에 알고 있고, ‘관형사 + 명사 -> 명사’라는 규칙을 안다면 ‘신메뉴’를 명사로 인식할 수 있습니다.

사전: {신/관형사, 메뉴/명사}
형태소규칙: '관형사 + 명사 -> 명사'

pos('신메뉴') = morpheme(신/관형사 + 메뉴/명사) = '명사'

형태소 분석기는 단어를 분해하여 단어를 구성하는 요소들을 인식하려 합니다. 애초에 단일 형태소가 아닌 단어는 복합 형태소라 가정을 하였기 때문에 이를 분해하여 아는 형태소들로 인식하려 하는 경향이 있습니다.

이처럼 미등록단어 문제는 언제나 발생합니다. 그렇기 때문에 많은 형태소 분석기 / 품사 판별기는 사용자 사전을 추가할 수 있는 기능을 제공합니다.

그러나 분석가가 잘 아는 도메인이 아니라면, 분석 전에 어떤 단어들이 데이터에 존재하는지 예상하기는 어렵습니다. 그런데 데이터 분석을 하려면 형태소 분석이나 품사 판별을 수행해야 합니다. 닭과 달걀의 문제입니다.

Ambiguity in tokenization

미등록단어 문제와 비슷한 문제가 또 있습니다. 누가 했던 말인지는 모르지만, 텍스트 데이터를 다루는 사람이라며 누구라도 할 수 있는 말입니다. ‘텍스트분석, 자연어처리는 처음부터 끝까지 모호성과의 싸움‘입니다.

다음과 같은 사전을 가지고 있을 경우 ‘서울대공원에서’는 어떻게 인식되어야 할까요?

{
	'명사': {'서울', '서울대', '공원', '대공원'},
	'조사': {'에서'}
}

‘서울대/명사 + 공원/명사 + 에서/조사’도 가능하며, ‘서울/명사 + 대공원/명사 + 에서/조사’도 가능합니다.

형태소 분석기, 품사 판별기는 학습데이터를 바탕으로 가능한 여러 개우 후보 중에서 가장 가능성이 높은 후보를 최종 결과로 선택합니다. 만약 학습된 모델의 P(서울대 + 공원) > P(서울 + 대공원) 이었다면, 해당 어절은 ‘서울대 + 공원 + 에서’로 나뉘어질 것입니다. 설령 해당 문서가 어린이날 행사와 관련된 문서였더라도요.

학습 데이터의 도메인과 우리가 분석할 데이터의 도메인은 다를 가능성이 높습니다. 학습된 지식만을 이용하여 우리의 데이터를 분석하는 것은 ‘학습 데이터의 시선으로 우리의 데이터를 재단하는 것’입니다. 가르쳐 준대로만 행동합니다. 가르쳐 주지 않은 것도 스스로 배울 수 있으면 더 좋을 것입니다. 그렇기 때문에 우리에게 필요한 모델은 학습 데이터와 적용할 데이터 간의 차이를 이해하고, 이를 스스로에게 반영할 수 있는 모델입니다.

Needs for unsupervised word extractions

‘우리가 분석해야 할 데이터를 이해한다’라는 말의 의미는 P(서울대 + 공원), P(서울 + 대공원) 의 확률을 계산하는 모델의 패러메터를 조절하는 것만 의미하는 것이 아닙니다. 사전에 없는 단어들도 분석할 데이터에서 스스로 학습할 수 있어야 한다는 의미입니다.

한 가지 다행인 점은 모든 품사에서 새로운 단어가 만들어지는 것은 아니라는 것입니다. 일단 명사는 새로운 단어가 자주 만들어짐을 압니다. 이는 새로운 개념이 만들어지기 때문입니다. 새로운 사건, 새로운 사람을 지칭하기 위하여 명사가 만들어집니다.

하지만 조사는 새롭게 만들어지지 않습니다. 조사는 문법 기능을 담당하기 때문입니다. 문법은 규칙이며, 규칙이 바뀔 때에는 이를 이용하는 사람들 간의 합의가 필요합니다. 그렇기 때문에 조사와 같은 문법이 변하는데는 긴 시간이 필요합니다.

새로운 어미도 만들어집니다. 말투 때문입니다. ‘저녁 이제 먹을라궁’ 처럼 대화체에서는 ‘-을라궁’ 처럼 다양한 어미가 만들어지기도 합니다. 일단 어떤 품사에서 새로운 단어가 만들어지는지를 파악해야 그 방법을 설계할 수 있습니다.

규칙 기반의 방법이 새로운 단어를 인식하는데 이용될 수도 있습니다만, 이는 매우 위험한 접근입니다. ‘-은/조사’는 명사 뒤에 등장합니다. 이 규칙을 이용하여 ‘-은’ 앞을 명사라고 생각할 수도 있습니다. 그러나 에이핑크의 ‘손나은’ 은 ‘손나/명사 + 은/조사’가 아닙니다. 한국어 텍스트에 자주 이용되는 글자수는 1천자가 되지 않습니다. 뉴스와 같은 텍스트에서는 300 자 정도로 99 % 이상의 단어가 기술됩니다. ‘은’으로 끝나는 수 많은 명사가 존재합니다.

다른 해결 방법으로 통계를 이용한 단어 추출 방법들이 있습니다. 단어의 경계에는 특징이 있습니다. 예를 들어 ‘손나은’ 다음에 등장하는 글자는 ‘손나은 + 은’, ‘손나은 + 이’, ‘손나은 + 의’ 처럼 다양합니다. 또한 연예 뉴스에서는 ‘손나은’ 이라는 세글자는 자주 등장합니다. 그렇기 때문에 ‘손나’라는 두 단어 다음에 등장할 글자는 ‘은’으로 예상이 됩니다. 하지만 ‘손나은’ 다음에 등장할 글자는 모두가 다르게 예상할 것입니다. 이러한 특징을 이용하여 단어를 추출하는 방법들을 이후에 이야기하려 합니다.

  • Left-side subword tokenizer 는 문서 판별 등의 작업에 이용할 수 있는 아주 간단한 토크나이저 입니다.
  • Word piece model 은 out of vocabulary 문제를 우회 (해결이 아닙니다) 하는 토크나이저 입니다.
  • Cohesion score 는 단어의 일부분으로 다른 부분이 얼마나 잘 예상되느냐에 대한 정보를 단어 추출에 이용합니다.
  • KR-WordRank 는 graph ranking 방법을 이용하여 단어를 추출합니다.
  • Branching EntropyAcessor Variety 는 손나은의 오른쪽에 등장하는 글자의 다양성의 정보를 이용합니다.