딥러닝_선형회귀모델_코드연습

2 minute read

문제 해결을 위해 당뇨병 환자의 데이터 준비하기

from sklearn.datasets import load_diabetes
diabetes=load_diabetes()
print(diabetes.data.shape, diabetes.target.shape)
(442, 10) (442,)
diabetes.data[0:3]
array([[ 0.03807591,  0.05068012,  0.06169621,  0.02187235, -0.0442235 ,
        -0.03482076, -0.04340085, -0.00259226,  0.01990842, -0.01764613],
       [-0.00188202, -0.04464164, -0.05147406, -0.02632783, -0.00844872,
        -0.01916334,  0.07441156, -0.03949338, -0.06832974, -0.09220405],
       [ 0.08529891,  0.05068012,  0.04445121, -0.00567061, -0.04559945,
        -0.03419447, -0.03235593, -0.00259226,  0.00286377, -0.02593034]])

입력 데이터와 타깃 데이터 자세히 보기

diabetes.target[:3]
array([151.,  75., 141.])

당뇨병 환자 데이터 시각화하기

import matplotlib.pyplot as plt
plt.scatter(diabetes.data[:,2], diabetes.target)
plt.xlabel('x')
plt.ylabel('y')
plt.show()

#이후 코드를 간단하게 쓰기 위해
x=diabetes.data[:,2]
y=diabetes.target

딥러닝_선형회귀모델_코드연습output4

#임의의 값으로 시작
w=1.0
b=1.0
#첫 번째 샘플에 대한 예측 만들기
#x[0]는 당뇨병 세번째 특성이다.
y_hat =x[0] * w+b
print(y_hat)
1.0616962065186886
#첫 번째 샘플의 실제 타깃
print(y[0])
151.0

여기서 1.0616962065186886과 151.0의 차이를 좁혀나가야한다.

#w값을 조절해 예측값을 바꾸어 보자
#w를 0.1만큼 증가시켜 보자
w_inc= w+0.1
y_hat_inc=x[0]*w_inc+b
print(y_hat_inc)
1.0678658271705574

w에 0.1을 증가시켜본 결과 1.06786으로 타킷(151.0)에 조금 더 가까워졌다.

#얼마만큼 증가했는지 알아보자
w_rate=(y_hat_inc - y_hat)/(w_inc - w)
print(w_rate)
0.061696206518688734
#변화율을 더하면 예측값이 증가!
w_new=w+w_rate
print(w_new)
1.0616962065186888
#똑같은 방법으로 절편도 업데이트를 해보자
b_inc=b+0.1
y_hat_inc = x[0] * w + b_inc
print(y_hat_inc)
1.1616962065186887
b_rate = (y_hat_inc - y_hat)/ (b_inc - b)
print(b_rate)
1.0
#절편(b)같은 경우 변화율이 1이니까 1을 써주면 된다.
b_new = b+1
print(b_new)
2.0

여기까지 변화율을 더해줘서 업데이트하는 건 y_hat이 y보다 작다고 가정해두고 진행하고 있다는것을 명심해야한다.

이 방식의 문제점은 y_hat이 y에 한참 미치지 못 하는 경우, w와 b를 더 큰 폭으로 수정할 수 없다. 그리고 y_hat이 y보다 커지면 y_hat을 감소시키지 못한다.

이 문제점을 개선한 것이 오차 역전파로 가중치와 절편을 업데이트 하는 방법이다.

err= y[0] -y_hat
w_new = w + w_rate * err
b_new = b + 1 * err
print(w_new, b_new)
10.250624555904514 150.9383037934813

위 코드의 결과를 보면 가중치와 절편이 큰 폭으로 바뀌었음을 알 수 있다.

#이번에는 두 번째 샘플을 사용하여 w와 b를 계산합니다.
y_hat = x[1]*w_new +b_new
err= y[1] - y_hat
w_rate = x[1] #두 번째 샘플의 변화율은 샘플 값 그 자체입니다.
w_new = w_new + w_rate * err
b_new = b_new + 1* err
print(w_new, b_new)
14.132317616381767 75.52764127612664

이런 식으로 전체 샘플을 반복하여 가중치와 절편을 조정한다.

for x_i, y_i in zip(x, y):
  y_hat=x_i *w +b
  err=y_i - y_hat
  w_rate = x_i
  w = w + w_rate * err
  b= b+1 * err
print(w,b)
587.8654539985689 99.40935564531424
#위에서 구한 것을 그래프를 그려 살펴보자
plt.scatter(x,y)
pt1 = (-0.1, -0.1 * w + b)
pt2 = (0.15, 0.15 *w + b)
plt.plot([pt1[0], pt2[0]], [pt1[1], pt2[1]])
plt.xlabel('x')
plt.ylabel('y')
plt.show()

딥러닝_선형회귀모델_코드연습output5

여러 에포크를 반복하기

#더 정교하게 값을 얻기위해 for문으로 여러번 더 반복하기
for i in range(1,100): #100번 더 반복
  for x_i, y_i in zip(x, y):
    y_hat=x_i *w +b
    err=y_i - y_hat
    w_rate = x_i
    w = w + w_rate * err
    b= b+1 * err

print(w,b)
913.5973364345905 123.39414383177204
plt.scatter(x,y)
pt1 = (-0.1, -0.1 * w + b)
pt2 = (0.15, 0.15 *w + b)
plt.plot([pt1[0], pt2[0]], [pt1[1], pt2[1]])
plt.xlabel('x')
plt.ylabel('y')
plt.show()

딥러닝_선형회귀모델_코드연습output6

모델로 예측하기

x_new = 0.18 #새로운 입력데이터
y_pred = x_new *w +b
print(y_pred)
287.8416643899983
plt.scatter(x,y)
plt.scatter(x_new, y_pred)
plt.xlabel('x')
plt.ylabel('y')
plt.show(0)

딥러닝_선형회귀모델_코드연습output7

딥러닝_선형회귀모델_코드연습output8

Leave a comment