ML

[ML] 결정트리

tenacy 2024. 7. 19. 08:03

앞 장에서는 SVM에 대해 알아봤습니다. 이는 분류와 회귀, 다중 출력까지도 작업이 가능한 알고리즘이었습니다. 이 장에서 배울 결정 트리도 이와 동일한 작업을 수행하며, 복잡한 데이터셋도 학습할 수 있는 특징이 있습니다.

결정 트리 학습과 시각화

결정 트리가 어떻게 예측을 수행하는 모델을 만들어 알아보겠습니다.

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

iris = load_iris()
X = iris.data[:, 2:]
y = iris.target

tree_clf = DecisionTreeClassifier(max_depth=2)
tree_clf.fit(X, y)

이를 시각화하면 다음과 같습니다.

예측하기

어떻게 위 그림과 같은 예측을 만들어낼 수 있을까요? 최상단에 있는 노드를 루트 노드라 하며, 최하단에 있는 즉, 자식을 가지고 있지 않은 노드를 리프 노드라고 합니다. 새로운 붓꽃의 품종을 분류하려 할 때 루트 노드부터 검사합니다. 그 다음 결과에 맞는 자식 노드로 이동하며 이를 리프 노드로 이동할 때까지 반복합니다. 리프 노드로 이동했다면 해당 노드의 예측 클래스를 보고 결정 트리가 새로 발견한 꽃의 품종을 예측합니다.

결정 트리의 여러 장점 중 하나는 데이터 전처리가 거의 필요하지 않다는 것입니다. 사실 특성의 스케일을 맞추거나 평균을 원점에 맞추는 작업이 필요하지 않습니다.


Q. 왜 결정 트리는 데이터 전처리가 필요없을까?

A. 결정 트리는 바로 다음에 나오는 불순도를 기반으로 하고 있으며, 이 정보만 신경 쓰면 되기 때문에 특별한 경우를 제외하고는 전처리 작업이 필요 없다.


노드의 각 속성이 의미하는 바는 다음과 같습니다.

  • sample
    • 적용 훈련 샘플 수
    • 예를 들어, (깊이 1, 오른쪽) 노드의 sample과 직계 자식 노드들((깊이 2, 왼쪽), (깊이 2, 오른쪽))의 sample 합(54 + 46)은 같습니다.
  • value
    • 노드에서 각 클래스에 얼마나 많은 훈련 샘플이 있는지
  • gini
    • 불순도
    • 한 노드의 모든 샘플이 같은 클래스에 속해 있다면 이 노드를 순수(gini = 0)하다고 합니다.

위 그림은 결정 트리의 결정 경계를 보여줍니다. 굵은 수직선이 루트 노드의 결정 경계를 나타냅니다. 왼쪽 영역은 순수 노드이기 때문에 더 이상 나눌 수 없습니다. 하지만 오른쪽 영역은 순수 노드가 아니므로 깊이 1의 오른쪽 노드는 꽃잎 너비 1.75cm에서 나누어집니다. max_depth를 2로 설정했기 때문에 더 분할되지 않습니다.

클래스 확률 추정

결정 트리는 한 샘플이 특정 클래스 $k$에 속할 확률을 추정할 수도 있습니다. 먼저 이 샘플에 대해 리프 노드를 찾기 위해 트리를 탐색하고 그 노드에 있는 클래스 $k$의 훈련 샘플의 비율을 반환합니다.

print(tree_clf.predict_proba([[5, 1.5]]))
print(tree_clf.predict([[5, 1.5]]))

CART 훈련 알고리즘

사이킷런은 결정 트리를 훈련시키기 위해 CART(Classification And Regression Tree) 알고리즘을 사용합니다. 먼저 훈련 세트를 하나의 특성 $k$의 임곗값 $t_k$를 사용해 두 개의 서브셋으로 나눕니다. 어떻가 $k$와 $t_k$를 고를까요? 가장 순수한 서브셋으로 나눌 수 있는 $(k, t_k)$ 짝을 찾습니다.

CART 알고리즘이 훈련 세트를 성공적으로 둘로 나누었다면 같은 방식으로 서브셋을 또 나누고 그 다음엔 서브셋의 서브셋을 나누고 이런 식으로 계속 반복합니다. 이 과정은 최대 깊이(max_depth)가 되면 중지하거나 불순도를 줄이는 분할을 찾을 수 없을 때 멈추게 됩니다. max_depth 외 다른 몇 개의 매개변수도 중지 조건에 관여합니다.