줘이리의 인생적기

[tensorflow 17] 이항 분류02 본문

공부/tensorflow

[tensorflow 17] 이항 분류02

줘이리 2021. 5. 18. 22:00
728x90

저번 시간에 train, test 셋으로 나누는 작업까지 해보았습니다.

 

다음 작업은 정답 행렬을 원-핫 인코딩 방식으로 바꾸는 함수를 사용하는 것입니다.

 

https://wikidocs.net/22647

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

원-핫인코딩에 관한 내용은 이 자료를 이용하시면 되겠습니다.

 

그 이후 모델을 만들고, complie 후 네트워크 학습을 시키도록 하겠습니다

 

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

#wine 데이터 받아오기
red = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv', sep=';')
white = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv', sep=';')

#red wine 일 때 type 0 속성 추가
red['type'] = 0
#white wine 일 때 type 1 속성 추가
white['type'] = 1

#wine 확인
print("red wine 데이터")
print(red.head())
print("white wine 데이터")
print(white.head())

#pandas cancat으로 두 와인 데이터 합치기
wine = pd.concat([red, white])
print("wine 데이터 describe")
print(wine.describe())

#red wine, white wine 갯수 비교
print(wine['type'].value_counts())

#info 함수로 데이터에 잘못된 정보들이 있는가 확인
#정규화를 위해 필수적인 작업
print(wine.info())

#정규화
wine_norm = (wine - wine.min()) / (wine.max() - wine.min())

#데이터 섞기, farc=1은 모든 데이터를 섞겠다는 뜻의 인자
wine_shuffle = wine_norm.sample(frac=1)
print("데이터 랜덤 섞기")
print(wine_shuffle.head())

#numpy로 변환
wine_np = wine_shuffle.to_numpy()
print(wine_np[:5])

#80퍼센트 데이터를 train
train_idx = int(len(wine_np) * 0.8)

#X는 12개의 속성, Y는 추가한 wine의 type 정보
train_X, train_Y = wine_np[:train_idx, :-1], wine_np[:train_idx, -1]
test_X, test_Y = wine_np[train_idx:, :-1], wine_np[train_idx:, -1]

print("train_X[0] = ", train_X[0])
print("train_Y[0] = ", train_Y[0])
print("test_X[0] = ", test_X[0])
print("test_Y[0] = ", test_Y[0])

#num_classes는 wine, white 2개이기 때문에 2
train_Y = tf.keras.utils.to_categorical(train_Y, num_classes=2)
test_Y = tf.keras.utils.to_categorical(test_Y, num_classes=2)
print("train_Y[0] = ", train_Y[0])
print("test_Y[0] = ", test_Y[0])

#모델 만들기
model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=48, activation='relu', input_shape=(12,)),
    tf.keras.layers.Dense(units=24, activation='relu'),
    tf.keras.layers.Dense(units=12, activation='relu'),
    tf.keras.layers.Dense(units=2, activation='softmax')
])
#마지막 layers는 2개의 분류를 하기 때문에 units=2로 지정

#Adam을 사용하였고, accuracy 인자 추가
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.07), loss='categorical_crossentropy', metrics=['accuracy'])

#네트워크 학습
history = model.fit(train_X, train_Y, epochs=25, batch_size=32, validation_split=0.25)

#학습 시각화
plt.figure(figsize=(12,4))

#loss 시각화
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], 'b-', label='loss')
plt.plot(history.history['val_loss'], 'r--', label='val_loss')
plt.xlabel('Epoch')
plt.legend()

#accuracy 시각화
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], 'g-', label='accuracy')
plt.plot(history.history['val_accuracy'], 'k--', label='val_accuracy')
plt.xlabel('Epoch')
plt.ylim(0.7, 1)
plt.legend()

plt.show()

#test 평가
model.evaluate(test_X, test_Y)

일부 설명이 필요한 함수들은 주석으로 설명을 했지만

 

softmax 활성화 함수, crossentropy 등은 나중에 자세하게 다루어 보겠습니다.

 

loss값은 0.0438, accuracy는 0.9892로 잘 나왔습니다.

 

이제 테스트 값을 볼까요

99.5%확률로 매우 정확하게 red wine과 white wine을 분류하는 것을 확인할 수 있습니다.