1. Iris 붓꽃 데이터
1) 사이킷런 내장 모듈
- sklearn.dataset : 서브패키지는 다양한 예제 데이터셋을 제공, 데이터를 불러오는 명령들은 load, make,
- sklearn.model_selection
- sklearn.neighbors
(1) 데이터 적재¶
- scikit-learn의 dataset모듈에 포함되어 있음
In [1]:
import numpy as np import pandas as pd from sklearn.datasets import load_iris # from sklearn.datasets import load_breast_cancer iris_dataset = load_iris() # cancer_dataset = load_breast_cancer()
In [2]:
print("iris_dataset의 키: \n{}".format(iris_dataset.keys())) # print("cancer_dataset의 키: \n{}".format(cancer_dataset.keys()))
iris_dataset의 키: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
In [3]:
print(iris_dataset.DESCR)
.. _iris_dataset: Iris plants dataset -------------------- **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: ============== ==== ==== ======= ===== ==================== Min Max Mean SD Class Correlation ============== ==== ==== ======= ===== ==================== sepal length: 4.3 7.9 5.84 0.83 0.7826 sepal width: 2.0 4.4 3.05 0.43 -0.4194 petal length: 1.0 6.9 3.76 1.76 0.9490 (high!) petal width: 0.1 2.5 1.20 0.76 0.9565 (high!) ============== ==== ==== ======= ===== ==================== :Missing Attribute Values: None :Class Distribution: 33.3% for each of 3 classes. :Creator: R.A. Fisher :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov) :Date: July, 1988 The famous Iris database, first used by Sir R.A. Fisher. The dataset is taken from Fisher's paper. Note that it's the same as in R, but not as in the UCI Machine Learning Repository, which has two wrong data points. This is perhaps the best known database to be found in the pattern recognition literature. Fisher's paper is a classic in the field and is referenced frequently to this day. (See Duda & Hart, for example.) The data set contains 3 classes of 50 instances each, where each class refers to a type of iris plant. One class is linearly separable from the other 2; the latter are NOT linearly separable from each other. .. topic:: References - Fisher, R.A. "The use of multiple measurements in taxonomic problems" Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to Mathematical Statistics" (John Wiley, NY, 1950). - Duda, R.O., & Hart, P.E. (1973) Pattern Classification and Scene Analysis. (Q327.D83) John Wiley & Sons. ISBN 0-471-22361-1. See page 218. - Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System Structure and Classification Rule for Recognition in Partially Exposed Environments". IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. PAMI-2, No. 1, 67-71. - Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule". IEEE Transactions on Information Theory, May 1972, 431-433. - See also: 1988 MLC Proceedings, 54-64. Cheeseman et al"s AUTOCLASS II conceptual clustering system finds 3 classes in the data. - Many, many more ...
In [7]:
print(iris_dataset['DESCR'][:200] + "\n...") # 데이터셋 설명 앞부분만
.. _iris_dataset: Iris plants dataset -------------------- **Data Set Characteristics:** :Number of Instances: 150 (50 in each of three classes) :Number of Attributes: 4 numeric, predictive ...
- 예측하려는 붓꽃 품종의 이름을 가지고 있는 key : target_names
In [8]:
format("타깃 이름: {}".format(iris_dataset['target_names']))
Out[8]:
"타깃 이름: ['setosa' 'versicolor' 'virginica']"
- 특성을 설명하는 문자열 리스트 : feature_names
In [9]:
format("특성 이름: {}".format(iris_dataset['feature_names']))
Out[9]:
"특성 이름: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']"
- 실제 데이터(target, data) 중 data는 꽃잎의 길이오 폭, 꽃받침의 길이와 폭을 수치 값으로 가지고 있는 Numpy 배열
In [10]:
print("data의 타입 {}".format(type(iris_dataset['data'])))
data의 타입 <class 'numpy.ndarray'>
In [12]:
print("data의 크기 {}".format(iris_dataset['data'].shape)) # 배열의 행은 개개의 꽃, 열은 각 꽃의 측정치
data의 크기 (150, 4)
In [13]:
print("data의 처음 다섯 행:\n{}".format(iris_dataset['data'][:5]))
data의 처음 다섯 행: [[5.1 3.5 1.4 0.2] [4.9 3. 1.4 0.2] [4.7 3.2 1.3 0.2] [4.6 3.1 1.5 0.2] [5. 3.6 1.4 0.2]]
- 1열: 꽃받침의 길이
- 2열: 꽃받침의 폭
- 3열: 꽃잎의 길이
- 4열: 꽃잎의 폭
- target 배열: 샘플 붓꽃의 품종을 담은 Numpy 배열
In [14]:
print("data의 타입 {}".format(type(iris_dataset['target'])))
data의 타입 <class 'numpy.ndarray'>
In [16]:
print("data의 타입 {}".format(iris_dataset['target'].shape)) # 1차언 배열
data의 타입 (150,)
In [18]:
print("타깃:\n{}".format(iris_dataset['target'])) # 0: setosa, 1: versicolor, 2: virginica
타깃: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
(2) 훈련 데이터와 테스트 데이터¶
- 머신러닝 모델을 만들 때 사용하는 훈련데이터와 모델이 얼마나 잘 작동하는지 측정하는 테스트 데이터로 나눔
- scikit-learn 데이터셋을 섞어서 나눠주는 train_test_split 함수 제공(훈련세트:75%, 테스트세트:25%)
- scikit-learn에서 데이터는 대문자 X로 표시, 레이블은 소문자 y로 표시
- 이는 수학에서 함수의 입력을 x, 출력을 y로 나타내는 표준공식 f(x)=y에서 유래
- 수학의 표기 방식을 따르되 데이터는 2차원 배열이므로 대문자를 X, 타깃은 1차원 배열(벡터)이므로 소문자 y 사용
In [19]:
from sklearn.model_selection import train_test_split
In [20]:
X_train, X_test, y_train, y_test = train_test_split( iris_dataset['data'], iris_dataset['target'], random_state=0 )
- train 데이터와, test 데이터로 나누기 전에 무작위로 섞어주지 않으면 순서대로 나누어 지기 때문에 y_test(테스트레이블) 값이 모두 2가 나오게 된다
- 세 클래스 중 하나만 포함한 테스트 세트를 사용하면 모델이 얼마나 잘 일반화 되었는지 알 수 없다.
- 테스트 세트는 모든 클래스의 데이터를 포함하도록 잘 섞어야 한다.
- random_state = 0 은 이 함수를 여러번 실행해도 같은 랜덤값이 리턴 된다.
In [21]:
print("X_train 크기: {}".format(X_train.shape)) print("y_train 크기: {}".format(y_train.shape))
X_train 크기: (112, 4) y_train 크기: (112,)
In [22]:
print("X_test 크기: {}".format(X_test.shape)) print("y_test 크기: {}".format(y_test.shape))
X_test 크기: (38, 4) y_test 크기: (38,)
(3) 데이터 살펴보기¶
- 머신러닝 모델을 만들기 전에 머신러닝 없이도 풀 수 있는 문제가 아닌지, 혹은 필요한 정보가 누락되어 있는지 데이터를 조사해 보는것이 좋다.
- 실제 데이터에는 일관성이 없거나 이상한 값이 들어가 있는 경우가 종종 있다.
산점도 행렬을 통해 데이터의 특성을 찾아보자
In [23]:
# X_train 데이터를 사용해서 데이터프레임을 만든다 iris_dataframe = pd.DataFrame(X_train, columns = iris_dataset.feature_names)
In [24]:
iris_dataframe.head()
Out[24]:
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | 5.9 | 3.0 | 4.2 | 1.5 |
1 | 5.8 | 2.6 | 4.0 | 1.2 |
2 | 6.8 | 3.0 | 5.5 | 2.1 |
3 | 4.7 | 3.2 | 1.3 | 0.2 |
4 | 6.9 | 3.1 | 5.1 | 2.3 |
In [25]:
pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15,15), marker='o', hist_kwds={'bins':20}, s=60, alpha=.8)
Out[25]:
array([[<Axes: xlabel='sepal length (cm)', ylabel='sepal length (cm)'>, <Axes: xlabel='sepal width (cm)', ylabel='sepal length (cm)'>, <Axes: xlabel='petal length (cm)', ylabel='sepal length (cm)'>, <Axes: xlabel='petal width (cm)', ylabel='sepal length (cm)'>], [<Axes: xlabel='sepal length (cm)', ylabel='sepal width (cm)'>, <Axes: xlabel='sepal width (cm)', ylabel='sepal width (cm)'>, <Axes: xlabel='petal length (cm)', ylabel='sepal width (cm)'>, <Axes: xlabel='petal width (cm)', ylabel='sepal width (cm)'>], [<Axes: xlabel='sepal length (cm)', ylabel='petal length (cm)'>, <Axes: xlabel='sepal width (cm)', ylabel='petal length (cm)'>, <Axes: xlabel='petal length (cm)', ylabel='petal length (cm)'>, <Axes: xlabel='petal width (cm)', ylabel='petal length (cm)'>], [<Axes: xlabel='sepal length (cm)', ylabel='petal width (cm)'>, <Axes: xlabel='sepal width (cm)', ylabel='petal width (cm)'>, <Axes: xlabel='petal length (cm)', ylabel='petal width (cm)'>, <Axes: xlabel='petal width (cm)', ylabel='petal width (cm)'>]], dtype=object)
(4) K-최근접 이웃(k-nearest neighbors,k-nn) 알고리즘을 이용한 머신러닝¶
- 훈련데이터를 통해 모델이 만들어지고 새로운 데이터가 들어오면 가까운 훈련 데이터 포인트를 찾아 분류한다
- scikit-learn의 모든 머신러닝 모델은 Estimator라는 파이썬 클래스로 각각 구현되어 있다.
- k-최근접 이웃 분류 알고리즘은 neighbors 모듈 아래 KNeighborsClassifier 클래스에 구현되어 있다.
- 모델을 사용하기 위해 클ㄹ스로부터 객체를 만들고 paramiter를 설정한다.
- 가장 중요한 이웃의 개수를 1로 지정하고 모델을 만들어 보자
In [27]:
from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=1)
- 훈련 데이터 셋으로부터 모델을 만들기 위해 fit 메서드 사용
In [28]:
knn.fit(X_train, y_train)
Out[28]:
KNeighborsClassifier(n_neighbors=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
KNeighborsClassifier(n_neighbors=1)
- fit 메서드는 knn 객체 자체를 변환시키면서 반환시킴
(5) 예측하기¶
- 위에서 만든 모델을 사용해서 새 데이터에 대한 예측을 만들 수 있다.
- 야생에서 꽃받침의 길이는 3cm, 폭은 4.2cm, 꽃입의 길이는 0.8cm, 폭은 0.4cm인 붓꽃을 찾았다고 가정하고 이 붓꽃의 품종을 찾아보자
- 측정값은 numpy 배열로 만드는데, 하나의 붓꽃 샘플(1)에 4가지 특성(4)이 있으므로 1 by 4 배열을 만들어야 한다.
- 붓꽃 하나의 측정갑은 2차원 numpy 배열에 행으로 들어가므로, scikit-learn은 항상 데이터가 2차원 배열일 것으로 예상
In [32]:
X_new = np.array([[3, 4.2, 0.8, 0.4]]) X_new
Out[32]:
array([[3. , 4.2, 0.8, 0.4]])
In [33]:
print("X_new.shape: {}".format(X_new.shape))
X_new.shape: (1, 4)
In [37]:
prediction = knn.predict(X_new) print("예측: {}".format(prediction))
예측: [0]
In [35]:
print("예측한 붓꽃의 이름: {}".format(iris_dataset['target_names'][prediction]))
예측한 붓꽃의 이름: ['setosa']
- 하나의 입력, 특성을 가진 값이 아니기 때문에 아래와 같이 벡터 형태로 나타내면 에러가 남
In [42]:
X_new2 = np.array([3, 4.2, 0.8, 0.4]) print(X_new2) print(X_new2.ndim)
[3. 4.2 0.8 0.4] 1
In [44]:
# #### 에러가 남 # X_new2 = np.array([3, 4.2, 0.8, 0.4]) # X_new2prediction = knn.predict(X_new2) # prediction
(6) 모델평가¶
- 앞에서 만든 테스트 셋을 가지고 현재 만든 학습 모델이 잘 만들어졌는지 확인
In [45]:
y_pred = knn.predict(X_test) # 만들어진 학습모델은 가지고 테스트 데이터의 붓꽃품종을 예측
In [46]:
y_pred # 테스트 데이터의 예측 값
Out[46]:
array([2, 1, 0, 2, 0, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2, 0, 0, 1, 1, 0, 2, 1, 0, 2, 2, 1, 0, 2])
In [48]:
y_pred == y_test # 예측 품종과 실제 품종이 같으면 true
Out[48]:
array([ True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, False])
- 테스트 세트의 정확도
In [49]:
print("테스트 세트의 정확도 : {:.4f}%".format(np.mean(y_pred == y_test)*100))
테스트 세트의 정확도 : 97.3684%
- knn 객체의 score 메서드 사용
In [51]:
print("테스트 세트의 정확도 : {:.4f}%".format(knn.score(X_test, y_test)*100))
테스트 세트의 정확도 : 97.3684%
In [52]:
from sklearn import metrics
- sklearn.metrics의 accuracy_score 사용
In [53]:
print("테스트 세트의 정확도 : {:.4f}%". format( metrics.accuracy_score(y_test, y_pred)*100 ))
테스트 세트의 정확도 : 97.3684%
In [ ]:
반응형
'데이터분석' 카테고리의 다른 글
[23.07.18] 머신러닝(선형회귀) - 33(3) (0) | 2023.07.18 |
---|---|
[23.07.18] 머신러닝(k-최근접 이웃 회귀) - 33(2) (0) | 2023.07.18 |
[23.07.17] 머신러닝(Machine Learning) - 32(1) (0) | 2023.07.18 |
[23.07.07] 프로젝트 주제 발표 - 26(1) (0) | 2023.07.07 |
[23.07.06] 인스타그램 크롤링 - 25(1) (1) | 2023.07.06 |