1. iris 데이터
from sklearn.datasets import load_iris
iris = load_iris()
iris.keys()
# sklearn의 datasets은 Python의 dict 형과 유사
# dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
print(iris['DESCR'])
# DESCR은 description. 데이터 셋에 대한 설명을 제공
**Data Set Characteristics:**
:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
- sepal length in cm
- sepal width in cm
- petal length in cm
- petal width in cm
- class:
- Iris-Setosa
- Iris-Versicolour
- Iris-Virginica
:Summary Statistics:
print(iris
['target_names'])
# ['setosa' 'versicolor' 'virginica']
print(iris['feature_names'])
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
# DataFrame으로 만들기
import pandas as pd
iris_pd = pd.DataFrame(iris.data, columns=iris['feature_names'])
# 품종 정보 DataFrame column에 추가
# 0, 1, 2의 값이 각 품종을 의미
iris_pd['species'] = iris.target
# pairplot 으로 상관관계 찾기
import matplotlib.pyplot as plt
import seaborn as sns
sns.pairplot(iris_pd, hue='species')
2. Decision Tree
# # setosa 구분은 잘되나 나머지 2개의 품종 구분이 힘들다.두가지 품종의대하여 자세히 보기
iris_12 = iris_pd[iris_pd['species'] != 0]
iris_12
plt.figure(figsize=(12,6))
sns.scatterplot(x= 'petal length (cm)', y= 'petal width (cm)', data=iris_12 , hue='species', palette='Set2')
# sklearn을 이용한 결정나무의 구현
from sklearn.tree import DecisionTreeClassifier
iris_tree = DecisionTreeClassifier()
iris_tree.fit(iris.data[:, 2:], iris.target)
# Accuracy 확인
from sklearn.metrics import accuracy_score
y_pred_tr = iris_tree.predict(iris.data[:, 2:])
accuracy_score(iris.target, y_pred_tr)
# 0.9933333333333333
# Tree model visualization
from sklearn.tree import plot_tree
plt.figure(figsize=(12,6))
plot_tree(iris_tree)
# iris의 품종을 분류하는 결정나무 모델이 어떻게 데이터를 분류했는지 확인
from mlxtend.plotting import plot_decision_regions
plt.figure(figsize=(14,8))
plot_decision_regions(X=iris.data[:, 2:], y=iris.target, clf= iris_tree, legend=2)
plt.show()
Accuracy가 높다고 믿을 수 있을까?
- Acc가 높게 나왔다고 해도 좀 더 확인해 볼 필요가 있다
3. 데이터 분리
- 데이터를 분리하여 학습한뒤 테스트 데이터로 확인한다
- 과적합을 확인하기위하여 내가 가지고 있는 데이터애서 최대한 노력한다
# 처음부터 다시진행 해보자
# 데이터를 훈련 / 테스트로 분리
# 8:2 확률로 특성(features)과 정답(labels)를 분리
# 각 클래스(setosa, versicolor, verginica) 별로 동일 비율이 아닐때 사용하는 옵션 stratify=labels (갯수 맞춰주는 옵션)
from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
from sklearn.model_selection import train_test_split
features = iris.data[:, 2:]
labels = iris.target
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2,stratify=labels ,random_state=13)
# train 데이터만 대상으로 결정나무 모델을 만들기
# 학습할 때 마다 일관성을 위해 random_state만 고정
# 모델을 단순화시키기 위해 max_depth를 조정
from sklearn.tree import DecisionTreeClassifier
iris_tree = DecisionTreeClassifier(max_depth=2, random_state=13)
iris_tree.fit(X_train, y_train)
#train 데이터에 대한 accuracy 확인
from sklearn.metrics import accuracy_score
y_pred_tr = iris_tree.predict(iris.data[:, 2:])
y_pred_tr
accuracy_score(iris.target, y_pred_tr)
# 0.9533333333333334 (iris 데이터는 단순해서 acc가 높게 나타났다)
# 테스터 데이터에 대한 accuracy
y_pred_test = iris_tree.predict(X_test)
accuracy_score(y_test, y_pred_test)
# 0.9666666666666667
# 전체 데이터 관찰
scatter_highlight_kwargs = {'s':150, 'label':'Test data', 'alpha':0.9}
scatter_kwargs = {'s': 120, 'edgecolor': None, 'alpha':0.9}
plt.figure(figsize=(12,8))
plot_decision_regions(
X = features,
y= labels,
X_highlight=X_test,
clf= iris_tree,
legend=2,
scatter_highlight_kwargs= scatter_highlight_kwargs,
scatter_kwargs = scatter_kwargs,
contour_kwargs={'alpha' : 0.2}
)
# 특성을 4개로 진행
features = iris.data
labels = iris.target
X_train, X_test, y_train, y_test = train_test_split(
features,
labels,
test_size=0.2,
stratify=labels,
random_state=13
)
iris_tree = DecisionTreeClassifier(max_depth=2, random_state=13)
iris_tree.fit(X_train, y_train)
# 전체 특성을 사용한 결정나무 모델
plt.figure(figsize=(12,6))
plot_tree(iris_tree)
4. 모델을 사용하는 방법
# 길가다가 주운 iris가 sepal과 petal의 length, width가 각각 [4.3, 2. , 1.2, 1.0] 일때
test_data = [[4.3,2.,1.2,1.]]
# 각 클래스별 확률
iris_tree.predict_proba(test_data)
# array([[0. , 0.97222222, 0.02777778]])