◾와인 데이터 분석
1. 와인 데이터 개요
- Wine : 분류 문제에서 Iris 꽃 데이터만큼 알려지진 않았지만 많이 사요오딘다.
- 인류 역사상 최초의 술로 알려져있다.
- 기원전 7000년 무렵 조지아-아르메이나-터키 동북부(코카서스)에서 흔적 발견
- 플라톤 : '신이 인간에게 내려준 선물 중 포도주만큼 위대한 가치를 지닌 것은 없다.'
- 와인 맛 분류 : 링크
- 데이터 : 링크
- 레드 와인 품질 데이터(다운로드) : 링크
- 화이트 와인 품질 데이터(다운로드) : 링크
import pandas as pd
red_wine = pd.read_csv('winequality-red.csv', sep=';')
white_wine = pd.read_csv('winequality-white.csv', sep=';')
- 두 데이터의 구조는 동일함을 확인
- 컬럼의 종류
- fixed acidity : 고정 산도
- volatile acidity : 휘발성 산도
- citric acid : 시트르산
- residual sugar : 잔류 당분
- chlorides : 염화물
- free sulfur dioxide : 자유 이산화황
- total sulfur dioxide : 총 이산화황
- density : 밀도
- pH
- sulphates : 황산염
- alcohol
- quality : 0 ~ 10(높을 수록 좋은 품질)
red_wine['color'] = 1.
white_wine['color'] = 0.
wine = pd.concat([red_wine, white_wine])
wine.reset_index(drop=True, inplace=True)
wine.info()
wine['quality'].unique()
wine['quality'].value_counts()
import plotly.express as px
fig = px.histogram(wine, x='quality')
fig.show()
- 화이트 와인의 수가 많은을 확인
- 레드 와인은 등급이 조금 작은 것을 확인
fig = px.histogram(wine, x='quality', color='color')
fig.show()
2. 레드와인, 화이트 와인 분류
x = wine.drop(['color'], axis=1)
y = wine['color']
from sklearn.model_selection import train_test_split
import numpy as np
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=13)
np.unique(y_train, return_counts=True)
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Histogram(x=x_train['quality'], name='Train'))
fig.add_trace(go.Histogram(x=x_test['quality'], name='Test'))
fig.update_layout(barmode='overlay')
fig.update_traces(opacity=0.75)
fig.show()
- 정확성 측면에서 훈련값과 테스트값이 비슷하다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
wine_tree = DecisionTreeClassifier(max_depth = 2, random_state=13)
wine_tree.fit(x_train, y_train)
y_pred_tr = wine_tree.predict(x_train)
y_pred_test = wine_tree.predict(x_test)
- (total sulfur dioxide : 총 이산화황)를 중요하게 판단한다.
- chlorides : 염화물
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(12, 8))
plot_tree(wine_tree)
plt.show()
3. 데이터 전처리
fig = go.Figure()
fig.add_trace(go.Box(y=x['fixed acidity'], name='fixed acidity'))
fig.add_trace(go.Box(y=x['chlorides'], name='chlorides'))
fig.add_trace(go.Box(y=x['quality'], name='quality'))
fig.show()
from sklearn.preprocessing import MinMaxScaler, StandardScaler
MMS = MinMaxScaler()
SS = StandardScaler()
MMS.fit(x)
SS.fit(x)
x_ss = SS.transform(x)
x_mms = MMS.transform(x)
x_ss_pd = pd.DataFrame(x_ss, columns=x.columns)
x_mms_pd = pd.DataFrame(x_mms, columns=x.columns)
fig = go.Figure()
fig.add_trace(go.Box(y=x_mms_pd['fixed acidity'], name='fixed acidity'))
fig.add_trace(go.Box(y=x_mms_pd['chlorides'], name='chlorides'))
fig.add_trace(go.Box(y=x_mms_pd['quality'], name='quality'))
fig.show()
fig = go.Figure()
fig.add_trace(go.Box(y=x_ss_pd['fixed acidity'], name='fixed acidity'))
fig.add_trace(go.Box(y=x_ss_pd['chlorides'], name='chlorides'))
fig.add_trace(go.Box(y=x_ss_pd['quality'], name='quality'))
fig.show()
- MinMaxScaler를 이용한 학습
- 결정나무에는 거의 효과가 없다.
x_train, x_test, y_train, y_test = train_test_split(x_mms_pd, y, test_size=0.2, random_state=13)
wine_tree = DecisionTreeClassifier(max_depth = 2, random_state=13)
wine_tree.fit(x_train, y_train)
y_pred_tr = wine_tree.predict(x_train)
y_pred_test = wine_tree.predict(x_test)
print('Train Acc : {}'.format(accuracy_score(y_train, y_pred_tr)))
print('Train Acc : {}'.format(accuracy_score(y_test, y_pred_test)))
- StandardScaler를 이용한 학습
- 결정나무에는 거의 효과가 없다.
x_train, x_test, y_train, y_test = train_test_split(x_ss_pd, y, test_size=0.2, random_state=13)
wine_tree = DecisionTreeClassifier(max_depth = 2, random_state=13)
wine_tree.fit(x_train, y_train)
y_pred_tr = wine_tree.predict(x_train)
y_pred_test = wine_tree.predict(x_test)
print('Train Acc : {}'.format(accuracy_score(y_train, y_pred_tr)))
print('Train Acc : {}'.format(accuracy_score(y_test, y_pred_test)))
dict(zip(x_train.columns, wine_tree.feature_importances_))
4. 맛의 이진 분류
- quality 컬럼 이진화
- 5 이상 : 1(맛있다)
- 5 미만 : 0(맛있지 않다)
wine['taste'] = [1. if grade > 5 else 0. for grade in wine['quality']]
wine.info()
X = wine.drop(['taste'], axis=1)
y = wine['taste']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 13)
wine_tree = DecisionTreeClassifier(max_depth=2, random_state = 13)
wine_tree.fit(X_train, y_train)
- 정확성이 1이 나온다.
- 왜 1이 나왔을까??
- quality 컬럼을 사용하여 100%로 구분하였다.
- quality 컬럼을 사용하여 taste 컬럼을 만들었는데 quality 컬럼을 지우지 않아 정확성이 100%로 나오게 되었다.
- taste를 만드는데 사용한 quality도 제거한 뒤 수행해야한다.
y_pred_tr = wine_tree.predict(X_train)
y_pred_Test = wine_tree.predict(X_test)
print('Train Acc : {}'.format(accuracy_score(y_train, y_pred_tr)))
print('Test Acc : {}'.format(accuracy_score(y_test, y_pred_Test)))
plt.figure(figsize=(12, 8))
plot_tree(wine_tree, feature_names=X.columns)
plt.show()
X = wine.drop(['taste', 'quality'], axis=1)
y = wine['taste']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 13)
wine_tree = DecisionTreeClassifier(max_depth=2, random_state = 13)
wine_tree.fit(X_train, y_train)
y_pred_tr = wine_tree.predict(X_train)
y_pred_Test = wine_tree.predict(X_test)
print('Train Acc : {}'.format(accuracy_score(y_train, y_pred_tr)))
print('Test Acc : {}'.format(accuracy_score(y_test, y_pred_Test)))
- alcohol과 volatile acidity, free sulfur dioxide 컬럼을 사용하였다.
- alcohol이 높으면 맛잇는 것일까?
plt.figure(figsize=(12, 8))
plot_tree(wine_tree, feature_names=X.columns)
plt.show()