검색
← 모듈 로드맵

결정 트리: 지니 불순도 · 정보 이득 · 가지치기

강의 · 입문자 · KAITABASE 정리

지니 · 정보 이득 손계산, 회귀 트리 분산 감소, 깊이 제한 · 가지치기 실행으로 익히는 결정 트리

먼저 알아야 할 것

비율 · 확률엔트로피분산과적합과 검증

다루는 내용

예/아니오 질문으로 데이터를 나누는 결정 트리가 분할을 고르는 기준을 scikit-learn 문서의 지니 · 엔트로피 · 가중 불순도 식으로 설명하고, 두 후보 분할을 손계산으로 비교합니다. 회귀 트리가 분산을 가장 많이 줄이는 지점을 찾는 과정과 계단 함수의 외삽 한계를 보여 줍니다. 유방암 데이터에서 깊이 · ccp_alpha를 바꾼 실행 결과로 과적합과 가지치기를 확인합니다.

해설

결정 트리: 지니 불순도 · 정보 이득 · 가지치기

결정 트리(decision tree)는 "나이가 30 이하인가?", "소득이 300 이상인가?" 같은 예/아니오 질문을 차례로 던져 데이터를 잘게 나누는 모델입니다. 사람이 읽을 수 있는 규칙이 나오고 전처리가 거의 필요 없어 실무에서 아주 많이 쓰이며, 랜덤 포레스트와 그래디언트 부스팅의 부품이기도 합니다. 이 수업은 "어떤 질문이 좋은 질문인가"를 지니 불순도와 정보 이득으로 직접 계산하고, 트리가 과적합하는 이유와 깊이 제한 · 가지치기로 막는 법을 실행 결과로 봅니다.

항목내용
참고 자료scikit-learn 사용자 안내서 '1.10 Decision Trees' · scikit-learn.org/stable/modules/tree.html
트랙 · 수준머신러닝 · 기초
이 수업의 범위분할 규칙, 지니 불순도, 엔트로피와 정보 이득, 가중 불순도, 회귀 트리(분산 감소), 탐욕적 성장, 과적합, max_depth · min_samples_leaf, 비용-복잡도 가지치기, 특성 중요도, 장단점
먼저 알면 좋은 것비율 계산, 엔트로피(log⁡2\log_2), 분산, 과적합과 검증

들어가기 전에

한눈에 보기

  • 트리가 질문(분할)을 고르는 기준 — "나눈 뒤 각 쪽이 얼마나 한 클래스로 순수해졌나" — 을 압니다.
  • 지니 불순도와 엔트로피로 두 후보 분할을 직접 비교해 어느 쪽이 좋은지 계산합니다.
  • 회귀 트리가 분산을 가장 많이 줄이는 지점을 찾는 과정을 숫자 6개로 따라갑니다.
  • 깊이를 키울수록 학습 정확도는 1로 가지만 테스트 정확도는 그렇지 않음을 실행 결과로 봅니다.
  • max_depth · min_samples_leaf · ccp_alpha로 트리를 다스리는 법과 트리의 장단점을 정리합니다.

1. 질문으로 나누기

직관(해설용 비유): 스무고개와 같습니다. 좋은 첫 질문은 후보를 반쯤으로 확 줄여 주는 질문입니다. 결정 트리는 매 단계에서 "어떤 특성을 어떤 값에서 자르면 양쪽이 가장 깔끔하게 나뉘는가"를 모든 후보에 대해 계산하고 가장 좋은 것을 고릅니다.

단계(분류 트리)

  1. 현재 노드의 데이터에 대해, 모든 특성 jj와 가능한 임곗값 tt를 후보로 둡니다(xj≤tx_j \le t면 왼쪽, 아니면 오른쪽).
  2. 후보마다 나눈 뒤의 가중 불순도를 계산합니다.
  3. 가중 불순도가 가장 작은(불순도 감소가 가장 큰) 후보로 나눕니다.
  4. 자식 노드마다 1~3을 반복하다가, 노드가 순수해지거나 멈춤 조건(깊이, 최소 표본 수)에 걸리면 잎(leaf)으로 둡니다.
  5. 잎의 예측은 그 안 데이터의 다수 클래스(회귀면 평균)입니다.

