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))
'CS > 머신러닝' 카테고리의 다른 글
| 혼자 공부하는 머신러닝 + 딥러닝 - Ch 4-1 (0) | 2023.01.12 |
|---|---|
| 혼자 공부하는 머신러닝 + 딥러닝 - Ch 3-3 (0) | 2023.01.11 |
| 혼자 공부하는 머신러닝 + 딥러닝 - Ch3-1 (0) | 2023.01.08 |
| 혼자 공부하는 머신러닝 + 딥러닝 - Ch2 (0) | 2023.01.07 |
| 혼자 공부하는 머신러닝 + 딥러닝 - Ch1 (0) | 2023.01.04 |
댓글