본문 바로가기
CS/머신러닝

혼자 공부하는 머신러닝 + 딥러닝 - Ch3-2

by jaehoonChoi 2023. 1. 8.

Ch 3-2에서는 선형회귀에 대해 공부합니다.

선형회귀는 간단하면서 강력한 방법입니다. 많은 경우 일상데이터는 출력과 비례하는 경우가

많기 때문에 활용도가 높습니다. 예를 들어 공부시간과 성적같은 데이터가 있습니다.

 

 

1차 model 

Ch 3-1의 데이터를 이용하여 선형회귀로 예측 해봅시다. 

선형회귀 모델은 사이킷런의 LinearRegression 을 import하여 훈련할 수 있습니다.

선형회귀 객체를 생성하고 모델이름을 lr로 정해줍니다.

훈련데이터로 학습시키고 그 결과 기울기와 절편 값을 학습하게 됩니다.

각각 coef_ 와 intercept_ 로 저장되어 있습니다.

이제 고정된 두 점을 이어서 빨간색 직선을 표시하고 모델의 성능을 출력해봅시다.

#선형회귀
lr=LinearRegression() # 객체 생성
lr.fit(train_X, train_Y) # 훈련
a,b=lr.coef_, lr.intercept_ # a, b는 기울기, y절편
plt.scatter(train_X, train_Y) # 산점도 
plt.plot([15, 50], [15*a+b, 50*a+b], color='red') # 직선 그리기
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
print(lr.score(test_X, test_Y)) # 성능 평가

결과는 다음과 같습니다.

 

좀 아쉽네요.. 대충 맞긴 하지만 이차함수 형태라면 더 정확하게 예측할 수 있을 것 같습니다.

 

 

 

 

2차식 model 

\(y=c_{1}x^2+c_{2}x+c_{3}\) 이라 모델을 설정하고 학습을 시켜보겠습니다.

그러기 위해선 \(x^2\) 에 해당하는 데이터가 필요합니다. 브로드캐스팅으로 쉽게 만들어줄 수 있습니다.

이제 이 두 행렬을 나란히 붙여서 N*2 꼴 행렬이 되게 만들어주겠습니다. 

# 브로드 캐스팅 + 행렬 붙이기
train_poly=np.column_stack((train_X**2, train_X)) 
test_poly=np.column_stack((test_X**2, test_X)) 
print(train_poly.shape, test_poly.shape)

 출력시 올바른 행렬이 나옴을 확인할 수 있습니다.

(42, 2) (14, 2)

이제 훈련을 진행시키고 얻은 상수들을 확인해줍시다.

변수 \(x\)의 차수가 있는 상수 \(c_1, c_2\)는 모두 묶여서 coef_에 저장되어 있습니다.

절편값은 따로 intercept_에 저장됩니다. 이들을 토대로 점들을 찍어봅니다.

변수 P를 numpy의 arange로 정수 배열로 정의합니다.

예측값들은 \(c_{1}P^2+c_{2}P+c_{3}\)가 됩니다. 이제 그려보고 성능을 확인해보겠습니다.

# 훈련 
lr=LinearRegression()
lr.fit(train_poly, train_Y)

# 최적의 상수
[c1, c2], c3=lr.coef_, lr.intercept_

# 그리기
P=np.arange(15, 50)
plt.scatter(train_X, train_Y)
plt.plot(P, c1*P**2+c2*P+c3, color='red')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 성능 평가 
print(lr.score(train_poly, train_Y))
print(lr.score(test_poly, test_Y))

결과를 출력해보면, 

 

 

이렇게 만족스러운 결과를 얻을 수 있습니다. 

이번 실습의 전체 코드입니다.

 

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

# 데이터 
fish_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
       21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
       23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
       27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
       39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
       44.0])

fish_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
       115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
       150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
       218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
       556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
       850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
       1000.0])


# train, test data set 
train_X, test_X, train_Y, test_Y=train_test_split(
    fish_length, fish_weight, random_state=42
) 

# 2차원 배열로 전환 
train_X=train_X.reshape(-1,1)
test_X=test_X.reshape(-1,1)

#선형회귀
lr=LinearRegression() # 객체 생성
lr.fit(train_X, train_Y) # 훈련
a,b=lr.coef_, lr.intercept_ # a, b는 기울기, y절편
plt.scatter(train_X, train_Y) # 산점도 
plt.plot([15, 50], [15*a+b, 50*a+b], color='red') # 직선 그리기
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
print(lr.score(test_X, test_Y)) # 성능 평가 

# 브로드 캐스팅 + 행렬 붙이기
train_poly=np.column_stack((train_X**2, train_X)) 
test_poly=np.column_stack((test_X**2, test_X)) 
print(train_poly.shape, test_poly.shape)

# 훈련 
lr=LinearRegression()
lr.fit(train_poly, train_Y)

# 최적의 상수
[c1, c2], c3=lr.coef_, lr.intercept_

# 그리기
P=np.arange(15, 50)
plt.scatter(train_X, train_Y)
plt.plot(P, c1*P**2+c2*P+c3, color='red')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 성능 평가 
print(lr.score(train_poly, train_Y))
print(lr.score(test_poly, test_Y))

 

 

 

댓글