새소식

컴퓨터공학 💻/딥러닝

[딥러닝] RNN 순환 신경망으로 영화 평론 감정 분석 예측기 만들기

  • -
RNN 순환 신경망으로 영화 평론 감정 분석 예측기 만들기

 

이전에 알려드린 순환 신경망 RNN 이론을 바탕으로 분석기를 하나 만들어보겠습니다.

 

 

IMDb: Ratings, Reviews, and Where to Watch the Best Movies & TV Shows

IMDb is the world's most popular and authoritative source for movie, TV and celebrity content. Find ratings and reviews for the newest movie and TV shows. Get personalized recommendations, and learn where to watch across hundreds of streaming providers.

www.imdb.com

영화 정보들을 보면 항상 유저들의 리뷰가 달리기 마련인데 imdb라는 영화 정보 데이터베이스 사이트 역시 유저들의 영화에 대한 리뷰를 살펴볼 수 있습니다.

 

Tensorflow에서 제공하는 imdb Dataset으로 imdb에 존재하는 유저들의 영화 평론, 리뷰가 긍정적인지 부정적인지를 얼마나 정확히 판별하는지 간단한 예측 모델을 만들어보겠습니다.

 

최근 공개된 시리즈물 'Loki'에 대한 유저들의 리뷰를 10 Stars 기준으로 살펴보면 긍정적인 반응이 대다수인 반면 2 Stars 기준으로 살펴보면 그냥 광고다, 시간 낭비다, 시작은 흥미있지만.. (연기가 끔찍하다) 등 악평이 난무한 것을 볼 수 있습니다. 이러한 리뷰 데이터들을 모아서 이 리뷰가 긍정적인지 부정적인지를 판별해봅시다.

 

(Google Colab 사용자라면 아래 설치 코드는 무시합니다)

pip3 install tensorflow
pip3 install keras
from keras.preprocessing import sequence
from keras.datasets import imdb
from keras import layers, models

keras datasets에서 imdb를 불러오고 레이어, 모델을 불러옵니다.

 

max_features=20000
maxlen=80

(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)

전처리는 이미 완료된 상태이므로 imdb에서 데이터를 로드합시다. max_features는 위 예시에서 빈도 수에 따라 0순위부터 20000순위까지 총 20000개의 데이터를 불러와서 저장합니다.

그러면 x_train 데이터에는 빈도 수에 따른 단어들의 인덱스가 리스트로 저장될 것입니다. (ex. [ 3, 47, 10098, 522, 1042 ... ] -> 3순위, 47순위, 10098순위, 522순위, 1042순위 ... )

그리고 y_train 데이터에는 그 단어들이 긍정인지 부정인지에 따라 1, 0으로 레이블링된 값이 들어갑니다.

 

train 데이터는 학습을 하면서 영향을 주는 데이터라면 test 데이터는 학습한 데이터가 정답에 근접하는 지를 평가합니다. train 데이터에서 발생한 loss만 업데이트하고 학습하고 test 데이터에서 발생한 loss는 학습에 반영하지 않습니다. (반영하면 안되겠죠..)

 

maxlen은 모델 학습을 위해 최대로 받을 문장의 길이입니다. 위 예시에서 80으로 설정한 것은 불러올 문장이 80보다 길면 80에서 자르고 짧다면 blank를 넣어서 80의 길이로 일정하게 맞춥니다. 

 

pad_sequences는 리뷰의 길이, 즉 sequence가 모두 다르므로 같은 길이의, maxlen으로 처리하는 함수입니다.

 

x = layers.Input((maxlen,))
h = layers.Embedding(max_features, 128)(x)
h = layers.SimpleRNN(128)(h)
y = layers.Dense(1, activation='sigmoid')(h)

Embedding은 단어들을 (위 예시에서)128 차원으로 벡터화합니다. (One Hot Encodding 방식 아닙니다. 여기서는 모델이 벡터값 안에 단어의 의미론적인 것들도 같이 학습합니다)

 

maxlen 길이 만큼 Input된 레이어들(x)을 Embedding 레이어로 벡터화하고 다시 RNN 레이어로 128차원으로(h) 받습니다. RNN 레이어로 통과된 레이어들이 긍정문인지 부정문인지를 판별합니다. 즉, 긍정(1)일 확률이 어느정도인지 0과 1의 신호값으로 표시하여 예측값이 0.3이면 부정(0), 0.8이면 긍정(1)이 됩니다.

 

model = models.Model(x, y)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
batch_size = 32
epochs = 3
model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(x_test, y_test))

마지막으로 모델의 시작점(x), 끝점(y)를 명시하면 됩니다. 위 예시에서 optimizer로 adam을 사용하였고, loss function으로 binary_crossentropy를 사용했습니다. batch_size는 전체 데이터를 몇개씩 나누어 학습할 것인지를 결정합니다. 

validation_data은 test 데이터들을 넣어서 모델에 대한 지표를 객관적으로 평가합니다.

 

이제 코드를 실행하고 결과를 살펴봅시다.

총 3번의 학습 결과 정확도가 0.57에서 0.87까지 증가한 것을 확인할 수 있습니다.

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.