
1. 개요
사이킷런에서 제공하는 붓꽃(Iris) 데이터셋을 사용하여 지도학습 유형의 분류 모델을 적용해 붓꽃의 품종을 판별하는 예제를 작성해본다.
2. 데이터셋 준비
필요한 라이브러리를 import 하고 sklearn 패키지에 내장돼 있는 붓꽃 데이터셋을 load_iris() 함수로 불러온다.
import numpy as np
import pandas as pd
from sklearn import datasets
iris = datasets.load_iris()
print(iris.keys())
dict_keys(['data', 'target', 'frame', 'target_names',
'DESCR', 'feature_names', 'filename', 'data_module'])
데이터셋의 설명은 'DESCR'키를 사용하여 가져올 수 있다.
print(iris['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.
|details-start|
**References**
|details-split|
- 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 ...
|details-end|
데이터는 'data'키를 사용하여 가져오고 타깃 변수는 'target'키 사용하여 가져온다.
iris['data'].shape # (150, 4)
iris['target'].shape # (150,)
붓꽃 데이터를 판다스 데이터프레임으로 변환한다.
df = pd.DataFrame(iris['data'], columns=iris['feature_names'])
df.head()

데이터프레임에 iris target 데이터를 새로운 열로 추가한다.
df['target'] = iris['target']
df.head()

3. 데이터셋 탐색
데이터프레임의 기본 정보를 info() 함수로 확인한다.
df.info()
class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal length (cm) 150 non-null float64
1 sepal width (cm) 150 non-null float64
2 petal length (cm) 150 non-null float64
3 petal width (cm) 150 non-null float64
4 target 150 non-null int32
dtypes: float64(4), int32(1)
memory usage: 5.4 KB
데이터프레임의 통계 정보를 describe() 함수로 확인한다. 평균, 표준편차, 최솟값, 최댓값 등을 요약해서 표시한다.
df.describe()

isnull() 함수를 사용하여 결측값이 있는지 확인을 한다. isnull() 함수에 sum() 함수를 체인하면 결측값의 개수를 표시해 준다.
df.isnull().sum()
sepal length (cm) 0
sepal width (cm) 0
petal length (cm) 0
petal width (cm) 0
target 0
dtype: int64
4. 데이터 시각화
corr() 함수는 변수 간의 상관 계수를 표시한다. 결과를 보면 target 값은 sepal length (cm), petal length (cm), petal width (cm)와 상관관계가 높음을 알 수 있다. 상관 계수 값을 이용해 데이터를 시각화해보자.
df.corr()

맷플롯립(matplotlib)과 시본(seaborn)을 사용하여 데이터를 시각화한다.
import matplotlib.pyplot as plt
import seaborn as sns
sns.heatmap(data=df.corr(), annot=True)
plt.show()

sepal length (cm)와 sepal width (cm)의 분포를 확인해 보자.
plt.hist(x='sepal length (cm)', data=df)
plt.show()

plt.hist(x='sepal width (cm)', data=df)
plt.show()

5. 데이터셋 분할
from sklearn.model_selection import train_test_split
x_data = df.loc[:, 'sepal length (cm)':'petal width (cm)']
y_data = df.loc[:, 'target']
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data,
test_size=0.2, shuffle=True, random_state=42)
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)
(120, 4) (120,) (30, 4) (30,)
6. KNN
KNN(K-Nearest-Neighbors)은 예측하려는 데이터 x가 주어지면, 기존 데이터 중 속성이 비슷한 K 개의 이웃을 찾는 분류 알고리즘이다. 데이터 x를 둘러싼 K 개의 가까운 이웃을 찾고, 이웃 데이터가 가장 많이 속해있는 목표 클래스를 예측값으로 결정한다.
K 값을 어떻게 설정하는지에 따라 예측하는 분류가 달라질 수 있다. K=5로 설정했다. fit() 함수에 훈련 데이터를 입력하여 모델 학습을 한다. x_test를 predict() 함수에 입력해 값을 예측한다.
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train, y_train)
knn_pred = knn.predict(x_test)
knn_pred
array([1, 0, 2, 1, 1, 0, 1, 2, 1, 1,
2, 0, 0, 0, 0, 1, 2, 1, 1, 2,
0, 2, 0, 2, 2, 2, 2, 2, 0, 0])
사이킷런 metrics 모듈에서 모델 성능을 평가하기 위해 accuracy_score를 import 한다.
x_test의 정답 레이블인 y_test를 예측값 knn_pred와 함께 입력해서 정확도를 산출해 보니 정확도가 100% 나왔다.
from sklearn.metrics import accuracy_score
knn_acc = accuracy_score(y_test, knn_pred)
knn_acc
1.0
7. SVM
SVM(Support Vector Machine)은 데이터셋의 벡터들이 고유의 축을 갖는 벡터 공간을 이룬다고 가정한다. 모든 데이터를 벡터 공간 내의 좌표에 점으로 표시하고, 각 데이터가 속하는 목표 클래스 별로 군집을 이룬다고 생각한다. 이때 각 군집까지의 거리를 최대한 멀리 유지하는 경계면을 찾는다.
SVM 알고리즘이 구현된 사이킷런 svm 모듈에서 분류 모델인 SVM 인스턴스 객체를 생성하고 모델을 학습시킨다. 커널(kernel)은 데이터를 벡터 공간으로 매핑하는 함수를 말하며, 'rbf'는 Radial Basis Foundation을 뜻한다.
from sklearn.svm import SVC
svc = SVC(kernel='rbf')
svc.fit(x_train, y_train)
svc_pred = svc.predict(x_test)
svc_pred
array([1, 0, 2, 1, 1, 0, 1, 2, 1, 1, 2, 0, 0, 0, 0, 1, 2, 1, 1, 2, 0, 2,
0, 2, 2, 2, 2, 2, 0, 0])
predict() 함수로 모델의 예측값을 산출한다. acccuracy_score() 함수로 예측의 정확도를 산출해 보니 100% 정확도가 나왔다.
from sklearn.metrics import accuracy_score
svc_acc = accuracy_score(y_test, svc_pred)
svc_acc
1.0
8. 로지스틱 회귀
로지스틱 회귀(Logistic Regression)는 분류 알고리즘이다. 시그모이드 함수의 출력값을 각 분류 클래스에 속하게 될 확률 값으로 사용한다. 붓꽃 데이터셋을 학습하여 각 품종에 속하는 확률을 0~1사이의 값으로 계산하고, 1에 가까우면 해당 클래스로 분류하고, 0에 가까우면 아니라고 분류한다.
사이킷런 linear_model 모듈에서 LogisticRegression 클래스를 불러왔다. 모델 인스턴스 객체를 생성하고, fit() 함수에 훈련 데이터를 입력하면 학습을 진행한다.
from sklearn.linear_model import LogisticRegression
lrc = LogisticRegression()
lrc.fit(x_train, y_train)
lrc_pred = svc.predict(x_test)
lrc_pred
array([1, 0, 2, 1, 1, 0, 1, 2, 1, 1,
2, 0, 0, 0, 0, 1, 2, 1, 1, 2,
0, 2, 0, 2, 2, 2, 2, 2, 0, 0])
predict() 함수로 모델의 예측값을 산출한다. acccuracy_score() 함수로 예측의 정확도를 산출해 보니 100%의 정확도가 나왔다.
from sklearn.metrics import accuracy_score
lrc_acc = accuracy_score(y_test, lrc_pred)
lrc_acc
1.0
predict_proba() 함수를 사용하면 각 클래스에 속할 확률 값을 예측한다.
실행 결과를 3개의 열과 30개의 행으로 구성된 넘파이 배열이 반환된다.
lrc_prob = lrc.predict_proba(x_test)
lrc_prob
array([[3.78546414e-03, 8.27209125e-01, 1.69005411e-01],
[9.46715849e-01, 5.32839506e-02, 2.00065738e-07],
[8.72667869e-09, 1.55702334e-03, 9.98442968e-01],
[6.43492314e-03, 7.92123358e-01, 2.01441719e-01],
[1.44114053e-03, 7.74296128e-01, 2.24262731e-01],
[9.55769961e-01, 4.42298617e-02, 1.76949624e-07],
[7.76227744e-02, 9.08067734e-01, 1.43094917e-02],
[1.61435709e-04, 1.55688827e-01, 8.44149737e-01],
[2.20813041e-03, 7.62682834e-01, 2.35109036e-01],
[2.83209562e-02, 9.45783073e-01, 2.58959704e-02],
[4.39778584e-04, 2.43338866e-01, 7.56221356e-01],
[9.68311159e-01, 3.16887627e-02, 7.81177481e-08],
[9.72933634e-01, 2.70663326e-02, 3.33567975e-08],
[9.62098336e-01, 3.79015525e-02, 1.10990789e-07],
[9.79266617e-01, 2.07333183e-02, 6.47655928e-08],
[4.54262691e-03, 7.12679398e-01, 2.82777975e-01],
[7.22936792e-06, 2.42139263e-02, 9.75778844e-01],
[2.73361883e-02, 9.47674145e-01, 2.49896671e-02],
[8.23339605e-03, 8.31124999e-01, 1.60641605e-01],
[1.41995339e-05, 3.59470991e-02, 9.64038701e-01],
[9.64368517e-01, 3.56312904e-02, 1.92964274e-07],
[1.31405149e-03, 3.99147841e-01, 5.99538108e-01],
[9.61625663e-01, 3.83740761e-02, 2.61284847e-07],
[1.85488000e-05, 4.58716140e-02, 9.54109837e-01],
[1.63856702e-06, 2.58884254e-02, 9.74109936e-01],
[9.32803760e-05, 1.05069115e-01, 8.94837605e-01],
[8.69070141e-06, 5.83452859e-02, 9.41646023e-01],
[4.30120370e-06, 1.88618113e-02, 9.81133887e-01],
[9.66843298e-01, 3.31565665e-02, 1.35883436e-07],
[9.56305623e-01, 4.36941449e-02, 2.32550905e-07]])
9. 의사결정나무
의사결정나무(Decision Tree) 모델은 트리 알고리즘을 사용한다. 트리의 각 분기점(node)에는 데이터셋의 피처를 하나씩 위치시킨다. 각 분기점에서 해당 피처에 관한 임의의 조건식을 가지고 계속 2개 이상 줄기로 가지를 나누면서 데이터를 구분한다.
사이킷런 tree 모듈에서 DecisionTreeClassifier을 가져와 트리의 최대 깊이를 3으로 설정한다. 트리의 깊이를 제한하는 이유는 모델이 지나치게 복잡한 구조를 갖게 되면 훈련 데이터에 과대 적합되기 때문이다. fit() 함수에 훈련 데이터를 입력해 모델을 학습시킨다.
from sklearn.tree import DecisionTreeClassifier
dtc = DecisionTreeClassifier(max_depth=3, random_state=42)
dtc.fit(x_train, y_train)
dtc_pred = dtc.predict(x_test)
dtc_pred
array([1, 0, 2, 1, 1, 0, 1, 2, 1, 1,
2, 0, 0, 0, 0, 1, 2, 1, 1, 2,
0, 2, 0, 2, 2, 2, 2, 2, 0, 0])
예측의 정확도를 확인해 보니 100%의 정확도가 나왔다.
from sklearn.metrics import accuracy_score
dtc_acc = accuracy_score(y_test, dtc_pred)
dtc_acc
1.0

'✨ 딥러닝·머신러닝' 카테고리의 다른 글
| TensorFlow - 텐서플로를 사용하여 MNIST 예제를 실행 (0) | 2026.06.16 |
|---|---|
| 사이킷런 - 지도학습으로 붓꽃의 품종을 판별 (0) | 2026.06.16 |
| 케라스(Keras) - 최소한의 코드로 딥러닝을 구현한다 (0) | 2026.06.15 |
| TensorFlow - 도커 컨테이너에서 텐서플로를 실행 (0) | 2026.06.15 |
| 신경망의 발견 - 신경망에서 단순 퍼셉트론, 다중 퍼셉트론, 딥러닝까지 (0) | 2026.06.15 |
댓글