Study/AI

[AI][ML]결정 트리(Decision Tree)

seomj 2022. 8. 11. 21:54

결정 트리

분류와 회귀 모두 가능한 지도 학습 모델 중 하나

의사 결정 규칙과 그 결과들을 트리 구조로 도식화한 의사 결정 지원 도구의 일종

3가지 종류의 노드로 구성

  • 결정 노드(decision node): 사각형으로 표시
  • 기회 노드(chance node): 원으로 표시
  • 종단 노드(end node): 삼각형으로 표시

스무고개 하듯이 예/아니오 질문을 이어가며 학습

특정 기준(질문)에 따라 데이터를 구분하는 모델

한번의 분기 때마다 변수 영역을 두 개로 구분

맨 처음 분류 기준: Root Node

맨 마지막 노드: Terminal Node 혹은 Leaf Node

 

새로운 데이터가 들어오면 체크리스트(?)를 바탕으로 하나씩 질문하고 해당 답에 대한 다음 나무 줄기를 따라가다가 결국에는 '이건 어떤 레이블이겠구나'라고 분류를 해줄 수 있게 된다.

 

그렇기에 질문을 잘 설계해야 한다.

 

프로세스

이와 같은 방식으로 데이터를 잘 구분할 수 있는 질문을 기준으로 나눈다. 이를 지나치게 많이 하면 오버피팅이 된다. 결정트리에 아무 파라미터를 주지 않고 모델링하면 오버피팅이 된다.

 

 

가지치기(Pruning)

오버피팅을 막기 위한 전략

최대 깊이나 터미널 노드의 최대 개수, 혹은 한 노드가 분할하기 위한 최소 데이터 수를 제한하는 것

min_sample_split: 한 노드에 들어있는 최소 데이터 수를 지정

max_depth: 최대 깊이를 지정

 

 

불순도(Impurity)

해당 범주 안에 서로 다른 데이터가 얼마나 섞여 있는지

위쪽은 불순도가 낮고, 아래쪽은 불순도가 높다.

즉, 위쪽은 순도가 높고 아래쪽은 순도가 낮다.

 

 

지니 불순도(Gini Impurity)

어떤 질문이 좋은 질문일까.

우리의 목표는 오른쪽 그림처럼 깔끔하게 나눠지는 것이다. 

이 불순물이 어느정도 포함되어 있는지 확인할 수 있는 지표로 지니 불순도 값을 확인할 수 있다.

 

계산법은 1에서 '전체 데이터 개수 중 각 레이블이 차지하는 개수의 비율'을 제곱해서 빼주면 된다.

 

ex) 총 4개의 데이터 세트에서 레이블 A가 3개, B가 1개 포함되어 있다면 다음과 같다.

 

만약 단 하나의 레이블로 퓨어하게 구성되어 있다면 지니 불순도의 값은 0이 될 것이다.

좋은 질문을 거쳐 분할된 데이터 세트는 지니 불순도 값이 작다.

 

 

정보 획득량(Information Gain)

지니 불순도를 구할 수 있다면, 이를 통해 어떤 질문에서 얻을 수 있는 정보 획득량(Information Gain)을 계산할 수 있다.

불순도 0.5의 데이터 세트를 3개의 데이터 세트로 분할했을 때, 여기서 얻은 정보 획득량은 다음과 같이 계산할 수 있다.

 

Information Gain = 0.5 - (0 + 0.375 + 0) = 0.125

 

이전 단계 불순도에서 다음 단계의 불순도 합을 빼주는 것이다.

즉, 분할된 데이터 세트들의 불순도가 작을수록 정보 획득량은 증가한다.

 

그러나 이것만으로 정보 획득량을 설명하기엔 부족한 측면이 있어 가중치(weight)를 적용하기도 한다.

 

 

Weighted Information Gain

불순도는 0으로 같지만, 오른쪽 데이터 세트가 더 의미있어 보인다. 데이터 개수가 충분히 많기에 이 분류가 우연이 아니라고 확신할 수 있기 때문이다.

 

이처럼 생성된 데이터 세트의 크기에 따라 가중치가 적용된 정보 획득량을 계산해보자.

분할하기 전 데이터에 비해 분할 후 생성된 데이터의 크기(비율)에 따라 가중치를 구해놓고 이를 불순도에 곱해서 정보 획득량을 구하면 된다.

 

Information Gain = 0.5 - ((2/10)*0.5 + (5/10)*0.48 + (3/10)*0.44) = 0.026

 

데이터 세트의 크기가 작을수록 그 불순도의 영향력도 작아진다.

 

 

재귀적(Recursive) 트리 빌딩

의사결정 트리에서는 정보 획득량이 큰 순서대로 질문을 배치하는 게 중요하다.

그리고 그 속성에 대해 어느 기준으로 나누는 게 좋을지 반복적으로 적용해 보면서 최적의 트리를 찾게 된다.

더 이상은 순수한 하위 집합을 만드는 방법을 찾을 수 없을 때까지 한다.


실습

import pandas as pd
data = pd.read_csv('D:/Ai/weather_play.csv')
 
data

# mapping dictionary 만들기
outlook_dic = {'overcast':0, 'rainy':1, 'sunny':2}
temperature_dic = {'cool':0, 'hot':1, 'mild':2}
humidity_dic = {'high':0, 'normal':1}
windy_dic = {False:0, True:1}


# 딕셔너리를 활용해 데이터 매핑
data['outlook'] = data['outlook'].map(outlook_dic)
data['temperature'] = data['temperature'].map(temperature_dic)
data['humidity'] = data['humidity'].map(humidity_dic)
data['windy'] = data['windy'].map(windy_dic)
 
data

#Decision tree classifier instance 생성
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
model.fit(data.iloc[:, :4].values, data['play'].values)

 

 

 

출처

https://hleecaster.com/ml-decision-tree-concept/

https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-4-%EA%B2%B0%EC%A0%95-%ED%8A%B8%EB%A6%ACDecision-Tree