관리 메뉴

HAMA 블로그

파이썬 코딩으로 말하는 데이터 분석 - 7. 회귀분석 (최소제곱법,경사하강법) 본문

통계 & 머신러닝 & 딥러닝

파이썬 코딩으로 말하는 데이터 분석 - 7. 회귀분석 (최소제곱법,경사하강법)

[하마] 이승현 (wowlsh93@gmail.com) 2017. 1. 31. 14:23


순서 

1. 통계 - 카운팅,min,max,평균,중앙값,산포도,분산,편차,공분산,상관관계 

2. 가설과 추론 (베이지언 - 사후확률,우도) 

3. 군집화 (K-Means)

4. 연관 (Apriori)

5. 함수형으로 데이터 다루기 

6.경사하강법

7. 회귀분석

8. 은닉 마코프법 (HMM) 

9. k-NN

10. DTW 

 * 참고로 "밑바닥부터 배우는 데이터과학" 서적은 numpy,scikit-learn 등의 외부라이브러리를 활용은 배제되었습니다.



회귀분석 

Okky 싸이트에 들어오는 사람들이 Okky 싸이트에 머무는 시간과 그들의 경력에 대해서 생각해보자.

머무는 시간이 1시간이면 , 경력은 5년
머무는 시간이 2시간이면,  경력은 7년 

..

이렇게 데이터가 누적되었을때, 그 둘 간의 어떠한 상관관계가 있는지 살펴봐서 , 머무는 시간이  X 시간일때  그 사람의 경력은 Y 년이라고 예측 가능 할 것이다.(물론 확률 몇%로 이렇게 조건이 붙겠지만.)  다른 예로 , 당신이 쥬씨 가게를 열었는데, 온도가 27도일때 몇잔이 팔리고..이런 데이타가 누적되었었을때 , 내일의 날씨를 안다면 , 내일 판매 될 잔 수를 알게 될 것이고, 재료를 준비하는데 도움이 될 것이다.

이렇게 두 데이타간의 상관관계가 있을때 이것에 대한 일반적인 식을 구해서 예측의 도구로 사용하는것을 회귀분석이라 한다. 

이러한 분석은 두 데이터가 아니라 , 여러 데이터를 통해서 할 수 도 있고 (중회귀분석),  0 혹은 1로 귀결을 맺는 로지스틱회귀 (내일 LG가 이길 것인가? 질것인가?) 등도 있지만 여기서는 단순회귀분석을 해보고자 한다.



위의 그림을 보면 x 축을 1,2,3 을 10도 20도 30도라는 온도로 생각하고  , y 축을 아이스커피 판매지수라고 생각하고 차트를 보자. 분명히 온도와 판매지수는 양의 상관관계가 있어 보인다.(날씨가 더울수록 판매가 잘 되는)

이때 저 직선 (회귀식) 을 구해서 추정하고 예측하는것을 회귀분석이라 한다. 저 직선을 구하면  몇도에선 몇잔 판매할 것이라는 것이  예측할 수 있을것임을  짐작할 수 있을것이다.

이제 회귀분석의 순서를 알아보자.

회귀분석 순서 

1. 회귀식을 구할 필요가 있는지를 검토하기 위하여 독립변수와 종속변수의 점그래프를 그려본다.

2. 회귀식을 구한다.

3. 회귀식의 정도를 확인한다.

4. '회귀계수의 검정' 을 실행한다.

5. 모회귀 Ax + B 를 추정한다.

6. 예측한다.


이 중에서 우리는 회귀식에 대해서만 알아본다. 


회귀식 

저 직선을 회귀식이라고 하며 아시다시피 직선의 방정식 y = ax + b 로 나타낼 수 있다. 

회귀식이 y =  30x + 100 이라면 30도 (x : 독립변수) 일때 1000잔 (y : 종속변수) 이 판매될거란 예측을 할 수 있게 된다. 


입력 데이터 + 알고리즘  ===>  결과 데이터 

데이터 + 회귀식 ====> 결과 


보통 우리들은 입력 데이터에 어떠한 알고리즘을 가지고 결과 데이터를 얻고 싶어한다. 하지만 딥러닝같은 신경망에서는 입력데이터와 결과데이터를 가지고 알고리즘을 산출해 내는데.. 회귀분석도 마찬가지이다. 데이터들을 가지고 회귀식을 만드는 것이쥐~

만드는 방법은 다음과 같다.


 y = ax + b    (y:종속변수 , x : 독립변수 , a : 회귀계수)
여기서 a와 b의 값을 찾는 방법을 말한다.



최소제곱법

위에서 보면 포인트들이 실제 데이터이고, 파란색 선이 아직 정해지지 않은  회귀식이라고 할 때 , d1,d2,d3,d4 이 세로선 들의 거리의 제곱의 합이 최소가 되도록 a,b 를 구하는 방법을 말한다. 

그리고 이 세로선들을 잔차라고 한다.


최소제곱법 순서

