Decision Tree를 이용한 와인데이터 분석

Jungmin·2022년 12월 13일

머신러닝

목록 보기
3/10

1. 데이터 불러오기 & 탐색

import pandas as pd

red_url = "https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/winequality-red.csv"
white_url = "https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/winequality-white.csv"

red_wine = pd.read_csv(red_url, sep=';')
white_wine = pd.read_csv(white_url, sep=';')
red_wine.head()
fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality
0 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5
1 7.8 0.88 0.00 2.6 0.098 25.0 67.0 0.9968 3.20 0.68 9.8 5
2 7.8 0.76 0.04 2.3 0.092 15.0 54.0 0.9970 3.26 0.65 9.8 5
3 11.2 0.28 0.56 1.9 0.075 17.0 60.0 0.9980 3.16 0.58 9.8 6
4 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5
white_wine.head()
fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality
0 7.0 0.27 0.36 20.7 0.045 45.0 170.0 1.0010 3.00 0.45 8.8 6
1 6.3 0.30 0.34 1.6 0.049 14.0 132.0 0.9940 3.30 0.49 9.5 6
2 8.1 0.28 0.40 6.9 0.050 30.0 97.0 0.9951 3.26 0.44 10.1 6
3 7.2 0.23 0.32 8.5 0.058 47.0 186.0 0.9956 3.19 0.40 9.9 6
4 7.2 0.23 0.32 8.5 0.058 47.0 186.0 0.9956 3.19 0.40 9.9 6
# red, white 두 데이터 합치기 
red_wine['color']= 1.
white_wine['color'] = 0.

wine = pd.concat([red_wine, white_wine])
wine['quality'].unique()
array([5, 6, 7, 4, 8, 3, 9], dtype=int64)
wine['quality'].value_counts()
6    2836
5    2138
7    1079
4     216
8     193
3      30
9       5
Name: quality, dtype: int64
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)
(array([0., 1.]), array([3913, 1284], dtype=int64))
# 훈련용과 테스트용이 레드/화이트에 따라 어느정도 구분이 되는지 확인
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()

# Decision Tree 훈련
from sklearn.tree import DecisionTreeClassifier

wine_tree = DecisionTreeClassifier(max_depth=2, random_state=13)
wine_tree.fit(X_train,y_train)

# 학습결과
from sklearn.metrics import accuracy_score

y_pred_tr = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train,y_pred_tr))
print('test Acc : ', accuracy_score(y_test,y_pred_test))
Train Acc :  0.9553588608812776
test Acc :  0.9569230769230769

와인데이터 몇개 항목의 boxplot 그려보기 데이터

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

from sklearn.preprocessing import MinMaxScaler, StandardScaler

ss = StandardScaler()
mms = MinMaxScaler()

ss.fit(X)
mms.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)

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

# StandardScaler  : 평균을 0. 표준편차를 1에 맞추기 
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()

# MinMax 확인 
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_train = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train,y_pred_train))
print('Test Acc : ', accuracy_score(y_test,y_pred_test))

Train Acc :  0.9553588608812776
Test Acc :  0.9569230769230769

# 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_train = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train,y_pred_train))
print('Test Acc : ', accuracy_score(y_test,y_pred_test))
Train Acc :  0.9553588608812776
Test Acc :  0.9569230769230769

결정나무는 화이트/레드 와인 구분을 어떻게 하는가?

import graphviz
from graphviz import Source
from sklearn.tree import export_graphviz

Source(export_graphviz(wine_tree, feature_names=X_train.columns,
                      class_names=['W','R'],
                      rounded=True, filled=True))    

# 레드와인과 화이트와인 구분하는 중요한 특성
dict(zip(X_train.columns, wine_tree.feature_importances_))
# max_depth를 높이면 위의 수치도 변함
{'fixed acidity': 0.0,
 'volatile acidity': 0.0,
 'citric acid': 0.0,
 'residual sugar': 0.0,
 'chlorides': 0.24230360549660776,
 'free sulfur dioxide': 0.0,
 'total sulfur dioxide': 0.7576963945033922,
 'density': 0.0,
 'pH': 0.0,
 'sulphates': 0.0,
 'alcohol': 0.0,
 'quality': 0.0}

✔ 이진분류

quality컬럼 이진화

wine['taste'] = [1. if grade > 5 else 0. for grade in wine['quality']]
wine.head()
fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality color taste
0 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5 1.0 0.0
1 7.8 0.88 0.00 2.6 0.098 25.0 67.0 0.9968 3.20 0.68 9.8 5 1.0 0.0
2 7.8 0.76 0.04 2.3 0.092 15.0 54.0 0.9970 3.26 0.65 9.8 5 1.0 0.0
3 11.2 0.28 0.56 1.9 0.075 17.0 60.0 0.9980 3.16 0.58 9.8 6 1.0 1.0
4 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5 1.0 0.0
# 레드/화이트 분류와 동일 과정을 거치기 
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)

y_pred_train = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train,y_pred_train))
print('Test Acc : ', accuracy_score(y_test,y_pred_test))
Train Acc :  1.0
Test Acc :  1.0
import matplotlib.pyplot as plt
import sklearn.tree as tree

plt.figure(figsize=(12,8))
tree.plot_tree(wine_tree, feature_names=X.columns);

# taste 와 함께 quality컬럼도 같이 제거해주어야 함.
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_train = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train,y_pred_train))
print('Test Acc : ', accuracy_score(y_test,y_pred_test))
Train Acc :  0.7294593034442948
Test Acc :  0.7161538461538461
plt.figure(figsize=(12,8))
tree.plot_tree(wine_tree, feature_names=X.columns,
            rounded=True,
            filled=True)
            
plt.show()

profile
데이터분석 스터디노트🧐✍️

0개의 댓글