본문 바로가기

파이썬/머신러닝

[#E5] Logistic Classification 이란?

Logistic Classification이란 간단하게 말해 해당하는 데이터 셋 X 가 일정 기준을 넘는지 넘지 못하는지 여부를 데이터 Y ( 0 or 1 )로 표현하는 러닝으로 볼 수 있습니다.


데이터는 예시로 다음과 같이 제공될 수 있습니다.


1
2
x_data = [[40, 40], [50, 50], [60, 60], [70, 70], [80, 80], [90, 90]]
y_data = [[0], [0], [0], [1], [1], [1]]
cs


x_data의 [40, 40] 데이터는 [0] 을 지정합니다.


쉽게 말해 국어 40점, 영어 40점을 맞은 학생은 NPASS ( 통과하지 못함 )입니다. 따라서 [70, 70] 데이터는 [1]을 지정하므로 국어 70점, 영어 70점을 맞은 학생은 PASS ( 통과 ) 입니다.


나머지 데이터도 같은 방식으로 해석할 수 있습니다. 즉, 국어, 영어가 70점이 넘는 학생은 모두 PASS입니다.

 

 

이제 데이터를 비교해보면,


Linear Regression에서 사용되었던 데이터


1
2
x_data = [[1, 2, 3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]]
y_data = [[10],[20],[30],[40],[50]]
cs


위와 같이 Linear Regression의 데이터에서 x_datay_data의 다양하거나 연속적인 숫자들을 지정합니다. 


[data1, data2, data3, ...] - > [ any number ]



그러나 Logistic Classification의 데이터에서 x_data는 y_data의 0 또는 1만을 지정합니다.


[data1, data2, data3, ...] - > [ 0 or 1 ]



즉, Linear Regression에서 연속적인 값을 가지는 Hypothesis = W * x + b 가 가능했던 것에 비해, Logistic Classification은 이 Hypothesis를 오직 0과 1의 사이의 값을 가지도록 가공한 후, 이후 기준값( Default : 0.5 ) 을 통해 0과 1로 캐스팅해야합니다.


바로 이 작업은 Sigmoid 함수로 쉽게 해결할 수 있습니다.



해당 함수는 항상 입력되는 값을 0과 1 사이의 값으로 변환시켜줍니다. 따라서 이후의 캐스팅 문제만 해결하면 됩니다.



따라서 Logistic Classification의 Hypothesis는 다음과 같이 정의할 수 있습니다.


1
2
3
4
//제공된 x데이터가 다차원 데이터이므로 matmul 함수를 이용한다
//LinearRegression Hypothesis = tf.matmul(X, W) + b
 
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
cs



마찬가지로 Cost 함수 또한 Sigmoid 함수를 고려한 형태로 수정해야합니다.


1
2
3
//LinearRegression cost = tf.reduce_mean(tf.square(hypothesis - Y))
 
cost = -tf.reduce_mean( Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis) )
cs

해당 Cost 함수에 대한 정확한 설명은 여기를 참고하세요.



이제 Hypothesis 와 Cost 함수를 알았으니 실행만 하면 됩니다. X와 Y, W, b의 형식은 이전과 동일합니다.

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
x_data = [[4040], [5050], [6060], [7070], [8080], [9090]]
y_data = [[0], [0], [0], [1], [1], [1]]
 
= tf.placeholder(tf.float32, shape=[None, 2])
= tf.placeholder(tf.float32, shape=[None, 1])
 
= tf.Variable(tf.random_normal([21]), name='weight')
= tf.Variable(tf.random_normal([1]), name='bias')
 
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
 
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *
                       tf.log(1 - hypothesis))
 
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)
 
 
with tf.Session() as sess:
    # Initialize TensorFlow variables
    sess.run(tf.global_variables_initializer())
 
    for step in range(10001):
        cost_val, _ = sess.run([cost, train], feed_dict={X: x_data, Y: y_data})
        if step % 200 == 0:
            print(step, cost_val)
 
cs

그런데 해당 부분은 오직 단계와 Cost만을 출력하게 됩니다.


Hypothesis가 잘 작동하여 올바른 예측값을 내었는지, 그리고 0과 1로 캐스팅하여 그 정확도는 얼마나 되는지는 다음과 같이 구할 수 있습니다.


1
2
3
4
//Hypothesis는 그대로 출력만 하면 되므로 제외
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
 
cs


predicted는 hypothesis 가 기준값인 0.5 이하일 경우 0으로, 0.5 이상일 경우 1로 캐스팅됩니다.


accuracy는 캐스팅된 predicted 값과 우리가 제공한 실제 Y 데이터가 맞는지 판단하여 평균을 내서 정확도를 구하게 됩니다.



SOURCE CODE


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
x_data = [[4040], [5050], [6060], [7070], [8080], [9090]]
y_data = [[0], [0], [0], [1], [1], [1]]
 
= tf.placeholder(tf.float32, shape=[None, 2])
= tf.placeholder(tf.float32, shape=[None, 1])
 
= tf.Variable(tf.random_normal([21]), name='weight')
= tf.Variable(tf.random_normal([1]), name='bias')
 
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
 
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *
                       tf.log(1 - hypothesis))
 
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)
 
# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
 
with tf.Session() as sess:
    # Initialize TensorFlow variables
    sess.run(tf.global_variables_initializer())
 
    for step in range(10001):
        cost_val, _ = sess.run([cost, train], feed_dict={X: x_data, Y: y_data})
        if step % 200 == 0:
            print(step, cost_val)
 
    # Accuracy report
    h, c, a = sess.run([hypothesis, predicted, accuracy],
                       feed_dict={X: x_data, Y: y_data})
    print("\nHypothesis: ", h, "\nCorrect (Y): ", c, "\nAccuracy: ", a)
 
cs


실행 결과에서 Cost는 3.8에서 10000번의 학습 후 0.14까지 내려갔습니다.


Hypothesis 값은 또한 0.5 이하에서 0, 그 이상에서 1로 캐스팅된다는 것을 감안하면 실제 Y값과 동일한 결과를 내는 것을 알 수 있습니다.


따라서 정확도는 1.0으로 잘 작동하는 것으로 판명됐습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
step   cost
0      3.8684075
...    ...
10000  0.1484115
 
Hypothesis:  
[[0.03028569]
 [0.15822667]
 [0.3026836 ]
 [0.7823812 ]
 [0.94020283]
 [0.9803797 ]] 
Correct (Y):  
[[0.]
 [0.]
 [0.]
 [1.]
 [1.]
 [1.]] 
Accuracy:  1.0
cs