데이터 분석/머신러닝, 딥러닝

결정 트리(Decision Tree)

fullfish 2025. 11. 5. 15:06

분류(Classification) 회귀(Regression) 모두 가능한 지도 학습 모델 하나

스무고개 하듯이 /아니오 질문을 이어가며 학습

 

가지 분리 기준
• 데이터를 섞여 있지 않게, 가장 깔끔하게 나누는 질문
• 불순도가 낮아지고 순수도가 높아지는 방향으로 분리
• 불확실성이 낮아지는 방향
• 최종 노드가 너무 많으면 Overfitting 가능성이 커짐

 

불순도 측정 지표
• 값이 작을수록 순수도가 높음(분류가 잘 됨): 0~1
• 지니(Gini)지수
 1 − Σkᵢ₌₁pᵢ² => 1 − Σ(각 범주별 개수/전체개수)²
• 엔트로피(Entropy)지수
 − Σkᵢ₌₁pᵢ log₂pᵢ

 

정보 이득 (Information gain)
• 부모 노드와 자식 노드간의 불순도 차이

 

가지치기 규칙 (Pruning rule)
• 오버피팅(과적합)을 막기 위한 전략
• 트리의 최대 깊이나 터미널 노드의 최대 개수, 혹은 한 노드가 분할하기 위한 최소 데이터 수를 제한하는 것
• 하이퍼 파라미터 지정으로 제한
 - min_sample_split : 부모 노드를 쪼개기 위해 필요한 최소 샘플 수
 - max_depth : 트리의 최대 깊이 지정
 - min_samples_leaf : 리프노드(터미널 노드)의 최소 샘플수 지정
 - max_features : 노드 분할 시 고려할 특성(피처) 수의 상한

max_features의 값

None          전체 특성 다 사용            feature   10개면 10개 전부 사용
"sqrt"        전체 특성 수의 제곱근만 사용    feature 100개면 → 10개만 무작위 선택
"log2"        전체 특성 수의 로그2값만 사용   feature 100개면 → 약 7개만 선택
정수 (int)     지정한 개수만 사용            5면 무조건 5개
실수 (float)   비율로 지정                 0.5면 절반만 선택

 

 

예시

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt

iris = load_iris(as_frame=True)
X = iris.data
Y = iris.target

x_train, x_test, y_train, y_test = train_test_split(
    X, Y, test_size=0.2, random_state=42, stratify=Y
)

dt = DecisionTreeClassifier(max_depth=5, random_state=42)
dt.fit(x_train, y_train)

pred = dt.predict(x_test)
print(accuracy_score(y_test, pred))
print(classification_report(y_test, pred))

plt.figure(figsize=(12, 6))
plot_tree(
    dt,
    feature_names=X.columns,
    class_names=iris.target_names,
    filled=True,
    rounded=True,
)
plt.tight_layout()
plt.show()

print(dt.feature_importances_)

for name, imp in zip(X.columns, dt.feature_importances_):
    print(f"{name:20s} {imp:.3f}")

 

 

트리는 스케일링을 할 필요가 없음