개요

흔히 '트리' 를 생각하면 알고리즘의 트리 구조를 많이 떠올리곤 합니다.
하지만 기계학습 분야에도 트리 구조가 쓰이는데, 바로 의사를 결정할 때 입니다.
cancer 데이터 살펴보기
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
cancer = load_breast_cancer()
print("cancer_dataset의 키: \n", cancer.keys())
# cancer_dataset의 키:
# dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
이번에는 sklearn에서 제공하는 데이터 중 하나인 '위스콘신 유방암 데이터'를 한번 사용해 보겠습니다.
의료분야에서 머신러닝이 어떻게 사용되는지 알 수 있는 굉장히 유명한 데이터입니다. 상당히 다양한 데이터들이 있네요.
cancer.target_names
# array(['malignant', 'benign'], dtype='<U9')
cancer에 어떤 종류가 있는지 살펴 보는 코드입니다.
malignant는 '악의 있는' 이라는 뜻을 가진, 악성(암)이고, benign '온화한' 이라는 뜻을 가진, 종기, 혹 따위를 의미합니다.
plt.figure(figsize=(30, 30))
mask = np.zeros_like(cancer_df.corr())
mask[np.triu_indices_from(mask)] = True
sns.heatmap(cancer_df.corr(), vmax=0.5, linewidths=0.2, linecolor="white", mask=mask, annot=True)
plt.show()

