chetyre/plot_digits_classification.ipynb

369 lines
59 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"# Recognizing hand-written digits\n",
"\n",
"This example shows how scikit-learn can be used to recognize images of\n",
"hand-written digits, from 0-9.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"source": [
"# Authors: The scikit-learn developers\n",
"# SPDX-License-Identifier: BSD-3-Clause\n",
"\n",
"# Standard scientific Python imports\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Import datasets, classifiers and performance metrics\n",
"from sklearn import datasets, metrics, svm\n",
"from sklearn.model_selection import train_test_split"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Digits dataset\n",
"\n",
"The digits dataset consists of 8x8\n",
"pixel images of digits. The ``images`` attribute of the dataset stores\n",
"8x8 arrays of grayscale values for each image. We will use these arrays to\n",
"visualize the first 4 images. The ``target`` attribute of the dataset stores\n",
"the digit each image represents and this is included in the title of the 4\n",
"plots below.\n",
"\n",
"Note: if we were working from image files (e.g., 'png' files), we would load\n",
"them using :func:`matplotlib.pyplot.imread`.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAADSCAYAAAAi0d0oAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAEHdJREFUeJzt3X+QVWX9B/AH3dQsk9VSLBJYdSa1yRVwJioVpsXfymqB/eHoOjZQ0iBlM8v0C7QkSJtRSxH9x9+O4g9Ix1KZXB2nf2JzLfsxg7nalDqiLFSaQHW/85z5LgPs6l3gfLrce1+vmR245+797LmX+2HP+z7Pec6oSqVSSQAAACXbq+yCAAAAmbABAACEEDYAAIAQwgYAABBC2AAAAEIIGwAAQAhhAwAACCFsAAAAIYQNAAAghLCxC7q6utL48eN36bGLFi1Ko0aNKn2fYE+jT6A6fQLV6ZP61lBhI7+ZRvLV09NT613d4/zqV79Kn/vc59L++++fxowZk+bNm5f++c9/1nq3CKBPds3jjz+eLrnkkvTJT34y7b333rv8i4/6oE923ttvv51uuOGGdMopp6TDDjssHXDAAen4449Py5YtS//5z39qvXsE0Ce7ZvHixenTn/50+shHPpL222+/dNRRR6X58+endevWpUY0qlKpVFKDuPPOO7e7ffvtt6cnnngi3XHHHdttnz59ejr00EN3+eds2bIl/fe//0377rvvTj/23//+d/GV31x7ir6+vjRlypR09NFHp9mzZ6e//vWv6ZprrknTpk1LP//5z2u9e5RMn+z6J2v33ntvmjhxYvrLX/5SBI6XXnqp1rtFEH2y855//vn0qU99Kn3+858vAseHPvSh9Nhjj6WHHnooXXjhhem2226r9S5SMn2ya77whS8UQeMTn/hEEcr/+Mc/pltuuSUdcsghxTHZBz7wgdRQKg1s7ty5OUhV/b633nqr0sxOP/30ymGHHVbZuHHj1m233HJL8do99thjNd034umTkfnb3/5W2bx5c/H3M888szJu3Lha7xL/Q/qkunXr1lWef/75Idsvvvji4rVbu3ZtTfaL/x19suvuv//+4rW75557Ko2moaZRjcTUqVOLaRC9vb3ppJNOKqYNfetb3yruW7VqVTrzzDPTRz/60SI9H3HEEen73//+kOHfHecO5k838zBhHg24+eabi8fl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",
"text/plain": [
"<Figure size 1000x300 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"digits = datasets.load_digits()\n",
"\n",
"_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))\n",
"for ax, image, label in zip(axes, digits.images, digits.target):\n",
" ax.set_axis_off()\n",
" ax.imshow(image, cmap=plt.cm.gray_r, interpolation=\"nearest\")\n",
" ax.set_title(\"Training: %i\" % label)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Classification\n",
"\n",
"To apply a classifier on this data, we need to flatten the images, turning\n",
"each 2-D array of grayscale values from shape ``(8, 8)`` into shape\n",
"``(64,)``. Subsequently, the entire dataset will be of shape\n",
"``(n_samples, n_features)``, where ``n_samples`` is the number of images and\n",
"``n_features`` is the total number of pixels in each image.\n",
"\n",
"We can then split the data into train and test subsets and fit a support\n",
"vector classifier on the train samples. The fitted classifier can\n",
"subsequently be used to predict the value of the digit for the samples\n",
"in the test subset.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"source": [
"# flatten the images\n",
"n_samples = len(digits.images)\n",
"data = digits.images.reshape((n_samples, -1))\n",
"\n",
"# Create a classifier: a support vector classifier\n",
"clf = svm.SVC(gamma=0.001)\n",
"\n",
"# Split data into 50% train and 50% test subsets\n",
"X_train, X_test, y_train, y_test = train_test_split(\n",
" data, digits.target, test_size=0.5, shuffle=False\n",
")\n",
"\n",
"# Learn the digits on the train subset\n",
"clf.fit(X_train, y_train)\n",
"\n",
"# Predict the value of the digit on the test subset\n",
"predicted = clf.predict(X_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below we visualize the first 4 test samples and show their predicted\n",
"digit value in the title.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxsAAADSCAYAAAAi0d0oAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAEepJREFUeJzt3QlsZHUdB/D/wopyuVVAxWuLZ7xgFEUTlS0CEkXjaLzwyLbGeKPVKKImbhXjHbMGj0iMWzUYPAjdeKESdxvwDtBGvKK4XSEoYEJX48nxzO+Zqe3S3bbr+3V2Zj+fpJRO3/zmzez7dd73/d/7z5qqqqoCAADQsIOaLggAABCEDQAAIIWwAQAApBA2AACAFMIGAACQQtgAAABSCBsAAEAKYQMAAEghbAAAACmEjRUaHBwsw8PDcz9v3769rFmzpv7elKg3NjbWWD1YbfoElkevwNL0SW/rqbAxPj5ebwydr7vd7W7lYQ97WHnDG95QbrzxxtJLvvWtb/XURv2Vr3ylPOlJTyoDAwPlqKOOKhs2bCjf/OY3u71aLEKfdI8+6S16pftuvfXW8shHPrJ+/T/60Y92e3VYhD7pnk984hPlEY94RLnrXe9a7ne/+5W3vOUt5W9/+1vpNWtLD3rve99bjjvuuPLPf/6zXHHFFeXTn/50vQFdc8015bDDDlvVdTn55JPLP/7xj3LIIYes6H6xvp/85CcX3eij3tq1+88/zfnnn1/e+MY3ljPPPLN88IMfrF/3+OPzrGc9q1x88cXlec97XrdXkUXok9WlT3qXXulu3/zhD3/o9mqwDPpkdb397W8vH/7wh8vzn//88qY3van88pe/rPvlF7/4RfnOd75Tesn+86quwDOe8Yzy+Mc/vv7/V77ylfURxI997GNl69at5ayzzlr0PpEEDz/88MbX5aCDDqpTfpOarvf/io37CU94Qvn6179eH9UIr3jFK+qU/fnPf95O1H5Kn6wufdK79Ep33HTTTfUObOxUvfvd7+726rAEfbJ6/vjHP9av7ctf/vLyhS98Ye72GFE6++yz6/eZZz/72aVX9NRpVHvytKc9rf6+Y8eO+nuc13fEEUeUa6+9tjzzmc8sRx55ZHnpS19a/+6OO+4omzdvLo961KPqDeve9753efWrX11uueWWBTWrqirve9/7yv3vf/86sZ9yyil1mtzdns4b/MlPflI/9j3ucY+60Y4//vjy8Y9/fG79IlmH+UOTeztv8Oqrr64b/e53v3v93E499dTy4x//eNGhzh/84Af1UNsxxxxTP/Zzn/vccvPNNy9YdteuXeXXv/51/X0pf/nLX8q97nWvBevYWY9DDz10yfuzf9An/6VPWIpeye2VjnPPPbc8/OEPLy972cuWfR/2H/okr09+9KMfldtuu628+MUvXnB75+eLLrqo9JKeHNnYXWzYIVJ2R/wjnXHGGeUpT3lKfR5oZ4gvNu7YMEZGRupTHqJJ4py42KBiQ7nLXe5SLxdHWWKDj402vq666qry9Kc/vfz73/9ecn2+973v1adOHHvssfXQ133uc5/yq1/9qnzjG9+of451uOGGG+rlvvjFLy5ZLxrtqU99ar2xn3POOfU6fuYznylDQ0NlcnKyPPGJT1ywfKTeaLRNmzaVmZmZusHj3Movf/nLc8tccskl9WuwZcuWBRddLSYe52tf+1p95DaSdAyhxv9Hs8TzoTfoE33C8uiV3F4JP/3pT+sRvzgdZ/4OH71Dn+T1yb/+9a/6++4Hqjqv55VXXll6StVDtmzZUsUqX3bZZdXNN99cXXfdddVFF11UHXXUUdWhhx5aXX/99fVyGzdurJc799xzF9z/8ssvr2+/8MILF9x+6aWXLrj9pptuqg455JDqzDPPrO6444655d75znfWy0X9jm3bttW3xfdw2223Vccdd1y1fv366pZbblnwOPNrvf71r6/vt5i4fdOmTXM/t9vten2uvfbaudtuuOGG6sgjj6xOPvnkO70+p5122oLHevOb31wdfPDB1ezs7J2Wje9LufHGG6tTTz21Xr7zdfTRR1c//OEPl7wvq0+f6BOWR690p1ei1kknnVSdddZZ9c87duyo7/uRj3xkyfuy+vTJ6vfJlVdeWS933nnnLfqaHXHEEVUv6cnTqE477bR6mOoBD3hAPaQUQ1uRFuPc6Ple+9rXLvj5q1/9alm3bl05/fTTy5///Oe5rxNPPLGusW3btnq5yy67rE7RkVLnH3EZHR1dct0ipUdij2VjRpr59uXoze23316++93vlna7XR70oAfN3R7J/SUveUl9VChO35jvVa961YLHimQedXbu3Dl3WyTq6K3lHIGKJB1D3Rs3bqxfw8997nP148c56L/73e9W/JxYHfpEn7A8emV1eyWOcP/85z8vH/rQh1a8/nSPPlm9Pnnc4x5Xj5xEj8QoSIyUfPvb365HZ2KEJS5m7yU9eRpVnHMXF8nErAFx3l+8wcfFQvPF7+Kcv/l++9vf1qc0xHnVe7pYLXQ2jIc+9KELfh9NFkNkyxlWfPSjH12aEOf7/f3vf6+f4+5iOrQ4D/K6666rz4PseOADH7hguc46735u5HK94AUvqF/PuCCp4znPeU79+rzrXe9aMETI/kOf/Jc+YSl6ZfV6JXbQ3vGOd5S3ve1t9U4rvUOfrO57ysUXX1xe9KIX1RONhIMPPri+JiRO4frNb35TeklPho2TTjppbkaEPYk5iXdvgtg4YmO/8MILF71PbND9IDbIxfx3lHBlfv/735dLL720XHDBBQtuv+c971mfkxnnWrJ/0id7p0/o0Cur1ytxHn8cvY6dqDhaG66//vq5nbK47b73ve+KpzQlnz5ZvT4JMWIUIygR1v70pz/VISyuQ4n+iNDXS3oybOyrBz/4wfUw3ZOf/OS9zg6zfv36+nv8A88fPouku1RCjccIMe90DDnuyXKH9aIJ4/SMxVJszGgQTZ15dKjzgT0xFLjYhzHFxWD0F32ycvrkwKRXVi4+UyOe8/wjwh3vf//76684JabVaqWtA6tLn/x/ImR0RnviszZiWtzlnK64P+nJazb21Qtf+MJ6Z+C888670+9iZ2B2drb+/9hQ45y4mElmfiKNmQWWEufZxYfexLKdeh3za3Xmnd59mcWScszEEPNYd44CdXZuvvSlL9VHTWOmhJVa7vRrD3nIQ+qmilNA5q9/HIm6/PLLy2Mf+9gVPzb7N33yP/qEvdErK++VmIkozvOf/xUz/ITYgYqf4/nSP/TJ/zdF9PwRopgVK0LQa17zmtJLDqiRjQ0bNtQX13zgAx8oU1NT9YYUG3ak6LiAKeZijk9qjET71re+tV4uplGL6dfiSEtcnHP00Ufv9TFihyM+VTOmvowjMzHFWVxQFBvX/E99jAujOn94Y5q42LB3n0+5I6aBi6naYuN+3eteV58TGX+cY2q0+HTJfbHc6dfitYjzBT/72c/W80vHxa5//etfy6c+9an6AqU495b+ok/+R5+wN3pl5b0SO4XxNV9nZy5GO+KCXPqLPin7NEV0TNcbU6jH84kR8gg5nSmjd78+ZL9X9ZDOlGE/+9nP9rpcTI92+OGH7/H3F1xwQXXiiSfWU7bFFGaPecxjqnPOOaee0qzj9ttvr97znvdUxx57bL3c0NBQdc0119TTqu1t+rWOK664ojr99NPr+rEuxx9/fHX++efP/T6maTv77LOrY445plqzZs2Cqdh2n34tXHXVVdUZZ5xRT3d22GGHVaeccsqdptTc0+uz2DquZJrCW2+9tV73VqtVP358xeN///vfX/K+rD59ok9YHr3SnV7Znalv92/6pDt9smXLluqEE06on0c8n5havVffT9bEf7odeAAAgP5zQF2zAQAArB5hAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJCi7z5BfKmPoN8XS33K476IT9Hslee/ffv2xmvGJ2LSPePj443XHBsba7zmzp07S4b4FNem+eRjuvX3NGvb27x5c0+8n9J9GfseGe8pGe99YWhoqCeef6tL+15GNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUqwtXTQ7O9t4zaGhocZrTk9PN15zw4YNJcPk5GTjNScmJhqv2Wq1Gq/Zr2ZmZhqvOTIyUg5kGa8pLMfo6GjjNQcHB0uGdrudUpf+k7GtZOwnZP3tHx4ebrzm1NRU3+x7GdkAAABSCBsAAEAKYQMAAEghbAAAACmEDQAAIIWwAQAApBA2AACAFMIGAACQQtgAAABSCBsAAEAKYQMAAEghbAAAACmEDQAAIIWwAQAApBA2AACAFMIGAACQQtgAAABSCBsAAEAKYQMAAEghbAAAACnWli7avHlz4zWnp6cbr7lt27bGa87MzJQMk5OTjddstVqN16S71q1b13jNXbt29cR6hna7nVKX/tIr71E7duwoGQYGBlLq0n9mZ2cbrzk4ONh4zYmJiZJh69atjdds9dG+l5ENAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBibemiVqvVeM1169Y1XnPz5s2N15yZmSkZ1q9f33jNdrvdeE2Wb3BwsCe26ZGRkdIrJiYmGq85OjraeE2Wb/v27Y3XHBsba7zmpk2beuJvRFafeD/pTxnvKePj4z2z75Wx7zk0NFT6hZENAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBiTVVVVekjMzMzjdccHh5uvObk5GTJcMIJJzRec2pqqvGadNfg4GDjNYeGhnqiZhgZGWm85tVXX914zVar1XjNftVut3vib19GzYmJidIrfXLJJZf0xL89dPu9ajhh3zOj5nIY2QAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAgxdrSZwYHBxuvOTs7W3rF9PR04zXHx8cbrzk8PNx4zX6Vsf3t3Lmz8Zqjo6ON12y1WiXDyMhI4zW3b9/eM8+/H7fprVu3Nl5z/fr1jddst9uN15ycnCwH8ns0KzM2NtZ4zYGBgZ54T8kyNTXVE69ptxjZAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAp1uaU7S/T09PlQDY7O9vtVTigDQwMNF5z48aNjdccGxsrvWLdunWN1xwaGmq8Zr/qlW16Zmam8ZqDg4ON15ycnCwZMl7TVqvVeE1WZnR0tPGa7Xa78ZpTU1ON1xweHi4Zdu3a1RN/K7rFyAYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASCFsAAAAKYQNAAAghbABAACkEDYAAIAUwgYAAJBC2AAAAFIIGwAAQAphAwAASLGmqqoqp3T/aLfbjdecmZkpGQYGBhqvOTEx0RPryfJNTU31RJ/s3LmzZNiyZUvjNYeHhxuvSf8ZHx9vvObIyEjJsGPHjsZrDg4ONl6T/tRqtRqvOT09XTJs2rSp8ZpjY2OlXxjZAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAp1lRVVeWUBgAADmRGNgAAgBTCBgAAkELYAAAAUggbAABACmEDAABIIWwAAAAphA0AACCFsAEAAKQQNgAAgJLhP/LI/xgQyRqSAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 1000x300 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))\n",
"for ax, image, prediction in zip(axes, X_test, predicted):\n",
" ax.set_axis_off()\n",
" image = image.reshape(8, 8)\n",
" ax.imshow(image, cmap=plt.cm.gray_r, interpolation=\"nearest\")\n",
" ax.set_title(f\"Prediction: {prediction}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":func:`~sklearn.metrics.classification_report` builds a text report showing\n",
"the main classification metrics.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Classification report for classifier SVC(gamma=0.001):\n",
" precision recall f1-score support\n",
"\n",
" 0 1.00 0.99 0.99 88\n",
" 1 0.99 0.97 0.98 91\n",
" 2 0.99 0.99 0.99 86\n",
" 3 0.98 0.87 0.92 91\n",
" 4 0.99 0.96 0.97 92\n",
" 5 0.95 0.97 0.96 91\n",
" 6 0.99 0.99 0.99 91\n",
" 7 0.96 0.99 0.97 89\n",
" 8 0.94 1.00 0.97 88\n",
" 9 0.93 0.98 0.95 92\n",
"\n",
" accuracy 0.97 899\n",
" macro avg 0.97 0.97 0.97 899\n",
"weighted avg 0.97 0.97 0.97 899\n",
"\n",
"\n"
]
}
],
"source": [
"print(\n",
" f\"Classification report for classifier {clf}:\\n\"\n",
" f\"{metrics.classification_report(y_test, predicted)}\\n\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also plot a `confusion matrix <confusion_matrix>` of the\n",
"true digit values and the predicted digit values.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Confusion matrix:\n",
"[[87 0 0 0 1 0 0 0 0 0]\n",
" [ 0 88 1 0 0 0 0 0 1 1]\n",
" [ 0 0 85 1 0 0 0 0 0 0]\n",
" [ 0 0 0 79 0 3 0 4 5 0]\n",
" [ 0 0 0 0 88 0 0 0 0 4]\n",
" [ 0 0 0 0 0 88 1 0 0 2]\n",
" [ 0 1 0 0 0 0 90 0 0 0]\n",
" [ 0 0 0 0 0 1 0 88 0 0]\n",
" [ 0 0 0 0 0 0 0 0 88 0]\n",
" [ 0 0 0 1 0 1 0 0 0 90]]\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test, predicted)\n",
"disp.figure_.suptitle(\"Confusion Matrix\")\n",
"print(f\"Confusion matrix:\\n{disp.confusion_matrix}\")\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the results from evaluating a classifier are stored in the form of a\n",
"`confusion matrix <confusion_matrix>` and not in terms of `y_true` and\n",
"`y_pred`, one can still build a :func:`~sklearn.metrics.classification_report`\n",
"as follows:\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Classification report rebuilt from confusion matrix:\n",
" precision recall f1-score support\n",
"\n",
" 0 1.00 0.99 0.99 88\n",
" 1 0.99 0.97 0.98 91\n",
" 2 0.99 0.99 0.99 86\n",
" 3 0.98 0.87 0.92 91\n",
" 4 0.99 0.96 0.97 92\n",
" 5 0.95 0.97 0.96 91\n",
" 6 0.99 0.99 0.99 91\n",
" 7 0.96 0.99 0.97 89\n",
" 8 0.94 1.00 0.97 88\n",
" 9 0.93 0.98 0.95 92\n",
"\n",
" accuracy 0.97 899\n",
" macro avg 0.97 0.97 0.97 899\n",
"weighted avg 0.97 0.97 0.97 899\n",
"\n",
"\n"
]
}
],
"source": [
"# The ground truth and predicted lists\n",
"y_true = []\n",
"y_pred = []\n",
"cm = disp.confusion_matrix\n",
"\n",
"# For each cell in the confusion matrix, add the corresponding ground truths\n",
"# and predictions to the lists\n",
"for gt in range(len(cm)):\n",
" for pred in range(len(cm)):\n",
" y_true += [gt] * cm[gt][pred]\n",
" y_pred += [pred] * cm[gt][pred]\n",
"\n",
"print(\n",
" \"Classification report rebuilt from confusion matrix:\\n\"\n",
" f\"{metrics.classification_report(y_true, y_pred)}\\n\"\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}