본문 바로가기
공부공부/얕게 둘러본 부분들

[인공지능/AI _ 2] - 머신러닝 > 지도 학습 > 회귀 (선형 회귀와 다항 회귀 실습)

by Lee_story_.. 2025. 3. 20.
728x90

 

오늘은 머신러닝 방법 중!

하나인 지도학습에 포함되어있는

회귀! 에 대한 내용을 공부해보겠습니다!

 

 

일단!

회귀 (Regression)


회귀란 머신러닝의 지도학습에 속하는 기술로서, 입력 변수(독립 변수)를 바탕으로 연속적인 숫자 값을 예측하는 방법입니다.

 

예를들어 특정회사에서 어떠한 제품군에 대한 판매기록들이 있을때,

그것들을 학습하여 "아, 특정 날에대한  **물품이 어느정도 팔리겠구나!" 하고 예측하는 것을 목표로

학습시키는 방법입니다.

 

 

그렇기에 학습이 끝나면 특정 값에 대해서는 값이 변경될 일이 없고,

동일한 입력에 대해서 동일한 출력을 나타냅니다.

 

 

회귀에 대해서는 대표적으로 선형회귀와 다항회귀등이 있고, 

이번 글에서는 두 회귀방법에 대해서 알아볼 예정입니다. 

 

 

선형 회귀 (Linear Regression)


선형회귀는 회귀의 가장 기본적이고 널리 사용되는 기법으로, 입력 변수 X와 출력 변수 y사이의 관계를 직선 형태로 모델링합니다.

 

아래가 기본적인 선형회귀의 수식!

흠....? 그냥 단순한... 1차원 방정식이지만, 해당 수식의 요소들을 다음과 같이 정의합니다. 

 

  • : 예측하고자 하는 값(종속변수)
  • x: 입력 데이터(독립변수)
  • w: 가중치(Weight), 직선의 기울기
  • b: 편향(Bias), 직선의 y 절편

 

다시 수식으로 보면, 선형 회귀란, x와 y의 값을 가지고,

정확한 가중치(W), 편향(b)를 찾기 위해 학습을 하는 과정이라고 볼 수 있습니다. 

(w와 b에 대한 값이 정해지면, 다음 값들에 대한 예측값을 출력할 수 있기때문!)

 

 

입력데이터의 종류가 많다면, 아래와 같은 형식을 취하기도 합니다.(복잡해지는...)

이를 다중 선형회귀라고 합니다. 

 

 

다시, 일반 선형회귀로 돌아와서

입력데이터가 하나라면....?  그에 맞는 선 하나만 그려주면 되겠죠? 아래처럼

 

 

 

하지만 값이 많아진다면...? 선형으로 모든 값에 대한 정확한 예측이 가능한가???

 

안되죠.... 하지만 최적의 가중치와 편향으로 실제 값과의 오차를 줄여줘서,

최대한 정답과 유사하게 예측을 해야하는데....

 

 

이를 위해서 선형회귀에서는 비용함수최적화 함수를 사용합니다.

비용함수는 예측값과 실제값의 차이를 측정하는 방법!

최적화 함수는 비용함수가 최소로 되는 W,b의 값을 찾는 방법입니다. 

 

 

주로 비용함수에는 MSE(평균제곱오차)를 사용하는데, 

MSE는 (예측값과 실제값간의 차이 = 편향)의 제곱 평균을 베이스로 계산됩니다. 

 

최적화기법으로는 경사하강법을 사용하고,

 

경사하강법은 다음과 같은 구조로 반복하며 기울기를 찾습니다. 

 

  • (1) 현재 파라미터(w,bw, b)로 예측값을 계산
  • (2) 예측값과 실제값의 차이를 이용해 비용함수 기울기를 계산
  • (3) 계산된 기울기를 바탕으로 파라미터를 업데이트

 

 

 

 

그럼 여기까지가 이론......

이제 선형회귀에 대한 실습코드 부분!

 

 

선형 회귀 실습 코드


선형회귀에 앞서 일단 데이터를 생성해줍시다.

 

 

아래처럼 np.random.rand를 이용하면 랜덤한값들을 생성할 수 있습니다. 

x = np.random.rand(2000)*100
y = 0.8*x+np.random.randn(2000)*30

 

 x는 1~100까지의 값들을 2000개 생성하고,

y의 경우는 y=0.8x의 수식에서 + 알파를 해주어 약간 선형에서 노이즈?를 발생시킨 느낌으로 생성했습니다. 

 

 

 

 

 

 

그리고.... 사실 아래처럼 sklearn에서 LinearRegression에 대해서는 함수가 따로 존재하기에, 

from sklearn.linear_model import LinearRegression
model = LinearRegression() 
model.fit(x.reshape(-1,1), y)

비용함수와 경사하강법을 구성할 필요는 없습니다...

하지만 함수가 어떻게 만들어지는지는 한번 구경구경해보겠습니다.

 

 

 

먼저 비용함수는 아래처럼 예측값과의 차이의 제곱평균으로 정의해주었고,

# 비용함수 (MSE) 정의
def compute_cost(x, y, w, b):
    m = len(y)
    predictions = w * x + b
    return (1/m) * np.sum((y - predictions)**2)

 

 

경사하강법은.... 아래처럼  계속해서 갱신되는 가중치와 편향 예측값을 토대로 값을 계산하고,

또 그 값을 통해 나온 예측값으로 가중치와 편향에 대한 오차를 줄여나가는 방법으로 최적의 값을 찾아나갑니다.

for i in range(epochs):
    predictions = w * x + b

    dw = -(2/m) * np.sum(x * (y - predictions))
    db = -(2/m) * np.sum(y - predictions)

    w = w - learning_rate * dw
    b = b - learning_rate * db

 

 

 

아래는 실제 실행코드!

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression


if __name__ == '__main__':
    x = np.random.rand(10)*100
    y = 0.8*x+np.random.randn(10)*100

    model = LinearRegression() 
    
    model.fit(x.reshape(-1,1), y) 
     
    b0,b1 = model.intercept_, model.coef_[0]   
    print("b0",b0)
    print("b1",b1)

    # 시각화
    plt.scatter(x, y, s=5)
    plt.plot(x, model.predict(x.reshape(-1,1)), color='red', linewidth=2)
    plt.show()

 

 

 

y의 값의 노이즈 정도를 변경해주면,

아래처럼 선형그래프가 계속 변경하게 됩니다 굳굳

 

    x = np.random.rand(1000)*100
    y = 0.8*x+np.random.randn(1000)*10

 

 

    x = np.random.rand(1000)*100
    y = 0.8*x+np.random.randn(1000)*200

 

 

    x = np.random.rand(1000)*100
    y = 0.8*x+np.random.randn(1000)*2000

 

 

y값의 노이즈가 커질수록.... 선형그래프가 누워버리는... (당연한)

 

여기까지 선형회귀 마무리

 

 

 

 

 

 

 

 

 

그럼 이제 다항회귀!

 

다항 회귀 (Polynomial Regression)


다항 회귀는 회귀 분석의 한 종류로, 독립변수(x)와 종속변수(y) 사이의 관계를 다항식(Polynomial) 으로 나타내는 회귀 방법입니다.

 

다항식... 하나의 y값에 x가 여러개 나올수 있는 식들을 말합니다....

그렇다면, 앞서 알아본 선형회귀로 x와 y의 관계에 대해서 그릴수 있을까...?

 

 

아래는 단순한  이차 방적식입니다. 

 

만약 데이터들에 대한 점들을 찍었는데 위와같이.. 곡선에 가깝게 나온다면!

선형으로 그릴순 있으나.... 예측값에 대해서 정확도가 낮을 수 밖에 없습니다...(거의 예측 못할듯;)

 

 

그래서! 이러한 경우에는 선형회귀가 아닌 다항회귀를 사용하여 값을 예측합니다!

 

 

다항회귀를 사용하면!

- 복잡한 비선형 관계를 효과적으로 모델링 가능
- 데이터 적합성이 뛰어남

 

하지만..

- 차수가 너무 높으면 과적합(overfitting)이 발생할 수 있음
- 계산량 증가

 

그러니 언제나 그렇듯, 데이터에 대한 적절한 방법을 채택하는게 제일 중요해 보입니다...

 

 

그럼 실습 시작!

 

 

다항 회귀 실습 코드


 

다항회귀 실습도 sklearn에서 지원해주는 LinearRegression함수로 계산가능합니다...

다항식에 대한 특징을 추출하는 과정이 필요하긴 하지만, 그 외의 부분은 동일합니다.

 

동일한 과정으로 데이터를 만들어 주고

x = np.sort(np.random.rand(100, 1) * 10, axis=0)
y = 1 + 2 * x + x**2 + np.random.randn(100, 1) * 10  # 2차 다항 관계

 

 

해당 차수까지 표현되는 데이터를 확장해야합니다.

degree = 2  # 다항식 차수 설정
poly_features = PolynomialFeatures(degree=degree, include_bias=False)
x_poly = poly_features.fit_transform(x)

 

현재는 2차항까지 있기에 degree를 2로설정하여, 입력변수(x)를 지정된 차수(degree) 까지 모두 확장합니다.

 

만약 5차까지 있다면, 아래처럼 확장되고, 이 데이터들을 특징으로 변환합니다.

그리고 선형회귀와 동일하게 

학습하고 시각화 하면 끝!

# 다항회귀 모델 생성 및 학습
poly_model = LinearRegression()
poly_model.fit(x_poly, y)

# 예측 수행
y_pred = poly_model.predict(x_poly)

# 시각화
plt.scatter(x, y, color='blue', alpha=0.6, label='Actual data')
plt.plot(x, y_pred, color='red', linewidth=2, label=f'Polynomial Regression (Degree={degree})')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.title('Polynomial Regression')
plt.show()

 

 

 

아래는 선형회귀와 비교한 결과입니다....

 

흠.... 차이가 그렇게 안큰거...같은... 

 

 

 

5차까지 늘리고 다시 그려보았습니다. 

y = 1 + 2 * x + 2*x**2+ 3*x**5 + np.random.randn(100, 1) * 10 

degree = 5  # 다항식 차수 설정
poly_features = PolynomialFeatures(degree=degree, include_bias=False)
x_poly = poly_features.fit_transform(x)

 

 

 

확실히 이런데이터가 들어오게 되면, 선형회귀로 해결이 불가능하다는게.... 보이네요 굳굳

 

 

 

 

 

여기까지가 "회귀" 마무리!

 

 

 

 

틀린점이 있다면 댓 달아주세요!

 
728x90

댓글