위 사진은 맨 위의 'mean radius'가 각각의 값들과 어느 정도의 관계를 가지고 있는지를 나타낸 그래프입니다.
DecisionTreeClassifier 학습
x_train, x_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=42)
항상 그랬듯이 학습 / 테스트 데이터를 분할해 줍니다.
(저번 글부터 계속 등장하고 있는 코드입니다.)
tree = DecisionTreeClassifier()
tree.fit(x_train, y_train)
의사 결정 트리를 사용할 것이기 때문에 DecisionTreeClassifier에 데이터들을 넣어줍니다.
print("훈련 세트 정확도: {:.3f}".format(tree.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(tree.score(x_test, y_test)))
# 훈련 세트 정확도: 1.000
# 테스트 세트 정확도: 0.923
뭔가 어느정도 학습이 된거 같은데, 정확도가 조금 낮은거 같습니다.
어떻게 하면 정확도를 더 올릴 수 있을까요?
tree = DecisionTreeClassifier(max_depth=4, random_state=0)
tree.fit(x_train, y_train)
# DecisionTreeClassifier(max_depth=4, random_state=0)
여기서 바로 가지치기가 등장합니다.
의사를 결정할 때, 너무 많은 질문을 하게 되면 점점 깊숙하게 들어가게 되어 원래 찾고자 하는 것에서 벗어날 수 있기 때문에 가지치기를 하게 됩니다.
max_depth의 숫자를 바꾸게 되면 정확도가 달라질 수 있습니다.
print("훈련 세트 정확도: {:.3f}".format(tree.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(tree.score(x_test, y_test)))
# 훈련 세트 정확도: 0.988
# 테스트 세트 정확도: 0.951
가지치기를 하니 정확도가 상승하였습니다.
from sklearn.tree import plot_tree
plt.figure(figsize=(20, 20))
plot_tree(tree, filled=True, feature_names=cancer.feature_names)
plt.show()

위 사진은 저희가 구현한 기계학습의 의사 결정 트리입니다.
아까 지정한 max_depth만큼만 분류한 것을 확인하실 수 있습니다.
RandomForestClassifier 학습
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(n_estimators=5, random_state=2)
forest.fit(x_train, y_train)
# RandomForestClassifier(n_estimators=5, random_state=2)
하지만 DecisionTreeClassifier보다 더 성능이 좋은 것이 하나 있습니다.
바로 RandomForestClassifier, 랜덤 포레스트입니다.
print("훈련 세트 정확도: {:.3f}".format(forest.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(forest.score(x_test, y_test)))
# 훈련 세트 정확도: 1.000
# 테스트 세트 정확도: 0.958
아까 사용한 DecisionTreeClassifier보다 0.07 더 향상된 것을 보실 수 있습니다.
from sklearn.ensemble import VotingClassifier # voting 앙상블 기법
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
for_clf = RandomForestClassifier(n_estimators=5, random_state=2)
ada_clf = AdaBoostClassifier(n_estimators=10, random_state=2)
gb_clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=2)
vo_clf = VotingClassifier(estimators=[("KNN", knn_clf), ("FOREST", for_clf),
("ADA", ada_clf), ("GRA", gb_clf)], voting="soft")
이번에는 여러가지 분류 기법들의 정확도를 비교해 보겠습니다.
gb_clf(그라디언트 부스팅)는 여러 개의 결정 트리를 묶어 강력한 모델을 만들고, 이진 트리의 오차를 보완하는 방식입니다.
from sklearn.metrics import accuracy_score
clf = [vo_clf, knn_clf, for_clf, ada_clf, gb_clf]
for clf in clf :
clf.fit(x_train, y_train)
pred = clf.predict(x_test)
name = clf.__class__.__name__
print(f"{name} 정확도 : {accuracy_score(y_test, pred):.5f}")
# VotingClassifier 정확도 : 0.96503
# KNeighborsClassifier 정확도 : 0.93007
# RandomForestClassifier 정확도 : 0.95804
# AdaBoostClassifier 정확도 : 0.93706
# GradientBoostingClassifier 정확도 : 0.95804
RandomForestClassifier가 0.95804로 가장 높은 정확도를 보이고 있습니다.
마지막으로, 이것이 암인지, 아니면 단순히 혹 종류인지 분류하는 모델을 구현해 보겠습니다.
predict = vo_clf.predict(x_test)
proba = vo_clf.predict_proba(x_test)
for i in range(len(predict)) :
print(f"예측 : {predict[i]}, 확률 : {proba[i]}")
# 예측 : 1, 확률 : [0.03866417 0.96133583]
# 예측 : 0, 확률 : [0.99852196 0.00147804]
# 예측 : 1, 확률 : [0.10775523 0.89224477]
# 예측 : 1, 확률 : [0.0760093 0.9239907]
# 예측 : 0, 확률 : [0.6755587 0.3244413]
# ...
0은 암, 1은 종기나 혹 따위를 뜻합니다.
from sklearn.metrics import recall_score
recall = recall_score(y_test, pred)
print(f"재현율 : {recall}")
# 재현율 : 0.9888888888888889
재현율이 상당히 높게 나왔습니다. 그러므로 잘 학습된 모델이라 말할 수 있겠습니다.
'🧠 인공지능' 카테고리의 다른 글
패턴 인식, 자료 분석 - SVM (0) | 2022.10.24 |
---|---|
FinanceDataReader로 주식 예측하기 (0) | 2022.09.21 |
경사하강법을 통해 오차 줄이기 (0) | 2022.09.19 |
KNN의 한계를 해결한 선형 회귀 (0) | 2022.09.07 |
Naive Bayes과 Iris (0) | 2022.09.04 |
개요

흔히 '트리' 를 생각하면 알고리즘의 트리 구조를 많이 떠올리곤 합니다.
하지만 기계학습 분야에도 트리 구조가 쓰이는데, 바로 의사를 결정할 때 입니다.
cancer 데이터 살펴보기
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
cancer = load_breast_cancer()
print("cancer_dataset의 키: \n", cancer.keys())
# cancer_dataset의 키:
# dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
이번에는 sklearn에서 제공하는 데이터 중 하나인 '위스콘신 유방암 데이터'를 한번 사용해 보겠습니다.
의료분야에서 머신러닝이 어떻게 사용되는지 알 수 있는 굉장히 유명한 데이터입니다. 상당히 다양한 데이터들이 있네요.
cancer.target_names
# array(['malignant', 'benign'], dtype='<U9')
cancer에 어떤 종류가 있는지 살펴 보는 코드입니다.
malignant는 '악의 있는' 이라는 뜻을 가진, 악성(암)이고, benign '온화한' 이라는 뜻을 가진, 종기, 혹 따위를 의미합니다.
plt.figure(figsize=(30, 30))
mask = np.zeros_like(cancer_df.corr())
mask[np.triu_indices_from(mask)] = True
sns.heatmap(cancer_df.corr(), vmax=0.5, linewidths=0.2, linecolor="white", mask=mask, annot=True)
plt.show()

위 사진은 맨 위의 'mean radius'가 각각의 값들과 어느 정도의 관계를 가지고 있는지를 나타낸 그래프입니다.
DecisionTreeClassifier 학습
x_train, x_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=42)
항상 그랬듯이 학습 / 테스트 데이터를 분할해 줍니다.
(저번 글부터 계속 등장하고 있는 코드입니다.)
tree = DecisionTreeClassifier()
tree.fit(x_train, y_train)
의사 결정 트리를 사용할 것이기 때문에 DecisionTreeClassifier에 데이터들을 넣어줍니다.
print("훈련 세트 정확도: {:.3f}".format(tree.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(tree.score(x_test, y_test)))
# 훈련 세트 정확도: 1.000
# 테스트 세트 정확도: 0.923
뭔가 어느정도 학습이 된거 같은데, 정확도가 조금 낮은거 같습니다.
어떻게 하면 정확도를 더 올릴 수 있을까요?
tree = DecisionTreeClassifier(max_depth=4, random_state=0)
tree.fit(x_train, y_train)
# DecisionTreeClassifier(max_depth=4, random_state=0)
여기서 바로 가지치기가 등장합니다.
의사를 결정할 때, 너무 많은 질문을 하게 되면 점점 깊숙하게 들어가게 되어 원래 찾고자 하는 것에서 벗어날 수 있기 때문에 가지치기를 하게 됩니다.
max_depth의 숫자를 바꾸게 되면 정확도가 달라질 수 있습니다.
print("훈련 세트 정확도: {:.3f}".format(tree.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(tree.score(x_test, y_test)))
# 훈련 세트 정확도: 0.988
# 테스트 세트 정확도: 0.951
가지치기를 하니 정확도가 상승하였습니다.
from sklearn.tree import plot_tree
plt.figure(figsize=(20, 20))
plot_tree(tree, filled=True, feature_names=cancer.feature_names)
plt.show()

위 사진은 저희가 구현한 기계학습의 의사 결정 트리입니다.
아까 지정한 max_depth만큼만 분류한 것을 확인하실 수 있습니다.
RandomForestClassifier 학습
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(n_estimators=5, random_state=2)
forest.fit(x_train, y_train)
# RandomForestClassifier(n_estimators=5, random_state=2)
하지만 DecisionTreeClassifier보다 더 성능이 좋은 것이 하나 있습니다.
바로 RandomForestClassifier, 랜덤 포레스트입니다.
print("훈련 세트 정확도: {:.3f}".format(forest.score(x_train, y_train)))
print("테스트 세트 정확도: {:.3f}".format(forest.score(x_test, y_test)))
# 훈련 세트 정확도: 1.000
# 테스트 세트 정확도: 0.958
아까 사용한 DecisionTreeClassifier보다 0.07 더 향상된 것을 보실 수 있습니다.
from sklearn.ensemble import VotingClassifier # voting 앙상블 기법
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
for_clf = RandomForestClassifier(n_estimators=5, random_state=2)
ada_clf = AdaBoostClassifier(n_estimators=10, random_state=2)
gb_clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=2)
vo_clf = VotingClassifier(estimators=[("KNN", knn_clf), ("FOREST", for_clf),
("ADA", ada_clf), ("GRA", gb_clf)], voting="soft")
이번에는 여러가지 분류 기법들의 정확도를 비교해 보겠습니다.
gb_clf(그라디언트 부스팅)는 여러 개의 결정 트리를 묶어 강력한 모델을 만들고, 이진 트리의 오차를 보완하는 방식입니다.
from sklearn.metrics import accuracy_score
clf = [vo_clf, knn_clf, for_clf, ada_clf, gb_clf]
for clf in clf :
clf.fit(x_train, y_train)
pred = clf.predict(x_test)
name = clf.__class__.__name__
print(f"{name} 정확도 : {accuracy_score(y_test, pred):.5f}")
# VotingClassifier 정확도 : 0.96503
# KNeighborsClassifier 정확도 : 0.93007
# RandomForestClassifier 정확도 : 0.95804
# AdaBoostClassifier 정확도 : 0.93706
# GradientBoostingClassifier 정확도 : 0.95804
RandomForestClassifier가 0.95804로 가장 높은 정확도를 보이고 있습니다.
마지막으로, 이것이 암인지, 아니면 단순히 혹 종류인지 분류하는 모델을 구현해 보겠습니다.
predict = vo_clf.predict(x_test)
proba = vo_clf.predict_proba(x_test)
for i in range(len(predict)) :
print(f"예측 : {predict[i]}, 확률 : {proba[i]}")
# 예측 : 1, 확률 : [0.03866417 0.96133583]
# 예측 : 0, 확률 : [0.99852196 0.00147804]
# 예측 : 1, 확률 : [0.10775523 0.89224477]
# 예측 : 1, 확률 : [0.0760093 0.9239907]
# 예측 : 0, 확률 : [0.6755587 0.3244413]
# ...
0은 암, 1은 종기나 혹 따위를 뜻합니다.
from sklearn.metrics import recall_score
recall = recall_score(y_test, pred)
print(f"재현율 : {recall}")
# 재현율 : 0.9888888888888889
재현율이 상당히 높게 나왔습니다. 그러므로 잘 학습된 모델이라 말할 수 있겠습니다.
'🧠 인공지능' 카테고리의 다른 글
패턴 인식, 자료 분석 - SVM (0) | 2022.10.24 |
---|---|
FinanceDataReader로 주식 예측하기 (0) | 2022.09.21 |
경사하강법을 통해 오차 줄이기 (0) | 2022.09.19 |
KNN의 한계를 해결한 선형 회귀 (0) | 2022.09.07 |
Naive Bayes과 Iris (0) | 2022.09.04 |