선형 회귀
- x: 다른 변수의 값을 변하게 하는 변수 - 독립 변수
- y: x에 의해 값이 종속적으로 변하는 변수 - 종속 변수
선형 회귀는 한 개 이상의 독립 변수 x와 종속 변수 y의 선형 관계를 모델링한다.
단순 선형 회귀 분석
y = wx + b
위 수식은 단순 선형 회귀의 수식이다.
독립 변수 x와 곱해지는 값 w를 머신 러닝에서는 가중치, 별도로 더해지는 값 b를 편향이라고 한다.
각각 직선의 기울기와 절편을 의미한다.
다중 선형 회귀 분석
y = w1x1 + w2x2 + w3x3 + ... + wnxn + b
부동산 가격, 주가 예측은 한가지 요소에만 영향을 받지 않는다.
이런 다수의 요소를 가지고 예측을 하고 싶은 경우 y는 하나이지만 x는 여러 개가 된다.
비용 함수
선형 회귀에서 궁극적으로 해애하는 것은 어떤 직선을 찾을 지, 그 직선을 결정하는 w와 b를 찾는 것이다.
데이터를 잘 표현하는 w와 b를 찾기 위해서는 실제값과 예측값의 오차를 계산하고, 이를 최소화 하는 값을 찾는다,
이 때 실제값과 예측값에 대한 오차를 나타내는 식을 목적 함수, 비용 함수, 손실 함수라고 한다.
직선이 데이터를 잘 나타내는지 검증할 수 있는 비용 함수로는 MSE가 있다.
MSE는 오차들의 제곱을 평균 낸 것이다.
왜 굳이 제곱을 하는가 하면, 단순히 실제값과 예측값의 오차를 계산하면 음수와 양수가 공존할 것이다.
오차의 절대적인 크기를 구할 수 없기 때문에 모든 오차를 제곱하여 더하는 방번을 사용한다.
MSE가 아닌 절댓값을 더하는 MAE, MSE의 값에 루트를 씌워 오차의 정도(단위)를 맞춰주는 RMSE도 있다.
옵티마이저
러닝은 비용함수를 최소화하는 매개 변수인 w와 b를 찾기 위한 작업이다.
이때 사용된느 알고리즘을 옵티마이저 or 최적화 알고리즘이라고 부른다.
경사하강법
가장 기본적인 옵티마이저 알고리즘이다.
편의를 위해 편향을 제외하고 y = wx라는 식을 가지고 경사 하강법을 수행한다고 하자.
위 식에서의 w와 비용 함수의 값 cost의 관계는 아래와 같다.
w가 무한대로 커지면 cost 또한 무한대로 커지고, w가 무한대로 작아져도 cost는 무한대로 커진다.
러닝에서 해야할 일은 cost가 최소값을 가지게 하는 w를 찾는 일이므로,
그래프의 볼록한 부분의 맨 아래 w 값을 찾아야 한다.
이 점을 찾아가는 방법은 접선에서의 기울기를 이용한다.
찾아야하는 부분의 접선의 기울기는 0이다. 즉, 접선의 기울기가 0에 가까워 지도록 w를 찾아가야 한다.
비용함수는 MSE이고, w를 구하기 위해 w를 업데이트 하는 식은 아래와 같다.
이 식은 현재 w에서의 접선의 기울기와 a를 곱한 값을 현재 w에서 빼서 업데이트 하는 것이다.
기울기를 뺀다는 것은 기울기가 음수일 때 찾아야 하는 해로부터 왼쪽에 존재한다는 것이다.
따라서 현재 w에서 기울기를 빼면 새로운 w는 현재 w보다 큰 값을 가지게 된다.
양수인 경우는 반대로 마찬가지다.
아래 그림을 참고하면 이해가 쉽다.
그리고 위에서 사용한 a는 학습률이다.
학습률은 w의 값을 변경할 때 얼마나 크게 변경할지를 결정하고, 0~1 사이의 값을 가진다.
a를 크게 하면 정답을 빨리 찾아갈 수도 있지만 발산하게 될 수도 있으니 적절하게 결정해야 한다.
자동 미분
tensorflow의 tape_gradient() 함수를 이용하면 자동으로 미분한다.
import tensorflow as tf
w = tf.Variable(3.)
def f(w):
z = 2*(w**3) + 5
return z
with tf.GradientTape() as tape:
z = f(w)
gradients = tape.gradient(z, [w])
print(gradients)
# [<tf.Tensor: shape=(), dtype=float32, numpy=54.0>]
함수를 나타내는 식을 f(x) 함수로 선언한다.
z에 이 함수에 w를 넣은 결과 값을 저장한다.
tape.gradient() 함수를 이용해 미분된 식의 계산값을 구할 수 있다.
선형 회귀 활용
이를 이용해 선형 회귀를 구현해볼 수 있다.
x = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 공부하는 시간
y = [11, 22, 33, 44, 53, 66, 77, 87, 95] # 각 공부하는 시간에 맵핑되는 성적
w = tf.Variable(4.0)
b = tf.Variable(1.0)
def hypothesis(x):
return w*x + b
def mse_loss(y_pred, y):
return tf.reduce_mean(tf.square(y_pred - y))
optimizer = tf.optimizers.SGD(0.01) # 학습률 설정
for i in range(301):
with tf.GradientTape() as tape:
y_pred = hypothesis(x)
cost = mse_loss(y_pred, y)
gradients = tape.gradient(cost, [w, b])
optimizer.apply_gradients(zip(gradients, [w, b]))
if i % 10 == 0:
print("epoch : {:3} | w의 값 : {:5.4f} | b의 값 : {:5.4} | cost : {:5.6f}".format(i, w.numpy(), b.numpy(), cost))
우선 사용할 변수 x와 y를 선언한다.
학습할 변수 w, b를 선언하면서 초기값을 정해준다.
가설을 함수로 정의한다. y = wx + b
비용 함수를 계산할 mse_loss 함수도 정의한다.
옵티마이저는 경사 하강법을 사용하고, 학습률은 0.01로 설정한다.
경사 하강법을 300번 반복 수행한다.
위에서 한 예시처럼 함수의 값을 계산하고, mse를 계산한다.
그 후 미분한 값을 계산한 후 w를 업데이트한다.
케라스
케라스를 이용해 구현할 수도 있다.
케라스로 모델을 만드는 기본 구조는 Sequential로 model이라는 이름의 모델을 만들고
add를 통해 입력과 출력 벡터의 차원과 같은 필요한 정보들을 추가한다.
activation은 어떤 함수를 사용할 것인지 의미하는데 선형 회귀에서는 linear를 사용한다.
옵티마이저로 기본 경사 하강법을 사용하고 싶다면 sgd라고 작성한다.
손실 함수로는 mse를 사용한다.
전체 훈련 횟수는 300으로 epochs를 300으로 설정한다.
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import optimizers
x = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 공부하는 시간
y = [11, 22, 33, 44, 53, 66, 77, 87, 95] # 각 공부하는 시간에 맵핑되는 성적
model = Sequential()
model.add(Dense(1, input_dim=1, activation='linear'))
sgd = optimizers.SGD(lr=0.01)
model.compile(optimizer=sgd, loss='mse', metrics=['mse'])
model.fit(x, y, epochs=300)
해당 결과를 그래프로 그리면 아래와 같다.
print(model.predict([9.5]))
# [[102.1539]]
위처럼 결과를 예측할 수도 있다.
시험 성적은 0~100점이겠지만 범위를 초과하는 102점을 예측하기도 한다.
'AI > NLP' 카테고리의 다른 글
[Wiki] 머신 러닝 기본 (0) | 2024.06.06 |
---|---|
[Wiki] 벡터 유사도 (1) | 2024.06.04 |
[Wiki] 카운트 기반 단어 표현 (1) | 2024.06.03 |
[Wiki] 언어 모델 (1) | 2024.06.02 |
[Wiki] 한국어 전처리 패키지 (1) | 2024.06.02 |