codestates / ds-blog

blog sharing for data science bootcamp course
2 stars 4 forks source link

[이동훈] Project 2 - Wine Quality #220

Open kroonstazy opened 4 years ago

kroonstazy commented 4 years ago

데이터 출처 UCI Machine Learning Repository

개요

와인 가격은 많은 요인의 영향을 받는다.

분명히 위의 요인들 중에서 와인의 품질에 영향을 미치는 요인도 있지만 그렇다고 위의 모든 요인들이 와인 품질에 영향을 주는것은 아니다.

보통 '비싼술 = 좋은술' 이라는 편견을 가지고 있지만 꼭 그렇지는 않다. 우리가 흔히말하는 가성비가 좋은 와인도 분명 존재한다.

가성비 좋은 제품을 알아보기 위해, 와인 성분을 분석하여, 어떤 와인이 좋은 품질 점수를 받았는지 알아보도록 하겠다.

특성 설명

1) 불휘발산 (타타르산 tartaric acid - g / L) : 와인에 포함되어있는 잘 날아가지 않는 산 2) 휘발산 (아세트산 acetic acid - g / L) : 와인에 포함되어있는 아세트산, 너무 높으면 와인에서 좋지못한, 식초 맛이 날 수 있다. 3) 시트르산 (g / L) : 아주 소량만 관찰되면, 시트르산은 와인에 신선한, 상쾌한 맛을 더한다. 4) 잔여 당 (g / L) : 와인의 발효가 끝난뒤 남은 당분 (당분이 1 g/L 이하인 와인은 매우 드물며, 당분이 45 g/L 이상인 와인은 단 와인) 5) 염화나트륨 (sodium chloride - g / L) : 와인에 존재하는 소금 6) 유리(free) 이산화 황 (mg / L) : (이산화황 가스 / 술폰산(bisulfite)이온으로 존재한다) 이산화 황의 농도. 와인안에 미생물이 자라는것을 방지하고, 산화를 막는다. 7) 총 이산화 황 (mg / L) : 와인안에 들어있는 총 이산화 황의 농도. 적은 양의 bond 이산화 황은 와인안에 있어도, 알기 어렵지만. free 이산화 황은 50 ppm만 넘어도, 향과 맛에서 특유의 냄사가 난다. 8) 밀도 (g / cm^3) 와인의 밀도는, 와인내 알콜과, 설탕의양에 따라 물의 밀도와 비슷하다 9) 산도 (pH) : (산성) 0 - 14 (염기성) 일반적으로 와인의 산도는 pH 3~4 사이 10) 황산칼륨 (potassium sulphate - g / L) : 와인에 손재하는 SO2 수치에 영향을 미친다. 와인의 항균제, 산화방지제 혁할 11) 알콜 (% by volume)

Baseline Model

우선은 내가 만드려고 하는 모델과 비교할 수 있는 기준모델을 만들었다.

# Baseline Model : 기준모델
guess = red['quality'].mean()
print('품질점수 평균 :', guess)

# 기준모델의 평가지수  MAE
errors = red['quality'] - guess
mean_abs_errors = errors.abs().mean()
print('MAE :',mean_abs_errors)

품질점수 평균 : 5.6360225140712945 MAE : 0.6831779242889846 평가지표로는 단위가 보존되고, 직관적으로 판단하기 쉬운 Mean Absolute Error를 선택하였다.

download

와인 quality/품질의 분포도가 궁금하여, 시각화를 진행했다. 얼핏 보면 정규 분포를 따르는것 같지만, 대부분의 와인이 5점과 6점을 기록하고 있다.

사용한 모델 : XGBoost Regressor

본격적으로 모델을 만들었다.

import xgboost as xgb
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

data_dmatrix = xgb.DMatrix(data=X_train, label=y_train)
xg_reg = xgb.XGBRegressor(objective = 'reg:squarederror', 
                         learning_rate=0.2,
                         n_jobs=-1,
                         n_estimators=1000, metrics="mae")
xg_reg.fit(X_train, y_train,
           eval_set=[(X_train, y_train), (X_val, y_val)],
           early_stopping_rounds=10,
           eval_metric='mae') # 평가지표로, mae 선택

평가지표 해석

훈련데이터

#Train Data 
import math
pred_t = xg_reg.predict(X_train)
print('R^2 score', r2_score(y_train, pred_t))
print('MAE score', mean_absolute_error(y_train, pred_t)) #해석하기 제일 직관적이기 때문에 선택

R^2 score 0.5927876952867295 MAE score 0.40513136258248333

R^2 score : 훈련데이터의 60% 정도가 우리가 만든 회귀 모델에 들어 맞는다. MAE : 작으면 작을 수록, 좋다. 우리는 0~10까지의 품질 점수를 예측하는데 생기는 오차값. MAE : 0.40는 기대했던것 보다 더 큰 값이다.


