본문 바로가기
머신러닝/Linear Regression

회귀를 통해 이해하는 Cost function_1

by 미생22 2024. 5. 3.
728x90

Cost Function이란 데이터 셋과 어떤 가설 함수와의 오차를 계산하는 함수이다. Cost Function의 결과가 작을수록 데이터셋에 더 적합한 Hypothesis(가설 함수)라는 의미다. Cost Function의 궁극적인 목표는 Global Minimum을 찾는 것이다.

 

주택의 규모에 따른 가격이 위와 같다고 하면, 우리가 데이터를 하나 주고 가격을 가격을 알려줍니다. 정답을 알려주기 때문에 지도학습(supervised learning)이네요. 그 출력 결과인 가격은 연속적인(continuous) 값이므로 회귀(regression) 문제입니다.

 

어쨌든 머신러닝 모델은 학습데이터를 주고 알고리즘을 만듭니다. 그 후 hypothesis라는 가설(=모델)이 나옵니다.

hypothesis는 1차식이라고 하면 선형 모델이 되는 것이고, 어쨋건 저 기울기와 y절편을 알면 됩니다.

어떻게 하면 알 수 있을까요?

만약 1차 함수라면 선형 회귀입니다. 두 개의 변수만 알아내면 되지요.

우리는 입력값을 알고있고, 출력값을 알고 있습니다. 이걸 이용해서 모델을 만들었다고 합시다.

우리는 여기서 참 값과 모델 사이의 오차가 최소가 되는 모델을 선정하고 싶은데요,

데이터가 한 직선 위에 있을 수 있지만, 아닌 경우들도 있습니다. 

점 3개를 가장 잘 지나가는 직선을 찾아야합니다. 어떤 직선을 손으로 그어도 최선인가.. 싶으므로

 

그림에서 나오는 연두색 길이(Error)가 최소가 되는 직선을 찾으면 됩니다. 먼저 각각의 에러를 구합니다.

 

여기서 방향이 중요하니까 절대값을 씌우던, 제곱을 하던 하는겁니다.

 

저희는 각각의 에러를 제곱하겠습니다. (에러를 제곱하는 이유는 부호를 없애기 위함입니다)

그런데 보통 절대값보다 제곱을 좋아합니다(미분할 수 있어서입니다^^)

 

에러 각각을 제곱하고 평균을 구합니다. 이게바로 그 유명한 mean squared error(mse)입니다.

 

이게 그 유명한 cost function...중 하나입니다.

 

딥러닝 할때 매우 자주 많이 사용할 예정입니다.

위 식의 본질은 결국 에러인데요, cost function은 에러를 표현하는 하나의 도구인데 이 에러가 작아질수록 좋은거겠죠.

이 cost function을 최소화 할 수 있다면 최적의 직선을 찾을 수 있습니다.

계산해 보겠습니다.

h는 theta*x라고 가정하고 cost func를 찾았습니다. 이 cost func는 h자리에 theta*x를 넣으면 됩니다.

이거를 전개해서 정리하면 됩니다.

 

J를 최소로 만들 수 있을까요?

일단 전개부터 하겠습니다.

그 전에 poly1d에 대해서 다시 알아보면,

 

import numpy as np

a = np.poly1d([1, 1])
b = np.poly1d([1, -1])
a, b

 

a*b

 

poly1d에 대해 눈치채셨나요? np.poly1d([1, 1])sms x+1, np.poly1d([1, -1])은 x-1 이었습니다.
따라서 x*2-1이기 때문에 [1, 0, -1]이 나온겁니다.
이게 poly1d의 역할입니다.

 

pinkwink.kr에서 numpy poly1d를 검색하면 더 자세한 설명이 나옵니다.

이제 theta를 구하기 위해 poly1d를 써보겠습니다.

np.poly1d([2, -1])**2 + np.poly1d([3, -5])**2 + np.poly1d([5, -6])**2

 

그리고 이를 그래프로 그린 뒤 최솟값을 찾아보겠습니다.

 

2차함수의 최솟값을 찾는 방법은 고등학교때 미분을 통해 구할 수 있다는 것을 배웠습니다.

손으로 미분해보겠습니다.

우리는 python이 있기 때문에 python으로 미분하기 위해 sympy를 사용해보겠습니다.

!pip install sympy

설치를 해주고 sym이라고 줄여서 불러보겠습니다.

import sympy as sym

theta = sym.Symbol('theta') #theta를 기호로 인식하라는 뜻입니다.
diff_th = sym.diff(38*theta**2 - 94*theta + 62, theta)

 

sym.Symbol('theta') 는theta를 기호로 인식하라는 뜻입니다.

 

여기서 diff_th를 출력해보면,

1.2368정도가 나와 아래와 같이 1.24로 볼 수 있습니다.

행렬이 아니라 미분을 동원한 OLS라고 봐도 됩니다. ㅎㅎ

 

 

728x90