From caef0bb16a0996f123b96cc7ced79323cd8abe3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20Ervel=C3=A4?= <elias.m.ervela@utu.fi>
Date: Wed, 12 Jan 2022 15:29:21 +0000
Subject: [PATCH] Upload New File

---
 ...d_4_-_Model_Validation_and_Selection.ipynb | 2374 +++++++++++++++++
 1 file changed, 2374 insertions(+)
 create mode 100644 Round_4_-_Model_Validation_and_Selection.ipynb

diff --git a/Round_4_-_Model_Validation_and_Selection.ipynb b/Round_4_-_Model_Validation_and_Selection.ipynb
new file mode 100644
index 0000000..6651fa2
--- /dev/null
+++ b/Round_4_-_Model_Validation_and_Selection.ipynb
@@ -0,0 +1,2374 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "be6c282cc6461619571de5d4da247a0b",
+     "grade": false,
+     "grade_id": "cell-97da75c1d52f0687",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "# Machine Learning with Python - Model Validation and Selection\n",
+    "\n",
+    "## Introduction\n",
+    "\n",
+    "In the previous rounds you have implemented supervised machine learning (ML) methods by combining particular choices for\n",
+    "\n",
+    "* data points, their features and labels, \n",
+    "* a hypothesis space (of predictor functions) \n",
+    "* and a loss function that measures the quality of a particular predictor function out of the hypothesis space. \n",
+    "\n",
+    "ML algorithms are optimization methods that try to find (or learn) the best predictor out of the hypothesis space by minimizing the average loss over some labeled data points (the training data). This predictor is then used to predict the labels of new data points."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "f83a72458ea6244135e5607b2bfec005",
+     "grade": false,
+     "grade_id": "cell-85d7ef6fc6ff2a13",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "We begin this round with an example that presents the problem of **overfitting** that is prevalent when fitting complex predictors to data. \n",
+    "\n",
+    "The code snippet below read in some data points $(x^{(i)},y^{(i)})$, for $i=1,2,\\ldots$, which are characterized by a scalar feature $x^{(i)}$ and a numeric label $y^{(i)}$. Note that we consider the datapoint in the last element of $y$ to be an outlier and remove this from the dataset."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "da48e81f302a513fb7598f8adcde13c7",
+     "grade": false,
+     "grade_id": "cell-d1aa568825aa58d9",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Total number of labeled data points =  19\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfIAAAE/CAYAAAC950G6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAdQElEQVR4nO3df5RcdZnn8fdDiKQxSDBpRtMRAx6mdYcfSWgEDKASNDryI6AIKgrrzEbwLCIwEaLLBLPrioazyDirLM6gqAiOGgLIGRNUMgGVH0k6EDDkZBgEu4PQoo1BmjHAs390JSZNd9KV7q5bt/r9Oienq771rbpPvlXJp++tW/VEZiJJksppt6ILkCRJu84glySpxAxySZJKzCCXJKnEDHJJkkrMIJckqcR2L7qAXTFp0qScOnVq0WVIklQTq1at+m1mNvd3WymDfOrUqaxcubLoMiRJqomIeGyg2zy0LklSiRnkkiSVmEEuSVKJlfI9cklqBJs3b6ajo4Pnn3++6FJUJ8aNG8eUKVMYO3bsoO9jkEtSQTo6Othrr72YOnUqEVF0OSpYZvL000/T0dHB/vvvP+j7eWhdkgry/PPPM3HiRENcAEQEEydOrPoIjUEuSQUyxLWtXXk9GOSSNIqNHz9+0HMvu+wyrrjiihF7/Gq2sbPH7e7u5itf+UpV294Vf//3f8+Pf/zjHc5Zvnw5P//5z0eshlH9HvmS9k4WLV3Pxu4eJk9oYt7sVuZMbym6rJpzHSQ1mi1B/vGPf3xEt7Nw4cKdzlm+fDnjx4/nLW95y4jUMGr3yJe0dzJ/8Vo6u3tIoLO7h/mL17KkvbPo0mrKdZDKY0l7JzMv/yn7X3IbMy//6Yj9O7311ls54ogjmD59OscffzxPPvnk1tvuv/9+jjvuOA488EC+9rWvbR1ftGgRhx9+OIcccggLFizo93EHmvO5z32O1tZWjj/+eNavX9/vfR999FGOOuooDj/8cC699NKt488++yyzZs1ixowZHHzwwdx8880AXHLJJTzyyCNMmzaNefPmDTivr/Hjx3PRRRcxY8YMZs2aRVdXFwBr1qzhyCOP5JBDDuGUU07h97//PQBnn3023//+94Hebx1dsGDB1m08/PDD/OpXv+Lqq6/myiuvZNq0adx5551873vf46CDDuLQQw/l2GOP3enzsTOjNsgXLV1Pz+YXtxvr2fwii5b2/yJqVK6DVA61/KX76KOP5u6776a9vZ0zzjiDL37xi1tve+CBB7jtttv4xS9+wcKFC9m4cSPLli1jw4YN3HvvvaxZs4ZVq1axYsWK7R5zoDmrVq3ixhtvpL29ncWLF3Pffff1W9P555/Pueeey3333cdrXvOarePjxo3jpptuYvXq1dxxxx1cdNFFZCaXX345b3jDG1izZg2LFi0acF5ff/zjH5kxYwarV6/mrW99K5/97GcB+MhHPsIXvvAFHnjgAQ4++OCt431NmjSJ1atXc+6553LFFVcwdepUzjnnHC644ALWrFnDMcccw8KFC1m6dCn3338/t9xyS9XPT1+j9tD6xu6eqsYblesglcOOfuke7rfCOjo6OP3003niiSf405/+tN1HoU4++WSamppoamri7W9/O/feey933XUXy5YtY/r06UDvXvKGDRu229tctmxZv3M2bdrEKaecwp577gnASSed1G9NP/vZz/jBD34AwIc//GEuvvhioPcjW5/+9KdZsWIFu+22G52dndsdQdhioHnb/lIAsNtuu3H66acDcOaZZ3LqqafyzDPP0N3dzVvf+lYAzjrrLE477bR+6zz11FMBOOyww1i8eHG/c2bOnMnZZ5/N+9///q3zh2LUBvnkCU109hNWkyc0FVBNcVwHqRxq+Uv3eeedx4UXXshJJ53E8uXLueyyy7be1ves6oggM5k/fz4f+9jHBnzMgeZ86UtfGvSZ2v3Nu/766+nq6mLVqlWMHTuWqVOn9vvxrcHOG8w2d2SPPfYAYMyYMbzwwgv9zrn66qu55557uO2225g2bRpr1qxh4sSJVW1nW6P20Pq82a00jR2z3VjT2DHMm91aUEXFcB2kchjol+uR+KX7mWeeoaWldy//uuuu2+62m2++meeff56nn36a5cuXc/jhhzN79myuvfZann32WQA6Ozt56qmntrvfQHOOPfZYbrrpJnp6eti0aRO33nprvzXNnDmTG2+8EegN5W1r3XfffRk7dix33HEHjz3W2yRsr732YtOmTTud19dLL7209T3v73znOxx99NHsvffe7LPPPtx5550AfOtb39q6dz4YfWt55JFHOOKII1i4cCGTJk3i17/+9aAfqz+jdo98y6Go0X62tusglcO82a3MX7x2u8Prw/FL93PPPceU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\n",
+      "text/plain": [
+       "<Figure size 576x360 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Import libraries\n",
+    "import numpy as np \n",
+    "from sklearn import datasets \n",
+    "import matplotlib.pyplot as plt  \n",
+    "from sklearn.preprocessing import PolynomialFeatures\n",
+    "from sklearn.linear_model import LinearRegression\n",
+    "\n",
+    "# load the toy dataset \"linnerud\" provide by the \"sklearn\" package\n",
+    "linnerud = datasets.load_linnerud()\n",
+    "# read in the exercise parameters (nr. of chinups ..) for each athlete\n",
+    "Exercise = linnerud['data']\n",
+    "# read in the physiological (weight ...) paramters for each athlete\n",
+    "Physio = linnerud['target']\n",
+    "\n",
+    "x = Physio[:-1,0].reshape(-1,1) \n",
+    "# convert Lbs to Kg\n",
+    "x = x*0.453 \n",
+    "# we use number of chinups as label and store them (for all athletes) in numpy array y\n",
+    "y = Exercise[:-1,0] \n",
+    "\n",
+    "m_total = y.shape[0]  # Number of datapoints in the dataset\n",
+    "print (\"Total number of labeled data points = \", m_total)\n",
+    "\n",
+    "# Plot a scatterplot of the dataset\n",
+    "plt.figure(figsize=(8, 5))\n",
+    "plt.scatter(x, y,label=\"Labeled data points\")\n",
+    "plt.ylabel('label ' + r'$y$')\n",
+    "plt.xlabel('feature ' + r'$x$')\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "c0502a64f3bb61ec416e11de112907bb",
+     "grade": false,
+     "grade_id": "cell-8fd784a728ac00b0",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "Next, we choose four data points as our **training set** in this example. The training set is the set on which we will fit the models. The rest of the data will be used to assess how well the model fitted on the training set predicts the values of data points that are not used in training. Conventionally, this set is called the **validation set**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "92900b59164e8fc363b7047b9547e05f",
+     "grade": false,
+     "grade_id": "cell-2601ad49c9617b02",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfIAAAE/CAYAAAC950G6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3de3hddZ33/feXNtAUy5Qp5X5oObTVGpm20kKKIHIsUBDUwgADA0oBKVABHbQK6nBSbpip1+08dUQHlZN04AIshQeEIieRmyK2TaFFGhkUatMOlGoYkBTT8nv+yE5o0px2k+yVtfN+XRdXdtZeh2/WTvlkrfVb6xspJSRJUj5tl3UBkiRp2xnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5djgrAvYFrvssksaM2ZM1mVIklQSS5cufSOlNLK993IZ5GPGjGHJkiVZlyFJUklExKsdveepdUmScswglyQpxwxySZJyLJfXyCWpnDQ2NrJmzRo2btyYdSnK2JAhQ9h9992pqKjo9jIGuSRlbM2aNQwbNowxY8YQEVmXo4yklNiwYQNr1qxh7Nix3V7OU+uSlLGNGzcyYsQIQ3yAiwhGjBhR9JkZg1yS+gFDXLBtvwcGuSSJD3zgA52+/8orrzBx4sSi1jlz5kzuvvvubs/f3W10Z70333wza9eu7fa2t8WSJUu4+OKLO52nvr6e66+/vk/rGNDXyBfW1DF3US1r6xsYNbySOdOrmDFldNZllZz7QVK5ufnmm5k4cSKjRo3qs21UV1dTXV3d6TzNQT579uw+q2PAHpEvrKnjsgUrqKtvIAF19Q1ctmAFC2vqsi6tpNwPUv4srKnjoOseY+ylD3DQdY/16r/Xt99+m2nTprHvvvsyadIk7r333pb3Nm3axJlnnslHP/pRTjrpJN555x0Ali5dyqGHHsp+++3H9OnTWbdu3Vbr7WiepUuXss8++3DggQfy/e9/v92aUkpceOGF/N3f/R3HHXccr7/+est7V199NVOnTmXixInMmjWLlBJ33303S5Ys4fTTT2fy5Mk0NDS0O19bM2fO5Pzzz+fggw/mwx/+MPfffz/QNIbhrLPOYtKkSUyZMoXHH38cgCeeeILjjz8egCuvvJKzzz6bww47jHHjxjFv3jwALr30Ul5++WUmT57MnDlzWLduHYcccgiTJ09m4sSJ/OpXvyr6M2prwAb53EW1NDRubjWtoXEzcxfVZlRRNtwPUr709R/fQ4YM4Z577mHZsmU8/vjjfPnLX24JvdraWmbNmsXzzz/PTjvtxPXXX09jYyMXXXQRd999N0uXLuXss8/mG9/4Rqt1djbPWWedxbx581i8eHGHNd1zzz3U1tayYsUKfvSjH/H000+3vHfhhRfym9/8hpUrV9LQ0MD999/PSSedRHV1NfPnz2f58uVUVla2O197XnnlFX75y1/ywAMPcP7557Nx48aWPzBWrFjB7bffzplnntnugLRVq1axaNEinn32Wa666ioaGxu57rrr+OAHP8jy5cuZO3cu//mf/8n06dNZvnw5zz33HJMnTy7uA2rHgD21vra+oajp5cr9IOVLZ39898YlsZQSX//613nyySfZbrvtqKur47XXXgNgjz324KCDDgLgjDPOYN68eRxzzDGsXLmSo446CoDNmzez2267tVpnbW1tu/O8+eab1NfXc+ihhwLw2c9+lgcffHCrmp588klOO+00Bg0axKhRozjiiCNa3nv88cf513/9V9555x3+9Kc/MWHCBD71qU9ttY7uznfKKaew3XbbMX78eMaNG8eqVat46qmnuOiiiwD4yEc+wl577cXvfve7rZY97rjj2GGHHdhhhx3YddddW/bblqZOncrZZ59NY2MjM2bMMMh7YtTwSuraCatRwyszqCY77gcpX/r6j+/58+ezfv16li5dSkVFBWPGjGk5+mw7ojoiSCkxYcKETo+oO5qnvr6+26O025tv48aNzJ49myVLlrDHHntw5ZVXtnuk3N352ttO88/YHTvssEPL60GDBrFp06at5jnkkEN48skneeCBB/jsZz/LnDlz+NznPtet9XdkwJ5anzO9isqKQa2mVVYMYs70qowqyob7QcqXjv7I7q0/vt9880123XVXKioqePzxx3n11febbq1evboljG+//XY+8YlPUFVVxfr161umNzY28sILL7RaZ0fzDB8+nL/5m7/hqaeeApr+iGjPIYccwh133MHmzZtZt25dyzXq5jDeZZddePvtt1uNZB82bBhvvfVWl/O1ddddd/Hee+/x8ssv8/vf/56qqioOOeSQltp+97vfsXr1aqqquvf/yC3rAHj11VfZddddOffccznnnHNYtmxZt9bTmQF7RN58Cmqgj9Z2P0j5Mmd6FZctWNHq9Hpv/vF9+umn86lPfYrq6momT57MRz7ykZb39t57b2655RbOO+88xo8fzwUXXMD222/P3XffzcUXX8ybb77Jpk2b+NKXvsSECRNalutsnptuuomzzz6boUOHMn369HZrOuGEE3jssceYNGkSH/7wh1tOxQ8fPpxzzz2XSZMmMWbMGKZOndqyTPPAtcrKShYvXtzhfG1VVVVx6KGH8tprr/HDH/6QIUOGMHv2bM4//3wmTZrE4MGDufnmm1sdfXdmxIgRHHTQQUycOJFjjz2WiRMnMnfuXCoqKvjABz7Arbfe2q31dCa6e8qgP6murk72I5dULl588UX23nvvbs/vLaN9Y+bMmRx//PGcdNJJmdbR3u9DRCxNKbV7r9uAPSKXpLyaMWW0wa0WBrkkSTQ9RCaPBuxgN0nKlXXPwx+KfHhI7UOw4eW+qUf9hkEuSf3d2hq46ViYfzLUbn2fdbuW3gJ3fg5+PM0wL3MGuST1Z5sb4ebj4a9vw6YGuOusrsN86S3w4Ndg87vQUA+3bP3gE5UPg1yS+rNBFXDgF6CicJ94V2HeHOKbCg+IGTwEDr6kNLUqEyUL8oi4MSJej4iVbaZfFBG1EfFCRPxrqeqRpNw4/Otw4IVdh/lWIV4J078NUz/f6ep70mrzk5/8JPX19Z3Oc/nll/PII49s0/p7YuHChfz2t78t+XZLrZRH5DcDx2w5ISIOBz4DfDSlNAH4TgnrkaT8OOKbcMDsjsO8vRA/+ltdhjh0HuSbN29ud3qzn//85wwfPrzTea6++mqOPPLILuvobQZ5L0spPQn8qc3kC4DrUkrvFuZ5fasFJUlNpl0OH7tg6zB/4CvthPjVsP+53Vpt21abTzzxBIcffjj/+I//yKRJkwCYMWMG++23HxMmTOCGG25oWXbMmDG88cYbvPLKK+y9996ce+65TJgwgaOPPpqGhqZ6Zs6c2fJY1DFjxnDFFVe0tEldtWoVAOvXr+eoo45i33335bzzzmOvvfbijTfeaFXn5s2bmTlzJhMnTmTSpEl897vfBeDll1/mmGOOYb/99uPggw9m1apVPP3009x3333MmTOHyZMn8/LL5TvgL+tr5B8GDo6IX0fELyOi4+fmSZKawnz/81qHec1PW4f4UVfB/rO6vcq2rTYBnn32Wa655pqWI9obb7yRpUuXsmTJEubNm8eGDRu2Ws9LL73EF77whZbnqP/sZz9rd3u77LILy5Yt44ILLuA732k6EXvVVVdxxBFHsGzZMk444QRWr1691XLLly+nrq6OlStXsmLFCs466ywAZs2axfe+9z2WLl3Kd77zHWbPns3HP/5xPv3pTzN37lyWL1/OBz/4wW7vj7zJ+oEwg4GdgQOAqcCdETEutfPc2IiYBcwC2HPPPUtapCT1GxFw5JWQ3oPf/Bga34FNhU5egyub3vvYeT3ezP7778/YsWNbvp83bx733HMPAH/84x956aWXGDFiRKtlxo4d29KWc7/99uOVV15pd90nnnhiyzwLFiwA4KmnnmpZ/zHHHMPOO++81XLjxo3j97//PRdddBHHHXccRx99NG+//TZPP/00J598cst877777jb+1PmUdZCvARYUgvvZiHgP2AVY33bGlNINwA3Q9Kz1klYpSf1JBIz4UFOYt5Jg5716ZRM77rhjy+snnniCRx55hMWLFzN06FAOO+ywdtuAtm3j2XxqvaP5tmz12Z2+HzvvvDPPPfccixYt4vvf/z533nkn//Zv/8bw4cNZvnx5UT9fOcn61PpC4AiAiPgwsD3wRqdLSNJA1zKwrRCm21U0fd20sXv3mbfRttVmW2+++SY777wzQ4cOZdWqVTzzzDPbWnmHPvGJT3DnnXcC8PDDD/PnP/95q3neeOMN3nvvPf7+7/+eb33rWyxbtoyddtqJsWPHctdddwFNfxA899xz3fq5ykUpbz+7HVgMVEXEmog4B7gRGFe4Je0O4Mz2TqtLkgqW3br1wLZxh3b/PvN2bNlqc86cOVu9f8wxx7Bp0yY++tGP8s///M8ccMABvfGTtHLFFVfw8MMPs++++/Lggw+y2267MWzYsFbz1NXVcdhhhzF58mRmzpzJtddeCzT1Mf/JT37CPvvsw4QJE7j33nsBOPXUU5k7dy5Tpkwp68FutjGVpIx1u43pslvh519tc5/4NTD1HHj0anjmemjc4r2Tb4KqY/uu8F707rvvMmjQIAYPHszixYu54IILBuzpctuYSlI5qrkNfj6n9cC25hCHptHs8H6YNx+Z5yTMV69ezSmnnMJ7773H9ttvz49+9KOsS8oNg7w9656HjW/C2IO7v0ztQ7DLeBhRvrc4SMpIzW1N94p3FOLNchzm48ePp6amJusycinrwW79j12GJPUnmxvh/kvaP53enmmXb/0EuPsuKk2tyoRBviW7DEnKSIfjlQZVwKnzmwJ88JDOQ7xZc5gPHgIVO8Jpd/R+weoT2zJuzVPrW2ruMvT0vO6dlrLLkKReMGTIEDZs2MCIESOIiK1nGH9UU5j/ZQPsc0r3Vjrtchi2G4yaAru3O0ZK/UxKiQ0bNjBkyJCilnPUense+zYs/vfOR39uY5chSWqrsbGRNWvWtPuQFQ0sQ4YMYffdd6eioqLVdEetF+uIbzY9MamjASM96DIkSW1VVFS0ehyqVAyDvCPTLoeU4Nc/aB3mU85oGkG6jV2G9L6FNXXMXVTL2voGRg2vZM70KmZMGZ11WZKUKwZ5Z6Zd3nRk/ux/vB/mNT9tfQtIkV2G1GRhTR2XLVhBQ2NTr+O6+gYuW7ACwDCXpCI4ar0zzV2Gpp4LFUObpvVBl6GBaO6i2pYQb9bQuJm5i2ozqkiS8skg70oJugwNRGvr2++K1NF0SVL7DPKu9HKXITUZNbyyqOmSpPYZ5J3pgy5DajJnehWVFYNaTausGMSc6VUZVSRJ+WSQd6SjLkNn/Gzrxx8a5kWbMWU01544idHDKwlg9PBKrj1xkgPdJKlIPhCmPTW3wQNf7rxBQc5bBkqS8qOzB8J4RN5WMV2GPDKXJGXMIN+SXYYkSTljkG/JLkOSpJzxyW5t2WVIkpQjBnl7PjSt+GV81rokKQOeWpckKccMckmScqxkQR4RN0bE6xGxsp33vhIRKSJ2KVU9kiSVg1JeI78Z+Hfg1i0nRsQewFHA6hLWAtgPW5KUfyU7Ik8pPQn8qZ23vgt8FSjpI+aa+2HX1TeQeL8f9sKaulKWIUlSj2R6jTwiPg3UpZSeK/W27YctSSoHmd1+FhFDgW8AR3dz/lnALIA999yzx9u3H7YkqRxkeUT+QWAs8FxEvALsDiyLiP+nvZlTSjeklKpTStUjR47s8cbthy1JKgeZBXlKaUVKadeU0piU0hhgDbBvSum/S7F9+2FLkspBKW8/ux1YDFRFxJqI6OIh5n3LftiSpHJgP3JJkvo5+5FLklSmDHJJknLMIJckKccMckmScswglyQpxwxySZJyzCCXJCnHMnvWuvqGrVn7Fz8PSX3NIC8jza1Zm7u6NbdmBQyPDPh5SCoFT62XEVuz9i9+HpJKwSAvI7Zm7V/8PCSVgkFeRmzN2r/4eUgqBYO8jNiatX/x85BUCg52KyPNA6gcJd0/+HlIKgXbmEqS1M/ZxlSSpDJlkEuSlGMGuaTirXse/vCr4papfQg2vNw39UgDmEEuqThra+CmY2H+yVD7YPeWWXoL3Pk5+PE0w1zqZQa5pO7b3Ag3Hw9/fRs2NcBdZ3Ud5ktvgQe/BpvfhYZ6uOVTpalVGiAMckndN6gCDvwCVBQeatNVmDeH+KbC0+wGD4GDLylNrdIAYZBLKs7hX4cDL+w6zLcK8UqY/m2Y+vnS1iuVuZIFeUTcGBGvR8TKLabNjYhVEfF8RNwTEcNLVY+kHjjim3DA7I7DvL0QP/pbhrjUB0r2QJiIOAR4G7g1pTSxMO1o4LGU0qaI+BeAlNLXulpXOT4Qxr7V6ki//t145Cr49Q+gcYvAnnIG1NzWJsSvhv1nZVenlHOdPRCmZI9oTSk9GRFj2kx7eItvnwFOKlU9/Yl9q9WRfv+7Me1ySO/Bs//RFOabGqDmp7BpY9P7gyvhqKsMcakP9adr5GcD3byXpbzYt1od6fe/GxFw5JUw9VyoGNo0bcsQP/JK+Nh52dQmDRD9Isgj4hvAJmB+J/PMioglEbFk/fr1pSuuBOxbrY7k4ncjAkZ8qOnIvJUEO++VSUnSQJJ5kEfEmcDxwOmpkwv2KaUbUkrVKaXqkSNHlq7AErBvtTqSi9+NloFthSPx7Sqavm7a2L37zCX1SKZBHhHHAF8DPp1SeifLWrJk32p1pN//biy7devR6eMO7f595pJ6rJS3n90OLAaqImJNRJwD/DswDPhFRCyPiB+Wqp7+ZMaU0Vx74iRGD68kgNHDK7n2xEn9YzCTMtWvfzeW3Qo//2qb+8SvgTN+1vmtaZJ6lf3IJRWv5jZ44MutB7ZNvwamnvP+PI9eDc9c3/rWtJNvgqpjS1+vlHP2I5fUe2pugwe+0nmIQ9OtaR6ZS33OIO8OWzZKTTY3wv2XbH06vW2IN2svzO+7qDS1SgOEQd4VWzZK7xtUAafObwrwwUM6D/FmzWE+eAhU7Ain3VGaWqUBwmvkndncCP8ypqllI3TvGl+rZ0wH7DQKLvlt39cqldJ/PQp/2QD7nNL9ZZ79EYyaAru3e5lPUie8Rr6tbNkote9D04oLcYD9zzXEpT5gkHfFlo2SpH7MIO8OWzZKkvqpknU/y71pl0NK77dsbA7zDls2npttvZKkAcEj8mJMuxz2P6/1kXnNT1uHuC0bJUklZJAXw5aNkqR+xiAvli0bJUn9iEFeLFs2SpL6EYO8GLZslCT1MwZ5d9myUZLUDxnk3VFzG/x8TseNIuzyJEnKiEHeFVs2SpL6MYO8M7ZslCT1cwZ5Z2zZKEnq53xEa1fGH9UU5sW0bJx2OQzbzZaNkqQ+Z5B3x4emFb+Mz1qXJJWAp9YlScoxg1ySpBwrWZBHxI0R8XpErNxi2t9GxC8i4qXC151LVY8kSeWglEfkNwPHtJl2KfBoSmk88Gjhe0mS1E0lC/KU0pPAn9pM/gxwS+H1LcCMUtUjSVI5yPoa+f9KKa0DKHzdtaMZI2JWRCyJiCXr168vWYGSJPVn3Q7yiHgkIvbpy2I6k1K6IaVUnVKqHjlyZFZlSJLUrxRzRP5V4LsRcVNE7NZL23+teV2Fr6/30nolSRoQuh3kKaVlKaUjgPuBhyLiioio7OH27wPOLLw+E7i3h+uTJGlAKeoaeUQEUAv8ALgIeCkiPtvNZW8HFgNVEbEmIs4BrgOOioiXgKMK30uSpG7q9iNaI+IpYBzwAvAMMBNYBXwxIg5OKc3qbPmU0mkdvLUNzz+VJElQ3LPWzwdeSCmlNtMviogXe7EmSZLUTd0O8pTSyk7ePq4XapEkSUXqlfvIU0q/7431SJKk4mT9QBhJktQDBrkkSTnW5TXyiHgLaB7gFoWvqfA6pZR26qPaJElSF7oM8pTSsFIUIkmSilfMs9YjIs6IiH8ufL9HROzfd6VJkqSuFHON/HrgQOAfC9+/DXy/1yuSJEndVswDYT6WUto3ImoAUkp/jojt+6guSZLUDcUckTdGxCAKA98iYiTwXp9UJUmSuqWYIJ8H3APsGhHXAE8B/7tPqpIkSd1SzCNa50fEUpqanAQwI6XkM9YlScpQMdfISSmtoqnjmSRJ6geKaWM6BJgNfIKm6+RPAT9IKW3so9okSVIXijkivxV4C/he4fvTgJ8CJ/d2UZIkqXuKCfKqlNI+W3z/eEQ819sFSZKk7itm1HpNRBzQ/E1EfAz4v71fkiRJ6q7uNE1ZQdM18QrgcxGxuvDWnsBv+7A2SZLUhe6cWj++z6uQJEnbpDvdz15tfh0ROwPjgSFbzPLqVgtJkqSSKOb2s88DXwR2B5YDBwCLgSP6pjRJktSVYga7fRGYCryaUjocmAKs740iIuKfIuKFiFgZEbcX7lmXpB5ZWFPHQdc9xthLH+Cg6x5jYU1d1iVJva6YIN/Y/PCXiNih8JS3qp4WEBGjgYuB6pTSRGAQcGpP1ytpYFtYU8dlC1ZQV99AAurqG7hswQrDXGWnmCBfExHDgYXAIxFxL7C2l+oYDFRGxGBgaC+uV9IANXdRLQ2Nm1tNa2jczNxFtRlVJPWNYpqmnFB4eWVEPA7sBDzU0wJSSnUR8R1gNdAAPJxSerjtfBExC5gFsOeee/Z0s5LK3Nr6hqKmS3nV5RF5RLwVEf+z5X/A/wf8J7ChpwUURsJ/BhgLjAJ2jIgz2s6XUrohpVSdUqoeOXJkTzcrqcyNGl5Z1HQpr7oM8pTSsJTSTu38NyyltFMv1HAk8IeU0vqUUiOwAPh4L6xX0gA2Z3oVlRWDWk2rrBjEnOk9Htoj9StFtTHtI6uBAyJiKE2n1qcBS7ItSVLezZgyGmi6Vr62voFRwyuZM72qZbpULjIP8pTSryPibmAZsAmoAW7ItipJ5WDGlNEGt8pe5kEOkFK6Argi6zokScqbYm4/kyRJ/YxBLklSjhnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5ZhBLklSjhnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5ZhBLklSjhnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5ZhBLklSjhnkkiTlWL8I8ogYHhF3R8SqiHgxIg7MuiZJkvJgcNYFFPy/wEMppZMiYntgaNYFlYuFNXXMXVTL2voGRg2vZM70KmZMGZ11WSqCn6GkzmQe5BGxE3AIMBMgpfRX4K9Z1lQuFtbUcdmCFTQ0bgagrr6ByxasADAIcsLPUFJX+sOp9XHAeuCmiKiJiB9HxI5ZF1UO5i6qbQmAZg2Nm5m7qDajilQsP0NJXekPQT4Y2Bf4QUppCvAX4NK2M0XErIhYEhFL1q9fX+oac2ltfUNR09X/+BlK6kp/CPI1wJqU0q8L399NU7C3klK6IaVUnVKqHjlyZEkLzKtRwyuLmq7+x89QUlcyD/KU0n8Df4yIqsKkacBvMyypbMyZXkVlxaBW0yorBjFnelUHS6i/8TOU1JXMB7sVXATML4xY/z1wVsb1lIXmwVCOeM4vP0NJXYmUUtY1FK26ujotWbIk6zIkSSqJiFiaUqpu773MT61LkqRtZ5BLkpRjBrkkSTlmkEuSlGMGuSRJOWaQS5KUYwa5JEk5ZpBLkpRj/eXJbtKAZb9xST1hkEsZst+4pJ7y1LqUIfuNS+opg1zKkP3GJfWUQS5lyH7jknrKIJcyZL9xST3lYDcpQ/Ybl9RTBrmUsRlTRhvckraZp9YlScoxg1ylte55+MOvilum9iHY8HLf1CNJOWeQq3TW1sBNx8L8k6H2we4ts/QWuPNz8ONphrkktcMgV2lsboSbj4e/vg2bGuCus7oO86W3wINfg83vQkM93PKp0tQqSTlikKs0BlXAgV+AisL90V2FeXOIbyo8GGXwEDj4ktLUKkk5YpCrdA7/Ohx4YddhvlWIV8L0b8PUz5e2XknKgX4T5BExKCJqIuL+rGtRHzrim3DA7I7DvL0QP/pbhrgkdaA/3Uf+ReBFYKesC1Efm3Y5pAS//gE0Nrwf5lPOgJrb2oT41bD/uT3anG1CJZWzfnFEHhG7A8cBP866FpXItMth//NaH5nX/LR1iB91Few/q0ebaW4TWlffQOL9NqELa+p6Vr8k9RP9IsiBfwO+CryXdSEqkQg48kqYei5UDG2atmlj09fBlU3vfey8Hm/GNqGSyl3mQR4RxwOvp5SWdjHfrIhYEhFL1q9fX6Lq1KciYMSHILX9+y3Bznv1yiZsEyqp3GUe5MBBwKcj4hXgDuCIiLit7UwppRtSStUppeqRI0eWukb1hZaBbYUj8e0qmr5u2ti9+8y7wTahkspd5kGeUrospbR7SmkMcCrwWErpjIzLUl9bduvWo9PHHdr9+8y7yTahkspd5kGuAWjZrfDzr7a5T/waOONnnd+atg1mTBnNtSdOYvTwSgIYPbySa0+c5Kh1SWUjUkpZ11C06urqtGTJkqzL0LaouQ0e+HLrgW3Tr4Gp57w/z6NXwzPXN92a1jzPyTdB1bGlr1eS+oGIWJpSqm7vPY/IVTo1t8EDX+k8xKHp1rRePjKXpHJlkKs0NjfC/ZdsfTq9bYg3ay/M77uoNLVKUo4Y5CqNQRVw6vymAB88pPMQb9Yc5oOHQMWOcNodpalVknKkPz2iVeVu/FFNYf6XDbDPKd1bZtrlMGw3GDUFdm/38pAkDWgGuUrrQ9OKX6aHz1qXpHLmqXVJknLMIJckKccMckmScswglyQpxwxySZJyzCCXJCnHDHJJknLMIJckKccMckmScswglyQpxwxySZJyzCCXJCnHDHJJknLMIJckKccMckmScswglyQpxwxySZJyLPMgj4g9IuLxiHgxIl6IiC9mXZMkSXkxOOsCgE3Al1NKyyJiGLA0In6RUvpt1oVJPbWwpo65i2pZW9/AqOGVzJlexYwpo7MuS1IZyTzIU0rrgHWF129FxIvAaMAgV64trKnjsgUraGjcDEBdfQOXLVgBYJhL6jWZn1rfUkSMAaYAv862Eqnn5i6qbQnxZg2Nm5m7qDajiiSVo34T5BHxAeBnwJdSSv/TzvuzImJJRCxZv3596QuUirS2vqGo6SOCXGQAAAa0SURBVJK0LfpFkEdEBU0hPj+ltKC9eVJKN6SUqlNK1SNHjixtgdI2GDW8sqjpkrQtMg/yiAjgJ8CLKaX/k3U9Um+ZM72KyopBraZVVgxizvSqjCqSVI4yD3LgIOCzwBERsbzw3yezLkrqqRlTRnPtiZMYPbySAEYPr+TaEyc50E1Sr+oPo9afAiLrOqS+MGPKaINbUp/qD0fkkiRpGxnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5ZhBLklSjmV+H7kkSeUii9bFBrkkSb0gq9bFnlqXJKkXZNW62CCXJKkXZNW62CCXJKkXZNW62CCXJKkXZNW62MFukiT1guYBbY5alyQpp7JoXeypdUmScswglyQpxwxySZJyzCCXJCnHDHJJknLMIJckKccMckmScswglyQpxyKllHUNRYuI9cCrfbT6XYA3+mjd6pr7P1vu/2y5/7PXXz+DvVJKI9t7I5dB3pciYklKqTrrOgYq93+23P/Zcv9nL4+fgafWJUnKMYNckqQcM8i3dkPWBQxw7v9suf+z5f7PXu4+A6+RS5KUYx6RS5KUYwM2yCOiKiKWb/Hf/0TElyLibyPiFxHxUuHrzlnXWq4i4p8i4oWIWBkRt0fEEPd/6UTEFwv7/oWI+FJhmvu/D0XEjRHxekSs3GJah/s8Ii6LiP+KiNqImJ5N1eWjg/1/cuHfwHsRUd1m/lzs/wEb5Cml2pTS5JTSZGA/4B3gHuBS4NGU0njg0cL36mURMRq4GKhOKU0EBgGn4v4viYiYCJwL7A/sAxwfEeNx//e1m4Fj2kxrd59HxN/R9G9iQmGZ6yNiUOlKLUs3s/X+XwmcCDy55cQ87f8BG+RtTANeTim9CnwGuKUw/RZgRmZVlb/BQGVEDAaGAmtx/5fK3sAzKaV3UkqbgF8CJ+D+71MppSeBP7WZ3NE+/wxwR0rp3ZTSH4D/oukPL22j9vZ/SunFlFJtO7PnZv8b5E1OBW4vvP5fKaV1AIWvu2ZWVRlLKdUB3wFWA+uAN1NKD+P+L5WVwCERMSIihgKfBPbA/Z+Fjvb5aOCPW8y3pjBNpZGb/T/ggzwitgc+DdyVdS0DSeE64GeAscAoYMeIOCPbqgaOlNKLwL8AvwAeAp4DNmValNqKdqZ5m1Hp5Gb/D/ggB44FlqWUXit8/1pE7AZQ+Pp6ZpWVtyOBP6SU1qeUGoEFwMdx/5dMSuknKaV9U0qH0HS68SXc/1noaJ+voeksSbPdabr8pNLIzf43yOE03j+tDnAfcGbh9ZnAvSWvaGBYDRwQEUMjImgap/Ai7v+SiYhdC1/3pGmwz+24/7PQ0T6/Dzg1InaIiLHAeODZDOobqHKz/wf0A2EK1wb/CIxLKb1ZmDYCuBPYk6awOTml1HZwinpBRFwF/ANNp3RrgM8DH8D9XxIR8StgBNAIXJJSetTf/74VEbcDh9HUYes14ApgIR3s84j4BnA2Tf9GvpRSejCDsstGB/v/T8D3gJFAPbA8pTS9MH8u9v+ADnJJkvLOU+uSJOWYQS5JUo4Z5JIk5ZhBLklSjhnkkiTlmEEuSVKOGeSSJOWYQS6VoYi4OCJejIj5RS43PCJm91VdknqfD4SRylBErAKOLbRfLGa5McD9hR7xxSwXNP3/5L1ilpPUcx6RS2UmIn4IjAPui4h/iogzIuLZiFgeEf8REYMK8y2MiKUR8UJEzCosfh3wwcK8cyNiTESs3GLdX4mIKwuvxxSO+q8HlgF7dLStNvU9HhFHFV5/OyLm9ekOkcqcQS6VmZTS+TR1aTqcphal/wAclFKaDGwGTi/MenZKaT+gGri48Jz1S4GXU0qTU0pzurG5KuDWlNIUYGgn29rSFcA3IuJ0YArwT9v4o0oCBmddgKQ+NQ3YD/hN09lvKnm/TebFEXFC4fUeNHV3+u8i1/9qSumZbmyrRUrpycKp+EuAw1JKm4vcpqQtGORSeQvglpTSZa0mRhxGU0/4A1NK70TEE8CQdpbfROszd23n+UtX29qqoIhJwG7AGymlt7rzQ0jqmKfWpfL2KHDSFr3H/zYi9gL+BvhzIcQ/AhxQmP8tYNgWy78G7BoRIyJiB+D4bdhWi4jYDZgPfAb4S0RM7/mPKA1sBrlUxlJKvwW+CTwcEc8Dv6DpaPghYHBh2reAZwrzbwD+b0SsjIi5KaVG4Grg18D9wKpt2BYAETEUWAB8OaX0YmG7V/buTywNPN5+JklSjnlELklSjhnkkiTlmEEuSVKOGeSSJOWYQS5JUo4Z5JIk5ZhBLklSjhnkkiTl2P8P681XN4okKp8AAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<Figure size 576x360 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Choose the datapoints in the 4 final elements as the training set\n",
+    "x_train = x[m_total-4:]\n",
+    "y_train = y[m_total-4:]\n",
+    "\n",
+    "# Let the rest be the validation set\n",
+    "x_val = x[:m_total-4]\n",
+    "y_val = y[:m_total-4]\n",
+    "\n",
+    "# Plot the points not in the training set and the points in the training set\n",
+    "plt.figure(figsize=(8, 5))\n",
+    "plt.scatter(x_val, y_val, label=\"labeled data points\")\n",
+    "plt.scatter(x_train, y_train, s=400, marker=r'$\\times$', label=\"training set\")\n",
+    "plt.ylabel('label ' + r'$y$')\n",
+    "plt.xlabel('feature ' + r'$x$')\n",
+    "plt.legend(loc='upper right')\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "f84cf7057a2a6989b0fac3b6dc593d6d",
+     "grade": false,
+     "grade_id": "cell-46af00bfd04c2706",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "Next, we will compare the fit of two polynomial predictors of different degree on the training set and analyze how well the optimal predictors generalize to the validation set.\n",
+    "\n",
+    "Using the four data points (marked by crosses in the above plot) in the training set, we learn (find) the best predictors out of the hypothesis spaces\n",
+    "\n",
+    "$$ \\mathcal{H}^{(4)} = \\{ h(x) = w_{0}+w_{1}x+w_{2}x^2+w_{3}x^3+w_{4}x^{4} \\mbox{ with tunable weights } w_{0},\\ldots,w_{4} \\in \\mathbb{R} \\}.$$\n",
+    "\n",
+    "and\n",
+    "\n",
+    "$$ \\mathcal{H}^{(1)} = \\{ h(x) = w_{0}+w_{1}x \\mbox{ with tunable weights } w_{0},w_1 \\in \\mathbb{R} \\}.$$\n",
+    "\n",
+    "That is, we fit a fourth degree polynomial regression model and a linear regression model to the training data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "306357c29f50871d4eccfc7cf6dcdb63",
+     "grade": false,
+     "grade_id": "cell-7be1c2de8fb89d1c",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 576x360 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# choose best predictor out of the hypothesis space given by all \n",
+    "# polynomials h(x) = w_0 + w_1*x ... + w_4*x^4 of maximum degree 4 \n",
+    "poly = PolynomialFeatures(degree = 4) \n",
+    "# transform scalar feature x to a feature vector [x^0 x^1 ... x^4]\n",
+    "X_poly = poly.fit_transform(x_train) \n",
+    "# we can now use linear regression using the transformed feature vectors \n",
+    "poly_reg = LinearRegression() \n",
+    "# compute optimal weights to minimize training error \n",
+    "poly_reg.fit(X_poly, y_train) \n",
+    "\n",
+    "lin_reg = LinearRegression()\n",
+    "lin_reg.fit(x_train, y_train)\n",
+    "\n",
+    "# Plot the resulting \"optimal\" predictor (having minimum training error) \n",
+    "x_grid = np.linspace(69, 93, num=100)\n",
+    "x_grid_2 = np.linspace(69, 113, num=100)\n",
+    "X_poly = poly.fit_transform(x_grid.reshape(-1,1))\n",
+    "\n",
+    "# Plot the dataset and predictor functions\n",
+    "plt.figure(figsize=(8,5))\n",
+    "plt.scatter(x_val, y_val,label=\"validation set\")\n",
+    "plt.scatter(x_train, y_train, s=400,marker=r'$\\times$', label=\"training set\")\n",
+    "plt.plot(x_grid, poly_reg.predict(X_poly), color = 'red', label=\"$r=4$\")\n",
+    "plt.plot(x_grid_2, lin_reg.predict(x_grid.reshape(-1,1)), color = 'green', label=\"$r=1$\")\n",
+    "plt.ylabel('label ' + r'$y$')\n",
+    "plt.xlabel('feature ' + r'$x$')\n",
+    "plt.legend(loc='upper right')\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "b5f69ce2cd9f59d087b10217be95e67e",
+     "grade": false,
+     "grade_id": "cell-b5608ed9b712d8e5",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "The above figure shows that the 4th degree polynomial (the red curve) fits the training data (orange crosses) almost perfectly. The average means-squared error incurred on the four training data points is essentially zero. However, it is quite clear that the polynomial fits the data outside of the training set very poorly.\n",
+    "\n",
+    "In contrast, the linear predictor provides a reasonable linear trend for the entire dataset, even though the fit on the training set is worse than that of the 4th degree polynomial.\n",
+    "\n",
+    "The phenomenon where a predictor has a very low error on the training set but generalizes poorly to other data from the same distribution is called **overfitting**. Thus, we can conclude that the 4th degree polynomial predictor **overfits** the training data. Due to the possibility of overfitting, we cannot be confident in that a predictor that fits the training data well is able to accurately predict the labels of new data points.\n",
+    "\n",
+    "The key idea of **validation** is to estimate the error of a predictor on data points that were not used for training the model. The validation error exposes models that overfit the training data, and thus it gives a more realistic estimate of the predictive capability of a model on new data points, in comparison to the training error. In the above figure, we could use the prediction error incurred for the data points marked by blue dots to validate the predictor functions. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "7fc7a30c37ca8db1440e930ae7a81470",
+     "grade": false,
+     "grade_id": "cell-49483a7aad5aa158",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## Learning goals\n",
+    "\n",
+    "\n",
+    "In this round you will learn a simple but powerful approach for choosing a \"good\" hypothesis space out of a set of alternatives. In particular, you will \n",
+    "\n",
+    "* learn that the training error is a poor quality measure for a hypothesis space \n",
+    "* learn that the validation error is a more useful quality measure for a hypothesis space \n",
+    "* learn how to choose between different hypothesis spaces (models) using the validation error\n",
+    "* learn about regularization as a soft variant of model selection. \n",
+    "\n",
+    "## Background Material \n",
+    "\n",
+    "* [Video lecture](https://www.youtube.com/watch?v=MyBSkmUeIEs) of Prof. Andrew Ng on model validation and selection\n",
+    "* [Short video](https://www.youtube.com/watch?v=TIgfjmp-4BA) on K-Fold Cross validation from Udacity\n",
+    "* [Video lecture](https://www.youtube.com/watch?v=KvtGD37Rm5I) of Prof. Andrew Ng on regularization\n",
+    "* Chapter 2; Chapter 6; Chapter 7 of this [tutorial](https://arxiv.org/abs/1805.05052)  "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "c63370161f651a6e1d179d1339b68671",
+     "grade": false,
+     "grade_id": "cell-90c66bf37e8ad022",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "\n",
+    "## What is model validation?\n",
+    "\n",
+    "Suppose that we want to predict a numeric label (quantity of interest) $y \\in \\mathbb{R}$ based on some features $\\mathbf{x}=(x_{1},\\ldots,x_{n}) \\in \\mathbb{R}^{n}$ of a data point. In order to learn a good predictor $h(\\mathbf{x})$, we can use some data points $\\mathbb{X} = \\{ \\big( \\mathbf{x}^{(i)},y^{(i)}\\big)\\}$ for which we have determined the true label value $y^{(i)}$. Each data point in the training data $\\mathbb{X}$ is characterized by features $\\mathbf{x}^{(i)}$ and a label (quantity of interest) $y^{(i)}$. \n",
+    "\n",
+    "Consider a predictor $h(\\mathbf{x})$ which works extremely well on the dataset $\\mathbb{X}$,\n",
+    "\n",
+    "\\begin{equation}\n",
+    "\\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}}\\big(y^{(i)} - \\underbrace{h(\\mathbf{x}^{(i)})}_{= \\hat{y}^{(i)}}\\big)^{2}\\approx 0.\n",
+    "\\end{equation}\n",
+    "\n",
+    "Even if the predictor $h(\\mathbf{x})$ does exceptionally well on the data set $\\mathbb{X}$, we can not be sure that the method will work well on new data points (different from the data points in $\\mathbb{X}$). \n",
+    "This is particularly true for ML models that allow for complex predictor functions $h(\\mathbf{x})$. Examples of complex  predictor functions are linear functions $h(\\mathbf{x}) = \\mathbf{w}^{T} \\mathbf{x} = \\sum_{r=1}^{n} x_{r} w_{r}$ using a large number of features $x_{1},\\ldots,x_{n}$ (the number $n$ of features is a measure of the complexity of the space of linear functions).\n",
+    "\n",
+    "Another example for a vast hypothesis space is given by the set of all predictor functions that can be represented by a given deep neural network structure with billions of adjustable weights (each edge has one weight $w$ that can be tuned). When using an extremely large hypothesis space $\\mathcal{H}$, it is very likely that just by chance one finds a predictor function $h(\\cdot) \\in \\mathcal{H}$ that perfectly fits (reproduces) a given set of labeled data points (unless this dataset is VERY large). \n",
+    "\n",
+    "It is worth emphasizing that the optimal complexity of the predictor function is typically dependent on the size of the dataset. A deep neural network might generalize well when trained on a huge dataset, whereas even a linear model with many features might be prone to severe overfitting on a small dataset. In particular, it can be shown that if the number of features is equal to the number of datapoints, a linear model can fit the data perfectly.\n",
+    "\n",
+    "ML methods that perform well on training data due to memorization of the training data do not pick up any intrinsic relation between features $\\mathbf{x}$ and label $y$. Such an ML method merely overfits the training data and will not be able to **generalize well** to new data. \n",
+    "\n",
+    "In order to detect overfitting we need to implement some form of **validation**. The idea behind validation is quite simple: \n",
+    "\n",
+    "**Split the available labeled data points $\\mathbb{X}$ into two different subsets, a training set $\\mathbb{X}^{(t)}$ of size $m_{t}$ and a validation set $\\mathbb{X}^{(v)}$ of size $m_{v}$.** \n",
+    "\n",
+    "<img src=\"../../data/R4_ModelValSel/SplitValTrain.jpg\" alt=\"Drawing\" style=\"width: 600px;\"/>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "7c978e6a86045915131281b108bc4210",
+     "grade": false,
+     "grade_id": "cell-714536d18e8f3dff",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='splitTestandValidationfunction'></a>\n",
+    "<div class=\" alert alert-info\">\n",
+    "<b>Demo.</b> Split Data into Training and Validation Set.\n",
+    "\n",
+    "The code snippet below creates a synthetic dataset of $m$ datapoints $(\\mathbf{x}^{(i)},y^{(i)})$. Each data point is characterized by the feature vector $\\mathbf{x}^{(i)}=\\big(x^{(i)}_{1},\\ldots,x_{n}^{(i)}\\big)^{T} \\in \\mathbb{R}^{n}$ and a numeric label $y^{(i)} \\in \\mathbb{R}$. The feature vectors are stored in the rows of the matrix $\\mathbf{X}\\in \\mathbb{R}^{m \\times n}$. The labels are collected into the vector $\\mathbf{y}=\\big(y^{(1)},\\ldots,y^{(m)}\\big)^{T} \\in \\mathbb{R}^{m}$. \n",
+    "\n",
+    "The Python library `scikit-learn` provides the function \n",
+    "\n",
+    "`X_train, X_test, y_train, y_test=train_test_split(X, y, test_size=0.2, random_state=2)` \n",
+    "\n",
+    "which can be used to split a dataset into training and validation set. The function reads in the feature vectors in the numpy array `X` of shape ($m,n$) and the labels in the numpy array `y` of shape ($m,$). \n",
+    "\n",
+    "The function returns numpy arrays `X_train` of shape ($m_{t},n$), `X_val`of shape ($m_{v},n$), `y_train` of shape ($m_{t},$) and `y_val` of shape ($m_{v},$). The input parameter `test_size` specifies the relative size $m_{v}/m$ of the validation set. When using `test_size=0.2`, $20 \\%$ of the original data points are used for the validation set and the remaining $80 \\%$ in the training set.\n",
+    "\n",
+    "[Scikit-learn documentation of train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "170d0a35cc75d5510927d687b1fddd8f",
+     "grade": false,
+     "grade_id": "cell-b8b4f6fb62eef46b",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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09y1QnJvOJ5701xm7T+L7qnd7S1UktQUL9KTpEGKCObMnAPA3JvmAjBn5py1wvGcmXPsPZOkUcYeZEkagt6Q3NuTvN5p6xmOpXHsvPPOY9NNN21qm1NPPZV99tmn5bVEBBdffHFT27z//e+nu7u75bWMNgZkSRqiak9yL8Ox1Bqj7ULYt7/97TzwwANNbfORj3yEn/70p8NU0fBavHgxEcHChQtH/LUH8wdAowzIkjREvWOOq+pduCepOaPtQtjeGTu23XbbprbbdNNNeeELXzhMVWkwDMiSNAS1F+StPmV13Qv3JDWvnRfCPvPMM3zoQx9i8uTJbLTRRhxwwAFcf/31a5YvWLCAiODKK69kv/32Y4MNNmDevHl1h1icccYZTJ48mU033ZSjjjqKf/u3f2Pq1KlrltcOsTjmmGN44xvfyNy5c5kyZQpbbrklxx57LCtWrFizztVXX81BBx3ElltuyVZbbcXMmTO55557mnqPzz33HB/5yEfYcsst2XLLLfnQhz7Ec889t9Y6A73OtGnTAHjFK15BRKwZnnHzzTdzyCGHsPXWWzNp0iT++q//mhtuuGGtfZ911lnssccebLTRRmyzzTbMnDmTVatWrVn+zW9+k7322ouNNtqIPfbYgzlz5rB69WqANcfviCOOICLWOp4tkZnj6vHyl788JakVVq9enbOumpWcSs66alauXr2633ZpPLr77ruHtH2936eR+P364Ac/mNttt11efvnleffdd+dxxx2Xm2yyST788MOZmdnT05NA7rPPPjlv3ry8//77c9myZfnNb34zN9lkkzX7+fa3v50bbrhhnnPOOXnvvffm6aefnpMmTcpddtllzTqf+tSncu+9917z/Oijj85Jkyblcccdl3fffXfOmzcvN9988zz99NPXrHPxxRfnxRdfnL/+9a/z9ttvzyOOOCJf9KIX5TPPPLNmHSC/973v9fkeP/e5z+WkSZPyO9/5Tt5zzz35/ve/PzfbbLM8+OCDG36dX/ziFwnk1VdfnUuXLs1HH300MzOvvfbavOCCC/Luu+/Oe+65J0888cTcYostcvny5ZmZefPNN+f666+f3/rWt3Lx4sV522235Re/+MVcuXJlZmaeffbZud122+X3vve9fOCBB/Kyyy7LyZMn51e+8pXMzFy2bFkCec455+TSpUtz2bJlfb7P/s5BYGHWyYttD6wj/TAgS2qV+Q/M7/M/6ep/4vMfmN+mCqX2G2pAzlz796n3MZzh+Mknn8yJEyfm+eefv6Zt1apVueuuu+bJJ5+cmc8H5IsvvnitbWsD8gEHHJAnnHDCWuu87nWvGzAg77jjjmvCYmbmcccdl695zWv6rXm99dbLn/3sZ2vaBgrI22+/fX76059e8/y5557L3Xfffa2APNDrLFq0KIG8+eab+9wms/gZbrfddnnhhRdmZuYll1ySkyZNyscff7zu+jvttFNecMEFa7XNmTMn99xzz4bfX6/BBGSHWEjSIE2fNp35R82ve0Fe74V784+az/Rp09tUoTQ2jPSFsPfffz8rV67kVa961Zq29ddfnwMPPJC77757rXW7urr63devfvUr9ttvv7Xa9t9//wFr2GuvvZgw4fnZeHfYYYe1bpl8//338853vpMXvehFTJo0icmTJ7N69Wp+97vfDbhvgMcee4ylS5dy4IEHrmlbb7311qltsK+zbNkyTjjhBPbYYw8233xzNttsM5YtW7Zmu9e97nXssssuTJs2jXe9612cf/75PPHEEwAsX76cBx98kBNOOIFNN910zeOkk07i/vvvb+j9DZXzIEvSEPQXfiPCcCy1QGb9C2GHKyQXHYv178JW27bJJpsMuL/B1Dhx4sR19tE7/hbgTW96E1OmTOGss85iypQpTJgwgb322otnn3226dfqz2Bf5+ijj+aRRx5hzpw5TJ06lQ033JDXvOY1a7bbbLPNuPXWW7nuuuu45pprOOOMM/j4xz/OzTffzPrrrw/AmWeeyStf+cqWvp9G2YMsSZI6Vm84HskLYXfbbTc22GCDtS7Ke+6557jhhhvYa6+9mtrXS17yEn7xi1+s1Vb7vFmPPvoo99xzDx//+Md57Wtfy5577skTTzyx1gVuA9l8883ZfvvtufHGG9e0ZeZatTXyOhtssAHAOhf3XX/99XzgAx/gDW94A3vvvTebbbYZS5cuXWudCRMmMGPGDM444wzuuOMOnnrqKS6//HImT57MlClTuP/++9ltt93WefSaOHHiOq/bKvYgS5KkjlQbjnt7jOvdwbKVPcmbbLIJ73vf+zjppJPYeuutmTZtGnPmzOGRRx7hn/7pn5ra16xZszj22GN5xStewUEHHcSll17KTTfdxJZbbjno+rbccku23nprzjnnHHbaaSce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vPBC3njjDQAeeOABLrjgAtavX09EEBFt5Rntr/W3v/2N888/n7333psRI0Zw/PHH8/TTT7e1bx+Jvu+++zjssMMYOXIk73vf+3jhhRd2ea/Gjx9PRUUFo0aN4sQTT9zhvt10001MmjSJiooKxo8fzze+8Q1aW1sBGDduHABnnXUWEdG2nS8lmyCnlD6WUhqTUipPKe2fUvqPlNJ3U0rfzbZ/K6X09pTS5JTSUSml3xQ7ZkmSVDpa1q/vU3tvfPjDH+aNN97g3nvvbdu3fv167rzzTs4991wAmpubOfnkk7nnnntYvnw5Z5xxBqeffjorV67s9nU+8YlP8Oyzz3LvvfeyaNEibr31Vl588cUd+gwZMoRrr72Wp59+mh/+8Ic89thjXHrppQC85z3v4dprr6WyspLVq1ezevVqLrvssk6v9eijj3LnnXfy2GOPUVlZyUknncTGjRvb+mzevJl58+Zx44038sgjj/DGG28wY8aMDs8H0NjYyCWXXMIXvvAF/vCHP3Dvvfdy0kkntbX/+7//O5///Of58pe/zIoVK/j617/OV7/6Vb797W8D8Pjjj7f1W716ddt2vgzYEgtJkqRSs/fee3PKKadw2223tSV8DQ0NlJWVceqppwIwefJkJk+e3HbM7Nmzufvuu/nJT37CnDlzdnmNP/7xj/zsZz/joYce4phjjgHglltu4ZBDDtmh32c/+9m2z+PGjePqq69m+vTp3HLLLQwbNow999yTiKCmpqbTa/3pT3/irrvu4sEHH2Tq1KkAfP/73+fAAw/ktttu48ILLwSgpaWF66+/nre97W0AXHbZZVxwwQW0trYyZMjO47Evv/wyI0eO5LTTTqO6upqDDjpoh3syd+5crr76as4880wADj74YGbNmsW3v/1tZs6cyfZ3yvbaa68u4++tkh1BliRJGojOPfdcFi1axIYNGwC47bbbOPPMM6moqAAyI8qXX345kyZNYu+996aqqorGxkZefvnlbp1/xYoVDBkyhCk5JSIHHXQQ++233w79fvWrX/GBD3yA/fffn+rqak4//XS2bNnCmjVruv29bL/W0Ucf3bZvzz335B3veAfPPPNM277hw4e3JccA++23H1u3bm0r6WjvAx/4AAcddBAHH3ww55xzDrfccgtNTU0ArFu3jldeeYWLL76Yqqqqtq9Zs2bx3HPPdTv2vjBBliRJyqMPfehDlJWVceedd7J27VruvffetvIKyIyu/vjHP2bu3Lk8+OCDPPnkk0yZMoUtW7Z06/zdeeXqpZde4oMf/CATJ07kxz/+McuWLWurU+7udXZ1rYho+1xWVtZh2/aa4faqq6t54oknuP322znwwAOZN28eEyZMYNWqVW3HfPe73+XJJ59s+3rqqad2qH3uTybIkiRJeTR8+HDOPPNMbrvtNv7rv/6Lmpoapk2b1tb+0EMP8fGPf5wzzjiDww8/nP33379HI6MTJ06ktbV1h7rbl19+mVWrVrVtNzY2smXLFr7xjW9w9NFHM378+B3aAYYNG8a2bdu6vNakSZNobW3lkUceadv35ptv8vvf/55JkyZ1O+aOlJWV8f73v5958+bxu9/9jvXr17N48WJGjx7N2LFjee6553jrW9+609d25eXlu4y/17H1y1klSZJ2Y+eeey7HH388L7zwAmefffYOdbjjx4+noaGB6dOnU15ezpe+9CU2bdrU7XO/7W1v46STTuLiiy9m4cKFjBgxgn/6p39ixIgRbX0OPfRQWltbufbaazn99NP57W9/y7XXXrvDecaNG8emTZu45557OOKII6isrKSysnKHPoceeijTp09vu9Zee+3F7Nmz2WOPPTj77LN7eXdg8eLFPPfcc0ydOpV99tmH+++/n6amJiZOnAjAF7/4RS699FL22msvTjnlFLZu3coTTzzBa6+9xpVXXtkW/3333ce0adMYPnw4e++9d6/jac8RZEmSpDybOnUqY8eO5ZlnntmhvAIy06/tu+++HHvssZx88skcddRRHHvssT06/80338zBBx/M+9//fk499VTOPvvsHaY6O/zww7nuuuu45pprmDRpEt/73vdYsGDBDud4z3vew4wZM/jYxz7GqFGjuPrqqzu81k033cSUKVM47bTTmDJlChs2bODnP//5Dgl5T+21114sWrSI448/ngkTJrBgwQK+973vtd2HCy+8kBtvvJHvf//7TJ48mWOPPZaFCxdy8MEHt53j61//Ovfffz8HHHAARxxxRK9j6UjsblMH19bWpsbGxmKHIUmSdmHFihVtI4q9cfuUKV1O5VY2ciQffuyxXp9fA0NXz1FELEsp1bbfb4mFJEkalEx+1VuWWEiSJEk5TJAlSZKkHCbIkiRJUg4TZEmSVLJ2t8kElF+9fX5MkCVJ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\n",
+      "text/plain": [
+       "<Figure size 720x720 with 2 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Import libraries\n",
+    "from sklearn.preprocessing import StandardScaler\n",
+    "from sklearn.datasets import load_boston\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from sklearn.model_selection import train_test_split    # Import train_test_split function\n",
+    "from sklearn import metrics\n",
+    "\n",
+    "m = 20    # Number of data points\n",
+    "n = 10    # Number of features\n",
+    "\n",
+    "np.random.seed(4)    # Set random seed for reproduceability\n",
+    "\n",
+    "X = np.random.randn(m,n)    # create feature vectors using random numbers\n",
+    "y = np.random.randn(m)    # create labels using random numbers \n",
+    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2)  # Split dataset with 80% training and 20% test\n",
+    "\n",
+    "plt.rc('legend', fontsize=14)    #  Set font size for legends\n",
+    "plt.rc('axes', labelsize=14)    #  Set font size for axis labels\n",
+    "\n",
+    "fig, axes = plt.subplots(2, 1, figsize=(10,10))    # Create figure with two subplots\n",
+    "axes[0].set_title('Scatterplot of the entire dataset', fontsize=16)\n",
+    "\n",
+    "axes[0].scatter(X[:, 0], X[:, 1], c='g',marker ='x', s=80, label='original dataset')  # Scatter plot of the original dataset\n",
+    "axes[0].legend(loc='best')    # Set legend and set it in the best (automatically determined) position\n",
+    "axes[0].set_xlabel(r'feature $x_1$')    # Set the label of the x-axis\n",
+    "axes[0].set_ylabel(r'feature $x_2$')    # Set the label of the y-axis\n",
+    "\n",
+    "axes[1].scatter(X_train[:, 0], X_train[:, 1], c='g', marker ='o', s=80, label='training set')  # Scatter plot of the training set\n",
+    "axes[1].scatter(X_val[:, 0], X_val[:, 1], c='brown', marker ='s', s=80, label='validation set')  # Scatter plot of the validation set\n",
+    "axes[1].set_title('Training and validation sets', fontsize=16)\n",
+    "axes[1].legend(loc='best')    # Set legend and set it in the best (automatically determined) position\n",
+    "axes[1].set_xlabel(r'feature $x_1$')    # Set the label of the x-axis\n",
+    "axes[1].set_ylabel(r'feature $x_2$')    # Set the label of the y-axis\n",
+    "\n",
+    "fig.tight_layout()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "825a6083aed2b286c9509044f93a2877",
+     "grade": false,
+     "grade_id": "cell-d82c01565964839f",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "The training set $\\mathbb{X}^{(t)}$ is used to learn the optimal predictor $h_{\\rm opt} \\in \\mathcal{H}$ out of the hypothesis space: \n",
+    "\n",
+    "\\begin{equation} \n",
+    "h_{\\rm opt}  = {\\rm argmin}_{h \\in \\mathcal{H}} \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - \\underbrace{h(\\mathbf{x}^{(i)})}_{= \\hat{y}^{(i)}}\\big)^{2}. \n",
+    "\\end{equation} \n",
+    "\n",
+    "The minimum objective value of this optimization problem is the **training error** \n",
+    "\n",
+    "\\begin{equation}\n",
+    "E_{\\rm train} = (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h_{\\rm opt}(\\mathbf{x}^{(i)})\\big)^{2}.\n",
+    "\\end{equation} \n",
+    "\n",
+    "Note that the training error $E_{\\rm train}$ measures the performance of the predictor $h_{\\rm opt}$ on the same data points $\\mathbb{X}^{(t)}$ which have been used to tune (learn) $h_{\\rm opt}$. Therefore, the training error $E_{\\rm train}$ is too **optimistic** as an estimate for the average error (or loss) of $h_{\\rm opt}$ on new data points which are different from $\\mathbb{X}^{(t)}$. \n",
+    "\n",
+    "To estimate the error incurred by $h_{\\rm opt}$ on new data points, we calculate the average loss incurred by $h_{\\rm opt}$ on the validation set $\\mathbb{X}^{(v)}$. This yields the **validation error**\n",
+    "\n",
+    "\\begin{equation}\n",
+    "E_{\\rm val} = (1/m_{v}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(v)}} \\big(y^{(i)} - h_{\\rm opt}(\\mathbf{x}^{(i)})\\big)^{2}. \n",
+    "\\end{equation}\n",
+    "\n",
+    "The validation error $E_{\\rm val}$ is a much better estimate for the average error (or loss) of the predictor $h_{\\rm opt}$. \n",
+    "\n",
+    "The training error $E_{\\rm train}$ provides a quality measure for the particular predictor $h_{\\rm opt}$. In contrast, the validation error $E_{\\rm val}$ provides a quality measure for the entire hypothesis space $\\mathcal{H}$. Therefore, we can use the validation error for **model selection**. In model selection, we choose the best hypothesis space $\\mathcal{H}$ out of a set of alternative hypothesis spaces $\\mathcal{H}^{(1)},\\mathcal{H}^{(2)},\\ldots$ by selecting the one that achieves the lowest validation error $E_{\\rm val}$."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "aa1022d9b407196f224d1b51b85d413b",
+     "grade": false,
+     "grade_id": "cell-de358afd2c4fac99",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## The Problem \n",
+    "\n",
+    "Model validation and selection is best understood by working through a particular example. To this end, we revisit the problem of predicting the grayscale value $y$ of a pixel in an aerial photograph. In **Round 2 - Regression**, we have formalized the grayscale value prediction as an ML problem with\n",
+    "\n",
+    "1. **data points** which represent pixels in the photograph. Each data point is characterized by features $\\mathbf{x} = (x_{1},\\ldots,x_{n}) \\in \\mathbb{R}^{n}$. Moreover, we define the grayscale value of the pixel as the label $y$ of the data point. \n",
+    "\n",
+    "2. a **hypothesis space** $\\mathcal{H}$ consisting of predictor functions $h: \\mathbb{R}^{n} \\rightarrow \\mathbb{R}$ from features $\\mathbf{x} \\in \\mathbb{R}^{n}$ to a predicted grayscale value $\\hat{y}=h(\\mathbf{x})\\in \\mathbb{R}$ and \n",
+    "\n",
+    "3. a **loss function**, such as squared error loss, which measures the quality of a predictor."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "33f44c0e6775d5ff8a9066aab1a7a1a4",
+     "grade": false,
+     "grade_id": "cell-3d2949507bb9fa14",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='handsondata'></a>\n",
+    "<div class=\" alert alert-info\">\n",
+    "<p><b>Demo.</b> Loading the Data.</p>\n",
+    "    \n",
+    "The following code snippet defines a function `X,y = GetFeaturesLabels(m,n)` which reads in the features and labels of pixels which are not corrupted (not fully black). The input parameters are the number `m` of data points and the number `n` of features to be used for each data point. The function returns a matrix $\\mathbf{X}$ and vector $\\mathbf{y}$. \n",
+    "\n",
+    "The features $\\mathbf{x}^{(i)}$ of data points are stored in the rows of the numpy array `X` (of shape (m,n)) and the corresponding grayscale values $y^{(i)}$ in the numpy array `y` (of shape (m,1)). The two arrays represent the feature matrix $\\mathbf{X} = \\begin{pmatrix} \\mathbf{x}^{(1)} & \\ldots & \\mathbf{x}^{(m)} \\end{pmatrix}^{T}$ and the label vector $\\mathbf{y} = \\big( y^{(1)}, \\ldots, y^{(m)} \\big)^{T}$. \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "2a27182544123e44123b40374f260f57",
+     "grade": false,
+     "grade_id": "cell-711d85b7cf810763",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Pandas provides functions for loading (storing) data from (to) files\n",
+    "import pandas as pd  \n",
+    "# the library \"cv2\" provides powerful methods for image processing and computer vision\n",
+    "import cv2 \n",
+    "# import functions for displaying and plotting data \n",
+    "from matplotlib import pyplot as plt \n",
+    "from IPython.display import display, HTML\n",
+    "# library \"numpy\" provides matrix (represented by numpy arrays) operations \n",
+    "import numpy as np   \n",
+    "# library \"random\" provides functions for generating random numbers\n",
+    "import random\n",
+    "\n",
+    "def GetFeaturesLabels(m, n):\n",
+    "    \n",
+    "    # m - number of data points (pixels)\n",
+    "    # n - number of features\n",
+    "    \n",
+    "    # filename of image file containing corrupted pixels\n",
+    "    corrupted = '../../../coursedata/R2_Regression/SomePhotoCorrupted.bmp'\n",
+    "    \n",
+    "    # read corrupted image as numpy array\n",
+    "    Photo = cv2.imread(corrupted, 0)\n",
+    "    # set image size (100 by 100 pixels)\n",
+    "    Photo = cv2.resize(Photo, (100, 100))\n",
+    "    \n",
+    "    # get image height and width \n",
+    "    imgheight = Photo.shape[0]\n",
+    "    imgwidth = Photo.shape[1]\n",
+    "\n",
+    "    # determine \"uncorroputed pixels\" by finding indices of those pixels with grayscale value larger than 0\n",
+    "    good_idx = np.where(Photo > 0)\n",
+    "\n",
+    "    # store the vertical coordinate (row index) of uncorroputed pixels in numpy array `rows`\n",
+    "    rows = good_idx[0] \n",
+    "    # store the horizontal coordinate (column index) of uncorroputed pixels in numpy array `cols` \n",
+    "    cols = good_idx[1]\n",
+    "    \n",
+    "    # set pads for defining pixel neighborhood and augmenting the image\n",
+    "    wp = 1\n",
+    "    hp = 1\n",
+    "\n",
+    "    # augment image with stripes such that we can also define neighborhoods of border pixels \n",
+    "    # the values of these pixels are zero\n",
+    "    tmp = np.vstack((np.zeros((wp, imgwidth)), Photo, np.zeros((wp, imgwidth))))\n",
+    "    augmented = np.hstack((np.zeros((2*wp + imgheight, hp)), tmp, np.zeros((2*wp + imgheight, hp))))\n",
+    "\n",
+    "    # initialize feature vectors `x1`, `x2`and label vector `y` as numpy arrays \n",
+    "    x1 = np.zeros((m,1))\n",
+    "    #x2 = np.zeros((m,1))\n",
+    "    y = np.zeros((m,1))\n",
+    "    \n",
+    "    # calculate the mean and median gray scale value of a pixel neighborhood \n",
+    "    # here we define 3x3 pixel matrix surrounding a pixel as its neighborhood \n",
+    "    for iter_datapoint in range(m):\n",
+    "        row = rows[iter_datapoint] + wp # add wp to get the index of same data point in augmented Photo\n",
+    "        col = cols[iter_datapoint] + hp # add hp to get the index of same data point in augmented Photo\n",
+    "\n",
+    "        # get the true label (gray scale value) of a datapoint (pixel)\n",
+    "        y[iter_datapoint] = augmented[row, col]\n",
+    "\n",
+    "        # get values of pixel with its neighborhood (3x3 matrix) from image\n",
+    "        neighbors = np.copy(augmented[(row-wp):(row+wp+1), (col-hp):(col+hp+1)])\n",
+    "        # set value of a data point to 0 in order to exlude this value from calculation\n",
+    "        # for the 3x3 array the indices for this data point(center of the neighborhood) is [1,1]\n",
+    "        neighbors[1,1] = 0\n",
+    "        \n",
+    "        # calculate the feature of a data point (pixel) - the mean and median gray level of the neighborhoud\n",
+    "        # zero values are exluded from calculation\n",
+    "        x1[iter_datapoint] = np.mean(neighbors[neighbors != 0])   \n",
+    "        #x2[iter_datapoint] = np.median(neighbors[neighbors != 0]) \n",
+    "        \n",
+    "    np.random.seed(30) # this is done so that every time that below np.random.randn is called, it produces the same output. \n",
+    "                       # this is needed for testing purposes\n",
+    "    # lets add some \"extra features\" here \n",
+    "    X = np.hstack((x1, np.random.randn(n,m).T)) \n",
+    "    \n",
+    "    X = X[:,:n]\n",
+    "    return X, y"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "442ad125c79a044829d63ca0296dfe8a",
+     "grade": false,
+     "grade_id": "cell-ddfcf8b06137c570",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## Linear Predictors \n",
+    "\n",
+    "To predict the grayscale value $y$ of a pixel based on the first $r$ features (or characteristics) $\\mathbf{x}=(x_{1},\\ldots,x_{r})^{T} \\in \\mathbb{R}^{r}$, we try to find (or learn) a predictor function $h(\\mathbf{x})$ such that $y \\approx h(\\mathbf{x})$. We restrict ourselves to linear predictor functions without an intercept term. Thus, we use the hypothesis space \n",
+    "\n",
+    "$$ \\mathcal{H}^{(r)} = \\{ h(\\mathbf{x}) = \\mathbf{w}^{T} \\mathbf{x} \\mbox{ with some weight } \\mathbf{w}\\in \\mathbb{R}^{r} \\}.$$ \n",
+    "\n",
+    "Carefully note that for each value $r\\in \\{1,\\ldots,n\\}$, we obtain a different hypothesis space $\\mathcal{H}^{(r)}$ (or \"model\"). These hypothesis spaces are nested such that\n",
+    "\n",
+    "$$\\mathcal{H}^{(1)} \\subseteq \\mathcal{H}^{(2)} \\subseteq \\mathcal{H}^{(3)} \\ldots .$$\n",
+    "\n",
+    "This means that the hypothesis space $\\mathcal{H}^{(i)}$ contains all functions in the hypothesis spaces $\\mathcal{H}^{(j)}$, for $j=1,\\ldots,i-1$.\n",
+    "\n",
+    "For a fixed model parameter $r$, the weight vector $\\mathbf{w} \\in \\mathbb{R}^{r}$ is tuned by minimizing the average squared error loss incurred on the labeled data points in the training set $\\mathbb{X}^{(t)}$: \n",
+    "\n",
+    "\\begin{align}\\min_{h \\in \\mathcal{H}^{(r)}}  & \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}}  (y^{(i)} - h(\\mathbf{x}^{(i)}) )^{2} \\nonumber \\\\ \n",
+    "= \\min_{\\mathbf{w} \\in \\mathbb{R}^{r}} & \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}}  \\big(y^{(i)} -  \\mathbf{w}^{T}\\mathbf{x}^{(i)}  \\big)^{2}.\n",
+    "\\end{align}\n",
+    "\n",
+    "Solving this training problem provides us with optimal choices for weight vector $\\mathbf{w}$. \n",
+    "However, we have another design parameter at our disposal: the number $r$ of features! While each pixel is characterized by $n$ features in our dataset, we are free to use fewer e.g. only the first $r \\leq n$ of these features. \n",
+    "\n",
+    "What is the best choice for $r$? "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "992752c5b620b6dd0a2cceab64db4e80",
+     "grade": false,
+     "grade_id": "cell-0399c961c185f2f3",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## The Wrong Way \n",
+    "\n",
+    "Let us try out each hypothesis space $\\mathcal{H}^{(r)}$ on the training data $\\mathbb{X}^{(t)}$. For each $r=1,\\ldots,h,$ we find the optimal predictor $h_{\\rm opt}^{(r)} \\in \\mathcal{H}^{(r)}$ by minimizing the average loss\n",
+    "\n",
+    "\\begin{align} \n",
+    "\\mathcal{E}(r) & = (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big( y^{(i)}- h^{(r)}(\\mathbf{x}^{(i)}) \\big)^{2}. \n",
+    "\\end{align} \n",
+    "\n",
+    "The training error for the hypothesis space $\\mathcal{H}^{(r)}$ is then calculated as the mean-squared error incurred by the optimal predictor $h_{\\rm opt}^{(r)}$:\n",
+    "\n",
+    "\\begin{align} \n",
+    "E_{\\rm train}(r) & = (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big( y^{(i)}- h_{\\rm opt}^{(r)}(\\mathbf{x}^{(i)}) \\big)^{2} \\nonumber \\\\ \n",
+    "& = (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big( y^{(i)}- \\mathbf{w}_{\\rm opt}^T \\mathbf{x}^{(i)}) \\big)^{2}. \\nonumber \n",
+    "\\end{align} \n",
+    "\n",
+    "We can see that when the loss function is the mean-squared error - such as in ordinary least squares regression - the loss of the optimal predictor is equivalent to the training error. However, this is not always the case as we will see later in this notebook when considering regularization. \n",
+    "\n",
+    "It is tempting to choose the number $r$ of features according to the smallest training error $E_{\\rm train}(r)$. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "ffd4758844993ca456e82b77869e4548",
+     "grade": false,
+     "grade_id": "cell-0aaf4cb2c4109eb2",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false
+    }
+   },
+   "source": [
+    "<a id='trainModel'></a>\n",
+    "<div class=\" alert alert-info\">\n",
+    "<p><b>Demo.</b> Varying Number of Features </p>\n",
+    "    \n",
+    "The following code snippet computes the training error $E_{\\rm train}(r)$ for each choice of $r$. For each particular value $r=1,\\ldots,n$, the best linear predictor $h(\\mathbf{x}) = \\mathbf{w}^{T} \\mathbf{x}$ is found using the  function `.fit()` of the `LinearRegression` class in scikit-learn.\n",
+    "\n",
+    "[Documentation of the LinearRegression class in scikit-learn](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html) \n",
+    "\n",
+    "</div>    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "b355c08fc529a8c56586132fa4801ad7",
+     "grade": false,
+     "grade_id": "cell-acd5c9243afcd36f",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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q1bRs2dPNttsM+644w5GjBiR9axqYcsGMxgzBg49FE47DW67LXYiERERWY+PP/6YRYsWsfvuu9OpU6e1lpYtW/Loo49Sr149+vbtu9Z+paWlmBkTJkygX79+NG7cmNuSv/v7778/d911V07yqoUtW+rXD4XaV1+F69natYN99omdSkREpGaNHg3TptXsa/bqFRpOMjB16lTq169P7969K3z+hRde4Gc/+9k6g91OS362Sy65hAsvvJCtttqKVq1aAdCnTx8uuOACli5dSpMmTarwg1ROLWzZ1KgR3H8//PSnMHAgvPpq7EQiIiJSgalTp7J69Wo6dOhA8+bNf1gGDhwIwCeffELnzp3X2W/69Ok0btyYe++994fr29q2bQtAly5dWLlyJV988UXW86qFLdtatoTHHoO+fWHffeHFF2GbbWKnEhERqRkZtnTFMnXqVA455BAuvvjitdZvtNFGACxdupSOHTuus9+0adPYZ5992GKLLdZ5bk2r2tKlS7OeVy1sudCxIzzxBBQVwV57QWlp7EQiIiKS4s0336Rv375sscUWay3t27cHoF27dixcuHCd/aZPn87uu+9e4TEXLFgA8MMxskkFW65svnkYn23RIujfHyr40EVERKTmzZo1iwULFlR6/RpA7969mTFjxlrrFi9ezMcff8yOO+5Y4T7vvPMOXbp0qbBlrrpUsOVS795h6qqPPoLf/Q5y0EQqIiIimZk6dSoAnTp1Ys6cOWstq1atAmCvvfbivffe4+uvv/5hv7feeguAXr16VXjcF154gf79++ckswq2XOvXD26/HV5+GQYNguSLICIiInGsKdi22WYbOnfu/MPSpUsXvv/+ewB69uxJnz59mDBhwg/7TZ8+nS233JLmzZuvc8xly5Zx//33c/zxx+ckswq2mnDooXD11TBpEpx4IrjHTiQiIlJn/f3vf8fd11nKysp+GKIDwuwFV111FatXrwbgxBNP5P3336/wmOPGjeMXv/gFO+20U04yq5doTRkxAubOhfPPD7MhXHBB7EQiIiKyHv3792fEiBGUlpay6aabrnfbBg0acPXVV+csiwq2mvTXv4YprC68MPQkPfXU2IlERERkPUaOHJnWdsOHD89pDhVsNckMrrsO5s+HUaOgQwc47LDYqURERCTPRb2GzcxamdlEM3vfzN4zs53N7Dwz+9zMpiXL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C/8KKhVsIiIiUvv87GdwzTXw5JPwt7/FTlNtKthERESkdjruuDA229/+Bo8+GjtNtahgExERkdrJDK67DnbYAY48EmbPjp2oylSwiYiISO3VpEm4nq2sDAYMgGXLYieqEhVsIiIiUrttvjncdhtMnQojR8ZOUyUq2ERERKT2239/OPNMuOkmuOWW2GkypoJNRERE6obzz4c994STT4Zp02KnyYgKNhEREakb6teHf/0L2rYNk8QvWhQ7UdpUsImIiEjd0aED3HsvfPopHH106IxQAFSwiYiISN2y885w+eXw0ENwySWx06RFBZuIiIjUPaecAocfDn/+c5goPs+pYBMREZG6xwzGjoWttw6FW2lp7ETrpYJNRERE6qbmzcOgukuXwsCBsGJF7ESVUsEmIiIiddfWW4dx2V59Ff74x9hpKqWCTUREROq2AQPg97+Hq6+Gu+6KnaZCKthERERELr4Ydt0VjjsO3n03dpp1qGATERERadAA7r4bWrQIg+p+913sRGtRwSYiIiIC0KVLKNpmzoRhw8A9dqIfqGATERERWWP33cPp0YkTYcyY2Gl+oIJNREREJNUf/gAHHwynnQYvvBA7DaCCTURERGRtZvDPf8Jmm8Fhh8GcObETqWATERERWcdGG4VBdRctgkGDYNWqqHFUsImIiIhUpGdPuOkmeO45OOusqFGKor66iIiISD4bPBheeQWaNAm9Rs2ixFDBJiIiIrI+V18drVBbQ6dERURERNYncrEGKthERERE8p4KNhEREZE8p4JNREREJM+pYBMRERHJcyrYRERERPKcCjYRERGRPKeCTURERCTPqWATERERyXMq2ERERETynAo2ERERkTyngk1EREQkz6lgExEREclz5u6xM+SMmc0HPomdoxZoB3wVO4RUiz7DwqfPsLDp8yt8NfEZburu7St6olYXbJIdZjbF3Ytj55Cq02dY+PQZFjZ9foUv9meoU6IiIiIieU4Fm4iIiEieU8Em6RgbO4BUmz7DwqfPsLDp8yt8UT9DXcMmIiIikufUwiYiIiKS51SwSaXMbGMze9bM3jOzd81sVOxMkjkzq29mb5rZw7GzSObMrJWZTTSz95PfxZ1jZ5LMmFlJ8m/oO2Z2l5k1jp1J1s/M/mlm88zsnZR1bczsKTP7KLltXZOZVLDJ+qwC/uDu2wA7ASPMbNvImSRzo4D3YoeQKrsSeNzdtwZ2QJ9lQTGzrsBIoNjdtwfqA4PippI03Ar0L7fuDOBpd98SeDp5XGNUsEml3P1Ld38juf8d4Q9F17ipJBNm1g3YF7g5dhbJnJm1BHYDxgG4+wp3XxQ3lVRBEdDEzIqApsAXkfPIBrj788CCcqsPAMYn98cDB9ZkJhVskhYz6w70Bl6Lm0QyNAY4HSiLHUSqZDNgPnBLclr7ZjNrFjuUpM/dPwf+D/gU+BL4xt2fjJtKqqiju38JoUED6FCTL66CTTbIzJoD/wZGu/u3sfNIesxsP2Ceu0+NnUWqrAjYEbje3XsDi6nh0zBSPcl1TgcAPYAuQDMzOzJuKilEKthkvcysAaFYu9Pd74udRzLSF9jfzGYDE4B+ZnZH3EiSoVKg1N3XtGxPJBRwUjh+Dcxy9/nuvhK4D9glciapmrlm1hkguZ1Xky+ugk0qZWZGuHbmPXe/PHYeyYy7n+nu3dy9O+Ei52fcXf+zLyDuPgf4zMy2SlbtCcyIGEky9ymwk5k1Tf5N3RN1HClUk4Ahyf0hwIM1+eJFNfliUnD6AkcBb5vZtGTdWe7+aMRMInXNqcCd/9/evYVKVYZhHP8/nsqMCFIqKrWsQAsVIe2gJV2EGEoXZUFS2QErLyQNhTK6qEBNSCKUqMwussgOkFlKaKKVSeWhgxh5zNRE86yZp7eL79s57Pbs2dux2at4fjdrZtZa73pnXQwP3/rWLEntgPXAiBbux5ohIpZJehdYTrrzfgV+6kHhSXoLGAh0lPQr8DQwEXhH0gOkIH5HTXvykw7MzMzMis2XRM3MzMwKzoHNzMzMrOAc2MzMzMwKzoHNzMzMrOAc2MzMzMwKzoHNzMzMrOAc2Mzsf0NSK0kvS/pdUkgaWM12ZmZF4cBmZi1CUidJR/M/wLeRdFBS5yrLDib9sewQ4ELgyyq3axZJiyS9dDpqmZmV8pMOzKylXAesjIhDkvoBuyLilyprXg5si4hKAayp27UISe0i4kiNjtUmIo7V4lhmduo8wmZmLeV64Iv8un/J67IknSFpqqTtkg5L+kpS/7xuJvAC0Dlf5txYpkaD2ykZJ2mdpD8kfS9peMl+gyQtkbRb0i5J8yV1r1f3JmBUrhuSujY06iZppqSPSt4vkjRd0hRJO+rORRN6ujGfgwOS9kpaJunqRs7fxbmvuyQtlHQYuKfSeTezlucRNjOrmXzJ87v89izguKT7gPZASNoDzIqIR8uUmAwMA+4nPVdzDDBP0hXAaGBTXncNcLxMjXLbPQvcDowCfiKNAL4iaXdEzAU6AFNz/+2BCcAcST3yaNho4EpgDfBErrmjaWcGgOGkZ0wOAFSpJ2A+6eHTrwF3A22BPo18b4DeeTkeeDLX3NOMHs2shTiwmVktbSWFhnOAb4BrgQPASuBW0gOVDzS0o6QOwCPAgzlAIelh4GZgVERMkLQfOB4Rv5VrICL21t8u1x4D3BIRS/KmGyT1JYWluRHxXr1+RgD7gL7A57nuEeBQ6fEl0UQbImJsve/bWE9LgXOBORGxLq9fU+EYvYDDwB0RsbapjZlZy3NgM7OayXOlNkoaBnwdEask3QBsj4jFFXbvRhpF+vvSaUQcl7QU6FFlaz2AM0mjdVHyeVtgI4CkbsAzQD+gE2lK9N4OSAAAAjpJREFUSSug2hsl6nzbnJ4iYle+DDtf0gJgATA7IjY3cozewMcOa2b/PQ5sZlYzkn4EupBCRytJB0i/Q23y600RcVW53fMyGljX0GfNUTefdwhplK/U0bycA2wBRublMWA10K5C7ROc7L1O2wa2O9jcniJihKSpwCBgKPCcpNsiYn6ZXnoBvovV7D/Igc3MamkwKawsAMaRRpXeBmYC8zgZjhqyFjhCukFhPYCk1qR5XbOq7Gs18CfQJSIW1l8p6TygO+nS62f5sz788zf0CNC63mc7SH8dUqoXeeTuVHuqExGrgFXAJEmfAPeS5rfV/w4dSKOUyysc18wKyIHNzGomIjZJugA4nzRh/gTp0t/7EbG1wr4HJU0HJkraCWwAHsu1plXZ135JU4ApSpPOFgNnk+bYnQBeBXYCD0naDFwEPE8aZSu1EegrqStpLt4uYCEwVdJQ0iT/kcAlVAhsTejp01zrQ9KI32VAT2B6mZI983JloyfDzArJgc3Mam0gaf7aYUkDgC2VwlqJ8Xn5OmnC/QpgUERsOw19PQVsBx4nhZ59pHAzOSJOSLoTeBH4gTTaNxZ4r16NKcAbpNGx9sClwAxSWJqRt5kGfAB0rKYn4BDprtTZudZ24E1gUplavYCfI6LBmzrMrNgUUe3UDzMzMzP7N/mPc83MzMwKzoHNzMzMrOAc2MzMzMwKzoHNzMzMrOAc2MzMzMwKzoHNzMzMrOAc2MzMzMwKzoHNzMzMrOAc2MzMzMwK7i+6FSRC+H7vxQAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<Figure size 720x432 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from sklearn.linear_model import LinearRegression\n",
+    "from sklearn.metrics import mean_squared_error\n",
+    "\n",
+    "m = 20                        # we use the first m=20 data points (pixels) from the aerial photo \n",
+    "n = 10                        # maximum number of features used \n",
+    "\n",
+    "X,y = GetFeaturesLabels(m,n)  # read in m data points using n features \n",
+    "linreg_error = np.zeros(n)    # vector for storing the training error of LinearRegresion.fit() for each r\n",
+    "\n",
+    "for r_minus_1 in range(n):    # loop r times\n",
+    "    reg = LinearRegression(fit_intercept=False)    # create an object for linear predictors\n",
+    "    reg = reg.fit(X[:,:(r_minus_1 + 1)], y)    # find best linear predictor (minimize training error)\n",
+    "    pred = reg.predict(X[:,:(r_minus_1 + 1)])    # compute predictions of best predictors \n",
+    "    linreg_error[r_minus_1] = mean_squared_error(y, pred)    # compute training error \n",
+    "\n",
+    "plot_x = np.linspace(1, n, n, endpoint=True)    # plot_x contains grid points for x-axis (1,...,n)\n",
+    "\n",
+    "# Plot training error E(r) as a function of feature number r\n",
+    "plt.rc('legend', fontsize=14)    #  Set font size for legends\n",
+    "plt.rc('axes', labelsize=14)    #  Set font size for axis labels\n",
+    "plt.figure(figsize=(10,6))    # Set figure size\n",
+    "plt.plot(plot_x, linreg_error, label='$E(r)$', color='red')\n",
+    "plt.xlabel('# of features $r$')\n",
+    "plt.ylabel('training error $E(r)$')\n",
+    "plt.title('training error vs number of features', fontsize=16)\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "66ffaa02fcd482d749b283a6aff03bae",
+     "grade": false,
+     "grade_id": "cell-4fba2c040fb160f3",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false
+    }
+   },
+   "source": [
+    "### Let's Interpret the Results!\n",
+    "\n",
+    "Based on the above plot, we could argue that we should choose the linear model with $r=10$ features since this yields the lowest training error $E(r)$. **This reasoning is incorrect** since our ultimate goal is to find a predictor for new pixels for which we do not know the grayscale values (e.g. corrupted pixels). Our goal is not to accurately reproduce the grayscale values of pixels for which we already know these values! \n",
+    "\n",
+    "Using the training error $E_{\\rm train}(r)$ to assess the quality of the predictor $h_{\\rm opt}^{(r)}$ is misleading since $h_{\\rm opt}^{(r)}$ is based on the weight vector $\\mathbf{w}$ that is perfectly tuned to the training data $\\mathbb{X}^{(t)}$. Also, the more features (larger $r$) we use, the better we will be able to fit the training data $\\mathbb{X}^{(t)}$ (obtain smaller training error). However, this does not necessarily lead to better performance on new data. A complex model with too many features (large $r$) might only fit the training data very well, and generalize poorly to new data.\n",
+    "\n",
+    "Consider the case of $r=m_{\\rm train}$, i.e., the number of features is the same as the number of labeled data points in the training set. Under very mild conditions it can be shown that in this case there always exists a linear predictor $h(\\mathbf{x})=\\mathbf{w}^{T} \\mathbf{x}$ such that $y^{(i)} = h(\\mathbf{x}^{(i)})$, i.e., the training error is exactly zero (see Chapter 7.1 of the coursebook)! \n",
+    "A better way to evaluate the quality of a predictor is presented next."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "8f13b441e7c592f7961274a75d01cef0",
+     "grade": false,
+     "grade_id": "cell-8e508ee65304e99f",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "##  The Right Way\n",
+    "\n",
+    "The training error $E_{\\rm train}(r)$ is a bad measure for the quality of a hypothesis space $\\mathcal{H}^{(r)}$ since it will always favor larger spaces (larger number $r$ of features). A more useful measure for the quality of a hypothesis space $\\mathcal{H}^{(r)}$ is the validation error \n",
+    "\n",
+    "\\begin{equation}\n",
+    "E_{\\rm val}(r) = (1/m_{v}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(v)}} \\big(y^{(i)} - h^{(r)}_{\\rm opt}(\\mathbf{x}^{(i)})\\big)^{2}, \n",
+    "\\end{equation} \n",
+    "\n",
+    "where the predictor $h_{\\rm opt}^{(r)}(\\mathbf{x}) = \\mathbf{w}_{\\rm opt}^T\\mathbf{x}$ is obtained by minimizing the training error $E_{\\rm train}(r)$ with respect to $\\mathbf{w}$. \n",
+    "\n",
+    "Since a lower validation error corresponds to better predictions, the best hypothesis space for our problem is the one with the lowest validation error. Consequently, we should choose the model with the lowest validation error when performing model selection in machine learning."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "b5bda1d34b2750a130a79077d8572a6b",
+     "grade": false,
+     "grade_id": "cell-8a7b319a106cbd05",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='splitTestandValidationfunction'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<b>Student Task.</b> Generate Training and Validation Set.\n",
+    "   \n",
+    "Use the `scikit-learn` library function `train_test_split()` to split the data points obtained from the function `GetFeaturesLabels` into a training and validation set. The function should be used with the choice `random_state=2` and `test_size=0.2`. \n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "43473bbe5d33ed82934766b430175abc",
+     "grade": false,
+     "grade_id": "cell-9cc67382efb4ce19",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true
+    }
+   },
+   "outputs": [],
+   "source": [
+    "from sklearn.model_selection import train_test_split    # Import train_test_split function\n",
+    "\n",
+    "m = 20    # we use the first m=20 data points (pixels) from the aerial photo\n",
+    "n = 10    # maximum number of features used \n",
+    "\n",
+    "X, y = GetFeaturesLabels(m,n)    # read in m data points using n features \n",
+    "\n",
+    "### STUDENT TASK ###\n",
+    "# Compute the training and validation sets\n",
+    "# X_train, X_val, y_train, y_val = ...\n",
+    "# YOUR CODE HERE\n",
+    "\n",
+    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "7dd13ab8fc6953e27887597c540e1d62",
+     "grade": true,
+     "grade_id": "cell-2fbabdcefb77f271",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Sanity checks passed!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Check dimensions of train and validation vectors\n",
+    "assert len(X_train) == 16, \"The 'x_train' vector has the wrong length\"\n",
+    "assert len(y_train) == 16, \"The 'y_train' vector has the wrong length\"\n",
+    "assert len(X_val) == 4,   \"The 'x_val' vector has the wrong length\"\n",
+    "assert len(y_val) == 4, \"The 'y_val' vector has the wrong length\"\n",
+    "print('Sanity checks passed!')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "f8df093e1a147e9f2343622e6215fbab",
+     "grade": false,
+     "grade_id": "cell-428dadef568d5aef",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='trainValErrorsfunction'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<b>Student Task.</b> Compute Training and Validation Error. \n",
+    "\n",
+    "**(1)** Complete the function `get_train_val_errors(X_train, X_val, y_train, y_val, n_features)` that returns the training error and validation error for each choice of $r=1,\\ldots,n$. Please use `fit_intercept=False`. The training errors should be stored in a numpy array `err_train` of shape (n,1) and the validation errors should be stored in the numpy array `err_val` of shape (n,1). The first entries of `err_train` and `err_val` should be $E_{\\rm train}(1)$ and $E_{\\rm val}(1)$. \n",
+    "\n",
+    "**(2)** Complete the function `get_best_model(err_val)`, that takes as input the validation errors `err_val` for each number of features $r=1,\\ldots,n$ and returns the optimum number $\\hat{r}$ of features (such that the validation error is smallest). \n",
+    "\n",
+    "Hint: you can determine the index of the smallest entry in a numpy array using `np.argmin()` ([see documentation](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.argmin.html)).\n",
+    "\n",
+    "**IMPORTANT!**: Remember that indexing for numpy arrays starts with index 0. However, we start with model size $r=1$. Thus, you need to add 1 to the index that you get by using `np.argmin()`.\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "err_train, err_val = get_train_val_errors(X_train, X_val, y_train, y_val, n)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "e721ab656b8ec082e644cd360ff37bd3",
+     "grade": false,
+     "grade_id": "cell-7791084dee96529b",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def get_train_val_errors(X_train, X_val, y_train, y_val, n_features):  \n",
+    "    err_train = np.zeros((n,1))    # Array for storing training errors\n",
+    "    err_val = np.zeros((n,1))    # Array for storing validation errors\n",
+    "    \n",
+    "    for r_minus_1 in range(n_features):    # Loop over the number of features r (minus one)\n",
+    "        ### STUDENT TASK ###\n",
+    "        # YOUR CODE HERE\n",
+    "        reg = LinearRegression(fit_intercept=False)    # create an object for linear predictors\n",
+    "        reg = reg.fit(X_train[:,:(r_minus_1 + 1)], y_train)    # find best linear predictor (minimize training error)-\n",
+    "        pred_train = reg.predict(X_train[:,:(r_minus_1 + 1)])    # compute predictions of best predictors \n",
+    "        err_train[r_minus_1] = mean_squared_error(y_train, pred_train)    # compute training error \n",
+    "        \n",
+    "        pred_val = reg.predict(X_val[:,:(r_minus_1 + 1)])\n",
+    "        err_val[r_minus_1] = mean_squared_error(y_val, pred_val)    # compute training error \n",
+    "        \n",
+    "        \n",
+    "    return err_train, err_val\n",
+    "\n",
+    "def get_best_model(err_val):\n",
+    "    # best_model = ...\n",
+    "    # YOUR CODE HERE\n",
+    "    \n",
+    "    best_model = np.argmin(err_val)+1\n",
+    "    \n",
+    "    return best_model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "c3338cb97a87fedb7ee3205a32185fff",
+     "grade": true,
+     "grade_id": "cell-c1430b345ba97bfc",
+     "locked": true,
+     "points": 3,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Sanity checks passed!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Calculate training and validation errors using ´get_train_val_errors´\n",
+    "err_train, err_val = get_train_val_errors(X_train, X_val, y_train, y_val, n)\n",
+    "\n",
+    "# Perform some sanity checks on the results\n",
+    "assert err_train.shape == (n,1), \"numpy array err_train has wrong shape\"\n",
+    "assert err_val.shape == (n,1), \"numpy array err_val has wrong shape\"\n",
+    "print('Sanity checks passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "5b9823f38844472bac91f8289b1f5533",
+     "grade": true,
+     "grade_id": "cell-b6e6c7e09a33407f",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The best model is obtained for r=2\n",
+      "Sanity checks passed!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Get the best model using `get_best_model`\n",
+    "best_model = get_best_model(err_val)\n",
+    "\n",
+    "# Print the best model\n",
+    "print('The best model is obtained for r={}'.format(best_model))\n",
+    "\n",
+    "# Perform some sanity checks on the result\n",
+    "assert best_model != None, \"Please choose a value between 1 and n \"\n",
+    "assert best_model <= n, \"The values should be less than n\"\n",
+    "assert best_model > 0, \"The values should be more than 0\"\n",
+    "print('Sanity checks passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "6af3da2252039d65e28bdc7259fcc3a5",
+     "grade": false,
+     "grade_id": "cell-802d3729eb036c9f",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "Next, we plot the training and validation errors from the previous task:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "0e67f4ab4b2bbb99c3b692d0247ae9a4",
+     "grade": false,
+     "grade_id": "cell-64473b41dbc92dfa",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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c8+FKVMgNRUefND38Cwp6tWDt96CRo38/KiLFoUdUYlSgt4pERERKVZbt0LXrjBrlp+5YOTIkjnlVOPG8PbbULs2nHkmLF8edkQlhhI3ERGR8mDDBvi///PNj88954ffKMmaN/fJW6VKcNppsGJF2BGVCErcREREyrrVq+GPf/Tzj86cCf37hx1RfFq29AMB//KLT96++y7siEKnxE1ERKQsW7bMTxb/ww8+CerePeyICua443yHhc2bffK2fn3YEYVKiZvkafPmzTRs2JAV+VRR9+3bl4ceeihJUYmISFw++cRPEL9vn5+DtFOnsCMqnHbt/Hl5338PZ5wBP/0UdkShUeJWBnTp0gUzy3Hp2bNnkbd977330qNHD373u9/ludyoUaO455572Lp1a5H3KSIiCfDOO9Clix9Q94MP4Pjjw46oaDp18s28X38N3brBtm1hRxQKJW5lwKJFi0hNTWXdunXZLs8//3yRtrtz504mTJjAoEGD8l22VatWHH744UyePLlI+xQRkQT4z398k2jz5j5pO+KIsCNKjNNOg5degsWLoWdP2LEj7IiSTolbIowZA/PmZS+bN8+XF7MVK1awZcsWTj31VBo1apTtUrt27SJte9asWVSoUIFOUVXrGRkZmBlTp06lS5cuVKtWjWeffZZevXoVOVkUEZEievpp6NPHTxb//vvQtGnYESXWWWf5Meg+/NCPR7d7d9gRJZUSt0Ro3x769fs1eZs3z99v377Yd52enk7FihVp27Ztwrc9f/582rVrh0WN8bN48WIA7r//fm644QaWLl1K79696dChAwsXLmTXrl0Jj0VEROLw0ENw2WW+ifStt+Dgg8OOqHj06+dne5g7F/70Jz8TRDlRAua3KIGuvdZXwxZEkyZ+UMPGjWHdOmjVCu6801/i0aYNPPxwgUNNT08nMzOTBg0aZCvv3r07L774YoG2tWrVKvr27UtaWhoAq1evpnHjxjmWW7JkCdWqVePFF1/kiIjq9yZNmrB3717Wrl2b7zlxIiKSQM7Bbbf5mRD69PE1UlWrhh1V8brkEti5E4YO9dN3TZ4MFSuGHVWxU+KWKHXr+qRtzRo49FB/PwnS09Pp06cPo0ePzlb+m9/8psjb3rVrFw0bNsxRvnjxYnr06JEtaQOoXr36gfVERCRJMjPhqqvgiSdg0CB48slykcAA8Ne/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\n",
+      "text/plain": [
+       "<Figure size 720x432 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Plot the training and validation errors for the different number of features r\n",
+    "plt.figure(figsize=(10,6))\n",
+    "plt.plot(range(1, n + 1), err_train, color='black', label=r'$E_{\\rm train}(r)$', marker='o')  # Plot training error\n",
+    "plt.plot(range(1, n + 1), err_val, color='red', label=r'$E_{\\rm val}(r)$', marker='x')  # Plot validation error\n",
+    "\n",
+    "plt.title('Training and validation error for different number of features', fontsize=16)    # Set title\n",
+    "plt.ylabel('Empirical error')    # Set label for y-axis\n",
+    "plt.xlabel('r features')    # Set label for x-axis\n",
+    "plt.xticks(range(1, n + 1))  # Set the tick labels on the x-axis to be 1,...,n\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "663071219152effb81995c26bf1df8fc",
+     "grade": false,
+     "grade_id": "cell-61ecf20008a16c4b",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "From the figure, we see that the training error is monotonically decreasing with an increasing number $r$ of features used in the linear predictor $h(\\mathbf{x}) = w_{1}x_{1}+\\ldots+w_{r}x_{r}$. However, the validation error is first decreasing but then rapidly increases for larger values of $r$. It is clear that the training error can be very misleading as a measure for prediction error on new data for large values of $r$, which correspond to more complex models.\n",
+    "\n",
+    "Some questions arise when observing the above figure. How come the validation error is lower than the training error when $r < 5$, and why does the validation error drop for $r=10$ features? \n",
+    "\n",
+    "The reason for these apparent anomalies turns out to be pure randomness. Using only a single split of the data into training and validation set bears the risk of being extremely \"unlucky\", in the sense that the single split might result in a highly non-typical validation set such that the validation error is not a reliable measure for the average error on new data. This problem is particularly prevalent when using small datasets, such as in this exercise ($m=20$).\n",
+    "\n",
+    "In our case, the validation set happens to fit the optimal predictors for $r < 5$ too well by chance. As a result, the resulting validation errors are unrealistically low and do not give a reliable estimate of the error of the model on new data. Equally well, we could have obtained a validation set that gives excessively high validation errors and therefore pessimistic estimates of the generalization capabilities of the model. \n",
+    "\n",
+    "Next we will consider $K$-fold cross-validation, which is a straightforward extension to the \"single-split approach\" that increases the robustness of the validation error. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true,
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "00310778b648361001210c42980baa2f",
+     "grade": false,
+     "grade_id": "cell-a417d9495eb3f40e",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## K-fold Cross-Validation\n",
+    "\n",
+    "In general, there is no unique optimal way of splitting a data set into a training and validation set. The precise choice of how to divide data points into the training and validation set and also their relative size (80/20, 50/50 ...) has to be considered case-by-case for the application at hand. \n",
+    "\n",
+    "To get more guidance on how to split the data, one typically needs to have additional knowledge about the statistical properties of the data generating process. An accurate probabilistic model for the data points allows determining optimal split ratios between the training and validation set. That said, probabilistic (generative) models for the observed data points is beyond the scope of this course. \n",
+    "\n",
+    "$K$-fold cross-validation randomly splits the data into $K$ equal-sized subsets (\"folds\"). It then executes $K$ rounds, each round corresponding to one of the $K$ folds. In the $k$th round, the $k$th fold is used as the validation set and the remaining $K-1$ folds are used as the training set. The validation errors obtained during each fold are then averaged to obtain the final validation error. \n",
+    "\n",
+    "As an example, a diagram of  5-fold cross-validation is depicted below. For each round, the fold which is used as the validation set is indicated by \"test\". \n",
+    "\n",
+    "![Components](cross_validation_diagram.png)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "0d2a2cb40e2fa7caee5d478d3522f1d4",
+     "grade": false,
+     "grade_id": "cell-b9348b815d7f7519",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='kfold'></a>\n",
+    "<div class=\" alert alert-info\">\n",
+    "<p><b>Demo.</b> Splitting data into K-folds in sklearn.</p>\n",
+    "    \n",
+    "The code snippet below shows how to use a `KFold` object in scikit-learn to iterate through `K` train/validation splits of the dataset `X`.\n",
+    "    \n",
+    "On initialization the `KFold` object is given the number of data splits `K` as an argument to the parameter `n_splits`. The Python [generator function](https://docs.python.org/3.8/glossary.html#term-generator) `KFold.split(X)` can then be used to iterate through the pairs of training and validation indices. \n",
+    "\n",
+    "For an array `idx` of indices, the data points in X corresponding to these indices can be obtained by `X[idx,:]`. We can use this to obtain the training and validation sets given the indices of the datapoints in the respective sets.\n",
+    "\n",
+    "For more information, see the scikit-learn [documentation of KFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html).\n",
+    "</div>  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Iteration 1:\n",
+      "Indices for validation set: [0 1 2 3]\n",
+      "Indices for training set: [ 4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]\n",
+      "X_val shape: (4, 10), X_train shape: (16, 10) \n",
+      "\n",
+      "Iteration 2:\n",
+      "Indices for validation set: [4 5 6 7]\n",
+      "Indices for training set: [ 0  1  2  3  8  9 10 11 12 13 14 15 16 17 18 19]\n",
+      "X_val shape: (4, 10), X_train shape: (16, 10) \n",
+      "\n",
+      "Iteration 3:\n",
+      "Indices for validation set: [ 8  9 10 11]\n",
+      "Indices for training set: [ 0  1  2  3  4  5  6  7 12 13 14 15 16 17 18 19]\n",
+      "X_val shape: (4, 10), X_train shape: (16, 10) \n",
+      "\n",
+      "Iteration 4:\n",
+      "Indices for validation set: [12 13 14 15]\n",
+      "Indices for training set: [ 0  1  2  3  4  5  6  7  8  9 10 11 16 17 18 19]\n",
+      "X_val shape: (4, 10), X_train shape: (16, 10) \n",
+      "\n",
+      "Iteration 5:\n",
+      "Indices for validation set: [16 17 18 19]\n",
+      "Indices for training set: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15]\n",
+      "X_val shape: (4, 10), X_train shape: (16, 10) \n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Import KFold class from scikitlearn library\n",
+    "from sklearn.model_selection import KFold\n",
+    "\n",
+    "K=5    # Specify the number of folds of split data into\n",
+    "kf = KFold(n_splits=K, shuffle=False)    # Create a KFold object with 'K' splits\n",
+    "\n",
+    "# For all splits, print the validation and training indices\n",
+    "iteration = 0\n",
+    "for train_indices, test_indices in kf.split(X):\n",
+    "    iteration += 1\n",
+    "    X_train = X[train_indices,:]    # Get the training set    \n",
+    "    X_val = X[test_indices,:]    # Get the validation set\n",
+    "    print('Iteration {}:'.format(iteration))\n",
+    "    print('Indices for validation set:', test_indices)\n",
+    "    print('Indices for training set:', train_indices)\n",
+    "    print('X_val shape: {}, X_train shape: {} \\n'.format(X_val.shape, X_train.shape))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "36d5fe621e7ea1cbe13cf3d4b79fecb0",
+     "grade": false,
+     "grade_id": "cell-13d40bbc019a9337",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='kfold'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<p><b>Student task.</b> 5-Fold Cross Validation.</p>\n",
+    "     \n",
+    "The purpose of the code snippet below is to compute the training and validation errors for each choice of $r=1,\\ldots,n$ using 5-fold cross-validation. Your task is to complete the part of the loop that performs 5-fold cross-validation using the `KFold` class in scikit-learn. For each $r$ you should\n",
+    "    \n",
+    "1. Iterate over the `K` pairs of train and test indices and for each pair, calculate the training and validation errors of a linear regression model (with `fit_intercept=False`) and store them in  `train_errors_per_cv_iteration` and `test_errors_per_cv_iteration` respectively.\n",
+    "    \n",
+    "    \n",
+    "2. Calculate the average training- and validation errors and store these at index `r_minus_1` in the arrays `err_train` and `err_val` (both of shape $(n, )$) respectively.\n",
+    "\n",
+    "For more information, see the scikit-learn [documentation of KFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html).\n",
+    "\n",
+    "Afterwards, the training- and validation errors are plotted for comparison with the errors from the previous student task.\n",
+    "\n",
+    "</div>  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "40f4c6f7f953fe0fbae5de1fc5b7e5ec",
+     "grade": false,
+     "grade_id": "cell-2c1e9a0779d74d86",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "m = 20    # we use the first m=20 data points (pixels) from the aerial photo \n",
+    "n = 10\n",
+    "\n",
+    "X, y = GetFeaturesLabels(m,n)  # read in m data points with n features \n",
+    "\n",
+    "err_train = np.zeros(n)  # Array to store training errors\n",
+    "err_val = np.zeros(n)  # Array to store validation errors\n",
+    "\n",
+    "K = 5\n",
+    "kf = KFold(n_splits=K, shuffle=False)    # Create a KFold object with 'K' splits\n",
+    "\n",
+    "for r_minus_1 in range(n):\n",
+    "    train_errors_per_cv_iteration = []  # List for storing the training errors for the splits\n",
+    "    val_errors_per_cv_iteration = []  # List for storing the validation errors for the splits\n",
+    "    \n",
+    "    ### STUDENT TASK ###\n",
+    "    # YOUR CODE HERE\n",
+    "    \n",
+    "    \n",
+    "print('Training errors for each K:')\n",
+    "print(err_train, '\\n')\n",
+    "print('Validation error for each K:')\n",
+    "print(err_val, '\\n')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "e12b3bd59c834ecd7d8e60b06f5c8ca0",
+     "grade": true,
+     "grade_id": "cell-5bc4c8b664e0ce92",
+     "locked": true,
+     "points": 3,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Perform sanity checks on the outputs\n",
+    "assert err_train.shape == (n,), \"err_train is of the wrong shape!\"\n",
+    "assert err_val.shape == (n,), \"err_val is of the wrong shape!\"\n",
+    "assert err_val[0] < err_val[1], \"The second element of err_val should be larger than the first element!\"\n",
+    "\n",
+    "print(\"Sanity checks passed!\")\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "3243d66147d2e0dfced05eb1ff5df57c",
+     "grade": false,
+     "grade_id": "cell-9a20c7f588fbbb63",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Plot the training and validation errors for the different number of features r\n",
+    "plt.figure(figsize=(10,6))\n",
+    "plt.plot(range(1, n+1), err_train, color='black', label=r'$E_{\\rm train}(r)$', marker='o')  # Plot training error\n",
+    "plt.plot(range(1, n+1), err_val, color='red', label=r'$E_{\\rm val}(r)$', marker='x')  # Plot validation error\n",
+    "\n",
+    "plt.title('5-fold training and validation errors for different number of features', fontsize=16)    # Set title\n",
+    "plt.ylabel('Empirical error')    # Set label for y-axis\n",
+    "plt.xlabel('r features')    # Set label for x-axis\n",
+    "plt.xticks(range(1, n + 1))  # Set the tick labels on the x-axis to be 1,...,n\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "3be984bff94cf711853090b640a49953",
+     "grade": false,
+     "grade_id": "cell-12f1478400587745",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "If we compare the figure above to the one in the previous student task, we can see that the validation error obtained by 5-fold cross-validation seems to provide a more realistic estimate of the performance of the model on new data. The validation error is now consistently larger than the training error, and the rising trend of the validation error seems slightly smoother.\n",
+    "\n",
+    "In practice, it is almost always preferable to use K-fold cross-validation instead of a single validation split for model validation and selection due to the increased robustness of the validation error."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "75ced8bad0618ba563d24b85b69eb79a",
+     "grade": false,
+     "grade_id": "cell-a451b1c380ed82da",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "##  Regularization\n",
+    "\n",
+    "Consider a ML method based on a large hypothesis space such as linear predictors using many features or polynomials with a large degree. Large hypothesis spaces typically contain complex predictors that achieve very low training errors by overfitting the data. Thus, if we search for the optimal predictor in this hypothesis space (i.e train our model) by minimizing the training error, we will obtain a predictor that overfits the training data and  generalizes poorly to data that is not in the training set.\n",
+    "\n",
+    "One solution to prevent overfitting is to choose a model out of a selection of candidate models based on the validation error, like we did in the student task \"Compute Training and Validation Error\". By using the validation error as the selection criteria, we are able to select the model that performs best on new data. While this approach is useful, it can be very difficult to implement in settings where the number of feasible hypothesis spaces is very large.\n",
+    "\n",
+    "**Regularization** is a more sophisticated approach to prevent overfitting, and is based on the idea of **estimating the expected increase of the validation error (relative to the training error) incurred by more complex predictors**. When applying regularization, a large hypothesis space is used in conjunction with a loss function that penalizes the complexity of the predictor. If we recall that the optimal predictor is found by minimizing the loss function, it is clear that by choosing a loss function that penalizes complexity, the optimal predictor will be less complex. In practice, the penalization is done by adding a **regularization term** $\\mathcal{R}(h)$ to the training error: \n",
+    "\n",
+    "\\begin{equation}\n",
+    "h^{(\\lambda)}_{\\rm opt}  = {\\rm argmin}_{h \\in \\mathcal{H}} \\underbrace{\\underbrace{(1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h(\\mathbf{x}^{(i)}) \\big)^{2}}_{\\mbox{ training error}} + \\underbrace{\\alpha \\mathcal{R}(h)}_{\\mbox{anticipated increase of error (loss) on new data}}}_{\\mbox{ estimate (approximation) of validation error }}.  \n",
+    "\\end{equation}\n",
+    "\n",
+    "The regularization term $\\mathcal{R}(h)$ quantifies the anticipated increase in the validation error (compared to the training error) due to the \"complexity\" (e.g. the number of features used in a linear predictor) of a particular predictor. In a nutshell, the regularization term penalizes the use of more complex predictors and therefore favors \"simpler\" predictor functions. The precise meaning of \"complexity\" or \"simpler\" is determined by the (design) choice for the regularization term $\\mathcal{R}(h)$. \n",
+    "\n",
+    "Two widely used choices for measuring the complexity of linear predictors $h(\\mathbf{x}) = \\mathbf{w}^{T}\\mathbf{x}$ is the squared Euclidean norm $\\mathcal{R}(h) = \\|\\mathbf{w}\\|^{2}_{2}=\\sum_{r=1}^{n} w_{r}^{2}$ or the $\\ell_{1}$ norm $\\mathcal{R}(h) = \\|\\mathbf{w}\\|_{1}=\\sum_{r=1}^{n} |w_{r}|$. \n",
+    "\n",
+    "The regularization parameter $\\alpha$ **offers a trade-off between the prediction error (training error) incurred on the training data and the complexity of a predictor**. The larger we choose $\\alpha$, the more emphasis is put on obtaining \"simple\" predictor functions. Using very small values for $\\alpha$ prefers predictor functions which achieve a small training error (at the expense of being a more complicated function).\n",
+    "\n",
+    "In order to actually implement regularization, we need to \n",
+    "- choose (define) the function $\\mathcal{R}(h)$ that quantifies some notion of complexity of a predictor function $h \\in \\mathcal{H}^{(n)}$. \n",
+    "- choose the value of the regularization parameter $\\alpha$. \n",
+    "\n",
+    "A principled approach to these choices is to assume a probabilistic model for how the data points are generated. It is then possible to relate optimal choices for the function $\\mathcal{R}(h)$ and the value $\\alpha$ to the parameters of the probability distribution of the data points. However, probabilistic modelling in machine learning is beyond the scope of this course. \n",
+    "\n",
+    "Instead of probabilistic modelling, we can use again the concept of validation sets to find good choices for the regularization function and parameter. In particular, \n",
+    "- we first specify a set of different choices for the function $\\mathcal{R}(h)$ and regularization parameter value $\\alpha$, \n",
+    "- for each choice for $\\alpha$ and $\\mathcal{R}(h)$, we learn a predictor that minimizes the regularized training error \n",
+    "\n",
+    "\\begin{equation}\n",
+    "h^{(\\alpha)}_{\\rm opt}  = {\\rm argmin}_{h \\in \\mathcal{H}} (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h(\\mathbf{x}^{(i)}) \\big)^{2} + \\alpha \\mathcal{R}(h).    \n",
+    "\\end{equation}\n",
+    "- evaluate the resulting predictor $h^{(\\alpha)}_{\\rm opt}$ by computing the validation error\n",
+    "\\begin{equation}\n",
+    "E_{\\rm val}^{(\\alpha)} = (1/m_{\\rm v}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(v)}} \\big(y^{(i)} - h^{(\\alpha)}_{\\rm opt}(\\mathbf{x}^{(i)})\\big)^{2}.\n",
+    "\\end{equation} \n",
+    "\n",
+    "We then use the regularization measure $\\mathcal{R}(h)$ and the value for $\\alpha$ with smallest validation error $E_{\\rm val}^{(\\alpha)}$. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "a94c08a6baafd3f077d13a2f8fd6f0e0",
+     "grade": false,
+     "grade_id": "cell-a697f48e6cf7e933",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='ridgeReg'></a>\n",
+    "<div class=\" alert alert-info\">\n",
+    "<p><b>Demo.</b> Ridge Regression. </p>\n",
+    "\n",
+    "Ridge regression learns a linear predictor functions $h^{(\\mathbf{w})}(\\mathbf{x}) =\\mathbf{w}^{T} \\mathbf{x}$ by minimizing the sum of training error and the scaled regularization term $\\mathcal{R}(h)=\\|\\mathbf{w}\\|_{2}^{2}$. A ridge regression model can be fitted to a dataset with scikit-learn by using the function `Ridge.fit()`. After fitting the model, the optimal weight vector $\\mathbf{w}_{\\rm opt}$ is stored in the attribute `Ridge.coef_` of the `Ridge` instance. \n",
+    "\n",
+    "[See documentation of Ridge](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html)\n",
+    "\n",
+    "</div>  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "c07e7cd6607a3005b486d3d866403ee2",
+     "grade": false,
+     "grade_id": "cell-ef05953e6a07a985",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "from sklearn.linear_model import Ridge\n",
+    "\n",
+    "m = 20\n",
+    "n = 10\n",
+    "X, y = GetFeaturesLabels(m, n)\n",
+    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2)  # 80% training and 20% test\n",
+    "\n",
+    "alpha = 10    # Define value of the regularization parameter 'alpha'\n",
+    "\n",
+    "ridge = Ridge(alpha=alpha, fit_intercept=False)    # Create Ridge regression model\n",
+    "ridge.fit(X_train, y_train)    # Fit the Ridge regression model on the training set\n",
+    "y_pred = ridge.predict(X_train)    # Predict the labels of the training set\n",
+    "w_opt = ridge.coef_    # Get the optimal weights (regression coefficients) of the fitted model\n",
+    "err_train = mean_squared_error(y_pred, y_train)    # Calculate the training error\n",
+    "\n",
+    "# Print optimal weights and training error\n",
+    "print('Optimal weights: \\n', w_opt)\n",
+    "print('Training error: \\n', err_train)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "26f505666ea32a6dbd6bc528841eae2f",
+     "grade": false,
+     "grade_id": "cell-81a742e0f9b6ebf9",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "**The Lasso** is another regularized regression method, which regularizes the training error of linear predictors $h(\\mathbf{x}) = \\mathbf{w}^{T} \\mathbf{x}$ with the complexity measure $\\mathcal{R}(h)= \\|\\mathbf{w}\\|_{1}$. In Lasso regression, it is customary to use a regularized loss function where the training error term is multiplied by $1/2$. That is,\n",
+    "\n",
+    "\\begin{equation}\n",
+    "\\mathcal{E}(\\textbf{w}) = \\frac{1}{2m_t} \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h(\\mathbf{x}^{(i)}) \\big)^{2} + \\alpha |\\textbf{w}|.\n",
+    "\\end{equation}\n",
+    "\n",
+    "Since $\\alpha$ can be freely chosen, the multiplicative constant is of no practical importance and is only included in order to make analytical calculations more convenient. Still, the exact form of the loss function is important knowledge since this loss function is typically used in Lasso implementations, incuding the one in scikit-learn."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "657de5e3b1f82b23a255db435831a658",
+     "grade": false,
+     "grade_id": "cell-b63b8bd46646688d",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='lassoReg'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<b>Student Task.</b> Lasso Regression.\n",
+    "\n",
+    "Complete the function `fit_lasso` that uses the Scikit-learn function `Lasso.fit()` to compute the optimal predictor for $\\alpha=$ `alpha_val`. When initializing Lasso, please use `fit_intercept=False`. This function is then used find the optimal Lasso predictor for $\\alpha = 10$.\n",
+    "\n",
+    "[Documentation for Lasso in Scikit-learn](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html)\n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "2e16895b4a609c7e3c274e2a3a28c31f",
+     "grade": false,
+     "grade_id": "cell-b6cd24ae92c6b545",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "from sklearn.linear_model import Lasso\n",
+    "\n",
+    "X,y = GetFeaturesLabels(m,n)    # read in m data points using n features \n",
+    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2)    # 80% training and 20% test\n",
+    "\n",
+    "def fit_lasso(X_train, y_train, alpha_val):\n",
+    "    ### STUDENT TASK ###\n",
+    "    # .\n",
+    "    # .\n",
+    "    # .\n",
+    "    # w_opt = ...\n",
+    "    # training_error = ...\n",
+    "    # YOUR CODE HERE\n",
+    "    raise NotImplementedError()\n",
+    "    return w_opt, training_error"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "28907e52675b27f5ef57e63857189df8",
+     "grade": true,
+     "grade_id": "cell-44c7f2c09ba11e52",
+     "locked": true,
+     "points": 3,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Set alpha value\n",
+    "alpha_val = 10\n",
+    "\n",
+    "# Fit Lasso and calculate optimal weights and training error using the function 'fit_lasso'\n",
+    "w_opt, training_error = fit_lasso(X_train, y_train, alpha_val)\n",
+    "\n",
+    "# Print optimal weights and the corresponding training error\n",
+    "print('Optimal weights: \\n', w_opt)\n",
+    "print('Training error: \\n', training_error)\n",
+    "\n",
+    "# Perform some sanity checks on the outputs\n",
+    "from sklearn.linear_model import Lasso\n",
+    "assert w_opt.reshape(-1,1).shape == (10,1), \"'w_opt' has wrong shape\"\n",
+    "assert np.isscalar(training_error), \"'training_error' is not scalar\"\n",
+    "assert training_error < 1000, \"'training_error' is too large\"\n",
+    "print('Sanity check tests passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "f9ab2d112f80e6c54503744bfb8a1eb8",
+     "grade": false,
+     "grade_id": "cell-1355f27ba4fd6ca5",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "When using Lasso or ridge regression, we need to find a suitable value for the regularization parameter $\\alpha$. A simple but useful approach is **grid search**: We first specify a list of values to be used for the regularization parameter. For each value $\\alpha$, we determine a predictor $h^{(\\alpha)}$ by minimizing the regularized training error: \n",
+    "\\begin{equation}\n",
+    "h^{(\\alpha)}  = {\\rm argmin}_{h \\in \\mathcal{H}} (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h(\\mathbf{x}^{(i)}) \\big)^{2} + \\alpha \\mathcal{R}(h).    \n",
+    "\\end{equation}\n",
+    "The resulting training error is \n",
+    "\\begin{equation} \n",
+    "E_{\\rm train}(\\alpha) = (1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h^{(\\alpha)}(\\mathbf{x}^{(i)}) \\big)^{2}. \n",
+    "\\end{equation}\n",
+    "Note that the training error $E_{\\rm train}(\\alpha)$ is measured on the training data $\\mathbb{X}^{t}$ which was also used to tune the predictor $h^{(\\alpha)}$ (in the above opimtization problem). Therefore, $E_{\\rm train}(\\alpha)$ is too optimistic as a measure for the average error of $h^{(\\alpha)}$ on new data points. Instead, we will measure the quality of $h^{(\\alpha)}$ via the validation error  \n",
+    "\\begin{equation} \n",
+    "E_{\\rm val}(\\alpha) = (1/m_{v}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(v)}} \\big(y^{(i)} - h^{(\\alpha)}(\\mathbf{x}^{(i)}) \\big)^{2} \n",
+    "\\end{equation}\n",
+    "incurred by the predictor $h^{(\\alpha)}$ on the validation set $\\mathbb{X}^{(v)}$. We then choose the value $\\alpha$ resulting in the smallest validation error $E_{\\rm val}(\\alpha)$. This grid search can be computationally expensive since we have to solve a separate optimization problem (of minimizing the regularized training error) for each value of $\\alpha$. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "2696c4ac17e5ef0949629909c8056560",
+     "grade": false,
+     "grade_id": "cell-8e4d019532f4bff3",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='lassoParameter'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<b>Student Task.</b> Tuning Lasso Parameter.\n",
+    "    \n",
+    "Complete the function `lasso_param_search` that computes the Lasso estimator $h^{(\\alpha)}$ for each value $\\alpha$ in the input parameter `alpha_values`. The function returns the resulting validation errors $E_{\\rm val}(\\alpha^{(i)})$ and training errors $E_{\\rm train}(\\alpha^{(i)})$ in the numpy arrays `err_val` of shape (`n_values`,1) and `err_train` of shape (`n_values`,1), as well as the weight vector of the optimal model with the optimal alpha $\\hat{\\alpha}$ (yielding the smallest validation error) in the variable `w_opt`. In the error arrays, the first entry `err_val[0]` should be $E_{\\rm val}(\\alpha^{(1)})$, and so on. \n",
+    "* `Use fit_intercept = false`\n",
+    "* [scikit-learn function for Lasso](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html) \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "68ff8235ffe0abd1fccf5ab36cc2dd0b",
+     "grade": false,
+     "grade_id": "cell-ef618671a3220a4f",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def lasso_param_search(X_train, X_val, y_train, y_val, alpha_values):\n",
+    "    n_values = len(alpha_values)    # The number of candidate values for 'alpha'\n",
+    "    err_train = np.zeros([n_values,1])    # Array for training errors\n",
+    "    err_val = np.zeros([n_values,1])    # Array for validation errors\n",
+    "    \n",
+    "    ### STUDENT TASK ###\n",
+    "    # Pseudocode:\n",
+    "    # -For each alpha in alpha_values:\n",
+    "    #   -fit a lasso model on the training data\n",
+    "    #   -calculate and store training and validation errors\n",
+    "    # -Find the best alpha (i.e. the one with the lowest validation error)\n",
+    "    # -Calculate/retrieve the optimal weights (coefficients) corresponding to this alpha\n",
+    "    # YOUR CODE HERE\n",
+    "    raise NotImplementedError()\n",
+    "    return w_opt, err_train, err_val"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "a65a9043742178acf9a0b7c658bf394a",
+     "grade": true,
+     "grade_id": "cell-b3b01a65b2b8c214",
+     "locked": true,
+     "points": 3,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Specify a list of values for alpha to be considered\n",
+    "alpha_values = np.array([0.01, 0.05, 0.2, 1, 3, 10, 1e2, 1e3, 1e4])\n",
+    "\n",
+    "# Calculate the optimal weights, and training and validation errors for the alpha values defined above using lasso_param_search\n",
+    "w_opt, err_train, err_val = lasso_param_search(X_train, X_val, y_train, y_val, alpha_values)\n",
+    "\n",
+    "# Perform some sanity checks on the outputs\n",
+    "assert w_opt.reshape(-1,1).shape == (10,1), \"'w_opts' has wrong shape\"\n",
+    "assert len(err_train) == 9, \"'err_train' has wrong shape\"\n",
+    "assert len(err_val) == 9, \"'err_val' has wrong shape\"\n",
+    "print('Sanity check tests passed!')\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "6d8ea5ab252c2c2baadff1464f116cff",
+     "grade": false,
+     "grade_id": "cell-535f1b0a4667461c",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Plot the training and validation errors\n",
+    "plt.figure(figsize=(10,6))    # Set figure size\n",
+    "plt.plot(alpha_values, err_train, marker='o', color='black', label='training error')    # Plot training errors\n",
+    "plt.plot(alpha_values, err_val, marker='o', color='red', label='validation error')    # Plot validation errors\n",
+    "plt.xscale('log')    # Set x-axis to logarithmic scale\n",
+    "plt.xlabel(r'$\\alpha$')    # Set label of x-axis\n",
+    "plt.ylabel(r'$E(\\alpha)$')    # Set label of y-axis\n",
+    "plt.title(r'Errors with respect to $\\alpha$', fontsize=16)    # Set title\n",
+    "plt.legend()    # Show legend\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "5e28156b082848665ce85b3c1cf1027a",
+     "grade": false,
+     "grade_id": "cell-25e8202490edf5af",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "## Take Home Quiz\n",
+    "\n",
+    "Answer the following questions by setting, for each question, the variable `answer_R4_Q??` to the index of the correct answer. E.g. if you think that the second answer in the first quiz question is the right one, then set `answer_R4_Q1=2`. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "4b201ec0c4030b83ce8feeb89b5e4773",
+     "grade": false,
+     "grade_id": "cell-30fe04a19dab009c",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='QuestionR4_1'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<p><b>Student Task.</b> Question R4.1. </p>\n",
+    "\n",
+    "<p>What is the goal of model selection in machine learning?</p>\n",
+    "\n",
+    "<ol>\n",
+    "  <li> To choose (learn) the optimal predictor function $h_{\\rm opt}$ out of a given hypothesis space (model) $\\mathcal{H}$.</li>\n",
+    "  <li> To select the most suitable car model using machine learning methods.</li>\n",
+    "  <li> To select the optimal weights used for regularization.</li>\n",
+    "  <li> To select the best hypothesis space out of a set of candidates $\\lbrace \\mathcal{H}^{(1)}, \\mathcal{H}^{(2)}, \\ldots,\\mathcal{H}^{(n)} \\rbrace$.</li>\n",
+    "</ol> \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "85a2d03581c9e80d6f103a56b137e7d3",
+     "grade": false,
+     "grade_id": "cell-01dd62184f9f57d9",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# answer_R4_Q1  = ...\n",
+    "# YOUR CODE HERE\n",
+    "answer_R4_Q1  = 4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "03f83e12c8ac3efccb733e4d69228ea9",
+     "grade": true,
+     "grade_id": "cell-b0c15dcdd6f57af7",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Sanity check tests passed!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# this cell is for tests\n",
+    "assert answer_R4_Q1 in [1,2,3,4], '\"answer_R4_Q1\" Value should be an integer between 1 and 4.'\n",
+    "print('Sanity check tests passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "873752d871b907e20f3e445bba9e81db",
+     "grade": false,
+     "grade_id": "cell-2d849c30b77c3a9d",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='QuestionR4_2'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<p><b>Student Task.</b> Question R4.2. </p>\n",
+    "\n",
+    "<p>What is a good measure for the prediction error (loss) incurred by a predictor function $h(\\mathbf{x})$ on new data points?</p>\n",
+    "<ol>\n",
+    "  <li> The empirical error (average loss) of $h(\\mathbf{x})$ on the <b>training set</b> which is also used to tune $h(\\mathbf{x})$. </li>\n",
+    "  <li> The empirical error (average loss) of $h(\\mathbf{x})$ on some <b>validation set</b> which is different from the training set. \n",
+    "</ol> \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "1692238b3fabbad6a8bcf5a745905c4b",
+     "grade": false,
+     "grade_id": "cell-786b53bfbed054d1",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# answer_R4_Q2  = ...\n",
+    "# YOUR CODE HERE\n",
+    "answer_R4_Q2  = 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "b74b7d8d11e904404f430a515ae75fa0",
+     "grade": true,
+     "grade_id": "cell-fcd79fc73255e27d",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Sanity check tests passed!\n"
+     ]
+    }
+   ],
+   "source": [
+    "# this cell is for tests\n",
+    "assert answer_R4_Q2 in [1,2], '\"answer_R4_Q2\" Value should be an integer between 1 and 2.'\n",
+    "print('Sanity check tests passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "171d8404ed8e7143c95222dbb5fb5752",
+     "grade": false,
+     "grade_id": "cell-e89debc2a73facf2",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='QuestionR4_3'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<p><b>Student Task.</b> Question R4.3. </p>\n",
+    "\n",
+    "Regularized linear regression amounts to finding the predictor $h(\\mathbf{x})$ which minimizes the regularized training error \n",
+    "\\begin{equation} \n",
+    "(1/m_{t}) \\sum_{\\big(\\mathbf{x}^{(i)},y^{(i)}\\big) \\in \\mathbb{X}^{(t)}} \\big(y^{(i)} - h(\\mathbf{x}^{(i)}) \\big)^{2} + \\alpha \\mathcal{R}(h).\n",
+    "\\end{equation}\n",
+    "Which statement is true?\n",
+    "\n",
+    "<ol>\n",
+    "  <li> Using a large value for the regularization parameter $\\alpha$ prefers predictors with large complexity $\\mathcal{R}(h)$ but small training error.</li>\n",
+    "  <li>  Using a small value for the regularization parameter $\\alpha$ prefers predictors with large complexity $\\mathcal{R}(h)$ but small training error.</li>\n",
+    "  <li> For regularization parameter $\\alpha=0$, the optimal predictor is always $h(\\mathbf{x}) =0$. </li>\n",
+    "  <li> For regularization parameter $\\alpha=0$, the optimal predictor is always $h(\\mathbf{x}) =42$.</li>\n",
+    "</ol> \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "5c0d6926a549d0c05836505477624fbd",
+     "grade": false,
+     "grade_id": "cell-8a7f812f9a71b8f3",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# answer_R4_Q3  = ...\n",
+    "# YOUR CODE HERE\n",
+    "raise NotImplementedError()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "630e26a571fe4dd9091ee325b6188054",
+     "grade": true,
+     "grade_id": "cell-530e6746dd4af06c",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# this cell is for tests\n",
+    "assert answer_R4_Q3 in [1,2,3,4], '\"answer_R4_Q3\" Value should be an integer between 1 and 4.'\n",
+    "print('Sanity check tests passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "markdown",
+     "checksum": "f7ad469aa93e7576beef79f298c8cf7c",
+     "grade": false,
+     "grade_id": "cell-2bd3fa9a8a8b2da9",
+     "locked": true,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "source": [
+    "<a id='QuestionR4_4'></a>\n",
+    "<div class=\" alert alert-warning\">\n",
+    "<p><b>Student Task.</b> Question R4.4. </p>\n",
+    "\n",
+    "Use the previously implemented code in \"Tuning Lasso Parameter\" to find the optimal predictor (lowest validation error) for $\\alpha=$ `alpha_val`. Using the same dataset.\n",
+    "When initializing Lasso, please use `fit_intercept=False`. \n",
+    "<p>Which alpha should be chosen to achieve an optimal predictor?</p> \n",
+    "<p>Possible alpha values are given in the code cell below.</p>\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "50e9f2b4ed75e58efc357f5b464e51ec",
+     "grade": false,
+     "grade_id": "cell-11392734fc803cfe",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "alpha_values = np.array([0.01, 0.05, 0.2, 1, 3, 10, 1e2, 1e3])\n",
+    "\n",
+    "# answer_R4_Q4  = ...\n",
+    "# YOUR CODE HERE\n",
+    "raise NotImplementedError()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "deletable": false,
+    "editable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "56b6d159e0d107274e4d78f86586373e",
+     "grade": true,
+     "grade_id": "cell-d7f48b684296863d",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# this cell is for tests\n",
+    "assert answer_R4_Q4 in [0.01, 0.05, 0.2, 1, 3, 10, 1e2, 1e3], 'answer_R4_Q3\" Value should be a value out of given alpha values..'\n",
+    "print('Sanity check tests passed!')\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.3"
+  },
+  "varInspector": {
+   "cols": {
+    "lenName": 16,
+    "lenType": 16,
+    "lenVar": 40
+   },
+   "kernels_config": {
+    "python": {
+     "delete_cmd_postfix": "",
+     "delete_cmd_prefix": "del ",
+     "library": "var_list.py",
+     "varRefreshCmd": "print(var_dic_list())"
+    },
+    "r": {
+     "delete_cmd_postfix": ") ",
+     "delete_cmd_prefix": "rm(",
+     "library": "var_list.r",
+     "varRefreshCmd": "cat(var_dic_list()) "
+    }
+   },
+   "types_to_exclude": [
+    "module",
+    "function",
+    "builtin_function_or_method",
+    "instance",
+    "_Feature"
+   ],
+   "window_display": false
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
-- 
GitLab