Last active
April 7, 2025 19:04
-
-
Save georgehc/9131aee796ae5bfb99f9c65fa795b588 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# UDA Prediction and Model Validation\n", | |
"\n", | |
"Author: George H. Chen (georgechen [at symbol] cmu.edu)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"import numpy as np\n", | |
"\n", | |
"import torchvision\n", | |
"import torchvision.transforms as transforms\n", | |
"\n", | |
"np.random.seed(0)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Loading in the data and a quick data inspection" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"train_dataset = torchvision.datasets.MNIST(root='data/',\n", | |
" train=True,\n", | |
" transform=transforms.ToTensor(),\n", | |
" download=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"train_images = np.array([image.numpy() for image, label in train_dataset])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"train_labels = np.array([label for image, label in train_dataset])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(60000, 1, 28, 28)" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"train_images.shape" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"array([5, 0, 4, ..., 5, 6, 8])" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"train_labels" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<matplotlib.image.AxesImage at 0x14a6b8350>" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAaEAAAGdCAYAAAC7EMwUAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAaI0lEQVR4nO3df2jU9x3H8dfVH1d1lytBk7vUmGVF202dpWrVYP3R1cxApf4oWMtGZEPa+YOJ/cGsDNNBjdgpRdI6V0amW239Y9a6KdUMTXRkijpdRYtYjDOdCcFM72LUSMxnf4hHz1j1e975vkueD/iCufu+vY/ffuvTby75xueccwIAwMBD1gsAAHRfRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJjpab2AW3V0dOjcuXMKBALy+XzWywEAeOScU0tLi/Ly8vTQQ3e+1km7CJ07d075+fnWywAA3Kf6+noNHDjwjvuk3afjAoGA9RIAAElwL3+fpyxCH3zwgQoLC/Xwww9r5MiR2rdv3z3N8Sk4AOga7uXv85REaPPmzVq8eLGWLVumI0eO6JlnnlFJSYnOnj2bipcDAGQoXyruoj1mzBg99dRTWrduXeyx73//+5o+fbrKy8vvOBuNRhUMBpO9JADAAxaJRJSVlXXHfZJ+JXTt2jUdPnxYxcXFcY8XFxertra20/5tbW2KRqNxGwCge0h6hM6fP6/r168rNzc37vHc3Fw1NjZ22r+8vFzBYDC28ZVxANB9pOwLE259Q8o5d9s3qZYuXapIJBLb6uvrU7UkAECaSfr3CfXv3189evTodNXT1NTU6epIkvx+v/x+f7KXAQDIAEm/Eurdu7dGjhypqqqquMerqqpUVFSU7JcDAGSwlNwxYcmSJfrpT3+qUaNGady4cfr973+vs2fP6tVXX03FywEAMlRKIjR79mw1NzfrN7/5jRoaGjRs2DDt2LFDBQUFqXg5AECGSsn3Cd0Pvk8IALoGk+8TAgDgXhEhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmelovAEgnPXr08DwTDAZTsJLkWLhwYUJzffv29Tzz+OOPe55ZsGCB55nf/va3nmfmzJnjeUaSrl696nlm5cqVnmfefvttzzNdBVdCAAAzRAgAYCbpESorK5PP54vbQqFQsl8GANAFpOQ9oaFDh+rvf/977ONEPs8OAOj6UhKhnj17cvUDALirlLwndOrUKeXl5amwsFAvvfSSTp8+/a37trW1KRqNxm0AgO4h6REaM2aMNm7cqJ07d+rDDz9UY2OjioqK1NzcfNv9y8vLFQwGY1t+fn6ylwQASFNJj1BJSYlmzZql4cOH67nnntP27dslSRs2bLjt/kuXLlUkEolt9fX1yV4SACBNpfybVfv166fhw4fr1KlTt33e7/fL7/enehkAgDSU8u8Tamtr05dffqlwOJzqlwIAZJikR+j1119XTU2N6urqdODAAb344ouKRqMqLS1N9ksBADJc0j8d9/XXX2vOnDk6f/68BgwYoLFjx2r//v0qKChI9ksBADJc0iP0ySefJPu3RJoaNGiQ55nevXt7nikqKvI8M378eM8zkvTII494npk1a1ZCr9XVfP31155n1q5d63lmxowZnmdaWlo8z0jSv//9b88zNTU1Cb1Wd8W94wAAZogQAMAMEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAMz7nnLNexDdFo1EFg0HrZXQrTz75ZEJzu3fv9jzDf9vM0NHR4XnmZz/7meeZS5cueZ5JRENDQ0JzFy5c8Dxz8uTJhF6rK4pEIsrKyrrjPlwJAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmiBAAwExP6wXA3tmzZxOaa25u9jzDXbRvOHDggOeZixcvep6ZPHmy5xlJunbtmueZP/3pTwm9Fro3roQAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADPcwBT63//+l9DcG2+84Xnm+eef9zxz5MgRzzNr1671PJOoo0ePep6ZMmWK55nW1lbPM0OHDvU8I0m//OUvE5oDvOJKCABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAw43POOetFfFM0GlUwGLReBlIkKyvL80xLS4vnmfXr13uekaSf//znnmd+8pOfeJ75+OOPPc8AmSYSidz1/3muhAAAZogQAMCM5wjt3btX06ZNU15ennw+n7Zu3Rr3vHNOZWVlysvLU58+fTRp0iQdP348WesFAHQhniPU2tqqESNGqKKi4rbPr1q1SmvWrFFFRYUOHjyoUCikKVOmJPR5fQBA1+b5J6uWlJSopKTkts855/Tee+9p2bJlmjlzpiRpw4YNys3N1aZNm/TKK6/c32oBAF1KUt8TqqurU2Njo4qLi2OP+f1+TZw4UbW1tbedaWtrUzQajdsAAN1DUiPU2NgoScrNzY17PDc3N/bcrcrLyxUMBmNbfn5+MpcEAEhjKfnqOJ/PF/exc67TYzctXbpUkUgkttXX16diSQCANOT5PaE7CYVCkm5cEYXD4djjTU1Nna6ObvL7/fL7/clcBgAgQyT1SqiwsFChUEhVVVWxx65du6aamhoVFRUl86UAAF2A5yuhS5cu6auvvop9XFdXp6NHjyo7O1uDBg3S4sWLtWLFCg0ePFiDBw/WihUr1LdvX7388stJXTgAIPN5jtChQ4c0efLk2MdLliyRJJWWluqPf/yj3nzzTV25ckXz58/XhQsXNGbMGO3atUuBQCB5qwYAdAncwBRd0rvvvpvQ3M1/VHlRU1Pjeea5557zPNPR0eF5BrDEDUwBAGmNCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZriLNrqkfv36JTT317/+1fPMxIkTPc+UlJR4ntm1a5fnGcASd9EGAKQ1IgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMNzAFvuGxxx7zPPOvf/3L88zFixc9z+zZs8fzzKFDhzzPSNL777/veSbN/ipBGuAGpgCAtEaEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmOEGpsB9mjFjhueZyspKzzOBQMDzTKLeeustzzMbN270PNPQ0OB5BpmDG5gCANIaEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGG5gCBoYNG+Z5Zs2aNZ5nfvSjH3meSdT69es9z7zzzjueZ/773/96noENbmAKAEhrRAgAYMZzhPbu3atp06YpLy9PPp9PW7dujXt+7ty58vl8cdvYsWOTtV4AQBfiOUKtra0aMWKEKioqvnWfqVOnqqGhIbbt2LHjvhYJAOiaenodKCkpUUlJyR338fv9CoVCCS8KANA9pOQ9oerqauXk5GjIkCGaN2+empqavnXftrY2RaPRuA0A0D0kPUIlJSX66KOPtHv3bq1evVoHDx7Us88+q7a2ttvuX15ermAwGNvy8/OTvSQAQJry/Om4u5k9e3bs18OGDdOoUaNUUFCg7du3a+bMmZ32X7p0qZYsWRL7OBqNEiIA6CaSHqFbhcNhFRQU6NSpU7d93u/3y+/3p3oZAIA0lPLvE2publZ9fb3C4XCqXwoAkGE8XwldunRJX331Vezjuro6HT16VNnZ2crOzlZZWZlmzZqlcDisM2fO6K233lL//v01Y8aMpC4cAJD5PEfo0KFDmjx5cuzjm+/nlJaWat26dTp27Jg2btyoixcvKhwOa/Lkydq8ebMCgUDyVg0A6BK4gSmQIR555BHPM9OmTUvotSorKz3P+Hw+zzO7d+/2PDNlyhTPM7DBDUwBAGmNCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZriLNoBO2traPM/07On9BzW3t7d7nvnxj3/seaa6utrzDO4fd9EGAKQ1IgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMCM9zsOArhvP/zhDz3PvPjii55nRo8e7XlGSuxmpIk4ceKE55m9e/emYCWwwpUQAMAMEQIAmCFCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGG5gC3/D44497nlm4cKHnmZkzZ3qeCYVCnmcepOvXr3ueaWho8DzT0dHheQbpiyshAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMNzBF2kvkxp1z5sxJ6LUSuRnpd7/73YReK50dOnTI88w777zjeWbbtm2eZ9C1cCUEADBDhAAAZjxFqLy8XKNHj1YgEFBOTo6mT5+ukydPxu3jnFNZWZny8vLUp08fTZo0ScePH0/qogEAXYOnCNXU1GjBggXav3+/qqqq1N7eruLiYrW2tsb2WbVqldasWaOKigodPHhQoVBIU6ZMUUtLS9IXDwDIbJ6+MOHzzz+P+7iyslI5OTk6fPiwJkyYIOec3nvvPS1btiz2kyM3bNig3Nxcbdq0Sa+88kryVg4AyHj39Z5QJBKRJGVnZ0uS6urq1NjYqOLi4tg+fr9fEydOVG1t7W1/j7a2NkWj0bgNANA9JBwh55yWLFmi8ePHa9iwYZKkxsZGSVJubm7cvrm5ubHnblVeXq5gMBjb8vPzE10SACDDJByhhQsX6osvvtDHH3/c6Tmfzxf3sXOu02M3LV26VJFIJLbV19cnuiQAQIZJ6JtVFy1apG3btmnv3r0aOHBg7PGb31TY2NiocDgce7ypqanT1dFNfr9ffr8/kWUAADKcpysh55wWLlyoLVu2aPfu3SosLIx7vrCwUKFQSFVVVbHHrl27ppqaGhUVFSVnxQCALsPTldCCBQu0adMmffbZZwoEArH3eYLBoPr06SOfz6fFixdrxYoVGjx4sAYPHqwVK1aob9++evnll1PyBwAAZC5PEVq3bp0kadKkSXGPV1ZWau7cuZKkN998U1euXNH8+fN14cIFjRkzRrt27VIgEEjKggEAXYfPOeesF/FN0WhUwWDQehm4B9/2Pt+d/OAHP/A8U1FR4XnmiSee8DyT7g4cOOB55t13303otT777DPPMx0dHQm9FrquSCSirKysO+7DveMAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABgJqGfrIr0lZ2d7Xlm/fr1Cb3Wk08+6Xnme9/7XkKvlc5qa2s9z6xevdrzzM6dOz3PXLlyxfMM8CBxJQQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmOEGpg/ImDFjPM+88cYbnmeefvppzzOPPvqo55l0d/ny5YTm1q5d63lmxYoVnmdaW1s9zwBdEVdCAAAzRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZbmD6gMyYMeOBzDxIJ06c8Dzzt7/9zfNMe3u755nVq1d7npGkixcvJjQHIDFcCQEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZnzOOWe9iG+KRqMKBoPWywAA3KdIJKKsrKw77sOVEADADBECAJjxFKHy8nKNHj1agUBAOTk5mj59uk6ePBm3z9y5c+Xz+eK2sWPHJnXRAICuwVOEampqtGDBAu3fv19VVVVqb29XcXGxWltb4/abOnWqGhoaYtuOHTuSumgAQNfg6Serfv7553EfV1ZWKicnR4cPH9aECRNij/v9foVCoeSsEADQZd3Xe0KRSESSlJ2dHfd4dXW1cnJyNGTIEM2bN09NTU3f+nu0tbUpGo3GbQCA7iHhL9F2zumFF17QhQsXtG/fvtjjmzdv1ne+8x0VFBSorq5Ov/71r9Xe3q7Dhw/L7/d3+n3Kysr09ttvJ/4nAACkpXv5Em25BM2fP98VFBS4+vr6O+537tw516tXL/eXv/zlts9fvXrVRSKR2FZfX+8ksbGxsbFl+BaJRO7aEk/vCd20aNEibdu2TXv37tXAgQPvuG84HFZBQYFOnTp12+f9fv9tr5AAAF2fpwg557Ro0SJ9+umnqq6uVmFh4V1nmpubVV9fr3A4nPAiAQBdk6cvTFiwYIH+/Oc/a9OmTQoEAmpsbFRjY6OuXLkiSbp06ZJef/11/fOf/9SZM2dUXV2tadOmqX///poxY0ZK/gAAgAzm5X0gfcvn/SorK51zzl2+fNkVFxe7AQMGuF69erlBgwa50tJSd/bs2Xt+jUgkYv55TDY2Nja2+9/u5T0hbmAKAEgJbmAKAEhrRAgAYIYIAQDMECEAgBkiBAAwQ4QAAGaIEADADBECAJghQgAAM0QIAGCGCAEAzBAhAIAZIgQAMEOEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAzaRch55z1EgAASXAvf5+nXYRaWlqslwAASIJ7+fvc59Ls0qOjo0Pnzp1TIBCQz+eLey4ajSo/P1/19fXKysoyWqE9jsMNHIcbOA43cBxuSIfj4JxTS0uL8vLy9NBDd77W6fmA1nTPHnroIQ0cOPCO+2RlZXXrk+wmjsMNHIcbOA43cBxusD4OwWDwnvZLu0/HAQC6DyIEADCTURHy+/1avny5/H6/9VJMcRxu4DjcwHG4geNwQ6Ydh7T7wgQAQPeRUVdCAICuhQgBAMwQIQCAGSIEADCTURH64IMPVFhYqIcfflgjR47Uvn37rJf0QJWVlcnn88VtoVDIelkpt3fvXk2bNk15eXny+XzaunVr3PPOOZWVlSkvL099+vTRpEmTdPz4cZvFptDdjsPcuXM7nR9jx461WWyKlJeXa/To0QoEAsrJydH06dN18uTJuH26w/lwL8chU86HjInQ5s2btXjxYi1btkxHjhzRM888o5KSEp09e9Z6aQ/U0KFD1dDQENuOHTtmvaSUa21t1YgRI1RRUXHb51etWqU1a9aooqJCBw8eVCgU0pQpU7rcfQjvdhwkaerUqXHnx44dOx7gClOvpqZGCxYs0P79+1VVVaX29nYVFxertbU1tk93OB/u5ThIGXI+uAzx9NNPu1dffTXusSeeeML96le/MlrRg7d8+XI3YsQI62WYkuQ+/fTT2McdHR0uFAq5lStXxh67evWqCwaD7ne/+53BCh+MW4+Dc86Vlpa6F154wWQ9VpqampwkV1NT45zrvufDrcfBucw5HzLiSujatWs6fPiwiouL4x4vLi5WbW2t0apsnDp1Snl5eSosLNRLL72k06dPWy/JVF1dnRobG+PODb/fr4kTJ3a7c0OSqqurlZOToyFDhmjevHlqamqyXlJKRSIRSVJ2drak7ns+3HocbsqE8yEjInT+/Hldv35dubm5cY/n5uaqsbHRaFUP3pgxY7Rx40bt3LlTH374oRobG1VUVKTm5mbrpZm5+d+/u58bklRSUqKPPvpIu3fv1urVq3Xw4EE9++yzamtrs15aSjjntGTJEo0fP17Dhg2T1D3Ph9sdBylzzoe0u4v2ndz6ox2cc50e68pKSkpivx4+fLjGjRunxx57TBs2bNCSJUsMV2avu58bkjR79uzYr4cNG6ZRo0apoKBA27dv18yZMw1XlhoLFy7UF198oX/84x+dnutO58O3HYdMOR8y4kqof//+6tGjR6d/yTQ1NXX6F0930q9fPw0fPlynTp2yXoqZm18dyLnRWTgcVkFBQZc8PxYtWqRt27Zpz549cT/6pbudD992HG4nXc+HjIhQ7969NXLkSFVVVcU9XlVVpaKiIqNV2Wtra9OXX36pcDhsvRQzhYWFCoVCcefGtWvXVFNT063PDUlqbm5WfX19lzo/nHNauHChtmzZot27d6uwsDDu+e5yPtztONxO2p4Phl8U4cknn3zievXq5f7whz+4EydOuMWLF7t+/fq5M2fOWC/tgXnttddcdXW1O336tNu/f797/vnnXSAQ6PLHoKWlxR05csQdOXLESXJr1qxxR44ccf/5z3+cc86tXLnSBYNBt2XLFnfs2DE3Z84cFw6HXTQaNV55ct3pOLS0tLjXXnvN1dbWurq6Ordnzx43btw49+ijj3ap4/CLX/zCBYNBV11d7RoaGmLb5cuXY/t0h/Phbschk86HjImQc869//77rqCgwPXu3ds99dRTcV+O2B3Mnj3bhcNh16tXL5eXl+dmzpzpjh8/br2slNuzZ4+T1GkrLS11zt34stzly5e7UCjk/H6/mzBhgjt27JjtolPgTsfh8uXLrri42A0YMMD16tXLDRo0yJWWlrqzZ89aLzupbvfnl+QqKytj+3SH8+FuxyGTzgd+lAMAwExGvCcEAOiaiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAz/wdVbyhNmNF0pQAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"plt.imshow(train_images[0][0], cmap='gray')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"train_images = train_images[:5000]\n", | |
"train_labels = train_labels[:5000]\n", | |
"train_images_flat = train_images.reshape(len(train_images), -1) # flattens out each training image" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(5000, 784)\n" | |
] | |
} | |
], | |
"source": [ | |
"print(train_images_flat.shape)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Classification using $k$-nearest neighbors" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<style>#sk-container-id-1 {\n", | |
" /* Definition of color scheme common for light and dark mode */\n", | |
" --sklearn-color-text: black;\n", | |
" --sklearn-color-line: gray;\n", | |
" /* Definition of color scheme for unfitted estimators */\n", | |
" --sklearn-color-unfitted-level-0: #fff5e6;\n", | |
" --sklearn-color-unfitted-level-1: #f6e4d2;\n", | |
" --sklearn-color-unfitted-level-2: #ffe0b3;\n", | |
" --sklearn-color-unfitted-level-3: chocolate;\n", | |
" /* Definition of color scheme for fitted estimators */\n", | |
" --sklearn-color-fitted-level-0: #f0f8ff;\n", | |
" --sklearn-color-fitted-level-1: #d4ebff;\n", | |
" --sklearn-color-fitted-level-2: #b3dbfd;\n", | |
" --sklearn-color-fitted-level-3: cornflowerblue;\n", | |
"\n", | |
" /* Specific color for light theme */\n", | |
" --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n", | |
" --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n", | |
" --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n", | |
" --sklearn-color-icon: #696969;\n", | |
"\n", | |
" @media (prefers-color-scheme: dark) {\n", | |
" /* Redefinition of color scheme for dark theme */\n", | |
" --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n", | |
" --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n", | |
" --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n", | |
" --sklearn-color-icon: #878787;\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 {\n", | |
" color: var(--sklearn-color-text);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 pre {\n", | |
" padding: 0;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 input.sk-hidden--visually {\n", | |
" border: 0;\n", | |
" clip: rect(1px 1px 1px 1px);\n", | |
" clip: rect(1px, 1px, 1px, 1px);\n", | |
" height: 1px;\n", | |
" margin: -1px;\n", | |
" overflow: hidden;\n", | |
" padding: 0;\n", | |
" position: absolute;\n", | |
" width: 1px;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-dashed-wrapped {\n", | |
" border: 1px dashed var(--sklearn-color-line);\n", | |
" margin: 0 0.4em 0.5em 0.4em;\n", | |
" box-sizing: border-box;\n", | |
" padding-bottom: 0.4em;\n", | |
" background-color: var(--sklearn-color-background);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-container {\n", | |
" /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n", | |
" but bootstrap.min.css set `[hidden] { display: none !important; }`\n", | |
" so we also need the `!important` here to be able to override the\n", | |
" default hidden behavior on the sphinx rendered scikit-learn.org.\n", | |
" See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n", | |
" display: inline-block !important;\n", | |
" position: relative;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-text-repr-fallback {\n", | |
" display: none;\n", | |
"}\n", | |
"\n", | |
"div.sk-parallel-item,\n", | |
"div.sk-serial,\n", | |
"div.sk-item {\n", | |
" /* draw centered vertical line to link estimators */\n", | |
" background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n", | |
" background-size: 2px 100%;\n", | |
" background-repeat: no-repeat;\n", | |
" background-position: center center;\n", | |
"}\n", | |
"\n", | |
"/* Parallel-specific style estimator block */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel-item::after {\n", | |
" content: \"\";\n", | |
" width: 100%;\n", | |
" border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n", | |
" flex-grow: 1;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel {\n", | |
" display: flex;\n", | |
" align-items: stretch;\n", | |
" justify-content: center;\n", | |
" background-color: var(--sklearn-color-background);\n", | |
" position: relative;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel-item {\n", | |
" display: flex;\n", | |
" flex-direction: column;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel-item:first-child::after {\n", | |
" align-self: flex-end;\n", | |
" width: 50%;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel-item:last-child::after {\n", | |
" align-self: flex-start;\n", | |
" width: 50%;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-parallel-item:only-child::after {\n", | |
" width: 0;\n", | |
"}\n", | |
"\n", | |
"/* Serial-specific style estimator block */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-serial {\n", | |
" display: flex;\n", | |
" flex-direction: column;\n", | |
" align-items: center;\n", | |
" background-color: var(--sklearn-color-background);\n", | |
" padding-right: 1em;\n", | |
" padding-left: 1em;\n", | |
"}\n", | |
"\n", | |
"\n", | |
"/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n", | |
"clickable and can be expanded/collapsed.\n", | |
"- Pipeline and ColumnTransformer use this feature and define the default style\n", | |
"- Estimators will overwrite some part of the style using the `sk-estimator` class\n", | |
"*/\n", | |
"\n", | |
"/* Pipeline and ColumnTransformer style (default) */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-toggleable {\n", | |
" /* Default theme specific background. It is overwritten whether we have a\n", | |
" specific estimator or a Pipeline/ColumnTransformer */\n", | |
" background-color: var(--sklearn-color-background);\n", | |
"}\n", | |
"\n", | |
"/* Toggleable label */\n", | |
"#sk-container-id-1 label.sk-toggleable__label {\n", | |
" cursor: pointer;\n", | |
" display: block;\n", | |
" width: 100%;\n", | |
" margin-bottom: 0;\n", | |
" padding: 0.5em;\n", | |
" box-sizing: border-box;\n", | |
" text-align: center;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n", | |
" /* Arrow on the left of the label */\n", | |
" content: \"▸\";\n", | |
" float: left;\n", | |
" margin-right: 0.25em;\n", | |
" color: var(--sklearn-color-icon);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n", | |
" color: var(--sklearn-color-text);\n", | |
"}\n", | |
"\n", | |
"/* Toggleable content - dropdown */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-toggleable__content {\n", | |
" max-height: 0;\n", | |
" max-width: 0;\n", | |
" overflow: hidden;\n", | |
" text-align: left;\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-0);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-toggleable__content.fitted {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-0);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-toggleable__content pre {\n", | |
" margin: 0.2em;\n", | |
" border-radius: 0.25em;\n", | |
" color: var(--sklearn-color-text);\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-0);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-0);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n", | |
" /* Expand drop-down */\n", | |
" max-height: 200px;\n", | |
" max-width: 100%;\n", | |
" overflow: auto;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n", | |
" content: \"▾\";\n", | |
"}\n", | |
"\n", | |
"/* Pipeline/ColumnTransformer-specific style */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
" color: var(--sklearn-color-text);\n", | |
" background-color: var(--sklearn-color-unfitted-level-2);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
" background-color: var(--sklearn-color-fitted-level-2);\n", | |
"}\n", | |
"\n", | |
"/* Estimator-specific style */\n", | |
"\n", | |
"/* Colorize estimator box */\n", | |
"#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-2);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-2);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n", | |
"#sk-container-id-1 div.sk-label label {\n", | |
" /* The background is the default theme color */\n", | |
" color: var(--sklearn-color-text-on-default-background);\n", | |
"}\n", | |
"\n", | |
"/* On hover, darken the color of the background */\n", | |
"#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n", | |
" color: var(--sklearn-color-text);\n", | |
" background-color: var(--sklearn-color-unfitted-level-2);\n", | |
"}\n", | |
"\n", | |
"/* Label box, darken color on hover, fitted */\n", | |
"#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n", | |
" color: var(--sklearn-color-text);\n", | |
" background-color: var(--sklearn-color-fitted-level-2);\n", | |
"}\n", | |
"\n", | |
"/* Estimator label */\n", | |
"\n", | |
"#sk-container-id-1 div.sk-label label {\n", | |
" font-family: monospace;\n", | |
" font-weight: bold;\n", | |
" display: inline-block;\n", | |
" line-height: 1.2em;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-label-container {\n", | |
" text-align: center;\n", | |
"}\n", | |
"\n", | |
"/* Estimator-specific */\n", | |
"#sk-container-id-1 div.sk-estimator {\n", | |
" font-family: monospace;\n", | |
" border: 1px dotted var(--sklearn-color-border-box);\n", | |
" border-radius: 0.25em;\n", | |
" box-sizing: border-box;\n", | |
" margin-bottom: 0.5em;\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-0);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-estimator.fitted {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-0);\n", | |
"}\n", | |
"\n", | |
"/* on hover */\n", | |
"#sk-container-id-1 div.sk-estimator:hover {\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-2);\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 div.sk-estimator.fitted:hover {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-2);\n", | |
"}\n", | |
"\n", | |
"/* Specification for estimator info (e.g. \"i\" and \"?\") */\n", | |
"\n", | |
"/* Common style for \"i\" and \"?\" */\n", | |
"\n", | |
".sk-estimator-doc-link,\n", | |
"a:link.sk-estimator-doc-link,\n", | |
"a:visited.sk-estimator-doc-link {\n", | |
" float: right;\n", | |
" font-size: smaller;\n", | |
" line-height: 1em;\n", | |
" font-family: monospace;\n", | |
" background-color: var(--sklearn-color-background);\n", | |
" border-radius: 1em;\n", | |
" height: 1em;\n", | |
" width: 1em;\n", | |
" text-decoration: none !important;\n", | |
" margin-left: 1ex;\n", | |
" /* unfitted */\n", | |
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n", | |
" color: var(--sklearn-color-unfitted-level-1);\n", | |
"}\n", | |
"\n", | |
".sk-estimator-doc-link.fitted,\n", | |
"a:link.sk-estimator-doc-link.fitted,\n", | |
"a:visited.sk-estimator-doc-link.fitted {\n", | |
" /* fitted */\n", | |
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n", | |
" color: var(--sklearn-color-fitted-level-1);\n", | |
"}\n", | |
"\n", | |
"/* On hover */\n", | |
"div.sk-estimator:hover .sk-estimator-doc-link:hover,\n", | |
".sk-estimator-doc-link:hover,\n", | |
"div.sk-label-container:hover .sk-estimator-doc-link:hover,\n", | |
".sk-estimator-doc-link:hover {\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-3);\n", | |
" color: var(--sklearn-color-background);\n", | |
" text-decoration: none;\n", | |
"}\n", | |
"\n", | |
"div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n", | |
".sk-estimator-doc-link.fitted:hover,\n", | |
"div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n", | |
".sk-estimator-doc-link.fitted:hover {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-3);\n", | |
" color: var(--sklearn-color-background);\n", | |
" text-decoration: none;\n", | |
"}\n", | |
"\n", | |
"/* Span, style for the box shown on hovering the info icon */\n", | |
".sk-estimator-doc-link span {\n", | |
" display: none;\n", | |
" z-index: 9999;\n", | |
" position: relative;\n", | |
" font-weight: normal;\n", | |
" right: .2ex;\n", | |
" padding: .5ex;\n", | |
" margin: .5ex;\n", | |
" width: min-content;\n", | |
" min-width: 20ex;\n", | |
" max-width: 50ex;\n", | |
" color: var(--sklearn-color-text);\n", | |
" box-shadow: 2pt 2pt 4pt #999;\n", | |
" /* unfitted */\n", | |
" background: var(--sklearn-color-unfitted-level-0);\n", | |
" border: .5pt solid var(--sklearn-color-unfitted-level-3);\n", | |
"}\n", | |
"\n", | |
".sk-estimator-doc-link.fitted span {\n", | |
" /* fitted */\n", | |
" background: var(--sklearn-color-fitted-level-0);\n", | |
" border: var(--sklearn-color-fitted-level-3);\n", | |
"}\n", | |
"\n", | |
".sk-estimator-doc-link:hover span {\n", | |
" display: block;\n", | |
"}\n", | |
"\n", | |
"/* \"?\"-specific style due to the `<a>` HTML tag */\n", | |
"\n", | |
"#sk-container-id-1 a.estimator_doc_link {\n", | |
" float: right;\n", | |
" font-size: 1rem;\n", | |
" line-height: 1em;\n", | |
" font-family: monospace;\n", | |
" background-color: var(--sklearn-color-background);\n", | |
" border-radius: 1rem;\n", | |
" height: 1rem;\n", | |
" width: 1rem;\n", | |
" text-decoration: none;\n", | |
" /* unfitted */\n", | |
" color: var(--sklearn-color-unfitted-level-1);\n", | |
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 a.estimator_doc_link.fitted {\n", | |
" /* fitted */\n", | |
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n", | |
" color: var(--sklearn-color-fitted-level-1);\n", | |
"}\n", | |
"\n", | |
"/* On hover */\n", | |
"#sk-container-id-1 a.estimator_doc_link:hover {\n", | |
" /* unfitted */\n", | |
" background-color: var(--sklearn-color-unfitted-level-3);\n", | |
" color: var(--sklearn-color-background);\n", | |
" text-decoration: none;\n", | |
"}\n", | |
"\n", | |
"#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n", | |
" /* fitted */\n", | |
" background-color: var(--sklearn-color-fitted-level-3);\n", | |
"}\n", | |
"</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=3)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\"> KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier(n_neighbors=3)</pre></div> </div></div></div></div>" | |
], | |
"text/plain": [ | |
"KNeighborsClassifier(n_neighbors=3)" | |
] | |
}, | |
"execution_count": 10, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"from sklearn.neighbors import KNeighborsClassifier\n", | |
"classifier = KNeighborsClassifier(n_neighbors=3)\n", | |
"classifier.fit(train_images_flat, train_labels)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"predicted_train_labels = classifier.predict(train_images_flat)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"array([5, 0, 4, ..., 2, 1, 2])" | |
] | |
}, | |
"execution_count": 12, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"predicted_train_labels" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"0.9704" | |
] | |
}, | |
"execution_count": 13, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"(predicted_train_labels == train_labels).mean()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"0.9704\n" | |
] | |
} | |
], | |
"source": [ | |
"raw_accuracy = np.mean(predicted_train_labels == train_labels)\n", | |
"print(raw_accuracy)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Choosing hyperparameter $k$ (number of nearest neighbors) using a validation set" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from sklearn.model_selection import train_test_split\n", | |
"\n", | |
"proper_train_images_flat, val_images_flat, proper_train_labels, val_labels = \\\n", | |
" train_test_split(train_images_flat, train_labels, test_size=0.2, random_state=0)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"k: 1 accuracy: 0.93\n", | |
"k: 2 accuracy: 0.921\n", | |
"k: 4 accuracy: 0.925\n", | |
"k: 8 accuracy: 0.92\n", | |
"k: 16 accuracy: 0.907\n", | |
"k: 32 accuracy: 0.887\n", | |
"k: 64 accuracy: 0.86\n", | |
"k: 128 accuracy: 0.815\n", | |
"Best k: 1 accuracy: 0.93\n" | |
] | |
} | |
], | |
"source": [ | |
"best_score = -np.inf\n", | |
"best_k = None\n", | |
"best_model = None\n", | |
"\n", | |
"for k in 2**np.arange(0, 8):\n", | |
" classifier = KNeighborsClassifier(n_neighbors=k)\n", | |
" classifier.fit(proper_train_images_flat, proper_train_labels)\n", | |
" predicted_val_labels = classifier.predict(val_images_flat)\n", | |
" score = np.mean(predicted_val_labels == val_labels) # raw accuracy\n", | |
" print('k:', k, 'accuracy:', score)\n", | |
" \n", | |
" if score > best_score:\n", | |
" best_score = score\n", | |
" best_k = k\n", | |
" best_model = classifier\n", | |
"\n", | |
"print('Best k:', best_k, 'accuracy:', best_score)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Searching over multiple hyperparameters" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"best_score = -np.inf\n", | |
"best_hyperparam_setting = None\n", | |
"best_model = None\n", | |
"\n", | |
"list_of_hyperparam_settings = [(k, dist)\n", | |
" for k in 2**np.arange(0, 8)\n", | |
" for dist in ['euclidean', 'cosine', 'manhattan']]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[(1, 'euclidean'),\n", | |
" (1, 'cosine'),\n", | |
" (1, 'manhattan'),\n", | |
" (2, 'euclidean'),\n", | |
" (2, 'cosine'),\n", | |
" (2, 'manhattan'),\n", | |
" (4, 'euclidean'),\n", | |
" (4, 'cosine'),\n", | |
" (4, 'manhattan'),\n", | |
" (8, 'euclidean'),\n", | |
" (8, 'cosine'),\n", | |
" (8, 'manhattan'),\n", | |
" (16, 'euclidean'),\n", | |
" (16, 'cosine'),\n", | |
" (16, 'manhattan'),\n", | |
" (32, 'euclidean'),\n", | |
" (32, 'cosine'),\n", | |
" (32, 'manhattan'),\n", | |
" (64, 'euclidean'),\n", | |
" (64, 'cosine'),\n", | |
" (64, 'manhattan'),\n", | |
" (128, 'euclidean'),\n", | |
" (128, 'cosine'),\n", | |
" (128, 'manhattan')]" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"list_of_hyperparam_settings" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Hyperparameter setting: (1, 'euclidean') accuracy: 0.93\n", | |
"Hyperparameter setting: (1, 'cosine') accuracy: 0.946\n", | |
"Hyperparameter setting: (1, 'manhattan') accuracy: 0.918\n", | |
"Hyperparameter setting: (2, 'euclidean') accuracy: 0.921\n", | |
"Hyperparameter setting: (2, 'cosine') accuracy: 0.935\n", | |
"Hyperparameter setting: (2, 'manhattan') accuracy: 0.903\n", | |
"Hyperparameter setting: (4, 'euclidean') accuracy: 0.925\n", | |
"Hyperparameter setting: (4, 'cosine') accuracy: 0.939\n", | |
"Hyperparameter setting: (4, 'manhattan') accuracy: 0.914\n", | |
"Hyperparameter setting: (8, 'euclidean') accuracy: 0.92\n", | |
"Hyperparameter setting: (8, 'cosine') accuracy: 0.946\n", | |
"Hyperparameter setting: (8, 'manhattan') accuracy: 0.912\n", | |
"Hyperparameter setting: (16, 'euclidean') accuracy: 0.907\n", | |
"Hyperparameter setting: (16, 'cosine') accuracy: 0.926\n", | |
"Hyperparameter setting: (16, 'manhattan') accuracy: 0.887\n", | |
"Hyperparameter setting: (32, 'euclidean') accuracy: 0.887\n", | |
"Hyperparameter setting: (32, 'cosine') accuracy: 0.91\n", | |
"Hyperparameter setting: (32, 'manhattan') accuracy: 0.865\n", | |
"Hyperparameter setting: (64, 'euclidean') accuracy: 0.86\n", | |
"Hyperparameter setting: (64, 'cosine') accuracy: 0.898\n", | |
"Hyperparameter setting: (64, 'manhattan') accuracy: 0.832\n", | |
"Hyperparameter setting: (128, 'euclidean') accuracy: 0.815\n", | |
"Hyperparameter setting: (128, 'cosine') accuracy: 0.875\n", | |
"Hyperparameter setting: (128, 'manhattan') accuracy: 0.784\n", | |
"Best hyperparameter setting: (1, 'cosine') accuracy: 0.946\n" | |
] | |
} | |
], | |
"source": [ | |
"for hyperparam_setting in list_of_hyperparam_settings:\n", | |
" k, dist = hyperparam_setting\n", | |
"\n", | |
" classifier = KNeighborsClassifier(n_neighbors=k, metric=dist)\n", | |
" classifier.fit(proper_train_images_flat, proper_train_labels)\n", | |
" predicted_val_labels = classifier.predict(val_images_flat)\n", | |
" score = np.mean(predicted_val_labels == val_labels)\n", | |
" print('Hyperparameter setting:', hyperparam_setting, 'accuracy:', score)\n", | |
"\n", | |
" if score > best_score:\n", | |
" best_score = score\n", | |
" best_hyperparam_setting = hyperparam_setting\n", | |
" best_model = classifier\n", | |
"\n", | |
"print('Best hyperparameter setting:', best_hyperparam_setting, 'accuracy:', best_score)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Finally actually looking at the test data" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"test_dataset = torchvision.datasets.MNIST(root='data/',\n", | |
" train=False,\n", | |
" transform=transforms.ToTensor(),\n", | |
" download=True)\n", | |
"test_images = np.array([image.numpy() for image, label in test_dataset])\n", | |
"test_labels = np.array([label for image, label in test_dataset])\n", | |
"\n", | |
"test_images_flat = test_images.reshape(len(test_images), -1) # flattens out each test image" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(10000, 1, 28, 28)" | |
] | |
}, | |
"execution_count": 21, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"test_images.shape" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(10000, 784)" | |
] | |
}, | |
"execution_count": 22, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"test_images_flat.shape" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"0.9375\n" | |
] | |
} | |
], | |
"source": [ | |
"predicted_test_labels = best_model.predict(test_images_flat)\n", | |
"test_set_accuracy = np.mean(predicted_test_labels == test_labels)\n", | |
"print(test_set_accuracy)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Confusion matrix\n", | |
"\n", | |
"We can visualize to see where (in terms of which classes) predictions agree or disagree with the true labels on the test set. This can help us quickly see which classes seem to be hard cases." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x14a6e4350>" | |
] | |
}, | |
"execution_count": 24, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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", | |
"text/plain": [ | |
"<Figure size 640x480 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n", | |
"\n", | |
"cm = confusion_matrix(test_labels, best_model.predict(test_images_flat),\n", | |
" labels=best_model.classes_)\n", | |
"ConfusionMatrixDisplay(confusion_matrix=cm,\n", | |
" display_labels=best_model.classes_).plot()" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python [conda env:base] *", | |
"language": "python", | |
"name": "conda-base-py" | |
}, | |
"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.12.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment