Notice
Recent Posts
Recent Comments
Link
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

My blog

[ML_week4_chap4] 분류 본문

ML

[ML_week4_chap4] 분류

gayoung 2026. 2. 10. 17:54

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) 유형 

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

  1. 검색 공간 설정 (hp 모듈사용함): - 파라미터별로 탐색할 범위를 지정 (예: hp.quniform은 간격 있는 숫자)
  2. 목적 함수 생성: - 파라미터를 입력받아 모델을 학습시키고 성능 지표(Loss)를 반환하는 함수.
    주의1: HyperOpt는 무조건 최솟값을 찾으려 함. 따라서 정확도나 AUC처럼 클수록 좋은 값은 -1을 곱해서 넘겨줘야 함.
    주의2: HyperOpt는 값을 실수로만 줌. max_depth 같은 정수형 파라미터는 함수 안에서 int()로 형변환 필수.
  3. 최적화 수행 (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 (기반 모델들 예측값을 다시 피처로 최종 예측)

  1. 여러개의 다른 개별 기반 모델(knn,랜덤포레스트,xgboost )들이 원복 학습 데이터를 학습 후 예측
  2. 각 모델이 예측한 결과값을 모아 새로운 데이터 세트 생성 = 메타모델
  3.  메타 모델이 학습데이터로 사용하여 최종 레이블 값을 학습하고 예측함

오히려 모델이 너무 복잡해져 연산비용이 커지고 데이터량 적으면 과적합 위험이 있어 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