머신러닝 분류 알고리즘 정리로 결정트리와 앙상블 학습에 대해 개념 정리로 어떠한 상황에 어떤 학습방법을 사용하는게 좋을까 라는 판단이 가능하도록 유도하는것이 목적인 정리

 

 

1. 결정트리

루트노드와 그아래 규칙 노드와 리프노드로 가지치기를 하듯 분류하는 알고리즘이다

결정트리의 올바른 방향은 지니계수가 작아지고 결정트리가 대칭을 유지하도록 데이터 전처리 및 엔지니어링 하는것이 바람직하다.

 

용어 정리

루트 노드 시작점
규칙 노드 가지 치기 규칙
리프 노드 분류 결정 값을 가짐
지니계수  정보이득 지수값 (값이 크면 불순도가 높음)

 

 

파라미터

min_samples_split  노드를 분할하기 위한 최소 샘플 데이터 수
min_samples_leaf  리프 노드의 최소 샘플 데이터 수
max_features  분할에 사용되는 최대 피쳐 수 (default는 모두사용)
max_depth  트리의 최대 깊이 설정
max_leaf_nodes  리프 노드 최대 개수

 

 

활용 방안

  • 결정 트리 시각화

 

 

  • 피쳐별 중요도 (Featuer Importance) 시각화

 

  • 산포도 기반 시각화

 

 

 

 

2. 앙상블 학습

앙상블 학습은 여러개의 알고리즘을 생성, 학습, 예측 값 처리 후 최종 결과를 도출하는 기법으로 방식에 따라 다음의 4가지로 구분한다. 쉽게보면 위의 결정트리가 학습 결과가 약한 모델이라면 이를 반복 혹은 계속적인 학습, 결합을 통해 강한 모델을 만드는 방식이다

  • 보팅

다른 알고리즘을 여러개 병렬 연결하여 사용하는 방법이다

 

종류에 따라 하드 보팅, 소프트 보팅으로 나눌수 있으며 방법은 아래의 사진과 같다.

하드 보팅 다수결, 최빈값
소프트 보팅 확률값 평균

하드 보팅은 상황에 따라 약한 분류 모델의 다수표를 받아 선정될 수 있기에 약점이 존재하여 소프트 보팅이 주로 성능이 더 높음으로 판단된다.

 

  • 배깅

개별 모델들이 서로 다른 샘플링 데이터를 훈련에 사용하여 병렬 연결하며 동일 알고리즘을 여러개 만들어서 소프트 보팅을 수행한다. 부스팅 모델에 비해 특수한 경우가 아니고선 성능이 좋을 확률이 낮음  EX) 랜덤 포레스트

 

샘플링 데이터는 위의 표처럼 중복된 샘플링일수 있음

 

  • 부스팅

현재는 가장 강한 분류 모델로 여러개의 약한 분류기를 순차적으로 학습 및 예측을 수행하며 잘못 예측한 데이터에 가중치를 부여하여 오류를 개선하여 다음 학습에 반영하는 방식이다.

 

모델 종류

AdaBoost  반복적인 가중치 계산을 통해 값들을 분류하며 성능 향상하는 방식
GBM (Gradient Boost Machine) 1. Ada에서 가중치를 업데이트 하는 방식으로의 개선 
2. 경사하강법 가중치 업데이트 방식
XGBoost 1. GBM의 느린학습속도와 과적합을 보완
2. 병렬 학습
3. 조기학습종료 기능
4. 과적합 방지 파라미터 (L1,L2) 
LGBM 비대칭형 분류
서드파티 CatBoost

 

 

XGBoost

  • 파라미터
