From 99944b76ce156f47250c908d66b78677a6e5412a Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Wed, 4 Dec 2019 01:39:16 -0500 Subject: [PATCH 01/14] hyperparameter tuning tutorial --- .../Hyperparameter_Tuning_RF_Final.ipynb | 856 ++++++++++++++++++ .../varying_depths_plot.png | Bin 0 -> 92171 bytes .../varying_features_plot.png | Bin 0 -> 166480 bytes 3 files changed, 856 insertions(+) create mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb create mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/varying_depths_plot.png create mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/varying_features_plot.png diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb new file mode 100644 index 0000000000000..0dfa3a44ed754 --- /dev/null +++ b/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb @@ -0,0 +1,856 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameter Tuning Tutorial \n", + "\n", + "
\n", + " Objective: \n", + "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", + "
\n", + "\n", + " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", + "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", + "1. Random sampling of training data points when building trees\n", + "2. Random subsets of features considered when splitting nodes\n", + "\n", + "**The Dataset**\n", + "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", + "\n", + "
\n", + "\n", + "# Hyperparameter Tuning Methods\n", + "\n", + "
\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import GridSearchCV\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. GridSearchCV\n", + "\n", + "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", + "\n", + "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import GridSearchCV\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. RandomizedSearchCV\n", + "\n", + "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n", + "\n", + "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations. Of the 100 possible combinations, this sample code below in the tutorial selects 50." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Results \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Models |Performance | Best Params | Computation Time |\n", + "|---------------|--------------|---------------------------------|----------------------------|\n", + "|Base Model | 0.89 ± 0.02 | | | \n", + "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", + "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111|CPU total time: 2h 6min 6s | \n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Code \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Code is structured in the following order.\n", + "
    \n", + "
  1. Loading and Preprocessing Data
  2. \n", + "
  3. Building Base Random Forest Model
  4. \n", + "
  5. Tuning the number of features
  6. \n", + "
  7. Tuning the depths of the trees
  8. \n", + "
  9. Grid Search Tuning
  10. \n", + "
  11. Random Search Tuning
  12. \n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import fetch_openml\n", + "# Load data from https://www.openml.org/d/554\n", + "from PIL import Image, ImageDraw\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section One: Loading and Preprocessing Data\n", + "