1. Sxx (x의 편차의 제곱의 합) , Syy (y의 편차의 제곱의 합), Sxy(x와 y의 편차의 곱의 합) 을 구한다.

2. 잔차의 제곱의 합을 구한다. Sl 이라 하자.

3. Sl 을 각각 a 와 b 에 대해서 미분한 후 0 으로 놓는다. 

4. Step 3의 결과를 정리한다.

5. Step 4이 결과를 정리한다.

6. 회귀식을 구한다.


1번은 그냥 데이터를 가지고 x평균, y평균, 각각의 편차등을 구하는  쉬운 산수일것이다.


2번의 경우  

x , y , y' = ax + b , y - y' , (y-y')^2 이 필요하다. 여기서 y-y' 이 잔차이다. 

y 는 데이터를 통한 측정값이고 , y' 는 회귀로 알아내야 할 예측값이라고 한다.

즉 기온이 29, 커피판매수 77이면 

x = 29 

y = 77 

y' 는 =====>   a*29 + b     

(y - y') ====>   77 - (a*29+b)  

가 된다.

결국 SI = {77-(a*29+b)}^2 + ...... + {84-(a*30+b)}^2  이렇게 나타낼 수 있게 된다.


3번의 경우 

위의 SI 식을 가지고 a,b 각각에 대해서 편미분을 해준다. 

dSl / da =  2{77- (29*a + b) } * (-29) + ..............

dSI / db = 2{77-(29a+b)} * (-1) + .... 


4,5번의 경우 

3번에서 도출된 식을 양변에 1/2 곱하고, 이항해주고 어쩌고 저쩌고해서 짧게 나타내보면 

a = Sxy / Sxx    ==> 3.7 

b = y평균 - x평균 * a 라고 정리된다.


6. 회귀식 

y = 3.7x = 36.4  뭐 이런식으로 구해진다. 더 자세한 것은 레퍼런스를 참고하자.


즉 알고보니  

a =  x와 y 편차의 곱의 합  / x 의 편차의 제곱의 합 

b =  y평균 - x평균 * a  

인 것이다.



코드로 말해요


자 이제 코드로 살펴볼 시간이다.

최소제곱법은 아래와 같다. (위에 도출된 식과 비교해보라. 동일하다 ^^) 

def least_squares_fit(x,y):
beta = correlation(x, y) * standard_deviation(y) / standard_deviation(x)
alpha = mean(y) - beta * mean(x)
return alpha, beta


경사하강법을 통해서도 알파와 베타를 구할 수 있는데 
(경사하강법은 다음 포스트에서 좀 더 자세히 다룰 예정이다) 

def predict(alpha, beta, x_i):
return beta * x_i + alpha

def error(alpha, beta, x_i, y_i):
return y_i - predict(alpha, beta, x_i)
def squared_error(x_i, y_i, theta):
alpha, beta = theta
return error(alpha, beta, x_i, y_i) ** 2

def squared_error_gradient(x_i, y_i, theta):
alpha, beta = theta
return [-2 * error(alpha, beta, x_i, y_i), # alpha partial derivative
-2 * error(alpha, beta, x_i, y_i) * x_i] # beta partial derivative

theta = [ alpha, beta] 로 설정하면 경사 하강법을 통해 모델을 만들 수 있다.

random.seed(0)
theta = [random.random(), random.random()]
alpha, beta = minimize_stochastic(squared_error,
squared_error_gradient,
num_friends_good,
daily_minutes_good,
theta,
0.0001)


*경사하강법


def minimize_stochastic(target_fn, gradient_fn, x, y, theta_0, alpha_0=0.01):

data = zip(x, y)
theta = theta_0 # initial guess
alpha = alpha_0 # initial step size
min_theta, min_value = None, float("inf") # the minimum so far
iterations_with_no_improvement = 0

# if we ever go 100 iterations with no improvement, stop
while iterations_with_no_improvement < 100:
value = sum( target_fn(x_i, y_i, theta) for x_i, y_i in data )

if value < min_value:
# if we've found a new minimum, remember it
# and go back to the original step size
min_theta, min_value = theta, value
iterations_with_no_improvement = 0
alpha = alpha_0
else:
# otherwise we're not improving, so try shrinking the step size
iterations_with_no_improvement += 1
alpha *= 0.9

# and take a gradient step for each of the data points
for x_i, y_i in in_random_order(data):
gradient_i = gradient_fn(x_i, y_i, theta)
theta = vector_subtract(theta, scalar_multiply(alpha, gradient_i))

return min_theta


마지막으로 아래 동영상을 참고하시길 바란다. 노트에 손글씨로 직접 풀이를 해 보는 동영상인데 

매우 도움이 될 것이다. 

선형회귀와 Gradient Descent


전체 소스는 아래에 있다.

https://github.com/insightbook/Data-Science-from-Scratch/blob/master/code/ch14_simple_linear_regression.py



레퍼런스 :

밑바닥부터 시작하는 데이터 과학

만화로 쉽게 배우는 회귀분석  

Comments