scikit-learn은 CART 알고리즘을 최적화한 버전을 쓰며, 항상 둘로 나누는 이진 트리를 만듭니다. 각 단계에서 지금 가장 좋은 분할만 고르는 탐욕적(greedy) 방법이라, 트리 전체로 최적이라는 보장은 없습니다.

2. 불순도: 지니와 엔트로피

노드 mm에서 클래스 kk의 비율을 pmkp_{mk}라고 할 때, scikit-learn 문서의 두 기준은 다음과 같습니다.

지니: H(Qm)=∑kpmk(1−pmk)=1−∑kpmk2,엔트로피: H(Qm)=−∑kpmklog⁡pmk\text{지니: } H(Q_m) = \sum_k p_{mk}(1 - p_{mk}) = 1 - \sum_k p_{mk}^2,\qquad \text{엔트로피: } H(Q_m) = -\sum_k p_{mk}\log p_{mk}
G(Qm,θ)=nmleftnmH(Qmleft)+nmrightnmH(Qmright),불순도 감소=H(Qm)−G(Qm,θ)G(Q_m, \theta) = \frac{n_m^{\text{left}}}{n_m}H(Q_m^{\text{left}}) + \frac{n_m^{\text{right}}}{n_m}H(Q_m^{\text{right}}),\qquad \text{불순도 감소} = H(Q_m) - G(Q_m, \theta)
기호뜻
QmQ_m노드 mm에 들어온 데이터
pmkp_{mk}그 안에서 클래스 kk의 비율
θ=(j,t)\theta = (j, t)분할 후보: 특성 jj를 임곗값 tt로 자름
nmleft,nmrightn_m^{\text{left}}, n_m^{\text{right}}왼쪽 · 오른쪽으로 간 개수
GG자식 불순도를 개수 비율로 가중 평균한 값 — 작을수록 좋은 분할

지니의 뜻: 노드에서 무작위로 두 개를 뽑았을 때(복원 추출) 클래스가 서로 다를 확률입니다. 순수하면 0, 두 클래스가 반반이면 0.5입니다. 엔트로피는 클래스를 알아내는 데 필요한 평균 비트 수로, 반반이면 1비트입니다. 엔트로피로 잰 불순도 감소를 정보 이득(information gain)이라고 부릅니다. scikit-learn 기본값은 criterion='gini'입니다.

3. 숫자로 해 보기: 두 분할 비교(해설용)

예제 10개, 구매 5 · 비구매 5에서 시작합니다. 뿌리 노드의 지니 =1−(0.52+0.52)=0.5= 1 - (0.5^2 + 0.5^2) = 0.5, 엔트로피 =1= 1비트입니다.

분할 A — 왼쪽 5개(구매 4, 비구매 1), 오른쪽 5개(구매 1, 비구매 4)

  • 각 자식 지니 =1−(0.82+0.22)=1−0.68=0.32= 1 - (0.8^2 + 0.2^2) = 1 - 0.68 = 0.32
  • 가중 지니 =0.5×0.32+0.5×0.32=0.32= 0.5 \times 0.32 + 0.5 \times 0.32 = 0.32 → 감소 0.18
  • 각 자식 엔트로피 =−0.8log⁡20.8−0.2log⁡20.2≈0.722= -0.8\log_2 0.8 - 0.2\log_2 0.2 \approx 0.722 → 정보 이득 ≈\approx 0.278

