목차
- IRIS 품종 분류를 위한 data set 로드
- data set에 포함된 feature, target, name확인
- KNN 알고리즘을 통해 예측과 평가
이번에는 K- Nearest Neighbor(KNN) 알고리즘을 실제로 적용해보기 위해 scikit-learn에서 제공하는 IRIS data set을 이용해 머신러닝 모델을 만든후 예측과 평가를 진행해 볼 것이다. 모든 과정은 google colab에서 진행할 것이다.
먼저 scikit.learn.datasets에서 필요한 load_iris를 import해주고 scikit-learn에서 제공하는 data를 로드해주자.
from sklearn.datasets import load_iris
iris_dataset = load_iris()
필요한 dataset을 로드하였으니 dataset에 든 key, target, feature을 확인해보자.
print("iris_dataset의 키들 : \n{}".format(iris_dataset.keys()))
print("target_names : \n{}".format(iris_dataset['target_names']))
print("featrue_names : \n{}".format(iris_dataset['feature_names']))
실행결과는 아래와 같다.
iris_dataset의 키들 :
dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])
target_names :
['setosa' 'versicolor' 'virginica']
featrue_names :
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
먼저 key에 총 6가지 종류의 keyrk 존재하는 것을 알 수 있다.
data : 각 IRIS의 feature들에 대한 실제 값들이 존재 한다.
target : target name의 index들이 존재한다. 이번경우 target_name이 총 3종류 이므로 0,1,2로 구성되어있을 것이다.
target name : IRIS 품종에대한 이름이 존재한다.
DESCR : 해당 dataset에 대한 간단한 설명이 들어있는 부분이다.
feature_name : IRIS의 data 특성이 저장되어있다. 이번 경우 꽃받침의 길이, 너비 꽃잎의 길이, 너비를 특성으로 가진다.
이제는 로드한 데이터에서 train 부분과 test부분으로 나누어주어야한다. 만약 train 데이터를 통해 test를 진행한다면 당연히 모두 맞는 결과를 내놓을 수 밖에 없다. 따라서 train에 사용할 데이터와 test에 사용할 데이터는 달라야 한다. 가장 쉬운 방법으로 이미 준비된 dataset에서 일부 떼어내어 train set과 test set을 분리하는 방법이 있다.
scikit.learn은 data를 자동으로 섞어 train set과 test set으로 분리해주는 train_test_split함수를 제공한다. train_test_split 함수는 model_selection 모듈 아래에 존재한다.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
iris_dataset['data'], iris_dataset['target'], random_state=0)
print("X_train 의 크기 : {}".format(X_train.shape))
print("y_train 의 크기 : {}".format(y_train.shape))
print("X_test 의 크기 : {}".format(X_test.shape))
print("y_test 의 크기 : {}".format(y_test.shape))
random_state 매개변수가 눈에 띄는데 해당 매개변수는 랜덤 seed값이며 train_test_split 함수는 기본적으로 75:25 비율로 dataset을 분리해준다. 이는 위 코드의 실행결과에서 확인 할 수도 있다.
X_train 의 크기 : (112, 4)
y_train 의 크기 : (112,)
X_test 의 크기 : (38, 4)
y_test 의 크기 : (38,)
위에서 확인 하지는 않았지만 IRIS dataset에는 150개의 data가 들어있다. 따라서 112:38의 비율로 나누어진다. 또한 만약 data가 작은 경우 무작위로 data를 나눠주므로 샘플링 편향이 발생할 수 있는데 stratify 매개변수에 target data를 전달해주면 클래스 비율에 맞게 자동으로 data를 나누어준다. 이번 경우는 data의 크기가 작은 수준을 아니므로 무시해도 상관 없다.
이번에는 나누어진 data set을 시각적으로 확인해보자.
!pip install mglearn
import pandas as pd
import mglearn
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(12,12), marker='o',
hist_kwds={'bins':20}, s=60, alpha=.8, cmap=mglearn.cm3)
먼저 mglearn을 pip를 이용해 설치해주고 pandas와 mglearn을 임포트 해준다.
각각의 색깔의 점들은 IRIS품종의 종류를 나타내고 각각의 특성에 따라 산점도를 나타내준다.
이제 KNN을 구현해 놓은 KNeighborsClassifier 임포트해 학습시켜보자.
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=10)
knn.fit(X_train, y_train)
n_neighbor 매개변수는 참고하는 가까운 data중 몇개를 참고할지 설정하는 매개 변수이다. 이번 경우 10을 설정해주었다. 이후 fit 메서드에 X_train과 y_train을 전달하여 학습을 진행 할 것이다. 각각은 data와 target을 인자로 전달 해 준것이다. 실행해주면 아래와 같이 출력이 된다.
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
metric_params=None, n_jobs=None, n_neighbors=10, p=2,
weights='uniform')
이제 학습이 완료 되었으므로 새로운 data를 생성하여 predict 메서드를 사용해 예측을 진행 할것이다.
import numpy as np
X_new = np.array([[7,2.1,6.9,0.3]])
prediction = knn.predict(X_new)
print("예측한 타깃의 이름 : {}".format(iris_dataset['target_names'][prediction]))
먼저 numpy를 임포트 하여야한다. data set자체가 넘파이 배열로 주어지기 때문이다. 이후 predict 메서드를 이용해 새로운 data에 대한 결과를 확인해보자.
예측한 타깃의 이름 : ['virginica']
이제는 아까 분리하였던 test set에을 이용해 결과를 에측해보자.
y_prediction = knn.predict(X_test)
#X_test(data)에 대하여 품종예측
for i in range(0,len(y_prediction)):
y_pred = y_prediction[i]
print("{} : {}".format(X_test[i],iris_dataset['target_names'][y_pred]))
[5.8 2.8 5.1 2.4] : virginica
[6. 2.2 4. 1. ] : versicolor
[5.5 4.2 1.4 0.2] : setosa
[7.3 2.9 6.3 1.8] : virginica
[5. 3.4 1.5 0.2] : setosa
[6.3 3.3 6. 2.5] : virginica
[5. 3.5 1.3 0.3] : setosa
[6.7 3.1 4.7 1.5] : versicolor
[6.8 2.8 4.8 1.4] : versicolor
[6.1 2.8 4. 1.3] : versicolor
[6.1 2.6 5.6 1.4] : virginica
[6.4 3.2 4.5 1.5] : versicolor
[6.1 2.8 4.7 1.2] : versicolor
[6.5 2.8 4.6 1.5] : versicolor
[6.1 2.9 4.7 1.4] : versicolor
[4.9 3.6 1.4 0.1] : setosa
[6. 2.9 4.5 1.5] : versicolor
[5.5 2.6 4.4 1.2] : versicolor
[4.8 3. 1.4 0.3] : setosa
[5.4 3.9 1.3 0.4] : setosa
[5.6 2.8 4.9 2. ] : virginica
[5.6 3. 4.5 1.5] : versicolor
[4.8 3.4 1.9 0.2] : setosa
[4.4 2.9 1.4 0.2] : setosa
[6.2 2.8 4.8 1.8] : virginica
[4.6 3.6 1. 0.2] : setosa
[5.1 3.8 1.9 0.4] : setosa
[6.2 2.9 4.3 1.3] : versicolor
[5. 2.3 3.3 1. ] : versicolor
[5. 3.4 1.6 0.4] : setosa
[6.4 3.1 5.5 1.8] : virginica
[5.4 3. 4.5 1.5] : versicolor
[5.2 3.5 1.5 0.2] : setosa
[6.1 3. 4.9 1.8] : virginica
[6.4 2.8 5.6 2.2] : virginica
[5.2 2.7 3.9 1.4] : versicolor
[5.7 3.8 1.7 0.3] : setosa
[6. 2.7 5.1 1.6] : virginica
잘 결과를 출력해주는 것을 알 수있다.
마지막으로는 score 메서드를 사용해서 이번 학습에대한 정확도를 확인해보자.
print("테스트 세트의 정확도 :",knn.score(X_test, y_test))
테스트 세트의 정확도 : 0.9736842105263158
정확도가 거의 1에 근접하므로 성공적으로 학습을 진행했다고 할 수 있을 것 같다.
github주소
github.com/smlijun/machine_learning/blob/main/IRIS%20%EB%B6%84%EB%A5%98%20KNN.ipynb