ecsimsw

선형 회귀 / Linear Regression / MSE / cost function 본문

선형 회귀 / Linear Regression / MSE / cost function

JinHwan Kim 2020. 2. 28. 09:55

Linear Regression

 

   - 어떠한 경향을 갖는다. 라는 것에 다음 데이터의 결과를 예측할 때가 많다. 더 많은 시간을 공부에 쓰면 더 좋은 점수를 받더라, 반도체 집적 회로의 성능이 2년에 2배씩 증가하더라. 처럼 기존의 데이터가 어떤 경향을 갖는지를 파악하여, 그럼 8시간 공부한 시험에는 몇 점을 받겠구나, 반도체는 2020년도에 어떤 성능을 갖겠구나 라는 예측을 하게 된다. 이렇게 종족 변수(y)와 독립 변수(x)의 선형 상관 관계를 모델링한 것을 선형 회귀라고 한다. 

 

   - 독립 변수(x)의 개수에 따라, 1개라면 단순 선형 회귀, 2개 이상이라면 다중 선형 회귀 분석이라고 한다.

 

Hypothesis

 

   - 대략 50명 정도 되는 사람의 키와 몸무게를 기록했다고 생각해보자. 해당 집단의 기록은 아래 그래프처럼 키가 클수록 무거운 경향을 보였기에 조사자는 키가 큰 사람이 몸무게가 많이 나갈 것이라는 예측을 하게 되었다. 그럼 이 경향을 함수로 표현하고 175cm인 사람을 대입하면, 그 사람의 몸무게를 대략 예상할 수 있을 것이다. 이 함수를 가설(Hypothesis)라고 한다.

 

어떤 가설이 데이터를 가장 합리적으로 표현할까

   - 3명의 조사자 중 첫번째 조사자는 몸무게별 키의 대략적인 분표를 파란색 직선으로, 두번째 조사자는 빨간색 직선으로, 세번째 조사자는 초록색 직선으로 생각하였다. 그래서 각각 175cm라는 새로운 데이터가 들어왔을 때, 본인이 예측한 키의 값을 합리적이라고 주장한다. 어떤 조사자가 가장 합리적으로 예측하였을까

 

단순 선형 회귀 가설

   - 정확히 표시한 직선이 아니지만 셋 중에서는 빨간색 직선이 데이터 경향을 가장 잘 표현하였고, 새로운 데이터에 대한 예측이 가장 그럴 듯 할 것이다. 즉 정확한 예측을 위해선 기존의 데이터 양상을 얼마나 합리적으로 정확하게 표현하는데에 있다. 

 

Cost function / MSE (mean squared Error)

 

   - 그렇다면 어떻하면 분포를 가장 잘 표현하는 직선을 찾을 수 있을까. 아래 그림처럼 직선이 가설이고, 직선 위의 원 표시가 예측 값, 검정색이 실제 값이다. 즉 오차는 그 둘 사이의 거리인 파란색 점선이 될 것이다. 이 오차를 가장 작게하는 직선이 가장 최적의 가설일 것이다.

 

오차 = 실측 값과 예측 값 사이의 거리

   - 이를 수식으로 표현하면 각 예측 값 - 실측 값의 제곱의 합으로 한 직선의 오차의 절대 크기를 구할 수 있고, 이를 데이터 개수 n으로 나눠 오차 제곱 합의 평균을 구하는 다음 식을 Mean squared error, MSE라고 한다.

 

MSE

    - 위 MSE cost 식을 가장 작게 하는 H(x), 즉 W,b를 구하는 것이 학습의 목표가 된다. 이 오차를 최소화하는 최적화 알고리즘을 Optimizer라고 한다.  

 

Example

import tensorflow as tf

x =tf.placeholder(tf.float32)
y =tf.placeholder(tf.float32)

W = tf.Variable(tf.random_normal([1])) 
b = tf.Variable(tf.random_normal([1]))

hypothesis = W*x+b

cost = tf.reduce_mean(tf.square(hypothesis-y))

#Optimizer => Gradient Desent 
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

for step in range(2001):
	h_, W_, b_, t_ = sess.run([hypothesis, W, b, train], feed_dict = {x:[1,2,3], y:[2,4,6]})
	if step%100 ==0:
		print(step, W_, b_)

print(sess.run(hypothesis,feed_dict = {x:[4,54]})) 
0 [1.4437026] [0.86717445]
100 [1.677845] [0.7323308]
200 [1.7467577] [0.57567924]
300 [1.8009287] [0.45253593]
400 [1.8435118] [0.35573432]
500 [1.8769863] [0.2796395]
600 [1.9032999] [0.21982205]
700 [1.923985] [0.1728]
800 [1.9402454] [0.13583669]
900 [1.9530274] [0.10677999]
1000 [1.9630752] [0.08393876]
1100 [1.9709738] [0.0659835]
1200 [1.9771826] [0.0518691]
1300 [1.9820635] [0.04077392]
1400 [1.9859004] [0.03205184]
1500 [1.9889164] [0.02519561]
1600 [1.9912872] [0.01980606]
1700 [1.993151] [0.01556943]
1800 [1.994616] [0.01223899]
1900 [1.9957677] [0.00962109]
2000 [1.996673] [0.00756308]
[  7.994255 107.8279  ]
Comments