Python Code can be found at https://github.uio.no/larsbog/FYS-STK4155
Learning goals¶
After completing these exercises, you will know how to
- Derive expectation and variances values related to linear regression
- Compute expectation and variances values related to linear regression
- Compute and evaluate the trade-off between bias and variance of a model
Deliverables¶
Complete the following exercises while working in a jupyter notebook. Then, in canvas, include
- The jupyter notebook with the exercises completed
- An exported PDF of the notebook (https://code.visualstudio.com/docs/datascience/jupyter-notebooks#_export-your-jupyter-notebook)
Use the books!¶
This week deals with various mean values and variances in linear regression methods (here it may be useful to look up chapter 3, equation (3.8) of Trevor Hastie, Robert Tibshirani, Jerome H. Friedman, The Elements of Statistical Learning, Springer).
For more discussions on Ridge regression and calculation of expectation values, Wessel van Wieringen's article is highly recommended.
The exercises this week are also a part of project 1 and can be reused in the theory part of the project.
Definitions¶
We assume that there exists a continuous function $f(\boldsymbol{x})$ and a normal distributed error $\boldsymbol{\varepsilon}\sim N(0, \sigma^2)$ which describes our data
$$ \boldsymbol{y} = f(\boldsymbol{x})+\boldsymbol{\varepsilon} $$
We further assume that this continous function can be modeled with a linear model $\mathbf{\tilde{y}}$ of some features $\mathbf{X}$.
$$ \boldsymbol{y} = \boldsymbol{\tilde{y}} + \boldsymbol{\varepsilon} = \boldsymbol{X}\boldsymbol{\beta} +\boldsymbol{\varepsilon} $$
We therefore get that our data $\boldsymbol{y}$ has an expectation value $\boldsymbol{X}\boldsymbol{\beta}$ and variance $\sigma^2$, that is $\boldsymbol{y}$ follows a normal distribution with mean value $\boldsymbol{X}\boldsymbol{\beta}$ and variance $\sigma^2$.
Exercise 1: Expectation values for ordinary least squares expressions¶
a) With the expressions for the optimal parameters $\boldsymbol{\hat{\beta}_{OLS}}$ show that
$$ \mathbb{E}(\boldsymbol{\hat{\beta}_{OLS}}) = \boldsymbol{\beta}. $$
$$ \mathbb{E}(\boldsymbol{\hat{\beta}_{OLS}}) = \mathbb{E} \left((X^T X)^{-1} X^T y\right) = \mathbb E \left((X^T X)^{-1} X^T \tilde y + (X^T X)^{-1} X^T \epsilon \right) = \beta + \mathbb{E} \left((X^T X)^{-1} X^T \epsilon \right) = \beta $$
b) Show that the variance of $\boldsymbol{\hat{\beta}_{OLS}}$ is
$$ \mathbf{Var}(\boldsymbol{\hat{\beta}_{OLS}}) = \sigma^2 \, (\mathbf{X}^{T} \mathbf{X})^{-1}. $$
$$ \begin{aligned} \mathbf{Var}(\hat \beta_{OLS}) &= \mathbb E (\beta_{OLS} - \mathbb{E}(\hat{\beta}_{OLS}))^2 \\ &= \mathbb E (\beta_{OLS} - \beta)^2\\ &= \mathbb E (\beta + (X^T X)^{-1} X^T \epsilon - \beta)^2\\ &= \mathbb E ((X^T X)^{-1} X^T \epsilon)^2\\ &= \sigma^2 \mathbb E ((X^T X)^{-1} X^T X ((X^T X)^{-1})^T)\\ &= \sigma^2 ((X^T X)^{-1})^T\\ &= \sigma^2 (X^T X)^{-1} \end{aligned} $$
We can use the last expression when we define a confidence interval for the parameters $\boldsymbol{\hat{\beta}_{OLS}}$. A given parameter ${\boldsymbol{\hat{\beta}_{OLS}}}_j$ is given by the diagonal matrix element of the above matrix.
Exercise 2: Expectation values for Ridge regression¶
a) With the expressions for the optimal parameters $\boldsymbol{\hat{\beta}_{Ridge}}$ show that
$$ \mathbb{E} [ \hat{\boldsymbol{\beta}}^{\mathrm{Ridge}} ]=(\mathbf{X}^{T} \mathbf{X} + \lambda \mathbf{I}_{pp})^{-1} (\mathbf{X}^{\top} \mathbf{X})\boldsymbol{\beta} $$
We see that $\mathbb{E} [ \hat{\boldsymbol{\beta}}^{\mathrm{Ridge}} ] \not= \mathbb{E} [\hat{\boldsymbol{\beta}}^{\mathrm{OLS}} ]$ for any $\lambda > 0$.
$$ \mathbb E \hat \beta_\mathrm{Ridge} = \mathbb E \left((X^TX + \lambda I)^{-1} X^T \tilde y\right) + \mathbb E \left((X^T X + \lambda I)^{-1} X^T \epsilon\right) = \mathbb E \left((X^TX + \lambda I)^{-1} X^T \tilde y\right) = (X^TX + \lambda I)^{-1} X^T X \beta $$
b) Show that the variance is
$$ \mathbf{Var}[\hat{\boldsymbol{\beta}}^{\mathrm{Ridge}}]=\sigma^2[ \mathbf{X}^{T} \mathbf{X} + \lambda \mathbf{I} ]^{-1} \mathbf{X}^{T}\mathbf{X} \{ [ \mathbf{X}^{\top} \mathbf{X} + \lambda \mathbf{I} ]^{-1}\}^{T} $$
We see that if the parameter $\lambda$ goes to infinity then the variance of the Ridge parameters $\boldsymbol{\beta}$ goes to zero.
$$ \begin{aligned} \mathrm{Var}(\hat \beta_\mathrm{Ridge}) &= \mathbb E (\hat \beta_\mathrm{Ridge} - \mathbb E \hat \beta_\mathrm{Ridge})^2\\ &= \mathbb E \left[\left((X^TX + \lambda I)^{-1} X^T \tilde y\right) + \left((X^T X + \lambda I)^{-1} X^T \epsilon\right) - (X^TX + \lambda I)^{-1} X^T X \beta \right]^2 \\ &= \mathbb E \left[(X^T X + \lambda I)^{-1} X^T \epsilon\right]^2\\ &= \sigma^2 (X^T X + \lambda I)^{-1} X^T X ((X^T X + \lambda I)^{-1})^T \end{aligned} $$
Exercise 3: Deriving the expression for the Bias-Variance Trade-off¶
The aim of this exercise is to derive the equations for the bias-variance tradeoff to be used in project 1.
The parameters $\boldsymbol{\hat{\beta}_{OLS}}$ are found by optimizing the mean squared error via the so-called cost function
$$ C(\boldsymbol{X},\boldsymbol{\beta}) =\frac{1}{n}\sum_{i=0}^{n-1}(y_i-\tilde{y}_i)^2=\mathbb{E}\left[(\boldsymbol{y}-\boldsymbol{\tilde{y}})^2\right] $$
a) Show that you can rewrite this into an expression which contains
- the variance of the model (the variance term)
- the expected deviation of the mean of the model from the true data (the bias term)
- the variance of the noise
In other words, show that:
$$ \mathbb{E}\left[(\boldsymbol{y}-\boldsymbol{\tilde{y}})^2\right]=\mathrm{Bias}[\tilde{y}]+\mathrm{var}[\tilde{y}]+\sigma^2, $$
with
$$ \mathrm{Bias}[\tilde{y}]=\mathbb{E}\left[\left(\boldsymbol{y}-\mathbb{E}\left[\boldsymbol{\tilde{y}}\right]\right)^2\right], $$
and
$$ \mathrm{var}[\tilde{y}]=\mathbb{E}\left[\left(\tilde{\boldsymbol{y}}-\mathbb{E}\left[\boldsymbol{\tilde{y}}\right]\right)^2\right]=\frac{1}{n}\sum_i(\tilde{y}_i-\mathbb{E}\left[\boldsymbol{\tilde{y}}\right])^2. $$ In order to arrive at the equation for the bias, we have to approximate the unknown function $f$ with the output/target values $y$.
$$ \begin{aligned} \mathbb E[(y-\tilde y)^2] &= \mathbb E[(f+\varepsilon-\tilde y)^2] \\ &= \mathbb E[(f - \mathbb E[\tilde y] + \mathbb E[\tilde y]-\tilde y + \varepsilon)^2] \\ &= \mathbb E[(f - \mathbb E[\tilde y])^2] + \mathbb E[(\tilde y - \mathbb E[\tilde y])^2] + \mathbb E[\varepsilon^2] \\ &\quad + 2\,\mathbb E[(f - \mathbb E[\tilde y])(\mathbb E[\tilde y]-\tilde y)] + 2\,\mathbb E[(f - \mathbb E[\tilde y])\varepsilon] + 2\,\mathbb E[(\mathbb E[\tilde y]-\tilde y)\varepsilon] \\ &= (f - \mathbb E[\tilde y])^2 + \mathrm{Var}(\tilde y) + \sigma^2, \end{aligned} $$
b) Explain what the terms mean and discuss their interpretations.
Bias: Difference between true function and average prediction. Systematic error. High bias = underfitting.
Variance: How much predictions change if we retrain on different data. Sensitivity to training data. High variance = overfitting.
Irreducible noise $\sigma^2$: Random noise in data we can’t model away. Sets the minimum possible error.
Exercise 4: Computing the Bias and Variance¶
Before you compute the bias and variance of a real model for different complexities, let's for now assume that you have sampled predictions and targets for a single model complexity using bootstrap resampling.
a) Using the expression above, compute the mean squared error, bias and variance of the given data. Check that the sum of the bias and variance correctly gives (approximately) the mean squared error.
import numpy as np
n = 100
bootstraps = 1000
predictions = np.random.rand(bootstraps, n) * 10 + 10
targets = np.random.rand(bootstraps, n)
def calculate_key_metrics(y_pred, y_test):
y_pred = np.array(y_pred).T
y_test = np.array(y_test).T
error = np.mean( np.mean((y_test - y_pred)**2, axis=1, keepdims=True) )
bias = np.mean( (y_test - np.mean(y_pred, axis=1, keepdims=True))**2 )
variance = np.mean( np.var(y_pred, axis=1, keepdims=True) )
return error, bias, variance
def print_key_metrics(predictions, targets):
mse, bias, variance = calculate_key_metrics(predictions, targets)
print(f"MSE ({mse:.3f}) = Bias ({bias:.3f}) + Variance ({variance:.3f}) = {bias + variance:.3f}")
print_key_metrics(predictions, targets)
MSE (218.794) = Bias (210.484) + Variance (8.306) = 218.790
b) Change the prediction values in some way to increase the bias while decreasing the variance.
predictions = predictions * 0.5 + 20
print_key_metrics(predictions, targets)
MSE (731.318) = Bias (729.240) + Variance (2.077) = 731.316
c) Change the prediction values in some way to increase the variance while decreasing the bias.
predictions = (predictions - np.mean(predictions, axis=0)) * 20
print_key_metrics(predictions, targets)
MSE (830.999) = Bias (0.332) + Variance (830.621) = 830.954
d) Perform a bias-variance analysis of a polynomial OLS model fit to a one-dimensional function by computing and plotting the bias and variances values as a function of the polynomial degree of your model.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import (
PolynomialFeatures,
) # use the fit_transform method of the created object!
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.utils import resample
n = 40
bootstraps = 20
x = np.linspace(-3, 3, n)
y = np.exp(-(x**2)) + 1.5 * np.exp(-((x - 2) ** 2)) + np.random.normal(0, 0.1, size=n)
biases = []
variances = []
mses = []
p_degrees = list(range(1, 5))
for p in p_degrees:
predictions = np.zeros((bootstraps, int(n*0.2)), dtype=float)
targets = np.zeros((bootstraps, int(n*0.2)), dtype=float)
targets_nf = np.zeros((bootstraps, int(n*0.2)), dtype=float)
X = PolynomialFeatures(degree=p).fit_transform(x.reshape(-1, 1))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
for b in range(bootstraps):
x_sample, y_sample = resample(X_train, y_train)
model = LinearRegression().fit(X_train, y_train)
predictions[b, :] = model.predict(X_test)
targets[b, :] = y_test
#targets_nf[b, :] = y_test
mse, bias, variance = calculate_key_metrics(predictions, targets)
mses.append(mse)
biases.append(bias)
variances.append(variance)
plt.plot(p_degrees, np.array(mses), label="MSE", lw=3)
plt.plot(p_degrees, biases, label="Bias^2", linestyle="dashed", lw=2)
plt.plot(p_degrees, variances, label="Variance", linestyle="dashed", lw=2)
#plt.plot(range(1, 5), np.array(biases) + np.array(variances), label="Bias^2 + Variance", linestyle="dashed")
plt.xlabel("Model Complexity (Polynomial Degree)")
plt.ylabel("Error")
plt.legend()
plt.show()
e) Discuss the bias-variance trade-off as function of your model complexity (the degree of the polynomial).
f) Compute and discuss the bias and variance as function of the number of data points (choose a suitable polynomial degree to show something interesting).
p = 3
biases = []
variances = []
mses = []
p_degrees = list(range(1, 5))
N_values = [10, 20, 40, 80, 160]
for N in N_values:
n = N
x = np.linspace(-3, 3, n)
X = PolynomialFeatures(degree=p).fit_transform(x.reshape(-1, 1))
y = np.exp(-(x**2)) + 1.5 * np.exp(-((x - 2) ** 2)) + np.random.normal(0, 0.1, size=n)
predictions = np.zeros((bootstraps, int(n*0.2)), dtype=float)
targets = np.zeros((bootstraps, int(n*0.2)), dtype=float)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
for b in range(bootstraps):
x_sample, y_sample = resample(X_train, y_train)
model = LinearRegression().fit(X_train, y_train)
predictions[b, :] = model.predict(X_test)
targets[b, :] = y_test
mse, bias, variance = calculate_key_metrics(predictions, targets)
mses.append(mse)
biases.append(bias)
variances.append(variance)
plt.plot(N_values, np.array(mses), label="MSE", lw=3)
plt.plot(N_values, biases, label="Bias^2", linestyle="dashed", lw=2)
plt.plot(N_values, variances, label="Variance", linestyle="dashed", lw=2)
#plt.plot(range(1, 5), np.array(biases) + np.array(variances), label="Bias^2 + Variance", linestyle="dashed")
plt.xlabel("Training Data Size")
plt.ylabel("Error")
plt.legend()
plt.show()
Exercise 5: Interpretation of scaling and metrics¶
In this course, we often ask you to scale data and compute various metrics. Although these practices are "standard" in the field, we will require you to demonstrate an understanding of why you need to scale data and use these metrics. Both so that you can make better arguements about your results, and so that you will hopefully make fewer mistakes.
First, a few reminders: In this course you should always scale the columns of the feature matrix, and sometimes scale the target data, when it is worth the effort. By scaling, we mean subtracting the mean and dividing by the standard deviation, though there are many other ways to scale data. When scaling either the feature matrix or the target data, the intercept becomes a bit harder to implement and understand, so take care.
Briefly answer the following:
a) Why do we scale data?
- You can get a feeling for parameter values
- Similar Hyperparameters are usable over multiple different problem sets
- No Numerical Inaccuracies due to float limitations
- No Bias of Features in regualrized regression (see next questions)
- There's no major disadvantage
b) Why does the OLS method give practically equivelent models on scaled and unscaled data?
c) Why does the Ridge method not give practically equivelent models on scaled and unscaled data? Why do we only consider the model on scaled data correct?
d) Why do we say that the Ridge method gives a biased model?
The expectation value for the ridge parameters only approaches the true value $\beta$ in the limit $\lambda \to 0$, this is why we call it biased. As independent of number of training samples our estimate will always differ from the true value given $\lambda \neq 0$ (in which case it would be OLS). The larger the parameter value (i.e. parameter not equal to zero), the larger our cost value. Even though it may be needed that the paramter is bigger for our targets and predictions to align perfectly. This may be a problem if the goal of our analysis is the closest possible parameter estimates given near infinite number of training samples (because in this case the deviation from the true value approaches 0).
e) Is the MSE of the OLS method affected by scaling of the feature matrix? Is it affected by scaling of the target data?
It is only affected by scaling of the target data. The MSE is in units of $[y]^2$. So if our scaled unit is $[y_{scaled}] = 10[y]$, then our MSE will be scaled by a factor of 100.
f) Read about the R2 score, a metric we will ask you to use a lot later in the course. Is the R2 score of the OLS method affected by scaling of the feature matrix? Is it affected by scaling of the target data?
g) Give interpretations of the following R2 scores: 0, 0.5, 1.
- 0: There is no correlation between the prediction and the target values. The target values can be equally good described by just giving the mean of the values.
- 0.5: Half of the variation in the target values can be explained by the models predictions.
- 1: The prediction perfectly aligns with the target values.
h) What is an advantage of the R2 score over the MSE?
- It is invariant under scaling of the target values
- It has a limited range of values with a particular meaning.