민프
[AI | ML] [분류기] Decision Tree (결정 트리)에 대해서 알아보자 본문
이번 포스팅에서는 분류기 중 Decision Tree(결정 트리)에 대해서 알아보겠습니다.
1. Decision Tree란?
결정 트리(decision tree)는 의사 결정 규칙과 그 결과들을 트리 구조로 도식화한 의사 결정 지원 도구의 일종이다. 결정 트리는 운용 과학, 그 중에서도 의사 결정 분석에서 목표에 가장 가까운 결과를 낼 수 있는 전략을 찾기 위해 주로 사용된다
- 위키백과-
https://ko.wikipedia.org/wiki/%EA%B2%B0%EC%A0%95_%ED%8A%B8%EB%A6%AC
위키백과에 따르면 의사 결정 규칙에 대한 결과들을 트리 구조로 도식화 한 의사 결정 지원의 도구라고 하는데요
과연 이게 무슨 말 일까요?
이해를 돕기 위해 아래 시험 합격에 대한 합격/불합격에 대한 Decision Tree를 도식화 한 것 인데 이것을 보면서 말씀드리겠습니다.
결정 트리(Decision Tree)는 분류와 회귀 문제에 널리 사용하는 모델입니다.
기본적으로 결정 트리는 결정에 다다르기 위해 예/아니오 질문을 이어 나가면서 학습합니다.
여기에서의 목표는 YES/NO 질문으로 문제를 해결하는 것 입니다.
1-1. Decision Tree의 Node 및 변수 (독립/종속)
결정 트리 에서는 3가지 노드로 구성되어 있는데 Root Node, Intermediate Node 그리고 Terminal Node(Neaf Node)는 트리 구조에서 각각 중요한 역할을 합니다.
1. Root Node (루트 노드)
-> 결정 트리의 첫 번째 노드로, 데이터를 가장 처음으로 나누는 기준이 되는 질문이 있는 노드입니다.
2. Intermediate Node (중간 노드)
-> 루트 노드와 리프 노드 사이에 위치한 노드로, 중간 단계에서 데이터를 추가로 나누는 역할을 합니다. 따라서 Intermediate Node는 여러 개가 있을 수 있습니다.
3. Terminal Node (Leaf Node/리프 노드)
-> 결정 트리의 끝에 있는 노드로 더 이상 나누지 않고 최종적인 분류 결과를 나타내는 노드 입니다. 이 노드는 우리가 예측하고자 하는 최종 결과가 담겨 있습니다.
자 여기에서 Decision Tree를 만들려면 트리의 각 분할 단계에서 데이터를 분류할 때 기준이 되는 독립 변수(Independent Variables)가 있고, 독립 변수들의 조합에 따라 결정되는 결과로 Decision Tree의 Leaf Node에서 나타나는 최종 출력 값 입니다.
결론적으로 위 도표에서 아래와 같이 구성된다고 생각하시면 됩니다.
- 독립 변수 : Root Node, Intermediate Node
- 종속 변수 : Terminal Node(Leaf Node)
1-2. Impurity(불순도), Entropy, Gini Index(지니 인덱스)
Decision Tree는 각 영역의 순도(homogeneity)의 증가, 불순도(impurity)혹은 불확실성(uncertainty)이 최대한 감소하도록 하는 방향으로 학습을 진행합니다.
여기에서 불순도(Impurity)는 해당 범주 안에 서로 다른 데이터가 얼마나 섞여있는지를 말합니다. 즉 얼마나 다른 카테고리와 섞여있는지 입니다.
이렇게 순도가 증가/불확실성이 감소하는 것과 어떤 기준으로 데이터를 분할했을 때, 그 분할로 인해 얼마나 불확실성이 줄었는지를 측정하는 것이 정보이론에서는 정보획득(information gain)이라고 하는데요.
즉, Information Gain이 높을수록 성능이 좋은 것이고, 낮을수록 성능이 좋지 못한 것 입니다.
근데 또 여기에서 Information Gain한계점은 무작정 분할을 더 잘게 많이 할수록 Information gain의 값은 더 커지기 때문에 Information gain 값도 고려해서 개발을 한다면 더 좋은 성능의 Decision Tree를 만들 수 있을 것 입니다.
여기까지 정리를 해보자면
1. Decision Tree는 데이터를 이용하여 Tree구조를 만들고, 분류하거나 결과값을 예측하는 분석 방법을 말한다.
2. Decision Tree를 만들때에는 각 node들의 복잡성 즉, impurity가 가장 낮은 방향으로 tree가 만들어진다.
3. impurity 지표들을 바탕으로 node들의 복잡성을 계산하는 방법이 대표적으로 Entropy, Gini Index 등..) 이 있다.
4. Decision Tree 이전의 복잡성 이후의 복잡성을 비교하여 어느정도 좋아졌는지를 나타내는 건 정보획득(information gain)이다.
그럼 계속해서 데이터가 균일한 정도를 나타내는 지표, 즉 순도를 계산하는 방법 중 2가지 방식(Entropy, Gini Index)에 대해서 말씀드려보겠습니다.
1. Entropy
Entropy는 '규칙적이지 않은 정도'를 측정하는 물리학적 양입니다.
즉, Decision tree에서는 불확실성이나 혼란도를 측정하는 척도를 나타내는데요.
어떤 데이터가 얼마나 혼란스러운지, 얼마나 예측하기 어려운지를 나타냅니다.
엔트로피 값이 높을수록 해당 데이터 집합이 더 혼란스럽고(Ex. 다양한 클래스가 섞여있을 때..), 낮을수록 데이터가 더 정리되어 있다는 것을 의미합니다. 공식은 아래와 같습니다.
여기에서 pi는 클래스 i에 속할 확률 입니다.
엔트로피 값의 범위는 아래와 같습니다.
- 0: 모든 데이터가 하나의 클래스로 이루어진 경우, 즉 완전히 정리된 상태
- 1: 데이터가 완전히 섞여서 예측이 매우 어려운 상태
2. Gini Index(지니 계수)
Gini Index는 데이터가 특정 클래스에 속할 확률을 기준으로 불순도(Impurity)를 측정하는 방법입니다.
지니 계수는 클래스가 균일할수록 (즉, 한 클래스가 우세할수록) 값이 작아집니다.
공식은 아래와 같습니다.
위 공식에서 pi는 마찬가지로 클래스 i에 속할 확률 입니다.
Gini Index 값의 범위는 아래와 같습니다.
- 0: 0에 가까울수록 불확실성이 적고(한 클래스가 대부분인 상태)
- 1 : 1에 가까울수록 불확실성이 큽니다. (즉, 클래스가 골고루 섞인 상태)
여기까지 Entropy와 Gini Index를 알아보았는데요
둘 중 어느 로직을 사용하는 것이 더 좋은가에 대한 부분은 딱히 승자가 없이, 둘 다 결정 트리에서 비슷한 성능을 보여줍니다.
자 그럼 이게 실제로 어떻게 동작을 하는지 알아보겠습니다.
2. Deicision Tree 동작과정
실제 Decision Tree가 어떻게 동작하게 되는지
아래의 데이터를 기준으로 말씀드려보겠습니다.
여기에서 종속변수와 독립변수는 아래와 같이 이루어져 있습니다.
- 독립변수 : Cartoon, winter, > 1 (인원 수)
- 종속변수 : Family winter photo
2-1. Root Node 선택
결정 트리는 가장 먼저 데이터를 잘 나눌 수 있는 기준을 선택합니다.
여기에서 이제 Gini Index, Entropy, Information Gain을 사용하여 선택하게 됩니다.
즉 아래 사진과 같이 독립 변수에 대한 Gini Index, Entropy, Information Gain을 수행하여 점수가 좋은 것을 선택하여 Root Node를 선택하게 됩니다.
2-2. Intermediate Node 선택
위 의 순서에서 Cartton Character가 Root Node로 선택되었다면 이후 Intermediate Node를 선택하게 되는데 여기에서도 동일하게 Gini Index, Entropy, Information Gain을 수행하여 점수가 좋은 것을 선택하여 Intermediate Node를 선택하게 됩니다.
2-3. Terminal Node 및 Decision Tree 완성
위 순서들을 통과하여 아래와 같이 Terminal Node 및 Decision Tree를 완성시켜주게 됩니다.
3. 가지치기 (Pruning)
위 의 예시들은 트리의 깊이가 2~3개짜리로 보여드렸는데
만약 아래와 같이 깊이가 깊어진다면 과적합이 일어날 수 있고, 그에 따른 불필요한 복잡한 구조가 되게 됩니다.
가지치기는 이러한 문제를 해결하기 위해 트리의 깊이를 제한하거나, 불필요한 노드를 제거하여 과적합을 방지하고 일반화 성능을 개선하는 데 사용됩니다.
3-1 가지치기(Pruning)란 무엇인가?
가지치기는 결정 트리에서 불필요하거나 의미 없는 분할을 제거하여 트리의 복잡성을 줄이는 기법입니다. 트리가 너무 깊어지면 학습 데이터에 과도하게 맞춰질 수 있는데, 이는 과적합의 원인이 됩니다. 가지치기는 이러한 불필요한 분할을 제거함으로써 트리의 단순화를 이루고, 새로운 데이터에 대한 예측 성능을 향상시킬 수 있습니다.
3-2 가지치기(pruning)의 종류
과적합을 막는 전략은 크게 2가지 입니다.
1) 사전 가지치기(Pre-pruning)
트리를 학습할 때, 미리 정해진 조건에 따라 트리의 성장을 제한하는 방법입니다. 예를 들어서, 트리의 깊이를 제한하거나, 최소한의 샘플 수가 특정 값 이하로 떨어지면 더 이상 분할하지 않는 방법입니다.
간단히 말씀드리자면 트리의 최대 깊이나 리프의 최대 개수를 제한하거나, 노드가 분할하기 위한 포인트의 최소 개수를 지정하는 것 입니다.
scikit-learn에서 결정트리는 DecisionTreeRegressor와 DecisionTreeClassifier에 구현되어 있고, scikit-learn은 사전 가지치기만 지원합니다.
tree = DecisionTreeClassifier(max_depth=4, random_state=0)
tree.fit(X_train, y_train)
print("훈련 세트 정확도: {:.3f}".format(tree.score(X_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(tree.score(X_test, y_test))
이렇게 트리 깊이를 제한하면 과대적합은 줄어들게 됩니다.
여기에서 훈련 세트의 정확도는 떨어뜨리지만 테스트 데이터 세트의 정확도를 개선시켜서 실제 서비스에서 오는 비교 데이터에 대한 정확도를 올릴 수 있습니다.
근데 여기에서 주의할 점은 너무 일찍 분할을 멈추면 트리가 충분히 학습을 못할 수 있으므로 가지치기 시점을 잘 지정해주셔야합니다.
2) 사후 가지치기 (Post-pruning)
완전히 학습한 트리에서 불필요한 가지를 제거하는 방법입니다.
방법으로는 가지 병합, 오차 복잡도 기반 가지치기가 있습니다.
결론적으로 아래와 같은 기존 데이터가
(전체 데이터)
/ \
조건1(True) 조건1(False)
/ \ / \
조건2(True) 조건2(False) 조건2(True) 조건2(False)
아래와 같이 불필요한 분할을 제거하고, 중요한 조건들만 남긴 상태입니다. 이로 인해 과적합이 줄어들고, 예측도 더 빠르게 이루어지게 됩니다.
(전체 데이터)
/ \
조건1(True) 조건1(False)
(결과) (결과)
이제 결론 정리를 해보겠습니다.
여기까지 정리를 해보자면
1. Decision Tree는 데이터를 이용하여 Tree구조를 만들고, 분류하거나 결과값을 예측하는 분석 방법을 말한다.
2. Decision Tree를 만들때에는 각 node들의 복잡성 즉, impurity가 가장 낮은 방향으로 tree가 만들어진다.
3. impurity 지표들을 바탕으로 node들의 복잡성을 계산하는 방법이 대표적으로 Entropy, Gini Index 등..) 이 있다.
4. Decision Tree 이전의 복잡성 이후의 복잡성을 비교하여 어느정도 좋아졌는지를 나타내는 건 정보획득(information gain)이다.
5. Depth가 길어지면 복잡도가 커지게 되어 과적합이 일어나게 되는데 이걸 제어하는게 가지치기(Pruning)이고, 종류로는 사전/사후 가지치기가 있다.(post/pre)
- pre-pruning : 트리를 학습할 때, 미리 정해진 조건에 따라 트리의 성장을 제한하는 방법
- post-pruning : 완전히 학습한 트리에서 불필요한 가지를 제거하는 방법
4. 실제 데이터 분석
위 데이터는 제가 실제로 운동과 관련 된 운동 데이터(Train, Test)를 만들어서 Decision Tree에 적용해본 것 인데요.
성능 지표를 보면 아래와 같습니다. 성능이 나쁘진 않은 것 같네요
그래프 해석을 해보자면
1. Root Node (루트 노드)
- PCA Component 1 <= -5.35: 트리의 가장 상단에 있는 노드입니다. 이 노드는 데이터를 첫 번째 주성분의 값에 따라 나누고 있습니다
- gini = 0.815: 초기 데이터는 여러 클래스가 섞여 있어, 지니 계수가 0.815로 높습니다.
- samples = 426: 총 426개의 샘플이 있으며, 다양한 운동 동작에 해당합니다.
- value = [91, 20, 77, 80, 79, 79]: 각 클래스에 속하는 샘플의 수를 나타냅니다. 예를 들어, 첫 번째 클래스에 91개의 샘플이 있고, 두 번째 클래스에 20개의 샘플이 있는 식입니다.
2. 왼쪽 자식 노드
- PCA Component 1 <= -5.394: 첫 번째 주성분 값이 -5.394보다 작을 경우, 이 노드로 이동합니다.
- gini = 0.042: 이 노드에서는 불확실성이 거의 없으며, 대부분의 샘플이 ham_go 클래스에 속합니다.
- samples = 93: 93개의 샘플이 이 노드로 분류됩니다.
- value = [91, 2, 0, 0, 0, 0]: 이 노드에서 거의 모든 샘플이 첫 번째 클래스인 ham_go에 속해 있습니다.
- 이 노드는 다시 두 그룹으로 나뉩니다
- 왼쪽: gini = 0.0이고, 83개의 샘플이 ham_go로 완전히 분류됩니다.
- 오른쪽: gini = 0.32로, 10개의 샘플 중 8개는 ham_go이고, 나머지 2개는 ham_ready입니다.
3. 오른쪽 자식 노드
- PCA Component 2 <= -5.714: 첫 번째 분할에서 PCA Component 1 값이 -5.35보다 크면 이 노드로 이동하며, 두 번째 주성분인 PCA Component 2에 따라 다시 나눕니다.
- gini = 0.773: 불확실성이 여전히 높습니다. 여러 클래스가 섞여 있습니다.
- samples = 333: 이 노드로는 333개의 샘플이 분류됩니다.
- value = [0, 18, 77, 80, 79, 79]: 여러 운동 동작이 섞여 있습니다.
- 이 노드도 다시 두 그룹으로 나뉩니다
- 왼쪽: gini = 0.0이고, 79개의 샘플은 모두 squat_up 동작입니다.
- 오른쪽: 두 그룹으로 나뉘어, 한쪽은 squat_down과 sphinx_up 동작으로 나뉘며, 이들은 여러 단계로 세분화됩니다.
참고링크
https://ko.wikipedia.org/wiki/%EA%B2%B0%EC%A0%95_%ED%8A%B8%EB%A6%AC
https://process-mining.tistory.com/42
https://www.youtube.com/watch?v=n0p0120Gxqk
'[AI | ML]' 카테고리의 다른 글
[AI | ML] [분류기] Random Forest에 대해서 알아보자 - 1. 보팅편(Voting) (8) | 2024.10.28 |
---|---|
[AI | ML] [HPE] Landmarks 정보 (2D, 3D) 선택에 대한 고찰 (8) | 2024.10.23 |
[AI | ML] [분류기] SVM (Support Vector Machine)에 대해서 알아보자 (4) | 2024.10.02 |
[논문리뷰] GAN(Generative Adversarial Networks) (feat. 퍼셉트론, 다중퍼셉트론, MCMC, DBN, NCE 등..) (2) | 2024.06.11 |
[AI | ML][분류기] K-Nearnest Neighbor 알고리즘 (KNN, k-최근접 이웃)에 대해서 알아보자 (2) | 2024.01.24 |