아래와 같은 순서로 책을 보시면 파이썬 => 판다스 => 머신러닝, 딥러닝을 공부할 수 있습니다. 제가 정리한 글에 있습니다.
https://steemit.com/kr/@papasmf1/73cj22
핸즈온 머신러닝 책의 소스는 아래의 깃허브에 있습니다. 참고하실 수 있습니다.
https://github.com/rickiepark/handson-ml
제가 테스트하고 실습하는 환경은 맥에 아나콘다 최근 패키지를 설치해서 주피터랩으로 실행하고 있습니다.
6장 결정 트리를 정리해 보았습니다.
SVM처럼 결정 트리 Decision Tree는 분류와 회귀 작업 그리고 다중 출력 작업도 가능한 다재다능한 머신러닝 알고리즘입니다. 또한 매우 복잡한 데이터셋도 학습할 수 있는 강력한 알고리즘입니다.
결정 트리는 최근에 자주 사용되는 가장 강력한 머신러닝 알고리즘 중 하나인 랜덤 포레스트의 기본 구성 요소이기도 합니다.
6.1 결정 트리 학습과 시각화
from future import division, print_function, unicode_literals
import numpy as np
import os
np.random.seed(42)
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
matplotlib.rc('font', family='AppleGothic')
matplotlib.rcParams['axes.unicode_minus'] = False
PROJECT_ROOT_DIR = "."
CHAPTER_ID = "decision_trees"
def image_path(fig_id):
return os.path.join(PROJECT_ROOT_DIR, "images", CHAPTER_ID, fig_id)
def save_fig(fig_id, tight_layout=True):
if tight_layout:
plt.tight_layout()
plt.savefig(image_path(fig_id) + ".png", format='png', dpi=300)
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
X = iris.data[:, 2:] # petal length and width
y = iris.target
tree_clf = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf.fit(X, y)
from sklearn.tree import export_graphviz
export_graphviz(
tree_clf,
out_file=image_path("iris_tree.dot"),
feature_names=["꽃잎 길이 (cm)", "꽃잎 너비 (cm)"],
class_names=iris.target_names,
rounded=True,
filled=True
)
(미리 터미널을 열어서 아래와 같이 설치를 해야 이미지가 출력됩니다.)
conda install python-graphviz ==> 이렇게 설치하면 문제 없음^^
import graphviz
with open("images/decision_trees/iris_tree.dot") as f:
dot_graph = f.read()
dot = graphviz.Source(dot_graph)
dot.format = 'png'
dot.render(filename='iris_tree', directory='images/decision_trees', cleanup=True)
dot
6.2 예측하기
새로 발견한 붓꽃의 품종을 분류하려 한다고 가정하겠습니다. 먼저 루트 노드에서 시작합니다. 이 노드는 꽃잎의 길이가 2.45cm보다 짧은지 검사합니다. 만약 그렇다면 루트 노트에서 왼쪽의 자식 노드로 이동합니다. 이 경우 이 노드가 리프 노드이므로 추가적인 검사를 하지 않습니다. 그냥 노드에 있는 예측 클래스를 보고 결정 트리가 새로 발견한 꽃의 품종을 Iris-Setosa(class=setosa)라고 예측합니다.
또 다른 꽃을 발견했는데 이번에는 꽃잎의 길이가 2.45cm보다 깁니다. 이번에는 루트 노드의 오른쪽 자식 노드로 이동해야 합니다. 이 노드는 리프 노드가 아니라서 추가로 ‘꽃잎의 너비가 1.75cm보다 작은지’검사해야 합니다. 만약 그렇다면 이 꽃은 아마도 Iris-Versicolor(깊이 2, 왼쪽)일 것입니다. 그렇지 않다면 Iris-Virginica(깊이 2, 오른쪽)일 것입니다. 아주 간단명료하네요.
from matplotlib.colors import ListedColormap
def plot_decision_boundary(clf, X, y, axes=[0, 7.5, 0, 3], iris=True, legend=False, plot_training=True):
x1s = np.linspace(axes[0], axes[1], 100)
x2s = np.linspace(axes[2], axes[3], 100)
x1, x2 = np.meshgrid(x1s, x2s)
X_new = np.c_[x1.ravel(), x2.ravel()]
y_pred = clf.predict(X_new).reshape(x1.shape)
custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])
plt.contourf(x1, x2, y_pred, alpha=0.3, cmap=custom_cmap)
if not iris:
custom_cmap2 = ListedColormap(['#7d7d58','#4c4c7f','#507d50'])
plt.contour(x1, x2, y_pred, cmap=custom_cmap2, alpha=0.8)
if plot_training:
plt.plot(X[:, 0][y0], X[:, 1][y0], "yo", label="Iris-Setosa")
plt.plot(X[:, 0][y1], X[:, 1][y1], "bs", label="Iris-Versicolor")
plt.plot(X[:, 0][y2], X[:, 1][y2], "g^", label="Iris-Virginica")
plt.axis(axes)
if iris:
plt.xlabel("꽃잎 길이", fontsize=14)
plt.ylabel("꽃잎 너비", fontsize=14)
else:
plt.xlabel(r"$x_1$", fontsize=18)
plt.ylabel(r"$x_2$", fontsize=18, rotation=0)
if legend:
plt.legend(loc="lower right", fontsize=14)
plt.figure(figsize=(8, 4))
plot_decision_boundary(tree_clf, X, y)
plt.plot([2.45, 2.45], [0, 3], "k-", linewidth=2)
plt.plot([2.45, 7.5], [1.75, 1.75], "k--", linewidth=2)
plt.plot([4.95, 4.95], [0, 1.75], "k:", linewidth=2)
plt.plot([4.85, 4.85], [1.75, 3], "k:", linewidth=2)
plt.text(1.40, 1.0, "깊이=0", fontsize=15)
plt.text(3.2, 1.80, "깊이=1", fontsize=13)
plt.text(4.05, 0.5, "(깊이=2)", fontsize=11)
save_fig("decision_tree_decision_boundaries_plot")
plt.show()