qcoding

[데이터분석실습][이진분류_LR]_Categorical Feature Encoding Challenge 본문

Python 데이터분석

[데이터분석실습][이진분류_LR]_Categorical Feature Encoding Challenge

Qcoding 2022. 7. 3. 17:26
반응형

https://www.kaggle.com/competitions/cat-in-the-dat

 

Categorical Feature Encoding Challenge | Kaggle

 

www.kaggle.com

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791191905076&orderClick=LAV&Kc= 

 

머신러닝·딥러닝 문제해결 전략 - 교보문고

캐글 수상작 리팩터링으로 배우는 문제해결 프로세스와 전략 | 이 책은 수많은 캐글 수상자의 노트북을 수집/분석하여 여러분께 공통된 문제해결 패턴을 안내해줍니다. 총 7개의 경진대회를 이

www.kyobobook.co.kr

해당 책을 공부하면서 필요한 부분을 정리하였습니다.

 

 

## 범주형 데이터 인코딩 방법

1) 데이터 확인

# 데이터 둘러보기

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl


train=pd.read_csv('/kaggle/input/catinthedat1/train.csv',index_col='id')
test=pd.read_csv('/kaggle/input/catinthedat1/test.csv',index_col='id')
submission=pd.read_csv('/kaggle/input/catinthedat1/sample_submission.csv',index_col='id')

print(train.shape , test.shape)

print(train.shape)
print(test.shape)

# 데이터 확인하기
train.head().T

# 데이터 분석을 위한 resumtable 함수 

def resumetable(df):
    print(f'데이터셋 형상 {df.shape}')
    summary=pd.DataFrame(df.dtypes, columns=['데이터타입'])
#     reset_index()를 하면 기존에 index 였던 피처 열이 뒤로 가면서 "index" 라는 column 이름이 되고 앞에 새로운 숫자 인덱스가 생김
    summary=summary.reset_index()
    summary=summary.rename(columns={'index' : '피처'})
    summary['결측값 갯수'] = df.isnull().sum().values
    summary['교윳값 갯수'] = df.nunique().values
#     loc를 통해서 index 이름으로 가져옴
    summary['첫번째 값']=df.iloc[0].values
    summary['두번째 값']=df.iloc[1].values
    summary['세번째 값']=df.iloc[2].values

    return summary
resumetable(train)

-> 고윳값과 이름에 따라 피처들을 분리함

-> 1) 이진 bin 0 ~ 4

    2) 명목형 (nominal) nom_0 ~ nom_9

    3) 순서형 (ordinal) ord_0 ~ ord_5

    4) 그외    day,month, target

-> 이진분류에서 bin_3 / bin_4 의 경우 "T" , "Y" 를 숫자형으로 바꿔주어야함

-> 명목형데이터 nom_5 ~ nom_9 의 고윳값은 매우많음

 

## 인코딩시에 각각의 순서에 맞게 매칭 하려면 미리 어떤식으로 순서를 정할지 생각해야함

-> 순서형 ord_ 데이터들은 순서가 중요함. 교윳값들을 확인함

for i in range(3):
    feature = 'ord_'+str(i)
    print(f'{feature} 교유값 : {train[feature].unique()}')

ord_0 : 숫자형이므로 숫자 크기에 순서를 맞춤

ord_1 : 캐글 등급이므로 등급으로 순서를 맞춤 --> Novice - Contributor -> Expert - > Grandmaster

ord_2 : 날씨이므로 내가 임의로 인코딩 순서를 정함 -> Freezing, Cold, Warm, Hot, Boiling Hot, Lava Hot

 

for i in range(3,6):
    feature = 'ord_'+str(i)
    print(f'{feature} 교유값 : {train[feature].unique()}')

 

ord_3 ~ ord_5 는 알파벳이므로 알파벳 순서에 맞게 인코딩 진행

 

print(f'day 교유값 : {train["day"].unique()}')
print(f'month 교유값 : {train["month"].unique()}')
print(f'target 교유값 : {train["target"].unique()}')

day의 경우는 1~7로 되어있으므로, 요일을 나타낸 다는 것을 짐작할 수 있음.

 

 

2) 데이터 시각화

2-1) 타킷값 분포

- 데이터의 불균형 정도나 정규분포 형태를 비교할 때 사용함. (회귀 시 정규분포 형태가 좋음)

## 데이터 시각화
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline

#타킷값 분포확인
mpl.rc('font',size=15)
plt.figure(figsize=(7,6))

ax=sns.countplot(x='target' , data=train)
ax.set(title="Target")

# ax를 통해서 그래프 사각형의 높이 / 너비 / 위치를 파악함
rectangle = ax.patches[0]
print('사각형 높이',rectangle.get_height())
print('사각형 너비',rectangle.get_width())
print('사각형 왼쪽 테두리의 x축 위치',rectangle.get_x())


#  텍스트 위치의 x , y좌표 계산
# countplot 에서 막대 도형의 높이는 데이터 갯수와 동일함

print('텍스트 위치의 x 좌표', rectangle.get_x() + rectangle.get_width()/2)
print('텍스트 위치의 y좌표', rectangle.get_height() + len(train) * 0.001)

## 막대그래프위에 텍스트를 입력하는 함수

def write_percent(ax,total_size):
    for patch in ax.patches:
        height = patch.get_height()
        width = patch.get_width()
#         도형의 왼쪽 테두리
        left_coord = patch.get_x()
#     전체에서 비율을 얼마나 차지하는지
        percent = height / total_size * 100
    
#     (x,y) 좌표에 텍스트 입력
        ax.text(
            x=left_coord + width / 2,
            y= height + total_size * 0.001,
            s=f'{percent:1.1f}%',
#             가운데정렬
            ha='center'
        )
plt.figure(figsize=(7,6))

ax= sns.countplot(x='target' , data=train)
write_percnet(ax, len(train))
ax.set(title='Target')

 

2-2) 이진 피처 분포확인

# 이진 분포 확인
# GridSpec 사용함
import matplotlib.gridspec as gridspec

# 3행 2열 tool 준비
mpl.rc('font' , size=12)
# 3행 2열
grid=gridspec.GridSpec(3 , 2)
plt.figure(figsize=(10,16))
# subplot 간 좌우 여백 설정
plt.subplots_adjust(wspace=0.4 , hspace=0.3)


# subplot 그래프 그리기
bin_features=['bin_0','bin_1','bin_2','bin_3','bin_4']

for idx, feature in enumerate(bin_features):
#     위에서 만든 grid에 몇번째에 해당하는 지 선택함
    ax=plt.subplot(grid[idx])
    
#     ax축에 타킷값 분포 카운트 plot 그리기
    sns.countplot(
        x=feature,
        data=train,
        hue='target',
#         그래프 색상 설정
        palette='pastel',
        ax=ax
    )
    ax.set(title=f'{feature} by target')
    write_percnet(ax,len(train))

2-3) 명목형(nominal) 피처 분포 확인

-> 여기서는 nom_5 ~ nom_9는 고윳값 갯수가 많고 의미없는 문자열이므로 nom_0 ~ nom_4 피처만 확인함

 

## 1) 교차분석표 생성함수 만들기

-> 교차표 (cross-tablation) , 교차분석표는 범주현 데이터 2개를 비교 분석하는 데 사용되는 표로 각 범주형 데이터의 빈도나 통계량을 행과 열로 결합해놓은 표

-> 목적은 명목형 피처별 타킷값 1비율울 구하기 위함 -> point plot을 구하기 위함

# 교차분석표 -> nom_0 피처

crosstab=pd.crosstab(train['nom_0'],train['target'], normalize='index')*100
crosstab

-> 고유한 값마다 target이 어떻게 이루어 져있는지 비율로 확인가능함. ex) Blue 인 경우 target이 1인 비율은 24.1% 임

## 현재 인덱스가 피처 이름이므로 열로 가져와야 그래프를 그리기 편하기 때문에 피처를 열로 만들어줌
crosstab=crosstab.reset_index()
crosstab

## 교차분석표 만드는 함수

def get_crosstab(df,feature):
    crosstab=pd.crosstab(df[feature],df['target'],normalize='index') * 100
    crosstab=crosstab.reset_index()
    return crosstab
#각 column 가져오기
# crosstab['nom_0']
# crosstab[0]
crosstab[1]

 

 

## 2) Point plot 생성함수 만들기

## 포인트 플롯 생성함수 만들기
#  countplot을 그린 위에 포인트 플롯을 중첩해서 그림

# ax : 포인트 플폿을 그릴 축
# feature : 포인트 플롯을 그릴 피처
# crosstab : 교차분석표

def plot_pointplot(ax,feature,crosstab):
#     x축은 공유하고, y축은 공유하지 않는 새로운 축생성
    ax2=ax.twinx()
    
