👩‍💻LEARN : ML&Data/Book Study

[모두의 딥러닝] #2-5. 선형회귀모델 : 먼저 긋고 수정하기

쟈니유 2023. 2. 10. 16:32
728x90

일단 지르고 고치자


#2-5. 선형회귀모델 : 먼저 긋고 수정하기 

 

1. 경사 하강법의 개요

 

  • 포물선모양의 함수 그래프에서 최소값(맨 꼭지점)을 갖는 함수는 x와 평행하는 평행선 함수로 기울기가 0이다.
  • 즉 미분 값이 0 인 지점을 찾으면 최솟값을 찾을 수 있다.
  • 미분값이 0인 지점을 찾는 법
    • 특정 x(a1이라 하자)에서의 미분(=기울기)을 구한다
    • 구한 기울기의 반대방향(+-)으로 얼마간 이동시킨 a2에서 미분을 구한다 
    • 앞에서 구한 미분값이 0이 아니면 앞 과정을 반복한다 > 기울기가 0인 한 점으로 수렴 
  • 경사하강법이란 
    • 오차의 변화에 따라 이차 함수 그래프를 만들고 적절한 학습률을 설정해 미분 값이 0인 지점을 찾는 것 
      • 학습률 : a값을 얼마나 이동할 지 이동 거리를 정해주는 것. 적절히 바꾸면서 최적의 학습률을 찾아가야 함 

 

