카테고리 없음

선형회귀

Scalarr 2023. 11. 1. 21:21

단순 선형 회귀는 가장 기본적이면서도 그만큼 강력한 회귀 분석 기법 중 하나이다. 회귀 분석 기법은 종속 변수와 독립 변수 간의 관계를 모델링하고 예측하는데, 그중에서도 단순 선형 회귀는 하나의 종속 변수와 하나의 독립 변수 간의 관계를 다룬다. 이를 통해 주어진 데이터로부터 변수 간의 선형적인 관계를 파악하고, 이 관계를 기반으로 알려지지 않은 값을 예측할 수 있다.

 

선형회귀의 주요 목적은 종속 변수와 독립 변수 사이의 관계를 모델링하는 것이고, 주로 데이터의 패턴, 추세, 상관관계를 이해하고 예측하는 데 사용된다. 이를 통해 집의 면적과 가격의 관계, 공부 시간과 성적의 관계 등 두가지 변수의 관계를 파악하고 예측할 수 있다.

 

단순 선형 회귀하는데 필요한 것은 종속 변수, 독립 변수 이외에 상수항, 기울기, 오차 항 등이 필요하다. 따라서, 우리는 프로그램을 통해 자동으로 상수항과 기울기를 찾아내야 한다. 이를 위해서 주어진 데이터가 선형 회귀를 하기 적합한지 확인하고, 데이터를 수집한 뒤, 최소제곱법 등의 방법을 이용해 오차를 제일 적게 발생시키는 상수항과 기울기를 찾는다. 이는 파이썬으로 다음과 같은 코드로 이루어질 수 있다.

 

파이토치를 이용한다.

 

라이브러리 불러오기

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
import torch
import torch.nn as nn
print(f'PyTorch Version: {torch.__version__}')

 

무작위로 산점도 데이터를 생성한다.

def f1(x, w, b):
    return w*x + b

w = 5.
b = 3.

x_true = np.linspace(-1,1,100)
y_true = f1(x_true, w, b)

n = 10
x_data = np.linspace(-1, 1, n)
y_data = f1(x_data, w, b) + np.random.randn(n)

plt.plot(x_true, y_true, "k-", label="Ground Truth")
plt.plot(x_data, y_data, "r.", label="Data")
plt.legend()
plt.xlim([-1, 1])
plt.ylim([-2, 8])
plt.show()

 

생성된 데이터를 numpy에서 pytorch 텐서로 변환한다.

print(type(x_data), type(y_data))
print('-----------------------')

 
x_data_tensor = torch.tensor(x_data, dtype=torch.float32)
y_data_tensor = torch.tensor(y_data, dtype=torch.float32)

print(type(x_data_tensor), type(y_data_tensor))
print('-----------------------')
print(x_data_tensor.shape, y_data_tensor.shape)

 

파이토치 모델을 사용하기 위해서는 2차원 배열로 변환해주어야 한다. 여기서는 세로로 긴 배열을 만든다.

(-1 넣으면 다른 값에 맞춰져서 나옴)

x_data_tensor = x_data_tensor.view(-1,1)
y_data_tensor = y_data_tensor.view(-1,1)

 

파이토치에 있는 선형 모델을 사용한다.  입력값과 출력값을 결정해주어야 한다. 초기에는 가중치와 바이어스가 랜덤으로 결정되는데, model.weight와 model.bias 함수를 이용해 가중치와 바이어스를 볼 수 있다.

 

input_size = 1
output_size = 1

model = nn.Linear(input_size, output_size)
 
print(model.weight)
print(model.bias)

 

경사하강법을 이용해서 최적화를 한다. 최소제곱법을 이용해서 학습한다.

learning_rate = 0.01
loss_method = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

 

학습 횟수를 지정해주고 학습시킨다. 손실함수가 수렴하는 것을 확인할 수 있다.

num_epochs = 1000

for epoch in range(num_epochs):
 
    y_pred_tensor = model(x_data_tensor)
 
    loss = loss_method(y_pred_tensor, y_data_tensor)
 
    loss.backward()
 
    optimizer.step()
    optimizer.zero_grad() 
 
    if (epoch + 1) % 10 == 0:
        print(f'Epoch: {epoch+1}\tLoss = {loss.item():.5f}')

 

얻은 값으로 그래프를 그린다.

x_true_tensor = torch.from_numpy(x_true.astype(np.float32)).view(-1,1)

y_pred_tensor = model(x_true_tensor).detach() 
y_pred = y_pred_tensor.numpy()
 
print(f'Original parameters: w = {w}, b = {b}')
 
weight = model.weight[0,0].item()
bias = model.bias[0].item()

print(f'Trained parameters: w = {weight:.5f}, b = {bias:.5f}')
 
plt.plot(x_true, y_true, "k-", label="Ground Truth")
plt.plot(x_data, y_data, "r.", label="Data")
plt.plot(x_true, y_pred, "b-", label="Linear Regression")
plt.legend()
plt.xlim([-1, 1])
plt.ylim([-2, 8])
plt.show()