{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapter 12: Discriminant Analysis\n",
    "\n",
    "> (c) 2019 Galit Shmueli, Peter C. Bruce, Peter Gedeck \n",
    ">\n",
    "> Code included in\n",
    ">\n",
    "> _Data Mining for Business Analytics: Concepts, Techniques, and Applications in Python_ (First Edition) \n",
    "> Galit Shmueli, Peter C. Bruce, Peter Gedeck, and Nitin R. Patel. 2019.\n",
    "\n",
    "## Import required packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:17.991457Z",
     "iopub.status.busy": "2021-05-27T20:03:17.990974Z",
     "iopub.status.idle": "2021-05-27T20:03:18.851258Z",
     "shell.execute_reply": "2021-05-27T20:03:18.850775Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "no display found. Using non-interactive Agg backend\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n",
    "import matplotlib.pylab as plt\n",
    "\n",
    "import dmba\n",
    "from dmba import classificationSummary\n",
    "\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table 12.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:18.859061Z",
     "iopub.status.busy": "2021-05-27T20:03:18.856187Z",
     "iopub.status.idle": "2021-05-27T20:03:18.865921Z",
     "shell.execute_reply": "2021-05-27T20:03:18.865528Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coefficients [[0.1002303  0.78518471]]\n",
      "Intercept [-21.73876167]\n",
      "Decision function\n",
      " = 0.10*Income + 0.79*Lot_Size + -21.74\n",
      "\n",
      "Example Income=$60K Lot_Size=18.4Kft2\n",
      "  0.10*60 + 0.79*18.4 + -21.74 = -1.28\n",
      "  negative => nonowner\n"
     ]
    }
   ],
   "source": [
    "mower_df = dmba.load_data('RidingMowers.csv')\n",
    "\n",
    "da_reg = LinearDiscriminantAnalysis()\n",
    "da_reg.fit(mower_df.drop(columns=['Ownership']), mower_df['Ownership'])\n",
    "\n",
    "c_income = da_reg.coef_[0, 0]\n",
    "c_lotSize = da_reg.coef_[0, 1]\n",
    "intercept = da_reg.intercept_[0]\n",
    "print('Coefficients', da_reg.coef_)\n",
    "print('Intercept', da_reg.intercept_)\n",
    "\n",
    "print('Decision function')\n",
    "print(' = {:.2f}*Income + {:.2f}*Lot_Size + {:.2f}'.format(c_income, c_lotSize, intercept))\n",
    "\n",
    "print('\\nExample Income=$60K Lot_Size=18.4Kft2')\n",
    "print('  {:.2f}*60 + {:.2f}*18.4 + {:.2f} = {:.2f}'.format(c_income, c_lotSize, intercept,\n",
    "                                                          da_reg.decision_function([[60, 18.4]])[0]))\n",
    "print('  negative => nonowner')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:18.870725Z",
     "iopub.status.busy": "2021-05-27T20:03:18.870295Z",
     "iopub.status.idle": "2021-05-27T20:03:18.872921Z",
     "shell.execute_reply": "2021-05-27T20:03:18.873364Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-21.73876167])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mower_df\n",
    "da_reg.coef_\n",
    "da_reg.intercept_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Figure 12.1 and Figure 12.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:18.879720Z",
     "iopub.status.busy": "2021-05-27T20:03:18.879292Z",
     "iopub.status.idle": "2021-05-27T20:03:19.161530Z",
     "shell.execute_reply": "2021-05-27T20:03:19.161148Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 19904 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = mower_df[mower_df.Ownership=='Owner'].plot.scatter(x='Income', y='Lot_Size', c='blue', label='owner')\n",
    "mower_df[mower_df.Ownership!='Owner'].plot.scatter(x='Income', y='Lot_Size', c='red', label='nonowner', ax=ax)\n",
    "\n",
    "ax.plot(da_reg.means_[:,0], da_reg.means_[:,1], 'x', color='black', label='Class means', markersize=10)\n",
    "x_adhoc = np.array([48, 85])\n",
    "y_adhoc = np.array([24, 14])\n",
    "ax.plot(x_adhoc, y_adhoc, '-', color='C0', label='ad hoc line')\n",
    "ax.set_xlabel('Income ($000s)')\n",
    "ax.set_ylabel('Lot Size (000s sqft)')\n",
    "ax.set_xlim(20, 120)\n",
    "ax.set_ylim(13, 25)\n",
    "\n",
    "box = ax.get_position()\n",
    "ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])\n",
    "plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.177476Z",
     "iopub.status.busy": "2021-05-27T20:03:19.176977Z",
     "iopub.status.idle": "2021-05-27T20:03:19.435493Z",
     "shell.execute_reply": "2021-05-27T20:03:19.434897Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24224 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = mower_df[mower_df.Ownership=='Owner'].plot.scatter(x='Income', y='Lot_Size', c='blue', label='owner')\n",
    "mower_df[mower_df.Ownership!='Owner'].plot.scatter(x='Income', y='Lot_Size', c='red', label='nonowner', ax=ax)\n",
    "\n",
    "ax.plot(da_reg.means_[:,0], da_reg.means_[:,1], 'x', color='black', label='Class means', markersize=5)\n",
    "x_lda = np.array(ax.get_xlim())\n",
    "y_lda = (- intercept - c_income * x_lda) / c_lotSize\n",
    "ax.plot(x_lda, y_lda, '--', color='C1', label='DA line')\n",
    "ax.plot(x_adhoc, y_adhoc, '-', color='C0', label='ad hoc line')\n",
    "ax.set_xlabel('Income ($000s)')\n",
    "ax.set_ylabel('Lot Size (000s sqft)')\n",
    "ax.set_xlim(20, 120)\n",
    "ax.set_ylim(13, 25)\n",
    "\n",
    "box = ax.get_position()\n",
    "ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])\n",
    "plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table 12.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.456040Z",
     "iopub.status.busy": "2021-05-27T20:03:19.450793Z",
     "iopub.status.idle": "2021-05-27T20:03:19.459020Z",
     "shell.execute_reply": "2021-05-27T20:03:19.459415Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    Income  Lot_Size Ownership  Dec. Function Prediction  p(Owner)\n",
      "1     60.0      18.4     Owner      -1.277545   Nonowner  0.217968\n",
      "2     85.5      16.8     Owner       0.022032      Owner  0.505508\n",
      "3     64.8      21.6     Owner       1.716152      Owner  0.847632\n",
      "4     61.5      20.8     Owner       0.757244      Owner  0.680755\n",
      "5     87.0      23.6     Owner       5.511634      Owner  0.995977\n",
      "6    110.1      19.2     Owner       4.372141      Owner  0.987533\n",
      "7    108.0      17.6     Owner       2.905362      Owner  0.948111\n",
      "8     82.8      22.4     Owner       4.148445      Owner  0.984456\n",
      "9     69.0      20.0     Owner       0.880823      Owner  0.706993\n",
      "10    93.0      20.8     Owner       3.914499      Owner  0.980440\n",
      "11    51.0      22.0     Owner       0.647047      Owner  0.656345\n",
      "12    81.0      20.0     Owner       2.083587      Owner  0.889298\n",
      "13    75.0      19.6  Nonowner       1.168131      Owner  0.762807\n",
      "14    52.8      20.8  Nonowner      -0.114760   Nonowner  0.471342\n",
      "15    64.8      17.2  Nonowner      -1.738661   Nonowner  0.149483\n",
      "16    43.2      20.4  Nonowner      -1.391044   Nonowner  0.199241\n",
      "17    84.0      17.6  Nonowner       0.499835      Owner  0.622420\n",
      "18    49.2      17.6  Nonowner      -2.988180   Nonowner  0.047963\n",
      "19    59.4      16.0  Nonowner      -3.222126   Nonowner  0.038342\n",
      "20    66.0      18.4  Nonowner      -0.676163   Nonowner  0.337118\n",
      "21    47.4      16.4  Nonowner      -4.110816   Nonowner  0.016130\n",
      "22    33.0      18.8  Nonowner      -3.669689   Nonowner  0.024851\n",
      "23    51.0      14.0  Nonowner      -5.634430   Nonowner  0.003560\n",
      "24    63.0      14.8  Nonowner      -3.803519   Nonowner  0.021806\n"
     ]
    }
   ],
   "source": [
    "da_reg = LinearDiscriminantAnalysis()\n",
    "da_reg.fit(mower_df.drop(columns=['Ownership']), mower_df['Ownership'])\n",
    "\n",
    "result_df = mower_df.copy()\n",
    "result_df.index = result_df.index + 1\n",
    "result_df['Dec. Function'] = da_reg.decision_function(mower_df.drop(columns=['Ownership']))\n",
    "result_df['Prediction'] = da_reg.predict(mower_df.drop(columns=['Ownership']))\n",
    "result_df['p(Owner)'] = da_reg.predict_proba(mower_df.drop(columns=['Ownership']))[:, 1]\n",
    "\n",
    "print(result_df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table 12.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.464274Z",
     "iopub.status.busy": "2021-05-27T20:03:19.463780Z",
     "iopub.status.idle": "2021-05-27T20:03:19.487116Z",
     "shell.execute_reply": "2021-05-27T20:03:19.486754Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coefficients and intercept\n",
      "                    fatal  no-injury  non-fatal\n",
      "constant        -1.972659  -0.891172  -0.610471\n",
      "RushHour        -0.996411   0.033430  -0.015774\n",
      "WRK_ZONE        -0.457188   0.220012  -0.204480\n",
      "WKDY            -1.471777   0.165707  -0.135404\n",
      "INT_HWY          0.755344  -0.075816   0.060599\n",
      "LGTCON_day       0.009515  -0.031421   0.030124\n",
      "LEVEL            0.976626  -0.082717   0.063598\n",
      "SPD_LIM          0.048033   0.004381  -0.005014\n",
      "SUR_COND_dry    -5.999809  -0.164874   0.257895\n",
      "TRAF_two_way     0.752985  -0.012844  -0.000048\n",
      "WEATHER_adverse -6.596690   0.079166   0.032564\n",
      "\n",
      "Confusion Matrix (Accuracy 0.5283)\n",
      "\n",
      "          Prediction\n",
      "   Actual     fatal no-injury non-fatal\n",
      "    fatal         1         1         3\n",
      "no-injury         6       114       172\n",
      "non-fatal         6        95       202\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "non-fatal    303\n",
       "no-injury    292\n",
       "fatal          5\n",
       "Name: MAX_SEV, dtype: int64"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "accidents_df = dmba.load_data('accidents.csv')\n",
    "lda_reg = LinearDiscriminantAnalysis()\n",
    "lda_reg.fit(accidents_df.drop(columns=['MAX_SEV']), accidents_df['MAX_SEV'])\n",
    "\n",
    "print('Coefficients and intercept')\n",
    "fct = pd.DataFrame([lda_reg.intercept_], columns=lda_reg.classes_, index=['constant'])\n",
    "fct = fct.append(pd.DataFrame(lda_reg.coef_.transpose(), columns=lda_reg.classes_, \n",
    "                              index=list(accidents_df.columns)[:-1]))\n",
    "print(fct)\n",
    "print()\n",
    "classificationSummary(accidents_df['MAX_SEV'], \n",
    "                      lda_reg.predict(accidents_df.drop(columns=['MAX_SEV'])),\n",
    "                      class_names=lda_reg.classes_)\n",
    "accidents_df.MAX_SEV.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.490784Z",
     "iopub.status.busy": "2021-05-27T20:03:19.490377Z",
     "iopub.status.idle": "2021-05-27T20:03:19.494193Z",
     "shell.execute_reply": "2021-05-27T20:03:19.493707Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.9726587 , -0.89117217, -0.61047129])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lda_reg.intercept_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table 12.4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.503733Z",
     "iopub.status.busy": "2021-05-27T20:03:19.500508Z",
     "iopub.status.idle": "2021-05-27T20:03:19.513581Z",
     "shell.execute_reply": "2021-05-27T20:03:19.513224Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  Classification     Actual  Score fatal  Score no-injury  Score non-fatal  \\\n",
      "0      no-injury  no-injury        -5.94            -0.46            -0.96   \n",
      "1      no-injury  non-fatal        -1.05            -0.46            -1.04   \n",
      "2      no-injury  no-injury        -7.88            -0.63            -0.77   \n",
      "3      no-injury  no-injury        -8.38            -0.54            -0.84   \n",
      "4      no-injury  non-fatal        -9.84            -0.50            -0.85   \n",
      "\n",
      "   Propensity fatal  Propensity no-injury  Propensity non-fatal  \n",
      "0          0.00e+00                  0.62                  0.38  \n",
      "1          2.63e-01                  0.47                  0.27  \n",
      "2          0.00e+00                  0.54                  0.46  \n",
      "3          0.00e+00                  0.57                  0.43  \n",
      "4          0.00e+00                  0.59                  0.41  \n"
     ]
    }
   ],
   "source": [
    "result = pd.concat([\n",
    "    pd.DataFrame({'Classification': lda_reg.predict(accidents_df.drop(columns=['MAX_SEV'])),\n",
    "                  'Actual': accidents_df['MAX_SEV']}),\n",
    "    pd.DataFrame(lda_reg.decision_function(accidents_df.drop(columns=['MAX_SEV'])), \n",
    "                 columns=['Score {}'.format(cls) for cls in lda_reg.classes_]),\n",
    "    pd.DataFrame(lda_reg.predict_proba(accidents_df.drop(columns=['MAX_SEV'])), \n",
    "                 columns=['Propensity {}'.format(cls) for cls in lda_reg.classes_])\n",
    "], axis=1)\n",
    "\n",
    "pd.set_option('precision',2)\n",
    "pd.set_option('chop_threshold', .01)\n",
    "print(result.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 12.5 Prior probabilities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.521742Z",
     "iopub.status.busy": "2021-05-27T20:03:19.521314Z",
     "iopub.status.idle": "2021-05-27T20:03:19.525266Z",
     "shell.execute_reply": "2021-05-27T20:03:19.525604Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Decision function\n",
      " = 0.10*Income + 0.79*Lot_Size + -23.47\n",
      "\n",
      "Example Income=$75K Lot_Size=19.6Kft2\n",
      "  Owner (no-priors) => Nonowner (priors)\n",
      "\n",
      "Example Income=$84K Lot_Size=17.6Kft2\n",
      "  Owner (no-priors) => Nonowner (priors)\n"
     ]
    }
   ],
   "source": [
    "da_reg_prior = LinearDiscriminantAnalysis(priors=[0.85,0.15])\n",
    "da_reg_prior.fit(mower_df.drop(columns=['Ownership']), mower_df['Ownership'])\n",
    "\n",
    "c_income = da_reg_prior.coef_[0, 0]\n",
    "c_lotSize = da_reg_prior.coef_[0, 1]\n",
    "intercept = da_reg_prior.intercept_[0]\n",
    "\n",
    "print('Decision function')\n",
    "print(' = {:.2f}*Income + {:.2f}*Lot_Size + {:.2f}'.format(c_income, c_lotSize, intercept))\n",
    "\n",
    "\n",
    "data = [[75, 19.6]]\n",
    "print('\\nExample Income=$75K Lot_Size=19.6Kft2')\n",
    "print('  {} (no-priors) => {} (priors)'.format(da_reg.predict(data)[0], da_reg_prior.predict(data)[0]))\n",
    "\n",
    "data = [[84, 17.6]]\n",
    "print('\\nExample Income=$84K Lot_Size=17.6Kft2')\n",
    "print('  {} (no-priors) => {} (priors)'.format(da_reg.predict(data)[0], da_reg_prior.predict(data)[0]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.535796Z",
     "iopub.status.busy": "2021-05-27T20:03:19.535357Z",
     "iopub.status.idle": "2021-05-27T20:03:19.700862Z",
     "shell.execute_reply": "2021-05-27T20:03:19.700450Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26020 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = mower_df[mower_df.Ownership=='Owner'].plot.scatter(x='Income', y='Lot_Size', c='blue', label='owner')\n",
    "mower_df[mower_df.Ownership!='Owner'].plot.scatter(x='Income', y='Lot_Size', c='red', label='nonowner', ax=ax)\n",
    "\n",
    "ax.plot(da_reg.means_[:,0], da_reg.means_[:,1], 'x', color='black', label='Class means', markersize=5)\n",
    "x_lda_prior = np.array(ax.get_xlim())\n",
    "y_lda_prior = (- intercept - c_income * x_lda) / c_lotSize\n",
    "ax.plot(x_lda, y_lda, '--', label='DA line')\n",
    "ax.plot(x_lda_prior, y_lda_prior, '--', label='DA line (priors)')\n",
    "ax.set_xlabel('Income ($000s)')\n",
    "ax.set_ylabel('Lot Size (000s sqft)')\n",
    "ax.set_xlim(20, 120)\n",
    "ax.set_ylim(13, 25)\n",
    "\n",
    "box = ax.get_position()\n",
    "ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])\n",
    "plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Figure 12.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:19.708022Z",
     "iopub.status.busy": "2021-05-27T20:03:19.707589Z",
     "iopub.status.idle": "2021-05-27T20:03:21.040856Z",
     "shell.execute_reply": "2021-05-27T20:03:21.040441Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 61448 characters]\n",
      "text/plain": [
       "<Figure size 360x720 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib.lines import Line2D\n",
    "from matplotlib.ticker import ScalarFormatter, FormatStrFormatter\n",
    "\n",
    "universal_df = dmba.load_data('UniversalBank.csv')\n",
    "\n",
    "fig, axes = plt.subplots(nrows=2, ncols=1, figsize=[5, 10])\n",
    "plt.subplots_adjust(hspace=0.25)\n",
    "# plt.tight_layout()\n",
    "\n",
    "def createGraph(df, title, ax):\n",
    "    ccIdx = df[df['Personal Loan'] == 0].index\n",
    "    df.loc[ccIdx].plot(x='Income', y='CCAvg', kind='scatter',\n",
    "                              label='nonacceptor', color='C1',\n",
    "                              ylim = (0.05, 20), xlim = (5, 300),\n",
    "                              logx=True, logy=True, ax=ax)\n",
    "    df.drop(ccIdx).plot(x='Income', y='CCAvg', kind='scatter',\n",
    "                              label='acceptor', color='C0',\n",
    "                              ylim = (0.05, 20), xlim = (5, 300),\n",
    "                              logx=True, logy=True, ax=ax)\n",
    "    ax.set_xlabel('Annual Income ($000s)')\n",
    "    ax.set_ylabel('Monthly Credit Card Average Spending ($000s)')\n",
    "    ax.xaxis.set_major_formatter(ScalarFormatter())\n",
    "    ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))\n",
    "    ax.set_title(title)\n",
    "createGraph(universal_df.sample(200, random_state=10), 'Sample of 200 customers', axes[0])\n",
    "createGraph(universal_df, 'All 5000 customers', axes[1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:21.047750Z",
     "iopub.status.busy": "2021-05-27T20:03:21.047281Z",
     "iopub.status.idle": "2021-05-27T20:03:21.054774Z",
     "shell.execute_reply": "2021-05-27T20:03:21.054367Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Age</th>\n",
       "      <th>Experience</th>\n",
       "      <th>Income</th>\n",
       "      <th>ZIP Code</th>\n",
       "      <th>Family</th>\n",
       "      <th>CCAvg</th>\n",
       "      <th>Education</th>\n",
       "      <th>Mortgage</th>\n",
       "      <th>Personal Loan</th>\n",
       "      <th>Securities Account</th>\n",
       "      <th>CD Account</th>\n",
       "      <th>Online</th>\n",
       "      <th>CreditCard</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>25</td>\n",
       "      <td>1</td>\n",
       "      <td>49</td>\n",
       "      <td>91107</td>\n",
       "      <td>4</td>\n",
       "      <td>1.6</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>45</td>\n",
       "      <td>19</td>\n",
       "      <td>34</td>\n",
       "      <td>90089</td>\n",
       "      <td>3</td>\n",
       "      <td>1.5</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>39</td>\n",
       "      <td>15</td>\n",
       "      <td>11</td>\n",
       "      <td>94720</td>\n",
       "      <td>1</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>35</td>\n",
       "      <td>9</td>\n",
       "      <td>100</td>\n",
       "      <td>94112</td>\n",
       "      <td>1</td>\n",
       "      <td>2.7</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>35</td>\n",
       "      <td>8</td>\n",
       "      <td>45</td>\n",
       "      <td>91330</td>\n",
       "      <td>4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   ID  Age  Experience  Income  ZIP Code  Family  CCAvg  Education  Mortgage  \\\n",
       "0   1   25           1      49     91107       4    1.6          1         0   \n",
       "1   2   45          19      34     90089       3    1.5          1         0   \n",
       "2   3   39          15      11     94720       1    1.0          1         0   \n",
       "3   4   35           9     100     94112       1    2.7          2         0   \n",
       "4   5   35           8      45     91330       4    1.0          2         0   \n",
       "\n",
       "   Personal Loan  Securities Account  CD Account  Online  CreditCard  \n",
       "0              0                   1           0       0           0  \n",
       "1              0                   1           0       0           0  \n",
       "2              0                   0           0       0           0  \n",
       "3              0                   0           0       0           0  \n",
       "4              0                   0           0       0           1  "
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "universal_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-05-27T20:03:21.058153Z",
     "iopub.status.busy": "2021-05-27T20:03:21.057729Z",
     "iopub.status.idle": "2021-05-27T20:03:21.060777Z",
     "shell.execute_reply": "2021-05-27T20:03:21.060342Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5000, 14)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "universal_df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "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.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