분할 B — 왼쪽 3개(구매 3, 비구매 0), 오른쪽 7개(구매 2, 비구매 5)

  • 왼쪽은 순수: 지니 0, 엔트로피 0
  • 오른쪽 지니 =1−((2/7)2+(5/7)2)=20/49≈0.408= 1 - ((2/7)^2 + (5/7)^2) = 20/49 \approx 0.408
  • 가중 지니 =0.3×0+0.7×0.408≈0.286= 0.3 \times 0 + 0.7 \times 0.408 \approx 0.286 → 감소 0.214
  • 오른쪽 엔트로피 ≈0.863\approx 0.863, 가중 ≈0.604\approx 0.604 → 정보 이득 ≈\approx 0.396

두 기준 모두 B를 고릅니다. 한쪽을 완전히 순수하게 만든 분할이 점수가 더 좋았습니다. 지니와 엔트로피는 대부분의 경우 비슷한 분할을 고르며, 지니는 로그 계산이 없어 조금 빠릅니다. (위 숫자는 python으로 다시 계산해 확인했습니다.)

4. 회귀 트리: 분산을 줄이는 자리 찾기

정답이 실수이면 불순도로 분산(평균제곱오차)을 씁니다. 잎의 예측은 그 안의 평균입니다.

yˉm=1nm∑y∈Qmy,H(Qm)=1nm∑y∈Qm(y−yˉm)2\bar y_m = \frac{1}{n_m}\sum_{y \in Q_m} y,\qquad H(Q_m) = \frac{1}{n_m}\sum_{y \in Q_m}(y - \bar y_m)^2

숫자로 해 보기(해설용): x=1,2,3,4,5,6x = 1, 2, 3, 4, 5, 6, y=5,6,5,20,21,22y = 5, 6, 5, 20, 21, 22. 뿌리 분산은 약 61.8입니다.

임곗값 tt왼쪽 평균오른쪽 평균가중 분산
1.55.014.848.47
2.55.517.032.42
3.55.3321.00.44
4.59.021.527.08
5.511.422.046.2

t=3.5t = 3.5에서 가중 분산이 0.44로 가장 작습니다. 트리는 "x≤3.5x \le 3.5면 5.33, 아니면 21.0"이라는 계단 모양 예측을 만듭니다. 회귀 트리의 예측은 언제나 이런 계단 함수라서, 학습 범위 밖(x=10x = 10)에서도 마지막 계단 값(21.0)만 냅니다 — 추세를 외삽하지 못한다는 뜻입니다.

mermaid
flowchart TB
  R[뿌리: 전체 데이터] --> Q1{모든 특성 · 임곗값 후보에서 불순도 감소 계산}
  Q1 --> S[가장 좋은 분할 x_j ≤ t 선택]
  S --> L[왼쪽 자식]
  S --> Ri[오른쪽 자식]
  L --> C{멈춤 조건? 순수 · max_depth · min_samples_leaf}
  Ri --> C
  C -- 아니오 --> Q1
  C -- 예 --> Leaf[잎: 다수 클래스 또는 평균으로 예측]
  Leaf --> P[필요하면 비용-복잡도 가지치기]

5. 과적합과 트리 다스리기

직관: 멈춤 조건이 없으면 트리는 잎마다 예제가 하나씩 남을 때까지 질문을 계속해 학습 데이터를 통째로 외웁니다. 잡음까지 규칙으로 만들어 버리는 것입니다.

실행해 보기: scikit-learn 내장 유방암 진단 데이터(569개, 특성 30개)를 학습 70% · 테스트 30%로 나눠(시드 0, 클래스 비율을 맞춘 층화 분할 stratify=y, 트리도 random_state=0) 깊이를 바꿔 봤습니다.

max_depth잎 수학습 정확도테스트 정확도
120.9320.889
240.9420.906
380.9800.901
5150.9970.912
제한 없음(실제 깊이 6)161.0000.906

학습 정확도는 깊이와 함께 1.0까지 오르지만, 테스트 정확도는 0.89~0.91 사이에서 거의 늘지 않습니다. 학습 정확도가 1이라는 사실은 아무것도 보장하지 않습니다. (Python 3.14 · scikit-learn 1.9.0 실행 결과. 데이터 분할이 바뀌면 숫자도 바뀝니다.)

주요 손잡이(scikit-learn 기본값)

