머신러닝 분야를 가장 앞서가고 있는 앙상블이라는 기법인데 이는 여러 모델한테 물어봐서 좋은 결과를 나타내는 기법입니다.
이때 앙상블에 사용될 수 있는 가장 좋은 모델 중 하나가 Decision Trees입니다.
결정 트리는 다음과 같은 특징들이 있습니다.
- (현재) 가장 강력한 ML 알고리즘 중 하나
- 분류, 회귀, 다중 출력 작업 등 많은 분야에서 활용되는 다재다능한 알고리즘
- 매우 복잡한 데이터셋도 학습 가능
- 랜덤 포레스트의 리본 구성 요소: Decision Trees가 엄청나게 많이 있는 앙상블 모델이 랜덤 포레스트(random forest)
- 알고리즘이 매우 직관적이고 결정 방식을 이해하기 쉽습니다.
직관적인 이유는 위에 그림을 보고 이해할 수 있습니다. 테니스를 치고 싶을 상황일 경우 결정하기 위한 조건을 트리로 만들어 결정합니다.
아래 코드는 붓꽃 데이터셋에 DecisionTreeClassifier를 훈련시키는 코드입니다. X 데이터는 꽃잎의 길이와 너비를 의미하며 y은 정답 레이블을 의미합니다. 다음으로는 DecisionTreeClassifier 결정 트리 분류기를 가지고 객체를 만드는데 max_depth를 사용하며 이는 결정 트리 깊이를 설정하는 파라미터입니다.
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)
트리를 시각화하는 export_graphviz를 사용하여 위에서 학습을 마친 결정 트리 분류기를 나타낼 수 있습니다.
from sklearn-tree import export_graphviz
export _graphviz(
tree_clf,
out_file-image_path("iris_tree.dot"),
feature_names-iris.feature_names[2:],
class_names=iris.target_names,
rounded=True,
filled-True
)
$ conda install python-graphviz
$ dot -Tpng iris_tree.dot -o iris_tree.png
최 상단에 있는 노드는 루트 노드로 꽃잎의 길이가 2.45보다 작거나 같을 경우 True이므로 내려가면 리프 노드가 존재하고 2.45보다 클 경우에는 False로 내려가서 자식 노드를 만나게됩니다, 자식 노드를 만나게 되면 추가적인 검사를 하게 됩니다. 즉 노드를 타고 조건에 맞는 끝까지 내려가게 되었을때에 해당하는 class를 정답으로 인식하게 됩니다. 중요한 점은 위에서 max_depth를 2로 설정했기 때문에 2층까지 존재합니다.
- 결정 트리의 장점 중 하나는 데이터 전처리가 거의 필요 없습니다
- 특히 특성 스케일을 맞추거나 평균을 원점에 맞추는 작업이 필요 없습니다.
예측하기
결정 트리에서 samples 속성은 얼마나 많은 훈련 샘플이 적용되었는지 헤아린 것입니다.
노드의 value 속성은 노드에서 각 클래스에 얼마나 많은 훈련 샘플이 있는지 알려줍니다.
마지막으로 노드의 gini 속성은 불순도를 측정합니다. 한 노드의 모든 샘플이 같은 클래스에 속해 있다면 이 노드를 순수(gini=0)하다고 합니다.
좌측 초록색 노드의 불순도를 구한 값이며 불순도는 낮을수록 좋습니다.
사이킷런은 이진 트리만 만드는 CART 알고리즘을 사용합니다. 그러므로 리프 노드 외의 모든 노드는 자식 노드를 두 개씩 가집니다(즉, 질문의 답은 '예' 또는 '아니오'입니다). 하지만 ID3 같은 알고리즘은 둘 이상의 자식 노드를 가진 결정 트리를 만들 수 있습니다.
결정 트리의 결정 경계
아래의 그림은 위에 결정 트리의 결정 경계를 보여줍니다. 굵은 수직선이 루트 노드(깊이 0)의 결정 경계(꽃잎 길이=2.45cm)를 나타냅니다. 왼쪽 영역은 순수 노드(Iris-Setosa만 있음)이기 때문에 더는 나눌 수 없습니다. 하지만 오른쪽 영역은 순수 노드가 아니므로 깊이 1의 오른쪽 노드는 꽃잎 너비=1.75cm에서 나누어집니다(파선). max_depth를 3으로 하면 깊이 2의 두 노드가 각각 결정 경계를 추가로 만듭니다(점선). 결정 트리 연산자에서 파라미터 max_depth를 0, 1, 2로 설정할때마다 아래처럼 계속 나뉘는 것을 확인할 수 있습니다.
화이트박스 모델 = 매우 직관적이고 간단하며 이해하기 쉬운 결정 방식을 사용하며 필요하면 손으로 따라해 볼수도 있습니다.
> 결정 트리는 직관적이고 결정 방식을 이애하기 쉽기 떄문에 화이트박스 모델이라고 합니다.
블랙박스 모델 = 성능이 뛰어나고 예측을 만드는 연산 과정을 쉽게 확인이 가능하나 왜 그런 예측을 만드는지 쉽게 설명하기 어려움
> 랜덤 포레스트나 신경망은 블랙박스 모델입니다.
> 블랙박스 모델은 성능이 뛰어나고 예측을 만드는 연산 과정을 쉽게 확인할 수 있지만 예측을 왜 그렇게 만드는지는 설명하기 어렵습니다.
클래스 확률 추정
결정 트리는 한 샘플이 특정 클래스 k에 속할 확률을 추정할 수도 있습니다. 먼저 이 샘플에 대해 리프 노드를 찾기 위해 트리를 탐색하고 그 노드에 있는 클래스 k의 훈련 샘플의 비율을 반환합니다. 예를 들어 길이가 5cm이고 너비가 1.5cm인 꽃잎을 발견했다고 가정합니다. 이에 해당하는 리프 노드는 깊이 2에서 왼쪽 노드이므로 결정 트리는 그에 해당하는 확률을 출력합니다. 즉, Iris-Setosa는 0%(0/54), Iris-Versicolor는 90.7%(49/54), Iris-Versicolor는 9.3%(5/54)입니다. 만약 클래스를 하나 예측한다면 가장 높은 확률을 가진 Iris-Versicolor(클래스 1)를 출력할 것입니다.
지니 불순도 또는 엔트로피
기본적으로 지니 불순도가 사용되지만 criterion 매개변수를 "entropy"로 지정하여 엔트로피 불순도를 사용할 수 있습니다. 엔트로피는 분자의 무질서함을 측정하는 것으로 원래 열역학의 개념입니다. 분자가 안정되고 질서 정연하면 엔트로피가 0에 가깝습니다. 이런 엔트로피는 정보 이론에도 포함되어 모든 메시지가 동일할 때 엔트로피가 0이 됩니다. 머신러닝에서는 불순도의 측정 방법으로 자주 사용됩니다. 예를 들어 어떤 세트가 한 클래스의 샘플만 담고 있다면 엔트로피가 0입니다.
위에 엔트로피 공식을 사용하여 결정 트리에서 깊이 2의 왼쪽 노드의 엔트로피는 다음과 같음을 확인할 수 있습니다.
규제 하이퍼파라미터
결정 트리는 훈련 데이터에 대한 제약 사항이 거의 없습니다. 제한을 두기 않으면 트리가 훈련 데이터에 아주 가깝게 맞추려고 합니다 (이는 오버피팅 되기 쉽습니다). 결정 트리는 모델 파라미터가 전혀 없는 것이 아니라 훈련되기 전에 파라미터 수가 결정되지 않기 때문에 이런 모델을 '비파라미터 모델'이라 부릅니다, 따라서 모델 구조가 자유로이 데이터의 구조에 맞춰질 수 있습니다. 반대로 선형 모델과 같은 '파라미터 모델'은 미리 정의된 모델 파라미터 수를 가집니다, 이는 자유도가 제한되고 오버피팅 위험은 줄어들지만 언더피팅 위험은 커지는 특징이 있습니다.
위와 같은 이유로 모델 파라미터를 미리 정의하지 않으면 오버 피팅되기 쉽기 때문에 결정 트리의 규제가 필요합니다.
규제 하이퍼파라미터는 사용하는 알고리즘에 따라 다르지만 보통 적어도 결정 트리의 최대 깊이는 제어할 수 있습니다. sklearn에서는 max_depth 매개변수로 이를 조절합니다(기본값은 제한이 없는 것을 의미하는 None입니다). max_depth를 줄이면 모델을 규제하게 되고 과대적합의 위험이 감소합니다.
규제를 통해 결정 트리의 형태를 제한하는 예시입니다. min_samples_leaf를 4로 설정하여 리프 노드가 가지고 있어야할 최소 샘플 수를 정한것 입니다. 왼쪽 모델은 과대적합 되었고 오른쪽 모델은 일반화 성능이 더 좋을 것 같아 보입니다.
결정 트리 회귀
결정 트리는 회귀 문제에도 사용할 수 있습니다. sklearn의 DecisionTreeRegressor를 사용해 잡음이 섞인 2차 함수 형태의 데이터셋에서 max_depth=2 설정으로 회귀 트리를 만들어보는 코드입니다.
from sklearn.tree import DecisionTreeRegresor
tree_reg = DecisionTreeRegresor(max_depth=2)
tree_reg.fit(X, y)
앞에 있었던 분류 트리와 매우 비슷한 회귀 결정 트리가 만들어집니다. 주요한 차이는 각 노드에서 클래스를 예측하는 대신 어떤 값을 예측한다는 점입니다. 예를 들어 x1=0.6인 샘플의 타깃값을 예측한다고 가정해봤을때 루트 노드부터 시작하여 트리를 순회하면 결국 value=0.111인 리프 노드에 도달하게 됩니다. 이 리프 노드에 있는 110개 훈련 샘플의 평균 타깃값이 예측값이. 됩니다. 이 예측값을 사용해 110개 샘플에 대한 평균제곱오차(MSE)를 계산하면 0.015가 됩니다.
위 모델의 예측은 아래 왼쪽에 나타나 있습니다. max_depth=3으로 설정하면 오른쪽 그래프와 같은 예측을 얻게 됩니다. 각 영역의 예측값은 항상 그 영역에 있는 타깃값의 평균이 됩니다. 알고리즘은 예측값과 가능한 한 많은 샘플이 가까이 있도록 영역을 분할합니다.
CART 알고리즘은 훈련셋을 불순도를 최소화하는 방향으로 분할하는 대신 평균제곱오차(MSE)를 최소화하도록 분할하는 것을 제외하고는 앞에 내용과 비슷합니다. 다음은 알고리즘이 최소화하기 위한 비용 함수입니다.
분류에서와 같이 회귀 작업에서도 결정 트리는 오버피팅되기 쉽습니다. 예를 들어 아래처럼 min_samples_leaf=10으로 지정하면 오른쪽 그래프처럼 훨씬 그럴싸한 모델을 만들어줍니다.
오른쪽은 제한 없이 학습된 결정 트리로 명백하게 훈련셋에 오버피팅된 것을 확인할 수 있으며
왼쪽은 모델에 규제를 함으로서 훨씬 '납득할 만한' 모델을 생성한 것을 확인할 수 있습니다.
불안정성
결정 트리 불안정성
결정 트리는 이해하고 해석하기 쉬우며, 사용하기 편하고, 여러 용도로 사용할 수 있으며, 성능도 뛰어납니다. 하지만 몇 가지 제한 사항이 있습니다. 결정 트리는 계단 모양의 결정 경계를 만듭니다. 그래서 훈련셋의 회전에 민감합니다. 아래 그림은 간단한 선형으로 구분될 수 있는 데이터셋을 예로 보여줍니다. 왼쪽의 결정 트리는 쉽게 데이터셋을 구분하지만, 데이터셋을 45도 회전한 오른쪽의 결정 트리는 불필요하게 구불구불해졌습니다. 두 결정 트리 모두 훈련셋을 완벽하게 학습하지만 오른쪽 모델은 잘 일반화되어 있지 않습니다. 이런 문제를 해결하는 한 가지 방법은 훈련 데이터를 더 좋은 방향으로 회전시키는 PCA 기법을 사용하는 것입니다.
결정 트리의 주된 문제는 훈련 데이터에 있는 작은 변화에도 매우 민감하다는 것입니다. 예를 들어 훈련셋에서 가장 넓은 Iris-Versicolor(꽃잎 길이가 4.8cm이고 너비가 1.8cm인 것)를 제거하고 결정 트리를 훈련시키면 아래 그림과 같은 모델을 얻게 됩니다. 이전에 만든 결정 트리와는 매우 다른 모습입니다. 사실 sklearn에서 사용하는 훈련 알고리즘은 (random_state 매개변수를 지정하지 않으면)확률적이기 때문에 같은 훈련 데이터에서도 다른 모델을 얻을 수 있습니다.
'AI > Machine Learning' 카테고리의 다른 글
머신러닝 - 서포트 백터 머신 (0) | 2024.08.19 |
---|---|
머신러닝 - 모델 훈련, 선형회귀, 경사하강법 (0) | 2024.08.14 |
머신러닝 - 로지스틱 회귀 (0) | 2024.08.14 |
사이킷런 scikit-learn 이란? (0) | 2024.07.09 |
여러 개의 레이블을 갖는 하나의 데이터 분류하기 - 다중 레이블 분류 (2) | 2024.07.08 |