Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

SYDev

Chapter 03-2: 선형 회귀 본문

KHUDA 4th/머신러닝 기초 세션

Chapter 03-2: 선형 회귀

시데브 2023. 8. 3. 18:58
k-최근접 이웃의 한계를 인지하고, 선형·다항 회귀 알고리즘으로 문제를 해결하자.

 

 

k-최근접 이웃의 한계

 chapter 03-1에서 다룬 모델로 길이가 50cm인 샘플의 무게를 예측해보자.

 

import numpy as np
perch_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])
perch_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])

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42)
train_input = train_input.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)

from  sklearn.neighbors import KNeighborsRegressor
knr=KNeighborsRegressor(n_neighbors=3)
knr.fit(train_input, train_target)

print(knr.predict([[50]])
[1033.33333333]

 

-> k-최근접 이웃 알고리즘은 해당 샘플의 무게를 1033g 정도로 예측했다.

 

 그렇다면 이를 산점도로 그려보자.

import matplotlib.pyplot as plt

distances, indexes = knr.kneighbors([[50]])

plt.scatter(train_input, train_target)

plt.scatter(train_input[indexes], train_target[indexes], marker='D')

plt.scatter(50, 1033, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 산점도를 통해 문제를 명확히 파악할 수 있다.

  • k-최근접 이웃 회귀 알고리즘에서 50cm 샘플의 최근접 샘플은 모두 45cm 범위에 포진해있기 때문에, 길이가 대략 45cm인 샘플들과 무게가 비슷하다고 예측한다.
  • 그렇기 때문에, 길이 45cm를 넘어가는 샘플부터는 k-최근접 이웃 회귀 알고리즘의 정확도가 현저히 떨어진다.

+ 100cm 샘플의 경우도 같은지 확인해보자.

더보기
distances, indexes = knr.kneighbors([[100]])

plt.scatter(train_input, train_target)

plt.scatter(train_input[indexes], train_target[indexes], marker='D')

plt.scatter(100, 1033, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

선형 회귀

  • 선형 회귀(linear regression): 특성과 타깃 사이의 관계를 가장 잘 나타내는 선형 방정식을 찾아, 주어진 데이터의 예측값을 찾아내는 데이터 분석 기법
from sklearn.linear_model import LinearRegression
lr=LinearRegression()

lr.fit(train_input, train_target) #선형 회귀 모델을 훈련

print(lr.predict([[50]]))
print(lr.coef_, lr.intercept_)  #직선의 기울기와 y절편
[1241.83860323]
[39.01714496] -709.0186449535477
plt.scatter(train_input, train_target)

plt.plot([15, 50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])  #점 (15, 15*lr.coef_+lr.intercept_)과 (50, 50*lr.coef_+lr.intercept_)를 연결하는 직선

plt.scatter(50, 1241.8, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

print(lr.score(train_input, train_target))
print(lr.score(test_input, test_target))
0.939846333997604
0.8247503123313558

-> 훈련 세트와 테스트 세트의 정확도가 전체적으로 낮은 것으로 보아, 과소적합되었다는 것을 알 수 있다. 이는 모델의 복잡도를 높일 필요가 있다는 것을 의미한다.

 

 

다항 회귀

  • 다항 회귀(polynomial regression): 다항식을 사용한 선형 회귀, 이 함수는 비선형(non-linear)이라 할 수도 있지만 치환을 이용하면 선형 관계로 표현할 수 있다.
train_poly = np.column_stack((train_input ** 2, train_input)) #각 원소를 제곱한 train_input을 train_input 배열과 나란히 붙이는 작업
test_poly = np.column_stack((test_input ** 2, test_input))  #각 원소를 제곱한 test_input을 test_input 배열과 나란히 붙이는 작업

lr = LinearRegression()
lr.fit(train_poly, train_target)

print(train_poly.shape, test_poly.shape)
print(lr.predict([[50**2, 50]]))
print(lr.coef_, lr.intercept_)  #2차 방정식의 계수, 가중치를 순서대로 출력
(42, 2) (14, 2)
[1573.98423528]
[  1.01433211 -21.55792498] 116.0502107827827

 위를 통해 모델이 학습한 그래프를 $무게 = 1.01*길이^2 -21.6*길이 + 116.05$로 예측할 수 있다.

 

point = np.arange(15, 50) #15부터 49까지 정수 배열

plt.scatter(train_input, train_target)

plt.plot(point, 1.01*point**2 - 21.6*point + 116.05)  #15에서 49까지 2차 방정식 그래프

plt.scatter(50, 1574, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))
0.9706807451768623
0.9775935108325122

-> 조금 남아있는 과소적합의 문제를 다음 절에서 해결해보자.


참고자료

 

선형 회귀란 무엇인가요? - 선형 회귀 모델 설명 - AWS

Amazon SageMaker는 고품질 기계 학습 모델(ML)을 빠르게 준비, 빌드, 훈련, 배포할 수 있는 완전관리형 서비스입니다. Amazon SageMaker Autopilot은 사기 탐지, 이탈 분석, 표적 마케팅과 같은 분류 및 회귀

aws.amazon.com