일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- knn
- Pycaret
- TypeError
- KAKAO
- Scienceplots
- Python
- Tire
- MAPE
- 논문
- RMES
- 논문editor
- Mae
- SMAPE
- 파이썬을파이썬답게
- 에러해결
- 카카오
- PAPER
- Alignments
- n_sample
- 스택
- 코테
- python 갯수세기
- mMAPE
- Overleaf
- 프로그래머스
- n_neighbors
- mes
- 평가지표
- iNT
- 논문작성
- Today
- Total
EunGyeongKim
지도학습 : 회귀_2차원 모델(평면) 본문
입력이 2차원일 경우 x=(x0, x1)에 확장
1차원일경우 xn은 나이만 의미했지만, 이번에는 몸무게 정보도 사용하여 키를 예측함
사람 체질량 지수가 23이라고 가정하여 데이터를 만듬
$$weight = 23 * \frac{height^2}{100}* noise$$
나이를 x0으로, 몸무게 데이터를 x1로 추가함.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
#create data
x_n = 16
np.random.seed(seed=1)
x = 5+25 * np.random.rand(x_n)
x0 = x
x0_min = 5
x0_max = 30
prm_c = [170, 108, 0.2] # 생성 매개변수
t = prm_c[0] - prm_c[1] * np.exp(-prm_c[2]*x) + 4 *np.random.randn(x_n)
x1 = 23 * (t/100)**2*np.random.randn(x_n)
x1_min = 40
x1_max = 75
# show 2D data
def show_data2(ax, x0, x1, t):
for i in range(len(x0)):
ax.plot([x0[i],x0[i]], [x1[i], x1[i]], [120, t[i]], color='gray')
ax.plot(x0, x1, t, 'o', color='cornflowerblue', markeredgecolor='black', markersize =6, markeredgewidth=0.5)
#elev = elevation angle(양각), azim = azimuth angle(x,y plane angle)
ax.view_init(elev=35, azim=-75)
#main
plt.figure(figsize=(6,5))
ax = plt.subplot(1,1,1, projection='3d')
show_data2(ax, x0, x1, t)
plt.show()
tip. 데이터 표시 방법
n = 데이터 번호
m = 벡터의 요소(0=나이, 1=몸무게 등)
n, m은 x의 아래첨자로 씀.
$$x_n = [x_{n,0}, x_{n,1}]$$
N개의 2차원 벡터 xn에 대해 각각 tn이 할당됨. 2d은 1d보다 1차원이 늘어났으므로 선이 아니라 면을 적용하면 새로운 x=[x0, x1]에 대해 t(키)가 예측이 가능함
임의의 w에 대해 면을 그리는 함수
# show plane
def show_plane(ax, w):
px0 = np.linspace(x0_min, x0_max, 5)
px1 = np.linspace(x1_min, x1_max, 5)
px0, px1 = np.meshgrid(px0, px1)
y = w[0]*px0 + w[1]*px1 + w[2]
ax.plot_surface(px0, px1, y, rstride = 1, cstride = 1, alpha=0.3, color = 'blue', edgecolor='black')
# plane mse
def mse_plane(x0, x1, t, w):
y = w[0]*x0 + w[1]*x1 + w[2]
mse = np.mean((y-t)**2)
return mse
#main
plt.figure(figsize=(6,5))
ax = plt.subplot(1,1,1,projection='3d')
w = [1.5, 1, 90]
show_plane(ax, w)
show_data2(ax, x0, x1, t)
mse = mse_plane(x0, x1, t, w)
print("SD={0:.3f}cm".format(np.sqrt(mse)))
plt.show()
매개변수의 해석해
데이터에 가장 적합한 w = [w0, w1, w2]를 구하자. 2차원 면 모델의 경우에도 1차원과 마찬가지로 평균제곱오차를 다음과 같이 정의 가능
$$J = \frac{1}{N}\sum_{n=0}^{N-1}(y(x_n) - t_n)^2 = \frac{1}{N}\sum_{n=0}^{N-1}(w_0x_{n,0} + w_1x_{n,1} + w_2 - t_n)^2$$
w를 움식이면 면이 여러방향을 향하며, 그에따라 J가 변화함. 목표는 J가 가장 작아지는 w = [w0, w1, w2]를 구하는것임. J를 최소화하는 최적의 w는 기울기가 0임. 따라서 아주 작은 w의 변화에 대해서 J의 변화는 0이기 때문에 J를 w0, w1, w2으로 편미분한것은 0인 관계가 성립됨
$$\frac{\partial J}{\partial w_0} = 0, \frac{\partial J}{\partial w_1} = 0, \frac{\partial J}{\partial w_2} = 0$$
w0에 대한 편미분 식은 다음과 같음.
$$\frac{\partial J}{\partial w_0} = \frac{2}{N}\sum_{n=0}^{N-1}(w_0x_{n,0} + w_1x_{n, 1}+w_2 - t_n)x_{n, 0}$$
$$ = 2\left\{ w_0 <x_0^2> + w_1<x_0x_1> + w_2<x_0> - <{tx_0}> \right\} = 0$$
w1에 대한 편미분 식은 다음과 같음.
$$\frac{\partial J}{\partial w_1} = \frac{2}{N}\sum_{n=0}^{N-1}(w_0x_{n,0} + w_1x_{n, 1}+w_2 - t_n)x_{n, 1}$$
$$= 2\left\{ w_0 <x_0x_1> + w_1<x_1^2> + w_2<x_1> - <{tx_1}> \right\} = 0$$
w2에 대한 편미분 식은 다음과 같음.
$$\frac{\partial J}{\partial w_2} = \frac{2}{N}\sum_{n=0}^{N-1}(w_0x_{n,0} + w_1x_{n, 1}+w_2 - t_n)$$
$$= 2\left\{ w_0 <x_0> + w_1<x_1> + w_2 - <t> \right\} = 0$$
w0, w1, w2의 연립 방적식을 풀면 다음과 같은 식을 얻을 수 있음.
$$w_0 = \frac{cov(t, x_1) cov(x_0, x_1) - var(x_1)cov(t, x_0)}{cov(x_0, x_1)^2 - var(x_0)var(x_1)}$$
$$w_1 = \frac{cov(t, x_0) cov(x_0, x_1) - var(x_0)cov(t, x_1)}{cov(x_0, x_1)^2 - var(x_0)var(x_1)}$$
$$w_2 = -w_0 <x_0> - w_1<x_1>+<t>$$
'var(a) = <a^2> - <a>^2' 은 a의 분산, 'cov(a, b) = <ab>-<a><b>'는 a와 b의 공분산이라고 불리는 통계량
a의 분산은 a와 얼마나 차이가 있는지를 나타내고, a와 b의 공분산은 a와 b가 서로 얼마나 영향을 끼치고 있는지를 나타냄
위 식에 실제 데이터 x0, x1와 목표데이터 t값을 넣어 w0, w1, w2값을 구하고, 그 면을 그려봄
# analytic
def fit_plane(x0, x1, t):
c_tx0 = np.mean(t*x0) - np.mean(t) * np.mean(x0)
c_tx1 = np.mean(t*x1) - np.mean(t) * np.mean(x1)
c_x0x1 = np.mean(x0 * x1) - np.mean(x0) * np.mean(x1)
v_x0 = np.var(x0)
v_x1 = np.var(x1)
w0 = (c_tx1*c_x0x1 - v_x1*c_tx0) / (c_x0x1**2 - v_x0*v_x1)
w1 = (c_tx0*c_x0x1 - v_x0*c_tx1) / (c_x0x1**2 - v_x0*v_x1)
w2 = -w0 * np.mean(x0) - w1 * np.mean(x1) + np.mean(t)
return np.array([w0,w1,w2])
# main
plt.figure(figsize = (6,5))
ax = plt.subplot(1,1,1,projection = '3d')
w = fit_plane(x0, x1, t)
print("w0={0:.1f}, w1={1:.1f}, w2={2:.1f},".format(w[0], w[1], w[2]))
show_plane(ax, w)
show_data2(ax, x0, x1, t)
mse = mse_plane(x0, x1, t, w)
print("SD={0:.3f}cm".format(np.sqrt(mse)))
plt.show()
'ML & DL' 카테고리의 다른 글
지도학습 : 회귀_1차원 모델(선형기저함수_오버피팅, k-fold cross validation) (2) (1) | 2023.02.23 |
---|---|
지도학습 : 회귀_1차원 데이터(선형 기저 함수 모델, 가우시안) (1) (0) | 2023.02.23 |
지도학습 : 회귀(Regression)_1차원 데이터 선형모델 매개변수의 해석해 (2) (0) | 2023.02.22 |
지도학습 : 회귀 (Regression)_1차원 데이터, 직선 (1) (0) | 2023.02.20 |
미분, 편미분 (0) | 2023.02.20 |