-
Tensorflow - 분류모델, 원핫인코딩, Softmax(아이리스 품종 분류)생활코딩/머신러닝야학 2020. 8. 18. 12:08
[강의 출처] opentutorials.org/module/4966/28987
아이리스 품종 분류
꽃잎길이 꽃잎폭 꽃받침길이 꽃받침폭 품종 5.1 3.5 1.4 0.2 setosa 7.0 3.2 4.7 1.4 versicolor 6.7 3.3 5.7 2.1 virginica -위 데이터와 같은 독립변수(꽃잎길이, 꽃잎폭, 꽃받침길이, 꽃받침폭)를 가지고 종속변수(품종)을 찾아내는 문제
-아이리스 문제는 기존 레모네이드, 보스턴 집값 문제와는 달리, 종속변수인 '품종'이 숫자값이 아닌 범주형 데이터임
-범주형 데이터는 해당 범주(ex이 아이리스가 어떤 품종 아이리스인지)에 따라 결과를 분류하기 때문에 분류모델
-분류모델의 범주들을 수식으로 처리하려면 원핫인코딩과 같은 변환 작업이 필요
-분류모델은 예측결과값을 해당 범주에 해당할 확률값(0~100%)으로 리턴하며, 그 과정에서 Softmax/Sigmoid 함수를 이용
회귀모델과 분류모델
-회귀모델(Regression) : 종속변수가 양적 데이터인 경우 (ex 37점/48점/67점 등등)
-분류모델(Classification) : 종속변수가 범주형 데이터인 경우 (ex 합격/불합격)
원핫인코딩(onehot-encoding)
-아래 테이블에서처럼, 품종 분류만큼 범주를 추가한 다음, 해당 범주에 해당하면 1, 아니면 0으로 데이터를 변환하는 작업
-pd.get_dummies(데이터)로 처리 가능
품종 → setosa vriginica versicolor setosa 1 0 0 virginica 0 1 0 versicolor 0 0 1 -위의 아이리스 데이터 예제를 변환하면 아래와 같이 됨
꽃잎길이 꽃잎폭 꽃받침길이 꽃받침폭 품종.setosa 품종.versicolor 품종.virginica 5.1 3.5 1.4 0.2 1 0 0 7.0 3.2 4.7 1.4 0 1 0 6.7 3.3 5.7 2.1 0 0 1 Softmax/Sigmoid
-결과를 확률표현으로 받기 위해 이용하는 함수. K가 범주 개수일 때,
-Softmax: K > 2, 다층 분류시 사용 (the multiclass logistic regression)
-Sigmoid: K = 2, 이진 분류시 사용 (the two-class logistic regression)
[출처] stats.stackexchange.com/questions/233658/softmax-vs-sigmoid-function-in-logistic-classifier
-아이리스 문제의 경우, 종속변수가 3개이기 때문에 수식도 3개가 필요.
y1 = w1x1 + w2x2 + w3x3 + w4x4 + b
y2 = w1x1 + w2x2 + w3x3 + w4x4 + b
y3 = w1x1 + w2x2 + w3x3 + w4x4 + b-위와 같은 경우, y1, y2, y3은 이론적으로 +-무한대의 값을 가질 수 있기 때문에, 이를 확률값으로 변환하기 위해서 아래와 같이 함수 적용
y1 = softmax(w1x1 + w2x2 + w3x3 + w4x4 + b)
y2 = softmax(w1x1 + w2x2 + w3x3 + w4x4 + b)
y3 = softmax(w1x1 + w2x2 + w3x3 + w4x4 + b)-이렇게 적용된 값이 아래와 같다면,
y1(품종.setosa) == 0.2
y2(품종.virginica) == 0.3
y3(품종.versicolor) == 0.5
각각 setosa일 확률은 20%, virginica일 확률은 30%, versicolor일 확률은 50%라는 의미
-이 경우 Softmax처럼, 퍼셉트론의 출력 양식을 조절해주는 함수들을 활성화 함수(Activation)이라고 부름
# 라이브러리 사용 import tensorflow as tf import pandas as pd # 1.과거의 데이터를 준비합니다. 파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/iris.csv' 아이리스 = pd.read_csv(파일경로) 아이리스.head() # 원핫인코딩 인코딩 = pd.get_dummies(아이리스) """ 데이터 내의 범주형 데이터에 대해 원핫인코딩한 결과를 얻을 수 있음 """ 인코딩.head() # 칼럼이름 출력 print(인코딩.columns) """ Index(['꽃잎길이', '꽃잎폭', '꽃받침길이', '꽃받침폭', '품종_setosa', '품종_versicolor', '품종_virginica'], dtype='object') # pandas에서 원핫인코딩이 완료되었기 때문에 품종_품종명 컬럼이 새로 생김 """ # 독립변수, 종속변수 독립 = 인코딩[['꽃잎길이', '꽃잎폭', '꽃받침길이', '꽃받침폭']] 종속 = 인코딩[['품종_setosa', '품종_versicolor', '품종_virginica']] print(독립.shape, 종속.shape) # (150, 4) (150, 3) # 2. 모델의 구조를 만듭니다 X = tf.keras.layers.Input(shape=[4]) """독립변수 = ['꽃잎길이', '꽃잎폭', '꽃받침길이', '꽃받침폭']""" Y = tf.keras.layers.Dense(3, activation='softmax')(X) """종속변수 = ['품종_setosa', '품종_versicolor', '품종_virginica'] 분류문제이기 때문에 활성화함수(activation)에 softmax 지정 필요 기존 레모네이드/보스턴 집값 문제는 y=x 형태의 identity 활성화 함수를 적용했었던 것""" model = tf.keras.models.Model(X, Y) model.compile(loss='categorical_crossentropy', # 분류모델이므로, 회귀의 mse와는 다름 metrics='accuracy') # 분류문제는 성능을 정확도로 출력이 가능 # 3.데이터로 모델을 학습(FIT)합니다. model.fit(독립, 종속, epochs=100) """ Epoch 78/100 5/5 [==============================] - 0s 2ms/step - loss: 0.3041 - accuracy: 0.9400 Epoch 79/100 5/5 [==============================] - 0s 2ms/step - loss: 0.3028 - accuracy: 0.9467 # loss가 점차 줄어들고 있는 상황에서는 여력이 있으므로 accuracy가 1에 근접할 때까지 반복학습 """ # 모델을 이용합니다. # 맨 처음 데이터 5개 print(model.predict(독립[:5])) """ [[9.86754239e-01 1.31175015e-02 1.28261789e-04] # setosa 0.986754239 [9.73487616e-01 2.59828754e-02 5.29477198e-04] # setosa 0.973487616 [9.81271088e-01 1.84753798e-02 2.53479055e-04] # setosa 0.981271088 [9.63053584e-01 3.63809019e-02 5.65536087e-04] # setosa 0.963053584 [9.87355530e-01 1.25438590e-02 1.00636840e-04]] # setosa 0.987355530 """ print(종속[:5]) # 실제 정답 확인 """ 품종_setosa 품종_versicolor 품종_virginica 0 1 0 0 1 1 0 0 2 1 0 0 3 1 0 0 4 1 0 0 """ # 맨 마지막 데이터 5개 print(model.predict(독립[-5:])) """ [[3.0813608e-04 1.8219605e-01 8.1749576e-01] # virginica 0.81749576 [3.5609794e-04 2.2095713e-01 7.7868676e-01] # virginica 0.77868676 [5.7861791e-04 3.2042387e-01 6.7899752e-01] # virginica 0.67899752 [3.8180550e-04 3.3763635e-01 6.6198188e-01] # virginica 0.66198188 [8.5562665e-04 4.7935012e-01 5.1979423e-01]] # virginica 0.51979423 versicolor 0.47935012 """ print(종속[-5:]) # 실제 정답 확인 """ 품종_setosa 품종_versicolor 품종_virginica 145 0 0 1 146 0 0 1 147 0 0 1 148 0 0 1 149 0 0 1 """ # weights & bias 출력 print(model.get_weights()) """ y1 y2 y3 [array([[ 0.72453135, 0.05253643, 0.41662827], # 꽃잎길이 [ 1.4853274 , 0.3600737 , -1.2542167 ], # 꽃잎폭 [-2.1532962 , 0.42979974, 0.42914116], # 꽃받침길이 [-1.7550048 , -1.0885421 , 1.1693642 ]], dtype=float32), # 꽃받침폭 array([ 1.1139759 , 0.4094376 , -0.87570363], dtype=float32)] # bias # 위의 weight와 bias로 수식을 구성한다면 아래와 같이 됨 y1 = softmax(0.72453135 * x1 + 1.4853274 * x2 + -2.1532962 * x3 + -1.7550048 * x4 + 1.1139759) """
'생활코딩 > 머신러닝야학' 카테고리의 다른 글
Tensorflow - 데이터 타입과 N/A값 (전처리 Tip) (0) 2020.08.19 Tensorflow - 히든레이어와 인공신경망 (0) 2020.08.19 Tensorflow - 딥러닝 모델과 퍼셉트론(보스턴 집값 예측) (0) 2020.08.17 Tensorflow - 지도학습 순서(레모네이드 판매 예측) (0) 2020.08.14 Pandas 기초 - shape, indexing, columns, head (0) 2020.08.14