텍스트 마이닝 4편. 형태소 분석(1/3)

 

 

 
 

형태소 분석기를 사용하기 위해서는 pos()에서 나온 결과를 처리하는 방법을 이해하는게 필요합니다.

입력
pos() 입력으로 굉장히 긴 텍스트를 입력으로 지정하는 것은 그리 좋은 일이 아닙니다.
문장 단위의 입력이 적절 합니다. 문장이라는 것의 기준이 생각보다 애매해서 텍스트를 문장으로 분리하려면 여러 가지 고려가 필요합니다.
우선 단순하게 해보면

문장 구분 방법 : "마침표(.), 물음표(?), 느낌표(!)에 이어서 공백 문자가 있으면 문장을 나눈다."

가장 간단한 방법은  텍스트에서 문장 구분자를 명시적인 분절이 쉬운 문자열로 치환하는 것 입니다.
이를 파이썬으로 구현하면 다음과 같습니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

#!/usr/bin/env python3
#  -*- coding: utf-8 -*

import konlpy
import pprint

def split_text(text):

    new_text = text.replace(".",".\n").replace("?","?\n").replace("!","!\n")
    sentences = new_text.splitlines()

    return sentences

def main():
    """
    문장 분리를 실험한다.
    """

    file_name = input("Enter Input file name : ")
    with open(file_name, "r", encoding ='utf-8') as f :
        for line in f:
            sentences = split_text(line)
            for sentence in sentences:
                print(sentence)
                print("="*50)

main()

위 코드에서 replace() 메소드를 이용하여 문장을 명시적으로 구분할 수 있도록 준비했습니다. splitlines() 메소드로 줄바꿈 문자 단위로 입력 문자열을 분절하는 것입니다.
이 방법은 입력 텍스트의 줄바꿈이 문장의 중간에서 이루어지지 않았다고 가정한 것입니다.
완벽한 방법은 아니지만 대부분에는 적용 가능합니다.

참고해야할 파이썬 코드는 다음과 같습니다.

replace() 메소드를 연쇄(chaining)하여 사용하였습니다.
with 문을 사용하였다.  여기서는 열린 파일을 수트로 주어진 코드 블럭 실행 후 반드시 닫아주는 동작을 하도록 한다고 보면 됩니다. 권장하는 파일 입출력 방법입니다.

출력
형태소 분석 결과를 파일에 저장했다가 사용하려는 경우에는 몇 가지 고려 사항이 있습니다.
첫 번째는 입력 텍스트를 함께 저장할 것인가의 문제입니다. 형태소 분석 결과에는 입력 텍스트가 포함되어 있지 않습니다.  한국어의 형태론적 특성 상 형태소 분석 결과로부터 입력 텍스트를 복원하는 것이 거의 불가능합니다. 그러므로 원천 입력 텍스트가 필요할 때는 저장을 해둬야 합니다. 나아가 입력 텍스트의 구조, 즉 단락 구분이나 문장 구분, 그리고 어절 구분을 얼마나 반영할 것인가도 고려해야 합니다. 
두 번째는 저장 형식의 선택입니다. 일정 수준으로 문장의 구조가 반영된 형태로 저장하는 것이 좋은데, 결국 어떠한 형태를 취해서 저장할 것인지 선택해야 합니다.

다음 예제에서는 입력 텍스트의 문장과 어절 구분을 보존하는 형태소 분석 결과 저장 방법을 보일 것입니다. 저장 형식은 어절 단위 수직 텍스트 형식, 문장 단위 수평 텍스트 형식, 그리고 JSON형식 입니다.

#!/usr/bin/env python3
#  -*- coding: utf-8 -*

import konlpy
import pprint
import ujson
from konlpy.tag import Komoran

def split_text(text):

    new_text = text.replace(".",".\n").replace("?","?\n").replace("!","!\n")
    sentences = new_text.splitlines()

    return sentences

def get_morph_anal(analyzer, text):
    """
    형태소 분석을 하여 결과를 돌려 준다.
    """

    morph_anal = analyzer.pos(text, flatten=False   )

    return morph_anal

def print_morph_anal(text, morph_anal, output_format):
    """
    형태소 분석 결과를 출력한다.
    """
    output_format = output_format.lower()
    if output_format =="json":
       output = get_json_output(text,morph_anal)
    elif output_format == "vert":
        output = get_vert_output(text, morph_anal)
    elif output_format == "hori":
        output = get_hori_output(text,morph_anal)

    print(output)

def get_json_output(text, morph_anal):
    """
    텍스트의 분석결과를 json 형식의 문자열로 만든다.
    """

    outputObj={
        "text" : text,
        "morphAnal" : morph_anal
    }
    output = ujson.dumps(outputObj,ensure_ascii=False)

    return output

def get_vert_output(text, morph_anal):
    """
    텍스트 분석 결과를 수직 형식의 문자열로 만든다.
    """

    vert_elems = []
    wordforms = text.split()

    for wordform, wordform_anal in zip(wordforms, morph_anal):
        morphs = []

        for lex, pos in wordform_anal:
            morphs.append(lex + "/" + pos)

        vert_elems.append(wordform + "\t" + "+".join(morphs))

    output = "\n".join(vert_elems)

    return output

def get_hori_output(text, morph_anal):
    """
    텍스트 분석 결과를 수평 형식의 문자열로 만든다.
    """

    hori_elems = []
    wordforms = text.split()

    for wordform, wordform_anal in zip(wordforms, morph_anal):
        morphs=[]

        for lex, pos in wordform_anal:
            morphs.append(lex + "/" + pos)

        hori_elems.append(wordform + "_" + "+".join(morphs))

    output = " ".join(hori_elems)

    return output

def main():
    """
    형태소 분석 결과를 텍스트 형식으로 저장한다.
    """
    file_name = input("Enter input file name : ")
    komoran = Komoran()

    with open(file_name,"r", encoding="utf-8") as f:
        for line in f:
            sentences = split_text(line)
            for sentence in sentences:
                morph_anal = get_morph_anal(komoran,sentence)
                print_morph_anal(sentence, morph_anal, "json")
                print_morph_anal(sentence, morph_anal, "vert")
                print_morph_anal(sentence, morph_anal, "hori")

main()


문장 분리를 위해 앞서 작성한 split_text() 함수를 사용합니다.
형태소 분석 결과를 얻는 get_morph_anal() 함수를 정의합니다. 이 함수는 형태소 분석기 클래스 인스턴스와 분석 대상 문자열을 인자로 받습니다.
pos()에서 flatten=False 인자를 주어 형태소 분석 결과에서 어절의 구분을 유지하게 합니다.
get_json_output() 함수에서 ujson 모듈의 dumps() 함수를 이용해 딕셔너리 형의 객체를 JSON 호환 문자열로 만듭니다. ensure_ascii=False 인자는 한글을 문자열에서 문자로 표현하게 한다. 
get_vert_output()과 get_hori_output() 함수에서 zip() 함수를 이용하여 두 개의 리스트의 항 목들에 순차적으로 접근합니다.
력 문자열을 만들기 위해 문자열에 들어갈 항목들을 리스트에 차례차례 넣은 후 join() 메소드를 이용하여 하나의 문자열로 만든다.
수직, 수평 형식은 품사 주석 말뭉치를 구축할 때에 널리 쓰이는 형식으로 가독성을 유지 하면서도 구조적 속성을 유지하기 위해 개발된 형식입니다.
그러나 이들 형식은 구분자의 중의성이 발생할 가능성이 있고 입출력을 위해 문자열을 파싱해야 하는 부담이 따릅니다.
JSON 형식은 인간 가독성보다는 기계 가독성에 초점을 둔 형식으로 입출력이 매우 간편합니다.

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
232 Mining English and Korean text with Python file 졸리운_곰 2018.03.26 8198
231 [TENSORFLOW] tensorboard 사용하기 file 졸리운_곰 2018.03.24 1287
230 텐서보드 사용법 file 졸리운_곰 2018.03.24 166
229 Networks in Python and SciKit Learn 0.18 file 졸리운_곰 2018.03.22 356
228 한글 NLP with Python file 졸리운_곰 2018.03.04 425
227 python 텐서플로우 설치 후 테스트 코드 file 졸리운_곰 2018.03.04 1171
226 파이썬으로 3줄 요약기를 만들어보자. file 졸리운_곰 2018.03.04 2253
225 python dev 사용자 입력과 출력 졸리운_곰 2018.03.01 60
224 [파이썬으로 구현한 알고리즘] (7) 트리(Tree) file 졸리운_곰 2018.02.27 1447
223 [파이썬으로 구현한 알고리즘] (6) 쉘 정렬(Shell Sort) file 졸리운_곰 2018.02.27 262
222 [파이썬으로 구현한 알고리즘] (5) 삽입 정렬(Insertion Sort) file 졸리운_곰 2018.02.27 256
221 [파이썬으로 구현한 알고리즘] (4) 버블 정렬(Bubble Sort) file 졸리운_곰 2018.02.27 268
220 [파이썬으로 구현한 알고리즘] (3) 선택 정렬(Selection Sort) file 졸리운_곰 2018.02.27 103
219 [파이썬으로 구현한 알고리즘] (2) 스택/큐 (Stack/Queue) file 졸리운_곰 2018.02.27 244
218 [파이썬으로 구현한 알고리즘] (1) 연결 리스트(Linked List) file 졸리운_곰 2018.02.27 488
» 텍스트 마이닝 4편. 형태소 분석(1/3) 졸리운_곰 2018.02.18 1602
216 텍스트 마이닝 3편. 형태소 분석 사전작업 졸리운_곰 2018.02.18 346
215 텍스트 마이닝 2편. 텍스트 파일 file 졸리운_곰 2018.02.18 716
214 텍스트 마이닝 1편. 소개 file 졸리운_곰 2018.02.18 393
213 증권뉴스데이터 수집(3/3편) 졸리운_곰 2018.02.18 105
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED