티스토리 뷰

반응형

Logistic Regression란 선형회귀와 다르게 출력이 2가지인(0또는 1) 이항분류를 하는 경우 사용한다.


예를들어 새로 온 메일이 스팸인지 아닌지 구별하거나 남자인지 여자인지 등 


분류의 경우가 2가지인것을 사용한다.


tensorflow 소스를 통해 알아보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
 
x_data = [[12],
          [23],
          [31],
          [43],
          [53],
          [62]]
y_data = [[0],
          [0],
          [0],
          [1],
          [1],
          [1]]
= np.asarray(x_data)
= np.reshape(y_data,[-1])
df = pd.DataFrame(dict(x=x[:,0], y=x[:,1], color=y))
sns.lmplot('x''y', data=df, hue='color', fit_reg=False)
plt.show()
 
cs


가장 처음 위와 같이 x_data와 y_data를 구성하였습니다.


이를 pandas 를 이용하여 그래프로 표현하면 아래와 같습니다.


y가 0인경우와 1인 경우 hue를 이용하여 색을 다르게 점을 찍었습니다.


값이 0,1 둘 뿐이므로 이 두개의 클래스를 분류하기 위해서 Logistic Regression을 사용하면 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
= tf.placeholder(tf.float32,[None,2])
= tf.placeholder(tf.float32,[None,1])
 
logits = tf.layers.dense(X,1,activation=None)
 
Y_ = tf.nn.sigmoid(logits)
predict = tf.round(Y_)
 
cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits,labels=Y))
train = tf.train.AdamOptimizer(0.01).minimize(cost)
 
sess = tf.Session()
sess.run(tf.global_variables_initializer())
 
for i in range(10001):
    c,_ = sess.run([cost,train],feed_dict={X:x_data,Y:y_data})
    if i%1000==0:
        print('cost:',c)
print('Finish')
 
sess.run([predict],feed_dict={X:x_data})
cs

1개층의 Layer로 tensorflow의 dense(Fully connected Network)함수를 이용하여 네트워크를 구성하였습니다.

이후에 sigmoid함수를 통해 예측된 값을 Y_로 두었고 round함수를 통해 0 또는 1로 반올림한 값을 predict에 저장하였습니다.

sigmoid함수란 아래 그래프와 같습니다.

이처럼 1/1+exp(-x) 함수로 음의 무한부터 양의무한까지 0~1 값만을 가집니다.


따라서 입력값 x가 0보다 작으면 y는 0.5보다 작아지고 x가 0보다 크면 y는 0.5보다 커집니다.


이를 기준으로 두가지의 클래스를 분류하게 됩니다.


실제값과 예측값의 오차함수 cost는 다음과 같이 정의합니다. 



예를들어 예측이 맞은 경우 실제 y가 0이고 예측값 h(x)가 0이면 cost값은 0이 됩니다.


반대로 y가 1, h(x)가 1 이어도 cost값은 0이 됩니다.


그러나 예측이 틀린경우, y=1, h(x)=0인 경우와 y=0, h(x)=1인 경우는


cost함수가 무한대로 값이 커집니다. (실제로 h(x)는 0과 1사이의 값으로 0과 1에 가까울뿐 0,1은 아니다.)


이를 이용하여 이 cost를 줄이기 위한 Optimizer를 사용합니다.


이를 직접 구현하지 않고 tensorflow를 이용하여


tf.nn.sigmoid_cross_entropy_with_logits(logits=, labels=)


라는 함수로 쉽게 구현이 가능합니다.


학습하는 소스는 이전과 같습니다.


학습이 잘 되었는지 확인하기 위해서 임의의 점을 네트워크를 통과시켜 보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import random
data=[]
pred=[]
for i in range(0,30):
    x = random.randint(0,6)
    y = random.randint(0,3)
    data.append([x,y])
    pred.append(sess.run(predict,feed_dict={X:[[x,y]]}))
    
data = np.asarray(data)
pred = np.reshape(pred,[-1])
 
df = pd.DataFrame(dict(x=data[:,0], y=data[:,1], color=pred))
sns.lmplot('x''y', data=df, hue='color', fit_reg=False)
plt.show()
 
cs

위와 같은 소스를 통해 임의의 점 30개를 네트워크에 통과시키고

예측된 값들을 pred 변수에 저장하여 이를 pandas를 통해 plot해보았습니다.


위 그래프와 같이 첫 데이터(맨 위에 그래프)를 학습하여 좌표평면에서 


잘 구분이 되는 것을 확인할 수 있습니다.


이를 통해 Logistic Regression이 잘 학습된 것을 알 수 있습니다.





반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday