본문 바로가기
ML | DL

신용카드 사용자 연체 예측 AI 경진대회

by 편의점소세지 2021. 5. 27.
반응형

https://dacon.io/competitions/official/235713/overview/description

 

신용카드 사용자 연체 예측 AI 경진대회

출처 : DACON - Data Science Competition

dacon.io

최근 데이콘에서 신용카드 연체 예측 AI 경진대회를 참가했는데요. 

성적은 0.69965로 314위(상위 약 50%)로 마무리 했습니다.

이번에 준비 하면서 순위권 참가자와 저희 팀과의 차이점이 무엇인지 그리고 배웠던 내용들을 공유하려고 합니다.

 

저희는 Git으로 작업을 했고 master branch에서 pycaret.ipynb가 최고 점수를 받았습니다.

https://github.com/ICJH-DACON/Credit_card_DACON

 

ICJH-DACON/Credit_card_DACON

Contribute to ICJH-DACON/Credit_card_DACON development by creating an account on GitHub.

github.com

 

저희는 전처리를 Preprocessor.py파일을 이용해서 따로 전처리르 파일을 class를 만들었습니다. 

 

모델 작성 내용

 

전처리 내용 

  • 안쓰는 column을 drop했습니다.
  • house_type, income_type은 pd.dummy를 이용해서 원핫인코딩 했습니다.
  • edu_type, family_type은 categorical변수로 인코딩했습니다.
drop_columns = ['index', 'FLAG_MOBIL', 'child_num', 'occyp_type']
df.drop(columns=drop_columns, axis=1, inplace=True)

object_variables = ["house_type", "income_type"]

df = dummy_object(df, object_variables)
df = encode_all_order_type(df)
df = encode_YN(df)


def dummy_object(df, object_variables):
    dummied_df = pd.get_dummies(df[object_variables])
    concat_df  = pd.concat([df, dummied_df], axis=1)
    concat_df  = concat_df.drop(columns=object_variables)
    return concat_df
    
def encode_all_order_type(df) :
    df["edu_type"] = df["edu_type"].apply(encode_edu_type)
    df["family_type"] = df["family_type"].apply(encode_family_type)

    return df

def encode_family_type(item):
    types = ['Married', 'Civil marriage', 'Separated', 'Single / not married', 'Widow']
    return types.index(item)

def encode_edu_type(item):
    types = ['Higher education', 'Secondary / secondary special', 'Incomplete higher', 'Lower secondary',
             'Academic degree']
    return types.index(item)
    
def encode_YN(df):
    df['reality'] = df['reality'].apply(encode_yes_no)
    df['gender'] = df['gender'].apply(encode_gender)
    df['car'] = df['car'].apply(encode_yes_no)
    return df
    
def encode_gender(item):
    if item == 'M' or item == 1:
        return 1
    else:
        return 0

def encode_yes_no(item):
    if item == 'Y' or item == 1:
        return 1
    else:
        return 0

일일이 함수로 만들어서 인코딩했는데 나중에 보니까 from category_encoders.ordinal import OrdinalEncoder이라는 좋은 라이브러리가 있더라고요... ㅎㅎ

 

이렇게 전처리된 data를 갖고 pycaret라이브러리를 이용해서 앙상블했습니다. 

from pycaret.classification import *

clf = setup(data=train, target='credit', train_size=0.8)

add_metric('logloss', 'LogLoss', log_loss, greater_is_better=False, target='pred_proba')

best2 = compare_models(fold=5, sort='logloss', n_select=2, exclude=['svm', 'ridge'])
tuned_best2 = [tune_model(i, optimize='logloss') for i in best2]
blend_best2 = blend_models(estimator_list=tuned_best2, fold=5, optimize='logloss') 
pred = predict_model(blend_best2)

final_model = finalize_model(blend_best2)
prep_pipe = get_config('prep_pipe')
prep_pipe.steps.append(['trained_model', final_model])
pred = prep_pipe.predict_proba(test)

pycaret라이브러리에서는 현재 저장돼 있는 모든 모델을 fit해봤을 때 선택한 optimize방식에서 가장 성능이 좋은 n개(코드에서는 2개를 선택했습니다)의 모델을 선택합니다.

 

선택한 모델을 최적의 하이퍼파라미터를 tuning해주고, 이후 앙상블 모델을 만들어서 예측하는 것입니다. 저는 catboost, xgboost로 했을 때 최고점수가 나왔습니다. 또한, 코드에서 처럼 자동으로 모델을 선택하게하지 않고 직접 list에 넣어서 만들 수도 있습니다.

https://pycaret.org 에서 다양한 사용법 확인해보세요

 

Home - PyCaret

Data Preparation in PyCaret Whether its imputing missing values, transforming categorical data, feature engineering or even hyperparameter tuning of models, PyCaret automates all of it. It orchestrates the entire pipeline no matter how complex it is. 

pycaret.org

 

 

우승팀과의 차이점

 

우승팀의 코드가 올라왔는데 가장 큰 요인은 파생변수 생성 및 전처리 방식이 문제였다고 생각합니다. 

1위 팀 '소회의실'팀의 코드의 전처리를 보겠습니다.

 

1위팀의 모델은 15개의 k-fold하고, catboost를 사용했습니다.

 

전처리 방식

  • before_EMPLOYED: 고용되기 전까지의 일수
  • DAYS_BIRTH 파생변수- Age(나이), 태어난 월, 태어난 주(출생연도의 n주차)
  • DAYS_EMPLOYED_m 파생변수- EMPLOYED(근속연수), DAYS_EMPLOYED_m(고용된 달) ,DAYS_EMPLOYED_w(고용된 주(고용연도의 n주차))  
  • ability: 소득/(살아온 일수+ 근무일수)
  • income_mean: 소득/ 가족 수
  • ID 생성: 각 컬럼의 값들을 더해서 고유한 사람을 파악(*한 사람이 여러 개 카드를 만들 가능성을 고려해 begin_month는 제외함)

앞으로 더 많이 공부해야겠습니다.

 

 

반응형

댓글