#     포인트플롯 그리기
    ax2 = sns.pointplot(
        x=feature,
#         비율이므로 100% -> 1이 max값임
        y=1,
        data=crosstab,
#         포인트 플롯의 순서
        order=crosstab[feature].values,
        color='black',
        legend=False
    )

#     y축범위
    ax2.set_ylim(crosstab[1].min()-5 , crosstab[1].max()*1.1)
    ax2.set_label('Target 1 Ratio(%)')

 

 

## 3) 피처 분포도 및 피처별 타깃값 1의 비율 포인트 플롯 생성함수 만들기

## 피처 분포도 및 피처별 타깃값 1의 비율 포인트 플롯 생성함수 만들기

def plot_cat_dist_with_true_ratio(df, features, num_rows, num_cols, size=(15,20)):
    plt.figure(figsize=size)
    grid=gridspec.GridSpec(num_rows,num_cols)
    plt.subplots_adjust(wspace=0.45 , hspace = 0.3)
    
    for idx, feature in enumerate(features):
        ax=plt.subplot(grid[idx])
#         교차분석표 생성
        crosstab = get_crosstab(df,feature)
    
#     ax축에 타깃값 분포 카운트 플롯 그리기
        sns.countplot(
            x=feature,
            data=df,
            order=crosstab[feature].values,
            color='skyblue',
            ax=ax
        )
#     비율표시
        write_percent(ax,len(df))

#     point plot 그리기
        plot_pointplot(ax,feature,crosstab)
#     그래프 제목설정
        ax.set_title(f'{feature}')

 

features=["nom_0","nom_1","nom_2","nom_3","nom_4"]
plot_cat_dist_with_true_ratio(train,features,num_rows=3, num_cols=2 )

-> 각 point plot은 target 1에 해당하는 비율로 카테고리에 따라 비율이 달라지는 것으로 nom_0 ~ nom_4는 타켓을 구별하는 필요한 feature라는 것을 확인할 수 있다.

-> 각 피처는 one-hot 인코딩을 사용함

 

 

2-4) 순서형 피처 분포 확인

->  ord_0 ~ ord_3 까지 교윳값이 15개 이하

-> ord_4, ord_5 는 교윳값이 매우 많음

features=["ord_0","ord_1","ord_2","ord_3"]
plot_cat_dist_with_true_ratio(train,features,num_rows=2, num_cols=2 )

-> 순서형은 피처 자체에 순서를 부여하기 위해서 CategoricalDtype() 함수를 사용함

-> 변경된 것을 확인하기 위해서 변경전 데이터를 확인함

-> ord_0 은 숫자이고 , ord_3은 알파벳임, 위의 함수에서 countplot을 그릴 때 order=crosstab[feature].values 를 사용하여, 순서를 feature 의 순서로 했으므로, 숫자와 알파벳은 순서대로 분류가 되어있음.

 

# CategoricalDtype 
# categories : 범주형 데이터 타입으로 인코딩할 값 목록
# ordered : True로 설정하면 categories에 전달한 값의 순서가 유지됨

from pandas.api.types import CategoricalDtype

# 임의로 순서를 정함
ord_1_values=['Novice','Contributor','Expert','Master','Grandmaster']
ord_2_values=['Freezing','Cold','Warm','Hot','Boiling Hot','Lava Hot']

# 순서를 지정한 범주형 데이터 타입
ord_1_dtype=CategoricalDtype(categories=ord_1_values , ordered=True)
ord_2_dtype=CategoricalDtype(categories=ord_2_values , ordered=True)

# 데이터 타입 변경
train['ord_1']=train['ord_1'].astype(ord_1_dtype)
train['ord_2']=train['ord_2'].astype(ord_2_dtype)

위에서 변경후에는 dtype이 object -> category로 변경되었으며, Categories에서 피처 자체에 순서를 부여하고 있음을 확인할 수 있음.

 

그래프를 다시 그려보면

features=["ord_0","ord_1","ord_2","ord_3"]
plot_cat_dist_with_true_ratio(train,features,num_rows=2, num_cols=2 )

위와 같이 순서로 정렬이 되며, 고윳값의 순서에 따라 target 이 1이 되는 비율도 커진 다는 것을 확인할 수 있음.

##ord_4 / ord_5의 분포를 확인
features=["ord_4","ord_5"]
plot_cat_dist_with_true_ratio(train,features,num_rows=2, num_cols=1,size=(15,12))

