Can you cut the time a Mercedes-Benz spends on the test bench?
https://www.kaggle.com/c/mercedes-benz-greener-manufacturing
이 프로젝트에서는...
feature 엔지니어링을 잘해야한다.
적절한 feature들로만 성능이 높게 나올 수 있다.
주어진 공정들의 시간을 더해서 테스트 시간을 예측한다.
보안상 때문에 x1, x2, 등으로 이름이 붙여있음
카테고리, 0과1 등 label을 추정을 해야만 하는 한계도 있음
프로젝트 목적
test_bench time predict
ML 프로젝트 수행 순서
- 라이브러리, 데이터 불러오기
- EDA 수행
- 전처리 수행, feature engineering
- 데이터 분할
- 학습 진행
- 하이퍼 파라미터 튜닝 수행 (과적합 주의)
- 최종 테스트 진행
상관관계 분석, VIP : 다중 공산성 제거
from statsmodels.stats.outliers_influence import variance_inflation_factor
하이퍼파라미터 튜닝을 위한 라이브러리 optuna
import optuna
김용담 강사님의 코드 분석
1. 사용할 라이브러리와 데이터를 불러온다.
# 데이터분석 4종 세트
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 데이터를 불러옵니다.
train = pd.read_csv("../input/mercedes-benz-greener-manufacturing/train.csv.zip")
test = pd.read_csv("../input/mercedes-benz-greener-manufacturing/test.csv.zip")
2. EDA
1. 결측치는 없다
- dtype이 object인 column : X0 ~ X8까지 8개. (categorical feature)
-> 어떻게 처리할지 고민해야함. (Ordinal Encoding VS One-Hot Encoding)
- (이런것을 고민하는구나, 과연 어떤 선택을 어떠한 근거로 하셨을까)-> categorical feature들은 종류 정보들이 알파벳으로 되어있으며(anomynized) 이 정보들 대비 target값의 차이가 있는지 확인. (특별하게 관련 없음)
- (feature 하나하나 잘 살펴보고 target과 관련이 있는지 확인하기)-> binary feature들중에서 0만 가지고 있는 column들이 있음. (0만?..그러면 왜있는거지)
-> 정보가 충분하지 않다고 판단(target value와의 관련성 0) 삭제.
- target distribution -> train data에 180을 넘는 데이터가 하나 있음. 이 데이터를 outlier라고 생각하고 제거.
- (이상치는 찾아서 제거한다.)
### outlier 찾아서 지우기!
plt.figure(figsize=(12, 8))
#sns.histplot(data=train, x="y")
#sns.boxplot(data=train, x="y", whis=3)
sns.boxplot(data=train, x="y")
## train에 y column이 161을 넘는 데이터를 제거하자
outliers = train.loc[train.y > 135] ## IQR*1.5
train = train.drop(index=outliers.index)
train
y에 대한 boxplot
카테고리, 바이너리 column을 나눈다.
# X0 ~ X8 : categorical variables --> 8개
cat_vars = train.columns[2:10]
cat_vars
# X10 ~ : binary variables
binary_vars = train.columns[10:]
binary_vars
바이너리에서 0 과 1의 비율을 확인 (X는 384개나 있음..)
# binary variable들의 0과 1의 구성 비율을 확인합니다!
# 1. value_counts 함수를 이용한 방법
# temp = train.X10.value_counts(normalize=True).values * 100
# print(f"0의 비율: {temp[0]:.4f}%, 1의 비율: {temp[1]:.4f}%")
# 2. 1의 개수를 이용한 방법
all0_cols = [] # column에 있는 모든 데이터가 다 0인 케이스.
for col in binary_vars:
one_percent = train[col].mean() * 100 # 1의 비율을 퍼센트로 표현
if one_percent == 0.0: # 1의 개수가 0인 경우.
all0_cols.append(col) ## 모든 값이 0인 column들을 추가합니다.
print(f"[{col}] 0의 비율: {100 - one_percent:.2f}%\t1의 비율: {one_percent:.2f}%")
[X10] 0의 비율: 98.65% 1의 비율: 1.35%
[X11] 0의 비율: 100.00% 1의 비율: 0.00%
...
...
...
이런식으로 출력이 된다.
여기서 1이 없는 경우의 col은 삭제
train = train.drop(columns=all0_cols)
train
4154 rows × 365 columns 으로 columns수가 줄어들었다.
3. feature engineering
1. correlation
1. VIF
1. PCA
상관계수가 0.7보다 높은 것들을 추리기
# 1. Correlation이 높은 변수들 찾기 --> 필요없는 column : ID, y
temp = train.drop(columns=["ID", "y"])
corr = temp.corr() # 363 x 363
threshold = 0.7
#display(corr.loc[corr.X1 > threshold])
# e.g. X1 ----> [X3, X6, X10]
# X2 ----> [....]
# X3 ----> [X1, X6, X10, ..., ...] (skip)
# X4 ----> [....]
high_correlated_cols = []
for col in temp.columns:
if col in high_correlated_cols:
continue
temp_cols = list(corr.loc[(corr[col] > threshold) | (corr[col] < -threshold)].index[1:]) # 보고 있는 column을 제외하고 threshold보다 상관계수가 높은 column들을 리스트로 변환.
high_correlated_cols = high_correlated_cols + temp_cols # 리스트 누적
high_correlated_cols = set(high_correlated_cols) # 중복 column들 제거
high_correlated_cols
위와같이 0.7이상의 상관관계를 가진 col이 매우 많았다.
VIF가 10이 넘는 변수 찾기
VIF_i = 1/ 1 - R2_i
다중공산성 방지를 위해
# 2. VIF가 10이 넘는 변수들 찾기
## VIF_i = 1 / 1 - R2_i
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif_list = [variance_inflation_factor(temp, idx) for idx in range(len(temp.columns))]
vif_df = pd.DataFrame(index=temp.columns, data=vif_list, columns=["VIF"])
vif_df.sort_values(by="VIF", ascending=False) # VIF가 큰 순서대로 정렬해서 만든 DataFrame
## VIF가 가장 큰 (또는 10보다 큰 column중에 하나)를 골라서 제거 한 뒤에 다시 VIF 계산. (loop)
## Continue..
이런식의 VIF 결과가 나온다.
3. PCA
차원의 저주를 피하기 위해 PCA 진행
# 3. PCA(Principal Component Analysis)를 이용하여 변수 크기 줄이기
from sklearn.decomposition import PCA
## PCA의 n_components -----> hyper-parameter!
# 1. n_components = 6 : 6차원으로 내려주세요.
# 2. n_components = 0.90 : 원본 데이터의 분포를 90% 보존하는 차원으로 내려주세요.
#pca = PCA(n_components=15)
pca = PCA(n_components=0.95)
X = pca.fit_transform(temp) # 주성분을 기준으로 데이터를 "저차원"으로 변환
pca_columns = [f"PC{i}" for i in range(X.shape[1])]
pca_df = pd.DataFrame(columns=pca_columns, data=X)
pca_df
PCA를 진행하기 전에는 363개의 COL수였는데, PCA를 진행하고 나니 12개의 특성으로 줄일 수 있었다.
이때 이 PCA는 원본 데이터의 95%를 보존하면서 저차원으로 내린 것을 알 수 있다.
'Machine Learning' 카테고리의 다른 글
나이브베이즈 (Naive_bayes) 분류 모델 (0) | 2022.05.27 |
---|---|
LightGBM에 대하여 (0) | 2022.05.25 |
XGBoost 기초 설명 (0) | 2022.05.25 |
Lasso 와 Ridge 회귀 (regression) (0) | 2022.05.25 |
선형회귀와 LGBM 실습 (0) | 2022.05.17 |