Random Forest : iris ๋ฐ์ดํฐ์ ํ์ต, ์๊ฐํ
1. ๋๋คํฌ๋ ์คํธ
์ฌ๋ฌ ๊ฐ์ ์์ฌ๊ฒฐ์ ๋๋ฌด ๋ชจ๋ธ์ ์์ฑํ๊ณ , ๊ฐ ๋ชจ๋ธ์ ์์ธก ๊ฒฐ๊ณผ๋ฅผ ์ข ํฉ -> ์ต์ข ๊ฒฐ์ ์ ๋ด๋ฆฌ๋ ์์๋ธ ๊ธฐ๋ฒ ์ค ํ๋
์ฃผ๋ก ๋ถ๋ฅ, ํ๊ท ๋ฌธ์ ์ ์ฐ์, ๊ฐ๋ณ ๋๋ฌด์ ์ฝ์ ์ ๋ณด์, ์ ์ฒด ๋ชจ๋ธ์ ์ ํ๋์ ์ผ๋ฐํ ์ฑ๋ฅ์ ๋์
< ๋ชฉ์ >
- ์ฌ๋ฌ ๊ฒฐ์ ๋๋ฌด๋ฅผ ์์ฑํ์ฌ ๊ณผ์ ํฉ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ ๋ฐฐ์ใด
- ๋๋ค ํฌ๋ ์คํธ ๋ชจ๋ธ ๋ด๋ถ ๊ตฌ์กฐ (๊ฒฐ์ ๋๋ฌด)๋ฅผ ์๊ฐํํ์ฌ ์ดํด๋ ฅ์ ๋์ด๊ณ ์ ํจ
2. ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
pandas : ๋ฐ์ดํฐ ํ๋ ์ ๋ค๋ฃจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋ฐ์ดํฐ ๋ถ์, ์ ์ฒ๋ฆฌ ์์
numpy : ๋ค์ฐจ์ ๋ฐฐ์ด ์ฐ์ฐ ๋ฐ ์์น ๊ณ์ฐ์ ํต์ฌ
matplotlib.pyplot : ๋ฐ์ดํฐ ์๊ฐํ๋ฅผ ์ํ ๋ํ์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
sklearn.datasets.load_iris : ๋จธ์ ๋ฌ๋ ํ์ต์ฉ ๋ฐ์ดํฐ์
sklearn.ensemble.RandomForestClassifier : ๋๋ค ํฌ๋ ์คํธ ๋ถ๋ฅ ๋ชจ๋ธ ๊ตฌํ
sklearn.tree.plot.tree : ์์ฌ๊ฒฐ์ ๋๋ฌด ์๊ฐํ
< ๋ถ์ ํ๋ฆ >
๋ฐ์ดํฐ ๋ก๋
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
๋ชจ๋ธ ํ์ต (RandomForestClassifier)
- n_estimators : ํธ๋ฆฌ์ ๊ฐ์ ์ค์
max_depth : ๊ฐ ๊ฒฐ์ ๋๋ฌด์ ์ต๋ ๊น์ด ์ ํ
๋ชจ๋ธ ์๊ฐํ
3. ์ฝ๋ ๋ฏ์ด๋จน๊ธฐ
# ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import plot_tree
# ๋ฐ์ดํฐ ๋ก๋
iris = load_iris()
# ๋
๋ฆฝ๋ณ์(X), ์ข
์๋ณ์(y) ์ค์
X = iris.data[:, 2:4] # ๊ฝ์ ๊ธธ์ด์ ๋์ด๋ง ์ฌ์ฉ
y = iris.target # ๋ถ๊ฝ ํ์ข
(0, 1, 2)
# ๋ชจ๋ธ ์์ฑ (๋๋คํฌ๋ ์คํธ)
rf = RandomForestClassifier(
n_estimators=3, # 3๊ฐ์ ๊ฒฐ์ ๋๋ฌด๋ฅผ ์์ฑ
max_depth=3, # ๊ฐ ๋๋ฌด์ ์ต๋ ๊น์ด๋ 3
random_state=42 # ๊ฒฐ๊ณผ ์ฌํ์ฑ์ ์ํด ๋์ ์ค์
)
# ๋ชจ๋ธ ํ์ต
rf.fit(X, y)
# ์๊ฐํ๋ฅผ ์ํ ์ค์
plt.figure(figsize=(20, 5))
# ๊ฐ ๊ฒฐ์ ๋๋ฌด ์๊ฐํ
for i in range(len(rf.estimators_)):
plt.subplot(1, len(rf.estimators_), i+1) # subplot์ ๊ฐ๋ก๋ก ๋์ด
plot_tree(
rf.estimators_[i], # ๋๋คํฌ๋ ์คํธ์ ๊ฐ ํธ๋ฆฌ
feature_names=iris.feature_names[2:4],
class_names=iris.target_names,
filled=True,
rounded=True
)
plt.title(f'Tree {i+1}') # ๊ฐ subplot ์ ๋ชฉ
plt.tight_layout() # ์๋ธํ๋กฏ ๊ฐ๊ฒฉ ์๋์กฐ์
plt.show()
4. ๋ชจ๋ธ ๋ถ์ ์ธ์ฌ์ดํธ
1.ํธ๋ฆฌ๋ณ ์ฃผ์ ํน์ง, ํจํด
<Tree1>
์ฒซ ๋ฒ์งธ ๋ ธ๋๋ ๊ฝ์ ๋์ด (petal width)๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถํ , ๊ฐ์ด 0.8cm ์ดํ์ด๋ฉด setosa๋ก ๋ถ๋ฅ๋จ
์ดํ ๊ฝ์ ๊ธธ์ด (petal length)์ ๊ฝ์ ๋์ด๋ฅผ ๊ธฐ์ค์ผ๋ก versicolor์ virginica๋ฅผ ๊ตฌ๋ถํจ
์ง๋์ง์ ๋ฎ์ ๋ ธ๋๊ฐ ๋ณด์ -> ๋ช ํํ ํด๋์ค ๊ตฌ๋ถ์ด ์ด๋ฃจ์ด์ง๊ณ ์์
<Tree 2, 3>
2 -> ์ง๋์ง์0.08์์ ์ฝ๊ฐ์ ํด๋์ค ํผ์ฌ๊ฐ ๋ฐ์ํ์ง๋ง ์ ๋ฐ์ ์ผ๋ก ๋ช ํํ ๊ธฐ์ค์ผ๋ก ์์ ์ ์ผ๋ก ๋ถ๋ฅ
3 -> ์ง๋์ง์ 0.0 ์๋ฒฝํ ํ ํด๋์ค๋ง์ ๋ํ๋ (์ ๋ขฐ๋ ๋งค์ฐ ๋์)
+) ์ง๋์ง์๋ ํด๋น ๋ ธ๋์์ ํด๋์ค๊ฐ ์ผ๋ง๋ ์์ฌ์๋์ง ๋ํ๋. (0์ ๊ฐ๊น์ธ ์๋ก ๋ ธ๋์ ์๋๊ฐ ๋์์ง๋ค๋ ๊ฒ์ ์๋ฏธ)
ํ์ ๋ ธ๋๋ก ๊ฐ์๋ก ์ง๋์ง์๊ฐ ๋ฎ์์ ธ ๋ช ํํ ๋ถ๋ฅ๊ฐ ์ด๋ฃจ์ด์ง
5. ๋ฐฐ์ด ์
ํ์ดํผํ๋ผ๋ฏธํฐ์ ์ ์ฉ?
์ค์ ์ค๋ฌด์์๋ 3๊ฐ์ ํธ๋ฆฌ๋ก๋ ์ถฉ๋ถํ์ง ์์. 100๊ฐ ์ด์์ ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํด ์์ ์ฑ ํ๋ณด
max_depth๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ ํฌ๊ธฐ์ ๋ณต์ก์ฑ์ ๋ฐ๋ผ ์กฐ์ ๋จ. ๊ณผ์ ํฉ ๋ฐฉ์ง๋ฅผ ์ํด 5~20 ์ฌ์ด์์ ์ต์ ์ ๊ฐ์ ์ฐพ๋ ๊ฒ์ด ์ผ๋ฐ์
์๋ ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋ ๋์ ํด๋ณด๊ธฐ ( GridSearchCV, RandomizedSearchCV )
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 10, None],
'min_samples_split': [2, 5, 10]
}
grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5)
grid_search.fit(X, y)
print(grid_search.best_params_)
๋ฐ์ดํฐ ๋ถ๊ท ํ ์กฐ์ฌ
์ค์ ๋ฐ์ดํฐ์์๋ ํด๋์ค ๋ถ๊ท ํ (ํ ํด๋์ค ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ๋ง๊ฑฐ๋, ์ ์ ๊ฒฝ์ฐ) ์์ฃผ ๋ฐ์
์ด๋, class_weight = 'balanced' ์ต์ ์ ์ฌ์ฉํ๊ฑฐ๋ SMOTE ๊ธฐ๋ฒ์ ํ์ฉํด ๋ฐ์ดํฐ ๊ท ํ์ ๋ง์ถ๋ ๊ฒ์ด ํ์
ํน์ง ์ค์๋ (Feature importance) ๊ธฐ๋ฅ ํ์ฉํ๊ธฐ
์ด๋ค ๋ณ์๊ฐ ์ค์ํ ์ง ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์์
์ )
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
plt.bar(range(X.shape[1]), importances[indices])
plt.xticks(range(X.shape[1]), iris.feature_names[2:4], rotation=45)
plt.title("Feature Importance")
plt.show()