DeepLearning - 선형 회귀
딥러닝의 가장 기본적인 계산 원리
- 선형 회귀, 그리고 로지스틱 회귀
1. 선형회귀
-
어떠한 문제가 발생했을 때, 그 문제의 요인이 무엇인가
-
라는 함수를 찾자.
-
하나로 y를 설명 할 수 있어 = 단순 선형 회귀
-
등 여러 개가 필요해 = 다중 선형 회귀
내가 이 문제에 관한 규칙을 갖는 선을 그었어! 이제 내가 직면한 상황이 어디로 나타날지 점을 찍을 수 있어!
1-1. 최소제곱법
: 기울기 a와 y절편 b를 구하기 위함
코드화
x = np.array([1, 2, 3, 4, 5]) # 다이어트 경과일
y = np.array([46, 46,2, 45,9, 45.8]) # 몸무게 변화
# cal분모, 제곱의 합
divisor = sum([(i-mx)**2 for i in x])
# cal분자
def top(x, y, mx, my):
d =0
for i in range(len(x)):
d += (x[i] -mx) * (y[i] - my)
return d
dividend = top(x, y, mx, my)
result = dividend / divisor
b = my - (mx*a)
1-2. 평균제곱오차
-
: 원소의 순서
-
: 원소의 총 개수
-
: 가 대입되었을 때 직선의 방정식(예측값)
코드화
a = -1.0
b = 50.0
x = np.array([1, 2, 3, 4, 5]) # 다이어트 경과일
y = np.array([46.0, 46.2, 45.9, 45.8, 45.7]) # 몸무게
def calculate(x):
return a * x + b # -x + 50, 즉 하루마다 0.1kg가 감소할 것이라는 기대
# 예측 값 계산
pred = calculate(x)
# 평균 제곱 오차 계산
def mseCalculate(y, pY):
return np.mean((y - pY) ** 2)
print(pred)
print(mseCalculate(y, pred))
오차를 확인하였다면, 이제 이 오차를 줄일 수 있는 새로운 선을 찾는 것이다
2. 선형회귀 모델
- 기울기 a가 큰 경우
- = 오차가 커질 가능성이 농후하다
- = y축과 나란한 직선이 되어간다
- : 🤔 그렇다면 오차가 작은 경우는, 이차함수의 최솟값이자 기울기가 0인 순간(y축에 수직)에 이르는 경우겠네.
2-1. 경사하강법
: 오차의 변화에 따라 이차 함수 그래프 생성 -> 학습률을 통한 인 지점 구하기
- 2차함수에서 임의의 지점의 기울기를 구한다(= 미분을 한다)
- 1번에서 기울기를 반전(+-)시킨 에서의 미분을 구한다 (*여기서 이동거리 = 학습률 개념 존재)
- 미분 값이 0에 도달할 때까지 1,2를 범위를 줄여가며 진행한다
2-2. 경사하강법의 수식
-
기존의 평균제곱 오차의 공식을 응용한다()
-
알아내고 싶은 건, 정확한 식의 설립을 위한 ‘a’와 ‘b’이므로 각각에 대한 편미분 구하기
- a편미분 =
- b편미분 =
코드화
# 초기값
a = -1.0
b = 50.0
x = np.array([1, 2, 3, 4, 5]) # 다이어트 경과일
y = np.array([46.0, 46.2, 45.9, 45.8, 45.7]) # 몸무게
def calculate(x, a, b): # 예측 함수
return a * x + b
def mseCalculate(y, pY): # 평균 제곱 오차 계산
return np.mean((y - pY) \*\* 2)
# 하이퍼파라미터
learning_rate = 0.01 # 얼마나 수정할 지
epochs = 1000 # 몇 번 반복할지
n = len(x)
for i in range(epochs): # 경사하강법
pred = calculate(x, a, b)
da = -(2 / n) * np.sum(x * (y - pred)) # 편미분(gradient) 계산
db = -(2 / n) * np.sum(y - pred)
a = a - learning_rate * da
b = b - learning_rate * db
# 100번마다 출력
if i % 100 == 0:
mse = mseCalculate(y, pred)
print(f"epoch={i}, a={a:.4f}, b={b:.4f}, mse={mse:.6f}")
final_pred = calculate(x, a, b)
final_mse = mseCalculate(y, final_pred)
print("a =", a)
print("b =", b)
print("pred =", final_pred)
print("mse =", final_mse)
주의점
- learning_rate가 발산하지 않도록 적절한 값으로 설정해야함