Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

🏋️ Exercises

Please fill the missing code pieces as indicated by the .... The imports are always provided at the top of the code chunks. This should give you a hint for which functions/classes to use. Have a look at the online documentation if you are unsure how to use them.

Exercise 1: Model Selection

We are working with the California Housing dataset again, which you already know from the resampling session. It is based on the 1990 U.S. Census and contains features describing districts in California.

  1. Load the data and extract the features (X) and the target (y)

  1. Baseline model

    • Split the data into 80% training and 20% test data (print the shapes to confirm that it was successful)

    • Evaluate a linear regression with all features on the training data, using 5-fold cross-validation and R² as the performance metric. Remember what you learned about shuffling in the resampling session!

    • Print the individual and the average R²

  1. Apply forward stepwise selection to find a simpler model

    • Use a linear regression model, the same cross-validation folds as for the baseline, R² as the score, and k_features="parsimonious". This option picks the smallest subset whose CV score is within one standard error of the best subset (see the documentation)

    • Print the best CV R² as well as the chosen features. How does the CV R² compare to the baseline?

  1. Evaluate both the baseline model and the selected model on the test set. Is the simpler model worse?

Exercise 2: Lasso

Please implement a Lasso regression model similar to the Ridge model in the Regularization section:

  1. Prepare the data: drop the highly correlated features and rows with missing data, split the data into training and test set, and scale the predictors

  2. Use LassoCV with 5-fold cross-validation to find the optimal λ. Test 100 values between 0.01 and 1000, evenly spaced on a log scale (np.logspace())

  3. Print the optimal λ, the training and test R², and the coefficients. Which predictors does Lasso remove?

  4. Is the optimal λ at the edge of the range you tested? Why would that be a problem?

Exercise 3: Principal Component Analysis

In this exercise, we work with the Diabetes dataset from scikit-learn. It contains 10 baseline measurements of 442 diabetes patients: age, sex, body mass index (bmi), average blood pressure (bp), and six blood serum measurements (s1 to s6). The target is a measure of disease progression one year after baseline. You can read more in the documentation or with print(diabetes.DESCR).

  1. Inspect the data

    • Use .describe() and .isna().sum() to get summary statistics and to check for missing values

    • Look at the mean and the standard deviation of the features. What do you notice? (Hint: print(diabetes.DESCR))

  1. Fit a PCA

    • Standardize the features with StandardScaler() and fit a PCA() with all components

    • Plot the explained variance ratio of each component (scree plot, e.g. as bars) and the cumulative explained variance (line) next to each other

    • How many components do you need to explain at least 80% of the variance? Is there a clear elbow?

  1. Interpret the loadings

    • Create a DataFrame with the loadings of the first three components (one row per component, one column per feature)

    • Plot it with sns.heatmap() (useful arguments: annot=True, cmap="coolwarm", center=0)

    • Which features have the largest absolute loadings on PC1 and PC2? What could these components represent? The serum measurements are: s1 total cholesterol, s2 LDL (“bad” cholesterol), s3 HDL (“good” cholesterol), s4 ratio of total cholesterol to HDL, s5 triglycerides (log), s6 blood sugar

  1. Project the data

    • Transform the standardized data into the PCA space

    • Create a scatter plot of PC1 against PC2 and color the points by disease progression (y)

    • Along which component does the disease progression change? Remember that the PCA never saw y!

Exercise 3.2: PCR and PLS

Now we use the components to predict disease progression. We continue with the same data (X and y) as in the previous exercise.

  1. Visualize the correlations between the predictors with a heatmap. Which predictors are strongly correlated? Why could this be a problem for a linear regression?

  1. PCR with a range of components

    • Split the data into 80% training and 20% test data (random_state=42)

    • Set up a 10-fold cross-validation with shuffling (random_state=42)

    • For 1 to 10 components, create a PCR pipeline with make_pipeline() (StandardScaler, PCA, LinearRegression) and evaluate it on the training data with cross_val_score(). Store the mean R² of each model

  1. PLS and comparison

    • Do the same with PLSRegression (it standardizes the predictors by itself)

    • As a baseline, also compute the cross-validated R² of a plain linear regression with all predictors

    • Plot the R² of PCR and PLS over the number of components, and add the baseline as a horizontal line (ax.axhline())

    • How does PLS compare to PCR?

  1. Why does the PCR performance jump at 4 components?

    • Fit the first two steps of a PCR pipeline (scaler and PCA with all components) on the training data and compute the scores of the training data

    • Compute the correlation of each component with y_train (np.corrcoef()) and compare it to the explained variance ratio of the component

    • What do you notice? How does this relate to the example in the session?

  1. Test set evaluation

    • For PCR and PLS, choose the smallest number of components after which the CV R² hardly improves

    • Fit both models and the linear regression baseline on the full training data and print their test R²

    • Was the dimension reduction worth it in this dataset?

Exercise 4: Logistic Regression

For today’s exercise we will use the Breast Cancer Wisconsin (Diagnostic). It is a collection of data used for predicting whether a breast tumor is malignant (cancerous) or benign (non-cancerous), containing information derived from images of breast mass samples obtained through fine needle aspirates.

The dataset consists of 569 samples with 30 features that measure various characteristics of cell nuclei, such as radius, texture, perimeter, and area. Each sample is labeled as either malignant (1) or benign (0).

  1. Please visit the documentation and familiarize yourself with the dataset

  2. Take an initial look at the features (predictors) and targets (outcomes)

  1. Split the data into training and test sets (stratify y)

  2. Create and fit a baseline model using only 2-3 interpretable predictors of your choice

    • Print the model coefficients

  3. Evaluate on the test set:

    • Accuracy

    • Confusion matrix

    • Classification report

    • Compare test accuracy to train accuracy. Is there a big gap?

