본문 바로가기
데이터 과학 관련 스터디/모두의 딥러닝

[모두의 딥러닝] 12장 다중 분류 문제 해결하기

by inhovation97 2020. 7. 12.

이제껏 우리는 이진분류에 관한 데이터만 다루었습니다. 12장은 레이블 데이터가 3개 이상의 범주형 데이터를 다룰 때를 위한 챕터입니다.

앞에서 딥러닝을 공부하면서 레이블의 범주가 3개 이상이면 어떤 식으로 알고리즘이 분류할지 계속 궁금했습니다.

 

출력층은 활성화 함수(sigmoid)가 1 or 0의 값을 뱉어내는데 과연 이럴 때는 어떻게 알고리즘을 설계하거나 작동할지가 진짜 의문이었는데 답은 간단하더군요! ㅋㅋ

그냥 출력층의 개수를 범주의 개수와 똑같이 맞춥니다!

이제 데이터를 보겠습니다. 이번 데이터는 꽃잎의 모양과 길이 등의 정보를 토대로 꽃의 3종류를 분류하는 문제입니다.

 

 

 

<pair plot>

 

pair plot은 몇개의 피쳐들에 한하여 범주형 데이터를 시각화 할때, hue를 지정해주고 그리면 굉장히 유용합니다. 범주별 특성을 한눈에 파악할 수 있습니다.

정말 버릴 피쳐가 없을 정도로 꽃잎의 종류에 따라 plot이 아주 명확하게 나오네요!

#필요한 모듈 import
import seaborn as sns
import matplotlib.pyplot as plt

sns.pairplot(df, hue='species') # hue에 범주형 피쳐를 넣어 산점도를 범주로 구분하여 시각화

 

 

 

<원-핫 인코딩>

 

 우리는 꽃잎의 정보들을 가지고 품종을 예측해야합니다. 하지만 품종 피쳐인 'species'가 문자열로 되어 있어요. 컴퓨터는 문자열보다는 숫자를 좋아합니다. 숫자로 바꿔주면 속도 측면에서도 유리할 수 있기 때문에 우리는 문자열을 숫자로 바꿔주는 작업을 해야합니다.

문자열로 표현된 범주형 변수를 숫자로 바꿔주면 '정수 인코딩'

0, 1 값으로 값을 변경해면 '원-핫 인코딩'이라고 합니다.

 

굳이 용어를 구분하는건 중요치 않지만 이번 데이터 셋은 출력층에 있어서 소프트 맥스라는 활성화 함수를 이용해야 하기 때문에 0,1로 바꿔주는 원-핫 인코딩을 수행할겁니다.

# 원-핫 인코딩

import tensorflow as tf

dataset = df.values
X = dataset[:,0:4].astype(float)
Y_obj = dataset[:,4]

from sklearn.preprocessing import LabelEncoder

e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)


#from tensorflow.keras.utils import np_utils

Y_encoded = tf.keras.utils.to_categorical(Y)

저는 항상 데이터를 다룰 때, pandas를 이용해서 데이터 프레임 형태로 많이 다뤘는데, 책에서는 이렇게 array배열로 많이 다루더군요. 이미 습관이 많이 베어서... 하지만 분명히 속도 측면에서 훨씬 좋을 것 같아요.

 

 

 

주석처리한 np_utils 모듈은 아마 버전차이 때문인지 임포트되지 않지만, to_categorical 함수는 잘 작동합니다. 신경 안써도 될 것 같아요!

원-핫 인코딩으로 Y를 만들면 끝이 아니라, 활성화 함수를 적용하기 위해서는 Y_encoded의 형태로 바꿔줘야 합니다. 이는 3가지로 분류하는 데에 각 범주들에게 확률을 개별적으로 부여하지 않고, 세 범주 확률값의 합을 1로 계산해놓기 위함입니다. 그래서 활성화 함수도 소프트맥스(softmax) 함수를 이용합니다.

 

아래 링크를 보면 데이터 셋도 똑같이 iris데이터를 예로 들어서 쉽게 이해할 수 있습니다. 정수 인코딩을 하게 되면 발생하는 문제점에 관한 내용도 있습니다.

https://wikidocs.net/35476

 

 

<모델 최적화>

 

오차 함수는 다중 분류이기 때문에 categorical_crossentropy를 이용했고, 최적화 함수는 9장에서 나왔던 adam으로 설정했습니다.

# 필요한 모듈 import
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.preprocessing import LabelEncoder


# 모델의 설정

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]))

책이랑 같은 정확도가 나옴을 알 수 있습니다.

'다중 분류 문제 해결하기' 12장도 포스팅을 마칩니다.

댓글