Machine Learning

profileSiper
Assignment5.ipynb

{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "<center>\n", "<h1> Assignment 5: Multi-Classification</h1>\n", "<hr>\n", "\n", "<h3><mark>Due date: Mar 13th, 2020 (Friday)</mark></h3>\n", "<h3>Total Points: 100</h3>\n", "\n", "\n", "</center>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Please put your name, student ID, date and time here \n", "* Name:\n", "* Student ID:\n", "* Date:\n", "* Time:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* In this assignment, you will investigate the handwritten digits dataset.\n", "* Sample images:\n", "<img src=\"Mnist.png\">\n", "\n", "* Please apply the folowing eight methods to classify the handwritten digits dataset.\n", "* Split the dataset into training sets and test sets\n", "* Fit the training data sets to the following eight algorithms\n", "* Print the classification report on the test data sets\n", "\n", "<h4>Method 1: KNN</h4>\n", "<h4>Method 2: Linear SVM</h4>\n", "<h4>Method 3: Gaussian Kernel SVM</h4>\n", "<h4>Method 4: Naive Bayes</h4>\n", "<h4>Method 5: Decision Tree</h4> \n", "<h4>Method 6: Random Forest</h4> \n", "<h4>Method 7: Voting Classifier</h4> \n", "<h4>Method 8: Bagging</h4> " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'data': array([[ 0., 0., 5., ..., 0., 0., 0.],\n", " [ 0., 0., 0., ..., 10., 0., 0.],\n", " [ 0., 0., 0., ..., 16., 9., 0.],\n", " ...,\n", " [ 0., 0., 1., ..., 6., 0., 0.],\n", " [ 0., 0., 2., ..., 12., 0., 0.],\n", " [ 0., 0., 10., ..., 12., 1., 0.]]), 'target': array([0, 1, 2, ..., 8, 9, 8]), 'target_names': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), 'images': array([[[ 0., 0., 5., ..., 1., 0., 0.],\n", " [ 0., 0., 13., ..., 15., 5., 0.],\n", " [ 0., 3., 15., ..., 11., 8., 0.],\n", " ...,\n", " [ 0., 4., 11., ..., 12., 7., 0.],\n", " [ 0., 2., 14., ..., 12., 0., 0.],\n", " [ 0., 0., 6., ..., 0., 0., 0.]],\n", "\n", " [[ 0., 0., 0., ..., 5., 0., 0.],\n", " [ 0., 0., 0., ..., 9., 0., 0.],\n", " [ 0., 0., 3., ..., 6., 0., 0.],\n", " ...,\n", " [ 0., 0., 1., ..., 6., 0., 0.],\n", " [ 0., 0., 1., ..., 6., 0., 0.],\n", " [ 0., 0., 0., ..., 10., 0., 0.]],\n", "\n", " [[ 0., 0., 0., ..., 12., 0., 0.],\n", " [ 0., 0., 3., ..., 14., 0., 0.],\n", " [ 0., 0., 8., ..., 16., 0., 0.],\n", " ...,\n", " [ 0., 9., 16., ..., 0., 0., 0.],\n", " [ 0., 3., 13., ..., 11., 5., 0.],\n", " [ 0., 0., 0., ..., 16., 9., 0.]],\n", "\n", " ...,\n", "\n", " [[ 0., 0., 1., ..., 1., 0., 0.],\n", " [ 0., 0., 13., ..., 2., 1., 0.],\n", " [ 0., 0., 16., ..., 16., 5., 0.],\n", " ...,\n", " [ 0., 0., 16., ..., 15., 0., 0.],\n", " [ 0., 0., 15., ..., 16., 0., 0.],\n", " [ 0., 0., 2., ..., 6., 0., 0.]],\n", "\n", " [[ 0., 0., 2., ..., 0., 0., 0.],\n", " [ 0., 0., 14., ..., 15., 1., 0.],\n", " [ 0., 4., 16., ..., 16., 7., 0.],\n", " ...,\n", " [ 0., 0., 0., ..., 16., 2., 0.],\n", " [ 0., 0., 4., ..., 16., 2., 0.],\n", " [ 0., 0., 5., ..., 12., 0., 0.]],\n", "\n", " [[ 0., 0., 10., ..., 1., 0., 0.],\n", " [ 0., 2., 16., ..., 1., 0., 0.],\n", " [ 0., 0., 15., ..., 15., 0., 0.],\n", " ...,\n", " [ 0., 4., 16., ..., 16., 6., 0.],\n", " [ 0., 8., 16., ..., 16., 8., 0.],\n", " [ 0., 1., 8., ..., 12., 1., 0.]]]), 'DESCR': \".. _digits_dataset:\\n\\nOptical recognition of handwritten digits dataset\\n--------------------------------------------------\\n\\n**Data Set Characteristics:**\\n\\n :Number of Instances: 5620\\n :Number of Attributes: 64\\n :Attribute Information: 8x8 image of integer pixels in the range 0..16.\\n :Missing Attribute Values: None\\n :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr)\\n :Date: July; 1998\\n\\nThis is a copy of the test set of the UCI ML hand-written digits datasets\\nhttp://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits\\n\\nThe data set contains images of hand-written digits: 10 classes where\\neach class refers to a digit.\\n\\nPreprocessing programs made available by NIST were used to extract\\nnormalized bitmaps of handwritten digits from a preprinted form. From a\\ntotal of 43 people, 30 contributed to the training set and different 13\\nto the test set. 32x32 bitmaps are divided into nonoverlapping blocks of\\n4x4 and the number of on pixels are counted in each block. This generates\\nan input matrix of 8x8 where each element is an integer in the range\\n0..16. This reduces dimensionality and gives invariance to small\\ndistortions.\\n\\nFor info on NIST preprocessing routines, see M. D. Garris, J. L. Blue, G.\\nT. Candela, D. L. Dimmick, J. Geist, P. J. Grother, S. A. Janet, and C.\\nL. Wilson, NIST Form-Based Handprint Recognition System, NISTIR 5469,\\n1994.\\n\\n.. topic:: References\\n\\n - C. Kaynak (1995) Methods of Combining Multiple Classifiers and Their\\n Applications to Handwritten Digit Recognition, MSc Thesis, Institute of\\n Graduate Studies in Science and Engineering, Bogazici University.\\n - E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.\\n - Ken Tang and Ponnuthurai N. Suganthan and Xi Yao and A. Kai Qin.\\n Linear dimensionalityreduction using relevance weighted LDA. School of\\n Electrical and Electronic Engineering Nanyang Technological University.\\n 2005.\\n - Claudio Gentile. A New Approximate Maximal Margin Classification\\n Algorithm. NIPS. 2000.\"}\n" ] } ], "source": [ "# Importing the dataset\n", "from sklearn.datasets import load_digits\n", "digits = load_digits()\n", "print(digits)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 4 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "digits.images[0].shape\n", "list = [10,100,100,45]\n", "fig = plt.figure()\n", "for i,j in enumerate(list):\n", " plt.subplot(2,2,i+1)\n", " plt.imshow(digits.images[j],cmap='gray')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "X = digits.data\n", "y = digits.target" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Step 1. Split the dataset into training data and testing data (<mark>10 points</mark>)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 2. Algorithm Analysis (<mark>80 points</mark>)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 1. KNN" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 2. Linear SVM" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 3. Gaussian Kernal SVM" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 4. Naive Bayes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 5. Decision Tree" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Method 6. Random Forest" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Method 7. Voting Classifier" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Method 8. Bagging" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Step 3: Accuracy Results Table (<mark>8 points</mark>)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "<table>\n", " <thead>\n", " <tr>\n", " <th></th>\n", " <th>KNN</th>\n", " <th>L_SVM</th>\n", " <th>RBF_SVM</th>\n", " <th>NB</th>\n", " <th>DT</th>\n", " <th>RF</th>\n", " <th>Voting</th>\n", " <th>Bagging</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <td>Accuracy</td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " </tr>\n", " <tr>\n", " <td>Weighted Precision</td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " </tr>\n", " <tr>\n", " <td>Weighted Recall</td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " <td></td>\n", " </tr>\n", " </tbody>\n", "</table>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Step 4: Conclusion (<mark>2 Points</mark>)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "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.4" } }, "nbformat": 4, "nbformat_minor": 2 }