import numpy as np
import pandas as pd
from pickle import TRUE
import statsmodels.formula.api as smf
from plotnine import *
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import PolynomialFeatures
# Use one random-number generator so every simulated dataset is reproducible.
rng = np.random.default_rng(123)
def simulate_quartic_data(n=1000, x_sd=0.25, noise_sd=0.5):
"""Simulate data from the quartic relationship used in the slides."""
x = rng.normal(loc=0, scale=x_sd, size=n)
y = (
1
+ 5.3 * x
- 45 * x**2
- 35.5 * x**3
+ 60 * x**4
+ rng.normal(loc=0, scale=noise_sd, size=n)
)
return pd.DataFrame({"x": x, "y": y})
def simulate_quadratic_data(n=1000, x_sd=0.25, noise_sd=0.5):
"""Simulate data from the quadratic relationship used for knot examples."""
x = rng.normal(loc=0, scale=x_sd, size=n)
y = 1 + 5.3 * x - 45 * x**2 + rng.normal(loc=0, scale=noise_sd, size=n)
return pd.DataFrame({"x": x, "y": y})
def simulate_sine_data(n=1000, x_sd=3.5, noise_sd=0.25):
"""Simulate data from the sinusoidal relationship used in the slides."""
x = rng.normal(loc=0, scale=x_sd, size=n)
y = 1 + np.sin(np.pi * x / 8) + rng.normal(loc=0, scale=noise_sd, size=n)
return pd.DataFrame({"x": x, "y": y})
# Each object corresponds to one of the original R simulation chunks.
motivating_polynomial_data = simulate_quartic_data()
motivating_sine_data = simulate_sine_data()
linear_fit_data = simulate_quartic_data()
quartic_fit_data = simulate_quartic_data()
polynomial_example_data = simulate_quartic_data()
step_plot_data = simulate_quartic_data()
step_example_data = simulate_quartic_data()
knot_data = simulate_quadratic_data()
more_knots_data = simulate_quadratic_data()
cubic_spline_data = simulate_quartic_data()
natural_spline_data = simulate_quartic_data()
spline_example_data = simulate_quartic_data()