set.seed(42)
tr_idx <- sample(nrow(nhanes_cc), round(0.7 * nrow(nhanes_cc)))
X_tr <- X[tr_idx, ]; y_tr <- y[tr_idx]
X_te <- X[-tr_idx, ]; y_te <- y[-tr_idx]
# Null model baseline
null_rmspe <- sqrt(mean((y_te - mean(y_tr))^2))
# OLS
ols <- lm(y_tr ~ X_tr)
ols_rmspe <- sqrt(mean((y_te - cbind(1, X_te) %*% coef(ols))^2))
# Forward stepwise (AIC) โ refit on training data
tr_df <- as.data.frame(cbind(SBP = y_tr, X_tr))
fwd <- step(lm(SBP ~ 1, data=tr_df),
scope = list(upper = lm(SBP ~ ., data=tr_df)),
direction = "forward", trace = FALSE)
te_df <- as.data.frame(cbind(SBP = y_te, X_te))
fwd_rmspe <- sqrt(mean((y_te - predict(fwd, newdata=te_df))^2))
# Ridge and LASSO via CV
cv_ridge <- cv.glmnet(X_tr, y_tr, alpha = 0, nfolds = 10)
cv_lasso <- cv.glmnet(X_tr, y_tr, alpha = 1, nfolds = 10)
ridge_rmspe <- sqrt(mean((y_te - predict(cv_ridge, X_te, s="lambda.min"))^2))
lasso_rmspe <- sqrt(mean((y_te - predict(cv_lasso, X_te, s="lambda.min"))^2))
# Summary table
results <- data.frame(
Method = c("Null (mean)", "OLS", "Forward (AIC)", "Ridge", "LASSO"),
Test_RMSPE = round(c(null_rmspe, ols_rmspe, fwd_rmspe, ridge_rmspe, lasso_rmspe), 3)
)
results$vs_Null <- round(100 * (1 - results$Test_RMSPE / null_rmspe), 1)
names(results)[3] <- "% better than null"
print(results)