본문 바로가기
개발 Tools/파이썬_Deep learning & ML

머신러닝 결정트리 (지니계수, 정보 이득 지수, min_samples_split, min_samples_leaf, max_features, max_depth, max_leaf_nodes, graphviz)

by 전컴반 2021. 8. 2.
반응형

결정 트리는 하나의 스무고개 같은 느낌이다. 하나하나 조건에 맞게 데이터를 나눈다. 한번 나눌 때마다 최대한 많이 나누야 적게 나누고 원하는 결과를 빨리 얻을 수 있다. 스무고개에서 20번 다 물어보고 맞추는 거보다. 10번째에 맞추는 게 더 빠르기 때문이다.

조금 다르게 예를 들면 0~100 사이의 숫자를 맞출 때 만약 정답이 32라 하면, 우린 첫 번째로 50보다 큰지 작은지 물어보는 게 합리적이다 생각한다. 10보다 큰지 작은지 묻는다면 도박을 하는 것과 같다. 이처럼 결정 트리에도 분류하는 방법이 있는데 기준은 2가지 방법이 있다.

 

지니 계수

 

첫번째로 지니 계수를 이용한다. 지니 계수란, 불평등 지수를 나타내는데 0~1 사이의 값으로 평가된다. 0이면 가장 평등하고 1은 불평등함을 나타낸다.

다시 말해, 0이면 다양한 값들이 들어있고 1이면 하나의 값들이 들어있다는 의미다. 우린 조건을 지날 때마다 최대한 많은 데이터를 분류해야 한다.

 

정보 이득 지수 (엔트로피)

 

두 번째로는 정보 이득 지수라는 지표를 사용한다. 간단히 말해 엔트로피가 높다면 다양한 값들이 들어 있고, 낮다면 같은 값이 들어있다고 본다.

허나, 정보 이득 지수는 (1- 엔트로피)의 값을 가진다.

 

파라미터

min_samples_split : 디폴트는 2이다. 노드를 분할하기 위한 최소한의 샘플 데이터 수이다. 예를 들면, 한번 나눴는데 한 집단에 2개의 데이터가 들어있다면 더 이상 나누지 않는 것이다. 만약에 1이라면 끝까지 계속 나누기 때문에 과적합의 가능성이 있다. 


min_samples_leaf : 말단 노드가 되기 위한 최소한의 샘플 데이터 수


max_features : 디폴트는 None이다. 이 말은 모든 특징을 이용하여 분할의 기준을 정한다는 뜻이다. 즉, 몇 개의 특징을 가지고 분할할지 정하는 것이다.


max_depth : 트리의 최대 깊이 지정하는 것이다. 디폴트는 None이다.


max_leaf_nodes : 말단 노드의 최대 개수

 

라이브러리

 

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  
from sklearn.tree import export_graphviz
import graphviz

 

예측

 

간단하다. 데이터를 분리하고 결정 트리를 만들어 예측해본다.

 

iris = load_iris()
iris_data = iris.data
iris_target = iris.target

X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_target, test_size=0.2, random_state=1)

clf = DecisionTreeClassifier(random_state=999)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)

score = accuracy_score(y_test, pred)
print(score)

출력
0.9666666666666667

 

높은 성능을 가진다.

 

graphviz

 

위와 같은 결과를 어떻게 도출했는지 graphviz라는 도구를 사용하여 확인할 수 있다. 설치를 따로 해줘야 한다.

설치법은 구글에 잘 나와있다.

 

코드를 보겠다.

 

iris_label_name = iris.target_names

export_graphviz(clf, out_file="tree.dot", class_names=iris_label_name, feature_names=iris.feature_names, impurity=True, filled=True)

with open("tree.dot") as f:
    dot_graph = f.read()

graph = graphviz.Source(dot_graph)
graph.render(view=True)

 

먼저 파일로 만들어서 읽어오면 그림으로 불러온다. 주피터에서는 그냥 graphviz.Source(dot_graph)만 치면 나오지만 본인은 파이참을 사용하고 있어 graph.render(view=True)를 사용했다.

 

 

보면 위에서 본 지니계수를 기준으로 분류했다. 따로 파라미터를 설정하지 않아 기본값으로 들어갔지만 위에서 배운 파라미터를 지정하여 조절할 수 있다.

반응형

댓글