{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "**Chapter 3 – Classification**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# To support both python 2 and python 3\n", "from __future__ import division, print_function, unicode_literals\n", "\n", "# Common imports\n", "import numpy as np\n", "import os\n", "\n", "# to make this notebook's output stable across runs\n", "np.random.seed(42)\n", "\n", "# To plot pretty figures\n", "%matplotlib inline\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "mpl.rc('axes', labelsize=14)\n", "mpl.rc('xtick', labelsize=12)\n", "mpl.rc('ytick', labelsize=12)\n", "\n", "# Where to save the figures\n", "PROJECT_ROOT_DIR = \".\"\n", "CHAPTER_ID = \"classification\"\n", "\n", "def save_fig(fig_id, tight_layout=True):\n", " path = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID, fig_id + \".png\")\n", " print(\"Saving figure\", fig_id)\n", " if tight_layout:\n", " plt.tight_layout()\n", " plt.savefig(path, format='png', dpi=300)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# MNIST" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Download and Read the data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To download the data set\n", "from sklearn.datasets import fetch_openml\n", "import sklearn\n", "import numpy as np\n", "def sort_by_target(mnist):\n", " reorder_train = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[:60000])]))[:, 1]\n", " reorder_test = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[60000:])]))[:, 1]\n", " mnist.data[:60000] = mnist.data[reorder_train]\n", " mnist.target[:60000] = mnist.target[reorder_train]\n", " mnist.data[60000:] = mnist.data[reorder_test + 60000]\n", " mnist.target[60000:] = mnist.target[reorder_test + 60000]\n", "print('The scikit-learn version is {}.'.format(sklearn.__version__))\n", "#If scikit-learn version is <0.20, please use conda update scikit-learn to update " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Reading Data\n", "mnist = fetch_openml('mnist_784',version = 1, cache = True)\n", "mnist.target = mnist.target.astype(np.int8)\n", "sort_by_target(mnist)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mnist.data.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X, y = mnist[\"data\"], mnist[\"target\"]\n", "X.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "some_digit = X[36000]\n", "some_digit_image = some_digit.reshape(28, 28)\n", "plt.imshow(some_digit_image, cmap = mpl.cm.binary,\n", " interpolation=\"nearest\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "shuffle_index = np.random.permutation(60000)\n", "X_train, y_train = mnist[\"data\"][:60000], mnist[\"target\"][:60000]\n", "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train a binary classifier:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_train_5 = (y_train == 5)\n", "y_test_5 = (y_test == 5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import SGDClassifier\n", "sgd_clf = SGDClassifier(max_iter=5, tol=-np.infty, random_state=42)\n", "#https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html\n", "sgd_clf.fit(X_train, y_train_5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sgd_clf.predict([some_digit])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Performance Measures:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Measuring Accuracy Using Cross-Validation:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import cross_val_score\n", "cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Implementing corss-validation:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import StratifiedKFold\n", "from sklearn.base import clone\n", "\n", "skfolds = StratifiedKFold(n_splits=3, random_state=42)\n", "\n", "for train_index, test_index in skfolds.split(X_train, y_train_5):\n", " clone_clf = clone(sgd_clf)\n", " X_train_folds = X_train[train_index]\n", " y_train_folds = (y_train_5[train_index])\n", " X_test_fold = X_train[test_index]\n", " y_test_fold = (y_train_5[test_index])\n", "\n", " clone_clf.fit(X_train_folds, y_train_folds)\n", " y_pred = clone_clf.predict(X_test_fold)\n", " n_correct = sum(y_pred == y_test_fold)\n", " print(n_correct / len(y_pred))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check another naive classifier:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.base import BaseEstimator\n", "class Never5Classifier(BaseEstimator):\n", " def fit(self, X, y=None):\n", " pass\n", " def predict(self, X):\n", " return np.zeros((len(X), 1), dtype=bool)\n", "never_5_clf = Never5Classifier()\n", "cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Confusion Matrix: Count the number of times instances of class A are classfied as class B" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import cross_val_predict\n", "\n", "y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)\n", "#cross_val_predict perform K fold cross-validation and returns the predictions made on each test fold\n", "len(y_train_pred)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import confusion_matrix\n", "\n", "confusion_matrix(y_train_5, y_train_pred)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_train_perfect_predictions = y_train_5\n", "confusion_matrix(y_train_5, y_train_perfect_predictions)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Precision: TP/(TP+FP), Recall : TP/(TP+FN)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import precision_score, recall_score\n", "\n", "precision_score(y_train_5, y_train_pred)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "recall_score(y_train_5, y_train_pred)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "F_1 score: harmonic mean of precision and recall: 2/(1/pre+1/rec)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import f1_score\n", "f1_score(y_train_5, y_train_pred)" ] }, { "attachments": { "Screenshot%20from%202019-01-27%2017-27-36.png": { "image/png": "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vWHDhkEe1xlx7733EkKWLFlyqh2wirj00kvZGzdt2hSRoD5z5sy+q4vt27dHzClTpkxpaWlh77Nq1SpCyFdffVVTUyOVSjGN8ng8kUik0Wg6OjoYhnnssccIIR988AHDMF988QU+ateuXRFfd/DgQaVSaTQa6QwYCASeffZZ9hRJCHn66ad/9rSsXr0a8+/BgwdnzJiBPxSJREuXLj1y5Ah7zx07dhBCli5d+v3331Pf68svv4z//eabb1QqFfvbr7jiipKSkr7f+Pbbb7On1CuuuAIZkjabje5z2223EUK2bNkScS0i7NUrr7wSK7qOjg6NRgNDi8fjicViqVTqdDodDodWq9VqtRFjePPNN9lTtkAgWLVqVVVVFXufjz76SCgUbtmyxW63syUx0tPT169fH/GBd9xxB/kpl156aVdX18+ef44RBTkbM+cXFLnyer1/+MMfPvvss4aGhieeeOKrr746vdvm66+/vu+++4qKiubOnZubm2u1Wk+ePPnRRx/Nnj37uuuue/nll/EG6ejouO666zZu3KjX6//whz+kp6dXVlZu27bt+uuvp6I0YOvWrUuXLhWJRHfccYfZbFar1Q0NDXv37t2+ffuFF174/vvvz58/nxCyYMGCzZs3Hz161Gw2z5071+fz4fUNKQvU2t5///0HDhz44YcfnE4n+53l9XqfeeYZiUSCqSIcDr/55ptPPvlkR0fHsmXLcnJyNBrNkSNHPvvss7y8vPvuu+/uu+8+/UkIhUL79++fPHkyn89/4IEHDAbDvn37Pv744yVLlqxduzY/P5/uRgh5/PHHt2/fnpiYKJfLqVP51Vdfveuuu8Lh8OLFiy+88EKZTLZ37941a9YsXrx4w4YN9K3k8XiWL1++a9cui8WC8OCOHTuuueaavh7NQCAQDoeZ3jzpQCBw4403fvHFF1qt9qabbho3bpzH41mzZs27776rUCheffVVQsiVV17J5/P379+v1+uvuuqqnp4eeK1wMtnly3feeecbb7whEolWrlw5ffp0h8Oxdu3awsLCefPmrV+/fvz48fR4w+HwPffcc+DAgVWrVmm12tbW1vXr1+/Zs2flypU7d+6k/sK77rrro48+Sk1NXbFiRVxcXE9Pz6ZNm7Zs2TJt2rSvv/764osvPs3JH0vMnDnTarW63e6+sdbTEw6HOzs7hUJhTk7OII2N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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "Precision/Recall Tradeoff:![Screenshot%20from%202019-01-27%2017-27-36.png](attachment:Screenshot%20from%202019-01-27%2017-27-36.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_scores = sgd_clf.decision_function([some_digit])\n", "y_scores" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "threshold = 200000\n", "y_some_digit_pred = (y_scores > threshold)\n", "y_some_digit_pred" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Decide which Threshold to use: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n", " method=\"decision_function\")\n", "#by setting method = \"decision_function\", cross_val_predict returns the decision scores" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#For all possible threshods:\n", "from sklearn.metrics import precision_recall_curve\n", "#https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_curve.html\n", "precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n", " plt.plot(thresholds, precisions[:-1], \"b--\", label=\"Precision\", linewidth=2)\n", " plt.plot(thresholds, recalls[:-1], \"g-\", label=\"Recall\", linewidth=2)\n", " plt.xlabel(\"Threshold\", fontsize=16)\n", " plt.legend(loc=\"upper left\", fontsize=16)\n", " plt.ylim([0, 1])\n", "\n", "plt.figure(figsize=(8, 4))\n", "plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n", "plt.xlim([-700000, 700000])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "95% precision classfier:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_train_pred_90 = (y_scores > 70000)\n", "precision_score(y_train_5, y_train_pred_90)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.plot(recalls, precisions)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another measurement - receiver operating characteristic (ROC): recall/1-specificity , specificity: true negative rate, 1-specificity: false negative rate" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import roc_curve\n", "\n", "fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def plot_roc_curve(fpr, tpr, label=None):\n", " plt.plot(fpr, tpr, linewidth=2, label=label)\n", " plt.plot([0, 1], [0, 1], 'k--')\n", " plt.axis([0, 1, 0, 1])\n", " plt.xlabel('False Positive Rate', fontsize=16)\n", " plt.ylabel('True Positive Rate', fontsize=16)\n", "\n", "plt.figure(figsize=(8, 6))\n", "plot_roc_curve(fpr, tpr)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import roc_auc_score\n", "#area under the curve \n", "roc_auc_score(y_train_5, y_scores)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another classfier: RandomForestClassifier()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.ensemble import RandomForestClassifier\n", "forest_clf = RandomForestClassifier(n_estimators=10, random_state=42)\n", "y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n", " method=\"predict_proba\")\n", "#predict_proba method returns an array containing a row per instance and a column per class, \n", "#each containing the probability that the given instance belongs to the given class" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_probas_forest" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_scores_forest = y_probas_forest[:, 1] # score = proba of positive class\n", "fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.figure(figsize=(8, 6))\n", "plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n", "plot_roc_curve(fpr_forest, tpr_forest, \"Random Forest\")\n", "plt.legend(loc=\"lower right\", fontsize=16)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "roc_auc_score(y_train_5, y_scores_forest)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multiclass Classification: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "one to all strategy : train 10 binary classifiers. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sgd_clf.fit(X_train, y_train)\n", "sgd_clf.predict([some_digit])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "some_digit_scores = sgd_clf.decision_function([some_digit]) #10 scores, one per class\n", "some_digit_scores" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.argmax(some_digit_scores)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "one to one strategy: for each pair of digits, one classifier" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.multiclass import OneVsOneClassifier\n", "ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5, tol=-np.infty, random_state=42))\n", "ovo_clf.fit(X_train, y_train)\n", "ovo_clf.predict([some_digit])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(ovo_clf.estimators_)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "some_digit_scores = ovo_clf.decision_function([some_digit])\n", "some_digit_scores" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#RandomForestClassifier:\n", "forest_clf.fit(X_train, y_train)\n", "forest_clf.predict([some_digit])\n", "forest_clf.predict_proba([some_digit])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "cross-validation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Better\n", "from sklearn.preprocessing import StandardScaler\n", "scaler = StandardScaler()\n", "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64)) #scaling the inputs\n", "cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Error Analysis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n", "conf_mx = confusion_matrix(y_train, y_train_pred)\n", "conf_mx" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.matshow(conf_mx, cmap=plt.cm.gray)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "row_sums = conf_mx.sum(axis=1, keepdims=True)\n", "norm_conf_mx = conf_mx / row_sums\n", "np.fill_diagonal(norm_conf_mx, 0)\n", "plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Analyse individual errors:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cl_a, cl_b = 3, 5\n", "# GN: rows with True value are selected\n", "X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)] #GN: '3' classified as 3\n", "X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)] #GN: '3' classified as 5\n", "X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)] #GN: '5' classified as 3\n", "X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)] #GN: '5' classified as 5\n", "\n", "def plot_digits(instances, images_per_row=10, **options):\n", " size = 28\n", " images_per_row = min(len(instances), images_per_row)\n", " images = [instance.reshape(size,size) for instance in instances]\n", " n_rows = (len(instances) - 1) // images_per_row + 1\n", " row_images = []\n", " n_empty = n_rows * images_per_row - len(instances)\n", " images.append(np.zeros((size, size * n_empty)))\n", " for row in range(n_rows):\n", " rimages = images[row * images_per_row : (row + 1) * images_per_row]\n", " row_images.append(np.concatenate(rimages, axis=1))\n", " image = np.concatenate(row_images, axis=0)\n", " plt.imshow(image, cmap = mpl.cm.binary, **options)\n", " plt.axis(\"off\")\n", " \n", "plt.figure(figsize=(8,8))\n", "plt.subplot(221); plot_digits(X_aa[:25], images_per_row=5)\n", "plt.subplot(222); plot_digits(X_ab[:25], images_per_row=5)\n", "plt.subplot(223); plot_digits(X_ba[:25], images_per_row=5)\n", "plt.subplot(224); plot_digits(X_bb[:25], images_per_row=5)\n", "plt.show()\n", "#SGDclassifier is quite sensitive to image shifting and rotation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multilabel Classification" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.neighbors import KNeighborsClassifier\n", "\n", "y_train_large = (y_train >= 7)\n", "y_train_odd = (y_train % 2 == 1)\n", "#https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.c_.html\n", "y_multilabel = np.c_[y_train_large, y_train_odd] #concatenation\n", "\n", "knn_clf = KNeighborsClassifier()\n", "knn_clf.fit(X_train, y_multilabel)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "knn_clf.predict([some_digit])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3, n_jobs=-1)\n", "f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")\n", "#This running may take time\n", "# To give more weight to one of the label, set average = \"weighted\"\n", "#https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multioutput Classification" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Multioutput = multilabel + multiclass [multiouput system is not limited to classification problems]\n", "#Build a system that removes noise from images (noisy image -> clean digit image)\n", "#multilabel: one label per pixel\n", "#multiclass: each label can have multiple values" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "noise = np.random.randint(0, 100, (len(X_train), 784))\n", "X_train_mod = X_train + noise\n", "noise = np.random.randint(0, 100, (len(X_test), 784))\n", "X_test_mod = X_test + noise\n", "y_train_mod = X_train\n", "y_test_mod = X_test" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "some_index = 5500\n", "def plot_digit(data):\n", " image = data.reshape(28, 28)\n", " plt.imshow(image, cmap = mpl.cm.binary,\n", " interpolation=\"nearest\")\n", " plt.axis(\"off\")\n", "plt.subplot(121); plot_digit(X_test_mod[some_index])\n", "plt.subplot(122); plot_digit(y_test_mod[some_index])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "knn_clf.fit(X_train_mod, y_train_mod)\n", "clean_digit = knn_clf.predict([X_test_mod[some_index]])\n", "plot_digit(clean_digit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extra Material: Random Classifier: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.dummy import DummyClassifier\n", "dmy_clf = DummyClassifier()\n", "y_probas_dmy = cross_val_predict(dmy_clf, X_train, y_train_5, cv=3, method=\"predict_proba\")\n", "y_scores_dmy = y_probas_dmy[:, 1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fprr, tprr, thresholdsr = roc_curve(y_train_5, y_scores_dmy)\n", "plot_roc_curve(fprr, tprr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Questions/Exercises" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.Try to build a classifier for the MNIST dataset that achieves over 97% accuracy on the test set.\n", "Hint: the KNeighborsClassifier works quite well for this task; you just need to find good hyperparameter values (try a grid search on the weights and n_neighbors hyperparameters)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import fetch_openml\n", "import sklearn\n", "import numpy as np\n", "def sort_by_target(mnist):\n", " reorder_train = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[:60000])]))[:, 1]\n", " reorder_test = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[60000:])]))[:, 1]\n", " mnist.data[:60000] = mnist.data[reorder_train]\n", " mnist.target[:60000] = mnist.target[reorder_train]\n", " mnist.data[60000:] = mnist.data[reorder_test + 60000]\n", " mnist.target[60000:] = mnist.target[reorder_test + 60000]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "print('The scikit-learn version is {}.'.format(sklearn.__version__)) #If scikit-learn version is <0.20, please use conda update scikit-learn to update " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Reading Data\n", "mnist = fetch_openml('mnist_784',version = 1, cache = True)\n", "mnist.target = mnist.target.astype(np.int8)\n", "sort_by_target(mnist)\n", "shuffle_index = np.random.permutation(60000)\n", "X_train, y_train = mnist[\"data\"][:60000], mnist[\"target\"][:60000]\n", "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Classifier: KNeighborsClassifier()\n", "# https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Grid Search: GridSearchCV()\n", "#https://scikit-learn.org/stable/modules/grid_search.html" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.Data Augmentation\n", "Write a function that can shift an MNIST image in any direction (left, right, up or down) by one pixel. Then for each image in the training set create four shifted copies (one per direction) and add them to the training set. Finally, train your best model on this expanded training set and measure its accuracy on the test set. \n", "\n", "Hint: you can use shift() function from the scipy.ndimage.interpolation module (https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.ndimage.interpolation.shift.html): shift(image, [2,1], cval=0, model=\"constant\") shifts the image 2 pixels down and 1 pixel to the right. Moreover, the points outside the boundaries are filled with \"cval=0\".\n", "\n", "Obersevation: Your model should perform even better! This techinique of artifically growing the training set is called \"data augmentation\" or \"trainig set expansion\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Give a function which takes the image and shift it $dx$ along the x axis and $dy$ along the y axis\n", "def shift_image(image, dx, dy):\n", " image = image.reshape([28,28])\n", " shifted_image = #To fill \n", " return shifted_image.reshape([-1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Test the function, taking one digit as example and plot it\n", "image = X_train[1000]\n", "shifted_left = shift_image(image,-5,0)\n", "plt.imshow(shifted_left.reshape(28,28), interpolation = \"nearest\", cmap=\"Greys\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#For each training image, create four shifted images (one pixel to each direction) and put them into training set.\n", "X_train_augmented = [image for image in X_train]\n", "y_train_augmented = [label for label in y_train]\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Shuffle the new training set\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Train the new training set on the previous best classfier (KNeighborsClassifier) and show the accuracy." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Tackle the Titanic dataset: \n", "The goal is to predict whether a passenger survived based on attributes like age, sex, passenger class etc.\n", "Download the data (https://project.inria.fr/chuan/course_material_classification/) which includes one train.csv and one test.csv. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Load the data into list\n", "import pandas as pd\n", "train_data = pd.read_csv() #To fill the path of train.csv\n", "test_data = pd.read_csv() #To fill the path of test.csv" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To see the details of the data\n", "train_data.head()\n", "test_data.head()\n", "#The meanings of the attributes: https://www.kaggle.com/c/titanic/data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To see how much data is missing\n", "train_data.info()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Dispaly numerical attributes information \n", "train_data.describe()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Reuse the DataframeSelector from last course to select specific attributes from the DataFrame\n", "from sklearn.base import BaseEstimator, TransformerMixin\n", "class DataFrameSelector(BaseEstimator, TransformerMixin):\n", " def __init__(self, attribute_names):\n", " self.attribute_names = attribute_names\n", " def fit(self, X, y=None):\n", " return self\n", " def transform(self, X):\n", " return X[self.attribute_names]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To fill: Build the pipeline for the numerical attributes \"Age\", \"SibSp\", \"Parch\", \"Fare\"\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.impute import SimpleImputer\n", "\n", "num_pipeline = Pipeline()\n", "num_pipeline.fit_transform(train_data)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Build the pipeline for the string categorical attributes \"Pclass\", \"Sex\", \"Embarked\"\n", "from sklearn.preprocessing import OneHotEncoder\n", "class MostFrequentImputer(BaseEstimator, TransformerMixin):\n", " def fit(self, X, y=None):\n", " self.most_frequent_ = pd.Series([X[c].value_counts().index[0] for c in X],\n", " index=X.columns)\n", " return self\n", " def transform(self, X, y=None):\n", " return X.fillna(self.most_frequent_)\n", "cat_pipeline = Pipeline([\n", " (\"select_cat\", DataFrameSelector([\"Pclass\", \"Sex\", \"Embarked\"])),\n", " (\"imputer\", MostFrequentImputer()),\n", " (\"cat_encoder\", OneHotEncoder(sparse=False)),\n", " ])\n", "cat_pipeline.fit_transform(train_data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Join the numerical and categorical pipelines\n", "from sklearn.pipeline import FeatureUnion\n", "preprocess_pipeline = FeatureUnion(transformer_list=[\n", " (\"num_pipeline\", num_pipeline),\n", " (\"cat_pipeline\", cat_pipeline),\n", " ])\n", "X_train = preprocess_pipeline.fit_transform(train_data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To fill: get the labels for the training data\n", "y_train = " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To fill: Choose a binary classifier for training and have a prediction on the test data\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To fill: Use cross-validation to have an idea of how good our model is" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Option: choose another classifier to see if it improves the result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note: To improve the result further, you could:\n", "\n", " 1)Compare many more models and tune hyperparameters using cross validation and grid search,\n", " 2)Do more feature engineering, for example:\n", " replace SibSp and Parch with their sum,\n", " try to identify parts of names that correlate well with the Survived attribute \n", " (e.g. if the name contains \"Countess\", then survival seems more likely),\n", " 3)try to convert numerical attributes to categorical attributes: for example, different age groups had very different survival rates (see below), so it may help to create an age bucket category and use it instead of the age. Similarly, it may be useful to have a special category for people traveling alone since only 30% of them survived.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Build a SPAM Classifier" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Download the examples of spam and ham from Apache SpamAssasin's public datasets. \n", "import os\n", "import tarfile\n", "from six.moves import urllib\n", "\n", "DOWNLOAD_ROOT = \"http://spamassassin.apache.org/old/publiccorpus/\"\n", "HAM_URL = DOWNLOAD_ROOT + \"20030228_easy_ham.tar.bz2\"\n", "SPAM_URL = DOWNLOAD_ROOT + \"20030228_spam.tar.bz2\"\n", "SPAM_PATH = os.path.join(\"datasets\", \"spam\")\n", "\n", "def fetch_spam_data(spam_url=SPAM_URL, spam_path=SPAM_PATH):\n", " if not os.path.isdir(spam_path):\n", " os.makedirs(spam_path)\n", " for filename, url in ((\"ham.tar.bz2\", HAM_URL), (\"spam.tar.bz2\", SPAM_URL)):\n", " path = os.path.join(spam_path, filename)\n", " if not os.path.isfile(path):\n", " urllib.request.urlretrieve(url, path)\n", " tar_bz2_file = tarfile.open(path) #Unzip the datasets \n", " tar_bz2_file.extractall(path=SPAM_PATH)\n", " tar_bz2_file.close()\n", "fetch_spam_data()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "HAM_DIR = os.path.join(SPAM_PATH, \"easy_ham\")\n", "SPAM_DIR = os.path.join(SPAM_PATH, \"spam\")\n", "ham_filenames = [name for name in sorted(os.listdir(HAM_DIR)) if len(name) > 20]\n", "spam_filenames = [name for name in sorted(os.listdir(SPAM_DIR)) if len(name) > 20]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(ham_filenames)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#We can use Python's email module to parse these emails (this handles headers, encoding, and so on):\n", "import email\n", "import email.policy\n", "\n", "def load_email(is_spam, filename, spam_path=SPAM_PATH):\n", " directory = \"spam\" if is_spam else \"easy_ham\"\n", " with open(os.path.join(spam_path, directory, filename), \"rb\") as f:\n", " return email.parser.BytesParser(policy=email.policy.default).parse(f)\n", "ham_emails = [load_email(is_spam=False, filename=name) for name in ham_filenames]\n", "spam_emails = [load_email(is_spam=True, filename=name) for name in spam_filenames]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(ham_emails[1].get_content().strip())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#To fill: split the datasets into a training set and a test set\n", "#Hint: using train_test_split function from sklearn.model_selection \n", "\n", "X_train, X_test, y_train, y_test = " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Email prepocessing - convert HTML to plain text: The following function first drops the section, then converts all tags to the word HYPERLINK, then it gets rid of all HTML tags, leaving only the plain text. For readability, it also replaces multiple newlines with single newlines, and finally it unescapes html entities (such as > or  ):\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import re\n", "from html import unescape\n", "\n", "def html_to_plain_text(html):\n", " text = re.sub('.*?', '', html, flags=re.M | re.S | re.I)\n", " text = re.sub('', ' HYPERLINK ', text, flags=re.M | re.S | re.I)\n", " text = re.sub('<.*?>', '', text, flags=re.M | re.S)\n", " text = re.sub(r'(\\s*\\n)+', '\\n', text, flags=re.M | re.S)\n", " return unescape(text)\n", "\n", "def email_to_text(email):\n", " html = None\n", " for part in email.walk():\n", " ctype = part.get_content_type()\n", " if not ctype in (\"text/plain\", \"text/html\"):\n", " continue\n", " try:\n", " content = part.get_content()\n", " except: # in case of encoding issues\n", " content = str(part.get_payload())\n", " if ctype == \"text/plain\":\n", " return content\n", " else:\n", " html = content\n", " if html:\n", " return html_to_plain_text(html)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(spam_emails[7].get_content().strip())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(html_to_plain_text(spam_emails[7].get_content())[:100], \"...\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(email_to_text(spam_emails[7])[:100], \"...\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**In the following: a data preparation pipeline is done to convert each mail into a feature vector indicating the presence or absence of each possible word. \n", "For example, if all emails only ever contain four words, \"Hello\", \"how\", \"are\", \"you\", then the email \"Hello you Hello Hello you\" would be converted into a vector [1,0,0,1] (existence) or [3,0,0,2] (counting)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.base import BaseEstimator, TransformerMixin\n", "import urlextract #pip3 install urlextract\n", "from collections import Counter\n", "import nltk #pip3 install nltk \n", "import numpy as np\n", "\n", "class EmailToWordCounterTransformer(BaseEstimator, TransformerMixin):\n", " def __init__(self, strip_headers=True, lower_case=True, remove_punctuation=True,\n", " replace_urls=True, replace_numbers=True, stemming=True):\n", " self.strip_headers = strip_headers\n", " self.lower_case = lower_case\n", " self.remove_punctuation = remove_punctuation\n", " self.replace_urls = replace_urls\n", " self.replace_numbers = replace_numbers\n", " self.stemming = stemming\n", " def fit(self, X, y=None):\n", " return self\n", " def transform(self, X, y=None):\n", " X_transformed = []\n", " for email in X:\n", " text = email_to_text(email) or \"\"\n", " if self.lower_case:\n", " text = text.lower()\n", " if self.replace_urls and urlextract.URLExtract() is not None:\n", " #replace URLs with the word \"URL\"\n", " urls = list(set(urlextract.URLExtract().find_urls(text)))\n", " urls.sort(key=lambda url: len(url), reverse=True)\n", " for url in urls:\n", " text = text.replace(url, \" URL \")\n", " if self.replace_numbers:\n", " text = re.sub(r'\\d+(?:\\.\\d*(?:[eE]\\d+))?', 'NUMBER', text)\n", " if self.remove_punctuation:\n", " text = re.sub(r'\\W+', ' ', text, flags=re.M)\n", " word_counts = Counter(text.split()) #split sentences into words using Python's split() method, which uses whitespaces for word boundaries\n", " if self.stemming and nltk.PorterStemmer() is not None:\n", " # stemming\n", " stemmed_word_counts = Counter()\n", " for word, count in word_counts.items():\n", " stemmed_word = nltk.PorterStemmer().stem(word)\n", " stemmed_word_counts[stemmed_word] += count\n", " word_counts = stemmed_word_counts\n", " X_transformed.append(word_counts)\n", " return np.array(X_transformed)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X_few = spam_emails[:2]\n", "X_few_wordcounts = EmailToWordCounterTransformer().fit_transform(X_few)\n", "X_few_wordcounts" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Now we have the word counts, and we need to convert them to vectors. For this, we will build another transformer whose fit() method will build the vocabulary (an ordered list of the most common words) and whose transform() method will use the vocabulary to convert word counts to vectors. The output is a sparse matrix.\n", "from scipy.sparse import csr_matrix\n", "\n", "class WordCounterToVectorTransformer(BaseEstimator, TransformerMixin):\n", " def __init__(self, vocabulary_size=1000):\n", " self.vocabulary_size = vocabulary_size\n", " def fit(self, X, y=None):\n", " total_count = Counter()\n", " for word_count in X:\n", " for word, count in word_count.items():\n", " total_count[word] += min(count, 10)\n", " most_common = total_count.most_common()[:self.vocabulary_size]\n", " self.most_common_ = most_common\n", " self.vocabulary_ = {word: index + 1 for index, (word, count) in enumerate(most_common)}\n", " return self\n", " def transform(self, X, y=None):\n", " rows = []\n", " cols = []\n", " data = []\n", " for row, word_count in enumerate(X):\n", " for word, count in word_count.items():\n", " rows.append(row)\n", " cols.append(self.vocabulary_.get(word, 0))\n", " data.append(count)\n", " return csr_matrix((data, (rows, cols)), shape=(len(X), self.vocabulary_size + 1))\n", "vocab_transformer = WordCounterToVectorTransformer(vocabulary_size=10)\n", "X_few_vectors = vocab_transformer.fit_transform(X_few_wordcounts)\n", "X_few_vectors.toarray()\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vocab_transformer.vocabulary_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To fill: Try out several classifiers and see if you can build a great spam classifier, with both high recall and high precision" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.pipeline import Pipeline\n", "\n", "preprocess_pipeline = Pipeline([\n", " (\"email_to_wordcount\", EmailToWordCounterTransformer()),\n", " (\"wordcount_to_vector\", WordCounterToVectorTransformer()),\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }