ML_wine

이병찬·2024년 3월 14일

ML

목록 보기
4/14

데이터 불러오기 및 합치기

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

white_wine.head()

red_wine['color'] = 1
white_wine['color'] = 0

wine = pd.concat([red_wine, white_wine])
wine.info

quality의 속성 및 분포도 확인

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

레드/화이트 와인 분류기_데이터분리(훈련용, 테스트용) 및 시각화 확인

X = wine.drop(['color'], axis = 1) # feature
y = wine['color'] # label

# color에 따라 와인을 구별할 것으로 feature 데이터 에서는 color 컬럼을 삭제하고 label 데이터에서는 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') # overlay : 겹치도록 설정
fig.update_traces(opacity = 0.75) # opacity : 투명도
fig.show()

결정나무(DecisionTree) 훈련 및 학습 결과

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) # train 예측
y_pred_test = wine_tree.predict(X_test) # test 예측

print('Train Acc : ', accuracy_score(y_train, y_pred_tr))
print('Test Acc : ', accuracy_score(y_test, y_pred_test))
# accuracy_score(정답데이터, 예측데이터) : 정답데이터와 예측데이터를 비교하여 정확도를 계산해달라는 명령어

와인데이터의 특성 확인(boxplot)

X.columns

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()
  • 컬럼들의 범위의 격차가 심하면 교육이 제대로 안될 수도 있다
  • 최대/최소 범위가 다르고 평균과 분산이 각각 다르다
  • 특성의 편향 문제는 최적의 모델을 찾는데 방해가 될 수도 있다

MinMaxScaler와 StandardScaler 적용 미 시각화

from sklearn.preprocessing import MinMaxScaler, StandardScaler

MMS = MinMaxScaler()
SS = StandardScaler()

X_ss = SS.fit_transform(X)
X_mss = MMS.fit_transform(X)

X_ss_pd = pd.DataFrame(X_ss, columns=X.columns)
X_mms_pd = pd.DataFrame(X_mss, columns=X.columns)
  • 결정나무에서는 이런 전처리는 의미를 가지진 않는다
  • 주로 cost function을 최적화할 때 유효한 경우가 있다
  • MinMaxScaler와 StandardScaler 적용해봐야 어느 것이 효율적인지 알 수 있다

MinMaxScaler 시각화

  • 최대/최소값을 강제로 1과 0으로 설정하는 것
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 시각화

  • 최대/최소값을 강제로 1과 0으로 설정하는 것
def px_box(target_pd):
    fig = go.Figure()
    fig.add_trace(go.Box(y=target_pd['fixed acidity'], name='fixed acidity'))
    fig.add_trace(go.Box(y=target_pd['chlorides'], name='chlorides'))
    fig.add_trace(go.Box(y=target_pd['quality'], name='quality'))
    fig.show()
    
px_box(X_ss_pd)

MinMaxScaler와 StandardScaler 각가 결정나무(DecisionTree) 학습 후 acc 확인

  • 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 : ', accuracy_score(y_train, y_pred_tr))
print('Test ACC : ', accuracy_score(y_test, y_pred_test))
# accuracy_score(정답데이터, 예측데이터) : 정답데이터와 예측데이터를 비교하여 정확도를 계산해달라는 명령어
  • 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 : ', accuracy_score(y_train, y_pred_tr))
print('Test ACC : ', accuracy_score(y_test, y_pred_test))

결정나무(DecisionTree)에 시각화로 화이트와인과 레드와인을 구분하는 특성 확인

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

plt.figure(figsize=(8, 8))
feature_names_list  = X.columns.tolist()
# .tolist() : 인덱스 데이터를 리스트로 변환해주는 메써드
plot_tree(wine_tree, feature_names=feature_names_list)
  • total sulfur dioxide 를 첫번째 중요 feature로 residual sugar 를 두번쨰 중요 feature로 설정

feature_importances 이용한 중요 특성 확인

dict(zip(X_train.columns, wine_tree.feature_importances_))
# .feature_importances_ : max_depth= 설정 시 모델을 결정하기 위한 중요 feature가 어떻게 나왔는지 각각의 중요도를 보여주는 메써드
# max_depth= 를 높게 설정하게 되면 모델이 복잡해지면서 여러가지 feature를 더 많이 고려한 것을 보여준다

quality를 이진화 하여 taste 컬럼 추가

wine['taste'] = [1.0 if grade > 5 else 0.0 for grade in wine['quality']]
wine.head()

quality 컬럼을 지우지 않을 시 정확도가 왜 100% 인가? 이건 불가능하다

  • quality를 feature에서 지우지 않았기 때문에 taste의 기준이 되었던 quality로 학습을 진행하여 정확도가 100%가 나올수 있었다
  • 잘못된 feature 설정에 의하여 잘못된 학습을 진행한 경우이다
  • 정확도가 1이면 의심해 보아야하는 경우가 있는 것이다

quality 삭제 후 재학습

X = wine.drop(['taste', 'quality'], axis = 1) # feature
y = wine['taste'] # label

# taste에 따라 와인을 구별할 것으로 feature 데이터 에서는 taste 컬럼을 삭제하고 label 데이터에서는 taste 컬럼만 지정해준다
# 전 과정에 의하여 quality로 인하여 잘못된 학습이 진행되어 feature 데이터 에서 quality도 삭제

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 : ', accuracy_score(y_train, y_pred_tr))
print('Test ACC : ', accuracy_score(y_test, y_pred_test))
# accuracy_score(정답데이터, 예측데이터) : 정답데이터와 예측데이터를 비교하여 정확도를 계산해달라는 명령어

어떤 와인이 맛있다고 할 수 있을까?

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

plt.figure(figsize=(8, 8))
feature_names_list  = X.columns.tolist()
# .tolist() : 인덱스 데이터를 리스트로 변환해주는 메써드
plot_tree(wine_tree, feature_names=feature_names_list,
          rounded=True, filled=True)
  • 결정나무는 와인을 평가할때 alcohol을 가장 첫번째 기준으로 꼽았다
  • 결국에 와인의 다양한 속성들이 있지만 알콜의 도수가 맛있는 와인을 평가하는 첫번째 기준이 되었다
profile
비전공 데이터 분석가 도전

0개의 댓글