{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# [NTDS'19] tutorial 5: machine learning with scikit-learn\n", "[ntds'19]: https://github.com/mdeff/ntds_2019\n", "\n", "[Nicolas Aspert](https://people.epfl.ch/nicolas.aspert), [EPFL LTS2](https://lts2.epfl.ch).\n", "\n", "* Dataset: [digits](https://archive.ics.uci.edu/ml/datasets/Pen-Based+Recognition+of+Handwritten+Digits)\n", "* Tools: [scikit-learn](https://scikit-learn.org/stable/), [numpy](http://www.numpy.org), [scipy](https://www.scipy.org), [matplotlib](https://matplotlib.org)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*scikit-learn* is a machine learning python library. Most commonly used algorithms for classification, clustering and regression are implemented as part of the library, e.g.\n", "* [Logistic regression](https://en.wikipedia.org/wiki/Logistic_regression)\n", "* [k-means clustering](https://en.wikipedia.org/wiki/K-means_clustering)\n", "* [Support vector machines](https://en.wikipedia.org/wiki/Support-vector_machine)\n", "* ...\n", "\n", "The aim of this tutorial is to show basic usage of some simple machine learning techniques. \n", "Check the official [documentation](https://scikit-learn.org/stable/documentation.html) for more information, especially the [tutorials](https://scikit-learn.org/stable/tutorial/index.html) section." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "import numpy as np\n", "from matplotlib import pyplot as plt\n", "import sklearn" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data loading\n", "\n", "We will use a dataset named *digits*.\n", "It is made of 1797 handwritten digits images (of size 8x8 pixels each) acquired from 44 different writers. \n", "Each image is labelled according to the digit present in the image.\n", "\n", "You can find more information about this dataset [here](https://archive.ics.uci.edu/ml/datasets/Pen-Based+Recognition+of+Handwritten+Digits).\n", "\n", "![digits](https://scikit-learn.org/stable/_images/sphx_glr_plot_lle_digits_001.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load the dataset." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import load_digits\n", "\n", "digits = load_digits()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `digits` variable contains several fields.\n", "\n", "In `images` you have all samples as 2-dimensional arrays." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1797, 8, 8)\n", "[[ 0. 0. 5. 13. 9. 1. 0. 0.]\n", " [ 0. 0. 13. 15. 10. 15. 5. 0.]\n", " [ 0. 3. 15. 2. 0. 11. 8. 0.]\n", " [ 0. 4. 12. 0. 0. 8. 8. 0.]\n", " [ 0. 5. 8. 0. 0. 9. 8. 0.]\n", " [ 0. 4. 11. 0. 1. 12. 7. 0.]\n", " [ 0. 2. 14. 5. 10. 12. 0. 0.]\n", " [ 0. 0. 6. 13. 10. 0. 0. 0.]]\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "print(digits.images.shape)\n", "print(digits.images[0])\n", "plt.imshow(digits.images[0], cmap=plt.cm.gray);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In `data`, the same samples are represented as 1-d vectors of length 64." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1797, 64)\n", "[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3.\n", " 15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0.\n", " 0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12.\n", " 0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]\n" ] } ], "source": [ "print(digits.data.shape)\n", "print(digits.data[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " In `target` you have the label corresponding to each image." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1797,)\n", "[0 1 2 ... 8 9 8]\n" ] } ], "source": [ "print(digits.target.shape)\n", "print(digits.target)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us visualize the 20 first entries of the dataset (image display kept small on purpose)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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NwAAAACgnK5HlgAAAADgLYGLJQAAAABowMUSAAAAADTgYgkAAAAAGnCxBAAAAAANWp/hYGYTl8pbv379eHvnzp21fQ899NB4e/v27bV9p06dmvh+7j6vh5u1xRk98sgjtdcLFy4cb99+++21fQ88MHmF0fnGKU0f6+rVq2uvDx06NN5+7LHHWn836uOYbtu2bbydz/1TTz013l65cmVtX8lzH8+1JO3fv3+8vW7duqnfr484Y7l8+umna/tuvvnm+bxd0bq0fPnyqd+vr7q0ZcuW8XY+9/F8L1u2rLbv9OnT4+0lS5bU9p06darzY3rXXXc1xiXVy2j8PUl68cUXJ75fH+c+tj/5eLa1P236iDPGdscdd9T2xbqUy29bG9B3XcpiG5DPczzWeV9fdenaa68db2/dWl8tOB63tjKZdXFMc/2MdT63mzG2WJalej3LfWvf5z6X0fgZ8ufru87H8yzVz3Wu87ndjJYuXTrezv3ZW/14StO3TzG2/DqX0bbvAX0c07Y60daO5s8U9RFnjGUu7X2bSXEysgQAAAAADeb9dPA4onD55ZfX9i1atGi8/cILL9T23XDDDePtgweHfWhxvpOwatWq8faaNWtq+9pGlvoS78gfPny4tq/tjnff8uhRHFXctGlTbd+ePXvG2ytWrKjtiyOOQ8t3ZvLdkpLi+YxlUpI2bNgw3n7mmWcm/rshxDuPOc4dO3YMGstc5Hof737lO2Hxzt9c7pTPV9soXCyzefRmvqM508plK991juKz+h5/vP5Q97mMMnYh3hHNMccymtuD+Dr+H0PIcV522WWN29Lw5VOSDhw4MPE943HLo599y2U01okcSzxumzdvru2Ln2mIfiHGksthHomZ9O/6OPcbN26svY5tfPz+IdXrUr5r3/YZ+pbbxXichqovUW7/YtvSNtLVd/t+NjGW/Bnivlx+Y70bohzEke3cVs53ZGkSRpYAAAAAoAEXSwAAAADQgIslAAAAAGgw9ZylPP8kzlO64ooravviimgPPvjgxP9niDlLMd+yLQ90FuawxPzLnPsfV0fJK/f1be/evbXXu3btGm8fPXq0ti+e+5JzlKT23PCYW9s292eIvNuYA5zzbmOueNsKdEPkY7fNS8qr95TWNn8irprTNu9hCLHdaVsJsW1VtC7ysbO8+lV05MiR2usY99DHr21uVZxrI9XP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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(15, 0.5))\n", "for index, (image, label) in enumerate(zip(digits.images[0:20], digits.target[0:20])):\n", " ax = fig.add_subplot(1, 20, index+1)\n", " ax.imshow(image, cmap=plt.cm.gray)\n", " ax.set_title(label)\n", " ax.axis('off')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Training/Test set\n", "\n", "Before training our model, the [`train_test_split`](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) function will separate our dataset into a training set and a test set. The samples from the test set are never used during the training phase. This allows for a fair evaluation of the model's performance." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split\n", "\n", "train_img, test_img, train_lbl, test_lbl = train_test_split(\n", " digits.data, digits.target, test_size=1/6) # keep ~300 images as test set" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can check that all classes are well balanced in the training and test sets." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([151, 152, 143, 157, 151, 149, 155, 155, 137, 147]),\n", " array([0. , 0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 6.3, 7.2, 8.1, 9. ]))" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.histogram(train_lbl, bins=10)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([27, 30, 34, 26, 30, 33, 26, 24, 37, 33]),\n", " array([0. , 0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 6.3, 7.2, 8.1, 9. ]))" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.histogram(test_lbl, bins=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Supervised learning: logistic regression\n", "\n", "### Linear regression reminder\n", "\n", "Linear regression is used to predict an dependent value $y$ from an n-dimensional vector $x$.\n", "The assumption made here is that the output depends linearly on the input components, i.e. $y = mx + b$.\n", "\n", "Given a set of input and output values, the goal is to compute $m$ and $b$ minimizing the [mean squared error (MSE)](https://en.wikipedia.org/wiki/Mean_squared_error) between the predicted and actual outputs.\n", "In scikit-learn this method is available through [`LinearRegression`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html).\n", "\n", "### Logistic regression\n", "\n", "Logistic regression is used to predict categorical data (e.g. yes/no, member/non-member, ham/spam, benign/malignant, ...).\n", "It uses the output of a linear predictor, and maps it to a probability using a [sigmoid function](https://en.wikipedia.org/wiki/Sigmoid_function), such as the logistic function $s(z) = \\frac{1}{1+e^{-z}}$. \n", "The output is a probability score between 0 and 1, and using a simple thresholding the class output will be positive if the probability is greater than 0.5, negative if not.\n", "A [log-loss cost function](http://wiki.fast.ai/index.php/Logistic_Regression#Cost_Function) (not just the MSE as for linear regression) is used to train logistic regression (using gradient descent for instance).\n", "\n", "[Multinomial logistic regression](https://en.wikipedia.org/wiki/Multinomial_logistic_regression) is an extension of the binary classification problem to a $n$-classes problem." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now create a logistic regression object and fit the parameters using the training data.\n", "\n", "NB: as the dataset is quite simple, default parameters will give good results. Check the [documentation](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html) for fine-tuning possibilities." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import LogisticRegression\n", "\n", "# All unspecified parameters are left to their default values.\n", "logisticRegr = LogisticRegression(verbose=1, solver='liblinear', multi_class='auto') # set solver and multi_class to silence warnings" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[LibLinear]" ] }, { "data": { "text/plain": [ "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n", " intercept_scaling=1, l1_ratio=None, max_iter=100,\n", " multi_class='auto', n_jobs=None, penalty='l2',\n", " random_state=None, solver='liblinear', tol=0.0001, verbose=1,\n", " warm_start=False)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "logisticRegr.fit(train_img, train_lbl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model performance evaluation\n", "\n", "For a binary classification problem, let us denote by $TP$, $TN$, $FP$, and $FN$ the number of true positives, true negatives, false positives and false negatives.\n", "\n", "### Accuracy\n", "\n", "The *accuracy* is defined by $a = \\frac{TP}{TP + TN + FP + FN}$\n", "\n", "NB: in scikit-learn, models may have different definitions of the `score` method. For multi-class logistic regression, the value is the mean accuracy for each class." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "accuracy = 0.9600\n" ] } ], "source": [ "score = logisticRegr.score(test_img, test_lbl)\n", "print(f'accuracy = {score:.4f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### F1 score\n", "\n", "Accuracy only provides partial information about the performance of a model. Many other [metrics](https://scikit-learn.org/stable/modules/model_evaluation.html#classification-metrics) are part of scikit-learn.\n", "\n", "A metric that provides a more complete overview of the classification performance is the [F1 score](https://en.wikipedia.org/wiki/F1_score). It takes into account not only the valid predictions but also the incorrect ones, by combining precision and recall.\n", "\n", "*Precision* is the number of positive predictions divided by the total number of positive class values predicted, i.e. $p=\\frac{TP}{TP+FP}$. A low precision indicates a high number of false positives.\n", "\n", "*Recall* is the number of positive predictions divided by the number of positive class values in the test data, i.e. $r=\\frac{TP}{TP+FN}$. A low recall indicates a high number of false negatives.\n", "\n", "Finally the F1 score is the harmonic mean between precision and recall, i.e. $F1=2\\frac{p.r}{p+r}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us compute the predicted labels in the test set:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "pred_lbl = logisticRegr.predict(test_img)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import f1_score, classification_report\n", "from sklearn.utils.multiclass import unique_labels" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The [`f1_score`](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html#sklearn.metrics.f1_score) function computes the F1 score. The `average` parameter controls whether the result is computed globally over all classes (`average='micro'`) or if the F1 score is computed for each class then averaged (`average='macro'`)." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.96" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f1_score(test_lbl, pred_lbl, average='micro')" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9594503798365037" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f1_score(test_lbl, pred_lbl, average='macro')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`classification_report` provides a synthetic overview of all results for each class, as well as globally." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 1.00 1.00 1.00 27\n", " 1 0.91 0.97 0.94 30\n", " 2 1.00 1.00 1.00 34\n", " 3 0.95 0.81 0.88 26\n", " 4 1.00 0.97 0.98 30\n", " 5 1.00 1.00 1.00 33\n", " 6 1.00 0.96 0.98 26\n", " 7 0.92 1.00 0.96 24\n", " 8 0.88 0.97 0.92 37\n", " 9 0.97 0.91 0.94 33\n", "\n", " accuracy 0.96 300\n", " macro avg 0.96 0.96 0.96 300\n", "weighted avg 0.96 0.96 0.96 300\n", "\n" ] } ], "source": [ "print(classification_report(test_lbl, pred_lbl))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Confusion matrix\n", "\n", "In the case of a multi-class problem, the *confusion matrix* is often used to present the results." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import confusion_matrix\n", "\n", "def plot_confusion_matrix(y_true, y_pred, classes,\n", " normalize=False,\n", " title=None,\n", " cmap=plt.cm.Blues):\n", " \"\"\"\n", " This function prints and plots the confusion matrix.\n", " Normalization can be applied by setting `normalize=True`.\n", " \"\"\"\n", " if not title:\n", " if normalize:\n", " title = 'Normalized confusion matrix'\n", " else:\n", " title = 'Confusion matrix, without normalization'\n", "\n", " # Compute confusion matrix\n", " cm = confusion_matrix(y_true, y_pred)\n", " # Only use the labels that appear in the data\n", " classes = classes[unique_labels(y_true, y_pred)]\n", " if normalize:\n", " cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n", " print(\"Normalized confusion matrix\")\n", " else:\n", " print('Confusion matrix, without normalization')\n", "\n", " print(cm)\n", "\n", " fig, ax = plt.subplots()\n", " im = ax.imshow(cm, interpolation='nearest', cmap=cmap)\n", " ax.figure.colorbar(im, ax=ax)\n", " # We want to show all ticks...\n", " ax.set(xticks=np.arange(cm.shape[1]),\n", " yticks=np.arange(cm.shape[0]),\n", " # ... and label them with the respective list entries\n", " xticklabels=classes, yticklabels=classes,\n", " title=title,\n", " ylabel='True label',\n", " xlabel='Predicted label')\n", "\n", " # Rotate the tick labels and set their alignment.\n", " plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n", " rotation_mode=\"anchor\")\n", "\n", " # Loop over data dimensions and create text annotations.\n", " fmt = '.2f' if normalize else 'd'\n", " thresh = cm.max() / 2.\n", " for i in range(cm.shape[0]):\n", " for j in range(cm.shape[1]):\n", " ax.text(j, i, format(cm[i, j], fmt),\n", " ha=\"center\", va=\"center\",\n", " color=\"white\" if cm[i, j] > thresh else \"black\")\n", " fig.tight_layout()\n", " return ax" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Confusion matrix, without normalization\n", "[[27 0 0 0 0 0 0 0 0 0]\n", " [ 0 29 0 1 0 0 0 0 0 0]\n", " [ 0 0 34 0 0 0 0 0 0 0]\n", " [ 0 0 0 21 0 0 0 0 4 1]\n", " [ 0 1 0 0 29 0 0 0 0 0]\n", " [ 0 0 0 0 0 33 0 0 0 0]\n", " [ 0 1 0 0 0 0 25 0 0 0]\n", " [ 0 0 0 0 0 0 0 24 0 0]\n", " [ 0 1 0 0 0 0 0 0 36 0]\n", " [ 0 0 0 0 0 0 0 2 1 30]]\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_confusion_matrix(test_lbl, pred_lbl, np.array(list(map(lambda x: str(x), range(10)))), normalize=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Supervised learning: support-vector machines\n", "\n", "[Support-vector machines (SVM)](https://en.wikipedia.org/wiki/Support-vector_machine) are also used for classification tasks.\n", "For a binary classification task of $n$-dimensional feature vectors, a linear SVM try to return the ($n-1$)-dimensional hyperplane that separate the two classes with the largest possible margin.\n", "Nonlinear SVMs fit the maximum-margin hyperplane in a transformed feature space.\n", "Although the classifier is a hyperplane in the transformed feature space, it may be nonlinear in the original input space. \n", "\n", "The goal here is to show that a method (e.g. the previously used logistic regression) can be substituted transparently for another one." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "from sklearn import svm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Default parameters perform well on this dataset.\n", "It might be needed to adjust $C$ and $\\gamma$ (e.g. via a grid search) for optimal performance (cf. [SVC documentation](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC))." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "clf = svm.SVC(gamma='scale') # default kernel is RBF" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n", " decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',\n", " max_iter=-1, probability=False, random_state=None, shrinking=True,\n", " tol=0.001, verbose=False)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.fit(train_img, train_lbl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The classification accuracy improves with respect to logistic regression (here `score` also computes mean accuracy, as in logistic regression)." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9933333333333333" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.score(test_img, test_lbl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The F1 score is also improved." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 1.00 1.00 1.00 27\n", " 1 0.97 1.00 0.98 30\n", " 2 0.97 1.00 0.99 34\n", " 3 1.00 0.96 0.98 26\n", " 4 1.00 1.00 1.00 30\n", " 5 1.00 1.00 1.00 33\n", " 6 1.00 1.00 1.00 26\n", " 7 1.00 1.00 1.00 24\n", " 8 1.00 0.97 0.99 37\n", " 9 1.00 1.00 1.00 33\n", "\n", " accuracy 0.99 300\n", " macro avg 0.99 0.99 0.99 300\n", "weighted avg 0.99 0.99 0.99 300\n", "\n" ] } ], "source": [ "pred_lbl_svm = clf.predict(test_img)\n", "print(classification_report(test_lbl, pred_lbl_svm))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Unsupervised learning: $k$-means\n", "\n", "[$k$-means](https://en.wikipedia.org/wiki/K-means_clustering) aims at partitioning a samples into $k$ clusters, s.t. each sample belongs to the cluster having the closest mean. Its implementation is iterative, and relies on a prior knowledge of the number of clusters present. \n", "\n", "One important step in $k$-means clustering is the initialization, i.e. the choice of initial clusters to be refined.\n", "This choice can have a significant impact on results." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "from sklearn.cluster import KMeans" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "kmeans = KMeans(n_clusters=10)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,\n", " n_clusters=10, n_init=10, n_jobs=None, precompute_distances='auto',\n", " random_state=None, tol=0.0001, verbose=0)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kmeans.fit(digits.data)\n", "km_labels = kmeans.predict(digits.data)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, ..., 8, 9, 8])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "digits.target" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([9, 7, 7, ..., 7, 4, 4], dtype=int32)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "km_labels" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we have ground truth information of classes, we can check if the $k$-means results make sense.\n", "However as you can see, the labels produced by $k$-means and the ground truth ones do not match.\n", "An agreement score based on [mutual information](https://scikit-learn.org/stable/modules/clustering.html#clustering-evaluation), insensitive to labels permutation can be used to evaluate the results. " ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import adjusted_mutual_info_score" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/michael/.conda/envs/ntds_2019/lib/python3.7/site-packages/sklearn/metrics/cluster/supervised.py:746: FutureWarning: The behavior of AMI will change in version 0.22. To match the behavior of 'v_measure_score', AMI will use average_method='arithmetic' by default.\n", " FutureWarning)\n" ] }, { "data": { "text/plain": [ "0.7366155637042371" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "adjusted_mutual_info_score(digits.target, kmeans.labels_)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Unsupervized learning: dimensionality reduction\n", "\n", "You can also try to visualize the clusters as in this [scikit-learn demo](https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_digits.html). Mapping the input features to lower dimensional embeddings (2D or 3D), e.g. using PCA otr tSNE is required for visualization. [This demo](https://scikit-learn.org/stable/auto_examples/manifold/plot_lle_digits.html) provides an overview of the possibilities." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "from matplotlib import offsetbox\n", "\n", "def plot_embedding(X, y, title=None):\n", " \"\"\"Scale and visualize the embedding vectors.\"\"\"\n", " x_min, x_max = np.min(X, 0), np.max(X, 0)\n", " X = (X - x_min) / (x_max - x_min)\n", "\n", " plt.figure()\n", " ax = plt.subplot(111)\n", " for i in range(X.shape[0]):\n", " plt.text(X[i, 0], X[i, 1], str(y[i]),\n", " color=plt.cm.Set1(y[i] / 10.),\n", " fontdict={'weight': 'bold', 'size': 9})\n", "\n", " if hasattr(offsetbox, 'AnnotationBbox'):\n", " # only print thumbnails with matplotlib > 1.0\n", " shown_images = np.array([[1., 1.]]) # just something big\n", " for i in range(X.shape[0]):\n", " dist = np.sum((X[i] - shown_images) ** 2, 1)\n", " if np.min(dist) < 4e-3:\n", " # don't show points that are too close\n", " continue\n", " shown_images = np.r_[shown_images, [X[i]]]\n", " imagebox = offsetbox.AnnotationBbox(\n", " offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r),\n", " X[i])\n", " ax.add_artist(imagebox)\n", " plt.xticks([]), plt.yticks([])\n", " if title is not None:\n", " plt.title(title)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "from sklearn import manifold" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)\n", "X_tsne = tsne.fit_transform(digits.data)\n", "\n", "plot_embedding(X_tsne, digits.target,\n", " \"t-SNE embedding of the digits (ground truth labels)\")" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_embedding(X_tsne, km_labels,\n", " \"t-SNE embedding of the digits (kmeans labels)\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }