# ํ์ด์ฌ 2์ ํ์ด์ฌ 3 ์ง์
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)
๋ค์์ ๋ถ๊ฝ ๋ฐ์ดํฐ์ ์ DecisionTreeClassifier๋ฅผ ํ๋ จ์ํค๋ ์ฝ๋
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
X = iris.data[:, 2:] # ๊ฝ์์ ๊ธธ์ด์ ๋๋น
y = iris.target
tree_clf = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf.fit(X, y)
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=2, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=42, splitter='best')
iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
export_graphviz() ํจ์๋ฅผ ์ฌ์ฉํด ๊ทธ๋ํ ์ ์๋ฅผ iris-tree.dot ํ์ผ๋ก ์ถ๋ ฅํ์ฌ ํ๋ จ๋ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ์๊ฐํ
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
)
์ด .dot ํ์ผ์ graphviz ํจํค์ง๋ฅผ ์ฌ์ฉํ์ฌ png ํฌ๋งท์ผ๋ก ๋ณ๊ฒฝ
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
์์ ํธ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์์ธก์ ๋ง๋ค์ด๋ด๋์ง ์ดํด๋ณด๊ฒ ์
์ด ๋
ธ๋๋ ๊ฝ์์ ๊ธธ์ด๊ฐ 2.45cm๋ณด๋ค ์งง์์ง ๊ฒ์ฌ. ๋ง์ฝ ๊ทธ๋ ๋ค๋ฉด ์ผ์ชฝ์ ์์ ๋
ธ๋child node๋ก ์ด๋
์ด ๊ฒฝ์ฐ ์ด ๋
ธ๋๊ฐ ๋ฆฌํ ๋
ธ๋leaf node์ด๋ฏ๋ก ์ถ๊ฐ์ ์ธ ๊ฒ์ฌ๋ฅผ ํ์ง ์์
๋
ธ๋์ ์๋ ์์ธก ํด๋์ค(class=setosa)๋ฅผ ๋ณด๊ณ ๊ฒฐ์ ํธ๋ฆฌ๊ฐ ์๋ก ๋ฐ๊ฒฌํ ๊ฝ์ ํ์ข์ Iris-Setosa๋ผ๊ณ ์์ธก
NOTE_ ๊ฒฐ์ ํธ๋ฆฌ์ ์ฌ๋ฌ ์ฅ์ ์ค ํ๋๋ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๊ฐ ๊ฑฐ์ ํ์ํ์ง ์๋ค๋ ๊ฒ
โโโโย ํนํ ํน์ฑ์ ์ค์ผ์ผ์ ๋ง์ถ๊ฑฐ๋ ํ๊ท ์ ์์ ์ ๋ง์ถ๋ ์์
์ด ํ์ํ์ง ์์
[์ 6-1]์ ํ๋ จ ์๊ณ ๋ฆฌ์ฆ์ด i๋ฒ์งธ ๋
ธ๋์ gini ์ ์ Gi๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค
pi,k๋ i๋ฒ์งธ ๋
ธ๋์ ์๋ ํ๋ จ ์ํ ์ค ํด๋์ค k์ ์ํ ์ํ์ ๋น์จ
์๋ฅผ ๋ค์ด ๊น์ด 2์ ์ผ์ชฝ ๋
ธ๋์ gini ์ ์๋ 1-(0/54)2-(49/54)2-(5/54)2 โ 0.168
NOTE_ ์ฌ์ดํท๋ฐ์ ์ด์ง ํธ๋ฆฌ๋ง ๋ง๋๋ CART ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉ. ๊ทธ๋ฌ๋ฏ๋ก ๋ฆฌํ ๋ ธ๋ ์ธ์ ๋ชจ๋ ๋ ธ๋๋ ์์ ๋ ธ๋๋ฅผ ๋ ๊ฐ์ฉ ๊ฐ์ง
[๊ทธ๋ฆผ 6-2]๋ ์ด ๊ฒฐ์ ํธ๋ฆฌ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๋ณด์ฌ์ค
๋ชจ๋ธ ํด์: ํ์ดํธ๋ฐ์ค์ ๋ธ๋๋ฐ์ค
์๋ฅผ ๋ค์ด ๊ธธ์ด๊ฐ 5cm์ด๊ณ ๋๋น๊ฐ 1.5cm์ธ ๊ฝ์์ ๋ฐ๊ฒฌํ๋ค๊ณ ๊ฐ์
tree_clf.predict_proba([[5, 1.5]])
array([[0. , 0.90740741, 0.09259259]])
ํด๋์ค๋ฅผ ํ๋ ์์ธกํ๋ค๋ฉด ๊ฐ์ฅ ๋์ ํ๋ฅ ์ ๊ฐ์ง Iris-Versicolor(ํด๋์ค 1)๋ฅผ ์ถ๋ ฅ
tree_clf.predict([[5, 1.5]])
array([1])
์ด ๊ณผ์ ์ (max_depth ๋งค๊ฐ๋ณ์๋ก ์ ์๋) ์ต๋ ๊น์ด๊ฐ ๋๋ฉด ์ค์งํ๊ฑฐ๋ ๋ถ์๋๋ฅผ ์ค์ด๋ ๋ถํ ์ ์ฐพ์ ์ ์์ ๋ ๋ฉ์ถ๊ฒ ๋จ
๋ค๋ฅธ ๋ช ๊ฐ์ ๋งค๊ฐ๋ณ์๋ ์ค์ง ์กฐ๊ฑด์ ๊ด์ฌ(min_samples_split, min_samples_leaf, min_weight_fraction_leaf, max_leaf_nodes)
CAUTION_ CART ์๊ณ ๋ฆฌ์ฆ์ ํ์์ ์๊ณ ๋ฆฌ์ฆgreedy algorithm
โโโโโโย ๋งจ ์ ๋ฃจํธ ๋
ธ๋์์ ์ต์ ์ ๋ถํ ์ ์ฐพ์ผ๋ฉฐ ๊ฐ ๋จ๊ณ์์ ์ด ๊ณผ์ ์ ๋ฐ๋ณต. ํ์ฌ ๋จ๊ณ์ ๋ถํ ์ด ๋ช ๋จ๊ณ๋ฅผ ๊ฑฐ์ณ ๊ฐ์ฅ ๋ฎ์ ๋ถ์๋๋ก ์ด์ด์ง ์ ์์์ง ๊ณ ๋ คํ์ง ์์
โโโโโโย ํ์์ ์๊ณ ๋ฆฌ์ฆ์ ์ข
์ข
๋ฉ๋ํ ๋งํ ํผ๋ฅญํ ์๋ฃจ์
์ ๋ง๋ค์ด๋ด์ง๋ง ์ต์ ์ ์๋ฃจ์
์ ๋ณด์ฅํ์ง๋ ์์
์ด ๋ฌธ์ ๋ O(exp(m)) ์๊ฐ์ด ํ์ํ๊ณ ๋งค์ฐ ์์ ํ๋ จ ์ธํธ์๋ ์ ์ฉํ๊ธฐ ์ด๋ ค์
๊ทธ๋ฌ๋ฏ๋ก '๋ฉ๋ํ ๋งํ ์ข์ ์๋ฃจ์
'์ผ๋ก๋ง ๋ง์กฑํด์ผ ํจ
ํ์ง๋ง ํ๋ จ ์ธํธ๊ฐ ํด ๊ฒฝ์ฐ ์๋๊ฐ ๋ง์ด ๋๋ ค์ง
[๊ทธ๋ฆผ 6-1]์์ ๊น์ด 2์ ์ผ์ชฝ ๋ ธ๋์ ์ํธ๋กํผ๋ -$\frac{49}{54}$log2($\frac{49}{54}$)-$\frac{5}{54}$log2($\frac{5}{54}$) โ 0.445
[๊ทธ๋ฆผ 6-3]์ moons ๋ฐ์ดํฐ์ ์ ํ๋ จ์ํจ ๋ ๊ฐ์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ๋ณด์ฌ์ค
๊ฒฐ์ ํธ๋ฆฌ๋ ํ๊ท ๋ฌธ์ ์๋ ์ฌ์ฉํ ์ ์์. ๋ค์์ ์ฌ์ดํท๋ฐ์ DecisionTreeRegressor๋ฅผ ์ฌ์ฉํด ํ๊ท ํธ๋ฆฌ๋ฅผ ๋ง๋๋ ์ฝ๋
# 2์ฐจ์์ผ๋ก ๋ง๋ ๋ฐ์ดํฐ์
+ ์ก์
np.random.seed(42)
m = 200
X = np.random.rand(m, 1)
y = 4 * (X - 0.5) ** 2
y = y + np.random.randn(m, 1) / 10
from sklearn.tree import DecisionTreeRegressor
tree_reg = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg.fit(X, y)
DecisionTreeRegressor(criterion='mse', max_depth=2, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=42, splitter='best')
export_graphviz(
tree_reg,
out_file=image_path("regression_tree.dot"),
feature_names=["x1"],
rounded=True,
filled=True
)
import graphviz
with open("images/decision_trees/regression_tree.dot") as f:
dot_graph = f.read()
dot = graphviz.Source(dot_graph)
dot.format = 'png'
dot.render(filename='regression_tree', directory='images/decision_trees', cleanup=True)
dot
๋ถ๋ฅ ํธ๋ฆฌ์ ์ฃผ์ํ ์ฐจ์ด์
์ด ๋ชจ๋ธ์ ์์ธก์ ์๋ [๊ทธ๋ฆผ 6-5]์ ์ผ์ชฝ์ ๋ํ๋ ์๊ณ , max_depth=3์ผ๋ก ์ค์ ํ๋ฉด ์ค๋ฅธ์ชฝ ๊ทธ๋ํ์ ๊ฐ์ ์์ธก์ ์ป๊ฒ ๋จ
๋ถ๋ฅ์์์ ๊ฐ์ด ํ๊ท ์์ ์์๋ ๊ฒฐ์ ํธ๋ฆฌ๊ฐ ๊ณผ๋์ ํฉ๋๊ธฐ ์ฌ์
๊ฒฐ์ ํธ๋ฆฌ์ ์ ํ์ฌํญ
์๋ [๊ทธ๋ฆผ 6-7]์ ์ผ์ชฝ ๊ฒฐ์ ํธ๋ฆฌ๋ ์ฝ๊ฒ ๋ฐ์ดํฐ์ ์ ๊ตฌ๋ถํ์ง๋ง, ๋ฐ์ดํฐ์ ์ 45ยฐ ํ์ ํ ์ค๋ฅธ์ชฝ์ ๊ฒฐ์ ํธ๋ฆฌ๋ ๋ถํ์ํ๊ฒ ๊ตฌ๋ถ๊ตฌ๋ถํด์ ธ ์ ์ผ๋ฐํ๋ ๊ฒ ๊ฐ์ง ์์
ํ๋ จ ์ธํธ์์ ๊ฐ์ฅ ๋์ Iris-Versicolor(๊ฝ์ ๊ธธ์ด๊ฐ 4.8cm์ด๊ณ ๋๋น๊ฐ 1.8cm์ธ ๊ฒ)๋ฅผ ์ ๊ฑฐํ๊ณ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๋ จ์ํค๋ฉด [๊ทธ๋ฆผ 6-8]๊ณผ ๊ฐ์ ๋ชจ๋ธ์ ์ป๊ฒ ๋จ
์ด์ ์ ๋ง๋ ๊ฒฐ์ ํธ๋ฆฌ(๊ทธ๋ฆผ 6-2)์๋ ๋งค์ฐ ๋ค๋ฅธ ๋ชจ์ต์
1.๋ฐฑ๋ง ๊ฐ์ ์ํ์ ๊ฐ์ง ํ๋ จ ์ธํธ์์ (๊ท์ ์์ด) ํ๋ จ์ํจ ๊ฒฐ์ ํธ๋ฆฌ์ ๊น์ด๋ ๋๋ต ์ผ๋ง์ผ๊น์?
2.ํ ๋ ธ๋์ ์ง๋ ๋ถ์๋๊ฐ ๋ณดํต ๊ทธ ๋ถ๋ชจ ๋ ธ๋๋ณด๋ค ์์๊น์, ์๋๋ฉด ํด๊น์? ์ผ๋ฐ์ ์ผ๋ก ์๊ฑฐ๋ ํด๊น์, ์๋๋ฉด ํญ์ ์๊ฑฐ๋ ํด๊น์?
์๋ฅผ ๋ค์ด ํด๋์ค A์ ์ํ์ 4๊ฐ, ํด๋์ค B์ ์ํ์ 1๊ฐ ํฌํจํ ๋ ธ๋๋ฅผ ์๊ฐํด๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ ธ๋์ ์ง๋ ๋ถ์๋๋ 1-$\left ( \frac{1}{5} \right )^2$-$\left ( \frac{4}{5} \right )^2$ = 0.32 ์ ๋๋ค. ์ด ๋ฐ์ดํฐ์ ์ 1์ฐจ์์ด๊ณ A, B, A, A, A ์์ผ๋ก ๋์ด์ ์๋ค๊ณ ๊ฐ์ ํ๊ฒ ์ต๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ด ์ด ๋ ธ๋๋ฅผ ๋ ๋ฒ์งธ ์ํ ์ดํ์ ๋๋์ด ์ํ A, B๋ฅผ ๊ฐ์ง ์์ ๋ ธ๋์ ์ํ A, A, A๋ฅผ ๊ฐ์ง ์์ ๋ ธ๋๋ฅผ ๋ง๋ญ๋๋ค. ์ฒซ ๋ฒ์งธ ์์ ๋ ธ๋์ ์ง๋ ๋ถ์๋๋ 1-$\left ( \frac{1}{2} \right )^2$-$\left ( \frac{1}{2} \right )^2$ = 0.5๊ฐ ๋์ด ๋ถ๋ชจ๋ณด๋ค ํฝ๋๋ค. ์ด๋ ๋ค๋ฅธ ๋ ธ๋๊ฐ ์์ ๋ ธ๋๊ฐ ๋๋ ๊ฒ์ ๋ํ ๋๊ฐ์ ๋๋ค. ๊ฐ์ค์น๋ฅผ ์ค ์ ์ฒด ์ง๋ ๋ถ์๋๋ $\frac{2}{5}$ร0.5 + $\frac{3}{5}$ร0 = 0.2๊ฐ ๋์ด ๋ถ๋ชจ์ ์ง๋ ๋ถ์๋๋ณด๋ค ๋ฎ์ต๋๋ค.
3.๊ฒฐ์ ํธ๋ฆฌ๊ฐ ํ๋ จ ์ธํธ์ ๊ณผ๋์ ํฉ๋์๋ค๋ฉด max_depth๋ฅผ ์ค์ด๋ ๊ฒ์ด ์ข์๊น์?
4.๊ฒฐ์ ํธ๋ฆฌ๊ฐ ํ๋ จ ์ธํธ์ ๊ณผ์์ ํฉ๋์๋ค๋ฉด ์ ๋ ฅ ํน์ฑ์ ์ค์ผ์ผ์ ์กฐ์ ํ๋ ๊ฒ์ด ์ข์๊น์?
5.๋ฐฑ๋ง ๊ฐ์ ์ํ์ ๊ฐ์ง ํ๋ จ ์ธํธ์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๋ จ์ํค๋ ๋ฐ ํ ์๊ฐ์ด ๊ฑธ๋ ธ๋ค๋ฉด, ์ฒ๋ง ๊ฐ์ ์ํ์ ๊ฐ์ง ํ๋ จ ์ธํธ์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๋ จ์ํค๋ ๋ฐ๋ ๋๋ต ์ผ๋ง๋ ๊ฑธ๋ฆด๊น์?
6.์ญ๋ง ๊ฐ์ ์ํ์ ๊ฐ์ง ํ๋ จ ์ธํธ๊ฐ ์๋ค๋ฉด presort=True๋ก ์ง์ ํ๋ ๊ฒ์ด ํ๋ จ ์๋๋ฅผ ๋์ผ๊น์?
7.moons ๋ฐ์ดํฐ์ ์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๋ จ์ํค๊ณ ์ธ๋ฐํ๊ฒ ํ๋ํด๋ณด์ธ์.
a. make_moons(n_samples=1000, noise=0.4)๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ์
์ ์์ฑํฉ๋๋ค.
random_state=42๋ฅผ ์ง์ ํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ผ์ ํ๊ฒ ๋ง๋ญ๋๋ค:
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=10000, noise=0.4, random_state=42)
b. ์ด๋ฅผ train_test_split()์ ์ฌ์ฉํด ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ๋ก ๋๋๋๋ค.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
c. DecisionTreeClassifier์ ์ต์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฐพ๊ธฐ ์ํด ๊ต์ฐจ ๊ฒ์ฆ๊ณผ ํจ๊ป ๊ทธ๋ฆฌ๋ ํ์์ ์ํํฉ๋๋ค.(GridSearchCV๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค).
โ ํํธ: ์ฌ๋ฌ ๊ฐ์ง max_leaf_nodes ๊ฐ์ ์๋ํด๋ณด์ธ์.
from sklearn.model_selection import GridSearchCV
params = {'max_leaf_nodes': list(range(2, 100))}
grid_search_cv = GridSearchCV(DecisionTreeClassifier(random_state=42), params, cv=3, n_jobs=-1)
grid_search_cv.fit(X_train, y_train)
grid_search_cv.best_params_
{'max_leaf_nodes': 17}
d. ์ฐพ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํด ์ ์ฒด ํ๋ จ ์ธํธ์ ๋ํด ๋ชจ๋ธ์ ํ๋ จ์ํค๊ณ ํ ์คํธ ์ธํธ์์ ์ฑ๋ฅ์ ์ธก์ ํฉ๋๋ค. ๋๋ต 85~87%์ ์ ํ๋๊ฐ ๋์ฌ ๊ฒ์ ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก GridSearchCV๋ ์ ์ฒด ํ๋ จ ์ธํธ๋ก ์ฐพ์ ์ต์ ์ ๋ชจ๋ธ์ ๋ค์ ํ๋ จ์ํต๋๋ค(refit=False๋ก ์ง์ ํด์ ๋ฐ๊ฟ ์ ์์ต๋๋ค). ๊ทธ๋์ ๋ณ๋๋ก ์์ ํ ํ์๊ฐ ์์ต๋๋ค. ๋ชจ๋ธ์ ์ ํ๋๋ฅผ ๋ฐ๋ก ํ๊ฐํ ์ ์์ต๋๋ค:
from sklearn.metrics import accuracy_score
y_pred = grid_search_cv.predict(X_test)
accuracy_score(y_test, y_pred)
0.8695
8.๋๋ค ํฌ๋ ์คํธ๋ฅผ ๋ง๋ค์ด๋ณด์ธ์.
a. ์ด์ ์ฐ์ต๋ฌธ์ ์ ์ด์ด์, ํ๋ จ ์ธํธ์ ์๋ธ์
์ 1,000๊ฐ ์์ฑํฉ๋๋ค. ๊ฐ๊ฐ์ ๋ฌด์์๋ก ์ ํ๋ 100๊ฐ์ ์ํ์ ๋ด๊ณ ์์ต๋๋ค.
โย ํํธ: ์ฌ์ดํท๋ฐ์ ShuffleSplit์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
from sklearn.model_selection import ShuffleSplit
n_trees = 1000
n_instances = 100
mini_sets = []
rs = ShuffleSplit(n_splits=n_trees, test_size=len(X_train) - n_instances, random_state=42)
for mini_train_index, mini_test_index in rs.split(X_train):
X_mini_train = X_train[mini_train_index]
y_mini_train = y_train[mini_train_index]
mini_sets.append((X_mini_train, y_mini_train))
b. ์์์ ์ฐพ์ ์ต์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํด ๊ฐ ์๋ธ์
์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๋ จ์ํต๋๋ค. ํ
์คํธ ์ธํธ๋ก ์ด 1,000๊ฐ์ ๊ฒฐ์ ํธ๋ฆฌ๋ฅผ ํ๊ฐํฉ๋๋ค.
โย ๋ ์์ ๋ฐ์ดํฐ์
์์ ํ๋ จ๋์๊ธฐ ๋๋ฌธ์ ์ด ๊ฒฐ์ ํธ๋ฆฌ๋ ์์ ๋ง๋ ๊ฒฐ์ ํธ๋ฆฌ๋ณด๋ค ์ฑ๋ฅ์ด ๋จ์ด์ ธ ์ฝ 80%์ ์ ํ๋๋ฅผ ๋
๋๋ค.
from sklearn.base import clone
forest = [clone(grid_search_cv.best_estimator_) for _ in range(n_trees)]
accuracy_scores = []
for tree, (X_mini_train, y_mini_train) in zip(forest, mini_sets):
tree.fit(X_mini_train, y_mini_train)
y_pred = tree.predict(X_test)
accuracy_scores.append(accuracy_score(y_test, y_pred))
np.mean(accuracy_scores)
0.8054499999999999
c. ์ด์ ๋ง์ ์ ๋ถ๋ฆด ์ฐจ๋ก์
๋๋ค. ๊ฐ ํ
์คํธ ์ธํธ ์ํ์ ๋ํด 1,000๊ฐ์ ๊ฒฐ์ ํธ๋ฆฌ ์์ธก์ ๋ง๋ค๊ณ ๋ค์๋ก ๋์จ ์์ธก๋ง ์ทจํฉ๋๋ค(์ฌ์ดํ์ด์ mode() ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค).
โย ๊ทธ๋ฌ๋ฉด ํ
์คํธ ์ธํธ์ ๋ํ ๋ค์๊ฒฐ ์์ธกmajority-vote prediction์ด ๋ง๋ค์ด์ง๋๋ค.
Y_pred = np.empty([n_trees, len(X_test)], dtype=np.uint8) # 1000*2000 empty ๋ฐฐ์ด ์ ์ธ
for tree_index, tree in enumerate(forest): # ๋ด์ฅํจ์ enumerate(): ์์๊ฐ ์๋ ์๋ฃํ์ ๊ฐ์ ์ธ๋ฑ์ค์ ํจ๊ป ๋ฐํ
Y_pred[tree_index] = tree.predict(X_test)
print(Y_pred.shape)
Y_pred
(1000, 2000)
array([[0, 1, 0, ..., 0, 0, 1], [1, 1, 1, ..., 0, 0, 0], [1, 1, 0, ..., 0, 0, 1], ..., [1, 1, 0, ..., 0, 0, 0], [1, 1, 0, ..., 0, 0, 1], [1, 1, 0, ..., 0, 0, 0]], dtype=uint8)
from scipy.stats import mode
y_pred_majority_votes, n_votes = mode(Y_pred, axis=0) # ์ต๋น๊ฐ๊ณผ ๋น๋์ ๋ฐํ
y_pred_majority_votes
array([[1, 1, 0, ..., 0, 0, 0]], dtype=uint8)
n_votes
array([[951, 912, 963, ..., 919, 994, 602]])
d. ํ ์คํธ ์ธํธ์์ ์ด ์์ธก์ ํ๊ฐํฉ๋๋ค. ์์ ๋ง๋ ๋ชจ๋ธ๋ณด๋ค ์กฐ๊ธ ๋์(์ฝ 0.5~1.5% ์ ๋) ์ ํ๋๋ฅผ ์ป๊ฒ ๋ ๊ฒ์ ๋๋ค. ์ถํํฉ๋๋ค. ๋๋ค ํฌ๋ ์คํธ ๋ถ๋ฅ๊ธฐ๋ฅผ ํ๋ จ์์ผฐ์ต๋๋ค!
accuracy_score(y_test, y_pred_majority_votes.reshape([-1]))
0.872