⊢MachineLearning

지도학습 : 분류모델 - 의사결정나무

최 수빈 2025. 3. 16. 18:31

 

의사결정나무(Decision Tree)

 

데이터를 분류하거나 회귀하는 데 사용되는 예측 모델 중 하나

트리 구조를 가지며, 각 내부 노드는 특정 특징(feature)에 대한 테스트, 각 가지(branch)는 테스트 결과, 리프 노드(leaf)는 최종 클래스를 나타냄

 

직관적인 분류 모델로서, 데이터의 특징을 기준으로 분류를 수행

과적합(overfitting)의 위험이 존재하므로, 적절한 하이퍼파라미터 튜닝이 필요

 

  • 노드(Node) : 트리의 각 분기점으로, 하나의 특징(feature)에 대한 테스트를 의미
  • 루트 노드(Root Node) : 트리의 최상위 노드, 전체 데이터셋을 포함
  • 리프 노드(Leaf Node) : 최종적으로 결정된 클래스 레이블
  • 깊이 (Depth) : 루트 노드부터 리프 노드까지의 최대 거리
  • 분할 기준(Splitting Criteria) : 데이터를 분리하는 기준 - 정보 이득(Information Gain) 및 지니 계수(Gini Index)가 사용됨

 

분할 기준

 

정보 이득(Information Gain)

엔트로피(Entropy)를 기반으로 데이터를 분리하는 방법

엔트로피가 낮을수록 불확실성이 적음

 

Information Gain(D, A) = Entropy(D) - ∑ (|Dv| / |D|) * Entropy(Dv)

 

 

지니 계수(Gini Index)

 

불순도를 측정하는 방법

값이 작을수록 불순도가 낮음

Gini(D) = 1 - ∑ pi2

 

여기서 pᵢ는 클래스 i의 비율

 

 

의사결정나무 실습

 

유방암 데이터셋

데이터 로드 및 전처리

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 데이터 로드
cancer = load_breast_cancer()
X = cancer.data
y = cancer.target

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 데이터 스케일링
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

 

모델 학습 및 평가

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 모델 생성 및 학습
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

"""
Accuracy: 0.9473684210526315
Classification Report:
              precision    recall  f1-score   support

           0       0.93      0.93      0.93        43
           1       0.96      0.96      0.96        71

    accuracy                           0.95       114
   macro avg       0.94      0.94      0.94       114
weighted avg       0.95      0.95      0.95       114

Confusion Matrix:
[[40  3]
 [ 3 68]]

"""

 

 

 

타이타닉 데이터 실습

 

데이터 로드 및 전처리

import seaborn as sns

# 데이터 로드
titanic = sns.load_dataset('titanic')

# 필요한 열 선택 및 결측값 처리
titanic = titanic[['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']].dropna()

# 성별과 탑승한 곳 인코딩
titanic['sex'] = titanic['sex'].map({'male': 0, 'female': 1})
titanic['embarked'] = titanic['embarked'].map({'C': 0, 'Q': 1, 'S': 2})

# 특성과 타겟 분리
X = titanic.drop('survived', axis=1)
y = titanic['survived']

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 데이터 스케일링
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

 

모델 학습 및 평가

# 모델 생성 및 학습
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

"""
Accuracy: 0.6993006993006993
Classification Report:
              precision    recall  f1-score   support

           0       0.71      0.79      0.75        80
           1       0.69      0.59      0.63        63

    accuracy                           0.70       143
   macro avg       0.70      0.69      0.69       143
weighted avg       0.70      0.70      0.70       143

Confusion Matrix:
[[63 17]
 [26 37]]
 """