도순씨의 코딩일지
딥러닝 :: 다중 분류 문제, 상관도 그래프, 원핫코딩 본문
다중 분류 문제
여러 꽃들의 이미지가 있다. 딥러닝을 이용하여 이 꽃들이 어떤 종류인지 분류할 수 있을까?
위 csv 파일이 담고 있는 정보는 다음과 같다
샘플 수 : 150
속성 수 : 4(A, B, C, D)
- 정보 1(A) : 꽃받침 길이
- 정보 2(B) : 꽃받침 넓이
- 정보 3(C) : 꽃잎 길이
- 정보 4(D) : 꽃잎 넓이
클래스(E) : Iris-setosa, Iris-versicolor, Iris-virginica
지금까지 우리가 살펴보았던 것들은 클래스가 2개였다. 하지만 이번에는 클래스가 3개이다. 즉 참(1)과 거짓(0)으로 구분하는 것이 아닌, 다른 방법으로 접근해야 할 필요가 있다. 이렇게 여러 개의 답 중에서 하나를 고르는 분류 문제를 다중 분류(multi classifciation)라고 한다.
상관도 그래프
먼저 데이터의 일부를 불러와 내용을 보면 다음과 같다.
@ 코드
1
2
3
|
import pandas as pd
df = pd.read_csv("/Users/Downloads/006958-master/deeplearning/dataset/iris.csv", names = ["sepal_length", "sepal_width", "petal_length", "petal_width", "species"])
print(df.head())
|
cs |
@ 실행 결과
1
2
3
4
5
6
|
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
|
cs |
이번에는 pairplot() 함수를 써서 데이터 전체를 한 번에 보는 그래프를 다음과 같이 출력한다.
1
2
3
4
5
|
import seaborn as sns
import matplotlib.pyplot as plt
sns.pairplot(df, hue = 'species')
plt.show()
|
cs |
실행 결과는 다음과 같다.
사진으로 볼 때는 비슷해보이던 꽃잎과 꽃받침의 크기와 넓이가 품종별로 차이가 있음을 알 수 있다.
원 핫 코딩
케라스를 이용하여 아이리스의 품종을 예측하여 보자. 데이터 안에 문자열이 포함되어 있다. 이럴 때는 numpy 보다는 pandas로 데이터를 불러와 X와 Y 값을 구분하는 것이 좋다.
1
2
3
4
5
|
df = pd.read_csv("/Users/hansubin/Downloads/006958-master/deeplearning/dataset/iris.csv", names = ["sepal_length", "sepal_width", "petal_length", "petal_width", "species"])
dataset = df.values
X = dataset[:, 0:4].astype(float)
Y_obj = dataset [:,4]
|
cs |
또한 Y 값이 이번에는 숫자가 문자열입니다. 문자열을 숫자로 바꿔주려면 클래스 이름을 숫자 형태를 바꿔주어야 한다. 이를 가능하게 하는 함수가 sklearn 라이브러리의 LabelEncoder()이다.
1
2
3
4
5
|
from sklearn.preprocessing import LabelEncoder
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
|
cs |
이렇게 하면 array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'])가 array([1, 2, 3])로 바뀐다.
또한 활성화 함수를 적용하려면 Y 값이 숫자 0, 1로 이루어져 있어야 합니다. 이 조건을 만족시키려면 keras.util의 np_utils.categorical() 함수를 적용해야 한다.
1
2
3
|
from keras.utils import np_utils
Y_encoded = np_utils.to_categorical(Y)
|
cs |
array([1, 2, 3])가 다시 array([1., 0., 0.], [0., 1., 0/], [0., 0., 1.])로 바뀐다. 이처럼 여러 개의 Y 값을 0과 1로만 이루어진 형태로 바꿔 주는 기법을 원-핫-인코딩(one-hot-encoding)이라고 한다.
1
2
3
|
model = Sequential()
model.add(Dense(16, input_dim = 4, activation = 'relu'))
model.add(Dense(3, activation = 'softmax'))
|
cs |
activation은 softmax 활성화 활수로 사용하였다. 총합이 1인 형태로 바꿔서 계산해 주는 함수이다. 합계가 1인 형태로 변환하면 큰 값이 두드러지게 나타나고 작은 값은 더 작아진다. 즉 하나만 1이고 나머지는 모두 0인 형태로 전환시킬 수 있다.
아이리스 품종 예측 실행 코드는 다음과 같다.
@ 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
from keras.models import Sequential
from keras.layers.core import Dense
from keras.utils import np_utils
from sklearn.preprocessing import LabelEncoder
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy
import tensorflow as tf
# 시드값 설정
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(seed)
# 데이터 입력
df = pd.read_csv("/Users/Downloads/006958-master/deeplearning/dataset/iris.csv", names = ["sepal_length", "sepal_width", "petal_length", "petal_width", "species"])
# 데이터 분류
dataset = df.values
X = dataset[:, 0:4].astype(float)
Y_obj = dataset [:,4]
# 문자열을 숫자로 변환
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
Y_encoded = np_utils.to_categorical(Y)
# 모델의 설정
model = Sequential()
model.add(Dense(16, input_dim = 4, activation = 'relu'))
model.add(Dense(3, activation = 'softmax'))
# 모델 컴파일
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
# 모델 실행
model.fit(X, Y_encoded, epochs = 50, batch_size = 1)
# 결과 출력
print("\n Accuracy: %.4f" %(model.evaluate(X, Y_encoded)[1]))
|
cs |
@ 실행 결과
1
|
Accuracy: 0.9733
|
cs |
정확도가 97.33%라는 것을 알 수 있다.
* 출처
조태호, 모두의 딥러닝(2017), 길벗
'𝐂𝐎𝐌𝐏𝐔𝐓𝐄𝐑 𝐒𝐂𝐈𝐄𝐍𝐂𝐄 > 𝐃𝐄𝐄𝐏 𝐋𝐄𝐀𝐑𝐍𝐈𝐍𝐆' 카테고리의 다른 글
딥러닝 :: 베스트 모델 만들기 (0) | 2020.08.12 |
---|---|
딥러닝 :: 과적합 피하기 (0) | 2020.08.11 |
딥러닝 :: 데이터 가공하기, 그래프로 표현하기 (0) | 2020.08.10 |
딥러닝 :: 모델 설계하기, 교차 엔트로피, 모델 실행하기 (0) | 2020.08.06 |
딥러닝 :: 오차 역전파, 활성화 함수, 고급 경사 하강법 (0) | 2020.08.06 |