홀드 아웃 : 전체 데이터셋을 학습용, 검증용, 최종 평가용으로 분할하려 모델 성능 평가 기법 X : y(종속변수)를 제외한 나머지 변수 -> 입력 변수(features)들로 이루어진 행렬 y : 종속(타겟) 변수 -> 예측하려는 출력 값(label)들의 벡터
훈련용 X, 최종 테스트용 X + 중간 평가용(검증 세트) 데이터 분할(기본 데이터셋의 수가 많은 경우 활용 가능) -> 과적합 방지 : 훈련 세트에 너무 과도하게 맞춘 모델은 새로운 데이터 예측 성능 떨어짐(일반화 성능 확보 필요)
학습용 데이터(Training Sets) : 알고리즘이 데이터 패턴 학습 위한 데이터(전체 데이터의 60%~80% 권장) 검증용 데이터(Valid Sets) : 학습 도중 과적합 여부 모니터링 및 하이퍼파라미터 탐색 및 조정(전체 데이터의 10%~20% 권장) 시험용 데이터(Test Sets) : 모델 개발 후 객관적 성능 평가 및 평가 지표 산출 (전체 데이터의 10%~20% 권장) + 데이터셋의 데이터가 매우 적은 경우 : 검증용 데이터까지 분할하지 않고 학습용 / 시험용 데이터로만 분할하여 모델 적용
X, y 데이터 분할
# 필요한 라이브러리 불러오기
from sklearn.model_selection import train_test_split
# X, y로 데이터 분할
X = final_data.drop('is_fraud', axis=1)
y = final_data['is_fraud']
# X, y 확인
display(X.head(2))
y.head()
홀드 아웃
# 검증 세트 포함하여 데이터 분리
# 전체 데이터 구성 비율 = train(60%) : valid(20%) : test(20%)
# stratify는 분할된 모든 세트에서 클래스 분포가 원본과 동일하게 유지하기 위함(위 데이터는 1:0 = 50%:50% 이므로 적용하지 않아도 됨)
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.4, random_state=42)
X_valid, X_test, y_valid, y_test = train_test_split(X_valid, y_valid, test_size=0.5, random_state=42)
# 분할된 데이터에 적절한 수의 데이터가 들어갔는지 확인 (6:2:2 = 3:1:1비율로 분할되었는지 확인)
print(len(X_train), len(X_valid), len(X_test))
print(len(y_train), len(y_valid), len(y_test))
✔️ 머신러닝 모델 적용과 결과 해석
하이퍼파라미터 및 성능 확인
모델 선택(하이퍼파라미터) 여러 알고리즘을 비교하여, 검증 세트 또는 교차 검증 기반으로 성능이 가장 좋은 모델 선택
데이터 분석 모델 성능평가 Accuracy(정확도/정분류율) : 1을 1이라고 맞추고 0을 0이라고 맞춘 비율 False Positive Rate(오분류율) : 1을 0이라고 예측하고 0을 1이라고 예측해서 잘못 예측한 것 precision(정밀도) : 예측한 것 중에서 실제로 맞은 것, 예측 positive 중에서 실제 positive인 비율 Recall(재현율/민감도) : 실제값을 실제값으로 잘 예측한 것, 실제 Positive 중 예측 Positive가 맞은 것 F1-Score : precision과 recall의 조화 평균 Specificity(특이도) : 실제 nagative 중 예측에 성공한 비율
혼동 행렬 정확도 (Accuracy) 전체 중 맞춘 비율 = (𝑇𝑃+𝑇𝑁) / (𝑇𝑃+𝑇𝑁+𝐹𝑃+𝐹𝑁)
오분류율 (FPR, False Positive Rate) 실제 Negative 중 Positive로 잘못 예측한 비율 = 𝐹𝑃 / (𝐹𝑃+𝑇𝑁)
정밀도 (Precision) Positive라고 예측한 것 중 실제 Positive인 비율 = 𝑇𝑃 / (𝑇𝑃+𝐹𝑃)
재현율 / 민감도 (Recall / Sensitivity) 실제 Positive 중 올바르게 예측한 비율 = 𝑇𝑃 / (𝑇𝑃+𝐹𝑁)
특이도 (Specificity) 실제 Negative 중 올바르게 예측한 비율 = 𝑇𝑁 / (𝑇𝑁+𝐹𝑃)
F1 Score 정밀도와 재현율의 조화 평균 = 2*(Precision*Recall) / (Precision+Recall)
하이퍼파라미터 튜닝 모델 중 가장 성능이 좋은 모델 중 더 최적화된 성능을 내기 위해 수행 학습률, 트리 깊이, 정규화 계수 등 모델 설정을 검증 세트 성능 기준으로 최적화하는 과정 검증 세트 성능 기준으로 튜닝할 경우, 최종 테스트 세트로는 한 번만 평가해야 함
DecisionTreeClassifier 모델 적용 및 결과 확인
DecisionTreeClassifier 의사결정 트리 알고리즘 적용한 분류 모델 루트 노드 > 자식 노드에 동일 과정의 재귀 적용 -> 리프 노드에서 다수 클래스 예측
효과 비선형 관계와 피처 상호작용을 직관적 규칙으로 모델링 가능 트리 시각화 -> 모델 해석 용이성 예) 신용 평가, 의료 진단, 고객 이탈 예측 등
한계 트리 깊이가 깊어질수록 과적합 발생 단일 트리로는 편향 감소 한계
DecisionTreeClassifier 성능 평가 정확도(83.6%) : 무작정 높지만은 않은, 중간 정도의 분류 성능 F1-Score(84%) : 사기탐지 모델로 적합하나 15%~20% 정도의 미검출/오탐 가능성 존재
# 모델이 결과를 도출하기까지 걸리는 시간 확인 -> 모델 결정의 중요 요소
start = time.time()
# 모델 불러와서 예측 수행
dtc = DecisionTreeClassifier(random_state=42)
dtc.fit(X_train, y_train)
pred = dtc.predict(X_valid)
end = time.time()
# 예측된 결과 바탕으로 모델 성능 평가
print(f"소요 시간: {end - start:.2f} \n")
print('DecisionTreeClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
DecisionTreeClassifier 모델의 성능 향상: 불균형 데이터 대응
# DecisionTree 모델의 경우 : class_weight='balanced' 적용
# 다양한 방법이 존재하지만 다른 방법은 다음 시간에 확인
start = time.time()
dtc = DecisionTreeClassifier(random_state=42, class_weight='balanced')
dtc.fit(X_train, y_train)
pred = dtc.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('DecisionTreeClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
BaggingClassifier 모델 적용 및 결과 확인
배깅(Bagging) 원본 학습 데이터셋에서 복원추출 방법(중복 허용 랜덤 샘플링)으로 여러 데이터셋(부트스트랩)으로 생성 예) 원본 학습 데이터에 10개의 데이터 존재 > 그 중 랜덤하게 중복 가능한 5개 데이터 추출 > 5개의 데이터셋 생성생성된 각 데이터셋에 독립적 모델을 학습 시키고 평균(회귀) 또는 다수결(분류)로 합침
효과 오버피팅 완화 랜덤포레스트 모델 등 활용
한계 편향(Bias) 자체를 줄일 수 없음
BaggingClassifier 성능 평가
# 필요한 라이브러리 불러오기
from sklearn.ensemble import BaggingClassifier
# n_estimators : 기본 모델(base estimator)의 개수
# n_jobs : 병렬로 사용할 CPU 코어 수를 설정
start = time.time()
bc = BaggingClassifier(n_estimators=10, n_jobs=-1, random_state=42)
bc.fit(X_train, y_train)
pred = bc.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('BaggingClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
AdaBoostClassifier 모델 적용 및 결과 확인
부스팅(Boosting) 여러 약한 학습기를 순차적으로 학습 이전 모델이 틀린 샘플에 가중치를 높여 다음 모델이 어려운 샘플을 집중적으로 학습시킴
효과 편향(Bias) 감소에 효과적(점진적 오류 보정을 통한 강력한 모델 생성) XGBoost, LightGBM 등 활용
AdaBoostClassifier 성능 평가
# 필요한 라이브러리 불러오기
from sklearn.ensemble import AdaBoostClassifier
# n_estimators : 기본 모델(base estimator)의 개수
start = time.time()
abc = AdaBoostClassifier(n_estimators=10, random_state=42)
abc.fit(X_train, y_train)
pred = abc.predict(X_valid)
end = time.time()
print('AdaBoostClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
RandomForestClassifier 모델 적용 및 결과 확인
랜덤 배깅(RandomForest) 배깅 기반으로 다수의 결정 트리를 독립적으로 학습시키고 각 트리의 예측을 평균(회귀) 또는 다수결(분류) 로 합침
랜덤 포레스트 과정 1. 원본 데이터에서 복원추출 방법으로 통해 랜덤 샘플을 n_estimators 개만큼 생성 2. 트리별 학습 : 각 샘플마다 max_feature를 랜덤 선택 > 선택된 특성만으로 완전 성장/지정 깊이만큼 트리 생성 3. 예측 결합 : 분류(각 트리 예측 결과 중 다수결로 최종 레이블 선택) / 회귀(트리 예측 값의 평균)
효과 분산 감소 : 오버피팅 완화 특성 중요도(feature importance) 제공 : 모델 성능에 어떤 컬럼이 기여했는지 확인 가능 병렬 처리 가능 : 독립적 학습으로 분산 환경에서 학습 속도 향상
RandomForestClassifier 성능 평가
# 필요한 라이브러리 불러오기
from sklearn.ensemble import RandomForestClassifier
# 랜덤 포레스트 모델 적용
start = time.time()
rfc = RandomForestClassifier(n_estimators=10, n_jobs=-1, class_weight='balanced',random_state=42)
rfc.fit(X_train, y_train)
pred = rfc.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('RandomForestClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
XGBClassifier 모델 적용 및 결과 확인
XGBoost -> pip install xgboost 병렬연산이 가능해 처리 속도가 매우 빨라짐
# 필요한 라이브러리 불러오기
from xgboost import XGBClassifier
# XGBoost 모델 적용
start = time.time()
xgb = XGBClassifier(n_estimators=100, n_jobs=-1, random_state=10)
xgb.fit(X_train, y_train)
pred = xgb.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('XGBClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
XGBClassifier 모델의 성능 변화: 불균형 데이터 처리의 역효과
# scale_pos_weight=3 적용 -> 성능이 더 안 좋아짐
# 불균형 데이터를 보정한다고 해서 무조건 성능이 좋아지지는 않음
start = time.time()
xgb = XGBClassifier(n_estimators=100, n_jobs=-1, scale_pos_weight=3, random_state=10)
xgb.fit(X_train, y_train)
pred = xgb.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('XGBClassifier 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
LGBMClassifier 적용 및 결과 확인
LightGBM xgboost보다 속도를 더 빠름 비대칭 트리를 만듦
# 필요한 라이브러리 불러오기
from lightgbm import LGBMClassifier
# LightGBM 모델 적용
start = time.time()
lgbm = LGBMClassifier(n_estimators=1000, n_jobs=10,random_state=10)
lgbm.fit(X_train, y_train)
pred = lgbm.predict(X_valid)
end = time.time()
print(f"소요 시간: {end - start:.2f} \n")
print('LightGBM 모델 적용 결과')
print(confusion_matrix(y_valid, pred), end='\n\n')
print(f"정확도 = {accuracy_score(y_valid, pred)}")
print(classification_report(y_valid, pred))
모델 정확도 및 인사이트 정리
단일 DecisionTrees의 정확도(약 83%)가 가장 낮다. 앙상블(RandomForest, AdaBoost, XGB, LGBM)은 전반적으로 87~88%대로 확실히 개선될 것을 확인할 수 있다. Bagging은 성능을 괜찮지만 시간이 과도하게 오래 걸려서 비효율적이다. XGB에서 scale_pos_weight=3은 오히려 성능을 저하시킴을 확인하여, 불균형 처리 방법이 항상 긍정적이지 않음을 보여준다. 실행 기준으로는 XGBClassifier가 소요시간이 7초대에 정확도는 88.67%를 기록하며 가장 효율적이다.
인사이트
앙상블 계열(RandomForest, AdaBoost, XGB, LGBM)이 단일 트리 대비 안정적으로 높은 성능을 보였으며, 특히 XGBClassifier가 정확도와 효율성의 균형에서 가장 적합해 보인다. 다만 불균형 데이터 보정은 무조건 성능 향상을 불러오지 않으니 신중히 적용해야 한다.
이번 내용에서는Kaggle 이상거래 데이터 활용 분석 중 홀드 아웃과 머신러닝 모델 적용 및 결과 해석에 대해 알아보았습니다.
데이터 분석을 하기 위해서는 가장 꾸준히 공부해야 하는 언어는 파이썬(Python)이라고 생각합니다.
앞으로 꾸준히파이썬(Python)내용을 공부하고 정리할테니 파이썬 코딩에 도움이 되었으면 좋겠습니다.