하이퍼파라미터기본값역할
max_depthNone(제한 없음)최대 깊이. 문서는 3부터 시작해 늘려 보라고 권함
min_samples_leaf1잎의 최소 표본 수. 문서는 5를 첫 시도값으로 제안(회귀)
min_samples_split2나누기 위한 최소 표본 수
ccp_alpha0.0비용-복잡도 가지치기 세기
criteriongini(분류) · squared_error(회귀)불순도 기준

6. 비용-복잡도 가지치기

직관: 먼저 크게 키운 뒤, "잎을 하나 줄일 때 늘어나는 오류가 작은" 가지부터 잘라 냅니다. 잎 하나당 벌금 α\alpha를 매기는 셈입니다. scikit-learn 문서의 식은 다음과 같습니다.

Rα(T)=R(T)+α ∣T~∣,αeff(t)=R(t)−R(Tt)∣Tt∣−1R_\alpha(T) = R(T) + \alpha\,|\widetilde T|,\qquad \alpha_{\text{eff}}(t) = \frac{R(t) - R(T_t)}{|T_t| - 1}
기호뜻
R(T)R(T)트리 TT의 잎들의 (표본 가중) 불순도 합
∣T~∣\lvert\widetilde T\rvert잎의 개수
α\alpha잎 하나당 벌금(ccp_alpha)
αeff(t)\alpha_{\text{eff}}(t)노드 tt 아래 가지를 잘라 tt를 잎으로 만들 때의 "가성비" — 가장 작은 것(가장 약한 고리)부터 자름

실행 결과(같은 데이터): ccp_alpha 0.0 → 잎 16개, 테스트 0.906 / 0.005 → 잎 7개, 0.918 / 0.01 → 잎 5개, 0.918 / 0.02 → 잎 4개, 0.901. 잎을 16개에서 5개로 줄여도 테스트 성능은 오히려 조금 올랐습니다. 적당한 α\alpha는 cost_complexity_pruning_path로 후보를 뽑아 교차 검증으로 고릅니다.

역사 메모: CART는 Breiman · Friedman · Olshen · Stone의 책 Classification and Regression Trees(1984)에서 정리된 방법이며, "크게 키운 뒤 가지치기"가 그 핵심 아이디어 중 하나입니다.

7. 트리의 장단점

장점단점
규칙을 사람이 읽을 수 있음(export_text)과적합하기 쉬움
스케일링 거의 불필요(임곗값 비교라 단조 변환에 무관)데이터가 조금 바뀌어도 트리 모양이 크게 바뀜(불안정)
숫자 · 범주 섞인 표 데이터에 강함경계가 축에 평행한 계단 모양
예측이 빠름(깊이만큼 비교)외삽 불가, 매끄러운 함수 근사가 서툼

특성 중요도: 학습된 트리의 feature_importances_는 각 특성이 분할에서 줄인 불순도의 합(정규화)입니다. 어떤 특성이 많이 쓰였는지 빠르게 보는 데 좋지만, 값의 종류가 많은 특성을 과대평가하는 경향이 있어 해석에 주의합니다.

불안정성의 해법: scikit-learn 문서도 트리의 불안정성은 트리를 여러 개 묶은 앙상블로 누그러뜨린다고 적습니다. 다음 수업의 랜덤 포레스트와 그래디언트 부스팅이 바로 그것입니다.

연습 문제

1. 노드에 클래스 3개가 각 1/3씩 있습니다. 지니와 엔트로피는?

풀이: 지니 =1−3×(1/3)2=2/3≈0.667= 1 - 3 \times (1/3)^2 = 2/3 \approx 0.667. 엔트로피 =log⁡23≈1.585= \log_2 3 \approx 1.585비트.

2. 예제 8개(양성 4 · 음성 4)를 왼쪽 (양성 4, 음성 0) · 오른쪽 (양성 0, 음성 4)로 나누면 지니 감소는?

