{ "metadata": { "kernelspec": { "name": "python", "display_name": "Pyolite", "language": "python" }, "language_info": { "codemirror_mode": { "name": "python", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8" } }, "nbformat_minor": 4, "nbformat": 4, "cells": [ { "cell_type": "markdown", "source": "

\n \n \"Skills\n \n

\n\n# SVM (Support Vector Machines)\n\nEstimated time needed: **15** minutes\n\n## Objectives\n\nAfter completing this lab you will be able to:\n\n* Use scikit-learn to Support Vector Machine to classify\n", "metadata": {} }, { "cell_type": "markdown", "source": "In this notebook, you will use SVM (Support Vector Machines) to build and train a model using human cell records, and classify cells to whether the samples are benign or malignant.\n\nSVM works by mapping data to a high-dimensional feature space so that data points can be categorized, even when the data are not otherwise linearly separable. A separator between the categories is found, then the data is transformed in such a way that the separator could be drawn as a hyperplane. Following this, characteristics of new data can be used to predict the group to which a new record should belong.\n", "metadata": {} }, { "cell_type": "markdown", "source": "

Table of contents

\n\n
\n
    \n
  1. Load the Cancer data
  2. \n
  3. Modeling
  4. \n
  5. Evaluation
  6. \n
  7. Practice
  8. \n
\n
\n
\n
\n", "metadata": {} }, { "cell_type": "code", "source": "#!pip install scikit-learn==0.23.1", "metadata": { "trusted": true }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": "import piplite\nawait piplite.install(['pandas'])\nawait piplite.install(['matplotlib'])\nawait piplite.install(['numpy'])\nawait piplite.install(['scikit-learn'])\nawait piplite.install(['scipy'])\n", "metadata": { "trusted": true }, "execution_count": 1, "outputs": [] }, { "cell_type": "code", "source": "import pandas as pd\nimport pylab as pl\nimport numpy as np\nimport scipy.optimize as opt\nfrom sklearn import preprocessing\nfrom sklearn.model_selection import train_test_split\n%matplotlib inline \nimport matplotlib.pyplot as plt", "metadata": { "trusted": true }, "execution_count": 2, "outputs": [] }, { "cell_type": "code", "source": "from pyodide.http import pyfetch\n\nasync def download(url, filename):\n response = await pyfetch(url)\n if response.status == 200:\n with open(filename, \"wb\") as f:\n f.write(await response.bytes())\n", "metadata": { "trusted": true }, "execution_count": 3, "outputs": [] }, { "cell_type": "markdown", "source": "

Load the Cancer data

\nThe example is based on a dataset that is publicly available from the UCI Machine Learning Repository (Asuncion and Newman, 2007)[http://mlearn.ics.uci.edu/MLRepository.html]. The dataset consists of several hundred human cell sample records, each of which contains the values of a set of cell characteristics. The fields in each record are:\n\n| Field name | Description |\n| ----------- | --------------------------- |\n| ID | Clump thickness |\n| Clump | Clump thickness |\n| UnifSize | Uniformity of cell size |\n| UnifShape | Uniformity of cell shape |\n| MargAdh | Marginal adhesion |\n| SingEpiSize | Single epithelial cell size |\n| BareNuc | Bare nuclei |\n| BlandChrom | Bland chromatin |\n| NormNucl | Normal nucleoli |\n| Mit | Mitoses |\n| Class | Benign or malignant |\n\n
\n
\n\nFor the purposes of this example, we're using a dataset that has a relatively small number of predictors in each record. To download the data, we will use `!wget` to download it from IBM Object Storage.\n\n**Did you know?** When it comes to Machine Learning, you will likely be working with large datasets. As a business, where can you host your data? IBM is offering a unique opportunity for businesses, with 10 Tb of IBM Cloud Object Storage: [Sign up now for free](http://cocl.us/ML0101EN-IBM-Offer-CC)\n", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } } }, { "cell_type": "code", "source": "#Click here and press Shift+Enter\npath=\"https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-ML0101EN-SkillsNetwork/labs/Module%203/data/cell_samples.csv\"", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "trusted": true }, "execution_count": 4, "outputs": [] }, { "cell_type": "markdown", "source": "## Load Data From CSV File\n", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } } }, { "cell_type": "code", "source": "await download(path, \"cell_samples.csv\")", "metadata": { "trusted": true }, "execution_count": 5, "outputs": [] }, { "cell_type": "code", "source": "cell_df = pd.read_csv(\"cell_samples.csv\")\ncell_df.head()", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "trusted": true }, "execution_count": 6, "outputs": [ { "execution_count": 6, "output_type": "execute_result", "data": { "text/plain": " ID Clump UnifSize UnifShape MargAdh SingEpiSize BareNuc \\\n0 1000025 5 1 1 1 2 1 \n1 1002945 5 4 4 5 7 10 \n2 1015425 3 1 1 1 2 2 \n3 1016277 6 8 8 1 3 4 \n4 1017023 4 1 1 3 2 1 \n\n BlandChrom NormNucl Mit Class \n0 3 1 1 2 \n1 3 2 1 2 \n2 3 1 1 2 \n3 3 7 1 2 \n4 3 1 1 2 ", "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
IDClumpUnifSizeUnifShapeMargAdhSingEpiSizeBareNucBlandChromNormNuclMitClass
010000255111213112
1100294554457103212
210154253111223112
310162776881343712
410170234113213112
\n
" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "The ID field contains the patient identifiers. The characteristics of the cell samples from each patient are contained in fields Clump to Mit. The values are graded from 1 to 10, with 1 being the closest to benign.\n\nThe Class field contains the diagnosis, as confirmed by separate medical procedures, as to whether the samples are benign (value = 2) or malignant (value = 4).\n\nLet's look at the distribution of the classes based on Clump thickness and Uniformity of cell size:\n", "metadata": {} }, { "cell_type": "code", "source": "ax = cell_df[cell_df['Class'] == 4][0:50].plot(kind='scatter', x='Clump', y='UnifSize', color='DarkBlue', label='malignant');\ncell_df[cell_df['Class'] == 2][0:50].plot(kind='scatter', x='Clump', y='UnifSize', color='Yellow', label='benign', ax=ax);\nplt.show()", "metadata": { "trusted": true }, "execution_count": 7, "outputs": [ { "output_type": "display_data", "data": { "text/plain": "", "image/png": "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9yo6OtrqGJZw+U2uvw1UWVmp7du3KzIyUi6Xy+o4tlRRUaGEhARt27bN2B/cthPmw16YD3thPuylKefD7/dr7969io+PV7NmZh4NxxbABmjWrJk6depkdYyQEBUVxR9UG2E+7IX5sBfmw16aaj5M3fJ3jJm1FwAAwGAUQAAAAMNQANGkwsPD9d///d8KDw+3OgrEfNgN82EvzIe9MB9Ni5NAAAAADMMWQAAAAMNQAAEAAAxDAQQAADAMBRAAAMAwFEA0uqlTp6pfv36KjIxUu3btdOONN2rTpk1Wx8JRTz75pFwul8aOHWt1FKN9++23GjFihOLi4tSyZUv17NlT69atszqWkXw+nyZOnCiPx6OWLVuqa9euevzxx43+ndhgWrFiha6//nrFx8fL5XLpvffeC1ju9/v12GOPqWPHjmrZsqXS09OVn59vTVgHoQCi0S1fvlwjR47U6tWrlZWVpcOHD+vqq6/W/v37rY5mvNzcXL300kvq1auX1VGMVlZWpgEDBqh58+ZatGiRvvrqK02bNk2xsbFWRzPSU089pZkzZ+ovf/mLvv76az311FN6+umn9ec//9nqaEbYv3+/LrzwQs2YMaPW5U8//bSmT5+uF198UWvWrFHr1q2VkZGhgwcPBjmps/A1MGhy3333ndq1a6fly5fr8ssvtzqOsfbt26c+ffrof//3fzV58mRddNFFev75562OZaTx48dr5cqV+uijj6yOAklDhgxR+/bt9eqrr1aP/fznP1fLli31xhtvWJjMPC6XS++++65uvPFGSVVb/+Lj4/Xwww/rkUcekSSVl5erffv2mjNnjm6//XYL04Y2tgCiyZWXl0uS2rRpY3ESs40cOVKDBw9Wenq61VGM98EHH6hv37669dZb1a5dO/Xu3Vsvv/yy1bGM1b9/fy1ZskR5eXmSpM8++0wff/yxrr32WouToaioSDt37gz4uxUdHa3U1FStWrXKwmShL8zqAHC2yspKjR07VgMGDNAFF1xgdRxjLViwQOvXr1dubq7VUSBp8+bNmjlzpsaNG6dHH31Uubm5Gj16tFq0aKE77rjD6njGGT9+vCoqKtS9e3e53W75fD498cQTGj58uNXRjLdz505JUvv27QPG27dvX70M9UMBRJMaOXKkvvzyS3388cdWRzHWtm3bNGbMGGVlZSkiIsLqOFDVP4z69u2r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" }, "metadata": {} }, { "output_type": "display_data", "data": { "text/plain": "
" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "## Data pre-processing and selection\n", "metadata": {} }, { "cell_type": "markdown", "source": "Let's first look at columns data types:\n", "metadata": {} }, { "cell_type": "code", "source": "cell_df.dtypes", "metadata": { "trusted": true }, "execution_count": 8, "outputs": [ { "execution_count": 8, "output_type": "execute_result", "data": { "text/plain": "ID int64\nClump int64\nUnifSize int64\nUnifShape int64\nMargAdh int64\nSingEpiSize int64\nBareNuc object\nBlandChrom int64\nNormNucl int64\nMit int64\nClass int64\ndtype: object" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "It looks like the **BareNuc** column includes some values that are not numerical. We can drop those rows:\n", "metadata": {} }, { "cell_type": "code", "source": "cell_df = cell_df[pd.to_numeric(cell_df['BareNuc'], errors='coerce').notnull()]\ncell_df['BareNuc'] = cell_df['BareNuc'].astype('int')\ncell_df.dtypes", "metadata": { "trusted": true }, "execution_count": 9, "outputs": [ { "execution_count": 9, "output_type": "execute_result", "data": { "text/plain": "ID int64\nClump int64\nUnifSize int64\nUnifShape int64\nMargAdh int64\nSingEpiSize int64\nBareNuc int32\nBlandChrom int64\nNormNucl int64\nMit int64\nClass int64\ndtype: object" }, "metadata": {} } ] }, { "cell_type": "code", "source": "feature_df = cell_df[['Clump', 'UnifSize', 'UnifShape', 'MargAdh', 'SingEpiSize', 'BareNuc', 'BlandChrom', 'NormNucl', 'Mit']]\nX = np.asarray(feature_df)\nX[0:5]", "metadata": { "trusted": true }, "execution_count": 10, "outputs": [ { "execution_count": 10, "output_type": "execute_result", "data": { "text/plain": "array([[ 5, 1, 1, 1, 2, 1, 3, 1, 1],\n [ 5, 4, 4, 5, 7, 10, 3, 2, 1],\n [ 3, 1, 1, 1, 2, 2, 3, 1, 1],\n [ 6, 8, 8, 1, 3, 4, 3, 7, 1],\n [ 4, 1, 1, 3, 2, 1, 3, 1, 1]], dtype=int64)" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "We want the model to predict the value of Class (that is, benign (=2) or malignant (=4)). As this field can have one of only two possible values, we need to change its measurement level to reflect this.\n", "metadata": {} }, { "cell_type": "code", "source": "cell_df['Class'] = cell_df['Class'].astype('int')\ny = np.asarray(cell_df['Class'])\ny [0:5]", "metadata": { "trusted": true }, "execution_count": 11, "outputs": [ { "execution_count": 11, "output_type": "execute_result", "data": { "text/plain": "array([2, 2, 2, 2, 2])" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "## Train/Test dataset\n", "metadata": {} }, { "cell_type": "markdown", "source": "We split our dataset into train and test set:\n", "metadata": {} }, { "cell_type": "code", "source": "X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=4)\nprint ('Train set:', X_train.shape, y_train.shape)\nprint ('Test set:', X_test.shape, y_test.shape)", "metadata": { "trusted": true }, "execution_count": 12, "outputs": [ { "name": "stdout", "text": "Train set: (546, 9) (546,)\nTest set: (137, 9) (137,)\n", "output_type": "stream" } ] }, { "cell_type": "markdown", "source": "

Modeling (SVM with Scikit-learn)

\n", "metadata": {} }, { "cell_type": "markdown", "source": "The SVM algorithm offers a choice of kernel functions for performing its processing. Basically, mapping data into a higher dimensional space is called kernelling. The mathematical function used for the transformation is known as the kernel function, and can be of different types, such as:\n\n```\n1.Linear\n2.Polynomial\n3.Radial basis function (RBF)\n4.Sigmoid\n```\n\nEach of these functions has its characteristics, its pros and cons, and its equation, but as there's no easy way of knowing which function performs best with any given dataset. We usually choose different functions in turn and compare the results. Let's just use the default, RBF (Radial Basis Function) for this lab.\n", "metadata": {} }, { "cell_type": "code", "source": "from sklearn import svm\nclf = svm.SVC(kernel='rbf')\nclf.fit(X_train, y_train) ", "metadata": { "trusted": true }, "execution_count": 13, "outputs": [ { "execution_count": 13, "output_type": "execute_result", "data": { "text/plain": "SVC()" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "After being fitted, the model can then be used to predict new values:\n", "metadata": {} }, { "cell_type": "code", "source": "yhat = clf.predict(X_test)\nyhat [0:5]", "metadata": { "trusted": true }, "execution_count": 14, "outputs": [ { "execution_count": 14, "output_type": "execute_result", "data": { "text/plain": "array([2, 4, 2, 4, 2])" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "

Evaluation

\n", "metadata": {} }, { "cell_type": "code", "source": "from sklearn.metrics import classification_report, confusion_matrix\nimport itertools", "metadata": { "trusted": true }, "execution_count": 15, "outputs": [] }, { "cell_type": "code", "source": "def plot_confusion_matrix(cm, classes,\n normalize=False,\n title='Confusion matrix',\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 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 plt.imshow(cm, interpolation='nearest', cmap=cmap)\n plt.title(title)\n plt.colorbar()\n tick_marks = np.arange(len(classes))\n plt.xticks(tick_marks, classes, rotation=45)\n plt.yticks(tick_marks, classes)\n\n fmt = '.2f' if normalize else 'd'\n thresh = cm.max() / 2.\n for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n plt.text(j, i, format(cm[i, j], fmt),\n horizontalalignment=\"center\",\n color=\"white\" if cm[i, j] > thresh else \"black\")\n\n plt.tight_layout()\n plt.ylabel('True label')\n plt.xlabel('Predicted label')", "metadata": { "trusted": true }, "execution_count": 16, "outputs": [] }, { "cell_type": "code", "source": "# Compute confusion matrix\ncnf_matrix = confusion_matrix(y_test, yhat, labels=[2,4])\nnp.set_printoptions(precision=2)\n\nprint (classification_report(y_test, yhat))\n\n# Plot non-normalized confusion matrix\nplt.figure()\nplot_confusion_matrix(cnf_matrix, classes=['Benign(2)','Malignant(4)'],normalize= False, title='Confusion matrix')", "metadata": { "trusted": true }, "execution_count": 17, "outputs": [ { "name": "stdout", "text": " precision recall f1-score support\n\n 2 1.00 0.94 0.97 90\n 4 0.90 1.00 0.95 47\n\n accuracy 0.96 137\n macro avg 0.95 0.97 0.96 137\nweighted avg 0.97 0.96 0.96 137\n\nConfusion matrix, without normalization\n[[85 5]\n [ 0 47]]\n", "output_type": "stream" }, { "output_type": "display_data", "data": { "text/plain": "
", "image/png": "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q69YsmQJFSpU4PDhw/Tq1Qtvb29CQkIyFsMDKFEREREREzc3N7NE5WE+/PBDBgwYYJprUqlSJc6fP8+YMWMICQnB09MTgKioKLy8vEznRUVFERAQkO54NEdFRETEVmTj8uTbt29jZ2eeRtjb25OSkgKAn58fnp6ehIWFmfbHxMSwb98+atSoke7rqKIiIiJiK7LxgW9NmzZl1KhRFCtWjAoVKvDLL78wadIk3n777XvdGQz06tWLkSNHUrp0afz8/Bg8eDDe3t40a9Ys3ddRoiIiImIrsvFdP9OnT2fw4MG89957XL16FW9vb9555x2GDBliOqZfv37ExcXRpUsXbt68SWBgIBs2bMDJySn9YRnvf4ScPFFiYmJwd3fHsVJnDPYOOR2OSLpc3Dklp0MQSZdbMTGUeKog0dHR6ZrzkRmmn+d1h2HIlf4k4H7Gu/EkbBuWLfFaQhUVERERW2GD7/pRoiIiImIrsnHoJ7soUREREbEVNlhRsc6oRERERFBFRURExHZo6EdERESsVyaGfqx0kMU6oxIRERFBFRURERHboaEfERERsVoGQyZW/ShRERERkUdJy5NFREREso8qKiIiIrZCc1RERETEatng0I8SFREREVthgxUV60yfRERERFBFRURExHZo6EdERESslg0O/ShRERERsREGgwGDjSUq1lnnEREREUEVFREREZthixUVJSoiIiK2wvD/W0bPtUJKVERERGyELVZUNEdFRERErJYqKiIiIjbCFisqSlRERERshBIVERERsVq2mKhojoqIiIhYLVVUREREbIWWJ4uIiIi1ssWhHyUqIiIiNuLeOwkzmqhkbSxZRXNURERExGLFixc3VXDu37p16waA0WhkyJAheHl54ezsTFBQEBERERZfR4mKiIiIjTCQNnFI92ZhSWX//v1cvnzZtG3atAmAN998E4Dx48czbdo0Zs+ezb59+3B1daVhw4bEx8dbdB0N/YiIiNiI7JyjUrhwYbOvx44dS8mSJalTpw5Go5EpU6YwaNAggoODAVi0aBEeHh6sWbOGFi1apPs6qqiIiIjYCkMmNyAmJsZsS0hI+M/LJiYm8uWXX/L2229jMBiIjIzkypUrBAUFmY5xd3enevXq7N2716JbUqIiIiIiJj4+Pri7u5u2MWPG/Oc5a9as4ebNm7Rv3x6AK1euAODh4WF2nIeH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WfQk3piYGNzd3Ym6Hq35KvLYePvrwzkdgki6JN2JZeU7tYiOfvQ/Y1N/nm85fIE8eTN2rdhbMbwQUIyLFy+axZueisq7777LDz/8wK5duyhatCgAe/bsoWbNmly6dMm0qASgefPmGAwGli1blq64rGboJzt88skn1K9fH1dXV3744QcWLlzIp59+mtNhmXnnnXe4efMmt27deuBj9B/k8uXLLFq0yCpfFyAiItkoC9YnW7rY4v3332ft2rXs2LHDlKQApkdwREVFmSUqUVFRBAQEpLv/JypR+fnnnxk/fjy3bt2iRIkSTJs2jU6dOuV0WGZy5crFxx9/bNE594//iYjIkys7J9MajUa6d+/O6tWr2bZtG35+fmb7/fz88PT0JCwszJSYxMTEsG/fPt599910X+eJSlSWL1+e0yGIiIg8Mpl5uaCl53Xr1o0lS5bw7bffkjdvXtO8E3d3d5ydnTEYDPTq1YuRI0dSunRp/Pz8GDx4MN7e3jRr1izd13miEhURERHJGrNmzQKgbt26Zu3z5883vVy3X79+xMXF0aVLF27evElgYCAbNmywaCGLEhUREREbkZ2P0E/PWhyDwUBoaCihoaEZCwolKiIiIrbDBl/2o0RFRETERmTnZNrsYlUPfBMRERG5nyoqIiIiNiI7V/1kFyUqIiIiNsIGp6goUREREbEZNpipaI6KiIiIWC1VVERERGyELa76UaIiIiJiIzSZVkRERKyWDU5R0RwVERERsV6qqIiIiNgKGyypKFERERGxEZpMKyIiIlbLFifTao6KiIiIWC1VVERERGyEDU5RUaIiIiJiM2wwU1GiIiIiYiNscTKt5qiIiIiI1VJFRURExEbY4qofJSoiIiI2wganqGjoR0RERKyXKioiIiK2wgZLKkpUREREbIQtrvpRoiIiImIrMjGZ1krzFM1REREREeulioqIiIiNsMEpKkpUREREbIYNZipKVERERGyELU6m1RwVERERsVpKVERERGxE6iP0M7pZaseOHTRt2hRvb28MBgNr1qwx2280GhkyZAheXl44OzsTFBRERESERddQoiIiImIjDJncLBUXF0eVKlWYOXPmA/ePHz+eadOmMXv2bPbt24erqysNGzYkPj4+3dfQHBURERFbkc2TaRs3bkzjxo0fuM9oNDJlyhQGDRpEcHAwAIsWLcLDw4M1a9bQ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\n" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "You can also easily use the **f1\\_score** from sklearn library:\n", "metadata": {} }, { "cell_type": "code", "source": "from sklearn.metrics import f1_score\nf1_score(y_test, yhat, average='weighted') ", "metadata": { "trusted": true }, "execution_count": 18, "outputs": [ { "execution_count": 18, "output_type": "execute_result", "data": { "text/plain": "0.9639038982104676" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "Let's try the jaccard index for accuracy:\n", "metadata": {} }, { "cell_type": "code", "source": "from sklearn.metrics import jaccard_score\njaccard_score(y_test, yhat,pos_label=2)", "metadata": { "trusted": true }, "execution_count": 19, "outputs": [ { "execution_count": 19, "output_type": "execute_result", "data": { "text/plain": "0.9444444444444444" }, "metadata": {} } ] }, { "cell_type": "markdown", "source": "

Practice

\nCan you rebuild the model, but this time with a __linear__ kernel? You can use __kernel='linear'__ option, when you define the svm. How the accuracy changes with the new kernel function?\n", "metadata": {} }, { "cell_type": "code", "source": "# write your code here\nclf2 = svm.SVC(kernel='linear')\nclf2.fit(X_train, y_train) \nyhat2 = clf2.predict(X_test)\nprint(\"Avg F1-score: %.4f\" % f1_score(y_test, yhat2, average='weighted'))\nprint(\"Jaccard score: %.4f\" % jaccard_score(y_test, yhat2,pos_label=2))", "metadata": { "trusted": true }, "execution_count": 20, "outputs": [ { "name": "stdout", "text": "Avg F1-score: 0.9639\nJaccard score: 0.9444\n", "output_type": "stream" } ] }, { "cell_type": "markdown", "source": "
Click here for the solution\n\n```python\nclf2 = svm.SVC(kernel='linear')\nclf2.fit(X_train, y_train) \nyhat2 = clf2.predict(X_test)\nprint(\"Avg F1-score: %.4f\" % f1_score(y_test, yhat2, average='weighted'))\nprint(\"Jaccard score: %.4f\" % jaccard_score(y_test, yhat2,pos_label=2))\n\n```\n\n
\n", "metadata": {} }, { "cell_type": "markdown", "source": "

Want to learn more?

\n\nIBM SPSS Modeler is a comprehensive analytics platform that has many machine learning algorithms. It has been designed to bring predictive intelligence to decisions made by individuals, by groups, by systems – by your enterprise as a whole. A free trial is available through this course, available here: SPSS Modeler\n\nAlso, you can use Watson Studio to run these notebooks faster with bigger datasets. Watson Studio is IBM's leading cloud solution for data scientists, built by data scientists. With Jupyter notebooks, RStudio, Apache Spark and popular libraries pre-packaged in the cloud, Watson Studio enables data scientists to collaborate on their projects without having to install anything. Join the fast-growing community of Watson Studio users today with a free account at Watson Studio\n", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false } } }, { "cell_type": "markdown", "source": "### Thank you for completing this lab!\n\n## Author\n\nSaeed Aghabozorgi\n\n### Other Contributors\n\nJoseph Santarcangelo\n\n## Change Log\n\n| Date (YYYY-MM-DD) | Version | Changed By | Change Description |\n| ----------------- | ------- | ---------- | ---------------------------------- |\n| 2021-01-21 | 2.2 | Lakshmi | Updated sklearn library |\n| 2020-11-03 | 2.1 | Lakshmi | Updated URL of csv |\n| 2020-08-27 | 2.0 | Lavanya | Moved lab to course repo in GitLab |\n| | | | |\n| | | | |\n\n##

© IBM Corporation 2020. All rights reserved.

\n", "metadata": {} } ] }