diff --git a/open-machine-learning-jupyter-book/ml-advanced/model-selection.ipynb b/open-machine-learning-jupyter-book/ml-advanced/model-selection.ipynb index f22e18baf..6b33475ae 100644 --- a/open-machine-learning-jupyter-book/ml-advanced/model-selection.ipynb +++ b/open-machine-learning-jupyter-book/ml-advanced/model-selection.ipynb @@ -49,7 +49,9 @@ "\n", "### Overview\n", "\n", - "Remember that the main objective of any machine learning model is to generalize the learning based on training data, so that it will be able to do predictions accurately on unknown data. As you can notice the words 'Overfitting' and 'Underfitting' are kind of opposite of the term 'Generalization'. Overfitting and underfitting models don't generalize well and results in poor performance.\n", + "Remember that the main objective of any machine learning model is to generalize the learning based on training data, so that it will be able to do predictions accurately on unknown data. Here are a few concepts: the first is 'Hypothesis', the second is 'Truth'. When we obtain data and train it, we propose a hypothesis, and the process of forcing the hypothesis to be as close to the truth as possible is our training process. This process is called 'fitting', which means the model tries to learn the patterns, relationships, or rules in the data in order to make predictions or classifications on unknown data. Due to the existence of errors in the hypothesis, we introduce the concepts of generalization error and empirical error (training error). The generalization error represents the error in unknown samples when we fit the model to the truth. It is uncertain. On the other hand, the empirical error represents the error on the training set, and it can be determined. In order to reduce the error and approach the truth, we need model evaluation. However, due to the occurrence of overfitting, a smaller error does not necessarily indicate a better model.\n", + "\n", + "As you can notice the words 'Overfitting' and 'Underfitting' are kind of opposite of the term 'Generalization'. Overfitting and underfitting models don't generalize well and results in poor performance.\n", "\n", "These are the samples of over-fitting and under-fitting in regression:\n", "\n", @@ -60,6 +62,14 @@ "Over-fitting and under-fitting in regression\n", ":::\n", "\n", + "During the fitting process, we have an important parameter called 'bias'. It refers to the deviation of the model from the true relationship when attempting to fit the data.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a657c169", + "metadata": {}, + "source": [ "### Underfitting\n", "\n", "* Underfitting occurs when machine learning model don't fit the training data well enough. It is usually caused by simple function that cannot capture the underlying trend in the data.\n", @@ -84,6 +94,7 @@ "* A good fitting model generalizes the learnings from training data and provide accurate predictions on new data\n", "* To get the good fitting model, keep training and testing the model till you get the minimum train and test error. Here important parameter is 'test error' because low train error may cause overfitting so always keep an eye on test error fluctuations. The sweet spot is just before the test error start to rise.\n", "\n", + "In summary the goal of model selection is to find a model that fits the training data well and has low prediction error on new unknown data. If a model that is too simple is chosen, it may not fit the training data well, resulting in underfitting. On the other hand, if a model that is too complex is chosen, overfitting may occur, leading to a decrease in predictive performance on new data.\n", "Now let's take a look at another example, hoping it will be helpful for your understanding.\n", "\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/classification.png\n", @@ -99,10 +110,10 @@ "id": "23a0cb84", "metadata": {}, "source": [ - "\n", "### A simple example of linear regression \n", "\n", "This is a simple graphical representation of linear regression training. \n", + "\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-datapoints.jpg\n", "---\n", "name: Datapoints-ms\n", @@ -110,50 +121,35 @@ "Training data points \n", ":::\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-overfitting.jpg\n", - "---\n", - "name: Over-fitting-train-ms\n", - "---\n", - "Over-fitting model fits very well on training data\n", - ":::\n", + "First we have some data points, then we're going to train it by linear regression.\n", "\n", + "**Over-fitting model**\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-overfitting-testdata.jpg\n", - "---\n", - "name: Over-fitting-test-ms\n", - "---\n", - "Over-fitting model fits poorly on test data \n", - ":::\n", + "| ![Over-fitting-train-ms](https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-overfitting.jpg) | ![Over-fitting-test-ms]( https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-overfitting-testdata.jpg) |\n", + "|:--:|:--:|\n", + "| Over-fitting-train-ms |  Over-fitting-test-ms |\n", "\n", + "As we can see, over-fitting model fits very well on training data, but over-fitting model fits poorly on test data. \n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-underfitting.jpg\n", - "---\n", - "name: Under-fitting-train-ms\n", - "---\n", - "Under-fitting model fits poorly on training data\n", - ":::\n", + "**Under-fitting model**\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-underfitting-test-data.jpg\n", - "---\n", - "name: Under-fitting-test-ms\n", - "---\n", - "Under-fitting model fits poorly on test data\n", - ":::\n", + "| ![Under-fitting-train-ms](https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-underfitting.jpg) | ![Under-fitting-test-ms]( https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-underfitting-test-data.jpg) |\n", + "|:--:|:--:|\n", + "| Under-fitting-train-ms |  Under-fitting-test-ms |\n", "\n", + "As for under-fitting model, it fits poorly on training data and test data.\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-perfect-fit.jpg\n", - "---\n", - "name: Perfect-fitting-train-ms\n", - "---\n", - "Perfect-fitting model fits well on training data\n", - ":::\n", + "**Perfect-fitting model**\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-perfect-fit-test-data.jpg\n", - "---\n", - "name: Perfect-fitting-test-ms\n", - "---\n", - "Perfect-fitting model fits well on test data\n", - ":::\n" + "After seeing the under-fitting model and the over-fitting model we are eager to know what is a good-fitting model.\n", + "\n", + "| ![Perfect-fitting-train-ms](https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-perfect-fit.jpg) | ![Perfect-fitting-test-ms]( https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/bias-variance-perfect-fit-test-data.jpg) |\n", + "|:--:|:--:|\n", + "| Perfect-fitting-train-ms |  Perfect-fitting-test-ms |\n", + "\n", + "Perfect-fitting model fits well on training data and test data!\n", + "\n", + "When over-fitting occurs, the model demonstrates high accuracy or low error on the training data but performs poorly on the testing data or new data in practical applications. In contrast, under-fitting indicates that the model is unable to capture the complex relationships or patterns within the data." ] }, { @@ -163,6 +159,15 @@ "source": [ "## Bias variance tradeoff\n", "\n", + "In this section we talk about Bias Variance tradeoff \n", + "\n", + "So what is Bias and Variance? Or to say why they are so importent in model selection? \n", + "\n", + "Bias refers to the model's incorrect assumptions or simplifications about the problem. When a model has high bias, it may overlook some key features or patterns in the data, resulting in systematic errors in the predictions. In other words, a high-bias model tends to produce incorrect predictions.\n", + "\n", + "Variance refers to the sensitivity or volatility of the model to the training data. When a model has high variance, it is very sensitive to small perturbations in the training data and may overfit the noise and details in the training data, leading to poor generalization to new data. In other words, a high-variance model is more prone to the influence of randomness and produces larger prediction errors.\n", + "\n", + "Here are some illustrations showing the relationship between bias and variance in data fitting.\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/graphicalillustration.png\n", "---\n", "name: graphicalillustration-ms\n", @@ -170,19 +175,209 @@ "Graphical illustration of variance and bias\n", ":::\n", "\n", - "\n", - "\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/total_error.png\n", "---\n", "name: Model-complexity-ms\n", "---\n", "Model complexity v.s. error\n", - ":::" + ":::\n" ] }, { "cell_type": "markdown", - "id": "b4f22209", + "id": "2f23ec03", + "metadata": {}, + "source": [ + "## Metrics\n", + "\n", + "Were there some ways that can be used to represent the bias and variance of a model?\n", + "\n", + "First, when we start training, how to evaluate the goodness of fit?\n", + "\n", + "The simplest way is to output some metrics that can substitute for bias and variance. Here are several metrics that can be used for calculation:\n", + "\n", + "**Accuracy**:Accuracy is a commonly used evaluation metric in classification models. It represents the proportion of correctly classified samples in the predictions made by the model. A higher accuracy indicates better performance. However, when there is class imbalance in the dataset, accuracy may underestimate the model's performance.\n", + "\n", + "**Precision and Recall**:Precision and recall are primarily used to evaluate the performance of binary classification models, especially in the presence of class imbalance. Precision represents the proportion of true positive samples among those predicted as positive, while recall represents the proportion of true positive samples among all actual positive samples. Precision and recall can help provide a comprehensive evaluation of the model's classification performance.\n", + "\n", + "**F1 Score**:The F1 score is the harmonic mean of precision and recall, providing a balanced assessment of a model's accuracy and recall performance. A higher F1 score indicates better performance.\n", + "\n", + "**Mean Squared Error (MSE)**:MSE is a commonly used evaluation metric in regression models. It represents the average of the squared differences between predicted values and true values. A smaller MSE indicates better performance.\n", + "\n", + "**Log Loss**: Log loss is commonly used in binary or multi-class probability prediction problems. It measures the difference between predicted probabilities and true labels. A lower log loss indicates better performance.\n", + "\n", + "These metrics are used to evaluate the performance of models in the model selection process. However, it's important to note that these metrics only reflect the fit of the model to a particular dataset and may not fully capture its generalization performance.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "82087a9b", + "metadata": {}, + "source": [ + "### Confusion matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c1fd3833", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAHHCAYAAAB3K7g2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABNzUlEQVR4nO3de3zO9f/H8ee1sWtjB4QdWJtTQ5hD0ghTckyW+oYORug0X2dJ3zDUd6UUlUgOi0ip6Eu++i5CMomsIq2IJrZVDptZZrbP7w+/XesyY5frmvnM4+72uX273p/3+/N5fa7b5+t6eR8+H4thGIYAAABMwq2sAwAAAHAEyQsAADAVkhcAAGAqJC8AAMBUSF4AAICpkLwAAABTIXkBAACmQvICAABMheQFAACYCskLUM78/PPP6tKli/z8/GSxWLRq1SqXHv/gwYOyWCyKj4936XHNLDIyUpGRkWUdBnDNIHkBSsH+/fv16KOPqm7duvL09JSvr6/atWunWbNm6a+//irVc0dHR+v777/Xc889pyVLluimm24q1fNdSQMHDpTFYpGvr+8Fv8eff/5ZFotFFotFL730ksPHP3LkiGJjY5WUlOSCaAGUlgplHQBQ3nzyySf6xz/+IavVqgEDBqhJkyY6c+aMtmzZonHjxmnPnj2aN29eqZz7r7/+UmJiov71r39p2LBhpXKOkJAQ/fXXX6pYsWKpHP9SKlSooOzsbK1evVr33Xef3b6lS5fK09NTp0+fvqxjHzlyRFOmTFFoaKiaN29e4nb/+9//Lut8AC4PyQvgQgcOHFC/fv0UEhKiDRs2KDAw0LYvJiZG+/bt0yeffFJq5//jjz8kSVWqVCm1c1gsFnl6epba8S/FarWqXbt2evfdd4skL8uWLVPPnj314YcfXpFYsrOzValSJXl4eFyR8wE4h2EjwIWmT5+urKwsLViwwC5xKVC/fn2NGDHC9vns2bOaNm2a6tWrJ6vVqtDQUD399NPKycmxaxcaGqo777xTW7Zs0c033yxPT0/VrVtXixcvttWJjY1VSEiIJGncuHGyWCwKDQ2VdG64peC//y42NlYWi8WuLCEhQbfeequqVKkib29vhYWF6emnn7btL27Oy4YNG9S+fXtVrlxZVapUUe/evbV3794Lnm/fvn0aOHCgqlSpIj8/Pw0aNEjZ2dnFf7Hnuf/++/Xf//5XJ06csJV9/fXX+vnnn3X//fcXqX/s2DGNHTtWTZs2lbe3t3x9fdW9e3d9++23tjobN25U69atJUmDBg2yDT8VXGdkZKSaNGminTt3qkOHDqpUqZLtezl/zkt0dLQ8PT2LXH/Xrl1VtWpVHTlypMTXCqAokhfAhVavXq26deuqbdu2Jao/ZMgQTZo0SS1bttQrr7yijh07Ki4uTv369StSd9++fbr33nt1xx13aMaMGapataoGDhyoPXv2SJL69OmjV155RZLUv39/LVmyRDNnznQo/j179ujOO+9UTk6Opk6dqhkzZuiuu+7Sl19+edF2n332mbp27arff/9dsbGxGj16tLZu3ap27drp4MGDRerfd999OnnypOLi4nTfffcpPj5eU6ZMKXGcffr0kcVi0UcffWQrW7ZsmRo2bKiWLVsWqf/LL79o1apVuvPOO/Xyyy9r3Lhx+v7779WxY0dbItGoUSNNnTpVkvTII49oyZIlWrJkiTp06GA7ztGjR9W9e3c1b95cM2fOVKdOnS4Y36xZs1SjRg1FR0crLy9PkvTmm2/qf//7n1577TUFBQWV+FoBXIABwCUyMjIMSUbv3r1LVD8pKcmQZAwZMsSufOzYsYYkY8OGDbaykJAQQ5KxefNmW9nvv/9uWK1WY8yYMbayAwcOGJKMF1980e6Y0dHRRkhISJEYJk+ebPz9r4FXXnnFkGT88ccfxcZdcI5FixbZypo3b27UrFnTOHr0qK3s22+/Ndzc3IwBAwYUOd/DDz9sd8y7777buO6664o959+vo3LlyoZhGMa9995r3H777YZhGEZeXp4REBBgTJky5YLfwenTp428vLwi12G1Wo2pU6fayr7++usi11agY8eOhiRj7ty5F9zXsWNHu7JPP/3UkGQ8++yzxi+//GJ4e3sbUVFRl7xGAJdGzwvgIpmZmZIkHx+fEtVfu3atJGn06NF25WPGjJGkInNjGjdurPbt29s+16hRQ2FhYfrll18uO+bzFcyV+fjjj5Wfn1+iNqmpqUpKStLAgQNVrVo1W3mzZs10xx132K7z7x577DG7z+3bt9fRo0dt32FJ3H///dq4caPS0tK0YcMGpaWlXXDISDo3T8bN7dxfd3l5eTp69KhtSOybb74p8TmtVqsGDRpUorpdunTRo48+qqlTp6pPnz7y9PTUm2++WeJzASge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GzmzlRckL7jmeFU8d9ufys0r40iA0sE9jvKO5OUiLBaLVq1aVdZhwIUsku5pFqD9f2YrNTOnrMMBXI57vPyi56XQVZG8JCYmyt3dXT179nS4bWhoqGbOnOn6oEpo9uzZCg0Nlaenp9q0aaPt27eXWSy4tL7NAxTka9XCr38r61CAUsE9Xn5Z5GTy4uCkl7i4OLVu3Vo+Pj6qWbOmoqKilJycfNE2e/bs0T333KPQ0FBZLJZif5+d/e28KpKXBQsW6J///Kc2b96sI0eOlHU4Jfbee+9p9OjRmjx5sr755huFh4era9eu+v3338s6NFzAfeEBahLgo1lf/KoTf50t63AAl+Mehytt2rRJMTEx2rZtmxISEpSbm6suXbro1KlTxbbJzs5W3bp19fzzzysgIOCCdVzx21nmyUtWVpbee+89Pf744+rZs6fi4+OL1Fm9erVat24tT09PVa9eXXfffbckKTIyUr/++qtGjRpl1yUWGxur5s2b2x1j5syZCg0NtX3++uuvdccdd6h69ery8/NTx44d9c033zgU+8svv6yhQ4dq0KBBaty4sebOnatKlSpp4cKFDh0Hpe++8ACFB537S/1odm5ZhwO4HPd4+Xelh43WrVungQMH6sYbb1R4eLji4+OVkpKinTt3FtumdevWevHFF9WvXz9ZrdYL1nHFb2eZJy/vv/++GjZsqLCwMD344INauHChDMOw7f/kk0909913q0ePHtq1a5fWr1+vm2++WZL00UcfqXbt2po6dapSU1OVmppa4vOePHlS0dHR2rJli7Zt26YGDRqoR48eOnnyZInanzlzRjt37lTnzp1tZW5uburcubMSExNLHAdKX9/mAWod7KdFXx9Wztk8+Vrd5Wt1V0W38jP+i2sb9/g1ooyXSmdkZEiSqlWrdtnHcNVvZ5k/pG7BggV68MEHJUndunVTRkaGNm3apMjISEnSc889p379+mnKlCm2NuHh4ZLOfYHu7u7y8fEptnuqOLfddpvd53nz5qlKlSratGmT7rzzzku2//PPP5WXlyd/f3+7cn9/f/34448XbJOTk6OcnMIJdJmZmQ7FjMvToe65/6ON6hBqV75kx2FtS8kog4gA1+IehyPO/+2xWq3F9pIUyM/P18iRI9WuXTs1adLkss99Ob+dF1KmyUtycrK2b9+ulStXngumQgX17dtXCxYs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UxQTE6PVq1fb6mzdulX9+/fX4MGDtWvXLkVFRSkqKkq7d+92KLYyT16ysrL03nvv6fHHH1fPnj0VHx9fpM7q1avVunVreXp6qnr16rr77rslSZGRkfr11181atQoWSwWWf4/rYyNjVXz5s3tjjFz5kyFhobaPn/99de64447VL16dfn5+aljx4765ptvHIq9e/fuevbZZ23x4Op1X3iAwoPO/aV+NDu3rMMBXI57HK7m6G/ckiVL9Oijj6pv376qW7eu+vXrp0ceeUQvvPCCrc6sWbPUrVs3jRs3To0aNdK0adPUsmVLvf766w7FVubJy/vvv6+GDRsqLCxMDz74oBYuXCjDMGz7P/nkE919993q0aOHdu3apfXr1+vmm2+WJH300UeqXbu2pk6dqtTUVKWmppb4vCdPnlR0dLS2bNmibdu2qUGDBurRo4dOnjzp8msskJOTo8zMTLsNpa9v8wC1DvbToq8PK+dsnnyt7vK1uqtieZp6j2sa9/i1wU0WuVmc2P6/7+X836GcHNfMjcrJyZGnp6ddmZeXl7Zv367c3HMJdWJiojp37mxXp2vXrkpMTHToXGX+kLoFCxbowQcflCR169ZNGRkZ2rRpkyIjIyVJzz33nPr166cpU6bY2oSHh0uSqlWrJnd3d/n4+CggIMCh89522212n+fNm6cqVapo06ZNuvPOO524ouLFxcXZXQeujA51q0mSRnUItStfsuOwtqVklEFEgGtxj18bLmfo5/z2khQcHGxXPnnyZMXGxjpx5HO6du2q+fPnKyoqSi1bttTOnTs1f/585ebm6s8//1RgYKDS0tLk7+9v187f319paWkOnatMk5fk5GRt375dK1euPBdMhQrq27evFixYYEtekpKSNHToUJefOz09Xc8884w2btyo33//XXl5ecrOzlZKSorLz1VgwoQJGj16tO1zZmZmkZsIrhfz0Q9lHQJQqrjH4YhDhw7J19fX9tlqtbrkuBMnTlRaWppuueUWGYYhf39/RUdHa/r06XJzc+1AT5kmLwsWLNDZs2cVFBRkKzMMQ1arVa+//rr8/Pzk5eX4Q5bc3Nzshp4k2bqsCkRHR+vo0aOaNWuWQkJCZLVaFRERoTNnSu9x2lar1WU3CQDgGuOirhdfX1+75MVVvLy8tHDhQr355ptKT09XYGCg5s2bJx8fH9WoUUOSFBAQoPT0dLt26enpDo+elNmcl7Nnz2rx4sWaMWOGkpKSbNu3336roKAgvfvuu5KkZs2aaf369cUex8PDQ3l59g9iqlGjhtLS0uwSmKSkJLs6X375pYYPH64ePXroxhtvlNVq1Z9//um6CwQAwIXM8pyXihUrqnbt2nJ3d9fy5ct155132npeIiIiivymJyQkKCIiwqFzlFnPy5o1a3T8+HENHjxYfn5+dvvuueceLViwQI899pgmT56s22+/XfXq1VO/fv109uxZrV27VuPHj5d07jkvmzdvVr9+/WS1WlW9enVFRkbqjz/+0PTp03Xvvfdq3bp1+u9//2uXaTZo0EBLlizRTTfdpMzMTI0bN87hXp6srCzt27fP9vnAgQNKSkpStWrVdP311zvx7QAAULYu9Rs3YcIEHT582PYsl59++knbt29XmzZtdPz4cb388svavXu33n77bdsxRowYoY4dO2rGjBnq2bOnli9frh07dmjevHkOxVZmPS8LFixQ586diyQu0rnkZceOHfruu+8UGRmpFStW6D//+Y+aN2+u2267Tdu3b7fVnTp1qg4ePKh69erZuqUaNWqkN954Q7Nnz1Z4eLi2b9+usWPHFjn/8ePH1bJlSz300EMaPny4atas6dA17NixQy1atFCLFi0kSaNHj1aLFi00adIkR78OAAAuztkH1DnY8XKp37jU1FS7eaJ5eXmaMWOGwsPDdccdd+j06dPaunWr3WNK2rZtq2XLlmnevHkKDw/XBx98oFWrVqlJkyaOfRXG+ZNDcMVkZmbKz89PQ5Z8JY9K3mUdDgDAQWeyszT/oTbKyMgolXkkUuFvxYakFHn7XP45sk5m6rbm15dqrFdKmT/nBQAAwBFl/pwXAABQAq560Es5QPICAIAJOLtiqDy9VZrkBQAAE7icN0Of3768YM4LAAAwFXpeAAAwAaa8FCJ5AQDADMhebBg2AgAApkLPCwAAJsBqo0IkLwAAmACrjQoxbAQAAEyFnhcAAEyA+bqFSF4AADADshcbho0AAICp0PMCAIAJsNqoEMkLAAAmwGqjQiQvAACYAFNeCjHnBQAAmAo9LwAAmAFdLzYkLwAAmAATdgsxbAQAAEyFnhcAAEyA1UaFSF4AADABprwUYtgIAACYCj0vAACYAV0vNiQvAACYAKuNCjFsBAAATIWeFwAATIDVRoVIXgAA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jUqVKhlbt261qzt48GCjf//+hmEYxoQJE4zGjRvb7R8/fvwl31gsyVi5cmWx+1988UWjVatWts+TJ0823N3djd9++81W9t///tdwc3Ozvc27Xr16xrJly+yOM23aNCMiIsIwDMM4cOCAIcnYtWtXsecFcGUx5wW4Sq1Zs0be3t7Kzc1Vfn6+7r//fsXGxtr2N23a1G6ey7fffqt9+/bJx8fH7jinT5/W/v37lZGRodTUVLVp08a2r0KFCrrpppuKDB0VSEpKkru7uzp27FjiuPft26fs7GzdcccdduVnzpxRixYtJEl79+61i0OSIiIiSnyOAu+9955effVV7d+/X1lZWTp79qx8fX3t6lx//fWqVauW3Xny8/OVnJwsHx8f7d+/X4MHD9bQoUNtdc6ePSs/Pz+H4wFwZZC8AFepTp06ac6cOfLw8FBQUJAqVLD/v2vlypXtPmdlZalVq1ZaunRpkWPVqFHjsmLw8vJyuE1WVpYk6ZNPPrFLGqRz83hcJTExUQ888ICmTJmirl27ys/PT8uXL9eMGTMcjvWtt94qkky5u7u7LFYArkXyAlylKleurPr165e4fsuWLfXee++pZs2aRXofCgQGBuqrr75Shw4dJJ3rYdi5c6datmx5wfpNmzZVfn6+Nm3apM6dOxfZX9Dzk5eXZytr3LixrFarUlJSiu2xadSokW3ycYFt27Zd+iL/ZuvWrQoJCdG//vUvW9mvv/5apF5KSoqOHDmioKAg23nc3NwUFhYmf39/BQUF6ZdfftEDDzzg0PkBlB0m7ALlxAMPPKDq1aurd+/e+uKLL3TgwAFt3LhRw4cP12+//SZJGjFihJ5//nmtWrVKP/74o5544omLPqMlNDRU0dHRevjhh7Vq1SrbMd9//31JUkhIiCwWi9asWaM//vhDWVlZ8vHx0dixYzVq1Ci9/fbb2r9/v7755hu99tprtkmwjz32mH7++WeNGzdOycnJWrZsmeLj4x263gYNGiglJUXLly/X/v379eqrr15w8rGnp6eio6P17bff6osvvtDw4cN13333KSAgQJI0ZcoUxcXF6dVXX9VPP/2k77//XosWLdLLL7/sUDwArhySF6CcqFSpkjZv3qzrr79effr0UaNGjTR48GCdPn3a1hMzZswYPfTQQ4qOjlZERIR8fHx09913X/S4c+bM0b333qsnnnhCDRs21NChQ3Xq1ClJUq1atTRlyhQ99dRT8vf317BhwyRJ06ZN08SJExUXF6dGjRqpW7du+uSTT1SnTh1J5+ahfPjhh1q1apXCw8M1d+5c/fvf/3boeu+66y6NGjVKw4YNU/PmzbV161ZNnDixSL369eurT58+6tGjh7p06aJmzZrZLYUeMmSI5s+fr0WLFqlp06bq2LGj4uPjbbECuPpYjOJm6gEAAFyF6HkBAACmQvICAABMheQFAACYCskLAAAwFZIXAABgKiQvAADAVEheAACAqZC8AAAAUyF5AQAApkLyAgAATIXkBQAAmArJCwAAMJX/A4lHwiSj/H2ZAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#This is a note of confusion matrix\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "# Create actual labels and predicted labels\n", + "actual_labels = [0, 1, 0, 1, 1, 0, 0, 1]\n", + "predicted_labels = [0, 1, 1, 1, 0, 1, 0, 0]\n", + "\n", + "# Compute the confusion matrix\n", + "cm = confusion_matrix(actual_labels, predicted_labels)\n", + "\n", + "# Plot the confusion matrix\n", + "plt.imshow(cm, cmap=plt.cm.Blues)\n", + "plt.title('Confusion Matrix')\n", + "plt.colorbar()\n", + "plt.xticks([0, 1], ['Predicted 0', 'Predicted 1'])\n", + "plt.yticks([0, 1], ['Actual 0', 'Actual 1'])\n", + "\n", + "# Display counts in each cell\n", + "thresh = cm.max() / 2\n", + "for i in range(cm.shape[0]):\n", + " for j in range(cm.shape[1]):\n", + " plt.text(j, i, format(cm[i, j]), horizontalalignment=\"center\", color=\"white\" if cm[i, j] > thresh else \"black\")\n", + "\n", + "plt.xlabel('Predicted label')\n", + "plt.ylabel('True label')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c92b2136", + "metadata": {}, + "source": [ + "Above, we output a confusion matrix on actual_labels = [0, 1, 0, 1, 1, 0, 0, 1] and the predicted_labels = [0, 1, 1, 1, 0, 1, 0, 0]\n", + "\n", + "Of course, here we are just demonstrating how to output the confusion matrix to understand its meaning after obtaining these two sets of data. In the subsequent experiment, we will explain how to obtain the desired confusion matrix through code.\n", + "\n", + "There are four values in the matrix their meanings are as follows:\n", + "\n", + "**True Positive (TP)**: The number of positive instances correctly predicted as positive by the model.\n", + "\n", + "**False Negative (FN)**: The number of positive instances incorrectly predicted as negative by the model.\n", + "\n", + "**False Positive (FP)**: The number of negative instances incorrectly predicted as positive by the model.\n", + "\n", + "**True Negative (TN)**: The number of negative instances correctly predicted as negative by the model.\n", + "\n", + "As for the matrix we have above, TP is where we predicted as 1 and actually it is 1. FN is the acount that we predicted as 0 but actually it is 1. FP is predicted as 1 but actually it's 0. TN is we predicted as 0 and it's actually 0.\n", + "\n", + "After understanding the meaning of the matrix, we can use the following algorithms to calculate the desired metrics:\n", + "\n", + "**Accuracy**: The ratio of the number of correctly predicted samples to the total number of samples.\n", + "\n", + "$$Accuracy = \\frac{TP + TN}{TP + TN + FP + FN}$$\n", + "\n", + "**Precision**: The proportion of true positive predictions among the predicted positive instances, measuring the prediction accuracy of the model.\n", + "\n", + "$$Precision = \\frac{TP}{TP + FP}$$\n", + "\n", + "**Recall**: The proportion of true positive predictions among the actual positive instances, measuring the model's ability to identify positives.\n", + "\n", + "$$Recall = \\frac{TP}{TP + FN}$$\n", + "\n", + "**F1 Score**: The harmonic mean of precision and recall, considering both the accuracy and the identification ability of the model.\n", + "\n", + "$$F_1 \\text{ Score} = \\frac{2 \\cdot (Precision \\cdot Recall)}{Precision + Recall}$$\n", + "\n", + "When evaluating the bias of a model, we usually consider metrics such as precision, accuracy, and F1 score. A lower F1 score may indicate that the model has issues in balancing accuracy and identification ability, but it cannot be simply equated to lower bias. By considering multiple metrics and the specific requirements of the application scenario, a more comprehensive assessment of the model's performance can be achieved.\n" + ] + }, + { + "cell_type": "markdown", + "id": "1130ca67", + "metadata": {}, + "source": [ + "## Method \n", + "\n", + "Does a lower recall rate indicate better bias?\n", + "\n", + "**No**, a lower recall rate does not indicate better bias. In machine learning, recall rate is a metric that measures the model's ability to identify positive instances. A higher recall rate indicates that the model can better identify positive instances, while a lower recall rate means that the model may miss some true positive instances.\n", + "\n", + "Then does a lower F1 score indicate better bias?\n", + "\n", + "**No**, a lower F1 score does not indicate better bias. The F1 score is the harmonic mean of precision and recall, which considers both the accuracy and the identification ability of the model.Bias refers to the extent to which a model makes incorrect assumptions or oversimplifies the problem, and it is related to the model's prediction accuracy. A lower bias indicates that the model can better fit the training data and is closer to the true underlying relationship.\n", + "\n", + "The F1 score aims to consider both the precision and recall of the model. For certain applications, we are concerned with both the model's prediction accuracy (precision) and its ability to identify positive instances (recall). Therefore, a higher F1 score indicates that the model performs well in balancing prediction accuracy and identification ability.\n", + "\n", + "All these metrics are primarily used to measure the performance of a model on a specific dataset, while model bias typically refers to the systematic deviation of the model from the trends in the dataset, which may affect the model's ability to generalize.\n", + "\n", + "Then is there any way to indirectly indicate the bias of a model?\n", + "\n", + "Analyzing the difference between training error and validation error, Holdout Method,Cross-Validation, and Bootstrapping are all viable approaches.\n", + "\n", + "So what are these method?\n" + ] + }, + { + "cell_type": "markdown", + "id": "b5e50cc2", + "metadata": {}, + "source": [ + "### Holdout Method\n", + "\n", + "Splitting the dataset into mutually exclusive training and testing sets, using the training set to train the model, and then evaluating the model's performance using the testing set. By comparing the performance on different models using the validation set, we can select the best-performing model. The sampling criteria require stratified sampling, which means dividing the data proportionally based on data types. \n", + "\n", + "However, since different partitioning methods yield different data samples, the results of model evaluation also differ. Typically, we choose a large portion of the dataset (70-80%) as the training set and the remaining portion as the testing set.\n", + "By splitting the dataset, we can observe that the testing set only represents a small portion of the total dataset, which can lead to unstable evaluation results.\n" + ] + }, + { + "cell_type": "markdown", + "id": "c3090247", + "metadata": {}, + "source": [ + "### Cross-Validation\n", + "\n", + "Splitting the dataset into K mutually exclusive subsets (K-fold cross-validation), using each subset as a validation set in turn and the remaining subsets as training sets to train the model and evaluate its performance. By averaging or aggregating the results from K validations, the best model can be selected.\n", + "\n", + "The stability and fidelity of the results in cross-validation evaluation method largely depend on the value of K. Additionally, when the sample size is small but can be clearly separated, leave-one-out method (LOOCV) can be used.\n", + "\n", + "Cross-validation provides high precision, but it can be time-consuming when dealing with large datasets.\n", + "\n", + "In general, using 10-fold cross-validation is sufficient to indirectly assess the generalization ability of a model.\n" + ] + }, + { + "cell_type": "markdown", + "id": "81135eee", + "metadata": {}, + "source": [ + "### Bootstrapping\n", + "\n", + "Bootstrapping, also known as resampling or sampling with replacement, is a technique where each time a copy of a sample is selected from a dataset containing m samples and added to the resulting dataset. This process is repeated m times, resulting in a dataset with m samples. (Some samples may appear multiple times in the resulting dataset.) This resulting dataset is then used as the training set.\n", + "\n", + "Since the sampling is conducted independently, the probability that a specific sample is never selected in m iterations of sampling is $ [(1-\\frac{1}{m})^m] $. As m approaches infinity, $ lim_{m \\to \\infty} (1 - \\frac{1}{m})^m = \\frac{1}{e} $ the limit of this probability is $1/e$ , where e is the base of the natural logarithm and approximately equal to 2.71828. Therefore, when m is sufficiently large, the probability that a specific sample is never selected in m iterations of sampling is close to $\\frac{1}{e} ≈ 0.36787944117$ .\n" + ] + }, + { + "cell_type": "markdown", + "id": "a98e5323", "metadata": {}, "source": [ "## Interpreting the Learning Curves\n", @@ -197,10 +392,105 @@ "\n", "Ideally, we would create models that learn all of the signal and none of the noise. This will practically never happen. Instead we make a trade. We can get the model to learn more signal at the cost of learning more noise. So long as the trade is in our favor, the validation loss will continue to decrease. After a certain point, however, the trade can turn against us, the cost exceeds the benefit, and the validation loss begins to rise.\n", "\n", - "This trade-off indicates that there can be two problems that occur when training a model: not enough signal or too much noise. **Underfitting** the training set is when the loss is not as low as it could be because the model hasn't learned enough *signal*. **Overfitting** the training set is when the loss is not as low as it could be because the model learned too much *noise*. The trick to training deep learning models is finding the best balance between the two.\n", + "This trade-off indicates that there can be two problems that occur when training a model: not enough signal or too much noise. Underfitting the training set is when the loss is not as low as it could be because the model hasn't learned enough *signal*. Overfitting the training set is when the loss is not as low as it could be because the model learned too much *noise*. The trick to training deep learning models is finding the best balance between the two.\n", + "\n", + "We'll look at a couple ways of getting more signal out of the training data while reducing the amount of noise later.\n" + ] + }, + { + "cell_type": "markdown", + "id": "1e5c8a70", + "metadata": {}, + "source": [ + "Let's first take a look at a learning curve. In this part we're using a datasets called iris in scikit-learn." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "63830061", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#This is a note of a learning curve by using the iris dataset in sklearn\n", + "\n", + "import warnings\n", + "\n", + "# Ignore warnings\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.datasets import load_iris\n", + "from sklearn.model_selection import learning_curve\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Load the Iris dataset\n", + "iris = load_iris()\n", + "X = iris.data\n", + "y = iris.target\n", + "\n", + "# Feature scaling\n", + "scaler = StandardScaler()\n", + "X = scaler.fit_transform(X)\n", + "\n", + "# Define a logistic regression model\n", + "model = LogisticRegression()\n", "\n", - "We'll look at a couple ways of getting more signal out of the training data while reducing the amount of noise.\n", + "# Define the range of training set sizes\n", + "train_sizes = np.linspace(0.1, 1.0, 10)\n", "\n", + "# Generate learning curve data using the learning_curve function\n", + "train_sizes, train_scores, test_scores = learning_curve(model, X, y, train_sizes=train_sizes, cv=5)\n", + "\n", + "# Calculate the average accuracy for the training and test sets\n", + "train_scores_mean = np.mean(train_scores, axis=1)\n", + "test_scores_mean = np.mean(test_scores, axis=1)\n", + "\n", + "# Plot the learning curve\n", + "plt.figure()\n", + "plt.title(\"Learning Curve\")\n", + "plt.xlabel(\"Training Examples\")\n", + "plt.ylabel(\"Accuracy\")\n", + "plt.grid()\n", + "\n", + "# Plot the accuracy curves for the training and test sets\n", + "plt.plot(train_sizes, train_scores_mean, 'o-', color=\"r\", label=\"Training Accuracy\")\n", + "plt.plot(train_sizes, test_scores_mean, 'o-', color=\"g\", label=\"Cross-validation Accuracy\")\n", + "plt.legend(loc=\"best\")\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e5aa3d14", + "metadata": {}, + "source": [ + "First of all, let's take a look at a plot, this is a simple learning curve using an iris dataset in sklearn.dataset. We can simply notice the two curve we plot fells far apart when we have less examples, and when we enlarge the training examples we can see the two lines are approaching convergence.\n", + "\n", + "Why? \n", + "\n", + "To train a model, it is necessary to have a sufficient number of samples so that it can generalize patterns from the data. Assuming we have a function y=f(x), essentially, machine learning algorithms summarize and fit the f function based on a large number of (x, y) pairs. Therefore, if you have too few (x, y) pairs, the algorithm will not be able to summarize the function effectively. This is the impact of the sample size on the degree of fitting." + ] + }, + { + "cell_type": "markdown", + "id": "7338d800", + "metadata": {}, + "source": [ "## Capacity\n", "\n", "A model's **capacity** refers to the size and complexity of the patterns it is able to learn. For neural networks, this will largely be determined by how many neurons it has and how they are connected together. If it appears that your network is underfitting the data, you should try increasing its capacity.\n", @@ -209,24 +499,19 @@ "\n", "You'll explore how the capacity of a network can affect its performance in the exercise.\n", "\n", - "## Early Stopping\n", + "Determining an appropriate model capacity is a crucial task in model selection. Here are some common methods and guidelines to help determine the right model capacity:\n", "\n", - "We mentioned that when a model is too eagerly learning noise, the validation loss may start to increase during training. To prevent this, we can simply stop the training whenever it seems the validation loss isn't decreasing anymore. Interrupting the training this way is called **early stopping**.\n", + "**Rule of thumb**: In general, if the dataset is small or the task is relatively simple, choosing a lower-capacity model may be more suitable to avoid overfitting. For larger datasets or complex tasks, a higher-capacity model may be able to better fit the data.\n", "\n", - "Once we detect that the validation loss is starting to rise again, we can reset the weights back to where the minimum occured. This ensures that the model won't continue to learn noise and overfit the data.\n", + "**Cross-validation**: This method has been mentioned earlier in the previous text, and it is an extremely important approach in model selection. Therefore, it is necessary to mention this method multiple times and gain a deeper understanding of it.\n", "\n", - "Training with early stopping also means we're in less danger of stopping the training too early, before the network has finished learning signal. So besides preventing overfitting from training too long, early stopping can also prevent *underfitting* from not training long enough. Just set your training epochs to some large number (more than you'll need), and early stopping will take care of the rest.\n", + "**Learning curves**: Learning curves can help determine if the model capacity is appropriate. By plotting the performance of the model on the training set and the validation set as the number of training samples increases, one can observe the model's fitting and generalization abilities. If the model performs poorly on both the training set and the validation set, it may be underfitting due to low capacity. If the model performs well on the training set but poorly on the validation set, it may be overfitting due to high capacity. Adjustments to the model capacity can be made based on the trend of the learning curve.\n", "\n", - "## Adding Early Stopping\n", + "**Regularization**: Adjusting the model capacity through regularization techniques (which we will also mention in the text later). Increasing the regularization parameter can reduce model capacity and decrease the risk of overfitting. Decreasing the regularization parameter can increase model capacity and improve fitting ability. By evaluating the model performance on the validation set with different regularization parameters, an appropriate regularization parameter value can be chosen.\n", "\n", - "In Keras, we include early stopping in our training through a callback. A **callback** is just a function you want run every so often while the network trains. The early stopping callback will run after every epoch. (Keras has [a variety of useful callbacks](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks) pre-defined, but you can [define your own](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/LambdaCallback), too.)\n", + "**Model comparison experiments**: Train and evaluate models with different capacities and compare their performance on the validation set. By comparing the generalization performance of different-capacity models, select the model capacity with the best performance.\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/traintestoverfitting.png\n", - "---\n", - "name: EarlyStopping-ms\n", - "---\n", - "Early stopping\n", - ":::" + "Considering the above methods and guidelines, selecting an appropriate model capacity requires a balance between theory and practice and decision-making based on the specific problem and available resources. The ultimate goal is to choose a model that performs well on both the training data and new data, achieving good generalization ability." ] }, { @@ -238,10 +523,21 @@ "\n", "You may be familiar with Occam's Razor principle: given two explanations for something, the explanation most likely to be correct is the 'simplest' one, the one that makes the least amount of assumptions. This also applies to the models learned by neural networks: given some training data and a network architecture, there are multiple sets of weights values (multiple models) that could explain the data, and simple models are less likely to overfit than complex ones.\n", "\n", - "A 'simple model' in this context is a model where the distribution of parameter values has less entropy (or a model with fewer parmeters altogether, as we saw in the section above). Thus a common way to mitigate overfitting is to put constraints on the complexity of a network by forcing its weeights only to take small values, which makes the distribution of weight values more 'regular'. This is called 'weight regularization', and it is done by adding to the loss function of the network a cost associated with having large weights. This cost comes in two flavors:\n", + "A 'simple model' in this context is a model where the distribution of parameter values has less entropy (or a model with fewer parmeters altogether, as we saw in the section above). Thus a common way to mitigate overfitting is to put constraints on the complexity of a network by forcing its weeights only to take small values, which makes the distribution of weight values more 'regular'. This is called 'weight regularization', and it is done by adding to the loss function of the network a cost associated with having large weights. \n", + "\n", + "Let's consider a target function with a regularization term, which can be represented as:\n", + "\n", + "$$J(\\theta) = L(\\theta) + \\lambda R(\\theta)$$\n", + "\n", + "Here, $J(\\theta)$ is the target function, $\\theta$ represents the model's parameters, $L(\\theta)$ is the loss function (typically the model's error on the training data), $R(\\theta)$ is the regularization term, and \\lambda is the regularization parameter.\n", "\n", - "- L1 regularization, where the cost added is proportional to the aboslute value of the weights coefficients (i.e. to what is called the 'L1 norm' of the weights).\n", - "- L2 regularization, where the cost added is proportional to the square of the value of the weights coefficients (i.e. to what is called the 'L2 norm' of the weights). L2 regularization is also called weight decay in the context of neurral networks. Don't let the different name confuse you: weight decay is mathematically the exact same as L2 regularization.\n", + "The loss function $L(\\theta)$ measures how well the model fits the training data, and our goal is to minimize it. The regularization term $R(\\theta)$ constrains or penalizes the values of the model's parameters, and it controls the complexity of the model.\n", + "\n", + "The regularization parameter $\\lambda$ determines the weight of the regularization term in the target function. When $\\lambda$ approaches $\\theta$, the impact of the regularization term becomes negligible, and the model's objective is primarily to minimize the loss function. On the other hand, when $\\lambda$ approaches infinity, the regularization term's impact becomes significant, and the model's objective is to minimize the regularization term as much as possible, leading to parameter values tending towards zero.\n", + "\n", + "There are two forms of this cost: L1 regularization (also known as Lasso regression) with the regularization term $R(\\theta)$ represented as the sum of the absolute values of the parameters $\\theta$: $R(\\theta) = ||\\theta||_1$. L1 regularization can induce certain parameters of the model to become zero, thereby achieving feature selection and sparsity.\n", + "\n", + "L2 regularization (also known as Ridge regression) with the regularization term $R(\\theta)$ represented as the square root of the sum of the squares of the parameters $\\theta$: $R(\\theta) = ||\\theta||_2$. L2 regularization encourages the parameter values of the model to gradually approach zero but not exactly become zero, hence it does not possess the ability for feature selection.\n", "\n", "In `tf.keras`, weight regularization is added by passing weight regularizer instances to layers as keyword arguments. Let's add L2 weight regularization now.\n", "\n", @@ -251,7 +547,6 @@ "\n", "\n", "\n", - "\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/circlesquare.png\n", "---\n", "name: circlesquare-ms\n", @@ -259,54 +554,82 @@ "L1 and L2 regularization\n", ":::\n", "\n", + "Both are very common regularization techniques, but they are suitable for different scenarios. L1 regularization is suitable for situations that require feature selection or demand model interpretability. On the other hand, L2 regularization is more general and applicable in most cases to prevent overfitting and improve model generalization ability.\n" + ] + }, + { + "cell_type": "markdown", + "id": "2ccb9c25", + "metadata": {}, + "source": [ + "## Early Stopping\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/L1L2contour.png\n", - "---\n", - "name: explainedairegularization-ms\n", - "---\n", - "L1 and L2 regularization \n", - ":::\n", + "We mentioned that when a model is too eagerly learning noise, the validation loss may start to increase during training. To prevent this, we can simply stop the training whenever it seems the validation loss isn't decreasing anymore. Interrupting the training this way is called **early stopping**.\n", "\n", + "Once we detect that the validation loss is starting to rise again, we can reset the weights back to where the minimum occured. This ensures that the model won't continue to learn noise and overfit the data.\n", "\n", + "Training with early stopping also means we're in less danger of stopping the training too early, before the network has finished learning signal. So besides preventing overfitting from training too long, early stopping can also prevent *underfitting* from not training long enough. Just set your training epochs to some large number (more than you'll need), and early stopping will take care of the rest.\n", + "\n", + "## Adding Early Stopping\n", + "\n", + "In Keras, we include early stopping in our training through a callback. A **callback** is just a function you want run every so often while the network trains. The early stopping callback will run after every epoch. (Keras has [a variety of useful callbacks](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks) pre-defined, but you can [define your own](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/LambdaCallback), too.)\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/ridgelassoItayEvron.gif\n", + ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/traintestoverfitting.png\n", "---\n", - "name: berkeley189s21-ms\n", + "name: EarlyStopping-ms\n", "---\n", - "Different $\\beta$ and ellipses \n", - ":::\n", - "\n", + "Early stopping\n", + ":::\n" + ] + }, + { + "cell_type": "markdown", + "id": "585321db", + "metadata": {}, + "source": [ + "## The impact of the value of $\\lambda$ \n", "\n", + "We notice that the objective function contains not only the regularization term but also the regularization parameter $\\lambda$.\n", "\n", + "The selection of the regularization parameter is an important part of regularization, and it needs to be fine-tuned during the model training process.\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/p-norm_balls.webp\n", + ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/lagrange-animation.gif\n", "---\n", - "name: p-norm_balls\n", + "name: impact-of-lambda-ms\n", "---\n", - "Different p norm \n", + "The impact of the value of $\\lambda$ \n", ":::\n", "\n", + "The value of $\\lambda$ has a significant impact on weight regularization.\n", "\n", + "When $\\lambda$ is small, the effect of weight regularization is relatively minor. The network is more likely to learn complex patterns and structures, which can lead to overfitting. This means that the model may perform well on the training data but have poor generalization on new data.\n", "\n", + "When $\\lambda$ is large, the effect of weight regularization becomes more pronounced. The network is constrained to simpler patterns and structures, reducing the risk of overfitting. This can improve the model's generalization on new data but may result in a slight decrease in performance on the training data.\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/elastic_net_balls.webp\n", - "---\n", - "name: ElasticNet-ms\n", - "---\n", - "ElasticNet \n", - ":::\n", + "Choosing the appropriate value of $\\lambda$ requires adjustment and optimization based on the specific problem and dataset. Typically, cross-validation or other evaluation methods can be used to select the optimal $\\lambda$ value, finding a balance between model complexity and generalization ability.\n", "\n", + "When using regularization during model training, its effect can be better understood. Let's take the example of linear regression.\n", "\n", - "### The impact of the value of $\\lambda$ \n", + "Suppose we have a dataset containing house area and prices, and we want to use a linear regression model to predict house prices. We can define a linear regression model that includes an intercept term and a coefficient for the house area.\n", "\n", - ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/lagrange-animation.gif\n", - "---\n", - "name: impact-of-lambda-ms\n", - "---\n", - "The impact of the value of $\\lambda$ \n", - ":::\n", + "Without regularization, the objective of the model is to minimize the mean squared error (MSE) on the training data. This means the model will try to find the best-fitting line in the training data to minimize the differences between the predicted values and the actual values.\n", "\n", + "However, if the training data contains noise or outliers, or if the training set is relatively small, the model may overfit the data, leading to a decrease in prediction performance on new data. In such cases, regularization can help control the complexity of the model and reduce the risk of overfitting.\n", "\n", + "By adding L2 regularization (Ridge regularization) to the linear regression model, we introduce the square of the L2 norm of the parameters as a penalty term in the loss function. This encourages the model to prefer smaller parameter values during training, preventing the parameters from becoming too large.\n", + "\n", + "The effect of regularization is achieved by balancing the trade-off between minimizing the training error and minimizing the penalty term. A larger regularization parameter will penalize larger parameter values more strongly, making the model smoother and reducing the differences between parameters. This helps reduce the risk of overfitting and improves the model's generalization ability on new data.\n", + "\n", + "In summary, the role of regularization in linear regression models is to control the complexity of the model, reduce the risk of overfitting, and improve the model's generalization ability on new data.\n", + "\n", + "In this section, we primarily utilize learning curves to optimize the regularization parameter, also known as the learning curve.\n" + ] + }, + { + "cell_type": "markdown", + "id": "03100d74", + "metadata": {}, + "source": [ "## Dropout\n", "\n", "Dropout is one of the most effective and most commonly used regularization techniques for neural network, developed by Hinton and his students at the University of Toronto. Dropout, applied to a layer, consists of randomly \"dropping out\" (i.e. set to zero) a number of output features of the layer during training. Let's say a given layer would normally have returned a vector [0.2, 0.5, 1.3, 0.8, 1.1] for a given input sample during training; aafter applying dropout, this vector will have a few zero entries distributed at random, e.g. [0, 0.5, 1.3, 0, 1.1]. The 'dropout rate' is the fraction of the features that are being zeroed-out; it is usually set between 0.2 and 0.5. At test time, no units are dropped out, and instead the layer's output values are scaled down by a factor equal to the dropout rate, so as to balance for the fact that more units are active than at training time.\n", @@ -337,9 +660,14 @@ "\n", "Consider the neurons at the output layer. During training, each neuron usually get activations only from two neurons from the hidden layer (while being connected to four), due to dropout. Now, imagine we finished the training and remove dropout. Now activations of the output neurons will be computed based on four values from the hidden layer. This is likely to put the output neurons in unusual regime, so they will produce too large absolute values, being overexcited \n", "\n", - "To avoid this, the trick is to multiply the input connections' weights of the last layer by 1-p (so, by 0.5). Alternatively, one can multiply the outputs of the hidden layer by 1-p, which is basically the same \n", - "\n", - "\n", + "To avoid this, the trick is to multiply the input connections' weights of the last layer by 1-p (so, by 0.5). Alternatively, one can multiply the outputs of the hidden layer by 1-p, which is basically the same " + ] + }, + { + "cell_type": "markdown", + "id": "755eed48", + "metadata": {}, + "source": [ "## Conclusions\n", "\n", "\n", @@ -358,6 +686,8 @@ "How to choose a good model\n", ":::\n", "\n", + "The above image illustrates well why we consider bias as an important aspect in model selection and even in machine learning. When our model understands the signal, its improvement is positive. However, once the model starts to understand the noise, the bias of the model starts to increase. This is where cross-validation, mentioned earlier, comes into play.\n", + "\n", ":::{figure} https://static-1300131294.cos.ap-shanghai.myqcloud.com/images/model-selection/Bias-vs.webp\n", "---\n", "name: Conclusion-ms\n", @@ -365,10 +695,41 @@ "Conclusion \n", ":::\n", "\n", + "The purpose of model selection is to choose the best model among multiple candidate models for a given machine learning problem. The best model refers to the one that performs well on the training data and has good generalization ability to unseen new data.\n", + "\n", + "The importance of model selection lies in the fact that different models may have different adaptability to the nature of the data and the complexity of the problem. Selecting an appropriate model can improve the model's prediction accuracy, robustness, and interpretability.\n", + "\n", "## Your turn! 🚀\n", "\n", - "Machine learning model selection and dealing with overfitting and underfitting are crucial aspects of the machine learning pipeline. In this assignment, you'll have the opportunity to apply your understanding of these concepts and techniques. Please complete the following tasks:\n", - "[assignment](../assignments/ml-advanced/model-selection/model-selection-assignment-1)" + "Machine learning model selection and dealing with overfitting and underfitting are crucial aspects of the machine learning pipeline. In this assignment, you'll have the opportunity to apply your understanding of these concepts and techniques. \n", + "Please complete the following tasks:\n", + "\n", + "- [model-selection-assignment-1](../assignments/ml-advanced/model-selection/model-selection-assignment-1.ipynb)\n", + "\n", + "- [lasso-and-ridge-regression](../assignments/ml-advanced/model-selection/lasso-and-ridge-regression.ipynb)\n", + "\n", + "- [dropout-and-batch-normalization](../assignments/ml-advanced/model-selection/dropout-and-batch-normalization.ipynb)\n", + "\n", + "- [learning-curve-to-identify-overfit-underfit](../assignments/ml-advanced/model-selection/learning-curve-to-identify-overfit-underfit.ipynb)\n", + "\n", + "- [regularized-linear-models](../assignments/ml-advanced/model-selection/regularized-linear-models.ipynb)\n", + "\n", + "## Self study\n", + "\n", + "Here are some recommended open-source and free model selection projects on GitHub, you can refer to them for further study:\n", + "\n", + "- [An automated machine learning tool(AutoML), by aron-bram](https://github.com/automl/auto-sklearn)\n", + "\n", + "- [An open platform ModelHub, by 9zelle9](https://github.com/modelhub-ai/modelhub)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Acknowledgments\n", + "\n", + "Thanks to xyb for organizing the content related to model selection and for their suggestion to concretize abstract concepts.\n" ] } ], @@ -388,7 +749,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.3" } }, "nbformat": 4,