[48일차]Decision Tree - 분류

김준석·2024년 1월 31일

Decision Tree - 분류

결정 기준 (Decision Criteria)

데이터를 분할하는 기준을 결정하는데 사용되는 방법론

  • 트리의 각 단계에서 최적의 분할을 찾기 위해 사용되며
    이를 통해 트리의 깊이와 복잡성을 관리할 수 있음

  • 좋은 결정 기준은 트리를 더욱 간결하고 효율적으로 만들며
    과적합을 방지하고 일반화 성능을 향상시킴!

  • 분류 과정에서 사용되는 결정 기준
    • 정보 이득
    • 지니 불순도

  • • 회귀 과정에서 사용되는 결정 기준
    • MSE 최소화

Tree에서 가장 중요한 것은 분할을 잘하는 정도이다.
그렇기에 분할 결정 기준이 매우 중요!

엔트로피 (Entropy)

어떤 상황이나 현상이 품고 있는 불확실성을 의미하며, 포함하는 정보의 양과 반비례 한다는 의미

  • 엔트로피가 크다 → 불확실성이 크다 → 정보량이 적다

  • 반대로, 엔트로피가 작으면 → 불확실성이 작고, 알고 있는 정보가 많다!

  • 예를 들어, 두 사람이 가위 바위 보를 하는 상황에서

    • [상황 A] 두 사람이 뭘 낼지 모를 때 어떠한 정보도 없음
      따라서 불확실성이 큼
      결국 엔트로피가 크다
    • [상황 B] 한 사람이 뭘 낼지 알고, 한 명은 뭘 낼지 모를 때 한 명의 정보는 알고 있음
      불확실성이 있지만, 상황 A보다는 아님
      엔트로피가 상황 A보다는 작음!

엔트로피 (Entropy) 수식

엔트로피는 수치적으로 구할 수 있으며 아래와 같음

  • 앞의 가위 바위 보 예에서
    • 상황 A : 3.170 (p = 1/9)[모든 상황이 총 9개이다.]
    • 상황 B : 1.585 (p=1/3)[내가 낼 수 있는게 정해졌다면 상황은 총 3개다.]
      • 한 사람의 엔트로피는 0

정보 이득 (Information Gain)

상황은 특정한 정도의 엔트로피를 갖고 있음을 알 수 있다.

노드에 포함되는 데이터의 순도에 따라 엔트로피가 계산될 수 있음

  • 노드 안에 서로 다른 클래스의 데이터가 많이 섞여 있으면 순도 ↓
  • 같은 클래스의 데이터가 모여 있다면 순도 ↑
  • ʻ아빠ʼ ʻ엄마ʼ ʻ아들ʼ 을 갖는 노드는 ʻ아들ʼ만 갖는 노드보다 순도가 낮음
    • 불확실성이 크고, 정보가 적으며, 엔트로피가 크다!

정보 이득 (information gain)이란,
• 부모 노드와 자식 노드들의 엔트로피를 계산해
• 엔트로피가 낮아지는 방향으로 결정 경계를 선정하는 것을 의미함
즉, 정보 이득을 최대화 하는 방향으로!

[나이가 30살 이상이다!] 라는 분류를 해야 이후에 더 큰 정보를 얻을 수 있음.

식은 아래와 같다.

엔트로피 계산 예시

A ~ C 각 노드의 엔트로피 계산

  • 각 노드의 클래스 분포를 기준으로 엔트로피를 계산할 수 있음
  • 엔트로피가 클 수록 데이터가 고르게 분포 (순도가 낮음)

엔트로피가 작아지는 방향으로 노드를 만드는 결정 경계를 생성해야 함!

지니 불순도 (Gini Impurity)

데이터 집합의 순도를 측정하는 또 다른 방법
데이터 안에 존재하는 클래스 분포의 불균형을 평가하는 방법

p! : 데이터 집합 안에 존재하는 i 번째 클래스가 나타나는 확률

0 이상 1 미만의 값을 갖는다.
• 0 : 모든 데이터가 하나의 클래스에 속함. 제일 순도가 높은 상태
• 1에 가까운 값 : 모든 클래스의 데이터가 고루 섞인 상태로 불순도가 제일 높음

A ~ C 각 노드의 지니 불순도

Decision Tree 실습

위와 같은 데이터 형태를 분류 실습을 진행할 예정이다.

정보 이득과 지니 불순도 방법을 활용한 Decision Tree 모델 생성

# 정보 이득을 사용하는 결정 트리 분류기 생성
dt_entropy = DecisionTreeClassifier(criterion='entropy',
                                    max_depth=3, #노드 층 수를 의미
                                    min_samples_split=3) # 분기 진행 시작 조건인 노드 내 샘플 수
dt_entropy.fit(X, y)

# 지니 불순도를 사용하는 결정 트리 분류기 생성
dt_gini = DecisionTreeClassifier(criterion='gini',
                                 max_depth=3,
                                 min_samples_split=3) # 분기 진행 시작 조건인 노드 내 샘플 수
dt_gini.fit(X, y) # 피팅

max_depth=3 : 노드 층 수를 의미 / 3개의 층을 만들 것이라는 의미.

이후 sklearn의 plot_tree 를 사용하면 나눠진 모습을 그려볼 수 있다.

엔트로피를 기준으로 나눈 모습

# 두 모델의 훈련된 구조를 확인
from sklearn.tree import plot_tree

# 정보 이득을 사용한 결정 트리
plt.figure(figsize=(24, 12))
plot_tree(dt_entropy, filled=True,
          feature_names=['Feature 1', 'Feature 2'],
          class_names=['Class 0', 'Class 1', 'Class 2'])
plt.title("Decision Tree using Entropy")
plt.show()

지니 불순도를 사용한 결정 트리

# 지니 불순도를 사용한 결정 트리
plt.figure(figsize=(24, 12))
plot_tree(dt_gini, filled=True,
          feature_names=['Feature 1', 'Feature 2'],
          class_names=['Class 0', 'Class 1', 'Class 2'])
plt.title("Decision Tree using Gini")
plt.show()

어떤식으로 데이터를 분류했는지 시각화를 진행해 보자면 아래와 같이 나올 수 있다.

# 결정 경계 그려보기
import numpy as np

# 데이터와 결정 경계를 시각화하는 함수
def plot_decision_boundaries(X, y, model, title):
    # 마커와 색상 설정
    markers = ('s', 'x', 'o')
    colors = ('red', 'blue', 'green')
    cmap = plt.cm.RdYlBu

    # 결정 경계 그리기
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.01),
                           np.arange(x2_min, x2_max, 0.01))
    Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)

    # 데이터셋의 샘플 플로팅
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
                    alpha=0.8, c=colors[idx],
                    marker=markers[idx], label=f'Class {cl}')

    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.legend(loc='upper left')
    plt.title(title)

# 첫 번째 특성과 두 번째 특성을 이용한 데이터셋 시각화
plt.figure(figsize=(24, 12))
plt.subplot(1, 2, 1)
plot_decision_boundaries(X, y, dt_entropy, "Decision Tree (Entropy)")
plt.subplot(1, 2, 2)
plot_decision_boundaries(X, y, dt_gini, "Decision Tree (Gini)")
plt.show()

트리문제는 직관적으로 어떻게 나눴는지 확인할 수 있는 모습이다.

0개의 댓글