library(tidyverse)
library(tidymodels)
library(ISLR2)
# step_pls() requires the Bioconductor package mixOmics.
# Check this at the start so Quarto fails early with a useful message.
if (!requireNamespace("mixOmics", quietly = TRUE)) {
stop(
"mixOmics is not available to the R session used by Quarto. ",
"Install it in this same R installation with BiocManager::install('mixOmics'), ",
"then restart R/RStudio and render again."
)
}
library(mixOmics)Chapter 6 Applied Problems: Guided Assignment
Introduction
Use the approaches introduced in the Chapter 6 lab to complete the following applied problems. Continue to use tidymodels and the tidyverse. When tuning a model, use cross-validation on the training data and keep the test set untouched until the final model has been selected.
For every tuning procedure:
- set a random seed;
- use the same resamples when comparing candidate values of a tuning parameter;
- inspect the tuning plot rather than relying only on one numerical result;
- finalize the selected workflow and fit it to the entire training set;
- report test RMSE and test \(R^2\) only after model selection is complete.
Problem 1: Predicting college applications
Problem 1 — Chapter 6, Problem 9 with the assignment modifications
Use the College data to predict the number of applications received, Apps, from the remaining variables.
You will compare:
- ordinary least-squares regression,
- ridge regression,
- lasso regression,
- principal components regression (PCR),
- partial least squares (PLS).
For the tuned models, use 10-fold cross-validation. For the final comparison, create a properly formatted table with the model name, model complexity, test RMSE, and test \(R^2\).
Part (a): Prepare the data, split, and resamples
Guidance
- Convert
Collegeto a tibble and examine its variables. - Split the data into training and test sets, using
Appsfor stratification. - Create 10 folds from the training data for later cross-validation.
- Create one common preprocessing recipe that can be reused by all models.
- The
Collegedata include a categorical predictor, so account for new levels and create dummy variables. - Normalize numeric predictors so that regularized models are not affected by differences in measurement scale.
Useful functions include initial_split(), training(), testing(), vfold_cv(), recipe(), step_novel(), step_dummy(), step_zv(), and step_normalize().
Part (b): Ordinary linear regression
Guidance
Fit an ordinary linear regression model using all remaining variables to predict Apps.
Use a workflow containing the common recipe and a linear_reg() model with the lm engine. Fit the workflow to the full training set and evaluate it on the test set.
Report:
- test RMSE;
- test \(R^2\);
- the number of predictors retained by this model.
The ordinary linear model does not remove predictors, so its complexity count is the number of predictor columns after preprocessing.
Part (c): Ridge regression
Guidance
Fit a ridge regression model using the same predictors and preprocessing.
- Use
linear_reg()with theglmnetengine. - Set
mixture = 0for ridge regression. - Set
penalty = tune(). - Create a grid of possible penalty values and tune with the 10 folds created in part (a).
- Use
autoplot()to examine the tuning results. - Use
show_best()to inspect the best candidate values. - Select the best penalty, finalize the workflow, and fit the final model to all training observations.
Report:
- selected penalty value;
- test RMSE;
- test \(R^2\);
- model complexity.
Remember that ridge regression shrinks coefficients but generally does not set them exactly to zero.
Part (d): Lasso regression
Guidance
Repeat the regularization analysis using the lasso.
- Set
mixture = 1. - Tune
penaltyusing the same 10-fold resamples. - Display the tuning results with
autoplot(). - Finalize and fit the selected model.
- Apply
tidy()to the final fitted model to inspect its coefficients.
Report:
- selected penalty value;
- test RMSE;
- test \(R^2\);
- number of non-zero predictor coefficients retained by the final lasso model.
Do not count the intercept when determining model complexity.
Part (e): Principal components regression (PCR)
Guidance
Fit a PCR model using a PCA preprocessing step followed by ordinary linear regression.
For this assignment, tune the PCA variance threshold using cross-validation.
- Start from the common preprocessing recipe.
- Add
step_pca(all_predictors(), threshold = tune()). - Create a reasonable grid of threshold values.
- Tune using the same 10 folds.
- Use
autoplot()and the tuning results to select the best threshold. - Finalize and fit the model.
Report:
- selected threshold;
- test RMSE;
- test \(R^2\);
- number of principal components retained by the final model.
A useful way to count retained components is to examine the final model with tidy() and count the non-intercept component terms.
Part (f): Partial least squares (PLS)
Guidance
Fit a PLS model using the common preprocessing recipe.
- Add
step_pls(all_predictors(), num_comp = tune(), outcome = "Apps"). - Create a grid of possible values for
num_comp. - Tune using the same 10 folds.
- Display the tuning results with
autoplot(). - Select the best number of components, finalize the workflow, and fit the final model.
Report:
- selected number of components;
- test RMSE;
- test \(R^2\).
Part (g): Compare the models
Guidance
Create a properly formatted comparison table with one row for each model and these columns:
- short model name;
- number of predictors/components retained;
- test RMSE;
- test \(R^2\).
The table should contain the ordinary linear model, ridge, lasso, PCR, and PLS.
Use the table to answer the following questions:
- Which model has the smallest test RMSE?
- Which model has the largest test \(R^2\)?
- Are the performance differences large enough to clearly favor one method?
- Which models are simpler in terms of the number of retained predictors/components?
- If two models have nearly identical predictive performance, is there a reason to prefer the simpler one?
Remember that ordinary regression and ridge retain all predictor columns, while lasso may eliminate predictors and PCR/PLS reduce dimension through components.
Problem 2: Predicting Boston crime rate
Problem 2 — Chapter 6, Problem 11 with the assignment modifications
Use the Boston data to predict per-capita crime rate, crim.
Fit and tune the following four models:
- ridge regression,
- lasso regression,
- PCR,
- PLS.
Use cross-validation to tune each model. Display a tuning plot for each method and create a final comparison table similar to the one from Problem 1.
Part (a): Prepare the data and common resamples
Guidance
- Convert
Bostonto a tibble. - Split the data into training and test sets, stratifying by
crim. - Create 10 folds from the training data.
- Create common linear-regression and
glmnetmodel specifications. - Create a common recipe that prepares all predictors for the models.
Use the same split and the same folds for every model so the comparisons are fair.
Ridge regression
Guidance
- Use
mixture = 0andpenalty = tune(). - Choose a reasonable penalty grid.
- Tune using the 10 folds.
- Display the tuning results with
autoplot(). - Select the best model using RMSE.
- Finalize, fit, and evaluate on the test set.
Record the selected penalty, test RMSE, and test \(R^2\).
Lasso regression
Guidance
- Use
mixture = 1andpenalty = tune(). - Tune using 10-fold cross-validation.
- Display the tuning results.
- Finalize and fit the selected model.
- Use
tidy()to inspect the final coefficients.
Record:
- selected penalty;
- test RMSE;
- test \(R^2\);
- number of non-zero predictor coefficients.
Principal components regression (PCR)
Guidance
For this problem, tune PCR directly by the number of components.
- Add
step_pca(all_predictors(), num_comp = tune())to the common recipe. - Tune plausible component counts with the same 10 folds.
- Display the tuning plot.
- Select the best number of components using RMSE.
- Finalize, fit, and evaluate on the test set.
Record the selected number of components, test RMSE, and test \(R^2\).
Partial least squares (PLS)
Guidance
- Add
step_pls(all_predictors(), num_comp = tune(), outcome = "crim"). - Tune the number of components with the same 10 folds.
- Display the tuning plot.
- Select the best number of components using RMSE.
- Finalize, fit, and evaluate on the test set.
Record the selected number of components, test RMSE, and test \(R^2\).
Performance summary
Guidance
Create a table with one row for each of the four methods and the following columns:
- Model;
- Predictors / Components;
- Test RMSE;
- Test \(R^2\).
Use the table—not training performance—to compare the models.
Part (b): Choose a best model or set of models
Guidance
Using your comparison table, propose either:
- one preferred model, or
- a small set of models that appear essentially competitive.
Justify your choice using both predictive performance and model complexity. If several models have very similar RMSE and \(R^2\), say so rather than overstating small differences.
Part (c): Does the chosen model use all predictors?
Guidance
Answer this question in a way appropriate for the model you selected.
- For the lasso, inspect which original predictor coefficients are non-zero.
- For PCR or PLS, be careful: using fewer components does not necessarily mean that only a few original variables contribute. Each component can be a linear combination of many or all original predictors.
Explain clearly what “uses all predictors” means for your chosen model.
Submission checklist
Before submitting, verify that your report includes:
- reproducible random seeds;
- one untouched test set for each problem;
- 10-fold cross-validation for every tuned model;
- tuning plots for ridge, lasso, PCR, and PLS;
- selected hyperparameter values;
- test RMSE and test \(R^2\) for every final model;
- appropriate model-complexity counts;
- a formatted model-comparison table for each problem;
- written conclusions based on the test-set results and model complexity.