본문 바로가기
공허의 유산/마음의 거울

[오픈채팅의 재해석] 03. 핵심어 검출을 위한 명사 검출

by 바른생활머시마 2023. 9. 30.
728x90
반응형

어떤 결과물을 내는 방법은 여러가지가 있죠. 특히 프로그래밍의 경우에는 더 그렇습니다. 또한, 똑같은 기술을 설명하는 방법도 다양하죠. 핵심어 검출을 해 나가기에 앞서서 다른 분들의 글도 몇 가지 좀 살펴봤는데 정말 말끔하게 정리가 잘 된 포스트가 하나 있어서 읽어봤습니다. 적용 할 도메인에 따라 불용어 처리 같은 부분은 따로 처리를 해야겠지만, 기본적으로 어떤 텍스트 기반의 자료에서 주요 키워드를 검출하여 이를 보여주는 절차는 말끔하게 정리가 되어 있어서, 새로운 도메인에 대한 분석을 시작 할 때 해야 할 일을 잊지않고 챙겨야 할 때 좋은 참고 자료가 될 수 있을 것 같습니다.

https://m.blog.naver.com/j7youngh/222861344172

 

[ 한글 키워드 시각화 ] 파이썬 python 텍스트 마이닝 한글 ( 워드 클라우드 WordCloud, squrify 트리맵으

파이썬(python), matplotlib을 이용해 라인 플롯, 바 차트 등 다양한 그래프와 텍스트를 이용한 워드 클라...

blog.naver.com

 

 

전처리

 앞에서 카카오톡 대화 저장 문서에서 대화 내용만 꺼내는 전처리를 했었는데, 지금부터의 전처리는 형식의 전처리라기 보다는 언어적인 표현과 비언어적인(?) 표현을 구분하는 것입니다. 이 표현도 사실 좀 어색한 것이... 문서의 모든 것은 그 문서가 표현하고자 하는 내용을 잘 전달하기 위한 기호라서 사실 비언어적인 표현이라는 것이 있을까요???  참고 포스트에서 전처리를 하는 과정은 정규식을 통한 방법인데 특정 데이터를 걸러내는 기술적인 수단으로써 참고하기 좋은 코드인 것 같습니다.

https://m.blog.naver.com/j7youngh/222861344172

 E-mail, URL은 고유명사, 한글 자음은 감정을 표현하는 수단으로도 많이 쓰이므로 의성어나 의태어, 알파벳/숫자는 같은 의미의 한글도 있고, HTML이나 특수기호는 경우에 따라서 글의 어떤 부분을 강조하기 위한 수단이 되기도 하고... 이렇듯 필터링 해야 할 대상도 글의 의미를 담고 있는 기호라서 필터링 하기가 좀 망설여집니다.  특히, 청소년들이 사용하는 채팅 언어에서는 이러한 특성은 더욱 도드라지기 때문에 이런 부분을 고려하려면 일단 저런 필터링은 하지 않는 것이 좋겠습니다. 물론, 도메인에 따라서 달라져야 할 부분이기 때문에, 오히려 청소년 대화 글에서는 엉뚱한 요소를 필터링 해야 할 수도 있을 것 같습니다. 

 

 

형태소 분석 및 불용어 처리

형태소 중 명사와 한 자 이상 단어 추출의 기준을 적용하는 것 또한 도메인에 따라 달라져야 할 것 같습니다. 의미로 보자면 '명사'를 사용하는 것은 문제가 없을 것 같은데, '명사'라고 판단하는 기준이 일반적인 국어 문법을 기준으로 하면 안될 것 같아요. '신조어' 비율이 높은 문서를 기존 방법론으로 처리하는 것은 참 어려운 일인 것 같네요. AI학습이라는 것도 기존의 데이터를 바탕으로 패턴을 찾아내서 그럴듯한 추정값을 도출하는 과정인데, 이렇게 표현의 의미가 빠르게 변화하는 데이터는 이전과 다른 방법으로 처리가 되어야 할 것 같습니다. 문법 검사기에서 오류로 검출되면 이것이 정말 오류인지 새로운 표현인지 검토를 해야 될 것 같네요.

 

 일단, 명사와 한 자 이상 단어 추출 기준을 적용한 것을 보고, 살려야 할 표현인데 누락 된 표현은 없는지, 한 글자이지만 매우 중요한 표현인 것은 있는지 살펴보는 것도 매우 큰 의미가 있을 것 같습니다.

 

 

 파일을 줄 단위로 읽을 필요는 없어서 한꺼번에 읽도록 했더니, 그 동안 볼 수 없었던 새로운 에러를 만나게 되었습니다.

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 0: invalid continuation byte

 

저장 할 때 utf-8로 저장하지 않았나 싶어서, cp949로 했는데, 그래도 비슷한 에러가 납니다.

UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 1: illegal multibyte sequence

 

사용한 파일을 저장 할 때 분명히 utf-8로 저장을 했었습니다.

# 결과 파일
result_file_path = 'C:\Study\c4k\dcinside_gogall\KakaoOpenChat\\result.text'
result_file = open(result_file_path, 'w', encoding='utf-8')

소스 파일을 VSCode에서 읽어봐도 utf-8로 되고 있습니다. 

한 가지 마음에 걸리는 것은, 아이폰에서 저장한 대화 파일을 압축을 풀 때 오류가 있었습니다. 그러나, 파일 읽을 때는 문제가 없어서 그냥 사용했고, 특히나 저장은 별도 파일로 따로 utf-8를 지정하여 저장했기 때문에 문제가 없을 것으로 생각했습니다. 그 문제 말고는 특별히 문제가 될 것이 없는데 무슨 일인지 모르겠네요. @_@ euc-kr, ANSI도 안되고...

혹시나 한 줄씩 읽으면 되려나 해서 시도해봤지만 같은 결과이고..

src_doc_path = './KakaoOpenChat/dialog_only_filtered.text'
src_doc = open(src_doc_path, 'r', encoding='euc-kr')
for line in src_doc.readlines():
  nouns = komoran.nouns(line)
  print(nouns)  
src_doc.close()

 

혹시나 해서 VSCode로 다시 utf-8로 저장하니 잘 되네요.-_-

추측하자면...

아이폰에서 저장한 압축 파일 풀 때 무슨 문제가 있었고, 그것을 메모장 등은 어떻게 어떻게 읽었는데, 파일 저장을 할 때 문제가 되는 바이트도 함께 저장이 되었고, 에디터에서 문제를 수정해서 읽은 상태를 다시 저장하면서 문제가 되는 바이트가 제거 된 것... 요런 시나리오??

 

그래서, 다시 명사 추출을 해 보려니, 처음 보았던 에러가...

 

아하!! 

그럼 애초의 문제는 파일 읽기의 문제가 아니라, komoran의 명사 추출에서 발생했던 에러였고, komoran에서 처리 못하는 특수문자가 있었을 가능성이 높겠군요.

# Konlpy 설치
# https://konlpy.org/ko/latest/install/#id2

from konlpy.tag import Komoran
#import pickle
#from operator import itemgetter

komoran = Komoran()

# 소스 파일 읽기
src_doc_path = './KakaoOpenChat/dialog_only_filtered.text'
src_doc = open(src_doc_path, 'r', encoding='utf-8')  
src_article = src_doc.read()
src_doc.close()

# 명사 추출
nouns = komoran.nouns(src_article)
print(src_article)

 

어느 특수문자에서 에러가 나는지 살펴보기 위해 아래와 같이 에러나는 문장을 출력하도록 해보았습니다.

from konlpy.tag import Komoran

komoran = Komoran()

# 소스 파일 읽기
src_doc_path = './KakaoOpenChat/dialog_only_filtered.text'
src_doc = open(src_doc_path, 'r', encoding='utf-8')
for line in src_doc.readlines():
  try:
    nouns = komoran.nouns(line)
    print(nouns)  
  except:
    print("ERROR>"+line)
src_doc.close()

그런데, 특수 문자가 아닌 곳에서도  에러가 나는 것 같네요.

잘 처리가 되는 것도 있고...

꼬꼬마로 한번 해보니까, 이전에 할때 문제가 되었던 것처럼 응답이 없이 멈추는 경우는 없지만, 처리 시간이 꽤 오래 걸리는 경우가 종종 있습니다. 그래도, 인코딩 문제는 생기지 않고 잘 되네요. @_@ 

from konlpy.tag import Komoran, Kkma

#komoran = Komoran()
kkma = Kkma()

# 소스 파일 읽기
src_doc_path = './KakaoOpenChat/dialog_only_filtered.text'
src_doc = open(src_doc_path, 'r', encoding='utf-8')
for line in src_doc.readlines():
  line = line.strip()
  try:
    #nouns = komoran.nouns(line)
    nouns = kkma.nouns(line)
    print(nouns)  
  except:
    print("ERROR>"+line)

src_doc.close()

꼬꼬마로 한방에 하는 것도 될까요?

해보니까 진행 여부를 판단 할 수가 없네요

 

아주 멈춰버리지 않는다고 가정하고, 처리 시간이 오래 걸릴 것이니 처리 된 결과를 피클로 파일 저장 코드를 만들어 둬야겠습니다. 

꼬꼬마는 계속 켜두니까 Java에서 메모리 부족 에러가 뜨네요.

 

ERROR>네ㅔ네네네ㅔㅔ네네네ㅔ네네네네네ㅔㅔ네네네네네ㅔㅔ네ㅔㄴ넨

 

꼬꼬마는 같은 글자가 쭉 나오는 문장에서 응답이 없는것이 매우 큰 약점인 것 같네요.

무슨 옵션 같은 것으로 이런 현상을 회피 할 수 있는게 있을지 모르겠네요. 유명한 모듈이라 그렇게 허술하지는 않을 것 같은데... ^^

아무튼 하~~~~안참 걸려서 다 처리했고, 이제부터는 피클 데이터를 로딩하여 처리해 보겠습니다.

중간에 로그를 보니 명사가 검출되지 않은 행들도 많이 있었으니, 일단 빈 행들을 제거하는 것부터 해야겠네요. 

그런데, 검출이 되지 않은 행들이 정말 명사가 없었을지도 의문이니, 어떤 행들에서 명사가 검출되지 않았는지 먼저 체크 해 보는 것이 좋을 것 같습니다. 다음에는 처리 전후 문장을 비교 해 봐야겠습니다.

 

728x90
반응형

댓글