-
[DAYCON][오늘의 파이썬] Lv4 교차검증과 모델 앙상블을 활용한 와인 품질 분류하기python/오늘의 파이썬 2021. 11. 22. 16:17
[EDA]
1. seaborn pairplot
pairplot은 데이터에 들어 있는 각 컬럼(열)들의 모든 상관관계를 출력한다.
3차원 이상의 데이터라면 pairplot 함수를 사용해 분포도를 그려서 쉽게 모든 변수 간의 상관관계를 얻을 수 있다.
pairplot은 grid(격자) 형태로 각 집합의 조합에 대해 히스토그램과 분포도를 그려준다.
- 'data' 변수에 train의 "fixed acidity"부터 "chlorides"까지의 변수를 저장한다.
data = train.loc[:, 'fixed acidity' : 'chlorides']
- 'data'의 pairplot을 그린다.
sns.pairplot(data)
2. seaborn distplot
distplot 함수는 데이터의 히스토그램을 그려준다.
히스토그램이란 수치형 데이터 분포를 정확하게 표현해주는 시각화 방법으로,
변수를 여러 개의 bin으로 자르고(사용자 지정) bin당 관측수를 막대그래프로 표현한다.
- 'data' 변수에 train의 "fixed acidity"부터 "chlorides"까지의 변수를 저장한다.
data = train['fixed acidity']
- 'data'의 pairplot을 그린다.
sns.distplot(data,bins = 100)
3. seaborn | heatamp
히트맵:
두개의 범주형(Categorical) 변수에 대한 반응변수의 크기를 색깔의 변화로 표현하는 것.
ex) 일 별 기온을 보고자 할 때 매일 온도를 히트맵으로 표현하여 온도 변화의 추이를 볼 수 있다.
데이터 분석 과정에서는 변수별 상관관계를 확인 할때 히트맵 그래프를 많이 사용한다.
다중 공선 성 때문에 상관관계를 파악해야 한다.
- 히트맵 그래프에 그릴 변수를 지정한다. corr()는 데이터의 변수 간의 상관도를 출력하는 함수다.
data = train.corr()
- seaborn의 heatmap 함수를 사용해 히트맵 그래프를 그린다.
sns.heatmap(data)
4. 다중공선성 Scatter plot
다중공선선은 상관관계가 높은 독립변수들이 동시에 모델에 포함될 때 발생한다.
만약 두 변수가 완벽하게 다중공선성에 걸려있다면, 같은 변수를 두 번 넣은 것이므로 모델이 결괏값을 추론하는 데 방해가 될 수 있다.
다중공선성을 확인하는 방법 3가지
- Scatter plot을 통한 확인
- Heatmap 그래프를 통한 확인
- VIF(Variance Inflation Factors, 분산팽창요인)을 통한 확인
이번 실습에는 첫번째 방법인 Scatter plot을 이용하여 다중공선성을 확인해보자.
Scatter Plot(산점도 그래프)는 두 개의 연속형 변수에 대한 관계를 파악하는데 유용하게 사용할 수 있다.
위 그래프처럼 x 데이터가 증가함에 따라 y 데이터가 증가하는 경향을 보이는데, 이럴 경우 두 변수의 상관도가 높다고 해석할 수 있다.
- Scatter Plot을 그릴 변수 지정
x_data = train['residual sugar'] y_data = train['density']
- seaborn의 scatterplot 함수를 사용해 그래프를 그린다.
sns.scatterplot(x = x_data, y = y_data )
5. 다중공선성 VIF(분산 팽창 요인)
이번에는 변수의 다중공선성을 확인하는 방법 중 하나인 VIF(Variance Inflation Factors, 분산팽창요인)에 대해 알아보자.
VIF는 변수 간의 다중 공선성을 진단하는 수치이며 범위는 1 ~ ∞
통계학에서는 VIF 값이 10 이상이면 해당 변수가 다중공선성이 있는 것으로 판단한다.
VIF를 구하는 수식은 VIFk = 1 / (1 - Rj2)이다.
여기서 VIFk는 k번째 변수의 VIF 값을 의미하고, Rj2는 회귀분석에서 사용하는 결정계수다.
- 결괏값을 저장할 VIF라는 이름의 리스트 생성
vif = []
- values atribution(속성) 이용해 train 데이터의 값만 추출
train_val = train.values
- for문을 이용해서 variance_inflation_factor 함수에 인자로 train_val (train 데이터 값)과 인덱스 번호 지정
for i in range(len(train.columns)): vif.append(variance_inflation_factor(train_val, i))
- 데이터 프레임 형식으로 바꿔 가독성을 높인다.
vif_dataframe = pd.DataFrame() vif_dataframe['columns'] = train.columns vif_dataframe['VIF'] = vif vif_dataframe
[전처리]
1. 다중공선성 해결 | 변수 정규화
이번 단계부터는 다중공선성을 일으키는 변수들을 어떻게 다뤄줘야 할 지에 대해 알아보자.
다중공선성을 해결하는 방법 3가지
- 변수 정규화
- 변수 제거
- PCA(주성분 분석)
정규화를 적용하기 전에 분산 팽창 요인(VIF)을 확인하고 정규화를 적용한 후 분산 팽창 요인을 확인해 서로 비교해보자.
- train 데이터의 VIF 계수 출력
vif = pd.DataFrame() vif["VIF Factor"] = [variance_inflation_factor(train.values, i) for i in range(train.shape[1])] vif["features"] = train.columns vif
- MinMaxScaler를 "scaler"라는 변수에 지정한다.
scaler = MinMaxScaler()
- "scaler"를 train으로 학습시킨다.
scaler.fit(train)
- "scaler"를 통해 train의 수치들을 변환시키고 train_scale에 저장한다.
train_scale = scaler.transform(train)
- scaler를 통해 변환된 데이터의 VIF를 확인한다.
new_train_df = pd.DataFrame(train_scale) new_train_df.columns = train.columns vif = pd.DataFrame() vif["VIF Factor"] = [variance_inflation_factor(new_train_df.values, i) for i in range(new_train_df.shape[1])] vif["features"] = new_train_df.columns vif
2. 다중공선성 해결 | 변수 제거
이번 시간에는 두 번째 방법인 VIF 기준 10 이상의 변수들을 제거해보자.
- train 데이터의 VIF 계수 출력
vif = pd.DataFrame() vif["VIF Factor"] = [variance_inflation_factor(train.values, i) for i in range(train.shape[1])] vif["features"] = train.columns vif
- 종속변수인 quality를 제외한 VIF 10이상의 변수 제거
new_train = train.drop(['alcohol','fixed acidity','total sulfur dioxide','density','pH','sulphates'],axis=1)
- VIF 10이상의 변수 제거 후 VIF 다시 확인
new_train_df = pd.DataFrame(new_train) new_train_df.columns = new_train.columns vif = pd.DataFrame() vif["VIF Factor"] = [variance_inflation_factor(new_train_df.values, i) for i in range(new_train_df.shape[1])] vif["features"] = new_train_df.columns vif
3. 다중공선성 해결 - PCA(1)
다중공선성을 해결하는 방법 3가지 중 마지막 방법인 PCA를 이해하기 위해서는 먼저 차원 축소 개념을 이해해야 한다.
차원 축소
많은 피처로 구성된 다차원 데이터 셋의 차원을 축소해 새로운 차원의 데이터 셋을 생성하는 것
일반적으로 차원이 증가할수록 데이터 포인트 간의 거리가 기하급수적으로 멀어지게 되고, 희소(sparse)한 구조를 가지게 된다.
수백 개 이상의 피처로 구성된 데이터 셋의 경우 상대적으로 적은 차원에서 학습된 모델보다 예측 신뢰도가 떨어진다.
또한 피처가 많은 경우 개별 피처 간의 상관관계가 높을 가능성이 크다.
선형 회귀와 같은 선형 모델에서는 입력 변수 간의 상관관계가 높을 경우, 이로 인한 다중 공선성 문제로 모델의 예측 성능이 떨어진다.
그리고 수십 개 이상의 피처가 있는 데이터의 경우 이를 시각적으로 표현해 데이터의 특성을 파악하기는 불가능하다.
이 경우 3차원 이하의 차원 축소를 통해서 시각적으로 데이터를 압축해서 표현할 수 있다.
또한 차원 축소를 할 경우 학습 데이터의 크기가 줄어들어서 학습에 필요한 처리 능력도 향상시킬 수 있다.
차원 숙소는 feature selection과 feature extraction으로 나눌 수 있다.
feature selection: 특정 피처에 종속성이 강한 불필요한 피처는 아예 제거하고, 데이터의 특징을 잘 나타내는 주요 피처만 선택하는 것
feature extraction: 기존 피처를 저 차원의 중요 피처로 압축해서 추출하는 것
새롭게 추출된 중요 특성은 기존의 피처가 압축된 것이므로 기존의 피처와는 완전히 다른 값이 된다.
PCA는 feature extraction의 기법 중 하나이다.
4. 다중공선성 해결 - PCA(2)
전 단계에서 PCA의 상위 개념인 차원 축소와 feature extraction에 대해 알아보았다.
이번 단계에서는 PCA의 개념에 대해 알아보자.
PCA: 많은 속성으로 구성된 원본 데이터를 그 핵심을 구성하는 데이터로 압축하는 것
PCA는 기존 데이터의 정보 유실 최소화를 위해 가장 높은 분산을 가지는 데이터 축을 찾아 해당 축으로 차원을 축소한다.
키와 몸무게 2개의 피처를 가지고 있는 데이터셋이 다음과 같이 구성되어 있다고 가정해보자.
이 2개의 피처를 한 개의 주성분을 가진 데이터 셋으로 차원 축소하는 과정은 다음과 같다.
PCA는 제일 먼저 가장 큰 데이터 변동성을 기반으로 첫 번째 벡터 축을 생성하고,
두 번째 축은 이 벡터 축에 직각이 되는 벡터(직교 벡터)를 축으로 한다.
세 번째 축은 다시 두 번째 축과 직각이 되는 벡터를 설정하는 방식으로 축을 생성한다.
이렇게 생성된 벡터 축에 원본 데이터를 투영하면 벡터 축의 개수만큼의 차원으로 원본 데이터가 차원 축소된다.
5. 다중공선성 해결 - PCA(3)
이번 단계에서는 iris 데이터를 이용해 PCA 실습을 진행해보자.
먼저 iris 데이터 로딩한 후 x축 : sepal length y축 : sepal width로 하여 품종 데이터 분포 시각화한다. 마지막으로 PCA를 이용해 차원 축소 후 변환된 데이터 셋을 2차원 상에서 시각화한다.
- 각 target 별로 다른 색으로 scatter plot
#setosa는 빨간색, versicolor는 노란색, virginica는 파란색 color=['r', 'y', 'b'] # setosa의 target 값은 0, versicolor는 1, virginica는 2. for i, c in enumerate(color): x_axis_data = df[df['target']==i]['sepal_length'] y_axis_data = df[df['target']==i]['sepal_width'] plt.scatter(x_axis_data, y_axis_data,color = c,label=iris.target_names[i]) plt.legend() plt.xlabel('sepal length') plt.ylabel('sepal width') plt.show()
- Target 값을 제외한 모든 속성 값을 MinMaxScaler를 이용하여 변환
df_features = df[['sepal_length','sepal_width','petal_length','petal_width']] df_scaler = MinMaxScaler().fit_transform(df_features)
- PCA를 사용하여 4차원 변수를 2차원으로 변환
pca = PCA(n_components=2)
- fit()과 transform()을 호출하여 PCA 변환
pca.fit(df_scaler) df_pca = pca.transform(df_scaler) print(df_pca.shape)
- PCA 변환된 데이터의 컬럼명을 각각 PCA_1, PCA_2로 지정
df_pca = pd.DataFrame(df_pca) df_pca.columns = ['PCA_1','PCA_2'] df_pca['target']=df.target df_pca.head(3)
- 각 target 별로 다른 색으로 scatter plot
#setosa는 빨간색, versicolor는 노란색, virginica는 파란색 color=['r', 'y', 'b'] # setosa의 target 값은 0, versicolor는 1, virginica는 2. for i, c in enumerate(color): x_axis_data = df_pca[df_pca['target']==i]['PCA_1'] y_axis_data = df_pca[df_pca['target']==i]['PCA_2'] plt.scatter(x_axis_data, y_axis_data, color = c,label=iris.target_names[i]) plt.legend() plt.xlabel('PCA_1') plt.ylabel('PCA_2') plt.show()
6. 연속성 변수 변환(1)
머신러닝 모델링을 하다 보면 제한된 변수로 성능을 끌어올리는데 한계가 생긴다.
그래서 어떻게 데이터를 증강시키는지, 어떤 파생 변수를 추가하는지가 중요하다.
특히 정형 데이터의 경우 데이터 증강은 제한적이다. 그래서 더더욱 효율적인 파생 변수를 추가하는 것이 중요하다.
이번 단계에선 수치 범위 구간을 직접 지정해 레이블링 해서 연속형 변수를 범주형 변수로 변환시켜보는 실습을 진행해보자.
- train 데이터 확인
train.head()
- train 데이터의 pH 변수를 구간이 4개인 범주형 변수로 변환
def func(x): if x < 3: return 'lowest' elif x < 3.3: return 'low' elif x < 3.5: return 'normal' else : return'high' train['pH'] = train['pH'].apply(lambda x : func(x))
- 변환 후 데이터 확인
train.head()
7. 연속성 변수 변환(2)
전 단계는 직접 수치 범위를 지정해서 나눴다. 직접 수치 범위를 나눌 경우 조금 더 세밀하게 조정 가능하다는 장점이 있지만, 여러 변수에 한 번에 적용하기에는 어렵고 각각의 변수에 맞는 범위를 지정하기 에는 많은 시간이 소요된다는 단점이 있다.
이번 단계에서는 판다스의 cut() 함수를 이용해 손쉽게 연속형 변수를 범주형 변수로 변환시켜보도록 하자.
- train 데이터의 alcohol 변수를 구간이 5개인 범주형 변수로 변환
train['alcohol'] = pd.cut(train.alcohol, 5,labels=False)
8. Polynomial Features(1)
이전 단계에는 연속형 데이터를 범주형 데이터로 변환시키는 방법으로 변수를 추가했다면, 이번 단계와 다음 단계에서는 Polynomial Features라는 라이브러리를 이용해 파생 변수를 생성해보도록 하자.
먼저 Polynomial Features라는 라이브러리에 대해 알아보자.
PolynomialFeatures라이브러리는 sklearn에 내장되어 있는 라이브러리다.
이 라이브러리를 이용하면 현재 데이터를 다항식 형태로 변환시킬 수 있다.
데이터에 x1, x2 변수가 있다면 PolynomialFeatures 라이브러리를 이용해
1, x1, x2, x1^2, x1*x2, x2^2 로 간단하게 변환시킬 수 있다.
- 임의의 데이터 생성
X = np.arange(6).reshape(3, 2) df = pd.DataFrame(X) df.columns = ['x_1','x_2'] df
- 차원을 2로 설정하여 fit_transform 메서드를 통해 데이터 변환
poly_features = PolynomialFeatures(degree=2) df_poly = poly_features.fit_transform(df)
- PolynomialFeatures로 변환된 데이터를 데이터 프레임 형태로 변환
df_poly = pd.DataFrame(df_poly) df_poly
- df_poly의 칼럼을 1, x1, x2, x1^2, x1*x2, x2^2로 변경
df_poly.columns = ['1','x1','x2','x1^2','x1*x2','x2^2'] df_poly
9. Polynomial Features(2)
이제 Polynomial Features 라이브러리를 와인 품질 분류 데이터에 Polynomial Features를 적용해 보고, decision tree 모델을 이용해 품질 분류를 해보자.
- train 데이터를 PolynomialFeatures를 이용하여 변환
poly_features = PolynomialFeatures(degree=2) # 차원은 2로 설정
- 와인 품질 기준인 quality 변수를 제외한 나머지 변수를 포함한 데이터 변환
df = train.drop('quality',axis = 1) df_poly = poly_features.fit_transform(df) # fit_transform 메소드를 통해 데이터 변환 df_poly = pd.DataFrame(df_poly) # PolynomialFeatures로 변환 된 데이터를 데이터 프레임 형태로 변환
- DecisionTreeClassifier 모델을 변환된 train 데이터로 학습
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier() model.fit(df_poly,train['quality'])
- test 데이터 변환
poly_features = PolynomialFeatures(degree=2) # 차원은 2로 설정 test_poly = poly_features.fit_transform(test) # fit_transform 메소드를 통해 데이터 변환 test_poly = pd.DataFrame(test_poly) # PolynomialFeatures로 변환 된 데이터를 데이터 프레임 형태로 변환
- 결괏값 추론
pred = model.predict(test_poly)
- 정답 파일 생성
submission = pd.read_csv('data/sample_submission.csv') submission['quality'] = pred submission.to_csv('poly.csv',index = False)
[모델링]
1. XGBoost 개념
XGBoost
Extreme Gradient Boosting의 약자
Boosting 기법을 이용하여 구현한 대표적인 알고리즘 Gradient Boost이고,
이 알고리즘을 병렬 학습이 지원되도록 구현한 라이브러리가 XGBoost
Regression, Classification 문제를 모두 지원하며, 성능과 자원 효율이 좋아서, 인기 있게 사용되는 알고리즘
여기서 Boosting이란, 여러 개의 성능이 높지 않은 모델을 조합해서 사용하는 앙상블 기법 중 하나다.
성능이 낮은 예측 모형들의 학습 에러에 가중치를 두고, 순차적으로 다음 학습 모델에 반영하여 강한 예측모형을 만든다.
XGBoost의 장점
기존 boosting 모델 대비 빠른 수행 시간(병렬 처리)
과적합 규제 지원(Regularization)
분류와 회귀 task에서 높은 예측 성능
Early Stopping(조기 종료) 기능 제공.
다양한 옵션을 제공해 Customizing이 용이.
결측치를 내부적으로 처리함.
2. XGBoost 실습
XGBoost를 이용해 와인 품질 분류를 진행해보자.
- 라이브러리 불러오기
from xgboost import XGBClassifier
- 데이터 확인
train.head()
- 원핫 인코딩
train_one = pd.get_dummies(train) test_one = pd.get_dummies(test)
- 모델 정의
model = XGBClassifier()
- 모델 학습
X = train_one.drop('quality',axis= 1) #X 는 train에서 quality 를 제외한 모든 변수 y = train_one['quality'] #y 는 train의 qulity 변수 model.fit(X,y)
- predict 메서드와 test_one 데이터를 이용해 품질 예측
pred = model.predict(test_one)
- sample_submission.csv 파일을 불러와 예측한 값으로 채워 주기
submission = pd.read_csv('data/sample_submission.csv') submission['quality'] = pred submission.head()
- 정답 파일 내보내기
submission.to_csv('xgb_pred.csv',index = False)
3. LightGBM 개념
xgboost는 굉장히 좋은 성능을 보여주었지만 여전히 속도면에서는 조금 느리다는 단점이 존재한다.
이러한 단점을 보완해주기 위해 탄생한 것이 LightGBM(LGBM) 이다.
LGBM은 기존의 gradinet boosting 알고리즘과 다르게 동작된다.
기존 boosting 모델들은 트리를 level-wise 하게 늘어나는 방법을 사용한 반면, LGBM은 leaf wise(리프 중심) 트리 분할을 사용한다.
leaf-wise은 속도가 빠르다는 것이 가장 큰 장점입니다. 데이터 양이 많아지는 상황에서 빠른 결과를 얻는데 시간이 점점 많이 걸리고 있는데, Light GBM은 큰 사이즈의 데이터를 다룰 수 있고 실행시킬 때 적은 메모리를 차지한다.
LGBM의 장점
- 대용량 데이터 처리
- 효율적인 메모리 사용
- 빠른 속도
- GPU 지원
LGBM의 단점
Light GBM은 Leaf-wise growh로 과적합의 우려가 다른 Tree 알고리즘 대비 높은 편이다. 그러므로 데이터의 양이 적을 경우 Overfiitng(과적합)에 취약한 면이 있어 데이터 양이 적은 경우에는 사용을 자제하는 것이 좋다.
4. LightGBM 실습
이번 단계에서는 Light GBM을 이용해 와인 품질 분류를 진행해보자.
- 라이브러리 불러오기
from lightgbm import LGBMClassifier
- 데이터 확인
train.head()
- 원핫 인코딩
train_one = pd.get_dummies(train) test_one = pd.get_dummies(test)
- 모델 정의
model = LGBMClassifier()
- 모델 학습
X = train_one.drop('quality',axis= 1) y = train_one['quality'] model.fit(X,y)
- predict 메서드와 test_one 데이터를 이용해 품질 예측
pred = model.predict(test_one)
- sample_submission.csv 파일을 불러와 예측한 값으로 채워 주기
submission = pd.read_csv('data/sample_submission.csv') submission['quality'] = pred submission.head()
- 정답 파일 내보내기
submission.to_csv('lgbm_pred.csv',index = False)
5. stratified k-fold 정의
k-fold 교차검증: 학습 데이터 셋을 학습 데이터와 검증 데이터로 나눠 반복해서 검증 및 평가 하는 것
k-fold의 문제점: k-fold의 경우 데이터 셋을 일정한 간격으로 잘라서 사용하기 때문에 target의 비율이 일정하지 않게 테스트 셋에 들어갈 수 있다.
stratified k-fold
k-fold의 문제점인 target 데이터의 비율을 일정하게 유지하지 못하는 것을 일정하게 유지하며, 교차 검증을 진행하는 것
6. stratified k-fold 실습
이번 단계에서는 stratified k-fold와 Light GBM을 이용해 와인 품질 분류를 실습해보자.
- 데이터 확인
train.head()
- 원핫 인코딩
train_one = pd.get_dummies(train) test_one = pd.get_dummies(test)
- StratifiedkFold 라이브러리를 이용해 5개의 fold로 나눔
skf = StratifiedKFold(n_splits = 5) X = train_one.drop('quality',axis = 1) y = train_one['quality'] cnt = 1 acc = 0 for train_idx, valid_idx in skf.split(X,y): train_data = train_one.iloc[train_idx] valid_data = train_one.iloc[valid_idx] # 모델 정의 model = LGBMClassifier() train_X = train_data.drop('quality',axis= 1) # train_data에서 quality 를 제외한 모든 변수 train_y = train_data['quality'] # train_data의 qulity 변수 # fit 메소드를 이용해 모델 학습 model.fit(train_X,train_y) valid_X = valid_data.drop('quality',axis = 1) valid_y = valid_data['quality'] # predict 메소드와 valid_X 데이터를 이용해 품질 예측 pred = model.predict(valid_X) # 모델 정확도 출력 print(cnt," 번째 모델 정확도 : " ,accuracy_score(pred,valid_y)) acc += accuracy_score(pred,valid_y) cnt+=1 print('모델 정확도 평균 : ',acc/5)
7. Voting Classifier 정의
Voting Classifier
여러 개의 모델을 결합하여 더 좋은 예측 결과를 도출하는 앙상블 기법 중 하나
hard voting 방법 : 각각의 모델들이 결과를 예측하면 각 모델의 예측을 모아 다수결 투표로 최종 예측 결과를 선정하는 방식
그림을 살펴보시면, 첫 번째 분류기는 0.9의 확률로 생존을 선택, 두 번째 분류기는 0.6의 확률로 사망을 선택, 세 번째 분류기는 0.7의 확률로 사망을 선택했다. 생존을 선택 한 모델이 1개, 사망을 선택한 모델이 2개 이기 때문에 Voting Classifier은 최종적으로 사망을 선택하게 된다.
soft voting 방법 : 각 모델들이 예측한 결괏값의 확률을 합산해 최종 예측 결과를 선정
단순히 개별 분류기의 예측 결과만을 고려하지 않고 높은 확률값을 반환하는 모델의 비중을 고려할 수 있기 때문에 Hard Voting 보다 성능이 더 좋은 편이다.
3개의 모델이 생존을 선택할 확률의 평균은 0.533 이고, 사망을 선택 할 확률의 평균은 0.466이다. 최종적으로 Voting Classifier는 Hard Voting과 다르게 생존을 선택하게 된다.
8. Voting Classifier 실습
Soft Voting을 이용해서 Voting Classifier실습을 진행해보자. VotingClassifier은 sklearn라이브러리에서 제공된다.
Voting Classifier에 사용할 모델은 Random Forest, Xgboost, Light GBM이다.
- 데이터 확인
train.head()
- 원핫 인코딩
train_one = pd.get_dummies(train) test_one = pd.get_dummies(test)
- 모델 정의, VotingClassifier 정의
LGBM = LGBMClassifier() XGB = XGBClassifier() RF = RandomForestClassifier() VC = VotingClassifier(estimators=[('rf',RF),('xgb',XGB),('lgbm',LGBM)],voting = 'soft')
- 모델 학습
X = train_one.drop('quality',axis= 1) # X 는 train에서 quality 를 제외한 모든 변수 y = train_one['quality'] # y 는 train의 qulity 변수 VC.fit(X,y)
- predict 메서드와 test_one 데이터를 이용해 품질 예측
pred = VC.predict(test_one)
- sample_submission.csv 파일을 불러와 예측된 값으로 채워 줌
submission = pd.read_csv('data/sample_submission.csv') submission['quality'] = pred submission.head()
- 정답 파일 내보내기
submission.to_csv('VC_pred.csv',index = False)
[튜닝]
튜닝 부분에서는 Randomforest, XGBoost, Light GBM 총 3개의 모델을 튜닝하고 Voting Classifier로 만드는 과정을 진행할 것이다.
1.Bayesian Optimization 복습
우리가 흔히 알고 있는 하이퍼 파라미터 튜닝 방법은 Grid Search, Random Search이다.
두 가지 튜닝 방법의 문제점은 이제까지의 사전 지식(실험결과) 가 반영되지 않는다는 것이다.
Baysian Optimization은 사전지식(실험 결과)을 반영해가며 하이퍼파라미터를 탐색한다. 즉, 현재까지 얻어진 모델의 파라미터와 추가적인 실험 정보를 통해 데이터가 주어 졌을 때 모델의 성능이 가장 좋을 확률이 높은 파라미터를 찾아낸다.
우리가 다룰 Bayesian Optimization 패키지에서는 다음과 같은 단계가 필요하다.
- 변경할 하이퍼 파라미터의 범위를 설정한다.
- Bayesian Optimization 패키지를 통해, 하이퍼 파라미터의 범위 속 값들을 랜덤 하게 가져온다.
- 처음 R번은 정말 Random 하게 좌표를 꺼내 성능을 확인한다.
- 이후 B번은 Bayesian Optimization을 통해 B번만큼 최적의 값을 찾는다.
2.Bayesian Optimization 실습
Bayesian Optimization 실습을 진행해보자.
전반적인 순서 :
- 변경할 하이퍼 파라미터의 범위를 설정한다.
- Bayesian Optimization에 필요한 함수 생성
- Bayesian Optimization를 이용해 하이퍼 파라미터 튜닝
- X에 학습할 데이터를 y에 목표 변수를 저장
X = train.drop(columns = ['index', 'quality']) y = train['quality']
- 랜덤포레스트의 하이퍼파라미터의 범위를 dictionary 형태로 지정
rf_parameter_bounds = { 'max_depth' : (1,3), # 나무의 깊이 'n_estimators' : (30,100), }
- 함수 생성
def rf_bo(max_depth, n_estimators): # 1. 함수에 들어가는 인자 = 위에서 만든 함수의 key값들 rf_params = { 'max_depth' : int(round(max_depth)), # 2. 함수 속 인자를 통해 받아와 새롭게 하이퍼파라미터 딕셔너리 생성 'n_estimators' : int(round(n_estimators)), } rf = RandomForestClassifier(**rf_params) # 3. 그 딕셔너리를 바탕으로 모델 생성 X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size = 0.2, ) # 4. train_test_split을 통해 데이터 train-valid 나누기 rf.fit(X_train,y_train) # 5.모델 학습 score = accuracy_score(y_valid, rf.predict(X_valid)) # 6. 모델 성능 측정 return score # 7. 모델의 점수 반환
- 'BO_rf"라는 변수에 Bayesian Optimization을 저장
BO_rf = BayesianOptimization(f = rf_bo, pbounds = rf_parameter_bounds,random_state = 0)
- Bayesian Optimization을 실행
BO_rf.maximize(init_points = 5, n_iter = 5)
- 하이퍼파라미터의 결괏값을 불러와 'max_params'라는 변수에 저장
max_params = BO_rf.max['params'] max_params['max_depth'] = int(max_params['max_depth']) max_params['n_estimators'] = int(max_params['n_estimators']) print(max_params)
- Bayesian Optimization의 결과를 'BO_tuend_rf'라는 변수에 저장
BO_tuend_rf = RandomForestClassifier(**max_params)
3. XGBoost 튜닝
Bayesian Optimization을 이용해 XGBoost 모델을 튜닝해보자.
XGBoost의 하이퍼파라미터들
XGBoost 파라미터 중 과적합을 방지하는 gamma, max_depth, subsample 3가지 파라미터를 튜닝해보자.
- X에 학습할 데이터를 y에 목표 변수를 저장
X = train.drop(columns = ['index', 'quality']) y = train['quality']
- XGBoost의 하이퍼파라미터의 범위를 dictionary 형태로 지정
xgb_parameter_bounds = { 'gamma' : (0,10), 'max_depth' : (1,3), # 나무의 깊이 'subsample' : (0.5,1) }
- 함수 생성
def xgb_bo(gamma,max_depth, subsample): xgb_params = { 'gamma' : int(round(gamma)), 'max_depth' : int(round(max_depth)), 'subsample' : int(round(subsample)), } xgb = XGBClassifier(**xgb_params) X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size = 0.2, ) xgb.fit(X_train,y_train) score = accuracy_score(y_valid, xgb.predict(X_valid)) return score
- 'BO_xgb'라는 변수에 Bayesian Optimization을 저장
BO_xgb = BayesianOptimization(f = xgb_bo, pbounds = xgb_parameter_bounds,random_state = 0)
- Bayesian Optimization을 실행
BO_xgb.maximize(init_points = 5, n_iter = 5)
- 튜닝된 파라미터를 바탕으로 test 데이터 셋 예측
#학습 xgb_tune =XGBClassifier(gamma = 4.376,max_depth = 3, subsample = 0.9818) xgb_tune.fit(X,y) #예측 pred = xgb_tune.predict(test.drop(columns = ['index'] )) #정답파일 내보내기 sub = pd.read_csv('data/sample_submission.csv') sub['quality'] = pred sub.to_csv('tune_xgb.csv',index = False)
4. Light GMB 튜닝
Light GBM의 하이퍼 파라미터
Light GBM 파라미터 중 주요한 n_estimators, max_depth, subsample 3가지 파라미터를 튜닝해보자.
- X에 학습할 데이터를 y에 목표 변수를 저장
X = train.drop(columns = ['index', 'quality']) y = train['quality']
- LGBM의 하이퍼파라미터의 범위를 dictionary 형태로 지정
lgbm_parameter_bounds = { 'n_estimators' : (30,100), 'max_depth' : (1,3), # 나무의 깊이 'subsample' : (0.5,1) }
- 함수 생성
def lgbm_bo(n_estimators,max_depth, subsample): lgbm_params = { 'n_estimators' : int(round(n_estimators)), 'max_depth' : int(round(max_depth)), 'subsample' : int(round(subsample)), } lgbm = LGBMClassifier(**lgbm_params) X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size = 0.2, ) lgbm.fit(X_train,y_train) score = accuracy_score(y_valid, lgbm.predict(X_valid)) return score
- 'BO_lgmb'라는 변수에 Bayesian Optimization을 저장
BO_lgbm = BayesianOptimization(f = lgbm_bo, pbounds = lgbm_parameter_bounds,random_state = 0)
- Bayesian Optimization을 실행
BO_lgbm.maximize(init_points = 5, n_iter = 5)
- 튜닝된 파라미터를 바탕으로 test 데이터 셋 예측
lgbm_tune =LGBMClassifier(n_estimators = 43 ,max_depth = 3, subsample = 1) lgbm_tune.fit(X,y) #학습 pred = lgbm_tune.predict(test.drop(columns = ['index'] )) #예측
- 정답 파일 내보내기
sub = pd.read_csv('data/sample_submission.csv') sub['quality'] = pred sub.to_csv('tune_lgbm.csv',index = False)
5. 모델 튜닝 / Voting Classifier(1)
이제 Random Forest, XGBoost, Light GBM 총 3개의 모델을 튜닝하고 Voting Classifier로 만들어 볼 것이다.
일단 Voting Classifier 정의까지 코드를 짜 보자.
- Random forest 튜닝
- XGBoost 튜닝
- LGBM 튜닝
- Voting Classifier 생성
# 모델 정의 (튜닝된 파라미터로) LGBM = LGBMClassifier(max_depth = 2.09,n_estimators=60, subsample = 0.8229) XGB = XGBClassifier(gamma = 4.376, max_depth = 2.784, subsample = 0.9818) RF = RandomForestClassifier(max_depth = 3.0, n_estimators = 35.31) # VotingClassifier 정의 VC = VotingClassifier(estimators=[('rf',RF),('xgb',XGB),('lgbm',LGBM)],voting = 'soft')
6. 모델 튜닝 / Voting Classifier(2)
이제 Voting Classifier을 이용해 train 데이터를 학습하고 test 데이터 셋을 예측해보자.
- 모델 학습
X = train_one.drop('quality',axis= 1) y = train_one['quality'] VC.fit(X,y)
- predict 메서드와 test_one 데이터를 이용해 품질 예측
pred = VC.predict(test_one)
- sample_submission.csv 파일을 불러와 예측된 값으로 채워주기
submission = pd.read_csv('data/sample_submission.csv') submission['quality'] = pred submission.head()
submission.to_csv('tune_voting.csv',index=False)
'python > 오늘의 파이썬' 카테고리의 다른 글
[DAYCON] 타이타닉 생존자 예측 (0) 2021.11.24 [DAYCON][오늘의 파이썬] Lv3. 교차검증과 LGBM 모델을 활용한 와인 품질 분류하기 (0) 2021.11.13 [DAYCON][오늘의 파이썬] Lv.2 결측치 보간법과 랜덤포레스트로 따릉이 데이터 예측하기 (0) 2021.11.04 [DACON 오늘의 파이썬][Lv1. 의사결정회귀나무로 따릉이 데이터 예측하기] (0) 2021.10.28