# Fit or Overfit?
# Core implementation example — ackleywill.com

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
import numpy as np

rng = np.random.default_rng(7)
x = np.linspace(-1, 1, 40).reshape(-1, 1)
y = np.sin(3 * x[:, 0]) + rng.normal(0, 0.2, len(x))
train = np.arange(len(x)) % 3 != 0
for degree in [1, 3, 9]:
    model = make_pipeline(
        PolynomialFeatures(degree, include_bias=False),
        StandardScaler(), Ridge(alpha=0.001)
    )
    model.fit(x[train], y[train])
    for name, mask in [("train", train), ("validation", ~train)]:
        rmse = np.sqrt(mean_squared_error(y[mask], model.predict(x[mask])))
        print(degree, name, round(rmse, 3))
