참고 서적
도서명: 모두의 딥러닝 저자 : 조태호 출판 : 길벗 발매 : 2020.01.27 |
가장 훌륭한 예측선 긋기 : 선형 회귀 (Linear Regression)
선형 회귀의 정의
"학생들의 중간고사 성적이 [ ]에 따라 다 다르다."
여기서 [ ]에 들어갈 내용을 '정보'라고 한다. 성적을 변하게 하는 '정보' 요소를 x라고 하고, 이 x 값에 따라 변하는 '성적'을 y라고 할 때, 'x 값이 변함에 따라 y 값도 변한다'는 이 정의 안에서, 독립적으로 변할 수 있는 값 x를 독립 변수라고 한다. 또한, 이 독립 변수에 따라 종속적으로 변하는 y를 종속 변수라고 한다. 선형 회귀란 독립 변수 x를 사용해 종속 변수 y의 움직임을 예측하고 설명하는 작업을 말한다.
하나의 x 값 만으로도 y 값을 설명할 수 있을 때 이를 단순 선형 회귀(simple linear regression)라고 한다. 또한, x 값이 여러 개 필요할 때는 다중 선형 회귀(multiple linear regression)라고 한다.
y = ax + b
이 직선을 훌륭하게 그으러면 직선의 기울기 a 값과 y 절편 b 값을 정확히 예측해내야 한다. 딥러닝을 포함한 머신러닝의 예측은 결국 이러한 기본 접근 방식과 크게 다르지 않다. 기존 데이터(정보)를 가지고 어떤 선이 그려질지를 예측한 뒤, 아직 답이 나오지 않은 그 무언가를 그 선에 대입해 보는 것이다.
최소 제곱법 : 기울기와 y절편을 알아보자
우리가 최소 제곱법(method of least squares)이라는 공식을 알고 적용한다면, 이를 통해 일차 함수의 기울기 a와 y 절편 b를 바로 구할 수 있다.
최소 제곱법은 주어진 x의 값이 하나일 때 적용이 가능하다. 여러 개의 x가 주어지는 경우 경사하강법을 사용한다.
위의 식을 쉽게 풀어서 다시 쓰면 x의 편차(각 값과 평균과의 차이)를 제곱해서 합한 값을 분모로 놓고, x와 y의 편차를 곱해서 합한 값을 분자로 놓으면 기울기가 나온다는 뜻이다.
이 직선에 우리는 다른 x 값(공부한 시간)을 집어넣어서 '공부량에 따른 성적을 예측'할 수 있다.
코딩으로 확인하는 최소 제곱
import numpy as np
#x값과 y 값
x = [2,4,6,8]
y = [81,93,91,97]
#x와 y의 평균 값
mx = np.mean(x)
my = np.mean(y)
print("x의 평균 값:", mx)
print("y의 평균 값:", my)
#기울기 공식의 분모
divisor = sum([(i - mx)**2 for i in x])
def top(x,mx,y,my):
d = 0
for i in range(len(x)):
d += (x[i] - mx) * (y[i] - my)
return d
dividend = top(x,mx,y,my)
print("분모:", divisor)
print("분자:", dividend)
a = dividend / divisor #기울기
b = my - (mx*a) # y절편
print("기울기 a =", a)
print("y 절편 b =", b)
mean() 함수: x의 모든 원소의 평균을 구한다
for i in x : x의 원소를 한 번씩 i 자리에 대입
평균 제곱 오차 : 오차를 평가하는 방법
딥러닝은 대부분 입력 값이 여러 개인 상황에서 이를 해결하기 위해 실행된다. 따라서 여러 개의 입력을 처리하기에는 최소 제곱법으로는 해결하기 어렵다. 이렇게 여러 개의 입력 값을 계산할 때는 임의의 선을 그리고 난 후, 이 선이 얼마나 잘 그려졌는지를 평가하여 조금씩 수정해 가는 방법을 사용한다. 이를 위해 주어진 선의 오차를 평가하는 오차 평가 알고리즘이 필요하다. 다음은 오차를 평가하는 방법 중 가장 많이 사용되는 평균 제곱 오차(mean square error, MSE)이다.
기울기 a와 y 절편 b를 찾아내는 가장 많이 사용하는 방법은 '일단 그리고 조금씩 수정해 나가기' 방식이다. 이는 딥러닝을 가능하게 해 주는 가장 중요한 원리 중 하나이다. 나중에 그린 선이 먼저 그린 선 보다 더 좋은지 나쁜지 각 선의 오차를 계산할 수 있어야 하고, 오차를 작은 쪽으로 바꾸는 알고리즘이 필요하다.
오차 = 예측 값 - 실제 값
오차에 양수와 음수가 섞여 있어서 오차를 단순히 더해 버리면 합이 0이 될 수도 있다. 부호를 없애야 정확한 오차를 구할 수 있다.따라서 오차의 합을 구할 때는각 오차의 값을 제곱해 준다. 이를 식으로 표현하면 다음과 같다.
오차의 합에 이어 각 x 값의 평균 오차를 이용한다. 위에서 구한 값을 n으로 나누면 오차 합의 평균을 구할 수 있다. 이를 평균 제곱 오차(Mean Squared Error, MSE)라고 부른다.
선형 회귀란
임의의 직선을 그어 이에 대한 평균 제곱 오차를 구하고,
이 값을 가장 작게 만들어 주는 a와 b 값을 찾아가는 작업이다.
코딩으로 확인하는 평균 제곱 오차
1. 임의로 정한 기울기 a와 y 절편 b의 값이 각각 3과 76이라고 할 때 fake_a_b라는 리스트를 만들어 여기에 이 값을 저장한다.
fake_a_b = [3, 76]
2. data라는 리스트를 만들어 공부한 시간과 이에 따른 성적을 각각 짝을 지어 저장한다.
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x = [i[0] for i in data]
y = [i[1] for i in data]
3. x 리스트와 y 리스트를 만들어 첫 번째 값을 x 리스트에 저장하고 두 번째 값을 y 리스트에 저장한다.( 평균 제곱 오차 식 구현)
def mse(y_hat, y):
return ((y_hat-y) ** 2).mean())
4. predict()라는 함수를 사용해 일차 방정식 y = ax + b를 구현한다.
def predict(x):
return fake_a_b[0]*x + fake_a_b[1]
5. mse() 함수에 데이터를 대입하여 최종값을 구하는 함수 mse_val()을 만듭니다.
def mse_val(predict_result, y):
return mse(np.array(predict_result), np.array(y))
6. 모든 x 값을 predict() 함수에 대입하여 예측 값을 구하고, 이 예측 값과 실제 값을 통해 최종값을 출력하는 코드를 다음과 같이 작성한다.
# 예측 값이 들어갈 빈 리스트
predict_result = []
# 모든 x 값을 한 번씩 대입하여
for i in range(len(x)):
# 그 결과에 해당하는 predict_result 리스트를 완성
predict_result.append(predict(x[i]))
print("공부시간 = %.f, 실제 점수 = %.f, 예측 점수 = %.f" % (x[i], y[i], predict(x[i])))
최종 코드
import numpy as np
# 기울기 a와 y 절편 b
fake_a_b = [3, 76]
# x, y의 데이터 값
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x = [i[0] for i in data]
y = [i[1] for i in data]
# y = ax + b에 a와 b 값을 대입하여 결과를 출력하는 함수
def predict(x):
return fake_a_b[0]*x + fake_a_b[1]
# MSE 함수
def mse(y_hat, y):
return ((y_hat, y) ** 2).mean())
# MSE 함수를 각 y 값에 대입하여 최종 값을 구하는 함수
def mse_val(predict_result,y):
return mse(np.array(predict_result), np.array(y))
# 예측 값이 들어갈 빈 리스트
predict_result = []
# 모든 x 값을 한 번씩 대입하여
for i in range(len(x)):
# predict_result 리스트를 완성
predict_result.append(predict(x[i]))
print("공부한 시간 = %.f, 실제 점수 = %.f, 예측 점수 = %.f" % (x[i], y[i], predict(x[i])))
# 최종 MSE 출력
print("mse 최종값: " + str(mse_val(predict_result,y)))
이를 통해 우리가 처음 가정한 a = 3, b = 76은 오차가 약 11.0이라는 것을 알게 되었다.
'공부정리 > 모두의 딥러닝 (교재 정리)' 카테고리의 다른 글
[deeplearning] 신경망의 이해 - 오차 역전파 (0) | 2022.04.29 |
---|---|
[deeplearning] 신경망의 이해 - 퍼셉트론, 다층 퍼셉트론 (0) | 2022.04.29 |
[deeplearning] 딥러닝의 동작 원리 - 로지스틱 회귀 (0) | 2022.04.14 |
[deeplearning] 딥러닝의 동작 원리 - 경사 하강법 (0) | 2022.04.14 |
[deeplearning] 딥러닝을 위한 기초 수학 (0) | 2022.04.07 |