ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Tensorflow - 분류모델, 원핫인코딩, Softmax(아이리스 품종 분류)
    생활코딩/머신러닝야학 2020. 8. 18. 12:08

    [강의 출처] opentutorials.org/module/4966/28987

     

    세번째 딥러닝 - 아이리스 품종 분류 - Tensorflow 1

    수업소개 아이피스 품봉을 분류하는 딥러닝 모델을 텐서플로우를 이용하여 만들어 보고, 분류모델과 회귀모델의 차이점을 이해합니다. 범주형 변수의 처리 방법인 원핫인코딩을 해야하는 이유

    opentutorials.org


    아이리스 품종 분류

    꽃잎길이 꽃잎폭 꽃받침길이 꽃받침폭 품종
    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)
    """

    댓글

Designed by Tistory.