{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modelling Intrusion Detection: Analysis of a Feature Selection Mechanism\n",
    "\n",
    "## Method Description\n",
    "\n",
    "### Step 1: Data preprocessing:\n",
    "All features are made numerical using one-Hot-encoding. The features are scaled to avoid features with large values that may weigh too much in the results.\n",
    "\n",
    "### Step 2: Feature Selection:\n",
    "Eliminate redundant and irrelevant data by selecting a subset of relevant features that fully represents the given problem.\n",
    "Univariate feature selection with ANOVA F-test. This analyzes each feature individually to detemine the strength of the relationship between the feature and labels. Using SecondPercentile method (sklearn.feature_selection) to select features based on percentile of the highest scores. \n",
    "When this subset is found: Recursive Feature Elimination (RFE) is applied.\n",
    "\n",
    "### Step 4: Build the model:\n",
    "Decision tree model is built.\n",
    "\n",
    "### Step 5: Prediction & Evaluation (validation):\n",
    "Using the test data to make predictions of the model.\n",
    "Multiple scores are considered such as:accuracy score, recall, f-measure, confusion matrix.\n",
    "perform a 10-fold cross-validation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Importing Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
    "from sklearn import preprocessing\n",
    "from sklearn.feature_selection import RFE\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.model_selection import train_test_split # Import train_test_split function\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dataset Information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_train=pd.read_csv('KDDTrain.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_test=pd.read_csv('KDDTest.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sample view of the training dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>tcp</th>\n",
       "      <th>ftp_data</th>\n",
       "      <th>SF</th>\n",
       "      <th>491</th>\n",
       "      <th>0.1</th>\n",
       "      <th>0.2</th>\n",
       "      <th>0.3</th>\n",
       "      <th>0.4</th>\n",
       "      <th>0.5</th>\n",
       "      <th>...</th>\n",
       "      <th>25</th>\n",
       "      <th>0.17.1</th>\n",
       "      <th>0.03</th>\n",
       "      <th>0.17.2</th>\n",
       "      <th>0.24</th>\n",
       "      <th>0.25</th>\n",
       "      <th>0.26</th>\n",
       "      <th>0.05</th>\n",
       "      <th>0.27</th>\n",
       "      <th>normal</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>udp</td>\n",
       "      <td>other</td>\n",
       "      <td>SF</td>\n",
       "      <td>146</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.88</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>S0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>26</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "      <td>232</td>\n",
       "      <td>8153</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>255</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.01</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "      <td>199</td>\n",
       "      <td>420</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>255</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>19</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 42 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   0  tcp ftp_data   SF  491   0.1  0.2  0.3  0.4  0.5  ...   25  0.17.1  \\\n",
       "0  0  udp    other   SF  146     0    0    0    0    0  ...    1    0.00   \n",
       "1  0  tcp  private   S0    0     0    0    0    0    0  ...   26    0.10   \n",
       "2  0  tcp     http   SF  232  8153    0    0    0    0  ...  255    1.00   \n",
       "3  0  tcp     http   SF  199   420    0    0    0    0  ...  255    1.00   \n",
       "4  0  tcp  private  REJ    0     0    0    0    0    0  ...   19    0.07   \n",
       "\n",
       "   0.03  0.17.2  0.24  0.25  0.26  0.05  0.27   normal  \n",
       "0  0.60    0.88  0.00  0.00  0.00   0.0  0.00   normal  \n",
       "1  0.05    0.00  0.00  1.00  1.00   0.0  0.00  neptune  \n",
       "2  0.00    0.03  0.04  0.03  0.01   0.0  0.01   normal  \n",
       "3  0.00    0.00  0.00  0.00  0.00   0.0  0.00   normal  \n",
       "4  0.07    0.00  0.00  0.00  0.00   1.0  1.00  neptune  \n",
       "\n",
       "[5 rows x 42 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_train.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sample view of the test dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>tcp</th>\n",
       "      <th>private</th>\n",
       "      <th>REJ</th>\n",
       "      <th>0.1</th>\n",
       "      <th>0.2</th>\n",
       "      <th>0.3</th>\n",
       "      <th>0.4</th>\n",
       "      <th>0.5</th>\n",
       "      <th>0.6</th>\n",
       "      <th>...</th>\n",
       "      <th>10.1</th>\n",
       "      <th>0.04.1</th>\n",
       "      <th>0.06.1</th>\n",
       "      <th>0.22</th>\n",
       "      <th>0.23</th>\n",
       "      <th>0.24</th>\n",
       "      <th>0.25</th>\n",
       "      <th>1.2</th>\n",
       "      <th>1.3</th>\n",
       "      <th>neptune</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.06</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "      <td>12983</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>86</td>\n",
       "      <td>0.61</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.61</td>\n",
       "      <td>0.02</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>icmp</td>\n",
       "      <td>eco_i</td>\n",
       "      <td>SF</td>\n",
       "      <td>20</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>57</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.28</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>saint</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>tcp</td>\n",
       "      <td>telnet</td>\n",
       "      <td>RSTO</td>\n",
       "      <td>0</td>\n",
       "      <td>15</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>86</td>\n",
       "      <td>0.31</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.02</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.83</td>\n",
       "      <td>0.71</td>\n",
       "      <td>mscan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "      <td>267</td>\n",
       "      <td>14515</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>255</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 42 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   0   tcp   private   REJ    0.1    0.2  0.3  0.4  0.5  0.6  ...  10.1  \\\n",
       "0  0   tcp   private   REJ      0      0    0    0    0    0  ...     1   \n",
       "1  2   tcp  ftp_data    SF  12983      0    0    0    0    0  ...    86   \n",
       "2  0  icmp     eco_i    SF     20      0    0    0    0    0  ...    57   \n",
       "3  1   tcp    telnet  RSTO      0     15    0    0    0    0  ...    86   \n",
       "4  0   tcp      http    SF    267  14515    0    0    0    0  ...   255   \n",
       "\n",
       "   0.04.1  0.06.1  0.22  0.23  0.24  0.25   1.2   1.3  neptune  \n",
       "0    0.00    0.06  0.00  0.00  0.00   0.0  1.00  1.00  neptune  \n",
       "1    0.61    0.04  0.61  0.02  0.00   0.0  0.00  0.00   normal  \n",
       "2    1.00    0.00  1.00  0.28  0.00   0.0  0.00  0.00    saint  \n",
       "3    0.31    0.17  0.03  0.02  0.00   0.0  0.83  0.71    mscan  \n",
       "4    1.00    0.00  0.01  0.03  0.01   0.0  0.00  0.00   normal  \n",
       "\n",
       "[5 rows x 42 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_test.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Columns Name of Training and Test dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "col_names = [\"duration\",\"protocol_type\",\"service\",\"flag\",\"src_bytes\",\n",
    "    \"dst_bytes\",\"land\",\"wrong_fragment\",\"urgent\",\"hot\",\"num_failed_logins\",\n",
    "    \"logged_in\",\"num_compromised\",\"root_shell\",\"su_attempted\",\"num_root\",\n",
    "    \"num_file_creations\",\"num_shells\",\"num_access_files\",\"num_outbound_cmds\",\n",
    "    \"is_host_login\",\"is_guest_login\",\"count\",\"srv_count\",\"serror_rate\",\n",
    "    \"srv_serror_rate\",\"rerror_rate\",\"srv_rerror_rate\",\"same_srv_rate\",\n",
    "    \"diff_srv_rate\",\"srv_diff_host_rate\",\"dst_host_count\",\"dst_host_srv_count\",\n",
    "    \"dst_host_same_srv_rate\",\"dst_host_diff_srv_rate\",\"dst_host_same_src_port_rate\",\n",
    "    \"dst_host_srv_diff_host_rate\",\"dst_host_serror_rate\",\"dst_host_srv_serror_rate\",\n",
    "    \"dst_host_rerror_rate\",\"dst_host_srv_rerror_rate\",\"label\"]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Shape of Training and Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'dataset_train' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-1-f6e5125c45e4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Number of Training records in Dataset:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdataset_train\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      2\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Number of Testing  records in Dataset:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdataset_test\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'dataset_train' is not defined"
     ]
    }
   ],
   "source": [
    "print(\"Shape of Training Dataset:\", dataset_train.shape)\n",
    "print(\"Shape of Testing Dataset:\", dataset_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Columns Assignement"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Assigning attribute name to dataset\n",
    "dataset_train = pd.read_csv(\"KDDTrain.csv\", header=None, names = col_names)\n",
    "dataset_test = pd.read_csv(\"KDDTest.csv\", header=None, names = col_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Label of training and test dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Label distribution Training set:\n",
      "normal             67343\n",
      "neptune            41214\n",
      "satan               3633\n",
      "ipsweep             3599\n",
      "portsweep           2931\n",
      "smurf               2646\n",
      "nmap                1493\n",
      "back                 956\n",
      "teardrop             892\n",
      "warezclient          890\n",
      "pod                  201\n",
      "guess_passwd          53\n",
      "buffer_overflow       30\n",
      "warezmaster           20\n",
      "land                  18\n",
      "imap                  11\n",
      "rootkit               10\n",
      "loadmodule             9\n",
      "ftp_write              8\n",
      "multihop               7\n",
      "phf                    4\n",
      "perl                   3\n",
      "spy                    2\n",
      "Name: label, dtype: int64\n",
      "\n",
      "Label distribution Test set:\n",
      "normal             9711\n",
      "neptune            4657\n",
      "guess_passwd       1231\n",
      "mscan               996\n",
      "warezmaster         944\n",
      "apache2             737\n",
      "satan               735\n",
      "processtable        685\n",
      "smurf               665\n",
      "back                359\n",
      "snmpguess           331\n",
      "saint               319\n",
      "mailbomb            293\n",
      "snmpgetattack       178\n",
      "portsweep           157\n",
      "ipsweep             141\n",
      "httptunnel          133\n",
      "nmap                 73\n",
      "pod                  41\n",
      "buffer_overflow      20\n",
      "multihop             18\n",
      "named                17\n",
      "ps                   15\n",
      "sendmail             14\n",
      "rootkit              13\n",
      "xterm                13\n",
      "teardrop             12\n",
      "xlock                 9\n",
      "land                  7\n",
      "xsnoop                4\n",
      "ftp_write             3\n",
      "sqlattack             2\n",
      "worm                  2\n",
      "perl                  2\n",
      "phf                   2\n",
      "udpstorm              2\n",
      "loadmodule            2\n",
      "imap                  1\n",
      "Name: label, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "#label distribution of Training set and testing set\n",
    "print('Label distribution Training set:')\n",
    "print(dataset_train['label'].value_counts())\n",
    "print()\n",
    "print('Label distribution Test set:')\n",
    "print(dataset_test['label'].value_counts())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Data preprocessing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One-Hot-Encoding (one-of-K) is used to to transform all categorical features into binary features. Requirement for One-Hot-encoding: \"The input to this transformer should be a matrix of integers, denoting the values taken on by categorical (discrete) features. The output will be a sparse matrix where each column corresponds to one possible value of one feature. It is assumed that input features take on values in the range [0, n_values).\"\n",
    "\n",
    "Therefore the features first need to be transformed with LabelEncoder, to transform every category to a number\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Identify categorical features¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set:\n",
      "Feature 'protocol_type' has 3 categories\n",
      "Feature 'service' has 70 categories\n",
      "Feature 'flag' has 11 categories\n",
      "Feature 'label' has 23 categories\n",
      "\n",
      "Distribution of categories in service:\n",
      "http        40338\n",
      "private     21853\n",
      "domain_u     9043\n",
      "smtp         7313\n",
      "ftp_data     6860\n",
      "Name: service, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# colums that are categorical and not binary yet: protocol_type (column 2), service (column 3), flag (column 4).\n",
    "# explore categorical features\n",
    "print('Training set:')\n",
    "for col_name in dataset_train.columns:\n",
    "    if dataset_train[col_name].dtypes == 'object' :\n",
    "        unique_cat = len(dataset_train[col_name].unique())\n",
    "        print(\"Feature '{col_name}' has {unique_cat} categories\".format(col_name=col_name, unique_cat=unique_cat))\n",
    "\n",
    "#see how distributed the feature service is, it is evenly distributed and therefore we need to make dummies for all.\n",
    "print()\n",
    "print('Distribution of categories in service:')\n",
    "print(dataset_train['service'].value_counts().sort_values(ascending=False).head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test set:\n",
      "Feature 'protocol_type' has 3 categories\n",
      "Feature 'service' has 64 categories\n",
      "Feature 'flag' has 11 categories\n",
      "Feature 'label' has 38 categories\n"
     ]
    }
   ],
   "source": [
    "# Test set\n",
    "print('Test set:')\n",
    "for col_name in dataset_test.columns:\n",
    "    if dataset_test[col_name].dtypes == 'object' :\n",
    "        unique_cat = len(dataset_test[col_name].unique())\n",
    "        print(\"Feature '{col_name}' has {unique_cat} categories\".format(col_name=col_name, unique_cat=unique_cat))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Conclusion: Need to make dummies for all categories as the distribution is fairly even. In total: 3+70+11=84 dummies.\n",
    "### Comparing the results shows that the Test set has fewer categories (6), these need to be added as empty columns."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LabelEncoder\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Insert categorical features into a 2D numpy array\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "categorical_columns=['protocol_type', 'service', 'flag']\n",
    "# insert code to get a list of categorical columns into a variable, categorical_columns\n",
    "categorical_columns=['protocol_type', 'service', 'flag'] \n",
    " # Get the categorical values into a 2D numpy array\n",
    "dataset_train_categorical_values = dataset_train[categorical_columns]\n",
    "dataset_test_categorical_values = dataset_test[categorical_columns]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>protocol_type</th>\n",
       "      <th>service</th>\n",
       "      <th>flag</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>udp</td>\n",
       "      <td>other</td>\n",
       "      <td>SF</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>S0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  protocol_type   service flag\n",
       "0           tcp  ftp_data   SF\n",
       "1           udp     other   SF\n",
       "2           tcp   private   S0\n",
       "3           tcp      http   SF\n",
       "4           tcp      http   SF"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_train_categorical_values.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dummy Columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Protocol_type_icmp', 'Protocol_type_tcp', 'Protocol_type_udp', 'service_IRC', 'service_X11', 'service_Z39_50', 'service_aol', 'service_auth', 'service_bgp', 'service_courier', 'service_csnet_ns', 'service_ctf', 'service_daytime', 'service_discard', 'service_domain', 'service_domain_u', 'service_echo', 'service_eco_i', 'service_ecr_i', 'service_efs', 'service_exec', 'service_finger', 'service_ftp', 'service_ftp_data', 'service_gopher', 'service_harvest', 'service_hostnames', 'service_http', 'service_http_2784', 'service_http_443', 'service_http_8001', 'service_imap4', 'service_iso_tsap', 'service_klogin', 'service_kshell', 'service_ldap', 'service_link', 'service_login', 'service_mtp', 'service_name', 'service_netbios_dgm', 'service_netbios_ns', 'service_netbios_ssn', 'service_netstat', 'service_nnsp', 'service_nntp', 'service_ntp_u', 'service_other', 'service_pm_dump', 'service_pop_2', 'service_pop_3', 'service_printer', 'service_private', 'service_red_i', 'service_remote_job', 'service_rje', 'service_shell', 'service_smtp', 'service_sql_net', 'service_ssh', 'service_sunrpc', 'service_supdup', 'service_systat', 'service_telnet', 'service_tftp_u', 'service_tim_i', 'service_time', 'service_urh_i', 'service_urp_i', 'service_uucp', 'service_uucp_path', 'service_vmnet', 'service_whois', 'flag_OTH', 'flag_REJ', 'flag_RSTO', 'flag_RSTOS0', 'flag_RSTR', 'flag_S0', 'flag_S1', 'flag_S2', 'flag_S3', 'flag_SF', 'flag_SH']\n"
     ]
    }
   ],
   "source": [
    "# protocol type\n",
    "unique_protocol=sorted(dataset_train.protocol_type.unique())\n",
    "string1 = 'Protocol_type_'\n",
    "unique_protocol2=[string1 + x for x in unique_protocol]\n",
    "# service\n",
    "unique_service=sorted(dataset_train.service.unique())\n",
    "string2 = 'service_'\n",
    "unique_service2=[string2 + x for x in unique_service]\n",
    "# flag\n",
    "unique_flag=sorted(dataset_train.flag.unique())\n",
    "string3 = 'flag_'\n",
    "unique_flag2=[string3 + x for x in unique_flag]\n",
    "# put together\n",
    "dumcols=unique_protocol2 + unique_service2 + unique_flag2\n",
    "print(dumcols)\n",
    "\n",
    "#do same for test set\n",
    "unique_service_test=sorted(dataset_test.service.unique())\n",
    "unique_service2_test=[string2 + x for x in unique_service_test]\n",
    "testdumcols=unique_protocol2 + unique_service2_test + unique_flag2\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Transform categorical features into numbers using LabelEncoder()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   protocol_type  service  flag\n",
      "0              1       20     9\n",
      "1              2       44     9\n",
      "2              1       49     5\n",
      "3              1       24     9\n",
      "4              1       24     9\n"
     ]
    }
   ],
   "source": [
    "#Transform categorical features into numbers using LabelEncoder()\n",
    "dataset_train_categorical_values_enc=dataset_train_categorical_values.apply(LabelEncoder().fit_transform)\n",
    "print(dataset_train_categorical_values_enc.head())\n",
    "# test set\n",
    "dataset_test_categorical_values_enc=dataset_test_categorical_values.apply(LabelEncoder().fit_transform)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# One-Hot-Encoding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "#One-Hot-Encoding¶\n",
    "enc = OneHotEncoder()\n",
    "dataset_train_categorical_values_encenc = enc.fit_transform(dataset_train_categorical_values_enc)\n",
    "dataset_train_cat_data = pd.DataFrame(dataset_train_categorical_values_encenc.toarray(),columns=dumcols)\n",
    "# test set\n",
    "dataset_test_categorical_values_encenc = enc.fit_transform(dataset_test_categorical_values_enc)\n",
    "dataset_test_cat_data = pd.DataFrame(dataset_test_categorical_values_encenc.toarray(),columns=testdumcols)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Protocol_type_icmp</th>\n",
       "      <th>Protocol_type_tcp</th>\n",
       "      <th>Protocol_type_udp</th>\n",
       "      <th>service_IRC</th>\n",
       "      <th>service_X11</th>\n",
       "      <th>service_Z39_50</th>\n",
       "      <th>service_aol</th>\n",
       "      <th>service_auth</th>\n",
       "      <th>service_bgp</th>\n",
       "      <th>service_courier</th>\n",
       "      <th>...</th>\n",
       "      <th>flag_REJ</th>\n",
       "      <th>flag_RSTO</th>\n",
       "      <th>flag_RSTOS0</th>\n",
       "      <th>flag_RSTR</th>\n",
       "      <th>flag_S0</th>\n",
       "      <th>flag_S1</th>\n",
       "      <th>flag_S2</th>\n",
       "      <th>flag_S3</th>\n",
       "      <th>flag_SF</th>\n",
       "      <th>flag_SH</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 84 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   Protocol_type_icmp  Protocol_type_tcp  Protocol_type_udp  service_IRC  \\\n",
       "0                 0.0                1.0                0.0          0.0   \n",
       "1                 0.0                0.0                1.0          0.0   \n",
       "2                 0.0                1.0                0.0          0.0   \n",
       "3                 0.0                1.0                0.0          0.0   \n",
       "4                 0.0                1.0                0.0          0.0   \n",
       "\n",
       "   service_X11  service_Z39_50  service_aol  service_auth  service_bgp  \\\n",
       "0          0.0             0.0          0.0           0.0          0.0   \n",
       "1          0.0             0.0          0.0           0.0          0.0   \n",
       "2          0.0             0.0          0.0           0.0          0.0   \n",
       "3          0.0             0.0          0.0           0.0          0.0   \n",
       "4          0.0             0.0          0.0           0.0          0.0   \n",
       "\n",
       "   service_courier  ...  flag_REJ  flag_RSTO  flag_RSTOS0  flag_RSTR  flag_S0  \\\n",
       "0              0.0  ...       0.0        0.0          0.0        0.0      0.0   \n",
       "1              0.0  ...       0.0        0.0          0.0        0.0      0.0   \n",
       "2              0.0  ...       0.0        0.0          0.0        0.0      1.0   \n",
       "3              0.0  ...       0.0        0.0          0.0        0.0      0.0   \n",
       "4              0.0  ...       0.0        0.0          0.0        0.0      0.0   \n",
       "\n",
       "   flag_S1  flag_S2  flag_S3  flag_SF  flag_SH  \n",
       "0      0.0      0.0      0.0      1.0      0.0  \n",
       "1      0.0      0.0      0.0      1.0      0.0  \n",
       "2      0.0      0.0      0.0      0.0      0.0  \n",
       "3      0.0      0.0      0.0      1.0      0.0  \n",
       "4      0.0      0.0      0.0      1.0      0.0  \n",
       "\n",
       "[5 rows x 84 columns]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_train_cat_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Add 6 missing categories from train set to test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['service_http_2784',\n",
       " 'service_urh_i',\n",
       " 'service_red_i',\n",
       " 'service_harvest',\n",
       " 'service_http_8001',\n",
       " 'service_aol']"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trainservice=dataset_train['service'].tolist()\n",
    "testservice= dataset_test['service'].tolist()\n",
    "difference=list(set(trainservice) - set(testservice))\n",
    "string = 'service_'\n",
    "difference=[string + x for x in difference]\n",
    "difference\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(22544, 84)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for col in difference:\n",
    "    dataset_test_cat_data[col] = 0\n",
    "\n",
    "dataset_test_cat_data.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Join encoded categorical dataframe with the non-categorical dataframe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(125973, 123)\n",
      "(22544, 123)\n"
     ]
    }
   ],
   "source": [
    "#Join encoded categorical dataframe with the non-categorical dataframe\n",
    "newdf=dataset_train.join(dataset_train_cat_data)\n",
    "newdf.drop('flag', axis=1, inplace=True)\n",
    "newdf.drop('protocol_type', axis=1, inplace=True)\n",
    "newdf.drop('service', axis=1, inplace=True)\n",
    "# test data\n",
    "newdf_test=dataset_test.join(dataset_test_cat_data)\n",
    "newdf_test.drop('flag', axis=1, inplace=True)\n",
    "newdf_test.drop('protocol_type', axis=1, inplace=True)\n",
    "newdf_test.drop('service', axis=1, inplace=True)\n",
    "print(newdf.shape)\n",
    "print(newdf_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Split Dataset into 4 datasets for every attack category\n",
    "## Rename every attack label: 0=normal, 1=DoS, 2=Probe, 3=R2L and 4=U2R.\n",
    "## Replace labels column with new labels column\n",
    "## Make new datasets\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0\n",
      "1    0\n",
      "2    1\n",
      "3    0\n",
      "4    0\n",
      "Name: label, dtype: object\n"
     ]
    }
   ],
   "source": [
    "# take label column\n",
    "labeldf=newdf['label']\n",
    "labeldf_test=newdf_test['label']\n",
    "# change the label column\n",
    "newlabeldf=labeldf.replace({ 'normal' : 0, 'neptune' : 1 ,'back': 1, 'land': 1, 'pod': 1, 'smurf': 1, 'teardrop': 1,'mailbomb': 1, 'apache2': 1, 'processtable': 1, 'udpstorm': 1, 'worm': 1,\n",
    "                           'ipsweep' : 2,'nmap' : 2,'portsweep' : 2,'satan' : 2,'mscan' : 2,'saint' : 2\n",
    "                           ,'ftp_write': 3,'guess_passwd': 3,'imap': 3,'multihop': 3,'phf': 3,'spy': 3,'warezclient': 3,'warezmaster': 3,'sendmail': 3,'named': 3,'snmpgetattack': 3,'snmpguess': 3,'xlock': 3,'xsnoop': 3,'httptunnel': 3,\n",
    "                           'buffer_overflow': 4,'loadmodule': 4,'perl': 4,'rootkit': 4,'ps': 4,'sqlattack': 4,'xterm': 4})\n",
    "newlabeldf_test=labeldf_test.replace({ 'normal' : 0, 'neptune' : 1 ,'back': 1, 'land': 1, 'pod': 1, 'smurf': 1, 'teardrop': 1,'mailbomb': 1, 'apache2': 1, 'processtable': 1, 'udpstorm': 1, 'worm': 1,\n",
    "                           'ipsweep' : 2,'nmap' : 2,'portsweep' : 2,'satan' : 2,'mscan' : 2,'saint' : 2\n",
    "                           ,'ftp_write': 3,'guess_passwd': 3,'imap': 3,'multihop': 3,'phf': 3,'spy': 3,'warezclient': 3,'warezmaster': 3,'sendmail': 3,'named': 3,'snmpgetattack': 3,'snmpguess': 3,'xlock': 3,'xsnoop': 3,'httptunnel': 3,\n",
    "                           'buffer_overflow': 4,'loadmodule': 4,'perl': 4,'rootkit': 4,'ps': 4,'sqlattack': 4,'xterm': 4})\n",
    "# put the new label column back\n",
    "newdf['label'] = newlabeldf\n",
    "newdf_test['label'] = newlabeldf_test\n",
    "print(newdf['label'].head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train:\n",
      "Dimensions of DoS: (113270, 123)\n",
      "Dimensions of Probe: (78999, 123)\n",
      "Dimensions of R2L: (68338, 123)\n",
      "Dimensions of U2R: (67395, 123)\n",
      "Test:\n",
      "Dimensions of DoS: (17171, 123)\n",
      "Dimensions of Probe: (12132, 123)\n",
      "Dimensions of R2L: (12596, 123)\n",
      "Dimensions of U2R: (9778, 123)\n"
     ]
    }
   ],
   "source": [
    "to_drop_DoS = [2,3,4]\n",
    "to_drop_Probe = [1,3,4]\n",
    "to_drop_R2L = [1,2,4]\n",
    "to_drop_U2R = [1,2,3]\n",
    "DoS_df=newdf[~newdf['label'].isin(to_drop_DoS)];\n",
    "Probe_df=newdf[~newdf['label'].isin(to_drop_Probe)];\n",
    "R2L_df=newdf[~newdf['label'].isin(to_drop_R2L)];\n",
    "U2R_df=newdf[~newdf['label'].isin(to_drop_U2R)];\n",
    "\n",
    "#test\n",
    "DoS_df_test=newdf_test[~newdf_test['label'].isin(to_drop_DoS)];\n",
    "Probe_df_test=newdf_test[~newdf_test['label'].isin(to_drop_Probe)];\n",
    "R2L_df_test=newdf_test[~newdf_test['label'].isin(to_drop_R2L)];\n",
    "U2R_df_test=newdf_test[~newdf_test['label'].isin(to_drop_U2R)];\n",
    "print('Train:')\n",
    "print('Dimensions of DoS:' ,DoS_df.shape)\n",
    "print('Dimensions of Probe:' ,Probe_df.shape)\n",
    "print('Dimensions of R2L:' ,R2L_df.shape)\n",
    "print('Dimensions of U2R:' ,U2R_df.shape)\n",
    "print('Test:')\n",
    "print('Dimensions of DoS:' ,DoS_df_test.shape)\n",
    "print('Dimensions of Probe:' ,Probe_df_test.shape)\n",
    "print('Dimensions of R2L:' ,R2L_df_test.shape)\n",
    "print('Dimensions of U2R:' ,U2R_df_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Feature Scaling:¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split dataframes into X & Y\n",
    "# assign X as a dataframe of feautures and Y as a series of outcome variables\n",
    "X_DoS = DoS_df.drop('label',1)\n",
    "Y_DoS = DoS_df.label\n",
    "X_Probe = Probe_df.drop('label',1)\n",
    "Y_Probe = Probe_df.label\n",
    "X_R2L = R2L_df.drop('label',1)\n",
    "Y_R2L = R2L_df.label\n",
    "X_U2R = U2R_df.drop('label',1)\n",
    "Y_U2R = U2R_df.label\n",
    "# test set\n",
    "X_DoS_test = DoS_df_test.drop('label',1)\n",
    "Y_DoS_test = DoS_df_test.label\n",
    "X_Probe_test = Probe_df_test.drop('label',1)\n",
    "Y_Probe_test = Probe_df_test.label\n",
    "X_R2L_test = R2L_df_test.drop('label',1)\n",
    "Y_R2L_test = R2L_df_test.label\n",
    "X_U2R_test = U2R_df_test.drop('label',1)\n",
    "Y_U2R_test = U2R_df_test.label"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Save a list of feature names for later use (it is the same for every attack category). Column names are dropped at this stage."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "colNames=list(X_DoS)\n",
    "colNames_test=list(X_DoS_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Use StandardScaler() to scale the dataframes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler1 = preprocessing.StandardScaler().fit(X_DoS)\n",
    "X_DoS=scaler1.transform(X_DoS) \n",
    "scaler2 = preprocessing.StandardScaler().fit(X_Probe)\n",
    "X_Probe=scaler2.transform(X_Probe) \n",
    "scaler3 = preprocessing.StandardScaler().fit(X_R2L)\n",
    "X_R2L=scaler3.transform(X_R2L) \n",
    "scaler4 = preprocessing.StandardScaler().fit(X_U2R)\n",
    "X_U2R=scaler4.transform(X_U2R) \n",
    "# test data\n",
    "scaler5 = preprocessing.StandardScaler().fit(X_DoS_test)\n",
    "X_DoS_test=scaler5.transform(X_DoS_test) \n",
    "scaler6 = preprocessing.StandardScaler().fit(X_Probe_test)\n",
    "X_Probe_test=scaler6.transform(X_Probe_test) \n",
    "scaler7 = preprocessing.StandardScaler().fit(X_R2L_test)\n",
    "X_R2L_test=scaler7.transform(X_R2L_test) \n",
    "scaler8 = preprocessing.StandardScaler().fit(X_U2R_test)\n",
    "X_U2R_test=scaler8.transform(X_U2R_test)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Check that the Standard Deviation is 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 1. 1. 1. 1.\n",
      " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1.\n",
      " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 0. 1. 0. 1. 1. 1.\n",
      " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n",
      " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 1. 1. 1. 1. 1.\n",
      " 1. 1.]\n"
     ]
    }
   ],
   "source": [
    "print(X_DoS.std(axis=0))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_Probe.std(axis=0);\n",
    "X_R2L.std(axis=0);\n",
    "X_U2R.std(axis=0);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 3: Feature Selection:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Univariate Feature Selection using ANOVA F-test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(113270, 13)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#univariate feature selection with ANOVA F-test. using secondPercentile method, then RFE\n",
    "#Scikit-learn exposes feature selection routines as objects that implement the transform method\n",
    "#SelectPercentile: removes all but a user-specified highest scoring percentage of features\n",
    "#f_classif: ANOVA F-value between label/feature for classification tasks.\n",
    "from sklearn.feature_selection import SelectPercentile, f_classif\n",
    "np.seterr(divide='ignore', invalid='ignore');\n",
    "selector=SelectPercentile(f_classif, percentile=10)\n",
    "X_newDoS = selector.fit_transform(X_DoS,Y_DoS)\n",
    "X_newDoS.shape\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Get the features that were selected: DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['logged_in',\n",
       " 'count',\n",
       " 'serror_rate',\n",
       " 'srv_serror_rate',\n",
       " 'same_srv_rate',\n",
       " 'dst_host_count',\n",
       " 'dst_host_srv_count',\n",
       " 'dst_host_same_srv_rate',\n",
       " 'dst_host_serror_rate',\n",
       " 'dst_host_srv_serror_rate',\n",
       " 'service_http',\n",
       " 'flag_S0',\n",
       " 'flag_SF']"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "true=selector.get_support()\n",
    "newcolindex_DoS=[i for i, x in enumerate(true) if x]\n",
    "newcolname_DoS=list( colNames[i] for i in newcolindex_DoS )\n",
    "newcolname_DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(78999, 13)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_newProbe = selector.fit_transform(X_Probe,Y_Probe)\n",
    "X_newProbe.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Get the features that were selected: Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['logged_in',\n",
       " 'rerror_rate',\n",
       " 'srv_rerror_rate',\n",
       " 'dst_host_srv_count',\n",
       " 'dst_host_diff_srv_rate',\n",
       " 'dst_host_same_src_port_rate',\n",
       " 'dst_host_srv_diff_host_rate',\n",
       " 'dst_host_rerror_rate',\n",
       " 'dst_host_srv_rerror_rate',\n",
       " 'Protocol_type_icmp',\n",
       " 'service_eco_i',\n",
       " 'service_private',\n",
       " 'flag_SF']"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "true=selector.get_support()\n",
    "newcolindex_Probe=[i for i, x in enumerate(true) if x]\n",
    "newcolname_Probe=list( colNames[i] for i in newcolindex_Probe )\n",
    "newcolname_Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(68338, 13)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_newR2L = selector.fit_transform(X_R2L,Y_R2L)\n",
    "X_newR2L.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get the features that were selected: R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['src_bytes',\n",
       " 'dst_bytes',\n",
       " 'hot',\n",
       " 'num_failed_logins',\n",
       " 'is_guest_login',\n",
       " 'dst_host_srv_count',\n",
       " 'dst_host_same_src_port_rate',\n",
       " 'dst_host_srv_diff_host_rate',\n",
       " 'service_ftp',\n",
       " 'service_ftp_data',\n",
       " 'service_http',\n",
       " 'service_imap4',\n",
       " 'flag_RSTO']"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "true=selector.get_support()\n",
    "newcolindex_R2L=[i for i, x in enumerate(true) if x]\n",
    "newcolname_R2L=list( colNames[i] for i in newcolindex_R2L)\n",
    "newcolname_R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(67395, 13)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_newU2R = selector.fit_transform(X_U2R,Y_U2R)\n",
    "X_newU2R.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Get the features that were selected: U2R\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['urgent',\n",
       " 'hot',\n",
       " 'root_shell',\n",
       " 'num_file_creations',\n",
       " 'num_shells',\n",
       " 'srv_diff_host_rate',\n",
       " 'dst_host_count',\n",
       " 'dst_host_srv_count',\n",
       " 'dst_host_same_src_port_rate',\n",
       " 'dst_host_srv_diff_host_rate',\n",
       " 'service_ftp_data',\n",
       " 'service_http',\n",
       " 'service_telnet']"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "true=selector.get_support()\n",
    "newcolindex_U2R=[i for i, x in enumerate(true) if x]\n",
    "newcolname_U2R=list( colNames[i] for i in newcolindex_U2R)\n",
    "newcolname_U2R"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Summary of features selected by Univariate Feature Selection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features selected for DoS: ['logged_in', 'count', 'serror_rate', 'srv_serror_rate', 'same_srv_rate', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_serror_rate', 'dst_host_srv_serror_rate', 'service_http', 'flag_S0', 'flag_SF']\n",
      "\n",
      "Features selected for Probe: ['logged_in', 'rerror_rate', 'srv_rerror_rate', 'dst_host_srv_count', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate', 'Protocol_type_icmp', 'service_eco_i', 'service_private', 'flag_SF']\n",
      "\n",
      "Features selected for R2L: ['src_bytes', 'dst_bytes', 'hot', 'num_failed_logins', 'is_guest_login', 'dst_host_srv_count', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'service_ftp', 'service_ftp_data', 'service_http', 'service_imap4', 'flag_RSTO']\n",
      "\n",
      "Features selected for U2R: ['urgent', 'hot', 'root_shell', 'num_file_creations', 'num_shells', 'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'service_ftp_data', 'service_http', 'service_telnet']\n"
     ]
    }
   ],
   "source": [
    "print('Features selected for DoS:',newcolname_DoS)\n",
    "print()\n",
    "print('Features selected for Probe:',newcolname_Probe)\n",
    "print()\n",
    "print('Features selected for R2L:',newcolname_R2L)\n",
    "print()\n",
    "print('Features selected for U2R:',newcolname_U2R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The authors state that \"After obtaining the adequate number of features during the univariate selection process, a recursive feature elimination (RFE) was operated with the number of features passed as parameter to identify the features selected\". This either implies that RFE is only used for obtaining the features previously selected but also obtaining the rank. This use of RFE is however very redundant as the features selected can be obtained in another way (Done in this project). One can also not say that the features were selected by RFE, as it was not used for this. The quote could however also imply that only the number 13 from univariate feature selection was used. RFE is then used for feature selection trying to find the best 13 features. With this use of RFE one can actually say that it was used for feature selection. However the authors obtained different numbers of features for every attack category, 12 for DoS, 15 for Probe, 13 for R2L and 11 for U2R. This concludes that it is not clear what mechanism is used for feature selection.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# To procede with the data mining, the second option is considered as this uses RFE. From now on the number of features for every attack category is 13.\n",
    "#2. Recursive Feature Elimination for feature ranking (Option 1: get importance from previous selected)¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DoS Features sorted by their rank:\n",
      "[(1, 'same_srv_rate'), (2, 'count'), (3, 'flag_SF'), (4, 'dst_host_serror_rate'), (5, 'dst_host_same_srv_rate'), (6, 'dst_host_srv_count'), (7, 'dst_host_count'), (8, 'logged_in'), (9, 'serror_rate'), (10, 'dst_host_srv_serror_rate'), (11, 'srv_serror_rate'), (12, 'service_http'), (13, 'flag_S0')]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "# Create a decision tree classifier. By convention, clf means 'classifier'\n",
    "clf = DecisionTreeClassifier(random_state=0)\n",
    "\n",
    "#rank all features, i.e continue the elimination until the last one\n",
    "rfe = RFE(clf, n_features_to_select=1)\n",
    "rfe.fit(X_newDoS, Y_DoS.astype('int'))\n",
    "print (\"DoS Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_DoS)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Probe Features sorted by their rank:\n",
      "[(1, 'dst_host_same_src_port_rate'), (2, 'dst_host_srv_count'), (3, 'dst_host_rerror_rate'), (4, 'service_private'), (5, 'logged_in'), (6, 'dst_host_diff_srv_rate'), (7, 'dst_host_srv_diff_host_rate'), (8, 'flag_SF'), (9, 'service_eco_i'), (10, 'rerror_rate'), (11, 'Protocol_type_icmp'), (12, 'dst_host_srv_rerror_rate'), (13, 'srv_rerror_rate')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newProbe, Y_Probe.astype(int))\n",
    "print (\"Probe Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_Probe)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "R2L Features sorted by their rank:\n",
      "[(1, 'src_bytes'), (2, 'dst_bytes'), (3, 'hot'), (4, 'dst_host_srv_diff_host_rate'), (5, 'service_ftp_data'), (6, 'dst_host_same_src_port_rate'), (7, 'dst_host_srv_count'), (8, 'num_failed_logins'), (9, 'service_imap4'), (10, 'is_guest_login'), (11, 'service_ftp'), (12, 'flag_RSTO'), (13, 'service_http')]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "rfe.fit(X_newR2L, Y_R2L.astype(int))\n",
    " \n",
    "print (\"R2L Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_R2L)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U2R Features sorted by their rank:\n",
      "[(1, 'hot'), (2, 'dst_host_srv_count'), (3, 'dst_host_count'), (4, 'root_shell'), (5, 'num_shells'), (6, 'service_ftp_data'), (7, 'dst_host_srv_diff_host_rate'), (8, 'num_file_creations'), (9, 'dst_host_same_src_port_rate'), (10, 'service_telnet'), (11, 'srv_diff_host_rate'), (12, 'service_http'), (13, 'urgent')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newU2R, Y_U2R.astype(int))\n",
    " \n",
    "print (\"U2R Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_U2R)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Recursive Feature Elimination, select 13 features each of 122 (Option 2: get 13 best features from 122 from RFE)¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "clf = DecisionTreeClassifier(random_state=0)\n",
    "rfe = RFE(estimator=clf, n_features_to_select=13, step=1)\n",
    "rfe.fit(X_DoS, Y_DoS.astype(int))\n",
    "X_rfeDoS=rfe.transform(X_DoS)\n",
    "true=rfe.support_\n",
    "rfecolindex_DoS=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_DoS=list(colNames[i] for i in rfecolindex_DoS)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_Probe, Y_Probe.astype(int))\n",
    "X_rfeProbe=rfe.transform(X_Probe)\n",
    "true=rfe.support_\n",
    "rfecolindex_Probe=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_Probe=list(colNames[i] for i in rfecolindex_Probe)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_R2L, Y_R2L.astype(int))\n",
    "X_rfeR2L=rfe.transform(X_R2L)\n",
    "true=rfe.support_\n",
    "rfecolindex_R2L=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_R2L=list(colNames[i] for i in rfecolindex_R2L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_U2R, Y_U2R.astype(int))\n",
    "X_rfeU2R=rfe.transform(X_U2R)\n",
    "true=rfe.support_\n",
    "rfecolindex_U2R=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_U2R=list(colNames[i] for i in rfecolindex_U2R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Summary of features selected by RFE\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features selected for DoS: ['src_bytes', 'dst_bytes', 'wrong_fragment', 'num_compromised', 'same_srv_rate', 'diff_srv_rate', 'dst_host_count', 'dst_host_same_srv_rate', 'dst_host_serror_rate', 'dst_host_srv_serror_rate', 'service_ecr_i', 'flag_RSTR', 'flag_S0']\n",
      "\n",
      "Features selected for Probe: ['src_bytes', 'dst_bytes', 'rerror_rate', 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_rerror_rate', 'service_finger', 'service_ftp_data', 'service_http', 'service_private', 'service_smtp', 'service_telnet']\n",
      "\n",
      "Features selected for R2L: ['duration', 'src_bytes', 'dst_bytes', 'hot', 'num_failed_logins', 'num_access_files', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'service_ftp_data', 'service_imap4']\n",
      "\n",
      "Features selected for U2R: ['duration', 'src_bytes', 'dst_bytes', 'hot', 'root_shell', 'num_file_creations', 'num_shells', 'srv_count', 'dst_host_count', 'dst_host_same_srv_rate', 'dst_host_srv_diff_host_rate', 'service_ftp_data', 'service_other']\n"
     ]
    }
   ],
   "source": [
    "print('Features selected for DoS:',rfecolname_DoS)\n",
    "print()\n",
    "print('Features selected for Probe:',rfecolname_Probe)\n",
    "print()\n",
    "print('Features selected for R2L:',rfecolname_R2L)\n",
    "print()\n",
    "print('Features selected for U2R:',rfecolname_U2R)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(113270, 13)\n",
      "(78999, 13)\n",
      "(68338, 13)\n",
      "(67395, 13)\n"
     ]
    }
   ],
   "source": [
    "print(X_rfeDoS.shape)\n",
    "print(X_rfeProbe.shape)\n",
    "print(X_rfeR2L.shape)\n",
    "print(X_rfeU2R.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 4: Build the model:\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Classifier is trained for all features and for reduced features, for later comparison.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The classifier model itself is stored in the clf variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,\n",
       "                       max_features=None, 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, presort=False,\n",
       "                       random_state=0, splitter='best')"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# all features\n",
    "clf_DoS=DecisionTreeClassifier(random_state=0)\n",
    "clf_Probe=DecisionTreeClassifier(random_state=0)\n",
    "clf_R2L=DecisionTreeClassifier(random_state=0)\n",
    "clf_U2R=DecisionTreeClassifier(random_state=0)\n",
    "clf_DoS.fit(X_DoS, Y_DoS.astype(int))\n",
    "clf_Probe.fit(X_Probe, Y_Probe.astype(int))\n",
    "clf_R2L.fit(X_R2L, Y_R2L.astype(int))\n",
    "clf_U2R.fit(X_U2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,\n",
       "                       max_features=None, 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, presort=False,\n",
       "                       random_state=0, splitter='best')"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# selected features\n",
    "clf_rfeDoS=DecisionTreeClassifier(random_state=0)\n",
    "clf_rfeProbe=DecisionTreeClassifier(random_state=0)\n",
    "clf_rfeR2L=DecisionTreeClassifier(random_state=0)\n",
    "clf_rfeU2R=DecisionTreeClassifier(random_state=0)\n",
    "clf_rfeDoS.fit(X_rfeDoS, Y_DoS.astype(int))\n",
    "clf_rfeProbe.fit(X_rfeProbe, Y_Probe.astype(int))\n",
    "clf_rfeR2L.fit(X_rfeR2L, Y_R2L.astype(int))\n",
    "clf_rfeU2R.fit(X_rfeU2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. Prediction & Evaluation (validation):\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using all Features for each category"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : DoS\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 1, 0, ..., 0, 0, 0])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Apply the classifier we trained to the test data (which it has never seen before)\n",
    "clf_DoS.predict(X_DoS_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 1.],\n",
       "       [0., 1.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [0., 1.],\n",
       "       [1., 0.],\n",
       "       [1., 0.]])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# View the predicted probabilities of the first 10 observations\n",
    "clf_DoS.predict_proba(X_DoS_test)[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9499</td>\n",
       "      <td>212</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>2830</td>\n",
       "      <td>4630</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0     1\n",
       "Actual attacks               \n",
       "0                  9499   212\n",
       "1                  2830  4630"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_DoS_pred=clf_DoS.predict(X_DoS_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_DoS_test, Y_DoS_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>2337</td>\n",
       "      <td>7374</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>212</td>\n",
       "      <td>2209</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0     2\n",
       "Actual attacks               \n",
       "0                  2337  7374\n",
       "2                   212  2209"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_Probe_pred=clf_Probe.predict(X_Probe_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_Probe_test, Y_Probe_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9707</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>2573</td>\n",
       "      <td>312</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0    3\n",
       "Actual attacks              \n",
       "0                  9707    4\n",
       "3                  2573  312"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_R2L_pred=clf_R2L.predict(X_R2L_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_R2L_test, Y_R2L_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>4</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9703</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>60</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0  4\n",
       "Actual attacks            \n",
       "0                  9703  8\n",
       "4                    60  7"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_U2R_pred=clf_U2R.predict(X_U2R_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_U2R_test, Y_U2R_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cross Validation: Accuracy, Precision, Recall, F-measure¶\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DoS¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99639 (+/- 0.00341)\n",
      "Precision: 0.99505 (+/- 0.00477)\n",
      "Recall: 0.99665 (+/- 0.00483)\n",
      "F-measure: 0.99585 (+/- 0.00392)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn import metrics\n",
    "accuracy = cross_val_score(clf_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='precision')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='recall')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='f1')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Probe¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99571 (+/- 0.00328)\n",
      "Precision: 0.99391 (+/- 0.00684)\n",
      "Recall: 0.99267 (+/- 0.00405)\n",
      "F-measure: 0.99329 (+/- 0.00512)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# R2L¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.97920 (+/- 0.01054)\n",
      "Precision: 0.97150 (+/- 0.01741)\n",
      "Recall: 0.96957 (+/- 0.01381)\n",
      "F-measure: 0.97050 (+/- 0.01482)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# U2R¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99663 (+/- 0.00259)\n",
      "Precision: 0.86481 (+/- 0.08952)\n",
      "Recall: 0.91672 (+/- 0.10661)\n",
      "F-measure: 0.88628 (+/- 0.07462)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RFECV for illustration¶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Automatically created module for IPython interactive environment\n"
     ]
    }
   ],
   "source": [
    "print(__doc__)\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.feature_selection import RFECV\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEbCAYAAADAsRPLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3deXycdbn//9c7W9ukadI2bSndW8pSoBQsu1pAREBkFYUjRxSOHBeUoweP8FNRew4/RNHjhseDRxQU4WAFRSybtcUDyNLSBUoplNLSdKFr0jZJ28zM9f3j/kw6mUwyd9tMNq7n4zGPmXub+3PPJPc1n11mhnPOOZetqLsT4JxzrmfyAOGccy4nDxDOOedy8gDhnHMuJw8QzjnncvIA4ZxzLicPEM4553IqibOTpOHAqcDBQBPwMjDfzFIFTJtzzrlupI46ykk6HbgBGAIsBDYC/YFDgUnALOB7Zra98El1zjnXlfIFiO8CPzazt3JsKwHOA4rN7PeFS6Jzzrnu0GGAcM45984Vq5Ja0nWSBinyC0kvSjqr0IlzzjnXfeK2Yroq1DOcBQwDPgl8u2Cpcq4TSVolqUnSTkkbJP1K0sCM7b+StCdsTz8+muPY9OMnGceODD+a1kvaIelVSd+SVBFeX5UjPddJmp8nrTsk1Ul6RtKnJcX9MVcm6XuSakNa35T0n/v+qTkXP0AoPJ8L/NLMFmesc643+JCZDQSmAccCN2Zt/46ZDcx4/G/2sRmPawEkDQH+DgwATjazSuD9QDVRI467gI/nSMs/hm0dpbUSGEf0Q+wrwC9iXueNwHTgBKASOJ2ogYlz+yxugFgg6XGiAPGYpErAm7i6XsfMNgCPEQWKA/UlYAdwhZmtCu+/xsyuM7MlwK+Bd0salz5A0hHAVODeGGmtN7OHgI8CV0o6KrxHlaS7JW2StFrS1zJyGMcDD5rZOousMrO7O+Fa3TtQ3ABxNVFz1+PNrBEoIypmcq5XkTQaOAdY0QlvdybwQHv9gcysFphLlGNI+zgw28w2xz2JmT0P1ALvCat+DFQBE4EZ4T3T/4/PAl+S9FlJR0vynL7bb7ECRPgHeBuYIum9wJFE2Wjneos/SNoBrCHqz/ONrO3XhzL/OknZN+8/ZGyrk/SpsH4osD7Pee8iBIjwK/9jdFy81J51wBBJxUQ5ihvNbEfIuXyPvUHoFuDWcJ75wFpJV+7H+ZyL3ZP6VqI/yleAZFhtwN8KlC7nOtuFZvYXSTOA3wI1QF3G9tvM7GsdHZtj/RZgZJ7zPgD8VNJJQHl4/Hnfkg7AKGArUbrLgNUZ21aH7ZhZErgduF3SAOAq4E5Jz5vZsv04r3sHi1vEdCFwmJmda2YfCo/zC5kw5wrBzJ4EfgXc1glv9xfgoo5aGIUi2VlExUD/CNxnZnv25SSSjicKAE8Bm4FmogrstLHA2hznbjKz24FtwJR9OadzED9ArARKC5kQ57rQD4D3SzrQiurvA4OAu9IV0ZJGSfq+pKkZ+91FlAO/hH0oXgp9j84D7gN+Y2YvhRzC/cDNkirDeb8E/CYc8y+STpM0QFJJKF6qxFsyuf0Qq4gJaAQWSZoD7E6vNLMvFCRVzhWQmW2SdDfwdaKbdj5/kpTMWH7CzC4ys62STgH+A3hOUgXRL/l7aV0J/jegHthtZi/EPF+CqKXgK0SB6GcZ2z9PVFG9EtgF/By4M2xrIqqTOISoGPg14BIzWxnjvM61EmuojfYqucxsfyrbnHPO9QKxx2KSVEY0iivAcjNrLliqnHPOdbu43fdPA14nah3xU+C10Ny1o2PulLRR0svtbJekH0laIWmJpOMytl0p6fXw8CZ6zjnXDeIWMS0A/sHMloflQ4F7zexdHRzzXmAncLeZHZVj+7lEZannAicCPzSzE8PwBfOJhgswYAHwLjPbtq8X55xzbv/FbcVUmg4OAGb2GnlaNZnZ34jabbfnAqLgYWb2LFAtaSTwAaJKwK0hKDwBnB0znc455zpJ3FZM8yX9gmhsGYh6aS44wHOPIurVmlYb1rW3vkM1NTU2fvz4A0ySc869syxYsGCzmQ3LtS1ugPgM8DngC0SjuP6NqC7iQOQaI8Y6WN/2DaRrgGsAxo4dy/z5OUdQds451w5Jq9vbFitAmNluorbY3++sRBHlDMZkLI8mGm+mFjgta/28dtJ1B3AHwPTp031qPOec60Qd1kFIuj88vxRaGrV6HOC5HwI+HloznQTUm9l6oqGYz5I0WNJgokmKHjvAcznnnNtH+XIQ14Xn8/b1jSXdS5QTqJFUSzR6ZimAmf0MmE3UgmkFUU/tT4ZtWyX9O5DucTrTzDqq7HbOOVcAHQaI8Ise4LNm9pXMbWGE16+0Parl2MvzvLcR1Wvk2nYne4cOcM451w3iNnN9f45153RmQpxzzvUsHeYgJH0G+CwwMavOoRJ4upAJc845173y1UH8FniEaJaqGzLW7/B6Aeec69vy1UHUEw1TfDmApOFAf2CgpIFm9lbhk9izLVu/nY07dlM9oJTB5WVUlZdS2a+EbY17WLWlkcY9CY4bO5iKfnG7nDjn9lfTniSzXqzl/UeM4KCq/p3ynlsb9lA1oJTionfe9N5xpxz9EFEfiIOJ5vMdBywjmpv6Heup1zfz8TufI5XVA0OCzCGuyoqLOGHCEM4/5mDOn3Yw/UuLuyR9a7Y28qcl6ygrLuKS40YzuKKsS877TmBmrK1rYvGaehKpFMeMrmbc0HKknnETSaaMItFj0pNtweqtvLm5kfFDy5k4bCBDMv42dyeSzH11I1NHV3Nw9YDY7/nU65u58cElrNnaxM//tpJ7rzmJUVnH704kMaPD/8E9iRSPvLye2S+tZ/GaejZs38URIwdx6yVHM3V0NTt3J3jq9c0cefAgxgwpbzkukUyRNKNfScf/3/NXbaV2WxPjayoYP7Sc6vK9125m1DU2s61xD3VNzQzqX8rEmgqKsoJTfVMzb25uYMLQCqrKCzeXW9zB+hYDZwB/MbNjJZ0OXG5m1xQsZfto+vTp1pU9qdfVNXHej5+iZmAZN190NNubmtnW2Exd4x7qm5qpLi9jQk05JUVFPLViM3OWvc0bmxoYXF7KBdNGcXB1f6oHlDFtbDWHjqg84PS8ubmBJ5dv5M3NDdQ1NbN6SyOL1uydcrlfSRFnHXkQu5uTrN7SSGX/Es6fdjAfPHokQwf2w8x4c3MDc5dv4tmVW9i0Yzd1jXsYWTWAr5xzONPGVJNIpnj8lbd5a2sjU0dVMXlEJc+8sZk/LlrHlp27OefokZx/zMEt/9Rr65qYt3wjz67cSs3AMqaNqWby8EqKi0TKjPX1TazaHOWyjhxVxbTR1S1BLJUyHnl5A//z1EpKisS0MdWMHVrB2m1NvLW1AYCqAWVUl5cyuLyU6gFR7q16QClFReKl2nqW1NYxoKw43LwreHXDdpbU1gMwbmg5Y4eUM6SijMHlZYwY1J8Rg/ohiVWbG3jytU0UCWYcOpyxQ8vZsauZJbX1LFpTx8K36lhcW8emHbtbfQdDK8r4hxPHcvW7J1DZv5S/LHubB19cy4btu6hvakaC8UMrGDe0nJqB/aguL2XYwH6Mr6lg7JDynDctM2Nrwx5WbWlg1ebG6HlLI6s2NyDB1e+ewHlTD6a4SDTuiW5cf1y0jieWvc2EoRVcecp4Ljz2YMrLSkiljJWbd7LwrTpWbm5o+RFTXlZMdXkplf1LKAoB5fjxQ3LenNdsbeTpFZtZtKaOxbX1VPYrYcZhwzhxwhD2JFPUNzYzavAAjh5VhSTMjIVr6qhvbGbc0HIM+O6jy3l06YZW73vRsaP4t7MPY+euBJ+/dyGvbthBcZE4a8oI3jN5GDt2NbN9VzPlZSVUl5cyvLI/44eWM6yyH0++tokHF65l3vJNTKyp4J/eM5FbHllGdXkp37nkGJ5esZlHXl7P+vpdNO5JUiQ4dEQlx46tZlT1AKrKy+hXUsT2pmY21O/iocXr2LhjNwdX9ef4CUOYNGwgv3l2NZt37uaUSTXMX72VXc0pqgaU8rMr3sXJk4Yy99WNfHnWEjbv3E15WTE1A/tx1KhBTBtTzRmHj+CQ4QMxM3725EpuffTVVtdeXV7KuKEVJFMpVm1uZOfuRKvtlf1LmDJyEAPKijGD2m2NvLGpoWX7xJoKTjtsODd9aP9mlZW0wMym59wWM0DMN7PpIVAca2apMAn6CfuVogIodIDYnUhy3o+eYtCAUi48dhSzFtTyxsadPHTtqUwcNjDv8WbGc29u5a5nVjFn2Ub2JFMt2w4/qJL3HTGcRDL69TCwf0nLH3/ttiZWb2mktLiI8TXRDe2VddtZXFvH1oZoSo7tTc2srWsCYFD/EgZXlDG0ooz3HTGCC6YdTMPuJHf9fRWPvryBIRVljB9azpqtTSx/ewfQNsczoaaC0YMHUDWglOfe3MqmHbs584gRLF1Xz/r6XW2ubWRVf4ZX9mNxuPmmf7Sm33N4ZT+272pmV3OqzbHZhlf2Y/zQCrY17uH1jTuZOKyCqgGlLF23nT2JFKXFYszgcoqKRF0IyInsLFwwYlA/mvYk2b4r0er9S4uLWFffRPaf/oDSYqoGlLJhe+trHFbZj807d7fsP7Gmgmljqpk2tppjRldTUiwWr6ln3vKNPP7K2wzsV0LVgFLW1jVx0KD+TB4xkOryMpoTKVZtaeCtrY007kmSLf25lRYVRUWV/UvYtGM3OzLSXyQYPbiccUPL2VC/K/qMaiooKynitbd3kDIYUlHGB44cwZLaepau297y3pnXW1Kk6Fep0epvMW1gvxL+/cIjuXDaKNbV7+KeZ1fz2NINLTemqgGlTB1dxbbGPby8dnub4yfUVHDypKE89fpm3tra2GpbeVkxn5kxiXOOPog1W5t4duUWfvnMKopCGgf2K+Hr503h1Q07uO+Ft6hrbG659na+ag6u6s9Hjx/LP8+YSP/SYhavqeOKXzzHjl0JigSnTKrhsIMqGVxeyu5EikVr6lhSW099U+tpbUqKxKmH1PCJU8czY/Kwll/u9U3N3Proqzy5fBOnHz6M0w4dzq2PvsqqLQ2ccfhwHlv6NocfVMl5U0dS19jM+vpdLK6to3Zb9H/5nsk1VJeX8afF6/jQMQdz7emH8NbWKNBHQb+B4qIiJgwtZ+zQCoZWlFE1oJRNO3azcE0dyzdsJxkuvmZgv+jH1oiBvLGpgYVv1TG4vJTvXnpM7g8nj84IEH8BLiSqrK4hKmY63sxO2a8UFUChA8STr23iyjuf56BB/VtuID+74jjOPmrkPr+XmdGwJ8nmHbuZt3wjf1i0jkVr6igrKaJ6QGmbm2ll/xISSaOpObqplBSJI0YOYsSg/khQVlLEiROGcFr4tRvXsvXb+eurG9kd3nf4oP7MOHRYq2zzzt0J/mveCu56ZjXTxlTziVPGc9y4wby0tp5X12/nmDHVnDB+CEVF0S/vx1/ZwM5wQ6sqL+O9k2s4ZPhAEilj+YYdrW4WIwZFwaBfaTFLautYvKaelZt2smpLA4mU8clTJ/DBo0dSXCT2JFJs3rmbEYP6tyoLTn+W2xqinFtdYzN7kkmmjKzioKr+pFLGm+GmfPhBlRw0qD+S2NWcZG1dE3WNe9jW0BzlZrY0snnnbo4bO5jTDhtGymDe8o0sXlPHxGEDmTammqmjq1oVCWR7dcN2bp/7BvVNzfzDCWM484gRlBS3bU2+qzlJffjFumpLA29taaQ53Kh3J1Nsb2qmvqmZmoHRZzS+ppzxQysYPbicspLo/dK5rF8+/Sbl/UqYNrqK6eOHcPKkoZQWF2FmzF+9jade30z6/3z0kHKOG1vNxJqBLTe/5mSKusZmduyKbpYNu5PMfHgpL6zaxpEHD2LZ+igAnHpIDacdNpwZh9YwadjAluKrjTt28VJtPeVlJQwaUMLStdt5cOFaXli1lZMnDeWCaaMYP7ScVVsa2dqwmwumjWLEoNb1A2u2NnLb48vZk0jxrQuOZHhl/5bPaUvDHqoHlFJeVszuRJTWDdt3sXpLA2vrmnjX2MEcH/4Gs/++56/aygeOPIjhg3LXR+xORN/D7uZUS/1h3GK5+qZmPnvPAp5esYWrTp3Av519WJtc4Nvbd/G7+Wv49bOreXv7bj5/xiF88cxD26S1O3VGgKggmuu2iGgk1yrgHjPb0pkJPRCFDhDf+OPL/O/8NSy66SxWbmpgS8Nu3jM55wCI+2VPItXyj29mvL19N5t37mZU9QCqQxnjxh3RuknDBnZZPYZ7Z0qmjJ/OXcEfF6/jzCNG8I8nj2tTnu+ieof19bta/ajKpTmZonZbExNqKrooZfF1RoCYAKw3s11heQAwwsxWdWZCD0QhA4SZ8Z7vzOXwgyr5nyuPL8g5nHOuO3QUIOL2pP4dkFlQmQzr3hFee3sntduaeN8RI7o7Kc4512XiBogSM9uTXgiv3zFtJue8+jYApx82vJtT4pxzXSdugNgk6fz0gqQLgM2FSVLP89dlGzlq1KBO63jjnHO9QdzuvZ8G7pH0E6IZ39YAHy9YqnqQrQ17ePGtbXz+jMndnRTnnOtScWeUewM4SdJAoortHYVNVs/x11c3kjJ43xFevOSce2fJN5rrFWb2G0lfyloPgJl15hSkPc76+ia+/cirTKyp4KiDq7o7Oc4516Xy5SDSjXsPfCyIXqZpT5JP3T2fXc1J7v3UiT2qY4tzznWFfAFiUnh+xczeMc1azYwvz1rM0nXb+cWV05ncCWMlOedcb5OvFdO5kkqBG7siMT3FHxet4+El67n+rMM443Dv++Cce2fKl4N4lKg5a4WkzBG5RDSt9KCCpaybbG3Yw8yHX2HamGo+PWNS/gOcc66P6jAHYWZfNrMq4M9mNijjUdkXgwPAf/z5FbY3NfPtS45+R04Q4pxzabE6ypnZBYVOSE/w9IrNPPDiWj49YxKHH9Qn459zzsXWYYCQ9FR43iFpe3hOP9oOAt/2+LMlLZe0QtINObaPkzRH0hJJ8ySNzth2q6SXw+Oj+3Nx++qJV96mvKyYa884pCtO55xzPVq+IqZ3h+fKjKKlyjhFTJKKgduBc4ApwOWSsqc8ug2428ymAjOJ5ptA0geB44BpwInAlyUV/Cd9IpViQGmxD6XtnHPELGKSNElSv/D6NElfkFSd57ATgBVmtjIM7ncfkF1UNQWYE17Pzdg+BXjSzBJm1gAsBs6Ok9YDkUyZ1zs451wQd7C+3wNJSYcAvwAmAL/Nc8woojGb0mrDukyLgUvC64uASklDw/pzJJVLqgFOB8bETOt+SyQ9QDjnXFrcAJEyswTRTfwHZvZFIN9cm7nutNmzE10PzJC0EJgBrAUSZvY4MBt4BrgX+DuQyDoWSddImi9p/qZNm2JeSvuS5gHCOefS4gaIZkmXA1cCD4d1pXmOqaX1r/7RwLrMHcxsnZldbGbHAl8N6+rD881mNs3M3k8UbF7PPoGZ3WFm081s+rBhBz79pxcxOefcXnEDxCeBk4GbzezNMAXpb/Ic8wIwWdIESWXAZcBDmTtIqpGUTsONwJ1hfXEoakLSVGAq8HjMtO43DxDOObdX3OG+XwG+ACBpMFBpZt/Oc0xC0rXAY0AxcKeZLZU0E5hvZg8BpwG3SDLgb8DnwuGlwP+FUWO3A1eEIq6CSqaMEg8QzjkHxAwQkuYB54f9FxHNMPekmX2po+PMbDZRXULmupsyXs8CZuU4bhdRS6YulUgZRfIA4ZxzEL+IqcrMtgMXA780s3cBZxYuWd0jlTJKij1AOOccxA8QJZJGAh9hbyV1n5NIGcWeg3DOOSB+gJhJVJewwsxekDSRHK2KeruUN3N1zrkWcSupfwf8LmN5JXs7uPUZiaRRUhQ3ZjrnXN8Wt5K6P3A1cCTQP73ezK4qULq6RdIMjw/OOReJezv8NXAQ8AHgSaJObzsKlajuEjVz9QjhnHMQP0AcYmZfBxrM7C7gg8DRhUtW90ikjCKvg3DOOWAfhtoIz3WSjgKqgPEFSVE3SnlHOeecaxGrDgK4I/Sg/jrRcBkDgZs6PqT38Y5yzjm3V9xWTP8TXj4JTCxccrqX5yCcc26vDgOEpHxDaXy/c5PTvRKpFMXek9o554D8OYjKLklFD5H0ntTOOdeiwwBhZt/qqoT0BEnzIibnnEuLOyf1XZlzUEsaLOnOwiWreyST3szVOefS4jZznWpmdekFM9sGHFuYJHUfz0E459xecQNEUWjmCoCkIcRvIttr+Ixyzjm3V9yb/PeAZyTNAoxo2O+bC5aqbuIBwjnn9orbD+JuSfOBMwABF4dpSPuUhAcI55xrEbuYKASEPhcUMnkzV+ec28uHLs2QTJl3lHPOucADRIakD7XhnHMt4vaDuDXOut4uaV7E5JxzaXFzEO/Pse6cfAdJOlvSckkrJN2QY/s4SXMkLZE0T9LojG3fkbRU0jJJP5IKe+dOpQwzKPYJg5xzDsgTICR9RtJLwOHhJp5+vAm8lOfYYuB2okAyBbhc0pSs3W4D7jazqcBM4JZw7CnAqcBU4CjgeGDGPl/dPkikDIBijw/OOQfkb8X0W+ARoht3Zg5gh5ltzXPsCcAKM1sJIOk+4AJat4SaAnwxvJ4L/CG8NqK5r8uImtWWAm/nOd8BSVk6QHiEcM45yJODMLN6M1sF/BDYamarzWw10CzpxDzvPQpYk7FcG9ZlWgxcEl5fBFRKGmpmfycKGOvD4zEzWxbngvaX5yCcc661uLfD/wJ2Ziw3hHUdyVVnYFnL1wMzJC0kKkJaCyQkHQIcAYwmCipnSHpvmxNI10iaL2n+pk2b4l1JO5Ipz0E451ymuHdDmVnLzd3MUuQvnqoFxmQsjwbWZe5gZuvM7GIzOxb4alhXT5SbeNbMdprZTqJirpOyT2Bmd5jZdDObPmzYsJiXkls6QHgzV+eci8QNECslfUFSaXhcB6zMc8wLwGRJEySVAZcRzWfdQlKNpHQabgTSQ4i/RZSzKJFUSpS7KGgRUzpA+HDfzjkXiRsgPg2cQlQEVAucCFzT0QFmlgCuBR4jurnfb2ZLJc2UdH7Y7TRguaTXgBHsHQBwFvAGUUupxcBiM/tT3IvaH56DcM651uIO1reRKAewT8xsNjA7a91NGa9nEQWD7OOSwD/v6/kORCKVAvCOcs45F8TtSX1o6ND2clieKulrhU1a1wrxwUdzdc65IG4R08+J6giaAcxsCfuRo+jJ0jmIEh+szznngPgBotzMns9al+jsxHSndEe5Ii9ics45IH6A2CxpEqEfg6QPE3Vg6zMSXkntnHOtxJ0w6HPAHURjMq0F3gQ+VrBUdYNE0pu5OudcprwBIvRTmG5mZ0qqAIrMbEfhk9a10kVMnoNwzrlI3iKm0Gv62vC6oS8GB9hbxOQ5COeci8Stg3hC0vWSxkgakn4UNGVdLOV1EM4510rcOoirwvPnMtYZMLFzk9N99o7m6gHCOecgfh3EFWb2dBekp9ukcxDek9o55yJx6yBu64K0dKuWZq7eUc4554D4dRCPS7qk0PNCd6eW0Vz77iU659w+iVsH8SWgAkhKaiKaDMjMbFDBUtbF9o7m6hMGOeccxB/NtbLQCeluXkntnHOtxc1BEOZwSE/7Oc/MHi5MkrpHuqOcBwjnnIvEHe7728B1wCvhcV1Y12d4DsI551qLm4M4F5gWWjQh6S5gIXBDoRLW1ZLpCYM8QDjnHBC/FRNAdcbrqs5OSHdLhgmDvCe1c85F4uYgbgEWSppL1ILpvUQTCPUZ6RyEj8XknHORuK2Y7pU0DzieKEB8xcw2FDJhXc1zEM4511rcSuqLgEYze8jM/gjsknRhYZPWtbwOwjnnWotbB/ENM6tPL5hZHfCNwiSpeyR8LCbnnGslboDItV+cgf7OlrRc0gpJbVo8SRonaY6kJZLmSRod1p8uaVHGo+A5lnRP6mIfi8k554D4AWK+pO9LmiRpoqT/BBZ0dICkYuB24BxgCnC5pClZu90G3G1mU4GZRJXhmNlcM5tmZtOAM4BG4PHYV7Ufkp6DcM65VuIGiM8De4D/Be4Hmmg9N0QuJwArzGylme0B7gMuyNpnCjAnvJ6bYzvAh4FHzKwxZlr3S9J7UjvnXCtxWzE1sO+d4kYBazKWa4ETs/ZZDFwC/BC4CKiUNNTMtmTscxnw/VwnkHQNcA3A2LFj9zF5rSWTPqOcc85lKuTQpbnutJa1fD0wQ9JCYAawFki0vIE0EjgaeCzXCczsDjObbmbThw0bdkCJ9RyEc861Fnuwvv1QC4zJWB4NrMvcwczWARcDSBoIXJLZWgr4CPCgmTUXMJ1AVAdRJOjDU14459w+6TAHIenW8Hzpfrz3C8BkSRMklREVFT2U9f41YUpTiHpm35n1HpcD9+7HufdZImWee3DOuQz5ipjOlVTKfgyrYWYJ4Fqi4qFlwP1mtlTSzDB0OMBpwHJJrwEjgJvTx0saT5QDeXJfz70/Uh4gnHOulXxFTI8Cm4EKSdsJM8kRc0Y5M5sNzM5ad1PG61nArHaOXUVU0d0lEinzJq7OOZehwxyEmX3ZzKqAP5vZIDOrzHzuojR2iaTnIJxzrpW4zVwvkDSCaLA+gOfMbFPhktX1kimjpNjno3bOubS4g/VdCjwPXErUsuh5SR8uZMK6WiJlFHkRk3POtYjbzPVrwPFmthFA0jDgL7RTf9AbpVLmneSccy5D7MH60sEh2LIPx/YK3szVOedai5uDeFTSY+ztk/BRslon9XYp8wDhnHOZ4lZSf1nSxcC7iZq43mFmDxY0ZV0s4UVMzjnXSuyhNszsAeCBAqalW6VS5vNRO+dchj5Vj3AgEqmU5yCccy6DB4gg6c1cnXOuldhFTGHAvcOJhtpYHiYB6jOijnIeIJxzLi1WgJD0QeBnwBtEldQTJP2zmT1SyMR1Je8o55xzrcXNQXwPON3MVgBImgT8GegzASJl3orJOecyxa2D2JgODsFKYGN7O/dGiaT3g3DOuUwd5iBC3weApZJmA/cT1UFcSjQhUJ+RTBllJV5n75xzafmKmD6U8fptonmjATYBgwuSom6S9J7UzjnXSocBwsw+2VUJ6W4+H4RzzrUWtxXTMOBTwPjMYxBBH0UAABlUSURBVMzsqsIkq+slfagN55xrJW4rpj8C/0c0xHeycMnpPp6DcM651uIGiHIz+0pBU9LNPEA451xrcZvtPCzp3IKmpJtFAcJbMTnnXFrcO+J1REGiSdJ2STskbc93kKSzJS2XtELSDTm2j5M0R9ISSfMkjc7YNlbS45KWSXpF0vi4F7U/EinDR9pwzrm9YgUIM6s0syIzG2Bmg8LyoI6OkVQM3A6cA0wBLpc0JWu324C7zWwqMBO4JWPb3cB3zewI4AQK3DHPcxDOOddah3fEfL/aFRndzuYTgBVmtjIM7HcfcEHWPlOAOeH13PT2EEhKzOwJADPbaWaNHaXlQEUBopBncM653iXfLfG7kn4v6eOSjpQ0PBT9nCHp34GngSPaOXYUsCZjuTasy7QYuCS8vgiolDQUOBSok/SApIWSvhtyJAUTdZTzCOGcc2kd3hHN7FLg68BhRMVF/0fU5PWfgOXAGelf+TnkKtG3rOXrgRmSFhL10l4LJIhaV70nbD8emAh8os0JpGskzZc0f9OmTR1dSl7eD8I551rL28zVzF4Bvrof710LjMlYHg2sy3rvdcDFAJIGApeYWb2kWmChma0M2/4AnAT8Iuv4O4A7AKZPn54dfPZJIpnyZq7OOZehkGUqLwCTJU0Ikw1dBjyUuYOkGknpNNwI3Jlx7ODQgxvgDOCVAqaVlOEBwjnnMhQsQJhZArgWeAxYBtxvZkslzZR0ftjtNGC5pNeAEcDN4dgkUfHSHEkvERVX/bxQaYVoTmoPEM45t1fsKUf3h5nNBmZnrbsp4/UsYFY7xz4BTC1k+jKlUp6DcM65TLFyEKE56xWSbgrLYyWdUNikda1EKuWV1M45lyFuEdNPgZOBy8PyDqJWTX2CmZEyfE5q55zLELeI6UQzOy40R8XMtoWK5z4hmYoaQHkOwjnn9oqbg2gOHdUMWuaHSBUsVV0sEQJEkQcI55xrETdA/Ah4EBgu6WbgKeD/L1iquljKPAfhnHPZYhUxmdk9khYA7yNqcnqhmS0raMq6UDoH4a2YnHNur7wBInRkW2JmRwGvFj5JXS/lAcI559rIW8RkZilgsaSxXZCebpHwSmrnnGsjbiumkcBSSc8DDemVZnZ++4f0HkmvpHbOuTbiBohvFTQV3cybuTrnXFtxK6mflDSCaOhtgOfNrKAzvHWllhyEd5RzzrkWcYfa+AjwPHAp8BHgOUkfLmTCulJLDsInpXbOuRZxi5i+ChyfzjWEjnJ/oZ2B9nqbvc1cfUY555xLi3tHLMoqUtqyD8f2eOkcRLEXMTnnXIu4OYhHJT0G3BuWPwo8Upgkdb2k94Nwzrk24lZSf1nSxcC7iXpS32FmDxY0ZV3IA4RzzrUVK0BImgDMNrMHwvIASePNbFUhE9dVkj4Wk3POtRG3HuF3tB69NRnW9QnJVHRp3lHOOef2ihsgSsxsT3ohvO5D80FEz56DcM65veIGiE2SWobVkHQBsLkwSep6iZCD8DoI55zbK24rpk8D90j6CVEl9Rrg4wVLVRfzSmrnnGsrbiumN4CTJA0EZGY7CpusruUBwjnn2oo71MZ1kgYRjeT6n5JelHRWjOPOlrRc0gpJN+TYPk7SHElLJM2TNDpjW1LSovB4aF8ual95RznnnGsrbh3EVWa2HTgLGA58Evh2RweEOaxvB84BpgCXS5qStdttwN1mNhWYCdySsa3JzKaFR0GHFfcchHPOtRU3QKTvnOcCvzSzxRnr2nMCsMLMVoZWT/cBF2TtMwWYE17PzbG9S/hgfc4511bcALFA0uNEAeIxSZW07heRyyiiyuy02rAu02LgkvD6IqBS0tCw3F/SfEnPSrowZjr3S8KLmJxzro24rZiuBqYBK82sMdzEP5nnmFx3W8tavh74iaRPAH8D1gKJsG2sma2TNBH4q6SXQmX53hNI1wDXAIwdu/8zoqbMi5iccy5b3FZMKeDFjOUtRCO6dqQWGJOxPBpYl/W+64CLAUILqUvMrD5jG2a2UtI84Fjgjazj7wDuAJg+fXp28IktkfQA4Zxz2Qo5ZPcLwGRJEySVAZcBrVojSaqRlE7DjcCdYf1gSf3S+wCnAq8UKqFJz0E451wbBQsQZpYArgUeA5YB95vZUkkzM3plnwYsl/QaMAK4Oaw/ApgvaTFR5fW3zaxwAcJbMTnnXBtx6yDSzVZHZB5jZm91dIyZzQZmZ627KeP1LHLMSmdmzwBHx03bgfIA4ZxzbcUd7vvzwDeAt9nbesmAqQVKV5dqaebqU44651yLuDmI64DDQuV0n+PNXJ1zrq24P5nXAPWFTEh3SqUDhHeUc865FnFzECuBeZL+DOxOrzSz7xckVV3McxDOOddW3ADxVniU0YcmCkrzjnLOOddW3I5y3wIIQ2yYme0saKq6WLqjnM8o55xze8Ud7vsoSQuBl4GlkhZIOrKwSes6Pie1c861FbeS+g7gS2Y2zszGAf8K/LxwyepaSTPPPTjnXJa4AaLCzOamF8xsHlBRkBR1g0TKPPfgnHNZYrdikvR14Ndh+QrgzcIkqeulUp6DcM65bLFnlAOGAQ8AD4bX+Yb77jUSKfMmrs45lyVuK6ZtwBcKnJZuk0qZd5JzzrksHQYIST8ws3+R9CfaTvZDoeeK7ioJL2Jyzrk28uUg0nUOtxU6Id0pmTKKvIjJOeda6TBAmNmC8HKamf0wc5uk64AnC5WwrpT0HIRzzrURt5L6yhzrPtGJ6ehWSW/m6pxzbeSrg7gc+AdggqTM6UIryT8nda/hHeWcc66tfHUQzwDrgRrgexnrdwBLCpWorpZImQ/U55xzWfLVQawGVgMnd01yukcy6QHCOeeyxR2s7yRJL0jaKWmPpKSk7YVOXFdJmlHs040651wrce+KPwEuB14HBgD/BPy4UInqasmUUezxwTnnWok7FhNmtkJSsZklgV9KeqaA6epSUYDwCOGcc5ni3hUbJZUBiyR9R9IXiTGaq6SzJS2XtELSDTm2j5M0R9ISSfMkjc7aPkjSWkk/iZnO/ZJMGT7ShnPOtRY3QPwjUAxcCzQAY4BLOjpAUjFwO3AOMAW4XNKUrN1uA+42s6nATOCWrO3/Thd0xkukUpR4DsI551qJO1jf6vCyCfhWzPc+AVhhZisBJN0HXAC8krHPFOCL4fVc4A/pDZLeBYwAHgWmxzznfkmlfD5q55zLlq+j3EvkGKQvLfzyb88oYE3Gci1wYtY+i4lyIj8ELgIqJQ0FthH1u/hH4H0dpbEzJFIpykpiV8c459w7Qr674nnh+XPhOT1438eAxjzH5vpJnh1srgd+IukTwN+AtUAC+Cww28zWqINB9CRdA1wDMHbs2DzJaV/SPAfhnHPZ4nSUQ9KpZnZqxqYbJD1NVG/Qnlqiuoq00cC6rPdfB1wczjEQuMTM6iWdDLxH0meBgUCZpJ1mdkPW8XcQzZfN9OnT283p5JNMpTxAOOdclrjlKhWS3m1mTwFIOoX8rZheACZLmkCUM7iMaFynFpJqgK1mlgJuBO4EMLOPZezzCWB6dnDoTEmvg3DOuTbiBoirgTslVYXlOqJpSNtlZglJ1wKPEbWAutPMlkqaCcw3s4eA04BbJBlREdPn2n3DAkqmUj5Yn3POZYnbimkBcIykQYDMrD7mcbOB2Vnrbsp4PQuYlec9fgX8Ks759lfCh/t2zrk28rViusLMfiPpS1nrATCz7xcwbV0m5RMGOedcG/lyEOl6hspCJ6Q7JVJGsU856pxzreRrxfTf4Tlu57heKeXzQTjnXBv5iph+1NF2M/tC5yane/iEQc4511a+IqYFXZKKbpb0AOGcc23kK2K6q6sS0p18TmrnnGsrVjNXScOArxANrtc/vd7MzihQurpUMunNXJ1zLlvcMa7vAZYBE4hGc11F1FO6T/AchHPOtRU3QAw1s18AzWb2pJldBZxUwHR1Ke8o55xzbcUdaqM5PK+X9EGiQfdGd7B/r+Id5Zxzrq24AeI/wjhM/wr8GBjE3ol+ejUzC81cfUY555zLFDdAPBfGX6oHTi9gerpcKgwS7j2pnXOutbg/m5+R9LikqyUNLmiKulgyRIiSYg8QzjmXKVaAMLPJwNeAI4EFkh6WdEVBU9ZF0gGiyHMQzjnXSuyCdzN73sy+BJwAbAX6RCe6pIUchFdSO+dcK7EChKRBkq6U9AjwDLCeKFD0eslkyEF4gHDOuVbiVlIvBv4AzDSzvxcwPV0ukUoBnoNwzrlscQPERLNQFtPHlBQX8cGjRzK+Jt8U2845984Sd8rRPhkcAKoGlHL7x47r7mQ451yP473DnHPO5eQBwjnnXE5xWzF9J7RkKpU0R9LmvtIPwjnnXG5xcxBnmdl24DygFjgU+HK+gySdLWm5pBWSbsixfVwIOEskzZM0OmP9AkmLJC2V9Ol9uCbnnHOdIG6AKA3P5wL3mtnWfAdIKgZuB84hmmjocklTsna7DbjbzKYCM4Fbwvr1wClmNg04EbhB0sEx0+qcc64TxA0Qf5L0KjAdmBNmmNuV55gTgBVmttLM9gD3ARdk7TMFmBNez01vN7M9ZrY7rO+3D+l0zjnXSeKOxXQDcDIw3cyagQba3uyzjQLWZCzXhnWZFgOXhNcXAZWShgJIGiNpSXiPW81sXZy0Ouec6xxxK6kvBRJmlpT0NeA3QL4in1xdk7P7U1wPzJC0EJgBrAUSAGa2JhQ9HQJcKWlEjnRdI2m+pPmbNm2KcynOOediituT+utm9jtJ7wY+QFR38F9E9QPtqQXGZCyPJpqJrkXIFVwMIGkgcEmYd6LVPpKWAu8BZmVtuwO4Ixy/SdLqmNeTVgNs3sdjeqK+ch3Qd67Fr6Pn6SvX0tnXMa69DXEDRDI8fxD4LzP7o6Rv5jnmBWCypAlEOYPLgH/I3EFSDbDVzFLAjcCdYf1oYIuZNYX5J04Fvt/RycxsWMxryTz/fDObvq/H9TR95Tqg71yLX0fP01eupSuvI27l71pJ/w18BJgtKW/FsZklgGuBx4BlwP1mtlTSTEnnh91OA5ZLeg0YAdwc1h8BPCdpMfAkcJuZvbQP1+Wcc+4Axc1BfAQ4m+hGXSdpJDH6QZjZbGB21rqbMl7PIqvYKKx/ApgaM23OOecKIG4rpkbgDeADkq4FhpvZ4wVNWde4o7sT0En6ynVA37kWv46ep69cS5ddh+IM1CrpOuBTwANh1UXAHWb24wKmzTnnXDeKGyCWACebWUNYrgD+HpqhOuec64PiVlKLvS2ZCK979RRs+caJ6qlCB8K5kpaFcaquC+uHSHpC0uvheXB3pzUOScWSFkp6OCxPkPRcuI7/lVTW3WmMQ1K1pFmSXg3fzcm98TuR9MXwd/WypHsl9e8N34mkOyVtlPRyxrqcn78iPwr/+0sk9agJYdq5lu+Gv60lkh6UVJ2x7cZwLcslfaAz0xI3QPySqFXRN0Pz1meBX3RmQrpSzHGieqoE8K9mdgRwEvC5kPYbgDlmNplo+JLeEvSuI2rllnYr8J/hOrYBV3dLqvbdD4FHzexw4Biia+pV34mkUcAXiEZMOAooJmqe3hu+k18RNaTJ1N7nfw4wOTyuIerT1ZP8irbX8gRwVCi1eY2oWwDhf/8y4MhwzE/D/a1zmFmsB3Ac0R/PdcCxcY/riQ+iYUMey1i+Ebixu9O1n9fyR+D9wHJgZFg3Elje3WmLkfbRRP+4ZwAPE+VKNwMlub6nnvoABgFvEopsM9b3qu+EvcPjDCFq4fgwUcfYXvGdAOOBl/N9/sB/A5fn2q+nPLKvJWvbRcA94XWrexdRt4KTOysdeZu5SioCllj0i+LFfPv3ErnGieqoV3iPJGk8cCzwHDDCzNYDmNl6ScO7MWlx/QD4N6AyLA8F6izqQwO5x+/qiSYCm4BfSjoGWED0Q6pXfSdmtlbSbcBbQBPwONG19MbvBNr//NsbJ259F6dvf10F/G94PYqoRCetU7+fvEVMFvVyXixpbGedtAeIM05UjxaGJvk98C8WzdXRq0g6D9hoZgsyV+fYtTd8LyVEOez/MrNjiQaz7NHFSbmEMvoLgAlEY61VEBXHZOsN30lHeuvfGZK+SlTMfE96VY7dOu1a4naUGwkslfQ80R9/lAqz89s/pEfLO05UTyaplCg43GNm6abHb0saGX4pjQQ2dl8KYzkVOF/SuUB/omKaHwDVkkrCL9be8r3UArVm9lxYnkUUIHrbd3Im8KaZbQKQ9ABwCr3zO4H2P/9e+f8v6UqiSdveZ6E8iQJfS9xK6m+FhM0Evpfx6K1axokKLTIuAx7q5jTFIklEDQSWmVnm+FQPAVeG11cS1U30WGZ2o5mNNrPxRJ//X83sY0Tzgnw47NbjrwPAzDYAayQdFla9D3iFXvadEBUtnSSpPPydpa+j130nQXuf/0PAx0NrppOA+nRRVE8l6WzgK8D5FnVcTnsIuExSP0Xj3k0Gnu+0E+epKDkEODXH+vcCk7q7IucAK4HOJWoN8Abw1e5Ozz6k+91EWcglwKLwOJeo/H4O8Hp4HtLdad2HazoNeDi8nhj+wFcAvwP6dXf6Yl7DNGB++F7+AAzujd8J0Y/BV4GXgV8TTdjV478T4F6iOoRmol/VV7f3+RMVy9we/vdfImq11e3XkOdaVhDVm6T/53+Wsf9Xw7UsB87pzLR02FEutE3//8xsSdb66cA3zOxD7R7snHOuV8tXxDQ+OzgAmNl8omZYzjnn+qh8AaJ/B9sGdGZCnHPO9Sz5AsQLkj6VvVLS1UTto51zzvVR+eogRgAPAnvYGxCmA2XARRa13nDOOdcHxR3N9XTgqLC41Mz+WtBUOeec63ZxJwyaa2Y/Dg8PDi4nSSbpexnL1yv/3OVx3/tXkj6cf88DPs+lYTTWuTm2fTeMdPrd/XjfaaFTYI8laed+Hnfh/gx2ub/nc10nbkc55+LYDVwsqaa7E5JpH0e3vBr4rJmdnmPbPwPHmVne6XZzmEbUXyW20JGrN/yPXkg0KrLrY3rDH5/rPRJE0yF+MXtDdg4g/etR0mmSnpR0v6TXJH1b0sckPS/pJUmTMt7mTEn/F/Y7LxxfHH7ZvxDGyv/njPedK+m3RJ2hstNzeXj/lyXdGtbdRNQR8WfZuQRJDxGNTfScpI9KGibp9+G8L0g6Nex3gqRnFM1x8Yykw0Jv/ZnARyUtCsd/U9L1Ge//sqTx4bFM0k+JBsccI+ksSX+X9KKk34VxuAif1Svhum/LcY0zwvkWhfRUhvVfzvi8vpXri2xvH0kfD+sWS/q1pFOA84HvhvNMCo9HJS0I39fh4dgJ4TpekPTvuc7repju7jXoj77zAHYSjam0CqgCrge+Gbb9Cvhw5r7h+TSgjmi8r37AWuBbYdt1wA8yjn+U6EfNZKIepv2JxvP/WtinH1Fv5gnhfRuACTnSeTDRsBLDiMYj+ytwYdg2j3Z61qbTHF7/Fnh3eD2WaOgTwvWnh8Y+E/h9eP0J4CcZx38TuD5j+WWivkXjgRRwUlhfA/wNqAjLXwFuIhqSezl76xGrc6T3T4SREICB4VrPIgriCp/lw8B7s76TnPsQzTmwHKgJ+6V7Jmd/t3OAyeH1iUTDqEAY4iK8/lzm5+mPnvmIO1ifc7GY2XZJdxPNHdIU87AXLIyFI+kNomGmIfrln1nUc79Fowu/LmklcDjRzWxqRu6kiiiA7AGeN7M3c5zveGCe7R2U7h6iG+AfYqYXopv/FKllMM1B4Rd6FXCXpMlEQ6KU7sN7pq02s/QQzicRFd88Hc5VBvwd2A7sAv5H0p+JbuLZnga+H67vATOrlXQW0We2MOwzkOjz+lvGce3tcwwwy8w2A5jZ1uwThtzNKcDvMj6bfuH5VOCS8PrXRBMRuR7MA4QrhB8QFY/8MmNdglCkqejOkTlt5e6M16mM5RSt/0azm9wZ0a/cz5vZY5kbJJ1GxsjDWTpjutwioolZWgVBST8G5prZRYrm65jXzvEtn0eQ2Sk1M90CnjCzy7PfQNIJRAPqXQZcSzTxUgsz+3YIHucCz0o6M7zfLWb23x1cW859JH2B/ENJFxHNHzGtne29YlhtF/E6CNfpwi/L+2k9NeUq4F3h9QXs3y/rSyUVhXqJiUTFHY8Bn1E0BDqSDpVUked9ngNmSKoJFdiXA0/uY1oeJ7opE86bviFWERWTQVSslLaDvRMjQfR5HBeOPY6oWCyXZ4FTJR0S9i0P1zgQqDKz2cC/EFWCtyJpkpm9ZGa3EhW9HU70eV2VUY8xSm0nMmpvnznARyQNDeuHZF+bRXOTvCnp0rCPFE2iBFGO5rLw+mPtXK/rQTxAuEL5HlH5edrPiW7KzxOVS7f3674jy4lu5I8AnzazXcD/EA1J/aKiSd7/mzw541CcdSPRMNaLgRfNbF+HsP4CMD1U2L4CfDqs/w5wi6SnieZ0TptLVCS1SNJHiebzGCJpEfAZopGFc6V1E1GguVfSEqKAcTjRDfnhsO5JcjQMAP4lVH4vJirue8TMHieqP/m7pJeI5q7IDFy0t4+ZLQVuBp4M75kebv4+4MuhInwS0c3/6rDPUqIfBBDVKX1O0gtEgdT1cLE6yjnnnHvn8RyEc865nDxAOOecy8kDhHPOuZw8QDjnnMvJA4RzzrmcPEA455zLyQOEc865nDxAOOecy+n/AYUYg/41/7M1AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_DoS = RFECV(estimator=clf_DoS, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_DoS.fit(X_DoS_test, Y_DoS_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV DoS')\n",
    "plt.plot(range(1, len(rfecv_DoS.grid_scores_) + 1), rfecv_DoS.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_Probe = RFECV(estimator=clf_Probe, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_Probe.fit(X_Probe_test, Y_Probe_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV Probe')\n",
    "plt.plot(range(1, len(rfecv_Probe.grid_scores_) + 1), rfecv_Probe.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_R2L = RFECV(estimator=clf_R2L, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_R2L.fit(X_R2L_test, Y_R2L_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV R2L')\n",
    "plt.plot(range(1, len(rfecv_R2L.grid_scores_) + 1), rfecv_R2L.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_U2R = RFECV(estimator=clf_U2R, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_U2R.fit(X_U2R_test, Y_U2R_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV U2R')\n",
    "plt.plot(range(1, len(rfecv_U2R.grid_scores_) + 1), rfecv_U2R.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Random Forest Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DoS Features sorted by their rank:\n",
      "[(1, 'same_srv_rate'), (2, 'dst_host_srv_serror_rate'), (3, 'flag_SF'), (4, 'count'), (5, 'dst_host_same_srv_rate'), (6, 'dst_host_srv_count'), (7, 'dst_host_serror_rate'), (8, 'logged_in'), (9, 'dst_host_count'), (10, 'srv_serror_rate'), (11, 'service_http'), (12, 'serror_rate'), (13, 'flag_S0')]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "\n",
    "from sklearn.feature_selection import RFE\n",
    "clf1 = RandomForestClassifier(n_jobs=2, random_state=0)\n",
    "\n",
    "#rank all features, i.e continue the elimination until the last one\n",
    "rfe = RFE(clf1, n_features_to_select=1)\n",
    "rfe.fit(X_newDoS, Y_DoS.astype('int'))\n",
    "print (\"DoS Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_DoS)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Probe Features sorted by their rank:\n",
      "[(1, 'dst_host_same_src_port_rate'), (2, 'dst_host_diff_srv_rate'), (3, 'service_private'), (4, 'service_eco_i'), (5, 'dst_host_srv_count'), (6, 'dst_host_srv_diff_host_rate'), (7, 'dst_host_rerror_rate'), (8, 'dst_host_srv_rerror_rate'), (9, 'logged_in'), (10, 'rerror_rate'), (11, 'srv_rerror_rate'), (12, 'Protocol_type_icmp'), (13, 'flag_SF')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newProbe, Y_Probe.astype(int))\n",
    "print (\"Probe Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_Probe)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "R2L Features sorted by their rank:\n",
      "[(1, 'src_bytes'), (2, 'hot'), (3, 'dst_host_same_src_port_rate'), (4, 'service_ftp_data'), (5, 'dst_host_srv_diff_host_rate'), (6, 'dst_host_srv_count'), (7, 'service_ftp'), (8, 'dst_bytes'), (9, 'service_http'), (10, 'num_failed_logins'), (11, 'is_guest_login'), (12, 'flag_RSTO'), (13, 'service_imap4')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newR2L, Y_R2L.astype(int))\n",
    " \n",
    "print (\"R2L Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_R2L)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U2R Features sorted by their rank:\n",
      "[(1, 'num_file_creations'), (2, 'dst_host_count'), (3, 'dst_host_srv_count'), (4, 'hot'), (5, 'root_shell'), (6, 'dst_host_srv_diff_host_rate'), (7, 'dst_host_same_src_port_rate'), (8, 'service_ftp_data'), (9, 'num_shells'), (10, 'service_telnet'), (11, 'urgent'), (12, 'service_http'), (13, 'srv_diff_host_rate')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newU2R, Y_U2R.astype(int))\n",
    " \n",
    "print (\"U2R Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_U2R)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Recursive Feature Elimination, select 13 features each of 122 (Option 2: get 13 best features from 122 from RFE)¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "clf1 = RandomForestClassifier(n_jobs=2, random_state=0)\n",
    "rfe = RFE(estimator=clf1, n_features_to_select=13, step=1)\n",
    "rfe.fit(X_DoS, Y_DoS.astype(int))\n",
    "X_rfeDoS=rfe.transform(X_DoS)\n",
    "true=rfe.support_\n",
    "rfecolindex_DoS=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_DoS=list(colNames[i] for i in rfecolindex_DoS)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_Probe, Y_Probe.astype(int))\n",
    "X_rfeProbe=rfe.transform(X_Probe)\n",
    "true=rfe.support_\n",
    "rfecolindex_Probe=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_Probe=list(colNames[i] for i in rfecolindex_Probe)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_R2L, Y_R2L.astype(int))\n",
    "X_rfeR2L=rfe.transform(X_R2L)\n",
    "true=rfe.support_\n",
    "rfecolindex_R2L=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_R2L=list(colNames[i] for i in rfecolindex_R2L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "rfe.fit(X_U2R, Y_U2R.astype(int))\n",
    "X_rfeU2R=rfe.transform(X_U2R)\n",
    "true=rfe.support_\n",
    "rfecolindex_U2R=[i for i, x in enumerate(true) if x]\n",
    "rfecolname_U2R=list(colNames[i] for i in rfecolindex_U2R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Summary of Features selected by RFE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Features selected for DoS: ['src_bytes', 'dst_bytes', 'wrong_fragment', 'num_compromised', 'count', 'srv_count', 'same_srv_rate', 'dst_host_same_srv_rate', 'dst_host_serror_rate', 'dst_host_srv_serror_rate', 'Protocol_type_icmp', 'Protocol_type_tcp', 'flag_SF']\n",
      "\n",
      "Features selected for Probe: ['src_bytes', 'dst_bytes', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate', 'Protocol_type_tcp', 'service_eco_i', 'service_private']\n",
      "\n",
      "Features selected for R2L: ['duration', 'src_bytes', 'dst_bytes', 'hot', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'dst_host_serror_rate', 'service_ftp', 'service_ftp_data']\n",
      "\n",
      "Features selected for U2R: ['duration', 'src_bytes', 'dst_bytes', 'hot', 'root_shell', 'num_file_creations', 'dst_host_count', 'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'service_ftp_data']\n"
     ]
    }
   ],
   "source": [
    "print('Features selected for DoS:',rfecolname_DoS)\n",
    "print()\n",
    "print('Features selected for Probe:',rfecolname_Probe)\n",
    "print()\n",
    "print('Features selected for R2L:',rfecolname_R2L)\n",
    "print()\n",
    "print('Features selected for U2R:',rfecolname_U2R)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(113270, 13)\n",
      "(78999, 13)\n",
      "(68338, 13)\n",
      "(67395, 13)\n"
     ]
    }
   ],
   "source": [
    "print(X_rfeDoS.shape)\n",
    "print(X_rfeProbe.shape)\n",
    "print(X_rfeR2L.shape)\n",
    "print(X_rfeU2R.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Build RF model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Classifier is trained for all features and for reduced features, for later comparison."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The classifier model itself is stored in the clf variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "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=10,\n",
       "                       n_jobs=None, oob_score=False, random_state=0, verbose=0,\n",
       "                       warm_start=False)"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# all features\n",
    "clf1_DoS=RandomForestClassifier(random_state=0)\n",
    "clf1_Probe=RandomForestClassifier(random_state=0)\n",
    "clf1_R2L=RandomForestClassifier(random_state=0)\n",
    "clf1_U2R=RandomForestClassifier(random_state=0)\n",
    "clf1_DoS.fit(X_DoS, Y_DoS.astype(int))\n",
    "clf1_Probe.fit(X_Probe, Y_Probe.astype(int))\n",
    "clf1_R2L.fit(X_R2L, Y_R2L.astype(int))\n",
    "clf1_U2R.fit(X_U2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "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=10,\n",
       "                       n_jobs=None, oob_score=False, random_state=0, verbose=0,\n",
       "                       warm_start=False)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# selected features\n",
    "clf1_rfeDoS=RandomForestClassifier(random_state=0)\n",
    "clf1_rfeProbe=RandomForestClassifier(random_state=0)\n",
    "clf1_rfeR2L=RandomForestClassifier(random_state=0)\n",
    "clf1_rfeU2R=RandomForestClassifier(random_state=0)\n",
    "clf1_rfeDoS.fit(X_rfeDoS, Y_DoS.astype(int))\n",
    "clf1_rfeProbe.fit(X_rfeProbe, Y_Probe.astype(int))\n",
    "clf1_rfeR2L.fit(X_rfeR2L, Y_R2L.astype(int))\n",
    "clf1_rfeU2R.fit(X_rfeU2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Evaluation and Predictions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : DoS\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, ..., 0, 0, 0])"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Apply the classifier we trained to the test data (which it has never seen before)\n",
    "clf1_DoS.predict(X_DoS_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.6, 0.4],\n",
       "       [0.8, 0.2],\n",
       "       [0.8, 0.2],\n",
       "       [1. , 0. ],\n",
       "       [0.8, 0.2],\n",
       "       [0.8, 0.2],\n",
       "       [0.8, 0.2],\n",
       "       [0.8, 0.2],\n",
       "       [0.5, 0.5],\n",
       "       [0.8, 0.2]])"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# View the predicted probabilities of the first 10 observations\n",
    "clf1_DoS.predict_proba(X_DoS_test)[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9188</td>\n",
       "      <td>523</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>6901</td>\n",
       "      <td>559</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0    1\n",
       "Actual attacks              \n",
       "0                  9188  523\n",
       "1                  6901  559"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_DoS_pred=clf1_DoS.predict(X_DoS_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_DoS_test, Y_DoS_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : Probe\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9522</td>\n",
       "      <td>189</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1256</td>\n",
       "      <td>1165</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0     2\n",
       "Actual attacks               \n",
       "0                  9522   189\n",
       "2                  1256  1165"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_Probe_pred=clf1_Probe.predict(X_Probe_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_Probe_test, Y_Probe_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9711</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>2884</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0  3\n",
       "Actual attacks            \n",
       "0                  9711  0\n",
       "3                  2884  1"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_R2L_pred=clf1_R2L.predict(X_R2L_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_R2L_test, Y_R2L_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9711</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>67</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0\n",
       "Actual attacks         \n",
       "0                  9711\n",
       "4                    67"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_U2R_pred=clf1_U2R.predict(X_U2R_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_U2R_test, Y_U2R_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cross Validation: Accuracy, Precision, Recall, F-measure¶\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DoS¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99819 (+/- 0.00211)\n",
      "Precision: 0.99919 (+/- 0.00132)\n",
      "Recall: 0.99665 (+/- 0.00468)\n",
      "F-measure: 0.99792 (+/- 0.00244)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn import metrics\n",
    "accuracy = cross_val_score(clf1_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf1_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='precision')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf1_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='recall')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf1_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='f1')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99613 (+/- 0.00295)\n",
      "Precision: 0.99618 (+/- 0.00466)\n",
      "Recall: 0.99169 (+/- 0.00595)\n",
      "F-measure: 0.99391 (+/- 0.00465)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf1_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf1_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf1_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf1_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.98039 (+/- 0.00775)\n",
      "Precision: 0.97501 (+/- 0.00958)\n",
      "Recall: 0.96926 (+/- 0.01519)\n",
      "F-measure: 0.97205 (+/- 0.01121)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf1_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf1_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf1_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf1_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.99703 (+/- 0.00250)\n",
      "Precision: 0.94882 (+/- 0.12792)\n",
      "Recall: 0.82826 (+/- 0.15928)\n",
      "F-measure: 0.87118 (+/- 0.11935)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf1_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf1_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf1_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf1_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RFECV for illustration¶"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_DoS = RFECV(estimator=clf1_DoS, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_DoS.fit(X_DoS_test, Y_DoS_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV DoS')\n",
    "plt.plot(range(1, len(rfecv_DoS.grid_scores_) + 1), rfecv_DoS.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_Probe = RFECV(estimator=clf1_Probe, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_Probe.fit(X_Probe_test, Y_Probe_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV Probe')\n",
    "plt.plot(range(1, len(rfecv_Probe.grid_scores_) + 1), rfecv_Probe.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_R2L = RFECV(estimator=clf1_R2L, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_R2L.fit(X_R2L_test, Y_R2L_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV R2L')\n",
    "plt.plot(range(1, len(rfecv_R2L.grid_scores_) + 1), rfecv_R2L.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "rfecv_U2R = RFECV(estimator=clf1_U2R, step=1, cv=10, scoring='accuracy')\n",
    "rfecv_U2R.fit(X_U2R_test, Y_U2R_test)\n",
    "# Plot number of features VS. cross-validation scores\n",
    "plt.figure()\n",
    "plt.xlabel(\"Number of features selected\")\n",
    "plt.ylabel(\"Cross validation score (nb of correct classifications)\")\n",
    "plt.title('RFECV U2R')\n",
    "plt.plot(range(1, len(rfecv_U2R.grid_scores_) + 1), rfecv_U2R.grid_scores_)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# To procede with the data mining, the second option is considered as this uses RFE. From now on the number of features for every attack category is 13.\n",
    "#2. Recursive Feature Elimination for feature ranking (Option 1: get importance from previous selected)¶"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Naive Bayes Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DoS Features sorted by their rank:\n",
      "[(1, 'count'), (1, 'dst_host_count'), (1, 'dst_host_same_srv_rate'), (1, 'dst_host_serror_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_serror_rate'), (1, 'flag_S0'), (1, 'flag_SF'), (1, 'logged_in'), (1, 'same_srv_rate'), (1, 'serror_rate'), (1, 'service_http'), (1, 'srv_serror_rate')]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.feature_selection import RFE\n",
    "clf2 =GaussianNB()\n",
    "#rank all features, i.e continue the elimination until the last one\n",
    "rfe = RFE(clf2, n_features_to_select=13)\n",
    "rfe.fit(X_newDoS, Y_DoS.astype('int'))\n",
    "print (\"DoS Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_DoS)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Probe Features sorted by their rank:\n",
      "[(1, 'Protocol_type_icmp'), (1, 'dst_host_diff_srv_rate'), (1, 'dst_host_rerror_rate'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'dst_host_srv_rerror_rate'), (1, 'flag_SF'), (1, 'logged_in'), (1, 'rerror_rate'), (1, 'service_eco_i'), (1, 'service_private'), (1, 'srv_rerror_rate')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newProbe, Y_Probe.astype(int))\n",
    "print (\"Probe Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_Probe)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "R2L Features sorted by their rank:\n",
      "[(1, 'dst_bytes'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'flag_RSTO'), (1, 'hot'), (1, 'is_guest_login'), (1, 'num_failed_logins'), (1, 'service_ftp'), (1, 'service_ftp_data'), (1, 'service_http'), (1, 'service_imap4'), (1, 'src_bytes')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newR2L, Y_R2L.astype(int))\n",
    " \n",
    "print (\"R2L Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_R2L)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U2R Features sorted by their rank:\n",
      "[(1, 'dst_host_count'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'hot'), (1, 'num_file_creations'), (1, 'num_shells'), (1, 'root_shell'), (1, 'service_ftp_data'), (1, 'service_http'), (1, 'service_telnet'), (1, 'srv_diff_host_rate'), (1, 'urgent')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newU2R, Y_U2R.astype(int))\n",
    " \n",
    "print (\"U2R Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_U2R)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Building the Naive Bayes Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GaussianNB(priors=None, var_smoothing=1e-09)"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# all features\n",
    "clf2_DoS=GaussianNB()\n",
    "clf2_Probe=GaussianNB()\n",
    "clf2_R2L=GaussianNB()\n",
    "clf2_U2R=GaussianNB()\n",
    "clf2_DoS.fit(X_DoS, Y_DoS.astype(int))\n",
    "clf2_Probe.fit(X_Probe, Y_Probe.astype(int))\n",
    "clf2_R2L.fit(X_R2L, Y_R2L.astype(int))\n",
    "clf2_U2R.fit(X_U2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Evaluation and Predictions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, ..., 0, 0, 0])"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf2_DoS.predict(X_DoS_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [1., 0.],\n",
       "       [0., 1.],\n",
       "       [0., 1.]])"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# View the predicted probabilities of the first 10 observations\n",
    "clf2_DoS.predict_proba(X_DoS_test)[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9447</td>\n",
       "      <td>264</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>3701</td>\n",
       "      <td>3759</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0     1\n",
       "Actual attacks               \n",
       "0                  9447   264\n",
       "1                  3701  3759"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_DoS_pred=clf2_DoS.predict(X_DoS_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_DoS_test, Y_DoS_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>76</td>\n",
       "      <td>9635</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>201</td>\n",
       "      <td>2220</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks    0     2\n",
       "Actual attacks              \n",
       "0                   76  9635\n",
       "2                  201  2220"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_Probe_pred=clf2_Probe.predict(X_Probe_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_Probe_test, Y_Probe_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9711</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>2885</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0\n",
       "Actual attacks         \n",
       "0                  9711\n",
       "3                  2885"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_R2L_pred=clf2_R2L.predict(X_R2L_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_R2L_test, Y_R2L_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Predicted attacks</th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Actual attacks</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>9711</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>67</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Predicted attacks     0\n",
       "Actual attacks         \n",
       "0                  9711\n",
       "4                    67"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_U2R_pred=clf2_U2R.predict(X_U2R_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_U2R_test, Y_U2R_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cross Validation: Accuracy, Precision, Recall, F-measure¶\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.86733 (+/- 0.01474)\n",
      "Precision: 0.98822 (+/- 0.01158)\n",
      "Recall: 0.70308 (+/- 0.03682)\n",
      "F-measure: 0.82145 (+/- 0.02371)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn import metrics\n",
    "accuracy = cross_val_score(clf2_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf2_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='precision')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf2_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='recall')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf2_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='f1')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.97898 (+/- 0.01148)\n",
      "Precision: 0.97323 (+/- 0.00912)\n",
      "Recall: 0.96051 (+/- 0.03039)\n",
      "F-measure: 0.96654 (+/- 0.01926)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf2_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf2_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf2_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf2_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.93561 (+/- 0.01004)\n",
      "Precision: 0.89097 (+/- 0.01370)\n",
      "Recall: 0.95508 (+/- 0.00770)\n",
      "F-measure: 0.91620 (+/- 0.01202)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf2_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf2_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf2_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf2_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.97259 (+/- 0.01121)\n",
      "Precision: 0.60132 (+/- 0.02891)\n",
      "Recall: 0.97911 (+/- 0.04265)\n",
      "F-measure: 0.66067 (+/- 0.04235)\n"
     ]
    }
   ],
   "source": [
    "accuracy = cross_val_score(clf2_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf2_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf2_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf2_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# KNeighbour Classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DoS Features sorted by their rank:\n",
      "[(1, 'count'), (1, 'dst_host_count'), (1, 'dst_host_same_srv_rate'), (1, 'dst_host_serror_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_serror_rate'), (1, 'flag_S0'), (1, 'flag_SF'), (1, 'logged_in'), (1, 'same_srv_rate'), (1, 'serror_rate'), (1, 'service_http'), (1, 'srv_serror_rate')]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.feature_selection import RFE\n",
    "clf3 = KNeighborsClassifier()\n",
    "#rank all features, i.e continue the elimination until the last one\n",
    "rfe = RFE(clf3, n_features_to_select=13)\n",
    "rfe.fit(X_newDoS, Y_DoS.astype('int'))\n",
    "print (\"DoS Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_DoS)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Probe Features sorted by their rank:\n",
      "[(1, 'Protocol_type_icmp'), (1, 'dst_host_diff_srv_rate'), (1, 'dst_host_rerror_rate'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'dst_host_srv_rerror_rate'), (1, 'flag_SF'), (1, 'logged_in'), (1, 'rerror_rate'), (1, 'service_eco_i'), (1, 'service_private'), (1, 'srv_rerror_rate')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newProbe, Y_Probe.astype(int))\n",
    "print (\"Probe Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_Probe)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "R2L Features sorted by their rank:\n",
      "[(1, 'dst_bytes'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'flag_RSTO'), (1, 'hot'), (1, 'is_guest_login'), (1, 'num_failed_logins'), (1, 'service_ftp'), (1, 'service_ftp_data'), (1, 'service_http'), (1, 'service_imap4'), (1, 'src_bytes')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newR2L, Y_R2L.astype(int))\n",
    " \n",
    "print (\"R2L Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_R2L)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U2R Features sorted by their rank:\n",
      "[(1, 'dst_host_count'), (1, 'dst_host_same_src_port_rate'), (1, 'dst_host_srv_count'), (1, 'dst_host_srv_diff_host_rate'), (1, 'hot'), (1, 'num_file_creations'), (1, 'num_shells'), (1, 'root_shell'), (1, 'service_ftp_data'), (1, 'service_http'), (1, 'service_telnet'), (1, 'srv_diff_host_rate'), (1, 'urgent')]\n"
     ]
    }
   ],
   "source": [
    "rfe.fit(X_newU2R, Y_U2R.astype(int))\n",
    " \n",
    "print (\"U2R Features sorted by their rank:\")\n",
    "print (sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), newcolname_U2R)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Building the KNearistNeighbour Classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# all features\n",
    "clf3_DoS=KNeighborsClassifier()\n",
    "clf3_Probe=KNeighborsClassifier()\n",
    "clf3_R2L=KNeighborsClassifier()\n",
    "clf3_U2R=KNeighborsClassifier()\n",
    "clf3_DoS.fit(X_DoS, Y_DoS.astype(int))\n",
    "clf3_Probe.fit(X_Probe, Y_Probe.astype(int))\n",
    "clf3_R2L.fit(X_R2L, Y_R2L.astype(int))\n",
    "clf3_U2R.fit(X_U2R, Y_U2R.astype(int))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Evaluation and Predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Confusion Matrices : DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf3_DoS.predict(X_DoS_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# View the predicted probabilities of the first 10 observations\n",
    "clf3_DoS.predict_proba(X_DoS_test)[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y_DoS_pred=clf3_DoS.predict(X_DoS_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_DoS_test, Y_DoS_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y_Probe_pred=clf3_Probe.predict(X_Probe_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_Probe_test, Y_Probe_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y_R2L_pred=clf3_R2L.predict(X_R2L_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_R2L_test, Y_R2L_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrices : U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y_U2R_pred=clf3_U2R.predict(X_U2R_test)\n",
    "# Create confusion matrix\n",
    "pd.crosstab(Y_U2R_test, Y_U2R_pred, rownames=['Actual attacks'], colnames=['Predicted attacks'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cross Validation: Accuracy, Precision, Recall, F-measure¶\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DoS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn import metrics\n",
    "accuracy = cross_val_score(clf3_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf3_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='precision')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf3_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='recall')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf3_DoS, X_DoS_test, Y_DoS_test, cv=10, scoring='f1')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Probe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "accuracy = cross_val_score(clf3_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf3_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf3_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf3_Probe, X_Probe_test, Y_Probe_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# R2L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "accuracy = cross_val_score(clf3_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf3_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf3_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf3_R2L, X_R2L_test, Y_R2L_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# U2R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "accuracy = cross_val_score(clf3_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='accuracy')\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (accuracy.mean(), accuracy.std() * 2))\n",
    "precision = cross_val_score(clf3_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='precision_macro')\n",
    "print(\"Precision: %0.5f (+/- %0.5f)\" % (precision.mean(), precision.std() * 2))\n",
    "recall = cross_val_score(clf3_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='recall_macro')\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (recall.mean(), recall.std() * 2))\n",
    "f = cross_val_score(clf3_U2R, X_U2R_test, Y_U2R_test, cv=10, scoring='f1_macro')\n",
    "print(\"F-measure: %0.5f (+/- %0.5f)\" % (f.mean(), f.std() * 2))\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
