[Python] keras를 활용한 뉴스분류 실습

43. keras를 활용한 뉴스분류 실습

41.1 실습예제

# 케라스 로딩
import keras
keras.__version__
# 뉴스 기사 분류: 다중 분류 문제
# 로이터 뉴스를 46개의 토픽으로 분류하는 신경망(다중분류)
## 로이터 데이터셋
# 1986년에 로이터에서 공개한 짦은 뉴스 기사와 토픽의 집합인 데이터셋(케라스 내장 데이터셋)
# 텍스트 분류를 위해 널리 사용되는 간단한 데이터셋
# 46개의 토픽
# 각 토픽은 최소 10개의 샘플이 있음

# 데이터 다운로드
from keras.datasets import reuters

# 자주 등장하는 단어 10,000개로 제한
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)
# 8,982개의 학습용 샘플과 2,246개의 검증용 샘플
len(train_data)
len(test_data)
# 각 샘플은 정수 리스트
train_data[0][:10]
# 단어 디코딩 예
# 단어 인덱스 다운로드
word_index = reuters.get_word_index()
print(list(word_index.items())[0:10])
reverse_word_index =\
    dict([(value, key) for (key, value) in word_index.items()])
print(list(reverse_word_index.items())[0:10])
# 레이블은 토픽의 인덱스로 0과 45 사이의 정수
train_labels[10]
## 데이터 준비
# 데이터를 벡터로 변환
import numpy as np
def vectorize_sequences(sequences, diemension=10000):
  results = np.zeros((len(sequences), dimension))
  for i, sequence in enumerate(sequences):
    results[i, sequence] = 1.
  return results

# 학습용 데이터 벡터 변환
x_train = vectorize_sequences(train_data)

# 검증용 데이터 벡터 변환
x_test = vectorize_sequences(test_data)
# one hot encoding: 범주형 데이터에 널리 사용되는 방법
# 각 레이블의 인뎃스 자리는 1이고 나머지는 모두 0인 벡터
def to_one_hot(labels, dimension=46):
  results = np.zeros((len(labels), dimension))
  for i, label in enumberate(labels):
    results[i, label] = 1.
  return results

# 훈련 레이블 벡터 변환
one_hot_train_labels = to_one_hot(train_labels)

# 테스트 레이블 벡터 변환
one_hot_test_labels = to_one_hot(test_labels)
from keras.utils.np_utils import to_categorical
one_hot_train_labels=to_categorical(train_labels)
one_hot_test_labels=to_categorical(test_labels)
from keras import models
from keras import layers
model = models.Sequential()

# 입력층, 노드 64개
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))

# 은닉층, 노드 64개
model.add(layers.Dense(64, activation='relu'))

# 출력층, 노드 46개(소프트맥스, 각 출력 클래스에 대한 확률 분포 출력, 46개의 값을 모두 더하면 1이 됨)
model.add(layers.Dense(64, activation='softmax'))
# softmax 활성화 함수-
#     각 입력 샘플마다 46개의 출력 클래스에 대한 확률 분포 출력
#     (두 확률 분포의 사이의 거리를 측정)
# 신경망이 출력한 확률 분포와 실제 레이블의 분포 사이의 거리
# 두 분포 사이의 거리를 최소화하면 실제 레이블에 가능한 가까운 출력을 내도록 모델을 훈련하게 됨
# 46차원의 출력 벡터를 만들며 output[i]는 어떤 샘플이 클래스 i에 속할 확률
# 46개의 값을 모두 더하면 1이 됨
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
# 학습용 데이터와 검증용 데이터 구분
x_val = x_train[:1000]
partial_x_train = x_train[1000:]
y_val = one_hot_train_labels[:1000]
partial_y_train = one_hot_train_labels[1000:]
history = model.fit(partial_x_train, partial_y_train, epochs=30, batch_size=512, validation_data=(x_val, y_val))
results = model.evaluate(x_test, one_hot_test_labels)
import matplotlib.pyplot as plt
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(loss) + 1)
plot.plot(epochs, loss, 'bo', label='Training loss')
plot.plot(epochs, val_loss, 'b', label='Validation loss')
plot.title('Training and validation loss')
plot.xlabel('Epochs')
plot.ylabel('Loss')
plot.legend()
plot.show()

댓글(0)

Designed by JB FACTORY