diff --git a/Data_Cleaning_EDA.ipynb b/Data_Cleaning_EDA.ipynb new file mode 100644 index 0000000..4f8aa6f --- /dev/null +++ b/Data_Cleaning_EDA.ipynb @@ -0,0 +1,952 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Reading the csv file in us_acci dataframe\n", + "us_acci = spark.read.csv(get_training_filename('US_Accidents.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shape is (981531, 49)\n" + ] + } + ], + "source": [ + "# Shape of the spark dataframe\n", + "\n", + "print('Shape is ',(us_acci.count(),len(us_acci.columns)))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Renaming the columns names which contain brackets for ease of usage\n", + "\n", + "us_acci = us_acci.select('*').withColumnRenamed('Distance(mi)','Distance')\\\n", + " .withColumnRenamed('Temperature(F)', 'Temperature').withColumnRenamed('Wind_Chill(F)', 'Wind_Chill')\\\n", + " .withColumnRenamed('Humidity(%)', 'Humidity').withColumnRenamed('Pressure(in)', 'Pressure')\\\n", + " .withColumnRenamed('Visibility(mi)', 'Visibility').withColumnRenamed('Wind_Speed(mph)', 'Wind_Speed')\\\n", + " .withColumnRenamed('Precipitation(in)', 'Precipitation')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "root\n", + " |-- ID: string (nullable = true)\n", + " |-- Source: string (nullable = true)\n", + " |-- TMC: double (nullable = true)\n", + " |-- Severity: integer (nullable = true)\n", + " |-- Start_Time: timestamp (nullable = true)\n", + " |-- End_Time: timestamp (nullable = true)\n", + " |-- Start_Lat: double (nullable = true)\n", + " |-- Start_Lng: double (nullable = true)\n", + " |-- End_Lat: double (nullable = true)\n", + " |-- End_Lng: double (nullable = true)\n", + " |-- Distance: double (nullable = true)\n", + " |-- Description: string (nullable = true)\n", + " |-- Number: double (nullable = true)\n", + " |-- Street: string (nullable = true)\n", + " |-- Side: string (nullable = true)\n", + " |-- City: string (nullable = true)\n", + " |-- County: string (nullable = true)\n", + " |-- State: string (nullable = true)\n", + " |-- Zipcode: string (nullable = true)\n", + " |-- Country: string (nullable = true)\n", + " |-- Timezone: string (nullable = true)\n", + " |-- Airport_Code: string (nullable = true)\n", + " |-- Weather_Timestamp: timestamp (nullable = true)\n", + " |-- Temperature: double (nullable = true)\n", + " |-- Wind_Chill: double (nullable = true)\n", + " |-- Humidity: double (nullable = true)\n", + " |-- Pressure: double (nullable = true)\n", + " |-- Visibility: double (nullable = true)\n", + " |-- Wind_Direction: string (nullable = true)\n", + " |-- Wind_Speed: double (nullable = true)\n", + " |-- Precipitation: double (nullable = true)\n", + " |-- Weather_Condition: string (nullable = true)\n", + " |-- Amenity: boolean (nullable = true)\n", + " |-- Bump: boolean (nullable = true)\n", + " |-- Crossing: boolean (nullable = true)\n", + " |-- Give_Way: boolean (nullable = true)\n", + " |-- Junction: boolean (nullable = true)\n", + " |-- No_Exit: boolean (nullable = true)\n", + " |-- Railway: boolean (nullable = true)\n", + " |-- Roundabout: boolean (nullable = true)\n", + " |-- Station: boolean (nullable = true)\n", + " |-- Stop: boolean (nullable = true)\n", + " |-- Traffic_Calming: boolean (nullable = true)\n", + " |-- Traffic_Signal: boolean (nullable = true)\n", + " |-- Turning_Loop: boolean (nullable = true)\n", + " |-- Sunrise_Sunset: string (nullable = true)\n", + " |-- Civil_Twilight: string (nullable = true)\n", + " |-- Nautical_Twilight: string (nullable = true)\n", + " |-- Astronomical_Twilight: string (nullable = true)\n", + "\n" + ] + } + ], + "source": [ + "# Schema of dataframe with datatypes of all columns\n", + "\n", + "us_acci.printSchema()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Summary of all numerical variables in the dataset to find the skewness, outliers, mean, median\n", + "\n", + "us_acci.describe().toPandas()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Columns to be dropped initially as a list\n", + "drop_col = ['ID','End_Lat','End_Lng','Description','Number','Street','Zipcode','Airport_Code','Country','Weather_Timestamp','Wind_Chill','Turning_Loop']" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping columns from the original dataset\n", + "\n", + "us_acci = us_acci.drop(*(drop_col))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+\n", + "|Source| TMC|Severity|Start_Time|End_Time|Start_Lat|Start_Lng|Distance|Side|City|County|State|Timezone|Temperature|Humidity|Pressure|Visibility|Wind_Direction|Wind_Speed|Precipitation|Weather_Condition|Amenity|Bump|Crossing|Give_Way|Junction|No_Exit|Railway|Roundabout|Station|Stop|Traffic_Calming|Traffic_Signal|Sunrise_Sunset|Civil_Twilight|Nautical_Twilight|Astronomical_Twilight|\n", + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+\n", + "| 0|240595| 0| 0| 0| 0| 0| 0| 0| 30| 0| 0| 1069| 18494| 19485| 15870| 21643| 14882| 145268| 658958| 21750| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 37| 37| 37| 37|\n", + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking null values in all the columns\n", + "\n", + "from pyspark.sql.functions import isnan, isnull, when, count, col\n", + "\n", + "us_acci.select([count(when(isnull(c), c)).alias(c) for c in us_acci.columns]).show()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Replacing same Wind_Direction named with different string N and North same\n", + "\n", + "us_acci = us_acci.withColumn('Wind_Direction', when(us_acci.Wind_Direction == 'E', 'East')\\\n", + " .when(us_acci.Wind_Direction == 'W', 'West')\\\n", + " .when(us_acci.Wind_Direction == 'N', 'North')\\\n", + " .when(us_acci.Wind_Direction == 'S', 'South')\\\n", + " .when(us_acci.Wind_Direction == 'VAR', 'Variable')\\\n", + " .when(us_acci.Wind_Direction == 'CALM', 'Calm')\\\n", + " .otherwise(us_acci.Wind_Direction))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Replacing same Weather_Condition named with different string Light Rain Shower and Light Rain Showers same\n", + "\n", + "us_acci = us_acci.withColumn('Weather_Condition', when(us_acci.Weather_Condition == 'Light Rain Shower', 'Light Rain Showers')\\\n", + " .when(us_acci.Weather_Condition == 'Light Snow Shower', 'Light Snow Showers')\\\n", + " .when(us_acci.Weather_Condition == 'Rain Shower', 'Rain Showers')\\\n", + " .otherwise(us_acci.Weather_Condition))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping Null rows from City Column as there are only 30 rows with City = Null\n", + "\n", + "us_acci = us_acci.where(col(\"city\").isNotNull())" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping Null rows from Timezone Column \n", + "\n", + "us_acci = us_acci.where(col(\"Timezone\").isNotNull())" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Clipping Temperature extreme values to suppress outliers\n", + "\n", + "lower = -30\n", + "upper = 115\n", + "us_acci = us_acci.withColumn('Temperature', when(us_acci.Temperature > upper, upper)\\\n", + " .when(us_acci.Temperature < lower, lower).otherwise(us_acci.Temperature).alias('Temperature'))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# Distance > 100 rows dropped\n", + "us_acci = us_acci.where(us_acci.Distance <100)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Clipping Visibility extreme values to suppress outliers \n", + "\n", + "upper = 20\n", + "us_acci = us_acci.withColumn('Visibility', when(us_acci.Visibility > upper, upper)\\\n", + " .otherwise(us_acci.Visibility).alias('Visibility'))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# Clipping Wind_Speed extreme values to suppress outliers \n", + "upper = 40\n", + "us_acci = us_acci.withColumn('Wind_Speed', when(us_acci.Wind_Speed > upper, upper)\\\n", + " .otherwise(us_acci.Wind_Speed).alias('Wind_Speed'))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Replacing Null values in Precipitation with 0\n", + "\n", + "us_acci = us_acci.withColumn('Precipitation', when(us_acci.Precipitation.isNull(), 0).otherwise(us_acci.Precipitation))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "#replacing missing values in categorical attributes with the mode of the corresponding variables\n", + "\n", + "for col_name in ['Wind_Direction', 'Weather_Condition']:\n", + " common = us_acci.dropna().groupBy(col_name).agg(fn.count('*')).orderBy('count(1)', ascending = False).first()[col_name]\n", + " us_acci = us_acci.withColumn(col_name, when(isnull(col_name), common).otherwise(us_acci[col_name]))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "#replacing missing values in numerical attributes with the median of the corresponding variables\n", + "\n", + "for col_name in ['Temperature', 'Humidity', 'Pressure', 'Visibility', 'Wind_Speed']:\n", + " median = us_acci.dropna().approxQuantile(col_name, [0.5], 0.00)[0]\n", + " us_acci = us_acci.withColumn(col_name, when(isnull(col_name), median).otherwise(us_acci[col_name]))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Removing Null values in last 4 columns \n", + "\n", + "us_acci = us_acci.filter(us_acci.Sunrise_Sunset.isNotNull())\n", + "\n", + "us_acci = us_acci.filter(us_acci.Civil_Twilight.isNotNull())\n", + "\n", + "us_acci = us_acci.filter(us_acci.Nautical_Twilight.isNotNull())\n", + "\n", + "us_acci = us_acci.filter(us_acci.Astronomical_Twilight.isNotNull())" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Adding Month of Year, Day of Week , Week of Year and Hour of the Day Column from Start Time\n", + "\n", + "us_acci = us_acci.withColumn(\"Start_Time\",to_timestamp(col(\"Start_Time\"))).withColumn(\"month_of_year\", date_format(col(\"Start_Time\"), \"MMMM\")).withColumn(\"day_of_week\", date_format(col(\"Start_Time\"), \"EEEE\")).withColumn(\"hour_day\", date_format(col(\"Start_Time\"), \"H\")).withColumn(\"week_of_year\", date_format(col(\"Start_Time\"), \"w\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+-------------+-----------+--------+------------+\n", + "|Source| TMC|Severity|Start_Time|End_Time|Start_Lat|Start_Lng|Distance|Side|City|County|State|Timezone|Temperature|Humidity|Pressure|Visibility|Wind_Direction|Wind_Speed|Precipitation|Weather_Condition|Amenity|Bump|Crossing|Give_Way|Junction|No_Exit|Railway|Roundabout|Station|Stop|Traffic_Calming|Traffic_Signal|Sunrise_Sunset|Civil_Twilight|Nautical_Twilight|Astronomical_Twilight|month_of_year|day_of_week|hour_day|week_of_year|\n", + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+-------------+-----------+--------+------------+\n", + "| 0|240120| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|\n", + "+------+------+--------+----------+--------+---------+---------+--------+----+----+------+-----+--------+-----------+--------+--------+----------+--------------+----------+-------------+-----------------+-------+----+--------+--------+--------+-------+-------+----------+-------+----+---------------+--------------+--------------+--------------+-----------------+---------------------+-------------+-----------+--------+------------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking null values in all the columns\n", + "\n", + "from pyspark.sql.functions import isnan, isnull, when, count, col\n", + "\n", + "us_acci.select([count(when(isnull(c), c)).alias(c) for c in us_acci.columns]).show()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shape is (980416, 41)\n" + ] + } + ], + "source": [ + "# Shape of the spark dataframe\n", + "\n", + "print('Shape is ',(us_acci.count(),len(us_acci.columns)))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "us_acci.toPandas().to_csv(\"Us_clean.csv\",header=True,index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# EDA" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Converting spark dataframe to Pandas DF for EDA\n", + "\n", + "Us_acci_pd = us_acci.toPandas()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "# Monthly Accident count showing how distribution of accidents on 12 months of the year\n", + "\n", + "month_lst = ['January','February','March','April','May','June','July','August','September','October','November','December']\n", + "Us_acci_pd.groupby(['Severity', 'month_of_year']).size().reset_index().pivot(columns='Severity', index='month_of_year', values=0).reindex(month_lst).plot(kind='bar', stacked=True, title='Monthly Accident count for the year for each severity',)\n", + "display()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Daily Accident count showing how distribution of accidents on 7 days of the week\n", + "\n", + "weekday_lst = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']\n", + "Us_acci_pd.groupby(['Severity', 'day_of_week']).size().reset_index().pivot(columns='Severity', index='day_of_week',values=0).reindex(weekday_lst).plot(kind='bar', stacked=True,title='Daily Accident count for the week for each severity')\n", + "display()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Day light savings in USA bi-annually for the weeks 11 and 45 rise is seen as compared to previous weeks 10 & 44 for March & November respectively\n", + "\n", + "col = ['10','11','12','44','45','46']\n", + "newcol = Us_acci_pd[Us_acci_pd.week_of_year.isin(col)]" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# For Day light Savings checking\n", + "day_acci = newcol.groupby(['Severity', 'week_of_year']).size().reset_index().pivot(columns='Severity', index='week_of_year', values=0).plot(kind='bar', stacked=True,title='Day Light Savings Week Comparison of Accidents')\n", + "display(day_acci)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "subset=['Amenity', 'Bump', 'Crossing',\n", + " 'Give_Way', 'Junction', 'No_Exit', 'Railway', 'Roundabout', 'Station',\n", + " 'Stop', 'Traffic_Calming', 'Traffic_Signal', 'Turning_Loop',\n", + " 'Sunrise_Sunset', 'Civil_Twilight', 'Nautical_Twilight',\n", + " 'Astronomical_Twilight']" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "subset.remove(\"Turning_Loop\")" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "# Severity as a percentage on y axis showing how severe the accidents can be considering the various variables \n", + "\n", + "fig,ax=plt.subplots(4,4,figsize=(20,30))\n", + "for i in range(len(subset)):\n", + " df_plot = Us_acci_pd.groupby([subset[i], \"Severity\"]).size().reset_index().pivot(columns=subset[i], index=\"Severity\", values=0)\n", + " df_plot.div(df_plot.sum(axis=1), axis=0).plot(kind='bar', stacked=True,ax=ax[int(i/4),i-int(i/4)*4])\n", + "display()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "# Sunrise Sunset for Day & Night comparison of Severity \n", + "\n", + "df_plot = Us_acci_pd.groupby([\"Sunrise_Sunset\",\"Civil_Twilight\"]).size().reset_index().pivot(columns=\"Sunrise_Sunset\", index= \"Civil_Twilight\", values=0)\n", + "display(df_plot.div(df_plot.sum(axis=1), axis=0).plot(kind='bar', stacked=True,title='Sunrise Sunset for Day & Night comparison of Severity'))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "fig,ax=plt.subplots(1,figsize=(20,10))\n", + "sns.scatterplot(x='Start_Lng', y='Start_Lat', data=Us_acci_pd, hue='Severity',palette='RdYlGn_r',ax=ax)\n", + "ax.xlabel('Longitude')\n", + "ax.ylabel('Latitude)')\n", + "ax.set_title('US Map showing severity of accidents by their categories')\n", + "plt.show()\n", + "display()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# Accident count showing how distribution of accidents on each hour days of the day for the whole 24 hours\n", + "\n", + "hour_lst = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23']\n", + "\n", + "\n", + "display(Us_acci_pd.groupby(['Severity', 'hour_day']).size().reset_index().pivot(columns='Severity', index='hour_day', values=0).reindex(hour_lst).plot(kind='bar', stacked=True,figsize=(10,7),title='Hourly accident count for each severity throughout 24 hours of a day'))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# Accidents count by each state and for each state count by severity of accidents\n", + "\n", + "display(pd.crosstab(columns=Us_acci_pd['Severity'],\n", + " index=Us_acci_pd['State']).plot(kind='bar',stacked=True,figsize=(16,8),color=['purple','orange','blue','red','green'],title='State Wise Accident count for each severity along with total count'))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "# Percent of severity\n", + "f,ax=plt.subplots(1,2,figsize=(12,8))\n", + "Us_acci_pd['Severity'].value_counts().plot.pie(explode=[0,0,0,0.2],autopct='%1.1f%%',ax=ax[0],shadow=False)\n", + "ax[0].set_title('Percentage Severity Distribution')\n", + "ax[0].set_ylabel('Count')\n", + "display(sns.countplot('Severity',data=Us_acci_pd,ax=ax[1],order=Us_acci_pd['Severity'].value_counts().index))\n", + "ax[1].set_title('Count of Severity')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "# plot a bar plot to visualize to see which states have the highest number of accidents\n", + "top_ten_cities = Us_acci_pd['State'].value_counts().head(10)\n", + "display(top_ten_cities.plot.bar(width=0.5,edgecolor='k',align='center',linewidth=2,title='10 US States with the Highest Number of Accidents',figsize=(16,7)))\n", + "plt.xlabel('States',fontsize=20)\n", + "plt.ylabel('Number of Accidents',fontsize=20)\n", + "ax.tick_params(labelsize=20)\n", + "plt.grid()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "# plot a bar plot to visualize to see which cities have the highest number of accidents\n", + "top_ten_cities = Us_acci_pd['City'].value_counts().head(10)\n", + "display(top_ten_cities.plot.bar(width=0.5,edgecolor='k',align='center',linewidth=2,title='10 US Cities with the Highest Number of Accidents',figsize=(16,7)))\n", + "plt.xlabel('Cities',fontsize=20)\n", + "plt.ylabel('Number of Accidents',fontsize=20)\n", + "ax.tick_params(labelsize=20)\n", + "plt.grid()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "# Accidents based on the side of the driving Left & Right USA Right side driving \n", + "\n", + "Side_lst = ['R','L']\n", + "display(Us_acci_pd.groupby(['Severity', 'Side']).size().reset_index().pivot(columns='Severity', index='Side',values=0).reindex(Side_lst).plot(kind='bar', stacked=True,title='Accidents Severity based on Right or Left Side of Driving'))" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(Us_acci_pd.boxplot(column=['Distance']))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "display(Us_acci_pd.boxplot(column=['Temperature']))" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "display(Us_acci_pd.boxplot(column=['Wind_Speed']))" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "display(Us_acci_pd.boxplot(column=['Humidity']))" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "display(Us_acci_pd.boxplot(column=['Pressure']))" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "display(Us_acci_pd.boxplot(column=['Visibility']))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# Univariate histogram of Temp \n", + "\n", + "var = 'Temperature'\n", + "x = Us_acci_pd[var]\n", + "\n", + "bins = np.arange(-30, 120,10.0)\n", + "\n", + "plt.hist(x, bins, alpha=0.8, histtype='bar', color='gold',\n", + " ec='black')\n", + "\n", + "plt.xlabel(var)\n", + "plt.ylabel('count')\n", + "plt.xticks(bins)\n", + "display(plt.show())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "# Univariate Analysis of Wind_Speed\n", + "\n", + "var = 'Wind_Speed'\n", + "x = Us_acci_pd[var]\n", + "\n", + "bins = np.arange(0, 100,5.0)\n", + "\n", + "plt.hist(x, bins, alpha=0.8, histtype='bar', color='gold',\n", + " ec='black')\n", + "\n", + "plt.xlabel(var)\n", + "plt.ylabel('count')\n", + "plt.xticks(bins)\n", + "display(plt.show())" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + }, + "name": "Data_Cleaning_Project_IST718 (5) (1)", + "notebookId": 1278832175434352 + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/IST718_USAccidents_Project_Report.pdf b/IST718_USAccidents_Project_Report.pdf new file mode 100644 index 0000000..236e178 Binary files /dev/null and b/IST718_USAccidents_Project_Report.pdf differ diff --git a/LR_Binary.ipynb b/LR_Binary.ipynb new file mode 100644 index 0000000..0bc509d --- /dev/null +++ b/LR_Binary.ipynb @@ -0,0 +1,725 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# importing required libraries\n", + "\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "spark = SparkSession.builder.getOrCreate()\n", + "from sklearn.metrics import classification_report\n", + "sc = spark.sparkContext\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import StringIndexer, VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Reading the the csv file in us_acci dataframe\n", + "us_train = spark.read.csv(get_training_filename('USAccident_train_OHE.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Reading the the csv file in us_acci dataframe\n", + "us_test = spark.read.csv(get_training_filename('USAccident_validation_OHE.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Converts the train data with Severity 3 and 4 to 1 and rest to 0\n", + "us_train=us_train.withColumn(\"Severity\",when(((us_train[\"Severity\"]==4) | (us_train[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Converts the test data with Severity 3 and 4 to 1 and rest to 0\n", + "us_test=us_test.withColumn(\"Severity\",when(((us_test[\"Severity\"]==4) | (us_test[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Declaring the vector assembler\n", + "va = VectorAssembler().setInputCols([i for i in us_train.columns if i!='Severity']).setOutputCol('features')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Centering the data\n", + "center = feature.StandardScaler(withMean=True, withStd=False, inputCol='features', outputCol='centered_features')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Converting the categorical columns with string to numerical labels\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LR Binary Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Create initial LogisticRegression model\n", + "lr_w = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")\n", + "\n", + "# Train model with Training Data\n", + "lrModel_w = Pipeline(stages=[label_stringIdx,va, center, lr_w])\n", + "\n", + "# Fits the model\n", + "lr_fit_w = lrModel_w.fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Performs the prediiction on test set\n", + "pred_lrb = lr_fit_w.transform(us_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7213747454175152\n" + ] + } + ], + "source": [ + "# Caculates the accuracy for binary data\n", + "true_labels=us_test.toPandas()[\"Severity\"]\n", + "binary_prediction=lr_fit_w.transform(us_test).select(\"prediction\").collect()\n", + "binary_true_labels=us_test.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Area Under ROC 0.7621852339529867\n" + ] + } + ], + "source": [ + "# Using the evaluator to calculate the AUC ROC\n", + "evaluator_lrb = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "print('Test Area Under ROC', evaluator_lrb.evaluate(pred_lrb))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training set areaUnderROC: 0.7621682343009717\n" + ] + } + ], + "source": [ + "trainingSummary = lr_fit_w.stages[-1].summary\n", + "roc = trainingSummary.roc.toPandas()\n", + "plt.plot(roc['FPR'],roc['TPR'])\n", + "plt.ylabel('False Positive Rate')\n", + "plt.xlabel('True Positive Rate')\n", + "plt.title('ROC Curve')\n", + "plt.grid(True)\n", + "plt.show()\n", + "print('Training set areaUnderROC: ' + str(trainingSummary.areaUnderROC))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lr_fit_w.stages[-1].getRegParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lr_fit_w.stages[-1].getElasticNetParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_lrb=(pred_lrb).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.91 0.81 131790\n", + " 1 0.65 0.34 0.44 64610\n", + "\n", + " micro avg 0.72 0.72 0.72 196400\n", + " macro avg 0.69 0.62 0.63 196400\n", + "weighted avg 0.71 0.72 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification report for calculating the metrics\n", + "print(classification_report(y_pred=prediction_lrb,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# stores all the co-efficients of the logistic regression\n", + "coef_L1_m=lr_fit_w.stages[-1].coefficients.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# makes a datafram of the coefficients\n", + "feat_imp_tuned_lrt = pd.DataFrame(list(zip([i for i in us_train.columns if i!='Severity'], coef_L1_m)),\n", + " columns = ['column', 'weight']).sort_values('weight')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features are 120\n", + "Eliminated features out of 120 are 0\n" + ] + } + ], + "source": [ + "# Printing the number of feature eliminated\n", + "coef_L1_m = np.absolute(coef_L1_m)\n", + "print('Total number of features are',len(coef_L1_m))\n", + "sorted_abs = np.sort(coef_L1_m)\n", + "weights_notzero = sorted_abs[sorted_abs == 0]\n", + "nonzero_weights = len(sorted_abs[sorted_abs == 0])\n", + "print('Eliminated features out of ' + str(len(coef_L1_m)) + ' are', len(weights_notzero))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LR Binary Grid Search Model" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "lr_new = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# Define a grid for tuning the algorithm\n", + "#paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01, 0.8,0.03]).addGrid(lr_new.elasticNetParam, [0.1,0.4,0.7]).build()\n", + "paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01]).addGrid(lr_new.elasticNetParam, [0.1]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Making the pipeline for prediction\n", + "cvModel_lrmu = Pipeline(stages=[label_stringIdx,va,center,lr_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Defining a evaluator for evaluating our prediction\n", + "evaluator_lrbt = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Defining the cross validator for model\n", + "cv = CrossValidator(estimator=cvModel_lrmu, estimatorParamMaps=paramGrid_lr, evaluator=evaluator_lrbt, numFolds=5).fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Makes prediction on test set\n", + "pred_lrbt = cv.transform(us_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Area Under ROC 0.7615211426502622\n" + ] + } + ], + "source": [ + "evaluator_lrb = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "print('Test Area Under ROC', evaluator_lrb.evaluate(pred_lrbt))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training set areaUnderROC: 0.7616980707233938\n" + ] + } + ], + "source": [ + "trainingSummary_t = cv.bestModel.stages[-1].summary\n", + "roc = trainingSummary_t.roc.toPandas()\n", + "plt.plot(roc['FPR'],roc['TPR'])\n", + "plt.ylabel('False Positive Rate')\n", + "plt.xlabel('True Positive Rate')\n", + "plt.title('ROC Curve')\n", + "plt.show()\n", + "print('Training set areaUnderROC: ' + str(trainingSummary_t.areaUnderROC))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.01" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv.bestModel.stages[-1].getRegParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv.bestModel.stages[-1].getElasticNetParam()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cv.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_lrbt=(pred_lrbt).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.73 0.92 0.81 131790\n", + " 1 0.66 0.31 0.42 64610\n", + "\n", + " micro avg 0.72 0.72 0.72 196400\n", + " macro avg 0.69 0.62 0.62 196400\n", + "weighted avg 0.71 0.72 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_lrbt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7195977596741344\n" + ] + } + ], + "source": [ + "# calculates the accuracy\n", + "true_labels=us_test.toPandas()[\"Severity\"]\n", + "evaluator_lrbt.evaluate(pred_lrbt)\n", + "binary_prediction=pred_lrbt.select(\"prediction\").collect()\n", + "binary_true_labels=us_test.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# stores all coefficients of the LR model\n", + "coef_L1_m=cv.bestModel.stages[-1].coefficients.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Makes a dataframe of the variables and their respective coefficients\n", + "feat_imp_tuned_lrt = pd.DataFrame(list(zip([i for i in us_train.columns if i!='Severity'], coef_L1_m)),\n", + " columns = ['column', 'weight']).sort_values('weight')" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features are 120\n", + "Eliminated features out of 120 are 28\n" + ] + } + ], + "source": [ + "# Shows the number of features that our LR model eliminated\n", + "coef_L1_m = np.absolute(coef_L1_m)\n", + "print('Total number of features are',len(coef_L1_m))\n", + "sorted_abs = np.sort(coef_L1_m)\n", + "weights_notzero = sorted_abs[sorted_abs == 0]\n", + "nonzero_weights = len(sorted_abs[sorted_abs == 0])\n", + "print('Eliminated features out of ' + str(len(coef_L1_m)) + ' are', len(weights_notzero))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/LR_Multiclass.ipynb b/LR_Multiclass.ipynb new file mode 100644 index 0000000..cac68a9 --- /dev/null +++ b/LR_Multiclass.ipynb @@ -0,0 +1,583 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# import the requied libraries\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import StringIndexer\n", + "from sklearn.metrics import classification_report\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "from pyspark.ml.classification import LogisticRegression\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "from pyspark.mllib.evaluation import MulticlassMetrics\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# importing the train data\n", + "us_train = spark.read.csv(get_training_filename('USAccident_train_OHE.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# importing the test data\n", + "us_test = spark.read.csv(get_training_filename('USAccident_validation_OHE.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we have converted class 2,3,4 to 0,1,2 for avoiding error while calculating the evaluation metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==2,0).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==2,0).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==3,1).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==3,1).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==4,2).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==4,2).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Declaring the vector assembler\n", + "va = VectorAssembler().setInputCols([i for i in us_train.columns if i!='Severity']).setOutputCol('features')" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Centering our data for logistic regression model\n", + "center = feature.StandardScaler(withMean=True, withStd=False, inputCol='features', outputCol='centered_features',)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Converting the labels from string to integers\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Create initial LogisticRegression model\n", + "lr = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")\n", + "\n", + "# Train model with Training Data\n", + "lrModel = Pipeline(stages=[label_stringIdx,va, center, lr])\n", + "\n", + "lr_fit = lrModel.fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating a multiclass evaluator\n", + "evaluator_mul = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7213798370672098\n" + ] + } + ], + "source": [ + "print(\"Accuracy:\",evaluator_mul.evaluate(lr_fit.transform(us_test)))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lr_fit.stages[-1].getElasticNetParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lr_fit.stages[-1].getRegParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_lrm=(lr_fit.transform(us_test)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.91 0.82 131790\n", + " 1 0.64 0.36 0.46 58617\n", + " 2 0.54 0.11 0.18 5993\n", + "\n", + " micro avg 0.72 0.72 0.72 196400\n", + " macro avg 0.64 0.46 0.49 196400\n", + "weighted avg 0.70 0.72 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "# prints the classification report for the evaluating our model\n", + "print(classification_report(y_pred=prediction_lrm,y_true=true_labels))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LR Multiclass Grid Search Model " + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "lr_new = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating a grid for tuning our model\n", + "#paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01, 0.04,0.07]).addGrid(lr_new.elasticNetParam, [0.2,0.5,0.8]).build()\n", + "paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01]).addGrid(lr_new.elasticNetParam, [0.2]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# Creates the pipeline for the model\n", + "cvModel_lrmu = Pipeline(stages=[label_stringIdx,va,center,lr_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# define the evaluator for checking the accuracy of our model\n", + "evaluator_mul = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a cross validator of 6 folds\n", + "cv = CrossValidator(estimator=cvModel_lrmu, estimatorParamMaps=paramGrid_lr, evaluator=evaluator_mul, numFolds=5,seed=42).fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cv.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.2" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv.bestModel.stages[-1].getElasticNetParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.01" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv.bestModel.stages[-1].getRegParam()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7184317718940937\n" + ] + } + ], + "source": [ + "print(\"Accuracy:\",evaluator_mul.evaluate(cv.bestModel.transform(us_test)))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# stores the LR co-efficients of all the variable\n", + "coeft_L1_m=cv.bestModel.stages[-1].coefficientMatrix.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features are 120\n", + "Eliminated features out of 120 are 105\n" + ] + } + ], + "source": [ + "# prints the total no of features eliminated\n", + "coef_L1_mul=cv.bestModel.stages[-1].coefficientMatrix.toArray()\n", + "coeft_L1_mb = np.squeeze(coeft_L1_m)\n", + "coef_one_b = coeft_L1_m[:][0]\n", + "coef_two_b = coeft_L1_m[:][1]\n", + "coef_three_b = coeft_L1_m[:][2]\n", + "coef_one_b = np.absolute(coef_one_b)\n", + "coef_two_b = np.absolute(coef_two_b)\n", + "coef_three_b = np.absolute(coef_three_b)\n", + "\n", + "print('Total number of features are',len(coef_three_b))\n", + "\n", + "sorted_abs = np.sort(coef_three_b)\n", + "weights_notzero = sorted_abs[sorted_abs == 0]\n", + "nonzero_weights = len(sorted_abs[sorted_abs == 0])\n", + "\n", + "print('Eliminated features out of ' + str(len(coef_three_b)) +' are', nonzero_weights)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# gets the prediction by running on our test set\n", + "prediction_lrt=(cv.bestModel.transform(us_test)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "# stores the true label for using it to print the classification report below\n", + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.91 0.82 131790\n", + " 1 0.64 0.36 0.46 58617\n", + " 2 0.54 0.11 0.18 5993\n", + "\n", + " micro avg 0.72 0.72 0.72 196400\n", + " macro avg 0.64 0.46 0.49 196400\n", + "weighted avg 0.70 0.72 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_lrm,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/LR_Multiclass_Bal .ipynb b/LR_Multiclass_Bal .ipynb new file mode 100644 index 0000000..de405bb --- /dev/null +++ b/LR_Multiclass_Bal .ipynb @@ -0,0 +1,1059 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "from pyspark.ml.classification import LogisticRegression\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import StringIndexer, VectorAssembler\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#Loading Train Data\n", + "\n", + "us_train = spark.read.csv(get_training_filename('USAccident_train_bal_cat.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#Loading Test Data\n", + "\n", + "us_test = spark.read.csv(get_training_filename('USAccident_val_bal_cate.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 3|234445|\n", + "| 4|219519|\n", + "| 2|263497|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in training dataset\n", + "\n", + "us_train.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 3| 58339|\n", + "| 4| 6121|\n", + "| 2|131724|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in testing dataset\n", + "\n", + "us_test.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for test dataset\n", + "\n", + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==2,0).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for train dataset\n", + "\n", + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==2,0).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for test dataset\n", + "\n", + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==3,1).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for train dataset\n", + "\n", + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==3,1).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for test dataset\n", + "\n", + "us_test=us_test.withColumn(\"Severity\",when(us_test[\"Severity\"]==4,2).otherwise(us_test[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for train dataset\n", + "\n", + "us_train=us_train.withColumn(\"Severity\",when(us_train[\"Severity\"]==4,2).otherwise(us_train[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Vector Assembler to convert all features except Severity to a single column features for feeding it to input of model\n", + "\n", + "va = VectorAssembler().setInputCols([i for i in us_train.columns if i!='Severity']).setOutputCol('features')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard Scaler to standardize data for the Logistic Regression\n", + "\n", + "center = feature.StandardScaler(withMean=True, withStd=False, inputCol='features', outputCol='centered_features')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# String Indexer to assign target Variable Severity name Label needed for the model to predict\n", + "\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Regression Multiclass Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# Create initial LogisticRegression model\n", + "lr = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")\n", + "\n", + "# LR model pipeline \n", + "\n", + "lrModel = Pipeline(stages=[label_stringIdx,va, center, lr])\n", + "\n", + "# Fir the training data using the LR model \n", + "\n", + "lr_fit = lrModel.fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Evaluator for Evaluating the model performance\n", + "\n", + "evaluator_mul = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy is 0.5680891408065898\n" + ] + } + ], + "source": [ + "# Accuracy calculation for the model on test data\n", + "\n", + "print(\"Accuracy is\",evaluator_mul.evaluate(lr_fit.transform(us_test)))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_lrm=(lr_fit.transform(us_test)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.89 0.48 0.62 131724\n", + " 1 0.51 0.74 0.61 58339\n", + " 2 0.14 0.93 0.24 6121\n", + "\n", + " accuracy 0.57 196184\n", + " macro avg 0.51 0.71 0.49 196184\n", + "weighted avg 0.75 0.57 0.60 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_lrm,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [], + "source": [ + "# Weights/coefficients for All variables assigned by LR Model \n", + "\n", + "coef_L1_mul=lr_fit.stages[-1].coefficientMatrix.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [], + "source": [ + "# Combining the 3 arrays of coefficient matrix to 1 array\n", + "\n", + "coeft_L1_mb = np.squeeze(coeft_L1_m)" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "# Extract 1st array of coefficients with features equal to number of columns\n", + "\n", + "coef_one_b = coeft_L1_m[:][0]" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [], + "source": [ + "# Extract 2nd array of coefficients with features equal to number of columns\n", + "\n", + "coef_two_b = coeft_L1_m[:][1]" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "# Extract 3rd array of coefficients with features equal to number of columns\n", + "\n", + "coef_three_b = coeft_L1_m[:][2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Number of Features Eliminated by L1 Regularization for Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features for 1st class are 119\n", + "Total number of features for 2nd class are 119\n", + "Total number of features for 3rd class are 119\n", + "Eliminated features for 1st class out of 119 are 60\n", + "Eliminated features for 2nd class out of 119 are 84\n", + "Eliminated features for 3rd class out of 119 are 64\n" + ] + } + ], + "source": [ + "# Taking the absolute value of the weights and calculating how many features were eliminated by the model for each class each array\n", + "\n", + "coef_one_b = np.absolute(coef_one_b)\n", + "coef_two_b = np.absolute(coef_two_b)\n", + "coef_three_b = np.absolute(coef_three_b)\n", + "\n", + "print('Total number of features for 1st class are',len(coef_one_b))\n", + "print('Total number of features for 2nd class are',len(coef_two_b))\n", + "print('Total number of features for 3rd class are',len(coef_three_b))\n", + "\n", + "sorted_abs_1 = np.sort(coef_one_b)\n", + "sorted_abs_2 = np.sort(coef_two_b)\n", + "sorted_abs_3 = np.sort(coef_three_b)\n", + "\n", + "weights_notzero_1 = sorted_abs_1[sorted_abs_1 == 0]\n", + "nonzero_weights_1 = len(sorted_abs_1[sorted_abs_1 == 0])\n", + "\n", + "weights_notzero_2 = sorted_abs_2[sorted_abs_2 == 0]\n", + "nonzero_weights_2 = len(sorted_abs_2[sorted_abs_2 == 0])\n", + "\n", + "weights_notzero_3 = sorted_abs_3[sorted_abs_3 == 0]\n", + "nonzero_weights_3 = len(sorted_abs_3[sorted_abs_3 == 0])\n", + "\n", + "print('Eliminated features for 1st class out of ' + str(len(coef_one_b)) +' are', nonzero_weights_1)\n", + "print('Eliminated features for 2nd class out of ' + str(len(coef_two_b)) +' are', nonzero_weights_2)\n", + "print('Eliminated features for 3rd class out of ' + str(len(coef_three_b)) +' are', nonzero_weights_3)" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": {}, + "outputs": [], + "source": [ + "# Pandas dataframe of weights of variables with variable names to find which variables are eliminated for 1st class\n", + "\n", + "feat_imp_tuned_lrb1 = pd.DataFrame(list(zip([i for i in us_train.columns if i!='Severity'], coef_one_b)),\n", + " columns = ['column', 'weight']).sort_values('weight')" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
columnweight
0Hour_Index_80.0
85clear0.0
49day_of_week_Index_30.0
48day_of_week_Index_40.0
47day_of_week_Index_10.0
86whirl0.0
88light0.0
84cloud0.0
89heavy0.0
90thunderstorm0.0
\n", + "
" + ], + "text/plain": [ + " column weight\n", + "0 Hour_Index_8 0.0\n", + "85 clear 0.0\n", + "49 day_of_week_Index_3 0.0\n", + "48 day_of_week_Index_4 0.0\n", + "47 day_of_week_Index_1 0.0\n", + "86 whirl 0.0\n", + "88 light 0.0\n", + "84 cloud 0.0\n", + "89 heavy 0.0\n", + "90 thunderstorm 0.0" + ] + }, + "execution_count": 123, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Sample of 10 features eliminated by the Logistic Regression Model after L1 Regularization for class 1\n", + "\n", + "feat_imp_tuned_lrb1[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LR Multiclass Grid Search Model " + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Logistic Regression Pipeline initialization\n", + "\n", + "lr_new = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Grid Search for tuning the hyper parameters of Logistic Regression Model\n", + "\n", + "paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01, 0.04,0.07]).addGrid(lr_new.elasticNetParam, [0.2,0.5,0.8]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating pipeline to be used for fitting the training data\n", + "\n", + "cvModel_lrmu = Pipeline(stages=[label_stringIdx,va,center,lr_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Multiclass Evaluator for evaluating the model performance\n", + "\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "\n", + "evaluator_mul = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross validator pipeline initialization for 5-fold cross validation and fitting the train data\n", + "\n", + "cv = CrossValidator(estimator=cvModel_lrmu, estimatorParamMaps=paramGrid_lr, evaluator=evaluator_mul, numFolds=5,seed=42).fit(us_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='LogisticRegression_63e671446ece', name='aggregationDepth', doc='suggested depth for treeAggregate (>= 2).'): 2,\n", + " Param(parent='LogisticRegression_63e671446ece', name='elasticNetParam', doc='the ElasticNet mixing parameter, in range [0, 1]. For alpha = 0, the penalty is an L2 penalty. For alpha = 1, it is an L1 penalty.'): 0.2,\n", + " Param(parent='LogisticRegression_63e671446ece', name='featuresCol', doc='features column name.'): 'centered_features',\n", + " Param(parent='LogisticRegression_63e671446ece', name='fitIntercept', doc='whether to fit an intercept term.'): True,\n", + " Param(parent='LogisticRegression_63e671446ece', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='LogisticRegression_63e671446ece', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='LogisticRegression_63e671446ece', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='LogisticRegression_63e671446ece', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='LogisticRegression_63e671446ece', name='standardization', doc='whether to standardize the training features before fitting the model.'): True,\n", + " Param(parent='LogisticRegression_63e671446ece', name='threshold', doc='Threshold in binary classification prediction, in range [0, 1]. If threshold and thresholds are both set, they must match.e.g. if threshold is p, then thresholds must be equal to [1-p, p].'): 0.5,\n", + " Param(parent='LogisticRegression_63e671446ece', name='family', doc='The name of family which is a description of the label distribution to be used in the model. Supported options: auto, binomial, multinomial'): 'auto',\n", + " Param(parent='LogisticRegression_63e671446ece', name='maxIter', doc='max number of iterations (>= 0).'): 100,\n", + " Param(parent='LogisticRegression_63e671446ece', name='regParam', doc='regularization parameter (>= 0).'): 0.01,\n", + " Param(parent='LogisticRegression_63e671446ece', name='tol', doc='the convergence tolerance for iterative algorithms (>= 0).'): 1e-06}" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper Parameters \n", + "\n", + "cv.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy is 0.5427251967540676\n" + ] + } + ], + "source": [ + "# Accuracy of the model on the testing data\n", + "\n", + "print(\"Accuracy is\",evaluator_mul.evaluate(cv.bestModel.transform(us_test)))" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [], + "source": [ + "# Coefficient matrix from Logistic Regression for each variable weight\n", + "\n", + "coeft_L1_m=cv.bestModel.stages[-1].coefficientMatrix.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [], + "source": [ + "# Combining the 3 arrays of coefficient matrix to 1 array\n", + "\n", + "coeft_L1_m = np.squeeze(coeft_L1_m)" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [ + "#Extract 1st array of coefficients with features equal to number of columns\n", + "\n", + "coef_one = coeft_L1_m[:][0]" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [], + "source": [ + "# Extract 2nd array of coefficients with features equal to number of columns\n", + "\n", + "coef_two = coeft_L1_m[:][1]" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [], + "source": [ + "# Extract 3rd array of coefficients with features equal to number of columns\n", + "\n", + "coef_three = coeft_L1_m[:][2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Number of Features Eliminated by L1 Regularization for Grid Model" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features for 1st class are 119\n", + "Total number of features for 2nd class are 119\n", + "Total number of features for 3rd class are 119\n", + "Eliminated features for 1st class out of 119 are 60\n", + "Eliminated features for 2nd class out of 119 are 84\n", + "Eliminated features for 3rd class out of 119 are 64\n" + ] + } + ], + "source": [ + "# Taking the absolute value of the weights and calculating how many features were eliminated by the model for each class each array\n", + "\n", + "coef_one = np.absolute(coef_one)\n", + "coef_two = np.absolute(coef_two)\n", + "coef_three = np.absolute(coef_three)\n", + "\n", + "print('Total number of features for 1st class are',len(coef_one))\n", + "print('Total number of features for 2nd class are',len(coef_two))\n", + "print('Total number of features for 3rd class are',len(coef_three))\n", + "\n", + "sorted_abs_1 = np.sort(coef_one)\n", + "sorted_abs_2 = np.sort(coef_two)\n", + "sorted_abs_3 = np.sort(coef_three)\n", + "\n", + "weights_notzero_1 = sorted_abs_1[sorted_abs_1 == 0]\n", + "nonzero_weights_1 = len(sorted_abs_1[sorted_abs_1 == 0])\n", + "\n", + "weights_notzero_2 = sorted_abs_2[sorted_abs_2 == 0]\n", + "nonzero_weights_2 = len(sorted_abs_2[sorted_abs_2 == 0])\n", + "\n", + "weights_notzero_3 = sorted_abs_3[sorted_abs_3 == 0]\n", + "nonzero_weights_3 = len(sorted_abs_3[sorted_abs_3 == 0])\n", + "\n", + "print('Eliminated features for 1st class out of ' + str(len(coef_one)) +' are', len(weights_notzero_1))\n", + "print('Eliminated features for 2nd class out of ' + str(len(coef_two)) +' are', len(weights_notzero_2))\n", + "print('Eliminated features for 3rd class out of ' + str(len(coef_three)) +' are', len(weights_notzero_3))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_lrmt=(cv.bestModel.transform(us_test)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.90 0.43 0.58 131724\n", + " 1 0.51 0.76 0.61 58339\n", + " 2 0.13 0.95 0.22 6121\n", + "\n", + " accuracy 0.54 196184\n", + " macro avg 0.51 0.71 0.47 196184\n", + "weighted avg 0.76 0.54 0.58 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_lrmt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [], + "source": [ + "# Pandas dataframe of weights of variables with variable names to find which variables are eliminated for 3rd class for Grid\n", + "\n", + "feat_imp_tuned_lrt3 = pd.DataFrame(list(zip([i for i in us_train.columns if i!='Severity'], coef_three)),\n", + " columns = ['column', 'weight']).sort_values('weight')" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
columnweight
59month_of_year_Index_20.0
79Wind_Direction_Index_160.0
78Wind_Direction_Index_90.0
77Wind_Direction_Index_50.0
76Wind_Direction_Index_150.0
75Wind_Direction_Index_60.0
74Wind_Direction_Index_130.0
73Wind_Direction_Index_100.0
71Wind_Direction_Index_20.0
68Wind_Direction_Index_110.0
\n", + "
" + ], + "text/plain": [ + " column weight\n", + "59 month_of_year_Index_2 0.0\n", + "79 Wind_Direction_Index_16 0.0\n", + "78 Wind_Direction_Index_9 0.0\n", + "77 Wind_Direction_Index_5 0.0\n", + "76 Wind_Direction_Index_15 0.0\n", + "75 Wind_Direction_Index_6 0.0\n", + "74 Wind_Direction_Index_13 0.0\n", + "73 Wind_Direction_Index_10 0.0\n", + "71 Wind_Direction_Index_2 0.0\n", + "68 Wind_Direction_Index_11 0.0" + ] + }, + "execution_count": 129, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Sample of 10 features eliminated by the Logistic Regression Model after L1 Regularization for class 3\n", + "\n", + "feat_imp_tuned_lrt3[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/RFDT_Multiclass.ipynb b/RFDT_Multiclass.ipynb new file mode 100644 index 0000000..fd665cc --- /dev/null +++ b/RFDT_Multiclass.ipynb @@ -0,0 +1,2168 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# imports the required library\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import OneHotEncoder, OneHotEncoderModel, StringIndexer, VectorAssembler\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the training data\n", + "us_train_cat = spark.read.csv(get_training_filename('USAccident_train_categorical.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the testing data\n", + "us_test_cat = spark.read.csv(get_training_filename('USAccident_validation_categorical.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for test dataset\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==2,0).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==2,0).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for test dataset\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==3,1).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==3,1).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for test dataset\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==4,2).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==4,2).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Vector Assembler to convert all features except Severity to a single column features for feeding it to input of model\n", + "\n", + "va = VectorAssembler().setInputCols([i for i in us_train_cat.columns if i!='Severity']).setOutputCol('features')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# String Indexer to assign target Variable Severity name Label needed for the model to predict\n", + "\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Multiclass Evaluator to evaluate the performance of the model with 3 class prediction \n", + "\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "\n", + "evaluator = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multiclass RF Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.ml.classification import RandomForestClassifier\n", + "\n", + "# Create an initial RandomForest model.\n", + "rf = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for RF Base Model \n", + "\n", + "rfModel = Pipeline(stages=[label_stringIdx,va, rf])" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Train RF base model with Training Data\n", + "\n", + "rf_fit = rfModel.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.6858234810872593\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data\n", + "\n", + "print(\"Accuracy:\",evaluator.evaluate(rf_fit.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_rfmu=(rf_fit.transform(us_test_cat)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.69 0.98 0.81 131571\n", + " 1 0.68 0.09 0.16 58293\n", + " 2 0.00 0.00 0.00 6115\n", + "\n", + " micro avg 0.69 0.69 0.69 195979\n", + " macro avg 0.45 0.36 0.32 195979\n", + "weighted avg 0.66 0.69 0.59 195979\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "D:\\Anaconda\\envs\\tensorflow\\lib\\site-packages\\sklearn\\metrics\\classification.py:1143: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n", + " 'precision', 'predicted', average, warn_for)\n", + "D:\\Anaconda\\envs\\tensorflow\\lib\\site-packages\\sklearn\\metrics\\classification.py:1143: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n", + " 'precision', 'predicted', average, warn_for)\n", + "D:\\Anaconda\\envs\\tensorflow\\lib\\site-packages\\sklearn\\metrics\\classification.py:1143: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n", + " 'precision', 'predicted', average, warn_for)\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_rfmu,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "code_folding": [] + }, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Base Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rfm = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], rf_fit.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Base Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rfm['column'][:10], y=feat_imp_tuned_rfm['weight'][:10],data=feat_imp_tuned_rfm)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multiclass RF Grid Search Model" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Create an initial RandomForest model.\n", + "\n", + "rf_new = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for RF Grid Model \n", + "\n", + "rfModel_new = Pipeline(stages=[label_stringIdx,va, rf_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Grid Search for Hyper Parameter Tuning\n", + "\n", + "#paramGrid_rf = ParamGridBuilder().addGrid(rf_new.numTrees, [10, 25, 60]).addGrid(rf_new.maxDepth, [3, 5, 10]).addGrid(rf_new.impurity,[\"entropy\", \"gini\"]).build()\n", + "\n", + "paramGrid_rf = ParamGridBuilder().addGrid(rf_new.numTrees, [60]).addGrid(rf_new.maxDepth, [10]).addGrid(rf_new.impurity,[\"entropy\"]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross Validator with 5 fold and Grid Search to fit the training data\n", + "\n", + "cv_rf = CrossValidator(estimator=rfModel_new, estimatorParamMaps=paramGrid_rf, evaluator=evaluator, numFolds=5).fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Cross Validation Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_rft = cv_rf.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7203679986120962\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data\n", + "\n", + "print(\"Accuracy:\",evaluator.evaluate(pred_rft))" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_rf=cv_rf.transform(us_test_cat).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.73 0.92 0.82 131571\n", + " 1 0.65 0.33 0.44 58293\n", + " 2 0.62 0.07 0.13 6115\n", + "\n", + " micro avg 0.72 0.72 0.72 195979\n", + " macro avg 0.67 0.44 0.46 195979\n", + "weighted avg 0.71 0.72 0.68 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_rf,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='RandomForestClassifier_d70a92d04e27', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees.'): False,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext'): 10,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='featureSubsetStrategy', doc='The number of features to consider for splits at each tree node. Supported options: auto, all, onethird, sqrt, log2, (0.0-1.0], [1-n].'): 'auto',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='featuresCol', doc='features column name'): 'features',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'entropy',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='labelCol', doc='label column name'): 'label',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation.'): 256,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='numTrees', doc='Number of trees to train (>= 1)'): 60,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='predictionCol', doc='prediction column name'): 'prediction',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='seed', doc='random seed'): 42,\n", + " Param(parent='RandomForestClassifier_d70a92d04e27', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0}" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper Parameters after tuning\n", + "\n", + "cv_rf.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Grid Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rft = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cv_rf.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5,1,'Top 10 Features based on Importance from Random Forest Grid Model')" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Grid Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rft['column'][:10], y=feat_imp_tuned_rft['weight'][:10],data=feat_imp_tuned_rft)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest Grid Model\")" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DecisionTreeClassificationModel (uid=dtc_eb02160664ee) of depth 10 with 729 nodes\n", + " If (feature 35 <= 3.5)\n", + " If (feature 36 <= 34.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 39 <= 13.5)\n", + " If (feature 16 <= 0.0105)\n", + " If (feature 16 <= 0.009999999888240001)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 18 <= 77.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 77.5)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.009999999888240001)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 19 <= 29.095)\n", + " If (feature 40 <= 9.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 9.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.095)\n", + " If (feature 40 <= 6.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 6.5)\n", + " Predict: 1.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 35 <= 2.5)\n", + " Predict: 1.0\n", + " Else (feature 35 > 2.5)\n", + " If (feature 36 <= 12.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 22 <= 0.045)\n", + " If (feature 40 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 8.5)\n", + " If (feature 17 <= 59.1)\n", + " Predict: 0.0\n", + " Else (feature 17 > 59.1)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.045)\n", + " If (feature 14 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.0105)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 22 <= 0.005)\n", + " If (feature 20 <= 8.5)\n", + " If (feature 17 <= 43.35)\n", + " Predict: 1.0\n", + " Else (feature 17 > 43.35)\n", + " Predict: 0.0\n", + " Else (feature 20 > 8.5)\n", + " If (feature 18 <= 99.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 99.5)\n", + " Predict: 0.0\n", + " Else (feature 22 > 0.005)\n", + " If (feature 4 <= 0.5)\n", + " If (feature 40 <= 4.5)\n", + " Predict: 2.0\n", + " Else (feature 40 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 4 > 0.5)\n", + " If (feature 40 <= 10.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 10.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 35 <= 2.5)\n", + " If (feature 0 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 21 <= 4.05)\n", + " Predict: 1.0\n", + " Else (feature 21 > 4.05)\n", + " Predict: 0.0\n", + " Else (feature 35 > 2.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 41 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 18 <= 44.5)\n", + " If (feature 42 <= 1.5)\n", + " If (feature 23 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 23 > 0.5)\n", + " If (feature 16 <= 0.0165)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0165)\n", + " Predict: 2.0\n", + " Else (feature 42 > 1.5)\n", + " If (feature 35 <= 1.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 44.5)\n", + " If (feature 39 <= 11.5)\n", + " If (feature 9 <= 0.5)\n", + " If (feature 23 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 23 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 9 > 0.5)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 2.0\n", + " Else (feature 21 > 3.25)\n", + " Predict: 0.0\n", + " Else (feature 39 > 11.5)\n", + " If (feature 21 <= 14.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 2.0\n", + " Else (feature 21 > 14.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 13.5)\n", + " If (feature 28 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 14 <= 0.5)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 39 <= 15.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 15.5)\n", + " If (feature 42 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 2.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 36 <= 2.5)\n", + " If (feature 18 <= 83.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 83.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 2.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 2.0\n", + " Else (feature 14 > 0.5)\n", + " If (feature 36 <= 14.5)\n", + " If (feature 36 <= 6.5)\n", + " If (feature 39 <= 16.5)\n", + " Predict: 2.0\n", + " Else (feature 39 > 16.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 6.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 2.0\n", + " Else (feature 36 > 14.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 18 <= 56.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 56.5)\n", + " Predict: 1.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 19 <= 29.795)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.795)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 26 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 26 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 19 <= 29.795)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.795)\n", + " Predict: 0.0\n", + " Else (feature 28 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 46 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 46 > 0.5)\n", + " If (feature 40 <= 7.5)\n", + " If (feature 47 <= 21.5)\n", + " If (feature 47 <= 20.5)\n", + " If (feature 36 <= 17.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 17.5)\n", + " Predict: 0.0\n", + " Else (feature 47 > 20.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 40 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 5.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 47 > 21.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 21 <= 5.9)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 21 > 5.9)\n", + " Predict: 0.0\n", + " Else (feature 40 > 7.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 36 <= 14.5)\n", + " If (feature 36 <= 12.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 14.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 1 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 36 <= 14.5)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 19 <= 30.205)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.205)\n", + " Predict: 1.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 36 > 14.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 34.5)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 26 <= 0.5)\n", + " If (feature 21 <= 0.6)\n", + " If (feature 18 <= 33.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 33.5)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 16 <= 0.6205)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.6205)\n", + " If (feature 35 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 36 <= 43.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 43.5)\n", + " If (feature 18 <= 99.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 99.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 0.6)\n", + " If (feature 39 <= 2.5)\n", + " If (feature 19 <= 29.985)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 18 <= 61.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 61.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.985)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 20 <= 2.25)\n", + " Predict: 0.0\n", + " Else (feature 20 > 2.25)\n", + " Predict: 1.0\n", + " Else (feature 41 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 2.5)\n", + " If (feature 35 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 35 > 0.5)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 16 <= 0.0105)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0105)\n", + " Predict: 1.0\n", + " Else (feature 41 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 26 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 42 <= 2.5)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 17 <= 65.9)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " If (feature 41 <= 1.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 1.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 65.9)\n", + " If (feature 29 <= 0.5)\n", + " If (feature 16 <= 0.0105)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0105)\n", + " Predict: 1.0\n", + " Else (feature 29 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 2.5)\n", + " If (feature 18 <= 86.5)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 0.5)\n", + " If (feature 42 <= 8.5)\n", + " Predict: 1.0\n", + " Else (feature 42 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 86.5)\n", + " If (feature 18 <= 89.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 89.5)\n", + " Predict: 1.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 16 <= 0.0015)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 14 <= 0.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 19 <= 30.125)\n", + " If (feature 21 <= 0.6)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 0.6)\n", + " If (feature 18 <= 67.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 67.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.125)\n", + " Predict: 1.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 19 <= 29.875)\n", + " If (feature 37 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 1.5)\n", + " If (feature 36 <= 41.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 41.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.875)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 20 <= 11.0)\n", + " Predict: 0.0\n", + " Else (feature 20 > 11.0)\n", + " Predict: 1.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 21 <= 0.6)\n", + " Predict: 1.0\n", + " Else (feature 21 > 0.6)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " If (feature 40 <= 1.5)\n", + " If (feature 39 <= 11.5)\n", + " If (feature 19 <= 30.125)\n", + " If (feature 21 <= 7.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 7.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.125)\n", + " Predict: 0.0\n", + " Else (feature 39 > 11.5)\n", + " Predict: 2.0\n", + " Else (feature 40 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 42 <= 1.5)\n", + " If (feature 20 <= 7.5)\n", + " If (feature 36 <= 38.5)\n", + " Predict: 2.0\n", + " Else (feature 36 > 38.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 7.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0015)\n", + " If (feature 14 <= 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 22 <= 0.045)\n", + " If (feature 35 <= 2.5)\n", + " If (feature 36 <= 47.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 2.0\n", + " Else (feature 36 > 47.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 2.5)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 22 > 0.045)\n", + " Predict: 1.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 37 <= 1.5)\n", + " If (feature 19 <= 29.095)\n", + " If (feature 35 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 2.5)\n", + " If (feature 41 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 5.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.095)\n", + " If (feature 41 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 5.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 1.5)\n", + " If (feature 0 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 0 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " If (feature 36 <= 36.5)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 17 <= 62.25)\n", + " If (feature 47 <= 22.5)\n", + " Predict: 1.0\n", + " Else (feature 47 > 22.5)\n", + " Predict: 2.0\n", + " Else (feature 17 > 62.25)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 16 <= 0.1915)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.1915)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 18 <= 83.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 83.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 36.5)\n", + " If (feature 16 <= 0.018500000000000003)\n", + " If (feature 21 <= 7.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 7.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 19 <= 29.744999999999997)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.744999999999997)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 0.018500000000000003)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 16 <= 1.825000047685)\n", + " If (feature 31 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 1.825000047685)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 19 <= 30.015)\n", + " If (feature 19 <= 29.744999999999997)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.744999999999997)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.015)\n", + " Predict: 2.0\n", + " Else (feature 35 > 3.5)\n", + " If (feature 23 <= 0.5)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 16 <= 0.3325)\n", + " If (feature 46 <= 0.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 42 <= 3.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 3.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 46 > 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 35 <= 11.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 35 > 11.5)\n", + " If (feature 41 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " If (feature 41 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 5.5)\n", + " If (feature 19 <= 30.305)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.305)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.3325)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 16 <= 1.825000047685)\n", + " If (feature 45 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 0.5)\n", + " If (feature 42 <= 5.5)\n", + " If (feature 26 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 26 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 5.5)\n", + " If (feature 19 <= 30.645)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.645)\n", + " Predict: 0.0\n", + " Else (feature 16 > 1.825000047685)\n", + " If (feature 19 <= 29.744999999999997)\n", + " If (feature 36 <= 12.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 12.5)\n", + " If (feature 35 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 8.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.744999999999997)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 20 <= 4.5)\n", + " If (feature 13 <= 0.5)\n", + " If (feature 41 <= 3.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 3.5)\n", + " Predict: 2.0\n", + " Else (feature 13 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 4.5)\n", + " If (feature 18 <= 83.5)\n", + " If (feature 16 <= 1.825000047685)\n", + " Predict: 0.0\n", + " Else (feature 16 > 1.825000047685)\n", + " Predict: 1.0\n", + " Else (feature 18 > 83.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 47 <= 14.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 47 > 14.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 29 <= 0.5)\n", + " If (feature 39 <= 1.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 13 <= 0.5)\n", + " If (feature 19 <= 30.645)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.645)\n", + " Predict: 1.0\n", + " Else (feature 13 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 1.5)\n", + " If (feature 16 <= 0.46349999999999997)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.46349999999999997)\n", + " If (feature 42 <= 5.5)\n", + " If (feature 17 <= 57.1)\n", + " If (feature 20 <= 4.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 57.1)\n", + " Predict: 0.0\n", + " Else (feature 42 > 5.5)\n", + " Predict: 1.0\n", + " Else (feature 29 > 0.5)\n", + " If (feature 19 <= 30.105)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 35 <= 17.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 17.5)\n", + " Predict: 1.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 19 <= 29.795)\n", + " If (feature 18 <= 44.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 44.5)\n", + " If (feature 36 <= 25.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 25.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.795)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 18 <= 83.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 83.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.105)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 18 <= 66.5)\n", + " If (feature 17 <= 46.2)\n", + " Predict: 0.0\n", + " Else (feature 17 > 46.2)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 66.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 17 <= 48.8)\n", + " Predict: 0.0\n", + " Else (feature 17 > 48.8)\n", + " Predict: 1.0\n", + " Else (feature 44 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 20 <= 17.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 17 <= 57.1)\n", + " Predict: 0.0\n", + " Else (feature 17 > 57.1)\n", + " If (feature 36 <= 32.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 32.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 16 <= 0.0199999997765)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0199999997765)\n", + " If (feature 39 <= 12.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 17.5)\n", + " If (feature 21 <= 6.95)\n", + " Predict: 1.0\n", + " Else (feature 21 > 6.95)\n", + " If (feature 18 <= 20.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 20.5)\n", + " If (feature 41 <= 3.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 3.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " If (feature 19 <= 29.325)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 35 <= 5.5)\n", + " Predict: 1.0\n", + " Else (feature 35 > 5.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.325)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 22 <= 0.015)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 16 <= 0.1915)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.1915)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.015)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 47 <= 13.5)\n", + " If (feature 20 <= 12.5)\n", + " If (feature 14 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " If (feature 37 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 1.5)\n", + " If (feature 39 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " If (feature 16 <= 1.825000047685)\n", + " If (feature 41 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 1.825000047685)\n", + " If (feature 32 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 20 > 12.5)\n", + " If (feature 19 <= 29.325)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.325)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " If (feature 36 <= 10.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 10.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 47 > 13.5)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 46 <= 0.5)\n", + " If (feature 16 <= 0.053500000000000006)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.053500000000000006)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 46 > 0.5)\n", + " If (feature 36 <= 40.5)\n", + " If (feature 18 <= 33.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 33.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 40.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 47 <= 15.5)\n", + " If (feature 42 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 47 > 15.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 40 <= 3.5)\n", + " If (feature 16 <= 0.014499999999999999)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.014499999999999999)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 36 <= 51.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 51.5)\n", + " Predict: 2.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 3.5)\n", + " If (feature 40 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 4.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 23 > 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 16 <= 0.0199999997765)\n", + " If (feature 17 <= 76.4)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 39 <= 2.5)\n", + " If (feature 41 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 2.5)\n", + " If (feature 42 <= 6.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 6.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 17 <= 55.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 55.5)\n", + " If (feature 35 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 8.5)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 36 <= 2.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 2.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 76.4)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 19 <= 29.875)\n", + " If (feature 17 <= 80.8)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 80.8)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.875)\n", + " If (feature 41 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 5.5)\n", + " If (feature 40 <= 4.5)\n", + " If (feature 40 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 39 <= 8.5)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 40 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 8.5)\n", + " If (feature 40 <= 9.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 9.5)\n", + " Predict: 0.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0199999997765)\n", + " If (feature 18 <= 63.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 47 <= 11.5)\n", + " If (feature 19 <= 28.735)\n", + " If (feature 39 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 28.735)\n", + " If (feature 19 <= 29.795)\n", + " If (feature 39 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 5.5)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.795)\n", + " Predict: 0.0\n", + " Else (feature 47 > 11.5)\n", + " If (feature 36 <= 31.5)\n", + " If (feature 18 <= 54.5)\n", + " If (feature 16 <= 0.46349999999999997)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.46349999999999997)\n", + " Predict: 0.0\n", + " Else (feature 18 > 54.5)\n", + " Predict: 2.0\n", + " Else (feature 36 > 31.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 47 <= 16.5)\n", + " If (feature 18 <= 44.5)\n", + " If (feature 21 <= 5.4)\n", + " Predict: 0.0\n", + " Else (feature 21 > 5.4)\n", + " Predict: 2.0\n", + " Else (feature 18 > 44.5)\n", + " If (feature 41 <= 1.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 1.5)\n", + " Predict: 0.0\n", + " Else (feature 47 > 16.5)\n", + " Predict: 1.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 63.5)\n", + " If (feature 22 <= 0.11499999999999999)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 35 <= 5.5)\n", + " If (feature 16 <= 0.9285000035765)\n", + " If (feature 32 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.9285000035765)\n", + " If (feature 20 <= 9.5)\n", + " Predict: 0.0\n", + " Else (feature 20 > 9.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 5.5)\n", + " If (feature 41 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 1 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 22 > 0.11499999999999999)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 47 <= 7.5)\n", + " If (feature 41 <= 4.5)\n", + " If (feature 35 <= 7.5)\n", + " If (feature 16 <= 0.6205)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.6205)\n", + " If (feature 21 <= 0.6)\n", + " Predict: 0.0\n", + " Else (feature 21 > 0.6)\n", + " Predict: 1.0\n", + " Else (feature 35 > 7.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 4.5)\n", + " If (feature 40 <= 8.5)\n", + " If (feature 35 <= 16.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 16.5)\n", + " If (feature 18 <= 49.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 49.5)\n", + " If (feature 4 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 4 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 8.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 47 > 7.5)\n", + " If (feature 17 <= 51.25)\n", + " Predict: 0.0\n", + " Else (feature 17 > 51.25)\n", + " If (feature 36 <= 19.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 19.5)\n", + " If (feature 19 <= 29.915)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.915)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 14 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 5 <= 0.5)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 19 <= 29.975)\n", + " If (feature 18 <= 63.5)\n", + " If (feature 21 <= 6.95)\n", + " If (feature 39 <= 4.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 6.95)\n", + " Predict: 0.0\n", + " Else (feature 18 > 63.5)\n", + " If (feature 35 <= 7.5)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 35 > 7.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.975)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 8 <= 0.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 19 <= 29.665)\n", + " If (feature 40 <= 7.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 7.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.665)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 47 <= 7.5)\n", + " If (feature 36 <= 2.5)\n", + " Predict: 1.0\n", + " Else (feature 36 > 2.5)\n", + " Predict: 0.0\n", + " Else (feature 47 > 7.5)\n", + " If (feature 16 <= 0.0205)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0205)\n", + " Predict: 2.0\n", + " Else (feature 8 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 5 > 0.5)\n", + " If (feature 17 <= 65.9)\n", + " Predict: 0.0\n", + " Else (feature 17 > 65.9)\n", + " Predict: 1.0\n", + "\n" + ] + } + ], + "source": [ + "# Tree from the best Model printing it \n", + "\n", + "print(cv_rf.bestModel.stages[-1].trees[3].toDebugString)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Base Model Multiclass Classification" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "from pyspark.ml.classification import DecisionTreeClassifier\n", + "\n", + "# Create initial Decision Tree Model\n", + "\n", + "dt = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\")\n", + "\n", + "# Creating pipeline for DT Base Model \n", + "\n", + "dt_pipe = Pipeline(stages=[label_stringIdx, va, dt])\n", + "\n", + "# Train DT Base model with Training Data\n", + "\n", + "dtModel = dt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "# Multiclass Evaluator to evaluate the performance of the model \n", + "\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "\n", + "evaluator_dt = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Fitted Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_dt = dtModel.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7120507809510203\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data\n", + "\n", + "print(\"Accuracy:\",evaluator_dt.evaluate(pred_dt))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_dt=pred_dt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.89 0.81 131571\n", + " 1 0.60 0.36 0.45 58293\n", + " 2 0.50 0.22 0.31 6115\n", + "\n", + " micro avg 0.71 0.71 0.71 195979\n", + " macro avg 0.61 0.49 0.52 195979\n", + "weighted avg 0.69 0.71 0.69 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_dt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Base Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dt = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Base Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dt['column'][:10], y=feat_imp_tuned_dt['weight'][:10],data=feat_imp_tuned_dt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Multiclass Base Model\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Grid Search Multiclass Classification" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Initializing DT Grid Pipeline \n", + "\n", + "dt_new = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\")\n", + "\n", + "# Creating pipeline for DT Grid Model \n", + "\n", + "dt_new_pipe = Pipeline(stages=[label_stringIdx, va, dt_new])\n", + "\n", + "# Creating Grid Search for Hyper Parameter Tuning for DT Model\n", + "\n", + "#grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth, [10,15,30]).addGrid(dt_new.minInstancesPerNode, [500,1000,1500]).addGrid(dt_new.maxBins,[20,35,50]).build()\n", + "grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth,[30]).addGrid(dt_new.minInstancesPerNode, [500]).addGrid(dt_new.maxBins,[20]).build()\n", + "# Cross Validator Pipeline with 5 fold \n", + "\n", + "cv1_dt = CrossValidator(estimator=dt_new_pipe,estimatorParamMaps=grid_dt, numFolds=5, evaluator=evaluator_dt)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "# Fitting the training data using the Cross Validator Pipeline \n", + "\n", + "dtModel_t = cv1_dt.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Cross Validation Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_dtt = dtModel_t.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7259502293613092\n" + ] + } + ], + "source": [ + "# Evaluation of Testing Data using Multiclass Evaluator \n", + "\n", + "print(\"Accuracy:\",evaluator_dt.evaluate(pred_dtt))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='DecisionTreeClassifier_90ff862f7958', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees.'): False,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext'): 10,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='featuresCol', doc='features column name'): 'features',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='labelCol', doc='label column name'): 'label',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 20,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 30,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation.'): 256,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 500,\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='predictionCol', doc='prediction column name'): 'prediction',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',\n", + " Param(parent='DecisionTreeClassifier_90ff862f7958', name='seed', doc='random seed'): 3427287019239861576}" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel_t.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'DecisionTreeClassificationModel' object has no attribute 'getMaxBins'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Decision Tree Hyper Parameter Value Max Bins from Best Model\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mdtModel_t\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbestModel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstages\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetMaxBins\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m: 'DecisionTreeClassificationModel' object has no attribute 'getMaxBins'" + ] + } + ], + "source": [ + "# Decision Tree Hyper Parameter Value Max Bins from Best Model\n", + "\n", + "dtModel_t.bestModel.stages[-1].getMaxBins()" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Decision Tree Hyper Parameter Value Max Depth from Best Model\n", + "\n", + "dtModel_t.bestModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "500" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Decision Tree Hyper Parameter Value Minimum Instances Per Node from Best Model\n", + "\n", + "dtModel_t.bestModel.stages[-1].getMinInstancesPerNode()" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_dtt=pred_dtt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.77 0.86 0.81 131571\n", + " 1 0.61 0.47 0.53 58293\n", + " 2 0.51 0.22 0.31 6115\n", + "\n", + " micro avg 0.73 0.73 0.73 195979\n", + " macro avg 0.63 0.52 0.55 195979\n", + "weighted avg 0.71 0.73 0.71 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_dtt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Grid Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtt = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel_t.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Grid Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtt['column'][:10], y=feat_imp_tuned_dtt['weight'][:10],data=feat_imp_tuned_dtt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Multiclass tuned\");" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/RFDT_Multiclass_Bal.ipynb b/RFDT_Multiclass_Bal.ipynb new file mode 100644 index 0000000..01918b8 --- /dev/null +++ b/RFDT_Multiclass_Bal.ipynb @@ -0,0 +1,2770 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.classification import DecisionTreeClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.feature import OneHotEncoder, OneHotEncoderModel, StringIndexer, VectorAssembler\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the training data\n", + "\n", + "us_train_cat = spark.read.csv(get_training_filename('USAccident_balanced_train_cat.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the testing data\n", + "\n", + "us_test_cat = spark.read.csv(get_training_filename('USAccident_validation_cate.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+---------------+\n", + "|count(Severity)|\n", + "+---------------+\n", + "| 3|\n", + "+---------------+\n", + "\n" + ] + } + ], + "source": [ + "# Counting the Distinct Severity of Accidents in training data\n", + "\n", + "us_train_cat.agg(countDistinct(\"Severity\")).show()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+---------------+\n", + "|count(Severity)|\n", + "+---------------+\n", + "| 3|\n", + "+---------------+\n", + "\n" + ] + } + ], + "source": [ + "# Counting the Distinct Severity of Accidents in testing data\n", + "\n", + "us_test_cat.agg(countDistinct(\"Severity\")).show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 3|234445|\n", + "| 4|219519|\n", + "| 2|263497|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in training dataset\n", + "\n", + "us_train_cat.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 3| 58339|\n", + "| 4| 6121|\n", + "| 2|131724|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in testing dataset\n", + "\n", + "us_test_cat.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for test dataset\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==2,0).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 0 to severity 2 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==2,0).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for test dataset\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==3,1).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 1 to severity 3 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==3,1).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for test dataset\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(us_test_cat[\"Severity\"]==4,2).otherwise(us_test_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label 2 to severity 4 label for train dataset\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(us_train_cat[\"Severity\"]==4,2).otherwise(us_train_cat[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Vector Assembler to convert all features except Severity to a single column features for feeding it to input of model\n", + "\n", + "va = VectorAssembler().setInputCols([i for i in us_train_cat.columns if i!='Severity']).setOutputCol('features')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# String Indexer to assign target Variable Severity name Label needed for the model to predict\n", + "\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Multiclass Evaluator to evaluate the performance of the model with 3 class prediction \n", + "\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "\n", + "evaluator = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multiclass RF Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Create an initial RandomForest model\n", + "rf = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for RF Base Model \n", + "\n", + "rfModel = Pipeline(stages=[label_stringIdx,va, rf])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Train RF base model with Training Data\n", + "\n", + "rf_fit = rfModel.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy is 0.5453502834074134\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data for accuracy as metric\n", + "\n", + "print(\"Accuracy is\", evaluator.evaluate(rf_fit.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_rfmu=(rf_fit.transform(us_test_cat)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.92 0.42 0.57 131724\n", + " 1 0.49 0.80 0.61 58339\n", + " 2 0.13 0.94 0.24 6121\n", + "\n", + " accuracy 0.55 196184\n", + " macro avg 0.52 0.72 0.47 196184\n", + "weighted avg 0.77 0.55 0.57 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_rfmu,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Base Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rfm = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], rf_fit.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from Random Forest')" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmcAAALhCAYAAAAaWwPUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdeZhkZX328e/tDAiyiMoosgygQREXlIy4QCS4gonighGX8Loir+KubzAmGsXdqHFBJ2jQqFGiRgzqCG4obiiDIpuiIy6MCAwqi6gg8Hv/OKehaHumu6Fq6uma7+e6+uo6W9Xv1HLqruc855xUFZIkSWrDzcZdgCRJkq5nOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFM2sAk2SRJJdl+zHVckGTvcdagTpK/S/LLJL9Lcpdx1zNKSQ5N8sVx1yGti+FMI9Nv6Kf+rk3yh4HhJw35sZ6U5Fv9Yxw/w/R7Jzktye+TfCfJ3dZxX8ckuXJa/Y+6ifU1EYg2RC2FwCQnJ3nyuOuYwduAp1XV5lX1g/X5wAOfjSv6z9rqJG9MkvVZx7Al2bVfr8HtyHfWcw0G0QXKcKaR6Tf0m1fV5sAvgEcMjPuvIT/cr4G3AG+dPiHJpsD/AkcBtwI+DhybZPE67u+Iwfqr6lNDrnfekiwadw26cZLcLEmT29skGwHbAmetZfq6PifDdOd+W/Eg4KlAiyF2vq6Zth3Zc753sB6ffzWkyY2FNgxJNk1yZJJf9b+W39x/UZBkvySrkrwqyW+SnJvkcWu7r6o6vqo+AfxqhskPAf5YVe+uqivpQtwWwLxbU5LskOR/k1zc13TowLS9knw7yaVJzk/ytoEN60n9/3OmWuKm/6qd3rrWt+C9I8nnk1wB3K9/zv4tyXl9i9A7k9y8n3+bJMcnuSTJr5N8eZbVeVSSnyVZk+S1Uy0V/S/+r/TP+5ok/5lki4E6/7l/zS5L8oMkf9WPX9RPO7d/fv4ryVYDyz09yS/6+3zpLM/zrZN8pJ/3p0n+30B9hyb5Uv/cXJLkJ0kePMu6Tt3voUm+nORd/ev04yTLkhySbrfehUkOGpj/mP45PjHJ5f3jbjcwfZ8k3+3v6+Qk9x6YdnKSVyf5NvB74L3AvYH39e+Bt/Tzvad//1+WrlX3vgP38Yb+efxo//inJ7nnwPSdBt6PF0/dZz/tWUnO6V/Hzw7WPTDPLYHf9oPnJDmrH39Bkpf0w5f14+6e5Gv9c356kv2nPU9vT/KFdC1gX0ly2yTv7uc/K8nd5/IaVdU5wMnA4Ho+K8kP++dgVZKnDUyb2lb8Y/9++WUGWub7Olb0z++3gB2nPQezvYb/0r8uv0vyySS3SfKx/v5Ozo1oDe8/K6/qPw8XJjk6/Wcs3efv6iTPTHIesKIf/1fpti+X9PXuNXB/z0z3Wb48/bYyyb2AfwP+uq/9gvnWqTGqKv/8G/kf8DPgwdPGvQn4GrA1cDvgFODl/bT9gKuB1wMbAw+m+4LbeZbHOQw4ftq4lwHHThv3ReA5a7mPY4B/mmH8IuAM4B/6mu5E1yK4Tz99T7ov30XAHYFVwKH9tE2AArYfuL9DgS8ODN9gnr6O3wD3ofshdXNgOfAJYCvglsAJwCv7+d8GvB1Y3Nf3gLWs39TjnNDfz87AucCT++m7Ag/s72Mbui/KN/TTdu/nvR0Q4A5TrwlweP96bts/xgeA9/fT7glcDtyvX48j+9d377XU+DG6Fs7Ngb8Afgo8aeB5+xNwcP9cvxD42TreExdMPc7Ask/sn6c3Az/vn7uNgUfShZVNBl6DS/q6N+mf/y/2025LF1z+rr+vpwBrgFv200/un6s7Axv185w89TwP1HcwXYvuRsDLgfOAjfppb6B73z+kX9e3AV/pp20E/KCf5xbApsD9+2kH9dPu1M/3GuDEWd4P2097zk7pX8tN+3l+Dry4v7+HAb8beO2P6ZfZvZ//6/26P76v+83A5+by+MBd++fx/w7M80i692notgV/AO46sK34U//cbQQ8mu69tnk//VPAh/u67glcOM/X8AfATsCtgR8DPwT26ef/b+A9a1mvXYGr1zLt2f397ghsCXwGeO/AcgW8b+B13Ylu78CD6bYFD+/rvFX/dwlwx3757YC7zLSN8W/h/I29AP82jD9mDme/BB44MHwA8MP+9n7AH+m/JPtxxwEvneVxZgpnrwU+MG3c/wCHr+U+juk3/pf0f6v78fsAP54276vWsXE+HPhof/vGhrOjBqYvBq4CthsYty/wg/72m+gCzR1meY6mHuevB8a9CPjsWuY/CPhWf/uudK2T+wKLp833U2CvgeGd6YJFgNcNvgZ0wfJaZghndOHtmsH1AJ4/9br2z9uZA9Nu3a/PVmupf3o4O2Ng2r37ZW85MO4KYNeB1+ADMzzWEuCZwEnTHut7wEH97ZOBf5w2/c/C2bTp6Z+zO/fDbwA+MzB9D+CSgdf+l8DNZrifE+nDbD+8EV2Aud063g/Tw9kTB4YfQhfOMjDuWPrPUP88vXNg2kuB7017ni+Y5f14af/cF12w32gdz9PxwLP62/v1y95sYPpldEFsk/59ttPAtLdyfTiby2v44oFpRzLwQw94HHDyWmqcClmXDPwd1k/7Bl0fv6l5d+f6z8rUctsOTH8lfXgbGPdVuvA7Fc4OYGB7OfB+N5wtwD93a2oskoSuVebnA6N/Tverb8qaqvrjtOnb3oiH+x3dr9NBW9L9ul6b11bVVv3f1G6LHYGd+t0KlyS5hC7UbAOQZLckn+t3U1wGvIKuVfCmOG/g9rZ0X7JnDTz+p+h+/UMXQs8HTux387xoHvd93XObZNskH+93D11G9wt+a4CqOosudL4WuKjf5Xa7/vXcAVgxUNv36H7l36a/7+ser6oupftCnck2/XK/mFbf4HtjcBfN7/v/m8+yvlMuHLj9B+DKvp7BcYP3NVj3b+jeT9v2f4Pv35nqPI9ZJHlZv/vxUvpWO274vpm+rlO17QD8tKquneFudwSWD7wWa+haKuezC276e+8X1X/j96av6/TndfrwbK/PXem6GxwM7EXXagRAkkf2uxZ/06/PA7nhc7Rm2vMw9TxtQxd4pr/XB9drttfwpqzXNQPbka2q6l1redyf07WQ3bofvraqzh+YviPw5GnbnmV0Ae63wJOA5wEXJDkuyV+soyYtAIYzjUW/kb+AG/b/WErXEjBl6ySbTJs+uMGaq7PofpkCXeds4G6spQP0OpxH17I3uLHdoqoe3U9/L/Bdut0LWwKvpvtigO6X8HRXMPAFRB/yphlc7ld0X7B3HHj8W1bVbaALPFX1/KraEXgs8E+D/VJmsMPA7cHn9s19bXfr1+MZA+tBVf1nVd2fbpfmJsBr+tdzqiV08PnZpKou7mu/7vH6vk63XEtdF9C1diydVt8vZ5595AbrvjXdl/Gv6J6vHafNO73O6a/7DYaTPAR4Lt2uuK3ovpz/wMDzvQ7n0f1YmGk7fh7wlGmvxaZVdeoc7nemWs/nhq8HjOA1qaprq+pDwOl03RFIshldi/ARwG2raivgy8ztObqAbj2mv9enzOU1HIXpj7uU7nX/TT88/X1zHvC+aa/nZlX1NoCq+mxVPYg+RAPvWcv9aIEwnGmcPgq8su9ge1u6PiMfHpi+EfDPSTZO8kC6XSv/M9Md9R1sN6Hb9XezdJ3rpzrjfwHYNF1n8JvT9VG6gq5fzHx8vX+sF0zdf5J7JNmjn74FcGlV/S7JXel2mQBQ3YEIl9IFmimnAfdKctckt6BraVurqvoTcDTw9iRbp7ND/wU/1bqwc9+KdSndrsFr1nGX/5Dklkl2otsd/N8D6/E74LIkS+laB+kfY7e+A/XN6b5M/jDwGMuBNyTZoZ/3tkke0U/7GPCYJPfpl30NXQCbaT2vpNtl9rokmyW5I91uzQ/PNP96cMC0uk+sqovodrPfK8mB/XvhYLov2T87lcuAC7nhe2ALut2Na+j6vL2aLvDOxdfpWn+PSHKLdAeL3L+ftpwunN8ZIMmtkjx2jvc7k6/Rfa5e0K/rQ4CH0oWmUXg98Jwkt6FrUdoIuAi4Nskjgb+ey530Le+fBl7VPz/3oGtlmnJjXsNh+CjwkiRL0x0I8BrgI9NaJgf9J/C4JA/qt3Wb9re3SbJdkr/ptyFX0n12pz6TFwI7pD/QSguH4Uzj9ArgbLoWrNPo+mG8aWD6z+haii6gCyVPrapz13Jfz6QLCm+jC3F/AN4FUFV/oOuPcShd34yDgEdV1dXzKbYPRw8H7k+3G2IN3S/Uqd0aLwSekeR3dH1T/nvaXbwC+Hi/W+KRVXUG1x8U8UPgK3Mo4wV0v7pX0gWw4+k6zAPcpb+Py+mODv3Xqjp5Hff1WeD7/X19nOvDzyvojmS9lC4kDQbiTemOdp1qDduc60Plm+gOtPhyksuBb9L1kaKqvkfXmfwTwGq6X/cXr6O2Z/X/f07XSvI+YNinX5mrD9P1/bqY7jn+PwBVdSFdR/WX03XWPgz426q6ZB339Tbg4CS/TfImuuBwEvATug70F9O9r2Y18H7cneuf08f00z5K9/7/ZL9r+jS6z8WN0oecvwUOpFvXtwKPr6qf3Nj7nOXxVtK9L1/Ut7y+hO65+jXwKPojGOfoWXQHsFwI/Dvw/oHHuTGv4TC8B/gk3WfkJ3QtZmvthtBv9x5L18f1YrrPxfPpvsMX0bUyXkC3Dvema42FbvvwM7ouCKtHsB4akaw9qEvjk2Q/4F1VZd8JjU2SY+gOPnjNuGuRtOGw5UySJKkhhjNJkqSGuFtTkiSpIbacSZIkNcRwJkmS1JCJutr91ltvXTvttNO4y5AkSZrVqaeeenFVLZk+fqLC2U477cTKlSvHXYYkSdKskky/fBjgbk1JkqSmGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhi8ddwKj95Us/OO4S5u3UNx887hIkSdKY2HImSZLUEMOZJElSQ0YazpLsl+ScJKuSHL6O+e6d5JokB853WUmSpEkysnCWZBFwJLA/sBvwhCS7rWW+NwInzHdZSZKkSTPKlrM9gVVVdW5VXQUcAxwww3zPBf4HuOhGLCtJkjRRRhnOtgPOGxhe3Y+7TpLtgEcDy+e77MB9HJJkZZKVa9asuclFS5IkjdMow1lmGFfThv8N+IequuZGLNuNrDqqqpZV1bIlS5bciDIlSZLaMcrznK0GdhgY3h44f9o8y4BjkgBsDTw8ydVzXFaSJGnijDKcnQLskmRn4JfAQcATB2eoqp2nbif5APCZqvpUksWzLStJkjSJRhbOqurqJIfRHYW5CDi6qs5Kcmg/fXo/s1mXHVWtkiRJrRjp5ZuqagWwYtq4GUNZVT1ltmUlSZImnVcIkCRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGjDScJdkvyTlJViU5fIbpByQ5PclpSVYm2Xtg2s+SnDE1bZR1SpIktWLxqO44ySLgSOAhwGrglCTHVdXZA7N9CTiuqirJPYCPAbsOTN+3qi4eVY2SJEmtGWXL2Z7Aqqo6t6quAo4BDhicoap+V1XVD24GFJIkSRuwUYaz7YDzBoZX9+NuIMmjk/wQ+CzwtIFJBXw+yalJDlnbgyQ5pN8lunLNmjVDKl2SJGk8RhnOMsO4P2sZq6pjq2pX4FHAEQOT9qqqPYD9geckecBMD1JVR1XVsqpatmTJkmHULUmSNDajDGergR0GhrcHzl/bzFV1EnDHJFv3w+f3/y8CjqXbTSpJkjTRRhnOTgF2SbJzko2Bg4DjBmdI8hdJ0t/eA9gY+HWSzZJs0Y/fDHgocOYIa5UkSWrCyI7WrKqrkxwGnAAsAo6uqrOSHNpPXw48Fjg4yZ+APwCP74/cvB1wbJ/bFgMfqarjR1WrJElSK0YWzgCqagWwYtq45QO33wi8cYblzgV2H2VtkiRJLfIKAZIkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1ZKThLMl+Sc5JsirJ4TNMPyDJ6UlOS7Iyyd5zXVaSJGkSjSycJVkEHAnsD+wGPCHJbtNm+xKwe1XdE3ga8L55LCtJkjRxRtlytiewqqrOraqrgGOAAwZnqKrfVVX1g5sBNddlJUmSJtEow9l2wHkDw6v7cTeQ5NFJfgh8lq71bM7LSpIkTZpRhrPMMK7+bETVsVW1K/Ao4Ij5LAuQ5JC+v9rKNWvW3OhiJUmSWjDKcLYa2GFgeHvg/LXNXFUnAXdMsvV8lq2qo6pqWVUtW7JkyU2vWpIkaYxGGc5OAXZJsnOSjYGDgOMGZ0jyF0nS394D2Bj49VyWlSRJmkSLR3XHVXV1ksOAE4BFwNFVdVaSQ/vpy4HHAgcn+RPwB+Dx/QECMy47qlolSZJaMbJwBlBVK4AV08YtH7j9RuCNc11WkiRp0nmFAEmSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqyEjDWZL9kpyTZFWSw2eY/qQkp/d/30yy+8C0nyU5I8lpSVaOsk5JkqRWLB7VHSdZBBwJPARYDZyS5LiqOntgtp8C+1TVb5PsDxwF3Gdg+r5VdfGoapQkSWrNKFvO9gRWVdW5VXUVcAxwwOAMVfXNqvptP3gysP0I65EkSWreKMPZdsB5A8Or+3Fr83TgcwPDBXw+yalJDhlBfZIkSc0Z2W5NIDOMqxlnTPalC2d7D4zeq6rOT3Jb4AtJflhVJ82w7CHAIQBLly696VVLkiSN0ShbzlYDOwwMbw+cP32mJPcA3gccUFW/nhpfVef3/y8CjqXbTfpnquqoqlpWVcuWLFkyxPIlSZLWv1GGs1OAXZLsnGRj4CDguMEZkiwFPgn8fVX9aGD8Zkm2mLoNPBQ4c4S1SpIkNWFkuzWr6uokhwEnAIuAo6vqrCSH9tOXA68AbgO8OwnA1VW1DLgdcGw/bjHwkao6flS1SpIktWKUfc6oqhXAimnjlg/cfgbwjBmWOxfYffp4SZKkSecVAiRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIbMO5wluVWSe4yiGEmSpA3dnMJZkq8k2TLJrYHvA+9P8tbRliZJkrThmWvL2S2r6jLgMcD7q+ovgQePrixJkqQN01zD2eIktwf+DvjMCOuRJEnaoM01nL0KOAFYVVWnJLkD8OPRlSVJkrRhWjzH+X5VVdcdBFBV59rnTJIkafjm2nL2zjmOkyRJ0k2wzpazJPcD7g8sSfKigUlbAotGWZgkSdKGaLbdmhsDm/fzbTEw/jLgwFEVJUmStKFaZzirqq8CX03ygar6+XqqSZIkaYM11wMCbp7kKGCnwWWq6oGjKEpz94tX333cJczb0lecMe4SJElq1lzD2ceB5cD7gGtGV44kSdKGba7h7Oqqes9IK5EkSdKsR2veur/56STPBo4FrpyaXlW/GWFtkiRJG5zZWs5OBQpIP/zSgWkF3GEURUmSJG2oZjtac+f1VYgkSZLm2OcsyWNmGH0pcEZVXTTckiRJkjZccz0g4OnA/YAT++G/Bk4G7pTk1VX1oRHUJkmStMGZazi7FrhLVV0IkOR2wHuA+wAnAYYzSZKkIZjrhc93mgpmvYuAO/VHa/5p+GVJkiRtmObacva1JJ+hOxktwGOBk5JsBlwyksokSZI2QHMNZ8+hC2R70Z1W44PA/1RVAfuOqDZJkqQNzpzCWR/CPtH/SZIkaURmu0LA16tq7ySX05109rpJdJlty5FWJ0mStIGZ7SS0e/f/t1g/5UiSJG3Y5nq0Jkn2TvLU/vbWSbx6gCRJ0pDNKZwleSXwD8DL+lEbAx8eVVGSJEkbqrm2nD0aeCRwBUBVnQ+4q1OSJGnI5hrOruqP2CyA/vxmkiRJGrK5hrOPJfl3YKskzwS+CLx3dGVJkiRtmGY7lcYLgG8A/0Z3stnLgDsDr6iqL4y+PEmSpA3LbC1n2wNvp7uW5svprqN5InDqXO48yX5JzkmyKsnhM0x/UpLT+79vJtl9rstKkiRNonWGs6p6SVXdH9gG+EfgN8DTgDOTnL2uZZMsAo4E9gd2A56QZLdps/0U2Keq7gEcARw1j2UlSZImzlz7nG0KbAncsv87H/j2LMvsCayqqnOr6irgGOCAwRmq6ptV9dt+8GS6lro5LStJkjSJZutzdhRwV+ByujD2TeCtA4FqXbYDzhsYXg3cZx3zPx343I1cVpIkaSLMduHzpcDNgR8Dv6QLSZfM8b4zw7iaYRxJ9qULZ3vfiGUPAQ4BWLp06RxL00Kx1zv3GncJ8/KN535j3CVIkha42fqc7QfcG/jXftSLgVOSfD7Jq2a579XADgPD29PtDr2BJPcA3gccUFW/ns+yfY1HVdWyqlq2ZMmSWUqSJElq26x9zqpzJrCCbrfjN4A7As+fZdFTgF2S7JxkY+Ag4LjBGZIsBT4J/H1V/Wg+y0qSJE2i2fqcPQ+4P7AX3Wk0vgF8CzgaOGNdy1bV1UkOA04AFgFHV9VZSQ7tpy8HXgHcBnh3EoCr+1awGZe98aspSZK0MMzW52wn4BPAC6vqV/O986paQdfiNjhu+cDtZwDPmOuykiRJk26d4ayqXrS+CpEkSdLcz3MmSZKk9cBwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktSQkYazJPslOSfJqiSHzzB91yTfSnJlkpdMm/azJGckOS3JylHWKUmS1IrFo7rjJIuAI4GHAKuBU5IcV1VnD8z2G+B5wKPWcjf7VtXFo6pRkiSpNaNsOdsTWFVV51bVVcAxwAGDM1TVRVV1CvCnEdYhSZK0YIwynG0HnDcwvLofN1cFfD7JqUkOGWplkiRJjRrZbk0gM4yreSy/V1Wdn+S2wBeS/LCqTvqzB+mC2yEAS5cuvXGVSpIkNWKULWergR0GhrcHzp/rwlV1fv//IuBYut2kM813VFUtq6plS5YsuQnlSpIkjd8ow9kpwC5Jdk6yMXAQcNxcFkyyWZItpm4DDwXOHFmlkiRJjRjZbs2qujrJYcAJwCLg6Ko6K8mh/fTlSbYBVgJbAtcmeQGwG7A1cGySqRo/UlXHj6pWSZKkVoyyzxlVtQJYMW3c8oHbF9Dt7pzuMmD3UdYmSZLUIq8QIEmS1BDDmSRJUkMMZ5IkSQ0xnEmSJKVsja0AACAASURBVDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNGWk4S7JfknOSrEpy+AzTd03yrSRXJnnJfJaVJEmaRCMLZ0kWAUcC+wO7AU9Istu02X4DPA/41xuxrCRJ0sQZZcvZnsCqqjq3qq4CjgEOGJyhqi6qqlOAP813WUmSpEk0ynC2HXDewPDqftyol5UkSVqwRhnOMsO4GvaySQ5JsjLJyjVr1sy5OEmSpBaNMpytBnYYGN4eOH/Yy1bVUVW1rKqWLVmy5EYVKkmS1IpRhrNTgF2S7JxkY+Ag4Lj1sKwkSdKCtXhUd1xVVyc5DDgBWAQcXVVnJTm0n748yTbASmBL4NokLwB2q6rLZlp2VLVKkiS1YmThDKCqVgArpo1bPnD7ArpdlnNaVpIkadJ5hQBJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhqyeNwFSBuyrz5gn3GXMC/7nPTVcZcgSRPPljNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSEjDWdJ9ktyTpJVSQ6fYXqSvKOffnqSPQam/SzJGUlOS7JylHVKkiS1YvGo7jjJIuBI4CHAauCUJMdV1dkDs+0P7NL/3Qd4T/9/yr5VdfGoapQkSWrNKFvO9gRWVdW5VXUVcAxwwLR5DgA+WJ2Tga2S3H6ENUmSJDVtlOFsO+C8geHV/bi5zlPA55OcmuSQtT1IkkOSrEyycs2aNUMoW5IkaXxGGc4yw7iaxzx7VdUedLs+n5PkATM9SFUdVVXLqmrZkiVLbny1kiRJDRhlOFsN7DAwvD1w/lznqaqp/xcBx9LtJpUkSZpoIzsgADgF2CXJzsAvgYOAJ06b5zjgsCTH0B0IcGlV/SrJZsDNqury/vZDgVePsFZJQ/auF3963CXM22FvecS4S5Ck0YWzqro6yWHACcAi4OiqOivJof305cAK4OHAKuD3wFP7xW8HHJtkqsaPVNXxo6pVkiSpFaNsOaOqVtAFsMFxywduF/CcGZY7F9h9lLVJkiS1yCsESJIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1ZPG4C5Ckhei1Tz5w3CXM28s//IlxlyBpDmw5kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJasjicRcgSWrPD1775XGXMG93efkDx12CNBS2nEmSJDXEcCZJktQQd2tKkjY4//Iv/zLuEuZlodWrm8aWM0mSpIbYciZJ0oT52Mf3HHcJ8/J3j/vOuEtoii1nkiRJDbHlTJIkLRi7f+KEcZcwb98/8GHzmn+kLWdJ9ktyTpJVSQ6fYXqSvKOffnqSPea6rCRJ0iQaWThLsgg4Etgf2A14QpLdps22P7BL/3cI8J55LCtJkjRxRtlytiewqqrOraqrgGOAA6bNcwDwweqcDGyV5PZzXFaSJGnipKpGc8fJgcB+VfWMfvjvgftU1WED83wGeENVfb0f/hLwD8BOsy07cB+H0LW6AdwZOGckK/TntgYuXk+PNQ6u38Lm+i1ck7xu4PotdK7fcO1YVUumjxzlAQGZYdz0JLi2eeaybDey6ijgqPmVdtMlWVlVy9b3464vrt/C5votXJO8buD6LXSu3/oxynC2GthhYHh74Pw5zrPxHJaVJEmaOKPsc3YKsEuSnZNsDBwEHDdtnuOAg/ujNu8LXFpVv5rjspIkSRNnZC1nVXV1ksOAE4BFwNFVdVaSQ/vpy4EVwMOBVcDvgaeua9lR1XojrfddqeuZ67ewuX4L1ySvG7h+C53rtx6M7IAASZIkzZ+Xb5IkSWqI4UySJKkhhjNJkqSGGM50nSRPnza8KMkrx1WPpMmRZJMZxm09jlrWhyQbjbsGLVyGs3lK8uAZxv2fcdQyAg9KsiLJ7ZPcDTgZ2GLcRQ1Tkh2nXsMkmyaZmPVLckSSxQPDWyZ5/zhruqmSfC/Jd2f4+16S7467vmFJsscMf3ccfD0nwCn9KZMASPJY4JtjrGdoknwpydKB4b8EvjPGkoYqyW1nGHfncdQyCkle2V/Te2p48yTvHWdNk/TBX19e0W9UXgJsDrwPuBL4z7FWNQRV9cQkjwfOoDu1yROq6htjLmtokjyT7lJftwbuSHdy4+XAg8ZZ1xAtBr6d5KnANsA7+7+F7MBxF7CevBvYAzid7gopd+tv3ybJoVX1+XEWNyRPBI5O8hVgW+A2wAPHWtHwvBX4QpK3ANvRXQv6meMtaai+luSfq+pjAEleDDwd2G28ZQ3N5sDJSZ4C3I7u87h8nAV5Ko15ShLgxcCz+lGvqKqPjrGkoUmyC13IPAO4C3A28KKq+v1YCxuSJKcBewLfrqp79ePOqKq7j7ey4elbBT8N/BZ4QFWtGnNJmoMkxwBHTJ3PMcluwEuBI4BPVtU9x1nfsCR5FPAh4HIm7P2ZZB/gi3TXZbxnVV045pKGJsnt6c7/9Ue68PID4MVV9buxFjZESR4C/C9wCfDXVfWjcdbjbs35uxVwH+AndC1mO/aBbRJ8mi5sPgvYB/gx3dUaJsWVVXXV1EC/y2hifp0keQDwduDVwFeAdyXZdqxFDUmSeyc5OcmlSf6Y5Mokl427riHadfBE21V1NnCvqjp3jDUNVZL/AF4A3IPuhOOfTvKc8VY1HEleBhxJ1xL4GuArSR423qqGp79yz/HA/YCdgA9OWDC7P/A24PXA14C3JtlmnDW5W3P+TgbeUFVHJ9kUeCPwDeD+4y1rKPasqssAqmtSfUuSSbps1leT/COwaf8r6dl0gXRS/CvwuP6LnSSPAb4M7DrWqobj3cCTgWPoWj+fwg2vv7vQnZPkPXTrB/B44EdJbg78aXxlDdWZwDP6bctP+/5nbx1zTcOyPd328/d0uwA/B/wH3VVuFrwkXwB+Rbe7fXu63dMnVdVLxlvZ0LyDrhvPGQB9956vAmPrV+duzXlKsrSqfjFt3AOq6qRx1TQsSW5Bt8t2aVU9s9/Neeeq+syYSxuKJDej6yfxULp+PScA76sJ+RAkWVRV10wbd5uq+vW4ahqWJKdW1V8O7oZO8s2qmoQfRfQ/9J4N7E333vw6XSD9I3CLSWml6NdzaVWdM+5aRiHJzavqynHXMWxJHlVVnxoYXgy8rKqOGGNZQ5NkcVVdPW3ckqpaM7aaJuR7ab3pd2E+CbhDVb26P0Jnm6pa8EfmJPlv4FTg4Kq6W78h/dYE9XfZDPjjVIDpj865+QT1qbsd8Dpgu6rar++3dL+q+o8xl3aTJTkJeDBwNPALul/xz6yqe4y1MM1ZkkfQte5uXFU7J7kn8OqqeuSYS7vJkuxJ11J2y6pammR3ulbC5465tKFJsiOwS1V9sf9uWFxVl4+7rmFIsoRud/T2VfU3/bZzz6r6wLhqss/Z/L2bbr/7E/rhy+n6GkyCO1bVm+h3o1TVH+h+xU+KLwGbDgxvSteBd1J8gK418Pb98I/o+vhMgqfQba8OA64BdmGCjuRMsleSLyT5UZJzp/7GXdeQ/QvdLulLAKrqNGDncRY0RO8A/hb4NUBVfR/Yd6wVDVF/pPsngH/vR20PfGrtSyw4H6Dbjbl9P/xjur1IY2Ofs/m7T1XtkeR7AFX12yQbj7uoIbmq/0VUAEnuSHfQw6TYZHD3UFX9rt+VOym2rqqP9Z2Tqaqrk1wz20ILwUDH+D8C/zzOWkbkP4AX0rVcT8RrNoOrq+rSacdPTcqum5tV1c+nrdskvY7PoT/SHaCqfjzTuc8WsNtW1UeSvBSgqv407m2n4Wz+/tTvDpsKMEuAa8db0tC8ku6InB2S/BewF12LxaS4IskeVfVduO5EkX8Yc03DdEWS23D9e/O+wKXjLWk4+nV5JbAjA9utqrrT2Ioarkur6nPjLmLEzkzyRGBR35/1eUzISWiB8/pdm9V/PzyXruV6UlxZVVdNhc9JO9Kdbtt5a67fdt6bbq/Y2NjnbJ6SPInuSKo96M4JdiDwT1X18bEWNiT9l/t96XZnnlxVF4+5pKHpP3DHAOf3o24PPL6qTh1fVcOTZA+6k87eje7IuCXAgVV1+lgLG4IkPwD+H9NaliblXFJJ3gAsAj7JQGv11A+JSdC3Ur+cGx6Qc0RV/XGshQ1B34r0Drp+kdB1lzhsUrafSd5Etzv6YLrg+Wzg7Kp6+VgLG5Iky+hOQ3RX4Pt0JxI+sN/1Pp6aDGfzl2RXurPKB/hSVf1gzCXdJP2X+lpN2BfERnSHRwf4YVVNymkKgOt+0U6t3zmTsn5Jvl1V9xl3HaOS5MQZRldVTcoZ9LWATfqR7gB996S70K3f2YPnxBxLPRP03I5U3+S5VlX1m/VVy7ANfDFsAiyj++UQupNFfruq9h5XbcPWn2xwJ264a+yDYytoCPrzma1VVX1yfdUyKkle39+c3rK04FsFJ12ST7OOXWAL+WjNJG9j3ev2ovVYjuYpyTrfe1U1tvN82uds7k6l+xAGWEp3eZwAW9Ed2r9gjzqqqn3hukvIHDJwIr670V1DdCIk+RDdNTVP4/pdYwUs6HAGPKL/f1u6kyF/uR/el+5KAQs+nNGd/2vwP3Sv3QPGUMvQJHlyVX04yYxf4lU1CSdp/df+/2Porvn64X74CcDPxlHQEJ3Z/78vXXeCj/XDBzIBV1dJcgbrDp8L/VQ2j+v/b0237TyR7nt9H7qjNw1nrauqnQGSLAeOq6oV/fD+XN/PYKHbdSqYAVTVmf25iCbFMmC3SWqKB6iqpwIk+Qzd+v2qH749E3Kal6r6q3HXMCKb9f+3GGsVI1RVXwVIckRVDYbpT/fnr1uwps4h2PdFfsBUN4IkR9IdXLXQ/W3/f+oyWx/q/z8JWPDnh6yqvwfor4SzW1X9sh/ejq4P4di4W3Oeps5UPm3cyqpaNq6ahiXJR4Er6H7ZFt3lcjavqiesc8EFIsnHgedNhZdJk+TMqrrbwPDNgNMHxy1USZ43w+hLgVOr6swZpqkx/UEdfzN1WpQkOwMrquou463spktyDt1pli7ph7ei6xIytsv/DFOSb1TVXrONW6hm2HYGOGOc205bzubv4iT/xA0DzIK/PE7vqcD/BZ7fD58EvGd85Qzd1sDZSb7DDfstLdg+L9N8JckJwEfp3psH0TXTT4L7A/cGpi4l9nDgO8Dzk/xXVb1lbJUNQX803GvoTu1yPLA78IKq+vA6F1xYXkj3Hp06Z91OwLPGV85QvRk4LcnUSa2nLoA+KTZLsndVfR2u67u72SzLLCQnJfksN9x2jrVV15azeeoPDHgl1/d1OQl41UI+IGBDkWSfmcZP7XaZBP3BAVO7AE+qqmPHWc+w9KHzwKnLxSTZgq5/z2OBlVW12zjru6mSnFZV90zyaOBRdEHmxKrafcylDVW6C7nv2g/+cJKuQ9nvCrtvP3jy1C6ySdCfE/Jo4Jb9qEuAp03Kkfx9S9njGNh2Ap8YZxcYw5muk2QvukusTD/R5x3GVZME1+0Su/vUxYn7w96/X1V3SfK9qrrXeCu8aZKcVVV3TfJe4H+q6vgk35/AcDZxR0tPSbIN3cFig+s2KSfZBSDJlnS5YSJObt0yd2vOU5I70R3BuBM3/BBOwvmIJvoSMv1Z5t9Jdy6bjelO+nlFVW051sKGpG81eyPdUZvp/2pC1u9jwLeSTF3P75HAx9JdzP6c8ZU1NJ9O8kO63ZrP7q88suBPzjpogo+WJsnr6Lq4/IDrrxhTdLvfF7y+xfOx9N97U1cKqKpXj7GsoUlyAPAGYFsa2XbacjZPSb4PLOfPz1S+4M8yvwGc6HMlXV+Cj9MduXkwsEtV/eNYCxuSJKuARyz0kyKvTZL70J1KI8DXq+rkMZc0VEluBVxWVdf0Z9PfsqouGHddw9K3fk7c0dJw3QEBu0/C1Q5mkuR4+gNwuOH33oLu6zml33Y+evBsBeNmy9n8XV1Vk9RJftCJSd7MBF9CpqpWJVlUVdcA708ySbsdLpy0YJZks6q6ot+d8oP+b2rallV12fiqG54kjwOO74PZP9FdHu41wMSEM7pzgm0DTOLR0j8FbjbuIkZo+6rab9xFjNCFLQUzMJzdGJ9O8mzgWG4YYCbhgICpVrPB04IU3ZFHk+D3fV+l0/qj437FZB1xtDLJfwOf4obvzYV8EtpPAPsDZ3HDk2GmH146jqJG4J+r6uNJ9gYeRnfi1vdw/WdyEkzy0dKXA9/rj9YcXLdJuULAN5PcvbUAM0SnJPkv/nzbObaT0Lpbc56S/HSG0WWn+fYl2RG4kK6/2Qvpjjw6sqp+MtbChiTJ+2cYXVX1tPVejOZl6qCG/jJVZ1TVRybhQIdBk3y0dJKnzzR+6iS1C12Ss4G/oGshvJLr+2Qt9CsEANf1h5yuqurg9V5Mz3Am1nbpmCkTcgkZkjy/qt4+2zi1I8kOwKVTuy+TPAA4gO6yP8trci7s/hngl3RXG/lLugMDvjNpR2tqYep/2P6Zqvr5+q5lQ2E4m6NJvrh0kleua3pVvWp91TJKSb5bVXtMG7fgWyeSvJN1X/9uprPrLwhJTqY7v9nqJLvTXTf0TcDdgd9X1SFjLXBI+gMA9qNrNftxf+mtu1fV58dc2k2W5HJmfn+O/Yi4myrJ91j3Z2+PtU1bCPrzeq7VQu/Ok4YvXG+fs7l7xDqmFQv44tJzDV9JXlZVrx91PcOW5AnAE4Gd+2uoTdmSybi6w8pxFzBCt6iq1f3tJwNHV9Ub+0tTfX+MdQ1VVf0+yU+AhyV5GPC1SQhmAFU1p+uGJrlVVf121PUM2YHjLmDETqX7fssM0wpY6N15mr30my1nQ5bk/1TVf467jlGYqeVpIeib5HcGXg8cPjDpcrprT149lsLWsyTvrKrnjruO+UhyRlXdvb99KvDyqjq+Hz59gvq8PB94Jtf/yHs0cFRVvXN8Va1fC3X7MhdJvl5Ve4+7jlFJcteqOmvcdYxKkn+rqhesz8e05Wz4ng9MZDhj5l9Pzev7Rfw8yYOBP1TVtf3JhHcFJvXoo5ksxIsUfzXJR+iOrL0N3W7NqbOxT0R/s97T6S6cfQVAkjcC36I7afKGYkFuX+Zoko4Kn8mH6E7/MqkeMPsswzXJ52UZl0newCz0ZtaTgE36a+B9ie5C7x8Ya0WazfOAFXTn+/qrqrqqH78t8M9jq2r4wg2vynENk70tmclC376syySvG2x479WRs+Vs+Cb5Q7jQP4Dp+/Y8HXhnVb2p79CrRlXVtcCHZxh/gxMjT8Buo/cD304ydaH6R9FdTk1aCCb5e28sDGfDt9ADzLp8fNwF3ERJcj/gSXS7kWDD+gxM8ntzQe82qqq3JvkK11+e6qlVtaH9cJjk9+ckr9uGYL2/fu7WHL5vjLuA+UrypiSHzjD+hX3fFwCq6nXrt7KhewHwMuDYqjoryR2AE8dc09D1FwOfySSfz23B/nJPcrMkZ1bVd6vqHVX19kkLZlPrOMtsD1ovxYxAf+HzdY17yvqrZiyumn2Wds10qqxp4961HsvpHt+jNecnye2A1wHbVtX+SXaD/9/evYfZWdbnHv/eiQhIElDJJVpOGkEFChTKFqFAAdHuehaRUrCK1OKxVtxF2bUcrN3ai42KeBYP6EYRBVtN5dCiBoyCAglBEE8FhC1skApERGrg3n8870pWJpNJZtaa9cz7zv25rrlm1rtmMfe4xqxnPYffj2e1uRJ0U/15t2YJqf/6HMppxt3qJIvJkLQfcDYwz/b2TV2w422/vnK0adf2k35N65iTbP+8dpbp0uXfcT01FK/rShFhSe+0fXLf7bnAZ20fXTHW0Kzn+bvG9t61Ms2mJZ1h+Qxlf8jfNbd/DHyRdu8P8diBWXPxEUmtn47vHYOW9DXGmWHpSG8/gPdR+jJ+FcD2dU1F/dmg7X+nTwRuaPpOPtC72KG/Tejg7yjpeOC1wM6S+vdBzqfUCOuK7Xt1LiVtStnicu2GHjTTNTUF/wT4PUn9nXAWAOu8Jo5SBmeTt7Xt8yWdBGB7laSHN/SgGe43knay/ZP+i5J2orSRabte37T/XTXFCNi+bcx4uu1/mwBI2h64y/Zvm9ubU/6/eFvzLa+qlW0Qkp4KPAEYWwj6IEo7py7pRKeRMc6nnPxep4ai7bvqRJoWxwLnNq97BwMX2X5f5UzDcBelEO1vgf46bStZ+/kcuQzOJu8BSY+nmYGRtC9wX91IAzsZuEjSu1jzbu8PKfuzRlp4bzrYvqb5vETSwubru+ummha3NUublvRoShmKH1bONCwXAvv13X4EuAD4b1BmCWuEGoL3A//T9or+i5IeAE6h3TPya+lCg/Oxmo4GvwKOaFYZFlJeVx8l6Um2f1E14IAk9S/1nQl8jLKveomkvcaemm6bZm/nMknn9t74zRTZczZJzR/rWcBulBH3QkrvvxUTPnCGk7Qb8LeU3wvKu4jTbbe+SGvzj+YpwBspy19zgFWUchrvrJltmCRtTfkH9NmU3/NS4M22W9+iStJy23uOudb6PT3NQYBx93T2d0fogjE9Nh8NbAI80Obemj2SXgf8A6UdXG85zLZ3qZdqcJImOjBl24eMLMw0aiZZTgF2oAyue31fd66VKTNnk2T7WkkHAU+jPIE/st36SuW2fwC8snaOafI3lOr4+9i+GaA5qfkRSW/pyPQ8tn9JKRPSRfdI+lPbXweQ9Hyg1U2XG5tNcN/mI0sxAmN7bEp6Mc3MZwe8FXhG12bkbR9cO8OIfBo4kbJyNCO2gmTmbJIkvQE41/a9ze3HAkfZ/nDdZFM3phn4Otq8YRegKTR7WDN46b++ELjU9h/USTYcks5iglIStv96hHGmRdNu6/OUFk4AdwPH2P5xvVSDk/QF4Bu2PzHm+nHAc2wfWSfZaEi60va+tXMMqqlRd6jtGfHCPmxdrFLQT9JVtp9ZO0e/DM4maT3LK8va/AIv6W7gNuALwFWMOfnW9r0iG1g6Wu99bSGpN+O5P7AL5fQwwBHANbbfUiXYNJC0FUDvzVHbNS96X6HUierf7/lo4CW276yVbdjG1I2aQ/k9D7L9rEqRBiap98Znd2AnYDHwUO9+2x+okWvYJF1EU6XA9h6SHgUsa/uyu6Tdmy+Paj5fyNrPX7XtSlnWnLw5kuRmVNvUe3l05UyD2gY4jPIH+ufAvwJfsH3DhI9qj4kKJLa6eCKA7XMAJL0KOLi3zC7po5R9Z60l6SjbX+h7EexdB9r/4mf7/wH7STqYNfs9/9X2NyrGmi4v6Pt6FXAL8KI6UYZmYfP5juaj9fvn1qOLVQoAPjTmdn8LOFOh4XlPBmeTdylwfvPCZ0qNm4vrRhpMMxV/MXBxU8PmKOBbTeHBs+qmG4o9JN0/znUx8Z6ftnkSpb5Sby/WvOZam23VfF444Xe1nO1v0sFuFf1sH1s7w7DZ/vvaGUaki1UKsH1A7Qzrk8HZ5J0I/BXwOtaciDu7aqIhaAZlz6MMzHYEPkCZ4m0923NrZxiR91COhfde5A8CTq0XZyi2az4vs92Jv8fZStK2lJPu+1Ne5L9NOU18e9VgQyBpvL/N+4CrgU/YbvsM/QmU4taLJC2lqVJQN9LwjJ2Zb9xH2RayobZj0yJ7ziahWcI8x/YxtbMMk6RzKEsqFwHn1fpjjMFJ2gbobWy9qu17liRdD+wJfL/N7ZkCJP0b5VBHryj0McDRtg+rl2o4JH2Asj3kC82lIylFhOcBm9lu/Un4Zp9Zp6oU9Eg6D9iHsmcQ4E+B7wHPoBwAPGPkmTI4mxxJlwAv6MA7odUkPcKadir9fxC9Wi9d3UfRCZKebvumMQUjV2tzocimpcpxwBZA/9J072/zcVWCxaSt5zDVOtfaSNIS2wf13RawxPaBkm7sQL2zx1Bmz3aw/Zqme8zTbC/ewENboXldf5ntlc3t+ZTuD4cDV9d4/rKsOXm3AEub8hP9xcB7+wAAEdhJREFU/eHeu95HzHzXtfm0aXACZam99+5u7DuuNheKPJFSQ2ox0OqSLsEvJR3DmtmloyhFW7vgCZK27VuifRJr9kk+tJ7HtMmnKaeJeydrb6f01+zE4AzYnrVbFT4E7Gj7N5KqPH8ZnE3eL5qPOZTN112Q6dN2O1vSNr2CkU1pjcMpbyROrZhrGK6yvbeku7taQ2oWeTXwQeB9lH9zvtNc64ITge9Kuokyq7sz8EZJWwDnVk02HItsHynpKADbD2pME9+WO5/y/P1zc/uFlIN/WwA/qhEoy5qBpNuB9c78tXxWsPMkXQs82/Z/SjoQOA94E2Wv1jNst3bjrqQfUJpKvxNYp16b7QkLKEeMiqTNKXUGBdxg+8ENPKQ1JH0HOBRYansvSYso5Za60uEBSc+klNIQ8G3bV9bMk5mzSWpOwq0zom15j7G5lI2rXXonNJvMtd0rn3Ek8HHbFwAXSFpeMdcwvIGycXwrSlHdfqacIIsZrMsdLCQdZHuJpLFL7k+S1KU3D6dSyi1tJ+lcyonbV9UMNAyStrD9gKQFwA+bj959C2yPV4JpJDI4m7z/0ff1ZpTlo1WVsgzLHe5QA/BZaK6kR9leRXl3+1d997X6/+NNd4olkq62/bHaeWJKru77+jRKg+muOAxYwrpvHKBDbx5sXyrpGmBfypv4N49th9dSXwb+O3AD4xyGo+xFqyLLmkMw9qRO27S9/dRsJ+nvKEe/f0n5x2Qv25b0VErpl/2rBhwSSU+nLButLhxs+/P1EsVk5d+adpL0OeBy4ArbN9XOMxtkcDZJkvqP7s8B9gY+YPtplSINTNLj+pbFooWait1PpDRyf6C5tjMwr82lNHokvQN4DvB04BLguZR9IS+d8IExo0i6tkv16tZTvHS1trcX65F0CGU/1gHAU4DlwOW2z6wabEB9vTXHld6a7XINZbpTlOXMmyl1mForA7P2G2/zqu0f18gyTY6kHHC41vYrJD0RyDJn1NbptmI9tr8haQmlUOvBlLaFuwKtHpyxbm/Nfumt2Sa2n1w7Q8Qs9KDthyWtagpE3kl5Bx8znKSVrNnP85i+PretL3I9W3prSrqMUgj6u8AVwD6276qbanDprdkhkjah9NXsjai/BXysS60sImagZZK2Aj5F2WB+P9D65drZwHZX6kGuQ9JbbZ8hqVe7bS22T6gQazqsoGzh2Y3Sc/JeSd9te7mQCU7bAnVL9WRwNnkfATYBPtzcfkVz7S+rJYrosKbY5am27wU+1LRaWdCFvXTRej9rPne6H7HttwBImgccS+kYsA2wac1cQzBjT9vmQMAkSbrO9h4buhYRwyPpGtt7184RMR5J29v+ee0c00XSGymHAfYGbmXNyc1vVA3WYZk5m7yHJS2y/TMASU8B0lYmYnp9T9JemS2LGeo8SQuBq1gzcPnhBh7TJptTushc09RTXIukx9r+1ehjDYekH7NmP93lM+EwVWbOJknSoZQp3f9oLu0IHGv7m9VCRXRUr7iupOuBZ1CWkR5gzWbyzpRliHaTtBnwTMp+5NcAm9ueFac5214iRdJjKAV2D6B0P1hEORk+3nLnSGTmbCNJ2ge4zfZlknYCjgeeDVwKXFc1XER3fQ/YC3hx7SAR69PUGTyAMjDbmtLq6IqqoUar7a3/HgJWUt74PUgp6F2tdRNk5myjdbm5dMRMlYry0QaSHqacIn43sHi8pb8u68DM2a8pLZzeD1w2E8qEZHC2kfo3/Uv6EHC37VOb28tt71kzX0QXSbqdstdlXLbXe1/EqEjamrIcdiBl0/x/AUttn1Y12Ih0YHB2OKUDwh9SZs+WUvaeLamVaU6tH9xCcyX1loEPBfpPqWR5OGJ6zAXmAfPX8xFRXdME/Ebgh5TTjDtT2o21mqSNLbre6mVN2xc05UKOBS6ilMa6tGamzJxtpNnSXDpiJmn7O/KYHST9jHJY5Qrg28B3bf+2bqrB9UrYSLrM9qETfF+r+zNL+iJlb+vPKc/hFZTn8DfVMmVwtvG63lw6YqbJnrOYySS90fYHJc213bmSSpKWAf9MmUl639j7276tQNK+tq+U9Czg+zNpr2AGZxExY7X9HXl0W9dndiU9jXJS+m+Aj469v+176mby85e9UhExY2VgFlGP7R8B/yRphe2LaueZTTJzFhERMQWSVgHj7UvqFUleMOJI00LSlsAplNOoUPpRvtP2ffVSDU7SvZSODuOyPW5D9FHIzFlERMTUXD9L9kR+itLc/eXN7VdQOuW8tFqi4bgbOKN2iPFkcBYRERETWWT78L7bp0laXi3N8KysWctsIqlzFhERMTVf2phvknTSdAeZZg9K+qPeDUn7U9octd0tG/NNkg6b5hzr/szsOYuIiJg+M/lU4MaQtAfwWWDL5tKvgFfaXlEv1ejUeP6yrBkRETG92l5B/zpgD0kLmttrNQWX9Erb51QJNxojf/6yrBkRETG9OrFEZfv+sQOzxptHHma0Rv78ZXAWERExvVo9c7YRuv77jVwGZxEREdNrow4OtFgnZgYncMuof2AOBEREREyBpLOYYGBi+69HGKeatvbAlTRhnTbbF44qy1g5EBARETE1V9cOMAob0dh96cjCDNcLJrjPQLXBWWbOIiIiYr0k3Qx8Gfi07Rtr55kNMjiLiIgYgKSFwNuAXYDNetdtH1It1BBJmg/8GXAsZa/6p4Dz1nNys5UkPQ/YlbWfv3fWypMDAREREYM5F/gh8GTgNMoG8u/XDDRMtlfa/oTt/YATKU3Q75B0jqSnVo43MEkfBY4E3kQ5eXoEsEPNTBmcRUREDObxtj8J/M72EtuvBvatHWpYJM2V9EJJXwHOpDQLfwrwNeDrVcMNx362/wL4le3TgGcB29UMlAMBERERg/ld8/mOZnnsF8C2FfMM20+AbwKn2/5O3/UvSzqwUqZh6vUJ/Y2kJwH3UGZBq8ngLCIiYjDvkrQl8FbgLGAB8Ja6kYZqd9u/Hu+OjpQLWSxpK+B04FrKSc2zawbKgYCIiIhYL0mbAcex7ob5V1cLNU0kbQpsZvu+mjmy5ywiImIAzcb4rfpuP1bSp2pmGrLPAdsAzwWWUJZsV1ZNNESS3tB7/mw/BMyR9PqqmTJzFhERMXXjVchva9X88fR+F0krbO8uaRPgkg6VCllue88x16o+f5k5i4iIGMwcSY/t3ZD0OLq1p7t34OFeSbsBWwI71oszdHMkrW7eLmku8OiKeTr1xxMREVHDGcB3JH25uX0E8I8V8wzbx5vB5zuArwLzgL+vG2moLgHOb+qdGXgtcHHNQFnWjIiIGJCkXYBDKEVML+tCmyNJJ4x3ufls2+8dZZ7pImkOcDxwKOX3uxQ4ewP9RKc3UwZnERERkydpge37m2XMddj+z1FnGiZJpzRfPg3YhzJrBqVh+OW2/7JKsFkgg7OIiIgpkLTY9vObxuCmzLqs/mz7KVUDDomkS4HDba9sbs8HvmT7T+omG4yk822/XNL1lOdtLbZ3rxALyOAsIiIiJiDpJmCPpsxErxbYdbafXjfZYCQ90fYdksbto2n71lFn6smBgIiIiAFJ2p1ygnH166rtC6sFGq7PAd9remsaeAlwTt1Ig7N9R/Pl622/rf8+Sf8EvG3dR41GZs4iIiIG0BSc3R24AXikuewuVdCXtBdwQHPzctvLauYZJknX2t5rzLUVWdaMiIhoKUk32t6ldo6YHEmvA14PLAJ+2nfXfGCp7WOqBCODs4iIiIFI+iRwRhfKZ8wmTbP6xwLvBt7ed9fK2idtMziLiIgYgKQDga8BdwIPsea0ZrVlsdh4krYf77rtn486S08GZxEREQOQ9FPgBOB61uw5q3raLzZeXykNAZsBTwZ+ZHvXWplyWjMiImIwP7f91Q1/W8xEtn+//3Zz+OH4SnFKhsycRURETJ2kDwNbUZY2H+pd71ApjVlnvBOco5SZs4iIiMFsThmUPafvmoEMzlpgTA/ROcBewN2V4gCZOYuIiIhZrK+HKMAq4BbgAtu/rZMog7OIiIiBSNoWOAvYnzJj9m3gzbZvrxosWiuDs4iIiAFI+jfg85Q2RwDHAEfbPqxeqthYkhYCJwK7Uk5rAmD7kFqZ5tT6wRERER2x0Panba9qPj4DLKwdKjbaucBNlBIap1GWNb9fM1AGZxEREYP5paRjJM1tPo4B7qkdKjba421/Evid7SVNT9R9awbK4CwiImIwrwZeTukQcAfwsuZatMPvms93SHqepD8Atq0ZKHvOIiIiYtaS9HzgCmA7ysGOBcBpNQsLZ3AWERExgGZD+WuAHemrH9osj0VMWorQRkREDOZfKDMv/w48XDlLbCRJJ09wt23/w8jCjJGZs4iIiAFIWm57z9o5YnIkvXWcy1sAx1EOCcwbcaTVMjiLiIgYgKR3Ad+x/fXaWWJqJM0H3kwZmJ0PnGH7rmp5MjiLiIiYOkkrKTMu/8Wak3+2vaBeqtgYkh4HnAAcDZwDnGn7V3VTZc9ZRETEQGzPr50hJk/S6cBLgY8Dv2/715UjrZaZs4iIiAFJeiFwYHPzW7YX18wTGybpEeAhSrPz/sGQqDzzmcFZRETEACS9B9iH0gYI4CjgGttvr5cq2iyDs4iIiAFIWgHsafuR5vZcYJnt3esmi7ZK+6aIiIjBbdX39ZbVUkQn5EBARETEYN4NLJP0Tcp+pQOBk+pGijbLsmZERMQUSRKlSfYqyr4zAVfZvrNqsGi1DM4iIiIGIOka23vXzhHdkT1nERERg7lS0j61Q0R3ZOYsIiJiAJJuBHYGbgUeYE2drJzWjCnJ4CwiImIAknYY77rtW0edJbohy5oRERGDeZftW/s/gHfVDhXtlcFZRETEYHbtv9EUoc0BgZiyDM4iIiKmQNJJklYCu0u6v/lYCdwF/EvleNFi2XMWERExAEnvtp2iszE0mTmLiIgYzGJJWwBIOkbSe9d3SCBiY2RwFhERMZiPAL+RtAdwIqWkxmfrRoo2y+AsIiJiMKtc9gi9CDjT9pnA/MqZosXS+DwiImIwKyWdBLwCOKA5rZnX15iyzJxFREQM5kjgIeDYpuH5/sAWdSNFm2VkHxERMQDbd0r6BvDnkv4PcDPw/sqxosUyOIuIiJgCSTsDfwYcBdwDfJFSourgqsGi9VLnLCIiYgokPQJcARxn+6fNtf+w/ZS6yaLtsucsIiJiag4H7gS+KekTkg4FVDlTdEBmziIiIgbQFKB9MWV58xDgHOArti+tGixaK4OziIiIIZH0OOAI4Ejbh9TOE+2UwVlERETEDJI9ZxEREREzSAZnERERETNIBmcR0SmSHpa0vO9jxyn8N7aS9Prhp4uI2LDsOYuITpH0a9vzBvxv7Agstr3bJB831/bDg/zsiIjMnEVE50maK+l0Sd+XtELS8c31eZIuk3StpOslvah5yHuARc3M2+mS/ljS4r7/3gclvar5+hZJJ0v6NnCEpEWSLpZ0jaQrJD29+b4jJP1A0nWSLh/t/wIR0SZp3xQRXbO5pOXN1zfbfglwHHCf7X0kbQoslXQpcBvwEtv3S9oauFLSV4G3A7vZ3hNA0h9v4Gf+1vYfNd97GfBa2z+R9Ezgw5TaVycDz7X9fyVtNdxfOSK6JIOziOiaB3uDqj7PAXaX9LLm9pbATsDtwP+SdCDwCPB7wBOm8DO/CGUmDtgP+JK0ulD8ps3npcBnJJ0PXDiFnxERs0QGZxExGwh4k+1L1rpYliYXAnvb/p2kW4DNxnn8KtbeBjL2ex5oPs8B7h1ncIjt1zYzac8Dlkva0/Y9U/llIqLbsucsImaDS4DXSdoEQNLOTcudLYG7moHZwcAOzfevBOb3Pf5WYBdJm0raEjh0vB9i+37gZklHND9HkvZovl5k+yrbJwO/BLYb/q8ZEV2QmbOImA3OBnYErlVZb7yb0gvxXOBrkq4GlgM3Adi+R9JSST8ALrL9t81y5ArgJ8CyCX7W0cBHJL0D2AQ4D7gOOF3STpRZvMuaaxER60gpjYiIiIgZJMuaERERETNIBmcRERERM0gGZxEREREzSAZnERERETNIBmcRERERM0gGZxEREREzSAZnERERETNIBmcRERERM8j/B9HBlQvBpUt+AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Base Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rfm['column'][:10], y=feat_imp_tuned_rfm['weight'][:10],data=feat_imp_tuned_rfm)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multiclass RF Grid Search Model" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "# Create an initial RandomForest model.\n", + "\n", + "rf_new = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for RF Grid Model \n", + "\n", + "rfModel_new = Pipeline(stages=[label_stringIdx,va, rf_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Grid Search for Hyper Parameter Tuning\n", + "\n", + "paramGrid_rf = ParamGridBuilder().addGrid(rf_new.numTrees, [10, 25, 60]).addGrid(rf_new.maxDepth, [3, 6, 10]).addGrid(rf_new.impurity,[\"entropy\", \"gini\"]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross Validator with 5 fold and Grid Search to fit the training data\n", + "\n", + "cv_rf = CrossValidator(estimator=rfModel_new, estimatorParamMaps=paramGrid_rf, evaluator=evaluator, numFolds=5,seed=42).fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Cross Validation Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_rft = cv_rf.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy is 0.5714176487379196\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data for Accuracy calculation\n", + "\n", + "print(\"Accuracy is \",evaluator.evaluate(pred_rft))" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_rf=cv_rf.transform(us_test_cat).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.92 0.46 0.61 131724\n", + " 1 0.50 0.79 0.61 58339\n", + " 2 0.15 0.94 0.25 6121\n", + "\n", + " accuracy 0.57 196184\n", + " macro avg 0.52 0.73 0.49 196184\n", + "weighted avg 0.77 0.57 0.60 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_rf,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='RandomForestClassifier_19a2a830fa51', name='featuresCol', doc='features column name.'): 'features',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='seed', doc='random seed.'): 42,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees. Users can set how often should the cache be checkpointed or disable it by setting checkpointInterval.'): False,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext.'): 10,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='featureSubsetStrategy', doc=\"The number of features to consider for splits at each tree node. Supported options: 'auto' (choose automatically for task: If numTrees == 1, set to 'all'. If numTrees > 1 (forest), set to 'sqrt' for classification and to 'onethird' for regression), 'all' (use all features), 'onethird' (use 1/3 of the features), 'sqrt' (use sqrt(number of features)), 'log2' (use log2(number of features)), 'n' (when n is in the range (0, 1.0], use n * number of features. When n is in the range (1, number of features), use n features). default = 'auto'\"): 'auto',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='leafCol', doc='Leaf indices column name. Predicted leaf index of each instance in each tree by preorder.'): '',\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation. If too small, then 1 node will be split per iteration, and its aggregates may exceed this size.'): 256,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='minWeightFractionPerNode', doc='Minimum fraction of the weighted sample count that each child must have after split. If a split causes the fraction of the total weight in the left or right child to be less than minWeightFractionPerNode, the split will be discarded as invalid. Should be in interval [0.0, 0.5).'): 0.0,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='numTrees', doc='Number of trees to train (>= 1).'): 60,\n", + " Param(parent='RandomForestClassifier_19a2a830fa51', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0}" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper Parameters after tuning\n", + "\n", + "cv_rf.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SparseVector(46, {0: 0.0004, 1: 0.0008, 3: 0.0001, 4: 0.0002, 5: 0.0, 6: 0.0, 7: 0.0, 8: 0.0003, 9: 0.0002, 10: 0.0, 11: 0.0052, 13: 0.0001, 14: 0.0004, 15: 0.0, 16: 0.2309, 17: 0.0028, 18: 0.0021, 19: 0.0052, 20: 0.0007, 21: 0.0035, 22: 0.0006, 23: 0.0017, 24: 0.0, 25: 0.0183, 26: 0.0001, 27: 0.0069, 28: 0.0, 29: 0.0005, 31: 0.001, 32: 0.004, 33: 0.0, 34: 0.0539, 35: 0.3209, 36: 0.0916, 37: 0.0008, 38: 0.0049, 39: 0.0127, 40: 0.1946, 41: 0.0031, 42: 0.0032, 43: 0.0048, 44: 0.0071, 45: 0.0162})" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Feature Importance Sparse Matrix\n", + "\n", + "cv_rf.bestModel.stages[-1].featureImportances" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Grid Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rft = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cv_rf.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from Random Forest Grid Model')" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Grid Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rft['column'][:10], y=feat_imp_tuned_rft['weight'][:10],data=feat_imp_tuned_rft)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest Grid Model\")" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DecisionTreeClassificationModel: uid=dtc_c75d2dd73064, depth=10, numNodes=1039, numClasses=3, numFeatures=46\n", + " If (feature 35 <= 0.5)\n", + " If (feature 36 <= 0.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 29 <= 0.5)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 45 <= 18.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 18.5)\n", + " Predict: 2.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 18 <= 41.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 41.5)\n", + " If (feature 16 <= 1.2955)\n", + " Predict: 1.0\n", + " Else (feature 16 > 1.2955)\n", + " Predict: 2.0\n", + " Else (feature 21 > 3.25)\n", + " Predict: 1.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 16 <= 0.966)\n", + " If (feature 9 <= 0.5)\n", + " If (feature 37 <= 11.5)\n", + " If (feature 32 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 11.5)\n", + " Predict: 1.0\n", + " Else (feature 9 > 0.5)\n", + " If (feature 37 <= 10.5)\n", + " If (feature 18 <= 50.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 50.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 10.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.966)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 40 <= 8.5)\n", + " If (feature 10 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 10 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 8.5)\n", + " If (feature 37 <= 12.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 22 <= 0.045)\n", + " If (feature 19 <= 29.744999999999997)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.744999999999997)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.045)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 16 <= 0.966)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.966)\n", + " Predict: 2.0\n", + " Else (feature 21 > 3.25)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 26 <= 0.5)\n", + " If (feature 9 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 9 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 26 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " If (feature 38 <= 2.5)\n", + " If (feature 21 <= 0.6)\n", + " Predict: 2.0\n", + " Else (feature 21 > 0.6)\n", + " If (feature 13 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 13 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 2.5)\n", + " If (feature 37 <= 4.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 4.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 23 <= 0.5)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 21 <= 6.45)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 6.45)\n", + " If (feature 22 <= 0.10500000000000001)\n", + " Predict: 0.0\n", + " Else (feature 22 > 0.10500000000000001)\n", + " Predict: 1.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 16 <= 1.2955)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 1.2955)\n", + " If (feature 21 <= 5.4)\n", + " Predict: 0.0\n", + " Else (feature 21 > 5.4)\n", + " Predict: 1.0\n", + " Else (feature 23 > 0.5)\n", + " If (feature 18 <= 99.5)\n", + " If (feature 21 <= 5.4)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 5.4)\n", + " Predict: 0.0\n", + " Else (feature 18 > 99.5)\n", + " Predict: 1.0\n", + " Else (feature 29 > 0.5)\n", + " If (feature 17 <= 67.9)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 16 <= 1.8465)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 20 <= 11.0)\n", + " Predict: 0.0\n", + " Else (feature 20 > 11.0)\n", + " Predict: 1.0\n", + " Else (feature 16 > 1.8465)\n", + " Predict: 2.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 21 <= 10.2)\n", + " If (feature 37 <= 4.5)\n", + " If (feature 17 <= 51.2)\n", + " If (feature 45 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 17 > 51.2)\n", + " Predict: 1.0\n", + " Else (feature 37 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 10.2)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 37 <= 12.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 44 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 17 > 67.9)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 37 <= 9.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 16 <= 0.2135)\n", + " If (feature 17 <= 69.9)\n", + " Predict: 0.0\n", + " Else (feature 17 > 69.9)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.2135)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 9.5)\n", + " If (feature 14 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 14 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 18 <= 21.5)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 21.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 19 <= 29.785)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 21 <= 5.4)\n", + " If (feature 0 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 21 > 5.4)\n", + " If (feature 29 <= 0.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 16 <= 0.4845)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.4845)\n", + " If (feature 37 <= 6.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 6.5)\n", + " Predict: 1.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 29 > 0.5)\n", + " If (feature 39 <= 2.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 21 <= 19.0)\n", + " Predict: 0.0\n", + " Else (feature 21 > 19.0)\n", + " Predict: 1.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 2.5)\n", + " If (feature 18 <= 33.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 33.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 0.5)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 18 <= 66.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 66.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 21 <= 5.4)\n", + " Predict: 0.0\n", + " Else (feature 21 > 5.4)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.785)\n", + " If (feature 29 <= 0.5)\n", + " If (feature 43 <= 0.5)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 45 <= 5.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 16 <= 0.2895)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.2895)\n", + " Predict: 1.0\n", + " Else (feature 45 > 5.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 43 > 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 21 <= 9.1)\n", + " Predict: 0.0\n", + " Else (feature 21 > 9.1)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 16 > 5.0E-4)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 40 <= 4.5)\n", + " If (feature 20 <= 0.225)\n", + " Predict: 1.0\n", + " Else (feature 20 > 0.225)\n", + " Predict: 0.0\n", + " Else (feature 40 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 19 <= 30.255000000000003)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.255000000000003)\n", + " Predict: 0.0\n", + " Else (feature 29 > 0.5)\n", + " If (feature 45 <= 1.5)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 21 <= 11.75)\n", + " If (feature 45 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 0.5)\n", + " If (feature 17 <= 57.1)\n", + " Predict: 1.0\n", + " Else (feature 17 > 57.1)\n", + " Predict: 0.0\n", + " Else (feature 21 > 11.75)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " If (feature 37 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 5.5)\n", + " If (feature 18 <= 85.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 85.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 1.5)\n", + " If (feature 38 <= 7.5)\n", + " If (feature 19 <= 30.165)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.165)\n", + " If (feature 21 <= 7.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 7.5)\n", + " If (feature 17 <= 71.15)\n", + " Predict: 0.0\n", + " Else (feature 17 > 71.15)\n", + " Predict: 1.0\n", + " Else (feature 38 > 7.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 16 <= 0.0105)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.0105)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 45 <= 12.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 12.5)\n", + " If (feature 0 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 0 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 36 > 0.5)\n", + " If (feature 16 <= 0.053500000000000006)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 19 <= 30.165)\n", + " If (feature 45 <= 1.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 40 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 40 <= 3.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 3.5)\n", + " If (feature 22 <= 0.035)\n", + " Predict: 0.0\n", + " Else (feature 22 > 0.035)\n", + " Predict: 1.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 4 <= 0.5)\n", + " If (feature 37 <= 7.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 7.5)\n", + " Predict: 0.0\n", + " Else (feature 4 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 1.5)\n", + " If (feature 5 <= 0.5)\n", + " If (feature 43 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 43 > 0.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 21 <= 6.45)\n", + " Predict: 0.0\n", + " Else (feature 21 > 6.45)\n", + " Predict: 1.0\n", + " Else (feature 5 > 0.5)\n", + " If (feature 17 <= 77.1)\n", + " If (feature 19 <= 29.545)\n", + " If (feature 21 <= 13.4)\n", + " Predict: 1.0\n", + " Else (feature 21 > 13.4)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.545)\n", + " Predict: 0.0\n", + " Else (feature 17 > 77.1)\n", + " If (feature 40 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 21 <= 13.9)\n", + " Predict: 0.0\n", + " Else (feature 21 > 13.9)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.165)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 20 <= 11.0)\n", + " If (feature 3 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 3 > 0.5)\n", + " If (feature 37 <= 3.5)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 3.5)\n", + " Predict: 0.0\n", + " Else (feature 20 > 11.0)\n", + " If (feature 19 <= 30.185000000000002)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.185000000000002)\n", + " If (feature 38 <= 5.5)\n", + " If (feature 42 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 5.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 18 <= 55.5)\n", + " If (feature 18 <= 38.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 38.5)\n", + " If (feature 17 <= 33.2)\n", + " If (feature 16 <= 5.0E-4)\n", + " Predict: 1.0\n", + " Else (feature 16 > 5.0E-4)\n", + " Predict: 0.0\n", + " Else (feature 17 > 33.2)\n", + " Predict: 0.0\n", + " Else (feature 18 > 55.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 40 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 37 <= 2.5)\n", + " If (feature 21 <= 7.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 7.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 2.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 18 <= 38.5)\n", + " If (feature 19 <= 29.905)\n", + " If (feature 17 <= 53.5)\n", + " If (feature 19 <= 29.825)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.825)\n", + " If (feature 1 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 53.5)\n", + " If (feature 17 <= 71.15)\n", + " If (feature 21 <= 20.85)\n", + " Predict: 0.0\n", + " Else (feature 21 > 20.85)\n", + " Predict: 1.0\n", + " Else (feature 17 > 71.15)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.905)\n", + " If (feature 45 <= 6.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 6.5)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 39 <= 1.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 1.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 38.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 45 <= 13.5)\n", + " If (feature 26 <= 0.5)\n", + " If (feature 38 <= 8.5)\n", + " If (feature 18 <= 38.5)\n", + " If (feature 37 <= 7.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 7.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 38.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 26 > 0.5)\n", + " If (feature 17 <= 77.1)\n", + " Predict: 0.0\n", + " Else (feature 17 > 77.1)\n", + " Predict: 1.0\n", + " Else (feature 45 > 13.5)\n", + " If (feature 18 <= 50.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 50.5)\n", + " If (feature 45 <= 14.5)\n", + " If (feature 18 <= 93.5)\n", + " If (feature 17 <= 43.1)\n", + " Predict: 0.0\n", + " Else (feature 17 > 43.1)\n", + " Predict: 1.0\n", + " Else (feature 18 > 93.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 14.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.053500000000000006)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 45 <= 12.5)\n", + " If (feature 8 <= 0.5)\n", + " If (feature 16 <= 0.2135)\n", + " If (feature 19 <= 30.095)\n", + " If (feature 19 <= 29.785)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.785)\n", + " If (feature 39 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 2.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.095)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.2135)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 37 <= 5.5)\n", + " If (feature 40 <= 16.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 16.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 5.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 37 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 8.5)\n", + " Predict: 1.0\n", + " Else (feature 8 > 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 38 <= 6.5)\n", + " If (feature 45 <= 9.5)\n", + " If (feature 45 <= 1.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 9.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 6.5)\n", + " If (feature 40 <= 8.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 12.5)\n", + " If (feature 45 <= 17.5)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 17 <= 67.9)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 23 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 23 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 18 <= 44.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 44.5)\n", + " Predict: 1.0\n", + " Else (feature 17 > 67.9)\n", + " If (feature 16 <= 0.966)\n", + " If (feature 17 <= 77.1)\n", + " Predict: 0.0\n", + " Else (feature 17 > 77.1)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.966)\n", + " If (feature 39 <= 3.5)\n", + " Predict: 2.0\n", + " Else (feature 39 > 3.5)\n", + " Predict: 0.0\n", + " Else (feature 42 > 0.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 18 <= 58.5)\n", + " If (feature 18 <= 44.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 44.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 58.5)\n", + " If (feature 17 <= 65.85)\n", + " Predict: 0.0\n", + " Else (feature 17 > 65.85)\n", + " Predict: 1.0\n", + " Else (feature 45 > 17.5)\n", + " If (feature 19 <= 29.115000000000002)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 18 <= 88.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 88.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 38 <= 6.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 6.5)\n", + " If (feature 38 <= 8.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 8.5)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.115000000000002)\n", + " If (feature 16 <= 1.8465)\n", + " If (feature 38 <= 7.5)\n", + " If (feature 39 <= 2.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 2.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 7.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 1.8465)\n", + " If (feature 16 <= 5.1419999999999995)\n", + " If (feature 38 <= 4.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 4.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 5.1419999999999995)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 21 <= 19.0)\n", + " If (feature 37 <= 3.5)\n", + " If (feature 45 <= 20.5)\n", + " If (feature 39 <= 5.5)\n", + " If (feature 19 <= 30.255000000000003)\n", + " If (feature 38 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 2.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.255000000000003)\n", + " If (feature 45 <= 9.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 9.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 5.5)\n", + " If (feature 18 <= 53.5)\n", + " If (feature 21 <= 15.5)\n", + " Predict: 1.0\n", + " Else (feature 21 > 15.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 53.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 20.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 3.5)\n", + " If (feature 28 <= 0.5)\n", + " If (feature 45 <= 3.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 3.5)\n", + " If (feature 18 <= 62.5)\n", + " If (feature 19 <= 28.695)\n", + " Predict: 0.0\n", + " Else (feature 19 > 28.695)\n", + " Predict: 1.0\n", + " Else (feature 18 > 62.5)\n", + " Predict: 1.0\n", + " Else (feature 28 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 19.0)\n", + " If (feature 37 <= 11.5)\n", + " If (feature 37 <= 8.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 8.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 11.5)\n", + " If (feature 3 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 3 > 0.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 0.5)\n", + " If (feature 36 <= 0.5)\n", + " If (feature 45 <= 13.5)\n", + " If (feature 38 <= 4.5)\n", + " If (feature 4 <= 0.5)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 13 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 13 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 3 <= 0.5)\n", + " If (feature 20 <= 0.625)\n", + " Predict: 2.0\n", + " Else (feature 20 > 0.625)\n", + " If (feature 16 <= 0.0165)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0165)\n", + " Predict: 2.0\n", + " Else (feature 3 > 0.5)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 19 <= 28.695)\n", + " Predict: 2.0\n", + " Else (feature 19 > 28.695)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 17 <= 84.4)\n", + " Predict: 0.0\n", + " Else (feature 17 > 84.4)\n", + " Predict: 1.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 38 <= 2.5)\n", + " If (feature 45 <= 8.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 8.5)\n", + " If (feature 39 <= 3.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 3.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 2.5)\n", + " If (feature 45 <= 11.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 11.5)\n", + " If (feature 18 <= 21.5)\n", + " Predict: 0.0\n", + " Else (feature 18 > 21.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 27 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 16 <= 0.966)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.966)\n", + " Predict: 2.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 16 <= 0.0035)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0035)\n", + " Predict: 2.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 4 > 0.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 17 <= 46.75)\n", + " If (feature 19 <= 29.355)\n", + " If (feature 9 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 9 > 0.5)\n", + " If (feature 17 <= 37.2)\n", + " Predict: 0.0\n", + " Else (feature 17 > 37.2)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.355)\n", + " If (feature 45 <= 4.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 4.5)\n", + " If (feature 15 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 15 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 17 > 46.75)\n", + " If (feature 18 <= 87.5)\n", + " If (feature 20 <= 5.25)\n", + " Predict: 0.0\n", + " Else (feature 20 > 5.25)\n", + " If (feature 22 <= 0.035)\n", + " Predict: 2.0\n", + " Else (feature 22 > 0.035)\n", + " Predict: 0.0\n", + " Else (feature 18 > 87.5)\n", + " If (feature 38 <= 0.5)\n", + " If (feature 20 <= 1.9)\n", + " Predict: 0.0\n", + " Else (feature 20 > 1.9)\n", + " Predict: 2.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 20 <= 1.1)\n", + " If (feature 45 <= 9.5)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 1.0\n", + " Else (feature 21 > 3.25)\n", + " Predict: 0.0\n", + " Else (feature 45 > 9.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 1.1)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 41 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 44 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 4.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 4.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 19 <= 30.134999999999998)\n", + " If (feature 20 <= 3.5)\n", + " If (feature 8 <= 0.5)\n", + " If (feature 22 <= 0.08499999999999999)\n", + " If (feature 31 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.08499999999999999)\n", + " Predict: 2.0\n", + " Else (feature 8 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 20 > 3.5)\n", + " If (feature 19 <= 29.545)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 45 <= 12.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.545)\n", + " Predict: 2.0\n", + " Else (feature 19 > 30.134999999999998)\n", + " If (feature 16 <= 0.966)\n", + " If (feature 45 <= 4.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 4.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 37 <= 14.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 14.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.966)\n", + " If (feature 45 <= 4.5)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 43 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 43 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 4.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 25 <= 0.5)\n", + " If (feature 22 <= 0.08499999999999999)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.08499999999999999)\n", + " If (feature 22 <= 0.095)\n", + " If (feature 4 <= 0.5)\n", + " If (feature 38 <= 5.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 5.5)\n", + " Predict: 0.0\n", + " Else (feature 4 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 22 > 0.095)\n", + " If (feature 21 <= 13.9)\n", + " If (feature 6 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 6 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 13.9)\n", + " If (feature 37 <= 8.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 8.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " If (feature 45 <= 1.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 38 <= 5.5)\n", + " If (feature 37 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 5.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 5.5)\n", + " Predict: 0.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 45 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 1.5)\n", + " If (feature 14 <= 0.5)\n", + " If (feature 45 <= 12.5)\n", + " If (feature 37 <= 10.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 10.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 12.5)\n", + " Predict: 1.0\n", + " Else (feature 14 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 13.5)\n", + " If (feature 11 <= 0.5)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 39 <= 1.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 17 <= 65.85)\n", + " If (feature 19 <= 29.115000000000002)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.115000000000002)\n", + " Predict: 2.0\n", + " Else (feature 17 > 65.85)\n", + " If (feature 19 <= 29.825)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.825)\n", + " Predict: 1.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 45 <= 14.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 14.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 1.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 16 <= 0.0045000000000000005)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.0045000000000000005)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 19 <= 28.695)\n", + " Predict: 0.0\n", + " Else (feature 19 > 28.695)\n", + " If (feature 5 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 5 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 20 <= 9.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 18 <= 81.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 81.5)\n", + " Predict: 2.0\n", + " Else (feature 20 > 9.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 38 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 4.5)\n", + " Predict: 2.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 38 <= 3.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 3.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 5.0E-4)\n", + " If (feature 45 <= 15.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 15.5)\n", + " If (feature 37 <= 7.5)\n", + " If (feature 40 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 7.5)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 45 <= 16.5)\n", + " If (feature 22 <= 0.295)\n", + " If (feature 19 <= 30.005000000000003)\n", + " If (feature 18 <= 65.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 65.5)\n", + " If (feature 35 <= 1.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 30.005000000000003)\n", + " If (feature 42 <= 0.5)\n", + " If (feature 23 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 23 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 42 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 22 > 0.295)\n", + " Predict: 2.0\n", + " Else (feature 45 > 16.5)\n", + " If (feature 35 <= 1.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 39 > 0.5)\n", + " If (feature 18 <= 58.5)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 58.5)\n", + " If (feature 38 <= 8.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 11 > 0.5)\n", + " If (feature 18 <= 65.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 19 <= 29.785)\n", + " If (feature 37 <= 15.5)\n", + " If (feature 37 <= 14.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 14.5)\n", + " If (feature 17 <= 53.5)\n", + " Predict: 1.0\n", + " Else (feature 17 > 53.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 15.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.785)\n", + " If (feature 17 <= 71.15)\n", + " If (feature 44 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " Predict: 1.0\n", + " Else (feature 17 > 71.15)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 37 <= 3.5)\n", + " If (feature 39 <= 4.5)\n", + " If (feature 17 <= 80.69999999999999)\n", + " Predict: 2.0\n", + " Else (feature 17 > 80.69999999999999)\n", + " Predict: 0.0\n", + " Else (feature 39 > 4.5)\n", + " If (feature 37 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 2.5)\n", + " If (feature 44 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 3.5)\n", + " If (feature 21 <= 3.25)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 19 <= 28.695)\n", + " Predict: 1.0\n", + " Else (feature 19 > 28.695)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 31 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 31 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 45 <= 14.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 14.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 65.5)\n", + " If (feature 38 <= 3.5)\n", + " If (feature 45 <= 14.5)\n", + " If (feature 37 <= 8.5)\n", + " If (feature 19 <= 29.665)\n", + " If (feature 16 <= 0.1375)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.1375)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.665)\n", + " If (feature 16 <= 0.1375)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.1375)\n", + " Predict: 2.0\n", + " Else (feature 37 > 8.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 14.5)\n", + " If (feature 39 <= 5.5)\n", + " If (feature 17 <= 72.95)\n", + " Predict: 2.0\n", + " Else (feature 17 > 72.95)\n", + " If (feature 20 <= 9.5)\n", + " Predict: 0.0\n", + " Else (feature 20 > 9.5)\n", + " Predict: 2.0\n", + " Else (feature 39 > 5.5)\n", + " If (feature 37 <= 5.5)\n", + " If (feature 16 <= 0.053500000000000006)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.053500000000000006)\n", + " Predict: 2.0\n", + " Else (feature 37 > 5.5)\n", + " If (feature 40 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 3.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 20 <= 8.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 8.5)\n", + " If (feature 39 <= 5.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 5.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 18 <= 77.5)\n", + " Predict: 1.0\n", + " Else (feature 18 > 77.5)\n", + " If (feature 39 <= 1.5)\n", + " Predict: 1.0\n", + " Else (feature 39 > 1.5)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " If (feature 41 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 22 <= 0.025)\n", + " Predict: 2.0\n", + " Else (feature 22 > 0.025)\n", + " Predict: 0.0\n", + " Else (feature 36 > 0.5)\n", + " If (feature 16 <= 5.0E-4)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 21 <= 17.65)\n", + " If (feature 45 <= 12.5)\n", + " If (feature 41 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 0 <= 0.5)\n", + " If (feature 20 <= 2.65)\n", + " Predict: 1.0\n", + " Else (feature 20 > 2.65)\n", + " Predict: 0.0\n", + " Else (feature 0 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 12.5)\n", + " If (feature 37 <= 2.5)\n", + " If (feature 38 <= 2.5)\n", + " If (feature 20 <= 9.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 9.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 2.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 2.5)\n", + " If (feature 32 <= 0.5)\n", + " If (feature 19 <= 29.744999999999997)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.744999999999997)\n", + " Predict: 0.0\n", + " Else (feature 32 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 17.65)\n", + " If (feature 45 <= 3.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 3.5)\n", + " If (feature 38 <= 7.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 7.5)\n", + " If (feature 19 <= 29.925)\n", + " If (feature 39 <= 2.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 2.5)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.925)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 38 <= 3.5)\n", + " If (feature 21 <= 0.6)\n", + " If (feature 9 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 9 > 0.5)\n", + " If (feature 19 <= 29.935000000000002)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.935000000000002)\n", + " Predict: 1.0\n", + " Else (feature 21 > 0.6)\n", + " If (feature 19 <= 29.994999999999997)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.994999999999997)\n", + " If (feature 21 <= 9.6)\n", + " Predict: 2.0\n", + " Else (feature 21 > 9.6)\n", + " Predict: 0.0\n", + " Else (feature 38 > 3.5)\n", + " If (feature 17 <= 37.2)\n", + " If (feature 1 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 43 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 43 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 17 > 37.2)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 19 <= 29.785)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.785)\n", + " Predict: 0.0\n", + " Else (feature 41 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 20 <= 2.65)\n", + " If (feature 18 <= 66.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 66.5)\n", + " Predict: 0.0\n", + " Else (feature 20 > 2.65)\n", + " If (feature 38 <= 3.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 19 <= 29.115000000000002)\n", + " Predict: 1.0\n", + " Else (feature 19 > 29.115000000000002)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 3.5)\n", + " If (feature 25 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 25 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 38 <= 3.5)\n", + " If (feature 39 <= 1.5)\n", + " If (feature 19 <= 30.115000000000002)\n", + " If (feature 45 <= 21.5)\n", + " If (feature 19 <= 30.025)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.025)\n", + " If (feature 21 <= 9.6)\n", + " Predict: 0.0\n", + " Else (feature 21 > 9.6)\n", + " Predict: 2.0\n", + " Else (feature 45 > 21.5)\n", + " If (feature 20 <= 0.9)\n", + " Predict: 2.0\n", + " Else (feature 20 > 0.9)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 39 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.115000000000002)\n", + " If (feature 19 <= 30.255000000000003)\n", + " If (feature 37 <= 0.5)\n", + " If (feature 21 <= 0.6)\n", + " Predict: 0.0\n", + " Else (feature 21 > 0.6)\n", + " Predict: 2.0\n", + " Else (feature 37 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 30.255000000000003)\n", + " Predict: 2.0\n", + " Else (feature 39 > 1.5)\n", + " If (feature 19 <= 29.925)\n", + " If (feature 1 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 1 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 19 > 29.925)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 45 <= 17.5)\n", + " Predict: 2.0\n", + " Else (feature 45 > 17.5)\n", + " If (feature 45 <= 20.5)\n", + " Predict: 1.0\n", + " Else (feature 45 > 20.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 3.5)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 14 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 14 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 37 <= 13.5)\n", + " If (feature 39 <= 0.5)\n", + " If (feature 37 <= 2.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 2.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 37 > 13.5)\n", + " If (feature 17 <= 60.9)\n", + " If (feature 21 <= 4.05)\n", + " Predict: 0.0\n", + " Else (feature 21 > 4.05)\n", + " Predict: 2.0\n", + " Else (feature 17 > 60.9)\n", + " Predict: 0.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 18 <= 72.5)\n", + " If (feature 19 <= 29.355)\n", + " If (feature 41 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.355)\n", + " If (feature 17 <= 46.75)\n", + " Predict: 1.0\n", + " Else (feature 17 > 46.75)\n", + " Predict: 0.0\n", + " Else (feature 18 > 72.5)\n", + " If (feature 38 <= 4.5)\n", + " Predict: 2.0\n", + " Else (feature 38 > 4.5)\n", + " If (feature 19 <= 30.115000000000002)\n", + " Predict: 2.0\n", + " Else (feature 19 > 30.115000000000002)\n", + " Predict: 0.0\n", + " Else (feature 16 > 5.0E-4)\n", + " If (feature 1 <= 0.5)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 19 <= 28.695)\n", + " If (feature 45 <= 12.5)\n", + " If (feature 16 <= 0.2135)\n", + " If (feature 38 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 0.5)\n", + " If (feature 17 <= 78.9)\n", + " Predict: 0.0\n", + " Else (feature 17 > 78.9)\n", + " Predict: 2.0\n", + " Else (feature 16 > 0.2135)\n", + " Predict: 2.0\n", + " Else (feature 45 > 12.5)\n", + " If (feature 18 <= 67.5)\n", + " If (feature 3 <= 0.5)\n", + " If (feature 38 <= 4.5)\n", + " Predict: 0.0\n", + " Else (feature 38 > 4.5)\n", + " Predict: 2.0\n", + " Else (feature 3 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 67.5)\n", + " If (feature 21 <= 5.4)\n", + " If (feature 21 <= 0.6)\n", + " Predict: 2.0\n", + " Else (feature 21 > 0.6)\n", + " Predict: 0.0\n", + " Else (feature 21 > 5.4)\n", + " Predict: 2.0\n", + " Else (feature 19 > 28.695)\n", + " If (feature 40 <= 0.5)\n", + " If (feature 20 <= 7.5)\n", + " Predict: 0.0\n", + " Else (feature 20 > 7.5)\n", + " If (feature 16 <= 0.2895)\n", + " If (feature 22 <= 0.005)\n", + " Predict: 0.0\n", + " Else (feature 22 > 0.005)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.2895)\n", + " Predict: 0.0\n", + " Else (feature 40 > 0.5)\n", + " If (feature 27 <= 0.5)\n", + " If (feature 21 <= 20.85)\n", + " Predict: 2.0\n", + " Else (feature 21 > 20.85)\n", + " If (feature 11 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 11 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 27 > 0.5)\n", + " If (feature 16 <= 0.053500000000000006)\n", + " Predict: 0.0\n", + " Else (feature 16 > 0.053500000000000006)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " If (feature 44 <= 0.5)\n", + " If (feature 35 <= 1.5)\n", + " If (feature 17 <= 62.7)\n", + " If (feature 29 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 29 > 0.5)\n", + " If (feature 19 <= 29.884999999999998)\n", + " Predict: 0.0\n", + " Else (feature 19 > 29.884999999999998)\n", + " Predict: 2.0\n", + " Else (feature 17 > 62.7)\n", + " If (feature 3 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 3 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 35 > 1.5)\n", + " If (feature 37 <= 3.5)\n", + " If (feature 37 <= 0.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 37 > 3.5)\n", + " If (feature 21 <= 8.55)\n", + " Predict: 1.0\n", + " Else (feature 21 > 8.55)\n", + " If (feature 16 <= 0.0105)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.0105)\n", + " Predict: 0.0\n", + " Else (feature 44 > 0.5)\n", + " If (feature 31 <= 0.5)\n", + " If (feature 13 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 13 > 0.5)\n", + " If (feature 39 <= 0.5)\n", + " Predict: 0.0\n", + " Else (feature 39 > 0.5)\n", + " If (feature 21 <= 5.9)\n", + " Predict: 1.0\n", + " Else (feature 21 > 5.9)\n", + " Predict: 2.0\n", + " Else (feature 31 > 0.5)\n", + " If (feature 38 <= 10.5)\n", + " If (feature 4 <= 0.5)\n", + " If (feature 20 <= 3.5)\n", + " Predict: 1.0\n", + " Else (feature 20 > 3.5)\n", + " Predict: 2.0\n", + " Else (feature 4 > 0.5)\n", + " Predict: 1.0\n", + " Else (feature 38 > 10.5)\n", + " If (feature 21 <= 9.6)\n", + " If (feature 37 <= 13.5)\n", + " Predict: 1.0\n", + " Else (feature 37 > 13.5)\n", + " Predict: 0.0\n", + " Else (feature 21 > 9.6)\n", + " Predict: 2.0\n", + " Else (feature 1 > 0.5)\n", + " If (feature 26 <= 0.5)\n", + " If (feature 45 <= 12.5)\n", + " If (feature 21 <= 3.25)\n", + " Predict: 0.0\n", + " Else (feature 21 > 3.25)\n", + " If (feature 17 <= 82.30000000000001)\n", + " If (feature 34 <= 0.5)\n", + " If (feature 19 <= 28.695)\n", + " Predict: 0.0\n", + " Else (feature 19 > 28.695)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 17 > 82.30000000000001)\n", + " If (feature 17 <= 90.95)\n", + " Predict: 2.0\n", + " Else (feature 17 > 90.95)\n", + " If (feature 23 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 23 > 0.5)\n", + " Predict: 0.0\n", + " Else (feature 45 > 12.5)\n", + " If (feature 18 <= 58.5)\n", + " If (feature 41 <= 0.5)\n", + " If (feature 34 <= 0.5)\n", + " Predict: 2.0\n", + " Else (feature 34 > 0.5)\n", + " If (feature 16 <= 0.1375)\n", + " Predict: 1.0\n", + " Else (feature 16 > 0.1375)\n", + " Predict: 2.0\n", + " Else (feature 41 > 0.5)\n", + " Predict: 2.0\n", + " Else (feature 18 > 58.5)\n", + " If (feature 16 <= 0.0155)\n", + " If (feature 45 <= 18.5)\n", + " If (feature 17 <= 51.2)\n", + " Predict: 2.0\n", + " Else (feature 17 > 51.2)\n", + " Predict: 0.0\n", + " Else (feature 45 > 18.5)\n", + " Predict: 2.0\n", + " Else (feature 16 > 0.0155)\n", + " Predict: 2.0\n", + " Else (feature 26 > 0.5)\n", + " Predict: 1.0\n", + "\n" + ] + } + ], + "source": [ + "# Tree from the best Model printing it \n", + "\n", + "print(cv_rf.bestModel.stages[-1].trees[3].toDebugString)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Base Model Multiclass Classification" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Create initial Decision Tree Model\n", + "\n", + "dt = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for DT Base Model \n", + "\n", + "dt_pipe = Pipeline(stages=[label_stringIdx, va, dt])\n", + "\n", + "# Train DT Base model with Training Data\n", + "\n", + "dtModel = dt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "# Multiclass Evaluator to evaluate the performance of the model \n", + "\n", + "from pyspark.ml.evaluation import MulticlassClassificationEvaluator\n", + "\n", + "evaluator_dt = MulticlassClassificationEvaluator(labelCol=\"label\", predictionCol=\"prediction\", metricName=\"accuracy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Fitted Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_dt = dtModel.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy 0.5456816050238552\n" + ] + } + ], + "source": [ + "# Evaluation of model using Multiclass Evaluator on Test data\n", + "\n", + "print(\"Accuracy\",evaluator_dt.evaluate(pred_dt))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_dt=pred_dt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.93 0.42 0.58 131724\n", + " 1 0.48 0.79 0.60 58339\n", + " 2 0.14 0.95 0.25 6121\n", + "\n", + " accuracy 0.55 196184\n", + " macro avg 0.52 0.72 0.47 196184\n", + "weighted avg 0.77 0.55 0.57 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_dt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Base Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dt = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from DT Multiclass Base Model')" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Base Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dt['column'][:10], y=feat_imp_tuned_dt['weight'][:10],data=feat_imp_tuned_dt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Multiclass Base Model\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Grid Search Multiclass Classification" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Initializing DT Grid Pipeline \n", + "\n", + "dt_new = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for DT Grid Model \n", + "\n", + "dt_new_pipe = Pipeline(stages=[label_stringIdx, va, dt_new])\n", + "\n", + "# Creating Grid Search for Hyper Parameter Tuning for DT Model\n", + "\n", + "grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth, [10,15,30]).addGrid(dt_new.minInstancesPerNode, [500,1000,1500]).addGrid(dt_new.maxBins,[20,35,50]).build()\n", + "\n", + "# Cross Validator Pipeline with 5 fold cv to fit the training data\n", + "\n", + "cv1_dt = CrossValidator(estimator=dt_new_pipe,estimatorParamMaps=grid_dt, numFolds=5, evaluator=evaluator_dt,seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "# Fitting the training data using the Cross Validator Pipeline \n", + "\n", + "dtModel_t = cv1_dt.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform Test data using Cross Validation Pipeline Built earlier for prediction of Test data\n", + "\n", + "pred_dtt = dtModel_t.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy is 0.6133068955674265\n" + ] + } + ], + "source": [ + "# Evaluation of Testing Data using Multiclass Evaluator \n", + "\n", + "print(\"Accuracy is\",evaluator_dt.evaluate(pred_dtt))" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='DecisionTreeClassifier_b6336355b38a', name='featuresCol', doc='features column name.'): 'features',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='seed', doc='random seed.'): 42,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees. Users can set how often should the cache be checkpointed or disable it by setting checkpointInterval.'): False,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext.'): 10,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='leafCol', doc='Leaf indices column name. Predicted leaf index of each instance in each tree by preorder.'): '',\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 35,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 30,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation. If too small, then 1 node will be split per iteration, and its aggregates may exceed this size.'): 256,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 500,\n", + " Param(parent='DecisionTreeClassifier_b6336355b38a', name='minWeightFractionPerNode', doc='Minimum fraction of the weighted sample count that each child must have after split. If a split causes the fraction of the total weight in the left or right child to be less than minWeightFractionPerNode, the split will be discarded as invalid. Should be in interval [0.0, 0.5).'): 0.0}" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Decision Tree Hyper Parameter Values from Best Model\n", + "\n", + "dtModel_t.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SparseVector(46, {0: 0.0004, 1: 0.0001, 11: 0.0046, 14: 0.0, 16: 0.1281, 17: 0.0045, 18: 0.002, 19: 0.0092, 21: 0.0006, 22: 0.0002, 23: 0.001, 25: 0.0049, 27: 0.0056, 32: 0.0071, 34: 0.0834, 35: 0.5412, 36: 0.1411, 37: 0.0011, 38: 0.0093, 39: 0.0142, 40: 0.019, 41: 0.0001, 44: 0.0006, 45: 0.0218})" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Feature Importance Sparse Matrix\n", + "\n", + "dtModel_t.bestModel.stages[-1].featureImportances" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_dtt=pred_dtt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.88 0.55 0.68 131724\n", + " 1 0.52 0.73 0.61 58339\n", + " 2 0.17 0.90 0.29 6121\n", + "\n", + " accuracy 0.61 196184\n", + " macro avg 0.52 0.73 0.52 196184\n", + "weighted avg 0.75 0.61 0.64 196184\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_dtt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Grid Model for Multiclass Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtt = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel_t.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from DT Multiclass tuned')" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Grid Model for Multiclass Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtt['column'][:10], y=feat_imp_tuned_dtt['weight'][:10],data=feat_imp_tuned_dtt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Multiclass tuned\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/RF_DT_GBT_Binary.ipynb b/RF_DT_GBT_Binary.ipynb new file mode 100644 index 0000000..a6110d6 --- /dev/null +++ b/RF_DT_GBT_Binary.ipynb @@ -0,0 +1,1596 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# import the required libraries\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.classification import GBTClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import DecisionTreeClassifier\n", + "from pyspark.ml import Pipeline\n", + "from sklearn.metrics import classification_report\n", + "from pyspark.ml.feature import OneHotEncoder, OneHotEncoderModel, StringIndexer\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# reads the train data\n", + "us_train_cat = spark.read.csv(get_training_filename('USAccident_train_categorical.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# reads the test data\n", + "us_test_cat = spark.read.csv(get_training_filename('USAccident_validation_categorical.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# creates a vector assembler\n", + "va = VectorAssembler().setInputCols([i for i in us_train_cat.columns if i!='Severity']).setOutputCol('features')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# creates a string indexer\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we convert the multiclass data into binary data" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(((us_train_cat[\"Severity\"]==4) | (us_train_cat[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(((us_test_cat[\"Severity\"]==4) | (us_test_cat[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating the evaluator for our binary classification\n", + "evaluator_rfb = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# RF Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Create an initial RandomForest model.\n", + "rf = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Train model with Training Data\n", + "rfModel = Pipeline(stages=[label_stringIdx,va, rf])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "rf_fit = rfModel.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC ROC score: 0.7634901876492165\n" + ] + } + ], + "source": [ + "print(\"AUC ROC score:\",evaluator_rfb.evaluate(rf_fit.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.6892473173146102\n" + ] + } + ], + "source": [ + "# Prints the accuracy of our binary classification\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "evaluator_rfb.evaluate(rf_fit.transform(us_test_cat))\n", + "binary_prediction=rf_fit.transform(us_test_cat).select(\"prediction\").collect()\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rf_fit.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "20" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rf_fit.stages[-1].getNumTrees" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'gini'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rf_fit.stages[-1].getImpurity()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# tranforming the test data for predictions\n", + "prediction_rfb=(rf_fit.transform(us_test_cat)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# storing the true labels for evaluation purpose below\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.69 0.98 0.81 131571\n", + " 1 0.73 0.09 0.16 64408\n", + "\n", + " micro avg 0.69 0.69 0.69 195979\n", + " macro avg 0.71 0.54 0.48 195979\n", + "weighted avg 0.70 0.69 0.59 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_rfb,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# create a dataframe to print the feature importance\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rf = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], rf_fit.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rf['column'][:10], y=feat_imp_tuned_rf['weight'][:10],data=feat_imp_tuned_rf)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# RF Grid Search " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Create an initial RandomForest model.\n", + "rf_new = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Train model with Training Data\n", + "rfModel_new = Pipeline(stages=[label_stringIdx,va, rf_new])\n", + "\n", + "#paramGrid_rft = ParamGridBuilder().addGrid(rf_new.numTrees, [10, 30, 60]).addGrid(rf_new.maxDepth, [3, 5, 10]).addGrid(rf_new.impurity,[\"entropy\", \"gini\"]).build()\n", + "paramGrid_rft = ParamGridBuilder().addGrid(rf_new.numTrees, [60]).addGrid(rf_new.maxDepth, [10]).addGrid(rf_new.impurity,[\"gini\"]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# creating a cross validator for tuning our model\n", + "cv_rf = CrossValidator(estimator=rfModel_new, estimatorParamMaps=paramGrid_rft, evaluator=evaluator_rfb, numFolds=5).fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# store the predictions from our test set\n", + "pred_rft = cv_rf.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROC AUC sccore: 0.7880870240899686\n" + ] + } + ], + "source": [ + "print(\"ROC AUC sccore:\",evaluator_rfb.evaluate(pred_rft))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7257971517356452\n" + ] + } + ], + "source": [ + "# Printing the accuracy of our binary predictions\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "evaluator_rfb.evaluate(pred_rft)\n", + "binary_prediction=pred_rft.select(\"prediction\").collect()\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv_rf.bestModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "60" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv_rf.bestModel.stages[-1].getNumTrees" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'gini'" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv_rf.bestModel.stages[-1].getImpurity()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='RandomForestClassifier_deb569e64636', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees.'): False,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext'): 10,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='featureSubsetStrategy', doc='The number of features to consider for splits at each tree node. Supported options: auto, all, onethird, sqrt, log2, (0.0-1.0], [1-n].'): 'auto',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='featuresCol', doc='features column name'): 'features',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='labelCol', doc='label column name'): 'label',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation.'): 256,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='numTrees', doc='Number of trees to train (>= 1)'): 60,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='predictionCol', doc='prediction column name'): 'prediction',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='seed', doc='random seed'): 42,\n", + " Param(parent='RandomForestClassifier_deb569e64636', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0}" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv_rf.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# storing the predictions of our test set\n", + "prediction_rft=pred_rft.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# storing the true labels of our test set\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.91 0.82 131571\n", + " 1 0.66 0.34 0.45 64408\n", + "\n", + " micro avg 0.73 0.73 0.73 195979\n", + " macro avg 0.70 0.63 0.63 195979\n", + "weighted avg 0.71 0.73 0.70 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_rft,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Creates a Dataframe of feature importances from our model\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rfg = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cv_rf.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rfg['column'][:10], y=feat_imp_tuned_rfg['weight'][:10],data=feat_imp_tuned_rfg)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest Grid\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GBT Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "# Declares the gbt classifier model\n", + "gbt = GBTClassifier(seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Creates a pipeline for our model\n", + "gbt_pipe = Pipeline(stages=[label_stringIdx, va, gbt])" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Fits the pipeline on our train data\n", + "gbtModel = gbt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROC AUC Score: 0.787408211157604\n" + ] + } + ], + "source": [ + "print(\"ROC AUC Score:\",evaluator_rfb.evaluate(gbtModel.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7289046275366238\n" + ] + } + ], + "source": [ + "# Calculates the accuracy of our model\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "evaluator_rfb.evaluate(gbtModel.transform(us_test_cat))\n", + "binary_prediction=gbtModel.transform(us_test_cat).select(\"prediction\").collect()\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gbtModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gbtModel.stages[-1].getStepSize()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "20" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gbtModel.stages[-1].getMaxIter()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Predict on test data\n", + "prediction_gbtn=gbtModel.transform(us_test_cat).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "# Stores the true labels from our test data\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.76 0.88 0.81 131571\n", + " 1 0.63 0.43 0.51 64408\n", + "\n", + " micro avg 0.73 0.73 0.73 195979\n", + " macro avg 0.69 0.65 0.66 195979\n", + "weighted avg 0.72 0.73 0.71 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_gbtn,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a dataframe for our feature importances\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_gtbb = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], gbtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_gtbb['column'][:10], y=feat_imp_tuned_gtbb['weight'][:10],data=feat_imp_tuned_gtbb)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from GBT Base Model\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GBT Binary Tuned Best Model" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a GBT Classifier\n", + "gbt_t_new = GBTClassifier(maxIter=55,seed=42)\n", + "gbt_pipe_t_new = Pipeline(stages=[label_stringIdx, va, gbt_t_new])\n", + "\n", + "# Create a evaluator for our model\n", + "evaluator = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "\n", + "# Create grid for tuning the model\n", + "#grid_gbt_t_new = ParamGridBuilder().addGrid(gbt_t_new.stepSize, [0.1,0.3,0.01]).addGrid(gbt_t_new.maxDepth, [3, 5, 8]).build()\n", + "grid_gbt_t_new = ParamGridBuilder().addGrid(gbt_t_new.stepSize, [0.3]).addGrid(gbt_t_new.maxDepth, [8]).build()\n", + "cv1_gbt_t_new = CrossValidator(estimator=gbt_pipe_t_new,estimatorParamMaps=grid_gbt_t_new, numFolds=5, evaluator=evaluator,seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "# fit the cross validation model\n", + "cvModel_gbt_t_new = cv1_gbt_t_new.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROC AUC Score: 0.8032377340351009\n" + ] + } + ], + "source": [ + "print(\"ROC AUC Score:\",evaluator_rfb.evaluate(cvModel_gbt_t_new.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7407885538756703\n" + ] + } + ], + "source": [ + "# calculates the accuracy of the binary model\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "evaluator_rfb.evaluate(cvModel_gbt_t_new.transform(us_test_cat))\n", + "binary_prediction=cvModel_gbt_t_new.transform(us_test_cat).select(\"prediction\").collect()\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cvModel_gbt_t_new.bestModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.3" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cvModel_gbt_t_new.bestModel.stages[-1].getStepSize()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='GBTClassifier_34f6d1b395a8', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees.'): False,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext'): 10,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='featureSubsetStrategy', doc='The number of features to consider for splits at each tree node. Supported options: auto, all, onethird, sqrt, log2, (0.0-1.0], [1-n].'): 'all',\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='featuresCol', doc='features column name'): 'features',\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='labelCol', doc='label column name'): 'label',\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='lossType', doc='Loss function which GBT tries to minimize (case-insensitive). Supported options: logistic'): 'logistic',\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 8,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='maxIter', doc='maximum number of iterations (>= 0)'): 55,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation.'): 256,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='predictionCol', doc='prediction column name'): 'prediction',\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='seed', doc='random seed'): 42,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='stepSize', doc='Step size (a.k.a. learning rate) in interval (0, 1] for shrinking the contribution of each estimator.'): 0.3,\n", + " Param(parent='GBTClassifier_34f6d1b395a8', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cvModel_gbt_t_new.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "# Stores the prediction from ourr test set\n", + "prediction_gbt_t_new=cvModel_gbt_t_new.transform(us_test_cat).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "# Stores the true labels from our test set\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.78 0.86 0.82 131571\n", + " 1 0.63 0.50 0.56 64408\n", + "\n", + " micro avg 0.74 0.74 0.74 195979\n", + " macro avg 0.71 0.68 0.69 195979\n", + "weighted avg 0.73 0.74 0.73 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_gbt_t_new,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a dataframe of feature importances\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_gbt_t_new = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cvModel_gbt_t_new.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_gbt_t_new['column'][:10], y=feat_imp_tuned_gbt_t_new['weight'][:10],data=feat_imp_tuned_gbt_t_new)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from GBT Best tuned\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Trees Binary Classification Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# Create initial Decision Tree Model\n", + "dt = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creates a pipeline\n", + "dt_pipe = Pipeline(stages=[label_stringIdx, va, dt])\n", + "\n", + "# Train model with Training Data\n", + "dtModel = dt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "# Makes prediction from our test set\n", + "pred_dt = dtModel.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROC AUC: 0.6639903304724255\n" + ] + } + ], + "source": [ + "# prints the ROC AUC score\n", + "print(\"ROC AUC:\",evaluator.evaluate(pred_dt))" + ] + }, + { + "cell_type": "code", + "execution_count": 203, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 203, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 204, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 204, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel.stages[-1].getMinInstancesPerNode()" + ] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "32" + ] + }, + "execution_count": 205, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel.stages[-1].getMaxBins()" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7156021818664244\n" + ] + } + ], + "source": [ + "# calculates the accuracy of our model\n", + "evaluator.evaluate(pred_dt)\n", + "\n", + "binary_prediction=pred_dt.select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_dtb=pred_dt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.74 0.89 0.81 131571\n", + " 1 0.61 0.37 0.46 64408\n", + "\n", + " micro avg 0.72 0.72 0.72 195979\n", + " macro avg 0.68 0.63 0.63 195979\n", + "weighted avg 0.70 0.72 0.69 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_dtb,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtb= pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtb['column'][:10], y=feat_imp_tuned_dtb['weight'][:10],data=feat_imp_tuned_dtb)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Binary Base Model\");" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Binary Classification Grid Search" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "# declares a decision tree classifier\n", + "dt_new = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\")\n", + "\n", + "dt_new_pipe = Pipeline(stages=[label_stringIdx, va, dt_new])\n", + "\n", + "evaluator = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "\n", + "#grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth, [10,15,30]).addGrid(dt_new.minInstancesPerNode, [500,1000,1500]).addGrid(dt_new.maxBins,[20,35,50]).build()\n", + "grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth, [10]).addGrid(dt_new.minInstancesPerNode, [500]).addGrid(dt_new.maxBins,[50]).build()\n", + "\n", + "cv1_dt = CrossValidator(estimator=dt_new_pipe,estimatorParamMaps=grid_dt, numFolds=5, evaluator=evaluator)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "dtModel_t = cv1_dt.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "pred_dtt = dtModel_t.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC ROC: 0.5687880524415173\n" + ] + } + ], + "source": [ + "print(\"AUC ROC:\",evaluator.evaluate(pred_dtt))" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.7307313538695472\n" + ] + } + ], + "source": [ + "# calculates the accuracy \n", + "evaluator.evaluate(pred_dtt)\n", + "\n", + "binary_prediction=pred_dtt.select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "print(\"Accuracy:\",np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='DecisionTreeClassifier_6cf0199ad377', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees.'): False,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext'): 10,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='featuresCol', doc='features column name'): 'features',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='labelCol', doc='label column name'): 'label',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 50,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation.'): 256,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 500,\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='predictionCol', doc='prediction column name'): 'prediction',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities'): 'probability',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name'): 'rawPrediction',\n", + " Param(parent='DecisionTreeClassifier_6cf0199ad377', name='seed', doc='random seed'): -3198175077911245588}" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel_t.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 179, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel_t.bestModel.stages[-1].getMaxDepth()" + ] + }, + { + "cell_type": "code", + "execution_count": 180, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "500" + ] + }, + "execution_count": 180, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel_t.bestModel.stages[-1].getMinInstancesPerNode()" + ] + }, + { + "cell_type": "code", + "execution_count": 181, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "50" + ] + }, + "execution_count": 181, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtModel_t.bestModel.stages[-1].getMaxBins()" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [], + "source": [ + "prediction_dtbt=pred_dtt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.77 0.85 0.81 131571\n", + " 1 0.61 0.49 0.54 64408\n", + "\n", + " micro avg 0.73 0.73 0.73 195979\n", + " macro avg 0.69 0.67 0.68 195979\n", + "weighted avg 0.72 0.73 0.72 195979\n", + "\n" + ] + } + ], + "source": [ + "print(classification_report(y_pred=prediction_dtbt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtbt= pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel_t.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtbt['column'][:10], y=feat_imp_tuned_dtbt['weight'][:10],data=feat_imp_tuned_dtbt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Binary Grid Model\");" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/RF_DT_GBT_LR_Binary_Bal.ipynb b/RF_DT_GBT_LR_Binary_Bal.ipynb new file mode 100644 index 0000000..bd8fd9a --- /dev/null +++ b/RF_DT_GBT_LR_Binary_Bal.ipynb @@ -0,0 +1,2548 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 214, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:py4j.java_gateway:An error occurred while trying to connect to the Java server (127.0.0.1:62046)\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 958, in _get_connection\n", + " connection = self.deque.pop()\n", + "IndexError: pop from an empty deque\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1096, in start\n", + " self.socket.connect((self.address, self.port))\n", + "ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it\n" + ] + }, + { + "ename": "Py4JNetworkError", + "evalue": "An error occurred while trying to connect to the Java server (127.0.0.1:62046)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_get_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 957\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 958\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdeque\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 959\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mIndexError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mIndexError\u001b[0m: pop from an empty deque", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mConnectionRefusedError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1095\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1096\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msocket\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maddress\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mport\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1097\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msocket\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmakefile\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"rb\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mConnectionRefusedError\u001b[0m: [WinError 10061] No connection could be made because the target machine actively refused it", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mpyspark\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mml\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mevaluation\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mBinaryClassificationEvaluator\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 25\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mpyspark\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mml\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfeature\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mOneHotEncoder\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mOneHotEncoderModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mStringIndexer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mVectorAssembler\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 26\u001b[1;33m \u001b[0mspark\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mSparkSession\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbuilder\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetOrCreate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 27\u001b[0m \u001b[0msc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mspark\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msparkContext\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\sql\\session.py\u001b[0m in \u001b[0;36mgetOrCreate\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 186\u001b[0m \u001b[0msession\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mSparkSession\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 187\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_options\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 188\u001b[1;33m \u001b[0msession\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_jsparkSession\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msessionState\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msetConfString\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 189\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msession\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 190\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self, *args)\u001b[0m\n\u001b[0;32m 1282\u001b[0m \u001b[0mproto\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mEND_COMMAND_PART\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1283\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1284\u001b[1;33m \u001b[0manswer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgateway_client\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1285\u001b[0m return_value = get_return_value(\n\u001b[0;32m 1286\u001b[0m answer, self.gateway_client, self.target_id, self.name)\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command, retry, binary)\u001b[0m\n\u001b[0;32m 1010\u001b[0m \u001b[1;32mif\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0mbinary\u001b[0m\u001b[0;31m`\u001b[0m \u001b[1;32mis\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[0;31m`\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1011\u001b[0m \"\"\"\n\u001b[1;32m-> 1012\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1013\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1014\u001b[0m \u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_get_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 958\u001b[0m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdeque\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 959\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mIndexError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 960\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 961\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 962\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_create_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 964\u001b[0m connection = GatewayConnection(\n\u001b[0;32m 965\u001b[0m self.gateway_parameters, self.gateway_property)\n\u001b[1;32m--> 966\u001b[1;33m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 967\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 968\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1106\u001b[0m \u001b[1;34m\"server ({0}:{1})\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maddress\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mport\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1107\u001b[0m \u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1108\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPy4JNetworkError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1109\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1110\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_authenticate_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m: An error occurred while trying to connect to the Java server (127.0.0.1:62046)" + ] + } + ], + "source": [ + "from pyspark.sql import SparkSession\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import RandomForestClassifier\n", + "from pyspark.ml.classification import LogisticRegression,RandomForestClassifier\n", + "from pyspark.ml.classification import GBTClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.classification import DecisionTreeClassifier\n", + "from pyspark.ml.tuning import CrossValidator, ParamGridBuilder\n", + "from pyspark.ml.classification import LogisticRegression\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator\n", + "from pyspark.ml.feature import OneHotEncoder, OneHotEncoderModel, StringIndexer, VectorAssembler\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading Train data\n", + "\n", + "us_train_cat = spark.read.csv(get_training_filename('USAccident_train_bal_bin.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+---------------+\n", + "|count(Severity)|\n", + "+---------------+\n", + "| 2|\n", + "+---------------+\n", + "\n" + ] + } + ], + "source": [ + "# Number of unique labels in Severity column\n", + "\n", + "us_train_cat.agg(countDistinct(\"Severity\")).show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 1|258836|\n", + "| 0|263700|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in training dataset\n", + "\n", + "us_train_cat.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the test data\n", + "\n", + "us_test_cat = spark.read.csv(get_training_filename('USAccident_validation_new.csv'), header = True, inferSchema = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------+------+\n", + "|Severity| count|\n", + "+--------+------+\n", + "| 3| 58617|\n", + "| 4| 5993|\n", + "| 2|131790|\n", + "+--------+------+\n", + "\n" + ] + } + ], + "source": [ + "# Checking the balance of data in testing dataset\n", + "\n", + "us_test_cat.groupBy('Severity').count().show()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Vector Assembler to convert all features except Severity to a single column features for feeding it to input of model\n", + "\n", + "va = VectorAssembler().setInputCols([i for i in us_train_cat.columns if i!='Severity']).setOutputCol('features')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# String Indexer to assign target Variable Severity name Label needed for the model to predict\n", + "\n", + "label_stringIdx = StringIndexer(inputCol=\"Severity\", outputCol=\"label\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label of 1 to category 3 and 4 and combine them to make it 1 category for train data\n", + "\n", + "us_train_cat=us_train_cat.withColumn(\"Severity\",when(((us_train_cat[\"Severity\"]==4) | (us_train_cat[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Assigning label of 1 to category 3 and 4 and combine them to make it 1 category for test data\n", + "\n", + "us_test_cat=us_test_cat.withColumn(\"Severity\",when(((us_test_cat[\"Severity\"]==4) | (us_test_cat[\"Severity\"]==3)),1).otherwise(0))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Evaluator defined for Binary Classification\n", + "\n", + "evaluator_rfb = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# RF Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Create an initial RandomForest model.\n", + "rf = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Pipeline with stages for fitting the training data\n", + "\n", + "rfModel = Pipeline(stages=[label_stringIdx,va, rf])" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Fit the training data using RF pipeline\n", + "\n", + "rf_fit = rfModel.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Predict the test data using fitted train pipeline\n", + "\n", + "pred_rfbb = rf_fit.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.7516960347127739\n" + ] + } + ], + "source": [ + "# AUC Score for the test data\n", + "\n", + "print(\"AUC Score is\", evaluator_rfb.evaluate(pred_rfbb))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_rfbb=(pred_rfbb).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.86 0.59 0.70 131790\n", + " 1 0.49 0.80 0.61 64610\n", + "\n", + " accuracy 0.66 196400\n", + " macro avg 0.68 0.70 0.66 196400\n", + "weighted avg 0.74 0.66 0.67 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_rfbb,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SparseVector(119, {2: 0.0001, 3: 0.0001, 4: 0.0, 5: 0.0, 7: 0.0, 9: 0.0006, 13: 0.0003, 14: 0.0001, 15: 0.0, 17: 0.0, 19: 0.0, 20: 0.0, 21: 0.0, 23: 0.0228, 24: 0.0088, 25: 0.0142, 26: 0.0025, 27: 0.006, 28: 0.0, 30: 0.0268, 32: 0.0003, 34: 0.0164, 36: 0.0976, 38: 0.0, 40: 0.0007, 42: 0.0017, 44: 0.0025, 48: 0.0, 49: 0.0, 50: 0.0014, 51: 0.0508, 52: 0.0274, 53: 0.0, 54: 0.0, 55: 0.0, 58: 0.0001, 59: 0.0, 60: 0.0001, 61: 0.0, 62: 0.0001, 63: 0.0, 65: 0.0, 66: 0.0, 67: 0.0, 68: 0.0, 70: 0.0, 71: 0.0001, 73: 0.0, 75: 0.0001, 77: 0.0, 78: 0.0, 81: 0.1403, 82: 0.0434, 83: 0.0004, 84: 0.0001, 85: 0.0, 87: 0.0, 89: 0.0, 92: 0.0, 93: 0.0, 94: 0.0, 95: 0.0112, 97: 0.0, 98: 0.0005, 100: 0.05, 101: 0.0002, 102: 0.0003, 103: 0.0014, 104: 0.0, 105: 0.0209, 106: 0.0001, 107: 0.0121, 109: 0.1052, 110: 0.0, 111: 0.0209, 113: 0.001, 115: 0.0088, 116: 0.013, 117: 0.0, 118: 0.288})" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Feature Importance from RF model \n", + "\n", + "rf_fit.stages[-1].featureImportances" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Base Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rfbb = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], rf_fit.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from Random Forest binary balanced')" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmcAAALsCAYAAACmxRAKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzde7y19Zz/8ddbB6WDUIrOEglFbqGMJmRikONMJtNIpKFxCD9nOTOMs0iaGGNohEyRGsdyanRHSohESmc6Swd9fn9c19Zqt/d979291l7fve7X8/HYj73WdVqf61rXda33dU5VIUmSpDbcbtwFSJIk6WaGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM6kOUiyRpJKssmY67gwycPHWYM6Sf4uye+SXJ3kPuOuZ5SS7J/ka+OuoxVJTkryzFna3SvJ5Qtd00ySHJHktbex33ckOWzYNa2IlWn9ZzhrTL+in/q7Kcm1A+/3GvJn7ZXk+/1nHDdD+wcnOTXJH5P8IMn9ljGsI5JcN63+J61gfU0EopVRSyvBZf0Qjtl7gWdX1dpV9bOF/OCBZeOaflk7L8m/JslC1jFsSbbpx2twPfKDBa5hhYJoVf2iqtYbZk1a+RjOGtOv6NeuqrWB3wJPGGj2X0P+uN8D7wbeM71FkjWB/wEOBe4EHAkclWTVZQzvzYP1V9UXh1zvvCVZZdw16LZJcrskTa6jkqwG3B04Y5b2y1pOhune/briUcA+QIshdr7+PG09suN8B7CA039BuT5beTS54tPskqyZ5OAkF/Rby+/qfyhIsnuSs5K8Mckfkpyd5OmzDauqjquqzwEXzNB6N+BPVfXhqrqOLsStA8x7b0qSTZP8T5JL+5r2H2i3c5L/S3JFkvOTvHdgxXpi///MqT1x07dqp+9d6/fgfSDJ/ya5BnhYP83el+Tcfo/QB5Pcvu9+oyTHJbk8ye+TfGM5o/OkJL9JckmSt07tqei3+L/VT/dLkvxHknUG6nxd/51dmeRnSf6qb75K3+7sfvr8V5L1BvrbN8lv+2G+fDnT+c5JPt13++sk/2+gvv2TfL2fNpcn+VWSRy9nXKeGu3+SbyT5UP89/TLJkiT7pTusd1GSPQe6P6Kfxt9MclX/uRsPtN8lyQ/7YZ2U5MED7U5K8qYk/wf8EfgY8GDgsH4eeHff3Uf6+f/KdHt1HzowjHf00/Ez/eefluQBA+23GJgfL50aZt/ueUnO7L/HLw/WPdDNHYHL+rdnJjmjb35hkpf176/sm90/ybf7aX5aksdOm07vT/LVdHvAvpXkrkk+3Hd/RpL7z+U7qqozgZOAwfF8XpKf99PgrCTPHmg3ta54dT+//C4De+b7Oo7tp+/3gc2nTYPlfYdv6L+Xq5N8Icldkny2H95JuQ17w/tl5Y398nBRksPTL2Pplr8bkzw3ybnAsX3zv0q3frm8r3fngeE9N92yfFX6dWWSBwLvA/66r/3CZZR07ySn9NPg8/188Zdapk2Pg/r/V/bT9U59u1X7fi/qa/xmknsP9Dt9fbZTuvXY7Qa62SvJScuoc8PMvizOuhxNm/ZzqfN9SY7vP+e7STYfaL99unXIZf1y8tKB73Qo67+JU1X+NfoH/AZ49LRm7wS+DawPbAicDLymb7c7cCPwdmB14NF0P3BbLudzDgCOm9bsVcBR05p9DXjBLMM4AnjtDM1XAU4HXtHXdC+6PYK79O13pPvxXQXYCjgL2L9vtwZQwCYDw9sf+NrA+1t009fxB+AhdBsftwcOAT4HrAfcETgeOKjv/r3A+4FV+/oeMcv4TX3O8f1wtgTOBp7Zt98GeGQ/jI3ofijf0bfbvu92QyDAPaa+E+CV/fd59/4zPgF8vG/3AOAq4GH9eBzcf78Pn6XGz9Lt4VwbuCfwa2Cvgel2A7B3P61fAvxmGfPEhVOfM9DvP/TT6V3AOf20Wx14Il1YWWPgO7i8r3uNfvp/rW93V7rg8nf9sJ4FXALcsW9/Uj+t7g2s1ndz0tR0Hqhvb7o9uqsBrwHOBVbr272Dbr7frR/X9wLf6tutBvys7+YOwJrATn27Pft29+q7ewvwzeXMD5tMm2Yn99/lmn035wAv7Yf3N8DVA9/9EX0/2/fdf6cf97/v634X8JW5fD5w3346/vNAN0+km09Dty64FrjvwLrihn7arQY8mW5eW7tv/0XgU31dDwAumud3+DNgC+DOwC+BnwO79N3/N/CRWcZrG+DGWdo9vx/u5sC6wJeAjw30V8BhA9/rFnRHBx5Nty54XF/nnfq/y4Gt+v43Bu4z0zpmllpO6r/bbeiWt2OAw2Yah77bM+nWb2sB3wPe0LdbFfinfhhrAB8BTpq2Xp2+PvsVsOtAN19h2evlGZfFOS5Hh82jzouBHfphfQ74RN/uTv10P6Cvf13gwcNe/03a39gL8G8ZX87M4ex3wCMH3u8B/Lx/vTvwJ/ofyb7Z0cDLl/M5M4Wzt04tXAPNPg+8cpZhHEG38r+8/zuvb74L8Mtp3b6R2VfOrwQ+07++reHs0IH2qwLXAxsPNNsV+Fn/+p10geYey5lGU5/z1wPNDgS+PEv3ewLf71/fl27v5K7AqtO6+zWw88D7LemCRYC3DX4HdMHypplWTv3K68+D4wG8aOp77afbTwba3bkfn/VmqX96ODt9oN2D+37vONDsGmCbge/gEzN81gbAc4ETp33Wj4A9+9cnAa+e1v5W4Wxa+/TT7N79+3cAXxpovwNw+cB3/zvgdjMM55v0YbZ/vxpdgNlwGfPD9HD2DwPvd6P7Ac9As6Pol6F+On1woN3LgR9Nm84XLmd+vKKf9kX3w7baMqbTccDz+te79/3ebqD9lXQ/iGv089kWA+3ew83hbC7f4UsH2h3MwIYe8HQGftinDWcqZF0+8HdA3+67dOf4TXW7PTcvK1P93X2g/UH04W2g2Ql04XcqnO3BwPpyYH6fSzh7w7R57JqBcZgezl42bb3xxVmGu1E/7Qc3dA6d1s1BwL/3rzfsp8H6swxv1mVxjsvRYfOo80MD7Z8CnNq/3od+XTjDcIay/pvEPw9rLiJJQrdQnDPQ+By6rb4pl1TVn6a1v/tt+Lir6bZwBq1LtyUzm7dW1Xr939Rhi82BLfpd4Zenu4rpwH48SLJtkq/0u8uvBF5Pt1dwRZw78PrudD+yZwx8/hfptv6hC6HnA9/sD/McOI9h/2XaJrl7kiP7w0NX0m3Brw9QVWfQhc63Ahf3u+437L/PTYFjB2r7Ed0W8l36Yf/l86rqCrof1Jls1Pf322n1Dc4bg4do/tj/X3s54zvlooHX1wLX9fUMNhsc1mDdf6Cbn+7e/w3OvzPVeS7LkeRV6Q4/XkG/145bzjfTx3Wqtk2BX1fVTTMMdnPgkIHv4hK6LfX5HIKbPu/9tvpflt70cZ0+Xae/X973c1+60w32Bnam22sEQJIn9oeq/tCPzyO55TS6ZNp0mJpOG9H9OE6f1wfHa3nf4YqM158H1iPrVdWHZvncc+j2kN25f39TVZ0/0H5z4JnT1j1L6ALcZcBewAuBC5McneSey6hpJtOnzx2mDm3OYMb5sT9c+G/9Yb0r6fYwhm75n+lzAD4JPCXJGsAzgK9W1aVzqXPasjiX5Yh51LmsZe5XMwxzmOu/iWM4W0T6lfyF3PL8j83o9gRMWb9faAfbD66w5uoMui1ToDs5G7gfs5wAvQzn0u3ZG1zZrlNVT+7bfwz4Id3hhXWBN9Et9NBt4U13DQM/QPQhb5rB/i6g+4HdauDz71hVd4Fuga+qF1XV5sBTgdcOnpcyg00HXg9O23f1td2vH4/nDIwHVfUfVbUT3SHNNYC39N/n1J7QwemzRr+yvWDw8/oV/7JW/jf1NQ3W97uZOx+5wbrvTLeivoBuem0+rdvpdU7/3m/xPsluwL/QHYpbj+7H+VoGpvcynEu3sTDTuu9c4FnTvos1q+qUOQx3plrP55bfB4zgO6mqm6rqP4HT6E5HIMladHuE3wzctbqrB7/B3KbRhXTjMX1enzKX73AUpn/uZnTf+x/699Pnm3Pp9vwMfp9rVdV7Aarqy1X1KPoQTXeobqbhzGb69PnjtA2WudgHeAzdHt070u11g1t+T7eop6p+TfddPwH4R+A/51rn4LI4z+VoLnXO5ly6Q7q3MOT138QxnC0+nwEOSneC7V3pzhP41ED71YDXJVk9ySPpDq18fqYB9SdjrkF36O926U6unzoZ/6vAmulOBr893TlK19CdFzMf3+k/68VTw0+yXZId+vbrAFdU1dVJ7kt3yASA6i5EuIIu0Ew5FXhgkvsmuQPdnrZZVdUNwOHA+5Osn86m/Yppau/Clv1W3BV0hwb/vIxBviLJHZNsQXc4+L8HxuNq4Mokm9HtHaT/jG3TnUB9e7qV37UDn3EI8I4km/bd3jXJE/p2n6XbQn5I3+9b6ALYTON5Hd0hs7clWSvJVnSHNT81U/cLYI9pdX+zqi6mO8z+wCRP6+eFvel+2G51K5cBF3HLeWAdusONl9Cd8/YmusA7F9+h2/v75iR3SHexyE59u0Powvm9AZLcKclT5zjcmXybbrl6cT+uu9H9wB25AsNclrcDL0hyF7o9SqvRnQd0U5InAn89l4H0e96PAd7YT5/t6PYyTbkt3+EwfAZ4WZLN0l0I8Bbg09P2TA76D+DpSR7Vr+vW7F9vlGTjJH/br0Ouo1t2p5bJi4BN019otQzPSndPs7WBN3DzumA+1qE7FeX3dOejvWWO/X0SeB3dcnHMcrqdbVmcz3J0W+uE7kjFPZP8c/+7tG5uvoBkKOu/SWQ4W3xeD/yUbg/WqXTnYbxzoP1v6PYUXUgXSvapqrNnGdZz6YLCe+lC3LXAhwCq6lq68zH2pzs3Y0/gSVV148yDmlkfjh4H7ES36/8Sui3UqV3eLwGek+RqunNTpq/gXg8c2e/2fmJVnc7NF0X8HPjWHMp4Md1W91K6AHYc3QnzAPfph3EV3dWh/1ZVy7ry6cvAj/thHcnN4ef1dFeyXkEXkgYD8Zp0V7tObQ2uzc2h8p10F1p8I8lVdCcL7wBQVT+iO5n8c8B5dFv3yzp88bz+/zl0e0kOA4Z9+5W5+hTdOSuX0k3jfwKoqovoTlR/Dd2K/gDg8VW1rJt2vhfYO92VXu+k+zE6ke5Qydn9Z1wyl6IG5sftuXmaPqVv9xm6+f8L/aGbU+mWi9ukDzmPB55GN67vAf6+qm51iGcYqmop3Xx5YL/n4WV00+r3wJPor2Cco+fRnc90EfBR4OMDn3NbvsNh+AjwBbpl5Fd0e8xmPQ2hX+89le4c10vplosX0f3urUK3l/FCunF4MN1eJOjWD7+hOwXhvGXU8590gfF3dKHhpbdhnP6dbt69kO7Cqblu/B5Jtw77bL9htiwzLovMbzm6rXXSH0Leje435GK6iyOmrvof5vpvomT2jQ4tNkl2pzspc77nTkhDk+QIuosP5rN1LWmO+sPyv6W7CGO+RzO0CLjnTJKkxeUZwJUGs8k1kXdRliRpEqW74ewWdPcd1ITysKYkSVJDPKwpSZLUkIk6rLn++uvXFltsMe4yJEmSluuUU065tKo2mN58pOGsv3rw/XSXLR9WVe+Y1n4Pupsk3kR3+4cXT53guLx+Z7LFFluwdOnS4Y6EJEnSCCSZ/rQNYISHNZOsQnffqscC2wLPSLLttM6+DmxfVQ8Ank13X6a59itJkjRxRnnO2Y7AWVV1dlVdT/dg1D0GO6iqqwfu7rwWNz+mYrn9SpIkTaJRhrONueUDW8/jlg/GBSDJk5P8nO7O68+eT7+SJEmTZpThbKYHot7qvh1VdVRVbUP3eJE3z6dfgCT7JVmaZOkll8zpCS6SJEnNGmU4O4+BJ8oDm9A933BGVXUisFWS9efTb1UdWlVLqmrJBhvc6oIHSZKkRWWU4exkYOskWyZZne6hp0cPdpDknknSv94BWJ3uIbTL7VeSJGkSjexWGlV1Y5IDgOPpbodxeFWdkWT/vv0hwFOBvZPcAFwL/H1/gcCM/Y6qVkmSpFZM1OOblixZUt7nTJIkLQZJTqmqJdOb+/gmSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGrjruAUXvQyz857hLm7ZR37T3uEiRJ0pi450ySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqyEjDWZLdk5yZ5Kwkr5yh/V5JTuv/vpdk+4F2v0lyepJTkywdZZ2SJEmtWHVUA06yCnAwsBtwHnBykqOr6qcDnf0a2KWqLkvyWOBQ4CED7XetqktHVaMkSVJrRrnnbEfgrKo6u6quB44A9hjsoKq+V1WX9W9PAjYZYT2SJEnNG2U42xg4d+D9eX2z2ewLfGXgfQH/m+SUJPvN1lOS/ZIsTbL0kksuWaGCJUmSxm1khzWBzNCsZuww2ZUunD18oPHOVXV+krsCX03y86o68VYDrDqU7nAoS5YsmXH4kiRJi8Uo95ydB2w68H4T4PzpHSXZDjgM2KOqfj/VvKrO7/9fDBxFd5hUkiRpoo0ynJ0MbJ1kyySrA3sCRw92kGQz4AvAP1bVLwaar5VknanXwGOAn4ywVkmSpCaM7LBmVd2Y5ADgeGAV4PCqOiPJ/n37Q4DXA3cBPpwE4MaqWgJsCBzVN1sV+HRVHTeqWiVJkloxynPOqKpjgWOnNTtk4PVzgOfM0N/ZwPbTm0uSJE06nxAgSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktSQkYazJLsnOTPJWUleOUP7vZKc1v99L8n2c+1XkiRpEo0snCVZBTgYeCywLfCMJNtO6+zXwC5VtR3wZuDQefQrSZI0cUa552xH4KyqOruqrgeOAPYY7KCqvldVl/VvTwI2mWu/kiRJk2iU4Wxj4NyB9+f1zWazL/CV+fabZL8kS5MsveSSS1agXEmSpPEbZTjLDM1qxg6TXenC2Svm229VHVpVS6pqyQYbbHCbCpUkSWrFqiMc9nnApgPvNwHOn95Rku2Aw4DHVtXv59OvJEnSpBnlnrOTga2TbJlkdWBP4OjBDpJsBnwB+Meq+sV8+pUkSZpEI9tzVlU3JjkAOB5YBTi8qs5Isn/f/hDg9cBdgA8nAbixP0Q5Y7+jqlWSJKkVozysSVUdCxw7rdkhA6+fAzxnrv1KkiRNOp8QIEmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDVk3uEsyZ2SbDeKYiRJklZ2cwpnSb6VZN0kdwZ+DHw8yXtGW5okSdLKZ657zu5YVVcCTwE+XlUPAh49urIkSZJWTnMNZ6smuRvwd8CXRliPJEnSSm2u4eyNwPHAWVV1cpJ7AL8cXVmSJEkrp1Xn2N0FVfWXiwCq6mzPOZMkSRq+ue45++Acm0mSJGkFLHPPWZKHATsBGyQ5cKDVusAqoyxMkiRpZbS8w5qrA2v33a0z0PxK4GmjKkqSJGlltcxwVlUnACck+URVnbNANUmSJK205npBwO2THApsMdhPVT1yFEVJkiStrOYazo4EDgEOA/48unIkSZJWbnMNZzdW1UdGWokkSZKWe7XmnfuXxyR5PnAUcN1U+6r6wwhrkyRJWuksb8/ZKUAB6d+/fKBdAfcYRVGSJEkrq+VdrbnlQhUiSZKkOZ5zluQpMzS+Aji9qi4ebkmSJEkrr7k+vmlfuis19+r/PgYcCHw3yT/O1lOS3ZOcmeSsJK+cof02Sb6f5LokL5vW7jdJTk9yapKlcx4jSZKkRWyuV2veBNynqi4CSLIh8BHgIcCJwH9O7yHJKsDBwG7AecDJSY6uqp8OdPYH4IXAk2b53F2r6tI51ihJkrTozXXP2RZTwax3MXCv/mrNG2bpZ0fgrKo6u6quB44A9hjsoKourqqTlzEMSZKklcpc95x9O8mX6G5GC/BU4MQkawGXz9LPxsC5A+/Po9vTNlcF/G+SAj5aVYfO1FGS/YD9ADbbbLN5DF6SJKk9cw1nL6ALZDvT3Vbjk8Dnq6qAXWfpJzM0q3nUtnNVnZ/krsBXk/y8qk681QC70HYowJIlS+YzfEmSpObMKZz1Iexz/d9cnQdsOvB+E+D8ufZcVef3/y9OchTdYdJbhTNJkqRJssxzzpJ8p/9/VZIrB/6uSnLlcoZ9MrB1ki2TrA7sCRw9l6KSrJVknanXwGOAn8ylX0mSpMVseTehfXj/f535DriqbkxyAHA8sApweFWdkWT/vv0hSTYClgLrAjcleTGwLbA+cFSSqRo/XVXHzbcGSZKkxWau55yR5OHA1lX18STrA+tU1a+X1U9VHQscO63ZIQOvL6Q73DndlcD2c61NkiRpUszpVhpJDgJeAbyqb7Q68KlRFSVJkrSymut9zp4MPBG4Bv5ysv68D3VKkiRp2eYazq7vr9gs+MtJ+pIkSRqyuYazzyb5KLBekucCX6N7vqYkSZKGaJkXBPRXT34XeB/dzWavBO4NvL6qvjr68iRJklYuy7tacxPg/cA2wGnA9+jC2ikjrkuSJGmltLz7nL0MoL+J7BJgJ+DZwMeSXF5V246+REmSpJXHXO9ztibdjWLv2P+dD5w+qqIkSZJWVss75+xQ4L7AVcD/0R3WfE9VXbYAtUmSJK10lne15mbA7YELgd/RPcz88lEXJUmStLJa3jlnu6d7wOV96c43eylwvyR/AL5fVQctQI2SJEkrjeWec9bffPYnSS4Hruj/Hg/sCBjOJEmShmh555y9kG6P2c7ADXS30fg+cDheENCE377p/uMuYd42e72zjiRJs1nenrMtgM8BL6mqC0ZfjiRJ0spteeecHbhQhUiSJGnuz9aUJEnSAjCcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDTGcSZIkNcRwJkmS1BDDmSRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQ1YddwHSsuz8wZ3HXcK8fPdfvjvuEiRJi5x7ziRJkhpiOJMkSWqI4UySJKkhhg+o0UAAACAASURBVDNJkqSGGM4kSZIaMtJwlmT3JGcmOSvJK2dov02S7ye5LsnL5tOvJEnSJBpZOEuyCnAw8FhgW+AZSbad1tkfgBcC/3Yb+pUkSZo4o9xztiNwVlWdXVXXA0cAewx2UFUXV9XJwA3z7VeSJGkSjTKcbQycO/D+vL7ZUPtNsl+SpUmWXnLJJbepUEmSpFaMMpxlhmY17H6r6tCqWlJVSzbYYIM5FydJktSiUYaz84BNB95vApy/AP1KkiQtWqMMZycDWyfZMsnqwJ7A0QvQryRJ0qI1sgefV9WNSQ4AjgdWAQ6vqjOS7N+3PyTJRsBSYF3gpiQvBratqitn6ndUtUrjcsIjdhl3CfOyy4knjLsESZp4IwtnAFV1LHDstGaHDLy+kO6Q5Zz6lSRJmnQ+IUCSJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSEjDWdJdk9yZpKzkrxyhvZJ8oG+/WlJdhho95skpyc5NcnSUdYpSZLUilVHNeAkqwAHA7sB5wEnJzm6qn460Nljga37v4cAH+n/T9m1qi4dVY2SJEmtGVk4A3YEzqqqswGSHAHsAQyGsz2AT1ZVASclWS/J3arqghHWJWkBfOilx4y7hHk74N1PGHcJkjTScLYxcO7A+/O45V6x2brZGLgAKOB/kxTw0ao6dKYPSbIfsB/AZpttNpzKJWk53vrMp427hHl7zac+N+4SJM3BKM85ywzNah7d7FxVO9Ad+nxBkkfM9CFVdWhVLamqJRtssMFtr1aSJKkBowxn5wGbDrzfBDh/rt1U1dT/i4Gj6A6TSpIkTbRRhrOTga2TbJlkdWBP4Ohp3RwN7N1ftflQ4IqquiDJWknWAUiyFvAY4CcjrFWSJKkJIzvnrKpuTHIAcDywCnB4VZ2RZP++/SHAscDjgLOAPwL79L1vCByVZKrGT1fVcaOqVZIkqRWjvCCAqjqWLoANNjtk4HUBL5ihv7OB7UdZmyRJUot8QoAkSVJDDGeSJEkNMZxJkiQ1xHAmSZLUEMOZJElSQwxnkiRJDRnprTQkSYvTz976jXGXMG/3ec0jx12CNBTuOZMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIasuq4C5AkaaG94Q1vGHcJ87LY6tWKMZxJkjRhPnvkjuMuYV7+7uk/GHcJTfGwpiRJUkMMZ5IkSQ0xnEmSJDXEcCZJktQQw5kkSVJDDGeSJEkN8VYakiRp0dj+c8ePu4R5+/HT/mZe3bvnTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSGGM0mSpIYYziRJkhpiOJMkSWqI4UySJKkhhjNJkqSGGM4kSZIaYjiTJElqiOFMkiSpIYYzSZKkhhjOJEmSGmI4kyRJaojhTJIkqSEjDWdJdk9yZpKzkrxyhvZJ8oG+/WlJdphrv5IkSZNoZOEsySrAwcBjgW2BZyTZdlpnjwW27v/2Az4yj34lSZImzij3nO0InFVVZ1fV9cARwB7TutkD+GR1TgLWS3K3OfYrSZI0cVJVoxlw8jRg96p6Tv/+H4GHVNUBA918CXhHVX2nf/914BXAFsvrd2AY+9HtdQO4N3DmSEbo1tYHLl2gzxoHx29xc/wWr0keN3D8FjvHb7g2r6oNpjdcdYQfmBmaTU+Cs3Uzl367hlWHAofOr7QVl2RpVS1Z6M9dKI7f4ub4LV6TPG7g+C12jt/CGGU4Ow/YdOD9JsD5c+xm9Tn0K0mSNHFGec7ZycDWSbZMsjqwJ3D0tG6OBvbur9p8KHBFVV0wx34lSZImzsj2nFXVjUkOAI4HVgEOr6ozkuzftz8EOBZ4HHAW8Edgn2X1O6pab6MFP5S6wBy/xc3xW7wmedzA8VvsHL8FMLILAiRJkjR/PiFAkiSpIYYzSZKkhhjOJEmSGmI4kxa5JH+TZN8kW0xr/uzxVCRpkiV5/bhrmHReEDAHSX7EzDfBDVBVtcMM7SZCkkOrar/ld9m+JDN9T1cA51TVjQtdzzAkeRvwcOCHwBOA91XVB/t2P5yEebO/nc4N1a+skuwK7AD8tKq+MtbihijJ5sDWVfW1JGsCq1bVVeOua1SS7FNVHx93HcOUZG3gXsDZVXX5uOsZlSS/rarNxl3HJDOczUGSrZbVvqp+tVC1jEKSO8/WCvhxVW2ykPWMSpKT6H7UT6Mbt/v1r+8C7F9V/zvG8m6TJKcDD+xvP7Me8GngzKp6SZIfVdUDx1ziCkvyY+Cvq+qyJC8Hnkx3G55dgKVV9aqxFjgESZ5L9xi6O1fVVkm2Bg6pqkeNubSRmYQf+CQfrqrn968fTrf8/Qq4J/C8qjp2nPWtiCRXztYKWLOqRnkT+7FKcmpVPWCcNUzsxB2mxR6+5uAS4Bxu+disqcdo3XUsFY3Gb4B9p+6Zl2Rb4OXAm4EvAIsunNHtXbkRoKouT/IE4NAkR9I9aWMSrFJVl/Wv/x74q6q6Nsk76PYYLvpwBrwA2BH4P4Cq+mWSRb/sJTlttlbAhgtZy4g8dOD1m4EnVdUPk9wD+CzdRsRidTnw4Kq6aHqLJOeOoZ6hSvLE2VoBd1/IWmZiOJuHJA8GPgjcB7g93Zd4XVWtO9bCVtzZwKOq6rfTW0zCQjhgm8GbGVfVT5M8sKrOTmZ6nOui8Ksku1TVCQBV9Wdg3yRvAZ463tKG5sok96uqn9A9kHgN4Fq69deknDd7XVVdPzUfJlmVWZ4nvMhsCPwNcNm05gG+t/DljNS6VfVDgH6dssq4C1pBnwQ2B24Vzuj2EC52nwf+m5mXszUXuJZbMZzNz4eBZwJH0G3lPotbPgN0sXofcCfgVuEMeOcC1zJKZyb5CN33B91emF8kuT1ww/jKWiFPn6lhVb22H1cAkty3wadszNX+wH/1hzcvBpYmOQHYDnjbWCsbnhOSvBpYM8luwPOBY8Zc0zB8CVi7qk6d3iLJtxa+nKHbpt87GGCLJHfqD7/fDlhtzLWtkKp67TLavWLq9SJet5wOvH2m2lvYKeE5Z/OQ5JSqelCS06vq/n2z71XVTuOubSEk2a2qvjruOm6r/iTr59OdQB/gO3SB+0/AHarq6jGWN1KL/eKAfi/EY+hOtl4VOA84flJOuu5/zPelG8fQPbrusFpJVtBToWbcdcxXfxHHoPOr6oYk6wOPqKovjKOuhbRY1y1J/hr4dVWdM0O7h1bVSQtf1UANK8myPxRJTgQeDRxOt5fpAuC5VbXdWAtbIIt1IVR3xfEkXBywLEk+X1WL8lBukrWAP/WHpafC6O2r6o/jrWxhTPq6ZTHPm8sz6euWJP+vqhb8CNKknK+xUJ5FN80OAP4MbA08bZwFLbBFe2IWQJKdk3w1yS+SnD31N+66FsjKsBV2j3EXsAK+zi3Pc1kT+NqYahmHRb1umYPFPG8uz6SvW/Ycx4d6ztk8VNXUD/mfgNeNs5YxWewL4b8DLwFOoQvXmiyLef5cY/CwelVdneQO4yxogS3m724uJn38JtlYNhwMZ/OQ5KHAQXRXsPxl2lXVvcZWlObjikm6aek8XT/uArRM1yTZYepqvyQPorsiVWrdpK9bxhKsPaw5Px+nO4H80cBfDfytLH4z7gJW0DeTvCvJw5LsMPU37qKGIcm+096vkuSgqfdV9dBb9zVxFvOhsRcDRyb5dpJv013if8CYa1pIi/m7m4tFO36uW8bz3RnO5ufKqjqmqs6vqoum/sZd1LAkeXN/f6Wp9+sm+cvjVarqKeOpbGgeAiyhu/3Cu/u/fxtrRcPzqCTHJrlbkvsBJwHrjLuoYZrppqxJ7j3w9hXT2y8WVXUysA3wz3RXFN+nqk4Zb1XDk+TRMzT7p4G3i/pJCJM8b7ISrFumSzJ4G5SxXHHr1ZrzkOTt/csvANdNNa+q2e6Cvaj04/cYYB9gI7ob7n6wqj401sI0J0n+HjgY+CPwjKr67phLGqokZwKvq6rP9u9fSvfEh23HW9lwJNkJ2IJbnjLxybEVNET9le5nAC8D1gYOo7vx7kRcULUSzJsTu25J8nVgn6mbsPenFBw27itQDWfz0B9umK6q6hELXsyI9Fu4x9Dd0fsRVXXWmEtaYUmeWVWfSnLgTO2r6j0LXdOw9c9i/A+6GyveB/gpcOAk3Yohyd2AQ+kuyNkQ+Bnw0km4P12S/wS2Ak7l5otVqqpeOL6qhifdow9eCjyvb/T6qvrMGEsaqgmfNyd63ZLkb4H30B1J2RjYg+4WWSePsy4vCJiHqpro88uSPAJ4P/Am4P7Ah5I8u6rOH29lK2yt/v8k74o/Bjigqr7W/xAeCJwM3He8ZQ1PVV2Q5Di6Z2neBLxqEn78ekuAbSf4prN3ojut4FfAJsDmSTIp4zvh8+ZEr1uq6stJrqa7dc2lwANaOF3JPWfzkGSmrdgrgFP65/4takl+ADyrqn7av38K8Laq2ma8lWl5kqxbVVdOa7Z1Vf1yXDUNW5Kv0t34+YV0P/CHAydW1cvGWtgQpHtQ/Qur6oJx1zIKSX4BvKOqDu+f1PGvwJJJebrKhM+bE71uSfIqYC+68z23o7sQ58VVdfw46/KCgPnZCXgR3eGHrYB/oTtH65P9OQaL3cOmghlA/+iRncdYz1AleWd/kcNqSb6e5NIkzxx3XUNyY5LXJfkY/OVQxL2X089ic3BV7V1Vl/cbQzvRbRxNgvWBnyY5PsnRU3/jLmqIHl1VhwNU1bX94dpXjrmmYZrkeXPS1y2bADtW1ber6mDgb2lg3nTP2TwkOR54WlVd1b9fB/gs8FRg6WI/+TPJhnRXMm5cVbsn2ZYusP37mEsbiiSnVtUDkjwZeBLdDWm/WVXbj7m0FZbkv+lurrt3Vd2v3zvx/ap6wJhLG6r+WYZb94dY1gRWnVoeF7Mku8zUvKpOWOhaRqE/HLYXcI+qelOSzYCNquoHYy5taCZ43lxZ1i23r6rrlt/lwnDP2fxsxi1vDHkdsEV/YmQzX+oK+ATdA5fv1r//Bd39lybF1OXRjwM+U1V/GGcxQ7ZV//y3G6DbO8EivrfSTJI8F/gc8NG+0SbAF8dX0fBU1Qkz/Y27riH6MPAw4Bn9+6vorv6bCJM8bzLh65YkOyY5Hfhl/377JB8cc1mGs3n6LPD9JK9J8hrg28Bn0z20+MzxljYU6/eXgt8EUFU3MlmPOTomyc/pTr7+epIN6K6umgTX91u0BZBkKyZjg2HQC+gOs18J0J/zcqv7Sy1GSR6a5OQkVye5Psmfk1y5/D4XjYdU1Qvol7equgxYfbwlDdXEzptM/rrlA8Djgd8DVNWPgV3HWhFerTkvVXVQkmOBh9NtObyoqk7qW4/l4ahDdk2Su3DzQvhQJue8CarqlUn+le5mwn9Ocg3dZdOT4CDgOGDTJP9F90PxrLFWNHzXVdX13REy6G+YPCnnZXyIbh1yJN3Gw97A1mOtaLhuSLIKN69bNqDfCJwQkzxvTvq65XZVdc7Ud9cb+04Jw9kcJFmrqq5Jsi7d/Wt+NtDuVleyLGIHAkcDWyX5LrABMBE3iQRI8nTguD6YvRbYAXgLcOF4K1txVfXVJD8EHsrNGw6XjrmsYTshyauBNZPsRncn/WPGXNPQVNVZSVapqj8DH0/yvXHXNEQfAI4C7prkrXTrldeOt6Shmth5cyVYt5ybZEeg+g2If6E7pWesvCBgDpJ8paoem+Rcbrk1FLobRW42ptKGrt/iuzfduJ1ZVTeMuaShSXJaVW2X5OHA2+ke3fTqqnrImEu7zbKcZ4NW/yDtSZDkdsC+dFdIh+78yMMm4V5Z6e6g/2i6O+dfSHdbhmdNwsUqU5JsQ/eYpgBfr6qfLaeXRWMS582VZd2S7tFbH6Bb/qC739kB4w6ghjNN3c9sVv0tNRa9JD+qqgeme0zV6VX16alm467ttkryzf7lGnSHw35M9+OwHfB/VfXwcdWmueuv9LuI7jyslwB3pLs9w6/GWtgKSnLnZbWfsItyJorrlvHysOYcJNkUuGLq8GW6O+nvAfwGOGQC9i49of9/V7r783yjf78r8C3G9ODXEfhdko/SbSH9a5Lbs8gviqmqXQGSHAHsV1Wn9+/vR/ccw0Wvv5Jq1q3IqtpuAcsZlSdV1fvpTph/I0CSF9E9sWMxO4Xuuwvd1e6X9a/XA34LbDm+0lbcJM+bk75uSfJelv3dzfi4v4WyqH+YFtCRwLrQXWZLd+7ExXSPI1n0l4NX1T5VtQ/djLptVT21qp7KhDyeY8Df0R1u2L2qLgfuDLx8vCUNzTZTK0+A/kaYk3IfosfTbUAc1//t1f8dS3f7gknwTzM0e9ZCFzFsVbVlVd2Dbrl7QlWtX1V3oftOJ2Gjb2WYNyd13fIT4Ay6x/o9DDi3/3sIDWQjD2vOwdS5Sv3rdwFU1cv78wx+XFX3H2uBQ5LkJ1V1v4H3twNOG2y22PXheuoZqd/uL5te9JJ8BrgG+BRdyH4msHZVPWOZPS4iSb5bVTsvr9likuQZwD/QXQH+7YFW6wI3VtWjZ+xxkUlySlU9aFqzpVW1ZFw1DdMkzptTJn3dkuQbwN9MHQFLsjrdhWOPHGddHtacm8FrbB8JvAagqm5KMknp9lv9UxA+Q7cQ7gl8c9m9LB79YaLncvMW+6eSHFpVY7/h4BDsQ/dsuBf1708EPjK+ckZirSQPr6rvACTZiZsfar9YfY/u5P/1gXcPNL8KOG0sFY3Gpf0V0oM/8L8fb0lDNYnz5pRJX7dsTPddXd6/v0PfbKzcczYHST5EdwjsArpHNd2rv6fNRsCXp28RLmb9xQFTe5ZOrKqjxlnPMCU5je5xVNf079eiewzJoj0vZGWS5EF0D5S+Y9/ocuDZk3DVWD8vXttv8N0L2Ab4ygSczwr85cKAg4BH9I1OBN44KRcETPK8OemSPIfuti5f6xs9EnhL9c+CHRfD2Rz0h/f+ge6xRkdU1bl98x3ong937Djr09z0J+8+uKr+1L9fAzh5Eg5LJ9kZeAOwOQN7xPvzfSZKf7/BVNXE3CA5ySl0G0V3Ak4ClgJ/rKq9xlqY5mVC582JX7ck2ZjuPm4AJ1XV78ZZDxjOhirJdxbz5cX9XrN/pbtqM9x8H7d1x1rYkCQ5kO7E66m9gU8CPlFV7xtfVcOR7rFUL6G7Ou4vd7euqok5dNRfXftUYAtu+SPxpnHVNCxJflhVOyT5F2DNqnrnYr/Ny6B+b+DLuPV3N9bzeoZlwufNlWHdshHd1cSD391YbwLtOWfDtdjPMXgn3RVVE3NzyEFV9Z4k3+Lmx2/tU1U/Gm9VQ3NFVX1l3EWM2P/QPU7sFCbr2X4ASfIwuiv99u2bTdL6+UjgELqb7I790TgjMMnz5kSvW5K8je4cyJ9x8yPFCnjc2Ipishb+Fiz23ZAXTWowm3bl6SSeB/LN/kriLzDw4zBh57xsUlW7j7uIEXkx8CrgqKo6I8k9mKCLceiuPJ2kk8inm+R5c9LXLVPnkf9p3IUMMpxp0NIk/w18kVsuhIv+fkT9idY/TrJZVf123PWMwNQjqAZvTVB0J7dOiu8luf/gPZcmRVWdAJww8P5s4IXjq2jojknyfLpTCgbXLRNxQQATPG8y+euWX9PAfc2m85yzIVrs54gk+fgMjauqnr3gxYxAfz+bBwM/oLtvDwBV9cSxFaU5S/JT4J50K9PruPmcyEV7tW2S91XVi5Mcwwx73idl3kzy6xka16ScVD6J8+bKIsmRdI+k+hq33HAY6xMCDGfzkGQz4OKBq/3WBNYfuHpz+0m5qekkSXJPYENuvad4F+B3VfXvC1/VcPQXOcyqqt6zULWMWv/8yVupqnMWupZhSfKgqjolyS4zte/3qKlxEzpvrhTrliT7ztR83L8LHtacny/QPXtyyk3A54EdARZrMEvyQZb9jLHFfnjlfcCrq+oWN/VMcg3dvZcWbTije/TIRBt4ePZVYy1kBKrqlP7/CUk26F9fMt6qhqe/AnxWi/2UiUmeN1kJ1i0w/hA2G8PZ/KxaVddPvamq6/pLqBe7peMuYMS2mB7MAKpqaZItFr6c4amqN86luySvqqq3j7qeERl8ePZ0BSzaQ2NJQreBcADd+N0uyY3AByfhNgx0z52cTbH4n685sfPmpK9bkvyIZe+U2GEBy7kVD2vOQ5KvA++euulskscDL62qXcdb2cJI8sGq+v/t3Xu07nOBx/H3x0k0HLcYkkquLek4Zayk0qA0jW4qS0pJF9XkMjSJNTIqQyuTBi3lUjoZiZLSKTmFDgmFcyq3CUlNkbsjCef4zB+/3z4e2z57P5u9n+/z+/0+r7We9ezf99n77M+2v377+3yv+5TOMVmSbrS90WRfa5ORfbRK55hOkl5o+5rSOSZD0v5US/b3sn1zXbYB1fE4P7T9+ZL5BkXSHrbnlM4xXZpYN/vV1HuLpA3He932TYPKMpY0ziah3kjx68Az66I7gN1t/6ZcqsFp8P+EpwMX2D5pVPn7gB1t71om2eA0fbFKP5pYP+t376+xfeeo8rWAeW3/nY1o4u9uMtr887X93lJqc/kMa05C3Qj7B0mr1df3TvAlMRz+FThb0juphiGgWhb+dGDnYqkGqwvvwsYaWhp2y49umEE170zS8iUCFdLE391ktPnna/u9pcjm8mmc9UHSbrZPl7TvqHIAbB9bJFj0xfafgW0kbQdsXhd/3/YFBWMNWpv/OIxo4h+Jh5/ka23TxN/dZLT552v7vaXI7y6Ns/6sVj+vVTRFeY3+n9D2hbRr1/XJ+GbpADGmLSQtGqNcwIqDDlNQo+8tHZd7yzRI46w/z6mfFzR96Xc/JK1k+4ExXjpm4GFiXJI+C/zW9pdGle8PrGP74wC2jyiRb8Aa19Nke0bpDEPiktIBplnj6mbuLUsVeeMwdEcWDKk3SJoBHFI6yHSStE290/V19fUWko4fed32V0tli2V6PXDiGOXHADsNOMu0kvSpUdczJJ02cm1768Gnin5IWlvSlyWdW19v1rv5p+29y6V76lpaNztxb6kPPh+v7D2DS/OYNM768yPgbmCWpLt7HvdIasvZcACfB14L3AVLN9XdtmiimIhtPzpG4aO0b6jouZIOBqj3FzwbuKFspOjTV4HzgHXr699QLdRpizbWza7cW8Y6sH5p47PU5vJpnPXnQKp5Z+dRzTsbeaxJy+ahjRxF1WNJkSDRr79K2nh0YV32YIE802lP4EX1H8HvARfaPqxspOjTmrbPpDpVBduLade9pY11s9X3FkkfrLey2VTSVT2PG6hHj0rKnLP+XG57S0l32G7TDWW0P0jaBrCkpwP7MgSVNMZ1KHCupMN5/DYhB9OSnglJvftDHQOcQDVHab6kl9i+qkyymIQHJD2TeuWbpK2B+8pGeupaXjfbfm85EzgfOBI4qKf8ftu3l4n0mGxC2wdJV1P9Aj8F7D/6ddvnDDzUNJC0JtUN5tVU3dbzgP1s31U0WIxL0ubAx3hsm5BrgKNs/7pcqqkjabwVtra9/cDCxJNSN2KOo6qjV1ONOLxtrGPVmqTtdbPt95YR9TFqa9HTYWX7T+USpXHWF0mvAnYH3gL8YNTLtv3uwaeKiGgOSU8DNqV64/e/th8pHCkCSR8GPk0113pkjp1tb1YuVRpnkyLpg7ZPKJ1jqkk6jvEPgN13Wa9FWZLG7bW1/cZBZZluktYGjgDWtf06SZsBL7P95cLRYgKSPgKcNnKqiqTVgd1sHz/+VzZDG+tmV+4tkm6k+l3dUTpLrzTOJknSC4DN6Nkg0vbXyyV66iTtUX/4cqqf7Yz6ehfgSttPGMqN4SDpDuAPwOnA5YxaRWV7folc06HehuEU4N9tb1H3xCyw/aLC0WICkhbanj2qrDVnMraxbnbl3iLpJ8AOwzafPAsCJkHSIcCOwAuoVm6+Fvgp1WHojWV7DoCk9wDbjQw3SPoS1byzGF7rAK8BdgPeAXwfON32NUVTTY81bZ85smWB7cWSoweqzgAAEE9JREFUhuqGGsu0nCS57g2o9418euFMU6mNdbPV95ae4xhvBC6QNBd4aOT10scyZiuNydkV2A641fa7gC1oVwN3XWBmz/XKPLYvUQwh20ts/9D2HsDWVDean0jap3C06dDKFX8dMQ84U9IOkran6o35YeFMU6l1dbMD95aRLbFuBS4CVuHxW2UV1aaGxSA8aHuJpMWSZgK3ARuUDjWFPgMs6FmB9CrgsHJxoh/1ppc7Ub3DXR84FmjjMWMHAOcAG0q6hHrFX9lI0acDgb2AD/PYSvCTiyaaWq2sm22+t9j+ROkM48mcs0mQdALwceCdVHuALQKua9NqTUnrAC+tLy+3fVvJPDE+SXOolrmfC3zD9tWFI02rrPhrnnoIc47t3UtnmU5tq5tdubdIGquxeR9wBXCS7SLnoqZx1qd6H5R1bN9aX28ErNLwTQaBapGD7etHbai4VBt+xraS9Cgwckh97//MoloOvsrgU00PSX9H1UPxPNsfqHcq39T23MLRYgKSzgPeUOoP3XRrY93syr1F0rFU8+tOr4t2Bf5INa1nxXpYd/C50jjrn6QrbW9ZOsdUk3Si7b16hjMfVymavpFim7VpxdtEJJ1BtVP5u21vLukZwKWjVwHG8KlHHV5CNfQ38gcf20cXCzWF2lg3u3JvkTTf9qt6rgXMt72tpGtL7XeWBQGT8/Nl9S413MmS1rG9ne3tgDnAX6h28m78vImW69K7qw1tfxZ4BMD2g7TrAOY2+xMwl+pvzsyeR1u0sW525d6ytqT1eq7X5bEFAQ+N8fkDkQUBfZD0tPqg3lcAH5B0E9W7v5Hu3aY32L5EdWQTkralOqpqH2A2cCJpoA2zv5d0wLJebEvPRO3hukdiZEXchhS8eUb/bH+ydIZp1sa62ZV7y4HApZKup/qbvgmwt6SVgNNKhUrjrD8/p+qSf3PpINNkhu276493BU60fRZwlqSFBXPFxGZQzY1o+rv0fhxGtf3CcySdRrVp8ntKBor+1FMmntAT06IpE4fRvrrZiXuL7XMk/YhqA3YB19Q9nwD/VSpX5pz1oe1j7/XB7rPrjROvB/ayfdHIa7Y3H/9fiFIkXdWCntu+1XtJbU11E73M9p2FI0UfJPXO1V0ReCuw2PaBhSJNubbVzbbfWyS9yvZ8SWMeQ2V73OOrplt6zvqzVsu7d08H5ku6E3gQuBiWrkht9EaKHdDqd7W9JJ1KtVnkxbavL50n+mf7ylFFl0hqxfE/0Nq62fZ7y2uA+VTHFI5mqsUrxaTnrA+SbgW+yDIqaxvmU9Q7Wj8LmGf7gbpsE2DlbKUxvCSt0TMk3Wr1zvKvAF5JtfnzQuAi28cUDRYTkrRGz+VywJbAsbY3LRRpSrWxbnbp3jKM0jjrQ9u7dyOaot7QdCuqY9Q+RHVqxwvKpoqJSLqZqjdCwGLgZuBTtn9aNNgUSt1slp6zNcdU+mzNDGv2p+3duxFDT9L5wErApVRD71vZvr1squiH7eeXzjCdUjcbqfj5meNJ46w/O5QOEBH8imo4bHOquZD3Srq0Z2VVDClJy1Odq7ltXfQT4ISmH3HUI3WzYXK2ZkTEFJK0MrAn8G9UR6qtUDhSTEDSycDyVBtcA7wLWGL7/eVSTb3UzeaQ9FHbn5P0ecbe5mWZiwAHIT1nEdEIkvammnC9JXAL8BXqlcUx9LayvUXP9QWSflkszRRL3Wykm+rnoTzQPY2ziGiKZwBHA1fWJ3Y8jqTVbd8z+FjRhyWSNrR9E4CkDYAlhTNNpdTNhrH9nfrDH9n+fdEwY8iwZkS0QlZVDy9JOwCnAL+ti9YH9rR9YbFQA5S6Obwk/YxqccDlPLZX3XVlU+Xg84hoj6yqHjKStpK0ju3zgY2BbwOLgHlAa4Y1+5C6OaRsbwO8CDgJWBs4T9IdZVNlWDMi2iPDAMPnBODV9ccvBQ4C9gFmAycCbyuUa9BSN4dUvQH7K6lWEq9JdUZq8fmCaZxFRMR0mdGzy/yuwIm2zwLOkrSwYK6IEZcAVwBHAnPHmjNYQoY1I2KoSep3A9MMHQ2fGZJGOgF2AC7oea3xnQOpm62wNnAEVe/ZjyXNk/QfhTOlcRYRQ+9bsHQX9vFks+jhczowX9J3gQeph4skbUS1WWvTpW42nO07gWuB66i2QdkE2LFoKLJaMyKGnKQFwHeA9wOfH/267aMHHir6Vs/peRYwz/YDddkmwMq2ryoa7ilK3Ww+STdR7Xl2MfBT4FLbfyubqgXdyhHRem8H3kx1v5pZOEtMku3Lxij7TYks0yB1s6Ek7W37C8Amtoduz730nEVEI0h6ne1zS+eIGC11s3mGfe+5zDmLiKb4maSjJV1RPz4nadXSoSJI3Ywplp6ziGgESWdRnYPXe3j2FrbfUi5VROpmE0laDPx1rJcA215lwJEeHyKNs4hoAkkLbc+eqCxi0FI3m0fSAtsvLp1jWTKsGRFN8aCkV4xcSHo51fYMEaWlbsaUymrNiGiKDwFf65nLcw+wR8E8ESNSN5vnm/18kqSDbR853WGe8H0zrBkRTSJpFQDbi0aV72F7zthfFTH9Ujfbp9SqzgxrRkSj2F40+o9fbb+Bh4nokbrZSkWO3krjLCLaIucXxrBK3WyuIsOLaZxFRFtkjkYMq9TN5krPWUTEU5DeiRhWqZvN1dfCgamW1ZoR0QiSZkxwBt4lAwsT0SN1s3kkHcc4PZq2962fjxhYqB5ZrRkRjSDpZuBbwCm2ry2dJ2JE6mbzSBp3q5PSq2vTOIuIRpA0E3g7sCfVlIyvAN9Yxuq4iIFJ3YyplsZZRDSOpG2B04HVqHosPm37xrKpIlI3m0bSWsDHgc2AFUfKbW9fLBRZEBARDSFphqQ3SjobOAb4HLAB8D3gB0XDRaelbjbaacB1wPOBTwK/A35RMhBkQUBENMcNwIXAUbZ/1lP+rbq3IqKU1M3meqbtL0vaz/Z8YL6k+aVDpXEWEU0xy/ZfxnphZGVVRCGpm831SP18q6SdgD8B6xXMA6RxFhHNsVjSR4AX8vi5Ie8tFykCSN1sssPrA+s/ChwHrALsXzZS5pxFRHOcCqwDvBaYT/Xu9v6iiSIqqZsNZXuu7ftsX217O9tb2j6ndK40ziKiKTay/QnggXoPop2AFxXOFAGpm40laY6k1XquV5f0lZKZII2ziGiOkbkh90raHFgVWL9cnIilUjeba5bte0cubN8DvLhgHiBzziKiOU6UtDpwCHAOsDLwibKRIoDUzSZbTtLqdaMMSWswBG2jbEIbEUNN0gFjFdfPtn30IPNEjEjdbD5J7wYOptowGGAX4D9tn1ou1RC0DiMiJjCzft4U2IqqZwLgDcBFRRJFVFI3G8721yRdAWxP1bB+yzCcj5qes4hoBEnzgLfavr++ngl80/Y/lU0WXZe62TySVrG9qB7GfALbdw86U6/0nEVEUzwXeLjn+mEy6TqGQ+pm83wdeD1wJWCqXrPe5w3KRUvjLCKa41Tg5/X5hQZ2BuaUjRQBpG42ju3X18/PL51lLBnWjIjGkPQS4JX15UW2F5TMEzEidbO5JM2i6ulc2mFl+9vFApHGWURERHRUveHsLOAa4NG62KWP3krjLCIiIjpJ0rW2NyudY7ScEBARERFddamkoWucpecsIiIiOknStsD3gNuAh6hXa9qeVTRXGmcRERHRRZJuBA4Afs1jc86wfUuxUGQrjYiIiOiu39s+Z+JPG6z0nEVEREQnSToeWI1qaPOhkfLSW2mk5ywiIiK66hlUjbIde8oMZJ+ziIiIiKhkK42IiIjoJEnrSTpb0u2S/izpLEnrlc6VxllERER01SnAOcC6wLOp5p6dUjQRGdaMiIiIjpK00PbsicoGLT1nERER0VV3Stpd0oz6sTtwV+lQ6TmLiIiITpL0XOALwMuoVmn+DNiv9Ca0aZxFREREDJHscxYRERGdJGkt4APA+vS0iWy/t1QmSOMsIiIiuuu7wMXAj4ElhbMslWHNiIiI6KRhWJk5lqzWjIiIiK6aK+mfS4cYLT1nERER0UmS7gdWAh4GHqmLbXuVcqnSOIuIiIgYKlkQEBEREZ0l6Y3AtvXlT2zPLZkH0nMWERERHSXpM8BWwGl10W7AlbYPKpcqjbOIiIjoKEm/AmbbfrS+ngEssD2rZK6s1oyIiIguW63n41WLpeiROWcRERHRVUcCCyRdCIhq7tnBZSNlWDMiIiI6SJKA9YDFVPPOBFxu+7aiwUjjLCIiIjpK0pW2tyydY7TMOYuIiIiuukzSVqVDjJaes4iIiOgkSdcCmwC3AA9QDW269GrNNM4iIiKikyQ9b6xy27cMOkuvDGtGREREVx1u+5beB3B46VBpnEVERERXvbD3ot6EtvgCgTTOIiIiolMkHSzpfmCWpEX1437gduC7heNlzllERER0k6QjbRffdHa09JxFREREV82VtBKApN0lHb2sRQKDlMZZREREdNUXgb9K2gI4kGpLja+VjZTGWURERHTXYlfzu94EHGP7GGBm4Uw5+DwiIiI6635JBwPvAl5Zr9Ys3jZKz1lERER01a7AQ8Ce9YHnLwdWKhtpCFqHERERESXYvk3SBcA7JP0PcDPw34VjpXEWERER3SJpE+DtwG7AXcAZVNuLbVc0WC37nEVERESnSHoUuBh4n+0b67Lf2t6gbLJK5pxFRERE17wVuA24UNJJknYAVDjTUuk5i4iIiE6qN6B9M9Xw5vbAHOBs2/OK5krjLCIiIrpO0hrALsCutrcvmiWNs4iIiIjhkTlnEREREUMkjbOIiIiIIZLGWUS0iqQlkhb2PNZ/Ev/GapL+ZerTRURMLHPOIqJVJP3F9spP8d9YH5hre/NJft0M20ueyveOiEjPWUS0nqQZko6S9AtJv5L0wbp8ZUnnS7pK0q8lvan+ks8AG9Y9b0dJ+kdJc3v+vS9Iek/98e8kHSrpp8AukjaU9ENJV0q6WNIL6s/bRdLVkn4p6aLB/heIiCbJ8U0R0TbPkLSw/vhm2zsD7wPus72VpBWASyTNA/4A7Gx7kaQ1gcsknQMcBGxuezaApH+c4Hv+zfYr6s89H/iQ7RskvRQ4nmr/pEOB19r+o6TVpvZHjog2SeMsItrmwZFGVY8dgVmS3lZfrwpsDPwfcISkbYFHgWcDaz+J73kGVD1xwDbAN6Wlm42vUD9fAnxV0pnAt5/E94iIjkjjLCK6QMA+ts97XGE1NLkWsKXtRyT9DlhxjK9fzOOngYz+nAfq5+WAe8doHGL7Q3VP2k7AQkmzbd/1ZH6YiGi3zDmLiC44D/iwpOUBJG1SH9uyKnB73TDbDnhe/fn3AzN7vv4WYDNJK0haFdhhrG9iexFws6Rd6u8jSVvUH29o+3LbhwJ3As+Z+h8zItogPWcR0QUnA+sDV6kab7yD6jy904DvSboCWAhcD2D7LkmXSLoaONf2x+rhyF8BNwALxvle7wS+KOkQYHngG8AvgaMkbUzVi3d+XRYR8QTZSiMiIiJiiGRYMyIiImKIpHEWERERMUTSOIuIiIgYImmcRURERAyRNM4iIiIihkgaZxERERFDJI2ziIiIiCHy/6gPGgqQZpWFAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Base Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rfbb['column'][:10], y=feat_imp_tuned_rfbb['weight'][:10],data=feat_imp_tuned_rfbb)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest binary balanced\")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6618991853360489" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Accuracy calculation for RF Base Model\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "\n", + "binary_prediction=(pred_rfbb).select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# RF Grid Search " + ] + }, + { + "cell_type": "code", + "execution_count": 210, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:py4j.java_gateway:An error occurred while trying to connect to the Java server (127.0.0.1:62046)\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1174, in send_command\n", + " self.socket.sendall(command.encode(\"utf-8\"))\n", + "ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1014, in send_command\n", + " response = connection.send_command(command)\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1178, in send_command\n", + " \"Error while sending\", e, proto.ERROR_ON_SEND)\n", + "py4j.protocol.Py4JNetworkError: Error while sending\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 958, in _get_connection\n", + " connection = self.deque.pop()\n", + "IndexError: pop from an empty deque\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1096, in start\n", + " self.socket.connect((self.address, self.port))\n", + "ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it\n" + ] + }, + { + "ename": "Py4JNetworkError", + "evalue": "An error occurred while trying to connect to the Java server (127.0.0.1:62046)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mConnectionResetError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command)\u001b[0m\n\u001b[0;32m 1173\u001b[0m \u001b[1;31m# if it sent a RST packet (SO_LINGER)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1174\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msocket\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msendall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mencode\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"utf-8\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1175\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mConnectionResetError\u001b[0m: [WinError 10054] An existing connection was forcibly closed by the remote host", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command, retry, binary)\u001b[0m\n\u001b[0;32m 1013\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1014\u001b[1;33m \u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1015\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mbinary\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command)\u001b[0m\n\u001b[0;32m 1177\u001b[0m raise Py4JNetworkError(\n\u001b[1;32m-> 1178\u001b[1;33m \"Error while sending\", e, proto.ERROR_ON_SEND)\n\u001b[0m\u001b[0;32m 1179\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m: Error while sending", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_get_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 957\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 958\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdeque\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 959\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mIndexError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mIndexError\u001b[0m: pop from an empty deque", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mConnectionRefusedError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1095\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1096\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msocket\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maddress\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mport\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1097\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msocket\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmakefile\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"rb\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mConnectionRefusedError\u001b[0m: [WinError 10061] No connection could be made because the target machine actively refused it", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Create an initial RandomForest model.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mrf_new\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mRandomForestClassifier\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlabelCol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"label\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfeaturesCol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"features\"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mseed\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m42\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m# Train model with Training Data\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mrfModel_new\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mPipeline\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstages\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mlabel_stringIdx\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mva\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrf_new\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\__init__.py\u001b[0m in \u001b[0;36mwrapper\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 109\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Method %s forces keyword arguments.\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 110\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_input_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 111\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 112\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 113\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\classification.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, featuresCol, labelCol, predictionCol, probabilityCol, rawPredictionCol, maxDepth, maxBins, minInstancesPerNode, minInfoGain, maxMemoryInMB, cacheNodeIds, checkpointInterval, impurity, numTrees, featureSubsetStrategy, seed, subsamplingRate, leafCol, minWeightFractionPerNode)\u001b[0m\n\u001b[0;32m 1424\u001b[0m \u001b[0msuper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mRandomForestClassifier\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1425\u001b[0m self._java_obj = self._new_java_obj(\n\u001b[1;32m-> 1426\u001b[1;33m \"org.apache.spark.ml.classification.RandomForestClassifier\", self.uid)\n\u001b[0m\u001b[0;32m 1427\u001b[0m self._setDefault(maxDepth=5, maxBins=32, minInstancesPerNode=1, minInfoGain=0.0,\n\u001b[0;32m 1428\u001b[0m \u001b[0mmaxMemoryInMB\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m256\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcacheNodeIds\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcheckpointInterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\wrapper.py\u001b[0m in \u001b[0;36m_new_java_obj\u001b[1;34m(java_class, *args)\u001b[0m\n\u001b[0;32m 65\u001b[0m \u001b[0mjava_obj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_jvm\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 66\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mname\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mjava_class\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\".\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 67\u001b[1;33m \u001b[0mjava_obj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjava_obj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 68\u001b[0m \u001b[0mjava_args\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0m_py2java\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0marg\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0marg\u001b[0m \u001b[1;32min\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 69\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mjava_obj\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mjava_args\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m 1676\u001b[0m \u001b[0mproto\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mREFLECTION_COMMAND_NAME\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1677\u001b[0m \u001b[0mproto\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mREFL_GET_UNKNOWN_SUB_COMMAND_NAME\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mname\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;34m\"\\n\"\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_id\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1678\u001b[1;33m \"\\n\" + proto.END_COMMAND_PART)\n\u001b[0m\u001b[0;32m 1679\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0manswer\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mproto\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mSUCCESS_PACKAGE\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1680\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mJavaPackage\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_gateway_client\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mjvm_id\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_id\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command, retry, binary)\u001b[0m\n\u001b[0;32m 1027\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_should_retry\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mretry\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpne\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1028\u001b[0m \u001b[0mlogging\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minfo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Exception while sending command.\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1029\u001b[1;33m \u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbinary\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mbinary\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1030\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1031\u001b[0m logging.exception(\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36msend_command\u001b[1;34m(self, command, retry, binary)\u001b[0m\n\u001b[0;32m 1010\u001b[0m \u001b[1;32mif\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0mbinary\u001b[0m\u001b[0;31m`\u001b[0m \u001b[1;32mis\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[0;31m`\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1011\u001b[0m \"\"\"\n\u001b[1;32m-> 1012\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1013\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1014\u001b[0m \u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_get_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 958\u001b[0m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdeque\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 959\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mIndexError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 960\u001b[1;33m \u001b[0mconnection\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 961\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 962\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m_create_connection\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 964\u001b[0m connection = GatewayConnection(\n\u001b[0;32m 965\u001b[0m self.gateway_parameters, self.gateway_property)\n\u001b[1;32m--> 966\u001b[1;33m \u001b[0mconnection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 967\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mconnection\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 968\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36mstart\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1106\u001b[0m \u001b[1;34m\"server ({0}:{1})\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0maddress\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mport\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1107\u001b[0m \u001b[0mlogger\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1108\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mPy4JNetworkError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1109\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1110\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_authenticate_connection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mPy4JNetworkError\u001b[0m: An error occurred while trying to connect to the Java server (127.0.0.1:62046)" + ] + } + ], + "source": [ + "\n", + "# Create an initial RandomForest model\n", + "\n", + "rf_new = RandomForestClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Pipeline with stages for RF Grid Search Model\n", + "\n", + "rfModel_new = Pipeline(stages=[label_stringIdx,va, rf_new])\n", + "\n", + "# Grid Search for tuning Hyper parameters \n", + "\n", + "paramGrid_rft = ParamGridBuilder().addGrid(rf_new.numTrees, [10,25,60]).addGrid(rf_new.maxDepth, [3,6,10]).addGrid(rf_new.impurity,[\"entropy\", \"gini\"]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "metadata": {}, + "outputs": [ + { + "ename": "Py4JJavaError", + "evalue": "An error occurred while calling o124422.fit.\n: org.apache.spark.SparkException: Job aborted due to stage failure: Task 7 in stage 51187.0 failed 1 times, most recent failure: Lost task 7.0 in stage 51187.0 (TID 368623, DESKTOP-TT8TT9T.fios-router.home, executor driver): java.lang.OutOfMemoryError: Java heap space\r\n\tat java.lang.reflect.Array.newArray(Native Method)\r\n\tat java.lang.reflect.Array.newInstance(Unknown Source)\r\n\tat java.io.ObjectInputStream.readArray(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:76)\r\n\tat org.apache.spark.serializer.DeserializationStream$$anon$1.getNext(Serializer.scala:168)\r\n\tat org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIterator(MemoryStore.scala:221)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIteratorAsValues(MemoryStore.scala:299)\r\n\tat org.apache.spark.storage.BlockManager.maybeCacheDiskValuesInMemory(BlockManager.scala:1516)\r\n\tat org.apache.spark.storage.BlockManager.getLocalValues(BlockManager.scala:825)\r\n\tat org.apache.spark.storage.BlockManager.get(BlockManager.scala:1111)\r\n\tat org.apache.spark.storage.BlockManager.getOrElseUpdate(BlockManager.scala:1178)\r\n\tat org.apache.spark.rdd.RDD.getOrCompute(RDD.scala:360)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:311)\r\n\tat org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)\r\n\tat org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:349)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:313)\r\n\tat org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)\r\n\tat org.apache.spark.scheduler.Task.run(Task.scala:127)\r\n\nDriver stacktrace:\r\n\tat org.apache.spark.scheduler.DAGScheduler.failJobAndIndependentStages(DAGScheduler.scala:1989)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2(DAGScheduler.scala:1977)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2$adapted(DAGScheduler.scala:1976)\r\n\tat scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)\r\n\tat scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)\r\n\tat scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)\r\n\tat org.apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:1976)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1(DAGScheduler.scala:956)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1$adapted(DAGScheduler.scala:956)\r\n\tat scala.Option.foreach(Option.scala:407)\r\n\tat org.apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:956)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:2206)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2155)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2144)\r\n\tat org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:49)\r\n\tat org.apache.spark.scheduler.DAGScheduler.runJob(DAGScheduler.scala:758)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2116)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2137)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2156)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2181)\r\n\tat org.apache.spark.rdd.RDD.$anonfun$collect$1(RDD.scala:1004)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)\r\n\tat org.apache.spark.rdd.RDD.withScope(RDD.scala:388)\r\n\tat org.apache.spark.rdd.RDD.collect(RDD.scala:1003)\r\n\tat org.apache.spark.rdd.PairRDDFunctions.$anonfun$collectAsMap$1(PairRDDFunctions.scala:737)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)\r\n\tat org.apache.spark.rdd.RDD.withScope(RDD.scala:388)\r\n\tat org.apache.spark.rdd.PairRDDFunctions.collectAsMap(PairRDDFunctions.scala:736)\r\n\tat org.apache.spark.ml.tree.impl.RandomForest$.findBestSplits(RandomForest.scala:588)\r\n\tat org.apache.spark.ml.tree.impl.RandomForest$.run(RandomForest.scala:226)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.$anonfun$train$1(RandomForestClassifier.scala:144)\r\n\tat org.apache.spark.ml.util.Instrumentation$.$anonfun$instrumented$1(Instrumentation.scala:191)\r\n\tat scala.util.Try$.apply(Try.scala:213)\r\n\tat org.apache.spark.ml.util.Instrumentation$.instrumented(Instrumentation.scala:191)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.train(RandomForestClassifier.scala:122)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.train(RandomForestClassifier.scala:48)\r\n\tat org.apache.spark.ml.Predictor.fit(Predictor.scala:152)\r\n\tat sun.reflect.GeneratedMethodAccessor2715.invoke(Unknown Source)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\r\n\tat java.lang.reflect.Method.invoke(Unknown Source)\r\n\tat py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)\r\n\tat py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)\r\n\tat py4j.Gateway.invoke(Gateway.java:282)\r\n\tat py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)\r\n\tat py4j.commands.CallCommand.execute(CallCommand.java:79)\r\n\tat py4j.GatewayConnection.run(GatewayConnection.java:238)\r\n\tat java.lang.Thread.run(Unknown Source)\r\nCaused by: java.lang.OutOfMemoryError: Java heap space\r\n\tat java.lang.reflect.Array.newArray(Native Method)\r\n\tat java.lang.reflect.Array.newInstance(Unknown Source)\r\n\tat java.io.ObjectInputStream.readArray(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:76)\r\n\tat org.apache.spark.serializer.DeserializationStream$$anon$1.getNext(Serializer.scala:168)\r\n\tat org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIterator(MemoryStore.scala:221)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIteratorAsValues(MemoryStore.scala:299)\r\n\tat org.apache.spark.storage.BlockManager.maybeCacheDiskValuesInMemory(BlockManager.scala:1516)\r\n\tat org.apache.spark.storage.BlockManager.getLocalValues(BlockManager.scala:825)\r\n\tat org.apache.spark.storage.BlockManager.get(BlockManager.scala:1111)\r\n\tat org.apache.spark.storage.BlockManager.getOrElseUpdate(BlockManager.scala:1178)\r\n\tat org.apache.spark.rdd.RDD.getOrCompute(RDD.scala:360)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:311)\r\n\tat org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)\r\n\tat org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:349)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:313)\r\n\tat org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)\r\n\tat org.apache.spark.scheduler.Task.run(Task.scala:127)\r\n", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mPy4JJavaError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mcv_rf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mCrossValidator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mrfModel_new\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mestimatorParamMaps\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparamGrid_rft\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mevaluator\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mevaluator_rfb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnumFolds\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mseed\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m42\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mus_train_cat\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\base.py\u001b[0m in \u001b[0;36mfit\u001b[1;34m(self, dataset, params)\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 130\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 131\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 132\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 133\u001b[0m raise ValueError(\"Params must be either a param map or a list/tuple of param maps, \"\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\tuning.py\u001b[0m in \u001b[0;36m_fit\u001b[1;34m(self, dataset)\u001b[0m\n\u001b[0;32m 350\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 351\u001b[0m \u001b[0mtasks\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_parallelFitTasks\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mest\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0meva\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalidation\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mepm\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcollectSubModelsParam\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 352\u001b[1;33m \u001b[1;32mfor\u001b[0m \u001b[0mj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmetric\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msubModel\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mimap_unordered\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtasks\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 353\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mj\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mmetric\u001b[0m \u001b[1;33m/\u001b[0m \u001b[0mnFolds\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 354\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcollectSubModelsParam\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\multiprocessing\\pool.py\u001b[0m in \u001b[0;36mnext\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 746\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0msuccess\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 747\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 748\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 749\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 750\u001b[0m \u001b[0m__next__\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnext\u001b[0m \u001b[1;31m# XXX\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\multiprocessing\\pool.py\u001b[0m in \u001b[0;36mworker\u001b[1;34m(inqueue, outqueue, initializer, initargs, maxtasks, wrap_exception)\u001b[0m\n\u001b[0;32m 119\u001b[0m \u001b[0mjob\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwds\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtask\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 120\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 121\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 122\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 123\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mwrap_exception\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mfunc\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0m_helper_reraises_exception\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\tuning.py\u001b[0m in \u001b[0;36m\u001b[1;34m(f)\u001b[0m\n\u001b[0;32m 350\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 351\u001b[0m \u001b[0mtasks\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_parallelFitTasks\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mest\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0meva\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalidation\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mepm\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcollectSubModelsParam\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 352\u001b[1;33m \u001b[1;32mfor\u001b[0m \u001b[0mj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmetric\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msubModel\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mpool\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mimap_unordered\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtasks\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 353\u001b[0m \u001b[0mmetrics\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mj\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mmetric\u001b[0m \u001b[1;33m/\u001b[0m \u001b[0mnFolds\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 354\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcollectSubModelsParam\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\tuning.py\u001b[0m in \u001b[0;36msingleTask\u001b[1;34m()\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 51\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0msingleTask\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 52\u001b[1;33m \u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodelIter\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 53\u001b[0m \u001b[0mmetric\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0meva\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mevaluate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtransform\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mvalidation\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mepm\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 54\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmetric\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcollectSubModel\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\base.py\u001b[0m in \u001b[0;36m__next__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 60\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"No models remaining.\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 61\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcounter\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 62\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfitSingleModel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 63\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 64\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\base.py\u001b[0m in \u001b[0;36mfitSingleModel\u001b[1;34m(index)\u001b[0m\n\u001b[0;32m 103\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 104\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mfitSingleModel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 105\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mestimator\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mparamMaps\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 106\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 107\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0m_FitMultipleIterator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfitSingleModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mparamMaps\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\base.py\u001b[0m in \u001b[0;36mfit\u001b[1;34m(self, dataset, params)\u001b[0m\n\u001b[0;32m 127\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 128\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mparams\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 129\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 130\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 131\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\pipeline.py\u001b[0m in \u001b[0;36m_fit\u001b[1;34m(self, dataset)\u001b[0m\n\u001b[0;32m 107\u001b[0m \u001b[0mdataset\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstage\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtransform\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 108\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;31m# must be an Estimator\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 109\u001b[1;33m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstage\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 110\u001b[0m \u001b[0mtransformers\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 111\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mi\u001b[0m \u001b[1;33m<\u001b[0m \u001b[0mindexOfLastEstimator\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\base.py\u001b[0m in \u001b[0;36mfit\u001b[1;34m(self, dataset, params)\u001b[0m\n\u001b[0;32m 129\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 130\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 131\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 132\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 133\u001b[0m raise ValueError(\"Params must be either a param map or a list/tuple of param maps, \"\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\wrapper.py\u001b[0m in \u001b[0;36m_fit\u001b[1;34m(self, dataset)\u001b[0m\n\u001b[0;32m 319\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 320\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 321\u001b[1;33m \u001b[0mjava_model\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_fit_java\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 322\u001b[0m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjava_model\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 323\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_copyValues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\ml\\wrapper.py\u001b[0m in \u001b[0;36m_fit_java\u001b[1;34m(self, dataset)\u001b[0m\n\u001b[0;32m 316\u001b[0m \"\"\"\n\u001b[0;32m 317\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_transfer_params_to_java\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 318\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_java_obj\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_jdf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 319\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 320\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_fit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdataset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self, *args)\u001b[0m\n\u001b[0;32m 1284\u001b[0m \u001b[0manswer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgateway_client\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_command\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommand\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1285\u001b[0m return_value = get_return_value(\n\u001b[1;32m-> 1286\u001b[1;33m answer, self.gateway_client, self.target_id, self.name)\n\u001b[0m\u001b[0;32m 1287\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1288\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mtemp_arg\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mtemp_args\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\pyspark\\sql\\utils.py\u001b[0m in \u001b[0;36mdeco\u001b[1;34m(*a, **kw)\u001b[0m\n\u001b[0;32m 96\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdeco\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 97\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 98\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 99\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mpy4j\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprotocol\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPy4JJavaError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 100\u001b[0m \u001b[0mconverted\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconvert_exception\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjava_exception\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\protocol.py\u001b[0m in \u001b[0;36mget_return_value\u001b[1;34m(answer, gateway_client, target_id, name)\u001b[0m\n\u001b[0;32m 326\u001b[0m raise Py4JJavaError(\n\u001b[0;32m 327\u001b[0m \u001b[1;34m\"An error occurred while calling {0}{1}{2}.\\n\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 328\u001b[1;33m format(target_id, \".\", name), value)\n\u001b[0m\u001b[0;32m 329\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 330\u001b[0m raise Py4JError(\n", + "\u001b[1;31mPy4JJavaError\u001b[0m: An error occurred while calling o124422.fit.\n: org.apache.spark.SparkException: Job aborted due to stage failure: Task 7 in stage 51187.0 failed 1 times, most recent failure: Lost task 7.0 in stage 51187.0 (TID 368623, DESKTOP-TT8TT9T.fios-router.home, executor driver): java.lang.OutOfMemoryError: Java heap space\r\n\tat java.lang.reflect.Array.newArray(Native Method)\r\n\tat java.lang.reflect.Array.newInstance(Unknown Source)\r\n\tat java.io.ObjectInputStream.readArray(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:76)\r\n\tat org.apache.spark.serializer.DeserializationStream$$anon$1.getNext(Serializer.scala:168)\r\n\tat org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIterator(MemoryStore.scala:221)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIteratorAsValues(MemoryStore.scala:299)\r\n\tat org.apache.spark.storage.BlockManager.maybeCacheDiskValuesInMemory(BlockManager.scala:1516)\r\n\tat org.apache.spark.storage.BlockManager.getLocalValues(BlockManager.scala:825)\r\n\tat org.apache.spark.storage.BlockManager.get(BlockManager.scala:1111)\r\n\tat org.apache.spark.storage.BlockManager.getOrElseUpdate(BlockManager.scala:1178)\r\n\tat org.apache.spark.rdd.RDD.getOrCompute(RDD.scala:360)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:311)\r\n\tat org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)\r\n\tat org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:349)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:313)\r\n\tat org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)\r\n\tat org.apache.spark.scheduler.Task.run(Task.scala:127)\r\n\nDriver stacktrace:\r\n\tat org.apache.spark.scheduler.DAGScheduler.failJobAndIndependentStages(DAGScheduler.scala:1989)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2(DAGScheduler.scala:1977)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2$adapted(DAGScheduler.scala:1976)\r\n\tat scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)\r\n\tat scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)\r\n\tat scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)\r\n\tat org.apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:1976)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1(DAGScheduler.scala:956)\r\n\tat org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1$adapted(DAGScheduler.scala:956)\r\n\tat scala.Option.foreach(Option.scala:407)\r\n\tat org.apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:956)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:2206)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2155)\r\n\tat org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2144)\r\n\tat org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:49)\r\n\tat org.apache.spark.scheduler.DAGScheduler.runJob(DAGScheduler.scala:758)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2116)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2137)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2156)\r\n\tat org.apache.spark.SparkContext.runJob(SparkContext.scala:2181)\r\n\tat org.apache.spark.rdd.RDD.$anonfun$collect$1(RDD.scala:1004)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)\r\n\tat org.apache.spark.rdd.RDD.withScope(RDD.scala:388)\r\n\tat org.apache.spark.rdd.RDD.collect(RDD.scala:1003)\r\n\tat org.apache.spark.rdd.PairRDDFunctions.$anonfun$collectAsMap$1(PairRDDFunctions.scala:737)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)\r\n\tat org.apache.spark.rdd.RDD.withScope(RDD.scala:388)\r\n\tat org.apache.spark.rdd.PairRDDFunctions.collectAsMap(PairRDDFunctions.scala:736)\r\n\tat org.apache.spark.ml.tree.impl.RandomForest$.findBestSplits(RandomForest.scala:588)\r\n\tat org.apache.spark.ml.tree.impl.RandomForest$.run(RandomForest.scala:226)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.$anonfun$train$1(RandomForestClassifier.scala:144)\r\n\tat org.apache.spark.ml.util.Instrumentation$.$anonfun$instrumented$1(Instrumentation.scala:191)\r\n\tat scala.util.Try$.apply(Try.scala:213)\r\n\tat org.apache.spark.ml.util.Instrumentation$.instrumented(Instrumentation.scala:191)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.train(RandomForestClassifier.scala:122)\r\n\tat org.apache.spark.ml.classification.RandomForestClassifier.train(RandomForestClassifier.scala:48)\r\n\tat org.apache.spark.ml.Predictor.fit(Predictor.scala:152)\r\n\tat sun.reflect.GeneratedMethodAccessor2715.invoke(Unknown Source)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\r\n\tat java.lang.reflect.Method.invoke(Unknown Source)\r\n\tat py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)\r\n\tat py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)\r\n\tat py4j.Gateway.invoke(Gateway.java:282)\r\n\tat py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)\r\n\tat py4j.commands.CallCommand.execute(CallCommand.java:79)\r\n\tat py4j.GatewayConnection.run(GatewayConnection.java:238)\r\n\tat java.lang.Thread.run(Unknown Source)\r\nCaused by: java.lang.OutOfMemoryError: Java heap space\r\n\tat java.lang.reflect.Array.newArray(Native Method)\r\n\tat java.lang.reflect.Array.newInstance(Unknown Source)\r\n\tat java.io.ObjectInputStream.readArray(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.defaultReadFields(Unknown Source)\r\n\tat java.io.ObjectInputStream.readSerialData(Unknown Source)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject0(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat java.io.ObjectInputStream.readObject(Unknown Source)\r\n\tat org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:76)\r\n\tat org.apache.spark.serializer.DeserializationStream$$anon$1.getNext(Serializer.scala:168)\r\n\tat org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIterator(MemoryStore.scala:221)\r\n\tat org.apache.spark.storage.memory.MemoryStore.putIteratorAsValues(MemoryStore.scala:299)\r\n\tat org.apache.spark.storage.BlockManager.maybeCacheDiskValuesInMemory(BlockManager.scala:1516)\r\n\tat org.apache.spark.storage.BlockManager.getLocalValues(BlockManager.scala:825)\r\n\tat org.apache.spark.storage.BlockManager.get(BlockManager.scala:1111)\r\n\tat org.apache.spark.storage.BlockManager.getOrElseUpdate(BlockManager.scala:1178)\r\n\tat org.apache.spark.rdd.RDD.getOrCompute(RDD.scala:360)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:311)\r\n\tat org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:52)\r\n\tat org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:349)\r\n\tat org.apache.spark.rdd.RDD.iterator(RDD.scala:313)\r\n\tat org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)\r\n\tat org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)\r\n\tat org.apache.spark.scheduler.Task.run(Task.scala:127)\r\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:root:Exception while sending command.\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1181, in send_command\n", + " answer = smart_decode(self.stream.readline()[:-1])\n", + " File \"C:\\Users\\hites\\Anaconda3\\lib\\socket.py\", line 589, in readinto\n", + " return self._sock.recv_into(b)\n", + "ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1014, in send_command\n", + " response = connection.send_command(command)\n", + " File \"C:\\Spark_installed\\spark-3.0.0-preview2-bin-hadoop2.7\\python\\lib\\py4j-0.10.8.1-src.zip\\py4j\\java_gateway.py\", line 1193, in send_command\n", + " \"Error while receiving\", e, proto.ERROR_ON_RECEIVE)\n", + "py4j.protocol.Py4JNetworkError: Error while receiving\n" + ] + } + ], + "source": [ + "# 5-fold Cross Validator Pipeline and fitting the train data using this cv pipeline\n", + "\n", + "cv_rf = CrossValidator(estimator=rfModel_new, estimatorParamMaps=paramGrid_rft, evaluator=evaluator_rfb, numFolds=5,seed=42).fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Predicting the test data using fitted cv pipeline\n", + "\n", + "pred_rft = cv_rf.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.7819275566312943\n" + ] + } + ], + "source": [ + "# AUC Score of tuned RF model\n", + "\n", + "print(\"AUC Score is\", evaluator_rfb.evaluate(pred_rft))" + ] + }, + { + "cell_type": "code", + "execution_count": 216, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='RandomForestClassifier_8713e549bc1f', name='featuresCol', doc='features column name.'): 'features',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='seed', doc='random seed.'): 42,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees. Users can set how often should the cache be checkpointed or disable it by setting checkpointInterval.'): False,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext.'): 10,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='featureSubsetStrategy', doc=\"The number of features to consider for splits at each tree node. Supported options: 'auto' (choose automatically for task: If numTrees == 1, set to 'all'. If numTrees > 1 (forest), set to 'sqrt' for classification and to 'onethird' for regression), 'all' (use all features), 'onethird' (use 1/3 of the features), 'sqrt' (use sqrt(number of features)), 'log2' (use log2(number of features)), 'n' (when n is in the range (0, 1.0], use n * number of features. When n is in the range (1, number of features), use n features). default = 'auto'\"): 'auto',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'entropy',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='leafCol', doc='Leaf indices column name. Predicted leaf index of each instance in each tree by preorder.'): '',\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation. If too small, then 1 node will be split per iteration, and its aggregates may exceed this size.'): 256,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='minWeightFractionPerNode', doc='Minimum fraction of the weighted sample count that each child must have after split. If a split causes the fraction of the total weight in the left or right child to be less than minWeightFractionPerNode, the split will be discarded as invalid. Should be in interval [0.0, 0.5).'): 0.0,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='numTrees', doc='Number of trees to train (>= 1).'): 60,\n", + " Param(parent='RandomForestClassifier_8713e549bc1f', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0}" + ] + }, + "execution_count": 216, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper Parameters after tuning\n", + "\n", + "cv_rf.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "60" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best model number of trees parameter from Grid Search\n", + "\n", + "cv_rf.bestModel.stages[-1].getNumTrees" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6788441955193483" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Accuracy of the model on test data\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]\n", + "\n", + "binary_prediction=pred_rft.select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_rft=pred_rft.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.87 0.61 0.72 131790\n", + " 1 0.51 0.81 0.62 64610\n", + "\n", + " accuracy 0.68 196400\n", + " macro avg 0.69 0.71 0.67 196400\n", + "weighted avg 0.75 0.68 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_rft,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of RF Grid Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_rfg = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cv_rf.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from Random Forest Grid')" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of RF Grid Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_rfg['column'][:10], y=feat_imp_tuned_rfg['weight'][:10],data=feat_imp_tuned_rfg)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from Random Forest Grid\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GBT Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize the GBT Base model\n", + "\n", + "gbt = GBTClassifier(seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "# Pipeline with stages to be used to fit the train data\n", + "\n", + "gbt_pipe = Pipeline(stages=[label_stringIdx, va, gbt])" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "# Fitting the training data using the pipeline above\n", + "\n", + "gbtModel = gbt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.7842374103722184\n" + ] + } + ], + "source": [ + "# AUC Score from the model on the test data\n", + "\n", + "print(\"AUC Score is\", evaluator_rfb.evaluate(gbtModel.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_gbtn=(gbtModel.transform(us_test_cat)).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [], + "source": [ + "# True labels from the test data for the target variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.88 0.60 0.72 131790\n", + " 1 0.51 0.83 0.63 64610\n", + "\n", + " accuracy 0.68 196400\n", + " macro avg 0.69 0.72 0.67 196400\n", + "weighted avg 0.75 0.68 0.69 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_gbtn,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of GBT Base Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_gtbb = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], gbtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from GBT Base Model')" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of GBT Base Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_gtbb['column'][:10], y=feat_imp_tuned_gtbb['weight'][:10],data=feat_imp_tuned_gtbb)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from GBT Base Model\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GBT Binary Classification Grid Search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GBT Binary Tuned Best Model" + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Initializing GBT Grid Pipeline \n", + "\n", + "gbt_t_new = GBTClassifier(maxIter=55,seed=42)\n", + "\n", + "# Creating pipeline for GBT grid Model \n", + "\n", + "gbt_pipe_t_new = Pipeline(stages=[label_stringIdx, va, gbt_t_new])\n", + "\n", + "# Binary Classification Evaluator\n", + "\n", + "evaluator = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "\n", + "# Creating Grid Search for Hyper Parameter Tuning for GBT model\n", + "\n", + "grid_gbt_t_new = ParamGridBuilder().addGrid(gbt_t_new.stepSize, [0.2,0.4,0.01]).addGrid(gbt_t_new.maxDepth, [3, 5, 8]).build()\n", + "\n", + "# Cross Validator Pipeline with 5 fold cv to fit the training data\n", + "\n", + "cv1_gbt_t_new = CrossValidator(estimator=gbt_pipe_t_new,estimatorParamMaps=grid_gbt_t_new, numFolds=5, evaluator=evaluator,seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": {}, + "outputs": [], + "source": [ + "# Fitting train data using 5-fold cross validator pipeline\n", + "\n", + "cvModel_gbt_t_new = cv1_gbt_t_new.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.8118245222266022\n" + ] + } + ], + "source": [ + "# AUC Score from the fitted pipeline for the test data\n", + "\n", + "print(\"AUC Score is\", evaluator.evaluate(cvModel_gbt_t_new.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 173, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7997203339021297" + ] + }, + "execution_count": 173, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# AUC Score from the Cross validator Pipeline\n", + "\n", + "np.max(cvModel_gbt_t_new.avgMetrics)" + ] + }, + { + "cell_type": "code", + "execution_count": 217, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='GBTClassifier_48357a426a79', name='featuresCol', doc='features column name.'): 'features',\n", + " Param(parent='GBTClassifier_48357a426a79', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='GBTClassifier_48357a426a79', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='GBTClassifier_48357a426a79', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='GBTClassifier_48357a426a79', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='GBTClassifier_48357a426a79', name='seed', doc='random seed.'): 42,\n", + " Param(parent='GBTClassifier_48357a426a79', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees. Users can set how often should the cache be checkpointed or disable it by setting checkpointInterval.'): False,\n", + " Param(parent='GBTClassifier_48357a426a79', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext.'): 10,\n", + " Param(parent='GBTClassifier_48357a426a79', name='featureSubsetStrategy', doc=\"The number of features to consider for splits at each tree node. Supported options: 'auto' (choose automatically for task: If numTrees == 1, set to 'all'. If numTrees > 1 (forest), set to 'sqrt' for classification and to 'onethird' for regression), 'all' (use all features), 'onethird' (use 1/3 of the features), 'sqrt' (use sqrt(number of features)), 'log2' (use log2(number of features)), 'n' (when n is in the range (0, 1.0], use n * number of features. When n is in the range (1, number of features), use n features). default = 'auto'\"): 'all',\n", + " Param(parent='GBTClassifier_48357a426a79', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: variance'): 'variance',\n", + " Param(parent='GBTClassifier_48357a426a79', name='leafCol', doc='Leaf indices column name. Predicted leaf index of each instance in each tree by preorder.'): '',\n", + " Param(parent='GBTClassifier_48357a426a79', name='lossType', doc='Loss function which GBT tries to minimize (case-insensitive). Supported options: logistic'): 'logistic',\n", + " Param(parent='GBTClassifier_48357a426a79', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 32,\n", + " Param(parent='GBTClassifier_48357a426a79', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 8,\n", + " Param(parent='GBTClassifier_48357a426a79', name='maxIter', doc='max number of iterations (>= 0).'): 55,\n", + " Param(parent='GBTClassifier_48357a426a79', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation. If too small, then 1 node will be split per iteration, and its aggregates may exceed this size.'): 256,\n", + " Param(parent='GBTClassifier_48357a426a79', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='GBTClassifier_48357a426a79', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1,\n", + " Param(parent='GBTClassifier_48357a426a79', name='minWeightFractionPerNode', doc='Minimum fraction of the weighted sample count that each child must have after split. If a split causes the fraction of the total weight in the left or right child to be less than minWeightFractionPerNode, the split will be discarded as invalid. Should be in interval [0.0, 0.5).'): 0.0,\n", + " Param(parent='GBTClassifier_48357a426a79', name='stepSize', doc='Step size (a.k.a. learning rate) in interval (0, 1] for shrinking the contribution of each estimator.'): 0.2,\n", + " Param(parent='GBTClassifier_48357a426a79', name='subsamplingRate', doc='Fraction of the training data used for learning each decision tree, in range (0, 1].'): 1.0,\n", + " Param(parent='GBTClassifier_48357a426a79', name='validationTol', doc='Threshold for stopping early when fit with validation is used. If the error rate on the validation input changes by less than the validationTol, then learning will stop early (before `maxIter`). This parameter is ignored when fit without validation is used.'): 0.01}" + ] + }, + "execution_count": 217, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Hyper pramaters from the best model \n", + "\n", + "cvModel_gbt_t_new.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 177, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_gbt_t_new=cvModel_gbt_t_new.transform(us_test_cat).toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 178, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 180, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.88 0.65 0.75 131790\n", + " 1 0.53 0.82 0.65 64610\n", + "\n", + " accuracy 0.70 196400\n", + " macro avg 0.71 0.73 0.70 196400\n", + "weighted avg 0.77 0.70 0.71 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_gbt_t_new,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 181, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of GBT Grid Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_gbt_t_new = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cvModel_gbt_t_new.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 182, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from GBT Best tuned')" + ] + }, + "execution_count": 182, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of GBT Grid Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_gbt_t_new['column'][:10], y=feat_imp_tuned_gbt_t_new['weight'][:10],data=feat_imp_tuned_gbt_t_new)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from GBT Best tuned\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Trees Binary Classification Base Model" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Create initial Decision Tree Model\n", + "dt = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Pipeline with stages created for DT Model \n", + "\n", + "dt_pipe = Pipeline(stages=[label_stringIdx, va, dt])\n", + "\n", + "# Train model with Training Data\n", + "\n", + "dtModel = dt_pipe.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "# Binary Class Evaluator Initialize\n", + "\n", + "evaluator = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform the test data to get prediction from the model for the test data\n", + "\n", + "pred_dt = dtModel.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.7039599188458128\n" + ] + } + ], + "source": [ + "# AUC Score from the evaluator for the test data\n", + "\n", + "print(\"AUC Score is\",evaluator.evaluate(pred_dt))" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6643584521384929" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Accuracy Calculation for DT Base Model\n", + "\n", + "binary_prediction=pred_dt.select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_dtb=pred_dt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.86 0.60 0.70 131790\n", + " 1 0.49 0.81 0.61 64610\n", + "\n", + " accuracy 0.66 196400\n", + " macro avg 0.68 0.70 0.66 196400\n", + "weighted avg 0.74 0.66 0.67 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_dtb,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Base Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtb= pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from DT Binary Base Model')" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Base Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtb['column'][:10], y=feat_imp_tuned_dtb['weight'][:10],data=feat_imp_tuned_dtb)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Binary Base Model\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decision Tree Binary Classification Grid Search" + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing DT Grid Pipeline\n", + "\n", + "dt_new = DecisionTreeClassifier(labelCol=\"label\", featuresCol=\"features\",seed=42)\n", + "\n", + "# Creating pipeline for DT Grid Model \n", + "\n", + "dt_new_pipe = Pipeline(stages=[label_stringIdx, va, dt_new])\n", + "\n", + "# Binary Evaluator Initializing\n", + "\n", + "evaluator = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "\n", + "# Creating Grid Search for Hyper Parameter Tuning for DT Model\n", + "\n", + "grid_dt = ParamGridBuilder().addGrid(dt_new.maxDepth, [10,15,30]).addGrid(dt_new.minInstancesPerNode, [500,1000,1500]).addGrid(dt_new.maxBins,[20,35,50]).build()\n", + "\n", + "# Cross Validator Pipeline with 5 fold cv to fit the training data\n", + "\n", + "cv1_dt = CrossValidator(estimator=dt_new_pipe,estimatorParamMaps=grid_dt, numFolds=5, evaluator=evaluator,seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "metadata": {}, + "outputs": [], + "source": [ + "# Fitting the train data using the 5-fold Cross validator pipeline\n", + "\n", + "dtModel_t = cv1_dt.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "metadata": {}, + "outputs": [], + "source": [ + "# Predicting the test data using the fitted pipeline\n", + "\n", + "pred_dtt = dtModel_t.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score 0.6710458592255817\n" + ] + } + ], + "source": [ + "# AUC Score for the fitted pipeline for test data\n", + "\n", + "print(\"AUC Score\", evaluator.evaluate(pred_dtt))" + ] + }, + { + "cell_type": "code", + "execution_count": 218, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='featuresCol', doc='features column name.'): 'features',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='seed', doc='random seed.'): 42,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='cacheNodeIds', doc='If false, the algorithm will pass trees to executors to match instances with nodes. If true, the algorithm will cache node IDs for each instance. Caching can speed up training of deeper trees. Users can set how often should the cache be checkpointed or disable it by setting checkpointInterval.'): False,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='checkpointInterval', doc='set checkpoint interval (>= 1) or disable checkpoint (-1). E.g. 10 means that the cache will get checkpointed every 10 iterations. Note: this setting will be ignored if the checkpoint directory is not set in the SparkContext.'): 10,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='impurity', doc='Criterion used for information gain calculation (case-insensitive). Supported options: entropy, gini'): 'gini',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='leafCol', doc='Leaf indices column name. Predicted leaf index of each instance in each tree by preorder.'): '',\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='maxBins', doc='Max number of bins for discretizing continuous features. Must be >=2 and >= number of categories for any categorical feature.'): 50,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='maxDepth', doc='Maximum depth of the tree. (>= 0) E.g., depth 0 means 1 leaf node; depth 1 means 1 internal node + 2 leaf nodes.'): 10,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='maxMemoryInMB', doc='Maximum memory in MB allocated to histogram aggregation. If too small, then 1 node will be split per iteration, and its aggregates may exceed this size.'): 256,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='minInfoGain', doc='Minimum information gain for a split to be considered at a tree node.'): 0.0,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='minInstancesPerNode', doc='Minimum number of instances each child must have after split. If a split causes the left or right child to have fewer than minInstancesPerNode, the split will be discarded as invalid. Should be >= 1.'): 1500,\n", + " Param(parent='DecisionTreeClassifier_0bccbe6ff0a3', name='minWeightFractionPerNode', doc='Minimum fraction of the weighted sample count that each child must have after split. If a split causes the fraction of the total weight in the left or right child to be less than minWeightFractionPerNode, the split will be discarded as invalid. Should be in interval [0.0, 0.5).'): 0.0}" + ] + }, + "execution_count": 218, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper parameters for the DT Grid Search Model\n", + "\n", + "dtModel_t.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 167, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_dtbt=pred_dtt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 169, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 170, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.88 0.57 0.70 131790\n", + " 1 0.49 0.85 0.62 64610\n", + "\n", + " accuracy 0.66 196400\n", + " macro avg 0.69 0.71 0.66 196400\n", + "weighted avg 0.76 0.66 0.67 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_dtbt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 171, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating Pandas Dataframe for Features and their Importance of DT Grid Model for Binary Classification\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_dtbt= pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], dtModel_t.bestModel.stages[-1].featureImportances)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 172, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Top 10 Features based on Importance from DT Binary Grid Model')" + ] + }, + "execution_count": 172, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plotting top 10 Features from Feature Importance of DT Grid Model for Binary Classification\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "sns.barplot(x=feat_imp_tuned_dtbt['column'][:10], y=feat_imp_tuned_dtbt['weight'][:10],data=feat_imp_tuned_dtbt)\n", + "plt.xticks(rotation=90)\n", + "plt.xlabel(\"Features\")\n", + "plt.ylabel(\"Weights\")\n", + "plt.title(\"Top 10 Features based on Importance from DT Binary Grid Model\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Regression " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Base Model Binary" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard Scaler to standardize the output of vector assembler before feeding it to Logistic Regression\n", + "\n", + "center = feature.StandardScaler(withMean=True, withStd=False, inputCol='features', outputCol='centered_features')" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [], + "source": [ + "# Create initial LogisticRegression model\n", + "lr = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")\n", + "\n", + "# Pipeline for training data \n", + "\n", + "lrModel = Pipeline(stages=[label_stringIdx,va, center, lr])\n", + "\n", + "# Fit the train data using LR model\n", + "\n", + "lr_fit = lrModel.fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [], + "source": [ + "# Transsform test data to predict Severity by using fitted pipeline from training data\n", + "\n", + "pred_lrb = lr_fit.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Area Under ROC for Logistic Base Model 0.7619402091983631\n" + ] + } + ], + "source": [ + "# Evaluator to get AUC Score for test data\n", + "\n", + "evaluator_lrb = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')\n", + "print('Test Area Under ROC for Logistic Base Model ', evaluator_lrb.evaluate(lr_fit.transform(us_test_cat)))" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training set areaUnderROC: 0.7627619042131226\n" + ] + } + ], + "source": [ + "# ROC Curve for LR Base Model\n", + "\n", + "trainingSummary = lr_fit.stages[-1].summary\n", + "roc = trainingSummary.roc.toPandas()\n", + "plt.plot(roc['FPR'],roc['TPR'])\n", + "plt.ylabel('False Positive Rate')\n", + "plt.xlabel('True Positive Rate')\n", + "plt.title('ROC Curve')\n", + "plt.grid(True)\n", + "plt.show()\n", + "print('Training set areaUnderROC: ' + str(trainingSummary.areaUnderROC))" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "# Logistic Regression Coefficients to Array \n", + "\n", + "coef_l1=lr_fit.stages[-1].coefficientMatrix.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": {}, + "outputs": [], + "source": [ + "# to stack the coefficient array column wise for further analysis\n", + "\n", + "cof_l1=np.hstack(coef_l1)" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating pandas dataframe with Logistic Regression weights for each variable along with variable name\n", + "\n", + "pd.set_option('display.max_rows', None)\n", + "feat_imp_tuned_b = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], cof_l1)),\n", + " columns = ['column', 'weight']).sort_values('weight',ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [], + "source": [ + "# Coefficient from LR model for each variable\n", + "\n", + "coef_L1=lr_fit.stages[-1].coefficients.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 6.10404226e-02, 3.84503967e-01, 5.55462923e-01, 2.83682423e-02,\n", + " 3.11545767e-01, 5.72957889e-01, 2.68684159e-01, 6.40513508e-01,\n", + " 2.39662302e-01, 7.29093517e-01, 3.38870399e-01, 6.35365038e-01,\n", + " 3.42524554e-01, 3.00627117e-01, 2.86496247e-01, 3.33305131e-01,\n", + " 1.74724528e-01, 7.28250150e-01, 4.11683887e-01, 1.01770132e-01,\n", + " 7.77776525e-02, 4.80918989e-01, 1.93834032e-01, 6.10964689e-02,\n", + " 7.07937460e-02, -2.46781145e-02, 3.25562566e-02, 1.93521868e+00,\n", + " 6.98425343e-01, 2.44544359e-01, -2.92797816e-01, 4.20970924e-01,\n", + " 1.18834527e+00, -4.98702447e-01, 1.49876162e+00, -3.76084559e-01,\n", + " 8.73144768e-01, 1.01459587e+00, -3.68386095e-01, 8.15470313e-01,\n", + " 1.02401163e+00, 1.33550551e+00, 9.34355323e-01, -5.02078892e-02,\n", + " 1.90952537e+00, 1.15563651e+00, 6.80595337e-01, 5.58708379e-02,\n", + " 2.25339626e-02, 2.20958954e-02, 7.43138848e-04, 6.98986882e-01,\n", + " 6.92230035e-01, 3.43491620e-01, 1.09905601e-01, -6.59910295e-02,\n", + " 2.73193089e-01, 6.57264786e-02, 1.43917276e-01, 6.74550394e-05,\n", + " 7.00180998e-02, 2.05815870e-01, 3.62644772e-01, 2.44123017e-01,\n", + " 8.74585264e-02, 2.65865377e-02, 1.39148506e-02, -3.64614378e-02,\n", + " 3.60980672e-02, 5.39018526e-02, 6.97262794e-02, 3.48474891e-02,\n", + " 7.32900545e-02, 9.03299822e-03, 3.43603153e-02, 1.55938700e-02,\n", + " 1.39685633e-02, 3.34354498e-02, 4.88498457e-02, 7.42683555e-02,\n", + " 6.41895294e-03, -1.52099373e+00, -2.92797816e-01, 3.21061922e-01,\n", + " 1.12504363e-01, 9.90974565e-02, 8.69937407e-01, -3.11252258e-01,\n", + " -4.64919144e-02, 7.05797649e-02, 2.02713308e-01, -2.74288756e-03,\n", + " 4.03122329e-01, 2.52918849e-01, 3.42967380e-01, -3.63234523e-01,\n", + " -1.65340324e-01, 2.05437823e-01, 2.01133559e-01, 3.13500571e-01,\n", + " 3.03022094e-01, -3.83431591e-03, 1.29392900e-04, 5.04152924e-02,\n", + " 1.42110421e-02, 9.75298836e-03, 3.16315594e-02, -7.36661603e-01,\n", + " 3.93267264e-01, -6.70645537e-01, 3.50216355e-01, 1.91966480e-01,\n", + " 3.17809826e-02, 1.69946149e-01, -2.11351631e+00, -4.39883557e-01,\n", + " -1.60607312e+00, -9.26287099e-01, -1.28426974e+00])" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "coef_L1" + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features are 119\n", + "Eliminated features out of 119 are 0\n" + ] + } + ], + "source": [ + "# Taking absolute values of weights and calculating the number of features eliminated by LR Model after L1 regularization \n", + "\n", + "coef_L1 = np.absolute(coef_L1)\n", + "\n", + "print('Total number of features are',len(coef_L1))\n", + "\n", + "sorted_abs = np.sort(coef_L1)\n", + "\n", + "weights_notzero = sorted_abs[sorted_abs == 0]\n", + "nonzero_weights = len(sorted_abs[sorted_abs == 0])\n", + "\n", + "print('Eliminated features out of ' + str(len(coef_L1)) + ' are', nonzero_weights)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_lrbal=pred_lrb.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.85 0.63 0.72 131790\n", + " 1 0.50 0.77 0.61 64610\n", + "\n", + " accuracy 0.67 196400\n", + " macro avg 0.67 0.70 0.66 196400\n", + "weighted avg 0.73 0.67 0.68 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_lrbal,y_true=true_labels))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Binary Grid Search Binary" + ] + }, + { + "cell_type": "code", + "execution_count": 183, + "metadata": {}, + "outputs": [], + "source": [ + "# Logistic Regression Pipeline initialization\n", + "\n", + "lr_new = LogisticRegression(labelCol=\"label\", featuresCol=\"centered_features\")" + ] + }, + { + "cell_type": "code", + "execution_count": 187, + "metadata": {}, + "outputs": [], + "source": [ + "# Grid Search for tuning the hyper parameters of Logistic Regression Model\n", + "\n", + "paramGrid_lr = ParamGridBuilder().addGrid(lr_new.regParam, [0.01, 0.04,0.07]).addGrid(lr_new.elasticNetParam, [0.1,0.4,0.7]).build()" + ] + }, + { + "cell_type": "code", + "execution_count": 185, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating pipeline to be used for fitting the training data\n", + "\n", + "cvModel_lrbal = Pipeline(stages=[label_stringIdx,va,center,lr_new])" + ] + }, + { + "cell_type": "code", + "execution_count": 186, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Binary Evaluator for evaluating the model performance\n", + "\n", + "evaluator_lrbt = BinaryClassificationEvaluator(labelCol='label',metricName='areaUnderROC')" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross validator pipeline initialization for 5-fold cross validation and fitting the train data\n", + "\n", + "cv_lrbal = CrossValidator(estimator=cvModel_lrbal, estimatorParamMaps=paramGrid_lr, evaluator=evaluator_lrbt, numFolds=5,seed=42).fit(us_train_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 189, + "metadata": {}, + "outputs": [], + "source": [ + "# Testing the test data on fitted 5 fold cv pipeline\n", + "\n", + "pred_lrbalt=cv_lrbal.transform(us_test_cat)" + ] + }, + { + "cell_type": "code", + "execution_count": 190, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AUC Score is 0.7612376191461516\n" + ] + } + ], + "source": [ + "# Accuracy calculation from the Multiclass evaluator\n", + "\n", + "print(\"AUC Score is\",evaluator_lrbt.evaluate(pred_lrbalt))" + ] + }, + { + "cell_type": "code", + "execution_count": 191, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training set areaUnderROC: 0.7622374995379829\n" + ] + } + ], + "source": [ + "# ROC Curve for Logistic Regression Grid Search Model\n", + "\n", + "trainingSummary_t = cv_lrbal.bestModel.stages[-1].summary\n", + "roc = trainingSummary_t.roc.toPandas()\n", + "plt.plot(roc['FPR'],roc['TPR'])\n", + "plt.ylabel('False Positive Rate')\n", + "plt.xlabel('True Positive Rate')\n", + "plt.title('ROC Curve')\n", + "plt.grid(True)\n", + "plt.show()\n", + "print('Training set areaUnderROC: ' + str(trainingSummary_t.areaUnderROC))" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Param(parent='LogisticRegression_f000cca535b6', name='aggregationDepth', doc='suggested depth for treeAggregate (>= 2).'): 2,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='elasticNetParam', doc='the ElasticNet mixing parameter, in range [0, 1]. For alpha = 0, the penalty is an L2 penalty. For alpha = 1, it is an L1 penalty.'): 0.1,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='featuresCol', doc='features column name.'): 'centered_features',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='fitIntercept', doc='whether to fit an intercept term.'): True,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='labelCol', doc='label column name.'): 'label',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='predictionCol', doc='prediction column name.'): 'prediction',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='probabilityCol', doc='Column name for predicted class conditional probabilities. Note: Not all models output well-calibrated probability estimates! These probabilities should be treated as confidences, not precise probabilities.'): 'probability',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='rawPredictionCol', doc='raw prediction (a.k.a. confidence) column name.'): 'rawPrediction',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='standardization', doc='whether to standardize the training features before fitting the model.'): True,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='threshold', doc='Threshold in binary classification prediction, in range [0, 1]. If threshold and thresholds are both set, they must match.e.g. if threshold is p, then thresholds must be equal to [1-p, p].'): 0.5,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='family', doc='The name of family which is a description of the label distribution to be used in the model. Supported options: auto, binomial, multinomial'): 'auto',\n", + " Param(parent='LogisticRegression_f000cca535b6', name='maxIter', doc='max number of iterations (>= 0).'): 100,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='regParam', doc='regularization parameter (>= 0).'): 0.01,\n", + " Param(parent='LogisticRegression_f000cca535b6', name='tol', doc='the convergence tolerance for iterative algorithms (>= 0).'): 1e-06}" + ] + }, + "execution_count": 212, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Best Model Hyper parameters after Tuning LR Model\n", + "\n", + "cv_lrbal.bestModel.stages[-1].extractParamMap()" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6688034623217922" + ] + }, + "execution_count": 194, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Accuracy Calculation for the test data from the model\n", + "\n", + "binary_prediction=pred_lrbalt.select(\"prediction\").collect()\n", + "\n", + "binary_true_labels=us_test_cat.select(\"Severity\").collect()\n", + "\n", + "np.sum(list([int(binary_true_labels[i][0]==binary_prediction[i][0]) for i in range(len(true_labels))]))/len(true_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "metadata": {}, + "outputs": [], + "source": [ + "# Prediction output from the model to pandas\n", + "\n", + "prediction_lrbalt=pred_lrbalt.toPandas()[\"prediction\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "metadata": {}, + "outputs": [], + "source": [ + "# True Labels from test data for Target Variable\n", + "\n", + "true_labels=us_test_cat.toPandas()[\"Severity\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing Classification Report from sklearn\n", + "\n", + "from sklearn.metrics import classification_report" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.85 0.61 0.71 131790\n", + " 1 0.50 0.78 0.61 64610\n", + "\n", + " accuracy 0.67 196400\n", + " macro avg 0.67 0.70 0.66 196400\n", + "weighted avg 0.74 0.67 0.68 196400\n", + "\n" + ] + } + ], + "source": [ + "# Classification Report Generation for all metrics display at once\n", + "\n", + "print(classification_report(y_pred=prediction_dtbalt,y_true=true_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": {}, + "outputs": [], + "source": [ + "# Coefficient from LR model for each variable\n", + "\n", + "coef_L1_m=cv_lrbal.bestModel.stages[-1].coefficients.toArray()" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-0.05730593, 0.1631614 , 0.22683363, -0.0922915 , 0.12743824,\n", + " 0.22850115, 0.0874906 , 0.29489116, 0. , 0.37672293,\n", + " 0.15445802, 0.28753523, 0.14824354, 0.00970946, 0.10372804,\n", + " 0.08653566, 0. , 0.37548958, 0.13350159, -0.01698079,\n", + " -0.04548731, 0.17180723, 0.01903713, 0.10730425, 0.08693924,\n", + " 0.01656798, 0.06626178, 1.65740542, 0.5776856 , 0. ,\n", + " -0.25852766, 0.34445895, 0.99689203, -0.21432981, 1.33791048,\n", + " 0. , 0.80841273, 0.59158904, -0.23910861, 0.58651763,\n", + " 0.90778268, 0.11721702, 0.81946075, 0. , 1.58545586,\n", + " 0.78832342, 0.50243283, 0.0249303 , 0. , 0. ,\n", + " -0.01444565, 0.63605211, 0.62860006, 0.22391409, 0.02995857,\n", + " -0.11490668, 0.14692048, 0. , 0.02469895, -0.06192017,\n", + " 0. , 0.10814645, 0.23145346, 0.13481408, 0.03663532,\n", + " 0. , 0. , -0.03897284, 0. , 0. ,\n", + " 0.02532982, 0.00652907, 0.01371828, 0. , 0. ,\n", + " 0. , 0. , 0. , 0.01066444, 0.02208044,\n", + " 0. , -1.41648022, -0.25852766, 0.26103542, 0. ,\n", + " 0. , 0. , -0.22986335, 0.0026555 , 0.04903758,\n", + " 0.14350738, 0. , 0.21757303, 0.08485045, 0.0949972 ,\n", + " -0.44105302, 0. , 0.01732823, 0.07618706, 0. ,\n", + " 0.23152556, -0.00195721, 0. , 0.0395699 , 0.00836024,\n", + " 0.01054067, 0.00280582, -0.64456 , 0. , -0.63672179,\n", + " 0.17710428, 0.18114564, 0. , 0.0416721 , -0.79625681,\n", + " -0.37949686, -1.40585049, -0.38560954, -1.20185474])" + ] + }, + "execution_count": 200, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "coef_L1_m" + ] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [], + "source": [ + "# Pandas dataframe of weights of variables with variable names to find which variables are eliminated\n", + "\n", + "feat_imp_tuned_lrt = pd.DataFrame(list(zip([i for i in us_train_cat.columns if i!='Severity'], np.absolute(coef_L1_m))),\n", + " columns = ['column', 'weight']).sort_values('weight')" + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
columnweight
80Wind_Direction_Index_120.0
65Wind_Direction_Index_70.0
85clear0.0
84cloud0.0
57month_of_year_Index_110.0
29TMC_Index_180.0
77Wind_Direction_Index_50.0
76Wind_Direction_Index_150.0
75Wind_Direction_Index_60.0
74Wind_Direction_Index_130.0
\n", + "
" + ], + "text/plain": [ + " column weight\n", + "80 Wind_Direction_Index_12 0.0\n", + "65 Wind_Direction_Index_7 0.0\n", + "85 clear 0.0\n", + "84 cloud 0.0\n", + "57 month_of_year_Index_11 0.0\n", + "29 TMC_Index_18 0.0\n", + "77 Wind_Direction_Index_5 0.0\n", + "76 Wind_Direction_Index_15 0.0\n", + "75 Wind_Direction_Index_6 0.0\n", + "74 Wind_Direction_Index_13 0.0" + ] + }, + "execution_count": 211, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Sample of 10 features eliminated by the Logistic Regression Model after L1 Regularization\n", + "\n", + "feat_imp_tuned_lrt[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of features are 119\n", + "Eliminated features out of 119 are 28\n" + ] + } + ], + "source": [ + "# Taking absolute values of weights and calculating the number of features eliminated by LR Model after L1 regularization \n", + "\n", + "coef_L1_m = np.absolute(coef_L1_m)\n", + "\n", + "print('Total number of features are',len(coef_L1_m))\n", + "\n", + "sorted_abs = np.sort(coef_L1_m)\n", + "\n", + "weights_notzero = sorted_abs[sorted_abs == 0]\n", + "nonzero_weights = len(sorted_abs[sorted_abs == 0])\n", + "\n", + "print('Eliminated features out of ' + str(len(coef_L1_m)) + ' are', len(weights_notzero))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/StringIndexing_OHE_Conversion.ipynb b/StringIndexing_OHE_Conversion.ipynb new file mode 100644 index 0000000..44e237f --- /dev/null +++ b/StringIndexing_OHE_Conversion.ipynb @@ -0,0 +1,504 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#importing all required libraries\n", + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.sql.functions import udf\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import StringIndexer\n", + "from pyspark.ml.feature import OneHotEncoderEstimator" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# reads the cleaned data file\n", + "data=spark.read.csv(get_training_filename(\"Us_clean.csv\"),inferSchema=True,header=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Extracts hour of the day from the start time of the accident and stores in a new column named Hour \n", + "data=data.withColumn(\"Hour\", date_format(col(\"Start_Time\"), \"H\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping column Start time,end time, timezone, start latitude and end latitude as they won't be helpful in predicting\n", + "# the severiy of the accident\n", + "# The columns city, county and state have high cardinality so we have dropped them\n", + "drop_col=[\"Start_Time\",\"End_Time\",\"Start_Lat\",\"Start_Lng\",'City','County','State','Timezone']" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#Dropping the columns \n", + "data = data.drop(*(drop_col))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# As the data contains very few rows (around 300 in 1 million rows) of Severity 1 we have converted it to Severity 2 because \n", + "# both the classes indicate accidents with less severity \n", + "data=data.withColumn(\"Severity\",when(data[\"Severity\"]==1,2).otherwise(data[\"Severity\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# TMC column is an important column so we decided not to drop it\n", + "# It has around 25000 missing so using the mode to impute does not make sense\n", + "# So, we have made a different category for the missing values\n", + "data=data.fillna({'TMC':'-1'})" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "#list of all categorical columns\n", + "categorical_columns=['Source','Side','Wind_Direction','month_of_year','day_of_week',\"TMC\",'Sunrise_Sunset','Civil_Twilight',\n", + " 'Nautical_Twilight','Astronomical_Twilight',\"Hour\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#encoding the categrical column as models do not accept string\n", + "stages = []\n", + "\n", + "#iterate through all categorical values\n", + "for categoricalCol in categorical_columns:\n", + " #create a string indexer for those categorical values and assign a new name including the word 'Index'\n", + " stringIndexer = StringIndexer(inputCol = categoricalCol, outputCol = categoricalCol + '_Index')\n", + "\n", + " #append the string Indexer to our list of stages\n", + " stages += [stringIndexer]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Running the pipeline which encodes the categorical column\n", + "\n", + "pipeline = Pipeline(stages = stages)\n", + "#fit the pipeline to our dataframe\n", + "pipelineModel = pipeline.fit(data)\n", + "#transform the dataframe\n", + "data= pipelineModel.transform(data)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Dropping the original categorical column\n", + "data=data.drop(*(categorical_columns))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "#List of columns with binary values i.e. True/False\n", + "\n", + "binary_columns=['Amenity','Bump','Crossing','Give_Way','Junction','No_Exit','Railway','Roundabout','Station','Stop',\n", + "'Traffic_Calming','Traffic_Signal']" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Converts the binary values into 0/1\n", + "\n", + "for i in binary_columns:\n", + " data=data.withColumn(i,data[i].cast(\"int\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "#Converts the Weather Condition to lowercase\n", + "data=data.withColumn('Weather_Condition',fn.lower(col(\"Weather_Condition\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Replaces T-storm with Thunderstorm because they are the same weather condition\n", + "data=data.withColumn('Weather_Condition', regexp_replace('Weather_Condition', 'T-Storm', 'Thunderstorm'))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# List of manually picked weather conditions that we thought could help in predicting the severity \n", + "w_conditions=[\"cloud\",\"clear\",\"whirl\",\"wind\",\"light\",\"heavy\",\"thunderstorm\",\"shower\",\"snow\",\"rain\",\"drizzle\",\n", + " \"fair\",\"hail\",\"haze\",\"overcast\",'pellets']" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "#Splits the strings in the weather condition on space character and converts it into a list of words\n", + "data=data.withColumn('Weather_Condition', fn.split(\"Weather_Condition\",\" \"))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Removes the word having length less than 4 and also the word \"with\"\n", + "data_clean1=udf(lambda x: list([i for i in x if ((len(i)>3) and (i!=\"with\"))]),\n", + " returnType=ArrayType(StringType()))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Executes the above function\n", + "data=data.withColumn(\"Weather_Condition\",data_clean1(\"Weather_Condition\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# Converts the categorical columns into String type\n", + "for i in categorical_columns:\n", + " data = data.withColumn(i+\"_Index\", data[i+\"_Index\"].cast(StringType()))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Removes the words from the weather condition column that are not present in the w_conditions list\n", + "data_clean2=udf(lambda x: list([i for i in w_conditions if any(i in j for j in x)]),\n", + " returnType=ArrayType(StringType()))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Executes the above function\n", + "data=data.withColumn(\"Weather_Condition\",data_clean2(\"Weather_Condition\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Makes dummy variable for each weather condition in our list\n", + "exprs = [fn.when(fn.array_contains(fn.col('Weather_Condition'), column), 1).otherwise(0).alias(column)\\\n", + " for column in w_conditions]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Makes a temporary dataframe of our weather condition and dummy variables \n", + "temp=data.select(['Weather_Condition']+exprs)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "#create two dataframe which we will join to make our final dataframe \n", + "df1 = data.withColumn(\"id\", monotonically_increasing_id())\n", + "df2 = temp.withColumn(\"id\", monotonically_increasing_id())" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Creates the final datafram\n", + "data = df2.join(df1, \"id\", \"outer\").drop(\"id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "# Now we can drop the weather condition column after making dummies from it\n", + "data=data.drop(\"Weather_Condition\")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "# Splits the dataframe into train and test\n", + "training_df, validation_df= data.randomSplit([0.8, 0.2],seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "training_df.toPandas().to_csv(\"USAccident_train_categorical.csv\",index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "validation_df.toPandas().to_csv(\"USAccident_validation_categorical.csv\",index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## One Hot Encoding" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# list of columns to be one hot encoded\n", + "categorical_columns2=[i+\"_Index\"for i in categorical_columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating dummies of categorical column\n", + "for category in categorical_columns2:\n", + " categ = data.select(category).distinct().rdd.flatMap(lambda x:x).collect()\n", + " exprs = [fn.when(fn.col(category) == cat,1).otherwise(0)\\\n", + " .alias(category+\"_\"+str(int(float(cat)))) for cat in categ]\n", + " data = data.select(exprs+data.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping all the original categorical columns\n", + "data=data.drop(*(categorical_columns2))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "# From the n dummies made for each categorical column, dropping the nth dummy\n", + "data=data.drop(*([i+\"_Index_0\" for i in categorical_columns]))" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "# Splits the dataframe into train and test\n", + "training_df, validation_df= data.randomSplit([0.8, 0.2],seed=42)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "training_df.toPandas().to_csv(\"USAccident_train_OHE.csv\",index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "validation_df.toPandas().to_csv(\"USAccident_validation_OHE.csv\",index=False)" + ] + } + ], + "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.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Undersampling_Oversampling.ipynb b/Undersampling_Oversampling.ipynb new file mode 100644 index 0000000..4ffb180 --- /dev/null +++ b/Undersampling_Oversampling.ipynb @@ -0,0 +1,461 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.getOrCreate()\n", + "sc = spark.sparkContext\n", + "from pyspark.sql import Row\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.functions import *\n", + "import matplotlib.pyplot as plt\n", + "from pyspark.sql import functions as fn\n", + "from pyspark.ml import feature, regression, evaluation, Pipeline\n", + "import seaborn as sns\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml import Pipeline\n", + "from pyspark.ml.regression import LinearRegression\n", + "from pyspark.ml.stat import Correlation\n", + "from pyspark.ml.feature import StringIndexer\n", + "from pyspark.ml.feature import OneHotEncoderEstimator\n", + "from pyspark.ml.feature import VectorAssembler\n", + "from pyspark.ml.classification import RandomForestClassifier\n", + "from pyspark.ml.evaluation import BinaryClassificationEvaluator,MulticlassClassificationEvaluator\n", + "from sklearn.metrics import classification_report\n", + "from pyspark.ml.classification import DecisionTreeClassifier\n", + "from pyspark.ml.tuning import CrossValidator,ParamGridBuilder" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Do not delete or change this cell\n", + "\n", + "import os\n", + "\n", + "# Define a function to determine if we are running on data bricks\n", + "# Return true if running in the data bricks environment, false otherwise\n", + "def is_databricks():\n", + " # get the databricks runtime version\n", + " db_env = os.getenv(\"DATABRICKS_RUNTIME_VERSION\")\n", + " \n", + " # if running on data bricks\n", + " if db_env != None:\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + "# Define a function to read the data file. The full path data file name is constructed\n", + "# by checking runtime environment variables to determine if the runtime environment is \n", + "# databricks, or a student's personal computer. The full path file name is then\n", + "# constructed based on the runtime env.\n", + "# \n", + "# Params\n", + "# data_file_name: The base name of the data file to load\n", + "# \n", + "# Returns the full path file name based on the runtime env\n", + "#\n", + "def get_training_filename(data_file_name): \n", + " # if running on data bricks\n", + " if is_databricks():\n", + " # build the full path file name assuming data brick env\n", + " full_path_name = \"/FileStore/tables/%s\" % data_file_name\n", + " # else the data is assumed to be in the same dir as this notebook\n", + " else:\n", + " # Assume the student is running on their own computer and load the data\n", + " # file from the same dir as this notebook\n", + " full_path_name = data_file_name\n", + " \n", + " # return the full path file name to the caller\n", + " return full_path_name" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Sampling will only be performed on training data\n", + "# below we import the data\n", + "training_df=spark.read.csv(get_training_filename(\"USAccident_train_categorical.csv\"),inferSchema=True,header=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Balancing for Multiclass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**For balancing the multiclass data, we will oversample the class 4 as it has the least data and undersample class 2 with the most data.**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Oversampling Target 4" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# The class 4 will be oversampled in such a way that the new number of rows of class 4 matches the number of class 3.\n", + "major_df = training_df.filter(col(\"Severity\") == 3)\n", + "minor_df = training_df.filter(col(\"Severity\") == 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# calculating the ratio of number of rows in class 3 by class 4\n", + "oversampling_ratio = int(major_df.count()/minor_df.count())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "a=range(oversampling_ratio)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# storing the new oversampled data of class 4\n", + "oversampled_df = minor_df.withColumn(\"dummy\", explode(array([lit(x) for x in a]))).drop('dummy')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Undersampling Target 2" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# The class 2 will be undersampled in such a way that the new number of rows of class 2 matches the number of class 3.\n", + "major_df = training_df.filter(col(\"Severity\") == 2)\n", + "minor_df = training_df.filter(col(\"Severity\") == 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# calculating the ratio of number of rows in class 2 by class 3\n", + "ratio=int(major_df.count()/minor_df.count())" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "#Performs the undersampling\n", + "undersampled_df = major_df.sample(False, 1/ratio)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "unsampled_class_data=training_df.filter(col(\"Severity\") == 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Combining the data to create our final dataset\n", + "temp_data=unsampled_class_data.unionAll(undersampled_df)\n", + "balanced_data=temp_data.unionAll(oversampled_df)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# saving in a csv file\n", + "balanced_data.toPandas().to_csv(\"USAccident_balanced_train_categorical.csv\",index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### One Hot encoding for balanced data" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "#list of all categorical columns\n", + "categorical_columns=['Source','Side','Wind_Direction','month_of_year','day_of_week',\"TMC\",'Sunrise_Sunset','Civil_Twilight',\n", + " 'Nautical_Twilight','Astronomical_Twilight',\"Hour\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "#list of columns to be one hot encoded\n", + "categorical_columns2=[i+\"_Index\"for i in categorical_columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating dummies of categorical column\n", + "for category in categorical_columns2:\n", + " categ = balanced_data.select(category).distinct().rdd.flatMap(lambda x:x).collect()\n", + " exprs = [fn.when(fn.col(category) == cat,1).otherwise(0)\\\n", + " .alias(category+\"_\"+str(int(float(cat)))) for cat in categ]\n", + " balanced_data = balanced_data.select(exprs+balanced_data.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping all the original categorical columns\n", + "balanced_data=balanced_data.drop(*(categorical_columns2))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# From the n dummies made for each categorical column, dropping the nth dummy\n", + "balanced_data=balanced_data.drop(*([i+\"_Index_0\" for i in categorical_columns]))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "balanced_data.toPandas().to_csv(\"USAccident_balanced_train_categorical_OHE.csv\",index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Balancing for Binary Data" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# binarizing the target variable\n", + "training_df_new=training_df.withColumn(\"Severity\",fn.when(((training_df[\"Severity\"]==1) | (training_df[\"Severity\"]==2)),0).otherwise(1))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# The class 0 will be undersampled in such a way that the new number of rows of class 0 matches the number of class 1.\n", + "major_df = training_df_new.filter(col(\"Severity\") == 0)\n", + "minor_df = training_df_new.filter(col(\"Severity\") == 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "ratio=int(major_df.count()/minor_df.count())" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# performs the undersampling\n", + "undersampled_df = major_df.sample(False, 1/ratio)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Combining the data to create the balanced dataset for binary output\n", + "balanced_data_binary=training_df_new.filter(col(\"Severity\") == 1).unionAll(undersampled_df)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "balanced_data_binary.toPandas().to_csv(\"USAccident_balanced_train_binary.csv\",index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### One Hot Encoding for balanced data" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "#list of all categorical columns\n", + "categorical_columns=['Source','Side','Wind_Direction','month_of_year','day_of_week',\"TMC\",'Sunrise_Sunset','Civil_Twilight',\n", + " 'Nautical_Twilight','Astronomical_Twilight',\"Hour\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "#list of columns to be one hot encoded\n", + "categorical_columns2=[i+\"_Index\"for i in categorical_columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Creating dummies of categorical column\n", + "for category in categorical_columns2:\n", + " categ = balanced_data_binary.select(category).distinct().rdd.flatMap(lambda x:x).collect()\n", + " exprs = [fn.when(fn.col(category) == cat,1).otherwise(0)\\\n", + " .alias(category+\"_\"+str(int(float(cat)))) for cat in categ]\n", + " balanced_data_binary = balanced_data_binary.select(exprs+balanced_data_binary.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Dropping all the original categorical columns\n", + "balanced_data_binary=balanced_data_binary.drop(*(categorical_columns2))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# From the n dummies made for each categorical column, dropping the nth dummy\n", + "balanced_data_binary=balanced_data_binary.drop(*([i+\"_Index_0\" for i in categorical_columns]))" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Saves as csv\n", + "balanced_data_binary.toPandas().to_csv(\"USAccident_balanced_train_binary_OHE.csv\",index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}