\n", + "\n", + "
\n", + " There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(70000, 784)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the dataset\n", + "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", + "\n", + "# Check dimensions of the data\n", + "images.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "label: 9\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Pick the fifth image from the dataset (it's a 9)\n", + "i = 4\n", + "image, label = images[i], labels[i]\n", + "\n", + "# Print the image\n", + "output = Image.new(\"L\", (28, 28))\n", + "output.putdata(image)\n", + "print('label:',label)\n", + "plt.imshow(np.asarray(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train samples: 10000\n", + "Test samples: 1000\n" + ] + } + ], + "source": [ + "# Splitting the data into training and testing samples\n", + "from sklearn.model_selection import train_test_split\n", + "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", + " test_size = 1000, random_state = 42)\n", + "print('Train samples:', images_train.shape[0])\n", + "print('Test samples:', images_test.shape[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Assume a Gaussian distribution for the MNIST dataset and standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Feature Scaling\n", + "from sklearn.preprocessing import StandardScaler\n", + "scaler = StandardScaler()\n", + "images_train = scaler.fit_transform(images_train)\n", + "images_test = scaler.transform(images_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Two: Create and evaluate base Random Forest model with 500 estimators.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.954\n", + "[0.91133005 0.89108911 0.90049751 0.89393939 0.88265306]\n", + "Cross-Validation (CV=5) Accuracy: 0.90 (+/- 0.02)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Three: Tuning number of features.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "5\n", + "6\n", + "9\n", + "12\n", + "16\n", + "21\n", + "27\n", + "36\n", + "48\n", + "64\n", + "84\n", + "111\n", + "147\n", + "194\n", + "256\n", + "337\n", + "445\n", + "588\n", + "776\n", + "CPU times: user 2h 10min 47s, sys: 16.3 s, total: 2h 11min 3s\n", + "Wall time: 2h 18min 44s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Variable to store the accuracies of each random forest classifier with varying number of features\n", + "accuracies = []\n", + "# Number of features to perform a hyperparameter sweep\n", + "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each feature value\n", + "num_trials = 10\n", + "\n", + "feature_dataObj = pd.DataFrame()\n", + "feature_list = []\n", + "accuracy_scores = []\n", + "\n", + "for feature in features:\n", + " print(feature)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " feature_list.append(feature)\n", + " \n", + "feature_dataObj['Feature List'] = feature_list\n", + "feature_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Feature List Accuracy\n", + "0 4 0.845\n", + "1 4 0.845\n", + "2 4 0.845\n", + "3 4 0.837\n", + "4 4 0.846\n", + ".. ... ...\n", + "195 776 0.786\n", + "196 776 0.791\n", + "197 776 0.794\n", + "198 776 0.798\n", + "199 776 0.795\n", + "\n", + "[200 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import seaborn as sns\n", + "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", + "# plt.title('Varying Max_Features for MNIST Data')\n", + "plt.xlabel('Number of Features',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(feature_dataObj)\n", + "# save the figure to the current working directory\n", + "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Four: Tuning maximum depth of trees.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "6\n", + "9\n", + "13\n", + "21\n", + "32\n", + "48\n", + "73\n", + "111\n", + "168\n", + "CPU times: user 25min 47s, sys: 10 s, total: 25min 57s\n", + "Wall time: 28min 4s\n" + ] + } + ], + "source": [ + "%%time\n", + "# Variable to store the accuracies of each random forest classifier with varying number of features\n", + "accuracies = []\n", + "# Number of depths to perform a hyperparameter sweep\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each depth value\n", + "num_trials = 10\n", + "\n", + "depth_dataObj = pd.DataFrame()\n", + "depth_list = []\n", + "accuracy_scores = []\n", + "\n", + "for depth in depths:\n", + " print(depth)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " depth_list.append(depth)\n", + " \n", + "depth_dataObj['Depth List'] = depth_list\n", + "depth_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Depth List Accuracy\n", + "0 4 0.824\n", + "1 4 0.806\n", + "2 4 0.810\n", + "3 4 0.812\n", + "4 4 0.816\n", + ".. ... ...\n", + "95 168 0.956\n", + "96 168 0.958\n", + "97 168 0.957\n", + "98 168 0.955\n", + "99 168 0.958\n", + "\n", + "[100 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEKCAYAAADXdbjqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3de5wdVZnv/8939yXpdK4kASEhJAheMooDtAgiOOJlgKOi6M8BFWTGITiCM16YGTiOwOB4vKB49IhCUOTiBR2POBlFQQGVcdBDwiUQMBBBIeGWhABJ6E5f9vP7o6q6q3d2d1ene/fuTn/fr1fTtVfVrnpS7K5nr7Wq1lJEYGZmNhKlegdgZmYTn5OJmZmNmJOJmZmNmJOJmZmNmJOJmZmNWGO9A6iVefPmxeLFi+sdhpnZhLJq1apNETF/uO/bbZPJ4sWLWblyZb3DMDObUCT9aVfe52YuMzMbMScTMzMbMScTMzMbMScTMzMbsTFNJpKOlbRW0jpJ51RZv5+kmyStlvRLSQtz6xZJulHS/ZLuk7R4LGM3M7OBjVkykdQAXAIcBywFTpa0tGKzzwNXR8RBwIXAp3PrrgYuioiXAocBT9U+ajMzK2IsayaHAesi4qGI6ASuBU6o2GYpcHO6fEu2Pk06jRHxc4CI2BYRz49N2GZWLgcbt+5gw5bn2bh1B+WyRxu3/sYymSwAHs29Xp+W5d0NnJguvx2YIWku8CLgGUk/lHSnpIvSmk4/kpZJWilp5caNG2vwT7DdnS+aOyuXg7VPbuXtX/0NR372Ft7+1d+w9smtPjfWz3h7aPFs4CuSTgN+DWwAekjiPAo4GHgE+B5wGvCN/JsjYjmwHKCtrW3CfdLL5WDz9k46u3tobmxgbmszpZLG3T7rdcyIIAIiW4b0dVLet11fWeW2yQbV15cEjz/bwRnXrGL9lnYWzmnhslMOZa+ZU+gp94+hf1zJ/rL15YByBD3lvtcRQU9Ev9cDbwflKPfbLgjKEZQrts32ERW/ywHl7N8Y0FOOdH3+vdm+K/ZZ7ttXELxh6V6c9Z07Wb+lHYD1W9o5/eqVfPU9h3DrgxtpKInGUin5aRBNJSVlDX2/G0slmrL16evGhhKNpey1aGos0SDR0JB8x1Xvf0Dpgnpfp7/Tgr7X/bfv/VXlfQO9RxUf1YHWDxaDKncyRurx954Zy2SyAdg393phWtYrIh4jrZlImg68IyKekbQeuCsiHkrX/Qg4nIpkMpFl3/5Ov3pl74Xs0vceyqyWRrp60qtXJP8JRN/lK7kAgIh0P2WSC0Jzo9jRFfzdt/sujl97zyE0NYqOrnJ6YVTvxbRcTi4oKCkvZxfhcvTbJsgubn0XHdLlGVMbmdnSzJnfuaP3mF9598E8/kwHT23dQU856O4p0xNBdzno6Ul+l8tBd7mclJWTC2+ybaQX3KQsizG7EPaUy70Xv+yCWU4vntnFu6dyfTm7YGfLyfn6X29/GeetWNPvonnGNas4/y1L+fC1dyX//ui7QGfnIJ/kdkdHHTi/95xk1m9pp72zh4tueGDUj9cgUSpBQ0lJcimJUilJOMk67bSuIV1fUrYufX/up3ddbj+NA+yrod+29JXn9tOYba/+6xob+pdlx8jKS6UkWZaUJcwkTYk0yeWSl9IVybq+hJYliKxpSSWY0liivbPMB77V9/d++altvHivGWOSUMYymdwOHChpCUkSOQl4d34DSfOApyOiDJwLXJF772xJ8yNiI3AMsNuMldLe2d37bS9/IfvAt1bxiTcv5YxrVhXajwSl9JNXElzy7kO48Mf39dvn3337Dj7x5qV84JpVNbn4XXbKoZx73R39jnnWd+7kE29eyvkr1oxo3yVBSX1/wKUSO/0h9//NTuuaVaLU+5p+F5Y9pk+petHca+ZUXveSPSllf/RK9p3/nf2xl9KLgSRKZOui9yKRXSB6t6PvApL//yeSbYB++yO3v+zY0BdDdsx+F6CKuHv3mV2Y0ipAb5ylvuOXBLOnNbNwTku/c7NwTguzWpr4zIkv70vu5SzxpzWrMrmEnkvqafLuyW3TU859aaj46c6+XPRE75eQ7MtHfptyOegsl3u37U732V11n+X0mCP6SO6SnZJVqX/iKVWuG/A1uYRYYtnR+3P2v9+9Uw3yug8eyfwZU2r+7xqzZBIR3ZLOAm4AGoArImKNpAuBlRGxAvgL4NOSgqSZ68z0vT2SzgZuUvLXswq4fKxir4Vn2zv5+Zon+em9T/DbhzdzxfteWfVCtnBOC+8/cgnltG2l95sw/Zsmsmaccu5b8t6zplbd5z6zW3jXK/ftvfCUSn0XvlLuQldS/qKZlfW9zl9Qs/X77TGt6jEXz53GZ058ee+FO3tPQ0mIJDH0HbMvWfS/OKtf81Qm+/eTa7LpbXMgu0xG7nV/QXLsGVMaq140W5sbeVfbvmRTXFdef1StTMn/j+yCDv0v6tD/m2n2DTP7BimSi3rfdlUSC/Re+JNz2Nfckh2z1HusfOLon1jy57j33OSO2VBKviRUNv/Nn9nMMS/Zs1+NMF8D7G1eS2vKPeVIanPlXPKhfyLKLu7Z+esLJ3eWpd7/F6Xcdjvlheif6Puf9+TkJ5+dXEy5mmxWC87/+/IJrPcnkhp0b406l/SSbcq5BLjrybK7p0xHVwyYLEtS1b+9zu6eyjNTE2PaZxIR1wPXV5Sdl1v+AfCDAd77c+CgmgY4CgZrs3zquQ5+eu/j/GzNk9zxpy3s6C7T2tzAYUv2oHWAC9mUxgaOftG83gtiduFjkD+g7OIwbYB9Tmtu4C0H7dO/32GnCzADXCWrHTQtFDQ2lKoes7GUlPf7Vk/ft/KS+mpU2YWxRHKxLKGdvlVnSadfDYG+BJSFldUEemsA9P9WjuhdX0IsP+VQluUumstPaWPB7KksmNMyaNv5eGo3r4XZLc1c98Ejx6QtvrcpNWtazfVT5b8s5ZtY+zU5puvol9x2TnTlSGpHkdaOehNiuXqiy3+Jyf8ZlHLJLRNkST79gsPOfzrKPknK1ULp+1vIf1bzXw4qvyhkfw8zW6r/vTc37nSvUk2o8iTsLtra2mKsRw0eqN/j/sef49u/+xP3bHiOnnIwe1oTR+w/l1cu3oPF86ZRkpjV0khTQ0P/9s5T2th/fmv6DWrnDlai79tU/o+ruyfpvC0Jtjzf1W+fl773UGa3NNET0XsxzpqO8h/c/MW398NdpbzvW3fft8c/bNze7xyMZbvtSNWzA9PGv4FaA8gt51sNqiW6yC1ntZGsb68nyjslujL09u1Frqmwrz8wec/0qY00NZT44LfvGNHfnqRVEdE23HPjZDKKNm7dwdu/+pudvhl84s1LOf8/7uWIF87jkEWzWTCnhZJES1MDL5g5lTnTm5nenFQSfTeXme2KSJu/nn6+k66e8i7/7e1qMhlvtwZPaJ3dPVXbLJfMbeXTJ74cScyZ1sReM6cyq6WZluadq5+j3VFWKmlMOt/qfUyzyU4SjY1iz5lT63J8J5NR1NzYULXNcmpziVfsO4cZaTXUzGx34yvbKJrb2syl7z2UhXNaAHrbLBfOnsYerc1OJGa223LNZBSVSuL+x5/jE29eyv7zWpk9rdn9BWY2Kfir8ij7xn89zGd++numNjUwf8YUJxIzmxScTEbRw5u28/sntnLofnPYo7W53uGYmY0ZJ5NR9J93PwbAaw+cx7Qqd2qZme2unExG0Y9XP8b+81p5xb6zd6unn83MhuJkMkr+sHEbDzy5jUMXz2GOm7jMbJJxMhkl/3lX1sQ1n+lTfJOcmU0uTiaj5MerH2f/ea28bMEsN3GZ2aTjZDIK1j21lXUbt9G2eA57THcTl5lNPk4mo+A/7noMAUcfOJ8ZbuIys0moUDKR9DZJvtd1AD9e/Tj7z2/lpXvPdBOXmU1KRWsm3wY2SPqspBfVMqCJ5oEnt/Lwpu28cskezPNIuWY2SRVNJi8AzgdeC9wv6b8k/bWk1tqFNjH86M4NCHjNC+e5icvMJq1CySQitkbEZRFxOMnUub8DPg08LulySYcX2Y+kYyWtlbRO0jlV1u8n6SZJqyX9UtLCivUzJa2X9JUix6u1iOAnqx/ngD2n85K9J8ZMgmZmtTDsDviIWAN8EVgONAN/Bdwq6XeSBpyjPe1zuQQ4DlgKnCxpacVmnweujoiDgAtJElbeJ4FfDzfmWln7xFb+9PTzHLZkD+ZPr8+ENGZm40HhZCKpSdK7JP0MeBg4BvgAsBewH3A/8L1BdnEYsC4iHoqITuBa4ISKbZYCN6fLt+TXSzo0PdaNRWOutevu3IAEr37hXGZMdROXmU1eha6Akv4PcDIQwDXARyPivtwm7Wmz1WOD7GYB8Gju9XrgVRXb3A2cCHwJeDswQ9JcYAvwBeC9wBsGiXMZsAxg0aJFQ//DdlEyx/kO3rh0L159wDz2mzvNTVxmNqkV/Tq9FDgL+GFaq6hmE/C6EcZzNvAVSaeRNGdtAHqADwLXR8T6wW69jYjlJM1vtLW1xQhjqapcDtY+uZXTr17J+i3tLJzTwvJTDqVcDicUM5u0CiWTiHh9gW26gV8NsskGYN/c64VpWX4fj5HUTJA0HXhHRDwj6QjgKEkfBKYDzZK2RcROnfi1tnl7Z28iAVi/pZ1l16ziug8eyXzfGmxmk1TRZq5PAY9GxKUV5R8AFkTEJwrs5nbgQElLSJLIScC7K/Y3D3g6IsrAucAVABHxntw2pwFt9UgkAJ3dPb2JJLN+Szud3T31CMfMbFwo2gF/CnBnlfJVwKlFdpDWXM4CbiDprP9+RKyRdKGkt6ab/QWwVtIDJJ3tnyoY35hpbmxg4ZyWfmUL57TQ3OgBAsxs8lLE0F0LkjqApRHxUEX5/sB9ETHu7otta2uLlStXjvp+q/WZXH5qGy/ey8+ZmNnEJ2lVRLQN931FO+AfAY4CHqooP5rkrqxJo1QS+8yeyifevJQFs1vYa+ZU5rY2O5GY2aRWtJnrMuCLkk6X9ML0ZxnJ7brLaxfe+LRx6w7OuGYVN6x5gvkzpjiRmNmkV/Ruri+kneNfJnnqHaAT+FJEfK5WwY1Xm7Yld0fPmdZU50jMzMaHwo9tR8S5kv6N5JkTgPsjYlttwhrfNqfJZN503wpsZgbDSCYAEbGd5BbfSW3Tth0A7DO7ZYgtzcwmh8LJRNLrSIZUWURfUxcAEXHMKMc1rm3etgMBL5g17m5iMzOri6IzLZ4G/BSYQfIsyEZgDnAIcN+Ab9xNbdq2gxlTG2lt9uCOZmZQ/G6us4GzIuJkoAs4NyIOBr4FTLp+k41bO5nZ0kRjg+/iMjOD4slkf+AX6fIOkvGxAL4CnDbKMY17m7bvYFZLE00Nw54Oxsxst1T0ariZpIkLknG1XpYuzwUmXS/05m2dzJzaRIOfLzEzA4onk1uBN6XL3we+LOmbwHeBn9cisPHs6e2dzGxppNHJxMwMKH4311lAduvSp4Fu4EiSxPJvNYhr3Oro6mHbjm5mtTQx2NwqZmaTyZDJRFIjyXDxPwJIh4f/bI3jGrc2b08eWJw1tXmILc3MJo8hm7nSoeMvAjx2CMkzJgCzW31bsJlZpmifyW+BQ2sZyESRPf2+R6trJmZmmaJfry8HPi9pEcmEWNvzKyPijtEObLzKBnnce+aku4nNzGxARZPJd9LfF1dZF8CkmWYwG+TR43KZmfUp2sy1ZJCf/YseTNKxktZKWidppzncJe0n6SZJqyX9UtLCtPzPJd0maU267q+KHnO0bdq2gymNJea4mcvMrFfR+Uz+NNIDSWoALgHeSDI74+2SVkREfmyvzwNXR8RVko4huQ35FOB54NSIeFDSPsAqSTdExDMjjWu4Nm3bwcyWJpob/fS7mVmmUDKRdOJg6yPihwV2cxiwLptHXtK1wAn0HyhyKfDRdPkW+m5HfiB3rMckPQXMB8Y+mWzdwaypfmDRzCyvaJ/JDwYoj/R3kT6TBcCjudfrgVdVbHM3cCLwJeDtwAxJcyNic7aBpMNIhsD/Q4FjjrpN2zuZ5UEezcz6KdRWExGl/A/JxfxVJMOsHD2K8ZwNvFbSncBrScYB68lWStobuAb46/ThyX4kLZO0UtLKjRs3jmJYfTZv28HMlmYaS27mMjPL7NIVMSK6I+J24H8CXy34tg3AvrnXC9Oy/H4fi4gT0+HtP56WPQMgaSbwE+DjEfHbAeJaHhFtEdE2f/78Yf2biiiXgy3bu5g1tdGDPJqZ5Yz06/UzwAsLbns7cKCkJZKaSYZoWZHfQNI8SVlM5wJXpOXNwHUknfMDNbnV3LPtXfREMKvFgwGYmeUV7YA/pLII2Bv4Z+DOIvuIiG5JZwE3kPSxXBERayRdCKyMiBUkszh+WlIAvwbOTN/+LpLmtLnprI8Ap0XEXUWOPVqyp99nTXMyMTPLK9oBv5Kks72ybee3wF8XPVhEXA9cX1F2Xm75B1Tp7I+Ib5HM6lhX2dPvfsbEzKy/oslkScXrMrAxIjpGOZ5xbfP2pGYyb7qTiZlZ3pg9tLg72LQ1SSYLPJSKmVk/hTrgJX1K0geqlH9A0idHP6zxafP2TiTYc+bUoTc2M5tEit7NdQrVO9pXAaeOXjjj26ZtncyY0kRrs+cyMTPLK5pM9gSqPQW4Gdhr9MIZ3zZu7fDT72ZmVRRNJo8AR1UpP5pkWJRJYdO2Tma1NNLU4KffzczyirbXXAZ8MX148Oa07PUko/pOmvngN2/fwb5zpvnpdzOzCkXv5vqCpHnAl0nG5QLoBL4UEZ+rVXDjzdPbOnnZPrM8YrCZWYXCPckRca6kfyMZJh7g/ojYVpuwxp+Orh62d/Ywc2oTkpOJmVle0eFUXgA0RsR6kjG2svKFQFdEPFmj+MaN3qFUPC6XmdlOivYkfws4rkr5X5IMCb/b29w7lIqTiZlZpaLJpI1k4MVKt6brdntZzWSOB3k0M9tJ0WTSCEypUj51gPLdTlYz2XvWtDpHYmY2/hRNJr8D/q5K+Znk+lB2Z5vSQR73me2hVMzMKhW9m+vjwM2SDqLvOZNjgIOBN9QisPFm09ZOpjaVmD3NIwabmVUqOgf8b4EjgIeBE9Ofh4EjIuK/axfe+LFp2w5mTm2iudFPv5uZVRrOcyZ3A++tLJc0IyK2jmpU49CmbTuY1dJEk8flMjPbyS5/zZb0GklXAY+PYjzjVpZMPJSKmdnOhpVMJO0p6R8l/R74BTAf+NAw3n+spLWS1kk6p8r6/STdJGm1pF+mD0Vm694n6cH0533DiXs0bN7WycypTTSV3MxlZlZpyGYuJWOHHAecnv5eCRwAvCoiVhU9kKQG4BLgjSQjDd8uaUVE3Jfb7PPA1RFxlaRjSAaSPEXSHsD5JM+0BLAqfe+WoscfiXI52PJ8J7Namii5ZmJmtpNBv2ansyg+AnwJuAtYGhGvIbmgtw/zWIcB6yLioYjoBK4FTqjYZil9d4vdklv/l8DPI+LpNIH8HDh2mMffZc+0d1EOmOmhVMzMqhqqzeZc4ErgJRHxrxHx0AiOtQB4NPd6fVqWdzfJnWIAbwdmSJpb8L010zsu1zTPsGhmVs1QyeSfSC7q6yV9UdLBNY7nbOC1ku4EXgtsAHqKvlnSMkkrJa3cuLHaxJC7Jksme/gZEzOzqgZNJhFxcUS8jKS2MAP4laQ1gBj+dL0bgH1zrxemZfnjPRYRJ0bEwSQPShIRzxR5b7rt8ohoi4i2+fPnDzO8gWVDqew500+/m5lVU/Shxdsi4m+BvYEvkgyhclNaC/jngse6HThQ0pJ0xsaTgBX5DSTNk5TFdC5wRbp8A/AmSXMkzQHelJaNiaxmsreTiZlZVcO6zzUitkfE1yPiCODlJKMGf7Tge7uBs0iSwP3A9yNijaQLJb013ewvgLWSHiCp+Xwqfe/TwCdJEtLtwIVp2ZjYvK2TkmDPWZNiTEszs2Hb5R7liFgDfETSPw3jPdcD11eUnZdb/gHwgwHeewV9NZUxtXl7MpTKtCZ3wJuZVTPiJ/Aioms0AhnPnnpuBzNbmmjyuFxmZlX56ljAprRm0ugHFs3MqnIyKWDztuTpdycTM7PqnEwKeHp7J7NaGj3Io5nZAIbdoyxpNhVJaCzvrBpr7Z09PN/Zw8yWJpJhyszMrFKhZCJpP+BSklt384+Bi2ScroZRj2wcKJeDzdt38L1lhzOlsUS5HB7o0cysiqI1k28Cs4H3A4+RJJDdWrkcrH1yK6dfvZL1W9pZOKeFy09t48V7zXBCMTOrUDSZHAYcHhH31jKY8WTz9s7eRAKwfks7p1+9kus+eCTzZ/jhRTOzvKId8A8Dk+oK2tnd05tIMuu3tNPZXXjcSTOzSaNoMvkH4NOSDqhlMONJc2MDC+e09CtbOKeF5sbdsnvIzGxEiiaT/6Bv3KznJT2X/6ldePUzt7WZy09t600oWZ/J3FYPQ29mVqlon8lZNY1iHCqVxIv3msFX33MI7Z09LJjTwj6zWtz5bmZWRaFkEhFX1TqQ8ahUEj+79wmW//oh/vvcY5xIzMwGUPihRUlTgPeQzNMewBrguxGxo0axjQvtXT00N5ZoLHmwADOzgRS6QkpaCjwIXAy8Cjgc+N/AA5JeWrvw6q+jq0xzY4kGP/1uZjagol+3vwTcCSyKiKMi4ihgEXA3SVLZbXV09dDcUKKhwcnEzGwgRZu5jgReGRG9d25FxHOSPg78tiaRjRMdXT1MaSx5xGAzs0EUrZl0kAynUmlWum639Xxn0mfiVi4zs4EVTSb/CVwu6UhJDenPa4DLgBVFDybpWElrJa2TdE6V9Ysk3SLpTkmrJR2fljdJukrSPZLul3Ru0WOOVFYzKTmbmJkNaDhPwD8I3EpSE+kAfgU8AHy4yA4kNQCXAMeR3BF2ctqxn/cvwPcj4mDgJOCrafn/B0yJiJcDhwJnSFpcMPYRye7mcjIxMxtY0edMngFOkHQg8JK0+P6IWDeMYx0GrIuIhwAkXQucANyXPxQwM12eRTJCcVbeKqkRaAE6gTF58r6jq4fZ05pxl4mZ2cCGNTlWRDxIUkPZFQuAR3Ov15PcZpx3AXCjpA8BrcAb0vIfkCSex4FpwEfGakKujq4yzQ0lT4xlZjaIAZOJpC8D50bE9nR5QBHx96MUz8nAlRHxBUlHANdIehlJraYH2AeYA9wq6RdZLScX8zJgGcCiRYtGJaCsz8TMzAY2WM3k5UBTbnmkNgD75l4vTMvy3g8cCxARt0maCswD3g38LCK6gKck/QZoA/olk4hYDiwHaGtrG5UJvLI+EzMzG9iAySQiXldteQRuBw6UtIQkiZxEkiTyHgFeD1yZPlk/FdiYlh9DUlNppe8J/Jrb0VV2zcTMbAhFh1M5T9K0KuUtks4rso+I6CYZffgG4H6Su7bWSLpQ0lvTzT4GnC7pbuC7wGkRESR3gU2XtIYkKX0zIlYXOe5I9JSDzp6yayZmZkMo2gF/PnAp8HxF+bR03YVFdhIR1wPXV5Sdl1u+j+Rp+8r3bSO5PXhM7UhnVXTNxMxscEWvkiK5PbfSwcCY3FVVD+2dSTJxzcTMbHCD1kwkbSVJIgE8JCmfUBpI+jQurV149dXRXQagucHJxMxsMEM1c51FUiu5Avg48GxuXSfwx4i4rUax1V1WM5nied/NzAY1aDLJZliU9DDw3+mtuZNGR5ebuczMiig6nMqvsmVJLwCaK9Y/MspxjQtZB/zUJtdMzMwGUyiZSJoJ/B/gXVQkktRuebVt70z6THw3l5nZ4IpeJb8AvAJ4G8mIwe8G/pFkfK2/qk1o9Zc1c7VOGdYQZmZmk07Rq+RxwMkRcaukHmBVRHxP0uPAGSQDMe522tNkMq3ZNRMzs8EUvUrOBv6ULj8LzE2XbwNePdpBjRd9NZOmIbY0M5vciiaTPwD7p8v3AycpGZP9RHbjhxazZNLiDngzs0EVTSZXAgely58hadrqBC4CPjv6YY0PHV1JB3xrs5OJmdlgit4a/MXc8s2SXkIyBPyDEXFPrYKrt94+k6lOJmZmg9ml25TS50p2y2dL8jq6emgsyU/Am5kNoegQ9N+U9LEq5R+V9PXRD2t8yCbGaiz5bi4zs8EUvUoeB9xcpfxm4PjRC2d86ehK5jJp8PzvZmaDGs6twduqlG8H9hi9cMaXjq4emhtKNDQ4mZiZDaZoMnmA6jWQ/wGsG71wxpesmcs1EzOzwRXtgP8CcKmkPelr7no98GHgzFoENh60d/YwpbGEc4mZ2eAK1UzSoeg/DJwK/Dz9OQX4aER8s+jBJB0raa2kdZLOqbJ+kaRbJN0pabWk43PrDpJ0m6Q1ku6RNLXocXdVR1ozKTmbmJkNqvCtwRFxGXCZpPnp643DOZCkBuAS4I0kA0TeLmlFOu975l+A70fE1yQtJZkvfrGkRuBbwCkRcbekuUDN51Zp700mtT6SmdnENux7XiNi43ATSeowYF1EPBQRncC1wAmVuwdmpsuzgMfS5TcBqyPi7jSGzRHRswsxDEvWAe+aiZnZ4AasmUhaDbw2IrZIuofkQl9VRBw00LqcBcCjudfrgVdVbHMBcKOkDwGtwBvS8hcBIekGYD5wbUR8rsAxR6Sjq8yeM9xnYmY2lMGauf4vsCO3PGAyGUUnA1dGxBckHQFcI+llJHG+Bngl8Dxwk6RVEXFT/s2SlgHLABYtWjTiYLI+EzmbmJkNarBk8jDQAxARF4zCsTYA++ZeL0zL8t4PHJse87a0k30eSS3m1xGxCUDS9cAhQL9kEhHLgeUAbW1tI05+HV09HkrFzKyAwfpMvknafyGpJ70teCRuBw6UtERSM3ASsKJim0dIbjlG0kuBqcBG4Abg5ZKmpZ3xrwXuo8aSJ+BdKzEzG8pgyWQjcES6LEbYzBUR3cBZJInhfpK7ttZIulDSW9PNPgacLulu4LvAaZHYAlxMkpDuAu6IiJ+MJJ6hlMtBZ0/ZNRMzswIGa+a6FPiRpCBJJE8M1HcQEYWuuBFxPcntvvmy83LL9wFHDvDeb5HcHjwmOrqTm8WaGjzIo5nZUAZMJhFxgaR/Bw4EfgicDjwzVoHVWzYx1pRGJxMzs6EM+tBiRKwB1kj6V+C7EfH82IRVf9nEWM1OJmZmQ+Z8LLIAABE5SURBVCo60+K/1jqQ8abDycTMrLCxfGhxQmnvTJLJVHfAm5kNqehDiz8Yg1jGlR3drpmYmRU1WAf8v1ZbnizaO5MOeNdMzMyGVnQO+JKkUu71CyT9raRX1y60+sr6TKY1u2ZiZjaUolfKnwAfApA0HVgJXAT8StKpNYqtrrK7uVqnFB6l38xs0iqaTNrom2HxROA5YE+SZ0/OrkFcdZfVTFqnOpmYmQ2laDKZTt8Di28CrouILpIE88JaBFZvvcmk2cnEzGwoRZPJI8CRklqBvySZthdgD5Ih4Xc72RPwLU3ugDczG0rRr90XA9cA24A/Ab9Oy48G7qlBXHXXWzOZ4mRiZjaUok/AXyZpFcl8JD+PiHK66g/AJ2oVXD21d/XQUBJTXDMxMxtS4Q6BiFhJchcXAJKaaj0MfD0lc5mUaCz51mAzs6EUfc7k7yW9I/f6G0C7pLWSXlyz6OqovauH5oYSDSVPjmVmNpSiX7v/nmSyLCQdDbwLeDfJRFVfqE1o9ZVM2etkYmZWRNFmrgUkc8IDvAX494j4fjoA5K01iazO2jt7aG4s4VxiZja0ojWT7CFFgDcCN6XLXSTztO92OtJmrtIAs0uamVmfosnkRuBySV8HDgB+mpb/GX01liFJOjbtZ1kn6Zwq6xdJukXSnZJWSzq+yvptkmr+1H17V1IzcS4xMxta0WRyJvAbYD7wzoh4Oi0/BPhukR1IagAuAY4DlgInS1pasdm/AN+PiIOBk4CvVqy/mL5EVlMdWTLB2cTMbChFnzN5jnSgx4ry84dxrMOAdRHxEICka4ETgPvyuwRmpsuzgMeyFZLeRlIL2j6MY+6y9q4eZrU0uc/EzKyAYQ88JekFQHO+LCIeKfDWBcCjudfrgVdVbHMBcKOkDwGtwBvSY04H/pmkv2bAJi5Jy4BlAIsWLSoQ0sA6usrMm+4+EzOzIoo+ZzJL0lWS2oENJDWE/M9oORm4MiIWAscD16TzqFwAfDEitg325ohYHhFtEdE2f/78EQWS3RpcctXEzGxIRWsmnwdeAbwN+CHwNyQ1jX8APlZwHxtIhmPJLEzL8t4PHAsQEbdJmgrMI6nBvFPS54DZQFlSR0R8peCxhy3rMzEzs6EVTSbHASdHxK2SeoBVEfE9SY8DZ1BsjvjbgQMlLSFJIieRPPiY9wjweuBKSS8lue14Y0QclW0g6QJgWy0TCfQNp2JmZkMrerWcTTJaMMCzwNx0+Tag0NS9EdENnAXcANxPctfWGkkXSnprutnHgNMl3U1yl9hpEREFYxw15XLQ2VOmucHJxMysiKI1kz8A+5PUHO4HTpL0/0hmXXx6sDfmRcT1wPUVZefllu8DjhxiHxcUPd6u6uhOhp+f0ugRg83Miij61ftK4KB0+TMkTVudJPPAf3b0w6qvbGIsN3OZmRVT9DmTL+aWb5b0EpJ54R+MiN1ucqxsYiwnEzOzYnZpgvP0uZIiz5ZMSO1dWTOXk4mZWREDJhNJHy26k4i4eHTCGR+ymsnUJicTM7MiBquZ7DR8ygCCZMys3UZHlzvgzcyGY8BkEhFLxjKQ8cQd8GZmw+OrZRXtnUnNpLXZNRMzsyIGTSaSjpP0R0kzq6ybla57Y+3Cq4/sOZPWKbt0f4KZ2aQzVM3kLOCidAj6fiLiWZJnTD5ci8DqqbdmMsU1EzOzIoZKJgcBvxhk/c0kA0DuVjq6kz6T1mbXTMzMihgqmcwHyoOsD/rG6dptdKQ1k2lOJmZmhQyVTNbTN4xKNQex8zDyE152a7CbuczMihkqmfwE+KSklsoVkqYBF6bb7Fbau3pokJjS5GRiZlbEUO04nwLeCTwg6SvA79Pyl5J0zgv4X7ULrz6yuUwaS75z2sysiEGTSUQ8JenVwNdIkkY2h22QzEtyZkQ8WdsQx157Ostig+d/NzMrZMge5oj4E3C8pDnAASQJ5cGI2FLr4Oqlo6uH5oYSrpiYmRVT+HalNHncXsNYxo3nO7tpbixRcs3EzKwQf/euIuszcS4xMytmTJOJpGMlrZW0TtI5VdYvknSLpDslrZZ0fFr+RkmrJN2T/j6mlnH2NnM5m5iZFTJmT+VJagAuAd5I8vzK7ZJWpPO+Z/4F+H5EfE3SUpL54hcDm4C3RMRjkl5G0vm/oFaxtnf1MMU1EzOzwsayZnIYsC4iHoqITuBa4ISKbQLIBpWcBTwGEBF3RsRjafkaoEXSlFoF2pHezeWaiZlZMWOZTBYAj+Zer2fn2sUFwHslrSeplVSboOsdwB0RsaNyhaRlklZKWrlx48ZdDjTrM3EyMTMrZrx1wJ8MXBkRC4HjgWsk9cYo6c9IRio+o9qbI2J5RLRFRNv8+fN3OYi+PpNd3oWZ2aQylslkA7Bv7vVCdh7X6/3A9wEi4jZgKjAPQNJC4Drg1Ij4Qy0DzZq55JqJmVkhY5lMbgcOlLREUjNwErCiYptHgNcDSHopSTLZKGk2yRhg50TEb2od6I7uMlM8Za+ZWWFjdjdXRHRLOovkTqwG4IqIWCPpQmBlRKwAPgZcLukjJJ3xp0VEpO87ADhP0nnpLt8UEU+Ndpzd3WW+fPLB7DN7Khu37mBuazMlt3eZmQ1KEVHvGGqira0tVq5cOaz3lMvB75/YyrJrVrJ+SzsL57Rw+altvHivGU4oZjYpSFoVEW3DfZ/bcnI2b+/sTSQA67e0c/rVK9m8vbPOkZmZjW9OJjmd3T29iSSzfks7nd09dYrIzGxicDLJaW5sYOGc/vOALZzTQnOjJ8kyMxuMk0nO3NZmLj+1rTehZH0mc1ub6xyZmdn4NmZ3c00EpZJ48V4zuHbZ4XT1lJk+pcl3c5mZFeCaSYVSSUyf0khPOZg/Y4oTiZlZAa6ZVDF7WjOzp7lpy8ysKNdMzMxsxJxMzMxsxJxMzMxsxJxMzMxsxJxMzMxsxJxMzMxsxJxMzMxsxJxMzMxsxHbb+UwkbQT+NMgm84BNYxTOaJuosTvusTdRY5+occPEjT2Le7+ImD/cN++2yWQoklbuygQw48FEjd1xj72JGvtEjRsmbuwjjdvNXGZmNmJOJmZmNmKTOZksr3cAIzBRY3fcY2+ixj5R44aJG/uI4p60fSZmZjZ6JnPNxMzMRomTiZmZjdikTCaSjpW0VtI6SefUO56BSNpX0i2S7pO0RtI/pOUXSNog6a705/h6x1qNpD9KuieNcWVatoekn0t6MP09p95x5kl6ce683iXpOUkfHq/nXNIVkp6SdG+urOo5VuLL6ed+taRDxlncF0n6fRrbdZJmp+WLJbXnzv2l4yzuAT8bks5Nz/daSX9Zn6h7Y6kW+/dycf9R0l1p+fDPeURMqh+gAfgDsD/QDNwNLK13XAPEujdwSLo8A3gAWApcAJxd7/gKxP9HYF5F2eeAc9Llc4DP1jvOIT4rTwD7jddzDhwNHALcO9Q5Bo4HfgoIOBz43TiL+01AY7r82Vzci/PbjcPzXfWzkf6t3g1MAZak152G8RR7xfovAOft6jmfjDWTw4B1EfFQRHQC1wIn1DmmqiLi8Yi4I13eCtwPLKhvVCN2AnBVunwV8LY6xjKU1wN/iIjBRlKoq4j4NfB0RfFA5/gE4OpI/BaYLWnvsYm0v2pxR8SNEdGdvvwtsHDMAxvCAOd7ICcA10bEjoh4GFhHcv2pi8FilyTgXcB3d3X/kzGZLAAezb1ezwS4QEtaDBwM/C4tOittDrhivDUV5QRwo6RVkpalZXtFxOPp8hPAXvUJrZCT6P/HNRHOOQx8jifSZ/9vSGpRmSWS7pT0K0lH1SuoQVT7bEyk830U8GREPJgrG9Y5n4zJZMKRNB34v8CHI+I54GvAC4E/Bx4nqZ6OR6+JiEOA44AzJR2dXxlJfXpc3psuqRl4K/DvadFEOef9jOdzPBBJHwe6gW+nRY8DiyLiYOCjwHckzaxXfFVMyM9GhZPp/8Vp2Od8MiaTDcC+udcL07JxSVITSSL5dkT8ECAinoyInogoA5dTx6rzYCJiQ/r7KeA6kjifzJpW0t9P1S/CQR0H3BERT8LEOeepgc7xuP/sSzoNeDPwnjQRkjYTbU6XV5H0PbyobkFWGOSzMe7PN4CkRuBE4HtZ2a6c88mYTG4HDpS0JP32eRKwos4xVZW2Y34DuD8iLs6V59u53w7cW/neepPUKmlGtkzSuXovybl+X7rZ+4D/qE+EQ+r3TW0inPOcgc7xCuDU9K6uw4Fnc81hdSfpWOCfgLdGxPO58vmSGtLl/YEDgYfqE+XOBvlsrABOkjRF0hKSuP/fWMdXwBuA30fE+qxgl855ve4sqOcPyV0tD5Bk24/XO55B4nwNSRPFauCu9Od44BrgnrR8BbB3vWOtEvv+JHey3A2syc4zMBe4CXgQ+AWwR71jrRJ7K7AZmJUrG5fnnCThPQ50kbTJv3+gc0xyF9cl6ef+HqBtnMW9jqSPIfusX5pu+470M3QXcAfwlnEW94CfDeDj6fleCxw33j4rafmVwAcqth32OfdwKmZmNmKTsZnLzMxGmZOJmZmNmJOJmZmNmJOJmZmNmJOJmZmNmJOJ2SQi6TRJ2+odh+1+nExstyfpSkkh6RtV1n02XffjGsewOD1O9rMtHZb865IOqtEx/yjp7Frs26ySk4lNFo8C70qfxgd6h5E4FXhkDOM4lmRqgZcDHwH2BFZJOmkMYzAbdU4mNlmsJnki/F25sv8BdAC/zG8o6ZWSbpS0ScnkWP8l6Yjc+tdK6pL0F7myM9Jt9x8ijs0R8UREPBwR10dENpjkpUong0r39+p0tNbn04mXvpYfaE/SLyVdKulLkrakPxdJKmXrSeZhuSirDVX8G18v6V5J25VMwLakwDk0G5CTiU0m3yAZ2jzzN8A32XlU3RkkQ2QcRTJo313A9ZLmAkTEr4CLgGskzZH0EuBi4EMRsStjRn0emEUyRhKSXg7cSDI0xytIBuH7c+CKive9h+Rv+AjgDGAZ8OF03YkkQ2ZcSFITyo8fNQU4N/33HwHMBuo2e6HtHhrrHYDZGPoO8HlJBwJbSZqcPkRywe0VETfnX0v6EMlYRccB30qLzwfeSJKgFgM/joir2DX3pb+zWs0/At+LiN6hzCX9HXCnpD0jGYUZknGW/j6SMZF+L+lFJMOFXxwRT0vqAbZGxBMVx2sEzoyItem+Pw9cIUnh8ZVsFzmZ2KQREVskXUfyjfwZ4JcR8UgyOHMfSXsCnwReRzKxVAPQAizK7atL0rtJBsN7CjhmBKFlAWQX8kOBAyT9VZVtXkjfkPK/rbj43wZ8UtLMSOa9GciOLJGkHiOZwnoOxWcRNOvHycQmmytIprLdBpw3wDZXkSSRj5DMY7+DZBTe5ortDidpZpoNzCdJULtiafo7ayIrAV8Hvlhl29GYD6O74nWWkNzsbbvMycQmm5uATmAe8KMBtnkNSfPRTwAk7UX/PgfSDuuvAGeSNJd9S9KR0TeH+XCcDTxLMlw8JEN+/1lErBvifa+qaJo6HHgsVyvpJKlVmdWcv4nYpJJeeA8ClkTEjgE2ewB4r6Slkl4JXEtyYQYgnTToGuBXEXEZ8LckM+qdXyCEuZJekE7OdpykFcA7SeaTeDbd5rPAYendWgdLOkDSmyVdVrGvfYD/LenFkt5J0teSr838EThK0gJJ8wrEZrbLXDOxSScitg6xyd8Ay4FVJP0JF5A0Y2X+J3AAybMiRMRmSe8juePrhoj4r0H2/bP0dzvJ3Va3kkxSdXcuvtWSjgb+DfgVSe3iIZKpj/O+na77HUlT1Tfon0zOAy4jmZxpCn39LmajzpNjmU1A6XMk90bEWfWOxQzczGVmZqPAycTMzEbMzVxmZjZirpmYmdmIOZmYmdmIOZmYmdmIOZmYmdmIOZmYmdmI/f/hLtqUXnfb9gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", + "plt.xlabel('Max Depth',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(depth_dataObj)\n", + "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Five: Grid Search Tuning\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", + "Wall time: 12h 1min 47s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_depth': 21, 'max_features': 21}" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "# Perform Grid Search Tuning\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=21, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Six: Random Search Tuning.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", + "Wall time: 7h 38min 25s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_features': 21, 'max_depth': 111}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "import numpy as np\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=111, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/varying_depths_plot.png b/doc/tutorial/hyperparameter_tuning_random_forest/varying_depths_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..07096b019cb80b5f7879575b57204344008817c0 GIT binary patch literal 92171 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%0DX;I18Jd`MRd%ozcLSz5`pQ?*M&P-f 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 literal 0 HcmV?d00001 From 5645790e71e00c1e249b1d40def134da1cdfc4aa Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Fri, 6 Dec 2019 22:54:54 -0500 Subject: [PATCH 02/14] Add files via upload Added heat map --- .../Tuning_Tutorial_Edit1.ipynb | 1232 +++++++++++++++++ 1 file changed, 1232 insertions(+) create mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb new file mode 100644 index 0000000000000..9061f777bde71 --- /dev/null +++ b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb @@ -0,0 +1,1232 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameter Tuning Tutorial \n", + "\n", + "
\n", + " Objective: \n", + "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", + "
\n", + "\n", + " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", + "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", + "1. Random sampling of training data points when building trees\n", + "2. Random subsets of features considered when splitting nodes\n", + "\n", + "**The Dataset**\n", + "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", + "\n", + "
\n", + "\n", + "# Hyperparameter Tuning Methods\n", + "\n", + "
\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import GridSearchCV\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. GridSearchCV\n", + "\n", + "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", + "\n", + "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import GridSearchCV\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. RandomizedSearchCV\n", + "\n", + "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n", + "\n", + "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations. Of the 100 possible combinations, this sample code below in the tutorial selects 50." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```Python\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Results \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Models |Performance | Best Params | Computation Time |\n", + "|---------------|--------------|----------------------------------|----------------------------|\n", + "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", + "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", + "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Code \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Code is structured in the following order.\n", + "
    \n", + "
  1. Loading and Preprocessing Data
  2. \n", + "
  3. Building Base Random Forest Model
  4. \n", + "
  5. Tuning the number of features
  6. \n", + "
  7. Tuning the depths of the trees
  8. \n", + "
  9. Grid Search Tuning
  10. \n", + "
  11. Random Search Tuning
  12. \n", + "
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import fetch_openml\n", + "# Load data from https://www.openml.org/d/554\n", + "from PIL import Image, ImageDraw\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section One: Loading and Preprocessing Data\n", + "
\n", + "\n", + "
\n", + " There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(70000, 784)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the dataset\n", + "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", + "\n", + "# Check dimensions of the data\n", + "images.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "label: 9\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Pick the fifth image from the dataset (it's a 9)\n", + "i = 4\n", + "image, label = images[i], labels[i]\n", + "\n", + "# Print the image\n", + "output = Image.new(\"L\", (28, 28))\n", + "output.putdata(image)\n", + "print('label:',label)\n", + "plt.imshow(np.asarray(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train samples: 10000\n", + "Test samples: 1000\n" + ] + } + ], + "source": [ + "# Splitting the data into training and testing samples\n", + "from sklearn.model_selection import train_test_split\n", + "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", + " test_size = 1000, random_state = 42)\n", + "print('Train samples:', images_train.shape[0])\n", + "print('Test samples:', images_test.shape[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Assume a Gaussian distribution for the MNIST dataset and standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Feature Scaling\n", + "from sklearn.preprocessing import StandardScaler\n", + "scaler = StandardScaler()\n", + "images_train = scaler.fit_transform(images_train)\n", + "images_test = scaler.transform(images_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Two: Create and evaluate base Random Forest model with 500 estimators.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.954\n", + "[0.91133005 0.89108911 0.90049751 0.89393939 0.87755102]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n", + "CPU times: user 25.3 s, sys: 258 ms, total: 25.6 s\n", + "Wall time: 25.7 s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Three: Tuning number of features.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "5\n", + "6\n", + "9\n", + "12\n", + "16\n", + "21\n", + "27\n", + "36\n", + "48\n", + "64\n", + "84\n", + "111\n", + "147\n", + "194\n", + "256\n", + "337\n", + "445\n", + "588\n", + "776\n", + "CPU times: user 5h 9min 11s, sys: 2min 52s, total: 5h 12min 3s\n", + "Wall time: 35min 29s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of features\n", + "accuracies = []\n", + "# Number of features to perform a hyperparameter sweep\n", + "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each feature value\n", + "num_trials = 10\n", + "\n", + "feature_dataObj = pd.DataFrame()\n", + "feature_list = []\n", + "accuracy_scores = []\n", + "\n", + "for feature in features:\n", + " print(feature)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5, n_jobs = -2)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " feature_list.append(feature)\n", + " \n", + "feature_dataObj['Feature List'] = feature_list\n", + "feature_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'feature_dataObj' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mseaborn\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0msns\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlineplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Feature List'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Accuracy'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfeature_dataObj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmarker\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'o'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# plt.title('Varying Max_Features for MNIST Data')\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Number of Features'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfontsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m14\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Classification Accuracy'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfontsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m14\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'feature_dataObj' is not defined" + ] + } + ], + "source": [ + "import seaborn as sns\n", + "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", + "# plt.title('Varying Max_Features for MNIST Data')\n", + "plt.xlabel('Number of Features',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(feature_dataObj)\n", + "# save the figure to the current working directory\n", + "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Four: Tuning maximum depth of trees.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "6\n", + "9\n", + "13\n", + "21\n", + "32\n", + "48\n", + "73\n", + "111\n", + "168\n", + "CPU times: user 25min 45s, sys: 11 s, total: 25min 56s\n", + "Wall time: 25min 59s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of depths\n", + "accuracies = []\n", + "# Number of depths to perform a hyperparameter sweep\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each depth value\n", + "num_trials = 10\n", + "\n", + "depth_dataObj = pd.DataFrame()\n", + "depth_list = []\n", + "accuracy_scores = []\n", + "\n", + "for depth in depths:\n", + " print(depth)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " depth_list.append(depth)\n", + " \n", + "depth_dataObj['Depth List'] = depth_list\n", + "depth_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Depth List Accuracy\n", + "0 4 0.812\n", + "1 4 0.812\n", + "2 4 0.814\n", + "3 4 0.808\n", + "4 4 0.818\n", + ".. ... ...\n", + "95 168 0.954\n", + "96 168 0.959\n", + "97 168 0.959\n", + "98 168 0.959\n", + "99 168 0.957\n", + "\n", + "[100 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", + "plt.xlabel('Max Depth',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(depth_dataObj)\n", + "plt.xscale('log')\n", + "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Five: Grid Search Tuning\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", + "Wall time: 12h 1min 47s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_depth': 21, 'max_features': 21}" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "# Perform Grid Search Tuning\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=21, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Section Six: Random Search Tuning.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", + "Wall time: 7h 38min 25s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_features': 21, 'max_depth': 111}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "import numpy as np\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=111, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predficted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'n_depth': 4, 'n_features': 4}\n", + "0.814\n", + "trial score: 0.814\n", + "{'n_depth': 4, 'n_features': 6}\n", + "0.824\n", + "trial score: 0.824\n", + "{'n_depth': 4, 'n_features': 12}\n", + "0.82\n", + "trial score: 0.82\n", + "{'n_depth': 4, 'n_features': 21}\n", + "0.821\n", + "trial score: 0.821\n", + "{'n_depth': 4, 'n_features': 36}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 64}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 111}\n", + "0.797\n", + "trial score: 0.797\n", + "{'n_depth': 4, 'n_features': 194}\n", + "0.79\n", + "trial score: 0.79\n", + "{'n_depth': 4, 'n_features': 337}\n", + "0.768\n", + "trial score: 0.768\n", + "{'n_depth': 4, 'n_features': 588}\n", + "0.733\n", + "trial score: 0.733\n", + "{'n_depth': 6, 'n_features': 4}\n", + "0.859\n", + "trial score: 0.859\n", + "{'n_depth': 6, 'n_features': 6}\n", + "0.87\n", + "trial score: 0.87\n", + "{'n_depth': 6, 'n_features': 12}\n", + "0.882\n", + "trial score: 0.882\n", + "{'n_depth': 6, 'n_features': 21}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 36}\n", + "0.894\n", + "trial score: 0.894\n", + "{'n_depth': 6, 'n_features': 64}\n", + "0.891\n", + "trial score: 0.891\n", + "{'n_depth': 6, 'n_features': 111}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 194}\n", + "0.887\n", + "trial score: 0.887\n", + "{'n_depth': 6, 'n_features': 337}\n", + "0.876\n", + "trial score: 0.876\n", + "{'n_depth': 6, 'n_features': 588}\n", + "0.855\n", + "trial score: 0.855\n", + "{'n_depth': 9, 'n_features': 4}\n", + "0.905\n", + "trial score: 0.905\n", + "{'n_depth': 9, 'n_features': 6}\n", + "0.917\n", + "trial score: 0.917\n", + "{'n_depth': 9, 'n_features': 12}\n", + "0.928\n", + "trial score: 0.928\n", + "{'n_depth': 9, 'n_features': 21}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 36}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 9, 'n_features': 64}\n", + "0.941\n", + "trial score: 0.941\n", + "{'n_depth': 9, 'n_features': 111}\n", + "0.939\n", + "trial score: 0.939\n", + "{'n_depth': 9, 'n_features': 194}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 337}\n", + "0.935\n", + "trial score: 0.935\n", + "{'n_depth': 9, 'n_features': 588}\n", + "0.925\n", + "trial score: 0.925\n", + "{'n_depth': 13, 'n_features': 4}\n", + "0.936\n", + "trial score: 0.936\n", + "{'n_depth': 13, 'n_features': 6}\n", + "0.943\n", + "trial score: 0.943\n", + "{'n_depth': 13, 'n_features': 12}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 21}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 36}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 64}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 13, 'n_features': 111}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 13, 'n_features': 194}\n", + "0.949\n", + "trial score: 0.949\n", + "{'n_depth': 13, 'n_features': 337}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 13, 'n_features': 588}\n", + "0.942\n", + "trial score: 0.942\n", + "{'n_depth': 21, 'n_features': 4}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 21, 'n_features': 12}\n", + "0.955\n", + "trial score: 0.955\n", + "{'n_depth': 21, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 21, 'n_features': 36}\n", + "0.96\n", + "trial score: 0.96\n", + "{'n_depth': 21, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 21, 'n_features': 111}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 21, 'n_features': 194}\n", + "0.951\n", + "trial score: 0.951\n", + "{'n_depth': 21, 'n_features': 337}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 32, 'n_features': 4}\n", + "0.946\n", + "trial score: 0.946\n", + "{'n_depth': 32, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 32, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 32, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 32, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 32, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 32, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 32, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 48, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 48, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 48, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 48, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 48, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 48, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 48, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 48, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 73, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 73, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 73, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 73, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 73, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 73, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 73, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 73, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 111, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 111, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 111, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 111, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 111, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 111, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 111, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 111, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 168, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 168, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 168, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 168, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 168, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 168, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 168, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 168, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.model_selection import ParameterGrid\n", + "from sklearn.metrics import accuracy_score\n", + "import numpy as np\n", + "\n", + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depth = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "grid = {'n_features': features, 'n_depth': depth}\n", + "param_combo = []\n", + "acc_scores = []\n", + "\n", + "list_features = []\n", + "list_depths = []\n", + "\n", + "num_trials = 1\n", + "trial_score = 0\n", + "for count, params in enumerate(ParameterGrid(grid)):\n", + " print(params)\n", + " for t in range(num_trials):\n", + "\n", + " # Obtain similarity matrix from USPORF classifier\n", + " clf = RandomForestClassifier(n_estimators = 500,\n", + " max_features = params['n_features'],\n", + " max_depth = params['n_depth'],\n", + " random_state=42,\n", + " n_jobs = -2)\n", + "\n", + " clf.fit(images_train, labels_train)\n", + " \n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " print(score)\n", + "\n", + " # Save tree information and associated ARI score\n", + " param_combo.append(params)\n", + " trial_score += score\n", + " list_depths.append(params['n_depth'])\n", + " list_features.append(params['n_features'])\n", + " \n", + " print('trial score:',trial_score/num_trials)\n", + " acc_scores.append(trial_score/num_trials)\n", + " trial_score = 0" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "data = {'Depth':list_depths, 'Features':list_features, 'Accuracy': acc_scores}\n", + "df = pd.DataFrame(data) \n", + "df = df.pivot(\"Depth\", \"Features\", \"Accuracy\")\n", + "ax = sns.heatmap(df,linewidths=.5)" + ] + }, + { + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 7624546d512d98466f7f6fb7a25c3c697d77f0d9 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 12 Dec 2019 16:06:35 -0500 Subject: [PATCH 03/14] removed html tags --- .../Tuning_Tutorial_Edit1.ipynb | 129 ++++++++---------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb index 9061f777bde71..db302b24c9979 100644 --- a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb +++ b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb @@ -6,10 +6,8 @@ "source": [ "# Parameter Tuning Tutorial \n", "\n", - "
\n", " Objective: \n", "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", - "
\n", "\n", " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", @@ -19,11 +17,7 @@ "**The Dataset**\n", "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", "\n", - "
\n", - "\n", "# Hyperparameter Tuning Methods\n", - "\n", - "
\n", " " ] }, @@ -102,9 +96,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Results \n", - "
" + "# Results " ] }, { @@ -126,26 +118,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Code \n", - "
" + "# Code \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", "Code is structured in the following order.\n", - "
    \n", - "
  1. Loading and Preprocessing Data
  2. \n", - "
  3. Building Base Random Forest Model
  4. \n", - "
  5. Tuning the number of features
  6. \n", - "
  7. Tuning the depths of the trees
  8. \n", - "
  9. Grid Search Tuning
  10. \n", - "
  11. Random Search Tuning
  12. \n", - "
