Decision Tree 시각화 방법 정리 (graphviz vs matplotlib)

2025. 7. 1. 15:19Python(AI)

Decision Tree 시각화 방법 정리 (graphviz vs matplotlib)

이번 포스팅에서는 Decision Tree 모델을 학습한 뒤, 트리를 시각화하는 방법 두 가지를 정리해봤다.

하나는 graphviz를 사용하는 방식이고, 다른 하나는 matplotlib의 plot_tree()를 사용하는 방식이다.

1. 공통 전제: 트리 모델 학습


from sklearn.tree import DecisionTreeClassifier

tree_model = DecisionTreeClassifier()
tree_model.fit(X_train, y_train)

트리 모델 학습은 동일하다. 이 모델을 기반으로 각각 다른 방식으로 시각화를 해본다.

2. 방법 ①: graphviz로 시각화

graphviz는 시각적으로 정돈된 고품질 트리 시각화가 가능하다. 다만, 시스템에 별도로 graphviz를 설치해야 한다.


from sklearn.tree import export_graphviz
import graphviz

# .dot 파일 생성
export_graphviz(tree_model, out_file="./data/tree.dot", 
                class_names=["식용", "독성"],
                feature_names=X_oh.columns,
                filled=True, impurity=True)

# .dot 파일 읽고 PDF로 저장
with open("./data/tree.dot", encoding='utf-8') as f:
    dot_graph = f.read()

graph = graphviz.Source(dot_graph)
graph.render("./data/tree", format="pdf")

이렇게 하면 ./data/tree.pdf 파일이 생성되며, 이를 열어보면 예쁘게 정돈된 의사결정 트리를 볼 수 있다.

graphviz의 장점

  • 출판용/보고서용으로 적합한 고품질 그래픽
  • 노드 간 거리, 선, 텍스트가 깔끔하게 정렬됨
  • 복잡한 트리도 선명하게 표현 가능

단점

  • graphviz 프로그램을 별도로 설치해야 함
  • 즉각적인 화면 시각화는 어려움 (파일 열어야 함)

3. 방법 ②: matplotlib의 plot_tree로 시각화

plot_tree()는 Python만으로 바로 시각화할 수 있는 방식이다. Jupyter Notebook이나 VS Code Interactive 창에서 바로 시각화 가능해서 간편하다.


from sklearn.tree import plot_tree
import matplotlib.pyplot as plt

plt.figure(figsize=(20, 10))
plot_tree(tree_model,
          feature_names=X_oh.columns,
          class_names=["식용", "독성"],
          filled=True, rounded=True)
plt.title("의사결정나무 시각화")
plt.show()

matplotlib 방식의 장점

  • Python만 있으면 별도 설치 없이 바로 사용 가능
  • 실습용, 데모용으로 빠르게 확인 가능

단점

  • 노드 배치나 정렬이 깔끔하지 못할 수 있음
  • 복잡한 트리는 시각적으로 겹치고 보기 어려움

4. 두 방식 비교 요약

항목 graphviz matplotlib.plot_tree
정밀도 고화질, 정돈된 시각화 기본적인 도식 수준
설치 필요 여부 그래픽 툴 별도 설치 필요 Python만으로 가능
사용 목적 논문, 보고서 등 출력용 실습, 빠른 확인용
파일 저장 .pdf, .png 등 다양하게 저장 가능 savefig()로 저장 가능

6. 전체 코드 (matplotlib 시각화 기반)

내가 진행한 전체 실습 코드는 아래와 같다. 원핫 인코딩 후 Decision Tree 모델을 학습하고, plot_tree()로 시각화하는 과정까지 모두 포함되어 있다.


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score

# 데이터 불러오기
data = pd.read_csv("./data/mushroom.csv")

# 결측치 확인
data.isnull().sum()

# 특성과 정답 분리
X = data.drop(columns=["poisonous"])
y = data["poisonous"]

print("문제 데이터 크기:", X.shape)
print("정답 데이터 크기:", y.shape)
print("정답 분포:\n", y.value_counts())

# 원핫 인코딩
X_oh = pd.get_dummies(X)
print("원핫 인코딩 후:", X_oh.shape)

# 학습/테스트 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X_oh, y, test_size=0.3, random_state=3)

# 모델 학습
tree_model = DecisionTreeClassifier(random_state=3)
tree_model.fit(X_train, y_train)

# 예측 및 정확도
y_pred = tree_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("정확도:", accuracy)

# 교차 검증
cv_scores = cross_val_score(tree_model, X_train, y_train, cv=5)
print("교차 검증 정확도:", cv_scores)
print("평균 교차 검증 정확도:", np.mean(cv_scores))

# 특성 중요도
fi_df = pd.DataFrame(tree_model.feature_importances_,
                     index=X_oh.columns,
                     columns=["importance"])
print("특성 중요도 상위 항목:\n", fi_df['importance'].sort_values(ascending=False).head())

# matplotlib으로 시각화
plt.figure(figsize=(20, 10))
plot_tree(tree_model,
          feature_names=X_oh.columns,
          class_names=["식용", "독성"],
          filled=True,
          rounded=True,
          fontsize=8)
plt.title("의사결정나무 시각화")
plt.show()

5. 마무리

두 방식 모두 학습한 모델을 잘 시각화해주는 도구이긴 하지만, 목적에 따라 선택하는 게 중요한 것 같다.

실습이나 빠른 확인이 목적이라면 matplotlib.plot_tree로 충분하고, 나중에 리포트나 블로그용 이미지가 필요하면 graphviz로 다시 시각화하면 될 듯하다.

나도 프로젝트 결과를 정리할 때는 graphviz로 다시 시각화해서 PDF로 뽑아봐야겠다.