import warnings
# 경고 메시지 출력 표기 생략
warnings.filterwarnings('ignore')최소제곱법 (Least Ordinary Squares)
최소제곱법, 또는 최소자승법, 최소제곱근사법, 최소자승근사법(method of least squares, least squares approximation)은 어떤 계의 해방정식을 근사적으로 구하는 방법으로, 근사적으로 구하려는 해와 실제 해의 오차의 제곱의 합이 최소가 되는 해를 구하는 방법입니다.
최소제곱법 공식유도
from IPython.display import YouTubeVideo
YouTubeVideo('-oBmMED_5rI', width=480)한계
- 노이즈(outlier)에 취약합니다.
- 특징 변수와 샘플 건수에 비례해서 계산 비용이 높습니다.
RSS(Residual Sum of Square) 공식
실제 값(y)과 가설(\(\hat{y}\))에 의한 예측 값의 차이가 가장 작은 계수 계산
선형함수:
\(y = wx + b\)일때,
\(\Large w = \Large\frac{\sum(x-\bar{x})(y-\bar{y})}{\sum(x-\bar{x})^{2}}\)
\(\Large b = \Large\bar{y} - w\bar{x}\)
샘플 데이터를 생성합니다.
import numpy as np
import matplotlib.pyplot as plt
# 랜덤시드 설정
np.random.seed(123)
# 50개의 X를 생성합니다.
x = np.arange(50)
# w=기울기, b=절편
w = 0.3
b = 0.8
# 선형회귀 식을 작성합니다. y 값을 산출합니다.
y = w * x + b위의 수식에 근거하여 y 데이터 생성시 일직선으로 표현되는 단순한 선형함수가 완성되므로, 약간의 노이즈를 추가합니다.
# 노이즈를 랜덤하게 생성합니다.
noise = np.random.uniform(-1.25, 1.25, size=y.shape)
# y 값에 노이즈를 추가합니다.
yy = y + noise생성한 샘플 데이터를 시각화합니다.
plt.figure(figsize=(10, 7))
plt.plot(x, y, color='r', label=f'y = {w}x + {b}')
plt.scatter(x, yy, label='data')
plt.legend(fontsize=15)
plt.show()샘플 데이터 생성 코드를 함수로 만들기
def make_linear(w=0.5, b=0.8, size=50, noise=1.0):
x = np.arange(size)
y = w * x + b
noise = np.random.uniform(-abs(noise), abs(noise), size=y.shape)
yy = y + noise
plt.figure(figsize=(10, 7))
plt.plot(x, y, color='r', label=f'y = {w}x + {b}')
plt.scatter(x, yy, label='data')
plt.legend(fontsize=15)
plt.show()
print(f'w: {w}, b: {b}')
return x, yyx, y = make_linear(size=100, w=0.3, b=0.8, noise=0.5)Python 코드로 구현
최소제곱법 (Least Square) 공식
RSS(Residual Sum of Square)
실제 값(y)과 가설(\(\hat{y}\))에 의한 예측 값의 차이가 가장 작은 계수 계산
선형함수:
\(\Large y = wx + b\)일때,
\(\Large w = \Large\frac{\sum(x-\bar{x})(y-\bar{y})}{\sum(x-\bar{x})^{2}}\)
\(\Large b = \Large\bar{y} - w\bar{x}\)
x_bar변수에는 x에 대한 평균을 구합니다.y_bar변수에는 y에 대한 평균을 구합니다.
# 코드를 입력해 주세요
x_bar =
y_bar =
print(f'x_bar: {x_bar}, y_bar: {y_bar}')
[출력 결과]
x_bar: 49.5, y_bar: 15.660657927243854
w의 계수 값 찾기
\(\Large w = \Large\frac{\sum(x-\bar{x})(y-\bar{y})}{\sum(x-\bar{x})^{2}}\)
w를 계산하여 calcaulated_weight에 대입 합니다.
# 코드를 입력해 주세요
calculated_weight = # 코드검증
print('w: {:.2f}'.format(calculated_weight))
[출력 결과]
w: 0.30
b의 계수 값 구현
\(\Large b = \Large \bar{y} - w\bar{x}\)
calculated_bias 변수 생성 후 계산된 결과를 대입하세요
# 코드를 입력해 주세요
calculated_bias = # 코드검증
print('b: {:.2f}'.format(calculated_bias))
[출력 결과]
b: 0.79
# 최종 결과
print('w: {:.2f}, b: {:.2f}'.format(calculated_weight, calculated_bias))노이즈 값을 증가 시켰을 때
최소제곱법은 노이즈에 취약하다는 단점이 있습니다.
이를 직접 눈으로 확인해 보도록 하겠습니다.
x, y = make_linear(size=100, w=0.3, b=0.8, noise=0.5)
# 임의로 2개의 outlier를 추가해 보도록 하겠습니다.
y[5]=20
y[10]=20
plt.figure(figsize=(10, 7))
plt.scatter(x, y)
plt.show()# 코드입력
x_bar = x.mean()
y_bar = y.mean()
calculated_weight = ((x - x_bar) * (y - y_bar)).sum() / ((x - x_bar)**2).sum()
calculated_bias = y_bar - calculated_weight * x_bar
# 최종 결과
print('w: {:.2f}, b: {:.2f}'.format(calculated_weight, calculated_bias))
[출력 결과]
w: 0.28, b: 2.00