Python tech/NLP

[Python keras] 감성 분석 딥러닝 모델 생성 - TextVectorization

콜레오네 2021. 2. 1. 02:25

Python tensorflow keras 

textvectorization 

sentimental analysis using deep learning

 

준비해야할 것 : 수집한 댓글 데이터

 

훈련 데이터(Train Data)를 생성하기 위해 약 900개의 댓글을 하나하나 레이블링(Labeling) 해주었습니다.

이때, 감성 수치는 긍정은 1, 부정은 0

제가 레이블링한 데이터를 사용하고 싶다면

아래 링크에서 train-data/comment-labeling.csv 파일을 활용하셔도 됩니다.

>> github.com/Minku-Koo/Comment-Sentiment-Analysis 

 

900개의 훈련 데이터가 부족할 것이라고 판단해서 전이 학습(Transfer Learning)을 시키기로 하였습니다.

아래 링크는 네이버 영화 리뷰 데이터입니다. 마찬가지로 긍정 리뷰는 1, 부정 리뷰는 0

>> https://github.com/e9t/nsmc 

 

최종 훈련 데이터 : 수작업 레이블링 댓글 약 900개 + 네이버 영화 리뷰 20만 개


데이터 전처리 

 

데이터는 KoNLPy의 Okt 모듈을 활용하여 형태소 분석을 진행합니다.

아래는 KoNLPy 사용 예시

(Okt를 제외하고도 Komoran, Hannanum, Kkma 등 다양한 모듈이 있습니다.)

from konlpy.tag import Okt

ok = Okt()
comment = ok.pos("댓글 데이터를 입력해주면 형태소 분석이 됩니다.")

위와 같이 Okt 모듈을 활용하여 형태소 분석을 진행한 다음

조사, 구두점, 숫자 그리고 불용어(Stop word)를 제거합니다.

그리고 다시 분리된 모든 형태소를 공백을 기준으로 하나의 문자열로 합쳐줍니다.

이러면 댓글 데이터 전처리 완료

 

불용어 리스트는 아래 링크에서 가져왔습니다. 

>> www.ranks.nl/stopwords/korean


준비된 데이터를 훈련 데이터와 테스트 데이터로 구분해줍니다.

train_test_split 함수를 사용합니다.

이때 x, y 변수는 각각 댓글과 감성 값입니다.

 

(저는 전이 학습을 시켰기 때문에, 댓글 데이터와 네이버 리뷰 데이터를 같은 비율로 가져와서 합쳤습니다.)

from sklearn.model_selection import train_test_split

test_percent = 0.2 # 테스트 데이터 비율
# 훈련 데이터와 테스트 데이터 생성
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=test_percent)

 

댓글 감성 수치를 예측할 RNN 모델을 생성하는 함수를 만들어줍니다.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
from tensorflow.keras.layers import Dense, Embedding, Flatten
from tensorflow.keras import Input, Model
from tensorflow.keras import models

def build_model(train_data): # to make rnn model
    train_data = tf.data.Dataset.from_tensor_slices(train_data)
    model = Sequential()
    model.add(Input(shape=(1,), dtype="string")) # input one string data (comment)
    max_tokens = 15000 # dictionary size
    max_len = 50 # comment to vectorize size
    vectorize_layer = TextVectorization( # make textvectorization 
      max_tokens=max_tokens,
      output_mode="int",
      output_sequence_length=max_len,
    )
    
    vectorize_layer.adapt(train_data.batch(64))
    model.add(vectorize_layer)
    model.add(layers.Embedding(max_tokens + 1,output_dim= 200))
    model.add(Flatten())
    model.add(Dense(8, activation="relu"))
    model.add(Dense(1, activation="sigmoid"))
    return model

 

해당 모델은 댓글 데이터 하나를 입력받고, 하나의 감성 값을 출력해주는 모델

Input(shape=(1,), dtype="string") > 데이터 1개를 입력받고, 데이터 타입은 문자열

keras 내장 함수인 TextVectorization텍스트 데이터를 벡터화해줍니다.

TextVectorization 의 파라미터를 정의해줍니다. (아래 '변수 설명' 참조)

 

벡터화한 데이터를 Embedding 레이어에 넣어줍니다.

이때, 첫 번째 인자는 max_tokens에 1을 더해준 값으로 설정하면 됩니다.

 

Flatten()은 "평평하게 하다."라는 의미로,

Embedding 레이어를 통과한 데이터를 Dense에 넣을 수 있는 형태로 변환해줍니다.

(이걸 넣지 않았더니, 정확도가 매우 낮게 나왔습니다.)

 

Dense는 units=8, 활성화 함수는 relu로 구성해줍니다.

마지막 출력층은 units=1 (하나만 출력되어야 하기 때문), 활성화 함수는 sigmoid

(감성 값의 범위는 0 이상 1 이하 소수이기 때문에 sigmoid 사용)

 

 

변수 설명

  • train_data : 훈련 댓글 리스트
  • max_tokens : 전체 단어 사전 크기 (모든 댓글을 토큰화하여 사전에 등록해줍니다.)
  • max_len : 텍스트를 벡터화한 크기 (출력 최대 크기)

생성된 모델을 컴파일하고 훈련시킵니다.

from tensorflow.keras import layers
from tensorflow.keras import optimizers
from tensorflow.keras import losses
from tensorflow.keras import metrics

rnn_model =build_model(x_train) # 모델 생성 함수를 통해 모델 생성
rnn_model.compile( # rnn model compile 컴파일 진행
        optimizer=  "adam",  # 최적화 함수
        loss='binary_crossentropy', # 손실 함수
        metrics=['accuracy']
    )

# model training
history = rnn_model.fit(x_train,y_train, #훈련시키기
                   epochs = 5,  batch_size = 128  , validation_data = (x_test, y_test) )

최적화 함수adam

손실 함수는 이진 분류이기 때문에 binary_crossentropy

이후 댓글 데이터와 감성 데이터를 넣고 훈련시켜줍니다.

 


최종 RNN 모델

 

RNN 모델 구조

모델 훈련 과정

 

정확도 95%, 손실값 0.11

 

이로써 RNN 모델이 완성되었네요.


생성한 RNN 모델을 저장해봅시다.

model_save_path = "../dir/" # model save path
model_name ="rnn-model" #model save file name
tf.saved_model.save(rnn_model, model_save_path+model_name)

모델을 저장할 경로와 저장할 모델 이름을 설정해줍니다.

마지막으로 모델을 위와 같이 저장해주면 나중에 다시 생성 및 훈련시키지 않아도 바로 불러올 수 있습니다.

 

 

반응형