- 전체
- Python 일반
- Python 수학
- Python 그래픽
- Python 자료구조
- Python 인공지능
- Python 인터넷
- Python SAGE
- wxPython
- TkInter
- iPython
- wxPython
- pyQT
- Jython
- django
- flask
- blender python scripting
- python for minecraft
- Python 데이터 분석
- Python RPA
- cython
- PyCharm
- pySide
Python 자료구조 텍스트 마이닝 4편. 형태소 분석(1/3)
2018.02.18 23:37
텍스트 마이닝 4편. 형태소 분석(1/3)
형태소 분석기를 사용하기 위해서는 pos()에서 나온 결과를 처리하는 방법을 이해하는게 필요합니다.
입력
pos() 입력으로 굉장히 긴 텍스트를 입력으로 지정하는 것은 그리 좋은 일이 아닙니다.
문장 단위의 입력이 적절 합니다. 문장이라는 것의 기준이 생각보다 애매해서 텍스트를 문장으로 분리하려면 여러 가지 고려가 필요합니다.
우선 단순하게 해보면
문장 구분 방법 : "마침표(.), 물음표(?), 느낌표(!)에 이어서 공백 문자가 있으면 문장을 나눈다."
가장 간단한 방법은 텍스트에서 문장 구분자를 명시적인 분절이 쉬운 문자열로 치환하는 것 입니다.
이를 파이썬으로 구현하면 다음과 같습니다.
#!/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 형식은 인간 가독성보다는 기계 가독성에 초점을 둔 형식으로 입출력이 매우 간편합니다.
[출처] 텍스트 마이닝 4편. 형태소 분석(1/3)|작성자 엉드루
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.