검증데이터

#Validation Data
import math
pred = xg_reg.predict(X_val)
print('R^2 score', r2_score(y_val, pred))
print('MAE score', mean_absolute_error(y_val, pred)) #해석하기 제일 직관적이기 때문에 선택

R^2 score 0.4421892930448479 MAE score 0.4732346348464489

R^2 score : 검증 데이터의 44% 정도가 우리가 만든 회귀 모델에 들어 맞는다. MAE : 검증 데이터의 MAE 는 훈련 데이터의 MAE 값보다는 더크다 (검증 데이터로 품질 점수를 예측 했을때 오차가 더 커졌다. )

그래도 기준모델의 MAE : 0.6831779242889846 보다는 성능이 좋다.


모델 해석을 위한 시각화

PDP

isolate : '알콜 함량' 특성이 Quality/품질에 미치는 영향

download-1

위 시각화를 통해 우리가 얻을 수 있는 insight 알콜 함량 9.3% 이하 : 품질에 아무런 영향을 주지 못함 알콜 함량 9.3% 이상일때는 품질 점수에 긍정적인 영향을 미침 알콜 함량 12% 쯤에서 가장 긍정적인 영향을 미침, 14%는 오히려, 품질 점수가 조금 감소하였다.

interactive : 알콜 vs 잔여 당분

와인에서의 알콜은, 포도의 당분이 분해되면서 생기는 것이기 때문에, 알콜과, 잔여 당분 특성의 관계를 알고 싶었다.

download-2

X 축 : 알콜 함량 Y 축 : 잔여 당분

알콜함량이 8.4%일때, 품질 점수는 4점대 9.3%~ 11.2% 까지는 5점대 11.9%~13.9% 는 6점대를 기록. (최고 품질 점수는 알콜 함량이 11.9%일때)

잔여 당분이 너무 낮거나 (0.9) 너무 높으면 (15.5) 오히려 품질 점수에 악영향을 주는것을 볼 수 있다.

SHAP

하나의 샘플을 관찰

import shap

# load JS visualization code to notebook
shap.initjs()

# train XGBoost model
explainer = shap.TreeExplainer(xg_reg)
shap_values = explainer.shap_values(X_train)
shap.force_plot(explainer.expected_value, shap_values[507,:], X_train.iloc[0,:])
Screen Shot 2020-11-06 at 5 12 44 AM

빨간색은 품질 점수가 올라가는 요인 파란색은 품질 점수가 내려가는 요인

전제 데이터 셋을 관찰

SHAP Val

Y 축 : 품질 점수 X 축 : 샘플들의 품질점수로 정렬한 시각화.

모델의 목적

와인을 잘 모르는 사람도, 와인의 성분정보를 얻을 수 있다면, 가성비 좋은 와인을 찾을 수 있으면 하는 마음에서 모델을 만들어 보았습니다.

모델의 한계

와인의 성분만을 분석 했기 때문에, 품질 점수가 완벽한 척도는 아니다.

사람마다 선호하는 맛이 다르기 때문에 (단맛, 신맛, 드라이) 품질 점수가, 개인의 선호도를 대변해 주지 않는다.

애초에 품질 점수도 사람이 평가한 것이기 때문에, 객관적이지 않을 수 있다.

레드와인과 화이트 와인의 평가 기준이 다르기 때문에, 지금 만든 모델로는 화이트 와인 품질을 알기에는 부적합 하다.

johnnykoo84 commented 4 years ago

좋은 점

  1. 특성 설명이 잘 되어 있어 와인을 모르는 사람도 충분히 읽기 쉽게 설명되어 있습니다.
  2. 특성 설명 외에도 아주 소프트란 랜딩이 가능하도록 인트로가 작성되어 있습니다.
  3. 시각화 자료가 적절히 잘 사용되고 있습니다.

아쉬운 점

  1. 이 작업을 위해 충분히 EDA가 되었었을것 같은데 전체가 아니더라도 EDA Highlight 내용을 요약된 버전으로 추가할 수 있지 않았을까 합니다. 최소한 몇 개의 데이터가 있고 분포는 어떠하며 등등 -> 퀄리티 분포는 잘 공유해 주셨네요
  2. 왜 XGBoost Regressor 를 사용했으며, 이 모델은 어떠한 모델인지 설명이 짤막하게라도 있으면 좋았겠다 싶습니다.
  3. 정확히 프로젝트 결과물 요구사항에 대한 목적이 불분명했을 순 있는데, 만약 블로그라면, 전체 글은 흐름이 있는 읽을 수 있는 narrative 형태여야 합니다. 지금 글은 narrative와 summary 로 혼합되어 있습니다.