2026.03.21
DeepLearning - 선형 회귀

DeepLearning - 선형 회귀

딥러닝의 가장 기본적인 계산 원리

  • 선형 회귀, 그리고 로지스틱 회귀

1. 선형회귀

  • 어떠한 문제가 발생했을 때, 그 문제의 요인이 무엇인가

  • f(x)f(x) 라는 함수를 찾자.

  • xx 하나로 y를 설명 할 수 있어 = 단순 선형 회귀

  • x1,x2,x3x_1, x_2, x_3 등 여러 개가 필요해 = 다중 선형 회귀

    내가 이 문제에 관한 규칙을 갖는 선을 그었어! 이제 내가 직면한 상황이 어디로 나타날지 점을 찍을 수 있어!


1-1. 최소제곱법

: 기울기 a와 y절편 b를 구하기 위함

  • a(기울기)=((xx평균)(yy평균)의합)(xx평균)2의합 a(기울기) = \frac{((x-x평균)(y-y평균)의 합)}{(x-x평균)^2의 합}
  • b(y절편)=y의평균(x의평균)(기울기a) b(y절편) = y의 평균 - (x의 평균 )(기울기 a)

코드화

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. 평균제곱오차

  • ii: 원소의 순서

  • nn: 원소의 총 개수

  • y^\hat{y}: xix_i 가 대입되었을 때 직선의 방정식(예측값)

    MSE=1ni=1n(yiy^i)2MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^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. 경사하강법

: 오차의 변화에 따라 이차 함수 그래프 생성 -> 학습률을 통한 미분=0미분=0 인 지점 구하기

  1. 2차함수에서 임의의 a1a_1 지점의 기울기를 구한다(= 미분을 한다)
  2. 1번에서 기울기를 반전(+-)시킨 a2a_2 에서의 미분을 구한다 (*여기서 이동거리 = 학습률 개념 존재)
  3. 미분 값이 0에 도달할 때까지 1,2를 범위를 줄여가며 진행한다

2-2. 경사하강법의 수식

  1. 기존의 평균제곱 오차의 공식을 응용한다(haty=axi+bhat{y} = ax_i + b) 1n_i=1n(yiy^_i)2\frac{1}{n} \sum\_{i=1}^{n} (y_i - \hat{y}\_i)^2 1n_i=1n(yi(axi+b))2\frac{1}{n} \sum\_{i=1}^{n} (y_i - (ax_i+b))^2

  2. 알아내고 싶은 건, 정확한 식의 설립을 위한 ‘a’와 ‘b’이므로 각각에 대한 편미분 구하기

  • a편미분 = 2n xi(yi(axi+b))\frac{2}{n}\sum\ -x_i(y_i-(ax_i+b))
  • b편미분 = 2n (yi(axi+b))\frac{2}{n}\sum\ -(y_i-(ax_i+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가 발산하지 않도록 적절한 값으로 설정해야함