감성분석과 문서분류

Python을 이용해 텍스트에 나타난 감성과 의견을 분석하고, 문서를 카테고리에 따라 분류합니다.


수강중

2. 선형 모형

동영상이 없는 텍스트 강의 자료입니다.

텐서플로로 선형 모형을 만들어 감성분석을 실시합니다.

데이터 불러오기

앞 강의에서 만든 데이터를 불러옵니다.

import joblib

x_train, x_test, y_train, y_test, cv = joblib.load('review.pkl')

선형 모형

텐서플로를 불러옵니다.

import tensorflow as tf
  • Dense(1): 1개의 예측(긍/부정)을 하는 선형 모형을 만듭니다.
  • input_shape=(1000,): 1000개의 단어를 입력 받습니다.
  • activation=: 시그모이드 활성화 함수를 사용합니다.
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(1, input_shape=(1000,), activation='sigmoid'))

모형 요약을 확인합니다. 1,000개의 단어에 가중치가 부여되고, 1개의 절편이 있기 때문에 파라미터의 수는 1,001개입니다.

model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_2 (Dense)              (None, 1)                 1001      
=================================================================
Total params: 1,001
Trainable params: 1,001
Non-trainable params: 0
_________________________________________________________________

학습 준비

  • 학습 알고리즘(optimizer)는 adam을 사용합니다.
  • 손실함수(loss)는 교차 엔트로피(binary_crossentropy)를 사용합니다.
  • 보조적인 지표로 정확도(accurary)를 사용합니다. 정확도란 전체 사례 중 맞은 사례의 비율을 의미합니다.
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

학습

모든 데이터를 한번 학습하는 것을 1 에포크(epoch)라고 합니다. 아래는 epochs=10이므로 총 10 에포크를 진행합니다.

model.fit(x_train, y_train, epochs=10)
WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: <class 'scipy.sparse.csr.csr_matrix'>, <class 'NoneType'>
Train on 800 samples
Epoch 1/10
800/800 [==============================] - 0s 92us/sample - loss: 0.6906 - accuracy: 0.5412
Epoch 2/10
800/800 [==============================] - 0s 32us/sample - loss: 0.6809 - accuracy: 0.6162
Epoch 3/10
800/800 [==============================] - 0s 30us/sample - loss: 0.6718 - accuracy: 0.6875
Epoch 4/10
800/800 [==============================] - 0s 35us/sample - loss: 0.6629 - accuracy: 0.7375
Epoch 5/10
800/800 [==============================] - 0s 34us/sample - loss: 0.6542 - accuracy: 0.7950
Epoch 6/10
800/800 [==============================] - 0s 31us/sample - loss: 0.6457 - accuracy: 0.8325
Epoch 7/10
800/800 [==============================] - 0s 31us/sample - loss: 0.6373 - accuracy: 0.8575
Epoch 8/10
800/800 [==============================] - 0s 34us/sample - loss: 0.6292 - accuracy: 0.8712
Epoch 9/10
800/800 [==============================] - 0s 42us/sample - loss: 0.6212 - accuracy: 0.8775
Epoch 10/10
800/800 [==============================] - 0s 41us/sample - loss: 0.6135 - accuracy: 0.8813
<tensorflow.python.keras.callbacks.History at 0x25f7354d128>

모형 학습결과로 loss는 0.6135, 정확도는 0.8813 (약 88%)을 확인할 수 있습니다. 해당 결과는 실행할 때마다 달라질 수 있습니다.

모형 평가

실제 성능을 파악하기 위해 테스트용 데이터로 평가를 해보겠습니다. model.evaluate()를 사용합니다.

model.evaluate(x_test, y_test)
WARNING:tensorflow:Falling back from v2 loop because of error: Failed to find data adapter that can handle input: <class 'scipy.sparse.csr.csr_matrix'>, <class 'NoneType'>
200/200 [==============================] - 0s 135us/sample - loss: 0.6389 - accuracy: 0.7450
[0.6388983941078186, 0.745]

모형 평가결과로 loss는 0.63889, 정확도는 0.745 (약 75%)입니다.

가중치

모형에서 단어별 가중치(weight)를 추출합니다.

weight, bias = model.trainable_weights

단어와 가중치를 짝을 지어 표의 형태로 만듭니다.

import pandas as pd

word_weight = pd.DataFrame({
    '단어': cv.get_feature_names(),
    '가중치': weight.numpy().flat
})

단어들을 가중치의 오름차순으로 정렬합니다. 이렇게 하면 가중치가 가장 작은 단어들이 위로 올라오게 됩니다. 가중치가 작다는 것은 이 단어들이 많이 나오는 리뷰는 부정적이라는 뜻입니다.

word_weight.sort_values('가중치').head()
단어 가중치
988 worst -0.168656
333 horrible -0.167978
411 money -0.165708
319 having -0.160401
358 junk -0.157501

단어들을 가중치의 내림차순으로 정렬합니다. 이렇게 하면 가중치가 가장 큰 단어들이 위로 올라오게 됩니다. 가중치가 크다는 것은 이 단어들이 많이 나오는 리뷰는 부정적이라는 뜻입니다.

word_weight.sort_values('가중치', ascending=False).head()
단어 가중치
985 works 0.238472
310 great 0.207153
255 excellent 0.194057
423 nice 0.190334
114 best 0.186735