줘이리의 인생적기

[tensorflow 18] 다항분류 본문

공부/tensorflow

[tensorflow 18] 다항분류

줘이리 2021. 5. 20. 00:30
728x90

앞서 공부했던 이항 분류는 범주의 수가 2개 였었죠

 

이번에는 다항분류를 공부해볼텐데, 다항 분류는 범주의 수가 3개 이상인 경우입니다.

 

wine 데이터셋에서 quality를 가지고 다항분류를 해보겠습니다.

 

import pandas as pd

#white wine, red 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=';')

#wine 데이터 합치기
wine = pd.concat([red, white])

#quality 속성 카운트
print(wine['quality'].value_counts())

3~9등급의 quality가 분포되어 있는것을 확인할 수 있습니다.

 

3, 4, 5등급은 나쁨, 제일 많은 6등급은 보통, 7, 8, 9등급은 좋음으로 분류해보겠습니다.

 

import pandas as pd

#white wine, red 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=';')

#wine 데이터 합치기
wine = pd.concat([red, white])

#quality 속성 카운트
print("quality 속성")
print(wine['quality'].value_counts())

#특정 데이터 인덱스 골라내기
wine.loc[wine['quality']<=5, 'new_quality'] = 0
wine.loc[wine['quality']==6, 'new_quality'] = 1
wine.loc[wine['quality']>=7, 'new_quality'] = 2

#new quality 속성 카운트
print("new_quality 속성")
print(wine['new_quality'].value_counts())

 

loc를 이용하여 데이터 인덱스를 골라내고 새로운 속성을 추가하여 분류 하였습니다.

 

이제 제법 데이터 분포가 적당해보이네요

 

이제 기존 quality 속성을 삭제하고, 정규화 및 train data, test data로 나누어보겠습니다.

 

내친김에 학습과 시각화, 평가까지 마무리해보겠습니다

 

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

#white wine, red 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['type'] = 0
white['type'] = 1

#wine 데이터 합치기
wine = pd.concat([red, white])

#quality 속성 카운트
print("quality 속성")
print(wine['quality'].value_counts())

#특정 데이터 인덱스 골라내기
wine.loc[wine['quality']<=5, 'new_quality'] = 0
wine.loc[wine['quality']==6, 'new_quality'] = 1
wine.loc[wine['quality']>=7, 'new_quality'] = 2

#new quality 속성 카운트
print("new_quality 속성")
print(wine['new_quality'].value_counts())

#quality 삭제
del wine['quality']

#정규화
wine_norm = (wine - wine.min()) / (wine.max() - wine.min())
wine_shuffle = wine_norm.sample(frac=1)
wine_np = wine_shuffle.to_numpy()

#data 나누기
train_idx = int(len(wine_np) * 0.8)
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]
train_Y = tf.keras.utils.to_categorical(train_Y, num_classes=3)
test_Y = tf.keras.utils.to_categorical(test_Y, num_classes=3)

#학습
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=3, activation='softmax')
])

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()

#평가
model.evaluate(test_X, test_Y)

 

 

평가는 80.3퍼센트로 매우 정확한 수치는 아니네요

 

위와 같은 파라미터값들로 진행을 했을 때는 이정도의 loss값과 accuracy가 나왔습니다.

 

좀 더 좋은 값을 내기 위해 조정작업이 필요합니다. 조정하는 작업들을 다음 포스팅에서 진행해보겠습니다.