상세 컨텐츠

본문 제목

[파이썬 머신러닝 완벽 가이드] 04 분류 (3) 결정트리 과적합

학습기록

by green010809 2024. 4. 18. 11:37

본문

1. 결정 트리가 어떻게 학습 데이터를 분할해 예측을 수행하는지 

2. 이로 인한 과적합 문제

1,2를 시각화해 알아보겠다.

 

과정 1 : 분류를 위한 데이터 세트 제작

#테스트용 분류 데이터를 만들기 위한 함수 make_classification()
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
%matplotlib inline

plt.title("3 Class values with 2 Features Sample data creation")

# 2차원 시각화를 위해서 feature는 2개, 결정값 클래스는 3가지 유형의 classification 샘플 데이터 생성. 
X_features, y_labels = make_classification(n_features=2, n_redundant=0, n_informative=2,
                             n_classes=3, n_clusters_per_class=1,random_state=0)


# plot 형태로 2개의 feature로 2차원 좌표 시각화, 각 클래스값은 다른 색깔로 표시됨. 
plt.scatter(X_features[:, 0], X_features[:, 1], marker='o', c=y_labels, s=25, cmap='rainbow', edgecolor='k')

 

 

위 코드의 결과 그래프

 

위 그래프는 각 피처가 X,Y축으로 나열된 2차원 그래프이며, 3개의 클래스 값 구분은 색깔로 돼 있습니다.

 

++ 추가 정보

함수 make_classification()을 이해하기 위함 자료

출처 : make_classification(데이터 만들기) :: Taegu (tistory.com)

 

make_classification(데이터 만들기)

make_classification¶make_classification은 사이킷런의 패키지로 가상의 분류모형 데이터를 생성해주는 함수이다. 매개변수에 대해 알아보자. 참고 : https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make

taeguu.tistory.com

 

X_features[:, 0]

 

python에서 a[:,0]의 의미는

a라는 리스트에서 모든 행에 대한 첫 번째 열을 의미합니다.

 

그렇다면 a[:,1]의 의미는?

리스트 a에서 모든 행의 두 번째 열을 의미합니다.

 

a[0,:]의 의미는 ?

첫 번째 행의 모든 열을 뜻합니다.

 

과정 2 : X_features와 y_labels 데이터 세트를 기반으로 결정트리 학습

import numpy as np

# Classifier의 Decision Boundary를 시각화 하는 함수
def visualize_boundary(model, X, y):
    fig,ax = plt.subplots()
    
    # 학습 데이타 scatter plot으로 나타내기
    ax.scatter(X[:, 0], X[:, 1], c=y, s=25, cmap='rainbow', edgecolor='k',
               clim=(y.min(), y.max()), zorder=3)
    ax.axis('tight')
    ax.axis('off')
    xlim_start , xlim_end = ax.get_xlim()
    ylim_start , ylim_end = ax.get_ylim()
    
    # 호출 파라미터로 들어온 training 데이타로 model 학습 . 
    model.fit(X, y)
    # meshgrid 형태인 모든 좌표값으로 예측 수행. 
    xx, yy = np.meshgrid(np.linspace(xlim_start,xlim_end, num=200),np.linspace(ylim_start,ylim_end, num=200))
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    
    # contourf() 를 이용하여 class boundary 를 visualization 수행. 
    n_classes = len(np.unique(y))
    contours = ax.contourf(xx, yy, Z, alpha=0.3,
                           levels=np.arange(n_classes + 1) - 0.5,
                           cmap='rainbow', clim=(y.min(), y.max()),
                           zorder=1)
from sklearn.tree import DecisionTreeClassifier

 

학습 1 ) 결정 트리 생성에 대한 제약 X + visualize_boundary() 함수 사용

visualize_boundary()

머신러닝 모델이 클래스 값을 예측하는 결정 기준을 색상과 경계로 나타내 모델이 어떻게 데이터 세트를 예측 분류하는지 이해를 도움

 

from sklearn.tree import DecisionTreeClassifier

# 특정한 트리 생성 제약없는 결정 트리의 Decsion Boundary 시각화.
dt_clf = DecisionTreeClassifier(random_state=156).fit(X_features, y_labels)
visualize_boundary(dt_clf, X_features, y_labels)

 

일부 이상치 데이터까지 분류하기 위해 분할이 자주일어나 결정 기준 경계가 매우 많아졌다.

 

결정 트리의 기본 하이퍼 파라미터 설정은 

1. 리프 노드 안에 데이터가 모두 균일

2. 하나만 존재

와 같은 엄격한 기준이기에 복잡해졌다.

 

복잡한 모델은 다른 형태의 데이터 세트를 예측했을 때, 정확도가 떨어지게 됨 ( 과적합 문제 )

 

학습 2 ) min_samples_leaf = 6 을 설정

6개 이하의 데이터는 리프 노드를 생성할 수 있도록 규칙을 완화 

# min_samples_leaf=6 으로 트리 생성 조건을 제약한 Decision Boundary 시각화
dt_clf = DecisionTreeClassifier(min_samples_leaf=6, random_state=156).fit(X_features, y_labels)
visualize_boundary(dt_clf, X_features, y_labels)

결과 )

이상치에 크게 반응하지 않으면서 좀 더 일반화된 분류 규칙에 따라 분류됐음

 

결론 )

학습1 모델보다 학습2 모델의 성능이 더 뛰어날 가능성이 높다

그 이유는 테스트 데이터는 학습 데이터와 다르며,

학습 데이터에만 최적화된 분류 기준은 테스트 데이터 세트에서 정확도를 떨어뜨릴 수 있기 때문

 

 

관련글 더보기