2021. 3. 12. 00:10ㆍ머신러닝
우리가 앞서 정리했던 Cubic Spline, Natural Cubic Spline은 knot이라는 절단점을 정하여 구간별로 적절한 3차 다항식을 Fitting하였습니다.
Smoothing Spline은 knots의 Maximal set을 활용함으로써 절단점을 어디로 할지 결정하는 것에 있어서 자유롭습니다. 즉 주어진 Input X의 Unique한 모든 값을 knot으로써 활용한다는 것입니다. 따라서 Smoothing Spline을 구현하는 것은 모든 Unique한 X값을 knot으로 하는 Natural Cublic Spline을 구현한 것과 같습니다. 다만, 아래의 식에서 보는 것과 같이 추가적인 Penalty가 주어지기 때문에 $\lambda$가 0이 아니라면 Ridge, Lasso와 같이 Natural Cubic Spline의 Shrinkage 버전이 됩니다.
위 식에서 $\lambda$가 있는 term은 Penalty term이며, $\lambda$는 Fitting하는 곡선의 Roughness를 나타냅니다.
$\lambda$가 0이라면, $f$는 어떠한 함수가 될 수 있으며, $\lambda$가 무한대에 가까워 진다면, Simple least squares line fit이 됩니다. 그 이유는 $\lambda$가 무한대라면, 이차 미분 값이 0이 되어야 하기 때문입니다.
위에서 정리한 것 처럼 Smoothing Spline은 모든 Unique한 X값을 knot으로 하는 Natural Cublic Spline을 구현한 것과 같습니다. 그렇기 때문에 많은 degree of freedom을 가지게 됩니다. (절단점이 늘어날 수록 Fitting하는 곡선의 자유도가 높아지게 됩니다.) 하지만 우리는 추가적인 Penalty term을 가지게 되는데, 이 Penalty term의 Parameter인 $\lambda$를 조정함으로써, 곡선의 Roughness를 조절하게 됩니다. 그렇기 때문에 Effective degree of freedom의 개념이 도입되게 됩니다. $\lambda$에 따라 Fitting 하는 곡선의 유연함이 변하기 때문입니다.
이 Effective degree of freedom은 $\lambda$ 가 0부터 무한대까지 변할 때, n부터 2까지로 변하게 됩니다. 즉 $\lambda$가 커질수록 Effective degree of freedom은 작아지게 됩니다. 이 것은 직관적으로 당연한데, $\lambda$가 커질수록 직선에 가까워지기 때문에 Fitting의 유연성이 떨어지게 됩니다.
Python에서 Smoothing Spline을 구현해보겠습니다.
다만, 위에서 설명했던 것과 동일한 직관에 의해 작동되는(R에서 제공한 smooth.spline과 같은) Package는 없는 것 같습니다. 오히려 Matlab에서 제공하는 Cubic Smoothing Spline 함수와 동일하며, 해당 해키지의 Formula는 아래와 같습니다.
위에서 w와 $\lambda$의 Default값은 1이며, p를 조절함으로써 roughness를 조절하게 됩니다. 만약 p가 0이라면 linear fit과 동일합니다. 위의 함수가 좀 더 구현하는 입장에서 고려할 것이 조금 더 있는것으로 보이는데, error measure 부분에 weight을 고려할 수 있고 $\lambda$를 구간별로 다르게 가져갈 수 있기 때문입니다.
Python csaps 패키지를 활용하여 구현해보겠습니다. X값과 Y값이 1:1로 배열되어야 하기 때문에, 전처리를 수행해야 합니다.
## Smoothing Spline
from csaps import CubicSmoothingSpline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
## Data loading
data = pd.read_csv("Wage.csv")
train_x_mod = data.sort_values("age").groupby("age")["wage"].median().reset_index()
## Smoothing Spline
smoothing_spline = CubicSmoothingSpline(train_x_mod["age"], train_x_mod["wage"], smooth=0.85)
## Prediction
xp = np.linspace(train_x_mod["age"].min(),train_x_mod["age"].max(),70)
yp = smoothing_spline(xp)
## Plot
plt.scatter(data["age"], data["wage"], facecolor='None', edgecolor='k', alpha=0.3)
plt.plot(xp, yp, linewidth=3)
plt.show()
'머신러닝' 카테고리의 다른 글
KRR(Kernel Ridge Regression) (0) | 2021.03.23 |
---|---|
Kernel Regression (0) | 2021.03.23 |
Natural Cubic Spline (0) | 2021.03.09 |
Piecewise Polynomial and Regression Splines (3) | 2021.03.02 |
로지스틱 회귀모형(Logistic Regression) (0) | 2021.02.23 |