{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "     \n", "     \n", "     \n", "     \n", "     \n", "   \n", "[Home Page](../../START_HERE.ipynb)\n", "\n", "[Previous Notebook](Challenge.ipynb)\n", "     \n", "     \n", "     \n", "     \n", "[1](Challenge.ipynb)\n", "[2]\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bike Rental Prediction Challenge - Solution\n", "\n", "## 1. Introduction\n", "\n", "This notebook walks through an end-to-end GPU machine learning workflow where cuDF is used for processing the data and cuML is used to train machine learning models on it. \n", "\n", "After completing this excercise, you will be able to use cuDF to load data from disk, combine tables, scale features, use one-hote encoding and even write your own GPU kernels to efficiently transform feature columns. Additionaly you will learn how to pass this data to cuML, and how to train ML models on it. The trained model is saved and it will be used for prediction.\n", "\n", "It is not required that the user is familiar with cuDF or cuML. Since our aim is to go from ETL to ML training, a detailed introduction is out of scope for this notebook. We recommend [Introduction to cuDF](../../CuDF/01-Intro_to_cuDF.ipynb) for additional information.\n", "\n", "### 1.2. Problem statement\n", "\n", "We are trying to predict daily demand for short-term bike rentals made in 2011 and 2012. We will combine three data sources: bike rental information, historical weather data, and dates of public holidays. In Section 2 of this notebook we will use cuDF to combine these data into a single dataset that can be used as an input for machine learning algorithms. In Section 3 we train models using cuML to predict bike rentals.\n", "\n", "### 1.3 Why RAPIDS?\n", "\n", "Using the GPU accelerated libraries from RAPIDS greatly reduces the execution time of a data science workflow. This leads to faster iteration with data preparation and model selection, and overall a more efficient workflow.\n", "\n", "### 1.2.1 References\n", "\n", "This notebook is inspired by the [blog article](https://medium.com/rapids-ai/essential-machine-learning-with-linear-models-in-rapids-part-1-of-a-series-992fab0240da) from Paul Mahler and its accompanying [notebook](https://github.com/rapidsai-community/notebooks-contrib/blob/master/blog_notebooks/regression/regression_blog_notebook.ipynb). The dataset is prepared along the steps given by *Hadi Fanaee-T and Joao Gama* in their [paper](https://doi.org/10.1007/s13748-013-0040-3) *Event labeling combining ensemble detectors and background knowledge*. The exploratory data analysis notebooks by [Vivek Srinivasan](https://www.kaggle.com/viveksrinivasan/eda-ensemble-model-top-10-percentile) and [Mitesh Yadav](https://www.kaggle.com/miteshyadav/comprehensive-eda-with-xgboost-top-10-percentile) provided useful input for this excercise. \n", "\n", "First part of this notebook contains sections from [Introduction to cuDF](https://github.com/rapidsai-community/notebooks-contrib/blob/master/getting_started_notebooks/intro_tutorials/02_Introduction_to_cuDF.ipynb) by Paul Hendricks, which gives a concise introduction to cuDF, also discussing a few points not mentioned in this notebook. \n", "\n", "Dataset sources:\n", "- The bike sharing dataset is provided by [Capital Bike Share](https://www.capitalbikeshare.com/system-data).\n", "- The weather data is retrieved from the [Bike Sharing Dataset](https://archive.ics.uci.edu/ml/datasets/bike+sharing+dataset) hosted by the UCI Machine Learning repository.\n", "- The original source of the weather data is https://www.freemeteo.com.\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Prepare dataset with cuDF\n", "Let's start by loading the necessary libraries" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import cudf\n", "import pandas as pd\n", "import numpy as np\n", "\n", "from datetime import datetime, timedelta\n", "import os\n", "import sys\n", "sys.path.insert(1, os.path.realpath(os.path.pardir))\n", "import importlib\n", "import utils\n", "importlib.reload(utils)\n", "from utils import fetch_bike_dataset, fetch_weather_dataset, read_bike_data_pandas\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.1 Prepare weather data\n", "First, we will download the weather data." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloading https://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip to data/Bike-Sharing-Dataset.zip\n", "Weather file saved at data/weather2011-2012.csv\n" ] } ], "source": [ "filename = fetch_weather_dataset()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "cuDF DataFrames are a tabular structure of data that reside on the GPU. We interface with these cuDF DataFrames in the same way we interface with Pandas DataFrames that reside on the CPU - with a few deviations. Load data from CSV file into a cuDF DataFrame." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "weather = cudf.read_csv(filename)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.1 Inspecting a cuDF DataFrame\n", "\n", "There are several ways to inspect a cuDF DataFrame. The first method is to enter the cuDF DataFrame directly into the REPL. This shows us an overview about the DatFrame including its type and metadata such as the number of rows or columns." ] }, { "cell_type": "code", "execution_count": 4, "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", " \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", "
HourTemperatureRelative TemperatureRel. humidityWindWeather
02011-01-01T00:00:00Z3.283.0014810.0000Clear or Partly cloudy
12011-01-01T01:00:00Z2.341.9982800.0000Clear or Partly cloudy
22011-01-01T02:00:00Z2.341.9982800.0000Clear or Partly cloudy
32011-01-01T03:00:00Z3.283.0014750.0000Clear or Partly cloudy
42011-01-01T04:00:00Z3.283.0014750.0000Clear or Partly cloudy
.....................
173742012-12-31T19:00:00Z4.221.00166011.0014Mist or Cloudy
173752012-12-31T20:00:00Z4.221.00166011.0014Mist or Cloudy
173762012-12-31T21:00:00Z4.221.00166011.0014Clear or Partly cloudy
173772012-12-31T22:00:00Z4.221.9982568.9981Clear or Partly cloudy
173782012-12-31T23:00:00Z4.221.9982658.9981Clear or Partly cloudy
\n", "

17379 rows × 6 columns

\n", "
" ], "text/plain": [ " Hour Temperature Relative Temperature Rel. humidity \\\n", "0 2011-01-01T00:00:00Z 3.28 3.0014 81 \n", "1 2011-01-01T01:00:00Z 2.34 1.9982 80 \n", "2 2011-01-01T02:00:00Z 2.34 1.9982 80 \n", "3 2011-01-01T03:00:00Z 3.28 3.0014 75 \n", "4 2011-01-01T04:00:00Z 3.28 3.0014 75 \n", "... ... ... ... ... \n", "17374 2012-12-31T19:00:00Z 4.22 1.0016 60 \n", "17375 2012-12-31T20:00:00Z 4.22 1.0016 60 \n", "17376 2012-12-31T21:00:00Z 4.22 1.0016 60 \n", "17377 2012-12-31T22:00:00Z 4.22 1.9982 56 \n", "17378 2012-12-31T23:00:00Z 4.22 1.9982 65 \n", "\n", " Wind Weather \n", "0 0.0000 Clear or Partly cloudy \n", "1 0.0000 Clear or Partly cloudy \n", "2 0.0000 Clear or Partly cloudy \n", "3 0.0000 Clear or Partly cloudy \n", "4 0.0000 Clear or Partly cloudy \n", "... ... ... \n", "17374 11.0014 Mist or Cloudy \n", "17375 11.0014 Mist or Cloudy \n", "17376 11.0014 Clear or Partly cloudy \n", "17377 8.9981 Clear or Partly cloudy \n", "17378 8.9981 Clear or Partly cloudy \n", "\n", "[17379 rows x 6 columns]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A second way to inspect a cuDF DataFrame is to wrap the object in a Python print function `print(weather)` function. This results in showing the rows and columns of the dataframe with simple formating.\n", "\n", "For very large dataframes, we often want to see the first couple rows. We can use the `head` method of a cuDF DataFrame to view the first N rows." ] }, { "cell_type": "code", "execution_count": 5, "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", "
HourTemperatureRelative TemperatureRel. humidityWindWeather
02011-01-01T00:00:00Z3.283.0014810.0Clear or Partly cloudy
12011-01-01T01:00:00Z2.341.9982800.0Clear or Partly cloudy
22011-01-01T02:00:00Z2.341.9982800.0Clear or Partly cloudy
\n", "
" ], "text/plain": [ " Hour Temperature Relative Temperature Rel. humidity \\\n", "0 2011-01-01T00:00:00Z 3.28 3.0014 81 \n", "1 2011-01-01T01:00:00Z 2.34 1.9982 80 \n", "2 2011-01-01T02:00:00Z 2.34 1.9982 80 \n", "\n", " Wind Weather \n", "0 0.0 Clear or Partly cloudy \n", "1 0.0 Clear or Partly cloudy \n", "2 0.0 Clear or Partly cloudy " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.2 Columns\n", "\n", "cuDF DataFrames store metadata such as information about columns or data types. We can access the columns of a cuDF DataFrame using the `.columns` attribute." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index(['Hour', 'Temperature', 'Relative Temperature', 'Rel. humidity', 'Wind',\n", " 'Weather'],\n", " dtype='object')\n" ] } ], "source": [ "print(weather.columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can modify the columns of a cuDF DataFrame by modifying the `columns` attribute. We can do this by setting that attribute equal to a list of strings representing the new columns. Let's shorten the two longest column names!" ] }, { "cell_type": "code", "execution_count": 7, "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", "
HourTemperatureRTempHumidityWindWeather
02011-01-01T00:00:00Z3.283.0014810.0Clear or Partly cloudy
12011-01-01T01:00:00Z2.341.9982800.0Clear or Partly cloudy
22011-01-01T02:00:00Z2.341.9982800.0Clear or Partly cloudy
32011-01-01T03:00:00Z3.283.0014750.0Clear or Partly cloudy
42011-01-01T04:00:00Z3.283.0014750.0Clear or Partly cloudy
\n", "
" ], "text/plain": [ " Hour Temperature RTemp Humidity Wind \\\n", "0 2011-01-01T00:00:00Z 3.28 3.0014 81 0.0 \n", "1 2011-01-01T01:00:00Z 2.34 1.9982 80 0.0 \n", "2 2011-01-01T02:00:00Z 2.34 1.9982 80 0.0 \n", "3 2011-01-01T03:00:00Z 3.28 3.0014 75 0.0 \n", "4 2011-01-01T04:00:00Z 3.28 3.0014 75 0.0 \n", "\n", " Weather \n", "0 Clear or Partly cloudy \n", "1 Clear or Partly cloudy \n", "2 Clear or Partly cloudy \n", "3 Clear or Partly cloudy \n", "4 Clear or Partly cloudy " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### TODO rename the relative temperature column to RTemp, and the relative humidity to Humidity\n", "#weather.columns = ['Hour', 'Temperature', 'Relative Temperature', 'Rel. Humidity', 'Wind', 'Weather']\n", "weather.columns = ['Hour', 'Temperature', 'RTemp', 'Humidity', 'Wind', 'Weather']\n", "weather.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.3 Series\n", "\n", "cuDF DataFrames are composed of rows and columns. Each column is represented using an object of type `Series`. For example, if we subset a cuDF DataFrame using just one column we will be returned an object of type `cudf.dataframe.series.Series`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "0 81\n", "1 80\n", "2 80\n", "3 75\n", "4 75\n", " ..\n", "17374 60\n", "17375 60\n", "17376 60\n", "17377 56\n", "17378 65\n", "Name: Humidity, Length: 17379, dtype: int64\n" ] } ], "source": [ "humidity = weather['Humidity']\n", "print(type(humidity))\n", "print(humidity)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also see a column of values on the left hand side with values 0, 1, 2, 3. These values represent the index of the Series.\n", "The DataFrame and Series objects have both an index attribute that will be useful for joining tables and also for selecting data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.4 Data Types\n", "\n", "We can also inspect the data types of the columns of a cuDF DataFrame using the `dtypes` attribute." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hour object\n", "Temperature float64\n", "RTemp float64\n", "Humidity int64\n", "Wind float64\n", "Weather object\n", "dtype: object\n" ] } ], "source": [ "print(weather.dtypes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can modify the data types of the columns of a cuDF DataFrame by passing in a cuDF Series with a modified data type." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hour object\n", "Temperature float64\n", "RTemp float64\n", "Humidity float64\n", "Wind float64\n", "Weather object\n", "dtype: object\n" ] } ], "source": [ "weather['Humidity'] = weather['Humidity'].astype(np.float64)\n", "print(weather.dtypes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The 'Weather' column provides a description of the weather condidions. We should mark it as a categorical column." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Clear or Partly cloudy\n", "1 Clear or Partly cloudy\n", "2 Clear or Partly cloudy\n", "3 Clear or Partly cloudy\n", "4 Clear or Partly cloudy\n", " ... \n", "17374 Mist or Cloudy\n", "17375 Mist or Cloudy\n", "17376 Clear or Partly cloudy\n", "17377 Clear or Partly cloudy\n", "17378 Clear or Partly cloudy\n", "Name: Weather, Length: 17379, dtype: category\n", "Categories (4, object): ['Clear or Partly cloudy', 'Heavy Rain, Snow + Fog, Ice', 'Light Rain or Snow, Thunderstorm', 'Mist or Cloudy']" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather['Weather'] = weather['Weather'].astype('category')\n", "weather['Weather']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After this step the numerical category codes can be accessed using the `.cat.codes` attribute of the column. We actually will not need the category labels, we just replace the 'Weather' column with the category codes." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "weather['Weather'] = weather['Weather'].cat.codes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The data type of the 'Hour' column is `object` which means a string. Let's convert this to a numeric value! This cannot be done with the `astype` method, you should use the [cudf.to_datetime](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.to_datetime) function!" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Hour datetime64[ns]\n", "Temperature float64\n", "RTemp float64\n", "Humidity float64\n", "Wind float64\n", "Weather uint8\n", "dtype: object" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### TODO convert the 'Hour' column from string to datetime\n", "weather['Hour'] = cudf.to_datetime(weather['Hour'])\n", "weather.dtypes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2.1.2 Prepare features\n", "##### Operations with cudf Series\n", "We can perform mathematical operations on the Series data type. We will scale the Humidity and and Temperature variables, so that they lay in the [0, 1] range (some ML algorithms work better if the input data is scaled this way)." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "weather['Humidity'] = weather['Humidity'] / 100.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will scale the temperature using the following formula T = (T - Tmin) / (Tmax - Tmin). First we select the min and max values." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-7.06 39.0\n" ] } ], "source": [ "T = weather['Temperature']\n", "\n", "# Select the minimum temperature\n", "Tmin = T.min()\n", "\n", "### TODO select the maximum temperature (1 line of code)\n", "Tmax = T.max()\n", "\n", "print(Tmin, Tmax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could simply use the Tmin and Tmax values and apply the above formula on the series. \n", "\n", "##### User defined functions (UDF)\n", "We can write custom functions to operate on the data. When cuDF executes a UDF, it gets just-in-time (JIT) compiled into a CUDA kernel (either explicitly or implicitly) and is run on the GPU. Let's write a function that scales the temperature!" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def scale_temp(T):\n", " # Note that the Tmin and Tmax variables are stored during compilation time and remain constant afterwards\n", " T = (T - Tmin) / (Tmax - Tmin)\n", " return T " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The applymap function will call scale_temp on all element of the series" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "weather['Temperature'] = weather['Temperature'].applymap(scale_temp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets do the same min-max scaling for the wind data" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0 56.996900000000004\n" ] } ], "source": [ "### TODO calculate the minimum and maximum values of the 'Wind' column (2 lines of code)\n", "Wmin = weather['Wind'].min()\n", "Wmax = weather['Wind'].max()\n", "\n", "print(Wmin, Wmax)\n", "\n", "### TODO define a scale_wind function and apply it on the Wind column (~ 2-3 lines of code)\n", "def scale_wind(w):\n", " return (w - Wmin) / ( Wmax - Wmin)\n", "\n", "### TODO apply the scale_wind function on the 'Wind' column\n", "weather['Wind'] = weather['Wind'].applymap(scale_wind)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's inspect the table, the Temperature, Wind and Humidity columns should have values in the [0, 1] range." ] }, { "cell_type": "code", "execution_count": 19, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TemperatureRTempHumidityWindWeather
count17379.00000017379.00000017379.00000017379.00000017379.000000
mean0.48672215.4011570.6269470.2234600.947868
std0.19648611.3421140.1930130.1438111.334769
min0.000000-16.0000000.0000000.0000000.000000
25%0.3265315.9978000.4800000.1228400.000000
50%0.48979615.9968000.6300000.2280470.000000
75%0.65306124.9992000.7800000.2982253.000000
max1.00000050.0000001.0000001.0000003.000000
\n", "
" ], "text/plain": [ " Temperature RTemp Humidity Wind Weather\n", "count 17379.000000 17379.000000 17379.000000 17379.000000 17379.000000\n", "mean 0.486722 15.401157 0.626947 0.223460 0.947868\n", "std 0.196486 11.342114 0.193013 0.143811 1.334769\n", "min 0.000000 -16.000000 0.000000 0.000000 0.000000\n", "25% 0.326531 5.997800 0.480000 0.122840 0.000000\n", "50% 0.489796 15.996800 0.630000 0.228047 0.000000\n", "75% 0.653061 24.999200 0.780000 0.298225 3.000000\n", "max 1.000000 50.000000 1.000000 1.000000 3.000000" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Dropping Columns\n", "\n", "The relative temperature column is correlated with the temperature, it will not give much extra information for the ML model. We want to remove this column from our `DataFrame`. We can do so using the `drop_column` method. Note that this method removes a column in-place - meaning that the `DataFrame` we act on will be modified." ] }, { "cell_type": "code", "execution_count": 20, "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", " \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", "
HourTemperatureHumidityWindWeather
02011-01-01 00:00:000.2244900.810.0000000
12011-01-01 01:00:000.2040820.800.0000000
22011-01-01 02:00:000.2040820.800.0000000
32011-01-01 03:00:000.2244900.750.0000000
42011-01-01 04:00:000.2244900.750.0000000
..................
173742012-12-31 19:00:000.2448980.600.1930183
173752012-12-31 20:00:000.2448980.600.1930183
173762012-12-31 21:00:000.2448980.600.1930180
173772012-12-31 22:00:000.2448980.560.1578700
173782012-12-31 23:00:000.2448980.650.1578700
\n", "

17379 rows × 5 columns

\n", "
" ], "text/plain": [ " Hour Temperature Humidity Wind Weather\n", "0 2011-01-01 00:00:00 0.224490 0.81 0.000000 0\n", "1 2011-01-01 01:00:00 0.204082 0.80 0.000000 0\n", "2 2011-01-01 02:00:00 0.204082 0.80 0.000000 0\n", "3 2011-01-01 03:00:00 0.224490 0.75 0.000000 0\n", "4 2011-01-01 04:00:00 0.224490 0.75 0.000000 0\n", "... ... ... ... ... ...\n", "17374 2012-12-31 19:00:00 0.244898 0.60 0.193018 3\n", "17375 2012-12-31 20:00:00 0.244898 0.60 0.193018 3\n", "17376 2012-12-31 21:00:00 0.244898 0.60 0.193018 0\n", "17377 2012-12-31 22:00:00 0.244898 0.56 0.157870 0\n", "17378 2012-12-31 23:00:00 0.244898 0.65 0.157870 0\n", "\n", "[17379 rows x 5 columns]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather.drop(['RTemp'],axis=1,inplace=True)\n", "weather" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to remove a column without modifying the original DataFrame, we can use the `drop` method. This method will return a new DataFrame without that column (or columns)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Index\n", "\n", "Like `Series` objects, each `DataFrame` has an index attribute." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "RangeIndex(start=0, stop=17379)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weather.index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the index values to subset the `DataFrame`. Lets use this to plot the first 48 values. Before plotting we have to transfer from the GPU memory to the system memory. We use the `to_array` method to return a copy of the data as a numpy array." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0, 0.5, 'Temperature [C]')" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "selection = weather[weather.index<48]\n", "plt.plot(selection['Hour'].to_array(), selection['Temperature'].to_array())\n", "plt.xlabel('Hour')\n", "plt.ylabel('Temperature [C]')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also change the index. Our dataset has one entry for each hour, so one could set the 'Hour' coulmn as index by calling\n", "```\n", "weather = weather.set_index('Hour')\n", "```\n", "\n", "We do not perform this change right now, but we will use it later." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "#weather = weather.set_index('Hour')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2 Prepare bike sharing data\n", "We start by downloading the data" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "24744.0kB [00:01, 13625.36kB/s] \n", "42448.0kB [00:17, 2456.30kB/s] \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Files extracted: ['data/2011-capitalbikeshare-tripdata.csv', 'data/2012Q1-capitalbikeshare-tripdata.csv', 'data/2012Q2-capitalbikeshare-tripdata.csv', 'data/2012Q3-capitalbikeshare-tripdata.csv', 'data/2012Q4-capitalbikeshare-tripdata.csv']\n" ] } ], "source": [ "files = fetch_bike_dataset([2011,2012])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's read the first file to have an idea of the dataset" ] }, { "cell_type": "code", "execution_count": 25, "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", " \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", " \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", "
DurationStart dateEnd dateStart station numberStart stationEnd station numberEnd stationBike numberMember type
035482011-01-01 00:01:292011-01-01 01:00:37316205th & F St NW316205th & F St NWW00247Member
13462011-01-01 00:02:462011-01-01 00:08:323110514th & Harvard St NW3110114th & V St NWW00675Casual
25622011-01-01 00:06:132011-01-01 00:15:3631400Georgia & New Hampshire Ave NW31104Adams Mill & Columbia Rd NWW00357Member
34342011-01-01 00:09:212011-01-01 00:16:363111110th & U St NW31503Florida Ave & R St NWW00970Member
42332011-01-01 00:28:262011-01-01 00:32:1931104Adams Mill & Columbia Rd NW31106Calvert & Biltmore St NWW00346Casual
..............................
12267623002011-12-31 23:41:192011-12-31 23:46:203120115th & P St NW3121417th & Corcoran St NWW01459Member
12267633872011-12-31 23:46:432011-12-31 23:53:1031223Convention Center / 7th & M St NW3120115th & P St NWW01262Member
12267642612011-12-31 23:47:272011-12-31 23:51:4931107Lamont & Mt Pleasant NW31602Park Rd & Holmead Pl NWW00998Member
122676520602011-12-31 23:55:122012-01-01 00:29:333120521st & I St NW31222New York Ave & 15th St NWW00042Member
12267664682011-12-31 23:55:562012-01-01 00:03:453122118th & M St NW3111110th & U St NWW01319Member
\n", "

