주제

3차 프로젝트 4일차

 

  • 어제에 이어 랜덤 포레스트 모델을 파인 튜닝
  • 특성 중요도가 낮은 피쳐 제외
  • 피쳐 엔지니어링 : 총상환원금 비율과 총상환이자 비율 추가

 

1. 피쳐 엔지니어링

  • 새로운 피쳐인 총상환원금 비율과 총상환이자 비율을 생성하여 추가함
    • 팀 회의 때 멘토님께서 피쳐 엔지니어링할 때 '비율' 같은 것을 많이 추가한다고 하셨던 걸 인상깊게 들었음
# 총상환원금비율과 총상환이자비율 추가
train['총상환원금비율'] = train['총상환원금'] / train['대출금액']
train['총상환이자비율'] = train['총상환이자'] / train['대출금액']

 

 

2. 모델 훈련

  • 이번에는 총 11개의 피쳐들로 다시 훈련을 시도해보았음
  • 이번에는 정확도와 F1 점수를 같이 보기 위해 성능 평가 메트릭을 추가
from sklearn.metrics import make_scorer, f1_score, accuracy_score

scoring = {
    'accuracy': make_scorer(accuracy_score),
    'f1_score_macro': make_scorer(f1_score, average='macro')
}

scores = cross_validate(rf, X, y, cv=StratifiedKFold())

accuracy_scores = scores['test_accuracy']
f1_scores = scores['test_f1_score_macro']

print("Accuracy Scores:", accuracy_scores)
print("F1 Scores:", f1_scores)

avg_accuracy_score = np.mean(accuracy_scores)
avg_f1_score = np.mean(f1_scores)

print("Average Accuracy Score:", avg_accuracy_score)
print("Average F1 Score:", avg_f1_score)

정확도가 크게 증가한 모습

  • 새로운 피쳐를 2개 추가한 후에 정확도가 크게 증가했다.
  • F1 score도 나쁘지 않은 점수가 나옴
  • 특성 중요도 확인
    • 정확도가 크게 증가한 이유는 역시 새로운 피쳐 2개 덕분이었다.
    • 총상환원금비율과 총상환이자비율의 중요도가 가장 높았다
    • 여기서 중요도가 낮은 근로기간, 대출목적 등은 추후에 제거하여 다시 훈련하기로 결정

특성 중요도 시각화

 

3. 하이퍼파라미터 튜닝

  • 이전에는 기본 모델을 사용했고 이번에는 하이퍼 파라미터 튜닝을 통해 최적의 파라미터 조합을 찾아보았다
  • 이보다 더 섬세한 옵션을 주고 싶었지만 튜닝 특성상 CPU 작업을 오래 하기 때문에 10분이상을 기다려도 결과가 나오지 않아 내 노트북이 버틸 수 있을 정도로만 주었다.
# hyperparameter tuning
# 더 많은 옵션을 추가하고 싶지만 노트북 성능상 불가능했음
params = {
    'n_estimators' : [100, 200],
    'max_depth' : [5, 10],
    'min_samples_split' : [2, 5],
    'min_samples_leaf' : [1, 2],
}
  • 튜닝은 GridSearchCV로 진행
# 훈련
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_validate, StratifiedKFold, GridSearchCV
from sklearn.metrics import make_scorer, f1_score, accuracy_score


rf = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(estimator=rf, param_grid=params, n_jobs=-1)
grid_search.fit(X,y)
scores = cross_validate(rf, X, y, cv=StratifiedKFold(), scoring=scoring)
  • 최적의 파라미터 확인
# 최적의 파라미터 확인
print(grid_search.best_params_)

최적의 파라미터

  • 최적의 파라미터로 튜닝한 모델과 앞선 훈련 세트에서 중요도가 낮은 피쳐 3개를 제외한 새로운 훈련 세트의 조합으로 다시 한번 학습
rf = RandomForestClassifier(
    n_estimators=200, 
    max_depth=10, 
    min_samples_split=5,
    min_samples_leaf=1,
    n_jobs=-1,
    random_state=42
)
scores = cross_validate(rf, X, y, cv=StratifiedKFold(), scoring=scoring)

정확도와 F1 score

  • 정확도는 93.2%, F1 score는 88.1%로 오히려 감소했다.
  • 기본값 모델보다 튜닝된 모델의 정확도가 더 떨어져서 혹시 훈련 세트에 문제가 있는 것은 아닐까 하고 피쳐 11개인 세트와 8개인 세트, 그리고 기본값 모델, 튜닝된 모델로 가능한 조합을 다 시도해봤다.
  • 결과는 다음과 같다 :
모델 종류 기본 모델 튜닝된 모델
피쳐 개수 피쳐 11개 피쳐 8개 피쳐 11개  피쳐 8개
정확도 0.948 0.945 0.935 0.933
F1 score 0.928 0.924 0.888 0.881
  • 튜닝된 모델이 더 정확도가 낮고, 피쳐의 개수가 적을수록 정확도가 떨어졌다
  • 튜닝을 할때 노트북 성능의 한계로 조금 더 많고 촘촘한 옵션을 사용해보지 못한 것이 원인이 아닐까 예상해본다
  • 어느정도 정확도에 도달했을 때는 0.01을 올리는 것도 쉽지 않은 일인 것 같다

 

4. 이상치 제거

  • 우선 가장 중요도가 높은 피쳐들의 이상치 확인을 위해 박스플롯을 그렸다
    • 이때 스케일링 전 데이터를 사용

총상환원금비율와 총상환이자비율에 이상치가 많은 것을 확인

  • 가장 중요도가 높았던 총상환원금비율의 이상치만 제거
  • IQR 방법을 사용
    • 1사분위 * 1.5 보다 작거나 3사분위 * 1.5 보다 크면 이상치로 간주
# 이 중 특성 중요도가 가장 높았던 총상환원금비율의 이상치 제거 시도
# IQR 기법 사용
Q1 = train[['총상환원금비율']].quantile(0.25)
Q3 = train[['총상환원금비율']].quantile(0.75)

IQR = Q3 - Q1

threshold = 1.5

outliers = (train[['총상환원금비율']] < (Q1 - threshold * IQR)) | (train[['총상환원금비율']] > (Q3 + threshold * IQR))

train_no_outliers = train[~outliers.any(axis=1)]

print("이상치 제거 후 :")
print(train_no_outliers)
  • 이상치 제거가 잘 되었는지 다시 확인하기 위해 시각화

총상환원금비율의 이상치가 많이 제거됨

  • 이상치가 제거된 데이터 총 95546개를 가지고 진행

 

5. 시도 정리

  • 다시 스케일링을 해주고 피쳐 여러 개를 소거해가며 기본 모델에 주입
  • 여태까지의 시도를 총정리 해본 결과 :

시도 결과 정리

  • 가장 결과가 좋았던 조합은 총상환원금비율의 이상치를 제거한 피쳐 4개(총상환원금비율, 총상환이자비율, 총상환원금_log, 총상환이자_log)를 기본 모델에 주입한 것이었다
    • 마지막에 시도해본 조합인데 정확도와 f1 점수 모두 올라서 놀랐다.
  • 이상치를 제거한 데이터를 아직 튜닝 모델에 넣어보진 않았지만 가설을 세워보자면 기본 모델보다 성능이 떨어질 것 같다.
  • 튜닝 모델은 한번 돌리는 데에도 시간이 걸리기 때문에 마지막에 시도해보기로 하였다.

+ Recent posts