앞서 분석한 데이터 기반으로 전처리를 진행한다. 라이브러리를 부르면
import numpy as np
import pandas as pd
import re
import json
from konlpy.tag import Okt
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from tensorflow.python.keras.preprocessing.text import Tokenizer
DATA_IN_PATH='./data_in/'
train_data=pd.read_csv(DATA_IN_PATH+'ratings_train.txt', header=0, delimiter='\t', quoting=3)
불러온 라이브러리는 대부분 영어 전처리와 같고 다른점은 한글 토그나이징 도구인 KoNLPy를 사용한다는 점이다.
train_data['document'][:5]
보면 영어와 다르게 HTML 태그가 없어서 Beautiful Soup은 안쓴다. 하지만 특수문자나 숫자는 지워야 하는데 먼저 첫 번째 리뷰를 전처리 해보면, (정규 표현식을 이용해 제거한다.)
review_text=re.sub("[^가-힣ㄱ-ㅎㅏ-ㅣ\\s]","",train_data['document'][0])
print(review_text)
특수문자가 제거됐고 이제 불용어를 제거하기 위해 문장 단어로 나눠야한다. okt를 이용한다. 그리고 형태소 분석기를 사용할 때 어간 추출을 사용해 어간이 추출된 단어로 나눈다.
okt=Okt()
review_text=okt.morphs(review_text,stem=True)
print(review_text)
결과를 보면 문장이 각 단어로 나눠져 있다. 불용어를 제거해야하는데 한글 불용어는 파이썬 라이브러리가 없어 직접 불용어 사전을 만들어 제거해야한다.
stop_words=set(['은','는','이','가','하','아','것','들','의','있','되','수','보','주','등','한'])
clean_review=[token for token in review_text if not token in stop_words]
print(clean_review)
이제 전체 데이터에 적용하기 위해 하나의 함수로 만든다.
def preprocessing(review, okt, remove_stopwords = False, stop_words = []):
# 함수의 인자는 다음과 같다.
# review : 전처리할 텍스트
# okt : okt 객체를 반복적으로 생성하지 않고 미리 생성후 인자로 받는다.
# remove_stopword : 불용어를 제거할지 선택 기본값은 False
# stop_word : 불용어 사전은 사용자가 직접 입력해야함 기본값은 비어있는 리스트
# 1. 한글 및 공백을 제외한 문자 모두 제거.
review_text = re.sub("[^가-힣ㄱ-ㅎㅏ-ㅣ\\s]", "", review)
# 2. okt 객체를 활용해서 형태소 단위로 나눈다.
word_review = okt.morphs(review_text, stem=True)
if remove_stopwords:
# 불용어 제거(선택적)
word_review = [token for token in word_review if not token in stop_words]
return word_review
전처리 과정을 함수로 정의했으니 학습 데이터에 대한 전처리를 진행한다.
stop_words=set(['은','는','이','가','하','아','것','들','의','있','되','수','보','주','등','한'])
okt=Okt()
clean_train_review=[]
for review in train_data['document']:
# 비어있는 데이터에서 멈추지 않도록 문자열인 경우에만 진행
if type(review)==str:
clean_train_review.append(preprocessing(review, okt, remove_stopwords=True, stop_words=stop_words))
else:
# string이 아니면 비어있는 값 추가
clean_train_review.append([])
clean_train_review[:4]
이제 해당 리뷰를 인덱스 벡터로 변환하면 되는데, 평가 데이터도 동일하게 진행하기에 평가 데이터도 앞 과정을 똑같이 수행한다.
test_data=pd.read_csv(DATA_IN_PATH+'ratings_test.txt', header=0, delimiter='\t', quoting=3)
clean_test_review=[]
for review in test_data['document']:
# 빈 데이터에서 멈추지 않도록 문자열인 경우에만 진행
if type(review)==str:
clean_test_review.append(preprocessing(review, okt, remove_stopwords=True, stop_words=stop_words))
else:
# stirng이 아니면 비어있는 값 추가
clean_test_review.append([])
이제 학습 데이터와 평가 데이터에 대해 인덱스 벡터로 바꾼 후 패딩 처리만 하면 모든 전처리가 끝난다. 텐서플로의 전처리 모듈을 사용하는데, 토크나이징 객체를 만든 후 학습 데이터에 대해서만 적용하고 해당 객체를 사용해 두 데이터를 인덱스 벡터로 만든다. 마지막으로 데이터들을 패딩처리하면 된다.
tokenizer=Tokenizer()
tokenizer.fit_on_texts(clean_train_review)
train_sequences=tokenizer.texts_to_sequences(clean_train_review)
test_sequences=tokenizer.texts_to_sequences(clean_test_review)
# 단어 사전 형태
word_vocab=tokenizer.word_index
# 문장 최대 길이
MAX_SEQUENCE_LENGTH=8
# 학습 데이터를 벡터화
train_inputs=pad_sequences(train_sequences, maxlen=MAX_SEQUENCE_LENGTH, padding='post')
# 학습 데이터의 라벨
train_labels=np.array([train_data['label']])
# 평가 데이터를 벡터화
test_inputs=pad_sequences(test_sequences, maxlen=MAX_SEQUENCE_LENGTH, padding='post')
# 평가 데이터의 라벨
test_labels=np.array(test_data['label'])
패딩 처리할 때 최대 길이를 8로 했는데 이유는 데이터 분석 과정에서 단어 평균 개수가 약 8개였기때문.
학습, 평가 데이터에 대해 입력값과 라벨값을 만든 후에 모델링에서 사용하도록 저장한다.
TRAIN_INPUT_DATA='nsmc_train_input.npy'
TRAIN_LABEL_DATA='nsmc_train_label.npy'
TEST_INPUT_DATA='nsmc_test_input.npy'
TEST_LABEL_DATA='nsmc_test_label.npy'
DATA_CONFIGS='data_configs.json'
data_configs={}
data_configs['vocab']=word_vocab
# vocab size 추가
data_configs['vocab_size']=len(word_vocab)+1
import os
# 저장하는 디렉터리가 존재하지 않으면 생성
if not os.path.exists(DATA_IN_PATH):
os.makedirs(DATA_IN_PATH)
# 전처리된 학습 데이터를 넘파이 형태로 저장
np.save(open(DATA_IN_PATH+TRAIN_INPUT_DATA,'wb'),train_inputs)
np.save(open(DATA_IN_PATH+TRAIN_LABEL_DATA,'wb'),train_labels)
# 전처리된 평가 데이터를 넘파이 형태로 저장
np.save(open(DATA_IN_PATH+TEST_INPUT_DATA,'wb'),test_inputs)
np.save(open(DATA_IN_PATH+TEST_LABEL_DATA,'wb'),test_labels)
# 데이터 사전을 json 형태로 저장
json.dump(data_configs, open(DATA_IN_PATH+DATA_CONFIGS,'w'), ensure_ascii=False)
전처리는 끝냈고, 다음은 모델을 만든다.
[ 출처 : 책 ( 텐서플로와 머신러닝으로 시작하는 자연어 처리) ]
[ NLP ] 텍스트 유사도 (1) (1) | 2021.01.30 |
---|---|
[ NLP ] 한글 텍스트 분류 (3) (0) | 2021.01.21 |
[ NLP ] 한글 텍스트 분류 (1) (0) | 2021.01.12 |
[ NLP ] 영어 텍스트 분류 (7) (0) | 2021.01.10 |
[ NLP ] 영어 텍스트 분류 (6) (0) | 2020.12.30 |