자연어처리를 위한 형태소 분석기들 중에는 Java 로 구현된 것들이 많습니다. 알고리즘을 Python 으로 옮겨 재구현하지 않고도 Python 환경에서 이를 이용할 수 있습니다. KoNLPy 는 다양한 언어로 구현된 형태소 분석기들을 Python 환경에서 이용할 수 있도록 도와줍니다. 여기에서 Jpype 는 Java 구현체들을 Python 에서 이용할 수 있도록 두 언어를 연결해줍니다. 이전 포스트에서 IPython notebook 의 Python 환경에서 Komoran 을 이용하는 과정을 이야기하였습니다. 이번 포스트에서는 Komoran 3 을 Python package 로 만드는 과정에 대하여 이야기합니다. 특히 JVM starting 과 호환 가능한 데이터 형식에 대하여 이야기합니다.
Conditional Random Field based Named Entity Recognition
Named Entity Recognition (NER) 은 문장에서 특정한 종류의 단어를 찾아내는 information extraction 문제 중 하나입니다. ‘디카프리오가 나온 영화 틀어줘’라는 문장에서 ‘디카프리오’를 사람으로 인식하는 것을 목표로 합니다. 단어열로 표현된 문장에 각 단어의 종류를 인식하는 sequential labeling 방법이 주로 이용되었습니다. 최근에는 Recurrent Neural Network 와 같은 방법도 이용되지만, 오래전부터 Conditional Random Field (CRF) 가 이용되었습니다. 특히 CRF 모델은 named entities 를 판별하는 규칙을 해석할 수 있다는 점에서 유용합니다. 이번 포스트에서는 CoNLL 2002 NER task dataset 에 CRF 를 적용하여 NER 모델을 만드는 과정에 대하여 설명합니다.
한국어 용언의 활용 함수 (Korean conjugation)
한국어의 단어는 9 품사로 이뤄져 있습니다. 그 중 용언에 해당하는 형용사와 동사는 활용 (conjugation) 이 됩니다. 용언은 어간 (stem) 과 어미 (ending) 로 구성되어 있으며, 용언의 원형은 어간의 원형에 종결어미 ‘-다’가 결합된 형태입니다. 예를 들어 ‘하다’라는 동사는 ‘하/어간 + 다/어미’로 구성되어 있습니다. ‘-다’가 ‘-니까’와 같은 다른 어미로 치환되어 ‘하 + 니까’로 동사의 형태가 변할 수 있습니다. 이처럼 어간과 어미의 모양이 변하지 않으면서 어미만 치환되는 활용을 용언의 규칙 활용이라 합니다. 하지만 ‘-았어’ 라는 어미를 ‘하/어간’과 결합하려면 어간의 뒷부분과 어미의 앞부분의 모양이 변합니다. ‘하 + 았어 -> 했어’ 처럼 어간과 어미의 형태가 변하는 경우를 용언의 불규칙 활용이라 합니다. 이번 포스트에서는 어간과 어미의 원형이 주어졌을 때 불규칙 활용이 된 용언을 만드는 conjugate 함수를 구현합니다.
한국어 용언의 원형 복원 (Korean lemmatization)
한국어의 단어는 9 품사로 이뤄져 있습니다. 그 중 용언에 해당하는 형용사와 동사는 활용 (conjugation) 이 됩니다. 용언은 어간 (stem) 과 어미 (ending) 로 구성되어 있으며, 용언의 원형은 어간의 원형에 종결어미 ‘-다’가 결합된 형태입니다. 어미 부분이 다른 어미로 교체되기만 한 활용을 규칙활용이라 합니다. 반면 활용 도중 어간의 뒷부분 혹은 어미의 앞부분의 형태가 변하는 활용을 불규칙 활용이라 합니다. 불규칙 활용은 용언의 형태소 분석을 어렵게 하는 원인 중 하나입니다. 이번 포스트에서는 불규칙 활용의 경우를 유형화하여 어간과 어미의 원형 후보를 만드는 lemmatizer 의 candidate 함수를 구현합니다.
Cherry picking distort distribution.
머신 러닝 모델은 학습데이터로부터 특정한 패턴을 학습합니다. 그리고 학습된 모델의 성능은 테스트 데이터를 이용하여 측정됩니다. 모델의 일반화 성능은 validation dataset 을 이용한 성능 테스트를 통하여 측정됩니다. 우리는 주로 모델의 학습 과정은 training, test dataset 을 이용한 과정으로 정의합니다. 하지만 사실은 validation dataset 을 이용하여 성능이 가장 좋은 “모델을 선택”하는 과정까지도 학습에 포함됩니다. 사실 우리는 cherry picking 을 하고 있습니다. 이번 포스트에서는 모델의 학습 과정에서 우리가 행하는 cherry picking 의 과정과 그 위험성에 대한 선배의 세미나의 내용을 기록하였습니다.
Unsupervised noun extraction (3). Usage of extractor and tokenizer
이전 포스트에서 한국어 어절의 특징인 L + [R] 구조를 이용하여 통계 기반으로 명사를 추출하는 두 가지 방법을 제안하였습니다. Unsupervised noun extraction (2) 는 첫번째 포스트에서 제안되었던 soynlp.noun.LRNounExtractor 의 문제점을 유형화하고 이를 해결한 방법에 대한 포스트입니다. 두번째 포스트의 방법은 soynlp.noun.LRNounExtractor_v2 에 구현되어 있습니다. 명사 추출기의 역할은 명사 리스트를 만드는 것 까지입니다. 그 다음으로 필요한 기능은 주어진 문장들에서 명사를 잘라내는 토크나이징입니다. 이를 위해서 분석할 도메인의 데이터에 포함된 명사 리스트를 만든 뒤, 이를 Komoran 이나 soynlp.pos 와 같은 품사 판별기에 사용자 사전으로 추가할 수도 있습니다. 혹은 우리가 구축한 명사 리스트만을 이용하여 간단한 토크나이저를 만들 수도 있습니다. 이번 포스트에서는 두번째 포스트에서 제안된 명사 추출기를 이용하여 명사 리스트를 만든 뒤, string match 를 이용하여 토크나이징을 하는 과정을 공유합니다.
Unsupervised noun extraction (2). Improving accuracy and recall
이전 포스트에서 한국어 어절의 특징인 L + [R] 구조를 이용하여 통계 기반으로 명사를 추출하는 방법을 제안하였습니다. 통계는 대부분 major pattern 에 유리합니다. 통계적으로 유의할 만큼의 관찰이 없으면 잘못된 판단을 하기 쉽습니다. Unsupervised algorithms 는 exception 을 잘 처리할 수 있는 탄탄한 논리가 필요합니다. 이번 포스트에서는 이전 포스트의 명사 추출 방법이 잘못된 판단을 할 수 있는 위험 요소들을 살펴보고 이를 해결하는 방법들을 소개합니다.
Unsupervised noun extraction. L-R structure
한국어는 5언 9 품사로 이뤄져 있습니다. 그 중 한국어로 이뤄진 텍스트의 70 % 이상이 체언 (명사, 수사, 대명사) 입니다. 명사는 어떤 개념을 설명하기 위한 단어입니다. 텍스트의 도메인마다 다른 개념들이 존재하기 때문에 각 도메인마다 서로 다른 명사들이 존재합니다. 그렇기 때문에 명사에 의한 미등록단어 문제가 가장 심각합니다. 그러나 사람은 새로운 도메인이라 하더라도 몇 개의 문서만 읽어보면 새로운 명사를 제대로 인식할 수 있습니다. 이는 한국어 어절 구조에 특징이 있기 때문입니다. 이번 포스트에서는 한국어 어절 구조의 특징인 L-R pattern 을 이용하여 통계 기반으로 명사를 추출하는 방법을 소개합니다. 이 포스트에는 Pycon KR 2017 의 발표내용이 포함되어 있습니다.
Tree traversal of trained decision tree (scikit-learn)
scikit-learn 에서 제공되는 decision tree 를 학습하면 각 branching 과정에 대한 정보가 모델에 저장됩니다. 이를 이용하면 tree traversal visualization 을 하거나, parameters 를 저장하여 직접 decsion rules based classifier 를 만들 수 있습니다. 이번 포스트에서는 학습된 decision tree 의 parameters 를 이용하는 방법을 소개합니다.
Decision trees are not appropriate for text classifications.
의사결정나무 (Decision tree) 는 classification 과정에 대한 해석을 제공하는 점과 다른 classifiers 보다 데이터의 전처리를 (상대적으로) 덜해도 된다는 장점이 있습니다. 하지만 bag of words model 과 같은 sparse data 의 분류에는 적합하지 않습니다. 이번 포스트에서는 의사결정나무가 무엇을 학습하는지 알아보고, 왜 sparse data 에는 적합하지 않은지에 대하여 이야기합니다.