이전에 실습했던 와인 데이터를 이용하여 모델을 학습하고, 와인을 다항 분류(품질 분류) 해보겠습니다.
이항 분류와의 차이는 출력층의 활성화 함수가 Softmax 라는 점입니다.
코드는 아래와 같습니다.
import tensorflow as tf
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 와인 데이터셋 불러오기
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=';')
print(red.head())
print(white.head())
# 와인 데이터셋 합치기
print(red.head(2))
print(white.head(2))
wine = pd.concat([red, white])
print(wine['quality'].describe())
print(wine['quality'].value_counts())
# 품질 히스토그램
plt.hist(wine['quality'], bins=7, rwidth=0.8)
plt.show()
# 품질을 3개의 범주(좋음, 보통, 나쁨)로 재분류
wine.loc[wine['quality'] <= 5, 'new_quality'] = 0
wine.loc[wine['quality'] == 6, 'new_quality'] = 1
wine.loc[wine['quality'] >= 7, 'new_quality'] = 2
print(wine['new_quality'].describe())
print(wine['new_quality'].value_counts())
# 데이터 정규화 및 train, test 데이터 분리
del wine['quality']
wine_backup = wine.copy()
wine_norm = (wine - wine.min()) / (wine.max() - wine.min())
wine_norm['new_quality'] = wine_backup['new_quality']
wine_shuffle = wine_norm.sample(frac=1)
wine_np = wine_shuffle.to_numpy()
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=(11,)),
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.001), loss='categorical_crossentropy', metrics=['accuracy'])
history = model.fit(train_X, train_Y, epochs=25, batch_size=1, validation_split=0.25)
# 다항 분류 모델 학습 결과 시각화
plt.figure(figsize=(12, 4))
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()
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.5, 0.7)
plt.legend()
plt.show()
# 다항 분류 모델 평가
model.evaluate(test_X, test_Y)
코드를 분석해보면,
먼저 describe()를 이용하여 품질 데이터('quality')의 비율을 확인합니다.
히스토그램을 이용해 시각화 했을 때, 'quality'의 최솟값은3, 최댓값은 9라는 것과 항목 수가 균일하지 않다는 것을 확인할 수 있습니다.
모든 범주에 대한 세세한 분류는 어려울 것으로 보이기 때문에, 크게 세 가지로 재분류 합니다.
wine.loc[wine['quality'] <= 5, 'new_quality'] = 0
wine.loc[wine['quality'] == 6, 'new_quality'] = 1
wine.loc[wine['quality'] >= 7, 'new_quality'] = 2
위 코드는
3 <= wine['quality'] <= 5 일 때, wine['new_quality'] = 0 (나쁨)
wine['quality'] == 6 일 때, wine['new_quality'] = 1 (보통)
7 <= wine['quality'] <= 9 일 때, wine['new_quality'] = 2 (좋음)
를 할당 합니다.
기존에 있던 wine['quality']를 제거하고 (제거 하지 않으면 의미 없습니다.) 데이터를 표준화합니다.
훈련 데이터와 테스트 데이터를 80:20 비율로 분할합니다.
fit()을 이용하여 학습하고, 손실도와 정확도를 시각화합니다.
테스트 데이터를 기반으로 evaluate()를 이용하여 모델을 평가합니다.
데이터의 구성이 균일하지 않기 때문에 정확도는 약 60% 밖에 나오지 않았습니다.
더 좋은 성과를 내기 위해서는 뉴런 또는 계층의 수를 키워보거나 학습률을 조정하는 등 하이퍼 파라미터 조정을 해야 합니다.
'AI > TensorFlow & PyTorch' 카테고리의 다른 글
[TensorFlow] This is probably because cuDNN failed to initialize 오류 (0) | 2021.04.06 |
---|---|
[TensorFlow] 텐서플로우(TensorFlow 2.x) Fashion MNIST (0) | 2021.03.05 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 와인 데이터 이항 분류 (0) | 2021.03.05 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 로지스틱 회귀 예제 (0) | 2021.03.05 |
[TensorFlow] 텐서플로우(TensorFlow 2.x) 보스턴 주택 가격 예측 (0) | 2021.03.02 |