[Preprocessing] (복합) 명사 추출 + 형태소 분석기 사용자 사전 등록

한글 문서를 형태소로 분석하는 경우 미등록 단어 문제로 인해 분석의 질이 낮아질 수 있음

https://github.com/lovit/soynlp/blob/master/tutorials/nounextractor-v1_usage.ipynb

주로 새로운 (복합) 명사가 생겨나는데서 문제가 발생한다면, 기존 형태소 분석기가 이러한 (복합) 명사를 인식할 수 있도록 사용자 사전에 등록하는 방식으로 문제를 해결할 수 있을 것이다.

Soynlp (https://github.com/lovit/soynlp)에서는 한국어의 L+R 구조를 이용하여, R에 위치한 글자를 바탕으로 L이 명사일 확률이 얼마인지를 계산하는 모델을 제공한다.

from soynlp.noun import LRNounExtractor_v2
from nltk import sent_tokenize

noun_extractor = LRNounExtractor_v2(verbose=True)
nouns = noun_extractor.train_extract(sent_tokenize(corpus))

LRNounExtractor_v2 를 호출하고 corpus를 리스트로 넣어준다. 이를 통해 얻은 nouns는 단어를 key로 count와 score를 담은 dictionary 객체이다. count와 score의 threshold를 정해 어느 정도 이상 빈번하게 등장하며 모델이 판단하기에 명사일 가능성이 높은 것들만 따로 저장해 볼 수 있다.

tgt_noun = []
for noun in nouns:
    if (nouns[noun][0] >= lower_count) and (nouns[noun][1]) >= lower_score:
        tgt_noun.append(noun)

이렇게 추출된 명사들에 대해 클리닝 작업을 해볼 수 있다.

non_noun_eomi_list = ('.', '?', ',', '야', '고', '는', '까', '한', '인', '들', '이', '면', '로', '은')
tgt_noun = set([item.strip(""""',.‘“△[]()”’ """) for item in tgt_noun if (item[-1] not in non_noun_eomi_list) \
                        & (sum([1 if char.isdigit() else 0 for char in item]) <= 2) \
                        & (len(re.sub('[^가-힣]', '', item)) >= 4) \
                        & (not re.search('[^가-힣0-9]', item))])

마지막으로 이렇게 얻은 (복합) 명사 리스트를 기존에 사용하는 형태소 분석기 (여기서는 Mecab과 Khaiii)의 사용자 사전에 등록할 수 있다.

#Save to Mecab
f1 = open(os.path.join('/home', 'yoonchan', 'Downloads', 'mecab-ko-dic-2.1.1-20180720',\
                       'user-dic', 'lab_strike_nouns.csv'), 'w')
for noun in nouns:
    #f1.write(noun + '\t\t\t\tNNP\t*\tT\t' + noun + '\t*\t*\t*\t*\t*\n')
    f1.write(noun + ',,,,NNP,*,T,' + noun + ',*,*,*,*\n')
f1.close()

#Build Khaiii again
#https://hanshuginn.blogspot.com/2019/02/khaiii.html
f1 = open(os.path.join('/home', 'yoonchan', 'khaiii', 'rsc', 'src', 'preanal.my'), 'w')
for noun in nouns:
    f1.write(noun + '\t' + noun + '/NNG\n')
f1.close()

Mecab 사용자 사전 업데이트에 관해서는 아래의 링크를,

http://blog.daum.net/moon0sool/162

https://somjang.tistory.com/entry/Google-Colab%EC%97%90%EC%84%9C-mecab-ko-dic-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%82%AC%EC%A0%84-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0

https://medium.com/@john_analyst/konlpy%EC%9D%98-mecab-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%82%AC%EC%A0%84-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0-mac-1be092fe1217

Khaiii 사용자 사전 업데이트에 관해서는 아래의 링크를 확인하면 된다.

https://hanshuginn.blogspot.com/2019/02/khaiii.html

예를 들어 추출된 명사에 ‘베리알랜’이 포함되어 있었다면,

from konlpy.tag import Mecab
m = Mecab()
sent = '베리알랜은 플래쉬다'
m.morphs(sent)

베리알랜이 한 단위로 NNP로 인식이 된다!

끝!