booster  부스팅 알고리즘 트리기반 모델 : gbtree or dart
선형기반 모델 : gblinear 
dart : 과적합 방지를 위한 특정 비율 dropout 적용
objective 훈련 목적 회귀 :  reg:squarederror
이진분류 : binary:logistic
다중분류 : multi:softmax
확률값 다중분류 : multi:softprob
eta learning_rate
학습 비율 가중
부스팅을 반복 과정에서 모델 업데이트 비율
default : 0.3
범위 : 0 ~ 1
min_child_weight 과적합 방지 범위 0 ~ 1
하위 노드의 최소 가중치의 합 (리프 노드까지의 모든가중치의 합에 대한 제한값)
값이 크면 과소적합 우려가있음
max_depth 트리의 깊이 과적합 방지
분류가 깊어지면 메모리 사용량 증가로 학습 속도가 저하
max_leaf_nodes 리프 노드의 최대 개수 리프 노드의 최대 개수
gamma 노드 분할 시 최소 감소값 지정 default 0
노드 분할시 필요한 최소 감소값을 지정
손실 감소가 gamma보다 크면 노드 분할
값이 클수록과대 적합 방지 효과 
subsamplt 데이터 샘플링 비율 default 1
범위 0 ~ 1 (0.6~1 사용)
데이터의 샘플링 비율
colsample_bytree 각 트리 샘플링 비율 각 트리 샘플링 비율
범위 0~1
default 1
lambda 가중치에 대한 L2규제 조정값 가중치에 대한 L2규제 조정값 (릿지 알고리즘)
default 1
값이 크면 과대적합 방지효과
alpha 가중치에 대한 L1규제 조정값 가중치에 대한 L1규제 조정값 (라쏘 알고리즘)
값이 크면 과대적합 방지효과
default 1
scale_pos_weight 불균형 데이터 가중치 조정값 label값이 불균형할때 균형을 맞춤
random_state 랜덤 시드값 랜덤 시드

 

LGBM

  • 파라미터

  • 스태킹

2단계를 통해 모델을 생성하는 방법으로 1차 모델의 예측 결과를 2차 모델의 훈련 데이터로 사용하는 형태

 

 

3. 앙상블 학습 시 추가 방안

 

그리드서치 

- 하이퍼파라미터 튜닝

 

K폴드

- 데이터 분할 방식

 

'Python > 머신러닝' 카테고리의 다른 글

[XAI] XGBoost 분류 모델 시각화  (6) 2024.08.28
머신러닝 데이터 교차검증 python  (0) 2024.03.05
머신러닝 피쳐스케일링 python  (0) 2024.03.05

신호처리 AI 프로젝트를 시작하면서 프로젝트 초기 데이터 분석을 하던 중 레퍼런스 중 기본연구보고서에서 결정트리를 시각화 한 사진을 보고 좋은 방법이라는 생각이 들어서 머신러닝으로 데이터를 분석하기 시작했다

 

 

1. DecisionTreeClassifier plot_tree 방법

처음에는 기본연구보고서와 같은방법으로 결정트리로 시각화 해보았으나 아래의 사진처럼 분석하던 데이터는 아래의 사진처럼 단순 트리 구조만으로 시각화 하기에는 좋지 않아보였고 이보다는 차트나 군집으로 시각화 하는것이 맞겠다는 생각이 들어서 XAI 방법에 대해 찾아보던 중 XGBoost로 시각화하는 방법을 찾게 됐다.

 

 

2. XGBoost - importance feature, Decision Boundary

XGBoost의 XGBClassifier의 gbtree booster를 사용해 트리 모델을 사용하면 트리 결과를 사용하여 아래 사진과 같이 시각화가 가능했다. feature importance의 결과를 바탕으로 값이 높은 feature 2개를 사용해서 시각화 하도록 만들었다. 확실히 한눈에 잘 보여서 이후 데이터 수집에서의 문제점을 찾아 ETL 프로그램을 수정했다.

 

 

3. 마무리

시각화로 인한 문제점 파악의 힘은 굉장했고 바로 핵심이 파악되어서 피쳐 엔지니어링 + 데이터 수집 관점 변경 으로 원하는 결과를 찾아냈다 피쳐 엔지니어링을 통해 찾아낸 핵심 데이터로 만든 오른쪽의 한줄로 구분되는 분류 모델은 매우 정확한 데이터 분석이였다 

 