\n", - "
" + " 1. Loading and Preprocessing Data \n", + " 2. Building Base Random Forest Model \n", + " 3. Tuning the number of features\n", + " 4. Tuning the depths of the trees\n", + " 5. Grid Search Tuning \n", + " 6. Random Search Tuning\n", + " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously" ] }, { @@ -167,13 +154,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section One: Loading and Preprocessing Data\n", - "
\n", + "## Section One: Loading and Preprocessing Data\n", "\n", - "
\n", - " There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n", - "
\n" + "There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n" ] }, { @@ -204,9 +187,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n", - "
\n" + "Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n" ] }, { @@ -260,9 +241,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n", - "
" + "Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n" ] }, { @@ -292,9 +271,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Assume a Gaussian distribution for the MNIST dataset and standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n", - "
" + "Standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n" ] }, { @@ -314,18 +291,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section Two: Create and evaluate base Random Forest model with 500 estimators.\n", - "
" + "## Section Two: Create and evaluate base Random Forest model with 500 estimators." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n", - "
" + "Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n" ] }, { @@ -379,9 +352,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section Three: Tuning number of features.\n", - "
" + "## Section Three: Tuning number of features." ] }, { @@ -456,19 +427,40 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 12, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'feature_dataObj' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mseaborn\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0msns\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlineplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Feature List'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Accuracy'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfeature_dataObj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmarker\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'o'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# plt.title('Varying Max_Features for MNIST Data')\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Number of Features'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfontsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m14\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Classification Accuracy'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfontsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m14\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'feature_dataObj' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + " Feature List Accuracy\n", + "0 4 0.845\n", + "1 4 0.844\n", + "2 4 0.839\n", + "3 4 0.838\n", + "4 4 0.838\n", + ".. ... ...\n", + "195 776 0.793\n", + "196 776 0.792\n", + "197 776 0.794\n", + "198 776 0.794\n", + "199 776 0.788\n", + "\n", + "[200 rows x 2 columns]\n" ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ @@ -486,9 +478,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section Four: Tuning maximum depth of trees.\n", - "
" + "## Section Four: Tuning maximum depth of trees." ] }, { @@ -602,9 +592,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section Five: Grid Search Tuning\n", - "
\n" + "## Section Five: Grid Search Tuning" ] }, { @@ -655,9 +643,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n", - "
" + "Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n" ] }, { @@ -708,9 +694,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "Section Six: Random Search Tuning.\n", - "
" + "## Section Six: Random Search Tuning." ] }, { @@ -764,9 +748,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - " Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n", - "
" + "Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n" ] }, { @@ -813,6 +795,13 @@ "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Seven: Heat Map" + ] + }, { "cell_type": "code", "execution_count": 17, From 1c84e499298ef830f123015904a468c908ac4634 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Fri, 13 Dec 2019 10:53:56 -0500 Subject: [PATCH 04/14] deleted unnecessary file --- .../Hyperparameter_Tuning_RF_Final.ipynb | 856 ------------------ 1 file changed, 856 deletions(-) delete mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb deleted file mode 100644 index 0dfa3a44ed754..0000000000000 --- a/doc/tutorial/hyperparameter_tuning_random_forest/Hyperparameter_Tuning_RF_Final.ipynb +++ /dev/null @@ -1,856 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Parameter Tuning Tutorial \n", - "\n", - "
\n", - " Objective: \n", - "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", - "
\n", - "\n", - " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", - "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", - "1. Random sampling of training data points when building trees\n", - "2. Random subsets of features considered when splitting nodes\n", - "\n", - "**The Dataset**\n", - "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", - "\n", - "
\n", - "\n", - "# Hyperparameter Tuning Methods\n", - "\n", - "
\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import GridSearchCV\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. GridSearchCV\n", - "\n", - "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", - "\n", - "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import GridSearchCV\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. RandomizedSearchCV\n", - "\n", - "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n", - "\n", - "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations. Of the 100 possible combinations, this sample code below in the tutorial selects 50." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import RandomizedSearchCV\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", - " cv = 3, random_state=42)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Results \n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "|Models |Performance | Best Params | Computation Time |\n", - "|---------------|--------------|---------------------------------|----------------------------|\n", - "|Base Model | 0.89 ± 0.02 | | | \n", - "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", - "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111|CPU total time: 2h 6min 6s | \n", - "\n", - "\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Code \n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Code is structured in the following order.\n", - "
    \n", - "
  1. Loading and Preprocessing Data
  2. \n", - "
  3. Building Base Random Forest Model
  4. \n", - "
  5. Tuning the number of features
  6. \n", - "
  7. Tuning the depths of the trees
  8. \n", - "
  9. Grid Search Tuning
  10. \n", - "
  11. Random Search Tuning
  12. \n", - "
