ML/분류(Classification)

결정트리의 과적합(Overfitting)

야뤼송 2024. 5. 7. 08:04
반응형

 

1. 결정트리 더미 데이터 생성

 

사이킷런에서 제공하는 make_classification()를 통해 분류 모형 데이터를 생성하고 시각화해 이를 통해 과적합(Overfitting)을 살펴본다.

 

make_classification()는 분류를 위해 테스트용 데이터를 쉽게 만들수 있도록 하는 함수이며 파라미터는 아래와 같다.

  • n_features : 독립 변수의 수, 디폴트 20
  • n_samples : 표본 데이터의 수, 디폴트 100
  • n_redundant : 독립 변수 중 다른 독립 변수의 선형 조합으로 나타나는 성분의 수, 디폴트 2
  • n_informative : 독립 변수 중 종속 변수와 상관 관계가 있는 성분의 수, 디폴트 2
  • n_repeated : 독립 변수 중 단순 중복된 성분의 수, 디폴트 0
  • n_classes : 종속 변수의 클래스 수, 디폴트 2
  • n_clusters_per_class : 클래스 당 클러스터의 수, 디폴트 2
  • weights : 각 클래스에 할당된 표본 수
  • random_state : 난수 발생 시드

 실습

과적합 케이스를 위해  다음과 같이 데이터를 생성한다. feature는 2개, 결정값 클래스는 3가지 유형을 가진 calssification 더미 데이터를 생성한다.

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')

▶ Out

 

 

2. 결정트리의 과적합

 

 실습

위에서 생성한 결정트리 더미 데이터를 가지고 Decision Boundary를 시각화하는 함수를 생성한다.

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)

 

 

주요 하이퍼파라미터를 default 셋팅된 결정트리의 Decison 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)

▶ Out

 

 

이제 주요 하이퍼 하이퍼파라미터 중 min_samples_leaf 값을 조정하여 Decision Boundary를 시각화해보자. min_samples_leaf를 간략히 설명하면 말단 노드(Leaf)가 되기 위한 최소한의 샘플 데이터 수를 설정하기 위한 값이다.

min_samples_leaf를 6으로 설정하게 되면 6개 이하의 데이터는 리프 노드를 생성할 수 있도록 생성 규칙을 완화하게 되면 좀 더 일반화되고 덜 복잡한 형태로 분류됨을 확인할 수 있다. 이렇게 하이퍼 파라미터를 조정하게 되면 모델의 성능을 향상시킬 수 있게 된다.

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

▶ Out

 

반응형