AI/제주 신용카드 빅데이터 경진대회

[2] Gradient Boosting 알고리즘 적용해 보기

eraser 2020. 7. 22. 00:09
반응형

# 지난 궁금증

 

1. 피쳐를 추가하여 예측하면 안 되는 것인지?
2. CANCEL 변수를 만들어 확인해 보니, 취소한 경우가 압도적으로 많았다. 단순히 3범주로 나누면 안 되는 것이었나?
☞ 피쳐 추가 및 범주 개수가 문제가 아니라, 전처리 및 범주 나누는 방향을 잘못 설정한 게 아닐까 싶다. 조금 더 고민해볼 것!

3. 예측 시 단순히 average를 취하는 것 말고 지역, 업종별로 CANCEL의 가중평균을 취해준다든지, 아니면 애초에 예측 템플릿을 pd.merge 등을 활용해 CANCEL 변수만 join해주는 방법을 사용해야 할 듯하다.

☞ 애초에 예측 데이터 시계열이 달라서 CANCEL 변수 join하기는 어려울 듯하다. 생각해 보니까 데이터베이스에 대한 이해만 조금만 더 했더라면, 어차피 unique key가 아니라 불가능한 방법이었다. 내가 구현하고 싶었던 대로 하려면, CUSTMR_CNT 등 다른 변수를 써야 하는데, 이 역시 unique key로 잡을 수는 없다. 예측 템플릿에서는 CUSTMR_CNT도 종속 변수라고 간주해야 하니까.
☞ 가중 평균 취하는 방법은. 음, 이것도 적당한 방법은 아닐 것 같다. 예측 템플릿에서는 애초에 년, 월이 달라지니까 이 방법 쓰는 게 적절한지 모르겠다.

 

 


 

# Gradient Boosting 모델링

 

 

 원자력 발전소 상태판단 경진대회, 천체 유형 분류 대회를 거치며 가장 좋은 결과를 낸 모델은 LGBM 모델이었다. 특별히 전처리, Feature Engineering을 진행하지 않았음에도 불구하고 하이퍼파라미터 조정만으로 리더보드 상에서 점수를 올릴 수 있었다. 물론 데이터에 대해 명확한 이해 없이 전처리, Feature Engineering을 진행하지 않고 하이퍼파라미터만 조정한다는 것은 그다지 좋지 않은(?) 발상이다. 그러나 이러한 종류의 경진대회를 진행함에 있어서 베이스라인 코드에 서로 다른 단일 알고리즘을 적용해 성능이 어떻게 달라지는지를 파악하는 것이 중요하다고 생각하기 때문에, 그 동안 좋은 결과를 얻었던 LGBM 모델, Kaggle에서 핫한 XGBoost 알고리즘을 적용해 Baseline 코드와 점수가 어떻게 달라지는지 비교해 본다.

 

 LGBM, XGBoost 알고리즘 각각에 대해 두 가지 경우를 적용해 본다. 첫째는 Baseline 코드와 동일하게 전처리를 진행하는 것, 둘째는 이전 단계에서 Baseline 코드에서 Cancel 피쳐를 추출해 활용하는 것이다.

 

 

 


 

 

1. LGBM

 

1.1. Baseline 전처리

 

 LGBM 모델에 넣을 수 있는 데이터셋 형태로 바꿔주기만 하면 된다. 평가 지표가 RMSLE이기 때문에, LGBM 모델 상에서 metric은 RMSE로 설정해 주었다.

 

 처음 적용한 파라미터는 다음과 같다. 

# 모델 파라미터
params_ = {
            'boosting_type': 'gbdt',
            'objective': 'regression',
            'metric': 'rmse',
            'learning_rate': 0.025,
            'metric_freq': 10,
            'max_depth': -1,
            'early_stopping_round': 50,
            'verbose': 1
           }

 

 훈련 데이터의 20%를 테스트 데이터로 남겨 놓고, 최초 훈련 에폭을 2000으로 설정한 뒤 RMSE 스코어의 변화 추이를 살펴 보았다.

[50]	valid_0's rmse: 2.28705
[100]	valid_0's rmse: 2.15662
[150]	valid_0's rmse: 2.05475
[200]	valid_0's rmse: 1.9864
[250]	valid_0's rmse: 1.93352
[300]	valid_0's rmse: 1.8876
[350]	valid_0's rmse: 1.8521
[400]	valid_0's rmse: 1.81719
[450]	valid_0's rmse: 1.78667
[500]	valid_0's rmse: 1.7558
...
[1500]	valid_0's rmse: 1.40913
[1550]	valid_0's rmse: 1.4005
[1600]	valid_0's rmse: 1.39246
[1650]	valid_0's rmse: 1.38282
[1700]	valid_0's rmse: 1.37158
[1750]	valid_0's rmse: 1.35788
[1800]	valid_0's rmse: 1.34697
[1850]	valid_0's rmse: 1.33784
[1900]	valid_0's rmse: 1.32572
[1950]	valid_0's rmse: 1.31378
[2000]	valid_0's rmse: 1.29997

 

 

 예측하고 리더보드 상에서 점수를 확인했을 때, 6.56xxx 정도가 나왔다. learning rate를 바꿔 보고, 학습 횟수를 늘려 보았는데, 학습 횟수를 늘릴수록 rmse 점수는 낮아지고, 학습 횟수를 10000까지 잡아도 조기 종료가 되지 않았다. 계속해서 학습 횟수를 늘리며 리더보드 상에서 점수를 측정해 보았는데, 제일 낮은 점수는 6.13xx 정도가 나왔다. RMSE 스코어가 낮아질수록 리더보드 상에서의 점수도 낮아져서 비례 관계가 있는 듯하다. 그러나 학습 횟수만 늘려 가며 계속해서 관찰하는 것이 의미가 없다고 생각해 종료했다.

 

 마침 코드 공유 게시판에 LGBM 파라미터를 조정해 가며 1점대의 점수를 얻었다는 글이 있었다. 해당 유저가 설정한 파라미터는 다음과 같다.

params = {
            'learning_rate' : 0.05,
            'boosting_type': 'gbdt',
            'objective': 'tweedie',
            'tweedie_variance_power': 1.1,
            'metric': 'rmse',
            'sub_row' : 0.75,
            'lambda_l2' : 0.1
        }

 

 

1.2. Cancel 피쳐 추가

 

 베이스라인 코드에 Cancel 피쳐를 추가해서 RandomForest 모델링을 진행했을 때와 동일하게 피쳐를 추가했다. 리더보드 상에서 가장 좋은 점수를 얻었던 파라미터 설정과 동일하게 모델 훈련 및 예측을 진행하고, 제출해 보았다. 6.52xx 정도의 점수가 나왔다. 아무래도 Cancel 피쳐를 추가하고 예측을 진행했을 때 좋은 결과가 나오지는 않는 듯하다.

 

 


 

 

 

2. XGBoost + Cancel 피쳐 추가

 

 Baseline 코드에 XGBoost 알고리즘만 적용해 봤을 때는 LGBM과 비슷하게 6점 후반대에서 초반대 정도가 나온다.  다른 팀원이 Baseline 코드 전처리에 2019년 12월 이후의 데이터만 활용하고, Cancel 피쳐를 만들어 다음의 파라미터를 적용했을 때에는 6.86 정도의 점수가 나온다.

 

from xgboost import XGBRegressor

# 모델 파라미터 설정
model = XGBRegressor(learning_Rate=0.01,
                     max_depth=6,
                     min_child_weight=3,
                     n_estimators=300,
                     nthread=4,
                     objective='reg:linear')

 

 다만 이 경우 적용한 방법은 내가 적용한 방법과 다르다. 나는 Cancel을 feature로 두고 예측 템플릿에서도 활용하여 각 경우의 예측치를 평균해주었지만, XGBoost 알고리즘을 담당한 팀원은 모델 훈련 시에만 Cancel을 활용하고 예측 템플릿에서는 Cancel을 활용하지 않았다.

 어떠한 경우든 Cancel 피쳐를 활용해서 예측을 진행했을 때, 그러지 않았을 때에 비해 예측 정확도는 낮아진다.

 

 

 


# 배운 점 및 더 생각해볼 점

 

 확실히, 별 다른 전처리를 진행하지 않은 상태에서도 범주형 변수만을 가지고 Gradient Boosting 알고리즘을 적용하면 Baseline 코드보다 점수는 높게 나온다. 단일 모델만을 사용한다고 가정했을 때, Random Forest 알고리즘보다는 Gradient Boosting 알고리즘이 성능이 조금 더 나은 듯하다.

 

 다만 Cancel 피쳐를 추가하는 부분은 고민해보아야 할 듯하다. 동일한 전처리, 동일한 파라미터를 가지고 훈련 및 예측을 진행했음에도 불구하고 Cancel 피쳐를 추가하지 않았을 때와 비교해 점수가 0.5 정도 낮게 나온다. RMLSE 평가 지표 상에서 0.5가 떨어지면, 예측 정확도가 상당히 떨어진다고 볼 수 있다.

 고민해 본 결과, Cancel 변수는 애초에 모델을 만들 때 피쳐로 사용하기에 적합하지 않은 것이라고도 보인다. 데이터의 특성 상, AMT 뿐만 아니라 CSTMR_CNT, CNT도 모두 각 feature별로 집계했을 때 나오는 결과 변수(혹은 종속 변수?)로 보아야 한다. 따라서 이 변수를 활용해 만든 Cancel 변수 역시 데이터를 feature별로 집계했을 때 나오는 결과 변수이다.

 따라서 이를 활용하고자 한다면, 다음과 같은 문제가 발생한다. 첫째, 예측 템플릿에서는 CSTMR_CNT, CNT가 없어 Cancel을 만들 수 없다. XGBoost 알고리즘 적용 시 사용한 방법처럼 예측 시에는 Cancel 변수를 사용할 수 없다. 둘째, Cancel 변수를 새로운 범주형 파생변수로 만들어 훈련 데이터 및 예측 템플릿에 추가하고자 할 경우, 곱연산 시 경우의 수가 3배로 늘어난다. 내가 적용했던 방법이지만, 결과적으로 예측 값을 산정할 때 경우의 수가 늘어나 버리기 때문에 문제가 된다.

 

 

1. 지난 번부터 계속 고민해 온 문제의 연장선상에 있는 문제이다. 어떻게든 Cancel 변수를 feature로 활용하고 싶다면, Cancel을 피쳐에 추가하되 집계 시 primary key로 쓰지 않는 방법을 찾아야 한다. 더 고민해 보자.

2. 파라미터를 어떻게 조정해야 효과적일까? 특히, 'tweedie', 'poisson' 등 다양한 objective를 어떻게 적용해야 할지 고민해 보자.

 

 

 

반응형