위의 ord_4 , ord_5 는 알파벳으로 countplot을 그릴 때 order=crosstab[feature].values로 알파벳순서로 정렬이 되었으며, 모두 순서형에 따라 target 1의 비율이 높아지는 것을 알 수 이음.

 

 

2-5) 날짜 피처 분포확인

## 날짜 피처 분포 확인
date_feature=['day','month']
plot_cat_dist_with_true_ratio(train,date_feature,num_rows=2, num_cols=1,size=(12,12))

-> day 와 month를 보면 약간의 반대되는 경향을 보임.

-> day와 month 둘다 숫자형이므로 머신러닝에서는 1 <-> 2월은  1<->3월 보다 가까운 것일 수록 연관성이 크다고 생각함.

그러나 12월 -> 1월은 한달 차이이지만 숫자가 크므로 연관성이 떨어진다고 파악하게 됨.

-> 이럴 경우 삼각함수 인코딩을 하여 시작과 끝을 매끄럽게 연결함

-> 매년 / 매월 / 매주 /매일 등 반복된느 데이터를 순환형 데이터 (cyclical data) 라고 함.

-> 책에서는 one-hot encoding이 성능이 더 좋으므로, 요일/ 월에 one-hot-encoding을 적용함.

 

 

3) 모델링

1) 이진 피처 인코딩 : 값이 숫자가 아닌 이진 피처는 0과 1로 인코딩

2) 명목형 피처 인코딩 : 전체 데이터가 크지 않으므로 모두 one-hot 인코딩

3) 순서형 피처 인코딩 : 고윳값들의 순서에 맞게 인코딩 ( 이미 숫자인 경우 인코딩 필요없음)

4) 날짜 피처 인코딩 : 값의 크고 작음으로 해석되지 못하도록 one-hot 인코딩

 

3-1) base 모델 - 로지스틱 회귀 모델

## 모델링
# 베이스라인 모델
train=pd.read_csv('/kaggle/input/catinthedat1/train.csv',index_col='id')
test=pd.read_csv('/kaggle/input/catinthedat1/test.csv',index_col='id')
submission=pd.read_csv('/kaggle/input/catinthedat1/sample_submission.csv',index_col='id')

#피처 엔지니어링을 위한 데이터 합치기
all_data = pd.concat([train,test],axis=0)
all_data=all_data.drop(columns=['target'] , axis=1)
all_data

 

# one-hot encoding

# 원핫인코딩
# all_data 내에서 숫자형과 문자형이 섞여 있으므로 숫자형만 해도 되지만, 여기서는 전체 다 수행함

from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder()
all_data_endcoed = encoder.fit_transform (all_data)

print(all_data_endcoed.shape)

# 피처엔지니어링 후 데이터 나누기

# 데이터 나누기
from sklearn.model_selection import train_test_split

num= len(train)
X_train = all_data_encoded[:num]
X_test= all_data_encoded [num:]
y=train['target']

# train 데이터 일부를 검증 데이터로 나누기
# 모델의 완성도를 확인하기 위해서 검증데이터를 사용함
# stratify 는 train과 valid 데이터 set을 나눌 때 y값이 어느 한쪽에만 1이나 0으로 몰리는 것이 아니라 공평하게 나누어 지기 위해서 사용함
# 사용하지 않을 경우-> 데이터가 불균등하게 나누어져서 학습에는 target이 1로만 했을 경우 0이 나올 확률이 낮아지므로 제대로 학습이 되지않음

X_train , X_valid , y_train , y_valid = train_test_split(X_train , y , test_size=0.1 , stratify = y, random_state=10)

print("X_train" , X_train.shape)
print("X_valid" , X_valid.shape)
print("y_train" , y_train.shape)
print("y_valid" , y_valid.shape)

## 모델학습

# logistic 모델
from sklearn.linear_model import LogisticRegression

logistic_model = LogisticRegression(max_iter=1000, random_state=42)
logistic_model.fit(X_train , y_train)

## 모델 성능검증

# 모델 성능검증
# pedict / predict_proba()
# 0열은 0이될 확률 , 1열은 1일될 확률

logistic_model.predict_proba(X_valid)

logistic_model.predict(X_valid)

## target값이 1이 될 확률 , 1번째열
## 이번대회에서는 target이 1이 될 확률을 예측하는 것이므로 predict_proba()를 사용하여 비교함
y_valid_preds = logistic_model.predict_proba(X_valid)[:,1]

