{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Changing K - Solution\n",
    "\n",
    "In this notebook, you will get some practice with different values of **k**, and how it changes the clusters that are observed in the data.  As well as how to determine what the best value for **k** might be for a dataset.\n",
    "\n",
    "To get started, let's read in our necessary libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "from sklearn.cluster import KMeans\n",
    "from sklearn.datasets import make_blobs\n",
    "import helpers2 as h\n",
    "import tests as t\n",
    "from IPython import display\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "# Make the images larger\n",
    "plt.rcParams['figure.figsize'] = (16, 9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`1.` To get started, there is a function called **simulate_data** within the **helpers2** module.  Read the documentation on the function by running the cell below.  Then use the function to simulate a dataset with 200 data points (rows), 5 features (columns), and 4 centers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "h.simulate_data?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = h.simulate_data(200, 5, 4)\n",
    "\n",
    "# This will check that your dataset appears to match ours before moving forward\n",
    "t.test_question_1(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`2.` Because of how you set up the data, what should the value of **k** be?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "k_value = 4\n",
    "\n",
    "# Check your solution against ours.\n",
    "t.test_question_2(k_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`3.` Let's try a few different values for **k** and fit them to our data using **KMeans**.\n",
    "\n",
    "To use KMeans, you need to follow three steps:\n",
    "\n",
    "**I.** Instantiate your model.\n",
    "\n",
    "**II.** Fit your model to the data.\n",
    "\n",
    "**III.** Predict the labels for the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Try instantiating a model with 4 centers\n",
    "kmeans_4 = KMeans(n_clusters=4)\n",
    "\n",
    "# Then fit the model to your data using the fit method\n",
    "model_4 = kmeans_4.fit(data)\n",
    "\n",
    "# Finally predict the labels on the same data to show the category that point belongs to\n",
    "labels_4 = model_4.predict(data)\n",
    "\n",
    "# If you did all of that correctly, this should provide a plot of your data colored by center\n",
    "h.plot_data(data, labels_4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`4.` Now try again, but this time fit kmeans using 2 clusters instead of 4 to your data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Try instantiating a model with 2 centers\n",
    "kmeans_2 = KMeans(n_clusters=2)\n",
    "\n",
    "# Then fit the model to your data using the fit method\n",
    "model_2 = kmeans_2.fit(data)\n",
    "\n",
    "# Finally predict the labels on the same data to show the category that point belongs to\n",
    "labels_2 = model_2.predict(data)\n",
    "\n",
    "# If you did all of that correctly, this should provide a plot of your data colored by center\n",
    "h.plot_data(data, labels_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`5.` Now try one more time, but with the number of clusters in kmeans to 7."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Try instantiating a model with 7 centers\n",
    "kmeans_7 = KMeans(n_clusters=7)\n",
    "\n",
    "# Then fit the model to your data using the fit method\n",
    "model_7 = kmeans_7.fit(data)\n",
    "\n",
    "# Finally predict the labels on the same data to show the category that point belongs to\n",
    "labels_7 = model_7.predict(data)\n",
    "\n",
    "# If you did all of that correctly, this should provide a plot of your data colored by center\n",
    "h.plot_data(data, labels_7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Visually, we get some indication of how well our model is doing, but it isn't totally apparent. Each time additional centers are considered, the distances between the points and the center will decrease.  However, at some point, that decrease is not substantial enough to suggest the need for an additional cluster.  \n",
    "\n",
    "Using a scree plot is a common method for understanding if an additional cluster center is needed.  The elbow method used by looking at a scree plot is still pretty subjective, but let's take a look to see how many cluster centers might be indicated.\n",
    "_________\n",
    "\n",
    "`6.` Once you have **fit** a kmeans model to some data in sklearn, there is a **score** method, which takes the data.  This score is an indication of how far the points are from the centroids.  By fitting models for centroids from 1-10, and keeping track of the score and the number of centroids, you should be able to build a scree plot.  \n",
    "\n",
    "This plot should have the number of centroids on the x-axis, and the absolute value of the score result on the y-axis.  You can see the plot I retrieved by running the solution code.  Try creating your own scree plot, as you will need it for the final questions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A place for your work - create a scree plot - you will need to\n",
    "# Fit a kmeans model with changing k from 1-10\n",
    "# Obtain the score for each model (take the absolute value)\n",
    "# Plot the score against k\n",
    "\n",
    "def get_kmeans_score(data, center):\n",
    "    '''\n",
    "    returns the kmeans score regarding SSE for points to centers\n",
    "    INPUT:\n",
    "        data - the dataset you want to fit kmeans to\n",
    "        center - the number of centers you want (the k value)\n",
    "    OUTPUT:\n",
    "        score - the SSE score for the kmeans model fit to the data\n",
    "    '''\n",
    "    #instantiate kmeans\n",
    "    kmeans = KMeans(n_clusters=center)\n",
    "\n",
    "    # Then fit the model to your data using the fit method\n",
    "    model = kmeans.fit(data)\n",
    "    \n",
    "    # Obtain a score related to the model fit\n",
    "    score = np.abs(model.score(data))\n",
    "    \n",
    "    return score\n",
    "\n",
    "scores = []\n",
    "centers = list(range(1,11))\n",
    "\n",
    "for center in centers:\n",
    "    scores.append(get_kmeans_score(data, center))\n",
    "    \n",
    "plt.plot(centers, scores, linestyle='--', marker='o', color='b');\n",
    "plt.xlabel('K');\n",
    "plt.ylabel('SSE');\n",
    "plt.title('SSE vs. K');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run our solution\n",
    "centers, scores = h.fit_mods()\n",
    "\n",
    "#Your plot should look similar to the below\n",
    "plt.plot(centers, scores, linestyle='--', marker='o', color='b');\n",
    "plt.xlabel('K');\n",
    "plt.ylabel('SSE');\n",
    "plt.title('SSE vs. K');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`7.` Using the scree plot, how many clusters would you suggest as being in the data?  What is K?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "value_for_k = 4\n",
    "\n",
    "# Test your solution against ours\n",
    "display.HTML(t.test_question_7(value_for_k))"
   ]
  },
  {
   "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.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
