본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 결정 트리(Decision Tree) 과적합 이유 3가지와 해결 방법 7가지 완벽 가이드

by Papa Martino V 2026. 4. 8.
728x90

결정 트리(Decision Tree)
결정 트리 (Decision Tree)

 

머신러닝 알고리즘 중 가장 직관적이고 해석력이 뛰어난 결정 트리(Decision Tree)는 데이터 과학자들에게 매우 사랑받는 도구입니다. 하지만 결정 트리는 치명적인 약점을 가지고 있습니다. 바로 과적합(Overfitting)에 매우 취약하다는 점입니다. 본 포스팅에서는 결정 트리가 왜 유독 과적합에 빠지기 쉬운지 그 구조적 이유를 분석하고, 실무에서 이를 해결하기 위한 7가지 구체적인 파이썬 구현 전략을 제시합니다.


1. 결정 트리가 과적합(Overfitting)에 취약한 근본적인 이유

결정 트리는 데이터의 불순도(Impurity)를 최소화하는 방향으로 영역을 분할해 나갑니다. 이 과정에서 발생하는 특유의 메커니즘이 과적합을 유도합니다.

  • 무한한 복잡성 가능성: 트리의 깊이(Depth)에 제한을 두지 않으면, 모델은 단 하나의 데이터 포인트가 남을 때까지 분할을 계속합니다. 이는 훈련 데이터의 '노이즈'까지 학습하게 만듭니다.
  • 비선형적 경계의 세분화: 선형 모델과 달리 결정 트리는 축에 수직인 계단식 경계를 만듭니다. 데이터가 조금만 복잡해도 이를 설명하기 위해 매우 복잡하고 지엽적인 경계를 생성합니다.
  • 탐욕적 알고리즘(Greedy Algorithm): 결정 트리는 현재 시점에서 가장 최적인 분할만을 선택합니다. 이 과정에서 전체적인 일반화보다는 당장의 오차 감소에 집중하게 됩니다.

결정 트리와 다른 모델의 과적합 메커니즘 차이 비교

비교 항목 결정 트리 (Decision Tree) 선형 모델 (Linear Model) 차이 및 특징
모델 유연성 매우 높음 (비모수적) 낮음 (모수적) 트리는 데이터 형태에 구속받지 않아 과하게 적응함
데이터 민감도 매우 예민함 상대적으로 둔감함 트리는 소수의 이상치에도 분할 경계가 완전히 변함
주요 과적합 요인 트리의 깊이 및 노드 수 가중치의 크기 (L1/L2) 트리는 '구조적 복잡성'이 과적합의 핵심
해결 접근법 가지치기 (Pruning) 규제화 (Regularization) 트리는 성장을 멈추거나 잘라내는 방식 사용

2. 실무 개발자를 위한 결정 트리 과적합 해결 Example 7가지

파이썬의 scikit-learn 라이브러리를 활용하여 실무 프로젝트에서 즉시 적용 가능한 과적합 방지 코드를 제공합니다.

Example 01. max_depth 설정을 통한 트리의 최대 깊이 제한

가장 기본적이면서 강력한 방법입니다. 트리가 너무 깊게 자라지 않도록 층수를 제한합니다.

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

# max_depth를 3으로 제한하여 과적합 방지
model = DecisionTreeClassifier(max_depth=3, random_state=42)
model.fit(X, y)

print(f"훈련 세트 정확도: {model.score(X, y):.4f}")

Example 02. min_samples_split으로 분할을 위한 최소 샘플 수 지정

노드를 분할하기 위해 필요한 최소 샘플 수를 설정하여, 너무 작은 데이터셋에서 분할이 일어나는 것을 방지합니다.

# 노드에 최소 20개 이상의 데이터가 있어야 분할 가능하도록 설정
model = DecisionTreeClassifier(min_samples_split=20, random_state=42)
model.fit(X, y)

Example 03. min_samples_leaf를 통한 리프 노드 조건 강화

말단 노드(Leaf)가 가져야 할 최소 샘플 수를 지정하여, 지엽적인 데이터에 모델이 반응하지 않게 합니다.

# 리프 노드에 최소 5개 이상의 데이터가 남도록 보장
model = DecisionTreeClassifier(min_samples_leaf=5, random_state=42)
model.fit(X, y)

Example 04. 비용 복잡도 가지치기 (Cost Complexity Pruning)

ccp_alpha 값을 조정하여 트리의 복잡도에 패널티를 부여합니다. 최신 실무 기법 중 하나입니다.

# ccp_alpha가 클수록 더 많은 노드가 가지치기 됨
model = DecisionTreeClassifier(ccp_alpha=0.01, random_state=42)
model.fit(X, y)

Example 05. GridSearch를 활용한 최적 하이퍼파라미터 찾기

교차 검증을 통해 과적합이 발생하지 않는 최적의 파라미터 조합을 자동으로 탐색합니다.

from sklearn.model_selection import GridSearchCV

params = {
    'max_depth': [3, 5, 7],
    'min_samples_leaf': [1, 3, 5]
}

grid_cv = GridSearchCV(DecisionTreeClassifier(), param_grid=params, cv=5)
grid_cv.fit(X, y)
print(f"최적 파라미터: {grid_cv.best_params_}")

Example 06. 특성 중요도(Feature Importance) 분석 후 변수 제거

과적합의 원인이 되는 불필요한 노이즈 특성을 제거하여 모델을 단순화합니다.

import pandas as pd

model = DecisionTreeClassifier().fit(X, y)
ftr_importances = pd.Series(model.feature_importances_, index=['sepal_l', 'sepal_w', 'petal_l', 'petal_w'])

# 중요도가 낮은 특성은 제외하고 재학습 고려
print(ftr_importances.sort_values(ascending=False))

Example 07. 앙상블 기법(Random Forest)으로의 전환

단일 트리의 한계를 극복하기 위해 여러 트리의 의견을 종합하는 배깅(Bagging) 방식을 사용합니다.

from sklearn.ensemble import RandomForestClassifier

# 100개의 트리를 생성하여 과적합 위험을 분산시킴
rf_model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
rf_model.fit(X, y)

3. 결론 및 실무적 제언

결정 트리는 데이터의 작은 변화에도 크게 휘둘리는 고분산(High Variance) 모델입니다. 따라서 실무에서는 단일 결정 트리를 그대로 사용하기보다는 위에서 소개한 7가지 제어 기법을 반드시 적용해야 합니다. 특히 최근에는 ccp_alpha를 활용한 사후 가지치기와 Random ForestXGBoost 같은 앙상블 모델로의 확장이 표준으로 자리 잡았습니다.

내용 출처 및 참고 자료:

  • Scikit-learn Official Documentation: Decision Trees (User Guide Section 1.10)
  • Introduction to Statistical Learning (James, Witten, Hastie, Tibshirani)
  • Machine Learning Mastery: How to Avoid Overfitting in Decision Trees
  • Python Data Science Handbook (Jake VanderPlas)
728x90