📢 RNN 으로 네이버 영화 리뷰에 대한 긍부정 감성 분석을 한 페이지입니다.
- SimpleRNN
- LSTM
- GRU
- Word Embedding + LSTM
- Word Embedding + LSTM 2 layer
import pandas as pd
import numpy as np
# 데이터 로딩
train_df = pd.read_csv('./data/ratings_train.txt', delimiter='\t')
test_df = pd.read_csv('./data/ratings_test.txt', delimiter='\t')
train_df.shape, test_df.shape # ((150000, 3), (50000, 3))

# 결측치 확인
train_df.isnull().sum()
test_df.isnull().sum()
# 결측치 제거
# 결측치 데이터 있는 행 제거
train_df.dropna(inplace=True)
test_df.dropna(inplace=True)
# 문제와 정답으로 분리
X_train = train_df['document']
X_test = test_df['document']
y_train = train_df['label']
y_test = test_df['label']
TextVectorization : 띄어쓰기 기준으로 잘라줌 → 정교하진 않지만 간단해서 실습 때 사용하겠음from tensorflow.keras.layers import TextVectorization
# 객체 생성
vectorizer = TextVectorization(max_tokens=5000,
output_mode = 'int',
standardize = 'lower_and_strip_punctutation',
output_sequence_length = 10)
max_tokens=5000output_mode = 'int'standardize = 'lower_and_strip_punctutation'output_sequence_length = 10# train 기준으로 단어 사전 구축
vectorizer.adapt(X_train)
vectorizer.vocabulary_size() # 5000
# 적용
X_train_vec = vectorizer(X_train)
X_train_vec.shape # TensorShape([149995, 10])
X_test_vec = vectorizer(X_test)
X_test_vec.shape # TensorShape([49997, 10])X_train[0]
# 아 더빙.. 진짜 짜증나네요 목소리X_train_vec[0]
# <tf.Tensor: shape=(10,), dtype=int64, numpy=array([ 37, 914, 5, 1, 1077, 0, 0, 0, 0, 0])># shape 변경
X_train_vec = np.reshape(X_train_vec, (-1,10,1))
X_test_vec = np.reshape(X_test_vec, (-1,10,1))
# import library
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Input, SimpleRNN, Dense
from tensorflow.keras.optimizers import Adam
# modeling
rnn_model = Sequential()
rnn_model.add(Input(shape=(10,1)))
rnn_model.add(SimpleRNN(units=64))
rnn_model.add(Dense(units=1, activation='sigmoid'))
# 학습/평가 방법 설정
rnn_model.compile(loss = 'binary_crossentropy',
optimizer = Adam(),
metrics = ['accuracy'])
# 학습
h = rnn_model.fit(X_train_vec, y_train,
validation_split=0.2,
epochs = 20,
batch_size = 128)
# 시각화
import matplotlib.pyplot as plt
plt.figure(figsize=(5,3))
plt.plot(h.history['accuracy'], label='acc')
plt.plot(h.history['val_accuracy'], label='val_acc')
plt.legned()

from tensorflow.keras.layers import LSTM, GRU
lstm_model = Sequential()
lstm_model.add(Input(shape=(10,1)))
lstm_model.add(LSTM(units=64)) # <- 이 부분에 SimpleRNN 대신 LSTM 이 들어감 !!!
lstm_model.add(Dense(units=1, activation='sigmoid'))
lstm_model.compile(loss = 'binary_crossentropy',
optimizer = Adam(),
metrics = ['accuracy'])
h2 = lstm_model.fit(X_train_vec, y_train,
validation_split=0.2,
epochs = 20,
batch_size = 128)
# 학습시간 5분
```python
# 시각화
import matplotlib.pyplot as plt
plt.figure(figsize=(5,3))
plt.plot(h2.history['accuracy'], label='acc')
plt.plot(h2.history['val_accuracy'], label='val_acc')
plt.legend()
```
from tensorflow.keras.layers import LSTM, GRU
gru_model = Sequential()
gru_model.add(Input(shape=(10,1)))
gru_model.add(GRU(units=64))
gru_model.add(Dense(units=1, activation='sigmoid'))
gru_model.compile(loss = 'binary_crossentropy',
optimizer = Adam(),
metrics = ['accuracy'])
h3 = gru_model.fit(X_train_vec, y_train,
validation_split=0.2,
epochs = 20,
batch_size = 128)
# 학습시간 6분
결과
# 시각화
import matplotlib.pyplot as plt
plt.figure(figsize=(5,3))
plt.plot(h3.history['accuracy'], label='acc')
plt.plot(h3.history['val_accuracy'], label='val_acc')
plt.legend()


from tensorflow.keras import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.optimizers import Adam
# 차원 수 조정
X_train_vec = X_train_vec.squeeze(-1)
X_train_vec.shape # (149995, 10)
# 모델 설계
embedding_model = Sequential()
embedding_model.add(Embedding(5000,50))
embedding_model.add(LSTM(units=64))
embedding_model.add(Dense(units=1, activation='sigmoid'))
embedding_model.compile(loss = 'binary_crossentropy',
optimizer = Adam(),
metrics = ['accuracy'])
embedding_model.fit(X_train_vec, y_train, validation_split = 0.2, batch_size=128, epochs=20)
embedding_model.add(Embedding(5000,50))(단어 사전 크기, 한 단어를 표현 할 벡터 크기) 지정(샘플 수, 순환 횟수) 이렇게 넣어줘야 함!(샘플 수, 순환 횟수, 특성 수) 이렇게 넣으면 오류 발생!
기존 LSTM 모델 보다 성능은 좋아짐!
그치만 과적합이 되었군여 …. validation accuracy 낮음 ㅠㅠ
벡터 크기 너무 크게 해서 과적합 된 것일 수 있으므로, vector size 를 50 에서 20 으로 줄여서 재학습
결과

리뷰 (단어 N개) → 긍/부(출력 값 1개)return_sequences = True<정리>
다수 입력 → 단일 출력 구조return_sequences = True (RNN 계열 모델의 출력 형태를 결정) → 모든 시점의 출력을 진행embedding_model3 = Sequential()
embedding_model3.add(Embedding(5000,20))
embedding_model3.add(LSTM(units=64, return_sequences=True)) # <- 이 부분 추가!!
embedding_model3.add(LSTM(units=64))
embedding_model3.add(Dense(units=1, activation='sigmoid'))
embedding_model3.compile(loss = 'binary_crossentropy',
optimizer = Adam(),
metrics = ['accuracy'])
embedding_model3.fit(X_train_vec, y_train, validation_split = 0.2, batch_size=128, epochs=20)
accuracy

loss
결론: 성능 개선하는거 되게 어렵네 … → 전이학습 이용하자!