풀이: 두 자식 모두 순수(지니 0)라 가중 지니 0, 감소 =0.5−0=0.5= 0.5 - 0 = 0.5로 가능한 최대입니다.

3. 4절 데이터에서 x=10x = 10의 예측값은?

풀이: x>3.5x > 3.5이므로 오른쪽 잎의 평균 21.0입니다. 트리는 학습 범위 밖으로 추세를 늘려 가지 못합니다.

4. 학습 정확도 1.0, 테스트 0.80인 트리를 개선하려면?

풀이: max_depth를 줄이거나, min_samples_leaf를 늘리거나, ccp_alpha로 가지치기하고 교차 검증으로 값을 고릅니다. 그래도 부족하면 랜덤 포레스트 같은 앙상블로 넘어갑니다.

스스로 점검

  1. 트리가 분할을 고를 때 최소화하는 값은 무엇인가요?
    • 답: 자식 노드 불순도를 개수 비율로 가중 평균한 값 G(Qm,θ)G(Q_m, \theta)입니다. 같은 말로, 불순도 감소(정보 이득)를 최대화합니다.
  2. 결정 트리에 표준화가 필요 없는 이유는?
    • 답: 분할이 "한 특성 ≤ 임곗값" 비교라서, 크기를 늘리거나 줄이는 단조 변환을 해도 양쪽으로 가는 예제가 바뀌지 않기 때문입니다.
  3. 회귀 트리가 외삽을 못 하는 이유는?
    • 답: 예측이 각 잎에 들어온 학습 데이터 평균인 계단 함수라서, 학습 범위 밖에서는 가장자리 잎의 값만 내기 때문입니다.

용어 정리

용어쉬운 뜻
결정 트리(decision tree)예/아니오 질문을 차례로 던져 예측하는 모델
노드 · 잎(node · leaf)질문하는 자리 · 더 나누지 않고 답을 내는 끝자리
분할(split)한 특성을 임곗값으로 둘로 나누는 것
지니 불순도(Gini impurity)두 개를 뽑았을 때 클래스가 다를 확률
엔트로피(entropy)클래스를 알아내는 데 필요한 평균 비트 수
정보 이득(information gain)분할로 줄어든 엔트로피
탐욕적 방법(greedy)매 단계 지금 가장 좋은 선택만 하는 방법
CART이진 분할로 분류 · 회귀 트리를 만드는 대표 알고리즘
가지치기(pruning)키운 트리에서 쓸모 적은 가지를 잘라 내기
비용-복잡도 가지치기(cost-complexity pruning)잎 하나당 벌금 α를 매겨 자르는 방법
특성 중요도(feature importance)특성이 줄인 불순도의 합

더 깊이 보려면

scikit-learn '1.10 Decision Trees'는 다중 출력 트리, 결측값 지원, 시간 복잡도, 실무 팁(데이터가 많고 특성이 많을 때의 요령)까지 정리합니다. 문서의 '최소 비용-복잡도 가지치기' 절은 αeff\alpha_{\text{eff}}를 따라 잎을 줄여 가는 과정을 예제로 보여 줍니다.

다음에 볼 것

라이선스

이 글은 원문 번역이 아니라 KAITABASE가 직접 쓴 해설이며, 숫자 예와 실행 결과는 설명용입니다(python · scikit-learn으로 직접 계산 · 실행). 참고 자료 scikit-learn 문서는 BSD-3-Clause 라이선스입니다.

출처

  • 참고: https://scikit-learn.org/stable/modules/tree.html (지니 · 엔트로피 · 회귀 기준 식, 분할 품질 G, 비용-복잡도 가지치기 식, CART, 과적합 대책 권고)
  • Breiman, L., Friedman, J., Olshen, R., Stone, C. (1984). Classification and Regression Trees. Wadsworth.

AI 원리부터 이해하기 · 머신러닝 모듈

머신러닝 모듈 학습

이 글은 머신러닝 모듈의 학습 자료입니다. 전체 17개 자료 중 7번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 scikit-learn 사용자 안내서(BSD-3)