{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "**CSC 466: Knowledge Discovery in Data **\n", "\n", "** Individual Test**\n", "\n", "**Task 2 **" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your Name :** \n", "\n", "**Cal Poly Email:** \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your Assignment**:\n", "\n", "1. Run 10-fold cross-validation on top of the trainMagicClassifier() classification method\n", "2. For each fold, report prediction accuracy\n", "3. Report overall prediction accuracy\n", "4. Report the overall confusion matrix" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Imports\n", "\n", "import numpy as np\n", "from matplotlib import pyplot as plt\n", "import seaborn\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Classifier**\n", "\n", "trainMagicClassifier() is a simple implementation of Support Vector Machine, with some hardcoded parameters.\n", "It takes as input a dataset \"data\", the array of labels \"labels\" (data point data[i] has class label label[i]), and two hyperparameters: Rate (this parameter in the context of SVMs is called the learing rate) and the number of iterations to complete (SVMs are typically trained using an iterative approach until convergence, this classifier replaces convergence with simply a number of iterations).\n", "\n", "You do not need to understand the code in trainMagicClassifier(), nor do you need to make any changes in this part of the notebook. The trained model is three coefficients model[0], model[1], model[2], which combine to form an equation of a line in 2D that separates the two classes:\n", "\n", "$$model[0]\\cdot x + model[1]\\cdot y + model[2] = 0$$\n", "\n", "where $x$ and $y$ are the coordinates of the 2D data point.\n", "\n", "**Note:** like all SVM classifiers, ours works only on binary classes, with class labels +1 and -1.\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def trainMagicClassifier(data, labels, Rate, iterations):\n", "\n", " C = 2 ## error significance\n", " thetas = np.ones(len(data))*-1\n", " w = np.array([-1,0,0]) # starting approximation \n", " \n", " # svmData = np.array([data[0],data[1], thetas])\n", " for j in range(iterations):\n", " HingeLoss = np.array([0,0,0])\n", " for i in range(len(data)):\n", " datum = data[i]\n", " \n", " ## compute the hinge loss\n", " y = labels[i]\n", " uVector = np.array([datum[0], datum[1], thetas[i]])\n", " if (w[0]*datum[0]+ w[1]*datum[1]+ w[2]*thetas[i])*y <= 1:\n", " HingeLoss = HingeLoss - y*uVector\n", " \n", " \n", " w = w - Rate *(w + C * HingeLoss)\n", " ##print(\"W:\", w)\n", " ## print(\"Loss:\", HingeLoss)\n", " ## plotW(slo,paso,w)\n", " return(w)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Predictor**:\n", "\n", "Using the model trained in trainMagicClassifier(), the predictor computes on which side of the line separating the classes a data point is, and returns the side (above = +1, below = -1) as the class predictor.\n", "\n", "You do not need to modify this code." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def predict(model, point):\n", " value = np.sign(model[0]*point[0]+model[1]*point[1]+model[2])\n", " ## print(value)\n", " return value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The generatePredictions(function) simply generates the list of predictions given a collection of the data points" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def generatePredictions(model, data):\n", " predictions = [predict(model, point) for point in data]\n", " return predictions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Execution Starts Here**\n", "\n", "First, we read the data, and split the input into the data table, and the class labels table." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [], "source": [ "filename=\"data5.csv\"\n", "\n", "rawData = np.loadtxt(filename, delimiter = \",\")\n", "\n", "## let's keep only the two columns with the data attributes\n", "\n", "data = rawData[:,0:2]\n", "labels = rawData[:,2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Training the Classifier**\n", "\n", "We set the learning rate to 0.01 (established empirically, don't worry about it).\n", "Then we train the classifier on the entire data set." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [], "source": [ "rate = 0.01\n", "model = trainMagicClassifier(data, labels, rate, 20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below,we display the learned model parameters" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([-7.35152749, 5.94812682, 1.17282658])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "... and generate the predictions" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [], "source": [ "predictions =generatePredictions(model,data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** Plotting**\n", "To illustrate the accuracy of the predictor we plot the model (blue line) against the scatter plot of the dataset colored according to the ground truth labels.\n", "\n", "As seen, our predictor does really well, misclassifying only two red points at the left edge of the scatter plot.\n", "\n", "**However**, we trained and tested on the same data." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "colors = ['red','red', 'green']\n", "prColors = [colors[int(i+1)] for i in labels ]\n", "\n", "plt.scatter(data[:,0], data[:,1], c=prColors)\n", "plt.plot(data[:,0], -(model[0]/model[1])*data[:,0] - model[2]/model[1])\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Your Task**\n", "In the cells below build the functionality for conducting the 10-fold cross-validation of the trainMagicClassifier() classifier.\n", "\n", "Each fold shall contain 10% of randomly selected points from the input dataset.\n", "\n", "For each fold, train on all other folds, then test on it and compute the accuracy.\n", "\n", "Report the accuracy of each fold, overall accuracy, and print out the confusion matrix\n", "\n", "**Notes**: you may want to create a function that splits the dataset into folds. For this task, it is ok to create 10 copies of the data (our dataset is small enough), if this makes your life easier, but you can also construct each training and testing set separately.\n", "\n", "There is no need to visualize any steps using graphs, but you can use the plotting structure above to make things look better for\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fold 0 accuracy: 100.0%\n", "Fold 1 accuracy: 100.0%\n", "Fold 2 accuracy: 100.0%\n", "Fold 3 accuracy: 90.0%\n", "Fold 4 accuracy: 90.0%\n", "Fold 5 accuracy: 80.0%\n", "Fold 6 accuracy: 90.0%\n", "Fold 7 accuracy: 100.0%\n", "Fold 8 accuracy: 100.0%\n", "Fold 9 accuracy: 100.0%\n", "Total accuracy: 95.0%\n", "True Positives: 47 | True Negatives: 48\n", "False Positives: 4 | False Negatives: 1\n" ] } ], "source": [ "# Create a list that represents the randomized indices of both lists\n", "randomized_indices = np.random.permutation(len(data))\n", "\n", "# Take that list of random indices and break it into 10 equal sized chunks\n", "equal_length_sets = np.array_split(randomized_indices, 10)\n", "\n", "# Create a variable for tracking total accuracy\n", "total_accuracy = 0\n", "\n", "# Create variables for tracking the confusion matrix: true positive, true negative, false positive, false negative\n", "tp = tn = fp = fn = 0\n", "\n", "# For each partition...\n", "for fold_value, test in enumerate(equal_length_sets):\n", " # Get your 10% of testing data\n", " test_set = data[test]\n", " test_labels = labels[test]\n", "\n", " # Get your 90% of training data. There is probably a better way to do this but I am panicking\n", " train_set = []\n", " train_labels = []\n", " for train in equal_length_sets:\n", " if not np.array_equal(train, test):\n", " train_set.append(data[train])\n", " train_labels.append(labels[train])\n", " train_set = [item for sublist in train_set for item in sublist]\n", " train_labels = [item for sublist in train_labels for item in sublist]\n", " \n", " # Convert your train_set and train_labels to numpy arrays\n", " train_set, train_labels = np.array(train_set), np.array(train_labels)\n", " \n", " # Create your model and get your predictions\n", " rate = 0.01\n", " model = trainMagicClassifier(train_set, train_labels, rate, 20)\n", " predictions = generatePredictions(model, test_set)\n", " \n", " # Calculate the accuracy and the confusion matrix\n", " # Once again: This is bad code, but I am panicking\n", " accuracy = 0\n", " for i, prediction in enumerate(predictions):\n", " if prediction == test_labels[i]:\n", " accuracy += 1\n", " if prediction == 1.0:\n", " tp += 1\n", " else:\n", " tn += 1\n", " else:\n", " if prediction == 1.0:\n", " fp += 1\n", " else:\n", " fn += 1\n", " \n", " # Get a percentage value for accuracy\n", " accuracy /= len(predictions)\n", " \n", " # Report the accuracy\n", " print(\"Fold {} accuracy: {}%\".format(fold_value, accuracy * 100))\n", " \n", " # Increment the total accuracy\n", " total_accuracy += accuracy\n", "\n", "# Print out the total accuracy and the confusion matrix \n", "print(\"Total accuracy: {}%\".format(total_accuracy * 10))\n", "print(\"True Positives: {} | True Negatives: {}\".format(tp, tn))\n", "print(\"False Positives: {} | False Negatives: {}\".format(fp, fn))\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Congratulations!** You are done.\n", "\n", "Download the notebook and submit it using the\n", "\n", " handin dekhtyar 466-test \n", " \n", " command." ] } ], "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }