My blog
[ML_week4_chap4] 분류 본문
01 분류의 개요
1) 개념
- 지도학습의 대표적인 유형으로, 명시적인 정답(Label)이 있는 데이터를 학습하여 미지의 데이터에 대한 레이블을 예측
- 데이터의 피처(Feature)와 레이블(Label) 사이의 패턴을 인지하고 모델을 생성
2) 주요 알고리즘
- 나이브 베이즈: 베이즈 통계 기반
- 로지스틱 회귀: 독립변수와 종속변수의 선형 관계 기반
- 결정 트리: 데이터 균일도에 따른 규칙 기반
- SVM: 클래스 간 최대 마진 탐색
- 최소 근접(KNN): 근접 거리 기준
- 신경망: 심층 연결 기반
- 앙상블 : 여러 알고리즘의 결합 (정형 데이터 예측 성능 최강)
02 결정 트리
1) 개념 및 작동 원리
데이터에 있는 규칙을 학습을 통해 자동으로 찾아내 Tree 기반의 분류 규칙을 만드는 알고리즘 (if/else 방식의 스무고개 느낌)
- 핵심 지표: 정보의 균일도 : 트리를 분할할 때 최대한 균일한 데이터 세트가 되도록
- - 정보 이득: 1 - 엔트로피(혼잡도)
- - 지니 계수: 지니 계수가 낮을수록 데이터 균일도가 높음
-> 정보이득 높거나 지니 계수 낮은 조건으로 반복적으로 분할
2) 결정 트리의 특징
- 장점: 직관적 , 데이터의 스케일링이나 정규화 등 사전 가공 영향거의 없음
- 단점 : 정확도 높이려면 조건 추가 , 트리가 깊어져 과적합에 취약함 (depth 늘리면 어느정도 좋아지다가 정확도 안좋아짐)
사이킷런의 DecisionTreeClassifier는 지니 계수를 기본으로 사용하며, 트리의 크기를 제한하는 튜닝이 필수적
ex ) max_depth 조절 ,
ex) min_samples.leaf 을 높게 잡아서 이 정도면 분할 , 리프노드 될 수있게해 더 이상 분할X
ex) 피처 중요도 (ndarray 형태 )로 파악 가능
03 앙상블
1) 개념
- 다양한 분류기의 예측을 결합함으로써 단일 분류기보다 더 신뢰성 높은 예측값 얻는 것 : 집단 지성 느낌ㄴ

2) 유형
- 보팅 : 서로 다른 알고리즘을 가진 분류기들이 같은 데이터 세트를 학습
예: (로지스틱 회귀 + KNN + SVM)이 투표
- 원본 데이터 그대로 사용
+ ) [하드] : 분류기 다수결 , [소프트] : 모든 레이블 결정확률 / 평균 - 배깅 : 같은 알고리즘을 가진 분류기들이 서로 다른 샘플 데이터 학습
- 부트스트래핑: 전체 데이터에서 중복을 허용하여 샘플링하는 방식.
예 ) 랜덤 포레스트 - 부스팅 : 여러개의 분류기가 순차적으로 학습하고 앞서 틀린 데이터에 가중치 부여해 다음 분류기가 더 잘 맞추게함예측 성능 좋음 , 순차적 학습 특성상 속도 느림 (결정 트리 알고리즘 기반 )
예 ) AdaBoost, Gradient Boost, XGBoost, LightGBM
보팅,스태킹 - 서로 다른 알고리즘 기반
배깅 ,부스팅 - 대부분 결정 트리 알고리즘 기반

04 랜덤포레스트
1) 개념
- 배깅 : 같은 알고리즘으로 여러개 분류기 만들어서 보팅으로 최종 결정 ex) 랜덤포레스트
- 핵심메커니즘 : 부트스트래핑 (전체 학습 데이터 세트에서 중복허용해 무작위로 N개 샘플 추출 )
2) 하이퍼 파라미터 및 튜닝
n_estimators : 결정 트리 개수 : 늘릴수록 성능 좋아지지만 속도 느림
max_features : 최적의 분할을 위해 고려할 피처 개수
n_jobs : 멀티 코어에서 -1로 설정하면 모든 cpu 사용해서 병렬 학습 수행
05 GBM (gradient boosting machine )
- 여러 개의 약한 학습기를 순차적으로 학습 ->이전 학습기가 잘못 예측한 데이터에 가중치를 부여해 오차를 개선해 나가는 방식
- 경사하강법 (오류값을 최소화하는 방식으로 가중치 업데이트)
- 장점 : 랜덤 포레스트 보다 과적합에 강하지만 , 랜덤포레스트 보다 보통 예측성능 나음
- 단점 : 오래걸림 , 병렬처리 지원안돼
06 XGBoost
1) 정의
- 트리 기반 앙상블 학습에서 인기많음
- GBM기반 , 기존 GBM 단점(느린 속도 , 과적합) 문제 개선한 알고리즘
- 예측성능 , 병렬학습 , 과적합 규제 , 조기 중단에 이점이 있음
- 성능 , 속도 모두 잡음
2) 파이썬 래퍼 VS 사이킷런 래퍼
- 파이썬 네이티브 래퍼 : DF 바로 넣을 수 없고 DMatirx 라는 전용 객체 변환 / 예측시 0.5보다 큰지 직접 비교해 클래스 결
- 사이킷런 래퍼 : fit(),predict() 방식 그대로 씀 *predic()가 결과값이 아닌 확률 값 반환
3) 주요 파라미터
- eta (learning_rate): 학습률.
- max_depth: 트리의 최대 깊이.
- min_child_weight: 추가 분할을 결정하기 위한 최소 가중치 합. 높을수록 보수적(과적합 방지).
- gamma: 분할을 하기 위한 최소 손실 감소 값. 클수록 과적합 감소 효과
- sub_sample / colsample_bytree: 데이터 및 피처를 샘플링하는 비율
07 LightGBM
위의 xgBoost와 결정적인 차이는 트리 분할방식
- XGBoost : 균형 트리 분할 (깊이 최소화 , 과적합에 강함) but 시간 그래도 오래걸림
- LightGBM : 리프 중심 트리 분할 (손실값 loss가 가장 큰 리프 노드를 계속 분할) -> 비대칭적이지만 학습 반복할 수록 예측 오류를 빨리 줄일 수 있고 속도가 빠름 + 메모리 사용량 작고 , 카테고리 형 피처의 자동변환과 최적 분할 수행
- 조기 중단 가능
- leaning_rate를 작게 , n_esitimator를 크게 하는게 기본이지만 너무 크면 과적합문제

얘네 둘이 하이퍼파라미터 수가 많은편이라 grid search방식으로 하면 시간오래걸림
08 베이지안 최적화 기반 HyperOpt
1) 개념
- 목적 함수의 식을 몰라도, 최소/최대 값을 만드는 최적의 입력값을 적은 시도로 빠르게 찾아내는 기법.
- Grid Search의 노가다 탈출: 파라미터 조합이 수만 개일 때, 다 해보는 게 아니라 어디쯤 정답이 있을 것 같다 추측함
2) 핵심 구성 요소
- 대체 모델 : 지금까지 시도해본 결과들을 바탕으로실제 함수 추정하는 가상의 모델 (HyperOpt는 TPE 알고리즘 )
- 획득 함수 : 대체 모델이 그린 지도를 보고 다음 최적의 파라미터 후보를 추천해주는 역할.
3) HyperOpt 실무 적용 과정
- 검색 공간 설정 (hp 모듈사용함): - 파라미터별로 탐색할 범위를 지정 (예: hp.quniform은 간격 있는 숫자)
- 목적 함수 생성: - 파라미터를 입력받아 모델을 학습시키고 성능 지표(Loss)를 반환하는 함수.
주의1: HyperOpt는 무조건 최솟값을 찾으려 함. 따라서 정확도나 AUC처럼 클수록 좋은 값은 -1을 곱해서 넘겨줘야 함.
주의2: HyperOpt는 값을 실수로만 줌. max_depth 같은 정수형 파라미터는 함수 안에서 int()로 형변환 필수. - 최적화 수행 (fmin 함수):
설정한 횟수(max_evals)만큼 반복하며 최적의 조합을 도출.
우리가 하는거 (1.목적함수 정의 , 2.검색 공간 정의 , fmin호출)
fmin 호출시 -> (대체모델(가상지도) , 획득함수(파라미터 추측),->목적함수 실행 -> 대체모델에 다시 값 넘겨주면서 수정 )
4) 장단점 및 특징
장점: Grid Search보다 훨씬 빠르고 효율적임. 파라미터가 많은 XGBoost나 LightGBM 튜닝에 좋
단점: 데이터가 너무 적으면 별로
분류실습
지도학습에서 불균형한 레이블 데이터 세트를 학습시키면 머신러닝 모델은 제대로 된 예측을 하기 어려움
- > 적은 데이터를 늘리거나 많은 데이터를 줄이는 방식사용
- 언더 샘플링 - 많은 데이터 세트를 적은 데이터 세트 수준으로 감소
너무 많은 정상 데이터를 줄여버리면 오히려 모델이 정상 데이터의 특징을 제대로 학습하지 못하는 부작용으로 잘 사용X - 오버 샘플링: 적은 데이터 세트를 증식하여 충분한 데이터를 확보
단순 복제는 과적합을 유발 -> 원본 데이터의 피처 값들을 아주 약간만 변형하여 증식하는 방식을 주로 씀
ex) SMOTE
IQR (사분위간 범위) 편차를 이용해 이상치를 찾아내는 과정
이상치 데이터 제거
iqr = q3-a1
- 하한선 : Q1 - (1.5 * IQR)
- 상한선 : Q3 + (1.5 * IQR)
SMOTE
적은 데이터 세트에 있는 개별 데이터들의 K-최근접 이웃을 찾아서 이 데이터와 이웃 사이의 값을 생성해 새로운 데이터 생성
특징 : 단순히 데이터 복제X , 기존 데이터를 기반으로 가상의 새로운 데이터를 만드므로 과적합 방지효과
- 재현율 높아지나 정밀도 낮아지는 현상이 일반적
smote = SMOTE(rnadom_state=0)
# 학습 데이터 세트에 smote 적용한다 (테스트 는 모델 성능 왜곡)
x_train_over , y_train_over = smote.fit_resample(x_train,y_train)
11 스태킹 앙상블
개별 알고리즘으로 예측한 데이터를 최종 학습 데이터로 사용해서 별도의 최종 메타모델로 다시 학습
- Base model (여러개의 개별 알고리즘 모델 )
- Meta Model (기반 모델들 예측값을 다시 피처로 최종 예측)