from sklearn.metrics import roc_auc_score

# ROC AUC 점수계산
roc_auc = roc_auc_score(y_valid , y_valid_preds)

print(f"검증 데이터 ROC ACU : {roc_auc :.4f}")

## 예측 및 결과제출

## 결과제출
#  test 데이터를 사용하여 결과예측
y_preds = logistic_model. predict_proba(X_test)[:,1]

# 제출파일 생성
submission['target'] = y_preds
submission.to_csv('submission.csv')

 

4) 성능개선 1

1) 피처 맞춤 인코딩

-> 이진 피처와 순서형 피처 ord_1 , ord_2는 수작업 인코딩

-> 순서형 ord_3, ord_4 , ord_5는 ordinal 인코딩

-> 명목형 , 날짜형 one-hot 인코딩

 

2) 피처 스케일링

-> 순서형 피처에만 적용하며, 이진피처는 0과 1 , 명목형과 날짜형도 one-hot 인코딩 후에 0과 1로 되므로 최소/최대값이 0/1로 되므로 관계없음

 

3) 하이퍼 파라미터 최적화

 

 

 

1) 피처 맞춤 인코딩 

1-1) 이진피처

## 성능개선
## 모델링
train=pd.read_csv('/kaggle/input/catinthedat1/train.csv',index_col='id')
test=pd.read_csv('/kaggle/input/catinthedat1/test.csv',index_col='id')
submission=pd.read_csv('/kaggle/input/catinthedat1/sample_submission.csv',index_col='id')

#피처 엔지니어링을 위한 데이터 합치기
all_data = pd.concat([train,test],axis=0)
all_data=all_data.drop(columns=['target'] , axis=1)
## 이진피처 인코딩
# bin_3과 bin_4는 F / T 와 N/ Y로 되어 있으므로 인코딩 필요함
# Series 데이터 형태에 map 함수를 적용함

all_data['bin_3'] = all_data['bin_3'].map({'F':0 , 'T':1})
all_data['bin_4'] = all_data['bin_4'].map({'N':0 , 'Y':1})

1-2) 순서형 피처 인코딩

## 순서형 피처 인코딩
# ord_0은 숫자로 인코딩 x 
# ord_1 과 ord_2는 순서를 통해서 인코딩
# ord_3 ~ ord_5는 알파벳 순서대로 인코딩


# ord_1 , ord_2
# 앞에서 작성한 임의 순서대로 숫자로 인코딩을 진행함
ord_1_dict={'Novice':0,'Contributor':1,'Expert':2,'Master':3,'Grandmaster':4}
ord_2_dict={'Freezing':0,'Cold':1,'Warm':2,'Hot':3,'Boiling Hot':4,'Lava Hot':5}

all_data['ord_1'] = all_data['ord_1'].map(ord_1_dict)
all_data['ord_2'] = all_data['ord_2'].map(ord_2_dict)


# ord_3 ~ ord_5 는 알파벳 순서이므로 sklearn 의 OrdinalEncoer를 사용함

from sklearn.preprocessing import OrdinalEncoder

ord_345=['ord_3','ord_4','ord_5']

ord_encoder= OrdinalEncoder()

# ord_3~ ord_5 까지 인코딩진행함
all_data[ord_345]=ord_encoder.fit_transform(all_data[ord_345])

# 인코딩이 잘되었는 지출력함. ord_encoder.categories_ 에 각각의 카테고리 분류가 순서대로 들어가 있음
for feature , category in zip (ord_345 ,ord_encoder.categories_ ):
    print(f"feature : {feature}")
    print(f'category : {category}')

# 인코딩 후 비교
# 알파벳 순서대로 숫자로 인코딩되었음.
all_data[ord_345].head()

 

1-3) 명목형 피처 인코딩

# 명목형 피처 인코딩
# nom_0 ~ nom_9,  총10개

nom_features= [f'nom_{i}' for i in range(10)]

# one-hot encoding 진행
# 기존행렬에 추가하면 열이 너무 많아지기 때문에 별도의 matrix (CSR 형태 Compressed Sparse Row)
# one-hot encoding을 하면 대부분의 값이 0인 희소행렬 (sparse)행렬이 생기므로 메모리 낭비를 하지 않기 위해 CSR 형태를 사용함

