Idealim
article thumbnail

/* 본 게시물은 ' Introduction to MachineLearning with Python | 안드레이스 뮐러, 세라 가이도 ' 의 내용과 참고자료를 토대로 작성되었습니다. */

/* 본 글은 개인적으로 공부한 내용을 정리한 글이므로 오류가 있을 수 있습니다. */


1. 결정트리란?

결정트리는 분류와 회귀 문제에 널리 사용하는 모델이다. 기본적으로 결정 트리는 결정에 다다르기 위해 예/아니오 질문을 이어 나가면서 학습한다. (스무고개와 비슷하다.)

결정트리 장점

  • 트리를 시각화하면 데이터가 어떻게 분류(예측)되는지 확인이 가능하다. 
  • 데이터의 스케일에 영향을 받지 않는다. 
  • 각 특성이 개별적으로 처리되어 데이터를 분할하는데 데이터 스케일의 영향을 받지 않으므로 결정 트리에서는 특성의 정규화나 표준화 같은 데이터 전처리 과정이 필요없다. 

결정트리 단점

  • 사전 가전치기를 사용해도 과대적합되는 경향이 있기 떄문에 일반화 성능이 좋지 않다.
  • 트리 모델은 훈련 데이터 밖의 새로운 데이터를 예측할 능력이 없다.

결정 트리의 단점을 보완하기 위해 앙상블 기법을 사용한다. 앙상블에 대한 내용은 다음 게시글로 다루겠다.


2. 트리의 구조

결정 트리 예시

네모 상자를 노드라 부른다. 맨 처음 노드를 루트 노드, 마지막 노드는 리프라고 한다. 마지막 노드 중 타깃 하나로만 이루어진 경우 순수 노드라고 한다.


3. 결정 트리 다루기

결정 트리 과정 이해하기

특성 0, 1 에 대한 데이터 셋

* 정보 이득이 최대가 되도록 분류한다. (정보 이득 = 부모 불순도 - 자식 노드 사이의 불순도 차이) 


결정 트리 만들기

#데이터 셋 불러오기
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()

#결정트리 생성 및 훈련
from sklearn.model_selection import train_test_split
train_input, test_input, train_label, test_label = train_test_split(
    cancer.data, cancer.target, stratify=cancer.target, random_state=42)
dt = DecisionTreeClassifier(random_state = 42)
dt.fit(train_input, train_label)
print("훈련 세트 정확도: {:.3f}".format(dt.score(train_input, train_label)))
print("테스트 세트 정확도: {:.3f}".format(dt.score(test_input, test_label)))

훈련 세트에 대해 100%의 정확성을 보아 과대적합이 일어난 것을 알 수 있다.


결정 트리 복잡도 제어하기

일반적으로 트리 만들기를 모든 리프 노드가 순수 노드가 될 때까지 진행하면 모델이 매우 복잡해지고 훈련 데이터에 과대적합된다. 위 예시처럼 훈련 세트에 100% 정확하게 맞는다. 이를 막기 위한 방법은 크게 두 가지이다. 트리 생성을 일찍 중단하는 방법(사전 가전치기)과 트리를 만든 후 데이터 포인트가 적은 노드를 삭제하거나 병합하는 방법(사후 가지치기)이 있다. DecisionTreeClassifier 는 max_depth 매개변수를 통해 사전 가전치기를 할 수 있다. 

#max_depth 설정
dt_max_depth = DecisionTreeClassifier(max_depth=4, random_state=0)
dt_max_depth.fit(train_input, train_label)
print("훈련 세트 정확도: {:.3f}".format(dt_max_depth.score(train_input, train_label)))
print("테스트 세트 정확도: {:.3f}".format(dt_max_depth.score(test_input, test_label)))

트리 깊이를 4로 제한하여 과대적합을 줄였다. 테스트 세트 정확도가 이전보다 높아진 것을 확인할 수 있다.


결정 트리 분석

트리를 시각화 하는 방법은 2가지가 있다. 첫 번째로는 graphviz 라이브러리를 사용한 방법, 두 번째로는 plot_tree 메서드를 사용한 방법이 있다. 이번 예시로는 두 번째 방법을 사용하겠다.

# 방법2. plot_tree 메서드 사용
from sklearn.tree import plot_tree
# class_names : 노드 클래스, filled : 클래스 별 색 구별
plot_tree(dt_max_depth, class_names=["악성", "양성"], feature_names=cancer.feature_names, impurity=False,
         filled=True, rounded=True, fontsize=4)
plt.show()

* 사용한 feature 에 따라 색이 다르다.


트리의 특성 중요도

트리를 만드는 과정에서 각 특성이 얼마나 중요한지 평가하는 특성 중요도를 확인해보자.

print("특성 중요도:\n", dt_max_depth.feature_importances_)

값이 0~1 사이에 존재한다. 각 특성에 대해 0은 트리를 만드는데 전혀 사용되지 않았다는 의미이고, 1은 완벽하게 타깃 클래스를 예측했다는 의미이다. 특성 중요도의 전체 합은 1이다. 특성 중요도를 시각화해보자.

def plot_feature_importances_cancer(model):
    # feature 개수
    n_features = cancer.data.shape[1]
    print(n_features)
    print(np.arange(n_features))
    plt.barh(np.arange(n_features), model.feature_importances_, align='center')
    plt.yticks(np.arange(n_features), cancer.feature_names, fontname= "Arial")
    plt.xlabel("특성 중요도")
    plt.ylabel("특성")
    plt.ylim(-1, n_features)
    plt.show()

plot_feature_importances_cancer(dt_max_depth)


참고 자료

[URL] :

반응형
profile

Idealim

@Idealim

읽어주셔서 감사합니다. 잘못된 내용이 있으면 언제든 댓글로 피드백 부탁드립니다.