01. Apple Quality
출처: https://www.kaggle.com/datasets/nelgiriyewithana/apple-quality
Apple Quality
Explore the World of Fruits
www.kaggle.com
1. 데이터 불러오기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('/kaggle/input/apple-quality/apple_quality.csv')
df.head()
판다스를 활용해서 데이터를 불러오면 먼저 데이터의 헤드를 보며 어떤 데이터인지 대략적으로 파악한다.
캐글에서 제공되는 데이터는 Features에 대한 설명이 있기 때문에 이를 잘 읽고 어떻게 데이터를 분석할 것인지 판단하는 것이 중요하다.
각 피처를 살펴보면서 대략적인 판단을 한다.
1) 결측치는 없는가?
2) 각 데이터들이 표준화가 된 것인지 확인한다.
3) 'Quality'는 'good', 'bad' 뿐인지 확인한다.
3가지의 판단을 했고, 구체적인 내용은 EDA를 통해 확인한다.
2. EDA
데이터 분석을 위해서 먼저 총 데이터의 개수를 확인한다. 그리고 앞서 체크했던 3가지의 물음에 대해 확인을 한다.
1) 결측치 확인
df.isna().sum()
결측치가 각 피처별로 1개가 나왔다. 아마 한 행의 데이터가 누락된 것으로 판단되어, 해당 데이터를 삭제하기로 하였다.
print(df.shape)
df.dropna(inplace = True)
print(df.shape)
데이터 프레임의 shape을 보며, 옳게 삭제됐는지 확인하는 과정을 거쳤다.
이 때, 추가적으로 각 데이터의 타입이 어떻게 됐는지 확인을 진행했다.
print(df.dtypes)
df['Acidity'] = df['Acidity'].apply(float)
print(df.dtypes)
먼저 타입을 봤을 때, 하나의 피처가 'Object'로 되어 있는 것을 확인했다. 그래서 해당 피처를 'float64'로 변경하였다.
이때, 중요한 것은 결측치가 있기 때문에 타입 변경을 먼저 하면 안된다는 것이다. 먼저 결측치를 제거하고, 타입 변경을 진행해야 에러가 발생하지 않는다.
다음으로 데이터의 분포를 살펴봤다. 사실 피처 엔지니어링보다 해당 과정이 선행이 될 필요가 있다. 하지만 대략적으로 데이터를 파악했을 때, 정규분포의 형태를 띄고 있다고 판단하여 확인용으로만 진행했다.
sns.histplot(x = 'Juiciness', data = df)
모든 컬럼의 분포를 확인했을 때, 이상치가 없다고 판단했으며, 데이터가 정규분포를 띄고 있기 때문에 표준화를 진행하지 않아도 된다고 판단했다.
EDA 이후에 피처엔지니어링을 진행해야 하지만, 데이터의 개수도 많지 않았고 잘 정제되어 있었기 때문에 쉽게 진행했다.
3. 피처 엔지니어링 및 데이터 전처리
1. 'A_id' 피처 제거하기
2. 'good', 'bad'를 변환하기
df['Quality'].replace({
'good' : 0,
'bad' : 1
})
X = df.drop('A_id', axis = 1)
y = X.pop('Quality')
이후 바로 X, y로 독립변수와 종속변수를 분류할 것이므로 먼저 Quality를 문자에서 숫자로 변경했다.
다음으로 'A_id'를 제거했고, X 에서 'Quality' 열만 y로 추출했다.
4. 모델 학습하기
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X, y, test_size = 0.2, random_state = 123)
from xgboost import XGBClassifier
from sklearn.ensemble import RandomForestClassifier
from lightgbm import LGBMClassifier
model_xgb = XGBClassifier(max_depth = 5, n_estimators = 450, learning_rate = 0.01, min_child_weight = 5, subsample = 0.5, random_state = 123)
model_xgb.fit(X_tr, y_tr)
pred_xgb = model_xgb.predict(X_val)
model_rf = RandomForestClassifier(max_depth =5, n_estimators = 100, min_samples_split = 2, max_features = 'auto')
model_rf.fit(X_tr, y_tr)
pred_rf = model_rf.predict(X_val)
model_lgb = LGBMClassifier(max_depth = 5, num_leaves = 28, n_estimators = 150, learning_rate = 0.1, min_child_weight = 3, subsample = 0.7)
model_lgb.fit(X_tr, y_tr)
pred_lgb = model_rf.predict(X_val)
학습할 모델은 XGboost, RF, LightGBM으로 선정하였다.
좋은 성능을 보이는 모델이고, 어떤 모델이 좋은 성능을 보일지는 해봐야 아는 것이기 때문에, 나는 주로 3개의 모델을 활용해서 비교한다.
개인적인 프로젝트를 진행했다면, 최적의 하이퍼 파라미터 튜닝을 위해 Optuna 를 활용했겠지만, 여기서는 생략했다.
따라서 해당 파라미터는 임의의 값이다.
5. 모델 평가하기
개인적으로는 accuracy, recall 등을 직접 확인하는 것을 좋아하지만, 한눈에 보기 위해 리포트를 활용했다.
그리고 0, 1을 'good', 'bad'로 나타내기 위해 딕셔너리와 매핑을 활용해서 새로운 데이터 프레임으로 추출했다.
from sklearn.metrics import classification_report
report = classification_report(y_val, pred_xgb, output_dict=True)
df_report = pd.DataFrame(report).transpose()
replace_dict = {'0': 'good', '1': 'bad'}
df_report.index = df_report.index.map(lambda i: replace_dict.get(i, i))
print("model_xgb")
print(df_report)
print('='*100)
report = classification_report(y_val, pred_rf, output_dict=True)
df_report = pd.DataFrame(report).transpose()
replace_dict = {'0': 'good', '1': 'bad'}
df_report.index = df_report.index.map(lambda i: replace_dict.get(i, i))
print("model_rf")
print(df_report)
print('='*100)
report = classification_report(y_val, pred_lgb, output_dict=True)
df_report = pd.DataFrame(report).transpose()
replace_dict = {'0': 'good', '1': 'bad'}
df_report.index = df_report.index.map(lambda i: replace_dict.get(i, i))
print("model_lgb")
print(df_report)
print('='*100)
코드를 하나씩 보면, report 변수에 classification_report 값을 넣었는데, 딕셔너리 형태로 받아서 이를 데이터 프레임으로 변경하는 과정을 거쳤다.
그리고 람다와 매핑을 활용해서 0을 good, 1을 bad로 변경했고 이를 출력하는 과정을 거쳤다.
대체로 성능이 좋게나왔다. 아무래도 데이터가 너무 깔끔했으니까.
조금더 복잡한 데이터를 활용해서 주관적인 견해(도메인 지식)를 활용해서 학습을 진행해보고 싶다.
'파이썬 데이터분석' 카테고리의 다른 글
[04] Jobs and Salaries in Data Science (1) | 2024.01.25 |
---|---|
[03] Wine Dataset for Clustering (1) | 2024.01.20 |
[02] Real Estate Dataset (0) | 2024.01.18 |