{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "_You are currently looking at **version 1.3** of this notebook. To download notebooks and datafiles, as well as get help on Jupyter notebooks in the Coursera platform, visit the [Jupyter Notebook FAQ](https://www.coursera.org/learn/python-machine-learning/resources/bANLa) course resource._\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Assignment 1 - Introduction to Machine Learning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For this assignment, you will be using the Breast Cancer Wisconsin (Diagnostic) Database to create a classifier that can help diagnose patients. First, read through the description of the dataset (below)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.datasets import load_breast_cancer\n",
    "\n",
    "cancer = load_breast_cancer()\n",
    "\n",
    "#print(cancer.DESCR) # Print the data set description"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The object returned by `load_breast_cancer()` is a scikit-learn Bunch object, which is similar to a dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['feature_names', 'target_names', 'DESCR', 'data', 'target'])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cancer.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 0 (Example)\n",
    "\n",
    "How many features does the breast cancer dataset have?\n",
    "\n",
    "*This function should return an integer.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "30"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# You should write your whole answer within the function provided. The autograder will call\n",
    "# this function and compare the return value against the correct solution value\n",
    "def answer_zero():\n",
    "    # This function returns the number of features of the breast cancer dataset, which is an integer. \n",
    "    # The assignment question description will tell you the general format the autograder is expecting\n",
    "    return len(cancer['feature_names'])\n",
    "\n",
    "# You can examine what your function returns by calling it in the cell. If you have questions\n",
    "# about the assignment formats, check out the discussion forums for any FAQs\n",
    "answer_zero() "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 1\n",
    "\n",
    "Scikit-learn works with lists, numpy arrays, scipy-sparse matrices, and pandas DataFrames, so converting the dataset to a DataFrame is not necessary for training this model. Using a DataFrame does however help make many things easier such as munging data, so let's practice creating a classifier with a pandas DataFrame. \n",
    "\n",
    "\n",
    "\n",
    "Convert the sklearn.dataset `cancer` to a DataFrame. \n",
    "\n",
    "*This function should return a `(569, 31)` DataFrame with * \n",
    "\n",
    "*columns = *\n",
    "\n",
    "    ['mean radius', 'mean texture', 'mean perimeter', 'mean area',\n",
    "    'mean smoothness', 'mean compactness', 'mean concavity',\n",
    "    'mean concave points', 'mean symmetry', 'mean fractal dimension',\n",
    "    'radius error', 'texture error', 'perimeter error', 'area error',\n",
    "    'smoothness error', 'compactness error', 'concavity error',\n",
    "    'concave points error', 'symmetry error', 'fractal dimension error',\n",
    "    'worst radius', 'worst texture', 'worst perimeter', 'worst area',\n",
    "    'worst smoothness', 'worst compactness', 'worst concavity',\n",
    "    'worst concave points', 'worst symmetry', 'worst fractal dimension',\n",
    "    'target']\n",
    "\n",
    "*and index = *\n",
    "\n",
    "    RangeIndex(start=0, stop=569, step=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_one():\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer\n",
    "\n",
    "\n",
    "answer_one()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 2\n",
    "What is the class distribution? (i.e. how many instances of `malignant` (encoded 0) and how many `benign` (encoded 1)?)\n",
    "\n",
    "*This function should return a Series named `target` of length 2 with integer values and index =* `['malignant', 'benign']`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_two():\n",
    "    cancerdf = answer_one()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer\n",
    "\n",
    "\n",
    "answer_two()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 3\n",
    "Split the DataFrame into `X` (the data) and `y` (the labels).\n",
    "\n",
    "*This function should return a tuple of length 2:* `(X, y)`*, where* \n",
    "* `X`*, a pandas DataFrame, has shape* `(569, 30)`\n",
    "* `y`*, a pandas Series, has shape* `(569,)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_three():\n",
    "    cancerdf = answer_one()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return X, y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 4\n",
    "Using `train_test_split`, split `X` and `y` into training and test sets `(X_train, X_test, y_train, and y_test)`.\n",
    "\n",
    "**Set the random number generator state to 0 using `random_state=0` to make sure your results match the autograder!**\n",
    "\n",
    "*This function should return a tuple of length 4:* `(X_train, X_test, y_train, y_test)`*, where* \n",
    "* `X_train` *has shape* `(426, 30)`\n",
    "* `X_test` *has shape* `(143, 30)`\n",
    "* `y_train` *has shape* `(426,)`\n",
    "* `y_test` *has shape* `(143,)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "def answer_four():\n",
    "    X, y = answer_three()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return X_train, X_test, y_train, y_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 5\n",
    "Using KNeighborsClassifier, fit a k-nearest neighbors (knn) classifier with `X_train`, `y_train` and using one nearest neighbor (`n_neighbors = 1`).\n",
    "\n",
    "*This function should return a * `sklearn.neighbors.classification.KNeighborsClassifier`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "def answer_five():\n",
    "    X_train, X_test, y_train, y_test = answer_four()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 6\n",
    "Using your knn classifier, predict the class label using the mean value for each feature.\n",
    "\n",
    "Hint: You can use `cancerdf.mean()[:-1].values.reshape(1, -1)` which gets the mean value for each feature, ignores the target column, and reshapes the data from 1 dimension to 2 (necessary for the precict method of KNeighborsClassifier).\n",
    "\n",
    "*This function should return a numpy array either `array([ 0.])` or `array([ 1.])`*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_six():\n",
    "    cancerdf = answer_one()\n",
    "    means = cancerdf.mean()[:-1].values.reshape(1, -1)\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 7\n",
    "Using your knn classifier, predict the class labels for the test set `X_test`.\n",
    "\n",
    "*This function should return a numpy array with shape `(143,)` and values either `0.0` or `1.0`.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_seven():\n",
    "    X_train, X_test, y_train, y_test = answer_four()\n",
    "    knn = answer_five()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 8\n",
    "Find the score (mean accuracy) of your knn classifier using `X_test` and `y_test`.\n",
    "\n",
    "*This function should return a float between 0 and 1*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def answer_eight():\n",
    "    X_train, X_test, y_train, y_test = answer_four()\n",
    "    knn = answer_five()\n",
    "    \n",
    "    # Your code here\n",
    "    \n",
    "    return # Return your answer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Optional plot\n",
    "\n",
    "Try using the plotting function below to visualize the differet predicition scores between training and test sets, as well as malignant and benign cells."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def accuracy_plot():\n",
    "    import matplotlib.pyplot as plt\n",
    "\n",
    "    %matplotlib notebook\n",
    "\n",
    "    X_train, X_test, y_train, y_test = answer_four()\n",
    "\n",
    "    # Find the training and testing accuracies by target value (i.e. malignant, benign)\n",
    "    mal_train_X = X_train[y_train==0]\n",
    "    mal_train_y = y_train[y_train==0]\n",
    "    ben_train_X = X_train[y_train==1]\n",
    "    ben_train_y = y_train[y_train==1]\n",
    "\n",
    "    mal_test_X = X_test[y_test==0]\n",
    "    mal_test_y = y_test[y_test==0]\n",
    "    ben_test_X = X_test[y_test==1]\n",
    "    ben_test_y = y_test[y_test==1]\n",
    "\n",
    "    knn = answer_five()\n",
    "\n",
    "    scores = [knn.score(mal_train_X, mal_train_y), knn.score(ben_train_X, ben_train_y), \n",
    "              knn.score(mal_test_X, mal_test_y), knn.score(ben_test_X, ben_test_y)]\n",
    "\n",
    "\n",
    "    plt.figure()\n",
    "\n",
    "    # Plot the scores as a bar chart\n",
    "    bars = plt.bar(np.arange(4), scores, color=['#4c72b0','#4c72b0','#55a868','#55a868'])\n",
    "\n",
    "    # directly label the score onto the bars\n",
    "    for bar in bars:\n",
    "        height = bar.get_height()\n",
    "        plt.gca().text(bar.get_x() + bar.get_width()/2, height*.90, '{0:.{1}f}'.format(height, 2), \n",
    "                     ha='center', color='w', fontsize=11)\n",
    "\n",
    "    # remove all the ticks (both axes), and tick labels on the Y axis\n",
    "    plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')\n",
    "\n",
    "    # remove the frame of the chart\n",
    "    for spine in plt.gca().spines.values():\n",
    "        spine.set_visible(False)\n",
    "\n",
    "    plt.xticks([0,1,2,3], ['Malignant\\nTraining', 'Benign\\nTraining', 'Malignant\\nTest', 'Benign\\nTest'], alpha=0.8);\n",
    "    plt.title('Training and Test Accuracies for Malignant and Benign Cells', alpha=0.8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Uncomment the plotting function to see the visualization.\n",
    "\n",
    "**Comment out** the plotting function when submitting your notebook for grading. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#accuracy_plot() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "coursera": {
   "course_slug": "python-machine-learning",
   "graded_item_id": "f9SY5",
   "launcher_item_id": "oxndk",
   "part_id": "mh1Vo"
  },
  "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
