https://dacon.io/competitions/official/235713/overview/description
최근 데이콘에서 신용카드 연체 예측 AI 경진대회를 참가했는데요.
성적은 0.69965로 314위(상위 약 50%)로 마무리 했습니다.
이번에 준비 하면서 순위권 참가자와 저희 팀과의 차이점이 무엇인지 그리고 배웠던 내용들을 공유하려고 합니다.
저희는 Git으로 작업을 했고 master branch에서 pycaret.ipynb가 최고 점수를 받았습니다.
https://github.com/ICJH-DACON/Credit_card_DACON
저희는 전처리를 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 에서 다양한 사용법 확인해보세요
우승팀과의 차이점
우승팀의 코드가 올라왔는데 가장 큰 요인은 파생변수 생성 및 전처리 방식이 문제였다고 생각합니다.
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는 제외함)
앞으로 더 많이 공부해야겠습니다.
'ML | DL' 카테고리의 다른 글
AutoML_Alex 라이브러리 설명 (0) | 2021.07.15 |
---|---|
RandomForest, XGBoost, LGBM, CatBoost뭐가 다를까? (1) | 2021.06.09 |
ALS 추천시스템(Implicit 라이브러리) (0) | 2021.06.01 |
프로그래머스 Dev-Matching 머신러닝 개발자 - 아직 공부가 부족하다 (0) | 2021.05.25 |
댓글