working_helen
[모델링] 예측 모델 모델링 및 성능 평가 본문
1. 최종 모델링 데이터
2. 모델링 과정
1) XGBoost
2) Random Forest
3) Logistic Regression
4) KNN
3. 최종 모델 선정
1) 평가 지표 결정
4. KNN
1. 최종 모델링 데이터
총 6가지 설명변수 X Dataframe
데이터 전처리 | 파일 | X 변수명 |
변수 선택 X > PCA X | 미삭제_PCA안함.csv | X1 |
변수 선택 X > PCA 1 | 미삭제_PCA1.csv | X2 |
변수 선택 X > PCA 2 | 미삭제_PCA2.csv | X3 |
변수 선택 O > PCA X | 삭제_PCA안함.csv | X4 |
변수 선택 O > PCA 1 | 삭제_PCA1.csv | X5 |
변수 선택 O > PCA 2 | 삭제_PCA2.csv | X6 |
2. 모델링 과정
Step 1. train / validation / test 데이터 분리
train test split > SMOTE 처리 > train validation split
- 처음 원본 데이터에서 train : test = 6:4 split
- train 데이터에서 train : val = 1:1 split
- `sampling_strategy=0.4`에서 SMOTH 결과 폐업 : 영업 = 0.5 : 1 resampled
- 데이터셋 비율
train : test = 0.6 : 0.4
train_re : validation = 0.5 : 0.5
resample에서 폐업 : 영업 = 0.5 : 1 - 데이터셋 종류
X_test, y_test : 원본에서 split한 test set
X_train, y_train : 원본에서 split한 train set
X_train_re, y_train_re : train set에서 split한 train_re set
X_val, y_val : train set에서 split한 validation set
X_resampled, y_resampled : train_re set에 불균형 처리
Step 2. 모델 적합 및 성능 확인
- 총 6가지 X를 XGBoost / Random Forest / Logistic Regression / KNN에 모델링 => 24가지 모델 적합
- 각 모델에서 최적의 모델 선정 => 4가지 모델에서 최적의 모델 선정
1) XGBoost
- XGBClassifier 공통 객체를 이용해 Grid Search 진행
- Grid Search 결과로 얻은 최적 모델을 이용
- 모델 성능 평가 + ROC-AUC curve 그리기 + feature importance 확인
- feature importance : xgboost의 plot_importance 클래스 이용
파라미터명 | 의미 | 기능 |
n_estimators | 생성할 weak learner 수 | |
objective | 학습 모델 종류 (reg, binary, multi 등) | |
eval_metric | 비용 평가 지표 (rmse, mae, logloss, auc 등) |
|
max_depth | 트리의 최대 깊이 | 높을수록 모델의 복잡도가 커져 과적합이 일어나기 쉽다. |
min_child_weight | child 관측치에 대한 가중치의 최소합 | 이 값보다 작으면 leaf node가 된다. 값이 높을수록 과적합이 방지된다. |
colsample_bytree | 각 트리마다 사용된 feature의 비율 | 값이 낮을수록 과적합이 방지된다. |
early_stopping_rounds | 비용 평가 지표가 감소하지 않는 최대 반복횟수 |
eval_set으로 계산한 loss가 해당 횟수 이상동안 개선이 없으면, 지정해준 n_estimate 수만큼 반복하지 않더라도 학습을 멈춘다. 과적합을 방지한다. |
eval_set | 평가를 수행하는 검증 데이터 set |
변수명 (n=1~6) | 의미 |
xgb_clf | XGBClassifier 공통 객체 xgb_clf 생성 |
xgb_gridcv | xgb_clf를 이용한 Grid Search 객체 |
xgb_model_n | Grid Search 결과로 얻은 Xn_resampled에서 최적 파라미터 모델 |
xgb_n_yn_pred | xgb_model_n의 Xn_test 예측값 |
pred_positive_label_n | xgb_model_n의 Xn_test Positive 확률값 |
# 기본 객체 생성
xgb_clf = XGBClassifier(n_estimators=100, objective='binary:logistic', eval_metric='auc')
# Grid Search : 파라미터 튜닝
params = {'max_depth':[5,7],
'min_child_weight':[1,3,5],
'colsample_bytree':[0.5, 0.75]}
xgb_gridcv = GridSearchCV(xgb_clf, param_grid=params, cv=3)
xgb_gridcv.fit(X1_resampled, y1_resampled, early_stopping_rounds=30,
eval_set=[(X1_resampled, y1_resampled), (X1_test, y1_test)])
# 모델 적합 : 최적의 파라미터로 XGBClassifier 적합
xgb_model_1 = xgb_gridcv.best_estimator_
# 성능 평가
xgb_1_y1_pred = xgb_model_1.predict(X1_test)
evaluate(y1_test, xgb_1_y1_pred)
# ROC-AUC curve
pred_positive_label_1 = xgb_model_1.predict_proba(X1_test)[:,1]
AUC = roc_auc_score(y_true=y1_test, y_score=pred_positive_label_1)
2) Random Forest
- RandomForestClassifier 공통 객체를 이용해 Grid Search 진행
- Grid Search 결과로 얻은 최적 모델을 이용
- 모델 성능 평가 + ROC-AUC curve 그리기 + feature importance 확인
- feature importance : RandomForestClassifier의 method .feature_importances_ 이용
파라미터명 | 의미 | 기능 |
random_state | 난수 seed 설정 | random하게 난수를 생성하는데, 이때 seed를 고정해두면 반복 실행에서 동일한 결과를 출력한다. |
min_samples_split | 내부 노드를 분할하는데 필요한 최소 샘플 수 |
값이 작을수록 분할 노드가 많아져 과적합 가능성이 증가한다. |
min_samples_leaf | 리프 노드에 있어야 할 최소 샘플 수 | 값이 작을수록 리프 노드가 많아져 과적합 가능성 이 증가한다. |
변수명 (n=1~6) | 의미 |
rf | RandomForestClassifier 공통 객체 rf 생성 |
rf_gridcv | rf를 이용한 Grid Search 객체 |
rf_model_n | Grid Search 결과로 얻은 Xn_resampled에서 최적 파라미터 모델 |
rf_n_yn_pred | rf_model_n의 Xn_test 예측값 |
pred_positive_label_n | rf_model_n의 Xn_test Positive 확률값 |
# 기본 객체 생성
rf = RandomForestClassifier(n_estimators=100, random_state=42)
# Grid Search : 파라미터 튜닝
params = {'max_depth':[1,2,3,4,5],
'min_samples_split':[2, 5],
'min_samples_leaf':[1,3]}
rf_gridcv = GridSearchCV(rf, param_grid=params, cv=3 , scoring='f1')
rf_gridcv.fit(X1_resampled, y1_resampled)
# 모델 적합 : 최적의 파라미터로 RandomForestClassifier 적합
rf_model_1 = rf_gridcv.best_estimator_
# 이하 xgboost와 동일
3) Logistic Regression
- LogisticRegression 공통 객체를 이용해 Grid Search 진행
- Grid Search 결과로 얻은 최적 모델을 이용
- 모델 성능 평가 + ROC-AUC curve 그리기 + feature importance 확인
- feature importance : 회귀계수로 확인
파라미터명 | 의미 | 기능 |
C | regularization의 강도를 결정하는 parameter | C값이 낮을수록 regularization이 강화 |
solver | 최적화 문제에 사용할 알고리즘 L1 L2 penalty 조건을 지원 |
loss function의 최솟값을 어떻게 찾을 것인지를 방법 설정 |
max_iter | Gradient Descent 수행 횟수 | 가중치 업데이트를 위해 Gradient Descent을 몇 번 반복할지 |
변수명 (n=1~6) | 의미 |
logreg | LogisticRegression 공통 객체 logreg 생성 |
lg_gridcv | logreg를 이용한 Grid Search 객체 |
lg_model_n | Grid Search 결과로 얻은 Xn_resampled에서 최적 파라미터 모델 |
lg_n_yn_pred | lg_model_n의 Xn_test 예측값 |
pred_positive_label_n | lg_model_n의 Xn_test Positive 확률값 |
# 기본 객체 생성
logreg = LogisticRegression()
# Grid Search : 파라미터 튜닝
params = {'C':[0.01,0.1,1],
'solver':['liblinear','lbfgs'],
'max_iter':[100, 300]}
lg_gridcv = GridSearchCV(logreg, param_grid=params, cv=3 , scoring='f1')
lg_gridcv.fit(X1_resampled, y1_resampled)
# 모델 적합 : 최적의 파라미터로 LogisticRegression 적합
lg_model_1 = lg_gridcv.best_estimator_
# 이하 xgboost와 동일
4) KNN
- KNeighborsClassifier 공통 객체를 이용
- Grid Search 진행하지 않고 바로 모델링
- 모델 성능 평가 + ROC-AUC curve 그리기
- feature importance : 확인 어려움
파라미터명 | 의미 | 기능 |
n_neighbors | 가장 가까운 이웃 data의 개수 | 값이 작아지면 model의 결정경계가 복잡해져 overfitting 가능성 증가, 값이 커지면 model의 결정경계가 단순해져 underfitting 가능성이 증가한다. |
변수명 (n=1~6) | 의미 |
knn_model | KNeighborsClassifier 공통 객체 knn_model 생성 |
knn_model_n | knn_model을 Xn_resampled에 바로 적합한 모델 |
knn_n_yn_pred | knn_model_n의 Xn_test 예측값 |
pred_positive_label_n | knn_model_n의 Xn_test Positive 확률값 |
# 기본 객체 생성
knn_model = KNeighborsClassifier(n_neighbors=3)
# 모델 적합
knn_model_1 = knn_model.fit(X1_resampled, y1_resampled)
# 이하 xgboost와 동일
🚨 ERROR Check
"AttributeError: 'Flags' object has no attribute 'c_contiguous'"
KNN 모델에서는 input을 dataframe이 아닌 numpy 배열로 받기 때문에 df를 array로 변환해서 fit 해줘야한다.
→ df.to_numpy() method 이용해서 ndarray로 변환
(참고 : https://github.com/scikit-learn/scikit-learn/pull/26772)
5) 모델 성능 평가
- 평가 지표 : accuracy / f1 score / precision / recall / ROC curve와 AUC
- 성능 평가 함수 evaluate 정의
## 성능 평가 함수 정의
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report
def evaluate(y_test, y_pred):
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
print('정확도: {:.4f}'.format(accuracy))
print('정밀도: {:.4f}'.format(precision))
print('재현율: {:.4f}'.format(recall))
print('f1 score: {:.4f}'.format(f1))
## ROC-ACU
from sklearn.metrics import roc_auc_score, roc_curve
#Positive 확률값 계산 > auc값 계산
pred_positive_label_n = xgb_model_n.predict_proba(X6_test)[:,1]
AUC = roc_auc_score(y_true=yn_test, y_score=pred_positive_label_n)
#FPR, TPR, Threshold array 리턴 > 그래프 그리기
fpr, tpr, cut = roc_curve(y_true=yn_test, y_score=pred_positive_label_n)
plt.plot(fpr, tpr)
plt.title('ROC-AUC CURVE', fontsize=15, y=1)
plt.text(0.4, 0.4, f'AUC = {AUC:.4}', fontsize=12, fontweight="bold")
Step 3. 최종 모델 선정
평가 지표 : accuracy / f1 score / precision / recall / ROC curve와 AUC
평가 지표 | 정의 | 성능 평가 |
accuracy | 예측 결과 정답인 비율 | accuracy값이 높을수록 모델 성능이 좋다. |
precision | 모델이 True라고 분류한 것 중에서 실제로 True인 것의 비율 |
precision이 낮아 모델이 정확하지 않을수록 negative이지만 positive로 예측한 노이즈가 많아진다. |
recall | 실제 True인 것 중에서 모델이 True라고 예측한 것의 비율 | recall이 낮으면 데이터에서 positive case들을 잘 찾지 못해 TP가 감소하고 FN이 증가한다. |
f1 score | precision과 recall의 조화평균 |
precision과 recall이 모두 높을수록 높아지며, 1에 가까울수록 성능이 좋다. (0~1의 값) |
ROC curve | Threshold 변화에 따른 FP와 TP 비율 시각화 (Threshold 결정시 근거) |
ROC 커브가 좌상단에 가까울수록 모델 성능이 좋다. |
AUC | ROC 커브 아래의 면적을 계산한 값 | AUC값이 높을수록 모델 성능이 좋다. |
1) 평가 지표 결정
accuracy
- 모델 성능을 평가하는 가장 직관적이고 일반적인 지표로 사용되었다.
- 불균형 데이터의 경우 accuracy는 적절한 평가 지표가 되지 못한다.
➡️ 본 프로젝트 데이터의 경우 전체 데이터에서 '폐업' 데이터가 0.8%로 매우 불균형한 상태이다. 따라서 '폐업'과 '영업'을 분류하는 문제에 대해 모두 '영업'이라고 판단하는 모델을 만들었다고 하더라도 정확도는 99.2%로 매우 높게 나온다. 따라서 현재 데이터셋에는 accuracy가 적합한 평가 지표라고 할 수 없다.
f1 score
- f1 score은 불균형 데이터에도 적용할 수 있어 accuracy를 대체하여 사용할 수 있다.
- f1 score은 precision과 recall을 함께 고려할 수 있도록 만든 평가지표이며, precision과 recall의 중요성을 동등하게 가정하기 때문에 precision과 recall 중 어느 한쪽으로 치우치지 않을때 높은 값을 보인다.
- 어떤 문제를 해결하느냐에 따라 precision과 recall 중 더 중요하게 확인해야하는 지표가 달라진다. 따라서 두 지표 간 중요성이 다른 경우에는 f1 score는 적합하지 않을 수 있다.
➡️ 본 프로젝트의 경우 '폐업' 상점을 예측하여 소상공인들의 피해를 줄이는 것이 최초 목표였다. 따라서 '폐업' 가능성이 있는 경우를 최대한 발견하여 True Negative를 늘리고 False Positive를 줄이는 것이 중요하다고 판단했다. 즉 TN을 많게, FP를 적게 만드는 모델이 적합하다고 판단했다.
precision이 낮아 모델이 정확하지 않을수록 negative이지만 positive로 예측하는 FN이 많아진다. 따라서 f1 score을 사용하되 precision과 recall 중에서 precision을 높이는 것을 더 중요한 기준으로 삼았다.
ROC-curve와 AUC
- 이진 분류 문제에서 f1 score를 사용하기 어려운 경우, 그 대안으로 ROC-curve와 AUC를 사용할 수 있다.
- f1 score와 마찬가지로 불균형 데이터도 적용할 수 있다.
➡️ 본 프로젝트의 경우 앞서 f1-socre을 참고하되 precision을 recall보다 더 우선시하기로 결정했다. 이때 f1-score을 보완 및 대체하기 위한 지표로 ROC-curve와 AUC값도 사용하기로 결정했다.
=> accuracy은 판단 기준에서 제외
f1-score가 높은 것을 보되, recall보단 precision이 높은 것을 더 우선시
ROC-curve와 AUC값 보조적으로 사용
2) XGBoost 최적 모델 선정
- 5번과 6번 모델의 경우 f1-score와 AUC값이 가장 높지만, precision 값이 낮음
- 4번 모델의 경우 f1-score와 AUC값은 중간 정도, precision이 0.0556으로 가장 높음
=> X4(변수 삭제 > PCA X) 모델 선택
3) Random Forest 최적 모델 선정
- 3번 모델의 precision이 가장 높긴 하지만 다른 모델과 큰 차이가 없음
- 5번 모델의 경우 f1 score와 AUC가 모두 높은 편에 해당
=> X5(변수 삭제 > PCA1) 모델 선택
4) Logistic Regression 최적 모델 선정
- 5번 모델이 f1 score, precision, AUC 모두에서 가장 높음
=> X5(변수 삭제 > PCA1) 모델 선택
5) KNN 최적 모델 선정
- recall과 AUC는 모든 모델에서 다 유사
- 1번, 3번 모델에서 precision과 f1 score가 높게 나옴
- 3번보다 1번 모델에서 AUC가 높음
=> X1(변수 미삭제 > PCA 안함) 선택
6) 최종 최적 모델 선정
- AUC가 압도적으로 낮은 knn 모델 제외
- f1 score와 AUC값만을 본다면 logistic regression 모델이 최적
- 하지만 precision 값을 중심으로 본다면 xgboost 모델이 최적
=> 최종 모델은 xgboost 모델로 선정
Step 4. 모델의 최종 성능 평가
✅ 최종 모델 : X4(변수 선택 > PCA X) 데이터셋 + XGBoost 적용
📌 test error
- f1-score = 0.044, precision = 0.09, recall = 0.029
- AUC = 0.7403
Reference
https://www.thedatahunt.com/trend-insight/f1-score#f1-score-wonriwa-gyesanbeop
https://libertegrace.tistory.com/entry/Evaluation1
[xgboost 파라미터]
https://wooono.tistory.com/97
https://libertegrace.tistory.com/entry/Classification-4-%EC%95%99%EC%83%81%EB%B8%94-%ED%95%99%EC%8A%B5Ensemble-Learning-Boosting3-XGBoost
[rf 파라미터]
https://inuplace.tistory.com/570
https://sevillabk.github.io/RandomForest/
[logress 파라미터]
https://woolulu.tistory.com/22
https://m.blog.naver.com/gdpresent/221703566189
[knn 파라미터]
https://woolulu.tistory.com/1
'TAVE > 뿌스팅 project' 카테고리의 다른 글
[데이터 수집] 주소 -> 위도/경도 전환 (0) | 2023.08.23 |
---|---|
[애플리케이션] streamlit 웹 구현 (0) | 2023.08.07 |
[데이터 전처리] 설명변수 PCA (0) | 2023.08.07 |
[데이터 전처리] Encoding 인코딩 (0) | 2023.08.07 |
[데이터 전처리] EDA 및 변수 선택 (0) | 2023.08.07 |