- 여러개의 다른 개별 기반 모델(knn,랜덤포레스트,xgboost )들이 원복 학습 데이터를 학습 후 예측
- 각 모델이 예측한 결과값을 모아 새로운 데이터 세트 생성 = 메타모델
- 메타 모델이 학습데이터로 사용하여 최종 레이블 값을 학습하고 예측함
오히려 모델이 너무 복잡해져 연산비용이 커지고 데이터량 적으면 과적합 위험이 있어 CV 세트 기반 스태킹 적용
CV 세트 기반의 스태킹
- 개별 모델들이 각각 교차 검증으로 (메타 모델을 위한 학습용 스태킹 데이터 생성과 예측을 위한 테스트용 스태킹 데이터 생성)

스탭1: 기반 모델별로 메타 모델을 위한 데이터 생성
ex) 3개의 폴드
1, 2번 폴드로 학습, 3번 폴드예측 => 이 결과가 메타 모델의 학습데이터 일부
동시에 학습된 모델로 원본 테스트 데이터를 예측함> 평균을 내 메타 모델의 테스트 데이터
총 N번의 반복을 통해 생성된 예측값들을 수직으로 쌓아 원본 학습 데이터와 크기가 같은 최종 메타 학습 데이터 만듬
테스트 데이터 예측값들은 평균을 내어 최종 메타 테스트 데이터를 만듬
스탭2: 메타 모델에서 최종적인 학습과 예측 수행
- 각 기반 모델들이 생성한 학습용 예측 데이터들을 결합(수평)해 최종 메타 학습 피처 데이터 생성 (피처 개수 == 기반 모델 개수)
- 메타 모델 학습및 예측 : 위에서 만든 데이터와 원본 학습 데이터 레이블(y_train)을 결합하여 메타 모델을 학습
원본
| 데이터 | 행 | 열 (피처) |
| X_train | 455 | 30 |
| X_test | 114 | 30 |
메타데이터 결합
| 데이터 이름 | 행 | 열 | 구성 요소 |
| Stack_final_X_train | 455 | 4 | [KNN예측, RF예측, DT예측, Ada예측] |
| Stack_final_X_test | 114 | 4 | [KNN평균, RF평균, DT평균, Ada평균] |
최종 메타 모델 학습 및 예측
메타 모델가 볼 건 이제 30개의 피처가 아니라 4개의 피처뿐.
학습: lr_final.fit(Stack_final_X_train, y_train) | 입력: (455, 4) ↔ 정답: (455, ) - 행의 개수가 455개로 똑같아서 학습이 가능
예측: lr_final.predict(Stack_final_X_test) | 입력: (114, 4) → 결과: (114, )
최종적으로 나온 114개의 정답 과 실제 y_test(114개)와 비교해서 정확도를 확인
# Step 1: 개별 기반 모델별로 메타 모델을 위한 데이터 생성 함수
def get_stacking_base_datasets(model, X_train_n, y_train_n, X_test_n, n_folds):
# 1. 지정된 n_folds만큼 KFold 객체 생성
kf = KFold(n_splits=n_folds, shuffle=False)
# 2. 메타 모델이 사용할 학습 데이터와 테스트 데이터 저장용 배열 초기화
# train_fold_pred: (원본 학습 데이터 수, 1) -> 1개 모델의 예측치
train_fold_pred = np.zeros((X_train_n.shape[0], 1))
# test_pred: (원본 테스트 데이터 수, n_folds) -> 폴드마다 예측치를 저장했다가 나중에 평균
test_pred = np.zeros((X_test_n.shape[0], n_folds))
print(model.__class__.__name__ , ' 모델 학습 시작')
# 3. K-Fold 교차 검증을 수행하며 학습/예측 데이터 생성
for folder_counter, (train_index, valid_index) in enumerate(kf.split(X_train_n)):
# 학습용 데이터와 검증용 데이터 분리
X_tr = X_train_n[train_index] # 훈련용 덩어리 (공부할 데이터)
y_tr = y_train_n[train_index]
X_vl = X_train_n[valid_index] # 검증용 덩어리 (학습에 참여 안 한 데이터)
# [학습] 기반 모델이 분할된 학습 데이터로 공부
model.fit(X_tr, y_tr)
# 학습에 참여 안 한 검증 데이터(X_vl)를 예측 -> 메타 모델의 학습 데이터가 됨
# 과적합 방지
train_fold_pred[valid_index, :] = model.predict(X_vl).reshape(-1, 1)
# 매 반복마다 원본 테스트 데이터(X_test_n)를 예측하여 저장
test_pred[:, folder_counter] = model.predict(X_test_n)
print(f'\t 폴드 세트: {folder_counter} 완료')
# 4. 테스트 데이터 예측값들을 평균 내어 최종적인 메타 테스트 피처 생성
test_pred_mean = np.mean(test_pred, axis=1).reshape(-1, 1)
return train_fold_pred, test_pred_mean
# Step 2: 기반 모델별 데이터 생성 수행
# 각 개별 모델들로부터 메타 모델용 학습/테스트 데이터 세트 반환
knn_train, knn_test = get_stacking_base_datasets(knn_clf, X_train, y_train, X_test, 7)
rf_train, rf_test = get_stacking_base_datasets(rf_clf, X_train, y_train, X_test, 7)
dt_train, dt_test = get_stacking_base_datasets(dt_clf, X_train, y_train, X_test, 7)
ada_train, ada_test = get_stacking_base_datasets(ada_clf, X_train, y_train, X_test, 7)
# Step 3: 생성된 데이터를 결합하여 최종 메타 모델 학습 및 예측
# 개별 모델이 만든 예측 데이터(피처)들을 칼럼 방향(수평)으로 결합
# (455, 1) 짜리 4개를 붙여서 -> (455, 4) 형태로 변환
Stack_final_X_train = np.concatenate((knn_train, rf_train, dt_train, ada_train), axis=1)
Stack_final_X_test = np.concatenate((knn_test, rf_test, dt_test, ada_test), axis=1)
# 최종 메타 모델(LogisticRegression) 학습
# (기반 모델들의 예측값들을 입력(X)으로 하고, 실제 정답(y_train)을 타겟으로 학습)
lr_final.fit(Stack_final_X_train, y_train)
# 최종 예측 및 정확도 측정
stack_final_pred = lr_final.predict(Stack_final_X_test)
print('\n최종 메타 모델의 예측 정확도: {0:.4f}'.format(accuracy_score(y_test, stack_final_pred)))'ML' 카테고리의 다른 글
| [ML_week5_chap7] 군집화 (0) | 2026.02.17 |
|---|---|
| [ML_week4_chap3] 평가 (0) | 2026.02.10 |
| [ML_week3_chap5] 회귀 (0) | 2026.02.03 |
| [ML_week2_chap6] 차원축소 (0) | 2026.01.27 |
| [ML_week2_chap2] 사이킷런 (0) | 2026.01.24 |