프로젝트 초기 가능성 검사였고 분류 모델 AI인 점 + 시각화의 시너지가 잘맞아서 좋은 효과를 낸것 같다

이후 프로젝트에서 회귀 모델 분석에서도 XAI 방식을 적용해보면 좋을것 같다

 

 

4. Code

XGB 사용되는 부분의 기본 코드입니다

# 훈련/테스트 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.7)#, random_state=1)

# XGBoost 모델 학습
xg_reg = XGBClassifier(
    booster='gbtree', 
    max_depth=20, 
    objective='binary:logistic', 
    eval_metric='logloss',
    verbosity=0,
    n_estimators = 100,
    device='cuda',
    validate_parameters = True)
xg_reg.fit(X_train, y_train)

pred = xg_reg.predict_proba(X_test)
pred_t = pred[:, -1]
fpr, tpr, _ = roc_curve(y_test.values, pred_t)

print('XGBoost AUC:', auc(fpr, tpr))

# 피처 중요도 시각화
plt.figure(figsize=(10, 6))
plot_importance(xg_reg, importance_type='weight', max_num_features=10, height=0.5)
plt.show()

# XGB 경계 시각화
xg_importantces_param_count = 2

xg_importances = xg_reg.feature_importances_
xg_indices = np.argsort(importances)[::-1]
xg_importances_param = X.columns[xg_indices[:xg_importantces_param_count]]

X_subset = X_train[[xg_importances_param[i] for i in range(xg_importantces_param_count)]]
xg_subset_reg = XGBClassifier(
    booster='gbtree', 
    max_depth=20, 
    objective='binary:logistic', 
    eval_metric='rmse',
    verbosity=0,
    n_estimators = 100,
    device='cuda',
    validate_parameters = True)
xg_subset_reg.fit(X_subset, y_train)

x_min, x_max = X_subset[xg_importances_param[0]].min() - 1, X_subset[xg_importances_param[0]].max() + 1
y_min, y_max = X_subset[xg_importances_param[1]].min() - 1, X_subset[xg_importances_param[1]].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
                     np.arange(y_min, y_max, 0.01))
Z = xg_subset_reg.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.figure(figsize=(10, 6))
plt.contourf(xx, yy, Z, alpha=0.4, cmap='viridis')
sns.scatterplot(x=X_train[xg_importances_param[0]], y=X_train[xg_importances_param[1]], hue=y_train, palette='viridis', edgecolor='k')
plt.title(f'Decision Boundary ({xg_importances_param[0]} vs {xg_importances_param[1]})')
plt.xlabel(f'{xg_importances_param[0]}')
plt.ylabel(f'{xg_importances_param[1]}')
plt.show()

인공지능 학습에서 데이터 label의 균형 분포와 shuffle은 과적합과 데이터 불균형 문제의 효과적인 예방법이다

 

 

 

1. K 폴드 교차 검증

 

K 폴드 교차 검증으로 전체 데이터를 나누는 방법으로 사용된다

import numpy as np
from sklearn.model_selection import KFold
arr = np.arange(20)

folds = KFold(n_splits=5, shuffle=True)
for train_idx, vaild_idx in folds.split(arr):
  print( f'훈련용 { arr[train_idx] }, 검증용 { arr[vaild_idx] }' )

n_splits 는 데이터 세트 개수, shuffle은 데이터를 섞을지의 여부로 0 ~ 19의 데이터를 훈련용과 검증용을 구분하여

val를 K폴드 교차 검증 방법으로 나누는 코드이다

훈련용 [ 0  2  3  4  5  6  7 10 11 12 13 14 16 17 18 19], 검증용 [ 1  8  9 15]
훈련용 [ 1  2  4  5  7  8  9 10 11 12 14 15 16 17 18 19], 검증용 [ 0  3  6 13]
훈련용 [ 0  1  3  4  5  6  7  8  9 10 13 14 15 16 17 18], 검증용 [ 2 11 12 19]
훈련용 [ 0  1  2  3  6  7  8  9 11 12 13 15 16 17 18 19], 검증용 [ 4  5 10 14]
훈련용 [ 0  1  2  3  4  5  6  8  9 10 11 12 13 14 15 19], 검증용 [ 7 16 17 18]

 

 

 

 

