데이터 한 그릇

딥러닝의 동작 원리(2) - 로지스틱 회귀 본문

카테고리 없음

딥러닝의 동작 원리(2) - 로지스틱 회귀

장사이언스 2022. 1. 4. 14:07
  • 시그모이드 함수
  • 오차 공식
  • 로그 함수
  • 로지스틱 회귀에서 퍼셉트론으로

로지스틱 회귀

True or False 중 하나를 선택해야 하는 경우 로지스틱 회귀 원리를 거쳐 이루어진다.

데이터의 위치가 0 혹은 1로 존재할 경우에는, 직선으로 데이터를 잘 표현할 수 없다.

이때 사용하는 게 로지스틱 회귀

 


시그모이드 함수

 

y = 1 / 1 + e^-(ax+b)

 

결국 시그모이드 함수도 ax + b 를 구해야 함을 알 수 있다. (선형 회귀에서도 직선 ax + b 를 구하는 게 목표였다.)

단 직선에서 a는 기울기, b는 절편을 의미했다면 시그모이드 함수는 다르다.

시그모이드 함수 내에서 a 는 그래프의 경사도를 의미, b 는 그래프의 좌우 이동을 의미한다.

a값이 커지면 경사가 커지고 작아지면 경사가 작아진다.

시그모이드 함수 a와 b에 따른 오차 그래프는 각각 다르다.

 

오차값을 기준으로 그래프 모양

 

a가 무한대로 작아질수록 오차도 무한대로 커지지만 a가 무한대로 커진다고 해서 오차가 무한대로 커지지 않는다.

b는 음으로 양으로 무한대로 오차가 늘어나기 때문에 이차 방정식의 모양을 가진다.

 


오차 공식

선형 회귀에서도 직선을 만들고 그 직선의 오차를 구해서 더 적은 오차를 가진 예측선으로 나아가는 경사 하강법을 사용했다.

시그모이드 함수 또한 마찬가지이다. 시그모이드 함수 또한 경사 하강법을 사용하지만 오차를 구하는 방식이 다르다. (선형 회귀는 mse를 구했다.)

시그모이드 함수의 특징은 실제 값이 0일 때, 1에 가깝게 예측할수록 오차 값이 커진다. 반대로 실제 값이 1일 때, 0에 가깝게 예측할수록 오차 값이 커진다. 이는 로그 함수와 같다.

 

즉 시그모이드 함수에선 예측값에 실제값에 따른 오차 그래프가 각각 도출된다.

 


 

로그함수

오차에 대한 그래프는 두 개의 로그 함수가 x자로 겹친 모습으로 나타낼 수 있다.

실제값이 1인 경우 예측값이 1이면 오차가 0이고 예측값이 0에 가까워질수록 오차가 커지는 그래프 모양을 가진다.

반대로 실제값이 0인 경우 예측값이 0이면 오차가 0이고, 예측값이 1에 가까워질수록 오차가 커지는 그래프 모양을 가진다.

식으로는

실제값이 1이면, -logh,

실제값이 0이면, -log(1-h)

로 표현할 수 있다.

그러면 일반적으로는 어떤 식을 사용해야할까?

밑의 식을 사용하면 실제 값에 따라 그에 맞는 그래프를 그릴 수 있다.

 

-{y_Data logh + (1-y_Data)log(1-h)}

(y_Data 가 실제값을 의미, 실제값이 1이면 -logh 만 남고, 0이면, -log(1-h)만 남는다.)

 

=> 이 오차식이 선형 회귀에서는 mse 식과 같다고 보면 된다.

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = [[2,0],[4,0],[6,0],[8,1],[10,1],[12,1],[14,1]]

x_data = [i[0] for i in data]
y_data = [i[1] for i in data]

plt.scatter(x_data, y_data)
plt.xlim(0,15)
plt.ylim(-1,1.1)

a = 0
b = 0
lr = 0.05

def sigmoid(x):
    return 1/(1 + np.e**(-x))


for i in range(2001):
    for x_data, y_data in data:
        a_diff = x_data*(sigmoid(a*x_data+b) - y_data)
        b_diff = sigmoid(a * x_data + b) - y_data
        a = a - lr * a_diff
        b = b - lr * b_diff
        if i% 1000 ==0:
            print(i,a,b)
    
    plt.scatter(x_data, y_data)
    plt.xlim(0,15)
    plt.ylim(-.1,1.1)
    x_range = (np.arange(0,15,0.1))
    plt.plot(np.arange(0,15,0.1),np.array([sigmoid(a*x+b) for x in x_range]))
    plt.show

 

이때 속성이 1개가 아니고 여러 개라면 softmax 함수를 사용해야 한다.

 


로지스틱 회귀에서 퍼셉트론으로

입력 -> 가중치 -> +b -> 함수적용 -> 결과출력

이 그림을 퍼셉트론 이라고 칭함

Comments