Iris 데이터셋은 데이터셋을 활용하는 실습에서 다들 한번 씩 해봤을 법한 입문용 데이터셋이다.
iris는 붓꽃이라는 꽃인데, 붓꽃에는 여러가지의 품종이 있다.
이 꽃의 품종을 Iris 데이터셋에 있는 꽃잎의 길이와 너비, 꽃받침의 길이와 너비를 기반으로 예측하는 것이다.
우리는 지도학습의 대표적인 예인 분류 방법을 이용할 것이다.
그래서 학습을 위해 주어지는 데이터 세트 (학습 데이터)와 머신러닝 모델의 예측 성능을 평가하기 위해 주어지는 데이터 세트 (테스트 데이터)가 있어야 한다.
먼저 load_iris() 함수로 iris dataset을 가져오는데, 그 데이터셋 구성을 설명하겠다.
iris 데이터 셋 구성 (iris['필드명']으로 볼 수 있다.)
- DESCR : 데이터셋의 정보를 보여준다.
- data : feature data (각 배열에 4개의 속성으로 구성되어있다.)
- feature_names : feature data의 컬럼(열) 이름
- target : label data (수치형)
- target_name : label data의 이름 (문자형)
먼저 데이터셋의 정보에 대해서 봐보자! iris['DESCR']을 치게 되면 데이터셋의 정보를 보여준다고 위에서 말했다..
데이터셋의 타입과 특징(Attribute)들, 그리고 각 컬럼 별 통계정보 또한 보여준다.
>>> import pandas as pd
>>> from sklearn.datasets import load_iris # scikit-learn에 있는 Iris 데이터셋을 가져오기 위해서 load_iris를 import한다.
>>> iris = load_iris() # 말그대로 iris 데이터셋을 로드한다.
>>> print(iris['DESCR']) # 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.
.. 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 ...
이제 iris['data']를 실행시켜보자. 각 배열 속 구성은 sepal(꽃 받침) length, sepal width, petal(꽃잎) length, petal width이다.
>>> data = iris['data']
>>> data[:10]
array([[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],
[5.4, 3.9, 1.7, 0.4],
[4.6, 3.4, 1.4, 0.3],
[5. , 3.4, 1.5, 0.2],
[4.4, 2.9, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1]])
그다음 feature_names를 뽑아보자. 'data'의 컬럼 이름이라 했으니 당연히 'sepal length', 'sepal width', 'petal length', 'petal width' 일것이다.
>>> feature_names = iris['feature_names']
>>> feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
이제 'target'과 'target_names'를 확인할 시간이다.
'target'은 label data(수치형)이라 했다. label data는 결과데이터라고 생각하면 된다. 즉, 꽃의 종류가 target_names일 것이다! target은 수치형으로 표현된다.
>>> target = iris['target']
>>> target
array([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])
>>> iris['target_names']
array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
이제 iris 데이터셋의 필드들을 알았으니, 데이터 프레임을 만들어보자.
feature_names를 컬럼명으로 하고, data를 value로 하고, 마지막 열에 'target'을 추가하면 될 것이다!
# pandas의 DataFrame()을 이용해, 데이터와 컬럼명을 넣어준다!
>>> df_iris = pd.DataFrame(data, columns = feature_names)
>>> df_iris.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
# 라벨 데이터인 target 컬럼도 추가해준다!
>>> df_iris['target'] = target
>>> df_iris.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
이제 해당 데이터셋에서 학습 데이터와 테스트 데이터를 적절히 분리해줘서!
1. 데이터 프레임을 만든 후
2. 시각화로 데이터를 확인하고!
3. 학습 데이터로 학습을 시키고!
4. 테스트 데이터로 예측을 하게 한 후!
5. 성능을 검사해보는 과정을 해보겠다.
1. 데이터 프레임 만들어주기
데이터를 적절히 분리하기 위해서는 train_test_split() 함수를 사용해야한다.
이는 값을 나눠서 반환하는 함수이다!
저장할 변수들을 미리 정해놓자면,
x_train과 x_valid는 feature 데이터이고,
y_train과 y_valid는 label 데이터이다.
다시 말해,
x_train(feature 데이터)와 y_trian(target 데이터) 은 학습(훈련) 데이터로 쓰일 데이터이고,
x_valid(feature 데이터)와 y_valid(target 데이터) 는 예측 데이터로 쓰일 데이터이다.
>>> from sklearn.model_selection import train_test_split
>>> x_train, x_valid, y_train, y_valid = train_test_split(df_iris.drop('target', 1), df_ir
is['target'])
x_train과 x_valid는 feature 데이터 4개의 컬럼만 들어가야하니, 'target' 컬럼(exis=1)을 지워주는 drop() 함수를 사용한다.
그리고 train_test_split() 을 통해 적절히 분배되는데,
x_train, y_train에는 df_iris.drop('target', 1)이 분배되고
x_valid, y_valid에는 df_iris['target']이 분배된다.
이렇게 명령어를 치고나도 뭐가 뭔지 모르겠다면, 직접 변수들을 출력해보면 이해가 잘된다!
# 먼저 x_train은 4개의 feature이고, (80%)
>>> x_train
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
135 7.7 3.0 6.1 2.3
47 4.6 3.2 1.4 0.2
137 6.4 3.1 5.5 1.8
116 6.5 3.0 5.5 1.8
22 4.6 3.6 1.0 0.2
.. ... ... ... ...
77 6.7 3.0 5.0 1.7
68 6.2 2.2 4.5 1.5
11 4.8 3.4 1.6 0.2
46 5.1 3.8 1.6 0.2
139 6.9 3.1 5.4 2.1
[112 rows x 4 columns]
# x_valid는 또 4개의 feature이다. (20%)
>>> x_valid
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
42 4.4 3.2 1.3 0.2
80 5.5 2.4 3.8 1.1
66 5.6 3.0 4.5 1.5
110 6.5 3.2 5.1 2.0
31 5.4 3.4 1.5 0.4
20 5.4 3.4 1.7 0.2
41 4.5 2.3 1.3 0.3
124 6.7 3.3 5.7 2.1
128 6.4 2.8 5.6 2.1
34 4.9 3.1 1.5 0.2
6 4.6 3.4 1.4 0.3
23 5.1 3.3 1.7 0.5
1 4.9 3.0 1.4 0.2
83 6.0 2.7 5.1 1.6
101 5.8 2.7 5.1 1.9
120 6.9 3.2 5.7 2.3
149 5.9 3.0 5.1 1.8
127 6.1 3.0 4.9 1.8
140 6.7 3.1 5.6 2.4
108 6.7 2.5 5.8 1.8
53 5.5 2.3 4.0 1.3
38 4.4 3.0 1.3 0.2
100 6.3 3.3 6.0 2.5
96 5.7 2.9 4.2 1.3
78 6.0 2.9 4.5 1.5
95 5.7 3.0 4.2 1.2
27 5.2 3.5 1.5 0.2
131 7.9 3.8 6.4 2.0
25 5.0 3.0 1.6 0.2
9 4.9 3.1 1.5 0.1
56 6.3 3.3 4.7 1.6
35 5.0 3.2 1.2 0.2
103 6.3 2.9 5.6 1.8
114 5.8 2.8 5.1 2.4
30 4.8 3.1 1.6 0.2
54 6.5 2.8 4.6 1.5
39 5.1 3.4 1.5 0.2
122 7.7 2.8 6.7 2.0
# y_train에는 'target'컬럼만! (80%)
>>> y_train
135 2
47 0
137 2
116 2
22 0
..
77 1
68 1
11 0
46 0
139 2
Name: target, Length: 112, dtype: int32
# y_valid에도 'target' 컬럼만! (20%)
>>> y_valid
42 0
80 1
66 1
110 2
31 0
20 0
41 0
124 2
128 2
34 0
6 0
23 0
1 0
83 1
101 2
120 2
149 2
127 2
140 2
108 2
53 1
38 0
100 2
96 1
78 1
95 1
27 0
131 2
25 0
9 0
56 1
35 0
103 2
114 2
30 0
54 1
39 0
122 2
Name: target, dtype: int32
데이터 갯수 차이를 보면 알겠지만 80 대 20 정도로 분배된다.
x_train, y_train이 80%, x_valid, y_valid가 20%이다.
각각 학습(훈련) 데이터와 예측 데이터로 쓰일 것이다. shape으로 확인해보자.
# 학습(훈련) 데이터 (80%)
>>> x_train.shape, y_train.shape
((112, 4), (112,)) # 112행 4열과 112행
# 예측 데이터 (20%)
>>> x_valid.shape, y_valid.shape
((38, 4), (38,)) # 38행 4열과 38행
이제! 시각화로 확인해보자!!
2. 시각화로 데이터 확인
시각화 모듈로는 seaborn을 사용할 것이다.
>>> import seaborn as sns # 시각화 모듈
>>> sns.countplot(y_train) # 학습(훈련)데이터의 target 데이터

sns의 countplot() 함수는 데이터를 막대그래프로 보여주는 함수이다. 그럼 갑자기 왜 target 데이터를 뽑아봤을까?
x_train, x_valid, y_train, y_valid = train_test_split(df_iris.drop('target', 1), df_iris['target'])
해당 train_test_split() 함수를 이용해 데이터를 배분하는 명령어를 누르고 시각화를 보여줄때마다 그래프는 다양한 비율을 이루게 된다. 즉, 해당 명령어를 몇 번 실행시켜보면 실행시킬 때마다 데이터가 0, 1, 2의 값이 무작위로 shuffle 되는 것을 확인할 수 있다.
그렇게 뽑지않고, 균등하게 뽑도록 하려면 target값만 균등하게 뽑히도록 하면 나머지도 자동으로 균등하게 된다.
이때 쓰이는 옵션은 stratify 옵션이다.
target값을 균등하게 뽑을 수 있도록 하려면 stratify 옵션을 target으로 지정해주면 된다. stratify=df_iris['target']
x_train, x_valid, y_train, y_valid = train_test_split(df_iris.drop('target', 1), df_iris['target'], stratify=df_iris['target'])

그럼 target은 왜 균등하게 배분해야하나 궁금증이 들 수 있다. 만약 target(0,1,2) 중에서 데이터에 '1'의 비율만 너무 심하게 많이 들어가게 되면, 제대로 학습하기가 어렵다. 그래서 0,1,2의 데이터를 골고루 넣어주는 것이다.
옵션을 추가한 후에 계속 실행시켜보고 시각화로 확인해보면 0,1,2의 막대그래프 높이가 계속 비슷하게 나타나는 것을 확인할 수 있다.
이제 학습(훈련) 데이터를 이용해서 학습(훈련)을 시켜보자!
3. 학습 데이터로 학습시키기
데이터를 학습시킬 때 쓰는 함수는 sklearn.svm 모듈의 SVC 함수이다.
SVM(Support Vector Machine)은 데이터 분석 중 분류에 이용되는 지도학습 모델이다!
훈련에 쓸
데이터는 x_train(feature 데이터)과 y_train(label 데이터)이다.이 데이터 샘플을 SVM으로 학습시키는 코드는 다음과 같다.
>>> from sklearn.svm import SVC
>>> clf = SVC() # 모델 생성 (괄호 내에 옵션을 넣을 수있는데, default로 채워진다.)
SVC(C=1.0, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False) # 디폴트값
>>> clf.fit(x_train, y_train) # 훈련 데이터를 넣어서 fit()함수로 모델을 훈련
4. 테스트 데이터로 예측하기
예측 데이터를 인자로 하는 predict() 함수로 예측을 실행한다.
그 예측값은 y_pred에 저장된다.
>>> y_pred = clf.predict(x_valid)
>>> print("예측결과 데이터 : ", y_pred)
예측결과 데이터 : [0 1 1 2 0 0 0 2 2 0 0 0 0 2 2 2 2 2 2 2 1 0 2 1 1 1 0 2 0 0 1 0 2 2 0
1 0 2]
5. 성능 검사
간단히 정답률을 산출해서 성능을 검사해보겠다.
예측 데이터인 x_valid를 넣어서 예측한 결과값과
y_valid(예측 결과 데이터로 주어졌던) 가 일치하는지 비교하여 정답률을 출력해보자.
이때 쓰이는 함수는 sklearn.metrics 모듈의 accuracy_score() 함수이다.
>>> from sklearn.metrics import accuracy_score
>>> print("정답률 : ", accuracy_score(y_valid, y_pred))
정답률 : 0.9736842105263158
97% 정답률이 나왔다!
'언어 > Python' 카테고리의 다른 글
[Pandas] DataFrame 데이터 삭제 (0) | 2021.03.28 |
---|---|
[DataFrame] 특정 문자와 일치하는 행 추출 및 제거하기 (0) | 2021.03.22 |
[colab] 7. colab으로 scikit-learn 모듈 사용하기(Linear SVC) (0) | 2021.01.23 |
[colab] 6. 머신러닝 (0) | 2021.01.23 |
[colab] 5. colab으로 matplotlib를 이용한 그래프 그리기 (0) | 2021.01.22 |