{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Chap03-4. 영화 리뷰 분류: 이진 분류 문제\n",
"이 notebook에서는 리뷰 텍스트 기반으로 영화 리뷰를 긍정 혹은 부정으로 나누는 이진 분류를 IMDB 데이터셋을 이용해 보여주겠습니다. \n",
"
\n",
"\n",
"### IMDB 데이터셋\n",
"인터넷 영화 데이터베이스로부터 가져온 양극단의 리뷰 50,000개로 이루어진 데이터셋입니다. \n",
"이 데이터셋은 훈련 데이터 25,000개와 테스트 데이터 25,000개로 나뉘어 있고 각각 50%는 부정, 50%는 긍정 리뷰로 구성되어 있습니다. \n",
"
\n",
"한편 IMDB 데이터셋은 Keras에 포함되어 있습니다. \n",
"이 데이터는 전처리되어 있어 각 리뷰(단어 시퀀스)가 숫자 시퀀스로 변환되어 있습니다. 여기서 각 숫자는 사전에 있는 고유한 단어를 나타냅니다."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# imdb 데이터셋 로드하기\n",
"from tensorflow.keras.datasets import imdb\n",
"\n",
"(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`imdb.load_data()`를 통해서 데이터를 로드할 수 있으며, 파라미터인 `num_words`는 가장 많은 빈도로 존재하는 단어 10000개만 사용하겠다는 것을 나타냅니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이렇게 불러온 데이터셋은 전처리가 진행된 데이터이고, 출력해보면 다음과 같은 결과가 나옵니다."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1st train data: [1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]\n",
"1st train label: 1\n"
]
}
],
"source": [
"print(\"1st train data: \", train_data[0])\n",
"print(\"1st train label: \", train_labels[0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"위와 같이 각 리뷰 데이터는 단어 인덱스의 리스트입니다.(단어가 인코딩 된 것) 그리고 라벨에서 0은 **부정**을, 1은 **긍정**을 나타냅니다. \n",
"재미삼아 각 리뷰를 우리가 알아볼 수 있도록 원래의 텍스트로 돌려보도록 하겠습니다. \n",
"자주 사용된 10000개의 단어만 사용했으므로 인덱스에 포함되지 않은 단어는 ?로 출력이 되도록 하겠습니다."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"word_index = imdb.get_word_index()\n",
"\n",
"def decode_review(review):\n",
" reverse_word_index = dict(\n",
" [(value, key) for (key, value) in word_index.items()])\n",
" decode = ' '.join(\n",
" [reverse_word_index.get(i - 3, '?') for i in review])\n",
" return decode"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"? this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert ? is an amazing actor and now the same being director ? father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for ? and would recommend it to everyone to watch and the fly fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also ? to the two little boy's that played the ? of norman and paul they were just brilliant children are often left out of the ? list i think because the stars that play them all grown up are such a big profile for the whole film but these children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was shared with us all\""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"decode_review(train_data[0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"위와 같이 영화에 대한 긍정적인 리뷰를 볼 수 있습니다. \n",
"
\n",
"한편 keras에서 제공한 데이터셋과 같은 숫자 리스트는 바로 신경망에 넣어줄 수 없습니다. \n",
"이 리스트를 텐서(벡터)로 변환하는 과정을 거쳐야 합니다. \n",
"여기에서는 **one-hot encoding**을 사용하겠습니다."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"def vectorize_sequences(sequences, dimension=10000):\n",
" results = np.zeros((len(sequences), dimension))\n",
" for i, sequence in enumerate(sequences):\n",
" results[i, sequence] = 1.\n",
" return results"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x_train (25000, 10000)\n",
"x_test (25000, 10000)\n"
]
}
],
"source": [
"x_train = vectorize_sequences(train_data)\n",
"x_test = vectorize_sequences(test_data)\n",
"\n",
"print(\"x_train \", x_train.shape)\n",
"print(\"x_test \", x_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"라벨 또한 벡터로 만들겠습니다."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"y_train (25000,)\n",
"y_test (25000,)\n"
]
}
],
"source": [
"y_train = np.asarray(train_labels).astype('float32')\n",
"y_test = np.asarray(test_labels).astype('float32')\n",
"\n",
"print(\"y_train \", y_train.shape)\n",
"print(\"y_test \", y_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"그리고 훈련하는 동안 처음 본 데이터에 대한 모델의 정확도를 측정하기 위해서 훈련 데이터에서 10000개의 샘플을 추출해 검증 세트를 만들겠습니다."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"x_val = x_train[:10000]\n",
"partial_x_train = x_train[10000:]\n",
"y_val = y_train[:10000]\n",
"partial_y_train = y_train[10000:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 신경망에 주입할 데이터는 모두 준비가 되었으니, 신경망 모델을 만들겠습니다. \n",
"여기에서는 Sequential 클래스를 사용해 모델을 정의를 할 것인데, `relu` 활성화 함수를 사용한 Dense 층 두 개를 쌓고 마지막 층은 확률을 출력하기 위해 `sigmoid` 활성화 함수를 사용하겠습니다. \n",
"![neural networks structure](./images/nn-2.png)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras import models\n",
"from tensorflow.keras import layers\n",
"\n",
"model = models.Sequential()\n",
"model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))\n",
"model.add(layers.Dense(16, activation='relu'))\n",
"model.add(layers.Dense(1, activation='sigmoid'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"마지막으로 손실함수와 옵티마이저를 선택하면 학습 할 준비가 끝납니다. \n",
"이 문제는 이진 분류 문제이고 신경망의 출력이 확률이기 때문에, `binary_crossentropy`손실이 적합합니다.(`mean_squared_error`도 사용가능합니다.) \n",
"또한 옵티마이저는 SGD 종류 중 하나인 `RMSProp`를 사용하겠습니다. \n",
"`metrics`에는 평가 할 지표를 넣으면 되는데 이진 분류에서의 정확도를 나타내는 `binary_accuracy`를 사용하겠습니다. ([[링크](https://keras.io/metrics/#available-metrics)] 참조) \n",
"케라스에는 `rmsprop`, `binary_crossentropy`, `accuracy`가 이미 포함되어 있지만 여기에서는 모듈을 불러와서 사용하겠습니다."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras import optimizers\n",
"from tensorflow.keras import losses\n",
"from tensorflow.keras import metrics\n",
"\n",
"model.compile(optimizer=optimizers.RMSprop(lr=0.001),\n",
" loss=losses.binary_crossentropy,\n",
" metrics=[metrics.binary_accuracy])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 컴파일이 끝나면 모델을 학습시키면 됩니다. \n",
"512개의 샘플씩 미니 배치를 만들어 20번의 에포크 동안 훈련시킵니다. \n",
"위에서 만든 검증 세트를 사용해서 훈련하는 동안의 정확도를 측정할 수 있습니다."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train on 15000 samples, validate on 10000 samples\n",
"Epoch 1/20\n",
"15000/15000 [==============================] - 2s 143us/step - loss: 0.4974 - binary_accuracy: 0.7951 - val_loss: 0.3795 - val_binary_accuracy: 0.8655\n",
"Epoch 2/20\n",
"15000/15000 [==============================] - 1s 98us/step - loss: 0.2939 - binary_accuracy: 0.9038 - val_loss: 0.3006 - val_binary_accuracy: 0.8870\n",
"Epoch 3/20\n",
"15000/15000 [==============================] - 1s 89us/step - loss: 0.2146 - binary_accuracy: 0.9297 - val_loss: 0.2771 - val_binary_accuracy: 0.8904\n",
"Epoch 4/20\n",
"15000/15000 [==============================] - 1s 93us/step - loss: 0.1708 - binary_accuracy: 0.9437 - val_loss: 0.2768 - val_binary_accuracy: 0.8866\n",
"Epoch 5/20\n",
"15000/15000 [==============================] - 1s 96us/step - loss: 0.1357 - binary_accuracy: 0.9563 - val_loss: 0.2823 - val_binary_accuracy: 0.8878\n",
"Epoch 6/20\n",
"15000/15000 [==============================] - 1s 89us/step - loss: 0.1144 - binary_accuracy: 0.9631 - val_loss: 0.3021 - val_binary_accuracy: 0.8856\n",
"Epoch 7/20\n",
"15000/15000 [==============================] - 1s 82us/step - loss: 0.0944 - binary_accuracy: 0.9727 - val_loss: 0.3191 - val_binary_accuracy: 0.8815\n",
"Epoch 8/20\n",
"15000/15000 [==============================] - 1s 82us/step - loss: 0.0783 - binary_accuracy: 0.9780 - val_loss: 0.3450 - val_binary_accuracy: 0.8787\n",
"Epoch 9/20\n",
"15000/15000 [==============================] - 1s 87us/step - loss: 0.0653 - binary_accuracy: 0.9818 - val_loss: 0.3961 - val_binary_accuracy: 0.8691\n",
"Epoch 10/20\n",
"15000/15000 [==============================] - 1s 88us/step - loss: 0.0537 - binary_accuracy: 0.9859 - val_loss: 0.4247 - val_binary_accuracy: 0.8696\n",
"Epoch 11/20\n",
"15000/15000 [==============================] - 1s 94us/step - loss: 0.0428 - binary_accuracy: 0.9904 - val_loss: 0.4273 - val_binary_accuracy: 0.8740\n",
"Epoch 12/20\n",
"15000/15000 [==============================] - 1s 93us/step - loss: 0.0369 - binary_accuracy: 0.9911 - val_loss: 0.4510 - val_binary_accuracy: 0.8739\n",
"Epoch 13/20\n",
"15000/15000 [==============================] - 1s 90us/step - loss: 0.0307 - binary_accuracy: 0.9929 - val_loss: 0.4768 - val_binary_accuracy: 0.8733\n",
"Epoch 14/20\n",
"15000/15000 [==============================] - 1s 82us/step - loss: 0.0235 - binary_accuracy: 0.9945 - val_loss: 0.5131 - val_binary_accuracy: 0.8697\n",
"Epoch 15/20\n",
"15000/15000 [==============================] - 1s 81us/step - loss: 0.0191 - binary_accuracy: 0.9968 - val_loss: 0.5399 - val_binary_accuracy: 0.8707\n",
"Epoch 16/20\n",
"15000/15000 [==============================] - 1s 81us/step - loss: 0.0166 - binary_accuracy: 0.9969 - val_loss: 0.5722 - val_binary_accuracy: 0.8685\n",
"Epoch 17/20\n",
"15000/15000 [==============================] - 1s 81us/step - loss: 0.0089 - binary_accuracy: 0.9995 - val_loss: 0.6328 - val_binary_accuracy: 0.8642\n",
"Epoch 18/20\n",
"15000/15000 [==============================] - 1s 82us/step - loss: 0.0100 - binary_accuracy: 0.9991 - val_loss: 0.6419 - val_binary_accuracy: 0.8669\n",
"Epoch 19/20\n",
"15000/15000 [==============================] - 1s 81us/step - loss: 0.0096 - binary_accuracy: 0.9985 - val_loss: 0.6722 - val_binary_accuracy: 0.8666\n",
"Epoch 20/20\n",
"15000/15000 [==============================] - 1s 83us/step - loss: 0.0041 - binary_accuracy: 0.9999 - val_loss: 0.7095 - val_binary_accuracy: 0.8639\n"
]
}
],
"source": [
"history = model.fit(partial_x_train,\n",
" partial_y_train,\n",
" epochs=20,\n",
" batch_size=512,\n",
" validation_data=(x_val, y_val))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`model.fit()` 메서드는 `History` 객체를 반환합니다. 이 객체는 훈련하는 동안 발생한 모든 정보를 담고 있는 딕셔너리인 history 속성을 가지고 있습니다."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['val_loss', 'val_binary_accuracy', 'loss', 'binary_accuracy'])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"history_dict = history.history\n",
"history_dict.keys()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"matplotlib을 통해서 훈련과 검증 손실, 훈련과 검증 정확도를 그려보도록 하겠습니다"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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1luMHTuWk046iVmzZtGnTx/mzJnDIYccssuxiqTD11+HqSbeffebb/+LF4cmoeTJflu2hC5d4LTTws/SW/v2mZmjKNtqXVLIliZNmjBgwAAuvPDCHTqYN27cyHe+8x0aNGjA3LlzWblyZaXHOeaYY3j44YcZOHAgb7/9NgsXLgTCtNt77rknzZo145NPPmH27Nn0798fgKZNm/LZZ599q/mob9++jBo1irFjx+LuPPHEEzz00ENVfm/NmjWjRYsWvPTSS/Tt25eHHnqIfv36sX37dj766CMGDBjA0UcfzYwZM9i8eTPFxcV069aNbt26MX/+fN59910lBcmqf/4ThgwJ6x6X6tAhnOz79dvx5F/m36jOUVJIoxEjRnDqqafuMBJp5MiRnHzyyXTr1o38/PydnhzHjBnDBRdcQJcuXejSpUuixtGjRw8OP/xwDjnkENq3b7/DtNujR49m8ODB7LvvvsydOzexv2fPnowaNYpe0fJNF198MYcffnilTUUV+dOf/sRll13Gli1b2G+//bj//vvZtm0b55xzDhs3bsTdufLKK2nevDm//OUvmTt3LvXq1aNr166JVeREsmH+fDj5ZGjXDv7wh3DiP+ggiEaESxmaOluyQr8zyYS33w41gWbN4KWXoG3bbEeUPalOnV0HWshEpC5atixcRNaoEfz973U7IVSFmo9EpNYpKgprFmzdGtYv2G+/bEdUc9SapFC6bKTkvprWZCk1y9q1oYbw6afwwgthDWRJXa1oPmrUqBHFxcU62dQA7k5xcbEuaJNYbNgQpp9YuRKeeQaicRpSBbHWFMxsMHAnUB+4x90nllPmTOAGwIE33f3sqr5Ou3btKCoqYt26ddWMWDKhUaNGtGvXLtthSC3z+edw0klhDqKnnoKjj852RDVTbEnBzOoDU4DvA0XAfDOb6e7vJJU5EPgfoI+7f2pm39mV12rQoAGdO3dOR9giUgN99RWceiq8+io8+mioLciuibP5qBewzN2Xu/vXwAxgaJkylwBT3P1TAHdfG2M8IlILlZTA8OHwt7/BfffB6adnO6KaLc6k0Bb4KOl+UbQv2UHAQWb2ipm9GjU3fYuZjTazQjMrVBORiJTavh0uvBD++leYPDksciPVk+2O5t2AA4H+wAjgbjP71kIA7j7N3fPdPb9169YZDlFEcpE7XHEFPPQQTJgQJquT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\n",
"text/plain": [
"