영화 리뷰를 사용한 텍스트 분류
영화 리뷰 (review) 텍스트를 긍정 (positive) 또는 부정 (negative)으로 분류한다. 이 예제는 이진 (binary) 또는 클래스 (class)가 두 개인- 분류 문제이다. 이진 분류는 머신러닝에서 중요하고 널리 사용된다.
여기에서는 인터넷 영화 데이터베이스 (Internet Movie Database)에서 수집한 50,000개의 영화 리뷰 텍스트를 담은 IMDB 데이터셋을 사용한다. 25,000개 리뷰는 훈련용으로, 25,000개는 테스트용으로 나뉘어져 있다. 훈련 세트와 테스트 세트의 클래스는 균형이 잡혀 있다. 즉 긍정적인 리뷰와 부정적인 리뷰의 개수가 동일하다.
모델을 만들고 훈련하기 위해 텐서플로의 고수준 파이썬 API인 tf.keras를 사용한다. tf.keras를 사용한 고급 텍스트 분류 튜토리얼은 MLCC 텍스트 분류 가이드를 참고하면 된다.
import tensorflow as tf
from tensorflow import keras
import numpy as np
print(tf.__version__)
IMDB 데이터셋 다운로드
IMDB 데이터셋은 텐서플로와 함께 제공된다. 리뷰 (단어의 시퀀스 (sequence))는 미리 전처리해서 정수 시퀀스로 변환되어 있다. 각 정수는 어휘 사전에 있는 특정 단어를 의미한다.
다음 코드는 IMDB 데이터셋을 컴퓨터에 다운로드한다.
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
매개변수 num_words=10000은 훈련 데이터에서 가장 많이 등장하는 상위 10,000개의 단어를 선택한다. 데이터 크기를 적당하게 유지하기 위해 드물에 등장하는 단어는 제외한다.
데이터 탐색
이 데이터셋의 샘플은 전처리된 정수 배열이다. 이 정수는 영화 리뷰에 나오는 단어를 나타낸다. 레이블 (label)은 정수 0 또는 1입니다. 0은 부정적인 리뷰이고 1은 긍정적인 리뷰이다.
print("훈련 샘플: {}, 레이블: {}".format(len(train_data), len(train_labels)))
훈련 샘플: 25000, 레이블: 25000
리뷰 텍스트는 어휘 사전의 특정 단어를 나타내는 정수로 변환되어 있다. 첫 번째 리뷰를 확인한다.
print(train_data[0])
[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]
영화 리뷰들은 길이가 다르다. 다음 코드는 첫 번째 리뷰와 두 번째 리뷰에서 단어의 개수를 출력한다. 신경망의 입력은 길이가 같아야 하기 때문에 나중에 이 문제를 해결해야 한다.
len(train_data[0]), len(train_data[1])
(218, 189)
정수를 단어로 다시 변환하기
정수를 다시 텍스트로 변환하는 방법이 있다면 유용하다. 여기에서는 정수와 문자열을 매핑한 딕셔너리 (dictionary) 객체에 질의하는 헬퍼 (helper) 함수를 만든다.
# 단어와 정수 인덱스를 매핑한 딕셔너리
word_index = imdb.get_word_index()
# 처음 몇 개 인덱스는 사전에 정의되어 있습니다
word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
def decode_review(text):
return ' '.join([reverse_word_index.get(i, '?') for i in text])
이제 decode_review 함수를 사용해 첫 번째 리뷰 텍스트를 출력할 수 있다.
decode_review(train_data[0])
데이터 준비
리뷰-정수 배열은 신경망에 주입하기 전에 텐서로 변환되어야 한다. 변환하는 방법에는 몇 가지가 있다.
|
여기서는 두 번째 방식을 사용한다. 영화 리뷰의 길이가 같아야 하므로 pad_sequences 함수를 사용해 길이를 맞춘다.
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
샘플의 길이를 확인한다.
len(train_data[0]), len(train_data[1])
(256, 256)
(패딩된) 첫 번째 리뷰 내용을 확인한다.
print(train_data[0])
[ 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 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0]
'DNN with Keras > TensorFlow' 카테고리의 다른 글
[TensorFlow] 회귀 (Regression) (1) (0) | 2022.06.15 |
---|---|
[TensorFlow] 기본 분류 (텍스트 분류) (2) (0) | 2022.06.15 |
[TensorFlow] 기본 분류 (이미지 분류) (2) (0) | 2022.06.15 |
[TensorFlow] 기본 분류 (이미지 분류) (1) (0) | 2022.06.15 |
[TensorFlow] TensorSpace (0) | 2021.12.23 |