머신 러닝 공부를 하기위해 사용 가능한 프로그램이면서, 이미 나와있어 구체적인 기능을 알 수 있는 프로젝트로
문장 자동완성 프로젝트를 해봅니다.
프로젝트 개발 순서
1. 학습에 필요한 데이터 얻기
2. 데이터 가공하기(전처리)
3. 모델 설계하기(학습)
4. 학습 후 평가
데이터 얻기
이번 프로젝트에서는, 국립국어원의 말뭉치 "위험한 실험 : 교육개혁의 정치학(1999)"를 사용하겠습니다.
링크 : https://ithub.korean.go.kr/user/total/database/corpusView.do
다운로드 받아 파이썬 파일과 같은 디렉토리에 위치시킵니다.
데이터 가공하기(전처리)
다운로드 받은 데이터에는 html태그 및 특수문자와 같은 학습과정에 방해가 되는 것들이 있습니다.
이를 학습전에 먼저 제거하고, 학습에 필요한 형식으로 만드는 과정을 진행합니다.
다운로드 받은 말뭉치에 쓰여진 HTML 태그 및 특수문자는 정규표현식을 이용해 해당 내용을 지워줍니다.
또한, 박상길님이 개발한 KSS(Korean Sentence Splitter)를 이용해 문단을 문장 단위로 나눠 준 후
sentence_list에 넣습니다.
import re
import kss
f = open('4BH00005.txt', encoding="utf8")
i=0
sentence_list = []
while True:
line = f.readline()
if not line: break
if line != '\n':
i=i+1
line = re.sub('<.+?>', '', line, 0, re.S)
line = re.sub('\(.+?\)', '', line, 0, re.S)
line = re.sub('\[.+?\]', '', line, 0, re.S)
line = re.sub('\{.+?\}', '', line, 0, re.S)
line = re.sub('《.+?》', '', line, 0, re.S)
line = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!『』\‘|\(\)\[\]\<\>`\'…《》\{\}_「」±√]', '', line,0,re.S)
line = line.lower()
if len(line) >10:
sentence_list+= kss.split_sentences(line)
f.close()
print(len(sentence_list)) #출력결과 : 2264
#2264개의 문장이 sentence_list에 들어갔습니다.
케라스의 토크나이져를 이용해 토큰화를 진행합니다.
vocab_size를 총 단어의 갯수보다 1 크게 해줍니다.
그 이유는 단어 100개를 토큰화 및 원핫 인코딩을 진행하면, 크기가 101인 배열로 인코딩되기 때문입니다.
from tensorflow.keras.preprocessing.text import Tokenizer
t = Tokenizer()
t.fit_on_texts(sentence_list)
vocab_size = len(t.word_index) + 1
print('단어 집합의 크기 : %d' % vocab_size) #출력결과 : 13809
이제 정수인코딩 및 하나의 문장을 여러 단계적으로 분리합니다.
sequences = list()
for line in sentence_list:
encoded = t.texts_to_sequences([line])[0] # 각 샘플에 대한 정수 인코딩
for i in range(1, len(encoded)):
sequence = encoded[:i+1]
sequences.append(sequence)
sequences[:11] # 11개의 샘플 출력
샘플출력 결과는 다음과 같습니다.
[[4919, 232],
[4919, 232, 25],
[4919, 232, 25, 2797],
[4919, 232, 25, 2797, 4920],
[8, 609],
[8, 609, 610],
[8, 609, 610, 611],
[8, 609, 610, 611, 215],
[8, 609, 610, 611, 215, 1169],
[8, 609, 610, 611, 215, 1169, 232],
[8, 609, 610, 611, 215, 1169, 232, 1170]]
정수 인코딩 된 정수를 이용해 단어를 얻기 위해 정수를 key, 단어를 value로 하는 index_to_word 딕셔너리를 만듭니다.
index_to_word={}
for key, value in t.word_index.items(): # 인덱스를 단어로 바꾸기 위해 index_to_word를 생성
index_to_word[value] = key
단계적으로 분리된 각 줄들을 레이블로 분리하기 전에, 같은 크기로 만들기 위해 가장 긴 문장으로 패딩 작업을 수행합니다.
패딩 작업을 한 뒤에는 문장들의 가장 마지막 단어를 y 레이블로 분리합니다.
분리된 y레이블에 대해 원-핫 인코딩을 수행합니다.
max_len=max(len(l) for l in sequences)
from tensorflow.keras.preprocessing.sequence import pad_sequences
sequences = pad_sequences(sequences, maxlen=max_len, padding='pre')
import numpy as np
sequences = np.array(sequences)
X = sequences[:,:-1] # 가장 마지막을 제외하고
y = sequences[:,-1] # 가장 마지막만
from tensorflow.keras.utils import to_categorical
y = to_categorical(y, num_classes=vocab_size)
이제 모델을 설계합니다.
모델 설계하기(학습)
전처리 된 데이터를 모델에 학습시킵니다.
이번 프로젝트는 RNN의 변형인 GRU 모델을 이용하여 학습하겠습니다.
GRU 모델 설명 : https://wikidocs.net/22889
학습 후 평가
테스트를 통해 학습이 의도한대로 되었는지 확인합니다.
테스트 데이터를 이용해 정확도와 희소문제가 발생하였는지 등을 확인하고 보완합니다.
이번 프로젝트는 다음을 참고하여 진행됩니다.
딥 러닝을 이용한 자연어 처리 입문(Won Joon Yoo) : https://wikidocs.net/book/2155
'게임개발 외 프로젝트 > 머신러닝' 카테고리의 다른 글
CNN을 이용한 음식 이미지 분류 (0) | 2021.06.29 |
---|