Artificial Intelligence/Machine Learning

지도학습(분류) - 의사결정나무

DaTALK 2021. 12. 3.

1. 서론

* 의사결정나무기법은 지도학습 중 '분류문제'에 해당하는 기법이다.

 

* (앞서) 지도학습 분류기법의 개념에 관해 먼저 숙지하자. (하단 포스팅 참조)

https://dataworld.tistory.com/44

 

지도학습(분류)

1. 서론 ML 기법 중 '분류' 기법에 대해 알아본다. (ML 기법 중 '회귀' 기법에 관한 포스팅은 아래 여러 포스팅 참조!) -- 단순선형회귀 -- https://dataworld.tistory.com/42 지도학습 (회귀) - 단순선형회귀 1...

dataworld.tistory.com

 

 

2. 의사결정나무(Decision Tree) 개념

 

* 스무고개와 같이 특정 질문들을 통해 정답을 찾아가는 모델

* 최상단의 뿌리 마디에서 마지막 끝 마디까지 아래 방향으로 진행한다.

* 간단하게 한 수치를 기준으로 Yes, No로 나눌 수 있지만, 그렇지 않은 경우가 다수 존재.

- 예를 들어 중간 마디를 추가해야 하는 경우가 존재한다.

- 1개의 feature일 경우 하단 [1] 그림과 같이 의사결정나무를 만들 수 있으며,

- 2개 이상의 feature일 경우 하단 [2] 그림과 같이 만들 수 있다.

* 뿌리 마디에서 분리 기준을 기준으로 하여 분리하고 맨 마지막의 끝 마디는 class

(도중에 나눠진 마디는 중간 마디(Internal Node))

 

 

[1] 중간 마디가 존재하는 경우 위와 같이 의사결정나무 모델을 생성한다.

 

[2] 두 개의 feature일 경우, 위와 같이 의사결정나무 모델을 생성한다.

[1] 불순도

* 주어진 여러 데이터를 어떤 분류기준으로 나눌 지 정한다.

* 이 때, 데이터의 불순도(Impurity)를 최소화하는 구역으로 나누자 (분류기준을 정할 때의 척도)

 

* 불순도 = 다른 데이터가 섞여 있는 정도

- 데이터가 많이 섞여 있을 수록 불순도가 높게 측정

 

{1} 지니 불순도(Gini Impurity)

* 지니 계수(Gini Index) = 해당 구역 안에서 특정 클래스에 속하는 데이터의 비율을 모두 제외한 겂

- 다양성을 계산하는 방법

- 즉, 어떤 분류 기준을 가지고 데이터를 나누었을 때 나뉜 각 부류의 지니 계수가 구해짐

 

* 지니 불순도(Gini Impurity)

- 각 부류 별 구해진 지니 계수를 가지고 지니 불순도를 구함

 

* 지니 불순도 계산하기 (예)

X가 1 & 2인 경우 그리고 아닌 경우로 분류를 하였을 때의 gini impurity 구하기

- 상단 그림과 같이 각각 모든 경우로 분류를 하였을 경우 가장 낮은 Gini 불순도를 갖는 기준을 선택한다.

- 한 번 Gini 불순도에 의하여 나누면, 또 나뉜 부류에서 계속적으로 Gini 불순도 기준을 적용한다.

 

[2] 깊이

* 깊이 = 중간 Node의 개수

* 의사결정나무 깊이가 깊어질수록 세분화해서 나눌 수 있음

* 하지만 너무 깊은 모델은 과적합을 야기할 수 있다.

- 즉 데이터에 따라 다를 수 있지만 너무 깊은 모델은 지양한다.

- 짜잘한 데이터까지 모두 세밀하게 고려하면 잡음까지 고려해서 모델 성능이 오히려 떨어질 수 있음

 

[3] 특징

* 결과가 직관적이며 해석하기 쉽다

* 나무 깊이가 깊어질수록 과적합(overfitting) 문제 발생 가능성이 매우 높다

* 학습이 끝난 트리의 작업 속도가 매우 빠르다

 

3. 의사결정나무(Decision Tree) 간단 실습

[1] 데이터 준비 및 전처리하기

- 분류 문제 해결을 위해 매우 유명하고도 유명한 Iris 데이터를 사용한다.

- 꽃받침 길이, 꽃받침 넓이, 꽃잎 길이, 꽃잎 넓이 4가지 변수 & 세 종류의 붓꽃 클래스로 구성되어 있다.

 

Iris 데이터 구성

 

Q) 위 네 가지 변수가 주어졌을 때, 어떠한 붓꽃 종류인지 예측하는 분류 모델을 구현해 보기

- 4개의 변수를 갖는 feature 데이터 & class 변수를 label 데이터로 분류 (지도학습)

- 학습용 & 평가용 데이터로 나누기

 

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# use 'load_iris' function (sklearn function) to load iris data
X, Y = load_iris(return_X_y = True)

# load data into a dataframe
df = pd.DataFrame(X, columns=['꽃받침 길이','꽃받침 넓이', '꽃잎 길이', '꽃잎 넓이'])
df['클래스'] = Y

# preprocess data and divide it into X & Y
X = df.drop(columns=['클래스'])
Y = df['클래스']

# use train_test_split function to separate train & test data in X & Y each

train_X, test_X, train_Y, test_Y

 

[2] 의사결정나무 학습 및 출력

* 각 노드에서 불순도를 최소로 하는 의사결정나무 모델을 구현하기 위해서는 sklearn의 DecisionTreeClassifier을 사용한다.

 

* 먼저 해당 모델의 객체를 불러와 초기화

(초기화할 때 파라미터로 max_depth를 설정하여 의사결정나무의 최대 깊이를 조절할 수 있음)

* 그 다음, fit 함수에 학습에 필요한 데이터(위 [1]에서 전처리한 데이터)를 입력하여 학습을 수행

(fit함수에서 집어넣을, 즉 학습할 데이터는 test data가 아닌 훈련용 train data 사용)

 

DTmodel = DecisionTreeClassifier()
DTmodel.fit(train_X, train_Y)

 

* 학습한 결과를 출력한다.

- plot_tree 함수 사용

 

plt.rc('font', family='NanumBarunGothic')
fig = plt.figure(figsize=(25,20))
_ = tree.plot_tree(DTmodel, 
                   feature_names=['꽃받침 길이','꽃받침 넓이', '꽃잎 길이', '꽃잎 넓이'],  
                   class_names=['setosa', 'versicolor', 'virginica'],
                   filled=True)

fig.savefig("decision_tree.png")

 

 

* 출력 결과 해석

- 각 네모 칸의 entropy는 gini impurity에 해당한다

- samples는 네모 칸에 해당되는 데이터 개수

- DecisionTreeClassifier의 parameter는 max_depth를 조절하면서 과적합을 방지할 수 있다. (적정 max_depth 사용 필수)

 

[3] 의사결정나무 - 데이터 예측

* DecisionTreeClassifier로 만든 모델의 내장함수 predict를 사용하여 새로 들어오는 데이터를 기반으로 분류(예측)를 할 수 있다.

* 여기서 예측할 때 train data가 아닌 test data 새로운 데이터 이용

 

pred_X = DTmodel.predict(test_X)

 

 

 

 

 

- 출처 - 2021 NIPA/AI 기본/응용 교육과정

댓글