2. 파이썬 코딩으로 확인하는 선형 회귀

  • 먼저 평균 제곱 오차의 식을 가져온다 
  • (실제 값 - 예측값)**2 의 합 / n 
  • 이 때 예측값은 y=ax+b에 x를 넣은 값이므로 이를 대입하면
  • (yi - (axi+b)**2의 합 / n 이 된다. 
  • 이 값을 미분할 때 궁금한 것은 a,b이므로 각각 편미분을 수행한다. 
import numpy as np
import matplotlib.pyplot as plt

#넘파이 배열 만들기

x = np.array([2,4,6,8])
y = np.array([81,93,91,97])

#데이터 분포 그래프 확인해보기

plt.scatter(x,y)
plt.show

#기울기, 절편 초기화해놓기

a = 0
b = 0

#학습률 세팅

lr = 0.03
epochs = 2001

#n 수 정해주기

n = len(x)

#경사하강법

for i in range(epochs):
  y_pred = a* x + b
  error = y - y_pred #오차

  a_diff = (2/n) * sum(-x*error) #오차함수 a로 편미분
  b_diff = (2/n) * sum(-(error)) #오차함수 b로 편미분
  #학습률 곱해서 값 업데이트
  a = a - lr*a_diff
  b = b - lr*b_diff

#100번마다 현재 기울기와 절편 노티스
  if i % 100 == 0:
     print("epoch =%.f, 기울기 =%.04f, 절편 =%.04f" % (i,a,b))

epoch =0, 기울기 =27.8400, 절편 =5.4300 epoch =100, 기울기 =7.0739, 절편 =50.5117 epoch =200, 기울기 =4.0960, 절편 =68.2822 epoch =300, 기울기 =2.9757, 절편 =74.9678 epoch =400, 기울기 =2.5542, 절편 =77.4830 epoch =500, 기울기 =2.3956, 절편 =78.4293 epoch =600, 기울기 =2.3360, 절편 =78.7853 epoch =700, 기울기 =2.3135, 절편 =78.9192 epoch =800, 기울기 =2.3051, 절편 =78.9696 epoch =900, 기울기 =2.3019, 절편 =78.9886 epoch =1000, 기울기 =2.3007, 절편 =78.9957 epoch =1100, 기울기 =2.3003, 절편 =78.9984 epoch =1200, 기울기 =2.3001, 절편 =78.9994 epoch =1300, 기울기 =2.3000, 절편 =78.9998 epoch =1400, 기울기 =2.3000, 절편 =78.9999 epoch =1500, 기울기 =2.3000, 절편 =79.0000 epoch =1600, 기울기 =2.3000, 절편 =79.0000 epoch =1700, 기울기 =2.3000, 절편 =79.0000 epoch =1800, 기울기 =2.3000, 절편 =79.0000 epoch =1900, 기울기 =2.3000, 절편 =79.0000 epoch =2000, 기울기 =2.3000, 절편 =79.0000

 

#최종 값 대입해서 그래프 그리기

y_pred = a * x + b

plt.scatter(x,y)
plt.plot(x,y_pred, 'r')
plt.show()

 

3. 다중선형회귀의 개요 

 

x가 여러개일 때. 즉 성적에 학습시간 뿐 아니라 과외여부가 영향을 미치는 것 등이 이에 해당함

 

4. 파이썬 코딩으로 확인하는 다중 선형 회귀 

#데이터 넣기

x1 = np.array([2,4,6,8])
x2 = np.array([0,4,2,3])
y = np.array([81,93,91,97])

#분포 확인하기

fig = plt.figure()

ax = fig.add_subplot(111, projection = '3d')
ax.scatter3D(x1,x2,y)
plt.show()

 

#a,b 값 초기화

a1 = 0
a2 = 0
b = 0

n = len(x1)

#학습률

lr = 0.01
epochs = 2001


#경사하강법

for i in range(epochs):
y_pred = a1 * x1 + a2 * x2 + b #예측값 세팅
error = y - y_pred
#편미분
a1_diff = (2/n) * sum(-x1 * (error))
a2_diff = (2/n) * sum(-x2 * (error))
b_diff = (2/n) * sum(-(error))
#학습률 곱해서 업데이트
a1 = a1 - lr*a1_diff
a2 = a2 - lr*a2_diff
b = b - lr*b_diff

#if i % 100 == 0 :
# print("epoch=%.f, 기울기1 =%.04f, 기울기2 =%.04f, 절편 =%.04f" % (i,a1, a2, y)) 여기서 또 프린트 안됨...

print(y)
print(y_pred)

[81 93 91 97] [80.76387645 92.97153922 91.42520875 96.7558749 ]

 

→ 2000번 반복시켰을 시 ,실제 점수와 가까운 값을 만들어 내고 있음 확인 가능 

 

5. 텐서플로에서 실행하는 선형회귀, 다중 선형 회귀 모델 

 

  • 가설함수 H(x) : 문제를 해결하기 위한 가설 함수 
  • 가중치 : 기울기 a이며 표시는 w 로함 
  • 편향 : 절편 b이며 표시는 bfh gka 
  • 손실함수 : 평균제곱오차 의미 
  • 경사하강법 : 옵티마이저 중 하나 
import numpy as np
import matplotlib.pyplot as plt

#1. 텐서플로 케라스에서 필요 함수 호출

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

x = np.array([2,4,6,8])
y = np.array([81,93,91,97])

model = Sequential()

#2. modeling - 첫번째 인자 : y개수, input_dim : x 개수, activation : 선형모델

model.add(Dense(1,input_dim=1, activation='linear'))


#3. 경사하강법(sgd)과 오차판단위해 평균제곱오차(mse) 사용

model.compile(optimizer='sgd', loss='mse')
model.fit(x,y, epochs = 2000)

plt.scatter(x,y)
plt.plot(x,model.predict(x), 'r')
plt.show()

#예측모델 테스트 with 임의의 값

hour = 7
prediction = model.predict([hour])
print("%.f 시간을 공부할 경우 예상 점수는 %.02f 점입니다" %(hour, prediction))

1/1 [==============================] - 0s 30ms/step 7 시간을 공부할 경우 예상 점수는 95.12 점입니다

 

#다중선형모델 만들기

x = np.array([[2,0],[4,4],[6,2],[8,3]])
y = np.array([81,93,91,97])

model = Sequential()

model.add(Dense(1,input_dim = 2, activation ='linear'))
model.compile(optimizer='sgd', loss = 'mse')

model.fit(x,y,epochs = 2000)

hour = 7
private_class = 4
prediction = model.predict([[hour, private_class]])

print("공부시간 : %.f , 과외횟수 : %.f , 예상 점수 : %.02f" % (hour, private_class, prediction))

....

1/1 [==============================] - 0s 5ms/step - loss: 0.0743 Epoch 2000/2000 1/1 [==============================] - 0s 4ms/step - loss: 0.0743 1/1 [==============================] - 0s 169ms/step 공부시간 : 7 , 과외횟수 : 4 , 예상 점수 : 97.53