2015년 7월 29일 수요일

자연어 처리를 위한 준비 과정와 간단한 응용사례 소개

학습 방식으로 빠른 성능을 보이는 MeCab 형태소 분석기를 구성하고,
자연어처리(NLTK)를 활용한 간략한 응용 예제를 소개한다.

MeCab 형태소 분석기 구성하기 

1. MeCab Korean 설치
 - 한국어의 특성에 대한 가중치 부분 수정된 버전
 - https://bitbucket.org/eunjeon/mecab-ko/downloads/

2. MeCab Korean Dicationay 설치
 - 한국어 말뭉치로 학습되어진 모델(사전)
 - https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/

3. MeCab Python Library 설치
 - pip3 install mecab-python3

4. 참고 홈페이지 (은전한닙프로젝트)
 - https://bitbucket.org/eunjeon/mecab-ko
 - 맥에서는 --prefix로 경로를 특정해서 사용한다.

* 아키 구성
MeCab 분석기에서는, 미리 학습되어진 모델을 통해서, 신규 문장에 대한 형태소 분석 결과를 리턴한다.

MeCab,NLTK 및 위키백과 활용하기

* 문장을 받아서, 질의 문장이면, 주제어를 위키백과에 조회해서, 결과를 출력한다.


가. MeCab을 통해서 문장을 형태소로 분리하기

In [1]:
import MeCab
m = MeCab.Tagger ()
In [2]:
# 문장을 형태소로 분류한다.
out = m.parse("시리님 노아의 방주가 뭐죠?")
print(out)
시리 NNP,인명,F,시리,*,*,*,*,
님 XSN,*,T,님,*,*,*,*
노아 NNG,*,F,노아,*,*,*,*
의 JKG,*,F,의,*,*,*,*
방주 NNG,*,F,방주,*,*,*,*
가 JKS,*,F,가,*,*,*,*
뭐 NP,*,F,뭐,Inflect,NP,NP,뭣/NP/*
죠 VCP+EF,*,F,죠,Inflect,VCP,EF,이/VCP/*+죠/EF/*
? SF,*,*,*,*,*,*,*
EOS

In [3]:
# NLTK 라이브러리에서 사용할 포멧으로 만든다.
def pos_tagger(s):
    """ (단어,태그) 셋을 만들기 """
    word_tag = []
    for r in s.split('\n'):
        p = r.split('\t')
        if len(p) > 1:
            w, o = p
            t = o.split(',')[0]
            word_tag.append((w,t))
    return word_tag
set_wp = pos_tagger(out)
print(set_wp)
[('시리', 'NNP'), ('님', 'XSN'), ('노아', 'NNG'), ('의', 'JKG'), ('방주', 'NNG'), ('가', 'JKS'), ('뭐', 'NP'), ('죠', 'VCP+EF'), ('?', 'SF')]

나. NLTK를 통해서 형태소 패턴을 활용하기

In [4]:
# 문법 패턴을 정의 한다.
grammar = """
명사: {<NNG>}
명사구: {<명사><JKG><명사>}
동사구: {<NP\+VCP\+EF>}
동사구: {<NP><VCP\+EF>}
"""
In [5]:
import nltk
cp = nltk.RegexpParser(grammar)
tree = cp.parse(set_wp)
print(tree)
(S
  시리/NNP
  님/XSN
  (명사구 (명사 노아/NNG) 의/JKG (명사 방주/NNG))
  가/JKS
  (동사구 뭐/NP 죠/VCP+EF)
  ?/SF)

다. 질의 문장에 대해서 주제어를 위키백과에서 조회하기

In [6]:
bucket = []
for i in tree.subtrees(filter=lambda t: t.label() == '동사구'):
    if ''.join([ w for w,p in i.leaves() ]) in ['뭔가요','뭐죠','무엇인가요']:
        for j in tree.subtrees(filter=lambda t: t.label() == '명사' or t.label() == '명사구'):
            space = lambda p : ' ' if p == 'JKG' else ''
            bucket.append(''.join([ w+space(p) for w,p in j.leaves() ])) 
print(bucket)
['노아의 방주', '노아', '방주']
In [7]:
# 주제를 가진 단어들에 대한 위키백과 참고하기.
import wikipedia as wk
wk.set_lang("ko")
for title in bucket:
    page = wk.page(title)
    print(title,'_____위키백과_____\n',page.summary)
노아의 방주 _____위키백과_____
 노아의 방주(영어:Noah's Ark; 히브리어:תיבת נח; 고전히브리어:Teyvat Noaḥ, -方舟)는 아브라함 계통의 종교에서 전승되는 이야기 속에 등장하는 배이다. 모세오경 중의 창세기에 실려있으며, 노아와 관련된 일련의 이야기 속에 등장하기 때문에 노아의 방주로 통칭된다. 주로 기독교의 전승이 널리 알려져 있으나, 그 외의 아브라함 계통 종교들인 유대교, 이슬람교, 만다교 등에서도 모두 각자의 전승을 가지고 있다. 그러나 종교와 전승에 따라서는 전해지는 내용이나 받아들이는 해석에 조금씩 차이가 있다.
노아 _____위키백과_____
 노아(Noah)는 이스라엘과 아랍의 전설에 등장하는 인물이자 성경 구약성서의 창세기의 홍수이야기(창세기 6:5-17)에도 나오는 인물이다. 구약 창세기 4장과 5장에 따르면, 노아는 아담과 하와의 첫째 아들인 카인의 후손이 아니라 셋째 아들인 셋의 후손이다. 성경의 창세기 5장에 따르면, 노아의 아들은 셈 · 함 · 야벳의 3명이다.
실존여부는 불명확하나 기원전 2800년 경 무렵 메소포타미아와 그 주변 지역에 일어났던 대 홍수기에 살던 한 실존인물에서 유래한 것으로 추정된다. 당시 메소포타미아, 앗시리아, 그리스 지역에도 홍수가 범람하여 소수의 생존자가 있었다는 신화들도 존재한다. 노아의 모델이 된 인물은 이때 이스라엘 혹은 아랍 지역에서 홍수를 피해 살아남은 한 인물이 신화화된것으로 추정된다.
방주 _____위키백과_____
 《엡실론의 방주》(일본어: イプシロンの方舟 (-ふね) 이프시론노 후네[*])는 KOTOKO의 4번째 앨범을 말한다. 2009년 10월 14일 발매.

필자가 최근에 같이 일하게 된 시리(Siri)를 보면, 한글 자연어 처리 영역도 꽤 높은 수준에 도달 했음을 느낀다. 가벼운 문자 보내기, 음악 재생이 매우 편리하고, 위키백과 사전을 읽어주는 기능은 10년을 손가락과 눈으로 일한 IT 엔지니어에 대한 축복임이 틀림 없다.

혹시 자연어 처리 관련해서 입문하시는 분이라면, "한국어 형태소 분석과 정보 검색"이라는 책을 추천해 봅니다.


0 개의 댓글:

댓글 쓰기