Hint: If you get a warning about convergence, try setting max_iter=10000 in the logistic regression class.

  1. Use all predictors and build a pipeline with standardisation

  2. Evaluate on the test set

  3. Compare:

    • Baseline model vs full model (test accuracy, precision, recall for malignant)

    • Is the full model clearly better?

    • Is there any sign of overfitting (train vs test)?

  1. Create a custom plot which visualizes the confusion matrix It should contain:

    • The four squares of the matrix (color coded)

    • Labels of the actual values in the middle of each square

    • Labels for all squares

    • A colorbar

    • A title

  2. Use scikit-learn to do the same

Exercise 5: LDA, QDA & Naïve Bayes

Once again, we will use the Iris dataset for classificationa analysis. Your task is to compare the performance of LDA, QDA, and Gaussian Naïve Bayes!

  1. Load the iris dataset from sklearn.datasets. We will use only the first two features (sepal length and width)

  2. TODO: Split the data into training and test sets (use stratification!)

  3. TODO: Fit LDA, QDA, and Naïve Bayes classifiers to the training data and orint the classification report for all models on the test data

  4. Plot the decision boundaries for both models

Once you have trained all three models, you can plot their decision boundaries based on the training data. For this, you can use the provided helper function below:

Exercise 6: Polynomial and Flexible Regression

In this exercise, we analyse the relationship between wage and age using four flexible regression approaches:

  • Polynomial regression

  • Stepwise functions (degree-0 splines)

  • Spline regression

  • Local regression (LOWESS)

We will use the Wage dataset for the following exercises. Please briefly visit the documentation for further information: https://rdrr.io/cran/ISLR/man/Wage.html

Loading...
<Figure size 640x480 with 1 Axes>

Please predict Wage from Age using four different models:

  1. A polynomial regression model of degree 3

  2. A stepwise model with cut points at 30, 50, and 65 years

  3. A third order spline regression model with df=6

  4. A lowes local regression model with frac=0.4

Plot the resulting model fits in a single figure.

We can then plot all the models:

Exercise 7: Generalized Additive Models

Objective: Understand how the number of basis functions (df) and the polynomial degree (degree) affect the flexibility of a spline and the resulting fit in a Generalized Additive Model.

  1. Use the diabetes dataset and focus on the relationship between bmi and target.

  2. We want to test different combinations of parameters. For the dfs, please use 4, 6, 12. For the degree, please use 2 and 3 (quadratic and cubic).

  3. Fit the GAMs for each parameter combination. The resulting models will be plotted automatically for visual comparison.

We now use the wage dataset, which contains income information for a group of workers, along with demographic and employment-related features such as age, education, marital status, and job class.

  1. Explore the dataset

    • Which variables are numeric?

    • Which ones are categorical?

  2. Fit a GAM predicting wage from age, year, education, jobclass, and maritl

Note: For categorical features we use a one-hot encoding with pd.get_dummies()

Exercise 8: Trees

  1. Inspect the data

    • How many features are there and what are they?

    • What is the target?

  2. Split the data into a train and test set, and make sure the classes are equally distributed (stratify=y)

  3. Fit the DecisionTreeClassifier(max_depth=3) and report train vs. test accuracy.

  4. Tree inspection (discuss in group)

    • After fitting the model, the tree will be plotted automatically

    • What is the very first split (feature name and threshold)?

    • Which leaf nodes are pure, and which have mixed classes?

See if you can improve the classification performance with a random forest classifier and hyperparameter tuning.

  1. Set up the clasifier + a parameter grid for grid search with 5-fold CV

    • n_estimators: 50, 100, 200

    • max_depth: None, 10, 20

    • min_samples_split: 2, 5, 10

    • max_features: “sqrt”, “log2”, 0.5

  2. Fit the model with the grid search

  3. Print the best hyperparameters

  4. Evaluate the best model on the test set

Exercise 9: Gradient Boosting

Your goal is to manually implement a gradient boosting algorithm and compare it with scikit-learn’s GradientBoostingRegressor. You should complete this exercise without any new libraries.

  • Complete the custom_gb_mse() and predict_gb() functions

    1. Start with constant prediction equal to the mean of y

    2. Compute residuals

    3. Fit weak learners to residuals

    4. Update the model using a learning rate

  • Compare your custom implementation with sklearn

Exercise 10: SVMs

For the SVM exercises we will use the fmri dataset from seaborn, which contains measurements of brain activity (signal) in two brain regions (frontal and parietal) under two event types (stim vs. cue).

We will try to answer a very simple research question:

Can we distinguish between cue and stim events based on the fMRI signal in the parietal and frontal brain regions?

To do this, we need to turn the long‐format data into a classic “feature matrix” (one row = one sample, two columns = our two brain‐region signals) plus a corresponding label vector (cue/stim):

With the features and target in the correct form, please perform the following tasks:

  1. Split the data into a train and test set

  2. Scale the predictors to mean 0 and std 1

  3. Fit a linear as well as a rbf SVC and discuss the classification reports

After fitting both models, you can run the code chunk below to plot the decision boundary:

Training a Support Vector Classifier (SVC) on more complex datasets often requires a systematic hyperparameter search to identify optimal model settings.

Implement a grid search that explores multiple kernels and their corresponding hyperparameters using the following configuration:

  • Kernels: rbf, linear

  • C: np.logspace(-2, 2, 10)

  • gamma: np.logspace(-3, 1, 10) (for rbf)

Further use:

  • Cross-validation: 5-fold

  • Scoring metric: accuracy

Note: Usually you would use a finer grid, but we keep it simpler for the sake of the exercise.

After fitting the model:

  1. Print the optimal hyperparameters

  2. Print the best cross-validation accuracy

  3. Print the test accuracy