\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.datasets import fetch_openml\n", - "# Load data from https://www.openml.org/d/554\n", - "from PIL import Image, ImageDraw\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import seaborn as sns" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section One: Loading and Preprocessing Data\n", - "
\n", - "\n", - "
\n", - " There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n", - "
\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(70000, 784)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Load the dataset\n", - "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", - "\n", - "# Check dimensions of the data\n", - "images.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n", - "
\n" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "label: 9\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# Pick the fifth image from the dataset (it's a 9)\n", - "i = 4\n", - "image, label = images[i], labels[i]\n", - "\n", - "# Print the image\n", - "output = Image.new(\"L\", (28, 28))\n", - "output.putdata(image)\n", - "print('label:',label)\n", - "plt.imshow(np.asarray(output))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Train samples: 10000\n", - "Test samples: 1000\n" - ] - } - ], - "source": [ - "# Splitting the data into training and testing samples\n", - "from sklearn.model_selection import train_test_split\n", - "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", - " test_size = 1000, random_state = 42)\n", - "print('Train samples:', images_train.shape[0])\n", - "print('Test samples:', images_test.shape[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Assume a Gaussian distribution for the MNIST dataset and standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [], - "source": [ - "# Feature Scaling\n", - "from sklearn.preprocessing import StandardScaler\n", - "scaler = StandardScaler()\n", - "images_train = scaler.fit_transform(images_train)\n", - "images_test = scaler.transform(images_test)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section Two: Create and evaluate base Random Forest model with 500 estimators.\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.954\n", - "[0.91133005 0.89108911 0.90049751 0.89393939 0.88265306]\n", - "Cross-Validation (CV=5) Accuracy: 0.90 (+/- 0.02)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section Three: Tuning number of features.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "6\n", - "9\n", - "12\n", - "16\n", - "21\n", - "27\n", - "36\n", - "48\n", - "64\n", - "84\n", - "111\n", - "147\n", - "194\n", - "256\n", - "337\n", - "445\n", - "588\n", - "776\n", - "CPU times: user 2h 10min 47s, sys: 16.3 s, total: 2h 11min 3s\n", - "Wall time: 2h 18min 44s\n" - ] - } - ], - "source": [ - "%%time\n", - "# Variable to store the accuracies of each random forest classifier with varying number of features\n", - "accuracies = []\n", - "# Number of features to perform a hyperparameter sweep\n", - "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each feature value\n", - "num_trials = 10\n", - "\n", - "feature_dataObj = pd.DataFrame()\n", - "feature_list = []\n", - "accuracy_scores = []\n", - "\n", - "for feature in features:\n", - " print(feature)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " feature_list.append(feature)\n", - " \n", - "feature_dataObj['Feature List'] = feature_list\n", - "feature_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Feature List Accuracy\n", - "0 4 0.845\n", - "1 4 0.845\n", - "2 4 0.845\n", - "3 4 0.837\n", - "4 4 0.846\n", - ".. ... ...\n", - "195 776 0.786\n", - "196 776 0.791\n", - "197 776 0.794\n", - "198 776 0.798\n", - "199 776 0.795\n", - "\n", - "[200 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import seaborn as sns\n", - "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", - "# plt.title('Varying Max_Features for MNIST Data')\n", - "plt.xlabel('Number of Features',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(feature_dataObj)\n", - "# save the figure to the current working directory\n", - "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section Four: Tuning maximum depth of trees.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "6\n", - "9\n", - "13\n", - "21\n", - "32\n", - "48\n", - "73\n", - "111\n", - "168\n", - "CPU times: user 25min 47s, sys: 10 s, total: 25min 57s\n", - "Wall time: 28min 4s\n" - ] - } - ], - "source": [ - "%%time\n", - "# Variable to store the accuracies of each random forest classifier with varying number of features\n", - "accuracies = []\n", - "# Number of depths to perform a hyperparameter sweep\n", - "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each depth value\n", - "num_trials = 10\n", - "\n", - "depth_dataObj = pd.DataFrame()\n", - "depth_list = []\n", - "accuracy_scores = []\n", - "\n", - "for depth in depths:\n", - " print(depth)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " depth_list.append(depth)\n", - " \n", - "depth_dataObj['Depth List'] = depth_list\n", - "depth_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Depth List Accuracy\n", - "0 4 0.824\n", - "1 4 0.806\n", - "2 4 0.810\n", - "3 4 0.812\n", - "4 4 0.816\n", - ".. ... ...\n", - "95 168 0.956\n", - "96 168 0.958\n", - "97 168 0.957\n", - "98 168 0.955\n", - "99 168 0.958\n", - "\n", - "[100 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", - "plt.xlabel('Max Depth',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(depth_dataObj)\n", - "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section Five: Grid Search Tuning\n", - "
\n" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", - "Wall time: 12h 1min 47s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_depth': 21, 'max_features': 21}" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import GridSearchCV\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "# Perform Grid Search Tuning\n", - "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=21, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "Section Six: Random Search Tuning.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", - "Wall time: 7h 38min 25s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_features': 21, 'max_depth': 111}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import RandomizedSearchCV\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "import numpy as np\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", - " cv = 3, random_state=42)\n", - "\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=111, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "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.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 70d72da4a5c87a353deb3ab999f329ca28b5b16e Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Sun, 15 Dec 2019 09:45:37 -0500 Subject: [PATCH 05/14] edited according to TA input - removed "code cells that are rendered not as cells" for clarity - moved the results section to the end of code --- .../Tuning_Tutorial_Edit1.ipynb | 117 ++++-------------- 1 file changed, 26 insertions(+), 91 deletions(-) diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb index db302b24c9979..d78143af8f40e 100644 --- a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb +++ b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb @@ -18,100 +18,16 @@ "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", "\n", "# Hyperparameter Tuning Methods\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import GridSearchCV\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. GridSearchCV\n", - "\n", - "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", "\n", - "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import GridSearchCV\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. RandomizedSearchCV\n", - "\n", - "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n", + " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", + " \n", + " 1. GridSearchCV\n", "\n", - "> Below is the grid of all possible parameter combinations that are supplied to the Random Forest model. Only two parmeters, max_features and the max_depth of the random forest model, is tweaked. There are 100 possible combinations of these combinations. Of the 100 possible combinations, this sample code below in the tutorial selects 50." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```Python\n", - "from sklearn.model_selection import RandomizedSearchCV\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", - " cv = 3, random_state=42)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Results " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "|Models |Performance | Best Params | Computation Time |\n", - "|---------------|--------------|----------------------------------|----------------------------|\n", - "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", - "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", - "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", + "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", "\n", + " 2. RandomizedSearchCV\n", "\n", - "\n", - "" + "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" ] }, { @@ -132,7 +48,8 @@ " 4. Tuning the depths of the trees\n", " 5. Grid Search Tuning \n", " 6. Random Search Tuning\n", - " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously" + " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously\n", + " 8. Summary of Results" ] }, { @@ -1189,6 +1106,24 @@ "ax = sns.heatmap(df,linewidths=.5)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Summary of Results\n", + "\n", + "|Models |Performance | Best Params | Computation Time |\n", + "|---------------|--------------|----------------------------------|----------------------------|\n", + "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", + "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", + "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, { "cell_type": "code", "execution_count": null, From 5bfc6db6b337bdcfbb4d844e8e5c3b6560e33870 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Sun, 15 Dec 2019 09:46:13 -0500 Subject: [PATCH 06/14] heatmap of hyperparameter tuning tutorial --- Heatmap.png | Bin 0 -> 70538 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Heatmap.png diff --git a/Heatmap.png b/Heatmap.png new file mode 100644 index 0000000000000000000000000000000000000000..7298fb4dde9305ad54011fa5f41f6ca74fd446b4 GIT binary patch literal 70538 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 B@N@tG literal 0 HcmV?d00001 From 21265a82854b17a8bd28e0219cf709db216b5aa7 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:24:05 -0500 Subject: [PATCH 07/14] Delete Tuning_Tutorial_Edit1.ipynb --- .../Tuning_Tutorial_Edit1.ipynb | 1156 ----------------- 1 file changed, 1156 deletions(-) delete mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb deleted file mode 100644 index d78143af8f40e..0000000000000 --- a/doc/tutorial/hyperparameter_tuning_random_forest/Tuning_Tutorial_Edit1.ipynb +++ /dev/null @@ -1,1156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Parameter Tuning Tutorial \n", - "\n", - " Objective: \n", - "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", - "\n", - " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", - "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", - "1. Random sampling of training data points when building trees\n", - "2. Random subsets of features considered when splitting nodes\n", - "\n", - "**The Dataset**\n", - "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", - "\n", - "# Hyperparameter Tuning Methods\n", - "\n", - " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", - " \n", - " 1. GridSearchCV\n", - "\n", - "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", - "\n", - " 2. RandomizedSearchCV\n", - "\n", - "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Code \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Code is structured in the following order.\n", - " 1. Loading and Preprocessing Data \n", - " 2. Building Base Random Forest Model \n", - " 3. Tuning the number of features\n", - " 4. Tuning the depths of the trees\n", - " 5. Grid Search Tuning \n", - " 6. Random Search Tuning\n", - " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously\n", - " 8. Summary of Results" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.datasets import fetch_openml\n", - "# Load data from https://www.openml.org/d/554\n", - "from PIL import Image, ImageDraw\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import seaborn as sns" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section One: Loading and Preprocessing Data\n", - "\n", - "There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(70000, 784)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Load the dataset\n", - "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", - "\n", - "# Check dimensions of the data\n", - "images.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "label: 9\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# Pick the fifth image from the dataset (it's a 9)\n", - "i = 4\n", - "image, label = images[i], labels[i]\n", - "\n", - "# Print the image\n", - "output = Image.new(\"L\", (28, 28))\n", - "output.putdata(image)\n", - "print('label:',label)\n", - "plt.imshow(np.asarray(output))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Train samples: 10000\n", - "Test samples: 1000\n" - ] - } - ], - "source": [ - "# Splitting the data into training and testing samples\n", - "from sklearn.model_selection import train_test_split\n", - "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", - " test_size = 1000, random_state = 42)\n", - "print('Train samples:', images_train.shape[0])\n", - "print('Test samples:', images_test.shape[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# Feature Scaling\n", - "from sklearn.preprocessing import StandardScaler\n", - "scaler = StandardScaler()\n", - "images_train = scaler.fit_transform(images_train)\n", - "images_test = scaler.transform(images_test)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Two: Create and evaluate base Random Forest model with 500 estimators." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.954\n", - "[0.91133005 0.89108911 0.90049751 0.89393939 0.87755102]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n", - "CPU times: user 25.3 s, sys: 258 ms, total: 25.6 s\n", - "Wall time: 25.7 s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Three: Tuning number of features." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "6\n", - "9\n", - "12\n", - "16\n", - "21\n", - "27\n", - "36\n", - "48\n", - "64\n", - "84\n", - "111\n", - "147\n", - "194\n", - "256\n", - "337\n", - "445\n", - "588\n", - "776\n", - "CPU times: user 5h 9min 11s, sys: 2min 52s, total: 5h 12min 3s\n", - "Wall time: 35min 29s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "\n", - "# Variable to store the accuracies of each random forest classifier with varying number of features\n", - "accuracies = []\n", - "# Number of features to perform a hyperparameter sweep\n", - "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each feature value\n", - "num_trials = 10\n", - "\n", - "feature_dataObj = pd.DataFrame()\n", - "feature_list = []\n", - "accuracy_scores = []\n", - "\n", - "for feature in features:\n", - " print(feature)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5, n_jobs = -2)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " feature_list.append(feature)\n", - " \n", - "feature_dataObj['Feature List'] = feature_list\n", - "feature_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Feature List Accuracy\n", - "0 4 0.845\n", - "1 4 0.844\n", - "2 4 0.839\n", - "3 4 0.838\n", - "4 4 0.838\n", - ".. ... ...\n", - "195 776 0.793\n", - "196 776 0.792\n", - "197 776 0.794\n", - "198 776 0.794\n", - "199 776 0.788\n", - "\n", - "[200 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import seaborn as sns\n", - "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", - "# plt.title('Varying Max_Features for MNIST Data')\n", - "plt.xlabel('Number of Features',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(feature_dataObj)\n", - "# save the figure to the current working directory\n", - "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Four: Tuning maximum depth of trees." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "6\n", - "9\n", - "13\n", - "21\n", - "32\n", - "48\n", - "73\n", - "111\n", - "168\n", - "CPU times: user 25min 45s, sys: 11 s, total: 25min 56s\n", - "Wall time: 25min 59s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "\n", - "# Variable to store the accuracies of each random forest classifier with varying number of depths\n", - "accuracies = []\n", - "# Number of depths to perform a hyperparameter sweep\n", - "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each depth value\n", - "num_trials = 10\n", - "\n", - "depth_dataObj = pd.DataFrame()\n", - "depth_list = []\n", - "accuracy_scores = []\n", - "\n", - "for depth in depths:\n", - " print(depth)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " depth_list.append(depth)\n", - " \n", - "depth_dataObj['Depth List'] = depth_list\n", - "depth_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Depth List Accuracy\n", - "0 4 0.812\n", - "1 4 0.812\n", - "2 4 0.814\n", - "3 4 0.808\n", - "4 4 0.818\n", - ".. ... ...\n", - "95 168 0.954\n", - "96 168 0.959\n", - "97 168 0.959\n", - "98 168 0.959\n", - "99 168 0.957\n", - "\n", - "[100 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", - "plt.xlabel('Max Depth',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(depth_dataObj)\n", - "plt.xscale('log')\n", - "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Five: Grid Search Tuning" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", - "Wall time: 12h 1min 47s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_depth': 21, 'max_features': 21}" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import GridSearchCV\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "# Perform Grid Search Tuning\n", - "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=21, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Six: Random Search Tuning." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", - "Wall time: 7h 38min 25s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_features': 21, 'max_depth': 111}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import RandomizedSearchCV\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "import numpy as np\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", - " cv = 3, random_state=42)\n", - "\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=111, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predficted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Seven: Heat Map" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'n_depth': 4, 'n_features': 4}\n", - "0.814\n", - "trial score: 0.814\n", - "{'n_depth': 4, 'n_features': 6}\n", - "0.824\n", - "trial score: 0.824\n", - "{'n_depth': 4, 'n_features': 12}\n", - "0.82\n", - "trial score: 0.82\n", - "{'n_depth': 4, 'n_features': 21}\n", - "0.821\n", - "trial score: 0.821\n", - "{'n_depth': 4, 'n_features': 36}\n", - "0.809\n", - "trial score: 0.809\n", - "{'n_depth': 4, 'n_features': 64}\n", - "0.809\n", - "trial score: 0.809\n", - "{'n_depth': 4, 'n_features': 111}\n", - "0.797\n", - "trial score: 0.797\n", - "{'n_depth': 4, 'n_features': 194}\n", - "0.79\n", - "trial score: 0.79\n", - "{'n_depth': 4, 'n_features': 337}\n", - "0.768\n", - "trial score: 0.768\n", - "{'n_depth': 4, 'n_features': 588}\n", - "0.733\n", - "trial score: 0.733\n", - "{'n_depth': 6, 'n_features': 4}\n", - "0.859\n", - "trial score: 0.859\n", - "{'n_depth': 6, 'n_features': 6}\n", - "0.87\n", - "trial score: 0.87\n", - "{'n_depth': 6, 'n_features': 12}\n", - "0.882\n", - "trial score: 0.882\n", - "{'n_depth': 6, 'n_features': 21}\n", - "0.89\n", - "trial score: 0.89\n", - "{'n_depth': 6, 'n_features': 36}\n", - "0.894\n", - "trial score: 0.894\n", - "{'n_depth': 6, 'n_features': 64}\n", - "0.891\n", - "trial score: 0.891\n", - "{'n_depth': 6, 'n_features': 111}\n", - "0.89\n", - "trial score: 0.89\n", - "{'n_depth': 6, 'n_features': 194}\n", - "0.887\n", - "trial score: 0.887\n", - "{'n_depth': 6, 'n_features': 337}\n", - "0.876\n", - "trial score: 0.876\n", - "{'n_depth': 6, 'n_features': 588}\n", - "0.855\n", - "trial score: 0.855\n", - "{'n_depth': 9, 'n_features': 4}\n", - "0.905\n", - "trial score: 0.905\n", - "{'n_depth': 9, 'n_features': 6}\n", - "0.917\n", - "trial score: 0.917\n", - "{'n_depth': 9, 'n_features': 12}\n", - "0.928\n", - "trial score: 0.928\n", - "{'n_depth': 9, 'n_features': 21}\n", - "0.938\n", - "trial score: 0.938\n", - "{'n_depth': 9, 'n_features': 36}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 9, 'n_features': 64}\n", - "0.941\n", - "trial score: 0.941\n", - "{'n_depth': 9, 'n_features': 111}\n", - "0.939\n", - "trial score: 0.939\n", - "{'n_depth': 9, 'n_features': 194}\n", - "0.938\n", - "trial score: 0.938\n", - "{'n_depth': 9, 'n_features': 337}\n", - "0.935\n", - "trial score: 0.935\n", - "{'n_depth': 9, 'n_features': 588}\n", - "0.925\n", - "trial score: 0.925\n", - "{'n_depth': 13, 'n_features': 4}\n", - "0.936\n", - "trial score: 0.936\n", - "{'n_depth': 13, 'n_features': 6}\n", - "0.943\n", - "trial score: 0.943\n", - "{'n_depth': 13, 'n_features': 12}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 21}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 36}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 64}\n", - "0.954\n", - "trial score: 0.954\n", - "{'n_depth': 13, 'n_features': 111}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 13, 'n_features': 194}\n", - "0.949\n", - "trial score: 0.949\n", - "{'n_depth': 13, 'n_features': 337}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 13, 'n_features': 588}\n", - "0.942\n", - "trial score: 0.942\n", - "{'n_depth': 21, 'n_features': 4}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 21, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 21, 'n_features': 12}\n", - "0.955\n", - "trial score: 0.955\n", - "{'n_depth': 21, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 21, 'n_features': 36}\n", - "0.96\n", - "trial score: 0.96\n", - "{'n_depth': 21, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 21, 'n_features': 111}\n", - "0.954\n", - "trial score: 0.954\n", - "{'n_depth': 21, 'n_features': 194}\n", - "0.951\n", - "trial score: 0.951\n", - "{'n_depth': 21, 'n_features': 337}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 21, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 32, 'n_features': 4}\n", - "0.946\n", - "trial score: 0.946\n", - "{'n_depth': 32, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 32, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 32, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 32, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 32, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 32, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 32, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 32, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 32, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 48, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 48, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 48, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 48, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 48, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 48, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 48, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 48, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 48, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 48, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 73, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 73, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 73, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 73, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 73, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 73, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 73, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 73, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 73, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 73, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 111, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 111, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 111, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 111, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 111, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 111, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 111, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 111, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 111, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 111, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 168, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 168, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 168, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 168, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 168, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 168, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 168, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 168, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 168, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 168, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.model_selection import ParameterGrid\n", - "from sklearn.metrics import accuracy_score\n", - "import numpy as np\n", - "\n", - "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", - "depth = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "grid = {'n_features': features, 'n_depth': depth}\n", - "param_combo = []\n", - "acc_scores = []\n", - "\n", - "list_features = []\n", - "list_depths = []\n", - "\n", - "num_trials = 1\n", - "trial_score = 0\n", - "for count, params in enumerate(ParameterGrid(grid)):\n", - " print(params)\n", - " for t in range(num_trials):\n", - "\n", - " # Obtain similarity matrix from USPORF classifier\n", - " clf = RandomForestClassifier(n_estimators = 500,\n", - " max_features = params['n_features'],\n", - " max_depth = params['n_depth'],\n", - " random_state=42,\n", - " n_jobs = -2)\n", - "\n", - " clf.fit(images_train, labels_train)\n", - " \n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " print(score)\n", - "\n", - " # Save tree information and associated ARI score\n", - " param_combo.append(params)\n", - " trial_score += score\n", - " list_depths.append(params['n_depth'])\n", - " list_features.append(params['n_features'])\n", - " \n", - " print('trial score:',trial_score/num_trials)\n", - " acc_scores.append(trial_score/num_trials)\n", - " trial_score = 0" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", - "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "data = {'Depth':list_depths, 'Features':list_features, 'Accuracy': acc_scores}\n", - "df = pd.DataFrame(data) \n", - "df = df.pivot(\"Depth\", \"Features\", \"Accuracy\")\n", - "ax = sns.heatmap(df,linewidths=.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Summary of Results\n", - "\n", - "|Models |Performance | Best Params | Computation Time |\n", - "|---------------|--------------|----------------------------------|----------------------------|\n", - "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", - "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", - "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", - "\n", - "\n", - "\n", - "\n", - "" - ] - }, - { - "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.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 6a25f0d558c92ee7892b5636a2d0c87fbb346240 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:24:37 -0500 Subject: [PATCH 08/14] changed filename and fixed typo 1-->2 --- .../hyperparameter_tuning_random_forest.ipynb | 1156 +++++++++++++++++ 1 file changed, 1156 insertions(+) create mode 100644 doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb new file mode 100644 index 0000000000000..d78143af8f40e --- /dev/null +++ b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb @@ -0,0 +1,1156 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameter Tuning Tutorial \n", + "\n", + " Objective: \n", + "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", + "\n", + " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", + "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", + "1. Random sampling of training data points when building trees\n", + "2. Random subsets of features considered when splitting nodes\n", + "\n", + "**The Dataset**\n", + "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", + "\n", + "# Hyperparameter Tuning Methods\n", + "\n", + " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", + " \n", + " 1. GridSearchCV\n", + "\n", + "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", + "\n", + " 2. RandomizedSearchCV\n", + "\n", + "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Code \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Code is structured in the following order.\n", + " 1. Loading and Preprocessing Data \n", + " 2. Building Base Random Forest Model \n", + " 3. Tuning the number of features\n", + " 4. Tuning the depths of the trees\n", + " 5. Grid Search Tuning \n", + " 6. Random Search Tuning\n", + " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously\n", + " 8. Summary of Results" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import fetch_openml\n", + "# Load data from https://www.openml.org/d/554\n", + "from PIL import Image, ImageDraw\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section One: Loading and Preprocessing Data\n", + "\n", + "There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(70000, 784)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the dataset\n", + "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", + "\n", + "# Check dimensions of the data\n", + "images.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "label: 9\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Pick the fifth image from the dataset (it's a 9)\n", + "i = 4\n", + "image, label = images[i], labels[i]\n", + "\n", + "# Print the image\n", + "output = Image.new(\"L\", (28, 28))\n", + "output.putdata(image)\n", + "print('label:',label)\n", + "plt.imshow(np.asarray(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train samples: 10000\n", + "Test samples: 1000\n" + ] + } + ], + "source": [ + "# Splitting the data into training and testing samples\n", + "from sklearn.model_selection import train_test_split\n", + "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", + " test_size = 1000, random_state = 42)\n", + "print('Train samples:', images_train.shape[0])\n", + "print('Test samples:', images_test.shape[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Feature Scaling\n", + "from sklearn.preprocessing import StandardScaler\n", + "scaler = StandardScaler()\n", + "images_train = scaler.fit_transform(images_train)\n", + "images_test = scaler.transform(images_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Two: Create and evaluate base Random Forest model with 500 estimators." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.954\n", + "[0.91133005 0.89108911 0.90049751 0.89393939 0.87755102]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n", + "CPU times: user 25.3 s, sys: 258 ms, total: 25.6 s\n", + "Wall time: 25.7 s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Three: Tuning number of features." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "5\n", + "6\n", + "9\n", + "12\n", + "16\n", + "21\n", + "27\n", + "36\n", + "48\n", + "64\n", + "84\n", + "111\n", + "147\n", + "194\n", + "256\n", + "337\n", + "445\n", + "588\n", + "776\n", + "CPU times: user 5h 9min 11s, sys: 2min 52s, total: 5h 12min 3s\n", + "Wall time: 35min 29s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of features\n", + "accuracies = []\n", + "# Number of features to perform a hyperparameter sweep\n", + "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each feature value\n", + "num_trials = 10\n", + "\n", + "feature_dataObj = pd.DataFrame()\n", + "feature_list = []\n", + "accuracy_scores = []\n", + "\n", + "for feature in features:\n", + " print(feature)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5, n_jobs = -2)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " feature_list.append(feature)\n", + " \n", + "feature_dataObj['Feature List'] = feature_list\n", + "feature_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Feature List Accuracy\n", + "0 4 0.845\n", + "1 4 0.844\n", + "2 4 0.839\n", + "3 4 0.838\n", + "4 4 0.838\n", + ".. ... ...\n", + "195 776 0.793\n", + "196 776 0.792\n", + "197 776 0.794\n", + "198 776 0.794\n", + "199 776 0.788\n", + "\n", + "[200 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import seaborn as sns\n", + "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", + "# plt.title('Varying Max_Features for MNIST Data')\n", + "plt.xlabel('Number of Features',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(feature_dataObj)\n", + "# save the figure to the current working directory\n", + "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Four: Tuning maximum depth of trees." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "6\n", + "9\n", + "13\n", + "21\n", + "32\n", + "48\n", + "73\n", + "111\n", + "168\n", + "CPU times: user 25min 45s, sys: 11 s, total: 25min 56s\n", + "Wall time: 25min 59s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of depths\n", + "accuracies = []\n", + "# Number of depths to perform a hyperparameter sweep\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each depth value\n", + "num_trials = 10\n", + "\n", + "depth_dataObj = pd.DataFrame()\n", + "depth_list = []\n", + "accuracy_scores = []\n", + "\n", + "for depth in depths:\n", + " print(depth)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " depth_list.append(depth)\n", + " \n", + "depth_dataObj['Depth List'] = depth_list\n", + "depth_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Depth List Accuracy\n", + "0 4 0.812\n", + "1 4 0.812\n", + "2 4 0.814\n", + "3 4 0.808\n", + "4 4 0.818\n", + ".. ... ...\n", + "95 168 0.954\n", + "96 168 0.959\n", + "97 168 0.959\n", + "98 168 0.959\n", + "99 168 0.957\n", + "\n", + "[100 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", + "plt.xlabel('Max Depth',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(depth_dataObj)\n", + "plt.xscale('log')\n", + "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Five: Grid Search Tuning" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", + "Wall time: 12h 1min 47s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_depth': 21, 'max_features': 21}" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "# Perform Grid Search Tuning\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=21, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Six: Random Search Tuning." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", + "Wall time: 7h 38min 25s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_features': 21, 'max_depth': 111}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "import numpy as np\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=111, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predficted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Seven: Heat Map" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'n_depth': 4, 'n_features': 4}\n", + "0.814\n", + "trial score: 0.814\n", + "{'n_depth': 4, 'n_features': 6}\n", + "0.824\n", + "trial score: 0.824\n", + "{'n_depth': 4, 'n_features': 12}\n", + "0.82\n", + "trial score: 0.82\n", + "{'n_depth': 4, 'n_features': 21}\n", + "0.821\n", + "trial score: 0.821\n", + "{'n_depth': 4, 'n_features': 36}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 64}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 111}\n", + "0.797\n", + "trial score: 0.797\n", + "{'n_depth': 4, 'n_features': 194}\n", + "0.79\n", + "trial score: 0.79\n", + "{'n_depth': 4, 'n_features': 337}\n", + "0.768\n", + "trial score: 0.768\n", + "{'n_depth': 4, 'n_features': 588}\n", + "0.733\n", + "trial score: 0.733\n", + "{'n_depth': 6, 'n_features': 4}\n", + "0.859\n", + "trial score: 0.859\n", + "{'n_depth': 6, 'n_features': 6}\n", + "0.87\n", + "trial score: 0.87\n", + "{'n_depth': 6, 'n_features': 12}\n", + "0.882\n", + "trial score: 0.882\n", + "{'n_depth': 6, 'n_features': 21}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 36}\n", + "0.894\n", + "trial score: 0.894\n", + "{'n_depth': 6, 'n_features': 64}\n", + "0.891\n", + "trial score: 0.891\n", + "{'n_depth': 6, 'n_features': 111}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 194}\n", + "0.887\n", + "trial score: 0.887\n", + "{'n_depth': 6, 'n_features': 337}\n", + "0.876\n", + "trial score: 0.876\n", + "{'n_depth': 6, 'n_features': 588}\n", + "0.855\n", + "trial score: 0.855\n", + "{'n_depth': 9, 'n_features': 4}\n", + "0.905\n", + "trial score: 0.905\n", + "{'n_depth': 9, 'n_features': 6}\n", + "0.917\n", + "trial score: 0.917\n", + "{'n_depth': 9, 'n_features': 12}\n", + "0.928\n", + "trial score: 0.928\n", + "{'n_depth': 9, 'n_features': 21}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 36}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 9, 'n_features': 64}\n", + "0.941\n", + "trial score: 0.941\n", + "{'n_depth': 9, 'n_features': 111}\n", + "0.939\n", + "trial score: 0.939\n", + "{'n_depth': 9, 'n_features': 194}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 337}\n", + "0.935\n", + "trial score: 0.935\n", + "{'n_depth': 9, 'n_features': 588}\n", + "0.925\n", + "trial score: 0.925\n", + "{'n_depth': 13, 'n_features': 4}\n", + "0.936\n", + "trial score: 0.936\n", + "{'n_depth': 13, 'n_features': 6}\n", + "0.943\n", + "trial score: 0.943\n", + "{'n_depth': 13, 'n_features': 12}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 21}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 36}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 64}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 13, 'n_features': 111}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 13, 'n_features': 194}\n", + "0.949\n", + "trial score: 0.949\n", + "{'n_depth': 13, 'n_features': 337}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 13, 'n_features': 588}\n", + "0.942\n", + "trial score: 0.942\n", + "{'n_depth': 21, 'n_features': 4}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 21, 'n_features': 12}\n", + "0.955\n", + "trial score: 0.955\n", + "{'n_depth': 21, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 21, 'n_features': 36}\n", + "0.96\n", + "trial score: 0.96\n", + "{'n_depth': 21, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 21, 'n_features': 111}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 21, 'n_features': 194}\n", + "0.951\n", + "trial score: 0.951\n", + "{'n_depth': 21, 'n_features': 337}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 32, 'n_features': 4}\n", + "0.946\n", + "trial score: 0.946\n", + "{'n_depth': 32, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 32, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 32, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 32, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 32, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 32, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 32, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 48, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 48, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 48, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 48, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 48, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 48, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 48, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 48, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 73, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 73, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 73, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 73, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 73, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 73, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 73, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 73, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 111, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 111, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 111, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 111, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 111, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 111, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 111, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 111, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 168, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 168, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 168, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 168, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 168, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 168, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 168, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 168, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.model_selection import ParameterGrid\n", + "from sklearn.metrics import accuracy_score\n", + "import numpy as np\n", + "\n", + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depth = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "grid = {'n_features': features, 'n_depth': depth}\n", + "param_combo = []\n", + "acc_scores = []\n", + "\n", + "list_features = []\n", + "list_depths = []\n", + "\n", + "num_trials = 1\n", + "trial_score = 0\n", + "for count, params in enumerate(ParameterGrid(grid)):\n", + " print(params)\n", + " for t in range(num_trials):\n", + "\n", + " # Obtain similarity matrix from USPORF classifier\n", + " clf = RandomForestClassifier(n_estimators = 500,\n", + " max_features = params['n_features'],\n", + " max_depth = params['n_depth'],\n", + " random_state=42,\n", + " n_jobs = -2)\n", + "\n", + " clf.fit(images_train, labels_train)\n", + " \n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " print(score)\n", + "\n", + " # Save tree information and associated ARI score\n", + " param_combo.append(params)\n", + " trial_score += score\n", + " list_depths.append(params['n_depth'])\n", + " list_features.append(params['n_features'])\n", + " \n", + " print('trial score:',trial_score/num_trials)\n", + " acc_scores.append(trial_score/num_trials)\n", + " trial_score = 0" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "data = {'Depth':list_depths, 'Features':list_features, 'Accuracy': acc_scores}\n", + "df = pd.DataFrame(data) \n", + "df = df.pivot(\"Depth\", \"Features\", \"Accuracy\")\n", + "ax = sns.heatmap(df,linewidths=.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Summary of Results\n", + "\n", + "|Models |Performance | Best Params | Computation Time |\n", + "|---------------|--------------|----------------------------------|----------------------------|\n", + "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", + "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", + "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 3aabf3cc02da233176f1df5d7373e4fad3e7edd4 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:27:07 -0500 Subject: [PATCH 09/14] typo changed --- hyperparameter_tuning_random_forest.ipynb | 1156 +++++++++++++++++++++ 1 file changed, 1156 insertions(+) create mode 100644 hyperparameter_tuning_random_forest.ipynb diff --git a/hyperparameter_tuning_random_forest.ipynb b/hyperparameter_tuning_random_forest.ipynb new file mode 100644 index 0000000000000..67e0249e3e03d --- /dev/null +++ b/hyperparameter_tuning_random_forest.ipynb @@ -0,0 +1,1156 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameter Tuning Tutorial \n", + "\n", + " Objective: \n", + "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", + "\n", + " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", + "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", + "1. Random sampling of training data points when building trees\n", + "2. Random subsets of features considered when splitting nodes\n", + "\n", + "**The Dataset**\n", + "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", + "\n", + "# Hyperparameter Tuning Methods\n", + "\n", + " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", + " \n", + " 1. GridSearchCV\n", + "\n", + "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", + "\n", + " 2. RandomizedSearchCV\n", + "\n", + "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Code \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Code is structured in the following order.\n", + " 1. Loading and Preprocessing Data \n", + " 2. Building Base Random Forest Model \n", + " 3. Tuning the number of features\n", + " 4. Tuning the depths of the trees\n", + " 5. Grid Search Tuning \n", + " 6. Random Search Tuning\n", + " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously\n", + " 8. Summary of Results" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import fetch_openml\n", + "# Load data from https://www.openml.org/d/554\n", + "from PIL import Image, ImageDraw\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section One: Loading and Preprocessing Data\n", + "\n", + "There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(70000, 784)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the dataset\n", + "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", + "\n", + "# Check dimensions of the data\n", + "images.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "label: 9\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Pick the fifth image from the dataset (it's a 9)\n", + "i = 4\n", + "image, label = images[i], labels[i]\n", + "\n", + "# Print the image\n", + "output = Image.new(\"L\", (28, 28))\n", + "output.putdata(image)\n", + "print('label:',label)\n", + "plt.imshow(np.asarray(output))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train samples: 10000\n", + "Test samples: 1000\n" + ] + } + ], + "source": [ + "# Splitting the data into training and testing samples\n", + "from sklearn.model_selection import train_test_split\n", + "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", + " test_size = 1000, random_state = 42)\n", + "print('Train samples:', images_train.shape[0])\n", + "print('Test samples:', images_test.shape[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Feature Scaling\n", + "from sklearn.preprocessing import StandardScaler\n", + "scaler = StandardScaler()\n", + "images_train = scaler.fit_transform(images_train)\n", + "images_test = scaler.transform(images_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Two: Create and evaluate base Random Forest model with 500 estimators." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.954\n", + "[0.91133005 0.89108911 0.90049751 0.89393939 0.87755102]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n", + "CPU times: user 25.3 s, sys: 258 ms, total: 25.6 s\n", + "Wall time: 25.7 s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Three: Tuning number of features." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "5\n", + "6\n", + "9\n", + "12\n", + "16\n", + "21\n", + "27\n", + "36\n", + "48\n", + "64\n", + "84\n", + "111\n", + "147\n", + "194\n", + "256\n", + "337\n", + "445\n", + "588\n", + "776\n", + "CPU times: user 5h 9min 11s, sys: 2min 52s, total: 5h 12min 3s\n", + "Wall time: 35min 29s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of features\n", + "accuracies = []\n", + "# Number of features to perform a hyperparameter sweep\n", + "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each feature value\n", + "num_trials = 10\n", + "\n", + "feature_dataObj = pd.DataFrame()\n", + "feature_list = []\n", + "accuracy_scores = []\n", + "\n", + "for feature in features:\n", + " print(feature)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5, n_jobs = -2)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " feature_list.append(feature)\n", + " \n", + "feature_dataObj['Feature List'] = feature_list\n", + "feature_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Feature List Accuracy\n", + "0 4 0.845\n", + "1 4 0.844\n", + "2 4 0.839\n", + "3 4 0.838\n", + "4 4 0.838\n", + ".. ... ...\n", + "195 776 0.793\n", + "196 776 0.792\n", + "197 776 0.794\n", + "198 776 0.794\n", + "199 776 0.788\n", + "\n", + "[200 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import seaborn as sns\n", + "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", + "# plt.title('Varying Max_Features for MNIST Data')\n", + "plt.xlabel('Number of Features',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(feature_dataObj)\n", + "# save the figure to the current working directory\n", + "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Four: Tuning maximum depth of trees." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "6\n", + "9\n", + "13\n", + "21\n", + "32\n", + "48\n", + "73\n", + "111\n", + "168\n", + "CPU times: user 25min 45s, sys: 11 s, total: 25min 56s\n", + "Wall time: 25min 59s\n" + ] + } + ], + "source": [ + "%%time\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "\n", + "# Variable to store the accuracies of each random forest classifier with varying number of depths\n", + "accuracies = []\n", + "# Number of depths to perform a hyperparameter sweep\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "\n", + "# Number of experiments to run for each depth value\n", + "num_trials = 10\n", + "\n", + "depth_dataObj = pd.DataFrame()\n", + "depth_list = []\n", + "accuracy_scores = []\n", + "\n", + "for depth in depths:\n", + " print(depth)\n", + " \n", + " for t in range(num_trials):\n", + " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", + " clf.fit(images_train, labels_train)\n", + "\n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " accuracy_scores.append(score)\n", + " depth_list.append(depth)\n", + " \n", + "depth_dataObj['Depth List'] = depth_list\n", + "depth_dataObj['Accuracy'] = accuracy_scores " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Depth List Accuracy\n", + "0 4 0.812\n", + "1 4 0.812\n", + "2 4 0.814\n", + "3 4 0.808\n", + "4 4 0.818\n", + ".. ... ...\n", + "95 168 0.954\n", + "96 168 0.959\n", + "97 168 0.959\n", + "98 168 0.959\n", + "99 168 0.957\n", + "\n", + "[100 rows x 2 columns]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", + "plt.xlabel('Max Depth',fontsize=14)\n", + "plt.ylabel('Classification Accuracy',fontsize=14)\n", + "print(depth_dataObj)\n", + "plt.xscale('log')\n", + "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Five: Grid Search Tuning" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", + "Wall time: 12h 1min 47s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_depth': 21, 'max_features': 21}" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "# Perform Grid Search Tuning\n", + "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=21, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Six: Random Search Tuning." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", + "Wall time: 7h 38min 25s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_features': 21, 'max_depth': 111}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "import numpy as np\n", + "\n", + "# Set up classifier\n", + "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", + "\n", + "# Set up combinations of paramters to tune\n", + "param_grid = { \n", + " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", + " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", + "}\n", + "\n", + "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", + " cv = 3, random_state=42)\n", + "\n", + "CV_clf.fit(images_train, labels_train)\n", + "\n", + "CV_clf.best_params_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", + " max_depth=111, max_features=21, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=500,\n", + " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", + " warm_start=False)\n", + "Accuracy: 0.957\n", + "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", + "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# Set up classifier and train classifer\n", + "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", + "print(clf)\n", + "clf.fit(images_train, labels_train)\n", + "\n", + "# Test classifier\n", + "predicted_labels = clf.predict(images_test)\n", + "\n", + "# Evaluate classifier\n", + "print(\"Accuracy: \", accuracy_score(labels_test, predficted_labels))\n", + "\n", + "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", + "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", + "print(scores)\n", + "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section Seven: Heat Map" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'n_depth': 4, 'n_features': 4}\n", + "0.814\n", + "trial score: 0.814\n", + "{'n_depth': 4, 'n_features': 6}\n", + "0.824\n", + "trial score: 0.824\n", + "{'n_depth': 4, 'n_features': 12}\n", + "0.82\n", + "trial score: 0.82\n", + "{'n_depth': 4, 'n_features': 21}\n", + "0.821\n", + "trial score: 0.821\n", + "{'n_depth': 4, 'n_features': 36}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 64}\n", + "0.809\n", + "trial score: 0.809\n", + "{'n_depth': 4, 'n_features': 111}\n", + "0.797\n", + "trial score: 0.797\n", + "{'n_depth': 4, 'n_features': 194}\n", + "0.79\n", + "trial score: 0.79\n", + "{'n_depth': 4, 'n_features': 337}\n", + "0.768\n", + "trial score: 0.768\n", + "{'n_depth': 4, 'n_features': 588}\n", + "0.733\n", + "trial score: 0.733\n", + "{'n_depth': 6, 'n_features': 4}\n", + "0.859\n", + "trial score: 0.859\n", + "{'n_depth': 6, 'n_features': 6}\n", + "0.87\n", + "trial score: 0.87\n", + "{'n_depth': 6, 'n_features': 12}\n", + "0.882\n", + "trial score: 0.882\n", + "{'n_depth': 6, 'n_features': 21}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 36}\n", + "0.894\n", + "trial score: 0.894\n", + "{'n_depth': 6, 'n_features': 64}\n", + "0.891\n", + "trial score: 0.891\n", + "{'n_depth': 6, 'n_features': 111}\n", + "0.89\n", + "trial score: 0.89\n", + "{'n_depth': 6, 'n_features': 194}\n", + "0.887\n", + "trial score: 0.887\n", + "{'n_depth': 6, 'n_features': 337}\n", + "0.876\n", + "trial score: 0.876\n", + "{'n_depth': 6, 'n_features': 588}\n", + "0.855\n", + "trial score: 0.855\n", + "{'n_depth': 9, 'n_features': 4}\n", + "0.905\n", + "trial score: 0.905\n", + "{'n_depth': 9, 'n_features': 6}\n", + "0.917\n", + "trial score: 0.917\n", + "{'n_depth': 9, 'n_features': 12}\n", + "0.928\n", + "trial score: 0.928\n", + "{'n_depth': 9, 'n_features': 21}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 36}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 9, 'n_features': 64}\n", + "0.941\n", + "trial score: 0.941\n", + "{'n_depth': 9, 'n_features': 111}\n", + "0.939\n", + "trial score: 0.939\n", + "{'n_depth': 9, 'n_features': 194}\n", + "0.938\n", + "trial score: 0.938\n", + "{'n_depth': 9, 'n_features': 337}\n", + "0.935\n", + "trial score: 0.935\n", + "{'n_depth': 9, 'n_features': 588}\n", + "0.925\n", + "trial score: 0.925\n", + "{'n_depth': 13, 'n_features': 4}\n", + "0.936\n", + "trial score: 0.936\n", + "{'n_depth': 13, 'n_features': 6}\n", + "0.943\n", + "trial score: 0.943\n", + "{'n_depth': 13, 'n_features': 12}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 21}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 36}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 13, 'n_features': 64}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 13, 'n_features': 111}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 13, 'n_features': 194}\n", + "0.949\n", + "trial score: 0.949\n", + "{'n_depth': 13, 'n_features': 337}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 13, 'n_features': 588}\n", + "0.942\n", + "trial score: 0.942\n", + "{'n_depth': 21, 'n_features': 4}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 21, 'n_features': 12}\n", + "0.955\n", + "trial score: 0.955\n", + "{'n_depth': 21, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 21, 'n_features': 36}\n", + "0.96\n", + "trial score: 0.96\n", + "{'n_depth': 21, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 21, 'n_features': 111}\n", + "0.954\n", + "trial score: 0.954\n", + "{'n_depth': 21, 'n_features': 194}\n", + "0.951\n", + "trial score: 0.951\n", + "{'n_depth': 21, 'n_features': 337}\n", + "0.944\n", + "trial score: 0.944\n", + "{'n_depth': 21, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 32, 'n_features': 4}\n", + "0.946\n", + "trial score: 0.946\n", + "{'n_depth': 32, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 32, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 32, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 32, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 32, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 32, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 32, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 32, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 48, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 48, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 48, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 48, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 48, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 48, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 48, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 48, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 48, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 73, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 73, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 73, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 73, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 73, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 73, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 73, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 73, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 73, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 111, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 111, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 111, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 111, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 111, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 111, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 111, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 111, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 111, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n", + "{'n_depth': 168, 'n_features': 4}\n", + "0.948\n", + "trial score: 0.948\n", + "{'n_depth': 168, 'n_features': 6}\n", + "0.947\n", + "trial score: 0.947\n", + "{'n_depth': 168, 'n_features': 12}\n", + "0.959\n", + "trial score: 0.959\n", + "{'n_depth': 168, 'n_features': 21}\n", + "0.957\n", + "trial score: 0.957\n", + "{'n_depth': 168, 'n_features': 36}\n", + "0.958\n", + "trial score: 0.958\n", + "{'n_depth': 168, 'n_features': 64}\n", + "0.956\n", + "trial score: 0.956\n", + "{'n_depth': 168, 'n_features': 111}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 194}\n", + "0.953\n", + "trial score: 0.953\n", + "{'n_depth': 168, 'n_features': 337}\n", + "0.95\n", + "trial score: 0.95\n", + "{'n_depth': 168, 'n_features': 588}\n", + "0.94\n", + "trial score: 0.94\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.model_selection import ParameterGrid\n", + "from sklearn.metrics import accuracy_score\n", + "import numpy as np\n", + "\n", + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depth = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "grid = {'n_features': features, 'n_depth': depth}\n", + "param_combo = []\n", + "acc_scores = []\n", + "\n", + "list_features = []\n", + "list_depths = []\n", + "\n", + "num_trials = 1\n", + "trial_score = 0\n", + "for count, params in enumerate(ParameterGrid(grid)):\n", + " print(params)\n", + " for t in range(num_trials):\n", + "\n", + " # Obtain similarity matrix from USPORF classifier\n", + " clf = RandomForestClassifier(n_estimators = 500,\n", + " max_features = params['n_features'],\n", + " max_depth = params['n_depth'],\n", + " random_state=42,\n", + " n_jobs = -2)\n", + "\n", + " clf.fit(images_train, labels_train)\n", + " \n", + " # Test classifier\n", + " predicted_labels = clf.predict(images_test)\n", + "\n", + " # Evaluate classifier\n", + " score = accuracy_score(labels_test, predicted_labels)\n", + " print(score)\n", + "\n", + " # Save tree information and associated ARI score\n", + " param_combo.append(params)\n", + " trial_score += score\n", + " list_depths.append(params['n_depth'])\n", + " list_features.append(params['n_features'])\n", + " \n", + " print('trial score:',trial_score/num_trials)\n", + " acc_scores.append(trial_score/num_trials)\n", + " trial_score = 0" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", + "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", + "data = {'Depth':list_depths, 'Features':list_features, 'Accuracy': acc_scores}\n", + "df = pd.DataFrame(data) \n", + "df = df.pivot(\"Depth\", \"Features\", \"Accuracy\")\n", + "ax = sns.heatmap(df,linewidths=.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Summary of Results\n", + "\n", + "|Models |Performance | Best Params | Computation Time |\n", + "|---------------|--------------|----------------------------------|----------------------------|\n", + "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", + "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", + "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From b963e9c1480db530ce8cfb287bd112a4ec48b875 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:28:50 -0500 Subject: [PATCH 10/14] spacing changes --- .../hyperparameter_tuning_random_forest.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb index d78143af8f40e..68a6ec601617e 100644 --- a/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb +++ b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb @@ -21,11 +21,11 @@ "\n", " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", " \n", - " 1. GridSearchCV\n", + "1. GridSearchCV\n", "\n", "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", "\n", - " 2. RandomizedSearchCV\n", + "2. RandomizedSearchCV\n", "\n", "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" ] From 6a4592e137fdcceb6ba41a7c2db13269aad64c42 Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:30:20 -0500 Subject: [PATCH 11/14] Add files via upload --- .../hyperparameter_tuning_random_forest.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb index 68a6ec601617e..90168de8e5ffa 100644 --- a/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb +++ b/doc/tutorial/hyperparameter_tuning_random_forest/hyperparameter_tuning_random_forest.ipynb @@ -21,11 +21,11 @@ "\n", " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", " \n", - "1. GridSearchCV\n", + "**GridSearchCV**\n", "\n", "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", "\n", - "2. RandomizedSearchCV\n", + "**RandomizedSearchCV**\n", "\n", "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" ] From 19a4f61263170e94172370ea263671edefac55fd Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 11:30:35 -0500 Subject: [PATCH 12/14] changed from numbering to bullets --- hyperparameter_tuning_random_forest.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyperparameter_tuning_random_forest.ipynb b/hyperparameter_tuning_random_forest.ipynb index 67e0249e3e03d..90168de8e5ffa 100644 --- a/hyperparameter_tuning_random_forest.ipynb +++ b/hyperparameter_tuning_random_forest.ipynb @@ -21,11 +21,11 @@ "\n", " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", " \n", - " 1. GridSearchCV\n", + "**GridSearchCV**\n", "\n", "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", "\n", - " 2. RandomizedSearchCV\n", + "**RandomizedSearchCV**\n", "\n", "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" ] From 344061a754da7e65bcec6c5bf8a6e3ad68c3ccee Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 17:16:26 -0500 Subject: [PATCH 13/14] Delete hyperparameter_tuning_random_forest.ipynb --- hyperparameter_tuning_random_forest.ipynb | 1156 --------------------- 1 file changed, 1156 deletions(-) delete mode 100644 hyperparameter_tuning_random_forest.ipynb diff --git a/hyperparameter_tuning_random_forest.ipynb b/hyperparameter_tuning_random_forest.ipynb deleted file mode 100644 index 90168de8e5ffa..0000000000000 --- a/hyperparameter_tuning_random_forest.ipynb +++ /dev/null @@ -1,1156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Parameter Tuning Tutorial \n", - "\n", - " Objective: \n", - "This tutorial covers how to perform hyperparameter tuning on a random forest model using sklearn's GridSearchCV and RandomSearchCV. \n", - "\n", - " **Brief Overview of Random Forests from** [TowardDataScience](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76): Click on hyperlink to learn more.\n", - "> A random forest is a model made up of many decision trees. Rather than just simply averaging the prediction of trees (which we could call a “forest”), this model uses two key concepts that gives it the name random:\n", - "1. Random sampling of training data points when building trees\n", - "2. Random subsets of features considered when splitting nodes\n", - "\n", - "**The Dataset**\n", - "The random forest model will be trained to recognize handwritten digits from the MNIST database. Each greyscale image is 28 x 28, representing the digits 0-9, and consists of 60,000 training images and 10,000 test images. To reduce computational time, this tutorial uses only a subset of the full dataset (10,000 train images and 1,000 test images). Assuming a Gaussian distribution for the MNIST dataset, the dataset is also standardized such that each feature has a mean of 0 and a standard deviation of 1.\n", - "\n", - "# Hyperparameter Tuning Methods\n", - "\n", - " The base random forest model which will be tuned is initialized with 500 estimators and a random state of 42. Using five-fold cross validation, this base model has an mean accuracy score of 0.89 with a standard deviation of 0.02. \n", - " \n", - "**GridSearchCV**\n", - "\n", - "This function allows you to run an exhaustive search on all of the possible parameters and parameter combinations as inputs to the Random Forest model and returns the parameters that gives the best performance. \n", - "\n", - "**RandomizedSearchCV**\n", - "\n", - "Instead of trying out an exhaustive list of parameters and parameter combinations like GridSearchCV, only a fixed number of parameter combinations is sampled from the full sample space containing all possible combinations of parameter settings. The number of parameter settings that are tried is given by n_iter. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Code \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Code is structured in the following order.\n", - " 1. Loading and Preprocessing Data \n", - " 2. Building Base Random Forest Model \n", - " 3. Tuning the number of features\n", - " 4. Tuning the depths of the trees\n", - " 5. Grid Search Tuning \n", - " 6. Random Search Tuning\n", - " 7. Heat Map of Classification Accuracy when tuning features and trees simultaneously\n", - " 8. Summary of Results" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.datasets import fetch_openml\n", - "# Load data from https://www.openml.org/d/554\n", - "from PIL import Image, ImageDraw\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import seaborn as sns" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section One: Loading and Preprocessing Data\n", - "\n", - "There are 70,000 images of handwritten digits in this dataset. Each 28x28 pixel image has been transformed into a 1D vector with 784 features.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(70000, 784)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Load the dataset\n", - "images, labels = fetch_openml('mnist_784', version=1, return_X_y=True)\n", - "\n", - "# Check dimensions of the data\n", - "images.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Visualize the data. Use PIL to reshape and create a new image object and matplotlib to visualize the numpy array.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "label: 9\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# Pick the fifth image from the dataset (it's a 9)\n", - "i = 4\n", - "image, label = images[i], labels[i]\n", - "\n", - "# Print the image\n", - "output = Image.new(\"L\", (28, 28))\n", - "output.putdata(image)\n", - "print('label:',label)\n", - "plt.imshow(np.asarray(output))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Split the data into training and testing samples. To reduce computational time, use only 10,000 samples for training and 1000 for testing.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Train samples: 10000\n", - "Test samples: 1000\n" - ] - } - ], - "source": [ - "# Splitting the data into training and testing samples\n", - "from sklearn.model_selection import train_test_split\n", - "images_train, images_test, labels_train, labels_test = train_test_split(images, labels, train_size = 10000,\n", - " test_size = 1000, random_state = 42)\n", - "print('Train samples:', images_train.shape[0])\n", - "print('Test samples:', images_test.shape[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Standardize the data such that each feature has a mean of 0 and a standard deviation of 1.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# Feature Scaling\n", - "from sklearn.preprocessing import StandardScaler\n", - "scaler = StandardScaler()\n", - "images_train = scaler.fit_transform(images_train)\n", - "images_test = scaler.transform(images_test)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Two: Create and evaluate base Random Forest model with 500 estimators." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Set up a random forest classifier with 500 trees, leaving other parameters as default parameters.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=None, max_features='auto', max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.954\n", - "[0.91133005 0.89108911 0.90049751 0.89393939 0.87755102]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n", - "CPU times: user 25.3 s, sys: 258 ms, total: 25.6 s\n", - "Wall time: 25.7 s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Three: Tuning number of features." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "5\n", - "6\n", - "9\n", - "12\n", - "16\n", - "21\n", - "27\n", - "36\n", - "48\n", - "64\n", - "84\n", - "111\n", - "147\n", - "194\n", - "256\n", - "337\n", - "445\n", - "588\n", - "776\n", - "CPU times: user 5h 9min 11s, sys: 2min 52s, total: 5h 12min 3s\n", - "Wall time: 35min 29s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "\n", - "# Variable to store the accuracies of each random forest classifier with varying number of features\n", - "accuracies = []\n", - "# Number of features to perform a hyperparameter sweep\n", - "features = np.logspace(2.0, 10.0, num=20, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each feature value\n", - "num_trials = 10\n", - "\n", - "feature_dataObj = pd.DataFrame()\n", - "feature_list = []\n", - "accuracy_scores = []\n", - "\n", - "for feature in features:\n", - " print(feature)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_features = feature, max_depth = 5, n_jobs = -2)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " feature_list.append(feature)\n", - " \n", - "feature_dataObj['Feature List'] = feature_list\n", - "feature_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Feature List Accuracy\n", - "0 4 0.845\n", - "1 4 0.844\n", - "2 4 0.839\n", - "3 4 0.838\n", - "4 4 0.838\n", - ".. ... ...\n", - "195 776 0.793\n", - "196 776 0.792\n", - "197 776 0.794\n", - "198 776 0.794\n", - "199 776 0.788\n", - "\n", - "[200 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import seaborn as sns\n", - "sns.lineplot(x='Feature List', y='Accuracy',data=feature_dataObj, marker='o')\n", - "# plt.title('Varying Max_Features for MNIST Data')\n", - "plt.xlabel('Number of Features',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(feature_dataObj)\n", - "# save the figure to the current working directory\n", - "plt.savefig('varying_features_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Four: Tuning maximum depth of trees." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "6\n", - "9\n", - "13\n", - "21\n", - "32\n", - "48\n", - "73\n", - "111\n", - "168\n", - "CPU times: user 25min 45s, sys: 11 s, total: 25min 56s\n", - "Wall time: 25min 59s\n" - ] - } - ], - "source": [ - "%%time\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "\n", - "# Variable to store the accuracies of each random forest classifier with varying number of depths\n", - "accuracies = []\n", - "# Number of depths to perform a hyperparameter sweep\n", - "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "\n", - "# Number of experiments to run for each depth value\n", - "num_trials = 10\n", - "\n", - "depth_dataObj = pd.DataFrame()\n", - "depth_list = []\n", - "accuracy_scores = []\n", - "\n", - "for depth in depths:\n", - " print(depth)\n", - " \n", - " for t in range(num_trials):\n", - " clf = RandomForestClassifier(n_estimators=500, max_depth = depth)\n", - " clf.fit(images_train, labels_train)\n", - "\n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " accuracy_scores.append(score)\n", - " depth_list.append(depth)\n", - " \n", - "depth_dataObj['Depth List'] = depth_list\n", - "depth_dataObj['Accuracy'] = accuracy_scores " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Depth List Accuracy\n", - "0 4 0.812\n", - "1 4 0.812\n", - "2 4 0.814\n", - "3 4 0.808\n", - "4 4 0.818\n", - ".. ... ...\n", - "95 168 0.954\n", - "96 168 0.959\n", - "97 168 0.959\n", - "98 168 0.959\n", - "99 168 0.957\n", - "\n", - "[100 rows x 2 columns]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "sns.lineplot(x='Depth List', y='Accuracy',data = depth_dataObj,marker='o')\n", - "plt.xlabel('Max Depth',fontsize=14)\n", - "plt.ylabel('Classification Accuracy',fontsize=14)\n", - "print(depth_dataObj)\n", - "plt.xscale('log')\n", - "plt.savefig('varying_depths_plot.png', dpi=300, bbox_inches='tight')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Five: Grid Search Tuning" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3h 54min 26s, sys: 1min 12s, total: 3h 55min 39s\n", - "Wall time: 12h 1min 47s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_depth': 21, 'max_features': 21}" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import GridSearchCV\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num = 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "# Perform Grid Search Tuning\n", - "CV_clf = GridSearchCV(estimator=clf, param_grid=param_grid, cv= 3)\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Evalulate the performance Random Forest classifier using the best combination of parameters found by GridSearchCV. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=21, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87878788 0.89285714]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.01)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 21, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predicted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Six: Random Search Tuning." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2h 19min 36s, sys: 29.2 s, total: 2h 20min 6s\n", - "Wall time: 7h 38min 25s\n" - ] - }, - { - "data": { - "text/plain": [ - "{'max_features': 21, 'max_depth': 111}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%time\n", - "from sklearn.model_selection import RandomizedSearchCV\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "import numpy as np\n", - "\n", - "# Set up classifier\n", - "clf = RandomForestClassifier(n_estimators = 500, random_state=42)\n", - "\n", - "# Set up combinations of paramters to tune\n", - "param_grid = { \n", - " 'max_features': np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int),\n", - " 'max_depth' : np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int),\n", - "}\n", - "\n", - "CV_clf = RandomizedSearchCV(estimator=clf, param_distributions=param_grid, n_iter = 50,\n", - " cv = 3, random_state=42)\n", - "\n", - "CV_clf.fit(images_train, labels_train)\n", - "\n", - "CV_clf.best_params_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Evalulate the performance Random Forest classifier using the best combination of parameters found by RandomizedSearchCV. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',\n", - " max_depth=111, max_features=21, max_leaf_nodes=None,\n", - " min_impurity_decrease=0.0, min_impurity_split=None,\n", - " min_samples_leaf=1, min_samples_split=2,\n", - " min_weight_fraction_leaf=0.0, n_estimators=500,\n", - " n_jobs=None, oob_score=False, random_state=42, verbose=0,\n", - " warm_start=False)\n", - "Accuracy: 0.957\n", - "[0.90147783 0.88613861 0.89054726 0.87373737 0.89795918]\n", - "Cross-Validation (CV=5) Accuracy: 0.89 (+/- 0.02)\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# Set up classifier and train classifer\n", - "clf = RandomForestClassifier(n_estimators=500, max_features = 21, max_depth = 111, random_state = 42)\n", - "print(clf)\n", - "clf.fit(images_train, labels_train)\n", - "\n", - "# Test classifier\n", - "predicted_labels = clf.predict(images_test)\n", - "\n", - "# Evaluate classifier\n", - "print(\"Accuracy: \", accuracy_score(labels_test, predficted_labels))\n", - "\n", - "# Using cross validation to evaluate performance. Compute mean score and 95% interval of score estimate\n", - "scores = cross_val_score(clf, images_test, labels_test, cv=5, scoring='accuracy')\n", - "print(scores)\n", - "print(\"Cross-Validation (CV=5) Accuracy: %0.2f (+/- %0.2f)\" % (scores.mean(), scores.std() * 2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section Seven: Heat Map" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'n_depth': 4, 'n_features': 4}\n", - "0.814\n", - "trial score: 0.814\n", - "{'n_depth': 4, 'n_features': 6}\n", - "0.824\n", - "trial score: 0.824\n", - "{'n_depth': 4, 'n_features': 12}\n", - "0.82\n", - "trial score: 0.82\n", - "{'n_depth': 4, 'n_features': 21}\n", - "0.821\n", - "trial score: 0.821\n", - "{'n_depth': 4, 'n_features': 36}\n", - "0.809\n", - "trial score: 0.809\n", - "{'n_depth': 4, 'n_features': 64}\n", - "0.809\n", - "trial score: 0.809\n", - "{'n_depth': 4, 'n_features': 111}\n", - "0.797\n", - "trial score: 0.797\n", - "{'n_depth': 4, 'n_features': 194}\n", - "0.79\n", - "trial score: 0.79\n", - "{'n_depth': 4, 'n_features': 337}\n", - "0.768\n", - "trial score: 0.768\n", - "{'n_depth': 4, 'n_features': 588}\n", - "0.733\n", - "trial score: 0.733\n", - "{'n_depth': 6, 'n_features': 4}\n", - "0.859\n", - "trial score: 0.859\n", - "{'n_depth': 6, 'n_features': 6}\n", - "0.87\n", - "trial score: 0.87\n", - "{'n_depth': 6, 'n_features': 12}\n", - "0.882\n", - "trial score: 0.882\n", - "{'n_depth': 6, 'n_features': 21}\n", - "0.89\n", - "trial score: 0.89\n", - "{'n_depth': 6, 'n_features': 36}\n", - "0.894\n", - "trial score: 0.894\n", - "{'n_depth': 6, 'n_features': 64}\n", - "0.891\n", - "trial score: 0.891\n", - "{'n_depth': 6, 'n_features': 111}\n", - "0.89\n", - "trial score: 0.89\n", - "{'n_depth': 6, 'n_features': 194}\n", - "0.887\n", - "trial score: 0.887\n", - "{'n_depth': 6, 'n_features': 337}\n", - "0.876\n", - "trial score: 0.876\n", - "{'n_depth': 6, 'n_features': 588}\n", - "0.855\n", - "trial score: 0.855\n", - "{'n_depth': 9, 'n_features': 4}\n", - "0.905\n", - "trial score: 0.905\n", - "{'n_depth': 9, 'n_features': 6}\n", - "0.917\n", - "trial score: 0.917\n", - "{'n_depth': 9, 'n_features': 12}\n", - "0.928\n", - "trial score: 0.928\n", - "{'n_depth': 9, 'n_features': 21}\n", - "0.938\n", - "trial score: 0.938\n", - "{'n_depth': 9, 'n_features': 36}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 9, 'n_features': 64}\n", - "0.941\n", - "trial score: 0.941\n", - "{'n_depth': 9, 'n_features': 111}\n", - "0.939\n", - "trial score: 0.939\n", - "{'n_depth': 9, 'n_features': 194}\n", - "0.938\n", - "trial score: 0.938\n", - "{'n_depth': 9, 'n_features': 337}\n", - "0.935\n", - "trial score: 0.935\n", - "{'n_depth': 9, 'n_features': 588}\n", - "0.925\n", - "trial score: 0.925\n", - "{'n_depth': 13, 'n_features': 4}\n", - "0.936\n", - "trial score: 0.936\n", - "{'n_depth': 13, 'n_features': 6}\n", - "0.943\n", - "trial score: 0.943\n", - "{'n_depth': 13, 'n_features': 12}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 21}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 36}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 13, 'n_features': 64}\n", - "0.954\n", - "trial score: 0.954\n", - "{'n_depth': 13, 'n_features': 111}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 13, 'n_features': 194}\n", - "0.949\n", - "trial score: 0.949\n", - "{'n_depth': 13, 'n_features': 337}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 13, 'n_features': 588}\n", - "0.942\n", - "trial score: 0.942\n", - "{'n_depth': 21, 'n_features': 4}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 21, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 21, 'n_features': 12}\n", - "0.955\n", - "trial score: 0.955\n", - "{'n_depth': 21, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 21, 'n_features': 36}\n", - "0.96\n", - "trial score: 0.96\n", - "{'n_depth': 21, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 21, 'n_features': 111}\n", - "0.954\n", - "trial score: 0.954\n", - "{'n_depth': 21, 'n_features': 194}\n", - "0.951\n", - "trial score: 0.951\n", - "{'n_depth': 21, 'n_features': 337}\n", - "0.944\n", - "trial score: 0.944\n", - "{'n_depth': 21, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 32, 'n_features': 4}\n", - "0.946\n", - "trial score: 0.946\n", - "{'n_depth': 32, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 32, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 32, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 32, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 32, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 32, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 32, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 32, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 32, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 48, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 48, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 48, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 48, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 48, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 48, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 48, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 48, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 48, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 48, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 73, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 73, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 73, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 73, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 73, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 73, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 73, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 73, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 73, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 73, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 111, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 111, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 111, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 111, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 111, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 111, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 111, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 111, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 111, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 111, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n", - "{'n_depth': 168, 'n_features': 4}\n", - "0.948\n", - "trial score: 0.948\n", - "{'n_depth': 168, 'n_features': 6}\n", - "0.947\n", - "trial score: 0.947\n", - "{'n_depth': 168, 'n_features': 12}\n", - "0.959\n", - "trial score: 0.959\n", - "{'n_depth': 168, 'n_features': 21}\n", - "0.957\n", - "trial score: 0.957\n", - "{'n_depth': 168, 'n_features': 36}\n", - "0.958\n", - "trial score: 0.958\n", - "{'n_depth': 168, 'n_features': 64}\n", - "0.956\n", - "trial score: 0.956\n", - "{'n_depth': 168, 'n_features': 111}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 168, 'n_features': 194}\n", - "0.953\n", - "trial score: 0.953\n", - "{'n_depth': 168, 'n_features': 337}\n", - "0.95\n", - "trial score: 0.95\n", - "{'n_depth': 168, 'n_features': 588}\n", - "0.94\n", - "trial score: 0.94\n" - ] - } - ], - "source": [ - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.model_selection import ParameterGrid\n", - "from sklearn.metrics import accuracy_score\n", - "import numpy as np\n", - "\n", - "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", - "depth = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "grid = {'n_features': features, 'n_depth': depth}\n", - "param_combo = []\n", - "acc_scores = []\n", - "\n", - "list_features = []\n", - "list_depths = []\n", - "\n", - "num_trials = 1\n", - "trial_score = 0\n", - "for count, params in enumerate(ParameterGrid(grid)):\n", - " print(params)\n", - " for t in range(num_trials):\n", - "\n", - " # Obtain similarity matrix from USPORF classifier\n", - " clf = RandomForestClassifier(n_estimators = 500,\n", - " max_features = params['n_features'],\n", - " max_depth = params['n_depth'],\n", - " random_state=42,\n", - " n_jobs = -2)\n", - "\n", - " clf.fit(images_train, labels_train)\n", - " \n", - " # Test classifier\n", - " predicted_labels = clf.predict(images_test)\n", - "\n", - " # Evaluate classifier\n", - " score = accuracy_score(labels_test, predicted_labels)\n", - " print(score)\n", - "\n", - " # Save tree information and associated ARI score\n", - " param_combo.append(params)\n", - " trial_score += score\n", - " list_depths.append(params['n_depth'])\n", - " list_features.append(params['n_features'])\n", - " \n", - " print('trial score:',trial_score/num_trials)\n", - " acc_scores.append(trial_score/num_trials)\n", - " trial_score = 0" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "features = np.logspace(2.0, 10, num= 10, base=2.0, endpoint = False, dtype = int)\n", - "depths = np.logspace(2.0, 8.0, num = 10, base=2.0, endpoint = False, dtype = int)\n", - "data = {'Depth':list_depths, 'Features':list_features, 'Accuracy': acc_scores}\n", - "df = pd.DataFrame(data) \n", - "df = df.pivot(\"Depth\", \"Features\", \"Accuracy\")\n", - "ax = sns.heatmap(df,linewidths=.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Summary of Results\n", - "\n", - "|Models |Performance | Best Params | Computation Time |\n", - "|---------------|--------------|----------------------------------|----------------------------|\n", - "|Base Model | 0.89 ± 0.02 | n_features = 28, max_depth = None|CPU total time: 25.3s | \n", - "|Grid Search | 0.89 ± 0.01 | n_features = 21, max_depth = 21 |CPU total time: 3h 55min 39s|\n", - "|Random Search | 0.90 ± 0.02 | n_features = 21, max_depth = 111 |CPU total time: 2h 6min 6s | \n", - "\n", - "\n", - "\n", - "\n", - "" - ] - }, - { - "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.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 1aaea80cab6c252a53b88a08d211000cf5e3426b Mon Sep 17 00:00:00 2001 From: Jenny Trieu Date: Thu, 19 Dec 2019 17:16:40 -0500 Subject: [PATCH 14/14] Delete Heatmap.png --- Heatmap.png | Bin 70538 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Heatmap.png diff --git a/Heatmap.png b/Heatmap.png deleted file mode 100644 index 7298fb4dde9305ad54011fa5f41f6ca74fd446b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70538 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 B@N@tG