2. 층화 K 폴드 교차 검증

 

데이터 label이 불균형하게 분포되어있을때 균형있는 분포를 위해 사용된다

from sklearn.model_selection import StratifiedKFold
y = np.array(['A']*5 + ['B']*45)
X = np.arange( len(y) )
folds = StratifiedKFold(n_splits=5)
for idx, (train_idx, vaild_idx) in enumerate( folds.split(X, y) ):
  print( f'검증용 {idx + 1} 번째 데이터')
  print( f'검증용 { y[vaild_idx] }' )

45:5 비율의 데이터를 K폴드로 나누면 A데이터가 없는 데이터세트가 생길 수 있기에 층화 K폴드를 사용하면 된다

 

검증용 1 번째 데이터
검증용 ['A' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B']
검증용 2 번째 데이터
검증용 ['A' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B']
검증용 3 번째 데이터
검증용 ['A' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B']
검증용 4 번째 데이터
검증용 ['A' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B']
검증용 5 번째 데이터
검증용 ['A' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B' 'B']

 

 

 

 

3. GridSearchCV

교차검증과 하이퍼파라미터 튜닝

from sklearn.model_selection import GridSearchCV, RandomizedSearchCV, train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=45)
X_train.shape, X_test.shape, y_train.shape, y_test.shape

gridModel = GridSearchCV(
    model,
    {
        'max_depth':[1,2,3],
        'min_samples_split':[2,3]
    },
    cv = 5,
    refit = True,
    return_train_score=True

교차검증과 함께 하이퍼파라미터 튜닝도 같이 진행하게 된다 위 예시 코드로는 max_depth에 1,2,3, min_samples_split 2,3  의 값중 가장 정확도가 높은 파라미터를 얻을 수 있게된다.

 

해당 방법은 대규모 학습에서는 미니멀하게 학습을 진행하여 실험적으로 진행한다

 

 

 

 

4. RandomizedSearchCV

random_cv = RandomizedSearchCV(
    DecisionTreeClassifier(), 
    {
        'max_depth':randint(low=3, high=11),
        'max_features':randint(low=2, high=4),
    },
    n_iter=24,
    random_state=1,
    scoring='accuracy',
    verbose=1
)

 

n_iter 탐색횟수만큼 랜덤하게 학습을 진행한다

검증용이 테스트용보다 정확도가 높은 경우가 자주 발생하여 과적합이 자주 발생하는 방법이다

머신러닝 피쳐스케일링의 4가지 방식

 

 

 

1. MinMax Scaler

from sklearn.preprocessing import MinMaxScaler
MinMaxScaler().fit_transform(arr)

최소값이 0, 최대값이 1이 되도록 조정한다

이상수치가 있을 시 좁은 구간에 데이터가 몰릴 수 있음 제거필요

 

 

 

2. Standard Scaler

from sklearn.preprocessing import StandardScaler
StandardScaler().fit_transform(arr2)

평균 0, 표준편차 1이 되도록 모든 값을 조정하여 정규분포를 따르게한다

 

 

 

3.MaxAbs Scaler

from sklearn.preprocessing import MaxAbsScaler
MaxAbsScaler().fit_transform(arr3)

0을 기준으로 절대값이 최대인값을 1로 설정하고 나머지 값들은 기준에 맞추어 0~1 사이로 변환 처리

 

 

4. Robust Scaler

from sklearn.preprocessing import RobustScaler
RobustScaler().fit_transform(arr4)

중앙값을 0, 사분위수 기준 전체 데이터의 50%가 중앙에 밀집되도록 변환

중앙에 흩어진 범위가 1이 되도록 조정한다

 

 

 

+ Recent posts