1226767 rows × 9 columns

\n", "
" ], "text/plain": [ " Duration Start date End date \\\n", "0 3548 2011-01-01 00:01:29 2011-01-01 01:00:37 \n", "1 346 2011-01-01 00:02:46 2011-01-01 00:08:32 \n", "2 562 2011-01-01 00:06:13 2011-01-01 00:15:36 \n", "3 434 2011-01-01 00:09:21 2011-01-01 00:16:36 \n", "4 233 2011-01-01 00:28:26 2011-01-01 00:32:19 \n", "... ... ... ... \n", "1226762 300 2011-12-31 23:41:19 2011-12-31 23:46:20 \n", "1226763 387 2011-12-31 23:46:43 2011-12-31 23:53:10 \n", "1226764 261 2011-12-31 23:47:27 2011-12-31 23:51:49 \n", "1226765 2060 2011-12-31 23:55:12 2012-01-01 00:29:33 \n", "1226766 468 2011-12-31 23:55:56 2012-01-01 00:03:45 \n", "\n", " Start station number Start station \\\n", "0 31620 5th & F St NW \n", "1 31105 14th & Harvard St NW \n", "2 31400 Georgia & New Hampshire Ave NW \n", "3 31111 10th & U St NW \n", "4 31104 Adams Mill & Columbia Rd NW \n", "... ... ... \n", "1226762 31201 15th & P St NW \n", "1226763 31223 Convention Center / 7th & M St NW \n", "1226764 31107 Lamont & Mt Pleasant NW \n", "1226765 31205 21st & I St NW \n", "1226766 31221 18th & M St NW \n", "\n", " End station number End station Bike number \\\n", "0 31620 5th & F St NW W00247 \n", "1 31101 14th & V St NW W00675 \n", "2 31104 Adams Mill & Columbia Rd NW W00357 \n", "3 31503 Florida Ave & R St NW W00970 \n", "4 31106 Calvert & Biltmore St NW W00346 \n", "... ... ... ... \n", "1226762 31214 17th & Corcoran St NW W01459 \n", "1226763 31201 15th & P St NW W01262 \n", "1226764 31602 Park Rd & Holmead Pl NW W00998 \n", "1226765 31222 New York Ave & 15th St NW W00042 \n", "1226766 31111 10th & U St NW W01319 \n", "\n", " Member type \n", "0 Member \n", "1 Casual \n", "2 Member \n", "3 Member \n", "4 Casual \n", "... ... \n", "1226762 Member \n", "1226763 Member \n", "1226764 Member \n", "1226765 Member \n", "1226766 Member \n", "\n", "[1226767 rows x 9 columns]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cudf.read_csv(files[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are only interested in the events when a bicicle was rented. Let us read the first column from all files, by specifying the `usecols` argument to [read_csv](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.io.csv.read_csv). We can use the `parse_dates` argument to parse the date string into a datetime variable, or the [to_datetime](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.to_datetime) function that we have used for the weather dataset. After all the tables are read we will concatenate them.\n", "\n", "Note: one has to specify a list of columns [ column1, column2 ] for the `usecol` argument." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "def read_bike_data(files):\n", " # Reads a list of files and concatenates them\n", " tables = []\n", " for filename in files:\n", " ### TODO read column 1 ('Start date') from the CSV file, and convert it to datetime format\n", " ### (1-2 lines of code)\n", " tmp_df = cudf.read_csv(filename, parse_dates=[1], usecols=[1])\n", " \n", " ### END TODO\n", " tables.append(tmp_df) \n", " \n", " merged_df = cudf.concat(tables, ignore_index=True)\n", " \n", " # Sanity checks\n", " if merged_df.columns != ['Start date']:\n", " raise ValueError(\"Error incorrect set of columns read\")\n", " if merged_df['Start date'].dtype != 'datetime64[ns]':\n", " raise TypeError(\"Stard date should be converted to datetime type\")\n", " \n", " return merged_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will also measure the execution time of reading and processing the data (you can execute the cell multiple times to have a better measurement)." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 91.6 ms, sys: 330 ms, total: 422 ms\n", "Wall time: 421 ms\n" ] } ], "source": [ "%%time\n", "bikes_raw = read_bike_data(files)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For comparision, we can repeat the same operation on the CPU. We have prepared a helper function for that." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 4.31 s, sys: 192 ms, total: 4.51 s\n", "Wall time: 4.5 s\n" ] } ], "source": [ "%%time\n", "bikes_raw_pd = read_bike_data_pandas(files)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We want to count the number of rental events in every hour. We will define a new feature where we remove the minutes and seconds part of the time stamp. Since pandas has a convenient `floor` function defined to do it, we will convert the column to a pandas Series, transform it with the floor operation, and then put it back on the GPU." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "bikes_raw['Hour'] = bikes_raw['Start date'].to_pandas().dt.floor('h')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will aggregate the number of bicicle rental events for each hour. We use the [groupby](https://docs.rapids.ai/api/cudf/nightly/api.html#groupby) function." ] }, { "cell_type": "code", "execution_count": 30, "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", "
cnt
Hour
2011-01-01 00:00:0016
2011-01-01 01:00:0038
2011-01-01 02:00:0031
2011-01-01 03:00:0012
2011-01-01 04:00:001
\n", "
" ], "text/plain": [ " cnt\n", "Hour \n", "2011-01-01 00:00:00 16\n", "2011-01-01 01:00:00 38\n", "2011-01-01 02:00:00 31\n", "2011-01-01 03:00:00 12\n", "2011-01-01 04:00:00 1" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bikes = bikes_raw.groupby('Hour').agg('count')\n", "bikes.columns = ['cnt']\n", "bikes.head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's add a column to the new dataset: the date without the time of the day. We can derive that similarly to the 'Hour' feature above. After the groupby operation, the 'Hour' became the index of the dataset, we will apply the `floor` operation on the index. " ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "bikes['date'] = bikes.index.to_pandas().floor('D')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It will be usefull to define a set of additional features: hour of the day, day of month, month and year https://docs.rapids.ai/api/cudf/nightly/api.html#datetimeindex" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "bikes['hr'] = bikes.index.hour\n", "\n", "### TODO add year and month features (~ 2 lines of code)\n", "bikes['year'] = bikes.index.year\n", "bikes['month'] = bikes.index.month" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remove the offset from year" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "bikes['year'] = bikes['year'] - 2011" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Visualize data\n", "It is a good practice to visulize the data. We will have to use the to_array() method to convert the cudF Series objects to numpy arrays that can be plotted." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(bikes.index.to_array(), bikes['cnt'].to_array())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is hard to see much apart from the global trend. Let's have a look how the 'cnt' variable looks like as a function the 'month' and 'hr' features. We will use [boxplot](https://seaborn.pydata.org/generated/seaborn.boxplot.html) from the Seaborn package." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtoAAAFNCAYAAAA+ZchVAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABj3UlEQVR4nO3deXxU9b0//tc7G0vYhwCZsNgE7fe2XK2VugBuwWLRttb2ar3htvbqve2l1mpbsIr+ul0VLtFbrbapXrUrsbWLRXEhQrSoVVSqIgqtITUswxIGQlgkZHn//jhnhjnD5MySc87MnHk9H488Mp8z55zPZ2Yyn7zP53wWUVUQEREREZGzirJdACIiIiIiP2KgTURERETkAgbaREREREQuYKBNREREROQCBtpERERERC5goE1ERERE5AIG2pQyEfm5iNya7XKQv4nI90Tk19kuB5EbWI9SrhGR8SKyRkQOiMidaR57nohsc6tsfsBAO0+IyHsi8r6IHBSRfSLyhIhMciGf50TkiJnPHhH5o4hUZnAeFZGpSfaZKCLLRCQsIodE5BUR+WTmpQdE5CQR+Z1Z9v0isl5EvikixQM5bwr5pvTPUwytIvKOm+XJF6ykyUusR1POl/WoA8y/twvitn1JRF7wsAyDRGSxiGwx//bfFZGFIiIxu30ZwB4AI1T1W3HHP2X+HR8UkW4RORqT/qnDZf2SiPTGnP8fIvIzETnJyXy8xkA7v3xKVYcBqASwC8A9LuXzNTOfkwCMAvBDpzMQkTEAXgBwFMCHAYw182kUkX/J8Jw1ANYC2Argn1V1JIDLAEwHMNyJcjvgHADjAFSLyMcyOYGIlDhbJKKCwnrU/pysR/OQzev5HYDZAC6C8fl9AUZgfXfMPlMAvKMJVjBU1bmqOsz8W14GYGkkrar/5eiLMLxk5jUSwAUA3gewTkSmuZCXJxho5yFVPQLg9wA+FNkmIiNF5Jci0i4ibSJyi4gUicgYEdkmIp8y9xsmIi0i8sUU8tkL4A8AEv6Bi8h/mufaKyKPiUjQ3L7G3OVN86r08wkO/waAgwCuVtWdqvq+qj4M4DYAd0auts0Wnf8yr8L3iciP467EY30fwF9U9ZuqusN8DX9T1TpV7TDP92kReVtEOsxWp3+KeT2W1qPY1pVIy6uIfEtEdovIDhH5d/O5LwOYB+AG8/U+bvO2XglgOYAnzcex7+eHReQZ8/3cJSKLzO3fE5Hfi8ivRaQTwJdEJGi+53vNz+A/Y85zuoi8JiKd5nn+19w+2DxH2Hz9r4rI+ESFNFtiFpotWYdE5EExbi8+JcbtxVUiMjpmf7v39T0RWWCea7+I/NYsSzmApwAEY1owguZhZebf8wHzvNNjzvdtEdluPvc3EZlt834TJcR6lPWo2/VoKkTkn8z3sMN8Tz8d89xzIvIfMWlLa7j5Xl8jIu8CeDfBuWcDmAPgc6q6QVV7VPVlAP8G4BoRmSoiPzffw8j7fkH8eVJ8Hcd9pub2QSJyhxgt6rtE5KciMiTZ+VS1V1U3q+pXAfwZwPdizvk7Edlp/j9ZIyIfNrd/zMyjJGbfz4nIG5m8JseoKn/y4AfAewAuMB8PBfALAL+Mef6XMCqe4QBOAPB3GJUvYHzRdsJoAfg/AL+3yec5AP9hPh4LoBnAr8z0zwHcaj6uhXGr6aMABsFoFVoTcx4FMNUmn5cBfD/B9g+Yx34w5jwrYLQITQbQDuAT/ZxzJ4B/t8nzJACHAHwcQCmAGwC0AChLVOa413segB4APzCPvQjAYQCj4/e1yX8ogE7z2M+Z718k7+EAdgD4FoDBZvoM87nvAegG8BkYF8dDYFQ8PzH3/Yj5vsw2938JwBfMx8MAnGk+/gqAx81yFAM4Dcatwv7+3l4GMB5AFYDdAP4K4FTz824G8N0U39f3ALwCIAhgDICNAP4r5n3dFpf39wAcMd+nYgCLAbxsPvdBGC1tQTN9AoCabH8/+ZMfP2A9OgqsRz8Db+vRC+K2fQnAC+bjUvO9WwSgzPx7OBDzuUX/juKPjXmvn4FRrw5JkP8SAH/up2xtAL6S6vve334pfKZ3AXjMLONw871b3M/5La8vZvtVAHbFpYfD+M7cBeCNmOfeATA3Jv0ogG+5Wa8k+2GLdn75k4h0wKhkPg6gHgDE6Df3eQA3qeoBVX0PwJ0wbhFBVZtg3D5aDeBiGBWFnR+Z+bwJo9L6ZoJ95gF4SFX/qqpdAG4CcJaInJDiaxlrnjvejpjnI5aoaoeqbgHwLIwKMZFAP+eM+DyAJ1T1GVXtBnAHjMp2Ropl7gbwA1XtVtUnYbQkfTDFYwHgswC6ADTB+KdXAuPzAIBPAtipqneq6hHzc1wbc+xLqvonVe2D8d7MAvBtc983ADwA8/M2yzlVRMaq6kE1WjAi2wMw/gn2quo6Ve20Ke89qrpLVbcDeB7AWlV93fy8H4URdAOpva8/UtWQGq17j6P/zzDiBVV9UlV7AfwKwCnm9l4YleuHRKRUVd9T1c1JzkUUi/Uo61Ev69E/ma3VHebfw09injsTRhC/RFWPqmqz+Zr+NY33Y7Gq7lXV9xM819/fB8ztY/t5Ll0JP1Pzrsl/AviGWcYDAG4HcEWa5w/BCNQBAKr6kPnZdsG4gDpFREaaT/8CRot9pGvVhQAaM39pA8dAO798RlVHwQg0vgbgzyIyAcaXpQzGFWpEG4yWyIj7Ydy6/JmqhpPk83VVHaWqVao6T1XbE+wTjM1PVQ8CCMflaWcPjD6S8Spjno/YGfP4MIyKKZFwP+eMiC9zH4zW0VTLHFbVnhTLksiVAB5R4/ZdF4A/4thtz0kA7ALGrTGPgwAilVZE7Od9NYxWp03mbc3IwKhfAVgJ4DciEhKRpSJSapPnrpjH7ydIR157Ku9rqp9hf/sPFpESVW0BcD2MynW3iPxGjnU3IUoF61HWo4B39ehnzL+DUebf3VfjyrDVfA8TlSEVW22e6+/vA+b2Pf08l67+PtMKGC3/62IuNJ42t6ejCsBewLggFpElIrLZ7AL0nrlP5KLh1wA+JSLDAFwO4Hk1u0BlCwPtPGReRf8RRuveLBhflm4YAxoiJgPYDkRbau6DcVt0viQZxZ6iUGx+YvS3DUTyTMEqAJ8Tkfi/wcthVBx/z6BMq2DcSuxPfJkFRsUcKfNhGJVCxIQ08j5uEEksEZkI47bgv5l9y3YC+BcAF4nIWBivuSbF84cAjBGR2IFJ0c9bVd9V1X+FcYv7fwD8XkTKzdaG76vqh2C0Pn0SQNI+pilI9r7asX3fEh6g2qiqs8w8FcZrJEoL61H7c9o8z3rUuXo0BGBS3OcXLQOMLjrJ3ku792wVgDMkbmYdETkdxmfWnHaJ07MHRqPMh2MuNkaqMdgxHZfCuKsKAHUALoExUHIkjC5eACAAYN6Bfck85gswLoyyioF2HhLDJQBGA9ho3l5/BMBtIjJcRKbAuE0ZmYt4kfn7Khi3+X4pA5+mqRHAv4vIR0RkEIzbQWvN262A0fpZbXP8DwGMAPCgiEwwB5j8K4CbASxU1bQDMADfBTBDROrNFiqYgz1+LSKjYLxHF4vIbLMF4lswbkH+xTz+DQB15hXzJwCcm0beyV7vF2D80/sgjFu2H4HRWrINxm3CFQAmiMj15uCR4SJyRqITqepWs8yLzfftZBitL8vM1/xvIlJhtpJ0mIf1isj5IvLP5mffCSOo6E3jNfYn2ftqZxeAQMxtP1si8kERqTX/5o7AqMSdeA1UYFiP9ov1KDyrR9fCCKZvEJFSETkPwKcA/MZ8/g0AnxWRoeaF3dXpnFxVV8Ho6vQHMQaJFovImeZrbFDV4wZQOsl87/4PwA9FZBwAiEiViFyY7FizrB8QkXtg9AP/vvnUcBh/b2EYFyG3Jzj8lzDGDvwzjG6OWcVAO788LiIHYXy5bwNwpaq+bT53LYwvbCuM6Z4aATwkIqfB+GfxRfMfyf/AuAK+cSAFUdXVAP4/GKPpd8BoRYjtd/U9AL8Q43bR5QmOD8NoRRoMY/BC2CznF1T1txmWaTOAs2Bc4b4tIvvN8r0G4ICq/g1G3617YFxpfwrGVF9HzVNcZ27rgNF38k9pZP8gjH7DHSKS6LgrAfxEjZkBoj8AfgrjczwAo7/op2Dc4n0XwPk2+f2r+TpDMCqS76rqM+ZznzBf/0EYUzhdocYMCxNgzLLQCWNA4p9xLIjIWArvq92xmwA8DKDVfO+SdQMZBGOAzx4cG5i2yPYIIivWo/ZlYj1qcL0eNd+zTwOYC+O9/AmMv7FN5i4/hDF14y4YfY+XZZDN52D0yX8aRt/pX8N4n6/NpMwZ+DaMAZ8vi9HVYxXs++SfFfP9fA7GheTHVPUt8/lfwuhesx3G3/zLCc7xKIy7Lo+q6iEnXsRASGYXvEREREREuUdENsOYVWVVtsvCFm0iIiIi8gUR+RyMO05u90FPia9WRiIiIiKiwiQiz8FYhOoLcbO5ZA27jhARERERuYBdR4iIiIiIXMBAm4iIiIjIBa710RaRh2BM5L5bVaeZ28YA+C2M6XTeA3C5qu4zn7sJxhyRvTBW1Fppbj8NwM9hLPH6JIDrUpkbdOzYsXrCCSc4+pqIiLywbt26Paqa7uppA5bNept1NhHlK7s627U+2iJyDow5G38ZU2EvhbHk6RIRuRHAaFX9toh8CMZcuqfDWJJ0FYCTVLVXRF6BMS/nyzAq7B+p6lPJ8p8+fbq+9tprrrw2IiI3icg6VZ2ehXyzVm+zziaifGVXZ7vWdURV18Bcmz7GJTAmXYf5+zMx23+jql2q+g8Yk5ufLiKVAEao6ktma8gvY44hIiIHsd4mInKW1320x6vqDgAwf48zt1cB2Bqz3zZzW5X5OH47ERF5g/U2EVGGcmUwpCTYpjbbE59E5Msi8pqIvNbe3u5Y4YiI6DgDrrdZZxOR33kdaO8ybyvC/L3b3L4NwKSY/SYCCJnbJybYnpCq3q+q01V1ekWF5+OIiIj8yLV6m3U2Efmd14H2YwCuNB9fCWB5zPYrRGSQiHwAwIkAXjFvUx4QkTNFRAB8MeYYIiJyH+ttIqIMuTm938MAzgMwVkS2AfgugCUAHhGRqwFsAXAZAKjq2yLyCIB3APQAuEZVe81TzcexaaKeMn+IiMhhrLeJiJzl2yXYOVUUkfNaWlqwcOFC3Hnnnaiurs52cXwrW9P7ZRPrbCLKV1mZ3o+I/Of222/H4cOHcdttt2W7KERERDmPgTYRpaSlpQXbt28HAGzbtg2tra1ZLhEREVFuc62PNhH5y+23325J33bbbXjwwQddySscDmPx4sVYtGgRxowZ40oeRESFpqGhIdpIEmk4qaqqQnV1NebPn+/YMXQMW7SJKCWRCjZi27Zt/ew5cI2NjdiwYQOWLVvmWh5ERIXsyJEjOHLkiOvHFDq2aBNRTgmHw2hqaoKqoqmpCfPmzWOrNhGRA2JboBcuXAgAqK+vd/wYOoYt2j4TDoexYMEC7N27N9tFIZ8pKiqyTTulsbERfX19AIC+vj62ahMRUd5ioO0zvOVObqmsrLSkg8GgK/k0Nzejp6cHANDT04Pm5mZX8iEiInIbA20fib/lzlZtclI4HLak9+zZ40o+M2bMsKRnzpzpSj5ERERuY6DtI7zlTm4aP368bdotfl1Ui4iI/I+Bto/wlnthc7t//u7du23TTnnxxRdt00RERPmCgbaP1NbWoqTEmEimpKQEtbW1WS4Recnt/vmzZ8+GiAAARASzZ892JZ9x48bZpomIiPIFA20fqauri84EUVRUhHnz5mW5ROQVL/rn19XVRS/kSktLXfv72rVrl22aiIgoXzDQ9pFAIIA5c+ZARDBnzhzOPVxAvOifHwgEcO655wIAzj33XNf+vrLVF5yIiMhpDLR9pq6uDtOmTWNrdoHxun++mwMUveoLTkRE5DYG2j4TCARwxx13sDW7wHjRPz8cDmPNmjUAgDVr1rg26DK+77dbfcGJiIjcxkCbyAe86J/v1fSRc+fOtaQvvvhiV/IhIiJyGwNtIh/won++V91THn30UUv6j3/8oyv5EBERuY2BNpEH3J7jGnC/f75X00c+99xzlvSzzz7rSj5ERERuY6BN5AG357gG3O+fX1dXFx0EqaquBfTxAy25MiQREeUrBtpU0LxoafZijmsvBAIBS9qtgP7888+3TRMREeULBtpU0LxoaW5sbERvby8AoLe319W83LRu3TrL63j99dddySe+S8oFF1zgSj5ERERuY6BNBcurlubm5mZLgOrWIMJ169Zh7ty5rgXAt956qyX9gx/8wJV87rvvPku6oaHBlXyIiIjcxkCbCpZX09XNmDHDNu2U22+/HX19fccFxE45fPiwbdopbW1ttmkiIqJ8wUCbCpbXqylGiIjj51y3bh0OHjwIADh48KBrrdpeKC8vt00TERHlCwbaVLC8mq7uL3/5iyX94osvOp7H7bffbkm70ao9aNAg27RT3n//fds0ERFRvmCgTQXLi9UUASOgLy4uBgAUFxe7EtBHWrP7Szuhq6vLNu2USHee/tJERET5goE2FSwvVlMEjIA+ti+4GwH9sGHDbNNERETkPQbaVNBmzJgBEcGsWbNczSd2oRc3fOlLX7Kkr776alfy8QL7aBMRkV8w0Kac1dLSgksvvRStra2u5XHfffehr6/P1Snk7r77btu0Ex599FFL+g9/+IPjecQvWDN27FjH8wAQnQqxvzQREVG+YKBNOWvp0qU4fPgwlixZ4sr5W1paolPHtbW1uRbQr1271pJ++eWXHc9j+/btlvS2bdsczyN+Or9Dhw45ngdw/AI1XLCGiIjyFQNtykleBMFLly61pN0K6P3Cq9lA6urqoo9FxLVBqkRERG5joE05yYsg2KuFUYYOHWqbdkJFRYUlPW7cOMfz8HLAZWQ2GDfmHCciIvIKA23KSV4EwV4Fjrfccosl/Z3vfMfxPPbs2WNJt7e3O57H1772NUv6uuuuczwPwFixMxJgi4hrK3YSERG5jYE25aQpU6bYpp3Q3d1tm3bKCSecYEm78VriZzNxY3aT+IV2nn/+ecfzAIwVOyMDIHt7ez1bsZOIiMhpDLQpJ33lK1+xpOfPn+94HvGzZsR3v3BK/Iwmbs5w4qb4wHrNmjWu5DNjxgxLeubMma7kQ0RE5DYG2pST4pctf+GFFxzPY+fOnZb0jh07HM8DOL7sbrUE+0X8ipNHjhzJUkmIiIgGhoE25aT47gJudB+IH2jn1sA7L7p1+En8RVZ8moiIKF+UZLsARInU1tZixYoVlrTTzjvvPKxatSqaPv/88x3PAwAmTJhgaT2fMGGCK/n4BResIco9DQ0N0WlWI/P2V1VVobq62pWufUR+wRZtyknx/XTdWCL90ksvtaQ/+9nPOp4HAJx44omW9EknneR4HmPGjLFNExE55ciRI+zSRZQiBto+Ew6HsWDBAuzdu9e1PLxYGv3HP/6xJX3vvfc6nsdvfvMbS/rhhx92PA8AePXVVy3pV155xfE89u3bZ5smIhqI+fPno76+HvX19aipqUFNTQ3q6+vZmk2UBANtn2lsbMSGDRtcnXvY7aXRAW+WFPdqFg0v+oKzHzgREVHuYaDtI+FwGCtXroSqoqmpyZVWbS+WRvcbr5Yud1tktcb+0k4ZPHiwJT1kyBBX8iEiInJbVgJtEfmGiLwtIhtE5GERGSwiY0TkGRF51/w9Omb/m0SkRUT+JiIXZqPM+aCxsRE9PT0AjMVX3GjV9mJpdAA4++yzbdPkvfgBqbNnz3Yln/i+n/l6YeInrLOJiDLjeaAtIlUAvg5guqpOA1AM4AoANwJYraonAlhtpiEiHzKf/zCATwD4iYgUe13ufLB69epolwFVxerVqx3Pw4ul0QHgiiuusKTr6upcyccLXk0j6LarrrrKNk3+xDqbiChz2eo6UgJgiIiUABgKIATgEgC/MJ//BYDPmI8vAfAbVe1S1X8AaAFwurfFzQ/jxo2zTTvBi6XRAeDRRx+1pP/whz84nkcgELCk41eKdEr8ipNufC5ELmOdTUSUAc8DbVXdDuAOAFsA7ACwX1WbAIxX1R3mPjsARKKRKgBbY06xzdxGcXbt2mWbdoIXS6MD3ixY09HRYUm7NVPHnj17LOn29nZX8nFb/NLxP/nJT1zJx6u+4JQa1tlERJnLRteR0TBaPD4AIAigXET+ze6QBNsSTqkgIl8WkddE5LV8DWYGYtSoUbZpJ3ixNDrgzSwaXs3U4ZfAMX6WFreWku/r67NNk7dYZxMRZS4b//EvAPAPVW1X1W4AfwQwA8AuEakEAPP3bnP/bQAmxRw/EcZty+Oo6v2qOl1Vp8ffri8EsasPJko7wYuWZsCbfs2DBg2yTTvlrLPOsqTjF+MhynGss4mIMpSNJdi3ADhTRIYCeB/AbACvATgE4EoAS8zfy839HwPQKCL/C6M15UQAzq/4QSmpra3FU089hd7eXhQXF7uyNDoAVFZWWubSDgaDjueRrWn33Gg5nzZtGjZs2GBJD1Tsksv9WbhwIQA4ugzz4MGDLTOPcHq/rGOdTUSUoWz00V4L4PcA/grgLbMM98OorD8uIu8C+LiZhqq+DeARAO8AeBrANara63W580FlZaVt2gl1dXWWmU3mzZvneB6AMSd4rPh+zvkkvrtNfNoJEyZMsKTd+OxLS0tt007p6uqypLnUc3axzibKfV6sCk2ZyUaLNlT1uwC+G7e5C0ZLSaL9bwNwm9vlyndTp07Fjh07LGk3xAbabgkEApYW7fgZQsgqPnh/8cUXsWDBggGdM76FuqWlBddcc000/aMf/QjV1dUDyoPyA+tsotwWuyr0tddem+3iUIz8HJVFCa1bt8427YTGxkZL2q2l3uOXYI9PO6G8vNw27RQvWpvj+3270Q986tSp0VbsyspK14JsLidPRJS6cDiMpqYmV1eFpswx0PYRL4ItLxbFcUtDQwMWLlwY/Uk0v3Xkufip7AYiG9P7ubUozpQpU1BUVITvfOc7rpyfiMgrfulu0djYGJ2dqa+vz7UGMMoMA20fcyPY8mJRHK+MGDEi+rioqAjDhw93JZ+SkhLbtBMSdR1xw9ChQzFt2jR2GUmRX/6RE/lRbHeLfNbc3Iyenh4AQE9Pj2uzgVFmstJHm9zhRj/deF4sigMYAd3hw4ct6YFKNCvGV77yFbz33nu4/fbbceqppw44j0QOHTpkm3bCjBkzsGrVqmh65syZjufhleLiYvT29lrS+Yr9JolyU3x3i3nz5mHMmDEpHbd48WIsWrQopf29UFtbi6effho9PT0oKSlxbTYwygxbtH2ktrY22lrq1pdt/Pjxtmmn/PM//7Nt2ikjRozAySef7FqQnS353K/55JNPtqRPOeWULJVkYNhvkih3ZdrdIhdbwevq6qILoRUVFbk2GxhlhoG2j3jxZfOqRXv9+vW26XySqC+407yYQtArmzZtsqQ3btyYpZIMDPtNEuWuTLpbeHnxnE63s0AggDlz5kBEMGfOnJxpaScDA20fCQQCOOOMMwAAZ555pitftvhp9saOHet4HgCOK3s+T+/nxZzgtbW10S4Wbi4k5IVsLSTkNPabJMpdtbW10XFMIpJSnZnpxXMmYzXSbTmvq6vDtGnT2Jqdgxho+0xkJb9kK/plKn5Z99h5u/MxHy9EKub+0k6oq6uzBNqsbLPPi65cRJSZuXPnWmbQuvjii5Mek+nF80MPPYS33noLDz74YEr7Z9JyHggEcMcdd7A1OwdxMKSPtLS0ROeb3rZtG1pbWx2fHcKrOY7jZ0xxa7o6L7gxuC/R8uiR92j48OFYvHhxdLuTy6N74YwzzsDatWuj6TPPPDOLpclcXV0dnnzySQDGxRUvfohyx1NPPWVJP/HEE0kHLGcy6DAcDkcD8ubmZlx99dVJg+FELeccTJ2/2KLtI0uXLrWklyxZ4ngegwYNsqQHDx7seB4AcNZZZ1nSbswJ7hWvutsUFRWhqKgor6dcBIAvfvGLlvSVV16ZpZIQkV/FrwGRypoQmYyDeuihhyxBcyqt2ux25i9s0faRtrY227QT4vvLxk7B56T4gL6srMyVfLywe/duS9qJAaSJWqgXLlwIAKivrx/w+b0U3zq/bds2y/O33HILqqqqADjbOu/2NF2JVlFlqxRRbhg3bpzlf2QqDRSBQADnnHMOVq1ahXPPPTeleuPZZ589Lh2pq/vD6fr8hYG2j5SXl1vmaHZrSXE3xAdbGzZssDzf3NwcDVjzrSsEpaejo8OS3rdvXzTQdpLbc1w3NzdbWrKam5sZaBPliPgGkPh0Mql2m8ykG2RdXR1WrlwZ3T8fu51F/qdHurO60ViSLxho+4gXszUUFRVZBvNFbqM5bdSoUZYBIKNHj3YlH8q++Er3nnvuwYoVKwAYgwg/8YlPOB6ghsNhrFy5Mu3FKtJx2mmn4fnnn4+mp0+f7uj5iShzs2fPxhNPPAFVhYhg9uzZSY8Jh8NYs2YNAGDNmjUp9bc+77zzLIuJnX/++UnzCQQCGDduHLZv347x48fn9QDHI0eOZLsIWcdA20e8GEA4c+ZMS/Awa9YsR84bH2yFw2HMmzcPqoqysjLce++9eV3ZUOrq6uqi/wDdmg++sbEx2geyu7vblVbt+MGqmzdvdvT8RJS5SKtxd3c3SktLU6pnMhmkeOmll1oC7c9+9rNJ8wmHwwiFQgCAUCiEvXv35t3/v8j/9Hzt0ugkDob0kfgBg14MIHRr1pFAIBBtxc6nCfgbGhqwcOFCy09paalln9LS0uhzDQ0NWSpp7vLis1+9erVlaq9UBkKlK3LLtL80EWVPIBDAhRdemNYiL5kMUkw0u0kyDz30ULR+SnUAJeUutmj7mBst2l6uQDh+/Hh0dXXlZf+0WLFT+yVK0/Hc/uwzGQiVrqFDh1oGCw8dOtTxPIgoc3V1dWhra0u5nslkkGJ8MJ7KWI10BlCyL3TuY6DtIy+99JIl7UYQ7OX81qWlpaipqcmb1mwg8WwgsX2OAeCiiy7ioLgk3P7sBzoQKhVdXV22aSLKrsgiL6mqq6uLtlCrakoBem1traX+TyU4z+T/LPtC5y52HfERLxaT8dP81l6pq6uLVpRlZWV530LvB/EDn1IZCJUuPy26RORH6S6NHggELMu2p9IQEP8/MpVxTen8n50/fz7q6+tRU1ODmpoa1NfXo76+nq3ZOYSBto9UVFTYpp1w9OhR2zQdL1/7m/vZ3LlzLelUll9OFy9KiXJbukujr1u3ztJH+/XXX096zH333WdJc1xO4WGg7SNe3A6PXRobAF5++WXH8/Cj8ePHo7y8nK3ZOSKTAUrp8tOiS0R+E780eiqt2rfddpsl/d///d9Jj8lkIbn4bp8vvvhi0mModzHQ9hHeqs5d+djf3M8SDVBympcDh4koPZksjR67IFyidCJTpkyxTScSu1ZFojTlFwbaPjJhwgRLurKy0vE8GMyTH3gxFWZtbS2Ki4sBAMXFxVxGmSiHJJrZww033HCDJX3jjTcmPYb/Z/2FgbaPxN/6CofDjucxePBg2zRRPoifAcSNsQZ1dXXRlVPdWniHiDLjVTA7derU6JR7EydORHV1ddJj4i/KeZGe3xho+4gXMyl4scw7kdu86AMZWUYZQN4vo0zkN6eddpolPX369KTHRC6c+0v3JxJcf+ADH0hp/6uuusqSvvrqq1M6jnITA20fiZ9lJL4riRNKSkps00T5wItFhMLhcHQRie3bt6c8hRgRuS+TQYrxA5rjBzwnEg6Ho5MIrF27lvVAAWKg7SM/+9nPLOkHHnjA8TwiUxv1lyYiw0MPPRR9rKpcRpkoh+zcudOS3rFjR9Jj4heFSeWObmNjo2XQ5bJly5IeE1t3JEpTfmGgTUTkAi9mNiGi3Nbc3GyZezuVeuC5556zpN0aqEneYKBNROQCTtFFRLW1tZbVJFMZ2OjFKs/kHQbaPhLff4wLZBAlNmTIEEt66NChWSoJEfnZ3Llzo4Gyqqa0Cq0X04+Sdxho+wjn3iRKTfx0fvHT/TkhMod2f2kiclY4HMaCBQtSGnDo1cD+TFahjR9kyWl08xsDbR8ZO3asbZqIDF7MOhI/XdjHPvYxx/MgomMaGxuxYcOGlAYcZjJV37Rp0yzpk08+Oekxq1evtk0nwiXY/YWBto/Ej6KOTxORd7Zt22abJiLnhMNhNDU1QVXR1NSUtFU7fjrc+HQio0ePtqRHjRqV9Jj4+fMDgUDSY+K7isycOTPpMZS7GGj7CAdQEOWOyBzaEQy0idzT2NgYvTPV29ubtFU7fjq/VKb3e+mllyzp+JbnRDKZRjC+K1v8tIKUXxhoExG5YMqUKbZpInJOc3OzJdBONo1eJrMCeXVMfFcRdh3Jb1zWz0fcmE6soaEBra2ttvssXLgw+ri6uhrz588fcL5E+e6GG27ANddcE03feOONWSwNkb/NmDEDq1atsqSdNmTIEBw6dMiSTiaTO82cGtRf2KJNROSCqVOnYtiwYQCAYcOGobq6OsslIiocyWbdqqqqsqQnTpyY9JyxQXaitFM4g5i/sEWbbMW3Tt966614/vnno+lzzjkHN998s9fFIsp54XA42reyq6sLe/fuPW5gFBE5I9FMHQsWLOh3/y984QtYsmRJNH3llVcmzaOkpCS6ymMk7QaOt/IXtmhTWuIDb3YToXzkxRzXjY2N0ceqmtKUY0SUmfgVF5OtwPjwww9b0r/+9a+T5hEbZCdKOyWTqQcpd/HT85HS0lJL2o2VIQOBAEaMGAHAaM1mCx3lIy/m0W5ubo7+I+7p6Uk6OIuIMhffJ3vWrFm2+7e1tdmmnRK/2Ewqi8+ke9FAuY2Bto+ce+65tmmnVFVVoby8nK3ZlLe8WBWutrY22hJVVFTEf5ZELrrvvvss6YaGBtv9M6kDzj77bNt0IvFT9cWvSptI/GJXZ5xxRtJjKHcx0PYxt/p1lZaWoqamhq3ZlLe8GNVfV1cXPW9fXx/mzZvneB5EZEi3hTqTbiBz5861pC+++OKkx8T/H06lrrn77rst6R/+8IdJj6HcxUDbQ+FwGAsWLEi6YlWmOPcmUe547733LGm3bk0TUfrz1peXl9umE/nxj39sSd97770pli4977//viV9+PBhV/IhbzDQ9lBjYyM2bNjg2qCoTJZ6JSpElZWVtmkn3H777Zb0rbfe6ngeRGS44YYbLOlk89bHr7aYyuqLmaz2mkkfbfKXrATaIjJKRH4vIptEZKOInCUiY0TkGRF51/w9Omb/m0SkRUT+JiIXZqPMAxUOh9HU1ARVRVNTkyut2pks9UpUiMLhsG3aCQcPHrRN55tCrLeJBmrQoEGWdCqBNoNzf8lWi/bdAJ5W1f8H4BQAGwHcCGC1qp4IYLWZhoh8CMAVAD4M4BMAfiIizs/F5bLGxkZLf003WrW9mEmByA/Gjx9vm3bC0KFDbdN5qODqbcofS5cutaRj58hOZMKECZa0G3e1AGD//v2WdEdHR9Jjuru7bdOUXzxfsEZERgA4B8CXAEBVjwI4KiKXADjP3O0XAJ4D8G0AlwD4jap2AfiHiLQAOB3AS54WfIASTfV17bXXZrlURIUp/m6PG3d/ysrKLH0r41u28kmh1tuUP9IdDNne3m5J79692/Ey5ZKGhga0trZatm3evBkAsHDhQsv26upqzirmoGy0aFcDaAfwMxF5XUQeEJFyAONVdQcAmL/HmftXAdgac/w2c9txROTLIvKaiLwW/yXKttra2uj0QSUlJZzqiyiLvLj7E99ytW/fPsfz8JAr9XYu19mUX9IdDOnFzEOZil8Dw4k1MVpbW7FxUwt2tB+N/vRpGfq0zLJt46aW4wJyGphsLMFeAuCjAK5V1bUicjfM2439kATbEs5bp6r3A7gfAKZPn55Ta5bW1dWhqakJgDGnLqf6IsoedrNKmyv1di7X2X4XaeGMDPCrqjKug/K1NfOGG27ANddcE00nGwzp1SqPgwYNssylncqdrfhZR+LTmRoVmIzzPn2z7T7PPXabI3nRMdlo0d4GYJuqrjXTv4dRge8SkUoAMH/vjtl/UszxEwGEPCqrYwKBAObMmQMRwZw5c1yZg5rLthLlDp/10S7IersQHDlyJKUZN3Ld6NGjLelRo0bZ7u/FolXA8QvWxKcTERHbNB3P7emTB8LzFm1V3SkiW0Xkg6r6NwCzAbxj/lwJYIn5e7l5yGMAGkXkfwEEAZwI4BWvy+2Euro6tLW1udaancu3woiyKb5/4rBhwyyzgAwfPjzaT9GpFj0/fR8Lud72q8jfeOTvvr6+PpvFGbD4lSAbGhpw8839t95mEswWFxdb7n4VF7szvreiosLSZ7yiosKVfPwkdvrkXBv/lq0mz2sBLBOR9QA+AuB2GBX1x0XkXQAfN9NQ1bcBPAKjQn8awDWqmpf3eQOBAO644w6uqEiUZZMmTbKkJ06c6Hges2bNsqRTWa45xxVkvU354fnnn7ek16xZY7t/Jv2g47t9pNINJJNl2/fs2WObJisvpk8eiGz00YaqvgFgeoKnZvez/20A8r7jUDgcxuLFi7Fo0SIG20QeStRC/bnPfQ4HDx7EmWeeie9///uulyF+KeZ8U6j1NvnToUOHbNOJxK/QmMqKjXPnzrVcBNgt2x658xZ/9yvf6w63JZo+OZdatdmJ10NurwxJRKmbNGkSysvLcd1117ly/hdffNE2TUT+l8my7fH9y9244+YniaZPziUMtD0SDoexcuVKqCpWrlyZc7c2iApNaWkpampqXLu7FH/eQCDgSj5ElL5TTz3VNp1IJt1A0lm2ff78+aivr8dPfvKT6LaioqLjFuMhq1yfPpmBNrwZrdrY2Bhd3am7u9uVVm2OVCbKHfGL4IRCnHSDKFfEL1CTbB73hoaGhH2n4wdhOiEQCERbtWfPns2upknU1dVFZ1nLxemTs9JHO9d4MVp19erVx6WdzmvQoEGWaZryeSU6onznp1lHiPwmnZbmiNLSUhQVFaGvrw8jR45EaWmpW8VDZWUluru7cdVVV7mWRy6JnRkqdm73VGaBikyf/MQTT7g2ffJAFHygHT9add68ea58SGPGjLF8sd3II34uVD/MjUpERJSMiFgGDSa7oztlyhTLMu3JVpKMBHvXX389tmzZgp/+9KeuBnRud21LJtGS7YA3y7ZnEru4PX3yQBR8oO3VaNWdO3fapomIiHJNooDLi2ArXfFzT48bN67ffRsaGo5rjS4rK0NDQ0PS8qcbAFdUVFi6pdiVK5e0trZi06YWVIyJuwBRYxrE8O7u6Kb2vW0YqNj3PZO53SPTJ+eigg+0E41WzaVpYYiIiLKltbUVb21aj9KYsbw9ZsPxpvb10W3dYWfzTXc63HDYWoBkc08PHTo02go+aNAgDBkyZEDldapcuaRizBRcdtEtSff73ZO3elCa/FXwgXZtbS2efvpp9PT0uDpa9fzzz8eqVassaSLyr9GjR2Pfvn2WNFE+Kg0AYy+x74qxZ7mzcz2nO3Yqfq5pu7mnI62n11xzDVpbW3HXXXehurp6YAXuB8dqUMHPOuLVaNVLL73Ukv7c5z7nSj5ElBtig+xEaSJKLJOV/iorK23TiQwdOhTTpk1zJchuaGg4rmsNFaaCD7QDgQDOOeccAMC5557r2sCDp556ypJ+4oknXMmHiIgonyUaO5VMfBeN+DRRthR8oB3LzWVO41cqyrWVi4iIiHJBJiv9xXfNynZXrcjiM2eccYZl+5lnnpmlElG2pBRoi8jMVLblo3A4jDVr1gAA1qxZ49qiNR/84Adt00TkL/GzC3g524Cf62zyv0xW+otfICo+nS3XXXedbZr8L9UW7XtS3JZ3MrlFlYk333zTkl6/fn0/e2aurKzMNk1E3rn++ust6W9+85teZu/bOpv8L9dX+ktHIBDAsGHDABit2bm2mAq5z3bWERE5C8AMABUiEvtfYgSAYjcL5hWvpveLH2nc29vreB7x53QjDyJKzV/+8hdL+oUXXsCpp57qap6FUGeT/2Wy0l9xcbHlf15xce78uU+aNAlbtmxha3aBStaiXQZgGIyAfHjMTyeAf3G3aN6IvyXl1vR+RFRYsjQuw/d1NhWGuro6TJs2LeXW7FxuaMr2Ko+UXbYt2qr6ZwB/FpGfq+rAl/7JQdOmTcOKFSui6VNOOSWLpRmYiooKy4qT+bICFZEfzZgxwzJ3/syZ7neRLoQ6mwpDLq/0R5SOVPtoDxKR+0WkSUSaIz+ulswjP/rRjyzpH/7wh1kqycDFLvMKwLIcLRF5q6uryzbtMt/W2UREAxUOh7FgwQLXJsCIlerKkL8D8FMADwDInfsxDjh8+LBtOp+IiG2aiLzz4osvWtIvvPCCl9n7ts4mIhqodFceHYhUA+0eVW1wtSSUtoaGBrS2tkbTw4YNQ0dHhyUdWZmquro6uuwsEbkvy0svs86mvBYOh7F48WIsWrQopb7NImJZC4MNTdSf+JVH582b52r/+VS7jjwuIl8VkUoRGRP5ca1UPjRo0CDbtBMyWYKWiHyJdTbltdgWx1TELzjn5gJ0lN+8mtY5ItUW7SvN3wtjtimAameL4z2vroJHjhxp6TM9atSoAZ8zUQv15z//eXR0dODjH/84FixYMOA8iCgv+bbOJv8Lh8N46qmnoKp46qmnXG9xpMLi1bTOESkF2qr6AddKkGVeXQXHD0zctWuXK/lUVlaiu7sbV111lSvnJ6LE4rtyjRgxAp2dndH0yJEjPevK5ec6m/yvsbExOj1fb2+vJ/1oqXDU1tbi6aefRk9PT8orjw5ESoG2iHwx0XZV/aWzxfGvyspKy5KwbnXr4HydRLmhqqrKEmgHg0HP8madTfmsqanpuDQDbXJKXV1d9G/Mi5VHU+068rGYx4MBzAbwVwCstFMUuU0RkUuT6RPRwCVqob7sssvQ2dmJs88+G7fccouXxWGdTXmru7vbNk00EJmsPDoQqXYdsVxKishIAL9ypUQe82rZVs5xTVR4qqqq0Nvbi69+9aue5uvnOpv8jwMbyW11dXVoa2tzvTUbSH3WkXiHAZzoZEGy5fzzz7dNO4VzXBMVnhzqyuWbOpuIaKAiK496UTen2kf7cRgj1gGgGMA/AXjErUJ5qba21rJM8gUXXOBKPrNmzcLzzz8fTZ999tmu5ENE5Oc6myiRwYMH48iRI5Y0US5ItY/2HTGPewC0qeo2F8rjuR//+MeW9L333osHH3zQ8Xzmzp1rCbQvuugix/MgIjL5ts4mSqSrq8s2XehCoRD2dx7Cc4/dZrtfR7gN2l3u6eBtv0up64iq/hnAJgDDAYwGcNTNQnlp+/btlvS2be78L7rnnnss6bvvvtuVfIiI/FxnEyXCft2Uq1LtOnI5gHoAzwEQAPeIyEJV/b2LZfOEVwvWxE7tlyhNROQUP9fZRJS+YDAIKT2K8z59s+1+zz12GyoryjwqVWFIdTDkzQA+pqpXquoXAZwO4P9zr1jeKSoqsk0TEeUh39bZ5H/8v0zpCofDWLBgAfbu3Zvtohwn1b/eIlWNnY8unMaxOS1+Pmu35rcOBAKW9NixY13Jh4gIPq6zyf8+9rGPWdKnn356v/s2NDRg4cKFx92NdmuqXspNjY2N2LBhA5YtW5btohwn1Yr3aRFZKSJfEpEvAXgCwJPuFcs78SOThwwZ4ko+vEInIg/5ts4m/2tra7Ok33vvvbTPwT7ahSMcDqOpqQmqiqamppxr1baN9kRkqojMVNWFAO4DcDKAUwC8BOB+D8rnObe+nFywhojcVoh1NvnPzp07bdOx5s+fj/r6elx88cWW7ZzZq3A0Njair68PANDX15dzrdrJmlXvAnAAAFT1j6r6TVX9BoyWkbvcLZo3YufdTJQmIsojd8HndTZRInV1ddHHpaWlnqz4R7mhubkZPT09AICenh40NzdnuURWyQLtE1R1ffxGVX0NwAmulMhjXLGRiHzE93U2+V9paaltOpFAIBBd5e/CCy/MhdVYySO1tbUoKTEm0SspKUFtbW2WS2SVLNC2W1rJnc7MHuPcm0TkI76vs8n/uru7bdP9GT9+PMrLy9maXWDq6uqi496Kiopy7vNPFmi/KiL/Gb9RRK4GsM6dInmrqqrKkp44cWKWSkJENGC+r7OJ+lNaWoqamhq2ZheYQCCAOXPmQEQwZ86cnPv8ky1Ycz2AR0VkHo5V0tMBlAG41MVyeWbixImW1SEZaBNRHrsePq+zKX80NDSgtbU1+j820rBVXV2N+fPnZ7No5DN1dXVoa2vLudZsIEmgraq7AMwQkfMBTDM3P6GqudXTfABeffVVS/qVV15xJZ/BgwdbBlrGTytIRDRQhVBnU/7hJAPktkAggDvuuCPbxUgopSXYVfVZAM+6XJasiEwJ01/aKZzdhIi84uc6m/JHpNV64cKFAID6+vpsFocoK1IKtImIiIgo+yJdcmJt3rwZwLGLmohMu+mEQiF07j+M3z15a9J928Nt6OoZmnYehSJrgbaIFAN4DcB2Vf2kiIwB8FsYU1C9B+ByVd1n7nsTgKsB9AL4uqquzEqhiYgKFOtsotzQ2tqKDZvexaDApOi2o2pMgfhu+7G75V3hrZ6Wy4sLgHyUzRbt6wBsBDDCTN8IYLWqLhGRG830t0XkQwCuAPBhAEEAq0TkJFXtzUahiYgKFOtsohwxKDAJky+5wXafLcuXZnz+YDCIQSXduOyiW5Lu+7snb0VgXClaW1vx940tmDBqcvS5or4yAEDnjqPRbTs7tmRcrnyUlUBbRCYCuBjAbQC+aW6+BMB55uNfAHgOwLfN7b9R1S4A/xCRFgCnw1hSmIiIXMY6m7wkIpY1LbiQXP6YMGoy/mP2zbb7PLD6No9KkxuSzaPtlrsA3AAgduTheFXdAQDm73Hm9ioAsfc/tpnbjiMiXxaR10Tktfb2dscLTURUoO4C62zyCBeSIz/xvEVbRD4JYLeqrhOR81I5JMG2hN86Vb0fwP0AMH369JS+maeeeipef/31aPqjH/1oKoeljVfoRJSPcq3OJiICrH3CY+dqz7X+39noOjITwKdF5CIYywWPEJFfA9glIpWqukNEKgHsNvffBmBSzPETAYScKkwgELCk3VpRiFfoRJSncqrOJiKKl8tTJnvedURVb1LViap6AowBM82q+m8AHgNwpbnblQCWm48fA3CFiAwSkQ8AOBGAY6vKvPDCC7Zpp3CpdyLKR7lWZxMRAcY87fX19aivr0dNTQ1qampQX1+fU63ZQG7No70EwCMicjWALQAuAwBVfVtEHgHwDoAeANc4OXq9qKjINu2U+KXe4wNvIqI8k5U6m7wVCoXQ3QnsWW5/F7Y7DIS6nblxUVJSgp6eHkuaKF9l9a9XVZ+DMVIdqhoGMLuf/W6DMdrdcYcPH7ZNO+W1116zTRMR5bpcqLPJ3xoaGixBNgD09PSgoaEh51oqiVLBy0SPeLXUOxERkVOCwSA6S/dg7CX2A/j3LFcEK4KO5Dlo0CB0dXVZ0kT5ioG2R4qKitDb22tJExER0THz58/Hxz/+cVxzzTXRbXfddReqq6uzWCqizDHQdkn8UqTFxcWWQLu4uDi6JGmuTUVDRESULVOnTo22ak+ZMoVBNuW1gm9WHTdunG3aKYn6nBEREdHxJk2ahKKiItx4443ZLgrRgBR8i3ZxcbFtOlPxLdT33HMPVqxYEU1fdNFFuPbaax3Ji44Xf0ehP5s3bwaA6N0FO7zzQETkjaFDh2LatGlszaa8V/CB9o4dO2zTTqmrq8MTTzwBVUVZWRnmzZvnSj5kaG1txfpN7wCBYfY7ajcAYH37Fvv9wgcdKhkREREVioIPtL2arzMQCGD06NHYu3cv5syZ49oKlBQjMAwll0x35FQ9y/09HSPvABARETmv4ANtL/tOjx8/Hl1dXWzNppzT2tqKDZvexaDAJNv9jmopAODddvvlbrvCWx0rGxERUb4q+EDbS6WlpaipqWFrNuWkQYFJmHzJDY6ca8vypY6ch4iIyGnhcBiLFy/GokWLXI/JGGgT5Th26yAiInJOY2MjNmzYgGXLlrk+MQUDbaIMpRoAAwMLgo2BnX9DUcB+6sk+NVZu29C+z36/8O6kZSAiIvKjcDiMlStXQlXR1NSEefPmudqqXfCBdkVFBdrb26Npt+bRJv8xAuCNkEDyL6iqAgDeat9lv194b8LtRYFxGPTJf02/kAl0rXjYkfMQERHlm8bGRnR3GzOOHT161PVW7YIPtPfs2WNJxwbd5A4/dYWQwBiUfPJCx87Xs2KlY+fKRX767InyTaLvX3/fNX6vyK9Wr159XJqBtosiLY39pcl5ra2teGvTepQG7PfrMT+KTe3rbffrDjtUMHJda2srNm1qQcWYKfY7ahkAILy723a39r1tThWNyPdaW1vx9qb1GBZzE67brGfbdh+rZw8mvrFG5AtjxozB9u3bo+lAIEkwMkAFH2hTdpQGgLGXiCPn2rOcF0f5pGLMFFx20S2OnOt3T97qyHmICsWwMcApF9nv8+aT3pQl13lxB6C/u3x2+dDA7Ny505J2a6HCCAbaRERE5GvpBM2AEdAa43A2QQJjo9sjN73faj/W7VTDe+IPT5mRx99RHKi0bO/TYgDA2+0Hott6w+4GhIWgoaEBvb29lm29vb1oaGhwrasUA20iIiLytUSD1/sbpB47KF0CY1H6yUtsz929YvmAylYcqMTQT3056X6HH79/QPmQYdSoUejo6LCk3cRAm4iIiHwv1cHrfh+UXsjmz5+Pyy+/HHV1dQCAoqIiNDQ0cHo/IiIiIspdoVAIB/YfwgOrb7Pdb0dHGw5quUelOl4gEIi2as+ePZsrQxIRERHlg3QHUGYiFAqhq/MQtixfartfV3grQt3ZC2hTka0pJysrK9Hd3Y2rrrrKkfPZYaBNRERE5IBEK/kmWrXXjyv0BoNBdMpR/Mfsm233e2D1bRhRaUzh2trainffacGkEZOjz5f2GM8d2XY0um1r5xZHy1paWoqamhrXW7MBBtpERETkEC6Kk9pKvgNZoTcYDOJQ6RFMvuQG2/22LF+KYMXgjPPxyqQRk/GtM26y3efOtYs9Ko3zGGgTEVFOCofDWLx4MRYtWuRJyxMNnNGiuwEYGxvgGS2T6/e0HNu054i3BSPKkoILtFNZAjpy1e3Xq20ionzQ2NiIDRs2YNmyZa4ukUwOGzsYxZfY9z/uXW7/f5jILwou0Kb+pXIRAthP8p8IL1iIKF3hcBhNTU1QVTQ1NWHevHls1SaivFNwgXZ8wPfss89iyZIl0fTNN9+Mc845x+ti5YTW1lZs3LgeI0fb79fbZ/wO7Vyf9Jz79yXdhYjoOI2NjejrMyqbvr4+tmoTUV4quEA73vnnnx8NtEtKSgo2yI4YORo4Z45z51vT5Ny5iKhwNDc3o6enBwDQ09OD5uZmBtpElHeKsl2AXDBx4kQAwLe//e0sl4SIiACgtrYWJSVGW1BJSQlqa2uzXCIiovQx0AYwZswYnHzyyQXfmk1ElCvq6upQVGT8iyoqKsK8efOyXCIiovQVfNcRIiLKPYFAAHPmzMETTzyBOXPmcCAk0QB1hLfguceOLY9+cP8uAMCwkeMt+1RWTPW8bH7GQJuIfMWN2XM4c052zJ07F83Nzbj44ouzXRSivJZouffNncb85pUVZdFtlRVTUV1dnVIdWmhaWlqwcOFC3HnnnQnfz/4w0CYiX0m0pG8iiZb5TcTppX8pdU899RTef/99PPHEExwISRbprkBZ6BI1FETep/r6+n6fo2OWLl2Kw4cPY8mSJbj//vtTPo6BNhH5TipL+qYqn5f+zWecR5vsGCtQbgQCI49t1F4AwPr20LFt4f0el4z8qKWlBW1tbQCAtrY2tLa2pnwBx0CbiIhyDufRpqQCI1HyqXNtd+l5/M8eFYb8bOnSpZZ0Oq3anHWEiIhyTqJ5tImIsiHSmt1f2g4DbSIiyjmcR5uIckWkLuovbYeBNhER5RzOo01EuSJyd62/tB320SYiopzDebSJsqt9bxt+9+Stlm0dnTsBAKNGTLDsFxjHubf7w0CbiIhyUl1dHdra2tiaTQMWCoWgnfvRs2Jl0n01vBeh7l4Eg0FPytXbeRCHH08+sK43vAOh7gOelKu/GTU6DhjToQbGlUa3BcZ5O/d2ulM7DmQNhP7WZRCRlM/BQDtPcBEOIio0gUAAd9xxR7aLQQXKCM470b1iue1+Gt6DULf9fPz5pr/YwOm5t0OhEA51Hko6jerWzjaUh8oBGFM7trzzLiYPr4o+X9ZjhLNHtx6ObttyYHva5enPqFGj0NHREU1PnDgx5WMZaOeJ1tZW/G3jelSMst9PjNmwsHfHetv92jscKRYREVHOCwaDCJcWo+STFybdt2fFSgQrxiMUCiXd14ly7Ss9gKGf+nLSfQ8/fj+CFcNdL1M+mDy8Cjd9zH66z8Wv3jPgfCIXHOFwGHV1dQCMMSPx0/3ZYaCdRypGAZefX+zIuR55tteR8xAVIjfuMAG8yxQv0yWPKXtCoRDQeQS9y5N8P/YcQeioEch62RUgHUZwXobST15iu1/3iuUIVoz1pEx+EwwGcaTvaNIFxu5cuxiDg2W2+7gpEAhEW7Vnz56d1pgRzwNtEZkE4JcAJgDoA3C/qt4tImMA/BbACQDeA3C5qu4zj7kJwNUAegF8XVWTd7IiInKJcevyb5gcMyAokbIeY9aMo9uSr063xRxklIuyVW9nuuRxoYkEqtu3G7fKq6qMW+r5cuFmrPL4DhAYdmyjdgMA1rdvObYtfNDjkqUvFAqhr/MAulY8bLtfX3g3Qt3ve9LfmpxRWVmJ7u5uXHXVVWkdl40W7R4A31LVv4rIcADrROQZAF8CsFpVl4jIjQBuBPBtEfkQgCsAfBhAEMAqETlJVdkkS0RZM3nEBCw6898dO9/tL//MsXO5wPN6eyBLHheqI0eO2D4fCoVwcD/w5pP25zkYBkI9mXWbCAaD2FN2GMWX2H9WvctbERwbE2QGhqHkkum2x/Qsfy2jMvlRV3grtiw/1n3h6P7dAICykeMs+6DiRM/L5lelpaWoqalJewYkzwNtVd0BYIf5+ICIbARQBeASAOeZu/0CwHMAvm1u/42qdgH4h4i0ADgdwEvelpzyiXH78oBzFXP4AELd1n886YxiT1VktHt8Pqm0kKQq0pJClKps1NsDWfK40ERare0GqpE3gsEg9pbuw6BP/qvtfl0rHkawYnRGeSS64NzcadwBqKkYfGxjxYm8OM0BWe2jLSInADgVwFoA483KHKq6Q0Qil2VVAF6OOWybuY2IiDzmVb09kCWPKbFgMIjukj045SL7/d58EgiOY5eGXJWoOxAvsnJX1gJtERkG4A8ArlfVTps5CRM9of2c88sAvgwAkydPdqKYlKeCwSD2lPYkvRWZqp7lryFYYf3Hk84o9pTzMUe7x+eTSgtJqgbSkkKFzel6267OHjduHHbv3m1JExHlm6wswS4ipTAq62Wq+kdz8y4RqTSfrwQQqWG3AZgUc/hEAAk7j6nq/ao6XVWnV1RUuFN4IqIC5Ea9bVdnHzhwwJI+eDD3B8IREcXLxqwjAuBBABtV9X9jnnoMwJUAlpi/l8dsbxSR/4UxqOZEAK94V2JyWigUQncnsGd5whsTaesO47j+05SeUCiErs5DlsE1A9EV3opQd7kj56Lsy0a9/f771nEEhw8f7mdPIqLclY2uIzMBfAHAWyLyhrltEYyK+hERuRrAFgCXAYCqvi0ijwB4B8bI92s44wgRkadYbxMRZSAbs468gMT99wBgdj/H3AbgNtcKRZ4KBoPoLN2DsZf0278zLXuW63H9pyk9wWAQh0qPYPIlNzhyvi3LlyIYO/qd8hrrbco1xsxSHeh5/M/2O4Y7EOoG56umrMlKH20iIiI3tLS04NJLL01p5U4iIrdxCXYi8kwoFELn/sP43ZO3OnK+9nAbunqGOnIu8geuJlkYjJmlgJJPnWu7X8/jf+YdTw/t7NiCB1Yfu5EVPrgLABAYNt6yz4jKqRnnEQqFcOjAQSx+9R7b/doObEN5aFh05dRYmzdvBnBsWsQIN1ZTZaBNRES+wNUkibIn0XetffNRAMCIyrLothGVUz39Xra2tqLlnb9h8ogJ0W1lPUaHjqPb9ke3benc6Ur+DLQdkOhqKZH+rqASceOqiijbgsEgBpV047KLbnHkfL978lYExpU6ci7Kf1xNkih7vFpIJxgM4mjvYdz0sWtt91v86j0oCxp3PCePmIBFZ/677f63v/wzx8oYi4G2A1pbW/HuO+sxaUSx7X6lPX0AgCPb3rbdb2snB+cTUWETEaiqJZ0MV5MkolzDQNshk0YUY+FZzvQVrX+J88USUWGLDbITpRMZNmyYZWGbYcOGOV4uyl8a3oueFSuPpfcbiyLJyOHH7Ye4FXqJMsVAm4iIfKGnp8c2TR7ZcwS9y2O6U+43+uliZJllH4z1rkiJ+gRv7jQuymrig+qK8aiurkZrays0vAfdK5ZHn9L9Rp9eGTny2LbwHqDCwxdDeYWBNhER+cKsWbOwatUqS5q8lTCg3W+MT6oZW3Ns49jE+7olk/7DDQ0Nx23b3GkE2jWxgXXF2AG9lt7wDhx+3DqWoG9/GABQNDJg2Q8V1tZ3yn0MtInIV0KhEA51HsKdaxc7cr6tnW0oD3E5+Xxw4MABSzq2G4mdcDiMxYsXY9GiRRgzZowbRSsYmQS0xuIzB9Cz/DX7k4cPINQdGnAZU+XF4L7+AvTNnbsBADWxgXXFcM6ik4cYaBMRkS+88sorlvTatWtTOq6xsREbNmzAsmXLcO219jMZECXTF96NrhUPH0vv3wcAKBo52rIPKkb3O7uYG7N1UHYw0KaoUCiEjv3AmibnztmxD0Cfdy0QRMFgEEf6juJbZ9zkyPnuXLsYg4NlyXekrMtkAGU4HEZTUxNUFU1NTZg3bx5btT1mLD7Tg5JLptvu17P8tZxffCZxX/C9AICaimOBNipGs3W6QDDQJiKinJKob2xku9PrCzQ2NqKvz5h6ta+vj63aNCBezSVN+cPXgbYbC8kA/l1MJhgMAkV7cM4c5865pgkITsjtFggiyj1Dhw7F4cPHpjotL3enn3xzc3N0dpKenh40Nzcz0I7THQb2LD92d6DHXEyvZKR1H1R4Wy6iVBjjdg4kXZCmrXMnykOHHM/f14G2sezmRkweaX8bsKzXqECObt+V9Jxb9u91pGxERJTY/Pnzcfnll6Ouri667YEHHnClS8eMGTMsM5XMnDnT8TzyWeKuEOYsIhUxs4hUeDuLCPnH1s4tlsHruw8Zsdi48vGWfU7EVM/L5gRfB9oAMHnkGNxytnNNtLc+72AHZiIiSigQCERbtT/60Y+61m86fqaSzs5OV/LJVzndFSK8Hz2P//lYer85y8zIYZZ9kOP9ugtZoouz7s3GvOuDJx4bG3MipmZ8IRcMBnG0b39KS7CXBY3bNIl6RPTX+yFZuXwfaBMRUX6aMmUKtmzZknK3vkzEz0yS6kwl2ZZuIOC37o72Le0xgXVFkC3tOSxXL+SMHhGbMHnksf5QZb3G76Pbw9FtW/a3Jz0XA20iIspJpaWlqKmp4SwgCbS2tmLjxvWImTEOvcaYToR2ro9uM2eW851cDdDIPyaPrMDNMy6z3ee2v/wu6XkYaBMREeWhkaORdPC6k9O1ElH6GGjniVAohM79wCPP9jpyvt0dwBHl/NZEmUh1FHs63BrxTpQXwgetK0PuN2ecGTnUsg9nNqF8w0CbiIiIssa+v/XkYxs5swnlIQbaeSIYDGKw7MHl5xc7cr5Hnu3FmEqOxCbKRKqj2NMRO+KdqJCwvzX5GQNtIiIiIsobWw5sx+JX74mmdx02Zv8YP7TCss9UnOh52eIx0CYioryW6irATgmHw1i8eDEWLVrEGVGIPJao+9DRzcbqrmWTjvXpn4oTUV1d7WndkAgDbSIiojQ0NjZiw4YNWLZsGZdrJ/JYul2N3JyHPxUMtB1gzEDQi/qXDjtyvq2dvSgPcUYQIqJURP7xXnjhha7nFQ6H0dTUBFVFU1MT5s2bx1ZtIuoXA22iAdDwXvSsWJl8v/3GMs8ycnjS86FivCNlIyo0t99+OxYtWhRNL1myxPE8Ghsb0dtrTLPa29vLVm0iHwqFQji0vzPpgjRt+9tRLl22+zDQdkAwGMSRvn1YeNbQ5DunoP6lwxgc5IwgAxY/L2siieZq7edc8fO3pjPN1ObOgwCAmmRBdMV4Tl9FlKHTTjvNkj711FMdz6O5udkSaDc3N2cl0A6FQujYn3xBmo59APp4h5QK25bOnZZ1D3Yd2gsAGF8+xrLPVDg/8xMDbfKlVIPVhHO1JpJg/tZE/cT6w6mqiOy1t7cf15dy82bj+xm/vbq6ut/v3wknnID33nvPldZswAjmn3/++Wh6+vTpruRDRM5IPHhyDwCgbOKxwHoqRkb3DQaDOKqDUlqCvSwYsN3H14G20fS/H7c+79watG3796JcnFmdkdyTahCcLwFwX3g3ulY8bL/P/n0AgKKRo5OeCxX2+xB5raurCy3vbMTkkcdamMp6FQBwdPuu6LYt+/fanmfEiBE4+eSTXWnNBoB3333XNu2VYDAIFO1JaQn24ATeIaXCle152n0daBP5Qeqt80YAUpMsiK4Yze4plJMmjxyDW862jxydajjJdErAnTt3WtI7duxwpDxE5E++DrSNpv/ipBV3Om59vgllQQ5WG6juMLBnudru07Pf+F2SpMtUdxjH9Z/2E69a57vCW7Fl+VLbfY7u3w0AKBs5Lum5UJH9hQKI8k3sBcD27dsBAFVVVbbdZYgod/k60KbclH7/6Rr7HRP0n6b0pP6ZdAMAaioG2+9YcWK/52zf24bfPXmr7eEdnUar4agRE2z3a9/bhsC4qfZlIUrAyykBM3XkyBHHz3lwL/Dmk8fS73cav4eMsO4D+2tpIkoRA23ynN/6T/uBV59JqgF9x4GjAIDAuFLb/QLjpvIiiwbka1/7Gu69995o+rrrrstiaazfRafrwETflc0HjAaNKeNiGjTGsfGCaMv+dsv0frsOdQAAxpePsuwztaqAB0MSUW7hRRblmk996lOWQPuiiy7KYmncle1BYUT5IvFMJR0AgLKYwHpqVSDpRSkDbSLyna2dW3Dn2sW2++w+ZMxkMa7cfszF1s4tOBHsnuK27u5utO3fm3SwY+zMT4kGNGYyJWBlZSV27NiR9dZsIsoN6V6UfvWrX+33XAy0ichXUr3l3b3Z6J4yeGKZ7X4ngt1TclVrayta3nkHk0cOi24r6zXGERzdviW6bcv+g7bnqaioQEVFhaut2S0tLVi4cCHuvPNO/j0RFRAG2mSxf1/ylcYOGquJY5j9auLR8wXtx7MROYrdU/JTaWkppqQ4vV/szE+TRw7DorPtF425/fkkK8R64NZbb8Xhw4fxgx/8AD//+c+zXRwi8ggD7TzS3gE88qz9YjkdZsPNqGG2u6G9AxhTad2W8swTh4xbs8EJSWYDgRFks/WGiPygoaGh3+12F3gtLS3R+bZ37NiB1tZW1otEBYKBtkO2dvai/qXDtvvsPtQHABhXXpT0XPEzEKdaKe8z+yeOqbQPgsdUZr6kOFsCiYAtnTtx+8s/s91n1yFjEaHx5WNs94ucbyqSTBrvc1vi+mjvOmTcPhtfPtyyz9SqzNcycKpfdzpuvdU6nWWiVu10y0VE+cH3gXZ8xZ1Iosrc7nzxlXzqfUKNSnPwRPsg+MQE52QQTJQ7Uv3OH928BwBQNjF5AD0VIws6gBo0aBCmfuifLNuObjZu0ZXF1LlTq8YP6H1qbW3Fu++sx6QRxdFtpT1GI8iRbW9Ht23tPP7u4fz587Fhwwa0tLREt5100klJ6+f41SMTrSbZ2tqKTRvXY8yoY9vUKBZ271gf3ba349jz8V39EnXrY/c9ouzydaCd+j/D4yvz/iSq5BkEExUWfuedV1FRcdz7lOz9C4VCOLT/QNI+2G37D6BcQtH0pBHFWHjWUNtj+rtD+eMf/9iyyM0999xje55UhUIhxK+VOyJBF0A19501a9ZxzyXq1sfuezRQsXdbYu+ycLXS1Pg60OY/QyIiGohEXToiBg0aZOnWER942B2brF93MvkwJ3bk9cd3gWGAlj0DDZoHD06yKjAdJ28CbRH5BIC7ARQDeEBVl2S5SERE1A8v6uxgMIiWjg7Ltl2HjJbo8eXHWqwFgmAwCMBsBU9hTM3Wzl6Uh4xW8L9vXI8JIyX63HAz1ggMO4rO0FsAgJ3749uj038tJbIHF80W2/2eXK0YVxkcUF5e80Nwlu5Fg1etwAO5mEn1c8mkvH58vzKVF4G2iBQD+DGAjwPYBuBVEXlMVd/JbsmIiCieV3V24tXbjH+gZVWTo9umVln37eqx9sE+aj4sO9ZtG109QDnMLh1xMXRg2PHBsKqxL2AEJrt27bIt+zPPPINnnnkG48ePj85msrfDCKQjOs1ZpGK7kOztAMbFzRjlhUwCIT8FaBGZXDSkesxAXoubQfNA5Pv75YS8CLQBnA6gRVVbAUBEfgPgEgBpV9pejTj3Ip9cy8OrfPItD6/yycc8vMrHL3nkkQHV2akGW5HH/X3vEr3Ps2bNQmtrK0KhEN5//30AgJq/iwYNwZAhQ6Kt39XV1XjhhRdwtBfY0aHo6QX6EjRcFwnQF5Pu7OzEoUOHbF9j5PnOzs5oXgAs5TrSZfyWomPlGpdgxqhMWum8aAkdCC8CtHRee7rf14F+v3M1cE6VX94vJy7k8iXQrgKwNSa9DcAZTp3cqyubXK2ccjEPr/Lha8m9PLzKxy955ChH6mw3gq1Ewfn27dsBAFVVVQn/gUb2iw2CY0WC4EgAnCiYjw28y8vLjzsmk3Kl+9oHcoxXAZ2XAVqufT9zNWjOVfnQOg8AovH3xHKQiFwG4EJV/Q8z/QUAp6vqtXH7fRnAlwFg8uTJp7W1tXleViKigRKRdapqv9xhDmOdfbzvfve7ePnllzFz5kx85zvfyXZxiMhBdnV2vrRobwMwKSY9EUAofidVvR/A/QAwffr03L+CICLyJ9bZcb7//e9nuwhElAX2SxTmjlcBnCgiHxCRMgBXAHgsy2UiIqLEWGcTESFPWrRVtUdEvgZgJYypoh5S1beTHEZERFnAOpuIyJAXgTYAqOqTAJ7MdjmIiCg51tlERPnTdYSIiIiIKK8w0CYiIiIicgEDbSIiIiIiFzDQJiIiIiJyAQNtIiIiIiIXMNAmIiIiInIBA20iIiIiIheIqj9XvRWRdgBtaRwyFsAel4rjdT5+ycOrfPhaci8Pr/LJ1TymqGqFG4XJVTZ1dibvnxfHsFwsV64dw3Jlr1z919mqyh/jYuM1v+Tjlzz4Wgo3Dz+9Fq/eL7/+ZPL+eXEMy8Vy5doxLFdulotdR4iIiIiIXMBAm4iIiIjIBQy0j7nfR/n4JQ+v8uFryb08vMrHL3n4WSbvnxfHsFy5l0cmx+RquTI5huXKvTz8OxiSiIiIiCib2KJNREREROSCgg+0ReQhEdktIhtczGOSiDwrIhtF5G0Ruc6lfAaLyCsi8qaZz/fdyMfMq1hEXheRFS6d/z0ReUtE3hCR19zIw8xnlIj8XkQ2mZ/PWQ6f/4Pma4j8dIrI9U7mYebzDfMz3yAiD4vIYKfzMPO5zszjbadeR6LvoIiMEZFnRORd8/dol/K5zHwtfSIy3aU86s2/r/Ui8qiIjBpoPoVCRD4hIn8TkRYRuTGF/dOqzzOpmzOtZ9OtMzOpA9OtzzKpnzKpa1KpNzKpB9L9Tmfy/eznmP82939DRJpEJJjsmJjnFoiIisjYJHl8T0S2x3w2F6WSh4hca35n3haRpSm8lt/G5PGeiLyRZP+PiMjLkb9LETk9hTxOEZGXzL/nx0VkRMxzCb+Ddp+9zTF2n31/xyT8/G32t/3sE0p3mhK//QA4B8BHAWxwMY9KAB81Hw8H8HcAH3IhHwEwzHxcCmAtgDNdek3fBNAIYIVL538PwFgPPv9fAPgP83EZgFEu5lUMYCeM+TadPG8VgH8AGGKmHwHwJRfKPw3ABgBDAZQAWAXgRAfOe9x3EMBSADeaj28E8D8u5fNPAD4I4DkA013KYw6AEvPx/zjxWgrhx/y+bAZQbX4330xWb6Zbn2dSN2daz6ZbZ2ZSBw6kPkulfsqkrkm13sikHkj3O53J97OfY0bEPP46gJ+m8ncIYBKAlTDmix+bJI/vAViQzt86gPPN93eQmR6XzvcDwJ0AvpMkjyYAc83HFwF4LoVyvQrgXPPxVQD+O+a5hN9Bu8/e5hi7z76/YxJ+/jb72372iX4KvkVbVdcA2OtyHjtU9a/m4wMANsKosJzOR1X1oJksNX8c74QvIhMBXAzgAafP7SXzqvocAA8CgKoeVdUOF7OcDWCzqqazkFKqSgAMEZESGP/QQi7k8U8AXlbVw6raA+DPAC4d6En7+Q5eAiNogPn7M27ko6obVfVvAz13kjyazPcLAF4GMNGp/HzudAAtqtqqqkcB/AbG30W/0q3PM6mbM6lnvagzHajPUq2f0q1rUqo3MqkH0v1OZ/L97OeYzphkOeI+f5u/wx8CuCGN/fvVzzHzASxR1S5zn92p5iMiAuByAA8n2V8BRFqkRyLu8+/nmA8CWGM+fgbA52L27+872O9n398xST77/o5J+Pnb7G/72SdS8IG210TkBACnwmgFceP8xeatn90AnlFVN/K5C0Zl0efCuSMUQJOIrBORL7uURzWAdgA/E+OW7gMiUu5SXgBwBWIqMaeo6nYAdwDYAmAHgP2q2uR0PjBapc4RkYCIDIXRmjHJhXwAYLyq7gCMCg/AOJfy8dpVAJ7KdiHyRBWArTHpbXChgSIinbo5g3r2LqRfZ6ZbBw60PktaP2VY1wyk3vC6Hkj5+ykit4nIVgDzAHwnhf0/DWC7qr6ZRnm+ZnZTeEhS6z53EoCzRWStiPxZRD6WRl5nA9ilqu8m2e96APXma78DwE0pnHsDgE+bjy9DP59/3Hcwpc8+k5jK5piEn3/8/ul+9gy0PSQiwwD8AcD1cVdFjlHVXlX9CIyrstNFZJqT5xeRTwLYrarrnDxvAjNV9aMA5gK4RkTOcSGPEhi3uBpU9VQAh2DconKciJTBqGh+58K5R8O4+v8AgCCAchH5N6fzUdWNMG6tPQPgaRi38ntsD6IoEbkZxvu1LNtlyROSYJsr02SlWzenU88OoM5Mtw7MuD5LtX7KpK7Jl3oj3e+nqt6sqpPM/b+W5NxDAdyMFIKyGA0AagB8BMZFzZ0pHFMCYDSAMwEsBPCI2VKdin9Fag1B8wF8w3zt34B5ByWJq2D8Da+D0Q3jaPwOmcRHTh7T3+efaP90PnuAgbZnRKQUxoe1TFX/6HZ+5i3D5wB8wuFTzwTwaRF5D8at3FoR+bXDeUBVQ+bv3QAehXEb2WnbAGyLaY36PYx/VG6YC+CvqrrLhXNfAOAfqtquqt0A/ghghgv5QFUfVNWPquo5MG4PJmv9yNQuEakEAPP37iT75zQRuRLAJwHMU1XOqZqabbC2fE2EC12iBlI3p1jPZlRnZlAHDqQ+S7V+yqiuGUC94Uk9MMDvZyNiukL0owbGxcmb5t/BRAB/FZEJ/R2gqrvMC7o+AP+H1P4HbgPwR7N70ysw7qCMTXIMzG5AnwXw2xTyuBLG5w4YF2ZJy6Wqm1R1jqqeBiOY3xyXf6LvoO1nn8n3tr9j+vv8U8gjlc+egbYXzCvKBwFsVNX/dTGfipgRs0NgVIqbnMxDVW9S1YmqegKMW43Nqupo66mIlIvI8MhjGIMVHJ8VRlV3AtgqIh80N80G8I7T+ZhSbS3IxBYAZ4rIUPNvbTaM/mSOE5Fx5u/JMCpmt17TYzAqdJi/l7uUj+tE5BMAvg3g06p6ONvlySOvAjhRRD5gtrheAePvwjGZ1M3p1rOZ1JmZ1IEDrM9SrZ8yqmsGUG+4Xg9k8v0UkRNjkp9Gkv+zqvqWqo5T1RPMv4NtMAba7bTJozImeSlS+x/4JwC15vEnwRgQuyeF4y4AsElVt6WwbwjAuebjWqRw0RTz+RcBuAXAT2Oe6+872O9nn+H3NuEx/X3+Nvun9dkD4KwjML7wOwB0w/jjv9qFPGbBuOW5HsAb5s9FLuRzMoDXzXw2IGb0sEvv3XlwYdYRGH0N3zR/3gZws4uv4SMAXjPfsz8BGO1CHkMBhAGMdPF1fN/8wm8A8CuYo85dyOd5GP+83wQw26FzHvcdBBAAsBpGJb4awBiX8rnUfNwFYBeAlS7k0QKjr3Hku590lDp/ou/nRTBG+29OpR5Itz7PpG4eSD2bap2ZaR2YSX2Wbv2USV2TSr2RST2Q7nc6k+9nP8f8wXz96wE8DmOQXMp/h4ibUaafPH4F4C0zj8cAVKZQrjIAvzbL9lcAtamUC8DPAfxXip/JLADrzM9yLYDTUjjmOhjf478DWAIYiyXafQftPnubY+w++/6OSfj52+xv+9kn+uHKkERERERELmDXESIiIiIiFzDQJiIiIiJyAQNtIiIiIiIXMNAmIiIiInIBA20iIiIiIhcw0KaCIyIqIr+KSZeISLuIrMjwfKNE5Ksx6fMyPRcRUT4SkYNx6S+JyL0u5TVSRH4pIpvNn1+KyMiY5+tF5G0RqY/Z9u8i8ob5c1RE3jIfLxGR74nIggGU5zkR+ZsYy6VvEpF7I3OtEzHQpkJ0CMA0c7EJAPg4gO0DON8oAF9NthMREaVHRIoTbH4QQKuq1qhqDYB/AHgg5vmvwFgQZmFkg6r+TFU/oqofgbHoyvlmOqVl6lMwT1VPhjHPehfyeJEtchYDbSpUTwG42HxsWRVNRMaIyJ/M1omXReRkc/v3ROQhs/WiVUS+bh6yBECN2ToSaUEZJiK/N1s3lpmrTMFsPXnHPPcd3rxUIqLsEZEpIrLarPdWmytEQkR+LiL/ErPfQfP3eSLyrIg0wli0JfZcUwGcBuC/Yzb/AMB0EakRkccAlANYKyKfT6OYH0pQt0NE/k1EXjHr9/v6CfyjVPUogBsATBaRU8xz/ElE1pmt7F82t10tIj+Myec/RcS1laMpexhoU6H6DYArRGQwjBaItTHPfR/A62brxCIAv4x57v8BuBDA6QC+KyKlAG4EsNlsHYm0oJwK4HoAH4KxyttMERkDY+WqD5vnvtWtF0dE5LEhMV0z3oAR/EbcC+CXZr23DMCPUjjf6TBWxPxQ3PYPAXhDVXsjG8zHb8CoWz8N4H2zPv5tGuU/rm4XkX8C8HkAM82W8F4A85KdyCzPm+Y5AeAqVT0NwHQAXxeRAIz/QZ82/4cAwL8D+Fka5aU8UZLtAhBlg6quF5ETYLRmPxn39CwAnzP3axaRQEz/vydUtQtAl4jsBjC+nyxeUdVtAGD+0zkBwMsAjgB4QESeAMB+3ETkF++bwSgAo482jMASAM4C8Fnz8a8ALE3hfK+o6j8SbBcYS2Onuj1Vier22TBaz181b0oOAbA7xfNJzOOvi8il5uNJAE5U1ZdFpBnAJ0VkI4BSVX3ruLNQ3mOgTYXsMQB3ADgPQCBmuyTYN1KBd8Vs60X/36Hj9lPVHhE5HUblfQWArwGoTb/YRER5LVKf9sC8s252ryuL2edQP8e+DeBUESlS1T7z2CIApwDYOIAyJarbBcAvVPWmdE5kdi/5ZwAbReQ8ABcAOEtVD4vIcwAGm7s+AOOu6SawNdu32HWECtlDAH6QoBVhDczbg2YluUdVO23OcwDA8GSZicgwACNV9UkY3Uo+knaJiYjyz19gNC4ARt36gvn4PRgtxgBwCYBSJKGqLQBeB3BLzOZbAPzVfM5JqwH8i4iMA6Ljd6bYHWB2BVkMYKuqrgcwEsA+M8j+fwDOjOyrqmthtHDXIWacEPkLW7SpYJldO+5O8NT3APxMRNYDOAzgyiTnCYvIiyKyAcYgyyf62XU4gOVmv3AB8I1My05ElEe+DuAhEVkIoB1Gf2QA+D8YdeIrMILa/lqx410N4B4RaYFRl75kbnOUqr4jIrcAaDJbzbsBXAOgLcHuy0SkC8AgAKtgXDgAwNMA/sv8f/I3GF0IYz0C4COqus/p8lNuENWBdGkiIiIiokyIsebCD1V1dbbLQu5g1xEiIiIiD4mx0NnfYQwiZZDtY2zRJiIiIiJyAVu0iYiIiIhcwECbiIiIiMgFDLSJiIiIiFzAQJuIiIiIyAUMtImIiIiIXMBAm4iIiIjIBf8/uHd4q0kjC3gAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(nrows=1,ncols=2)\n", "fig.set_size_inches(12, 5)\n", "sns.boxplot(data=bikes.to_pandas(), y=\"cnt\",x=\"month\",orient=\"v\",ax=axes[0])\n", "sns.boxplot(data=bikes.to_pandas(), y=\"cnt\",x=\"hr\",orient=\"v\",ax=axes[1])\n", "axes[0].set(xlabel='Months', ylabel='Count',title=\"Box Plot On Count Across months\")\n", "axes[1].set(xlabel='Hour Of The Day', ylabel='Count',title=\"Box Plot On Count Across Hour Of The Day\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3.2.1 Combine weather data with bike rental data" ] }, { "cell_type": "code", "execution_count": 36, "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", " \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", " \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", "
cntdatehryearmonthHourTemperatureHumidityWindWeather
17376902012-12-31211122012-12-31 21:00:000.2448980.600.1930180
17377612012-12-31221122012-12-31 22:00:000.2448980.560.1578700
17378502012-12-31231122012-12-31 23:00:000.2448980.650.1578700
51841462011-08-0822082011-08-08 22:00:000.7551020.570.1228400
5185722011-08-0823082011-08-08 23:00:000.7346940.660.1228400
.................................
2331132011-04-121042011-04-12 01:00:000.6122450.500.1053253
2332142011-04-122042011-04-12 02:00:000.5918370.530.1578703
233312011-04-123042011-04-12 03:00:000.5714290.560.1578703
233462011-04-124042011-04-12 04:00:000.5510200.640.1578703
2335162011-04-125042011-04-12 05:00:000.5306120.680.1578703
\n", "

17378 rows × 10 columns

\n", "
" ], "text/plain": [ " cnt date hr year month Hour Temperature \\\n", "17376 90 2012-12-31 21 1 12 2012-12-31 21:00:00 0.244898 \n", "17377 61 2012-12-31 22 1 12 2012-12-31 22:00:00 0.244898 \n", "17378 50 2012-12-31 23 1 12 2012-12-31 23:00:00 0.244898 \n", "5184 146 2011-08-08 22 0 8 2011-08-08 22:00:00 0.755102 \n", "5185 72 2011-08-08 23 0 8 2011-08-08 23:00:00 0.734694 \n", "... ... ... .. ... ... ... ... \n", "2331 13 2011-04-12 1 0 4 2011-04-12 01:00:00 0.612245 \n", "2332 14 2011-04-12 2 0 4 2011-04-12 02:00:00 0.591837 \n", "2333 1 2011-04-12 3 0 4 2011-04-12 03:00:00 0.571429 \n", "2334 6 2011-04-12 4 0 4 2011-04-12 04:00:00 0.551020 \n", "2335 16 2011-04-12 5 0 4 2011-04-12 05:00:00 0.530612 \n", "\n", " Humidity Wind Weather \n", "17376 0.60 0.193018 0 \n", "17377 0.56 0.157870 0 \n", "17378 0.65 0.157870 0 \n", "5184 0.57 0.122840 0 \n", "5185 0.66 0.122840 0 \n", "... ... ... ... \n", "2331 0.50 0.105325 3 \n", "2332 0.53 0.157870 3 \n", "2333 0.56 0.157870 3 \n", "2334 0.64 0.157870 3 \n", "2335 0.68 0.157870 3 \n", "\n", "[17378 rows x 10 columns]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf_bw = bikes.merge(weather, left_index=True, right_on='Hour', how='inner')\n", "\n", "# inspect the merged table\n", "gdf_bw" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the data is not sorted after the merge use the [sort_values](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.core.dataframe.DataFrame.sort_values) method to" ] }, { "cell_type": "code", "execution_count": 37, "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", " \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", " \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", "
cntdatehryearmonthHourTemperatureHumidityWindWeather
0162011-01-010012011-01-01 00:00:000.2244900.810.0000000
1382011-01-011012011-01-01 01:00:000.2040820.800.0000000
2312011-01-012012011-01-01 02:00:000.2040820.800.0000000
3122011-01-013012011-01-01 03:00:000.2244900.750.0000000
412011-01-014012011-01-01 04:00:000.2244900.750.0000000
.................................
173741182012-12-31191122012-12-31 19:00:000.2448980.600.1930183
17375892012-12-31201122012-12-31 20:00:000.2448980.600.1930183
17376902012-12-31211122012-12-31 21:00:000.2448980.600.1930180
17377612012-12-31221122012-12-31 22:00:000.2448980.560.1578700
17378502012-12-31231122012-12-31 23:00:000.2448980.650.1578700
\n", "

17378 rows × 10 columns

\n", "
" ], "text/plain": [ " cnt date hr year month Hour Temperature \\\n", "0 16 2011-01-01 0 0 1 2011-01-01 00:00:00 0.224490 \n", "1 38 2011-01-01 1 0 1 2011-01-01 01:00:00 0.204082 \n", "2 31 2011-01-01 2 0 1 2011-01-01 02:00:00 0.204082 \n", "3 12 2011-01-01 3 0 1 2011-01-01 03:00:00 0.224490 \n", "4 1 2011-01-01 4 0 1 2011-01-01 04:00:00 0.224490 \n", "... ... ... .. ... ... ... ... \n", "17374 118 2012-12-31 19 1 12 2012-12-31 19:00:00 0.244898 \n", "17375 89 2012-12-31 20 1 12 2012-12-31 20:00:00 0.244898 \n", "17376 90 2012-12-31 21 1 12 2012-12-31 21:00:00 0.244898 \n", "17377 61 2012-12-31 22 1 12 2012-12-31 22:00:00 0.244898 \n", "17378 50 2012-12-31 23 1 12 2012-12-31 23:00:00 0.244898 \n", "\n", " Humidity Wind Weather \n", "0 0.81 0.000000 0 \n", "1 0.80 0.000000 0 \n", "2 0.80 0.000000 0 \n", "3 0.75 0.000000 0 \n", "4 0.75 0.000000 0 \n", "... ... ... ... \n", "17374 0.60 0.193018 3 \n", "17375 0.60 0.193018 3 \n", "17376 0.60 0.193018 0 \n", "17377 0.56 0.157870 0 \n", "17378 0.65 0.157870 0 \n", "\n", "[17378 rows x 10 columns]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### TODO sort the table according to the index (1 line of code)\n", "gdf_bw = gdf_bw.sort_values(by='Hour')\n", "\n", "# Inspect the sorted table\n", "gdf_bw" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.3 Add working day feature\n", "\n", "Apart from the weather, in important factor that influences people's daily activities is whether it is a working day or not. In this section we will create a working day feature. First we add the weekday as a new feature column. \n", "We can use the [weekday](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.core.series.DatetimeProperties.weekday) attribute of the [datetime](https://docs.rapids.ai/api/cudf/nightly/api.html#datetimeindex)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "gdf_bw['Weekday'] = gdf_bw['date'].dt.weekday" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next create a table with all the holidays in Washington DC in 2011-2011" ] }, { "cell_type": "code", "execution_count": 39, "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", " \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", "
dateDescription
02011-01-17Martin Luther King Jr. Day
12011-02-21Washington's Birthday
22011-04-15Emancipation Day
32011-05-30Memorial Day
42011-07-04Independence Day
52011-09-05Labor Day
62011-11-11Veterans Day
72011-11-24Thanksgiving
82011-12-26Christmas Day
92012-01-02New Year's Day
102012-01-16Martin Luther King Jr. Day
112012-02-20Washington's Birthday
122012-04-16Emancipation Day
132012-05-28Memorial Day
142012-07-04Independence Day
152012-09-03Labor Day
162012-11-12Veterans Day
172012-11-22Thanksgiving
182012-12-25Christmas Day
\n", "
" ], "text/plain": [ " date Description\n", "0 2011-01-17 Martin Luther King Jr. Day\n", "1 2011-02-21 Washington's Birthday\n", "2 2011-04-15 Emancipation Day\n", "3 2011-05-30 Memorial Day\n", "4 2011-07-04 Independence Day\n", "5 2011-09-05 Labor Day\n", "6 2011-11-11 Veterans Day\n", "7 2011-11-24 Thanksgiving\n", "8 2011-12-26 Christmas Day\n", "9 2012-01-02 New Year's Day\n", "10 2012-01-16 Martin Luther King Jr. Day\n", "11 2012-02-20 Washington's Birthday\n", "12 2012-04-16 Emancipation Day\n", "13 2012-05-28 Memorial Day\n", "14 2012-07-04 Independence Day\n", "15 2012-09-03 Labor Day\n", "16 2012-11-12 Veterans Day\n", "17 2012-11-22 Thanksgiving\n", "18 2012-12-25 Christmas Day" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "holidays = cudf.DataFrame({'date': ['2011-01-17', '2011-02-21', '2011-04-15', '2011-05-30', '2011-07-04', '2011-09-05', '2011-11-11', '2011-11-24', '2011-12-26', '2012-01-02', '2012-01-16', '2012-02-20', '2012-04-16', '2012-05-28', '2012-07-04', '2012-09-03', '2012-11-12', '2012-11-22', '2012-12-25'],\n", "'Description': [\"Martin Luther King Jr. Day\", \"Washington's Birthday\", \"Emancipation Day\", \"Memorial Day\", \"Independence Day\", \"Labor Day\", \"Veterans Day\", \"Thanksgiving\", \"Christmas Day\", \n", "\"New Year's Day\", \"Martin Luther King Jr. Day\", \"Washington's Birthday\", \"Emancipation Day\", \"Memorial Day\", \"Independence Day\", \"Labor Day\", \"Veterans Day\", \"Thanksgiving\", \"Christmas Day\"]})\n", "\n", "# Print the dataframe\n", "holidays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We convert the date from string to datetime type, and drop the description column. Additionally we add a new column marked 'Holiday'. This will be useful to mark the holidays after we merge the tables." ] }, { "cell_type": "code", "execution_count": 40, "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", " \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", "
dateHoliday
02011-01-171
12011-02-211
22011-04-151
32011-05-301
42011-07-041
52011-09-051
62011-11-111
72011-11-241
82011-12-261
92012-01-021
102012-01-161
112012-02-201
122012-04-161
132012-05-281
142012-07-041
152012-09-031
162012-11-121
172012-11-221
182012-12-251
\n", "
" ], "text/plain": [ " date Holiday\n", "0 2011-01-17 1\n", "1 2011-02-21 1\n", "2 2011-04-15 1\n", "3 2011-05-30 1\n", "4 2011-07-04 1\n", "5 2011-09-05 1\n", "6 2011-11-11 1\n", "7 2011-11-24 1\n", "8 2011-12-26 1\n", "9 2012-01-02 1\n", "10 2012-01-16 1\n", "11 2012-02-20 1\n", "12 2012-04-16 1\n", "13 2012-05-28 1\n", "14 2012-07-04 1\n", "15 2012-09-03 1\n", "16 2012-11-12 1\n", "17 2012-11-22 1\n", "18 2012-12-25 1" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "holidays['date'] = cudf.to_datetime(holidays['date'])\n", "holidays.drop(['Description'],axis=1,inplace=True)\n", "holidays['Holiday'] = 1\n", "holidays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we are ready to merge the tables using the commond `date` column. We want keep every element from the gdf_bw table (our *left* table), so we use a left join. Hint: use [merge](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.core.dataframe.DataFrame.merge) with the `on` and `how` attributes" ] }, { "cell_type": "code", "execution_count": 41, "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", " \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", " \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", " \n", "
cntdatehryearmonthHourTemperatureHumidityWindWeatherWeekdayHoliday
02972011-12-03160122011-12-03 16:00:000.3673470.460.00000005<NA>
12292011-12-03170122011-12-03 17:00:000.3469390.620.00000005<NA>
22202011-12-03180122011-12-03 18:00:000.3265310.530.15787005<NA>
31742011-12-03190122011-12-03 19:00:000.2857140.610.10532505<NA>
41242011-12-03200122011-12-03 20:00:000.2857140.610.10532505<NA>
.......................................
17373152011-12-25190122011-12-25 19:00:000.3061220.560.15787006<NA>
17374252011-12-25200122011-12-25 20:00:000.3061220.490.10532506<NA>
17375182011-12-25210122011-12-25 21:00:000.2857140.560.15787006<NA>
17376172011-12-25220122011-12-25 22:00:000.2653060.610.19301806<NA>
17377162011-12-25230122011-12-25 23:00:000.2448980.650.15787006<NA>
\n", "

17378 rows × 12 columns

\n", "
" ], "text/plain": [ " cnt date hr year month Hour Temperature \\\n", "0 297 2011-12-03 16 0 12 2011-12-03 16:00:00 0.367347 \n", "1 229 2011-12-03 17 0 12 2011-12-03 17:00:00 0.346939 \n", "2 220 2011-12-03 18 0 12 2011-12-03 18:00:00 0.326531 \n", "3 174 2011-12-03 19 0 12 2011-12-03 19:00:00 0.285714 \n", "4 124 2011-12-03 20 0 12 2011-12-03 20:00:00 0.285714 \n", "... ... ... .. ... ... ... ... \n", "17373 15 2011-12-25 19 0 12 2011-12-25 19:00:00 0.306122 \n", "17374 25 2011-12-25 20 0 12 2011-12-25 20:00:00 0.306122 \n", "17375 18 2011-12-25 21 0 12 2011-12-25 21:00:00 0.285714 \n", "17376 17 2011-12-25 22 0 12 2011-12-25 22:00:00 0.265306 \n", "17377 16 2011-12-25 23 0 12 2011-12-25 23:00:00 0.244898 \n", "\n", " Humidity Wind Weather Weekday Holiday \n", "0 0.46 0.000000 0 5 \n", "1 0.62 0.000000 0 5 \n", "2 0.53 0.157870 0 5 \n", "3 0.61 0.105325 0 5 \n", "4 0.61 0.105325 0 5 \n", "... ... ... ... ... ... \n", "17373 0.56 0.157870 0 6 \n", "17374 0.49 0.105325 0 6 \n", "17375 0.56 0.157870 0 6 \n", "17376 0.61 0.193018 0 6 \n", "17377 0.65 0.157870 0 6 \n", "\n", "[17378 rows x 12 columns]" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### TODO merge tables and on the column 'date', use a left merge \n", "gdf = gdf_bw.merge(holidays, on='date', how='left')\n", "\n", "# inspect the result\n", "gdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We reset the index to 'Hour' and sort the table accordingly. Notice that most of the rows in the 'Holiday' column are filled with ``, only the dates that appeared in the holiday table are filled with 1. We shall fill the empty fields with zero." ] }, { "cell_type": "code", "execution_count": 42, "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", " \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", " \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", " \n", " \n", " \n", "
cntdatehryearmonthTemperatureHumidityWindWeatherWeekdayHoliday
Hour
2011-01-01 00:00:00162011-01-010010.2244900.810.000000050
2011-01-01 01:00:00382011-01-011010.2040820.800.000000050
2011-01-01 02:00:00312011-01-012010.2040820.800.000000050
2011-01-01 03:00:00122011-01-013010.2244900.750.000000050
2011-01-01 04:00:0012011-01-014010.2244900.750.000000050
....................................
2012-12-31 19:00:001182012-12-31191120.2448980.600.193018300
2012-12-31 20:00:00892012-12-31201120.2448980.600.193018300
2012-12-31 21:00:00902012-12-31211120.2448980.600.193018000
2012-12-31 22:00:00612012-12-31221120.2448980.560.157870000
2012-12-31 23:00:00502012-12-31231120.2448980.650.157870000
\n", "

17378 rows × 11 columns

\n", "
" ], "text/plain": [ " cnt date hr year month Temperature Humidity \\\n", "Hour \n", "2011-01-01 00:00:00 16 2011-01-01 0 0 1 0.224490 0.81 \n", "2011-01-01 01:00:00 38 2011-01-01 1 0 1 0.204082 0.80 \n", "2011-01-01 02:00:00 31 2011-01-01 2 0 1 0.204082 0.80 \n", "2011-01-01 03:00:00 12 2011-01-01 3 0 1 0.224490 0.75 \n", "2011-01-01 04:00:00 1 2011-01-01 4 0 1 0.224490 0.75 \n", "... ... ... .. ... ... ... ... \n", "2012-12-31 19:00:00 118 2012-12-31 19 1 12 0.244898 0.60 \n", "2012-12-31 20:00:00 89 2012-12-31 20 1 12 0.244898 0.60 \n", "2012-12-31 21:00:00 90 2012-12-31 21 1 12 0.244898 0.60 \n", "2012-12-31 22:00:00 61 2012-12-31 22 1 12 0.244898 0.56 \n", "2012-12-31 23:00:00 50 2012-12-31 23 1 12 0.244898 0.65 \n", "\n", " Wind Weather Weekday Holiday \n", "Hour \n", "2011-01-01 00:00:00 0.000000 0 5 0 \n", "2011-01-01 01:00:00 0.000000 0 5 0 \n", "2011-01-01 02:00:00 0.000000 0 5 0 \n", "2011-01-01 03:00:00 0.000000 0 5 0 \n", "2011-01-01 04:00:00 0.000000 0 5 0 \n", "... ... ... ... ... \n", "2012-12-31 19:00:00 0.193018 3 0 0 \n", "2012-12-31 20:00:00 0.193018 3 0 0 \n", "2012-12-31 21:00:00 0.193018 0 0 0 \n", "2012-12-31 22:00:00 0.157870 0 0 0 \n", "2012-12-31 23:00:00 0.157870 0 0 0 \n", "\n", "[17378 rows x 11 columns]" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf = gdf.set_index('Hour')\n", "gdf = gdf.sort_index()\n", "\n", "### TODO fill empty holiday values with zero\n", "gdf['Holiday'] = gdf['Holiday'].fillna(0)\n", "gdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we create a workingday feature. Assuming that the first five days of the week are working days, one could do that simply with the following operation:\n", "```\n", "gdf['Workingday'] = (gdf['Weekday'] < 5) & (gdf['Holiday']!=1)\n", "```\n", "But we could do it with user defined functions too. Previously we have only used UDF to process elements of a series. Now we will process rows of a dataframe and\n", "combine the 'Weekday' and 'Holiday' columns to calculate the new feature 'Workingday'.\n", "\n", "More on user defined functions in our [blog](https://medium.com/rapids-ai/user-defined-functions-in-rapids-cudf-2d7c3fc2728d) and in the [documentation](https://docs.rapids.ai/api/cudf/nightly/guide-to-udfs.html)." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "def workday_kernel(Weekday, Holiday, Workingday):\n", " for i, (w, h) in enumerate(zip(Weekday, Holiday)):\n", " # variable w will take values from the Weekday column\n", " # variable h will take values from the Holiday column\n", " Workingday[i] = w < 5 and h != 1" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "gdf = gdf.apply_rows(workday_kernel, incols=['Weekday', 'Holiday'], outcols=dict(Workingday=np.float64), kwargs=dict())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After this step we will not need the 'Holiday' and 'date' columns, we can drop them" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "gdf = gdf.drop(['Holiday', 'date'],axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.4 One-hot encoding\n", "\n", "We have all now the data in a single table, but we still want to change their encoding. We're going to create one-hot encoded variables, also known as dummy variables, for each of the time variables as well as the weather situation.\n", "\n", "\n", "A summary from https://machinelearningmastery.com/why-one-hot-encode-data-in-machine-learning/:\n", "\n", "\"The integer values have a natural ordered relationship between each other and machine learning algorithms may be able to understand and harness this relationship.\n", "For categorical variables where no such ordinal relationship exists, the integer encoding is not enough.\n", "\n", "In fact, using this encoding and allowing the model to assume a natural ordering between categories may result in poor performance or unexpected results (predictions halfway between categories).\n", "\n", "In this case, a one-hot encoding can be applied to the integer representation. This is where the integer encoded variable is removed and a new binary variable is added for each unique integer value.\n", "\"\n", "\n", "We start by one-hot encoding the 'Weather' column using the [one_hot_encoding](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.core.dataframe.DataFrame.one_hot_encoding) method from cuDF DataFrame. This is very the [get_dummies](https://docs.rapids.ai/api/cudf/nightly/api.html#cudf.core.reshape.get_dummies) function (which might be more familiar for Pandas users), but one_hot_encoding works on a single input column and performs the operation in place. " ] }, { "cell_type": "code", "execution_count": 46, "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", " \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", "
cnthryearmonthTemperatureHumidityWindWeatherWeekdayWorkingdayWeather_dummy_0Weather_dummy_1Weather_dummy_2Weather_dummy_3
Hour
2011-01-01 00:00:00160010.2244900.810.0050.01.00.00.00.0
2011-01-01 01:00:00381010.2040820.800.0050.01.00.00.00.0
2011-01-01 02:00:00312010.2040820.800.0050.01.00.00.00.0
\n", "
" ], "text/plain": [ " cnt hr year month Temperature Humidity Wind \\\n", "Hour \n", "2011-01-01 00:00:00 16 0 0 1 0.224490 0.81 0.0 \n", "2011-01-01 01:00:00 38 1 0 1 0.204082 0.80 0.0 \n", "2011-01-01 02:00:00 31 2 0 1 0.204082 0.80 0.0 \n", "\n", " Weather Weekday Workingday Weather_dummy_0 \\\n", "Hour \n", "2011-01-01 00:00:00 0 5 0.0 1.0 \n", "2011-01-01 01:00:00 0 5 0.0 1.0 \n", "2011-01-01 02:00:00 0 5 0.0 1.0 \n", "\n", " Weather_dummy_1 Weather_dummy_2 Weather_dummy_3 \n", "Hour \n", "2011-01-01 00:00:00 0.0 0.0 0.0 \n", "2011-01-01 01:00:00 0.0 0.0 0.0 \n", "2011-01-01 02:00:00 0.0 0.0 0.0 " ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "codes = gdf['Weather'].unique()\n", "gdf = gdf.one_hot_encoding('Weather', 'Weather_dummy', codes)\n", "# Inspect the results\n", "gdf.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We're going to drop the original variable as well as one of the new dummy variables so we don't create colinearity (more about this problem [here](https://towardsdatascience.com/one-hot-encoding-multicollinearity-and-the-dummy-variable-trap-b5840be3c41a))." ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "gdf = gdf.drop(['Weather', 'Weather_dummy_1'],axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We create a copy of the dataset. It will make it easier to start over in case something would go wrong during the next excercise. " ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "gdf_backup = gdf.copy()" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "dummies_list = ['month', 'hr', 'Weekday']\n", "\n", "gdf = gdf_backup.copy()\n", "\n", "for item in dummies_list:\n", " ### Todo implement one-hot encoding for item\n", " codes = gdf[item].unique()\n", " gdf = gdf.one_hot_encoding(item, item + '_dummy', codes)\n", " gdf = gdf.drop('{}_dummy_1'.format(item),axis=1)\n", " gdf = gdf.drop(item,axis=1) # drop the original item" ] }, { "cell_type": "code", "execution_count": 50, "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", " \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", " \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", " \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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cntyearTemperatureHumidityWindWorkingdayWeather_dummy_0Weather_dummy_2Weather_dummy_3month_dummy_2...hr_dummy_20hr_dummy_21hr_dummy_22hr_dummy_23Weekday_dummy_0Weekday_dummy_2Weekday_dummy_3Weekday_dummy_4Weekday_dummy_5Weekday_dummy_6
Hour
2011-01-01 00:00:001600.2244900.810.0000000.01.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
2011-01-01 01:00:003800.2040820.800.0000000.01.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
2011-01-01 02:00:003100.2040820.800.0000000.01.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
2011-01-01 03:00:001200.2244900.750.0000000.01.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
2011-01-01 04:00:00100.2244900.750.0000000.01.00.00.00.0...0.00.00.00.00.00.00.00.01.00.0
..................................................................
2012-12-31 19:00:0011810.2448980.600.1930181.00.00.01.00.0...0.00.00.00.01.00.00.00.00.00.0
2012-12-31 20:00:008910.2448980.600.1930181.00.00.01.00.0...1.00.00.00.01.00.00.00.00.00.0
2012-12-31 21:00:009010.2448980.600.1930181.01.00.00.00.0...0.01.00.00.01.00.00.00.00.00.0
2012-12-31 22:00:006110.2448980.560.1578701.01.00.00.00.0...0.00.01.00.01.00.00.00.00.00.0
2012-12-31 23:00:005010.2448980.650.1578701.01.00.00.00.0...0.00.00.01.01.00.00.00.00.00.0
\n", "

17378 rows × 49 columns

\n", "
" ], "text/plain": [ " cnt year Temperature Humidity Wind Workingday \\\n", "Hour \n", "2011-01-01 00:00:00 16 0 0.224490 0.81 0.000000 0.0 \n", "2011-01-01 01:00:00 38 0 0.204082 0.80 0.000000 0.0 \n", "2011-01-01 02:00:00 31 0 0.204082 0.80 0.000000 0.0 \n", "2011-01-01 03:00:00 12 0 0.224490 0.75 0.000000 0.0 \n", "2011-01-01 04:00:00 1 0 0.224490 0.75 0.000000 0.0 \n", "... ... ... ... ... ... ... \n", "2012-12-31 19:00:00 118 1 0.244898 0.60 0.193018 1.0 \n", "2012-12-31 20:00:00 89 1 0.244898 0.60 0.193018 1.0 \n", "2012-12-31 21:00:00 90 1 0.244898 0.60 0.193018 1.0 \n", "2012-12-31 22:00:00 61 1 0.244898 0.56 0.157870 1.0 \n", "2012-12-31 23:00:00 50 1 0.244898 0.65 0.157870 1.0 \n", "\n", " Weather_dummy_0 Weather_dummy_2 Weather_dummy_3 \\\n", "Hour \n", "2011-01-01 00:00:00 1.0 0.0 0.0 \n", "2011-01-01 01:00:00 1.0 0.0 0.0 \n", "2011-01-01 02:00:00 1.0 0.0 0.0 \n", "2011-01-01 03:00:00 1.0 0.0 0.0 \n", "2011-01-01 04:00:00 1.0 0.0 0.0 \n", "... ... ... ... \n", "2012-12-31 19:00:00 0.0 0.0 1.0 \n", "2012-12-31 20:00:00 0.0 0.0 1.0 \n", "2012-12-31 21:00:00 1.0 0.0 0.0 \n", "2012-12-31 22:00:00 1.0 0.0 0.0 \n", "2012-12-31 23:00:00 1.0 0.0 0.0 \n", "\n", " month_dummy_2 ... hr_dummy_20 hr_dummy_21 \\\n", "Hour ... \n", "2011-01-01 00:00:00 0.0 ... 0.0 0.0 \n", "2011-01-01 01:00:00 0.0 ... 0.0 0.0 \n", "2011-01-01 02:00:00 0.0 ... 0.0 0.0 \n", "2011-01-01 03:00:00 0.0 ... 0.0 0.0 \n", "2011-01-01 04:00:00 0.0 ... 0.0 0.0 \n", "... ... ... ... ... \n", "2012-12-31 19:00:00 0.0 ... 0.0 0.0 \n", "2012-12-31 20:00:00 0.0 ... 1.0 0.0 \n", "2012-12-31 21:00:00 0.0 ... 0.0 1.0 \n", "2012-12-31 22:00:00 0.0 ... 0.0 0.0 \n", "2012-12-31 23:00:00 0.0 ... 0.0 0.0 \n", "\n", " hr_dummy_22 hr_dummy_23 Weekday_dummy_0 \\\n", "Hour \n", "2011-01-01 00:00:00 0.0 0.0 0.0 \n", "2011-01-01 01:00:00 0.0 0.0 0.0 \n", "2011-01-01 02:00:00 0.0 0.0 0.0 \n", "2011-01-01 03:00:00 0.0 0.0 0.0 \n", "2011-01-01 04:00:00 0.0 0.0 0.0 \n", "... ... ... ... \n", "2012-12-31 19:00:00 0.0 0.0 1.0 \n", "2012-12-31 20:00:00 0.0 0.0 1.0 \n", "2012-12-31 21:00:00 0.0 0.0 1.0 \n", "2012-12-31 22:00:00 1.0 0.0 1.0 \n", "2012-12-31 23:00:00 0.0 1.0 1.0 \n", "\n", " Weekday_dummy_2 Weekday_dummy_3 Weekday_dummy_4 \\\n", "Hour \n", "2011-01-01 00:00:00 0.0 0.0 0.0 \n", "2011-01-01 01:00:00 0.0 0.0 0.0 \n", "2011-01-01 02:00:00 0.0 0.0 0.0 \n", "2011-01-01 03:00:00 0.0 0.0 0.0 \n", "2011-01-01 04:00:00 0.0 0.0 0.0 \n", "... ... ... ... \n", "2012-12-31 19:00:00 0.0 0.0 0.0 \n", "2012-12-31 20:00:00 0.0 0.0 0.0 \n", "2012-12-31 21:00:00 0.0 0.0 0.0 \n", "2012-12-31 22:00:00 0.0 0.0 0.0 \n", "2012-12-31 23:00:00 0.0 0.0 0.0 \n", "\n", " Weekday_dummy_5 Weekday_dummy_6 \n", "Hour \n", "2011-01-01 00:00:00 1.0 0.0 \n", "2011-01-01 01:00:00 1.0 0.0 \n", "2011-01-01 02:00:00 1.0 0.0 \n", "2011-01-01 03:00:00 1.0 0.0 \n", "2011-01-01 04:00:00 1.0 0.0 \n", "... ... ... \n", "2012-12-31 19:00:00 0.0 0.0 \n", "2012-12-31 20:00:00 0.0 0.0 \n", "2012-12-31 21:00:00 0.0 0.0 \n", "2012-12-31 22:00:00 0.0 0.0 \n", "2012-12-31 23:00:00 0.0 0.0 \n", "\n", "[17378 rows x 49 columns]" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.5 Save the prepared dataset" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "gdf.to_csv('../../../data/bike_sharing.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Predict bike rentals with cuML\n", "\n", "cuML is a GPU accelerated machine learning library. cuML's Python API mirrors the [Scikit-Learn](https://scikit-learn.org/stable/) API.\n", "\n", "cuML currently requires all data be of the same type, so this loop converts all values into floats" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "import cuml" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "for col in gdf.columns:\n", " gdf[col] = gdf[col].astype('float64')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.1 Prepare training and test data\n", "It is customary to denote the input feature matrix with X, and the target that we want to predict with y. We separete the target column 'cnt' from the rest of the table." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "y = gdf['cnt']\n", "X = gdf.drop('cnt',axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's split the data randomly into a train and a test set" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = cuml.preprocessing.model_selection.train_test_split(X, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2 Linear regression\n", "Our first model is a simple linear regression, which tries to predict the output as a linear combination of the input features:\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "LinearRegression(algorithm='eig', fit_intercept=True, normalize=False, handle=, verbose=4, output_type='cudf')" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reg = cuml.LinearRegression()\n", "reg.fit(X_train, y_train)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can make prediction with the trained data" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "y_hat = reg.predict(X_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can visualize the how well the model works. Let's plot data for may 2012:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "import datetime as dt\n", "def plot_timerange(model, start, end):\n", " start_date = dt.datetime.strptime(start, '%Y-%m-%d')\n", " end_date = dt.datetime.strptime(end, '%Y-%m-%d')\n", " idx = (X.index >= start_date) & (X.index <= end_date)\n", " X_may = X[idx]\n", " y_may = y[idx]\n", "\n", " ### TODO predict the values for X_may (1 line of code)\n", " y_pred = reg.predict(X_may)\n", "\n", " plt.plot(X_may.index.to_array(), y_may.to_array())\n", " plt.plot(X_may.index.to_array(), y_pred.to_array(), '--')" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timerange(reg, '2011-06-01', '2011-06-05')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often we are interested in a single score. The default score method for regression problems is the [r2_score](https://en.wikipedia.org/wiki/Coefficient_of_determination)." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train score 0.6813958127305259\n", "test score 0.6820591407880712\n" ] } ], "source": [ "train_score = reg.score(X_train, y_train)\n", "### TODO calculate test score (the score on X_test, ~ 1 line of code)\n", "test_score = reg.score(X_test, y_test)\n", "\n", "print('train score', train_score)\n", "print('test score', test_score)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.3 Save and load the trained model\n", "We can pickle any cuML model" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [], "source": [ "import pickle\n", "pickle_file = 'my_model.pickle'\n", "\n", "with open(pickle_file, 'wb') as pf:\n", " pickle.dump(reg, pf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load the saved model" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loaded model score 0.6820591407880712\n", "Original model score 0.6820591407880712\n" ] } ], "source": [ "with open(pickle_file, 'rb') as pf:\n", " loaded_model = pickle.load(pf)\n", "\n", "print('Loaded model score', loaded_model.score(X_test, y_test))\n", "print('Original model score', reg.score(X_test, y_test))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.4 Ridge regression with hyperparameter tuning\n", "Ridge regression is a linear regression model with an added L2 regularization term. Regularization is often used in practice to avoid overfitting. The strength of the regularization is set by the alpha hyperparameter. \n", "We're going to do a small hyperparameter search for alpha, checking 100 different values. This is fast to do with RAPIDS. Also notice that we are appending the results of each Ridge model onto the dictionary containing our earlier results, so we can more easily see which model is the best at the end. " ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [], "source": [ "output = {'score_OLS': test_score}\n", "\n", "for alpha in np.arange(0.01, 1, 0.01): #alpha value has to be positive \n", " ridge = cuml.Ridge(alpha=alpha, fit_intercept=True)\n", " ### TODO fit the model and calculate the test score (2 lines of code)\n", " ridge.fit(X_train, y_train)\n", " score = ridge.score(X_test, y_test)\n", " ### END EXCERCISE ###\n", " output['score_RIDGE_{}'.format(alpha)] = score" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we see that our regulaized model does better than the rest, include OLS with all the variables. " ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Max score: score_RIDGE_0.33\n" ] } ], "source": [ "print('Max score: {}'.format(max(output, key=output.get)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.5 Additional cuML models (Optional)\n", "#### 3.5.1 Support vector regression\n", "\n", "Support vector regression is a more complex model, with an execution time that scales with at least O(n_rows^2). RAPIDS cuML includes a fast SVM solver that makes it feasable to run SVM on larger datasets." ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 276 ms, sys: 160 ms, total: 437 ms\n", "Wall time: 436 ms\n" ] }, { "data": { "text/plain": [ "0.8799074097909845" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "reg = cuml.svm.SVR(kernel='rbf', gamma=0.1, C=100, epsilon=0.1)\n", "## Todo\n", "reg.fit(X_train, y_train)\n", "reg.score(X_train, y_train)\n", "reg.score(X_test, y_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use sklearns [GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html) to perform hyperparameter search. Sklearn's GridSearchCV requires input that the input data is a host array. Fortunately cuML is flexible with the [input format](https://medium.com/rapids-ai/input-and-output-configurability-in-rapids-cuml-e719d72c135b), and we can pass numpy array directly to it (at a cost of additional host to device copies, because under the hood cuML copies the data to the GPU). If the data size is reasonably small, then we can pay the price of additional data movement and combine the convenience of GridSearchCV with the speed of cuML algorithms." ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "param_grid = [ {'C': [0.01, 0.1, 1, 10, 100], 'gamma': [10, 1, 0.1, 0.01, 0.001], 'kernel': ['rbf']} ]" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [], "source": [ "X_train_np = X_train.as_matrix()\n", "y_train_np = y_train.to_array()\n", "X_test_np = X_test.as_matrix() \n", "y_test_np = y_test.to_array()" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Best parameters set found on development set:\n", "\n", "{'C': 100, 'gamma': 0.1, 'kernel': 'rbf'}\n", "\n", "Grid scores on development set:\n", "\n", "-0.067 (+/-0.011) for {'C': 0.01, 'gamma': 10, 'kernel': 'rbf'}\n", "-0.066 (+/-0.011) for {'C': 0.01, 'gamma': 1, 'kernel': 'rbf'}\n", "-0.061 (+/-0.011) for {'C': 0.01, 'gamma': 0.1, 'kernel': 'rbf'}\n", "-0.066 (+/-0.011) for {'C': 0.01, 'gamma': 0.01, 'kernel': 'rbf'}\n", "-0.067 (+/-0.011) for {'C': 0.01, 'gamma': 0.001, 'kernel': 'rbf'}\n", "-0.067 (+/-0.011) for {'C': 0.1, 'gamma': 10, 'kernel': 'rbf'}\n", "-0.060 (+/-0.011) for {'C': 0.1, 'gamma': 1, 'kernel': 'rbf'}\n", "-0.012 (+/-0.011) for {'C': 0.1, 'gamma': 0.1, 'kernel': 'rbf'}\n", "-0.057 (+/-0.011) for {'C': 0.1, 'gamma': 0.01, 'kernel': 'rbf'}\n", "-0.066 (+/-0.011) for {'C': 0.1, 'gamma': 0.001, 'kernel': 'rbf'}\n", "-0.063 (+/-0.011) for {'C': 1, 'gamma': 10, 'kernel': 'rbf'}\n", "0.001 (+/-0.011) for {'C': 1, 'gamma': 1, 'kernel': 'rbf'}\n", "0.273 (+/-0.014) for {'C': 1, 'gamma': 0.1, 'kernel': 'rbf'}\n", "0.023 (+/-0.009) for {'C': 1, 'gamma': 0.01, 'kernel': 'rbf'}\n", "-0.056 (+/-0.011) for {'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}\n", "-0.025 (+/-0.012) for {'C': 10, 'gamma': 10, 'kernel': 'rbf'}\n", "0.377 (+/-0.017) for {'C': 10, 'gamma': 1, 'kernel': 'rbf'}\n", "0.669 (+/-0.013) for {'C': 10, 'gamma': 0.1, 'kernel': 'rbf'}\n", "0.366 (+/-0.017) for {'C': 10, 'gamma': 0.01, 'kernel': 'rbf'}\n", "0.028 (+/-0.009) for {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}\n", "0.248 (+/-0.022) for {'C': 100, 'gamma': 10, 'kernel': 'rbf'}\n", "0.831 (+/-0.024) for {'C': 100, 'gamma': 1, 'kernel': 'rbf'}\n", "0.876 (+/-0.011) for {'C': 100, 'gamma': 0.1, 'kernel': 'rbf'}\n", "0.633 (+/-0.013) for {'C': 100, 'gamma': 0.01, 'kernel': 'rbf'}\n", "0.373 (+/-0.017) for {'C': 100, 'gamma': 0.001, 'kernel': 'rbf'}\n", "\n" ] } ], "source": [ "from sklearn.model_selection import GridSearchCV\n", "reg = GridSearchCV(cuml.svm.SVR(), param_grid, scoring='r2' )\n", "\n", "reg.fit(X_train_np, y_train_np)\n", "\n", "print(\"Best parameters set found on development set:\")\n", "print()\n", "print(reg.best_params_)\n", "print()\n", "print(\"Grid scores on development set:\")\n", "print()\n", "means = reg.cv_results_['mean_test_score']\n", "stds = reg.cv_results_['std_test_score']\n", "for mean, std, params in zip(means, stds, reg.cv_results_['params']):\n", " print(\"%0.3f (+/-%0.03f) for %r\" % (mean, std * 2, params))\n", "print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3.5.2 KNN Regression\n", "k-Nearest Neighbors regression is a machine learning technique that predicts an unknown observation by using the k most similar known observations in the training dataset." ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 60.3 ms, sys: 261 ms, total: 321 ms\n", "Wall time: 320 ms\n" ] }, { "data": { "text/plain": [ "0.7120309195645623" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "### TODO tune the n_neighbors hyperparameter to achieve better performance\n", "knn = cuml.neighbors.KNeighborsRegressor(n_neighbors=8)\n", "knn.fit(X_train, y_train, convert_dtype=True)\n", "pred = knn.predict(X_test)\n", "knn.score(X_test, y_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can compare the execution time of training KNN with cuML and with scikit-learn" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [], "source": [ "import sklearn\n", "import sklearn.neighbors" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 5.83 s, sys: 0 ns, total: 5.83 s\n", "Wall time: 5.83 s\n" ] }, { "data": { "text/plain": [ "0.7119398662494515" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "knn = sklearn.neighbors.KNeighborsRegressor(n_neighbors=8)\n", "knn.fit(X_train_np, y_train_np,)\n", "pred = knn.predict(X_test_np)\n", "knn.score(X_test_np, y_test_np)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.6 XGBoost (Optional)\n", "RAPIDS integrates seamlessly with the XGBoost library. Here is how to use it for our example" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [], "source": [ "import xgboost as xgb" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [], "source": [ "xgr=xgb.XGBRegressor(max_depth=8,min_child_weight=6,gamma=0.4)\n", "dtrain = xgb.DMatrix(X_train, label=y_train)\n", "dtest = xgb.DMatrix(X_test, label=y_test)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'tree_method': 'gpu_hist', 'objective': 'reg:squarederror'}\n" ] } ], "source": [ "# instantiate params\n", "params = {}\n", "\n", "# general params\n", "general_params = {}\n", "params.update(general_params)\n", "\n", "# booster params\n", "booster_params = {'tree_method': 'gpu_hist'}\n", "params.update(booster_params)\n", "\n", "# learning task params\n", "learning_task_params = {'objective': 'reg:squarederror'}\n", "params.update(learning_task_params)\n", "print(params)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": [ "evallist = [(dtest, 'test'), (dtrain, 'train')]\n", "num_round = 100" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0]\ttest-rmse:199.18784\ttrain-rmse:200.30351\n", "[1]\ttest-rmse:162.09444\ttrain-rmse:162.71335\n", "[2]\ttest-rmse:137.25905\ttrain-rmse:136.83050\n", "[3]\ttest-rmse:120.35908\ttrain-rmse:119.77563\n", "[4]\ttest-rmse:107.99054\ttrain-rmse:107.15930\n", "[5]\ttest-rmse:100.17688\ttrain-rmse:99.31792\n", "[6]\ttest-rmse:94.51825\ttrain-rmse:93.23972\n", "[7]\ttest-rmse:90.02152\ttrain-rmse:88.41567\n", "[8]\ttest-rmse:87.24374\ttrain-rmse:85.44088\n", "[9]\ttest-rmse:84.38741\ttrain-rmse:82.57428\n", "[10]\ttest-rmse:81.15561\ttrain-rmse:78.72398\n", "[11]\ttest-rmse:78.11271\ttrain-rmse:74.94260\n", "[12]\ttest-rmse:76.49943\ttrain-rmse:72.95665\n", "[13]\ttest-rmse:74.66074\ttrain-rmse:70.91374\n", "[14]\ttest-rmse:72.05053\ttrain-rmse:67.98150\n", "[15]\ttest-rmse:70.95134\ttrain-rmse:66.81727\n", "[16]\ttest-rmse:70.03428\ttrain-rmse:65.69633\n", "[17]\ttest-rmse:67.92854\ttrain-rmse:63.02364\n", "[18]\ttest-rmse:67.05556\ttrain-rmse:61.93159\n", "[19]\ttest-rmse:65.70933\ttrain-rmse:60.53908\n", "[20]\ttest-rmse:65.15248\ttrain-rmse:59.73316\n", "[21]\ttest-rmse:64.53308\ttrain-rmse:58.98966\n", "[22]\ttest-rmse:63.51178\ttrain-rmse:57.82574\n", "[23]\ttest-rmse:62.71511\ttrain-rmse:56.73420\n", "[24]\ttest-rmse:62.33528\ttrain-rmse:56.03647\n", "[25]\ttest-rmse:61.82107\ttrain-rmse:55.35518\n", "[26]\ttest-rmse:61.35674\ttrain-rmse:54.68117\n", "[27]\ttest-rmse:61.01687\ttrain-rmse:54.21539\n", "[28]\ttest-rmse:60.57789\ttrain-rmse:53.62215\n", "[29]\ttest-rmse:59.97852\ttrain-rmse:52.79226\n", "[30]\ttest-rmse:59.75838\ttrain-rmse:52.38144\n", "[31]\ttest-rmse:59.33269\ttrain-rmse:51.76035\n", "[32]\ttest-rmse:59.00826\ttrain-rmse:51.20699\n", "[33]\ttest-rmse:58.75043\ttrain-rmse:50.73730\n", "[34]\ttest-rmse:58.22901\ttrain-rmse:49.93842\n", "[35]\ttest-rmse:57.82102\ttrain-rmse:49.37877\n", "[36]\ttest-rmse:57.50741\ttrain-rmse:48.89431\n", "[37]\ttest-rmse:57.35290\ttrain-rmse:48.60536\n", "[38]\ttest-rmse:57.03769\ttrain-rmse:48.08765\n", "[39]\ttest-rmse:56.89780\ttrain-rmse:47.75967\n", "[40]\ttest-rmse:56.47898\ttrain-rmse:47.12102\n", "[41]\ttest-rmse:56.33428\ttrain-rmse:46.83911\n", "[42]\ttest-rmse:56.12777\ttrain-rmse:46.53151\n", "[43]\ttest-rmse:55.93485\ttrain-rmse:46.22023\n", "[44]\ttest-rmse:55.77229\ttrain-rmse:45.91986\n", "[45]\ttest-rmse:55.61733\ttrain-rmse:45.64424\n", "[46]\ttest-rmse:55.41594\ttrain-rmse:45.24457\n", "[47]\ttest-rmse:55.28618\ttrain-rmse:45.01399\n", "[48]\ttest-rmse:55.17868\ttrain-rmse:44.72273\n", "[49]\ttest-rmse:55.03380\ttrain-rmse:44.47870\n", "[50]\ttest-rmse:54.97081\ttrain-rmse:44.23529\n", "[51]\ttest-rmse:54.90307\ttrain-rmse:44.03345\n", "[52]\ttest-rmse:54.76747\ttrain-rmse:43.59862\n", "[53]\ttest-rmse:54.72055\ttrain-rmse:43.33952\n", "[54]\ttest-rmse:54.64332\ttrain-rmse:43.20725\n", "[55]\ttest-rmse:54.60225\ttrain-rmse:43.05660\n", "[56]\ttest-rmse:54.43866\ttrain-rmse:42.85313\n", "[57]\ttest-rmse:54.35900\ttrain-rmse:42.68765\n", "[58]\ttest-rmse:54.27787\ttrain-rmse:42.53922\n", "[59]\ttest-rmse:54.06460\ttrain-rmse:42.21499\n", "[60]\ttest-rmse:54.02811\ttrain-rmse:42.03825\n", "[61]\ttest-rmse:53.99411\ttrain-rmse:41.78006\n", "[62]\ttest-rmse:53.94808\ttrain-rmse:41.66055\n", "[63]\ttest-rmse:53.85906\ttrain-rmse:41.51670\n", "[64]\ttest-rmse:53.75808\ttrain-rmse:41.27258\n", "[65]\ttest-rmse:53.68151\ttrain-rmse:41.04708\n", "[66]\ttest-rmse:53.60903\ttrain-rmse:40.91206\n", "[67]\ttest-rmse:53.47453\ttrain-rmse:40.72940\n", "[68]\ttest-rmse:53.45846\ttrain-rmse:40.52702\n", "[69]\ttest-rmse:53.41235\ttrain-rmse:40.39108\n", "[70]\ttest-rmse:53.30926\ttrain-rmse:40.24170\n", "[71]\ttest-rmse:53.24992\ttrain-rmse:40.05484\n", "[72]\ttest-rmse:53.20187\ttrain-rmse:39.83406\n", "[73]\ttest-rmse:53.15774\ttrain-rmse:39.66462\n", "[74]\ttest-rmse:53.13012\ttrain-rmse:39.50941\n", "[75]\ttest-rmse:53.05473\ttrain-rmse:39.39987\n", "[76]\ttest-rmse:53.01971\ttrain-rmse:39.26834\n", "[77]\ttest-rmse:52.90548\ttrain-rmse:39.09363\n", "[78]\ttest-rmse:52.85016\ttrain-rmse:38.97043\n", "[79]\ttest-rmse:52.78326\ttrain-rmse:38.87738\n", "[80]\ttest-rmse:52.68287\ttrain-rmse:38.64835\n", "[81]\ttest-rmse:52.63625\ttrain-rmse:38.45353\n", "[82]\ttest-rmse:52.60709\ttrain-rmse:38.39142\n", "[83]\ttest-rmse:52.54555\ttrain-rmse:38.27810\n", "[84]\ttest-rmse:52.52675\ttrain-rmse:38.13488\n", "[85]\ttest-rmse:52.47684\ttrain-rmse:38.01691\n", "[86]\ttest-rmse:52.44044\ttrain-rmse:37.93409\n", "[87]\ttest-rmse:52.38221\ttrain-rmse:37.81918\n", "[88]\ttest-rmse:52.37294\ttrain-rmse:37.68341\n", "[89]\ttest-rmse:52.34564\ttrain-rmse:37.59253\n", "[90]\ttest-rmse:52.32901\ttrain-rmse:37.52166\n", "[91]\ttest-rmse:52.24760\ttrain-rmse:37.38437\n", "[92]\ttest-rmse:52.21513\ttrain-rmse:37.26507\n", "[93]\ttest-rmse:52.19221\ttrain-rmse:37.18996\n", "[94]\ttest-rmse:52.19040\ttrain-rmse:36.98294\n", "[95]\ttest-rmse:52.17594\ttrain-rmse:36.85601\n", "[96]\ttest-rmse:52.16236\ttrain-rmse:36.73325\n", "[97]\ttest-rmse:52.15352\ttrain-rmse:36.65076\n", "[98]\ttest-rmse:52.08389\ttrain-rmse:36.48926\n", "[99]\ttest-rmse:52.05710\ttrain-rmse:36.43145\n" ] } ], "source": [ "bst = xgb.train(params, dtrain, num_round, evallist)\n" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [], "source": [ "y_pred = bst.predict(dtest)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [], "source": [ "import cupy as cp\n", "from cuml.metrics.regression import r2_score\n", "y_pred_cp = cp.asarray(y_pred)\n", "y_test_cp = cp.asarray(y_test).astype(np.float32)" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9151233434677124" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r2_score(y_test_cp, y_pred_cp)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timerange(reg, '2011-06-01', '2011-06-05')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Licensing\n", " \n", "This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Previous Notebook](Challenge.ipynb)\n", "     \n", "     \n", "     \n", "     \n", "[1](Challenge.ipynb)\n", "[2]\n", "     \n", "     \n", "     \n", "     \n", "\n", "\n", "     \n", "     \n", "     \n", "     \n", "     \n", "   \n", "[Home Page](../../START_HERE.ipynb)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 4 }