from sklearn.preprocessing import OneHotEncoder

onehot_encoder = OneHotEncoder()
encoded_nom_matrix = onehot_encoder.fit_transform(all_data[nom_features])

encoded_nom_matrix

## 기존행렬에 명목형 피처를 삭제함
all_data=all_data.drop(columns=nom_features , axis=1)

1-4) 날짜 피처 인코딩

## 날짜 피처 인코딩
date_features= ['day','month']

from sklearn.preprocessing import OneHotEncoder

onehot_encoder = OneHotEncoder()
encoded_date_matrix = onehot_encoder.fit_transform(all_data[date_features])

# 기존피처 삭제
all_data=all_data.drop(columns=date_features , axis=1)

encoded_date_matrix

 

2) 피처 스케일링

## 순서형 피처 스케일링 진행

-> 순서형은 알파벳이나 임의로 부여한 순서대로 되어있으므로 숫자에 0 , 1, 2 ,3 등 크기가 다르므로 다른 이진변수나 one-hot encoding 변수는 0과 1인데 반해서 숫자가 크므로 더 높은 영향을 미친다고 모델이 파악할 수 있으므로 올바른 학습을 위해서 피처스케일링을 진행함

 

## 순서형 변수 피처 스케일링 사용

from sklearn.preprocessing import MinMaxScaler

ord_features = [ f'ord_{i}' for i in range(6)]

# min-max 정규화
all_data[ord_features] = MinMaxScaler().fit_transform(all_data[ord_features])

 

## 피처 합치기 ( CSR 형식으로 합쳐서 사용함)

# 피처 합치기
# all_data 는 dataframe 이고 encoded_nom_matrix와 encoded_date_matrix 는 csr 형태이므로 모두 csr 형태로 맞춰서 합춰줌

from scipy import sparse

# 가로로 합치기 
all_data_sprs = sparse.hstack(
        [
            sparse.csr_matrix(all_data),
            encoded_nom_matrix,
            encoded_date_matrix
        ],
    format='csr'
)
all_data_sprs

## 데이터 나누기

## 데이터 나누기

num=len(train)

X_train = all_data_sprs[:num]
X_test = all_data_sprs[num:]

y=train['target']


from sklearn.model_selection import train_test_split

X_train , X_valid , y_train , y_valid = train_test_split(X_train, y, test_size = 0.1, stratify= y , random_state=10)

print("X_train" , X_train.shape)
print("X_valid" , X_valid.shape)
print("y_train" , y_train.shape)
print("y_valid" , y_valid.shape)

 

3) 하이퍼 파라미터 최적화

## 하이퍼파라미터 최적화

# C는 규제 강도 -> 작을 수록 규제강도가 세짐

# 소요시간을 출력해줌
%%time

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression

# 모델생성
logistic_model = LogisticRegression()

# 하이퍼파라미터 
lr_params={
    'C':[0.1 , 0.125, 0.2],
    'max_iter' : [800, 900 ,1000],
    'solver' : ['liblinear'],
    'random_state':[42]
}


# gridsearch 객체생성

gridsearch_logistic_model = GridSearchCV(
            estimator = logistic_model,
            param_grid =lr_params,
            scoring = 'roc_auc',
            cv=5
)

gridsearch_logistic_model.fit(X_train , y_train)

best_parameter = gridsearch_logistic_model.best_params_

print("최적 파라미터",best_parameter)

## 모델성능검증
y_valid_preds=gridsearch_logistic_model.best_estimator_.predict_proba(X_valid)[:,1]

# 검증데이터 ROC AUC
from sklearn.metrics import roc_auc_score

roc_auc= roc_auc_score(y_valid, y_valid_preds)

print(f'검증데이터 roc_auc: {roc_auc}' )

## 예측 및 결과제출
y_preds=gridsearch_logistic_model.best_estimator_.predict_proba(X_test)[:,1]

# 제출파일 생성
submission['target']=y_preds
submission.to_csv('./submission.csv')

 

4) 성능개선 2

-> 앞에서 10% 를 valid data set으로 검증에 사용하였는데, train data 양이 많을 수록 좋기 대문에

-> train_test_split 에서 test_size = 0.1로 해서 10%를 사용한 것만 지우고 다시 똑같이 사용하면

   점수를 향상시킬 수 있음

-> 모델을 정했다면 모델의 향상을 위해 마지막 검증데이터 모두를 훈련에 사용함.

 

반응형
Comments