[처음 배우는 딥러닝 챗봇] Python을 이용한 딥러닝 챗봇 제작기 (2)

2 minute read

전처리 과정

다음으로는 챗봇 엔진의 전처리 과정을 구현한다. 전처리 과정은 형태소 분석기를 통해 토크나이징(Tokenizing) 작업을 통해 의미 있는 정보만을 남기고 나머지 쓸모 없는 단어들을 제거한다.

이 때 한국어의 자연어 처리를 위해 KoNLPy 를 사용한다. 또한 KoNLPy 라이브러리에는 Kkma, Komoran, Okt 등의 형태소 분석기가 존재한다. 본 책에서는 분석 품질과 분석 속도 둘 다 적당히 괜찮은 Komoran을 사용한다.

전처리를 담당하는 모듈을 제작하기 위해 /utils 디렉터리에 Preprocess.py 파일을 생성하여 다음과 같이 코드를 작성한다. 앞서 설명했듯이, 이 코드를 작성하기 전에 KoNLPy 모듈과 pickle 모듈을 설치해야 한다.

KoNLPy 모듈 설치 과정에 오류가 생겨 시간을 많이 소모했다. 오류는 전에 Anaconda와 Pipenv를 사용하면서 Python 버전과 PyCharm 내의 인터프리터가 상당히 꼬여 있었던 것이 원인이었다. 덕분에 컴퓨터에 깔린 Java와 Python 관련 프로그램들을 전부 지웠다가 처음부터 다시 설치하였다. 또한 KoNLPy의 경우 일반적인 설치 방법과 다르게 다른 프로그램들을 추가적으로 요구하기 때문에 주의해야 한다. KoNLPy의 설치 방법은 이 글, PyCharm 인터프리터가 꼬였을 때의 해결 방법은 이 글 을 참고하면 된다.

from konlpy.tag import Komoran
import pickle


class Preprocess:
    def __init__(self, word2index_dic='', userdic=None):  # 생성자
        # 단어 인덱스 사전 불러오기
        if word2index_dic != '':
            f = open(word2index_dic, "rb")
            self.word_index = pickle.load(f)
            f.close()
        else:
            self.word_index = None

        # 형태소 분석기 초기화
        self.komoran = Komoran(userdic=userdic)

        # 제외할 품사
        # 참조 : https://komorandocs.readthedocs.io/ko/latest/firststep/postypes.html
        # 관계언 제거, 기호 제거
        # 어미 제거
        # 접미사 제거
        self.exclusion_tags = [
            'JKS', 'JKC', 'JKO', 'JKB', 'JKV', 'JKQ',
            'JX', 'JC',
            'SF', 'SP', 'SS', 'SE', 'SO',
            'EP', 'EF', 'EC', 'ETN', 'ETM',
            'XSN', 'XSV', 'XSA'
        ]

    # 형태소 분석기 POS 태거
    def pos(self, sentence):
        return self.komoran.pos(sentence)

    # 불용어 제거 후 필요한 품사 정보만 가져오기
    def get_keywords(self, pos, without_tag=False):
        f = lambda x: x in self.exclusion_tags
        word_list = []
        for p in pos:
            if f(p[1]) is False:
                word_list.append(p if without_tag is False else p[0])
        return word_list

    # 키워드를 단어 인덱스 시퀀스로 변환
    def get_wordidx_sequence(self, keywords):
        if self.word_index is None:
            return []
        w2i = []
        for word in keywords:
            try:
                w2i.append(self.word_index[word])
            except KeyError:
                # 해당 단어가 사전에 없는 경우 OOV 처리
                w2i.append(self.word_index['OOV'])
        return w2i

내용을 보면 Komoran 형태소 분석기의 웹사이트 주소가 책과 다르다. 아마도 웹사이트의 주소가 최근 바뀌었던 것 같다.

챗봇 전처리 클래스 테스트

앞서 작성한 코드가 잘 작동하는지를 확인해보자. /test 디렉터리에 preprocess_test.py 파일을 생성하여 다음과 같이 코드를 작성한다. 저자 분의 Github 에서 사용자 단어 사전 파일(user_dic.tsv) 을 /utils 디렉터리에 저장한다. 사용자 단어 사전은 형태소 분석기에서 인식하지 못하는 단어들을 저장해놓은 것이다. 파일을 열어보면 음식의 이름들이 저장되어 있는 것을 확인할 수 있다.

from utils.Preprocess import Preprocess

sent = input()

# 전처리 객체 생성
p = Preprocess(userdic='../utils/user_dic.tsv')

# 형태소 분석기 실행
pos = p.pos(sent)

# 품사 태그와 같이 키워드 출력
ret = p.get_keywords(pos, without_tag=False)
print(ret)

# 품사 태그 없이 키워드 출력
ret = p.get_keywords(pos, without_tag=True)
print(ret)

출처

조경래 님이 집필하신 처음 배우는 딥러닝 챗봇 교재를 참고하여 글을 작성하였다.

예제 또한 저자 분의 Github 에서 발췌하였다.

Leave a comment