diff --git "a/C\303\263pia_de_Notebooks_NB01_02__Condicionais_hs.ipynb" "b/C\303\263pia_de_Notebooks_NB01_02__Condicionais_hs.ipynb" new file mode 100644 index 000000000..dfefafb07 --- /dev/null +++ "b/C\303\263pia_de_Notebooks_NB01_02__Condicionais_hs.ipynb" @@ -0,0 +1,411 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Cópia de Notebooks/NB01_02__Condicionais.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Y-QMrzHhpcu" + }, + "source": [ + "

CONDICIONAIS - IF

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wYGZ0eGlv--6" + }, + "source": [ + "# **AGENDA**:\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q3FpTG0dh47M" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWuIj53sVSnA" + }, + "source": [ + "___\n", + "# **CONDICIONAIS**\n", + "> Usado para decidir se uma determinada instrução ou bloco de instruções será executada ou não, isto é, se uma determinada condição for verdadeira, um bloco de instrução será executado." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NyG1l3awJzEq" + }, + "source": [ + "# Não executar o código a seguir:\n", + "if condicao1:\n", + " \n", + "elif condicao2:\n", + " \n", + "elif condicao3:\n", + " \n", + " ...\n", + "elif condicaoN:\n", + " \n", + "else:\n", + " " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FCJBMTh5WX5C" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vn5u7CEaWZjH" + }, + "source": [ + "def mensagem(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lW0ME_nVXU4M" + }, + "source": [ + "mensagem(35, 40)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EBBU8Yw2XxUo" + }, + "source": [ + "Nenhuma mensagem? E agora?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xQ23cAjMX1kx", + "outputId": "3612d39b-3f92-40fd-af14-2dfbca6b0697", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem(45, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "45 é maior que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BeHU0tPuWK4s" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gSzCnjS0Fk-d" + }, + "source": [ + "def mensagem2(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é menor ou igual a {i_limite}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KxbmxuDwYFX_", + "outputId": "8f1faff1-de34-4967-865f-17453f7992af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem2(35, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é menor ou igual a 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lToDO6pzWPGL" + }, + "source": [ + "## Exemplo 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a1NlziSbGrIl", + "outputId": "ffed270b-c16f-4d30-cdaf-80ae96898a94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " \n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " \n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + "print(s_mensagem)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0ms_mensagem\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0;34mf'{i_idade} é maior que {i_limite4}'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms_mensagem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 's_mensagem' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V8FF3lFLYqui" + }, + "source": [ + "Porque temos um erro nesta função?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y5F09RKGYyoX" + }, + "source": [ + "**Resposta**: por causa da indentação! A forma correta é:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vR-oFyzAY5UC" + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QgkBOGKdYgGU", + "outputId": "701f4620-817f-41e0-e9d7-f6b06adf6b3d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "mensagem3(35, 10, 20, 30, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é maior que 30 e menor que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LLk7bhjSwZch" + }, + "source": [ + "___\n", + "# **Wrap Up**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lJvjcjm8NQ85" + }, + "source": [ + "___\n", + "# Exercícios\n", + "## **Exercício 1**: \n", + "Escreva uma função em Python que receba um número inteiro i_limite e, na sequência, imprime os números inteiros de 0 a i_limite;\n", + "\n", + "## **outros exercícios**: \n", + "Nos sites abaixo você vai encontrar exercícios de Python:\n", + "### https://pynative.com/python-if-else-and-for-loop-exercise-with-solutions/;\n", + "### https://www.w3resource.com/python-exercises/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gi091pZrwbnY" + }, + "source": [ + "# Exercicio 1\n", + "def imprime_inteiros(i_limite):\n", + " for i_inteiro in range(i_limite+1):\n", + " print(i_inteiro, end=' ')\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vq2andamdPsZ", + "outputId": "7b7f7864-9402-4b13-86eb-c14aa95b55e5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "imprime_inteiros(10)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0 1 2 3 4 5 6 7 8 9 10 " + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MG_rtFd0eGgb" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/3DP_1_Feature Engineering_Fase1-TESTE.ipynb b/Notebooks/3DP_1_Feature Engineering_Fase1-TESTE.ipynb new file mode 100644 index 000000000..13a846cc6 --- /dev/null +++ b/Notebooks/3DP_1_Feature Engineering_Fase1-TESTE.ipynb @@ -0,0 +1,4856 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + }, + "colab": { + "name": "Copy of 10. Feature Selection Techniques.ipynb", + "provenance": [], + "toc_visible": true, + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ngLc7b9XiKxN" + }, + "source": [ + "# 3DP_FEATURE ENGINEERING - FASE 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNj9RdXbXmWq" + }, + "source": [ + "## Carrega as biblotecas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9JCQatsiKxR" + }, + "source": [ + "from sklearn import feature_selection\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_ebv3nAzU2ac" + }, + "source": [ + "## Carrega o dataframe\n", + "* A seguir, os principais atributos/features do dataframe:\n", + " * **PassengerID**: ID do passageiro;\n", + " * **Survived**: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * **Pclass**: Classe em que o passageiro viaja (1 classe, 2 classe, 3 classe, etc);\n", + " * **Age**: Idade do Passageiro;\n", + " * **SibSp**: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * **Parch**: Número de pais/crianças a bordo;\n", + " * **Fare**: Valor pago pela viagem;\n", + " * **Cabin**: Cabine do Passageiro;\n", + " * **Embarked**: A porta pelo qual o Passageiro embarcou.\n", + " * **Name**: Nome do Passageiro;\n", + " * **Sex**: Sexo do Passageiro." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8M5uO9r-Vtze" + }, + "source": [ + "url_train= 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/Titanic_With_MV.csv'\n", + "url_test= 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/Titanic_test.csv'\n", + "\n", + "# Carrega os dataframes de treinamento e teste e define 'PassengerId' como chave\n", + "df_train= pd.read_csv(url_train, index_col='PassengerId')\n", + "df_test= pd.read_csv(url_test, index_col='PassengerId')\n", + "\n", + "# Faz uma cópia dos dados originais da variável resposta 'Survived'\n", + "df_train_Survived = df_train[\"Survived\"].copy()\n", + "\n", + "# merge train and test\n", + "df = df_train.append(df_test, sort= False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QvbVxLs4ZZ0B" + }, + "source": [ + "## Entendendo o dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yr4kSh-vZcam", + "outputId": "8b2389b7-ad00-4a86-8748-3104a3ec5996", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Número de linhas/instâncias do dataframe\n", + "df.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1309, 11)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 229 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "icC1tMH1ZhlA", + "outputId": "64a5866c-06ec-4401-bfcc-2d753e070ac5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "# Colunas do dataframe\n", + "df.columns" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket',\n", + " 'Fare', 'Cabin', 'Embarked'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 230 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsVfiqfjwXcX", + "outputId": "2390399f-b753-448b-eba7-3817c8b8e35d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "# Tratar o nome das colunas usando lower\n", + "df.columns= [cols.lower() for cols in df.columns]\n", + "\n", + "# Verificar se o nome das variáveis estão ok\n", + "df.columns" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['survived', 'pclass', 'name', 'sex', 'age', 'sibsp', 'parch', 'ticket',\n", + " 'fare', 'cabin', 'embarked'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 231 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2opFNkvZ2sf", + "outputId": "e3a5efc3-4e57-4d31-d909-db35cff48129", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 289 + } + }, + "source": [ + "# Informações gerais sobre o dataframe\n", + "df.info()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "Int64Index: 1309 entries, 1 to 1309\n", + "Data columns (total 11 columns):\n", + "survived 891 non-null float64\n", + "pclass 1309 non-null int64\n", + "name 1309 non-null object\n", + "sex 1309 non-null object\n", + "age 1046 non-null float64\n", + "sibsp 1309 non-null int64\n", + "parch 1309 non-null int64\n", + "ticket 1309 non-null object\n", + "fare 1308 non-null float64\n", + "cabin 295 non-null object\n", + "embarked 1307 non-null object\n", + "dtypes: float64(3), int64(3), object(5)\n", + "memory usage: 122.7+ KB\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MeHf-pPtaFfM" + }, + "source": [ + "O que você diria do output acima? Que informações você consegue abstrair disso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GAM06rMgaMnZ", + "outputId": "ae88c0f3-7f46-48e2-fb0a-8494ff4ed1b3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 354 + } + }, + "source": [ + "# Visualizando parte do dataframe\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnamesexagesibspparchticketfarecabinembarked
PassengerId
10.03Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
31.03Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
50.03Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " survived pclass ... cabin embarked\n", + "PassengerId ... \n", + "1 0.0 3 ... NaN S\n", + "2 1.0 1 ... C85 C\n", + "3 1.0 3 ... NaN S\n", + "4 1.0 1 ... C123 S\n", + "5 0.0 3 ... NaN S\n", + "\n", + "[5 rows x 11 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 233 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ngoNsaGgaXsJ" + }, + "source": [ + "## Deletar atributos/features que não são de interesse\n", + "* Eu não vejo, a priori, valor na variável 'ticket'. Portanto, vou deletá-la do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BIihFnbTaj6K", + "outputId": "c4220be8-0f4c-455c-d087-4404e8360790", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "df= df.drop(['ticket'], axis=1) # axis= 1 indica que se trata de uma operação na coluna do dataframe. Lembre-se: axis= 0 indica operação nas linhas do dataframe.\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnamesexagesibspparchfarecabinembarked
PassengerId
10.03Braund, Mr. Owen Harrismale22.0107.2500NaNS
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...female38.01071.2833C85C
31.03Heikkinen, Miss. Lainafemale26.0007.9250NaNS
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01053.1000C123S
50.03Allen, Mr. William Henrymale35.0008.0500NaNS
\n", + "
" + ], + "text/plain": [ + " survived pclass ... cabin embarked\n", + "PassengerId ... \n", + "1 0.0 3 ... NaN S\n", + "2 1.0 1 ... C85 C\n", + "3 1.0 3 ... NaN S\n", + "4 1.0 1 ... C123 S\n", + "5 0.0 3 ... NaN S\n", + "\n", + "[5 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 234 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C8Sb5kOJasHr" + }, + "source": [ + "Observe que a coluna 'ticket' foi de fato deletada do dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3bbuq8rOawGN" + }, + "source": [ + "A seguir, crio a variável 'survived2' para ajudar no entendimento dos dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AyyfGIGya1bw", + "outputId": "13c90a85-66e7-4b87-9ea6-56dc2f1241ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 371 + } + }, + "source": [ + "df['survived2'] = df['survived']\n", + "df['survived2'] = df['survived2'].map({0:'Died',1:'Survived'})\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnamesexagesibspparchfarecabinembarkedsurvived2
PassengerId
10.03Braund, Mr. Owen Harrismale22.0107.2500NaNSDied
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...female38.01071.2833C85CSurvived
31.03Heikkinen, Miss. Lainafemale26.0007.9250NaNSSurvived
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01053.1000C123SSurvived
50.03Allen, Mr. William Henrymale35.0008.0500NaNSDied
\n", + "
" + ], + "text/plain": [ + " survived pclass ... embarked survived2\n", + "PassengerId ... \n", + "1 0.0 3 ... S Died\n", + "2 1.0 1 ... C Survived\n", + "3 1.0 3 ... S Survived\n", + "4 1.0 1 ... S Survived\n", + "5 0.0 3 ... S Died\n", + "\n", + "[5 rows x 11 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 235 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cegg0IcQa6NL" + }, + "source": [ + "## Entendendo as variáveis Originais do Dataframe\n", + "* Vamos verificar como as variáveis estão preenchidas a fim de corrigir possíveis problemas de preenchimento." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_WCbklv0bDlp" + }, + "source": [ + "A função a seguir nos ajudará com o Data Visualization, cruzando a variável-resposta 'Survived' com qualquer outra passada à função:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "epxI-F2UbGGS" + }, + "source": [ + "def Avalia_Taxa_Sobrevivencia(df, column):\n", + " title_xt = pd.crosstab(df[column], df['survived2'])\n", + " print(pd.crosstab(df[column], df['survived2'], margins=True))\n", + " title_xt_pct = title_xt.div(title_xt.sum(1).astype(float), axis=0)\n", + " \n", + " title_xt_pct.plot(kind='bar', stacked=True, title='Taxa de Sobrevivência dos Passageiros', \n", + " color= ['r', 'g'])\n", + " plt.xlabel(column)\n", + " plt.ylabel('Taxa de Sobrevivência')\n", + " plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),shadow=True, ncol=2)\n", + " plt.show()\n", + "\n", + "def Catplot_Graph(x, y, hue= 'survived2', col= None):\n", + " plt.rcdefaults()\n", + " g= sns.catplot(x= x, y= y, hue= hue, palette={'Died':'red','Survived':'blue'}, col= col, data=df, kind= 'bar', height=4, aspect=.7)\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a11nwzJKbNE-" + }, + "source": [ + "### Variável 'sex'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j56d6Z6ZbQ2m" + }, + "source": [ + "Vamos avaliar o preenchimento desta variável." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5X-0G4xNbU_b", + "outputId": "4f602695-5eb0-4b4e-a7bf-ad996fdac034", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 272 + } + }, + "source": [ + "df['sex'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "male 833\n", + "female 458\n", + "m 4\n", + "M 3\n", + "f 2\n", + "W 1\n", + "MALE 1\n", + "w 1\n", + "Woman 1\n", + "F 1\n", + "fEMALE 1\n", + "Men 1\n", + "mALE 1\n", + "Female 1\n", + "Name: sex, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 237 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eS2lsALObZwX" + }, + "source": [ + "Qual sua opinião sobre esse preenchimento?\n", + "\n", + "Algum problema?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AYQCZ9HObhXk" + }, + "source": [ + "Aqui temos vários problemas... Olhando para estes resultados, você concorda que 'male', 'm', 'MALE', M', 'mALE' e 'Men' se trata da mesma informação?\n", + "\n", + "Da mesma forma, 'female', 'f', 'F', 'Female', 'fEMALE', 'Woman', 'w' e 'W' também se trata da mesma informação?\n", + "\n", + "Então, vamos fazer o seguinte:\n", + "\n", + "Toda vez que eu encontrar um desses valores: ['m', 'MALE', 'M', 'mALE', 'Men'], vou substituir por 'male'; Toda vez que eu encontrar um desses valores: ['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], vou substituit por 'female'. O comando a seguir faz estas substituições:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hQx_tNBQblst" + }, + "source": [ + "Definindo o dicionário para fazermos as substituições dos valores inconsistentes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LPZzQwRfbnSi", + "outputId": "b8f78b06-59b2-4843-e7cd-9378f86a1df1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 255 + } + }, + "source": [ + "dSex= {}\n", + "dSex.update(dict.fromkeys(['m', 'MALE', 'M', 'mALE', 'Men', 'male'], 'male'))\n", + "dSex.update(dict.fromkeys(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W', 'female'], 'female'))\n", + "dSex" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'F': 'female',\n", + " 'Female': 'female',\n", + " 'M': 'male',\n", + " 'MALE': 'male',\n", + " 'Men': 'male',\n", + " 'W': 'female',\n", + " 'Woman': 'female',\n", + " 'f': 'female',\n", + " 'fEMALE': 'female',\n", + " 'female': 'female',\n", + " 'm': 'male',\n", + " 'mALE': 'male',\n", + " 'male': 'male',\n", + " 'w': 'female'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 238 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ3lwKRKbsx0" + }, + "source": [ + "Aplica a transformação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "idBwRNI7bvCC", + "outputId": "4b83067f-3096-4425-cf46-e7eb365c5e56", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "df['sex2']= df['sex'].map(dSex)\n", + "df['sex2'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "male 843\n", + "female 466\n", + "Name: sex2, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 239 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzDl78rfb3p5" + }, + "source": [ + "Qual a conclusão? Este preenchimento faz mais sentido que o anterior?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YPOpGyCpb_Yy" + }, + "source": [ + "**Atenção:** Os comandos abaixo são uma alternativa ao map() aplicado anteriormente para corrigir os atributos da variável 'Sex':\n", + "\n", + "```\n", + "df['Sex2'] = df['Sex'].replace(['m', 'MALE', 'M', 'mALE', 'Men'], 'male')\n", + "df['Sex3'] = df['Sex2'].replace(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], 'female') \n", + "df.Sex3.value_counts()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "muDUjFZecMAK" + }, + "source": [ + "Ok, de fato corrigimos os problemas de preenchimento da variável 'sex'. então, vamos renomear nossa variável para o que tínhamos antes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iWiYCTj8b1Dq", + "outputId": "9f36189e-58a0-4b47-bbb2-a123a8a6ee11", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 371 + } + }, + "source": [ + "# Deleta as variáveis 'sex':\n", + "df= df.drop(columns= ['sex'], axis= 1)\n", + "\n", + "# Renomea a variável auxiliar 'sex2' para 'sex':\n", + "df= df.rename(columns= {'sex2': 'sex'})\n", + "\n", + "# Mostra os dados:\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfarecabinembarkedsurvived2sex
PassengerId
10.03Braund, Mr. Owen Harris22.0107.2500NaNSDiedmale
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.2833C85CSurvivedfemale
31.03Heikkinen, Miss. Laina26.0007.9250NaNSSurvivedfemale
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.1000C123SSurvivedfemale
50.03Allen, Mr. William Henry35.0008.0500NaNSDiedmale
\n", + "
" + ], + "text/plain": [ + " survived pclass ... survived2 sex\n", + "PassengerId ... \n", + "1 0.0 3 ... Died male\n", + "2 1.0 1 ... Survived female\n", + "3 1.0 3 ... Survived female\n", + "4 1.0 1 ... Survived female\n", + "5 0.0 3 ... Died male\n", + "\n", + "[5 rows x 11 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 240 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XxKmFfe9cSxE", + "outputId": "22eed0ae-4d82-4d36-984d-c34ea9987709", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"sex\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 241 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-tYbYZW1V_eO" + }, + "source": [ + "### Variável 'cabin'\n", + "* No caso da variável 'cabin', vamos construir as variáveis 'deck' e 'seat'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GCflGdANp4jU", + "outputId": "1bc2cf22-9273-4a5f-d78f-4a4f83b341b2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "set(df['cabin'])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'A10',\n", + " 'A11',\n", + " 'A14',\n", + " 'A16',\n", + " 'A18',\n", + " 'A19',\n", + " 'A20',\n", + " 'A21',\n", + " 'A23',\n", + " 'A24',\n", + " 'A26',\n", + " 'A29',\n", + " 'A31',\n", + " 'A32',\n", + " 'A34',\n", + " 'A36',\n", + " 'A5',\n", + " 'A6',\n", + " 'A7',\n", + " 'A9',\n", + " 'B10',\n", + " 'B101',\n", + " 'B102',\n", + " 'B11',\n", + " 'B18',\n", + " 'B19',\n", + " 'B20',\n", + " 'B22',\n", + " 'B24',\n", + " 'B26',\n", + " 'B28',\n", + " 'B3',\n", + " 'B30',\n", + " 'B35',\n", + " 'B36',\n", + " 'B37',\n", + " 'B38',\n", + " 'B39',\n", + " 'B4',\n", + " 'B41',\n", + " 'B42',\n", + " 'B45',\n", + " 'B49',\n", + " 'B5',\n", + " 'B50',\n", + " 'B51 B53 B55',\n", + " 'B52 B54 B56',\n", + " 'B57 B59 B63 B66',\n", + " 'B58 B60',\n", + " 'B61',\n", + " 'B69',\n", + " 'B71',\n", + " 'B73',\n", + " 'B77',\n", + " 'B78',\n", + " 'B79',\n", + " 'B80',\n", + " 'B82 B84',\n", + " 'B86',\n", + " 'B94',\n", + " 'B96 B98',\n", + " 'C101',\n", + " 'C103',\n", + " 'C104',\n", + " 'C105',\n", + " 'C106',\n", + " 'C110',\n", + " 'C111',\n", + " 'C116',\n", + " 'C118',\n", + " 'C123',\n", + " 'C124',\n", + " 'C125',\n", + " 'C126',\n", + " 'C128',\n", + " 'C130',\n", + " 'C132',\n", + " 'C148',\n", + " 'C2',\n", + " 'C22 C26',\n", + " 'C23 C25 C27',\n", + " 'C28',\n", + " 'C30',\n", + " 'C31',\n", + " 'C32',\n", + " 'C39',\n", + " 'C45',\n", + " 'C46',\n", + " 'C47',\n", + " 'C49',\n", + " 'C50',\n", + " 'C51',\n", + " 'C52',\n", + " 'C53',\n", + " 'C54',\n", + " 'C55 C57',\n", + " 'C6',\n", + " 'C62 C64',\n", + " 'C65',\n", + " 'C68',\n", + " 'C7',\n", + " 'C70',\n", + " 'C78',\n", + " 'C80',\n", + " 'C82',\n", + " 'C83',\n", + " 'C85',\n", + " 'C86',\n", + " 'C87',\n", + " 'C89',\n", + " 'C90',\n", + " 'C91',\n", + " 'C92',\n", + " 'C93',\n", + " 'C95',\n", + " 'C97',\n", + " 'C99',\n", + " 'D',\n", + " 'D10 D12',\n", + " 'D11',\n", + " 'D15',\n", + " 'D17',\n", + " 'D19',\n", + " 'D20',\n", + " 'D21',\n", + " 'D22',\n", + " 'D26',\n", + " 'D28',\n", + " 'D30',\n", + " 'D33',\n", + " 'D34',\n", + " 'D35',\n", + " 'D36',\n", + " 'D37',\n", + " 'D38',\n", + " 'D40',\n", + " 'D43',\n", + " 'D45',\n", + " 'D46',\n", + " 'D47',\n", + " 'D48',\n", + " 'D49',\n", + " 'D50',\n", + " 'D56',\n", + " 'D6',\n", + " 'D7',\n", + " 'D9',\n", + " 'E10',\n", + " 'E101',\n", + " 'E12',\n", + " 'E121',\n", + " 'E17',\n", + " 'E24',\n", + " 'E25',\n", + " 'E31',\n", + " 'E33',\n", + " 'E34',\n", + " 'E36',\n", + " 'E38',\n", + " 'E39 E41',\n", + " 'E40',\n", + " 'E44',\n", + " 'E45',\n", + " 'E46',\n", + " 'E49',\n", + " 'E50',\n", + " 'E52',\n", + " 'E58',\n", + " 'E60',\n", + " 'E63',\n", + " 'E67',\n", + " 'E68',\n", + " 'E77',\n", + " 'E8',\n", + " 'F',\n", + " 'F E46',\n", + " 'F E57',\n", + " 'F E69',\n", + " 'F G63',\n", + " 'F G73',\n", + " 'F2',\n", + " 'F33',\n", + " 'F38',\n", + " 'F4',\n", + " 'G6',\n", + " 'T',\n", + " nan}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 242 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7E6yje89u7KF" + }, + "source": [ + "Como podemos ver, trata-se de uma variável categórica com vários níveis. Portanto, vamos capturar somente a primeira letra da variável 'cabin'. Para tal, vamos utilizar a função slice().\n", + "\n", + "> slice() - Get substring from a given string using slice object;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wmZLlSaArR6F" + }, + "source": [ + "A seguir, capturamos a primeira letra da variável 'Cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hUZTJU0MvVxP", + "outputId": "1b05c1a5-65af-4d90-9a51-696ee929af48", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "# definindo a variável 'deck' que representará a primeira letra da variável 'cabin'\n", + "df[\"deck\"] = df[\"cabin\"].str.slice(0,1) # slice(inicio, tamanho_da_string)\n", + "df['deck'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "C 94\n", + "B 65\n", + "D 46\n", + "E 41\n", + "A 22\n", + "F 21\n", + "G 5\n", + "T 1\n", + "Name: deck, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 243 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6myhrth0rZ6t" + }, + "source": [ + "A seguir, vamos extrair a parte numérica da variável 'cabin' usando Expressões Regulares:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8UXkACPmsfwN" + }, + "source": [ + "# Importar a biblioiteca para Expressões Regulares\n", + "import re" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QKk-fnW4rf4o", + "outputId": "1c9c1b59-19ce-4e10-80ea-61b80a9443fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + } + }, + "source": [ + "# Primeiramente, usamos a função split() para separar o conteúdo da variável em colunas: \n", + "new = df[\"cabin\"].str.split(\" \", n= 3, expand = True) \n", + "new.head(5)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
0123
PassengerId
1NaNNaNNaNNaN
2C85NoneNoneNone
3NaNNaNNaNNaN
4C123NoneNoneNone
5NaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3\n", + "PassengerId \n", + "1 NaN NaN NaN NaN\n", + "2 C85 None None None\n", + "3 NaN NaN NaN NaN\n", + "4 C123 None None None\n", + "5 NaN NaN NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 245 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dFqoR-Xew9gX" + }, + "source": [ + "Observe acima que o comando gera quantos splits da variável eu quiser. No entanto, por simplicidade, me interessa somente o primeiro split." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_M7vA6WoVG05" + }, + "source": [ + "Agora, vou extrair o número do assento do passageiro usando Expressões Regulares:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVH5o9KT_IH3", + "outputId": "fbb20adc-123a-4e37-f163-2c980568598f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 136 + } + }, + "source": [ + "# Aqui está o conteúdo de new[0]:\n", + "new[0].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "PassengerId\n", + "1 NaN\n", + "2 C85\n", + "3 NaN\n", + "4 C123\n", + "5 NaN\n", + "Name: 0, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 246 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P7NTcsGOxxSX", + "outputId": "61481b94-bf2c-4259-894b-95e34abc7483", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + } + }, + "source": [ + "new2= new[0].str.extract('(\\d+)')\n", + "new2.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
0
PassengerId
1NaN
285
3NaN
4123
5NaN
\n", + "
" + ], + "text/plain": [ + " 0\n", + "PassengerId \n", + "1 NaN\n", + "2 85\n", + "3 NaN\n", + "4 123\n", + "5 NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 247 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf8vw2Mc18bQ" + }, + "source": [ + "Por fim, vou carregar esta informação ao dataframe df:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6l6EoRvsxRXn", + "outputId": "760b25ed-ee3a-4a5e-da60-61eaee32c5a8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df[\"seat\"]= new2\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfarecabinembarkedsurvived2sexdeckseat
PassengerId
10.03Braund, Mr. Owen Harris22.0107.2500NaNSDiedmaleNaNNaN
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.2833C85CSurvivedfemaleC85
31.03Heikkinen, Miss. Laina26.0007.9250NaNSSurvivedfemaleNaNNaN
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.1000C123SSurvivedfemaleC123
50.03Allen, Mr. William Henry35.0008.0500NaNSDiedmaleNaNNaN
\n", + "
" + ], + "text/plain": [ + " survived pclass ... deck seat\n", + "PassengerId ... \n", + "1 0.0 3 ... NaN NaN\n", + "2 1.0 1 ... C 85\n", + "3 1.0 3 ... NaN NaN\n", + "4 1.0 1 ... C 123\n", + "5 0.0 3 ... NaN NaN\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 248 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LK4V61uy3N9s" + }, + "source": [ + "Por fim, excluir a variável 'cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4uAr55J43NY7" + }, + "source": [ + "df= df.drop(columns= [\"cabin\"], axis=1, errors=\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qZuH7YJXZCgY" + }, + "source": [ + "### Variável 'embarked'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nTPikhrIZGya", + "outputId": "fd84dd6a-7289-40d1-feab-9e5191b91258", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "df['embarked'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "S 914\n", + "C 270\n", + "Q 123\n", + "Name: embarked, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 250 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ixbZsuqOZsOc", + "outputId": "f7ace000-ed9d-455a-a4ce-a8722ecb9dd3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"embarked\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 251 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n3JLUzP8DH9rOtI0QD4kAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvdU8aAwZNvG" + }, + "source": [ + "Não vejo problemas com esta variável. Vamos em frente..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QBWfecCEF9ie" + }, + "source": [ + "### Variável 'pclass'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5TajFI92F_UI", + "outputId": "b762b729-d4c2-4e80-9dd2-334f67ea72ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "df['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3 709\n", + "1 323\n", + "2 277\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 252 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "atG9HFsYGNHE" + }, + "source": [ + "Algum problema com esta variável?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hdBdLzIPg3xD", + "outputId": "c6e49200-d76b-4025-9331-4ba999a09b3f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"pclass\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 253 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAFgCAYAAACbqJP/AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAE6RJREFUeJzt3X+s3fV93/HnKxhKSxMMyZ3n2kZk\nq0XE2obQW0pGV3WwdEDXGHUpSdoGl3lyJ5EokaatbJXatc3aZF2bAZ2QrJLUTmlSSpLhUURnOfRX\nFiAmOEAwGbeozPYMvoQf+cHSiuzdP87nlpMb2xw6f++5H9/nQzo63+/nfM/hbV3p6S9fn3tOqgpJ\nUj9eMe0BJEkvj+GWpM4YbknqjOGWpM4YbknqjOGWpM4YbknqjOGWpM4YbknqzKppD/D/49JLL607\n77xz2mNI0vGSSQ7q+oz7qaeemvYIkrTkug63JK1EhluSOmO4JakzhluSOmO4JakzhluSOmO4Jakz\nhluSOmO4JakzhluSOmO4JakzhluSOtP1pwNKGs5FN1w07RFOGJ9616eO6+sNdsad5Jwke8duX0ry\nniRnJtmV5NF2f0Y7PkmuTzKX5IEk5w81myT1bLBwV9UXquq8qjoP+F7geeATwLXA7qraCOxu+wCX\nARvbbStw41CzSVLPluoa9yXAn1fV48AmYHtb3w5c0bY3ATtq5G5gdZK1SzSfJHVjqcL9NuAjbXtN\nVR1q208Aa9r2OmD/2HMOtLVvkGRrkj1J9szPzw81ryQtW4OHO8kpwJuB31/8WFUVUC/n9apqW1XN\nVtXszMzMcZpSkvqxFGfclwGfraon2/6TC5dA2v3htn4Q2DD2vPVtTZI0ZinC/XZevEwCsBPY3LY3\nA7eNrV/V3l1yIfDc2CUVSVIz6Pu4k5wGvAn4mbHl9wG3JNkCPA5c2dbvAC4H5hi9A+XqIWeTpF4N\nGu6q+irw6kVrX2T0LpPFxxZwzZDzSNKJwF95l6TOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTO\nGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J\n6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6syg\n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\nrkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qrnc6VUKSTNp" + }, + "source": [ + "### Variável 'parch'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i4ed-0zSvJc", + "outputId": "029427d3-2436-4fe8-f957-9b8ec2baf4ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "df['parch'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 1002\n", + "1 170\n", + "2 113\n", + "3 8\n", + "5 6\n", + "4 6\n", + "9 2\n", + "6 2\n", + "Name: parch, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 254 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qd7u__6KZ6DM", + "outputId": "b9638d31-849f-4888-fe06-a39852a1a9ce", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"parch\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 255 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAFgCAYAAACbqJP/AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAE7FJREFUeJzt3X+w3XV95/HnSyJFaAWEuywmOGFa\nxmrddqG3lJYu7cKujdQaxqJju2qWZSe7W3SxdFppO1NYd5zR2VpFbZlJCTZU6o+CltRxUAYQW2el\nBqWCRNcMrSYZMBcF/DXWYt/7x/kEjpgbTuo953s+3Odj5s79fr/ne895R5lnvvme8/3eVBWSpH48\nZegBJEmHxnBLUmcMtyR1xnBLUmcMtyR1xnBLUmcMtyR1xnBLUmcMtyR1Zs3QA0zDhg0b6sYbbxx6\nDEk6VJlkpyflEfcDDzww9AiSNDVPynBL0pOZ4ZakzhhuSeqM4ZakzhhuSeqM4ZakzhhuSeqM4Zak\nzhhuSeqM4Zakzkwt3EmuTrIvyd1j256R5KYkn2/fj23bk+StSXYl+XSS08Z+ZlPb//NJNk1rXknq\nxTSPuP8U2PC4bZcCN1fVKcDNbR3gBcAp7WszcCWMQg9cBvw0cDpw2f7YS9JqNbW7A1bVR5Osf9zm\njcAvtOVtwEeA17bt11RVAR9PckySE9u+N1XVVwCS3MToL4N3HcosP/lb1/yL/gzfrzv+zysHeV1J\nT26zPsd9QlXd15bvB05oy2uB3WP77Wnbltv+PZJsTrIjyY6lpaWVnVqS5shgb062o+tawefbUlWL\nVbW4sLCwUk8rSXNn1uH+UjsFQvu+r23fC5w0tt+6tm257ZK0as063NuB/Z8M2QTcMLb9le3TJWcA\nD7dTKh8Cnp/k2Pam5PPbNklatab25mSSdzF6c/H4JHsYfTrkDcB7k1wIfAF4adv9g8C5wC7gm8AF\nAFX1lST/G/hE2+91+9+olKTVapqfKvnVZR465wD7FnDRMs9zNXD1Co4mSV3zyklJ6ozhlqTOGG5J\n6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozh\nlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTO\nGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J\n6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6swg4U7yG0k+k+TuJO9KckSSk5Pc\nnmRXkvckObzt+wNtfVd7fP0QM0vSvJh5uJOsBf4nsFhVzwMOA14GvBF4c1X9CPAgcGH7kQuBB9v2\nN7f9JGnVGupUyRrgaUnWAEcC9wFnA9e1x7cB57XljW2d9vg5STLDWSVprsw83FW1F/gD4IuMgv0w\ncAfwUFU90nbbA6xty2uB3e1nH2n7H/f4502yOcmOJDuWlpam+4eQpAENcarkWEZH0ScDzwSOAjZ8\nv89bVVuqarGqFhcWFr7fp5OkuTXEqZL/APx9VS1V1T8B7wPOBI5pp04A1gF72/Je4CSA9vjRwJdn\nO7IkzY8hwv1F4IwkR7Zz1ecA9wC3Aue3fTYBN7Tl7W2d9vgtVVUznFeS5soQ57hvZ/Qm4yeBu9oM\nW4DXApck2cXoHPbW9iNbgePa9kuAS2c9syTNkzVPvMvKq6rLgMset/le4PQD7Pst4CWzmEuSeuCV\nk5LUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLU\nGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMt\nSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x\n3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0ZJNxJjklyXZLPJtmZ\n5GeSPCPJTUk+374f2/ZNkrcm2ZXk00lOG2JmSZoXQx1xXwHcWFU/CvwEsBO4FLi5qk4Bbm7rAC8A\nTmlfm4ErZz+uJM2PmYc7ydHAWcBWgKr6dlU9BGwEtrXdtgHnteWNwDU18nHgmCQnznhsSZobQxxx\nnwwsAe9I8qkkVyU5Cjihqu5r+9wPnNCW1wK7x35+T9v2XZJsTrIjyY6lpaUpji9Jwxoi3GuA04Ar\nq+pU4Bs8dloEgKoqoA7lSatqS1UtVtXiwsLCig0rSfNmiHDvAfZU1e1t/TpGIf/S/lMg7fu+9vhe\n4KSxn1/XtknSqjTzcFfV/cDuJM9um84B7gG2A5vatk3ADW15O/DK9umSM4CHx06pSNKqs2ag1301\ncG2Sw4F7gQsY/SXy3iQXAl8AXtr2/SBwLrAL+GbbV5JWrUHCXVV3AosHeOicA+xbwEVTH0qSOuGV\nk5LUGcMtSZ0x3JLUGcMtSZ0x3JLUmYnCneTmSbZJkqbvoB8HTHIEcCRwfLvNatpDT+cA9wuRJE3f\nE32O+78BrwGeCdzBY+H+KvD2Kc4lSVrGQcNdVVcAVyR5dVW9bUYzSZIOYqIrJ6vqbUl+Flg//jNV\ndc2U5pIkLWOicCf5M+CHgTuB77TNBRhuSZqxSe9Vsgg8t903RJI0oEk/x3038K+nOYgkaTKTHnEf\nD9yT5G+Bf9y/sapeNJWpJEnLmjTcl09zCEnS5Cb9VMlt0x5EkjSZST9V8jUe++W9hwNPBb5RVU+f\n1mCSpAOb9Ij7h/YvJwmwEThjWkNJkpZ3yHcHrJG/BH5xCvNIkp7ApKdKXjy2+hRGn+v+1lQmkiQd\n1KSfKvnlseVHgH9gdLpEkjRjk57jvmDag0iSJjPpL1JYl+T9Sfa1r+uTrJv2cJKk7zXpm5PvALYz\nui/3M4G/atskSTM2abgXquodVfVI+/pTYGGKc0mSljFpuL+c5OVJDmtfLwe+PM3BJEkHNmm4/wvw\nUuB+4D7gfOA/T2kmSdJBTPpxwNcBm6rqQYAkzwD+gFHQJUkzNOkR94/vjzZAVX0FOHU6I0mSDmbS\ncD8lybH7V9oR96RH65KkFTRpfN8E/N8kf9HWXwK8fjojSZIOZtIrJ69JsgM4u216cVXdM72xJEnL\nmfh0Rwu1sZakgR3ybV0lScMy3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLU\nGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUmcHCneSwJJ9K8oG2fnKS25PsSvKeJIe37T/Q1ne1\nx9cPNbMkzYMhj7gvBnaOrb8ReHNV/QjwIHBh234h8GDb/ua2nyStWoOEO8k64JeAq9p6GP0+y+va\nLtuA89ryxrZOe/yctr8krUpDHXG/Bfht4J/b+nHAQ1X1SFvfA6xty2uB3QDt8Yfb/t8lyeYkO5Ls\nWFpamubskjSomYc7yQuBfVV1x0o+b1VtqarFqlpcWFhYyaeWpLky8W95X0FnAi9Kci5wBPB04Arg\nmCRr2lH1OmBv238vcBKwJ8ka4Gjgy7MfW5Lmw8yPuKvqd6pqXVWtB14G3FJV/wm4FTi/7bYJuKEt\nb2/rtMdvqaqa4ciSNFfm6XPcrwUuSbKL0TnsrW37VuC4tv0S4NKB5pOkuTDEqZJHVdVHgI+05XuB\n0w+wz7eAl8x0MEmaY/N0xC1JmoDhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozh\nlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTO\nGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J\n6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozhlqTOGG5J6ozh\nlqTOGG5J6szMw53kpCS3JrknyWeSXNy2PyPJTUk+374f27YnyVuT7Ery6SSnzXpmSZonQxxxPwL8\nZlU9FzgDuCjJc4FLgZur6hTg5rYO8ALglPa1Gbhy9iNL0vyYebir6r6q+mRb/hqwE1gLbAS2td22\nAee15Y3ANTXyceCYJCfOeGxJmhuDnuNOsh44FbgdOKGq7msP3Q+c0JbXArvHfmxP2/b459qcZEeS\nHUtLS1ObWZKGNli4k/wgcD3wmqr66vhjVVVAHcrzVdWWqlqsqsWFhYUVnFSS5ssg4U7yVEbRvraq\n3tc2f2n/KZD2fV/bvhc4aezH17VtkrQqDfGpkgBbgZ1V9YdjD20HNrXlTcANY9tf2T5dcgbw8Ngp\nFUladdYM8JpnAq8A7kpyZ9v2u8AbgPcmuRD4AvDS9tgHgXOBXcA3gQtmO64kzZeZh7uq/gbIMg+f\nc4D9C7hoqkNJUke8clKSOmO4JakzhluSOjPEm5Nqvvi6fzPI6z7r9+8a5HUlrQyPuCWpM4Zbkjpj\nuCWpM4ZbkjpjuCWpM4ZbkjpjuCWpM4ZbkjpjuCWpM4ZbkjpjuCWpM4ZbkjpjuCWpM4ZbkjpjuCWp\nM96PW9/jzLedOcjrfuzVHxvkdaXeeMQtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLU\nGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMt\nSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ0x3JLUGcMtSZ1ZM/QAk0qyAbgCOAy4qqreMPBI\nmrHbzvr5QV735z962yCvKy2ni3AnOQz4I+A/AnuATyTZXlX3DDuZVru3/+ZfDfbar3rTLy/72Otf\nfv4MJ/luv/fO6wZ77dWii3ADpwO7qupegCTvBjYChlvqyM7X3zLI6z7n984+6OOXX375bAZZoddN\nVa3sJFOQ5HxgQ1X917b+CuCnq+pVY/tsBja31WcDn1uhlz8eeGCFnmslOdehca7JzeNMsDrmeqCq\nNjzRTr0ccT+hqtoCbFnp502yo6oWV/p5v1/OdWica3LzOBM417hePlWyFzhpbH1d2yZJq04v4f4E\ncEqSk5McDrwM2D7wTJI0iC5OlVTVI0leBXyI0ccBr66qz8zo5Vf89MsKca5D41yTm8eZwLke1cWb\nk5Kkx/RyqkSS1BhuSeqM4T6IJBuSfC7JriSXDj0PQJKrk+xLcvfQs4xLclKSW5Pck+QzSS6eg5mO\nSPK3Sf6uzfS/hp5pXJLDknwqyQeGnmW/JP+Q5K4kdybZMfQ8+yU5Jsl1ST6bZGeSnxl6JoAkFye5\nu/339ZqZva7nuA+sXWb//xi7zB741aEvs09yFvB14Jqqet6Qs4xLciJwYlV9MskPAXcA5w35v1eS\nAEdV1deTPBX4G+Diqvr4UDONS3IJsAg8vapeOPQ8MAo3sFhVc3WhS5JtwF9X1VXtk2VHVtVDA8/0\nPODdjK7s/jZwI/Dfq2rXtF/bI+7lPXqZfVV9m9H/QRsHnomq+ijwlaHneLyquq+qPtmWvwbsBNYO\nPFNV1dfb6lPb11wcqSRZB/wScNXQs8y7JEcDZwFbAarq20NHu3kOcHtVfbOqHgFuA148ixc23Mtb\nC+weW9/DwCHqRZL1wKnA7cNO8ujpiDuBfcBNVTX4TM1bgN8G/nnoQR6ngA8nuaPdRmIenAwsAe9o\np5auSnLU0EMBdwP/LslxSY4EzuW7LxScGsOtFZXkB4HrgddU1VeHnqeqvlNV/5bR1bant3/eDirJ\nC4F9VXXH0LMcwM9V1WnAC4CL2qm5oa0BTgOurKpTgW8Ag7/nVFU7gTcCH2Z0muRO4DuzeG3DvTwv\nsz9E7Tzy9cC1VfW+oecZ1/5pfSvwhDfwmYEzgRe188nvBs5O8s5hRxqpqr3t+z7g/YxOGQ5tD7Bn\n7F9L1zEK+eCqamtV/WRVnQU8yOh9sakz3MvzMvtD0N4I3ArsrKo/HHoegCQLSY5py09j9EbzZ4ed\nCqrqd6pqXVWtZ/Tf1S1V9fKBxyLJUe2NZdqpiOczOh0wqKq6H9id5Nlt0znMyS2dk/yr9v1ZjM5v\n//ksXreLS96HMPBl9stK8i7gF4Djk+wBLquqrcNOBYyOIl8B3NXOKQP8blV9cMCZTgS2tU8IPQV4\nb1XNzUfv5tAJwPtHfwezBvjzqrpx2JEe9Wrg2nYQdS9wwcDz7Hd9kuOAfwIumtWbpn4cUJI646kS\nSeqM4ZakzhhuSeqM4ZakzhhuSeqM4ZZWUJL183bnRj35GG7pXyCJ10BoMIZbq1Y7Ov5skmvbPZ6v\nS3Jkkt9P8ol2n+Ut7apQknwkyVvafaovTnJCkve3+33/XZKfbU99WJI/afdo/nC7alNaMYZbq92z\ngT+uqucAXwV+HXh7Vf1Uu9/504Dxe2UfXlWLVfUm4K3AbVX1E4zunbH/ytpTgD+qqh8DHgJ+ZUZ/\nFq0Shlur3e6q+lhbfifwc8C/T3J7kruAs4EfG9v/PWPLZwNXwqN3IXy4bf/7qtp/2f8dwPppDa/V\nyfN0Wu0ef8+HAv6Y0W+B2Z3kcuCIsce/McFz/uPY8ncYHbVLK8Yjbq12zxr7/YW/xujXmwE80O4t\nfv5BfvZm4H/Ao7+w4ejpjSk9xnBrtfsco18YsBM4ltGpjz9hdDvTDzG6ve9yLmZ0WuUuRqdEnjvl\nWSXAuwNqFWu/Yu0D8/RLl6VJeMQtSZ3xiFuSOuMRtyR1xnBLUmcMtyR1xnBLUmcMtyR15v8DHTPO\ndbcumhYAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z9vM3vktC7BG" + }, + "source": [ + "#### Exercício:\n", + "* Criar o atributo 'sozinho_parch', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nd4TyOYjs-HW" + }, + "source": [ + "# Função para retornar 0 ou 1 em função dos valores de variavel\n", + "def sozinho(variavel):\n", + " if (variavel == 0):\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5oByiBuos_B3", + "outputId": "ca493249-7147-4273-e3ac-cf22ff8ecec7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df['sozinho_parch'] = df['parch'].map(sozinho)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parch
PassengerId
10.03Braund, Mr. Owen Harris22.0107.2500SDiedmaleNaNNaN1
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.2833CSurvivedfemaleC851
31.03Heikkinen, Miss. Laina26.0007.9250SSurvivedfemaleNaNNaN1
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.1000SSurvivedfemaleC1231
50.03Allen, Mr. William Henry35.0008.0500SDiedmaleNaNNaN1
\n", + "
" + ], + "text/plain": [ + " survived pclass ... seat sozinho_parch\n", + "PassengerId ... \n", + "1 0.0 3 ... NaN 1\n", + "2 1.0 1 ... 85 1\n", + "3 1.0 3 ... NaN 1\n", + "4 1.0 1 ... 123 1\n", + "5 0.0 3 ... NaN 1\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 257 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C1ICby1oSd41" + }, + "source": [ + "### Variável 'sibsp'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5n7JNEQqTNjz", + "outputId": "dc13b210-2928-488d-84e9-22a36929848a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "df['sibsp'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 891\n", + "1 319\n", + "2 42\n", + "4 22\n", + "3 20\n", + "8 9\n", + "5 6\n", + "Name: sibsp, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 258 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NLfMhiy0x4u5" + }, + "source": [ + "* Algum problema?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nayYFRK9g8iV", + "outputId": "feb5e2e5-a924-49ee-8f1c-7d3f56745e5f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"sibsp\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 259 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_58rZqMaDzf-" + }, + "source": [ + "#### Exercício:\n", + "* Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HUrJ4IywrEoA", + "outputId": "c2e6a80d-a2ba-4a47-ed3c-6e7c501eeb28", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df['sozinho_sibsp'] = df['sibsp'].map(sozinho)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibsp
PassengerId
10.03Braund, Mr. Owen Harris22.0107.2500SDiedmaleNaNNaN10
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.2833CSurvivedfemaleC8510
31.03Heikkinen, Miss. Laina26.0007.9250SSurvivedfemaleNaNNaN11
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.1000SSurvivedfemaleC12310
50.03Allen, Mr. William Henry35.0008.0500SDiedmaleNaNNaN11
\n", + "
" + ], + "text/plain": [ + " survived pclass ... sozinho_parch sozinho_sibsp\n", + "PassengerId ... \n", + "1 0.0 3 ... 1 0\n", + "2 1.0 1 ... 1 0\n", + "3 1.0 3 ... 1 1\n", + "4 1.0 1 ... 1 0\n", + "5 0.0 3 ... 1 1\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 260 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0MO9jj2NvGp_" + }, + "source": [ + "### Variável 'fare'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UuWlMV6XvQHs" + }, + "source": [ + "Transformações: arredondar variável Fare." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "boAj64RHvQHu" + }, + "source": [ + "df['fare']= round(df['fare'], 0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3CIqHUJpvcPa" + }, + "source": [ + "### Variável 'age'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VULFXjvap3qZ" + }, + "source": [ + "Transformações: arredondar variável 'age'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kpNhCRxcp7h9" + }, + "source": [ + "df['age']= round(df['age'], 0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0fZMKKpdHIl" + }, + "source": [ + "## Derivar outros atributos/features" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H6n6PzWjoSYf" + }, + "source": [ + "### Variável 'mv_age':\n", + "* Variável (dummy) que assume os valores 1, se o valor de age> 0 e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QluOnZD7kHFW", + "outputId": "26077a35-f1ea-4d12-bf39-3733787d9168", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibsp
PassengerId
10.03Braund, Mr. Owen Harris22.0107.0SDiedmaleNaNNaN10
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.0CSurvivedfemaleC8510
31.03Heikkinen, Miss. Laina26.0008.0SSurvivedfemaleNaNNaN11
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.0SSurvivedfemaleC12310
50.03Allen, Mr. William Henry35.0008.0SDiedmaleNaNNaN11
\n", + "
" + ], + "text/plain": [ + " survived pclass ... sozinho_parch sozinho_sibsp\n", + "PassengerId ... \n", + "1 0.0 3 ... 1 0\n", + "2 1.0 1 ... 1 0\n", + "3 1.0 3 ... 1 1\n", + "4 1.0 1 ... 1 0\n", + "5 0.0 3 ... 1 1\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 263 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qKMVIXGDsNkh" + }, + "source": [ + "Para construir a variável 'mv_age', vamos utilizar a função pd.isna(). Por exemplo, o comando abaixo verifica se cada linha/observação da variável 'age' é um NaN." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UHzKFytXsNkh", + "outputId": "45bc64e2-5708-493a-9e2e-3f2ac06c37ab", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df['age'].isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "263" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lW4NYZrjsNkk" + }, + "source": [ + "A seguir, criamos uma variável auxiliar intitulada 'mv_aux', que receberá 'True', caso 'age' seja NaN e 'False', caso contrário.\n", + "\n", + "Veja abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-bTvVuVpsNkl", + "outputId": "3efb4a54-5d14-40f1-b620-5fb9cdbeff72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df['mv_aux']= df['age'].isna()\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_aux
PassengerId
10.03Braund, Mr. Owen Harris22.0107.0SDiedmaleNaNNaN10False
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.0CSurvivedfemaleC8510False
31.03Heikkinen, Miss. Laina26.0008.0SSurvivedfemaleNaNNaN11False
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.0SSurvivedfemaleC12310False
50.03Allen, Mr. William Henry35.0008.0SDiedmaleNaNNaN11False
\n", + "
" + ], + "text/plain": [ + " survived pclass ... sozinho_sibsp mv_aux\n", + "PassengerId ... \n", + "1 0.0 3 ... 0 False\n", + "2 1.0 1 ... 0 False\n", + "3 1.0 3 ... 1 False\n", + "4 1.0 1 ... 0 False\n", + "5 0.0 3 ... 1 False\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 265 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "R_gk5S4nsNko", + "outputId": "0f69dcb5-75e6-4280-da3d-bab15059d47c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "# Adiciona a nova coluna baseado no dicionario \n", + "df['mv_age'] = df['mv_aux'].map({True: 1, False: 0})\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_auxmv_age
PassengerId
10.03Braund, Mr. Owen Harris22.0107.0SDiedmaleNaNNaN10False0
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.0CSurvivedfemaleC8510False0
31.03Heikkinen, Miss. Laina26.0008.0SSurvivedfemaleNaNNaN11False0
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.0SSurvivedfemaleC12310False0
50.03Allen, Mr. William Henry35.0008.0SDiedmaleNaNNaN11False0
\n", + "
" + ], + "text/plain": [ + " survived pclass ... mv_aux mv_age\n", + "PassengerId ... \n", + "1 0.0 3 ... False 0\n", + "2 1.0 1 ... False 0\n", + "3 1.0 3 ... False 0\n", + "4 1.0 1 ... False 0\n", + "5 0.0 3 ... False 0\n", + "\n", + "[5 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 266 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IHzMcHl8sNkq" + }, + "source": [ + "Deleta a variável auxiliar 'mv_aux':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DYKh0uMYsNks", + "outputId": "ddcc284c-af6f-4761-8dc4-bc25e4ac94b2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df= df.drop(columns= ['mv_aux'], axis=1)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_age
PassengerId
10.03Braund, Mr. Owen Harris22.0107.0SDiedmaleNaNNaN100
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.0CSurvivedfemaleC85100
31.03Heikkinen, Miss. Laina26.0008.0SSurvivedfemaleNaNNaN110
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.0SSurvivedfemaleC123100
50.03Allen, Mr. William Henry35.0008.0SDiedmaleNaNNaN110
\n", + "
" + ], + "text/plain": [ + " survived pclass ... sozinho_sibsp mv_age\n", + "PassengerId ... \n", + "1 0.0 3 ... 0 0\n", + "2 1.0 1 ... 0 0\n", + "3 1.0 3 ... 1 0\n", + "4 1.0 1 ... 0 0\n", + "5 0.0 3 ... 1 0\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 267 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "34-Qbd_QrC8W" + }, + "source": [ + "Qual a relação entre a variável 'mv_age' e a variável-resposta?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bhY8-UjyrC8Z", + "outputId": "f9c29d9b-3ba4-4eb4-ffa6-1f8b6d55a264", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 383 + } + }, + "source": [ + "Avalia_Taxa_Sobrevivencia(df, 'mv_age')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "survived2 Died Survived All\n", + "mv_age \n", + "0 424 290 714\n", + "1 125 52 177\n", + "All 549 342 891\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEZCAYAAAB4hzlwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3XmYHVWZx/HvrzsBgmHThJCFLMiu\nQDDNoghGcFgcbAYFkiBxRpgJy4ABHBxGCRCEGUHGBWSA6DABJYRNpEVHGBEQ2bsBgSQgESQJJCYB\nEkhMJEm/80edLi5N9+0b6Lo36fw+z9NP13ar3rq3br33nFN1ShGBmZkZQF2tAzAzs3WHk4KZmeWc\nFMzMLOekYGZmOScFMzPLOSmYmVnOScFykg6VNLsG210g6ZNV2tZvJI1Zi+VPl/SKpD1qsf0u1vWw\npOO6Y109iaSNJS2TNKjWsayPnBRqIB2wbX+tklaUjH+x1vG9F5KGS/qZpMWSlkp6al3cl4g4MCJu\nrGTZlAj2AxqAb0vqU83t10JK0H9Jx+ICST+StGmt41obEfHXiOgbEa/UOpb1kZNCDaQDtm9E9AXm\nAJ8rmXZ9reN7j24AngO2BfoBXwYWdfdGJPXq7nV2JiJ+HxFHR8QrEXFwRKyo1rZr7OB0bO4N7A98\nrcbxdCtJ9bWOYV3mpLAOkrSfpEckLUlVF99tOxlK+rSkhZIGpvG9JL0u6cNp/FxJL0p6U9Izkv62\nzHY+IOn6tJ2ngT3bzd9W0u3p1/8Lkk7qZD0i+zX9PxGxIiJWRURLRNxVsswXJM1M2/q1pB3areYT\nkp6V9JqkKZI2Tq87VNJsSZMk/Rm4Mk0/MpVGlki6X9Kuafp5kn7SLr6rJV2Shh+WdJykTdOv4e1L\nlhucSm1bldtGmrdA0hnpPV6a3seNSuYfnV77pqTnJR1Uuv00vLOke9M+L5J0raTNynxef5vWtUTS\nd9rNq5c0WdIcSX+WdE3butLnPD1tZ0k6trbqbDttImIOcBfw0bSeE9Nn9Gb6TI4v2f42kn6V1v+q\npN+UzJskab6kNyTNkrR/mt7pcd7B/n5P7arLUjzPpf36haTBafomkkLSkDQ+XdJlku6StBz4uKQP\nSpqW3vcXJX0tHcdtn8vv0ue6SNJ1Xb1XPUpE+K+Gf8CfgM+0m7Y3sBdQD3wYmA2cVDL/P4H/BTYF\n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\n5yuY7f1rbW3V/Pnzd5ozZ84jjY2NDU1NTfNrHZO9zd9yK6u1tXXnAQMG9HJCsO5SV1fHwIED63r3\n7j0I+LfGxsZ+tY7J3uZvunXFJQTrdnV1daTHsW9GdgWcrSP8bTezWutd6wDsbW5TsLXT3Q8pr+Dq\nt/r6enbbbTdWrVpFr169+NKXvsQZZ5xBXV0dzc3NXHfddVx22WUVb3L06NFceumlNDR07+N/Nbl7\n35s4r7IrAy+66CKmTZtGfX09dXV1XH311eyzzz7va9tNTU3MnDmTs89+/z2g9O3bl2XLlr3v9Vh1\nOCnYOq9Pnz48+WR2+frChQs59thjeeONN5g8eTINDQ3dfnJfnzz00EPccccdPP7442y88cYsXryY\nt956q6LXrl69ml69Oj4FNDY20tjY2J2h2nrC1Ue2Xtl6662ZMmUKP/jBD4gI7r33Xg4//HAAli9f\nzvHHH8/ee+/Nnnvuye233w7AihUrGDt2LLvssgtHHnkkK1asqOUudKv58+fTr18/Nt54YwD69evH\noEGDGD58OIsXLwagubmZ0aNHA3D++eczfvx49ttvP8aPH8++++7LjBkz8vWNHj2a5uZmpk6dyqmn\nnsrSpUsZNmwYra1ZTyjLly9n2223ZdWqVfzxj3/k0EMPZdSoUey///48++yzALz44ot8/OMfZ7fd\nduOcc86p4rth3cFJwdY72223HWvWrGHhwoXvmH7RRRdx4IEH8uijj3LPPfdw1llnsXz5cq688ko2\n3XRTZs2axeTJk2lpaalR5N3v4IMPZu7cuey4446ccsop3HfffV2+ZubMmfz617/mhhtuYMyYMdx0\n001AlmDmz5//jpLXFltswciRI/P13nHHHRxyyCH07t2bCRMmcPnll9PS0sKll17KKaecAsDEiRM5\n+eSTefrppxk4cGABe21FclKwHuOuu+7iW9/6FiNHjmT06NGsXLmSOXPm8Nvf/pbjjjsOgN13353d\nd9+9xpF2n759+9LS0sKUKVPo378/Y8aMYerUqWVf09jYSJ8+fQA45phjuOWWWwC46aabOOqoo961\n/JgxY7jxxhsBmD59OmPGjGHZsmU8+OCDHH300YwcOZITTzyR+fOz2w0eeOABxo0bB8D48eO7a1et\nStymYOudF154gfr6erbeemtmzXr7+UARwa233spOO+1Uw+iqr76+ntGjRzN69Gh22203rr32Wnr1\n6pVX+axcufIdy3/gAx/IhwcPHsyHPvQhnnrqKW688Uauuuqqd62/sbGRr3/967z22mu0tLRw4IEH\nsnz5crbccsu8rac9dfcFCVY1LinYemXRokWcdNJJnHrqqe868RxyyCFcfvnltPXn9cQTTwBwwAEH\nMG3aNACeeeYZnnqqs16a1z+SNyn6AAAB/0lEQVTPPfcczz//fD7+5JNPMmzYMIYPH55Xk916661l\n1zFmzBguueQSli5d2mEpqm/fvuy1115MnDiRww8/nPr6ejbffHNGjBjBzTffDGQJ+fe//z0A++23\nH9OnTwfg+uuv75b9tOpxScHWTg06UFyxYgUjR47ML0kdP348Z5555ruWmzRpEqeffjq77747ra2t\njBgxgjvuuIOTTz6ZL3/5y+yyyy7ssssujBo1qpA4K72EtDstW7aM0047jSVLltCrVy+23357pkyZ\nwqxZszjhhBOYNGlS3sjcmaOOOoqJEycyadKkTpcZM2YMRx99NPfee28+7frrr+fkk0/mwgsvZNWq\nVYwdO5Y99tiD73//+xx77LFcfPHFHHHEEd20p1Yt7iXVymppaYmiTqK2YWtpaWHy5MlTgWuampru\nr3U8lnH1kZmZ5ZwUzMws56RgXYm2q1jMuktrayuuul43OSlYWXV1dc8uWLBgjRODdZfW1lbmz5/f\nunLlysW1jsXezVcfWVmtra0Hz5s37/5XXnlluK89t+4QEaxcufK166677sdAP+CNWsdkb3NSsLJG\njRo1r7GxcSdgAjAKWFPjkKzn+CDwO2BGVwta9fiSVKtIY2NjL2AwsEmtY7EeYwXwclNTk39orEOc\nFMzMLOeGZjMzyzkpmJlZzknBzMxy/w91op44Q8PhVAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "umQ3fIKlsNlN" + }, + "source": [ + "### Variável 'age_category'\n", + "* Construir a variável 'age_category' baseado na variável 'age'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W66GkyuKkhFe" + }, + "source": [ + "def Age_Category(age):\n", + " if (age <= 1):\n", + " return 1\n", + " elif (age <= 5):\n", + " return 2\n", + " elif(age <= 10):\n", + " return 3\n", + " elif (age <= 15):\n", + " return 4\n", + " elif (age <= 20):\n", + " return 5\n", + " elif (age <= 25):\n", + " return 6\n", + " elif(age < 30):\n", + " return 7\n", + " elif(age < 35):\n", + " return 8\n", + " elif(age < 40):\n", + " return 9\n", + " elif(age < 45):\n", + " return 10\n", + " elif(age < 50):\n", + " return 11\n", + " elif(age < 60):\n", + " return 12\n", + " elif(age < 70):\n", + " return 13\n", + " elif(age < 80):\n", + " return 14\n", + " else:\n", + " return 15" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TnLzC6hCkuBL" + }, + "source": [ + "df['age_category'] = df['age'].map(Age_Category)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kG8td6HPsNlP", + "outputId": "a1debdae-ae3e-41e4-fc8f-52696809fc11", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df['age_category']) # Esse comando mostra os NaN's da variável" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 271 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B_3s5cgxfNKQ" + }, + "source": [ + "### Variável 'title'\n", + "\n", + "* Para fins de Data Manipulation, vamos capturar o tratamento dos passageiros contido na variável 'Name'. Ou seja, 'Mr.', 'Mrs.', 'Miss' e etc...\n", + "\n", + "> Fonte: As funções get_title e title_map foram extraídas de https://www.kaggle.com/tjsauer/titanic-survival-python-solution" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gslSjRdDoJFY", + "outputId": "68f27f6d-d52b-48e8-c2e3-ad86acf44792", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassnameagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_ageage_category
PassengerId
10.03Braund, Mr. Owen Harris22.0107.0SDiedmaleNaNNaN1006
21.01Cumings, Mrs. John Bradley (Florence Briggs Th...38.01071.0CSurvivedfemaleC851009
31.03Heikkinen, Miss. Laina26.0008.0SSurvivedfemaleNaNNaN1107
41.01Futrelle, Mrs. Jacques Heath (Lily May Peel)35.01053.0SSurvivedfemaleC1231009
50.03Allen, Mr. William Henry35.0008.0SDiedmaleNaNNaN1109
\n", + "
" + ], + "text/plain": [ + " survived pclass ... mv_age age_category\n", + "PassengerId ... \n", + "1 0.0 3 ... 0 6\n", + "2 1.0 1 ... 0 9\n", + "3 1.0 3 ... 0 7\n", + "4 1.0 1 ... 0 9\n", + "5 0.0 3 ... 0 9\n", + "\n", + "[5 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 272 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nfIG6toGfhd5" + }, + "source": [ + "def get_title(name):\n", + " if '.' in name:\n", + " return name.split(',')[1].split('.')[0].strip()\n", + " else:\n", + " return 'Unknown'\n", + "\n", + "def title_map(title):\n", + " if title in ['Mr', 'Ms']:\n", + " return 1\n", + " elif title in ['Master']:\n", + " return 2\n", + " elif title in ['Ms','Mlle','Miss']:\n", + " return 3\n", + " elif title in [\"Mme\", \"Ms\", \"Mrs\"]:\n", + " return 4\n", + " elif title in [\"Jonkheer\", \"Don\", \"Sir\", \"the Countess\", \"Dona\", \"Lady\"]:\n", + " return 5\n", + " elif title in [\"Capt\", \"Col\", \"Major\", \"Dr\", \"Rev\"]:\n", + " return 6\n", + " else:\n", + " return 7" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7qNUwnCepe_x" + }, + "source": [ + "Captura o tratamento dos passageiros:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-Ltf33vgJ6Q", + "outputId": "930abc58-2b12-434e-9e93-c3da788dc000", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df['title'] = df['name'].apply(get_title).apply(title_map) \n", + "set(df['title']) # Esse comando mostra os NaN's da variável" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1, 2, 3, 4, 5, 6}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 274 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D3hY0WVhpRYK" + }, + "source": [ + "Drop a coluna 'Name', pois não vamos mais precisar dela em nossas análises:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8i3xKCes5WF" + }, + "source": [ + "df= df.drop(columns= [\"name\"], axis=1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Sl1uFdwpW3y" + }, + "source": [ + "Apresenta o conteúdo do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2uFnw-pZpan-", + "outputId": "a72224f4-41de-406a-da4c-07be3c824184", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 410 + } + }, + "source": [ + "df.head(10)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_ageage_categorytitle
PassengerId
10.0322.0107.0SDiedmaleNaNNaN10061
21.0138.01071.0CSurvivedfemaleC8510094
31.0326.0008.0SSurvivedfemaleNaNNaN11073
41.0135.01053.0SSurvivedfemaleC12310094
50.0335.0008.0SDiedmaleNaNNaN11091
60.03NaN008.0QDiedmaleNaNNaN111151
70.0154.00052.0SDiedmaleE46110121
80.032.03121.0SDiedmaleNaNNaN00022
91.0327.00211.0SSurvivedfemaleNaNNaN01074
101.0214.01030.0CSurvivedfemaleNaNNaN10044
\n", + "
" + ], + "text/plain": [ + " survived pclass age ... mv_age age_category title\n", + "PassengerId ... \n", + "1 0.0 3 22.0 ... 0 6 1\n", + "2 1.0 1 38.0 ... 0 9 4\n", + "3 1.0 3 26.0 ... 0 7 3\n", + "4 1.0 1 35.0 ... 0 9 4\n", + "5 0.0 3 35.0 ... 0 9 1\n", + "6 0.0 3 NaN ... 1 15 1\n", + "7 0.0 1 54.0 ... 0 12 1\n", + "8 0.0 3 2.0 ... 0 2 2\n", + "9 1.0 3 27.0 ... 0 7 4\n", + "10 1.0 2 14.0 ... 0 4 4\n", + "\n", + "[10 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 276 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci5FKBazGidH" + }, + "source": [ + "### Variável 'family_size'\n", + "* As variáveis 'sibsp' e 'parch' estão relacionadas ao grupo familiar. Portanto, vamos criar a variável 'family_size', da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DICRTPxhGvt5" + }, + "source": [ + "df['family_size']= df['sibsp']+df['parch']+1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6tLLmTrZhDvG", + "outputId": "6d120e96-a9b6-4291-d7ad-f64b3dba1c6a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 386 + } + }, + "source": [ + "sns.catplot(x=\"family_size\", kind=\"count\", data=df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 278 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sxwSYcLBY1gy", + "outputId": "0b4ad32e-8d61-49fd-b022-adab64863a26", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df['family_size']) # Esse comando mostra os NaN's da variável" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1, 2, 3, 4, 5, 6, 7, 8, 11}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 279 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5LrvxqXo2uL" + }, + "source": [ + "# DataViz - Data Visualization" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rJlcGd49vmkk", + "outputId": "8bd4559e-4ec7-499d-f664-cec23cab9e89", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 255 + } + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassagesibspparchfareembarkedsurvived2sexdeckseatsozinho_parchsozinho_sibspmv_ageage_categorytitlefamily_size
PassengerId
10.0322.0107.0SDiedmaleNaNNaN100612
21.0138.01071.0CSurvivedfemaleC85100942
31.0326.0008.0SSurvivedfemaleNaNNaN110731
41.0135.01053.0SSurvivedfemaleC123100942
50.0335.0008.0SDiedmaleNaNNaN110911
\n", + "
" + ], + "text/plain": [ + " survived pclass age ... age_category title family_size\n", + "PassengerId ... \n", + "1 0.0 3 22.0 ... 6 1 2\n", + "2 1.0 1 38.0 ... 9 4 2\n", + "3 1.0 3 26.0 ... 7 3 1\n", + "4 1.0 1 35.0 ... 9 4 2\n", + "5 0.0 3 35.0 ... 9 1 1\n", + "\n", + "[5 rows x 17 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 282 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "htQ1dODRwfHw", + "outputId": "e7ea64a5-ff9e-4a2e-e4d9-d224192a4a7b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 275 + } + }, + "source": [ + "df.plot.scatter('age','fare', s= 50, c= 'survived')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p6KuSmVpeo_6" + }, + "source": [ + "# Conclusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GxVLsfqXesFC" + }, + "source": [ + "df.head(50)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aidvIN0ZyLx2" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oAIrbEJ5nsiz" + }, + "source": [ + "# Salvar cópia do dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f2ktaBhAnxPi" + }, + "source": [ + "df.to_csv(\"df_3DP_FE1.csv\", sep= ',', index = True, header=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GhB-30cIXtJZ" + }, + "source": [ + "# Exercícios\n", + "* Para cada dataframe a seguir, avalie o que necessita ser feito em termos de qualidade de dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 1 - Predict Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_cancer['target'] = df_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 2 - Predict Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-CawPH2nb5cl" + }, + "source": [ + "## Exercícios 3 - Diabetes\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lVjBS7QcZuT" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB01_02__Condicionais: if, elif, else_hs.ipynb b/Notebooks/NB01_02__Condicionais: if, elif, else_hs.ipynb new file mode 100644 index 000000000..e27c4913c --- /dev/null +++ b/Notebooks/NB01_02__Condicionais: if, elif, else_hs.ipynb @@ -0,0 +1,373 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Notebooks/NB01_02__Condicionais.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Y-QMrzHhpcu" + }, + "source": [ + "

CONDICIONAIS - IF

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wYGZ0eGlv--6" + }, + "source": [ + "# **AGENDA**:\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q3FpTG0dh47M" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWuIj53sVSnA" + }, + "source": [ + "___\n", + "# **CONDICIONAIS**\n", + "> Usado para decidir se uma determinada instrução ou bloco de instruções será executada ou não, isto é, se uma determinada condição for verdadeira, um bloco de instrução será executado." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NyG1l3awJzEq" + }, + "source": [ + "# Não executar o código a seguir:\n", + "if condicao1:\n", + " \n", + "elif condicao2:\n", + " \n", + "elif condicao3:\n", + " \n", + " ...\n", + "elif condicaoN:\n", + " \n", + "else:\n", + " " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FCJBMTh5WX5C" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vn5u7CEaWZjH" + }, + "source": [ + "def mensagem(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lW0ME_nVXU4M" + }, + "source": [ + "mensagem(35, 40)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EBBU8Yw2XxUo" + }, + "source": [ + "Nenhuma mensagem? E agora?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xQ23cAjMX1kx", + "outputId": "3612d39b-3f92-40fd-af14-2dfbca6b0697", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem(45, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "45 é maior que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BeHU0tPuWK4s" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gSzCnjS0Fk-d" + }, + "source": [ + "def mensagem2(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é menor ou igual a {i_limite}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KxbmxuDwYFX_", + "outputId": "8f1faff1-de34-4967-865f-17453f7992af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem2(35, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é menor ou igual a 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lToDO6pzWPGL" + }, + "source": [ + "## Exemplo 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a1NlziSbGrIl", + "outputId": "ffed270b-c16f-4d30-cdaf-80ae96898a94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " \n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " \n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + "print(s_mensagem)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0ms_mensagem\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0;34mf'{i_idade} é maior que {i_limite4}'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms_mensagem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 's_mensagem' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V8FF3lFLYqui" + }, + "source": [ + "Porque temos um erro nesta função?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y5F09RKGYyoX" + }, + "source": [ + "**Resposta**: por causa da indentação! A forma correta é:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vR-oFyzAY5UC" + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QgkBOGKdYgGU", + "outputId": "701f4620-817f-41e0-e9d7-f6b06adf6b3d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "mensagem3(35, 10, 20, 30, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é maior que 30 e menor que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LLk7bhjSwZch" + }, + "source": [ + "___\n", + "# **Wrap Up**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lJvjcjm8NQ85" + }, + "source": [ + "___\n", + "# Exercícios\n", + "## **Exercício 1**: \n", + "Escreva uma função em Python que receba um número inteiro i_limite e, na sequência, imprime os números inteiros de 0 a i_limite;\n", + "\n", + "## **outros exercícios**: \n", + "Nos sites abaixo você vai encontrar exercícios de Python:\n", + "### https://pynative.com/python-if-else-and-for-loop-exercise-with-solutions/;\n", + "### https://www.w3resource.com/python-exercises/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gi091pZrwbnY" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB01_02__Condicionais_hs.ipynb b/Notebooks/NB01_02__Condicionais_hs.ipynb new file mode 100644 index 000000000..bacbbc5eb --- /dev/null +++ b/Notebooks/NB01_02__Condicionais_hs.ipynb @@ -0,0 +1,373 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Notebooks/NB01_02__Condicionais.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Y-QMrzHhpcu" + }, + "source": [ + "

CONDICIONAIS - IF

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wYGZ0eGlv--6" + }, + "source": [ + "# **AGENDA**:\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q3FpTG0dh47M" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWuIj53sVSnA" + }, + "source": [ + "___\n", + "# **CONDICIONAIS**\n", + "> Usado para decidir se uma determinada instrução ou bloco de instruções será executada ou não, isto é, se uma determinada condição for verdadeira, um bloco de instrução será executado." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NyG1l3awJzEq" + }, + "source": [ + "# Não executar o código a seguir:\n", + "if condicao1:\n", + " \n", + "elif condicao2:\n", + " \n", + "elif condicao3:\n", + " \n", + " ...\n", + "elif condicaoN:\n", + " \n", + "else:\n", + " " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FCJBMTh5WX5C" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vn5u7CEaWZjH" + }, + "source": [ + "def mensagem(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lW0ME_nVXU4M" + }, + "source": [ + "mensagem(35, 40)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EBBU8Yw2XxUo" + }, + "source": [ + "Nenhuma mensagem? E agora?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xQ23cAjMX1kx", + "outputId": "3612d39b-3f92-40fd-af14-2dfbca6b0697", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem(45, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "45 é maior que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BeHU0tPuWK4s" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gSzCnjS0Fk-d" + }, + "source": [ + "def mensagem2(i_idade, i_limite):\n", + " if i_idade > i_limite:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é menor ou igual a {i_limite}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KxbmxuDwYFX_", + "outputId": "8f1faff1-de34-4967-865f-17453f7992af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "mensagem2(35, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é menor ou igual a 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lToDO6pzWPGL" + }, + "source": [ + "## Exemplo 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a1NlziSbGrIl", + "outputId": "ffed270b-c16f-4d30-cdaf-80ae96898a94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " \n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " \n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + "print(s_mensagem)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0ms_mensagem\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0;34mf'{i_idade} é maior que {i_limite4}'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms_mensagem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 's_mensagem' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V8FF3lFLYqui" + }, + "source": [ + "Porque temos um erro nesta função?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y5F09RKGYyoX" + }, + "source": [ + "**Resposta**: por causa da indentação! A forma correta é:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vR-oFyzAY5UC" + }, + "source": [ + "def mensagem3(i_idade, i_limite1, i_limite2, i_limite3, i_limite4):\n", + " if ((i_idade > i_limite1) and (i_idade < i_limite2)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite1} e menor que {i_limite2}'\n", + " elif ((i_idade > i_limite3) and (i_idade < i_limite4)):\n", + " s_mensagem= f'{i_idade} é maior que {i_limite3} e menor que {i_limite4}'\n", + " else:\n", + " s_mensagem= f'{i_idade} é maior que {i_limite4}'\n", + " \n", + " print(s_mensagem)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QgkBOGKdYgGU", + "outputId": "701f4620-817f-41e0-e9d7-f6b06adf6b3d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "mensagem3(35, 10, 20, 30, 40)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "35 é maior que 30 e menor que 40\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LLk7bhjSwZch" + }, + "source": [ + "___\n", + "# **Wrap Up**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lJvjcjm8NQ85" + }, + "source": [ + "___\n", + "# Exercícios\n", + "## **Exercício 1**: \n", + "Escreva uma função em Python que receba um número inteiro i_limite e, na sequência, imprime os números inteiros de 0 a i_limite;\n", + "\n", + "## **outros exercícios**: \n", + "Nos sites abaixo você vai encontrar exercícios de Python:\n", + "### https://pynative.com/python-if-else-and-for-loop-exercise-with-solutions/;\n", + "### https://www.w3resource.com/python-exercises/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gi091pZrwbnY" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB02__Numpy_hs.ipynb b/Notebooks/NB02__Numpy_hs.ipynb new file mode 100644 index 000000000..f71a98b7e --- /dev/null +++ b/Notebooks/NB02__Numpy_hs.ipynb @@ -0,0 +1,6176 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB02__Numpy.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6QhLXoatkvKR" + }, + "source": [ + "

NUMPY

\n", + "\n", + "> NumPy é um pacote para computação científica e álgebra linear para Python.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b8EZupp68vW8" + }, + "source": [ + "# **AGENDA**:\n", + "> Neste capítulo, vamos abordar os seguintes assuntos:\n", + "\n", + "* NumPy\n", + "* Criar arrays\n", + "* Criar Arrays Multidimensionais\n", + "* Selecionar itens\n", + "* Aplicar funções como max(), min() e etc\n", + "* Calcular Estatísticas Descritivas: média e variância\n", + "* Reshaping\n", + "* Tansposta de um array\n", + "* Autovalores e Autovetores\n", + "* Wrap Up\n", + "* Exercícios" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cO5t3xCO8kyK" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "\n", + "* Nosso foco com o NumPy é facilitar o uso do Pandas;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z2IFUG4GSB0Z" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jYLeDVH-SNCg" + }, + "source": [ + "![Numpy](https://github.com/MathMachado/Materials/blob/master/numpy_basics-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0mKvExmgUFOk" + }, + "source": [ + "# **ESCALAR, VETORES, MATRIZES E TENSORES**\n", + "\n", + "![Tensor](https://github.com/MathMachado/Materials/blob/master/tensor.png?raw=true)\n", + "\n", + "Source: [PyTorch for Deep Learning: A Quick Guide for Starters](https://towardsdatascience.com/pytorch-for-deep-learning-a-quick-guide-for-starters-5b60d2dbb564)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o00pYRIkXiAU" + }, + "source": [ + "## Import Statement - Primeiros exemplos\n", + "> Como exemplo, considere gerar uma amostra aleatória de tamanho 10 da Distribuição Normal(0, 1):" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l_XuvcUDWNDk" + }, + "source": [ + "## Importar a library NumPy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "am_ZTIGaapCo" + }, + "source": [ + "### **Opção 1**: Importar a biblioteca NumPy COM alias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b4irLw6BWVVZ" + }, + "source": [ + "import numpy as np" + ], + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JK54ga7dXnJu" + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(media, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "a_numeros1 = np.random.normal(media, desvio_padrao, size = 10) # Array 1D de size = 10\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-0934isZUm6" + }, + "source": [ + "**Observação**: Altere o valor de [precision] para 4, 2 e 0 e observe o que acontece." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ob_8S_bYYa2" + }, + "source": [ + "### **Opção 2**: Importar a biblioteca NumPy SEM alias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NcGd1ho_XDXU" + }, + "source": [ + "import numpy" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zFYH6J5-Ydjl" + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "numpy.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "numpy.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(mu, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "numpy.random.normal(size = 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AwWSzYrZWfvA" + }, + "source": [ + "### **Opção 3**: Importar funções específicas da biblioteca NumPy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bfYJzcqRa5eu" + }, + "source": [ + "from numpy import set_printoptions\n", + "from numpy.random import seed, normal" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xj6fbpvubH_p", + "outputId": "35bb3776-a9c6-4352-f00d-02552a987e47", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(mu, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1 \n", + "np.random.normal(size = 10)" + ], + "execution_count": 4, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 2.51, 1.11, 2.06, 0.56, 0.3 , 1.05, -0.13, 1.06, 1.14,\n", + " 1.38])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 4 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7nC6S2hpGIRF" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "00RerJPChnuP" + }, + "source": [ + "___\n", + "# **Estatísticas Descriticas com NumPy**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qa6ro1VJlShd" + }, + "source": [ + "## Exemplo 1\n", + "> Vamos voltar ao mesmo exemplo anterior, mas desta vez, usando a opção 1 (com alias):\n", + "\n", + "* Gerar uma amostra aleatória de tamanho 10 da Distribuiçao Normal(0, 1)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "31dSBU8khvFk", + "outputId": "b1e515e2-6f14-4d72-e859-18d2b0ad14db", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "# Define seed\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(media, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "\n", + "np.random\n", + "a_numeros1 = np.random.normal(media, desvio_padrao, size = 10) # Array 1D de size = 10\n", + "a_numeros1" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 2.51, 1.11, 2.06, 0.56, 0.3 , 1.05, -0.13, 1.06, 1.14,\n", + " 1.38])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aT7LNdLyG7Mf", + "outputId": "a0f0f45d-0d0a-4292-f8a6-816d8c1cd36f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.mean(a_numeros1)" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1.1043374540652753" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vu3qg9LKHV7H", + "outputId": "143c7e96-09e0-48d4-9882-1a2464be3889", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.std(a_numeros1)" + ], + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.735246705657231" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wa2t0P3nevTh" + }, + "source": [ + "Conferindo a média e desvio-padrão do array gerado:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "drUyk3f5ekDq", + "outputId": "a550f2ef-f2ab-4867-f55c-79ddc3ec4552", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Distribuição N({np.mean(a_numeros1)}, {np.std(a_numeros1)})'" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Distribuição N(1.1043374540652753, 0.735246705657231)'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XSp7Hd-Gib67" + }, + "source": [ + "Estávamos à espera de media = 0 e sigma = 1. Certo? Porque isso não aconteceu?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HP_8VSgygXOF" + }, + "source": [ + "## **Laboratório 1**\n", + "> Altere os valores de [size] para 100, 1.000, 10.000, 100.000 e 1.000.000 e relate o que acontece com a média e desvio padrão." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4TbmVbdcg6iU" + }, + "source": [ + "## **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-qdiqBVHg-gd", + "outputId": "52e5582c-e6bd-4f58-8c92-cc1190464723", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "# Define a média e o desvio-padrão\n", + "media = 0\n", + "desvio_padrao = 1\n", + "\n", + "# Define seed\n", + "np.random.seed(seed = 20111974)\n", + "l_lista_numeros = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]\n", + "\n", + "for i_size in l_lista_numeros:\n", + " a_numeros1 = np.random.normal(media, desvio_padrao, size = i_size)\n", + " print(f'Size: {i_size}--> Distribuição: N({np.mean(a_numeros1)}, {np.std(a_numeros1)})')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Size: 10--> Distribuição: N(1.1043374540652753, 0.735246705657231)\n", + "Size: 100--> Distribuição: N(-0.14020525697186714, 0.9254100654233511)\n", + "Size: 1000--> Distribuição: N(0.021644923462910873, 1.0054417533501039)\n", + "Size: 10000--> Distribuição: N(0.015499353804764507, 0.9970905566844254)\n", + "Size: 100000--> Distribuição: N(0.002039323041103302, 0.9960906293570095)\n", + "Size: 1000000--> Distribuição: N(-1.1062145143945444e-06, 0.999473966169304)\n", + "Size: 10000000--> Distribuição: N(0.0002892972723094128, 1.0001202837422036)\n", + "Size: 100000000--> Distribuição: N(0.00011967896623555603, 0.999944390106086)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bp-YuviQwWqE" + }, + "source": [ + "Com relação à Distribuição Normal($\\mu, \\sigma$), temos que:\n", + "\n", + "![NormalDistribution](https://github.com/MathMachado/Materials/blob/master/NormalDistribution.PNG?raw=true)\n", + "\n", + "Fonte: [Normal Distribution](https://towardsdatascience.com/understanding-the-68-95-99-7-rule-for-a-normal-distribution-b7b7cbf760c2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KwHBY3Enk04N" + }, + "source": [ + "## Lei Forte dos Grandes Números - LFGN\n", + "> Por favor, leia o que diz a [Law of large numbers](https://en.wikipedia.org/wiki/Law_of_large_numbers). --> 3 minutos.\n", + "\n", + "* O que você aprendeu com isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BhwmSkAjlszT" + }, + "source": [ + "## Exemplo 2\n", + "> Vamos nos aprofundar um pouco mais no que diz a LFGN. Para isso, vamos simular o lançamento de dados. Como sabemos, os dados possuem 6 lados numerados de 1 a 6, com igual probabilidade. Certo?\n", + "\n", + "A LFGN nos diz que à medida que N (o tamanho da amostra ou número de dados) cresce, então a média dos dados converge para o valor esperado. Isso quer dizer que:\n", + "\n", + "$$\\frac{1+2+3+4+5+6}{6}= \\frac{21}{6}= 3,5$$\n", + "\n", + "Ou seja, à medida que N (o tamanho da amostra) cresce, espera-se que a média dos dados se aproxime de 3,5. Ok?\n", + "\n", + "Vamos ver se isso é verdade..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-QcJXf6roj0D" + }, + "source": [ + "Vamos usar o método np.random.randint (= função randint definido na classe np.random), a seguir:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A2u0RzLOrRE2" + }, + "source": [ + "O que significa ou qual é a interpretação do resultado abaixo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B3-X_VBerUfa", + "outputId": "c55bbf0c-4ff6-46ec-c54d-15bfea2d7b20", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# Define seed\n", + "import numpy as np\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Simular 100 lançamentos de um dado:\n", + "a_dados_simulados = np.random.randint(1, 7, size = 100)\n", + "a_dados_simulados" + ], + "execution_count": 1, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4, 5, 3, 1, 1, 4, 3, 1, 2, 2, 1, 1, 6, 4, 5, 3, 1, 4, 1, 6, 2, 4,\n", + " 6, 2, 4, 3, 2, 6, 3, 6, 2, 6, 1, 3, 1, 2, 4, 2, 4, 6, 3, 2, 6, 1,\n", + " 4, 3, 6, 5, 2, 3, 3, 3, 3, 2, 1, 6, 2, 1, 2, 3, 1, 5, 6, 6, 6, 6,\n", + " 5, 6, 6, 5, 6, 3, 3, 2, 4, 2, 6, 1, 2, 3, 4, 5, 5, 3, 1, 6, 6, 5,\n", + " 5, 1, 4, 6, 2, 2, 4, 3, 6, 1, 5, 5])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 1 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m8Of2MMIrbF3", + "outputId": "d362e33e-4b05-4a06-d231-31c9517341bd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 136 + } + }, + "source": [ + "# Importar o pandas, pois vamos precisar do método pd.value_counts():\n", + "import pandas as pd\n", + "pd.value_counts(a_dados_simulados)" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "6 22\n", + "3 18\n", + "2 18\n", + "1 17\n", + "4 13\n", + "5 12\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "54VwED8Br8rx" + }, + "source": [ + "**Interpretação**: Isso quer dizer que fizemos a simulação de lançamento de um dado 100 vezes. Acima, a frequência com que cada lado do dado aparece.\n", + "\n", + "Eu estava à espera de frequência igual para cada um dos lados, isto é, por volta dos 16 ou 17. Ou seja:\n", + "\n", + "$$\\frac{100}{6}= 16,66$$\n", + "\n", + "Mas ok, vamos continuar com nosso experimento..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HT_Dak-umC6I", + "outputId": "45e74f5f-7c2c-4a85-daf8-ff37831f790e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "# Definir a semente\n", + "np.random.seed(20111974)\n", + "\n", + "for i_size in [10, 30, 50, 75, 100, 1000, 10000, 100000, 1000000]:\n", + " a_dados_simulados = np.random.randint(1, 7, size = i_size)\n", + " print(f'Size: {i_size} --> Média: {np.mean(a_dados_simulados)}')" + ], + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Size: 10 --> Média: 2.6\n", + "Size: 30 --> Média: 3.3666666666666667\n", + "Size: 50 --> Média: 3.72\n", + "Size: 75 --> Média: 3.2666666666666666\n", + "Size: 100 --> Média: 3.42\n", + "Size: 1000 --> Média: 3.461\n", + "Size: 10000 --> Média: 3.5259\n", + "Size: 100000 --> Média: 3.50794\n", + "Size: 1000000 --> Média: 3.50151\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "edWNNOnXtbtd" + }, + "source": [ + "E agora, como você interpreta esses resultados?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eL6gXThkYcSf" + }, + "source": [ + "## Calcular percentis\n", + "> Boxplot" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jlGOQfXfPf0D" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "grtEXG2BoNRt" + }, + "source": [ + "Considere o array de retornos (simulados) a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DjPKKq01YjF9", + "outputId": "71a8f79c-54d0-4d00-faef-27d2be4ccf89", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "import numpy as np\n", + "np.random.seed(20111974)\n", + "\n", + "# Simulando Retornos de ativos financeiros com a distribuição Normal(0, 1):\n", + "a_retornos = np.random.normal(0, 1, 100)\n", + "print(f'Média: {np.mean(a_retornos)}')" + ], + "execution_count": 4, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média: -0.016996335492713833\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ajjlfqgssLVO", + "outputId": "955f617e-2a59-403d-c1cf-f6e3fb5d76c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "a_retornos" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632, 1.13807032, 1.37966044,\n", + " -2.05995563, 0.67474814, 0.72722843, -0.33923852, 0.43613107,\n", + " 0.59135489, -1.29281877, 1.17712036, -0.98644163, -1.79034143,\n", + " -1.08913605, -0.90712825, -1.02291108, -1.36445713, -0.29429164,\n", + " 0.06343709, -1.14196185, -0.50706079, -0.83539436, -1.41492946,\n", + " -0.2159062 , -1.16519474, -0.60767518, -0.61510925, 1.0771542 ,\n", + " 0.5043687 , 0.02674197, 1.83494644, 0.34728874, -1.14671885,\n", + " -0.59841423, -0.42698353, 0.10901983, -0.75168457, 0.71689294,\n", + " -0.50810299, 0.47524103, -0.38248511, -1.37491973, 1.5355728 ,\n", + " -0.27356178, 0.68072592, -1.80454873, 1.16995833, -0.37988822,\n", + " 0.19305861, 1.53792436, -0.11802807, -0.97621103, -1.23463994,\n", + " 1.0504434 , 1.91481015, 0.80359454, 0.35869561, 1.03409992,\n", + " -0.37200685, 0.32947575, 0.70038627, -0.98085533, -1.21072144,\n", + " 0.74366412, 0.18372348, 0.10430302, -0.78160841, -0.0423915 ,\n", + " 1.67094293, -1.07256479, -0.5493723 , -1.83082917, 0.11510819,\n", + " 1.3911365 , -0.28940563, 0.31904722, -0.70009623, -0.4353552 ,\n", + " -2.0301258 , -0.14205882, 1.66292963, -0.57691495, -0.78963384,\n", + " -0.80660503, 0.05581487, 0.8715663 , -0.3499477 , 1.37366912,\n", + " 0.88027638, -1.47925906, -0.40657104, -0.18789895, 0.47475142])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XZ3m06gv9lei" + }, + "source": [ + "A seguir, o boxplot do array a_retornos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QtuwJP449tBQ", + "outputId": "4e8bf67a-7227-4287-f757-4f079c21d3b2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "# Import da biblioteca seaborn: Uma das principais libraries para Data Visualization (outras: matplotlib)\n", + "import seaborn as sns\n", + "\n", + "sns.boxplot(y = a_retornos)" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAADrCAYAAAB0Oh02AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAIPUlEQVR4nO3d3YtdVxnH8d/TxJeIikiHCqMxyogiIgiDIF4I6kXtjSgIeiGIQvTCYQRBlP4JghAGbwKKN6I3WhSM+AKCCCpORKS1UQ6C2MGX0YIWEpXY5YUR25pmzuRsZ5+n+XwgkLNnZu2HkHxZWdknU2OMANDXXXMPAMBqhBygOSEHaE7IAZoTcoDmhBygudNz3PTuu+8e586dm+PWAG1dvnz5T2OMjadenyXk586dy/7+/hy3Bmirqn5zs+uOVgCaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoLlZniNnfezt7WWxWMw9xlo4ODhIkmxubs48yXrY2trKzs7O3GOwBCGHG65duzb3CHBbhPwOZ8f1X7u7u0mSCxcuzDwJHI8zcoDmhBygOSEHaE7IAZoTcoDmhBygOSEHaE7IAZoTcoDmhBygOSEHaE7IAZoTcoDmhBygOSEHaE7IAZpbOeRV9bKq+l5V/aKqHqqq3SkGA2A5U3yHoOtJPj7G+GlVvSDJ5ar6zhjjFxOsDcARVt6RjzF+N8b46Y2fP5bk4SS+ey3ACZn0jLyqziV5Q5IfT7kuAE9vspBX1fOTfCXJx8YYf73Jx89X1X5V7R8eHk51W4A73iQhr6pn5d8R/+IY46s3+5wxxsUxxvYYY3tjY2OK2wKQaZ5aqSSfS/LwGOMzq48EwHFMsSN/c5L3J3lrVf3sxo/7JlgXgCWs/PjhGOMHSWqCWQC4Dd7ZCdCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0J+QAzQk5QHNCDtCckAM0N0nIq+rzVfXHqnpwivUAWN5UO/IvJLl3orUAOIZJQj7G+H6SR6dYC4DjcUYO0NyJhbyqzlfVflXtHx4entRtAZ7xTizkY4yLY4ztMcb2xsbGSd0W4BnP0QpAc1M9fvilJD9M8uqqeqSqPjTFugAc7fQUi4wx3jfFOgAcn6MVgOaEHKA5IQdoTsgBmhNygOaEHKC5SR4/7GZvby+LxWLuMVgz//k9sbu7O/MkrJutra3s7OzMPcbTuiNDvlgs8rMHH84/n/fiuUdhjdz1j5EkufzrP8w8Cevk1NX1/49d78iQJ8k/n/fiXHvNfXOPAay5M1cuzT3CkZyRAzQn5ADNCTlAc0IO0JyQAzQn5ADNCTlAc0IO0JyQAzQn5ADNCTlAc0IO0JyQAzQn5ADNCTlAc0IO0JyQAzQn5ADNCTlAc0IO0JyQAzQn5ADNCTlAc0IO0JyQAzQn5ADNTRLyqrq3qn5ZVYuq+uQUawKwnJVDXlWnknw2yTuSvDbJ+6rqtauuC8ByptiRvzHJYozx6zHGP5J8Ock7J1gXgCVMEfLNJL99wutHblx7kqo6X1X7VbV/eHg4wW0BSE7wHzvHGBfHGNtjjO2NjY2Tui3AM94UIT9I8rInvH7pjWsAnIApQv6TJK+qqldU1bOTvDfJ1ydYF4AlnF51gTHG9ar6aJJvJTmV5PNjjIdWngyApawc8iQZY1xKcmmKtU7CwcFBTl39S85caTMyMJNTV/+cg4Prc49xS97ZCdDcJDvybjY3N/P7v5/OtdfcN/cowJo7c+VSNjfvmXuMW7IjB2hOyAGaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoDkhB2hOyAGaE3KA5oQcoDkhB2ju9NwDzOXU1Udz5sqlucdgjdz1t78mSR5/7gtnnoR1curqo0numXuMW7ojQ761tTX3CKyhxeKxJMnWK9f7Dy0n7Z61b8YdGfKdnZ25R2AN7e7uJkkuXLgw8yRwPM7IAZoTcoDmhBygOSEHaG6lkFfVe6rqoap6vKq2pxoKgOWtuiN/MMm7k3x/glkAuA0rPX44xng4SapqmmkAODZn5ADNHbkjr6rvJnnJTT50/xjja8veqKrOJzmfJGfPnl16QABu7ciQjzHePsWNxhgXk1xMku3t7THFmgA4WgFob9XHD99VVY8keVOSb1TVt6YZC4BlrfrUygNJHphoFgBug6MVgOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKA5IQdoTsgBmhNygOaEHKC5lUJeVZ+uqitV9fOqeqCqXjTVYAAsZ9Ud+XeSvG6M8fokv0ryqdVHAuA4Vgr5GOPbY4zrN17+KMlLVx8JgOOY8oz8g0m+OeF6ACzh9FGfUFXfTfKSm3zo/jHG1258zv1Jrif54i3WOZ/kfJKcPXv2toYF4H/VGGO1Bao+kOTDSd42xri6zNdsb2+P/f39le7LNPb29rJYLOYeYy3859dha2tr5knWw9bWVnZ2duYegyeoqstjjO2nXj9yR37Eovcm+USStywbcVhXZ86cmXsEuC0r7cirapHkOUn+fOPSj8YYHznq6+zIAY7v/7IjH2P4OyjAzLyzE6A5IQdoTsgBmhNygOaEHKA5IQdoTsgBmlv5Lfq3ddOqwyS/OfEbw9HuTvKnuYeAp/HyMcbGUy/OEnJYV1W1f7N3zsE6c7QC0JyQAzQn5PBkF+ceAI7LGTlAc3bkAM0JOUBzQg7QnJADNCfkAM39C46PaZwmexaoAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9ujdjxNY6qE" + }, + "source": [ + "# Vamos usar o método np.percentile(array, q = [p1, p2, p3, ..., p99])\n", + "percentis = np.percentile(a_retornos, q = [1, 5, 25, 50, 55, 75, 99])\n", + "\n", + "# Primeiro Quartil\n", + "q1 = percentis[2]" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AbOH4m6JR_lR", + "outputId": "f0d97c35-cc96-48a4-e354-95db5dbb8528", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "percentis" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-2.0304241 , -1.49481318, -0.78361477, -0.12205087, 0.08182676,\n", + " 0.71947681, 2.06016123])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c75g2Egco2lc" + }, + "source": [ + "Em qual posição do array a_retornos se encontra Q3?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nZr-A82Zo8Kb", + "outputId": "49f16b21-0184-42e5-d732-d8d68d495ef0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "q3 = percentis[5]\n", + "\n", + "# ou de trás para a frente do conteúdo da lista:\n", + "q3_2 = percentis[-2]\n", + "print(q3, q3_2)" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0.7194768106252311 0.7194768106252311\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sWrnESPQT4JM" + }, + "source": [ + "# lim_inferior e lim_superior para detecção de outliers\n", + "lim_inferior = q1 - 1.5 * (q3 - q1)\n", + "lim_superior = q3 + 1.5 * (q3 - q1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yb4-ZJlUUYsi" + }, + "source": [ + "f'Limite Inferior: {lim_inferior}; Limite Superior: {lim_superior}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jr6oXIHlUxOe" + }, + "source": [ + "np.min(a_retornos)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UxE47cN0U54X" + }, + "source": [ + "np.max(a_retornos)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OTB9HnIac499" + }, + "source": [ + "___\n", + "# **Ordenar itens de um array**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jgj8Yw46dBMx" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.random(10)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cC9272GFdRln" + }, + "source": [ + "Ordenando os itens de a_numeros1..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YUP90nBVdUeF" + }, + "source": [ + "np.sort(a_numeros1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lG763cDGj-yB" + }, + "source": [ + "___\n", + "# **Obter ajuda**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ehxPlD3EkEYL" + }, + "source": [ + "help(np.random.normal)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1Q_konJVaBsV" + }, + "source": [ + "___\n", + "# **Criar arrays 1D**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DddZT5kadYJ7" + }, + "source": [ + "import numpy as np\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "np.random.seed(seed = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jaqd-VnF3yIt" + }, + "source": [ + "Criar o array 1D a_numeros1, com os seguintes números:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3niz_zHaF3e" + }, + "source": [ + "a_numeros1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyfXbW_ZKJBS" + }, + "source": [ + "Qual a dimensão de a_numeros1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gbHlydALKB3R" + }, + "source": [ + "# Dimensão do array\n", + "a_numeros1.ndim" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "am9otElpKNPa" + }, + "source": [ + "Qual o shape (dimensão) do array a_numeros1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "juJJ74d2wale" + }, + "source": [ + "# Números de itens no array\n", + "a_numeros1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BHg4Rre3GwPy" + }, + "source": [ + "O array a_numeros1 poderia ter sido criado usando a função np.arange(inicio, fim, step):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I3fyusN7G5Zn" + }, + "source": [ + "# Lembre-se que o número 10 é exclusive.\n", + "a_numeros2 = np.arange(start = 0, stop = 10, step = 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IHCEpmUxXsaK" + }, + "source": [ + "Outra alternativa seria usar np.linspace(start = 0, stop = 10, num = 9). Acompanhe a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JB9Y_x3RX1GX" + }, + "source": [ + "# Com np.linspace, o valor 9 é inclusive.\n", + "a_numeros3 = np.linspace(0, 9, 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P6MR8MPeYOZm" + }, + "source": [ + "Compare os resultados de a_numeros1, a_numeros2 e a_numeros3 a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tWEzge6HYSFu" + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lUNlFVKYYT9f" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xo8Lid5fYVPW" + }, + "source": [ + "a_numeros3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V9aW7C4vHAcF" + }, + "source": [ + "Ou seja, a_numeros1 é igual a a_numeros2 que também é igual a a_numeros3. Ok?\n", + "\n", + "**ATENÇÃO**: Observe que a sintaxe para criar a_numeros3 é ligeiramente diferente da sintaxe usada para criar a_numeros1 e a_numeros2. Abaixo, a sintaxe do comando np.linspace:\n", + "\n", + "![](https://github.com/MathMachado/Materials/blob/master/linspace_sintaxe.PNG?raw=true)\n", + "\n", + "Source: [HOW TO USE THE NUMPY LINSPACE FUNCTION](https://www.sharpsightlabs.com/blog/numpy-linspace/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KNnwZa3uvYqE" + }, + "source": [ + "Soma 2 à cada item de a_numeros1:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jt2KVyviw0bp" + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "arROkhWXbdTW" + }, + "source": [ + "a_numeros2 = a_numeros1 + 2\n", + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJx2vG86vdVi" + }, + "source": [ + "Multiplicar por 10 cada item de a_numeros1:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vm7abO6Ebkun" + }, + "source": [ + "a_numeros1 = a_numeros1*10\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0Ev1xnBwaYJG" + }, + "source": [ + "___\n", + "# **Criar Arrays Multidimensionais**\n", + "> Ao criarmos, por exemplo, um array 2D, então a chamamos de matriz." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gHaeAug5vjjd" + }, + "source": [ + "Criar o array com 2 linhas e 3 colunas usando números aleatórios:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VDi0vIPSYR4F" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randn(2, 3)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DIdd-nA3tJjV" + }, + "source": [ + "## Dimensão de um array\n", + "> Dimensão é o número de linhas e colunas da matriz." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pKvjjnkrK-v7" + }, + "source": [ + "a_numeros1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-DHS5jXELCfa" + }, + "source": [ + "a_numeros1 é um array 2D (ou matriz), ou seja, 2 linhas, onde cada linha tem 3 elementos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HJI6X1wvv4Bg" + }, + "source": [ + "Criar um array com 3 linhas e 3 colunas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hXPbWh3Tv26T" + }, + "source": [ + "a_numeros2 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])\n", + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "we6ZJOICc7bQ" + }, + "source": [ + "# Número de linhas e colunas de a_numeros1:\n", + "a_numeros1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f0ocwuI1dED6" + }, + "source": [ + "# Número de linhas e colunas de a_numeros2\n", + "a_numeros2.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CApPtnW0YuRP" + }, + "source": [ + "# Somar 2 à cada elemento de a_numeros2\n", + "a_numeros2 = a_numeros2+2\n", + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M87aGmxRY3RW" + }, + "source": [ + "# Multiplicar por 10 cada elemento de a_numeros2\n", + "a_numeros2 = a_numeros2*10\n", + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qZt93y1IL_v7" + }, + "source": [ + "___\n", + "# **Copiar arrays**\n", + "> Considere o array abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sH2FTXj5MRRC" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randn(2, 3)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VtgKeMt6MYrr" + }, + "source": [ + "Fazendo a cópia de a_numeros1..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "K0hOHR3IMa-o" + }, + "source": [ + "a_numeros1_copia = a_numeros1.copy()\n", + "a_numeros1_copia" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lFpmcR0HkCar" + }, + "source": [ + "___\n", + "# **Operações com arrays**\n", + "> Considere um array com temperaturas em Farenheit dado por:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VnagcUqVkLhW" + }, + "source": [ + "# Define a seed\n", + "np.random.seed(20111974)\n", + "\n", + "a_temperatura_farenheit = np.array(np.random.randint(0, 100, 10))\n", + "a_temperatura_farenheit " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VrjNKfXxk1yv" + }, + "source": [ + "type(a_temperatura_farenheit)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o1STejhrk0kZ" + }, + "source": [ + "Transformando a temperatura Fahrenheit em Celsius..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E_jXflR_lNy3" + }, + "source": [ + "a_temperatura_celsius = 5*a_temperatura_farenheit/9 - 5*32/9\n", + "a_temperatura_celsius" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U4pCv0pNqPZI" + }, + "source": [ + "# O mesmo resultado, porém, escrito de forma diferente:\n", + "a_temperatura_celsius = (5/9)*a_temperatura_farenheit - (160/9)\n", + "a_temperatura_celsius" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UT4YD2FawUA" + }, + "source": [ + "___\n", + "# **Selecionar itens**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pqOv8P1za1m8" + }, + "source": [ + "# Selecionar o segundo item de a_numeros1 (lembre-se que no Python arrays começam com indice = 0)\n", + "a_numeros1[1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TIwVKk6AyRv6" + }, + "source": [ + "Dado a_numeros2 abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zoDmbXo6bCeu" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iJXSPp-0yb4w" + }, + "source": [ + "... selecionar o item da linha 2, coluna 3 do array a_numeros2:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sJiVfnlzcjRv" + }, + "source": [ + "a_numeros2[1, 2]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xl5HwJIMcv2e" + }, + "source": [ + "# Selecionar o último elemento de a_numeros1 --> Lembre-se que a_numeros1 é um array. Desta forma, teremos o último elemento do array!\n", + "a_numeros1[-1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ezTH0HsyrnAl" + }, + "source": [ + "Veja..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OBv9EM54rYX3" + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Po3WLFC-rod8" + }, + "source": [ + "a_temperatura_celsius[-1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4qJJ2HCedW4h" + }, + "source": [ + "___\n", + "# **Aplicar funções como max(), min() e etc**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_meTJdUsda4e" + }, + "source": [ + "f'O máximo de a_numeros1 é: {np.max(a_numeros1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m-wiBkAidnhN" + }, + "source": [ + "f'O mínimo de a_numeros1 é: {np.min(a_numeros1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lmupnRHQdtwh" + }, + "source": [ + "f'O máximo de a_numeros2 é: {np.max(a_numeros2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "H2z7oB6Bd786" + }, + "source": [ + "f'O máximo de cada LINHA de a_numeros2 é: {np.max(a_numeros2, axis = 1)}' # Aqui, axis = 1 é que diz ao numpy que estamos interessados nas linhas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gj2ZBDsWeMyk" + }, + "source": [ + "f'O máximo de cada COLUNA de a_numeros2 é: {np.max(a_numeros2, axis = 0)}' # axis = 0, diz ao numpy que estamos interessados nas colunas." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7_tEfm2IecIU" + }, + "source": [ + "___\n", + "# **Calcular Estatísticas Descritivas: média e variância**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lIY5jx3ueh7q" + }, + "source": [ + "f'A média de a_numeros1 é: {np.mean(a_numeros1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VmqSELRReuAW" + }, + "source": [ + "f'A média de a_numeros2 é: {np.mean(a_numeros2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gxap-Wg5e2_H" + }, + "source": [ + "f'O Desvio Padrão de a_numeros2 é: {np.std(a_numeros2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R0GcljGtfBvP" + }, + "source": [ + "___\n", + "# **Reshaping**\n", + "> Muito útil em Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vfEmw01j8zux" + }, + "source": [ + "## Exemplo 1\n", + "* O array a_numeros2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-Lb3VZCCfK_a" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YWN_nN-4fD7u" + }, + "source": [ + "# reshaping para 9 linhas e 1 coluna:\n", + "a_numeros2.reshape(9, 1) # a_numeros2.reshape(9,-1) produz o mesmo resultado." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id9ILRRt7SwY" + }, + "source": [ + "## Mais um exemplo de Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9RA9Ht2b7Swd", + "outputId": "eadedfd5-fd6c-49c8-db5c-6f8f30d45f36", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(1, 10, size = 15))\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8KxR4xZT7cRv" + }, + "source": [ + "### Solução\n", + "> Temos 15 elementos em a_numeros1 para construir (\"reshape\") um array 3D com 2 colunas.\n", + "\n", + "A princípio, a solução seria..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VMdHl1Il7wLw", + "outputId": "d51c7263-f523-4af8-9606-ee93cab66f1c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "a_numeros1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "ValueError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma_numeros1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mValueError\u001b[0m: cannot reshape array of size 15 into shape (2)" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pZS4b4-y708q" + }, + "source": [ + "Porque temos esse erro?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4disywvR8HeH" + }, + "source": [ + "E se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3oEAAXTp8I7Z", + "outputId": "e8c8a90f-c34a-4304-d9b4-fd7f04ce224f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(1, 10, size = 16)) # Observe que agora temos 16 elementos\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4, 3])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iUhth0QV8Rpt" + }, + "source": [ + "Reshapping..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9D1y7uD88Qip", + "outputId": "e7d22bcd-c10f-4ea3-e41b-03f6f98a054f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 151 + } + }, + "source": [ + "a_numeros1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9],\n", + " [3, 9],\n", + " [2, 9],\n", + " [1, 5],\n", + " [3, 1],\n", + " [9, 4],\n", + " [8, 2],\n", + " [4, 3]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ALh-sq7DMnN5", + "outputId": "db373349-7910-4f1f-93f3-8ac8f67da8b8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 151 + } + }, + "source": [ + "# OU --> Neste caso, estamos reshaping o array em 8 linhas e 2 colunas\n", + "a_numeros1.reshape(8, -1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9],\n", + " [3, 9],\n", + " [2, 9],\n", + " [1, 5],\n", + " [3, 1],\n", + " [9, 4],\n", + " [8, 2],\n", + " [4, 3]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yvTnrszn8Yk0" + }, + "source": [ + "Porque agora deu certo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LeQ9LqIE8baG" + }, + "source": [ + "## Último exemplo com reshape\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OQOC9iiN8hZT" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randn(2, 3)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cvce8qBl9Cvq" + }, + "source": [ + "Queremos agora transformá-la num array de 3 linhas e 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QDDsYoVt9Klz" + }, + "source": [ + "a_numeros1.reshape(-1, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AdwU5ygt9Svq" + }, + "source": [ + "Poderia ser..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5uBeokKc9Uo-" + }, + "source": [ + "a_numeros1.reshape(3, -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OeRBsobc9aKj" + }, + "source": [ + "E por fim, também poderia ser..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MDt8UYYH9dBw" + }, + "source": [ + "a_numeros1.reshape(3, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "91o5vycQfdKW" + }, + "source": [ + "___\n", + "# **Transposta**\n", + "* O array a_numeros2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RsZwyuhoffjb" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A3MzTVoGfiyO" + }, + "source": [ + "# Transposta do array a_numeros2 é dado por:\n", + "a_numeros2.T" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ij-ZW5IyzXIb" + }, + "source": [ + "Ou seja, linha virou coluna. Ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qLy6ajgpt3lU" + }, + "source": [ + "# **Inversa da matriz quadrada**\n", + "> Se uma matriz é não-singular, então sua inversa existe.\n", + "\n", + "* Se o determinante de uma matriz is not equal to zero, then the matrix isé diferente de 0, então a matriz é não-singular." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-u7jRq34t9_x" + }, + "source": [ + "import numpy as np\n", + "\n", + "a_numeros1 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])\n", + "a_numeros2 = np.array([[6, 2], [5, 3]])\n", + "a_numeros3 = np.array([[1, 3, 5],[2, 5, 1],[2, 3, 8]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7zmHHWWlvaYB" + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3fHKyhOJvcak" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vQG7yyfjwLg9" + }, + "source": [ + "a_numeros3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qa2Yre2rwgRk" + }, + "source": [ + "## Determinantes da matriz quadrada" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N6jwuC6twkyc" + }, + "source": [ + "np.linalg.det(a_numeros1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QSvViNwzwnhI" + }, + "source": [ + "np.linalg.det(a_numeros2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o8jwsnccw5id" + }, + "source": [ + "np.linalg.det(a_numeros3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kkVaTgzgw_XJ" + }, + "source": [ + "A seguir, calculamos as inversas das matrizes acima definidas..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b9FgWvTYvpik" + }, + "source": [ + "np.linalg.inv(a_numeros2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KsdEt1kIvsM_" + }, + "source": [ + "np.linalg.inv(a_numeros1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VA_F7_7kccpn" + }, + "source": [ + "Porque não temos a inversa de a_numeros1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ANPBCnmVwOf4" + }, + "source": [ + "np.linalg.inv(a_numeros3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XAf9k1egxcdF" + }, + "source": [ + "# **Resolver sistemas de equações lineares**\n", + "> Considere o sistema de euqações lineares abaixo:\n", + "\n", + "\\begin{equation}\n", + "x + 3y + 5z = 10\\\\\n", + "2x+ 5y + z = 8 \\\\\n", + "2x + 3y + 8z= 3\n", + "\\end{equation}\n", + "\n", + "Ou $Ax = b$. A solução deste sistema de equações é dada por $A^{-1}b$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oNf5nqaLxhBY" + }, + "source": [ + "Ou seja, basta encontrarmos a inversa de A e multiplicarmos por b." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "omzC5dGA0btc" + }, + "source": [ + "A= np.array([[1, 3, 5], [2, 5, 1], [2, 3, 8]])\n", + "np.linalg.inv(A)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AiXI3oxB05iE" + }, + "source": [ + "Agora basta multiplicar a matriz inversa $A^{-1}$ acima por b. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XoGebKDa2Fcd" + }, + "source": [ + "A_Inv = np.linalg.inv(A)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sKaP0a1QZG-P" + }, + "source": [ + "b= np.array([10, 8, 3]).reshape(3, -1)\n", + "b" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3dAVq8dg19VI" + }, + "source": [ + "A_Inv.dot(b)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zso6hTnB17cm" + }, + "source": [ + "Uma forma fácil de se fazer isso é utilizar a expressão abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ptQHIVll1E4P" + }, + "source": [ + "b= np.array([[10], [8], [3]])\n", + "b" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X4VL8lyY1Xus" + }, + "source": [ + "np.linalg.solve(A, b)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fJKmwTS59-Bc" + }, + "source": [ + "# **Empilhar arrays**\n", + "\n", + "## Exemplo 1\n", + "\n", + "![Empilhar1](https://github.com/MathMachado/Materials/blob/master/Empilhar1.PNG?raw=true)\n", + "\n", + "## Exemplo 2\n", + "\n", + "![Empilhar2](https://github.com/MathMachado/Materials/blob/master/Empilhar2.PNG?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rhPTt3EwXden" + }, + "source": [ + "## Gerar os arrays do exemplo1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zEI-yBy3-E46" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randn(5, 8)\n", + "\n", + "np.random.seed(19741120)\n", + "a_numeros2 = np.random.randn(8, 8)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UYsAqBRp--79" + }, + "source": [ + "## Método 1 - Concatenate([A, B])" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgO1ujvhObyE", + "outputId": "c40e7ed9-255b-4886-dddf-3b17f2b1be2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2aQY_klZOeg9", + "outputId": "14eb3d9c-d0fc-4b6a-fe19-1790695c838f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 289 + } + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bK70vaq8_KMH", + "outputId": "f6d400cf-4b54-4990-815b-052f5224aadd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.concatenate([a_numeros1, a_numeros2], axis = 0) # axis= 0 diz ao NumPy para empilhar as linhas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CpaXBkm8_BF8" + }, + "source": [ + "## Método 2 - np.r_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3QnVUzAY_teZ", + "outputId": "e8adfd85-e760-40f5-d9ac-48353d24ccd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.r_[a_numeros1, a_numeros2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XmSPbDP6_20W" + }, + "source": [ + "**Obs**.: Eu prefiro este método!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dzVKW_wX_Dzw" + }, + "source": [ + "## Método 3 - np.vstack([A, B]) = np.r_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uL7lEN_mABID", + "outputId": "d1ea4d86-2cc1-4e2d-af72-b3a292ef15fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.vstack([a_numeros1, a_numeros2])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "68icJ-2ZAdRj" + }, + "source": [ + "# Concatenar arrays\n", + "\n", + "## Exemplo 1\n", + "\n", + "![Concatenar1](https://github.com/MathMachado/Materials/blob/master/Concatenar1.PNG?raw=true)\n", + "\n", + "# Exemplo 2\n", + "\n", + "![Concatenar2](https://github.com/MathMachado/Materials/blob/master/Concatenar2.PNG?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OplgK9YoQi9o" + }, + "source": [ + "## Concatenar os elementos de dois arrays - np.c_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lpdsbTEKQ9EY" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randint(0, 10, 100).reshape(-1, 10)\n", + "a_numeros2 = np.random.randint(0, 2, 10).reshape(-1, 1)" + ], + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JPxhGsaSSMk2", + "outputId": "700ec21b-ab45-4b58-d302-2a5861349678", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 8, 2, 8, 9, 1, 8, 0, 4, 2],\n", + " [0, 8, 9, 3, 7, 1, 3, 2, 9, 7],\n", + " [7, 9, 5, 6, 8, 7, 0, 9, 3, 9],\n", + " [3, 1, 8, 6, 3, 5, 4, 1, 2, 9],\n", + " [8, 6, 6, 1, 0, 9, 2, 0, 7, 5],\n", + " [5, 4, 4, 2, 7, 2, 7, 9, 3, 1],\n", + " [5, 0, 1, 2, 3, 8, 7, 5, 4, 0],\n", + " [5, 9, 6, 6, 1, 3, 6, 0, 4, 9],\n", + " [2, 1, 0, 9, 1, 4, 2, 9, 7, 9],\n", + " [5, 3, 7, 6, 3, 9, 8, 4, 3, 0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9ZyUPfybTfej", + "outputId": "ac27a20e-1622-4cb9-d6f6-74ee467bdb72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [1],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nS1cPG3aRug1", + "outputId": "c70cf891-ae8f-445d-c271-c6b7f7da1738", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "# colocando o array a_numeros2 do lado de a_numeros1.\n", + "np.c_[a_numeros1, a_numeros2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 8, 2, 8, 9, 1, 8, 0, 4, 2, 1],\n", + " [0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 0],\n", + " [7, 9, 5, 6, 8, 7, 0, 9, 3, 9, 0],\n", + " [3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 0],\n", + " [8, 6, 6, 1, 0, 9, 2, 0, 7, 5, 0],\n", + " [5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 1],\n", + " [5, 0, 1, 2, 3, 8, 7, 5, 4, 0, 0],\n", + " [5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 0],\n", + " [2, 1, 0, 9, 1, 4, 2, 9, 7, 9, 0],\n", + " [5, 3, 7, 6, 3, 9, 8, 4, 3, 0, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kIgU1YBw0OeM" + }, + "source": [ + "___\n", + "# **Selecionar itens que satisfazem condições**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e2pL5anBV0DI", + "outputId": "3f88ada5-6035-4a4c-ba3c-75c50e70535b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.arange(10, 0, -1)\n", + "a_numeros1" + ], + "execution_count": 15, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i9HuZZAfV302" + }, + "source": [ + "Selecionar somente os itens > 7:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZCESvr7iXMkV" + }, + "source": [ + "## Usando np.where()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdrAQLHkTS-v", + "outputId": "18f6bed6-13f8-4c21-8e3c-cc7a2f016349", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O_ZBaWxfWA9o", + "outputId": "d0828963-049a-405e-d909-d1ddcd4571cf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Índices do array que atendem a condição\n", + "l_indices = np.where(a_numeros1 > 7)\n", + "l_indices" + ], + "execution_count": 17, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(array([0, 1, 2]),)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EdWlfPOZWPME" + }, + "source": [ + "**Atenção**: Capturamos os índices. Para selecionar os itens, basta fazer:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tOxs3iYQWWxu", + "outputId": "83e88f0a-8dbf-434f-c5ca-f561119c7c28", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros2 = a_numeros1[l_indices]\n", + "a_numeros2" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PGsENqkaXRjh" + }, + "source": [ + "## Alternativa: Usando []" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YbdRNk1WXTLT", + "outputId": "0788cf3d-33c0-4acf-9c91-83ba2d60a5c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1[a_numeros1 > 7]" + ], + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jijpzFxcSQC8" + }, + "source": [ + "Acho que vale a pena quebrar esta solução para entendermos melhor como as coisas funcionam:#" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rujhP2LQSWsq" + }, + "source": [ + " # Primeiro, avalie o resultado de a_numeros1 > 7:" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FYZaBsasSb3N", + "outputId": "07162754-7d8e-4999-8313-3fdd20d6cb54", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_numeros1 > 7" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ True, True, True, False, False, False, False, False, False,\n", + " False])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvEof-UKaaVG", + "outputId": "cdd88df9-5224-420c-e653-047e02e779b4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1[a_numeros1 > 7]" + ], + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nO4FiBmDUZOT", + "outputId": "53a4b692-3214-4c79-dabd-089ad82ed2d4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": 22, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ci5lT9nmSfsX" + }, + "source": [ + "Agora, com este resultado, fica fácil entender como o Python seleciona os elementos. Consegue explicar?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1v5Lfin0GGKD" + }, + "source": [ + "# Substituir itens baseado em condições\n", + "> Substituir os valores negativos do array abaixo por 0." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CLY_u0ePWdN7" + }, + "source": [ + "## Gerar o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NUANFy-fNXf5", + "outputId": "ed6284d2-bf8f-4c2b-8e25-5c9df5258e7d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(0, 10, size = 100))\n", + "\n", + "# Lista aleatória de índices que vou alterar\n", + "np.random.seed(20111974)\n", + "l_indices= np.random.randint(0, 99, 9)\n", + "\n", + "for i in l_indices:\n", + " a_numeros1[i] = -1*a_numeros1[i]\n", + "\n", + "a_numeros2 = a_numeros1.copy()\n", + "a_numeros2" + ], + "execution_count": 23, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 8, 8, -2, 8, 9, 1, 8, 0, -4, 2, 0, 8, 9, 3, 7, 1, 3,\n", + " 2, 9, 7, 7, 9, 5, 6, 8, 7, 0, -9, 3, 9, 3, 1, 8, 6,\n", + " 3, 5, 4, 1, 2, 9, -8, 6, -6, 1, 0, 9, -2, 0, 7, 5, 5,\n", + " 4, 4, 2, 7, 2, 7, 9, 3, 1, -5, 0, 1, 2, 3, 8, 7, 5,\n", + " 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, -1, 0, 9, 1,\n", + " 4, 2, 9, -7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dWVyI40uN2d2", + "outputId": "037f708d-ffad-462b-f7e2-5f0779d18d1f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Indices a serem multiplicados por -1:\n", + "l_indices" + ], + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([60, 42, 40, 8, 27, 2, 46, 88, 81])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Whuu854OJDZ" + }, + "source": [ + "## Substituir os valores negativos por 0" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sr268Rp8b-Se", + "outputId": "69b8f95c-8624-46db-fa98-3636db6d54d8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + "a_numeros2 < 0" + ], + "execution_count": 25, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C-eKqPrfOQF6", + "outputId": "c685b6d3-bc94-483d-dc1a-bc5fd4cb2d3a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_numeros2[a_numeros2 < 0] = 0\n", + "a_numeros2" + ], + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([8, 8, 0, 8, 9, 1, 8, 0, 0, 2, 0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 7, 9,\n", + " 5, 6, 8, 7, 0, 0, 3, 9, 3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 0, 6, 0, 1,\n", + " 0, 9, 0, 0, 7, 5, 5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 0, 0, 1, 2, 3, 8,\n", + " 7, 5, 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, 0, 0, 9, 1, 4, 2, 9,\n", + " 0, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eDLM0_JSZlfB" + }, + "source": [ + "Observe acima que os valores negativos foram substituídos por 0, como queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AEHJ0rA3dHHU" + }, + "source": [ + "## Substituir os valores negativos por 0 e os positivos por 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y32J8SRNZwRF", + "outputId": "7eb344d0-c969-4868-f349-ade25dce94d6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "a_numeros2 = a_numeros1.copy()\n", + "a_numeros2" + ], + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 8, 8, -2, 8, 9, 1, 8, 0, -4, 2, 0, 8, 9, 3, 7, 1, 3,\n", + " 2, 9, 7, 7, 9, 5, 6, 8, 7, 0, -9, 3, 9, 3, 1, 8, 6,\n", + " 3, 5, 4, 1, 2, 9, -8, 6, -6, 1, 0, 9, -2, 0, 7, 5, 5,\n", + " 4, 4, 2, 7, 2, 7, 9, 3, 1, -5, 0, 1, 2, 3, 8, 7, 5,\n", + " 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, -1, 0, 9, 1,\n", + " 4, 2, 9, -7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1bSD9Fs6P5wW", + "outputId": "cf6756c5-52e0-447b-cd1f-3fbc8c79e8f0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_numeros2 = np.where(a_numeros2 <= 0, 0, 1)\n", + "a_numeros2" + ], + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", + " 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,\n", + " 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,\n", + " 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,\n", + " 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i027scjl0qkm" + }, + "source": [ + "___\n", + "# Outliers\n", + "> Qualquer ponto/observação que é incomum quando comparado com todos os outros pontos/observações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UnDTqRnZHQ3W" + }, + "source": [ + "## Z-Score\n", + "\n", + "* Z-Score pode ser utilizado para detectar Outliers.\n", + "* É a diferença entre o valor e a média da amostra expressa como o número de desvios-padrão. \n", + "* Se o escore z for menor que 2,5 ou maior que 2,5, o valor estará nos 5% do menor ou maior valor (2,5% dos valores em ambas as extremidades da distribuição). No entanto, é pratica comum utilizarmos 3 ao invés dos 2,5.\n", + "\n", + "![Z_Score](https://github.com/MathMachado/Materials/blob/master/Z_Score.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N7gb2zhtd0uM" + }, + "source": [ + "## IQR Score\n", + "\n", + "* O Intervalo interquartil (IQR) é uma medida de dispersão estatística, sendo igual à diferença entre os percentis 75 (Q3) e 25 (Q1), ou entre quartis superiores e inferiores, IQR = Q3 - Q1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lMmWOKNvghI7" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z3VZdU8rICZA" + }, + "source": [ + "## Desafio\n", + "> Substituir os outliers do array por:\n", + "1. Q1-1.5\\*(Q3 - Q1), se ponto < Q1-1.5\\*IQR\n", + "2. Q3+1.5\\*(Q3 - Q1), se ponto > Q3+1.5\\*IQR" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DUw_a-MjWvBc" + }, + "source": [ + "### Desafio para resolverem\n", + "> Objetivo: Simular aleatoriamente o salário de 1.000 pessoas com distribuição N(1.045; 100). \n", + "* Identificar os outliers da distribuição que acabamos de simular;\n", + "* Qual a média da distribuição que simulamos?\n", + "* Qual o desvio-padrão;\n", + "* Plotar o Boxplot da distribuição dos dados;\n", + "* Quantas pessoas > Q3 + 1.5*(Q3-Q1)\n", + "\n", + "Obs.: Use np.random.seed(20111974)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RL0Zb0fyDory", + "outputId": "12b72d2b-5a07-476c-b682-b43458dad537", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "np.random.seed(19741120)\n", + "a_numeros1 = np.array(np.random.normal(100, 10, size = 100))\n", + "\n", + "# Lista aleatória de índices que vou alterar\n", + "np.random.seed(20111974)\n", + "l_indices = np.random.randint(0, 99, 10)\n", + "np.sort(l_indices)\n", + "\n", + "a_numeros1_copia = a_numeros1.copy()\n", + "for i in l_indices:\n", + " a_numeros1_copia[i] = 2*a_numeros1_copia[i]\n", + "\n", + "a_numeros1_copia" + ], + "execution_count": 29, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 92.26622483, 88.94525348, 202.01256141, 88.54282712,\n", + " 78.47337726, 92.47442751, 78.47005101, 96.69822268,\n", + " 177.90685389, 103.28896747, 100.10101983, 86.67863666,\n", + " 96.60541955, 99.87009928, 100.53428231, 98.13587989,\n", + " 103.94738054, 91.06457686, 94.93326767, 92.53390871,\n", + " 118.35863649, 87.94631286, 112.01848858, 105.1160897 ,\n", + " 94.30477141, 90.66561289, 97.50274717, 219.69742669,\n", + " 111.93333668, 122.99564969, 101.66570222, 107.13574148,\n", + " 95.47489218, 109.21639184, 107.3421263 , 121.78111913,\n", + " 99.43447875, 112.53259996, 96.29607519, 114.38552019,\n", + " 217.12921824, 98.87427612, 192.91994052, 109.41366709,\n", + " 99.13038373, 85.09992988, 200.16973311, 108.67052746,\n", + " 116.34090601, 113.63210628, 99.78246389, 95.46983552,\n", + " 96.28887641, 99.52839308, 77.2662565 , 109.53187379,\n", + " 107.10054804, 92.01167315, 96.83422097, 84.16471762,\n", + " 192.44970327, 97.02396587, 92.65757933, 94.42967769,\n", + " 94.02193121, 96.78511833, 113.48163484, 113.01668438,\n", + " 105.02843445, 107.58835306, 110.94932036, 99.23942748,\n", + " 93.74530061, 98.11132421, 84.62965767, 101.61893629,\n", + " 97.35568508, 94.27312327, 105.55501746, 105.45183177,\n", + " 91.55201318, 207.3344281 , 103.85618579, 98.93911584,\n", + " 119.4216084 , 91.53859352, 79.86676575, 106.45458816,\n", + " 311.17594425, 106.44862258, 113.52153879, 111.68130043,\n", + " 100.4550085 , 93.80661302, 98.87736992, 122.53185044,\n", + " 112.21271855, 101.34656943, 104.99984125, 94.74563688])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZnmykyahLWX9", + "outputId": "3bbfbafd-8715-4f72-de0e-693f2dcd9887", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_numeros1)}; Mediana: {np.median(a_numeros1)}; STD: {np.std(a_numeros1)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 100.18633633362035; Mediana: 99.33695311387913; STD: 10.028092450008492'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 55 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILhNe80xW5C6" + }, + "source": [ + "### Solução do desafio" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U993i1GJg2hk", + "outputId": "86faf16c-d671-4ebc-b695-7dc204185f8d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "sns.boxplot(y = a_numeros1_copia)" + ], + "execution_count": 30, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VtenLK1uK1Pi" + }, + "source": [ + "Consegue identificar os outliers do array?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e3sHuGVGFBdW" + }, + "source": [ + "## Objetivo\n", + "> Substituir os outliers por mediana. \n", + "\n", + "* Como fazer isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSegPNKCI-dS" + }, + "source": [ + "### Siga os passos a seguir\n", + "1. Calcule estatísticas descritivas antes das transformações par avaliar o impacto;\n", + " * Calcule média, mediana e desvio-padrão dos dados originais;\n", + "2. Calcule os valores a seguir:\n", + " * Q1, Q3\n", + " * IQR = Q3-Q1\n", + " * lim_inferior = Q1-1.5\\*IQR\n", + " * lim_superior = Q3+1.5\\*IQR\n", + "3. Proceda à substituição:\n", + " * Se a_numeros1_copia[i] < lim_inferior então a_numeros1_copia[i]= Mediana\n", + " * Se a_numeros1_copia[i] > lim_superior então a_numeros1_copia[i]= Mediana\n", + "4. Calcule as estatísticas descritivas após as substituições e compare com os valores antes das transformações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9DQ7YnWaFn4v" + }, + "source": [ + "### Minha solução\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RBXJbTeGLC7Q" + }, + "source": [ + "1. Estatísticas Descritivas antes das transformações:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QueKYn7MLG12", + "outputId": "c410c7bb-76f4-4f8a-de71-1bbe0dfa6a21", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_numeros1_copia)}; Mediana: {np.median(a_numeros1_copia)}; STD: {np.std(a_numeros1_copia)}'" + ], + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 110.56825524166379; Mediana: 99.98555955648851; STD: 35.484921348581274'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oOBJ8INWL5fo" + }, + "source": [ + "Observe o quanto nossos dados estão distorcidos dos valores originalmente utilizados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MX-fJeh2MBTD" + }, + "source": [ + "2. Calcular Q1, Q3 e IQR" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JlsPiQeGMGeU" + }, + "source": [ + "Q1= np.percentile(a_numeros1_copia, q = [25])\n", + "Q3= np.percentile(a_numeros1_copia, q = [75])\n", + "Q2= np.percentile(a_numeros1_copia, q = [50])\n", + "IQR = Q3-Q1\n", + "lim_inferior = Q1-1.5*IQR\n", + "lim_superior = Q3+1.5*IQR" + ], + "execution_count": 32, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VF2NJ3rCeI1_", + "outputId": "7b94b22f-a175-4f06-9ac1-1872aa52cfd8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Q1: {Q1}; Q3: {Q3}; lim_inferior: {lim_inferior}; lim_superior: {lim_superior}'" + ], + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Q1: [94.39845112]; Q3: [111.13231538]; lim_inferior: [69.29765473]; lim_superior: [136.23311177]'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjnwJ7HwMxcl" + }, + "source": [ + "3. Substituir\n", + "* Se a_numeros1[i] < lim_inferior então a_numeros1[i]= Mediana\n", + "* Se a_numeros1[i] > Lia_Sup então a_numeros1[i]= Mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcAn-IwVfbcI" + }, + "source": [ + "a_numeros2 = a_numeros1_copia.copy()" + ], + "execution_count": 35, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3SSE45oM9oh", + "outputId": "b6fa4f55-88ac-4864-d4b5-08d642438aed", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "a_numeros2[a_numeros2 < lim_inferior[0]] = Q2[0]\n", + "a_numeros2[a_numeros2 > lim_superior[0]] = Q2[0]\n", + "a_numeros2" + ], + "execution_count": 36, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 92.26622483, 88.94525348, 99.98555956, 88.54282712,\n", + " 78.47337726, 92.47442751, 78.47005101, 96.69822268,\n", + " 99.98555956, 103.28896747, 100.10101983, 86.67863666,\n", + " 96.60541955, 99.87009928, 100.53428231, 98.13587989,\n", + " 103.94738054, 91.06457686, 94.93326767, 92.53390871,\n", + " 118.35863649, 87.94631286, 112.01848858, 105.1160897 ,\n", + " 94.30477141, 90.66561289, 97.50274717, 99.98555956,\n", + " 111.93333668, 122.99564969, 101.66570222, 107.13574148,\n", + " 95.47489218, 109.21639184, 107.3421263 , 121.78111913,\n", + " 99.43447875, 112.53259996, 96.29607519, 114.38552019,\n", + " 99.98555956, 98.87427612, 99.98555956, 109.41366709,\n", + " 99.13038373, 85.09992988, 99.98555956, 108.67052746,\n", + " 116.34090601, 113.63210628, 99.78246389, 95.46983552,\n", + " 96.28887641, 99.52839308, 77.2662565 , 109.53187379,\n", + " 107.10054804, 92.01167315, 96.83422097, 84.16471762,\n", + " 99.98555956, 97.02396587, 92.65757933, 94.42967769,\n", + " 94.02193121, 96.78511833, 113.48163484, 113.01668438,\n", + " 105.02843445, 107.58835306, 110.94932036, 99.23942748,\n", + " 93.74530061, 98.11132421, 84.62965767, 101.61893629,\n", + " 97.35568508, 94.27312327, 105.55501746, 105.45183177,\n", + " 91.55201318, 99.98555956, 103.85618579, 98.93911584,\n", + " 119.4216084 , 91.53859352, 79.86676575, 106.45458816,\n", + " 99.98555956, 106.44862258, 113.52153879, 111.68130043,\n", + " 100.4550085 , 93.80661302, 98.87736992, 122.53185044,\n", + " 112.21271855, 101.34656943, 104.99984125, 94.74563688])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VEGFio0Nfj7O" + }, + "source": [ + "4. Estatísticas Descritivas para avaliarmos o impacto:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gX1LZHFqfjFQ", + "outputId": "b98ed302-57bb-4f81-9a70-e2c695f0c029", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_numeros2)}; Mediana: {np.median(a_numeros2)}; STD: {np.std(a_numeros2)}'" + ], + "execution_count": 37, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 100.35899750691053; Mediana: 99.92782941793924; STD: 9.602142763141016'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-xnguZ7XgyvK", + "outputId": "992beaa4-f2e9-4462-c344-dafb124a4a27", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "sns.boxplot(y = a_numeros2)" + ], + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uEPFcBjFhETQ" + }, + "source": [ + "Como podem ver, os outliers desapareceram, como queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tHfzjW_ymKuR" + }, + "source": [ + "___\n", + "# **Valores únicos**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HzmQgWZVmUUD", + "outputId": "5ceea152-492f-4cbc-e67b-8a1c9a3aec84", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "import numpy as np\n", + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.randint(0, 100, 100)\n", + "a_numeros1" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([60, 42, 40, 8, 27, 2, 46, 88, 81, 88, 80, 13, 30, 82, 96, 63, 79,\n", + " 91, 72, 13, 89, 67, 93, 33, 99, 73, 77, 42, 55, 45, 41, 21, 22, 8,\n", + " 62, 10, 0, 94, 15, 9, 67, 89, 35, 42, 97, 93, 8, 83, 26, 5, 68,\n", + " 90, 74, 57, 40, 22, 45, 6, 81, 95, 0, 25, 50, 80, 76, 29, 7, 21,\n", + " 5, 95, 52, 93, 31, 78, 61, 50, 50, 7, 41, 3, 33, 47, 5, 16, 33,\n", + " 19, 92, 60, 56, 55, 53, 28, 84, 16, 27, 85, 22, 38, 49, 90])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dm9ky1F1mrNA" + }, + "source": [ + "Quem são os valores únicos do array?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-LPRqc-mS5j", + "outputId": "68a139d6-59fe-46ce-a36f-dcf2d50c9cef", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "np.unique(a_numeros1)" + ], + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 0, 2, 3, 5, 6, 7, 8, 9, 10, 13, 15, 16, 19, 21, 22, 25, 26,\n", + " 27, 28, 29, 30, 31, 33, 35, 38, 40, 41, 42, 45, 46, 47, 49, 50, 52,\n", + " 53, 55, 56, 57, 60, 61, 62, 63, 67, 68, 72, 73, 74, 76, 77, 78, 79,\n", + " 80, 81, 82, 83, 84, 85, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uXZZoTd6nMuq" + }, + "source": [ + "___\n", + "# **Diferença entre dois arrays**\n", + "> O resultado é um array com os **valores únicos de A que não estão em B**. Na teoria de conjuntos escrevemos $A - B = A - A \\cap B$.\n", + "\n", + "![Difference](https://github.com/MathMachado/Materials/blob/master/set_Difference.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uW6i3m9q1ZNs" + }, + "source": [ + "\n", + "* Vamos ver como isso funciona na prática:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vw05sfe22mfk" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qqw2do90nQ7k" + }, + "source": [ + "a_numeros1 = np.array([0, 1, 2, 4, 5, 7, 8, 8]) # array de valores que serão excluidos em a_numeros1. Observe que '3' não pertence a a_numeros1.\n", + "a_numeros2 = np.array([1, 6, 7, 3])" + ], + "execution_count": 41, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zXJ00pOMorM-", + "outputId": "48b60273-7035-4083-811a-0672427ebd12", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.setdiff1d(a_numeros1, a_numeros2)" + ], + "execution_count": 42, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 4, 5, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8GXZNgjfo8lO" + }, + "source": [ + "Observe que o resultado são os elementos de a_numeros1 que não pertencem a x_Y. Mas como fica o '3' nesta história?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aJSu6VKb2oc_" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N1wahElXTqoB", + "outputId": "95a40bbf-533b-4e5e-cec3-4365a591861a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.arange(10)\n", + "a_numeros1" + ], + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nxDpCMg7T7Rj", + "outputId": "96e4285c-0f00-4153-d0aa-d2e766032786", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros2 = np.array([1, 5, 7])\n", + "a_numeros2" + ], + "execution_count": 44, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 5, 7])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3LU3qYyiUXqm", + "outputId": "cc0bc36f-a91e-449a-d0f2-14a381049097", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.setdiff1d(a_numeros1, a_numeros2)" + ], + "execution_count": 45, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 3, 4, 6, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mzZEytrRUioU" + }, + "source": [ + "Observe que os elementos de a_numeros2 foram deletados de a_numeros1. Ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gJRcoVRUnaY9" + }, + "source": [ + "___\n", + "# Diferença Simétrica\n", + "* Em teoria de conjuntos, chamamos de Diferença Simétrica e escrevemos $(A \\cup B)- (A \\cap B)$.\n", + "\n", + "![DifferenceSymetric](https://github.com/MathMachado/Materials/blob/master/set_DifferenceSymetric.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2Uzzm85Kup3H" + }, + "source": [ + "* Vamos ver como isso funciona na prática:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1z5wZ8VwpsWN" + }, + "source": [ + "import numpy as np\n", + "a_numeros1 = np.array([0, 1, 2, 4, 5, 7, 8]) # Observe que [1, 4, 7] pertencem a a_numeros1, mas 3, não. Portanto:\n", + "a_numeros2 = np.array([1, 4, 7, 3])" + ], + "execution_count": 46, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tqd_9XO5p7bo", + "outputId": "4fa4d87e-1858-437c-a9f1-c589a05fe24c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.setxor1d(a_numeros1, a_numeros2)" + ], + "execution_count": 47, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 3, 5, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_meurG3mqS5Y" + }, + "source": [ + "Como explicamos ou interpretamos este resultado?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kc8JoKe2nj2n" + }, + "source": [ + "___\n", + "# **União de dois arrays**\n", + "> Retorna os valores **únicos** dos dois arrays. Na teoria dos conjuntos, escrevemos:\n", + "\n", + "$$A \\cup B$$\n", + "\n", + "![Union](https://github.com/MathMachado/Materials/blob/master/set_Union.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1LZxorw2p2mg" + }, + "source": [ + "a_numeros1 = np.array([0, 1, 2, 4, 5, 7, 8, 8])\n", + "\n", + "# Observe que [1, 4, 7] pertencem a a_numeros1, mas 3, não. Portanto:\n", + "a_numeros2 = np.array([1, 4, 7, 3])" + ], + "execution_count": 48, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "COsZEmSwuY5L", + "outputId": "de10c400-956a-417c-82b6-435eb67d811b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.union1d(a_numeros1, a_numeros2)" + ], + "execution_count": 49, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 7, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b53bR-GYRu_3" + }, + "source": [ + "___\n", + "# **Selecionar itens comuns dos arrays X e Y**\n", + "* Na teoria de conjuntos, chamamos de intersecção e escrevemos $X \\cap Y$.\n", + "\n", + "![Intersection](https://github.com/MathMachado/Materials/blob/master/set_Intersection.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n2ec2tqqR1Gw" + }, + "source": [ + "* Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rXVQQvBqR4J-", + "outputId": "2cd7bc3f-a2ce-4cc2-c4b3-f2c2ba91ce74", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.arange(10)\n", + "a_numeros1" + ], + "execution_count": 50, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pZTHhHxGSRfB", + "outputId": "9ac004d4-e9fe-4078-d651-0bc323996738", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros2 = np.arange(8, 18)\n", + "a_numeros2" + ], + "execution_count": 51, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MxB2_qHpScMB" + }, + "source": [ + "Quais são os elementos comuns à X e Y?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e-rncJHtSfw0", + "outputId": "181798e4-5d52-4d1d-a9f1-66efb0bb3361", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.intersect1d(a_numeros1, a_numeros2)" + ], + "execution_count": 52, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Bb39sWdfqaF" + }, + "source": [ + "___\n", + "# **Autovalores e Autovetores**\n", + "> Autovetor e Autovalor são um dos tópicos mais importantes em Machine Learning.\n", + "\n", + "Por definição, o escalar $\\lambda$ e o vetor $v$ são autovalor e autovetor da matriz $A$ se\n", + "\n", + "$$Av = \\lambda v$$\n", + "\n", + "## Leitura Adicional:\n", + "\n", + "* [Machine Learning & Linear Algebra — Eigenvalue and eigenvector](https://medium.com/@jonathan_hui/machine-learning-linear-algebra-eigenvalue-and-eigenvector-f8d0493564c9)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XZBKq8nGCUbL" + }, + "source": [ + "* O array a_numeros2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iYlZGKFUfw-R" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6EfvIbBNf02Z" + }, + "source": [ + "# Calcula autovalores e autovetores:\n", + "a_Autovalores, a_Autovetores= np.linalg.eig(a_numeros2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v3GtQQvAz9QU" + }, + "source": [ + "Os autovalores do array a_numeros2 são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WvZGyBR1f9vP" + }, + "source": [ + "a_Autovalores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AuuDRJVh0FC8" + }, + "source": [ + "Os autovetores do array a_numeros2 são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6m4YFAwsf_rA" + }, + "source": [ + "a_Autovetores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DASn2Un9ZNV-" + }, + "source": [ + "___\n", + "# **Encontrar Missing Values (NaN)**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TKilWBsSXtR4" + }, + "source": [ + "## Gerar o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lqLI2ER_ZUMY" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.random.random(100)\n", + "\n", + "# Inserindo 15 NaN's no array:\n", + "np.random.seed(20111974)\n", + "l_indices_aleatorios= np.random.randint(0, 100, size = 15)\n", + "\n", + "for i_indices in l_indices_aleatorios:\n", + " #print(i_indices)\n", + " a_numeros1[i_indices] = np.nan" + ], + "execution_count": 53, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ZkbMPXMawYh", + "outputId": "029308be-52e1-4e3d-cf1f-ec1bb64a2530", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": 54, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, nan, 0.65478409, 0.85708456,\n", + " 0.60174181, 0.87298309, 0.45573342, nan, 0.64300912,\n", + " 0.54808035, 0.35321428, 0.32005665, nan, 0.85159044,\n", + " 0.75930202, 0.65675987, 0.3278323 , 0.34592275, 0.41510657,\n", + " 0.30635652, 0.26750355, 0.30663224, 0.35503537, 0.60299892,\n", + " 0.0221767 , 0.36265947, nan, 0.28077438, 0.37056609,\n", + " nan, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " nan, 0.14442301, nan, 0.70671296, 0.07163699,\n", + " 0.56212721, nan, 0.83632274, 0.21435895, 0.85491145,\n", + " 0.62878505, 0.38468856, 0.90553087, 0.33703023, 0.06707729,\n", + " 0.1023552 , 0.84821523, 0.12156391, 0.94423963, 0.15835682,\n", + " nan, 0.91080887, 0.58558559, 0.36799242, 0.71647196,\n", + " 0.0740405 , 0.47889268, 0.77503169, 0.96720855, 0.71575223,\n", + " 0.28887146, 0.33306388, 0.95399002, 0.23557899, 0.97714605,\n", + " 0.85188315, 0.63303051, 0.57297905, 0.66792818, 0.87621361,\n", + " nan, nan, nan, 0.68323127, 0.28826713,\n", + " 0.32846648, 0.98334327, 0.17156066, nan, 0.91917489,\n", + " 0.98381602, 0.75915187, 0.31400247, 0.97074481, 0.07574498,\n", + " 0.55661541, nan, 0.4936932 , 0.07351232, 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 54 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z7Bs75NvbSjx" + }, + "source": [ + "Ok, inserimos aleatoriamente 14 NaN's no array a_numeros1. Agora, vamos contar quantos NaN's (já sabemos a resposta!)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hL1Wn0vdX8ur" + }, + "source": [ + "## Identificar os NaN's" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5R-n3H0xbd6d", + "outputId": "5eef40ef-4f0c-4678-8177-c150ca9b2278", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan(a_numeros1).sum()" + ], + "execution_count": 55, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 55 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y7hh5uowoa3U" + }, + "source": [ + "Ok, temos 14 NaN's em a_numeros1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iVLQf_bqbyNU" + }, + "source": [ + "Ok, agora eu quero saber os índices desses NaN's." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kJHxjZiwb5HM", + "outputId": "d92df3ef-e4f8-48bc-9dba-c53a8a83e27d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_indices= np.where(np.isnan(a_numeros1))\n", + "i_indices" + ], + "execution_count": 56, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(array([ 2, 8, 13, 27, 30, 40, 42, 46, 60, 80, 81, 82, 88, 96]),)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 56 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W_jHGNImok7L", + "outputId": "78a1c58a-772a-4937-ddc1-18b24123bf6e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Checando...\n", + "a_numeros1[2]" + ], + "execution_count": 57, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "nan" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 57 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iPhHAhDYcMWO" + }, + "source": [ + "Vamos conferir se está correto? Para isso, basta comparar com l_indices_aleatorios:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gxQYslRCe11G" + }, + "source": [ + "___\n", + "# **Deletar NaN's de um array**\n", + "> Considere o mesmo array que acabamos de trabalhar. Agora eu quero excluir os NaN's identificados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AeBARFqNfNnN", + "outputId": "b98e2229-54c3-4d6c-ffa1-7e859bb2cdfc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "a_numeros1" + ], + "execution_count": 58, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, nan, 0.65478409, 0.85708456,\n", + " 0.60174181, 0.87298309, 0.45573342, nan, 0.64300912,\n", + " 0.54808035, 0.35321428, 0.32005665, nan, 0.85159044,\n", + " 0.75930202, 0.65675987, 0.3278323 , 0.34592275, 0.41510657,\n", + " 0.30635652, 0.26750355, 0.30663224, 0.35503537, 0.60299892,\n", + " 0.0221767 , 0.36265947, nan, 0.28077438, 0.37056609,\n", + " nan, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " nan, 0.14442301, nan, 0.70671296, 0.07163699,\n", + " 0.56212721, nan, 0.83632274, 0.21435895, 0.85491145,\n", + " 0.62878505, 0.38468856, 0.90553087, 0.33703023, 0.06707729,\n", + " 0.1023552 , 0.84821523, 0.12156391, 0.94423963, 0.15835682,\n", + " nan, 0.91080887, 0.58558559, 0.36799242, 0.71647196,\n", + " 0.0740405 , 0.47889268, 0.77503169, 0.96720855, 0.71575223,\n", + " 0.28887146, 0.33306388, 0.95399002, 0.23557899, 0.97714605,\n", + " 0.85188315, 0.63303051, 0.57297905, 0.66792818, 0.87621361,\n", + " nan, nan, nan, 0.68323127, 0.28826713,\n", + " 0.32846648, 0.98334327, 0.17156066, nan, 0.91917489,\n", + " 0.98381602, 0.75915187, 0.31400247, 0.97074481, 0.07574498,\n", + " 0.55661541, nan, 0.4936932 , 0.07351232, 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 58 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e497B492fFru", + "outputId": "98168450-f277-4834-f342-29fececcc27f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 323 + } + }, + "source": [ + "a_numeros1[~np.isnan(a_numeros1)]" + ], + "execution_count": 59, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, 0.65478409, 0.85708456, 0.60174181,\n", + " 0.87298309, 0.45573342, 0.64300912, 0.54808035, 0.35321428,\n", + " 0.32005665, 0.85159044, 0.75930202, 0.65675987, 0.3278323 ,\n", + " 0.34592275, 0.41510657, 0.30635652, 0.26750355, 0.30663224,\n", + " 0.35503537, 0.60299892, 0.0221767 , 0.36265947, 0.28077438,\n", + " 0.37056609, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " 0.14442301, 0.70671296, 0.07163699, 0.56212721, 0.83632274,\n", + " 0.21435895, 0.85491145, 0.62878505, 0.38468856, 0.90553087,\n", + " 0.33703023, 0.06707729, 0.1023552 , 0.84821523, 0.12156391,\n", + " 0.94423963, 0.15835682, 0.91080887, 0.58558559, 0.36799242,\n", + " 0.71647196, 0.0740405 , 0.47889268, 0.77503169, 0.96720855,\n", + " 0.71575223, 0.28887146, 0.33306388, 0.95399002, 0.23557899,\n", + " 0.97714605, 0.85188315, 0.63303051, 0.57297905, 0.66792818,\n", + " 0.87621361, 0.68323127, 0.28826713, 0.32846648, 0.98334327,\n", + " 0.17156066, 0.91917489, 0.98381602, 0.75915187, 0.31400247,\n", + " 0.97074481, 0.07574498, 0.55661541, 0.4936932 , 0.07351232,\n", + " 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 59 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpvKfJU_fmA6" + }, + "source": [ + "Observe que os NaN's foram excluidos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_Dv8MmNYg8zN" + }, + "source": [ + "___\n", + "# **Converter lista em array**\n", + "> Considere a lista a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "but6T9dVhFYb", + "outputId": "fadc10e9-3767-4061-f839-711837b06002", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_Lista = [np.random.randint(0, 10, 10)]\n", + "l_Lista" + ], + "execution_count": 60, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[array([8, 9, 3, 7, 1, 3, 2, 9, 7, 7])]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 60 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xytj4Eo4hTh9", + "outputId": "e7874289-2ad3-4e8c-fa2a-1f4bb238b333", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(l_Lista)" + ], + "execution_count": 61, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "list" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 61 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qrINdcruhWcH" + }, + "source": [ + "Convertendo a minha lista para array:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RoSyaX0OhZSE", + "outputId": "810f770f-beb4-43a9-bd85-ae8ed6c5c32f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros = np.asarray(l_Lista)\n", + "a_numeros" + ], + "execution_count": 62, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 9, 3, 7, 1, 3, 2, 9, 7, 7]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 62 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMjTdbBUhlrk", + "outputId": "f8d483d1-b233-448e-90d9-c29813af67ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(a_numeros)" + ], + "execution_count": 63, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 63 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mbm3ZP9DhxDI" + }, + "source": [ + "___\n", + "# Converter tupla em array\n", + "> Considere a tupla a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cZxEFYLAh3S_", + "outputId": "1e267cf3-068c-464d-d282-2d3c8416a0fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "t_numeros = ([np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)])\n", + "t_numeros" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "([array([8, 8, 2])], [array([8, 9, 1])], [array([8, 0, 4])])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vlTXUJviiAml", + "outputId": "9962557d-f255-41d7-864d-55d521783332", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(t_numeros)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tuple" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yEaOlq8oh3oh", + "outputId": "21edc300-270a-49f1-d044-8916038f8033", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_numeros = np.asarray(t_numeros)\n", + "a_numeros" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[[8, 8, 2]],\n", + "\n", + " [[8, 9, 1]],\n", + "\n", + " [[8, 0, 4]]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PSgQDmRWh3g5", + "outputId": "70328871-4dd7-4d28-e76c-53ba48ae049a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(a_numeros)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pH-Ht6yMiqJN" + }, + "source": [ + "___\n", + "# Acrescentar elementos à um array\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dFaDZInZiwoo", + "outputId": "3c98416a-07d4-499c-a08a-7e7a37c327e2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.arange(5)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d3zrlf_Ci73Z", + "outputId": "997f288a-994f-418c-9110-bc78e0eb92cd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.append(a_numeros1, [np.random.randint(0, 10, 3), np.random.randint(0, 10, 3), np.random.randint(0, 10, 3)])\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 8, 8, 2, 8, 9, 1, 8, 0, 4])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eFRhtk13ojqA" + }, + "source": [ + "___\n", + "# **Converter array 1D num array 2D**\n", + "> Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wYhBgW9Zu6ZP" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(0, 10, 6))\n", + "\n", + "np.random.seed(19741120)\n", + "a_numeros2 = np.array(np.random.randint(0, 10, 6))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "febs9AUHvs6n" + }, + "source": [ + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "C9OEd-iavvBm" + }, + "source": [ + "a_numeros2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KJWjtaWKv0MJ" + }, + "source": [ + "np.column_stack((a_numeros1, a_numeros2)) # Atenção aos parênteses em (a_numeros1, a_numeros2)." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xr_WZXJ7pi2D" + }, + "source": [ + "___\n", + "# **Excluir um elemento específico do array usando indices**\n", + "> Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tS0ZzOs8w0dw" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(0, 10, 6))\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7bOJiKDKxEsC" + }, + "source": [ + "Suponha que eu queira excluir os valores '8' de a_numeros1. Os índices dos valores '8' são: [0, 1, 3]. Portanto, temos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SSjueEvjxTJO" + }, + "source": [ + "a_numeros1 = np.delete(a_numeros1, [0, 1, 3])\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZkGZ2Rgp--5" + }, + "source": [ + "___\n", + "# **Frequência dos valores únicos de um array**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z2BWKfH0xvQ8", + "outputId": "7712eab3-15ea-4064-dcfa-8121cf51f2a0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(0, 10, 100))\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([8, 8, 2, 8, 9, 1, 8, 0, 4, 2, 0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 7, 9,\n", + " 5, 6, 8, 7, 0, 9, 3, 9, 3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 8, 6, 6, 1,\n", + " 0, 9, 2, 0, 7, 5, 5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 5, 0, 1, 2, 3, 8,\n", + " 7, 5, 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, 1, 0, 9, 1, 4, 2, 9,\n", + " 7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s_tdQBsax4rQ" + }, + "source": [ + "Suponha que eu queira saber quantas vezes o número/elemento '2' aparece em a_numeros1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6yIlk7pWyAtf", + "outputId": "1dde1573-d81b-43b5-adc7-809674303603", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_itens_unicos, i_count = np.unique(a_numeros1, return_counts=True)\n", + "l_itens_unicos" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyvrIwS9yZIR" + }, + "source": [ + "O que significa o output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uO-MPMhXyV9H", + "outputId": "42892cc5-0e5e-4c61-cb4a-72add57cc618", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_count" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 10, 10, 11, 8, 8, 8, 10, 10, 15])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zwoezXrPyofK" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgYycSG7yr5e", + "outputId": "b87844ae-1ef3-4c99-fa77-84ef657020ae", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "np.asarray((l_itens_unicos, i_count))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],\n", + " [10, 10, 10, 11, 8, 8, 8, 10, 10, 15]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SwIZiJAiy06T" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JpNRpN2Dql3N" + }, + "source": [ + "___\n", + "# **Combinações possíveis de outros arrays**\n", + "> Considere o exemplo a seguir:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BUr89dH4zLXD" + }, + "source": [ + "a_numeros1 = [2, 4, 6]\n", + "a_numeros2 = [0, 8]\n", + "a_numeros4 = [1, 5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cEZH6l-Czx7y" + }, + "source": [ + "np.meshgrid(a_numeros1, a_numeros2, a_numeros4)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "btvmDkEcz0tH" + }, + "source": [ + "np.array(np.meshgrid(a_numeros1, a_numeros2, a_numeros4))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z0xhO7rGz059" + }, + "source": [ + "np.array(np.meshgrid(a_numeros1, a_numeros2, a_numeros4)).T" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eMv4lFnD0Enn" + }, + "source": [ + "# Resultado final\n", + "a_numeros3 = np.array(np.meshgrid(a_numeros1, a_numeros2, a_numeros4)).T.reshape(-1,3)\n", + "a_numeros3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rz80YANfAh2k" + }, + "source": [ + "___\n", + "# **Wrap Up**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_cyhMsAVXxGC" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNjovMw3uJ3R" + }, + "source": [ + "## Exercício 1 - Selecionar os números pares\n", + "> Dado o 1D array abaixo, selecionar somente os números pares." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "isDzQjwjBX3V", + "outputId": "eff14fb7-c4f7-4113-f568-01b4ba21c9b3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kq1zt-uO1HXv" + }, + "source": [ + "### **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFmK_n2M1Ks9", + "outputId": "11dbc1b6-10b6-42b1-a1bc-b8bc8d464d42", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1[a_numeros1 % 2 == 0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 4, 6, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sScYG0hp05vb" + }, + "source": [ + "___\n", + "## Exercício 2 - Substituir pela mediana\n", + "> Dado o array 1D abaixo, substituir os números pares pela mediana de a_numeros1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XLZ-DIWU1WFs", + "outputId": "52bad0fc-24e7-43b7-cec0-6f2cfbffddff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9c4QWJno1WVB" + }, + "source": [ + "### **Minha solução**\n", + "* Primeiramente, precisamos calcular a mediana.\n", + "* Depois, substituimos os valores pares de a_numeros1 pela mediana encontrada anteriormente. Ok?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rx7NGAO01Wfb", + "outputId": "9667049f-ff4c-45f9-be1b-013a2e03d464", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_numeros1[a_numeros1 % 2 == 0] = np.median(a_numeros1)\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4, 1, 4, 3, 4, 5, 4, 7, 4, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2c_AphX82qp8" + }, + "source": [ + "Verificando..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kVta0Cr13Z9", + "outputId": "adac6c2d-f9d9-42a6-f13a-c41ae6ae8d09", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'A média de a_numeros1 é: {np.median(a_numeros1)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A média de a_numeros1 é: 4.0'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L9O-Hf5x26TY" + }, + "source": [ + "___\n", + "## Exercício 3 - Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 2D com 3 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_laUvtB4Wl-", + "outputId": "92df1bde-642a-455d-ddef-619c29cf29dc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(1, 10, size = 15))\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dKzEX8TK5b4Z" + }, + "source": [ + "### **Minha solução**\n", + "* O array 1D a_numeros1 acima possui 15 elementos. Como queremos transformá-lo num array 2D com 3 colunas, então cada coluna terá 5 elementos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I-j5yVD04249", + "outputId": "0a2877e5-79af-4258-bb77-bf665892a112", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_numeros1.reshape(5, 3) \n", + "# Poderia ser a_numeros1.reshape(-1, 3), onde \"-1\" pede para o NumPy calcular o número de linhas. " + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9, 3],\n", + " [9, 2, 9],\n", + " [1, 5, 3],\n", + " [1, 9, 4],\n", + " [8, 2, 4]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F1vfS8jE6L0_" + }, + "source": [ + "___\n", + "## Exercício 4 - Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xcN-bez56L1D", + "outputId": "a3f2336e-fd0f-438f-93f6-74a67d26d939", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_numeros1 = np.array(np.random.randint(1, 10, size = 16))\n", + "a_numeros1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4, 3])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_JTbsHSGjaYS", + "outputId": "7f9ab328-1b90-4f12-bfa7-eff24af344ce", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "a_numeros1.reshape(-1,2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9],\n", + " [3, 9],\n", + " [2, 9],\n", + " [1, 5],\n", + " [3, 1],\n", + " [9, 4],\n", + " [8, 2],\n", + " [4, 3]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7iICnOyG6fcj" + }, + "source": [ + "### **Minha solução**\n", + "* O array 1D a_numeros1 acima possui 16 elementos. Queremos transformá-lo num array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vdq5ybuD6fcn" + }, + "source": [ + "a_numeros1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "haQfWPcCs_H0" + }, + "source": [ + "## Exercício 5\n", + "Para mais exercícios envolvendo arrays, visite a página [Python: Array Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/array/)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LQQL0JS2tnc0" + }, + "source": [ + "## Exercício 6\n", + "Para mais exercícios envolvendo matemática, viste a página [Python Math: - Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/math/index.php)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qNskKFy9t4D5" + }, + "source": [ + "## Exercício 7\n", + "Para mais exercícios envolvendo NumPy em geral, visite a página [NumPy Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/numpy/index.php)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qqc1AiHXuKZ5" + }, + "source": [ + "## Exercício 8\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jYrgc3KvtmLy" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB02__Numpy_hs2.ipynb b/Notebooks/NB02__Numpy_hs2.ipynb new file mode 100644 index 000000000..ba74fa73f --- /dev/null +++ b/Notebooks/NB02__Numpy_hs2.ipynb @@ -0,0 +1,5840 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB02__Numpy.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6QhLXoatkvKR" + }, + "source": [ + "

NUMPY

\n", + "\n", + "> NumPy é um pacote para computação científica e álgebra linear para Python.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b8EZupp68vW8" + }, + "source": [ + "# **AGENDA**:\n", + "> Neste capítulo, vamos abordar os seguintes assuntos:\n", + "\n", + "* NumPy\n", + "* Criar arrays\n", + "* Criar Arrays Multidimensionais\n", + "* Selecionar itens\n", + "* Aplicar funções como max(), min() e etc\n", + "* Calcular Estatísticas Descritivas: média e variância\n", + "* Reshaping\n", + "* Tansposta de um array\n", + "* Autovalores e Autovetores\n", + "* Wrap Up\n", + "* Exercícios" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cO5t3xCO8kyK" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "\n", + "* Nosso foco com o NumPy é facilitar o uso do Pandas;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z2IFUG4GSB0Z" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jYLeDVH-SNCg" + }, + "source": [ + "![Numpy](https://github.com/MathMachado/Materials/blob/master/numpy_basics-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0mKvExmgUFOk" + }, + "source": [ + "# **ESCALAR, VETORES, MATRIZES E TENSORES**\n", + "\n", + "![Tensor](https://github.com/MathMachado/Materials/blob/master/tensor.png?raw=true)\n", + "\n", + "Source: [PyTorch for Deep Learning: A Quick Guide for Starters](https://towardsdatascience.com/pytorch-for-deep-learning-a-quick-guide-for-starters-5b60d2dbb564)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o00pYRIkXiAU" + }, + "source": [ + "## Import Statement - Primeiros exemplos\n", + "> Como exemplo, considere gerar uma amostra aleatória de tamanho 10 da Distribuição Normal(0, 1):" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l_XuvcUDWNDk" + }, + "source": [ + "## Importar a library NumPy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "am_ZTIGaapCo" + }, + "source": [ + "### **Opção 1**: Importar a biblioteca NumPy COM alias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b4irLw6BWVVZ" + }, + "source": [ + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JK54ga7dXnJu", + "outputId": "1a31527c-f8b6-44d5-ecbd-9f08abc5f8d6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(media, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "a_conjunto1 = np.random.normal(media, desvio_padrao, size = 10) # Array 1D de size = 10\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 2.51, 1.11, 2.06, 0.56, 0.3 , 1.05, -0.13, 1.06, 1.14,\n", + " 1.38])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-0934isZUm6" + }, + "source": [ + "**Observação**: Altere o valor de [precision] para 4, 2 e 0 e observe o que acontece." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ob_8S_bYYa2" + }, + "source": [ + "### **Opção 2**: Importar a biblioteca NumPy SEM alias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NcGd1ho_XDXU" + }, + "source": [ + "import numpy" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zFYH6J5-Ydjl" + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "numpy.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "numpy.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(mu, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "numpy.random.normal(size = 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AwWSzYrZWfvA" + }, + "source": [ + "### **Opção 3**: Importar funções específicas da biblioteca NumPy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bfYJzcqRa5eu" + }, + "source": [ + "from numpy import set_printoptions\n", + "from numpy.random import seed, normal" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xj6fbpvubH_p" + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "set_printoptions(precision = 2, suppress = True)\n", + "\n", + "'''\n", + "Define seed por questões de reproducibilidade, ou seja, \n", + "garante que todos vamos gerar os mesmos números aleatórios\n", + "'''\n", + "seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(mu, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1 \n", + "np.random.normal(size = 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "00RerJPChnuP" + }, + "source": [ + "___\n", + "# **Estatísticas Descriticas com NumPy**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qa6ro1VJlShd" + }, + "source": [ + "## Exemplo 1\n", + "> Vamos voltar ao mesmo exemplo anterior, mas desta vez, usando a opção 1 (com alias):\n", + "\n", + "* Gerar uma amostra aleatória de tamanho 10 da Distribuiçao Normal(0, 1)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "31dSBU8khvFk" + }, + "source": [ + "# Set up o número de casas decimais para o NumPy:\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "# Define seed\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Gera 10 números aleatórios a partir da Distribuição Normal(media, desvio_padrao)\n", + "media = 0\n", + "desvio_padrao = 1\n", + "\n", + "np.random\n", + "a_conjunto1 = np.random.normal(media, desvio_padrao, size = 10) # Array 1D de size = 10\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wa2t0P3nevTh" + }, + "source": [ + "Conferindo a média e desvio-padrão do array gerado:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "drUyk3f5ekDq" + }, + "source": [ + "f'Distribuição N({np.mean(a_conjunto1)}, {np.std(a_conjunto1)})'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XSp7Hd-Gib67" + }, + "source": [ + "Estávamos à espera de media = 0 e sigma = 1. Certo? Porque isso não aconteceu?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HP_8VSgygXOF" + }, + "source": [ + "## **Laboratório 1**\n", + "> Altere os valores de [size] para 100, 1.000, 10.000, 100.000 e 1.000.000 e relate o que acontece com a média e desvio padrão." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4TbmVbdcg6iU" + }, + "source": [ + "## **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-qdiqBVHg-gd" + }, + "source": [ + "# Define a média e o desvio-padrão\n", + "media = 0\n", + "desvio_padrao = 1\n", + "\n", + "# Define seed\n", + "np.random.seed(seed = 20111974)\n", + "l_lista_conjunto = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]\n", + "\n", + "for i_size in l_lista_conjunto:\n", + " a_conjunto1 = np.random.normal(media, desvio_padrao, size = i_size)\n", + " print(f'Size: {i_size}--> Distribuição: N({np.mean(a_conjunto1)}, {np.std(a_conjunto1)})')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bp-YuviQwWqE" + }, + "source": [ + "Com relação à Distribuição Normal($\\mu, \\sigma$), temos que:\n", + "\n", + "![NormalDistribution](https://github.com/MathMachado/Materials/blob/master/NormalDistribution.PNG?raw=true)\n", + "\n", + "Fonte: [Normal Distribution](https://towardsdatascience.com/understanding-the-68-95-99-7-rule-for-a-normal-distribution-b7b7cbf760c2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KwHBY3Enk04N" + }, + "source": [ + "## Lei Forte dos Grandes Números - LFGN\n", + "> Por favor, leia o que diz a [Law of large numbers](https://en.wikipedia.org/wiki/Law_of_large_numbers). --> 3 minutos.\n", + "\n", + "* O que você aprendeu com isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BhwmSkAjlszT" + }, + "source": [ + "## Exemplo 2\n", + "> Vamos nos aprofundar um pouco mais no que diz a LFGN. Para isso, vamos simular o lançamento de dados. Como sabemos, os dados possuem 6 lados numerados de 1 a 6, com igual probabilidade. Certo?\n", + "\n", + "A LFGN nos diz que à medida que N (o tamanho da amostra ou número de dados) cresce, então a média dos dados converge para o valor esperado. Isso quer dizer que:\n", + "\n", + "$$\\frac{1+2+3+4+5+6}{6}= \\frac{21}{6}= 3,5$$\n", + "\n", + "Ou seja, à medida que N (o tamanho da amostra) cresce, espera-se que a média dos dados se aproxime de 3,5. Ok?\n", + "\n", + "Vamos ver se isso é verdade..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-QcJXf6roj0D" + }, + "source": [ + "Vamos usar o método np.random.randint (= função randint definido na classe np.random), a seguir:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A2u0RzLOrRE2" + }, + "source": [ + "O que significa ou qual é a interpretação do resultado abaixo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B3-X_VBerUfa" + }, + "source": [ + "# Define seed\n", + "import numpy as np\n", + "np.random.seed(seed = 20111974)\n", + "\n", + "# Simular 100 lançamentos de um dado:\n", + "a_dados_simulados = np.random.randint(1, 7, size = 100)\n", + "a_dados_simulados" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m8Of2MMIrbF3" + }, + "source": [ + "# Importar o pandas, pois vamos precisar do método pd.value_counts():\n", + "import pandas as pd\n", + "pd.value_counts(a_dados_simulados)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "54VwED8Br8rx" + }, + "source": [ + "**Interpretação**: Isso quer dizer que fizemos a simulação de lançamento de um dado 100 vezes. Acima, a frequência com que cada lado do dado aparece.\n", + "\n", + "Eu estava à espera de frequência igual para cada um dos lados, isto é, por volta dos 16 ou 17. Ou seja:\n", + "\n", + "$$\\frac{100}{6}= 16,66$$\n", + "\n", + "Mas ok, vamos continuar com nosso experimento..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HT_Dak-umC6I" + }, + "source": [ + "# Definir a semente\n", + "np.random.seed(20111974)\n", + "\n", + "for i_size in [10, 30, 50, 75, 100, 1000, 10000, 100000, 1000000]:\n", + " a_dados_simulados = np.random.randint(1, 7, size = i_size)\n", + " print(f'Size: {i_size} --> Média: {np.mean(a_dados_simulados)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "edWNNOnXtbtd" + }, + "source": [ + "E agora, como você interpreta esses resultados?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eL6gXThkYcSf" + }, + "source": [ + "## Calcular percentis\n", + "> Boxplot" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jlGOQfXfPf0D" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)\n", + "\n", + "Fonte: [Understanding Boxplots](https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "grtEXG2BoNRt" + }, + "source": [ + "Considere o array de retornos (simulados) a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DjPKKq01YjF9" + }, + "source": [ + "import numpy as np\n", + "np.random.seed(20111974)\n", + "\n", + "# Simulando Retornos de ativos financeiros com a distribuição Normal(0, 1):\n", + "a_retornos = np.random.normal(0, 1, 100)\n", + "print(f'Média: {np.mean(a_retornos)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ajjlfqgssLVO" + }, + "source": [ + "a_retornos" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XZ3m06gv9lei" + }, + "source": [ + "A seguir, o boxplot do array a_retornos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QtuwJP449tBQ" + }, + "source": [ + "# Import da biblioteca seaborn: Uma das principais libraries para Data Visualization (outras: matplotlib)\n", + "import seaborn as sns\n", + "\n", + "sns.boxplot(y = a_retornos)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9ujdjxNY6qE" + }, + "source": [ + "# Vamos usar o método np.percentile(array, q = [p1, p2, p3, ..., p99])\n", + "percentis = np.percentile(a_retornos, q = [1, 5, 25, 50, 55, 75, 99])\n", + "\n", + "# Primeiro Quartil\n", + "q1 = percentis[2]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c75g2Egco2lc" + }, + "source": [ + "Em qual posição do array a_retornos se encontra Q3?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nZr-A82Zo8Kb" + }, + "source": [ + "q3 = percentis[5]\n", + "\n", + "# ou de trás para a frente do conteúdo da lista:\n", + "q3_2 = percentis[-2]\n", + "print(q3, q3_2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sWrnESPQT4JM" + }, + "source": [ + "# lim_inferior_outlier e lim_superior_outlier para detecção de outliers\n", + "lim_inferior_outlier = q1 - 1.5 * (q3 - q1)\n", + "lim_superior_outlier = q3 + 1.5 * (q3 - q1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yb4-ZJlUUYsi" + }, + "source": [ + "f'Limite Inferior: {lim_inferior_outlier}; Limite Superior: {lim_superior_outlier}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jr6oXIHlUxOe" + }, + "source": [ + "np.min(a_retornos)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UxE47cN0U54X" + }, + "source": [ + "np.max(a_retornos)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OTB9HnIac499" + }, + "source": [ + "___\n", + "# **Ordenar itens de um array**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jgj8Yw46dBMx" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.random(10)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cC9272GFdRln" + }, + "source": [ + "Ordenando os itens de a_conjunto1..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YUP90nBVdUeF" + }, + "source": [ + "np.sort(a_conjunto1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lG763cDGj-yB" + }, + "source": [ + "___\n", + "# **Obter ajuda**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ehxPlD3EkEYL" + }, + "source": [ + "help(np.random.normal)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1Q_konJVaBsV" + }, + "source": [ + "___\n", + "# **Criar arrays 1D**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DddZT5kadYJ7" + }, + "source": [ + "import numpy as np\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "np.random.seed(seed = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jaqd-VnF3yIt" + }, + "source": [ + "Criar o array 1D a_conjunto1, com os seguintes números:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3niz_zHaF3e" + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyfXbW_ZKJBS" + }, + "source": [ + "Qual a dimensão de a_conjunto1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gbHlydALKB3R" + }, + "source": [ + "# Dimensão do array\n", + "a_conjunto1.ndim" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "am9otElpKNPa" + }, + "source": [ + "Qual o shape (dimensão) do array a_conjunto1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "juJJ74d2wale" + }, + "source": [ + "# Números de itens no array\n", + "a_conjunto1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BHg4Rre3GwPy" + }, + "source": [ + "O array a_conjunto1 poderia ter sido criado usando a função np.arange(inicio, fim, step):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I3fyusN7G5Zn" + }, + "source": [ + "# Lembre-se que o número 10 é exclusive.\n", + "a_conjunto2 = np.arange(start = 0, stop = 10, step = 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IHCEpmUxXsaK" + }, + "source": [ + "Outra alternativa seria usar np.linspace(start = 0, stop = 10, num = 9). Acompanhe a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JB9Y_x3RX1GX" + }, + "source": [ + "# Com np.linspace, o valor 9 é inclusive.\n", + "a_conjunto3 = np.linspace(0, 9, 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P6MR8MPeYOZm" + }, + "source": [ + "Compare os resultados de a_conjunto1, a_conjunto2 e a_conjunto3 a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tWEzge6HYSFu" + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lUNlFVKYYT9f" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xo8Lid5fYVPW" + }, + "source": [ + "a_conjunto3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V9aW7C4vHAcF" + }, + "source": [ + "Ou seja, a_conjunto1 é igual a a_conjunto2 que também é igual a a_conjunto3. Ok?\n", + "\n", + "**ATENÇÃO**: Observe que a sintaxe para criar a_conjunto3 é ligeiramente diferente da sintaxe usada para criar a_conjunto1 e a_conjunto2. Abaixo, a sintaxe do comando np.linspace:\n", + "\n", + "![](https://github.com/MathMachado/Materials/blob/master/linspace_sintaxe.PNG?raw=true)\n", + "\n", + "Source: [HOW TO USE THE NUMPY LINSPACE FUNCTION](https://www.sharpsightlabs.com/blog/numpy-linspace/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KNnwZa3uvYqE" + }, + "source": [ + "Soma 2 à cada item de a_conjunto1:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jt2KVyviw0bp" + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "arROkhWXbdTW" + }, + "source": [ + "a_conjunto2 = a_conjunto1 + 2\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJx2vG86vdVi" + }, + "source": [ + "Multiplicar por 10 cada item de a_conjunto1:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vm7abO6Ebkun" + }, + "source": [ + "a_conjunto1 = a_conjunto1*10\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0Ev1xnBwaYJG" + }, + "source": [ + "___\n", + "# **Criar Arrays Multidimensionais**\n", + "> Ao criarmos, por exemplo, um array 2D, então a chamamos de matriz." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gHaeAug5vjjd" + }, + "source": [ + "Criar o array com 2 linhas e 3 colunas usando números aleatórios:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VDi0vIPSYR4F" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randn(2, 3)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DIdd-nA3tJjV" + }, + "source": [ + "## Dimensão de um array\n", + "> Dimensão é o número de linhas e colunas da matriz." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pKvjjnkrK-v7" + }, + "source": [ + "a_conjunto1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-DHS5jXELCfa" + }, + "source": [ + "a_conjunto1 é um array 2D (ou matriz), ou seja, 2 linhas, onde cada linha tem 3 elementos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HJI6X1wvv4Bg" + }, + "source": [ + "Criar um array com 3 linhas e 3 colunas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hXPbWh3Tv26T" + }, + "source": [ + "a_conjunto2 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "we6ZJOICc7bQ" + }, + "source": [ + "# Número de linhas e colunas de a_conjunto1:\n", + "a_conjunto1.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f0ocwuI1dED6" + }, + "source": [ + "# Número de linhas e colunas de a_conjunto2\n", + "a_conjunto2.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CApPtnW0YuRP" + }, + "source": [ + "# Somar 2 à cada elemento de a_conjunto2\n", + "a_conjunto2 = a_conjunto2+2\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M87aGmxRY3RW" + }, + "source": [ + "# Multiplicar por 10 cada elemento de a_conjunto2\n", + "a_conjunto2 = a_conjunto2*10\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qZt93y1IL_v7" + }, + "source": [ + "___\n", + "# **Copiar arrays**\n", + "> Considere o array abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sH2FTXj5MRRC" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randn(2, 3)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VtgKeMt6MYrr" + }, + "source": [ + "Fazendo a cópia de a_conjunto1..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "K0hOHR3IMa-o" + }, + "source": [ + "a_salarios_copia = a_conjunto1.copy()\n", + "a_salarios_copia" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lFpmcR0HkCar" + }, + "source": [ + "___\n", + "# **Operações com arrays**\n", + "> Considere um array com temperaturas em Farenheit dado por:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VnagcUqVkLhW" + }, + "source": [ + "# Define a seed\n", + "np.random.seed(20111974)\n", + "\n", + "a_temperatura_farenheit = np.array(np.random.randint(0, 100, 10))\n", + "a_temperatura_farenheit " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VrjNKfXxk1yv" + }, + "source": [ + "type(a_temperatura_farenheit)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o1STejhrk0kZ" + }, + "source": [ + "Transformando a temperatura Fahrenheit em Celsius..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E_jXflR_lNy3" + }, + "source": [ + "a_temperatura_celsius = 5*a_temperatura_farenheit/9 - 5*32/9\n", + "a_temperatura_celsius" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U4pCv0pNqPZI" + }, + "source": [ + "# O mesmo resultado, porém, escrito de forma diferente:\n", + "a_temperatura_celsius = (5/9)*a_temperatura_farenheit - (160/9)\n", + "a_temperatura_celsius" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UT4YD2FawUA" + }, + "source": [ + "___\n", + "# **Selecionar itens**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pqOv8P1za1m8" + }, + "source": [ + "# Selecionar o segundo item de a_conjunto1 (lembre-se que no Python arrays começam com indice = 0)\n", + "a_conjunto1[1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TIwVKk6AyRv6" + }, + "source": [ + "Dado a_conjunto2 abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zoDmbXo6bCeu" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iJXSPp-0yb4w" + }, + "source": [ + "... selecionar o item da linha 2, coluna 3 do array a_conjunto2:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sJiVfnlzcjRv" + }, + "source": [ + "a_conjunto2[1, 2]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xl5HwJIMcv2e" + }, + "source": [ + "# Selecionar o último elemento de a_conjunto1 --> Lembre-se que a_conjunto1 é um array. Desta forma, teremos o último elemento do array!\n", + "a_conjunto1[-1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ezTH0HsyrnAl" + }, + "source": [ + "Veja..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OBv9EM54rYX3" + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Po3WLFC-rod8" + }, + "source": [ + "a_temperatura_celsius[-1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4qJJ2HCedW4h" + }, + "source": [ + "___\n", + "# **Aplicar funções como max(), min() e etc**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_meTJdUsda4e" + }, + "source": [ + "f'O máximo de a_conjunto1 é: {np.max(a_conjunto1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m-wiBkAidnhN" + }, + "source": [ + "f'O mínimo de a_conjunto1 é: {np.min(a_conjunto1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lmupnRHQdtwh" + }, + "source": [ + "f'O máximo de a_conjunto2 é: {np.max(a_conjunto2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "H2z7oB6Bd786" + }, + "source": [ + "f'O máximo de cada LINHA de a_conjunto2 é: {np.max(a_conjunto2, axis = 1)}' # Aqui, axis = 1 é que diz ao numpy que estamos interessados nas linhas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gj2ZBDsWeMyk" + }, + "source": [ + "f'O máximo de cada COLUNA de a_conjunto2 é: {np.max(a_conjunto2, axis = 0)}' # axis = 0, diz ao numpy que estamos interessados nas colunas." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7_tEfm2IecIU" + }, + "source": [ + "___\n", + "# **Calcular Estatísticas Descritivas: média e variância**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lIY5jx3ueh7q" + }, + "source": [ + "f'A média de a_conjunto1 é: {np.mean(a_conjunto1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VmqSELRReuAW" + }, + "source": [ + "f'A média de a_conjunto2 é: {np.mean(a_conjunto2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gxap-Wg5e2_H" + }, + "source": [ + "f'O Desvio Padrão de a_conjunto2 é: {np.std(a_conjunto2)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R0GcljGtfBvP" + }, + "source": [ + "___\n", + "# **Reshaping**\n", + "> Muito útil em Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vfEmw01j8zux" + }, + "source": [ + "## Exemplo 1\n", + "* O array a_conjunto2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-Lb3VZCCfK_a" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YWN_nN-4fD7u" + }, + "source": [ + "# reshaping para 9 linhas e 1 coluna:\n", + "a_conjunto2.reshape(9, 1) # a_conjunto2.reshape(9,-1) produz o mesmo resultado." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id9ILRRt7SwY" + }, + "source": [ + "## Mais um exemplo de Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9RA9Ht2b7Swd", + "outputId": "eadedfd5-fd6c-49c8-db5c-6f8f30d45f36", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(1, 10, size = 15))\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8KxR4xZT7cRv" + }, + "source": [ + "### Solução\n", + "> Temos 15 elementos em a_conjunto1 para construir (\"reshape\") um array 3D com 2 colunas.\n", + "\n", + "A princípio, a solução seria..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VMdHl1Il7wLw", + "outputId": "d51c7263-f523-4af8-9606-ee93cab66f1c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 163 + } + }, + "source": [ + "a_conjunto1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "ValueError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma_numeros1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mValueError\u001b[0m: cannot reshape array of size 15 into shape (2)" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pZS4b4-y708q" + }, + "source": [ + "Porque temos esse erro?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4disywvR8HeH" + }, + "source": [ + "E se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3oEAAXTp8I7Z", + "outputId": "e8c8a90f-c34a-4304-d9b4-fd7f04ce224f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(1, 10, size = 16)) # Observe que agora temos 16 elementos\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([9, 9, 3, 9, 2, 9, 1, 5, 3, 1, 9, 4, 8, 2, 4, 3])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iUhth0QV8Rpt" + }, + "source": [ + "Reshapping..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9D1y7uD88Qip", + "outputId": "e7d22bcd-c10f-4ea3-e41b-03f6f98a054f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "a_conjunto1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9],\n", + " [3, 9],\n", + " [2, 9],\n", + " [1, 5],\n", + " [3, 1],\n", + " [9, 4],\n", + " [8, 2],\n", + " [4, 3]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ALh-sq7DMnN5", + "outputId": "db373349-7910-4f1f-93f3-8ac8f67da8b8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "# OU --> Neste caso, estamos reshaping o array em 8 linhas e 2 colunas\n", + "a_conjunto1.reshape(8, -1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[9, 9],\n", + " [3, 9],\n", + " [2, 9],\n", + " [1, 5],\n", + " [3, 1],\n", + " [9, 4],\n", + " [8, 2],\n", + " [4, 3]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yvTnrszn8Yk0" + }, + "source": [ + "Porque agora deu certo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LeQ9LqIE8baG" + }, + "source": [ + "## Último exemplo com reshape\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OQOC9iiN8hZT" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randn(2, 3)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cvce8qBl9Cvq" + }, + "source": [ + "Queremos agora transformá-la num array de 3 linhas e 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QDDsYoVt9Klz" + }, + "source": [ + "a_conjunto1.reshape(-1, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AdwU5ygt9Svq" + }, + "source": [ + "Poderia ser..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5uBeokKc9Uo-" + }, + "source": [ + "a_conjunto1.reshape(3, -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OeRBsobc9aKj" + }, + "source": [ + "E por fim, também poderia ser..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MDt8UYYH9dBw" + }, + "source": [ + "a_conjunto1.reshape(3, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "91o5vycQfdKW" + }, + "source": [ + "___\n", + "# **Transposta**\n", + "* O array a_conjunto2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RsZwyuhoffjb" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A3MzTVoGfiyO" + }, + "source": [ + "# Transposta do array a_conjunto2 é dado por:\n", + "a_conjunto2.T" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ij-ZW5IyzXIb" + }, + "source": [ + "Ou seja, linha virou coluna. Ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qLy6ajgpt3lU" + }, + "source": [ + "# **Inversa da matriz quadrada**\n", + "> Se uma matriz é não-singular, então sua inversa existe.\n", + "\n", + "* Se o determinante de uma matriz is not equal to zero, then the matrix isé diferente de 0, então a matriz é não-singular." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-u7jRq34t9_x" + }, + "source": [ + "import numpy as np\n", + "\n", + "a_conjunto1 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])\n", + "a_conjunto2 = np.array([[6, 2], [5, 3]])\n", + "a_conjunto3 = np.array([[1, 3, 5],[2, 5, 1],[2, 3, 8]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7zmHHWWlvaYB" + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3fHKyhOJvcak" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vQG7yyfjwLg9" + }, + "source": [ + "a_conjunto3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qa2Yre2rwgRk" + }, + "source": [ + "## Determinantes da matriz quadrada" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N6jwuC6twkyc" + }, + "source": [ + "np.linalg.det(a_conjunto1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QSvViNwzwnhI" + }, + "source": [ + "np.linalg.det(a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o8jwsnccw5id" + }, + "source": [ + "np.linalg.det(a_conjunto3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kkVaTgzgw_XJ" + }, + "source": [ + "A seguir, calculamos as inversas das matrizes acima definidas..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b9FgWvTYvpik" + }, + "source": [ + "np.linalg.inv(a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KsdEt1kIvsM_" + }, + "source": [ + "np.linalg.inv(a_conjunto1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VA_F7_7kccpn" + }, + "source": [ + "Porque não temos a inversa de a_conjunto1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ANPBCnmVwOf4" + }, + "source": [ + "np.linalg.inv(a_conjunto3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XAf9k1egxcdF" + }, + "source": [ + "# **Resolver sistemas de equações lineares**\n", + "> Considere o sistema de euqações lineares abaixo:\n", + "\n", + "\\begin{equation}\n", + "x + 3y + 5z = 10\\\\\n", + "2x+ 5y + z = 8 \\\\\n", + "2x + 3y + 8z= 3\n", + "\\end{equation}\n", + "\n", + "Ou $Ax = b$. A solução deste sistema de equações é dada por $A^{-1}b$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oNf5nqaLxhBY" + }, + "source": [ + "Ou seja, basta encontrarmos a inversa de A e multiplicarmos por b." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "omzC5dGA0btc" + }, + "source": [ + "A= np.array([[1, 3, 5], [2, 5, 1], [2, 3, 8]])\n", + "np.linalg.inv(A)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AiXI3oxB05iE" + }, + "source": [ + "Agora basta multiplicar a matriz inversa $A^{-1}$ acima por b. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XoGebKDa2Fcd" + }, + "source": [ + "A_Inv = np.linalg.inv(A)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sKaP0a1QZG-P" + }, + "source": [ + "b= np.array([10, 8, 3]).reshape(3, -1)\n", + "b" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3dAVq8dg19VI" + }, + "source": [ + "A_Inv.dot(b)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zso6hTnB17cm" + }, + "source": [ + "Uma forma fácil de se fazer isso é utilizar a expressão abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ptQHIVll1E4P" + }, + "source": [ + "b= np.array([[10], [8], [3]])\n", + "b" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X4VL8lyY1Xus" + }, + "source": [ + "np.linalg.solve(A, b)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fJKmwTS59-Bc" + }, + "source": [ + "# **Empilhar arrays**\n", + "\n", + "## Exemplo 1\n", + "\n", + "![Empilhar1](https://github.com/MathMachado/Materials/blob/master/Empilhar1.PNG?raw=true)\n", + "\n", + "## Exemplo 2\n", + "\n", + "![Empilhar2](https://github.com/MathMachado/Materials/blob/master/Empilhar2.PNG?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rhPTt3EwXden" + }, + "source": [ + "## Gerar os arrays do exemplo1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zEI-yBy3-E46" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randn(5, 8)\n", + "\n", + "np.random.seed(19741120)\n", + "a_conjunto2 = np.random.randn(8, 8)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UYsAqBRp--79" + }, + "source": [ + "## Método 1 - Concatenate([A, B])" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgO1ujvhObyE", + "outputId": "c40e7ed9-255b-4886-dddf-3b17f2b1be2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2aQY_klZOeg9", + "outputId": "14eb3d9c-d0fc-4b6a-fe19-1790695c838f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 289 + } + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bK70vaq8_KMH", + "outputId": "f6d400cf-4b54-4990-815b-052f5224aadd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.concatenate([a_conjunto1, a_conjunto2], axis = 0) # axis= 0 diz ao NumPy para empilhar as linhas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CpaXBkm8_BF8" + }, + "source": [ + "## Método 2 - np.r_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3QnVUzAY_teZ", + "outputId": "e8adfd85-e760-40f5-d9ac-48353d24ccd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.r_[a_conjunto1, a_conjunto2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XmSPbDP6_20W" + }, + "source": [ + "**Obs**.: Eu prefiro este método!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dzVKW_wX_Dzw" + }, + "source": [ + "## Método 3 - np.vstack([A, B]) = np.r_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uL7lEN_mABID", + "outputId": "d1ea4d86-2cc1-4e2d-af72-b3a292ef15fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "np.vstack([a_conjunto1, a_conjunto2])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n", + " 1.04930857, -0.12607366, 1.06227632],\n", + " [ 1.13807032, 1.37966044, -2.05995563, 0.67474814, 0.72722843,\n", + " -0.33923852, 0.43613107, 0.59135489],\n", + " [-1.29281877, 1.17712036, -0.98644163, -1.79034143, -1.08913605,\n", + " -0.90712825, -1.02291108, -1.36445713],\n", + " [-0.29429164, 0.06343709, -1.14196185, -0.50706079, -0.83539436,\n", + " -1.41492946, -0.2159062 , -1.16519474],\n", + " [-0.60767518, -0.61510925, 1.0771542 , 0.5043687 , 0.02674197,\n", + " 1.83494644, 0.34728874, -1.14671885],\n", + " [-0.77337752, -1.10547465, 0.10062807, -1.14571729, -2.15266227,\n", + " -0.75255725, -2.1529949 , -0.33017773],\n", + " [-1.10465731, 0.32889675, 0.01010198, -1.33213633, -0.33945805,\n", + " -0.01299007, 0.05342823, -0.18641201],\n", + " [ 0.39473805, -0.89354231, -0.50667323, -0.74660913, 1.83586365,\n", + " -1.20536871, 1.20184886, 0.51160897],\n", + " [-0.56952286, -0.93343871, -0.24972528, 0.98487133, 1.19333367,\n", + " 2.29956497, 0.16657022, 0.71357415],\n", + " [-0.45251078, 0.92163918, 0.73421263, 2.17811191, -0.05655212,\n", + " 1.25326 , -0.37039248, 1.43855202],\n", + " [ 0.85646091, -0.11257239, -0.35400297, 0.94136671, -0.08696163,\n", + " -1.49000701, 0.00848666, 0.86705275],\n", + " [ 1.6340906 , 1.36321063, -0.02175361, -0.45301645, -0.37111236,\n", + " -0.04716069, -2.27337435, 0.95318738],\n", + " [ 0.7100548 , -0.79883269, -0.3165779 , -1.58352824, -0.37751484,\n", + " -0.29760341, -0.73424207, -0.55703223]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "68icJ-2ZAdRj" + }, + "source": [ + "# Concatenar arrays\n", + "\n", + "## Exemplo 1\n", + "\n", + "![Concatenar1](https://github.com/MathMachado/Materials/blob/master/Concatenar1.PNG?raw=true)\n", + "\n", + "# Exemplo 2\n", + "\n", + "![Concatenar2](https://github.com/MathMachado/Materials/blob/master/Concatenar2.PNG?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OplgK9YoQi9o" + }, + "source": [ + "## Concatenar os elementos de dois arrays - np.c_[A, B]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lpdsbTEKQ9EY" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randint(0, 10, 100).reshape(-1, 10)\n", + "a_conjunto2 = np.random.randint(0, 2, 10).reshape(-1, 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JPxhGsaSSMk2", + "outputId": "47727fe9-05f1-4ff7-ec0a-04579120cf78", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 8, 2, 8, 9, 1, 8, 0, 4, 2],\n", + " [0, 8, 9, 3, 7, 1, 3, 2, 9, 7],\n", + " [7, 9, 5, 6, 8, 7, 0, 9, 3, 9],\n", + " [3, 1, 8, 6, 3, 5, 4, 1, 2, 9],\n", + " [8, 6, 6, 1, 0, 9, 2, 0, 7, 5],\n", + " [5, 4, 4, 2, 7, 2, 7, 9, 3, 1],\n", + " [5, 0, 1, 2, 3, 8, 7, 5, 4, 0],\n", + " [5, 9, 6, 6, 1, 3, 6, 0, 4, 9],\n", + " [2, 1, 0, 9, 1, 4, 2, 9, 7, 9],\n", + " [5, 3, 7, 6, 3, 9, 8, 4, 3, 0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9ZyUPfybTfej", + "outputId": "ac27a20e-1622-4cb9-d6f6-74ee467bdb72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [1],\n", + " [0],\n", + " [0],\n", + " [0],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nS1cPG3aRug1", + "outputId": "c70cf891-ae8f-445d-c271-c6b7f7da1738", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "# colocando o array a_conjunto2 do lado de a_conjunto1.\n", + "np.c_[a_conjunto1, a_conjunto2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 8, 2, 8, 9, 1, 8, 0, 4, 2, 1],\n", + " [0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 0],\n", + " [7, 9, 5, 6, 8, 7, 0, 9, 3, 9, 0],\n", + " [3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 0],\n", + " [8, 6, 6, 1, 0, 9, 2, 0, 7, 5, 0],\n", + " [5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 1],\n", + " [5, 0, 1, 2, 3, 8, 7, 5, 4, 0, 0],\n", + " [5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 0],\n", + " [2, 1, 0, 9, 1, 4, 2, 9, 7, 9, 0],\n", + " [5, 3, 7, 6, 3, 9, 8, 4, 3, 0, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kIgU1YBw0OeM" + }, + "source": [ + "___\n", + "# **Selecionar itens que satisfazem condições**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e2pL5anBV0DI", + "outputId": "f37cd827-ee00-49ba-994d-77cab3a24421", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1 = np.arange(10, 0, -1)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i9HuZZAfV302" + }, + "source": [ + "Selecionar somente os itens > 7:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZCESvr7iXMkV" + }, + "source": [ + "## Usando np.where()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdrAQLHkTS-v", + "outputId": "44a6e480-1b6c-4dad-ee29-2fcb4ada5097", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O_ZBaWxfWA9o", + "outputId": "fae44244-ff29-4b04-cd2d-a4c768487e75", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Índices do array que atendem a condição\n", + "l_indices = np.where(a_conjunto1 > 7)\n", + "l_indices" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(array([0, 1, 2]),)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EdWlfPOZWPME" + }, + "source": [ + "**Atenção**: Capturamos os índices. Para selecionar os itens, basta fazer:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tOxs3iYQWWxu", + "outputId": "b402fdfd-c6e0-4170-b35c-c7c5cd2ca85e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto2 = a_conjunto1[l_indices]\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PGsENqkaXRjh" + }, + "source": [ + "## Alternativa: Usando []" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YbdRNk1WXTLT", + "outputId": "062b157c-00fb-4f8f-d207-a0c8e9871e48", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1[a_conjunto1 > 7]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 9, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jijpzFxcSQC8" + }, + "source": [ + "Acho que vale a pena quebrar esta solução para entendermos melhor como as coisas funcionam:#" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rujhP2LQSWsq" + }, + "source": [ + " # Primeiro, avalie o resultado de a_conjunto1 > 7:" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FYZaBsasSb3N", + "outputId": "0a190896-249c-4d7c-ea0d-a20a53536446", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_conjunto1 > 7" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ True, True, True, False, False, False, False, False, False,\n", + " False])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvEof-UKaaVG" + }, + "source": [ + "a_conjunto1[a_conjunto1 > 7]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nO4FiBmDUZOT", + "outputId": "9f54e601-d95a-444c-bd59-28947e332248", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-1, -1, -1, 7, 6, 5, 4, 3, 2, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ci5lT9nmSfsX" + }, + "source": [ + "Agora, com este resultado, fica fácil entender como o Python seleciona os elementos. Consegue explicar?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1v5Lfin0GGKD" + }, + "source": [ + "# Substituir itens baseado em condições\n", + "> Substituir os valores negativos do array abaixo por 0." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CLY_u0ePWdN7" + }, + "source": [ + "## Gerar o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NUANFy-fNXf5" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(0, 10, size = 100))\n", + "\n", + "# Lista aleatória de índices que vou alterar\n", + "np.random.seed(20111974)\n", + "l_indices= np.random.randint(0, 99, 9)\n", + "\n", + "for i in l_indices:\n", + " a_conjunto1[i] = -1*a_conjunto1[i]\n", + "\n", + "a_conjunto2 = a_conjunto1.copy()\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dWVyI40uN2d2" + }, + "source": [ + "# Indices a serem multiplicados por -1:\n", + "l_indices" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Whuu854OJDZ" + }, + "source": [ + "## Substituir os valores negativos por 0" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sr268Rp8b-Se", + "outputId": "82514805-b350-45c4-a3fc-7cb24c847b7f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto2 < 0" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([False, False, False])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C-eKqPrfOQF6" + }, + "source": [ + "a_conjunto2[a_conjunto2 < 0] = 0\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eDLM0_JSZlfB" + }, + "source": [ + "Observe acima que os valores negativos foram substituídos por 0, como queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AEHJ0rA3dHHU" + }, + "source": [ + "## Substituir os valores negativos por 0 e os positivos por 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y32J8SRNZwRF" + }, + "source": [ + "a_conjunto2 = a_conjunto1.copy()\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1bSD9Fs6P5wW" + }, + "source": [ + "a_conjunto2 = np.where(a_conjunto2 <= 0, 0, 1)\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i027scjl0qkm" + }, + "source": [ + "___\n", + "# Outliers\n", + "> Qualquer ponto/observação que é incomum quando comparado com todos os outros pontos/observações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UnDTqRnZHQ3W" + }, + "source": [ + "## Z-Score\n", + "\n", + "* Z-Score pode ser utilizado para detectar Outliers.\n", + "* É a diferença entre o valor e a média da amostra expressa como o número de desvios-padrão. \n", + "* Se o escore z for menor que 2,5 ou maior que 2,5, o valor estará nos 5% do menor ou maior valor (2,5% dos valores em ambas as extremidades da distribuição). No entanto, é pratica comum utilizarmos 3 ao invés dos 2,5.\n", + "\n", + "![Z_Score](https://github.com/MathMachado/Materials/blob/master/Z_Score.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N7gb2zhtd0uM" + }, + "source": [ + "## IQR Score\n", + "\n", + "* O Intervalo interquartil (IQR) é uma medida de dispersão estatística, sendo igual à diferença entre os percentis 75 (Q3) e 25 (Q1), ou entre quartis superiores e inferiores, IQR = Q3 - Q1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lMmWOKNvghI7" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DUw_a-MjWvBc" + }, + "source": [ + "### Desafio para resolverem\n", + "> **Objetivo**: Simular aleatoriamente o salário de 1.000 pessoas com distribuição N(1.045; 100). \n", + "* Identificar os _outliers_ da distribuição que acabamos de simular;\n", + "* Qual a média da distribuição que simulamos?\n", + "* Qual o desvio-padrão;\n", + "* Plotar o Boxplot da distribuição dos dados;\n", + "* Quantas pessoas > Q3 + 1.5*(Q3-Q1)\n", + "* Substituir os outliers do array por:\n", + " * Q1-1.5*(Q3 - Q1), se ponto < Q1-1.5*(Q3-Q1)\n", + " * Q3+1.5*(Q3 - Q1), se ponto > Q3+1.5*(Q3-Q1)\n", + "\n", + "Obs.: Use np.random.seed(20111974)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L9ntAdS_oOAh" + }, + "source": [ + "### Geração aleatória do array a_salarios com distribuição $N(\\mu, \\sigma)$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RL0Zb0fyDory", + "outputId": "b66caa11-c8a4-4f9b-c5d0-23ace3f54a89", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "import numpy as np\n", + "np.random.seed(20111974)\n", + "np.set_printoptions(precision = 2, suppress = True)\n", + "\n", + "media = 1045\n", + "desvio_padrao = 100\n", + "i_tamanho = 1000\n", + "\n", + "a_salarios = np.array(np.random.normal(media, desvio_padrao, size = i_tamanho))\n", + "a_salarios[:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n", + " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n", + " 1088.61, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n", + " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n", + " 961.46, 903.51])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 1 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fc3a-yhViCTs" + }, + "source": [ + "### Geração aleatória dos índices que serão (manualmente) alterados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Iakt6i1cgEcB", + "outputId": "fc266c05-ffa5-457f-df79-1ac19df60878", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Lista aleatória de índices que vou alterar\n", + "np.random.seed(19741120)\n", + "l_indices = np.random.randint(0, i_tamanho, 10)\n", + "\n", + "# Estas são as posições que serão alteradas (manualmente)\n", + "np.sort(l_indices)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 14, 105, 208, 349, 484, 567, 615, 616, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oXwME1rciHkw" + }, + "source": [ + "### Cópia dos salários para compararmos o ANTES e DEPOIS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BEtnua7sgp_y", + "outputId": "a581c437-ba16-4768-8129-49f7f67bbff6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# cópia do array a_salarios\n", + "a_salarios_copia = a_salarios.copy()\n", + "a_salarios_copia2 = a_salarios.copy()\n", + "\n", + "a_salarios[:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n", + " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n", + " 1088.61, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n", + " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n", + " 961.46, 903.51])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "So8qj3Yrh-Az" + }, + "source": [ + "### Alteração (manual dos salários): 2 alternativas\n", + "> Vamos medir o tempo para avaliarmos o que é mais rápido. Qual solução é mais rápida?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z0613on8z5VH" + }, + "source": [ + "from timeit import default_timer as timer\n", + "from datetime import timedelta" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NpvvholVxMhs", + "outputId": "06c8c1ac-5a4c-42e8-a2c2-0840b15baf25", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Índices a serem alterados\n", + "l_indices" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([567, 14, 616, 484, 208, 105, 349, 615, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BqXsmMdm1yF-" + }, + "source": [ + "#### Solução 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FiiOrlnbgKOD", + "outputId": "728d7500-6870-4321-8f81-9b425d1fbcaa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Alteração dos salários dos índices propostos\n", + "start = timer()\n", + "for i_indice in l_indices:\n", + " a_salarios_copia[i_indice] = 2*a_salarios[i_indice] # Loop para os índices a serem alterados (manualmente)\n", + "\n", + "a_salarios_copia[:30]\n", + "end = timer()\n", + "print(timedelta(seconds=end-start))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000118\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgvKC-aFzWpZ" + }, + "source": [ + "#### Solução 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XWlQC5Jazt26", + "outputId": "3265351c-57b1-4bd4-864b-a614d9129d60", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "start = timer()\n", + "a_salarios_copia2[l_indices] = 2*a_salarios_copia2[l_indices] # Loop para os índices a serem alterados (manualmente)\n", + "a_salarios_copia2[:30]\n", + "end = timer()\n", + "\n", + "print(timedelta(seconds=end-start))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000251\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U92w03afhrmC" + }, + "source": [ + "### Compare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ls-jCFCYhtD8", + "outputId": "8b1dff92-91e3-4cc0-ecae-3c337dd53799", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Antes\n", + "a_salarios[l_indices]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 826.43, 1088.61, 1121.95, 833.96, 1165.97, 1081.13, 1078.51,\n", + " 1094.67, 904.32, 1128.66])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nwwU06OahzD2", + "outputId": "b5b5ca1f-a355-4604-96c5-a7d1736c8fc6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Depois\n", + "a_salarios_copia[l_indices]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1652.85, 2177.23, 2243.89, 1667.93, 2331.93, 2162.26, 2157.02,\n", + " 2189.34, 1808.63, 2257.32])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qyUUdHmtisJS", + "outputId": "9f926c6b-d17e-4bb8-ac0e-60008a40b2c4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras elementos de a_salarios\n", + "a_salarios[:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n", + " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n", + " 1088.61, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n", + " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n", + " 961.46, 903.51])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CJ1FEjlCi0-n", + "outputId": "caeb29f2-5c48-419e-c3fb-539dc1ded4fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras posições de a_salarios_copia\n", + "a_salarios_copia[:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n", + " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n", + " 2177.23, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n", + " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n", + " 961.46, 903.51])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbSUgxxiOUL" + }, + "source": [ + "### Algumas Estatísticas Descritivas:\n", + "#### Antes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZnmykyahLWX9", + "outputId": "288c4212-b78d-42a0-9f2d-e3676b738654", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Média: {np.mean(a_salarios)}; Mediana: {np.median(a_salarios)}; STD: {np.std(a_salarios)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 1047.150212238584; Mediana: 1047.631166829137; STD: 101.18708333868835'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ow7MHjgmPIty" + }, + "source": [ + "#### Depois" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5iO-BAikieHJ", + "outputId": "3e3f1ec5-47d1-4954-8362-c3d8d266d07e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Média: {np.mean(a_salarios_copia)}; Mediana: {np.median(a_salarios_copia)}; STD: {np.std(a_salarios_copia)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 1057.4744151862524; Mediana: 1048.089607774499; STD: 144.64306489539533'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILhNe80xW5C6" + }, + "source": [ + "### Solução do desafio" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OyFbWs-APowd", + "outputId": "bee45538-605a-4bc3-9508-2f3bd4b18883", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "\n", + "# Boxplot antes dos \"outliers\"\n", + "sns.boxplot(y = a_salarios)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAADrCAYAAACFMUa7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAReUlEQVR4nO3df2xd93nf8fdHEpJaATbLFOu5lDy5k5AtDbzAJRwDQ4dslm3ZaKygWwMbA8RlxuRijqyuAzpnBSoggYEWHRBYWmuAgwXLQObM+xFE2TQ7jDbM/8yp6cCV5cSp75w4FuEfLOUqw5SmlfXsDx4tNzQp8vJSvGTP+wVc3HOe8733PtcwPzz6nu/lTVUhSWqHDYNuQJK0egx9SWoRQ1+SWsTQl6QWMfQlqUUMfUlqkU2DbuBytm7dWjt27Bh0G5K0rrzwwgt/UlXD8x1b06G/Y8cOJicnB92GJK0rSV5f6JjTO5LUIouGfpKjSd5JcnqeY/8iSSXZ2uwnyeEknSSnktzUNXYsyavNbWxl34YkaSmWcqb/OLBnbjHJduB24Add5TuBXc1tP/BoM/Ya4BDwceBm4FCSLf00Lknq3aKhX1XPAmfnOfRF4DeB7j/esxd4omY9B1yd5DrgDmCiqs5W1bvABPP8IpEkXVnLmtNPsheYqqo/mnNoBHija/9MU1uoLq1LMzMzPPjgg8zMzAy6FaknPYd+ks3AvwJ+e+XbgST7k0wmmZyenr4SLyH17dixY7z00ks88cQTg25F6slyzvT/BnAD8EdJvg9sA76V5K8BU8D2rrHbmtpC9fepqvGqGq2q0eHheZeZSgM1MzPD008/TVXx9NNPe7avdaXn0K+ql6rqZ6tqR1XtYHaq5qaqegs4DuxrVvHcApyrqjeBZ4Dbk2xpLuDe3tSkdefYsWNcvHgRgPfee8+zfa0rS1my+STwv4APJzmT5L7LDD8BvAZ0gH8L/DOAqjoLfAF4vrl9vqlJ6843vvENLly4AMCFCxeYmJgYcEfS0i36idyquneR4zu6tgt4YIFxR4GjPfYnrTm7d+/mxIkTXLhwgU2bNnHbbbcNuiVpyfxErtSjsbExNmyY/dHZuHEj+/btG3BH0tIZ+lKPhoaG2LNnD0nYs2cPQ0NDg25JWjJDX1qGu+++m82bN/PJT35y0K1IPTH0pWU4fvw458+f52tf+9qgW5F6YuhLPXKdvtYzQ1/qkev0tZ4Z+lKPXKev9czQl3q0e/duNm2a/YiL6/S13hj6Uo9cp6/1zNCXeuQ6fa1na/qL0aW1amxsjO9///ue5WvdMfSlZRgaGuLw4cODbkPqmdM7ktQinulryY4cOUKn0xl0G2vC1NTsdwCNjPitnwA7d+7kwIEDg25DS2DoS8vwox/9aNAtSMti6GvJPJP7iYMHDwLwyCOPDLgTqTfO6UtSixj6ktQihr4ktYihL0ktsmjoJzma5J0kp7tqX0hyKsmLSb6e5OeaepIcTtJpjt/U9ZixJK82t7Er83YkSZezlDP9x4E9c2q/V1U3VtXHgP8C/HZTvxPY1dz2A48CJLkGOAR8HLgZOJRkS9/dS5J6smjoV9WzwNk5tR927X4IqGZ7L/BEzXoOuDrJdcAdwERVna2qd4EJ3v+LRJJ0hS17nX6Sh4F9wDng7zXlEeCNrmFnmtpCdUnSKlr2hdyq+q2q2g58CfjsSjWUZH+SySST09PTK/W0kiRWZvXOl4B/0GxPAdu7jm1ragvV36eqxqtqtKpGh4eHV6A9SdIlywr9JLu6dvcCrzTbx4F9zSqeW4BzVfUm8Axwe5ItzQXc25uaJGkVLTqnn+RJ4BPA1iRnmF2Fc1eSDwMXgdeBX2uGnwDuAjrAeeAzAFV1NskXgOebcZ+vqp+6OCxJuvIWDf2qunee8mMLjC3ggQWOHQWO9tSdJGlF+YlcSWoRQ1+SWsTQl6QWMfQlqUUMfUlqEUNfklrE0JekFjH0JalFDH1JahFDX5JaxNCXpBYx9CWpRQx9SWoRQ1+SWsTQl6QWMfQlqUUMfUlqEUNfklrE0JekFjH0JalFDH1JapFFQz/J0STvJDndVfu9JK8kOZXkK0mu7jr2uSSdJN9NckdXfU9T6yR5aOXfiiRpMUs5038c2DOnNgF8tKpuBP4Y+BxAko8A9wC/0DzmD5JsTLIR+H3gTuAjwL3NWEnSKlo09KvqWeDsnNrXq+pCs/scsK3Z3gt8uap+XFXfAzrAzc2tU1WvVdWfA19uxkqSVtFKzOn/E+C/NdsjwBtdx840tYXqkqRV1FfoJ/kt4ALwpZVpB5LsTzKZZHJ6enqlnlaSRB+hn+QfA78M/KOqqqY8BWzvGratqS1Uf5+qGq+q0aoaHR4eXm57kqR5LCv0k+wBfhO4u6rOdx06DtyT5INJbgB2AX8IPA/sSnJDkg8we7H3eH+tS5J6tWmxAUmeBD4BbE1yBjjE7GqdDwITSQCeq6pfq6qXkzwFfJvZaZ8Hquq95nk+CzwDbASOVtXLV+D9SJIuY9HQr6p75yk/dpnxDwMPz1M/AZzoqTtJ0oryE7mS1CKGviS1iKEvSS1i6EtSixj6ktQihr4ktYihL0ktYuhLUosY+pLUIoa+JLWIoS9JLWLoS1KLGPqS1CKGviS1iKEvSS1i6EtSixj6ktQihr4ktciiX5fYdkeOHKHT6Qy6Da0xl/6fOHjw4IA70Vqzc+dODhw4MOg2FmToL6LT6fDi6e/w3uZrBt2K1pANf14AvPDa2wPuRGvJxvNnB93Cogz9JXhv8zX86G/eNeg2JK1xV71yYtAtLGrROf0kR5O8k+R0V+1Xk7yc5GKS0TnjP5ekk+S7Se7oqu9pap0kD63s25AkLcVSLuQ+DuyZUzsN/ArwbHcxyUeAe4BfaB7zB0k2JtkI/D5wJ/AR4N5mrCRpFS06vVNVzybZMaf2HYAkc4fvBb5cVT8GvpekA9zcHOtU1WvN477cjP12P81Lknqz0ks2R4A3uvbPNLWF6u+TZH+SySST09PTK9yeJLXbmlunX1XjVTVaVaPDw8ODbkeS/lJZ6dU7U8D2rv1tTY3L1CVJq2Slz/SPA/ck+WCSG4BdwB8CzwO7ktyQ5APMXuw9vsKvLUlaxKJn+kmeBD4BbE1yBjgEnAWOAMPAf03yYlXdUVUvJ3mK2Qu0F4AHquq95nk+CzwDbASOVtXLV+INSZIWtpTVO/cucOgrC4x/GHh4nvoJYO1/ckGS/hJbcxdyJUlXjqEvSS1i6EtSixj6ktQihr4ktYihL0ktYuhLUosY+pLUIoa+JLWIX5e4iKmpKTaeP7cuvgZN0mBtPD/D1NSFQbdxWZ7pS1KLeKa/iJGREd768Sa/GF3Soq565QQjI9cOuo3L8kxfklrE0JekFjH0JalFDH1JahFDX5JaxNCXpBYx9CWpRQx9SWqRRUM/ydEk7yQ53VW7JslEkleb+y1NPUkOJ+kkOZXkpq7HjDXjX00ydmXejiTpcpZypv84sGdO7SHgZFXtAk42+wB3Arua237gUZj9JQEcAj4O3AwcuvSLQpK0ehYN/ap6Fjg7p7wXONZsHwM+1VV/omY9B1yd5DrgDmCiqs5W1bvABO//RSJJusKWO6d/bVW92Wy/BVz6YxMjwBtd4840tYXqkqRV1PeF3KoqoFagFwCS7E8ymWRyenp6pZ5WksTyQ//tZtqG5v6dpj4FbO8at62pLVR/n6oar6rRqhodHh5eZnuSpPksN/SPA5dW4IwBX+2q72tW8dwCnGumgZ4Bbk+ypbmAe3tTkyStokX/nn6SJ4FPAFuTnGF2Fc7vAE8luQ94Hfh0M/wEcBfQAc4DnwGoqrNJvgA834z7fFXNvTgsSbrCFg39qrp3gUO3zjO2gAcWeJ6jwNGeupMkrSg/kStJLWLoS1KL+B25S7Dx/FmueuXEoNvQGrLhz34IwMWf+SsD7kRrycbzZ/nJx5bWJkN/ETt37hx0C1qDOp3/A8DOn1/bP+Babdeu+cww9Bdx4MCBQbegNejgwYMAPPLIIwPuROqNc/qS1CKGviS1iKEvSS1i6EtSixj6ktQihr4ktYihL0ktYuhLUosY+pLUIoa+JLWIoS9JLWLoS1KLGPqS1CKGviS1iKEvSS1i6EtSi/QV+kkOJjmd5OUkv97UrkkykeTV5n5LU0+Sw0k6SU4luWkl3oAkaemWHfpJPgr8U+Bm4G8Dv5xkJ/AQcLKqdgEnm32AO4FdzW0/8GgffUuSlqGfM/2/BXyzqs5X1QXgfwK/AuwFjjVjjgGfarb3Ak/UrOeAq5Nc18frS5J61E/onwZ+KclQks3AXcB24NqqerMZ8xY/+Wr4EeCNrsefaWqSpFWy7C9Gr6rvJPld4OvA/wVeBN6bM6aSVC/Pm2Q/s9M/XH/99cttT5I0j74u5FbVY1X1i1X1d4F3gT8G3r40bdPcv9MMn2L2XwKXbGtqc59zvKpGq2p0eHi4n/YkSXP0u3rnZ5v765mdz/93wHFgrBkyBny12T4O7GtW8dwCnOuaBpIkrYJlT+80/lOSIeAvgAeq6k+T/A7wVJL7gNeBTzdjTzA7798BzgOf6fO1JUk96iv0q+qX5qnNALfOUy/ggX5eT5LUHz+RK0ktYuhLUosY+pLUIoa+JLWIoS9JLWLoS1KLGPqS1CKGviS1iKEvSS1i6EtSixj6ktQihr4ktYihL0ktYuhLUosY+pLUIoa+JLWIoS9JLWLoS1KLGPqS1CKGviS1iKEvSS3SV+gn+edJXk5yOsmTSX4myQ1Jvpmkk+TfJ/lAM/aDzX6nOb5jJd6AJGnplh36SUaAB4HRqvoosBG4B/hd4ItVtRN4F7ivech9wLtN/YvNOEnSKup3emcTcFWSTcBm4E3g7wP/sTl+DPhUs7232ac5fmuS9Pn6kqQeLDv0q2oK+NfAD5gN+3PAC8CfVtWFZtgZYKTZHgHeaB57oRk/NPd5k+xPMplkcnp6erntSZLm0c/0zhZmz95vAH4O+BCwp9+Gqmq8qkaranR4eLjfp5Mkdelnemc38L2qmq6qvwD+M/B3gKub6R6AbcBUsz0FbAdojv9VYKaP15ck9aif0P8BcEuSzc3c/K3At4H/AfzDZswY8NVm+3izT3P8v1dV9fH6kqQe9TOn/01mL8h+C3ipea5x4F8Cv5Gkw+yc/WPNQx4Dhpr6bwAP9dG3JGkZNi0+ZGFVdQg4NKf8GnDzPGP/DPjVfl5PktQfP5ErSS1i6EtSixj6ktQihr4ktYihL0kt0tfqHbXLkSNH6HQ6g25jTbj03+HgwYMD7mRt2LlzJwcOHBh0G1oCQ19ahquuumrQLUjLYuhryTyTk9Y/5/QlqUUMfUlqEUNfklrE0JekFjH0pWWYmZnhwQcfZGbGr4TQ+mLoS8swPj7OqVOnGB8fH3QrUk8MfalHMzMzTExMADAxMeHZvtYVQ1/q0fj4OBcvXgTg4sWLnu1rXTH0pR6dPHnysvvSWmboSz2a+9XOftWz1hNDX+rRrbfe+lP7u3fvHlAnUu8MfalH999/Pxs2zP7obNiwgf379w+4I2nplh36ST6c5MWu2w+T/HqSa5JMJHm1ud/SjE+Sw0k6SU4luWnl3oa0eoaGhv7/2f1tt93G0NDQgDuSlm7ZoV9V362qj1XVx4BfBM4DXwEeAk5W1S7gZLMPcCewq7ntBx7tp3FpkO6//35uvPFGz/K17qzU9M6twP+uqteBvcCxpn4M+FSzvRd4omY9B1yd5LoVen1pVQ0NDXH48GHP8rXurFTo3wM82WxfW1VvNttvAdc22yPAG12POdPUJEmrpO/QT/IB4G7gP8w9VrNr2Xpaz5Zkf5LJJJPT09P9tidJ6rISZ/p3At+qqreb/bcvTds09+809Slge9fjtjW1n1JV41U1WlWjw8PDK9CeJOmSlQj9e/nJ1A7AcWCs2R4DvtpV39es4rkFONc1DSRJWgXp59OEST4E/AD4+ao619SGgKeA64HXgU9X1dkkAf4NsIfZlT6fqarJRZ5/unkOaS3aCvzJoJuQ5vHXq2reqZK+Ql9qsySTVTU66D6kXviJXElqEUNfklrE0JeWzz+kr3XHOX1JahHP9CWpRQx9SWoRQ1+SWsTQl6QWMfQlqUX+Hw7RzvrAsf4dAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U993i1GJg2hk", + "outputId": "6f8719c1-df46-42d4-f816-b3a1ada3d7b5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 271 + } + }, + "source": [ + "# Boxplot do array a_salarios_copia depois dos \"outliers\"\n", + "sns.boxplot(y = a_salarios_copia)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VtenLK1uK1Pi" + }, + "source": [ + "Consegue identificar os outliers do array?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e3sHuGVGFBdW" + }, + "source": [ + "## Objetivo\n", + "> Identificar e substituir os outliers pela mediana dos dados. \n", + "\n", + "* Como fazer isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSegPNKCI-dS" + }, + "source": [ + "### Siga os passos a seguir\n", + "1. Calcule estatísticas descritivas antes das transformações par avaliar o impacto;\n", + " * Calcule média, mediana e desvio-padrão dos dados originais;\n", + "2. Calcule os valores a seguir:\n", + " * Q1, Q3\n", + " * IQR = Q3-Q1\n", + " * lim_inferior_outlier = Q1-1.5\\*IQR\n", + " * lim_superior_outlier = Q3+1.5\\*IQR\n", + "3. Proceda à substituição:\n", + " * Se a_salarios_copia[i] < lim_inferior_outlier então a_salarios_copia[i]= Mediana\n", + " * Se a_salarios_copia[i] > lim_superior_outlier então a_salarios_copia[i]= Mediana\n", + "4. Calcule as estatísticas descritivas após as substituições e compare com os valores antes das transformações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9DQ7YnWaFn4v" + }, + "source": [ + "### Minha solução\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RBXJbTeGLC7Q" + }, + "source": [ + "1. Estatísticas Descritivas antes das transformações:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QueKYn7MLG12", + "outputId": "75489f71-3f1e-4819-b5fe-21f134bf2b1e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_salarios_copia)}; Mediana: {np.median(a_salarios_copia)}; STD: {np.std(a_salarios_copia)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 1057.4744151862524; Mediana: 1048.089607774499; STD: 144.64306489539533'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oOBJ8INWL5fo" + }, + "source": [ + "Observe o quanto nossos dados estão distorcidos dos valores originalmente utilizados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MX-fJeh2MBTD" + }, + "source": [ + "2. Calcular Q1, Q3 e IQR" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JlsPiQeGMGeU" + }, + "source": [ + "Q1 = np.percentile(a_salarios_copia, q = [25])\n", + "Q3 = np.percentile(a_salarios_copia, q = [75])\n", + "Q2 = np.percentile(a_salarios_copia, q = [50])\n", + "p99 = np.percentile(a_salarios_copia, q = [99])\n", + "p95 = np.percentile(a_salarios_copia, q = [95])\n", + "\n", + "IQR = Q3-Q1 # Diferença interquartílica\n", + "lim_inferior_outlier = Q1-1.5*IQR\n", + "lim_superior_outlier = Q3+1.5*IQR" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VF2NJ3rCeI1_", + "outputId": "34a2097c-334f-472f-9fe0-7198ea827e47", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Q1: {Q1}; Q3: {Q3}; lim_inferior_outlier: {lim_inferior_outlier}; lim_superior_outlier: {lim_superior_outlier}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Q1: [974.41]; Q3: [1119.81]; lim_inferior: [756.33]; lim_superior: [1337.89]'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjnwJ7HwMxcl" + }, + "source": [ + "3. Substituir\n", + "* Se a_salarios[i] < lim_inferior_outlier --> a_salarios[i] = Mediana\n", + "* Se a_salarios[i] > lim_superior_outlier --> a_salarios[i] = Mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcAn-IwVfbcI" + }, + "source": [ + "a_salarios2 = a_salarios_copia.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M4UJY4vbRics", + "outputId": "8792d911-f1f7-4068-ba6e-d9e42674be7a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "Q2[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1048.089607774499" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3SSE45oM9oh", + "outputId": "f6c222d1-3b09-4500-fbde-79a513097aa8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_salarios2[a_salarios2 < lim_inferior_outlier[0]] = Q2[0] # Atribuição da Mediana\n", + "a_salarios2[a_salarios2 > lim_superior_outlier[0]] = Q2[0] # Atribuição da Mediana\n", + "a_salarios2[:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n", + " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n", + " 1048.09, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n", + " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n", + " 961.46, 903.51])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VEGFio0Nfj7O" + }, + "source": [ + "4. Estatísticas Descritivas para avaliarmos o impacto das alterações na amostra:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gX1LZHFqfjFQ", + "outputId": "5749f50a-88b3-4bbe-8886-74db69c975d4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas - Depois do trtamento de OUtliers:\n", + "f'Média: {np.mean(a_salarios2)}; Mediana: {np.median(a_salarios2)}; STD: {np.std(a_salarios2)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 1047.3019702056902; Mediana: 1048.089607774499; STD: 98.3265929249586'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cSXrg2PFSYKY", + "outputId": "771a880e-398f-4765-9d84-f93342b9c34d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas - Antes do trtamento de OUtliers:\n", + "f'Média: {np.mean(a_salarios)}; Mediana: {np.median(a_salarios)}; STD: {np.std(a_salarios)}'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Média: 1047.150212238584; Mediana: 1047.631166829137; STD: 101.18708333868835'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZVc6_nsGS_J2" + }, + "source": [ + "### Exercício: Substituir e comentar com seus respectivos colegas de grupo quando substituimos:\n", + "* Q2[0] pela média.\n", + "* Q2[0] pelo valor do percentil 95 e 99." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-xnguZ7XgyvK", + "outputId": "95e3ea05-085a-4684-ccd6-deef149e8476", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 269 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "sns.boxplot(y = a_salarios2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uEPFcBjFhETQ" + }, + "source": [ + "Como podem ver, os outliers desapareceram, como queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tHfzjW_ymKuR" + }, + "source": [ + "___\n", + "# **Valores únicos**\n", + "> Considere o array de a_idades a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HzmQgWZVmUUD", + "outputId": "a8fe3bba-2483-4c62-8d46-963f79ae0462", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 121 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "a_idades = np.random.randint(18, 100, 100)\n", + "a_idades" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([78, 60, 58, 26, 45, 20, 64, 99, 98, 31, 48, 81, 97, 90, 31, 85, 51,\n", + " 91, 95, 60, 73, 63, 59, 39, 40, 26, 80, 28, 18, 33, 27, 85, 53, 60,\n", + " 26, 44, 23, 86, 92, 75, 58, 40, 63, 24, 99, 18, 43, 68, 98, 94, 47,\n", + " 25, 39, 23, 70, 49, 96, 79, 68, 68, 25, 59, 21, 51, 65, 23, 34, 51,\n", + " 37, 78, 74, 73, 71, 46, 34, 45, 40, 56, 67, 31, 22, 43, 65, 64, 36,\n", + " 76, 19, 82, 75, 35, 38, 68, 43, 73, 91, 92, 61, 37, 73, 72])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 73 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dm9ky1F1mrNA" + }, + "source": [ + "Quem são os valores únicos do array?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-LPRqc-mS5j", + "outputId": "6c61d635-95b9-4cec-e7d8-12ec2b0e0322", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 87 + } + }, + "source": [ + "np.unique(a_idades)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 33, 34, 35, 36, 37,\n", + " 38, 39, 40, 43, 44, 45, 46, 47, 48, 49, 51, 53, 56, 58, 59, 60, 61,\n", + " 63, 64, 65, 67, 68, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82,\n", + " 85, 86, 90, 91, 92, 94, 95, 96, 97, 98, 99])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 74 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uXZZoTd6nMuq" + }, + "source": [ + "___\n", + "# **Diferença entre dois arrays**\n", + "> O resultado é um array com os **valores únicos de A que não estão em B**. Na teoria de conjuntos escrevemos $A - B = A - A \\cap B$.\n", + "\n", + "![Difference](https://github.com/MathMachado/Materials/blob/master/set_Difference.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uW6i3m9q1ZNs" + }, + "source": [ + "\n", + "* Vamos ver como isso funciona na prática:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vw05sfe22mfk" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qqw2do90nQ7k" + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 4, 5, 7, 8, 8]) # array de valores que serão excluidos em a_conjunto1. Observe que '3' não pertence a a_conjunto1.\n", + "a_conjunto2 = np.array([1, 6, 7, 3])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zXJ00pOMorM-", + "outputId": "c3108557-ad55-45cc-f707-3af35cf456c1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "np.setdiff1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 4, 5, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8GXZNgjfo8lO" + }, + "source": [ + "Observe que o resultado são os elementos de a_conjunto1 que não pertencem a x_Y. Mas como fica o '3' nesta história?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aJSu6VKb2oc_" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N1wahElXTqoB" + }, + "source": [ + "a_conjunto1 = np.arange(10)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nxDpCMg7T7Rj" + }, + "source": [ + "a_conjunto2 = np.array([1, 5, 7])\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3LU3qYyiUXqm" + }, + "source": [ + "np.setdiff1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mzZEytrRUioU" + }, + "source": [ + "Observe que os elementos de a_conjunto2 foram deletados de a_conjunto1. Ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gJRcoVRUnaY9" + }, + "source": [ + "___\n", + "# Diferença Simétrica\n", + "* Em teoria de conjuntos, chamamos de Diferença Simétrica e escrevemos $(A \\cup B)- (A \\cap B)$.\n", + "\n", + "![DifferenceSymetric](https://github.com/MathMachado/Materials/blob/master/set_DifferenceSymetric.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2Uzzm85Kup3H" + }, + "source": [ + "* Vamos ver como isso funciona na prática:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1z5wZ8VwpsWN" + }, + "source": [ + "import numpy as np\n", + "a_conjunto1 = np.array([0, 1, 2, 4, 5, 7, 8]) # Observe que [1, 4, 7] pertencem a a_conjunto1, mas 3, não. Portanto:\n", + "a_conjunto2 = np.array([1, 4, 7, 3])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tqd_9XO5p7bo", + "outputId": "d7670965-e38f-40a1-9864-8ec850143245", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "np.setxor1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 3, 5, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_meurG3mqS5Y" + }, + "source": [ + "Como explicamos ou interpretamos este resultado?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kc8JoKe2nj2n" + }, + "source": [ + "___\n", + "# **União de dois arrays**\n", + "> Retorna os valores **únicos** dos dois arrays. Na teoria dos conjuntos, escrevemos:\n", + "\n", + "$$A \\cup B$$\n", + "\n", + "![Union](https://github.com/MathMachado/Materials/blob/master/set_Union.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1LZxorw2p2mg" + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 4, 5, 7, 8, 8])\n", + "\n", + "# Observe que [1, 4, 7] pertencem a a_conjunto1, mas 3, não. Portanto:\n", + "a_conjunto2 = np.array([1, 4, 7, 3])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "COsZEmSwuY5L" + }, + "source": [ + "np.union1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b53bR-GYRu_3" + }, + "source": [ + "___\n", + "# **Selecionar itens comuns dos arrays X e Y**\n", + "* Na teoria de conjuntos, chamamos de intersecção e escrevemos $X \\cap Y$.\n", + "\n", + "![Intersection](https://github.com/MathMachado/Materials/blob/master/set_Intersection.PNG?raw=true)\n", + "\n", + "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n2ec2tqqR1Gw" + }, + "source": [ + "* Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rXVQQvBqR4J-", + "outputId": "c1332edd-af01-45cb-d3e1-c6e3ba30e157", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "a_conjunto1 = np.arange(10)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 53 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pZTHhHxGSRfB", + "outputId": "2c93501a-3ed8-4297-d58e-990c529a5a3d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "a_conjunto2 = np.arange(8, 18)\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 54 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MxB2_qHpScMB" + }, + "source": [ + "Quais são os elementos comuns à X e Y?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e-rncJHtSfw0", + "outputId": "11f0b85d-c634-419a-cc62-e0899f9cef31", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "np.intersect1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 55 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Bb39sWdfqaF" + }, + "source": [ + "___\n", + "# **Autovalores e Autovetores**\n", + "> Autovetor e Autovalor são um dos tópicos mais importantes em Machine Learning.\n", + "\n", + "Por definição, o escalar $\\lambda$ e o vetor $v$ são autovalor e autovetor da matriz $A$ se\n", + "\n", + "$$Av = \\lambda v$$\n", + "\n", + "## Leitura Adicional:\n", + "\n", + "* [Machine Learning & Linear Algebra — Eigenvalue and eigenvector](https://medium.com/@jonathan_hui/machine-learning-linear-algebra-eigenvalue-and-eigenvector-f8d0493564c9)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XZBKq8nGCUbL" + }, + "source": [ + "* O array a_conjunto2 tem a seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iYlZGKFUfw-R" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6EfvIbBNf02Z" + }, + "source": [ + "# Calcula autovalores e autovetores:\n", + "a_autovalores, a_autovalores= np.linalg.eig(a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v3GtQQvAz9QU" + }, + "source": [ + "Os autovalores do array a_conjunto2 são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WvZGyBR1f9vP" + }, + "source": [ + "a_autovalores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AuuDRJVh0FC8" + }, + "source": [ + "Os autovetores do array a_conjunto2 são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6m4YFAwsf_rA" + }, + "source": [ + "a_autovalores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DASn2Un9ZNV-" + }, + "source": [ + "___\n", + "# **Encontrar Missing Values (NaN)**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TKilWBsSXtR4" + }, + "source": [ + "## Gerar o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lqLI2ER_ZUMY" + }, + "source": [ + "import numpy as np\n", + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.random(100)\n", + "\n", + "# Inserindo 15 NaN's no array:\n", + "np.random.seed(20111974)\n", + "l_indices_aleatorios= np.random.randint(0, 100, size = 15)\n", + "\n", + "for i_indices in l_indices_aleatorios:\n", + " #print(i_indices)\n", + " a_conjunto1[i_indices] = np.nan" + ], + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gw--poMaadv3", + "outputId": "53e3313d-21b5-4bee-b469-c9898dfa00fb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_indices_aleatorios" + ], + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([60, 42, 40, 8, 27, 2, 46, 88, 81, 88, 80, 13, 30, 82, 96])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ZkbMPXMawYh", + "outputId": "c23cbf32-34e4-4e15-cf93-b04d6b50ed45", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 4, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, nan, 0.65478409, 0.85708456,\n", + " 0.60174181, 0.87298309, 0.45573342, nan, 0.64300912,\n", + " 0.54808035, 0.35321428, 0.32005665, nan, 0.85159044,\n", + " 0.75930202, 0.65675987, 0.3278323 , 0.34592275, 0.41510657,\n", + " 0.30635652, 0.26750355, 0.30663224, 0.35503537, 0.60299892,\n", + " 0.0221767 , 0.36265947, nan, 0.28077438, 0.37056609,\n", + " nan, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " nan, 0.14442301, nan, 0.70671296, 0.07163699,\n", + " 0.56212721, nan, 0.83632274, 0.21435895, 0.85491145,\n", + " 0.62878505, 0.38468856, 0.90553087, 0.33703023, 0.06707729,\n", + " 0.1023552 , 0.84821523, 0.12156391, 0.94423963, 0.15835682,\n", + " nan, 0.91080887, 0.58558559, 0.36799242, 0.71647196,\n", + " 0.0740405 , 0.47889268, 0.77503169, 0.96720855, 0.71575223,\n", + " 0.28887146, 0.33306388, 0.95399002, 0.23557899, 0.97714605,\n", + " 0.85188315, 0.63303051, 0.57297905, 0.66792818, 0.87621361,\n", + " nan, nan, nan, 0.68323127, 0.28826713,\n", + " 0.32846648, 0.98334327, 0.17156066, nan, 0.91917489,\n", + " 0.98381602, 0.75915187, 0.31400247, 0.97074481, 0.07574498,\n", + " 0.55661541, nan, 0.4936932 , 0.07351232, 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 4 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z7Bs75NvbSjx" + }, + "source": [ + "Ok, inserimos aleatoriamente 14 NaN's no array a_conjunto1. Agora, vamos contar quantos NaN's (já sabemos a resposta!)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hL1Wn0vdX8ur" + }, + "source": [ + "## Identificar os NaN's" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5R-n3H0xbd6d", + "outputId": "227eef3e-0d3f-4a98-f95a-cbdffff6e77b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan(a_conjunto1).sum()" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y7hh5uowoa3U" + }, + "source": [ + "Ok, temos 14 NaN's em a_conjunto1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iVLQf_bqbyNU" + }, + "source": [ + "Ok, agora eu quero saber os índices desses NaN's." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kJHxjZiwb5HM", + "outputId": "adf8ae23-3be3-473b-d04e-cb973e145dfa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_indices = np.where(np.isnan(a_conjunto1))\n", + "i_indices" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(array([ 2, 8, 13, 27, 30, 40, 42, 46, 60, 80, 81, 82, 88, 96]),)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W_jHGNImok7L", + "outputId": "da396cce-64d9-4d31-ed2f-eac04e37ff36", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Checando...\n", + "a_conjunto1[2]" + ], + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "nan" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iPhHAhDYcMWO" + }, + "source": [ + "Vamos conferir se está correto? Para isso, basta comparar com l_indices_aleatorios:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gxQYslRCe11G" + }, + "source": [ + "___\n", + "# **Deletar NaN's de um array**\n", + "> Considere o mesmo array que acabamos de trabalhar. Agora eu quero excluir os NaN's identificados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AeBARFqNfNnN", + "outputId": "7c991ca5-7403-492d-9fef-b03de1e4da34", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, nan, 0.65478409, 0.85708456,\n", + " 0.60174181, 0.87298309, 0.45573342, nan, 0.64300912,\n", + " 0.54808035, 0.35321428, 0.32005665, nan, 0.85159044,\n", + " 0.75930202, 0.65675987, 0.3278323 , 0.34592275, 0.41510657,\n", + " 0.30635652, 0.26750355, 0.30663224, 0.35503537, 0.60299892,\n", + " 0.0221767 , 0.36265947, nan, 0.28077438, 0.37056609,\n", + " nan, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " nan, 0.14442301, nan, 0.70671296, 0.07163699,\n", + " 0.56212721, nan, 0.83632274, 0.21435895, 0.85491145,\n", + " 0.62878505, 0.38468856, 0.90553087, 0.33703023, 0.06707729,\n", + " 0.1023552 , 0.84821523, 0.12156391, 0.94423963, 0.15835682,\n", + " nan, 0.91080887, 0.58558559, 0.36799242, 0.71647196,\n", + " 0.0740405 , 0.47889268, 0.77503169, 0.96720855, 0.71575223,\n", + " 0.28887146, 0.33306388, 0.95399002, 0.23557899, 0.97714605,\n", + " 0.85188315, 0.63303051, 0.57297905, 0.66792818, 0.87621361,\n", + " nan, nan, nan, 0.68323127, 0.28826713,\n", + " 0.32846648, 0.98334327, 0.17156066, nan, 0.91917489,\n", + " 0.98381602, 0.75915187, 0.31400247, 0.97074481, 0.07574498,\n", + " 0.55661541, nan, 0.4936932 , 0.07351232, 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ck1w6_Tvb72M", + "outputId": "af2fc919-3ccf-457a-c493-f775addd9eb6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + "np.isnan(a_conjunto1)" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([False, False, True, False, False, False, False, False, True,\n", + " False, False, False, False, True, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " True, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, True, False, True, False, False,\n", + " False, True, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, True,\n", + " True, True, False, False, False, False, False, True, False,\n", + " False, False, False, False, False, False, True, False, False,\n", + " False])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e497B492fFru", + "outputId": "90ea8d35-7338-46d6-d1bc-1c14a4a7030b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 323 + } + }, + "source": [ + "a_conjunto1[~np.isnan(a_conjunto1)]" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53097233, 0.56965626, 0.65478409, 0.85708456, 0.60174181,\n", + " 0.87298309, 0.45573342, 0.64300912, 0.54808035, 0.35321428,\n", + " 0.32005665, 0.85159044, 0.75930202, 0.65675987, 0.3278323 ,\n", + " 0.34592275, 0.41510657, 0.30635652, 0.26750355, 0.30663224,\n", + " 0.35503537, 0.60299892, 0.0221767 , 0.36265947, 0.28077438,\n", + " 0.37056609, 0.43587362, 0.20494254, 0.20850854, 0.64886762,\n", + " 0.81792888, 0.71541492, 0.50313939, 0.1657674 , 0.60122378,\n", + " 0.14442301, 0.70671296, 0.07163699, 0.56212721, 0.83632274,\n", + " 0.21435895, 0.85491145, 0.62878505, 0.38468856, 0.90553087,\n", + " 0.33703023, 0.06707729, 0.1023552 , 0.84821523, 0.12156391,\n", + " 0.94423963, 0.15835682, 0.91080887, 0.58558559, 0.36799242,\n", + " 0.71647196, 0.0740405 , 0.47889268, 0.77503169, 0.96720855,\n", + " 0.71575223, 0.28887146, 0.33306388, 0.95399002, 0.23557899,\n", + " 0.97714605, 0.85188315, 0.63303051, 0.57297905, 0.66792818,\n", + " 0.87621361, 0.68323127, 0.28826713, 0.32846648, 0.98334327,\n", + " 0.17156066, 0.91917489, 0.98381602, 0.75915187, 0.31400247,\n", + " 0.97074481, 0.07574498, 0.55661541, 0.4936932 , 0.07351232,\n", + " 0.11418944])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpvKfJU_fmA6" + }, + "source": [ + "Observe que os NaN's foram excluidos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "60-l91_ccJxt" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kywe-SmtcLpF" + }, + "source": [ + "### **Exercício**: Atribuir a mediana aos valores nan da amostra." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_Dv8MmNYg8zN" + }, + "source": [ + "___\n", + "# **Converter lista em array**\n", + "> Considere a lista a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "but6T9dVhFYb" + }, + "source": [ + "l_Lista = [np.random.randint(0, 10, 10)]\n", + "l_Lista" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xytj4Eo4hTh9" + }, + "source": [ + "type(l_Lista)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qrINdcruhWcH" + }, + "source": [ + "Convertendo a minha lista para array:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RoSyaX0OhZSE" + }, + "source": [ + "a_conjunto = np.asarray(l_Lista)\n", + "a_conjunto" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMjTdbBUhlrk" + }, + "source": [ + "type(a_conjunto)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mbm3ZP9DhxDI" + }, + "source": [ + "___\n", + "# Converter tupla em array\n", + "> Considere a tupla a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cZxEFYLAh3S_" + }, + "source": [ + "np.random.seed(20111974)\n", + "t_numeros = ([np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)])\n", + "t_numeros" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vlTXUJviiAml" + }, + "source": [ + "type(t_numeros)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yEaOlq8oh3oh" + }, + "source": [ + "a_conjunto = np.asarray(t_numeros)\n", + "a_conjunto" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PSgQDmRWh3g5" + }, + "source": [ + "type(a_conjunto)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pH-Ht6yMiqJN" + }, + "source": [ + "___\n", + "# Acrescentar elementos à um array\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dFaDZInZiwoo" + }, + "source": [ + "a_conjunto1 = np.arange(5)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "d3zrlf_Ci73Z" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.append(a_conjunto1, [np.random.randint(0, 10, 3), np.random.randint(0, 10, 3), np.random.randint(0, 10, 3)])\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eFRhtk13ojqA" + }, + "source": [ + "___\n", + "# **Converter array 1D num array 2D**\n", + "> Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wYhBgW9Zu6ZP" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(0, 10, 6))\n", + "\n", + "np.random.seed(19741120)\n", + "a_conjunto2 = np.array(np.random.randint(0, 10, 6))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "febs9AUHvs6n" + }, + "source": [ + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "C9OEd-iavvBm" + }, + "source": [ + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KJWjtaWKv0MJ" + }, + "source": [ + "np.column_stack((a_conjunto1, a_conjunto2)) # Atenção aos parênteses em (a_conjunto1, a_conjunto2)." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xr_WZXJ7pi2D" + }, + "source": [ + "___\n", + "# **Excluir um elemento específico do array usando indices**\n", + "> Considere os arrays a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tS0ZzOs8w0dw" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(0, 10, 6))\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7bOJiKDKxEsC" + }, + "source": [ + "Suponha que eu queira excluir os valores '8' de a_conjunto1. Os índices dos valores '8' são: [0, 1, 3]. Portanto, temos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SSjueEvjxTJO" + }, + "source": [ + "a_conjunto1 = np.delete(a_conjunto1, [0, 1, 3])\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZkGZ2Rgp--5" + }, + "source": [ + "___\n", + "# **Frequência dos valores únicos de um array**\n", + "> Considere o array a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z2BWKfH0xvQ8", + "outputId": "8e684b4b-1ceb-4075-e529-1edb95e30edb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(0, 10, 100))\n", + "a_conjunto1" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([8, 8, 2, 8, 9, 1, 8, 0, 4, 2, 0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 7, 9,\n", + " 5, 6, 8, 7, 0, 9, 3, 9, 3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 8, 6, 6, 1,\n", + " 0, 9, 2, 0, 7, 5, 5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 5, 0, 1, 2, 3, 8,\n", + " 7, 5, 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, 1, 0, 9, 1, 4, 2, 9,\n", + " 7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s_tdQBsax4rQ" + }, + "source": [ + "Suponha que eu queira saber quantas vezes o número/elemento '2' aparece em a_conjunto1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6yIlk7pWyAtf", + "outputId": "587f9dc5-f92b-4843-c173-4d0aff309bf5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_itens_unicos, i_count = np.unique(a_conjunto1, return_counts = True)\n", + "l_itens_unicos" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyvrIwS9yZIR" + }, + "source": [ + "O que significa o output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uO-MPMhXyV9H", + "outputId": "5f141140-a6d0-4a68-e037-918286166f54", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_count" + ], + "execution_count": 17, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 10, 10, 11, 8, 8, 8, 10, 10, 15])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zwoezXrPyofK" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgYycSG7yr5e", + "outputId": "17c18c3a-55cb-405a-9d9c-c1c9d1e122ae", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "np.asarray((l_itens_unicos, i_count))" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],\n", + " [10, 10, 10, 11, 8, 8, 8, 10, 10, 15]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SwIZiJAiy06T" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JpNRpN2Dql3N" + }, + "source": [ + "___\n", + "# **Combinações possíveis de outros arrays**\n", + "> Considere o exemplo a seguir:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BUr89dH4zLXD" + }, + "source": [ + "a_conjunto1 = [2, 4, 6]\n", + "a_conjunto2 = [0, 8]\n", + "a_conjunto4 = [1, 5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cEZH6l-Czx7y" + }, + "source": [ + "np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "btvmDkEcz0tH" + }, + "source": [ + "np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z0xhO7rGz059" + }, + "source": [ + "np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)).T" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eMv4lFnD0Enn" + }, + "source": [ + "# Resultado final\n", + "a_conjunto3 = np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)).T.reshape(-1,3)\n", + "a_conjunto3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rz80YANfAh2k" + }, + "source": [ + "___\n", + "# **Wrap Up**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_cyhMsAVXxGC" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNjovMw3uJ3R" + }, + "source": [ + "## Exercício 1 - Selecionar os números pares\n", + "> Dado o 1D array abaixo, selecionar somente os números pares." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "isDzQjwjBX3V" + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kq1zt-uO1HXv" + }, + "source": [ + "### **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFmK_n2M1Ks9" + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sScYG0hp05vb" + }, + "source": [ + "___\n", + "## Exercício 2 - Substituir pela mediana\n", + "> Dado o array 1D abaixo, substituir os números pares pela mediana de a_conjunto1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XLZ-DIWU1WFs" + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9c4QWJno1WVB" + }, + "source": [ + "### **Minha solução**\n", + "* Primeiramente, precisamos calcular a mediana.\n", + "* Depois, substituimos os valores pares de a_conjunto1 pela mediana encontrada anteriormente. Ok?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rx7NGAO01Wfb" + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0] = np.median(a_conjunto1)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2c_AphX82qp8" + }, + "source": [ + "Verificando..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kVta0Cr13Z9" + }, + "source": [ + "f'A média de a_conjunto1 é: {np.median(a_conjunto1)}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L9O-Hf5x26TY" + }, + "source": [ + "___\n", + "## Exercício 3 - Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 2D com 3 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_laUvtB4Wl-" + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(1, 10, size = 15))\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dKzEX8TK5b4Z" + }, + "source": [ + "### **Minha solução**\n", + "* O array 1D a_conjunto1 acima possui 15 elementos. Como queremos transformá-lo num array 2D com 3 colunas, então cada coluna terá 5 elementos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I-j5yVD04249" + }, + "source": [ + "a_conjunto1.reshape(5, 3) \n", + "# Poderia ser a_conjunto1.reshape(-1, 3), onde \"-1\" pede para o NumPy calcular o número de linhas. " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F1vfS8jE6L0_" + }, + "source": [ + "___\n", + "## Exercício 4 - Reshape\n", + "> Dado o array 1D abaixo, reshape para um array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xcN-bez56L1D" + }, + "source": [ + "# Define seed\n", + "np.random.seed(20111974)\n", + "a_conjunto1 = np.array(np.random.randint(1, 10, size = 16))\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7iICnOyG6fcj" + }, + "source": [ + "### **Minha solução**\n", + "* O array 1D a_conjunto1 acima possui 16 elementos. Queremos transformá-lo num array 3D com 2 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vdq5ybuD6fcn" + }, + "source": [ + "a_conjunto1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "haQfWPcCs_H0" + }, + "source": [ + "## Exercício 5\n", + "Para mais exercícios envolvendo arrays, visite a página [Python: Array Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/array/)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LQQL0JS2tnc0" + }, + "source": [ + "## Exercício 6\n", + "Para mais exercícios envolvendo matemática, viste a página [Python Math: - Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/math/index.php)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qNskKFy9t4D5" + }, + "source": [ + "## Exercício 7\n", + "Para mais exercícios envolvendo NumPy em geral, visite a página [NumPy Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/numpy/index.php)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qqc1AiHXuKZ5" + }, + "source": [ + "## Exercício 8\n" + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB07__Dictionaries_hs.ipynb b/Notebooks/NB07__Dictionaries_hs.ipynb new file mode 100644 index 000000000..28d54e5e2 --- /dev/null +++ b/Notebooks/NB07__Dictionaries_hs.ipynb @@ -0,0 +1,3137 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB07__Dictionaries.ipynb", + "provenance": [], + "collapsed_sections": [ + "n8BIbzQbNWUo", + "7eS94uQ4NhVR", + "SYOgJpGYVLUu", + "CaHFxk98W5if", + "ReWUyWiHXCnc", + "CqszHxaKHr2h", + "tXgF1Wl9gHKY", + "Fotx7XUquAo8", + "36kmLUYDvsUI", + "SWO2GdNovxAp", + "vpN54l4vxze5", + "u4HOf9SNytSq", + "6BQ9oZiD9hg5", + "tz5-QdrX9vct", + "p1muBgMX8NK4", + "FxTC2-U88ajk", + "z8EYn0pP25Rh" + ], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iBW6agsvqqAm" + }, + "source": [ + "

DICIONÁRIOS

\n", + "\n", + "* Coleção desordenada, mutável e indexada (estrutura do tipo {key: value}) de itens;\n", + "* Não permite itens duplicados;\n", + "* Usamos {key: value} para representar os itens do dicionário;\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LFcr_2Xnq2ho" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r8vR-lHJIhgM" + }, + "source": [ + "# **NOTAS E OBSERVAÇÕES**\n", + "* Levar os exemplos de lambda function daqui para o capítulo de Lambda Function.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DkxCxjsbE5fL" + }, + "source": [ + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cGUWTualFCOk" + }, + "source": [ + "![DataSctructures](https://github.com/MathMachado/Materials/blob/master/PythonDataStructures.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ublDMf3R_qMn" + }, + "source": [ + "A seguir, os principais métodos associados aos dicionários. Para isso, considere as listas l_frutas e l_precos_frutas que darão origem ao dicionário d_frutas a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FxuJ7Awd8f5a", + "outputId": "b92e247b-99a3-4687-87af-de5ccb28961f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 54 + } + }, + "source": [ + "# Definição da lista l_frutas:\n", + "l_frutas = ['Avocado', 'Apple', 'Apricot', 'Banana', 'Blackcurrant', 'Blackberry', 'Blueberry', 'Cherry', 'Coconut', 'Fig', 'Grape', 'Kiwi', 'Lemon', 'Mango', 'Nectarine', \n", + " 'Orange', 'Papaya', 'Passion Fruit', 'Peach', 'Pineapple', 'Plum', 'Raspberry', 'Strawberry', 'Watermelon']\n", + "\n", + "print(l_frutas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['Avocado', 'Apple', 'Apricot', 'Banana', 'Blackcurrant', 'Blackberry', 'Blueberry', 'Cherry', 'Coconut', 'Fig', 'Grape', 'Kiwi', 'Lemon', 'Mango', 'Nectarine', 'Orange', 'Papaya', 'Passion Fruit', 'Peach', 'Pineapple', 'Plum', 'Raspberry', 'Strawberry', 'Watermelon']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jJyxuMQc9Ewy", + "outputId": "4396f10a-5709-45cc-d923-347e4183fb7b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "# Definição da lista l_precos_frutas:\n", + "l_precos_frutas = [0.35, 0.40, 0.25, 0.30, 0.70, 0.55, 0.45, 0.50, 0.75, 0.60, 0.65, 0.20, 0.15, 0.80, 0.75, 0.25, 0.30,0.45,0.55,0.55,0.60,0.40,0.50,0.45]\n", + "l_precos_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.35,\n", + " 0.4,\n", + " 0.25,\n", + " 0.3,\n", + " 0.7,\n", + " 0.55,\n", + " 0.45,\n", + " 0.5,\n", + " 0.75,\n", + " 0.6,\n", + " 0.65,\n", + " 0.2,\n", + " 0.15,\n", + " 0.8,\n", + " 0.75,\n", + " 0.25,\n", + " 0.3,\n", + " 0.45,\n", + " 0.55,\n", + " 0.55,\n", + " 0.6,\n", + " 0.4,\n", + " 0.5,\n", + " 0.45]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hXP3kxW4-AI1" + }, + "source": [ + "Observe abaixo o uso das funções dict() e zip() para criarmos o dicionário d_frutas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qT_4sYxA9dyn", + "outputId": "15bd1dd0-81aa-4592-ca39-f8465f89eafe", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "# Definir o dicionário d_frutas: estrutura do tipo {chave1: valor1, chave2: valor2, ..., chaveN: valorN} --> JSON\n", + "d_frutas = dict(zip(l_frutas, l_precos_frutas))\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.4,\n", + " 'Apricot': 0.25,\n", + " 'Avocado': 0.35,\n", + " 'Banana': 0.3,\n", + " 'Blackberry': 0.55,\n", + " 'Blackcurrant': 0.7,\n", + " 'Blueberry': 0.45,\n", + " 'Cherry': 0.5,\n", + " 'Coconut': 0.75,\n", + " 'Fig': 0.6,\n", + " 'Grape': 0.65,\n", + " 'Kiwi': 0.2,\n", + " 'Lemon': 0.15,\n", + " 'Mango': 0.8,\n", + " 'Nectarine': 0.75,\n", + " 'Orange': 0.25,\n", + " 'Papaya': 0.3,\n", + " 'Passion Fruit': 0.45,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.6,\n", + " 'Raspberry': 0.4,\n", + " 'Strawberry': 0.5,\n", + " 'Watermelon': 0.45}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iHKUaGNT_IDt" + }, + "source": [ + "A seguir, resumo dos principais métodos relacionados à dicionários:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MQLZ1mwW_yiU" + }, + "source": [ + "| Método | Descrição | Exemplo | Resultado |\n", + "|-------------------------|----------------------------------------------------------------------------------------------------|------------------------------------------|--------------------------------------------------------------------------------|\n", + "| d_dicionario.clear() | Remove todos os itens de d_dicionario | d_frutas.clear() | {} |\n", + "| d_dicionario.copy() | Retorna uma cópia de d_dicionario | d_frutas2= d_frutas.copy() | d_frutas2 é uma cópia de d_frutas |\n", + "| d_dicionario.get(key) | Retorna o valor para key, se key estiver em d_dicionario | d_frutas.get('Passion Fruit') | 0.45 |\n", + "| | | d_frutas.get('XPTO') | O Python não apresenta nenhum retorno |\n", + "| d_dicionario.items() | Retorna um objeto com as tuplas (key, valor) de d_dicionario | d_frutas.items() | dict_items([('Avocado', 0.35), ..., ('Watermelon', 0.45)]) |\n", + "| d_dicionario.keys() | Retorna um objeto com as keys de d_dicionario | d_frutas.keys() | dict_keys(['Avocado', 'Apple', ..., 'Watermelon']) |\n", + "| d_dicionario.values() | Retorna um objeto com os valores de d_dicionario | d_frutas.values() | dict_values([0.35, 0.4, ..., 0.45]) |\n", + "| d_dicionario.popitem() | Retorna e remove um item de d_dicionario | d_frutas.popitem() | ('Watermelon', 0.45) |\n", + "| | | 'Watermelon' in d_frutas | False |\n", + "| d_dicionario.pop(key[, default]) | Retorna e remove o item de d_dicionario correspondente à key | d_frutas.pop('Orange') | 0.25 |\n", + "| | | 'Orange' in d_frutas | False |\n", + "| d_dicionario.update(d2) | Adiciona item(s) à d_dicionario se key não estiver em d_dicionario. Se key estiver em d_dicionario, atualizará key com o novo valor | d_frutas.update({'Cherimoya': 1.3}) | Adicionará o item {'Cherimoya': 1.3} à d_frutas, pois key= 'Cherimoya' não está em d_frutas. |\n", + "| | | d_frutas.update({'Orange': 0.55}) | Atualiza o valor de key= 'Orange' para 0.55. O valor anterior era 0.25 |\n", + "| d_dicionario.fromkeys(keys, value) | Retorna um dicionário com keys especificadas e valores | tFruits= ('Avocado', 'Apple', 'Apricot') | |\n", + "| | | d_frutas.fromkeys(tFruits, 0) | {'Apple': 0, 'Apricot': 0, 'Avocado': 0} |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uH6cHnctDu2l" + }, + "source": [ + "A seguir, vamos apresentar mais alguns exemplos de dicionários e seus métodos associados:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YeCPxCab4e4k" + }, + "source": [ + "___\n", + "# **EXEMPLO**\n", + "* Os dias da semana como dicionário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N_2J839X4lps", + "outputId": "72c3547d-59ee-4e42-bc85-5e050e3209dd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 136 + } + }, + "source": [ + "d_dia_semana = {'Seg': 'Segunda', 'Ter': 'Terça', 'Qua': 'Quarta', 'Qui': 'Quinta', 'Sex': 'Sexta', 'Sab': 'Sabado', 'Dom': 'Domingo'}\n", + "d_dia_semana" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Dom': 'Domingo',\n", + " 'Qua': 'Quarta',\n", + " 'Qui': 'Quinta',\n", + " 'Sab': 'Sabado',\n", + " 'Seg': 'Segunda',\n", + " 'Sex': 'Sexta',\n", + " 'Ter': 'Terça'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 4 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CnZLR-VX6FV4" + }, + "source": [ + "Observe que:\n", + "* os itens do dicionário d_dia_semana seguem a estrutura {key: value}.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eHuvY7BWQKhQ", + "outputId": "e340fc45-e036-4812-fc51-6f941063e588", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_dia_semana['Seg'] # A chave aqui é 'Seg'" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Segunda'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j65BxhzGG0NA" + }, + "source": [ + "___\n", + "# **DECLARAR OU INICIALIZAR UM DICIONÁRIO VAZIO**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LEGwQ0U-fKtL" + }, + "source": [ + "Por exemplo, o comando abaixo declara um dicionário vazio chamado d_paises:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2iPWXPBLfOlr", + "outputId": "41fc8f1a-70cd-4e56-aeb0-0c0e4aac5571", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises = {} # Também podemos usar a função dict() para criar o dicionário vazio da seguinte forma: d_paises= dict()\n", + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vCxZv-jmG5y0" + }, + "source": [ + "___\n", + "# **OBTER O TIPO DO OBJETO**\n", + "> type(d_dicionario)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "voPYpGIGff3o", + "outputId": "b05165d8-375a-44e9-cacf-876eb0da4071", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(d_paises)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X3MvCkFiG-UO" + }, + "source": [ + "___\n", + "# **ADICIONAR ITENS AO DICIONÁRIO**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fzP8iG5xfi0H" + }, + "source": [ + "Adicionar o valor 'Italy' à key = 1. Em outras palavras, estamos a adicionar o item {1: 'Italy'}" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EXZ7eEZofnza", + "outputId": "0976b0e9-c5d3-4341-d444-d6e556c225bb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises[1] = 'Italy'\n", + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rH51ORGHHREE" + }, + "source": [ + "Adicionar o valor 'Denmark' à key= 2. Em outras palavras, estamos a adicionar o item {2: 'Denmark'}" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GAXSzSiufv1u", + "outputId": "19a48880-61f6-4c24-ba7c-e5b81e1cad52", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises[2] = 'Denmark'\n", + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xqdc_IYoHVVQ" + }, + "source": [ + "Adicionar o valor 'Brazil' à key= 3. Em outras palavras, estamos a adicionar o item {3: 'Brazil'}" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FN7km8C9gAjM", + "outputId": "99f3df3e-aa72-4b86-aff7-9383f4f74dcb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises[3]= 'Brazil'\n", + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark', 3: 'Brazil'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iwU8pJKRHapD" + }, + "source": [ + "___\n", + "# **ATUALIZAR VALORES DO DICIONÁRIO**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CxXUV7TugLXn" + }, + "source": [ + "O que acontece quando eu atribuo à key 3 outro valor, por exemplo, 'France'. Vamos conferir abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr6DtJnDgU5I", + "outputId": "b2d7aa85-4860-4c0d-b1dd-7f3ae61f9e17", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Adicionar o valor 'France' à key= 3\n", + "d_paises[3]= 'France'\n", + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark', 3: 'France'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xB9G1l3_ggo-" + }, + "source": [ + "Como a key= 3 existe no dicionário d_paises, então o Python substitui o valor anterior 'Brazil' pelo novo valor, 'France'. \n", + "\n", + "* Lembre-se, os dicionários são mutáveis!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T8JBxySZHiOJ" + }, + "source": [ + "___\n", + "# **OBTER KEYS DO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FQtAHjJdb0xK", + "outputId": "aad4e409-d6b5-4c3f-a06c-fff1cb7a6688", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark', 3: 'France'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ALwbHwi4iwky", + "outputId": "82d7b6c6-53a8-4f1d-abdb-d4906a269097", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises.keys()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_keys([1, 2, 3])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FIvi0Li1Hng5" + }, + "source": [ + "___\n", + "# **OBTER VALORES DO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cp0PPtl3jEKo", + "outputId": "de0432c6-240d-4783-b6ff-7692b3d92188", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises.values()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_values(['Italy', 'Denmark', 'France'])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JUblZBMjHrwl" + }, + "source": [ + "___\n", + "# **OBTER ITENS (key, value) DO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LraTwXjdjG3m", + "outputId": "fa2310f2-2a88-4d4c-8799-bacd6b40fcc6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises.items()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_items([(1, 'Italy'), (2, 'Denmark'), (3, 'France')])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJEMg2LKHyGa" + }, + "source": [ + "___\n", + "# **OBTER VALOR PARA UMA KEY ESPECÍFICA**\n", + "* d_dicionario.get(key)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dzgBhsphjSQm" + }, + "source": [ + "Qual o valor para key= 1?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FUfTjqktjW60", + "outputId": "0ce4b014-66c5-4bbe-af35-1b627f877a6f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_paises.get(1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'Italy'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tyJ0KsloIBoD" + }, + "source": [ + "___\n", + "# **COPIAR DICIONÁRIO**\n", + "* d_dicionario.copy()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XL17EmvMkkky", + "outputId": "198fd037-5b42-41c5-a959-fcaaa419d35d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises2 = d_paises.copy()\n", + "d_paises2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark', 3: 'France'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8V25l2ZoIG4B" + }, + "source": [ + "___\n", + "# **REMOVER TODOS OS ITENS DO DICIONÁRIO**\n", + "* d_dicionario.clear()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-8Gs1gYjqLN" + }, + "source": [ + "d_paises.clear()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ro_42gzDjsdV", + "outputId": "b31b6516-a7af-45ff-85e2-a7e6fa8e40ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pCzKkKoujv7G" + }, + "source": [ + "Como esperado, removemos todos os itens do dicionário d_paises. Entretanto, o dicionário d_paises continua a existir!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MKtPwGVsIaLQ" + }, + "source": [ + "___\n", + "# **DELETAR O DICIONÁRIO**\n", + "* del d_dicionario" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8wvM-o7Lj7A0" + }, + "source": [ + "del d_paises" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wK83ZURYkD_T", + "outputId": "03254461-9939-4ef9-de30-c4b59c920674", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdCountries\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'dCountries' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aSe3veUB1lo_" + }, + "source": [ + "Como esperado, pois agora o dicionário já não existe mais. Ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "STtkGUvEg7d1" + }, + "source": [ + "___\n", + "# **ITERAR PELO DICIONÁRIO**\n", + "* Considere o dicionário d_frutas a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IG8hKSvcfalZ" + }, + "source": [ + "# Definindo os valores iniciais do dicionário d_frutas:\n", + "d_frutas = {'Avocado': 0.35, \n", + " 'Apple': 0.40, \n", + " 'Apricot': 0.25, \n", + " 'Banana': 0.30, \n", + " 'Blackcurrant': 0.70, \n", + " 'Blackberry': 0.55, \n", + " 'Blueberry': 0.45, \n", + " 'Cherry': 0.50, \n", + " 'Coconut': 0.75, \n", + " 'Fig': 0.60, \n", + " 'Grape': 0.65, \n", + " 'Kiwi': 0.20, \n", + " 'Lemon': 0.15, \n", + " 'Mango': 0.80, \n", + " 'Nectarine': 0.75, \n", + " 'Orange': 0.25, \n", + " 'Papaya': 0.30,\n", + " 'Passion Fruit': 0.45,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.60,\n", + " 'Raspberry': 0.40,\n", + " 'Strawberry': 0.50,\n", + " 'Watermelon': 0.45}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ppRkK_jJJG6W" + }, + "source": [ + "Mostrando os itens do dicionário d_frutas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bI7Ctf0ohyz8", + "outputId": "3fedf44b-015e-474f-b5d3-1f2aa09d1957", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.4,\n", + " 'Apricot': 0.25,\n", + " 'Avocado': 0.35,\n", + " 'Banana': 0.3,\n", + " 'Blackberry': 0.55,\n", + " 'Blackcurrant': 0.7,\n", + " 'Blueberry': 0.45,\n", + " 'Cherry': 0.5,\n", + " 'Coconut': 0.75,\n", + " 'Fig': 0.6,\n", + " 'Grape': 0.65,\n", + " 'Kiwi': 0.2,\n", + " 'Lemon': 0.15,\n", + " 'Mango': 0.8,\n", + " 'Nectarine': 0.75,\n", + " 'Orange': 0.25,\n", + " 'Papaya': 0.3,\n", + " 'Passion Fruit': 0.45,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.6,\n", + " 'Raspberry': 0.4,\n", + " 'Strawberry': 0.5,\n", + " 'Watermelon': 0.45}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wXFfyiyPtD35" + }, + "source": [ + "Qual o valor para a fruta 'Apple'? Para responder à esta pergunta, basta lembrar que 'Apple' é uma key do dicionário d_frutas. Certo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JpreyE_LtCcU", + "outputId": "7ff1b31c-9a76-4de8-d38f-a36e77bd30f6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_frutas['Apple']" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.4" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RMWau2TOclHr", + "outputId": "741f0735-17a1-4f4f-ec4c-4df8bc82c987", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "d_frutas['blablabla'] # Isso significa que 'blablabla' não faz parte do dicionário!" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md_frutas\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'blablabla'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# Isso significa que 'blablabla' não faz parte do dicionário!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m: 'blablabla'" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JBMf8SbAJmiq" + }, + "source": [ + "## Iterar pelas keys do dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i-6-pNQCcyXY", + "outputId": "fc039905-cff5-4b3a-cc54-139f3a2204c6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for chave in d_frutas.keys():\n", + " print(chave)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Avocado\n", + "Apple\n", + "Apricot\n", + "Banana\n", + "Blackcurrant\n", + "Blackberry\n", + "Blueberry\n", + "Cherry\n", + "Coconut\n", + "Fig\n", + "Grape\n", + "Kiwi\n", + "Lemon\n", + "Mango\n", + "Nectarine\n", + "Orange\n", + "Papaya\n", + "Passion Fruit\n", + "Peach\n", + "Pineapple\n", + "Plum\n", + "Raspberry\n", + "Strawberry\n", + "Watermelon\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9u4xJ0FfdCxm" + }, + "source": [ + "## Iterar pelos valores do dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vrFPwQPDdFP3", + "outputId": "0db51495-3826-4c2e-9f06-4cbbc1ec7376", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for i_valor in d_frutas.values():\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0.35\n", + "0.4\n", + "0.25\n", + "0.3\n", + "0.7\n", + "0.55\n", + "0.45\n", + "0.5\n", + "0.75\n", + "0.6\n", + "0.65\n", + "0.2\n", + "0.15\n", + "0.8\n", + "0.75\n", + "0.25\n", + "0.3\n", + "0.45\n", + "0.55\n", + "0.55\n", + "0.6\n", + "0.4\n", + "0.5\n", + "0.45\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yDkOLvRFJxco" + }, + "source": [ + "## Iterar pelos itens (chave, valor) do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "H8BCC6qodU6o", + "outputId": "7cf6c927-b433-47d4-af28-b93c51b960cf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 54 + } + }, + "source": [ + "d_frutas.items()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_items([('Avocado', 0.35), ('Apple', 0.4), ('Apricot', 0.25), ('Banana', 0.3), ('Blackcurrant', 0.7), ('Blackberry', 0.55), ('Blueberry', 0.45), ('Cherry', 0.5), ('Coconut', 0.75), ('Fig', 0.6), ('Grape', 0.65), ('Kiwi', 0.2), ('Lemon', 0.15), ('Mango', 0.8), ('Nectarine', 0.75), ('Orange', 0.25), ('Papaya', 0.3), ('Passion Fruit', 0.45), ('Peach', 0.55), ('Pineapple', 0.55), ('Plum', 0.6), ('Raspberry', 0.4), ('Strawberry', 0.5), ('Watermelon', 0.45)])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DpFB1g-3kDSt", + "outputId": "3a9f1b1a-d96b-47b8-b36d-9e306d4c4271", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for item in d_frutas.items():\n", + " print(item) " + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "('Avocado', 0.35)\n", + "('Apple', 0.4)\n", + "('Apricot', 0.25)\n", + "('Banana', 0.3)\n", + "('Blackcurrant', 0.7)\n", + "('Blackberry', 0.55)\n", + "('Blueberry', 0.45)\n", + "('Cherry', 0.5)\n", + "('Coconut', 0.75)\n", + "('Fig', 0.6)\n", + "('Grape', 0.65)\n", + "('Kiwi', 0.2)\n", + "('Lemon', 0.15)\n", + "('Mango', 0.8)\n", + "('Nectarine', 0.75)\n", + "('Orange', 0.25)\n", + "('Papaya', 0.3)\n", + "('Passion Fruit', 0.45)\n", + "('Peach', 0.55)\n", + "('Pineapple', 0.55)\n", + "('Plum', 0.6)\n", + "('Raspberry', 0.4)\n", + "('Strawberry', 0.5)\n", + "('Watermelon', 0.45)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-LmEUroVKDUA" + }, + "source": [ + "## Iterar pela key e valor do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oRhZ_Zq9oQIg", + "outputId": "02b624d2-eebd-4666-f2b3-972f1defe060", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for key, value in d_frutas.items():\n", + " print(\"%s --> %s\" %(key, value))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Avocado --> 0.35\n", + "Apple --> 0.4\n", + "Apricot --> 0.25\n", + "Banana --> 0.3\n", + "Blackcurrant --> 0.7\n", + "Blackberry --> 0.55\n", + "Blueberry --> 0.45\n", + "Cherry --> 0.5\n", + "Coconut --> 0.75\n", + "Fig --> 0.6\n", + "Grape --> 0.65\n", + "Kiwi --> 0.2\n", + "Lemon --> 0.15\n", + "Mango --> 0.8\n", + "Nectarine --> 0.75\n", + "Orange --> 0.25\n", + "Papaya --> 0.3\n", + "Passion Fruit --> 0.45\n", + "Peach --> 0.55\n", + "Pineapple --> 0.55\n", + "Plum --> 0.6\n", + "Raspberry --> 0.4\n", + "Strawberry --> 0.5\n", + "Watermelon --> 0.45\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fotx7XUquAo8" + }, + "source": [ + "___\n", + "# **VERIFICAR SE UMA KEY ESPECÍFICA PERTENCE AO DICIONÁRIO**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ju__WsSoKXtk" + }, + "source": [ + "A fruta 'Apple' (que em nosso caso, é uma key) existe no dicionário?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-gkEKNZPTeMp", + "outputId": "30f46535-0f53-450b-b598-a8eab0f04121", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "'Apple' in d_frutas.keys()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fMzBeFMIusv7" + }, + "source": [ + "A fruta 'Coconut' pertence ao dicionário d_frutas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SKtEwmBCuxyi", + "outputId": "cf52b903-90e0-432f-8b7e-bc878d5c5f5f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "'Coconut' in d_frutas.keys()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rrH8ArqsK6Bd" + }, + "source": [ + "___\n", + "# **VERIFICAR SE VALOR PERTENCE AO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DbWpbuLTK9sn", + "outputId": "a97cf9c4-369a-453f-955d-0078dd83dbf0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "0.4 in d_frutas.values()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "36kmLUYDvsUI" + }, + "source": [ + "## Adicionar novos itens ao dicionário\n", + "* Considere o dicionário d_frutas2 abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Rwq4-UG4--u", + "outputId": "e5da55a7-9d26-4a48-e148-8d5b187d8db0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_frutas2 = {'Grapefruit': 1.0}\n", + "d_frutas2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Grapefruit': 1.0}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vljceM6_5H9o" + }, + "source": [ + "O comando abaixo adiciona o dicionário d_frutas2 ao dicionário d_frutas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BD_mYMM5O5o", + "outputId": "b1d770f5-19fa-4f10-9d4e-d98e14811e88", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "d_frutas.update(d_frutas2)\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.4,\n", + " 'Apricot': 0.25,\n", + " 'Avocado': 0.35,\n", + " 'Banana': 0.3,\n", + " 'Blackberry': 0.55,\n", + " 'Blackcurrant': 0.7,\n", + " 'Blueberry': 0.45,\n", + " 'Cherry': 0.5,\n", + " 'Coconut': 0.75,\n", + " 'Fig': 0.6,\n", + " 'Grape': 0.65,\n", + " 'Grapefruit': 1.0,\n", + " 'Kiwi': 0.2,\n", + " 'Lemon': 0.15,\n", + " 'Mango': 0.8,\n", + " 'Nectarine': 0.75,\n", + " 'Orange': 0.25,\n", + " 'Papaya': 0.3,\n", + " 'Passion Fruit': 0.45,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.6,\n", + " 'Raspberry': 0.4,\n", + " 'Strawberry': 0.5,\n", + " 'Watermelon': 0.45}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ffh-94lo55n4" + }, + "source": [ + "Agora, considere o dicionário d_frutas3 abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JMAq_jbP5---" + }, + "source": [ + "d_frutas3 = {'Apple': 0.70}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Jd6B2cy-6KmY" + }, + "source": [ + "Qual o resultado do comando abaixo?\n", + "\n", + "* Atenção: A fruta 'Apple' (é uma key do dicionário d_frutas) tem valor 0.40. E no dicionário d_frutas3 a fruta 'Apple' tem valor 0.70." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4GKdTw76PXI", + "outputId": "c9f4ccec-90b3-4e91-bf19-976493cc3933", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "d_frutas.update(d_frutas3)\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.7,\n", + " 'Apricot': 0.25,\n", + " 'Avocado': 0.35,\n", + " 'Banana': 0.3,\n", + " 'Blackberry': 0.55,\n", + " 'Blackcurrant': 0.7,\n", + " 'Blueberry': 0.45,\n", + " 'Cherry': 0.5,\n", + " 'Coconut': 0.75,\n", + " 'Fig': 0.6,\n", + " 'Grape': 0.65,\n", + " 'Grapefruit': 1.0,\n", + " 'Kiwi': 0.2,\n", + " 'Lemon': 0.15,\n", + " 'Mango': 0.8,\n", + " 'Nectarine': 0.75,\n", + " 'Orange': 0.25,\n", + " 'Papaya': 0.3,\n", + " 'Passion Fruit': 0.45,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.6,\n", + " 'Raspberry': 0.4,\n", + " 'Strawberry': 0.5,\n", + " 'Watermelon': 0.45}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMmDfrln6o0c" + }, + "source": [ + "Como esperado, como key= 'Apple' existe no dicionário d_frutas, então o Python atualizou o valor de key= 'Apple' para 0.70." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SWO2GdNovxAp" + }, + "source": [ + "## Modificar keys e valores" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DX9UTy4TwlAw" + }, + "source": [ + "Suponha que queremos aplicar um desconto de 10% para cada fruta do nosso dicionário.\n", + "\n", + "* Como fazemos isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RV-YOkrffa3h", + "outputId": "6a7a1330-7ecd-4924-bf73-f3e0bc16baae", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_frutas.keys()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_keys(['Avocado', 'Apple', 'Apricot', 'Banana', 'Blackcurrant', 'Blackberry', 'Blueberry', 'Cherry', 'Coconut', 'Fig', 'Grape', 'Kiwi', 'Lemon', 'Mango', 'Nectarine', 'Orange', 'Papaya', 'Passion Fruit', 'Peach', 'Pineapple', 'Plum', 'Raspberry', 'Strawberry', 'Watermelon', 'Grapefruit'])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tV8k5w2Bf1Oq", + "outputId": "4ee0496f-ab86-4c6d-fc9f-b04863017bb0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_frutas.items()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_items([('Avocado', 0.35), ('Apple', 0.4), ('Apricot', 0.25), ('Banana', 0.3), ('Blackcurrant', 0.7), ('Blackberry', 0.55), ('Blueberry', 0.45), ('Cherry', 0.5), ('Coconut', 0.75), ('Fig', 0.6), ('Grape', 0.65), ('Kiwi', 0.2), ('Lemon', 0.15), ('Mango', 0.8), ('Nectarine', 0.75), ('Orange', 0.25), ('Papaya', 0.3), ('Passion Fruit', 0.45), ('Peach', 0.55), ('Pineapple', 0.55), ('Plum', 0.6), ('Raspberry', 0.4), ('Strawberry', 0.5), ('Watermelon', 0.45), ('Grapefruit', 1.0)])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZziGmKGmwqwn", + "outputId": "178faaca-bf7d-4542-a5ef-662b96a70362", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "for key, value in d_frutas.items():\n", + " d_frutas[key] = round((value * 0.9), 2) # Isso representa um desconto de 10% no valor das frutas\n", + "\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.63,\n", + " 'Apricot': 0.23,\n", + " 'Avocado': 0.32,\n", + " 'Banana': 0.27,\n", + " 'Blackberry': 0.5,\n", + " 'Blackcurrant': 0.63,\n", + " 'Blueberry': 0.41,\n", + " 'Cherry': 0.45,\n", + " 'Coconut': 0.68,\n", + " 'Fig': 0.54,\n", + " 'Grape': 0.59,\n", + " 'Grapefruit': 0.9,\n", + " 'Kiwi': 0.18,\n", + " 'Lemon': 0.14,\n", + " 'Mango': 0.72,\n", + " 'Nectarine': 0.68,\n", + " 'Orange': 0.23,\n", + " 'Papaya': 0.27,\n", + " 'Passion Fruit': 0.41,\n", + " 'Peach': 0.5,\n", + " 'Pineapple': 0.5,\n", + " 'Plum': 0.54,\n", + " 'Raspberry': 0.36,\n", + " 'Strawberry': 0.45,\n", + " 'Watermelon': 0.41}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s1B-yN8lM-C1" + }, + "source": [ + "Mostra d_frutas com os valores atualizados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZLa85knxBtY", + "outputId": "2c7c12f8-8885-4f34-a0d1-1323e98a9437", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 442 + } + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.63,\n", + " 'Apricot': 0.23,\n", + " 'Avocado': 0.32,\n", + " 'Banana': 0.27,\n", + " 'Blackberry': 0.5,\n", + " 'Blackcurrant': 0.63,\n", + " 'Blueberry': 0.41,\n", + " 'Cherry': 0.45,\n", + " 'Coconut': 0.68,\n", + " 'Fig': 0.54,\n", + " 'Grape': 0.59,\n", + " 'Grapefruit': 0.9,\n", + " 'Kiwi': 0.18,\n", + " 'Lemon': 0.14,\n", + " 'Mango': 0.72,\n", + " 'Nectarine': 0.68,\n", + " 'Orange': 0.23,\n", + " 'Papaya': 0.27,\n", + " 'Passion Fruit': 0.41,\n", + " 'Peach': 0.5,\n", + " 'Pineapple': 0.5,\n", + " 'Plum': 0.54,\n", + " 'Raspberry': 0.36,\n", + " 'Strawberry': 0.45,\n", + " 'Watermelon': 0.41}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 84 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vpN54l4vxze5" + }, + "source": [ + "## Deletar keys do dicionário\n", + "* Deletar uma key significa deletar todo o item {key: value}, ok?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eDlthLStNIwR" + }, + "source": [ + "Suponha que queremos deletar a fruta 'Avocado' do dicionário d_frutas.\n", + "\n", + "* Como fazer isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fnpzHZU_x5Y1" + }, + "source": [ + "for key in list(d_frutas.keys()): # Dica: use a função list para melhorar a performance computacional\n", + " if key == 'Avocado':\n", + " del d_frutas[key] # Deleta key = 'Avocado'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VyPUrobONqvI" + }, + "source": [ + "Mostra o dicionário d_frutas atualizado:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IwnsHejhyT4l", + "outputId": "5062a125-6a3d-48e3-f272-22d89ebbd09e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.63,\n", + " 'Apricot': 0.23,\n", + " 'Banana': 0.27,\n", + " 'Blackberry': 0.5,\n", + " 'Blackcurrant': 0.63,\n", + " 'Blueberry': 0.41,\n", + " 'Cherry': 0.45,\n", + " 'Coconut': 0.68,\n", + " 'Fig': 0.54,\n", + " 'Grape': 0.59,\n", + " 'Grapefruit': 0.9,\n", + " 'Kiwi': 0.18,\n", + " 'Lemon': 0.14,\n", + " 'Mango': 0.72,\n", + " 'Nectarine': 0.68,\n", + " 'Orange': 0.23,\n", + " 'Papaya': 0.27,\n", + " 'Passion Fruit': 0.41,\n", + " 'Peach': 0.5,\n", + " 'Pineapple': 0.5,\n", + " 'Plum': 0.54,\n", + " 'Raspberry': 0.36,\n", + " 'Strawberry': 0.45,\n", + " 'Watermelon': 0.41}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4HOf9SNytSq" + }, + "source": [ + "## Filtrar/Selecionar itens baseado em condições\n", + "Em algumas situações você vai querer filtrar os itens do dicionário que satisfaçam alguma(s) condições.\n", + "\n", + "* Considere o exemplo a seguir: queremos selecionar/filtrar somente as frutas com preços maiores que 0.5." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EwqxWiVlyvgH" + }, + "source": [ + "d_frutas_filtro = {}\n", + "\n", + "for key, value in d_frutas.items():\n", + " if value > 0.5:\n", + " d_frutas_filtro.update({key: value})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eb0jmAKWOtYt" + }, + "source": [ + "Mostrar o conteúdo do dicionário d_frutas_filtro:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SsStWM5k1s-Q", + "outputId": "3d0e9a69-0949-49fd-eb1a-b04859607534", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "d_frutas_filtro" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.63,\n", + " 'Blackcurrant': 0.63,\n", + " 'Coconut': 0.68,\n", + " 'Fig': 0.54,\n", + " 'Grape': 0.59,\n", + " 'Grapefruit': 0.9,\n", + " 'Mango': 0.72,\n", + " 'Nectarine': 0.68,\n", + " 'Plum': 0.54}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u1ve6xIGOjrE" + }, + "source": [ + " Como se pode ver, temos várias frutas com preços acima de 0.5 (satisfaz a condição)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KJqpPrfkCk9L" + }, + "source": [ + "## Cálculos com os itens do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "exD8HXodCqg6" + }, + "source": [ + "from collections import Counter" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llCLTysdCuwB" + }, + "source": [ + "Somando os valores de todas as frutas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uG0VP1MNCroX", + "outputId": "034db243-6cd7-4782-ea00-69706bd3cabc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "sum(d_frutas.values())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "11.219999999999997" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a5MBNCF-C5-4" + }, + "source": [ + "Quantos itens existem no dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkvygR0PC9bT", + "outputId": "9c2e7a2d-e487-489a-9344-1632414c1f0b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "len(list(d_frutas))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "24" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xBNFaklq8OC9" + }, + "source": [ + "## Sortear itens do dicionário - sorted(d_dicionario.items(), reverse= True/False)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WULJMjHA-mal" + }, + "source": [ + "Ordem alfabética (por key):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SH0WIKZ8-Ylr", + "outputId": "cd096812-50e3-4c0d-875c-fd387e0d6be1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "d_frutas_ordenadas = sorted(d_frutas.items(), reverse = False)\n", + "d_frutas_ordenadas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('Apple', 0.63),\n", + " ('Apricot', 0.23),\n", + " ('Banana', 0.27),\n", + " ('Blackberry', 0.5),\n", + " ('Blackcurrant', 0.63),\n", + " ('Blueberry', 0.41),\n", + " ('Cherry', 0.45),\n", + " ('Coconut', 0.68),\n", + " ('Fig', 0.54),\n", + " ('Grape', 0.59),\n", + " ('Grapefruit', 0.9),\n", + " ('Kiwi', 0.18),\n", + " ('Lemon', 0.14),\n", + " ('Mango', 0.72),\n", + " ('Nectarine', 0.68),\n", + " ('Orange', 0.23),\n", + " ('Papaya', 0.27),\n", + " ('Passion Fruit', 0.41),\n", + " ('Peach', 0.5),\n", + " ('Pineapple', 0.5),\n", + " ('Plum', 0.54),\n", + " ('Raspberry', 0.36),\n", + " ('Strawberry', 0.45),\n", + " ('Watermelon', 0.41)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T4Li1Q2d-pnZ" + }, + "source": [ + "Ordem reversa (por key):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PoBOmfpM_A_a", + "outputId": "079b0969-f79d-47ba-a557-afe19a55c528", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "d_frutas_ordenadas_reverse = sorted(d_frutas.items(), reverse = True)\n", + "d_frutas_ordenadas_reverse" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('Watermelon', 0.41),\n", + " ('Strawberry', 0.45),\n", + " ('Raspberry', 0.36),\n", + " ('Plum', 0.54),\n", + " ('Pineapple', 0.5),\n", + " ('Peach', 0.5),\n", + " ('Passion Fruit', 0.41),\n", + " ('Papaya', 0.27),\n", + " ('Orange', 0.23),\n", + " ('Nectarine', 0.68),\n", + " ('Mango', 0.72),\n", + " ('Lemon', 0.14),\n", + " ('Kiwi', 0.18),\n", + " ('Grapefruit', 0.9),\n", + " ('Grape', 0.59),\n", + " ('Fig', 0.54),\n", + " ('Coconut', 0.68),\n", + " ('Cherry', 0.45),\n", + " ('Blueberry', 0.41),\n", + " ('Blackcurrant', 0.63),\n", + " ('Blackberry', 0.5),\n", + " ('Banana', 0.27),\n", + " ('Apricot', 0.23),\n", + " ('Apple', 0.63)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FxTC2-U88ajk" + }, + "source": [ + "## Função filter()\n", + "* A função filter() aplica um filtro no dicionário, retornando apenas os itens que satisfaz as condições do filtro." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iJq1clvOHVG2", + "outputId": "4fcf65ea-fff4-4320-d093-79822f54ae12", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.63,\n", + " 'Apricot': 0.23,\n", + " 'Banana': 0.27,\n", + " 'Blackberry': 0.5,\n", + " 'Blackcurrant': 0.63,\n", + " 'Blueberry': 0.41,\n", + " 'Cherry': 0.45,\n", + " 'Coconut': 0.68,\n", + " 'Fig': 0.54,\n", + " 'Grape': 0.59,\n", + " 'Grapefruit': 0.9,\n", + " 'Kiwi': 0.18,\n", + " 'Lemon': 0.14,\n", + " 'Mango': 0.72,\n", + " 'Nectarine': 0.68,\n", + " 'Orange': 0.23,\n", + " 'Papaya': 0.27,\n", + " 'Passion Fruit': 0.41,\n", + " 'Peach': 0.5,\n", + " 'Pineapple': 0.5,\n", + " 'Plum': 0.54,\n", + " 'Raspberry': 0.36,\n", + " 'Strawberry': 0.45,\n", + " 'Watermelon': 0.41}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtTKvNeJNycl" + }, + "source": [ + "### Filtrando por key:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uIDW5FhwAiSs", + "outputId": "b266365b-417a-4f9f-9fda-c033446472e8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_frutas2 = {chave: valor for chave, valor in filter(lambda t: t[0] == 'Apple', d_frutas.items())}\n", + "d_frutas2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.4}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 4 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JtbUrtyaTl-H" + }, + "source": [ + "#### Versões mais Pythonic!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "l4etRMMEToau", + "outputId": "bbc5e488-9d65-48ec-b9df-152b89e68c72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 178 + } + }, + "source": [ + "# Opção 1:\n", + "d_frutas2 = dict(filter(lambda t: t[0] == 'Apple', d_frutas.items()))\n", + "d_frutas2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Opção 1:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0md_frutas2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mchavechave\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mvalor\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mchave\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalor\u001b[0m \u001b[0;32min\u001b[0m \u001b[0md_frutas\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mchave\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'Apple'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'd_frutas' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0y0cfS61Vbgw" + }, + "source": [ + "# Opção 2:\n", + "d_frutas2 = {chave: valor for chave, valor in d_frutas.items() if chave == 'Apple'}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3XmPlpNqBVMl" + }, + "source": [ + "### A expressão acima é equivalente à expressão abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_5j19I7tiHgp", + "outputId": "87e3bd82-8ec6-4f59-c8e2-74aaa80858d3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_filtro = {}\n", + "\n", + "for chave, valor in d_frutas.items():\n", + " if chave == 'Apple':\n", + " d_filtro.update({chave: valor})\n", + "\n", + "d_filtro" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.4}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nUMGIzxeNt_U" + }, + "source": [ + "### Filtrando por valor:\n", + "\n", + "Equivalente a:\n", + "\n", + "```\n", + "d_frutas3 = {}\n", + "\n", + "for key, value in d_frutas.items():\n", + " if value > 0.5:\n", + " d_frutas3.update({key: value})\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tvHcQatANltL", + "outputId": "8feaf5b1-1db8-4391-8950-248ba8ab46c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "d_frutas3 = {k: v for k, v in filter(lambda t: t[1] > 0.5, d_frutas.items())}\n", + "d_frutas3" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Blackberry': 0.55,\n", + " 'Blackcurrant': 0.7,\n", + " 'Coconut': 0.75,\n", + " 'Fig': 0.6,\n", + " 'Grape': 0.65,\n", + " 'Mango': 0.8,\n", + " 'Nectarine': 0.75,\n", + " 'Peach': 0.55,\n", + " 'Pineapple': 0.55,\n", + " 'Plum': 0.6}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mqOFuiG1WEMG" + }, + "source": [ + "#### Versões mais Pythonic!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n0QV7jEfWEMH", + "outputId": "bbc5e488-9d65-48ec-b9df-152b89e68c72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 178 + } + }, + "source": [ + "# Opção 1:\n", + "d_frutas3 = dict(filter(lambda t: t[1] > 0.5, d_frutas.items()))\n", + "d_frutas3" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Opção 1:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0md_frutas2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mchavechave\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mvalor\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mchave\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalor\u001b[0m \u001b[0;32min\u001b[0m \u001b[0md_frutas\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mchave\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'Apple'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'd_frutas' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5BhyxoDvWEMK" + }, + "source": [ + "# Opção 2:\n", + "d_frutas3 = {chave: valor for chave, valor in d_frutas.items() if valor > 0.5}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qA_XhCdmA6Gn" + }, + "source": [ + "___\n", + "# **EXERCÍCIOS**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSpyl_URgNyE" + }, + "source": [ + "## Exercício 1\n", + "* É possível sortear os itens de um dicionário? Explique sua resposta." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CXqc9kHch6Mm" + }, + "source": [ + "## Exercício 2\n", + "* É possível termos um dicionário do tipo abaixo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BBWO9Zth_mc", + "outputId": "14be585a-7315-4901-863a-9ba18090b5e8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "d_colaboradores = {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}\n", + "d_colaboradores" + ], + "execution_count": 1, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Gerentes': ['A', 'B', 'C'],\n", + " 'Gerentes_Projeto': ['A', 'E'],\n", + " 'Programadores': ['B', 'D', 'E', 'F', 'G']}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 1 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TNiJSG_uiePb" + }, + "source": [ + "Como acessar o Gerente 'A'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rGvVgyz7jxwn", + "outputId": "c4e02509-6910-46c5-d906-b7d6f542dfb3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_colaboradores['Gerentes']" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['A', 'B', 'C']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c-VwXvdij3QQ", + "outputId": "f4344858-8ebf-4e0c-b336-e7a6ed4a43a2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_colaboradores['Programadores']???" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['B', 'D', 'E', 'F', 'G']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VBLRSQSw6mGB", + "outputId": "ffdc226c-92c9-4096-ea0f-e13f25dc8a1c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_colaboradores['Gerentes'][0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WV0WaGB4kCiP", + "outputId": "171e4ea0-c66f-49c2-f4ea-deb44b315d43", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "s_gerentes = d_colaboradores['Gerentes']\n", + "s_gerentes[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 62 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yRrG7wUgkf6K", + "outputId": "122c0ff9-47af-4a50-874e-42779aa3c068", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "s_gerente_A = d_colaboradores.values()\n", + "s_gerente_A" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_values([['A', 'B', 'C'], ['B', 'D', 'E', 'F', 'G'], ['A', 'E']])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 55 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ntVcr_3XwaQ-" + }, + "source": [ + "## Exercício 3\n", + "Consulte a página [Python Data Types: Dictionary - Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/dictionary/) para mais exercícios relacionados à dicionários." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7u5-o8dzlryA" + }, + "source": [ + "## **Exercício 4**\n", + "\n", + "Retornar do dicionário d_colaboradores somente o Programador cujo nome seja 'E'. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lRKtdcA07gax", + "outputId": "f5352b08-2e67-4a1d-d879-12501f486d43", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_colaboradores['Programadores'][2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'E'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7KRNcC_I-zHh", + "outputId": "9a18f79c-5d4c-4c25-82f0-9309e4d7ec20", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "list(filter(lambda t: t == 'E', d_colaboradores['Programadores']))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['E']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "02t2Uczp8D03", + "outputId": "13e14ec9-c3fd-4b9e-ed60-d5d191054081", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "s_prog = list(filter(lambda t: t == 'E', d_colaboradores['Programadores']))\n", + "s_prog[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'E'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zfnP-CArmPb4" + }, + "source": [ + "## **Exercício 5**\n", + "\n", + "Retornar qual é o cargo do funcionário (todas as pessoas da organização) que se chama 'A'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BVbHId2mR9mc", + "outputId": "4831d244-36fb-4f37-f730-fe0429328b05", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_A = [item[0] for item in d_colaboradores.items() for nome in item[1] if nome == 'A']\n", + "l_A" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['Gerentes', 'Gerentes_Projeto']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VzjLVeFvmnjk" + }, + "source": [ + "## **Exercício 6**\n", + "\n", + "* Quais são os colabores que são ao mesmo tempo:\n", + " * Gerente de Projeto e Gerente (funcional)?\n", + " * Gerentes de Projeto e Programadores?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wnCi3kWcl8Sb", + "outputId": "b9e78b70-1fc1-45cf-f54d-df64b6241927", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_gerentes = [ l_nomes for l_nomes in d_colaboradores['Gerentes_Projeto'] for nome_comp in l_nomes for nome_comp2 in d_colaboradores['Gerentes'] if nome_comp == nome_comp2]\n", + "l_gerentes" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['A']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3kZ5FQgjW0Rn", + "outputId": "c058767e-9d8a-4651-a3e9-80d8429ed736", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_gerentes = [ l_nomes for l_nomes in d_colaboradores['Gerentes_Projeto'] for nome_comp in l_nomes for nome_comp2 in d_colaboradores['Programadores'] if nome_comp == nome_comp2]\n", + "l_gerentes" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['E']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TjO_Ol77YMJj" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB09_01__Functions_hs.ipynb b/Notebooks/NB09_01__Functions_hs.ipynb new file mode 100644 index 000000000..4edc3de18 --- /dev/null +++ b/Notebooks/NB09_01__Functions_hs.ipynb @@ -0,0 +1,1471 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB09_01__Functions.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d_YndS20uqkK" + }, + "source": [ + "

FUNÇÕES

\n", + "\n", + "\n", + "\n", + "# **AGENDA**:\n", + "\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e0UKAZQvJ_c2" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO ÀS FUNÇÕES**\n", + "> Funções são uma sequência de comandos para executar uma tarefa.\n", + ">> Atenção ao que recomenda o PEP8 sobre como escrever funções." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z4-gPTjZUP50" + }, + "source": [ + "# Não executar este codigo!\n", + "def funcao(arg1, arg2, ..., argN):\n", + " " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "etxNlyRYo39A" + }, + "source": [ + "def show_hello_world():\n", + " print('Hello World!')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "G6I9PFvZpBgR" + }, + "source": [ + "type(show_hello_world)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_meNdNygpIbv" + }, + "source": [ + "show_hello_world()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6zfLd8HwpPpg" + }, + "source": [ + "___\n", + "# **DOCUMENTAR FUNÇÕES COM COMMENTS/DOCSTRING**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3yzgBxtNpRi_" + }, + "source": [ + "def show_hello_world():\n", + " '''\n", + " Esta função faz um cumprimento: 'Hello World!'\n", + " Inputs: \n", + " param1: djdjdjdjdj\n", + " param2: fjrjirjjirjir\n", + " '''\n", + " print('Hello World!')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0rBaxjpmpbm1" + }, + "source": [ + "show_hello_world()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6ThOwDQp4TfR" + }, + "source": [ + "# Se quisermos ver a documentação da função, basta invocar o statement __doc__ da seguinte forma:\n", + "show_hello_world.__doc__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9YZ2afpNA4st" + }, + "source": [ + "OU..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uSnwA4BVA5_t" + }, + "source": [ + "help(show_hello_world)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "whbnnMA5p1Jw" + }, + "source": [ + "___\n", + "# **FUNÇÕES COM ARGUMENTOS**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O3bSjLA_qTTc" + }, + "source": [ + "Definir a função mostra_nome com dois argumentos: s_primeiro_nome e s_ultimo_nome:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9jWyCCPPp4yS" + }, + "source": [ + "def mostra_nome(s_primeiro_nome, s_ultimo_nome):\n", + " print(f'Olá, meu nome é {s_primeiro_nome} {s_ultimo_nome}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOB3Ip63qIzr" + }, + "source": [ + "mostra_nome('Nelio', 'Machado')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Oi0c_GuesfcL" + }, + "source": [ + "Neste caso, o primeiro argumento da função (s_primeiro_nome) vai receber o valor 'Nelio' e o segundo argumento da função (s_ultimo_nome) vai receber 'Machado'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qkMblpnLsITO" + }, + "source": [ + "No entanto, também podemos invocar a função da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TTli7e6xsMCo" + }, + "source": [ + "mostra_nome(s_ultimo_nome = 'Machado', s_primeiro_nome = 'Nelio')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rmatMmhTsaVc" + }, + "source": [ + "Observe que o resultado é o mesmo. No entanto, desta forma, estamos dizendo o valor específico que cada parâmetro irá receber." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PnNYrgJ6VQo9" + }, + "source": [ + "## PEP8 + Annotations = Códigos mais fáceis de entender e atualizar\n", + "\n", + "> Observe abaixo quando combinamos PEP8 + Annotations para tornar o código Python ainda mais detalhado. O objetivo de _Annotations_ é deixar o código mais claro, sem mudar o comportamento da função. No exemplo abaixo, os argumentos da função s_primeiro_nome e s_ultimo_nome são argumentos do tipo _str_ e a função retorna um _output_ do tipo _str_." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aU2Sob37VVmi" + }, + "source": [ + "def mostra_nome2(s_primeiro_nome: str, s_ultimo_nome: str) -> str:\n", + " print(f'Olá, meu nome é {s_primeiro_nome} {s_ultimo_nome}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iIvqS73mXNam" + }, + "source": [ + "mostra_nome2(s_ultimo_nome = 'Machado', s_primeiro_nome = 'Nelio')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rSnrtFNtXrbN" + }, + "source": [ + "# **\\*args**\n", + "> \\*args permite que você passe mais argumentos do que o número de argumentos formais que você definiu anteriormente." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x2rsiSseqHcX" + }, + "source": [ + "O que acontece quando evocamos a função mostra_nome2('Nelio', 'Pereira', 'Machado')?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8ap7pqmOqUnP" + }, + "source": [ + "mostra_nome2('Nelio', 'Pereira', 'Machado')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aT0_PeuEvXiP" + }, + "source": [ + "## Exemplo 1\n", + "> Considere a função (simples) para imprimir o nome completo de um cliente." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Npbi_Hy0bUec" + }, + "source": [ + "# definimos a função mostra_nome3 da seguinte forma:\n", + "def mostra_nome3(*args):\n", + " nome = ' '.join(args)\n", + " print(f'Olá, meu nome é {nome}.')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dFzM0gA3_9za" + }, + "source": [ + "mostra_nome3('Nelio', 'Machado')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "370bpgaSvDbJ" + }, + "source": [ + "E agora, a função recebe qualquer quantidade de parâmetros." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DQcRFHu4qnc5" + }, + "source": [ + "mostra_nome3('Nelio', 'Pereira', 'Machado')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4kYcu6PEX-Nz" + }, + "source": [ + "mostra_nome3('Pedro', 'de', 'Alcantara', 'Francisco', 'Antonio', 'Joao', 'Carlos', 'Xavier', 'de', 'Paula', 'Miguel', 'Rafael', 'Joaquim', 'Jose', 'Gonzaga', 'Pascoal', 'Cipriano', 'Serafim')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KMgngPmFimxb" + }, + "source": [ + "Observe que desta forma pouco importa a quantidade de parâmetros que passamos á função." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y9pDa6ZRjo0U" + }, + "source": [ + "## Exemplo 2\n", + "* Suponha que estamos insteressados em desenvolver uma função que multiplica dois números (passados como parâmetros)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1A-vhsHxv1YE" + }, + "source": [ + "Antes de vermos a solução usando \\*args, vamos ver como seria nossa função se \\*args não existisse." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCDwruF8j5i5" + }, + "source": [ + "### Forma \"Normal\"" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_R03BiwLjtwB" + }, + "source": [ + "# Definição da função\n", + "def multiplicar_numeros(x1, x2):\n", + " '''\n", + " Objetivo: Esta função multiplica DOIS números passados como argumentos.\n", + " Autor: Nelio Machado\n", + " Data: 04/10/2020\n", + " '''\n", + " return (x1 * x2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0eVm1Qj9kDtd" + }, + "source": [ + "print(multiplicar_numeros(3, 4))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4h9Nhkickf_8" + }, + "source": [ + "### Usando \\*args" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9Kf89meJkjw8" + }, + "source": [ + "def multiplicar_numeros2(*args):\n", + " '''\n", + " Objetivo: Esta função multiplica vários números passados como argumentos.\n", + " Autor: Nelio Machado\n", + " Data: 04/10/2020\n", + " '''\n", + " print(args)\n", + " print(type(args))\n", + " x = 1\n", + " for N in args:\n", + " x *= N # Isso é a mesma coisa que: x = x * N\n", + " \n", + " return x" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZuIzwitWk7by" + }, + "source": [ + "print(multiplicar_numeros2(1, 2, 3, 4, 5)) # Isso é a mesma coisa que 5! (cinco fatorial)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U5kyPu792gMN" + }, + "source": [ + "Eu também posso fazer da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oc2NJmJf2s7X" + }, + "source": [ + "args = (1, 2, 3, 4, 5)\n", + "print(multiplicar_numeros2(*args))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GM5NVX3fsaKv" + }, + "source": [ + "# Para conferirmos o resultado da função\n", + "import math\n", + "math.factorial(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "38jVie_IjMXI" + }, + "source": [ + "# \\**kwargs\n", + "\n", + "* \\**kwargs é usado para passar um dicionário de comprimento variável para uma função.\n", + "* Argumento do tipo {chave: valor};\n", + "\n", + "* Para exemplificar o uso de \\**kwargs, vou usar parte do dicionário dFruits que definimos na sessão [Dictionaries](Dictionaries.ipynb). Qualquer dúvida, volte áquele capítulo para relembrar os principais conceitos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yAntQ724nMbv" + }, + "source": [ + "# Definindo a função para receber parâmetros em forma de dicionário:\n", + "def imprime_frutas(**kwargs):\n", + " '''\n", + " Objetivo: Esta função imprime as frutas contidas em kwargs.\n", + " Autor: Nelio Machado\n", + " Data: 04/10/2020\n", + " '''\n", + " for key, value in kwargs.items():\n", + " print(f'O valor de {key} é {value}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jpmSk9mfxww3" + }, + "source": [ + "Atenção à forma como os itens são passados à função!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "88-1lStInaVs" + }, + "source": [ + "imprime_frutas(Avocado = 0.35, Apple = 0.4, Apricot = 0.25, Banana = 0.30)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-jb_kkLiyQt8" + }, + "source": [ + "No entanto, posso passar um dicionário na forma como estamos acostumados, da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JZJNiLz7wgCy" + }, + "source": [ + "d_frutas = {'Apple': 0.4, 'Avocado': 0.3, 'Orange': 0.5, 'Lemon': 0.25}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Emjm6xP7cjmV" + }, + "source": [ + "# De forma geral, atribuimos/adicionamos/update dos itens do dicionário da seguinte forma:\n", + "d_frutas[chave] = valor" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7WMsKxh0cPpN" + }, + "source": [ + "# Lembre-se que d_frutas \n", + "d_frutas.items()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eUCum4JPEcxD" + }, + "source": [ + "imprime_frutas(**d_frutas) # Atenção à forma como passamos o dicionário para a função: **dicionario." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iK8-e7a1sXmn" + }, + "source": [ + "___\n", + "# **Python return**\n", + "> Uma função Python pode ou não retornar um valor." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HS0dGA55siWw" + }, + "source": [ + "def par_ou_impar(i_numero1, i_numero2):\n", + " '''\n", + " Esta função somente avalia se a soma de dois números é par ou impar. \n", + " A função retorna odd ou even.\n", + " '''\n", + " i_soma = i_numero1+i_numero2\n", + " i_modulo = i_soma % 2\n", + " print(f'A soma é {i_soma}')\n", + " if i_modulo > 0:\n", + " return 'Odd'\n", + " else:\n", + " return 'Even' " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mZTG2tDJuIZQ" + }, + "source": [ + "i_numero1 = int(input('Por favor, informe o primeiro número: '))\n", + "i_numero2 = int(input('Por favor, informe o segundo número.: '))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7p_9pq3Du18a" + }, + "source": [ + "type(i_numero1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4oO7aAjcvCAe" + }, + "source": [ + "type(i_numero2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Br7yT8UHuKYY" + }, + "source": [ + "s_resultado = par_ou_impar(i_numero1, i_numero2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "601QnggJuhf-" + }, + "source": [ + "print(f'O resultado é {s_resultado}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t6HNf9j9yKcT" + }, + "source": [ + "Mostra o valor de i_modulo ou i_soma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yu8RsyDAyXne" + }, + "source": [ + "i_modulo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nx3twrLRyaeJ" + }, + "source": [ + "Python reporta que i_modulo não existe.\n", + "Está correta esta informação?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "imkyRO4kyvgV" + }, + "source": [ + "Considere o exemplo a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwRiXDA5y19h" + }, + "source": [ + "i_modulo = 0\n", + "\n", + "def par_ou_impar_v2(i_numero1, i_numero2):\n", + " '''\n", + " Esta função somente avalia se a soma de dois números é par ou impar. \n", + " A função retorna odd ou even.\n", + " '''\n", + " i_soma = i_numero1+i_numero2\n", + " i_modulo = i_soma % 2\n", + " print(f'A soma é {i_soma}')\n", + " if i_modulo > 0:\n", + " return 'Odd'\n", + " else:\n", + " return 'Even' " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GYxLSGQLy_Ai" + }, + "source": [ + "i_numero1 = int(input('Por favor, informe o primeiro número: '))\n", + "i_numero2 = int(input('Por favor, informe o segundo número.: '))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NMtv99fjzHGs" + }, + "source": [ + "s_resultado = par_ou_impar_v2(i_numero1, i_numero2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qjOHnYDVzNGK" + }, + "source": [ + "print(f'O resultado é {s_resultado}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pPTecxRfzQUc" + }, + "source": [ + "Agora, vamos checar o valor de i_modulo..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jkQb2mQzzTEo" + }, + "source": [ + "i_modulo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oOlyGxBAzjE3" + }, + "source": [ + "Porque agora o Python reconhece a variável i_modulo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dceSkt9Z0BZh" + }, + "source": [ + "___\n", + "# **ESCOPO DE VARIÁVEIS: LOCAL & GLOBAL**\n", + "* **Local** - Variável declarada dentro da função. Em outras palavras, é uma variável local/uso da função.\n", + "\n", + "* **Global** - Variável declarada fora da função. Neste caso, a variável é visível à todo o programa. Entretanto, não se pode alterar o valor da variável dentro da função. Caso queira alterar o valor da variável dentro da função, então é necesário declarar a variável usando a palavra reservada 'global’." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0tIjI9GScPxu" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QRojHHJ20iTY" + }, + "source": [ + "def exemplo1():\n", + " i_valor = 20\n", + " i_valor += 1\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RdhElmTs0y1c" + }, + "source": [ + "exemplo1()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tytq7PnH08pz" + }, + "source": [ + "O escopo da variável 'i_valor' é local, ou seja, de uso/restrito à função. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "299AK0PA1lIg" + }, + "source": [ + "i_valor" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gGP4cx17y8EZ" + }, + "source": [ + "Portanto, o erro acima faz sentido, pois a variável i_valor é restrito á função. Ou seja, fora da função o Python não conhece este valor." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KTV_6Gzxfvpc" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zyi9AyJwfxTm" + }, + "source": [ + "i_valor = 100\n", + "\n", + "def exemplo2():\n", + " i_valor = 20\n", + " i_valor += 1\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iEWrboG6gBSs" + }, + "source": [ + "exemplo2()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JPvT0BHG-vxE" + }, + "source": [ + "Isso é um tanto estranho! Definimos, fora da função, i_valor= 100 e, dentro da função, redefinimos i_valor= 20. Entretanto, como vimos, exemplo2() retorna 21 como resultado." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_t8tIDC-149" + }, + "source": [ + "Agora, a seguir, fora da função, pedimos para ver o valor de i_valor e temos, como resposta, o valor 100." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I46Bn4FlgJLu" + }, + "source": [ + "i_valor" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IQlP5nbngL6E" + }, + "source": [ + "Saberia nos explicar o que está acontecendo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h8PHd6rLgtwK" + }, + "source": [ + "## Exemplo 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qB7_zPQVgvVT" + }, + "source": [ + "i_valor = 100\n", + "\n", + "def exemplo3():\n", + " global i_valor\n", + " i_valor = 20\n", + " i_valor += 1\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2KgQSbYCg8Eq" + }, + "source": [ + "exemplo3()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y7yWoojrg_9Z" + }, + "source": [ + "i_valor" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cGlmbIJGzWG6" + }, + "source": [ + "Saberia explicar o que acontece neste exemplo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X8qFfIoxhFOp" + }, + "source": [ + "## Exemplo 4" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZM-yTLuO1bFh" + }, + "source": [ + "i_valor = 20\n", + "\n", + "def exemplo4():\n", + " i_valor += 1\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLvfPO8w1zwL" + }, + "source": [ + "exemplo4()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2V7QzpZp2QcM" + }, + "source": [ + "Qual a razão deste erro?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "w9qI8kln1_C7" + }, + "source": [ + "i_valor" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AQFFGqLI1FWn" + }, + "source": [ + "___\n", + "# **ARGUMENTOS DEFAULT**\n", + "> Considere o exemplo a seguir: toda vez que vai ao supermercado compra 1 pack de leite (contendo 4 garrafas) e 1 garrafão de água de 5L. Portanto, de forma simples, podemos definir nossa função da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HbcSTiBI4nOj" + }, + "source": [ + "# Define a função para receber os parâmetros arroz, feijao, leite e água.\n", + "def lista_de_compras(arroz, feijao, leite= 1, agua= 1):\n", + " '''\n", + " Documentação da função: objetivos, autor e data.\n", + " '''\n", + " print('Lista de Compras:')\n", + " print(f'Quantidade de arroz.: {arroz} kilos.') \n", + " print(f'Quantidade de feijão: {feijao} kilos.') \n", + " print(f'Quantidade de leite.: {leite} pack com 4.') \n", + " print(f'Quantidade de água..: {agua} garrafa de 5 litros.') " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vwZnDgoq5pgB" + }, + "source": [ + "lista_de_compras(5, 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l7bY5BSO7eJF" + }, + "source": [ + "Como leite= 1 e agua= 1 são valores default's, não precisamos passar esses parâmetros, desde que informamos ao Python o valor default. No entanto, se numa determinada semana precisarmos de 2 pack's de leite, ao invés de 1, devemos informar ao Python o novo valor:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YY4OrFuH7yXi" + }, + "source": [ + "lista_de_compras(5, 3, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-nfrZAvN73YT" + }, + "source": [ + "Da mesma forma, se numa outra semana precisarmos de 2 garrafões de água ao invés de 1, informamos ao Python da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vpoh6TdM7_xb" + }, + "source": [ + "lista_de_compras(5, 3, 2, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q3qZn9FuVQly" + }, + "source": [ + "___\n", + "# **map()**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dav8k0JYWi4B" + }, + "source": [ + "## Exemplo 1\n", + "> Suponha que queremos o quadrado de cada número passado à uma função." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "R6NC0i2OVktM" + }, + "source": [ + "l_numeros = [0, 1, 2, 3, 4, 5]\n", + "l_numeros" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AVjYlN44Vw2k" + }, + "source": [ + "def quadrado_do_numero(i_numero):\n", + " return (i_numero**2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "i_4CHiehV7lD" + }, + "source": [ + "list(map(quadrado_do_numero, l_numeros))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5tq8QDSPWNf6" + }, + "source": [ + "OU..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZAfkybybWOcG" + }, + "source": [ + "for i in map(quadrado_do_numero, l_numeros):\n", + " print(i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c01V5CEzWlGF" + }, + "source": [ + "## Exemplo 2\n", + "> substituir_truer todos os valores True da lista abaixo por 1 e False por 0." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qH1ackDZWvKp" + }, + "source": [ + "import random\n", + "\n", + "l_dados = []\n", + "for i in range(50):\n", + " random.seed(i)\n", + " l_dados.append(random.choice([True, False]))\n", + " \n", + "l_dados" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Dt2UKC-WXsxr" + }, + "source": [ + "def substituir_true(s_String):\n", + " if s_String == True:\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BIIkPuDEXaM0" + }, + "source": [ + "list(map(substituir_true, l_dados))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzkLIH1gYpFQ" + }, + "source": [ + "___\n", + "# **Filter()**\n", + "* Filtra elementos baseado em condições." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cjU8YznfZai1" + }, + "source": [ + "Suponha que agora eu quero filtrar os itens True da lista l_dados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a3SeaKJgZlAZ" + }, + "source": [ + "def filtrar_true(item):\n", + " if item == True:\n", + " return True\n", + " else:\n", + " return False" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1Z1APDQtZyXs" + }, + "source": [ + "list(filter(filtrar_true, l_dados))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xPpFqVUnKEH7" + }, + "source": [ + "___\n", + "# **EXERCÍCIOS**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RDgCRPRs0W6C" + }, + "source": [ + "## Exercício 1\n", + "Construa uma função para retornar o dia da semana a partir de um número, sendo:\n", + "\n", + "* 1 - Dom\n", + "* 2 - Seg\n", + "* 3 - Ter\n", + "* 4 - Qua\n", + "* 5 - Qui\n", + "* 6 - Sex\n", + "* 7 - Sab" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N53NOsZjOv9m" + }, + "source": [ + "## Exercício 2\n", + "* Desenvolver uma função que retorna True se s_palavra pertence à uma string e False caso contrário. Se pertencer, retornar a posição da palavra." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NJeqwxDjPxub" + }, + "source": [ + "A frase abaixo foi extraída de [+ Bíblia + Camões + Legião Urbana - (Guerra) = Monte Castelo](http://compondoletras.blogspot.com/2013/11/biblia-camoes-legiao-urbana-guerra.html)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Dj_n_beIPRBN" + }, + "source": [ + "s_frase = 'O amor é o fogo que arde sem se ver. É ferida que dói e não se sente. É um contentamento descontente. É dor que desatina sem doer'\n", + "s_frase" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "s40FJ9iCPPY0" + }, + "source": [ + "s_palavra = 'fogo'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzc2eaM7QUFE" + }, + "source": [ + "A palavra s_palavra está em s_frase?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pMx9E0xMu1lc" + }, + "source": [ + "## Exercício 3\n", + "Para mais exercícios envolvendo funções, consulte [Python functions - Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/python-functions-exercises.php)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mw6Wg5hFvFMR" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs.ipynb new file mode 100644 index 000000000..a5ad57e24 --- /dev/null +++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs.ipynb @@ -0,0 +1,2777 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_01__Pandas.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fpUiw8PwC7_" + }, + "source": [ + "

PANDAS PARA DATA ANALYSIS

\n", + "\n", + "\n", + "\n", + "# **Resposta dos Exercícios**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wkxQFPPmeKLl" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eKawOG-neqaD" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas2.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iwd1lhq9mrD3" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o_cl0kFgQfFh" + }, + "source": [ + "## Exercício 1\n", + "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s8rQUo7yHKJ1" + }, + "source": [ + "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KTun1uSLuJ-A" + }, + "source": [ + "## Exercício 2\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Soq7GVZnuREq" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6KEsTARfvM1C" + }, + "source": [ + "## Exercício 3\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hgxE5gZ9vMEg" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K1', 'K0', 'K1'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K0', 'K0', 'K0'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iv7AmZ1ivm8R" + }, + "source": [ + "### Perguntas\n", + "* Qual o output e a interpretação dos comandos a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TWAW_1tuvvSO" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QjM7pBONvzCJ" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D1Rr3Ghsv2iS" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vXQwLjT-v3Iu" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EIdltTC-t_lF" + }, + "source": [ + "## Exercício 5\n", + "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bMwPLgWclWBq" + }, + "source": [ + "___\n", + "## Exercício 6 - Resolvido\n", + "* Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ej6WjQX90n1E" + }, + "source": [ + "### Identificação e tratamento dos Missing Values\n", + "* Em geral, deletamos variáveis com mais de 50% de Missing Values." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nuaM4JKNLeSI" + }, + "source": [ + "df4.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaYc-HXNJ1TQ" + }, + "source": [ + "pd.set_option('display.max_rows', 500)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5s71jcHIGch" + }, + "source": [ + "df_missing_values = pd.DataFrame(df4.isnull().sum())\n", + "df_missing_values['mv_percent'] = 100*df_missing_values[0]/df4.shape[0]\n", + "df_missing_values[0].sort_values(ascending= False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V7KUGAX6lilP" + }, + "source": [ + "import pandas as pd\n", + "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/MathMachado/Python4DS/DS_Python/Dataframes/Titanic_With_MV.csv?token =AGDJQ63MNPPPROFNSO2BZW25XSR72', index_col= 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m3UnAPJakCLR" + }, + "source": [ + "* Segue o dicionário de dados do dataframe Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_6RvRCXgwomw" + }, + "source": [ + "### Avaliando inconsistências nas COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PToomnfRxxI5" + }, + "source": [ + "import seaborn as sns\n", + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3nc_iuRR1Tju" + }, + "source": [ + "# Uniformizando o nome das COLUNAS\n", + "df_Titanic.columns= [cols.lower() for cols in df_Titanic.columns]\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G9jteCnAxdnK" + }, + "source": [ + "### Coluna 'pclass'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wUk0YNlxsgvf" + }, + "source": [ + "df_Titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9vPrB3AAx0Ym" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='pclass', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2n8s9Ad1m7od" + }, + "source": [ + "Não me parece nada estranho com a variável 'pclass'. Ou você identifica alguma coisa estranho?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m8EGM6gSxrzS" + }, + "source": [ + "### Coluna 'sex'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BRRgcLtinIRz" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8SQ8v2Wnspfb" + }, + "source": [ + "df_Titanic['sex'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wpp0iL0kyGTl" + }, + "source": [ + "Qual sua opinião sobre esse preenchimento?\n", + "\n", + "Algum problema?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jxx06kJFnNrP" + }, + "source": [ + "Oops... Aqui temos vários problemas... Olhando para estes resultados, você concorda que 'male', 'm', 'MALE', M', 'mALE' e 'Men' se trata da mesma informação?\n", + "\n", + "Da mesma forma, 'female', 'f', 'F', 'Female', 'fEMALE', 'Woman', 'w' e 'W' também se trata da mesma informação?\n", + "\n", + "Então, vamos fazer o seguinte:\n", + "\n", + "* Toda vez que eu encontrar um desses valores: ['m', 'MALE', 'M', 'mALE', 'Men'], vou substituir por 'male';\n", + "* Toda vez que eu encontrar um desses valores: ['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], vou substituit por 'female'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oQbEVi1t2tfR" + }, + "source": [ + "df_Titanic2= df_Titanic.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "apc-ccODyZ-d" + }, + "source": [ + "#### Corrigir com df.replace()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwoyLBK9oME5" + }, + "source": [ + "df_Titanic['sex2'] = df_Titanic['sex'].replace(['m', 'MALE', 'M', 'mALE', 'Men'], 'male')\n", + "df_Titanic['sex3'] = df_Titanic['sex2'].replace(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], 'female') " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RC35I-Njp4vh" + }, + "source": [ + "Vamos ver a distribuição dos dados novamente no gráfico:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1eGvEhA9qAN6" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex3', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IY3TaKUcszTQ" + }, + "source": [ + "df_Titanic['sex3'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2nOAcv3iqEaK" + }, + "source": [ + "Ok, de fato corrigimos os problemas de preenchimento da variável 'sex'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dqLqmrTWylY3" + }, + "source": [ + "#### Corrigir com df.map()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dRvuNo4E3Ewx" + }, + "source": [ + "df_Titanic= df_Titanic2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3X0_ZdwCyquk" + }, + "source": [ + "d_sexo= {}\n", + "d_sexo.update(dict.fromkeys(['m', 'MALE', 'M', 'mALE', 'Men', 'male'], 'male'))\n", + "d_sexo.update(dict.fromkeys(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W', 'female'], 'female'))\n", + "d_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ3lwKRKbsx0" + }, + "source": [ + "Aplica a transformação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "idBwRNI7bvCC" + }, + "source": [ + "df_Titanic['sex2'] = df_Titanic['sex'].map(d_sexo)\n", + "df_Titanic['sex2'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzDl78rfb3p5" + }, + "source": [ + "Qual a conclusão? Este preenchimento faz mais sentido que o anterior?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SvrZtKRpzIDc" + }, + "source": [ + "# Deleta as variáveis 'sex':\n", + "df_Titanic = df_Titanic.drop(columns = ['sex'], axis = 1).rename(columns= {'sex2': 'sex'})\n", + "\n", + "# Mostra os dados:\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6URC6h8xzfc5" + }, + "source": [ + "sns.catplot(x=\"sex\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "k_spkJbmqdRW" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgBNoXUNzoWZ" + }, + "source": [ + "### Feature Engineering\n", + "#### Coluna 'cabin'\n", + "* Construir as COLUNAS:\n", + " * deck - Letra de Cabin;\n", + " * seat - Número de Cabin" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fHsLrnut6mk" + }, + "source": [ + "Sugestões:\n", + "1) Não descartar nenhuma informação (Fábio);\n", + "\n", + "2) Coluna com número de cabines reservadas (Thomaz)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "p0NFFxx8z-vq" + }, + "source": [ + "set(df_Titanic['cabin'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7E6yje89u7KF" + }, + "source": [ + "Como podemos ver, trata-se de uma variável categórica com vários níveis. Portanto, vamos capturar somente a primeira letra da variável 'cabin'. Para tal, vamos utilizar a função slice().\n", + "\n", + "> str.slice() - Captura (slice) partes de s_Str." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wmZLlSaArR6F" + }, + "source": [ + "A seguir, capturamos a primeira letra da variável 'cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hUZTJU0MvVxP" + }, + "source": [ + "# definindo a variável 'deck' que representará a primeira letra da variável 'cabin'\n", + "df_Titanic[\"deck\"] = df_Titanic[\"cabin\"].str.slice(0, 1) # slice(inicio, tamanho_da_string)\n", + "df_Titanic['deck'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6myhrth0rZ6t" + }, + "source": [ + "A seguir, vamos extrair a parte numérica da variável 'cabin' usando Expressões Regulares:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8UXkACPmsfwN" + }, + "source": [ + "# Importar a biblioiteca para Expressões Regulares\n", + "import re" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QKk-fnW4rf4o" + }, + "source": [ + "# Primeiramente, usamos a função split() para separar o conteúdo da variável em COLUNAS: \n", + "new = df_Titanic[\"cabin\"].str.split(\" \", n = 3, expand = True) \n", + "new.head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dFqoR-Xew9gX" + }, + "source": [ + "Observe acima que o comando gera quantos splits da variável eu quiser. No entanto, por simplicidade, me interessa somente o primeiro split." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_M7vA6WoVG05" + }, + "source": [ + "Agora, vou extrair o número do assento do passageiro usando Expressões Regulares:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVH5o9KT_IH3" + }, + "source": [ + "# Aqui está o conteúdo de new[0]:\n", + "new[0].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "P7NTcsGOxxSX" + }, + "source": [ + "new2= new[0].str.extract('(\\d+)')\n", + "new2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf8vw2Mc18bQ" + }, + "source": [ + "Por fim, vou carregar esta informação ao dataframe df:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6l6EoRvsxRXn" + }, + "source": [ + "df_Titanic[\"seat\"] = new2\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LK4V61uy3N9s" + }, + "source": [ + "Por fim, excluir a variável 'cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4uAr55J43NY7" + }, + "source": [ + "df_Titanic= df_Titanic.drop(columns= [\"cabin\"], axis =1, errors=\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qZuH7YJXZCgY" + }, + "source": [ + "### Coluna 'embarked'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nTPikhrIZGya" + }, + "source": [ + "df_Titanic['embarked'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ixbZsuqOZsOc" + }, + "source": [ + "sns.catplot(x=\"embarked\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvdU8aAwZNvG" + }, + "source": [ + "Não vejo problemas com esta variável. Vamos em frente..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k2SLRAhrub_B" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YRJcWaYkuxK4" + }, + "source": [ + "sns.countplot(x = 'pclass', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rzrOUULUu6-P" + }, + "source": [ + "sns.countplot(x = 'sex', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DfSMcYYZ5yLV" + }, + "source": [ + "### Variável 'pclass'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q2uU0k-G5yLN" + }, + "source": [ + "df_Titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Gue26Y3A5yLL" + }, + "source": [ + "Algum problema com esta variável?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "q3P82wPp5yK8" + }, + "source": [ + "sns.catplot(x=\"pclass\", kind=\"count\", data = df)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qrnc6VUKSTNp" + }, + "source": [ + "### Coluna 'parch'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i4ed-0zSvJc" + }, + "source": [ + "df_Titanic['parch'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qd7u__6KZ6DM" + }, + "source": [ + "sns.catplot(x=\"parch\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z9vM3vktC7BG" + }, + "source": [ + "### Feature Engineering\n", + "* Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nd4TyOYjs-HW" + }, + "source": [ + "# Função para retornar 0 ou 1 em função dos valores de variavel\n", + "def sozinho(variavel):\n", + " if (variavel == 0):\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5oByiBuos_B3" + }, + "source": [ + "df_Titanic['sozinho_parch'] = df_Titanic['parch'].map(sozinho)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C1ICby1oSd41" + }, + "source": [ + "### Coluna 'sibsp'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5n7JNEQqTNjz" + }, + "source": [ + "df_Titanic['sibsp'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NLfMhiy0x4u5" + }, + "source": [ + "* Algum problema?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nayYFRK9g8iV" + }, + "source": [ + "sns.catplot(x=\"sibsp\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KzCX2MTmE9Tw" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sibsp', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_58rZqMaDzf-" + }, + "source": [ + "### Feature Engineering:\n", + "* Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HUrJ4IywrEoA" + }, + "source": [ + "df_Titanic['sozinho_sibsp'] = df_Titanic['sibsp'].map(sozinho)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0MO9jj2NvGp_" + }, + "source": [ + "### Coluna 'fare'\n", + "> Discretizar a coluna 'fare' em 10 buckets." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4-qO2Xk76Buz" + }, + "source": [ + "df_Titanic['fare_class'] = pd.qcut(df_Titanic['fare'], 10, labels=False)\n", + "df_Titanic['fare_class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "boAj64RHvQHu" + }, + "source": [ + "sns.catplot(x=\"fare_class\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3CIqHUJpvcPa" + }, + "source": [ + "### Coluna 'age'\n", + "> Discretizar a coluna 'age' em 10 buckets." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rCRnbKX57VN-" + }, + "source": [ + "df_Titanic['age_class'] = pd.qcut(df_Titanic['age'], 10, labels=False)\n", + "df_Titanic['age_class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uFsZLYDi7VOH" + }, + "source": [ + "sns.catplot(x=\"age_class\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DIY-sL337uje" + }, + "source": [ + "#### Alternativa para discretizar 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W66GkyuKkhFe" + }, + "source": [ + "def Age_Category(age):\n", + " if (age <= 1):\n", + " return 1\n", + " elif (age <= 5):\n", + " return 2\n", + " elif(age <= 10):\n", + " return 3\n", + " elif (age <= 15):\n", + " return 4\n", + " elif (age <= 20):\n", + " return 5\n", + " elif (age <= 25):\n", + " return 6\n", + " elif(age < 30):\n", + " return 7\n", + " elif(age < 35):\n", + " return 8\n", + " elif(age < 40):\n", + " return 9\n", + " elif(age < 45):\n", + " return 10\n", + " elif(age < 50):\n", + " return 11\n", + " elif(age < 60):\n", + " return 12\n", + " elif(age < 70):\n", + " return 13\n", + " elif(age < 80):\n", + " return 14\n", + " else:\n", + " return 15" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TnLzC6hCkuBL" + }, + "source": [ + "df_Titanic['age_class2'] = df['age'].map(Age_Category)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kG8td6HPsNlP" + }, + "source": [ + "set(df_Titanic['age_category']) # Esse comando mostra os NaN's da coluna, se houver." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B_3s5cgxfNKQ" + }, + "source": [ + "### Coluna 'title'\n", + "\n", + "* Para fins de Data Manipulation, vamos capturar o tratamento dos passageiros contido na variável 'nome'. Ou seja, 'Mr.', 'Mrs.', 'Miss' e etc...\n", + "\n", + "> Fonte: As funções get_title e title_map foram extraídas de https://www.kaggle.com/tjsauer/titanic-survival-python-solution" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gslSjRdDoJFY" + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XjqEVVnr8R4d" + }, + "source": [ + "Primeiramente, vamos entender como funciona, step by step..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D6gjWc3XozK7" + }, + "source": [ + "'Allen, Mr. William Henry'.split(',')[1].split('.')[0].strip()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nfIG6toGfhd5" + }, + "source": [ + "def get_title(nome):\n", + " if '.' in nome:\n", + " return nome.split(',')[1].split('.')[0].strip()\n", + " else:\n", + " return 'Unknown'\n", + "\n", + "def title_map(title):\n", + " if title in ['Mr', 'Ms']:\n", + " return 1\n", + " elif title in ['Master']:\n", + " return 2\n", + " elif title in ['Ms','Mlle','Miss']:\n", + " return 3\n", + " elif title in [\"Mme\", \"Ms\", \"Mrs\"]:\n", + " return 4\n", + " elif title in [\"Jonkheer\", \"Don\", \"Sir\", \"the Countess\", \"Dona\", \"Lady\"]:\n", + " return 5\n", + " elif title in [\"Capt\", \"Col\", \"Major\", \"Dr\", \"Rev\"]:\n", + " return 6\n", + " else:\n", + " return 7" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HLQoJwf0rjrf" + }, + "source": [ + "Exercícios\n", + "* Melhorar a função title_map." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7qNUwnCepe_x" + }, + "source": [ + "Captura o tratamento dos passageiros:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-Ltf33vgJ6Q" + }, + "source": [ + "df_Titanic['title'] = df_Titanic['nome'].apply(get_title).apply(title_map) \n", + "set(df_Titanic['title']) # Esse comando mostra os NaN's da variável" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D3hY0WVhpRYK" + }, + "source": [ + "Drop a coluna 'nome', pois não vamos mais precisar dela em nossas análises:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8i3xKCes5WF" + }, + "source": [ + "df_Titanic= df_Titanic.drop(columns= [\"nome\"], axis =1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Sl1uFdwpW3y" + }, + "source": [ + "Apresenta o conteúdo do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2uFnw-pZpan-" + }, + "source": [ + "df_Titanic.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0fZMKKpdHIl" + }, + "source": [ + "## Missing Value\n", + "> Faça o devido tratamento de NaN's das COLUNAS do dataframe df_Titanic.\n", + "\n", + "**Pergunta**: Na coluna 'value', os valores 0 (zero) são considerados Missing Values?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UHzKFytXsNkh" + }, + "source": [ + "df_Titanic['age'].isna().sum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZC1ULWd883t2" + }, + "source": [ + "## Relação causa --> efeito" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_WCbklv0bDlp" + }, + "source": [ + "A função a seguir nos ajudará com o Data Visualization, cruzando a variável-resposta 'survived' com qualquer outra passada à função:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "epxI-F2UbGGS" + }, + "source": [ + "def taxa_sobrevivencia(df, column):\n", + " title_xt = pd.crosstab(df[column], df['survived'])\n", + " print(pd.crosstab(df[column], df['survived'], margins=True))\n", + " title_xt_pct = title_xt.div(title_xt.sum(1).astype(float), axis =0)\n", + " \n", + " title_xt_pct.plot(kind='bar', stacked=True, title='Taxa de Sobrevivência dos Passageiros', \n", + " color= ['r', 'g'])\n", + " plt.xlabel(column)\n", + " plt.ylabel('Taxa de Sobrevivência')\n", + " plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),shadow=True, ncol=2)\n", + " plt.show()\n", + "\n", + "def grafico_catplot(x, y, hue = 'survived', col= None):\n", + " plt.rcdefaults()\n", + " g= sns.catplot(x= x, y= y, hue = hue, palette={'Died':'red','Survived':'blue'}, col= col, data = df, kind= 'bar', height=4, aspect=.7)\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "34-Qbd_QrC8W" + }, + "source": [ + "Qual a relação entre a variável 'sex' e a variável-resposta?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bhY8-UjyrC8Z" + }, + "source": [ + "taxa_sobrevivencia(df_Titanic, 'sex')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbexhGtayV4X" + }, + "source": [ + "## Exercício 7\n", + "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P62MXm3tK8Ty" + }, + "source": [ + "## Exercício 8\n", + "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Du7Y8E4uFmiu" + }, + "source": [ + "i_linhas_Titanic = df_Titanic.shape[0]\n", + "\n", + "df_Titanic['aleatorio'] = np.random.random(i_linhas_Titanic)\n", + "df_Titanic.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LMD3HksDL0PQ" + }, + "source": [ + "## Exercício 9\n", + "\n", + "1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);\n", + "2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n", + "3. Qual o dtype de cada variável/atributo do dataframe?\n", + "4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n", + "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;\n", + "6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n", + "7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição.\n", + "8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');\n", + "9. Qual a número de jogadores por idade?\n", + "10. Quantos jogadores possuem cada clube?\n", + "11. Qual a média de idade por clube?\n", + "12. Qual a média de salário por país?\n", + "13. Qual a média de salário por clube?\n", + "14. Qual a média de salário por idade?\n", + "15. Quanto cada clube gasta com pagamento de salários?\n", + "16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?\n", + "17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n", + "18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n", + "19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'.\n", + "20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed'=?\n", + "21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?\n", + "22. Quem são os outliers em termos de salário?\n", + "23. Quem são os outliers em termos de potência no chute?\n", + "24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?\n", + "25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "70Ml5KyZ04mk" + }, + "source": [ + "A seguir, significado da variável \"Position\":\n", + "* GK = Goalkeeper – Goleiro.\n", + "* RB = Right Back – Zagueiro Direito.\n", + "* CB = Central Back – Zagueiro Central.\n", + "* LB = Left Back – Zagueiro Esquerdo.\n", + "* SW = Sweeper – Líbero.\n", + "* RWB = Right Wing Back – Lateral Direito.\n", + "* LWB = Left Wing back – Lateral Esquerdo.\n", + "* CDM = Central Defensive Midfielder – Meio Campo Defensivo / Volante.\n", + "* CM = Central Midfielder – Meia Central.\n", + "* CAM = Center Attacking Middlefielder – Meio Campo Ofensivo / Armador.\n", + "* OM = Offensive Midfielder – Meia Ofensivo.\n", + "* LOM = Left Offensive Midfielder – Meia Esquerda Ofensivo.\n", + "* ROM = Right Offensive Midfielder – Meia Direita Ofensivo.\n", + "* LM = Left Midfielder – Meia Esquerda.\n", + "* RM = Right Midfielder – Meia Direita.\n", + "* LWM = Left Wing Midfielder – Meio Ala Esquerdo.\n", + "* RWM = Right Wing Midfielder – Meio Ala Direito.\n", + "* RW = Right Winger – Ala Direito.\n", + "* LW = Left Winger – Ala Esquerto.\n", + "* LF = Left Forward – Atacante Esquerdo.\n", + "* RF = Right Forward – Atacante Direito.\n", + "* ST = Striker – Atacante.\n", + "* CF = Center Forward – Centro Avante.\n", + "* RS = Right Striker – Atacante Direito.\n", + "* LS = Left Striker – Atacante Esquerdo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tjHDjj68zawa" + }, + "source": [ + "## 1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wzosi4Ue1vDs" + }, + "source": [ + "### Carregar as libraries necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B0fqR6rzMAa3" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vgoLTamaOC50" + }, + "source": [ + "#### Configurar ambiente" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RRwi_z8JOFrD" + }, + "source": [ + "d_configuracao = {\n", + " 'display.max_columns': 1000,\n", + " 'display.expand_frame_repr': True,\n", + " 'display.max_rows': 10,\n", + " 'display.precision': 2,\n", + " 'display.show_dimensions': True\n", + " }\n", + "\n", + "for op, value in d_configuracao.items():\n", + " pd.set_option(op, value)\n", + " print(op, value)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MdVljEbcMGU9" + }, + "source": [ + "#### Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GMivDUHEMFKp" + }, + "source": [ + "df = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA.csv?token=AGDJQ63GC7SPIHTGNW73QB27RXRN6') #, index_col= 'PassengerId')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7pDUpFVLTOfl" + }, + "source": [ + "#### Definir a coluna 'ID' como index do dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TEue20CbMp9U" + }, + "source": [ + "df.set_index('ID', inplace = True)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G8CDrpI1_wMd" + }, + "source": [ + "### Função para retirar os sinais de \"+\" ou \"-\" em algumas colunas/vriáveis:\n", + "* Percebeste algumas colunas com o sinal de \"+\" no nome?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7zqHkNCsEDpJ" + }, + "source": [ + "A seguir, exemplo de algumas colunas com este problema:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_hUvJbCqCBBl" + }, + "source": [ + "df[['RS', 'LS', 'ST']].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "78QhptWdEIB0" + }, + "source": [ + "A seguir, definimos um dataframe chamado df_string contendo a quantidade de colunas separadas pelo sinal \"+\". Observe que o máximo de colunas que obtemos são 2. Porque?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DzeSvQMGF4G7" + }, + "source": [ + "df_string = df['RS'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n", + "df_string.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PEzqRR5CEUru" + }, + "source": [ + "df_string[0] = pd.to_numeric(df_string[0])\n", + "df_string[1] = pd.to_numeric(df_string[1])\n", + "df_string['RS2'] = df_string[0]+df_string[1]\n", + "\n", + "df_string.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2t4rnjRWFPON" + }, + "source": [ + "df_string.dtypes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MAYju4f6GFzw" + }, + "source": [ + "df_string.drop(columns= [0, 1], axis = 1, inplace = True)\n", + "df = pd.merge(df, df_string, how = 'left', on = 'ID')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sm5lOGrrHoDp" + }, + "source": [ + " **Desafio**: Próximo passo: transformar isso numa função para tratar as demais variáveis!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QtmOlKNpzbOz" + }, + "source": [ + "## 2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7TzcuD2GxfBP" + }, + "source": [ + "### Colunas que poderiam previamente ser eliminadas:\n", + "* Photo\n", + "* Flag\n", + "* Club Logo\n", + "* Unnamed: 0" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kXDe_AdEx3DD" + }, + "source": [ + "df2 = df.copy()\n", + "\n", + "l_cols_drop = ['Unnamed: 0', 'Photo', 'Flag', 'Club Logo']\n", + "df2.drop(columns = l_cols_drop, axis = 1, inplace = True)\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m97dcDy9zbSO" + }, + "source": [ + "## 3. Qual o dtype de cada variável/atributo do dataframe?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GEbvITXR2U17" + }, + "source": [ + "# Função para nos mostrar o tipo das colunas:\n", + "def mostra_tipo(df):\n", + " d_tipos = dict(zip(df.columns, df.dtypes))\n", + " for item in d_tipos.items():\n", + " print(item)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3B9vxmbl9HNP" + }, + "source": [ + "mostra_tipo(df2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5XKcxC0Pzshm" + }, + "source": [ + "## 4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A7T31nFiPdDu" + }, + "source": [ + "### Mudar o tipo de algumas colunas\n", + "* Exemplo: 'Wage', 'Value' e 'Release Clause'. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VJSsvOpK71n7" + }, + "source": [ + "df4 = df2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xyV-_MY9688C" + }, + "source": [ + "def transforma_monetarias(coluna):\n", + " if 'M' in coluna:\n", + " return int(float(coluna.replace('M', '')) * 1000000)\n", + "\n", + " elif 'K' in coluna:\n", + " return int(float(coluna.replace('K', '')) * 1000)\n", + " \n", + " else:\n", + " return int(coluna) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AJ9-8sVS6MXj" + }, + "source": [ + "Substituindo o símbolo \"€\" por '':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ArgK2NVe6vqz" + }, + "source": [ + "l_colunas_monetarias = ['Value', 'Wage']\n", + "\n", + "for coluna in l_colunas_monetarias:\n", + " df4[coluna] = df4[coluna].str.replace('€', '')\n", + " df4[coluna] = df4[coluna].apply(lambda x: transforma_monetarias(x))\n", + "\n", + "df4.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c_lznTRHzbV9" + }, + "source": [ + "## 5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "usM674sR8Gv9" + }, + "source": [ + "df5 = df4.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N6LCmJ0QUsJo" + }, + "source": [ + "### Nome das colunas --> Substituir os \" \" por \"_\" nos nomes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NWJYqphfUxn1" + }, + "source": [ + "df5.columns = [c.replace(' ', '_') for c in df5.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lXUOzLWmVTNZ" + }, + "source": [ + "### Renomear as colunas usando lower()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZwwLMOYRVXnr" + }, + "source": [ + "df5.columns = [c.lower() for c in df5.columns]\n", + "mostra_tipo(df5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uc12gBThz1nD" + }, + "source": [ + "## 6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nYgvxvcT8QIT" + }, + "source": [ + "df6 = df5.copy()\n", + "df6.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9STC9fsWJAHn" + }, + "source": [ + "# Fazendo uma cópia permanente do dataframe df6 para uso futuro\n", + "df6[['overall', 'potential', 'value', 'wage', 'nationality', 'position', 'age', 'preferred_foot']].to_csv('FIFA_algumas_features.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ESFYFvOy8XOM" + }, + "source": [ + "Aqui vou substituir os Missing Values pela mediana. Fique à vontade para substituir por outras alternativas como min, max, média, limite superior de outliers e limite inferior para outliers." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "j7zDrRvi8iay" + }, + "source": [ + "l_colunas_numericas = df6.select_dtypes(np.number).columns.tolist()\n", + "l_colunas_numericas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mZEM0N2f9vi7" + }, + "source": [ + "# Mediana antes da substituição:\n", + "df6[l_colunas_numericas].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dzfw0kp69dK2" + }, + "source": [ + "# Substituição pela mediana\n", + "for coluna in l_colunas_numericas:\n", + " df6[coluna].fillna(df6[coluna].median())\n", + "\n", + "# Mediana depois da substituição:\n", + "df6[l_colunas_numericas].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jpQR9zDC-nEj" + }, + "source": [ + "Abaixo, identifiquei 252 registros com value = 0 --> Nestes casos, vou atribuir a mediana também." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s1Zj3gBJ-Z5c" + }, + "source": [ + "df6[df6['value'] == 0]['value'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HjuNw2u6-7i9" + }, + "source": [ + "# Mediana antes\n", + "df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VWEp0Tc_-vLD" + }, + "source": [ + "# Atribuição da mediana para os valores 0 de 'value'\n", + "df6.loc[df6['value'] == 0, 'value'] = df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HynCT_Yu_JL-" + }, + "source": [ + "# Mediana depois\n", + "df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B4O5kw6h_z3H" + }, + "source": [ + "E se tivéssemos substituído pela média, ao invés da mediana? Teria mudado alguma coisa?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eU7ybhA2zbZh" + }, + "source": [ + "## 7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A34BwvXrXAqU" + }, + "source": [ + "df7 = df6.copy()\n", + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fu87YSiudcM_" + }, + "source": [ + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IQQ7AvgBYZmx" + }, + "source": [ + "df_jogadores_por_paises = pd.DataFrame(df7.groupby(by=['nationality']).size())\n", + "df_jogadores_por_paises.columns = ['numero_jogadores']\n", + "df_jogadores_por_paises.sort_values(by = ['numero_jogadores'], ascending = False, inplace= True)\n", + "df_jogadores_por_paises = df_jogadores_por_paises.reset_index()\n", + "df_jogadores_por_paises\n", + "\n", + "# Numa única linha ficaria assim:\n", + "df_jogadores_por_paises2 = pd.DataFrame(df7.groupby(by=['nationality']).size(), columns= ['numero_jogadores']).sort_values(by = ['numero_jogadores'], ascending = False).reset_index()\n", + "df_jogadores_por_paises2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JfyDUEC2zbcv" + }, + "source": [ + "## 8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0a9MvyWPcu-C" + }, + "source": [ + "df_media_idade_por_paises = df7.groupby(by = ['nationality']).agg({'age': ['count', 'mean']}).reset_index()\n", + "df_media_idade_por_paises.columns = ['nationality', 'numero_joagadores', 'media_idade']\n", + "df_media_idade_por_paises.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n", + "df_media_idade_por_paises.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vNmu0xyg0CW4" + }, + "source": [ + "## 9. Qual a número de jogadores por idade?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DRVvPgpRf9vw" + }, + "source": [ + "df_jogadores_por_idade = df7.groupby(by = ['age']).agg({'age': ['count']}).reset_index()\n", + "df_jogadores_por_idade.columns = ['age', 'numero_joagadores']\n", + "df_jogadores_por_idade.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n", + "df_jogadores_por_idade.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8eChi2NW0CZp" + }, + "source": [ + "## 10. Quantos jogadores possuem cada clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JpNI3ZlHgUx1" + }, + "source": [ + "df_jogadores_por_clube = df7.groupby(by = ['club']).size().reset_index()\n", + "df_jogadores_por_clube.columns = ['clube', 'numero_joagadores']\n", + "df_jogadores_por_clube.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n", + "df_jogadores_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gMiibNwW0Cck" + }, + "source": [ + "## 11. Qual a média de idade por clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D9rF9frzgqSr" + }, + "source": [ + "df_media_idade_por_clube = df7.groupby(by = ['club']).agg({'age': ['count', 'mean']}).reset_index()\n", + "df_media_idade_por_clube.columns = ['clube', 'numero_joagadores', 'media_idade']\n", + "df_media_idade_por_clube.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n", + "df_media_idade_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uE_o76xH0QU-" + }, + "source": [ + "## 12. Qual a média de salário por país?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "keQXqnU7hJy4" + }, + "source": [ + "df_media_salario_por_pais = df7.groupby(by = ['nationality']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_pais.columns = ['nationality', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_pais.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_pais.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vqT1ozNA0Cfd" + }, + "source": [ + "## 13. Qual a média de salário por clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "54_Q2IGchmN-" + }, + "source": [ + "df_media_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_clube.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4eflozOo0Cif" + }, + "source": [ + "## 14. Qual a média de salário por idade?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xtq9Am60hwGr" + }, + "source": [ + "df_media_salario_por_idade = df7.groupby(by = ['age']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_idade.columns = ['age', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_idade.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_idade.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L0yRSSIb0WYj" + }, + "source": [ + "## 15. Quanto cada clube gasta com pagamento de salários?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C9N7_pLfh_uq" + }, + "source": [ + "df_soma_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean', 'sum']}).reset_index()\n", + "df_soma_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario', 'soma_salario']\n", + "df_soma_salario_por_clube.sort_values(by = ['soma_salario'], ascending = False, inplace = True)\n", + "df_soma_salario_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1c7NGMg90YMi" + }, + "source": [ + "## 16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RAU41Iyaihvc" + }, + "source": [ + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bM_ePTWfiTFq" + }, + "source": [ + "df_potential_por_clube = df7.groupby(by = ['potential', 'club', 'nationality']).agg({'potential': ['count']}).reset_index()\n", + "df_potential_por_clube.columns = ['potential', 'club', 'nationality', 'numero_joagadores']\n", + "df_potential_por_clube.sort_values(by = ['potential'], ascending = False, inplace = True)\n", + "df_potential_por_clube.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HytWPvfvjTON" + }, + "source": [ + "#### Quem é o jogador com potential = 95?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Fk2X1q7LjWJE" + }, + "source": [ + "df7.loc[df7['potential'] == 95]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W2o4oLzujnHj" + }, + "source": [ + "#### Quem são os jogadores com potencial = 94?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GOCyMr-qjsL7" + }, + "source": [ + "df7.loc[df7['potential'] == 94]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LHDJimdw0ClU" + }, + "source": [ + "## 17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FXFp5nxrj9Yc" + }, + "source": [ + "df_overall = df7.groupby(by = ['overall', 'club', 'nationality']).agg({'overall': ['count']}).reset_index()\n", + "df_overall.columns = ['overall', 'club', 'nationality', 'numero_joagadores']\n", + "df_overall.sort_values(by = ['overall'], ascending = False, inplace = True)\n", + "df_overall.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LTooiIdk1XV" + }, + "source": [ + "#### Quem é o jogador com overall = 94?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QieAKyi7k5Bb" + }, + "source": [ + "df7.loc[df7['overall'] == 94]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JFH54d1D0b5B" + }, + "source": [ + "## 18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n", + "* Para responder esta questão, tirei a média de overall e potential." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JZ7PTFTle_d" + }, + "source": [ + "df18 = df7.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "s25u8RoplMZ8" + }, + "source": [ + "df18['overall_potential'] = ((df18['potential']+df18['overall'])/2)\n", + "df18[['name', 'overall', 'potential', 'overall_potential']].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8gJFzhhIlDCH" + }, + "source": [ + "df_overall_potential = df18.groupby(by = ['club', 'nationality', 'age']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential.columns = ['club', 'nationality', 'age', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "adpxQpWlmvac" + }, + "source": [ + "De forma geral:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fzn_81eomrj2" + }, + "source": [ + "df_overall_potential2 = df18.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential2.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential2.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential2.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dM8FehYC0df7" + }, + "source": [ + "## 19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_967BF6MnD4U" + }, + "source": [ + "df19 = df18.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wXPah5zOmkXc" + }, + "source": [ + "df_goleiros = df19[df19['position'] == 'GK']\n", + "df_goleiros.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "77ehyNmSnTIB" + }, + "source": [ + "df_overall_potential_goleiros = df_goleiros.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential_goleiros.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential_goleiros.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential_goleiros.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-dEtuBtF0fiZ" + }, + "source": [ + "## 20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed')?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KWMU1hMMnxTI" + }, + "source": [ + "df20 = df19.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sezEQIjqnwCZ" + }, + "source": [ + "df20.sort_values(by = 'sprintspeed', ascending = False).head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aEg0eaFO0lF6" + }, + "source": [ + "## 21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xXuj-dc7oA-0" + }, + "source": [ + "df21 = df20.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8HGT_dM2oEES" + }, + "source": [ + "df21.sort_values(by = 'shotpower', ascending = False).head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bRk42JIf0moZ" + }, + "source": [ + "## 22. Quem são os outliers em termos de salário?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qRNaog7y0qI4" + }, + "source": [ + "### Identificação e tratamento dos Outliers\n", + "* Qual o Overall médio do Barcelona, Juventus e Real Madrid?\n", + "* E qual o overall médio depois do tratamento dos outliers?\n", + "* Quem são os atletas que estão influenciando a média?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_bIxG1Sw9OUB" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)\n", + "\n", + "Fonte: [Understanding Boxplots](https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qEiikIxNoZkl" + }, + "source": [ + "df22 = df21.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lGYYvE0BoOoV" + }, + "source": [ + "q1_salario, q3_salario = df22['wage'].quantile([0.25,0.75]).to_list()\n", + "iqr_salario = q3_salario - q1_salario\n", + "print(q1_salario, q3_salario)\n", + "print(iqr_salario)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PB44VV9pogT1" + }, + "source": [ + "outlier_salario_inferior = q1_salario - 1.5 * iqr_salario\n", + "outlier_salario_superior = q3_salario + 1.5 * iqr_salario\n", + "\n", + "df_outliers_salario = df22[['name', 'club', 'nationality', 'wage', 'overall', 'potential']]\n", + "\n", + "# Salários outliers inferiores\n", + "df_outliers_salario[df_outliers_salario['wage'] < outlier_salario_inferior]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9867KNNBqG7Z" + }, + "source": [ + "# Top 10 Salários outliers superior\n", + "df_outliers_salario[df_outliers_salario['wage'] > outlier_salario_superior].sort_values(by = ['wage'], ascending = False).head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gT2zGwq90oQ5" + }, + "source": [ + "## 23. Quem são os outliers em termos de potência no chute?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "05uYj7cwqrdW" + }, + "source": [ + "df23 = df22.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GzbVRU9HqrdZ" + }, + "source": [ + "q1_chute, q3_chute = df23['shotpower'].quantile([0.25,0.75]).to_list()\n", + "iqr_chute = q3_chute - q1_chute\n", + "print(q1_chute, q3_chute)\n", + "print(iqr_chute)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V5TQX_yGqrda" + }, + "source": [ + "outlier_chute_inferior = q1_chute - 1.5 * iqr_chute\n", + "outlier_chute_superior = q3_chute + 1.5 * iqr_chute\n", + "\n", + "df_outliers_chute = df23[['name', 'club', 'nationality', 'shotpower', 'overall', 'potential']]\n", + "\n", + "# Salários outliers inferiores\n", + "df_outliers_chute[df_outliers_chute['shotpower'] < outlier_chute_inferior]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "URj1SYXxqrdc" + }, + "source": [ + "# Top 10 outliers superiores - shotpower\n", + "df_outliers_chute[df_outliers_chute['shotpower'] > outlier_chute_superior].sort_values(by = ['shotpower'], ascending = False).head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eHm1qeHx0pza" + }, + "source": [ + "## 24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OR6MD2GQ0rNq" + }, + "source": [ + "## 25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;" + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs2.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs2.ipynb new file mode 100644 index 000000000..2c4eeaa3c --- /dev/null +++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_hs2.ipynb @@ -0,0 +1,2777 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_01__Pandas.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fpUiw8PwC7_" + }, + "source": [ + "

PANDAS PARA DATA ANALYSIS

\n", + "\n", + "\n", + "\n", + "# **Resposta dos Exercícios**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wkxQFPPmeKLl" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eKawOG-neqaD" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas2.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iwd1lhq9mrD3" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o_cl0kFgQfFh" + }, + "source": [ + "## Exercício 1\n", + "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s8rQUo7yHKJ1" + }, + "source": [ + "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KTun1uSLuJ-A" + }, + "source": [ + "## Exercício 2\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Soq7GVZnuREq" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6KEsTARfvM1C" + }, + "source": [ + "## Exercício 3\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hgxE5gZ9vMEg" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K1', 'K0', 'K1'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K0', 'K0', 'K0'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iv7AmZ1ivm8R" + }, + "source": [ + "### Perguntas\n", + "* Qual o output e a interpretação dos comandos a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TWAW_1tuvvSO" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QjM7pBONvzCJ" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D1Rr3Ghsv2iS" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vXQwLjT-v3Iu" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EIdltTC-t_lF" + }, + "source": [ + "## Exercício 5\n", + "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bMwPLgWclWBq" + }, + "source": [ + "___\n", + "## Exercício 6 - Resolvido\n", + "* Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ej6WjQX90n1E" + }, + "source": [ + "### Identificação e tratamento dos Missing Values\n", + "* Em geral, deletamos variáveis com mais de 50% de Missing Values." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nuaM4JKNLeSI" + }, + "source": [ + "df4.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaYc-HXNJ1TQ" + }, + "source": [ + "pd.set_option('display.max_rows', 500)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5s71jcHIGch" + }, + "source": [ + "df_missing_values = pd.DataFrame(df4.isnull().sum())\n", + "df_missing_values['mv_percent'] = 100*df_missing_values[0]/df4.shape[0]\n", + "df_missing_values[0].sort_values(ascending= False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V7KUGAX6lilP" + }, + "source": [ + "import pandas as pd\n", + "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/MathMachado/Python4DS/DS_Python/Dataframes/Titanic_With_MV.csv?token =AGDJQ63MNPPPROFNSO2BZW25XSR72', index_col= 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m3UnAPJakCLR" + }, + "source": [ + "* Segue o dicionário de dados do dataframe Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_6RvRCXgwomw" + }, + "source": [ + "### Avaliando inconsistências nas COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PToomnfRxxI5" + }, + "source": [ + "import seaborn as sns\n", + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3nc_iuRR1Tju" + }, + "source": [ + "# Uniformizando o nome das COLUNAS\n", + "df_Titanic.columns= [cols.lower() for cols in df_Titanic.columns]\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G9jteCnAxdnK" + }, + "source": [ + "### Coluna 'pclass'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wUk0YNlxsgvf" + }, + "source": [ + "df_Titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9vPrB3AAx0Ym" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='pclass', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2n8s9Ad1m7od" + }, + "source": [ + "Não me parece nada estranho com a variável 'pclass'. Ou você identifica alguma coisa estranho?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m8EGM6gSxrzS" + }, + "source": [ + "### Coluna 'sex'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BRRgcLtinIRz" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8SQ8v2Wnspfb" + }, + "source": [ + "df_Titanic['sex'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wpp0iL0kyGTl" + }, + "source": [ + "Qual sua opinião sobre esse preenchimento?\n", + "\n", + "Algum problema?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jxx06kJFnNrP" + }, + "source": [ + "Oops... Aqui temos vários problemas... Olhando para estes resultados, você concorda que 'male', 'm', 'MALE', M', 'mALE' e 'Men' se trata da mesma informação?\n", + "\n", + "Da mesma forma, 'female', 'f', 'F', 'Female', 'fEMALE', 'Woman', 'w' e 'W' também se trata da mesma informação?\n", + "\n", + "Então, vamos fazer o seguinte:\n", + "\n", + "* Toda vez que eu encontrar um desses valores: ['m', 'MALE', 'M', 'mALE', 'Men'], vou substituir por 'male';\n", + "* Toda vez que eu encontrar um desses valores: ['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], vou substituit por 'female'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oQbEVi1t2tfR" + }, + "source": [ + "df_Titanic2= df_Titanic.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "apc-ccODyZ-d" + }, + "source": [ + "#### Corrigir com df.replace()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwoyLBK9oME5" + }, + "source": [ + "df_Titanic['sex2'] = df_Titanic['sex'].replace(['m', 'MALE', 'M', 'mALE', 'Men'], 'male')\n", + "df_Titanic['sex3'] = df_Titanic['sex2'].replace(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], 'female') " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RC35I-Njp4vh" + }, + "source": [ + "Vamos ver a distribuição dos dados novamente no gráfico:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1eGvEhA9qAN6" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex3', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IY3TaKUcszTQ" + }, + "source": [ + "df_Titanic['sex3'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2nOAcv3iqEaK" + }, + "source": [ + "Ok, de fato corrigimos os problemas de preenchimento da variável 'sex'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dqLqmrTWylY3" + }, + "source": [ + "#### Corrigir com df.map()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dRvuNo4E3Ewx" + }, + "source": [ + "df_Titanic= df_Titanic2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3X0_ZdwCyquk" + }, + "source": [ + "d_sexo= {}\n", + "d_sexo.update(dict.fromkeys(['m', 'MALE', 'M', 'mALE', 'Men', 'male'], 'male'))\n", + "d_sexo.update(dict.fromkeys(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W', 'female'], 'female'))\n", + "d_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ3lwKRKbsx0" + }, + "source": [ + "Aplica a transformação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "idBwRNI7bvCC" + }, + "source": [ + "df_Titanic['sex2'] = df_Titanic['sex'].map(d_sexo)\n", + "df_Titanic['sex2'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzDl78rfb3p5" + }, + "source": [ + "Qual a conclusão? Este preenchimento faz mais sentido que o anterior?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SvrZtKRpzIDc" + }, + "source": [ + "# Deleta as variáveis 'sex':\n", + "df_Titanic = df_Titanic.drop(columns = ['sex'], axis = 1).rename(columns= {'sex2': 'sex'})\n", + "\n", + "# Mostra os dados:\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6URC6h8xzfc5" + }, + "source": [ + "sns.catplot(x=\"sex\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "k_spkJbmqdRW" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgBNoXUNzoWZ" + }, + "source": [ + "### Feature Engineering\n", + "#### Coluna 'cabin'\n", + "* Construir as COLUNAS:\n", + " * deck - Letra de Cabin;\n", + " * seat - Número de Cabin" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fHsLrnut6mk" + }, + "source": [ + "Sugestões:\n", + "1) Não descartar nenhuma informação (Fábio);\n", + "\n", + "2) Coluna com número de cabines reservadas (Thomaz)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "p0NFFxx8z-vq" + }, + "source": [ + "set(df_Titanic['cabin'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7E6yje89u7KF" + }, + "source": [ + "Como podemos ver, trata-se de uma variável categórica com vários níveis. Portanto, vamos capturar somente a primeira letra da variável 'cabin'. Para tal, vamos utilizar a função slice().\n", + "\n", + "> str.slice() - Captura (slice) partes de s_Str." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wmZLlSaArR6F" + }, + "source": [ + "A seguir, capturamos a primeira letra da variável 'cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hUZTJU0MvVxP" + }, + "source": [ + "# definindo a variável 'deck' que representará a primeira letra da variável 'cabin'\n", + "df_Titanic[\"deck\"] = df_Titanic[\"cabin\"].str.slice(0, 1) # slice(inicio, tamanho_da_string)\n", + "df_Titanic['deck'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6myhrth0rZ6t" + }, + "source": [ + "A seguir, vamos extrair a parte numérica da variável 'cabin' usando Expressões Regulares:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8UXkACPmsfwN" + }, + "source": [ + "# Importar a biblioiteca para Expressões Regulares\n", + "import re" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QKk-fnW4rf4o" + }, + "source": [ + "# Primeiramente, usamos a função split() para separar o conteúdo da variável em COLUNAS: \n", + "new = df_Titanic[\"cabin\"].str.split(\" \", n = 3, expand = True) \n", + "new.head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dFqoR-Xew9gX" + }, + "source": [ + "Observe acima que o comando gera quantos splits da variável eu quiser. No entanto, por simplicidade, me interessa somente o primeiro split." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_M7vA6WoVG05" + }, + "source": [ + "Agora, vou extrair o número do assento do passageiro usando Expressões Regulares:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVH5o9KT_IH3" + }, + "source": [ + "# Aqui está o conteúdo de new[0]:\n", + "new[0].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "P7NTcsGOxxSX" + }, + "source": [ + "new2= new[0].str.extract('(\\d+)')\n", + "new2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf8vw2Mc18bQ" + }, + "source": [ + "Por fim, vou carregar esta informação ao dataframe df:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6l6EoRvsxRXn" + }, + "source": [ + "df_Titanic[\"seat\"] = new2\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LK4V61uy3N9s" + }, + "source": [ + "Por fim, excluir a variável 'cabin':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4uAr55J43NY7" + }, + "source": [ + "df_Titanic= df_Titanic.drop(columns= [\"cabin\"], axis =1, errors=\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qZuH7YJXZCgY" + }, + "source": [ + "### Coluna 'embarked'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nTPikhrIZGya" + }, + "source": [ + "df_Titanic['embarked'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ixbZsuqOZsOc" + }, + "source": [ + "sns.catplot(x=\"embarked\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvdU8aAwZNvG" + }, + "source": [ + "Não vejo problemas com esta variável. Vamos em frente..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k2SLRAhrub_B" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YRJcWaYkuxK4" + }, + "source": [ + "sns.countplot(x = 'pclass', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rzrOUULUu6-P" + }, + "source": [ + "sns.countplot(x = 'sex', hue ='embarked', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DfSMcYYZ5yLV" + }, + "source": [ + "### Variável 'pclass'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q2uU0k-G5yLN" + }, + "source": [ + "df_Titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Gue26Y3A5yLL" + }, + "source": [ + "Algum problema com esta variável?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "q3P82wPp5yK8" + }, + "source": [ + "sns.catplot(x=\"pclass\", kind=\"count\", data = df)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qrnc6VUKSTNp" + }, + "source": [ + "### Coluna 'parch'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i4ed-0zSvJc" + }, + "source": [ + "df_Titanic['parch'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qd7u__6KZ6DM" + }, + "source": [ + "sns.catplot(x=\"parch\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z9vM3vktC7BG" + }, + "source": [ + "### Feature Engineering\n", + "* Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nd4TyOYjs-HW" + }, + "source": [ + "# Função para retornar 0 ou 1 em função dos valores de variavel\n", + "def sozinho(variavel):\n", + " if (variavel == 0):\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5oByiBuos_B3" + }, + "source": [ + "df_Titanic['sozinho_parch'] = df_Titanic['parch'].map(sozinho)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C1ICby1oSd41" + }, + "source": [ + "### Coluna 'sibsp'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5n7JNEQqTNjz" + }, + "source": [ + "df_Titanic['sibsp'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NLfMhiy0x4u5" + }, + "source": [ + "* Algum problema?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nayYFRK9g8iV" + }, + "source": [ + "sns.catplot(x=\"sibsp\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KzCX2MTmE9Tw" + }, + "source": [ + "sns.countplot(x = 'survived', hue ='sibsp', data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_58rZqMaDzf-" + }, + "source": [ + "### Feature Engineering:\n", + "* Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HUrJ4IywrEoA" + }, + "source": [ + "df_Titanic['sozinho_sibsp'] = df_Titanic['sibsp'].map(sozinho)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0MO9jj2NvGp_" + }, + "source": [ + "### Coluna 'fare'\n", + "> Discretizar a coluna 'fare' em 10 buckets." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4-qO2Xk76Buz" + }, + "source": [ + "df_Titanic['fare_class'] = pd.qcut(df_Titanic['fare'], 10, labels=False)\n", + "df_Titanic['fare_class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "boAj64RHvQHu" + }, + "source": [ + "sns.catplot(x=\"fare_class\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3CIqHUJpvcPa" + }, + "source": [ + "### Coluna 'age'\n", + "> Discretizar a coluna 'age' em 10 buckets." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rCRnbKX57VN-" + }, + "source": [ + "df_Titanic['age_class'] = pd.qcut(df_Titanic['age'], 10, labels=False)\n", + "df_Titanic['age_class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uFsZLYDi7VOH" + }, + "source": [ + "sns.catplot(x=\"age_class\", kind=\"count\", data = df_Titanic)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DIY-sL337uje" + }, + "source": [ + "#### Alternativa para discretizar 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W66GkyuKkhFe" + }, + "source": [ + "def Age_Category(age):\n", + " if (age <= 1):\n", + " return 1\n", + " elif (age <= 5):\n", + " return 2\n", + " elif(age <= 10):\n", + " return 3\n", + " elif (age <= 15):\n", + " return 4\n", + " elif (age <= 20):\n", + " return 5\n", + " elif (age <= 25):\n", + " return 6\n", + " elif(age < 30):\n", + " return 7\n", + " elif(age < 35):\n", + " return 8\n", + " elif(age < 40):\n", + " return 9\n", + " elif(age < 45):\n", + " return 10\n", + " elif(age < 50):\n", + " return 11\n", + " elif(age < 60):\n", + " return 12\n", + " elif(age < 70):\n", + " return 13\n", + " elif(age < 80):\n", + " return 14\n", + " else:\n", + " return 15" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TnLzC6hCkuBL" + }, + "source": [ + "df_Titanic['age_class2'] = df['age'].map(Age_Category)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kG8td6HPsNlP" + }, + "source": [ + "set(df_Titanic['age_category']) # Esse comando mostra os NaN's da coluna, se houver." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B_3s5cgxfNKQ" + }, + "source": [ + "### Coluna 'title'\n", + "\n", + "* Para fins de Data Manipulation, vamos capturar o tratamento dos passageiros contido na variável 'nome'. Ou seja, 'Mr.', 'Mrs.', 'Miss' e etc...\n", + "\n", + "> Fonte: As funções get_title e title_map foram extraídas de https://www.kaggle.com/tjsauer/titanic-survival-python-solution" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gslSjRdDoJFY" + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XjqEVVnr8R4d" + }, + "source": [ + "Primeiramente, vamos entender como funciona, step by step..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D6gjWc3XozK7" + }, + "source": [ + "'Allen, Mr. William Henry'.split(',')[1].split('.')[0].strip()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nfIG6toGfhd5" + }, + "source": [ + "def get_title(nome):\n", + " if '.' in nome:\n", + " return nome.split(',')[1].split('.')[0].strip()\n", + " else:\n", + " return 'Unknown'\n", + "\n", + "def title_map(title):\n", + " if title in ['Mr', 'Ms']:\n", + " return 1\n", + " elif title in ['Master']:\n", + " return 2\n", + " elif title in ['Ms','Mlle','Miss']:\n", + " return 3\n", + " elif title in [\"Mme\", \"Ms\", \"Mrs\"]:\n", + " return 4\n", + " elif title in [\"Jonkheer\", \"Don\", \"Sir\", \"the Countess\", \"Dona\", \"Lady\"]:\n", + " return 5\n", + " elif title in [\"Capt\", \"Col\", \"Major\", \"Dr\", \"Rev\"]:\n", + " return 6\n", + " else:\n", + " return 7" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HLQoJwf0rjrf" + }, + "source": [ + "Exercícios\n", + "* Melhorar a função title_map." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7qNUwnCepe_x" + }, + "source": [ + "Captura o tratamento dos passageiros:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-Ltf33vgJ6Q" + }, + "source": [ + "df_Titanic['title'] = df_Titanic['nome'].apply(get_title).apply(title_map) \n", + "set(df_Titanic['title']) # Esse comando mostra os NaN's da variável" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D3hY0WVhpRYK" + }, + "source": [ + "Drop a coluna 'nome', pois não vamos mais precisar dela em nossas análises:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8i3xKCes5WF" + }, + "source": [ + "df_Titanic= df_Titanic.drop(columns= [\"nome\"], axis =1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Sl1uFdwpW3y" + }, + "source": [ + "Apresenta o conteúdo do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2uFnw-pZpan-" + }, + "source": [ + "df_Titanic.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0fZMKKpdHIl" + }, + "source": [ + "## Missing Value\n", + "> Faça o devido tratamento de NaN's das COLUNAS do dataframe df_Titanic.\n", + "\n", + "**Pergunta**: Na coluna 'value', os valores 0 (zero) são considerados Missing Values?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UHzKFytXsNkh" + }, + "source": [ + "df_Titanic['age'].isna().sum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZC1ULWd883t2" + }, + "source": [ + "## Relação causa --> efeito" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_WCbklv0bDlp" + }, + "source": [ + "A função a seguir nos ajudará com o Data Visualization, cruzando a variável-resposta 'survived' com qualquer outra passada à função:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "epxI-F2UbGGS" + }, + "source": [ + "def taxa_sobrevivencia(df, column):\n", + " title_xt = pd.crosstab(df[column], df['survived'])\n", + " print(pd.crosstab(df[column], df['survived'], margins=True))\n", + " title_xt_pct = title_xt.div(title_xt.sum(1).astype(float), axis =0)\n", + " \n", + " title_xt_pct.plot(kind='bar', stacked=True, title='Taxa de Sobrevivência dos Passageiros', \n", + " color= ['r', 'g'])\n", + " plt.xlabel(column)\n", + " plt.ylabel('Taxa de Sobrevivência')\n", + " plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),shadow=True, ncol=2)\n", + " plt.show()\n", + "\n", + "def grafico_catplot(x, y, hue = 'survived', col= None):\n", + " plt.rcdefaults()\n", + " g= sns.catplot(x= x, y= y, hue = hue, palette={'Died':'red','Survived':'blue'}, col= col, data = df, kind= 'bar', height=4, aspect=.7)\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "34-Qbd_QrC8W" + }, + "source": [ + "Qual a relação entre a variável 'sex' e a variável-resposta?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bhY8-UjyrC8Z" + }, + "source": [ + "taxa_sobrevivencia(df_Titanic, 'sex')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbexhGtayV4X" + }, + "source": [ + "## Exercício 7\n", + "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P62MXm3tK8Ty" + }, + "source": [ + "## Exercício 8\n", + "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Du7Y8E4uFmiu" + }, + "source": [ + "i_linhas_Titanic = df_Titanic.shape[0]\n", + "\n", + "df_Titanic['aleatorio'] = np.random.random(i_linhas_Titanic)\n", + "df_Titanic.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LMD3HksDL0PQ" + }, + "source": [ + "## Exercício 9\n", + "\n", + "1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);\n", + "2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n", + "3. Qual o dtype de cada variável/atributo do dataframe?\n", + "4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n", + "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;\n", + "6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n", + "7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição.\n", + "8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');\n", + "9. Qual a número de jogadores por idade?\n", + "10. Quantos jogadores possuem cada clube?\n", + "11. Qual a média de idade por clube?\n", + "12. Qual a média de salário por país?\n", + "13. Qual a média de salário por clube?\n", + "14. Qual a média de salário por idade?\n", + "15. Quanto cada clube gasta com pagamento de salários?\n", + "16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?\n", + "17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n", + "18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n", + "19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'.\n", + "20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed'=?\n", + "21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?\n", + "22. Quem são os outliers em termos de salário?\n", + "23. Quem são os outliers em termos de potência no chute?\n", + "24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?\n", + "25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "70Ml5KyZ04mk" + }, + "source": [ + "A seguir, significado da variável \"Position\":\n", + "* GK = Goalkeeper – Goleiro.\n", + "* RB = Right Back – Zagueiro Direito.\n", + "* CB = Central Back – Zagueiro Central.\n", + "* LB = Left Back – Zagueiro Esquerdo.\n", + "* SW = Sweeper – Líbero.\n", + "* RWB = Right Wing Back – Lateral Direito.\n", + "* LWB = Left Wing back – Lateral Esquerdo.\n", + "* CDM = Central Defensive Midfielder – Meio Campo Defensivo / Volante.\n", + "* CM = Central Midfielder – Meia Central.\n", + "* CAM = Center Attacking Middlefielder – Meio Campo Ofensivo / Armador.\n", + "* OM = Offensive Midfielder – Meia Ofensivo.\n", + "* LOM = Left Offensive Midfielder – Meia Esquerda Ofensivo.\n", + "* ROM = Right Offensive Midfielder – Meia Direita Ofensivo.\n", + "* LM = Left Midfielder – Meia Esquerda.\n", + "* RM = Right Midfielder – Meia Direita.\n", + "* LWM = Left Wing Midfielder – Meio Ala Esquerdo.\n", + "* RWM = Right Wing Midfielder – Meio Ala Direito.\n", + "* RW = Right Winger – Ala Direito.\n", + "* LW = Left Winger – Ala Esquerto.\n", + "* LF = Left Forward – Atacante Esquerdo.\n", + "* RF = Right Forward – Atacante Direito.\n", + "* ST = Striker – Atacante.\n", + "* CF = Center Forward – Centro Avante.\n", + "* RS = Right Striker – Atacante Direito.\n", + "* LS = Left Striker – Atacante Esquerdo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tjHDjj68zawa" + }, + "source": [ + "## 1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wzosi4Ue1vDs" + }, + "source": [ + "### Carregar as libraries necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B0fqR6rzMAa3" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vgoLTamaOC50" + }, + "source": [ + "#### Configurar ambiente" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RRwi_z8JOFrD" + }, + "source": [ + "d_configuracao = {\n", + " 'display.max_columns': 1000,\n", + " 'display.expand_frame_repr': True,\n", + " 'display.max_rows': 10,\n", + " 'display.precision': 2,\n", + " 'display.show_dimensions': True\n", + " }\n", + "\n", + "for op, value in d_configuracao.items():\n", + " pd.set_option(op, value)\n", + " print(op, value)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MdVljEbcMGU9" + }, + "source": [ + "#### Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GMivDUHEMFKp" + }, + "source": [ + "df = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA.csv?token=AGDJQ63GC7SPIHTGNW73QB27RXRN6') #, index_col= 'PassengerId')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7pDUpFVLTOfl" + }, + "source": [ + "#### Definir a coluna 'ID' como index do dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TEue20CbMp9U" + }, + "source": [ + "df.set_index('ID', inplace = True)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G8CDrpI1_wMd" + }, + "source": [ + "### Função para retirar os sinais de \"+\" ou \"-\" em algumas colunas/vriáveis:\n", + "* Percebeste algumas colunas com o sinal de \"+\" no nome?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7zqHkNCsEDpJ" + }, + "source": [ + "A seguir, exemplo de algumas colunas com este problema:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_hUvJbCqCBBl" + }, + "source": [ + "df[['RS', 'LS', 'ST']].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "78QhptWdEIB0" + }, + "source": [ + "A seguir, definimos um dataframe chamado df_string contendo a quantidade de colunas separadas pelo sinal \"+\". Observe que o máximo de colunas que obtemos são 2. Porque?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DzeSvQMGF4G7" + }, + "source": [ + "df_string = df['RS'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n", + "df_string.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PEzqRR5CEUru" + }, + "source": [ + "df_string[0] = pd.to_numeric(df_string[0])\n", + "df_string[1] = pd.to_numeric(df_string[1])\n", + "df_string['RS2'] = df_string[0]+df_string[1]\n", + "\n", + "df_string.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2t4rnjRWFPON" + }, + "source": [ + "df_string.dtypes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MAYju4f6GFzw" + }, + "source": [ + "df_string.drop(columns= [0, 1], axis = 1, inplace = True)\n", + "df = pd.merge(df, df_string, how = 'left', on = 'ID')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sm5lOGrrHoDp" + }, + "source": [ + " **Desafio**: Próximo passo: transformar isso numa função para tratar as demais variáveis!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QtmOlKNpzbOz" + }, + "source": [ + "## 2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7TzcuD2GxfBP" + }, + "source": [ + "### Colunas que poderiam previamente ser eliminadas:\n", + "* Photo\n", + "* Flag\n", + "* Club Logo\n", + "* Unnamed: 0" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kXDe_AdEx3DD" + }, + "source": [ + "df2 = df.copy()\n", + "\n", + "l_cols_drop = ['Unnamed: 0', 'Photo', 'Flag', 'Club Logo']\n", + "df2.drop(columns = l_cols_drop, axis = 1, inplace = True)\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m97dcDy9zbSO" + }, + "source": [ + "## 3. Qual o dtype de cada variável/atributo do dataframe?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GEbvITXR2U17" + }, + "source": [ + "# Função para nos mostrar o tipo das colunas:\n", + "def mostra_tipo(df):\n", + " d_tipos = dict(zip(df.columns, df.dtypes))\n", + " for item in d_tipos.items():\n", + " print(item)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3B9vxmbl9HNP" + }, + "source": [ + "mostra_tipo(df2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5XKcxC0Pzshm" + }, + "source": [ + "## 4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A7T31nFiPdDu" + }, + "source": [ + "### Mudar o tipo de algumas colunas\n", + "* Exemplo: 'Wage', 'Value' e 'Release Clause'. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VJSsvOpK71n7" + }, + "source": [ + "df4 = df2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xyV-_MY9688C" + }, + "source": [ + "def transforma_monetarias(coluna):\n", + " if 'M' in coluna:\n", + " return int(float(coluna.replace('M', '')) * 1000000)\n", + "\n", + " elif 'K' in coluna:\n", + " return int(float(coluna.replace('K', '')) * 1000)\n", + " \n", + " else:\n", + " return int(coluna) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AJ9-8sVS6MXj" + }, + "source": [ + "Substituindo o símbolo \"€\" por '':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ArgK2NVe6vqz" + }, + "source": [ + "l_colunas_monetarias = ['Value', 'Wage']\n", + "\n", + "for coluna in l_colunas_monetarias:\n", + " df4[coluna] = df4[coluna].str.replace('€', '')\n", + " df4[coluna] = df4[coluna].apply(lambda x: transforma_monetarias(x))\n", + "\n", + "df4.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c_lznTRHzbV9" + }, + "source": [ + "## 5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "usM674sR8Gv9" + }, + "source": [ + "df5 = df4.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N6LCmJ0QUsJo" + }, + "source": [ + "### Nome das colunas --> Substituir os \" \" por \"_\" nos nomes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NWJYqphfUxn1" + }, + "source": [ + "df5.columns = [c.replace(' ', '_') for c in df5.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lXUOzLWmVTNZ" + }, + "source": [ + "### Renomear as colunas usando lower()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZwwLMOYRVXnr" + }, + "source": [ + "df5.columns = [c.lower() for c in df5.columns]\n", + "mostra_tipo(df5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uc12gBThz1nD" + }, + "source": [ + "## 6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nYgvxvcT8QIT" + }, + "source": [ + "df6 = df5.copy()\n", + "df6.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9STC9fsWJAHn" + }, + "source": [ + "# Fazendo uma cópia permanente do dataframe df6 para uso futuro\n", + "df6[['overall', 'potential', 'value', 'wage', 'nationality', 'position', 'age', 'preferred_foot']].to_csv('FIFA_algumas_features.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ESFYFvOy8XOM" + }, + "source": [ + "Aqui vou substituir os Missing Values pela mediana. Fique à vontade para substituir por outras alternativas como min, max, média, limite superior de outliers e limite inferior para outliers." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "j7zDrRvi8iay" + }, + "source": [ + "l_colunas_numericas = df6.select_dtypes(np.number).columns.tolist()\n", + "l_colunas_numericas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mZEM0N2f9vi7" + }, + "source": [ + "# Mediana antes da substituição:\n", + "df6[l_colunas_numericas].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dzfw0kp69dK2" + }, + "source": [ + "# Substituição pela mediana\n", + "for coluna in l_colunas_numericas:\n", + " df6[coluna].fillna(df6[coluna].median())\n", + "\n", + "# Mediana depois da substituição:\n", + "df6[l_colunas_numericas].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jpQR9zDC-nEj" + }, + "source": [ + "Abaixo, identifiquei 252 registros com value = 0 --> Nestes casos, vou atribuir a mediana também." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s1Zj3gBJ-Z5c" + }, + "source": [ + "df6[df6['value'] == 0]['value'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HjuNw2u6-7i9" + }, + "source": [ + "# Mediana antes\n", + "df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VWEp0Tc_-vLD" + }, + "source": [ + "# Atribuição da mediana para os valores 0 de 'value'\n", + "df6.loc[df6['value'] == 0, 'value'] = df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HynCT_Yu_JL-" + }, + "source": [ + "# Mediana depois\n", + "df6['value'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B4O5kw6h_z3H" + }, + "source": [ + "E se tivéssemos substituído pela média, ao invés da mediana? Teria mudado alguma coisa?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eU7ybhA2zbZh" + }, + "source": [ + "## 7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A34BwvXrXAqU" + }, + "source": [ + "df7 = df6.copy()\n", + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fu87YSiudcM_" + }, + "source": [ + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IQQ7AvgBYZmx" + }, + "source": [ + "df_jogadores_por_paises = pd.DataFrame(df7.groupby(by=['nationality']).size())\n", + "df_jogadores_por_paises.columns = ['numero_jogadores']\n", + "df_jogadores_por_paises.sort_values(by = ['numero_jogadores'], ascending = False, inplace= True)\n", + "df_jogadores_por_paises = df_jogadores_por_paises.reset_index()\n", + "df_jogadores_por_paises\n", + "\n", + "# Numa única linha ficaria assim:\n", + "df_jogadores_por_paises2 = pd.DataFrame(df7.groupby(by=['nationality']).size(), columns= ['numero_jogadores']).sort_values(by = ['numero_jogadores'], ascending = False).reset_index()\n", + "df_jogadores_por_paises2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JfyDUEC2zbcv" + }, + "source": [ + "## 8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0a9MvyWPcu-C" + }, + "source": [ + "df_media_idade_por_paises = df7.groupby(by = ['nationality']).agg({'age': ['count', 'mean']}).reset_index()\n", + "df_media_idade_por_paises.columns = ['nationality', 'numero_joagadores', 'media_idade']\n", + "df_media_idade_por_paises.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n", + "df_media_idade_por_paises.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vNmu0xyg0CW4" + }, + "source": [ + "## 9. Qual a número de jogadores por idade?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DRVvPgpRf9vw" + }, + "source": [ + "df_jogadores_por_idade = df7.groupby(by = ['age']).agg({'age': ['count']}).reset_index()\n", + "df_jogadores_por_idade.columns = ['age', 'numero_joagadores']\n", + "df_jogadores_por_idade.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n", + "df_jogadores_por_idade.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8eChi2NW0CZp" + }, + "source": [ + "## 10. Quantos jogadores possuem cada clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JpNI3ZlHgUx1" + }, + "source": [ + "df_jogadores_por_clube = df7.groupby(by = ['club']).size().reset_index()\n", + "df_jogadores_por_clube.columns = ['clube', 'numero_joagadores']\n", + "df_jogadores_por_clube.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n", + "df_jogadores_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gMiibNwW0Cck" + }, + "source": [ + "## 11. Qual a média de idade por clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D9rF9frzgqSr" + }, + "source": [ + "df_media_idade_por_clube = df7.groupby(by = ['club']).agg({'age': ['count', 'mean']}).reset_index()\n", + "df_media_idade_por_clube.columns = ['clube', 'numero_joagadores', 'media_idade']\n", + "df_media_idade_por_clube.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n", + "df_media_idade_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uE_o76xH0QU-" + }, + "source": [ + "## 12. Qual a média de salário por país?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "keQXqnU7hJy4" + }, + "source": [ + "df_media_salario_por_pais = df7.groupby(by = ['nationality']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_pais.columns = ['nationality', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_pais.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_pais.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vqT1ozNA0Cfd" + }, + "source": [ + "## 13. Qual a média de salário por clube?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "54_Q2IGchmN-" + }, + "source": [ + "df_media_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_clube.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4eflozOo0Cif" + }, + "source": [ + "## 14. Qual a média de salário por idade?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Xtq9Am60hwGr" + }, + "source": [ + "df_media_salario_por_idade = df7.groupby(by = ['age']).agg({'wage': ['count', 'mean']}).reset_index()\n", + "df_media_salario_por_idade.columns = ['age', 'numero_joagadores', 'media_salario']\n", + "df_media_salario_por_idade.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n", + "df_media_salario_por_idade.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L0yRSSIb0WYj" + }, + "source": [ + "## 15. Quanto cada clube gasta com pagamento de salários?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C9N7_pLfh_uq" + }, + "source": [ + "df_soma_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean', 'sum']}).reset_index()\n", + "df_soma_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario', 'soma_salario']\n", + "df_soma_salario_por_clube.sort_values(by = ['soma_salario'], ascending = False, inplace = True)\n", + "df_soma_salario_por_clube.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1c7NGMg90YMi" + }, + "source": [ + "## 16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RAU41Iyaihvc" + }, + "source": [ + "df7.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bM_ePTWfiTFq" + }, + "source": [ + "df_potential_por_clube = df7.groupby(by = ['potential', 'club', 'nationality']).agg({'potential': ['count']}).reset_index()\n", + "df_potential_por_clube.columns = ['potential', 'club', 'nationality', 'numero_joagadores']\n", + "df_potential_por_clube.sort_values(by = ['potential'], ascending = False, inplace = True)\n", + "df_potential_por_clube.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HytWPvfvjTON" + }, + "source": [ + "#### Quem é o jogador com potential = 95?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Fk2X1q7LjWJE" + }, + "source": [ + "df7.loc[df7['potential'] == 95]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W2o4oLzujnHj" + }, + "source": [ + "#### Quem são os jogadores com potencial = 94?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GOCyMr-qjsL7" + }, + "source": [ + "df7.loc[df7['potential'] == 94]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LHDJimdw0ClU" + }, + "source": [ + "## 17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FXFp5nxrj9Yc" + }, + "source": [ + "df_overall = df7.groupby(by = ['overall', 'club', 'nationality']).agg({'overall': ['count']}).reset_index()\n", + "df_overall.columns = ['overall', 'club', 'nationality', 'numero_joagadores']\n", + "df_overall.sort_values(by = ['overall'], ascending = False, inplace = True)\n", + "df_overall.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LTooiIdk1XV" + }, + "source": [ + "#### Quem é o jogador com overall = 94?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QieAKyi7k5Bb" + }, + "source": [ + "df7.loc[df7['overall'] == 94]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JFH54d1D0b5B" + }, + "source": [ + "## 18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n", + "* Para responder esta questão, tirei a média de overall e potential." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JZ7PTFTle_d" + }, + "source": [ + "df18 = df7.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "s25u8RoplMZ8" + }, + "source": [ + "df18['overall_potential'] = ((df18['potential']+df18['overall'])/2)\n", + "df18[['name', 'overall', 'potential', 'overall_potential']].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8gJFzhhIlDCH" + }, + "source": [ + "df_overall_potential = df18.groupby(by = ['club', 'nationality', 'age']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential.columns = ['club', 'nationality', 'age', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "adpxQpWlmvac" + }, + "source": [ + "De forma geral:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fzn_81eomrj2" + }, + "source": [ + "df_overall_potential2 = df18.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential2.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential2.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential2.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dM8FehYC0df7" + }, + "source": [ + "## 19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_967BF6MnD4U" + }, + "source": [ + "df19 = df18.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wXPah5zOmkXc" + }, + "source": [ + "df_goleiros = df19[df19['position'] == 'GK']\n", + "df_goleiros.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "77ehyNmSnTIB" + }, + "source": [ + "df_overall_potential_goleiros = df_goleiros.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n", + "df_overall_potential_goleiros.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n", + "df_overall_potential_goleiros.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n", + "df_overall_potential_goleiros.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-dEtuBtF0fiZ" + }, + "source": [ + "## 20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed')?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KWMU1hMMnxTI" + }, + "source": [ + "df20 = df19.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sezEQIjqnwCZ" + }, + "source": [ + "df20.sort_values(by = 'sprintspeed', ascending = False).head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aEg0eaFO0lF6" + }, + "source": [ + "## 21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xXuj-dc7oA-0" + }, + "source": [ + "df21 = df20.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8HGT_dM2oEES" + }, + "source": [ + "df21.sort_values(by = 'shotpower', ascending = False).head(5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bRk42JIf0moZ" + }, + "source": [ + "## 22. Quem são os outliers em termos de salário?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qRNaog7y0qI4" + }, + "source": [ + "### Identificação e tratamento dos Outliers\n", + "* Qual o Overall médio do Barcelona, Juventus e Real Madrid?\n", + "* E qual o overall médio depois do tratamento dos outliers?\n", + "* Quem são os atletas que estão influenciando a média?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_bIxG1Sw9OUB" + }, + "source": [ + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)\n", + "\n", + "Fonte: [Understanding Boxplots](https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qEiikIxNoZkl" + }, + "source": [ + "df22 = df21.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lGYYvE0BoOoV" + }, + "source": [ + "q1_salario, q3_salario = df22['wage'].quantile([0.25,0.75]).to_list()\n", + "iqr_salario = q3_salario - q1_salario\n", + "print(q1_salario, q3_salario)\n", + "print(iqr_salario)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PB44VV9pogT1" + }, + "source": [ + "outlier_salario_inferior = q1_salario - 1.5 * iqr_salario\n", + "outlier_salario_superior = q3_salario + 1.5 * iqr_salario\n", + "\n", + "df_outliers_salario = df22[['name', 'club', 'nationality', 'wage', 'overall', 'potential']]\n", + "\n", + "# Salários outliers inferiores\n", + "df_outliers_salario[df_outliers_salario['wage'] < outlier_salario_inferior]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9867KNNBqG7Z" + }, + "source": [ + "# Top 10 Salários outliers superior\n", + "df_outliers_salario[df_outliers_salario['wage'] > outlier_salario_superior].sort_values(by = ['wage'], ascending = False).head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gT2zGwq90oQ5" + }, + "source": [ + "## 23. Quem são os outliers em termos de potência no chute?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "05uYj7cwqrdW" + }, + "source": [ + "df23 = df22.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GzbVRU9HqrdZ" + }, + "source": [ + "q1_chute, q3_chute = df23['shotpower'].quantile([0.25,0.75]).to_list()\n", + "iqr_chute = q3_chute - q1_chute\n", + "print(q1_chute, q3_chute)\n", + "print(iqr_chute)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V5TQX_yGqrda" + }, + "source": [ + "outlier_chute_inferior = q1_chute - 1.5 * iqr_chute\n", + "outlier_chute_superior = q3_chute + 1.5 * iqr_chute\n", + "\n", + "df_outliers_chute = df23[['name', 'club', 'nationality', 'shotpower', 'overall', 'potential']]\n", + "\n", + "# Salários outliers inferiores\n", + "df_outliers_chute[df_outliers_chute['shotpower'] < outlier_chute_inferior]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "URj1SYXxqrdc" + }, + "source": [ + "# Top 10 outliers superiores - shotpower\n", + "df_outliers_chute[df_outliers_chute['shotpower'] > outlier_chute_superior].sort_values(by = ['shotpower'], ascending = False).head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eHm1qeHx0pza" + }, + "source": [ + "## 24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OR6MD2GQ0rNq" + }, + "source": [ + "## 25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;" + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_01__Pandas_hs.ipynb b/Notebooks/NB10_01__Pandas_hs.ipynb new file mode 100644 index 000000000..9b3a57d2f --- /dev/null +++ b/Notebooks/NB10_01__Pandas_hs.ipynb @@ -0,0 +1,5202 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Copy of NB10_01__Pandas.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fpUiw8PwC7_" + }, + "source": [ + "

PANDAS PARA DATA ANALYSIS

\n", + "\n", + "\n", + "\n", + "# **AGENDA**:\n", + "\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vo7mtiNSr_Wk" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [Learn Aggregation and Data Wrangling with Python](https://data-flair.training/blogs/data-wrangling-with-python/)\n", + "* [Python Data Cleansing by Pandas & Numpy | Python Data Operations](https://data-flair.training/blogs/python-data-cleansing/)\n", + "* [Pandas from basic to advanced for Data Scientists](https://towardsdatascience.com/pandas-from-basic-to-advanced-for-data-scientists-aee4eed19cfe)\n", + "* [Feature engineering and ensembled models for the top 10 in Kaggle “Housing Prices Competition”](https://towardsdatascience.com/feature-engineering-and-ensembled-models-for-the-top-10-in-kaggle-housing-prices-competition-efb35828eef0)\n", + "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n", + "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n", + "* [Gaining a solid understanding of Pandas series](https://towardsdatascience.com/gaining-a-solid-understanding-of-pandas-series-893fb8f785aa)\n", + "* [ariáveis Dummy: o que é? Quando usar? E como usar?](https://medium.com/data-hackers/vari%C3%A1veis-dummy-o-que-%C3%A9-quando-usar-e-como-usar-78de66cfcca9)\n", + "* [Exploratory Data Analysis Made Easy Using Pandas Profiling](https://towardsdatascience.com/exploratory-data-analysis-made-easy-using-pandas-profiling-86e347ef5b65)\n", + "* [Data Handling using Pandas; Machine Learning in Real Life](https://towardsdatascience.com/data-handling-using-pandas-machine-learning-in-real-life-be76a697418c)\n", + "* [Exploratory Data Analysis Tutorial in Python](https://towardsdatascience.com/exploratory-data-analysis-tutorial-in-python-15602b417445)\n", + "* [Exploring the data using python](https://towardsdatascience.com/exploring-the-data-using-python-47c4bc7b8fa2)\n", + "* [A better EDA with Pandas-profiling](https://towardsdatascience.com/a-better-eda-with-pandas-profiling-e842a00e1136)\n", + "* [Exploratory Data Analysis: Haberman’s Cancer Survival Dataset](https://towardsdatascience.com/exploratory-data-analysis-habermans-cancer-survival-dataset-c511255d62cb)\n", + "* [Exploring Exploratory Data Analysis](https://towardsdatascience.com/exploring-exploratory-data-analysis-1aa72908a5df)\n", + "* [Getting started with Data Analysis with Python Pandas](https://towardsdatascience.com/getting-started-to-data-analysis-with-python-pandas-with-titanic-dataset-a195ab043c77)\n", + "* [A Gentle Introduction to Exploratory Data Analysis](https://towardsdatascience.com/a-gentle-introduction-to-exploratory-data-analysis-f11d843b8184)\n", + "* [Exploratory Data Analysis (EDA) techniques for Kaggle competition beginners](https://towardsdatascience.com/exploratory-data-analysis-eda-techniques-for-kaggle-competition-beginners-be4237c3c3a9)\n", + "* [What is Exploratory Data Analysis?](https://towardsdatascience.com/exploratory-data-analysis-8fc1cb20fd15)\n", + "* [Exploring real estate investment opportunity in Boston and Seattle](https://towardsdatascience.com/exploring-real-estate-investment-opportunity-in-boston-and-seattle-9d89d0c9bed2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BUEbp88oD1Km" + }, + "source": [ + "___\n", + "# **ANÁLISE DE DADOS COM PANDAS**\n", + "## Highlights\n", + "\n", + "* Rápida e eficiente library para data manipulation;\n", + "* Ferramentas para ler e gravar todos os tipos de dados e formatos: CSV, txt, Microsoft Excel, SQL databases, JSON e HDF5 format;\n", + "* Pandas é a library mais popular para análise de dados. As principais ações que faremos com Pandas são:\n", + " * Ler/gravar diferentes formatos de dados;\n", + " * Selecionar subconjuntos de dados;\n", + " * Cálculos variados por coluna ou por linha das tabelas;\n", + " * Encontrar e tratar Missing Values;\n", + " * Combinar múltiplos dataframes;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wkxQFPPmeKLl" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eKawOG-neqaD" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas2.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TLdSmsJZwlcQ" + }, + "source": [ + "___\n", + "# **ATÉ QUE VOLUME DE DADOS PODEMOS USAR PANDAS?**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O7YKF5gB2x0K" + }, + "source": [ + "![RightToolForEachSize](https://github.com/MathMachado/Materials/blob/master/SizesAndTools.PNG?raw=true)\n", + "\n", + "## Sources\n", + "### Dask\n", + "* [Pandas, Dask or PySpark? What Should You Choose for Your Dataset?](https://medium.com/datadriveninvestor/pandas-dask-or-pyspark-what-should-you-choose-for-your-dataset-c0f67e1b1d36)\n", + "* [Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165)\n", + "* [Pandas, Fast and Slow](https://medium.com/when-i-work-data/pandas-fast-and-slow-b6d8dde6862e)\n", + "* [Por que Parquet](https://medium.com/when-i-work-data/por-que-parquet-2a3ec42141c6)\n", + "* [How to Run Parallel Data Analysis in Python using Dask Dataframes](https://towardsdatascience.com/trying-out-dask-dataframes-in-python-for-fast-data-analysis-in-parallel-aa960c18a915)\n", + "* [Why every Data Scientist should use Dask?](https://towardsdatascience.com/why-every-data-scientist-should-use-dask-81b2b850e15b)\n", + "\n", + "### Spark, Koalas\n", + "* [Databricks Koalas-Python Pandas for Spark](https://medium.com/future-vision/databricks-koalas-python-pandas-for-spark-ce20fc8a7d08)\n", + "* [Bye Pandas, Meet Koalas: Pandas APIs on Apache Spark (Ep. 4)](https://medium.com/@kyleake/bye-pandas-meet-koalas-pandas-apis-on-apache-spark-ep-4-aedcd363cf4e)\n", + "* [Koalas: Easy Transition from pandas to Apache Spark](https://databricks.com/blog/2019/04/24/koalas-easy-transition-from-pandas-to-apache-spark.html?source=post_page-----aedcd363cf4e----------------------)\n", + "* [Use PySpark for Your Next Big Problem](https://medium.com/swlh/use-pyspark-for-your-next-big-problem-8aa288d5ecfa)\n", + "* [A Neanderthal’s Guide to Apache Spark in Python](https://towardsdatascience.com/a-neanderthals-guide-to-apache-spark-in-python-9ef1f156d427)\n", + "* [The Jungle of Koalas, Pandas, Optimus and Spark](https://towardsdatascience.com/the-jungle-of-koalas-pandas-optimus-and-spark-dd486f873aa4)\n", + "* [From Pandas to PySpark with Koalas](https://towardsdatascience.com/from-pandas-to-pyspark-with-koalas-e40f293be7c8)\n", + "\n", + "# O que Dask?\n", + "\n", + "\"Dask is designed to extend the numpy and pandas packages to work on data processing problems that are too large to be kept in memory. It breaks the larger processing job into many smaller tasks that are handled by numpy or pandas and then it reassembles the results into a coherent whole.\" - Eric Ness ([Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yEyzjGUfG33-" + }, + "source": [ + "___\n", + "# **Carregar a library Pandas e verificar a versão**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oVMjT3DrG97K" + }, + "source": [ + "# Carrega a library Pandas\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "print(f'Versão do Pandas: {pd.__version__}')\n", + "print(f'Versão do NumPy.: {np.__version__}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OxoDsaKUVHdH" + }, + "source": [ + "# Configurações\n", + "> Podemos configurar o pandas de forma a tornar nosso trabalho mais produtivo. Podemos configurar, por exemplo, o número de LINHAS e COLUNAS a ser mostrado, precisão dos números float. Vamos ver com mais detalhes a seguir.\n", + "\n", + "Fonte: [5 Advanced Features of Pandas and How to Use Them](https://www.kdnuggets.com/2019/10/5-advanced-features-pandas.html)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOdqrf7uVlhC" + }, + "source": [ + "d_configuracao = {\n", + " 'display.max_columns': 1000,\n", + " 'display.expand_frame_repr': True,\n", + " 'display.max_rows': 10,\n", + " 'display.precision': 2,\n", + " 'display.show_dimensions': True\n", + " }\n", + "\n", + "for op, value in d_configuracao.items():\n", + " pd.set_option(op, value)\n", + " print(op, value)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Paz-R-FOAJ7F" + }, + "source": [ + "___\n", + "# **Criar um dataframe a partir de outros objetos**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L4Jc0C2qPAQz" + }, + "source": [ + "## Criar dataframe a partir de dicionários" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Sa5rKwq6Fscj" + }, + "source": [ + "### Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0ofIGkiSSuYq" + }, + "source": [ + "d_frutas = {'Apple': [5, 6, 6, 8, 10, 3, 2],\n", + " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iJCNvPlUTzTI" + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7Y_0O_tJTfm3" + }, + "source": [ + "# index=['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'] abaixo define os label.\n", + "df_frutas = pd.DataFrame(d_frutas, index = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'])\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l2ll8ktfUKz2" + }, + "source": [ + "O que se comprou na sexta?\n", + "\n", + "* Função df.loc[label] retorna o(s) valor(es) associados à label. Em nosso caso, os label (chaves do dicionário) são 'Seg', 'Ter', ..., 'Dom'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9Voor8_PUJum" + }, + "source": [ + "df_frutas.loc['Sex'] # Aqui, label= 'Sex'." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LMh4DTfebwAr" + }, + "source": [ + "* Ou seja, o label = 'Sex', que ocupa a posição 4, tem os valores:\n", + " * Apple..: 10\n", + " * Avocado: 3\n", + "\n", + "Da mesma forma, poderíamos utilizar a função df.iloc[index] para retornar o conteúdo/informações de index." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GJxawdh6bvJN" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "obJt9OPGcL-x" + }, + "source": [ + "Portanto, df.loc['Sex'] = df.iloc[4]. Correto?\n", + "\n", + "Para nos ajudar a memorizar, considere que:\n", + "\n", + "* pd.loc[label] --> loc começa com a letra **l**, o que remete à label da linha.\n", + "* pd.iloc[indice] --> iloc começa com a letra **i**, o que remete ao índice (inteiro) da linha." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v7QlCcEorEIX" + }, + "source": [ + "#### Qual é o output do code abaixo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kRRdQShrrKHk" + }, + "source": [ + "df_frutas.loc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EkjAtbrRF01h" + }, + "source": [ + "### Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2EOX5MC4E1xL" + }, + "source": [ + "Na prática, lidamos com grandes bancos de dados e, nesses casos, não temos label das LINHAS definidos. Para exemplificar, considere o mesmo exemplo que acabamos de ver, com uma pequena alteração:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RC_OXmdjrkQm" + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D6FckgDPFFs0" + }, + "source": [ + "df_frutas = pd.DataFrame(d_frutas) # Observe que aqui não definimos os indíces\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tkGc4JQcFPkp" + }, + "source": [ + "Veja agora que os label são números inteiros de 0 a N." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ri-EdUYAovLG" + }, + "source": [ + "#### Qual o conteúdo da linha cujo label é 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5YgWG_vlFVe_" + }, + "source": [ + "df_frutas.loc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFQxcAcVo2KD" + }, + "source": [ + "#### Qual o conteúdo da linha cujo índice é 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xB1j4n6HFank" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEbCke3TFf_q" + }, + "source": [ + "Ou seja, nesses casos, tanto faz usar pd.loc[] ou pd.iloc[]. Entendeu?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bKHw_VBKjkoL" + }, + "source": [ + "### Exemplo 3 - Definir os indices do dataframe usando df.set_index()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "13ArWIhYju6s" + }, + "source": [ + "d_frutas= {'Dia_Semana': ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'],\n", + " 'Apple': [5, 6, 6, 8, 10, 3, 2],\n", + " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}\n", + "\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Evw9w16gk5h0" + }, + "source": [ + "# Cria o dataframe df_frutas:\n", + "df_frutas = pd.DataFrame(d_frutas) # Não apontamos o índice do dataframe. Portanto, o índice é criado automaticamente de 0.. N.\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NLbbRrdYoclw" + }, + "source": [ + "#### Qual o conteúdo da linha 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lB-ngbutl_0c" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1aJLGapZlUFI" + }, + "source": [ + "# Definir 'Dia_Semana' como índice (label das linhas) do dataframe df_frutas\n", + "df_frutas.set_index('Dia_Semana', inplace = True)\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L1-U_sD-jAoO" + }, + "source": [ + "A expressão acima é equivalente a:\n", + "\n", + "```\n", + "df_frutas2 = df_frutas.set_index('Dia_Semana') # Observe que aqui não há 'inplace'\n", + "df_frutas2\n", + "```\n", + "\n", + "* Então, qual a função do 'inplace =True' na primeira opção?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oXeFjJonpQfB" + }, + "source": [ + "#### Qual o conteúdo da linha 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MMXg3vVQpUhh" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fhoYuGMlpVFj" + }, + "source": [ + "#### Qual o conteúdo da linha cujo label é 'Sex'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fmcWbrEspdYW" + }, + "source": [ + "df_frutas.loc['Sex']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bobggpoCTRkj" + }, + "source": [ + "### Qual a diferença entre as duas próximas linhas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SjiYgbNrsvpl" + }, + "source": [ + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OFhzE7hgTD0a" + }, + "source": [ + "df_frutas.mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V42I3807TNte" + }, + "source": [ + "df_frutas.mean(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6iUCthsbtLV8" + }, + "source": [ + "df_frutas.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YdkmYePYtcON" + }, + "source": [ + "df_frutas.dtypes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2RmgCIC2HZFp" + }, + "source": [ + "### Exemplo 4" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kbHHuMzzAR1A" + }, + "source": [ + "d_estudantes = {'Nome': ['Jack', 'Richard', 'Tommy', 'Ana'], \n", + " 'Age': [25, 34, 18, 21],\n", + " 'City': ['Sydney', 'Rio de Janeiro', 'Lisbon', 'New York'],\n", + " 'Country': ['Australia', 'Brazil', 'Portugal', 'United States']}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayKqLmHTANOu" + }, + "source": [ + "# Mostrar o conteúdo do dicionário d_estudantes...\n", + "d_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0ONA8QsBBP6R" + }, + "source": [ + "# Keys associadas ao dicionário d_estudantes\n", + "d_estudantes.keys()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "k8mmvKQ_BjO6" + }, + "source": [ + "# Itens associados ao dicionário d_estudantes\n", + "d_estudantes.items()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcm8V_UmBr1Y" + }, + "source": [ + "# Valores associados ao dicionário d_estudantes\n", + "d_estudantes.values()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KK7IejsPDkWC" + }, + "source": [ + "Temos uma key = 'nome'. Qual o conteúdo desta key?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eHvPpeiTBwoR" + }, + "source": [ + "d_estudantes['nome']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "S1y7p8CcDsXl" + }, + "source": [ + "Qual o output da expressão a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "26WIDl-HB3Bq" + }, + "source": [ + "d_estudantes['nome'][0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gV68kQ5HCIif" + }, + "source": [ + "Criando o dataframe df_estudantes a partir do dicionário d_estudantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2oa808hkCSaq" + }, + "source": [ + "df_estudantes = pd.DataFrame(d_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7HLp0FYpCiSc" + }, + "source": [ + "# Mostra o conteúdo do dataframe df_estudantes...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "en06lfazciE0" + }, + "source": [ + "**Atenção**: Observe que nesse caso, não definimos labels para as LINHAS. Na prática, isso é o mais comum, ou seja, os label = index, que aqui são números inteiros de 0 a N." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gFaPp-S-cy1-" + }, + "source": [ + "Mais uma vez, vamos usar df.loc[] e df.iloc[]..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mT9vwRBidGXX" + }, + "source": [ + "# Mostrando o conteúdo de da linha 3 usando df.loc[]\n", + "df_estudantes.loc[3]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zj88AwHUdix0" + }, + "source": [ + "OU" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SP2mG8todkMe" + }, + "source": [ + "# Mostrando o conteúdo de da linha 3 usando df.iloc[]\n", + "df_estudantes.iloc[3]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hzbLO0EDGWTf" + }, + "source": [ + "Ok, já discutimos isso anteriormente. Quando não temos labels para as LINHAS, então iloc[] = loc[]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvzVg7SpeOOB" + }, + "source": [ + "___\n", + "## Criar dataframes a partir de listas\n", + "* Considere a lista de frutas a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_PY9OROeUiT" + }, + "source": [ + "l_frutas = [('Melon', 6, 8, 5, 4 ,6, 2, 8), ('Avocado', 6, 6, 3, 8, 9, 3, 1), ('Blueberry', 7, 5, 9, 3, 1, 0, 4)]\n", + "l_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AfE_rHq5g4_P" + }, + "source": [ + "type(l_frutas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZpdPSi7RgVjK" + }, + "source": [ + "l_frutas[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NMyIpVW8gZTH" + }, + "source": [ + "l_frutas[0][0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-cyZVqQFhjjg" + }, + "source": [ + "# Lista contendo os nomes das COLUNAS do dataframe:\n", + "l_colunas = ['Frutas', 'Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']\n", + "l_colunas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wplKvgayfZm_" + }, + "source": [ + "# Convertendo as listas em dataframe\n", + "df_frutas = pd.DataFrame(l_frutas, columns = l_colunas) # Observe que aqui, o nome das COLUNAS é uma lista.\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GojgsAXTFZmB" + }, + "source": [ + "___\n", + "# **Copiar dataframes**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_Tda4ZwjWIW" + }, + "source": [ + "O dataframe df_estudantes tem o seguinte conteúdo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P5y0aVkdkA8o" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cp3bvPEqj5fS" + }, + "source": [ + "se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2PT5L11j8O0" + }, + "source": [ + "df_estudantes2 = df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2D29pGuikBBK" + }, + "source": [ + "então df_estudantes2 tem o mesmo conteúdo de df_estudantes, ok?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_IseZEpLkGS4" + }, + "source": [ + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "29MpozLrkI83" + }, + "source": [ + "Agora altere o valor 'Rio de Janeiro' para 'Sao Paulo' no dataframe df_estudantes2." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TXCqFiGFkmyv" + }, + "source": [ + "df_estudantes2['city'] = df_estudantes2['city'].replace({'Rio de Janeiro': 'Sao Paulo'})\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_0mgT7-8Fsl" + }, + "source": [ + "# OU\n", + "alteracoes = {'Rio de Janeiro': 'Sao Paulo'}\n", + "df_estudantes2['city'] = df_estudantes2['city'].replace(alteracoes)\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN8ZGu2Xk6vt" + }, + "source": [ + "Ok, alteramos o valor 'Rio de Janeiro' por 'Sao Paulo', como queríamos. Vamos ver o conteúdo de df_estudantes (**que está intacto, pois fizemos a alteração no dataframe df_estudantes2**)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "thNAWoDflRoQ" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VkIS8wVmlAyq" + }, + "source": [ + "Ooooops... df_estudantes foi alterado? Como, se procedemos a alteração em df_estudantes2 e NÃO em df_estudantes???\n", + "\n", + "* **As operações que fizermos em df_estudantes2 também serão aplicadas à df_estudantes**?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e9u-Z9NMltC9" + }, + "source": [ + "**Resposta**: SIM, pois df_estudantes2 é um ponteiro para df_estudantes. Ou seja, **qualquer operação que fizermos em df_estudantes2 será feita em df_estudantes**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IDwvsxhhmlE4" + }, + "source": [ + "Uma forma fácil de ver isso é através dos endereços de memória dos dois (**supostos diferentes**) dataframes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ePFwKua8mu7k" + }, + "source": [ + "id(df_estudantes2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bMvY_E0mmwQH" + }, + "source": [ + "id(df_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K5qC5BuzmyF0" + }, + "source": [ + "**Conclusão**: df_estudantes2 é ponteiro para df_estudantes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZZ50ejRImAQ8" + }, + "source": [ + "## Forma correta de fazer a cópia de um dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oTbzxNkDmQiJ" + }, + "source": [ + "Primeiramente, vamos reconstruir df_estudantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DmVq0vM0mTtQ" + }, + "source": [ + "df_estudantes = pd.DataFrame(d_estudantes)\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oZrlwtqJmYB_" + }, + "source": [ + "Fazendo a cópia do dataframe (**da forma correta**):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "No5A7nHDFbsy" + }, + "source": [ + "df_estudantes_Copy = df_estudantes.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NvKNFr8RnEft" + }, + "source": [ + "Vamos verificar os endereços de memória dos dois dataframes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_OO90SFki4f" + }, + "source": [ + "id(df_estudantes_Copy)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T0BibX8rkes5" + }, + "source": [ + "id(df_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbm-8cCUFgJa" + }, + "source": [ + "Agora, dataframe df_estudantes_Copy é uma cópia do dataframe df_estudantes" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SuL8WUxL-u6-" + }, + "source": [ + "___\n", + "# **Renomear COLUNAS do dataframe**\n", + "> **Snippet**: \n", + "\n", + " * df.rename(columns = {'Old_Name': 'New_Name'}, inplace = True)\n", + " * OU df = df.rename(columns = {'Old_Name': 'New_Name'})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IvpCfmQnIZKl" + }, + "source": [ + "Suponha que quero renamear a COLUNA 'nome' para 'nome_cliente', que é um nome mais sugestivo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o54Fa-yxnmuz" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FwzXjYJgCvGk" + }, + "source": [ + "df_estudantes= df_estudantes.rename(columns = {'nome': 'nome_cliente'})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gOolGiWt4A18" + }, + "source": [ + "O comando abaixo produz o mesmo resultado que a linha anterior:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y6jjAFRd341e" + }, + "source": [ + "```\n", + "df_estudantes.rename(columns= {'nome': 'nome_cliente'}, inplace = True)\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DwVMldKiF5gS" + }, + "source": [ + "# Mostrando o conteúdo de df_estudantes após renamearmos a coluna/variável 'nome' para 'Clien_Name'...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m-WZBLWqELOv" + }, + "source": [ + "Agora, suponha que queremos renamear 'age' para 'idade_cliente', 'city' para 'cidade_cliente' e 'country' para 'pais_cliente'..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS6ua4u1EX5g" + }, + "source": [ + "df_estudantes.rename(columns = {'age': 'idade_cliente', 'city': 'cidade_cliente', 'country': 'pais_cliente'}, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i_7LW07y4SvO" + }, + "source": [ + "O comando abaixo produz o mesmo resultado que a linha anterior:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9X-cv9RL4WjV" + }, + "source": [ + "```\n", + "df_estudante = df_estudantes.rename(columns= {'Age': 'idade_cliente', 'City': 'cidade_cliente', 'Country': 'pais_cliente'}, inplace = True)\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EOb1-TEKGM9I" + }, + "source": [ + "# Mostrando o conteúdo de df_estudantes após a múltipla operação de renamear...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q0IZZjLRJlU6" + }, + "source": [ + "Alguma dúvida até aqui?\n", + "Tudo bem até aqui?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5LwL2m5KbLYz" + }, + "source": [ + "## Challenge\n", + "* Aplicar lowercase() em todas as COLUNAS do dataframe df_estudantes. Como fazer isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MURfzmeLbUzF" + }, + "source": [ + "### Minha solução:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-FgBY-3xBi9" + }, + "source": [ + "df_estudantes2 = df_estudantes.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hlSlfcoub8gH" + }, + "source": [ + "# Colocar o nome das COLUNAS numa lista:\n", + "l_colunas = df_estudantes2.columns\n", + "l_colunas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_IGvEK4bdQP" + }, + "source": [ + "# Lowercase todas as COLUNAS\n", + "df_estudantes2.columns = [col.lower() for col in l_colunas]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0qzzAa3ycKmF" + }, + "source": [ + "# Mostrando o conteúdo do dataframe df_estudantes\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c-u-ndMPV_KX" + }, + "source": [ + "___\n", + "# **Adicionar/Acrescentar novas LINHAS ao dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MDkWbukBLhw7" + }, + "source": [ + "## Usando dicionários\n", + "* É necessário informar {'Column_Name': value} para cada inserção. Por exemplo, vou adicionar o seguinte registro ao dataframe:\n", + " * nome_cliente= 'Anderson';\n", + " * idade_cliente= 22;\n", + " * cidade_cliente= 'Porto';\n", + " * pais_cliente= 'Portugal'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GECPO7iyK9UU" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XQKqqC93LoQ_" + }, + "source": [ + "df_estudantes_Copia= df_estudantes.copy()\n", + "df_estudantes.append({'nome_cliente': 'Anderson', \n", + " 'idade_cliente': 22,\n", + " 'cidade_cliente': 'Porto',\n", + " 'pais_cliente': 'Portugal'}, ignore_index = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bdBttsHNLjd-" + }, + "source": [ + "Esse é o resultado que desejamos?\n", + "Saberia explicar-nos o que houve de errado?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6jDoq6CCMerp" + }, + "source": [ + "**DICA**: Lembre-se que no passo anterior, reescrevemos os nomes das COLUNAS usando o método lower()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ffReAaUHLvEF" + }, + "source": [ + "# Definindo df_estudantes novamente usando a cópia df_estudantes_Copia\n", + "df_estudantes = df_estudantes_Copia.copy()\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EzTo-IvmM2Fg" + }, + "source": [ + "Ok, restabelecemos a cópia de df_estudantes. Agora vamos à forma correta:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRhE76i4M6d6" + }, + "source": [ + "df_estudantes = df_estudantes.append({'nome_cliente': 'Anderson', \n", + " 'idade_cliente': 22,\n", + " 'cidade_cliente': 'Porto',\n", + " 'pais_cliente': 'Portugal'}, ignore_index= True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jAojB2MMNDRJ" + }, + "source": [ + "Bom, esse é o resultado que estávamos à espera..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5czZb-5wNp_F" + }, + "source": [ + "## Usando Series\n", + "* Como exemplo, considere que queremos adicionar os seguintes dados:\n", + " * nome_cliente= 'Bill';\n", + " * idade_cliente= 30;\n", + " * cidade_cliente= 'São Paulo';\n", + " * pais_cliente= 'Brazil'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3qCydqMNtGt" + }, + "source": [ + "novo_estudante = pd.Series(['Bill', 30, 'Sao Paulo', 'Brazil'], index= df_estudantes2.columns) # Olha que interessante: estamos a usar index= df_estudantes.columns." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_DyMDrNPrmC" + }, + "source": [ + "Vamos ver o conteúdo de novo_estudante:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jDQUl0RBPoLB" + }, + "source": [ + "novo_estudante" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zMKRNQrsPvxp" + }, + "source": [ + "Por fim, adiciona/acrescenta novo_estudante ao dataframe df_estudantes..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5mEQg26iPw4A" + }, + "source": [ + "df_estudantes2 = df_estudantes2.append(novo_estudante, ignore_index= True)\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Biwk2McAWW1Z" + }, + "source": [ + "___\n", + "# **Adicionar/acrescentar novas COLUNAS ao Dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EZFTH7A-Wpw5" + }, + "source": [ + "## Usando Lists\n", + "* Suponha que queremos adicionar a coluna/variável 'Score'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YzBKQo5epXP5" + }, + "source": [ + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pPoObAKJW6YF" + }, + "source": [ + "# Acrescentando ou criando a coluna/variável 'score' ao dataframe usando um objeto list\n", + "df_estudantes2['score'] = [500, 300, 200, 800, 700, 100]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ocbh8sZqWsoW" + }, + "source": [ + "# Mostra o conteúdo do dataframe df_estudantes...\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZxfCMcVxYQgL" + }, + "source": [ + "> **Atenção**:\n", + "\n", + "* Se a quantidade de valores da lista forem menores que o número de LINHAS do dataframe, então o Python apresenta um erro.\n", + "* Se a coluna/variável que queremos inserir já existe no dataframe, então os valores serão atualizados com os novos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "34ntllD_YbNa" + }, + "source": [ + "## Usando um valor default\n", + "* Adicionar a coluna 'total' com o mesmo valor para todas as LINHAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T7QSMJMQYous" + }, + "source": [ + "df_estudantes['total'] = 500\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gll-gJt7as3C" + }, + "source": [ + "## Adicionar uma COLUNA calculada a partir de outras COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T_pB_isBaw-E" + }, + "source": [ + "df_estudantes['percentagem'] = 100*(df_estudantes['score']/sum(df_estudantes['score']))\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D9TNylt84hle" + }, + "source": [ + "___\n", + "# **Ler/carregar dados no Python**\n", + "* Vários formatos de arquivos podem ser lidos:\n", + "\n", + "|Format Type | Data Description | Reader | Writer |\n", + "|---|---|---|---|\n", + "text | CSV | read_csv | to_csv |\n", + "text | JSON | read_json | to_json |\n", + "text | HTML | read_html | to_html |\n", + "text | Local clipboard | read_clipboard | to_clipboard |\n", + "binary | MS Excel | read_excel | to_excel |\n", + "binary | HDF5 Format | read_hdf | to_hdf |\n", + "binary | Stata | read_stata | to_stata |\n", + "binary | SAS | read_sas \n", + "binary | Python Pickle Format | read_pickle | to_pickle |\n", + "SQL | SQL | read_sql | to_sql |\n", + "SQL | Google Big Query | read_gbq | to_gbq |\n", + "\n", + "* Fonte: [IO tools (text, CSV, HDF5, …)](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ss8jLEUSblDm" + }, + "source": [ + "___\n", + "# **Ler/Carregar csv**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n8e9aphab_oe" + }, + "source": [ + "# carregar a library Pandas\n", + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R2fRd_MSQ2Xa" + }, + "source": [ + "A seguir, vamos:\n", + "* Ler o dataframe Titanic.csv;\n", + "* Definir 'PassengerId' como índice/chave da tabela através do comando index_col= 'PassengerId'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1R9YoFJ02TR7" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_With_MV.csv?token=AGDJQ67OZ36XJUJPE77Z7LC7RBCAU'\n", + "df_Titanic = pd.read_csv(url, index_col = 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS7_V15u0MgR" + }, + "source": [ + "df_Titanic.iloc[4] # NÃO É A MESMA COISA QUE df_Titanic.loc[4]!!!" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WJ9RlRDSkk0_" + }, + "source": [ + "* Segue o dicionário de dados do dataframe df_Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wz7Qd9mqMrfY" + }, + "source": [ + "# Show o dataframe df_Titanic:\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nDlANdnm4iod" + }, + "source": [ + "### DICA 1\n", + "Suponha que o dataframe que queremos ler esteja localizado em:\n", + "\n", + "```\n", + "/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes\n", + "```\n", + "\n", + "Desta forma, para ler o dataframe (local), basta usar o comando a seguir:\n", + "\n", + "```\n", + "url = '/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes/creditcard.csv'\n", + "df_Titanic = pd.read_csv(url)\n", + "```\n", + "\n", + "### Dica 2\n", + "No Windows, o diretório aparece, por exemplo, da seguinte forma: \n", + "```\n", + "C:\\nsolucoes4ds\\Data_Science\n", + "```\n", + "Observe as '\\\\' (**barras invertidas**). Neste caso, use o comando a seguir:\n", + "\n", + "```\n", + "url= r'C:\\nsolucoes4ds\\Data_Science\\creditcard.csv'\n", + "df_Titanic = pd.read_csv(url)\n", + "```\n", + "\n", + "Percebeu o r'diretorio'?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HubfewY8NgUv" + }, + "source": [ + "___\n", + "# **Corrigir (ou uniformizar) nome das COLUNAS**\n", + "* Por exemplo, reescrever o nome das COLUNAS usando lowercase()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4f_pEEOjvwjk" + }, + "source": [ + "Para facilitar nossas análises, vamos aplicar o método lower() em todos os valores das COLUNAS objects/strings. Para isso, considere a função abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ft13IahH1kVX" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-UlaHFPv7kp" + }, + "source": [ + "def transformacao_lower(df):\n", + " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n", + " df.columns = [col.lower() for col in df.columns]\n", + "\n", + " # Segunda transformação: Aplicar o método .str.lower() nos valores das COLUNAS object/strings:\n", + " l_cols_objeto = df.select_dtypes(include = ['object']).columns\n", + " \n", + " for col in l_cols_objeto:\n", + " df[col] = df[col].str.lower()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hNixsW8M7n1X" + }, + "source": [ + "Para saber mais sobre o método df[col].str.lower(), consulte [pandas.Series.str.lower](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.lower.html)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hz90zejtbxYj" + }, + "source": [ + "transformacao_lower(df_Titanic)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UE5P1W-CPePM" + }, + "source": [ + "# **Selecionar um subconjunto de colunas**\n", + "Suponha que eu queira selecionar somente as colunas 'Name' e 'Sex'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P7HJa4x7P0bQ" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3jLZUCfePsBs" + }, + "source": [ + "df_Titanic2 = df_Titanic[['Name', 'Sex']]\n", + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PyNsYTilnL2r" + }, + "source": [ + "# map()\n", + "> Artificio para lidar com a transformação de dados utilizando um dicionário: {'key': valor}." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6z4FcyyAiTfF" + }, + "source": [ + "# Construindo uma variável mais intuitiva para nos ajudar nas análises:\n", + "df_Titanic['survived2'] = df_Titanic['survived']\n", + "df_Titanic['survived2'] = df_Titanic['survived2'].map({0:'died', 1:'survived'})\n", + "df_Titanic[['survived', 'survived2']].head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwBWkaJOdhCv" + }, + "source": [ + "___\n", + "# **Selecionar COLUNAS do dataframe**\n", + "* Suponha que queremos selecionar somente as COLUNAS 'survived', 'sex' e 'embarked':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ivvj8JU2pBTq" + }, + "source": [ + "df_Titanic2 = df_Titanic[['survived', 'sex', 'embarked']]\n", + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nf-Wnof_fdTR" + }, + "source": [ + "___\n", + "# **Criar um dicionário a partir de um dataframe**\n", + "> Suponha o dataframe-exemplo a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lxf6Lgp4fit8" + }, + "source": [ + "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l7yzJu1y5huV" + }, + "source": [ + "De dataframe para Dicionário..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_6V0qFZGhEoF" + }, + "source": [ + "df.to_dict('dict')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0GIe6xtqPA1Z" + }, + "source": [ + "___\n", + "# **Criar uma lista a partir de um dataframe**\n", + "> Suponha o dataframe-exemplo a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fZxgejTtPLzX" + }, + "source": [ + "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JoShm6oF5qLV" + }, + "source": [ + "De dataframe para Lista..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gigPpSH_hlXu" + }, + "source": [ + "df.to_dict('list')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GpJDX-5xUUC0" + }, + "source": [ + "___\n", + "# **Mostrar as primeiras k LINHAS do dataframe**\n", + "> df.head(k), onde k é o número de LINHAS que queremos visualizar. Por default, k= 10." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RwC9j_OxUbIR" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G9cp2QrsA5M0" + }, + "source": [ + "___\n", + "# **Mostrar as últimas k LINHAS do dataframe**\n", + "> df.tail(k), onde k é o número de LINHAS que queremos ver. Por default, k= 10." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9mPxyhqoA4Wc" + }, + "source": [ + "df_Titanic.tail()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Odwm2qSLA_Ro" + }, + "source": [ + "Por default, df.tail() mostra as últimas 5 LINHAS/instâncias do dataframe. Entretando, pode ser ver qualquer número de LINHAS k, como, por exemplo, k= 10 mostrado abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUAnR00WA8ma" + }, + "source": [ + "df_Titanic.tail(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cZ64LfWv4zxo" + }, + "source": [ + "___\n", + "# **Mostrar o nome das COLUNAS do dataframe**\n", + "* df.columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CKUUrX5n4zFW" + }, + "source": [ + "df_Titanic.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6m7ukrOu5Inv" + }, + "source": [ + "___\n", + "# **Mostrar os tipos das COLUNAS do dataframe**\n", + "* Propriedade: df.dtypes --> Não há parênteses!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S4NIHAPPl9lc" + }, + "source": [ + "df_Titanic.dtypes # dtypes é uma propriedade, portanto não requer \"()\". Os métodos, por outro lado, requerem \"(arg1, arg2, ..., argN)\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DGc6m-UBdHlE" + }, + "source": [ + "___\n", + "# **Selecionar automaticamente as COLUNAS do dataframe pelo tipo**\n", + "> snippet: df.select_dtypes(include=[tipo]).columns\n", + "\n", + "| Tipo | O que seleciona | Sintaxe |\n", + "|------|-----------------|---------|\n", + "| number | colunas do tipo numéricas | df.select_dtypes(include=['number]).columns |\n", + "| float | colunas do tipo float | df.select_dtypes(include=['float']).columns |\n", + "| bool | colunas do tipo booleanas | df.select_dtypes(include=['bool']).columns |\n", + "| object | colunas do tipo categóricas/strings | df.select_dtypes(include=['object']).columns |\n", + "\n", + "* Se quisermos selecionar mais de um tipo, basta informar a lista de tipos. \n", + " * Exemplo: df.select_dtypes(include=['object', 'float']).columns\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O88YRCqIdYFL" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS Numéricas do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xG4a9ZfRnxPW" + }, + "source": [ + "### Lista com as COLUNAS numéricas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C87uga35dKsF" + }, + "source": [ + "l_cols_numericas = df_Titanic.select_dtypes(include = ['number']).columns # \".columns\" retorna a lista de colunas numéricas\n", + "l_cols_numericas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5W6kbIVNn2UA" + }, + "source": [ + "### DataFrame com as COLUNAS numéricas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTieUd_-eDmW" + }, + "source": [ + "df_numericas = df_Titanic.select_dtypes(include = ['number']) # Atenção: aqui não temos .columns --> Neste caso, o retorno será o dataframe.\n", + "df_numericas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xh4BFs_lds80" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS float do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tw3FD74MoC6q" + }, + "source": [ + "### Lista com as COLUNAS float:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5clAUAIrd3UR" + }, + "source": [ + "l_cols_float = df_Titanic.select_dtypes(include = ['float']).columns\n", + "l_cols_float" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IZPROG6IoHwy" + }, + "source": [ + "### DataFrame com as COLUNAS float:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "osJDsyMHeXX4" + }, + "source": [ + "df_float = df_Titanic.select_dtypes(include = ['float']) # Atenção: aqui não temos .columns\n", + "df_float.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5uObezIIfuJ4" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS Booleanas do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xMKP5HhgoeMg" + }, + "source": [ + "### Lista com as COLUNAS Booleanas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3Pn2IPBkf7k-" + }, + "source": [ + "l_cols_booleanas = df_Titanic.select_dtypes(include = ['bool']).columns\n", + "l_cols_booleanas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "k3sdiuXYokBE" + }, + "source": [ + "### DataFrame com as COLUNAS Booleanas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Oem-M-17f7lG" + }, + "source": [ + "df_booleanas = df_Titanic.select_dtypes(include=['bool']) # Atenção: aqui não temos .columns\n", + "df_booleanas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ObHYW92-gOXz" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS do tipo string (object)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IzM5CIKXoxHO" + }, + "source": [ + "### Lista com as COLUNAS do tipo object/string:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rdYThBingOX1" + }, + "source": [ + "l_cols_objeto = df_Titanic.select_dtypes(include=['object']).columns\n", + "l_cols_objeto" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2ZGB5d36o21t" + }, + "source": [ + "### DataFrame com as COLUNAS do tipo Object/String:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kWTtxeU4gOX4" + }, + "source": [ + "df_cols_obs = df_Titanic.select_dtypes(include=['object']) # Atenção: aqui não temos .columns\n", + "df_cols_obs.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SEBKHKRLkbUK" + }, + "source": [ + "___\n", + "# **Reordenar as COLUNAS do dataframe**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XRWfelWEkhae" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KBGDeR_JkyCc" + }, + "source": [ + "* Suponha que queremos reordenar as COLUNAS do dataframe df_Titanic em ordem alfabética, conforme abaixo:\n", + " * age;\n", + " * embarked;\n", + " * fare;\n", + " * parch;\n", + " * pclass;\n", + " * sex;\n", + " * sibsp;\n", + " * survived." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d9jJi6qllnq_" + }, + "source": [ + "df_Titanic = df_Titanic.reindex(sorted(df_Titanic.columns), axis = 1)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cj4MREti-izC" + }, + "source": [ + "___\n", + "# **Mostrar a dimensão do dataframe**\n", + "* Dimensão = Número de LINHAS e COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "50Tij93l-n7B" + }, + "source": [ + "df_Titanic.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZQo4YeH_-qfL" + }, + "source": [ + "Qual a interpretação?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "klHcwpPEALP8" + }, + "source": [ + "## **Quebrar a dimensão em duas partes: número de LINHAS e COLUNAS**\n", + "* Número de linhas do dataframe.: df_Titanic.shape[0]\n", + "* Número de colunas do dataframe: df_Titanic.shape[1]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qjR8OEdDAOog" + }, + "source": [ + "f'O dataframe df_Titanic possui {df_Titanic.shape[0]} linhas e {df_Titanic.shape[1]} colunas.'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pIsf_nDtyAvF" + }, + "source": [ + "___\n", + "# **Combinar dataframes: Merge, Join & Concatenate**\n", + "* Fonte: [Merge, join, and concatenate](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s1fSplrlEMHK" + }, + "source": [ + "* A seguir, três formas para combinar dataframes:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6DYtWxuIrdzF" + }, + "source": [ + "## Concatenate\n", + "* Une/empilha dataframes\n", + "* Fonte: https://github.com/aakankshaws/Pandas-exercises" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nnP5VuWkri_b" + }, + "source": [ + "import pandas as pd\n", + "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rkJvSGYSrm8b" + }, + "source": [ + "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n", + " 'B': ['B4', 'B5', 'B6', 'B7'],\n", + " 'C': ['C4', 'C5', 'C6', 'C7'],\n", + " 'D': ['D4', 'D5', 'D6', 'D7']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NCgdYvJIrqx1" + }, + "source": [ + "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n", + " 'B': ['B8', 'B9', 'B10', 'B11'],\n", + " 'C': ['C8', 'C9', 'C10', 'C11'],\n", + " 'D': ['D8', 'D9', 'D10', 'D11']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gUoyjyjur5Zn" + }, + "source": [ + "df1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xU6Rh10Gr7NA" + }, + "source": [ + "df2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qKwmOWsQr9wA" + }, + "source": [ + "df3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-MNn-XdlsjJS" + }, + "source": [ + "df= pd.concat([df1, df2, df3])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BV6HgxSYtG6Z" + }, + "source": [ + "Veja que basicamente empilhamos os dataframes. No entanto, se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Dp-oh-7ftLo5" + }, + "source": [ + "df = pd.concat([df1, df2, df3], axis = 1) # axis = 1 é uma operação de coluna\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iyDZt2XEtmVs" + }, + "source": [ + "Se, no entanto, tivermos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PAhjjVZtpP5" + }, + "source": [ + "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']},\n", + " index=[0, 1, 2, 3])\n", + "\n", + "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n", + " 'B': ['B4', 'B5', 'B6', 'B7'],\n", + " 'C': ['C4', 'C5', 'C6', 'C7'],\n", + " 'D': ['D4', 'D5', 'D6', 'D7']},\n", + " index=[4, 5, 6, 7])\n", + "\n", + "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n", + " 'B': ['B8', 'B9', 'B10', 'B11'],\n", + " 'C': ['C8', 'C9', 'C10', 'C11'],\n", + " 'D': ['D8', 'D9', 'D10', 'D11']},\n", + " index=[8, 9, 10, 11])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zGDHd-kPt3-T" + }, + "source": [ + "Então..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3bTl2Nr2t5WM" + }, + "source": [ + "df = pd.concat([df1, df2, df3], axis = 1)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sUXjlp_Jt925" + }, + "source": [ + "Porque isso acontece?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JdKXY873HrYt" + }, + "source": [ + "## Merge\n", + "> Primeiramente, vamos ver todos os casos possíveis de joins.\n", + "\n", + "### Exemplo\n", + "> O exemplo a seguir foi inspirado no exemplo apresentado em [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins). Considere os dataframes a seguir" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g4pmhk2t3x8s" + }, + "source": [ + "import pandas as pd\n", + "\n", + "d_Tabela_A = {'indices': [1,2,3,6,7,5,4,10], 'valores': ['A','B','C','D','E','F','G','H']}\n", + "d_Tabela_B = {'indices': [1,2,3,6,7,8,9,11], 'valores': ['AA', 'BB','CC','DD','EE','FF','GG','HH']}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XxfUULxY52ns" + }, + "source": [ + "df_conjunto_A = pd.DataFrame(d_Tabela_A).set_index('indices')\n", + "df_conjunto_B = pd.DataFrame(d_Tabela_B).set_index('indices')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gGdU36Vi0Yso" + }, + "source": [ + "![SQL_inner_join](https://github.com/MathMachado/Materials/blob/master/SQL_inner_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5w7ox7LV9cuG" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPhmKw-F9fWX" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5AaTlCPy9FBZ" + }, + "source": [ + "df_inner_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'inner')\n", + "df_inner_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U3OjFM0E0af-" + }, + "source": [ + "![SQL_left_join](https://github.com/MathMachado/Materials/blob/master/SQL_left_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-efYd9c69k4L" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SqFbNStz9k4S" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rUpc2k729KA-" + }, + "source": [ + "df_left_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'left')\n", + "df_left_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WioSBHjW06Hg" + }, + "source": [ + "![SQL_right_join](https://github.com/MathMachado/Materials/blob/master/SQL_right_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IrzPjGNp9o2n" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tFFTp_yG9o2s" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_D4tF7E-9PCx" + }, + "source": [ + "df_right_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'right')\n", + "df_right_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E9xFrurZ0ksg" + }, + "source": [ + "![SQL_outer_join](https://github.com/MathMachado/Materials/blob/master/SQL_outer_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kQCBAfj_9rO_" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FTDHYsgc9rP0" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hJqyAs0U9XwO" + }, + "source": [ + "df_outer_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'outer')\n", + "df_outer_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fHEgLynu0vve" + }, + "source": [ + "![SQL_left_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_left_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZA8CcERE-RRS" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IZiAa9X6-UL0" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jdUt63rA-Vjo" + }, + "source": [ + "df_left_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"left_only\"')\n", + "df_left_excluding_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CShcqL-h1MqK" + }, + "source": [ + "![SQL_right_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_right_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ECjUDoYf_C9x" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xym7VsXi_FXa" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-zFalmly_HJ7" + }, + "source": [ + "df_right_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"right_only\"')\n", + "df_right_excluding_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T8v4-zUt1WQz" + }, + "source": [ + "![SQL_outer_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_outer_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8HeMgBqyAYjW" + }, + "source": [ + "### Desafio: Como resolver este?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SkCbLsoktgKl" + }, + "source": [ + "### Observações:\n", + "\n", + "* Em alguns casos a variável chave nos dois dataframes que se quer fazer o join possui nomes diferentes. Neste caso, use 'left_on' e 'right_on' para definir o nome das COLUNAS chaves no dataframe da esquerda e direita:\n", + " * pd.merge(df1, df2, left_on =\"employee\", right_on =\"nome\")\n", + " * No exemplo acima, o dataframe df1 (dataframe da esquerda) possui chave 'employee' enquanto que o dataframe df2 (dataframe da direita), possui chave 'nome'. Usando as 'left_on' e 'right_on' fica claro o nome das chaves de ligação de cada dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6Obc0fHUwIpu" + }, + "source": [ + "## Joining" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DQOa89_cwLyd" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'A': ['A0', 'A1', 'A2'],\n", + " 'B': ['B0', 'B1', 'B2']},\n", + " index=['K0', 'K1', 'K2']) \n", + "\n", + "df_direito = pd.DataFrame({'C': ['C0', 'C2', 'C3'],\n", + " 'D': ['D0', 'D2', 'D3']},\n", + " index=['K0', 'K2', 'K3'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UHnX9rxzwMmx" + }, + "source": [ + "df_esquerdo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GBc1Mr0Qwff3" + }, + "source": [ + "df_direito" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TmIk3Kjlwg-7" + }, + "source": [ + "df_esquerdo.join(df_direito)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h609fbjjwoZ3" + }, + "source": [ + "df_esquerdo.join(df_direito, how ='outer')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y8W2kP-VCB3E" + }, + "source": [ + "___\n", + "# **Selecionar LINHAS do dataframe baseado nos índices**\n", + "### Leitura Adicional\n", + "* [pandas loc vs. iloc vs. ix vs. at vs. iat?\n", + "](https://stackoverflow.com/questions/28757389/pandas-loc-vs-iloc-vs-ix-vs-at-vs-iat/47098873#47098873)\n", + "* [Indexing and selecting data](https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NN1R1ngAG61x" + }, + "source": [ + "## 1st Approach - pd.loc[]\n", + "* Para capturar o conteúdo da linha k, use df.loc[row_indexer,column_indexer]." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oduXMUtIUvkN" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JX9nGPWcVLgE" + }, + "source": [ + "\n", + "Por exemlo, o comando a seguir mostra o conteúdo da linha 0, todas as COLUNAS(:)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U5-I2NgYC2fD" + }, + "source": [ + "df2= df_Titanic.loc[1,:]\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tDSJcQLTDyJw" + }, + "source": [ + "Mostrando o conteúdo das LINHAS k= 1:2 (ou seja, LINHAS 1 e 2), todas as COLUNAS(:)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JD1TDTqAD_5r" + }, + "source": [ + "df_Titanic.loc[1:2, :]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EoAmcdfnEIho" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1, coluna 'pclass':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8vjc5z3_EQfY" + }, + "source": [ + "df_Titanic.loc[1, ['pclass']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7bC8-H-QFLgd" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1 e COLUNAS ['pclass', 'sex']:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LYFTrZr_FR5g" + }, + "source": [ + "df_Titanic.loc[0, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UtUsmU8sXYTU" + }, + "source": [ + "Porque temos um erro aqui?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CRy5sDx-XbBL" + }, + "source": [ + "Versão correta abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Lfw0HEnXdn0" + }, + "source": [ + "df_Titanic.loc[1, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tjw3vjkDZg1Z" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1:5 e COLUNAS ['pclass', 'sex']:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4GuAE5MSZjNb" + }, + "source": [ + "df_Titanic.loc[1:5, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xRZxqE6RFnJI" + }, + "source": [ + "Agora suponha que queremos selecionar toda a 'sex'. Como fazer isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JdeD_uzfFrp5" + }, + "source": [ + "df_sex= df_Titanic.loc[:, 'sex']\n", + "df_sex.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z_WUjYxsX-Av" + }, + "source": [ + "Fácil selecionarmos o que queremos usando .loc() e iloc(), certo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RKk0zollHFbp" + }, + "source": [ + "## 2nd Approach - Usando lists\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jhwoY6LmGzC0" + }, + "source": [ + "df_Titanic[0:2] # Mostrar os conteúdos das LINHAS 0:2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I6EOVIDxGiy-" + }, + "source": [ + "df_Titanic[:3] # Mostrar os conteúdos até a linha 3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOHp77F8H9t1" + }, + "source": [ + "df_Titanic['sex'].head() # Mostrar o conteúdo inteiro da variável 'sex'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8nvHNdhPZ040" + }, + "source": [ + "df_Titanic[0:5]['sex'].head() # Mostrar as LINHAS 0 a 5 da variável 'sex'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GMFso1jaYXgN" + }, + "source": [ + "___\n", + "# **Selecionar/Filtrar/Substituir LINHAS do dataframe baseado em condições**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BKljSpS5ou-i" + }, + "source": [ + "## Exemplo 1\n", + "> Aproveitando o exemplo anterior, queremos selecionar do dataframe somente os passageiros do sexo 'male'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jek8Ru3Aam23" + }, + "source": [ + "### Approach 1: df.loc() e df.iloc()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eysZoBX2YKb-" + }, + "source": [ + "df_sexo_m_1 = df_Titanic.loc[df_Titanic['sex'] == 'male', 'sex']\n", + "df_sexo_m_1.head() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uLDOHKGfaq-Z" + }, + "source": [ + "### Approach 2: Uso do []" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QncrZwHkasiu" + }, + "source": [ + "df_sexo_m_2 = df_Titanic[df_Titanic['sex'] == 'male']['sex']\n", + "df_sexo_m_2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ot6UBTYJF-AJ" + }, + "source": [ + "### Approach 3: df.isin()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OBRF0be3VuTi" + }, + "source": [ + "#### Exemplo 1 - Filtro simples" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LeTDiGICGOzb" + }, + "source": [ + "df_sexo_m_3 = df_Titanic['sex'].isin(['male'])\n", + "df_sexo_m_3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q6emu30nGmpt" + }, + "source": [ + "#### Exemplo 2 - Filtro duplo = Duas condições\n", + "> Selecionar todas as LINHAS onde sexo = 'male' e Pclass = 1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TRaiCYMRGpgl" + }, + "source": [ + "# Filtros usando df.isin() \n", + "filtro_m = df_Titanic[\"sex\"].isin([\"male\"]) \n", + "filtro_class1 = df_Titanic[\"Pclass\"].isin([1]) \n", + " \n", + "# Mostra os resutados \n", + "df_Titanic[filtro_m & filtro_class1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Sh0DDj1xcPaI" + }, + "source": [ + "df_sexo_m_class = df_Titanic[((df_Titanic['sex'] == 'male') & (df_Titanic['Pclass'] == 1))]\n", + "df_sexo_m_class.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ujrYHyOsfW7n" + }, + "source": [ + "### Approach 4 - Filtrar com df.str.contains('s_substr')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gntbfHgTfanx" + }, + "source": [ + "# Mostrar todas as LINHAS onde a string 'Mr' aparece no nome do passageiro:\n", + "df2 = df_Titanic[df_Titanic['Name'].str.contains('Mr')]\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eaRtQ8Ja8MOH" + }, + "source": [ + "Para saber mais sobre o método df[col].str.contais(), consulte https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FyJ-gEjzQI2Y" + }, + "source": [ + "## Substituir valores do dataframe\n", + "> Suponha que queremos substituir todos os valores de pclass da seguinte forma:\n", + "* Se pclass = 1 --> pclass2 = 'Classe1';\n", + "* Se pclass = 2 --> pclass2 = 'Classe2';\n", + "* Se pclass = 3 --> pclass2 = 'Classe3';\n", + "\n", + "Como fazer isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Pi8MFiUPQQb7" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "19mynzdfQqVf" + }, + "source": [ + "df_Titanic['pclass2'] = df_Titanic['pclass']\n", + "df_Titanic['pclass2'][df_Titanic['pclass'] == 1] = 'Classe1'\n", + "df_Titanic['pclass2'][df_Titanic['pclass'] == 2] = 'Classe2'\n", + "df_Titanic['pclass2'][df_Titanic['pclass'] == 3] = 'Classe3'\n", + "df_Titanic['pclass2'].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KVSAYeU0KA2V" + }, + "source": [ + "___\n", + "# **Selecionar amostras aleatórias do dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U502dAs3OfOH" + }, + "source": [ + "Vimos que o dataframe df_Titanic é muito grande. Então, vamos selecionar aleatoriamente 100 LINHAS." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BrKUnAiPcAy" + }, + "source": [ + "import random \n", + "\n", + "# Biblioteca para avaliarmos o tempo de processamento de cada alternativa\n", + "import time" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iJ1G8lYgKGsc" + }, + "source": [ + "# Usando sample\n", + "t0= time.time()\n", + "df_Titanic_a100= df_Titanic.sample(100, replace= False, random_state= 20111974)\n", + "t1= time.time()\n", + "t= t1-t0\n", + "df_Titanic_a100.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8DvWOKizZQr8" + }, + "source": [ + "f'Tempo de processamento: {t}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nAHLTjpvYKPS" + }, + "source": [ + "# Usando NumPy\n", + "import numpy as np\n", + "\n", + "t0 = time.time()\n", + "np.random.seed(20111974)\n", + "indices = np.random.choice(df_Titanic.shape[0], replace = False, size=100)\n", + "df_Titanic_a100_2 = df_Titanic.iloc[indices]\n", + "t1 = time.time()\n", + "t = t1-t0\n", + "df_Titanic_a100_2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U8PEDMJ4a52P" + }, + "source": [ + "f'Tempo de processamento: {t}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wYeuJWdEdMPd" + }, + "source": [ + "df_Titanic_a100_2.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vNMiRkjCQ9Mu" + }, + "source": [ + "___\n", + "# **Descrever o Dataframe**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GllUFj56RHuD" + }, + "source": [ + "df_Titanic_a100.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "izbpIEi1d1sx" + }, + "source": [ + "df_Titanic_a100_2.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H40G3QzWbG9N" + }, + "source": [ + "___\n", + "# **Identificar e lidar com LINHAS duplicadas**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_OoM_HS5ZgxG" + }, + "source": [ + "## Exemplo 1\n", + "* considera as duplicatas em todas as COLUNAS do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5XOOdOZBbLc_" + }, + "source": [ + "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gio08BkTbTOp" + }, + "source": [ + "# Lista as duplicações em forma booleana\n", + "df.duplicated()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "obgbM4d_hJ_J" + }, + "source": [ + "Observe a linha 5, onde temos a informação que esta linha está duplicada. Na verdade, a linha 5 é igual à linha 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LHhOIb-EbWfn" + }, + "source": [ + "# Mostra as LINHAS duplicadas\n", + "df[df.duplicated()]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IyJS70_kZ-Jk" + }, + "source": [ + "# Deleta a linha 5 que, como vimos, estava duplicada (uma cópia da linha 1).\n", + "df= df.drop_duplicates()\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Q05mxOSaEjX" + }, + "source": [ + "## Exemplo 2\n", + "* Considera somente algumas COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jiqyjcqdaQ1y" + }, + "source": [ + "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "F_118d7vbZ9Y" + }, + "source": [ + "# Mostra as LINHAS duplicadas usando as COLUNAS 'A' e 'B'\n", + "df[df.duplicated(subset=['A','B'])]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_1w_ZZO4vF3A" + }, + "source": [ + "# Deleta as LINHAS 1 e 5, pois como podemos ver, são duplicatas da linha 0\n", + "df= df.drop_duplicates(subset = ['A', 'B'])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qVx6p8u36jhD" + }, + "source": [ + "___\n", + "# **Trabalhar com dados do tipo texto**\n", + "* Fontes:\n", + " * [Working with text data](https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html)\n", + " * [Using String Methods](https://www.ritchieng.com/pandas-string-methods/)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JLG3cVA1e8-B" + }, + "source": [ + "Preparando os dados para o exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G_CEULoyeP8C" + }, + "source": [ + "# Definir um dicionário com os dados: \n", + "import numpy as np\n", + "\n", + "l_idade = []\n", + "for i in range(6):\n", + " np.random.seed(i) \n", + " l_idade.append(np.random.randint(10, 40))\n", + " \n", + "\n", + "d_exemplo = {'Nome':['Mr. Antonio dos Santos', 'Mr. Joao Pedro', 'Miss. Priscila Alvarenga', 'Mr. fagner NoVAES', 'Miss. Danielle Aparecida', 'Mr. Paullo Amarantes'], \n", + " 'Idade': l_idade, \n", + " 'Cidade':['lisboa', 'Sintra', 'Braga', 'Guimaraes', 'Mafra', 'Nazare']} \n", + " \n", + "# Converte o dicionário num dataframe\n", + "df = pd.DataFrame(d_exemplo) \n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "or-Kzaqmdn2b" + }, + "source": [ + "* Sugestões do que podemos fazer com relação á coluna 'nome' do dataframe df:\n", + " * Extrair o cumprimento do nome: Mr., Miss e etc.\n", + " * Construir as COLUNAS PrimeiroNome e SegundoNome.\n", + " * Criar a variável classe_idade." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vd99ksvcg7uy" + }, + "source": [ + "## Extrair o cumprimento do nome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rNsANzFAg_Kn" + }, + "source": [ + "df_Nome= df['Nome'].str.split(' ', n = 2, expand = True) \n", + "df_Nome" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ianqsxLol008" + }, + "source": [ + "Altere o valor de n para 3 e explique como as coisas funcionam..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5NDAkEqCl6H5" + }, + "source": [ + "# Capturando o cumprimento do nome:\n", + "df['tamanho_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[0]\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B1QoH4LyrpVI" + }, + "source": [ + "## Construir as COLUNAS primeiro_nome e Segundo_Nome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cbi4eRN2mOu9" + }, + "source": [ + "# Capturando o primeiro nome:\n", + "df['primeiro_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[1]\n", + "df['ultimo_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[2]\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7eagWhgZrwOh" + }, + "source": [ + "### Construir a variável classe_idade\n", + "\n", + " | Limite Inferior | Limite Superior | Classe |\n", + " |-----------------|-----------------|--------|\n", + " | Inf | 15 | Inf_15 |\n", + " | 15 | 20 | 15_20 |\n", + " | 20 | 30 | 25_30 |\n", + " | 30 | 40 | 30_40 |\n", + " | 40 | 50 | 40_50 |\n", + " | 50 | Sup | 50_Sup |" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lBjRBGBWr2AH" + }, + "source": [ + "def classe_idade):\n", + " if (Idade <= 15):\n", + " return 'Inf_15'\n", + " if (15 < Idade <= 20):\n", + " return '15_20'\n", + " elif(20 < Idade <= 30):\n", + " return '20_30'\n", + " elif (30 < Idade <= 40):\n", + " return '30_40'\n", + " elif (40 < Idade <= 50):\n", + " return '40_50'\n", + " elif (Idade > 50):\n", + " return '50_Sup'\n", + " else:\n", + " return 'Outros'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OogrvjCrsdoh" + }, + "source": [ + "df['classe_idade'] = df['Idade'].map(classe_idade)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDtxz_eaRcmi" + }, + "source": [ + "___\n", + "# **Agrupar Informações: pd.groupby()**\n", + "* Fonte: [Group By: split-apply-combine](https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html)\n", + "\n", + "* Os componentes do comando Groupby()\n", + " * **Grouping_Column** - Coluna Categórica pelo qual os dados serão agrupados;\n", + " * **Aggregating_Column** - Coluna numérica cujos valores serão agrupados;\n", + " * **Aggregating_Function** - Função agregadora, ou seja: sum, min, max, mean, median, etc...\n", + "\n", + "> Sintaxe: \n", + "\n", + "```\n", + "df.groupby('Grouping_Column').agg({'Aggregating_Column': 'Aggregating_Function'})\n", + "\n", + "OU\n", + "\n", + "df['Aggregating_Column'].groupby(df['Grouping_Column']).Function()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bmFf-273XPXj" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wteEveUsd36C" + }, + "source": [ + "transformacao_lower(df_Titanic)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "buF5DhkFfqVA" + }, + "source": [ + "# Agrupando df_Titanic por 'sex3'\n", + "df_Titanic.groupby(['sex', 'pclass']).agg({'fare': ['min', 'median', 'mean','max'], 'age': ['count', 'mean','max']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YP3GDwq0gR_V" + }, + "source": [ + "# Agrupando df_Titanic por 'sex3' e 'Pclass'\n", + "df_Titanic.groupby(['sex3','Pclass']).agg({'Fare': ['max', 'min']}).round(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "se4tQ3ETeUfv" + }, + "source": [ + "df_Titanic.groupby(['sex3']).agg({'Age': ['mean','min','max']}).round(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zUj82I7Cm220" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OrLZjm9bXTOr" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x8aPZPT6XZVP" + }, + "source": [ + "### Preparando o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KrCe6RgOXaFx" + }, + "source": [ + "l_coluna = []\n", + "\n", + "for i in range(1,6):\n", + " np.random.seed(i)\n", + " l_coluna.append(np.random.randint(0, 10, 10))\n", + " \n", + "np.random.seed(6)\n", + "l_coluna.append(np.random.rand(10))\n", + "\n", + "l_coluna" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tXaHjmfSXeCw" + }, + "source": [ + "l_coluna[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U_aEVMTHq6ee" + }, + "source": [ + "df = pd.DataFrame({'coluna6' : ['a', 'a', 'b', 'b', 'a', 'b', 'b', 'b', 'a', 'a'],\n", + " 'coluna7' : ['um', 'dois', 'um', 'dois', 'um', 'dois', 'dois', 'um', 'um', 'dois'],\n", + " 'coluna1' : l_coluna[0],\n", + " 'coluna2' : l_coluna[1],\n", + " 'coluna3' : l_coluna[2],\n", + " 'coluna4' : l_coluna[3],\n", + " 'coluna5' : l_coluna[4],\n", + " 'coluna8' : l_coluna[5],\n", + " 'Pessoas' : ['Jose','Maria','Pedro','Carlos','Joao','Ana','Manoel','Mafalda','Antonio','Ricardo'],\n", + " 'sexo' : ['m','f','m','m','m','f','m','f','m','m']})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ok4a28lGlVC5" + }, + "source": [ + "Agrupando por 'coluna6':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vx77lyzlZIFW" + }, + "source": [ + "df.groupby('coluna6').agg({'coluna1': ['min','mean','median','max']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T6i-R2KemadE" + }, + "source": [ + "Agora, vamos repetir o processo usando duas COLUNAS-chaves 'coluna6' e 'coluna7':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WxmHQnQSZrXA" + }, + "source": [ + "df_estatisticas_descritivas = df.groupby(['coluna6','coluna7']).agg({'coluna1': ['min','mean','median','max']})\n", + "df_estatisticas_descritivas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ipw5EROwaaCX" + }, + "source": [ + "Observe que df_estatisticas_descritivas é um dataframe. Portanto, podemos selecionar LINHAS e/ou COLUNAS deste dataframe da forma que quisermos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qk5uSdVwb7dH" + }, + "source": [ + "# Índices do dataframe:\n", + "df_estatisticas_descritivas.index" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "brIgUFlkalix" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um':\n", + "df_estatisticas_descritivas.loc[('a', 'um')]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fQUs2PVHc6iR" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', primeiro valor:\n", + "df_estatisticas_descritivas.loc[('a', 'um')][0] # ou seja, selecionamos min" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zT0xiee6dDpK" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', segundo valor:\n", + "df_estatisticas_descritivas.loc[('a', 'um')][1] # ou seja, selecionamos mean" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vXlcjPM6dQKi" + }, + "source": [ + "E daí por diante..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EMxFMqn9dm3g" + }, + "source": [ + "Para aprender mais sobre como trabalhar com dois índices em um dataframe, consulte [Hierarchical indices, groupby and pandas](https://www.datacamp.com/community/tutorials/pandas-multi-index)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gNHyH7M0pGDy" + }, + "source": [ + "___\n", + "## Exemplo 3\n", + "### Operações e transformações em grupo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ywl3k_l8pGD0" + }, + "source": [ + "# Mostra o dataframe-exemplo:\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AF8cbNsjpGD5" + }, + "source": [ + "# Constroi dataframe df_Medias\n", + "df_Medias = df.groupby('coluna6').mean().add_prefix('mean_')\n", + "df_Medias" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JGlA6ufLpGD9" + }, + "source": [ + "# Combina (merge) com o dataframe df:\n", + "pd.merge(df, df_Medias, left_on ='coluna6', right_index=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1MjZu3sVpGEd" + }, + "source": [ + "___\n", + "# **Discretizar COLUNAS numéricas**\n", + "* pd.cut() - classes com base em valores;\n", + "* pd.qcut() - classes com base em quantis da amostra, ou seja teremos a mesma quantidade de itens em cada classe.\n", + "\n", + "> Este artifício é muito utilizado em Machine Learning quando queremos construir classes para variáveis numéricas (integer ou float). Acompanhe a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yK772hiSfZaE" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wi-nv6fshKIX" + }, + "source": [ + "## pd.cut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SVExQmzDpGEe" + }, + "source": [ + "# Construir 4 classes para a variável float 'coluna8':\n", + "Bucket_cut = pd.cut(df['coluna8'], 4) # aqui, estamos construindo 4 buckets\n", + "Bucket_cut" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OOD38I6ug1AY" + }, + "source": [ + "# Quem são os Bucket's que construimos:\n", + "Bucket_cut.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9s2eaZGtfsxu" + }, + "source": [ + "Como podem ver, de fato construimos 4 bucket's. **Observe que não temos a mesma quantidade de itens em cada classe!!!**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T7u0pS64hPHC" + }, + "source": [ + "## pd.qcut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cJTQTHA6pGEm" + }, + "source": [ + "Bucket_qcut = pd.qcut(df['coluna8'], 4, labels=False)\n", + "Bucket_qcut" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vM30Td_8hZre" + }, + "source": [ + "# Quem são os Bucket's que construimos:\n", + "Bucket_qcut.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jhf6V5LTh4G7" + }, + "source": [ + "## Comentários\n", + "* pd.qcut() garante uma distribuição mais uniforme dos valores em cada classe. Isso significa que é menos provável que você tenha uma classe com muitos dados e outra com poucos dados.\n", + "* Eu prefiro usar pd.qcut()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RNsR0NsS5iIU" + }, + "source": [ + "___\n", + "# **Distribuição conjunta - crosstabs**\n", + "> Suponha que queremos analisar o número de sobreviventes em relação à COLUNA embarked." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LKQv6YtSfGSU" + }, + "source": [ + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ANhb5rBffTh6" + }, + "source": [ + "pd.crosstab(df_Titanic2['survived'], df_Titanic2['embarked'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WIlHAYEVqSjT" + }, + "source": [ + "___\n", + "# **Deletar COLUNAS do dataframe**\n", + "> Deletar as COLUNAS 'coluna2' e 'coluna5' do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YssOMF_Vqso5" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rVF_1p0Gq3gZ" + }, + "source": [ + "## Usando inplace = True" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BjRIX1jqWQT" + }, + "source": [ + "df.drop(['coluna2','coluna5'], axis =1, inplace =True)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "POC2fnTlq8mK" + }, + "source": [ + "## Usando atribuição" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YRSwEbnfq7s_" + }, + "source": [ + "df= df.drop(['coluna2','coluna5'], axis =1)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bHth6KSv7k0G" + }, + "source": [ + "___\n", + "# **Criar COLUNAS dummies para dados categóricos**\n", + "> Nosso objetivo é construir variáveis dummies para nossas COLUNAS categóricas.\n", + "\n", + "* Fontes: \n", + " * [Categorical data](https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html)\n", + " * [Creating Dummy Variables](https://www.ritchieng.com/pandas-creating-dummy-variables/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GOqcARHqjMr_" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yNqvwEu9jbuW" + }, + "source": [ + "Vamos construir variáveis dummies para as COLUNAS 'coluna6' e 'coluna7', da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "16osZsMEjmDh" + }, + "source": [ + "pd.get_dummies(df['coluna6'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cb1gp_Y1jxz2" + }, + "source": [ + "Qual a interpretação do resultado acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cic19l-Mj39q" + }, + "source": [ + "pd.get_dummies(df['coluna7'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "44FDXcoyj-tT" + }, + "source": [ + "Qual a interpretação do resultado acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cxHc6BvDkCWl" + }, + "source": [ + "df = pd.get_dummies(df, columns =['coluna6', 'coluna7', 'sexo'])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2m25N4znZ2O" + }, + "source": [ + "df.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x0uXu0RRlB2a" + }, + "source": [ + "___\n", + "# **Calcular correlação (Análise de Correlação)**\n", + "> A correlação pode ser calculada usando o método df.corr(). Para mais detalhes sobre os tipos de correlação existentes bem como a aplicação de cada uma delas, consulte os links a seguir:\n", + "\n", + "* [Pearson correlation coefficient](https://en.wikipedia.org/wiki/Pearson_correlation_coefficient)\n", + "* [Kendall rank correlation coefficient](https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient)\n", + "* [Spearman's rank correlation coefficient](https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient).\n", + "\n", + "Para aprender mais sobre a geração de heatmap, consulte [Seaborn Heatmap Tutorial (Python Data Visualization)](https://likegeeks.com/seaborn-heatmap-tutorial/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AgoigF8AnYG0" + }, + "source": [ + "## Gerando o dataframe-exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NsuhsZCTmqEm" + }, + "source": [ + "# Visualizar os dados\n", + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D0JNMHqYoSMs" + }, + "source": [ + "# Mostra a matriz de correlação usando a correlação de Pearson\n", + "set_Colunas_Correlacionadas = set()\n", + "matriz_correlacao = df_X.corr().where(np.triu(np.ones(df_X.corr().shape), k = 1).astype(np.bool))\n", + "matriz_correlacao" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6scRm8kNnbby" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "# Gerando um dataframe com 15 colunas, sendo 9 informativas e 6 redundantes:\n", + "from sklearn.datasets import make_classification\n", + "X, y = make_classification(n_samples=1000, n_features=15, n_informative=9,\n", + " n_redundant=6, n_repeated=0, n_classes=2, n_clusters_per_class=1,\n", + " random_state=20111974)\n", + "\n", + "df_X = pd.DataFrame(X, columns= ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15'])\n", + "df_y = pd.DataFrame(y, columns= ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vnj6A8z6r7nM" + }, + "source": [ + "### Quem são as colunas altamente correlacionadas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a_YUD-dOr_p-" + }, + "source": [ + "for i in range(len(matriz_correlacao.columns)):\n", + " for j in range(i):\n", + " if abs(matriz_correlacao.iloc[i, j]) > 0.8:\n", + " colnome = matriz_correlacao.columns[i]\n", + " set_Colunas_Correlacionadas.add(colnome)\n", + "\n", + "set_Colunas_Correlacionadas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-0Xe6GdozYT" + }, + "source": [ + "A seguir, a correlação mais visual:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5-_Qadx1o1U9" + }, + "source": [ + "fig, ax = plt.subplots(figsize = (12, 12)) \n", + "mask = np.zeros_like(df_X.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_X.corr().abs(), mask= mask, ax= ax, cmap='coolwarm', annot= True, fmt= '.2f', center= 0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ZOp9ZGgtqFQ" + }, + "source": [ + "# **Scatterplot**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eReJJjG8tuKV" + }, + "source": [ + "## Com regressão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tVmdSo6ztruA" + }, + "source": [ + "sns.pairplot(df_X, kind = \"reg\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xG9A6b32twv-" + }, + "source": [ + "## Sem regressão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fyTOS3zVtz-O" + }, + "source": [ + "sns.pairplot(df_X, kind = \"scatter\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f-1bpipc6bMh" + }, + "source": [ + "___\n", + "# **Salvar dataframe como csv**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "64CoM1aY6gf6" + }, + "source": [ + "df_X.to_csv('example.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oy646p33DJV0" + }, + "source": [ + "# **Dicionário de palavras**\n", + "> Muito utilizado em NLP e Machine Learning.\n", + "* Caso de Uso: Seguradoras --> Quando um segurado aciona a Seguradora para descrever um acidente (por exemplo), há um algorítmo que transforma o áudio em texto para mineração de textos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DQR906rVD1V-" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sHvDaztJDPP7" + }, + "source": [ + "from sklearn.feature_extraction.text import CountVectorizer\n", + "CountVectorizer = CountVectorizer()\n", + "matriz_contagens = CountVectorizer.fit_transform(df_Titanic['name']) # Informe a coluna do tipo texto/string que queremos analisar/avaliar\n", + "print(matriz_contagens)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jwT-56dED8VJ" + }, + "source": [ + "df_dicionario_palavras = pd.DataFrame(CountVectorizer.get_feature_names(), columns = ['palavra'])\n", + "df_dicionario_palavras[\"vezes_que_aparece\"] = matriz_contagens.sum(axis = 0).tolist()[0]\n", + "df_dicionario_palavras = df_dicionario_palavras.sort_values(\"vezes_que_aparece\", ascending = False) #.reset_index(drop = True)\n", + "df_dicionario_palavras.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nx65RmEAGTvd" + }, + "source": [ + "# Desafio\n", + "> Transforme o code Python da sessão **Dicionário de palavras** em função para usarmos futuramente." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iwd1lhq9mrD3" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o_cl0kFgQfFh" + }, + "source": [ + "## Exercício 1\n", + "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s8rQUo7yHKJ1" + }, + "source": [ + "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KTun1uSLuJ-A" + }, + "source": [ + "## Exercício 2\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Soq7GVZnuREq" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6KEsTARfvM1C" + }, + "source": [ + "## Exercício 3\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hgxE5gZ9vMEg" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K1', 'K0', 'K1'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K0', 'K0', 'K0'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iv7AmZ1ivm8R" + }, + "source": [ + "### Perguntas\n", + "* Qual o output e a interpretação dos comandos a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TWAW_1tuvvSO" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QjM7pBONvzCJ" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D1Rr3Ghsv2iS" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vXQwLjT-v3Iu" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EIdltTC-t_lF" + }, + "source": [ + "## Exercício 5\n", + "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bMwPLgWclWBq" + }, + "source": [ + "___\n", + "## Exercício 6\n", + "* (a) Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN).\n", + "\n", + "### Feature Engineering\n", + "* (b) Com a coluna 'cabin', construir as colunas:\n", + " * deck - Letra de Cabin;\n", + " * seat - Número de Cabin\n", + "* (c) Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n", + "* (d) Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n", + "* (e) Discretizar a coluna 'fare' em 10 buckets.\n", + "* (f) Discretizar a coluna 'age'.\n", + "* (g) Capturar os títulos 'Ms', 'Mr' e etc contidos na coluna 'Title';\n", + "* (h) Qual a relação entre as variáveis e a variável-target?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V7KUGAX6lilP" + }, + "source": [ + "import pandas as pd\n", + "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/MathMachado/Python4DS/DS_Python/Dataframes/Titanic_With_MV.csv?token =AGDJQ63MNPPPROFNSO2BZW25XSR72', index_col= 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m3UnAPJakCLR" + }, + "source": [ + "* Segue o dicionário de dados do dataframe Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B_3s5cgxfNKQ" + }, + "source": [ + "## Resposta do item (a)\n", + "### Coluna XPTO\n", + "\n", + "\n", + "### Coluna XPTO2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q3oLgyhdL6xd" + }, + "source": [ + "## Resposta do item (b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbexhGtayV4X" + }, + "source": [ + "## Exercício 7\n", + "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Iia0ikd_KBtH" + }, + "source": [ + "## Exercício 8\n", + "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HPiLKUkWNYs3" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ldWQd9j4NhPS" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_01__Pandas_hs2.ipynb b/Notebooks/NB10_01__Pandas_hs2.ipynb new file mode 100644 index 000000000..d4b3c0c78 --- /dev/null +++ b/Notebooks/NB10_01__Pandas_hs2.ipynb @@ -0,0 +1,5534 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Copy of NB10_01__Pandas.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8fpUiw8PwC7_" + }, + "source": [ + "

PANDAS PARA DATA ANALYSIS

\n", + "\n", + "\n", + "\n", + "# **AGENDA**:\n", + "\n", + "> Veja o **índice** dos itens que serão abordados neste capítulo.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vo7mtiNSr_Wk" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [Learn Aggregation and Data Wrangling with Python](https://data-flair.training/blogs/data-wrangling-with-python/)\n", + "* [Python Data Cleansing by Pandas & Numpy | Python Data Operations](https://data-flair.training/blogs/python-data-cleansing/)\n", + "* [Pandas from basic to advanced for Data Scientists](https://towardsdatascience.com/pandas-from-basic-to-advanced-for-data-scientists-aee4eed19cfe)\n", + "* [Feature engineering and ensembled models for the top 10 in Kaggle “Housing Prices Competition”](https://towardsdatascience.com/feature-engineering-and-ensembled-models-for-the-top-10-in-kaggle-housing-prices-competition-efb35828eef0)\n", + "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n", + "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n", + "* [Gaining a solid understanding of Pandas series](https://towardsdatascience.com/gaining-a-solid-understanding-of-pandas-series-893fb8f785aa)\n", + "* [ariáveis Dummy: o que é? Quando usar? E como usar?](https://medium.com/data-hackers/vari%C3%A1veis-dummy-o-que-%C3%A9-quando-usar-e-como-usar-78de66cfcca9)\n", + "* [Exploratory Data Analysis Made Easy Using Pandas Profiling](https://towardsdatascience.com/exploratory-data-analysis-made-easy-using-pandas-profiling-86e347ef5b65)\n", + "* [Data Handling using Pandas; Machine Learning in Real Life](https://towardsdatascience.com/data-handling-using-pandas-machine-learning-in-real-life-be76a697418c)\n", + "* [Exploratory Data Analysis Tutorial in Python](https://towardsdatascience.com/exploratory-data-analysis-tutorial-in-python-15602b417445)\n", + "* [Exploring the data using python](https://towardsdatascience.com/exploring-the-data-using-python-47c4bc7b8fa2)\n", + "* [A better EDA with Pandas-profiling](https://towardsdatascience.com/a-better-eda-with-pandas-profiling-e842a00e1136)\n", + "* [Exploratory Data Analysis: Haberman’s Cancer Survival Dataset](https://towardsdatascience.com/exploratory-data-analysis-habermans-cancer-survival-dataset-c511255d62cb)\n", + "* [Exploring Exploratory Data Analysis](https://towardsdatascience.com/exploring-exploratory-data-analysis-1aa72908a5df)\n", + "* [Getting started with Data Analysis with Python Pandas](https://towardsdatascience.com/getting-started-to-data-analysis-with-python-pandas-with-titanic-dataset-a195ab043c77)\n", + "* [A Gentle Introduction to Exploratory Data Analysis](https://towardsdatascience.com/a-gentle-introduction-to-exploratory-data-analysis-f11d843b8184)\n", + "* [Exploratory Data Analysis (EDA) techniques for Kaggle competition beginners](https://towardsdatascience.com/exploratory-data-analysis-eda-techniques-for-kaggle-competition-beginners-be4237c3c3a9)\n", + "* [What is Exploratory Data Analysis?](https://towardsdatascience.com/exploratory-data-analysis-8fc1cb20fd15)\n", + "* [Exploring real estate investment opportunity in Boston and Seattle](https://towardsdatascience.com/exploring-real-estate-investment-opportunity-in-boston-and-seattle-9d89d0c9bed2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BUEbp88oD1Km" + }, + "source": [ + "___\n", + "# **ANÁLISE DE DADOS COM PANDAS**\n", + "## Highlights\n", + "\n", + "* Rápida e eficiente library para data manipulation;\n", + "* Ferramentas para ler e gravar todos os tipos de dados e formatos: CSV, txt, Microsoft Excel, SQL databases, JSON e HDF5 format;\n", + "* Pandas é a library mais popular para análise de dados. As principais ações que faremos com Pandas são:\n", + " * Ler/gravar diferentes formatos de dados;\n", + " * Selecionar subconjuntos de dados;\n", + " * Cálculos variados por coluna ou por linha das tabelas;\n", + " * Encontrar e tratar Missing Values;\n", + " * Combinar múltiplos dataframes;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wkxQFPPmeKLl" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eKawOG-neqaD" + }, + "source": [ + "![Pandas](https://github.com/MathMachado/Materials/blob/master/Pandas2.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TLdSmsJZwlcQ" + }, + "source": [ + "___\n", + "# **ATÉ QUE VOLUME DE DADOS PODEMOS USAR PANDAS?**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O7YKF5gB2x0K" + }, + "source": [ + "![RightToolForEachSize](https://github.com/MathMachado/Materials/blob/master/SizesAndTools.PNG?raw=true)\n", + "\n", + "## Sources\n", + "### Dask\n", + "* [Pandas, Dask or PySpark? What Should You Choose for Your Dataset?](https://medium.com/datadriveninvestor/pandas-dask-or-pyspark-what-should-you-choose-for-your-dataset-c0f67e1b1d36)\n", + "* [Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165)\n", + "* [Pandas, Fast and Slow](https://medium.com/when-i-work-data/pandas-fast-and-slow-b6d8dde6862e)\n", + "* [Por que Parquet](https://medium.com/when-i-work-data/por-que-parquet-2a3ec42141c6)\n", + "* [How to Run Parallel Data Analysis in Python using Dask Dataframes](https://towardsdatascience.com/trying-out-dask-dataframes-in-python-for-fast-data-analysis-in-parallel-aa960c18a915)\n", + "* [Why every Data Scientist should use Dask?](https://towardsdatascience.com/why-every-data-scientist-should-use-dask-81b2b850e15b)\n", + "\n", + "### Spark, Koalas\n", + "* [Databricks Koalas-Python Pandas for Spark](https://medium.com/future-vision/databricks-koalas-python-pandas-for-spark-ce20fc8a7d08)\n", + "* [Bye Pandas, Meet Koalas: Pandas APIs on Apache Spark (Ep. 4)](https://medium.com/@kyleake/bye-pandas-meet-koalas-pandas-apis-on-apache-spark-ep-4-aedcd363cf4e)\n", + "* [Koalas: Easy Transition from pandas to Apache Spark](https://databricks.com/blog/2019/04/24/koalas-easy-transition-from-pandas-to-apache-spark.html?source=post_page-----aedcd363cf4e----------------------)\n", + "* [Use PySpark for Your Next Big Problem](https://medium.com/swlh/use-pyspark-for-your-next-big-problem-8aa288d5ecfa)\n", + "* [A Neanderthal’s Guide to Apache Spark in Python](https://towardsdatascience.com/a-neanderthals-guide-to-apache-spark-in-python-9ef1f156d427)\n", + "* [The Jungle of Koalas, Pandas, Optimus and Spark](https://towardsdatascience.com/the-jungle-of-koalas-pandas-optimus-and-spark-dd486f873aa4)\n", + "* [From Pandas to PySpark with Koalas](https://towardsdatascience.com/from-pandas-to-pyspark-with-koalas-e40f293be7c8)\n", + "\n", + "# O que Dask?\n", + "\n", + "\"Dask is designed to extend the numpy and pandas packages to work on data processing problems that are too large to be kept in memory. It breaks the larger processing job into many smaller tasks that are handled by numpy or pandas and then it reassembles the results into a coherent whole.\" - Eric Ness ([Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yEyzjGUfG33-" + }, + "source": [ + "___\n", + "# **Carregar a library Pandas e verificar a versão**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oVMjT3DrG97K" + }, + "source": [ + "# Carrega a library Pandas\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "import locale # Nova importação\n", + "\n", + "print(f'Versão do Pandas: {pd.__version__}')\n", + "print(f'Versão do NumPy.: {np.__version__}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OxoDsaKUVHdH" + }, + "source": [ + "# Configurações\n", + "> Podemos configurar o pandas de forma a tornar nosso trabalho mais produtivo. Podemos configurar, por exemplo, o número de LINHAS e COLUNAS a ser mostrado, precisão dos números float. Vamos ver com mais detalhes a seguir.\n", + "\n", + "Fonte: [5 Advanced Features of Pandas and How to Use Them](https://www.kdnuggets.com/2019/10/5-advanced-features-pandas.html)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOdqrf7uVlhC" + }, + "source": [ + "d_configuracao = {\n", + " 'display.max_columns': 1000,\n", + " 'display.expand_frame_repr': True,\n", + " 'display.max_rows': 10,\n", + " 'display.precision': 2,\n", + " 'display.show_dimensions': True\n", + " }\n", + "\n", + "for op, value in d_configuracao.items():\n", + " pd.set_option(op, value)\n", + " print(op, value)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "plpT_-jFTCjO" + }, + "source": [ + "# OUTRA FORMA DE CONFIGURAR A EXIBIÇÃO\n", + "# cria variável pdod (iniciais de pd.options.display)\n", + "# usa método do Pandas para ajustar opções de display de dados\n", + "# locale.setlocale(locale.LC_NUMERIC, 'pt_BR') ## DEU ERRO - verificar depois\n", + "pdod = pd.options.display\n", + "pdod.max_rows = 100\n", + "pdod.min_rows = 50\n", + "pdod.max_columns = None\n", + "# pdod.float_format = '{:.2f}'.format \n", + "pdod.float_format = lambda x: locale.format_string('%.2f', x, grouping=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-vJufa3WTrG_" + }, + "source": [ + "dir(pd.options.display)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Paz-R-FOAJ7F" + }, + "source": [ + "___\n", + "# **Criar um dataframe a partir de outros objetos**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L4Jc0C2qPAQz" + }, + "source": [ + "## Criar dataframe a partir de dicionários" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Sa5rKwq6Fscj" + }, + "source": [ + "### Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0ofIGkiSSuYq" + }, + "source": [ + "d_frutas = {'Apple': [5, 6, 6, 8, 10, 3, 2],\n", + " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iJCNvPlUTzTI" + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7Y_0O_tJTfm3" + }, + "source": [ + "# index=['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'] abaixo define os label.\n", + "df_frutas = pd.DataFrame(d_frutas, index = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'])\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l2ll8ktfUKz2" + }, + "source": [ + "O que se comprou na sexta?\n", + "\n", + "* Função df.loc[label] retorna o(s) valor(es) associados à label. Em nosso caso, os label (chaves do dicionário) são 'Seg', 'Ter', ..., 'Dom'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9Voor8_PUJum" + }, + "source": [ + "df_frutas.loc['Sex'] # Aqui, label= 'Sex'." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LMh4DTfebwAr" + }, + "source": [ + "* Ou seja, o label = 'Sex', que ocupa a posição 4, tem os valores:\n", + " * Apple..: 10\n", + " * Avocado: 3\n", + "\n", + "Da mesma forma, poderíamos utilizar a função df.iloc[index] para retornar o conteúdo/informações de index." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GJxawdh6bvJN" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "obJt9OPGcL-x" + }, + "source": [ + "Portanto, df.loc['Sex'] = df.iloc[4]. Correto?\n", + "\n", + "Para nos ajudar a memorizar, considere que:\n", + "\n", + "* pd.loc[label] --> loc começa com a letra **l**, o que remete à label da linha.\n", + "* pd.iloc[indice] --> iloc começa com a letra **i**, o que remete ao índice (inteiro) da linha." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v7QlCcEorEIX" + }, + "source": [ + "#### Qual é o output do code abaixo?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kRRdQShrrKHk" + }, + "source": [ + "df_frutas.loc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EkjAtbrRF01h" + }, + "source": [ + "### Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2EOX5MC4E1xL" + }, + "source": [ + "Na prática, lidamos com grandes bancos de dados e, nesses casos, não temos label das LINHAS definidos. Para exemplificar, considere o mesmo exemplo que acabamos de ver, com uma pequena alteração:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RC_OXmdjrkQm" + }, + "source": [ + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D6FckgDPFFs0" + }, + "source": [ + "df_frutas = pd.DataFrame(d_frutas) # Observe que aqui não definimos os indíces\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tkGc4JQcFPkp" + }, + "source": [ + "Veja agora que os label são números inteiros de 0 a N." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ri-EdUYAovLG" + }, + "source": [ + "#### Qual o conteúdo da linha cujo label é 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5YgWG_vlFVe_" + }, + "source": [ + "df_frutas.loc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFQxcAcVo2KD" + }, + "source": [ + "#### Qual o conteúdo da linha cujo índice é 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xB1j4n6HFank" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEbCke3TFf_q" + }, + "source": [ + "Ou seja, nesses casos, tanto faz usar pd.loc[] ou pd.iloc[]. Entendeu?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bKHw_VBKjkoL" + }, + "source": [ + "### Exemplo 3 - Definir os indices do dataframe usando df.set_index()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "13ArWIhYju6s" + }, + "source": [ + "d_frutas= {'Dia_Semana': ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'],\n", + " 'Apple': [5, 6, 6, 8, 10, 3, 2],\n", + " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}\n", + "\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Evw9w16gk5h0" + }, + "source": [ + "# Cria o dataframe df_frutas:\n", + "df_frutas = pd.DataFrame(d_frutas) # Não apontamos o índice do dataframe. Portanto, o índice é criado automaticamente de 0.. N.\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NLbbRrdYoclw" + }, + "source": [ + "#### Qual o conteúdo da linha 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lB-ngbutl_0c" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1aJLGapZlUFI" + }, + "source": [ + "# Definir 'Dia_Semana' como índice (label das linhas) do dataframe df_frutas\n", + "df_frutas.set_index('Dia_Semana', inplace = True)\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "L1-U_sD-jAoO" + }, + "source": [ + "A expressão acima é equivalente a:\n", + "\n", + "```\n", + "df_frutas2 = df_frutas.set_index('Dia_Semana') # Observe que aqui não há 'inplace'\n", + "df_frutas2\n", + "```\n", + "\n", + "* Então, qual a função do 'inplace =True' na primeira opção?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oXeFjJonpQfB" + }, + "source": [ + "#### Qual o conteúdo da linha 4?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MMXg3vVQpUhh" + }, + "source": [ + "df_frutas.iloc[4]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fhoYuGMlpVFj" + }, + "source": [ + "#### Qual o conteúdo da linha cujo label é 'Sex'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fmcWbrEspdYW" + }, + "source": [ + "df_frutas.loc['Sex']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bobggpoCTRkj" + }, + "source": [ + "### Qual a diferença entre as duas próximas linhas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SjiYgbNrsvpl" + }, + "source": [ + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OFhzE7hgTD0a" + }, + "source": [ + "df_frutas.mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V42I3807TNte" + }, + "source": [ + "df_frutas.mean(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6iUCthsbtLV8" + }, + "source": [ + "df_frutas.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YdkmYePYtcON" + }, + "source": [ + "df_frutas.dtypes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2RmgCIC2HZFp" + }, + "source": [ + "### Exemplo 4" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kbHHuMzzAR1A" + }, + "source": [ + "d_estudantes = {'nome': ['Jack', 'Richard', 'Tommy', 'Ana'], \n", + " 'age': [25, 34, 18, 21],\n", + " 'city': ['Sydney', 'Rio de Janeiro', 'Lisbon', 'New York'],\n", + " 'country': ['Australia', 'Brazil', 'Portugal', 'United States']}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayKqLmHTANOu" + }, + "source": [ + "# Mostrar o conteúdo do dicionário d_estudantes...\n", + "d_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0ONA8QsBBP6R" + }, + "source": [ + "# Keys associadas ao dicionário d_estudantes\n", + "d_estudantes.keys()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "k8mmvKQ_BjO6" + }, + "source": [ + "# Itens associados ao dicionário d_estudantes\n", + "d_estudantes.items()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcm8V_UmBr1Y" + }, + "source": [ + "# Valores associados ao dicionário d_estudantes\n", + "d_estudantes.values()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KK7IejsPDkWC" + }, + "source": [ + "Temos uma key = 'nome'. Qual o conteúdo desta key?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eHvPpeiTBwoR" + }, + "source": [ + "d_estudantes['nome']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "S1y7p8CcDsXl" + }, + "source": [ + "Qual o output da expressão a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "26WIDl-HB3Bq" + }, + "source": [ + "d_estudantes['nome'][0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gV68kQ5HCIif" + }, + "source": [ + "Criando o dataframe df_estudantes a partir do dicionário d_estudantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2oa808hkCSaq" + }, + "source": [ + "df_estudantes = pd.DataFrame(d_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7HLp0FYpCiSc" + }, + "source": [ + "# Mostra o conteúdo do dataframe df_estudantes...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "en06lfazciE0" + }, + "source": [ + "**Atenção**: Observe que nesse caso, não definimos labels para as LINHAS. Na prática, isso é o mais comum, ou seja, os label = index, que aqui são números inteiros de 0 a N." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gFaPp-S-cy1-" + }, + "source": [ + "Mais uma vez, vamos usar df.loc[] e df.iloc[]..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mT9vwRBidGXX" + }, + "source": [ + "# Mostrando o conteúdo de da linha 3 usando df.loc[]\n", + "df_estudantes.loc[3]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zj88AwHUdix0" + }, + "source": [ + "OU" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SP2mG8todkMe" + }, + "source": [ + "# Mostrando o conteúdo de da linha 3 usando df.iloc[]\n", + "df_estudantes.iloc[3]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hzbLO0EDGWTf" + }, + "source": [ + "Ok, já discutimos isso anteriormente. Quando não temos labels para as LINHAS, então iloc[] = loc[]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VvzVg7SpeOOB" + }, + "source": [ + "___\n", + "## Criar dataframes a partir de listas\n", + "* Considere a lista de frutas a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_PY9OROeUiT" + }, + "source": [ + "l_frutas = [('Melon', 6, 8, 5, 4 ,6, 2, 8), ('Avocado', 6, 6, 3, 8, 9, 3, 1), ('Blueberry', 7, 5, 9, 3, 1, 0, 4)]\n", + "l_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AfE_rHq5g4_P" + }, + "source": [ + "type(l_frutas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZpdPSi7RgVjK" + }, + "source": [ + "l_frutas[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NMyIpVW8gZTH" + }, + "source": [ + "l_frutas[0][0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-cyZVqQFhjjg" + }, + "source": [ + "# Lista contendo os nomes das COLUNAS do dataframe:\n", + "l_colunas = ['Frutas', 'Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']\n", + "l_colunas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wplKvgayfZm_" + }, + "source": [ + "# Convertendo as listas em dataframe\n", + "df_frutas = pd.DataFrame(l_frutas, columns = l_colunas) # Observe que aqui, o nome das COLUNAS é uma lista.\n", + "df_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GojgsAXTFZmB" + }, + "source": [ + "___\n", + "# **Copiar dataframes**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gCkqcDo8X_ld" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_Tda4ZwjWIW" + }, + "source": [ + "O dataframe df_estudantes tem o seguinte conteúdo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P5y0aVkdkA8o" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cp3bvPEqj5fS" + }, + "source": [ + "se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2PT5L11j8O0" + }, + "source": [ + "df_estudantes2 = df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2D29pGuikBBK" + }, + "source": [ + "então df_estudantes2 tem o mesmo conteúdo de df_estudantes, ok?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_IseZEpLkGS4" + }, + "source": [ + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "29MpozLrkI83" + }, + "source": [ + "Agora altere o valor 'Rio de Janeiro' para 'Sao Paulo' no dataframe df_estudantes2." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TXCqFiGFkmyv" + }, + "source": [ + "df_estudantes2['city'] = df_estudantes2['city'].replace({'Rio de Janeiro': 'Sao Paulo'})\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_0mgT7-8Fsl" + }, + "source": [ + "# OU\n", + "alteracoes = {'Rio de Janeiro': 'Sao Paulo'}\n", + "df_estudantes2['city'] = df_estudantes2['city'].replace(alteracoes)\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN8ZGu2Xk6vt" + }, + "source": [ + "Ok, alteramos o valor 'Rio de Janeiro' por 'Sao Paulo', como queríamos. Vamos ver o conteúdo de df_estudantes (**que está intacto, pois fizemos a alteração no dataframe df_estudantes2**)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "thNAWoDflRoQ" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VkIS8wVmlAyq" + }, + "source": [ + "Ooooops... df_estudantes foi alterado? Como, se procedemos a alteração em df_estudantes2 e NÃO em df_estudantes???\n", + "\n", + "* **As operações que fizermos em df_estudantes2 também serão aplicadas à df_estudantes**?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e9u-Z9NMltC9" + }, + "source": [ + "**Resposta**: SIM, pois df_estudantes2 é um ponteiro para df_estudantes. Ou seja, **qualquer operação que fizermos em df_estudantes2 será feita em df_estudantes**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IDwvsxhhmlE4" + }, + "source": [ + "Uma forma fácil de ver isso é através dos endereços de memória dos dois (**supostos diferentes**) dataframes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ePFwKua8mu7k" + }, + "source": [ + "id(df_estudantes2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bMvY_E0mmwQH" + }, + "source": [ + "id(df_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K5qC5BuzmyF0" + }, + "source": [ + "**Conclusão**: df_estudantes2 é ponteiro para df_estudantes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZZ50ejRImAQ8" + }, + "source": [ + "## Forma correta de fazer a cópia de um dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oTbzxNkDmQiJ" + }, + "source": [ + "Primeiramente, vamos reconstruir df_estudantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DmVq0vM0mTtQ" + }, + "source": [ + "df_estudantes = pd.DataFrame(d_estudantes)\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oZrlwtqJmYB_" + }, + "source": [ + "Fazendo a cópia do dataframe (**da forma correta**):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "No5A7nHDFbsy" + }, + "source": [ + "df_estudantes_Copy = df_estudantes.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NvKNFr8RnEft" + }, + "source": [ + "Vamos verificar os endereços de memória dos dois dataframes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0_OO90SFki4f" + }, + "source": [ + "id(df_estudantes_Copy)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T0BibX8rkes5" + }, + "source": [ + "id(df_estudantes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbm-8cCUFgJa" + }, + "source": [ + "Agora, dataframe df_estudantes_Copy é uma cópia do dataframe df_estudantes" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SuL8WUxL-u6-" + }, + "source": [ + "___\n", + "# **Renomear COLUNAS do dataframe**\n", + "> **Snippet**: \n", + "\n", + " * df.rename(columns = {'Old_Name': 'New_Name'}, inplace = True)\n", + " * OU df = df.rename(columns = {'Old_Name': 'New_Name'})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IvpCfmQnIZKl" + }, + "source": [ + "Suponha que quero renamear a COLUNA 'nome' para 'nome_cliente', que é um nome mais sugestivo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o54Fa-yxnmuz" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FwzXjYJgCvGk" + }, + "source": [ + "df_estudantes= df_estudantes.rename(columns = {'nome': 'nome_cliente'})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gOolGiWt4A18" + }, + "source": [ + "O comando abaixo produz o mesmo resultado que a linha anterior:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y6jjAFRd341e" + }, + "source": [ + "```\n", + "df_estudantes.rename(columns= {'nome': 'nome_cliente'}, inplace = True)\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DwVMldKiF5gS" + }, + "source": [ + "# Mostrando o conteúdo de df_estudantes após renamearmos a coluna/variável 'nome' para 'Clien_Name'...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m-WZBLWqELOv" + }, + "source": [ + "Agora, suponha que queremos renamear 'age' para 'idade_cliente', 'city' para 'cidade_cliente' e 'country' para 'pais_cliente'..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS6ua4u1EX5g" + }, + "source": [ + "df_estudantes.rename(columns = {'age': 'idade_cliente', 'city': 'cidade_cliente', 'country': 'pais_cliente'}, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i_7LW07y4SvO" + }, + "source": [ + "O comando abaixo produz o mesmo resultado que a linha anterior:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9X-cv9RL4WjV" + }, + "source": [ + "```\n", + "df_estudante = df_estudantes.rename(columns= {'Age': 'idade_cliente', 'City': 'cidade_cliente', 'Country': 'pais_cliente'}, inplace = True)\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EOb1-TEKGM9I" + }, + "source": [ + "# Mostrando o conteúdo de df_estudantes após a múltipla operação de renamear...\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q0IZZjLRJlU6" + }, + "source": [ + "Alguma dúvida até aqui?\n", + "Tudo bem até aqui?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5LwL2m5KbLYz" + }, + "source": [ + "## Challenge\n", + "* Aplicar lowercase() em todas as COLUNAS do dataframe df_estudantes. Como fazer isso?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MURfzmeLbUzF" + }, + "source": [ + "### Minha solução:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r-FgBY-3xBi9" + }, + "source": [ + "df_estudantes2 = df_estudantes.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hlSlfcoub8gH" + }, + "source": [ + "# Colocar o nome das COLUNAS numa lista:\n", + "l_colunas = df_estudantes2.columns\n", + "l_colunas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_IGvEK4bdQP" + }, + "source": [ + "# Lowercase todas as COLUNAS\n", + "df_estudantes2.columns = [col.lower() for col in l_colunas]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0qzzAa3ycKmF" + }, + "source": [ + "# Mostrando o conteúdo do dataframe df_estudantes\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c-u-ndMPV_KX" + }, + "source": [ + "___\n", + "# **Adicionar/Acrescentar novas LINHAS ao dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MDkWbukBLhw7" + }, + "source": [ + "## Usando dicionários\n", + "* É necessário informar {'Column_Name': value} para cada inserção. Por exemplo, vou adicionar o seguinte registro ao dataframe:\n", + " * nome_cliente= 'Anderson';\n", + " * idade_cliente= 22;\n", + " * cidade_cliente= 'Porto';\n", + " * pais_cliente= 'Portugal'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GECPO7iyK9UU" + }, + "source": [ + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XQKqqC93LoQ_" + }, + "source": [ + "df_estudantes_Copia= df_estudantes.copy()\n", + "df_estudantes.append({'nome_cliente': 'Anderson', \n", + " 'idade_cliente': 22,\n", + " 'cidade_cliente': 'Porto',\n", + " 'pais_cliente': 'Portugal'}, ignore_index = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bdBttsHNLjd-" + }, + "source": [ + "Esse é o resultado que desejamos?\n", + "Saberia explicar-nos o que houve de errado?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6jDoq6CCMerp" + }, + "source": [ + "**DICA**: Lembre-se que no passo anterior, reescrevemos os nomes das COLUNAS usando o método lower()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ffReAaUHLvEF" + }, + "source": [ + "# Definindo df_estudantes novamente usando a cópia df_estudantes_Copia\n", + "df_estudantes = df_estudantes_Copia.copy()\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EzTo-IvmM2Fg" + }, + "source": [ + "Ok, restabelecemos a cópia de df_estudantes. Agora vamos à forma correta:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRhE76i4M6d6" + }, + "source": [ + "df_estudantes = df_estudantes.append({'nome_cliente': 'Anderson', \n", + " 'idade_cliente': 22,\n", + " 'cidade_cliente': 'Porto',\n", + " 'pais_cliente': 'Portugal'}, ignore_index= True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jAojB2MMNDRJ" + }, + "source": [ + "Bom, esse é o resultado que estávamos à espera..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5czZb-5wNp_F" + }, + "source": [ + "## Usando Series\n", + "* Como exemplo, considere que queremos adicionar os seguintes dados:\n", + " * nome_cliente= 'Bill';\n", + " * idade_cliente= 30;\n", + " * cidade_cliente= 'São Paulo';\n", + " * pais_cliente= 'Brazil'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3qCydqMNtGt" + }, + "source": [ + "novo_estudante = pd.Series(['Bill', 30, 'Sao Paulo', 'Brazil'], index= df_estudantes2.columns) # Olha que interessante: estamos a usar index= df_estudantes.columns." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_DyMDrNPrmC" + }, + "source": [ + "Vamos ver o conteúdo de novo_estudante:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jDQUl0RBPoLB" + }, + "source": [ + "novo_estudante" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zMKRNQrsPvxp" + }, + "source": [ + "Por fim, adiciona/acrescenta novo_estudante ao dataframe df_estudantes..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5mEQg26iPw4A" + }, + "source": [ + "df_estudantes2 = df_estudantes2.append(novo_estudante, ignore_index= True)\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Biwk2McAWW1Z" + }, + "source": [ + "___\n", + "# **Adicionar/acrescentar novas COLUNAS ao Dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EZFTH7A-Wpw5" + }, + "source": [ + "## Usando Lists\n", + "* Suponha que queremos adicionar a coluna/variável 'Score'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YzBKQo5epXP5" + }, + "source": [ + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pPoObAKJW6YF" + }, + "source": [ + "# Acrescentando ou criando a coluna/variável 'score' ao dataframe usando um objeto list\n", + "df_estudantes2['score'] = [500, 300, 200, 800, 700]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ocbh8sZqWsoW" + }, + "source": [ + "# Mostra o conteúdo do dataframe df_estudantes...\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZxfCMcVxYQgL" + }, + "source": [ + "> **Atenção**:\n", + "\n", + "* Se a quantidade de valores da lista forem menores que o número de LINHAS do dataframe, então o Python apresenta um erro.\n", + "* Se a coluna/variável que queremos inserir já existe no dataframe, então os valores serão atualizados com os novos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "34ntllD_YbNa" + }, + "source": [ + "## Usando um valor default\n", + "* Adicionar a coluna 'total' com o mesmo valor para todas as LINHAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T7QSMJMQYous" + }, + "source": [ + "df_estudantes['total'] = 500\n", + "df_estudantes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gll-gJt7as3C" + }, + "source": [ + "## Adicionar uma COLUNA calculada a partir de outras COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T_pB_isBaw-E" + }, + "source": [ + "df_estudantes2['percentagem'] = 100*(df_estudantes2['score']/sum(df_estudantes2['score']))\n", + "df_estudantes2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D9TNylt84hle" + }, + "source": [ + "___\n", + "# **Ler/carregar dados no Python**\n", + "* Vários formatos de arquivos podem ser lidos:\n", + "\n", + "|Format Type | Data Description | Reader | Writer |\n", + "|---|---|---|---|\n", + "text | CSV | read_csv | to_csv |\n", + "text | JSON | read_json | to_json |\n", + "text | HTML | read_html | to_html |\n", + "text | Local clipboard | read_clipboard | to_clipboard |\n", + "binary | MS Excel | read_excel | to_excel |\n", + "binary | HDF5 Format | read_hdf | to_hdf |\n", + "binary | Stata | read_stata | to_stata |\n", + "binary | SAS | read_sas \n", + "binary | Python Pickle Format | read_pickle | to_pickle |\n", + "SQL | SQL | read_sql | to_sql |\n", + "SQL | Google Big Query | read_gbq | to_gbq |\n", + "\n", + "* Fonte: [IO tools (text, CSV, HDF5, …)](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ss8jLEUSblDm" + }, + "source": [ + "___\n", + "# **Ler/Carregar csv**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n8e9aphab_oe" + }, + "source": [ + "# carregar a library Pandas\n", + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R2fRd_MSQ2Xa" + }, + "source": [ + "A seguir, vamos:\n", + "* Ler o dataframe Titanic.csv;\n", + "* Definir 'PassengerId' como índice/chave da tabela através do comando index_col= 'PassengerId'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1R9YoFJ02TR7" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/Titanic_With_MV.csv'\n", + "df_Titanic = pd.read_csv(url, index_col = 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS7_V15u0MgR" + }, + "source": [ + "df_Titanic.iloc[4] # NÃO É A MESMA COISA QUE df_Titanic.loc[4]!!!" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WJ9RlRDSkk0_" + }, + "source": [ + "* Segue o dicionário de dados do dataframe df_Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wz7Qd9mqMrfY" + }, + "source": [ + "# Show o dataframe df_Titanic:\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nDlANdnm4iod" + }, + "source": [ + "### DICA 1\n", + "Suponha que o dataframe que queremos ler esteja localizado em:\n", + "\n", + "```\n", + "/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes\n", + "```\n", + "\n", + "Desta forma, para ler o dataframe (local), basta usar o comando a seguir:\n", + "\n", + "```\n", + "url = '/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes/creditcard.csv'\n", + "df_Titanic = pd.read_csv(url)\n", + "```\n", + "\n", + "### Dica 2\n", + "No Windows, o diretório aparece, por exemplo, da seguinte forma: \n", + "```\n", + "C:\\nsolucoes4ds\\Data_Science\n", + "```\n", + "Observe as '\\\\' (**barras invertidas**). Neste caso, use o comando a seguir:\n", + "\n", + "```\n", + "url= r'C:\\nsolucoes4ds\\Data_Science\\creditcard.csv'\n", + "df_Titanic = pd.read_csv(url)\n", + "```\n", + "\n", + "Percebeu o r'diretorio'?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HubfewY8NgUv" + }, + "source": [ + "___\n", + "# **Corrigir (ou uniformizar) nome das COLUNAS**\n", + "* Por exemplo, reescrever o nome das COLUNAS usando lowercase()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4f_pEEOjvwjk" + }, + "source": [ + "Para facilitar nossas análises, vamos aplicar o método lower() em todos os valores das COLUNAS objects/strings. Para isso, considere a função abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ft13IahH1kVX" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-UlaHFPv7kp" + }, + "source": [ + "def transformacao_lower(df):\n", + " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n", + " df.columns = [col.lower() for col in df.columns]\n", + "\n", + " # Segunda transformação: Aplicar o método .str.lower() nos valores das COLUNAS object/strings:\n", + " l_cols_objeto = df.select_dtypes(include = ['object']).columns\n", + " \n", + " for col in l_cols_objeto:\n", + " df[col] = df[col].str.lower()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hNixsW8M7n1X" + }, + "source": [ + "Para saber mais sobre o método df[col].str.lower(), consulte [pandas.Series.str.lower](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.lower.html)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hz90zejtbxYj" + }, + "source": [ + "transformacao_lower(df_Titanic)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UE5P1W-CPePM" + }, + "source": [ + "# **Selecionar um subconjunto de colunas**\n", + "Suponha que eu queira selecionar somente as colunas 'Name' e 'Sex'." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P7HJa4x7P0bQ" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3jLZUCfePsBs" + }, + "source": [ + "df_Titanic2 = df_Titanic[['name', 'sex']]\n", + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PyNsYTilnL2r" + }, + "source": [ + "# map()\n", + "> Artificio para lidar com a transformação de dados utilizando um dicionário: {'key': valor}." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6z4FcyyAiTfF" + }, + "source": [ + "# Construindo uma variável mais intuitiva para nos ajudar nas análises:\n", + "df_Titanic['survived2'] = df_Titanic['survived']\n", + "df_Titanic['survived2'] = df_Titanic['survived2'].map({0:'died', 1:'survived'})\n", + "df_Titanic[['survived', 'survived2']].head(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwBWkaJOdhCv" + }, + "source": [ + "___\n", + "# **Selecionar COLUNAS do dataframe**\n", + "* Suponha que queremos selecionar somente as COLUNAS 'survived', 'sex' e 'embarked':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ivvj8JU2pBTq" + }, + "source": [ + "df_Titanic2 = df_Titanic[['survived', 'sex', 'embarked']]\n", + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nf-Wnof_fdTR" + }, + "source": [ + "___\n", + "# **Criar um dicionário a partir de um dataframe**\n", + "> Suponha o dataframe-exemplo a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lxf6Lgp4fit8" + }, + "source": [ + "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l7yzJu1y5huV" + }, + "source": [ + "De dataframe para Dicionário..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_6V0qFZGhEoF" + }, + "source": [ + "df.to_dict('dict')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0GIe6xtqPA1Z" + }, + "source": [ + "___\n", + "# **Criar uma lista a partir de um dataframe**\n", + "> Suponha o dataframe-exemplo a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fZxgejTtPLzX" + }, + "source": [ + "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JoShm6oF5qLV" + }, + "source": [ + "De dataframe para Lista..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gigPpSH_hlXu" + }, + "source": [ + "df.to_dict('list')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GpJDX-5xUUC0" + }, + "source": [ + "___\n", + "# **Mostrar as primeiras k LINHAS do dataframe**\n", + "> df.head(k), onde k é o número de LINHAS que queremos visualizar. Por default, k= 10." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RwC9j_OxUbIR" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G9cp2QrsA5M0" + }, + "source": [ + "___\n", + "# **Mostrar as últimas k LINHAS do dataframe**\n", + "> df.tail(k), onde k é o número de LINHAS que queremos ver. Por default, k= 10." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9mPxyhqoA4Wc" + }, + "source": [ + "df_Titanic.tail()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Odwm2qSLA_Ro" + }, + "source": [ + "Por default, df.tail() mostra as últimas 5 LINHAS/instâncias do dataframe. Entretando, pode ser ver qualquer número de LINHAS k, como, por exemplo, k= 10 mostrado abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUAnR00WA8ma" + }, + "source": [ + "df_Titanic.tail(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cZ64LfWv4zxo" + }, + "source": [ + "___\n", + "# **Mostrar o nome das COLUNAS do dataframe**\n", + "* df.columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CKUUrX5n4zFW" + }, + "source": [ + "df_Titanic.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6m7ukrOu5Inv" + }, + "source": [ + "___\n", + "# **Mostrar os tipos das COLUNAS do dataframe**\n", + "* Propriedade: df.dtypes --> Não há parênteses!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S4NIHAPPl9lc" + }, + "source": [ + "df_Titanic.dtypes # dtypes é uma propriedade, portanto não requer \"()\". Os métodos, por outro lado, requerem \"(arg1, arg2, ..., argN)\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DGc6m-UBdHlE" + }, + "source": [ + "___\n", + "# **Selecionar automaticamente as COLUNAS do dataframe pelo tipo**\n", + "> snippet: df.select_dtypes(include=[tipo]).columns\n", + "\n", + "| Tipo | O que seleciona | Sintaxe |\n", + "|------|-----------------|---------|\n", + "| number | colunas do tipo numéricas | df.select_dtypes(include=['number]).columns |\n", + "| float | colunas do tipo float | df.select_dtypes(include=['float']).columns |\n", + "| bool | colunas do tipo booleanas | df.select_dtypes(include=['bool']).columns |\n", + "| object | colunas do tipo categóricas/strings | df.select_dtypes(include=['object']).columns |\n", + "\n", + "* Se quisermos selecionar mais de um tipo, basta informar a lista de tipos. \n", + " * Exemplo: df.select_dtypes(include=['object', 'float']).columns\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O88YRCqIdYFL" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS Numéricas do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xG4a9ZfRnxPW" + }, + "source": [ + "### Lista com as COLUNAS numéricas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C87uga35dKsF" + }, + "source": [ + "l_cols_numericas = df_Titanic.select_dtypes(include = ['number']).columns # \".columns\" retorna a lista de colunas numéricas\n", + "l_cols_numericas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5W6kbIVNn2UA" + }, + "source": [ + "### DataFrame com as COLUNAS numéricas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTieUd_-eDmW" + }, + "source": [ + "df_numericas = df_Titanic.select_dtypes(include = ['number']) # Atenção: aqui não temos .columns --> Neste caso, o retorno será o dataframe.\n", + "df_numericas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xh4BFs_lds80" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS float do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tw3FD74MoC6q" + }, + "source": [ + "### Lista com as COLUNAS float:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5clAUAIrd3UR" + }, + "source": [ + "l_cols_float = df_Titanic.select_dtypes(include = ['float']).columns\n", + "l_cols_float" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IZPROG6IoHwy" + }, + "source": [ + "### DataFrame com as COLUNAS float:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "osJDsyMHeXX4" + }, + "source": [ + "df_float = df_Titanic.select_dtypes(include = ['float']) # Atenção: aqui não temos .columns\n", + "df_float.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5uObezIIfuJ4" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS Booleanas do dataframe" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xMKP5HhgoeMg" + }, + "source": [ + "### Lista com as COLUNAS Booleanas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3Pn2IPBkf7k-" + }, + "source": [ + "l_cols_booleanas = df_Titanic.select_dtypes(include = ['bool']).columns\n", + "l_cols_booleanas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "k3sdiuXYokBE" + }, + "source": [ + "### DataFrame com as COLUNAS Booleanas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Oem-M-17f7lG" + }, + "source": [ + "df_booleanas = df_Titanic.select_dtypes(include=['bool']) # Atenção: aqui não temos .columns\n", + "df_booleanas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ObHYW92-gOXz" + }, + "source": [ + "## Selecionar automaticamente as COLUNAS do tipo string (object)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IzM5CIKXoxHO" + }, + "source": [ + "### Lista com as COLUNAS do tipo object/string:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rdYThBingOX1" + }, + "source": [ + "l_cols_objeto = df_Titanic.select_dtypes(include=['object']).columns\n", + "l_cols_objeto" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2ZGB5d36o21t" + }, + "source": [ + "### DataFrame com as COLUNAS do tipo Object/String:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kWTtxeU4gOX4" + }, + "source": [ + "df_cols_obs = df_Titanic.select_dtypes(include=['object']) # Atenção: aqui não temos .columns\n", + "df_cols_obs.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SEBKHKRLkbUK" + }, + "source": [ + "___\n", + "# **Reordenar as COLUNAS do dataframe**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XRWfelWEkhae" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KBGDeR_JkyCc" + }, + "source": [ + "* Suponha que queremos reordenar as COLUNAS do dataframe df_Titanic em ordem alfabética, conforme abaixo:\n", + " * age;\n", + " * embarked;\n", + " * fare;\n", + " * parch;\n", + " * pclass;\n", + " * sex;\n", + " * sibsp;\n", + " * survived." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d9jJi6qllnq_" + }, + "source": [ + "# Dataframe ordenado\n", + "df_Titanic = df_Titanic.reindex(sorted(df_Titanic.columns), axis = 1)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cj4MREti-izC" + }, + "source": [ + "___\n", + "# **Mostrar a dimensão do dataframe**\n", + "* Dimensão = Número de LINHAS e COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "50Tij93l-n7B" + }, + "source": [ + "df_Titanic.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZQo4YeH_-qfL" + }, + "source": [ + "Qual a interpretação?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "klHcwpPEALP8" + }, + "source": [ + "## **Quebrar a dimensão em duas partes: número de LINHAS e COLUNAS**\n", + "* Número de linhas do dataframe.: df_Titanic.shape[0]\n", + "* Número de colunas do dataframe: df_Titanic.shape[1]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qjR8OEdDAOog" + }, + "source": [ + "f'O dataframe df_Titanic possui {df_Titanic.shape[0]} linhas e {df_Titanic.shape[1]} colunas.'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pIsf_nDtyAvF" + }, + "source": [ + "___\n", + "# **Combinar dataframes: Merge, Join & Concatenate**\n", + "* Fonte: [Merge, join, and concatenate](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s1fSplrlEMHK" + }, + "source": [ + "* A seguir, três formas para combinar dataframes:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6DYtWxuIrdzF" + }, + "source": [ + "## Concatenate\n", + "* Une/empilha dataframes\n", + "* Fonte: https://github.com/aakankshaws/Pandas-exercises" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nnP5VuWkri_b" + }, + "source": [ + "import pandas as pd\n", + "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rkJvSGYSrm8b" + }, + "source": [ + "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n", + " 'B': ['B4', 'B5', 'B6', 'B7'],\n", + " 'C': ['C4', 'C5', 'C6', 'C7'],\n", + " 'D': ['D4', 'D5', 'D6', 'D7']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NCgdYvJIrqx1" + }, + "source": [ + "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n", + " 'B': ['B8', 'B9', 'B10', 'B11'],\n", + " 'C': ['C8', 'C9', 'C10', 'C11'],\n", + " 'D': ['D8', 'D9', 'D10', 'D11']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gUoyjyjur5Zn" + }, + "source": [ + "df1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xU6Rh10Gr7NA" + }, + "source": [ + "df2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qKwmOWsQr9wA" + }, + "source": [ + "df3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-MNn-XdlsjJS" + }, + "source": [ + "df= pd.concat([df1, df2, df3])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BV6HgxSYtG6Z" + }, + "source": [ + "Veja que basicamente empilhamos os dataframes. No entanto, se fizermos..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Dp-oh-7ftLo5" + }, + "source": [ + "df = pd.concat([df1, df2, df3], axis = 1) # axis = 1 é uma operação de coluna\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iyDZt2XEtmVs" + }, + "source": [ + "Se, no entanto, tivermos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PAhjjVZtpP5" + }, + "source": [ + "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']},\n", + " index=[0, 1, 2, 3])\n", + "\n", + "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n", + " 'B': ['B4', 'B5', 'B6', 'B7'],\n", + " 'C': ['C4', 'C5', 'C6', 'C7'],\n", + " 'D': ['D4', 'D5', 'D6', 'D7']},\n", + " index=[4, 5, 6, 7])\n", + "\n", + "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n", + " 'B': ['B8', 'B9', 'B10', 'B11'],\n", + " 'C': ['C8', 'C9', 'C10', 'C11'],\n", + " 'D': ['D8', 'D9', 'D10', 'D11']},\n", + " index=[8, 9, 10, 11])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zGDHd-kPt3-T" + }, + "source": [ + "Então..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3bTl2Nr2t5WM" + }, + "source": [ + "df = pd.concat([df1, df2, df3], axis = 1)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sUXjlp_Jt925" + }, + "source": [ + "Porque isso acontece?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JdKXY873HrYt" + }, + "source": [ + "## Merge\n", + "> Primeiramente, vamos ver todos os casos possíveis de joins.\n", + "\n", + "### Exemplo\n", + "> O exemplo a seguir foi inspirado no exemplo apresentado em [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins). Considere os dataframes a seguir" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g4pmhk2t3x8s" + }, + "source": [ + "import pandas as pd\n", + "\n", + "d_Tabela_A = {'indices': [1,2,3,6,7,5,4,10], 'valores': ['A','B','C','D','E','F','G','H']}\n", + "d_Tabela_B = {'indices': [1,2,3,6,7,8,9,11], 'valores': ['AA', 'BB','CC','DD','EE','FF','GG','HH']}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XxfUULxY52ns" + }, + "source": [ + "df_conjunto_A = pd.DataFrame(d_Tabela_A).set_index('indices')\n", + "df_conjunto_B = pd.DataFrame(d_Tabela_B).set_index('indices')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gGdU36Vi0Yso" + }, + "source": [ + "![SQL_inner_join](https://github.com/MathMachado/Materials/blob/master/SQL_inner_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5w7ox7LV9cuG" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPhmKw-F9fWX" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5AaTlCPy9FBZ" + }, + "source": [ + "df_inner_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'inner')\n", + "df_inner_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U3OjFM0E0af-" + }, + "source": [ + "![SQL_left_join](https://github.com/MathMachado/Materials/blob/master/SQL_left_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-efYd9c69k4L" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SqFbNStz9k4S" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rUpc2k729KA-" + }, + "source": [ + "df_left_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'left')\n", + "df_left_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WioSBHjW06Hg" + }, + "source": [ + "![SQL_right_join](https://github.com/MathMachado/Materials/blob/master/SQL_right_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IrzPjGNp9o2n" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tFFTp_yG9o2s" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_D4tF7E-9PCx" + }, + "source": [ + "df_right_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'right')\n", + "df_right_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E9xFrurZ0ksg" + }, + "source": [ + "![SQL_outer_join](https://github.com/MathMachado/Materials/blob/master/SQL_outer_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kQCBAfj_9rO_" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FTDHYsgc9rP0" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "hJqyAs0U9XwO" + }, + "source": [ + "df_outer_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'outer')\n", + "df_outer_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fHEgLynu0vve" + }, + "source": [ + "![SQL_left_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_left_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZA8CcERE-RRS" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IZiAa9X6-UL0" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jdUt63rA-Vjo" + }, + "source": [ + "df_left_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"left_only\"')\n", + "df_left_excluding_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CShcqL-h1MqK" + }, + "source": [ + "![SQL_right_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_right_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ECjUDoYf_C9x" + }, + "source": [ + "df_conjunto_A" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xym7VsXi_FXa" + }, + "source": [ + "df_conjunto_B" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-zFalmly_HJ7" + }, + "source": [ + "df_right_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"right_only\"')\n", + "df_right_excluding_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T8v4-zUt1WQz" + }, + "source": [ + "![SQL_outer_excluding_join](https://github.com/MathMachado/Materials/blob/master/SQL_outer_excluding_join.png?raw=true)\n", + "\n", + "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iVEQFqx8Hdu5" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8HeMgBqyAYjW" + }, + "source": [ + "### Desafio: Como resolver este?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "djYoI_eUHD71" + }, + "source": [ + "df_right_left_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query(\n", + " '_merge==\"left_only\" | _merge==\"right_only\"')\n", + "df_right_left_excluding_join" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SkCbLsoktgKl" + }, + "source": [ + "### Observações:\n", + "\n", + "* Em alguns casos a variável chave nos dois dataframes que se quer fazer o join possui nomes diferentes. Neste caso, use 'left_on' e 'right_on' para definir o nome das COLUNAS chaves no dataframe da esquerda e direita:\n", + " * pd.merge(df1, df2, left_on =\"employee\", right_on =\"nome\")\n", + " * No exemplo acima, o dataframe df1 (dataframe da esquerda) possui chave 'employee' enquanto que o dataframe df2 (dataframe da direita), possui chave 'nome'. Usando as 'left_on' e 'right_on' fica claro o nome das chaves de ligação de cada dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6Obc0fHUwIpu" + }, + "source": [ + "## Joining" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DQOa89_cwLyd" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'A': ['A0', 'A1', 'A2'],\n", + " 'B': ['B0', 'B1', 'B2']},\n", + " index=['K0', 'K1', 'K2']) \n", + "\n", + "df_direito = pd.DataFrame({'C': ['C0', 'C2', 'C3'],\n", + " 'D': ['D0', 'D2', 'D3']},\n", + " index=['K0', 'K2', 'K3'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UHnX9rxzwMmx" + }, + "source": [ + "df_esquerdo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GBc1Mr0Qwff3" + }, + "source": [ + "df_direito" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TmIk3Kjlwg-7" + }, + "source": [ + "df_esquerdo.join(df_direito)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h609fbjjwoZ3" + }, + "source": [ + "df_esquerdo.join(df_direito, how ='outer')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y8W2kP-VCB3E" + }, + "source": [ + "___\n", + "# **Selecionar LINHAS do dataframe baseado nos índices**\n", + "### Leitura Adicional\n", + "* [pandas loc vs. iloc vs. ix vs. at vs. iat?\n", + "](https://stackoverflow.com/questions/28757389/pandas-loc-vs-iloc-vs-ix-vs-at-vs-iat/47098873#47098873)\n", + "* [Indexing and selecting data](https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NN1R1ngAG61x" + }, + "source": [ + "## 1st Approach - pd.loc[]\n", + "* Para capturar o conteúdo da linha k, use df.loc[row_indexer,column_indexer]." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oduXMUtIUvkN" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JX9nGPWcVLgE" + }, + "source": [ + "\n", + "Por exemlo, o comando a seguir mostra o conteúdo da linha 0, todas as COLUNAS(:)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U5-I2NgYC2fD" + }, + "source": [ + "df2= df_Titanic.loc[1,:]\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tDSJcQLTDyJw" + }, + "source": [ + "Mostrando o conteúdo das LINHAS k= 1:2 (ou seja, LINHAS 1 e 2), todas as COLUNAS(:)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JD1TDTqAD_5r" + }, + "source": [ + "df_Titanic.loc[1:2, :]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EoAmcdfnEIho" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1, coluna 'pclass':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8vjc5z3_EQfY" + }, + "source": [ + "df_Titanic.loc[1, ['pclass']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7bC8-H-QFLgd" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1 e COLUNAS ['pclass', 'sex']:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LYFTrZr_FR5g" + }, + "source": [ + "df_Titanic.loc[0, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UtUsmU8sXYTU" + }, + "source": [ + "Porque temos um erro aqui?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CRy5sDx-XbBL" + }, + "source": [ + "Versão correta abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Lfw0HEnXdn0" + }, + "source": [ + "df_Titanic.loc[1, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tjw3vjkDZg1Z" + }, + "source": [ + "Mostrar os conteúdos da linha k= 1:5 e COLUNAS ['pclass', 'sex']:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4GuAE5MSZjNb" + }, + "source": [ + "df_Titanic.loc[1:5, ['pclass', 'sex']]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xRZxqE6RFnJI" + }, + "source": [ + "Agora suponha que queremos selecionar toda a 'sex'. Como fazer isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JdeD_uzfFrp5" + }, + "source": [ + "df_sex= df_Titanic.loc[:, 'sex']\n", + "df_sex.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z_WUjYxsX-Av" + }, + "source": [ + "Fácil selecionarmos o que queremos usando .loc() e iloc(), certo?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RKk0zollHFbp" + }, + "source": [ + "## 2nd Approach - Usando lists\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jhwoY6LmGzC0" + }, + "source": [ + "df_Titanic[0:2] # Mostrar os conteúdos das LINHAS 0:2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I6EOVIDxGiy-" + }, + "source": [ + "df_Titanic[:3] # Mostrar os conteúdos até a linha 3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOHp77F8H9t1" + }, + "source": [ + "df_Titanic['sex'].head() # Mostrar o conteúdo inteiro da variável 'sex'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8nvHNdhPZ040" + }, + "source": [ + "df_Titanic[0:5]['sex'].head() # Mostrar as LINHAS 0 a 5 da variável 'sex'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GMFso1jaYXgN" + }, + "source": [ + "___\n", + "# **Selecionar/Filtrar/Substituir LINHAS do dataframe baseado em condições**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BKljSpS5ou-i" + }, + "source": [ + "## Exemplo 1\n", + "> Aproveitando o exemplo anterior, queremos selecionar do dataframe somente os passageiros do sexo 'male'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jek8Ru3Aam23" + }, + "source": [ + "### Approach 1: df.loc() e df.iloc()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eysZoBX2YKb-" + }, + "source": [ + "df_sexo_m_1 = df_Titanic.loc[df_Titanic['sex'] == 'male', 'sex']\n", + "df_sexo_m_1.head() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uLDOHKGfaq-Z" + }, + "source": [ + "### Approach 2: Uso do []" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QncrZwHkasiu" + }, + "source": [ + "df_sexo_m_2 = df_Titanic[df_Titanic['sex'] == 'male']['sex']\n", + "df_sexo_m_2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ot6UBTYJF-AJ" + }, + "source": [ + "### Approach 3: df.isin()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OBRF0be3VuTi" + }, + "source": [ + "#### Exemplo 1 - Filtro simples" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LeTDiGICGOzb" + }, + "source": [ + "df_sexo_m_3 = df_Titanic['sex'].isin(['male'])\n", + "df_sexo_m_3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q6emu30nGmpt" + }, + "source": [ + "#### Exemplo 2 - Filtro duplo = Duas condições\n", + "> Selecionar todas as LINHAS onde sexo = 'male' e Pclass = 1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TRaiCYMRGpgl" + }, + "source": [ + "# Filtros usando df.isin() \n", + "filtro_m = df_Titanic[\"sex\"].isin([\"male\"]) \n", + "filtro_class1 = df_Titanic[\"pclass\"].isin([1]) \n", + " \n", + "# Mostra os resutados \n", + "df_Titanic[filtro_m & filtro_class1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Sh0DDj1xcPaI" + }, + "source": [ + "df_sexo_m_class = df_Titanic[(df_Titanic['sex'] == 'male') & (df_Titanic['pclass'] == 1)]\n", + "df_sexo_m_class.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ujrYHyOsfW7n" + }, + "source": [ + "### Approach 4 - Filtrar com df.str.contains('s_substr')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gntbfHgTfanx" + }, + "source": [ + "# Mostrar todas as LINHAS onde a string 'Mr' aparece no nome do passageiro:\n", + "df2 = df_Titanic[df_Titanic['name'].str.contains('mr')]\n", + "df2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eaRtQ8Ja8MOH" + }, + "source": [ + "Para saber mais sobre o método df[col].str.contais(), consulte https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FyJ-gEjzQI2Y" + }, + "source": [ + "## Substituir valores do dataframe\n", + "> Suponha que queremos substituir todos os valores de pclass da seguinte forma:\n", + "* Se pclass = 1 --> pclass2 = 'Classe1';\n", + "* Se pclass = 2 --> pclass2 = 'Classe2';\n", + "* Se pclass = 3 --> pclass2 = 'Classe3';\n", + "\n", + "Como fazer isso?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Pi8MFiUPQQb7" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "19mynzdfQqVf" + }, + "source": [ + "df_Titanic['pclass2'] = df_Titanic['pclass']\n", + "df_Titanic.loc[df_Titanic['pclass'] == 1, 'pclass2'] = 'Classe1'\n", + "df_Titanic.loc[df_Titanic['pclass'] == 2, 'pclass2'] = 'Classe2'\n", + "df_Titanic.loc[df_Titanic['pclass'] == 3, 'pclass2'] = 'Classe3'\n", + "df_Titanic['pclass2'].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JC9z602zimyY" + }, + "source": [ + "df_Titanic['pclass3'] = df_Titanic['pclass']\n", + "df_Titanic['pclass3'] = df_Titanic['pclass3'].map({1:'Classe1',2:'Classe2',3:'Classe3'})\n", + "df_Titanic['pclass3'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KVSAYeU0KA2V" + }, + "source": [ + "___\n", + "# **Selecionar amostras aleatórias do dataframe**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U502dAs3OfOH" + }, + "source": [ + "Vimos que o dataframe df_Titanic é muito grande. Então, vamos selecionar aleatoriamente 100 LINHAS." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BrKUnAiPcAy" + }, + "source": [ + "import random \n", + "\n", + "# Biblioteca para avaliarmos o tempo de processamento de cada alternativa\n", + "import time" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iJ1G8lYgKGsc" + }, + "source": [ + "# Usando sample\n", + "t0= time.time()\n", + "df_Titanic_a100= df_Titanic.sample(100, replace= False, random_state= 20111974)\n", + "t1= time.time()\n", + "t= t1-t0\n", + "df_Titanic_a100.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8DvWOKizZQr8" + }, + "source": [ + "f'Tempo de processamento: {t}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nAHLTjpvYKPS" + }, + "source": [ + "# Usando NumPy\n", + "import numpy as np\n", + "\n", + "t0 = time.time()\n", + "np.random.seed(20111974)\n", + "indices = np.random.choice(df_Titanic.shape[0], replace = False, size=100)\n", + "df_Titanic_a100_2 = df_Titanic.iloc[indices]\n", + "t1 = time.time()\n", + "t = t1-t0\n", + "df_Titanic_a100_2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U8PEDMJ4a52P" + }, + "source": [ + "f'Tempo de processamento: {t}'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wYeuJWdEdMPd" + }, + "source": [ + "df_Titanic_a100_2.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vNMiRkjCQ9Mu" + }, + "source": [ + "___\n", + "# **Descrever o Dataframe**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GllUFj56RHuD" + }, + "source": [ + "df_Titanic_a100.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "izbpIEi1d1sx" + }, + "source": [ + "df_Titanic_a100_2.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H40G3QzWbG9N" + }, + "source": [ + "___\n", + "# **Identificar e lidar com LINHAS duplicadas**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_OoM_HS5ZgxG" + }, + "source": [ + "## Exemplo 1\n", + "* considera as duplicatas em todas as COLUNAS do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5XOOdOZBbLc_" + }, + "source": [ + "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gio08BkTbTOp" + }, + "source": [ + "# Lista as duplicações em forma booleana\n", + "df.duplicated()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "obgbM4d_hJ_J" + }, + "source": [ + "Observe a linha 5, onde temos a informação que esta linha está duplicada. Na verdade, a linha 5 é igual à linha 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LHhOIb-EbWfn" + }, + "source": [ + "# Mostra as LINHAS duplicadas\n", + "df[df.duplicated()]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IyJS70_kZ-Jk" + }, + "source": [ + "# Deleta a linha 5 que, como vimos, estava duplicada (uma cópia da linha 1).\n", + "df= df.drop_duplicates()\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Q05mxOSaEjX" + }, + "source": [ + "## Exemplo 2\n", + "* Considera somente algumas COLUNAS" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jiqyjcqdaQ1y" + }, + "source": [ + "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "F_118d7vbZ9Y" + }, + "source": [ + "# Mostra as LINHAS duplicadas usando as COLUNAS 'A' e 'B'\n", + "df[df.duplicated(subset=['A','B'])]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_1w_ZZO4vF3A" + }, + "source": [ + "# Deleta as LINHAS 1 e 5, pois como podemos ver, são duplicatas da linha 0\n", + "df= df.drop_duplicates(subset = ['A', 'B'])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qVx6p8u36jhD" + }, + "source": [ + "___\n", + "# **Trabalhar com dados do tipo texto**\n", + "* Fontes:\n", + " * [Working with text data](https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html)\n", + " * [Using String Methods](https://www.ritchieng.com/pandas-string-methods/)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JLG3cVA1e8-B" + }, + "source": [ + "Preparando os dados para o exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G_CEULoyeP8C" + }, + "source": [ + "# Definir um dicionário com os dados: \n", + "import numpy as np\n", + "\n", + "l_idade = []\n", + "for i in range(6):\n", + " np.random.seed(i) \n", + " l_idade.append(np.random.randint(10, 40))\n", + " \n", + "\n", + "d_exemplo = {'Nome':['Mr. Antonio dos Santos', 'Mr. Joao Pedro', 'Miss. Priscila Alvarenga', 'Mr. fagner NoVAES', 'Miss. Danielle Aparecida', 'Mr. Paullo Amarantes'], \n", + " 'Idade': l_idade, \n", + " 'Cidade':['lisboa', 'Sintra', 'Braga', 'Guimaraes', 'Mafra', 'Nazare']} \n", + " \n", + "# Converte o dicionário num dataframe\n", + "df = pd.DataFrame(d_exemplo) \n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "or-Kzaqmdn2b" + }, + "source": [ + "* Sugestões do que podemos fazer com relação á coluna 'nome' do dataframe df:\n", + " * Extrair o cumprimento do nome: Mr., Miss e etc.\n", + " * Construir as COLUNAS PrimeiroNome e SegundoNome.\n", + " * Criar a variável classe_idade." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vd99ksvcg7uy" + }, + "source": [ + "## Extrair o comprimento do nome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rNsANzFAg_Kn" + }, + "source": [ + "df_Nome= df['Nome'].str.split(' ', n = 2, expand = True) \n", + "df_Nome" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ianqsxLol008" + }, + "source": [ + "Altere o valor de n para 3 e explique como as coisas funcionam..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5NDAkEqCl6H5" + }, + "source": [ + "# Capturando o cumprimento do nome:\n", + "df['Tratamento_Nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[0]\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B1QoH4LyrpVI" + }, + "source": [ + "## Construir as COLUNAS primeiro_nome e Segundo_Nome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cbi4eRN2mOu9" + }, + "source": [ + "# Capturando o primeiro nome:\n", + "df['primeiro_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[1]\n", + "df['ultimo_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[2]\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7eagWhgZrwOh" + }, + "source": [ + "### Construir a variável classe_idade\n", + "\n", + " | Limite Inferior | Limite Superior | Classe |\n", + " |-----------------|-----------------|--------|\n", + " | Inf | 15 | Inf_15 |\n", + " | 15 | 20 | 15_20 |\n", + " | 20 | 30 | 25_30 |\n", + " | 30 | 40 | 30_40 |\n", + " | 40 | 50 | 40_50 |\n", + " | 50 | Sup | 50_Sup |" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lBjRBGBWr2AH" + }, + "source": [ + "def classe_idade(Idade):\n", + " if (Idade <= 15):\n", + " return 'Inf_15'\n", + " if (15 < Idade <= 20):\n", + " return '15_20'\n", + " elif(20 < Idade <= 30):\n", + " return '20_30'\n", + " elif (30 < Idade <= 40):\n", + " return '30_40'\n", + " elif (40 < Idade <= 50):\n", + " return '40_50'\n", + " elif (Idade > 50):\n", + " return '50_Sup'\n", + " else:\n", + " return 'Outros'" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OogrvjCrsdoh" + }, + "source": [ + "df['classe_idade'] = df['Idade'].map(classe_idade)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "57tzJCS0p_G4" + }, + "source": [ + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDtxz_eaRcmi" + }, + "source": [ + "___\n", + "# **Agrupar Informações: pd.groupby()**\n", + "* Fonte: [Group By: split-apply-combine](https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html)\n", + "\n", + "* Os componentes do comando Groupby()\n", + " * **Grouping_Column** - Coluna Categórica pelo qual os dados serão agrupados;\n", + " * **Aggregating_Column** - Coluna numérica cujos valores serão agrupados;\n", + " * **Aggregating_Function** - Função agregadora, ou seja: sum, min, max, mean, median, etc...\n", + "\n", + "> Sintaxe: \n", + "\n", + "```\n", + "df.groupby('Grouping_Column').agg({'Aggregating_Column': 'Aggregating_Function'})\n", + "\n", + "OU\n", + "\n", + "df['Aggregating_Column'].groupby(df['Grouping_Column']).Function()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bmFf-273XPXj" + }, + "source": [ + "## Exemplo 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wteEveUsd36C" + }, + "source": [ + "transformacao_lower(df_Titanic)\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "buF5DhkFfqVA" + }, + "source": [ + "# Agrupando df_Titanic por 'sex'\n", + "df_Titanic.groupby(['sex', 'pclass']).agg({'fare': ['min', 'median', 'mean','max'], 'age': ['count', 'mean','max']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YP3GDwq0gR_V" + }, + "source": [ + "# Agrupando df_Titanic por 'sex' e 'Pclass'\n", + "df_Titanic.groupby(['sex','pclass']).agg({'fare': ['max', 'min']}).round(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "se4tQ3ETeUfv" + }, + "source": [ + "df_Titanic.groupby(['sex']).agg({'age': ['mean','min','max']}).round(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zUj82I7Cm220" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OrLZjm9bXTOr" + }, + "source": [ + "## Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x8aPZPT6XZVP" + }, + "source": [ + "### Preparando o exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KrCe6RgOXaFx" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "l_coluna = []\n", + "\n", + "for i in range(1,6):\n", + " np.random.seed(i)\n", + " l_coluna.append(np.random.randint(0, 10, 10))\n", + " \n", + "np.random.seed(6)\n", + "l_coluna.append(np.random.rand(10))\n", + "\n", + "l_coluna" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tXaHjmfSXeCw" + }, + "source": [ + "l_coluna[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U_aEVMTHq6ee" + }, + "source": [ + "df = pd.DataFrame({'coluna6' : ['a', 'a', 'b', 'b', 'a', 'b', 'b', 'b', 'a', 'a'],\n", + " 'coluna7' : ['um', 'dois', 'um', 'dois', 'um', 'dois', 'dois', 'um', 'um', 'dois'],\n", + " 'coluna1' : l_coluna[0],\n", + " 'coluna2' : l_coluna[1],\n", + " 'coluna3' : l_coluna[2],\n", + " 'coluna4' : l_coluna[3],\n", + " 'coluna5' : l_coluna[4],\n", + " 'coluna8' : l_coluna[5],\n", + " 'Pessoas' : ['Jose','Maria','Pedro','Carlos','Joao','Ana','Manoel','Mafalda','Antonio','Ricardo'],\n", + " 'sexo' : ['m','f','m','m','m','f','m','f','m','m']})\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ok4a28lGlVC5" + }, + "source": [ + "Agrupando por 'coluna6':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vx77lyzlZIFW" + }, + "source": [ + "df.groupby('coluna6').agg({'coluna1': ['min','mean','median','max']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T6i-R2KemadE" + }, + "source": [ + "Agora, vamos repetir o processo usando duas COLUNAS-chaves 'coluna6' e 'coluna7':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WxmHQnQSZrXA" + }, + "source": [ + "df_estatisticas_descritivas = df.groupby(['coluna6','coluna7']).agg({'coluna1': ['min','mean','median','max']})\n", + "df_estatisticas_descritivas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ipw5EROwaaCX" + }, + "source": [ + "Observe que df_estatisticas_descritivas é um dataframe. Portanto, podemos selecionar LINHAS e/ou COLUNAS deste dataframe da forma que quisermos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qk5uSdVwb7dH" + }, + "source": [ + "# Índices do dataframe:\n", + "df_estatisticas_descritivas.index" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "brIgUFlkalix" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um':\n", + "df_estatisticas_descritivas.loc[('a', 'um')]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fQUs2PVHc6iR" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', primeiro valor:\n", + "df_estatisticas_descritivas.loc[('a', 'um')][0] # ou seja, selecionamos min" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zT0xiee6dDpK" + }, + "source": [ + "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', segundo valor:\n", + "df_estatisticas_descritivas.loc[('a', 'um')][1] # ou seja, selecionamos mean" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vXlcjPM6dQKi" + }, + "source": [ + "E daí por diante..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EMxFMqn9dm3g" + }, + "source": [ + "Para aprender mais sobre como trabalhar com dois índices em um dataframe, consulte [Hierarchical indices, groupby and pandas](https://www.datacamp.com/community/tutorials/pandas-multi-index)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gNHyH7M0pGDy" + }, + "source": [ + "___\n", + "## Exemplo 3\n", + "### Operações e transformações em grupo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ywl3k_l8pGD0" + }, + "source": [ + "# Mostra o dataframe-exemplo:\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AF8cbNsjpGD5" + }, + "source": [ + "# Constroi dataframe df_Medias\n", + "df_Medias = df.groupby('coluna6').mean().add_prefix('mean_')\n", + "df_Medias" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JGlA6ufLpGD9" + }, + "source": [ + "# Combina (merge) com o dataframe df:\n", + "pd.merge(df, df_Medias, left_on ='coluna6', right_index=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1MjZu3sVpGEd" + }, + "source": [ + "___\n", + "# **Discretizar COLUNAS numéricas**\n", + "* pd.cut() - classes com base em valores;\n", + "* pd.qcut() - classes com base em quantis da amostra, ou seja teremos a mesma quantidade de itens em cada classe.\n", + "\n", + "> Este artifício é muito utilizado em Machine Learning quando queremos construir classes para variáveis numéricas (integer ou float). Acompanhe a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yK772hiSfZaE" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wi-nv6fshKIX" + }, + "source": [ + "## pd.cut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GUAYB8J2KzJt" + }, + "source": [ + "Bucket_cut = pd.cut(df['coluna8'], 4) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SVExQmzDpGEe" + }, + "source": [ + "# Construir 4 classes para a variável float 'coluna8':\n", + "Bucket_cut = pd.cut(df['coluna8'], 4) # aqui, estamos construindo 4 buckets\n", + "Bucket_cut" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OOD38I6ug1AY" + }, + "source": [ + "# Quem são os Bucket's que construimos:\n", + "Bucket_cut.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9s2eaZGtfsxu" + }, + "source": [ + "Como podem ver, de fato construimos 4 bucket's. **Observe que não temos a mesma quantidade de itens em cada classe!!!**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T7u0pS64hPHC" + }, + "source": [ + "## pd.qcut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cJTQTHA6pGEm" + }, + "source": [ + "Bucket_qcut = pd.qcut(df['coluna8'], 4, labels=False)\n", + "Bucket_qcut" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vM30Td_8hZre" + }, + "source": [ + "# Quem são os Bucket's que construimos:\n", + "Bucket_qcut.value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jhf6V5LTh4G7" + }, + "source": [ + "## Comentários\n", + "* pd.qcut() garante uma distribuição mais uniforme dos valores em cada classe. Isso significa que é menos provável que você tenha uma classe com muitos dados e outra com poucos dados.\n", + "* Eu prefiro usar pd.qcut()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RNsR0NsS5iIU" + }, + "source": [ + "___\n", + "# **Distribuição conjunta - crosstabs**\n", + "> Suponha que queremos analisar o número de sobreviventes em relação à COLUNA embarked." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LKQv6YtSfGSU" + }, + "source": [ + "df_Titanic2 = df_Titanic.copy()\n", + "df_Titanic2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ANhb5rBffTh6" + }, + "source": [ + "pd.crosstab(df_Titanic2['survived'], df_Titanic2['embarked'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WIlHAYEVqSjT" + }, + "source": [ + "___\n", + "# **Deletar COLUNAS do dataframe**\n", + "> Deletar as COLUNAS 'coluna2' e 'coluna5' do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YssOMF_Vqso5" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rVF_1p0Gq3gZ" + }, + "source": [ + "## Usando inplace = True" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BjRIX1jqWQT" + }, + "source": [ + "df.drop(['coluna2','coluna5'], axis =1, inplace =True)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "POC2fnTlq8mK" + }, + "source": [ + "## Usando atribuição" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YRSwEbnfq7s_" + }, + "source": [ + "df= df.drop(['coluna2','coluna5'], axis =1)\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bHth6KSv7k0G" + }, + "source": [ + "___\n", + "# **Criar COLUNAS dummies para dados categóricos**\n", + "> Nosso objetivo é construir variáveis dummies para nossas COLUNAS categóricas.\n", + "\n", + "* Fontes: \n", + " * [Categorical data](https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html)\n", + " * [Creating Dummy Variables](https://www.ritchieng.com/pandas-creating-dummy-variables/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GOqcARHqjMr_" + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yNqvwEu9jbuW" + }, + "source": [ + "Vamos construir variáveis dummies para as COLUNAS 'coluna6' e 'coluna7', da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "16osZsMEjmDh" + }, + "source": [ + "pd.get_dummies(df['coluna6'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cb1gp_Y1jxz2" + }, + "source": [ + "Qual a interpretação do resultado acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cic19l-Mj39q" + }, + "source": [ + "pd.get_dummies(df['coluna7'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "44FDXcoyj-tT" + }, + "source": [ + "Qual a interpretação do resultado acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cxHc6BvDkCWl" + }, + "source": [ + "df = pd.get_dummies(df, columns =['coluna6', 'coluna7', 'sexo'])\n", + "df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2m25N4znZ2O" + }, + "source": [ + "df.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x0uXu0RRlB2a" + }, + "source": [ + "___\n", + "# **Calcular correlação (Análise de Correlação)**\n", + "> A correlação pode ser calculada usando o método df.corr(). Para mais detalhes sobre os tipos de correlação existentes bem como a aplicação de cada uma delas, consulte os links a seguir:\n", + "\n", + "* [Pearson correlation coefficient](https://en.wikipedia.org/wiki/Pearson_correlation_coefficient)\n", + "* [Kendall rank correlation coefficient](https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient)\n", + "* [Spearman's rank correlation coefficient](https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient).\n", + "\n", + "Para aprender mais sobre a geração de heatmap, consulte [Seaborn Heatmap Tutorial (Python Data Visualization)](https://likegeeks.com/seaborn-heatmap-tutorial/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AgoigF8AnYG0" + }, + "source": [ + "## Gerando o dataframe-exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6scRm8kNnbby" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "# Gerando um dataframe com 15 colunas, sendo 9 informativas e 6 redundantes:\n", + "from sklearn.datasets import make_classification\n", + "X, y = make_classification(n_samples=1000, n_features=15, n_informative=9,\n", + " n_redundant=6, n_repeated=0, n_classes=2, n_clusters_per_class=1,\n", + " random_state=20111974)\n", + "\n", + "df_X = pd.DataFrame(X, columns= ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15'])\n", + "df_y = pd.DataFrame(y, columns= ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NsuhsZCTmqEm" + }, + "source": [ + "# Visualizar os dados\n", + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D0JNMHqYoSMs" + }, + "source": [ + "# Mostra a matriz de correlação usando a correlação de Pearson\n", + "set_Colunas_Correlacionadas = set()\n", + "matriz_correlacao = df_X.corr().where(np.triu(np.ones(df_X.corr().shape), k = 1).astype(np.bool))\n", + "matriz_correlacao" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vnj6A8z6r7nM" + }, + "source": [ + "### Quem são as colunas altamente correlacionadas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a_YUD-dOr_p-" + }, + "source": [ + "set_Colunas_Correlacionadas = set()\n", + "for i in range(len(matriz_correlacao.columns)):\n", + " for j in range(i):\n", + " if abs(matriz_correlacao.iloc[j, i]) > 0.8: # consertei o código do Nélio invertendo i com j\n", + " colnome = matriz_correlacao.columns[j] # consertei o código do Nélio colocando j no lugar do i\n", + " set_Colunas_Correlacionadas.add(colnome)\n", + "\n", + "set_Colunas_Correlacionadas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MF8Cii-OXo8h" + }, + "source": [ + "for i in range(len(matriz_correlacao.columns)):\n", + " for j in range(i):\n", + " print(f'i = {i} | j = {j} | Correlacao = {matriz_correlacao.iloc[j, i]}') # consertei o código do Nélio invertendo i com j\n", + " # if abs(matriz_correlacao.iloc[i, j]) > 0.8: # código original do nelio com erro\n", + " # colnome = matriz_correlacao.columns[i] # código original do nelio com erro\n", + " # set_Colunas_Correlacionadas.add(colnome) \n", + "\n", + "#set_Colunas_Correlacionadas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-0Xe6GdozYT" + }, + "source": [ + "A seguir, a correlação mais visual:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5-_Qadx1o1U9" + }, + "source": [ + "fig, ax = plt.subplots(figsize = (12, 12)) \n", + "mask = np.zeros_like(df_X.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_X.corr().abs(), mask= mask, ax= ax, cmap='coolwarm', annot= True, fmt= '.2f', center= 0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ZOp9ZGgtqFQ" + }, + "source": [ + "# **Scatterplot**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eReJJjG8tuKV" + }, + "source": [ + "## Com regressão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tVmdSo6ztruA" + }, + "source": [ + "sns.pairplot(df_X, kind = \"reg\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xG9A6b32twv-" + }, + "source": [ + "## Sem regressão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fyTOS3zVtz-O" + }, + "source": [ + "sns.pairplot(df_X, kind = \"scatter\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f-1bpipc6bMh" + }, + "source": [ + "___\n", + "# **Salvar dataframe como csv**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "64CoM1aY6gf6" + }, + "source": [ + "df_X.to_csv('example.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oy646p33DJV0" + }, + "source": [ + "# **Dicionário de palavras**\n", + "> Muito utilizado em NLP e Machine Learning.\n", + "* Caso de Uso: Seguradoras --> Quando um segurado aciona a Seguradora para descrever um acidente (por exemplo), há um algorítmo que transforma o áudio em texto para mineração de textos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DQR906rVD1V-" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sHvDaztJDPP7" + }, + "source": [ + "from sklearn.feature_extraction.text import CountVectorizer\n", + "CountVectorizer = CountVectorizer()\n", + "matriz_contagens = CountVectorizer.fit_transform(df_Titanic['name']) # Informe a coluna do tipo texto/string que queremos analisar/avaliar\n", + "print(matriz_contagens)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jwT-56dED8VJ" + }, + "source": [ + "df_dicionario_palavras = pd.DataFrame(CountVectorizer.get_feature_names(), columns = ['palavra'])\n", + "df_dicionario_palavras[\"vezes_que_aparece\"] = matriz_contagens.sum(axis = 0).tolist()[0]\n", + "df_dicionario_palavras = df_dicionario_palavras.sort_values(\"vezes_que_aparece\", ascending = False) #.reset_index(drop = True) # Sorte ordena as linhas do dataframe\n", + "df_dicionario_palavras.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nx65RmEAGTvd" + }, + "source": [ + "# Desafio\n", + "> Transforme o code Python da sessão **Dicionário de palavras** em função para usarmos futuramente." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iwd1lhq9mrD3" + }, + "source": [ + "___\n", + "# **Exercícios**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o_cl0kFgQfFh" + }, + "source": [ + "## Exercício 1\n", + "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s8rQUo7yHKJ1" + }, + "source": [ + "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jlz6smN3TLuH" + }, + "source": [ + "url_USA_Abb = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/USA_Abbrev.csv'\n", + "url_USA_Area = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/USA_Area.csv'\n", + "url_USA_Pop = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/USA_Population.csv'\n", + "df_USA_Abb = pd.read_csv(url_USA_Abb)\n", + "df_USA_Area = pd.read_csv(url_USA_Area)\n", + "df_USA_Pop = pd.read_csv(url_USA_Pop)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Vh0yvaAmUl-G" + }, + "source": [ + "df_USA_Abb.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E_UBdJ66UlXS" + }, + "source": [ + "df_USA_Area.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ngvPiSVVUkcz" + }, + "source": [ + "df_USA_Pop.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uZkWKRsWUx7N" + }, + "source": [ + "df_USA = pd.merge(df_USA_Abb, df_USA_Area, how='outer', on='state')\n", + "df_USA" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jhPpQsGlUxlK" + }, + "source": [ + "df_USA1 = pd.merge(df_USA, df_USA_Pop, how='outer', left_on='abbreviation', right_on = 'state_region')\n", + "df_USA1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XponZhgnUxG8" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KTun1uSLuJ-A" + }, + "source": [ + "## Exercício 2\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Soq7GVZnuREq" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6KEsTARfvM1C" + }, + "source": [ + "## Exercício 3\n", + "Source: https://github.com/aakankshaws/Pandas-exercises\n", + "\n", + "* Considere os dataframes a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hgxE5gZ9vMEg" + }, + "source": [ + "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K1', 'K0', 'K1'],\n", + " 'A': ['A0', 'A1', 'A2', 'A3'],\n", + " 'B': ['B0', 'B1', 'B2', 'B3']})\n", + " \n", + "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n", + " 'key2': ['K0', 'K0', 'K0', 'K0'],\n", + " 'C': ['C0', 'C1', 'C2', 'C3'],\n", + " 'D': ['D0', 'D1', 'D2', 'D3']})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iv7AmZ1ivm8R" + }, + "source": [ + "### Perguntas\n", + "* Qual o output e a interpretação dos comandos a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TWAW_1tuvvSO" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QjM7pBONvzCJ" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D1Rr3Ghsv2iS" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vXQwLjT-v3Iu" + }, + "source": [ + "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EIdltTC-t_lF" + }, + "source": [ + "## Exercício 5\n", + "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bMwPLgWclWBq" + }, + "source": [ + "___\n", + "## Exercício 6\n", + "* (a) Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN).\n", + "\n", + "### Feature Engineering\n", + "* (b) Com a coluna 'cabin', construir as colunas:\n", + " * deck - Letra de Cabin;\n", + " * seat - Número de Cabin\n", + "* (c) Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n", + "* (d) Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n", + "* (e) Discretizar a coluna 'fare' em 10 buckets.\n", + "* (f) Discretizar a coluna 'age'.\n", + "* (g) Capturar os títulos 'Ms', 'Mr' e etc contidos na coluna 'Title';\n", + "* (h) Qual a relação entre as variáveis e a variável-target?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V7KUGAX6lilP" + }, + "source": [ + "import pandas as pd\n", + "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/Titanic_With_MV.csv', index_col= 'PassengerId')\n", + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m3UnAPJakCLR" + }, + "source": [ + "* Segue o dicionário de dados do dataframe Titanic:\n", + " * PassengerID: ID do passageiro;\n", + " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n", + " * Pclass: Classe;\n", + " * Age: Idade do Passageiro;\n", + " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n", + " * Parch: Número de pais/crianças a bordo;\n", + " * Fare: Valor pago pelo Passageiro;\n", + " * Cabin: Cabine do Passageiro;\n", + " * Embarked: A porta pelo qual o Passageiro embarcou.\n", + " * Name: Nome do Passageiro;\n", + " * sex: sexo do Passageiro\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B_3s5cgxfNKQ" + }, + "source": [ + "## Resposta do item (a)\n", + "### Coluna XPTO\n", + "\n", + "\n", + "### Coluna XPTO2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q3oLgyhdL6xd" + }, + "source": [ + "## Resposta do item (b)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Sm-LaRZZKAac" + }, + "source": [ + "df_Titanic.loc[pd.isna(df_Titanic['Cabin']), 'Cabin'] = 'N0'\n", + "df_Titanic['deck'] = df_Titanic['Cabin'].str.get(0)\n", + "df_Titanic['seat'] = df_Titanic['Cabin'].str[1:]\n", + "df_Titanic.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "d-d_4f6hKi6T" + }, + "source": [ + "## Resposta do item (c)\n", + "df_Titanic['sozinho_parch'] = df_Titanic['Parch']\n", + "s_sozinho_parch = df_Titanic['sozinho_parch'] > 0\n", + "df_Titanic.loc[s_sozinho_parch, ['sozinho_parch']] = 0\n", + "df_Titanic.loc[~s_sozinho_parch, ['sozinho_parch']] = 1\n", + "df_Titanic" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xAUT7OjvKirj" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fzzC3zP7KiaG" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aRHx_74nKiGd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WNHrcn9uKg-i" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbexhGtayV4X" + }, + "source": [ + "## Exercício 7\n", + "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Iia0ikd_KBtH" + }, + "source": [ + "## Exercício 8\n", + "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HPiLKUkWNYs3" + }, + "source": [ + "df_Titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TUVTlE9WYW8C" + }, + "source": [ + "## Exercício 9\n", + "O arquivo FIFA.csv contem dados relacionados à última edição do FIFA 2018 (um dos jogos de video-game mais famosos) e traz os mais variados dados sobre os jogadores (exemplo): idade, nacionalidade, potencial, salário e etc. Faça o seguinte:\n", + "\n", + "1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);\n", + "2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n", + "3. Qual o dtype de cada variável/atributo do dataframe?\n", + "4. Se alguma variávável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n", + "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;\n", + "6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n", + "7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição.\n", + "8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');\n", + "9. Qual a número de jogadores por idade?\n", + "10. Quantos jogadores possuem cada clube?\n", + "11. Qual a média de idade por clube?\n", + "12. Qual a média de salário por país?\n", + "13. Qual a média de salário por clube?\n", + "14. Qual a média de salário por idade?\n", + "15. Quanto cada clube gasta com pagamento de salários?\n", + "16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?\n", + "17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n", + "18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n", + "19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'.\n", + "20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed'=?\n", + "21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?\n", + "22. Quem são os outliers em termos de salário?\n", + "23. Quem são os outliers em termos de potência no chute?\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ldWQd9j4NhPS" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KVhF-Lc_XhDL" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_2_Missing_Value_Handling_hs.ipynb b/Notebooks/NB10_04__3DP_2_Missing_Value_Handling_hs.ipynb new file mode 100644 index 000000000..3b217d9a3 --- /dev/null +++ b/Notebooks/NB10_04__3DP_2_Missing_Value_Handling_hs.ipynb @@ -0,0 +1,1848 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_2_Missing_Value_Handling.ipynb", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rGVp396DAlIW" + }, + "source": [ + "

3DP_2 - MISSING VALUES HANDLING

\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ii1Mci_PxQdJ" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "slSYEvDtArHO" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [Working with missing data](https://pandas.pydata.org/pandas-docs/stable/user_guide/missing_data.html)\n", + "* [Handling Missing Data for a Beginner](https://towardsdatascience.com/handling-missing-data-for-a-beginner-6d6f5ea53436)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UGJtCSbTwraG" + }, + "source": [ + "___\n", + "# **3DP_MISSING VALUES HANDLING**\n", + "\n", + "> Lidar com Missing Values é um dos piores pesadelos de um Cientista de dados. Especialmente, se o número de MV for grande o suficiente (geralmente acima de 5%). Nesse caso, os valores não podem ser descartados e um Cientista de Dados inteligente deve \"imputar\" os valores ausentes.\n", + "\n", + "* Nesta sessão, vamos identificar, analisar e tratar Missing Values (MV).\n", + "* Como MV são gerados?\n", + " * Usuário se esqueceu de preencher ou preencheu errado o campo;\n", + " * Os dados foram perdidos durante a transferência manual de um banco de dados legado;\n", + " * Erro de programação;\n", + " * Os usuários optaram por não preencher um campo vinculado a suas crenças sobre como os resultados seriam usados ou interpretados.\n", + "* As funções df.isnull() e df.isna() são apropriadas para nos indicar quantas observações são MV no dataframe.\n", + "\n", + "* Na prática:\n", + " * Variáveis Contínuas/Numéricas - Podemos substituir os NaN por Média/Mediana/Moda;\n", + "\t* Variáveis Categóricas - Uma alternativa é atribuir uma categoria inexistente como, por exemplo \"MV\" para indicar o NaN.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4mFlY2iIHDaV" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING COM PYTHON (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CA-GboEcP4zY" + }, + "source": [ + "## Carregar as biliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x0fq_2HoP7OE" + }, + "source": [ + "import pandas as pd\n", + "from pandas import Series, DataFrame\n", + "\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "matplotlib.style.use('ggplot')\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P4_7D_4NA7KJ" + }, + "source": [ + "## Dataframes\n", + "* O dataframe abaixo foi gerado aleatoriamente para entendermos como lidar com os NaN's." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwyndikLOld0", + "outputId": "c8a71b76-e743-42ef-c482-be2e4872123e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 355 + } + }, + "source": [ + "df= pd.DataFrame({\n", + " 'idade': [32,38,np.nan,37,np.nan,36,38,32,0,np.nan],\n", + " 'salario': ['High', 'High', 'High', 'Low', 'Low', 'High', np.nan, 'Medium', 'Medium', 'High'],\n", + " 'pais': ['Spain', 'France', 'France', np.nan, 'Germany', 'France', 'Spain', 'France', np.nan, 'Spain']})\n", + "\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
idadesalariopais
032.0HighSpain
138.0HighFrance
2NaNHighFrance
337.0LowNaN
4NaNLowGermany
536.0HighFrance
638.0NaNSpain
732.0MediumFrance
80.0MediumNaN
9NaNHighSpain
\n", + "
" + ], + "text/plain": [ + " idade salario pais\n", + "0 32.0 High Spain\n", + "1 38.0 High France\n", + "2 NaN High France\n", + "3 37.0 Low NaN\n", + "4 NaN Low Germany\n", + "5 36.0 High France\n", + "6 38.0 NaN Spain\n", + "7 32.0 Medium France\n", + "8 0.0 Medium NaN\n", + "9 NaN High Spain" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nnJDArN0Thcs" + }, + "source": [ + "## Identificar os NaN's" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OuWnwsrWUOwJ" + }, + "source": [ + "A função df.isna() será usada para identificarmos os NaN's nos dataframes. Por exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MbpVaEz0Vrhv", + "outputId": "5f0e80df-6612-4870-dcf7-85dfe1a76af4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 359 + } + }, + "source": [ + "df.isna()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPais
0FalseFalseFalse
1FalseFalseFalse
2TrueFalseFalse
3FalseFalseTrue
4TrueFalseFalse
5FalseFalseFalse
6FalseTrueFalse
7FalseFalseFalse
8FalseFalseTrue
9TrueFalseFalse
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais\n", + "0 False False False\n", + "1 False False False\n", + "2 True False False\n", + "3 False False True\n", + "4 True False False\n", + "5 False False False\n", + "6 False True False\n", + "7 False False False\n", + "8 False False True\n", + "9 True False False" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 64 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yNTQr1HIYmfj" + }, + "source": [ + "Qual a interpretação deste output?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4j_sDA9UYwfy" + }, + "source": [ + "Para um dataframe muito grande, vamos usar a expressão abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_I9Rmip5Y0q1", + "outputId": "e308f7b0-385b-4060-e7cb-50c8b453a032", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "df.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Idade 3\n", + "Salario 1\n", + "Pais 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 65 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iylkpQhWY6Fb" + }, + "source": [ + "Mais prático não é? No entanto, vamos utilizar a função abaixo, que nos ajudará mais com os NaN's:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9CP1CsHPeeUQ" + }, + "source": [ + "def mostra_missing_value(df):\n", + " total = df.isnull().sum().sort_values(ascending = False)\n", + " percent = 100*round((df.isnull().sum()/df.isnull().count()).sort_values(ascending = False), 2)\n", + " missing_data = pd.concat([total, percent], axis = 1, keys=['Total', 'Percentual'])\n", + " print(missing_data.head(10))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nHB8ND2iefp4", + "outputId": "d9168eb0-b962-47dc-d07e-28b7e6462ff6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 87 + } + }, + "source": [ + "mostra_missing_value(df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " Total Percentual\n", + "idade 3 30.0\n", + "pais 2 20.0\n", + "salario 1 10.0\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qaKpKXBVZBeu" + }, + "source": [ + "## A função df.dropna()\n", + "* Esta função deleta as instâncias (linhas do dataframes) onde há pelo menos 1 NaN." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xhw5fJKFZGPn", + "outputId": "038d7b73-478d-4d1d-f488-237c7da6bf7a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 173 + } + }, + "source": [ + "df2 = df.dropna()\n", + "df2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPais
032.0HighSpain
138.0HighFrance
536.0HighFrance
732.0MediumFrance
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais\n", + "0 32.0 High Spain\n", + "1 38.0 High France\n", + "5 36.0 High France\n", + "7 32.0 Medium France" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 66 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BqWoQZ5fZeVk" + }, + "source": [ + "Como podemos ver, somente as instâncias 0, 1, 5 e 7 tem atributos não NaN's." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lc7lmP7hikBT" + }, + "source": [ + "Uma forma menos severa seria:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h1qLnkFoimU5", + "outputId": "7ee00406-e4df-42bb-d8e9-a156db0ec3dd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df3 = df.dropna(axis = 0, subset = ['pais'])\n", + "df3" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPaisIdade2Idade3Pais2
032.0HighSpain32.032.0Spain
138.0HighFrance38.038.0France
2NaNHighFranceNaN36.0France
4NaNLowGermanyNaN36.0Germany
536.0HighFrance36.036.0France
638.0NaNSpain38.038.0Spain
732.0MediumFrance32.032.0France
9NaNHighSpainNaN36.0Spain
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais Idade2 Idade3 Pais2\n", + "0 32.0 High Spain 32.0 32.0 Spain\n", + "1 38.0 High France 38.0 38.0 France\n", + "2 NaN High France NaN 36.0 France\n", + "4 NaN Low Germany NaN 36.0 Germany\n", + "5 36.0 High France 36.0 36.0 France\n", + "6 38.0 NaN Spain 38.0 38.0 Spain\n", + "7 32.0 Medium France 32.0 32.0 France\n", + "9 NaN High Spain NaN 36.0 Spain" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 91 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bbQC69pjizWO" + }, + "source": [ + "* Saberias explicar o que o comando acima fez?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z52kmtrSS_2J" + }, + "source": [ + "## Tratar os NaN's de Variáveis Numéricas\n", + "* Neste exemplo, vou substituir os NaN's da variável 'idade' pela mediana. No entanto, responda a seguinte perfunta:\n", + " * Faz sendido idade= 0?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TNadcxzRe5r3" + }, + "source": [ + "Acho que a resposta é não. Então, neste caso, 0 é um NaN. Vamos substituído pela mediana da variável:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O8SOOYbFfBtQ", + "outputId": "06afc715-c122-444a-891b-29ca9493efb0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 359 + } + }, + "source": [ + "df['idade2'] = df['idade'].replace({0: df['idade'].median()})\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPaisIdade2
032.0HighSpain32.0
138.0HighFrance38.0
2NaNHighFranceNaN
337.0LowNaN37.0
4NaNLowGermanyNaN
536.0HighFrance36.0
638.0NaNSpain38.0
732.0MediumFrance32.0
80.0MediumNaN36.0
9NaNHighSpainNaN
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais Idade2\n", + "0 32.0 High Spain 32.0\n", + "1 38.0 High France 38.0\n", + "2 NaN High France NaN\n", + "3 37.0 Low NaN 37.0\n", + "4 NaN Low Germany NaN\n", + "5 36.0 High France 36.0\n", + "6 38.0 NaN Spain 38.0\n", + "7 32.0 Medium France 32.0\n", + "8 0.0 Medium NaN 36.0\n", + "9 NaN High Spain NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 80 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YzpEHNXffRyC" + }, + "source": [ + "Como podemos verificar acima na variável 'idade2', o valor 0 foi substituído pela mediana da variável 'idade'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jlBNhkUtb60L" + }, + "source": [ + "Vamos verificar a média da variável antes da operação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ix4ioHTHcCAJ", + "outputId": "43bbd457-d06f-4d40-aa4e-2861bd624340", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df['idade2'].mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.57142857142857" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 82 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WefKW3WaTFdQ", + "outputId": "26c1c9f4-59e8-4f84-e0e7-5a29c8326711", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 359 + } + }, + "source": [ + "df['idade3'] = df['idade2']\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPaisIdade2Idade3
032.0HighSpain32.032.0
138.0HighFrance38.038.0
2NaNHighFranceNaNNaN
337.0LowNaN37.037.0
4NaNLowGermanyNaNNaN
536.0HighFrance36.036.0
638.0NaNSpain38.038.0
732.0MediumFrance32.032.0
80.0MediumNaN36.036.0
9NaNHighSpainNaNNaN
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais Idade2 Idade3\n", + "0 32.0 High Spain 32.0 32.0\n", + "1 38.0 High France 38.0 38.0\n", + "2 NaN High France NaN NaN\n", + "3 37.0 Low NaN 37.0 37.0\n", + "4 NaN Low Germany NaN NaN\n", + "5 36.0 High France 36.0 36.0\n", + "6 38.0 NaN Spain 38.0 38.0\n", + "7 32.0 Medium France 32.0 32.0\n", + "8 0.0 Medium NaN 36.0 36.0\n", + "9 NaN High Spain NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 83 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AOWQOGmEcIfi" + }, + "source": [ + "Aplicamos a operação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gAzxEchhdOXJ", + "outputId": "b17cafc9-eea2-4ce7-e2c5-de3b646a3c74", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 359 + } + }, + "source": [ + "df['idade3'].fillna(df['idade3'].median(), inplace = True)\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPaisIdade2Idade3
032.0HighSpain32.032.0
138.0HighFrance38.038.0
2NaNHighFranceNaN36.0
337.0LowNaN37.037.0
4NaNLowGermanyNaN36.0
536.0HighFrance36.036.0
638.0NaNSpain38.038.0
732.0MediumFrance32.032.0
80.0MediumNaN36.036.0
9NaNHighSpainNaN36.0
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais Idade2 Idade3\n", + "0 32.0 High Spain 32.0 32.0\n", + "1 38.0 High France 38.0 38.0\n", + "2 NaN High France NaN 36.0\n", + "3 37.0 Low NaN 37.0 37.0\n", + "4 NaN Low Germany NaN 36.0\n", + "5 36.0 High France 36.0 36.0\n", + "6 38.0 NaN Spain 38.0 38.0\n", + "7 32.0 Medium France 32.0 32.0\n", + "8 0.0 Medium NaN 36.0 36.0\n", + "9 NaN High Spain NaN 36.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 84 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eeKi5thjd5cn" + }, + "source": [ + "Podemos observar que os valores NaN's do atributo 'idade3' foi substituído pelo valor 36." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YhhlVz2ddkbm" + }, + "source": [ + "E agora, a média após a operação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "z2EsBMugdnCJ", + "outputId": "1e3e9566-3acb-4909-b433-c953deb5e589", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df['idade3'].mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.7" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 85 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kD-bY7Vlf6pH" + }, + "source": [ + "* Qual a conclusão?\n", + " * Houve muito impacto na distribuição da variável 'idade'?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3oE1ZuB4TFlr" + }, + "source": [ + "## Tratar NaN's de Variáveis Categóricas\n", + "* Observe a variável 'pais'. Temos alguns NaN's. As alternativas que temos são:\n", + " * substituir os NaN's desta variável pela moda (valor mais frequente) da distribuição.\n", + " * substiruir os NaN's por 'Undefined'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KNUkV4x2hLeV" + }, + "source": [ + "Qual o valor (no caso, País) mais frequente ?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OzuJ5p9UKa4v", + "outputId": "02a2b4d1-87ca-4af3-f7cc-60ae42b91930", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "df.pais.value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "France 4\n", + "Spain 3\n", + "Germany 1\n", + "Name: Pais, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 87 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GGmqsEflhYV3" + }, + "source": [ + "Ok, a instância 'France' é o mais frequente. Então vamos substituir os NaN's por 'France'. De forma automática, temos:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ms1EBykBh3Ic", + "outputId": "ddfe280e-8ceb-4bf9-81e3-4b2411d98046", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 52 + } + }, + "source": [ + "sMode_Of_pais = df['pais'].mode()[0]\n", + "sMode_Of_pais" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 France\n", + "dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XhsTLndlhk6W", + "outputId": "64fcc5ac-d9fe-44c4-b370-8ca63861a286", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 359 + } + }, + "source": [ + "df[\"pais2\"] = df[\"pais\"]\n", + "df[\"pais2\"] = df[\"pais2\"].fillna(sMode_Of_pais)\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
IdadeSalarioPaisIdade2Idade3Pais2
032.0HighSpain32.032.0Spain
138.0HighFrance38.038.0France
2NaNHighFranceNaN36.0France
337.0LowNaN37.037.0France
4NaNLowGermanyNaN36.0Germany
536.0HighFrance36.036.0France
638.0NaNSpain38.038.0Spain
732.0MediumFrance32.032.0France
80.0MediumNaN36.036.0France
9NaNHighSpainNaN36.0Spain
\n", + "
" + ], + "text/plain": [ + " Idade Salario Pais Idade2 Idade3 Pais2\n", + "0 32.0 High Spain 32.0 32.0 Spain\n", + "1 38.0 High France 38.0 38.0 France\n", + "2 NaN High France NaN 36.0 France\n", + "3 37.0 Low NaN 37.0 37.0 France\n", + "4 NaN Low Germany NaN 36.0 Germany\n", + "5 36.0 High France 36.0 36.0 France\n", + "6 38.0 NaN Spain 38.0 38.0 Spain\n", + "7 32.0 Medium France 32.0 32.0 France\n", + "8 0.0 Medium NaN 36.0 36.0 France\n", + "9 NaN High Spain NaN 36.0 Spain" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 90 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vdv--JyTj2s8" + }, + "source": [ + "df[\"pais3\"] = df[\"pais\"].fillna('pais_mv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AU7mwDcSkeSz", + "outputId": "a072a642-00ff-465d-a9c5-a2cb45b07e0f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 355 + } + }, + "source": [ + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
idadesalariopaispais3
032.0HighSpainSpain
138.0HighFranceFrance
2NaNHighFranceFrance
337.0LowNaNPais_MV
4NaNLowGermanyGermany
536.0HighFranceFrance
638.0NaNSpainSpain
732.0MediumFranceFrance
80.0MediumNaNPais_MV
9NaNHighSpainSpain
\n", + "
" + ], + "text/plain": [ + " idade salario pais pais3\n", + "0 32.0 High Spain Spain\n", + "1 38.0 High France France\n", + "2 NaN High France France\n", + "3 37.0 Low NaN Pais_MV\n", + "4 NaN Low Germany Germany\n", + "5 36.0 High France France\n", + "6 38.0 NaN Spain Spain\n", + "7 32.0 Medium France France\n", + "8 0.0 Medium NaN Pais_MV\n", + "9 NaN High Spain Spain" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lTtkurTY8ttj" + }, + "source": [ + "# **EXERCÍCIOS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uGQqvlYhiQ56" + }, + "source": [ + "## Exercício 1\n", + "* Trate os NaN's da variável 'salario'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5Nv2-w7t824J" + }, + "source": [ + "## Exercício 2 - Diabetes\n", + "* Carregue o dataframe diabeletes.csv e trate os NaN's." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "48KUsFSe9wwj" + }, + "source": [ + "### Carregar o dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I8RUE_aj9zND" + }, + "source": [ + "url_df= ''\n", + "df = pd.read_csv(url_df)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jgFm2aJL-EaL" + }, + "source": [ + "**Dica**: Algumas medidas não fazem sentido seram nulas (0). Portanto, os NaN's aqui neste dataframe são o valor 0. Portanto, substitua os NaN's (no caso, 0)das variáveis Glucose, BloodPressure, SkinThickness, Insulin e BMI por alguma medida como, por exemplo, média, mediana, moda e etc." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tK0YWKti_znY" + }, + "source": [ + "## Exercício 3 - Titanic\n", + "> Trate os NaN's do dataframe Titanic_With_MV.csv." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aMZzx7iFAFXH" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_hs.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs.ipynb new file mode 100644 index 000000000..1e66371b7 --- /dev/null +++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs.ipynb @@ -0,0 +1,1239 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_3_Data_Transformation.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5CgDLvphxfcX" + }, + "source": [ + "

3DP_3 - DATA TRANSFORMATION

\n", + "\n", + "* **Objetivo**: Preparar os dados para o Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PvW689ZBxbxH" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GNiuYCCxGe8v" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Desenvolver a sessão sobe WOE." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-TdSY74U0XS9" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Why, How and When to Scale your Features](https://medium.com/greyatom/why-how-and-when-to-scale-your-features-4b30ab09db5e)\n", + "* [Demonstrating the different strategies of KBinsDiscretizer](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_strategies.html#sphx-glr-auto-examples-preprocessing-plot-discretization-strategies-py);\n", + "* [Why do we need feature scaling in Machine Learning and how to do it using SciKit Learn?](https://medium.com/@contactsunny/why-do-we-need-feature-scaling-in-machine-learning-and-how-to-do-it-using-scikit-learn-d8314206fe73)\n", + "* [Importance of Feature Scaling](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html#sphx-glr-auto-examples-preprocessing-plot-scaling-importance-py) --> Muito importante por demonstrar os efeitos e a importância de se transformar as colunas numéricas.\n", + "* [Feature discretization](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_classification.html#sphx-glr-auto-examples-preprocessing-plot-discretization-classification-py) --> Mostra o impacto na acurácia dos modelos com e sem discretização. Ou seja, discretizar faz sentido!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l9DGifbWSmW3" + }, + "source": [ + "___\n", + "# **Machine Learning com Python (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vg82Iouo_Qm2" + }, + "source": [ + "# Porque dimensionar (Scale), padronizar (Standardize) e normalizar (Normalize) importa?\n", + "* Porque muitos algoritmos de Machine Learning performam melhor ou convergem mais rápido quando os atributos/colunas/variáveis estão na mesma escala e possuem distribuição \"próxima\" da Normal." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q-chlATnKSza" + }, + "source": [ + "## Carregar as bibliotecas (genéricas) Python" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kQGVQB18-tM_" + }, + "source": [ + "!pip install category_encoders\n", + "!pip install update" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7FJxrZckYxk6" + }, + "source": [ + "import pandas as pd\n", + "\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CyuWQM2NTMls" + }, + "source": [ + "pd.options.display.float_format = '{:.2f}'.format" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R0fuDyI8_UPf" + }, + "source": [ + "## Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oRWtarakgMY" + }, + "source": [ + "### Dataframe gerado aleatoriamente - variáveis com distribuição Normal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BXPXo3k0VDI" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "i_N = 10000\n", + "\n", + "df_A1 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N), # Observem que a média das colunas são distintas\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.normal(-5, 5, i_N),\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "93ST1JnoRZKm" + }, + "source": [ + "**Dica**: Podemos usar outras distribuições (se quisermos), como a Exponential (mostrada abaixo)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XUqjo5QcQH99" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "df_A2 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N),\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.exponential(1, i_N), # coluna3 tem distribuição Exponential\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J8MZNLbUkp8R" + }, + "source": [ + "### Dataframe gerado aleatoriamente 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BR-fDDujcTup" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "dados, classe = make_classification(n_samples = i_N, n_features = 4, n_informative = 3, n_redundant = 1, n_classes = 3)\n", + "\n", + "df_A3 = pd.DataFrame({'coluna1': dados[:,0],\n", + " 'coluna2':dados[:,1],\n", + " 'coluna3':dados[:,2],\n", + " 'coluna4':dados[:,3]}) #, 'coluna5':classe})\n", + "\n", + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zq1cnpwLKvjS" + }, + "source": [ + "df_A4 = pd.DataFrame({ \n", + " 'coluna1': np.random.beta(5, 1, i_N) * 25, \n", + " 'coluna2': np.random.exponential(10, i_N),\n", + " 'coluna3': np.random.normal(10, 2, i_N),\n", + " 'coluna4': np.random.normal(10, 10, i_N), \n", + "})\n", + "\n", + "df_A4.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O7sXQjvYRfhb" + }, + "source": [ + "#### Extração de amostras para compararmos" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rjVHsnnHRkIo" + }, + "source": [ + "df_A1_test = df_A1.sample(n = 100)\n", + "df_A2_test = df_A2.sample(n = 100)\n", + "df_A3_test = df_A3.sample(n = 100)\n", + "df_A4_test = df_A4.sample(n = 100)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t0v0uXFRl-yG" + }, + "source": [ + "___\n", + "# **Transformações**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pkzTO0fdz93b" + }, + "source": [ + "## (1) StandardScaler\n", + "* StandardScaler é a transformação que centraliza os dados através da remoção da média (dos dados) e, na sequência, redimensiona (scale) através da divisão pelo desvio-padrão;\n", + "* Após a transformação, os dados terão média zero e desvio-padrão 1;\n", + "* Assume que os dados (as colunas a serem transformadas) são normalmente distribuidos ;\n", + "* Se os dados não possuem distribuição Normal, então esta não é uma boa transformação a se aplicar.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-mean(x)}{std(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v1UOOWeQ0R_Y" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y1Lzx3xN6wpZ" + }, + "source": [ + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9cPq_7Vu2HCS" + }, + "source": [ + "Histograma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZYW9WwBC3hd_" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A1['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Histograma da coluna3')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h8ogcQvvT5zK" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Histograma da coluna3')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RrgxkESc-Uaq" + }, + "source": [ + "Considere o gráfico a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U7dHTF1W-Xsn" + }, + "source": [ + "df_A1.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hMS72n14-hDO" + }, + "source": [ + "Qual a interpretação para o gráfico acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "izqGNcNILdaX" + }, + "source": [ + "df_A1.plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZEkAqlZg-p0v" + }, + "source": [ + "A seguir, a transformação StandardScaler:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N4u3T_BX-oc_" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "voFQ4odSzzPZ" + }, + "source": [ + "O ideal é termos um array com as preditoras, da seguinte forma:\n", + "X = [coluna1, coluna2, ..., colunaN]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rPa4-SCt-ynX" + }, + "source": [ + "np.set_printoptions(precision = 3)\n", + "\n", + "A1_scale = StandardScaler().fit_transform(df_A1) # Combinação dos métodos fit() + transform()\n", + "\n", + "A1_scale_fit = StandardScaler().fit(df_A1) # Aplica o fit() separadamente\n", + "A1_scale_transform = A1_scale_fit.transform(df_A1) # Aplica o transform() separadamente.\n", + "A1_scale_fit_transform = StandardScaler().fit(df_A1).transform(df_A1) # Aplica fit().transform() encadeado\n", + "\n", + "A2_scale = StandardScaler().fit_transform(df_A2)\n", + "\n", + "A3_scale = StandardScaler().fit_transform(df_A3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ioZ_IN3Z6d39" + }, + "source": [ + "Observe abaixo que A1_scale = A1_scale_transform = A1_scale_fit_transform --> São arrays multidimensionais (do tipo NumPy)!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v4xQR4cu5D1J" + }, + "source": [ + "A1_scale" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "j6GtN2KF4E_A" + }, + "source": [ + "A1_scale_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0q2bvSqb6T4g" + }, + "source": [ + "A1_scale_fit_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WIhaErnA46Fi" + }, + "source": [ + "Transformando em dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HAhRvPze44JW" + }, + "source": [ + "df_A1_scale = pd.DataFrame(A1_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A2_scale = pd.DataFrame(A2_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A3_scale = pd.DataFrame(A3_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bmQp8wDO_E88" + }, + "source": [ + "Agora compare esse novo gráfico abaixo --> Vemos que os dados transformados tem distribuição Normal(0, 1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "csfqRhDH2zUb" + }, + "source": [ + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-krh1pDg22RF" + }, + "source": [ + "df_A1_scale.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2fTPWsm_Hq3" + }, + "source": [ + "df_A1_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9oN-829l3277" + }, + "source": [ + "df_A2.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jqh8L5BeUHT-" + }, + "source": [ + "df_A2_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yvz6O1zk4XNE" + }, + "source": [ + "df_A3.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ffU-fQxCUSmm" + }, + "source": [ + "df_A3_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y24MOLL83w9j" + }, + "source": [ + "### Exercício: Calcular a média e o desvio-padrão." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1Aa25gVlSdOi" + }, + "source": [ + "df_A1.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EXZUiZImSmOE" + }, + "source": [ + "df_A1_scale.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uIUQw5dpRwvA" + }, + "source": [ + "#### Correlação das colunas\n", + "* Observe que as correlações entre as variáveis não se alteram com as transformações." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uj1UerjORq9q" + }, + "source": [ + "df_A1.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jp6vPK0aR_p0" + }, + "source": [ + "df_A1_scale.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4fuURrao_M0c" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f0A9U7rs_RAT" + }, + "source": [ + "## (2) MinMaxScaler\n", + "* **Transformação muito popular e utilizada**.\n", + "* Transforma os dados para o intervalo (0, 1);\n", + "* Se StandardScaler não é aplicável, então essa transformação funciona bem.\n", + "* Sensível aos outliers. Portanto, o ideal é que os outliers sejam tratados previamente.\n", + "* Uma transformação similar à MinMaxScaler() é MaxAbsScaler() que redimensiona os dados no intervalo [-1, 1].\n", + "\n", + "$$z_{i}= \\frac{x_{i}-min(x)}{max(x)-min(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C0HbeuP-AU_p" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mgeLckzxAWaC" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S_W9bTO2AbEg" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PJRFbUpBAg5J" + }, + "source": [ + "A1_MinMaxScaler = MinMaxScaler().fit_transform(df_A1)\n", + "df_A1_MinMaxScaler = pd.DataFrame(A1_MinMaxScaler,columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7g8GA4LTA40U" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Z6D3vfnB9Nm" + }, + "source": [ + "## (3) RobustScaler\n", + "* Transformação ideal para dados com outliers.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-Q_{1}(x)}{Q_{3}(x)-Q_{1}(x)}$$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m3oyuxLeCW1D" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zeDF7-w_CcBy" + }, + "source": [ + "from sklearn.preprocessing import RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vLoqSKijCf2v" + }, + "source": [ + "A1_RobustScaler = RobustScaler().fit_transform(df_A1)\n", + "df_A1_RobustScaler = pd.DataFrame(A1_RobustScaler, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_RobustScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YVMgt-WEFif" + }, + "source": [ + "## Encoding Variáveis Categóricas" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xHYvLc8T_jxQ" + }, + "source": [ + "### Encoding Variáveis Ordinais\n", + "* Exemplo: Variáveis com valores ordinais: baixo, médio ou alto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i1BgGiGdSTcG" + }, + "source": [ + "#### Gera um dataframe como exemplo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kdVahfJAEkuO" + }, + "source": [ + "# Aqui vou usar a função randint - Retorna números inteiros aleatórios incluindo o número inferior e excluindo o superior.\n", + "\n", + "l_idade= [np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40),\n", + " np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40)]\n", + "\n", + "l_salario = ['baixo', 'medio', 'alto']\n", + "l_salario2 = np.random.choice(l_salario, 10, p = [0.6, 0.3, 0.1])\n", + "\n", + "df_A4 = pd.DataFrame({\n", + " 'idade': l_idade,\n", + " 'salario': l_salario2})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m_15P2eUHSBY" + }, + "source": [ + "df_A4" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R1g9pEuyHe2q" + }, + "source": [ + "Neste exemplo, vamos redefinir a variável categórical ordinal 'Salario' da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bkwFuEa8HnMV" + }, + "source": [ + "df_A4['salario_cat'] = df_A4['salario'].map({'baixo': 1, 'medio': 2, 'alto': 3})\n", + "df_A4" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DlaIFiWIIPAl" + }, + "source": [ + "### Encoding Variáveis Nominais\n", + "* Exemplo: Variáveis com valores nominais: Sexo (Feminino, Masculino).\n", + "\n", + "* Use One-Hot Encoding ou pd.get.dummies()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ffNoJQbgJRoY" + }, + "source": [ + "Vamos utilizar o dataframe criado no passo anterior:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PMCoUWZOI7c0" + }, + "source": [ + "df_A4['salario'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bdIEyBkaJeN8" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder, OneHotEncoder" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4MwK4cUEKeK4" + }, + "source": [ + "#### Aplicar LabelEncoder()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6X6VXDsHJiII" + }, + "source": [ + "le = LabelEncoder()\n", + "df_A4['salario_le'] = le.fit_transform(df_A4['salario'])\n", + "df_A4" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RY80x59J8Ham" + }, + "source": [ + "df_A4['salario'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dgv2Zz07Kqfj" + }, + "source": [ + "#### Aplicar pd.get.dummies()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WSZRIEs6K5sP" + }, + "source": [ + "dummies = pd.get_dummies(df_A4['salario'])\n", + "df_A4 = pd.concat([df_A4, dummies], axis = 1)\n", + "df_A4" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CY8GZ-HlNOgm" + }, + "source": [ + "# **Wrap Up**\n", + "* Use MinMaxScaler como transformação default, pois esta transformação não distorce os dados;\n", + "* Use RobustScaler se seus dados/coluna/variável possui outliers e gostaríamos de reduzir o efeito/impacto destes outliers. Entretanto, o melhor tratamento é estudar os outliers cuidadosamente e tratá-los adequadamente;\n", + "* Use StandardScaler se seus dados/colunas/variáveis possuem distribuição Normal (ou pelo menos se aproxima bem da distribuição Normal)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mwh0alhdgrE3" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "> Para cada um dos dataframes a seguir, aplique os seguintes steps:\n", + "\n", + "* Padronizar o nome das colunas\n", + " * Eliminar espaços entre os nomes das colunas;\n", + " * Eliminar caracteres especiais dos nomes das colunas;\n", + " * Renomear as colunas com lower() (ou upper());\n", + "* Aplicar a trasformação StandardScaler e MinMaxScaler em cada uma das colunas do dataframe;\n", + "* DataViz - Mostrar a distribuição das colunas para compararmos os resultados antes e depois das transformações.\n", + "* As correlações das colunas mudam com as transformações?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hSTKrd992LtI" + }, + "source": [ + "## Exercício 1 - Iris --> **Resolvido**\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mThqvGGr2Vuk" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n", + "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eU5FaJhdYblP" + }, + "source": [ + "df_iris.columns = [c.replace(' ', '_') for c in df_iris.columns]\n", + "df_iris.columns = [c.replace('_(cm)', '') for c in df_iris.columns]\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "K9DPAakJZQHH" + }, + "source": [ + "df_iris.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YYYmVq68Y8bB" + }, + "source": [ + "# Aplica a transformação:\n", + "df_iris_MinMaxScaler = MinMaxScaler().fit_transform(df_iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']])\n", + "\n", + "# Transformando em Dataframe:\n", + "df_iris_MinMaxScaler = pd.DataFrame(df_iris_MinMaxScaler, columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])\n", + "\n", + "# Gráfico\n", + "df_iris_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 2 - Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_A1_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_A1_cancer['target'] = df_A1_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_A1_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 3 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_A1_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_A1_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nzu0Dz33c8ds" + }, + "source": [ + "## Exercícios 4 - Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d6ahBZmqc_-1" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_A1_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_A1_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NyunIr6oaWEl" + }, + "source": [ + "## Exercícios 6 - 120 years of Olympic history: athletes and results\n", + "* [120 years of Olympic history: athletes and results](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)\n", + " * Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n", + " * Aplique as transformações que acabamos de estudar nos campos/colunas numéricas 'height' e 'weight'. Cuidado com os Missing Values contidos nas variáveis!\n", + " * Verifique/avalie o impacto dos outliers nestas colunas.\n", + " * Neste caso, qual transformação é mais adequado diante dos outliers?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hB_riY7ID0MV" + }, + "source": [ + "from google.colab import drive\n", + "\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1i3KI-M1Ds2U" + }, + "source": [ + "df = pd.read_csv('/content/drive/My Drive/Colab Notebooks/athlete_events.zip', compression='zip')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lVKFY-FV_2Jx" + }, + "source": [ + "# Para leitura do dataframe no Jupyter Notebook - usar o código abaixo\n", + "url = r'C:\\Users\\81689004720\\Desktop\\Python_Sufis\\Python - Avançado - Nelio\\athlete_events.csv'\n", + "df_olimpiadas = pd.read_csv(url)\n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o5fDp1Ib_Dg8" + }, + "source": [ + "# WOE - Weight Of Evidence\n", + "* As vantagens da transformação WOE são\n", + " * Lida bem com NaN's;\n", + " * Lida bem com outliers;\n", + " * A transformação é baseada no valor logarítmico das distribuições.\n", + " * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente." + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_hs2.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs2.ipynb new file mode 100644 index 000000000..8af225e60 --- /dev/null +++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs2.ipynb @@ -0,0 +1,1580 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_3_Data_Transformation.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5CgDLvphxfcX" + }, + "source": [ + "

3DP_3 - DATA TRANSFORMATION

\n", + "\n", + "* **Objetivo**: Preparar os dados para o Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PvW689ZBxbxH" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GNiuYCCxGe8v" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Desenvolver a sessão sobe WOE." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-TdSY74U0XS9" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Why, How and When to Scale your Features](https://medium.com/greyatom/why-how-and-when-to-scale-your-features-4b30ab09db5e)\n", + "* [Demonstrating the different strategies of KBinsDiscretizer](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_strategies.html#sphx-glr-auto-examples-preprocessing-plot-discretization-strategies-py);\n", + "* [Why do we need feature scaling in Machine Learning and how to do it using SciKit Learn?](https://medium.com/@contactsunny/why-do-we-need-feature-scaling-in-machine-learning-and-how-to-do-it-using-scikit-learn-d8314206fe73)\n", + "* [Importance of Feature Scaling](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html#sphx-glr-auto-examples-preprocessing-plot-scaling-importance-py) --> Muito importante por demonstrar os efeitos e a importância de se transformar as colunas numéricas.\n", + "* [Feature discretization](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_classification.html#sphx-glr-auto-examples-preprocessing-plot-discretization-classification-py) --> Mostra o impacto na acurácia dos modelos com e sem discretização. Ou seja, discretizar faz sentido!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l9DGifbWSmW3" + }, + "source": [ + "___\n", + "# **Machine Learning com Python (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vg82Iouo_Qm2" + }, + "source": [ + "# Porque dimensionar (Scale), padronizar (Standardize) e normalizar (Normalize) importa?\n", + "* Porque muitos algoritmos de **Machine Learning** performam melhor ou convergem mais rápido quando os atributos/colunas/variáveis estão na mesma escala e possuem distribuição \"próxima\" da Normal." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q-chlATnKSza" + }, + "source": [ + "## Carregar as bibliotecas (genéricas) Python" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kQGVQB18-tM_" + }, + "source": [ + "!pip install category_encoders\n", + "!pip install update" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7FJxrZckYxk6" + }, + "source": [ + "import pandas as pd\n", + "\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CyuWQM2NTMls" + }, + "source": [ + "pd.options.display.float_format = '{:.2f}'.format" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R0fuDyI8_UPf" + }, + "source": [ + "## Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oRWtarakgMY" + }, + "source": [ + "### Dataframe gerado aleatoriamente - variáveis com distribuição Normal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BXPXo3k0VDI" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "i_N = 10000\n", + "\n", + "df_A1 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N), # Observem que a média das colunas são distintas\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.normal(-5, 5, i_N),\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "93ST1JnoRZKm" + }, + "source": [ + "**Dica**: Podemos usar outras distribuições (se quisermos), como a Exponential (mostrada abaixo)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XUqjo5QcQH99" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "df_A2 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N),\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.exponential(5, i_N), # coluna3 tem distribuição Exponential\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J8MZNLbUkp8R" + }, + "source": [ + "### Dataframe gerado aleatoriamente 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BR-fDDujcTup" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "dados, classe = make_classification(n_samples = i_N, n_features = 4, n_informative = 3, n_redundant = 1, n_classes = 3)\n", + "\n", + "df_A3 = pd.DataFrame({'coluna1': dados[:,0],\n", + " 'coluna2':dados[:,1],\n", + " 'coluna3':dados[:,2],\n", + " 'coluna4':dados[:,3]}) #, 'coluna5':classe})\n", + "\n", + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zq1cnpwLKvjS" + }, + "source": [ + "df_A4 = pd.DataFrame({ \n", + " 'coluna1': np.random.beta(5, 1, i_N) * 25, \n", + " 'coluna2': np.random.exponential(5, i_N),\n", + " 'coluna3': np.random.normal(10, 2, i_N),\n", + " 'coluna4': np.random.normal(10, 10, i_N), \n", + "})\n", + "\n", + "df_A4.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O7sXQjvYRfhb" + }, + "source": [ + "#### Extração de amostras para compararmos" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rjVHsnnHRkIo" + }, + "source": [ + "df_A1_test = df_A1.sample(n = 100)\n", + "df_A2_test = df_A2.sample(n = 100)\n", + "df_A3_test = df_A3.sample(n = 100)\n", + "df_A4_test = df_A4.sample(n = 100)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t0v0uXFRl-yG" + }, + "source": [ + "___\n", + "# **Transformações**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pkzTO0fdz93b" + }, + "source": [ + "## (1) StandardScaler\n", + "* StandardScaler é a transformação que centraliza os dados através da remoção da média (dos dados) e, na sequência, redimensiona (scale) através da divisão pelo desvio-padrão;\n", + "* Após a transformação, os dados terão média zero e desvio-padrão 1;\n", + "* **Assume que os dados (as colunas a serem transformadas) são normalmente distribuidos**;\n", + "* Se os dados não possuem distribuição Normal, então esta **NÃO** é uma boa transformação a se aplicar.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-mean(x)}{std(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v1UOOWeQ0R_Y" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y1Lzx3xN6wpZ" + }, + "source": [ + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9cPq_7Vu2HCS" + }, + "source": [ + "Histograma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZYW9WwBC3hd_" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A1['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição Normal')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h8ogcQvvT5zK" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição Exponencial')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RrgxkESc-Uaq" + }, + "source": [ + "Considere o gráfico a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U7dHTF1W-Xsn" + }, + "source": [ + "df_A1.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hMS72n14-hDO" + }, + "source": [ + "Qual a interpretação para o gráfico acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "izqGNcNILdaX" + }, + "source": [ + "df_A1.plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZEkAqlZg-p0v" + }, + "source": [ + "A seguir, a transformação StandardScaler:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N4u3T_BX-oc_" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "voFQ4odSzzPZ" + }, + "source": [ + "O ideal é termos um array com as preditoras, da seguinte forma:\n", + "X = [coluna1, coluna2, ..., colunaN]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rPa4-SCt-ynX" + }, + "source": [ + "np.set_printoptions(precision = 3)\n", + "\n", + "A1_scale = StandardScaler().fit_transform(df_A1) # Combinação dos métodos fit() + transform()\n", + "\n", + "A1_scale_fit = StandardScaler().fit(df_A1) # Aplica o fit() separadamente\n", + "A1_scale_transform = A1_scale_fit.transform(df_A1) # Aplica o transform() separadamente.\n", + "A1_scale_fit_transform = StandardScaler().fit(df_A1).transform(df_A1) # Aplica fit().transform() encadeado\n", + "\n", + "A2_scale = StandardScaler().fit_transform(df_A2)\n", + "\n", + "A3_scale = StandardScaler().fit_transform(df_A3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a8tZJgbOplDd" + }, + "source": [ + "## Salvar os parâmetros do StandardScaler e outros --> Colocar aqui!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ERfRIz-njqcD" + }, + "source": [ + "A1_scale_fit.scale_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ioZ_IN3Z6d39" + }, + "source": [ + "Observe abaixo que A1_scale = A1_scale_transform = A1_scale_fit_transform --> São arrays multidimensionais (do tipo NumPy)!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v4xQR4cu5D1J" + }, + "source": [ + "A1_scale" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "j6GtN2KF4E_A" + }, + "source": [ + "A1_scale_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0q2bvSqb6T4g" + }, + "source": [ + "A1_scale_fit_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WIhaErnA46Fi" + }, + "source": [ + "Transformando em dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HAhRvPze44JW" + }, + "source": [ + "df_A1_scale = pd.DataFrame(A1_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A2_scale = pd.DataFrame(A2_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A3_scale = pd.DataFrame(A3_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bmQp8wDO_E88" + }, + "source": [ + "Agora compare esse novo gráfico abaixo --> Vemos que os dados transformados tem distribuição Normal(0, 1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "csfqRhDH2zUb" + }, + "source": [ + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-krh1pDg22RF" + }, + "source": [ + "df_A1_scale.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2fTPWsm_Hq3" + }, + "source": [ + "df_A1_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9oN-829l3277" + }, + "source": [ + "df_A2.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jqh8L5BeUHT-" + }, + "source": [ + "df_A2_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yvz6O1zk4XNE" + }, + "source": [ + "df_A3.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ffU-fQxCUSmm" + }, + "source": [ + "df_A3_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y24MOLL83w9j" + }, + "source": [ + "### Exercício: Calcular a média e o desvio-padrão." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1Aa25gVlSdOi" + }, + "source": [ + "df_A1.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EXZUiZImSmOE" + }, + "source": [ + "df_A1_scale.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uIUQw5dpRwvA" + }, + "source": [ + "#### Correlação das colunas\n", + "* Observe que as correlações entre as variáveis não se alteram com as transformações." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uj1UerjORq9q" + }, + "source": [ + "df_A1.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jp6vPK0aR_p0" + }, + "source": [ + "df_A1_scale.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4fuURrao_M0c" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f0A9U7rs_RAT" + }, + "source": [ + "## (2) MinMaxScaler\n", + "* **Transformação muito popular e utilizada**.\n", + "* Transforma os dados para o intervalo [0, 1];\n", + "* Se StandardScaler não é aplicável, então essa transformação funciona bem.\n", + "* Sensível aos _outliers_. Portanto, o ideal é que os _outliers_ sejam tratados previamente.\n", + "* Uma transformação similar à MinMaxScaler() é MaxAbsScaler() (redimensiona os dados no intervalo [-1, 1]) e centralizado em 0).\n", + "* Não corrige skewness;\n", + "* Sensível à outliers;\n", + "\n", + "$$z_{i}= \\frac{x_{i}-min(x)}{max(x)-min(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C0HbeuP-AU_p" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mgeLckzxAWaC" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S_W9bTO2AbEg" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PJRFbUpBAg5J" + }, + "source": [ + "A1_MinMaxScaler = MinMaxScaler().fit_transform(df_A1)\n", + "df_A1_MinMaxScaler = pd.DataFrame(A1_MinMaxScaler,columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7g8GA4LTA40U" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Z6D3vfnB9Nm" + }, + "source": [ + "## (3) RobustScaler\n", + "* Transformação ideal para dados com **outliers**.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-Q_{1}(x)}{Q_{3}(x)-Q_{1}(x)}$$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m3oyuxLeCW1D" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zeDF7-w_CcBy" + }, + "source": [ + "from sklearn.preprocessing import RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vLoqSKijCf2v" + }, + "source": [ + "A1_RobustScaler = RobustScaler().fit_transform(df_A1)\n", + "df_A1_RobustScaler = pd.DataFrame(A1_RobustScaler, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_RobustScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_D-7ik2xXpU" + }, + "source": [ + "### **Insight**: Gerar aleatoriamente colunas/variáveis com distribuição Gamma, Beta, Normal, Exponential e etc e avaliar o impacto das várias transformações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GxIOPmSYwX-e" + }, + "source": [ + "# **Wrap Up**\n", + "* Use MinMaxScaler como transformação default, pois esta transformação não distorce os dados;\n", + "* Use RobustScaler se seus dados/coluna/variável possui **outliers** e gostaríamos de reduzir o efeito/impacto destes **outliers**. Entretanto, o melhor tratamento é estudar os **outliers** cuidadosamente e tratá-los adequadamente;\n", + "* Use StandardScaler se seus dados/colunas/variáveis possuem distribuição Normal (ou pelo menos se aproxima bem da distribuição Normal)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YVMgt-WEFif" + }, + "source": [ + "## Encoding Variáveis Categóricas" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xHYvLc8T_jxQ" + }, + "source": [ + "### Encoding Variáveis Ordinais\n", + "* Exemplo: Variáveis com valores ordinais: baixo, médio ou alto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i1BgGiGdSTcG" + }, + "source": [ + "#### Dataframe-exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kdVahfJAEkuO" + }, + "source": [ + "# Aqui vou usar a função randint - Retorna números inteiros aleatórios incluindo o número inferior e excluindo o superior.\n", + "\n", + "l_idade = [\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40), \n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40)\n", + " ]\n", + "\n", + "l_salario = ['baixo', 'medio', 'alto']\n", + "l_salario2 = np.random.choice(l_salario, 10, p = [0.6, 0.3, 0.1])\n", + "\n", + "df_A5 = pd.DataFrame({\n", + " 'idade': l_idade,\n", + " 'salario': l_salario2})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m_15P2eUHSBY" + }, + "source": [ + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R1g9pEuyHe2q" + }, + "source": [ + "Neste exemplo, vamos redefinir a variável categórical ordinal 'Salario' da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bkwFuEa8HnMV" + }, + "source": [ + "df_A5['salario_cat'] = df_A5['salario'].map({'baixo': 1, 'medio': 2, 'alto': 3})\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DlaIFiWIIPAl" + }, + "source": [ + "### Encoding Variáveis Nominais\n", + "* Exemplo: Variáveis com valores nominais: Sexo (Feminino, Masculino).\n", + "\n", + "* Use One-Hot Encoding ou pd.get.dummies()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ffNoJQbgJRoY" + }, + "source": [ + "Vamos utilizar o dataframe criado no passo anterior:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PMCoUWZOI7c0" + }, + "source": [ + "df_A5['salario'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bdIEyBkaJeN8" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder, OneHotEncoder" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4MwK4cUEKeK4" + }, + "source": [ + "#### Aplicar LabelEncoder()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6X6VXDsHJiII" + }, + "source": [ + "le = LabelEncoder()\n", + "df_A5['salario_le'] = le.fit_transform(df_A5['salario'])\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RY80x59J8Ham" + }, + "source": [ + "df_A5['salario'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dgv2Zz07Kqfj" + }, + "source": [ + "#### Aplicar pd.get.dummies()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WSZRIEs6K5sP" + }, + "source": [ + "dummies = pd.get_dummies(df_A5['salario'])\n", + "df_A5 = pd.concat([df_A5, dummies], axis = 1)\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WeXKQ3lkg8qO" + }, + "source": [ + "# Power Transformations\n", + "* Tem por objetivo transformar a distribuição de probabilidade da variável/coluna a fim de torná-la Normal. Esta normalização é feita através da correção da skewness (estabilização da variância) da distribuição.\n", + "* Exemplos de Power Transformations:\n", + " * log;\n", + " * Ajuda com distribuições skewness;\n", + " * Útil para distribuições não-negativas e sem zeros;\n", + " * raiz quadrada;\n", + " * raiz cúbica;\n", + " * Transformação de Box-Cox e\n", + " * Transformação de Yeo-Johson." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BQDf9EfzRXYC" + }, + "source": [ + "### Transformação de Yeo-Johnson" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9q9lxbYhlKE" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Histograma da coluna3 - Distribuição Exponencial')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QJ91Stekh8JO" + }, + "source": [ + "from sklearn.preprocessing import PowerTransformer" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RCGFIeszkLVK" + }, + "source": [ + "df_A2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOQYdkyzi-PL" + }, + "source": [ + "yeo_johnson = PowerTransformer(method = 'yeo-johnson', standardize = True)\n", + "A2_yeo_johnson = yeo_johnson.fit_transform(df_A2)\n", + "df_A2_yeo_johnson = pd.DataFrame(A2_yeo_johnson, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A2_yeo_johnson.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T_5beALqkao_" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2_yeo_johnson['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição aproximadamente Normal')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BwEhZBARk7oA" + }, + "source": [ + "## Transformação de Box-Cox\n", + "* Inventada por dois grandes personagens da Estatística;\n", + "* A coluna/variável/atributo não pode conter números negativos ou zero. Ou seja, $X_{i} > 0$.\n", + "\n", + "* Se $w_{i}$ é a variável transformada e $x_{i}$ é a variável que queremos transformar.\n", + " * Se $\\lambda = 0$ --> $w_{i}^{(\\lambda)} = \\log(x_{i})$;\n", + " * Se $\\lambda <> 0$ --> $w_{i}^{(\\lambda)} = \\frac{x_{i}-1}{\\lambda}$;\n", + "* Se $\\lambda = 1$, então $w_{i}$ então os dados/distribuição já são normalmente distribuídos e a transformação de Box&Cox não se faz necessário.\n", + "* Precisamos escolher o valor de $\\lambda$ que permite a melhor aproximação da distribuição normal.\n", + "* A função scipy.stats.boxcox(array_1D) retorna o valor de $\\lambda$ ótimo. Basta passar como parâmetro o array de dimensão 1D que a função retorna o $\\lambda$ ótimo que melhor se ajusta aos seus dados.\n", + "* Para retornar seus dados aos valores originais, use scipy.special.inv_boxcox(y, lambda).\n", + "* Quais são as desvantagens da transformação?\n", + " * Perde-se a interpretação." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AZXkW4Baz87T" + }, + "source": [ + "Libraries necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QzWRS8chz8V_" + }, + "source": [ + "import numpy as np \n", + "from scipy import stats \n", + "import matplotlib.pyplot as plt " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lwyGVDMzC4y" + }, + "source": [ + "### Exemplo 1\n", + "* Dados possuem distribuição Exponencial." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tx5J1L8Az4qQ" + }, + "source": [ + "# Gráficos: \n", + "def compara_graficos(y, w, lambda_box_cox):\n", + " fig, ax = plt.subplots(1, 2) \n", + " \n", + " # Gráfico das distribuições originais e transformada\n", + " sns.distplot(y, hist = False, kde = True, kde_kws = {'shade': True, 'linewidth': 2}, label = \"Non-Normal\", color =\"green\", ax = ax[0]) \n", + " sns.distplot(w, hist = False, kde = True, kde_kws = {'shade': True, 'linewidth': 2}, label = \"Normal\", color =\"green\", ax = ax[1]) \n", + " \n", + " # Legendas \n", + " plt.legend(loc = \"upper right\") \n", + " \n", + " # Redimensionando os sub-gráficos \n", + " fig.set_figheight(5) \n", + " fig.set_figwidth(10) \n", + " \n", + " print(f\"Valor de Lambda usado na transformação: {lambda_box_cox}\") " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cf5PPVl9Rr5H" + }, + "source": [ + "Transforma os dados/distribuições:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xWLsXEBB0CQO" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_exponencial = np.random.exponential(size = 1000) \n", + "\n", + "# Dados transformados \n", + "box_cox, lambda_box_cox = stats.boxcox(distribuicao_exponencial) \n", + "compara_graficos(distribuicao_exponencial, box_cox, lambda_box_cox)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F9jObBLCZh19" + }, + "source": [ + "### Exemplo 2\n", + "* Dados possuem distribuição Beta.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CePoB8imzPRQ" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_beta = np.random.beta(1, 3, 1000)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "j1CwLPm6zRx2" + }, + "source": [ + "# transform training data & save lambda value \n", + "box_cox, lambda_box_cox = stats.boxcox(distribuicao_beta) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "snd63l9U0ugI" + }, + "source": [ + "compara_graficos(distribuicao_beta, box_cox, lambda_box_cox)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CQ6o9pOkPjUT" + }, + "source": [ + "### Transformação log\n", + "* De forma geral, a transformação **log** trata de dados skewed, tornando os dados (ou a distribuição dos dados) mais \"normal\";\n", + "* Se os dados forem de alguma forma normalmente distribuídos, então nada muda." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DrsXETsRPupd" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_beta = np.random.beta(1, 3, 1000)\n", + "\n", + "transformacao_log = np.log(distribuicao_beta)\n", + "compara_graficos(distribuicao_beta, transformacao_log, 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mwh0alhdgrE3" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "> Para cada um dos dataframes a seguir, aplique os seguintes steps:\n", + "\n", + "* Padronizar o nome das colunas\n", + " * Eliminar espaços entre os nomes das colunas;\n", + " * Eliminar caracteres especiais dos nomes das colunas;\n", + " * Renomear as colunas com lower() (ou upper());\n", + "* Aplicar a trasformação StandardScaler e MinMaxScaler em cada uma das colunas do dataframe;\n", + "* DataViz - Mostrar a distribuição das colunas para compararmos os resultados antes e depois das transformações.\n", + "* As correlações das colunas mudam com as transformações?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hSTKrd992LtI" + }, + "source": [ + "## Exercício 1 - Iris --> **Resolvido**\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mThqvGGr2Vuk" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n", + "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eU5FaJhdYblP" + }, + "source": [ + "df_iris.columns = [c.replace(' ', '_') for c in df_iris.columns]\n", + "df_iris.columns = [c.replace('_(cm)', '') for c in df_iris.columns]\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "K9DPAakJZQHH" + }, + "source": [ + "df_iris.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YYYmVq68Y8bB" + }, + "source": [ + "# Aplica a transformação:\n", + "df_iris_MinMaxScaler = MinMaxScaler().fit_transform(df_iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']])\n", + "\n", + "# Transformando em Dataframe:\n", + "df_iris_MinMaxScaler = pd.DataFrame(df_iris_MinMaxScaler, columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])\n", + "\n", + "# Gráfico\n", + "df_iris_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DKsHcjd77YZT" + }, + "source": [ + "### Aplicar as outras transformações e comparar os gráficos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 2 - Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_A1_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_A1_cancer['target'] = df_A1_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_A1_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 3 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_A1_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_A1_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nzu0Dz33c8ds" + }, + "source": [ + "## Exercícios 4 - Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d6ahBZmqc_-1" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_A1_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_A1_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NyunIr6oaWEl" + }, + "source": [ + "## Exercícios 5 - 120 years of Olympic history: athletes and results\n", + "* [120 years of Olympic history: athletes and results](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)\n", + " * Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n", + " * Aplique as transformações que acabamos de estudar nos campos/colunas numéricas 'height' e 'weight'. Cuidado com os Missing Values contidos nas variáveis!\n", + " * Verifique/avalie o impacto dos outliers nestas colunas.\n", + " * Neste caso, qual transformação é mais adequado diante dos outliers?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8V7OCd3G9zj1" + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z3g4dqM190mj" + }, + "source": [ + "url = '/content/drive/My Drive/Datasets4ML/athlete_events.csv'\n", + "df = pd.read_csv(url)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ExKsjGmKaEx" + }, + "source": [ + "## Exercício 6 - FIFA\n", + "* Aplique as transformações MinMaxScaler, RobustScaler e StandardScaler às colunas numéricas do dataframe FIFA_algumas_features.csv.\n", + "* Para as colunas categóricas, aplique a transformação mais adequada." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zjukr52HK3S_" + }, + "source": [ + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S41tXs2EKlHN" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA_algumas_features.csv?token=AGDJQ62CSW5KBLZNXH4TULK7SXICE'\n", + "\n", + "df = pd.read_csv(url, index_col = 'ID')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o5fDp1Ib_Dg8" + }, + "source": [ + "# WOE - Weight Of Evidence\n", + "* As vantagens da transformação WOE são\n", + " * Lida bem com NaN's;\n", + " * Lida bem com outliers;\n", + " * A transformação é baseada no valor logarítmico das distribuições.\n", + " * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente." + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_hs3.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs3.ipynb new file mode 100644 index 000000000..0a188359e --- /dev/null +++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_hs3.ipynb @@ -0,0 +1,1642 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_3_Data_Transformation.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5CgDLvphxfcX" + }, + "source": [ + "

3DP_3 - DATA TRANSFORMATION

\n", + "\n", + "* **Objetivo**: Preparar os dados para o Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PvW689ZBxbxH" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GNiuYCCxGe8v" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Desenvolver a sessão sobe WOE." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-TdSY74U0XS9" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Why, How and When to Scale your Features](https://medium.com/greyatom/why-how-and-when-to-scale-your-features-4b30ab09db5e)\n", + "* [Demonstrating the different strategies of KBinsDiscretizer](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_strategies.html#sphx-glr-auto-examples-preprocessing-plot-discretization-strategies-py);\n", + "* [Why do we need feature scaling in Machine Learning and how to do it using SciKit Learn?](https://medium.com/@contactsunny/why-do-we-need-feature-scaling-in-machine-learning-and-how-to-do-it-using-scikit-learn-d8314206fe73)\n", + "* [Importance of Feature Scaling](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html#sphx-glr-auto-examples-preprocessing-plot-scaling-importance-py) --> Muito importante por demonstrar os efeitos e a importância de se transformar as colunas numéricas.\n", + "* [Feature discretization](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_classification.html#sphx-glr-auto-examples-preprocessing-plot-discretization-classification-py) --> Mostra o impacto na acurácia dos modelos com e sem discretização. Ou seja, discretizar faz sentido!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l9DGifbWSmW3" + }, + "source": [ + "___\n", + "# **Machine Learning com Python (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vg82Iouo_Qm2" + }, + "source": [ + "# Porque dimensionar (Scale), padronizar (Standardize) e normalizar (Normalize) importa?\n", + "* Porque muitos algoritmos de **Machine Learning** performam melhor ou convergem mais rápido quando os atributos/colunas/variáveis estão na mesma escala e possuem distribuição \"próxima\" da Normal." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q-chlATnKSza" + }, + "source": [ + "## Carregar as bibliotecas (genéricas) Python" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kQGVQB18-tM_" + }, + "source": [ + "!pip install category_encoders\n", + "!pip install update" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7FJxrZckYxk6" + }, + "source": [ + "import pandas as pd\n", + "\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CyuWQM2NTMls" + }, + "source": [ + "pd.options.display.float_format = '{:.2f}'.format" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R0fuDyI8_UPf" + }, + "source": [ + "## Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oRWtarakgMY" + }, + "source": [ + "### Dataframe gerado aleatoriamente - variáveis com distribuição Normal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BXPXo3k0VDI" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "i_N = 10000\n", + "\n", + "df_A1 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N), # Observem que a média das colunas são distintas\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.normal(-5, 5, i_N),\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "93ST1JnoRZKm" + }, + "source": [ + "**Dica**: Podemos usar outras distribuições (se quisermos), como a Exponential (mostrada abaixo)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XUqjo5QcQH99" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "df_A2 = pd.DataFrame({\n", + " 'coluna1': np.random.normal(0, 2, i_N),\n", + " 'coluna2': np.random.normal(50, 3, i_N),\n", + " 'coluna3': np.random.exponential(5, i_N), # coluna3 tem distribuição Exponential\n", + " 'coluna4': np.random.normal(-10, 10, i_N)\n", + "})\n", + "\n", + "df_A2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J8MZNLbUkp8R" + }, + "source": [ + "### Dataframe gerado aleatoriamente 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BR-fDDujcTup" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "dados, classe = make_classification(n_samples = i_N, n_features = 4, n_informative = 3, n_redundant = 1, n_classes = 3)\n", + "\n", + "df_A3 = pd.DataFrame({'coluna1': dados[:,0],\n", + " 'coluna2':dados[:,1],\n", + " 'coluna3':dados[:,2],\n", + " 'coluna4':dados[:,3]}) #, 'coluna5':classe})\n", + "\n", + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zq1cnpwLKvjS" + }, + "source": [ + "df_A4 = pd.DataFrame({ \n", + " 'coluna1': np.random.beta(5, 1, i_N) * 25, \n", + " 'coluna2': np.random.exponential(5, i_N),\n", + " 'coluna3': np.random.normal(10, 2, i_N),\n", + " 'coluna4': np.random.normal(10, 10, i_N), \n", + "})\n", + "\n", + "df_A4.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O7sXQjvYRfhb" + }, + "source": [ + "#### Extração de amostras para compararmos" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rjVHsnnHRkIo" + }, + "source": [ + "df_A1_test = df_A1.sample(n = 100)\n", + "df_A2_test = df_A2.sample(n = 100)\n", + "df_A3_test = df_A3.sample(n = 100)\n", + "df_A4_test = df_A4.sample(n = 100)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t0v0uXFRl-yG" + }, + "source": [ + "___\n", + "# **Transformações**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pkzTO0fdz93b" + }, + "source": [ + "## (1) StandardScaler\n", + "* StandardScaler é a transformação que centraliza os dados através da remoção da média (dos dados) e, na sequência, redimensiona (scale) através da divisão pelo desvio-padrão;\n", + "* Após a transformação, os dados terão média zero e desvio-padrão 1;\n", + "* **Assume que os dados (as colunas a serem transformadas) são normalmente distribuidos**;\n", + "* Se os dados não possuem distribuição Normal, então esta **NÃO** é uma boa transformação a se aplicar.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-mean(x)}{std(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v1UOOWeQ0R_Y" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y1Lzx3xN6wpZ" + }, + "source": [ + "df_A3.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9cPq_7Vu2HCS" + }, + "source": [ + "Histograma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZYW9WwBC3hd_" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A1['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição Normal')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h8ogcQvvT5zK" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição Exponencial')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RrgxkESc-Uaq" + }, + "source": [ + "Considere o gráfico a seguir:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U7dHTF1W-Xsn" + }, + "source": [ + "df_A1.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma." + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hMS72n14-hDO" + }, + "source": [ + "Qual a interpretação para o gráfico acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "izqGNcNILdaX" + }, + "source": [ + "df_A1.plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZEkAqlZg-p0v" + }, + "source": [ + "A seguir, a transformação StandardScaler:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N4u3T_BX-oc_" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "voFQ4odSzzPZ" + }, + "source": [ + "O ideal é termos um array com as preditoras, da seguinte forma:\n", + "X = [coluna1, coluna2, ..., colunaN]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rPa4-SCt-ynX" + }, + "source": [ + "np.set_printoptions(precision = 3)\n", + "\n", + "A1_scale = StandardScaler().fit_transform(df_A1) # Combinação dos métodos fit() + transform()\n", + "\n", + "A1_scale_fit = StandardScaler().fit(df_A1) # Aplica o fit() separadamente\n", + "A1_scale_transform = A1_scale_fit.transform(df_A1) # Aplica o transform() separadamente.\n", + "A1_scale_fit_transform = StandardScaler().fit(df_A1).transform(df_A1) # Aplica fit().transform() encadeado\n", + "\n", + "A2_scale = StandardScaler().fit_transform(df_A2)\n", + "\n", + "A3_scale = StandardScaler().fit_transform(df_A3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a8tZJgbOplDd" + }, + "source": [ + "## Salvar os parâmetros do StandardScaler e outros --> Colocar aqui!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ERfRIz-njqcD" + }, + "source": [ + "A1_scale_fit.scale_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ioZ_IN3Z6d39" + }, + "source": [ + "Observe abaixo que A1_scale = A1_scale_transform = A1_scale_fit_transform --> São arrays multidimensionais (do tipo NumPy)!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v4xQR4cu5D1J" + }, + "source": [ + "A1_scale" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "j6GtN2KF4E_A" + }, + "source": [ + "A1_scale_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0q2bvSqb6T4g" + }, + "source": [ + "A1_scale_fit_transform" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WIhaErnA46Fi" + }, + "source": [ + "Transformando em dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HAhRvPze44JW" + }, + "source": [ + "df_A1_scale = pd.DataFrame(A1_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A2_scale = pd.DataFrame(A2_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A3_scale = pd.DataFrame(A3_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bmQp8wDO_E88" + }, + "source": [ + "Agora compare esse novo gráfico abaixo --> Vemos que os dados transformados tem distribuição Normal(0, 1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "csfqRhDH2zUb" + }, + "source": [ + "df_A1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-krh1pDg22RF" + }, + "source": [ + "df_A1_scale.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2fTPWsm_Hq3" + }, + "source": [ + "df_A1_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9oN-829l3277" + }, + "source": [ + "df_A2.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jqh8L5BeUHT-" + }, + "source": [ + "df_A2_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Yvz6O1zk4XNE" + }, + "source": [ + "df_A3.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ffU-fQxCUSmm" + }, + "source": [ + "df_A3_scale.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y24MOLL83w9j" + }, + "source": [ + "### Exercício: Calcular a média e o desvio-padrão." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1Aa25gVlSdOi" + }, + "source": [ + "df_A1.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EXZUiZImSmOE" + }, + "source": [ + "df_A1_scale.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uIUQw5dpRwvA" + }, + "source": [ + "#### Correlação das colunas\n", + "* Observe que as correlações entre as variáveis não se alteram com as transformações." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uj1UerjORq9q" + }, + "source": [ + "df_A1.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jp6vPK0aR_p0" + }, + "source": [ + "df_A1_scale.corr()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4fuURrao_M0c" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f0A9U7rs_RAT" + }, + "source": [ + "## (2) MinMaxScaler\n", + "* **Transformação muito popular e utilizada**.\n", + "* Transforma os dados para o intervalo [0, 1];\n", + "* Se StandardScaler não é aplicável, então essa transformação funciona bem.\n", + "* Sensível aos _outliers_. Portanto, o ideal é que os _outliers_ sejam tratados previamente.\n", + "* Uma transformação similar à MinMaxScaler() é MaxAbsScaler() (redimensiona os dados no intervalo [-1, 1]) e centralizado em 0).\n", + "* Não corrige skewness;\n", + "* Sensível à outliers;\n", + "\n", + "$$z_{i}= \\frac{x_{i}-min(x)}{max(x)-min(x)}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C0HbeuP-AU_p" + }, + "source": [ + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mgeLckzxAWaC" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S_W9bTO2AbEg" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PJRFbUpBAg5J" + }, + "source": [ + "A1_MinMaxScaler = MinMaxScaler().fit_transform(df_A1)\n", + "df_A1_MinMaxScaler = pd.DataFrame(A1_MinMaxScaler,columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7g8GA4LTA40U" + }, + "source": [ + "Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Z6D3vfnB9Nm" + }, + "source": [ + "## (3) RobustScaler\n", + "* Transformação ideal para dados com **outliers**.\n", + "\n", + "$$z_{i}= \\frac{x_{i}-Q_{1}(x)}{Q_{3}(x)-Q_{1}(x)}$$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m3oyuxLeCW1D" + }, + "source": [ + "df_A1.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zeDF7-w_CcBy" + }, + "source": [ + "from sklearn.preprocessing import RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vLoqSKijCf2v" + }, + "source": [ + "A1_RobustScaler = RobustScaler().fit_transform(df_A1)\n", + "df_A1_RobustScaler = pd.DataFrame(A1_RobustScaler, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "\n", + "# Gráfico\n", + "df_A1_RobustScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g_D-7ik2xXpU" + }, + "source": [ + "### **Insight**: Gerar aleatoriamente colunas/variáveis com distribuição Gamma, Beta, Normal, Exponential e etc e avaliar o impacto das várias transformações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GxIOPmSYwX-e" + }, + "source": [ + "# **Wrap Up**\n", + "* Use MinMaxScaler como transformação default, pois esta transformação não distorce os dados;\n", + "* Use RobustScaler se seus dados/coluna/variável possui **outliers** e gostaríamos de reduzir o efeito/impacto destes **outliers**. Entretanto, o melhor tratamento é estudar os **outliers** cuidadosamente e tratá-los adequadamente;\n", + "* Use StandardScaler se seus dados/colunas/variáveis possuem distribuição Normal (ou pelo menos se aproxima bem da distribuição Normal)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YVMgt-WEFif" + }, + "source": [ + "## Encoding Variáveis Categóricas" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xHYvLc8T_jxQ" + }, + "source": [ + "### Encoding Variáveis Ordinais\n", + "* Exemplo: Variáveis com valores ordinais: baixo, médio ou alto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i1BgGiGdSTcG" + }, + "source": [ + "#### Dataframe-exemplo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kdVahfJAEkuO" + }, + "source": [ + "# Aqui vou usar a função randint - Retorna números inteiros aleatórios incluindo o número inferior e excluindo o superior.\n", + "\n", + "l_idade = [\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40), \n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40),\n", + " np.random.randint(20, 40)\n", + " ]\n", + "\n", + "l_salario = ['baixo', 'medio', 'alto']\n", + "l_salario2 = np.random.choice(l_salario, 10, p = [0.6, 0.3, 0.1])\n", + "\n", + "df_A5 = pd.DataFrame({\n", + " 'idade': l_idade,\n", + " 'salario': l_salario2})" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m_15P2eUHSBY" + }, + "source": [ + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R1g9pEuyHe2q" + }, + "source": [ + "Neste exemplo, vamos redefinir a variável categórical ordinal 'Salario' da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bkwFuEa8HnMV" + }, + "source": [ + "df_A5['salario_cat'] = df_A5['salario'].map({'baixo': 1, 'medio': 2, 'alto': 3})\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DlaIFiWIIPAl" + }, + "source": [ + "### Encoding Variáveis Nominais\n", + "* Exemplo: Variáveis com valores nominais: Sexo (Feminino, Masculino).\n", + "\n", + "* Use One-Hot Encoding ou pd.get.dummies()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ffNoJQbgJRoY" + }, + "source": [ + "Vamos utilizar o dataframe criado no passo anterior:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PMCoUWZOI7c0" + }, + "source": [ + "df_A5['salario'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bdIEyBkaJeN8" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder, OneHotEncoder" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4MwK4cUEKeK4" + }, + "source": [ + "#### Aplicar LabelEncoder()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6X6VXDsHJiII" + }, + "source": [ + "le = LabelEncoder()\n", + "df_A5['salario_le'] = le.fit_transform(df_A5['salario'])\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RY80x59J8Ham" + }, + "source": [ + "df_A5['salario'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dgv2Zz07Kqfj" + }, + "source": [ + "#### Aplicar pd.get.dummies()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WSZRIEs6K5sP" + }, + "source": [ + "dummies = pd.get_dummies(df_A5['salario'])\n", + "df_A5 = pd.concat([df_A5, dummies], axis = 1)\n", + "df_A5" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WeXKQ3lkg8qO" + }, + "source": [ + "# Power Transformations\n", + "* Tem por objetivo transformar a distribuição de probabilidade da variável/coluna a fim de torná-la Normal. Esta normalização é feita através da correção da skewness (estabilização da variância) da distribuição.\n", + "* Exemplos de Power Transformations:\n", + " * log;\n", + " * Ajuda com distribuições skewness;\n", + " * Útil para distribuições não-negativas e sem zeros;\n", + " * raiz quadrada;\n", + " * raiz cúbica;\n", + " * **Transformação de Box-Cox** e\n", + " * Transformação de Yeo-Johson." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BQDf9EfzRXYC" + }, + "source": [ + "### Transformação de Yeo-Johnson (transformação default da librarie PowerTransformer)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9q9lxbYhlKE" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Histograma da coluna3 - Distribuição Exponencial')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QJ91Stekh8JO" + }, + "source": [ + "from sklearn.preprocessing import PowerTransformer" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RCGFIeszkLVK" + }, + "source": [ + "df_A2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iNVvFc4NMcB2" + }, + "source": [ + "dados = objeto.transform(dataframe)\n", + "dados_transformados = fit(df).transform(df)\n", + "dados_transformados = fit_transform(df)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOQYdkyzi-PL" + }, + "source": [ + "yeo_johnson = PowerTransformer(method = 'yeo-johnson', standardize = True)\n", + "A2_yeo_johnson = yeo_johnson.fit_transform(df_A2)\n", + "A2_yeo_johnson # array NumPy com os dados transformados" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yn1T_TY9M2nR" + }, + "source": [ + "df_A2_yeo_johnson = pd.DataFrame(A2_yeo_johnson, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n", + "df_A2_yeo_johnson.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T_5beALqkao_" + }, + "source": [ + "plt.figure(figsize = (12, 8))\n", + "plt.hist(df_A2_yeo_johnson['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n", + "\n", + "# Adiciona títulos e labels\n", + "plt.title('Coluna3 - Distribuição aproximadamente Normal')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BwEhZBARk7oA" + }, + "source": [ + "## Transformação de Box-Cox\n", + "* Inventada por dois grandes personagens da Estatística;\n", + "* A coluna/variável/atributo não pode conter números negativos ou zero. Ou seja, $x_{i} > 0$.\n", + "\n", + "* Se $w_{i}$ é a variável transformada e $x_{i}$ é a variável que queremos transformar.\n", + " * Se $\\lambda = 0$ --> $w_{i}^{(\\lambda)} = \\log(x_{i})$;\n", + " * Se $\\lambda <> 0$ --> $w_{i}^{(\\lambda)} = \\frac{x_{i}-1}{\\lambda}$;\n", + "* Se $\\lambda = 1$, então $w_{i}$ então os dados/distribuição já são normalmente distribuídos e a transformação de Box&Cox não se faz necessário.\n", + "* Precisamos escolher o valor de $\\lambda$ que permite a melhor aproximação da distribuição normal.\n", + "* A função scipy.stats.boxcox(array_1D) retorna o valor de $\\lambda$ ótimo. Basta passar como parâmetro o array de dimensão 1D que a função retorna o $\\lambda$ ótimo que melhor se ajusta aos seus dados.\n", + "* Para retornar seus dados aos valores originais, use scipy.special.inv_boxcox(y, lambda).\n", + "* Quais são as desvantagens/inconveniente da transformação?\n", + " * Perde-se a interpretação." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AZXkW4Baz87T" + }, + "source": [ + "Libraries necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QzWRS8chz8V_" + }, + "source": [ + "import numpy as np \n", + "from scipy import stats \n", + "import matplotlib.pyplot as plt " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iWQlhjRpO1Zc" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_exponencial = np.random.exponential(size = 1000) \n", + "\n", + "# Dados transformados \n", + "box_cox, lambda_box_cox = stats.boxcox(distribuicao_exponencial) \n", + "f\"lambda ótimo: {lambda_box_cox}\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "huT5bd89EiyD" + }, + "source": [ + "distribuicao_exponencial[:50]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zEG3u_LbPWP5" + }, + "source": [ + "# Dados transformados pela Box-Cox:\n", + "box_cox[0:30]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lwyGVDMzC4y" + }, + "source": [ + "### Exemplo 1\n", + "* Dados possuem distribuição Exponencial." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tx5J1L8Az4qQ" + }, + "source": [ + "# Gráficos: \n", + "def compara_graficos(y, w, lambda_box_cox):\n", + " fig, ax = plt.subplots(1, 2) \n", + " \n", + " # Gráfico das distribuições originais e transformada\n", + " sns.distplot(y, hist = False, kde = True, kde_kws = {'shade': True, 'linewidth': 2}, label = \"Non-Normal\", color = \"green\", ax = ax[0]) \n", + " sns.distplot(w, hist = False, kde = True, kde_kws = {'shade': True, 'linewidth': 2}, label = \"Normal\", color = \"green\", ax = ax[1]) \n", + " \n", + " # Legendas \n", + " plt.legend(loc = \"upper right\")\n", + " \n", + " # Redimensionando os sub-gráficos \n", + " fig.set_figheight(5)\n", + " fig.set_figwidth(10) \n", + " \n", + " print(f\"Valor de Lambda usado na transformação: {lambda_box_cox}\") " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xWLsXEBB0CQO" + }, + "source": [ + "compara_graficos(distribuicao_exponencial, box_cox, lambda_box_cox)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F9jObBLCZh19" + }, + "source": [ + "### Exemplo 2\n", + "* Dados possuem distribuição Beta.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CePoB8imzPRQ" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_beta = np.random.beta(1, 3, 1000)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "j1CwLPm6zRx2" + }, + "source": [ + "# transform training data & save lambda value \n", + "box_cox, lambda_box_cox = stats.boxcox(distribuicao_beta) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "DAy3IPUbWJut" + }, + "source": [ + "f\"Lambda ótimo: {lambda_box_cox}\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "snd63l9U0ugI" + }, + "source": [ + "compara_graficos(distribuicao_beta, box_cox, lambda_box_cox)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CQ6o9pOkPjUT" + }, + "source": [ + "### Transformação log\n", + "* De forma geral, a transformação **log** trata de dados skewed (diferentes da distribuição Normal), tornando os dados (ou a distribuição dos dados) mais \"normal\";\n", + "* Se os dados forem de alguma forma normalmente distribuídos, então nada muda." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DrsXETsRPupd" + }, + "source": [ + "# Gerando dados com distribuição Exponencial\n", + "distribuicao_beta = np.random.beta(1, 3, 1000)\n", + "\n", + "transformacao_log = np.log(distribuicao_beta)\n", + "\n", + "# Aproveitando a função compara_graficos()\n", + "compara_graficos(distribuicao_beta, transformacao_log, 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mwh0alhdgrE3" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "> Para cada um dos dataframes a seguir, aplique os seguintes steps:\n", + "\n", + "* Padronizar o nome das colunas\n", + " * Eliminar espaços entre os nomes das colunas;\n", + " * Eliminar caracteres especiais dos nomes das colunas;\n", + " * Renomear as colunas com lower() (ou upper());\n", + "* Aplicar a trasformação StandardScaler e MinMaxScaler em cada uma das colunas do dataframe;\n", + "* DataViz - Mostrar a distribuição das colunas para compararmos os resultados antes e depois das transformações.\n", + "* As correlações das colunas mudam com as transformações?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hSTKrd992LtI" + }, + "source": [ + "## Exercício 1 - Iris --> **Resolvido**\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mThqvGGr2Vuk" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n", + "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eU5FaJhdYblP" + }, + "source": [ + "df_iris.columns = [c.replace(' ', '_') for c in df_iris.columns]\n", + "df_iris.columns = [c.replace('_(cm)', '') for c in df_iris.columns]\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "K9DPAakJZQHH" + }, + "source": [ + "df_iris.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YYYmVq68Y8bB" + }, + "source": [ + "# Aplica a transformação:\n", + "df_iris_MinMaxScaler = MinMaxScaler().fit_transform(df_iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']])\n", + "\n", + "# Transformando em Dataframe:\n", + "df_iris_MinMaxScaler = pd.DataFrame(df_iris_MinMaxScaler, columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])\n", + "\n", + "# Gráfico\n", + "df_iris_MinMaxScaler.plot(kind = 'kde')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DKsHcjd77YZT" + }, + "source": [ + "### Aplicar as outras transformações e comparar os gráficos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 2 - Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_A1_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_A1_cancer['target'] = df_A1_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_A1_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 3 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_A1_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_A1_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nzu0Dz33c8ds" + }, + "source": [ + "## Exercícios 4 - Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d6ahBZmqc_-1" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_A1_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_A1_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NyunIr6oaWEl" + }, + "source": [ + "## Exercícios 5 - 120 years of Olympic history: athletes and results\n", + "* [120 years of Olympic history: athletes and results](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)\n", + " * Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n", + " * Aplique as transformações que acabamos de estudar nos campos/colunas numéricas 'height' e 'weight'. Cuidado com os Missing Values contidos nas variáveis!\n", + " * Verifique/avalie o impacto dos outliers nestas colunas.\n", + " * Neste caso, qual transformação é mais adequado diante dos outliers?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8V7OCd3G9zj1" + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Z3g4dqM190mj" + }, + "source": [ + "url = '/content/drive/My Drive/Datasets4ML/athlete_events.csv'\n", + "df = pd.read_csv(url)\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ExKsjGmKaEx" + }, + "source": [ + "## Exercício 6 - FIFA\n", + "* Aplique as transformações MinMaxScaler, RobustScaler e StandardScaler às colunas numéricas do dataframe FIFA_algumas_features.csv.\n", + "* Para as colunas categóricas, aplique a transformação mais adequada." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zjukr52HK3S_" + }, + "source": [ + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S41tXs2EKlHN" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA_algumas_features.csv?token=AGDJQ62CSW5KBLZNXH4TULK7SXICE'\n", + "\n", + "df = pd.read_csv(url, index_col = 'ID')\n", + "df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o5fDp1Ib_Dg8" + }, + "source": [ + "# WOE - Weight Of Evidence\n", + "* As vantagens da transformação WOE são\n", + " * Lida bem com NaN's;\n", + " * Lida bem com outliers;\n", + " * A transformação é baseada no valor logarítmico das distribuições.\n", + " * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente." + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs.ipynb b/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs.ipynb new file mode 100644 index 000000000..b0d28a16f --- /dev/null +++ b/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs.ipynb @@ -0,0 +1,4873 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_4_Anomaly_Detection.ipynb", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EAqSDJGzyYrx" + }, + "source": [ + "

3DP_4 - ANOMALY/OUTLIER DETECTION

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-VrOjTTymSK" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte a **Table of contents**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wSAsbafemNax" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Mostrar junto os gráficos com a região de Anomaly Score junto com a distribuição de probabilidade das variáveis envolvidas.\n", + "* Mensagens de deprecating --> Analisar e substituir os métodos, funções deprecated;\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7qK6Yx0tBqUz" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Comparing anomaly detection algorithms for outlier detection on toy datasets](https://scikit-learn.org/stable/auto_examples/plot_anomaly_comparison.html#sphx-glr-auto-examples-plot-anomaly-comparison-py)\n", + "* [Outlier detection with several methods](https://scikit-learn.org/0.18/auto_examples/covariance/plot_outlier_detection.html)\n", + "* [anomaly-detection-resources](https://github.com/MathMachado/anomaly-detection-resources)\n", + "* [Outlier Detection with Extended Isolation Forest](https://towardsdatascience.com/outlier-detection-with-extended-isolation-forest-1e248a3fe97b)\n", + "* [Outlier Detection with Isolation Forest](https://towardsdatascience.com/outlier-detection-with-isolation-forest-3d190448d45e)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f7tTnUJ6B2UG" + }, + "source": [ + "___\n", + "## O que é Anomaly Detection?\n", + "> Qualquer ponto/observação que é incomum quando comparado com todos os outros pontos/observações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7VJZf1U5Ds_w" + }, + "source": [ + "___\n", + "# **Machine Learning com Python (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rpHJ1qVUEwOn" + }, + "source": [ + "___\n", + "# **Técnicas tradicionais para detecção de outliers**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OOI_VTo3E3sv" + }, + "source": [ + "## Boxplot\n", + "\n", + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vivFsmJGFVC0" + }, + "source": [ + "## Z-Score\n", + "* Z-Score pode ser utilizado para detectar Outliers.\n", + "* É a diferença entre o valor e a média da amostra expressa como o número de desvios-padrão. \n", + "* Se o escore z for menor que 2,5 ou maior que 2,5, o valor estará nos 5% do menor ou maior valor (2,5% dos valores em ambas as extremidades da distribuição). No entanto, é pratica comum utilizarmos 3 ao invés dos 2,5.\n", + "\n", + "![Z_Score](https://github.com/MathMachado/Materials/blob/master/Z_Score.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hUw6W3SSFiwj" + }, + "source": [ + "## IQR Score\n", + "\n", + "* O Intervalo interquartil (IQR) é uma medida de dispersão estatística, sendo igual à diferença entre os percentis 75 e 25, ou entre quartis superiores e inferiores, IQR = Q3 - Q1.\n", + "\n", + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7_YohlTIF8zi" + }, + "source": [ + "___\n", + "# **Hands-On**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OrXdGg8t0V_D" + }, + "source": [ + "## Carrega as Bibliotecas necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7pYqwxIe1Hcq", + "outputId": "4065238d-0996-4036-d6bf-2a1bf1250073", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 683 + } + }, + "source": [ + "!pip install pyod" + ], + "execution_count": 1, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Collecting pyod\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/a3/4b/d2edd1e85b132d480feced17f044267b3e330391240779d78b1c3d378b24/pyod-0.8.3.tar.gz (96kB)\n", + "\r\u001b[K |███▍ | 10kB 24.8MB/s eta 0:00:01\r\u001b[K |██████▊ | 20kB 6.1MB/s eta 0:00:01\r\u001b[K |██████████▏ | 30kB 5.8MB/s eta 0:00:01\r\u001b[K |█████████████▌ | 40kB 6.3MB/s eta 0:00:01\r\u001b[K |█████████████████ | 51kB 6.5MB/s eta 0:00:01\r\u001b[K |████████████████████▎ | 61kB 7.2MB/s eta 0:00:01\r\u001b[K |███████████████████████▊ | 71kB 7.6MB/s eta 0:00:01\r\u001b[K |███████████████████████████ | 81kB 7.1MB/s eta 0:00:01\r\u001b[K |██████████████████████████████▍ | 92kB 7.5MB/s eta 0:00:01\r\u001b[K |████████████████████████████████| 102kB 4.8MB/s \n", + "\u001b[?25hCollecting combo\n", + " Downloading https://files.pythonhosted.org/packages/0a/2a/61b6ac584e75d8df16dc27962aa5fe99d76b09da5b6710e83d4862c84001/combo-0.1.1.tar.gz\n", + "Requirement already satisfied: joblib in /usr/local/lib/python3.6/dist-packages (from pyod) (0.16.0)\n", + "Requirement already satisfied: matplotlib in /usr/local/lib/python3.6/dist-packages (from pyod) (3.2.2)\n", + "Requirement already satisfied: numpy>=1.13 in /usr/local/lib/python3.6/dist-packages (from pyod) (1.18.5)\n", + "Requirement already satisfied: numba>=0.35 in /usr/local/lib/python3.6/dist-packages (from pyod) (0.48.0)\n", + "Requirement already satisfied: pandas>=0.25 in /usr/local/lib/python3.6/dist-packages (from pyod) (1.1.2)\n", + "Requirement already satisfied: scipy>=0.19.1 in /usr/local/lib/python3.6/dist-packages (from pyod) (1.4.1)\n", + "Requirement already satisfied: scikit_learn>=0.19.1 in /usr/local/lib/python3.6/dist-packages (from pyod) (0.22.2.post1)\n", + "Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from pyod) (1.15.0)\n", + "Requirement already satisfied: statsmodels in /usr/local/lib/python3.6/dist-packages (from pyod) (0.10.2)\n", + "Collecting suod\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/a1/87/9170cabe1b5e10a7d095c0e28f2e30e7c1886a13f063de85d3cfacc06f4b/suod-0.0.4.tar.gz (2.1MB)\n", + "\u001b[K |████████████████████████████████| 2.1MB 13.6MB/s \n", + "\u001b[?25hRequirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (2.4.7)\n", + "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (0.10.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (1.2.0)\n", + "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (2.8.1)\n", + "Requirement already satisfied: llvmlite<0.32.0,>=0.31.0dev0 in /usr/local/lib/python3.6/dist-packages (from numba>=0.35->pyod) (0.31.0)\n", + "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from numba>=0.35->pyod) (50.3.0)\n", + "Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.25->pyod) (2018.9)\n", + "Requirement already satisfied: patsy>=0.4.0 in /usr/local/lib/python3.6/dist-packages (from statsmodels->pyod) (0.5.1)\n", + "Building wheels for collected packages: pyod, combo, suod\n", + " Building wheel for pyod (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for pyod: filename=pyod-0.8.3-cp36-none-any.whl size=110349 sha256=41264a336d54b8628dab7dc68909de14cafec5c2fab86dc9a1d1adea764dcce0\n", + " Stored in directory: /root/.cache/pip/wheels/29/46/95/86facd235cce1d58ae6747ab1aea2b3742564325a66a60863a\n", + " Building wheel for combo (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for combo: filename=combo-0.1.1-cp36-none-any.whl size=42113 sha256=4e68819bebfddd1709034c7b2b6700761360d2c2d32f44a51b48c9eb70f400fa\n", + " Stored in directory: /root/.cache/pip/wheels/55/ec/e5/a2331372c676c467e70c6646e646edf6997d5c4905b8c0f5e6\n", + " Building wheel for suod (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for suod: filename=suod-0.0.4-cp36-none-any.whl size=2167158 sha256=7a79c8fb77870bdd3263611e03970b202bdc30fb4f9e7b1eeea2e0fa05ffa1c1\n", + " Stored in directory: /root/.cache/pip/wheels/57/55/e5/a4fca65bba231f6d0115059b589148774b41faea25b3f2aa27\n", + "Successfully built pyod combo suod\n", + "Installing collected packages: combo, suod, pyod\n", + "Successfully installed combo-0.1.1 pyod-0.8.3 suod-0.0.4\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gxBgvhA4mowO" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from numpy import percentile\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "import matplotlib\n", + "\n", + "from sklearn.ensemble import IsolationForest\n", + "\n", + "# Scaling variables\n", + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "from pyod.models.abod import ABOD\n", + "from pyod.models.cblof import CBLOF\n", + "#from pyod.models.feature_bagging import FeatureBagging\n", + "from pyod.models.hbos import HBOS\n", + "from pyod.models.iforest import IForest\n", + "from pyod.models.knn import KNN\n", + "#from pyod.models.lof import LOF\n", + "from scipy import stats\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WLf_c29t0ekj" + }, + "source": [ + "## Carrega dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YL_VQljA0gxZ", + "outputId": "bc14a91c-4e61-4061-eca5-ecf9c5ce4cfc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_titanic = sns.load_dataset('titanic')\n", + "df_titanic = df_titanic.dropna()\n", + "df_titanic.head()" + ], + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
111female38.01071.2833CFirstwomanFalseCCherbourgyesFalse
311female35.01053.1000SFirstwomanFalseCSouthamptonyesFalse
601male54.00051.8625SFirstmanTrueESouthamptonnoTrue
1013female4.01116.7000SThirdchildFalseGSouthamptonyesFalse
1111female58.00026.5500SFirstwomanFalseCSouthamptonyesTrue
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "1 1 1 female 38.0 ... C Cherbourg yes False\n", + "3 1 1 female 35.0 ... C Southampton yes False\n", + "6 0 1 male 54.0 ... E Southampton no True\n", + "10 1 3 female 4.0 ... G Southampton yes False\n", + "11 1 1 female 58.0 ... C Southampton yes True\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q2oxyyQWB-uz" + }, + "source": [ + "# Normalizar as variáveis 'age' e 'fare'\n", + "df_titanic_ss = df_titanic.copy()\n", + "df_titanic_ss[['fare', 'age']] = StandardScaler().fit_transform(df_titanic_ss[['fare','age']])" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rAKnKtil9Oz1", + "outputId": "cbe30a0f-c362-42ac-c96d-34aeb3d7f2c8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Linhas do df_titanic\n", + "df_titanic_ss.shape" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(182, 15)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sHSYUkEQFIwS" + }, + "source": [ + "# Função para plotar o Boxplot\n", + "def boxplot_sobreviveu(df, column):\n", + " plt.rcdefaults()\n", + " sns.catplot(x = 'survived', y = column, kind = \"box\", data = df, height = 4, aspect = 1.5)\n", + " \n", + " # add data points to boxplot with stripplot\n", + " sns.stripplot(x = 'survived', y = column, data = df, alpha = 0.3, jitter = 0.2, color = 'k');\n", + " plt.show()" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9-VgcNnFNb1", + "outputId": "ff6653c7-f679-4683-9d64-f9c93fb58bba", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 426 + } + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'fare')" + ], + "execution_count": 8, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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+ctf8m//9m/cf//9/Ou//isbNmzga1/7GgBbtmzh9ddf58tf/vLiPxQhxKohM2FCiFVr586dvPOd72THjh188IMf5N///d+Znp5e1HPs2rWr6ueOjg7e/e53853vfAeA06dP85vf/IaHHnqo7uN1XedDH/pQcP98Ps/3v//94P4nTpygUCjwrne9i0QiEfz79re/zcmTJwE4fPgwe/furXreSsAmhLh5yUyYEGLV0jSNZ599ll//+tf85Cc/4YknnuBzn/scL774Iqqq1ixL2rZd8xz1djk+9NBD/OVf/iVPPPEETz31FDt27LjiDNtDDz3E/fffz9jYGM8++yzRaJTf+73fAwiWKZ955hnWrl1b9bhwOLzo9yyEuHnITJgQYlVTFIV7772Xf/zHf+SVV14hFArxve99j46ODi5evBjcz3VdDh06tKDn/KM/+iNM0+RHP/oRTz311LyzYBX33HMPfX19PP3003znO9/hgx/8IIZhAHD77bcTDoc5d+4cGzdurPrX19cHwNatW3nppZeqnvOFF15YzMcghFiFZCZMCLFqvfjiizz33HO8+93vprOzkxdffJHx8XG2bt1KPB7n0Ucf5ZlnnmHDhg388z//84ILn8bjcR588EE+//nPc/jwYT7ykY9c9TEf/ehH+eY3v8mxY8f42c9+FhxPJpP89V//NY888gie5/H2t7+ddDrNr371K5qamnj44Yf5i7/4C772ta/xN3/zN3zyk5/k5Zdf5lvf+ta1fixCiFVCgjAhxKrV1NTEL37xCx5//HEymQwDAwN87Wtf473vfS+2bXPw4EE+9rGPoes6jzzyCO94xzsW/NwPPfQQv//7v899991Hf3//gu7/T//0TwwMDHDvvfdW3fbFL36Rjo4OHnvsMU6dOkVLSwt33XUXf//3fw9Af38///mf/8kjjzzCE088wZ49e/jSl77EJz7xicV9IEKIVUXxF7OXWwghhBBCLAnJCRNCCCGEaAAJwoQQQgghGkCCMCGEEEKIBpAgTAghhBCiASQIE0IIIYRoAAnChBBCCCEaQIIwIYQQQogGkCBMCCGEEKIBJAgTQgghhGgACcKEEEIIIRpAgjAhhBBCiAb4/8KfqICvlZ2gAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8FIo9tD1FQ0u", + "outputId": "e213bc87-210e-4723-c133-02a1cf67c919", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 426 + } + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'age')" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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ZnpZiKiEcTqSiEpCX18fUqkU7rvvPixbtgwAsHbt2mmdY8eOHfiLv/iLzO1PfepTePTRR/HGG29kgq79+/fjM5/5DARByHn83XffDavVipdeegl/+qd/mrn/H/3RH6GsrAzxeBzf/e538Zvf/Abt7e0AgMbGRrzxxhv493//d9x22214+umnsXLlSjzxxBMAgNWrV+PUqVP4x3/8x+lfFCIqaRwJI6KS0NraijvuuANr167FJz/5SfzoRz/C6OjotM6xadOmrNtutxt33XUXfvrTnwIAOjs7cejQITzwwAN5H6/T6fCpT30qc/9wOIyf/exnmfufO3cOkUgEd955J2w2W+bnueeew/nz5wEAHR0daGtryzrveMBGREsLR8KIqCRIkoRf//rX+P3vf4///d//xQ9+8AN89atfxZEjRyCKYs60ZDKZzDlHvlWODzzwAP78z/8cP/jBD7B//36sXbt20hG2Bx54ALfddhsGBgbw61//GmazGX/wB38AAJlpyl/+8peora3NepzRaJz2ayaixY0jYURUMgRBwLZt2/DNb34T7777LgwGA1566SW43W709fVl7ifLMt57770pnfPjH/84YrEYXn31Vezfv7/gKNi4j3zkI6ivr8fzzz+Pn/70p/jkJz8JvV4PAGhpaYHRaMTly5exatWqrJ/6+noAQHNzM44ePZp1zsOHD0/nMhDRIsGRMCIqCUeOHMGBAwdw1113wePx4MiRIxgcHERzczOsViv27NmDX/7yl1i5ciX+9V//dcqFT61WK3bt2oWvfe1r6OjowGc+85nrPuazn/0snnnmGZw5cwa/+93vMu1lZWX4y7/8Szz22GNQFAW33HILAoEA3nzzTdjtduzevRt/9md/hieeeAJ/9Vd/hS996Us4duwYnn322ZleFiIqYQzCiKgk2O12vP7663jyyScRDAaxbNkyPPHEE7jnnnuQTCZx4sQJPPjgg9DpdHjsscewffv2KZ/7gQcewMc+9jHceuutaGhomNL9v/Od72DZsmXYtm1b1rFvf/vbcLvd2Lt3Ly5cuACn04kNGzbgb//2bwEADQ0N+K//+i889thj+MEPfoAtW7bgu9/9Lr7whS9M74IQUckT1Oms7yYiIiKiOcGcMCIiIiINMAgjIiIi0gCDMCIiIiINMAgjIiIi0gCDMCIiIiINMAgjIiIi0gCDMCIiIiINMAgjIiIi0gCDMCIiIiINMAgjIiIi0gCDMCIiIiIN/P/a2jZlKpvEugAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wTd8J0LyfOKH", + "outputId": "b888e12d-1d41-47fd-f359-8ce104acb9d0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "df_titanic.columns" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare',\n", + " 'embarked', 'class', 'who', 'adult_male', 'deck', 'embark_town',\n", + " 'alive', 'alone'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TLX6YhlYfbQ9", + "outputId": "61dc83f0-0d37-47a9-8986-e1d9fc3c9a42", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + "df_titanic.fare.sort_values(ascending=False)" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "737 512.3292\n", + "679 512.3292\n", + "341 263.0000\n", + "438 263.0000\n", + "27 263.0000\n", + " ... \n", + "699 7.6500\n", + "715 7.6500\n", + "872 5.0000\n", + "263 0.0000\n", + "806 0.0000\n", + "Name: fare, Length: 182, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t0ZCXA15fzsq", + "outputId": "6a994ce8-185c-4eee-ba96-db3c338d195a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 111 + } + }, + "source": [ + "df_titanic[df_titanic['fare'] > 500]" + ], + "execution_count": 23, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
67911male36.001512.3292CFirstmanTrueBCherbourgyesFalse
73711male35.000512.3292CFirstmanTrueBCherbourgyesTrue
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "679 1 1 male 36.0 ... B Cherbourg yes False\n", + "737 1 1 male 35.0 ... B Cherbourg yes True\n", + "\n", + "[2 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dry76OnKi_X6", + "outputId": "471ba5fc-2fc8-4027-86ac-188e90c94952", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 111 + } + }, + "source": [ + "df_titanic[df_titanic['age'] > 70]" + ], + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
9601male71.00034.6542CFirstmanTrueACherbourgnoTrue
63011male80.00030.0000SFirstmanTrueASouthamptonyesTrue
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "96 0 1 male 71.0 ... A Cherbourg no True\n", + "630 1 1 male 80.0 ... A Southampton yes True\n", + "\n", + "[2 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fCqj102y9Kfo", + "outputId": "891bd5c0-76f3-47d2-a125-12be081812e2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 168 + } + }, + "source": [ + "# Descrever o dataframe, variável 'fare'\n", + "df_titanic_ss['fare'].describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "count 1.820000e+02\n", + "mean 2.537653e-16\n", + "std 1.002759e+00\n", + "min -1.034601e+00\n", + "25% -6.452479e-01\n", + "50% -2.873576e-01\n", + "75% 1.452571e-01\n", + "max 5.681797e+00\n", + "Name: fare, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SMcvIb1K_69n", + "outputId": "701603fd-6df5-4622-dbdc-62603ca91fff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + } + }, + "source": [ + "plt.scatter(range(df_titanic_ss.shape[0]), np.sort(df_titanic_ss['fare'].values))\n", + "plt.xlabel('index')\n", + "plt.ylabel('Fares')\n", + "plt.title(\"Distribuição da variável Fare\")\n", + "\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAHHCAYAAABHp6kXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deXRUVb728acSSAIZKgQSEiAEAghGBkGEl1Ea0wIiCk6AE6DCFVAbaW3AVgGvgq3t0A6N2CqotArSOCAKokyKIJOoAUWIYdKECDGVARIg2e8f3lRTmYdKqurk+1mr1kqdOnXqd+ok+Lj3PnvbjDFGAAAAPs7P0wUAAAC4A6EGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGALzEjh07NHfuXKWnp3u6FMAnEWqASpozZ45sNludfNagQYM0aNAg5/MNGzbIZrNp+fLlbvuMgwcPymazafHixVV+7/LlyxUeHq5+/fpp//79mjRpkp555hm31VYem82mOXPm1MlnuVNF3/eJEyc0atQonTlzRlFRUbVaS9Hv04YNG2r1c4C6RqhBvbR48WLZbDbnIygoSC1atNCQIUP07LPPKjs72y2f88svv2jOnDnavXu3W47nLR5//HFNmjRJMTEx6tSpk1asWKGRI0d6uiyfZYzRuHHjNGjQID3yyCOeLsep+N/JuY+ZM2d6ujyghAaeLgDwpIcfflht27bVmTNnlJaWpg0bNmjatGl66qmn9MEHH6hr167OfR944IEq/0P+yy+/aO7cuWrTpo0uvPDCSr/vk08+qdLnVEdcXJxOnTqlhg0bVvm977zzjlq2bKkGDRro119/VWhoqIKCgmqhSuso7/tOSUlR//79NX36dA9UVrGiv5Nzde7c2UPVAGUj1KBeGzZsmHr27Ol8PmvWLK1bt05XXHGFrrzySn3//fdq1KiRJKlBgwZq0KB2/2ROnjypxo0bKyAgoFY/R5Kzhao64uLinD9HRka6qyRLOnv2rAoLCxUQEFDm9x0fH+/VLR/F/07cITc3V8HBwW49JkD3E1DM4MGD9eCDD+rQoUNasmSJc3tpY2rWrl2r/v37Kzw8XCEhIerYsaPuv/9+Sb+PW7j44oslSRMmTHA22xeNqRg0aJA6d+6snTt3auDAgWrcuLHzvcXH1BQpKCjQ/fffr+joaAUHB+vKK6/UkSNHXPZp06aNxo8fX+K9xY9Z1hiPH374Qddff70iIyPVqFEjdezYUX/961+dr6ekpGjy5Mk677zz1KhRIzVt2lTXXXedDh48WOIzf/rpJ1133XWKiIhQ48aN9f/+3//TqlWrSuxXmvz8fN1zzz2KjIxUaGiorrzySh09erTEfocOHdKUKVPUsWPHCus515kzZxQREaEJEyaUeC0rK0tBQUG69957JUmnT5/WQw89pIsuukh2u13BwcEaMGCA1q9f7/K+ou/073//u5555hm1a9dOgYGB2rt3b6nf97fffqvx48crPj5eQUFBio6O1q233qoTJ04491m+fLlsNps2btxYos6FCxfKZrMpKSnJue2HH37Qtddeq4iICAUFBalnz5764IMPyv0uqquy331RN9bGjRs1ZcoURUVFqVWrVs7XP/74Yw0YMEDBwcEKDQ3V8OHDtWfPnlqpGdZGSw1Qiptvvln333+/PvnkE02cOLHUffbs2aMrrrhCXbt21cMPP6zAwEAdOHBAmzdvliSdf/75evjhh/XQQw9p0qRJGjBggCSpb9++zmOcOHFCw4YN05gxY3TTTTepefPm5db16KOPymazacaMGUpPT9czzzyjxMRE7d6929miVBPffvutBgwYoIYNG2rSpElq06aNkpOTtXLlSj366KOSpK+++kpbtmzR2LFj1apVK6WkpOjFF1/UoEGDtHfvXjVu3FiSdOzYMfXt21cnT57U3XffraZNm+q1117TlVdeqeXLl2vUqFHl1nL77bdryZIluuGGG9S3b1+tW7dOw4cPL7Hf9u3b9eWXX2rMmDFq1aqVDh48qAULFpSop7iGDRtq1KhRWrFihRYuXOjSOvbee+8pPz9fY8aMkfR7yHn55Zc1duxYTZw4UdnZ2XrllVc0ZMgQbdu2rUTX4qJFi5SXl6dJkyYpMDBQERERKiwsLFHD2rVrlZycrAkTJig6OlpJSUl66aWXtGfPHm3dulU2m03Dhw9XSEiIli1bpksuucTl/UuXLtUFF1zg7Aras2eP+vXrp5YtW2rmzJkKDg7WsmXLNHLkSP3nP/+p8Dsvi8Ph0PHjx122NWvWrMrf/ZQpUxQZGamHHnpIubm5kqQ33nhD48aN05AhQ/S3v/1NJ0+e1IIFC9S/f399/fXXatOmTbVqRj1lgHpo0aJFRpLZvn17mfvY7XbTvXt35/PZs2ebc/9knn76aSPJ/Prrr2UeY/v27UaSWbRoUYnXLrnkEiPJvPjii6W+dskllzifr1+/3kgyLVu2NFlZWc7ty5YtM5LMP/7xD+e2uLg4M27cuAqPmZKSUqK2gQMHmtDQUHPo0CGX9xYWFjp/PnnyZIljb9myxUgyr7/+unPbtGnTjCTz+eefO7dlZ2ebtm3bmjZt2piCgoISxymye/duI8lMmTLFZfsNN9xgJJnZs2dXuZ7SrFmzxkgyK1eudNl++eWXm/j4eOfzs2fPmvz8fJd9fvvtN9O8eXNz6623OrcVfadhYWEmPT3dZf/Svu+cnJwSNS1ZssRIMps2bXJuGzt2rImKijJnz551bktNTTV+fn7m4Ycfdm679NJLTZcuXUxeXp5zW2Fhoenbt6/p0KGDc1vR79P69evL+mqMMf/9OyntYUzlv/ui4/Tv39/lHLKzs014eLiZOHGiyzHS0tKM3W4vsR2oCN1PQBlCQkLKvQsqPDxckvT++++X+n/hlREYGFhq90dZbrnlFoWGhjqfX3vttYqJidFHH31Urc8/16+//qpNmzbp1ltvVevWrV1eO7fb7dwWoTNnzujEiRNq3769wsPDtWvXLudrH330kXr16qX+/fs7t4WEhGjSpEk6ePCg9u7dW2YtRedz9913u2yfNm1aiX0rW09pBg8erGbNmmnp0qXObb/99pvWrl2r0aNHO7f5+/s7W3IKCwuVkZGhs2fPqmfPnqV+xjXXXFOpsUbnjikxxigvL0+XXXaZJLkcd/To0UpPT3e5BXv58uUqLCx01pmRkaF169bp+uuvV3Z2to4fP67jx4/rxIkTGjJkiPbv36+ff/65wppK88ILL2jt2rUuD6nq3/3EiRPl7+/vfL527VplZmZq7NixznqPHz8uf39/9e7du0T3HlARQg1QhpycHJcAUdzo0aPVr18/3X777WrevLnGjBmjZcuWVSngtGzZskqDgjt06ODy3GazqX379hWOH6mMn376SVLFd7WcOnVKDz30kGJjYxUYGKhmzZopMjJSmZmZcjgczv0OHTqkjh07lnj/+eef73y9LIcOHZKfn5/atWvnsr2041W2ntI0aNBA11xzjd5//33l5+dLklasWKEzZ864hBpJeu2119S1a1cFBQWpadOmioyM1KpVq0r9jOJ3CpXF4XBo1qxZzjE1jRo1cs5Rc+5xhw4dKrvd7hK+li5dqgsvvFDnnXeeJOnAgQMyxujBBx9UZGSky2P27NmSVO1J/Xr16qXExESXh1T1777497J//35Jv4fL4jV/8sknTEKIKmNMDVCKo0ePyuFwqH379mXu06hRI23atEnr16/XqlWrtHr1ai1dulSDBw/WJ5984vJ/pOUdw93KmiCwoKCgUjVV5K677tKiRYs0bdo09enTR3a7XTabTWPGjKl2i5Un6xkzZowWLlyojz/+WCNHjtSyZcvUqVMndevWzbnPkiVLNH78eI0cOVL33XefoqKi5O/vr/nz5ys5ObnEMSt7XUePHq3NmzfrgQceUI8ePRQSEqKCggINGDDApfbAwECNHDlS7777rv75z3/q2LFj2rx5s+bNm+fcp2j/e++9V0OGDCn188r7fa6Oqn73xb+Xon3eeOMNRUdHl9i/tu82hPXwGwOU4o033pCkMv/jUMTPz0+XXnqpLr30Uj311FOaN2+e/vrXv2r9+vVKTEx0+wzERf9nW8QYowMHDrjMp9OkSRNlZmaWeO+hQ4cUHx9f5rGLXjv3TprSLF++XOPGjdOTTz7p3JaXl1fiM+Pi4rRv374S7//hhx+cr5clLi5OhYWFSk5OdmmdKe14la2nLAMHDlRMTIyWLl2q/v37a926dS53exV9Rnx8vFasWOFyTYtaQKojMzNTa9as0SOPPKIZM2Y4t//444+l7j969Gi99tpr+uyzz/T999/LGOPSmlR0/Ro2bOhsSaltNf3ui1rioqKi6qxmWBvdT0Ax69at0//+7/+qbdu2uvHGG8vcLyMjo8S2ortgiroyisZMVPYf+Yq8/vrrLuN8li9frtTUVA0bNsy5rV27dtq6datOnz7t3Pbhhx+WuPW7uMjISA0cOFCvvvqqDh8+7PKaMcb5s7+/v8tzSXruuedUUFDgsu3yyy/Xtm3btGXLFue23NxcvfTSS2rTpo0SEhLKrKXofJ599lmX7aUtxVDZesri5+ena6+9VitXrtQbb7yhs2fPluh6KmrhOvdziu4Cqy4/v9//+T1z5ozL9nMDwrkSExMVERGhpUuXaunSperVq5dLd05UVJQGDRqkhQsXKjU1tcT7f/3112rXWpaafvdDhgxRWFiY5s2bV+J7kGqnZlgbLTWo1z7++GP98MMPOnv2rI4dO6Z169Zp7dq1iouL0wcffFDu5HQPP/ywNm3apOHDhysuLk7p6en65z//qVatWjkHx7Zr107h4eF68cUXFRoaquDgYPXu3bvSYy6Ki4iIUP/+/TVhwgQdO3ZMzzzzjNq3b+9y2/ntt9+u5cuXa+jQobr++uuVnJysJUuWlBifUppnn31W/fv3V48ePTRp0iS1bdtWBw8e1KpVq5xLPVxxxRV64403ZLfblZCQoC1btujTTz9V06ZNXY41c+ZMvfXWWxo2bJjuvvtuRURE6LXXXlNKSor+85//OP+jXpoLL7xQY8eO1T//+U85HA717dtXn332mQ4cOFBi38rWU57Ro0frueee0+zZs9WlSxfnuJ9zP2PFihUaNWqUhg8f7ryNPSEhQTk5OZX+nHOFhYWpf//+euKJJ3T27Fm1bNlSa9asKREoizRs2FBXX3213n77beXm5urvf/97iX1eeOEF9e/fX126dNHEiRMVHx+vY8eOacuWLTp69Ki++eabatValpp+92FhYVqwYIFuvvlm9ejRQ2PGjFFkZKQOHz6sVatWqV+/fnr++efdWjMszmP3XQEeVPxW1YCAABMdHW3++Mc/mn/84x8ut00XKX5L92effWauuuoq06JFCxMQEGBatGhhxo4da3788UeX973//vsmISHBNGjQwOWW3ksuucRccMEFpdZX1i3db731lpk1a5aJiooyjRo1MsOHDy9x+7Uxxjz55JOmZcuWJjAw0PTr18/s2LGjUrd0G2NMUlKSGTVqlAkLCzOSTMeOHc2DDz7ofP23334zEyZMMM2aNTMhISFmyJAh5ocffij1VvLk5GRz7bXXmvDwcBMUFGR69eplPvzww1LPubhTp06Zu+++2zRt2tQEBwebESNGmCNHjpS4pbsq9ZSlsLDQxMbGGknmkUceKfX1efPmmbi4OBMYGGi6d+9uPvzwQzNu3DgTFxfn3K/oO33iiSdKHKO07/vw4cNm5MiRxm63m/DwcDNmzBiTlpZW4hyLrF271kgyNpvNHDlypNRzSU5ONrfccouJjo42DRs2NC1btjRXXHGFWb58uXOfqt7SXdbUB5X97is6zvr1682QIUOM3W43QUFBpl27dmb8+PFmx44d5dYHFGczpljbIQD8n8TERP3lL39x3mYMAN6MMTUAyjRixAiXpSIAwJsxpgZACW+99ZZyc3P1zjvvOOdNAQBvR0sNgBL27NmjO++8Uz///LNzUUcA8HaMqQEAAJbgUy01P//8s2666SY1bdpUjRo1UpcuXbRjxw5PlwUAALyAz4yp+e2339SvXz/94Q9/0Mcff6zIyEjt379fTZo08XRpAADAC/hM99PMmTO1efNmff7559U+hjFG2dnZCg0Ndfv09QAAwLN8pvvpgw8+UM+ePXXdddcpKipK3bt317/+9a9y35Ofn6+srCzn4+eff5bdbneZZh4AAFiDz4San376SQsWLFCHDh20Zs0aTZ48WXfffbdee+21Mt8zf/582e125yM2NrYOKwYAAHXJZ7qfAgIC1LNnT3355ZfObXfffbe2b99e5qJy+fn5zoUFJSkrK0uxsbFyOBwKCwur9ZoBAEDd8ZmWmpiYmBKr+p5//vllLv4mSYGBgQoLC3N5AAAAa/KZUNOvXz/t27fPZduPP/6ouLg4D1UEAAC8ic+EmnvuuUdbt27VvHnzdODAAb355pt66aWXNHXqVE+XBgAAvIDPjKmRpA8//FCzZs3S/v371bZtW02fPl0TJ06s9PuzsrJkt9sZUwMAgAX5VKipKUINAADW5TPdTwAAAOUh1AAAAEsg1AAAAEsg1AAAAEvwmVW6AQCAdykoNNqWkqE0xyll5J5WREigosOC1KtthPz96n7haEINAACostVJqZq7cq9SHXklXouxB2n2iAQN7RxTpzXR/QQAAKpkdVKqJi/ZVWqgkaRUR54mL9ml1UmpdVoXoQYAAFRaQaHR3JV7VZlJ7uau3KuCwrqbDo9QAwAAKm1bSkaZLTTnMvq9xWZbSkbtF/V/CDUAAKDS0rMrDjQ12b8mCDUAAKDSokKDanX/miDUAACASuvVNkIx9oqDik2/3wXVq21E7Rf1fwg1AACg0vz9bJo9IkGVmYVm9oiEOp2vhlADAACqZGjnGC24qUeZLTYx9iAtuKlHnc9TYzPG1N29Vh6WlZUlu90uh8OhsLAwT5cDAIBPY0ZhAABgCf5+NvVp19TTZTjR/QQAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACzBZ0LNnDlzZLPZXB6dOnXydFkAAMBLNPB0AVVxwQUX6NNPP3U+b9DAp8oHAAC1yKdSQYMGDRQdHe3pMgAAgBfyme4nSdq/f79atGih+Ph43XjjjTp8+HC5++fn5ysrK8vlAQAArMlnQk3v3r21ePFirV69WgsWLFBKSooGDBig7OzsMt8zf/582e125yM2NrYOKwYAAHXJZowxni6iOjIzMxUXF6ennnpKt912W6n75OfnKz8/3/k8KytLsbGxcjgcCgsLq6tSAQBAHfCpMTXnCg8P13nnnacDBw6UuU9gYKACAwPrsCoAAOApPtP9VFxOTo6Sk5MVExPj6VIAAIAX8JlQc++992rjxo06ePCgvvzyS40aNUr+/v4aO3asp0sDAABewGe6n44ePaqxY8fqxIkTioyMVP/+/bV161ZFRkZ6ujQAAOAFfHagcHVkZWXJbrczUBgAAAvyme4nAACA8hBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJRBqAACAJfhsqHnsscdks9k0bdo0T5cCAAC8gE+Gmu3bt2vhwoXq2rWrp0sBAABewudCTU5Ojm688Ub961//UpMmTTxdDgAA8BI+F2qmTp2q4cOHKzExscJ98/PzlZWV5fIAAADW1MDTBVTF22+/rV27dmn79u2V2n/+/PmaO3duLVcFAAC8gc+01Bw5ckR/+tOf9O9//1tBQUGVes+sWbPkcDicjyNHjtRylQAAwFNsxhjj6SIq47333tOoUaPk7+/v3FZQUCCbzSY/Pz/l5+e7vFaarKws2e12ORwOhYWF1XbJAACgDvlM99Oll16q7777zmXbhAkT1KlTJ82YMaPCQAMAAKzNZ0JNaGioOnfu7LItODhYTZs2LbEdAADUPz4zpgYAAKA8PjOmxh0YUwMAgHXRUgMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACyBUAMAACzBZ0LNggUL1LVrV4WFhSksLEx9+vTRxx9/7OmyAACAl/CZUNOqVSs99thj2rlzp3bs2KHBgwfrqquu0p49ezxdGgAA8AI2Y4zxdBHVFRERoSeeeEK33XZbpfbPysqS3W6Xw+FQWFhYLVcHAADqUgNPF1AdBQUFeuedd5Sbm6s+ffqUuV9+fr7y8/Odz7OysuqiPAAA4AE+0/0kSd99951CQkIUGBioO+64Q++++64SEhLK3H/+/Pmy2+3OR2xsbB1WCwAA6pJPdT+dPn1ahw8flsPh0PLly/Xyyy9r48aNZQab0lpqYmNj6X4CAMCCfCrUFJeYmKh27dpp4cKFldqfMTUAAFiXT3U/FVdYWOjSEgMAAOovnxkoPGvWLA0bNkytW7dWdna23nzzTW3YsEFr1qzxdGkAAMAL+EyoSU9P1y233KLU1FTZ7XZ17dpVa9as0R//+EdPlwYAALyAT4+pqSrG1AAAYF0+PaYGAACgCKEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYQrVCzerVq/XFF184n7/wwgu68MILdcMNN+i3335zW3EAAACVVa1Qc9999ykrK0uS9N133+nPf/6zLr/8cqWkpGj69OluLRAAAKAyGlTnTSkpKUpISJAk/ec//9EVV1yhefPmadeuXbr88svdWiAAAEBlVKulJiAgQCdPnpQkffrpp7rsssskSREREc4WHAAAgLpUrZaa/v37a/r06erXr5+2bdumpUuXSpJ+/PFHtWrVyq0FAgCAulVQaLQtJUNpjlPKyD2tiJBARYUESjYpPSvPuS06LEi9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P9VAs2bN5O/vX+KOl2PHjik6OtpDVdWeO++8Ux9++KHWr1+vVq1albtv7969JUkHDhyoi9LqRHh4uM477zwdOHBA0dHROn36tDIzM132sdq1P3TokD799FPdfvvt5e5nxetddB3L+/uOjo4ucVPA2bNnlZGR4fO/B0WB5tChQ1q7dq1LK01pevfurbNnz+rgwYN1U2AdiI+PV7NmzZy/11a+3kU+//xz7du3r8K/eck7rzmhpgYCAgJ00UUX6bPPPnNuKyws1GeffaY+ffp4sDL3Msbozjvv1Lvvvqt169apbdu2Fb5n9+7dkqSYmJjaLq/O5OTkKDk5WTExMbrooovUsGFDl2u/b98+HT582FLXftGiRYqKitLw4cPL3c+K17tt27aKjo52ucZZWVn66quvnNe4T58+yszM1M6dO537rFu3ToWFhc6g54uKAs3+/fv16aefqmnTphW+Z/fu3fLz8yvRPePLjh49qhMnTjh/r616vc/1yiuv6KKLLlK3bt0q3Ncrr7mnRyr7urffftsEBgaaxYsXm71795pJkyaZ8PBwk5aW5unS3Gby5MnGbrebDRs2mNTUVOfj5MmTxhhjDhw4YB5++GGzY8cOk5KSYt5//30THx9vBg4c6OHKa+bPf/6z2bBhg0lJSTGbN282iYmJplmzZiY9Pd0YY8wdd9xhWrdubdatW2d27Nhh+vTpY/r06ePhqt2noKDAtG7d2syYMcNlu5Wud3Z2tvn666/N119/bSSZp556ynz99dfOu3wee+wxEx4ebt5//33z7bffmquuusq0bdvWnDp1ynmMoUOHmu7du5uvvvrKfPHFF6ZDhw5m7NixnjqlSinvvE+fPm2uvPJK06pVK7N7926Xv/n8/HxjjDFffvmlefrpp83u3btNcnKyWbJkiYmMjDS33HKLh8+sfOWdd3Z2trn33nvNli1bTEpKivn0009Njx49TIcOHUxeXp7zGL54vY2p+HfdGGMcDodp3LixWbBgQYn3+8o1J9S4wXPPPWdat25tAgICTK9evczWrVs9XZJbSSr1sWjRImOMMYcPHzYDBw40ERERJjAw0LRv397cd999xuFweLbwGho9erSJiYkxAQEBpmXLlmb06NHmwIEDztdPnTplpkyZYpo0aWIaN25sRo0aZVJTUz1YsXutWbPGSDL79u1z2W6l671+/fpSf7fHjRtnjPn9tu4HH3zQNG/e3AQGBppLL720xPdx4sQJM3bsWBMSEmLCwsLMhAkTTHZ2tgfOpvLKO++UlJQy/+bXr19vjDFm586dpnfv3sZut5ugoCBz/vnnm3nz5rn8x98blXfeJ0+eNJdddpmJjIw0DRs2NHFxcWbixIkl/gfVF6+3MRX/rhtjzMKFC02jRo1MZmZmiff7yjW3GWNMrTYFAQAA1AHG1AAAAEsg1AAAAEsg1AAAAEsg1AAAAEsg1AAAAEsg1AAAAEsg1AAAAEsg1AAAAEsg1ADwuEGDBmnatGnVfv/Bgwdls9mca1ABqJ8aeLoAAFixYoUaNmzo6TIA+DhCDQCPi4iI8HQJACyA7icAHndu91ObNm00b9483XrrrQoNDVXr1q310ksvuey/bds2de/eXUFBQerZs6e+/vrrEsdMSkrSsGHDFBISoubNm+vmm2/W8ePHJUkbNmxQQECAPv/8c+f+jz/+uKKionTs2LFaPFMAtYlQA8DrPPnkk86wMmXKFE2ePFn79u2TJOXk5OiKK65QQkKCdu7cqTlz5ujee+91eX9mZqYGDx6s7t27a8eOHVq9erWOHTum66+/XtJ/Q9TNN98sh8Ohr7/+Wg8++KBefvllNW/evM7PF4B70P0EwOtcfvnlmjJliiRpxowZevrpp7V+/Xp17NhRb775pgoLC/XKK68oKChIF1xwgY4eParJkyc73//888+re/fumjdvnnPbq6++qtjYWP34448677zz9Mgjj2jt2rWaNGmSkpKSNG7cOF155ZV1fq4A3IdQA8DrdO3a1fmzzWZTdHS00tPTJUnff/+9unbtqqCgIOc+ffr0cXn/N998o/Xr1yskJKTEsZOTk3XeeecpICBA//73v9W1a1fFxcXp6aefrqWzAVBXCDUAvE7xO6FsNpsKCwsr/f6cnByNGDFCf/vb30q8FhMT4/z5yy+/lCRlZGQoIyNDwcHB1awYgDdgTA0An3L++efr22+/VV5ennPb1q1bXfbp0aOH9uzZozZt2qh9+/Yuj6LgkpycrHvuuUf/+te/1Lt3b40bN65KwQmA9yHUAPApN9xwg2w2myZOnKi9e/fqo48+0t///neXfaZOnaqMjAyNHTtW27dvV3JystasWaMJEyaooKBABQUFuummmzRkyBBNmDBBixYt0rfffqsnn3zSQ2cFwB0INQB8SkhIiFauXKnvvvtO3bt311//+tcS3UwtWrTQ5s2bVVBQoMsuu0xdunTRtGnTFB4eLj8/Pz366KM6dOiQFi5cKOn3LqmXXnpJDzzwgL755htPnBYAN7AZY4yniwAAAKgpWmoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAlEGoAAIAl/H8MBE4fiinCEAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NCcXnHHYIlM4", + "outputId": "c49ba369-ac5a-47b2-85a0-b25cffdfe4fe", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + } + }, + "source": [ + "df_titanic_ss.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassagesibspparchfare
count182.000000182.0000001.820000e+02182.000000182.0000001.820000e+02
mean0.6758241.1923081.464030e-170.4670330.4780222.537653e-16
std0.4693570.5164111.002759e+000.6450070.7558691.002759e+00
min0.0000001.000000-2.220506e+000.0000000.000000-1.034601e+00
25%0.0000001.000000-7.437173e-010.0000000.000000-6.452479e-01
50%1.0000001.0000002.411064e-020.0000000.000000-2.873576e-01
75%1.0000001.0000007.759421e-011.0000001.0000001.452571e-01
max1.0000003.0000002.839480e+003.0000004.0000005.681797e+00
\n", + "
" + ], + "text/plain": [ + " survived pclass ... parch fare\n", + "count 182.000000 182.000000 ... 182.000000 1.820000e+02\n", + "mean 0.675824 1.192308 ... 0.478022 2.537653e-16\n", + "std 0.469357 0.516411 ... 0.755869 1.002759e+00\n", + "min 0.000000 1.000000 ... 0.000000 -1.034601e+00\n", + "25% 0.000000 1.000000 ... 0.000000 -6.452479e-01\n", + "50% 1.000000 1.000000 ... 0.000000 -2.873576e-01\n", + "75% 1.000000 1.000000 ... 1.000000 1.452571e-01\n", + "max 1.000000 3.000000 ... 4.000000 5.681797e+00\n", + "\n", + "[8 rows x 6 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7pzTvLleGpWc", + "outputId": "df81c529-7718-4a7c-8c31-6aa5453b8535", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + } + }, + "source": [ + "# Distribuição da variável 'fare'\n", + "\n", + "sns.distplot(df_titanic_ss['fare'])\n", + "plt.title(\"Distribuição da variável Fare\")\n", + "sns.despine()" + ], + "execution_count": 27, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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iIiIZMXpwo0oiigrK2uwmiYRERHJg9OFm/Lycmi1Wqul64mIiEg+nC7cEBERkbwx3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsMNwQERGRrDDcEBERkaww3BAREZGsqKQugOTt898zWn3NrKFd26ESIiJyFmy5ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZYbghIiIiWWG4ISIiIllhuCEiIiJZkTzcrFq1ChEREdBoNBg6dCgOHjx43fNXrlyJ6OhouLm5ISwsDE899RRqamo6qFoiIiKyd5KGm40bNyIxMRFLlizB0aNHMXDgQIwfPx55eXmNnv/555/jmWeewZIlS3D27Fl88skn2LhxI5599tkOrpyIiIjslaThZsWKFZg3bx4SEhLQp08frF69Gu7u7lizZk2j5//6668YMWIEZs2ahYiICNx+++2YOXNms609RERE5DwkCze1tbU4cuQI4uPj/yxGoUB8fDwOHDjQ6DXDhw/HkSNHLGHm4sWL2LZtGyZOnNjkfXQ6HcrKyqweREREJF8qqW5cUFAAg8GAwMBAq+OBgYFITk5u9JpZs2ahoKAAcXFxEEURer0e//M//3Pdbqnly5fjxRdftGntREREZL8kH1DcGnv27MGyZcvw3nvv4ejRo9iyZQu2bt2Kl156qclrFi5ciNLSUssjMzOzAysmIiKijiZZy42fnx+USiVyc3Otjufm5iIoKKjRaxYtWoQHHngADz30EACgf//+qKysxPz58/Hcc89BoWiY1dRqNdRqte3fABEREdklyVpuXF1dMXjwYCQlJVmOGY1GJCUlYdiwYY1eU1VV1SDAKJVKAIAoiu1XLBERETkMyVpuACAxMRFz5szBkCFDEBsbi5UrV6KyshIJCQkAgNmzZyM0NBTLly8HAEyaNAkrVqzAoEGDMHToUKSkpGDRokWYNGmSJeQQERGRc5M03EyfPh35+flYvHgxcnJyEBMTg+3bt1sGGWdkZFi11Dz//PMQBAHPP/88srKy4O/vj0mTJuGVV16R6i0QERGRnRFEJ+vPKSsrg1arRWlpKby9vaUuR/Y+/z2j1dfMGtq1HSohIiJn4VCzpYiIiIiaw3BDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREssJwQ0RERLLCcENERESywnBDREREsiJ5uFm1ahUiIiKg0WgwdOhQHDx48Lrnl5SU4B//+AeCg4OhVqvRs2dPbNu2rYOqJSIiInunkvLmGzduRGJiIlavXo2hQ4di5cqVGD9+PM6dO4eAgIAG59fW1uK2225DQEAANm/ejNDQUKSnp8PHx0eC6omIiMgeCaIoilLdfOjQobj55pvx7rvvAgCMRiPCwsLw2GOP4Zlnnmlw/urVq/H6668jOTkZLi4ubbpnWVkZtFotSktL4e3tfUP1U/M+/z2j1dfMGtq1HSohIiJnIVm3VG1tLY4cOYL4+Pg/i1EoEB8fjwMHDjR6zXfffYdhw4bhH//4BwIDA9GvXz8sW7YMBoOhyfvodDqUlZVZPYiIiEi+JAs3BQUFMBgMCAwMtDoeGBiInJycRq+5ePEiNm/eDIPBgG3btmHRokV488038fLLLzd5n+XLl0Or1VoeYWFhNn0fREREZF8kH1DcGkajEQEBAfjwww8xePBgTJ8+Hc899xxWr17d5DULFy5EaWmp5ZGZmdmBFRMREVFHk2xAsZ+fH5RKJXJzc62O5+bmIigoqNFrgoOD4eLiAqVSaTnWu3dv5OTkoLa2Fq6urg2uUavVUKvVti2eiIiI7JZk4cbV1RWDBw9GUlISpkyZAsDUMpOUlIRHH3200WtGjBiBzz//HEajEQqFqdHp/PnzCA4ObjTYkOMSRRGXCipRVWuASikgrJM7PNTX/3Zty+BlgAOYiYjkRtKp4ImJiZgzZw6GDBmC2NhYrFy5EpWVlUhISAAAzJ49G6GhoVi+fDkA4OGHH8a7776LJ554Ao899hguXLiAZcuW4fHHH5fybZANiaKI3cl5WLU7BYfTiy3HPVyVuP+WcPwtLhKB3hoJKyQiInsnabiZPn068vPzsXjxYuTk5CAmJgbbt2+3DDLOyMiwtNAAQFhYGH766Sc89dRTGDBgAEJDQ/HEE0/g6aefluotkA0ZjCI2H8nEiculAABXpQK+Hq6o0RtQUlWHD/ddxPoDaVg5fRDu6Nd41yUREZGk69xIgevcdKyWdhUZRRFfHTYFG5VCQMKICMwb2Q0B3hqIoog95/Lx9q4LOJZRAkEAXpzcF7OHRbTpXtditxQRkbxI2nJDZPbNsSycuFwKhQCsuv8mjO/7Z8uMIAi4tVcARvbww+LvTuPz3zOw+NvTqDOI+FtcpIRVExGRPXKoqeAkT2ezy3A4vRgKAZgZ29Uq2FxNpVTglSn98GR8DwDAsm1n8WtqQUeWSkREDoDhhiRVU2fAdyeuAADiovzQN0R73fMFQcAT43rgnkGhMBhFPPb5MVwpqe6IUomIyEEw3JCkdpzJRWl1HXw9XDG2V2DzF8AUcJbd0x99Q7xRWFmLJ748BqPRqYaOERHRdTDckGRyymrw+8VCAMCUmFC4qlr+7ahxUWL1XwfD3VWJQ2nF2HSYK08TEZEJww1JZt/5fIgA+oZ4IyrAs9XXh/m6I/G2ngCA5T8mo0Knt3GFRETkiBhuSBLFVbU4ebkEADCmZ0CbX2fu8Aj0DvZGaXUdfvwj21blERGRA2O4IUnsTymAUQS6+3sgtJNbm19HpVRg2dR+EATgWGYJsji4mIjI6THcUIer0ulxKK0IADCqh/8Nv96grp1w98AQAMB/z+Q2czYREckdww11uMPpxagziAjRato01qYxT8T3hEIAzuWWI6Ow0iavSUREjonhhjqUKIo4mmHaEHNot84QBMEmrxvp54GbunYCAOw8y9YbIiJnxnBDHSq7tAZ55TqoFAL6NbNgX2vd2isASkFAan4lLhWw9YaIyFlxbynqUMfqW216BXvDzVXZ6Dlt3QCzk7srBod3wsG0IvySUoBIP48210lERI6LLTfUYQxGESculwIABoX5tMs9RkT5AQCSs8tQUKFrl3sQEZF9Y7ihDpOSV4EKnR7urkr0DPRql3v4e6nRK8gLIsBNNYmInFSbws3FixdtXQc5gRP1i/YN7OIDpcI2A4kbY269OZJejKparlpMRORs2hRuoqKicOutt2LDhg2oqamxdU0kQwajiOScMgDAgC62HUh8rW5+HgjWalBnEHEorbhd70VERPanTeHm6NGjGDBgABITExEUFIS///3vOHjwoK1rIxlJL6xETZ0R7q5KhPm6t+u9BEHA8O6m1ptDaUUwitwxnIjImbQp3MTExOCtt97ClStXsGbNGmRnZyMuLg79+vXDihUrkJ+fb+s6ycEl55QDAKIDvaCw0do219M/VAuNiwJFlbW4mM9p4UREzuSGBhSrVCrcc889+Oqrr/Daa68hJSUFCxYsQFhYGGbPno3sbG5kSCbmLqlewd4dcj9XlQIDu5hmZJm3eiAiIudwQ+Hm8OHDeOSRRxAcHIwVK1ZgwYIFSE1Nxc6dO3HlyhXcfffdtqqTHFhBuQ4FFbVQCgJ62Gi7hZa4OcIXAHDmShkqdBxYTETkLNq0iN+KFSuwdu1anDt3DhMnTsT69esxceJEKBSmrBQZGYl169YhIiLClrWSgzpb32oT6ecBjUvjC/e1hxAfN4T6uCGrpBrHMoox0gabdBIRkf1rU8vN+++/j1mzZiE9PR3ffPMN7rrrLkuwMQsICMAnn3xikyLJsZnH2/QKbp+1ba4ntr715nBaMUQOLCYicgptarnZuXMnunbt2iDQiKKIzMxMdO3aFa6urpgzZ45NiiTHpaszIL1+l+5eQR0z3uZq/bto8f3JK8iv0OFKaQ1Cfdw6vAYiIupYbWq56d69OwoKGq7+WlRUhMjIyBsuiuQjrbASRhHw9XCFr4drh99f46JE7/pBzMczuOYNEZEzaFO4aap5v6KiAhqN5oYKInkxT8PuJuEmljH1+1idvFzKNW+IiJxAq7qlEhMTAZgWSVu8eDHc3f9cjM1gMOD3339HTEyMbSskh5ZaUAEA6ObfcbOkrtUj0BNuLkqU6/RIza9Aj4COH/tDREQdp1Xh5tixYwBMLTd//PEHXF3/7GZwdXXFwIEDsWDBAttWSMmwO8oAACAASURBVA6rpKoW2SWm7Tm6+UvXcqNSKNC/ixYHLxXhRGYJww0Rkcy1Ktzs3r0bAJCQkIC33noL3t4dP0CUHMdvF4sgAvD3VMNb4yJpLTFdfHDwUhFOXSnD5IFGuKpuaIknIiKyY236H37t2rUMNtSs3y4WApC21casa2d3+Li5oFZvxIW8cqnLISKidtTilpt77rkH69atg7e3N+65557rnrtly5YbLowc36+pphl13SUcb2OmEAT0C9Xil5QCnMoqRd+Q9t2ZnIiIpNPicKPVaiHUb3io1fIHA11ffrkO53NNg4kjJZwpdbV+Id74JaUAyTnlqDMY4aJk1xQRkRy1ONysXbu20T8TNca8WWWQtwYe6jatFWlzXXzdoXVzQWl1HVLyKizr3xARkby06VfX6upqVFVVWb5OT0/HypUrsWPHDpsVRo7tSLppwbzwzu7NnNlxFIKAviGmQHMqq1TiaoiIqL20KdzcfffdWL9+PQCgpKQEsbGxePPNN3H33Xfj/ffft2mB5JjM4aarr/2EGwDoVz/W5mxOGfQGo8TVEBFRe2hTuDl69ChGjhwJANi8eTOCgoKQnp6O9evX4+2337ZpgeR4auoMOH3F1DIS3tk+xtuYde3sDi+NCjV1RqTmV0hdDhERtYM2hZuqqip4eZkWQtuxYwfuueceKBQK3HLLLUhPT7dpgeR4TmWVos4gws9TjU7u0q5vcy2FIKBP/VibM9mcEk5EJEdtCjdRUVH45ptvkJmZiZ9++gm33347ACAvL4/r35ClS2pwuI9lhp09MQ8kTs4p415TREQy1KZws3jxYixYsAAREREYOnQohg0bBsDUijNo0CCbFkiO589w00niShrXzc8DapUC5TV6ZBVXS10OERHZWJvCzbRp05CRkYHDhw9j+/btluPjxo3Dv/71L5sVR45HFEUczTCHG1+Jq2mcSqlAj0BTt+rZnDKJqyEiIltr8wIkQUFBCAoKsjoWGxt7wwWRY8soqkJBRS1clQr0C/XGuRz7HNfSO8gLp7JKcTab4YaISG7aFG4qKyvx6quvIikpCXl5eTAarafUXrx40SbFkeMxd0n176KFWqWUuJqmRQd5QSEAuWU6ZBRWoasdrcdDREQ3pk3h5qGHHsLevXvxwAMPIDg42C4HjZI0jmWUAAAGhflIXMn1ubuqEN7ZA5cKKrHzbC7+FhcpdUlERGQjbQo3P/74I7Zu3YoRI0bYuh6yU5//ntGi83afywMAVOj0Lb5GKr2DvXGpoBK7k/MYboiIZKRNA4o7deoEX1/7HCxK0tEbjcgurQEAhPq4SVxN83oGmnYrP3ipCFW1eomrISIiW2lTuHnppZewePFiq/2liHJLdTAYRbi5KOHr4Sp1Oc3yr19ksNZgxIHUQqnLISIiG2lTt9Sbb76J1NRUBAYGIiIiAi4u1qvQHj161CbFkWO5XGIKu106uTnEOCxBENAj0AsHLxVh7/l8jOsdKHVJRERkA20KN1OmTLF1HSQD5gXxHKFLyiz6qnBDRETy0KZws2TJElvXQTJwuT7cdOnkOOGmm58HXJQC0gurcKmgEpF+9rXRJxERtV6bxtwAQElJCT7++GMsXLgQRUVFAEzdUVlZWTYrjhxHrd6IvPL6wcSdHGfNGLWLEjdHmAbH762f6UVERI6tTeHm5MmT6NmzJ1577TW88cYbKCkxrW2yZcsWLFy40KYFkmPILq2GUQS81Cp4a9q88LUkRvf0BwDsYdcUEZEstCncJCYmYu7cubhw4QI0Go3l+MSJE7Fv3z6bFUeOI6ukfryNgwwmvtqY6AAAwG8XC1FTZ5C4GiIiulFtCjeHDh3C3//+9wbHQ0NDkZOTc8NFkeMxj7cJdaDxNmY9Az0R5K1BTZ0Rv18qkrocIiK6QW0KN2q1GmVlDTccPH/+PPz9/W+4KHI85pabLg40U8pMEARL19Tec+yaIiJydG0KN5MnT8bSpUtRV1cHwPTDISMjA08//TTuvfdemxZI9q9Wb0RBuQ4AEOyA4QYAxkTXh5vzHFRMROTo2hRu3nzzTVRUVMDf3x/V1dUYPXo0oqKi4OXlhVdeecXWNZKdyymrgQjAU62Ct8al2fPt0fAoPygVAlLzK5FZxJW3iYgcWZumtWi1WuzcuRP79+/HiRMnUFFRgZtuugnx8fG2ro8cwJX6LqkQH00zZ9ovrZsLBnfthINppgX9/npLuNQlERFRG7U63BiNRqxbtw5btmxBWloaBEFAZGQkgoKCIIqiw82UoRuXXWoKN8Fax+ySMhsd7Y+DaUXYc47hhojIkbWqW0oURUyePBkPPfQQsrKy0L9/f/Tt2xfp6emYO3cupk6d2l51kh27UmJavC/EQcfbmJkHFf+aWoBavVHiaoiIqK1a1XKzbt067Nu3D0lJSbj11lutntu1axemTJmC9evXY/bs2TYtkuyXwSgit6w+3Ggdt1sKAPoEe8PPU42CCh2OpBdjWPfOUpdERERt0KqWmy+++ALPPvtsg2ADAGPHjsUzzzyDf//73zYrjuxffrkOeqMItUqBTh6uUpdzQxQKASOiTIHm19QCiashIqK2alW4OXnyJO64444mn58wYQJOnDhxw0WR4zCPtwnSaqCQwXirEVF+AIBfUhhuiIgcVavCTVFREQIDA5t8PjAwEMXFxTdcFDkOy0wpBx9MbGYONycvl6Kspk7iaoiIqC1aFW4MBgNUqqaH6SiVSuj1+hsuihzHlVLzYGLHHm9jFurjhkg/DxiMIn6/yK0YiIgcUasGFIuiiLlz50KtVjf6vE6ns0lR5BhEUZTNNPCrjYjqjEsFldifUoDb+jTdUklERPapVeFmzpw5zZ7DmVLOo6S6DjV1RigEIMC78cDriOKi/LDhtwyOuyEiclCtCjdr165tlyJWrVqF119/HTk5ORg4cCDeeecdxMbGNnvdl19+iZkzZ+Luu+/GN9980y61UdNy67uk/L3UUCnatJOHXbqlW2cIApCSV4HcshoEesujy42IyFlI/hNp48aNSExMxJIlS3D06FEMHDgQ48ePR17e9TcwTEtLw4IFCzBy5MgOqpSulVO/vk2QzH74+7i7on+oFgCwn603REQOR/Jws2LFCsybNw8JCQno06cPVq9eDXd3d6xZs6bJawwGA+6//368+OKL6NatWwdWS1eTa7gBOCWciMiRSRpuamtrceTIEasNNxUKBeLj43HgwIEmr1u6dCkCAgLwt7/9rdl76HQ6lJWVWT3INnLqu6UCHXxl4sbE1Yeb/SkFEEVR4mqIiKg1JA03BQUFMBgMDdbOCQwMRE5OTqPX/PLLL/jkk0/w0Ucftegey5cvh1artTzCwsJuuG4C9EYjCipMs+Pk2HIzOLwTXFUK5JbpkJpfKXU5RETUCpJ3S7VGeXk5HnjgAXz00Ufw8/Nr0TULFy5EaWmp5ZGZmdnOVTqH/HIdjCKgcVFA6+YidTk2p3FR4uaITgA47oaIyNG0araUrfn5+UGpVCI3N9fqeG5uLoKCghqcn5qairS0NEyaNMlyzGg07d6sUqlw7tw5dO/e3eoatVrd5Lo81HaWLilvDQQZbLvQmBFRftifUohfUgowZ3iE1OUQEVELSdpy4+rqisGDByMpKclyzGg0IikpCcOGDWtwfq9evfDHH3/g+PHjlsfkyZNx66234vjx4+xy6kC5Mh5MbDaiu6l18LeLhdAbjBJXQ0RELSVpyw0AJCYmYs6cORgyZAhiY2OxcuVKVFZWIiEhAYBpUcDQ0FAsX74cGo0G/fr1s7rex8cHABocp/Zlnikl5zVg+oVq4a1RoaxGjz+ySjGoayepSyIiohaQPNxMnz4d+fn5WLx4MXJychATE4Pt27dbBhlnZGRAIaMF4uQit8w0mDhYhjOlzJQKAcO7+2H76RzsTylguCEichCShxsAePTRR/Hoo482+tyePXuue+26detsXxBdV3WtAaXVph2z5dxyA5j2mdp+Oge/pBTg0bE9pC6HiIhagE0i1GrmLikfNxdoXJQSV9O+zIv5HU0vQXWtQeJqiIioJRhuqNWcYbyNWaSfB0K0GtQajDiUViR1OURE1AIMN9Rq5g0zg2Q83sZMEARL6w3XuyEicgwMN9Rqct5TqjHcZ4qIyLEw3FCriKJoWeNGjntKNWZ4VGcAwJnsMhRV1kpcDRERNYfhhlqlpKoOOr0RSkGAv6dzrPwc4KVBdKAXRBE4kFoodTlERNQMhhtqFXOXlL+XGkqFPLddaIy59YZdU0RE9o/hhlrFsu2Ck3RJmcVxUDERkcNguKFWyS51nmngVxvarTNUCgEZRVXILKqSuhwiIroOhhtqlT83zHSO8TZmnmoVYsJM+5ixa4qIyL4x3FCL6Q1GFFSY9pRytpYbgFPCiYgcBcMNtVh+hQ5GEdC4KKB1c5G6nA4X18MUbn5NKYDRKEpcDRERNYXhhlosp/TPxfsEwXlmSpnFhPnAw1WJ4qo6nMkuk7ocIiJqgl3sCk6OQa57Sn3+e0aLzw3zdUdyTjne3ZWC1Q8MbseqiIiordhyQy3mrNPAr9bd3xMAkJpfIXElRETUFIYbarGru6WcVVSAKdykFVaips4gcTVERNQYhhtqkapaPcpq9ADk1y3VGgFeanipVagziDiaXix1OURE1AiGG2oR83gbH3cXaFyUElcjHUEQ0L2+9YZTwomI7BPDDbVILrukLMxdU9yKgYjIPjHcUIvklJkW72O4+XNQ8cmsUpRW1UlcDRERXYvhhlrEPFMq0IlnSplp3Vzg76WGKAIHLrL1hojI3jDcULOMRtEy5oYtNyZR/hx3Q0RkrxhuqFlZJdWo1RuhFAT4eTrXhplN+XPcTaHElRAR0bUYbqhZyTnlAIAAbzWUCufbdqExkX4eUCoEXCqoxOXiKqnLISKiqzDcULPO5Zj2UXLm9W2upXFRIibMBwBnTRER2RuGG2rW2fqWG463sRYXZdolfN95hhsiInvCcEPNOlcfbthyY210tD8A4OcL+dAbjBJXQ0REZgw3dF06vQGXCioBOPeGmY0Z2MUHPu4uKKvR43hmidTlEBFRPYYbuq6UvAoYjCLcXJTw1qikLseuKBUCRvYwtd7sPZ8vcTVERGTGcEPXlZz9Z5eUIHCm1LVG9zSFmz3nGG6IiOwFww1d17nc+sHEWq5v05hRPU2Div/IKkVBhU7iaoiICGC4oWYkW2ZKuUlciX0K8NKgb4g3AGAfu6aIiOwCww1dl3mNmyBvttw0ZUw0x90QEdkThhtqUnFlLXLrdwPnNPCmje4ZAMDUcmMwihJXQ0REDDfUJHOXVJdOblC7KCWuxn7d1NUHXhoViqvq8EdWqdTlEBE5PYYbapK5S6pXkLfEldg3lVJhWa14L2dNERFJjuGGmmSeKdUryEviSuyfZUr4+TyJKyEiIoYbapK5Wyqa4aZZ5q0YTmSWoLiyVuJqiIicG8MNNcpoFC17SrHlpnnBWjdEB3rBKAK/cJdwIiJJMdxQoy4XV6Oq1gBXpQIRfh5Sl+MQzFPCuVoxEZG0GG6oUWeyTYOJewR6wkXJb5OWMI+72Xs+H0ZOCScikgx/alGjzOGmdzBnSrXUkAhfeKpVKKjQcUo4EZGEGG6oUWfrw00fhpsWc1UpLK03SWdzJa6GiMh5MdxQo86y5aZNxvU2rVa88yynhBMRSUUldQFkf8pq6nC5uBoAW26u5/PfMxocq9LpIcAUDlftTkEnd1er52cN7dpB1REROS+23FADydmmKeAhWg207i4SV+NY3NUqhHc2zS5Lrm/9IiKijsVwQw2wS+rG9A42rQt0tn6dICIi6lgMN9TAmSsMNzfC/Lldyq9ETZ1B4mqIiJwPww01cDaH4eZG+Hmq4eephkEULftzERFRx2G4ISt6g9Gy7UKfEIabtupb/9mdvsJxN0REHY3hhqykFVZCpzfC3VWJcF93qctxWOZwcz6nHHUGo8TVEBE5F4YbsnIm+8+dwBUKQeJqHFeojxt83FxQazDiQm6F1OUQETkVhhuywplStiEIwlVdU9yKgYioIzHckBWGG9vpG6IFYBqgrTeya4qIqKMw3JAV8zTwPvVrtVDbde3sDi+1CjV1RlzMr5S6HCIip8FwQxaFFTrklesAANFBbLm5UQpBQO/6rqlT3CWciKjDMNyQxdn6wcQRnd3hqea2Y7YwINTUNXX6CrumiIg6CsMNWXC8je1F+HnAS6NCdZ0BKZw1RUTUIRhuyILhxvYUgmBpvTlxuUTiaoiInAPDDVmcYbhpFwO6+AAwdftV13KvKSKi9sZwQwAAnd6AlDxTt0lvzpSyqS6d3NDJ3bSgX1JyrtTlEBHJHsMNAQBS8iqgN4rw1qgQ6uMmdTmyIgiCpfXmu+NXJK6GiEj+GG4IwJ8zpXoFe0MQuO2CrQ2sDze7z+WhuLJW4mqIiOSN4YYA/DmYuA/H27SLIK0GwVoN6gwivj/J1hsiovbEcEMA/lxkrk8Iw017ualrJwDA10cuS1wJEZG82UW4WbVqFSIiIqDRaDB06FAcPHiwyXM/+ugjjBw5Ep06dUKnTp0QHx9/3fOpeUajiNP12y70r5+2TLY3MMwHKoWAE5dLkZJXLnU5RESyJXm42bhxIxITE7FkyRIcPXoUAwcOxPjx45GXl9fo+Xv27MHMmTOxe/duHDhwAGFhYbj99tuRlZXVwZXLR1phJSp0eqhVCvQI8JS6HNnyVKswJtofAPD1UX6/EhG1F8nDzYoVKzBv3jwkJCSgT58+WL16Ndzd3bFmzZpGz//3v/+NRx55BDExMejVqxc+/vhjGI1GJCUldXDl8vFHfZdU72BvqJSSf0vI2r03dQEA/OdoFgxGUeJqiIjkSdKfZLW1tThy5Aji4+MtxxQKBeLj43HgwIEWvUZVVRXq6urg6+vb6PM6nQ5lZWVWD7JmHm8zoAu7pNrb2N4B8HF3QU5ZDfadz5e6HCIiWZI03BQUFMBgMCAwMNDqeGBgIHJyclr0Gk8//TRCQkKsAtLVli9fDq1Wa3mEhYXdcN1yc/KyKdz043ibdqdWKS2tN58fzJC4GiIieXLoPohXX30VX375Jf7zn/9Ao9E0es7ChQtRWlpqeWRmZnZwlfaNg4k73sxYU8DelZyHnNIaiashIpIfScONn58flEolcnOtl6TPzc1FUFDQda9944038Oqrr2LHjh0YMGBAk+ep1Wp4e3tbPehPHEzc8aICvBAb6QuDUcSmwwzbRES2Jmm4cXV1xeDBg60GA5sHBw8bNqzJ6/75z3/ipZdewvbt2zFkyJCOKFW2OJhYGrNiuwIAvjyYwYHFREQ2JvlPs8TERHz00Uf49NNPcfbsWTz88MOorKxEQkICAGD27NlYuHCh5fzXXnsNixYtwpo1axAREYGcnBzk5OSgoqJCqrfg0DiYWBp39AuC1s0FV0prsOdc48seEBFR20gebqZPn4433ngDixcvRkxMDI4fP47t27dbBhlnZGQgOzvbcv7777+P2tpaTJs2DcHBwZbHG2+8IdVbcGgcTCwNjYsS9w0xDSxe92uatMUQEcmMIIqiU7WJl5WVQavVorS01OnH3xiMIga+uAMVOj1+fGIkel9nX6nPf+fMHluYNbSr5c+ZRVUY9fpuiCLw38RRiArwkrAyIiL5kLzlhqSTml+BCp0e7q5K9AzkD9aOFubrjvjephZKtt4QEdkOw40TO5ZRDMA0BVypECSuxjkljIgAAHx9JAulVXXSFkNEJBMMN07seGYJAGBQ/W7V1PGGdeuMXkFeqK4zYONhdv0REdkCw40TO5ZhCjcxYT4SV+K8BEGwtN6s+SUNtXqjtAUREckAw42TqtTpcT63HAAwqCvDjZSmDApFgJcaOWU1+PY4dwsnIrpRDDdO6uTlUhhFIESrQaB341tXUMdQq5R4MC4SALB6byqMXNSPiOiGMNw4KfN4mxi22tiF+4d2hZdGhdT8Svz3bG7zFxARUZNUUhdA0jDPlOJ4G/vgpXHBX28Jx/t7UvH+3lTc1icQgsAZbE1p67pLV68zRETyxZYbJySKImdK2aGEERFQqxQ4llGCny8USF0OEZHDYrhxQldKa5BXroNSIaBfCLddsBcBXhr89ZZwAMDK/56Hky0eTkRkMww3TuhwWhEAoE+wN9xclRJXQ1f7++huUKsUOMrWGyKiNmO4cUKH6sPNzRG+EldC12LrDRHRjWO4cUKHLpkGE8dGcryNPbq69WZXcp7U5RARORyGGydTUlWLc/WL9w1hy41dCvDSYO7wCADAP7efg4Hr3hARtQrDjZM5nGZqtenm7wE/T7XE1VBTHh7THd4aFc7lluObY1y1mIioNbjOjZOxjLcJZ6uNPfNxd8XDY6Lw2vZkrNh5HhU6PVyUrf9dhOu6EJEzYsuNkzloDjeRDDf2LmFEBIK8NcgqqcZvFwulLoeIyGEw3DiR6loD/rhcCgCI5Xgbu6dxUSLx9p4AgF3JeajQ6SWuiIjIMTDcOJHjmSXQG0UEeqsR5usmdTnUAtNu6oJ+od7Q6Y3YeYZ7ThERtQTDjRMxd23cHOHLfYschEIhYPFdfQGYFl/MLq2WuCIiIvvHcONEfk01rXg7IspP4kqoNWIjfdEvVAsRwPcnrnBhPyKiZjDcOIkKnR7HMkybZcYx3DicCf2C4KIUkFZYhWP1m54SEVHjGG6cxMFLhdAbRXT1dUeYr7vU5VArdXJ3xdjoAADAj39ko7rWIHFFRET2i+HGSfxywTTehl1SjmtEDz/4e6lRWWvAjjM5UpdDRGS3GG6cxP4U03gbdkk5LpVCgbsHhgAADl4qQnphpcQVERHZJ4YbJ5BXXoNzueUQBGBY985Sl0M3oJu/JwZ37QQRwJajWagzGKUuiYjI7jDcOIFfU0xdUn1DvOHr4SpxNXSjJvYPhpdahfwKHXaf467hRETXYrhxAj9f4BRwOXFzVWJSfffUvvP5yCrh2jdERFdjuJE5o1HE3vOm3+5H9fCXuBqylX6hWvQN8YZRBL46nMnuKSKiqzDcyNzxyyUoqKiFl1qFm7mflKzcHRMKT7UKeeU6bs1ARHQVhhuZSzpr+qE3Ktofrir+dcuJp1qFqYNCAZhmw13Mr5C4IiIi+8CfdjKXdNbUJRXfO0DiSqg99A72xpBw0+ypTYczUcmdw4mIGG7k7HJxFZJzyqEQgDE9GW7k6s4BwfDzVKOsRo+vj17m3lNE5PQYbmTM3GozJNwXnTgFXLbUKiVm3BwGlUJAck45fk0tlLokIiJJMdzI2H/rx9uMY5eU7IX4uGFCvyAAwI+nspFWwNWLich5MdzIVGlVHX67aPoNflzvQImroY5wS7fO6B+qhVEEvjiYgbLqOqlLIiKSBMONTP14Kht1BhG9grwQFeApdTnUAQRBwL03dUGgtxrlOj0+P5iBmjruHk5EzofhRqa+P3kFACwr2ZJzcFUpcP/QcGhcFMgoqsLTX5/kAGMicjoqqQsg28srr8GB+kGlkxlu7Mrnv2e0+z38PNWYFRuOdb9ewrfHryCisweeuq1nu9+3re9t1tCuNq6EiJwdW25kaOvJbBhFYFBXH4T5uktdDkkgKsATd8eYFvh7K+kCvjjY/qGKiMheMNzI0HcnTF1SbLVxbjdH+OIft3YHADz7nz8s3xdERHLHcCMzGYVVOJZRAoVgWtyNnNuC26Px11u6QhSBxI3H8dPpHKlLIiJqdww3MvPlIVP3w4goPwR4aSSuhqQmCAKWTu6HqYNCoTeKeOTfR/HNsSypyyIialcMNzJSqzdi0+FMAMD9Q8MlrobshUIh4PVpA3DvTV1gMIp4atNxfPprmtRlERG1G86WkpEdZ3JQUFGLQG81VyUmKyqlAq9PGwAPtRLrD6RjyXencSGvHEsm9YWL0r5+xxFFEXnlOqTmVeBiQSVySmuQW1aD0uo6VNcZoDeIKKzUQaVQwFOjgtbNBZ09XBHi4wZfD1coBEHqt0BEEmO4kZENv6UDAKbf3NXufmCR9BQKAS9O7otAbw3e2HEOG37LwPncCvxregxCfdwkq6tSp8eJzBIcyyzB8fpHfrmuTa/l5qJEd38P9AjwQp8Qb3io+V8ckTPiv3yZSMmrwG8Xi6AQgBk3h0ldDtkpQRDwj1ujEB3ohSe+PIaDl4pwx8p9eHFyX0wdFAqhA1o9DEYRl4urkJJXgZT8Ciz+9hT0RuuFBpUKAV193dHNzwOhndwQ6K2Bj7sL3FyUUCkV2HcuH7UGI8pr9CitrkNeeQ1ySmtQXWfAqStlOHWlDN+eyELPQC/cHOGL6CAvtugQORGGG5lY9+slAMDYXoEIkfC3cHIM8X0C8cPjI5G46TiOZZQgcdMJfHkwE8/d2RsDw3xsei9RFFFYUYsL+RVIyS3HxYJK6PRGq3NCtBoM6toJMWE+iOnqg34hWri5Kpt8zYoafYNjBqOIrJJqXMgrx9krZbhSWoPknHIk55Sjs4cr4nr4YdrgLnBVsVWTSO4YbmQgt6wGmw5dBgDMGxkpcTXkKCL9PPDV34dh9d5UvLMrBQfTinD3qv0YE+2POcMjMLqHPxSKtrV2VNXqkZpfiQu55UjJr0BJlfUmnm4uSnQP8EQPf088dVtPdO1844tNmlt7uvq6Y1yvQOSW1eBoejEOpRehsLIW3x6/gsNpxXhiXA/cO7gLlG18b0Rk/xhuZODDfRdRazAiNsIXQ7t1lrocciAqpQKPjjX9sH/9p3P4z7Es7DmXjz3n8hHorcat0QGI6+GH3sHeiOjs0SAQGI0iCip0SMmvwM8X8nG5uBpXSqpRWFlrdZ5SISDc1x09AjwRFeCFYB+NpZvIFsGmMYHeGkzoH4yxvQNwJL0Ye8/nI6ukGv/39Un8+/d0vDylP/p30bbLvYlIWoLoZLvqlZWVQavVorS0FN7e3lKXc8MKK3QY8dou1NQZcXMEQwAAE6pJREFUsf7BWIzq6d8u9+mIPZHI9lq7b9Olgkp8diAdXx3JRPk1XT8qhQCtmwu8NCoYRBE1dUYUV9Y2GC9jFuCltoSZSD+PJruD2rK3VFu+H+sMRuj0BryTlIJynR6CAPx1aDgW3B4NrbtLq1+PiOwXW24c3Me/XEJNnREDumgxsoef1OWQg4v088DiSX3w9IRo/H6xCLuS83AsoxjncytQXWdAYWVtg1YZhQCE+LhB6+aCUB83hHZyQ6jWDe52NlPJRanAnOERmBITile2ncW3x6/gs9/Sse2PbCye1AeTB4Z0yIBqImp/9vW/D7XK5eIqrPnFNJD40Vuj+B8z2YxapcSonv6WlkCjUURuuWmtmfIaPZQKAa5KBXw9XBHgpYZKqXCY1r0Abw3emjEI028Ow+JvTyMlrwJPfHkc20/l4JWp/eHr4Sp1iUR0gxhuHNiybWeh0xtxSzdf3NYnUOpySMYUCgHBWjcEa+UzE294dz9se3wkVu9NxdtJF/DjqRwcSivGq/f0Rzz/PRE5NIYbB/VrSgG2/ZEDhQC8MLkvW23IYUnZ4uOqUuDxcT0wtlcAEjcdx/ncCjy0/jDuG9IFi+7qAy8Nx+JQy7T1+7gtY86oeVzwwQHp9Aa88P1pAMADt4SjV5DjD4wmklK/UC2+ezQOfx/VDYIAbDp8GXes/BkHUgulLo2I2oDhxgG9vv0czudWwNfDFU/d1lPqcohkQeOixMKJvbFx/jCE+bohq6QaMz/6DS9+fxrVtQapyyOiVmC4cTB7z+fj4/pBxK9PGwAfdw5+JLKl2Ehf/PjEKMyMNXUXrN2fhglv7cPhtCKJKyOilmK4cSC5ZTX4f5tOAADmDAvHuN4c9EjUHjzVKiy/pz8+fTAWQd4apBVW4S8fHMArW8+gpo6tOET2juHGQZTV1GHu2kMoqNAhOtALCyf2lrokItkb3dMfPz01CtMGd4EoAh/9fAkT3voZ+87nS10aEV0Hw40D0OkN+J/PjuBsdhn8PNX4aPYQaFya3lSQiGxH6+aCN/4yEJ/MGYIALzUuFVRi9pqDeHjDEWSVVEtdHhE1guHGzlXo9Ji3/gh+TS2Eh6sS6xJubre9eIioaeN6B2Jn4mgk/P/27j6oqavPA/j35oUkQBIgQIJIebG20kUFBFHQqo9udaud+rRrHcdu1bHa6SC+0O0UO1OtHSt2kJZWVARb23lWB7fTte06qx2GPmptbVWsz1ZZaJFGEOVVGkiAhCTsHyA1xRfqCzck38/MnSSHcy+/O/fm5pdzTu5Ji4JUIuDw+XrMyj2GHX+vgtXOrioid8L73LixxrYuLPv4NC5caYNKLsXuf0tCXDgn+qPBu5t7b/C+G7emVcmx8al/wnNJEdj4xQWcMl5DzleV2P9DDVbPfBjPJo6ETMrvjERi47vQTZWUN+DJD77BhStt0Pn5oHjlJEzh3FFEbiE2TIMDL01C3sJ4GDRK1P3Widc++wl/yT2Gv5008qfjdFs9PT2wO5ywdjtgszvhZfNXDwm23LiZq6ZO5HxVif86WwcAeETvj6IXkhCp8xM5MiK6kSAImJ8QjjlxBvzH95ew8+hF1FzrwBtfXEBuyc/418SRWJTyEEaF+IsdKg2RDpsdzWYbms1WXLPYYO6yw2y1o72rG2arHV3dTtidTtgdPbiezmw6VA5BAHykEihkEmhUcuj8FQjx90GwvwIhagUignwRpfNDpM4XoWoF70g/CExu3ETttQ58/J0Rf/v+Emx2JwQBWDk1Buv++REOHiZyY0q5FC9OjcHilEj855laFH1Tjcutndhz4lfsOfErxo/U4qnxIzAzVo8onS8/mIa5rm4HjC0W/NpkQXWzBb82W1DdZEZFfTs67rLFrqcHsNqdsNqdaOuy43LrrQeqq+RSROp8EanrTXiig3uXmBB/BPv78PzqI/S4QXvYjh07kJOTg/r6eowfPx7bt2/HxIkTb1n/008/xRtvvAGj0YjRo0fjnXfewZNPPjmo/9XW1gatVguTyQSNRtxpCxrbu3C0ogn//b9XcKKqGdePxMSoILz2L2MwITJQ1PhuNFxmfKZ7d7djbobDOTIU44nsDieO/dyE/T/U4O+VjXDecIUND1AhdZQOaQ8HY1KMDnoNv4W7o06bA7WtHai91oFLLR29yUyzBdVNFlwxdeJ2n5oapQzBagV0fj5QK+XwV8igVsrgr5BBKZdCLpVAJhUgl0gglQj4a2I4rHYHrN29yY2psxvNZita+lqAGtq6UNMXx+XWDpfz6Y/UShlibkh2eh97X/v6eFdbhuh7e+DAAWRmZqKgoAApKSnIy8vD7NmzUVlZidDQ0AH1v/vuOyxatAjZ2dmYN28e9u/fj/nz5+Ps2bOIi4sTYQ/uzGZ3ou63zr4T1IILdW04V/sbKhvaXepNeTgYL06NxrRHQnjBIxqmZFIJZsbqMTNWj6Z2Kw6fv4r/+ekqyi61ou63Tnxadhmfll0GAAT4yvGIXo0xBjUe0asREeQLg0YJg0YJjUrG68B91tPT0588NLX3Jg/Xl7rW3mt0bWsnmtqtt92ORilDTIh/fyIRHeKHiqvt0Pn7QCH7cy3tWpUcwOAmaL3+WWJsseBSswXGlo6+1iMzLrd2or3Ljn9cNuEfl00D1jVolBgRoIRBq4RBo4JBq4Beo0SYVoVQtQIBvnKolXJIJZ5xzonecpOSkoLk5GTk5+cDAJxOJyIiIpCRkYGsrKwB9RcuXAiLxYJDhw71l02aNAnx8fEoKCi44/97UC03l1os2P9DDdq6umHq7F3aOu1oMVtxta3rlpn++JFa/GWMHn9NCHfrn3gPh2/ldH+w5ebB6LDZcdrYiu+qmnGiqhn/d7Xttt/ClXIJQtW9SY5GKYda2fuo8pHCRyqBj+yGpW+8hkQiQIAAiQAIQu+4IAGARBAgCL8/CkJfHfS+BuByjbo+IsS17Hq9gUHfcd07bKdnwJObb8fZA3Q7nH1LD7odTtgdTthueG61O2G22mGx2mGxOnqf23pfmzq70e0Y3EeeWinDQ0G+iAj0RXRf68f1ZCbIb2D3j9izgnd1O1BzrQPVTWZU97Uy/drXbXbNYhv0dtQKGTQqOTQqObQqGfwVcijkEiikkt5HmRSKvvNOIet9LZcKkEoESCQCpELvY4i/AjPGDGygGCqittzYbDaUlZVh/fr1/WUSiQSzZs3CyZMnb7rOyZMnkZmZ6VI2e/ZsfP755zetb7VaYbX+noWbTL0ZbVtb272G78J4tRW7Ss7f8u9KuQQRgb4ID1Th4RB/jB2pRXxEAHT+ir4a9vse0/3UYWm/cyXyCHd7Hg6Hc0Ts91iCQYEEQzjSp4Sjq9uB6iYzqhrN+KXRjKrGdtSbersh2rrs6LACRrNZ1Hg9lVophc5fAZ2fAsF+PtD5+yBUo8RDQb4ID1BhZKAvtL63aE1xWtF+k5aduz3/7+c5aVABhof8kPqQ6w9Qfuuw4VKLBY1tVjS0d6Gh3YoGUxca26xobO9Ck9mKTpsTAGCyAqb7ENL4kVpMGDHp3jd0E2q1+o6tmqImN83NzXA4HNDrXedI0uv1qKiouOk69fX1N61fX19/0/rZ2dnYtGnTgPKIiIi7jPru/TLk/5Hoz1shdgAPkCfvGw1PnnpO1gLQ/vuD2fZgel5EH3PzoK1fv96lpcfpdOLatWvQ6XRD0p/d1taGiIgI1NbWij6AmX7H4+KeeFzcE4+Le/LW46JWq+9YR9TkJjg4GFKpFA0NDS7lDQ0NMBgMN13HYDD8qfoKhQIKhcKlLCAg4B6ivjsajcarTr7hgsfFPfG4uCceF/fE4zKQqHco9vHxwYQJE1BaWtpf5nQ6UVpaismTJ990ncmTJ7vUB4CSkpJb1iciIiLvInq3VGZmJpYsWYKkpCRMnDgReXl5sFgsWLZsGQDghRdeQHh4OLKzswEAa9aswbRp05Cbm4u5c+eiuLgYZ86cQWFhoZi7QURERG5C+uabb74pZgBxcXEICAjA22+/jW3btgEA9u3bh0cffRQA8P7770Mmk2H+/PkAegcCx8bGIicnB1u3bkVDQwM+/PBDpKWlibYPdyKVSjF9+nTIZKLnknQDHhf3xOPinnhc3BOPy82Jfp8bIiIiovuJs4ITERGRR2FyQ0RERB6FyQ0RERF5FCY3RERE5FGY3AwRo9GI5cuXIzo6GiqVCqNGjcLGjRthsw1+QjO6P3bs2IGoqCgolUqkpKTg1KlTYofk1bKzs5GcnAy1Wo3Q0FDMnz8flZWVYodFf7B161YIgoC1a9eKHYrXq6urw/PPPw+dTgeVSoWxY8fizJkzYoflVpjcDJGKigo4nU7s3r0bFy5cwHvvvYeCggK8/vrrYofmVQ4cOIDMzExs3LgRZ8+exfjx4zF79mw0NjaKHZrXOnbsGNLT0/H999+jpKQE3d3deOKJJ2CxWMQOjfqcPn0au3fvxrhx48QOxeu1trYiLS0Ncrkchw8fRnl5OXJzcxEYGCh2aG6FPwUXUU5ODnbt2oXq6mqxQ/EaKSkpSE5ORn5+PoDeO2JHREQgIyMDWVlZIkdHANDU1ITQ0FAcO3YMjz/+uNjheD2z2YzExETs3LkTmzdvRnx8PPLy8sQOy2tlZWXh22+/xTfffCN2KG6NLTciMplMCAoKEjsMr2Gz2VBWVoZZs2b1l0kkEsyaNQsnT54UMTK6kclkAgC+N9xEeno65s6d6/K+IfF8+eWXSEpKwoIFCxAaGoqEhAQUFRWJHZbbYXIjkqqqKmzfvh0vvfSS2KF4jebmZjgcDuj1epdyvV6P+vp6kaKiGzmdTqxduxZpaWmIi4sTOxyvV1xcjLNnz/ZPf0Piq66uxq5duzB69Gh89dVXePnll7F69Wp88sknYofmVpjc3KOsrCwIgnDbpaKiwmWduro6zJkzBwsWLMCKFStEipzI/aSnp+P8+fMoLi4WOxSvV1tbizVr1mDfvn1QKpVih0N9nE4nEhMTsWXLFiQkJGDlypVYsWIFCgoKxA7NrXAyinv0yiuvYOnSpbetExMT0//8ypUrmDFjBlJTUznZ5xALDg6GVCpFQ0ODS3lDQwMMBoNIUdF1q1atwqFDh3D8+HGMHDlS7HC8XllZGRobG5GYmNhf5nA4cPz4ceTn58NqtUIqlYoYoXcKCwvDY4895lIWGxuLzz77TKSI3BOTm3sUEhKCkJCQQdWtq6vDjBkzMGHCBOzduxcSCRvOhpKPjw8mTJiA0tLS/olYnU4nSktLsWrVKpGj8149PT3IyMjAwYMHcfToUURHR4sdEgGYOXMmfvrpJ5eyZcuWYcyYMXjttdeY2IgkLS1twK0Sfv75Z0RGRooUkXticjNE6urqMH36dERGRmLbtm1oamrq/xtbDYZOZmYmlixZgqSkJEycOBF5eXmwWCxYtmyZ2KF5rfT0dOzfvx9ffPEF1Gp1//gnrVYLlUolcnTeS61WDxj35OfnB51Ox/FQIlq3bh1SU1OxZcsWPPfcczh16hQKCwvZE/AHTG6GSElJCaqqqlBVVTWgyZ2/xh86CxcuRFNTEzZs2ID6+nrEx8fjyJEjAwYZ09DZtWsXAGD69Oku5Xv37r1jly+Rt0lOTsbBgwexfv16vPXWW4iOjkZeXh4WL14sdmhuhfe5ISIiIo/CQR9ERETkUZjcEBERkUdhckNEREQehckNEREReRQmN0RERORRmNwQERGRR2FyQ0RERB6FyQ0RERF5FCY3ROTWenp6sHLlSgQFBUEQBJw7d07skIjIzfEOxUTk1g4fPoynn34aR48eRUxMDIKDgyGTceYYIro1XiGIyK1dvHgRYWFhSE1NvettdHd3Qy6X38eoiMidsVuKiNzW0qVLkZGRgZqaGgiCgKioKBw5cgRTpkxBQEAAdDod5s2bh4sXL/avYzQaIQgCDhw4gGnTpkGpVGLfvn0AgD179iA2NhZKpRJjxozBzp07xdo1InqA2C1FRG7LZDLhgw8+QGFhIU6fPg2pVIrjx49DEASMGzcOZrMZGzZsgNFoxLlz5yCRSGA0GhEdHY2oqCjk5uYiISEBSqUSX3/9NV599VXk5+cjISEBP/74I1asWIF3330XS5YsEXtXieg+YrcUEbktrVYLtVoNqVQKg8EAAHj22Wdd6nz00UcICQlBeXk54uLi+svXrl2LZ555pv/1xo0bkZub218WHR2N8vJy7N69m8kNkYdhtxQRDSu//PILFi1ahJiYGGg0GkRFRQEAampqXOolJSX1P7dYLLh48SKWL18Of3///mXz5s0uXVpE5BnYckNEw8pTTz2FyMhIFBUVYcSIEXA6nYiLi4PNZnOp5+fn1//cbDYDAIqKipCSkuJSTyqVPvigiWhIMbkhomGjpaUFlZWVKCoqwtSpUwEAJ06cuON6er0eI0aMQHV1NRYvXvygwyQikTG5IaJhIzAwEDqdDoWFhQgLC0NNTQ2ysrIGte6mTZuwevVqaLVazJkzB1arFWfOnEFraysyMzMfcORENJQ45oaIhg2JRILi4mKUlZUhLi4O69atQ05OzqDWffHFF7Fnzx7s3bsXY8eOxbRp0/Dxxx8jOjr6AUdNREONPwUnIiIij8KWGyIiIvIoTG6IiIjIozC5ISIiIo/C5IaIiIg8CpMbIiIi8ihMboiIiMijMLkhIiIij8LkhoiIiDwKkxsiIiLyKExuiIiIyKMwuSEiIiKP8v+1evfUlfLFcwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vZ9RJvhHkIB5", + "outputId": "dc181c26-7dd5-43eb-982f-dd8a2bcc892e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_titanic.describe()" + ], + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclassagesibspparchfare
count182.000000182.000000182.000000182.000000182.000000182.000000
mean0.6758241.19230835.6231870.4670330.47802278.919735
std0.4693570.51641115.6716150.6450070.75586976.490774
min0.0000001.0000000.9200000.0000000.0000000.000000
25%0.0000001.00000024.0000000.0000000.00000029.700000
50%1.0000001.00000036.0000000.0000000.00000057.000000
75%1.0000001.00000047.7500001.0000001.00000090.000000
max1.0000003.00000080.0000003.0000004.000000512.329200
\n", + "
" + ], + "text/plain": [ + " survived pclass age sibsp parch fare\n", + "count 182.000000 182.000000 182.000000 182.000000 182.000000 182.000000\n", + "mean 0.675824 1.192308 35.623187 0.467033 0.478022 78.919735\n", + "std 0.469357 0.516411 15.671615 0.645007 0.755869 76.490774\n", + "min 0.000000 1.000000 0.920000 0.000000 0.000000 0.000000\n", + "25% 0.000000 1.000000 24.000000 0.000000 0.000000 29.700000\n", + "50% 1.000000 1.000000 36.000000 0.000000 0.000000 57.000000\n", + "75% 1.000000 1.000000 47.750000 1.000000 1.000000 90.000000\n", + "max 1.000000 3.000000 80.000000 3.000000 4.000000 512.329200" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qa28Hc3ZC6FV" + }, + "source": [ + "___\n", + "## Kurtosis\n", + "> Kurtosis é uma medida estatística que define com que intensidade as caudas de uma distribuição diferem das caudas de uma distribuição Normal. Em outras palavras, a curtose identifica se as caudas de uma determinada distribuição contêm valores extremos.\n", + ">> A Kurtosis de uma distribuição Normal padrão é igual a 3. Portanto, se Kurtosis-3 > 0, então isso é o que chamamos de excesso de Kurtosis.\n", + ">>> **Alta Kurtosis é um indicador de que os dados possuem caudas pesadas ou outliers**.\n", + "\n", + "* **Dica muito importante**: Normalize os dados antes!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ynyNHZqmD-tb" + }, + "source": [ + "___\n", + "## Skewness\n", + "> É o grau de distorção da distribuição, ou seja, mede a falta de simetria na distribuição de dados, diferenciando valores extremos em uma cauda versus na outra. Uma distribuição simétrica terá uma assimetria de 0.\n", + "\n", + "![Skewness](https://github.com/MathMachado/Materials/blob/master/Skewness.png?raw=true)\n", + "\n", + "Source: [Skew and Kurtosis: 2 Important Statistics terms you need to know in Data Science](https://codeburst.io/2-important-statistics-terms-you-need-to-know-in-data-science-skewness-and-kurtosis-388fef94eeaa)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uoo3xVhBFixi" + }, + "source": [ + "### Interpretando a Skewness (Rule of Thumb)\n", + "* Se -0.5 < Skewness < 0.5: Dados razoavelmente simétricos;\n", + "* Se -1 < Skewness < -0.5: Dados moderadamente negativa;\n", + "* Se 0.5 < Skewness < 1: Dados moderadamente positiva;\n", + "* Se Skewness < -1: Dados altamente negativa;\n", + "* Se Skewness > 1: Dados altamente positiva.\n", + "\n", + "> **Dica**: Normalize os dados antes!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oHg3nyjUTiRu", + "outputId": "eaacbc04-e67b-4aa6-fec1-5d9cc97fa449", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cálculo das medidas de Skewness e Kurtosis para 'fare'\n", + "print(f\"Skewness: {df_titanic_ss['fare'].skew()}\")\n", + "print(f\"Kurtosis: {df_titanic_ss['fare'].kurt()}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Skewness: 2.7073683146429004\n", + "Kurtosis: 10.690697893681472\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V2jCZLGVH3Qu" + }, + "source": [ + "Olhando para as medidas de Skewness e Kurtosis logo acima, qual a conclusão?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0nnFS8vi_rOe", + "outputId": "fa152ce8-a07f-4bf4-9671-fe0012a72242", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 168 + } + }, + "source": [ + "# Distribuição da variável 'age'\n", + "df_titanic_ss['age'].describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "count 1.820000e+02\n", + "mean 1.464030e-17\n", + "std 1.002759e+00\n", + "min -2.220506e+00\n", + "25% -7.437173e-01\n", + "50% 2.411064e-02\n", + "75% 7.759421e-01\n", + "max 2.839480e+00\n", + "Name: age, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h9ZmvO1b_4sF", + "outputId": "56c563a6-6313-4d18-f336-d6bc308b1bf9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + } + }, + "source": [ + "plt.scatter(range(df_titanic_ss.shape[0]), np.sort(df_titanic_ss['age'].values))\n", + "plt.xlabel('index')\n", + "plt.ylabel('age')\n", + "plt.title(\"Distribuição da variável age\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAHHCAYAAABHp6kXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deXRUVdb38V8FSAIZKmYiYQohIIqAggoig1FRQATBCXACVHgaUBvRbsAWER4VxbEdGvER0RbbRmnUxiGIjC2iyNQYECQxgEIgQJokBJNAct4/eKs6ReZKzfl+1spa1K17b+1bN8j2nH33sRhjjAAAAPxckLcDAAAAcAWSGgAAEBBIagAAQEAgqQEAAAGBpAYAAAQEkhoAABAQSGoAAEBAIKkBAAABgaQGAHzMpk2bNGvWLOXk5Hg7FMCvkNQAdfT444/LYrF45LNSU1OVmppqf71mzRpZLBYtWbLEZZ+xd+9eWSwWvf3223U+dsmSJYqKilLv3r21Z88ejR8/Xi+99JLLYquOxWLR448/7pHPcqWavu9jx45p+PDhOnXqlOLj490ai+33ac2aNW79HMBTSGrQoL399tuyWCz2n9DQULVo0UIDBgzQyy+/rIKCApd8zsGDB/X4449r27ZtLjmfr5g7d67Gjx+vxMREnXfeeVq6dKmGDRvm7bD8ljFGo0ePVmpqqp544glvhwP4ncbeDgDwBbNnz1ZycrJOnTqlQ4cOac2aNZo8ebJeeOEF/fOf/1TXrl3t+z766KOaNm1anc5/8OBBzZo1S23bttVFF11U6+O+/PLLOn2OM5KSkvTbb7+pSZMmdT72ww8/VMuWLdW4cWMdOXJEERERCg0NdUOUgaO67zsrK0t9+vTRlClTvBAZ4P9IagBJgwYN0iWXXGJ/PX36dK1atUrXX3+9hg4dqh9//FFNmzaVJDVu3FiNG7v3r87JkyfVrFkzBQcHu/VzJNlHqJyRlJRk/3NcXJyrQgpIp0+fVllZmYKDg6v8vtu1a1fnhBnAfzH9BFThqquu0owZM7Rv3z4tWrTIvr2ympoVK1aoT58+ioqKUnh4uDp27KhHHnlE0pm6hUsvvVSSNHbsWPtUl62mIjU1VZ07d9bmzZvVr18/NWvWzH7s2TU1NqWlpXrkkUeUkJCgsLAwDR06VL/88ovDPm3bttWYMWMqHHv2Oauq8di1a5duvfVWxcXFqWnTpurYsaP+9Kc/2d/PysrShAkTdO6556pp06aKiYnRLbfcor1791b4zJ9//lm33HKLoqOj1axZM1122WX67LPPKuxXmeLiYj344IOKi4tTRESEhg4dql9//bXCfvv27dPEiRPVsWPHGuMp79SpU4qOjtbYsWMrvJefn6/Q0FA9/PDDkqSSkhI99thjuvjii2W1WhUWFqa+fftq9erVDsfZvtPnnntOL730klJSUhQSEqKdO3dW+n1v375dY8aMUbt27RQaGqqEhATdfffdOnbsmH2fJUuWyGKxaO3atRXinD9/viwWi9LT0+3bdu3apZtvvlnR0dEKDQ3VJZdcon/+85/VfhdVqct3u337dl1xxRVq2rSpWrVqpSeeeEILFy6UxWKpsP8XX3yhvn37KiwsTBERERo8eLB27NjhVIyAxEgNUK0777xTjzzyiL788kuNGzeu0n127Nih66+/Xl27dtXs2bMVEhKijIwMrV+/XpJ0/vnna/bs2Xrsscc0fvx49e3bV5J0+eWX289x7NgxDRo0SCNHjtQdd9yh5s2bVxvXk08+KYvFoqlTpyonJ0cvvfSS+vfvr23bttlHlOpj+/bt6tu3r5o0aaLx48erbdu2yszM1LJly/Tkk09Kkr777jtt2LBBo0aNUqtWrZSVlaXXX39dqamp2rlzp5o1ayZJOnz4sC6//HKdPHlSDzzwgGJiYvTOO+9o6NChWrJkiYYPH15tLPfee68WLVqk2267TZdffrlWrVqlwYMHV9jv+++/1zfffKORI0eqVatW2rt3r+bNm1chnrM1adJEw4cP19KlSzV//nyH0bGPP/5YxcXFGjlypKQzSc6bb76pUaNGady4cSooKNCCBQs0YMAAbdy4scLU4sKFC1VUVKTx48crJCRE0dHRKisrqxDDihUrlJmZqbFjxyohIUHp6el64403tGPHDn377beyWCwaPHiwwsPD9cEHH+iKK65wOH7x4sW64IIL1LlzZ0lnfid79+6tli1batq0aQoLC9MHH3ygYcOG6R//+EeN37mz3+2BAwd05ZVXymKxaPr06QoLC9Obb76pkJCQCud89913NXr0aA0YMEDPPPOMTp48qXnz5qlPnz7aunWr2rZtW6cYAUmSARqwhQsXGknm+++/r3Ifq9VqunXrZn89c+ZMU/6vzosvvmgkmSNHjlR5ju+//95IMgsXLqzw3hVXXGEkmddff73S96644gr769WrVxtJpmXLliY/P9++/YMPPjCSzJ///Gf7tqSkJDN69Ogaz5mVlVUhtn79+pmIiAizb98+h2PLysrsfz558mSFc2/YsMFIMn/961/t2yZPnmwkmX/961/2bQUFBSY5Odm0bdvWlJaWVjiPzbZt24wkM3HiRIftt912m5FkZs6cWed4KrN8+XIjySxbtsxh+3XXXWfatWtnf3369GlTXFzssM9//vMf07x5c3P33Xfbt9m+08jISJOTk+Owf2Xf94kTJyrEtGjRIiPJrFu3zr5t1KhRJj4+3pw+fdq+LTs72wQFBZnZs2fbt1199dWmS5cupqioyL6trKzMXH755aZDhw72bbbfp9WrV1f11Rhjav/d3n///cZisZitW7fatx07dsxER0cbSSYrK8sYc+b+R0VFmXHjxjmc89ChQ8ZqtVbYDtQW009ADcLDw6t9CioqKkqS9Mknn1T6f+G1ERISUun0R1XuuusuRURE2F/ffPPNSkxM1Oeff+7U55d35MgRrVu3TnfffbfatGnj8F75abfyI0KnTp3SsWPH1L59e0VFRWnLli329z7//HP16NFDffr0sW8LDw/X+PHjtXfvXu3cubPKWGzX88ADDzhsnzx5coV9axtPZa666irFxsZq8eLF9m3/+c9/tGLFCo0YMcK+rVGjRvaRnLKyMuXm5ur06dO65JJLKv2Mm266qVa1RmFhYfY/G2NUVFSka6+9VpIczjtixAjl5OQ4PIK9ZMkSlZWV2ePMzc3VqlWrdOutt6qgoEBHjx7V0aNHdezYMQ0YMEB79uzRgQMHaoypvNp+t2lpaerVq5fDiFV0dLRuv/12h/OtWLFCx48f16hRo+zxHT16VI0aNVLPnj0rTOcBtUVSA9TgxIkTDgnE2UaMGKHevXvr3nvvVfPmzTVy5Eh98MEHdUpwWrZsWaei4A4dOji8tlgsat++fY31I7Xx888/S5J9KqMqv/32mx577DG1bt1aISEhio2NVVxcnI4fP668vDz7fvv27VPHjh0rHH/++efb36/Kvn37FBQUpJSUFIftlZ2vtvFUpnHjxrrpppv0ySefqLi4WJK0dOlSnTp1yiGpkaR33nlHXbt2VWhoqGJiYhQXF6fPPvus0s9ITk6u9nNt8vLyNH36dHtNTdOmTe09asqfd+DAgbJarQ7J1+LFi3XRRRfp3HPPlSRlZGTIGKMZM2YoLi7O4WfmzJmSVOemfnW51+3bt69w/Nnb9uzZI+lMMnl2jF9++SVNB+E0amqAavz666/Ky8ur9D/UNk2bNtW6deu0evVqffbZZ0pLS9PixYt11VVX6csvv1SjRo1q/BxX1MGcraoGgaWlpbWKqSb333+/Fi5cqMmTJ6tXr16yWq2yWCwaOXKk0yNW3oxn5MiRmj9/vr744gsNGzZMH3zwgc477zxdeOGF9n0WLVqkMWPGaNiwYfrDH/6g+Ph4NWrUSHPmzFFmZmaFc9b2vo4YMULr16/Xo48+qu7duys8PFylpaXq27evQ+whISEaNmyYPvroI/3lL3/R4cOHtX79ej311FP2fWz7P/zwwxowYECln1fd73NlXH2vbce8++67SkhIqPC+u58uRODiNweoxrvvvitJVf7jYBMUFKSrr75aV199tV544QU99dRT+tOf/qTVq1erf//+Lu9AbPs/XRtjjDIyMhz66Zxzzjk6fvx4hWP37dundu3aVXlu23vln6SpzJIlSzR69Gg9//zz9m1FRUUVPjMpKUm7d++ucPyuXbvs71clKSlJZWVlyszMdBidqex8tY2nKv369VNiYqIWL16sPn36aNWqVQ5Pe9k+o127dlq6dKnDPbWNgDjj+PHjWr58uZ544glNnTrVvv2nn36qdP8RI0bonXfe0cqVK/Xjjz/KGOMwmmS7f02aNFH//v2djqu8utzrjIyMCsefvc028hYfH++yGAGJ6SegSqtWrdL//u//Kjk5uUJNQHm5ubkVttlqCmxTGbaaidr+A1uTv/71rw51PkuWLFF2drYGDRpk35aSkqJvv/1WJSUl9m2ffvpphUe/zxYXF6d+/frprbfe0v79+x3eM8bY/9yoUSOH15L0yiuvqLS01GHbddddp40bN2rDhg32bYWFhXrjjTfUtm1bderUqcpYbNfz8ssvO2yvbCmG2sZTlaCgIN18881atmyZ3n33XZ0+fbrC1JNthKv859ieAnNWUNCZ/wyfOnXKYXv5BKK8/v37Kzo6WosXL9bixYvVo0cPh2mu+Ph4paamav78+crOzq5w/JEjR+ocY22/2wEDBmjDhg0OnbNzc3P13nvvVdgvMjJSTz31VIXrdjZGQGKkBpB0pl/Grl27dPr0aR0+fFirVq3SihUrlJSUpH/+85/VNqebPXu21q1bp8GDByspKUk5OTn6y1/+olatWtmLY1NSUhQVFaXXX39dERERCgsLU8+ePWtdc3G26Oho9enTR2PHjtXhw4f10ksvqX379g6Pnd97771asmSJBg4cqFtvvVWZmZlatGhRhfqUyrz88svq06ePunfvrvHjxys5OVl79+7VZ599Zv8H6/rrr9e7774rq9WqTp06acOGDfrqq68UExPjcK5p06bp/fff16BBg/TAAw8oOjpa77zzjrKysvSPf/zD/o96ZS666CKNGjVKf/nLX5SXl6fLL79cK1eurHQ0oLbxVGfEiBF65ZVXNHPmTHXp0sVe91P+M5YuXarhw4dr8ODB9sfYO3XqpBMnTtT6c8qLjIxUnz599Oyzz+r06dNq2bKlli9fXiGhtGnSpIluvPFG/f3vf1dhYaGee+65Cvu89tpr6tOnj7p06aJx48apXbt2Onz4sDZs2KBff/1V//73v+sUY22/2z/+8Y9atGiRrrnmGt1///32R7rbtGmj3Nxc++hWZGSk5s2bpzvvvFPdu3fXyJEjFRcXp/379+uzzz5T79699eqrr9YpRkASj3SjYbM90m37CQ4ONgkJCeaaa64xf/7znx0em7Y5+5HulStXmhtuuMG0aNHCBAcHmxYtWphRo0aZn376yeG4Tz75xHTq1Mk0btzY4ZHeK664wlxwwQWVxlfVI93vv/++mT59uomPjzdNmzY1gwcPrvD4tTHGPP/886Zly5YmJCTE9O7d22zatKlWj3QbY0x6eroZPny4iYyMNJJMx44dzYwZM+zv/+c//zFjx441sbGxJjw83AwYMMDs2rWr0kfJMzMzzc0332yioqJMaGio6dGjh/n0008rveaz/fbbb+aBBx4wMTExJiwszAwZMsT88ssvFR7prks8VSkrKzOtW7c2kswTTzxR6ftPPfWUSUpKMiEhIaZbt27m008/NaNHjzZJSUn2/Wzf6bPPPlvhHJV93/v37zfDhg0zVqvVREVFmZEjR5pDhw5VuEabFStWGEnGYrGYX375pdJryczMNHfddZdJSEgwTZo0MS1btjTXX3+9WbJkiX2f2j7SXZfvduvWraZv374mJCTEtGrVysyZM8e8/PLLRpI5dOiQw76rV682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rBo1alThiZfDhw8rISHBS1G5z3333adPP/1Uq1evVqtWrardt2fPnpKkjIwMT4TmEVFRUTr33HOVkZGhhIQElZSU6Pjx4w77BNq937dvn7766ivde++91e4XiPfbdh+r+/udkJBQ4aGA06dPKzc31+9/D2wJzb59+7RixQqHUZrK9OzZU6dPn9bevXs9E6AHtGvXTrGxsfbf60C+3zb/+te/tHv37hr/zku+ec9JauohODhYF198sVauXGnfVlZWppUrV6pXr15ejMy1jDG677779NFHH2nVqlVKTk6u8Zht27ZJkhITE90dnsecOHFCmZmZSkxM1MUXX6wmTZo43Pvdu3dr//79AXXvFy5cqPj4eA0ePLja/QLxficnJyshIcHhHufn5+u7776z3+NevXrp+PHj2rx5s32fVatWqayszJ7o+SNbQrNnzx599dVXiomJqfGYbdu2KSgoqML0jD/79ddfdezYMfvvdaDe7/IWLFigiy++WBdeeGGN+/rkPfd2pbK/+/vf/25CQkLM22+/bXbu3GnGjx9voqKizKFDh7wdmstMmDDBWK1Ws2bNGpOdnW3/OXnypDHGmIyMDDN79myzadMmk5WVZT755BPTrl07069fPy9HXj8PPfSQWbNmjcnKyjLr1683/fv3N7GxsSYnJ8cYY8zvfvc706ZNG7Nq1SqzadMm06tXL9OrVy8vR+06paWlpk2bNmbq1KkO2wPpfhcUFJitW7earVu3GknmhRdeMFu3brU/5fP000+bqKgo88knn5jt27ebG264wSQnJ5vffvvNfo6BAweabt26me+++858/fXXpkOHDmbUqFHeuqRaqe66S0pKzNChQ02rVq3Mtm3bHP7OFxcXG2OM+eabb8yLL75otm3bZjIzM82iRYtMXFycueuuu7x8ZdWr7roLCgrMww8/bDZs2GCysrLMV199Zbp37246dOhgioqK7Ofwx/ttTM2/68YYk5eXZ5o1a2bmzZtX4Xh/ueckNS7wyiuvmDZt2pjg4GDTo0cP8+2333o7JJeSVOnPwoULjTHG7N+/3/Tr189ER0ebkJAQ0759e/OHP/zB5OXleTfwehoxYoRJTEw0wcHBpmXLlmbEiBEmIyPD/v5vv/1mJk6caM455xzTrFkzM3z4cJOdne3FiF1r+fLlRpLZvXu3w/ZAut+rV6+u9Hd79OjRxpgzj3XPmDHDNG/e3ISEhJirr766wvdx7NgxM2rUKBMeHm4iIyPN2LFjTUFBgReupvaqu+6srKwq/86vXr3aGGPM5s2bTc+ePY3VajWhoaHm/PPPN0899ZTDP/6+qLrrPnnypLn22mtNXFycadKkiUlKSjLjxo2r8D+o/ni/jan5d90YY+bPn2+aNm1qjh8/XuF4f7nnFmOMcetQEAAAgAdQUwMAAAICSQ0AAAgIJDUAACAgkNQAAICAQFIDAAACAkkNAAAICCQ1AAAgIJDUAACAgEBSA8DrUlNTNXnyZKeP37t3rywWi30NKgANU2NvBwAAS5cuVZMmTbwdBgA/R1IDwOuio6O9HQKAAMD0EwCvKz/91LZtWz311FO6++67FRERoTZt2uiNN95w2H/jxo3q1q2bQkNDdckll2jr1q0Vzpmenq5BgwYpPDxczZs315133qmjWq2fIQAAAt1JREFUR49KktasWaPg4GD961//su8/d+5cxcfH6/Dhw268UgDuRFIDwOc8//zz9mRl4sSJmjBhgnbv3i1JOnHihK6//np16tRJmzdv1uOPP66HH37Y4fjjx4/rqquuUrdu3bRp0yalpaXp8OHDuvXWWyX9N4m68847lZeXp61bt2rGjBl688031bx5c49fLwDXYPoJgM+57rrrNHHiREnS1KlT9eKLL2r16tXq2LGj/va3v6msrEwLFixQaGioLrjgAv3666+aMGGC/fhXX31V3bp101NPPWXf9tZbb6l169b66aefdO655+qJJ57QihUrNH78eKWnp2v06NEaOnSox68VgOuQ1ADwOV27drX/2WKxKCEhQTk5OZKkH3/8UV27dlVoaKh9n169ejkc/+9//1urV69WeHh4hXNnZmbq3HPPVXBwsN577z117dpVSUlJevHFF910NQA8haQGgM85+0koi8WisrKyWh9/4sQJDRkyRM8880yF9xITE+1//uabbyRJubm5ys3NVVhYmJMRA/AF1NQA8Cvnn3++tm/frqKiIvu2b7/91mGf7t27a8eOHWrbtq3at2/v8GNLXDIzM/Xggw/q//7v/9SzZ0+NHj26TokTAN9DUgPAr9x2222yWCwaN26cdu7cqc8//1zPPfecwz6TJk1Sbm6uRo0ape+//16ZmZlavny5xo4dq9LSUpWWluqOO+7QgAEDNHbsWC1cuFDbt2/X888/76WrAuAKJDUA/Ep4eLiWLVumH374Qd26ddOf/vSnCtNMLVq00Pr161VaWqprr71WXbp00eTJkxUVFaWgoCA9+eST2rdvn+bPny/pzJTUG2+8oUcffVT//ve/vXFZAFzAYowx3g4CAACgvhipAQAAAYGkBgAABASSGgAAEBBIagAAQEAgqQEAAAGBpAYAAAQEkhoAABAQSGoAAEBAIKkBAAABgaQGAAAEBJIaAAAQEP4fMEKBRJwl9TYAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GIAYrDJyCT6r", + "outputId": "f90e17e3-b26f-49e1-8910-76461cb2d4fa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + } + }, + "source": [ + "sns.distplot(df_titanic_ss['age'])\n", + "plt.title(\"Distribuição da variável age\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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hT03RNRu9957b7MtKIjaUldX1+z7kpISbNiwAWPGjGFhQ12OPTdEdFNffvklampq8M0335jvu0J0IyNHjsSECRPQr18/FBQU4NNPP0VlZSVefPFFqaORHWBxQ0Q3debMGbz99tsIDAzEm2++KXUcsgGTJk3C5s2b8dFHH0EQBAwZMgSffvopxo0bJ3U0sgPsuSEiIiJZYc8NERERyQqLGyIiIpIVuytuRFFEZWVli7tsEhERkTzYXXFTVVUFrVbb7Jb1REREJB92V9wQERGRvLG4ISIiIllhcUNERESywuKGiIiIZIXFDREREckKixsiIiKSFRY3REREJCssboiIiEhWWNwQERGRrLC4ISIiIllhcUNERESywuKGiIiIZIXFDREREckKixsiIiKSFRY3REREJCssboiIiEhWWNwQERGRrKikDkBE8vPFwSzJrv3wiFDJrk1E1oEjN0RERCQrLG6IiIhIVljcEBERkaywuCEiIiJZYXFDREREssLihoiIiGSFxQ0RERHJCosbIiIikhUWN0RERCQrLG6IiIhIVljcEBERkaywuCEiIiJZYXFDREREssLihoiIiGSFxQ0RERHJCosbIiIikhUWN0RERCQrLG6IiIhIVljcEBERkaywuCEiIiJZYXFDREREssLihoiIiGSFxQ0RERHJilUUNx988AHCw8Ph6OiIESNGICUlpV3P++qrryAIAqZNm9bFCYmIiMhWSF7cbNq0CQsXLsTSpUtx9OhRDBo0CAkJCSgsLLzh8zIyMrBo0SKMHTu2m5ISERGRLZC8uFmxYgXmz5+PxMREREdHY/Xq1XB2dsaaNWvafI5er8fvfvc7vPzyy4iMjOzGtERERGTtJC1uGhsbceTIEcTHx5uPKRQKxMfHIzk5uc3nLVu2DH5+fnj00Udveo2GhgZUVlY2+yIiIiL5krS4KS4uhl6vh7+/f7Pj/v7+yM/Pb/U5+/btw6effoqPP/64XddYvnw5tFqt+SskJOSWcxMREZH1knxaqiOqqqrwyCOP4OOPP4aPj0+7nrN48WJUVFSYv7Kzs7s4JREREUlJJeXFfXx8oFQqUVBQ0Ox4QUEBAgICWpyfmpqKjIwM3HvvveZjBoMBAKBSqXDhwgVERUU1e45Go4FGo+mC9ERERGSNJB25UavVGDp0KJKSkszHDAYDkpKSMHLkyBbn9+3b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nXdNnz6dO+64g9TUVKqqqli0aBHr1q1j5cqVZkfzqoiIiMvmVP1nDqlX51p59bNY8p3s2rXLGDJkiBEbG2sEBQUZ6enpxoMPPmgUFRWZHc3rFixYYABX/OXvJk6ceMVxr1271uxoDW7OnDlGamqqYbfbjaysLOPzzz83O5JPrF279op/xhMnTjQ7mld93ff0ggULzI7mdffee6+RlpZm2O12o2XLlsbQoUONVatWmR3LFL74KLjm3IiIiIhfabqTGERERESuQOVGRERE/IrKjYiIiPgVlRsRERHxKyo3IiIi4ldUbkRERMSvqNyIiIiIX1G5EREREb+iciMiIiJ+ReVGRERE/IrKjYiIiPgVlRsRafRWrFjBjTfeSHR0NHFxcYwaNYqCgoL6xz/77DN69OhBcHAwffr0YdmyZVgslvod1QH27NnDHXfcQXh4OAkJCUyYMIHS0lIzhiMiXqZyIyKNntPpJDs7m23btrFmzRqsVit33XUXHo+HyspKRo8eTdeuXcnNzeWPf/wj06ZNu+T5Z8+e5dZbb6Vnz55s27aNFStWUFxczLhx40wakYh4k3YFF5Emp7S0lJYtW7J79242btzIE088QVFREcHBwQDMnz+fyZMns337dnr06MEzzzzDJ598wsqVK+u/RlFRESkpKeTn59OhQwezhiIiXqArNyLS6B08eJDx48eTkZFBZGQk6enpABQWFpKfn0+3bt3qiw1AVlbWJc/fuXMna9euJTw8vP5Xp06dAC65vSUi/iHA7AAiIlczevRo0tLSeP3110lOTsbj8ZCZmYnL5fpWz6+urmb06NE899xzlz2WlJTU0HFFxGQqNyLSqJ05c4b8/Hxef/11brrpJgA2btxY/3jHjh15++23qa2tJSgoCICtW7de8jV69erFkiVLSE9PJyBAP/ZE/J1uS4lIoxYTE0NcXByvvfYahw4d4uOPPyY7O7v+8bvvvhuPx8P999/P/v37WblyJbNmzQLAYrEAMGXKFMrKyhg/fjxbt26loKCAlStXMmnSJNxutynjEhHvUbkRkUbNarWyePFicnJyyMzM5Fe/+hXPP/98/eORkZF88MEH7Nixgx49evC73/2Op556CqB+Hk5ycjKffvopbreb4cOH07VrV6ZOnUp0dDRWq34MivgbfVpKRPzOwoULmTRpEhUVFYSEhJgdR0R8TDefRaTJ+/vf/05GRgatWrVi586dTJs2jXHjxqnYiDRTKjci0uQ5HA6eeuopHA4HSUlJjB07lmeffdbsWCJiEt2WEhEREb+imXQiIiLiV1RuRERExK+o3IiIiIhfUbkRERERv6JyIyIiIn5F5UZERET8isqNiIiI+BWVGxEREfEr/x/hnf3iy4mnnwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "USy48-H2UXqB", + "outputId": "e13e7d01-589f-4329-cc96-7f827adac029", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cálculo das medidas de Skewness e Kurtosis para 'age'\n", + "print(f\"Skewness: {df_titanic_ss['age'].skew()}\")\n", + "print(f\"Kurtosis: {df_titanic_ss['age'].kurt()}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Skewness: 0.01841894050949496\n", + "Kurtosis: -0.2309427735598728\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ENQaVw2lItVL" + }, + "source": [ + "Olhando para as medidas de Skewness e Kurtosis logo acima, qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nt0PQIjW-wXd" + }, + "source": [ + "___\n", + "## **Isolation Forest Region**\n", + "* Source: [Outlier Detection with Isolation Forest](https://towardsdatascience.com/outlier-detection-with-isolation-forest-3d190448d45e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tM6Xht76KmUN" + }, + "source": [ + "### Anomaly Detection para 'fare'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uFuAUh5S778M", + "outputId": "7f8311f9-cd4f-4ed0-baf3-9fe55200790c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 388 + } + }, + "source": [ + "isolation_forest = IsolationForest(n_estimators = 100)\n", + "isolation_forest.fit(df_titanic['fare'].values.reshape(-1, 1))\n", + "xx = np.linspace(df_titanic['fare'].min(), df_titanic['fare'].max(), len(df_titanic)).reshape(-1, 1)\n", + "anomaly_score = isolation_forest.decision_function(xx)\n", + "outlier = isolation_forest.predict(xx)\n", + "plt.figure(figsize = (10, 4))\n", + "plt.plot(xx, anomaly_score, label = 'anomaly score')\n", + "plt.fill_between(xx.T[0], np.min(anomaly_score), np.max(anomaly_score), where = outlier == -1, color = 'r', alpha = .4, label = 'outlier region')\n", + "plt.legend()\n", + "plt.ylabel('anomaly score')\n", + "plt.xlabel('fare')\n", + "plt.show();" + ], + "execution_count": 29, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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biAClJeX8+mnn2apKskV1dXVAFsdH5uPVVdXU1ZW1u64zWbD7/e3nSM9Rzqd5tJLL+XII49kwIABQOsYcDgcFBYWtjv3m+Nka+No8zHpGT788EOGDx9ONBolPz+fWbNmcfDBB7Ns2TKNEQHgySefZMmSJSxatOhbx/ReIgDDhg3j4Ycf5oADDmDDhg1cf/31HHXUUSxfvlxjZBOFLBGRHmby5MksX7683fp4kc0OOOAAli1bRnNzM88++ywTJ05k3rx52S5LcsTatWu55JJLmDNnDi6XK9vlSI467rjj2v48aNAghg0bxj777MPTTz+N2+3OYmW5Q8sFu4GSkhKsVuu3urLU1NRQUVGRpaokV2weA9sbHxUVFd9qkpJMJmloaNAY6mGmTJnCSy+9xOuvv07v3r3b7q+oqCAej9PU1NTu/G+Ok62No83HpGdwOBz079+fIUOGMH36dAYPHsyf//xnjREBWpd61dbWcthhh2Gz2bDZbMybN4+ZM2dis9koLy/XOJFvKSwsZP/99+fzzz/Xe8kmClndgMPhYMiQIbz22mtt96XTaV577TWGDx+excokF/Tt25eKiop246OlpYWFCxe2jY/hw4fT1NTE4sWL286ZO3cu6XSaYcOGdXnNknmmaTJlyhRmzZrF3Llz6du3b7vjQ4YMwW63txsnK1asYM2aNe3GyYcfftgukM+ZMwev18vBBx/cNS9Eulw6nSYWi2mMCAAjRozgww8/ZNmyZW23oUOHMmHChLY/a5zINwWDQVauXEllZaXeSzbLducN2TlPPvmk6XQ6zYcfftj8+OOPzUmTJpmFhYXturJIzxUIBMylS5eaS5cuNQHzlltuMZcuXWp++eWXpmma5owZM8zCwkLz73//u/nBBx+YJ510ktm3b18zEom0PceYMWPMQw891Fy4cKH55ptvmvvtt585fvz4bL0kybALL7zQ9Pl85htvvGFu2LCh7RYOh9vOueCCC8y9997bnDt3rvnee++Zw4cPN4cPH952PJlMmgMGDDBHjRplLlu2zHzllVfM0tJS88orr8zGS5JOMG3aNHPevHnmqlWrzA8++MCcNm2aaRiG+eqrr5qmqTEiW7dld0HT1DgR05w6dar5xhtvmKtWrTLfeustc+TIkWZJSYlZW1trmqbGiGmapkJWN3L77bebe++9t+lwOMzDDz/cfOedd7JdknSR119/3QS+dZs4caJpmq1t3K+++mqzvLzcdDqd5ogRI8wVK1a0e476+npz/PjxZn5+vun1es2zzjrLDAQCWXg10hm2Nj4A86GHHmo7JxKJmL/61a/MoqIi0+PxmCeffLK5YcOGds+zevVq87jjjjPdbrdZUlJiTp061UwkEl38aqSznH322eY+++xjOhwOs7S01BwxYkRbwDJNjRHZum+GLI0TOfXUU83KykrT4XCYvXr1Mk899VTz888/bzuuMWKahmmaZnbm0ERERERERHoeXZMlIiIiIiKSQQpZIiIiIiIiGaSQJSIiIiIikkEKWSIiIiIiIhmkkCUiIiIiIpJBClkiIiIiIiIZpJAlIiIiIiKSQQpZIiKyRzJNk0mTJuH3+zEMg2XLlmW7JBER6SG0GbGIiOyRZs+ezUknncQbb7xBv379KCkpwWazZbssERHpAfS/iYiI7JFWrlxJZWUlRxxxxC4/RyKRwG63Z7AqERHpCbRcUERE9jhnnnkmF110EWvWrMEwDPr06cMrr7zC97//fQoLCykuLuaEE05g5cqVbY9ZvXo1hmHw1FNPccwxx+ByuXjssccAeOCBBzjooINwuVwceOCB3HXXXdl6aSIikgO0XFBERPY4zc3NzJw5k/vuu49FixZhtVqZP38+hmEwaNAggsEg11xzDatXr2bZsmVYLBZWr15N37596dOnD3/605849NBDcblczJ07lyuuuII77riDQw89lKVLl3Leeedxyy23MHHixGy/VBERyQItFxQRkT2Oz+ejoKAAq9VKRUUFAOPGjWt3zl/+8hdKS0v5+OOPGTBgQNv9l156Kaecckrb19deey1/+tOf2u7r27cvH3/8Mffee69ClojIHkrLBUVERIDPPvuM8ePH069fP7xeL3369AFgzZo17c4bOnRo259DoRArV67knHPOIT8/v+12ww03tFtqKCIiexbNZImIiAA//vGP2Weffbj//vupqqoinU4zYMAA4vF4u/Py8vLa/hwMBgG4//77GTZsWLvzrFZr5xctIiI5SSFLRET2ePX19axYsYL777+fo446CoA333xzh48rLy+nqqqKL774ggkTJnR2mSIi0k0oZImIyB6vqKiI4uJi7rvvPiorK1mzZg3Tpk3bqcdef/31XHzxxfh8PsaMGUMsFuO9996jsbGRyy+/vJMrFxGRXKRrskREZI9nsVh48sknWbx4MQMGDOCyyy7jpptu2qnHnnvuuTzwwAM89NBDDBw4kGOOOYaHH36Yvn37dnLVIiKSq9TCXUREREREJIM0kyUiIiIiIpJBClkiIiIiIiIZpJAlIiIiIiKSQQpZIiIiIiIiGaSQJSIiIiIikkEKWSIiIiIiIhmkkCUiIiIiIpJBClkiIiIiIiIZpJAlIiIiIiKSQQpZIiIiIiIiGaSQJSIiIiIikkEKWSIiIiIiIhn0/zy1URXuCBToAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FkhRwo1cgYtK", + "outputId": "771f93e4-9d22-41cf-d6f0-6ee611326a47", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# Vamos avaliar os dados do dataframe para fare > 200, por exemplo\n", + "df_titanic.loc[df_titanic['fare'] > 200].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
2701male19.032263.0000SFirstmanTrueCSouthamptonnoFalse
8811female23.032263.0000SFirstwomanFalseCSouthamptonyesFalse
11801male24.001247.5208CFirstmanTrueBCherbourgnoFalse
29911female50.001247.5208CFirstwomanFalseBCherbourgyesFalse
31111female18.022262.3750CFirstwomanFalseBCherbourgyesFalse
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "27 0 1 male 19.0 ... C Southampton no False\n", + "88 1 1 female 23.0 ... C Southampton yes False\n", + "118 0 1 male 24.0 ... B Cherbourg no False\n", + "299 1 1 female 50.0 ... B Cherbourg yes False\n", + "311 1 1 female 18.0 ... B Cherbourg yes False\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XFbRlmrYgtTS", + "outputId": "c59e564a-392c-4d63-8743-08f9ca4300b2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 27\n", + "df_titanic.loc[27]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 0\n", + "pclass 1\n", + "sex male\n", + "age 19\n", + "sibsp 3\n", + "parch 2\n", + "fare 263\n", + "embarked S\n", + "class First\n", + "who man\n", + "adult_male True\n", + "deck C\n", + "embark_town Southampton\n", + "alive no\n", + "alone False\n", + "Name: 27, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bH4o-CL-N9Np" + }, + "source": [ + "A região onde os dados têm baixa probabilidade de aparecer fica no lado direito da distribuição." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7HK9cBvwGOqG" + }, + "source": [ + "### Anomaly Detection para 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PoDzs4DTFSY-", + "outputId": "21bdf5d8-71fd-449f-d644-2f8ef94c2605", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 388 + } + }, + "source": [ + "isolation_forest = IsolationForest(n_estimators = 100)\n", + "isolation_forest.fit(df_titanic['age'].values.reshape(-1, 1))\n", + "xx = np.linspace(df_titanic['age'].min(), df_titanic['age'].max(), len(df_titanic)).reshape(-1, 1)\n", + "anomaly_score = isolation_forest.decision_function(xx)\n", + "outlier = isolation_forest.predict(xx)\n", + "plt.figure(figsize = (10, 4))\n", + "plt.plot(xx, anomaly_score, label='anomaly score')\n", + "plt.fill_between(xx.T[0], np.min(anomaly_score), np.max(anomaly_score), where = outlier == -1, color = 'r', alpha = .4, label = 'outlier region')\n", + "plt.legend()\n", + "plt.ylabel('anomaly score')\n", + "plt.xlabel('age')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GivF2cSFS208" + }, + "source": [ + "Observe no gráfico acima que há duas regiões em que os dados têm baixa probabilidade de aparecer: uma no lado esquerdo da distribuição, outra no lado direito da distribuição." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XtizVySOlPUT", + "outputId": "0b387228-ac36-4617-9e06-a231e7b0fbdf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# Avaliando os dados da cauda esquerda\n", + "df_titanic.loc[df_titanic['age'] < 15].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
1013female4.01116.7000SThirdchildFalseGSouthamptonyesFalse
18312male1.02139.0000SSecondchildFalseFSouthamptonyesFalse
19312male3.01126.0000SSecondchildFalseFSouthamptonyesFalse
20503female2.00110.4625SThirdchildFalseGSouthamptonnoFalse
29701female2.012151.5500SFirstchildFalseCSouthamptonnoFalse
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "10 1 3 female 4.0 ... G Southampton yes False\n", + "183 1 2 male 1.0 ... F Southampton yes False\n", + "193 1 2 male 3.0 ... F Southampton yes False\n", + "205 0 3 female 2.0 ... G Southampton no False\n", + "297 0 1 female 2.0 ... C Southampton no False\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YGnZlzDDlyZO", + "outputId": "d5e0eb2c-2637-4021-f6e7-885b3e74161d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 3\n", + "df_titanic.loc[10]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 1\n", + "pclass 3\n", + "sex female\n", + "age 4\n", + "sibsp 1\n", + "parch 1\n", + "fare 16.7\n", + "embarked S\n", + "class Third\n", + "who child\n", + "adult_male False\n", + "deck G\n", + "embark_town Southampton\n", + "alive yes\n", + "alone False\n", + "Name: 10, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YVhBJua_sG-u", + "outputId": "2b9f3aad-9f81-41e6-882d-cf5b3c0a0d02", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 136 + } + }, + "source": [ + "# Avaliando dados da cauda direita\n", + "df_titanic.loc[df_titanic['age'] > 65].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
9601male71.00034.6542CFirstmanTrueACherbourgnoTrue
63011male80.00030.0000SFirstmanTrueASouthamptonyesTrue
74501male70.01171.0000SFirstmanTrueBSouthamptonnoFalse
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... deck embark_town alive alone\n", + "96 0 1 male 71.0 ... A Cherbourg no True\n", + "630 1 1 male 80.0 ... A Southampton yes True\n", + "745 0 1 male 70.0 ... B Southampton no False\n", + "\n", + "[3 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LRkUWSletcq-", + "outputId": "6fb001bd-c1d8-407b-ffd3-15ea7405dda0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 96\n", + "df_titanic.loc[96]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 0\n", + "pclass 1\n", + "sex male\n", + "age 71\n", + "sibsp 0\n", + "parch 0\n", + "fare 34.6542\n", + "embarked C\n", + "class First\n", + "who man\n", + "adult_male True\n", + "deck A\n", + "embark_town Cherbourg\n", + "alive no\n", + "alone True\n", + "Name: 96, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JQKECo0BSefE", + "outputId": "46a0911a-3cf8-43d1-8232-f05c710e54dc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 454 + } + }, + "source": [ + "sns.regplot(x = \"age\", y = \"fare\", data = df_titanic_ss)\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AChZpGY4Ghc9", + "outputId": "eed40cf6-a0e9-438c-e674-4bac462b872f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "cols = ['fare', 'age']\n", + "df_titanic_ss[cols].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
fareage
1-0.1001100.152082
3-0.338485-0.039875
6-0.3547081.175852
10-0.815672-2.023430
11-0.6865431.431795
\n", + "
" + ], + "text/plain": [ + " fare age\n", + "1 -0.100110 0.152082\n", + "3 -0.338485 -0.039875\n", + "6 -0.354708 1.175852\n", + "10 -0.815672 -2.023430\n", + "11 -0.686543 1.431795" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s2tddgHcUiAF" + }, + "source": [ + "___\n", + "## **CBLOF - Cluster-based Local Outlier Factor**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbJ7k1bbbfr4" + }, + "source": [ + "# Normalizar as variáveis 'age' e 'fare'\n", + "df_titanic_ss = df_titanic.copy()\n", + "df_titanic_ss[['fare', 'age']] = MinMaxScaler().fit_transform(df_titanic_ss[['fare', 'age']])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "il0LFdCFJEsw" + }, + "source": [ + "X1 = df_titanic_ss['age'].values.reshape(-1, 1)\n", + "X2 = df_titanic_ss['fare'].values.reshape(-1, 1)\n", + "X = np.concatenate((X1,X2), axis = 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QtBn0u7CKlS6", + "outputId": "16701bb5-dcf1-4335-878b-545575f79f73", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 755 + } + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = CBLOF(contamination = outliers_fraction, check_estimator = False, random_state = 0)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "\n", + "plt.figure(figsize = (8, 8))\n", + "\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + "\n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS:',n_outliers,'INLIERS:',n_inliers)\n", + " \n", + "# Use threshold para definir um ponto como inlier ou outlier\n", + "# threshold = stats.scoreatpercentile(scores_pred,100 * outliers_fraction)\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# Calcula o Anomaly Score\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "\n", + "plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 7), cmap = plt.cm.Blues_r)\n", + " \n", + "# Desenha a linha vermelha a partir do qual Anomaly Score = thresold\n", + "a = plt.contour(xx, yy, Z, levels = [threshold], linewidths = 2, colors = 'red')\n", + " \n", + "# Região Azul onde threshold < Anomaly Score < max(Anomaly score)\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()], colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c = 'white', s = 20, edgecolor = 'k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c = 'black', s = 20, edgecolor = 'k')\n", + " \n", + "plt.axis('tight') \n", + "plt.legend([a.collections[0], b, c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop = matplotlib.font_manager.FontProperties(size = 10), loc = 'upper center', frameon = False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Cluster-based Local Outlier Factor (CBLOF)')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "OUTLIERS: 2 INLIERS: 180\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqoAAALRCAYAAACTYIFoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdd3xT9f7H8VdSuii0UCgUkD2UKYqKzIIoiAy3ArUMwXGRoV714gRx/RQFZInrgt5et96ryJQh4L6KiAMtlFZwALLKKNB1fn+EpA1dSZvknKTv5+PRB+TkJPmmSZt3P+f7/RybYRgGIiIiIiIWYzd7ACIiIiIiJVFQFRERERFLUlAVEREREUtSUBURERERS1JQFRERERFLUlAVEREREUtSUBURERERS1JQFRERERFLUlAVEREREUtSUJUqp1mzZowePdrsYfjM6NGjqVGjhtnD8JrNZmPatGlmD6PC+vTpQ58+fcweRqlOf59//PHH2Gw2Pv74Y9PGFGreeust4uPjOXr0qNlD8avc3FwaN27MggULzB6KVEEKqhIy0tPTueWWW2jRogVRUVHExsbSo0cPnn32WY4fPx6QMWRnZzNt2jSFAR/JzMzEZrPx9NNPmz2USsnNzWXOnDmcf/751KxZkxo1anD++eczZ84ccnNzK3y/n332GdOmTePQoUM+HG3lOUNxSV/Dhg3z6WOZ9TOXn5/P1KlTmThxYrE/FPPz81m0aBF9+vQhPj6eyMhImjVrxpgxY/j6669d+y1evLjY96devXr07duX5cuXF3tMm83GhAkTyh3bjz/+yA033ECjRo2IjIykYcOGJCcn8+OPPxbbt6QxOL+mTJkCQHh4OHfeeSePPfYYJ06c8PZbJVIp1cwegIgvLF26lGuvvZbIyEhGjhxJhw4dyMnJ4ZNPPuHuu+/mxx9/5IUXXvD7OLKzs3n44YcBLF1tk8A5duwYgwYNYv369QwePJjRo0djt9tZsWIFkydP5r333mPp0qXExMR4fd+fffYZDz/8MKNHj6ZWrVpl7tu7d2+OHz9ORERERZ+K1yZNmsT555/vtq1Zs2Y+fQyzfuaWLFnCL7/8ws033+y2/fjx41x11VWsWLGC3r17c9999xEfH09mZiZvvfUWr7zyCjt37uSMM85w3Wb69Ok0b94cwzDYs2cPixcv5rLLLmPJkiUMHjzYq3G99957DB8+nPj4eMaOHUvz5s3JzMzk5Zdf5p133uGNN97gyiuvLHY75xiK6tChg+v/Y8aMYcqUKbz22mvceOONXo1JpDIUVCXoZWRkMGzYMJo2bcratWtp0KCB67rbbruN7du3s3TpUhNHWHnHjh2rUJAR8915552sX7+euXPnulXD/va3vzF//nwmTJjAXXfdxXPPPefXcdjtdqKionx2f568J3v16sU111zjs8cMpPKe36JFi+jRoweNGjVy23733XezYsUKZs2axe233+523dSpU5k1a1ax+xo4cCDnnXee6/LYsWOpX78+r7/+uldBNT09nZSUFFq0aMGGDRtISEhwXTd58mR69epFSkoKW7ZsoUWLFmWO4XS1atWif//+LF68WEFVAkqH/iXoPfXUUxw9epSXX37ZLaQ6tWrVismTJ5d6+2nTpmGz2Yptdx4Sy8zMdG37+uuvGTBgAHXr1iU6OprmzZu7fmlnZma6Phgefvhh1+GzovMwf/75Z6655hri4+OJiorivPPO44MPPijxcdevX8/48eOpV6+eW/WlNDt27GDAgAHExMTQsGFDpk+fjmEYbvs8/fTTdO/enTp16hAdHU2XLl145513it3XRx99RM+ePalVqxY1atTgzDPP5L777nPb5+TJk0ydOpVWrVoRGRlJ48aNueeeezh58mSx/e644w4SEhKoWbMmQ4cO5bfffiv3+Xhj7969rg/3qKgozj77bF555ZVi+xUUFPDss8/SsWNHoqKiSEhI4NJLL3U7HLto0SIuuugi6tWrR2RkJO3atatwiPztt994+eWXueiii0o8ZHvbbbfRt29fXnrpJdf3xDndYfHixcX2L/p+mjZtGnfffTcAzZs3d73fir5fiyptjuqXX37JpZdeSlxcHNWrVycpKYlPP/3UbR/nz8hPP/3EiBEjqF27Nj179vTum1HEgQMHuOuuu+jYsSM1atQgNjaWgQMH8t133xXb98SJE0ybNo02bdoQFRVFgwYNuOqqq0hPT/foZ27t2rX06tWLmJgYatWqxeWXX87WrVsr9fxOnDjBihUruPjii922//bbbzz//PNccsklxUIqQFhYGHfddVe5P8+1atUiOjqaatW8qyXNmDGD7OxsXnjhBbeQClC3bl2ef/55jh07xlNPPeXV/TpdcsklfPLJJxw4cKBCtxepCFVUJegtWbKEFi1a0L17d78+zt69e+nfvz8JCQlMmTKFWrVqkZmZyXvvvQdAQkICzz33HH/729+48sorueqqqwDo1KkT4Jg35qzATJkyhZiYGN566y2uuOIK3n333WKH48aPH09CQgIPPfQQx44dK3Ns+fn5XHrppVx44YU89dRTrFixgqlTp5KXl8f06dNd+z377LMMHTqU5ORkcnJyeOONN7j22mv58MMPGTRokGucgwcPplOnTkyfPp3IyEi2b9/uFl4KCgoYOnQon3zyCTfffDNt27bl+++/Z9asWaSlpfHf//7Xte+4ceNITU1lxIgRdO/enbVr17oeyxeOHz9Onz592L59OxMmTKB58+a8/fbbjB49mkOHDrn9kTJ27FgWL17MwIEDGTduHHl5eWzcuJEvvvjCVU167rnnaN++PUOHDqVatWosWbKE8ePHU1BQwG233ebV2JYvX05+fj4jR44sdZ+RI0eybt06VqxYwbhx4zy+76uuuoq0tDRef/11Zs2aRd26dQGKBZSyrF27loEDB9KlSxemTp2K3W53BfWNGzdywQUXuO1/7bXX0rp1ax5//PFifwSV5MiRI+zbt89tW3x8PDt27OC///0v1157Lc2bN2fPnj08//zzJCUl8dNPP9GwYUPA8b4ePHgwa9asYdiwYUyePJkjR47w0Ucf8cMPP3DxxReX+TO3evVqBg4cSIsWLZg2bRrHjx9n7ty59OjRg02bNhWbhuDp8/vmm2/Iycnh3HPPddu+fPly8vLySElJKfd7U1RWVhb79u3DMAz27t3L3LlzOXr0KDfccINX97NkyRKaNWtGr169Sry+d+/eNGvWrMQjTM4xFOV8Tzl16dIFwzD47LPPvJ6SIFJhhkgQy8rKMgDj8ssv9/g2TZs2NUaNGuW6PHXqVKOkH4VFixYZgJGRkWEYhmH85z//MQDjf//7X6n3/ddffxmAMXXq1GLX9evXz+jYsaNx4sQJ17aCggKje/fuRuvWrYs9bs+ePY28vLxyn8+oUaMMwJg4caLb/Q4aNMiIiIgw/vrrL9f27Oxst9vm5OQYHTp0MC666CLXtlmzZhmA2+1O969//cuw2+3Gxo0b3bYvXLjQAIxPP/3UMAzD2Lx5swEY48ePd9tvxIgRpX6fisrIyDAAY8aMGaXuM3v2bAMwUlNT3Z5Xt27djBo1ahiHDx82DMMw1q5dawDGpEmTit1HQUGB6/+nf48MwzAGDBhgtGjRwm1bUlKSkZSUVOb4b7/9dgMwvv3221L32bRpkwEYd955p2EYhc950aJFxfY9/Xs2Y8YMt/doUae/z9etW2cAxrp16wzDcDzn1q1bGwMGDCj2/Js3b25ccsklrm3On5Hhw4eX+XxPf6ySvjIyMowTJ04Y+fn5brfJyMgwIiMjjenTp7u2/fOf/zQAY+bMmcUewznmsn7mOnfubNSrV8/Yv3+/a9t3331n2O12Y+TIkRV+fi+99JIBGN9//73b9jvuuKPc17so58/66V+RkZHG4sWLi+0PGLfddluJ93Xo0CGPfhcOHTrUAFw/F6WNoaTfiX/88YcBGE8++aRHz0/EF3ToX4La4cOHAahZs6bfH8u5WOXDDz/0eqX2gQMHWLt2Ldddd52ryrRv3z7279/PgAED2LZtG7///rvbbW666SbCwsI8foyih5adq4NzcnJYvXq1a3t0dLTr/wcPHiQrK4tevXqxadOmYs/z/fffp6CgoMTHevvtt2nbti1nnXWW67ns27ePiy66CIB169YBsGzZMsCxqKaokg6LVtSyZctITExk+PDhrm3h4eFMmjSJo0ePsn79egDeffddbDYbU6dOLXYfRad+FP0eOatMSUlJ7Nixg6ysLK/GduTIEaDs96fzOud7OVA2b97Mtm3bGDFiBPv373e9hseOHaNfv35s2LCh2Ot/6623evUYDz30EB999JHbV2JiIpGRkdjtjo+f/Px89u/f75piUvS9+O6771K3bl0mTpxY7L5Lmq5T1J9//snmzZsZPXo08fHxru2dOnXikksucb03K/L89u/fD0Dt2rXdtlf099H8+fNd35/U1FT69u3LuHHjXEdrPOHJe63o9ae/34qOwfl1OufzPb3yKuJPOvQvQS02NhYo/CXtT0lJSVx99dU8/PDDzJo1iz59+nDFFVcwYsQIIiMjy7zt9u3bMQyDBx98kAcffLDEffbu3eu2MKPoCtycnJxi88ISEhJcQdZutxdbHNGmTRsAtzmLH374IY8++iibN292m0ta9EP/+uuv56WXXmLcuHFMmTKFfv36cdVVV3HNNde4wsW2bdvYunVrqYeZ9+7dC8Cvv/6K3W6nZcuWbtefeeaZJd6uIn799Vdat27tGptT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IvXq1SvxDwxPzJo1i59//pnx48ezYsUKV+V05cqVvP/++yQlJfHMM8+43WbcuHH83//9H+PGjeO8885jw4YNrgp5UV26dAHg/vvvZ9iwYYSHhzNkyBCPKoV2u52XXnqJgQMH0r59e8aMGUOjRo34/fffWbduHbGxsSxZsqRCz7k8gwcPZvr06YwZM4bu3bvz/fff8+9//7vYPOuRI0fy6quvcuedd/LVV1/Rq1cvjh07xurVqxk/fjyXX355mT9zM2bMYODAgXTr1o2xY8e62lPFxcW59Vr1VlRUFP3792f16tVu7d8AnnnmGdLT05k0aRLvvfcegwcPpnbt2uzcuZO3336bn3/+udhpZJcvX+46ArB3715ee+01tm3bxpQpU4odov/666959NFHi42pT58+9OzZk1deeYXk5GQ6duxY7MxU+/bt4/XXXy82Z9xTH330ET169HCbRyzid2a1GxDxtbS0NOOmm24ymjVrZkRERBg1a9Y0evToYcydO9etJdTpbXsMwzC++eYbo2vXrkZERITRpEkTY+bMmcXaU23atMkYPny40aRJEyMyMtKoV6+eMXjwYOPrr792u6/PPvvM6NKlixEREVGsbU56eroxcuRIIzEx0QgPDzcaNWpkDB482HjnnXdc+zgft6w2WEWNGjXKiImJMdLT043+/fsb1atXN+rXr29MnTq1WAugl19+2WjdurURGRlpnHXWWcaiRYuKtedas2aNcfnllxsNGzY0IiIijIYNGxrDhw830tLS3O4rJyfHePLJJ4327dsbkZGRRu3atY0uXboYDz/8sJGVleXa7/jx48akSZOMOnXqGDExMcaQIUOMXbt2edWeqrSvf/3rX4ZhGMaePXuMMWPGGHXr1jUiIiKMjh07ltjeKS8vz5gxY4Zx1llnGREREUZCQoIxcOBA45tvvnHt88EHHxidOnUyoqKijGbNmhlPPvmkq01S0TZQnrSncjp58qQxa9Yso0uXLkZMTIxRvXp149xzzzVmz55t5OTkFNs/OzvbGDt2rBEXF2fUrFnTuO6664y9e/eW+D175JFHjEaNGhl2u91tjOW1p3L69ttvjauuusqoU6eOERkZaTRt2tS47rrrjDVr1rj2cb5HympZVpTzsd5+++0Srz9x4oTx97//3WjQoIERHR1t9OjRw/j8889L/J5mZ2cb999/v9G8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eoDk5uZyvgOE8x0snO9g4XwHSyiUvvkWKa0pKytLgwYN0ooVKxqXRSIRrVixQsOGDYv7nmHDhjV7vSQtX7681dcDAAAAUjviqaZPn67x48dr8ODBGjJkiB599FEdOHBAEyZMkCRde+21OuWUUzRnzhxJ0k033aSysjL95Cc/0RVXXKElS5boL3/5i5544on07gkAAAB8JfPuu+++O5U3nH322crPz9d9992nhx9+WJL0zDPP6PTTT5cUjaPq1KmTrrrqKklScXGxBgwYoLlz5+qBBx5QTU2NnnzySQ0fPjy1QjMzdckll6hTJyMfq0Wacb6DhfMdLJzvYOF8B0u6z7cnPkIVAAAAwUO6OAAAAIxEowoAAAAj0agCAADASDSqAAAAMJIxjer8+fPVp08f5eTkaOjQoXrnnXfafP3zzz+vM844Qzk5ORo4cKCWLVvmUKVIh1TO96JFi3TxxReroKBABQUFGjlyZMLrA2ZJ9fc7ZsmSJcrIyGhMEYE3pHq+9+zZo8mTJ6t3797Kzs5W//79+W+6h6R6vh999FGdfvrp6tKli4qLi3XzzTfr0KFDDlWL9lq1apWuvPJKnXzyycrIyNCLL76Y8D0rV67U+eefr+zsbPXr109PPfVU6htO24exdsCSJUusrKwsa/HixdZf//pXa+LEiVZ+fr5VU1MT9/VvvfWWlZmZaT300EPWBx98YP3oRz+yOnfubG3YsMHhytEeqZ7va665xpo/f761bt06a+PGjdZ1111n5eXlWX//+98drhztker5jtm6dat1yimnWBdffLH1jW98w6Fq0VGpnu+6ujpr8ODB1pgxY6w333zT2rp1q7Vy5Upr/fr1DleO9kj1fD/zzDNWdna29cwzz1hbt261XnnlFat3797WzTff7HDlSNWyZcusO+64w/rtb39rSbJ+97vftfn6jz/+2Oratas1ffp064MPPrDmzZtnZWZmWi+//HJK2zWiUR0yZIg1efLkxu8bGhqsk08+2ZozZ07c11999dXWFVdc0WzZ0KFDre9973u21on0SPV8t3TkyBGrR48e1tNPP21XiUij9pzvI0eOWBdddJH1i1/8who/fjyNqoeker4XLFhgnXbaaVZ9fb1TJSKNUj3fkydPti677LJmy6ZPn24NHz7c1jqRXsk0qrfeeqt11llnNVs2duxYa/To0Slty/Vb//X19Xr33Xc1cuTIxmWhUEgjR47U6tWr475n9erVzV4vSaNHj2719TBHe853SwcPHtThw4d1wgkn2FUm0qS95/uee+5Rr169dP311ztRJtKkPef7v//7vzVs2DBNnjxZhYWFOvvss3X//feroaHBqbLRTu053xdddJHefffdxscDPv74Yy1btkxjxoxxpGY4J129musfE/HZZ5+poaFBhYWFzZYXFhbqww8/jPue6urquK+vrq62rU6kR3vOd0u33XabTj755ON+AWCe9pzvN998U08++aTWr1/vRIlIo/ac748//livvfaaysvLtWzZMm3evFk33nijDh8+rFmzZjlRNtqpPef7mmuu0WeffaYvfelLsixLR44c0fe//3398Ic/dKJkOKi1Xq22tlaff/65unTpktR6XB9RBVLxwAMPaMmSJfrd736nnJwct8tBmu3bt08VFRVatGiRevbs6XY5cEAkElGvXr30xBNPaNCgQRo7dqzuuOMOLVy40O3SYIOVK1fq/vvv189+9jO99957+u1vf6ulS5fq3nvvdbs0GMr1EdWePXsqMzNTNTU1zZbX1NSoqKgo7nuKiopSej3M0Z7zHfPwww/rgQce0J/+9Cedc845dpaJNEn1fG/ZskXbtm3TlVde2bgsEolIkjp16qSPPvpIffv2tbdotFt7fr979+6tzp07KzMzs3HZgAEDVF1drfr6emVlZdlaM9qvPef7zjvvVEVFhb773e9KkgYOHKgDBw7ohhtu0B133KFQiPEzv2itV8vNzU16NFUyYEQ1KytLgwYN0ooVKxqXRSIRrVixQsOGDYv7nmHDhjV7vSQtX7681dfDHO0535L00EMP6d5779XLL7+swYMHO1Eq0iDV833GGWdow4YNWr9+fePX17/+dV166aVav369iouLnSwfKWrP7/fw4cO1efPmxn+QSFJVVZV69+5Nk2q49pzvgwcPHteMxv6REp2jA79IW6+W4kQvWyxZssTKzs62nnrqKeuDDz6wbrjhBis/P9+qrq62LMuyKioqrNtvv73x9W+99ZbVqVMn6+GHH7Y2btxozZo1i3gqD0n1fD/wwANWVlaW9cILL1g7duxo/Nq3b59bu4AUpHq+W2LWv7eker63b99u9ejRw5oyZYr10UcfWX/4wx+sXr16WT/+8Y/d2gWkINXzPWvWLKtHjx7W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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O7NmDgjRm5EE", + "outputId": "0d0379c1-b9ce-4aed-bf59-feb9e9d99091", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneoutlier
67911male0.443601011.0CFirstmanTrueBCherbourgyesFalse1
73711male0.430956001.0CFirstmanTrueBCherbourgyesTrue1
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... embark_town alive alone outlier\n", + "679 1 1 male 0.443601 ... Cherbourg yes False 1\n", + "737 1 1 male 0.430956 ... Cherbourg yes True 1\n", + "\n", + "[2 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HIRxOj93nVXu", + "outputId": "8b95aa23-b3f7-4ed6-83bd-31e971b6fa62", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 1\n", + "pclass 1\n", + "sex male\n", + "age 36\n", + "sibsp 0\n", + "parch 1\n", + "fare 512.329\n", + "embarked C\n", + "class First\n", + "who man\n", + "adult_male True\n", + "deck B\n", + "embark_town Cherbourg\n", + "alive yes\n", + "alone False\n", + "Name: 679, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 32 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "euxK-4K1oKs0", + "outputId": "24a8459e-163d-497c-ba60-b48a792bfff6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
agefare
meanmean
sex
female33.089.0
male38.069.0
\n", + "
" + ], + "text/plain": [ + " age fare\n", + " mean mean\n", + "sex \n", + "female 33.0 89.0\n", + "male 38.0 69.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nuNxqgWMtMHC", + "outputId": "d9f8600f-c28d-4c63-9a14-4045efd4dc1d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "36" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bLIZcvyuuU2R", + "outputId": "772602e6-5c1a-4a83-cb88-857a9b905fba", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "79" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fFd-D1HTVhE7" + }, + "source": [ + "___\n", + "## **HBOS - Histogram-based Outlier Detection**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q5Hh5iMEXuhM", + "outputId": "8ac4d33b-c4bd-4b03-e7ae-af052af8b2a7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 755 + } + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = HBOS(contamination = outliers_fraction)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1, 1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1, 1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1, 1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1, 1)\n", + " \n", + "print('OUTLIERS:', n_outliers, 'INLIERS:', n_inliers)\n", + " \n", + "# threshold define se um ponto será outlier ou inlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# Calcula o Anomaly score\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "\n", + "# Define a região azul tal que min(Anomaly score) < threshold\n", + "plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 7), cmap = plt.cm.Blues_r)\n", + " \n", + "# Desenha a linha a partir do queal Anomaly score = thresold\n", + "a = plt.contour(xx, yy, Z, levels = [threshold], linewidths = 2, colors = 'red')\n", + " \n", + "# Define a região laranja a partir do qual threshold < Anomaly score < max(Anomaly score)\n", + "plt.contourf(xx, yy, Z, levels = [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight') \n", + " \n", + "plt.legend([a.collections[0], b, c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size = 10), loc ='upper center', frameon = False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Histogram-base Outlier Detection (HBOS)')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "OUTLIERS: 2 INLIERS: 180\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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UW1qauLdd9/l5ptvblnmcrm47LLLePPNN01t4+DBgxw9epQBAwYEfcyRI0c4cuRIy/36+vqulBmz2uYs+j65BuIjZ9F37L6R+3h8DkRExEHOxZhM5YXkIRshMbHlR65dO01lq3ozMvEMzvJbllj0iande4aejLd//5b7CQ0NuD4398EDzWNP87vv2lNNwv7akOu5POGP0etSo7pv3z6am5vJyvJ/0rKysvjkE3NP3E033cTQoUO57LLLgj7mzjvv5LbbbutKaXEhnnMWfcd+529+zYQJE8jPz4+750BERBzkHOCXwCvAf8GQNUlUzW4CID3/xyS/+nLITTRet4QDv7nXb9mgSWeb2n3N3/5F07QZLfd7b3mDAd/6mql1q/Y3+d1PeeA+Un7/YOgVJ19qavtdEdVZ/3fddRdPP/00GzZsoE+fPkEfd/PNN3P99de33K+vr2fYsGHRKNH23Is8zF1xgJycnJZlvhnvsc537GsLt+JyueLyORAREQc59fjtuCFrkoxv9ppbPaX8QVLWmGgQAxjw1tfgcJsF28yv21KnT7m59ZL3vWZ+JyZ1qVEdOHAgiYmJVFdX+y2vrq5myJDOz7ned9993HXXXbzyyiucfXbnfw0kJyeTnJzcldJsK9x5p5kpsGapMWlow8eQkABTTrc2lilama5tj72kykOvRDjW7NuvmlQREXGIs4BME48bFWDZ5ADLAskIcN/suoHqMLNuFvBxN/cRRJca1aSkJM455xzWr1/PFVdcAdAyMSo3Nzfoevfccw933HEHL730Eueee27PKnaISOad1jTAT9zWf3qNFZmuoIxJERFxuNk9WHdhN9c7pQfrXnj8FspB4Llu7iOILs/6v/7663nsscf405/+xPbt21m0aBGNjY3Mnz8fgB/84Ad+k63uvvtufvnLX7J69WpGjBhBVVUVVVVVNDQ0hO8obCiSead2yVK1Sx0iIiISm7p8jeqVV17J3r17ufXWW6mqqmLChAn8+9//bplgVVlZicvV2qisWLGCpqYmvv3tb/ttZ9myZfzv//5vz6q3KV/mp9u9vGVm+pw5c/B6veTk5FBc1f0RwUhu24l1iIiISOzq1mSq3NzcoKf6N2zY4He/oqKiO7twNDN5p91t4iK5bSfWISIiIrFL52gjoG3eaVvhyPqM5LadWIeIiIjErqjGU8WLSOad2iVL1S51iIiISOxK8Hrt/wG09fX1pKenU/cYpPWzuhpzahth7orIzIiP5LadWIfErmhFn4mISM/VH4T0a6Guro60tLSwbFONaoQZmZ+ReaON5LadWIfEjpoG+P5yeKlNQPXlZ8NTueiPIBERm1Kj6sBGVUS67qt3wysfQnObK0gSXXDZmfDvm6yrS0REgotEo6rJVCJiK0W7jZHU5naXOTd7jOXFVdbUJSIi0adGVURspbS685+XqFEVEYkbalRFxFZ80WfBKPpMRCR+qFEVEVsZe6IxcSqx3f9OiS5juSbsiYjEDzWqImI7T+UaE6fauuxMY7mIiMQPBf5LXFAep7Nkphiz+xV9JiIS39SoSkyraYCclfpQAqcaowZVRCSu6dS/xLSclS42V6TidruprKzE7XazuSKVuSv00hcREbE7jahKzCraDWsLPbjdy5kzZw4Ac+bMwev1kpOTQ3GVRutERETsTMNKErN8eZyTJ0/2Wz5lyhRAeZwiIiJ2p0ZVYpYvj7OgoMBv+caNGwHlcYqIiNidTv1LzBp7ojFxKj9vMV6vlylTprBx40aW5Ocya6KLMUM8oTciIiIillGjKjHNvcjD3BUHyMnJaVnmm/UvIiIi9qZGVWJaZgqsWeppl8epJlVERMQJ1KhKXFAep4iIiPNoMpWIiIiI2JIaVRERERGxJTWqIiIiImJLalRFRERExJbUqIqIiIiILalRFRERERFbUqMqIiIiIrakRlVEREREbEmNqoiIiIjYkhpVEREREbElNaoiIiIiYktqVEVERETEltSoioiIiIgtqVEVEREREVvqZXUBItFQtBtKq2H0EBgzxOpqRERExAw1qhLTahogZ6WLtYWelmWzJrpwL/KQmWJhYSIiIhKSTv1LTMtZ6WJzRSput5vKykrcbjebK1KZu0IvfREREbvTiKrErKLdsLbQg9u9nDlz5gAwZ84cvF4vOTk5FFfpMgARERE707CSxKzSauPr5MmT/ZZPmTIFgJKqaFckIiIiXaFGVWJWdpbxtaCgwG/5xo0bAWNilYiIiNiXTv1LzBp7ojFxKj9vMV6vlylTprBx40aW5Ocya6KLMUM8oTciIiIillGjKjHNvcjD3BUHyMnJaVnmm/UvIiIi9qZGVWJaZgqsWeqhuMq4JtXIUVWTKiIi4gRqVCUujFHQv4iIiONoMpWIiIiI2JIaVRERERGxJTWqIiIiImJLalRFRERExJbUqIqIiIiILalRFRERERFbUqMqIiIiIrakRlVEREREbEmNqoiIiIjYkhpVEREREbElNaoiIiIiYktqVEVERETEltSoioiIiIgtqVEVEREREVtSoyoiIiIitqRGVURERERsSY2qiIiIiNiSGlURERERsSU1qiIiIiJiS2pURURERMSW1KiKiIiIiC2pURURERERW1KjKiIiIiK2pEZVRERERGxJjaqIiIiI2JIaVRERERGxJTWqIiIiImJLalRFRERExJbUqIqIiIiILfWyuoBIK9oNpdUwegiMGWJ1NSIiIiJiVsw2qjUNkLPSxdpCT8uyWRNduBd5yEyxsDARERERMSVmT/3nrHSxuSIVt9tNZWUlbrebzRWpzF0Rs4csIiIiElNickS1aDesLfTgdi9nzpw5AMyZMwev10tOTg7FVboMQERERMTuYnJ4sbTa+Dp58mS/5VOmTAGgpCraFYmIiIhIV8Vko5qdZXwtKCjwW75x40bAmFglIiIiIvYWk6f+x55oTJzKz1uM1+tlypQpbNy4kSX5ucya6GLMEE/ojYiIiIiIpWKyUQVwL/Iwd8UBcnJyWpb5Zv2LiIiIiP3FbKOamQJrlnoorjKuSTVyVNWkioiIiDhFzDaqPmMU9C8iIiLiSDE5mUpE/n979x4WVbX+AfwLA8NFuabcjEsiEBomSCCSYkZBKEdPpRxT0PJSiQcNQzNTMEtJxexiolbSEyZZKnkUb5BgIpkXMAsOCGL280HKvIBioLB+f/gwx5HhMjgzbOD7eZ55yrXX3muteffevOzLgoiIqPNjokpEREREksRElYiIiIgkiYkqEREREUkSE1UiIiIikqQu/9a/KiUVd/7Maj8dzAigy7Z0oauNh4iIiKSrWyWql68Dkcn6yMj/33yqjX8EwKpH521LF7raeIiIiEj6utWt/8hkffx4zgypqak4f/48UlNT8eM5M0xap/mvQZdt6UJXGw8RERFJX7e5olpSAWTkNyA1dS0mTpwIAJg4cSKEEIiMjMSZi5q7la3LtnShq42HiIiIOoduczmsrPLOf4cPH65UHhQUBODOn1ntjG3pQlcbDxEREXUO3SZRdbW9899Dhw4plefk5AC483JQZ2xLF7raeIiIiKhz6Da3/t3t77z8E/PvaAghEBQUhJycHMyO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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gHRoON0BnLVb", + "outputId": "73ec2b80-9edf-445b-8276-baa505178432", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneoutlier
31811female0.380374020.321798SFirstwomanFalseCSouthamptonyesFalse1
68911female0.178048010.412503SFirstchildFalseBSouthamptonyesFalse1
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... embark_town alive alone outlier\n", + "318 1 1 female 0.380374 ... Southampton yes False 1\n", + "689 1 1 female 0.178048 ... Southampton yes False 1\n", + "\n", + "[2 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YblU2tnxnXi7", + "outputId": "c96e85f5-7565-46bf-c355-223297a1d980", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 689\n", + "df_titanic.loc[689]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 1\n", + "pclass 1\n", + "sex female\n", + "age 15\n", + "sibsp 0\n", + "parch 1\n", + "fare 211.338\n", + "embarked S\n", + "class First\n", + "who child\n", + "adult_male False\n", + "deck B\n", + "embark_town Southampton\n", + "alive yes\n", + "alone False\n", + "Name: 689, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkWj5aQ-uzxB", + "outputId": "1a12b0f5-1cec-4a43-8fef-29c2ca67e779", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
agefare
meanmean
sex
female33.089.0
male38.069.0
\n", + "
" + ], + "text/plain": [ + " age fare\n", + " mean mean\n", + "sex \n", + "female 33.0 89.0\n", + "male 38.0 69.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EVy5NDrFujgD", + "outputId": "e3e2dbd7-b4fd-445a-fac4-3dbf9139ba08", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "36" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hgcp_LU6ujgJ", + "outputId": "e6959579-db19-4fbd-cc87-0b42421a0b90", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "79" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KyPUT9JmWeN-" + }, + "source": [ + "___\n", + "## **Isolation Forest**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Lrx85bG0YOqM", + "outputId": "84485503-9084-42e2-f251-56626897b391", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 755 + } + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = IForest(contamination = outliers_fraction,random_state = 0)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "# fare - inlier feature 1, age - inlier feature 2\n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "# fare - outlier feature 1, age - outlier feature 2\n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS: ', n_outliers,'INLIERS: ', n_inliers)\n", + " \n", + "# threshold value to consider a datapoint inlier or outlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# decision function calculates the raw anomaly score for every point\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "# fill blue map colormap from minimum anomaly score to threshold value\n", + "plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7),cmap=plt.cm.Blues_r)\n", + " \n", + "# draw red contour line where anomaly score is equal to thresold\n", + "a = plt.contour(xx, yy, Z, levels= [threshold],linewidths=2, colors='red')\n", + " \n", + "# fill orange contour lines where range of anomaly score is from threshold to maximum anomaly score\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight')\n", + "plt.legend([a.collections[0], b,c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size = 10), loc='upper center', frameon= False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol=5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Isolation Forest')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "OUTLIERS: 2 INLIERS: 180\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqoAAALRCAYAAACTYIFoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdeXwTdf7H8VeSJr1oS8uNXOVUUARREdRWPFB0UddbSr3P5dD1Zr1PdlfFCy9cj9Xoru76090VPAAVFBAv8EJFbkTuowVKW9rM749pm4amR9okM0nez8cjD2Ymk8lnmjD99Dvf7+frMAzDQERERETEZpxWByAiIiIiEowSVRERERGxJSWqIiIiImJLSlRFRERExJaUqIqIiIiILSlRFRERERFbUqIqIiIiIrakRFVEREREbEmJqoiIiIjYkhJVEYlrF110ET169AjrMV966SUcDgerVq0K63FFRCSQElURsVR10vfll19aHUodDzzwAG+//bbVYQTo0aMHDocj6KO0tNTq8OqYP38+d911Fzt27LA6FBGJQUlWByAiYlcPPPAAZ511FqeffnrA9sLCQs477zySk5MtiWvQoEFcf/31dbZ7PB4LomnY/Pnzufvuu7noooto3bq11eGISIxRoioiEiKXy4XL5bLs/ffbbz/Gjh0b9uP6fD7Ky8tJSUkJ+7FFRJpDt/5FxHY2bNjAxRdfTJcuXUhOTqZTp06cdtppdfqEPvXUUwwYMIDk5GQ6d+7MuHHjmnSL+aGHHmL48OG0adOG1NRUhgwZwr///e+AfRwOB7t37+bvf/97za31iy66CKi/j2pT4jnmmGM48MADWbJkCSNGjCAtLY399tuPv/71ryH/nOqze/durr/+erp27UpycjL9+vXjoYcewjCMOuc4fvx4Xn311Zq433vvPQDWrVvHJZdcQocOHUhOTmbAgAG88MILdd7riSeeYMCAAaSlpZGdnc2hhx7Ka6+9BsBdd93FjTfeCEBubm7Nz1F9e0WkqdSiKiK2c+aZZ/LDDz8wYcIEevTowaZNm5g5cyZr1qypGRh11113cffdd3P88cdz9dVX8/PPP/P000/zxRdfMG/ePNxud73Hf+yxxzj11FMpKCigvLycf/7zn5x99tm88847nHLKKQC88sorXHbZZRx++OFcccUVAPTq1aveY4YSz/bt2znppJM444wzOOecc/j3v//NzTffzEEHHcSoUaMa/fns3buXLVu2BGxLS0sjLS0NwzA49dRT+eijj7j00ksZNGgQ77//PjfeeCPr1q3jkUceCXjdhx9+yBtvvMH48eNp27YtPXr0YOPGjRxxxBE1iWy7du149913ufTSSykuLubaa68F4LnnnmPixImcddZZXHPNNZSWlvLtt9+ycOFCxowZwxlnnMHSpUv5xz/+wSOPPELbtm0BaNeuXaPnKCICgCEiYqEXX3zRAIwvvvjCMAzD2L59uwEYDz74YL2v2bRpk+HxeIyRI0calZWVNdunTp1qAMYLL7xQs+3CCy80unfvHvD6kpKSgPXy8nLjwAMPNI499tiA7enp6caFF15Yb8wrV64MOZ78/HwDMF5++eWabWVlZUbHjh2NM888s95zrta9e3cDqPO48847DcMwjLffftsAjPvuuy/gdWeddZbhcDiMZcuW1WwDDKfTafzwww8B+1566aVGp06djC1btgRsP++884ysrKyan99pp51mDBgwoMF4H3zwwYCflYhIKHTrX0RsJTU1FY/Hw8cff8z27duD7jNr1izKy8u59tprcTr9l7HLL7+czMxMpk+f3uh7VNu+fTtFRUUcffTRfP31182KOdR4WrVqFdDH1OPxcPjhh7NixYomvd/QoUOZOXNmwOOCCy4AYMaMGbhcLiZOnBjwmuuvvx7DMHj33XcDtufn59O/f/+adcMwePPNNxk9ejSGYbBly5aax4knnkhRUVHNz6l169b8+uuvfPHFF02KW0QkVLr1LyK2kpyczF/+8heuv/56OnTowBFHHMHvfvc7LrjgAjp27AjA6tWrAejXr1/Aaz0eDz179qx5vj7vvPMO9913H4sXL6asrKxmu8PhaFbMocbTpUuXOu+VnZ3Nt99+26T3a9u2Lccff3y9sXTu3JmMjIyA7QcccEBArNVyc3MD1jdv3syOHTuYNm0a06ZNC/oemzZtAuDmm29m1qxZHH744fTu3ZuRI0cyZswYjjzyyCadh4hIY9SiKiK2c+2117J06VImT55MSkoKt99+OwcccACLFi1q8bE/+eQTTj31VFJSUnjqqaeYMWMGM2fOZMyYMXUGG0VKfRUDovX+tdVuXQZz5D/A2LFj67TaVj+qE9EDDjiAn3/+mX/+858cddRRvPnmmxx11FHceeedUT8PEYlPalEVEVvq1asX119/Pddffz2//PILgwYN4uGHH8br9dK9e3cAfv75Z3r27FnzmvLyclauXFlvayPAm2++SUpKCu+//35AHdQXX3yxzr5NbWFtSTzh1r17d2bNmsXOnTsDWlV/+umngFjr065dOzIyMqisrGxS3Onp6Zx77rmce+65lJeXc8YZZ3D//fczadIkUlJSmt1KLSICalEVEZspKSmpM8NSr169yMjIqLlNf/zxx+PxeHj88ccDWiGff/55ioqKakbuB+NyuXA4HFRWVtZsW7VqVdAZqNLT05tU7qol8YTbySefTGVlJVOnTg3Y/sgjj+BwOBqtKuByuTjzzDN58803+f777+s8v3nz5prlrVu3Bjzn8Xjo378/hmGwd+9ewPwZApqZSkSaRS2qImIrS5cu5bjjjuOcc86hf//+JCUl8dZbb7Fx40bOO+88wGz1mzRpEnfffTcnnXQSp556Kj///DNPPfUUhx12WIPF8E855RSmTJnCSSedxJgxY9i0aRNPPvkkvXv3rtNHdMiQIcyaNYspU6bQuXNncnNzGTp0aJ1jtiSecBs9ejQjRozg1ltvZdWqVRx88MF88MEH/Oc//+Haa69tsMRWtT//+c989NFHDB06lMsvv5z+/fuzbds2vv76a2bNmsW2bdsAGDlyJB07duTII4+kQ4cO/Pjjj0ydOpVTTjmlpjV3yJAhANx6662cd955uN1uRo8eXZPAiog0yLqCAyIidctTbdmyxRg3bpyx//77G+np6UZWVpYxdOhQ44033qjz2qlTpxr777+/4Xa7jQ4dOhhXX321sX379oB9gpWnev75540+ffoYycnJxv7772+8+OKLxp133mnse0n86aefjLy8PCM1NdUAakpV7VueKpR48vPzg5Z0ChZnMN27dzdOOeWUBvfZuXOn8cc//tHo3Lmz4Xa7jT59+hgPPvig4fP5AvYDjHHjxgU9xsaNG41x48YZXbt2Ndxut9GxY0fjuOOOM6ZNm1azz7PPPmvk5eUZbdq0MZKTk41evXoZN954o1FUVBRwrHvvvdfYb7/9DKfTqVJVIhISh2FY0HtfRERERKQR6qMqIiIiIrakRFVEREREbEmJqoiIiIjYUsiJ6ty5cxk9ejSdO3fG4XAELemyr48//phDDjmE5ORkevfuzUsv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gwcPDvua1NRU68UXX2z02Lx586wePXo0u56ZM2daCs5J44svvvjiiy+++OLLQ187d+6Mpr1skZHxVDNmzGg0Cnv48GGdeeaZ2rNnj7KyslysDE6oqKhQ37599emnn8btYmyYi/2dXNjfyYX9nVzKy8t1xhlnqGvX+KQISFGe+u/WrZv8fr/KysoaPV5WVqaePcPPOOrZs2dUz5ek9PR0paenn/J4VlYWB3oSyczMZH8nEfZ3cmF/Jxf2d3Lx+eI33yKqJaWlpWnQoEFauXJl3WOBQEArV65UXl5e2Nfk5eU1er4krVixotnnAwAAAFIM8VRFRUUaN26cLr/8cg0ePFhPPPGEqqqqNH78eEnSzTffrD59+mj27NmSpGnTpik/P1+/+tWvdN1112nx4sV677339Mwzz8R3SwAAAJBQ/Pfdd9990bzgoosuUufOnfXggw9qzpw5kqQXXnhB5513nqRgHFW7du00evRoSVLfvn01YMAAPfbYY3r44YdVVlamZ599VkOHDo2uUL9fX/nKV9SunZGX1SLO2N/Jhf2dXNjfyYX9nVzivb898RGqAAAASD6kiwMAAMBINKoAAAAwEo0qAAAAjESjCgAAACMZ06jOmzdP/fr1U0ZGhoYMGaINGza0+PyXX35Z559/vjIyMjRw4EAtXbrUoUoRD9Hs74ULF+qqq65Sly5d1KVLFw0fPrzV4wNmifb3O2Tx4sVKSUmpSxGBN0S7vw8fPqxJkyapV69eSk9P17nnnsu/6R4S7f5+4okndN5556l9+/bq27evbr/9dh07dsyhahGrNWvW6Prrr1fv3r2VkpKi1157rdXXrFq1SpdddpnS09N1zjnn6Lnnnot+xXH7MNY2WLx4sZWWlmYtWrTI+sc//mFNmDDB6ty5s1VWVhb2+X/7298sv99vPfroo9aWLVusX/ziF1Zqaqq1efNmhytHLKLd3zfddJM1b948a+PGjdZHH31k/eAHP7CysrKszz77zOHKEYto93fIrl27rD59+lhXXXWV9c1vftOhatFW0e7v6upq6/LLL7dGjRplvf3229auXbusVatWWZs2bXK4csQi2v39wgsvWOnp6dYLL7xg7dq1y1q+fLnVq1cv6/bbb3e4ckRr6dKl1t1332394Q9/sCRZr776aovP//jjj60OHTpYRUVF1pYtW6y5c+dafr/fWrZs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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HLVraGcCnNTA", + "outputId": "957c19be-cec9-4d4a-9902-0f49f806198f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneoutlier
67911male0.443601011.0CFirstmanTrueBCherbourgyesFalse1
73711male0.430956001.0CFirstmanTrueBCherbourgyesTrue1
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... embark_town alive alone outlier\n", + "679 1 1 male 0.443601 ... Cherbourg yes False 1\n", + "737 1 1 male 0.430956 ... Cherbourg yes True 1\n", + "\n", + "[2 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y0WBmFOonZKY", + "outputId": "06cdcee2-c8fc-44ec-aa7b-f33d16d4d7c2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 1\n", + "pclass 1\n", + "sex male\n", + "age 36\n", + "sibsp 0\n", + "parch 1\n", + "fare 512.329\n", + "embarked C\n", + "class First\n", + "who man\n", + "adult_male True\n", + "deck B\n", + "embark_town Cherbourg\n", + "alive yes\n", + "alone False\n", + "Name: 679, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "auSy5b6Du3PH", + "outputId": "b1aae710-3d55-4ff1-81e1-635fdb96a8ca", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
agefare
meanmean
sex
female33.089.0
male38.069.0
\n", + "
" + ], + "text/plain": [ + " age fare\n", + " mean mean\n", + "sex \n", + "female 33.0 89.0\n", + "male 38.0 69.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fIQg2D6fuoSG", + "outputId": "94244010-8314-481c-a428-b526d3b70ca8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "36" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pNUds1oDuoSO", + "outputId": "64f51541-4329-404d-8d0b-f65faf2b397e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "79" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QbpzXB2RV4sq" + }, + "source": [ + "___\n", + "## **KNN - K-Nearest Neighbors**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6gtIWWbRYxEj", + "outputId": "8bc4ae18-4a33-489e-d13e-98a3160a9e13", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 755 + } + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = KNN(contamination = outliers_fraction)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS: ',n_outliers, 'INLIERS: ', n_inliers)\n", + " \n", + "# threshold value to consider a datapoint inlier or outlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# decision function calculates the raw anomaly score for every point\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "# fill blue map colormap from minimum anomaly score to threshold value\n", + "plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7),cmap=plt.cm.Blues_r)\n", + " \n", + "# draw red contour line where anomaly score is equal to thresold\n", + "a = plt.contour(xx, yy, Z, levels= [threshold],linewidths=2, colors='red')\n", + " \n", + "# fill orange contour lines where range of anomaly score is from threshold to maximum anomaly score\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight') \n", + " \n", + "plt.legend([a.collections[0], b,c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size=10), loc='upper center', frameon= False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('K-Nearest Neighbors (KNN)')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "OUTLIERS: 2 INLIERS: 180\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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zc5tV111lQEYt99+u8u+X375pQEYr7/+usv2RYsWuWx/9913ncdQnV27dhmAcc8999TwbpT5/PPPDcB46623jP379xspKSnG0KFDXcYcFxfnvH/gwAEjOTnZuOaaa1yeZ/v27UZSUpLL9nvuucco/9G7YsUKAzAmTZrk8thRo0ZVGnPpY8eMGeOy7/Dhw41GjRq5bAMMwFi+fLlz2+bNm42YmBhj+PDhzm3Dhg0zoqKijNzcXOe233//3UhISDB69uzp3Fb6b6VHjx5GUVGRy2slJSUZN9xwg+GpadOmGYBx4MCBSl8r/TcNGJdffnml1yyVl5dnAMbjjz9uFBUVGe3btzc6d+5sOBwOwzDK3rNdu3Y5H1P++/fKK68YgPHOO++4vHZVx/PGG28YgPHdd995fKwiUjeqqIqEiB07dhATE0PLli3r9Pi2bduSlZXF3Llz+eOPP6rc55133sHhcHDppZeye/du5y0tLY327dvz+eefO/eNjY11/v3QoUPs3r2b7t27YxgGq1atqvTc1113ncv9t956i6SkJPr27evyWl27diU+Pt75WsnJyQB89NFHziqrNyUlJTFp0iQ++OCDKscN8Mknn7B//34uv/xyl7FGRETQrVs3l/elotKODNdff73L9vHjx1f7mGuvvdbl/vnnn8+ePXsqVfrOPfdcunbt6rzfqlUrLrroIj7++GOKi4spLi5m8eLFDBs2jLZt2zr3a968OVdccQVfffVVpee85ppriIiIcNmWnJzMd9995/Ec5z179hAZGVltB4UdO3YAZsW/4mtWpXxV9b333nNrDJmZmW5XVVNSUgDcag8mIt6hoCoSIp5//nmioqIYMGAAa9eudW4vLi5m+/btLrdjx45V+RzTpk2jqKio2rmq69evxzAM2rdvT5MmTVxua9asYefOnc59t2zZwqhRo0hNTSU+Pp4mTZqQkZEBmK2zyouMjHTOdyz/Wvn5+TRt2rTSax08eND5WhkZGVxyySVMnz6dxo0bc9FFFzFv3jwKCws9fxOrMXHiRJKTk6udq7p+/XoA/vKXv1Qa6+LFi13el4o2b96M3W6nTZs2LtvbtWtX7WNatWrlcr80QFWcu9u+fftKj+3QoQOHDx9m165d7Nq1i8OHD3PSSSdV2u+UU07B4XBUmntccZxg9kH9+eefadmyJWeffTb33nsvGzdurHb87rrqqqsYMmQIDz30EE899ZRbj8nMzKRdu3Zun84vDberV6+uNdyWPl9d++CKiOcirR6AiHhHx44dWbBgARdccAF9+/bl66+/pmXLlmzdurVSuPj888/p1atXpedo27YtI0eOZO7cuc75h+U5HA5sNhsLFy6sssJVWhkrLi6mb9++7N27l9tuu42TTz6ZuLg4tm3bxqhRoyo1do+Ojq4099DhcNC0aVNef/31Ko+3dIGUzWbj//7v/1i2bBkffvghH3/8MWPGjOHJJ59k2bJlXul3WlpVvffee6usqpYez2uvvUZaWlqlr0dGevejtrrqojvBrL7KV8pLXXrppZx//vm8++67LF68mMcff5xHH32Ud955p8auE40aNaKoqIgDBw6QkJBQ6euRkZG8+eabDBgwgFtuuYXk5GRGjx5d4/hKg+eoUaPcXviUmZnJ/fffz3333cewYcOq3a/0F4HGjRu79bwiUn8KqiIh5Oyzz+a9995j8ODB9O3bly+//JK0tDQ++eQTl/06d+5c7XNMmzaN7OxsHn300UpfS09PxzAM2rRpQ4cOHap9jp9++ol169bxyiuvuCyeqjiOmqSnp/Ppp59y3nnnVRmOKjrnnHM455xzePDBB3njjTfIzMzk3//+N1dffbVXKmCTJk1i5syZTJ8+3TndoPxYAZo2bVrrCvaKTjzxRBwOB3l5eS4V0A0bNtR7zKWV3vLWrVtHw4YNnUG/YcOGLhX4Uv/73/+w2+1uTyVp3rw5119/Pddffz07d+7kzDPP5MEHH6wxqJ588smAufr/9NNPr3KfmJgYPvjgA3r37s0111xDcnIyw4cPr3EsI0eO5IEHHmD69OkMHTq01rG7G27z8vKw2+01/tsXEe/SqX+REHPBBRfwr3/9iw0bNjBgwACOHTtGnz59XG6lp4qrkp6ezsiRI3n++efZvn27y9cuvvhiIiIimD59eqXqnWEY7NmzByir+JXfxzAMnn76abeP49JLL6W4uJj777+/0teKioqcHQb27dtXaSxdunQBcJ7+b9iwIYBLVwJPlVZV33//fVavXu3ytf79+5OYmMhDDz1U5TzZXbt2Vfu8/fv3B+C5555z2T5r1qw6j7XUt99+69KtYOvWrbz//vv069ePiIgIIiIi6NevH++//75LZ4IdO3bwxhtv0KNHDxITE2t8jeLi4kpT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5s2b1a1bt5Oe//777+vaa6/VrFmzdPXVV+v555/XqFGj9OGHH+r8889PyE40lp/AprCl6yInE83h/AAAILq4J1M98sgjmjBhgsaPH69zzz1X8+bNU7t27bRw4cKIz3/sscf0/e9/X7feeqv69u2re+65RxdffLGeeOKJVhdvZ+RkojmcHwAARBfXiGptba0++OADTZ8+vX6Zx+PRsGHDtHr16oivWb16tcrKysKWDR8+XK+88kqT26mpqVFNTU394/3790uSqr+Jp1rrbK0K5mQ+9dRDGjlypCRp5MiROnz4sG688Uat3yH1OnnwGSmC8wMA4EahPi2h05+MOHz55ZeGJOP9998PW37rrbcaAwcOjPiaNm3aGM8//3zYsjlz5hjdunVrcjszZswwJPHFF1988cUXX3zx5bCvbdu2xdNeNsuW8VTTp08PG4Xdt2+fzjjjDO3cuVNZWVkWVoZkqK6uVl5enj7//POE3YwN++J4pxaOd2rheKeW/fv36/TTT1eXLl0Sts64GtWuXbvK6/WqqqoqbHlVVZVycyPPOMrNzY3r+ZKUkZGhjIyMk5ZnZWVxoqeQTp06cbxTCMc7tXC8UwvHO7V4PImbbxHXmnw+n/r376/ly5fXLwsEAlq+fLkKCwsjvqawsDDs+ZK0bNmyJp8PAAAASC2IpyorK9O4ceM0YMAADRw4UI8++qgOHTqk8ePHS5LGjh2rHj16aNasWZKkm2++WUVFRfrd736nq666SosWLdL//d//6amnnkrsngAAAMBVvHfddddd8bzg/PPPV3Z2tu699149/PDDkqTnnntOZ599tqRgHFV6erpGjRolScrLy1Pfvn310EMP6f7771dVVZUWLFigIUOGxFeo16tLL71U6em2vK0WCcbxTi0c79TC8U4tHO/Ukujj7YiPUAUAAEDqIV0cAAAAtkSjCgAAAFuiUQUAAIAt0agCAADAlmzTqM6ZM0c9e/ZUZmamBg0apHXr1jX7/BdeeEHnnHOOMjMz1a9fPy1ZsiRJlSIR4jne8+fP1yWXXKLOnTurc+fOGjZsWNTzA/YS7+93yKJFi5SWllafIgJniPd479u3T5MmTVL37t2VkZGhPn368He6g8R7vB999FGdffbZatu2rfLy8nTLLbfoyJEjSaoWLbVq1SqNHDlSp512mtLS0vTKK69Efc2KFSt08cUXKyMjQ71799YzzzwT/4YT9mGsrbBo0SLD5/MZCxcuNP75z38aEyZMMLKzs42qqqqIz3/vvfcMr9drPPjgg8bHH39s/OY3vzHatGljbNy4McmVoyXiPd7XXXedMWfOHGP9+vXGpk2bjOuvv97IysoyvvjiiyRXjpaI93iHbN++3ejRo4dxySWXGD/60Y+SVC1aK97jXVNTYwwYMMAYMWKE8e677xrbt283VqxYYWzYsCHJlaMl4j3ezz33nJGRkWE899xzxvbt242lS5ca3bt3N2655ZYkV454LVmyxLj99tuNl156yZBkvPzyy80+/9NPPzXatWtnlJWVGR9//LExe/Zsw+v1Gm+88UZc27VFozpw4EBj0qRJ9Y/r6uqM0047zZg1a1bE519zzTXGVVddFbZs0KBBxn/+53+aWicSI97j3dixY8eMjh07Gs8++6xZJSKBWnK8jx07ZgwePNh4+umnjXHjxtGoOki8x3vu3LnGWWedZdTW1iarRCRQvMd70qRJxmWXXRa2rKyszBgyZIipdSKxYmlUf/WrXxnnnXde2LLRo0cbw4cPj2tbll/6r62t1QcffKBhw4bVL/N4PBo2bJhWr14d8TWrV68Oe74kDR8+vMnnwz5acrwbO3z4sI4ePaouXbqYVSYSpKXH++6771a3bt10ww03JKNMJEhLjvdf/vIXFRYWatKkScrJydH555+v++67T3V1dckqGy3UkuM9ePBgffDBB/W3B3z66adasmSJRowYkZSakTyJ6tUs/5iI3bt3q66uTjk5OWHLc3Jy9Mknn0R8TWVlZcTnV1ZWmlYnEqMlx7uxadOm6bTTTjvpFwD205Lj/e6772rBggXasGFDMkpEArXkeH/66ad66623VFxcrCVLlmjr1q266aabdPToUc2YMSMZZaOFWnK8r7vuOu3evVvf/e53ZRiGjh07pp///Of69a9/nYySkURN9WrV1dX65ptv1LZt25jWY/mIKhCP+++/X4sWLdLLL7+szMxMq8tBgh04cEAlJSWaP3++unbtanU5SIJAIKBu3brpqaeeUv/+/TV69GjdfvvtmjdvntWlwQQrVqzQfffdpyeffFIffvihXnrpJZWXl+uee+6xujTYlOUjql27dpXX61VVVVXY8qqqKuXm5kZ8TW5ublzPh3205HiHPPzww7r//vv117/+VRdccIGZ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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6B-L7MwXg25Z", + "outputId": "0f8d806d-9e19-4133-c038-01d96c26b168", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df1.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneoutlier
111female0.468892100.139136CFirstwomanFalseCCherbourgyesFalse0
311female0.430956100.103644SFirstwomanFalseCSouthamptonyesFalse0
601male0.671219000.101229SFirstmanTrueESouthamptonnoTrue0
1013female0.038948110.032596SThirdchildFalseGSouthamptonyesFalse0
1111female0.721801000.051822SFirstwomanFalseCSouthamptonyesTrue0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... embark_town alive alone outlier\n", + "1 1 1 female 0.468892 ... Cherbourg yes False 0\n", + "3 1 1 female 0.430956 ... Southampton yes False 0\n", + "6 0 1 male 0.671219 ... Southampton no True 0\n", + "10 1 3 female 0.038948 ... Southampton yes False 0\n", + "11 1 1 female 0.721801 ... Southampton yes True 0\n", + "\n", + "[5 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gvXGH0BHBBNN", + "outputId": "b44557de-c87c-4012-adb9-63597c401390", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneoutlier
67911male0.443601011.0CFirstmanTrueBCherbourgyesFalse1
73711male0.430956001.0CFirstmanTrueBCherbourgyesTrue1
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... embark_town alive alone outlier\n", + "679 1 1 male 0.443601 ... Cherbourg yes False 1\n", + "737 1 1 male 0.430956 ... Cherbourg yes True 1\n", + "\n", + "[2 rows x 16 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MYbNaaO7D3NY", + "outputId": "bc9fcf92-8937-42e7-b79f-84a17a50ecb3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 286 + } + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 1\n", + "pclass 1\n", + "sex male\n", + "age 36\n", + "sibsp 0\n", + "parch 1\n", + "fare 512.329\n", + "embarked C\n", + "class First\n", + "who man\n", + "adult_male True\n", + "deck B\n", + "embark_town Cherbourg\n", + "alive yes\n", + "alone False\n", + "Name: 679, dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-juEvWvru5jp", + "outputId": "6f5f85aa-7249-4c32-8473-db43dc01eec3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 166 + } + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
agefare
meanmean
sex
female33.089.0
male38.069.0
\n", + "
" + ], + "text/plain": [ + " age fare\n", + " mean mean\n", + "sex \n", + "female 33.0 89.0\n", + "male 38.0 69.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B6NXG6oDusSg", + "outputId": "707873f7-a36b-45a5-e184-2aaf789985fc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "36" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 53 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cgHJb3iBusSl", + "outputId": "47a1c2c1-498e-4f85-8176-5464ac8077c4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "79" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 54 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1w7MIkoAG2Qr" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "Para cada um dos dataframes a seguir, faça uma análise de outlier utilizando uma das técnicas apresentadas e explique seus resultados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ep_Z3iQIG56r" + }, + "source": [ + "## Exercício 1 - Predict Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-Lvzrt7HN2l", + "outputId": "035c44f6-200d-41ab-c89d-4622f5b0bec6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 249 + } + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X = cancer['data']\n", + "y = cancer['target']\n", + "\n", + "df_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_cancer['target'] = df_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_cancer.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavitymean concave pointsmean symmetrymean fractal dimensionradius errortexture errorperimeter errorarea errorsmoothness errorcompactness errorconcavity errorconcave points errorsymmetry errorfractal dimension errorworst radiusworst textureworst perimeterworst areaworst smoothnessworst compactnessworst concavityworst concave pointsworst symmetryworst fractal dimensiontarget
017.9910.38122.801001.00.118400.277600.30010.147100.24190.078711.09500.90538.589153.400.0063990.049040.053730.015870.030030.00619325.3817.33184.602019.00.16220.66560.71190.26540.46010.11890malign
120.5717.77132.901326.00.084740.078640.08690.070170.18120.056670.54350.73393.39874.080.0052250.013080.018600.013400.013890.00353224.9923.41158.801956.00.12380.18660.24160.18600.27500.08902malign
219.6921.25130.001203.00.109600.159900.19740.127900.20690.059990.74560.78694.58594.030.0061500.040060.038320.020580.022500.00457123.5725.53152.501709.00.14440.42450.45040.24300.36130.08758malign
311.4220.3877.58386.10.142500.283900.24140.105200.25970.097440.49561.15603.44527.230.0091100.074580.056610.018670.059630.00920814.9126.5098.87567.70.20980.86630.68690.25750.66380.17300malign
420.2914.34135.101297.00.100300.132800.19800.104300.18090.058830.75720.78135.43894.440.0114900.024610.056880.018850.017560.00511522.5416.67152.201575.00.13740.20500.40000.16250.23640.07678malign
\n", + "
" + ], + "text/plain": [ + " mean radius mean texture ... worst fractal dimension target\n", + "0 17.99 10.38 ... 0.11890 malign\n", + "1 20.57 17.77 ... 0.08902 malign\n", + "2 19.69 21.25 ... 0.08758 malign\n", + "3 11.42 20.38 ... 0.17300 malign\n", + "4 20.29 14.34 ... 0.07678 malign\n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 55 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEHLrU0gHRtu" + }, + "source": [ + "## Exercício 2 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8G9GZnubHYjy", + "outputId": "c83f182b-c3f4-4d55-9ac8-ce1690d71acf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X = boston['data']\n", + "y = boston['target']\n", + "\n", + "df_boston = pd.DataFrame(np.c_[X, y], columns = np.append(boston['feature_names'], ['target']))\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATtarget
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT target\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 56 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlAdIYfmHaE8" + }, + "source": [ + "## Exercício 3 - Iris\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rke4C3wFHfYU", + "outputId": "7a1966b5-c787-4130-9ff0-55cc65bdbba2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns = np.append(iris['feature_names'], ['target']))\n", + "df_iris['target'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)target
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa
\n", + "
" + ], + "text/plain": [ + " sepal length (cm) sepal width (cm) ... petal width (cm) target\n", + "0 5.1 3.5 ... 0.2 setosa\n", + "1 4.9 3.0 ... 0.2 setosa\n", + "2 4.7 3.2 ... 0.2 setosa\n", + "3 4.6 3.1 ... 0.2 setosa\n", + "4 5.0 3.6 ... 0.2 setosa\n", + "\n", + "[5 rows x 5 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 57 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6qn3gC4NHj-p" + }, + "source": [ + "## Exercícios 4 - Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P-esq5TSHnf6", + "outputId": "eb042bc6-ad2f-49cb-eb35-2e1ba208e93d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X = diabetes['data']\n", + "y = diabetes['target']\n", + "\n", + "df_diabetes = pd.DataFrame(np.c_[X, y], columns = np.append(diabetes['feature_names'], ['target']))\n", + "df_diabetes.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
agesexbmibps1s2s3s4s5s6target
00.0380760.0506800.0616960.021872-0.044223-0.034821-0.043401-0.0025920.019908-0.017646151.0
1-0.001882-0.044642-0.051474-0.026328-0.008449-0.0191630.074412-0.039493-0.068330-0.09220475.0
20.0852990.0506800.044451-0.005671-0.045599-0.034194-0.032356-0.0025920.002864-0.025930141.0
3-0.089063-0.044642-0.011595-0.0366560.0121910.024991-0.0360380.0343090.022692-0.009362206.0
40.005383-0.044642-0.0363850.0218720.0039350.0155960.008142-0.002592-0.031991-0.046641135.0
\n", + "
" + ], + "text/plain": [ + " age sex bmi bp ... s4 s5 s6 target\n", + "0 0.038076 0.050680 0.061696 0.021872 ... -0.002592 0.019908 -0.017646 151.0\n", + "1 -0.001882 -0.044642 -0.051474 -0.026328 ... -0.039493 -0.068330 -0.092204 75.0\n", + "2 0.085299 0.050680 0.044451 -0.005671 ... -0.002592 0.002864 -0.025930 141.0\n", + "3 -0.089063 -0.044642 -0.011595 -0.036656 ... 0.034309 0.022692 -0.009362 206.0\n", + "4 0.005383 -0.044642 -0.036385 0.021872 ... -0.002592 -0.031991 -0.046641 135.0\n", + "\n", + "[5 rows x 11 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 58 + } + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs2.ipynb b/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs2.ipynb new file mode 100644 index 000000000..5ff30efaf --- /dev/null +++ b/Notebooks/NB10_04__3DP_4_Anomaly_Detection_hs2.ipynb @@ -0,0 +1,1484 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "NB10_04__3DP_4_Anomaly_Detection.ipynb", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EAqSDJGzyYrx" + }, + "source": [ + "

3DP_4 - ANOMALY/OUTLIER DETECTION

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-VrOjTTymSK" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte a **Table of contents**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wSAsbafemNax" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Mostrar junto os gráficos com a região de Anomaly Score junto com a distribuição de probabilidade das variáveis envolvidas.\n", + "* Mensagens de deprecating --> Analisar e substituir os métodos, funções deprecated;\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7qK6Yx0tBqUz" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Comparing anomaly detection algorithms for outlier detection on toy datasets](https://scikit-learn.org/stable/auto_examples/plot_anomaly_comparison.html#sphx-glr-auto-examples-plot-anomaly-comparison-py)\n", + "* [Outlier detection with several methods](https://scikit-learn.org/0.18/auto_examples/covariance/plot_outlier_detection.html)\n", + "* [anomaly-detection-resources](https://github.com/MathMachado/anomaly-detection-resources)\n", + "* [Outlier Detection with Extended Isolation Forest](https://towardsdatascience.com/outlier-detection-with-extended-isolation-forest-1e248a3fe97b)\n", + "* [Outlier Detection with Isolation Forest](https://towardsdatascience.com/outlier-detection-with-isolation-forest-3d190448d45e)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f7tTnUJ6B2UG" + }, + "source": [ + "___\n", + "## O que é Anomaly Detection (= Análise de Outliers)?\n", + "> Qualquer ponto/observação que é incomum quando comparado com todos os outros pontos/observações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7VJZf1U5Ds_w" + }, + "source": [ + "___\n", + "# **Machine Learning com Python (Scikit-Learn)**\n", + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rpHJ1qVUEwOn" + }, + "source": [ + "___\n", + "# **Técnicas tradicionais para detecção de outliers**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OOI_VTo3E3sv" + }, + "source": [ + "## Boxplot\n", + "* $IQR = Q_{3}-Q_{1}$\n", + "\n", + "![BoxPlot](https://github.com/MathMachado/Materials/blob/master/boxplot.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vivFsmJGFVC0" + }, + "source": [ + "## Z-Score\n", + "* Z-Score pode ser utilizado para detectar Outliers.\n", + "* É a diferença entre o valor e a média da amostra expressa como o número de desvios-padrão. \n", + "* Se o escore z for menor que 2,5 ou maior que 2,5, o valor estará nos 5% do menor ou maior valor (2,5% dos valores em ambas as extremidades da distribuição). No entanto, é pratica comum utilizarmos 3 ao invés dos 2,5.\n", + "\n", + "![Z_Score](https://github.com/MathMachado/Materials/blob/master/Z_Score.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7_YohlTIF8zi" + }, + "source": [ + "___\n", + "# **Hands-On**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OrXdGg8t0V_D" + }, + "source": [ + "## Carrega as Bibliotecas necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7pYqwxIe1Hcq" + }, + "source": [ + "!pip install pyod" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gxBgvhA4mowO" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from numpy import percentile\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "import matplotlib\n", + "\n", + "from sklearn.ensemble import IsolationForest\n", + "\n", + "# Scaling variables\n", + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "from pyod.models.abod import ABOD\n", + "from pyod.models.cblof import CBLOF\n", + "\n", + "#from pyod.models.feature_bagging import FeatureBagging\n", + "from pyod.models.hbos import HBOS\n", + "from pyod.models.iforest import IForest\n", + "from pyod.models.knn import KNN\n", + "#from pyod.models.lof import LOF\n", + "from scipy import stats\n", + "\n", + "# remove warnings to keep notebook clean\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WLf_c29t0ekj" + }, + "source": [ + "## Carrega dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GZyPw_7RRx26" + }, + "source": [ + "df_titanic = sns.load_dataset('titanic')\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zGqsV7kxSSCj" + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YL_VQljA0gxZ" + }, + "source": [ + "# Por simplicidade, vou descartando/omitindo todos os Missing Values\n", + "df_titanic = df_titanic.dropna() # Esta não é a forma adequada! Dê o devido tratamento aos Missing Values (NaN) da base de dados!\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q2oxyyQWB-uz" + }, + "source": [ + "# Normalizar as variáveis 'age' e 'fare'\n", + "df_titanic_ss = df_titanic.copy()\n", + "df_titanic_ss[['fare', 'age']] = StandardScaler().fit_transform(df_titanic_ss[['fare', 'age']])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rAKnKtil9Oz1" + }, + "source": [ + "# Linhas do df_titanic\n", + "df_titanic_ss.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sHSYUkEQFIwS" + }, + "source": [ + "# Função para plotar o Boxplot\n", + "def boxplot_sobreviveu(df, column):\n", + " plt.rcdefaults()\n", + " sns.catplot(x = 'survived', y = column, kind = \"box\", data = df, height = 4, aspect = 1.5)\n", + " \n", + " # add data points to boxplot with stripplot\n", + " sns.stripplot(x = 'survived', y = column, data = df, alpha = 0.3, jitter = 0.2, color = 'k');\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z7F4zWltT7l6" + }, + "source": [ + "Esta é a visão univariada da variável 'fare':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y4pahkOLUX1D" + }, + "source": [ + "df_titanic[['survived']].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9-VgcNnFNb1" + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'fare')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BIN9WDB1ffb9" + }, + "source": [ + "boxplot_sobreviveu(df_titanic_ss, 'fare')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8FIo9tD1FQ0u" + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'age')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fCqj102y9Kfo" + }, + "source": [ + "# Descrever o dataframe, variável 'fare'\n", + "pd.set_option('display.float_format', lambda x: '%.3f' %x)\n", + "df_titanic_ss['fare'].describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RwVlK5jXe_ya" + }, + "source": [ + "## Mostrar a frequência acumulada!! É mais informativo!!!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SMcvIb1K_69n" + }, + "source": [ + "plt.scatter(range(df_titanic_ss.shape[0]), np.sort(df_titanic_ss['fare'].values)) # A intenção do gráfico é ordenar os valores em df_titanic['fare'] do menor valor para o maior!\n", + "plt.xlabel('indices')\n", + "plt.ylabel('fares')\n", + "plt.title(\"Distribuição da variável fare\")\n", + "\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6nuuTtqHh0Kk" + }, + "source": [ + "Com o gráfico acima, podemos ver quais e quantos são os pontos que estão acima de $\\mu + 3\\sigma$ --> Se usarmos o critério do z-score, todos os pontos acima deste limiar são outliers!\n", + "\n", + " Colocar os gráficos lado a lado: df_titanic e df_titanic_ss!!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7pzTvLleGpWc" + }, + "source": [ + "# Distribuição da variável 'fare' (após StandardScaler)\n", + "sns.distplot(df_titanic_ss['fare'])\n", + "plt.title(\"Distribuição da variável fare\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3Cumr43hjByz" + }, + "source": [ + "# Distribuição da variável 'fare' (após StandardScaler)\n", + "sns.distplot(df_titanic['fare'])\n", + "plt.title(\"Distribuição da variável fare\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oXeTALDBk57N" + }, + "source": [ + "### Calcular a mediana e comparar com a média." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vB7ik75rjJUI" + }, + "source": [ + "df_titanic.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qa28Hc3ZC6FV" + }, + "source": [ + "___\n", + "## Kurtosis\n", + "> Kurtosis é uma medida estatística que define com que intensidade as caudas de uma distribuição diferem das caudas de uma distribuição Normal. Em outras palavras, a curtose identifica se as caudas de uma determinada distribuição contêm valores extremos.\n", + ">> A Kurtosis de uma distribuição Normal padrão é igual a 3. Portanto, se Kurtosis-3 > 0, então isso é o que chamamos de excesso de Kurtosis.\n", + ">>> **Alta Kurtosis é um indicador de que os dados possuem caudas pesadas ou outliers**.\n", + "\n", + "* **Dica muito importante**: Normalize os dados antes!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ynyNHZqmD-tb" + }, + "source": [ + "___\n", + "## Skewness\n", + "> É o grau de distorção da distribuição, ou seja, mede a falta de simetria na distribuição de dados, diferenciando valores extremos em uma cauda versus na outra. Uma distribuição simétrica terá uma assimetria de 0.\n", + "\n", + "![Skewness](https://github.com/MathMachado/Materials/blob/master/Skewness.png?raw=true)\n", + "\n", + "Source: [Skew and Kurtosis: 2 Important Statistics terms you need to know in Data Science](https://codeburst.io/2-important-statistics-terms-you-need-to-know-in-data-science-skewness-and-kurtosis-388fef94eeaa)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uoo3xVhBFixi" + }, + "source": [ + "### Interpretando a Skewness (Rule of Thumb)\n", + "* Se -0.5 < Skewness < 0.5: Dados razoavelmente simétricos;\n", + "* Se -1 < Skewness < -0.5: Dados moderadamente negativa;\n", + "* Se 0.5 < Skewness < 1: Dados moderadamente positiva;\n", + "* Se Skewness < -1: Dados altamente negativa;\n", + "* Se Skewness > 1: Dados altamente positiva.\n", + "\n", + "> **Dica**: Normalize os dados antes!" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oHg3nyjUTiRu" + }, + "source": [ + "# Cálculo das medidas de Skewness e Kurtosis para 'fare'\n", + "print(f\"Skewness: {df_titanic_ss['fare'].skew()}\")\n", + "print(f\"Kurtosis: {df_titanic_ss['fare'].kurt()}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V2jCZLGVH3Qu" + }, + "source": [ + "Olhando para as medidas de Skewness e Kurtosis logo acima, qual a conclusão?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0nnFS8vi_rOe" + }, + "source": [ + "# Distribuição da variável 'age'\n", + "df_titanic_ss['age'].describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h9ZmvO1b_4sF" + }, + "source": [ + "plt.scatter(range(df_titanic_ss.shape[0]), np.sort(df_titanic_ss['age'].values))\n", + "plt.xlabel('index')\n", + "plt.ylabel('age')\n", + "plt.title(\"Distribuição da variável age\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GIAYrDJyCT6r" + }, + "source": [ + "sns.distplot(df_titanic_ss['age'])\n", + "plt.title(\"Distribuição da variável age\")\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "USy48-H2UXqB" + }, + "source": [ + "# Cálculo das medidas de Skewness e Kurtosis para 'age'\n", + "print(f\"Skewness: {df_titanic_ss['age'].skew()}\")\n", + "print(f\"Kurtosis: {df_titanic_ss['age'].kurt()}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ENQaVw2lItVL" + }, + "source": [ + "Olhando para as medidas de Skewness e Kurtosis logo acima, qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nt0PQIjW-wXd" + }, + "source": [ + "___\n", + "## **Isolation Forest Region**\n", + "* Source: [Outlier Detection with Isolation Forest](https://towardsdatascience.com/outlier-detection-with-isolation-forest-3d190448d45e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tM6Xht76KmUN" + }, + "source": [ + "### Anomaly Detection para 'fare'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uFuAUh5S778M", + "outputId": "b2fda534-a71c-4bd0-b16d-444ab30794d6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 380 + } + }, + "source": [ + "# Instanciamento \n", + "isolation_forest = IsolationForest(n_estimators = 100) \n", + "\n", + "# Ajustamento (fit())\n", + "isolation_forest.fit(df_titanic['fare'].values.reshape(-1, 1))\n", + "xx = np.linspace(df_titanic['fare'].min(), df_titanic['fare'].max(), len(df_titanic)).reshape(-1, 1)\n", + "\n", + "anomaly_score = isolation_forest.decision_function(xx)\n", + "outlier = isolation_forest.predict(xx)\n", + "plt.figure(figsize = (10, 4))\n", + "plt.plot(xx, anomaly_score, label = 'anomaly score')\n", + "plt.fill_between(xx.T[0], np.min(anomaly_score), np.max(anomaly_score), where = outlier == -1, color = 'r', alpha = .4, label = 'outlier region')\n", + "plt.legend()\n", + "plt.ylabel('anomaly score')\n", + "plt.xlabel('fare')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1kAAAFzCAYAAADMqcNKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdeXiTVfrG8W/WtulKKW3ZFwEpmwIKgoooKOg4gKIi6oC4L4iKowPu6CiMIojLuIu7oj8RFVdERQcREEXZVSiL0NLS0jVtkib5/ZE2tEChgbRpwv25rl62b968edICvnfPOc8xeL1eLyIiIiIiIhIUxlAXICIiIiIiEkkUskRERERERIJIIUtERERERCSIFLJERERERESCSCFLREREREQkiBSyREREREREgkghS0REREREJIgUskRERERERILIHOoCGjuPx8POnTuJj4/HYDCEuhwREREREQkRr9dLcXExLVq0wGisfbxKIesQdu7cSevWrUNdhoiIiIiINBLbt2+nVatWtT6ukHUI8fHxgO8bmZCQEOJqREREREQkVIqKimjdurU/I9RGIesQqqYIJiQkKGSJiIiIiMghlxGp8YWIiIiIiEgQKWSJiIiIiIgEkUKWiIiIiIhIEGlNloiIiIiEJa/XS0VFBW63O9SlSIQwmUyYzeYj3rpJIUtEREREwo7T6SQrKwu73R7qUiTC2Gw2mjdvjtVqPexrKGSJiIiISFjxeDxkZmZiMplo0aIFVqv1iEceRLxeL06nk9zcXDIzM+nUqdNBNxw+GIUsEREREQkrTqcTj8dD69atsdlsoS5HIkhMTAwWi4WtW7fidDqJjo4+rOuo8YWIiIiIhKXDHWUQOZhg/LnSn0wREREREZEgUsiKUAV2J2t3Foa6DBERERGRo47WZIWbwkJwuWp/3GKBxEROn/Ete+wu5t94Mse3Tmq4+o7Uod5fuCkshE8+gbIy0JQGERGR4LDZoE8fyM313ftIgxl0/vkc360bjz/4YMO9qMEATZrAEXT7a2gKWeGksBCee87339okJsK117LH7gsqizfmNu6QZbfD+vWQkeELV4d6f+HG7YaSEkhKArP+uomIiASFwQBer+/D4wl1NUefhvy+e72++6kw+znrri+cuFy+ABIT4/sNzr7s9v1GgsymRt7O1G6HlSuhbVvf1wd7f+HGboesLN8/Ds2b6zdtIiIiwRIVBSaT7xeY+v9rwzIYfN/7hvq+V4Wsw+RyubCE4M+I5i+FI5sN4uL2/6gMJi733qRvaewh60Bqe3/h9hEJQVFERCRMeL1e7C53SD68Xm+d6/z866855dxzSerYkabHHsu5l17KpsxM/+Nbtm3DkJrKvAULOP2887C1bctxgwaxdMWKGtd5/+OP6XbqqUS1akW7Pn147L//rfF4uz59+PfMmYy98Ubi2rWjbe/efPT55+Tu3s2IsWOJa9eOnqedxk+rVvmfk5efz5hrr6Vlz57Y2ralx2mn8fa8ebW+lwdmzKD7wIH7HT/+9NO5Z/r0Az5nT0EBl153Hc0yMohp04ZO/fox5+23/Y//tXMnY669luTOnYlt144TzjqLZb/84n/8mWee4ZhjjsFqtXLsscfy+uuv17i+wWDgmWeeYfjw4cTGxvLQQw8B8OGHH9K7d2+io6Pp0KEDU6dOpaKiotb3dqQ0khWBihx7075J64BERETkKFBW4aHrEytD8trrJvbBZjHV6dzS0lImXXcdPbt2paS0lHsfeYTzLr+cVd98U6N1+F3TpjHj/vvp1KEDdz38MGOuu44/ly3DbDaz8tdfuejqq7n/9tsZPXIkP6xYwQ3/+hdNk5O5/OKL/deY9dxzPHznndxz223MevZZ/nHjjQw48USuuOQSHr3vPv71wAOMnTCBtd9/j8FgoNzhoE/PnvxrwgQS4uP55Kuv+MeNN3JMu3b07d17v/dyxSWXMHXGDFb88gsn9uoFwC+rV/PbunXMmzPngO//nunTWff773z29tukJCfzZ2YmZeXlAJSUlHDaiBG0bN6cj157jfTUVH7+7Tc8lVMFP/jgA26++WYef/xxhgwZwoIFCxg/fjytWrXi9NNP97/G/fffz/Tp03n88ccxm818//33jB07lieeeIJTTz2VTZs2cc011wBw33331ennFiiFrAhUPWQ5K8Jr/qqIiIhIJBv197/X+Prlxx+nWUYG6zZupHtGhv/4P2+4gb+deSYAU++4g26nnsqfmZl06dSJmc88w+BTT+We224DoPMxx7Bu40YeffrpGiHrnMGDuXbcOADuve02nnnlFU48/nguHD4cgH/ddBP9zzmHXTk5pKel0bJ5c/55443+59901VV88c03vPvhhwcMWa1atGDo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PPXUU6k2bW1t5t/+7d9MQUGBycrKMtOmTTPbt2/vcJ3Nmzeb008/3fh8PlNcXGxuuOEGE4vFDvPdSHe55JJLzNChQ43b7TYlJSVmwoQJqYBljMaIdO6LIUvjRM477zwzYMAA43a7zcCBA815551nPvroo9RxjRFjLGOMycwcmoiIiIiISN+jZ7JERERERETSSCFLREREREQkjRSyRERERERE0kghS0REREREJI0UskRERERERNJIIUtERERERCSNFLJERERERETSSCFLRET6JWMMM2bMoLCwEMuyWLNmTaa7JCIifYReRiwiIv3SSy+9xNlnn82SJUsYPnw4xcXFOJ3OTHdLRET6AP02ERGRfmnjxo0MGDCAk0466ZCvEYvFcLlcaeyViIj0BVouKCIi/c5FF13EVVddRU1NDZZlMWzYMBYuXMjJJ59Mfn4+RUVFnHnmmWzcuDF1zubNm7Esi/nz53Pqqafi9Xp55plnAHjyySc55phj8Hq9jBw5kocffjhTtyYiIj2AlguKiEi/09zczIMPPsjjjz/OypUrcTgcLFu2DMuyGD16NC0tLdx6661s3ryZNWvWYNs2mzdvprKykmHDhnHfffdx/PHH4/V6Wbx4MTfeeCP/9V//xfHHH8/q1au5/PLLuf/++7nwwgszfasiIpIBWi4oIiL9Tl5eHrm5uTgcDsrLywGYPn16hza/+tWvKCkpYe3atYwaNSq1/9prr+Xcc89Nbd92223cd999qX2VlZWsXbuWxx57TCFLRKSf0nJBERERYMOGDZx//vkMHz4cv9/PsGHDAKipqenQbty4camvQ6EQGzdu5NJLLyUnJyf1+elPf9phqaGIiPQvmskSEREBzjrrLIYOHcoTTzxBRUUFyWSSUaNGEY1GO7TLzs5Ofd3S0gLAE088QVVVVYd2Doej+zstIiI9kkKWiIj0e7t27WL9+vU88cQTnHLKKQC8+uqr+z2vrKyMiooKPv74Y6qrq7u7myIi0ksoZImISL9XUFBAUVERjz/+OAMGDKCmpoabbrrpgM69/fbbufrqq8nLy2PKlClEIhHeeustGhsbuf7667u55yIi0hPpmSwREen3bNvm+eefZ9WqVYwaNYrrrruOe+6554DOveyyy3jyySd56qmnOO644zj11FOZN28elZWV3dxrERHpqVTCXUREREREJI00kyUiIiIiIpJGClkiIiIiIiJppJAlIiIiIiKSRgpZIiIiIiIiaaSQJSIiIiIikkYKWSIiIiIiImmkkCUiIiIiIpJGClkiIiIiIiJppJAlIiIiIiKSRgpZIiIiIiIiaaSQJSIiIiIikkYKWSIiIiIiImn0/wGMkw4gtQ7m/gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F2-nWZ3KoPJ8" + }, + "source": [ + "**Conclusão**: anomaly_score > 0 --> Não é outliers. Do contrário, ou seja, se anomaly_score < 0 --> Outlier." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FkhRwo1cgYtK" + }, + "source": [ + "# Vamos avaliar os dados do dataframe para fare > 200, por exemplo\n", + "df_titanic.loc[df_titanic['fare'] > 200].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XFbRlmrYgtTS" + }, + "source": [ + "# Zoom na linha 27\n", + "df_titanic.loc[27]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bH4o-CL-N9Np" + }, + "source": [ + "A região onde os dados têm baixa probabilidade de aparecer fica no lado direito da distribuição." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7HK9cBvwGOqG" + }, + "source": [ + "### Anomaly Detection para 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PoDzs4DTFSY-" + }, + "source": [ + "isolation_forest = IsolationForest(n_estimators = 100)\n", + "isolation_forest.fit(df_titanic['age'].values.reshape(-1, 1))\n", + "xx = np.linspace(df_titanic['age'].min(), df_titanic['age'].max(), len(df_titanic)).reshape(-1, 1)\n", + "anomaly_score = isolation_forest.decision_function(xx)\n", + "outlier = isolation_forest.predict(xx)\n", + "plt.figure(figsize = (10, 4))\n", + "plt.plot(xx, anomaly_score, label='anomaly score')\n", + "plt.fill_between(xx.T[0], np.min(anomaly_score), np.max(anomaly_score), where = outlier == -1, color = 'r', alpha = .4, label = 'outlier region')\n", + "plt.legend()\n", + "plt.ylabel('anomaly score')\n", + "plt.xlabel('age')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GivF2cSFS208" + }, + "source": [ + "Observe no gráfico acima que há duas regiões em que os dados têm baixa probabilidade de aparecer: uma no lado esquerdo da distribuição, outra no lado direito da distribuição." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XtizVySOlPUT" + }, + "source": [ + "# Avaliando os dados da cauda esquerda\n", + "df_titanic.loc[df_titanic['age'] < 15].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YGnZlzDDlyZO" + }, + "source": [ + "# Zoom na linha 3\n", + "df_titanic.loc[10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YVhBJua_sG-u" + }, + "source": [ + "# Avaliando dados da cauda direita\n", + "df_titanic.loc[df_titanic['age'] > 65].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LRkUWSletcq-" + }, + "source": [ + "# Zoom na linha 96\n", + "df_titanic.loc[96]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JQKECo0BSefE" + }, + "source": [ + "sns.regplot(x = \"age\", y = \"fare\", data = df_titanic_ss)\n", + "sns.despine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AChZpGY4Ghc9" + }, + "source": [ + "cols = ['fare', 'age']\n", + "df_titanic_ss[cols].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s2tddgHcUiAF" + }, + "source": [ + "___\n", + "## **CBLOF - Cluster-based Local Outlier Factor**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbJ7k1bbbfr4" + }, + "source": [ + "# Normalizar as variáveis 'age' e 'fare'\n", + "df_titanic_ss = df_titanic.copy()\n", + "df_titanic_ss[['fare', 'age']] = MinMaxScaler().fit_transform(df_titanic_ss[['fare', 'age']])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "il0LFdCFJEsw" + }, + "source": [ + "X1 = df_titanic_ss['age'].values.reshape(-1, 1)\n", + "X2 = df_titanic_ss['fare'].values.reshape(-1, 1)\n", + "X = np.concatenate((X1,X2), axis = 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QtBn0u7CKlS6" + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = CBLOF(contamination = outliers_fraction, check_estimator = False, random_state = 0)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "\n", + "plt.figure(figsize = (8, 8))\n", + "\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + "\n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS:',n_outliers,'INLIERS:',n_inliers)\n", + " \n", + "# Use threshold para definir um ponto como inlier ou outlier\n", + "# threshold = stats.scoreatpercentile(scores_pred,100 * outliers_fraction)\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# Calcula o Anomaly Score\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "\n", + "plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 7), cmap = plt.cm.Blues_r)\n", + " \n", + "# Desenha a linha vermelha a partir do qual Anomaly Score = thresold\n", + "a = plt.contour(xx, yy, Z, levels = [threshold], linewidths = 2, colors = 'red')\n", + " \n", + "# Região Azul onde threshold < Anomaly Score < max(Anomaly score)\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()], colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c = 'white', s = 20, edgecolor = 'k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c = 'black', s = 20, edgecolor = 'k')\n", + " \n", + "plt.axis('tight') \n", + "plt.legend([a.collections[0], b, c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop = matplotlib.font_manager.FontProperties(size = 10), loc = 'upper center', frameon = False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Cluster-based Local Outlier Factor (CBLOF)')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O7NmDgjRm5EE" + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HIRxOj93nVXu" + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "euxK-4K1oKs0" + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nuNxqgWMtMHC" + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bLIZcvyuuU2R" + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fFd-D1HTVhE7" + }, + "source": [ + "___\n", + "## **HBOS - Histogram-based Outlier Detection**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q5Hh5iMEXuhM" + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = HBOS(contamination = outliers_fraction)\n", + "clf.fit(X)\n", + "\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1, 1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1, 1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1, 1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1, 1)\n", + " \n", + "print('OUTLIERS:', n_outliers, 'INLIERS:', n_inliers)\n", + " \n", + "# threshold define se um ponto será outlier ou inlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# Calcula o Anomaly score\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "\n", + "# Define a região azul tal que min(Anomaly score) < threshold\n", + "plt.contourf(xx, yy, Z, levels = np.linspace(Z.min(), threshold, 7), cmap = plt.cm.Blues_r)\n", + " \n", + "# Desenha a linha a partir do queal Anomaly score = thresold\n", + "a = plt.contour(xx, yy, Z, levels = [threshold], linewidths = 2, colors = 'red')\n", + " \n", + "# Define a região laranja a partir do qual threshold < Anomaly score < max(Anomaly score)\n", + "plt.contourf(xx, yy, Z, levels = [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight') \n", + " \n", + "plt.legend([a.collections[0], b, c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size = 10), loc ='upper center', frameon = False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Histogram-base Outlier Detection (HBOS)')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gHRoON0BnLVb" + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YblU2tnxnXi7" + }, + "source": [ + "# Zoom na linha 689\n", + "df_titanic.loc[689]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkWj5aQ-uzxB" + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EVy5NDrFujgD" + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hgcp_LU6ujgJ" + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KyPUT9JmWeN-" + }, + "source": [ + "___\n", + "## **Isolation Forest**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Lrx85bG0YOqM" + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = IForest(contamination = outliers_fraction,random_state = 0)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "# fare - inlier feature 1, age - inlier feature 2\n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "# fare - outlier feature 1, age - outlier feature 2\n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS: ', n_outliers,'INLIERS: ', n_inliers)\n", + " \n", + "# threshold value to consider a datapoint inlier or outlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# decision function calculates the raw anomaly score for every point\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "# fill blue map colormap from minimum anomaly score to threshold value\n", + "plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7),cmap=plt.cm.Blues_r)\n", + " \n", + "# draw red contour line where anomaly score is equal to thresold\n", + "a = plt.contour(xx, yy, Z, levels= [threshold],linewidths=2, colors='red')\n", + " \n", + "# fill orange contour lines where range of anomaly score is from threshold to maximum anomaly score\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight')\n", + "plt.legend([a.collections[0], b,c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size = 10), loc='upper center', frameon= False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol=5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('Isolation Forest')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HLVraGcCnNTA" + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "y0WBmFOonZKY" + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "auSy5b6Du3PH" + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fIQg2D6fuoSG" + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pNUds1oDuoSO" + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QbpzXB2RV4sq" + }, + "source": [ + "___\n", + "## **KNN - K-Nearest Neighbors**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6gtIWWbRYxEj" + }, + "source": [ + "outliers_fraction = 0.01\n", + "xx , yy = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))\n", + "clf = KNN(contamination = outliers_fraction)\n", + "clf.fit(X)\n", + "# predict raw anomaly score\n", + "scores_pred = clf.decision_function(X) * -1\n", + " \n", + "# prediction of a datapoint category outlier or inlier\n", + "y_pred = clf.predict(X)\n", + "n_inliers = len(y_pred) - np.count_nonzero(y_pred)\n", + "n_outliers = np.count_nonzero(y_pred == 1)\n", + "plt.figure(figsize = (8, 8))\n", + "# copy of dataframe\n", + "df1 = df_titanic_ss\n", + "df1['outlier'] = y_pred.tolist()\n", + " \n", + "inliers_fare = np.array(df1['fare'][df1['outlier'] == 0]).reshape(-1,1)\n", + "inliers_age = np.array(df1['age'][df1['outlier'] == 0]).reshape(-1,1)\n", + " \n", + "outliers_fare = df1['fare'][df1['outlier'] == 1].values.reshape(-1,1)\n", + "outliers_age = df1['age'][df1['outlier'] == 1].values.reshape(-1,1)\n", + " \n", + "print('OUTLIERS: ',n_outliers, 'INLIERS: ', n_inliers)\n", + " \n", + "# threshold value to consider a datapoint inlier or outlier\n", + "threshold = percentile(scores_pred, 100 * outliers_fraction)\n", + " \n", + "# decision function calculates the raw anomaly score for every point\n", + "Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) * -1\n", + "Z = Z.reshape(xx.shape)\n", + "# fill blue map colormap from minimum anomaly score to threshold value\n", + "plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), threshold, 7),cmap=plt.cm.Blues_r)\n", + " \n", + "# draw red contour line where anomaly score is equal to thresold\n", + "a = plt.contour(xx, yy, Z, levels= [threshold],linewidths=2, colors='red')\n", + " \n", + "# fill orange contour lines where range of anomaly score is from threshold to maximum anomaly score\n", + "plt.contourf(xx, yy, Z, levels= [threshold, Z.max()],colors='orange')\n", + "b = plt.scatter(inliers_fare, inliers_age, c='white',s=20, edgecolor='k')\n", + " \n", + "c = plt.scatter(outliers_fare, outliers_age, c='black',s=20, edgecolor='k')\n", + " \n", + "plt.axis('tight') \n", + " \n", + "plt.legend([a.collections[0], b,c], ['learned decision function', 'inliers', 'outliers'],\n", + " prop=matplotlib.font_manager.FontProperties(size=10), loc='upper center', frameon= False, bbox_to_anchor = (0.5, -0.05),\n", + " fancybox = True, shadow = True, ncol = 5)\n", + " \n", + "plt.xlim((0, 1))\n", + "plt.ylim((0, 1))\n", + "plt.title('K-Nearest Neighbors (KNN)')\n", + "plt.show();" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6B-L7MwXg25Z" + }, + "source": [ + "df1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gvXGH0BHBBNN" + }, + "source": [ + "# Zoom em alguns outliers...\n", + "df1.loc[df1['outlier'] == 1].head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MYbNaaO7D3NY" + }, + "source": [ + "# Zoom na linha 679\n", + "df_titanic.loc[679]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-juEvWvru5jp" + }, + "source": [ + "# Algumas medidas para compararmos\n", + "df_resumo = df_titanic.groupby('sex').agg({'age': ['mean'], 'fare': ['mean']}).round(0)\n", + "df_resumo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "B6NXG6oDusSg" + }, + "source": [ + "# Média Geral de 'age'\n", + "round(df_titanic['age'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cgHJb3iBusSl" + }, + "source": [ + "# Média Geral de 'fare'\n", + "round(df_titanic['fare'].mean())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1w7MIkoAG2Qr" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "Para cada um dos dataframes a seguir, faça uma análise de outlier utilizando uma das técnicas apresentadas e explique seus resultados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ep_Z3iQIG56r" + }, + "source": [ + "## Exercício 1 - Predict Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-Lvzrt7HN2l" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X = cancer['data']\n", + "y = cancer['target']\n", + "\n", + "df_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_cancer['target'] = df_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEHLrU0gHRtu" + }, + "source": [ + "## Exercício 2 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8G9GZnubHYjy" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X = boston['data']\n", + "y = boston['target']\n", + "\n", + "df_boston = pd.DataFrame(np.c_[X, y], columns = np.append(boston['feature_names'], ['target']))\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlAdIYfmHaE8" + }, + "source": [ + "## Exercício 3 - Iris\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rke4C3wFHfYU" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns = np.append(iris['feature_names'], ['target']))\n", + "df_iris['target'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6qn3gC4NHj-p" + }, + "source": [ + "## Exercícios 4 - Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P-esq5TSHnf6" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X = diabetes['data']\n", + "y = diabetes['target']\n", + "\n", + "df_diabetes = pd.DataFrame(np.c_[X, y], columns = np.append(diabetes['feature_names'], ['target']))\n", + "df_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_5_Feature_Selection_hs.ipynb b/Notebooks/NB10_04__3DP_5_Feature_Selection_hs.ipynb new file mode 100644 index 000000000..e190813dd --- /dev/null +++ b/Notebooks/NB10_04__3DP_5_Feature_Selection_hs.ipynb @@ -0,0 +1,6081 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + }, + "colab": { + "name": "NB10_04__3DP_5_Feature_Selection.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cka1jqOwy6KT" + }, + "source": [ + "

3DP_5 - FEATURE SELECTION

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3aYp_plmy17y" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rSFnHHQUKDX5" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Desenvolver t-SNE.\n", + "* https://towardsdatascience.com/feature-engineering-for-machine-learning-3a5e293a5114" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "arSNhd_2KHL6" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Feature Selection in Python — Recursive Feature Elimination](https://towardsdatascience.com/feature-selection-in-python-recursive-feature-elimination-19f1c39b8d15)\n", + "* [Feature Selection with sklearn and Pandas](https://towardsdatascience.com/feature-selection-with-pandas-e3690ad8504b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ngLc7b9XiKxN" + }, + "source": [ + "___\n", + "# **3DP_FEATURE SELECTION**\n", + "## Introdução à Feature Selection\n", + "> Nosso objetivo com Feature Engineering será:\n", + "* Deletar colunas irrelevantes;\n", + "* Deletar colunas com baixa correlação com a variável-target;\n", + "* Deletar colunas com baixa variância;\n", + "* Deletar colunas com muitos NaN's.\n", + "\n", + "* Sugestões:\n", + " * Normalize colunas numéricas;\n", + " * Aplique LabelEncoding (colunas numéricas) ou One Hot Encoding (colunas categóricas).\n", + "\n", + "![FeatureSelection](https://github.com/MathMachado/Materials/blob/master/FeatureSelection.png?raw=true)\n", + "\n", + "[Fonte](https://medium.com/@sundarstyles89/weight-of-evidence-and-information-value-using-python-6f05072e83eb)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9JCQatsiKxR" + }, + "source": [ + "from sklearn import feature_selection\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9U6Az5qpiKxU" + }, + "source": [ + "___\n", + "# **VarianceThreshold**\n", + "* Drop variáveis/features cuja variância seja inferior a um determinado threshold;\n", + "* Este é um método não-supervisionado, isto é, a variável rotulada (variável-resposta ou variável target) não entra e ação;\n", + "* **Intuição**: \n", + " * Features/variáveis com baixa variância contem baixa informação;\n", + "* **Como funciona**:\n", + " * Calcula a variância para cada feature/variável e então deleta a coluna/variável com baixa variância\n", + "* **Cuidados**:\n", + " * Assegure-se que as features/variáveis tenham a mesma escala. Ou seja, use StandardScaler() ou MinMaxScaler() para colocar as variáveis na mesma escala." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "euWJlVAViKxV", + "outputId": "0a16d5aa-7e5b-4db1-b5cc-e1a13f730cff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + } + }, + "source": [ + "df = pd.DataFrame(\n", + " {'sexo': ['m', 'm', 'f', 'm', 'm', 'm', 'm', 'm'], \n", + " 'b': [1, 2, 3, 1, 2, 1, 1, 1], \n", + " 'c': [1, 2, 3, 1, 2, 1, 1, 1]})\n", + "\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sexobc
0m11
1m22
2f33
3m11
4m22
5m11
6m11
7m11
\n", + "
" + ], + "text/plain": [ + " sexo b c\n", + "0 m 1 1\n", + "1 m 2 2\n", + "2 f 3 3\n", + "3 m 1 1\n", + "4 m 2 2\n", + "5 m 1 1\n", + "6 m 1 1\n", + "7 m 1 1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 212 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1rvj2MZ6Jtgq" + }, + "source": [ + "A seguir, usamos [LabelEncoder](sklearn.preprocessing.LabelEncoder) para a coluna 'sexo':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I6L5L_wtTSUe" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "le = LabelEncoder()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS2v_GnbiKxi", + "outputId": "5d026279-9b0f-4e3d-c9ac-3a9bff1be40e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + } + }, + "source": [ + "# Aplica o LabelEncoder à coluna 'sexo':\n", + "df['sexo'] = le.fit_transform(df['sexo'])\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sexobc
0111
1122
2033
3111
4122
5111
6111
7111
\n", + "
" + ], + "text/plain": [ + " sexo b c\n", + "0 1 1 1\n", + "1 1 2 2\n", + "2 0 3 3\n", + "3 1 1 1\n", + "4 1 2 2\n", + "5 1 1 1\n", + "6 1 1 1\n", + "7 1 1 1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 214 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1w-_VsJuWVHN", + "outputId": "3ad5cb6b-408e-4fd1-ba2e-2a98d7f55dda", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Calculando as variâncias de cada Feature/variável:\n", + "l_variaveis= ['sexo', 'b', 'c']\n", + "print(f'Variância das variáveis do dataframe df:')\n", + "for s_Var in l_variaveis:\n", + " print(f'{s_Var}: {round(df[s_Var].var(),2)}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Variância das variáveis do dataframe df:\n", + "sexo: 0.12\n", + "b: 0.57\n", + "c: 0.57\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3IITDmqUiKxo", + "outputId": "16e79dc1-1519-4750-f397-327b5455781d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Selecionar atributos cuja variância seja maior que 0.20:\n", + "vt = feature_selection.VarianceThreshold(threshold= .20)\n", + "vt.fit_transform(df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1, 1],\n", + " [2, 2],\n", + " [3, 3],\n", + " [1, 1],\n", + " [2, 2],\n", + " [1, 1],\n", + " [1, 1],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 216 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tAOL215MiKxu", + "outputId": "cf1d0ae2-8fd9-4971-b5a3-8b246bb39ed0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Variância calculada pela VarianceThreshold()\n", + "vt.variances_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.109375, 0.5 , 0.5 ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 217 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yntaZtd98boc" + }, + "source": [ + "### O que aconteceu aqui? Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FXyfpmWtiKyB" + }, + "source": [ + "___\n", + "# **ANOVA (Analysis Of Variance) com f_classif**\n", + "* Aplica-se aos casos em que as colunas a serem testadas sejam numéricas por natureza e a variável-target seja discreta por natureza;\n", + "* ANOVA é um teste que visa medir diferença entre grupos/experimentos. Aqui, **o propósito da ANOVA é testar se as colunas numéricas testadas são diferentes**. Obviamente que ao identificarmos colunas semelhantes, então podemos reduzir o número de colunas para evitarmos multicolinearidade, overfitting." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yB7TC9VKiKyC" + }, + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "df_cancer = load_breast_cancer()\n", + "X_cancer = df_cancer.data\n", + "y_cancer = df_cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "N2_mE0Z5xxvL", + "outputId": "5b255dcb-ec6e-4ee4-e0f8-d0d89a14fc64", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_cancer" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1.799e+01, 1.038e+01, 1.228e+02, ..., 2.654e-01, 4.601e-01,\n", + " 1.189e-01],\n", + " [2.057e+01, 1.777e+01, 1.329e+02, ..., 1.860e-01, 2.750e-01,\n", + " 8.902e-02],\n", + " [1.969e+01, 2.125e+01, 1.300e+02, ..., 2.430e-01, 3.613e-01,\n", + " 8.758e-02],\n", + " ...,\n", + " [1.660e+01, 2.808e+01, 1.083e+02, ..., 1.418e-01, 2.218e-01,\n", + " 7.820e-02],\n", + " [2.060e+01, 2.933e+01, 1.401e+02, ..., 2.650e-01, 4.087e-01,\n", + " 1.240e-01],\n", + " [7.760e+00, 2.454e+01, 4.792e+01, ..., 0.000e+00, 2.871e-01,\n", + " 7.039e-02]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 219 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t0QYORbSiKyL" + }, + "source": [ + "chi2, p_value = feature_selection.f_classif(X_cancer, y_cancer)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BC6y7etiKyP", + "outputId": "b6cf6b7d-77d9-49fa-96f1-10983adf21b8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(chi2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([647., 118., 697., 573., 84., 313., 534., 862., 70., 0., 269.,\n", + " 0., 254., 244., 3., 53., 39., 113., 0., 3., 861., 150.,\n", + " 898., 662., 122., 304., 437., 964., 119., 66.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 221 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYSOfeH4iKyW" + }, + "source": [ + "* **Comentário**: Acima, cada valor representa a importância de uma feature/coluna ==> **Quanto maior, melhor!**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k1fHrPM4upex", + "outputId": "690c1ed2-9c4f-4518-a356-6486b3ffcf63", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.76, 0. ,\n", + " 0.84, 0. , 0. , 0.11, 0. , 0. , 0. , 0.88, 0.06, 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 222 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JYciSVkMW8f" + }, + "source": [ + "* **Comentário**: Acima, os p_value's associados à cada valor de chi2 ==> **Quanto menor, melhor!**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1YVBLc7eu6_H" + }, + "source": [ + "## **Conclusão**: **Foco no p_value**. Se p_value < 0.05 ==> variável significativa/relevante para o modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r29_gmCgiKyY" + }, + "source": [ + "___\n", + "# **Univariate Regression Test using f_regression**\n", + "* Modelo Linear para testar o efeito individual de cada uma das variáveis regressoras;\n", + "* **Como funciona**:\n", + " * Usa a correlação entre cada variável e variável-target;\n", + " * F-test calcula a dependência linear;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IDzu3kCiKyZ", + "outputId": "b4941bbd-ebe8-4718-81b0-48666ada1d44", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.datasets import california_housing\n", + "house_data = california_housing.fetch_california_housing()\n", + "X_house, y_house = house_data.data, house_data.target\n", + "\n", + "X_house" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 8.3252 , 41. , 6.98412698, ..., 2.55555556,\n", + " 37.88 , -122.23 ],\n", + " [ 8.3014 , 21. , 6.23813708, ..., 2.10984183,\n", + " 37.86 , -122.22 ],\n", + " [ 7.2574 , 52. , 8.28813559, ..., 2.80225989,\n", + " 37.85 , -122.24 ],\n", + " ...,\n", + " [ 1.7 , 17. , 5.20554273, ..., 2.3256351 ,\n", + " 39.43 , -121.22 ],\n", + " [ 1.8672 , 18. , 5.32951289, ..., 2.12320917,\n", + " 39.43 , -121.32 ],\n", + " [ 2.3886 , 16. , 5.25471698, ..., 2.61698113,\n", + " 39.37 , -121.24 ]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 223 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1DS9T6WXw8qN", + "outputId": "038178a6-3f44-49da-f49c-695e8ff999c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_house # Variável contínua" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4.526, 3.585, 3.521, ..., 0.923, 0.847, 0.894])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 224 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uKYhjpEViKyl" + }, + "source": [ + "F, p_value = feature_selection.f_regression(X_house, y_house)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEqZ3I4jiKyp", + "outputId": "44e87de3-1abc-4664-817b-93801dc8eb36", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(F, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1.855657e+04, 2.328400e+02, 4.877600e+02, 4.511000e+01,\n", + " 1.255000e+01, 1.164000e+01, 4.380100e+02, 4.370000e+01])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 226 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rsaf7y8MiKyt" + }, + "source": [ + "### **Comentários**: Colunas com alto F-values tem maior poder preditivo. Portanto, **quanto maior, melhor**." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Fh80Xf8KG-Vj", + "outputId": "5e7aaa4e-563d-4643-b5f7-a7c6a16e5c21", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 0., 0., 0.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 227 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LKutBVPIxTP2", + "outputId": "c1a988e0-a69b-4642-b258-720024c66068", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 0., 0., 0.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 228 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DD-JKUQ1xjR8" + }, + "source": [ + "### **Conclusão**: **Foco no p_value**. Se p_value < 0.05 ==> variável significativa/relevante para o modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xvIXLHK9iKz8" + }, + "source": [ + "___\n", + "# **SelectFromModel**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "p0mtUVnjiKz8" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "boston = load_boston()\n", + "X_boston, y_boston = boston.data, boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WY1c2U10iK0A" + }, + "source": [ + "from sklearn.linear_model import LinearRegression" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3SJDM-Bxc_UF", + "outputId": "0096e7b9-84c4-4bfd-f6ea-06edb31747bc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Observe abaixo que a variável-target é float. Portanto, é um problema de regressão\n", + "y_boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,\n", + " 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,\n", + " 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,\n", + " 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,\n", + " 21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,\n", + " 35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,\n", + " 19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,\n", + " 20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,\n", + " 23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,\n", + " 33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,\n", + " 21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,\n", + " 20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,\n", + " 23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,\n", + " 15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,\n", + " 17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,\n", + " 25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,\n", + " 23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,\n", + " 32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,\n", + " 34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,\n", + " 20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,\n", + " 26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,\n", + " 31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,\n", + " 22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,\n", + " 42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,\n", + " 36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,\n", + " 32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,\n", + " 20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,\n", + " 20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,\n", + " 22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,\n", + " 21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,\n", + " 19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,\n", + " 32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,\n", + " 18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,\n", + " 16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,\n", + " 13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3, 8.8,\n", + " 7.2, 10.5, 7.4, 10.2, 11.5, 15.1, 23.2, 9.7, 13.8, 12.7, 13.1,\n", + " 12.5, 8.5, 5. , 6.3, 5.6, 7.2, 12.1, 8.3, 8.5, 5. , 11.9,\n", + " 27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3, 7. , 7.2, 7.5, 10.4,\n", + " 8.8, 8.4, 16.7, 14.2, 20.8, 13.4, 11.7, 8.3, 10.2, 10.9, 11. ,\n", + " 9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4, 9.6, 8.7, 8.4, 12.8,\n", + " 10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,\n", + " 15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,\n", + " 19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,\n", + " 29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,\n", + " 20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,\n", + " 23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 231 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2zNpau9HiK0C" + }, + "source": [ + "ml = LinearRegression()\n", + "sfm = feature_selection.SelectFromModel(ml, threshold = 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "62vOFTVViK0D", + "outputId": "a4a64f62-a280-4d40-8188-82b49ceda42d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Dataframe com as colunas mais relevantes\n", + "sfm.fit_transform(X_boston, y_boston).shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(506, 7)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 233 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8_j7HRZiK0J", + "outputId": "9a732d60-aa2f-43d2-8c94-c5ff85b3a694", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Dados originais\n", + "X_boston.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(506, 13)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 234 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yX5oufYkcrH7" + }, + "source": [ + "### **Conclusão**: Houve uma redução de 13 para 7 colunas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FaGrKVl0Re2A" + }, + "source": [ + "Abaixo, o indicador das colunas que foram selecionadas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hYVIANETRE2p", + "outputId": "e31de91e-1f8e-4a20-c2f3-891a43632b44", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "l_variaveis_selecionadas = sfm.get_support()\n", + "l_variaveis_selecionadas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([False, False, False, True, True, True, False, True, True,\n", + " False, True, False, True])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 235 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ol88OWzaVpJi" + }, + "source": [ + "___\n", + "# **Análise de Correlação**\n", + "* É sempre uma boa ideia eliminar colunas altamente correlacionadas do dataframe, pois colunas altamente correlacionadas fornecem a mesma informação.\n", + "\n", + "Fonte: [Better Heatmaps and Correlation Matrix Plots in Python](https://towardsdatascience.com/better-heatmaps-and-correlation-matrix-plots-in-python-41445d0f2bec)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KWBe1v_6V5HB" + }, + "source": [ + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "from sklearn.datasets import load_breast_cancer\n", + "df_cancer = load_breast_cancer()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vDz4Byzk8yA9" + }, + "source": [ + "X_cancer = pd.DataFrame(df_cancer.data)\n", + "y_cancer = df_cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XIPITCn4cgjs" + }, + "source": [ + "Usando a correlação de Pearson:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0vHleiMlxuCG", + "outputId": "ee6e2dd6-a45f-4527-a548-52b3c708bc64", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 955 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao = X_cancer.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k = 1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01234567891011121314151617181920212223242526272829
0NaN0.3237820.9978550.9873570.1705810.5061240.6767640.8225290.1477410.3116310.6790900.0973170.6741720.7358640.2226000.2060000.1942040.3761690.1043210.0426410.9695390.2970080.9651370.9410820.1196160.4134630.5269110.7442140.1639530.007066
1NaNNaN0.3295330.3210860.0233890.2367020.3024180.2934640.0714010.0764370.2758690.3863580.2816730.2598450.0066140.1919750.1432930.1638510.0091270.0544580.3525730.9120450.3580400.3435460.0775030.2778300.3010250.2953160.1050080.119205
2NaNNaNNaN0.9865070.2072780.5569360.7161360.8509770.1830270.2614770.6917650.0867610.6931350.7449830.2026940.2507440.2280820.4072170.0816290.0055230.9694760.3030380.9703870.9415500.1505490.4557740.5638790.7712410.1891150.051019
3NaNNaNNaNNaN0.1770280.4985020.6859830.8232690.1512930.2831100.7325620.0662800.7266280.8000860.1667770.2125830.2076600.3723200.0724970.0198870.9627460.2874890.9591200.9592130.1235230.3904100.5126060.7220170.1435700.003738
4NaNNaNNaNNaNNaN0.6591230.5219840.5536950.5577750.5847920.3014670.0684060.2960920.2465520.3323750.3189430.2483960.3806760.2007740.2836070.2131200.0360720.2388530.2067180.8053240.4724680.4349260.5030530.3943090.499316
5NaNNaNNaNNaNNaNNaN0.8831210.8311350.6026410.5653690.4974730.0462050.5489050.4556530.1352990.7387220.5705170.6422620.2299770.5073180.5353150.2481330.5902100.5096040.5655410.8658090.8162750.8155730.5102230.687382
6NaNNaNNaNNaNNaNNaNNaN0.9213910.5006670.3367830.6319250.0762180.6603910.6174270.0985640.6702790.6912700.6832600.1780090.4493010.6882360.2998790.7295650.6759870.4488220.7549680.8841030.8613230.4094640.514930
7NaNNaNNaNNaNNaNNaNNaNNaN0.4624970.1669170.6980500.0214800.7106500.6902990.0276530.4904240.4391670.6156340.0953510.2575840.8303180.2927520.8559230.8096300.4527530.6674540.7523990.9101550.3757440.368661
8NaNNaNNaNNaNNaNNaNNaNNaNNaN0.4799210.3033790.1280530.3138930.2239700.1873210.4216590.3426270.3932980.4491370.3317860.1857280.0906510.2191690.1771930.4266750.4732000.4337210.4302970.6998260.438413
9NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0001110.1641740.0398300.0901700.4019640.5598370.4466300.3411980.3450070.6881320.2536910.0512690.2051510.2318540.5049420.4587980.3462340.1753250.3340190.767297
10NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2132470.9727940.9518300.1645140.3560650.3323580.5133460.2405670.2277540.7150650.1947990.7196840.7515480.1419190.2871030.3805850.5310620.0945430.049559
11NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2231710.1115670.3972430.2317000.1949980.2302830.4116210.2797230.1116900.4090030.1022420.0831950.0736580.0924390.0689560.1196380.1282150.045655
12NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.9376550.1510750.4163220.3624820.5562640.2664870.2441430.6972010.2003710.7210310.7307130.1300540.3419190.4188990.5548970.1099300.085433
13NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0751500.2848400.2708950.4157300.1341090.1270710.7573730.1964970.7612130.8114080.1253890.2832570.3851000.5381660.0741260.017539
14NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3366960.2686850.3284290.4135060.4273740.2306910.0747430.2173040.1821950.3144570.0555580.0582980.1020070.1073420.101480
15NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8012680.7440830.3947130.8032690.2046070.1430030.2605160.1993710.2273940.6787800.6391470.4832080.2778780.590973
16NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.7718040.3094290.7273720.1869040.1002410.2266800.1883530.1684810.4848580.6625640.4404720.1977880.439329
17NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3127800.6110440.3581270.0867410.3949990.3422710.2153510.4528880.5495920.6024500.1431160.310655
18NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3690780.1281210.0774730.1037530.1103430.0126620.0602550.0371190.0304130.3894020.078079
19NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0374880.0031950.0010000.0227360.1705680.3901590.3799750.2152040.1110940.591328
20NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3599210.9937080.9840150.2165740.4758200.5739750.7874240.2435290.093492
21NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3650980.3458420.2254290.3608320.3683660.3597550.2330270.219122
22NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.9775780.2367750.5294080.6183440.8163220.2694930.138957
23NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2091450.4382960.5433310.7474190.2091460.079647
24NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.5681870.5185230.5476910.4938380.617624
25NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8922610.8010800.6144410.810455
26NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8554340.5325200.686511
27NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.5025280.511114
28NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.537848
29NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 ... 26 27 28 29\n", + "0 NaN 0.323782 0.997855 0.987357 ... 0.526911 0.744214 0.163953 0.007066\n", + "1 NaN NaN 0.329533 0.321086 ... 0.301025 0.295316 0.105008 0.119205\n", + "2 NaN NaN NaN 0.986507 ... 0.563879 0.771241 0.189115 0.051019\n", + "3 NaN NaN NaN NaN ... 0.512606 0.722017 0.143570 0.003738\n", + "4 NaN NaN NaN NaN ... 0.434926 0.503053 0.394309 0.499316\n", + "5 NaN NaN NaN NaN ... 0.816275 0.815573 0.510223 0.687382\n", + "6 NaN NaN NaN NaN ... 0.884103 0.861323 0.409464 0.514930\n", + "7 NaN NaN NaN NaN ... 0.752399 0.910155 0.375744 0.368661\n", + "8 NaN NaN NaN NaN ... 0.433721 0.430297 0.699826 0.438413\n", + "9 NaN NaN NaN NaN ... 0.346234 0.175325 0.334019 0.767297\n", + "10 NaN NaN NaN NaN ... 0.380585 0.531062 0.094543 0.049559\n", + "11 NaN NaN NaN NaN ... 0.068956 0.119638 0.128215 0.045655\n", + "12 NaN NaN NaN NaN ... 0.418899 0.554897 0.109930 0.085433\n", + "13 NaN NaN NaN NaN ... 0.385100 0.538166 0.074126 0.017539\n", + "14 NaN NaN NaN NaN ... 0.058298 0.102007 0.107342 0.101480\n", + "15 NaN NaN NaN NaN ... 0.639147 0.483208 0.277878 0.590973\n", + "16 NaN NaN NaN NaN ... 0.662564 0.440472 0.197788 0.439329\n", + "17 NaN NaN NaN NaN ... 0.549592 0.602450 0.143116 0.310655\n", + "18 NaN NaN NaN NaN ... 0.037119 0.030413 0.389402 0.078079\n", + "19 NaN NaN NaN NaN ... 0.379975 0.215204 0.111094 0.591328\n", + "20 NaN NaN NaN NaN ... 0.573975 0.787424 0.243529 0.093492\n", + "21 NaN NaN NaN NaN ... 0.368366 0.359755 0.233027 0.219122\n", + "22 NaN NaN NaN NaN ... 0.618344 0.816322 0.269493 0.138957\n", + "23 NaN NaN NaN NaN ... 0.543331 0.747419 0.209146 0.079647\n", + "24 NaN NaN NaN NaN ... 0.518523 0.547691 0.493838 0.617624\n", + "25 NaN NaN NaN NaN ... 0.892261 0.801080 0.614441 0.810455\n", + "26 NaN NaN NaN NaN ... NaN 0.855434 0.532520 0.686511\n", + "27 NaN NaN NaN NaN ... NaN NaN 0.502528 0.511114\n", + "28 NaN NaN NaN NaN ... NaN NaN NaN 0.537848\n", + "29 NaN NaN NaN NaN ... NaN NaN NaN NaN\n", + "\n", + "[30 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 238 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gDxrqpPXxuCM", + "outputId": "ebd4ba38-df7c-4775-c12d-b20102a2e73c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 989 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize = (20, 17)) \n", + "mask = np.zeros_like(X_cancer.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(X_cancer.corr().abs(), mask = mask, ax = ax, cmap ='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 239 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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afqH2kFERERERP77GNaJtp+vA+8u4tQG/IbPPq6bdfwna8BQ7+721zVfn/p5pMroyD+2hOX3cvl4t1SlLn1fVnMH+lRavLKsXnInnpNfe6FTpGWzxHrLFhEREZHf5S/9jMcjc6ae9j5tXWhw7g318rnU30INEREREREREflL0SCDiIiIiIiIiNQJDTKIiIiIiIiISJ3w/nl9IiIiIiIiIv9rDN2bPxlqLRERERERERGpExpkEBEREREREZE6oeUSIiIiIiIiIjWx6d78yVBriYiIiIiIiEid0CCDiIiIiIiIiNQJDTKIiIiIiIiISJ045XsyjCyacqojqik5Z+JpzwS45shL9ZJr5hTUS+4s30n1ktsnafdpzzwn/+PTngkwPP5AveR+sO/2esl9c/JC4PR/vou/7HfaM0VERETkT8Iw6vsK/lQ0k0FERERERERE6oQGGURERERERESkTmiQQURERERERETqxCnfk0FERERERETkT8vQvfmTodYSERERERERkTqhQQYRERERERERqRNaLiEiIiIiIiJSEz3C8qRoJoOIiIiIiIiI1AkNMoiIiIiIiIhIndAgg4iIiIhEVgzAAAAgAElEQVSIiIjUCe3JICIiIiIiIlITm+7Nn4x6G2RYsnUvT32+ENM0ubBHO64b1K1amW9/2s7U75YD0DI+iicvPxuA57/8kUVb9mBZFqktkrnngn4YXmzGsXfLIhZ++himadIudSTdzprgcXztD9PZtOwjbDY7DQPDOWvs4wSHJwDw4+yn2bN5IZZlktyyF/0uus+rTIAl29J46ovFmJbJhd3acN2ALtXrun4HU+etOlbXSJ4cM8Rd16+X8uPWNAAmDOrKsA4pXmUCLNl1kGfmrsa0LC7o0Jxre7b1OP7s3DWsSssE4IjTSV7pEX68cxQHC0u48+NFmBY4TZPRXVswsnMLr3N3bVrEvFnudu7YeyRnDjuunRe+z9oFMzFsNnz9/Dn78keIjG8OwNL/TGP9ko+x2Wycden9NG3bx6vM1atXM23qVEzTZOiwYYwaNcrj+Ny5c3nrzTeJjIwEYPh55zFs2DAA5s2dywcffADA6NGjGXzWWV7XdcmmHTzzwRxM0+KCPl249uy+1cp8t2ojU7/8AQNokRjLE+NHcTC3gDtfm4lpWjhdLkYPTGVk/+7e525P56mvlmCaFhd2a811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uqOYJStz+WruIf55R2s+mNadopIKHnzavQHnnvQyvl+czb9f64bLZfHc1J16soSIiIiIyClknGhXe8MwwoB7gfOBX57Llwl8ATxpWVatD5w/8tUU77fNryPTHRNPdyQA1xx5qV5yzcKCesmdlTypXnL7JO0+7Zlx++tuD46TYcuu2/1GvPVBxO31kvvm5IX1krv4y371kisiIiLyF1F/jzI4DQ7/8N5p79PWhYYDLquXz+WEMxmODSLcc+zHg2EY1wDTT9F1iYiIiIiIiMifzB95hOVDaJBBRERERERE/srqcX+DP6MTDjIYhrGhpkOAd1vDi4iIiIiIiMj/hNpmMsQAQ3E/svLXDGDpKbkiEREREREREflTqm2Q4Ssg0LKsn44/YBjGglNyRSIiIiIiIiL/JSzjL72vZZ2rbePH605wbGzdX46IiIiIiIiI/FlpBwsRERERERERqRMaZBARERERERGROvFHHmEpIiIiIiIi8temR1ieFLWWiIiIiIiIiNQJw7KsUxow5u70UxvwG8ZdEX26IwGYNiOjXnKPlh2tl1yjnnZZPVp25LRnNgz2P+2ZAPkZufWS27R903rJDQpteNozw8L8TnvmLx643KfeskVERETq0F/68Qtli2ad9j5tXfDvO6pePhfNZBARERERERGROqE9GURERERERERqUk8zuP+sNJNBREREREREROqEBhlEREREREREpE5ouYSIiIiIiIhITWy6N38y1FoiIiIiIiIiUic0yCAiIiIiIiIidUKDDCIiIiIiIiJSJ7Qng4iIiIiIiEgNLD3C8qRoJoOIiIiIiIiI1Il6m8nQoUUDrjw/DJsBP6ws5YsFRR7HWzXx48oRYSTF+vDSzBxWbjxceaxvlwAuGBQMwOfzi1i0ptSrzJ/XLeGj6U9hmSY9B13I0Auv8zi+6NtZLPr2Q2w2O34NGjL2+knEJTbDWVHBzNcfJn3XZgzDxshr7qZFu27e17VlQ665IBybDeavKGH294Uexx12uHlsFE0b+VJcavLCu9lk5zux22HCJRE0S/TDtGDG53ls3nXE69xObfwZPyoGmwFzlxTyyXd5nrkOg9uviqVZUgOKS1088+ZBsvKc9OsWxAVnhVeWa5zgxx1PpLFn/1Gvc8eNjHbnLi3k0+/yq+XedlUszRL9KC518exbh8jKc9K3WxAXDg6rLJec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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2p0kgfS-ao5o" + }, + "source": [ + "Como podemos ver, há várias colunas altamente correlacionados no dataframe. Vamos excluir (automaticamente!) as colunas altamente correlacionadas da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C7mUtTlFaoFx", + "outputId": "cb4734a6-f56a-48f0-9b23-cc478f88e9e8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 955 + } + }, + "source": [ + "set_variaveis_corr = set()\n", + "matrix_corr = X_cancer.corr()\n", + "matrix_corr" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01234567891011121314151617181920212223242526272829
01.0000000.3237820.9978550.9873570.1705810.5061240.6767640.8225290.147741-0.3116310.679090-0.0973170.6741720.735864-0.2226000.2060000.1942040.376169-0.104321-0.0426410.9695390.2970080.9651370.9410820.1196160.4134630.5269110.7442140.1639530.007066
10.3237821.0000000.3295330.321086-0.0233890.2367020.3024180.2934640.071401-0.0764370.2758690.3863580.2816730.2598450.0066140.1919750.1432930.1638510.0091270.0544580.3525730.9120450.3580400.3435460.0775030.2778300.3010250.2953160.1050080.119205
20.9978550.3295331.0000000.9865070.2072780.5569360.7161360.8509770.183027-0.2614770.691765-0.0867610.6931350.744983-0.2026940.2507440.2280820.407217-0.081629-0.0055230.9694760.3030380.9703870.9415500.1505490.4557740.5638790.7712410.1891150.051019
30.9873570.3210860.9865071.0000000.1770280.4985020.6859830.8232690.151293-0.2831100.732562-0.0662800.7266280.800086-0.1667770.2125830.2076600.372320-0.072497-0.0198870.9627460.2874890.9591200.9592130.1235230.3904100.5126060.7220170.1435700.003738
40.170581-0.0233890.2072780.1770281.0000000.6591230.5219840.5536950.5577750.5847920.3014670.0684060.2960920.2465520.3323750.3189430.2483960.3806760.2007740.2836070.2131200.0360720.2388530.2067180.8053240.4724680.4349260.5030530.3943090.499316
50.5061240.2367020.5569360.4985020.6591231.0000000.8831210.8311350.6026410.5653690.4974730.0462050.5489050.4556530.1352990.7387220.5705170.6422620.2299770.5073180.5353150.2481330.5902100.5096040.5655410.8658090.8162750.8155730.5102230.687382
60.6767640.3024180.7161360.6859830.5219840.8831211.0000000.9213910.5006670.3367830.6319250.0762180.6603910.6174270.0985640.6702790.6912700.6832600.1780090.4493010.6882360.2998790.7295650.6759870.4488220.7549680.8841030.8613230.4094640.514930
70.8225290.2934640.8509770.8232690.5536950.8311350.9213911.0000000.4624970.1669170.6980500.0214800.7106500.6902990.0276530.4904240.4391670.6156340.0953510.2575840.8303180.2927520.8559230.8096300.4527530.6674540.7523990.9101550.3757440.368661
80.1477410.0714010.1830270.1512930.5577750.6026410.5006670.4624971.0000000.4799210.3033790.1280530.3138930.2239700.1873210.4216590.3426270.3932980.4491370.3317860.1857280.0906510.2191690.1771930.4266750.4732000.4337210.4302970.6998260.438413
9-0.311631-0.076437-0.261477-0.2831100.5847920.5653690.3367830.1669170.4799211.0000000.0001110.1641740.039830-0.0901700.4019640.5598370.4466300.3411980.3450070.688132-0.253691-0.051269-0.205151-0.2318540.5049420.4587980.3462340.1753250.3340190.767297
100.6790900.2758690.6917650.7325620.3014670.4974730.6319250.6980500.3033790.0001111.0000000.2132470.9727940.9518300.1645140.3560650.3323580.5133460.2405670.2277540.7150650.1947990.7196840.7515480.1419190.2871030.3805850.5310620.0945430.049559
11-0.0973170.386358-0.086761-0.0662800.0684060.0462050.0762180.0214800.1280530.1641740.2132471.0000000.2231710.1115670.3972430.2317000.1949980.2302830.4116210.279723-0.1116900.409003-0.102242-0.083195-0.073658-0.092439-0.068956-0.119638-0.128215-0.045655
120.6741720.2816730.6931350.7266280.2960920.5489050.6603910.7106500.3138930.0398300.9727940.2231711.0000000.9376550.1510750.4163220.3624820.5562640.2664870.2441430.6972010.2003710.7210310.7307130.1300540.3419190.4188990.5548970.1099300.085433
130.7358640.2598450.7449830.8000860.2465520.4556530.6174270.6902990.223970-0.0901700.9518300.1115670.9376551.0000000.0751500.2848400.2708950.4157300.1341090.1270710.7573730.1964970.7612130.8114080.1253890.2832570.3851000.5381660.0741260.017539
14-0.2226000.006614-0.202694-0.1667770.3323750.1352990.0985640.0276530.1873210.4019640.1645140.3972430.1510750.0751501.0000000.3366960.2686850.3284290.4135060.427374-0.230691-0.074743-0.217304-0.1821950.314457-0.055558-0.058298-0.102007-0.1073420.101480
150.2060000.1919750.2507440.2125830.3189430.7387220.6702790.4904240.4216590.5598370.3560650.2317000.4163220.2848400.3366961.0000000.8012680.7440830.3947130.8032690.2046070.1430030.2605160.1993710.2273940.6787800.6391470.4832080.2778780.590973
160.1942040.1432930.2280820.2076600.2483960.5705170.6912700.4391670.3426270.4466300.3323580.1949980.3624820.2708950.2686850.8012681.0000000.7718040.3094290.7273720.1869040.1002410.2266800.1883530.1684810.4848580.6625640.4404720.1977880.439329
170.3761690.1638510.4072170.3723200.3806760.6422620.6832600.6156340.3932980.3411980.5133460.2302830.5562640.4157300.3284290.7440830.7718041.0000000.3127800.6110440.3581270.0867410.3949990.3422710.2153510.4528880.5495920.6024500.1431160.310655
18-0.1043210.009127-0.081629-0.0724970.2007740.2299770.1780090.0953510.4491370.3450070.2405670.4116210.2664870.1341090.4135060.3947130.3094290.3127801.0000000.369078-0.128121-0.077473-0.103753-0.110343-0.0126620.0602550.037119-0.0304130.3894020.078079
19-0.0426410.054458-0.005523-0.0198870.2836070.5073180.4493010.2575840.3317860.6881320.2277540.2797230.2441430.1270710.4273740.8032690.7273720.6110440.3690781.000000-0.037488-0.003195-0.001000-0.0227360.1705680.3901590.3799750.2152040.1110940.591328
200.9695390.3525730.9694760.9627460.2131200.5353150.6882360.8303180.185728-0.2536910.715065-0.1116900.6972010.757373-0.2306910.2046070.1869040.358127-0.128121-0.0374881.0000000.3599210.9937080.9840150.2165740.4758200.5739750.7874240.2435290.093492
210.2970080.9120450.3030380.2874890.0360720.2481330.2998790.2927520.090651-0.0512690.1947990.4090030.2003710.196497-0.0747430.1430030.1002410.086741-0.077473-0.0031950.3599211.0000000.3650980.3458420.2254290.3608320.3683660.3597550.2330270.219122
220.9651370.3580400.9703870.9591200.2388530.5902100.7295650.8559230.219169-0.2051510.719684-0.1022420.7210310.761213-0.2173040.2605160.2266800.394999-0.103753-0.0010000.9937080.3650981.0000000.9775780.2367750.5294080.6183440.8163220.2694930.138957
230.9410820.3435460.9415500.9592130.2067180.5096040.6759870.8096300.177193-0.2318540.751548-0.0831950.7307130.811408-0.1821950.1993710.1883530.342271-0.110343-0.0227360.9840150.3458420.9775781.0000000.2091450.4382960.5433310.7474190.2091460.079647
240.1196160.0775030.1505490.1235230.8053240.5655410.4488220.4527530.4266750.5049420.141919-0.0736580.1300540.1253890.3144570.2273940.1684810.215351-0.0126620.1705680.2165740.2254290.2367750.2091451.0000000.5681870.5185230.5476910.4938380.617624
250.4134630.2778300.4557740.3904100.4724680.8658090.7549680.6674540.4732000.4587980.287103-0.0924390.3419190.283257-0.0555580.6787800.4848580.4528880.0602550.3901590.4758200.3608320.5294080.4382960.5681871.0000000.8922610.8010800.6144410.810455
260.5269110.3010250.5638790.5126060.4349260.8162750.8841030.7523990.4337210.3462340.380585-0.0689560.4188990.385100-0.0582980.6391470.6625640.5495920.0371190.3799750.5739750.3683660.6183440.5433310.5185230.8922611.0000000.8554340.5325200.686511
270.7442140.2953160.7712410.7220170.5030530.8155730.8613230.9101550.4302970.1753250.531062-0.1196380.5548970.538166-0.1020070.4832080.4404720.602450-0.0304130.2152040.7874240.3597550.8163220.7474190.5476910.8010800.8554341.0000000.5025280.511114
280.1639530.1050080.1891150.1435700.3943090.5102230.4094640.3757440.6998260.3340190.094543-0.1282150.1099300.074126-0.1073420.2778780.1977880.1431160.3894020.1110940.2435290.2330270.2694930.2091460.4938380.6144410.5325200.5025281.0000000.537848
290.0070660.1192050.0510190.0037380.4993160.6873820.5149300.3686610.4384130.7672970.049559-0.0456550.0854330.0175390.1014800.5909730.4393290.3106550.0780790.5913280.0934920.2191220.1389570.0796470.6176240.8104550.6865110.5111140.5378481.000000
\n", + "
" + ], + "text/plain": [ + " 0 1 2 ... 27 28 29\n", + "0 1.000000 0.323782 0.997855 ... 0.744214 0.163953 0.007066\n", + "1 0.323782 1.000000 0.329533 ... 0.295316 0.105008 0.119205\n", + "2 0.997855 0.329533 1.000000 ... 0.771241 0.189115 0.051019\n", + "3 0.987357 0.321086 0.986507 ... 0.722017 0.143570 0.003738\n", + "4 0.170581 -0.023389 0.207278 ... 0.503053 0.394309 0.499316\n", + "5 0.506124 0.236702 0.556936 ... 0.815573 0.510223 0.687382\n", + "6 0.676764 0.302418 0.716136 ... 0.861323 0.409464 0.514930\n", + "7 0.822529 0.293464 0.850977 ... 0.910155 0.375744 0.368661\n", + "8 0.147741 0.071401 0.183027 ... 0.430297 0.699826 0.438413\n", + "9 -0.311631 -0.076437 -0.261477 ... 0.175325 0.334019 0.767297\n", + "10 0.679090 0.275869 0.691765 ... 0.531062 0.094543 0.049559\n", + "11 -0.097317 0.386358 -0.086761 ... -0.119638 -0.128215 -0.045655\n", + "12 0.674172 0.281673 0.693135 ... 0.554897 0.109930 0.085433\n", + "13 0.735864 0.259845 0.744983 ... 0.538166 0.074126 0.017539\n", + "14 -0.222600 0.006614 -0.202694 ... -0.102007 -0.107342 0.101480\n", + "15 0.206000 0.191975 0.250744 ... 0.483208 0.277878 0.590973\n", + "16 0.194204 0.143293 0.228082 ... 0.440472 0.197788 0.439329\n", + "17 0.376169 0.163851 0.407217 ... 0.602450 0.143116 0.310655\n", + "18 -0.104321 0.009127 -0.081629 ... -0.030413 0.389402 0.078079\n", + "19 -0.042641 0.054458 -0.005523 ... 0.215204 0.111094 0.591328\n", + "20 0.969539 0.352573 0.969476 ... 0.787424 0.243529 0.093492\n", + "21 0.297008 0.912045 0.303038 ... 0.359755 0.233027 0.219122\n", + "22 0.965137 0.358040 0.970387 ... 0.816322 0.269493 0.138957\n", + "23 0.941082 0.343546 0.941550 ... 0.747419 0.209146 0.079647\n", + "24 0.119616 0.077503 0.150549 ... 0.547691 0.493838 0.617624\n", + "25 0.413463 0.277830 0.455774 ... 0.801080 0.614441 0.810455\n", + "26 0.526911 0.301025 0.563879 ... 0.855434 0.532520 0.686511\n", + "27 0.744214 0.295316 0.771241 ... 1.000000 0.502528 0.511114\n", + "28 0.163953 0.105008 0.189115 ... 0.502528 1.000000 0.537848\n", + "29 0.007066 0.119205 0.051019 ... 0.511114 0.537848 1.000000\n", + "\n", + "[30 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 240 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9lvLldX5eWVW", + "outputId": "3a8f8ccb-e59e-408e-cd99-1f7439029321", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "for i in range(len(matrix_corr.columns)):\n", + " for j in range(i):\n", + " if abs(matrix_corr.iloc[i, j]) > 0.8:\n", + " colname = matrix_corr.columns[i]\n", + " set_variaveis_corr.add(colname)\n", + "\n", + "set_variaveis_corr" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{2, 3, 6, 7, 12, 13, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 241 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R4YC3Kl5erhc" + }, + "source": [ + "Deletando as colunas altamente correlacionadas do dataframe e calculando a correlação novamente:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "psDDQlrSevG5", + "outputId": "a2aea1b6-1826-4147-d8a5-0ccd7c95bc47", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 989 + } + }, + "source": [ + "X_cancer = X_cancer.drop(set_variaveis_corr, axis = 1)\n", + "\n", + "fig, ax = plt.subplots(figsize = (20, 17)) \n", + "mask = np.zeros_like(X_cancer.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(X_cancer.corr().abs(), mask = mask, ax = ax, cmap='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 242 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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IiIiIiIiIh6hJIOIiIiIiIiIeITmZBAREREREREphe5gWTaqZBARERERERERj1CSQUREREREREQ8QkkGEREREREREfEIzckgIiIiIiIiUgrL1KQMZaFKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBSm7mFZJqpkEBERERERERGPUJJBRERERERERDxCSQYRERERERER8QjNySAiIiIiIiJSCt3CsmzKPcnw5pfh5f0WPmXzihXeDqHSCQ+9xNshVDoh/b7ydgiVyjW587wdQqWTHRbp7RAqnVkRD3o7hErlsjBdb05ToA+Jp6qxYYa3Q6hU9rhq8/umPG+HUelc3CTE2yGIiA/RcAkRERERERER8QglGURERERERETEIzQng4iIiIiIiEgpNCdD2aiSQUREREREREQ8QkkGEREREREREfEIDZcQERERERERKYVGS5SNKhlERERERERExCOUZBARERERERERj1CSQUREREREREQ8QnMyiIiIiIiIiJRCt7AsG1UyiIiIiIiIiIhHKMkgIiIiIiIiIh6h4RIiIiIiIiIipbAsDZcoC1UyiIiIiIiIiIhHKMkgIiIiIiIi8i9kGMZlhmFsMQwjyTCMZ/6ivZNhGKsMwyg0DOOGv/OaSjKIiIiIiIiI/MsYhmEHxgC9gabALYZhND2l2x7gTuCzv/u6mpNBREREREREpBTmuXsLyzZAkmVZOwAMw5gGXA1s/L8OlmXtOtFm/t0XVSWDiIiIiIiIyL9PTWDvScv7Tjz3jyjJICIiIiIiInKOMQxjgGEYK0/6N6Ai3lfDJURERERERETOMZZljQfGn6HLfiDupOVaJ577R5RkEBERERERESmFZZ2zczIkAgmGYdSlKLlwM9Dvn76ohkuIiIiIiIiI/MtYllUIDAIWAJuALyzL2mAYxquGYVwFYBhGa8Mw9gE3Ah8ahrHhbK+rSgYRERERERGRfyHLsuYB8055bshJjxMpGkbxtynJICIiIiIiIlIK69y9hWW50HAJEREREREREfEIJRlERERERERExCOUZBARERERERERj9CcDCIiIiIiIiKl0JwMZaNKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBSmpeESZXFOJBma1fWjb/cAbDZYvPYYC5blu7UnxDno2y2AmlF2Js4+xKotBcVt7ZpX4fJLqgEwb+lRlq0/XqGxl5c2F4by0N11sdlg7o/pfDZrv1u7n8PguUcSaFgvkLyDhbzyzlZSDxwjJMjBq082olGDIL5bmM6oiTu9tAWetWvTIhZ9NRTLMmnW7kZadR/g1r5q4RQ2LPsSm81OtaBwut/yBiHhNQHYtGIWK74fC0CbngNp0ubaCo+/PGxfv4gF04ZimSYtOt5I+97u+2TZ91NYs7honwQEh3PFnW8Q6qxJTuZ+ZnwwCMs0cbkKad31Ni7qcouXtsKzlq7dxNufzMI0La7p0pY7r+r+l/1+WrGWp9/7iP+9+hhN68WTfCCLG596k9oxkQA0b1Cb5+7uW5Ghl4vVK5czefz7mKZJt559uK7vrW7tC+bN5rs5s7DZ7PhXq8b9Dz1BXHwd0tNSeOT+24mtGQ9Aw8ZNuW/Q497YBI/b9udvfPfZUEzLpGXHG+jYx/28WbpgCqsWzcBmtxMYHM7Vdw0lNKJmcXv+0UOMeaEPjS/sRp/bhlR0+OVi2ap1jJr0CaZpckX3Lvzn+iv/st8vvyfywrD3mDj8FRo3qEdu3kFeGP4+m5N20PvSjgwecEcFR15+lq1ax6jJU0/sk87857oz7JPh7zNx2MtF++TgQV4YPrpkn9x7ewVHXj5W/LGa0ROmYJoml/foRr8b3a+j38xfwOy5C7DZbFTz92fwoPuoEx9HQUEBI8aMZ2vSdgzDYNCAu2hxXnMvbYVnrVu1lM8mvoNpmnTqcTVXXH+nW/vP383k53lfYths+FcL4M4HnqNmXD0O5eUwetgz7EzaSIeuV/CfAU95ZwNERM7A55MMhgG39Axg5LSDZB80efbOENZtO05KplncJyvP5KO5h+nR1t9t3QB/gys6VOONj/LAgufuCmHdtgKOHPPtTJXNBo/eW4/HX9nAgczjfDjsfJYkZrF739HiPn26R3PwUCG3Priaru2d3Hd7bV55ZyvHC0wmfb6HuvEB1I0P8OJWeI5puvhlxqtcO3AKQaHRTB9xA3Wbd8VZo0Fxn8haTbj58Zn4VanGusWfseSb4fS+cyT5h3NYvmA0Nw+eCYbBtHeuo27zrvgHVPfiFv1zpuli/mevcutjUwgJi2bS0BtoeEFXImNL9kmN+Cbc8/xM/KpW449fPuPnGcO57r6RBFeP5M5npuPwq8Lx/MN8+PKVNGzRleDQaC9u0T/nMk3e+ngmY565n+jwUG4f8i6dLmpOvZo13PodPprPtAWLaF6/ttvzNaOdfPbGkxUZcrlyuVxMGDuSIa+/gzMikqcfu4/W7doTF1+nuE/HLt3pdfnVACQuW8JHE8bw4mvDAYiOqck7oyd5I/RyY5ou5k19lf88PpmQ8GgmvHojjVp0JapmyXkTE9+EAUNmUKVqNRIXfs4PX77NjQPfLW5fOGsUtRu28kb45cLlMhkx/mPefflpopzh9H9qCB3atKRuXE23fkeOHuXLOQto2rB+8XNVqvjR/5br2blnHzv27Kvo0MuNy2UyYsL/ePelp07sk5fo0LqUfTL3e5omnLRP/KrQ/5br2Lln/zmzT1wuF6PGTWT4a0OIdIYzcPAzXNK2FXXi44r7dOvckat69wJgyfJExk76mLdeeYG53/8IwKTRI8jOyeWZl4cydsSb2Gy+PdrXdLn45MNhPPnKaMKd0bzy5B1c2KYTNePqFfe5uFMvul52PQCrV/zK55Pf5YmX3sevSlWu63c/+/ZsZ/+e7d7aBBGRM/Ltv9JA3RgH6dkmGbkmLhNWbjzOBQlV3Ppk5prsP+Di1CqXZnX92LSzgCP5FkeOWWzaWUCzen4VGH35aNIgiP0pR0lJO0ZhocXPizPo0CbcrU/71mEsWJgOwK+/Z9LyvKIvzfnHTP7cfJDjBeZpr+ur0navIzSiNtUj4rA7qpBwYR92/PmTW5+4hHb4VSmqaKlRpwWHclMB2L15MfEN2+MfGIp/QHXiG7Zn96bfKnwbPC155zrCI2sTFlm0T5q17sPWNe77pE7jdvhVLdonNeu1IC+7aJ/YHVVw+BWdY4WFx7Gsc+NY2bB9D3HREdSKisDP4aBnuwv59Y/1p/UbN2M+d1zRlSp+Pp+jPaOkrZuoEVuTGjGx+Pn50aFTVxKXLXbrExAQWPw4P/8ohlHRUVas/TvWER4VT3hUHA5HFZq3vZwtp5w3dZu0o8qJ86ZWvQuKzxuA5F3rOZSXSf1m7Ss07vK0adt2asVEU7NGFH5+Drp3aMfiFX+c1m/CZzO59dorqOJXco2t5u/PBU0bUaWK7193T7YpaTu1YqJO2SerTus34bOZ3HpNH7ftr+ZflQuaNHLbT75u87YkasbUILZGNH5+fnTt1J6lyxPd+gQGlPyokZ9/jP/7U7J7zz4uPL+ociEstDpBgQFsSfL9L9Y7tm0gOiaOqBq1cPj50bZDD1Yv/9WtT7WAoOLHx/LzMU78ga3qX42GTVvg5+f+WVdEpDLx+SRDaLBB9kFX8XL2QZPQ4L+3WaHBNrIPlnxBKsu6lVmEsyrpmSXDPg5kHicivEqpfVwmHD7ionrwufml6VBuGkFhJb9GB4VGczg3rdT+G5fNoHaTTgAcLuO6vuJgThoh4SXbFRwWzcGc0rdrzeIZ1G/eqXg5NyuF8S9fyXtPd+GSy+71+SoGgPTsHKLDQ4uXo8Krk56d69Zn8869pGbl0OHCZqetn3wgi37Pv82A10ezerPvfwjOyswgIiKqeDk8IpLMzIzT+s2fM4sH7rmFT6aM4+77Hil+Pj01hSceuocXn36YjevXVkjM5S0vJ42Q8Jji5ZCwGuRll37erPptBg3OKzpvTNNkwfS36Nn33CptPpCVTVRESRI70hnOgcxstz5btu8iPSOTS1q1qOjwvOJAZjZRTmfxcqQznANZf7FPMrP+FfskIzOLqIiI4uUIp5MDmVmn9ft67nxuvfdBxn/0CYPuuweA+nXrsHRFIi6Xi5TUNLZu38GBA5kVFXq5yc46QHhEyXUzzBlNdtaB0/r9OO8LnrzvGr74+D1u7f9ERYYoIqewTMsn/3nLGb9RG4bRyjCMhYZhTDUMI84wjB8Mw8g1DCPRMIwLz7DeAMMwVhqGsXLTio89H7VIOdm8cjZpe9fTsmt/b4dSafy5bDYpu9Zzca+SfVI9PIYBL3/Lg0O/Z93SWRzKO/3L57nGNE1GfDqbx/pdfVpbRGgIc0YO4bOhT/DYrVfzwgdTOXQk/y9e5dzT+4pr+WDS5/znrvuYOf1/AISFO/nwoy94+/1J3Nn/QUYOf40jRw57OdKKtfb3b0jetYH2lxV9WUpc+BkJ53emeniNs6x5bjFNk/enfMqgu/p5O5RKwzRN3v/oMwbdeW7MZeMp1/TpzacTxjDgjtuYOn0GAL17dCXS6eT+x55mzMQpNGvcyOeHSpRF98v7MvzDr7nx9of49svJ3g5HRORvO9tf6g+AYcBcYCnwoWVZ1YFnTrT9JcuyxluW1cqyrFZN2pTvRE45By3Cgu3Fy2HBNnIO/r3y7ZyDJmEnVS6UZd3KLCPzGFHOksqFSGcVMrKOl9rHboPAADu5BwsrNM6KElQ9mkMnlSwfykkjsPrpv7zv2bKUxO/HcWX/sTgcRfsm8G+u62uCQ6PJyyrZroPZaX9ZjbBj41IWzx1H30Fji4dInPo6kTUT2LttZbnGWxGiwkJJy8opXk7PyiUqrGTujSP5x9i+L5X7ho7mykdfZf323QweMYmNO/ZQxc9BaHDR0IEmdeOoGeVkT2p6hW+DJ4U7I8jIKNmGrIwDOJ0RpfZv36kbK34vGk7h51eF4JCifVc/oRE1YmqSvH9v+QZcAUJCo8nLSilezstOJSTs9PNm+4al/DZnHLc8/EHxebNv+xpW/PQp7z7Zle+/GMbapbP54ct3Kiz28hIZHkZ6Rsmv0gcys4h0hhUvHzmaz849+3johTe4YcBjbNy6naffeJfNSTu8EW6FiHSGkZ5Z8mv7gcwsIsP/Yp+8+F9uuG9w0T7578hzdp9EOMNJzyhJRGdkZhLpDC+1/6Wd2rNkWdFwCrvdzoP33sWE997m9Ree4dDhw9SqGVPqur4iLDySrIySKqjszDTCwiNL7d+2Y09WLf+lAiITEfGMsyUZ/CzLmm9Z1ueAZVnWDIoe/AT4n3nVirErpZCocBvO6jbsNmjVtAprkwrOviKwYWcBTev6EVDVIKCqQdO6fmzY+ffWrcw2Jx2iVkw1akRVxeEw6NohgiWJ7qWJSxKz6XVpUSl054udrP4z969e6pwQHX8eORm7yM3ci6vwONtWz6Ve865ufdL3beTnL4Zw5b1jCQguKXOt3bgDe7YsJv9ILvlHctmzZTG1G3eo6E3wuNg655GVvovsA0X7ZEPiXBpe4L5PUvdsZN7UIdw0aCyBISX7JC8rlYLjRb/SHz2cy95tq3BG163Q+MtD03px7E09wP70TAoKC/l+2Wo6tSwZFhEUUI2fxr3OtyOH8O3IITSvX5sRg++hab14svMO4TKLEpT70jPYm5ZBzShnaW/lExo0bEzK/n2kpaZQUFDA4kU/06qt+1wCyftLJqb7I/F3YmJrAZCbm4PLVTSMLTUlmZTkfUTXiK244MtJbN3zyEzbTfaBfRQWHmf98nk0auF+3qTs3sic/73ELQ9/QNBJ5831A95m8NsLeWz4z/Ts+xQXXHI1PW70/TtuNE6ox96UVJLT0ikoKOTHxcto37plcXtQYABz/zeWGePfZcb4d2nasD5vPfcYjRvUO8Or+rbGDeqxNyWN5LQDJ+2TkuLPoMAA5n78ATM+HMGMD0cU7ZNnHz1n90njhAbsT04hJTWNgoICfl60hIvbtHbrsy+5JHm3bOUqasYWVfzk5x/jaH7R9Wbl6rXY7Xa3CSN9Vd2EpqSl7OFA2n4KCwpYvvgHLmzTya1PavKe4sdrVy4mOia+osMUEfn/drZB+PmGYfQEqgOWYRjXWJb1tWEYnQHXWdatEKYF074/wiM3BWMzYMm6Y6RkuLiyYzV2pxSyLqmA2jXsDLwumAB/g/Mb+HFlB5NXJuVxJN9i7tKjPHtnCABzlxzlSL5v31kCiuZYGDlxB28PaYrNZjDvpzR27T3K3TfHsXn7IZYmZjPvpzSefySBT8dcyMFDhbwyYmvx+tPGtSSwmh2Hw0aHtuE88cpGtztT+Bqb3UGX64cwe1x/TNNFs7bX44xJYNm8UUTFN6de824s+WYYBceOMG9K0Zjy4LAYrrx3HP6BobTu+QDTR9wAQJteD+IfGHqmt/MJNruDy/oN4fOR/TEtFy3aX09kzQR+mT2K2NrNadiiGz/OGEZB/hFmjivaJyHOGG4aNI6M1O38+MWbRbd2sSza9bqbqFqNvLxF/5zDbufJO67noWEf4jJNrurclvq1Yhg3Yz5N6sbR+aLSb5u2avN2Ppw5H4fdjmEYPHvXDVQPCiy1vy+w2x30H/gor734BKZp0rXH5cTXrsvnn0yiQUJjWrdrz/w5X7FuzR847A4Cg4IYNPhZADauX8u0qZNx2B0YNoMBDw4mODjEy1v0z9ntDi6/7UU+GXEPlmlyYYfriaqZwM+z3iO2TnMaX9iV778YzvFjR/jig0cBqO6Mod/DY70ceflx2O0Mvvd2Br8yHNM06dOtE/XiazHxs5k0blCXDm1annH9GwY8xuGjRyksLOS3hV1CCgAAIABJREFUFX8w4qWnT7sLg69x2O0M7n87g18dhmlaJfvk85k0rv839sl9g0v2yfI/GPHSUz69T+x2Ow/d35+nX3odl2nSu3tX6taOY8rUaTRMqE/7tq35es58/lizDofDQXBQIE8/+hAAObm5PPXS69gMgwhnOM8OftjLW+MZdruD2+59irdfeRjT5aJj96uoGV+frz4bR90GTbiwTWd+mvcFG9auwG53EBgUwr2PvFS8/uP3XkX+0cMUFhawavmvPPHy+253phARz7NOvYOAnJFxph1mGMYFFA2XMIHHgIHAHcB+4F7Lspae7Q3uezNL/yMn2bxis7dDqHT63nuJt0OodEJ8+/upx11TbZ63Q6h0doed+YvKv9Gfab4/lMmTuoclnr3Tv40+JJ7muN+5cbtqT9njqn32Tv9CFzfx/USxlLtz+h5Tt7+Y4pMXkP+9FuOV/5czDpewLGutZVm9LMvqbVnWZsuyHrEsK9SyrGaA7/90KSIiIiIiIiIe80/uWfgKMMVTgYiIiIiIiIhUNqYXbwfpi86YZDAMY11pTYDqUkVERERERESk2NkqGaKBXkD2Kc8bFN3SUkREREREREQEOHuSYQ4QZFnWmlMbDMP4pVwiEhERERERERGfdMYkg2VZ95yhrZ/nwxERERERERGpPCzNyVAmZ7y7hIiIiIiIiIjI36Ukg4iIiIiIiIh4xD+5haWIiIiIiIjIOc2yNFyiLFTJICIiIiIiIiIeoSSDiIiIiIiIiHiEkgwiIiIiIiIi4hGak0FERERERESkFJZpejsEn6JKBhERERERERHxCCUZRERERERERMQjlGQQEREREREREY/QnAwiIiIiIiIipTBNy9sh+BRVMoiIiIiIiIiIRyjJICIiIiIiIiIeoeESIiIiIiIiIqWwLA2XKAtVMoiIiIiIiIiIRyjJICIiIiIiIiIeoSSDiIiIiIiIiHiE5mQQERERERERKYWlW1iWiSoZRERERERERMQjlGQQEREREREREY/QcAkRERERERGRUmi4RNmokkFEREREREREPEJJBhERERERERHxCCUZRERERERERMQjyn1Ohlq1Q8r7LXyKYTTxdgiVzjX1//R2CJWOc/Mib4dQqfz53CfeDqHScUyZ4+0QKp0ff87wdgiVykpnM2+HUOkcPnjc2yFUOtf0CvR2CJXKoj807vpUAzttZ+82b0dR+cQlNPV2CFKBTMv0dgg+RZUMIiIiIiIiIuIRSjKIiIiIiIiIiEcoySAiIiIiIiIiHlHuczKIiIiIiIiI+CrL1HwtZaFKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBQaLlE2qmQQEREREREREY9QkkFEREREREREPEJJBhERERERERHxCM3JICIiIiIiIlIKy9KcDGWhSgYRERERERER8QglGURERERERETEI5RkEBERERERERGP0JwMIiIiIiIiIqUwTdPbIfgUVTKIiIiIiIiIiEcoySAiIiIiIiIiHqHhEiIi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EYfHXt3FpPNyCJnx1qI9lFbUc9bYLqzbXMeiVTW8uWAPE8/O5tZL8/jk0wgPPBs9DrIyQlz1/RwiHh0RMeWF9n3nkb0iDs++WcNFX++EGby/InpniVOPTaekIsKydfUUF4W44LSOdO5oDO2Xxqkjnduf/JRuXY2vn9Ap2pCb8frCWsoq23cbrPY3Xjicxrd+fAP333px9BaW475Jj+JBvPzUXygeMIyjRpzEC4/eyWd7djPt7quBaHFh4rV/ZvhxE1i9dA5/uOYcMGPI8BM48phxwX6gBIg4vPhuHT86LR0zY96qesqrnPFHhynZ6qzYEKFXgXH++HQ6d4AhfUKccrRzz7OHxm1v9yfaV5vIdTfdTCQS4bQJp9Cvbx+mPfo4hw0exPGjRvLCzJeZv2gxaeEwmZmZXDsp2ier2rGD6266mZAZ+fn5XHf1FQF/GhExb2GVQzMbAvQE5rj7rn2eP83dX23pF7T2dIn2ZtOGQ6NjmUg3frMk6BCSTv6KN4IOIaksue2RoENIOmkPzww6hKTzlyfV3OwrN79LyzulmE92pvaogv05+9SMlndKIW/M03nk8y4Z0/7vqtUaigcPDTqEZHNIL2w34fvt8+Qw67FjAvn/csDpEmZ2OfAccBmw1MzO2uflW1szMBERERERERFpX1qaLjERGOHuu8ysHzDDzPq5+z0c4tUqEREREREREfliWioyhPZOkXD3dWY2jmihoS8qMoiIiIiIiMghLsjbQbZHLd1dYouZDd+7ESs4nAkUAEe1ZmAiIiIiIiIi0r60VGT4AVC27xPuXufuPwDGtFpUIiIiIiIiItLuHHC6hLs3u+y/u7+d+HBEREREREREpL1qaU0GERERERERkZTlHgk6hHalpekSIiIiIiIiIiIHRUUGEREREREREUkIFRlEREREREREJCG0JoOIiIiIiIhIMyIRDzqEdkUjGUREREREREQkIVRkEBEREREREZGE0HQJERERERERkWZ4RLew/CI0kkFEREREREREEkJFBhERERERERFJCBUZRERERERERCQhtCaDiIiIiIiISDNct7D8QjSSQUREREREREQSQkUGEREREREREUkITZcQERERERERaYa7bmH5RWgkg4iIiIiIiIgkhIoMIiIiIiIiIpIQKjKIiIiIiIiISEJoTQYRERERERGRZugWll+MRjKIiIiI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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1oDecB_8fGwM" + }, + "source": [ + "### **Conclusão**: Qual a conclusão podemos tirar esta análise?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "avZ12nHqiK0M" + }, + "source": [ + "___\n", + "# **RFE - Recursive Feature Elimination** (continuação da Análise de Correlação)\n", + "* Muito tempo de processamento! Portanto, exclua as colunas altamente correlacionadas do dataframe previamente.\n", + "* A matriz X e target deste tópico vem do tópico anterior \"Análise de Correlação\";\n", + "\n", + "* Leitura recomendada: [Feature Selection in Python — Recursive Feature Elimination](https://towardsdatascience.com/feature-selection-in-python-recursive-feature-elimination-19f1c39b8d15)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MCGTzI59R3G7" + }, + "source": [ + "from sklearn.feature_selection import RFECV\n", + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.model_selection import StratifiedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sqsK1bGmiK0O", + "outputId": "3a989f0a-6324-4b9c-a668-c0b512558223", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "rf = RandomForestRegressor(random_state = 20111974)\n", + "filtro_rfe = RFECV(estimator = rf, step = 1, cv = StratifiedKFold(10))\n", + "filtro_rfe.fit(X_cancer, y_cancer)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RFECV(cv=StratifiedKFold(n_splits=10, random_state=None, shuffle=False),\n", + " estimator=RandomForestRegressor(bootstrap=True, ccp_alpha=0.0,\n", + " criterion='mse', max_depth=None,\n", + " max_features='auto', max_leaf_nodes=None,\n", + " max_samples=None,\n", + " min_impurity_decrease=0.0,\n", + " min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0,\n", + " n_estimators=100, n_jobs=None,\n", + " oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False),\n", + " min_features_to_select=1, n_jobs=None, scoring=None, step=1, verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 244 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MBnSFtWiDvOd", + "outputId": "863be880-0320-4154-c1a8-06fd72c65133", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_cancer.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(569, 13)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 245 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yomSdCzJD2tS", + "outputId": "f956d8e0-6038-4eed-b908-a1ee5d80762c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_cancer.size" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "569" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 246 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f-dKku9IiK0V", + "outputId": "aa8192fa-dbe9-4399-caf0-10ecd83b4e4a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Número ótimo de colunas:\n", + "filtro_rfe.n_features_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "8" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 247 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TUoMb40-iK0Y", + "outputId": "fc509029-ce5e-4102-c3a3-715e0e0af10c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 605 + } + }, + "source": [ + "plt.figure(figsize=(16, 9))\n", + "plt.title('Recursive Feature Elimination (rfe) com Cross-Validation', fontsize=18, fontweight='bold', pad=20)\n", + "plt.xlabel('Número de colunas selecionadas', fontsize=14, labelpad=20)\n", + "plt.ylabel('% Acurácia do Modelo', fontsize=14, labelpad=20)\n", + "plt.plot(range(1, len(filtro_rfe.grid_scores_) + 1), filtro_rfe.grid_scores_, color='#303F9F', linewidth=3)\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RG16C-2QdhUx" + }, + "source": [ + "### **Conclusão**: Houve uma redução para 7 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M8lpuOjti6Fw", + "outputId": "cf3d3eeb-0b63-40f1-8b4e-a2c581638b9f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "X_cancer.drop(X_cancer.columns[np.where(filtro_rfe.support_ == False)[0]], axis = 1, inplace = True)\n", + "X_cancer.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
014510151828
017.9910.380.118400.277601.09500.049040.030030.4601
120.5717.770.084740.078640.54350.013080.013890.2750
219.6921.250.109600.159900.74560.040060.022500.3613
311.4220.380.142500.283900.49560.074580.059630.6638
420.2914.340.100300.132800.75720.024610.017560.2364
\n", + "
" + ], + "text/plain": [ + " 0 1 4 5 10 15 18 28\n", + "0 17.99 10.38 0.11840 0.27760 1.0950 0.04904 0.03003 0.4601\n", + "1 20.57 17.77 0.08474 0.07864 0.5435 0.01308 0.01389 0.2750\n", + "2 19.69 21.25 0.10960 0.15990 0.7456 0.04006 0.02250 0.3613\n", + "3 11.42 20.38 0.14250 0.28390 0.4956 0.07458 0.05963 0.6638\n", + "4 20.29 14.34 0.10030 0.13280 0.7572 0.02461 0.01756 0.2364" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 249 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s7S87LApdESo", + "outputId": "096f4cc6-45fe-49f5-c4e8-8d098d3001f2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "filtro_rfe.estimator_.feature_importances_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.6274782 , 0.06895439, 0.02932265, 0.06823762, 0.05093922,\n", + " 0.01941762, 0.03383343, 0.10181687])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 250 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FEfmeic37hvw" + }, + "source": [ + "___\n", + "# **Feature Selection com Random Forest**\n", + "* Para demonstrar este método, vou utilizar o Boston Housing Price dataframe.\n", + "\n", + "![Supervised_X_Unsupervised](https://github.com/MathMachado/Materials/blob/master/Supervised_X_Unsupervised.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0F2BdrZgKzV5" + }, + "source": [ + "### Carregar o dataframe\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6H31U15q7kIO" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "# Função para carregar as informações do dataframe Iris\n", + "def carrega_df_iris():\n", + " global df_iris, l_iris_labels, X_iris, y_iris, iris\n", + "\n", + " iris = load_iris()\n", + " X_iris = iris['data']\n", + " y_iris= iris['target']\n", + "\n", + " df_iris = pd.DataFrame(np.c_[X_iris, y_iris], columns= np.append(iris['feature_names'], ['target']))\n", + " df_iris['target2']= df_iris['target']\n", + " df_iris= df_iris.rename(columns={'sepal length (cm)': 'Sepal Length', 'sepal width (cm)': 'sepal width', 'petal length (cm)': 'petal length', 'petal width (cm)': 'petal width'})\n", + " df_iris['target'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "\n", + " # Criar a lista de nomes das variáveis\n", + " l_iris_labels = ['Sepal Length','Sepal Width','Petal Length','Petal Width']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rD2DmkpNXkFy" + }, + "source": [ + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jVQuRHYhM4fD" + }, + "source": [ + "> A variável-resposta que estamos tentando prever/explicar é categórica. Portanto, vamos usar um algoritmo da classe supervisionado para Classificação.\n", + "\n", + "* SelectFromModel selecionará os atributos cuja importância seja maior do que a importância média de todos os recursos por padrão, mas podemos alterar esse limite se quisermos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1pPpC7GXLgpC" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.feature_selection import SelectFromModel" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dfSfuUlHQOSt" + }, + "source": [ + "# Particionar base de treinamento (80%) e validação (20%)\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_iris, y_iris, test_size = 0.2, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JDsdjsZ0M4F", + "outputId": "71d1931c-9569-4a44-d7b0-7a7cfb789fa5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(120, 4)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 255 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SH_B3C1u0Qkl", + "outputId": "1e00e16e-ed0b-4317-fe46-f0f5f0f46562", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(30, 4)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 256 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YQ270kclOFeK" + }, + "source": [ + "# Create a random forest Regressor\n", + "ml_rf = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vFSCt8uaeKFN", + "outputId": "154735f9-3388-4023-9de6-cabd217c793f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Treina o classificador\n", + "ml_rf.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=10000,\n", + " n_jobs=-1, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 258 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VfdKeUkgS6ul" + }, + "source": [ + "Os atributos mais importantes são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tnrwVLPKSNxr", + "outputId": "2a3db4d0-5794-48ad-ca10-ba988b399e85", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Imprime o nome do atributo associado à importância usando índice de Gini\n", + "for feature in zip(l_iris_labels, ml_rf.feature_importances_):\n", + " print(feature)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "('Sepal Length', 0.08731002037613723)\n", + "('Sepal Width', 0.021750035432184116)\n", + "('Petal Length', 0.39132734233988486)\n", + "('Petal Width', 0.4996126018517938)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x8FHRHlDWTn4" + }, + "source": [ + "* Os scores acima representam a importância de cada variável.\n", + " * A soma dos scores resulta em 100%;\n", + " * Os atributos 'Petal Length' (Score= 0.45) e 'Petal Width' (Score= 0.42) são os mais importantes.\n", + " * Combinados, as duas variáveis mais importantes somam ~0.86." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wbMnS_gIVBA8" + }, + "source": [ + "Como regra geral, selecione os atributos que tenha importância de no mínimo 0.15. \n", + "\n", + "Citar autor/Referência!!!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M3TnDYRVeMEs" + }, + "source": [ + "Algo mais visual:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o8QkARWpeI_e" + }, + "source": [ + "def importancia_variaveis():\n", + " # Calcula a importância das features\n", + " importances = ml_rf.feature_importances_\n", + "\n", + " # Ordena as features por importância\n", + " indices = np.argsort(importances)[::-1]\n", + "\n", + " # Associa a feature name com a feature importance\n", + " names = [iris.feature_names[i] for i in indices]\n", + "\n", + " # Barplot\n", + " plt.bar(range(X_treinamento.shape[1]), importances[indices])\n", + "\n", + " # Adiciona as feature names no eixo x-axis\n", + " plt.xticks(range(X_treinamento.shape[1]), names, rotation = 20, fontsize = 8)\n", + "\n", + " # Define o título do gráfico\n", + " plt.title(\"Importância Preditiva das variáveis\")\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ahZdlCBE6h_e", + "outputId": "1d263536-5b65-489a-905b-1bc6a4e54e1f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "importancia_variaveis()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAEfCAYAAABRUD3KAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deZgdVZnH8e+PhE3CnihbIAgRCIsKYXUdRGUziIKAG8zgII6MCziKjiKDiCyODg64oDJRBNkEjRAWGYRRRoSwiLJJYAIJa9jDJoS888d7blJ908sN6U53n/w+z9NP33urbtWpc6veOnWWKkUEZmY2/C0z2AkwM7P+4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEC3hUjaXdLfJG3WT8v7kKTL+2NZ/UnSQZJ+33j/jKTX9jL/rZLevgTSdZWkjw30ehZHT3klaaqkT/TTOr4v6Sv9saylhQP6EiZphqRdBjsd0H3gkLQs8BVgEnBif6wnIs6MiHe9ku9KmizpxRJAHpf0G0mb9ke62kXEqIi4p7HeY9umbx4RVw3EuoebZl61SPoo8HhEfK+f1nFoRHytP5a1tHBAXwop9fTbjwO+GhGXAWdIWnPJpaxHJ0bEKGA94BFgcvsMfWyT9RNJI3uZPAr4+JJKiy3MB8AgKpf810j6tqQnJd0jaafy+UxJj0g6sDH/5HIZ+htJcyRdLWmDxvSdJF0v6anyf6fGtKskfV3SNcBzwBnAW4BTSun3lDLrYcCPJT0NfAGY0FjG0ZLOlfTTsv5bJU1sTB8r6QJJsyU91lpmN1UbJ5fte1rSDZLe0kl+RcRzwFnAFj1s02slbVry53FJd0r6QGO9a0qaUtZ7HbBR2+8RkjaWdAjwIeDzJW9+XabPkLSLpHUkPS9pjcZ33yjpUUnLStpI0pUlDx6VdKak1XraLknvlHRH+d1OAdSY1uuyJH1B0v3l97hT0ju6Wf72kh6SNKLx2d6Sbimvt5P0h7IPPijpFEnLteXLJyXdBdzVzKvyeg9JNwHHA3dIOrrx3UskHdaWnj9Jel953dvvNf8qSdJoSReVND4u6XfyCXxhEeG/JfgHzAB2Ka8PAuYCfw+MAI4F7gNOBZYH3gXMAUaV+SeX928t008Gfl+mrQE8AXwEGAkcUN6vWaZfVZa9eZm+bPnsY23p+zCwZpnnCOAhYIUy7WjgBWD3kt5vANeWaSOAPwHfBlYCVgDe3NjO33eyjm7yazJwbHk9igzov+thm1YFZpb8HAm8EXgUmFDmPxs4t6RvC+D+tnQFsHH7env47a4E/rEx7STg++X1xsA7y280Bvgf4D962L7R5Tfdp/wmny37xMf6WhawSdnedcr7ccBGPaznbuCdjffnAUeW19sAO5Q8GwfcDnymLV9+Q+5jK3aTVzsDW5IFxK3Iq6j3lmkfBa5pLGsC8GTZnpX6+L2av/03gO+XPFqWLIxosI/nofY36AlY2v5YOKDf1Zi2ZTlQXtP47DHgDeX1ZODsxrRRwMvAWDKQX9e2rj8AB5XXVwHHtE2/iraA3k16nwBeX14fDVzRmDYBeL683hGYDYzsZhkH0Qicva2jm2mTyZPIk2Tgn9IKWu3bBOxHCfaNz34AfJU84bwEbNqYdhyvPKB/DLiyvFYJTG/tYRveC9zUw7SPUk6KjWXN6ul3aS6LDPaPALsAy/bxOx4LnF5erww8C2zQw7yfAS5sy5ed2+aZn1fdfP8/gG93ty7g64109Ph7tf8GwDHAr3pap//yz5csg+/hxuvnASKi/bNRjfczWy8i4hngcWCd8ndv27LvBdbt7rs9kfQ5SbeXy/8nyVLv6MYsDzVePwesoKxXHQvcGxFz+2Ed7b4ZEatFxFoRMSki7u5hmzYAti+X5U+WZX8IWIss3Y5sm789vxbFL4AdJa1NXjHNA35Xtu81ks4uVSFPAz/rZfvWoetvGs33vS0rIqaTwfdo4JEy3zo9rOcs4H2SlgfeB9wYEfeWdbyuVGc8VNZxXDfp7XHfkbR1qVqZIele8gTeSuMc4GJg/zL7AcCZ5XVvv1e7k4DpwOXKqskje0rP0swBffgZ23ohaRR5GfxA+dugbd71yWqFlvZba3Z5X+qyPw98AFg9IlYDnqJRp9uLmcD66r3RbHHX0Z3mNswEri7Bv/U3KiI+QV49zKWRf2T+dLLchSdGPAFcTpYyP0heObW+c1z5/pYRsQpZxdTT9j1I199UbWnsdVkRcVZEvJn87QM4oYf03kaewHYr6T2rMfl7wB3A+LKOL3WT3t7y4xzgIrL0vAHwk7bv/xw4QNKOZFXcb8vnvf1e7emfExFHRMRryR5Yh3fXXrC0c0AffnaX9ObSaPU18nJ9JjAVeJ2kD0oaKWk/skrkol6W9TDQ7Eu8Mhn0ZgMjJR0FrNJhuq4jg9PxklaStIKkN3Uz3+Ksoy8XkXnwkdI4uaykbSVtFhEvAxcAR0t6laQJwIG9LKs9b7pzFlllsg9dA+TKwDPAU5LWBf6ll2VcDGwu6X3lZPgpupZQe1yWpE0k7VxK3S+QV3Pz+kjvp8krivPa1vE08IyyS+ii9iNfjax6mytpO7IU3jSVPOEcA5wTEa009vh7ta9A0p7KBmuRBYCX+9jWpZID+vBzFlkn/DjZmPVhgIh4DNiTbGR8jCwF7xkRj/ayrJOBfSQ9Iek7wGXApcBfydLcC3RQTVPW/zLwHrJe9z6yHni/bmZ9xevoIA1zyIbk/ckrlofIEuvyZZbDyOqrh8j62f/qZXE/BiaUqoBf9jDPFGA88FBE/Knx+b8BW5OB52LyRNJTmh8F9iV7iDxWlndNh8tavnzv0bJNrwa+2Ms2/Rx4G1n339wvPkeW2ucAPyRL3IviE8BXJc0BjiIbnueLiL+VdO9C48TXwe/VNB64gjy5/QH4bkT8tpv5lmpacJVoQ52kycCsiPjyYKfFzIYel9DNzCrhgG5mVglXuZiZVcIldDOzSjigm5lVotdBIANp9OjRMW7cuMFavZnZsHTDDTc8GhFjups2aAF93LhxTJs2bbBWb2Y2LJXbK3TLVS5mZpVwQDczq4QDuplZJRzQzcwq0VFAl7RreTzU9O7uQ6x8xNhsSTeXvyH9xHIzsxr12ctF+RzCU8nHYM0Crpc0pdxfuemciDhsoQWYmdkS0UkJfTtgekTcExEvks9l3Gtgk2VmZouqk4C+Ll3vVz2Lro81a3m/pFsknS9pbDfTzcxsAPXXwKJfAz+PiL9J+jj5CKqd22eSdAhwCMD66/f29K/ejTvy4lf83RrMOH6PwU6CmQ1BnZTQ76frMw7Xo+tzKomIx8pTSQB+RD5JZyERcVpETIyIiWPGdDty1czMXqFOAvr1wHhJG5bnWO5PPnprvvLk85ZJwO39l0QzM+tEn1Uu5cGvh5HPghwBnB4Rt0o6BpgWEVOAT0maRD7893HgoAFMs5mZdaOjOvSImEo+ubv52VGN11+k94fTmpnZAPNIUTOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrhgG5mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0p0FNAl7SrpTknTJR3Zy3zvlxSSJvZfEs3MrBN9BnRJI4BTgd2ACcABkiZ0M9/KwKeBP/Z3Is3MrG+dlNC3A6ZHxD0R8SJwNrBXN/N9DTgBeKEf02dmZh3qJKCvC8xsvJ9VPptP0tbA2Ii4uLcFSTpE0jRJ02bPnr3IiTUzs54tdqOopGWAbwFH9DVvRJwWERMjYuKYMWMWd9VmZtbQSUC/HxjbeL9e+axlZWAL4CpJM4AdgCluGDUzW7I6CejXA+MlbShpOWB/YEprYkQ8FRGjI2JcRIwDrgUmRcS0AUmxmZl1a2RfM0TEXEmHAZcBI4DTI+JWSccA0yJiSu9LsKFm3JG9NnVUb8bxewx2EswGRJ8BHSAipgJT2z47qod53774yTIzs0XlkaJmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrhgG5mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEh0FdEm7SrpT0nRJR3Yz/VBJf5Z0s6TfS5rQ/0k1M7Pe9BnQJY0ATgV2AyYAB3QTsM+KiC0j4g3AicC3+j2lZmbWq05K6NsB0yPinoh4ETgb2Ks5Q0Q83Xi7EhD9l0QzM+vEyA7mWReY2Xg/C9i+fSZJnwQOB5YDdu6X1JmZWcf6rVE0Ik6NiI2ALwBf7m4eSYdImiZp2uzZs/tr1WZmRmcB/X5gbOP9euWznpwNvLe7CRFxWkRMjIiJY8aM6TyVZmbWp04C+vXAeEkbSloO2B+Y0pxB0vjG2z2Au/oviWZm1ok+69AjYq6kw4DLgBHA6RFxq6RjgGkRMQU4TNIuwEvAE8CBA5loMzNbWCeNokTEVGBq22dHNV5/up/TZWZmi8gjRc3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrhgG5mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrRUUCXtKukOyVNl3RkN9MPl3SbpFsk/bekDfo/qWZm1ps+A7qkEcCpwG7ABOAASRPaZrsJmBgRWwHnAyf2d0LNzKx3nZTQtwOmR8Q9EfEicDawV3OGiPhtRDxX3l4LrNe/yTQzs750EtDXBWY23s8qn/XkYOCS7iZIOkTSNEnTZs+e3XkqzcysT/3aKCrpw8BE4KTupkfEaRExMSImjhkzpj9XbWa21BvZwTz3A2Mb79crn3UhaRfgX4G3RcTf+id5ZmbWqU5K6NcD4yVtKGk5YH9gSnMGSW8EfgBMiohH+j+ZZmbWlz4DekTMBQ4DLgNuB86NiFslHSNpUpntJGAUcJ6kmyVN6WFxZmY2QDqpciEipgJT2z47qvF6l35Ol5mZLSKPFDUzq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrhgG5mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaV6CigS9pV0p2Spks6spvpb5V0o6S5kvbp/2SamVlf+gzokkYApwK7AROAAyRNaJvtPuAg4Kz+TqCZmXVmZAfzbAdMj4h7ACSdDewF3NaaISJmlGnzBiCNZmbWgU6qXNYFZjbezyqfmZnZELJEG0UlHSJpmqRps2fPXpKrNjOrXicB/X5gbOP9euWzRRYRp0XExIiYOGbMmFeyCDMz60EnAf16YLykDSUtB+wPTBnYZJmZ2aLqM6BHxFzgMOAy4Hbg3Ii4VdIxkiYBSNpW0ixgX+AHkm4dyESbmdnCOunlQkRMBaa2fXZU4/X1ZFWMmZkNko4CupktMO7Iiwc7CYNuxvF7DHYSrBse+m9mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpVwQDczq4QDuplZJRzQzcwq4YBuZlYJB3Qzs0o4oJuZVcIB3cysEg7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWCQd0M7NKOKCbmVXCAd3MrBIO6GZmlXBANzOrhAO6mVklHNDNzCrhgG5mVgkHdDOzSowc7ASY2dJn3JEXD3YSBtWM4/cYkOW6hG5mVgkHdDOzSjigm5lVwgHdzKwSDuhmZpXoKKBL2lXSnZKmSzqym+nLSzqnTP+jpHH9nVAzM+tdnwFd0gjgVGA3YAJwgKQJbbMdDDwRERsD3wZO6O+EmplZ7zopoW8HTI+IeyLiReBsYK+2efYCflJenw+8Q5L6L5lmZtaXTgYWrQvMbLyfBWzf0zwRMVfSU8CawKPNmSQdAhxS3j4j6c5XkughYDRt27Ykafhf/zj/Fp/zcPEM5/zboKcJS3SkaEScBpy2JNc5ECRNi4iJg52O4cr5t/ich4un1vzrpMrlfmBs4/165bNu55E0ElgVeKw/EmhmZp3pJKBfD4yXtKGk5YD9gSlt80wBDiyv9wGujIjov2SamVlf+qxyKXXihwGXASOA0yPiVknHANMiYgrwY+AMSdOBx8mgX7NhX200yJx/i895uHiqzD+5IG1mVgePFDUzq4QDuplZJRzQhzhJq0raqrz2YK1XQNJYSe8c7HQMZ5LeIumzkpYf7LQMJ0qvl7R/6/1Ars8BfYhq/PAbAIdLWsk9hxZN6UILMA/YqXVQWWckjZDUihE3AQ8A/yJp2UFM1rBQ8k7lmH0QeJ+kcQN9DDugDyGNg4fWDx8RtwB3AB+UtPpgpW24aMvDueX//cC/A2+RtMtgpW04KCXKZQAi4uWImFcKE89ExDnA2sDeg5vKoambvAtJy0XEI8AlwF6SNhzINDigDwGNnWBe47P3S5pU3p4DrA68aRCSNyy056GkV0n6jKTDJW0QEc8Av6f+LrWLrL0gUYL4CpK2l/Rb4GRJ7y6zXAS8b1ASOsS18g5A0laSzgdad6dtjd3ZdiDT4IdEDxJJIyLiZegShLYDdgKeAN4NvErSfRFxs6R7gXUkjSrBaanXnoelmuqdwFuAJ8n7dcwCvgnsC1wAfNx52FVbQeJtwO7knVUfBQ4H5gInA5dFxCXlJLlWRDw0KAkeAspdaOc1q1AkvYEsMGwKXAOcAewu6R0R8d+SHgBWLlc8zw5EulxCXwLKpdiKkubfO6IViCStLGljSWcCnwR2AN4eER8EzgN2LHWWDwMrA88v+S0YGiSNkrSNpJWhSx5uVD67ijwh3kWWjL4WEacCK0naJiL+BtwAvHlQNmAIkLSJpP0krdj47K2S/kHSKsAPyDzal7xl9qyI+DPwmKS/K1+5mgz4S5WSdwdDlyqV10p6o6SdgP8E7gSuADaJiF8BlwMTJK0AzAbWjYhnB6px1AF9CShn8fXIgwQASQdKuhQ4ABgFrECWJD8FzJC0GTANWAtYH/gLsF0riC2lNgAOjIg55SR5gKTLgeMiYg7wFHBdRPwU+DUL6np/A3y0vL6NbKRaWgnYNSKeB5D0beAzwIiIeBq4EZgTES+QJcx9yvd+C/xDef0ycPMSTfXQsAo5Wr71UJ+fkHk0BngI+CuZf+cDd0h6PXAdefxuTDYsbwEL2sj6mwP6AOjh7Ls1WYJE0lhgInB0uQPlHeRZfSJZVfAIsHVE3AksB2wIvAhMl7TWgG/AEFAuadvdBqwhafVyQGwP/HtE7Fem/zdZQodsdzigvD4faHW32x64e2BSPTS0evf00BvlXvLW1euU6fOAIyLih2X6b8hqK4BfAgeV1z8h8xHypDAgVQZDRQ/735tYcCvxnYD7I+JNEXE5WUi4mty/HgaeA3aKiJnAPeRJcCXgEkmrDlS6HdD7SWmEe08j2LQ+b+Xxiiy41N8I2DAirgUopaG/AOPJg+VBYLTyZmgnRsQVZED/Zs31lpKWk3R0s268zWjgFmBDSaPJ+wY90Jh+ASWPI+Iy4FlJq0TEzIg4tMxzREQ8M1CXvINN2U/8ckkjI+KlciXT3NYxwAzyym8MWYBYrTH9AvIBNStExDXAd8sJ4rlShUBEHFeqr6oiaX1JX5G0RnP/04Lurw8De5bXz5IFMADKFc9dZAl8FeDPwP+Vffl7EXE78GBETI6IpwZqGxzQF4OkZSS9ptSPrUKetbcqn727bfZLy3Qi4ipgFUlrl+W8ljyjP0OWxi+JiJMj4sWIeKJ854XW69pI2rKcCF8kr2TeJWlTSZ+UtHFj1nlkHo0jG46fJ7siriRpX7IB9HZJrcva/SLi6VZAKwfXnDKtqj79kvaWNKYE2ruBT0j6MnAmWRfe8hSZh1tExAPkra/3l/RhSeeVeY4j2x0UET+JiLnt+VXDCVHSsqUNa6tyDD9OlqT3Lg2/x8KC7q9kT5UtJC0fEdcBK0jasbRBfJBsPL4SWDYifhcRlzbaeVp90gc07xzQX4ESbPYmn8o0kQzCTwPXAkcA3wc+rRydKIBSsn5Q0u5lMecBR0r6E/BxsprlxIi4o8bST7tyMmxd1m4PtKpNLgD+mXyy1WjyGbUARMRjZCloSzLvfwi8hjzQPkA2OH0iIv7SCOLLNPr0V9P+UPKvGRjWBr4p6e1k98y9yZL48cCXWzOV0uE0YDNJr4uI04HbyUdNnhkRT0XEORHxWG8BaLifECXtAXyOrAbZCngPsCOZNx8Cguxl9uES7Ck9U24H3l8W83myR9DXyALZTRHxy4hY6ElIzfwa0LyLCP91+AeMLP/XJ+sU1yG7c/2BrLPdieyn+2pgG7LL18aN7+8BHAusX95vALy2bR0a7O0chHzdA3ih5OGWZF34NmXaL4FtG/MuSzYcf6G8fxUwqm15ywz2Ng1QPi20b5AN6tuRJ8RnyQLFimTvii3LPGcCOzeXAXwEOLGn/a2WPGxs70bl/4jyf0WyQDAWuJjsnXJs2f8uANYge/IcDkxoLG8i8EVgj/J+uU5+pyX15xJ6HyStKel46HLptQpZQhxDXqb9FfgSGdinkQfY3cBLwOsai7sEmAp8uVQx3BsR9zTrOaPsEbUom7bQflbaGz6t7K75ONmg9I3ILnK3klUvkFVVB5TvjIyIl8gAtZqkzSPiucg68WXUzQCtGrSuZJr7hqTNJE0GTgCOJvs9nw/8T2R97jTgHWX2S4B/LK9bv8V5ZD6vW5bX5XeqJQ8jIpQjrPcq71+WtA0ZlF9Ptmf9F3A6WTj7C/A/wN+RVzgvU3qmlO9PI08EO5e69hehayPqYB7DDujdaNuxHwO+qgU9B75OXsbOAQ4l++3+HhhffsgbgTdExJPkZdj6jUu2eRHxv2Q3uyeaQby2QN5SNm3+6M3y/yNk74lHyQPmeeBHLOhRcS4L6n0vJAdqzD+hlt/kGxFxa2M982oJQrDQPtiqh91J0qbl4z1ZUKr8K7AJeYXTegj7+SwY0Xk+cGOpx20NxHohsn58VnkfFeffE8APtGDY/YFkn/BzgL8nj99nySvBIKtVdiD3y/uB5xrHvyLi0Yg4IiIeb6xjSFTneaRo0Wy0aASgZcn68deR1QKfIPuL7012J/wRmYcvAeuVg+1xYEVJ65HB6JnWWbwlImaU/1UF8XKCUnQdefhqsv/9vsANkk4hGzf/EBFnSnquTDsB+GdJ25LPo11d0jqRDXe7t68rss90NdQ2erAtD/ckS9gjgLuV4xfuATaIiAclXUbm0ReAIySdCPwKuFrSqpH15if1sF7Vsh+2H8MlCK9NVpMsC7xf0j8Aq0TEfyoHV51OVr88DOwgaQLwJ/LqZXXgF838abtKGnJ5t1SX0FX6gzYbzsr7zSR9lqyfPI68BBtfLqs2AsY2Dr63k/WVm5ENeHPJEvisiHi8PZjXRtIakg5R3i8lyoG0pqTtyyxvI0dt7kf2APgcMJ1sZ4AckLExmW8/Iwe5LAvsFhEPtEpa3VXb1ELZy+koSZuX96tI+lzpabEceRWzSUTsCfyULHnfx4LRmiuR7TprAP9KXiVOi4ivRKOLXG2Nm5I2l7R1eT2ytS2l+m1f4GyyN9TBEXEuGaDnko2dW5eqqZXIBtEpZMcEAddHdi98vLf8GYp5V+1B0hdlN6PvLHirZSV9UNJGwBvI0vjLZGlyBBmEtidHIH5U0n7kAbQ52W/8qxGxW0RcGwN0n4ahQl0HRqxAtidsW6b9Pfn82b0kHQ38guwm9xhZTw7Zp36kpP8kqwheAN4ZEadFxIci4paIeKGcaOdBPXW60DUQFXPIAP368v5zZGPvTcD5EXEJOfR+bbIf/vPkVeEtkq4EJpEDXt5W9r+zo/SUUjd38BzuGvXVr6f04Il89vGKkr5B9lZZnTw+1wSeKleKNwM7A98DDpB0IXmFPTsi/hYRp0TESaW6dFh2zVxqAnqz0ay4iKzfHhl5X4aXyAEWbyPrIy8l69GeIXujXAgcGhE/JuvcJgEnRcQXS8n0mdZ6ltxWLXltJ0LIusg/k93gRPbu2RWYDBzMgm6F+5c8eoAccfdV4HdkVcsfaIw8rL1xk0YgKlrdMTdVDgzahLyfyluBjZX3WLkC2LfspzOAN0XEd8jS+j+RAf7Gsp7qGjehy37Rqq8+h2wcX7V8/jzZQ2pzcj+8iiycrUQe2xcDn42I35INoD+OiN0j4ufNdTTbtpbEdvWn2oPPmNbrVqNZuZxdpdTB3gu8t/GVn5BVAG8i68KfIusmR5BDol9QjqC7opQkr2hfZ00HEPR+IgQoAeb/yKH1E8i8upa80djHI+JBMu8+Vr5/DnBN5ACfW8iG0IPJBj7KMqvLQ+g1EM0jg/Q8sofU/WRj56+AiWVfvZAFoxRPi7zpGOWzC8mA9UhjecOeUpeTk6TVJB0kadOSn3+icY+kckzeRvZMEblfTQKWj4irgVNK3fesiLiorKfLOoZjIG+pLqC3zq7KniX7aEHPis2VXeSuBP5JOXR8MmWQQLm8f5YsCc0jG5z+CFwP83/oQyKH6bfWVV3+wSs6ET5EXvLvSAb8aeSgi3UlfaYcZN8qB9L0iLipfG8d4I9kaXMmlXglgYhslJtBtsWcQd7UaVvgbElfiIibKXkeXW/9ezWwe0R8vJwkq9Fqk2m9l/R+8iS3PRyKivkAAAVqSURBVDmacxuyEDapTG+VrH9P1p2/JiLuIAsM95X9b0p7wK7lBAgVBfT2y6QSeMcD/yvpcOBvwGlkI+Yo4CORQ/BfLWl0OehGlkbMC4Gryg7wnoi4obGeWi9nX9GJsHiCrDJ4LXnJOxU4i+zjfD5A80BqlFivjIgLo7KG40UNROU7T5E9V7YgS5U/Iq96Do+IE8o8z7XX60bep+alAd6kAaeFR76ifBbntySdLOk1ZB6+m+w3vj15IruZbI/ZKCJCC25I9g3yKVVExH9FjoAdtiXvTg3rgN5dg4+k10naR9KaZdILwOkRMZ3c3nPJnWF8qZucxoLqgNbJ4PuRfXRby2wOGqgmiMPinwjLd+aRdePPkb1XzoiI90fE0VH6OTfVlIf9EYgaX51BVk+NiIjrIxvppjeXXVNQauZbq6qjdXWo7CX1S7Jh+Ddku81IsrT9aXIg1Wjl3UevJYfrQ/ZiISKuiYi7u1tXzYZlQG8EoXltnx9KnpU3IX/075I7wyZllu3Jg+pgsh/5W8n7rvylLK95hzU11jMkBg30lwE4EQLcFRHHRsR9zRNhjQfSAAUiSt79ulV10twHa9JeiCif7SjpV8AZyob3B8grlutKXfcjZNfXl8nqqAeAVckG0H8HvtXNMpu/UzUnwt4My4FFjYDxbrKV/3ulxLM6eX+KeeTDIm4k7zX+FrKu9lZylOedLGice4Js1Ot2HTUpVUhdqgPK54eSA6euJW9U9F2y18kmZL61ToR/BI5iwYlw89Yyopu7ylV4ImzlX5dARPazX17ST8meO61AdGfZR5uB6FEy31qBaKGA3d16atI4fieRQflnZI+yUyPickm/II/hn5F5dwx57D5Ktt98izxZHhm93E661vzrjYbjNit7B/wbWWc7lbwr36Nk96TDyEal88iS91pkPe5jZI+K0RHx17blDbkRXwOp/UQo6YtkV8zWifAEMi/XjohvSnoPXU+El0elt/LtRFsg+gxwayMQnUeOPBwbEceUk+VMugaiM3oLRLUr9dynkH3EjyX3q8+T1Xovkl02v0ceu5PJ7ofbAO9dmvOtE8M1oI8E/gVYOSK+VEpJB5KDWPYmS5h7k13ojiHvaDi9bRnLUNqvlmjiB5FPhIvHgah/lCq7z5OD9FYn83EH8iZsHyCH629O5ufngHsj+9zP3+fUzUOabZjWoUfepOkqcpQiZFC6hyxlXkoOtHgS+Fap45wO3dd9Lsl0DwHPkt3j/hIR3yd7pLyB7A9+CVlP/l5y0M/D5PM7J0UOgf4rDP+BF4tpRXIg1Ulk0F6LvDHWHPJufj8kBw3NIvfDOyNih4h4qNGLqMp2hUUR2fX1THLU5spkoesBskB2BpmPy5H74G1k99Yuw/ujPKR5yad+aBuWdejF7cCakr5D9t29PCKel/TriJjS3ReW9h0gcnj0VSzo/9w8Ea5InghvB35S6tnnnwgbB1I1PVQWVeTTj84kT3rTyUD0IxYEotXJq8NWIBoP8wNRq/dFVe0Kr1RE3C7pAfKumiPIOvLrgEsj4uHWfMqHgD9S9sG53S/NWoZllQvMrzLZH3gXcHIsGKwyf/rSHHx6Imk1ctjzUyw4EZ60tFWfLI5SdbUb2Y/8U+SVzyptgWgsefVzkfN1Ycqbjh1NVl9Njog/tE3v6bmy1othG9Ah+/uST175epT7i/vg6Z1PhIvHgciGsuFc5QLZ3XAa2ePgCQfzvkWOiG09EWgGuEplUUSOav1SL9MdzBeBKr0R22AZ1iV0e2VKL4PdgWujPGzDFo0DkQ1FDuhmZpUYlt0WzcxsYQ7oZmaVcEA3M6uEA7qZWSUc0M3MKuGAbmZWif8Hheh1n1m37WwAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "owVs6pvJ8F8B" + }, + "source": [ + "## Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RISO1Ury8EEH", + "outputId": "943423c9-1aa1-448c-b737-ee23adda9e31", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao = df_iris.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k = 1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Sepal Lengthsepal widthpetal lengthpetal widthtarget2
Sepal LengthNaN0.117570.8717540.8179410.782561
sepal widthNaNNaN0.4284400.3661260.426658
petal lengthNaNNaNNaN0.9628650.949035
petal widthNaNNaNNaNNaN0.956547
target2NaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " Sepal Length sepal width petal length petal width target2\n", + "Sepal Length NaN 0.11757 0.871754 0.817941 0.782561\n", + "sepal width NaN NaN 0.428440 0.366126 0.426658\n", + "petal length NaN NaN NaN 0.962865 0.949035\n", + "petal width NaN NaN NaN NaN 0.956547\n", + "target2 NaN NaN NaN NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 262 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lieB7hDg8EEM", + "outputId": "a6c1c02d-3c2f-41e8-c1e5-6154f34d95ae", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 500 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize = (8, 8)) \n", + "mask = np.zeros_like(df_iris.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_iris.corr().abs(), mask = mask, ax = ax, cmap ='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 263 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A_FXdDMr8EEQ" + }, + "source": [ + "> Pela Análise de Correlação, vemos duas variáveis altamente correlacionadas com a variável-resposta, que são: 'Petal Width' e 'Petal Length', que são as duas variáveis mais importantes no dataframe. Lembram-se?\n", + ">> No entanto, confira a correlação entre 'Petal Width' e 'Petal Length'. Observou que a correlação entre elas é de 0.96? Estas variáveis são altamente correlacionadas..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "taei2KXSTmZ0" + }, + "source": [ + "### Usando SelectFromModel()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JLwboa9tTpBq", + "outputId": "ea927ac2-d0c4-4e10-ae72-7f9014aae8bb", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# A partir do Random Forest, seleciona features cuja importância seja maior que 0.15 e 0.45\n", + "sfm = SelectFromModel(rf, threshold = 0.15)\n", + "sfm_2 = SelectFromModel(rf, threshold = 0.45)\n", + "\n", + "# Treina o seletor\n", + "sfm.fit(X_treinamento, y_treinamento)\n", + "sfm_2.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SelectFromModel(estimator=RandomForestRegressor(bootstrap=True, ccp_alpha=0.0,\n", + " criterion='mse', max_depth=None,\n", + " max_features='auto',\n", + " max_leaf_nodes=None,\n", + " max_samples=None,\n", + " min_impurity_decrease=0.0,\n", + " min_impurity_split=None,\n", + " min_samples_leaf=1,\n", + " min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0,\n", + " n_estimators=100, n_jobs=None,\n", + " oob_score=False,\n", + " random_state=20111974,\n", + " verbose=0, warm_start=False),\n", + " max_features=None, norm_order=1, prefit=False, threshold=0.45)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2MiZrU56VzUW", + "outputId": "d64749e9-8883-4432-e68d-bfe4c1b8c7f1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Mostra as duas features mais importantes para sfm\n", + "for feature_list_index in sfm.get_support(indices = True):\n", + " print(l_iris_labels[feature_list_index])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Petal Length\n", + "Petal Width\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M0junBxr79Th", + "outputId": "e150591e-1db0-4754-8999-f5e198d3bd60", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Mostra as duas features mais importantes para sfm_2\n", + "for feature_list_index in sfm_2.get_support(indices = True):\n", + " print(l_iris_labels[feature_list_index])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Petal Width\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "neMolQ0gYtp7" + }, + "source": [ + "Selecionando somente os atributos mais importantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dXRWZgDeYxHS" + }, + "source": [ + "# Constroi um dataset contendo somente as variáveis mais importantes\n", + "# Nota: Neste caso, estamos a aplicar a transformação tanto na base de treinamento quanto de validação\n", + "X_treinamento_rfi = sfm.transform(X_treinamento)\n", + "X_teste_rfi = sfm.transform(X_teste)\n", + "\n", + "X_treinamento_rfi_2 = sfm_2.transform(X_treinamento)\n", + "X_teste_rfi_2 = sfm_2.transform(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1tmpt3YvZFvW", + "outputId": "a214e4c8-b1f9-4599-b018-757235a1aa0d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Criar um classificador Random Forest somente com as features mais importantes\n", + "clf_rfi = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50)\n", + "clf_rfi_2 = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50)\n", + "\n", + "# Treina o modelo com as features mais importantes\n", + "clf_rfi.fit(X_treinamento_rfi, y_treinamento)\n", + "clf_rfi_2.fit(X_treinamento_rfi_2, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=10000,\n", + " n_jobs=50, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 268 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "epVwhUeYZM7v", + "outputId": "1503fb45-653c-4c2a-9304-c3d0689b300d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "from sklearn.metrics import accuracy_score\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "\n", + "# Aplica o Classificador no dataframe teste\n", + "y_pred = clf_rfi.predict(X_teste_rfi)\n", + "\n", + "# Verifica acurácia\n", + "accuracy_score(y_teste, y_pred)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred) \n", + "index = ['setosa', 'versicolor', 'virginica'] \n", + "columns = ['setosa','versicolor', 'virginica'] \n", + "cm_df = pd.DataFrame(cm, columns, index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot = True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 269 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CA_rhTMiZbLN", + "outputId": "a1af75c9-690e-49a0-ed79-87259804b06b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Aplica o classificador na base de teste\n", + "y_pred_rfi = clf_rfi.predict(X_teste_rfi)\n", + "\n", + "# Avalia acurácia\n", + "accuracy_score(y_teste, y_pred_rfi)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred_rfi) \n", + "index = ['setosa','versicolor','virginica'] \n", + "columns = ['setosa','versicolor','virginica'] \n", + "cm_df = pd.DataFrame(cm,columns,index) \n", + "plt.figure(figsize=(10,6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 270 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lIYvP0Bq8ST_", + "outputId": "c16ef565-c421-42a2-a9c9-48fc04d4d6bc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Aplica o classificador na base de teste depois da análise de correlação\n", + "y_pred_rfi_2 = clf_rfi_2.predict(X_teste_rfi_2)\n", + "\n", + "# Avalia acurácia\n", + "accuracy_score(y_teste, y_pred_rfi_2)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred_rfi_2) \n", + "index = ['setosa','versicolor', 'virginica'] \n", + "columns = ['setosa','versicolor', 'virginica'] \n", + "cm_df = pd.DataFrame(cm,columns, index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot = True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 271 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uWdAUMQoZtaV" + }, + "source": [ + "> Como podemos ver:\n", + "* Modelo original (com 4 atributos) presenta acurácia de 93.3%;\n", + "* Modelo reduzido (com 2 atributos) apresenta acurácia de 93%;\n", + "* Modelo reduzido 2 (com 1 atributo) apresenta acurácia de 93%.\n", + "\n", + ">> Ou seja, reduzimos o modelo de 4 para 1 atributo/variável e a acurária continua a mesma." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OfCq7UGIpSYg", + "outputId": "5bec1c14-5210-4e28-84a2-b795ef78fe5a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Correlação dois a dois...\n", + "df_iris[['petal length', 'petal width']].corr()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
petal lengthpetal width
petal length1.0000000.962865
petal width0.9628651.000000
\n", + "
" + ], + "text/plain": [ + " petal length petal width\n", + "petal length 1.000000 0.962865\n", + "petal width 0.962865 1.000000" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 272 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BMfxK3UCbjfc" + }, + "source": [ + "## Feature Selection With XGBoost (Extreme Gradient Boosting)\n", + "> XGBoost, em geral, fornece melhores soluções do que outros algoritmos de Machine Learning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8ZYGjr0Su4y-", + "outputId": "919fa042-5b49-4378-a46b-cf33f6469e48", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "!pip install xgboost" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: xgboost in /usr/local/lib/python3.6/dist-packages (0.90)\n", + "Requirement already satisfied: scipy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.4.1)\n", + "Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.18.5)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "--vKKHVWbwGv" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "\n", + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_d5qWQmXgPIH", + "outputId": "1a2fe686-b70e-4812-d129-304cefd93611", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Cria um clasificador XGBoost\n", + "clf = XGBClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50, max_depth = 5, learning_rate = 0.05)\n", + "\n", + "# Treina o classificador\n", + "clf.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Calcula o y_pred e avalia a qualidade do ajuste\n", + "y_pred = clf.predict(X_teste)\n", + "predictions = [round(value) for value in y_pred]\n", + "accuracy = accuracy_score(y_teste, predictions)\n", + "print(f\"Acurácia: {accuracy}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácia: 0.8666666666666667\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fTdKMOKdC2UA", + "outputId": "0421c20e-1af7-473b-f0fa-4a77c4d1d3dd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Adaptado de https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/\n", + "# Ajusta o ML usando cada importância calculada como threshold\n", + "\n", + "thresholds = sorted(clf.feature_importances_)\n", + "for thresh in thresholds:\n", + "\t# seleciona as features usando threshold\n", + "\tselection = SelectFromModel(clf, threshold=thresh, prefit=True)\n", + "\tselect_X_treinamento = selection.transform(X_treinamento)\n", + "\t\n", + " # treina o ML\n", + "\tselection_clf = XGBClassifier()\n", + "\tselection_clf.fit(select_X_treinamento, y_treinamento)\n", + "\t\n", + " # Avalia o ML\n", + "\tselect_X_teste = selection.transform(X_teste)\n", + "\ty_pred = selection_clf.predict(select_X_teste)\n", + "\tpredictions = [round(value) for value in y_pred]\n", + "\taccuracy = accuracy_score(y_teste, predictions)\n", + "\tprint(f\"Threshold= {round(thresh,2)}, n= {select_X_treinamento.shape[1]}, Acurácia: {round(accuracy*100.0,2)}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Threshold= 0.009999999776482582, n= 4, Acurácia: 86.67\n", + "Threshold= 0.03999999910593033, n= 3, Acurácia: 86.67\n", + "Threshold= 0.44999998807907104, n= 2, Acurácia: 86.67\n", + "Threshold= 0.5, n= 1, Acurácia: 86.67\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zv2gbuc5glFJ", + "outputId": "490e0459-db4a-4406-f4f4-5f5d70519cce", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "# Calcula a importância das features\n", + "importances = clf.feature_importances_\n", + "\n", + "# Ordena as importâncias por ordem descendente\n", + "indices = np.argsort(importances)[::-1]\n", + "\n", + "# Organiza...\n", + "names = [iris.feature_names[i] for i in indices]\n", + "\n", + "# Barplot\n", + "plt.bar(range(X_treinamento.shape[1]), importances[indices])\n", + "\n", + "# Coloca o nome dos labels no eixo X\n", + "plt.xticks(range(X_treinamento.shape[1]), names, rotation=20, fontsize = 8)\n", + "\n", + "# Constroi o gráfico\n", + "plt.title(\"Feature Importance\")\n", + "\n", + "# Mostra o gráfico\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cXTwXiB_LVB3", + "outputId": "83b9f975-bd71-4604-aded-b8310da30193", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred) \n", + "index = ['setosa','versicolor','virginica'] \n", + "columns = ['setosa','versicolor','virginica'] \n", + "cm_df = pd.DataFrame(cm,columns,index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 278 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_ebv3nAzU2ac" + }, + "source": [ + "## Feature Selection using PCA (Principal Components Analysis)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8M5uO9r-Vtze" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wWS8bvXzX4Fg" + }, + "source": [ + "### Standardize the Data\n", + "* O PCA é afetado por escala, portanto, é necessário dimensionar as features/atributos antes de aplicar o PCA.\n", + "* Use o StandardScaler para padronizar os features/atributos usando com média = 0 e variância = 1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2oVG8_1HXweo" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.decomposition import PCA" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xYXnYebxclya" + }, + "source": [ + "Standardizing as features de X:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iDMzHm3mcpbs" + }, + "source": [ + "X_STD = StandardScaler().fit_transform(X_iris) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MmKMCuvMc63E" + }, + "source": [ + "pca_2c = PCA(n_components = 2)\n", + "X_PCA_2c = pca_2c.fit_transform(X_STD)\n", + "df_PCA_2c = pd.DataFrame(data = X_PCA_2c, columns = ['PCA1', 'PCA2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0Yfvb02JdV8B" + }, + "source": [ + "Vamos entender o que está acontecendo:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-PVc1vJ8d_w6" + }, + "source": [ + "Primeiramente, observe nosso array X abaixo. Cada coluna desse array representa uma coluna do dataframe df_iris. Por exemplo, a primeira coluna são os dados da variável 'Sepal Length'. Identificou?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BEp1JD0Odd3L", + "outputId": "28a25a6b-d24a-4e3d-cbf0-2f3af24b4298", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Listando as primeiras 5 linhas de X\n", + "X_iris[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[5.1, 3.5, 1.4, 0.2],\n", + " [4.9, 3. , 1.4, 0.2],\n", + " [4.7, 3.2, 1.3, 0.2],\n", + " [4.6, 3.1, 1.5, 0.2],\n", + " [5. , 3.6, 1.4, 0.2]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 286 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "41-KcSTneURx" + }, + "source": [ + "Segundo, com a standardização, construimos o array X_STD, que mostramos abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "igBQNHS5eaND", + "outputId": "93a6ece8-138e-4f56-f44a-061c45c7380e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_STD[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.90068117, 1.01900435, -1.34022653, -1.3154443 ],\n", + " [-1.14301691, -0.13197948, -1.34022653, -1.3154443 ],\n", + " [-1.38535265, 0.32841405, -1.39706395, -1.3154443 ],\n", + " [-1.50652052, 0.09821729, -1.2833891 , -1.3154443 ],\n", + " [-1.02184904, 1.24920112, -1.34022653, -1.3154443 ]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 287 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TgRD7-qPjg29" + }, + "source": [ + "Veja abaixo a média e desvio-padrão do array X_STD:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M0VL4ilZjliL", + "outputId": "cd424bdd-ef89-45b1-c965-2695797f5a87", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.mean(X_STD),np.std(X_STD)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(-1.4684549872375404e-15, 1.0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 288 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pyDJwNCgju0O" + }, + "source": [ + "Temos média 0 e desvio-padrão 1, certo? É isso que queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KB7R7OXQemze" + }, + "source": [ + "Por fim, a partir de X_STD, construimos o array X_PCA_2c, mostrado abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lNmAskXWerqG", + "outputId": "2f417913-1e00-445e-a990-6a1cbce2b417", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_PCA_2c[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-2.26470281, 0.4800266 ],\n", + " [-2.08096115, -0.67413356],\n", + " [-2.36422905, -0.34190802],\n", + " [-2.29938422, -0.59739451],\n", + " [-2.38984217, 0.64683538]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 289 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fT2N6Ym7fBt-" + }, + "source": [ + "Portanto, reduzimos (ou resumimos) o array X_STD de 4 dimensões para um array de 2 dimensões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cA54fhYgfQuC" + }, + "source": [ + "Finalmente, o dataframe final é mostrado abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kAQ4O9EBfUlN" + }, + "source": [ + "df_PCA_final_2c = pd.concat([df_PCA_2c, df_iris[['target']]], axis= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JXrOdfSZPBS_", + "outputId": "21e43aaa-c78d-4779-86e4-e4ec6864b1e9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_PCA_final_2c.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PCA1PCA2target
0-2.2647030.480027setosa
1-2.080961-0.674134setosa
2-2.364229-0.341908setosa
3-2.299384-0.597395setosa
4-2.3898420.646835setosa
\n", + "
" + ], + "text/plain": [ + " PCA1 PCA2 target\n", + "0 -2.264703 0.480027 setosa\n", + "1 -2.080961 -0.674134 setosa\n", + "2 -2.364229 -0.341908 setosa\n", + "3 -2.299384 -0.597395 setosa\n", + "4 -2.389842 0.646835 setosa" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MEbvp3RFf-zs" + }, + "source": [ + "### Visualizar reultados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GEqP-NVngBO1", + "outputId": "8ff483a3-ba1b-4579-deb2-400020f310c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 523 + } + }, + "source": [ + "fig = plt.figure(figsize = (8,8))\n", + "ax = fig.add_subplot(1,1,1) \n", + "ax.set_xlabel('PCA1', fontsize = 15)\n", + "ax.set_ylabel('PCA2', fontsize = 15)\n", + "ax.set_title('2 componentes PCA', fontsize = 20)\n", + "targets = ['setosa', 'versicolor', 'virginica']\n", + "colors = ['r', 'g', 'b']\n", + "for target, color in zip(targets,colors):\n", + " indicesToKeep = df_PCA_final_2c['target'] == target\n", + " ax.scatter(df_PCA_final_2c.loc[indicesToKeep, 'PCA1']\n", + " , df_PCA_final_2c.loc[indicesToKeep, 'PCA2']\n", + " , c = color\n", + " , s = 50)\n", + "ax.legend(targets)\n", + "ax.grid()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pZaGiGnUl6ER" + }, + "source": [ + "O que significa reduzir para 2 dimensões um array com 4 dimensões?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xF-whgBmlHN1", + "outputId": "a23c21ca-cc81-48ee-f293-067c4ea585d1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 654 + } + }, + "source": [ + "X_new = pca_2c.inverse_transform(X_PCA_2c)\n", + "plt.figure(figsize=(10, 10), dpi=80)\n", + "plt.scatter(X_STD[:, 0], X_STD[:, 1], alpha=0.2)\n", + "plt.scatter(X_new[:, 0], X_new[:, 1], alpha=0.9)\n", + "plt.axis('equal');" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XvLDQ2JF5NP8" + }, + "source": [ + "### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DK3R415_5RzY", + "outputId": "7bb27d07-dda9-4f39-ec26-39b20f49a0ca", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao= df_iris.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k=1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Sepal Lengthsepal widthpetal lengthpetal widthtarget2
Sepal LengthNaN0.117570.8717540.8179410.782561
sepal widthNaNNaN0.4284400.3661260.426658
petal lengthNaNNaNNaN0.9628650.949035
petal widthNaNNaNNaNNaN0.956547
target2NaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " Sepal Length sepal width petal length petal width target2\n", + "Sepal Length NaN 0.11757 0.871754 0.817941 0.782561\n", + "sepal width NaN NaN 0.428440 0.366126 0.426658\n", + "petal length NaN NaN NaN 0.962865 0.949035\n", + "petal width NaN NaN NaN NaN 0.956547\n", + "target2 NaN NaN NaN NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 294 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uLvvzpvl5Zy9", + "outputId": "02c8c610-efe1-45a0-e5c1-7bd308513e56", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 500 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize=(8, 8)) \n", + "mask = np.zeros_like(df_iris.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_iris.corr().abs(), mask= mask, ax= ax, cmap='coolwarm', annot= True, fmt= '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 295 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xo-llZpb7JfO" + }, + "source": [ + "Pela Análise de Correlação, vemos duas variáveis altamente correlacionadas com a variável-resposta, que são: 'Peta Width' e 'Petal Length', que são as duas variáveis mais importantes no dataframe. Lembram-se?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kjPawS_dgSKU" + }, + "source": [ + "### Variância explicada\n", + "* Como vimos, reduzimos um array de informações de 4 dimensões para um array com 2 dimensões. Com isso, perde-se alguma informação relativa à variância. Mas quanto perdemos?\n", + "\n", + "* A Variância Explicada (ou Explained Variance, em inglês), mede o quanto de informação (variação) foi atribuída a cada um dos componentes principais. Usando o atributo explain_variance_ratio_, é possível ver que o primeiro componente principal contém 72,77% da variação e o segundo componente principal contém 23,03% da variação. Juntos, os dois componentes contêm 95,80% das informações. Portanto, perdemos quase nada em termos de informação e o modelo não é prejudicado por esta redução.\n", + "\n", + "\n", + "A resposta à essa pergunta é:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i6gcdvtYgwpX", + "outputId": "d416ed99-d2aa-4f64-cad9-9ba37903aa3e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.72962445, 0.22850762, 0.03668922, 0.00517871])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 298 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "71ubjjflQEUf" + }, + "source": [ + "Observe que o terceiro e quarto valores são muito baixo. Ou seja, baixa variabilidade explicada... Portanto, daqui já conseguimos ver que o número ideal de componentes são 2." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m_4TqauJvIvX" + }, + "source": [ + "### Quantos componentes escolher" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2NRgjCjvUli", + "outputId": "da0675c7-c382-48d7-eccb-1f00037e5aff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 279 + } + }, + "source": [ + "pca = PCA().fit(X_STD)\n", + "plt.plot(np.cumsum(pca.explained_variance_ratio_))\n", + "plt.xlabel('number of components')\n", + "plt.ylabel('cumulative explained variance');" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AvQ6KwQdwAdC" + }, + "source": [ + "**Interpretação**: Esta curva quantifica quanto da variância total de 4 dimensões está contida nos primeiros N componentes. Por exemplo, a primeira componente principal tem aproximadamente 95% da variação, enquanto que 2 componentes (os dois primeiros) explicam quase 100% da variabilidade. Portanto, em nosso caso, 2 componentes principais são suficientes para captar grande parte da variabilidade dos dados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S151TcjQw6vc" + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2dNWrsMCyUUE" + }, + "source": [ + "### Medindo o impacto" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ueFuNN47zMd6" + }, + "source": [ + "#### Treinar o modelo com X_PCA" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yb4dpTHPyYlU" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mr3tAGbjTET8" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_PCA_2c, y_iris, test_size = 0.2, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IzCZCBSmylwZ", + "outputId": "d8218700-7b4d-40b3-be83-dd2f87c8f400", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Optamos por 2 componentes principais\n", + "classifier_2c = RandomForestClassifier(max_depth = 2, random_state = 0)\n", + "classifier_2c.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=2, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=100,\n", + " n_jobs=None, oob_score=False, random_state=0, verbose=0,\n", + " warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 307 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BiDgWh2PzYEY" + }, + "source": [ + "#### Fazer as predições" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A7V8DWW4zVPs" + }, + "source": [ + "y_pred_2c = classifier_2c.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JTm4msQy2ezQ" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "* Para cada um dos dataframes a seguir, selecione os melhores atributos utilizando as seguintes técnicas técnicas:\n", + " * Random Forest\n", + " * XGBoost\n", + " * RFE" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 1 - Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_cancer['target'] = df_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zA395jtOfGEl" + }, + "source": [ + "## Exercício 2 - Fraud Detection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "14fV0gz0flb8" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "url= 'https://raw.githubusercontent.com/MathMachado/Python_RFB/DS_Python/Dataframes/creditcard.csv?token=AGDJQ63IAZCFP7GTSZTOMAK5QBSP6'\n", + "df_CC= pd.read_csv(url)\n", + "df_CC.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 3 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-CawPH2nb5cl" + }, + "source": [ + "## Exercício 4 - Diabetes\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lVjBS7QcZuT" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qP1vjDdylyHr" + }, + "source": [ + "## Exercício 5 - Crimes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fqLHDXbOl0Sf" + }, + "source": [ + "url= 'https://raw.githubusercontent.com/MathMachado/Python_RFB/DS_Python/Dataframes/Crime.txt?token=AGDJQ665WUIWIEKDPK6WO625P3QUQ'\n", + "df_Crime = pd.read_table(url, sep=',', na_values='?')\n", + "df_Crime.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fxhTXj6Ll7wB" + }, + "source": [ + "df_Crime.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3b-Yv2HUmoI" + }, + "source": [ + "## Exercício 6 - Titanic" + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB10_04__3DP_5_Feature_Selection_hs2.ipynb b/Notebooks/NB10_04__3DP_5_Feature_Selection_hs2.ipynb new file mode 100644 index 000000000..13566c5bb --- /dev/null +++ b/Notebooks/NB10_04__3DP_5_Feature_Selection_hs2.ipynb @@ -0,0 +1,6081 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + }, + "colab": { + "name": "NB10_04__3DP_5_Feature_Selection.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cka1jqOwy6KT" + }, + "source": [ + "

3DP_5 - FEATURE SELECTION

\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3aYp_plmy17y" + }, + "source": [ + "# **AGENDA**:\n", + "\n", + "> Consulte **Table of contents**.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rSFnHHQUKDX5" + }, + "source": [ + "# **Melhorias da sessão**\n", + "* Desenvolver t-SNE.\n", + "* https://towardsdatascience.com/feature-engineering-for-machine-learning-3a5e293a5114" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "arSNhd_2KHL6" + }, + "source": [ + "___\n", + "# **Referências**\n", + "* [Feature Selection in Python — Recursive Feature Elimination](https://towardsdatascience.com/feature-selection-in-python-recursive-feature-elimination-19f1c39b8d15)\n", + "* [Feature Selection with sklearn and Pandas](https://towardsdatascience.com/feature-selection-with-pandas-e3690ad8504b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ngLc7b9XiKxN" + }, + "source": [ + "___\n", + "# **3DP_FEATURE SELECTION**\n", + "## Introdução à Feature Selection\n", + "> Nosso objetivo com Feature Engineering será:\n", + "* Deletar colunas irrelevantes;\n", + "* Deletar colunas com baixa correlação com a variável-target;\n", + "* Deletar colunas com baixa variância;\n", + "* Deletar colunas com muitos NaN's.\n", + "\n", + "* Sugestões:\n", + " * Normalize colunas numéricas;\n", + " * Aplique LabelEncoding (colunas numéricas) ou One Hot Encoding (colunas categóricas).\n", + "\n", + "![FeatureSelection](https://github.com/MathMachado/Materials/blob/master/FeatureSelection.png?raw=true)\n", + "\n", + "[Fonte](https://medium.com/@sundarstyles89/weight-of-evidence-and-information-value-using-python-6f05072e83eb)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9JCQatsiKxR" + }, + "source": [ + "from sklearn import feature_selection\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9U6Az5qpiKxU" + }, + "source": [ + "___\n", + "# **VarianceThreshold**\n", + "* Drop variáveis/features cuja variância seja inferior a um determinado threshold;\n", + "* Este é um método não-supervisionado, isto é, a variável rotulada (variável-resposta ou variável target) não entra e ação;\n", + "* **Intuição**: \n", + " * Features/variáveis com baixa variância contem baixa informação;\n", + "* **Como funciona**:\n", + " * Calcula a variância para cada feature/variável e então deleta a coluna/variável com baixa variância\n", + "* **Cuidados**:\n", + " * Assegure-se que as features/variáveis tenham a mesma escala. Ou seja, use StandardScaler() ou MinMaxScaler() para colocar as variáveis na mesma escala." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "euWJlVAViKxV", + "outputId": "0a16d5aa-7e5b-4db1-b5cc-e1a13f730cff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + } + }, + "source": [ + "df = pd.DataFrame(\n", + " {'sexo': ['m', 'm', 'f', 'm', 'm', 'm', 'm', 'm'], \n", + " 'b': [1, 2, 3, 1, 2, 1, 1, 1], \n", + " 'c': [1, 2, 3, 1, 2, 1, 1, 1]})\n", + "\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sexobc
0m11
1m22
2f33
3m11
4m22
5m11
6m11
7m11
\n", + "
" + ], + "text/plain": [ + " sexo b c\n", + "0 m 1 1\n", + "1 m 2 2\n", + "2 f 3 3\n", + "3 m 1 1\n", + "4 m 2 2\n", + "5 m 1 1\n", + "6 m 1 1\n", + "7 m 1 1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 212 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1rvj2MZ6Jtgq" + }, + "source": [ + "A seguir, usamos [LabelEncoder](sklearn.preprocessing.LabelEncoder) para a coluna 'sexo':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I6L5L_wtTSUe" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "le = LabelEncoder()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS2v_GnbiKxi", + "outputId": "5d026279-9b0f-4e3d-c9ac-3a9bff1be40e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + } + }, + "source": [ + "# Aplica o LabelEncoder à coluna 'sexo':\n", + "df['sexo'] = le.fit_transform(df['sexo'])\n", + "df" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sexobc
0111
1122
2033
3111
4122
5111
6111
7111
\n", + "
" + ], + "text/plain": [ + " sexo b c\n", + "0 1 1 1\n", + "1 1 2 2\n", + "2 0 3 3\n", + "3 1 1 1\n", + "4 1 2 2\n", + "5 1 1 1\n", + "6 1 1 1\n", + "7 1 1 1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 214 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1w-_VsJuWVHN", + "outputId": "3ad5cb6b-408e-4fd1-ba2e-2a98d7f55dda", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Calculando as variâncias de cada Feature/variável:\n", + "l_variaveis= ['sexo', 'b', 'c']\n", + "print(f'Variância das variáveis do dataframe df:')\n", + "for s_Var in l_variaveis:\n", + " print(f'{s_Var}: {round(df[s_Var].var(),2)}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Variância das variáveis do dataframe df:\n", + "sexo: 0.12\n", + "b: 0.57\n", + "c: 0.57\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3IITDmqUiKxo", + "outputId": "16e79dc1-1519-4750-f397-327b5455781d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Selecionar atributos cuja variância seja maior que 0.20:\n", + "vt = feature_selection.VarianceThreshold(threshold= .20)\n", + "vt.fit_transform(df)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1, 1],\n", + " [2, 2],\n", + " [3, 3],\n", + " [1, 1],\n", + " [2, 2],\n", + " [1, 1],\n", + " [1, 1],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 216 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tAOL215MiKxu", + "outputId": "cf1d0ae2-8fd9-4971-b5a3-8b246bb39ed0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Variância calculada pela VarianceThreshold()\n", + "vt.variances_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.109375, 0.5 , 0.5 ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 217 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yntaZtd98boc" + }, + "source": [ + "### O que aconteceu aqui? Qual a conclusão?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FXyfpmWtiKyB" + }, + "source": [ + "___\n", + "# **ANOVA (Analysis Of Variance) com f_classif**\n", + "* Aplica-se aos casos em que as colunas a serem testadas sejam numéricas por natureza e a variável-target seja discreta por natureza;\n", + "* ANOVA é um teste que visa medir diferença entre grupos/experimentos. Aqui, **o propósito da ANOVA é testar se as colunas numéricas testadas são diferentes**. Obviamente que ao identificarmos colunas semelhantes, então podemos reduzir o número de colunas para evitarmos multicolinearidade, overfitting." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yB7TC9VKiKyC" + }, + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "df_cancer = load_breast_cancer()\n", + "X_cancer = df_cancer.data\n", + "y_cancer = df_cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "N2_mE0Z5xxvL", + "outputId": "5b255dcb-ec6e-4ee4-e0f8-d0d89a14fc64", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_cancer" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1.799e+01, 1.038e+01, 1.228e+02, ..., 2.654e-01, 4.601e-01,\n", + " 1.189e-01],\n", + " [2.057e+01, 1.777e+01, 1.329e+02, ..., 1.860e-01, 2.750e-01,\n", + " 8.902e-02],\n", + " [1.969e+01, 2.125e+01, 1.300e+02, ..., 2.430e-01, 3.613e-01,\n", + " 8.758e-02],\n", + " ...,\n", + " [1.660e+01, 2.808e+01, 1.083e+02, ..., 1.418e-01, 2.218e-01,\n", + " 7.820e-02],\n", + " [2.060e+01, 2.933e+01, 1.401e+02, ..., 2.650e-01, 4.087e-01,\n", + " 1.240e-01],\n", + " [7.760e+00, 2.454e+01, 4.792e+01, ..., 0.000e+00, 2.871e-01,\n", + " 7.039e-02]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 219 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t0QYORbSiKyL" + }, + "source": [ + "chi2, p_value = feature_selection.f_classif(X_cancer, y_cancer)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7BC6y7etiKyP", + "outputId": "b6cf6b7d-77d9-49fa-96f1-10983adf21b8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(chi2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([647., 118., 697., 573., 84., 313., 534., 862., 70., 0., 269.,\n", + " 0., 254., 244., 3., 53., 39., 113., 0., 3., 861., 150.,\n", + " 898., 662., 122., 304., 437., 964., 119., 66.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 221 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYSOfeH4iKyW" + }, + "source": [ + "* **Comentário**: Acima, cada valor representa a importância de uma feature/coluna ==> **Quanto maior, melhor!**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k1fHrPM4upex", + "outputId": "690c1ed2-9c4f-4518-a356-6486b3ffcf63", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.76, 0. ,\n", + " 0.84, 0. , 0. , 0.11, 0. , 0. , 0. , 0.88, 0.06, 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 222 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JYciSVkMW8f" + }, + "source": [ + "* **Comentário**: Acima, os p_value's associados à cada valor de chi2 ==> **Quanto menor, melhor!**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1YVBLc7eu6_H" + }, + "source": [ + "## **Conclusão**: **Foco no p_value**. Se p_value < 0.05 ==> variável significativa/relevante para o modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r29_gmCgiKyY" + }, + "source": [ + "___\n", + "# **Univariate Regression Test using f_regression**\n", + "* Modelo Linear para testar o efeito individual de cada uma das variáveis regressoras;\n", + "* **Como funciona**:\n", + " * Usa a correlação entre cada variável e variável-target;\n", + " * F-test calcula a dependência linear;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IDzu3kCiKyZ", + "outputId": "b4941bbd-ebe8-4718-81b0-48666ada1d44", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.datasets import california_housing\n", + "house_data = california_housing.fetch_california_housing()\n", + "X_house, y_house = house_data.data, house_data.target\n", + "\n", + "X_house" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 8.3252 , 41. , 6.98412698, ..., 2.55555556,\n", + " 37.88 , -122.23 ],\n", + " [ 8.3014 , 21. , 6.23813708, ..., 2.10984183,\n", + " 37.86 , -122.22 ],\n", + " [ 7.2574 , 52. , 8.28813559, ..., 2.80225989,\n", + " 37.85 , -122.24 ],\n", + " ...,\n", + " [ 1.7 , 17. , 5.20554273, ..., 2.3256351 ,\n", + " 39.43 , -121.22 ],\n", + " [ 1.8672 , 18. , 5.32951289, ..., 2.12320917,\n", + " 39.43 , -121.32 ],\n", + " [ 2.3886 , 16. , 5.25471698, ..., 2.61698113,\n", + " 39.37 , -121.24 ]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 223 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1DS9T6WXw8qN", + "outputId": "038178a6-3f44-49da-f49c-695e8ff999c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_house # Variável contínua" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4.526, 3.585, 3.521, ..., 0.923, 0.847, 0.894])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 224 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uKYhjpEViKyl" + }, + "source": [ + "F, p_value = feature_selection.f_regression(X_house, y_house)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEqZ3I4jiKyp", + "outputId": "44e87de3-1abc-4664-817b-93801dc8eb36", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(F, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1.855657e+04, 2.328400e+02, 4.877600e+02, 4.511000e+01,\n", + " 1.255000e+01, 1.164000e+01, 4.380100e+02, 4.370000e+01])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 226 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rsaf7y8MiKyt" + }, + "source": [ + "### **Comentários**: Colunas com alto F-values tem maior poder preditivo. Portanto, **quanto maior, melhor**." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Fh80Xf8KG-Vj", + "outputId": "5e7aaa4e-563d-4643-b5f7-a7c6a16e5c21", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 0., 0., 0.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 227 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LKutBVPIxTP2", + "outputId": "c1a988e0-a69b-4642-b258-720024c66068", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.round(p_value, 2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 0., 0., 0.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 228 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DD-JKUQ1xjR8" + }, + "source": [ + "### **Conclusão**: **Foco no p_value**. Se p_value < 0.05 ==> variável significativa/relevante para o modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xvIXLHK9iKz8" + }, + "source": [ + "___\n", + "# **SelectFromModel**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "p0mtUVnjiKz8" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "boston = load_boston()\n", + "X_boston, y_boston = boston.data, boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WY1c2U10iK0A" + }, + "source": [ + "from sklearn.linear_model import LinearRegression" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3SJDM-Bxc_UF", + "outputId": "0096e7b9-84c4-4bfd-f6ea-06edb31747bc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Observe abaixo que a variável-target é float. Portanto, é um problema de regressão\n", + "y_boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,\n", + " 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,\n", + " 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,\n", + " 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,\n", + " 21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,\n", + " 35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,\n", + " 19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,\n", + " 20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,\n", + " 23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,\n", + " 33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,\n", + " 21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,\n", + " 20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,\n", + " 23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,\n", + " 15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,\n", + " 17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,\n", + " 25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,\n", + " 23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,\n", + " 32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,\n", + " 34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,\n", + " 20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,\n", + " 26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,\n", + " 31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,\n", + " 22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,\n", + " 42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,\n", + " 36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,\n", + " 32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,\n", + " 20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,\n", + " 20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,\n", + " 22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,\n", + " 21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,\n", + " 19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,\n", + " 32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,\n", + " 18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,\n", + " 16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,\n", + " 13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3, 8.8,\n", + " 7.2, 10.5, 7.4, 10.2, 11.5, 15.1, 23.2, 9.7, 13.8, 12.7, 13.1,\n", + " 12.5, 8.5, 5. , 6.3, 5.6, 7.2, 12.1, 8.3, 8.5, 5. , 11.9,\n", + " 27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3, 7. , 7.2, 7.5, 10.4,\n", + " 8.8, 8.4, 16.7, 14.2, 20.8, 13.4, 11.7, 8.3, 10.2, 10.9, 11. ,\n", + " 9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4, 9.6, 8.7, 8.4, 12.8,\n", + " 10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,\n", + " 15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,\n", + " 19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,\n", + " 29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,\n", + " 20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,\n", + " 23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 231 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2zNpau9HiK0C" + }, + "source": [ + "ml = LinearRegression()\n", + "sfm = feature_selection.SelectFromModel(ml, threshold = 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "62vOFTVViK0D", + "outputId": "a4a64f62-a280-4d40-8188-82b49ceda42d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Dataframe com as colunas mais relevantes\n", + "sfm.fit_transform(X_boston, y_boston).shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(506, 7)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 233 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8_j7HRZiK0J", + "outputId": "9a732d60-aa2f-43d2-8c94-c5ff85b3a694", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Dados originais\n", + "X_boston.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(506, 13)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 234 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yX5oufYkcrH7" + }, + "source": [ + "### **Conclusão**: Houve uma redução de 13 para 7 colunas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FaGrKVl0Re2A" + }, + "source": [ + "Abaixo, o indicador das colunas que foram selecionadas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hYVIANETRE2p", + "outputId": "e31de91e-1f8e-4a20-c2f3-891a43632b44", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "l_variaveis_selecionadas = sfm.get_support()\n", + "l_variaveis_selecionadas" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([False, False, False, True, True, True, False, True, True,\n", + " False, True, False, True])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 235 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ol88OWzaVpJi" + }, + "source": [ + "___\n", + "# **Análise de Correlação**\n", + "* É sempre uma boa ideia eliminar colunas altamente correlacionadas do dataframe, pois colunas altamente correlacionadas fornecem a mesma informação.\n", + "\n", + "Fonte: [Better Heatmaps and Correlation Matrix Plots in Python](https://towardsdatascience.com/better-heatmaps-and-correlation-matrix-plots-in-python-41445d0f2bec)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KWBe1v_6V5HB" + }, + "source": [ + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "from sklearn.datasets import load_breast_cancer\n", + "df_cancer = load_breast_cancer()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vDz4Byzk8yA9" + }, + "source": [ + "X_cancer = pd.DataFrame(df_cancer.data)\n", + "y_cancer = df_cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XIPITCn4cgjs" + }, + "source": [ + "Usando a correlação de Pearson:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0vHleiMlxuCG", + "outputId": "ee6e2dd6-a45f-4527-a548-52b3c708bc64", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 955 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao = X_cancer.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k = 1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01234567891011121314151617181920212223242526272829
0NaN0.3237820.9978550.9873570.1705810.5061240.6767640.8225290.1477410.3116310.6790900.0973170.6741720.7358640.2226000.2060000.1942040.3761690.1043210.0426410.9695390.2970080.9651370.9410820.1196160.4134630.5269110.7442140.1639530.007066
1NaNNaN0.3295330.3210860.0233890.2367020.3024180.2934640.0714010.0764370.2758690.3863580.2816730.2598450.0066140.1919750.1432930.1638510.0091270.0544580.3525730.9120450.3580400.3435460.0775030.2778300.3010250.2953160.1050080.119205
2NaNNaNNaN0.9865070.2072780.5569360.7161360.8509770.1830270.2614770.6917650.0867610.6931350.7449830.2026940.2507440.2280820.4072170.0816290.0055230.9694760.3030380.9703870.9415500.1505490.4557740.5638790.7712410.1891150.051019
3NaNNaNNaNNaN0.1770280.4985020.6859830.8232690.1512930.2831100.7325620.0662800.7266280.8000860.1667770.2125830.2076600.3723200.0724970.0198870.9627460.2874890.9591200.9592130.1235230.3904100.5126060.7220170.1435700.003738
4NaNNaNNaNNaNNaN0.6591230.5219840.5536950.5577750.5847920.3014670.0684060.2960920.2465520.3323750.3189430.2483960.3806760.2007740.2836070.2131200.0360720.2388530.2067180.8053240.4724680.4349260.5030530.3943090.499316
5NaNNaNNaNNaNNaNNaN0.8831210.8311350.6026410.5653690.4974730.0462050.5489050.4556530.1352990.7387220.5705170.6422620.2299770.5073180.5353150.2481330.5902100.5096040.5655410.8658090.8162750.8155730.5102230.687382
6NaNNaNNaNNaNNaNNaNNaN0.9213910.5006670.3367830.6319250.0762180.6603910.6174270.0985640.6702790.6912700.6832600.1780090.4493010.6882360.2998790.7295650.6759870.4488220.7549680.8841030.8613230.4094640.514930
7NaNNaNNaNNaNNaNNaNNaNNaN0.4624970.1669170.6980500.0214800.7106500.6902990.0276530.4904240.4391670.6156340.0953510.2575840.8303180.2927520.8559230.8096300.4527530.6674540.7523990.9101550.3757440.368661
8NaNNaNNaNNaNNaNNaNNaNNaNNaN0.4799210.3033790.1280530.3138930.2239700.1873210.4216590.3426270.3932980.4491370.3317860.1857280.0906510.2191690.1771930.4266750.4732000.4337210.4302970.6998260.438413
9NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0001110.1641740.0398300.0901700.4019640.5598370.4466300.3411980.3450070.6881320.2536910.0512690.2051510.2318540.5049420.4587980.3462340.1753250.3340190.767297
10NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2132470.9727940.9518300.1645140.3560650.3323580.5133460.2405670.2277540.7150650.1947990.7196840.7515480.1419190.2871030.3805850.5310620.0945430.049559
11NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2231710.1115670.3972430.2317000.1949980.2302830.4116210.2797230.1116900.4090030.1022420.0831950.0736580.0924390.0689560.1196380.1282150.045655
12NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.9376550.1510750.4163220.3624820.5562640.2664870.2441430.6972010.2003710.7210310.7307130.1300540.3419190.4188990.5548970.1099300.085433
13NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0751500.2848400.2708950.4157300.1341090.1270710.7573730.1964970.7612130.8114080.1253890.2832570.3851000.5381660.0741260.017539
14NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3366960.2686850.3284290.4135060.4273740.2306910.0747430.2173040.1821950.3144570.0555580.0582980.1020070.1073420.101480
15NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8012680.7440830.3947130.8032690.2046070.1430030.2605160.1993710.2273940.6787800.6391470.4832080.2778780.590973
16NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.7718040.3094290.7273720.1869040.1002410.2266800.1883530.1684810.4848580.6625640.4404720.1977880.439329
17NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3127800.6110440.3581270.0867410.3949990.3422710.2153510.4528880.5495920.6024500.1431160.310655
18NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3690780.1281210.0774730.1037530.1103430.0126620.0602550.0371190.0304130.3894020.078079
19NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.0374880.0031950.0010000.0227360.1705680.3901590.3799750.2152040.1110940.591328
20NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3599210.9937080.9840150.2165740.4758200.5739750.7874240.2435290.093492
21NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.3650980.3458420.2254290.3608320.3683660.3597550.2330270.219122
22NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.9775780.2367750.5294080.6183440.8163220.2694930.138957
23NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.2091450.4382960.5433310.7474190.2091460.079647
24NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.5681870.5185230.5476910.4938380.617624
25NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8922610.8010800.6144410.810455
26NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.8554340.5325200.686511
27NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.5025280.511114
28NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN0.537848
29NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 ... 26 27 28 29\n", + "0 NaN 0.323782 0.997855 0.987357 ... 0.526911 0.744214 0.163953 0.007066\n", + "1 NaN NaN 0.329533 0.321086 ... 0.301025 0.295316 0.105008 0.119205\n", + "2 NaN NaN NaN 0.986507 ... 0.563879 0.771241 0.189115 0.051019\n", + "3 NaN NaN NaN NaN ... 0.512606 0.722017 0.143570 0.003738\n", + "4 NaN NaN NaN NaN ... 0.434926 0.503053 0.394309 0.499316\n", + "5 NaN NaN NaN NaN ... 0.816275 0.815573 0.510223 0.687382\n", + "6 NaN NaN NaN NaN ... 0.884103 0.861323 0.409464 0.514930\n", + "7 NaN NaN NaN NaN ... 0.752399 0.910155 0.375744 0.368661\n", + "8 NaN NaN NaN NaN ... 0.433721 0.430297 0.699826 0.438413\n", + "9 NaN NaN NaN NaN ... 0.346234 0.175325 0.334019 0.767297\n", + "10 NaN NaN NaN NaN ... 0.380585 0.531062 0.094543 0.049559\n", + "11 NaN NaN NaN NaN ... 0.068956 0.119638 0.128215 0.045655\n", + "12 NaN NaN NaN NaN ... 0.418899 0.554897 0.109930 0.085433\n", + "13 NaN NaN NaN NaN ... 0.385100 0.538166 0.074126 0.017539\n", + "14 NaN NaN NaN NaN ... 0.058298 0.102007 0.107342 0.101480\n", + "15 NaN NaN NaN NaN ... 0.639147 0.483208 0.277878 0.590973\n", + "16 NaN NaN NaN NaN ... 0.662564 0.440472 0.197788 0.439329\n", + "17 NaN NaN NaN NaN ... 0.549592 0.602450 0.143116 0.310655\n", + "18 NaN NaN NaN NaN ... 0.037119 0.030413 0.389402 0.078079\n", + "19 NaN NaN NaN NaN ... 0.379975 0.215204 0.111094 0.591328\n", + "20 NaN NaN NaN NaN ... 0.573975 0.787424 0.243529 0.093492\n", + "21 NaN NaN NaN NaN ... 0.368366 0.359755 0.233027 0.219122\n", + "22 NaN NaN NaN NaN ... 0.618344 0.816322 0.269493 0.138957\n", + "23 NaN NaN NaN NaN ... 0.543331 0.747419 0.209146 0.079647\n", + "24 NaN NaN NaN NaN ... 0.518523 0.547691 0.493838 0.617624\n", + "25 NaN NaN NaN NaN ... 0.892261 0.801080 0.614441 0.810455\n", + "26 NaN NaN NaN NaN ... NaN 0.855434 0.532520 0.686511\n", + "27 NaN NaN NaN NaN ... NaN NaN 0.502528 0.511114\n", + "28 NaN NaN NaN NaN ... NaN NaN NaN 0.537848\n", + "29 NaN NaN NaN NaN ... NaN NaN NaN NaN\n", + "\n", + "[30 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 238 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gDxrqpPXxuCM", + "outputId": "ebd4ba38-df7c-4775-c12d-b20102a2e73c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 989 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize = (20, 17)) \n", + "mask = np.zeros_like(X_cancer.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(X_cancer.corr().abs(), mask = mask, ax = ax, cmap ='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 239 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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afqH2kFERERERP77GNaJtp+vA+8u4tQG/IbPPq6bdfwna8BQ7+721zVfn/p5pMroyD+2hOX3cvl4t1SlLn1fVnMH+lRavLKsXnInnpNfe6FTpGWzxHrLFhEREZHf5S/9jMcjc6ae9j5tXWhw7g318rnU30INEREREREREflL0SCDiIiIiIiIiNQJDTKIiIiIiIiISJ3w/nl9IiIiIiIiIv9rDN2bPxlqLRERERERERGpExpkEBEREREREZE6oeUSIiIiIiIiIjWx6d78yVBriYiIiIiIiEid0CCDiIiIiIiIiNQJDTKIiIiIiIiISJ045XsyjCyacqojqik5Z+JpzwS45shL9ZJr5hTUS+4s30n1ktsnafdpzzwn/+PTngkwPP5AveR+sO/2esl9c/JC4PR/vou/7HfaM0VERETkT8Iw6vsK/lQ0k0FERERERERE6oQGGURERERERESkTmiQQURERERERETqxCnfk0FERERERETkT8vQvfmTodYSERERERERkTqhQQYRERERERERqRNaLiEiIiIiIiJSEz3C8qRoJoOIiIiIiIiI1AkNMoiIiIiIiIhIndAgg4iIiIhEVgzAAAAgAElEQVSIiIjUCe3JICIiIiIiIlITm+7Nn4x6G2RYsnUvT32+ENM0ubBHO64b1K1amW9/2s7U75YD0DI+iicvPxuA57/8kUVb9mBZFqktkrnngn4YXmzGsXfLIhZ++himadIudSTdzprgcXztD9PZtOwjbDY7DQPDOWvs4wSHJwDw4+yn2bN5IZZlktyyF/0uus+rTIAl29J46ovFmJbJhd3acN2ALtXrun4HU+etOlbXSJ4cM8Rd16+X8uPWNAAmDOrKsA4pXmUCLNl1kGfmrsa0LC7o0Jxre7b1OP7s3DWsSssE4IjTSV7pEX68cxQHC0u48+NFmBY4TZPRXVswsnMLr3N3bVrEvFnudu7YeyRnDjuunRe+z9oFMzFsNnz9/Dn78keIjG8OwNL/TGP9ko+x2Wycden9NG3bx6vM1atXM23qVEzTZOiwYYwaNcrj+Ny5c3nrzTeJjIwEYPh55zFs2DAA5s2dywcffADA6NGjGXzWWV7XdcmmHTzzwRxM0+KCPl249uy+1cp8t2ojU7/8AQNokRjLE+NHcTC3gDtfm4lpWjhdLkYPTGVk/+7e525P56mvlmCaFhd2a811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uqOYJStz+WruIf55R2s+mNadopIKHnzavQHnnvQyvl+czb9f64bLZfHc1J16soSIiIiIyClknGhXe8MwwoB7gfOBX57Llwl8ATxpWVatD5w/8tUU77fNryPTHRNPdyQA1xx5qV5yzcKCesmdlTypXnL7JO0+7Zlx++tuD46TYcuu2/1GvPVBxO31kvvm5IX1krv4y371kisiIiLyF1F/jzI4DQ7/8N5p79PWhYYDLquXz+WEMxmODSLcc+zHg2EY1wDTT9F1iYiIiIiIiMifzB95hOVDaJBBRERERERE/srqcX+DP6MTDjIYhrGhpkOAd1vDi4iIiIiIiMj/hNpmMsQAQ3E/svLXDGDpKbkiEREREREREflTqm2Q4Ssg0LKsn44/YBjGglNyRSIiIiIiIiL/JSzjL72vZZ2rbePH605wbGzdX46IiIiIiIiI/FlpBwsRERERERERqRMaZBARERERERGROvFHHmEpIiIiIiIi8temR1ieFLWWiIiIiIiIiNQJw7KsUxow5u70UxvwG8ZdEX26IwGYNiOjXnKPlh2tl1yjnnZZPVp25LRnNgz2P+2ZAPkZufWS27R903rJDQpteNozw8L8TnvmLx643KfeskVERETq0F/68Qtli2ad9j5tXfDvO6pePhfNZBARERERERGROqE9GURERERERERqUk8zuP+sNJNBREREREREROqEBhlEREREREREpE5ouYSIiIiIiIhITWy6N38y1FoiIiIiIiIiUic0yCAiIiIiIiIidUKDDCIiIiIiIiJSJ7Qng4iIiIiIiEgNLD3C8qRoJoOIiIiIiIiI1Il6m8nQoUUDrjw/DJsBP6ws5YsFRR7HWzXx48oRYSTF+vDSzBxWbjxceaxvlwAuGBQMwOfzi1i0ptSrzJ/XLeGj6U9hmSY9B13I0Auv8zi+6NtZLPr2Q2w2O34NGjL2+knEJTbDWVHBzNcfJn3XZgzDxshr7qZFu27e17VlQ665IBybDeavKGH294Uexx12uHlsFE0b+VJcavLCu9lk5zux22HCJRE0S/TDtGDG53ls3nXE69xObfwZPyoGmwFzlxTyyXd5nrkOg9uviqVZUgOKS1088+ZBsvKc9OsWxAVnhVeWa5zgxx1PpLFn/1Gvc8eNjHbnLi3k0+/yq+XedlUszRL9KC518exbh8jKc9K3WxAXDg6rLJec4MedT6Z7ldulfSA3jE3AZoNvFuXx0Zxsj+M+DoM7xyeS0rghRSUunpiSRlZOBdGRPrz+eEv2Z7gztu4q45W3D3hVT4BOrf259qJIbDaYt6yIz+YVHFdXuPXyGJom+lFcajJ5RgbZeU7sNrhxTDRNE/2w2wwWrCrm07n5NaRU161DCDdfk4zdZjBnfhbvzz5Urb7/uLkZLZoGUFTs5KEXdpCZXU6X9sFMuCwJh8PA6bSY+m46634uqiGlunbNfBgzNBDDMPhx3WH+s/Swx/EWST6MHhJAoxgH0z4tYs2WcgAiQmzcNDIYwzCw22H+ysMsXOvdd7lVkp2L+vphGLB8cwXz11R4HG8ab+PCPn7ER9p455sjrN/lqjwWGmgwepAfYYE2LOD1Lw6TV2x5ldsszmBYNzs2A9buNFnys+lxPLW1jc7NbJgWlB6x+GK5i8Jj/xVdNtBOo0iD9CyL9xe4fuOvi4iIiIj8NdXLIINhwDUXhvH4G1nkFrp47G+xrNlcxoEsZ2WZnAInUz/M5dx+wR7nBjS0cdHgEO57KQOweOyWONZsLqP08Ik7DqbLxYdvPs4tk6YRGh7DU/eO5Yyu/YlLbFZZplufc+g7dBQAG1Yt4JO3n+Xm+6ewZN4nANz/3CcUF+byymM3cc+TM7F58SgTw4DrLgrn0WmZ5BY6eeK2eFb/XMaBzKqO0sAeQZSWmdzyxAF6dgzgsuFhvPBuNoNTgwC469mDBAfa+L9xMfzjxUNYXvSRbAZcPzqGB17aT25+Bc/em8zKDSXsyyivLHNWzxBKykxueGAPfboGcdWFUTzz1iEWripm4apiAJLjffnHDQleDzDYDLj+0mgeeOkAuQUVPHNPMis3lLLfIzeYkjIXEx/cS+8uQVx5YRTPvnWIRauKWfTr3Ovjvcq1GXDTFQn83zN7yMmr4MUHmrNiXRHpB6vOHdI3nJIyF9fds41+PUK4dmQcT05JB+BQVjk3T9rhVf2Ozx0/MoqHXj1AboGTp+9KZNWmUvZnVH22g1ODKSkzuemRdHp1DuTKERFMnpFJz06B+DgMbn9yH74+Bi/9XxI/rikmO895gsSq3Fuva8zfH91Kdm45U59oy9LVBaQdqOrwnzMwiuJSJ5ffsp4BPf+fvfsOj6LOHzj+ntlN75uySUghIaGFTugqCCoIFjgsiF2U01NP8ez+9NSzYDk9PcUudjxFRUQFVKQLhF4CBAik991Nb7szvz8WkywhyXIGcujn9Tw8z2a/35nPfGcmeZjPfIuJP18Zx+P/Okh5pZ0Hn9lPmbWR7rE+PPtQby67eZtb7VUUuHJSAP/82Ia1QuPhG0PYntFAQWnzQ3RZuYN3F1cycZSvy7a2So2n5tuwO8DLAx6/2cSOjAZsVdqxYVrFvGScF68tqsVWpXPX5T7szrRTZG3+JbBV6nzyYz3jh3i02v6qc71ZvrmBjBwHnh649bvza9zJww18+JOdihq46Xwj+3M1SlvkBwstOm9m2LE7IDVZ5ZzBBr5Y6zwX69M1PAwwNFk6iwkhhBBCnPYU+T/dieiSs5UU60lhqZ1iiwOHA37ZUUNqiutDSanVQXZhI/oxTwUDe3mz60At1bUa1bU6uw7UMrCXT4cxjxzcTXhkLGHmGIweHgwdM4kdaStd6vj4+jd9rq+vBZxjbwpyM+nVbzgAAUGh+PoGkH1oj3ttjfOisMxOscWOwwHrt1Uz7Ji2pvbzZeXmKgA27KymX7I3ADFmD3YfdL7trajSqK7TSIzxdCtucndvCksaKSptxO6ANZsrGT7Q36XOiIH+rNjgfGpat7WSAb19W+3nzGGBrN1c6VbMX+MWlDRSVOaMu3ZLBSMG+rnUGT7An583ON+er99WyYBex4mbGsCaLe7F7ZnoS35RA4UlDdgdOqs22hg52DU5NWpwID+udfYUWJNWzqC+/sfb1QlJiv+1rc4HzbVbqxje33W/w/r78/MmZzt+2V5F/57Otuo6eHmpqCp4eijYHTq1de0/cP+qd5I/+YV1FBTXY3forFhvYcywEJc6Y1JDWLayFIBVGywM6ec8HweP1FBmdSZBjuTU4uWp4mF0b4xZYrSRYquDUpuGQ4NNe+oY3Mv1fiwr18gtdrR6mHdoYD+aizAaFdwd1hZvVim1aZRV6Dg02JZhp3+ia27UUqlTUKa1imkOUVBVyMhxBm5ohMaOczgAdAtVsFTq2KpA02DPEY3eMa5/Lo8U6U1tyi3VCGxxGx8u1Kl3M5YQQgghhBC/J12SZAgJMlBW3vLtp52QQIN72wYasNiat7WUO9za1mYpJiQssnk/oRGUW4pa1Vv1/ac8cusUvvrwRS6bdR8AMd17sjNtFQ6HndKiXLIz92Ita73t8ZiCDJTZmp82ysrtmIJcj9cU2FxH06CmViPAT+VIfgOpKb6oKoSbjCTGeBEW7F7nk9BgI6XW5jfqZVY7ocdsawo2UmptjltdqxHg53psZwwNYPVm97vTt9znr3FNQR5t1nG210GAn+uteMbQANakuZdkCAvxoMTS3NZSayOhIa4xQ0M8KD1a59eYgf7OtkaGe/LKY8k8e38iKT1bJzzaEhpsoMzW4hzbWl/b0KDmOpoGNXXOa/vL9irq6zXeeSKBNx/rztcrbFTVuJdkCDN5UlzW3DOkpKyBMJNHm3U0DapqHAQGuF7/s0aYOJBZTaPdvdf7wYEqlorm3z1rhUZwgHu/twAhgSqPzg7huTtC+X59TYe9GACC/BSsVS16LVTpBPm7l6GICFGprde5frI3d8/w4aIxnm4nNwJ8oaKm+eeKGp2Adm6NwUkqB/Pd7CYhhBBCCCHE75isLnGMsefPYOz5M0hb8x3fL3yLa29/glHjp1KYe5hn7puJKSyKxF4DUdwYKvFb/bypipgID+beGU2J1c7+I3Vop/A5pmd3b+obdLLzGzqu3ImSf41bcPLjWm12rrlrL5XVDpLifXjkr/Hc/FAGNW72KvhvJcd7o+lw4/8dxt/XwBN3dGPn/hqKyk7N6+/uMT7MvjKWe5/cd0rigTMp8eibVoL9VW69LJAte+upqD55N7SqQGK0gec/rcFaqXPtJG+G9zGyMb1zz3H/BIVok8J7P8jcC0IIIYQQQvzXT8qKonzfTtlsRVE2K4qy+eCOT1qVW8sdhLZ44xsaZMRa4d5/0K0VDkzBzduaggxubRtsisBaWti8n7JigkzmNus7h1P8DIDBYOSS6+/hwec/4+b7X6KmuhJzVLxbx2spd7j0IAgNMmIpdz1eS0VzHVUFXx+VymoNTYP3F1u594V8nptfjJ+PSn6J66R3bSmz2Qlr8TY/NMTo0qMCwGKzExbSHNfPR6WyuvnYzkwNYM0J9GI4dp+/xrWUN7ZZx9leA5XVzQ/1Zw4NYM0JDNEotTYS3uJNfliIR9OQgF+VWRub3vb/GrOiykGjXW9q88GsWgpKGugW6eVW3DKbg9DgFuc4uPW1LStvrqOq4OvtvLZnpvqzbW8NDg3KqxzsO1xHjzhv99praSAitHmYQnioZ1MvjePVUVXw9zVQUem8/mEmTx6/O5m5rx4iv8i9uTYAbBUapha9hkICVWyVJ/5gbavSyC+xkxzXeg6FY5VX64S06LkQ7K9QXuVeYsJWpZNX6hxqoemwK9NOTLh7f/Iqa3AZ/hDoq1BZ07peQqTCmf0MLFjpwHFy81JCCCGEEKKL6Ip6Wv7rKu1GVhRlSBv/hgKD2tpO1/U3dV1P1XU9NWngzFblh3IbiAzzIDzEgMEAowb6siW99jh7am3H/joG9PTBz0fBz0dhQE8fduzveJb6+KQUiguyKS3Kxd7YyJZ1SxkwbKxLneKCrKbPu7euJiIyDoCG+lrq65xPGHt3/ILBYHCZMLI9h3LqiQozEm4yYjDA6MF+bN7j+rSyZU8N41KdY/lHDvBjzwFnezw9FLw8nQ9Y/Xt643DgMmFkew5k1REV4UFEqAdGgzNhsGlnlUudTTurGD8yCIAxQwLYub/5uBQFxpzgw75rXCNGA5wxNJBNO11X/9i0s4qzRzrnCBg9OIBdvzFuxuEaos2emMM8MBoUxo4IZsM21+TIhu0VnHOGc96CM4cFsWOv81wEBThXDwDnsIlosxcFJe71oDiYXUdUuAcRpqNtHeJP2i7Xtqbtrubs4c4JPEcN8mfXAWdbS612+ic75xLx8lTo2d2bvCL34u47VEW3KG8iw70wGhTGjzaxfrPryhTrt9iYOC4MgLEjTU0rSPj5Gph7f0/e+iSH3furWu27PYfz7ZhNBsKCVQwqDE/xZnuGe8ccEqDicTT35OutkBTrQWFZxwmK7CKNsGAVU6CCQYOO6lwAACAASURBVIXBPY3sPuxeYiO7WMPHC/yO5m6SYwwUWdxLUOSV6YQGKAT7OZM0Kd1V9ue6ZhEiQ+CCEQY+XWmnxv1cjRBCCCGEEL9ryrETK7oUKooDWMWvMyC6GqnreoczLl5xb/ZxAwzq7c01F4agqrAyrZpFKyq45LwgDuc2sCW9lsQYT+66Jgw/X5XGRp3ySgf3vODsiTAu1Y+Lxx9dwnJFBas2uz7Y3Xh1xHGPZffWNSyc/yyapjFq/FTOn34T33z6KvE9UhgwbByfvfsM+3duwGD0wMcvgMtvfIDo2CTKivP49xO3oCgqwaYIrvrLo4SGR7fa/xvvFR4nKgzu7cO1U01Hl+us4qufyrlsYjCHcuvZsqcWD6PCbTPDSOjmSVWNcwnLYoud8BAjD802o+k6lnIHr39WSqm19QNWfRtPOENT/Jh1aYRz6cz15Xy+1MLMC0I5mF3Hpp3VztUNrotyLq9Y41xKsqjUmcTol+zDNdPCuffZ7OPuG0BpY4D70BQ/brgkHMPRZR0XLrVwxQWhHMyqI22XM+6d10WSGONFZY3GP98poKisOe7VU8O477mcNuPW17ROKg0bEMDsmdEYVFi+xsqn3xRz9TQzGYdr2bi9Ag8PhXtmx9IjzofKagdzX8umsKSBMamBXD0tErtDR9fgo0WFbNzeOsHhE3j8AflD+v66hKXCTxsq+GK5lRmTTRzKriNtdw0eRoU7rjaTEOO8ti+8V0hRmR1vT4XbrjQTE+mBoiis2FDB1ytsrfZvLSw7btwRg4O49dp4VFXh+59L+PirfK6/rBv7D1WzfosNDw+FB2/rQXKCHxVVdv7xr4MUFNdz1Z+imTk1mrzC5nN4zxP7sFW49nJJ7J943Lj9kzyZcZ4fqqKwdkcd366t4eKxvhwpsLMjo4HuUUZuvSwQP2+VRrtOebXGI69b6ZvgwWXnNk+KuSKtltXbWl/HgODWf1L6xBuYdqYXqgob0xv5YXMj54/wJLvYwZ7DDmIjVGZN8cbHS8Fuh4oajWc+cSYte8YamHqGs0dHbonGf1bUt+pxEBJy/J4rSdEKk1INKApsP6SxZrfGuAEq+RadjFydqycYiAhWqDqaHy2v0fn06HKV151nICxQwdMItfWweIODQwWt/xT+/aqOe3MIIYQQQpwG3Jz56vRUtWHxaTn5lv/Ii7rkunSUZNgNTNN1vdX6foqi5Oi6HttRgLaSDCdTW0mGk62tJMPJ1laS4WRrK8lwsh0vyXCytZVkONnaSjKcbG0lGU624yUZTra2kgyngiQZhBBCCPE7IUmG/0FdlWToaOLHR2l7SMXtnXsoQgghhBBCCCHE/5guerl6umo3yaDr+sJ2ikM6+ViEEEIIIYQQQghxGvstU04+1mlHIYQQQgghhBBCiNNeuz0ZFEXZ2VYR0Pb6j0IIIYQQQgghxO9AVy4HeTrqaE4GMzARsB7zvQKsPylHJIQQQgghhBBCiNNSR0mGJYC/ruvbjy1QFGXlSTkiIYQQQgghhBBCnJY6mvhxVjtlMzv/cIQQQgghhBBCCHG6ksElQgghhBBCCCFEWxTl9PznVtOUSYqi7FcU5aCiKPe3UecyRVHSFUXZoyjKJx3ts6PhEkIIIYQQQgghhPidURTFALwKnAvkAmmKoizWdT29RZ1k4AFgjK7rVkVRIjrar/RkEEIIIYQQQggh/niGAwd1Xc/Udb0B+BS4+Jg6NwGv6rpuBdB1vbijnUpPBiGEEEIIIYQQoi2n6RKWiqLMBma3+OpNXdffbPFzNyCnxc+5wIhjdtPz6L7WAQbgUV3Xl7YX96QnGeaPazf+SfF+weyOK50EH5y5uEvi6pUVXRJ3Qbf/65K4F0RuPuUxA3O3nPKYAFhLuiTswujhXRL3w7d3nPKY96265pTHBPhl7jae/NTRJbEfmmHokrhCCCGEEOLUOZpQeLPDiu0zAsnAOCAGWK0oSn9d121tbXB6pmSEEEIIIYQQQgjxW+QBsS1+jjn6XUu5wGJd1xt1XT8MZOBMOrRJkgxCCCGEEEIIIcQfTxqQrChKgqIonsAM4Nju+Ytw9mJAUZQwnMMnMtvbqczJIIQQQgghhBBCtEF3cznI042u63ZFUW4DluGcb+FdXdf3KIryOLBZ1/XFR8vOUxQlHXAA9+i6XtbefiXJIIQQQgghhBBC/AHpuv4d8N0x3z3S4rMO3HX0n1tkuIQQQgghhBBCCCE6hSQZhBBCCCGEEEII0SlkuIQQQgghhBBCCNEWRd7Nnwg5W0IIIYQQQgghhOgUkmQQQgghhBBCCCFEp5DhEkIIIYQQQgghRBt0fp9LWJ4sXZZkWLf3MM989TOarjNtRD9mnTOiVZ1l2/bz+rL1gEKvbuHMvXoKmw5k8/yilU11DhdbeOaaKYzvn9xhzMPpq1n5xZNomkb/UZcy/LzZLuVbVsxn1y+fo6oGfPxNTLzyKQJN3QBYvehZDu9Zha5rxPUew9nTH0Jxc73UdfuzeGbxWjRdY9qwvsw6e2jrtu44wOs/pgHQKzqMuVecB8CL361nzb4sAGZPSGXSwI7b2RT3UB7PLtvsPMeDkrhhTD+X8ueWp5GWVQRAXaMdS3Uda++ZQb6tirsWrkLTdewOjSuG9ebSoT3djpu5ZzU/ffYkmq4xcMyljJzoep63rV7A1lWfoKoqHl6+TLryH4RFJQHwy9I32Ll+IaqiMuHy/yOx75luxdy4dQcvvfMhmqZxwTnjuGr6RS7l361Yxbz3FxBuCgHgT5PP48JzzwZg7PSrSIyLBcAcHsbcB//mdlvXpWfyzBc/omka00YNZNZ5o1rVWbZ1L69/vxbnfRzB3Oucx1ZgKefRBd9TZK1EUeCVmy+lW2iwe3EP5PLMdxuc99SQXsw6a6BL+XPfbyDtcAEAtY12rNV1rH3wagBu+WApu3JLGBRn5pWrznO7rQAHd69h2YIn0TWNwWdewpjJx/wOrfyUtJ8/RlUNeHr5MuWaxwmPTqKmysrC1+4g/8huBo6eyvlXPtJGhONL7R/AzVd2w6AqfL+qjM++LXYp9zAq3DM7juTuvlRU2XlqXhZFpQ1N5eEmD956ujcfLSpk4fclbsU0jR1D8iP3oRhUCv7zJVmvvetS7t0tit7PPo6nKYTG8nLS73yQ+sIigkcNI/nhe5rq+fZIYM/t91K6/Ge34iZGwnlDVBQFtmfq/LJXdykf3kthUKKCpkNNPSzZqFFRA+ZgmJSq4uUBmg7r9ujszdHbiCKEEEIIIcTJ0SVJBoem8dQXP/HGzZdgDg5g5osfM65fEj0iQ5vqZJVYeeenjbz/1ysI9PWmrLIGgOHJcXx2zzUAlFfXcsFT7zKqV/cOY2qagxWfP870W+cTEGzm4+cuoUf/8YQefbgFCI/pw5X3fIGHpw871nzC6kXPccEN/yI/cyv5mVu5+oHFAPznxZnkHtxEbHLrxMhx27poNW/ceBHmIH9mvvI54/om0MNsam5rqY13Vm7l/Vv+5GxrlbOtq/ceYV9eCZ/dcTkNDgc3vrGIM3rF4+/t6Vbcp7/fxOtXnoM50Jcr3/mesT1j6BHe/BB7z3nDmj4vSNvHvkKL8zwE+PDBdZPwNBqoaWhk+hvfMLZnDBEBvh3G1TQHP3z6OJf/dT4BIWben3sJSQPGNyURAPoOu5DBZ10BwIEdP7Fi4dNcdvs7lBYcZO/mb5n18LdUlRfxn5eu56bHlqGqhvbb6tB44c33ePHRBwgPNXHTvQ8zZvgQEmJjXOpNGDOSObOva7W9l6cn8198usO2tYqraTz1+XLeuHWG8z5+7j3G9U+mR1RYU52sYgvv/PAL78+5+uh9XN1U9n8fLuHGiaMZ1TuBmvoGt5NWDk3jqSXreePaSZgD/Zj5xmLG9Y6jR0RIU517zh/Z9PmTDXvYV1DW9PN1YwZQ22hn4eZ9J9ReTXOw9OPHufKudwkMMfP2E5fSc9B4wqObr22/ERcwdNwMAPZvX8EP/5nLzDlvY/TwYtzUOyjJO0BxXsYJxVUVuPWaGB549hCllkb+/WhPNmwrJzu/vqnOxLNMVFU7uP7evYwdEcysy6J4al5WU/mfZ3YjbWflCQRV6fX4g2y7ajb1hUWkLl5AyQ8rqTmY2VQl6cG/UfjlNxR+sZiQUcPpce9fSb/rIWy/pJE2+TIAjEGBjFr1LZbVv7gVVlGciYJPftaoqIUbzlU5kKdTWtFcp8iq8+5yHbsDhiQpTBik8NV6nUYHLN6gYa0Cf2+YNVEls1CnvtH9ZgshhBBCCPFbdcmcDLuzC4kNCyYmLBgPo4FJg3uxcvdBlzpf/rKTGWcMItDXG4DQ4zzg/rDjAGf07o6Pp0eHMQuzdhIcFk9wWCwGoye9h07h0K6fXOrE9RyJh6cPAFHdB1FlK3QWKAp2ewMOeyMOewOaoxHfgLBjQxy/rTnFxIYGERMa5GzrwGRWph92beumdGaM6t/cVn9nWzOLLQxJiMZoUPH19CA5MpR1+7NaxThu3PwyYk0BxIQE4GEwMDElnpUZOW3W/37PESaldAfAw2DA0+h8sG+wa+i6+29DC47sJDg8nuBw53nukzqFAztcz7OXj3/T58aGWjja/ejAjp/okzoFo4cnwWGxBIfHU3BkZ4cx9x44RLcoM9GREXh4GJlwxkjWbtri9jH/t3ZnFRAbFtJ8Hw/ty8pdB1zqfLl+BzPOHNriPvYD4FBBKXZNZ1TvBAB8vTzduo8BdueWEGsKJMYU6IzbP5GV+7LbrL90Vybn9+/R9POIHtH4ebkXq6X8wzsJiYgj5Oi1TRk+mf3b27m29TXOp2bA08uXuOShGD06TpAdq1eiL/lF9RSWNGB36KzcaGXUkCCXOqOGBPHDWmeSbE2ajUF9A1zKCksayMqrcztm4KB+1GRlU5eTh95op/ibpYSfd7ZLHd/kRKzrNwJg/WUTYeee3Wo/EZPPpWzlWrQ692JHm8BSCbZq0DRIz9bp2c01+ZRVDHaH83NeqU6Aj7PcUgnWKuf3VXVQXQe+Xm43WQghhBBCiE7RJT0Zim1VRAY3PwREBAWwK7vApU5WiRWAa19agEPXuWXiKMb0SXCps3TbPq4e13rowfFU2YoICIls+tk/2NzuA+yuXxbSve9ZAEQnDCY2eQRv/t8Z6LrOoLOuIjSyR5vbtlRcXkVkcPODV0SQP7uyi1zqZJXYALh23hc4NJ1bzh3GmF7x9IwK440f07jmrEHUNdpJy8wj0RyCO4ora4gM9Gv62Rzgx6780uPWzbdVkW+rYnj35vNTWF7N7f9ZQY6lkjvPGepWLwaASlsRgS3Oc0CImYLDrc/z1pUfk/bTfByORmbc+T7gvEbRCQNdtq20FbXa9lglFgsRYc29YMJDTezNONSq3soNaWxP30dsdCS333A15qPbNDQ0cuPd/4fBoHLlny7irBGpbrW12FZJZEiL+zg4gF1H8l3qZBU7H3yvfeFD5318/hmM6ZtIVrGFAB8v5rz1JXkWGyN7deeOi8ZhUDvO+xVX1hAZ1HxtIwJ92ZV7/CEA+bZK8qyVDE+McqtN7amwFhEY0ryfwJBI8jJ3tKqXtuJjNv7wHg57I1fd/d5vjhsa4kGJpfl1fKmlkd49XO/HsBZ1NA2qax0E+htoaNS5bEoEDzx7iEvOj3A7ppfZTH1+871XX1BE4KD+LnWq9mYQPukccud/TPjECRgD/DEGB2G3lTfVMV94Ptlvf+B23AAfqKxpTupV1EI3U9v1ByUqHCponQSMNoFBbU46CCGEEEKI/54uS1iekP/Zs2XXdLJKbbx922XMvXoKj322nIra5reBJeVVHCwoZXTv7p0eOz3ta4pydpM64UYArCVZWAoPcdM/VjH7idXkZGwg9+DmTotn1zRnW/88lbkzz+OxL1ZSUVvP6J5xnNE7nmvnfcH9nyxnYJwZw0m4wZelH+Gc3nEuD7iRQX58PvtCFt86lW92HqKsqrZTYw4ZdyV//sePjJt6N79891qn7vt4xqQO4fM3/sX7/5rLsIH9eeql15vKPn/zJd5+/gn+Puc2/v3Oh+QVdJzYcJdd08gqsfD2HTOZe+1FPLbgeypq6nBoGtsO5fK3aeP55O7ryC218fXGXZ0W91dLd2VyTkqCW8mLzjJs/JXc9vQPjL/kb6xdcvKvbXuunhbJV8tKqKvXOn3fB5/8J8EjhjLs2/8QPDKVuoIiZ4bjKM/wMPx6JWFZvb7TYwP0i1eIMils2OeaZPD3hotGqnyzqfPbLIQQQgghREfaffJQFCVQUZSnFUX5UFGUmceUzWtnu9mKomxWFGXzO9+vblUeEexPoa15fHRxeSXmIH+XOuYgf8al9MDDYCAmNIj4cBPZR9/4AyzfnsH4/kl4GNofr/8r/2AzldbCpp+rbEUEBJtb1cvat55Ny15n6uzXmrp2H9zxA1EJA/H08sPTy4/ufc+k4Mg2t+JGBPlTaGt+nVhcXoW5xVvoprb2SXC21RRIfFgQ2aXOtt40PpXP7pzBGzddjA7Eh7t2E28zboAvhRXN4/+LKquJCPA5bt2lLYZKHG8/SeHBbM0pPm75sQKCzVS0OM+V1iL8j3Oef9UndQoZO34EnNfo2G2Pd42OFW4yUVzaPOdASZmFsFDXHh9BgQF4ejiHCFxwztnsz2weshIe6nxVHB0ZwaB+fcg4fKTDmODsuVBobXEf2yoxt+ihA2AODmBc/2TntQ0LJj7CRHaJFXNwAL1iIogJC8ZoUDl7QE/25biX3IgI8KWwvPnaFlfUYA70O25d51CJRLf225HAEDMV1uYeRxXWQgJC2r4+/YZNaTWc4r9RZm0k3NQ8vCPM5EGp1XWigdIWdVQV/HwMVFQ56J3oy6zLonn/+b5MOy+cGReYueicjoc61RcV4RXd3DavKDP1Ra6/Aw3FJey++S7SplxO5nMvA2CvaL4fIi6YSMmyFeh2u9ttrayFAN/m4RGBPs7vjtXdDGP6Kny2RsPRIpfgaYTLz1JZuVMjv6z1dkIIIYQQQpxsHb3enI9zwPwXwAxFUb5QFOXXUb4j29pI1/U3dV1P1XU9ddb5Z7UqT4mNJLvERm5ZOY12B0u37Wdsiuvwg/H9k9h80DmHgLWqhqwSCzGhzQ/Y32/bx6Qhvd1oolNkXH9sJUcoL83BYW9g35ZvSew/3qVOcU46P/7nES6e/Rq+Ac3d7wNDosk9kIbmsONwNJJ7MA2T2b3hEikxEWSXlZNrqXC2dccBxvbp7trWlAQ2Z+Y521pdS1ZpOTGmIByahq3a2Xsjo6CUjIIyRiXHuRc3OpRsi7OrfKPDwbI9WYztGduq3uHScirqGhgYE970XVFFNXWNzgejitp6tuUU0z000K24UfH9sRYfwXb0PO/d/C1JA1zPs6X4SNPnQ7tXYoqIByBpwHj2bv4We2MDttIcrMVHiOo+oMOYvZMTyS0oJL+omMZGOz+t3cAZw1yH0ZRarE2f16VtIT4mGoDKqmoaGp0PrLaKSnbvy6B7bDe32poSF0V2iYXcUpvz2m5JZ2z/JJc64wf0ZPMB53wJ1qoasootxIQFkxIfRWVNHZajE5puysgiscXEp+3G7RZOtqWCXGulM+6uTMb2bn1fHC6xUVnXwMBY94cJtCe6e38sRVlYS3Jx2BvYs+k7eg50vbZlRUeaPh/Y2Xxtf4v9h2voZvbCHOaJ0aAwbkQIG7ZVuNTZsK2Cc89wJovOHBbMjr3Oh/2/PXWQa+9O59q70/lqeQmfLili8Y/HHzbUUuWOPfh2j8c7phuKh5GICydR+sNKlzoeIcFNc07E/+VGCj77yqXcfNH5FH3z/Qm1Nd8CpgAI8nMmS/rGKWTkufZUMAfD5GEqn63RqGme+xJVhUvOVNl5RGdf7gmFFUIIIYQQ7VHU0/NfF+loToYeuq5PP/p5kaIoDwErFEW5qL2NOgxqUHlg+nhueeMLNE1j6oh+JEWF8er360iJNTOuXxKje3dn/f4sps2dj6qqzLlwLMF+zjfxeZZyCm2VpPZo/dDcFtVg5OxLH+GLeTei6w76jZxOWFQy6759ici4fvToP4HVi56lsb6GJe/eAUBASBRT//w6yYMnkn1gAx88fSEoCt37nEmPYxIU7bb14jO55Z3FaJrO1GF9SIoM5dXlG0mJiWBc3wRG94xjfUYO0/75CaqqMGfyaIL9vKlvtHP9618C4OflyVMzzsFocO9mMaoq908azi0LfkLTdC4elERSeDDzVm6nb3Qo444mHH7txdByZYPM0nJe+HELCgo6OteM7EtyhHtzQagGI+fOeITP/n0juuag/+jphEcns+Yb53lOHjiBrSs/4si+XzAYjHj7BjL52mcACI9OpvfQ83nn8cmoqoFzZzzS4coSznNsYM5N1/G3x55B0zSmTBhLQlwMb3+ykN5JCZwxfCgLv13GurStGAwGAv39ePD2mwE4kpvH86+9g6Kq6JrGlX+6qNWqFG3HVXng0vO4Zd5/0HSdqSMHkBQVzqvfriYlLopx/ZMZ3SeB9fsOM+3Jt1AVlTlTz266j++aNp7ZryxA16FvrJnpowe5H3fKKG75YKnznhrSk6SIEF79aQsp3cIY19v5YL90VyYT+yW2WrXiureXcKS0nJqGRs59fgGPXnwmY5I7brNqMDJp5sN88q9Z6JrGwDHTieiWzMpFLxPVvR+9Bo1n84qPydzbfG0vumFu0/Yv3zee+tpqHI5G9m//iSvnvOOyMkVbNA1e/TCXp+5JRFUVlq+2kJVXxzXTIsk4UsOGbRUsXV3GvbPjmf9sHyqr7S4rS/w3dIeDjEeeYtAHr6EYDOR/tojqA4dImPMXKnelU/rjSoJHDqPHvX8FXce2aSv7H3myaXvvmGi8o8zYNpzYsCpdh2VbNK4Yq6KqsCPTubLEWf0UCiw6B/JhwiAVDyNMH+P8W1BeA5+v0egbqxAXDr6eCgMTnNf8m40aRbb2IgohhBBCCNG5lPZWDlAUZS+Qouu61uK764B7AH9d1zt8TVn33ZunfKH2942zT3VIAK6teblL4uqVFR1XOgkWdPu/Lol7QWTnzYfhrsDczp8vwS3W40/oeLItjL6nS+J++HbriSRPtvtWXXPKYwL8Mte9IVcnw0Mz3BtmJoQQQgjhJvfWYj9N2bavPOXPtJ0heNC4LrkuHb0W/wZweWWv6/p7wN+AhpN0TEIIIYQQQgghhDgNtTtcQtf1e9v4fqmiKE+dnEMSQgghhBBCCCH+N+jK77qjRqf7LbNBPNZpRyGEEEIIIYQQQojTXrs9GRRF2dlWEdDx2oJCCCGEEEIIIYT4w+hodQkzMBGwHvO9Aqw/KUckhBBCCCGEEEKI01JHSYYlOFeR2H5sgaIoK0/KEQkhhBBCCCGEEP8jdOW3zDLwx9PRxI+z2imb2fmHI4QQQgghhBBCiNOVpGSEEEIIIYQQQgjRKToaLiGEEEIIIYQQQvxxyRKWJ0R6MgghhBBCCCGEEKJTSJJBCCGEEEIIIYQQneKkD5fQigtOdohW6kL1Ux4TwFFS3CVx64tKuiSuNaBrznNhbNwpj+kXkHvKYwIYaiq7JG5WntYlcYPDQ055TK8Qj1MeE2D/nq75e3H7z9NIe6VLQjNs7YauCSyEEEIIIU4ZmZNBCCGEEEIIIYRogyxheWLkbAkhhBBCCCGEEKJTSJJBCCGEEEIIIYQQnUKGSwghhBBCCCGEEG3QkSUsT4T0ZBBCCCGEEEIIIUSnkCSDEEIIIYQQQgghOoUkGYQQQgghhBBCCNEpZE4GIYQQQgghhBCiDbKE5YmRsyWEEEIIIYQQQohOIUkGIYQQQgghhBBCdIouGy6x7lA+z/24BU3TmTqoBzeMSnEpf/7HLaRlFQFQ1+jAUlPHmrsubSqvqm9k+ltLODs5hvsnDnMrZva+Naz9+kk0TaPviEsYMn62S/n2VfPZu3EhisGAj5+J8Zc9SYCpGwCV1nx+/vz/qLIVoqAw5cY3CDTFuNfWw4U8v2IbDl1nWv9Erh/R27WtP29nc3axs612B5aaelbfPtWlrZfMX8a4pGjuP2eIWzEBPBJT8J14GSgq9dvXUrd+mUu5GhiC30XXo3j7gKJSu+IrGg/tBsB79CS8Bo0BXaNm2X9ozEx3O27O/jWsX/wkuq7Re9glDDrb9TzvXD2ffWkLUVUD3n4mxl76JAEhzvP81v19MUX2BMAvOIpJ173mVsxtWzYy/82X0DSNCeddwLRLrzpuvQ3rVvLPpx9m7otv0SPZeR2yDh/kjVeep7a2GkVRmfvim3h6erkVd93O/Tz/yWIcms60s4Zx/QVnt6qzfNMO3lj0IwrQMy6ap26+gv1Z+Tz1wVdU19ahqiqzLhzPxBED3YoJsG5/Fs8sXouma0wb1pdZZw9tVWfZjgO8/mMaAL2iw5h7xXkAvPjdetbsywJg9oRUJg1MdjtuYiScN0RFUWB7ps4ve3WX8uG9FAYlKmg61NTDko0aFTVgDoZJqSpeHqDpsG6Pzt4cvY0orgb28ua6i02oKqzYWMXXP1e4lBsNcOsVYSTGeFJZo/HShyWUWB0YDDD7klASYzzRdXjvawvph+rdbmvw6FEk3nM3qAaKFi0ib/57LuVeUZEk/f3veISEYK8oJ+Ohh2kodv4ej968ieqDBwFoKCxk7513uR23f5IXV00JRFVg1ZYalqypdinvFe/JlZMDiTUbmfe5jbQ9dU1ld18TQo8YTw5kN/DCR1a3YwIEjhhJ3B1zUFSVkiWLKfzoQ5dyT3MkCQ88hDE4BHtlBZmP/53GkpKmctXXl/4ffYp1zSqyX/znCcUWQgghhBC/H12SZHBoGnOXb+a1GeMxB/pw5XvLGJscQ4+woKY6d5/T/NC0YPN+9he5/od53uodDImNcDumpjlY/dXjXDj7XfyDzCx86VK69x2PKTKpqU54tz6k3LkQD08fdq9fwPpvn2fi1S8CL4dE5gAAIABJREFU8NOC+xh6zs3E9hxDY301uDkux6HpPPPjVuZdehbmAF+u+uhHxvaIJjEssLmtZw9q+vzp1gPsK7a57OO1dbsZEhPmdlsBUBR8z7+Cyo//hVZhJXDWAzRk7EQrLWiq4n3GFBrSN1O/dTVqWBQBM26j/JWHUMOi8ExJpfyNx1ADggi4cg7l8x4GveOHQk1zsHbR40y58V38gsx89cqlxPcdT4i5+TyHdevDn0YuxOjpQ/ovC9j43fOcc6XzPBs8vJl+56ITaqrD4eCd117g4SdexBQazgNzbiJ1xBhi4xJc6tXW1PDd4oUk9+rbYls7L//zH9x+18N0T0yisqIcg8G9XwuHpvHMh4uYd8+NmE1BXPXYK4wd3JfEbuamOtmFpcxfspL5D91CoJ8vlooqALy9PPjHTZcTFxlGibWCKx99mdH9ehLg5+NW3KcWreaNGy/CHOTPzFc+Z1zfBHqYTU11skptvLNyK+/f8icCfb0pq6oBYPXeI+zLK+GzOy6nweHgxjcWcUavePy9PTuMqyjORMEnP2tU1MIN56ocyNMpbfHMX2TVeXe5jt0BQ5IUJgxS+Gq9TqMDFm/QsFaBvzfMmqiSWahT39hxzBummXjyzWLKyu08fUcUm9NryStq3nD8CH+qazXumJvP6EG+zJwSwksflTJhhD8A9/yzgEB/lQdujODBlwrduY1BVUm8/3723PIXGoqKGPjxh1hWraI283BTle5z5lD87beUfLOEoGHDiL/9Ng48/AgAWn09O2bMdCNQ6/Zec2Egz75nwVLh4LGbw9i6r578EntTnbJyB299aeP8M/xabf/d2mo8PWoYP8z3xAKrKvF33U3GnL/SUFxM37fnY1u7hrojR5qqxN52O6VLv6ds6XcEDBlKzJ//wuEnHmsqj7npz1Tu2HbCbRZCCCGE+J+nKF19BKeVLhkusTu/jNgQf2JC/PEwGJjYJ56VGblt1l+ansWkvvFNP6cXWCirrmNUQpTbMYuzdxIUGkdQaCwGoydJgyZzeM9PLnW6JY3Ew9P5kGeOH0h1eSEAlsKDaJqD2J5jAPDw8muq12FbCy3EhPgTE+yPh0FlYu9YVh7Ka7ut+3KY1Duuua2FVsqq6xnZPdLttgIYoxPQLMVotlLQHDTs2Yxnz2PflOsoXs52qF4+aJXlAHj2HEjDns3gsKPZytAsxRijE3BHSY7zPAcePc89Bk7mSLrreY7uMRLj0fMXEdd8nv9bBzP2EhnVDXNkNB4eHow5awKbN6xtVe/Tj97m4ktm4uHR/EC9Y2sa8d170D3RmQQJCAzCYDC4FXd3Zg4x5lBiIkLxMBqZOGIgK7e59vj4ctUmLpswikA/50OfKdD54BsfGU5cpDNxFB4SSEigP9ZK1zfWbcbNKSY2NIiY0CA8jAYmDUxmZfphlzpfbkpnxqj+BPp6AxDq74yfWWxhSEI0RoOKr6cHyZGhrNuf5VbcaBNYKsFWDZoG6dk6Pbu5/sHNKga7w/k5r1QnwMdZbqkEqzO/QlUdVNeBrxudRZLiPCkqs1NsseNwwPrt1QxLcf3dS03xZdVm58437KyhX7KzzTFmT3YfcL7lr6jSqK7VSIzpOJkCENAvhbqcHOrz8tDtdkqWLcc0bpxLHd/EBMo3OXuKlKelYRo31q19t6dHjAfFZQ5KrA4cDtiwq5YhfVxPVKnNQU6RHV1rvX16ZgN19e71EGnJr09f6nNzqc/PR7fbsfz4AyFnnOVSx6d7ApVbNwNQuXULIWc2l/v26oUxxET5pk0nHFsIIYQQQvy+dEmSobiqFnNg81s4c4AvJZU1x62bX15Nvq2KYfHOt8OarvPCiq3cNd79YQMA1eVF+Ac3JyX8gyOpLi9qs/7ejQuJ6+38T7St9AhePgF8/97tfPbCNNZ/8yya5nArbkllLZEBzW8VI/x9Ka6sPW7d/PJq8surGRbn7KGh6TovrtzBnHED3IrVkhIQjKOiufeHVmlFDQh2qVO7+hs8+48g+K9z8Z9xGzXLPgVADQhGO2Zb5Zht21JdXoRfi/PsF9T+ed6XtpDYXs0PKw57PV++PJ1Fr1zOkT0/uhXTUlZCaHhzrxZTWDhlZaUudTIP7qestJihw0a7fF+QnwOKwhMP38W9d9zA1ws/dismQIm1nEhT83mJCAmi2FruUie7sISswlKuf2Ie1zz+Cut27m+1n92ZOTTa7cREmFqVHU9xeRWRwf7NcYP8KSp3TVBkldjIKrVx7bwvuOqVhU2JhJ5RYazPyKa2oRFrdS1pmXkUlle5FTfAByprmh9gK2qd37VlUKLCoYLWD7zRJjCozUmH9piCjJTZWrzFtzkICTIcU8dAmc35+6hpUFOrEeCrkpXfQGqKD6oK4SYjiTFehAa710vFMyKChqLm+7ahqAiv8HCXOtUZBwgdP955DOPPxujvjzHI2RtL9fRk4McfMuD991olJ9oTEmigrLz5b4ulXCMkwL2k12/hGR7eNNQDoKGkGI9j2ltz8AAhY8c5j/OscRj8/DAEBoKiEHvbHeS8+vJJP04hhBBCCPG/739+Cctl6VlM6B2HQXXmQz7bksEZPaIxB55gd+ATsH/LYkpy9zD1L84xybrDTsHhLVw65ysCgqNY/tEc9qV9Rd8Rl3Rq3OX7cpjQMwaD6nz7+9m2Q4xJjMQccHLa6pUynIYd66nb+CPGbon4X3w95W88flJiHc+BrYspzd3DhTc3j/2eef8K/ILMVJTlsOStazFF9iQwNK6dvXRM0zTef/sVbp3zYKsyh8PBvvRdzH3hTby8vHnsoTtJTOpF/0Gpvynmr+yaRk5RKW/e/2eKreXc+PTrfPaPOU3DIkpsFTz85qc8duNlqGrn5fzsmkZWqY23/zyVovJqbnj9KxbOmcHonnHsyS3m2nlfEOLnw8A4M4aTsCRPv3iFKJPChytcX7f7e8NFI1UWbzzOa/hO9nNaFd3MHjx9RxQlVjsZR+rRtBN/y9+WIy++SOJ99xFx0QVUbN1GfVERusOZINg8+QIaSkrw6taNfm++Ts3Bg9Tltt1b63SQ88q/ib/rbkLPn0LVju3OpISmETFtOuW/rHeZn0EIIYQQ4vdEl/USTki7SQZFUSKBvwMa8AhwOzAd2Avcoet6QRvbzQZmA/z72gu4YZzrA1uEvw9FFc1vXosqawhv40F62d4s7j+vefudeaVsyy3hs60HqG2w0+hw4OPpwR0t5jU4Hr8gM1W25sOtshXiF2RuVS8nYz1bfnqdqbd8iMHo7FrtFxxJWHRvgkJjAUjodw5FWTvajfer8AAfClv00iiuqiGijde/y/bncP+EwU0/7yooY1tuCZ9vP0Rto51Gh4avp5G/ntVxzwa90oYhMKTpZzUgBK3Sda4Hz0FjqFrgfPtoz8sEoweKrz9apQ31mG31Y7Zti1+QmeoW57m6/PjnOffAerateJ0Lb24+z79uDxAYGkt04nBK89I7TDKYQsMpK2l+C2spLSE0tHkOi9raGnKyD/PoA38FwGa18Mw/7ue+h+cSGhpO35SBBAY5eyQMSR1J5qEMt5IM4SFBFFqaz0uxtZyIkCCXOuaQIPr1iMXDaKBbuIk4cxjZRaWkJMZSVVvHHS/O59bpExmQFH/s7tsUEeRPoa25G0BxeRXmINfx+eYgf/rHmvEwGIgxBRIfFkR2qY1+sWZuGp/KTeOd7bt/wXLiw12PuS2VtRDgqwDOB/VAH+d3x+puhjF9nQkGR4tcgqcRLj9LZeVOjfwy99pqKbe79D4IDTZgLXccU8dBaLABS7kDVQVfH5XKGmfgDxY398h5/DYzBaV23NFQXIynufm+9TSbqT/mIbqhpJR9d98DgOrjQ+iE8Tiqqo6WOevW5+VRvnkLfr17uZVksFY4CG3RU8MUpGKtdK/X1G/RUFKCZ0RzbyDP8IhWSYPGslIOPnQ/4GxvyNizcVRV4d+vP/4DBxIxbTqqjw+qhwdabS25r8876ccthBBCCCH+93SUknkPSAdygJ+BWmAysAZ4va2NdF1/U9f1VF3XU49NMACkRIeSba0kz1ZFo8PBsr1ZjEvu1qre4bJyKuoaGNit+YHxqYvH8P2tU/nuLxczZ/xgLuiX0GGCASAitj/lpVlUlOXisDdwcPt3JKSMd6lTkpfOqi/+zuTr5+EbEOqybX1tJbVVFgDyDmwgxNyjw5gAKZEh5FiryLNV0+jQWLYvh7E9oo/T1goq6hoYEN0c98kpI/juzxfw7ewp3Dl2IFP6xruVYACw5x9BNUWgBoeCasAzJZXGDNfEiFZuwdjducKCGhqJYvRAr6mkMWMHnimpYDCiBoeimiKw5x8+XphWwmP6U16WRYXFeZ4P7fiO+D6u57k0L501X/6didfNw8e/ub31NeU47A0A1FVbKTyyzWXCyLYk9exNQX4uRYX5NDY2sm71T6SOOKOp3M/Pn3c/WcK8dz9n3rufk9yrL/c9PJceyb0ZOHQE2VmHqK+rw+Gwk757OzFx3d1qa0pCDDlFZeSVWGi021m2cQdjB/dxqTNuSApb9mUCYK2sJruolG4RJhrtdv728gdMGT2Ec4ad2HCYlJgIssvKybVU0Gh3sHTHAcb2cT3m8SkJbM50zv1hra4lq7ScGFMQDk3DVu2cpyCjoJSMgjJGJbvXUyTfAqYACPIDVYW+cQoZea49A8zBMHmYymdrNGpaLOSgqnDJmSo7j+jsO4EX+odyGogMMxJuMmIwwOhBfmze45rZ2LynhrGpzuEjIwf4suegs32eHgpens5eQf2TvdE0XCaMbE/lnnR84mLxio5GMRoJn3gelpWrXOoYg4ObJgGKueF6ir9eDIAhIADFw6OpTuCggdRkZroVNzOvEXOogbBgAwYDjOzvw7Z97q+I8d+q3rcXr9hYPKOiUIxGTOeci3XdGpc6xqCgpvZGXX0tJd9+4zzmx//OzulT2XnpNHJe/TelS7+TBIMQQgghxB9YR8MlzLqu/xtAUZS/6Lr+zNHv/60oyqz/Oqiqct+5qfzl05/RdJ2LByTSIzyYeat30jfKxLhk59KQy9KzmNgnHqUTZvNUDUbOnPYw37w16+jSitMxRSazaenLhMf2IyFlPL8seY7G+hqWfXgnAAHBUUy+4TVU1cDoC+/l6zeuA10nPCaFviMubT9gy7ZOGMytX6xG03Qu6p9Aj7AgXlu7m76RJsYmORMOy/blMLF3bKe0FXAuPbn0UwKuuANUlfrt63CUFuAz9kLs+Vk0HthJzY8L8ZtyFd4jJoAOVd+8B4CjtICG9C0E3fwoaA5qli5wa2UJcJ7nMRc/zPfvzELTNHodPc+bl79MWEw/uvcdz8bvnsPeUMOPHznP869LVVqLD7Hmq7+jKCq6rjFo3E1uJRkMBiOzbp7Dk4/8DU3TOPvcKcTGJ/DpR2/TI7k3w1okHI7l7x/ABVMv5/67bkJBYXDqyFbzNrTFaDBw31UXc+vz76BpGhedOYwe3SJ57cvl9E2IYezgvozu35MNezKY/uA/Magqd142mWB/P75dv5VtGYcpr6rhm7VbAHjsxsvoFd86AdU6rsoDF5/JLe8sdi4BO6wPSZGhvLp8IykxEYzrm8DonnGsz8hh2j8/QVUV5kweTbCfN/WNdq5//Uvneffy5KkZ52A0uNf9S9dh2RaNK8aqqCrsyHSuLHFWP4UCi86BfJgwSMXDCNPHOPdZXgOfr9HoG6sQFw6+ngoDE5z3+DcbNYo66CCjafDuVxYevCkCVYGVaVXkFjVy6cQgMnMa2JJey8+bqrjtijBeuj+aqhqNlz5yzscR5K/y4E1mdN3ZI+KVBaXtB2vJ4SDzmWdJmfcKqAaKv/6a2sxM4m65mar0dCyrVhOUOpT4228DXadi6zYOPT0XcE4I2eOhh0DXQFHJnf+ey6oUHbX3gyUV3HutCUWF1VtrySu286fx/hzOb2TbvnoSunlwxxUh+PkoDO7tzbTx/jz4b2fbHpoVSlS4AW9PlX/dHcE7i2zsOtjgVnuzX3ieXi+8BKpK6bdLqDt8mOhZN1Gzbx+2dWsIGDyEmD//BdCp3L6drBeec/98CiGEEEKIPwxFb+fhUVGUHbquDzz6+Qld1/+vRdkuXdf7dxSg5r3HOm8QtJveCn3kVIcE4MbCh7skbn1R14yFnt+vzc4sJ9W5Kae+vT1K15/ymACGouwuifvPulu7JO7Ozad+3oK//vSnUx4T4I0LlnRJ3Nt/ntYlcQGGrd3QZbGFEEIIcVL9rtd4LNq75ZQ/03YGc5+hXXJdOnqF+bWiKP4AxyQYkoDW0+QLIYQQQgghhBDiD6vd4RK6rh+3S4Cu6wcVRfn25BySEEIIIYQQQgghTke/ZS2OxzrtKIQQQgghhBBCCHHa62gJy51tFQGt1yUUQgghhBBCCCF+R3Tlt7yb/+PpcHUJYCJgPeZ7BeiamfCEEEIIIYQQQgjxP6mjJMMSwF/X9e3HFiiKsvKkHJEQQgghhBBCCCFOSx1N/DirnbKZnX84QgghhBBCCCHE/w79971CZ6eTwSVCCCGEEEIIIYToFJJkEEIIIYQQQgghRKeQJIMQQgghhBBCCCE6haLr+kkN8OSnjpMboA1LF5z6xS/GThtxymMCVFU2dEncMcN8uyTu8hXHLnZy8lVX1J7ymADFWYVdEjd1fL8uiTt5tOOUx/xyRZf8iWLq2YYuifv50vouiVuQXdolcb98OalL4gohhBB/ML/rSQvy9+/smv8w/kbRvQZ0yXX5XfZk6IoEgxBCCCGEEEII8Uf3u0wyCCGEEEIIIYQQ4tRrdwlLIYQQQgghhBDij0xXftejQTqd9GQQQgghhBBCCCFEp5AkgxBCCCGEEEIIITqFJBmEEEIIIYQQQgjRKWROBiGEEEIIIYQQog3673uFzk4nPRmEEEIIIYQQQgjRKSTJIIQQQgghhBBCiE4hSQYhhBBCCCGEEEJ0CpmTQQghhBBCCCGEaIOuyLv5E9FlSYbESDhviIqiwPZMnV/26i7lw3spDEpU0HSoqYclGzUqasAcDJNSVbw8QNNh3R6dvTl6G1FcDR8cwh03JaKqCkt+KOTjL3Jdyj2MCg/N6UWvHv5UVDby9+f2UVhcT2CAkX/c14feSQF8v6KIf7156ITamtxNYfJwI6oCWw44WL1Lcykf3VcltacBTdOproOv1tmxVTvLBvdQGTvQAMCqHQ62HdKO3X2bescZ+NNZXigKbEhv5KctjS7lidEq0870IjpM5YOldew45OD/2bvv8Ciq9YHj35ndDellN400SEhC710p0oRLUwQVKxbs3qvYUa+9oKKgoqIgVkAUBVFRpPcepJcQIA3Se8/uzO+PhYQlCdlcovl57/t5Hp4nu3Nm3z1TDnveOXMGIDrUwLj+LlXlAv1UvlxRxv4TNqfiHtu3keXzX0PTNLoPnMDA0Xc5LN+x5hu2r16AohpwaebO1be/SGBoNCkJ+1j6+fP2QrrO4KsfoF2PYU7FbB9lYuIwD1QFNu4t47etZQ7LY8KNXD/Mg7BAA58sLSLuSIXDclcXhZfu9mHPsUoW/l7sVEyATrHNuHWML6qisHZnMT+tL3RY3ibShVtG+xIRbOL9hTnsOFBatax/N3fGDfYCYMmaQjbGlTgdt2dnb+6/NQJVhV/XZvHNsjSH5SajwpP3RxIT6U5BkZVX3j1BelYFrVt5MGVyCwAUBb5cfJrNu/KcjhsbpjKmrxFFgZ1Hbazf63hMRAYrjO5rItissHBNJQdOVh+vI3oZaRNub6DX7LGy74Tzx/KBuM18M286mmaj/9Bx/OOa22stt3vrama/9TjPvPk1LaPbAbD8+3lsWr0UVTUw8c7H6dD1Mqdi/qfnD4Cvp8LEIc3w81TRgU+WlZJT6Fw7dWDPZr6d9yaaptFvyDhGXHNHreXitq7i4+mPMfWN+bSMbg/Arz98yubVS1FVlevveJL2TtYVoF1LIxMGu6EqsHl/BSt3lDssjw4zMH6QG6EBBj77uYQ9x6q3x/uP+HA6y74/cwo0Pl7q/DnUta07d1zjj6rCqq0FLFnleDwajfDQzUFEhTejsFjj7c/TyMyxYlDh/hsCiQpvhkFVWLezkB9W5jodVwghhBBC/DmaJMmgKPZEwYK1GgWlcMcwlfhUnayC6jLpuTrzftex2qBbtMKQLgpLtuhU2mDZNo3cIvB0hTuHq5xI0ymvrDsegKrCI/e0YsrzB8jMLmfO9C5s3pHDqeTqjt2oYcEUFlm54d5dDOkfwL2TInnhrSNUVGjMnZ9IVAt3IiM8GlzXMb2NfPZ7JQUlcO9oI4eTNDLzq8ucydH56KdKKm3Qq7XK8B4GFq234eYCg7oY+OinSnTg/jEmDidrlFXUGc4h7oQrmvHR0lLyinQeud6NAyespOdWd3TyCnUWrCpncDeTw7rHU2289Y29M+zeDJ651YMjSc4lGDTNxk9fvsztT3yKtzmI2S9cR9uugwgMja4q06nvaHoNngjA4bg1/LrwDSY9NofAsBjue+E7DAYjhXkZzHp2HK27DsJguPhhqihw43APZiwsILdA45nbfdgbX8mZrOrvnFOg8dlPRQzv41brZ1w10I1jyVan6nh+3Nuv8uP1TzPJzrfxyoOBxB0uJTWj+nOy8mzM/i6X0QM8Hdb1cFMYP8SbZ2alA/Dqg0HEHS6luLT+jqiqwD9vj+DJ146RmV3JB6+2ZcvuPJJSqxMr/xjkT2GxlUlTDnBFXz/uujGMV947wankUu5/5hCaBmZfEx9Pa8fWuDw0J/r7igJXXW7k0+WV5BfrPHi1C4cTNTLyzjumiuC79ZUM6OS4z1qHq4RaFN77oQKDAe4e7cLR5Ip6z1sAzWZjwZw3mPL8h/hZgnj1iZvp3HMgIeFRDuXKSotZ/csCImM6VL13OvkEOzet4MV3F5OXk8mMF+7jlVlLUA2Geuv6n54/ADcPc+X3XRUcS7bhYgLdufwCms3Gwjmv8/Bzs/GzBPH6kzfRqedAQsJb1VHXjufVNYFdm1bw/Mzvyc/JZMaL9/Dy+z/WW9dz9b1uqBvvf1dMXqHGEzd7sT+hkrTs6gMjp0Dnq19LGNrTtcb6lVZ4/cvCGu/XR1XgrmsDePGDVLLzrLz5WDg7DxSTklZ9YAzt401RicYDLydxeTdPbh1r4e3P07msqycmo8KUacm4mBTeezqCjbsLycxp2HkshBBCCCEaV5OM+wgxQ04h5BWDpsGhJJ3YUMfHgiRmgPVsHzE1S8fLzb48pxByi+zvF5VBcZm9I1yftjFepKaVcSa9DKtVZ/XGTPr1MjuU6d/bwm9r7J2+dZsz6d7JF4Cyco39hwuoqHD+yus5Yf4K2YU6uUVg02D/SY22EY6b/WSaPXkCkJyp4+1ur2tMqErCaY3SCiirgITTGrGhzu2yFkEqWXka2QU6Ng32HLPSMcqx45dTqHMmW7toB6hztJHDiVYqnfzdnnJiH5agCMyB4RiNLnTsPZLDcWscyri6VXe4K8pL4ewjYVyauVUlFCorK+w9HydEhhjJzLWRladh02DnoXK6xDh2/LLzNVIzbei1VDYi2IC3h8qhE070eM8THe5CeraVjBwbNhts3VtK93aOSYysXBvJaZVoF4TtFOvK/uNlFJfqFJfq7D9eRqfYmp232rSO9uB0WjlnMiqw2nTWbc3h8h6+DmUu6+7L7xuyAdiwPZeuHewjJsortKqEgoupYY/iCQ9QyC7QySm0H1N7E2y0a+F4POYW6aTl6DWOqSA/hZNpGppu75Cm5WjEhjt3LJ88foCA5mEEBIdhNJno2W84f+xYV6Pc0gUfMuLq2zC5VDcIf+xYR89+wzGZXAgICiWgeRgnjx+oN+alnD9BfgqqCseS7Sd1RSVOnz8njx8gMDi8qq49+g1n786adf1x4QeMGHcbJpfqEUd7d66jx9m6+geFEhgc7lRdAVoGG8jM1cjOt59Du49U0KmV4zmUU6BxOuvi7UVDRbdw5UxmJenZVqw22BRXRK+Ojgm5nh09WbvDnsDY+kcRHWPdAXviplkzFVW1H8tWm05pWcPbaCGEEEKI+ugof8t/TaXBSQZFUQIvNaiXGxSWVP9SLSi1v1eXLlEKCWdq/rINMYNBrU46XEyApRkZWdXDfzOzK/C3OGYn/M0uVWVsGhQXW/HxurTBHt7ukF98Xl2LqUoi1KZ7jEp8qv2HstcF6+YX63i5OxfXx0Mht+j8K8w6Pp4NP9C6xhiJO+b8lcGC3Ax8zMFVr73NQRTkptcot23VfN5+7EpWfDudUTc/XfV+csJe3ps6mlnPXMVVk56vdxQDgK+XSk5Bdecit1DD16v+q7dgT29cN8SDxaudv1XhHD9vA9n5542WyLdh9nYurvkS1vX3cyEju3o4S2Z2BRY/F4cyFrMLmWfLaBoUl9jwPnsst2nlwdy32jPnzfbMnJvo1CgGAG8Phfwix+PR28O5Y+pMtk5smAGTwZ4UjGqu4uvkunnZmZgt1ceUnyWQvJwMhzKJCYfJzU6nU4/+juvmZGD2Dzpv3SDysjPrjXkp50+gn0ppuc7tI115bKIbYy93cTZfRl5OBn7+59XVHERetmNdk04cJjcrnY7dBzium52Bn8N2Cqqxneri66WSW1h9IOQVafh6Of/fg9EIT9zsyWM3etIpuubIjrpYfA1k51Un97LzrJh9HM8Di091GU2DkjINLw+VrX8UUV6u8ekrkXzyYkt+XJNHUYkkGYQQQgghmtpFf0UqimK+4J8F2KEoip+iKOaLrHe3oii7FEXZtXP1nEv6gh1aKDQ3K2w74phk8HSFsX1Uftrx3/OjsnOUSqi/wsYD/z/q5O2uEOJvcPpWiYboM/QmHp3+O8Ove5R1y2ZXvR/eqjP/ev1n7n3hW9b/PIfKivKLfMqlu6K7K/sTKhw6WP/tjiQUM/nxgzzwzGFuuKo5pgbznO4SAAAgAElEQVSOaPhPxKdqHE22cd9VLtww2ERShl5jdMd/StM0vv38Ha697ZHG+cBLpCoQFWJg2aZy3llUisVbpVfbxrkzTdM0vvt8OhP+n9T1nH9/UsCbXxfx2S8lTBjkhr/Pnz9ILqaFK5oOk589yX0vJjJ2kC9BFpnLWAghhBCiqdX3iywLSLzgvVAgDtCBqBprALqufwJ8AvDqN7YaXYnCUvByV85+BHi72d+7UMsguLydwldr7EN4z3ExwvUDVNbt0zidXU8NzsrMLifQv3rkQoDFhaxsxw5sVk4Fgf7NyMyuwKCCh4eR/MJLu7+3oMR+VfQcbw8oKKnZu2rVXGFgJwOf/lZZVdfCEvtEeuf4eCicTHOuZ5ZfrON33pVXX0/Hq9DO6BJjZF+C1ekr3QDefoHk51RPQliQk463X1Cd5Tv2HsmyL16s8X5gSCtcXN3JSI0nNLJDLWtWyyvUMHtXd2r8vFTyCp1LjLQKNRIdbuSKbq40c1EwGqC8QueHdfWPbMgtsGE576qr2cdAToFzcXMKbLSLqj4ezT4GDp1wLqGSlVtBoKV65EKAxYXsXMeJOrJzKuzHeE4lqgoe7gYKLjiWk06XUVpuIzLcjWMn6q9vQbHj1XwfD4WCYuePqbV/2Fj7h337TBxkIivfuXV9LQHkZFcfU7nZGfiaqwdUlZUWczopgen/tk8wmp+XzazXH+bBqTPxNQeSk5V+3rrp+FoC6o15KedPXpFOapb9VguA/SestAhW2e7Eur7mQHKzzqtrTjq+luq6lpcWk5qUwDvPTbZ/z7xsPpz2MPc/NRNfSyC5Dtsp3WE7XfQ7F2r4nTdywddTJa8Bibdz2yY7XyM+2Up4kIGs/PrXz86zYfGtHvlg8TWSk+94DmXn28tk59lQVXB3VSks1ujfw5M9h0uwaZBfZOPIyTJaRbiSnu3E0DYhhBBCCPGnqe9y0+PAUWCsruuRuq5HAiln/641weCM0zlg9gIfD/uEjO0iFI6lOv6AD/KFkT1Vvt2oUXJe30tVYUJ/lX2ndI6k4LQj8YWENXeleWAzjEaFIf0D2LQjx6HMph3ZjBhs7xBfcXkAcfucn3W/LqlZOhZvBT9P+60dHSNVjlzwNIzmZoWr+hqZv7qS4vMeihCfqhEdouLqAq4uEB1SfStFfZLSNfx9VczeCgYVusYaOXCyYSMSusU27FYJgNDIjmSnJ5KTmYLVWsH+7ctp03WQQ5mstFNVfx/bux5LkP1pBzmZKdhs9ni5WalknTmBr39ovTFPnbYS6GfA30fFoELPds3YG+/c/ApzlxXx1Ad5TP0wj8WrS9i6v8KpBANAQkoFwRYjAX4GDAbo29mN3YdqyZbVYt+xMjrGuOLhpuDhptAxxpV9x8rqXxE4mlBMaLArwQEuGA0KV/Q1s2W347G6ZXceVw6wADCgtx9/HLTf0x4c4IJ69qwP9HchPMSVtEwnZhIFUjLPHste9mOqcysDh5KcOx4VpXrulGCzQrBZIT7FuXVbRrcn40wymempWCsr2blpBZ17Dqxa7u7hxYwv1jDt41+Y9vEvRMV25MGpM2kZ3Y7OPQeyc9MKKisryExPJeNMMpHRF09awaWdP0kZGm7NwOPsFBsxYQbSc5xLUNjrmkTW2bru2rSCzj2q6+rm4cU7n6/jtdm/8trsX4mK7cj9T82kZXR7OvcYyK6zdc1KTyXjTJJTdQVITLMR6KdiOXsOdW/jwv4E584ht2b25BzYJzSNCjVwJtu5bXU8qYzmASYCzUaMBujXzZOd+x2fTLHzQDGDetnnFOnbxZP98fbzMyvXSscY+312zVwUYlu6kpru3LEshBBCCNEQuqL+Lf81lYuOZNB1/W1FURYBMxRFSQae59zwg0ug67Bit8YNA+2Tdu09YX+yxIAOCmdydOJPw5AuKiYjjL/cvnHyS+C7jRrtwhUiAsDdRaFzpP1K40/bNdLryQfYNJjxSQJvv9ABVVX4ZXU6p5JLuPPGFhw5XsjmHTn8sjKNZ6e0ZuHsHhQUWnlh+pGq9b/9pCce7gaMRpX+vS08+sIBhydT1EXT4edtViYNM9kfYXncRkaezpAuBlKzNY4k64zoYcDFBBMH2XdHXhHMX2OltALW7rVx32j7lb61e22UOvkbWtPh+/Xl3DvWDVWF7YcqScvR+EdvF5IybBw8aSM8UOXOUa64NVNo39LIiN4abyywd5LNXgq+ngoJqQ1LTBgMRkbf8ixfvDXZ/gjLAdcQFBbDqh/eI7RlB9p2G8z2VQtIOLgF1WjCzd2b8Xe9DkDisd1s/HkOqtGEoiiMufU5PLz8nKrrgt+LeXiiN4oKm/eWczrLxtgBbiSesbI3vpKWzQ3cP94Ld1eVTtEuXNXfjefn5Nf72ReNq8Hny/J46g5/VFVh3a5iUjOsTBjmzYmUCuIOlxEVZmLKLRY83FS6tXFlwjBvnpiRTnGpzpI1Bbz8gD2ptWR1gVNPljgX9/3Pk5g2NRZVhd/WZZOYUsakCSEcO1nM1t35/Loui6fuj+SLGR0oLLLx6vv2x652aO3JxKuaY7Xq6LrOe/OSaoxwqDOuDsu2WLnjH/ZjeddRGxm5OsO6G0nJ1DicpBHmr3DLMBfcmkGbCJVh3XVmLLaPDLpnjH30RXkFLFpbczLMuhgMRm6c/CQzX3oAXdO4fMhYQiNa8ePCj2jRqh1deg2sc93QiFb0uHwYz/9rAqrBwI13PeXU0xYu5fzRdfhxUwUPjLN3gFMyNbYedK7DbjAYmTj5Kd59+T40TePywVcREhHNsoUf0iK6HZ17XlHnuiER0XS/bBgvPHQNBoOBG+6a6lRdz9X329WlPDDeA1WFrfsrOJOtMepyV5LSrOxPsBIRbODuqzxwd1Xo0MrIqMtceeXzQoItKjcMc0fX7cmk37eXOzyV4qJxNZi7OJPn7g9BVRVWbysgOa2CiSPNJCSVsfNACau3FvDQLUF88O8Iiko03vncPlrj1w35PHhTEDOnhqMoCmu2FZB4WpIMQgghhBBNTalttv1aCyrKWOBpoKWu68H1lT+nttsl/my/LdzyV4cEYOC43k0St6iwaX5YX97TyVkoG9nva3L/8pjFBc6NUGhsGYlp9Rf6E/QY7NwV8MY28rLGn/+jPj+s+cubKACuHuRcAqCxfffbnzvPSV3OJGU1Sdwf3ouuv5AQQgghLlXTPcrgL5B4/GjT/GC8RC2iWzfJfnF6lixd15cpirISaAWgKMrtuq5/9qd9MyGEEEIIIYQQook15eMg/44adKOGruuluq6fe/B6zdn6hBBCCCGEEEII8T/roiMZFEXZV9cioO5HBgghhBBCCCGEEOJ/Tn23SwQBw4ELb4JXgKaZ+EAIIYQQQgghhBD/L9WXZPgZ8NR1/Y8LFyiKsu5P+UZCCCGEEEIIIcT/E035OMi/o/oeYXnnRZbd2PhfRwghhBBCCCGEEH9XkpIRQgghhBBCCCFEo5AkgxBCCCGEEEIIIRpFfXMyCCGEEEIIIYQQ/7N0lKb+Cn8rMpJBCCGEEEIIIYQQjeJPH8lQXm77s0PU0H9sr788JoDZz9QkcU3GpsmsVVqbJu67we/95THVbuF/eUyA5JhhTRI3u7K8SeJGWw/95THzL+v5l8cE2Hqoac6fm0ZZmyTuwdTovzymn5fG4u3aXx4XYEJvyeELIYQQ4n+T3C4hhBBCCCGEEELUQVfkdomGkEstQgghhBBCCCGEaBSSZBBCCCGEEEIIIUSjkCSDEEIIIYQQQgghGoXMySCEEEIIIYQQQtRB12VOhoaQkQxCCCGEEEIIIYRoFJJkEEIIIYQQQgghRKOQ2yWEEEIIIYQQQog66HJtvkFkawkhhBBCCCGEEKJRSJJBCCGEEEIIIYQQjUKSDEIIIYQQQgghhGgUTTYnQ3SIwsheRhQF4uJtbDygOSy/rJ1KtxgDmqZTUg5LNlvJL7Yvu2WokbAAhaR0nflrrE7HjAlVGN3HiKoq7DxqY8M+m8PylsEKo3obCTYrLFpr5cCp6u80vKeBNuH2nMyaPTb2n3T8vheTdHQjW358FV3XaNNrAl0H3e2wfN+Gzzi8YzGqasDV08wV176Kl18oAJ882Q5zcCwAnr7NGXH7R07HbdVcYURPA6oCccc1Nh90/M592qp0a6Wi6VBcprNsm61qG9802ECYv0JShs7CdbZaPr1ux/dv5LeFr6LpGt36T6DfSMf67lr3DTvXzEdRDbg0c2fMpJcICIkm4eBmVn//NjZrJQajiWHXPkFk2z5Oxdx84gxvrY5D03Su7hzFHX3aOSyfvjqOnUkZAJRV2sgpKWPjw+OrlheVVzJ+7nIGxYbx1LDuTtd18+GTvPHDajRNZ1yfTtw5rHeNMiv2HGH2r1tAgdYhgUybNJod8UlMX7KmqszJ9BzemDSGwZ1inIq7e9dOPvn4IzRN48rhI7j2uom1f79NG3n9tZeZMXMWMbGxVFZW8sH77xIffwxFVbn7nvvo1Kmz0/XdF7eV+XPeRtM0Bg67itETJtVabueWNcx64ylemP45kTHtOPDHdr798oOqfTvxtn/SrlNPp2Ju27OPmfMWoGkaY4YM4JZrRjss/2XNRj786lv8zb4AjP/HUMYOHQhAWmY20z6aR0ZWDoqiMP2ZKTQPDHAq7pG9G/nxy2lomo3eg8YzeOxdDsu3rFrElpULUVUVl2buTJj8AsFh0QCcTjrK93NfpKy0CEVVeejlRZhcmjkVNyoYhnZRURX446TOtiO6w/KesQpdIhU0HUrK4ZedGgUl4O0O4y9XUQBVhd3HdfYk6LUHqcX+uC0smDsdTdMYMOxqRo2/rdZyu7as5oM3n+S56V8SGd2Og39s47svZ2G1VmI0mrjutoec3rcAJw9uYM3iV9E1jY6XX0vvKy9oL1Z/xr4t36GqBtw9zQy/+TV8LPb2cf2SNzlxYD26rtGizeUMvvYZFKX+R0wd27eRX75+DU3T6DFwAgPHOO7b7Wu+YfuqBSiqgWbN3Ln6jhcJDI2uWp6XdZp3p45h8LgH6D/yDqfrKoQQQoi/Jx15hGVDNEmSQVFgdB8jX/xeSUEJ3DPKyJFkjcz86jJncnQ+/rmSShv0bK1yZXcD322wd3Y3H7BhMkKPWEODYo69zMS83yooKIb7x5o4kqSRkVf9IzyvSOf7DVb6dXT83NbhKiEWlfeXVGIwwF0jTRxL0SivrD+uptnYvOQlRt01Dw+fIH54/1pathuMX1D1D1ZLSFuu+ddiTC5uHNy6kG2/TGfYzTMAMJhcmTBlqdP1PL++I3sZ+Gq1lYISuOsfRo6maGSdt43TcnQ+OWbFaoMeMSpDuxr4fpN9G285pGEyQPeYhg120TQby+e/xC2PzsPbL4g5L19L6y6DCQiprm/H3qPpcYW9U3z0jzWsWDSNm6fMxd3Tjxv++RFefkFkpBzj6xmTeeTtDfXGtGka01bu4qPrBxHk5cZNX6xkYHQorfx9qso8NqRb1d8Ldx/jaHquw2d8uHE/3cKd63yeH/e171by8f3XEeTrxY1vf8UVHVvRKti/qkxiRi6frtzOFw/fiLe7K9mF9ixOr5gIvn3iNgDyi0sZ/cpc+rZp6Vxcm42PPpzFK69Ow+Lvz5SH/0nvPn2JiGjhUK6kpIRlPy6hdes2Ve+t+O1XAD746BPy8nJ5/rlnmDFzFqpa/37WbDa+/PhNnnhxFmZLIC88NomuvfoTGhHlUK60pJjff/qGVrEdqt7z8vZlyjNv42cJICUxgbde+BfvfvaLE3XVeHvOV8x87nECLWYmP/ki/Xp2JTI81KHc4Mt68ehdt9RY/5X3P+HW8WPo1bkDJaVlqKpz/0Fomo0ln73K3VPn4GMJ4t1nr6ddt0FVSQSAbpeN4rKh1wNwcPcafvr6Te566hNsNisLP3iKG+5/nZAWbSguzMNgdK6pVRS4spvKN+s1CkrhtqEq8ad1sguqy6Tn6nyWoGO1QddWCoM6Kfy4TaeoDL5crWHTwGSEycNV4lPt79dbX5uNrz5+g8de/ACzJYiXHr+VLr0GEBp+wb4tLWblz98Qdd6+9fT25aFnZ+BnDiAl8Thvv/hPZsz71an6apqNVd++xLX//Awv3yC+fnMCrToOxr959XYODG/LLU9+j8nFjT82LGDD0rcYc+dMUk/EkXoijknPLANg4Ts3khy/g4jYmom+C2P+9OXL3P7Ep3ibg/jo+eto222QQxKhc9/R9B5sb6MOx61h+YI3uO3xOVXLly98g9hO/Z2qoxBCCCHE/5omuV0izF8hp0AntwhsGuw/qVWNEjjnZJpO5dkL6MmZOj4e1Z2DE2m6Ux18h5gBCtkFOrmF9pj7Tmi0jXCMmVcEabk6+gUX/wJ9FU6laWg6VFrtnfPYMOc2XUbyPrz9I/C2hGMwuhDdeSSnDq52KBMa3QeTixsAQRGdKc5Pa1jlahFqUcgp1MkrAk2Dg6c02lzwnU+l2zsqAClZGt7u1ctOpumUOz9IpErqiX2YAyPwC7DXt32vkRzZ41jfZm6eVX9XlJegnM0MNm/RDi+/IAACQmOorCjHWllRb8wDZ3II9/UizNcTk8HA8LYRrItPrbP8b4cSGdG2ukN+KC2H7OIy+kYGN6iuBxLPEB7gR5i/LyajgRHd2rBu/3GHMj9s3cvE/l3xdncFwOLlUeNzVu49Rr+2kbi5mJyKe+zYUZqHhBDcvDkmk4kBAwaybeuWGuW+/uoLJlx7PSYXl6r3kpMS6dS5CwC+vn54eHgSH3/Mqbgn4g8SFBxGYHAoRpOJ3v2vJG5HzSTQDws+ZtT4Wx3itohqjZ/FnsQJjYiisqKcSif27eHjJwgLDiI0OBCTyciQfr3ZuHOPU9/3ZHIqNptGr872DrG7myuuzZwbTZB0fD+WoHAsQeEYjS506TuSg7vXOpRxdT//OC61ZwiAY/u20DwilpAW9uSOh5cvqupcQjTEDLlFkFdsP28PJ+nEhjgmRpIyqTpvT2freLvbl2uavW0DMKo0KN9+Iv4ggc3DCQwOw2gy0avflezZvr5GuSXzZzPymkmYTOfv2zb4mc/t21ZO71uAtFP78Atoga+/vb1o030UCfsc24uI2Or2sXlkFwrz7O2jgoKtsgKbtRKbtQLNVomHt3+NGBdKSbC3UeZA+77t1Gckh+PWOJRxdat93wIc2r0KP/8wh6SEEEIIIYSo1iRJBi93yC+u7skXlIC3R90/ibvHqMSnOn97Qm183BWHmPkl+kVjnu9MjkZsmIrJAO7NIKq56pD0uJiS/HQ8fZpXvfbwCaa4IL3O8kd2LiaizYCq1zZrOd+/O54ls67n5IFVTsUE+zYuKKl+XVCi4+Ved/mu0SrHTzs/tLouhXnpeJur6+vtF0xhXs367lgzn/eeGsaq76Yz4sZnaiw/vHsFzVu0w3heZ6YuGYWlBJ2XIQnyciOzqLTWsqfzizmdX0zPFoEAaLrOO2v28MigLvXGqRE3v4hgX6+q14G+XqTnFzmUSczMJTEjh0kz53PzO1+z+fDJGp/zW9wRRnRr63Tc7OwsAvyrR134+weQnZ3tUOb48XiyMjPp2cvxqm5kVBTbt2/FZrORlnaGhLPlnJGbnYnZP6jqtdkSSG6247qnEo6Qk5VOlx796vycXVvW0CKqtUNHtS6ZObkE+purXgea/cjMzq1Rbv22Xdw65VmeeWsW6Vn2bZF8Og1PD3emvvk+tz32HLO++Aabzbl2JD83HV9L9XHsaw4iP6fmcbz59wW8/vAIfl7wDlff+rT9O6edAkXhk9fvYsbTE1j706dOxQTwdLOfq+cUloKXW93lO0cqJJypLu/lBndeqfLAaJVtR50bxQCQm5NRc9/mZDiUse/bNDpfbN9uXU2LqDZO7VuwtxdeftXJPU/foFrbi3P2b1lMZDt7+xgS1ZXw2N7MfrofH03tR8u2/bEEt6o3ZkFuBj6W6pje5iDyc2vG3LZqPm8/diUrFk1n9M32fVteVsyGn+cyeNz9TtVPCCGEEOJ/0UWTDIqijDjvbx9FUT5VFGWfoigLFEUJush6dyuKsktRlF1x6+Ze0hfsFKUSYlHYdODSkgyX4niqztFkjXvGmLh+kImkDPuohsZ2LG4ZmSkH6Tzwzqr3bpq6hvEPfc+QG6az5afXyM9OavS4HSMVQswKWw79ddu41+Cb+Ne0lQyd8Cgbf3acZyIjNZ5Vi99m9K0vNnrcFYeTGNI6HMPZ2wO+jYunX6sQhyRFY7LaNBIzc5n7z4lMmzSaF79ZQUFJdc8vM7+I46czuaxty0aLqWkac+d8zJ133V1j2bArR+Dv78/DDz3AnE9m06ZtO6dulXA27sJ5M5l4+0N1lklJSmDRl7O47f6pjRIToF/PriyePZ0vZ7xCz87teeV9e5tj0zT2Hj7Gg7dez9w3nud0eibL125stLgAl195I1Nn/saoG6awaulswH7rwcmjcdz0wJs88PxXHNi5mvgD2xo1LkD7CIVgs8L2o45JiU9/15i9XKNjCwV35wZu1EvTNL6Z9w4Tb59SZ5nUpAS+++J9Jt33dOMEvcChHT+SnnSAnkMnA5CbkUh2WgL3vLKee1/dQNKxbaQc39Vo8foMvYlHp//O8OseZd2P9n27ZskHXD5iEs1ca45IEkIIIcR/Lx3lb/mvqdR3o/BrwG9n/34bOAOMAa4BPgaurm0lXdc/AT4BeO6Lihrd8cISHEYCeLtDQXHNXntUc4WBHQ3MW1GJkxcg65Rf4njLhY+7UmvMuqzba2PdXvsY5euvMJKV79y67j5BFOWfqXpdnJ+Gh3fN/ExK/Bb2rJnN2Hu/wmCsvgro4WMv620JJySqF9mph/CxRNQbt/DsRHDneLsrFJbULBcZrNC/g4HPf7de8jYG8PINoiCnur4FuWl4+daZj6JDr1H88nV1MqEgJ41FHzzI1Xe+gTmw/noCBHq5kX7esI30wlICPGu//LvicCJPDetR9Xrf6Wz2JGfybVw8pZVWKm0abiYjD11R/2SIgT6epOUVVr3OyCskyMfToUyQrxcdWzTHZDAQZvGlRYAfSZm5dGhhv0r++56jDO4Ug8ng/PwiFos/mVnVIwiysjKxWCxVr0tLS0lKPMXUJx8HIDc3h5dfeo5/P/cSMbGx3HX3fVVlH3v0YULDwpyK62cJICer+opvTnZG1S0QAGWlJaQkJjDtWfvn5+dmM/PVx3j4melExrQjJyud915/grsffoGg5s7FDDD7kZGVU/U6IyeXAIufQxkfr+ptPmbIQD786lv7uhY/YlpGEBpsH7UyoFc3DsYnOBXXxy+IvOzq4zgvJx0fc93HcZe+I/lh3sv2dc1BRLXpjoe3/Xu26dKflJOHiOlQ/ySmRaWcvf3B3r54udkTBxdqGQiXtVOYv1ar9bwtKoPMAp3wADiaUm9Y/MyBNfetObDqdVlpCalJCUx79h4A8vOyee/VR/jXM+8QGW3ft+9Pe5y7Hn6RQCf3Ldjbi8Lc6tvDivLSa20vEo9sYdtvs7l+ytdVo5vi964kJLIzLmc7/JHt+nP65B7ConvUWP983n6B5GdXxyzIScfHr+5927HPSH78wt5GJSfs48DOFfy2aDplJYUoiorR1Iy+w25yus5CCCGEEP/tGnIJs4eu68/qup6o6/oMoOV/GjQ1S8fsreDrCQYVOkaqHElx7LQHmxXG9jUyf00lxU4O+b1ozEwdf28Fv7MxO0WpHE5yrletKOB29opgsJ/96uFxJ2/fCAzrSH5WIgU5KdisFRzfu5wW7QY7lMlKPcTG759nxKQPcfOs7iyWl+Rjs9rvbS4tziXt1B6HCSMvJjVbx+Kl4Othn2m+fUuVoymO3znYD0b3NvDNOisl5U59bL1CIzuSnZ5Ibqa9vgd3LKd1F8f6Zqefqvr72L51mAPt8yOUlRSw4N17GDr+USJiuuGs9s3NJOUWkppXRKXNxorDSVwRHVqj3MnsAgrKKugcWr2NXxvTl1/vH8vy+8YyZVAXRneIdCrBANA+ojlJmbmkZOdRabXxW9wRBnZw3D+DO8Ww63gyALlFJSRm5hLm71u1/Ne4w4zo7vytEgCxsa05fTqVtLQzVFZWsmHDenr36Vu13MPDgwXfLGbe518x7/OvaN2mbVWCoaysjLIye691T9xuDKpaY8LIukTGtCP9TDKZ6alYKyvZvvF3uvaqnvzO3cOTD75eydtzfuTtOT/SqnWHqgRDcVEh77w8hetufZDYts4/zaJNdCQpZ9I5nZ5JZaWV1Zu2069HV4cyWbl5VX9v2rWHFqH2BE7bVlEUFZeQm2+fNXH3gcO0DAtxKm54qw5kpSWRnZGC1VrBH1uX0777IIcymWcSq/4+vGc9/sH27di60+WkJcdTUV6KzWblxOFdBIXVP4wf4HQO+HmCz9nztm2EQvwFtzEF+cKIHiqLN2kO562XGxjP5qpcTRDur5BTiFMiY9qRcd6+3bHpd7r2qr5ty93Dk/e/Ws30OT8xfc5PtIrtUJVgKCkqZOYrDzPhlgeJaduw246CW3QkN+MUeVnJ2KwVHNn9C606OrYX6cmH+H3hc4y79yM8vKrPXW9zCMnxO9FsVmy2SlLidzp1u0RolL2Nysm079t925bTpqvjvs1KO1X199G967EE2fft3c9+zePvrObxd1Zz2ZW3MnDM3ZJgEEIIIYS4QH0jGQIVRXkE+xxi3oqiKLpeNS3ifzzGWtPhl+1Wbh1qQlXtj7DMzNMZ3MVAarbG0WSd4d0NuBjtowYA8othwdnHVd45woi/j4KLER6dYOLHLdZ65xPQdFi21crtI0woisLuYzYy8nSGdjOQkqVzJEkj1F/h5qEm3FygbYTKkG467/5QiUGFe0bZJ+Urq4Rv11mdvl1CNRjpd9W/WT73TnRNo3XP8ZiDY9i54j0CwjrQsv1gtv3yFpUVJaz8+mGg+lGVubsUBBUAACAASURBVBkJbPzheVBU0DW6DrrL6SSDrsPynTZuHmJ/TOgfCfand1zRSeV0js6xFJ1h3ezb+Nr+Z7dxic43Zx9XeduVBvy97dt4yjgjy7bZHO79vlh9R970b76eYa9vl37jCQyNYe3S9whp2YHWXQazY/V8Th7eimow4ubuzdV3TgNgx+r55GQksf6nD1n/04cA3PLIp3h4Wy4WEqOq8uSw7tz/7Xo0XeOqjlG0CvDhw437aRds5ooYe8JhxeFEhrdt4dQj7pxhNKhMHT+U+z5ajKZpXN2nI9HN/flg+SbahwdzRcdoLmvTki1HTjLutXmoqsKUqwbi62EfZZGanU9aXiE9WoU3KK7BYODe+x7kuWefRtM0hl05nBYtWvL1V18QExPrkHC4UH5+Hs89+zSKqmCx+PPoY082IK6RW+5+nLde+Jf9MYdDxhAW0Yof5n9My+i2dOs9oM51Vy3/lvQzKfy4aC4/LrLfzvD4C+/j7Wuucx0Ao8HAlMk388jL07FpGqMH9ycqIpQ5C3+gTXQk/Xt25btfVrJp5x6MBgNenh48++Dks99X5YFJ1/PQC2+iA62jWjB26BVO13Xcbc8wZ9rd6JpGzyvGERwWzW/fvU94VHvadx/M5t8XEH9gKwajETcPbybe9xoA7p4+DBg5iXefvR4UhbZd+tOu60Cn4uo6rIzTmDhARVFg30mdrALo317hTK7O8dMwqLOKixHG9bU3wQUlsHizhsUbhnRW0bE32NuP6g5P7Kmvvjfd9Thvv/hPNJuN/kPHEhrRiiULZtMyui1de9X9/VctX0T6mWSWLZrLsrP79rEXZtW7b8HeXgy57jm+/2AymmajY9/x+IfEsOnndwmO6EB0pyGsX/ImleUlLJtrvw3H29yccffOJrbrcJKObuPzV8eAohDZrn+NBEVddR1z67N8/uZkdF2j24BrCAqLYdX37xEa2YG23QazbdUCEg5uQTWYcPPwZsLdrzu3IYUQQgjxX0keYdkwin7hoxTOX6goz1/w1oe6rmcqihIMvKnr+q31Bajtdok/m9X6l4cEwN/fucnOGlth4X/wGIhGENOySZ6AytXHXvjLY6ohDUsENJbkmGFNEje70rf+Qn+CaOuhvzzm1vKef3lMgAMJTfOf1cCOtdw39Rc4mOpVf6FG5ufVdHP5TOjdJPMqCyGEEE3lv7oXfiQhpWk6mJeoTauwJtkvF+0l6rpe68x7uq6nKYqytrZlQgghhBBCCCGE+N90KZdaGn/qfyGEEEIIIYQQQvxtXXQkg6Io++paBNQ9HbcQQgghhBBCCPFfQOZkaJj6bqoPAoYDuRe8rwBb/pRvJIQQQgghhBBCiL+l+pIMPwOeuq7/ceECRVHW/SnfSAghhBBCCCGEEH9L9U38eOdFlt3Y+F9HCCGEEEIIIYQQf1dN8wxCIYQQQgghhBDib0DXZU6GhpAHeQshhBBCCCGEEKJRSJJBCCGEEEIIIYQQjUJulxBCCCGEEEIIIeogj7BsmD89yWC16n92iBpyskr+8pgAnp5Nk7PRtCYJy5mspolb1mPoXx7T/cSevzwmQIHNq0nini5omrjN/GL+8phlRU0zoKuoqLJJ4uaUujVJ3IomqG5adtP8ILgx7l5yVjZJaMzPftw0gYUQQgghzpLbJYQQQgghhBBCCNEoJMkghBBCCCGEEEKIRiFzMgghhBBCCCGEEHWQORkaRkYyCCGEEEIIIYQQolFIkkEIIYQQQgghhBCNQm6XEEIIIYQQQggh6iC3SzSMjGQQQgghhBBCCCFEo5AkgxBCCCGEEEIIIRqFJBmEEEIIIYQQQgjRKGROBiGEEEIIIYQQog66LnMyNESTJRliQhVG9zGiqgo7j9rYsM/msLxlsMKo3kaCzQqL1lo5cEqrWja8p4E24fZBGGv22Nh/UsMZ7SKNXDfEHVWFzXvLWbG93GF5dJiR64a4ERpo4NNlxcQdrXRY7uoCz0/2Ye+xCr5ZVep0XaOCYVhXFUWBvSd0th7RHZb3ilXoEqWg6VBSDj/v0CgoAW93mNBPRQFUFXbF6+xJ0GsPUovoEIV/9DSgKBB3XGPTAcft1LetSrcY1R63TGfpFhv5xfZlNw8xEBagkJShs2CNrZZPr1vy0Y1sWfYquq7RpucEugy622H5vg2fcWTnYlTVgKuHmYHXvoqXXygAc55qhzk4FgAP3+aMuO0jp2Ju3XOAmZ8txKZpjB3Sn1vHjXRY/svazcz66jsCzH4ATPjHIMYOGcDuA0d49/NFVeUST5/hpYfvYWCvrk7F3Xw0kTeWbULTNcb1bMedg7rXKLNibzyzV+0EoHWIP9NuuBKAGcu3sPFIIgB3D+nBiM4xTsUE2Lt7K1/OmYmm2Rg0bCxjr7211nI7Nq9l5rSneeWdeUTFtK16PysjjccfuJHxN9zJ6Gtucjru0X0b+fmr19A0jZ5XTOCKMXc5LN+++hu2rlqAqhpwcXVn3B0vEhQaXbU8L+s0M54aw5BxDzBg1B1Oxfxj9za++GQmmqYx+MoxXHXtLbWW2755LTNef5ZXZ8ylVUxbMtLP8Oh9NxISGgFATOv2TH7wCafremzfRpbPt9e1+8AJDBztWNcda75h++oFKKoBl2buXH37iwSGRpOSsI+lnz9vL6TrDL76Adr1GOZ03JhQhVF9jKiKwq5jtbSNQfa2McissGidlYPnt409DLQ+2zau/cP5thHgyB8bWfrlNDTNRu9B4xlylWN9t6xcxOaVC1FVFRdXd66d/ALBYfZ9ezrxKIs/fZGykiIUVeXhVxZhcmlWb8xThzew4Qd7W9G+z7X0GOrYVsSt/YyD275DVQ24eZoZesNreJtDSY7fxsYlr1eVy804wYhbZ9Cq01Cn6pp4eCMbltjjtus9oUbcPes+4+C2xVVxh0x8FW9zKCnx29i4dJpD3OG3vkOrjs7FNUW1x334daColP+xibItKxyWq95+eIy9HcXVDRSV0jVLqEw4AIDrZSNo1uVy0DVKViyi8sQhp2IKIYQQQvzVmiTJoCgw9jIT836roKAY7h9r4kiSRkZedQc6r0jn+w1W+nU0OKzbOlwlxKLy/pJKDAa4a6SJYyka5ZUXRqkZ84Zh7ry7qIjcQo2pk7zYd7ySM9nVP8JzCzS+WF7CsF61/zge29+N+GRrg+s6vLvKwnUaBaVw+zCV+NM6WQXVZdLzdOat1LHaoFsrhcGdFZZu1Skqgy9Wadg0MBnhrhEq8an2952JO6q3gS9XWikogbtHGjmarJGZX13mTI7OJ79YqbRBz1iVK7sb+G6DvUOz+aCGyQg9Yht2R42m2di09CVGTZ6Hh08QS2ZdS4t2g/ELqu5o+oe25Zo+izG6uHFo60K2L5/O0JtmAGAwuTL+4aUNimmzabz96Xze/fcjBJr9uGPqK/Tv0YXI8BCHckMu68ljkx071N07tOHL6fYOYX5hEdf+82l6d27nXFxN47WlG/h48liCfDy5cdZ3XNEuklZB5qoyiVl5fLouji/uuwZvd1eyi0oA2HD4FEdSM/n2oeupsNmY/PFS+rVugaerS71xNZuNz2a/zdSX38ViCeTZR+6gW+/+hEVEOpQrLSnmt5++Jbp1+xqf8fWn79G5ex+n6lkVV7Ox7IuXufPJT/E2B/HBc9fRttsghyRC58tG03vIRAAOxa3hl/lvcMcTc6qW/7LgDWI79Xc+ps3GvI/e5plXZmKxBPL0lMl0792v1rr+uuw7ols77rug4FDeeP+LBtXzXF1/+vJlbn/CXtfZL1xH266DCDyvrp36jqbXYHtdD8et4deFbzDpsTkEhsVw3wvfYTAYKczLYNaz42jddRAGQ/3NraLAmL4mPlthbxvvG2vicJJG5vltY7HO4o1W+l/YNobZ28ZZS+1t4+R/ONc2nqvvD5+9yj1Pz8HHEsTMZ66nffdBVUkEgG6Xj+KyYdcDcGDXGpZ99SZ3T/0Em83Kgg+e4sYHXiekRRuKC/MwGOuvq6bZWLf4Jcbd9xmevkEsemcCkR0GYwmujhkQ1paJj36PycWNfZsWsHnZW/zjtpmEx/Thxid+BKCsOI8vXr2SiDaX11/Rc3G/f4mr751njzvjWqI6DMZ8ftzQtlz/yGJMLm7s37yQzT9N5x+TZhAW04cbHl9aFffL14YT0dq5uCgK7v+4gcL5M9EKcvG+cyoVx/ahZZ2pKuLabxQVh3ZRHrcB1b85XhMfJH/WM6j+zXFp34P8j19E9fLB66Yp5H/4b9CdTzoLIYQQQvxVmmROhrAAhewCndxCsGmw74RG2wjHr5JXBGm5eo3fUIG+CqfSNDQdKq2QlqMTG1Z/NVo2N5CRp5GVb++07zxcSacYxw5ddoFGaqat1t9tEUEGvDxUDp904hf7eULMkFsIecWgaXAoSScm1HG4TWIGWM9erEzN1vFyty/XNPv2ATCqNOjBKaEWhZxCndwi+2ccOKVVjf4451S6TuXZuMlZGt7u1ctOpulUNKyqAGQm78PHEoG3JRyD0YVWnUdy6tBqhzIhrfpgdHEDIDCiM8X5aQ0PdJ5Dx08SFhxIaFAAJpORoZf3YsOuPxr8OWu37aZv1464Nqv/CizAgeQMwi0+hFl8MBkNjOgcw7pDJx3K/LDjEBP7dsTb3RUAi6d9I5/IyKFbZAhGg4q7i4mYYAubjyY6Ffd4/CGCmocRFByK0WSi74Ch7N6+oUa57+Z/wpjxN2MyOR7nO7euJyCoOWERUU7FOyc5YR+WoAjMgeEYjS507jOSw7vXOJRxdfOs+ruivBRFqT5qD+5ahV9AGEHndVzrc/zYYYLPq+tlA4awa9vGGuW+/XoOYyfcjMnk3L6rT8oJx7p27D2Sw3EXr+u5M9SlmVtVQqGyssKeOXBSmL9CjhNtY3otbWPAhW1jrk6ME20jQNLx/ViCw7EE2evbte9IDu5a61hf99r37bF9W2geEUtIizYAeHj5oqqOCZDapCfuw9e/BT7+9rYipusoTux3bCvCY/pgOttWBLfsQlEtbcXxvSto2bZ/Vbl64ybtw9c/oipubNeRnDjgGDfs/LgtOlOcV3vcFm2cj2sMiUTLyUDLywLNRsXBXbjEdr6glI7SzP55ajM3tEJ7VtgltjMVB3eBzYqWl42Wk4ExJBIhhBBCiP+PmiTJ4OOukF9c/Qs5v0TH28O5H+JncjRiw1RMBnBvBlHNVXycWNfPSyW3oHrUQl6hhp+nczEVYMJgN75fW+JU+fN5uUFBaXVdC0vs79Wlc5TCiTPV5b3cYPJwlQfHqGw74twoBrDfanHu1gewb2Mv97rLd4u2j5K4VMX56Xj4Nq967eETTHF+ep3lj+xcTHjrAVWvbdZyfnhvPEtnXc+pg6ucipmZk0ugxa/qdaDZj8zs3Brl1m2P4+ZHn+fp6R+RnpVTY/mqzTsZ1q+XUzEBMvKLCPat7ngF+niSfv5GBxIz80jMymPSh99z86zFVYmE2Ob+bDmWRGlFJbnFpew8kUpafpFTcXOzM7H4B1a9NlsCycnOdChz8vhRsjMz6NrT8SprWWkJP33/NeNvuNPpep5TkJuBjzm46rW3OYj83Jr7duvK+bz16JX89s10xtzyNADlZcWs/2UuQ8bd36CYOdmZWALOq6t/HXXNyqBbz8tqrJ+Zfoan/nUbLz71AIcPOJ94qq2uBbXUdduq+bz92JWs+HY6o25+uur95IS9vDd1NLOeuYqrJj3v1CgGAG8Px7axoFjHx925diotRyPmP2gbAfJz0/G1VJ+3Ppba9+2m3xfw2kMj+HnBO1w9yV7fzDOnUBSFj1+/i3emTmDNsk+dilmUn46nX/U29vQNumhbcWjbYlq0HVDj/WN7fiG222inYgIU56XjeV4b5ekTTNFF4h7cXnvc+D3Lie02yum4ipcvtoLqdkkrzEX18nUoU7rhJ1w69sb3X9PwnPggJSu+AUD18kW7YF3lgnWFEEII8efRUP6W/5pKg2+XUBTFout69p/xZZxxPFUnzF/jnjEmissgKcN+5e7PNLBbMw4kVJJX+OcGat9CoblZ4es11cmQwlKYu0LD09U+P8ORZJ3i8ot8yH+gU6RCiEXhsxUNm3vhUsXHLSMr5SBj7v2q6r0bn1qDh08QBdnJ/DxnEubgWLwtEZccq1+Pzgzr1wsXk4klK9fz8qx5zHrhsarlWbl5JCSl0KdzzVsLLoVV00jMymPuPVeTnl/MHbOXsHjKRC6LjeBgSgaTPvwePw83OkcEYVAaJ+enaRpff/ou9z787xrLvl8wl5FXXY+r20UyTpeo77Cb6DvsJv7Y8jNrfpzNdfdMY/UPH9BvxCSauXo0aixN0/hy7vvcN+WZGsv8zBZmffYDXt4+nDh+hOmvTGX6h1/j7t5436HP0JvoM/Qm9m79mXXLZjPhbvv9+uGtOvOv138m43QC338ylZhOA5yao+BSHD+tExagcc/o6rZRd35KBqf0u/JG+l15I3Gbf2bVktnccP/r2DQbJ4/G8dAri3Bp5srsV+8kLKo9sR0adjvOxRzZ9SPpyQcY/8+vHd4vzs8g6/QxItr0a7RYjnGXkZF8kPEPfuXwfnF+BllnGj9us/a9qNi7hbLtqzCGRuF51e3kf/xSo8YQQgghhPizXTTJoCjKNGC6rutZiqL0AL4FNEVRTMCtuq6vr2O9u4G7AUbcMouuAyc7LM8v0R2usPm4KxQUO9+BX7fXxrq99g7x9VcYycqvf93cQg0/7+pOnK+XSm6RczGjQgxEh5sY2K0ZzUwKBoNCWSUsXV//5I+FpeDtpgD2WF7u9vcu1DIILm9nTzDYaukYFJVBZr5OeAAcSan/OxeUgM95fSkfd4XCWgZiRDVXGNDRwGe/W2uN21AePkEU51XfY1ycn4aHT1CNcinxW9izZjZj7v0Kg9HFYX0Ab0s4IVG9yEo9VG+SIcDsR8Z5IxcycnIJOG9kA4CPV/WIg7GD+/PBV4sdlq/esouBvbphdOJe8nMCfTxJy6sefZCRX0SQj2MHNsjHk47hQZgMBsLM/8fefYdHUa0PHP/O7CYhvWcDKUAKvROK9CpFUMCGYkORay/YFRULKkW9FxURxS6gYrmI9CodQu8JARISQtqm992Z3x8bkywhZONFoj/fz/PwPNk5Z+bdM3Nm2DlzzhkvmgZ4k5SZQ7swE/cOiuHeQTEAPLtoNU0DvR2K6+sfSFZmeuVnc1Y6fv6BlZ9Lios4m3iK15639RrIzTYz+/WneXLqTE7GHWXntg0s/PwDigoLUBQFJ2dnho26sc64Xr5B5Jqruo3nmdPw9q15bH/XoedIfv78FcA21OLQ7lWsWDybkqJ8FEXF6OxCr6GXnnTSzz+QrIxqZc2sWdbkpFO8+txDVWV97RmefHEGkdGtK4eKRES1whQcQmpKEpHVJsCsT1m9LlHW9j1GsvSLV2osD2oSiXMjN9JT4glp3q7OuHmF9tdGL3eF3KI/dm28qb+RzDzH1vX2NZGTVXXe5mZd+th2umokPyx4DQAfPxMRrbri4WU751p36kvK6aN1NjJ4eJsoyK7axwU5aRe9ViSd2Mbu1fO4/uGvMRrth/7E719BZIehGAxOdReygruPiYJq16iC3PN41BI3ds08xj1kf42yxV1JZPsh9Yqr5+dg8Kq6Lqmevmj5OXZ5nDv1pmDRHAAsKafA6ITi5oGWn4N6wbr6BesKIYQQQvxV1PXo9Bpd1zMr/p4F3KzrehQwFHi7tpV0XZ+v63qMrusxFzYwAKRk6AR4Kfh6gEGFDhEqx5Icu8NVFHCteCAY7KsQ7KdwMqXudRNTrQT5qvh7qxhU6NbaiYMnyxyK+emyIp7/MJcX5uXxw4Zidh4udaiBAeCcGXw9bTf8qgptwpUawxJMPjAiRuX7zRpF1XopeLqCsWJocyOnirks8h0Ky7ksHT9PBZ+Kfdyumcrxs/b7KdgPRvc0sHCDhUIHh2HUJTC0PblZieSZk7Faykg4sJymrQfZ5clMOcrmH19m2F1zcfXwr1xeWpSL1WI7JiWF2Zw/s89uwsjatI5qxtnUNM6lZVBebmHt1l30jbEf65yZXfWDfHPsfpqFNrZLX7N1V72GSgC0DQ0iKSuXZHMe5RYrKw/E0791M7s8g9o2J/ZUCgDZhcUkZuYS6ueNVdPIqdjpcamZxKVmcVW0Yz02IqNbc/7cWdLPn8NSXs7239bStXvVZIpu7h7MX7iSOQt+Ys6Cn4hq2ZYnp84kIro1L8+YV7l8+LU3c92NdzrUwAAQGtGezPOJmNOTsVjKOLBjOa27DLTLk3n+TOXfJ/ZvIiC4KQD/evFrnnl3Hc+8u47ew+5gwOjJdTYwAES2aMX5c8mVZd322zq69qh6euzm7sHHC5fz/qc/8P6nP9jKWtHAkJebjWa13XCnnU/h/LmzmIJDHCprSPP2ZKUlYs6wlfXQzuW06lx7WeMObMLfZCurOSMZq9U2QWx2ZgqZqafwCXAsbkqmjr+3/bXx+B+4NprqcW0ECItsR+b5JLIqju2+7ctp29W+vBmpVXOGHNtXdWxbduhN6tl4ykqLsVotJByLxRQSWWdMU3h7cjLPkJt1FquljPh9vxLRzv5akZ58lPXfvcToez/EzdO/xjZO7P21XkMWAExh7cnJSCQ3y3aNitu3nOZt7eNmJB9lw/cvM2rS3IvGtQ3RqF9cy7kzqH5BqD7+oBpwbhtDedwBuzxarhljM9vcFqp/MIrRCb0on/K4Azi3jQGDEdXHH9UvCMu50xcLI4QQQog/gY7yt/zXUOp6bGtUFMWo67oFcNV1fTeArutxiqL84b6/mg5Lt1uYONwJRVHYE2clPUdnSBcDyZk6x5M0QgIUbhvihKsztA5XGdxF5z8/lmNQ4V/X2J4elZTDdxstDg2X0HT4dk0Rj9zkgarAtkNlpGZqjO7TiMTzVg6eLKdpsIH7xnng5qLQPsqJUX10Xl2QV/fGL0HXYfVejfH9VdSKV1hm5kG/dgqpZp34czCoo4qzEcb1srX55BbBki0a/l4wpJOKjm1eiJ3Hdbu3Q9RV3uW7rNw+xIiqwL6TtjdLDOyoci5L50SyztVdDTgbbU88AXILdRZtsN2U3T3MQIC3grMRplxv5L/brSScq3tHqwYjva97kRUL7kHTNFp2ux6/4GhiV88hILQdzdoMYufyWVjKilj79WNA1asqs9MT2PzTyyiKiq5rdBpwr0ONDEaDgSfuuZXHptteczhqYG8iwkKYv/hnWkc2o2+3Tny3fB1bYg9gMKh4ebgz9cGJleunpmeSlmmmc5sWju3cyrgqz13Xl/sXLEXTdMZ0a01UsD8frN5J29AgBrRpTq8W4WyLO8vYtxeiqgqPj+yFj3sjSsstTJz3o638Ls68MX4IRoNjwyUMBiN33fcEb738GJqmMWDIKEKbRvD91/OJiG5N1x6Ov72hPgwGI9feMZVPZ01C1zRi+o3DFBrNmh/mENK8HW26DGL7moWcPLINg8EJV3cvbpz8Zt0briPmxPse542XplS8rnMUYU0j+O7rj4mIbkXMJcp67PB+vv/mEwwGI4qqMunBp/Dw9HI47qjbp/LFrEm2V1hWlHXtj3MIadaO1l0GsXPtQhKObEM1OuHq5sX199rKmhi3h83LPkY12q5vo+94CXdP3zoi2mg6/LLdwl3DbOvujbddGwd3NpCSqXP8rO3aOGGw7drYKkxlcGedOT/Zro2TR1ZdG7/f5Ni18ffyjrvrBea/ORld0+g+YCzBYVGs/P49Qpu3pV3MILauXkjcoe0YjEZc3b245f43AHDz8Kb/yDv59ws3oygKrTr1pU2X/nXGVA1GBlz/Ev+dNwlNs9K2x/X4N45mx/L/EBTejoh2g9m6dCblpUUs/+xRADx9GzP63nkA5GUlU5CTSmhk/RoHVYOR/te/yNKPbNeoNr/HXTGHoLB2RLQbxJalsygvLWLF549Vxh01yfY63TyzLW5IPeOiaxStXIznLY+CqlK6fyvWzFRc+4/Gci6R8viDFK1dgvs1t9Gox2DQoeCXzwGwZqZSdnQP3vdNA81K0cpF8mYJIYQQQvxlKfolfqgoivIwMBp4C+gH+AI/AoOACF3XL/7C+mqeX1B6xX8JmTPrP0Hj5RDezLEbmMuttPQyD7x2kJdXg7wBlYkRW654TLdT+654TIAjbW5rkLiJOQ0zqVxz35oTcv7ZTmb51Z3pT7D/6B94fctlcFWnut/88GdITLvy14tL/f/2Z7p1730NEhfAb+pHDRZbCCHEP1rDPTa/AvbFZ/4tW/c7Rwc0yHG55K8+XdffUxTlEHA/0KIifzTwM/Dan//1hBBCCCGEEEII8XdR56MlXdc3AhsvXK4oykTgs8v/lYQQQgghhBBCiL8GXf9/3VHjsvtf3plXcyp1IYQQQgghhBBC/GPV9QrLg7UlAbW/30wIIYQQQgghhBD/OHUNlzABw4DsC5YrwLY/5RsJIYQQQgghhBB/EQ35Osi/o7oaGZYBHrqu778wQVGUjX/KNxJCCCGEEEIIIcTfUl1vl7jnEmm3Xv6vI4QQQgghhBBCiL+r/2XiRyGEEEIIIYQQQohKdb7CUgghhBBCCCGE+KeSV1jWj/RkEEIIIYQQQgghxGUhjQxCCCGEEEIIIYS4LP704RIDYq5815Llvzld8ZgA/dqXNEjcgrKGKa9BKWuQuK7m5CsfVDVc+ZhAS/OWBomb5z60QeKezva74jG7B8Rf8ZgAJz2iGiRuD5fYBonr16zNFY+ZnON+xWMCNGpsapC4lvwC8v49pUFiez32ToPEFUIIIcRfj8zJIIQQQgghhBBC1EJH5mSoDxkuIYQQQgghhBBCiMtCGhmEEEIIIYQQQghxWchwCSGEEEIIIYQQohbyCsv6kZ4MQgghhBBCCCGEuCykkUEIIYQQQgghhBCXhTQyCCGEEEIIIYQQ4rKQ/G+zDAAAIABJREFUORmEEEIIIYQQQohaaA39Bf5mpCeDEEIIIYQQQgghLgtpZBBCCCGEEEIIIcRl0WDDJY7u38IPn81A06xcNXgcV4+ZZJe+ZfV3/LZqEapqwKWRG+P/9TKNQyOxWspZOG8aZ08fRdOsdO93LVePnVRLFHutwg2M6+eCosCOo+Ws21Nulx7RRGVsXxeaBKh8ubKEAwnWyjQfD4Xxg13w9VDRgflLizHn6w7FPbR3K4sWzEbXrPQdMpaR10+8aL7Y7ev4cOZTvDjra5pFtaEgL4e5s57mzMkj9B44mgmTn3Uo3u+O7d/Cj5/b9nHPQeMYeuE+XvMdWyr2sXMjN8ZPfpng0EhiNy9j/S+fV+Y7lxTHk299R2izVg7FPbp/C0s+m4GmafQaPI6rx9xjl7559Xf8tmpx5bG95V8vVR7bb+ZN4+zpYxXHdjTDHDy2Ww/HM/O7lWiaxtg+Xbh7eN8aeVbFHuajZRsBhRahJt6adENlWkFxCeOmfcDATq147pZrHIoJsPX4GWYs/Q1N0xnbvS33DIqpGfdAHPNW7wRFoWXjAN6aMByAd5dt4bfjZ9B1nZ7R4TxzXT8UxbHX42w7eJzZ3yzFqmmM6d+diaMG1cizeucB5v+8GgWF6PDGvHH/BE4kpvDmFz9SWFyKqircc+1gru7RyeHyHtm3le8+m4mmafQePJbhY++2S/9t1fdsXPUtqqri0siNCf96kSZhkVjKy/lm/mskJhxFUVRumvgULdt1czjuiYObWfbVG2iaRrcBNzBg9L126TvXLWb72oWVdXns3a9gComqTM/JPMe7z45m8NgH6XfN3Rdu/qJ2x+7hw/mfoGlWhl99NeNvusEuffWadXz86Wf4+/sDcN3oaxgx7GoAnn/xZY6diKNdm9a8Nu0lh8sJEBEMQzqpqArsP62z47j9daZbC4VOzRU0HYpK4dfdGnlF4OUG1/dWUQBVhT0ndfYlOHaNAtix9yD/+fRrNE1j1JD+3D5utF368vWbmfvlYgL8fAG4fsQQRg8dAMD5jExmzP2U9MwsFEVh1tQnaBwU6FDcQ3u3sfCT2WiaRr+hY7jm+rsumi922zo+mPkML83+kuZRbTiyfwfff/k+Fks5RqMTN931KG06OFan4g9u5teFb6BrGl373UC/Ufb1adf6xexcvxBVsdWn6+56haCQKJJPHeS/n70MgI7OoDEP0qbrUIdiAmw9lcqsdfvQdJ0xHSK4u2dru/TZ6/ax+2w6ACXlFsxFpWx+dFxlekFpOdcvWMHA6BCeHdrV4biGpq1o1H8MiqpSdngHZbHr7dJd+l2HMazifDE6obp5kv/hCxhCo2jU/7rKfKpvEMUrvsKScNjh2EIIIcT/B/IKy/ppkEYGTbPy/YLpPDh1Pj7+wcx6bjztYwbSODSyMk/XPiPpc/VNAByK3cBPX8zigRfmsW/HaiyWMp5/+yfKSouZPmUMXXuPwD8o5JIxFQVuGODChz8Xk1OgM+VmVw6fspCWXfUjPCdfZ+HaUgZ1caqx/m1DG7E6toy4s1acnUB38Le7ZrXyzfwZPDFtLr7+Jl57+jY6de9Pk7AIu3zFxYWsXbaQiBbtKpc5Obsw9pb7SUlKICXppGMBf4+rWfn+0+k88IJtH79dsY+Dq+3jmN4j6TO02j7+chb3Pz+PmL6jiOk7CrA1MHwy+1GHGxg0zcp3C97goanz8fE3Meu5W2gfM8Du2Mb0GUnfimN7MHYDP34xiwdfmMfeHauxWMp54e0fKSst5vUpY4lx4NhaNY03Fy1n3mO3Y/L1YsKbH9O/Q0simwRV5klMy+LTlVv4/Kl78HJ3xZxXYLeND5ZuoEt0U4fKWD3uGz9t5KPJYzF5e3DrnG8Z0LY5kSb/qrgZOSxYH8sXD96Il1sjsgqKANh/JpX9Z1JZMuVWAO76YAmxp1LoFhnqUNy3vvyJuU9PxuTnze3T5tC/c1siQkyVeZLOZ/D5svV8OvVBvNzdKsvbyMWZVyePJzw4kIzsXCa8/B+uatcST3fXOuNqViuLPnmTR1+ah6+fiTefnUCHmP40Cas6tt36jqDfsBsBOLB7I0u+eJtHps5ly9ofAHjpnSXk5Zp5f/qDPPvWN6hq3Z2pNM3K0i9e455nFuDlZ+KDl26idZeBdo0IHXuNosfg8QAc3bueX7+Zwd1Pf1yZ/uvCGbToULPhqTZWq5X3P/yIt15/lYAAfx5+/Amu6tmdpuHhdvn69+vDQ/ffV2P9G68fR0lpKctXrHQ4JtiuU1d3UVm8SSOvGO4aohJ/TicrrypPWrbOZwk6Fit0jlQY2EHhvzt0Ckrgy3UaVg2cjDBpmEp8im153eXVeOfjL3n35acJ8vdj0tMv06dbF5qH2Z97g3r3YMq9d9RY//U587nz+mvp1qkdRcUlqKpj/xFrVitffTSDJ1/5AD9/E68+dQeduvcj5CLXxzXLFttdHz28fHh06rv4+gWSnHiSt195mHc/XVF3TM3KL1+9xl1P2erTvFduolXngQRVq08drhpF90G2+nRs33pWLJrBnU9+TFBINPdN+x6DwUh+TjofvDiWlp0GYjDU/V+pVdN4a+0ePrxpACZPVyZ8uYb+UU2IDPCuzPPk4M6Vfy/aE8eJ9By7bczdcoguYY413lRSFFwHjqPwx3noBbm43/I4llNH0MxplVlKf/svpRV/O3Xsg6HimmtNPknhN2/bElzc8Jz4PJbEE/WLL4QQQoh/nAYZLpF48hABweEEmMIwGp3o2msEh3ZvsMvj6uZR+XdpSTFU/mZVKCspxmq1UF5WisHoRKNqeWvT1KSSmaORladj1WBfnIX2EfY/DM35OqlZWo0GBJOvgqpC3Flbz4aycii3OFbWU/GHCWocSmBwKEYnJ7r3Gca+XRtr5Pt54VxGjL0LJyeXymUujVyJbtMZo7OzY8GqSTx5iEBT1T7ucpF9XH2/lZUWc7GH6Hu2rqBLrxEOxz1z8nDFsQ2tiDucg5c4tmUlxZVP7xUUykqKsFotlNXj2B4+nUJYkB+hgX44GY0Mi2nHxgP2P4R/3LKHmwd0w6viZtrPq2q7RxPPYc4r4Ko2kdTH4aQ0wgJ8CPX3xsloYHinaDYeOWUfd+dhxvfqgJdbIwD8PdwqygqlFgvlVo0yixWLplWm1eXIqSTCTAGEBvnjZDRydY9ObNx7xC7PT5t2cuPgXni5u9mVt2lwIOHBtpuUQF9v/Lw8yM63b3CpzZmThwkKDiPQZKvL3XoP4+DujXZ5XC+sUxUnbmryKVq26w6Al7cfrm6eJCbYf+fanE04iL8pHL+gMIxGZzr2HMmxPfZPYhu5XliXqyrzkdi1+AaGYgqNwlEn4uJp0qQxjRsH4+TkRP9+fdm2Y6fD63fu1BE317obbi7UxA+yCyCnEDQNjiXptGhif2ImZYClopPVuSwdLzdbuqaBtWJWIqNa7ZLpgGMnEwhtHERIcBBOTkaG9OnJll17HVr39NkUrFYr3TrZGgDcXBvRyMWljrVsTsUfIahxGEGV18er2bdzU418P30zj5Hj7sTJqepa2DSiFb5+trocEh5JeVkp5eVldcZMPmVfn9r3GMmxfbXXp/Jq9cnZxbWyQcFSXsZFL5q1OJxqJszHk1AfD5wMBoa1DmfjyZRa8688lsTw1lWNWkfPm8kqLOGqZsEOxwQwBIej5Wai55lBs1Ietw9jZLta8zu17Ez5iX01l0d3wHLmGFjKL7KWEEIIIUSVBunJkGNOx9e/6oeSj7+JM/EHa+T7beUiNvz6JRZLOQ+/tACAzj2Hcih2A1MnD6KsrIRxdz6Fu4d3jXUv5O2ukF1QrddCgU7TYMfaWIJ8VYpLdSaObIS/l0LcWSu/bCtzqDdDjjkDv4Cqsvr6B3E6zr6raWLCMcyZaXSM6cuqn7906DvVJdecjs8F+zjxZM19vHmVbR9bLeU8+OKCGun7tq9k0pNz6hE3DV//qifqvv4mzsQfqpFv08rFlcf2kZc+AWzH9mDsRl6YPJiysmLG3fm0Q8c2PSePYF+vys8mXy8OnU62y5OYlgXAnTMXoGka940aQO920WiaxttLVvHG3ePYccy+gaDOuHkFBPtU3YwEeXtwKCnNLk9ipu1J5J3vf49V17h/aA96t2pGx2aN6RYZypBXP0EHxvfqQITJz7G42XmY/HyqyuvnzeGEJPu45zMBuPu197HqOv8aM5ReHex7oxxOSKLcYiU0yB9HZJvT8Q2wr1OnL3JsN65YzNplX2O1lPPYtPkAhDZrwcHdG+nWZzjZmWkknTpKdlYazaPb1xk3Lzsdb7+quF5+Js4m1KzL29d8w5aVX2C1lDPpuc8AKC0pZNOvn3DPMwvYvPwzh8oJkJmVRWBAQOXnwIAAjp+o+QR3y9btHDp8hJCQEO679x6CAuv5lPkCHq6QV1R1YckvtjU81KZjc4WE1Kr8nq5wU18VXw9Yf9CxXgwAGVnZBPlX1YNAfz+OxifUyLdp+24OHD1BWONgHr77VkwB/pw9dx5Pdzeen/EfUtMziOnQlvtuuxmDoe7ra7Y5Hb+AquuFn38QCfH218czCccxZ56nY0wfVvx08etj7PZ1NI1oZdcIUZsL65O3r4nkUzXr086137B11RdYreXc/XRV3TmbcICfFrxAblYq109+y6FeDADpBcWYPKsankyebhw+l3XRvOdyCzmXW0i3cFtvLE3XeWfDfqaP6snOM2kXXac2irs3Wn5Vjwg9PwdD8MV7bSmevqje/ljPxtdIc2rZmbK9NRuAhBBCCCEu9Jee+LHf8Ft4+b0VXDfhcVb9YLtZSTx5GFVVef2jdUx7fwXrf/mSzLSzf+r3UBWIaGJg6ZZS3vm2GH8vle6tL0/7jKZpfPvZO9w8ccpl2V599R12Cy/NWcHoWx9n9Y/z7dLOxB/E2bkRTcKjL3vc/sPHM+295Vw34TFWVhzbMxXHdvpHa3nl/RWs/+ULMtOS69iSY6yaRlK6mU+euIu3Jt3Aq1//Ql5RMd9t2k2fdtGYfOtuzPgjLJpGYmYOn9w/jrcmDOeVJevJKy4lKTOH0+nZrJ56N2um3s2uk8nsPVX7U836slo1ks5n8tFz9/PG/RN4/bMl5BcWV6Zn5OTx0vzFTJt0k0NDFupjwIjxvP7BMsbe9igrltiGLPQaNAYffxNvPnMr3302i4iWHS973KuGTuCpt1cz/OYnWP/feQCs+/ED+gy/E5dG7pc1FkDPHt348rNP+OiD9+jSuROz3vn3ZY9xKW3DFYL9FHaesG+UWLBaY95yjfZNFdwc61DgkN7dOvH9R+/wxbvTienYlulzbOet1WrlwLE4HrzzFj6e+Qrn0jJYsWHzZYmpaRqLP32H8RMfrzVPSlIC33/xHnfe//xlifm7HkMmMGXWaq6+8Qk2/jKvcnlYZEceeWMZ/3r5O35b9jHlZaWX2Mofs+p4EoNbhmKoOEe+23eSPhGNMXk61tvpj3Jq2RlL/IEa4wEVN09U/8ZYEo//qfGFEEKIvyod5W/5r6Fc8le+oih7FUWZqihKvfqRK4oyWVGUWEVRYpcv+aRGuo9fENlZ5ys/52Sl4eNnqpHvd116jeDgblt31tgtv9K6Ux8MRic8vf2JaNmJJAe6XecW6vh6VO1oHw+F3ALHJlbIKdBJybQNtdB0OHTKQmigYzdIPn6BmDOrypqdlY6Pf9VcASXFhaQkJTBz6r08PfkaEuIOMeeNxzhz8qhD26+Nt18QORfsY2/fS+/jQ7vtuwzv3baCLr1H1jOuieysqidt2VlpePsF1Zq/a68RlcMpYrcsp02n3tWObWeHjm2Qjxfns6sGradl5xHk42WXx+TrRf8OLXEyGAgJ8KVpkD9J6WYOnErm2w27GPH8u7y7ZDXLdhzgPz+ucaisQV4enM+pGmqQnluAydv+Ztbk7cGAthE4GQyE+nnTNNCHpMwc1h9OoH14MG4uzri5ONO7VVMOJJ6/MMTF4/p6kWauejKZZs4l8IJGEpOfN/07t8XJaCAk0I/w4ECS0my9GwqKS3j0nU954IbhtI9yfB4KX78gsjPt65TvJY5tTO/h7K8YTmEwGLlp4lNMnf0dDzz7b4oL8wlq7FhsL98gcs1VcfPMl67LHXqO5OiedYBtqMWKxbOZ8fhgtq76ko2/zGfbmm/qjBng709GZmbl54zMzMoJHiu/l5cXzk62+VtGXD2U+JM1n/zXV0ExlcMfwNYzIb+4Zr5mQdCrjcKSLVrlEAm77ZRARp6Oo8P3A/19Sc+qeqqekWUmsGKCx995e3pWlnf0kAGcOHWmYl0/opuFExIchNFgoG/3rpVpdfH1C8KcWXW9MGel29WpkuIiUpISeGvqv3jy3tEkxB1mzvQpnK64Ppoz03jvrae497FXCGpc93wmULM+5Wan4XmJ+tS+x0iO7V1XY3lQk0icG7mRnlLzqf/FBHm4klbtYKblFxHoefEhNauOJTG8ddX5cTAlk2/3nmTkvF94d+N+lh05w382HXAorl6Yi+pZ1fNJ8fRBK8y9aF6nFp0uPlSiRScsCYdsY3KEEEIIIepQ152yL+ADbFAUZZeiKI8ritKkro3quj5f1/UYXddjRt5Q8+0A4ZHtyEhNJDM9GYulnD3bVtA+ZoBdnvTUxMq/j+z9jcDGtrGpvgGNiTtsGxtdWlLEmfiDmEKa1/WVSErTCPBR8fNSMKjQuYWRw6etda4HkJSu4eoC7rZh9USHGkgzO9ZA0Ty6LWmpZ8lIS8FSXs6uLavo1K1/Zbqbuyf/+XI9M+f/ysz5vxLZoj2PPP9vmkW1cWj7tQmPbEfG+USyKvbx3m0raHeJfXx0X9U+BtsTxP3bV9Ol1/B6xW0a2dbu2O7dtpIODh5bv4DGnDi8C6jfsW3brAlJ6VmkZGZTbrGwKvYw/Tu2tMszsGMrYuPOAJBdUEhiehahAb68ec/1rHxrCiveeJzHb7iaUT078ug4x2aLbxtmIikzh2RzLuUWKyv3x9O/jf2EdYPaRhCbYOuNkV1YTGJGDqF+XgT7eLLnVAoWq0a51cqeUyk0N/leLEwNbZqHcTYtk5QMM+UWC6t37qd/Z/v6MqBLW2KP2256s/MLSTqfQUiQH+UWC0/O+YJRvbsypFsHh+L9rmlUW9JTk8isqMu7t66iQ7W6DJBW7dge3ruZoGDbsS0rLbbNrQIcPbAd1WC0mzDyUkIj2pN5PhFzejIWSxkHdiyndZeBdnkyz5+p/PvE/k0EVHQH/9eLX/PMu+t45t119B52BwNGT6bX0Al1xmzZIpqUlHOknj9PeXk5m37bzFU9etjlyTKbK//evnMX4WGO3eReyjkz+HqAt7vtDRGtwxXiz9lfa0w+MDxGZckWjaJqD9E9XcFosP3dyAnCAhTM+Y7FbRUVwdnUNM6lZVBebmHtlh307tbZLk9mtYatLbv30jTE9l9B66gI8guLyM61NfTtPXSUZmGXnqz1d82j25Bud31cTefu/SrT3dw9eO+rdcz++Bdmf/wLkS3a8cgL79A8qg1FBfn8+/XHuOH2h4hu7fgbUkKatycrLZHsDFt9OrRzOa0629enrGr1Ke7AJvxNtvqUnZGM1WqbkCcnM4XM1FP4BDhW1raN/UjKziclp4Byq5VVx5IYEFVz3dNZeeSVlNGxSVWj1hujr2LF/aNZft9oHh/QiVFtm/Fo/44OxbWeP4vqE4ji5QeqAacWnS/6dgjVNwilkRvW1DM10owtu1y08UEIIYQQ4mLq6vOfrev6k8CTiqL0BW4B9iqKcgxYpOv6/EuvfnEGg5Eb736eudPvQ9es9Bw4lsZhUfz67fuER7alfcxAflu5iBOHdmAwGHHz8OL2B6cDtiEUX8+dyvQpY0DX6TFwDCFNW9YRETQdfthUyn3XuqKqsPNoOefNGiN6OJOUbuXIaSthQSr3XNMIVxeFts2MDO+hMWNhMboO/91SxoNjbU+dkjM0th9xbPIrg8HIhHuf4d1XHkTTNPoMvpaQ8Eh+XvghzaLa0Kl7/0uu//TkayguLsRqKWffro1MeXlujTdT1Bb3+ruf58M37rO9wnKAbR8v/+59wiJs+3jzqkXEVexjV3cvJjwwvXL9hGN78PEPJsAU5lA5q8e96e7n+WD6/RXHdgyNw6JY9u0HhEe2oUPFsT1+aGflsb3jwdcB6Dd8PF/PfZHXp4wFXafnwOsIadqizphGg4Fnx4/k/v98habpXNe7M1FNgpi7dD1tmjZhQMdW9GobxfajCYyb9j6qovL49UPxcXCixdrjqjw3ZgD3f/xfNE1jTPe2RAX788GqHbQNDWJA2wh6tWzKtrgkxs76ClVVeXxUH3zcXRnaIYpdJ5O54Z1vUIBeLZsyoE3dx/X38j59+xgemvUxVk3jun7diQwN5sMfV9GmWSj9u7TlqvYt2XE4jhuem4Wqqjx68yh8PNxZvnUPe0+cIregkF+27AZg2qSbadm07hslg8HIzZOeZc7r99teTzroOpqERbF08VyaRrahY7cBbFyxmOMHd2IwGnFz9+Kuh18FIC/XzHuvP4CiqPj4BTHxkdcd3s8Gg5Fr75jKp7MmoWsaMf3GYQqNZs0Pcwhp3o42XQaxfc1CTh7ZhsHghKu7FzdOftPh7V88poGH7v8Xz784DU3TGDZ0CM2ahvPFV9/QIjqKq3r24Oelv7Bj5y4MBgOeHp48+fhjletPefpZzp5NprikhFvvmMiURx8mpmuXOuPqOqzZqzG+n4qiwMHTOpl50LetQmq2zslzMLCjirMRxl5layPOK4IlWzX8vWBwR9srdhVg5wmdjIs/sK7BaDAwZdIdTHl1Jpqmc83gfkSEh/LJoh9oFdmcPt27sGT5arbs3odBVfHy9OCFh++t2FcqD915C49Nm4Gu67SMbMa1QwY4uJ+NTLj3Kd5+5WE0q5W+Q2zXx58WzqNZVGs6X+L6uHb5t6SlnmXpt5+w9Ftbj7knp72Pl8+l5zYxGIyMum0qX8yehKZpdOk7DlNINOt+nEOT5u1o3XkQO9YtJKFafRp3r60+Jcbt4bdfP8ZgcEJRFUbd/hLuno41DhpVlWeGdOGB7zeh6TrXtY8gMsCbuZsP0SbYjwHRtnNw1bEkhrUOd/h1tnXSNUo2/Ijb2MkoikrZkV1o5jRceg7Hmn4Wyylbb7HaJnxUvHxRPX2wJv/vPXWEEEII8c+g6JeYvVBRlL26rne5YJkBGArcrOv6xLoCrD5Q5viL2i+T5b/VPcP4n+GGwQ0z7qWgrOYrN68Eg3LFDy0AfbJ/vOIxlTxz3Zn+BJag+jXyXC673R3rzXG5ZRdfxkkEHNTVz7Hu7pfbwr2Ov+3icprUNrZB4sar/1vvrD8iOefyz8XhiFFHpzVIXIuDb4r5M3g99k6DxRZCCPGX0HATAFwBW486OM7+L6Z3G48GOS519WSIu3CBrutWYGXFPyGEEEIIIYQQQgigjjkZdF0fX1uaoih19mIQQgghhBBCCCHEP8f/8g65Vy7btxBCCCGEEEIIIf6CGvpVlH+3V1hecriEoigHa0sCan/nlxBCCCGEEEIIIf5x6pqTwQQMA7IvWK4A2/6UbySEEEIIIYQQQoi/pboaGZYBHrqu778wQVGUjX/KNxJCCCGEEEIIIcTf0iUbGXRdv+cSabde/q8jhBBCCCGEEEL8dWh/yxdYNpz/ZeJHIYQQQgghhBBC/E0pijJcUZQTiqKcVBTl2Uvku15RFF1RlJi6timNDEIIIYQQQgghxD+MoigG4ANgBNAGuEVRlDYXyecJPArsdGS70sgghBBCCCGEEELUoqFfRfknvsKyO3BS1/VTuq6XAYuB6y6S7zVgBlDiyEalkUEIIYQQQgghhPh/RlGUyYqixFb7N/mCLCHA2WqfkyuWVd9GFyBM1/VfHY1b19sl/mdfLM74s0PUcPb46SseEyD5ZJMGiWu1WhskbtuYpg0Sd7frTVc8ptlcesVjAqRsyWyQuM/cW9AgcXOKna94zG8PRF/xmAD92hU1SNxvz3RvkLgH9puveMyJY694SAB29XiuQeKeNbs2SFxF0WHzlZ8R67a+Dj2hEUIIIf6xdF2fD8z/o+sriqIC7wB31Wc96ckghBBCCCGEEEL886QAYdU+h1Ys+50n0A7YqCjKGaAnsLSuyR//9J4MQgghhBBCCCHE35Wu/7/tPbcbiFYUpTm2xoXxwK2/J+q6ngsE/P5ZUZSNwJO6rsdeaqPSk0EIIYQQQgghhPiH0XXdAjwErAKOAd/pun5EUZRXFUW59o9uV3oyCCGEEEIIIYQQ/0C6ri8Hll+w7KVa8g5wZJvSk0EIIYQQQgghhBCXhfRkEEIIIYQQQgghaqFf+Zco/a1JTwYhhBBCCCGEEEJcFtLIIIQQQgghhBBCiMtChksIIYQQQgghhBC10Ph/+wrLP4X0ZBBCCCGEEEIIIcRl0WA9GTq0cOH2Ud6oqsLG3YX8sqnALr1VM2duG+VNeLAT7y82s+twSWVa3y5ujBnoCcDPG/LZvLfIoZjdO/vwyD0RqKrCr2vT+ObHZLt0J6PCC4+2oEWkB3n5FqbNPs75jFK8PI28+lQrWkV5snJDGv/++FS9ytqplSsTx/mjqgrrduTx89pcu3SjAR6+LYiIMBcKCq2880U6GWYLBhXuvyWQ5qEuGFTYtLuAn9bmOBy3c2s37rkhEFWFtdvy+HFNtn1co8Kjt5uIDHchv1Bj9qepZJgt9IvxZMwQ38p8TZs488SMJM6klDkUNzpEYWR3I6oCe+Kt/HZIs0vv1UYlpoUBTdMpLIGftlrIKaz4zpEq/TsaANh0wMq+BO3CzV9URDAM7ayiKHDglM724/azs3RvodApQkHToagUlu3SyCsCLze4oY+KAqgqxMbr7EtwfGaXlmEq1/VxRlVg5zELG/ZZ7L9XY5VrezvT2F/hmzVlHDxlrUy7pqfCcaD5AAAgAElEQVQTrZsaUBSIO2vlv1vLHY7bsUUj7rjOF1WBDbsKWboxzy69VXMX7rjWl/BgJ+YszGTXoeLKtH5d3Rkz2AuAn9fl8dueQofj7t+zg8/n/wdN0xh09SjG3Hj7RfPt3LqRd96cyhvvfkJkdCvS01KZcv8EmoSEAxDdsi33PvSUQzFPHNzML1+9ia5Z6TbgBgaMvtcufce6xWxfuwhVVXFu5M64u6dhConCnJHCO8+MIrBxMwDCozoyduI0h8uaHLeZHcveQNM0Wna7gY797eMe2vI5cbuXoBgMNHLzo+/1r+PpG1KZXlZSwA//HkXTNoPpde2LDsc9tHcbCxfMRtes9B0yhmuun3jRfLHb1zF35tO8OOsrmke1oSAvh7mznub0yaP0Hjia2yY/43BMgMRjm/ntp+noukabHjcQM2SyXfq+jZ9xZMcSVNWAq4cfg8dPx8svhOT4HWz++a3KfNnppxh2xztEth/iUNy2EU6MH+qOqsDmAyWs3F5ilx4dZuTmoe6EBhmY/3MBe4/brkN+XioP3OCJqoBBhfWxJWzaV+pQzEN7t7Hwk9lomka/oWO45vq7Lpovdts6Ppj5DC/N/rJyH38w8xnbPh40itvruY8P79vKd5/ORNM0+gwey/Bxd9ulb1r1PRtXfouqqrg0cuO2+16kSVgklvJyvv7oNRITjqIqKjfd/RQt23VzOG7C4d9YtXg6uqbRqe+N9B5hf2z3bFxE7MaFqIqKUyM3rrn9NQKbRFFUkM0P8x7h3JnDdOw1luG3XvRtVrU6eXgzqxbZ4nbuewO9R14YdzG7N3yDqhpwdnHjmjterYy75MNHK+KOYcSE+sUVQgghRMNqkEYGRYG7rvXhzQWZmPOsvPZgEHuPlZCSXnWDlplj5aMl2VzT19NuXXdXhXGDPZn6fjq6DtMfDmLP0WKKSi59Y6iq8PjkSKZMO0xGVhnzZ3Ziy64sEpOrbr6uGWIiv9DCrQ/sYVCfAO67oxnT3j5BWZnGgkVJNA93IyLcrV5lVRWYdGMAr85NxZxj4a0nQog9VERyWtUN5eCrvCgs1nj49bP07uzObaP9ePeLdK7q7I6TUeGJGck4Oyn8+7lQtuwtIMNsuUTEqriTbwpk2vspZOVYmPlUOLsOFZJ8vqqhYEhF3AdeSaRPVw/uuC6Atz87z2+x+fwWmw9AeBNnnru3scMNDIoCo3sY+Wx1OXlFcN8oI8eSNDKqtaukmnU+/KWccit0b6kyLMbAt5usuDrDwE4GPvylHB14YLQTx85qlNQRWlFgWFeVRRs18oph4lCV+HM6mdXuu9NydD5do2OxQpdIhUEdFX7erlNQAl+s1bBq4GSEe4erxKfYljtS1rF9nZn/Sym5hTqPXt+Io2espGVX1cXsAp1v15fSv5OT3bpNTSrNglXe/s4W6MExLkQ2UUk4V3ejiqLAxLG+vPFxOlm5VqY/HMyeo0UXnD8W5n2bxTX9vezWdXdVGTfEmxfmnAd0pj/SmD1HiygsrrthRbNa+fTDd3jh9Xfx9w/iuccnEdOjD6Hhze3yFRcVsXzp90S1bGO33BQcwsz3Pq8zjl1Mzcp/v3ide575BG8/E++/dDOtuwzEFBJVmadTr1H0HDwegKN71/PrNzO5++n5APgHhfHo9J/qFfP3uNuWvsbwuxfg7mVi6dybCG81EF9TVVz/xq257sHvMTq7cmzHInavnM2gW96tTN+zZg7BzWLqF9dq5ev5b/HEtLn4+Zt49enb6dS9PyFhEXb5iosLWbtsEREt2lUuc3J2Ycwt95OSlEBKUkK9y7vxh1cZc9+nePiY+PbdG4loNwi/4KryBoa05uYpS3ByduXQ1kVs/WU2I+58l9Dontzy1M8AlBTm8OUbwwhv2duhuIoCtw5z591FeWTnabww0ZsD8eWkZlY1xpnzND77pYBhPV3t1s0t0Hjri1wsVnBxgmn3+rA/vozcgkvXZc1q5auPZvDkKx/Y9vFTd9Cpe7+L7uM1yxbX2Mdjb72flKSTJNd3H1utLPr4TR57aR6+/ibefGYCHbr1p0lYZGWe7n1H0H/YjQAc2L2R7z9/m0dfnMvmtT8A8PK7S8jLNfPe6w/y3IxvUNW6OyNqmpUVC19lwuOf4eVrYsH0G2jRcRCBTaqObbseo+k64BYA4vavY813b3LrYwswOrnQ/7pHyUiJJ+NcfP3Kq1lZ+c2rTJjyKV6+Jj55/UZadLow7ii6DrCduyf2r2fNt29x6+OfYHRyYcAYW9z0lLh6xRVCCCFEw2uQ4RKRYc6kZVnIyLZitcKOA0V0bd3ILk9mjpWz5y3oF7wvpEOLRhyKL6WwWKeoROdQfCkdW9qvezGtoz1JSS0hNa0Ui0Vn3ZYM+nT3t8vTp7s/KzekA7BpWyZdOvgAUFKqcehYHmVljj1Vry6qqQvnM8pJz7JgscLWvYV0a+9ul6dbOzc27rLd1G8/UEj7FrYf07oOLs4KqgrOTgoWq05xiWPfIbpZI1Izy0mriLtlbz7dO9jH7d7BnQ07bXfi2/YV0KFlzQaUvl092bK3oMby2oQGKGTl62QXgFWDQ6c1WofbV7PT53XKK+4hzmboeLnZxjhFh9husovLoKQMEs5ptAipu4o28YPsfMgpBE2Do0k60SH246YS08FSETMlS8ezIqam2b4ngFGlXqOtwoNUsnJ1zPk6Vg32n7TQtpnBLk92vk6qWb/oa2+cjAoG1daTxaBCfpFjPSiiwpw5n2kh3Ww7f7YfKCKmrf2xy8y2knS+vMb507FlIw7FF1NYrFFYrHMovpiOLe1v3mpzMu4YpsahmIJDMDo50avfEHbv2FIj37dff8x1N0zA2cnZoe1eytmEQ/ibwvEPCsNodKZjzxEc3bPeLk8jV4/Kv8tKi+t3EGuRkXwQL/9wvPzCMBidiegwkqRj9nGbRPbA6Gzbd4HhHSnMTatMy0w5QnFBJiHRjt1s/+5U/BGCGocRFByK0cmJHn2uZv+ujTXy/bTwQ0aMvRMnJ5fKZS6NXGnRpjNOzvXf72lJB/EJCMc7wFbeFp1HcurwOrs8odE9caoob3DTjhTmnK+xnZMHVtG0Vd/KfHVp3sRIRraVzBxbQ9/uo6V0irZvkMvK1UjJsNaoy1at6pw2GhUUB4/7hfu4e5+r2bdzU418P30zj5Hj7sSpWj227eNOdvvdUadPHiYoOIzAirgxfYZxYPdGuzyublV1ubSkGKWiUKnJp2jVrjsAXt5+uLp7kphwxKG4504fxC+wKb6BtmPbtts1xO23P7YuF5xDv8d1dnEjPDoG4x8o77nTB/ENCq+K230kJy4Rt7y0COzidsV4Ga4hQgghxOWg68rf8l9DaZBGBj8vlazc6k+qrPh6Gy6xRhVfLwPmC9f1qnvdAD9n0jOrutJmZJUS6G//AybAvyqPVYPCIgvenv9bZw8/byOZOVVPmLNyLPhdUFY/HyOZ2bY8mgZFJRqe7io79hdSWqbz8WtNmTctnKXrcykocqyRwc+7apsAWdkW/L3ty+LvfUHcYiue7vZVok8XDzZX9GpwhJcb5BZW3QzkFVLZiHAxXaNV4lNsZfK8YN3cQh1PBzqOeLpCXrUn8flFtmW16RihcCq1Kr+nK0wapvLQaJUdxx3rxQDg7a6QU+375hTqeLs7djInpmmcTLHy8p2uvHSHKyfOaqTnONbI4OttsDt/snItDp0DUHH+5FQ7f3IdO38AzFkZ+AcGVX72DwgkOyvDLs+pkyfIykynS7deNdbPSEvlmUcmMu3Zhzh2+IBDMfOy0/D2C6787O0XTF52eo1829csZOYTw1ix+G2uvf35qu+ckcJ/po7jo9fv4PSJWIdiAhTlpuPuXRXXzdtEYV5arfnjYn8gtEVfAHRNY+fyGfQY+bTD8X6XY07HL8BU+dnX31RjHycmHCM7M42OMX3rvf3aFOak4eHTuPKzh3cwBbm1l/fIziU0bd2vxvL4fctp0eUah+P6eKqY86quadn5Gj6ejtVHAF9PlZcneTPjIV9W7iiusxcDQPYF+9jPP4hss32dOpNwHHPmeTrG9HH4u9Qlx5yOb0BVnfL1M5GTVbMub1ixmBceGMWPX/2bm++21aHQpi04ELsRq9VCZloKSQlHyc6s/fhUl5+Thle1c8jT10R+Ts11Yzd8w/vPD2HdD7MYNn5qfYtXQ152Gl6+VXXKyzeY/OyacXev/4b3nxvKuiWzGXbLC/9zXCGEEEI0PJn48S8sqqkLmqYz+cVEHng1idEDvQnyv3IjXKKbulBarpOU6thQifrqGKESEqCw+XD9e4j8UW2bKjT2U9hRbc6G/GL4ZJXGh79qtG+m4F7/h3b15u+lYPJVee3LYl77spioEJXmjf/ep6OmaXz1yXvcfs9DNdJ8/fz54LMfmDHnM+6Y9BDvzX6FoiLH54Koy1VDb+Xpt1cx4uYprP/vRwB4+QTy7L/X8ejrP3LNhGdYPPdpSood75XjqJP7lpKZcpgO/e4B4NjORYS17GfXSHG5aJrG4s/e5eaJj1/2bTvqeOxS0s8eocuge+yWF+amk5kaR3iry3djXpfsfI1XPsnlhQ+z6dW+EZ4ONvJdiqZpLP70HcY30D4eOGI80+cuY9ztj7L8h48B6D14DL7+Jt54+la++2wWkS07OjRUoj5iBk7goTfWMvj6J9n864eXdduX0m3QBB56cw2DbniCLcuuXFwhhBBC/Hku+StFUZQYRVE2KIrytaIoYYqirFEUJVdRlN2KonS+xHqTFUWJVRQl9uT+r2ukm/M0/Ks9zffzMpBd7cnspWTnWe16Avh5GcjOq3vdTHMZQQFVd4+B/i5kZNnfPGdmVeUxqODuZiQ3v+75Dy7FnGshwKeqYcDfx2jXEwPAnGMhwNeWR1XBrZFKfqFG364e7DtWjFWDvAKNE6dLiQxz7A7YnFu1TQB/XyNZufZlycq9IK6rgfzCqhv+Pl0969WLASCvCLun+V7ukHeRYQCRjRX6dzDw9TpL5XCF/AvW9XZXyHdgTs/8YvByrVrP08227ELNTNC7jcL3m7XKmNUVlEBGrk5YYN0xwdbTwqfa9/VxV+x6YlxK+wgDiWlWyixQZoETSVaamhy7acjOtdqdP/7eRofOAag4f3yqnT/ejp0/AH7+gWRlVD15zcrMwNe/ameVFBdxNuk0rz73MA/dfQPxJ44y67VnSIg/jpOTM55e3gBERLXCFNyE1JSzdcb08jWRa67qlp9rPo+Xb1Ct+Tv0HMmRPbYu2UYnZ9w9bUOeQpu3xS8ojMzUMw6V1c07iMLcqrhFuWm4e5lq5Es5uY39Gz9i6O1zMRhtPaPSk/ZzdPtCvp05mF0rZnJy33/ZvfJth+L6+AVhrvaEOjsr7YJ9XEhK0klmTJ3MU5NHkRB3iDlvPM7pk0cd2n5t3H1MFOSkVn4uyD2Ph3fN8iad2EbsmnmMuqeqvL+L37+SyPZDMBicaqxXm5x8DT+vqnrv66mSk+9Yfawut0AnJcNCdFjdsX0v2MfmrHR8/arqVElxESlJCbw19V88ee9oEuIOM2f6lP95H/v4BZGdWVWnss1p+PjXXpdjeg+vHCpjMBi5aeJTvPj2dzzw7L8pKsonqElTh+J6+pjIq3YO5Wen4elT89j+zjacYq1D274UL18TedlVdSov+zyevrXHbdftmhrDKYQQQgjx91TXXc1cYCbwK7AN+EjXdW/g2Yq0i9J1fb6u6zG6rsdEdbqtRvqp5DKCA4wE+howGKBnRzf2HHOsj/rBuBLaR7vg1kjBrZFC+2gXDsbVve7x+HxCG7vSOMgFo1FhcJ9Atu422+XZutvM8IG2H339ewWw95Djb3KozcmkUhoHOhHkZ8RogN5d3Nl92P4JbuzhIgZ0t01weVVHdw7H2+6QM7MttKuYn8HFWSG6mQvn0h17A0F8YgmNA50J8rfF7dPFk90H7ePuPlTIwB62iQF7dfbgUFzVHb2iQO8unmzZU79GhpRMHX8vBV8PW0NN++Yqx8/a33g39lO47ioj36wrp7DaoYtP0YhqotLIGRo5Q1STqqEUl3LODL6e4O1uayxpE64Qn2If0+QDI2JUvt+sUVRtAnpPV9ucCACNnCA0UCHLwSKfTdcI8FHw87TNrdApysiRMw7e7OfrRDQxoCq27xzRxEB6tmMNFAnJZQQHOFWeP1d1dGPP0Yu0qlzEgRMldGjhirurgrurQocWrhw44di5F9miFefPnSX9/Dks5eVs+20tMT2q5hxwc/fgk4W/8v6nS3j/0yVEt2zDUy/OIDK6FXm52WhW275JO59C6rlkTMFN6owZGtGOrPOJmNOTsVjKOLBjBW26DLTLk3n+TOXfx/dvIiDYdvNVkGdG02wxs9LPkpWWiF9QqENlDQxpT15mIvnmZKyWMk4dXE546wvinjvK1p+nMfT2D3D1qJrfZcDNsxj/zHpufnod3Uc8TVTn6+g2/AmH4jaPbkNa6lky0lKwlJezc8tqOnXrX5nu5u7JnC/XM2v+MmbNX0Zki/Y88vy7NI9qc4mt1s0U1p6cjERys2zljdu3nOZtB9nlyUg+yobvX2bUpLm4efrX2Ebcvl/rNVQC4Mw5C0G+BgK8VQwqdGvjwoF4x65xvp4qThXtqG6NFKJDnUjLqvv8ax7dhvRq+3jXltV07l419MPN3YP3vlrH7I9/YfbHvxDZoh2PvPDO/7yPm0W1JT01icyKuLFbVtExpr9dnrRziZV/H9qzmaDGtrexlJUWU1piO8ePHtiOqhrtJoy8lCbN2mNOP0N2xlmsljKO7P6VFh3tj6057Uzl3/GHNuIX5FgDRp1x0xLJzrDVqSO7lteIm1U97sHLE1cIIYT4M+j63/NfQ6mr772TrusrABRFmaHr+hIAXdfXKYoy+48G1TT4fGkOz9wdgKrApthC/o+9+w6PotobOP6d2d30bMom2XQgIQECSO+9CKgockFFULxIEa5eO/aOFxv2BsJFvSpYQBRBmvQWeock1JCeTdlserI78/6xMZs1hCwayfW+5/M8PrI5Z/Y37czOnDYZuVbGDfflfEY1B09VEBOp46E7DHh5SnRp58m44TYefyeX0nKVHzYVM+c+e2XAik3FLs2Mb1PgnYVnmfd8B2QZft6Yw4W0Mu6+PZrkMyXs3FfA6l+yefrBNiz5qBvFJVZeeDOpdvlvFnTH21ODVivTv6eBR1487vRmistt66LleTwzKxRZltiUWEx6djW3XRfA2bRK9h8vY2NiMfffEcz7z0RRUmbj7c/trcVrt1u4d2Iwbz8RCRJs3lNMaqZrQxcUBRZ+m8vz90YgS7Ax0UJadhW33xDImYuV7DtWyi+7LDw42chHz7egpFThzU8drU4JrT3JK7RPHHklFBVWJVq561qd/RWWZ2zkmlWGddaQka+QlKYyqrsGNx1MGGI//cwl8NUmK+VVsPmIjVmj7a2Rm4/YKHdhc1UV1h9UmDBIRq55hWWeBQZ2kMgqUDmdCUM7ybhp4W997fVqRWWwbIeCQQ/DO8uo2OcL3JOkOr0Jo7FtXbG9iumj3ZEk2JdkJadQZWQPHWkmhZMXbEQFy9w1yg0vd4mElhpG9FCZ900FR8/ZaB0h88htHqBCUpqNk6muVVAoCnz2YwFPTgtBlmHLvlLSc6oZP8KP8+lVHDhZTkykGw9PDsLbS6ZrO09uudbG7LeyKS1XWPFLES//096V//tfiigtd224ikaj5e6ZDzP3uYdRFIXB195AVIsYvv1yETFxbeneq+Fu8qeOH+Hbrxah0WiRZJnp9z6Kj6++wfx1Y940+WkWvzEdRVHoPnAsxsg41i9/n8hW7UnoOpRdG5Zw5sRuNBotnt5+3DpjLgDnk/ezYfn79piSzM1/fx4vH3+XtlXWaOlz0zOs/XQaqqoQ3+1vBBjjOLDhPYIiO9Ci3VD2rXmD6soyNi21d6v38Qvj2skN1r26RKPRcsf0x3jrxftQFBv9h40hIjqWFUs+pmXrBLr0HHTZ5WfPGE1FeSlWazWH9m7h4ec/rPfWhIa2d9C4Z1m5YCqKopDQaxyGsDgS17xHSFQHYjoMZcdK+/au+exBAHwDwhg9zd693VKQTok5i4jYnle0vYoKS9aX8uAEPZIMO49Ukpln46aBnqRmWTlyupqWYRr+Mc4XLw+Za1q7MWaAJ88vLCLUoOHW4b6oqr1SdN2ecjJMjZchjUbLpOmzefPFf6LYbAwYflPNPp5Py9btGt3Hj06/0bGP92zlkRc+cGkfazRaJkx7gnfnzEJRFPoNHUN4dGtWLv2IFq0T6NRjMFvWfM2po3vQaLV4eeuZct9LAFiKCnhvzj+QJBn/wBDuvv9l13Yw9mM7auJzLH1nGopqo3O/cQRHxLHlx3cJb9GB+M7D2Lf5S86ftJchD289N015rXb5958YSmV5CTZbNcmHfmHiQ4ud3hBx+bjPsuSdqaiKQqd+4wiJiGPLD+8R1rIDbToPZf+mrzh3qiaul56b7na8CvW9x4dSWV5qj3t4I5Me+rdLcQVBEARBaH7Sb2fsdkqUpN3A84AfMA94QFXVHyRJGgS8qapqo+9nm/RkxlWvQ0lLOn+1QwIQEt14y+yfwWa78u7FTaF99+ZpdfLydH1iuKZSUFDZeKY/Qcb5vGaJ+/h0194O0NTOFwZe9Zin05pn5t1+7VwYC/QnOHTBu/FMf4Ijhwsaz9TEpoxtnrcTVNma5e3QpBU0T7mVpOZpKrljQPPNmi0IgiDU8z99Ud5wpLIZ+wX8ftd2cm+W49LYndBM7MMlFGAkMEuSpM+ADGD6n7tqgiAIgiAIgiAIgtC81P/tOpQmd9k5GVRVPaKq6khVVa9TVTVJVdUHVFX1V1W1PdDmKq2jIAiCIAiCIAiCIAh/AX/kHVgvNtlaCIIgCIIgCIIgCILwl3fZ4RKSJB1tKAlo+F1UgiAIgiAIgiAIgiD8v9PYnAxG7HMxFP7m7xL2V1oKgiAIgiAIgiAIwv8s5S857WPzaaySYRXgo6rq4d8mSJK05U9ZI0EQBEEQBEEQBEEQ/pIuW8mgqurUy6RNbPrVEQRBEARBEARBEAThr6p5XuYtCIIgCIIgCIIgCH8BqipeYXkl/sjbJQRBEARBEARBEARBEGqJSgZBEARBEARBEARBEJrEnz5cIi/T9GeHqMdT74NWd/VHguRcyLjqMQG07m7NEjcqPK5Z4o6MSbnqMc1qwFWPCbA1KapZ4p7Ob54pdG/M+eiqxzxlnXXVYwIcS/NplrgVFUqzxFVsVz+uVmqebW3z/QPNErdXq+hmiWuL73TVY253G8WaQ1c9LADXddE1T2BBEARB+Iv4n5yToTkqGARBEARBEARBEIT/Pap4heUVEcMlBEEQBEEQBEEQBEFoEqKSQRAEQRAEQRAEQRCEJiEqGQRBEARBEARBEARBaBJi8gJBEARBEARBEARBaICC1Nyr8JciejIIgiAIgiAIgiAIgtAkRCWDIAiCIAiCIAiCIAhNQgyXEARBEARBEARBEIQGiFdYXhnRk0EQBEEQBEEQBEEQhCYhKhkEQRAEQRAEQRAEQWgSopJBEARBEARBEARBEIQm0WxzMnTv6MvMSRFoZIk1W/P5dnWuU7pOKzF7RjRxLb2wlFiZ+1EqOXlVtenBgToWvtKWL3/IZtkak0sxu7X3YcbtYcgyrN9eyHdr8pzStVqJR6ZG0rqFB8UlNl5dkEZufjUhBh3z58SRkV0JQNK5cj78MtPlbe3ZJYAHpscgyxKrNmTz1fL0etv69ENtaBPrg6W4muffSCI7txK9r5Y5j7ejbWtf1mzK4Z1PzrocE6BHJz/um9ICjSyxemMuS3/Mqhf3yftiiY/xxlJs5cV3TpNjqqJbRz0zJkWj1UpYrSrzv7jIoRMWl+OeP7mNLcv/haIodOxzCz1HzHBKP7DpU47t/g5Z1uDpE8jISXPRB0YAsO2H1zl/YiuqqhDdth9Dxj2NJDX+yph9+w8w/5OF2BSF60Zcy2233uKUvn7DLyxa/CkGgwGAm268getGjgTgqWefJyk5mfYJ7ZjzwvMubyfA4QOJfPbJuyiKwtARo7n5ljsvmW/Pzi289cozzH17EbFxbcnNyeLhWZMIj4gGIK5Ne6bfN9vluBeTtrPjR/s+Tug1nq5Dnffx4a2fcmrPMiSNBk/vQIbe+i98a/ZxcWEmm797hhJzNhISN0xbgD4w0qW4KUe38/NXc1EUhW6DxjNo9HSn9L2bvmbPxiVIsgY3dy9unvIiIRGtST97lB8+q9m3qsrQm+8lofu1LsXcmZzKaz9uQ1FVxvZMYOqQ7vXyrDtymvkb9oAk0SYsiFcn2o/t2z/vZPupCwDMGNaDUZ3jXYoJEBMK13aRkSQ4ck5ld5LzYLye8RKdYyQUFcoqYdVeBUsZ6L1gfH8ZCZBl2H9a5dBZ1wfyXTi5jS3f249thz630PPa+uXn+O7vkDX28jNiYp3y86O9/KAqRLfpx2AXyw9AWvJ2dq+ai6ootOkxns6DnY/t0e2fkbx/GbKswcM7kIHjXsY3IKI2vaqihGVvj6ZFwjD6jXnW5e3tEKvj9pE+SJLE9kPlrNlV7pQeH61jwghvIo1aFnxv4cAp+++AwU/m3lv0SJKERgMb95az9WCFSzGPHtzNFwvfRFEUBl87hhvH33XJfPt2beK9157gxXmfEROXwNmUEyz+aC4AqqrytwnT6d5niMvbqottj/fI20CWqTi0g4qda53SZX0gPjdPQXL3BFmmbOP3VJ85DoBHv1F4dOkPikLpuq+pPnvS5bg7z2bw+rr99jLUuTV39+vglP7G+n3sS80BoKLaSkFpBTtmTyDTXMLDy7aiqCpWm8LtPdpySzfXy9Cuo0nM+/JHbIrCzYN6MeXGofXyrN9zmE9WrEeSJOKiwpn7j0kA3PfGQo6dTaVzXCvefWSqy3PqG3IAACAASURBVDFPHd7B95+/iqrY6D10HMPHTHPeFxu+Ycf6r5FkGXcPL26b/gKhkbHs37GKTT99Wpsv62IKj7zyHZEt27ocWxAEQfjfpariFZZXolkqGWQJ7p0cyZOvnyWvoJr3X4gn8VARFzMra/OMHBhISamNKY+dYlAvf6beGsbcj1Jr0++ZGMG+o8VXFHPWpHCeees8eYVW3n4mhsTDxaRl1YnZP4CSUhvTnzrNwB5+TBkfymsL0gDIMlXxz5eu7CEf7A8ZD98Ty0PPH8eUX8nCeZ3ZubeAC2lltXluuDaU4hIrt8/cz7ABwcy8qxUvvJFEVZXCoq9SiWnhRato7yuLK8EDU1sy++UkTPlVzH+lPbv2m0nNcNzAXz80mOJSK3fcf4QhfQO5Z1I0L71zhqJiK0+9lkx+YTUtozx5/em23DrzkEtxFcXGpu9eYty9n+Lrb+SrN8YT23EohrDWtXmCI9sxafZydG6eHNm+hG0/vMHou98h89xBMs8d5M4nVwLwzdsTST+zl6i4XpeNabPZ+PDj+bzy8hyCggz886GH6d27Fy2io53yDRw4gPtmzay3/C3j/kZlZSWr16xxaRtrt9VmY/HHb/H0y29jMITw5EPT6N6rP5HRrZzylZeV8fPK72jdJsHp78bQCF5//7Mrign2fbxtxUvcOGMxPn5Glr17Cy0ThhIYWmcfR7Sj/YPL0Ll5cnzXUnatnsfIO98GYOPSx+k2fCZR8f2oriwFybUOTYpi46f/zGHKY/9GH2hk/gu30q7LEEIiHHGv6TOankMnAHDq4CbWLH2Nux5dSEhkHLNe+A6NRkuxOZcPnhlLmy5D0GgufwmyKQpzV2xhwfSbMfr5MPH9bxicEEOsMbA2T6rJzL837+fzf4xH7+VBfom9bG07dZ6kDBPfPng7VTYb0+Z/T/+2LfHxcGt0WyUJRnaTWbpFwVIOU66VOZ2pklenri3HrLJ4g4rVBl1jJYZ2kvhht0pJBXz+i4JNAZ0Wpo+SOZ1h/7sr+3jTdy/xt5rys2TeeGI7OJefkMh2TKxTfrb/+AY3TKlTfp6wl59v33Gt/Pwad+fKOVw/9d9464388OGttGg3hACjI25QeDsS7v0OrZsnJxOXsnfNPIZNfLs2ff+G9whtVb8C6HIkCSaN8uXNr8wUWhSenRbA4ZQqsvJstXnyi2wsXlnMyD5eTsuaixXmfmrGagN3Hbw0M5AjKVWYS5TLb6vNxucLXufxFz8g0BDCc4/eRdeeA4iIjnHKV15WyrqfviY23vFAHtkilpfe/ByNRou5II+nHpxEl54DGj2Pf91Y7+smYvnybRRLIX7TnqI6+Qi2PEflr+eA66k8sZ/KA1vRBIXhO/GfmN97Ck1QGO7te2D++AVkXz/0dzyM+cNnXJqFyqYovLJmL/MnDceo92LSv9cwKD6S2GD/2jyzR/So/ffSfUkkZRcAEOzryX/+Pgo3rYayqmrGLfiJQfGRhPh61Ytzqbiv/mcFHz02A2OgH3c+/y6DuiYQExFam+ditonPftrE4mfvQ+/tRYHF8Zs++frBVFRVsXxTYqOxfqUoNpYtfplZTy/E3xDKW0/dRoduQwiNjK3N063fDfS79jYAju/fzA9fvM7MJxfQvf9ouvcfDUDmxRT+Pe9+UcEgCIIgCL9TswyXaBPjRWZOJdmmKqw2lS17CunT1c8pT5+ufmzYYb/R2b7PTOcEX6e0bFMVqRmutVoBxLfyJDO3kuy8aqw2lW17i+jd2dcpT6/OvmzcVQjAjgNFdGp7ZQ/2l9IuzpeM7AqyciqwWlU2bjfRv2egU54BvQys3WRvRdqy00S3a+w3fxWVCsdOWaiquvxN86W0be1DZnYFWbmVWG0qm3YV0K9HgFOeft0DWLfF3ptja2IBXTvoAThzoYz8wmoALqSV4+4mo9O6VnuXnXoU/6AW+AdFodG60bbbDZw9ttEpT3R8b3RungCEtexMiTnbniBJWK1V2KzV2KxVKLZqvHyDGo2ZnHKa8PAwwsJC0el0DB44kN2Je1xaX4AunTvh6enpcv5fnUk5hTEsEmNoBFqdjr4Dh7MvcUe9fN98uZAx4yfhpmv84dYVuReP4meIxs9g38etO1/P+RPO+ziitWMfG1t0orTIvo8Lss+gKDai4vsBoHP3rs3XmPRzRzEYowkMiUKrdaNjr+s5dXCTUx4PT5/af1dVlgP288bN3bP2Qay6usr+dOmC42k5RAX5E2nwQ6fVMKpTPFtOnHPK8/3eE0zocw16Lw8ADD72B6BzOYV0bRWOViPj5aYjLiyIncmp9WJcSnggFBaDuRQUBU5eVImLcF7n1Fyw1jwLZ+Sr+HrZ0xUFbDVFViv/ugdck516FP9gR/lp07V++Yn6TfkprlN+bNVVKDXlx+Zi+QEwpR1Fb4hGH2iPG9vpelJPOR/b8NheaGvihkR3otSS41g+4wTlJXlExvW7gq2FmHAtuYU28sz2Spm9Jyro0sa5nOQXKaTn2uo9T9sUx/7XaiVXTynOnj6BMTSSkJpy23vACA7s3VYv3/IlCxg9bjI6N8f6uLt71J7HVdWVSFdwdLURrbAV5qKY80CxUXliH7o2nerlk9zt57Hk4YlSXASArk0nKk/sA5sVxZyPrTAXbUSresteyvHMfKICfYkM8EWn0TCyfQu2pKQ1mH/NiQuMat/SHlejwU2rsW+vVUG9gqm1T5y9SFSIgcgQAzqtlhG9O7Pl4AmnPCu27OGW4f3Qe9vLbKDe8Zvcs30cXh7uLscDSD1zjKDQaIKMUWi1Orr0vY5j+39zjfJyXKMq61yj6jq482e69r3uimILgiAIguDQLD0ZDAE6TAXVtZ/zCqppG+vcMhJUJ4+iQGm5Db2PhqpqlVtvCOHJ188y/rqQK4qZV1gnZqGVNjGe9fKYCh0xy8oV9D72G6zQIDfeey6WsnKFL37I4cTpMlwRbHAnN8/RW8KUX0W7eOfKjaBAt9o8NgVKS634+WopKra6vH2/FRToRm6+Y3iJKb+KdnHeDeZRFCgps6H31WKpE3dgr0BOnyul2urazWWJOQffAEdLlY+/kawLRxvMf2z3MlomDAQgvFUXouJ68ckz/VFVlc4D78AQGtvgsr/Kz88nOMjxMBUUZCApOaVevp07d3H8+AkiIsK5Z/o0QoKDXdqmhhTkmzAEO85BQ1AwZ5KduzCfO5NMfl4uXXv05aflS5zSTDlZPH7/FDy9vLntjum061D/geNSSoty8PEPq/3s4x9KTuqRBvOf2rOM6Lb2fWzOu4C7py9rPvsnxQXpRMb1ofcNjyDLmkbjWgpz8Qt0HFt9oJH0s/WPbeIvX7Fz7efYbNXc/bij+3Ha2SOsWPQ05vwsxs941aXW39yiUkL9HA8FIX4+HEvLdsqTmmevGLzrw2XYVIVZ1/aiX5sWxIcHsWDDXiYP7EJFtZV9Z9OJCXGuaGuIrydYyh3nfHEZhBsazt8pRuJcliO/ryfcNlAmwAc2HXGtFwPUlB9/5/KTndpw+TmeuIxWdctPfC8+efbKyg9AqSUXHz9HXG+9kdy0huMm71tOZPwAAFRFYc/q1xh82+tkntntUrxf+etlCiyOXguFFoVWETqXlw/QyzwwwY+QQA3f/VLSaC8GgMJ8E4FBxtrPgYYQzqY4P/xeOJtEfl4Onbv3Z/WKL53SziQfZ9H7c8gzZTPzwRdc68UAyL7+KEUFtZ8VixndbyoKyrb+hH7Sg3j0HIqkc8Pypb2niMY3gOqMc3WWLUT29ccVucVlhOod136jrzfHMvMumTfTXEKmuYSeLR3nQnZRKf/8ZhNpBcU8OLybS70YAHILizAaHOtoDPTn+FnnSr7UbPtQx7vnfIBNUbhn7Aj6XvP7ew8UFeQSYHCsu3+gkdQzx+rl275uKVtWf47NWs29zy6ul35o91qmzX7/d6+HIAiC8L9HEa+wvCJ/Sk8GSZJmSJK0X5Kk/ekpy5v0u+8cG8qKdSYqKq+8df/3Kiiy8vfHkrn/pbMs+jaL2dOj8PT4358zs2WkJzMmRfHWwvN/yvef3PcjOWnH6T7MPma20JRKQfZZps/ZyoyXt5GWkkj6mf1NEqt3r558/um/mf/h+3Tt0pl5b73TJN97OYqi8MWi97lz6n310gICDXz46XJee+9TJk+7j/fnvUhZWWmTr0PygZWY0k/QZbB9TLNqs5J1/gB9b3yM8Q98h6UgjaR9K5o0Zu/hk3hk3npG3voIW1bOr/17VGwn7n9lFTNf+JatqxZSXVV5mW9xndWmkppnZtHMsbw6cSQvLtuEpbySvvHR9G/bgrs+XMYTS9bRKToUjdz05bZ9C4mwQInEOnM2FJfDonUKH69W6NhSwvvKGmRdcmrfj+RcPE63ofbyY64pP9Ne2sr0OTXl52zTlJ+6Th9aSV7GcToNtJ9TJxOXEtVmoFMlxdVSaFF44ZNCnvqggL7XeKD3/uPjJRVF4avF7zBxygOXTG/dpgOvfvANL877jJ+Wf05VE53HAO4delB5ZBfmdx6neOn7+Nx8N1fWF+aPWXfyAsPbRjuVk1A/b76bcSMr772Zn46eJb+k/DLfcGVsNoWLOXkseHIWc/8xiZcXf0dxadN9f0MGjLydZ99by40TH2b9igVOaRdOH8XN3ZOwqLg/fT0EQRAE4X/VZe+4JUnykSTpJUmSTkiSVCRJkkmSpERJkv5+ueVUVf1EVdXuqqp2j4wfVy89v7Ca4EBHa1VQoHMvA4C8OnlkGbw9NVhKbLSN8WLqreF8Pi+BsSOCmTDayE3DG+8SnF9YTVBAnZgB2tohAU7rFeCI6eUpYymxYbWqFJfaW9vOpFaQZaoiwuha13dTfiUhQY4njGCDG3n5zjeleQVVtXk0Mnh7/7FeDLXfaXCsY7DBjbyC6gbzyDL4eGlqezEEBbrx0qNxvPrhWTJzXL+J9vE3UlzoaGm2t8wa6+VLTdrF3nXzuXnGx2hrhhGcObKBsFadcHP3xs3dm5YJA8i60PhcEAaDAVOeo2UuLy+fIINzs7Ner8dNZz+2o0aM4PSZMy5vU0MCDcHkmxwTlubnmQgwOHpHVJSXkXbxPC89+U/uu3s8p5NP8sacxzl7Ogmdzg1fvX2IUEzrthhDw8nKaLgLc13efkZKzI5x3CXmbLz96u/jtJRdHNg4n+umfIRGa9/H3v6hBIW3xc8QhazR0qrDcPIyXJtATh8QQlGB49haCnLQB9SP+yv7cIqN9f4eEh6Lm4cXuRmnG40Z4udNdlFJ7efcohKMeh+nPEY/HwYntEKn0RAZ6EeLYH8u5pkBmD6sB98+dDsLpt+MCrQIcq31t7gc9J6OhztfL/vffqulEfolSHy3XakdIlFXSQWYilSiXOw04+NvdAx/wF5+fC5xbFOTd7F3/XzG1C0/RzcQ2rJO+Wk3gKzzrs2l4q0PoaTIEbfUknPJcyrjzC4Ob17AiMmOcyrn4mFO7F7C0teGkfjz65w+9CN7177pUlyzRSFQ7+hFE6CXMRfbLrNEA99TopBpshIX3XgviABDMAV5jqEeBfm59cpteupZ5j4zi4emj+Fs8nHe/tejnDvtXE4iolrh7uFJeqprc/UoxWZkP8dQOVnvj6240CmPe+f+VJ20VwxZ088haXVIXj7YiguR9QF1lg1AKTa7FDfE14tsi6MCM6e4lBDfSw+RWltnqMSlvqd1sD8H03IvmV4vf4AfOfmOdcwpMBMc4Dws0hjox6AuCei0GiKCDUSHBnMxx7WJnC/FLzCEwnzHeWwuyMEvsOEej136Xsexfc7DKQ7tWiOGSgiCIAjCH9RYs95XwDlgJPAi8B5wJzBEkqS5vzdo8vkyIozuGIPc0GokBvcKIPGQ89sLEg9ZuLa//YZsQA9/jpyyTwj1yNwz3PXoSe569CQr1pv4elUOK3+5dNfPulIulNfE1KHVSAzs6ceeI84TR+45UsywvvYbuf7d/DiaZL8x0/tokGueN0KDdISHuJGd5/zA3pCk08VEhnkQFuKOVisxbEAwO/YWOOXZsTefUUPtN/SD+wVz8KhrN4+XjXu2hIgwD0KD3dFqJIb2DWTXfucb2l0HzIwcbK+gGdQ7sPYNEt5eGl59Ip6FS9I4nlxS77svJzS6I2bTBYry0rBZq0g6sJqYjs4ziuemneSXb55jzIyP8fJ1VAboA8JJP70PxWbFZqsm/cw+Ao2Nd/duEx9HRkYm2dnZVFdXs2XbNnr36umUJ7/Asc8T9+wlOirqirbrUmLj25KdmUZudibW6mp2bfuF7r0cY9K9vH1YtGQ1HyxexgeLlxHXJoHZz75GbFxbLEWFKDb7w1ROdgZZmekYQ8NdihsS1ZGivFQs+enYrFWcOfwzrdo772NTxkm2Ln+e66d85LSPQ6I6UlleTHmJfX9knE4kwIV9DBDRqiP5OakUmNKxWqs4tudn2nZxnlk/L/tC7b9TjmzFYGwBQIEpHZvNXoFVmJdBXtY5/IMiaEz7SCMX88ykFxRRbbWx9kgKgxKcu5gP7RDD/nMZ9u8uLSfVZCYyUI9NUTDXtIqmZOWRkpVHn/joejEuJbMAAnzBz9teAZcQLXE6w7mfnNEfrusu8912hbI69XC+nlAzjB0PHUQGS+S7OEdtaHRHCk0XKMq3l5/kg5cuPxu/fo6bpjuXH9+AcNLP1Ck/Z10rPwDBkR2x5KViKbCfU2eP/Ex0u98c28yTbF/xAiMmf4injyPu0AlvMPGJTdz++EZ6X/8YcV3G0HPUIy7FPZ9pxRioIchfRiNDz/YeHE6panxBIMBXRlczUsHLQ6J1lI7s/MYrKGLiEsjOSiM3JwNrdTWJ29fTteeA2nQvbx8+/nIDby/8kbcX/khsmw489PQ8YuISyM3JqD2P83KzyEpPJdjoWrm1ZlxAExiC7G8AWYN7+x5UpzgPc1IsBeha2YcLaIJCkbQ61LJiqlOO4N6+B2i0yP4GNIEhWDNc62HWPtzAxYJiMgqLqbbZWHcilUHx9a9/5/OKsFRU0SnSUeGSYymlotq+vZbySg6l5dLSoHcpbkJMFGk5eWSY8qm2WlmfeJhBXdo75RncrQP7T9kraQqLS7mYbSIi+DLjkhoRHduBvOyL5OemY7VWc2jXGjp0cz6PTVmOIRsnD20jOMxxTVAUhcOJ6+giKhkEQRAE4Q9pbDBpS1VVP6v591uSJO1TVXWOJElTgJPAU78nqKLAh1+kM3e2/bWO67cVkJpRweSxoaRcKCPxkIW12/J5bEYLPn29HcWlVqc3S/zemB8vyWTOgy2RZYkNOwu5mFnJHWNCOH2hnD1Hilm/vZBHp0WycG4cxaU2Xq95s0SHeG/uGBOCzaaiqPDhl5mUlLrW2mZT4O1PzvLmCx2QZYnVG3O4kFbG1IktSDpTzM69BazekM0zD7Vh6fzuWIqtvDAvqXb5bz/pgbeXBq1WZkAvA4+8cNzpzRSX2973Fl/g9afbIMsSazabuJBezpRbI0g+W8quA2ZWb8rlqfti+fK9TlhKrMx5x966P3aUkfBQDyaPj2DyePuD4OyXkzBbGu9dIWu0DLnlOZZ/NA1VtdGh9ziCwuLYufpdQqM7ENtxGNt+eJ3qyjJWLbZ3R/YNCOPme+YT12UkF08n8p9XbgRJomW7AcR2rP/Ks9/SaDTcO2smTz37PIqiMOLa4bRs0YLPv/iS+Lg4+vTuxY8rf2L3nj1oNBp8fXx55CFHV+iHH3uc9LR0yisqmDT57zz0wP1079bVhbha7p75MHOfe7jmVXg3ENUihm+/XERMXFu69+rf4LKnjh/h268WodFokWSZ6fc+io+vazfvskbLgLHP8tPCqaiqQtse4wgMjWPv2vcIjupAq/ZD2b3qDaory1j3xYMA+PqHcf3dHyPLGvre+Bg/Lvg7qCrBke1J6HXL5QPW2d7Rdz7D529Ms7/CcuDfMEbG8cv37xHRsgPtug5lzy9LOHtiF7JWh6eXnnHTXwEgNeUA21ctRNbqkCSJGyc/h7dv4/MjaDUyT44ZxKxFK1EUhZt7JNA61MCH6xJpHxnC4PYx9I2PZlfKRcbO+xJZlnnohn74e3tSWW1lysf24VreHm7MvX0EWo1rwyVUFdYfVJgwSEaueYVlngUGdpDIKlA5nQlDO8m4aeFvfe3fWVQGy3YoGPQwvLOMir2j+54kFVORS2GRNVqGjn+O7z+ahqrYaF9Tfnatfhfjr+Xnx9epripj9aeO8jNmxnziOo8kLSWRL169EXC9/Pwat+9Nz7Bm8TRUVaFN978RaIxj/4b3CI7oQIuEoez5+Q2sVWX8suQhAHz8wxg5+SPXNqwBigpfrS3hoYl+yJLEjiMVZJpsjBnkxYUsK0dSqmgZpuXeW/V4e8h0inNjzCCF5+YXEhak4dZrHS3j63aXk5Hb+HVZo9EyecZs3njhfhRFYeCwG4mMjmX5Vwto1bodXXsNbHDZlJNHWLX8czRaLZIkc9fMx/DVu9Y7BlWhdM1S9JMeBEmm8vBObKYsPAffhDUzleqUI5St/w7vG+/Eo9dwAEp+/AwAmymLqpMH8J/1Iig2StcsdenNEgBaWeaJUT2ZtXQjiqIypnNrWgf789GWwySEGxhcU+Hway+Guq88PZdXxFu/HEBCQkVlcu8E4lyc10Sr0fDY5LHc9/pCbKrKmIE9iI0M5ePla0loFcWgru3p07ENicdSGP/E68iyzAMTRuPva58/YurLH3IhK5fyikque2AOz069lb7XtLlsTI1Gy7gpTzF/7j0oio1eQ8YSFtWan7/9gOiY9nToPoTt65aQcjwRWaPFy1vPxFmO9pKzp/bjbwglyPjHK6EFQRCE/y1XMPexAEiXmy1akqRdwGOqqu6QJOkm4F5VVUfWpCWrqnr5X3xg5F2Hr/oh0eqaZT5LLKbCxjP9CbTuTfPWgis1YVrjr8b7M4yMqT+p45/NrLp2Y93Utia59naAphYe3DxX0htz/thD6+/xVsWsqx4TINC/8ck2/wwlpVdvPpu6Tp3Iv+ox77mlea6Nsd/Obpa4Xq1c66nT1Gzxrk1a25S2u4266jF/dV0X1ycnFQRB+H/k6k0i1AxW7LX9JasZxvbUNMtxaexpfCawSJKkOOAEcDeAJEnBwId/8roJgiAIgiAIgiAIgvAXctlKBlVVjwI9L/F3kyRJLo4yFgRBEARBEARBEATh/4M/8j63F5tsLQRBEARBEARBEAThv5CK9Jf8r7lctieDJElHG0oCGn53nSAIgiAIgiAIgiAI/+80NieDEfvrK387o6EE7PpT1kgQBEEQBEEQBEEQhL+kxioZVgE+qqoe/m2CJElb/pQ1EgRBEARBEARBEIT/Espf8t0SzaexiR+nXiZtYtOvjiAIgiAIgiAIgiAIf1V/ZOJHQRAEQRAEQRAEQRCEWqKSQRAEQRAEQRAEQRCEJtHYnAyCIAiCIAiCIAiC8P+WKuZkuCKS+ifvsc1xna76ISleevBqhwTA9/auzRJX4948HVI2P7G3WeLO6H7iqscMSN5x1WMCmHckNkvct+MWNkvcsFCPqx5zZunrVz0mwIyTk5sl7iddvm2WuNbsrKse8/2gf131mADl5bZmiVtZ2Txx+3fTXfWYP/z825deXR1pKenNEhdg/Rddmi22IAiCC6TmXoE/03eJf82pH2/pLTfLcRHDJQRBEARBEARBEARBaBJiuIQgCIIgCIIgCIIgNEAMl7gyoieDIAiCIAiCIAiCIAhNQlQyCIIgCIIgCIIgCILQJEQlgyAIgiAIgiAIgiAITULMySAIgiAIgiAIgiAIDVDU/+mXZzQ50ZNBEARBEARBEARBEIQmISoZBEEQBEEQBEEQBEFoEqKSQRAEQRAEQRAEQRCEJiHmZBAEQRAEQRAEQRCEBqhqc6/BX4voySAIgiAIgiAIgiAIQpNotp4MgQP6EvfM46CRyfp2BRc/WeyU7h4eRrtXXkQXGEB1URGnHn2Kyuxc/Hv1oPXTj9bm84ppxckHHyfvl82Nxkw6sp2VX7yCotjoOXg8Q2+a7pS++5ev2bVhKZIs4+7hzfipL2CMbE2BKYM3Zo8mOKwlAC1ad2Lc1Bf+q7cVIKBfX2KfmI2kkcle/gNp//7UOW5YGPFznkcXGIC1yELSE09TlZNrTwsNJf6l53APNaKqcHzWfVRmZrkUNzZMYlQPDbIEB88o7DyhOKX3bifTNVZGUaG0QmVloo2iUnvapKEaIoMkLuaqLN1icykewJ6Dh/lg4WfYFIUbrh3KpPE3O6Wv2biF+Z99SZAhEICx149k9IhhtemlZWXcdd8j9O/VgwfvudvluDuTU3ntx20oqsrYnglMHdK9Xp51R04zf8MekCTahAXx6sSRALz98062n7oAwIxhPRjVOd7luG5trkF/050gy5Tv3ULp5p+c0mV/A3633YPs6QWyTPHP31CVdARdVAz68VNr85VsWEHl8f0ux42PlLmprw5Jgn1JNrYcsTqltwqVubGvjtBAiaUbqzh23nHsr+uppW20BoCNB60cPefa8b2YtJ0dK/+Fqii06zmerkNnOKUf2fopp/YuQ5I1ePoEMuTWf+EbEAHA/McSCAy171efgDCun/Kxy9u683Q6r61NRFFUxnaNZ+qATk7pb6zdw77z9jJRXm2lsLSCHU/eQVJWPv9avYuSymo0ksS0gZ0Y1SHG5bgdW7tzxw16ZAm2Hihj1fZSp/Q2LdyYdL2eKKOWj74zs+9ERW3ao5MDiI104/TFKt76stDlmAA7ky/y2qodKIrC2B4JTB3c1Xl7V+1g37kM+/ZWWSksLWfH89MAWHkgiYWbDwAwfUg3burW1qWYuy7kMG/rUWyqys3tWzClRxun9De3HmV/eh4AFVYrBWVVbJ01GoAsSxlzNh4ip7gMSZJ4b0wfwvXeLsWNCYXhnWVkCQ6fV0lMcm6e6BEv0bmVhKJCtOaszgAAIABJREFUWSWs3qdgKQO9F4zrJyMBsgwHzqgcOut600brcInre2qRJDh42sb2487Xxr4JMl3jNCiKSlklrNhprb02do6VGXSNvfxsPWrj8Fnlt1/foOYot2D/zf3xP6+iKDZ6DRlX7zd31y/fsGvDUmRZxs3di/HTXiA0sjUAmReTWb7oRSrKS5BkmQfmfIPOzb3RmB1iddw+0gdJkth+qJw1u8qd90W0jgkjvIk0alnwvYUDp6oAMPjJ3HuLHkmS0Ghg495yth6suFSIS+re0ZdZd0YiyxJrt+Tzzaocp3SdVmL2PS2Ia+VFcYmVf31wgZy8qtr0YIOORa+244sV2Sz7OdfluIIgCILw36h5KhlkmfgXnuLw3++hMjuH7suXkLdpC2VnztVmaf3Ew2T/8BPZK37Cv3dPYh55gFOzn8a8Zx/7b7rNvvJ+enr/soqCHbsbDakoNlZ89jIznlyEX6CR9569jfZdh2CsuaEB6NJ3NH2GTwDgxIFNrPzqdaY//gkABmMUD7+y4i+xrb/Gbf3MExybPovK7By6fPMV+Zu3UnbOETfm0YfIXbmanJU/4d+zB60e/CfJTz4LQJtX5nDxk0WYd+9B9vR0uY+QJMH1PTV8sdGKpQymX6clOV0hr8iRJ7tA5ZMUK1YbdI+TGd5Fw/Id9hvXXScVdBroFud6JxubTeHdBYuZ9+LTBBsMzHz0Sfr17E7L6EinfEP6922wAmHxV9/SqX07l2MC2BSFuSu2sGD6zRj9fJj4/jcMTogh1hhYmyfVZObfm/fz+T/Go/fyIL+kDIBtp86TlGHi2wdvp8pmY9r87+nftiU+Hm6NB5Yk9GPvovCTV7EVFWC4/yUqThzAlptZm8Vn2Bgqju6hfPdGNCHhBE6djemVh6jOTif/3WdBUZB9/TE8/C9MJw+C0vgDiyTBzf11LFpdRVGpyn1j3TmZaiPX7Dg3zCUq326pYuA1zpeWtlEyEUEy7y6vRKOBe0a7k5xmo7L68jEVxcb2FS9x44zFePsZWf7eLbRsP5RAo6PcBkW0Y9wDy9C5eXJ811J2r57HiDveBkCj8+DWh39ofJ/+hk1RmPvzbhbcORKj3puJC1cyuE00sSEBtXlmj+pV++8le06SlJUPgIdOy8tjB9LC4EeupYzbP/mRvrER6D0bf0CSJJh8o57XPyugwGLjxZlBHEyqJNPkeCjML7Kx8Hsz1/Wv/0D9845S3HRlDO3hdeXbu3IbC6beiFHvw8QPlzG4XUunc3n26P6O7d11lKRM+8N/UVkF8zfuZ+l945EkmPD+MgYntETv6dFITJVXtxzho7H9MPp4cufXmxkUE0aMQV+b55FB19T+++vDZ0k2mWs/P7/+AHf3aEPvFiGUVVmRXHyzlCTBiK4yX29VsJTD34fLnM5Uybc48uQUqnx6VsVqgy6xEkOukfgxUaWkAv6zUcGmgE4L00bKnM6w/92VuKN7a/l8fTWWMrjnBi1JaQqmOtfGrAKVBauqqbZBjzYyI7pp+G6bDU83GNxJw4JV1ajAzNE6ktIUKqoaDOcU92qXW6j5zf30X8x4ciF+BiPvPnMbCV2H1FYiAHTtewN9h9t/404c2MRPX77O9Cc+wWazsvTDJ7j9H68Q3qItpcVmNNrGb1ckCSaN8uXNr8wUWhSenRbA4ZQqsvIcFSP5RTYWryxmZB/nMmIuVpj7qRmrDdx18NLMQI6kVGEuafzaKEtw311RPPHaGfIKqnn/pTbsPljExUzHiTFqkIGSUhtTHj3J4N7+TL0tnLkfXqhNnzkxgn1HLZf4dkEQBOG/gRgucWWaZbiE/poOlKemUZGWgVptJWf1WoKGDXbK4906lsLdewEwJ+4laPjget8TPOpa8rftQKlo/A7v4tljBBmjMYREodW60bn3dZw4sMkpj4eXT+2/qyrLaYq3oTbHtgL4duxA+cU0KtIzUK1WTGvWYRjq/L1esTGY99bE3bsPwxB7uldMDJJGg3n3HgCU8nKX40YYJAqKVcwl9ufWExcU2kY6n2YXcuw37wDpeQr6Ovd657NVKp0b2RqVdPoMEaFGwkON6HRahg7oy869+1xePvnMOQrMZrp3vqbxzHUcT8shKsifSIMfOq2GUZ3i2XLinFOe7/eeYEKfa9B72R+4DD72jT2XU0jXVuFoNTJebjriwoLYmZzqUlxddCy2vBxsBSaw2ag4nIhH+2718snunvb/e3phs9S0aldX1VYoSFodXMEFMypYJr9IpaBYxabAkbM2ElpqnPIUlqhkF6j1LsQhATLnsxQUFaqtkF2g0CbKedlLyb14FL+gaPSGKDRaN1p3vp4LJzY65Ylo3Rudm31bjS06UWrOdn2jGnA8I4+oQD2RgXr7se0Qw5bkiw3mX3vsHNd1tPdWaBnkRwuDHwAhei8CvT0oLHOt/MRG6sjNt2EqtGGzQeKxcrq2c66cyDPbSMuxol7i2efkuSoqKq/8V/B4Wi5RBj8iA389l1uz5dT5BvOvPXKa6zrFAbArJY3ecZH4eXmg9/Sgd1wkO5PTGo15IqeAKD9vIv280WlkRsRHsuVcw72l1qWkMzI+CoBz+RasikLvFiEAeLlp8dS5VmceHgiFJWAutReFUxdV4sOdr/YXTdReozLzVfRe9nRFAVvNftfKXNFvRGSQRIFFpbDE/h3Hziu0jXK+Np7PVqmuiZtmUvHztkdoHSFzNlOhvAoqquBspkJchGs/381RbgEunjmGwRiFwVjzm9vnek4ccO6F99vf3F9rilKO7iIsOp7wFvYeMd6+/shy43FjwrXkFtrIM9srgvaeqKBLG+eK2/wihfRcW71ttSmOY67VSi5XWgG0ifUiM6eSbFMVVpvK1sRC+nbzc8rTp6sfG3bYKyK37TXTpb1vbVrfbn5km6pITXe954QgCIIg/De77F2KJEl+kiS9KklSkiRJBZIk5UuSdKrmb/6/N6h7aAgVWY4HgcrsXNyNRqc8JUnJBI+0d2cPGjEMrY8PWn/nH23jDaPIXbXWpZiWghz8DaG1n/0CQykqrN8lcef6Jbzy0EhWL32TMXc9Vfv3AlMGbz/1Nz6eM5lzSa53L2+ObQVwDwmhMtvRXbMyJwe3kGCnPKXJKRiGDwXAMHyoPa6fH54to7EWF5Pwzjy6freUVo88aO8b7AJfL7CUOT5bylR8L9Oo2qW1zJnMP1Y1aMovIDjIUPs52GDAlF+/q/i23Xu4+/7ZPPfqW+Sa7K2wiqLw0adfMGvKnVccN7eolFA/x01yiJ8POZYSpzypeYWk5pm568Nl3PHBt7UVCfHhQexKvkh5VTWFpeXsO5tOtrnYpbiyPgCbuaD2s62oANkvwClPyfrv8ejaj+Cn3yPg7tlYfvhPbZouKhbDI69ieOQVLN9/6lIvBgA/bzCXOo5VUanjIagxWfkK8VEyOg14uUNMuOzSsqWWHLz9w2o/e/uFUlqU02D+pL3LiG47sPazzVrJsnfHsfz92zh//BeX1hUg11JKaJ2u9yF6b3Lqnth1ZJpLyDAX07NVWL20Y+kmqm0KUQH6SyxZX4BeQ36Ro9W1oEghwNe1h7o/Itfym3NZ70NOUekl82YWFpNRWEzP2IiaZUucljXqfcj9TTm4ZMySCoy+no7lfDwxNdAlIMtSRkZRKT2i7NewVHMJvu46Hl2VyMQlm3hn+zFsimvXER9P+3XpV8XlUGc16unUSuJsliO/rydMHSFz72iZxGTXejGA/dpYVKf8WMpAf5ky0C1O5nSGvWzqvZzX2VKmOlXOXk5zlFuAosIc/A2OMuEfaKSooH7Z3bl+Ca88OIpVS97i5sn231xT9gWQJD55ZTpvPzWezT/926WY/nqZAouj/BRaFPyvoPwE6GVemBHAGw8YWLOrzKVeDABBAW6YChzdSkwFVRgCdM55AnWY8u1dQBQFSsts6H00eLjL3HqDkS9W/PHKUUEQBEH4b9HYk+O3QCEwWFXVQFVVDcCQmr9929BCkiTNkCRpvyRJ+1cV5f+uFTvz6lv49+xO9x+/wb9nNyqycxxNSIBbcBDebVpTsH3X7/r+hvQbMZEn317HDRMeZuMPCwDQ+wfz9LsbeWju99x4x+Ms+fAxKsoav4l2VXNt67l5b+PfvRtdv1uKf/duVGbnoCo2JI0Wv65dODfvbQ5OuAOPyEhCb76pSWMDdGwlER4oseuk62OLf6++Pbrx9cIPWPzeG3Tv3JFX3v0IgB/WrKd3t86E1KmkaEpWm0pqnplFM8fy6sSRvLhsE5bySvrGR9O/bQvu+nAZTyxZR6foUDQuVuS4wqNLH8r3b8P0r/spXPwG/rfPqm0lrE47S/6bT5D/3nN4D7kRtLpGvu2PO52hkJSm8I8x7kwc5sbFHAW1ifudpRxYSW76CToPdsw5ccdTmxj/wHKunTiPnSvnUpTXcG+E32vt8XMMT2hZ7/iZist4esVWXhozAFluin5R/x3WHj3N8A6xTXq+NmZdSjrD4yLQ1OxHm6JyKDOfBwd05D8TBpNRVMZPJ13rCXQl2kdLhAZK7El2rpT493qF+T8rdGwh4dX4KJgrdk2MTLhBYsfxP//aeDlXo9z2GzGRJ99Zyw23P8QvP8wHQLHZOJ98kEn3vs69z3/B8X0bOX08sUnjXkqhReGFTwp56oMC+l7jcdlKoKZy599C+X5tLhWVzXusBUEQBKEpNda/tKWqqq/V/YOqqtnAa5IkNTg7nqqqnwCfAGyO61TvjqQyOxePMEevAvfQECpznFs4qnJNHL/3YQA0Xp4EjxyOtdjR0hty/Qjy1m9CtbrWt14faMSc72gpKCrIxi8gpMH8nfpcz/efvgSAVueGVmfvchnZqj0GYxSm7AtExXRoNG5zbCtAZW4u7qGOHhPuRiNVuSbnuCYTJx+0Tywpe3oSNHwYtuISKnNyKElKoSLdPslb/qbN6K/p6FLc4prJ0X6l95IovkQDcKtQiQEdNHy23lq3PuV3CTYEYspzVGaZ8vMJNji37PvpHV1Tb7h2GAs+/wqAk0kpHD2ZxA9rNlBeXoHVasXTw4N77prYaNwQP2+yixyVTblFJRj1Pk55jH4+dIw2otNoiAz0o0WwPxfzzHSIMjJ9WA+mD+sBwBNL1tEiyLXOQYqlEI2/Y6y8xi8Qpci554Znj0EULnodgOrUM6DVIXv5opQ6xvzacjNRqyrQhkZiTW+4a/yvikrBv85Nt5+35NQy25jNh6xsPmQ/hycM1WEqanxZb72RUrOjC31pUTbefsZ6+dJTdnFg03zGzPoCjdbRPdqnJq/eEEV4TE/yMk/iFxTdaNwQvTfZFkdLfq6lFGMDTcdrj5/jqev7OP2tpKKK+77awD+HduOaqIavM79VaLFh8HO0vAb6yRQWuz7R3u8Vov/NuWwpweh36UkU1x45w1NjBtRZ1od95zNqP+dYSujRKqLxmD4e5BQ7JuXLKSkn2OfS8zisT0nn8cGOiTeNPp60CfYjsmYdB8eGcSy74JLL/lZJOTXDH+znn6+nveLgt1qGQN8Eia82K5e8RpVUgMmiEhUMyemNxy0uw6kXgN4LLJcoPzFhEoM6ali8rro2rqUMWhrrLitxIce1stcc5RbAL8CIOd9Rds0FOfgF1i+7v+rc53q+XzzHvmygkZi23fDW26/jbTsPIP38SeI69L5sTLNFIVDvKD8Behnz7yg/5hKFTJOVuGhd7cSQl5NXWEVwoOO6ExzoRn6h88QVeQXVBBt05BVWI8vg7aXBUmKjbaw3A3r4M21COD5eGhQVqqoUVv6Sd8XrLQiCIPx5XOwwKdRorCkqVZKkxyRJqr0zkCTJKEnS40Djg24bUHzsBJ4to/GIjEDSaTHeMIq8jVud8ugC/GtbXqPvmUr2MufJ20JGX0fOFQwfiIrpQF52KgW56VitVRxOXENCtyFOeUzZF2r/nXR4K0GhLQAosRSgKPYblfzcNPKyUzGEOE8q+N+0rQDFx0/gGR2NR0Q4klZL8HUjyd+8xSmP1r9O3Ol3k73ix9pltXpfdAH2Gzz/nj0oPes810BDMvJVDL4S/t72ERbtW8okpzvfoYcGwOheGr7eYqWs8oo265LaxMWSnpVNVk4u1dVWNm3fRd+ezm95yC9wPITv2ruf6Ej7Q9Azj9zPt//+iG8WfsCsKXcwYshAlyoYANpHGrmYZya9oIhqq421R1IYlNDKKc/QDjHsr5mRv7C0nFSTmchAPTZFwVxqf7JJycojJSuPPvGNP/wCVKedQxMUiiYgGDQaPDr3pvLkQac8ijkf97j2AGhCwpG0OpRSi32ZmhZo2d+ANjjcPreDC9JNCgY/iQBfCY0MnWI1nEp17QZekqht8Q0NlAgLlDmd3njtUkhUR8x5qVgK0rFZqzhz+GdaJgx1ymPKOMnW5c9z3d8/wsvH0SOlsqwIm9X+gFBeWkh26iEC6kwYeTntw4O4mF9EemGx/dgeP8egNvWPz3mTmeLyKjrVqUiottp46JuN3NipNde2b1Vvmcs5l1GN0aAhyF+DRgO9O3pyKKkJCkkj2keGcDGviPQCS825fIZB7eqv+/ncQorLK+kU7ag47Rsfxe7TaVjKK7CUV7D7dBp9a+ZOuJwEYwBp5hIyikqptimsT0ln0P+xd9/hUVTrA8e/M7ub3jfJJiEhkELvhN47AorYEHsBBPWK14pibyg2sHe8iiAKgjQB6b2GnlACgYT0bPqm7s78/tiQzRIggwK53t/5PI+PZOfMvvvOmT2zc+acmai6U06S84opKq+iXWiA07rFFVXkVzcgu1NziArQNiUlPQ/8vezTCGQZWjaWOHHelC2THwyPk1mwRXFqo7zdQV99DutmgIhAiTxts5xIy1UJ8JHw8wKdDG2byhw96xw3JEDihh56flpXhaXWNIykNIWYMBk3F3BzgZgwmaQ0bb2zDfG9BYiIbkNuZgrmc8fc7Stoff4xN8Mx+iRxn+OY27xdLzJTT1BZUYbNZuVU4h5M4dH1xkxOt2IK0BHoJ6OToWtrN/Yf13B3TMDfW+bcbT083CRiIgxkmrVtp2OnSmkU4kpIkAt6nUS/7v5sjy90KrN9XyFDetvbp75d/difYN9xnnzjBPc8kcA9TySwaFUOPy/NEh0MgiAIwj9efSMZxgJTgY3VHQ0qkAUsAW77q0FVm43jr06n/XefI+lkMhYspjTpJE2nPEzRoSOY123Er1scUU8+BioU7N7L8VffqlnfrVEYbiEhFOzSfm8EnU7PjfdN4+t3JqAoCl37jSEkPJZVCz4mvGlrWnceyLbVczlxeDuyTo+Hpy9jJ9ljnjq6h9ULPkbW6ZFlmZsfeBkPL21XnRsiVwBsNpLeeoc2X35mf4Tlot8pPXmKyEcmU3wkgbwNG/HrEkfTx/+FqqoU7o0n6Y3p9nUVhVPvfUDbb79AQqI4IZHMBb9py1eFFbtt3DXI/pi2/Sftd0/v304mPU/l+FmVIZ10uOjh1j723a+wVOXn6sdV3jdUR6CPhIse/j1Gz5IdNqf50Bei1+mYMvEBnn7lLRRF4bpB/WnaOILvfvqF5jFR9OoWx8Jlf7Bt1150OhlvLy+mTnn48rbnBePKPDe6H5O/WYKiKNzYpRUxIUY+XbWD1uHB9G8dRc9mjdl2PIUx781BlmX+PbIXfp7uVFRZuf/zhQB4urnw1rih6HUah58rCkWL/4P/hGeqH2G5EWtWGl5Db6bqbDIVCfEULf0J31vH49FnOACFv9in/hiaNsNvwPWg2EBRKVr0ParGqT+KCr9vreLB61yQZdh9zEZWvsqQznrO5ioknlEID5K4Z4gr7q7QMlLHkM4qHyyoQCfDpBvsZysVlfDz+kpNPcKyTk+fG19k2dcPoioKLbreTEBILLtWfURQeBuath7I9mXvUlVZyuofHwccj6rMzz7JxoUvI0kyqqrQccAEp6dSXIpeJ/PciB5M/nEViqpyY8dYYoL9+XRdPK3DAunfwt7hsPLwKYa1aYpU6y5xq44kE38mk8LSCpbsPwHAazf2oUVo/VNyFAV+WFbEM/cGIMmwKb6MtGwrNw30Ijm9in1HK2jayMCUcf54ukt0bOHGmIFePP+x/aRk2oNGQoN0uLnIzHwqmG8XF3Aoqf6TLL1O5rkb+jD5u6X2fONaEGMK4NM/d9G6URD9qzvPVh48wbD2MU75+nq4MXFgHHd8sgCAhwbG4etx6SdLAOhlmWf6t+fRxVuxqTC6VSTRRh8+355AK5N/TYfD6uNnGdqskVNMnSzxeO+2TPptCyrQMtiPMW2a1BsT7G3Un/EKt/eVkSQ4mKySWwR9Wktk5KskpcOA9jIuehjTw/6dLCqFBVsVjD4wqL2Miv2mjzuPqU5Ph7gURYXlO63cM9iALNsfYZlToDKwg440s8KxVJVhne1t49j+1W2jBeaus1JWCRsO2nhopH1q04aDNsq0nTs3yPcW7MfcMfdN4+u3J6IqCl36jyEkPIaVv35MRJT9mLu1+pir0+tx9/Th9sn2Y5+Hly99R9zLrBfGgiTRskMfWnXspynXn1aW8O87fJEliS0HyknPsTG6nwenM6wcOF5Jk1A9j9zmg6ebTPtYF0b3U3jpi3xCA3XcNsRxL6RV28tIy9bWyaAo8MkPZ3nr6WhkWWLVJjNn0sq556YQjieXsmNfESs3mnl2UiSz32tFcYnV6ckSgiAIgvC/RqpvfqUkSS2AcGCHqqoltV4frqpqvZfXLzRd4mornhdff6GrwHtcp/oLXQU61wZ5SAjrp+5qkLgT445c85j+x7Zc85gABVuu/jzkC/kw9usGiRsaUv/J6ZU2yTLjmscEmJhwT4PE/arjRW+nc1VZMy/+5Iir5ePAN695TICysqs/xeVCKioaJm7vzlf/vi7nW7yi7s19r4XU4xrmxlwlq3/s2GCxBUEQNPjfuQHVBczZ/M98iOVdfS7neUlXTn1Pl3gM+B14FDgsSdLoWovfuvBagiAIgiAIgiAIgvC/QVWlf+R/DaW+6RITgM6qqpZIktQEWCBJUhNVVWfxP95bJQiCIAiCIAiCIAjC5amvk0E+N0VCVdXTkiT1x97REInoZBAEQRAEQRAEQRAEoZb6JvNnSZLU4dwf1R0Oo4BAQNszDQVBEARBEARBEAThH0pV/5n/NZT6OhnuATJrv6CqqlVV1XuAvlftUwmCIAiCIAiCIAiC8I9zyekSqqpe9DbKqqpuvfIfRxAEQRAEQRAEQRCEf6qGefahIAiCIAiCIAiCIAj/c+q78aMgCIIgCIIgCIIg/L+lNOD9Df6JxEgGQRAEQRAEQRAEQRCuCNHJIAiCIAiCIAiCIAjCFSGpV/nZFrPXc80Hl8S9P+BahwRg71PrGyRulbVBwvLrf/Y1SNxhN3eov9AVFuArXfOY0HCPnlm14kyDxC0pKL7mMdv3iL3mMQFG9GiYL+7KXYYGias2wDjDxP2p1zwmQHAjY4PELcq3NEhcawMchBoiJkB2clqDxJ36aq8GiQswqpOYWSsIgiYN82P5GmmIc9or4f4BDVMvYiSDIAiCIAiCIAiCIAhXhOhkEARBEARBEARBEAThihCdDIIgCIIgCIIgCIIgXBFiop0gCIIgCIIgCIIgXERD3Sftn0qMZBAEQRAEQRAEQRAE4YoQnQyCIAiCIAiCIAiCIFwRopNBEARBEARBEARBEIQrQtyTQRAEQRAEQRAEQRAuQhH3ZLgsYiSDIAiCIAiCIAiCIAhXhOhkEARBEARBEARBEAThimiw6RKnjmxizS9voigK7XvdSo/hE52W79s0j/gNc5FkGRdXD4bf+TqBYTEAbF/5JQe2LkCWZQbf9gJRrftoiunVqQthEx8FWUf+6uXkLJjntNwQZCL88WfQ+fhiKykm9b03sZpzAWjy6jt4NG+FJeEQZ157/rJyPXnYkWuH3nVzjd/onOt1dzly3faHI9chY7XnCpB8ZBPrFryJqii07XUr3YY6x92zdjYHt/2KLOvw8Apg2F1v4WtsBMDGxe9y6vBGAHpc9zAtOo/QHDeurTeT7w5HliVWbjAzf1mW03KDXuLphyKJbepBcYmVNz85TVZuZc3yIKOBb95uyY+LMlmwIltTzNRjm9m25E1UVaFFl1voMMA514ObZnN09wJkWYebZwD9bn0Tb397rl9PbUVASDMAPP1CGX7f55pzbYj9+Fzctb+8iaLa43Yf5hx315rZHNz6K7LOXrfX3e2o2w2L3uXkIXvd9hzxMC3jtNdt++Zu3Dc6AFmGdTtL+H19kdNyvQ4eGRdIVLgLxaUKs37MISffhk4HE28xEhXugqrC97/nkXCyQlPMzq29mDguFFmG1Zvz+fWPXOeYeoknHwwnJtKN4hIbb3+ZSra5imCjgS9ejyUt0x7n6KkyPp2TrjnX2EYSo7rrkWWJ3cdsbDpoc1reJERiZDc9IQES89dbOXxaqVk2rIuOFhH2Ptx1+2wcSlbQ6lD8VuZ9+x6qYqPP4DGMuPn+C5bbs30tn894mhffnUOTmFaUFBXw2bvPcDrpCL0GXM+dE6dqjnku3xFd9cgS7D1hY9Mh58/cs5VMXDMdiqJiKYdFW60UWOzLOkbL9GuvA2DjARv7TmrPN7aRxMjuemRJYs/xutu5V2sdcc1kFBUs5fDb5ipH3BiZ/tVxNxywsS9JW9yOLT144KZAZBnWbC9i0ZoCp+V6PUy5y0RUhCvFFoX3v88kJ89K3zgvRg/0rykXGebCU++mcjqt8vwQF9SqqZ7bBnkgy7D1QAWrdjp/B2LC9dw2yJ1GwTq+XWIh/liV03I3F3h5vC8Hjlfy85oyTTEB2jVz5Z7r/ZAlifW7LSzdWOy0vEVTF+4e5UfjEAMfz8tj12HHe/fp5MGYgd4ALFpXzOb4Us1x2zd35/4b7e3F2p0l/L6u0Gm5XgeP3hFkby8sCjN/zCEn31rTXkRHuKKo8P26uz8+AAAgAElEQVTiPBJOlmuK+VfrVifDw+OCiYpwRSdLbNhdzG9/5mvOtVsnf6ZMiEGWJZb9mcGcBalOyw16iReeaEHzaG+Kiqt4aUYCmdn2+r/rlghGDQlFUVRmfpXErn3a4x7dv5nFP7yNotjoNuBmBo2e4LR825/z2frnPGRZxsXNg1vHv0JIuP0YlH7mGAu+fZXy0hIkWebxN+ZjcHHVHFsQBOH/E/EIy8vTIJ0MimJj9bzXuH3KbLz9TXw//RZi2w2sOfkCaNXlejr2HQfAiQNrWbtgOmMf+5bc9CQSdi9n/EvLKSnM4ueZ9zPxtVXIsu7SQWWZsMlTSH7haazmHKI//IKinduoSD1TUyT0wUnkr11NwbpVeLbrSMi9Ezj7wXQAcn6bj+zqSsDw6/9aro/Pxuciubbuej2d+jlyXfPrdG6fYs81cc9yJrxsz3Xeh/fz0Osacq2Ou+aX17j1X7Px9jMxZ8YtRLcdSGCoI25wREvufnYhBhd39m+ay6bF73L9gzM5eXgD2akJ3PvcYqzWSubPvJumrfri6u5Vb1xZgkfvjWDqO0nk5lXx8WvN2R5fSEq64wfi8H5GSiw27n8qgf7d/XhwbBhvfXq6ZvmkOxqx+2DRBd794rluWfwaI8d/h6eviUWf3Epkq4H4mxy5BjZqyU3dF6B3cSdh+zx2rniPwXd+CIDO4MbNjy/WHK923Gu+H1fH/fPn1xj7mD3uf96+hZh2znVrimjJvc/Z63bfxrlsWPQuo8fP5OShDWSmJHD/NHvdzvvwbqJaa6tbSYIHxgTw5lfZmAutTJ8Syp6EMtKyHCdCA7t5YSlTmPJ2Oj07eHDHSH9mzcllUDf7+z/9fgY+XjLPjQ/m+VmZ9TbYsgST7wzjhQ+Syc238uELUezYX0xqhuPkbFhvf0osNiY8f4K+XXy5/5YQ3vnS/gM/I6eSf712st7cLpTrDT0NfLeykiILPHyDgaMpCtkFjg9cUKKycJOV3m2d66x5hEyYUebjRVXodDBhhIHjZxUqqs6PUpdis/HTV+/w5Cuf4W808fozd9Ghaz/CIqKcypWVWVizbC5RzdrUvGZwcWXMuMmkpZwkLSXpsvO9vpue2aurKCqFSaP0JKYo5NQ6J8zIU/l8aRVVNujaXGZYnI75G224u8CADjo+X1qFCjx8vYHEVIVyDefdkgTX9zAwe5V9O0++wWCPW2s7p5sVPltis8dtITOsi575G6y4u8DAjno++70SFXhktAuJKZX1xpUlmHBrEK9+moa5wMqMpyLYfdjC2UxHBQ3u7kNJqcIjr6fQq5MX99xg5P3vs9i0p4RNe0oAaBzqwtQJoZo7GCQJxg3xYNb8EvKLFZ6715uDSVVkmB0dI/lFCv9ZUcqQrhc+0buhjzsnUq2a4tWOe/9of6Z/m4O50MYbjwYTn1hGWrbjfXILbHzxaz6j+jq3A57uEjcP8mHaJ/aO4jcfNRGfWIalrP5fWpIED94UwBtfZtnbi8fD2HOk9Lz2whtLqcJj09Po2cGTO0f5M/PHHAZ3t3dqPPVeOj5eMs+PN/HcrAxN7cVfrdueHb0w6CX+/XYqLgaJj55vzOa9xeTk1b+9ZRmemBTLv188SLa5gm8+6MSWnWZOpzo6ZEYNDaW4xMrtD+1iUJ8gJt8XxcszEmkS4cHgvsHc/chuAo2uzHy9HeMm7ULR0F+mKDZ+m/0mDz3/Nb5GEzOnjaV15wE1nQgAnXqNpOeQsQAc3rOOJT/OYOJzX2GzWZn76VTueGQ6YZEtsBQXoNOL23QJgiAIV0aDTJfIOH0Q/+BI/IIi0OldaNVlJCcOrnUqU/ukp6qyDEmSADhxcC2tuoxEb3DBLzAC/+BIMk4frDemR7MWVGakU5WVgWq1UrhpHT7deznHjGiC5WA8AJaD+5yWWw7Eo5Rpv4JzTnqyPVf/6lxbxo3k+IGL51pZ4cj1+IG1tIxzzjU9uf5cATJPH8Q/KBK/QHvcFp1HcvK8bdy4WXcMLu4AhDbtQHFBJgDmjCTCY+KQdXpcXD0IatSc5IRNmuI2j/YgPauCzJxKrDaVjTvy6dnZ16lMj06+/LnFDMCmXQV0bO1ds6xnZ18ycyo5c1bbVSuAnNSD+Bob42O05xrdfgSnE5xzDYvujr461+DG7bEUZmp+/4tpiP34XFy/IEfclnEjOXHePhXZ3FG3YVEdKM6355ubkURErHPdntJYtzGNXcgyW8nOs2Kzwbb9Frq0dncqE9fag43VJ2E7DpbSJtYNgHCTC4dP2Ou0qETBUqYQFe5Sb8xmTd1Jz64gM7cKq01l065CunfwdirTrYM3a7fZr/xt2VtI+xaemvK5lPAgCXORSn4x2BQ4eEqhZWPn5rKgBDLz1TonPsF+EqczFRQVqqyQmafSLFxbU3vqxGGCQ8MJCglHbzDQtfcw9u3aUKfc4rmfcd2Y+zAYHCejrm7uxLbqiN6l/u1aJ99ACXOxSn6JPd9DyXXzTc5UqaoeZJCao+LjYd+XYxvJnExXKKuE8ko4ma7QrJG2fMMDJfLq2c5OcbNVfD2r44bLJKU54ialKZq2c0ykGxk5VWSZrVhtsCW+hK5tnU+uu7T1Yv0u+9X+7ftLaNvMo8779OnsxZa9xXVev5gmoTqyCxRyCxVsCuxOrKJdrHNdmYsU0nJsFzyZbmzS4e0pk5isobeqlpiIc99bGzYbbD9QRudWzt/b3HwbqZlVdW5q1a6ZG4eSyrGUqVjKVA4lldOumZu2uI1dyazdXuyz0KW183aMa+PBhpr2wlKrvTBwOKlWe1Gurb34O3WrquDqKiPL4GKQsNpUysq1jYxpGevD2Ywy0rPKsVpV1mzKpnc3o1OZ3t2M/LHW3lmzYWsOndv717y+ZlM2VVaVjKxyzmaU0TLWR1PclKRDGEMiMJoi0Otd6NhjBEf2rHcq4+Zxkd8XB7cR2rgZYZEtAPD09tPUyS0IgiAIWjRIJ0Nxfhbe/iE1f3v7mSjOz6pTbu+Gn/jihcGs/+1dBt/2wmWtez69MZCqHMfQ+6rcHAzGQKcy5ckn8enZFwCfHn3QeXii89Z2sL+YkoIsfGp/Xn8TxQUXyHX9T3w+zZ7rkLHVuV5g3ZILrHshxQXO28nL78Jxzzm0bQFNW9lzDw5vQXLCZqoqyygtySP1+M6ak9T6BPq7kJPnuLKXk1eJ0d/gXCbAQI7Z/kNZUcBSasPHS4ebq8xtI038uOjyOgAshVl4+oXW/O3pG4Kl8OK5Ht29gIjmfWv+tlkr+O2jm1n8yVhOH1mjOW5D7Mdw+fvFwa0LiGpdq26POOo25Zj2ug3w1WMucFzVMxfY8PfVnVdGh7nAfkaoKFBapuDtIXMmvZK41u7IMgQF6IkKd8XoV/9VM6O/gdx8x0lVbr61zv5k9DeQk+/Yn0rLFHy87J8rJNCFj16K5u2nm9I6tu6J4sX4ekgUWhxnXIWlKj7VJ7f1ycizn+wadODhClGhcs2JcX0K8nIICHTUrb8xmAKz85ShMycTycvNon2c9uk19fHxwCnfIgs1nQgX0jlW5kSa/QTM+7x1Cy0q3ho3tY+ndF5cFd9LxI1rpuP4WaX6M9dd91Kf+Ryjnw5zgWOfMhdYCThvPzb6OsooCpSWK3h7Oh8ue3XyZkt8Sb3xzvH3lskvcpy0FhQr+Htp2y8k4JaB7ixcf/kd3f4+OsyFjikoeYU2Any0nUwG/J11fXXO7UVh3e0c4OMoU9NeeMqcTq8krrWHU3sRqKW9+Bt1u31/CRUVCt++0ZSvXm3C7+sKKCnV1skQZHQhO9cxuirHXEGQ0fW8Mq5k59o7TmwKWCxWfH301a/XWje3giCjto7Cwvws/IyOY5+v0UThBY4jW1bP5a0pw1k29wNuvNc+3TMn4zSSJPHl9Al88NwtrFvyraaYgiAIgqDFXx4bJ0nSH6qqXnclP8z5Ove/k8797+TIrqVs++NzRt33ztUMR8Z3nxM26TH8Bw3DcuQgVbk5qIqt/hWvgM4D7qTzAHuuW1d8zvX3X91ca0vY9TtZKYcZ+/gcAJq07E3mmUPMfe92PLwDCGvaAVm++v1Rd98Uwm8rsymv0D6f+3KdiF9C7tkjXD/px5rX7pi6Dk9fE0XmVJZ9fS8BIc3wMTa+YjGv9X5c25Gdv5Nx5jB3PGGv26atepNx5hBz3r0dd68AGkV1QJKuft2u311CI5OB6VNCycm3cvx0BcpVfhZQXqGV+545RrHFRkykGy88Esnkl05ovjr5VyWlqYQHKjx0vQFLOaRkK1fssUeKojB/9gc88NirV+YN/4L2UTKNAiW++ePatI01caNlwgIlvllxedMFrobYSFcqKhVSMrRNlfi7+nVy5fDJKgqK/39MCF2/q4TwYANvPx5GTr6VY6fLr/qjw2Ij3VBUGP9CMl4eOt6Y0oiDx0rJMjf8/vZ39R56B72H3kH81mWsWfQF4x6ejk2xkXwsnilvzMfF1Y0v3nyQ8KjWNGvTvaE/riAIwn8lLdPYBIdLdjJIktTpYouADpdYbyIwEeCeJ76k/yjnm9J5+5ucrp7ar7qbLvo5WsWNZPXcV/7SuudYzbkYgoJr/jYEBlFldr6BnDXPTMpbLwMgu7nh27MvisVS73tfipefiaLanzc/C2+/S+e66qdXAPvV7fPX9brEurXZr4w71i0puHDcM0e3sWPlF4z99xz0BsfVk+7DJ9N9+GQAls1+Ev/gppri5uZXEhTgeJ+gABfM+c7De3Pzqggy2q9QyzJ4eugoKrHRItqTPl38GH97GF4eOhQVKisVlqzJPT+ME09fE5aCjJq/LYWZePrWzfXsiW3sW/cF10/6EZ3exWl9AB9jBGFRXclNS9DUydAQ+zFo3y9OJ25j28ovuOO8uu153WR6Xmev2yXfPkmASVvd5hVanUYfGP105Bfazitjw+inI6/QhiyDh7tMcfXVwB+WOG5m9tqjJjJy6//xbs6vIrDWyIVAf32d/cmcX0WQvwFzvrUmZlGJ/XMVW+3/TzpTTkZOJY1MLiSdqX8qTmGp6jT6wNdDosii/SxnwwEbGw7YY4/trye3UNu6fgFB5OU66jbfnI2f0dFulZdZSEs5yYwX7Dd3Kyww89Fbj/PY8zNpEtNK8+c7X1EpTvn6eEJRad3PHB0q0a+djm9XVmGrPtgWl0LTkFrbylMiOVNbvkUW9by4EoUXihsm0b+9jm9WOOIWlao0DZGd1k3OrP8XgLnAhtHPsU8Z/fTknbcfmwvtZcwF1fuxm0yxxfHevTt5s2Wv9lEMAPnFCv4+js/r5y2TX6JtO0WF6YiJMNCvkyuuBgmdTqK8ChZvrP/mj/lFNoy1ruYH+OrIK9LWQZRXZKNVlOOKfICvjoRT2m7Yam8LarUXvnW3c16RrWb717QX1dv5P0vyAXub8fq/QkjPqX+ayN+p2z5xXuxLLMWmQGGJjaPJ5UQ3diPLXH8955grCQ50bKcgoys55orzylQQHOhGjrkSnQyennoKi6zVr9daN9CVHLO2zitffxMFZsexr9Cche8ljiMdeoxg4bevA+AXYCKqRWe8fOzTNlp26ENacoLoZBAEQRCuiPouYe4G3gPeP++/9wC/i62kqupXqqrGqaoad34HA0BoZFvysk9TkJuKzVpJwu7lxLQb6FQmL+t0zb+TDm/APzgSgJh2A0nYvRxrVSUFuankZZ8mtEm7ehMtPX4U17BGGEwhSHo9vn0HUrRzm1MZnY+P/W5VQNCtd5L35x/1vm99wpq0Jb9Wrol7lhPb/hK5HnLkGtt+IIl7HLnmZ58mrGn9uQKERDrHPbp3OdFtneNmpSawet5LjJn0OZ7ejvmjimKjrMT+4y4n7Sg5acdo0tL5/hUXc+xUKY1CXAkJckGvk+jX3Z/t8c53FN++r5Ahve3x+nb1Y3+CfX7sk2+c4J4nErjniQQWrcrh56VZ9XYwAASFt6XQfIaivLPYrJWcPLCCyJbOueamJbD5t5cZdt9nuHs5cq0oLcRmtf+gK7fkk3l6n9MNIy+lIfbjc3HP36fOj5uVmsCquS9x8+TP8fS5cN1mn7XXbVONdXsytZKQQD1BAXp0OujZwZM9R5xPcvYcKaVfnH0OcPd2HhypnlftYpBwdbF/t9rGuqEoON0A7mKOny6jkckVU6ABvU6ib1dfdh5wnge/80Axg3pWz2/u7MvBo/aOQR8vHXL1+WtIoIGwYBcyc7XNZ0/LUQn0kfD3Ap0M7aJkElO0dWFLErhXnzOE+EuEBEgkpWlbt2lsa7IyUsnJSsNaVcWuLavo0KVfzXIPT29m/bCOGV8tZ8ZXy4lu1vZvdzAApOWqGGvl27apzNFU5xPg0ACJ0T30/LS2CkutfpoTaQoxYTJuLvanH8SEOaZSaIrr67ydj563nUMDJEb3NDBnjdU57lmFmEa14jaSOXG2/rhJKeWEBhkIDtCj10HvTl7sPuTcmbz7sIUBXe33/ujRwYtDJxzTFCQJenb0Yku89vsxAJzJsBHsL2P0ldHJ0KWlgYNJ2k4mv1tWyvOfFzLtiyIWri9j5+EKTR0MACfPVhJi1BPkr0Ongx7t3dmboG3dg8fLaRvrhqe7hKe7RNtYNw4e13a/nJOpFYTWbi86erLniPN0j71HSulf0154cuTEBdqLZm7YbNrai79Tt7n5VtrG2u9V4eoi0ayJG2lZ2urn6IkiIsLcCTW5oddLDO4bzNZdZqcyW3eauW6QvQOgf68g4g/a2+Gtu8wM7huMQS8RanIjIsydxBPabnwcEd2G3MwUzNlnsVor2bd9Ba07D3Aqk5PhuLl14r6NBIbYj0HN2/UiI/UElRVl2GxWTibuwdQoWlNcQRAEQahPfdMlEoGHVFU9cf4CSZJSL1BeE1mnZ+jYl5j/0XhUxUa7njcTFBbLpiWzCI1sQ2z7QezdMIczR7cj6/S4efgwsnqIeVBYLC07X8c3r45A1ukYevtL2m5WpCikf/ERTV+bAbJM/p9/UJFymuA776fsxDGKd23Ds20HQu6dAKqK5fBB0j+fVbN61DuzcA1vjOzmTovvf+HsR+9SEr9bU65Dbn+Jn2dV59rrwrmeTnTkOup+R64tOl/H169U5zpOY67VcQfd9hILPx2Potho2+NmAsNi2bJsFiGN2xDTbhAbF82gqqKUJd9MAcAnIJQxk75AsVmZ9+GdALi6eTHy3neRddpm1igKfPLDWd56OhpZlli1ycyZtHLuuSmE48ml7NhXxMqNZp6dFMns91pRXGJ1erLEXyHr9PQa/SJ/fPsgiqLQvMvNBITEsmf1RwSGt6FJq4HsXPEu1spS1sx5HHA8qjI/+ySbF72MJMmoqkKH/hM0dzI0yH6MY5/65WN73LbVcTcvtddtbPtBrF84g8qKUn7/urpu/UO5+WF73f70vr1uXdy8GHX/5dXtd4vyeH5CMLIEG3aXcDariluH+XIqtZK9CWWs31XCo+MCmTU1jJJShVlz7J1Evl4yz08woar2ERGfzKu/8+hczM/npvP6402QZYk/t+aTkl7BXaODOXG6jJ0Hilm9OZ+nxofz9VuxFFtszKh+skSbZp7cNToYm01FUeHTOemUWLRdwVVUWLLdyv3DDUiSxN7jNrILVAZ30nE2V+VoikKjQIm7Bhtwd4GWjWUGdVKZ9VsVOhkeGmm/mlpeBb9ssGoe6q3T6blzwrN8+OojKIpC70E30KhxNIvnfk6TmFZ06Nrvkus/M3EkZWUWbNYq9u3awBMvf1bnyRQXy3fZDiv3DjHYH2GZZM93UAcdaWaFo6kqw+N0uBjg9gH2/aWgBH5aZ6WsEtYfsDF5lD3n9QdslGmcRaCosHS7lfuG2bdz/InquB11pOWqHE1VGN5Vj6sBxp2La1GZs8Yed8N+Kw/fYB+ls36/VVNcRYFvFuTw0sNhyLLE2h1FpGZWcvuIAE6mlLP7cClrtxcx5W4Tn77YmJJShQ++d4wuaRXtjrnAetnD6BUV5v9ZymO3eSFLsO1QJRm5Ctf3duNMpo2DSVVEhuiYdJMXHq4SbWMMjOqt8tq32p+0c7F8v19SwNQHApFliQ17LKRlW7lliA+nzlYSn1hOVLiBf99txNNdplMLN24Z4sMzH2ZhKVNZtK6I1x+xnxwvWluk6ckS5+J+91se0yaakCX7FIizWVXcNsyPk2cr2HukjHU7S3j0jkA+eq4RJaX2R1gC+HrpmDbRhKKq5BXa+GRejuaYf7Vu/9hUyKN3mpj5XASSJLFuRxFn0rXtyDYFPvgiiQ9ebYssSyxfk0lySikP3tmEoyeK2brLzLI/M3jxiZb8/GVXikqqeGVGIgDJKaWs25LDnM+6YLOpfPBFkuYhuTqdnpvum8ZX0yeiKgpd+48hJCKGlb9+THjT1rSJG8jW1XM5fmg7Or0ed08fxk1+CwAPL1/6jbiXmdPGIkkSLTr0oVWnS7cvgiAI/5+JR1heHkm9xBaTJOkW4JCqqscusOxGVVXrfe7f7PVc8yqJe39A/YWugr1Pra+/0FVQ1UBTRn/9z74GiTvs5ovO1LlqAny13aDtSmuoBm3VijP1F7oKSgou7+rwldC+R+w1jwkwokfDfHFX7jLUX+gqUK/2pPoLSNz/l/vC/5bgRsb6C10FRfl/b3rfX2VtgINQQ8QEyE5Oa5C4U1/VNuLsahjVSTzaUhAETRrmx/I18sWqa39OeyVMGtYw9XLJ6RKqqi4AJEmSBkmS5HXeYu3PGBQEQRAEQRAEQRAE4X/eJTsZJEl6DPgd+BdwWJKk0bUWv3U1P5ggCIIgCIIgCIIgCP8s9Y2BmwB0VlW1RJKkJsACSZKaqKo6i//xITGCIAiCIAiCIAiCIO7JcHnq62SQVVUtAVBV9bQkSf2xdzREIjoZBEEQBEEQBEEQBEGopb5HWGZJklRzl73qDodRQCDQ9mp+MEEQBEEQBEEQBEEQ/lnq62S4B8is/YKqqlZVVe8B+l61TyUIgiAIgiAIgiAIwj/OJadLqKp69hLLtl75jyMIgiAIgiAIgiAI/z0a4Enc/2j1jWQQBEEQBEEQBEEQBEHQRHQyCIIgCIIgCIIgCIJwRdT3dAlBEARBEARBEARB+H9L/cc+w7JhHggpRjIIgiAIgiAIgiAIgnBFXPWRDFEPd6i/0BV2es6eax4TIPL29g0SV+faMH1Fg1/d2yBxJzRec81j6g9tv+YxAcw7DzRI3LQ+8xskblWlcs1jPmd4/5rHBBj/4z0NEvebtj80SFxbfv41j/lBt7eueUwAXx9dg8S1lPo0SNyerSuvecyvf8q75jEbkty7TcME3nKIFfFV1zzsiE6Gax5TEARBuHLESAZBEARBEARBEARBEK4IcU8GQRAEQRAEQRAEQbiIf+wtGRqIGMkgCIIgCIIgCIIgCMIVIToZBEEQBEEQBEEQBEG4IsR0CUEQBEEQBEEQBEG4COXa35v8H02MZBAEQRAEQRAEQRAE4YoQnQyCIAiCIAiCIAiCIFwRopNBEARBEARBEARBEIQrQtyTQRAEQRAEQRAEQRAuQjzC8vKIkQyCIAiCIAiCIAiCIFwRDTaSwb93T2KefwZJlslYsIjUb2Y7LXcNC6X5G69gCPDHWlhE4jPPU5mVjV/XOKKnPl1TziOqCQlPTsW8dn29MY8e2MzvP7yNotjoNuBmBt4wwWn5tjXz2fbnPGRZxsXVg1vGv0JIeAwA6SnHWPjNq5SXlSDJMlNen4/BxVVTrgF9ehL7wrOgk8n4ZREpX31XJ9eW01/FEOBPVWEhiU89T0VmNn7duhAz7alauTYl4fFnyV1Tf64A/r16Ej31aSSdTObCxaR+e942Dg2l2esv12zjo1OnUZmVbV8WEkKz117CNcSEqsLhyY9SkZ6hKe7Z45vZsewtFEWheZdbaN/PeTsf2vI9x3cvQNLpcPMIoM/Nb+Dt36hmeWV5CQtnjiKy1SB63vCippjb9ifw/g8LUBSF0QN6ct/ooU7Ll27cwUc/LSYowBeA24b248aBPQH4eO5ituw7AsCDNw1naI/OmmICbD2Zzrt/7kFRVW5sH8MDPVs7LX/vz73sPpMFQLnVSp6lnM1P3kZ6YQlPLtiEooJVUbg9rhm3dmqmOa5bqw743foASDKWbWspXr3IabnOP5CAe/+F7O4Bso7CxXMoPxIPgKFRJP7jHkJ280BVFbLeeRasVZriRodKDOskI0mw76TCtkTnbt1uzSU6RssoKpSWqyzdqVBYCiY/GNFFh6sBFBW2HFFISNHWJRwTJjGiqx5JgvgTNjYfdr69b89WMp1idSiKSmkFLNpqpdBiX3b3YD3hQRIpWSo/rbNqinfO1qSzzFi5C0VRGdMplgd6t3Na/u7KXew+bf9OlFfZyLOUsWXqnRzNNPPW8h2UVFShkyTG92nHsDZNNcdt18yVu0f5IssSG3ZbWLqxxGl5iyYu3DXKl8YhBj75OY9dh8trlvXp5MGNA7wBWLy+mM3xpf/V+W47ncV7mw5hU+HG1o25P875O/D+pkPsOZtrj2m1kVdawcZJIwHIKC7l9TX7ySopQwI+Gt2DMB8PTXGjQyWGxcnIEuxLUtia4Lwvdm8h0TFGRlGgtEJlyQ6FQguY/GFkFx0uBvsVjc1HFBLOaL+0kXJ0M1t+fxNFUWjV7RY6DZzotHz/xtkk7rS3je6eAQy87U28A+xtY3F+Out/fYGSgkwkJEaO/xKfgHBNcaNCYEhH+/f2wCmV7UedP3PXZhIdoiT797YClu1SKCoFHw+4pbeMBMgy7Dmhsu+k9nwP79vKL9/NQFEUeg8aw/CbHnBavnHVr2xYOR9ZlnF18+CuSS8SFhGNtaqKOV++zpmTCciSzG0PPE3zNl00xWyo70+3Tv5MmRCDLEss+zODOQtSnZYb9BIvPNGC5tHeFBVX8dKMBDKzKwC465YIRg0JRVFUZn6VxK59+ZrjBg7pTasEGlsAACAASURBVKt3pyHpZFK/X8Cp9792Wu4WEUa7L97EJTCAqvxCDjz4NOVp9mNS89efJHh4PwCS3v6cjIV/aI6buH8Li354G7X699Tg0eOdlm/9cz5b//wZqbpubxv/CiHh0ezdsox1yxy/RTJSjvPkW7/SqEkLzbEFQRCE/34N08kgy8S++BwHH5xERVYWnX75CfP6jZSePFVTJPrpJ8j6fRlZvy/Fr1sXop54jKPPvkDBrj3svWms/cP7+tB15VLyt26vN6Si2Fg0+00mPvc1vkYTs14YS6tOA2o6EQA69RxJz8H29z6ydx1L58xgwtSvsNmszPt0KuMenk5YZAssxQXo9Bo3nSzT7JXn2X/fQ1RkZhG3cC656zZQmuTINWbqE2QuXkrmoqX4de9K1JNTSHx6GgU7d7PnBkeu3dcsI29L/bmeixvzwlQOTZhMRWYWHedXb+NTjrhRT/2b7CXLyVqyFL+uXWj6+L849pz9pL759NdJ+eobCrbvRHZ31zxGSFFsbFvyOsMf+BZPHxNLPruNxi0G4G9ybGdjaEtGP/Irehd3EnfMY/fK9xg47sOa5Xv//IiQJnHa8gRsisKM2b/wyfOPYjL6ce+0d+nbuS1R4aFO5Yb06MQz99/m9NqW+MMcTU7lp7enUlVl5aHXZ9GzfSu8PNw1xX171W4+HzcQk48Hd85eSb/YcKKDfGvKPDXE0WExb/cxjmXlARDk5c5/7h2Gi15HaWUVt3y9nH6x4QR7azhJkmT8x04g+6PXsBWYMT37DmUHd2PNPFtTxOe6Wyjduw3L5lXoQ8IJemQaGS9OBlkm4L4p5H0/i6q0M8ieXmCz1R8TkCQY3lnmp/U2ispg/FAdx9Ns5BY5ymTmwzerbFht0DlGYlAHmd+2KVTZ4PftNvJKwMsdxg/TcTLDRkU9fRuSBKO66/nP6iqKSuGhkXqOpirkFDrKZOSpfLmsiiobdGkuM7Szjl832XPaetiGQQ9xzXSacjzHpihMX7GTL+4eaq/br5fRr3ljooP8aso8Pbxrzb/n7UzkaKYZAHeDntdv7EOk0Yfs4lLu+GopPWLC8HGrv1NSkuC+G/yY/m0ueUU2Xn8kmPjEctKyHR0kuQU2vlyQz8g+3k7rerpL3DTImxc+yUZV4c1/BbM3oYzS8vq/uw2Rr01ReXvDQT4b0xOTlzt3z99Iv6YhRBl9aso82bdtzb9/PnCKY7Uq/uXV8TzQpRndGwdTWmlFkupNE7Bv4+u6yMxZZ6OoFMYP13HsbN39+Os/qvfjWInBHWUWblGossLi7Tbyiu378YTrdJxMr38/BnvbuGnRa1w/8Tu8fE0smHUrTVoNJCDE0TYGNWpJ68cXYHBx5/C2eWxb/h7D7ra3jWvnPUvnwZOIaNaLqgoLSNoGIkoSDOssM2+DQlEZ3D9E5kS66pRvVoHKd3+qWG3QKVpiYHuJxdtVSsrhP2sUbAoY9DBhuMyJNPvr9eZrszHv6+k8/tIX+BtNTH/2Ttp16UdYRHRNma59rqPfsFsBOLB7A79+/z5TXvyMzWsWAvDyhwsoKszj4zce4bl3fkKWL51zQ31/ZBmemBTLv188SLa5gm8+6MSWnWZOpzo6KUYNDaW4xMrtD+1iUJ8gJt8XxcszEmkS4cHgvsHc/chuAo2uzHy9HeMm7dL2qDRZpvWHL7Fr1AOUp2XRa/OvZC9fR8nRkzVFWk5/hrS5v5P202KM/brR/NUnODD+WYKG98O3Qyu2dB+D7OpCt1U/kLN6E9ZiS71hFcXGwtlvMOn5r/EzhvDhtLG06TyAkHBH3XbuNZJeQ+y/Xw7vWc/vP87goee+pHPvUXTuPQqA9JTjfPf+Y6KDQRAE4X9Qg0yX8GnXhrKUVMrPpqFWWclesQrjwP5OZTxioijYuQuAgp276ywHCBo6hLzNW1HK6//Fk5J0CKMpAqMpAr3ehQ49RnBkr/OIADcPr5p/V1aUce5X6/GD2wht3IywSPuB0NPbD1nWdtLi064NZWdSKU+155q1fCWBg5xz8YyJJn97da47dhE4+AK5Dh+CedMWTbkCeLettY2tVnL+uMA2jo6iYFd13F27MQ6wL/eIikLS6SjYvhMApaxMc9ycswfxMTbGJyACnd6FqHYjSElc51QmLLobehf7SXxQ4/ZYCrNqluWmHaGsJJdGsb00xQM4knSaiJBAwk2BGPR6hvToxMY9BzWtm5yWSceWMeh1OtzdXIlt3IjtBxI1rXs43UyEvzfh/t4YdDqGtYpkw4nUi5ZfmXCa4a2bAGDQ6XDR2/ehSquCehkTvVyaxFCVk4nNnAU2K6V7t+De/ryrfKqK7GbfxrK7B7ZCe+eGW8sOVKWdpirtDACKpQRUbQ/+DQuA/BKVAov9WcFHUhSahzuf2Z3Jtp+oAKSZVXw87MvziiGv+oJiSRmUloOnhoFA4YESeUUq+SVgU+BQskKLCOdmKzlTpao6ZmqOiq+n4zOdylQ1nQCe73BaLhEBteq2dVM2HE25aPk/Dp9ieJsoACKNvkRWnygHe3sQ4OlGvqVCU9zoCBeyzFZy8m3YbLDjQCmdW7o5lcktsJGaaa2zz7Rr5sahExVYylRKy1UOnaigfXPndf+b8j2SlU+Enyfhvp4YdDJDYxux4VTmRcuvOnaWYc3sV/VPmYuwKirdGwcD4OGix92greO3kRHyi1UKSqr34zMKzSOc9+PTWbX249zz9uNi++slZWApB09tm5jslIP4Ghvja7S3jTEdRpB8ZK3zZ4vpjqG6bTRFtsdSaN8eeZlJKIqNiGb2dtHg6llTrj5hAZBfTM33NiFFJbbR+d9bnL633tX5Kor9ewegl0FjPw4AyUmHCQ6JICgkHL3BQFzvYRzYvcGpjHutY25FeRlS9TE34+wpWrSxd2r5+Abg7unNmZNH6o3ZUN+flrE+nM0oIz2rHKtVZc2mbHp3MzqV6d3NyB9r7ce6DVtz6Nzev+b1NZuyqbKqZGSVczajjJaxPnViXIhfXDtKT6ZQdvosalUVGQtWYBo1yKmMV4tozBt2AGDeuJPg6uVeLaLJ27oH1WbDVlpG8eFjBA7poyluStIhAkMaE2iKQK830LHHdRze43ycv9jvqdr2bVtBx57XaYopCILQ0BT1n/lfQ2mQTgaX4GAqMh0/JiuysnA1BTuVKTl6nMAh9oNh4JCB6L280Pv5OpUJGjGM7BXahvcV5mfhZ3Rc2fYLMFGYl1Wn3NbVc5n++HCWzf2AG+95HoCczNMgSXw1fQIfPn8L65d+qykmgGtIMOUZtXLNzMbVZHIqU3L0GEHDqnMdOuiCuZpGDid72UrtcYODqch05FeRlYVLcJBTGcux4xgHDwTAOLh6G/v64t6kMdbiYlrNfI9Ov86j6ZOP2y/VaFBamI2nb0jN3x6+JixFdbfzOcf3LCS8mf2Hjaoo7FzxDt1GPKM5T4Cc/EJMRv+av01Gf3LyC+uUW7drP+OeeYtnP/yGTLN9OGpspL1TobyikoKiEvYkHCfLrG2oanZxGaZaw7NN3h7kFJddsGx6YQnpBSV0iXTUfWaRhdu+Xs51nyzivu6ttI1iAHR+Adjyc2v+tuXnofN1/kFbuHw+Hl37EvrmVwQ9Mo38+fZ9Vh8cCioEPvoipqnv4j1ktKaYAD4eEkW1Rg8XlYK3+8VPOzpEySRl1O3ACAsAnezodLgUbw8otDhayKJS8PG8eMzOsTIn0rR1mlxKdnEpIT6eNX+bfDzJLr7w0On0Anvddm0aUmfZobQcqmwKEQHeF1izrgAfGXOhY2RJXpENf19tHZr+Pjryzl/XR9u6DZFvdkk5Ji/HibLJy50cy4U7MzOKSkkrKqVLuL0NO1NgwdvVwFPLd3HH3A3M3HIEm8Yjqbe7ROHl7MfRMknpF9iPjdX7cbGmsFgKs/DycxyDvPxCnDpYz5e4cwGNW/QFoCD3NK7u3vzx/b/45YMxbFs6A0XRNgLJ2x2KyhzbprjU/trFtI+SOJXhKO/tDuOHyTx6vcyOo9pGMQAU5GXjH+jYR/wDTBSYs+uUW//Hz0x7eBS//TiTsQ/Y2/7wyGYc2LMBm81KblYaKScTyM+9+LY6p6G+P0FGF7JzHR1rOeYKgoyu55VxJTvXvvFsClgsVnx99NWv11o3t4Igo4umuG5hJsrTHNMYy9IycQ1z/n1RfOgYIaOHAGAaPQSDjxeGAD+KD9k7FWR3NwxGP4x9u+F+3ui/iynIz8bP6KhbX6OJwvy6dbtl9TzemDKcpXPf56Z7n6uzfN/2lXTqOUJTTEEQBOGf5ZJnjpIk+UiSNF2SpB8lSbrjvGWfXc0PdmrGB/h26UynhT/jGxdHRWYWqs3xQ88lKBDPZjHka50+oFGvoXfw3MyVjBz3b9Ys/gKwD/tMPhbPnY/M4JGXf+Tw7rWcOLzjisVMevsD/LrGEff7fPy6dqY8M8tx+YjqXJvHkLd52xWLCXDqvQ/xi+tMp1/n4RfX2b6NFRuSTo9vp46ceu9D4m+/C7fwcEJuvOGKxgZI2reE3LTDtOv7IACJO+cR0byvUyfFldKnUxuWfPQq82Y8T7e2LXj1sx8B6N6uJb06tOKBl99n2sezaRvbtN4huX/FqoQzDGrRGF2t9w7x8eSXCSP5ffINLD2UjLnkwh0Uf4VHXB9Kd6wnY9pEcj59E+N9j4EkIel0uEa3IG/2TLLfn4Z7+264Nm9b/xteprZNJEIDJLafd88GLze4sYeOJTu1nSBdjnZRMmFGiS2H/34nw+VYdTiZwS0jneoWIKe4lBcWbebV0b2QtY7l/wdoiHxXHU9jcEwYOtn+vjZFZV+6mcd7t+aH2/uSVmhhaeLFR178VW2bSIQZJbYlXGA/7qljyfYrvx8DHNu7hJyzR+jY3942qjYrGcl76Xn9M9wy5VeK8lI5untRPe9y+VpH2r+3O2rds6G4DL5ZpfD5coW2TSRNI5Aux4DrbufNz5Zx091TWLHQfj+BXoNuxN9o4q1n7uCX2e8S3bz9VWmX/z9IfH4GAX260Gv7bwT07kJZWiaqzUbu2q3krNpIz/Xz6Pj9++Tv3I+qceqcVr2HjuOFWSsZdccTrF70pdOyM0kHcXF1JzQi9orGFARBEP471HfUno19hORC4HZJkhZKknTuJ0b3i60kSdJESZL2SJK0Z2mBuc7yyuxsXEMcJ5KuJhMVWc694JU5OSQ89iTxN99O8qyPAbAVOy4ZBQ0fSu6a9ahWbTdz8/U3UWB29PgX5GXhG2C6aPkOPUZwpHr4n2+AiagWnfH08cfF1Z0WHfpwNjlBU9yKzGzcQmvlGhJMRZbzFZnK7BwOP/IEe0aPJfkDe67WWrkGjxhK7up1mnMFqMjOxjXEkZ+ryURldo5z3JwcEh5/ivhbx5E86xMAbMUlVGRlUXL0OOVn08Bmw7xuPV4ttc2Z9PANrhniC1BamIWnT93tnJa0jf0bvmTI3Z+h09uv2mSn7Cdh+1zmzxjErj9mkLTvd3avfL/emEH+vk6jD7LM+QT5O48E8fP2wsVgAGD0wJ4kJjtOSB4YM5y5bz/Hp9P+BapKZKjzqJqLCfZ2J6vWpf2s4lKCLnKJcFXCmZqpEnXfx4OYIF/iU3MuuPx8toI8dP6BNX/r/AOwFTp/z7x6DqI03t4pVZl8HMngguzpjTXfTEVSAoqlGLWqkvIj8bhERGmKW1SqUvu+ej4eUFxW9+pxU5NE71Yy8zfZaveV4aKH2/vpWH9QIa1us3BBxaU4TX/w8YAiS92YUaES/drqmLvO6hTzrwr29iCzyDE3OavIctGRJiuPJDO8rfM2LKmo5F9z1/DowE60C9e2PwHkFSkYa115DfDRkV+o7Yd/fpGNgPPXLdK2bkPkG+zlRlatjrWskjKCLjL3YPXxNIY1d9zk0OTlRvNAX8J9PdHLMv2jQjmaXaApbnGZiq+W/ThEoncbmZ831N2Pxw3QsX6/9v0YwNPXREmB4xhUUpCJp2/dtjH1+Db2rv2C6+53tI2efiEEhrXA1xiBrNPTtM1gctO0HYOKy8Cn1kgNbw/7a+drYoJerSR+3axc8DtUUg45hSoRQXWXXYhfQDD5uY5jQX5eFn7Gi+8bcb2Gs3/XBgB0Oj233f80L77/Cw9PnUlpaTHBYZH1xmyo70+OuZLgQEfvS5DRlRxzxXllKggOtO/fOhk8PfUUFlmrX6+1bqArOeZKTXHL07Nwa+QYfeDeKISKdOffFxUZ2cSPe4ytPW7i+CszAbAW2n9fnJzxJVu6j2HX9Q8iSRKWpNOa4vr5B1NgdtRtoTkLX/+L1+2FplPEb/tDTJUQBOEfRVX/mf81lPo6GaJVVZ2qqupiVVVvAOKBdZIkGS+1kqqqX6mqGqeqatz1fnWLFh06gntkY9wahSEZ9ASPGIZ5/UanMno/v5o5fI0nPEjmb4udlgePHE7Ocu13Qo6IbkNuZgrm7LNYrZXs376C1p0HOJXJyThT8+/EfRsJDLH/qGnerheZqSeorCjDZrNyKnEPplo3OLqU4kNHcG/SGLfwRkgGPaaRw/k/9u47OoqqfeD4987upvfeQ0LoHUIRpEgHUcSKglhBURG72EWxo1hee2+IP1EEBUR6b6HXQKjpZTfJpie7M78/JiRZSrJoIK++93MO57A7d/bZZ3J3yp177+Qtd8zV5F8n17vuIGvuabmOGkH2eQyVACjauw/3mOptbDQSPGIY5pWrHMo4buPbyZo3v2Zdo483Jn99CIJfj+6U1JmUsz7BkR2w5p2gyJKG3VbJ0d2LiGnjuJ3zMvaz/tfnGXLz+7h71daPATe8wdjHV3DDY8vpMeIxErqMpvvwhxuM2bZ5LCezcknPyaPKZmPpxu306+Y4M35eneETa7btIS5Sb/ixqyoFRXq//cMn0jl8MoOeHZ1rUGkXEcjJ/CLSC4qpsttZsv8EA1qcOdv7sbxCrOWVdIqsbRjItpZSXqU3GlnLKtiRlkuzQOe61FeeSMEUEo4hMAQMRjy6XUrZ7iSHMrb8XFxb6dvAGBaJMJpQi62U79+JKSIWYXIBRcG1RTuqss49j0RdGRYI8Bb4eeqjZ9rFKBxKc9x7hfnDyO56A0NpnXNsRYHr+yrsPq5yINX5PV56nkaAj8DPSz8x7xCncPD0mAGCKy8x8v2KKs7R2/68tYsM4qTZSnp+kf633XeM/q2izyh3LK8Aa1kFnaJqr7yq7HYe+nElozo1Z0jbZucV92haJWFBRoL9DRgM0KuTB9sOOJfU7kPldGjhioebwMNN0KGFK7sPObduU+TbNtSP1IIS0gtLqLKr/Hk4nf7xZ/ZiOmYpwlpRSccw/zrr+lNUWUV+dSXbmpZLvJNDUtLNp9Xj2LPX48t7KPy4+sx6fEN/hd1Hz68eA4REd6Aw7wRWs75vTNm5iLh2Ax3K5KbvZ/XPzzHytg/w8A50WLeirIiyYn1ulfTDm/APde4YlGEBf2/wrc63bYzgcLrjdw/1gxGJCj+tVR3y9XaH6qljcDNBVLDA7OTwkGYJ7cjJPEledjq2qiqS1i2hU2J/hzLZGbXH3D3b1hISHgPoY/gryvWWkP27NqIoRocJI8+lqX4/Bw9biY5wJzzUDaNRMLhfCOu3OLZArd9sZsQgvVFpQJ9gtu/WG8bXbzEzuF8IJqMgPNSN6Ah3Dhy2nhHjbAq37cEzIRb32EiEyUT4tSPJXuh4MW8KrD3ON390Emnf6JNqoiiYAvSJXb3bt8S7fUvylq13Km508/bk1pxPVbFj4+J6z6f271hDUFhMzWtVVdm1aQldLpGNDJIkSf9WDc2U5SqEUDRNnxlO07SXhBDpwBrAq/5V62G3kzLjVTp89iFCUcj6ZT6lKUdoNmUyRXv3Y165Gr8eicQ9dD9oGoVJ2zj8wiu1XyoiAtewMAq2bnM6pMFgZMytT/Hpq5PQVJXuA8YQFpXAHz+9R3R8O9p1G8j6P2dzeO9GDEYj7p4+jJ38MgAeXr70G3kL7zx9AwhBm859adulfwMRdZrdzqHpr9Dpiw8RBoXMub9SmnKEuKn3YN2zD/OK1fj1TCT+4ftBg4Kt2zg0/eWa9d0iI3ALC6NgS1I9Uc7Cbifl5ddo//EH+iMs582n9MhRYu+dTNG+/VhWrcaveyJxD0xB0zQKt20nZUb1NlZVjs58iw6ff4RAULT/AFlzf3EqrGIwcsmVT/PHl3eiaSotu12Nf2gLti19l6Co9sS2GcjWxW9QVVHKih8eBMDLN5whE/766BujwcBjt17P/a+8j13VuHJAL5pHh/PRT7/TJi6G/okdmfPHKtZs24PRYMDHy4Pn7h4PgM1mZ9J0/e6Op7sbL9x7C0aDc+NwjYrC40MTuWfOClRVY3Sn5jQP9uOD1btoGx7IgJZ6g8OS/ScY1ja2ZlIzgGPmQt5atl3vJ6TBhJ5taBHif45Ip1FV8n/8jOD7nkEoCsUbV2DLTMVn1FgqT6RQvieJgp+/JmDcZLwHjgJNw/yt3lNFKyuhaMVvhD7+OqBRtm875Xu3OxVW0+CPJJWbBhiqH4WnkmuF/h0UMi0ah9I1BnVWcDHBNZfq29BaovHjWpV2MYKYEIG7q6BT9dMNF2yyk93AzWdVg4WbbUwYbEJR9EdY5hZoDOxsIN2skpyqMaybARcj3DBA350VlsDs6sdV3jHcSJCvwMUID19rYv4GGykZDV8cGhWFaSN7Mfm7paiaxujOCSSE+PPByh20jQhkQCv9hPmPvccY3j7O4W/7577jbD+RRUFpOQt2pgDwwlWX0jqs3rZZPV8VvlpQwOO3B6EIWJ1UQnqOjWsGe3MsvYrtB8qJjzLx4PhAPNwFXdq4c81gO4+/nUNJmcavK4p48T79juK8FUWUnOUO/X9LvkZF4bEBHblv/kbsqsbodjE0D/Thw00HaBviR/94/Q7tn4fSGdoy0iGmQRE8cGk77p63AQ2NNiF+jGnfzKlcNQ0WJ6mMG6jX451H9KeVDOiokGHW6/HgLgouRri2uh4Xlmr8uLpOPXYRdKruzDF/k51sJ6ZxUQxG+o55ht8+vQNNU2nd/RoCwlqw5Y93CY5uT1y7gWz8Xd83Lvn2AQC8/cIZefuHKIqB3lc8xvyPbwVNIziqHW17Xud0vn9uVxnbX39k566j+pMl+rUXZFo0DmfAwE56vlf3VqrzhbnrVAJ9YHBnBQ19V7X5oObwZJf6GAxGxt45jXdenIyqqvQZOJqImAQW/PABsQlt6dR9AKsWz+HA7s0YjEY8PH247b4XALAWWnj3xXsQQsEvIITb75/hVMym+v3YVXjroxTemt4BRREsXJbFsZOl3DGuGQcPF7F+i5nfl2byzENtmPNxD6zFVTz/uj7B8LGTpaxYl8t3H3THbtd466MU554sgX5+se+hF+mx4HMwKKR98zPFB1Jo8cwUCrfvJWfhSgL79qTVCw+CBpb1W9n3gL6NFZORXku/A8BWVMzOOx5zeriEwWDkmluf5ONX7tIfCT5gDOHRCSz+6T9Ex7WjfeJlrP1zNof2bKr52940ufa85ujBJPwCwwgKPbMhU5IkSfp3EPXNai+EeB34U9O0Zae9Pxx4T9O0BgfTrW7T+aJ31LB+d54X5I3Ea2y3hgtdAAbXphmrumm68408jenuuOUNF2pkxj2NO/eHs8ybdzVJ3K/6/tgkcasqL+58CgBPmBoeknMh3LlnQpPE/azDN00S157v3ISqjektv5cbLnQB+Do5YWBjKym9+L8fgN7tnOve35g+/d5y0WMCnNib0iRxn1x+V5PEZd2eJgk7squpSeJKkvS3/HsmoDqLN39tysEHf93DVzXNxGD19mTQNO0xIURrIcQgYLOmacXV7/8hhLj/onxDSZIkSZIkSZIkSWoiWlM+D/JvaZq2n4aeLjEFmA9MAfYKIeo+7+6lC/nFJEmSJEmSJEmSJEn6Z2loToZJQDdN04qFEM2AuUKIZpqmvcO/vEuMJEmSJEmSJEmSJEnnp6FGBqXOEInjQogB6A0NschGBkmSJEmSJEmSJOlf7h87WqKJNDRjYLYQovOpF9UNDqOAIKDDhfxikiRJkiRJkiRJkiT9szTUyDAByKr7hqZpNk3TJgD9Lti3kiRJkiRJkiRJkiTpH6ehp0uk1bNsfeN/HUmSJEmSJEmSJEmS/qkampNBkiRJkiRJkiRJkv5naXJOhvPS0HAJSZIkSZIkSZIkSZIkp8hGBkmSJEmSJEmSJEmSGoVsZJAkSZIkSZIkSZIkqVFc8DkZ3PxcL3SIM1js4qLHBPAIcmuSuBVFlU0St6TE3iRxLT6xFz1mWNCRix4TwCPEv0niFhY0TZ0KDLz4+ws1v/iixwSoLG+abaxVVTVJ3PJs80WPWWxomlwrq9QmiWtroriW0ov/uzUYm+Yeicm9aY7zBndDk8QttV387ex9dWeWXfSousFpe5oosiRJ/+1UVU7KcD5kTwZJkiRJkiRJkiRJkhqFbGSQJEmSJEmSJEmSJKlRyEdYSpIkSZIkSZIkSdI5yEdYnh/Zk0GSJEmSJEmSJEmSpEYhGxkkSZIkSZIkSZIkSWoUspFBkiRJkiRJkiRJkqRGIedkkCRJkiRJkiRJkqRzkHMynB/Zk0GSJEmSJEmSJEmSpEYhGxkkSZIkSZIkSZIkSWoUspFBkiRJkiRJkiRJkqRG0WRzMvj26kXsAw8hDAo5CxaQ+e03DstdwsKIf+ppTH5+2KxWjjz/PJW5OTXLDR6edPxhDpY1qznx5kynYibvXstv376CptrpPuBaBlwx0WH5puVz2LjsBxRFwcXNk6tvf57QyISa5QV5Gbw17QoGj7mXfpff/l+dK4B/n940n/YowqCQ9fOvpH7+pcNy1/BwWr74HKYAf2yFVg5Oe4rKbD2ua1gYLV94FtewUDQN9k6+j4qMTKfiJkQIRnQ3IARsT1FZt1d1WH5JG4WuLRRUDUrLNX7diNY8KgAAIABJREFUYKewRF82fpCBqGDByRyN2SvsTue6NWkbH33yKXZVZcTQIdxw/XUOy/9cuozPvviSwMBAAK684nJGDBsGwJPPPMfB5GTatW3Di88/53RMgPUHjvPar6tQVZUxvdpzx6AeZ5RZsjOZj5ZsAqBVRDCv3jwSgFm/rWHN/mNoGvRqGcPjYwYghHAqrimhHZ7DbwRFoXz7WsrXLXZYrvgG4HXV7Qg3D1AUSpf9TNXhPQh3T7yvn4wxshkVOzdQsmj2eeXbKlph9KUuKAI2H7CxcofNYXl8uMKVfVwIDxR8v7SS3Udr/4aX9zLRJlavF4dS7cxfX+VUzPgwGNxZQRGw85jGpoOOg+K6txR0jhN6faqAhVtVrKXg4wHX9FEQgKLAthSNHUecH1C3/lgWM1ftxK5qjOkQx209Wjssn7lqJ0mpuQCUV9mxlFWw5t7RACTOmktCkC8AYd4evH1VH6fjdm7tzm1jAlCEYPnmIn5dXuiw3GiAKeOCiY9ypajUzqyvc8nNt2FQ4O6xQcRHuqIYYPXW4jPWrTffIxm8sTQJVdO4qlMCt/du55jv0m1sPZGt52uzYSkpZ+3D15NRWMzDc9egamBTVcYmtuS6ri2djmtKaI/nyBsRQlC+fS1la89Sl6++A8XNA4SgZGmdujz2HkwRzSjfuZ6Shc7X5ZbRCqP7mBACthyws2qnYz2OC1e4sreJsEDB7GWV7Dlauw8b2ctI6xi9Hh9OU1ngZD0GaBEpGNnDiCJg22E7a/Y47ht7t1VIbGlAVTVKymHeehsF1fvGLs0V+ncyALB6l50dR9TTP/7c+UYpXHGJESFga7Kd1bsc961xYYJRl5gICxD8sKKKvcdqP3t4DyOto/X7ESt22Nh91Pm4ybvX8vu3L6Oq6lmPuZuXz2HjstkoigEXNw/G3D79jGPurGlXMOg8jrkdElwZf7kPioDV20r5fW2Jw/JWsS6MG+lDdKiRD34qYOu+8pplj0zwp3mUC4dPVvLWd/lO5wnQvZMv990Wi0ERLFyeww/zHY+XJqPgifua0zLeE2uRjelvHyY7t5JuHXyYNC4Go1Fgs2l89O1JduyzOh03aOCltH5lGkIxkPbdzxx75zOH5W5R4bR/bwYugf5U5Reye/I0KjL033HL5x4meGg/UATmVRs5+MQrTsf9q+dTltx03np8FMHhzQCISejEmNuedypm4IA+tJz+OMJgIP2HXzjx/ueOuUaG0/bNFzAFBmArKGTv/U9QkannmvDUgwQN7IdQFMxrN3Lo2VedzlWSJAlAlZMynJemaWRQFJo9/CgHp06hMieHdl98RcHatZQdP1ZTJGbK/eQtXkTeokX4dOtG9OR7OPLC8zXLoybdhXXnDqdDqqqd+V/P4I7HP8M3IJT/PHsDbbpe5nBC07n3KHoNGgvA/u0rWPj969z+2Cc1y3+f/TqtOvb9r8/1VNyEp6exZ+JkKrKy6fLj95hXrqb06NGaIvGPPEjOgoVkL/gNvx7diXtgCslPPANAq1de5OQnn1GwcTOKu7vTs50IAZf3NPDNUhvWUpg00khyqkpunWudTIvGJwttVNmhe0uFod0M/LRGP+ldv0/FZITEls53srHb7bz/4Ue8MuNFgoICmfLgQ/Tq1ZPYmBiHcv369eW+yXefsf5111xNRUUFCxcvPmNZvXFVlZd/WcHHd19NqK83N82azYB2zWkeFlhT5kRuPp8v38rXU27Ax8MNc1EpADuPZbDzWAZzH70ZgFvf+z+SjqTRPSG64cBC4DlyHNZv30K15uM78Wmqkndiz609qXXvdzkV+5KoSFqFITgc73FTKXh7GpqtitKVv2IIicQYEnle+QoBY/q68MlvFRSWaEy9xo39x+1k59fWjfxijR9XVNC/s8lh3dhQhWZhCm/+n35Cf+9VrjSPUDiSUf8FixAwtKvCnNUq1jK4dbDC4QwNc51z8Ox8jS+PaNjs0KW54LKOgvmbNIrL4ZvlKnYVTEa4c5jC4XT9/YbYVY3XVuzgg2v6Eurtwfjvl9O/eQTxgT41ZR4Z0Lnm/3N2pHAwp6DmtavRwJybhzQc6DSKgDuuCeTFj7KwFNh45cEIkvaWkpZdeyE7sJc3xWUqU15Oo3cXT8Zf4c+sb3K5pLMnJoPg4TfScTEJZk2LZP32EnLzbfVEPJWvyqtLtvLhjQMJ9fFg3Jd/0L9FFM2DfWvzHdKt5v8/bE0mOdsCQLCXO1/fMgwXo4HSyiqu/XQh/VtEEeLt0XDCQuA1ahyFX7+Jas3H765nqDzoWJc9+o+icu9Wyrfqddln/APkz3pcr8vL52EMicQQ6nxdFgLGXGri098rKSzRmHK1K/tP2MmpU48LijV+XFlJ/06Oh8hT9XjWTxUA3DPalfgIhaMN1ONTca/oaeTLP6uwlsLdo4wcOHnmvvHD36qoskOPVgrDEg38uNqOuwtc1tnAh79VoQH3XGHiQKpKeaVz+Y7uY+TzRVUUlmjcd5ULB06o5BTUzRd+Wl1Fv46O+baKVogMFLz7SyUGA0wa5UJyaiUVTrSrqKqdBV+/yB2Pf45PQCjvP3v9GcfcTr1H0dPhmPsatz/2ac3yhbNfo+V5HHOFgAlX+PD6VxYsVjvT7w5i+8EKMnJrfwPmQjuf/lLAiEs9z1h/0boSXEylDOzuRN2tQxEw9Y5mPDrjILnmSj56pR0bkgo4kV5WU2bkwGCKSmyMv38Xl/UO4K5xMbzwdgqFRTaefC0Zc34VzaLdef2p1lx/t5PHe0WhzetPkXTNRMozsrlk2Y/k/LGSkuQjNUVavfAoGT8uIGPOfAL69qTlMw+wZ/IT+HXvjF/PLqzvOwaAnou+xb9Pd/LXb20w7N89nwoMiWbqS/Ocy7FOrq1mPMWOmyZRnplFj4VzyPtzJSWHa89pWjzzCJlzfyNz7gL8e/cgYdpU9k19Et9unfBL7MKmIdcAkDjvG/wvSSR/Y9L5fQdJkiTJaU0yXMKrbVvK09KoyMhAs9mwLFuKf79+DmXcm8VhTdIPANZt2xyWe7RqjSkggMLNm52OmXpkD4GhMQSGRGM0utCp1wj2b1vhUMbN3avm/5UVZVDnpvK+pGUEBEcSEpXA+WiKXAG8O7Sn7GQq5WnpaDYbuYuXEDhwgEMZj+bxFGzZAkDBlq0EXqYv94iPRxgMFGzUY6plZajlTlyZAZGBAkuRRn4x2FXYe1ytuQt2yvFsjarqG2mpeSo+dc7njmVpVDp/YxCA5EOHiYgIJzw8DJPJxIB+/di4yfnt1aVzJ9zd3c8vKLD3ZBbRQX5EBfphMhoY3qUVq/YecSjzy6Y9jO3TCR8PNwACqy+8hIAKm50qm0qlzY7Nbq9Z1hBjZBx2Sw5qfh7Y7VTs3YKpVWfHQhoIVz2mcHVHLaq+AK6qxHYyBWznuZGBmBAFc6GGpUjDrsLOFBvtmhkcyuQXaWRatLO2SZmMAoOi34k3KFBU2nDDVUQA5BdDQQmoKhw4qdEywrG3x8lcsFXXpwyzho+HvlxV9ToIYFQcfs4N2ptlIcrPiyg/L0wGhWGto1l1JOOc5f84eJLhrZ1oIGpAQowrWXlV5Jht2OywfkcJie0d60X39h6s3lIMwKZdJbRvodddTQNXVwVFAReTwGaDsgrn7jrvzTAT7e9NlL83JoOBYW1jWXU49Zzl/9h/nOHtmgFgMhhwMer1oNKmop1HS78xKt6xLu/ZgkvrLg5lNE1DuOo5CjePM+qyZmu4EaWu6BCFPGttPd51xH7Wepxl0Tg9Ew0wGhzrcbET9RggKkhgrrNv3HNMpU2M477xWFadfWNubV1uEak3yJVVQnklHMlQaRnp3OE7OlhgPi3ftrGO6+YXV+d7Wiqh/oJjWSqqBlU2yLKotIx2Lm7qkd0EhsYQUHPMHcmBBo65dXty7Utahn9wFKHnccxtHmUix2wnN9+O3Q6b9pTRtY2rQ5m8Ajup2Ta0s/w09h+tpLzi/O9UtU7wIiOrnMycCmx2jRUbLPTp7u9Qpk+iP0tW5QGwepOFru31BsuU46WY8/X98fHUMlxdFExG5/ZWvl07UHoslbITaWhVVWTOW0TIiMscyni1ao5ljX48tKzdTMiIgYD+u1JcXVBcTCiuLgiTkcpcs1Nx/+751F/h27kDZcdPUnYyDa3KRvb8xQQPdczVs0U8lvV6rvkbttQu10BxddVzdXFBMRqpcDJXSZIk6a9pkkYGl+AQKnOya15X5uRgCg52KFOachj/AfoBwr//AAyenhh9fEAIYu+/n5PvvXteMa352fgGhNW89g0Iw5qfc0a5jUtn8/rDw1g8502uvPlJACrKS1i98HMGjbnnvGJC0+QK4BoSQkVWbdyK7GxcQhzjliQfInCwfsIROHggRi8vjL6+uDeLwVZURNu3Z9L1px+Ie/gBvb+5E3w8qBn6AFBYqlHftXPXBP3u8t9hNpsJDgqqeR0UFEie+cwTiPXrN3D3vVN48eVXyMnN/VsxAXIKiwnz8655HeLnRXZhsUOZE7kFnMjN55Z35zD+7R9Yf+A4AJ2aRdA9IZrBz3/C4Oc/oXfrZsSHBuIMxccf1VrblVe15mPwcTyhLV21ANeOvfB76HW8x02lZNEPfzHLWr6egoKSOnc/SzR8PZ07czyRrZKSbue5W9x5doI7yamOd1LPxcsdrHUu4orKwLue9qBOcYIjmbXlvd3hjqEK945S2JTsXC8GgNziMsLqBArxcienqOysZTOsJWRYS+keHVLzXqVNZdz3y5kwewUrU9KdCwoE+BkwF9R2ZbcU2gn0dby7HOBrJK9Av7BWVSgtV/H2VNi0q4SKCpVPp8fw4bPR/LaqkOJS5xoZcorKCK3T2hfq7UHuufItLCajoJjusaE172VZS7j+04WM+M88bu3V1rleDIDi7YdaaKl5rVrzUXz8HMqUrlyAa6de+D/8Bj7jp1J8HsMizsbXEwqLa+tIYbGGj5P1+GS2ypF0O89McOPpm91ITrM7VY/h1L6xtqy1hJpGhLPp1kLhcLr+9/M+bd3Ckvr3qw5xPYVjviXO55tp1mgZZcBkAA9XfTiUn5PrWvNzHI65PgGhFOZnn1Fu49LveePhofwxZyZXOBxzPzvvY66/jwFzYd3fj4q/t6GeNRpHUIALOebabiW55kqCAkznLKOqUFxqx8fb8bfdr2cAh4+WUGVzrk65hYdSnl7b66c8Ixu38FCHMkV7kwkZNRiAkFGDMXp7YfL3pTBpF5Z1WxiwfxUD9q8ib8V6Sg4dxRl/53wKwJKbzjtPX83HMyZwLNm53gSu4SGUZ2bV5pqVjetpuRYfOETISD3X4BGD9Fz9fCncvov8DVvou20F/bavwLx6PaUpx5AkSTofmvrP/NdU6r1yFEKECSE+FEK8L4QIFEI8L4TYI4T4PyFE+IX8YiffexefLl1o//U3+HTpSmVODpqqEnrNNRRs2OAwZ0FjumTITTz25hJG3PAQK+Z/DMCyX97n0uETcHU7s3tlY2iqXI/OnIVfYje6/vQDfondqMjKRlPtCIMR365dODpzFtvHjsctKoqwq65s9Pgd4wQRgYL1+y78L6BXzx58/eXnfPT+e3Tt0pmZb719wWOCPkb9RG4Bn917Ha/ePJLpPy3FWlbOydwCjmVb+PO5O1n63ES2HE5l+9G0Rovr2qEHFTs3UPDWYxR9/w5eV9+hd59oIoE+glB/hRe/KePFb8pIiFSIC2/cNs52MYKwAMHmZMdGic//VPlokUqHWIGHaz0f8Bf9eTCVQS0iMSi123fhnSP5ftwgXh7Zg5mrdpFaUFzPJzSOhFhXVA0mPXeSe2ekcsUAH0ICG39E3JL9JxjUOgZDnYbHMB9P/m/i5cyffCW/7TmGufjsDRR/hWvHnlTsWE/+m49i/e4dvK+5s8nqcqCPIMRf4aVvy3np23ISIgw0C2v8tvpO8QqRQYK1e5vw7AA4nK6SnGpn8mgXbhxo4mSOhtrIQ1IvGTKOR9/8k+E3PMyK+R8BsPyX97l0+C0X7Jj736hZlDuTxkXz1qeNe/Gb/NwbBPRJ5JKVcwnonUh5RhaaXcUjLgavlvGs7jCI1e0HEti3J369ujZq7LOdT/n4BTPt7eVMnfELl497nDkfPEZ5WePsHw+9OBP/Xon0/OP/8O+VSHlmNpqq4t4sGs8W8azrPpi1iYPw79MTvx6Nm6skSZLkqKEz0K+AhYAnsBL4HhgJXAV8BIw+20pCiEnAJIBpcc24KjTEYXllbg4uIbUt0C4hIVSddme5Ki+Pw09MA0BxdyfgssuwFxfj1b4D3p06E3rNNSjuHigmE2ppKakfflBvIj7+oRRaalvBCy1Z+PiHnLN8x14jmffVC4De7XPP1j9ZNOdNykuLEEJgdHGl95Bx9cZsqlwBKnJycA2rjesaGkpljmPcytxc9j/wSE3coMGDsBcVU5GdTfHBQ5Sn6XdgzStW4tOxQ4MxAayl+p3CU3w9BNXTEDiIDxf062Dgyz9tNV3a/6rAwEBy8/JqXuflmQkKdOwV4ONTO5Z++NChfPbFV38vKBDi60VWQVHN65yCYkJ9vRzKhPp60SE2HJPBQFSgL7HB/pzMLSApJY0OsWF4uLoA0Kd1M3Ydz6RrfFSDcfW7vbU9FxQff+xWx0nKXLtcStF3ekOKLe0owmhCeHihlRTxVxWWaA53Mf08hcPd1fp0iDdwIttOZXXP9uSTdmJDFY5l1v/HLy47dbdXj+PtrjccnK5ZCPRuK/h+pXrW+lRcDrlWjehgSHaiLSfYy52sOoFyissIOUcXiiXJaUwb5Dhc5VTZKD8vEqOCSc4pINrP62yrO7AU2An0q73zGuBrwFzoOBzAUmgjyM+IpdCOooCHm0JRicqlXb3YebAMuwrWYpWDxypoHu1Kjrnh4QQh3u5kW2t/qNlFpQSfK9/9J5g2rPs5PseDhGBftqfmMqRNzFnL1KUWFaD4BtS81nvpFDiUcet6KdZvZgFgSz3yt+tyYQn4etXWY18vgdXJetw+zsDJbLW2HqfaiQ1TOJ7V8E5M3zfWxvXxdOylc0rzcEH/jgY+/6Oqpi4XleqTM9Z8Z0/BsSznvrO1RHPM19P5fAFW7rSzcqfeO2DsZSbyCp3sueEf4nDMtVqy8fUPPWf5jr1G8utX04FTx9wlLJ4zs/qYqzh1zM232gn0rfv7Ucgvcn4C4b8qz1JJSKBLzevgQBfyLFVnLZNnqURRwMvDgLVIr0hBAS688EgLXn3/CBnZFU7HLc/Mxi2y9n6PW0Qo5ZmOvUUqsnLZecsDABg8PQi9Ygg2axFRE66lIGk39hL9d5+3bB1+3TtTsGl7g3H/zvmU0eSC0aRvq6i4dgSERJOXeZyo+Pb1xqzIzMEtvLb3hFtYaM2kjqdUZueye+KDeq4e7oSM1HONvOkaCrfvxl6q79PNK9fh260TBVsazlWSJEn6axq6BROqadp7mqa9Cvhpmvaapmmpmqa9B8SeayVN0z7RNC1R07TE0xsYAIoPHMAtOhrX8HCE0UjA4CHkr13jUMbo61tztypiwi3k/P4bAEeef46dY0az8+oxnHzvXXIXL3Lqojsqvj3mrBNYctKw2SrZtWkxbbs6jufLyzpe8/+DO1cTFKanePcz3zFt1jKmzVpGn2E3c9kVk5xqYGiqXAGK9u7DPSYGt8gIhNFI8IhhmFeucozr51cTN2bi7WTNm1+zrtHHG5O/fiHr16M7JUec60aZYdYI8Bb4eenjlds3UziY6ngCHhYAV/QyMHuljRInu6/Xp1XLFqSnZ5CVlUVVVRWr1qyhV0/HpzyYLbVdsjdt3kJM9N8fP98uOoyTufmkmQupstn5Y0cy/dvHO5QZ2D6BpBR9bHt+cRkncvOJCvQlzN+bbUfSsNlVqux2th1NIy404GxhzmDLOI4hMBTFLwgMBlzb96AqeZdDGbXQgim+DQCGoHCE0fS3GhgAUnNUgvwEAd76mPTOCUb2HXfuBD6/SCM+woAi9JE38REGh4n2ziXDAv5eesOVokCbGMHhDMf1Qv1geKLC3HUqpXXOz73d9XHzAG4miA4SWJzcBO3C/EktKCa9sIQqu8qSg6n0jz+z89YxixVrRSUdw2sbtazllVRWTxKRX1bBzgyzw4SR9UlJrSA82ERIgBGjAfp08SRpn2MrXdLeUvr30BssenXyZG+KfuKcl2+jfYI+D4eri6BlrCvp2U7MDAi0iwjkZH4R6QXFVNntLNl/ggEtzmzwOpZXiLW8kk6RtcOTsq2llFfpF0vWsgp2pOXSLND7jHXPxpZ+DENAnbrcoQeVB3c6lNHrcltAr8v8zbqclqMS5Cvwr67HnZob2O9kPS4o1oiPUGrqcVy4Qk6+c62k6XkagT4C/+p9Y4c4hYOpjnU5PEAw+hIj3y+vctg3Hk5XSYhQcHMBNxdIiKgdStFgvrnVcevme9K5dYWgpvdPWIDeU+hwmnPrRsV3IM/hmLuINvUcc5PrHHPveuY7Hp+1nMdnLafPsAkMcPKYezS9itBAA0F+BgwG6NXBnR0Hnb9o/6sOHikmMtyNsGBXjAbBwN4BbEhybPjdsK2AYQP0303/XgE1T5Dw9DDw6rSWfDo7lb3J53dH37pjLx7xMbjHRCJMJsLHjCRn8UqHMqaA2uN83AN3kv69PuFieVomAX0SEQYDwmjEv0+i08Ml/s75VLHVgqrqvzdzTirm7BMEhDTcuG7dtRf3uFjcoiMRJiOho0eQu3SVY67+tbk2u+9OMn6szjU9E79edXLt1c1hwkhJkiSp8TXUk6FuI8Q3py376wMd7XaOvzmTVm+/i1AUcn//jbJjx4icOImSAwcoWLcWn676UxY0TaNo5w6Oz3zjL4cDMBiMXDnhKb54YyKqqpLYbwyhUS348+f3iIprR9uuA9mwdDYp+zZiMBhx9/Tl+kkv/62YTZXrqbgpL79G+48/0B9hOW8+pUeOEnvvZIr27ceyajV+3ROJe2AKmqZRuG07KTOqH1+lqhyd+RYdPv8IgaBo/wGy5v7iVFhVg0Vb7Nw8WH9M244Uffb0yzopZJg1ktM0hnYz4GKE6/vr1a+wROOHlfpJx+3DDAT5ClyM8NA1RuZvtHMko/6LUYPBwL2T7+bJZ55DVVWGDhlMs9hYvv72O1q2aMElvXoyf8FvbNy8GYPBgLeXNw8/OLVm/Ycee5y01DTKyssZN+FWHpx6P4ndGu5KaTQoPHH1QCZ/8guqqnFVj3YkhAXx/uINtIsOZUD75vRuHcuGQycY89rXKELw4BX98PN0Z0inFmw5nMq1b3yLENC7dTMGtGvu1DZGVSlZNBufmx8AoVCxYz323AzcLxuNLeM4Vcm7KP3z//C84hbceg0BNIp//aJmdb8HXkW4uiMMBkytO1P07SyH2fzPGVaDeWsrmTjKVX8U3kEb2fkaw7qbSM1V2X/cTnSwwi3DXfBwFbRtZmBod42ZP5az+6idhEiFh29wAw0OptrZf6LhCztNg6XbVcb2UxACdh/TyLNC33aCzHyNlAy9brkYYcwl+u7KWgpz16sE+sCgTgoa+pxjm5M1h5n862NUFB6/rDP3/rwWVdO4sn0zmgf58uH6fbQN86d/8wgAlhxMZViraIcJ645ZrLy0dDtCCDRN47burZxuZFBV+PxnM0/dFYaiwMrNRaRlVXHDcD+OpFaStK+UFZuLmTIumPeejKK4VGXWt/pwqiXrrNxzYzBvPR6JAFZuKeZkpnMTfBoVhceHJnLPnBWoqsboTs1pHuzHB6t30TY8kAEt9YuAJftPMKxtrGO+5kLeWrZd38gaTOjZhhYh/ueIdGbCxQu/x3fCg9WPY12HPTcDj4GjsaUfpzJ5FyV//IjX6Ftw7z0ENI3iebV12f/B12rqskvrLli/eavBuqxqMH9dFXderj+KdWuy/oSUoYlG0nJV9p9QiQoWTBjmiocrtIk1MCRR463/q2D3UTvNIxUevN4VNEhOVTlwwrmLblWD3zfZuGWISX+EZYo+n8OgzgbSzSoHUzWGJxpwMcHYy/R9Y0ExfL/CRlklrNxlZ/IofZz/yl12ypxrP0LVYMEGG7eP0OMmJetP0hjSTc/3wEmVqCDBzUNccHeF1jEKQ7ppzJpbiUGBu67Q7zpXVMKPK6ucHi6hH3Of5os37kRTVRL7XU1oVAuW/vwukXHtadt1IBuXziZl3wYMBhPunj5cN8n5RyieNVcVvvndymO3BCAUWLO9jPQcG1cP9OJYRhU7DlYQF2li6o3+eLoLurR2Y8xAL558T+8J99QdgYQHG3BzUXj7kRA+/7WAPSkNb2hVhXe/OM7rT7VCUQSLV+ZyPK2M266PJPlICRu2FbBwRQ5P3tec797thLXYxotvpwAwZngoEWFuTLg2kgnX6k9JeXTGQQqsDfdA0ux2Djz+Et1++gRhUEifPY+S5CMkTLuPwp37yP1jJQF9etDimQdA08jfmMT+x2YAkLXgTwL69qT3unmgQd7ydeQuWeXUdv4751PHkpNY+vN7GAxGhFC46tbn8PDyayCinmvyMy/T5fuPEIqBjB/nUXLoCPGP3It11z7ylq7Cv3d3EqZNRdM0CjZv4+BTLwGQvXAp/n160mvZL2iahnnVevKWrXYqV0mSpFPOZ2JrCUR9G0wI8QLwuqZpxae9nwC8qmnatQ0F2HxJz4v+F8l4Z8PFDglAxNTeTRK3osjJs81GtvyxLU0S97beF3/CprDkFQ0XugBKtjbNI7ZeCT3/yUYbQ2DgBZg0oQH35z970WMC3HrwziaJ+3Xnb5skbumRExc95usR/7noMQFc3C78ZINnY6tqmjkcenRyabhQI/v1tzMnkbwYUpNPNkncactvb5K4pYt3X/SY3ld3brjQBTI4bU+TxZakf4Gmm/zrIpj+XdU/spXhufGmJvm71DtcQtO0Z4EoIcQgIYRXnfdTgM8wXIjfAAAgAElEQVQu9JeTJEmSJEmSJEmSJOmfo6GnS0wB5gNTgL1CiLoTPTbCWAJJkiRJkiRJkiRJ+u+lqv/Mf02loTkZJgHdNE0rFkI0A+YKIZppmvYO//IuMZIkSZIkSZIkSZIknZ8GJ348NR+DpmnHhRAD0BsaYpGNDJIkSZIkSZIkSZIk1dHQIyyzhRA1M/BUNziMAoKADhfyi0mSJEmSJEmSJEmS9M/SUE+GCYDDc5Q0TbMBE4QQH1+wbyVJkiRJkiRJkiRJ/wXkIyzPT72NDJqmpdWzbH3jfx1JkiRJkiRJkiRJkv6pGhouIUmSJEmSJEmSJEnSv5AQYrgQIlkIkSKEmHaW5Q8JIfYLIXYLIZZXz89YL9nIIEmSJEmSJEmSJEn/Y4QQBuB9YATQFrhRCNH2tGI7gERN0zoCc4HXG/rchuZkkCRJkiRJkiRJkqT/Weq/d0qGHkCKpmlHAYQQc4DRwP5TBTRNW1mn/CZgfEMfKi70JBa3Pp/dJH8Sq6XooscMjwm66DEBykoqmyTuG+LpJokrxky46DFPurW66DEBFJpmj1Zud22SuMGm3Ise87W5gRc9JkB2al6TxA0M92+SuFoTHZ0vG3Dx98snM9SLHhMgN7esSeL6+7s1SdzlP2+56DG7Dux40WNC021jg6FpnlZuNF78uKWl9ose85TpE0xNFluSGlHT7DAukqe/qvxHNjPMuNWl3r+LEOJaYLimaXdWv74Z6Klp2n3nKP8fIEvTtBn1fe6/sidDUzQwSJIkSf9dmqKBQbo4mqKBQbo4mqKBQZIk6d9KCDEJmFTnrU80TfvkL37WeCAR6N9Q2X9lI4MkSZIkSZIkSZIkNYam6pH5d1U3KNTXqJAORNd5HVX9ngMhxGDgKaC/pmkVDcWVEz9KkiRJkiRJkiRJ0v+erUALIUScEMIFGAssqFtACNEF+Bi4UtO0HGc+VDYySJIkSZIkSZIkSdL/GE3TbMB9wBLgAPB/mqbtE0K8IIS4srrYG4AX8JMQYqcQYsE5Pq6GHC4hSZIkSZIkSZIkSf+DNE1bBCw67b1n6/x/8Pl+pmxkkCRJkiRJkiRJkqRzuMAPZPzXkcMlJEmSJEmSJEmSJElqFLKRQZIkSZIkSZIkSZKkRiGHS0iSJEmSJEmSJEnSOaj/0EdYNhXZk0GSJEmSJEmSJEmSpEYhGxkkSZIkSZIkSZIkSWoUTTZcokOCCzcN90ZRYM32MhauK3VY3jLWxE3DvYkONfLh3EKS9lcAEBNmZMLl3ri7Kqiaxm9rStiyr8KpmF3aeHD71UEoCizbaGXesgKH5UYjTB0fSny0K0UlKm9+lUWuxYZBgXtuDCE+2hWDIli1tYhfluY7nWvbZkauHeiOImD9nkqWbnH8vglRBq65zJ3IYANf/l7KjkNVNcvee8iXjDwVAItV5eNfS5yO2765CzcN90IosHZ7OYvWn7aNY0zcONyLqFAjH821su2A/r2iQ43cfLk37q4CVYPf15aw1cltDGBq3g7PYTeAolC+Yx3l6/9wWK74BOB11W0IV3dQFEqX/0JVyl6Euyfe192NMSKWip0bKfnjB6djbtyxh7e//AG7qnHloL5MGDPSYfnClev4z7c/ERzgD8C1wwdy5eB+bNt7kHe+mlNT7kR6Ji88eBf9e3R1Ku7ObZv46pN3UFWVgUNHcdV1N5+13Ob1q3jrlad5edZnNG/RmpzsTB6aPI6IyBgAWrRqx8T7HnU63x3bNvNlddxBQ0cx5rrxZy23af0q3nzlGV6d9WlN3Acmj6+J27JVOybd94jTcXdv38i3n76JqqoMGDKaK6695azltm5YwbuvTWP6zK+Ib9GWI4f28cUHLwOgaRpXj51I4iWXORUzKSmJDz/+BFVVGT5sKDdcf73D8j+XLuXzz78gMCgQgCtGXcGI4cMAWLpsGT/M+RGAG8fewJDBzj+Bp22ckesHeaAosH5XBUs2n/67NXL9IHciQwx8vqCE7clVDsvdXOC5O33ZdaiSOcvKnI7bpY0Hd1wbrO+nNljP2NcYjYKpN4fSPEbfT838IpNci41+id5cNdi/plxshAsPv3aS4+mVTsVtF2/ixqGeKEKwdmc5izc6fucW0UbGDvUiKsTAJ/OK2HZQ/9wAH4V7r/NBCDAosCKpnNXby53Ot31zEzcO80IIwdodZSze4Bi3ZYyJsUM9iQo18vEvVrYd0OMG+p6KKzAYYPmWMqfjpuxdy5IfXkJTVbr0vZY+Iyc5LN+2ag5bV36PohhwcfXg8gkvEByRQGlxPnM/nErG8b106n0VI8Y9e44IZxcfBkO6KAgBu45qbDzo2PWyR0tB53h9v1taAb9vUbGWgo8HXHupggAUBZIOa+w44ny3zdYxBsb0dUUI2Ly/iuXbHetqfITCmEtdCQ9S+HZJObuO2AFIiDRw1aUuNeVC/BW+WVLO3mN2p+I2DxcMS1RQBOxIUVm/3/E792ot6JKgoKpQWqGxYJNKYQmE+sPl3Q24mPTZvNfuU9l/wrl8e3TxY8rtcSgKLFyWw+x56Q7LTUbBk1Nb0DLeE2uRjelvHiIrtwIfLyMvPNqKVgle/LEyh3c+O+ZUvFP+l7Yx6HV5aFe9Lu88qrHxwGl1udVpdXlzbV2+7lJ9PUWBpEMa252sy2mH1rJp4ctoqkrLxGvp1H+iw/K9677iUNJchGLAzTOAvlfPwMs/smZ5ZXkxv7wzitg2g7jkymeczjUhQjCiuwEhYHuKyrq9qsPyS9oodG2h6LmWa/y6wU5h9ana+EEGooIFJ3M0Zq9w7m8qSZL0b9AkjQxCwM0jvXnj2wIsVjvPTQxgR3IFGbm1O2BLoZ3PfrUyoreHw7oVVRqfzrOSbbHj563w/KQA9h6ppLS8/oOUImDidcFMfz8dc4GN1x+JZuveEtKyak8EBvfyobhU5d4XT9KnqxcTrgzkza+y6d3FC5NR8OCrqbiYBO8+GcPabUXkWmxO5Xr9YHfe+6mEgiKVx8Z7s+dIFVnm2oOUxarx7eJSBnd3O2P9Khu88k1Rg3HOFnf8SG/e/DYfi1Xl2Yn+7EyuICOvdhubC+18/quV4adt48oqjc9+tZJjsePnpfDsJH/2plRSVuHEiYAQeI64Cet3s1Ct+fje+SRVybuw52XWFHHvO5KKfUlUbFuNISgc75umUPDuk2i2KkpXzscQEoExOLKeII7sdpU3P/ued559mJAAf26f9iJ9EzsTFx3hUG5Q7x48cuc4h/e6tW/NNzOfB6CwqJjrpjxBz07tnIqr2u188eFbPDVjFoGBITzx4J0k9ryUqJg4h3JlpaUsWvATCa3aOrwfGhbJ6+995XSep9jtdj7/8C2emTGLgMBgnnhwIok9+xB91rhzaXFa3LCwSGa+9+V5x1Xtdr7++HUen/4fAgJDePaRW+jaoy+RMfGnxS1hyW9zaN6yfc17UbHNeeHNrzEYjBRY8njygXF06dEXg6H+XZDdbuf9Dz7k5ZdmEBQUxP0PPEivXr2IjYlxKNevXz/uvWeyw3tFRUV8P3s2773zDgBTpk6lV8+eeHt7N5irEHDjEA/e+bGY/CKVJ27xZndKFZl1frf5VpWvF5UypIfrWT/jyr7uHE5teB9RlyJg0vXBPP+f6v3UozFs2VNCWlZtQ8HgS3woKVO5Z/oJLu3mxYTRQbz5ZRZrkopYk6TvK2IiXHhiYrjTDQxCwLjhXrw1u5B8q8rTt/ux83AlmXX2Fxarype/FTG0p7vDuoXFKq98VYDNDq4mmD7Jn52HKiksVk8Pc4643rz5fQH5VpVn7tTXzTxtP/XFgiKGXeK4nyooUnn5y9q4L9wdwK5DlRQ0EFdV7fzx/QuMe+gLfPxD+WzGdbTsPJDgiISaMu17jqLbgLEAJO9cwdIfX+WmBz/DaHJlwFVTyU0/TE76oQbzOz3XYd0UflilYi2D24YoHM7QyLPWlsku0PhiqYbNDl2bCwZ2Evy6UaO4HL5epmJXwWSEicMVDqfr7zsT95r+rnw0v4yCYo0Hr3dn7zEb2fm1+/P8Io3Zyyu4rIvJYd2UdDszf9QbfTxc4cmbPUlOde5CSQgY0V3huxV2rKVw53ADyWl2h3yz8uHTxXZsdujWQjC4i8LP61SqbPDrRjuWIvByh4kjDBzJsFNRde54oF+0PjAxnoen7yPXXMnHr3dk/VYLJ9JqG64uHxxKUbGNcffuYGCfQO6aEMv0Nw9RWaXy+Q8niYvxIC7Go54oZ8/1f2Ubn4o7PFFh9kq9Lt8+RK+PDnU5X+OLP6vrcoJgUGfBvA16nf2qTl2eNELhkBN1WVXtbPztRYbd9jmePqEs+PB6Ytpchn9I7e82MKINV97zE0YXdw5s/oGtS2Zy2dhZNcu3L3uXsGaJTm3burle3tPAN0ttWEth0kgjyakquYW1ZTItGp8stFFlh+4tFYZ2M/DTGv1vuH6fiskIiS1lx2FJ+qfT5DMsz0uT7PXiI01kW+zk5tux22Hz3nK6tHI8Uc8rUEnLtp3xTNJss51si77zLihSsZaoeHs0nEZCrBuZuVVkm23Y7LBuezE9Ong5lOnewYuVW/ST9I07i+nQUj/R0DRwdVVQFHAxCWx2jbLyhk+gAZqFGcjNVzEX6gfVbQcr6djc8STDYlXJyFMb9fmr8ZFGciw2cgv0uJv3VdC5teM2NheqpOXYOX0ek2yLnZxT27hYpahExdvTuapijIzDnp+DWpAHqp2KfVsxtep0RjnhqjeoCDd31KLqo3VVJbbUFLA5cZZTx/6Uo0SFhRAZGozJZGRwnx6s2brjvD4DYOWmbVzSuQNurme/aDxdyqEDhIZHERoWidFkone/wWzdtO6Mcj9+9ymjrx2Hi8nlLJ9y/lIOHSAsPJLQsAhMJhN9+g0i6Sxx53z3GaOvvQlTI8U9cngfoWFRhFTn26vvULZtWXNGuZ9nf8yoayZgcqmN6+rqVtOgUFlVgUA4FTP50CHCIyIIDw/HZDLRv18/Nm7c5NS6Sdu20aVLF7y9vfH29qZLly4kbdvm1LrNwg3kFKjkVf9utx6oomMLx+1otqqk59rP+ruNCTXg7alw4Nj51eUWzdzIzKu7nyqiR0dPhzI9OnqycrN+Nr9hRzEdW515QdS3mzfrthc7HTcuwkiOxU5e9f5iy/4KOrc8Ld/q/cXp+dpVsFVfExmNAuHcnxaA+AgjOfl14u4rp0urCxs349hu/ENi8A+OxmB0oV2PkSTvXO5QxtW99thQVVHKqQ93cfUgpkU3jH/hNxURAPlFUFACqgr7T2q0iHT80idyanNKN2t4e+jLVVXPF8Co4OSvRxcTqpBXqGK2athV2HHYRvt4x8a9/CKNTHP9x6BOCUYOnrBR5WS7WWSg/rkFxfr333dCpVW04zc/nq3V5pun4VOdr6VI/wdQXAYl5eB5Zhv8GdokeJGeWUZmdgU2m8aKdXlc2iPAoUyf7v4sWZkDwOqNZrp28AWgvEJlz8EiKqucO7bX9b+0jUGvy5bT6nLL+upynoa3+9+ry3lpu/EJiMEnQP/dxnccyckDKxzKhMf3xOiiN4KGRHeipDC7dv30fZQV5xHZoo+TEXWRgQJLkUZ+sf699x5XaR3teD50PFujqjrX1DwVnzq75GNZGpXndxiQJEn6VzjvRgYhRMjfDervo2CxOt4R9PcxnPfnxEUaMRoEOfkNt/oH+hkwF9Tu6c0FNgJ8HWMG+taWUVUoLdcvrjfuLKaiQuXzGXF8Mr0Z81cUUFzq3ImIn7dCflFt2YJiFT9v5ze70QiPjffikZu86JhganiFmriGM7fxecQ9JS7CiMEgyLU4d2dF8fZDLbTUvFatBRi8/R3KlK7+DdcOvfB74DW8b5xyXsMizibXUkBIUO2JZEigP7mWgjPKrdq0jfEPPceTMz8gO89yxvJl67cw5NKeTse1mHMJDK79OQQGBZNvznUoczQlGXNeDl279z7ze2dn8vj9t/H8tPs4sHfXX44bEBSM2Zx31rjdzhI3JzuTR++/nWfPM26+OZeAoNDauIEhZ+R7/MhBzHnZdE689Iz1U5L3Mu2+G3jy/pu4bfLjDfZiADCbzQQHBdW8DgoKwmw2n1Fu3fr13H3Pvcx46WVyc3PrrBtcu27g2dc9G39vhfw6v5+CIhV/L+dOhwVw7UB3fl5Z2mDZ0wX8P3v3HR5F8T9w/L17l95zqaSTQu8k9N6lS1FBRWmCogjoFwsggkiVojSpKghIUbHSO6F3pCZACKT3Ssjd3u+Pi0mOEHLRSH5+v/N6Hp6H3M7d52bnZnZ3dnbGQU1SatEVRnKqFo2D8X7SFEujKJCTqyvRCdiyoS2HT5s+AsrpkXaqvO2Fk53M1OGOzHnTmR3Hck0axQDgaC+TklHUtqRmKDjamX4scLKXmTrSibljNfwenlPmKAaAjNR47J08C/+2d/IgMzW+RLpT+75l8fud2Lt1Hl1e+NDk71QaOyvIyC26wszMMbxWmnpVJW7FFqW3s4LhXWTG9JQ5fs20UQwAjjYSaZlFn5OepcfBpjzdFAYNgtWcvWn6yBw7K4n0YlUgI4fCC83HqR8oExFTsvyqaAyP4aSY8HN20ViQkFw0eicx+SEuzualptEpkJ2jw8Hu7w3q/F/ax4a4kJlTlN+M3Cf/lutXlYgs/lu2huFdZd7sJXPsqmm/5eyMBGwcPAr/trF3Jye9ZL39043T2/AOaQWAXlE4+ftswrr9p+xAj7C3pvDRB4D0HD12Txjo0jDIMKpDEAThf90TzyIlSXJ+5J8GOClJkpMkSc5PeN9ISZJOS5J0+saZdRX+pQEcbGVG9nVg9faMCh0B8DjBfpYoehg+6TajP46iVztH3DVP50mTySsymLM+i7W/5tC/nRUuDk9v8ImDrcyIvvas2Z5BRe5ii9qh5F0IJ23hRDI3foFtn6GU795c+bVsXJ/vl81m/fyPCa1bk+mLVxttT0pNI/LuPZrWN+1RCVMoisK6VV/w0rAxJbY5OWtYsnYbsz9fy8vDx/DFvI/JyTF9vo2y4n69ajEvD3vjsXGXrd3K3M/XMGT4myyaN61C4367ZiGDXh372O1B1Woza/F3fDzvK37e9jUPH5o+z8eTNG3ShK+/WsvypUto0KAB8z6bXyGf+1e1aWjB5ch8o4uOpynYz4K8fD13Y017VKIipGYqTF2VxgdLU2le1wL7v3CB9ZfiZihMXZHKB4tTaF7XskLjhrYfzJiZu2nffwJHfllWYZ9rilp+Ep7OEseLzdmQmQurdios+1Whjr+EjWkDriqEvbWEp0bFtbv/zDPldfwlqmgkwh+ZT8DWEvo0V/HTsf/+Z9n/W/dx7cf9lnNg1Q6Fpb8o1A2o+N9yxPmfSIq5TJ1WwwC4emIj3iGtjTop/gl1Awz7+Ogf5R8NIwiC8N+mrCvWJOBMsX+nAS/gbMH/H0uv16/Q6/WN9Xp945BGJSfCS81QcLYvCu1kL5OaYfoBztJCYtxgR7btyyLynmnj0JLTdGgci0YCaBzVpKQbx0xOL0ojy2BtKZOZrdCqsS3nruagUyA9S8e12w8I9DVtXGFapvEdQUdbmbRM0w9A6Vn6gu+mcDNai4+7aXf50jJ1JfdxOeJamku8PciBbfuyuXXf9DsrSmYaskNR/5Ns74gu03jiOov6LXl4xfDz0d67haQ2Q7I2fnSlPFydHUkoNjIhITkVV2dHozQOdraYmxnKtleH1ly7FWW0fW/4KdqENUStNr3zyFnjSnJiQuHfyUmJOGmK7pw/yM0h+u5tpr3/JmOG9ufm9SvMnT6RyJvXMDMzx87eMEy3alB13D2qEHs/+i/FTUlKRKMputufWxB36vtv8frQAdy8foXZ098rETcwqFq54jppXElJKrpzlJKcUCK/96Ii+XTSaMaN6E3k9cssmPEOt25eMfocL58ALCytuBcVWWZMjUZDYlLRKI2kpCQ0Go1RGnt7+8Ky7dqlMzcjIoq9t2ikRVJyyfeWJjVTwalY/XG0k0nNMq3ToGoVFW0bWTJjlD392lnRpLYFfdo84TZfMSnpWlycin6DGic1yenG9S+5WBpZBmsrFZnZRXW7ZSO7co1igIL82v319uJP6VmGR0iCfUwbdZWWoeBcbBSbk71MWmb5L3bSshRiErUE+5Yd197JnYzUojliMlLjsHNyLzV97dDuJR6n+Csyc8G+2F1mO2vDa4/yd4cWNSW2HFYKh5UXl/UAEtP1+LiW3PY4adl6HO2K4jrYSqRnl68DrH6Qmku3tCjl+Elk5upxKHbH197a8NqjAjwkWtaW2XRAZ5RfczW80E7F/vMK900bgERSch5umqKRC64ac5JSHpaaRiWDjbWK9MzyzZ3yqP+lfWyIS+GjPAD2Vk/+LW+ugN+yjb0b2elxhX9nZ8Rj7VCy3t6PCOfCgS/p+OJSVGpDOSdEn+fq8Q1sntuBk7/PIeL8dk7t/KzsoBhGhzgUe2LNwVoi8zGD1Kp6SrSuo2Ljft1j8yoIwr+fXvl3/qssZXUyvAtcB3rp9foAvV4fANwr+H/VMt5bqtsx+bhrVLg4yqhU0KS2Jeeum3ZXU6WCt55zIPzCg8IVJ0wRcfcBnq5muDmrUasMw4lPXTK+g3vqcjbtwgyTwjWrb8ulm4YjSVKqljrBhosEC3OJEH9L7sebdpcwKk6Hm5OMxkFGJUOj6uZcijStY8TKQkJdcP5tYyVR1UtFbLJpJ+C372tx16gN+1iGJrUsOG/qPpZhTME+/nPFCVNp799B5eyG7KgBWYVFrVDybxgPyVcyUjALqG6I5eKBpDZDn1P+yS3/VCMogOjYeGLiE8nP17Ln6ElahdY3SpOUWvT4xOHT5/H38jTavvtI+R6VAAgMqU5cTDQJcTFo8/MJP7SHxk2Knve0trFl1YZfWbxmK4vXGCZgfHfybAKDq5ORnoqiM5RlfNx9YmPu4e5RpbRQRoJCqhMbc4/4uBjy8/M5emgvjZsUPZ5gY2PLmg2/sHTNFpau2UJwtZpMnDyLwODqpKenoiuMG0NszD3cTIxbNbgmcbHRJMTfR5ufz/HDu2gY1soov8vW72bByu0sWLmdwGq1GffhPKoG1yQh/j46neFEPikhlth7Ubi6lx23WkgIMTH3iYuLIz8/n4OHDtG0qXE5JacUdTAdP3ECXx8fABo3asTZs+fIzMwkMzOTs2fP0bhRI5PyGhVrXG9Da5hxMcK0Or/mlxw+WJbOh8sz2LY/lxOX8/jxoGmrS9yMeoCnqzlumj/bKTtOXXyknbqUTbsm9gA0b2DLpRtFZ7ySBC0a2nHkTPnq050YLe7OKlwK8htW04ILN0zLr5OdjFlBv4i1pUSQtxlxprZTf8YtaKfCally/q/G9TEtbhX/OqTER5GaeA+d9iF/nPyNkHrtjdIkx98p/P/NiwdwdvMz6Ts9SUwKONkZLlhkGWr6SiWGVbs7QrfGMlsOK+QUa3rtrCg8FliagberRLKJRRwdr+DqIONsJ6GSDUPy/zBx5YI/NQhRc/ZG+S7E7yeDs52EY0F+a/nJ3LhnnF8PJ+geJvPdQZ1RfmUZnmsjc/GWwtVo0y/Wr0Vk4e1phYebBWq1RPuWLhw9Zfxo3NFTqXRpZ3jcrE0zDecupT/uo8rlf2kfg+G37PzIb/nGY37Lz4TKbC7rt+xi2m/ZxasO6clRZKYY6u2ti7/hW914haLkmCuEb59KxxeXYGVb1KHcduBcnvvPPga+u5ewbv8hqH5vQrtMMC2vyXrDPrY1nBvV9pe5Fm181u7hDD2bqtiwX0u26QvrCIIg/Fd74m1bvV7/mSRJ3wELJEmKBj6Cvz9yXlFg/W+ZvPOSE7IEh889ICZRR992NtyO0XL+eh4BVdS8+bwjNpYy9UMs6NtW4cOlyYTVsiTEzxxba5mW9Q2jCVb9mMHduCcfnBUFVm1NZMrrVZBlib3HM4iOe8jzzzgTefcBpy7nsPdYBmNfcmfJZF+ychTmf2XoNf/9UDpjBruz8H0fJEli3/EMomJMOxFW9LB5by5v9LNBluHYpYfEJit0b2HJ3TgtlyK1+HqoGNnbBmtLidqBaro3t+STrzLx0Mi80Mkavd5w8bDrRJ7RqhRlxV3/WybjX3REliSOnM8lJlFHn7Y23InJ5/yNh/hXUTPmOYfCfdynrQ2Tl6UQWsuCED8zbK0lWhTs49U/ZhIdb8IJkF4h+/eN2A9+GySZvPNH0SXGYtW2F9qYKPJvXCBn1xZser6EZRPDcoJZ278qfLvjW58iWVghqVSYVa9P5vqFRitTPI5apWLC8MG8/ckCFEWhR/uWVPXxYsWmH6kR6E+r0Pps/m0vR06dR6WSsbe1YdKYoYXvj01IIj45hQY1Q0zat39SqdQMHTWeT6eML1jSsTs+flXZvH4VVYOrG134P+rq5Qts/nYVKpUaSZYZ8cY72NrZmxx32KhxzJgyAUVRaNepOz5+AWxab1geM7SMuN99uxqVSo0sS4x84x3syhH35ZHvMnfqWyiKQusOPfH2DWTbt18SEFSDhk1al/reG1cu8Mu2r1Gp1UiSzJBR/8HO3rHU9EUxVbw+ejQfTpqMoih07twJfz8/vlm3juDgYJo1bcr27T9x/MQJVCoVdna2TBg/DgA7OzsGvfA8b71t+HvwCy+YtLIEGOrPd7tzeGugLbIE4ZceEpuk0LOlJVFxOi5G5OPnoWLUs7ZYW0jUCTKjR0s901ZnlP3hT4qrwMrNCXz0hheyRGE79UJ3ZyLu5nHqUjZ7wjN4+2V3ln7kR1a2wmdri+pHzSArklINE0eWK64eNuzM4u0XHAqW7HxATJKO3q2tuROr5cLNh/h7qnm9vx02ljL1gs3p1VrhoxVpeLqoGNjBHj2Gh552ncjhfqJpF1iKHr7dkcW4QQ6GduqC4VjQu01B3BuGuG8MtC+M27uNwpTlqYa4nRwKP2vnsSfoalwAACAASURBVFzuJ5QdV1ap6TpoMhsWDkOvKNRr0Q83r2AO/Pg5nv61qVa/Paf3fcutq8dQqdRYWtvTa+iswvd/PrE9ebnZ6HT5XD+/l8HjVhutTFEavR52nVV4vo1hucELtwyz8beuLRGboudmDLSvJ2OuhmebG/r/03Ng6xEFjT10rC8X7uMT1/RGs9uXtY+3Hcrjtd6GZZRPXMknLkWha5g50Qk6/rijw8dNZugzllhZSNQKUNM1TGH2RkPHmJOdhKOtROT98l006/Xw+2mFwe0NS/+djzTMyN+2rkxMsp4b9/V0bGDIb/+WqoL86vnuoEItXwlfNwkrc4l6Bbczth/XEV/GytE6BRauusW8KTWRZYnf9sZzJzqXoc/7cC0yi/BTqfy2N54Pxwbz7ZIGZGZp+Xh+0Sohm5Y3xMZKhVot07KJM+98fMVoZQqxj4vi7jyj8EIbw4TYj/std6hv6ATs16Lot7zlsIKLPXRoIPPnj/nEddN+y7JKTbOek9j51XD0eoXghs/i5B7M2T2f4+JVG98a7Tm5Yy75eTns32ho820cPen00tJy7dNHKXr47aSOlzqqC5cJTUyHdvUM+/j6PT2dG6kwV8PANoZT6vRsPRv3G8pyaBcVLg4S5moY30/N9mM6ImPEnA2CIPz3k0xdjkOSpF7AB4C/Xq83+cG2V6bGP/XWNMPU2YsqmKevS9mJ/gG52U/v2evi5kqTKiWu1Pflpx7zrmW1px4TQK7Q2TBM90D3FB/4LsbVLLHsRBVs9lbTHqGoaPHRSWUn+gdoPJ3KTvQP0D+6jM1T0K5t5bTJdx8zud7TkJho2oiZiubkZOKyBBVo77aTTz0mQMP2dSslbmXsYwCV6unMr1KcWv30YwLk5FTe3B8fv2z6xN6C8P9Y5VTep+SdZTn/yh7CeaOtK6VcypxFUJKk6pIkdQD2Ae2AjgWvd/2Hv5sgCIIgCIIgCIIgCP8iZa0u8RawHXgTuAx01uv1lws2f/oPfzdBEARBEARBEARBEP5FyppKfwTQSK/XZ0mS5A9slSTJX6/XL+K/fEiMIAiCIAiCIAiCIAjlU1Yng6zX67MA9Hr9HUmS2mLoaPBDdDIIgiAIgiAIgiAI/+VMncdQMChrToZ4SZIK1wIs6HDoAbgAdf7JLyYIgiAIgiAIgiAIwr9LWZ0MLwNxxV/Q6/VavV7/MlD6enWCIAiCIAiCIAiCIPzPeeLjEnq9/t4Tth2t+K8jCIIgCIIgCIIgCP9/KJWwFPe/WZlLWAqCIAiCIAiCIAiCIJhCdDIIgiAIgiAIgiAIglAhRCeDIAiCIAiCIAiCIAgVoqwlLP+2kc9Z/9MhSrh41/2pxwRoXjWhUuImP7CrlLgJ1h9VSlyrma8/9ZhBjWs+9ZgAav/ASol7O7hbpcTN0j/933KjRk5PPSbAnsSMSon7TCfnSombmPb0+7Q3fXPlqccE2Nr7YKXEvdu4e6XEfaBYPvWYpw5VTr3t1UZVKXE9rePKTvQPiEj3eOoxG9hWTr2Nw6tS4gbkXSHlUqWExrlOy8oJLAj/QmIFy/IRIxkEQRAEQRAEQRAEQagQopNBEARBEARBEARBEIQKIToZBEEQBEEQBEEQBEGoEP/4nAyCIAiCIAiCIAiC8G+lV8SkDOUhRjIIgiAIgiAIgiAIglAhRCeDIAiCIAiCIAiCIAgVQjwuIQiCIAiCIAiCIAilUMQaluUiRjIIgiAIgiAIgiAIglAhRCeDIAiCIAiCIAiCIAgVQnQyCIIgCIIgCIIgCIJQIcScDIIgCIIgCIIgCIJQCrGEZflUWifDpbPhbFg1D0VRaN2pD937vfLYdKfD97JkzkSmzPuGgKCaZGWksWTORG5HXKFF+x68NHKiyTHvXDnEge9noCgKtZsNIKzTSKPtZ/at5fKxLcgqFVa2znQe9Cn2zl4AHNo+h9t/HAS9gm+1FrTt9yGSJJkU99yZE6xdsQhFUejQuQd9B7z42HTHjx7gs5mTmbVgJYHB1QGIuh3Bl4vnkZubjSTJzFqwAnNzC5Pi/nHuKJvXzkFRFFp06EvXvkONth/auYUDO79DlmUsLK0Z/NpkqvgEos3P59sV04mKvIIkyQx89V2q1Q41KSbA2dMnWfXlYhRFoVOXZ+g3cNBj04UfOcScT6cyb+EygkKqcXD/Hn7Y9l3h9qjbt/js8y+pGhhUZkyrWg1wfmEEyDJZh3eT/vs2o+0qZxdchr6NbG2DJMukbvuG3EtnsGnSBocufQrTmXn7Ezt9PA+jb5uU1/A7ccw7cBGdoqdPbX9eDatmtP2zAxc5fS8RgAf5OlJy8zj4ek8AQhd+T5CLAwAedlYs6N3cpJgAR6/eZvb3e1EUPX2b1mVYpyYl0uw8d43lv4eDBNWquDFrSA9O3rzLvB/2Faa5HZ/C7CE9aV832KS4lVG2506fYO2KzwvqT3f6Diy9/sz7dAqzFq4gqKD+3LkdyYrF88jJyUaWJGYtNL3+3P7jEPu2zkCvKNRpMYAmnY3bi9N713IxfAuyrMLa1pkuL36Kg8bQXhz8cS63Lh8EoFm316ne6BmTYgLUq2bJK72dkWXYdyKL7fszjLarVfDGCy5U9TYnM0dh0bpEElN1qFQwsr+Gqt7m6PXw1fYUrkTmmRz3+sXD/LLuUxRFIbRtf9r2HGG0/cTeTRzbswFZVmFuaU3foR/j7lVUfmlJMSx4rycd+r5B6+5DH/34Ut2+cogD2wztcp1mAwjrXLJdvnTMsJ+tbJ3pMrhYu/yjoV3W6xV8q7egnYntcsNaNox83gNZlth1OJWtO5KNtqvVEuOHViHIz4rMLB2zV9wjITkfAH8vC8a85ImVlYxegXEzbpOvNe3E4+i1O8z+8SCKotC3SW2GdSjZru48f4Plu44DUK2KK7Ne7AbAgp8Pc+jqbfR6PU1D/JjYp43Jx6Azp0+x8sulBfW2GwMGPv/473fkMLM+ncb8hYsJDqmGVqvli0XziYy4iU7R0b59JwY894JJMeGvH/sS4mN5e/SLVPHyBSCkWi1GjnnHpJgNa9kwYqA7siyx+0gaW3c+pmxfrUKgryWZ2TrmrLxvVLZvvOiBtaUKRa9n/Kd3TC7byjzervxySWGb3H/g48sn/MghZn/6MfMWLi0s28WL5nErIgKdoqNd+070f+7x7fnjXDt/mB+/mYWi6GjSrh8dehu3F+G7v+Po7o3Isoy5pTUDhk/Fw9vQXsREXWfr6o95kJOFJMu8/cl3mJnQLp88c47FK9eiKArPdOrAoAF9jbbv2LOfL9euw0XjDECf7l3p3qUjcQmJTJkxB71ej1arpW/PbvTq1sXkvF44c4xvVi5EUXS069SLXgNefvz3O7qfhbM+4JP5a6gaXKPw9aSEON59YxD9XhhGj2cHmxz32LlLLFy7EZ2ip1eHVrzc1/g48uv+IyxetwVXZycA+ndtT6+OrTlz+RqLvtpUmC7qfizTxr1Gm7CGJscWBEH4uyqlk0HR6Vj35Wze+XgJzhp3pr37MvXDWuPlU9UoXW5uNrt/2UTVkNqFr5mZW9B30Gju343g3t1I02MqOvZtmcazb6zFztGdDfP6E1i7PRrPopNkN+8aDHp3G2bmVlw4vIHD2+fS/dWFxNw6S8yts7z03k8AbF44iHsRJ/EJLnlh9yidTsfqZfOZ/MkCnDWuvD9uBI2btMDHN8A4rzk5/PbTVoKr1Sz2Xi2ffzadN8dPxr9qEJkZ6ahUphWZotOxcdVMxk5ZjpOzOzPfG0zdxm2o4hNYmCa0VTdadxkAwIVTB9j69We8NWkpR/YYLtCnzN9KRnoKi2e8wXuzvkWWy366RqfT8eXSRXw8Yy4aF1fefXs0YU2b4+PrXyK/v2zfRki1ogNxm3YdadOuIwB3bt9i5vTJJl2EIsk4D36N+PkfoU1NpsqkeeScP0l+bHRhEsfuA8k5fYTMAzsw8/TBfexk7r03kuwTB8k+YbgYNPPyw+2N903uYNApembtu8DSZ1vibmfFSxv20ybQk6oa+8I0E9rWLfz/pnORXE9MK/zbQq1i44sdTIplHFfh0y27+fL1gbg72jHos3W0rRNIoIdLYZqohFRW7z7B128Pwt7akuTMbADCgn3Z/J9XAEjPzqXHJ6toVt3ftLiVULY6nY5VyxYw5ZP5OLu48t64kTRu2vKxMX/d/pj6M286b02YVP76o+jYs3kaA940tBfr5/QnsE57XIq3Fz41eGmiob04f2gDh36cS89hC4m8fICE6CsMef9HtNqHfLfwJQJqtsbCyrbMuJIEQ/s6M2NFAsnpWmaO9eT0lVzux+cXpmnfxJbsXIWxs2JoXt+aQd2dWLQ+iQ5NDJ//7mex2NvKvD/cjQ8WxWHKZMiKouOnr6czbOJq7J3dWTJlIDUatjPqRKjXvAdNOhguTq+c3cev385m6H9WFm7/dcNsQuq2KjvYI3H3bZlGv4J2+du5hv1cvF129a7B4GLt8qEf59JjaLF2+X1Du/zdAtPaZVmC0YM8mbQgiuTUfBZ8WJUTFzKJjn1YmKZzS0eyc3SM/DCC1qH2vNLPjTkr7iPLMGG4F/NX3+f2vTzsbFTodKZdhOoUhU+/38+Xrz2Lu4MtgxZupG2tqgR6aArTRCWmsnrvKb4eM7Cg3uYAcP52DOfvxLD1HcNF+iuLN3M68h6hQT5lx9XpWL70C6bPmI3GxYXxb4+hSdNm+Pr6GaXLycnh5+0/UK1a9cLXjhw+RH5+PouXreTBgwe8MWo4rdu2w93dw6S4f/XYB+Dh4cW8L9aWGac4WYJRL3gweeFdklPzmf9+ACcuPlK2LRzJytbx2uRIWjW255Vn3Ziz0lC244dWYf7aGO6Us2wr93j7OR/PmIPGxZV33n6dsKbN8H2kfTSU7fdGbfLRwwfJz8/n82WryHvwgDGjhtKqbXuTylZRdHy/dgavfbASB407Cz98jlqN2hV2IgA0bNGd5p2eA+Dy6X38tG4OI99fgU6nZcOS9xj0xkyq+FUnOzMNlbrsdlmn07Fo+SrmTp+Cq8aZ0ePfo3mTxvj7GteBtq2aM3bUcKPXNE6OLJ73KeZmZuTm5jJ0zHiah4UWdkY8Ma86HWuXf8b70xeh0bgxafxQGjZphXeJ33E2O37eTFC1WiU+Y/3qz6nXqGmZsYzzq/DZqm9ZNGUCbs5ODH1vOq0a1yfAp4pRug7Nw3hnuHHHRaPa1flm3lQA0jOzGPDm+zSpV/J7CYIg/JMqZU6GWzf/wM3TBzcPb9RmZoS17My5ggu94n74djnPPDsEMzPzwtcsLK0IqVkfMzPT7kb+KS7qIo6ufji6+KBSm1OtYXciL+01SuMT0hQzcysAPP3rk5kWZ9ggSejyH6Jo89FpH6LT5WNt5/JoiMeKuHEVD08v3D2qYGZmRovWHTh9/EiJdJvWr6J3/0FGeb1w9hR+/oH4VzUcuO3sHVCpVCbFvRNxGTcPH1zdDfs4tEUXLp46YJTGyrrooudhXi4ShrtisfduUa12GAD2Ds5YWdsRFfmHSXFv3riGZxUvPDwN+W3Zuj0njoWXSPftujU8O+AFzMzNH/MpcPjgPlq1aW9STIuAYLQJcWiT4kGnJfvkYazrhz2SSo9kaQ2AbGWNNi21xOfYhLUi+1TJsinNH3Ep+Dja4O1og5lKpnM1bw5Expaafuf1aLpU8zb580tzOSoWH1cnvF0cMVOr6NqwOgcuRRil+f7YBZ5v1QB7a0sANHY2JT5n94UbtKwRgJW5mUlxK6NsI25cxaOKF+6eRfXnVCn1p0//wUYx/079ibtzEadi7UX1Rt2JvGjcXvgWby8CitqL5NgIvIMaI6vUmFtY4+pVjdtXDpkUN8jXnPhkLQkpWnQ6CD+fTWgtK6M0jWtZc/B0FgDHL+ZQO9hQxt7u5ly++QCAjCyF7FyFqt6PL4NHRUdeROPui7ObD2q1OfWaPsPVM/uM0lhaPdJeFLuL/sfpPTi5euPubUKnYDFxURdxdHlkP196wn72r09WsXZZq32IrqBdVkxsl0MCrIhNfEh8Uj5aHRw6lU7T+nZGaZrWt2NveDoAR85kUK+6of40rGnLnXsPuH3PMEIkM1uHqaMnL9+Nw0fjgLfGwVBvG4Rw4A/jjvLvj1/m+Rb1itVb6z+zSp5WR75O4aFWh1anPLZOP87NG9fxrFIFD09PzMzMaN26bSn19iv6DXjOqA5JEjx48ACdTsfDhw9Rq9VYW1ubFPfvHPv+quAAK2ITipXt6Qya1DMu2yb1bNl73FC2R89mUK+6IT8Natpw534ed/5C2Vbm8dajWJvcqnU7Tj6mbDesW0u/Ac9jblS2EnkFZZv3MK9cZXs34hIaDx807ob2okGzZ/jj9H6jNJaP5regvbhxMRxP3xCq+Bk6s2zsHJHlstvlazcj8PL0oIqHO2ZmZrRv3YLwE6dM+r5mZmaYmxmOcw/zteUa8hxx8wrunt64e3ihNjOjWeuOnDlRsj3f8u0KevZ7scTv+NSxg7i6e+LtW7XEe57kSsQtvD3c8HJ3xcxMTccWYRw6da5cnwGw//gZmtWvg6VF+c6ZBUEQ/q4ndjJIktS12P8dJElaLUnSRUmSNkiS5P5Xg6amJODsUvR2Z40bqSkJRmnuRF4jJSmOeo1b/tUwRrLS4rFzLOqht3V0Jys9vtT0l49vJaBmawCqBDTAJ6QJKya3ZMWklvjXaIXGI7DU9xaXkpyIxtWt8G9nF1eSk5OM0tyKuE5yUgKNQo2Hy8fGRIMk8cnk8fxn7FC2b/3WpJhg2MdOLkX5ddS4l9jHAAd+38SkN3rw/bqFDBz2HwC8/UO4eOoAOp2WpPj73L11hdTk0veVcX6TcHEpyq/GxYWU5ESjNJERN0hKTKRxWOk9+0cO7Tf5QlTlpEGbWrRPtanJqJw0RmnSftqEbdM2eM9ZjdvYKaRsXFHic2xCW5L9mJOH0iRkPcDdrugC0N3WisSs3Memjc3I4X56NqE+RfvmoVbhxW/3MWTjfvZHxJgeNz0LD8eiE2c3Rzvi07OM0kQlphKVkMKQhd/y4vz1HL1acnTGjrPX6NqwRonXS1MZZVsypmuJmLcirpOUmECjsGZGr8fcj0aSJKZPnsC7bw3jx60bTIoJkJkWj52TcXuRmVZ6HbgUXtReuHlX5/aVw+Q/zCUnK4XoGyfITI0zKa6zg5rkNG3h38lpOpwcVI+kUZGcpgNAUSAnV8HOWiYq5iGNa1khy+DqrKaqtwUaR9NGbmSkJuDgXJRfe2d30lNL5vfY7m+ZO6EzOzbNo+dLHwCQ9yCbg7+uokPf102KVVxWeffzsa34F2+Xg5uwYlJLvvywJX4mtssaRzWJKUUjQ5JStWgczUqmSTWk+XMf29uqqOJueBRl2tu+LJwUQL8uxu3MkySkZxvXWwc74tOzjdJEJaYSlZjKkC++48VFmzh67Q4A9fyrEBroTcepK+j48UqaV/OjqnvZd2EBkpOTcHFxLcqbi0uJY1BExE0SExMJDTMeBdKiZWssLS15efBzDB0ymL79BmBnZ48p/s6xDyAhPpZ33xrKlPfGcPXyBZNiahzVJKUWqz+p+SXqgMZRTVJKUdlm5yrY26jwcjcHPXz8lg8LPwzg2c6m7V+ovONtybItuY9La5Obt2yNhaUlrwwewPAhg+jTb6DJZZueGo+jxrPwbwfN49uLI7s28OnYrvyyYT59hhjai8TYO0iSxJczRzD//f7s+2m1STGTklNwcynqRHTRaEhMTimR7nD4cYa/OZ6pM+eRkFi0LxISkxj+5nief/U1nu/f26RRDACpyYloih2DnDVuJY5BtyOuk5yYQIPQFkavP8jN4edt6+n3wjCTYhWXmJKGm0vRd3TTOJGYklYi3YHjZ3hx/Ed8MG8p8Ukl98eeoyfp1LLsUbeCIJRNr+j/lf8qS1kjGT4t9v/PgFigJ3AK+LK0N0mSNFKSpNOSJJ3evrl8wx0BFEVh05r5PP/quHK/tyJcPbWd+LuXadTeMOQuLTGKlLhIhk87yIjph4i+cZx7kacrJJaiKHy9ajEvD3ujxDadTse1K5d4650pTJ+9lBPHDnPpfMXE/VPbbs/zyZJf6PviWH7fahj63Lx9Hxw17sycOIjNa+dStVo9k4ZumkJRFNasXMarI0aXmubGtatYWFji5x9QaprysglrRVb4Pu79ZxgJi6bhMmyc4TZdAfOAEPQP88iPuVthMYvbeT2ajiFeqOSimL8M78r6we2Z0S2Mzw5eJDot6wmfUD5anUJUYiqr3nyeWUN68PGmnWTkPCjcnpieRURMIs1r+FdYzMooW0VR+GrVEoYML63+XGTsO5P5ZM4STh47zMXzZyokbnFXThrai9COhvbCv0ZLqtZqw4Z5z/Pr2glUCahfYfXnSfafyiI5XcfMsZ4M6eXEjTt5KBV8cGnWaTDvfraLrs9NYN/25QDs/X4JLbsOwcLStDvrf9WVU9uJj75M4w6G/Zxa0C6PmH6QkZ8UtMsRFds+PkqlkqgZbM28VfeZOOcOzRrYFY5yqAhaRU9UUhqrXu/PrBe78fHmPWTkPuBuUhq3E1LYNWU4u6cM52RENGdv3a+QmIqisHrlcoaNeK3EthvXryHLMl+v38Sqtd/w4/dbiYstfbRWeeOWduxzctawbO1W5n6+hiHD32TRvGnk5GQ/5lMqjkqWqBlkxWerYwrLtm510+7sm6pyjrfLeXXEqBLbbl6/hiyrWLt+MyvWrufH77cQF2t6Z7cpWnYexAeLdtBj0Dj2/GBoL3SKjtvXzzL4jTmMmbqOy6f3cuPy8QqJ1yysMRtWL2PVF/NpVL8usxYuLtzm5urCqi/ms27FYnbuPUhKaskL9r9CURTWr17Ei8PeKrFt24ZVPNP7OSytKvZ39KeWjevz/bLZrJ//MaF1azJ9sXGHTVJqGpF379G0vnhUQhCEp688czI01uv19Qv+v0CSpCGlJdTr9SuAFQDhVzNLnOU6ObuRklTU652SnICTc1FP8YPcHO7fjWTWJMNJT3paMp/PGM9bH84nIKjmox9nEsMdsqK7iVlp8dg6lByMEXU9nJO7ljPgrfWoC4a9RVzcjYd/PcwtDCeT/jVaEXv7HN6BjcuM66xxJTmx6I5GSlIiGk1Rb3xubg7Rd28z9X3DASotNYXZ099j4uRZaDSu1KxVD3sHRwAaNm7Krcgb1KlfdlwnZzdSk4rym5Ycb7SPH9W4RVc2rDT0KalUaga++m7htjkfvIybp19pb30kvy4kJRXlNzkpCWdN0Z2W3Nwc7kbdZtLEcYX5nTFtEh9O+YSgEMOkiYcP7aNVW9PudAPoUpNROxXtU7WTBl2q8WRfti07Eb/wYwDybl1HMjNDtrVHyTQMm7UJa0X2ycMmxwRws7UkPrNo5EJ8Vi6utlaPTbvr+j0mtq9v9JpbQVpvRxsaebtwPSEdH8eyn9t3c7AlLi2z8O+EtEzcHYzf5+5oRx0/T8xUKrw1jvi5OnE3MZXafoa7T7vOXad93WDMTHx8ACqnbEvGTCwRMzrqNh+9N7Yw5uxp7zNxykw0Lm7UqF1Ufxo0bsrtyBvUrd+ozLh2ju5Gow8MI6Ee015cC+f4juU8N66ovQBo2nU0TbsaOlt+WTsBJzfTOlVS0rVGd141jipS03WPpNGhcVSRkq5DlsHaSiYzRwHgm5+KHgOaNsad2CQtprB3ciM9pSi/GSnxODiVPlitbtNn+PErQ32KjrzIpVM7+X3TPB7kZCJJMmpzC5p3KnuCM9ty7OeTO5czcGyxdvnCbjwDirXLNVsRe+cc3kFPbh+T07S4OheNXHBxUpOcll8yjZMZyanawn2ckaUjOTWfP27kkJFlKJPTl7II9LXkwrWyL4DdHGyM6216Ju4Oxh0U7o621PH1KKi3DgX1No3Tkfeo4+eJtYUh7y2q+3PhTiwNq3qVGVejcSEpqejOa3JS0iPHoFyiou7wwUTDxIqpqSl8Mm0Kk6ZM4+CBfTRs1Bi1Wo2joxM1atbi5s0beHh6lojzqL9z7AsMrl447DwwqBruHlWIvR9dOCFyaZLTtLg4Fas/TmZGI4MK0zgbXpdlsLGSycjWkZSq5fLNHDKy/yzbbAJ9Lbl4LafMvFbW8bZk2Zbcx1FRt5k0cTxgKNsZ0ybz4ZTpHDywl4aNQouVbW0ibt7Aw7NKiTiPcnByJy25qLMpPfnJ7UX9Zs+wbfV0AByd3alavRG29obJCmvUb8X921cIqf3kOQtcNM4kJBWNTEhKTsb1kdEIDvZFI4We6dyBFV+tf+znBPj5cOnKVdq0aFZi+6OcNK4kFzsGpSQnGB2DHuTmEB11i+kfGEZypaemMO+T//DOpDlE3LjCifD9bPhqCTnZWUiShJm5OV16DCgzrquzIwnFRiYkJKfi6uxonF+7ouN+rw6tWbJ+q9H2veGnaBPWELUJc14IgiBUtLK6y90kSRovSdIEwF4ynsr6L3e1BwTXJCE2msT4+2jz8zl5ZBcNwloXbre2seWLdXuZt/Jn5q38mcCQ2n+rgwHAw7cOqYl3SE+ORqd9yPWzv1K1jvHFTkL0FfZumkKvEcuwtisaBmvnVIV7EadQdFp0unzuRZ7C2d20xyWCQqoTG3OP+LgY8vPzOXpoL42bFD0CYmNjy5oNv7B0zRaWrtlCcLWahSdZ9Ro14W5UZMFzk1quXD6P9yMTOpXGL6gWCbF3SSrYx6eO7qRuaBujNPGxUYX/v3z2MG4ehpm8H+blkvfAcPF85cIxZJXaaAKrJwkOqU5szH3i42LJz8/nyKF9hDUtOpDb2NiybtOPrPxqIyu/2khI9ZpGF6GKonD08AFatW5nUjyAvDs3Ubt7onZxA5Uam7BW5Fw4aZRGm5KIVQ3DJIxmnt5IZuaFHQxIEjaNW5S7k6GmhxPRqVncT88mX6ew6/o92lQtefJ9OyWTW0XwcgAAIABJREFUjLx86noWnRBlPHjIQ63hZDY1N48LMclU1diVeO/j1PL15G5iKveS08jX6thx9hptahs/C9++bjCnIwwTX6Zm5RCVmIq3S9EJyu9nr9K1kemPSkDllG1QSHVi7xvXn9AmRUNSbWxsWbvxZ5at3cyytZsJrl6TiVNmEhRcnfoNw7h751ZR/bl0Hm8ff5PievjVITXhDmlJhvbi2plfCXykvYiPvsKujVPoO2oZNsXaC0XRkZtluNhPvH+NxPvX8a9hPIy2NJHRD/FwUePqrEalgub1bTj9h/EjOKf/yKFNY8PJZdO61vwRYRihYm4mYWFuaKLrBFuiKBhNGPkk3lXrkBQXRUrCPbTah1w4/hs1GhqXU1LcncL/Xz9/EBcPw4XQa5PXM3HBXiYu2EuLLi/TtudIkzoYwNAupyXeIb3Yfn5cu7znuyn0HmncLts7VeHezWLtcoRp7fKNO7lUcTPH3cUMtQpahzpw4oLxKKIT5zPp0Nyw8kvLRvZcvG7oRDjzRxZ+XhZYmEvIMtQOseZurGkreNTy8eBuUhr3ktMN9fbcDdrUMv6+7WsHcjryHgCpWbmGeqtxwMPRjjOR99DqFPJ1Os5E3ifAxMclgkOqERNzn7iCenvo0IFH6q0NGzZtY/VX61n91XqqVa/BpCnTCA6phqubGxcvnAfgwYNcrl+7irdP2ZNNwt879qWnp6LTGdrH+LgYYmPu4eZR9sXvzT/LVlNQto3tOXkh0yjNiYtZdGhqKNsWDe0LOxHOXsnC38sSC7Oiso2OeVgixuP8fzneHj60n7CmRY+e2NjYsn7TD6z8agMrv9pAteo1+XDK9GJla3jG31C2V0wuW5/A2iTF3SW5oL04d+w3ajUybi8Si+X36rmi9qJa3RbERt/kYV4uOp2WyKuncfcqO7/Vg4O4HxNLbFw8+fn57Dt0lGZhxqtwJKcUdbKGnzyNr4+hEy4xKZm8vIK5NrKyuHzlGj5eZf+eAAKDaxAXE01CXAza/HyOHdpDo7CiCW6tbWxZsWEHn6/+gc9X/0BQtVq8M2kOVYNr8NHs5YWvd+31HL0HDDGpgwGgRlAA0bHxxMQnkp+vZc/Rk7QKNb5RkVRsNMbh0+fx9zI+/9h9RDwqIQgVSdH/O/9VlrK6N1cCf175fA24AImSJHkA5/9qUJVKzeAR7/LZx2+i6HS06tgLL99AftiwHP+gGjQIa/PE978zoicPcrPRavM5d+IgE6YuLrEyxaNklZr2/afw/dLh6BUdtZr2w8UzmPBfF+HuW5vAOh04tH0O+Q9z+HWt4a6onZMnvUcuJ7h+F6JvHGfdrJ6AhH+NViUuOJ6U12GjxjFjygQURaFdp+74+AWwaf0qAoOrE9qk9DknbG3t6NHnOd4bPwIJiQaNmz722dXS4j43/D0+/2Q0iqLQvH1vqvgE8dOmpfgF1qReaFsO/L6JaxdPoFKrsbax55U3pwGQkZ7CF5+8jiTJODq78epbn5gU0xBXxYjRb/LxpInoFB0dO3fD1y+ADevWEhQcQljTJ19s/XH5Ii4ubibdTSmkKKRsWIH721MNS1ge3Ut+TDSOvQeRdyeC3AsnSd28Fs2QN7Dv1Av0epLWLCp8u2VILXQpSYaJI8tBLcv8p319xnx/FJ1eT+9afgS62LMs/Ao13R1pE2jIw67r0XQO8TaaKO92SiYz9pxDliQUvZ5XQqsZrUrxxLgqmff7dWT0sq0oikKfpnUI8nRhyW9HqOXjQds6QTSv7k/4tdv0/XQNsiwxrncbHG0MIyfuJ6cTl5ZJ40DTTij/VBllq1KpGT76bT6Z/A6KotC+0zOG+rNuNYHB1Qht+oT6Y2dHzz7PMXHcSCRJomHjpiXmbSiNrFLTYeAUti0ZjqLoqNOsHy5VgjnyyyI8fGsTVLcDB3+YQ35eDj+tMrQX9s6e9B21HEWnZeMCw0W2haUt3YfMRTZ5VQtY80MKH4xwQ5bgwKks7sXnM6CLA7eiH3LmSi77T2Yx5gUXFr1XhawchUXrDXf3HGxlPhjhjl5vGBGxeGNSGdGKqFRqer08iTVzh6NXFBq3fhZ372B2b/scr4Da1GzYnmO7NxDxRzgqlRlWNvYMGDnT5M8vjaxS027AFLYtHY5er6N2Qbt89FfDfg6s04FDPxr28y9ritrlPq8tJ7hBF+7ePM43M3uCZHq7rCiwfEMc0972RZYkdh9N425MHoN7uXIzKpeTF7LYdSSNCcO8WDEjiKxswxKWANk5Cj/uTmH+hwGgN4xkOH3JtMec1CqZ959tx+gVP6Do9fQJq0WQh4YlO45Ry9uNtrUDaV7Nj/DrUfSd8w2yJDGuZyscbazoVC+YkxHR9J+3DkmSaF7Nj7a1TJtITqVSMWr0GD6a9D6KotCxcxf8/PxZv+4rgoNDaNK09GNK9x69WbRgLq+PGg56PR07dSEgwNS4f/3Yd/XyBb77djUqlRpZlhj5xjsmzRegKLB8Uxwfj/VBliX2HE3jbuxDBvd04WbUA05ezGL3kTTGD63Cl9MDycrWMWeV4bGT7ByFH/ckM/+DAPR6PacvZ3P6smllW5nH25Gj32TqpIkFy4R2w9fPn2/XrSUouNoTy/aZHn34fMEcxowail6vp0OnrvgHmNa5oVKpefaVD1kxcyR6RSGsbV88fILYseULvANqUbtxe47u2sCNS8dQqdVY2djzwmjDyA1rWwfaPDOEhR8+hyRJVK/fipoNn3zO92de3xw1nIkffYJOUejWsT0Bfj6sXb+JkOBAWjQJ5fuffyP8xClUKhX2drZMHDsGgKjoeyxf8zUgAXoG9u1FVX/TRouoVGpeGTWBWR+9jaIotO3YA2+/qmxZv4KqwTVo1KR8K+qYSq1SMWH4YN7+ZAGKotCjfUuq+nixYtOP1Aj0p1VofTb/tpcjp86jUsnY29owaUzRsqmxCUnEJ6fQoGbIP/L9BEEQyiLpy1jfTJKk6oAXcEKv12cVe72rXq/fUVaAxz0u8U+7eNe0O8IVrXnVkhM9PQ3JDyonvx7WJScZehqsZpZ/grm/y6XxXx9F83eo/U076atot4O7VUpcrf7pD+s8fucvz2H7t+zZEVV2on/AcwPL17lUURLTnv5iRj9vufLUYwJs7V1ytaSn4W6N7pUS94Fi+dRjfjgvuexE/4DxY/wrJa6ndeXkNyK97CUtK1oD26tPPSZAHGU/fvRPCMirnHYKwLlOxUyuLggFpLKT/HuNnptWieMC/rpl7zpWSrmUtbrEm8B24E3gsiRJvYtt/vTx7xIEQRAEQRAEQRAE4X9RWbcNRwKN9Hp9liRJ/sBWSZL89Xr9Iv7Le6sEQRAEQRAEQRAEoTKXg/w3KquTQf7zEQm9Xn9HkqS2GDoa/BCdDIIgCIIgCIIgCIIgFFPWQ7LxkiQVTmdb0OHQA8MEkHX+yS8mCIIgCIIgCIIgCMK/S1kjGV4GjBaZ1uv1WuBlSZK+/Me+lSAIgiAIgiAIgiD8P1DWYgmCsSd2Muj1+ntP2Ha04r+OIAiCIAiCIAiCIAj/Vk9/TTFBEARBEARBEARBEP4riU4GQRAEQRAEQRAEQRAqRFlzMgiCIAiCIAiCIAjC/yxFLGFZLmIkgyAIgiAIgiAIgiAIFeIfH8ngp7rzT4co4YZF5ayu6ZUXUSlxHaw0lRI3UetWKXFdPJyfeszYwxeeekwAz0qJCtkB1pUSNzrd/qnH9HfNe+oxAfJyKieup11WpcS1t7SolLiVQbFzqpS4vpF7KyVuhvfTP+bm5aieekwArVI592bcsyIrJe5tyf2px3RMrpy8qh0fVkrcbMunf04DkDNpHImVELfadzsrIaogCE+bGMkgCIIgCIIgCIIgCEKFEHMyCIIgCIIgCIIgCEIp9HoxJ0N5iJEMgiAIgiAIgiAIgiBUCNHJIAiCIAiCIAiCIAhChRCPSwiCIAiCIAiCIAhCKfRiCctyESMZBEEQBEEQBEEQBEGoEKKTQRAEQRAEQRAEQRCECiE6GQRBEARBEARBEARBqBBiTgZBEARBEARBEARBKIWYk6F8xEgGQRAEQRAEQRAEQRAqhOhkEARBEARBEARBEAShQlTa4xInz5xj8cq1KIrCM506MGhAX6PtO/bs58u163DROAPQp3tXunfpSFxCIlNmzEGv16PVaunbsxu9unUxKWbk5UPs2TwDRVGo33IAzbqONNp+9uBGzh7YgCTLmFtY0+3F6bhUCQIg/PcvuXB0K7Is0+m5SVSt1crkvB4/d4mFazagUxR6dmjNy892N9r+674jLFn3Ha7OTgD069aBXh3bABCXmMzMZWtJSEpBkiQ++3Acnm4uJsU9dfoMy1asQlF0dO3cmecH9jfavmv3XlauWYtGowGgd8/udOvSGYAPJn/E1es3qF2zBtOnTjE5rwAXzhxj3aoFKDqFtp170av/y49NdzJ8H4tmfcD0z9ZSNbgGkTf+YNWSWYaNej3PvjCc0GZtTYppFlwb22cGIckyuWcOkXvoN6PtsoMzdv2GI1laI8ky2bu28vDGRcwCa2LTeQCSSo1epyV752byb101Oa/WdRvh+tJrIMtkHNhJ6s9bjLarNa64jxqPbG2LJMskbVpLzoXToFLhPnwsFgFBSLJMxpF9pP602eS44XfimHfgIjpFT5/a/rwaVs1o+2cHLnL6XiIAD/J1pOTmcfD1ngCELvyeIBcHADzsrFjQu7nJcSujbK9fPMzP62aiV3SEtu1P254jjLYf37uJY3s2Issy5pY2PDt0Ku5eQaQk3mf+xB64evoD4BtUj76vTjU5r1fOH2Hr2tkoikLzDs/Suc8wo+2Hd23m0M5NyLIKC0trXnhtCp7egei0+Xy7fCrRt6+iKDrCWvekS9/hJsdtUNOa4QPckCXYHZ7O97tSjbar1RJvD/Eg0MeCzGwd81bHkpCipXWoHX07OhWm8/OyYMKsu9y+l2dS3Itnw9mw6jMURaF1p9706PfKY9OdCt/HkjkT+Wje1wQE1eTy+RNs+WYxOm0+KrUZz73yFjXrhpqc3z/OFe3nFh2epXPfx+znHZuQCvbzoNem4OkTiDY/n40rpnE38g8kWab/qxMJqWVa3Ia1bBj5vAeyLLHrcCpbdyQbbVerJcYPrUKQnxWZWTpmr7hHQnI+AP5eFox5yRMrKxm9AuNm3CZfa9oQyqOXbzL3u99RFD19WjZkaLeSx5Fdpy+z/OcDSECIjwczhxe121m5D+j30RLa1a/Oe4O6l3hvqXGv3GL2tj0oikLfZvUY1rlZiTQ7z15l+e9HAIlqXm7MeqUXALEp6Uzd+DvxqZlIEiweNQAvjaNJcU+cvcCi1etQFIUeHdvyYr9eRtt/23eQpV9vLDz2PftMZ3p2agdAm34vUtXXBwB3VxdmfTDBpJiN69gx+iVvZFlix4Fkvvsl3mi7mVri3df8CA6wJjNLy4zFd4hPeli43VVjxqpZNVj3Qxxbf0swKSZUXntx7PxlFqz9DkVR6NWhJS/36Wa0/ZcD4SxetxVXZ0OZ9e/ajt4dWnHm8jUWfl10zImKiWP62BG0CWtgUtyr54/w/dez0Cs6mrbvR8fext/56O7vOLJrE5IsY2FpzXMjpuLhHcjpI7+w7+e1heli795gwswtePtXLzPm0YvXmbfhJ3SKnr6tQ3m1R7sSaXadvMCXP+4x1B/fKnw66gWuR8Xw6Tc/kJ37AFmWGdazPV2a1DMpn2D4HX++6hsURaF7p3Ylfse/7z3I0q834OpsOF99tntnenQq+m7ZOTm8/OZ/aNmkEeNGvmpy3JNnzrJ0xWoURaFb5468MKCf0fade/axYs3XhefJvXs8wzNdOhFx6zaLliwnJzcXWZYZNLA/7Vq3NDmudb3GuL8yCmQV6ft+J2W78bmJWuOK5xvvIlvbIMkyiRvWkH3+FKjUeIwci2XVYPR6PQlfLSP3ykWT4wrC/3eKXjwuUR6V0smg0+lYtHwVc6dPwVXjzOjx79G8SWP8C04o/tS2VXPGjjI+cGmcHFk871PMzczIzc1l6JjxNA8LLWxkS6MoOnZtnMbzb6/F3smdr2b2J7hu+8JOBIBaYT1p2OYFAG5e2MueLTN5fuxqkmIiuHr6V0Z89CtZ6fFsXPAqr03fiSyrTMirwryV61g05R3cNM4MmziNVqH1CfDxMkrXoXkYE0a8VOL9079YyZB+PQmrV4uc3AfIslRmTENcHYuXfcmsT6bh4qLhzXETaNY0DD9fX6N0bVq3ZMzoUSXeP6DfszzIy+O333eYFO9Pik7HV1/O4/1pn+OscWPyhFdpGNYKb98Ao3S5Odns+GkzgSG1Cl/z9gvkk/lrUanUpKYk8cHYl2gY1hKVqoyfqSRh1/Ml0tbOQ8lIwWnUFB5ePY8uMaYwiXXbnuRdPsWDk/tRuVbB4eVxpHz2LvqcLDLWL0LJTEPl5oXDKxNImTPetMxKMq6vvM79mR+iTUnCd/pCss8e5+H96MIkzn2eJ+v4YdL3/oa5lw9V3p3Gnbdfxa5JKyQzM+6+9zqSuQV+c5aTGX4AbVLZJ7U6Rc+s/2PvvMOjKrrH/7lb0jdlN7ubHpLQQSAkQIDQuyAqdrCggqKCgAULNhQQFFEECwiiIir2hgpI710glDQghPTdTa+7e/f3x4ZsliRk8UXze7/v/TwPD7k7Z+65M/femTNnzszdcoz3xyWiV3lyzxdbGRATTLTGt07myYFd6v7+6mg6yQVFdcfuCjlf3j3EtTLWoyXurSha+enTuTz4zEr81HqWvXQHHboPQh/qeG+79RlDwpA7ATh1ZAvr177BA7NWAKDRhTN93g9XX1bRyter5jP1hRX4a/S8+dxdXBc/kOCwmDqZ+MTr6Tf8dgCOH9rK95++yWOzP+TIvo1YLGZmv/U9NdWVzH3iZuL7jkKjC21KXR0yAR6+Q8fL72ZhLDLz5jORHDhezsVcxyBoWB9fyiqsPPLKeRLjVNx7s5ZFq3LYcbCUHQdLAYgMceO5h0NcdjCIVitrlr/B03OWodbomfP0fcT27E9oeLSTXGVlOZt+/Yrotp3rflP5+jPjhcUEqLVczEhj0ZzHeefj3y5X0aTer1fNZ9qLK/BX63njUj2HN1HPB7fy3advMvWFD9m9+TsAZi/+ntJiI+/Ne5RZC+zOpishE+CR8cG88HYGxkIzb8+OZv+xUjJzHHU8PNGf8gorD81Oo38PXybeouONFVnIZPDkpFAWr8ri3MVqVN5yrFbXjA6rKLLgi/V8MPNe9AG+TJi/ggFd2xEToquTycgz8vHvO/lk1oP4entiKilzOsf7P22he9tIl/TV1zv/m40sf+xO9P4qxr/5CQOva0NMsMNZnZFvYtWmvXw68x58vTwwlpbXpb2w5lcmjehD7/ZRVFTXIAiu9kEii1d8wtuvPIdWo2byrBfp27M7UeFhTnJD+iYw86GJDfK7u7mx+u3Xr6qsMgGm3hfOswvTMJjMLH21HXuPFHMhu6pOZuQADWXlVu5/6hQDE/x58I4Q5r93vi59yvhQDh4vuSq9LdVeWEWRRau+4N0XZqLTBHD/c/PpF9+VqLAQJ7mhfeJ56sHxTr/FdW7PmjftEwjFZeXcNm02vbp2dLm83348l0dmf4S/JojFz99B57hBBNUrb1zf0fQddgcASYe28uOaN5jy3HLiE8cQnzgGgOwLKaxa9LhLDgarKLJwzY+8//Qk9Go/7p6zjAGxHYkO1dfJXMg1sPrXbaye/Qi+3l5174+Hu5LXJt9BRFAgBYUlTHjlXfp0bovK27N5vVaRt5evZvGc59BqNDz09Ask9uxOq8ue48GJCU06EFZ+8Q1dOzZfRme9VpZ+sIKFc19Bq9Hw2MxZ9OnVk8gGdnJfpj3iPGHm4e7GM09MJyw0BIPRxKMznqJH91h8fLybVyzI0D/wGBfnPYfZaCDy9aWUHdpHTdaFOhHNuPGU7t1B0aZfcQuNIOzZ1zg77T78h9gdXOefnoLc14+w5+aR8fw0kAZmEhL/k1z1cglBEDT/qdIzqWmEBgcREqRHqVQyuH9f9uw/6FJepVKJm1IJQI3Z4vImHNnnjhOgiyRAG45c4UaH+NGkHNvsJOPu6VP3d011ZZ0xlXJsMx3iR6NQuuEfGE6ALpLsc655Z0+lnSUsSEdokA6lUsHQxJ7sPHjUpbznMrOwWkV6drUP1rw8PfBwd3cpb3JKKiEhwQQHB6FUKhnQvx979u13KS9AbLeueHk23wFfTnrqKfTBYeiCQlEolST0G8bh/TsayH27dgU33HIPbm5udb+5u3vUDTrNNTUN8jSFIiwaqzEfsbAArFaqThzArUPD2RjB3V4ewcMTsdQ+6LbkXKj725qfhaBQQnNOjVo8YtpizsvGUpALVgul+3bgHXfZDKHNhszTCwCZpzeWQmPtzzYEdw+QyRDc3LBZLIiVFS7pPZlrItzfmzB/b5RyGcPbhbEtPadJ+Q3JmYxoF9Zkuqu0xL3NTD+BRh+BRheOQuFG14RRnDq8xUnG47L3FtfGQFfkfFoSgUERBOrDUCiUdO8zkuMHtzrJeHrV01vlaC8EBGqqKrBaLdTUVCNXKPGoJ3sl2rTyIKfATJ7RjMUKuw6X0Kurs2HYs4sPW/fZB0F7jpbSpZ1Xg/P0i1ex83Cpy+U9m3oSfXA4uqAwFEolvRKHcXT/9gZy36/9kOvH3YtS6bi3kdHtCFBrAQiNiMFcU43Z7No9Pp+WhPZSPSuVxPUdyfFDV6jneu1y7sV02nbuCYDKT4Ont4oL6Seb1dk2ypOcghryDPY63nGwmIRuKieZhG4qNu8pBuz3oGt7+z3o3tGH8xer6pw3peVWXN0HKulcFuE6NWFaNUqFghE9OrPt2BknmR92Hub2gT3xrR38qH0dZT+VkY2xpJzeHWO4GpIycggPDCAs0B+lQs7IuI5sO5HqJPP9nmPc2S8OXy8PADQqe3nTcwxYRBu929sdiV7ubni6KV3Sezo1ndBgPSG1fd+QxAR2HTh8Vdd+tbSL8SI7r5rcghosVhvb9xXSJ87PSaZ3dz827bK3wzsOFBHbyXHv+8T5kVtQQ8bFKq6GlmovTqWds9sXei1KhYJhfXqw4+Cxq7p2gK37DpMQ29ll+yIj7URtecNRKJTE9hnFiUOXtcv1ylBdXUljDfOR3b/Rvc+oBr83RtLZTML0GsJ0Gvv706sr246ecpL5fvsBbh/SG19ve5t46f2JDNISEWR3qmkDfAnw9aGwniPtSpxOTat9jvW1z3Fvdu13/TlOTjtLYVExPbpd53IeqLXhgoMJCbLbcAP7J7J73wGX8oaFhhIWanc0BWrU+Pv5UVRc7FJej9btMOdlY86vtWv2bMOnx+WRT/XsGi9vLIUmANzCIqhI+gsAa0kx1vIyPKLbuqRXQkLi/x5XHE0JgrAAWGSz2QyCIMQDXwOiIAhK4F6bzdbQCnUBg9GELtAxixKo0XA6JbWB3M49+zhx8hRhISE8OmkiOq09T36BgedfnU9Wdi4PP3BPs1EMAGVFefgGBNUdqwL0jToKDm9dy4E/V2O1mhk/81MASovyCI3q6pS3rCivQd7GKDAVog90XJ9WreZUanoDuW37DvPXqRTCQ4KYfv+d6AM1XMjOw8fbi+feWEp2voEe13XkkbtvQy5v3jdkMBrR1qtjbWAgZ5KTG8jt2r2XE0knCQ0NZcrkB9FptS6VqylMxgI0gY6ZOXWgjvRkZ8P/XPoZjIY8Ynv0Zf0PnzulpSUnseLdeRgKcnlk5svNRzEAMt8ArMWmumOxxIQyzNkQr9j8I34Tn8IzYQiCmzvFq99scB63TvFYcjLAanGprAq1BovRUHdsMRnwiHFetmD8fi2hz87Db8RYZO7uZM2fDUDZgV34xCUQ9d5aZG7uFHy+ArHcedayKfLLqtCrHA4gvY8nSbmmRmVzSirIKi6nR7jjntRYRO5euwW5TGBij3YMah3SaN7LaYl7W1KYh5/a8d76qYPITG/43u7d9AU7//gUq8XM5Oc+dlxzQRZLXhiHh4cPw297nKh28S6VtdiUR4DGMUMWoNFzPvVEA7ntf3zF1vWfYbGYefyllQDEJgzj+KFtzH5oCDU1lYy7bxbePn4N8jaG2l+BodDx/BkLLbRp5dmkjChCRaUVlbeM0nKxTiYxTsX8D7NxlUJTAepA5/KeTU1ykjmffgaTIY9u8Yn8/sOaRs9zaO8WIqPbOTkhrkTRZfXsr266nrf8aq/n6S/b6zk0sh0nDm0jPnEUhYZcMs+eptCYS6s2VzbmNf4KCkzmumNDoYV2UZ4NZQrtMvY6FvH1kROid8Nmg1dnRODrI2fnwRK+2+C81KIp8otK0Ksdz4He34+kcxedZDLy7OeauHAlomjj4RsG0rdzG0RRZPE3G5j34Dj2nz7rkj6H3lKCAhwDaZ2/ihPnnZ+NjHx7+3Hf4jVYbTYeGZVI347RZOSbUHm6M/Oj78kyFZHQrhXTxw5E3ky0CECByYQu0DEnodWoOZ3SWN93kL9OnSE8JIhpD9yDvjZPTY2ZSU+9gFwuY8K4sfTv1fy7GxjgRoHJ4eAqMNXQPsbZSReoVlJgdNzb8gorvj5yasw2bh+t59mFadx2vY6roaXaiwJTEbp69o9O48/J1HMN5LbuP8LR06lEBOuZcd/tTjYJwKbdB7lrzDCXdAIUm/IJ0DjaZX+1noy0huXdueFLtq23t8uPvfhxg/Sje/9g0tNLXdJZUFhMkNqxTEcX4EfS2QtOMhdy7UsE75/7PlZR5OGbhtG3i3OfnHQ2E7PFQpiuebsRwGAqbPAcn0pNayC3fe9Bjp08Q3hIMFMfuAe9VoMoiry3ei0vzHyUw8eSGuS5ol6jqc7mBdAGajiTnNJAbueefRyvtZMfmfyAUx6AM8kpWCxmQoKDGuRtDIVag9lYUHdsMRrwaO0chWH45nPCZ8+GTnz/AAAgAElEQVTHf+RYZO4eZM59FoDqjLP4xCdQsnsrSo0Wj+g2KDRaSG9oe0pISPzfpzlLYbTNZrs0inoTuMNms7UGhgFvNZVJEISHBEE4JAjCoc/Xffu3Lqx3z3i+WPUBK5cuJq5bFxa8s6wuTacNZOXSxaxZsYwNm7djKiy6wpmujrhBE3hk3p8MGvcUu3/74Jqd90ok9ujGdx++yZq3X6Nn1468ttRufFhFK8dOpzD13jtYtfAlsvMK+G3rrmumN6FXDz5bvZLl7y2le2w33lz8zjU7d1OIosjaVUuY8MDjjaa3bteZN977ktfe+pifv/2MmhrXwr2bw71LL6qO7sL05pMUf/Y2qlsnQ72wX7kuBJ8Rt1H606fXRN8lVL0HUrJjE+en3Uv2Gy+jf/QpEAQ8YtphE0XOTb2b8zPvJ+D6cSi0rhkBV8OG5EyGtg1FXm+Zza+TRvL5hMHMG9WTt7YfJ7PINedGc7TUvQXoPWw8s97awKg7nmDLT8sB8PXX8uw7m5k+93tGT3iGr96fRVXltSnrJQaMvJNXlv7GjRNm8Md39iUa59OSkMlkzFv+J3OW/c6WXz7FkHexmTNdO9q08qC6xsaFHNcjRppDFEW+/Pht7rx/RpMyWRfS+frTpUx85PlrpvcSA0beyZxlv3FTvXruPfgm/DV6Fj5zF99+8gZR7bq6tITtP0EuF+jYxotFK7N45o3z9I5V1UU5XAusosiFfCMfPXk/r0++ldfW/ExpRSVfbztIYuc26ANcG3xeLRZRJKPAxMrp41lw31jmfPk7JRVVWEWRo+kXefLmwXzx1EQuGor4aX/DweTfpW98d75Z/g6fvrOAHl2vY/6SD+vSvlmxhJWL5vLyzKksXbWGrBzXHPt/l3vGBfH9H/lUVYvNC/9NWqK96BfXhR/ee521i16mZ5cOvPreaqd0Q2ER6ReySHBxqcRV6R5xFy+++wc3jH+CjT8sd0o7n3ocN3dPgsPbXDN9FlEkM8/Aimcf5vVHxjP3k+8oLa+sSy8oKuHFFV/xyoO3Nbus6mro06M7X69YwidLFhLf7Trmv2u3HX/4fRMJcd2cnBTXkoSe8Xz+8XI+WvYOcbFdeePtJU7pRpOJBYuX8NSMade0vL59B1K8fRNnH72biwteJHjqLBAEirduqF1isQztfY9QmXIKROs10ysh0dLYRNt/5b+WorlWRyEIwqXpRk+bzXYQwGazpQBNxtXZbLYVNpst3mazxd99x60N0gM1avINjhlgg9GI9rJoBD9fVd2yiOuHDyE1reHsTaBGTVRkOCdONb9Rn4+/npLC3Lrj0sI8VP76JuU7xo8m9a8/AVA1ktfnCnnro1UHkGdwzDIXmExoNQFOMn4qn7qy3jBkAMlnMwDQadS0aRVBaJAOhVxOv57dST6X4ZLeQI2Ggnp1XGAw1G3weAlfX986vaOGDyM1reEs09Wi1mgx1ttXwGTIJ0DjiI6oqqwgM+Msc2c/yvRJN5GWfJK35j3N2VTnexgaHoWHhycXM5qftRNLCpH7OZ4fma8aa4nzZnkecf2pTrIvybFkpiMolAi14Zwy3wB8x0+j5NuPEE0FuIrFZEShccwaKNSBdcshLuE7cDhl+3bay552BplSiVzli6rPQCqOHwarFWtJMZUpp/CIds3Y0vl4kFfqMJzyyirR+jS+tGVj8kVGtHNew6mrlQ3z9yYuLJDkfNfCKFvi3voG6Ck2Od69YlMuvgFNzzJ2Sbiek4fty6AUSje8VfaZr7CoTqh14RhyzrtSVPzUegqNjkFNoTEPP3XTeuP6jKoLjz606zc6duuLXKFE5achul2sS2H8AKYiC4EBjggPTYACU7G5SRmZDLw85U5RDP3iVOw85PpSCYAAtRaTwbm8l5ZAgP3eZl1IZ8ELU3hy8ljSU5JYMu9JzqXZw5VNhjzeXTCLh2bMQRfs+tIc/8vquciUh7/mCvXcdxTHDtjrWS5XcOvEWTy/6BumPPMuleWl6IKb36/AWGRBq3aE/AcGKDAWmRvKBNhl7HUso6TMirHQzMmUCkrKrFTX2Dh0ooyYCA+Xyqrz9yXP5HjX8oqK0QY4L9PQBfgyoGt7lAo5oYEBROo1XMg3cfxsJuu2HuD6597m7W828uu+Yyz5fpOLelXkFjqeh/yiUvT+znr1/ioGXtcGpVxOWKA/kTo1FwoK0furaBemIyzQH4VcxqAubTmT6dpgX6tWk29wtIcFRhOBl/d99fr5MUMHkXzWMQt/ySYICdLRrXMHUs6db1anobAGrdoRRaNVu2EsdL63BpMZrcZxb7295JSUWWkf482kO0P4bHFHbh6h5c4b9Iwd6tomyy3VXmjV/uQbHfZFvrGobhPNumurZ1+MHdKPM2edbYjNew8zoGcsCoXrW3T5qXUUGh3tcpHpyuWN7TOKEwedl1Mc3fO7y0slALQBfuSaHBNK+YXF6C5zuukD/Ogf28H+/mjVROgDuZBnt4PKKquY/vZqHrtlBF1au76vSaA6oMFzfGmDx0tc/hynpNuf45PJqXz/20Zun/w473+ylg1bd/HhZ1+6plejJr+gvg1nbGDD+TnZcENJqWcnl1dUMHvOPB64ZwId2ztHc1wJi8mIsl6/rtAEYik0OMn4DRpJ6V77Usmq1NMISjfkKl8QRQo+W07GM4+SvegV5F4+1ORkuaxbQkLi/xbNORneB34TBGEw8IcgCEsEQRggCMIc4K+/q7R9m9ZkZeeQk5uH2Wxmy47d9O7pvCu40eQYJO45cIiI2o0SCwxGqqtr18OWlZF06gzhoc2He4e0uo7C/PMUGTKxWmo4fWg9bboOdpIx5Z2v+zvtxDYCdPaOqE3XwZw+tB6LuYYiQyaF+ecJieqCK3RoHcXFnHyy8wowmy38uesAifHO+wUY6kVi7Dp0lFahwfa8MVGUlVdQWGxff3046XSDDZ2aol3bNmRlZZOTm4vZbGb7jp307tXLScZochgne/cfICL8P1+3H92mA7nZmeTnZmMxm9m3cxNxvRw7qHt5+7B87QaWrPyRJSt/pHW7Tjw5+02i23QgPzcba+1ShYL8HLKzMtDqg5vVack6h1yjQxYQCHI5Htf1pOaM874XYrERZXQHAOTaYFAosZWXInh44nfPDMo3fovlQsMQyCtRdTYFt6AQFFo9yBWoEvpTfnif87UZC/Ds3A0AZUg4gtINa0kxFkM+Xh3tS3AEd3c82rSnJjuzgY7G6BgUQGZhGVnF5ZitIhuTLzIgumE9nTOVUlJtpkuwwyAqqaqhxmKfWSisrOZYtpFojapB3sZoiXsbFt0ZY24GpvyLWCw1HNv3Ox27O+8obsg9X/f3mb+2Exhkf2/LSkyItbMoxvxMjHkZqHWuPeORMZ0oyMnAkH8Ri8XMkT1/0CV+oJNMfo7DWD95ZAfaYPumqurAYJKT7Gtnq6sqOJ96HH2o8+aYTZGaUUWwTolOo0Ahh8Q4Xw4cd147fOB4GYMS7Jt89olVcSLZsZeHIEDfv+FkiGrTkbycCxTkZWExm9m/axOxPfvXpXt5+7BszZ+89dHPvPXRz8S07cz02W8R1boj5WWlvD13Jrfd8xhtOri+YztAZOtO5OdkYMi7iMVs5vDuP7iumXrW1dZzTXUl1VX2sp8+theZXO60YWRTpJyvJETnhj5QiUIO/Xv4sf+Yc4TL/r9KGdLHPoBJjPPleLL9Hhw+WUZkqDvubgIyGXRu68WFHNcicjq1CuFCvoksQyFmi4UNB5MY2NU5DHlQt/YcSrEPUApLy8nIMxIaGMD8Sbfy+8In+O31mcy8bThjEroyfZxr4e2dIoK5UGDioqEIs8XKH4dPMeC61k4yg7u05VCqPfS8sKyCjHwTYYH+dIoMprSiClOpvZ4PpGQQHeTarGz7NtFczMklOy8fs9nC5l37SOwR5yRjqNfP7z54mMja/q20rJwas905UFRSStKZFFqFN78RYvLZCkKD3AnSuqGQCwxICGDvEWcn6t6jxQxLtJehf09//jplf1eenJvKvU+c4t4nTvHDhgK++iWPn/80NNDRGC3VXnSIaUVmTj7Z+QbMFgub9hykX7zzO1jfvth56Bitwpzb3Y27DzC8r+tfgwGIiOmMIfcCxtryHt3zO53jnNvlgnrlPXXUUV6wR0b9tW8DsVfhZOgUFUZmnpGsApP9/dl/jAGxHZxkBnbvxOEz9oF2YWk5F/IMhOrUmC0Wnnz3M0b36c7QHq7Zbpdo3ybmsud4L317Nvcc25/Vl56Yyrcrl/L1R+/y6MQJjBiUyJR773JJb7u2bZzs5G07dtGn1+V2cn0b7mCdDWc2m3ll7gKGDR5I/0TXvx4FUJWejDIoFOUlu6bPQMoOOds1ZkM+XrV2jVtoOLJau0Zwc0eo3dfD67ru2ESr04aREhIS/1tc0XVts9mWCoJwAngEaFsr3wb4EZj7d5XK5XKmTZnEMy/PxSqKjBo6mKjIcFZ//hVt28TQt1cPvv/lN/bsP4hcLsdX5cMz06cCkJF5kQ8//hT7JkI2br95LNGtmvdKy+QKht35El8tmYRNtNKl7y1oQ9qw4+clBEd2pk3XIRze9jnnT+9FJlfg4eXLmPsXAqANaUP7uFF89Mr1yORyht/1ksthuQq5nCcmTWDma29hFUXGDO5HdEQoH335A+1bt6Jfj1i+Wb+JXQf/spfVx5vZUyfV1pOMqffdweOvvIkNG+2jW9V92tKVOp76yMM8/+IriKLIiGFDaRUZwadr1tK2TWt6J/Tix59/Yd/+A8jlclQ+Kp6a6QiFfmLWs2RmXqSyqorx997PE9OnER/X3QW9CiY+/BQLX5mOKIoMGDqGsIhovl27gqjW7Ynr1b/JvMmnj/HLa58hVyiQCQL3T3kala8Ln0oTRcp+XYvffU8iyGRUHd6JNT8bryE3Yck6T82Zvyj7fR2qmybi1cf+ic7S71cB4JkwFLlGj/egsXgPsn+WquiTRdjKXRikiSL5n3xA6DNz7Z+w3L6RmqwLqG+5m+pzqZQf2Y9h7UfoJk0nYORNgI285YvtOjb9iv7hmUQs/AAEgZLtm6jJPN+8TkAhkzFrcDemfr8bq83GjZ0iiQn05YM9p+io92dAjN1Q35icyfC2YU67wZ8zlTLvz6PIBAHRZmNij3ZOX6W4Ei1xb+VyBWPvnc3Hb05GFEXi+9+MPqwNG79bSlhUJzp2H8yeTV+QdnIvcrkCT28/bn9ovr2syYfY9N1S5HIFgiDjpokv4+Xj2qf35HIFtz/wPO/Ne8T+ibZBNxEc3ppf171HRExHusQPYscfX3LmxH7kcgVePr7c+5i9Sew/8k4+f/9F5j5xM9hsJAy6kdBI1za/EkX4aF0BL08NQy6DP/eWkJlTw11jNKRlVHHwRDl/7ilhxsQgPnilFaUVIm+tcmz62am1J4ZC+8aRV4NcruDuybNYNOdxRKuVfkPHEhoRw/dffEhU6w7E9my63dn829fk5WTy07qV/LTOvtTr6VeW4evf/JpnuVzB7Q/a61kUrfQedBMh4a359avaeu4xiO2/O9fzPVPt9VxabGLZ3CkIMhn+ah33TZvvUllFET78IpdXZ0QgEwQ27S7iQnY1E8ZqSc2o5MCxMjbuKuLJB0NZMa81ZeX2T1gClFeI/LjJxOLZUWCDQyfKOHTCtSU4CrmcZ+66nkffsX/S8ca+scSE6Hj/py10jAxhYLf29OnUmr2n0hn38jLkgsCMW4bj79NwY8+rQSGX8dxtw3nk/XWINhs3JXShdbCW99bvoFNEMAOva0OfDlHsOXOOm+d9hEyQMfOmQfjXbj75xM2DeWjZl9hs0DFczy19urlc3pmTJ/LkHPtnHUcPGUBURBgrv/iW9q2jSOwZx7frN7D74JG6vu/5afYvHZ2/mMWiD1YhyGTYRJEJ48Y2+CpFY4giLPvsIvOfjkEmE9iww0hGVhX3jgsi5VwF+46W8Md2I89MiWT1oo6Ullmcvizxd2mp9kIhl/PUA3cxfd479s+EDupLdHgIK9b9RPuYSPrHd+Pr37ew89Cx2jr24sVHJ9blz843kG8oJLbj1W3OJ5cruOX+5/lw/sOIopVeg24mOLw1v329jIjoTnSOH8TODV+QkrQPmVyBl7cv4x9xvJ/ppw/hrwkiUB9+BS0Ny/rM3Tfy2CL7Jx3H9utBTGgQH3y/kY5RYQyI7Uif69qy72QKtzz/FnKZjBm3X4+/jzfr9xzhaMo5issq+GWXfdPGOZNup11k85M2CrmcGZMn8tScBYhWkeuHDiQqIoxVX3xDu9bRJPaM47v1G9h94HBtHfvw3OMPX1V9NobdTp7Msy/NQRRFRg4bQqvICD75/AvatmlNn149+eHn9ew9cBC5TI5K5cOsGdMA2L5rN8dPnqKktJSNf9ojSJ6e+Tito11wXoki+R+/R9jz80Emo3jbRmouZqC57V6qzqZQfngfBWtWEPTwDAJGjwObjZwPFtmv2c+f8Ofn2T8xbzKSs+yN/7geJCQk/nsRbM18WkYQhPZAKLDfZrOV1ft9pM1ma/b7hlkpJ/71xSCbsq9uF99rxQ2Be1pEb5nHP7PerzkKrFe3Oda1InKNi5+YvIYUnftn1wM3RXC/q5sZvlacGTSrRfRmFrvm8LiW+Li7ttHntea95a4tfbrWPDPt2u/94QrlZtd2rr+WvLP0P18C9nf4+u6W+Ta8rLqyeaF/gJKwf7/Pvfv1f3b/jaZ4+qlrv3eBK8Szr3mhf4B94tXNhF8L+let/9d1ApT5u+70uJbUKK7+S17XgooXZraI3nbrNrSIXol/hWvwfa//f7n3xZz/yu+xfvZacIvclysulxAE4XHgJ2AakCQIwo31kl2bNpKQkJCQkJCQkJCQkJCQkPifoLmdfiYDcTabrUwQhFbAt4IgtLLZbEv4P+6tkpCQkJCQkJCQkJCQkJCQuDqaczLILi2RsNls5wVBGIjd0RCJ5GSQkJCQkJCQkJCQkJCQ+D+O2IKfg/xvpLmvS+QJglC3y1Otw2EMEAi0zMYHEhISEhISEhISEhISEhIS/1/SnJPhXiC3/g82m81is9nuBZreSl5CQkJCQkJCQkJCQkJCQuJ/juY+YXnxCmm7r/3lSEhISEhISEhISEhISEhI/LfS3J4MEhISEhISEhISEhISEhL/s9ikPRmuiuaWS0hISEhISEhISEhISEhISEi4hORkkJCQkJCQkJCQkJCQkJCQuCZIyyUkJCQkJCQkJCQkJCQkJJrAZpOWS1wN/7iTIWDnN/+0igaIUS3zdU23zd+1iF6dRtMiesXet7eI3pbAXeXRInrP/bqvRfTaBgktonfXoap/XeeTQ9L/dZ0A/jp9i+htLZ5uEb1WN7d/XadfoO5f1wmQGda3RfSWWb1bRG/b4n+/nRItLXNv9ybJW0Rvj4v/vi0FYB327z/LFet/+td1AvhEhraI3vK+N7WIXu/rWv3rOsuzDWQ+esu/rhcg/P2WsdElJP5XkZZLSEhISEhISEhISEhISEhIXBMkJ4OEhISEhISEhISEhISEhMQ1QdqTQUJCQkJCQkJCQkJCQkKiCWyi2NKX8F+FFMkgISEhISEhISEhISEhISFxTZCcDBISEhISEhISEhISEhISEtcEyckgISEhISEhISEhISEhISFxTZD2ZJCQkJCQkJCQkJCQkJCQaAJRtLX0JfxXIUUySEhISEhISEhISEhISEhIXBMkJ4OEhISEhISEhISEhISEhMQ1QVouISEhISEhISEhISEhISHRBDabtFziamgxJ8Puszm8ufkoos3GTV2ieSChg1P6os1HOZiZD0CV2YKpopqd08fVpZdVm7ll1e8MahPKs8PiXNJ59uQONn89D9Em0rXvbSSMeMgp/eiOLzmy/QtkMhlKdy9GTniNwODWAOz9YznH93yLTJAx5I4XiO7Yz+WyyiPb4THgJhBkmE/up+bQFqd09/5jkYfZ9QgKNwQvH8o+fAF5WAzu/W+sk5MF6Kj6/XMsZ5Nc0rs7LYs3NhxAtNm4ObYND/S9zin9zY0HOHg+F4AqsxVTeSW7Zo3nTK6J+b/to6y6BrlMxqTE6xjRKcrl8h46dIgPlq9AFEVGjhjOHbff7pS+cdMmVq36GE2gBoAbxtzAqJEjANj05598+dU6AO668w6GDR3qkk5lm874XD8eQSaj8vAOKnf85pQu81OjumUSgocXgkxG+cZvqUk5jjKmI97Db0OQK7BZLZRv+Brz2dMul9WjYywBtz8AMhnlu/+kZMMPTunygEA0E6ch8/QGmYyiHz+nKumI/ZpDI1FPmILg4Qk2G7mvzwKL2SW9Pt17EPLQVJDJKdy4noJvv3SuD62esBmzkPv6YS0rJXPRPCxGAwCt5izEq11Hyk+dIOPV510uK8Cxw3tZs3IxolVk4PCxjL31vkblDuzZwrsLnuPVtz4huk0H0lNOsuq91+2JNhs33zWZHr0HuqSzXbicmxLdkMlg/ykLW44611F0sIwbE90I1sj4fGM1x89a69LG9FbSIVKBIEBKppUfd9W4XNYDh4+ybOVqrFaR0cOHMP7Wm53S/9i8lQ9XryFQowbg5tGjGD18CLn5Bbw0/01Em4jFYmXcmFGMHTXcZb3XtXZj/EgVMhnsOFLJ+l0VTultI5WMH6kiXK/gg2+LOXSqGoCIIAX3jlbh6S5DtNn4ZUc5B05Wu6x335HjLPn4c0RRZMzQAdwz7gan9N+27OT9z74iUB0AwC2jhnLDsIEA9L/1PqIjwgHQB2pY+PxMl/XuP/IXSz/6FFEUGT1sMBNuvdEp/ffN2/jgk7VoL9Xz9SMYM3xwXXp5RQX3TX2KxF7xzHj4AZd0dmnrzj1j/JDJBLYdLOeX7WVO6e1buXH3GD8igpQs+8rEgaSqurR+3b24aZAKgB+3lrLziPP9uRKHDx1g5fL3sYoiw0eM4tbb72pUbs+uHSyY/ypvvfMebdq2w2KxsHTJW5xNS8UqigwaPJTb7hjvst5jh/fy2UfvIIpWBg0by9jb7m1U7sDurbyz4HnmLv6Y6DaOPtmQn8vTj43nlrseZMy4CS7r3XPsNIvW/IAo2rhpYC8mjm3Ynm/ad5QV329AEKBNRCjzHrsHgF93HGDVT5sAePDGYYzp39MlnT26+vLovRHIZPD7VgNf/ZzrlK5UCDzzaBRtorwoKbMwd8lZ8gw1tIvxZuakSAAEAT77Npvdh4pcLmtMsMCIeBkyAY6miew+5WyMJrQXiG0tQxShotrGz/tEistBHwCje8hxU4LNBjtPipzKcN2QVUR1wHPIrSCTUXNsD9X7NzmlewwehzKibW3h3ZB5+VC8ZJY9bcCNKGM6AVC15w/MZ464rPfMXzv58bMFiKKVXoNuYciNk53S92xax+5NXyKTyXDz8OK2Sa8QVGvnZGck8+2qOVRVlCHIZMyYuw6lm3uzOluqn999LpdFW45itdm4+bpo7u/V3il90da/OHSh1l61WDFVVLNj2k0AxL/1Da0D/QAI8vXinZsTXda7/8gxlqxaU9smD+TuW8Y6pf+2ZTvvf/ol2to2edz1w7lh2CAABtxyt6NN1gay4PknXdarjO6E14jbQZBR/dcuqvZscEqX+QbgPfZ+u+0iyKjc8gPmdLtd6tFnJO7d+oJNpGLDOsxnT7mk06NjN/xvewAEGeV7NlO6saEtpb5vGjJPL5DJKf7xc6pOOmypgLseRubhhc0mkrfwGZdtKQkJiX+OFnEyWEWRBX8e5oPbB6JXeTLhs00MaB1CTG1DDPDUkNi6v788nEJyvnNn//6uE3QP17qsUxStbPrqVe54fDWqAD2fLriV1l0G1zkRADr2uIHY/najL/XYZrZ8+zq3T1uFISeN04fW8+CL6ykrzmPdkvuZPGcDMpm8ecWCgMfAcVT8sBxbWTFed87AcvYkoimvTqR6x891fyu7JiLXhtrr6WI6FV8stie4e+Iz8XksF5JdKq9VFHn9j318OGE4el8vJqxcz4C24cRo/etknh7uMNq+PHCaM7kmADyVcl67MZFIjS/5pRWMX/krvWNC8fVwa16v1cp773/A/HlzCQwM5PEZM0lISCAyIsJJrn///jz26CNOv5WWlrL2iy9YumQJANOmTyehVy9UKtWVlQoCqhvuoWj1IsQSEwFTXqLm9F9YC7LrRLwG3kB10kGqDmxFrg3B796ZmN56GltFGSWfL0EsLUKuC8Vv4pOY3nii2XLa9coIuGsy+UvmYC00EvTcG1QcP4gl52KdiN/1t1JxeA9lOzagCA5DN/UFsmdPAZkMzf3TMa5+F3PWeWTePmC1XkFZPWQyQh6ZzrkXnsZiLCDm7Q8p2b+H6syMOpHgB6dQuHkjRVs24N0llqD7JnNxsX2QX/D9OmTu7qhH3tCUhkYRrVY+Xf4mz766FLVGx0tPTiSuZz9CI6Kd5Corytnw8zpi2naq+y0sMobXFn+CXK6g0GRg9vS76d4zEbn8yk2QIMC4/m4s/6WK4jIbM2714OR5C3mFDiO8sMzGV1uqGdhN6ZS3VZCMVkFyFq2rBGDqzR7EhMhIzxabLavVamXJ8lW8+eqLaDVqpjz5HH16xtOq1mi7xKDEPkyfMsnpN02AP8venIebUkllZSX3T3uSPj3j65wRzZX3nutVvLmmCFOJlZcnqzmaXE12gePZMBVbWfljCaP6eDnlrTbb+OiHEvJMVvxVMl55SE1Seg0VVc0PWKxWkcUffcbbL89Cp1EzadbLJPboTlR4qJPc4L69eGJywwGqu5sbnyye26yexvS+s/xj3pozG61Gw8NPPU/fnnG0ighz1pvYu0kHwqq1X9OlU/tG0xpDEGDiWH9eX2XAVGLltcd0HDldRVa+pU7GUGRl+beFjO7n3PZ4ewqMG6LihWX52Gwwb5qOw6cqXaxjK8vfX8qr8xaiCdTy5IzH6JnQhygImpoAACAASURBVIiISCe5iooKfv7pB9q2c5Rp987tWMxmln6wkuqqKh6b8iD9Bw5Grw9qVq9otbL6w7d47rUlaDQ6XnjiAbr36kdYhLPjuLKinD9++ZrW7To1OMfnq96la1xCs7qcyiuKLPz0O957dgp6tT/3vvQ2/eM6Ex3quOYLuQWs/mUzq15+HF9vL0zFpQAUl5Xz0Q8b+Oy1JxAEgXteeIv+cZ3x9fZqSh0AMgGm3R/BM/NTKDCaeW9eB/YcLuJClsNJNGpQIKXlFu6bmcTA3gFMHh/G3HfPcj6zkkdnn0IUQe2vZPmCjuw9UoTYfHOBIMCoHjI+32KlpAImjZSTfNGKocQhk1sIH/1uxWKFuDYCQ2NlfLdLxGyBH/daMZWCjydMHiUnPdtKtStjJEHAc9jtlK9bhlhahOq+pzGnnUA0OhwrVVu+51Lp3boPQK63v1uK6E7Ig8IpXb0AFAp87ppuHxDWVDWiyBlRtPL96nk8/PxH+Gn0vDP7DjrFDapzIgB07zuaPsPuACDp0BZ+XvMGDz23AqvVwhfvPcv4x14nJLI95aVFyBUumKIt1M9bRRsL/zzC+7f1R6/y4u7P/2RATAjRgb51Mk8N6lb391dHUjlTz151V8j56j7Xncx1eq0ii1d8wtuvPIdWo2byrBfp27M7UeHObeOQvgnMfGhig/zubm6sfvv1q9aLIOA16i5K176DWFKI74PPUZNyHNGQUyfikTiamlOHqD6yA1lgMKo7p1K8bDaywGDcOsVTvHwOMpUfqgkzKX7/Rbv37Io6ZQTcMZn8d1/FWmRE/8xCKo8fxJLrsKV8R9ltqfKdG1AEhaF9bDY5Lz4CMhnqidMxfbIEc1bG1dlSEhIS/ygtsidDUo6JcH8VYf4+KOVyRnSIYFtaVpPyf5y+wMgOjkHqqVwTxvIqerdq3sC6RM754/hrI/HXhiNXuNEhfjSpxzY7ybh7+tT9ba6pBATA7nDoED8ahdIN/8Bw/LWR5Jw/7pJemT4CsdiIrcQEohVLylEU0Q2NuEso28ZiTjna8Pc2XbGcP+OydzYp20B4gC9hASp7HXeKYltyZpPyv588x8jOdqMzUuNHpMbegepUXqi9PCgsb97wAEhOSSE4JITg4GCUSiUD+vdn7959LuU9dPgwsbGxqFQqVCoVsbGxHDp8uNl8irBorMZ8xMICsFqpOnEAtw6xDeQEd0/7/x6eiKV2I8CSc6Hub2t+FoJCCc0MfC/h1qo1lvwcrIY8sFqoOLgLry7Os202GwgedsNY5uGFtcjuyPHo2A1zVgbmrPMAiOVlYHPBmgW82ranJicbc14ONouF4h1b8E3o6yTjHt6K8uN2L3/58aNO6eXHjiBWuj77eon01FPog8PQBYWiUCpJ6DeMw/t3NJD7du1yxtxyj9PMlLu7R51DwVzjejRBhE6GsVjEVGLDKsLRNCudopzvT2GpjRyjrYEdY7OBQg5ymeP/0krXZgjPpKYREhxESJAepVLJ4H592b3/kEt5lUolbkq7w6PGbMHmyiilluhQJXkmKwWFVqxW2J9URWw75xk+Q5HIxTxLg/LmGa3kmezGVVGpSEm5iMrLtSb+dFo6YcE6QoN0KJUKhiYmsOuA67Oaf5fTqWmEBl2qZwWD+/Vh1wHX6hkgOe0shUXF9OjWxeU8MeFu5BktdXW871gFcR08nGQMRVYycy0NQiO7tPXgRGo15ZU2KqpsnEitpms757xNkZqSTHBICEHBISiVSvr1H8j+vbsbyK1d8wm33HYHbm71nLqCQFVVFVarleqaahQKBV5eVx5wXyKt9r3V1763vfsPbfS9/WbtCm645W6USmdn8sG929Hqgwm7zJnYHCfTLxCuDyRMF4hSoWB4QizbDztH4f2wdS+3D02scx6o/exOnb3Hk+nZuR1+Pt74envRs3M79hw706zOdq29yc6tJie/BovVxra9JvrG+zvJ9InzZ+MOIwA79hcS29mus7pGrHMouCmFqyprqMbeDhWVgSjCyQyRduHO5zifZ8NSO/bJMtjw9bKnm0rt/wDKKqG8Crxde6SQB7dCLDIgFhtBtFJz+gjKNk2/C24d4zCftvep8sAgLJlp9n7HXIO1IAtldIcm89bnQtoJNEHhaPThKBRuxPa+npOHtjrJeHg57Kma6koEwV7elON7CI5oS0ik3YnmrfJ3acKmpfr5pFwTYQE+tfaqjBHtw9mWfgV79UwmI9tHNJnuKqdT0wkN1hNS2yYPSUxg14Hm7aH/FEVIFKIpH7HIYH+mTh7CrW3Xy6RsdfUsc/dELC0GwK1tV2pOHgKrBbHIiGjKRxHSfBSsW6vWmAtysRprbanDu/Ds2uMylTZkHrU6Pb2wFtfaUh26Yc46jznLPslyNbaUhITEP0uLRDLkl1WiV3nWHetVXiRlGxuVzS4uJ7u4nB4ROgBEm43FW/9i3pgE9p/PazRPY5QW5eEb4HBKqAL05Jxr6Cg4sm0tBzevxmo1c+eMTwEoK8ojJKqrU97SItd0y3z86jo3ALGsGHlQ4x2QoApA8FNjzUxtkKZo242ao9td0gmQX1JBkK933bHe14sTWQWNymYXlZFdVEbPRpw2J7IKMFtFwtXNRBPUYjQa0QYG1h0HBgaSnNww+mLX7t2cSEoiLDSUhx+ajFarrc3riE4J1ARiNDb+XNRH5htQ1+EAiCUmlGExTjIVm3/Eb+JTeCYMQXBzp3j1mw3O49YpHktOBlgtDdIaQx6gwVrouD5LkRH3qDZOMsW/rkM3/SVUg65H5uZO3pJXAFDqQsBmQzvtReQqP8oP7aJ0448u6VVoAjEX5Ncdmw0FeLVzNg6rzqXj26c/xp+/w7d3P+Re3shVvlhLSy4/ncsUGvNRB+rrjtWBOtKTTzrJnEs/g8mQR2yPRNb/sNYpLS05iY/enYuhIJcpM19pNooBwM9boKjMMdArLrMRoXdt4JyRJ5KeLfLKRPsAZneSmfxC15wMBqMJXe1yHgBtoJrTyQ3fyx1793P85GnCQoN57MGJ6LT2Zz+/wMBzr75OVk4uD99/j0tRDAABvjJMJQ4DqbBEJDpMeYUcjRMVqkAhF8gvdG1Gp8BYiE5Tr7waNadS0xvIbd97kGOnkgkPDmLaA+PR19ZRTY2ZB59+CblMzt3jxtC/l2tL2BrUs0bN6ZS0RvQe4NjJM4SHBDH1wXvRaQMRRZH3V69h9sypHD52wiV9AGpfGcbiepEhJVZiwpuP0gII8JVjuixvgK8LEW2A0WggMFBXdxwYqCU52XngnJ6WiqEgnx49E/jhu6/rfu+b2J8D+/Zw34Tbqa6u5sGHpqBS+eIKhcYCNPX0qjU60lIue2/TkjEW5BPboy+/fu94b6sqK/jlu895/rUl/PrDFy7pu0R+YRF6tWOAr1P7kZR+wUnmQq69T3pgzhJE0cZD40bQp2sHCgqL0WscefVqfwoKi5vVGRjgRr7R4cQsMNbQvrWPk4xG7UZBrYwoQnmFFV+VgpJSC+1jvHlqSiv0gW4seO+cS1EMACpPgeJ6ftuSCgjVCEDj7U23GBlpjURUhWjsztBLTofmkKn8EEsK647F0kIUwa0alRV8A5D5abBk2Ptja34WHn1HUX1gM4LSDUVEW0RDbqN5L6e4MA9/TXDdsZ9Gz4W0hvbUro1fsGP9Z1gsZh554WMACnLOIwgCy1+fTHlJId16j2Lw2AebL2sL9fMFpZUEqRwOPZ2PF0k5rtmrADUWkQlr/kQuE7i/Z3sGtQltNG8DvabG2saGbfK2fQf565S9bZz2wD1ObfKkp15ALpcxYdxY+veKd0mvoPLHevkzdZmjoHLHL6jGz8CjxyBQulG69h0AZCp/LFnnnPIKKmcnX2PI/dVYCw11x9ZCE26tLrOl1q9DO+0lfAZej8zdnfwlcwBQ6ILBBoFTX0Tu40vF4V2UbvrJpbJKSFwtNukTllfFFa18QRCOAN8DX9pstoat27/AhjMXGNIuDLnMPrD4+mgaidHB6FWuzeJcLd0HTqD7wAmcOvALe3/7gNETF/4jehpD2bYbltTjDULLBC8VMk0w1gzXlkpcLRtOnmNoh8i6Or5EQWkFL/y4i9duTEQmXN3MzpVI6NWLgQMH4qZUsv6331n01mIWLvgbYX1XgXuXXlQd3UXl7g0owmNQ3TqZwqWOMD65LgSfEbdR9Mmia6rXu0ci5Xu3Uvrnz7hFtSXw/unkvDoD5HLcW3cg9/VZ2Gqq0c2cQ01GOtXJrg+WrkTOxx8QMuVxAoaMoPzkccyGAmziPxtCKIoia1ct4eHpLzaa3rpdZxa+9xVZmedY/s6rdI3rjZsL63D/LhpfAV2AwKuf2q3/h8d6EBVs5VzOtZnl6N0jnsH9E3FTKvn5j00seGcZi+e9AoBOG8iqpW9hMJp4cf4bDOiTgDqgeWPrWuDnI+Ohm/1Y+WNJs1GqV0PfHt0Y2i8BN6WSHzdsYd67K3j31ecA+Hb5YrQaNVm5+Ux/eQExkWGEBumbOaNr9OkRx5D+fWvr+U/mL/mAd+a+yI+/b6RXXKyTIf7fjCiKrProA6Y/MatBWkryGWQyGZ98vo6yslKee3om3bp1Jyg45Jro/XzVEqbMaPjefvfFSq6/8Q48PP+Z/tZqFcnMNbBi9lTyTEU8NHcZX73esPz/FmfSy5n09EkiQjyY9UgUB44VYzZfW6PyulYCIRqBTzc5t0M+HnBTHzk/7fln2mm3DnGYk/+q6/Ms589gDo5EdfeTiJVlWLPOXfMZ4MTh40kcPp4ju3/lzx8+5K5HX8cqWjmXfITpc9fh5u7Bh/MeJCy6E207X91ynMZoqX7+EhvPZDKkbRhymcNeWv/QaHQqTy4WlfHw19tprfUj3N/nCmdxnb7x3Rnarw9uSiU/bdjM/CUfsuS12QB8s2IJWo2a7Nx8pr80j5iIcEKDr02b7N6pJzXH9lC1/08UodH43Hg/xctfvSbnbgqv+H5U7NtK6eZfcItqi2bi4+TOnYkgl+Me0568hc9gq6lGO/0Vai6cvWa2lISExN+nuSnBAMAf2CoIwgFBEGYKgtCsVSMIwkOCIBwSBOHQx9sbhtzqfDzJK62sO84rrUBbL7KhPhtOX2BkB8ea1eNZBtYdSeP6D3/h7W1/8evJ8yzZfqy5S0Llr6ek0OGlLy3Mw8e/6Qa3Q/xoUo79CYBPI3lVV8hbH7GsGFk9T67Mxw9bWeMzMoomlkoo2nbDkn4Cl6dVAJ2vF7kl5XXHeSUV6FTejcr+cfI8Iy/b2LGsuoZpX21m6qBYuoS5vveFRqOhwODwSBsMBjQa50GAr69vXTj5yBHDSU1Lq5fXEW1hMDbM2xhiSSFyP8dMscxX7eSJB/CI60910kEALJnpCAolQm04p8w3AN/x0yj59iNEU+PRHo1hLTQiD3Bcn8Jfg7XQ5CTj3XcIFYftIdE151IQFEpkPr5YCw1UpZ5CLC/FZq6hMukIbi6GI1uMBpRax0yJMlCL2WhwljEZuTD/ZdKmP0TeZysBEMvL+U8I0OgwGRwRPCZDPgEax7NRVVnBxYx05s1+lBmTbiI9OYnF857ibKrzBluh4VF4eHhyMeNsszqLy234+zgMNj8fgeJy14z+66IVZOSK1FigxgJnLlhppXdt1jlQoybf4JitKjCYCLzsWfTzVdU9x6OHDSYlvWF5AjVqWkVEcOKUa5uMFZaIqH0dzXKAr4zCEtcHHR7uAjMn+PPdljLSL7q+8ZVWE0B+vaihAqOpbjOxS/ipHOW9YehAks+er5ff/v6FBumI7dyelLMZuEKDejaaGkR9NFXPJ8+k8sP6DdwxeSofrF7Lhq07Wf5p87PtphIRjZ/jOVD7yiksdq2OC0usqC/P6+L90WgCMRgcEUgGQ4FT+1ZZWUFGxnlmP/MkkyZOIPnMaea9+hKpKcns2LaF7nE9UCgU+PsH0L5jJ9JSU1zSG6DRYqyn12TMR33Ze5uZcZbXnn+Uxx+8mbTkkyyaO4uzqadJSznFF5+8x+MP3swfP6/jp28+ZcOv37ikVxfgT57JEcWXbypGF+DnLKP2o3/3TigUckJ1GiKCtFzILUAb4Eee0ZE3z1SE9rK8jWEorEGncUSlaDVuGAudl2cZTTVoa2VkMvD2klNS6jyrfSG7ispqK1Hhjdsll1NaacOvnh/G16vxpVlRQQKJnWV8tc2KtV537qaAuwbJ2fqXSFbzwXt1iKXFyHwd76lMFYDYhH2h7BBHzWnnpUjVezdQ+skCytctA0HAaspvNO/l+AXoKTI61ugXG/PwC2jaJurW+3qSaje89lfriW4fh49vAG7unnTo1o+sc81vDthS/bxW5UluqSNMJb+sAl1T9mpyJiPbO+/bc0k2zN+H+HAtyXmubSaqVTfWNl7WJtdrG8cMHUTyWUcUwaU2OSRIR7fOHUg5d94lvbbSIuSXP1Olztfs1q0vNbXLbixZZ6G2nsXSogbPo620+fJai0zIAxwRsPIANdZi5xfBp88QKo7sAWptKaUbMm8VlkIj1WkOW6rq5BHcwq9uaZeEhMQ/Q3NOhkKbzfaUzWaLAJ4E2gBHBEHYKgjCQ01lstlsK2w2W7zNZot/YED3Bumdgv8fe/cdHkW1N3D8O7O76b0npJFGr6GD9N4RQUAFUUQQERUvNkSuClfFLiJVQAVREQVFeu8t9N7Te++7O/P+sblJlgDZ3BuS1+v5PI/Pg5kz+9szOzPnzJlT3IjOyCEuMxe90ciWi9F0DavYhexmWjbZhcU08yuriM0d1J5Nkwfx56RBvNS1OQMbBTOty53jxSryDWpCRvItMlNjMBqKuXh8I2FNu5ulSU++Vfrv6+d24+ZlatwIa9qdi8c3YtAXk5kaQ0byLXyDLRsDrCTFILt4IDm5gaxBG9ECw43zFdLJrl6mMYQJtyps00W0wHCXxof7aeTnQXR6NnEZOaZjfP4mXSL8K6S7mZpFdmERzco1JOiNRl7+aRcDm4bSq2FwleLWi4ggPj6OxMRE9Ho9e/bupV27tmZp0tLLHsQPHzlCYICpUG4VGUlU1ElycnLIyckhKuokrSIr73ZtiLuJxt0L2dUDNBpsmrSh+JL58VKy0krHm2o8fUGrQ83LQbKxxfmJF8nbuhZDdMVu2vdTfPsaOi9fNO5eoNFi17oTBWeOmaUxpqdiU990rmh96oDOCiUni4ILp7CqE4SkswJZxia8IfpyE0beT/6VS1j71UHn7YOk1eLcuTvZRw6apdE4OZlmIwM8RzxG+rZNVcrb3YSENyAxPobkxHgMej2H922jZdvOpdvt7B1YuGorny39jc+W/kZovca8/OZHhIQ3IDkxHmNJ99TU5ATi427j6e17r1ClYpIVPJxl3BwlNDK0CNNw/qZl3VwzcxVC/TTIkulhItRPQ1KGZQ119cPDiItPICExCb1ez859B+hwR3fTtPSyCu7Bo8cJ9DddXympaRQVmVZ1yMnN5dzFSwTUseyN8814Pd7uGjxcZDQaaNvYhpOXLVshQqOBFx515uDpwtIVJyxVPyyEmIQk4pNS0OsNbN9/mI6tzcc7p5Z7YNx/LIqgkjxl5+ZRrDc1aGRm53D20lWCAyzrElw/PJTYhEQSkpLR6w3s3HeQjm3Mr/nyx/nA0eME+Zs++63pU/l52Vf8uGQ+k8c/Rp9uD/HsuMpXXLgRW4yPhxZPVw0aDbRrZseJi5bNOXPmSiFNwq2xs5Gws5FoEm7NmSuW7RseUa/k3piAXq9n397dtG3XoXS7vb0Dq9asY+mKVSxdsYp69Rvw5qx3CI+oh6eXF2dOnwKgsLCAK5cuUifAsnHfoXdct4f2bieyTdnqSHb2DixevZkvlv3KF8t+JaxeI16Z+SEh4Q14+4OFpX/vO/hRhowYR5+BIyyK2zAkgJjEFOKS09AbDGw9fJLOLc3nI+oa2YQTF0333cycXKITU6jj5U77pvU4cu4y2Xn5ZOflc+TcZdo3rVdpzMvX86jjY4OPpxVajUTX9m4cPGH+kHPwRCa9O5vqFJ3bunLqvGlsgo+naQUbAC8PKwL8bEhMsWz+mLg0cHOUcDEtIkSjIJkrseaNDD6uMKCNzI97jOSXuzxlGR7tInPmhsLFmKr1mjAm3EZ29UR2dgdZg1WDlujvMmxBdvM2zQlUris7koRkY3rxIHv6ofH0w3Cz8nkvAAJCG5OaGE1aciwGQzEnD/1Jo8huZmlSEsoaGi+e3IOHj6k+Va9pRxJirlJcVIDRaOD6xeN41zEf9nA3tVXON/JxJSYjl7jMPPRGhS2XYugSWvF+/u/6atNy9dXswmKKSybiyMgv4lRcGiHulg1zqh8eQmxCIvEl98Yd+w/TqbX5vTG1/L3x2AmC/E3fK+eOe/K5S1csvicb4m8hu3khu5ScU41aob9i/iJPyUpHG2yaU0N290HS6lDzc9BfOY1Vo1ag0SK7uCO7eWGIv3m3MGYq1KUiO1FwxrxBzJCRgnW9srqUpNWh5GZTeOEUOr+yupR1eCP0ifeef0wQ/huqov4l/6stFs/JoKrqPmCfJElTgV7Ao8Di/yioLPNqz5Y89/MeFFVlSJMQQj2cWbDvLA193OhaMmZty8Vo+jQILJ0w6L8ha7T0GjWLn76cgKoYadJhOJ5+4ez7/XN8AhsT3qwHUbu/59alQ2g0WmzsnOg/zjRUwtMvnPqR/Vj2Tn9kWUOvUbMsW1kCQFUo3L0Ou6ETQZLQXziKkp6EVbs+GJNiMd40NThoI5qjv3Kqwu6So6tpjFxs5W99y9PKMq/1bcvk1dtRVIUhzcIJ83Jlwe6TNPR1p2s9UwV18/mb9G1U1+wYbz1/i6joJDILithw2lQgvzO4E/V9Kh9XrtFoeG7yZN6c+RaKotC7dy+Cg4L49rvvCA8Pp327dqxfv4HDR46g0WhwdHRg+sum5e4cHR0ZM3oUL7xo+v/HRo+ufGUJAEUh949VOI+bjiTLFJ7YhzE5HrseQzHE3aL40ilyN/2I49AnsetgmuU5Z90yAGzb9UTj7o19t8HYdzMtD5W54iPUPAsGxSoK6T8uxeuFWaYlLA/uQJ8Qg/OgURTfvk7BmWNk/LIC98efw7HHIFBV0ld+CYCan0f29g14v/4hqFB4/gSF5yyc1ElRiF/4BXXf+RBkmYxtmyiKvoXXY+MpuHqZnKMHsW/SHJ9xz4CqknfuDPFff166e8gHn2PtH4hsY0v9FT8R+8U8cqOO3SegiUajZdyzr/Dh7BdQFIUuPQfhHxjC2lWLqBvWgMhyDQ53unLxFL+/+y0arRZJknly0gwcnSofPqCosG5fMRMH2SBJcPSSaWWJPq11xKYonL9lJMBL5sm+1thaSzQM1tKnjcq8NQWcvm4krI6GV0bZoqpwOdrIhduWvXXWaDS88OzTzJg9B0VR6NezG3UDA/hm1RrqhYXSsW1r1v3+JweOHkej0eDk6MBrL04B4HZMLF9/862pkUdVGTl0ECHBQZVELMmvAt//mcMrT7giS7DvZCHxKUaGdbPnZryBU5eLqOunZeooF+xtZJpHWDOsq8KbC9Jo08iGiCArHOxkOjU3zRy39LdsohMrb5TRajS8PGEsL7/zIYqiMqBHZ0IC/Vn6wy/UD61LpzYtWfvnVvYfO4lGlnFydODNqaYl627HxjNv4XIkSUJVVR4fNrDCqhT3i/vixPG8MnsuiqLQv4fpOC9b9RP1w0Lo2LYVv/yxmQNHT6DRyDg6OPDatMmVf/B9KAqs2JDJq095IEuw53gecckGhvd05GacnqiLhYT463jpcXfsbCVaNLBleE8jr36WTF6Bym87c3j3eVNPol935pBn4WSiGo2GZydPZfbM11AUhZ69+xIYFMyq71YQFh5h1uBwp/4Dh/D5p/OYMulpUFV69OpD3bqWva3TaLQ8OWk677/9Ioqi0LXnQPyDQvj5+8WEhDcgsq3lyzFXhVaj4R/jhjP1w0UYFYXBXdoS6u/LwrWbaFA3gC6RjWnftD6Hz15mxIz3kWWZF0YPwqWkx93TQ3sz9q1PAZgwtDfODnfviVeeosCXK6J5//UIZBk2707jdmwh4x7x48rNPA6dyGLT7lRee64uKz9tTE6ukTlfmkaCNq7nwKghvhgMKqqq8sU30RV6ONyLqsKm4wqPddcgSXDqukJKFnRtKhOfpnIlTqVnCxkrLTzSyVR3yMpX+XGPQqNAiUAvCVsriWYlP+n6w0aSMu4TsDSwQsG2n7AfOQUkieKzh1FSE7HpNABDYjSGa6Yu41YNIkvfPJeSNTg89qLpY4oLyf9jpcXDJTQaLQ8/+SaL/zURVVFo03UYPgFhbP75S/zrNqJxq+4c2LqaK2cPodFqsbV3YvTkuQDYOTjTpf84PnvzUSRJon7zh2jYskvlQWupnNfKMq/2aMGUX/aiKCqDm9Ql1MOZr/efo6GPG13CTA/2Wy7F0Kd+gFld6mZaNnO2nSi9N45vW99sVYr7xtVoeOmZJ5n+zw9My/v26ELdQH+Wrl5L/bC6dGoTydqNWzhwLMpUBjnY88bUSQDcio3jo6+XIckyqqLw2MODK6xKcU+qQv7mNTiOngayTNGpAxhTE7DtMghD/G30V8+Qv30t9gMex6ZtD1Ah9/cVABhTEyi+cALnSbNBMZK/+YfKV5YAUBQyflyK5/NvIckyuYd2YkiIwWngKIpvX6Pw7HEyf1mJ22OTcew+EFSVtO/mm75uQR45O3/H+9UPAZWC81Gly4QLglC7pDtnzzbbKElrVFUd9d8EyF82q8abUNbUfbBjw+5lxFnL1yGuTloLhhQ8CIntR9ZKXIflc2o8ZkFq5ZOOPQhZsZbUNKtf4ce/Vp7oAVizo+qTHP63pveolelmeOOH6hkfW1XzRtyqlbhGjWWTK1an6Su9Kk/0AMyaUDuzm+caK38QfxAisixbQag6Dfukdn7bzgObV57oAXghkqaU+wAAIABJREFU9sVaibu/12c1HrPtumdqPCaAXZBljaPVLa/j0FqJq123pMZj5sWnVp7oAQlY8Eutxf4bqb4J3P4femTajb/kzI9rPw+pld/lvsMlVFUdJUlSfUmSekiSZDZTjSRJfR/sVxMEQRAEQRAEQRAE4a+kstUlpgLPAxeBZZIkTVNV9d9rw8wFNj/g7ycIgiAIgiAIgiAItUap5hV4/tdVNifDRCBSVdVcSZKCgbWSJAWrqvo5/+NdYgRBEARBEARBEARBqJrKGhlkVVVzAVRVvSVJUldMDQ1BiEYGQRAEQRAEQRAEQRDKqWwJyyRJkkpnOSppcBgIeABNHuQXEwRBEARBEARBEAThr6WyngxjAbM1nFRVNQBjJUla9MC+lSAIgiAIgiAIgiD8P6Aqf8nFJWrNfRsZVFWNvc+2A9X/dQRBEARBEARBEARB+KuqbLiEIAiCIAiCIAiCIAiCRSobLiEIgiAIgiAIgiAIf1tiuETViJ4MgiAIgiAIgiAIgiBUC9HIIAiCIAiCIAiCIAhCtZBU9cF2/Xjxy9wa71uSEp9V0yEBCAhxr5W4mekFtRJ31ACbWokbbBNT4zHjiv1qPCZAnt6qVuJ2vvZVrcT9vc60Go+5bt0957d9oOwcbWslrr7YUHmiByAnI7fGY9o729d4TIBOnWvnfhETV1QrcdNS8ms85oj+tXP9rPwpo1biNm3hXStx9Yaa7x7s5Kip8ZgAySn6Won7RMfaKYN8Us7WeMxs1+AajwlQqK2dsgAgJDS01mLXAqm2v8CDNPS5K3/J8RK/LYiold9FzMkgCIIgCIIgCIIgCPfwoF/M/68RwyUEQRAEQRAEQRAEQagWopFBEARBEARBEARBEIRqIRoZBEEQBEEQBEEQBEGoFmJOBkEQBEEQBEEQBEG4B0VRavsr/KWIngyCIAiCIAiCIAiCIFQL0cggCIIgCIIgCIIgCEK1EMMlBEEQBEEQBEEQBOEeVEUsYVkVoieDIAiCIAiCIAiCIAjVQjQyCIIgCIIgCIIgCIJQLWptuET9QA0Pd7ZGkuDwBT07TujNtof4yQx7yBo/D5lvNxdy+rqxdJuLg8SoHta4OsiowOINBaTnVN6FpWmENU8MdEaWJXYfy+P3Pbnm3ynYiscHOhPoo2P+mnSOniss3TZjvDthAVZcuV3MRyvTqpTXCH+ZQe21SBIcu2xkz2mj2fa6PhID2+vwcZP4YaeeczfLZi/t20ZL/QBTW9DOkwbO3LB8ZtOGdbWM7GGHLMOB00VsOVJktj3MX8vIHrbU8dKwbEMeUZfNfwMbK3h7gjOnrxSzZnuBxXHPnTzAT998iKIodOoxjL4PP2W2fc+Wn9m9+UdkWcbaxo7HJ72FX0AoBr2e7xe9y+3rF5AlmZFP/YN6jVtbFPPY8RMsXLwEo6LQr3cvHh05wmz71m3bWfrNctzd3QEYPGgA/fr0AeCNt97m0uXLNGrYgHdnv21xPgHORh1k9bKPUBUjD/UcyoDh4++a7vihHSz4cAZvzfuOumENyc3OZMG8Gdy8doGO3Qbx+MRXqxT3wqn9/LL8AxTFSPseD9N76ASz7fu3/sTeLT8gyxqsbewY9ezb+PqHYjToWb1wNjE3L6AoRtp0HkzvYRPuEaWiA1ei+eCPAyiKyrDWDXi6Swuz7fM2HuDYjXgACooNZOQVsH+W6fffEHWZJbtOAPBMt0gGt6xncdwrZ/bx56q5KIpCZJdH6DLwGbPtR3eu4ciO1UiyBitrO4aO/ydedcKIvX6G31aU/KaqSvehU2jYqpdFMZtF2DB2iCuyBLuO5rFhd7bZdq0GnhvlTt06VuTmK3y+KpXUDCMaDUx42I0QfytUFVZuyODijaJ7RKmocaiO0X0ckCSJfScL2HTQ/NqLCNQxqrc9/t5aFq3L5sTFYgDcnWWmjHBCkiQ0GthxtIA9UYV3C3FXTcKseXyAE7IEe07k88e+PLPt9YKseKy/EwHeWhb8nMmx82Wf/cpYV0L9rbgaXcwn32dYHBOgRQM7nn7EE1mG7QezWbfNfH+tVmLaE96EBlqTk6fw0TcJpKQb6NzKkaE9XUvTBflZMf2DaG7FFVcas2m4NU8McEaWYffxfH7fa14W1Au24okBTgR465j/Y4ZZXmeMcyO0pCz4+Lv0KuX11oW97F43B0VRaNx+BG16TTTbfmLncs4d+hlZo8HWwY3eY+bi5FYHgL3rP+Tm+T2gKgTW60jX4W8iSZJFccPrSAxop0WWJI5fMbL3jHkZ1LGRhlYRMooKeYWwbp+ezJKfv0WYTNdmGgB2nzZy8tr/7zLo/MkD/Lz8A1RFoUOPYfQZ9rTZ9r1bfmLvlh9L7o22jHl2Fr4l5c/qxe8Qff0CkiQzYvwMIiwsf6D2rp+Yy/s49MdcVEWhXutHaN7V/N54Zt8KLh9fiyxrsLF3o/Pw93B0rVO6vbgwl7WfDiSoYQ86DnnL4rghPtCzuYwswambKocvmdfBWkdINK8roaiQXwQbjylk54OTHQzvKCMBsgwnrqmcvG5ZF+RbF/eyd90cVFWhUbsRtOppfv1E7VrO+cM/I8um66fnaNP1E3P1MPt+/VdpuozkG/Qd+ymhTXtaFDfMT6Jfaw2SBFHXFPafM78G2jeQaRluun7yC1V+O2gkq+Tnf7yHBn9PiehkldU7jXf59Hs7fvw4ixd9jaIo9O7Tl5EjH71rugP79zN37nt89tkXhEdEoNfrmf/lF1y9ehVZlpj47CSaNm1mcdyDZy7x0aoNGBWFoV3aMH5g9wppth45zeLftiIhER7oy9zJjwHw/EdLOHs9mubhdfn85acq7HcvR0+cZP7S5RiNCgN692DMI8PMtm/esYuFy7/Dw90NgGED+jGgdw8Sk1OYNXceiqpgMBh5eGA/BvfrbXHc48ePs3DRIhRFoW+fPowcOdJs+7Zt21i6bBkeHh4ADBo4kL59+5q2bd/OmjVrABg1ahS9elp2PgnC30WtNDJIEjzS1ZqvfysgM1fl5UdtOXfDQFJGWUGTmaOyensR3VvqKuz/eC8bth4v5kqMESsdqBaUT5IETw524V/LUknPNvLuFC+iLhYSl2woTZOaaWTR2gwGPORYYf+Ne3Ox0kn0aGtf5bwO6ahl2Z96svJUnh9qxcXbCsmZ5fKaCz/v0dO5qfnPUS9Apo67xBfritFoYOJAKy7HFFOkvzPK3eOO7mXH5z/mkpGj8Po4R85c05OQVlY4ZmQrrPwzn15trO/6GYMfsuVqjOGu2+5FMRr5Ycm/eHHWQlzdvfnXq4/RtHUX/AJCS9O0eagfXfqYGgFOH9vNzys+ZtpbC9i3/RcA3v50LdlZ6Xz53hRe/2AVsnz/DjdGo5Gvvl7Iv957Fw8Pd6a+9DLt2rUlKDDQLF3nzg/x/ORJFfYfMfxhioqK2LhpU5Xz+v3i95k+ewFu7t68M+MJmrfpQp2AELN0BQV5bP/jB0IiGpf+TWdlzdDRk4mLvk5c9PWqxVWM/LxsDlNmLsbF3Yd5r4+iSatu+PqXHePITv3p1NtUWJ49votfV87juTcXcvLwVgyGYt74+FeKiwqY8/JQIjv2w92rzr3ClTIqCnM37GfRUwPxdrJnzIJ1dK0fRKi3W2mafwzoWPrv1QfPcikhFYCs/EIW7jjOD1OGI0kSo+avpWuDYJxs737u3Znf3799l/EzluHk5s3C2SNp0KIbXnXCStM0bT+QNt1HAXAxaiebfviAca8swcs/nMmzf0aj0ZKTmcz8mcOo16IbGs39b32SBOOHuTJ3STJpWUbmTPXhxIV8s/tFtzYO5BUovPRhAu2b2TGmvwtfrEqjexsHAF79NBEne5lXn/Zi5peJFt+nHuvryMerMsnIVnhrgiunrhSTkFpWOU3LMvLNhhz6tLcz2zczR2Hu8kwMRrDWwTuT3Dh9pZjM3MofCiUJxg5y4sMV6aRnG/nnJA+iLhURn1KW37QsI0vWZdKvU8V74J/787DS5dO9tV2FbfcjSzBxpCez58eRlmngw38EcvRsHrGJZQ0FPds7kVeg8Nw/b9Mp0oGxQzz4eHkie4/nsPd4DgCBfla8/oyvRQ0MkgTjBjnz/vI00rONvDPZkxMXC83zmmlk0dpM+j/kUGH/jftysbKS6N66amWBohjZ+fM7PDxlOY4u3qz+6BFCG3fH3bfsPPbyb8CYf/yCzsqW0/tWs2/9PAaM/4z4G1HE34jiidc2APDTZ2OIvXaUgPC2FuV3UHsdy7cUk50HkwfruBitkFKuDIpPU1iwwYjeCG3qy/RpreXH3QZsraB7Cy0L1hejAlOGWHExupjCyg9zrZRBitHIj0vn8sKsRbi4efPBa2No2qorvuXKn9YP9adzH9O98cyx3fyy8iOen/k1B0rKn5mf/EJOVhrz50zh1fdXV1r+/DuvtXH9KIqRAxvepf/Ty7B38ua3r0YS1KAbrt5l55SHXwMaTvkZrZUtFw7/wNFNH9FjzKel249v+wKfuq2qFFeSoHdLmTV7FLIL4MmeMlfjVdLKtcMmZagsv65iMEKLUIluTSXWH1bJLYRvdygYFdBpYUIfmatxpr9Xltfda99h2OTlOLh48+Mnj1C3cXfcfcry6unfgFHTTdfPmf2rObBhHv2e/IyA8HaMmbEegMK8TFbO6U1g/Y73ClUhrwPaavh2m4HsfJjYX8vlGIWUrLI0Cekqizca0BuhdYRM70gNP+813bMPnFfQaaFVRNU6DhuNRr5e8BXvzZmLh4cHL734Au3atSMwMMgsXX5+PuvX/0a9evVL/7Zls6kus+DrhWRmZjJr1kw+++wLi85lo6Lw/re/smDGRLzdnHli9hd0adGIkDrepWmiE1NY8cdOvpk5BSd7O9Kzyxppx/brSmGxnl92Ha5SXj9ftIx577yFp7sbk6a/Toc2rQgODDBL161TB6ZNMn8p4u7qwvx5c7DS6SgoKGD81Ol0aNOqtDGisrhfLVjA3Dlz8PDwYNqLL9K2XbsKdccunTvz3HPPmf0tJyeH1atX88XnnwPwwrRptGvbFkfHis8Pwv8OVRVLWFZFrQyXCPKWSc1USMtWMSpw8oqBJiHmlf70HJWENKVCxdzbVUKW4UqM6QZerAe9BXWQ0AArktIMpGQYMRrh8Ol8IhvYmKVJzTQSk2hAvcvTwPnrRRQWVf3kCvCUSMtWSc8x5fX0dSMNg8wPe0auSmK6ete83kxUUFRTHhPTFSICLPvJgn01JGcqpGaZCvNjF/U0DbcyS5OWrRCXYrzrw0+gtwZHe5mLNy1o0Sjn5rVzePkE4Onjj1ano1WnPpw+ttssja1dWcW9qLCg9G1cQuwN6jduA4CTsxu29o7cvn6+0piXr1zFz88XX18fdDodXTt35tDhIxZ/5xbNm2Fra2tx+n+7cfU8Xr4BeJXktW2n3pw6urtCul9Xf02/YePQ6coq0tY2tkQ0bIHOyqpC+srcvnYWD59APLwD0Gp1RHbox9lju8zS3HmMKX3hKVFcWIDRaEBfXIRGq8PGruKD1N2ci00mwN0JfzcndFoNfZuGsvvirXum33zmGv2amiqAB6/G0C7MH2c7G5xsrWkX5s+BK9EWxY29cQZ370DcvALQaq1o0rY/F6N2mqWxsS3LQ3FRAf/OsJW1bWmDgl5fbKoxWiAswIrEVAPJ6ab7xaHT+bRqZP4AENnQlr3HTa+rjpzNp3GY6X7i763j/HVTjTk7TyG/QCHE37LfOcRPS3KGkdRM03V79HwhLerdcd1mKcQmV7xujQoYStoitFrJ0qwCEOqvIznNWHZ/PFtAywbmD36pmUZikgzcrYy9cKOYwqKqT4gUHmxDQqqepDQDBiPsj8qhTVPzh7A2Te3ZdcT09HLwZC5N61V8EHso0pH9UbkV/n43of46ktLLlQVnCu5eFiQZ7npvPP8f5jXx9hlcPINw8QhAo7WiXssBXD+7wyxNQEQ7dFame5FvcHNyMhNNGyQJo74YxaDHaCjGaNRj5+hhUVx/D4n0bJWMHNM5cuaGQoNA83LkZqKKvuTciUlWcbY3nTzh/jLX4hQKiqGwGK7FKUT4//8tg25dO4enTwAe3qZ7cmTHvvcvf8rdKxJib1CvpPxxdHbHzs6RaAvKH6i96ycl5gxO7oE4uZnOqdBm/bl90fze6BfaFm3JOeUV2Iy87KSy/ePOU5Cbin+4ZQ/cpZ/pBhm5kJkHigIXo1Ui/MxvONEpZfej+DQVJzvTdkUxnYcAWrlc0VSJpNtncPEIwrnk+glvMYAbd14/4WXXj09wc3KzEit8zrXTWwhu8FBpusrUcZdIz1HJyDV973O3lNLepf92K6nc9ZOq4FTuFnUzUaW4atUoAK5cuVxSr/FFp9PRuXMXDh86VCHd9999yyMjRmBlVfZCLjo6mmbNTD0XXFxccLB34OrVqxbFPX8jmgBvD/y93NFptfRu25zdUebXwa97jjCiRwec7E0ZdXMqu6baNArHzqbylwflXbp6DT9fH/x8vNHpdHR/qCMHjhy3aF+dToeVzpT3Yr0BVbG8nn7lyhX8/PxKj3GXzp3veozv5sSJE7Ro0QJHR0ccHR1p0aIFJ06csDi2IPwd1Eojg7O9REZu+Tf5Ks4OlhU1Xq4yBUUq4/vb8MooWwZ3tLKoMu3mJJOWVfY2MD3biKuzpsrfvaqc7CWyyuU1K0/Fyd6yvCakqUT4a9BpwM4aQnxlXCzc19VRJiO77GabmaPgauExloBHutvyy658i9KXl5mejKuHT9n3cPMmMy25Qrpdm9bw5nMDWffdZzz61AwA/IMiOH18N0ajgdSkOKKvXyAjNanCvndKS0vD06Oswu3h4U5qWsUhLQcOHGTSlKm8O/dfJKekVDlvd8pMT8bNo6x139Xdm4w088+9ff0iGalJNGv10H8dr3xcV/eyY+zi7k1mesXjtHfzD/xzaj/Wr/qER8a/DkCLdr2wsrFl5sTuzHquNz0GjcPewdmiuMlZefg4l1UmvJwdSMrOu2va+Iwc4jJyaBNq6iGRnG2+r7ezA8n32PdO2RnJOLuV5dfJzZvsjIr5Pbx9FR+/0pstP33EgMffKP17zPXTfPH6QOa/OYQh496utBcDgKuzxux+kZZlwNXJ/H7hVi6NokB+oYKjnczthGIiG5q6iHu6aqjrb4W7hfcaFyeZ9OyyuBnZCi6Olt+nXJ1kZk90Zd40dzYdzLeoF4NpP/P8pmcpuFYh7n/KzVlLaka5t70ZBtydzX8f93JpFAXyC4w42psXXZ1aOrCvpFdDZVydNKTXQlmQm5mEo0vZeezg4k1u1r3vb+cOr6Vuw84A+NVtQUBEWxa/1YnFMzsR3OAh3H1C77lveU72Ell5ZWVQdp6Ks929y4JWERquxJrOGye7ivs63Wff8mqjDKpQ/rh7kXWXe+OeTWuYNWUAv373KSOfNg1V8w+O4MyxPSXlTyzRNy6SkVZ5+QO1d/3kZSfj4FyWX3snb/Luc05dPvYL/hGmskhVFI5s/IC2/WdUOa6DLWTnl50XOQXgeJ9n9mZ1Ja4nlKV3tIWne8tMGShz+HLlvRgAcrOScHA1v37ul9cLh9cS1KBzhb9fObmRiJYDKw9YwsmO0qEPAFn5Ko736XDSMszUM+O/lZaWhoeHZ+n/e3h4kHZHvebataukpKTQpo15j6a6ISEcPnIYo9FIYmIi165dJdXCOk9yRjbebi6l/+/t5kxKRpZZmtuJqUQnpfDUu/MZ986XHDxzqarZM5Oalo6Xh3vp/3t6uN21Drf30BGenjqdt9//iOSU1LLvnJLK01On8+hTkxg1fKhFvRhMce+sO1Y8xgD7Dxxg8nPP8d6cOaSUHMcK+7rfvd4pCH9n921kkCSplSRJuyRJ+l6SpABJkrZJkpQlSdIxSZJa3G/fB0WWIMRPw4b9RXzyYwHuTjJtGvxvrsR5NU7hcoyRyUOsGN1dR3SySk2sntKlpTXnruvJtGCei/9Ut36jmLPgDx5+Yhp//rIEgI49huLq7s3cGWP4afk8Qus1s6h7nyXatW3DyuXLWPjVl7Rs0ZyPPvmsWj73fhRFYc3yT3l0/EsPPNbddO47mre/3MSQx15iyy+LAbh97RyyLPPeoh3Mnr+Jnb9/S2pSTLXH3nzmGj0bhaCppt/PEu16Psb0j7bSZ+R0dm9YWPr3gNBmvPCvP5g0+yf2/LEEfbHl8yP8J3YfyyM9y8CcF3wYO9iVK7eLauS6BVOjxOzFGbwxP50OTW0sbtD8KwsPsqZIrxKdYEEf/r+Ii8fWkxR9jsjupq7BmSm3SU+8zoR39vDMu3uJuXKY2OuWvemrimahMn4eEvvOVm3seHV70GVQl36jeOerjQx7/EU2rTWVP+27m8qfD14dw9rl8wip1wypBu9fD9rVkxtIjTtHs86mOSouHP6BgHqdzRopHoRGgRI+bhJHLps3SizbqrDwT4UmQRJ2VXvxXalLx9eTFHOOlt3Nu9bnZSWTGn+FwPqdqjdgiaZ1JfzcJQ6cf/BdqhVFYemSxUx45pkK23r37oOHhyfTpk1l8eKFNGjQsNrqUgBGo0J0YiqLXp/M3MmP8d7yteTkWT5v13+ifetW/LB0Acu+/JjI5s14/7P5pdu8PD1Y9uXHfL/oS7bu3E16Rma1xW3bti0rVqzg6wULaNmiBR9//HG1fbbw16Mq6l/yv9pS2dP5AuBtwAU4CLykqmovSZJ6lGxrf7edJEmaCEwE6P7o5zTpaD75S1aeavZGw8XB/G3//WTmqsSlmoZaAJy9YSDIR6ayzvHp2YrZ20Q3Jw0ZWQ++IpWdZ95Lw9leIjvP8h981ykju06ZvueobjpSsyzbNyNHwdWprFBxcZTNeo/cT4ifhrAAHV1aWmOtk9BoJAr18NueygsRFzcvMlLLuihmpCfh4u51z/StOvZl1eK5AGg0WkaO/0fptg/eGIuXX9C9di3l7u5OSmpZq3Zqahoe7u5maZycnEr/3bd3b5Z+s6LSz62Mi5sX6eV6WmSkJeHqXvbmobAgj7joa3ww0zQ5VVZmGl/MfYkX3viUumEN/6u4GWllxzgzLQkXN+97pm/ZoR8/LnkPgOP7N9KgeSc0Wh2Ozu6E1GtO9PXzeHgH3HP/f/Nyticxq6xLenJWLt5Odx+XvvnMNd4YXNZ7w8vJvnRCSICkrFxah/hVGhPAydWLrPSy/GanJ+Hkeu/8Nmnbnw0r/1nx+/uFYmVjR3LcVerUbXyXPctkZBnN7hfuzloyss3vF+kladKzjMgy2NnI5OSbKpff/V5Wyfnnc94kpFjWXzYzW8GtXI8JVyeZzJyq36cycxXiUwyEB+pKJ4a8n4xs8/y6Octk/Adxqyo9y4CHa1kx5O6qJS3LfPxbWkmatEyD6TjbasjJK6vEd4p0tLgXA5jy6lYLZYGDi3fZ8AdMPRscnCuex7cvH+To1oWMeOF7tDrT8IJrZ7bhE9wMK2vT9Rbc4CESbp7EP7TysfTZeWXDH6CkZ0N+xbIg1E+iazMNS//Ul3Znz85Xqesjm+17M9GyB6jaKIMqlD9pyTjf594Y2bEvPyyZA5jKn0fKlT/z3hiLt2/l5Q/U3vVj7+RlNiQgLzsJ+7ucU3HXDnJq1yIGTvwWjdZ0TiVFnyLx1gkuHP4BfXE+ilGPztqONn2nVxo3t4CSHi2m39PR1tRwcKdgL+jQUGLVLqX0nDL7nEJIyVYJ8ITLsfeP6eDsTW6G+fVzt7xGXz7Isa0LGT71e7Ra8+E5V09tIrRpLzSainN93Ut2PjiXK+ac7SRy7tLBJsRXonMTDcu3Gu6a16pyd3cnNbWs90FqamrpxNUABQUF3L59m9deNfVEycjI4J13ZjNr1mzCIyKYOPHZ0rTTp79EHf/K510C8HJ1Iim9rPxKSs/C09W8t6O3mzONQwLRaTXU8XQj0MeT6KRUGoVUXo+4Gw93N5JTy3oBpKSmV6jDOTuVzXUwoFd3Fq/47q6fExwYyNkLF+nS8a6PJ3ekv7PuaH6Mwbzu2KdPH5Z9803pvmfOni3bNy2Npk2aVBpTEP5OKmva1KmquklV1R8AVVXVtZj+sQOwuddOqqouVlW1laqqre5sYACITlLwcJFxc5LQyNAiQsu5m5YVyNHJCrbWYF8SPdxfQ1J65RWXG7HF+Hho8XTVoNFAu2Z2nLho+czr/6nYFBV3JwlXR1Nem4VquBBtWQkkSZS28Pu4md4GXI21bN/bCUa8XGXcnWU0MrRuoOPMNcve9H3zRz5vfJ3Fmwuz+WVXAUfOFVnUwAAQHNaI5IRoUpPiMOj1HN+/hWatupilSYq/Xfrvsyf24eVrmmSnuKjANH8AcOH0IWRZazZh5L3UiwgnLi6exMRE9Ho9u/fupV3bNmZp0tLLZoE/fOQogQH/WWFYXt3whiQlxJBSktcj+7fSvHVZXu3sHfni253MW/wH8xb/QWhEk/+6gQEgMLQxKQm3SU2OxWDQc+LgJpq06mqWJjmh7Bifj9qLZ8kxdvXw5co5U5NcUWE+t66ewbtOXYviNqrjRXRqFrHp2egNRjafuU6XBsEV0t1MziCnoIhmgWUVwA7hARy6Fkt2QRHZBUUcuhZLh3DLfoM6dZuQlnSb9JRYDIZizh75k/otupmlSU28VfrvK6f34O5tejhIT4nFaDQ9tGakxpGacAMXj8orW9dji/Hx0JXeL9o3s+PEBfNr4MSFAjq3MtU+2zax4/w10/3ESidhrTM91DUJt8GoqGYTRt7PzXgD3m4aPFxM122bRjacumLZdevqKKMreV63s5EIC9CRmGbZffVGnB5vdw0eLiX3xya2nLz0YHt8AFy9XYivpxVe7lq0GujU0pFjZ8yH0Rw7m0e3tqaKXocWDpy9UlbDlyTo2NKR/Scsb2S4EafHx71cWdDUlqhLD74s8AlsQkbKLbLSYjAairkctZGQJub2IaFbAAAgAElEQVSztifHXGDHmlkMfuZr7BzLKruOrn7EXjuGYjRgNOqJvX4MN2/LhkvEpaq4O0u4OoBGhqYhMpfuKIN83SSGdNDx/XYDeeUOxdVYhbA6MjZWppUewurI/6/LoKDS8icWg17PiQObadravPwpf288F7UXL5/y5Y/p3Lp4+hAajcZswsj7qa3rx9O/Cdmpt8lOj8VoKOb66T8JbHDHvTH+Avt+nU3vsV9h61B2TnUfNY8xr+1k9Ks7aNd/BuEthljUwAAQnw6uDqaHb1mGBoESV+PN62HeLtC3lcza/Qr55Q6Fo61pZR4AGx0EeEikW3D5egc2ITO17Pq5enIjIY3vuH5iL7Dzp1kMuuP6+bfLURuJaDnAojyW5jVNxc1RwqXk+mkcLHMpxvwa8HGDQe00rN5lfv38NyIi6hEXX1av2bt3D23btSvdbm9vzw9rfmL5im9ZvuJb6tevX9rAUFhYSGGh6YucjIpCI2sqTBh5Lw3rBhCTlEpcSjp6g4GtR07RpYV5naVry0Ycv2SasDojJ4/oxBTqeFk2ROFu6oeHERefQEJiEnq9np37DtChrXkDalp62aorB48eJ9DfH4CU1DSKikwnWE5uLucuXiKgjmUvMCIiIogvd4z37N1Lu3LHGCDdrO54hICSumNkZCRRUVHk5OSQk5NDVFQUkZGRVc+8IPwPq6wnQ6EkSb0BZ0CVJGmoqqq/SZLUBfiPm+kVFX7ZU8SkwbbIMhy5oCcxXaFfWyuik42cv2kkwEvm6QE22FpLNArW0retwgerC1BVWL+/mCnDTAMAY1MUDp2v/C2hosCKDZm8+pSHaYmp43nEJRsY3tORm3F6oi4WEuKv46XH3bGzlWjRwJbhPY28+plpPoG3Jnrg56nFxlrmy9d8WPxLBmevVl6JUFTYcNDAU/10yBIcv2wkOUOlV6SW2BSFi9EK/h4ST/SywtYa6gfK9IpU+XRtMRoZnh1kaokvKoYfd+kt7natqPDjtnxeGOmALMHBs8UkpCoM6mTD7UQjZ67pCfLRMOlhB+ysJZqE6RjYSeWdZdmVf/h9aDRaRk14jc/fnYyiKHTsPgS/wDA2/LCAoLCGNGvdld2b1nDxzBE0Wi129k6Mf/4dALKz0vni3eeQJBkXNy+eeuE9C2NqmDJ5Em+89bZpqadePQkOCmLld98TER5O+3ZtWb/hdw4dOYJGo8HRwZHpL00r3f/lGa8SGxNLQWEhj419kpemvUCryJYW5fXxZ2bwyT+fR1GMdOoxhDqBofy6+muCwxrSok2X++7/j4kDKSzIw2DQc/Lobl5++6sKK1PcK+6Ip95gwZxJqIqRdt2G4RsQxsYf5xMY2ogmrbqxd/MPXD57GI1Gi52DE09MMb2t69x3NN8vmMmcl4eCqtK221DqBFm2lKRWI/P64E5MXr4RRVUZGlmPMG83vtp2jEb+nnQtaXDYfOYafZqGmS2v52xnw8RukYz5yjSD+7PdI3G2u2c7ZYX8DnxiJivnTTAtYdn5Ybz9w9m+7gvqBDemQcvuHNm+muvnDyJrddjaOTH8GdNyZbevnGDfH0uQtTokSWLQ2FnYO7pWErHkfrE+ndcneJmWOTyWR2ySnkd6O3MztpgTFwrYfSyX50Z58OkMX3LzFb5cbXoj4uQg8/oEL1TFNN5/wRrLx2kqKqzanMtLY5yRJYn9pwuJTzEypIsdtxIMnL5STLCvlikjnbC3kWkWbsWQLgqzFmbg66FhZK+yN05bDhUQl2zZbVpR4Ns/spkxzg1Jhr1RBcQlG3i4uwM34/WcvFRE3To6po12xd5WokV9G4Z1d+CNL015fvNpd3w9NdhYyXz2ihfLfsvkrAUPlIoCS35K5u0pdZAl2HE4m5jEYkYPcONadBHHzuax/WA2L471ZsHbQeTmKXy8PKF0/4ZhtqRmmCaOtPgYK7Dy9yxmPOluKguiTKuGDO/hyM24YqIuFRFSR8eLj7mZyoL6NgzvYeS1L0xvFd96xh1fTy02VjJfzPBmybpMzl6rvCyQNVq6PzKLdQsmoCpGGrUbjodvOAc3fo53YGNCm/Rg7/oP0Rfns3G56f7k6OrLkIkLCW/eh5grh/nu/UGARHCDhwi9o4HinvlV4fdDBp7sY7oGoq4aSc5U6dFCQ1yqyqUYhb5ttFjrYHQ3U5UgM0/l++0GCoph9ykDzw02lUO7Tpn+Zmncmi6DNBotj054nfnvmcqf9t2H4hcQxu9rviIotBFNS8qfy2cOo9HqsLV3ZOzUdwHIyUrny/cml5Y/416YY3Hc2rp+ZI2WDoNnsumbCaiqQr1WD+PmHc7xbV/gWacxQQ27c+TPeRiK89m+2jRsz8HFlz5jF/wHR7eMqsK2KIVRnWUkCc7cVEnNhocaSSRkqFyLh27NZKy0MKy96V1Wdj6sPaDg7gQ9mpmWH5eAI5dVs5Ua7pfXrsNnsX7hBBTFSKO2w3H3Defwn5/jFdiYkMY9OLDhQ/RF+fxZ7voZ9Ixp6Fx2Wiy5mQn4h7a5X5gKFBX+PGrkiZ5aZAlOXjOtLNGtmUx8msrlWJXekRqstDCyi+n6ycpT+WGX6d77VB8NHs4SVlp4ebiW9YeMXI+vvCKn0WiYPPk53pr5Joqi0Kt3b4KCgvnuu28JDw+nXbt7v6nPysrkrZlvIsky7u7uvPLKP+6Z9k5ajYYZTwzl+XmmJcGHdG5DqL8PX6/bQsNgf7q0bET7JvU4fO4Kj7w+D1mWmfboQFwcTA3uT89ZwK2EZAoKi+j34nu89fQIOjS5fx1Do9HwwrNPM2O2aXnffj27UTcwgG9WraFeWCgd27Zm3e9/cuDocTQaDU6ODrz24hQAbsfE8vU335panFWVkUMHERJsWYOK6RhPZubMmRgVhd69exMUFMS3331HRHg47dq1Y/369Rz+d93R0ZHpL78MgKOjI6NHj2baiy8CMGb0aLGyhCDcQbrbSgqlGyWpGfAhoAAvAZOBcUAc8IyqqgcrC/Dilxb2j6xGKfEWlFgPQEBIxZbzmpCZ/mDHwt3LqAGWPSRWt2Cb6p9DoDJxxZa1jFe3PH3VV5+oDp2vfVUrcX+vM63yRNVs3bpK+uk+IHb3myntAdIXV21Z2uqSk2HZ6g/Vyd65astMVpdOnWvnfhET9+Dfnt9NWkrVJwn+b43oXzvXz8qfMipP9AA0bXHvYR8Pkt5Q8+N5nWpg0sy7SbZwWFt1e6Jj7ZRBPilnK09UzbJdg2s8JkChtnbKAoCQUMt6RP2P+J+eCKrfk2dqb4KD/8KmFU1r5Xe573AJVVVPAy8CHwGxqqpOU1XVRVXVRoDT/fYVBEEQBEEQBEEQBOHvpbLVJV4AfgWmAuckSRpSbvPcB/nFBEEQBEEQBEEQBEH4a6lsToZngFaqquZKkhQMrJUkKVhV1c/5H+8SIwiCIAiCIAiCIAhC1VTWyCCrqpoLoKrqLUmSumJqaAhCNDIIgiAIgiAIgiAI/+MUtRrWp/0bqWwJyyRJkpr/+39KGhwGAh6AWBBWEARBEARBEARBEIRSlTUyjAUSy/9BVVWDqqpjgc4P7FsJgiAIgiAIgiAIgvCXc9/hEqqq3nNdHVVVD1T/1xEEQRAEQRAEQRCE/z9U5S+5gmWtqawngyAIgiAIgiAIgiAIgkVEI4MgCIIgCIIgCIIgCNVCNDIIgiAIgiAIgiAIglAtKlvCslqc2H6yJsKUCmwYgs66RrJWwdkj12o8ZkB4Hc7tP1PjcRnQhkDb+BoP63Nua43HjAt/kgBdTI3HvaQPxajUzmqx55uMq/mg6dD32Ks1GnIdU8lKzarRmAB2jrbEX0+o8bieAZ4U5BbWeFyAjMTUGo1n72xfa2Mox3huq/GYH8R15uFOeTUed8mvEh3bu9Zw1EK+Xlrz5Y+dky3zh52r8biLb3lz7GDNl0HN2/hjMNb8NXTmdHqNx/Txc+T8iZo/xnSU8E0+XeNhVUmmaPOGmg06+gXcLu2t2ZhAfON+aFRDjcc1SloSLp2q8bi+9ZtXnkioMlURS1hWxQPvyVDTDQzA36qBAaidBgaolQaG2lIbDQzA36uBgZpvYABqpYEBqJUGBuBv08AAtTdJU200MAC10sAA1EIDA7XSwADUSgMDUCsNDMDfpoEBqJ0GBqiVBgag5hsYoFYaGIBaaWAAsNXn1Erc2mjYEIQ7ieESgiAIgiAIgiAIgiBUi9p55S8IgiAIgiAIgiAIfwFiCcuqET0ZBEEQBEEQBEEQBEGoFqKRQRAEQRAEQRAEQRCEaiEaGQRBEARBEARBEARBqBZiTgZBEARBEARBEARBuAdVFUtYVoXoySAIgiAIgiAIgiAIQrUQjQyCIAiCIAiCIAiCIFQL0cggCIIgCIIgCIIgCEK1EHMyCIIgCIIgCIIgCMI9KIpa21/hL6XWGhnatHBl2jMhyLLEH9sSWfVLrNl2nVbizZfqUS/UgewcPW/Pu0RichFOjlrefbUB9cMc2bQzic8WX7c4ZpMwK8b0dUSWYW9UARv355ttjwjSMaavIwHeWr5em8XxC0UABPpoGTvAEVtrGUVV+X1vHkfPF1kcN7KRAxNH+yLLsHVfBj9vSjXbrtVKTH/an7AgG3Jyjby/KIbkND1e7joWvhtOXKIp1qUbBXz1fbzFcdu2dGXaM2ElxziB79fGmG3XaSVmvlyfeqGOZOfomfXhBRKTTbEefySAgb18URSVzxZf4+jJDIvjHj9+nIWLFqEoCn379GHkyJFm27dt28bSZcvw8PAAYNDAgfTt29e0bft21qxZA8CoUaPo1bOnRTEPXL7NB+v3oqgqw9o05OlurSqk2XL6Kgu3HQFJop6vB++P6QPAp38eYN/FWwBM7NGavs0jLM7rsRNRLFi8FEVR6Ne7F6NGDDePuX0HS75Zibu7GwBDBg6gf59eALw+659cvHyZxg0b8t7bMy2OCXDx1H7WrXwfVTHSrvtweg6ZYLb9wLYf2b91DZIsY21jx6PPzMbHP5Tj+/9g5+/LS9MlRF9h+r9+xj+4vkVxT584xLdLPkNRjHTrNZjBI8beNd3RA7v47P03eO+TbwgJb1D699TkRP4xZQzDRz/NwIcfsyimJrAeNp0HgySjv3CU4hO7zLZbdxqExj8MAEmrQ7JzIHfxLDR1QrF+aHBpOtnVk8ItqzDcOG9R3MjGDjw7xg9Zgi37Mvj5zxSz7VqtxCsT/AkLsiUnz8i/vo4uvW4XzYkgtuS6vXw9n/nfWX7dRjZxYNKYOsgybN6bzs8bzePqtBLTnwkgPNiW7Fwj//r6Nsmperw8dCyeW6807qXr+cxfGWdx3Ob1bRk/zA1ZkthxJIffdmSZ51cDUx/zJMTfmpx8I5+uTCElw4BWAxNHeBAaYI2iqiz/NZ0L1wstjtumuQvPjw9GI0ts3JHE6t/Mj5VOK/H61DDqhTiQlavnnU+ukphSRGRTZyY+FohOK6M3KCz87jYnz2VbFLNphDVPDHRGliV2H8vj9z25ZtvrB1vx+EBnAn10zF+TztFzZfl5qKUdQ7s5AvDbrhz2RZmXI/dz8NQFPv52LYqiMKRbB54c0tts++97DvPFqt/wdHMGYGTvLgzt3gGAL1f/xv6TpnP36Yf70rt9pMVxa+O6Bbh+bi9b1sxBVRSaPzSCjv0mmm0/sfsHju9ejSzJ6GzsGPDEu3j6hZGfm8EvC18g/tY5mnUYRt8xsyyO2by+LeMfdkeWJXYczua37Xc5jx/3IiTAmtw8I5+sTCYl3YBGhsmjPanrb41Ghj3Hcvl1e6bFcWvrt21Wz4Ynh7ghy7DzSC7rd5lfA1oNTBntQYi/FTn5Cp9/l0JKhhGNBiY+4k6IvxWqCivWp3PhuuX1mlBfiT4tZSQJTl5XOHjRvPLdtp5Ei1AZRYX8QpXfjyhk5YO3C/RvrcFaB4oK+88rXIi2rOLeqK6OkT3tkGXYf7qILYfN7zPhAVpG9rCjjpeGpetzibqsN9tuYwWzJ7hw6moxa7ZZft3W1jl14MxlPlq9AaOiMqxza8YP7FYhzdajp1n023YkICLQj7mTRnP5djxzv/2VvIJCZFnm6UHd6dO2mcVxdWGNsO87GmSZwqh9FO7fZLZddnbDYehTSDZ2IMvkb/8F/dWzSLb2OI6cjLZOMEWnDpL352rL81pbdbjjJ/h68VIUxUjf3r0ZNfIRs+1bt+1gyTfLcXd3B2DIoAH062O6tt94620uXr5C44YNeHe25fcogCNRp5i/ZAVGRWFAr+489shQs+2bduxm4Yrv8SipOw7r34eBvXuUbs/Lz2fc89Pp1LY1Lz77VJViC0JNqZVGBlmGl58N5aW3z5GSVsSSj5pz4Gg6t2LKbvoDevmQk2tg9KTj9HjIk0nj6jJ73iWKixWWrrpNSJAddQPtLY4pSfBEf0fmfZdJeraRt59x4+TlIuJTjKVp0rOMLP0tm34d7Mz2LdKrLPk1m6R0Iy6OMrMnunHuejH5hZUXjLIEkx/zY+YnN0nNMPDpzBAOn8ohJqGsMO/TyZXcPCPPvHGVzq2dGf+IDx8sMjUIJKQUM/UdyxtSSuPK8PKkcF566wzJaUUs/aQl+4+kmR3jgb19yck1MOrZo/R46P/aO+/wqKr0j3/OlPQ+qZCEmrBIDS10ULDvyqqrLsquvWABrKvI2rBgxS66YlkBXX8W7F0R6YZqaAGkhbRJJj0hycw9vz/ukGRSB82dIJzP88yTO7nnzveee895z3vfU24M0y/ryb2Pbad7UhCTx8fyjxt+Jtrmz9NzBzL1unVoXiyq6nK5eOHFF3n4oYeIjo5m5qxZpI8cSbfkZI90E8aP5/rrr/f4X3l5OUuWLOHZZ54BYMbMmYxMTyc0NLRtTU3j4Q+X8fLVfyUuPISLn/sfE0/qSa+4qPo0++0lLPwhgzev/xthQQEUVejXYfn2vew4ZOfdWVOpdbm4asEHjP1Td0IC/LzK63MvvcyjD95PtM3GjTffzqj0EXRLTvLM67ix3DT9mmbHX3DeX6mpqeGzL79uV6sxmubivdceZPrd/yHCFs9Tsy+i/9CTiU/sVZ9m6JizGXPqRQBkZvzA0rce47q7XmbY2D8zbOyfAcg5kMXCJ2Z4HWDQXC5eX/Akd819Bpstljm3XMGQ9HEkJvfwSFddVcmXn7xL7z79mv3GooXPMmjoSO8zKwQBE8+laukryIpSgi6agfPXrWjFBfVJalZ8Ur9tHTgGc0wXAFyH9lD1znx9h38gIf+8E+eBLK9kTQKun9aFu5/cS6HDydP39GLNpjIO5jSqt+P0envVXVmMHxHOFRfEM2+Bu94W1HLTfbu9z2cj3Rv+0ZXZj++l0FHHM/f2Zu3GMg400j1tfBQVVS6u/NdOJqSHc8UFCcx76UC97o337PpNuleeb2PugjwcJU4eubkLGZlVZOc3OOmnjAylolrjpoezGZ0WzLS/RDL/v3YmjdTr562PHyIsxMTd18Rz5/wcpBfPDSYTzLyqB7c9sA27o5YF8wawMqOY/dnV9WnOmhRLRaWTS27ayCljbFwzLZkH5u+itLyO2fN2UFRcR4+kQB6bcxIXXLu+XU0h4LJzInhkYSGOMhdzb4hlw/bDHCpw1qcpLHHx8nvFnD3O0/YEBwrOmxTKnOcLkBIeuimW9duqvWoLXJrGY6+/y/OzbyTOFsGldz/O+KED6JmY4JHu1FFDuONyz8Dsig2Z7Nh7kMXz7qSuzsm1c59h9KCTCAkKbFe3U+otup36YskDXHLz64RFxrHwob+ROugUYrr0rk/TP/0vDJ04FYCsTd/xzbuPcPGshVis/kyYMhP7oV3Yc7wvzyYBV10QzQMv5uIocTLv1q5k/OJZjieNCqOyWuOmBw8yJi2YaX+JYv6bBYxKC9YDeI9m42cVPH1XIis2VGB3ONtQ1OmseysEXHFuFA+9UkBRqZNHZiaQsa2aQ43rbXoIldUaM+flMHpwEBefHckziwqZlB4CwO1P5hIWYuKuq2KZ/UyeV/VWCDhjqInFP7goq4arTjOTdchFYaP4Rl4xvPqVC6cLhvYWTBps4oNVGnUu+Gi1C0cFhATCVaeb2ZProqaudb0jmlNPC+Lpd8opLte467IwtuyqJbeowTFxlGm88Vklp6YHtPgb54wPYtfBdoSa0Jll6tG3lvLi7VcRFxXOtPufZ0LaSfTsGlef5kBeIa9/uozX755OWHAQjjI9WBrgb2Xu1ReRHB+NvbiMS+57ltH9UwkNbr9MIQTBZ11C2VtPoZUVE371HOp2bsJlz61PEjj+bGq2ZlCTsQxzTAKhl8yk5Ok7kc46qn5Yijm2K5bYrl5f48704Z5/6WXmPfgA0dE2brr5VkaNHNGCvzqWG6df1+z4C84/j8M1NXz+xZde51XX1Xjm5dd44v67ibHZuO62uxgzYhjdkxM90p08dnSrAYTXFr/LoH59W9ynUBwrdMqaDH1TQjmUd5jc/MM4nZLvfrIzdkSUR5px6Ta+/D4fgGUr7QwdGAHA4RqNX7aXUVt7dK8R6dnVSr7Dhb3YhcsFazMPk9bH3yNNYYlGdr6zWSObX+Qi36EHI0rKNcoqNUKDvLt0qT0CySmoIa+wDqdLsnxdKSMHezqu6YND+W6VPlJgxfpSBv3J++BJa/RNCSM7t5oc9zX+dnkBY9NtHmnGptv44rtG13hQZP3/v11eQJ1Tkpt/mOzcavqmhHmlm5WVRZcuXUhISMBqtTJh/HjWrF7t1bHr168nLS2N0NBQQkNDSUtLY/369h8aMg/mkxQdQaItHKvFzBmDUlm29VePNB+s28rfRw0kLEh3PmwheiDp1/xihvTogsVsIsjPSkpCNCt37vfqfHdm7aJLQgIJ8fFYrVYmjh/LqjVrvToWYMjgQQQFetHoN2H/7l+Ijk8mOi4Ji8VK2ugz+SXje480AUEh9ds1NdWAaPY7G1Z+zpDRZ3qtu3vXNuISEomL74rFamXU+MmsX7u8Wbr/W/wKfzl/GlarZyP/8+ofiYlLIDG5p9eaprhktJJCZJkDNBfOrE1YejZ/CDqCNXUwdVmbmv+/90Cc+3eA0zsHM7VnEDkFteTZ3fV2bSmjBnvWgZFpYXy7Su+VWpFRyqC+IS391FGR2jOInPxa8uy1OF2SH9eWMDLNU3dUWhjfrtDtxU8/lzL4pN+v2zvZn7zCOgqKnDhdsHJjJcP6ewZbh/cP4sd1uhO7ZnMl/VP0spsY70fmbr1HsaxCo7Jao1dS+w4ewJ96h+htQUENTqfk+5WFjBke6ZFmzPAovlymj+b4cXURQwfoPcG791ZRVKzfz70Hq/H3M2G1NC/nTemV5Ed+kbO+LVizuYqhfT0fSgpLXBzMcyKbNAYDUwP4ZVcNldWSqsOSX3bVMKhPyw80Tdm6ex9J8dEkxkVjtVg4ddQQfszY4tWxew/lkda3NxazmcAAf1KSu7J683avju2MeguQs3cLUTHdiIxJwmzxo9/ws8na9J1HGv/AhrJbW1ONEPr98/MPIjllGBarZxvdHr27+ZNnb1SON1QyfIBnezq8fxDL1pUDsHpzJQNS9XIsJfj7CUwm8LMKnC5J9WHv/IzOure9k/WyXOBw4nLBqk2VDO/n2aYM6xfEjxnueruliv4penlNjPMjc5dnve2Z6F297RIFxRWSkkrQNNh6QKNPomfd218gcbr7cA4VScKC9P2OcnC4Bw5VVEPVYQj24jb3SLBQUKxRWKrh0iBjWy2DUjzPt6hU45Dd1WKgJDnOTFiQYNu+owsydFaZyvz1IIlxNhJjbVgtFk5PH8Syjds80nzw4zounDSKsGDdVkeF6fWpW3wMyfH6SNGYyDAiw0IoLq/0StfStQcuRwFacSG4XNRkrsPaZ7BnIgnCXy9Hwj8Qrdw9OqOuFueB3V63s/V57UwfrksCCQnxbn913FH5cGm/0YfbsWs3XePj6BIfh9Vq4ZRxo1m57mevj9+5+1ccJSUMGzzwqLUVvw+paX/IT2fRKUGGGJs/BYUNPXP2olqibZ6tTHSUX30alwaVlU7CQ3/7wIvIMBOOsoYLXVymERlmPurf6dHVgsUsKCh2tZ8YsEVaKSxuMLiFxU5skdZmaezuNJoGVdUaYSH6ucVH+/HsPb2Yd3sP+qV4Ov1tEWPza3KNa4hpco31+6A7GfXXOMzS/P4U1hBj8875KCwqIsY9DQIgOjqaoqKiZulWrFzJ9Ouv58GHHsJut7d8rM1GYQvHNqWgtJL48AZnNTY8hPwyz+HP+wuL2V9YwqUvvMe059+tb4RSu0SzaucBqmvrKK6s5uc92eSVlHuZVwcxMY3zaqOwyNE8r6tWc82NM3ng4UcpsNub7T9aSh0FRNri679HRMVR6iholu6nr95m7owz+GTxk5x/2V3N9m9c/SVDxpzltW5xkR1bdGz99yhbLI4iz/zs3b2TInsBacPHePz/cHUVn7y/iPOnXum1HoApOAytomF4qVZRiggJbzGtCI1AhEXhym4+gsCS0nLwoTVsERYKHY3rbV3zehthxe6o1c9Lg6pqV0O9jfHjuXt78+i/jq7eRkdasbenG2mtP7eWdJ+/P4XH7uxJv1TvdaMizBSVeI7qsoV72tuocAuFJc4G3cMaocEm9ufUMqyfPoQ5NspCzyQ/bBHe2eqYKD/sTdqCmCj/FtLo19mlQUWVq1lbMGFkFLv2VlDnbL8bNirMRFFpo7yWuYgM964tiAwz42h6rJftiL24lDhbQwAlzhaJvbi0Wbrv121i6h0P86/5r5JXpAeTUrrpD56Ha2opKasgY1sW+UXeTWHrjHoLUF6ST1hUg50KjYyjvCS/WbqMHxbz/OzJfPf+45z+96ObNtaUxmUUoKjESVSTexsVYaGwuHk5XrOpkppayX/mdmPBfcl8/H0pFVXeOWeddW+jwi0UeeS3eVmOCm+o20f8i9CgI/U2EJMJYqIs9Ez09x3S/0AAAB8FSURBVLrehgUJyhrNNiirgtDA1gN8g3ua2J3b/Fp2iQKzqSHo0BYRoYLi8oa6V1yuERHqnQsrgL9NCuK9H7yfInGEzixT8VER9d9jI8MpaFKmDuTZ2Z9XyOUPvsg/H3ielVt2NvudzF8PUud0khgb1WxfS5jCItHKGsqfVlaMOcwz8Fu17GP8B44k4pbHCL1kJpWfv+3Vb7dG5/lwnj5nTKv+6mquveEmHnh4Xof4cPYiBzHRDZ1+MTYb9hbq/PLVa7lixu3cM+8pCuz6NGtN03jx9beYfvk/fvd5KBRG02aLIoQIAe4AzgcSgVpgD7BASvlGG8ddA1wD0HvgbcR3P6e1pH8owkNMXHNuOK8uLfNqSOHvxVHq5LI7dlJe6aJ3twDm3NCN6ffs8joSfqySnp7OhIkT8bNa+fzzz3nyySeZN2+eoZpOl2R/YQmvXncu+aUVXPHSB7x3y8WMTk1m68F8Ln3hPSJDAhmUHI/Z1HGxt1EjhnPyhPH4Wa18+sVXPD7/WR5/eG6H/X5bjDt9KuNOn8r6FZ/x9Ycvc8n1D9fv27drC37+gSQkpXSYnqZpLFr4DNfN+nezfe8veZWzplxEQKD3D75HizVlMM7dW2haOUVQKKboeFwHmjtgRuAodXLpbTvq6+2/b+rGdXOMr7fFJU7+ect2t24g98zoxnV3Z1FlsO73a8vpGmfl0Vu6YHc42bm3xqupVR1F98RArpnWjdvnbms/8THOuCH9OX30UPysVj74dgX3v/gWL/17BiMH9mXbnv1cce+TRIaGMCClB6YOslOdXW+HnXwJw06+hMy1n/DTZy8x5YpHDdNqi97d/NE0yTX/3k9wkIm5M7qwJauagqL2h7Z7Q2fc27b44ecKusZZeWRmAvZiJ1n7agxZ1GxAd0FClOC/33kahZAA+OsoMx+t8a7D5vcwYYg/mXvqKCn37aJtRpcpp6ZxML+QV+68loLiUq56ZAHvzr25flqEvaSMf7/yDvdfdWGHlin/ASOo2bSKw6u/xpLYk5DzrqT0xXubtb0dSWf5cCPThzNx4hEf7ksef+ppHn/koQ77/dYYPXwok8aPwc9q5eMvv+GRZ15k/oP3sPSLrxk5dDCx0bb2f0Sh6GTaC1svBj4ETgcuBIKBd4A5QohUKeXslg6SUr4CvAIwbspPzayOvaiG2OiG3qoYmx+FRZ4LDhU6aomN9sdeVIvZBMHBFkrLf7thLi7TiAprMDyRYSaKy7xv3AL8BTdfEsH731ewJ9v7oWBFxXVEN+qJjI601A/xbZwmJtJKUbETkwmCAk2UVejnVu4eb7h7/2Fy7bV0jfNj9/72F1WzF9U2ucb+2JtcY/0+BHhe4zJn8/vjvg/eEG2zYS9sWNiysLCwfsGcI4SFNQz/Pv3001n42mv1x2755ZeGY4uKGDhgQLuaseHB5JU2RL0LSiuIC/McQh4XHsKA5DisZjOJUeF0i4ngQGEJ/ZPiuHrScK6eNByAO5d8RbfoCLwh2haF3d44r0X1i/S0lNczT5vMf15/06vfbovwqFiKi/Lqv5c48gmPim01fdroM/m/hZ6BjY2rvjiqqRIAkbYYigobRkw4igqIssXUfz9cXcXB/b8yd7a+1kZpsYMnHryD2+Y8xu6sbaxd9QNL3niBqsoKhBBY/fw4/c8XtKmpVZZhDWm4H6aQcGRF8x5CAEvqYA4v+7D5/1MG4dyTydE8+RaVOImOalxvrc3rbUkdMVF+jeqtueV6W1BLYrw/u/ZV0x6FxXXEtKdbXEd0lD5CqqluXb1utW4vvNR1lLiwRTT0zkWFmykq9bS3jlIn0REWHKUuXTfARHmlfk3fXNowgufBGQnk2r2zkXZHLTFN2gK7o6aFNH7YHbqdCgky17cFMVF+zL2jD488t5ucfO8WrXOUadga9URGhZkpLvWuLSguc9G3R8P5RoWZ2b7XO92YyHCPHur8omJiIj1H5USENtitKaeM5tklS+u/X3HuGVxxrr5A7pznXqdbQut1vjGdUW8BQiPiKHM02Kny4nxCI+JaTd9v+Nl8sfg+r/LUGkfK6BFs7vLqkabESXRk83I8bmgIG7dX49L06QM799bQK8nfqwfCzrq3jlKnx+gDW0Tzsuwo1et2fX4DTZS7e9P/+3HDOT9wYxy5hd75WGVVDdMfAMKCoLy6+QNmjzjB2JNMvPmdC1cj8+tngb9PMPPDFo1D7Q9WBKCkXBIZ2lBvI0NNlJR7Z9N7drWQkmhhwhB/AqwCs1lQUyv58EcvbGMnlqk8R8MovoLiUmKblKm4yHD690rCajHTNSaK5LhoDuQX0q9nEhXVh5k5/3VuOP90Bvbu1q7eEbSyYkyNRi6YwiJxlXn2svunjaV80dMAOLN/rV9wWVZ6N4KgKZ3nw3n6q/Z2/NUzTzuVV19742iz14wYWxT2woaCby8qIsbmOVokPKxhWvXZp07i5TcXA7BtRxZbtu1g6RffUF19GKfTSWBAANdeevHvPi+FoqNpL9zXXUr5hpQyW0r5FHCOlHIXcDlw3m8V3bGrnMSEABJi/bFYBJPGxbBinecw8xXrijjjFN0hmTgmhg1bvF+RtyX25tQRZzMTHWHCbIb0/gFs3Omdc2g2w4yLwlm1+XD9Gye8JWtfNV3j/ImLtmIxC8aPCGftZk9DvHZzOZNGu9dDGBrOlh363LmwEDMmdzseH22lS6wfeYXeOe87dpWR1CWQhLgALBbB5PGxrFzn2ZqvXFvEmZMaX2O9IVm5rojJ42OxWgQJcQEkdQlk+y7vVm1PTU0lJyeHvLw86urq+HH5ckaO9FwwzOFouNdr1q4lKUlfKHHo0KFs2LCB8vJyysvL2bBhA0OHtr/Kdr/EOA4UlpDtKKXO6eLLzVlMOMlzUbNT+vck41d9pf3iymr220tIjArDpWmUVOqORlZuIVm5hYxKTW6m0RJ9UlM4lJNLbl4+dXV1LFu+glHpIzzSFDXK6+q1P5OclNj0Z46a5F79Kcw7QFFBNk5nHRtXfUH/oZ6rTttzG+Ykbtu4nJiEhjxpmsamNV+RdpRBhl4pfcnLOUhBXg7OujpWL/+WoSPG1e8PCg7hlSVf8uzCD3l24Yf07tOP2+Y8Rs+Uvtz76IL6/59xzkVMueBSrx5UtPyDmCKiEWGRYDJjSR2Mc2/zHmtTZIw+NzSv+VxMa+pgnEcxVQIga28VXRrX2/Rw1mzyrANrN5UxebTuzIwdFs6WHbqTFBbaqN7GWOkS50+u3bsgna7rV687IT2CNRs9dddsKmPyWN1ejBsezubtum64h67fUenuPlhDQoyV2CgLFjOMSQsmY6vn0OKMzComjNAdv5GDgsncrdcbP6vA308XHpgagEvDY1G0tti5u4LEhADi3W3BKWOiWfWzp0O7KsPBGRP1h+IJo2xsyNSDTCFBZh6Z/SdeWXyAzJ3eO7e/ZtcSH20hJtKM2QwjBwWxfrt3b8PYknWYASn+BAUIggIEA1L82ZLl3bEn9erGgTw7hwoKqXM6+Wb1BsYP9ZxTW9hoOPTy9b/Qo6s+3cClaZSU6/d51/5D7DqQQ/pA7xZs7Yx6C9Cl+wAcBfsoth/E5axl68+fkTroFI80jvx99du7fllGVKz3D0MtsftAk3I8JJifMz3nomdkVjFxhO7AjxoUTOYuvRwXFjvp755L7+8nSOnuT06Bd+W4s+7tnoPushxlwWyG0YODydjq+eCcsbWKCcPc9XZgEFvd66c0rrcDUgLQNDwWjGyLHAdEhQoigvXFW/slm8jK9gwyxEfCWcNN/G+5i6pGbpPJBBeOM7Fln8b2g973fO/LdRIbZcIWbsJsgmEn+bF5t3fn+9onldz1Uil3v1TKez9UsSazxqsAA3RemerXI5GD+UUcsjuoczr5au1mJqR5LvQ3cUg/1u/Q1y4oLq/kQH4hXWOjqHM6ufXZ/3L26CFMHn508/adOfsw2+IwRUSD2Yx//xHU7dzskUYrdWDtqZ+LOToBYbH+5gADdLIPdyiH3Hp/9SdGpad7pPH04dZ1iA/XJ6UX2bl55OYXUFfn5PufVjF6hOfbNIocDe3gqnUZJCfqC2nOuXUG7y58kf/953mmXz6N004erwIMPkRq8g/56SzaG8lQKYQYK6VcIYQ4B3AASCk1cWSFpt+AS4P5r+zhyfv6Y3K/tmzfwSquvLgbO3aXs3Kdg8++yWPOzX14e8Ewysqd3PfEjvrj331lOMFBZiwWE+PSbdx6X6bHWxNaQtNg0efl3PaPSEwCftp4mBy7i3NPDmZvjpNNO2vo0cXCTX+PIDjAxOBUf86dqHH3i0WM6BdAajc/QoJMjB2sLzrz6tIyDuS1H43WNHhpSQ5zZ3XHZBJ8s7KYAzk1TJsSy6591azdXM7XPxVz21WJ/OfhFMorXTzmfrNE/9Rgpk2JxeWSaBJeWJRDRaV3PW4uDZ5asJun7h+gX+Nv89h7oIorL+nOjl3lrFxXxKff5PLvW/ryzssjKKuo477H9MWm9h6o4vsVdha9OByXS/LUgt1edwKbzWamT5/OnDlzcGkap512Gt26deO/b71FakoKI0eO5KOPPmLN2rWYzWZCQ0O59ZZbAAgNDWXq1KnMnDULgIunTm33zRIAFrOJu6ZMYPqrH6NpGn8dfhK942288NUa+iXGMrFfT0anJrMq6wDnPrEIk8nEzWePISI4kJo6J5e/9D4AwQF+PDz1NCxm74bamc1mbrzuau665340zcXpp06me7dk3li0hNSU3oxOH8HSjz9j9bp1mE1mQkNDuH3WjPrjb77jLg5mH6L68GGmXnolt8y4keFD07zQtXD+5bNZ8PC1aJqL9JPPJSGpN5+/+zzJPfvRf9jJ/PTVErIy12AyWwgKDuPi6Q1TJfZszyDCFk90XFIbKi3rXnbdrcy7dxaapjFx8p9J7NaT/1v0Cj1T+jI0fVz7P3K0SI3DPy4l6JyrwaS/wlJz5OOXfhqugmxc7oCDJWUwdbuaBxJEaCQiJALXoV+b7WsLTYOXFuXw4C099FfPrnDX27+66+2mcr5aXsxtVyfx6iOplFe6ePRl/Q0PA1KDmfbXOJwuiZTw/H8PeV1v63Vv64nZ/crbAzk1/OPcOLL2VrN2UxlfLXdw+zVJLHy0D+WVrvo3S/TvE8w/zo3XdTV4/s3so9Jd+H4Rd18bj8kEP6wtJzuvjovOiGDPwVoytlbx/doKbrokhudmJ1JRpTH/Lb13PDzEzJzr4tCk3mv63GLv56y6NHjm1b08PqcvJpPgi+8L2JddzeUXJbFzTwWrMor5/LsCZs9IYfFzaZRVOHlgvv6GkHPPjKdrfACX/i2RS/+mO363zd1GSVnbdlnT4I2PS/jXFdGYBPyYUcmhAifnTw5l76E6Nmw/TM9EKzdPsxEUKEjrG8j5k1386+kCKqslS78vZ+6Nek/zh9+XU9lCD25LWMxm7rjsQmY88gIuTXLOxJH0Skpgwf99St8eyUwYNpB3vlzG8vW/YDGbCQsJ4t7rpgHgdLq45n695zA4MIAHbrgUi9m7tSA6pd4CJrOFMy6+h7efvgpNuhg85nxiuqaw7KNn6NKtP6mDJ/HzD4vYu201ZrOFgOAwzrm8YarEc3eeQk11BS5XHTs3fsvFN7/m8WaKltA0ePX9QuZMj8dkEny/xl2Oz4xkz8EaMjKr+G5NOTOmxfDcnCQqqlzMf1Mvx1/+VMYNF8cw/85EEHod2J/jXZCus+6tpsFrHzqYfXUsJgHLfq4gO7+OC04P59eDtazfVs0P6yq4cWo0z9zZhYoqjWcW6T234SEmZl8dh5R6b/3zbxe2o9aAlPBlhsbFE80IAZt/1bCXwYQBJnIdkqxDkkmDTfhZ4fyxel7KKiX/+0mjX7IgOVYQ6C8Y5H6O/HiNi/x2+pE0Ce98XcXMi0IxCVi5pYbcQhd/GRfI/lwnW3bX0S3ezPTzQgkKEAzsbeUvYzXuX+hdB0mrup1Ypv41bQo3PLEQTdM4Z9xwenWN56UPvuakHolMSDuJ0QNSWbM1i/NnP4nZZGLWhWcRERLMZ6s2sDFrL6UVVXyyQl88+/6rLqRPty5eZbjy8yWE/WMWCBM1G1fisucQePIUnDn7qNu5maqv3yX4L5cSMPJUQFKx9LX6wyNmzUP4ByLMZqx/Gkz5W/M93kzRcl470Yebfi2z/30fmqbV+3BvvrWY1JTejBqZztKPP2HN2nW6vxoSym03z6o//pY77uTgwWyqDx/m4n9ezi0zb2LY0CHt6lrMZmZecwW33/ew/vrzSRPpkZzEa4vfpU/vnoxJH8b7n37BqnXrMZtNhIaEcOfM69v9XYXiWEM0XT3bY6cQg4D/ACnAVuBKKeVOIUQMMFVK+Wx7Ai1NlzCaXmnevyO3I7Fn//4FYX4LpflejjfsYP779O+P6P4WumR+0X6iDqbgpEntJzKArRVtO9VGERv823slfg+pXz3ic82LNv7T55pAp0WXQyLbD9wZgf1gXvuJOpiuKd71aHU0L13QOetD7Appf+SXEWzL825RuY7ko/ePLnDYUbx26dG/UrojuHpJ5/g1/Yd6/yrCjiJ7/+8LDPxWinJ/34jZ38qbf/fuTSQdzeGvPvW5ZnDa4PYTGUB+v1M7RdfP6d2IGSNI+FOnXOvf3AH9R2DCeas6b1jA7+DHD0Z3yn1pcySDlHKzEOJSoCuwRkpZ4f6/XQjh3QvnFQqFQqFQKBQKhUKh+IMi5R974X1f0+aYIiHEDPSFH28EMoUQUxrtfrjloxQKhUKhUCgUCoVCoVCciLS3JsPVwDApZYUQojvwnhCiu5TyGY7zITEKhUKhUCgUCoVCoVAojo72ggymRlMk9gkhJqIHGrqhggwKhUKhUCgUCoVCoVAoGtFekCFfCDFYSrkJwD2i4c/Aa8AAw89OoVAoFAqFQqFQKBSKTqQzXwf5R6S997z8E/BYElxK6ZRS/hMYb9hZKRQKhUKhUCgUCoVCofjD0d7bJbLb2Ley409HoVAoFAqFQqFQKBQKxR+V9kYyKBQKhUKhUCgUCoVCoVB4RXtrMigUCoVCoVAoFAqFQnHCIjWts0/hD4UayaBQKBQKhUKhUCgUCoWiQ1BBBoVCoVAoFAqFQqFQKBQdg5TymP0A1yjd409T6R6/mkr3+NVUusevptI9vnVPpLyeaLonUl5PNN0TKa/qc3x+jvWRDNco3eNSU+kev5pK9/jVVLrHr6bSPb51T6S8nmi6J1JeTzTdEymviuOQYz3IoFAoFAqFQqFQKBQKheIPggoyKBQKhUKhUCgUCoVCoegQjvUgwytK97jUVLrHr6bSPX41le7xq6l0j2/dEymvJ5ruiZTXE033RMqr4jhESCk7+xwUCoVCoVAoFAqFQqFQHAcc6yMZFAqFQqFQKBQKhUKhUPxBOGaDDEKIM4QQO4UQu4UQd/pI8zUhRIEQItMXem7NJCHED0KIbUKIrUKImT7SDRBCrBNCbHbr3u8LXbe2WQixUQjxqa803br7hBC/CCE2CSEyfKQZIYR4TwixQwixXQgxygeafdx5PPIpE0LMMlrXrX2zuzxlCiHeFkIE+EBzpltvq5H5bMk+CCGihBDfCCF2uf9G+kj3And+NSHEsI7WbEP3cXdZ3iKE+FAIEeEj3bluzU1CiK+FEF18odto361CCCmEiDZaUwhxnxDiUKP6e1ZHaram6/7/Te77u1UI8ZgvdIUQ/2uU131CiE0+0h0shFhzpD0QQozwgeYgIcRqdzv0iRAirCM13Rot+hRG2qo2NA21U23oGmqn2tA11E61pttof4fbqTbyaqidaiuvRtqpNvJrqJ1qQ9cwO9WGpuF2SnGC0Nnv0GzpA5iBPUBPwA/YDJzkA93xwBAg04d5TQCGuLdDgSwf5VUAIe5tK7AWGOmjPN8CLAE+9XG52gdE+1jzTeAq97YfEOFjfTOQB3TzgVZXYC8Q6P7+LnCZwZr9gUwgCLAA3wK9DdJqZh+Ax4A73dt3Ao/6SLcv0AdYBgzzYX5PAyzu7Ud9mN+wRtszgAW+0HX/Pwn4Ctjf0fajlbzeB9xmxD1tR/dkd/3xd3+P9dU1brT/SeAeH+X3a+BM9/ZZwDIfaP4MTHBvXwHMNSCvLfoURtqqNjQNtVNt6Bpqp9rQNdROtabr/m6InWojr4baqTZ0DbVTbV3jRmk63E61kV/D7FQbmobbKfU5MT7H6kiGEcBuKeWvUspa4B1gitGiUsrlgMNonSaauVLKDe7tcmA7+sOa0bpSSlnh/mp1fwxfoEMIkQicDbxqtFZnI4QIR3c0FwJIKWullCU+Po1JwB4p5X4f6VmAQCGEBf3BP8dgvb7AWilllZTSCfwInGeEUCv2YQp6IAn337/6QldKuV1KubOjtbzQ/dp9nQHWAIk+0i1r9DUYA2xVG/Z/PnCHjzUNpRXd6cA8KWWNO02Bj3QBEEII4ELgbR/pSuBID104HWyrWtFMBZa7t78Bzu9ITbduaz6FYbaqNU2j7VQbuobaqTZ0DbVT7fiLhtipTvRRW9M11E61l1+j7FQbuobZqTY0DbdTihODYzXI0BU42Oh7Nj4wap2NEKI7kIY+qsAXemb3kK8C4BsppS90n0ZvCDUfaDVFAl8LIdYLIa7xgV4PwA68LvTpIa8KIYJ9oNuYv2OA094SUspDwBPAASAXKJVSfm2wbCYwTghhE0IEoUf6kwzWbEyclDLXvZ0HxPlQu7O5AvjCV2JCiIeEEAeBS4B7fKQ5BTgkpdzsC71G3Ogedv1aRw5rb4dU9Lq0VgjxoxBiuI90jzAOyJdS7vKR3izgcXeZegK4yweaW2noMLkAg21VE5/CJ7bK136MF7qG2qmmur6yU411fWWnWrjGPrFTTXR9ZqdaKVOG26kmuj6xU000fWqnFMcvx2qQ4YRDCBECvA/MahINNwwppUtKORg9yj9CCNHfSD0hxJ+BAinleiN12mCslHIIcCZwgxBivMF6FvThsi9JKdOASvRhqj5BCOEHnAP8n4/0ItEbph5AFyBYCDHNSE0p5Xb04bBfA18CmwCXkZptnIvEB6OBjgWEEHcDTmCxrzSllHdLKZPcmjcarecOWs3GRwGNRrwE9AIGowfrnvSRrgWIAkYCtwPvunvtfMVUfBQQdTMduNldpm7GPeLMYK4ArhdCrEcfnlxrlFBbPoVRtqoz/Ji2dI22Uy3p+sJONdZFz5/hdqqFvPrETrWg6xM71UZZNtROtaBruJ1qQdNndkpxfHOsBhkO4Rk5S3T/77hECGFFr+CLpZQf+FrfPYT/B+AMg6XGAOcIIfahT4E5RQixyGDNetw97UeG132IPi3HSLKB7EYjRN5DDzr4ijOBDVLKfB/pTQb2SintUso64ANgtNGiUsqFUsqhUsrxQDH6vEJfkS+ESABw/+3wIebHGkKIy4A/A5e4H1Z8zWJ8M3yzF3rAbLPbZiUCG4QQ8UaKSinz3QFgDfgPxtupI2QDH7in0q1DH23WoQtdtoZ7etV5wP98oefmUnQbBXog1vDrLKXcIaU8TUo5FP1BZY8ROq34FIbaqs7yY1rTNdpOeZFfQ+xUC7qG26mW8uoLO9XKNTbcTrVRpgy1U63oGmqnWrm3PrFTiuOfYzXI8DOQIoTo4e6N/TvwcSefkyG4I7ALge1Syqd8qBsj3CsuCyECgVOBHUZqSinvklImSim7o9/T76WUhvZ0H0EIESyECD2yjb4wlKFvEZFS5gEHhRB93P+aBGwzUrMJvu4ZPACMFEIEucv1JPQ5foYihIh1/01GdwCWGK3ZiI/RnQDcfz/yobbPEUKcgT7d6RwpZZUPdVMafZ2CwbYKQEr5i5QyVkrZ3W2zstEXycozUvfIg6CbczHYTjViKfqiagghUtEXqi30kfZkYIeUMttHeqDPbZ7g3j4FMHyaRiNbZQLmAAsM0GjNpzDMVnWiH9OirtF2qg1dQ+1US7pG26k28mqonWqjTBlqp9opy4bZqTZ0DbNTbdxbw+2U4gRBHgOrT7b0QZ9bnYUeQbvbR5pvow/7qkM31Ff6QHMs+rDFLehDvTcBZ/lAdyCw0a2biQErerejPxEfvl0C/U0lm92frT4sU4OBDPd1XgpE+kg3GCgCwn18X+9Hd6wygbdwrwBtsOZP6MGbzcAkA3Wa2QfABnyH3vB/C0T5SPdc93YNkA985SPd3ejr5RyxVUa85aEl3ffdZWoL8An6ImuG6zbZv4+Of7tES3l9C/jFndePgQQfXWM/YJH7Om8ATvHVNQbeAK7raL128jsWWO+2G2uBoT7QnInu12QB8wBhQF5b9CmMtFVtaBpqp9rQNdROtaFrqJ1qTbdJmg61U23k1VA71YauoXaqrWtspJ1qI7+G2ak2NA23U+pzYnyElCfEFGKFQqFQKBQKhUKhUCgUBnOsTpdQKBQKhUKhUCgUCoVC8QdDBRkUCoVCoVAoFAqFQqFQdAgqyKBQKBQKhUKhUCgUCoWiQ1BBBoVCoVAoFAqFQqFQKBQdggoyKBQKhUKhUCgUCoVCoegQVJBBoVAoFAqFQqFQKBQKRYegggwKhUKhUCgUCoVCoVAoOgQVZFAoFAqFQqFQKBQKhULRIfw/x3YNH6akQPwAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2p0kgfS-ao5o" + }, + "source": [ + "Como podemos ver, há várias colunas altamente correlacionados no dataframe. Vamos excluir (automaticamente!) as colunas altamente correlacionadas da seguinte forma:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C7mUtTlFaoFx", + "outputId": "cb4734a6-f56a-48f0-9b23-cc478f88e9e8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 955 + } + }, + "source": [ + "set_variaveis_corr = set()\n", + "matrix_corr = X_cancer.corr()\n", + "matrix_corr" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01234567891011121314151617181920212223242526272829
01.0000000.3237820.9978550.9873570.1705810.5061240.6767640.8225290.147741-0.3116310.679090-0.0973170.6741720.735864-0.2226000.2060000.1942040.376169-0.104321-0.0426410.9695390.2970080.9651370.9410820.1196160.4134630.5269110.7442140.1639530.007066
10.3237821.0000000.3295330.321086-0.0233890.2367020.3024180.2934640.071401-0.0764370.2758690.3863580.2816730.2598450.0066140.1919750.1432930.1638510.0091270.0544580.3525730.9120450.3580400.3435460.0775030.2778300.3010250.2953160.1050080.119205
20.9978550.3295331.0000000.9865070.2072780.5569360.7161360.8509770.183027-0.2614770.691765-0.0867610.6931350.744983-0.2026940.2507440.2280820.407217-0.081629-0.0055230.9694760.3030380.9703870.9415500.1505490.4557740.5638790.7712410.1891150.051019
30.9873570.3210860.9865071.0000000.1770280.4985020.6859830.8232690.151293-0.2831100.732562-0.0662800.7266280.800086-0.1667770.2125830.2076600.372320-0.072497-0.0198870.9627460.2874890.9591200.9592130.1235230.3904100.5126060.7220170.1435700.003738
40.170581-0.0233890.2072780.1770281.0000000.6591230.5219840.5536950.5577750.5847920.3014670.0684060.2960920.2465520.3323750.3189430.2483960.3806760.2007740.2836070.2131200.0360720.2388530.2067180.8053240.4724680.4349260.5030530.3943090.499316
50.5061240.2367020.5569360.4985020.6591231.0000000.8831210.8311350.6026410.5653690.4974730.0462050.5489050.4556530.1352990.7387220.5705170.6422620.2299770.5073180.5353150.2481330.5902100.5096040.5655410.8658090.8162750.8155730.5102230.687382
60.6767640.3024180.7161360.6859830.5219840.8831211.0000000.9213910.5006670.3367830.6319250.0762180.6603910.6174270.0985640.6702790.6912700.6832600.1780090.4493010.6882360.2998790.7295650.6759870.4488220.7549680.8841030.8613230.4094640.514930
70.8225290.2934640.8509770.8232690.5536950.8311350.9213911.0000000.4624970.1669170.6980500.0214800.7106500.6902990.0276530.4904240.4391670.6156340.0953510.2575840.8303180.2927520.8559230.8096300.4527530.6674540.7523990.9101550.3757440.368661
80.1477410.0714010.1830270.1512930.5577750.6026410.5006670.4624971.0000000.4799210.3033790.1280530.3138930.2239700.1873210.4216590.3426270.3932980.4491370.3317860.1857280.0906510.2191690.1771930.4266750.4732000.4337210.4302970.6998260.438413
9-0.311631-0.076437-0.261477-0.2831100.5847920.5653690.3367830.1669170.4799211.0000000.0001110.1641740.039830-0.0901700.4019640.5598370.4466300.3411980.3450070.688132-0.253691-0.051269-0.205151-0.2318540.5049420.4587980.3462340.1753250.3340190.767297
100.6790900.2758690.6917650.7325620.3014670.4974730.6319250.6980500.3033790.0001111.0000000.2132470.9727940.9518300.1645140.3560650.3323580.5133460.2405670.2277540.7150650.1947990.7196840.7515480.1419190.2871030.3805850.5310620.0945430.049559
11-0.0973170.386358-0.086761-0.0662800.0684060.0462050.0762180.0214800.1280530.1641740.2132471.0000000.2231710.1115670.3972430.2317000.1949980.2302830.4116210.279723-0.1116900.409003-0.102242-0.083195-0.073658-0.092439-0.068956-0.119638-0.128215-0.045655
120.6741720.2816730.6931350.7266280.2960920.5489050.6603910.7106500.3138930.0398300.9727940.2231711.0000000.9376550.1510750.4163220.3624820.5562640.2664870.2441430.6972010.2003710.7210310.7307130.1300540.3419190.4188990.5548970.1099300.085433
130.7358640.2598450.7449830.8000860.2465520.4556530.6174270.6902990.223970-0.0901700.9518300.1115670.9376551.0000000.0751500.2848400.2708950.4157300.1341090.1270710.7573730.1964970.7612130.8114080.1253890.2832570.3851000.5381660.0741260.017539
14-0.2226000.006614-0.202694-0.1667770.3323750.1352990.0985640.0276530.1873210.4019640.1645140.3972430.1510750.0751501.0000000.3366960.2686850.3284290.4135060.427374-0.230691-0.074743-0.217304-0.1821950.314457-0.055558-0.058298-0.102007-0.1073420.101480
150.2060000.1919750.2507440.2125830.3189430.7387220.6702790.4904240.4216590.5598370.3560650.2317000.4163220.2848400.3366961.0000000.8012680.7440830.3947130.8032690.2046070.1430030.2605160.1993710.2273940.6787800.6391470.4832080.2778780.590973
160.1942040.1432930.2280820.2076600.2483960.5705170.6912700.4391670.3426270.4466300.3323580.1949980.3624820.2708950.2686850.8012681.0000000.7718040.3094290.7273720.1869040.1002410.2266800.1883530.1684810.4848580.6625640.4404720.1977880.439329
170.3761690.1638510.4072170.3723200.3806760.6422620.6832600.6156340.3932980.3411980.5133460.2302830.5562640.4157300.3284290.7440830.7718041.0000000.3127800.6110440.3581270.0867410.3949990.3422710.2153510.4528880.5495920.6024500.1431160.310655
18-0.1043210.009127-0.081629-0.0724970.2007740.2299770.1780090.0953510.4491370.3450070.2405670.4116210.2664870.1341090.4135060.3947130.3094290.3127801.0000000.369078-0.128121-0.077473-0.103753-0.110343-0.0126620.0602550.037119-0.0304130.3894020.078079
19-0.0426410.054458-0.005523-0.0198870.2836070.5073180.4493010.2575840.3317860.6881320.2277540.2797230.2441430.1270710.4273740.8032690.7273720.6110440.3690781.000000-0.037488-0.003195-0.001000-0.0227360.1705680.3901590.3799750.2152040.1110940.591328
200.9695390.3525730.9694760.9627460.2131200.5353150.6882360.8303180.185728-0.2536910.715065-0.1116900.6972010.757373-0.2306910.2046070.1869040.358127-0.128121-0.0374881.0000000.3599210.9937080.9840150.2165740.4758200.5739750.7874240.2435290.093492
210.2970080.9120450.3030380.2874890.0360720.2481330.2998790.2927520.090651-0.0512690.1947990.4090030.2003710.196497-0.0747430.1430030.1002410.086741-0.077473-0.0031950.3599211.0000000.3650980.3458420.2254290.3608320.3683660.3597550.2330270.219122
220.9651370.3580400.9703870.9591200.2388530.5902100.7295650.8559230.219169-0.2051510.719684-0.1022420.7210310.761213-0.2173040.2605160.2266800.394999-0.103753-0.0010000.9937080.3650981.0000000.9775780.2367750.5294080.6183440.8163220.2694930.138957
230.9410820.3435460.9415500.9592130.2067180.5096040.6759870.8096300.177193-0.2318540.751548-0.0831950.7307130.811408-0.1821950.1993710.1883530.342271-0.110343-0.0227360.9840150.3458420.9775781.0000000.2091450.4382960.5433310.7474190.2091460.079647
240.1196160.0775030.1505490.1235230.8053240.5655410.4488220.4527530.4266750.5049420.141919-0.0736580.1300540.1253890.3144570.2273940.1684810.215351-0.0126620.1705680.2165740.2254290.2367750.2091451.0000000.5681870.5185230.5476910.4938380.617624
250.4134630.2778300.4557740.3904100.4724680.8658090.7549680.6674540.4732000.4587980.287103-0.0924390.3419190.283257-0.0555580.6787800.4848580.4528880.0602550.3901590.4758200.3608320.5294080.4382960.5681871.0000000.8922610.8010800.6144410.810455
260.5269110.3010250.5638790.5126060.4349260.8162750.8841030.7523990.4337210.3462340.380585-0.0689560.4188990.385100-0.0582980.6391470.6625640.5495920.0371190.3799750.5739750.3683660.6183440.5433310.5185230.8922611.0000000.8554340.5325200.686511
270.7442140.2953160.7712410.7220170.5030530.8155730.8613230.9101550.4302970.1753250.531062-0.1196380.5548970.538166-0.1020070.4832080.4404720.602450-0.0304130.2152040.7874240.3597550.8163220.7474190.5476910.8010800.8554341.0000000.5025280.511114
280.1639530.1050080.1891150.1435700.3943090.5102230.4094640.3757440.6998260.3340190.094543-0.1282150.1099300.074126-0.1073420.2778780.1977880.1431160.3894020.1110940.2435290.2330270.2694930.2091460.4938380.6144410.5325200.5025281.0000000.537848
290.0070660.1192050.0510190.0037380.4993160.6873820.5149300.3686610.4384130.7672970.049559-0.0456550.0854330.0175390.1014800.5909730.4393290.3106550.0780790.5913280.0934920.2191220.1389570.0796470.6176240.8104550.6865110.5111140.5378481.000000
\n", + "
" + ], + "text/plain": [ + " 0 1 2 ... 27 28 29\n", + "0 1.000000 0.323782 0.997855 ... 0.744214 0.163953 0.007066\n", + "1 0.323782 1.000000 0.329533 ... 0.295316 0.105008 0.119205\n", + "2 0.997855 0.329533 1.000000 ... 0.771241 0.189115 0.051019\n", + "3 0.987357 0.321086 0.986507 ... 0.722017 0.143570 0.003738\n", + "4 0.170581 -0.023389 0.207278 ... 0.503053 0.394309 0.499316\n", + "5 0.506124 0.236702 0.556936 ... 0.815573 0.510223 0.687382\n", + "6 0.676764 0.302418 0.716136 ... 0.861323 0.409464 0.514930\n", + "7 0.822529 0.293464 0.850977 ... 0.910155 0.375744 0.368661\n", + "8 0.147741 0.071401 0.183027 ... 0.430297 0.699826 0.438413\n", + "9 -0.311631 -0.076437 -0.261477 ... 0.175325 0.334019 0.767297\n", + "10 0.679090 0.275869 0.691765 ... 0.531062 0.094543 0.049559\n", + "11 -0.097317 0.386358 -0.086761 ... -0.119638 -0.128215 -0.045655\n", + "12 0.674172 0.281673 0.693135 ... 0.554897 0.109930 0.085433\n", + "13 0.735864 0.259845 0.744983 ... 0.538166 0.074126 0.017539\n", + "14 -0.222600 0.006614 -0.202694 ... -0.102007 -0.107342 0.101480\n", + "15 0.206000 0.191975 0.250744 ... 0.483208 0.277878 0.590973\n", + "16 0.194204 0.143293 0.228082 ... 0.440472 0.197788 0.439329\n", + "17 0.376169 0.163851 0.407217 ... 0.602450 0.143116 0.310655\n", + "18 -0.104321 0.009127 -0.081629 ... -0.030413 0.389402 0.078079\n", + "19 -0.042641 0.054458 -0.005523 ... 0.215204 0.111094 0.591328\n", + "20 0.969539 0.352573 0.969476 ... 0.787424 0.243529 0.093492\n", + "21 0.297008 0.912045 0.303038 ... 0.359755 0.233027 0.219122\n", + "22 0.965137 0.358040 0.970387 ... 0.816322 0.269493 0.138957\n", + "23 0.941082 0.343546 0.941550 ... 0.747419 0.209146 0.079647\n", + "24 0.119616 0.077503 0.150549 ... 0.547691 0.493838 0.617624\n", + "25 0.413463 0.277830 0.455774 ... 0.801080 0.614441 0.810455\n", + "26 0.526911 0.301025 0.563879 ... 0.855434 0.532520 0.686511\n", + "27 0.744214 0.295316 0.771241 ... 1.000000 0.502528 0.511114\n", + "28 0.163953 0.105008 0.189115 ... 0.502528 1.000000 0.537848\n", + "29 0.007066 0.119205 0.051019 ... 0.511114 0.537848 1.000000\n", + "\n", + "[30 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 240 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9lvLldX5eWVW", + "outputId": "3a8f8ccb-e59e-408e-cd99-1f7439029321", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "for i in range(len(matrix_corr.columns)):\n", + " for j in range(i):\n", + " if abs(matrix_corr.iloc[i, j]) > 0.8:\n", + " colname = matrix_corr.columns[i]\n", + " set_variaveis_corr.add(colname)\n", + "\n", + "set_variaveis_corr" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{2, 3, 6, 7, 12, 13, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 241 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R4YC3Kl5erhc" + }, + "source": [ + "Deletando as colunas altamente correlacionadas do dataframe e calculando a correlação novamente:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "psDDQlrSevG5", + "outputId": "a2aea1b6-1826-4147-d8a5-0ccd7c95bc47", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 989 + } + }, + "source": [ + "X_cancer = X_cancer.drop(set_variaveis_corr, axis = 1)\n", + "\n", + "fig, ax = plt.subplots(figsize = (20, 17)) \n", + "mask = np.zeros_like(X_cancer.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(X_cancer.corr().abs(), mask = mask, ax = ax, cmap='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 242 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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IiIiIiIiIh6hJIOIiIiIiIiIeITmZBAREREREREphe5gWTaqZBARERERERERj1CSQUREREREREQ8QkkGEREREREREfEIzckgIiIiIiIiUgrL1KQMZaFKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBSm7mFZJqpkEBERERERERGPUJJBRERERERERDxCSQYRERERERER8QjNySAiIiIiIiJSCt3CsmzKPcnw5pfh5f0WPmXzihXeDqHSCQ+9xNshVDoh/b7ydgiVyjW587wdQqWTHRbp7RAqnVkRD3o7hErlsjBdb05ToA+Jp6qxYYa3Q6hU9rhq8/umPG+HUelc3CTE2yGIiA/RcAkRERERERER8QglGURERERERETEIzQng4iIiIiIiEgpNCdD2aiSQUREREREREQ8QkkGEREREREREfEIDZcQERERERERKYVGS5SNKhlERERERERExCOUZBARERERERERj1CSQUREREREREQ8QnMyiIiIiIiIiJRCt7AsG1UyiIiIiIiIiIhHKMkgIiIiIiIiIh6h4RIiIiIiIiIipbAsDZcoC1UyiIiIiIiIiIhHKMkgIiIiIiIi8i9kGMZlhmFsMQwjyTCMZ/6ivZNhGKsMwyg0DOOGv/OaSjKIiIiIiIiI/MsYhmEHxgC9gabALYZhND2l2x7gTuCzv/u6mpNBREREREREpBTmuXsLyzZAkmVZOwAMw5gGXA1s/L8OlmXtOtFm/t0XVSWDiIiIiIiIyL9PTWDvScv7Tjz3jyjJICIiIiIiInKOMQxjgGEYK0/6N6Ai3lfDJURERERERETOMZZljQfGn6HLfiDupOVaJ577R5RkEBERERERESmFZZ2zczIkAgmGYdSlKLlwM9Dvn76ohkuIiIiIiIiI/MtYllUIDAIWAJuALyzL2mAYxquGYVwFYBhGa8Mw9gE3Ah8ahrHhbK+rSgYRERERERGRfyHLsuYB8055bshJjxMpGkbxtynJICIiIiIiIlIK69y9hWW50HAJEREREREREfEIJRlERERERERExCOUZBARERERERERj9CcDCIiIiIiIiKl0JwMZaNKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBSmpeESZXFOJBma1fWjb/cAbDZYvPYYC5blu7UnxDno2y2AmlF2Js4+xKotBcVt7ZpX4fJLqgEwb+lRlq0/XqGxl5c2F4by0N11sdlg7o/pfDZrv1u7n8PguUcSaFgvkLyDhbzyzlZSDxwjJMjBq082olGDIL5bmM6oiTu9tAWetWvTIhZ9NRTLMmnW7kZadR/g1r5q4RQ2LPsSm81OtaBwut/yBiHhNQHYtGIWK74fC0CbngNp0ubaCo+/PGxfv4gF04ZimSYtOt5I+97u+2TZ91NYs7honwQEh3PFnW8Q6qxJTuZ+ZnwwCMs0cbkKad31Ni7qcouXtsKzlq7dxNufzMI0La7p0pY7r+r+l/1+WrGWp9/7iP+9+hhN68WTfCCLG596k9oxkQA0b1Cb5+7uW5Ghl4vVK5czefz7mKZJt559uK7vrW7tC+bN5rs5s7DZ7PhXq8b9Dz1BXHwd0tNSeOT+24mtGQ9Aw8ZNuW/Q497YBI/b9udvfPfZUEzLpGXHG+jYx/28WbpgCqsWzcBmtxMYHM7Vdw0lNKJmcXv+0UOMeaEPjS/sRp/bhlR0+OVi2ap1jJr0CaZpckX3Lvzn+iv/st8vvyfywrD3mDj8FRo3qEdu3kFeGP4+m5N20PvSjgwecEcFR15+lq1ax6jJU0/sk87857oz7JPh7zNx2MtF++TgQV4YPrpkn9x7ewVHXj5W/LGa0ROmYJoml/foRr8b3a+j38xfwOy5C7DZbFTz92fwoPuoEx9HQUEBI8aMZ2vSdgzDYNCAu2hxXnMvbYVnrVu1lM8mvoNpmnTqcTVXXH+nW/vP383k53lfYths+FcL4M4HnqNmXD0O5eUwetgz7EzaSIeuV/CfAU95ZwNERM7A55MMhgG39Axg5LSDZB80efbOENZtO05KplncJyvP5KO5h+nR1t9t3QB/gys6VOONj/LAgufuCmHdtgKOHPPtTJXNBo/eW4/HX9nAgczjfDjsfJYkZrF739HiPn26R3PwUCG3Priaru2d3Hd7bV55ZyvHC0wmfb6HuvEB1I0P8OJWeI5puvhlxqtcO3AKQaHRTB9xA3Wbd8VZo0Fxn8haTbj58Zn4VanGusWfseSb4fS+cyT5h3NYvmA0Nw+eCYbBtHeuo27zrvgHVPfiFv1zpuli/mevcutjUwgJi2bS0BtoeEFXImNL9kmN+Cbc8/xM/KpW449fPuPnGcO57r6RBFeP5M5npuPwq8Lx/MN8+PKVNGzRleDQaC9u0T/nMk3e+ngmY565n+jwUG4f8i6dLmpOvZo13PodPprPtAWLaF6/ttvzNaOdfPbGkxUZcrlyuVxMGDuSIa+/gzMikqcfu4/W7doTF1+nuE/HLt3pdfnVACQuW8JHE8bw4mvDAYiOqck7oyd5I/RyY5ou5k19lf88PpmQ8GgmvHojjVp0JapmyXkTE9+EAUNmUKVqNRIXfs4PX77NjQPfLW5fOGsUtRu28kb45cLlMhkx/mPefflpopzh9H9qCB3atKRuXE23fkeOHuXLOQto2rB+8XNVqvjR/5br2blnHzv27Kvo0MuNy2UyYsL/ePelp07sk5fo0LqUfTL3e5omnLRP/KrQ/5br2Lln/zmzT1wuF6PGTWT4a0OIdIYzcPAzXNK2FXXi44r7dOvckat69wJgyfJExk76mLdeeYG53/8IwKTRI8jOyeWZl4cydsSb2Gy+PdrXdLn45MNhPPnKaMKd0bzy5B1c2KYTNePqFfe5uFMvul52PQCrV/zK55Pf5YmX3sevSlWu63c/+/ZsZ/+e7d7aBBGRM/Ltv9JA3RgH6dkmGbkmLhNWbjzOBQlV3Ppk5prsP+Di1CqXZnX92LSzgCP5FkeOWWzaWUCzen4VGH35aNIgiP0pR0lJO0ZhocXPizPo0CbcrU/71mEsWJgOwK+/Z9LyvKIvzfnHTP7cfJDjBeZpr+ur0navIzSiNtUj4rA7qpBwYR92/PmTW5+4hHb4VSmqaKlRpwWHclMB2L15MfEN2+MfGIp/QHXiG7Zn96bfKnwbPC155zrCI2sTFlm0T5q17sPWNe77pE7jdvhVLdonNeu1IC+7aJ/YHVVw+BWdY4WFx7Gsc+NY2bB9D3HREdSKisDP4aBnuwv59Y/1p/UbN2M+d1zRlSp+Pp+jPaOkrZuoEVuTGjGx+Pn50aFTVxKXLXbrExAQWPw4P/8ohlHRUVas/TvWER4VT3hUHA5HFZq3vZwtp5w3dZu0o8qJ86ZWvQuKzxuA5F3rOZSXSf1m7Ss07vK0adt2asVEU7NGFH5+Drp3aMfiFX+c1m/CZzO59dorqOJXco2t5u/PBU0bUaWK7193T7YpaTu1YqJO2SerTus34bOZ3HpNH7ftr+ZflQuaNHLbT75u87YkasbUILZGNH5+fnTt1J6lyxPd+gQGlPyokZ9/jP/7U7J7zz4uPL+ociEstDpBgQFsSfL9L9Y7tm0gOiaOqBq1cPj50bZDD1Yv/9WtT7WAoOLHx/LzMU78ga3qX42GTVvg5+f+WVdEpDLx+SRDaLBB9kFX8XL2QZPQ4L+3WaHBNrIPlnxBKsu6lVmEsyrpmSXDPg5kHicivEqpfVwmHD7ionrwufml6VBuGkFhJb9GB4VGczg3rdT+G5fNoHaTTgAcLuO6vuJgThoh4SXbFRwWzcGc0rdrzeIZ1G/eqXg5NyuF8S9fyXtPd+GSy+71+SoGgPTsHKLDQ4uXo8Krk56d69Zn8869pGbl0OHCZqetn3wgi37Pv82A10ezerPvfwjOyswgIiKqeDk8IpLMzIzT+s2fM4sH7rmFT6aM4+77Hil+Pj01hSceuocXn36YjevXVkjM5S0vJ42Q8Jji5ZCwGuRll37erPptBg3OKzpvTNNkwfS36Nn33CptPpCVTVRESRI70hnOgcxstz5btu8iPSOTS1q1qOjwvOJAZjZRTmfxcqQznANZf7FPMrP+FfskIzOLqIiI4uUIp5MDmVmn9ft67nxuvfdBxn/0CYPuuweA+nXrsHRFIi6Xi5TUNLZu38GBA5kVFXq5yc46QHhEyXUzzBlNdtaB0/r9OO8LnrzvGr74+D1u7f9ERYYoIqewTMsn/3nLGb9RG4bRyjCMhYZhTDUMI84wjB8Mw8g1DCPRMIwLz7DeAMMwVhqGsXLTio89H7VIOdm8cjZpe9fTsmt/b4dSafy5bDYpu9Zzca+SfVI9PIYBL3/Lg0O/Z93SWRzKO/3L57nGNE1GfDqbx/pdfVpbRGgIc0YO4bOhT/DYrVfzwgdTOXQk/y9e5dzT+4pr+WDS5/znrvuYOf1/AISFO/nwoy94+/1J3Nn/QUYOf40jRw57OdKKtfb3b0jetYH2lxV9WUpc+BkJ53emeniNs6x5bjFNk/enfMqgu/p5O5RKwzRN3v/oMwbdeW7MZeMp1/TpzacTxjDgjtuYOn0GAL17dCXS6eT+x55mzMQpNGvcyOeHSpRF98v7MvzDr7nx9of49svJ3g5HRORvO9tf6g+AYcBcYCnwoWVZ1YFnTrT9JcuyxluW1cqyrFZN2pTvRE45By3Cgu3Fy2HBNnIO/r3y7ZyDJmEnVS6UZd3KLCPzGFHOksqFSGcVMrKOl9rHboPAADu5BwsrNM6KElQ9mkMnlSwfykkjsPrpv7zv2bKUxO/HcWX/sTgcRfsm8G+u62uCQ6PJyyrZroPZaX9ZjbBj41IWzx1H30Fji4dInPo6kTUT2LttZbnGWxGiwkJJy8opXk7PyiUqrGTujSP5x9i+L5X7ho7mykdfZf323QweMYmNO/ZQxc9BaHDR0IEmdeOoGeVkT2p6hW+DJ4U7I8jIKNmGrIwDOJ0RpfZv36kbK34vGk7h51eF4JCifVc/oRE1YmqSvH9v+QZcAUJCo8nLSilezstOJSTs9PNm+4al/DZnHLc8/EHxebNv+xpW/PQp7z7Zle+/GMbapbP54ct3Kiz28hIZHkZ6Rsmv0gcys4h0hhUvHzmaz849+3johTe4YcBjbNy6naffeJfNSTu8EW6FiHSGkZ5Z8mv7gcwsIsP/Yp+8+F9uuG9w0T7578hzdp9EOMNJzyhJRGdkZhLpDC+1/6Wd2rNkWdFwCrvdzoP33sWE997m9Ree4dDhw9SqGVPqur4iLDySrIySKqjszDTCwiNL7d+2Y09WLf+lAiITEfGMsyUZ/CzLmm9Z1ueAZVnWDIoe/AT4n3nVirErpZCocBvO6jbsNmjVtAprkwrOviKwYWcBTev6EVDVIKCqQdO6fmzY+ffWrcw2Jx2iVkw1akRVxeEw6NohgiWJ7qWJSxKz6XVpUSl054udrP4z969e6pwQHX8eORm7yM3ci6vwONtWz6Ve865ufdL3beTnL4Zw5b1jCQguKXOt3bgDe7YsJv9ILvlHctmzZTG1G3eo6E3wuNg655GVvovsA0X7ZEPiXBpe4L5PUvdsZN7UIdw0aCyBISX7JC8rlYLjRb/SHz2cy95tq3BG163Q+MtD03px7E09wP70TAoKC/l+2Wo6tSwZFhEUUI2fxr3OtyOH8O3IITSvX5sRg++hab14svMO4TKLEpT70jPYm5ZBzShnaW/lExo0bEzK/n2kpaZQUFDA4kU/06qt+1wCyftLJqb7I/F3YmJrAZCbm4PLVTSMLTUlmZTkfUTXiK244MtJbN3zyEzbTfaBfRQWHmf98nk0auF+3qTs3sic/73ELQ9/QNBJ5831A95m8NsLeWz4z/Ts+xQXXHI1PW70/TtuNE6ox96UVJLT0ikoKOTHxcto37plcXtQYABz/zeWGePfZcb4d2nasD5vPfcYjRvUO8Or+rbGDeqxNyWN5LQDJ+2TkuLPoMAA5n78ATM+HMGMD0cU7ZNnHz1n90njhAbsT04hJTWNgoICfl60hIvbtHbrsy+5JHm3bOUqasYWVfzk5x/jaH7R9Wbl6rXY7Xa3CSN9Vd2EpqSl7OFA2n4KCwpYvvgHLmzTya1PavKe4sdrVy4mOia+osMUEfn/drZB+PmGYfQEqgOWYRjXWJb1tWEYnQHXWdatEKYF074/wiM3BWMzYMm6Y6RkuLiyYzV2pxSyLqmA2jXsDLwumAB/g/Mb+HFlB5NXJuVxJN9i7tKjPHtnCABzlxzlSL5v31kCiuZYGDlxB28PaYrNZjDvpzR27T3K3TfHsXn7IZYmZjPvpzSefySBT8dcyMFDhbwyYmvx+tPGtSSwmh2Hw0aHtuE88cpGtztT+Bqb3UGX64cwe1x/TNNFs7bX44xJYNm8UUTFN6de824s+WYYBceOMG9K0Zjy4LAYrrx3HP6BobTu+QDTR9wAQJteD+IfGHqmt/MJNruDy/oN4fOR/TEtFy3aX09kzQR+mT2K2NrNadiiGz/OGEZB/hFmjivaJyHOGG4aNI6M1O38+MWbRbd2sSza9bqbqFqNvLxF/5zDbufJO67noWEf4jJNrurclvq1Yhg3Yz5N6sbR+aLSb5u2avN2Ppw5H4fdjmEYPHvXDVQPCiy1vy+w2x30H/gor734BKZp0rXH5cTXrsvnn0yiQUJjWrdrz/w5X7FuzR847A4Cg4IYNPhZADauX8u0qZNx2B0YNoMBDw4mODjEy1v0z9ntDi6/7UU+GXEPlmlyYYfriaqZwM+z3iO2TnMaX9iV778YzvFjR/jig0cBqO6Mod/DY70ceflx2O0Mvvd2Br8yHNM06dOtE/XiazHxs5k0blCXDm1annH9GwY8xuGjRyksLOS3hV1CCgAAIABJREFUFX8w4qWnT7sLg69x2O0M7n87g18dhmlaJfvk85k0rv839sl9g0v2yfI/GPHSUz69T+x2Ow/d35+nX3odl2nSu3tX6taOY8rUaTRMqE/7tq35es58/lizDofDQXBQIE8/+hAAObm5PPXS69gMgwhnOM8OftjLW+MZdruD2+59irdfeRjT5aJj96uoGV+frz4bR90GTbiwTWd+mvcFG9auwG53EBgUwr2PvFS8/uP3XkX+0cMUFhawavmvPPHy+253phARz7NOvYOAnJFxph1mGMYFFA2XMIHHgIHAHcB+4F7Lspae7Q3uezNL/yMn2bxis7dDqHT63nuJt0OodEJ8+/upx11TbZ63Q6h0doed+YvKv9Gfab4/lMmTuoclnr3Tv40+JJ7muN+5cbtqT9njqn32Tv9CFzfx/USxlLtz+h5Tt7+Y4pMXkP+9FuOV/5czDpewLGutZVm9LMvqbVnWZsuyHrEsK9SyrGaA7/90KSIiIiIiIiIe80/uWfgKMMVTgYiIiIiIiIhUNqYXbwfpi86YZDAMY11pTYDqUkVERERERESk2NkqGaKBXkD2Kc8bFN3SUkREREREREQEOHuSYQ4QZFnWmlMbDMP4pVwiEhERERERERGfdMYkg2VZ95yhrZ/nwxERERERERGpPCzNyVAmZ7y7hIiIiIiIiIjI36Ukg4iIiIiIiIh4xD+5haWIiIiIiIjIOc2yNFyiLFTJICIiIiIiIiIeoSSDiIiIiIiIiHiEkgwiIiIiIiIi4hGak0FERERERESkFJZpejsEn6JKBhERERERERHxCCUZRERERERERMQjlGQQEREREREREY/QnAwiIiIiIiIipTBNy9sh+BRVMoiIiIiIiIiIRyjJICIiIiIiIiIeoeESIiIiIiIiIqWwLA2XKAtVMoiIiIiIiIiIRyjJICIiIiIiIiIeoSSDiIiIiIiIiHiE5mQQERERERERKYWlW1iWiSoZRERERERERMQjlGQQEREREREREY/QcAkRERERERGRUmi4RNmokkFEREREREREPEJJBhERERERERHxCCUZRERERERERMQjyn1Ohlq1Q8r7LXyKYTTxdgiVzjX1//R2CJWOc/Mib4dQqfz53CfeDqHScUyZ4+0QKp0ff87wdgiVykpnM2+HUOkcPnjc2yFUOtf0CvR2CJXKoj807vpUAzttZ+82b0dR+cQlNPV2CFKBTMv0dgg+RZUMIiIiIiIiIuIRSjKIiIiIiIiIiEcoySAiIiIiIiIiHlHuczKIiIiIiIiI+CrL1HwtZaFKBhERERERERHxCCUZRERERERERMQjNFxCREREREREpBQaLlE2qmQQEREREREREY9QkkFEREREREREPEJJBhERERERERHxCM3JICIiIiIiIlIKy9KcDGWhSgYRERERERER8QglGURERERERETEI5RkEBERERERERGP0JwMIiIiIiIiIqUwTdPbIfgUVTKIiIiIiIiIiEcoySAiIiIiIiIiHqHhEiIi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EYfHXt3FpPNyCJnx1qI9lFbUc9bYLqzbXMeiVTW8uWAPE8/O5tZL8/jk0wgPPBs9DrIyQlz1/RwiHh0RMeWF9n3nkb0iDs++WcNFX++EGby/InpniVOPTaekIsKydfUUF4W44LSOdO5oDO2Xxqkjnduf/JRuXY2vn9Ap2pCb8frCWsoq23cbrPY3Xjicxrd+fAP333px9BaW475Jj+JBvPzUXygeMIyjRpzEC4/eyWd7djPt7quBaHFh4rV/ZvhxE1i9dA5/uOYcMGPI8BM48phxwX6gBIg4vPhuHT86LR0zY96qesqrnPFHhynZ6qzYEKFXgXH++HQ6d4AhfUKccrRzz7OHxm1v9yfaV5vIdTfdTCQS4bQJp9Cvbx+mPfo4hw0exPGjRvLCzJeZv2gxaeEwmZmZXDsp2ier2rGD6266mZAZ+fn5XHf1FQF/GhExb2GVQzMbAvQE5rj7rn2eP83dX23pF7T2dIn2ZtOGQ6NjmUg3frMk6BCSTv6KN4IOIaksue2RoENIOmkPzww6hKTzlyfV3OwrN79LyzulmE92pvaogv05+9SMlndKIW/M03nk8y4Z0/7vqtUaigcPDTqEZHNIL2w34fvt8+Qw67FjAvn/csDpEmZ2OfAccBmw1MzO2uflW1szMBERERERERFpX1qaLjERGOHuu8ysHzDDzPq5+z0c4tUqEREREREREfliWioyhPZOkXD3dWY2jmihoS8qMoiIiIiIiMghLsjbQbZHLd1dYouZDd+7ESs4nAkUAEe1ZmAiIiIiIiIi0r60VGT4AVC27xPuXufuPwDGtFpUIiIiIiIiItLuHHC6hLs3u+y/u7+d+HBEREREREREpL1qaU0GERERERERkZTlHgk6hHalpekSIiIiIiIiIiIHRUUGEREREREREUkIFRlEREREREREJCG0JoOIiIiIiIhIMyIRDzqEdkUjGUREREREREQkIVRkEBEREREREZGE0HQJERERERERkWZ4RLew/CI0kkFEREREREREEkJFBhERERERERFJCBUZRERERERERCQhtCaDiIiIiIiISDNct7D8QjSSQUREREREREQSQkUGEREREREREUkITZcQERERERERaYa7bmH5RWgkg4iIiIiIiIgkhIoMIiIiIiIiIpIQKjKIiIiIiIiISEJoTQYRERERERGRZugWll+MRjKIiIiI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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1oDecB_8fGwM" + }, + "source": [ + "### **Conclusão**: Qual a conclusão podemos tirar esta análise?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "avZ12nHqiK0M" + }, + "source": [ + "___\n", + "# **RFE - Recursive Feature Elimination** (continuação da Análise de Correlação)\n", + "* Muito tempo de processamento! Portanto, exclua as colunas altamente correlacionadas do dataframe previamente.\n", + "* A matriz X e target deste tópico vem do tópico anterior \"Análise de Correlação\";\n", + "\n", + "* Leitura recomendada: [Feature Selection in Python — Recursive Feature Elimination](https://towardsdatascience.com/feature-selection-in-python-recursive-feature-elimination-19f1c39b8d15)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MCGTzI59R3G7" + }, + "source": [ + "from sklearn.feature_selection import RFECV\n", + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.model_selection import StratifiedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sqsK1bGmiK0O", + "outputId": "3a989f0a-6324-4b9c-a668-c0b512558223", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "rf = RandomForestRegressor(random_state = 20111974)\n", + "filtro_rfe = RFECV(estimator = rf, step = 1, cv = StratifiedKFold(10))\n", + "filtro_rfe.fit(X_cancer, y_cancer)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RFECV(cv=StratifiedKFold(n_splits=10, random_state=None, shuffle=False),\n", + " estimator=RandomForestRegressor(bootstrap=True, ccp_alpha=0.0,\n", + " criterion='mse', max_depth=None,\n", + " max_features='auto', max_leaf_nodes=None,\n", + " max_samples=None,\n", + " min_impurity_decrease=0.0,\n", + " min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0,\n", + " n_estimators=100, n_jobs=None,\n", + " oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False),\n", + " min_features_to_select=1, n_jobs=None, scoring=None, step=1, verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 244 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MBnSFtWiDvOd", + "outputId": "863be880-0320-4154-c1a8-06fd72c65133", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_cancer.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(569, 13)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 245 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yomSdCzJD2tS", + "outputId": "f956d8e0-6038-4eed-b908-a1ee5d80762c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_cancer.size" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "569" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 246 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f-dKku9IiK0V", + "outputId": "aa8192fa-dbe9-4399-caf0-10ecd83b4e4a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Número ótimo de colunas:\n", + "filtro_rfe.n_features_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "8" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 247 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TUoMb40-iK0Y", + "outputId": "fc509029-ce5e-4102-c3a3-715e0e0af10c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 605 + } + }, + "source": [ + "plt.figure(figsize=(16, 9))\n", + "plt.title('Recursive Feature Elimination (rfe) com Cross-Validation', fontsize=18, fontweight='bold', pad=20)\n", + "plt.xlabel('Número de colunas selecionadas', fontsize=14, labelpad=20)\n", + "plt.ylabel('% Acurácia do Modelo', fontsize=14, labelpad=20)\n", + "plt.plot(range(1, len(filtro_rfe.grid_scores_) + 1), filtro_rfe.grid_scores_, color='#303F9F', linewidth=3)\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RG16C-2QdhUx" + }, + "source": [ + "### **Conclusão**: Houve uma redução para 7 colunas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M8lpuOjti6Fw", + "outputId": "cf3d3eeb-0b63-40f1-8b4e-a2c581638b9f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "X_cancer.drop(X_cancer.columns[np.where(filtro_rfe.support_ == False)[0]], axis = 1, inplace = True)\n", + "X_cancer.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
014510151828
017.9910.380.118400.277601.09500.049040.030030.4601
120.5717.770.084740.078640.54350.013080.013890.2750
219.6921.250.109600.159900.74560.040060.022500.3613
311.4220.380.142500.283900.49560.074580.059630.6638
420.2914.340.100300.132800.75720.024610.017560.2364
\n", + "
" + ], + "text/plain": [ + " 0 1 4 5 10 15 18 28\n", + "0 17.99 10.38 0.11840 0.27760 1.0950 0.04904 0.03003 0.4601\n", + "1 20.57 17.77 0.08474 0.07864 0.5435 0.01308 0.01389 0.2750\n", + "2 19.69 21.25 0.10960 0.15990 0.7456 0.04006 0.02250 0.3613\n", + "3 11.42 20.38 0.14250 0.28390 0.4956 0.07458 0.05963 0.6638\n", + "4 20.29 14.34 0.10030 0.13280 0.7572 0.02461 0.01756 0.2364" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 249 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s7S87LApdESo", + "outputId": "096f4cc6-45fe-49f5-c4e8-8d098d3001f2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "filtro_rfe.estimator_.feature_importances_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.6274782 , 0.06895439, 0.02932265, 0.06823762, 0.05093922,\n", + " 0.01941762, 0.03383343, 0.10181687])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 250 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FEfmeic37hvw" + }, + "source": [ + "___\n", + "# **Feature Selection com Random Forest**\n", + "* Para demonstrar este método, vou utilizar o Boston Housing Price dataframe.\n", + "\n", + "![Supervised_X_Unsupervised](https://github.com/MathMachado/Materials/blob/master/Supervised_X_Unsupervised.jpeg?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0F2BdrZgKzV5" + }, + "source": [ + "### Carregar o dataframe\n", + "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6H31U15q7kIO" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "# Função para carregar as informações do dataframe Iris\n", + "def carrega_df_iris():\n", + " global df_iris, l_iris_labels, X_iris, y_iris, iris\n", + "\n", + " iris = load_iris()\n", + " X_iris = iris['data']\n", + " y_iris= iris['target']\n", + "\n", + " df_iris = pd.DataFrame(np.c_[X_iris, y_iris], columns= np.append(iris['feature_names'], ['target']))\n", + " df_iris['target2']= df_iris['target']\n", + " df_iris= df_iris.rename(columns={'sepal length (cm)': 'Sepal Length', 'sepal width (cm)': 'sepal width', 'petal length (cm)': 'petal length', 'petal width (cm)': 'petal width'})\n", + " df_iris['target'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "\n", + " # Criar a lista de nomes das variáveis\n", + " l_iris_labels = ['Sepal Length','Sepal Width','Petal Length','Petal Width']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rD2DmkpNXkFy" + }, + "source": [ + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jVQuRHYhM4fD" + }, + "source": [ + "> A variável-resposta que estamos tentando prever/explicar é categórica. Portanto, vamos usar um algoritmo da classe supervisionado para Classificação.\n", + "\n", + "* SelectFromModel selecionará os atributos cuja importância seja maior do que a importância média de todos os recursos por padrão, mas podemos alterar esse limite se quisermos." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1pPpC7GXLgpC" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.feature_selection import SelectFromModel" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dfSfuUlHQOSt" + }, + "source": [ + "# Particionar base de treinamento (80%) e validação (20%)\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_iris, y_iris, test_size = 0.2, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JDsdjsZ0M4F", + "outputId": "71d1931c-9569-4a44-d7b0-7a7cfb789fa5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(120, 4)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 255 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SH_B3C1u0Qkl", + "outputId": "1e00e16e-ed0b-4317-fe46-f0f5f0f46562", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(30, 4)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 256 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YQ270kclOFeK" + }, + "source": [ + "# Create a random forest Regressor\n", + "ml_rf = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vFSCt8uaeKFN", + "outputId": "154735f9-3388-4023-9de6-cabd217c793f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Treina o classificador\n", + "ml_rf.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=10000,\n", + " n_jobs=-1, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 258 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VfdKeUkgS6ul" + }, + "source": [ + "Os atributos mais importantes são:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tnrwVLPKSNxr", + "outputId": "2a3db4d0-5794-48ad-ca10-ba988b399e85", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Imprime o nome do atributo associado à importância usando índice de Gini\n", + "for feature in zip(l_iris_labels, ml_rf.feature_importances_):\n", + " print(feature)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "('Sepal Length', 0.08731002037613723)\n", + "('Sepal Width', 0.021750035432184116)\n", + "('Petal Length', 0.39132734233988486)\n", + "('Petal Width', 0.4996126018517938)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x8FHRHlDWTn4" + }, + "source": [ + "* Os scores acima representam a importância de cada variável.\n", + " * A soma dos scores resulta em 100%;\n", + " * Os atributos 'Petal Length' (Score= 0.45) e 'Petal Width' (Score= 0.42) são os mais importantes.\n", + " * Combinados, as duas variáveis mais importantes somam ~0.86." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wbMnS_gIVBA8" + }, + "source": [ + "Como regra geral, selecione os atributos que tenha importância de no mínimo 0.15. \n", + "\n", + "Citar autor/Referência!!!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M3TnDYRVeMEs" + }, + "source": [ + "Algo mais visual:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o8QkARWpeI_e" + }, + "source": [ + "def importancia_variaveis():\n", + " # Calcula a importância das features\n", + " importances = ml_rf.feature_importances_\n", + "\n", + " # Ordena as features por importância\n", + " indices = np.argsort(importances)[::-1]\n", + "\n", + " # Associa a feature name com a feature importance\n", + " names = [iris.feature_names[i] for i in indices]\n", + "\n", + " # Barplot\n", + " plt.bar(range(X_treinamento.shape[1]), importances[indices])\n", + "\n", + " # Adiciona as feature names no eixo x-axis\n", + " plt.xticks(range(X_treinamento.shape[1]), names, rotation = 20, fontsize = 8)\n", + "\n", + " # Define o título do gráfico\n", + " plt.title(\"Importância Preditiva das variáveis\")\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ahZdlCBE6h_e", + "outputId": "1d263536-5b65-489a-905b-1bc6a4e54e1f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "importancia_variaveis()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "owVs6pvJ8F8B" + }, + "source": [ + "## Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RISO1Ury8EEH", + "outputId": "943423c9-1aa1-448c-b737-ee23adda9e31", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao = df_iris.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k = 1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Sepal Lengthsepal widthpetal lengthpetal widthtarget2
Sepal LengthNaN0.117570.8717540.8179410.782561
sepal widthNaNNaN0.4284400.3661260.426658
petal lengthNaNNaNNaN0.9628650.949035
petal widthNaNNaNNaNNaN0.956547
target2NaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " Sepal Length sepal width petal length petal width target2\n", + "Sepal Length NaN 0.11757 0.871754 0.817941 0.782561\n", + "sepal width NaN NaN 0.428440 0.366126 0.426658\n", + "petal length NaN NaN NaN 0.962865 0.949035\n", + "petal width NaN NaN NaN NaN 0.956547\n", + "target2 NaN NaN NaN NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 262 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lieB7hDg8EEM", + "outputId": "a6c1c02d-3c2f-41e8-c1e5-6154f34d95ae", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 500 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize = (8, 8)) \n", + "mask = np.zeros_like(df_iris.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_iris.corr().abs(), mask = mask, ax = ax, cmap ='coolwarm', annot = True, fmt = '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 263 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAHSCAYAAACZ5wCaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdd5wV1f3/8ddnC70X6UUBCyAqIDaiYklQo8YWS+I3GhOSWKM/jaiJGmLXmHy/xkSxt0QxmoiKUaNiRykKCAgiSu9lQYR1y+f3x51d767s3QHv3Lt37vv5eMyDKeee+dxx3c+eM2fOmLsjIiIiXyvIdgAiIiINjZKjiIhILUqOIiIitSg5ioiI1KLkKCIiUouSo4iISC1FGTiHnhUREWk4LKqKny/eLe2/748pmxtZvKmo5SgiIlJLJlqOIiKSB6w4K428SKjlKCIiUotajiIikhYFRWo5ioiIxJZajiIikhZWHJ/2lpKjiIikhbpVRUREYkwtRxERSQs9yiEiIhJjajmKiEhaxOmeo5KjiIikhbpVRUREYkwtRxERSYs4dauq5SgiIlKLWo4iIpIWVhiflqOSo4iIpEVBjJKjulVFRERqUctRRETSwgrUchQREYkttRxFRCQtrDA+7a34fBMREZE0UctRRETSIk6jVZUcRUQkLTQgR0REJMbUchQRkbSIU7eqWo4iIiK1qOUoIiJpEae5VdVyFBGRtLCCgrQvoc5rNtLM5prZfDMbvY3jvczsFTObYWYTzax7fXUqOYqISM4ys0LgTuAooD9wupn1r1XsNuBhdx8EjAFurK9eJUcREUkLK7C0LyEMA+a7+wJ3/wp4HDi+Vpn+wKvB+mvbOP4NSo4iItJgmdkoM5uStIyqVaQbsDhpe0mwL9l04MRg/QSgpZm1T3VeDcgREZG0iOJRDncfC4z9ltVcCvzFzM4C3gCWAhWpPqDkKCIiaZGlGXKWAj2StrsH+6q5+zKClqOZtQBOcvcNqSpVt6qIiOSyyUA/M9vZzBoBpwHjkwuYWQczq8p3VwD311epWo4iIpIWYR+9SCd3Lzez84EXgULgfnefZWZjgCnuPh44FLjRzJxEt+p59dVr7h5h2ABEfgIREQktsr7PGUcfmvbf94MmTMxKX61ajiIikhZxeiuHkqOIiKSFJh4XERGJsVAtRzM7EOidXN7dH44oJhERyUF51a1qZo8AfYAP+fqhSQeUHEVEJJbCtByHAv19O4a1BtP7jAK4++67GTWq9mw/IiISN9l4lCMqYZLjR0BnYHnYSmtN96NHOUREJKfUmRzN7FkSia0lMNvM3gdKq467+3HRhyciIrkiX+453paxKEREJOflRXJ099cBzOxmd788+ZiZ3Qy8HnFsIiIiWRHm7umR29h3VLoDERGR3Jallx1HItU9x18B5wK7mNmMpEMtgbejDkxERCRbUt1z/DvwAnAjMDpp/yZ3XxdpVCIiknPy4lEOdy8BSszsG6/2MLNidy+LNDIREckp+Ta36jRgNTAP+CRY/9zMppnZkCiDExERyYYwyfFl4Gh37+Du7UkMxnmOxP3Iv0YZnIiI5I44DcgJkxz3d/cXqzbc/SXgAHefBDSOLDIREZEsCTN93HIzuxx4PNg+FVhpZoVAZWSRiYhITsmLATlJzgCuAf4dbL8d7CsEfhhRXCIikmPyYoacKu6+BrigjsPz0xuOiIhI9oV5n+OuwKV882XHh0UXloiI5Jq8ajkCTwJ3Affy9cuORUREYitMcix3979FHomIiOS0OA3ICfNNnjWzc82si5m1q1oij0xERCRLwrQcfxL8e1nSPgd2SX84IiKSq/LqnqO775yJQEREJLflVbeqmTUzs9+a2dhgu5+ZfT/60ERERLIjTJp/APgKODDYXgpcF1lEIiKSm8zSv2RJmOTYx91vAcoA3P1LID4dyyIiIrWEGZDzlZk1JTEIBzPrA5RGGpWIiOScvBqQQ2Je1f8APczsMeAg4KwogxIRkdwTpwE5YUarvmxm04D9SXSnXgT0iTowERGRbAnTcsTd1wLPV20HybJnVEGJiEjuiVO36o62geNzBURERGoJ1XLcBk9rFCIikvPy4p6jmT3LtpOgAe0ji0hERHJSnLpVU7Ucb9vBYyIiIjmtzuTo7q9nMhAREcltcWo5xqeDWEREJE12dECOiIhITTEakBOfbyIiIpImOzJaFQB3Py6SiEREJCdZFt+ikW47OlpVRESkhmw952hmI4H/BQqBe939plrHewIPAW2CMqPdfUKqOjVaVUREcpaZFQJ3AkcCS4DJZjbe3WcnFfstMM7d/2Zm/YEJQO9U9dY7IMfM+gE3Av2BJlX73X2X7f0SIiISX1l6lGMYMN/dFwCY2ePA8UBycnSgVbDeGlhWX6Vh2sAPAH8DyoERwMPAo6HDFhERiU43YHHS9pJgX7JrgR+b2RISrcYL6qs0THJs6u6vAObuC939WuCYMBGLiEgeKShI+2Jmo8xsStIyagciOx140N27A0cDj5hZyvwX5jnH0qCST8zsfGAp0GIHghMRkRiLolvV3ccCY1MUWQr0SNruHuxLdg4wMqjvXTNrAnQAVtVVaZjkeBHQDLgQ+ANwGPCTEJ8DYPixGteTylvPHpLtEEREctlkoJ+Z7UwiKZ4GnFGrzCLgcOBBM9uDxPiZ1akqrTc5uvtkgKD1eKG7b9r+2EVEJO7q6amMhLuXB72aL5J4TON+d59lZmOAKe4+Hvh/wD1mdjGJwTlnuXvKVy+GGa06lMSgnJbBdgnwU3ef+q2+kYiISBoEzyxOqLXv6qT12cBB21NnmG7V+4Fz3f1NADMbTiJZDtqeE4mISMzF6K0cYZJjRVViBHD3t8ysPMKYREQkB2VrhpwohEmOr5vZ3cA/SPTVngpMNLPBAO4+LcL4REREMi5Mctwr+PeaWvv3IZEsD0trRCIikpPi9LLjMKNVR2QiEBERkYai3g5iM+tkZveZ2QvBdn8zOyf60EREJKdYQfqXLAlz5gdJPD/SNdieB/w6qoBERESyLUxy7ODu44BKSDxwCVREGpWIiOQcK7C0L9kSZkDOZjNrT2LwDWa2P1ASaVQiIpJ78uxRjkuA8UAfM3sb6AicHGlUIiIiWRRmtOo0MzsE2A0wYK67l0UemYiI5BSz+DzKUWcb2Mz2NbPOUH2fcQhwPfBHM2uXofhEREQyLlUH8d3AVwBmdjBwE/AwifuNqd6tJSIi+SiClx1nS6pu1UJ3XxesnwqMdfengKfM7MPoQxMRkVwSpxlyUqXlQjOrSp6HA68mHQszkEdERCQnpUpy/yAx6fgaYAtQ9cqqvuhRDhERqS2LM9qkW53J0d2vN7NXgC7AS0lvTS4ALshEcCIiItmQsnvU3SdtY9+86MIREZGcFaN7jrp3KCIiaWEx6laNzzcRERFJE7UcRUQkPWLUraqWo4iISC1qOYqISFpYjN7KEZ9vIiIikiZqOYqISHrE6K0cSo4iIpIe6lYVERGJL7UcRUQkPWLUraqWo4iISC1qOYqISFrE6VEOJUcREUkPza0qIiISX2o5iohIemhuVRERkfhSy1FERNIiTu9zVHIUEZH0ULeqiIhIfMWm5bjf4LZc9PO+FBQYz728nEf/ubjG8b0GtObCn/ehT+8WXHvLbCa+swaAvjs359Jzd6V5s0IqKpyHxy3i1bdWZ+MriIjkNnWrNiwFBXDJL/tx8e9msGptKffePpi33lvL54u/rC6zcvVWbvjzXE4/oXuNz5aWVnLd7R+zZPkW2rdrxH1/Gsz7H6zji80Vmf4aIiLSQNSbHM2sMXAS0Du5vLuPiS6s7bNHv1YsWb6FZSu3AvDfN1YxfL/2NZLjilWlQCmVXvOzi5dtqV5fu+4rNpSU0aZVI77YvAUREdkOeTa36jPA8UA5sDlpaTA6tm/EqjWl1dur15bSsX3j7a5nj34tKSoylq5QYhQRyWdhulW7u/vI7anUzEYBowD67Pn/6Nzr2B2JLaPat23E7y7Znev//DHu9ZcXEZFaYjS3aphv8o6Z7bk9lbr7WHcf6u5DM5EYV6/9ip06fN1S7Ni+MavXlqb4RE3NmhZyyzUDGfvIZ8yauymKEEVE4s8K0r+EOa3ZSDOba2bzzWz0No7/ycw+DJZ5ZrahvjrrbDma2UzAgzJnm9kCoBQwwN19UKioM+DjTzbSo2tTunRqwuq1pRxx8E78/rY5oT5bVGTccNUA/vPqyuoRrCIikhvMrBC4EzgSWAJMNrPx7j67qoy7X5xU/gJgn/rqTdWt+v0dDzezKirh9rvmc/vv96SgwHj+vyv4bNGXnPOj3nz8ySbefn8tu/dryQ1XDqBliyIO2rc95/yoN2eeN4XDhndk7wGtad2ymKMP7wzA9X/+mPmfNajbqiIiDV92JgEYBsx39wUAZvY4iXEys+sofzpwTX2V1pkc3X1hcKJH3P3M5GNm9ghw5jY/mCWTpq5j0tR1Nfbd99jn1esff7KJE8+e9I3PvTRxFS9NXBV1eCIiEo1uQPKD7UuA/bZV0Mx6ATsDr9ZXaZgBOQNqVV4IDAnxORERyScRTAKQPMAzMNbdx+5gdacB/3T3eh9kT3XP8QrgSqCpmW2s2g18BexoYCIiElcRPOcYJMJUOWcp0CNpu3uwb1tOA84Lc94607y73+juLYFb3b1VsLR09/bufkWYykVERCI2GehnZjubWSMSCXB87UJmtjvQFng3TKWpWo6Dg9Unk9arufu0MCcQEZE8kYXnHN293MzOB14ECoH73X2WmY0Bprh7VaI8DXjcPdyT7KnuOf4x+LcJMBSYTqJbdRAwBThg+7+GiIhIern7BGBCrX1X19q+dnvqTDVadQSAmT0NDHb3mcH2QGC7TiIiInkgRnOrhhmtultVYgRw94/MbI8IYxIRkVyUZ6+smmFm9wKPBts/AmZEF5KIiEh2hUmOZwO/Ai4Ktt8A/hZZRCIikptiNPF4vcnR3bcCfwoWERGR2Ev1KMc4d/9h0gTkNTSkicdFRKQByJMBOVXdqDkzAbmIiEg6pHqUY3mwegTwhrt/kpmQREQkJ+XZaNWewN1m1huYSmJAzpvu/mGEcYmISK6JUbdqvWne3a9x98NIvJ3jTeAyEklSREQkluptOZrZb4GDgBbAB8ClJJKkiIjI1/LpUQ7gRKAceB54HXjX3UsjjUpERCSLwjznONjMWpFoPR4JjDWzVe4+PPLoREQkZ3iM7jmG6VYdCHwHOITE2zkWo25VERGpLc9Gq95EYoTq/wGT3b0s2pBERESyK0y3qiYBEBGR+sWo5RifbyIiIpImYbpVRURE6pVXA3JERERCiVG3aqq3cjzLNt7GUcXdj4skIhERkSxL1XK8LWNRiIhI7suHblV3fz2TgYiIiDQUYSYB6AfcCPQHmlTtd/ddIoxLRERyTZ7NrfoAcA3wJ2AEcDZ6BERERGqJ02jVMEmuqbu/Api7L3T3a4Fjog1LREQke8K0HEvNrAD4xMzOB5aSeH2ViIjI12L0KEeYb3IR0Ay4EBgCnAn8JMqgREREsinM3KqTAYLW44XuvinyqEREJOd4PrUczWyomc0EZgAzzWy6mQ2JPjQREZHsCHPP8X7gXHd/E8DMhpMYwTooysBERCTHxGi0apjkWFGVGAHc/S0zK48wJhERyUFx6lYNkxxfN7O7gX+QmGv1VGCimQ0GcPdpEcYnIiKScWGS417Bv9fU2r8PiWR5WFojEhGR3JRP3aruPuLbnOC+Zjd8m4/H2oLRz/HCB2XZDqNBO2qf4myHICJ5KMxo1U5mdp+ZvRBs9zezc6IPTUREcooVpH/JkjBnfhB4EegabM8Dfh1VQCIikpvcLO1LtoRJjh3cfRxQCeDu5UBFpFGJiIhkUZgBOZvNrD2JwTeY2f5ASaRRiYhI7smzRzkuAcYDfczsbaAjcHKkUYmIiGRRmNGq08zsEGA3wIC57q4hliIiUoMTn0c5woxWPYXEOx1nAT8AnqiaAEBERKSKW0Hal2wJc+bfufumYE7Vw4H7gL9FG5aIiEj2hEmOVSNTjwHucffngUbRhSQiIjkpz55zXBrMrXoqMMHMGof8nIiISOTMbKSZzTWz+WY2uo4yPzSz2WY2y8z+Xl+dYUar/hAYCdzm7hvMrAtw2faFLiIicZeNh/bNrBC4EzgSWAJMNrPx7j47qUw/4ArgIHdfb2Y71VdvmNGqXwJPJ20vB5Zv/1cQERFJu2HAfHdfAGBmjwPHA7OTyvwcuNPd1wO4+6r6Kg3TchQREalXlkaXdgMWJ20vAfarVWZXgOBZ/ULgWnf/T6pKlRxFRCQ9IuhWNbNRwKikXWPdfex2VlME9AMOBboDb5jZnu6+IdUHREREGqQgEaZKhkuBHknb3YN9yZYA7wUT2HxmZvNIJMvJdVWqUaciIpIWWZoEYDLQz8x2NrNGwGkkpjxN9m8SrUbMrAOJbtYFqSpVchQRkZwVvCnqfBKvVpwDjHP3WWY2xsyOC4q9CKw1s9nAa8Bl7r42Vb3qVhURkbTI1tyq7j4BmFBr39VJ607iJRqXhK1TyVFERNIim3Ohplt8vomIiEiaqOUoIiLpkYUZcqKilqOIiEgtajmKiEhaeIzaW0qOIiKSFtmYeDwq8UnzIiIiaaKWo4iIpIUe5RAREYkxtRxFRCQtsjVDThTUchQREalFLUcREUmLON1zVHIUEZG00KMcIiIiMaaWo4iIpIUG5IiIiMSYWo4iIpIWGpAjIiJSi7pVRUREYkwtRxERSYs4davG55uIiIikSWxajs32Gkqns34JBYWUvPoC654ZV+N4UfuOdDnvMgqaNccKClj99/vZ/OFkWg4fQbtjT6ku17jnziwcfR6lCxdk+itEas6Hb/H0QzfhlRXsf9hJHHH8z7ZZbvp7L/PAny7mkusfp2efgSycP5Mn7rk2cdCdkSefy6BhR2QucBHJGXG65xiP5GgFdPrpeSy5/grK1q6h14138MWUSXy1dFF1kfYnnsGmd99gw8vP0ahbT7qP/gMLLvgJm956jU1vvQZAox696XbpNbFLjJWVFfzz/uv41VX30KZ9Z26/8lQGDhlB5+59apTbumUzr7/wKL36Dqre16VHX/7fDU9QWFhEyfrV3Hr5SQwYciiFhfH40RGR9MmrblUza2xmZ5jZlWZ2ddWSieDCatJ3N8pWLqNs1QqoKGfTOxNpse8BtUo5BU2bAVDQrDnl69d9o55WB41g0zuvRx9whi2cP5MOnXvSoVMPioqK2efAo5g55dVvlJsw7g4OP+6nFBU3qt7XqHHT6kRYXlZKjP4wFBGpU5g0/wxwPFAObE5aGoyidu0pW7u6ert87RqK2naoUWbNk4/S6juHsctfH6X76D+w8oE7v1FPywMOZuM7r0Ueb6aVrFtF2/adq7fbtOtEybpVNcos/mw2G9auYMDgQ77x+c8/mcFNlx7PzZedwA/PuVqtRhHZJsfSvmRLmN9y3d195PZUamajgFEAvx/Sn1P7dN+R2NKq1UGHUvL6y6x/7ima9NuDLuf/hs8v/QW4A4nWp39VyleLF2Y50syrrKzk3w/fwhm/un6bx3v3G8To255hxdJP+ftfr2KPvb9DcaPGGY5SRCRzwrQc3zGzPbenUncf6+5D3X1oJhJj+bq1FLfvWL1d1L4D5evX1CjTesRINr37BgBbP5mDFTeisGWr6uMtDzyUjW9PjDzWbGjdbifWr11Rvb1h3Upat9upert062ZWLJnPX8acze/P/y4L58/g3tsuYNGnH9Wop3O3PjRu0ozliz/JWOwikjvcLO1LttSZHM1sppnNAIYD08xsrpnNSNrfYGz9dC7FnbtR3LETFBbR8sBD+WLKpBplytasotnAvQFo1K0HBcWNqNhYkjhoRssDDmbTOxMzG3iG9OwzkDUrFrF21RLKy8v44J0XGDhkRPXxps1acv09b3HNX17imr+8RK++g/jZpXfQs89A1q5aQkVFOQDrVi9j5bLPaNexW7a+iohIRqTqVv1+xqL4tiorWXX/nXS/8gYoKKBk4kt8tWQh7U/5H7YumMfmqZNY/chYOv/i17Q95kRwZ/nfbqv+eNM99qR87erEgJ4YKiws4qSzr+SuG35BZWUF+404gS49+jJh3F/oucsABg4dUednF3w8jVfG30dBYREFVsDJP/0tLVq1zWD0IpIr3OMzYs88uOdWZwGzR9z9zPr21WXuqd9LfYI8tmD0c9kOocE7ap/ibIcgEjeRZbBPPl2Y9t/3/fr0ykrGDXPPcUDyhpkVAkOiCUdERCT7Ut1zvMLMNgGDzGxjsGwCVpF4vENERKRanB7lqDM5uvuN7t4SuNXdWwVLS3dv7+5XZDBGERGRjArznOOTZja41r4SYKG7l0cQk4iI5KB8m1v1r8BgYAaJG7l7Ah8Brc3sV+7+UoTxiYhIjohTcgwzIGcZsE/wUP8QYG9gAXAkcEuUwYmIiGRDmJbjru4+q2rD3Web2e7uvsCyOHuBiIg0LHFqOYZJjrPM7G/A48H2qcBsM2sMlEUWmYiISJaESY5nAecCvw623wYuJZEY655aRURE8kqcZsipNzm6+xbgj8FS2xdpj0hERHJSXnWrmtlBwLVAr+Ty7r5LdGGJiIhkT5hu1fuAi4GpQEW04YiISK6KU8sxzKMcJe7+gruvcve1VUvkkYmIiIRgZiOD1yrON7PR2zh+lpmtNrMPg+Vn9dUZpuX4mpndCjwNlFbtdPdp2xW9iIjEWjZajsHLMO4k8ez9EmCymY1399m1ij7h7ueHrTdMctwv+Hdo0j4HDgt7EhERkYgMA+a7+wIAM3scOB6onRy3S5jRqnpcQ0RE6pWlRzm6AYuTtpfwdaMu2UlmdjAwD7jY3Rdvo0y1eu85mlknM7vPzF4Itvub2Tnh4xYRkXxQiaV9MbNRZjYlaRm1A6E9C/R290HAy8BD9X0gzICcB4EXga7B9jy+nhBAREQkMu4+Npjbu2oZW6vIUqBH0nb3YF9yHWvdvWrMzL3AkPrOGyY5dnD3cUBlcJJy9EiHiIjUkqWXHU8G+pnZzmbWCDgNGJ9cwMy6JG0eB8ypr9IwA3I2m1l7EoNwMLP9SbzPUUREJKvcvdzMzifRw1kI3O/us8xsDDDF3ccDF5rZcUA5sI7EtKgphUmOl5DIwn3M7G2gI3Dyjn0NERGJq2zNreruE4AJtfZdnbR+BXDF9tQZZrTqNDM7BNiNxMuO57q73sYhIiI1xGmGnDqTo5mdWMehXc0Md386ophERESyKlXL8dgUx5zEjDkiIiJAnryyyt3PzmQgIiIiDUWYATkiIiL1yot7jiIiItsjTt2qYSYBEBERySs7MloVQKNVRUSkhspsB5BGGq0qIiJSi0ariohIWsTpnmOoATlmdgwwAGhStc/dx0QVlIiISDbVmxzN7C6gGTCCxKs+TgbejzguERHJMXF6lCPMaNUD3f1/gPXu/nvgAGDXaMMSEZFc425pX7IlTHLcEvz7pZl1BcqALinKi4iI5LQw9xyfM7M2wK3ANBIjVe+NNCoREck5cepWDZMcb3H3UuApM3uOxKCcrdGGJSIikj1hulXfrVpx91J3L0neJyIiAlDp6V+yJdUMOZ2BbkBTM9sHqtvLrUiMXg2lTe+dvlWAcbZ8fXG2Q2jQOn1vN57PdhAN2DFlc7MdgkgN+dKt+j3gLKA7cHvS/o3AlRHGJCIiklWpZsh5CHjIzE5y96cyGJOIiOSgOM2QE+ae49tmdp+ZvQBgZv3N7JyI4xIREcmaMMnxAeBFoGuwPQ/4dWQRiYhITnJP/5ItYZJjB3cfR/A2EncvByoijUpERHJOJZb2JVvCJMfNZtaexMP/mNn+QEmkUYmIiGRRmEkALgHGA33M7G2gI4nJx0VERKrFaUBOvcnR3aeZ2SHAbiSedZzr7mWRRyYiIpIlYV5Z1QQ4FxhOomv1TTO7y901hZyIiFTL5gCadAvTrfowsAm4I9g+A3gEOCWqoERERLIpTHIc6O79k7ZfM7PZUQUkIiK5KV+mj6syzcz2d/dJAGa2HzAl2rBERCTXZHOi8HQLkxyHAO+Y2aJguycw18xmAu7ugyKLTkREJAvCJMeRkUchIiI5L98e5ViYiUBEREQaijAtRxERkXrl26McIiIi9crmXKjpFmZuVRERkbyilqOIiKRFnLpV1XIUERGpRS1HERFJi7x6lENERCSMOM2Qo25VERGRWtRyFBGRtNCAHBERkRhTchQRkbRwLO1LGGY20szmmtl8MxudotxJZuZmNrS+OpUcRUQkZ5lZIXAncBTQHzjdzPpvo1xL4CLgvTD1KjmKiEhaVHr6lxCGAfPdfYG7fwU8Dhy/jXJ/AG4GtoapVMlRRETSwj39i5mNMrMpScuoWqftBixO2l4S7KtmZoOBHu7+fNjvotGqIiLSYLn7WGDsjn7ezAqA24GztudzSo4iIpIWWXqUYynQI2m7e7CvSktgIDDRzAA6A+PN7Dh3n1JXpepWFRGRXDYZ6GdmO5tZI+A0YHzVQXcvcfcO7t7b3XsDk4CUiRHUchQRkTSpzMLcqu5ebmbnAy8ChcD97j7LzMYAU9x9fOoatk3JUURE0iJbM+S4+wRgQq19V9dR9tAwdapbVUREpBa1HEVEJC00t6qIiEiMqeUoIiJpEaf3OSo5iohIWngWRqtGJTbJsdGue9LyuDPBCtgyeSJfTnyuxvGCNu1p/cNRWJNmUFDAFy+M46u502nUbyAtRv4QCougopxNEx6n7NPZWfoW0Vkw6w1eGXc9lV7JXgedwv7fqzkD0wdv/INpr/+dgoICihs3Y+SP/kCHLn2Z9f543n/5vupyq5bO5awr/kWnHntk+itEpuN3v0P/26/CCgtYfP+TfHrrPTWON+3ZlUH33ECjju0oW7eBD39yGVuXrgSgSY8uDLr7Opp274K7M/m4UWxZuHRbpxGRHBKP5GhGyx/8hA333kxFyTranT+G0tnTqFi1rLpI88OOZ+uM99ky6RUKd+pK27MvZc3Nl1C5eRMbHrydyk0bKOzUnbbnXMaaGy7K4pdJv8rKCl5+fAynXvgALdt24qGbTqbvoNoI/xEAACAASURBVMPo0KVvdZn++x7LPgefDsAn01/h1X/eyA8vuI8Bw45jwLDjAFi9dC5P33VerBIjBQUM+L+ree+os9m6ZCXDJ/2Tlc+9yhdzPq0ussfNl7Pk0X+z9JF/0/7Q/dnt+v/H9LN+A8DeD9zM/BvvYs0r71DYvBleWZmtbyKSdXk3IMfMCs2sq5n1rFqiDmx7FPfoQ8XalVSsWw0VFWydPonG/YfUKuVY4yYAFDRpRsWmDQCUL1tIZbBesXIJVtwo0YqMkeWfz6BNx1606diDwqJG7DH0GD6Z/kqNMo2btqheL/tqC2zjPWqzJz/PHkOPiTrcjGozbBBffrqQLZ8twcvKWPbE83Q69vAaZVrs0Ye1r00CYO3ESdXHW+zRBysqYs0r7wBQsflLKreEmvBfRBq4erOAmV0AXAOsBKr+LHZgUIRxbZeC1m2p3LCueruyZB3FPfvUKLP55adpc87lNDvou1hxY9bfe9M36mm8576ULf0cKsqjDjmjNm1YSau2nau3W7btxPLPZnyj3LSJjzH5lQeoqCjjtF8/9I3jH0+dwIm//GuksWZak66d2LJkRfX21qUraTOs5o/2xhkf0/mE7/L5HQ/T+QdHUtyqBcXt2tC8X2/KNmxkyLg7aLpzd9a88i4fX3kbqPUoeSpOA3LCtBwvAnZz9wHuvmewpEyMya8YeeTDT9IT6bfUZO8D2Dr1TdbccBEbHriN1qf+Euzr1lFhp260OOpUNj39QBajzK7Bh/6IX/zhvxz6g0t5d8Lfahxb9tl0iho1pWO3XbMUXfbMufwW2n9nX4ZP/hftDh7GliUr8IoKrKiIdsOHMvvym3l7/5NptnN3evzkxGyHK5I1UbyyKlvCJMfFQMn2VOruY919qLsPPXPvfjsW2XaoLFlPQZt21dsFrdtRUbK+Rpmm+x7C1hmJF0CXLZoPRcVYs5ZB+ba0OfMiNj5xNxXrVkUeb6a1bNOJjeu/bh1tWr+SFm061Vl+j6HHMG/6f2vsmzPlefrHrEsVYOuylTTt/nWrukm3TtWDbaqULl/F1B9ewFv7nsDc3/0JgPKSTWxduoKN0+ckumQrKlg5/hVa7fONF5CLSA6qMzma2SVmdgmwgMSrPq6o2hfsbzDKliygsH1nCtp2hMJCmuy1P6VzptUoU7FhLY36DgCgcKeuWHExvnkj1qQZbc66lC9eGEfZwobRyk23Lr32ZP2qz9mwZjEV5V8xZ8rz9B10WI0y61Z9Xr3+6UcTabdTr+ptr6zk46kvxO5+I0DJ5Jk079ubpr27Y8XFdD31GFY+92qNMsXt21b3MvS9fBRLHnwKgA2TZ1LcphWNOrQFoP2I/fhizvzMfgGRBiROLcdU9xxbBv8uCpZGwQKJe44NR2Ulm555mLbnXAYFBWyd/AYVK5fS/MgTKV/yGaVzPmDTc3+n1Unn0Gz4SMDZOC7x7sxmBx5JUYdOND/iBzQ/4gcArL/3Fnzzxix+ofQqKCziyNOuZtwdP8MrK9jzwJPo2LUfbz77v3TuOZB+ex3OtImP8vnH71JYWESTZq04+ic3V39+8fzJtGzbhTYde6Q4S27yigo+umgMw56/FyssZMmDT/HF7Pnses2FbJj6Eauee5X2hwxj9+suwd1Z99YUZl3w+8SHKyuZ85ub2e+lh8CgZNosFt37ZHa/kIikhXk9qdnMTnH3J+vbV5eVl5/ZsBJpA/L89x7JdggNWqfv7ZbtEBq0Y8rmZjsEyU2RPal/7yvpbzj97PDo4k0lzD3HK0LuExERiYU6u1XN7CjgaKCbmf1f0qFWQLyedRARkW8tTpMApLrnuAyYChwX/FtlE3BxlEGJiEjuidMjvnUmR3efDkw3s8fcvSyDMYmIiGRVqm7VmQSjUs2+eT+0vokAREQkv+RLt+r3g3/PC/6tGlr5YxraoxwiIiJplKpbdSGAmR3p7vskHbrczKYBo6MOTkREckecWo5hHuUwMzsoaePAkJ8TEZE8UunpX7IlzLuZzgHuN7PWJB4eXQ/8NNKoREREsqje5OjuU4G9guSIu2/XJOQiIpIf6ptxbcdkZYKclKNVf+zuj9aeZLxq5Kq73x5xbCIiIlmRquXYPPi3ZYoyIiIiQLwG5KQarXp3sHqzu2/NUDwiIpKj8mKGnCQfmdlK4M1geUv3HUVEJM7CDMjpa2Y9ge8AxwB3mtkGd9878uhERCRn5EW3ahUz6w4cRCI57gXMAt6KOC4REZGsCdOtugiYDNzg7r+MOB4REclR2XxoP93CzHSzD/AwcIaZvWtmD5vZORHHJSIikjVh7jlON7NPgU9JdK3+GDgEuC/i2EREJIfk2z3HKUBj4B0So1UPrpqUXEREpIpH0q/awGbISXKUu6+OPBIREZEGIky3qhKjiIjUK98G5IiIiOSVMN2qIiIi9cqLATlmdmKqD7r70+kPR0REclVljPpVU7Ucj01xzAElRxERiaVUb+U4O5OBiIhIbsuLbtVkZnYMMABoUrXP3cdEFZSIiEg21Tta1czuAk4FLiDxNOYpQK+I4xIRkRzjnv4lDDMbaWZzzWy+mY3exvFfmtlMM/vQzN4ys/711RnmUY4D3f1/gPXu/nvgAGDXcCGLiEi+qHRP+1IfMysE7gSOAvoDp28j+f3d3fcMXrV4C3B7ffWGSY5bgn+/NLOuQBnQJcTnREREojYMmO/uC9z9K+Bx4PjkAu6+MWmzOYlBpSmFuef4nJm1AW4FpgWV3hs2ahERyQ9emZXTdgMWJ20vAfarXcjMzgMuARoBh9VXaZiW4y3uvsHdnyJxr3F34LowEYuIiHwbZjbKzKYkLaN2pB53v9Pd+wCXA7+tr3yYluO7wOCg8lKg1MymVe0TEREB8Aie5XD3scDYFEWWAj2StrsH++ryOPC3+s6baoacziSaq03NbB++fm9IK6BZfRWLiIhkwGSgn5ntTCIpngackVzAzPq5+yfB5jHAJ9QjVcvxe8BZJLJw8siejcCVocMWEZG8UJmFe47uXm5m5wMvAoXA/e4+y8zGAFPcfTxwvpkdQWJA6XrgJ/XVm2qGnIeAh8zspOB+o4iISJ2i6FYNed4JwIRa+65OWr9oe+sMMyDnbTO7z8xeADCz/mZ2zvaeSEREJFeEGZDzQLBcFWzPA54A7gtzgiYd2uxYZHmgc5uybIfQoBW3K852CA1W2aZyJjTbPdthNFhHf/lxtkPISzF6KUeolmMHdx8HVEKifxeoiDQqERGRLArTctxsZu0JZhQws/2BkkijEhGRnOMxajqGSY6XAOOBPmb2NtARODnSqEREJOfk1Sur3H2amR0C7EbiWce57q6bZSIiElv1JkczawKcCwwn0bX6ppnd5e5bow5ORERyR2Wedas+DGwC7gi2zwAeIfFeRxERkdgJkxwHunvyu7FeM7PZUQUkIiK5KVuTAEQhTHKcZmb7u/skADPbD5gSbVgiIpJrsvTKqkiESY5DgHfMbFGw3ROYa2YzAXf3QZFFJyIikgVhkuPIyKMQEZGcV5lP3aruvjATgYiIiDQUYVqOIiIi9YrTgJwwc6uKiIjkFbUcRUQkLfJtEgAREZF6xahXVd2qIiIitanlKCIiaRGnV1ap5SgiIlKLWo4iIpIWeTUJgIiISBjqVhUREYkxtRxFRCQt1HIUERGJMbUcRUQkLWLUcFRyFBGR9FC3qoiISIyp5SgiImmhV1aJiIjEmFqOIiKSFnF6ZZVajiIiIrWo5SgiImkRp3uOSo4iIpIWepRDREQkxtRyFBGRtFDLUUREJMbUchQRkbTQy45FRERqUbeqiIhIjKnlKCIiaaHnHBugot570OTwk8AKKJvxLqXvv1zjeJMRJ1LUs19QuBEFzVqw8Y7LE8cOOZ6iXQaAGeWff8zWV5/KdPiRm/PhW/zr4Zvwygr2G3ESRxz/s22Wm/7eyzz454u5+LrH6dlnIAvnz2TcvdcmDrrzvZPPZdC+R2Qu8AxoP+IgdrtuNFZYyNLHnuLzO+6rcbxJ9y70//MfaNS+HWXrS/jovNGULl8JwBHLpvPFnE8A2Lp0OR/+zwUZjz9qHY4cTv9br8IKC1j84D9Z8Md7ahxv0qMrg+66nkYdEtdn+jmXsXVp4vo06d6FPf96HU27d8bdmXLCL9iyaGk2vobIdolHcjSjyZGnsHncnfimDbQ48zLKPp1J5doV1UW2vvZ09XqjfQ6msFN3AAq77kxht1344sEbAWh+xsUU9uhLxeL5mf0OEaqsrOCpB67jl1feQ5v2nfnTVacycMgIOnfvU6Pc1i2beeM/j9Kr76DqfV169OWS65+gsLCIkvWruW30SQwYfCiFhfH40aGggN1v+i3Tfvhzti5bwX4vPsHqF19j87wF1UV2veZSlo8bz/Jx42k7fBh9r/o1s86/AoCKraVMOvzkbEUfvYICBvzpat7//k/ZunQlB735JKuef5UvPv60usgeN/6GpX9/hqWP/Zv2h+zHbr+/hOk/S/zhude9N/PpLXex5tV3KGzeDK+szNY3kQzQ3KoNTGGXXlSuX4OXrIXKCso+nkpx3z3rLF+8xxDK5kwNthwrLIKqpaAQ37wpM4FnyKL5M+nQuScdOvWgqKiYfQ44io+mvPqNci+Mu4PDjv0pRcWNqvc1aty0OhGWl5VmLOZMaT14T778bBFbFi7By8pZ8e8X6DjysBplmu/ah3VvvQ/A+rfeZ6eRI7IRala0GTqILz9dxJbPl+BlZSz/5wQ6ff/wGmVa7N6HtRMnAbD29ffYKTjeYvc+WFEha159B4CKzV9SuWVrZr+AZJRXetqXMMxspJnNNbP5ZjZ6G8cvMbPZZjbDzF4xs1711VlncjSzVmZ2o5k9YmZn1Dr211ARZ4i1aINvWl+9XblpA9aizbbLtmpLQev2lC+aB0DFss8pX/wJrX51Ha3OvZ7yz+ZQuW5lRuLOlA3rV9Gmfefq7dbtO1GyflWNMos/m82GdSsYMPiQb3x+4fwZ3HTp8dzymxM45WdXx6fVCDTuvBOly77uYShdtpLGnXeqUWbT7LnsdEyiK3mno4+gqGULitu2BqCgcSP2e/EJ9p3wGB2PqplU46BJ105sXbq8envL0hU07tqpRplNM+fS+fgjAeh0/JEUt2pBcbs2NO/Xm/KSTQz+x/9x0LtPs/v1l0FBLP4elwbEzAqBO4GjgP7A6WbWv1axD4Ch7j4I+CdwS331pvpJfQAw4CngNDN7yswaB8f2ryfYUWY2xcymPDjpo/piyKji3YdQNu9DCG4cF7TpQEG7zmy863ds/NtvKeq1K4Xd+tRTS7xUVlbyzCO3cPyPL9vm8V59BzH6tme45PrHeeWZeyn7Kn4tyFQ+ufY22h4wlP3++yRtDxzK1mUr8IpE9+BbQ77Le987lY9+dTm7jbmcpr16ZDnazJtz5S20+86+HPTu07Qbvi9blq7AKyqwwiLaHjiEOVfcwjvDT6HZzj3ofuYJ2Q5XIuTuaV9CGAbMd/cF7v4V8DhwfK24XnP3L4PNSUD3+ipNlRz7uPtod/+3ux8HTANeNbP29VXq7mPdfai7Dz1r/4H1Ff/W/IsNWMu21dsFLdvgX2zYZtlGuw9O6lKFon57UbH8Myj7Csq+onzBbAq79Y465Ixq03YnNiTdfy1Zu5LWbb9uHZVu3cyKxfP5y5izGXPBd1k4fwb33XYBiz6t+YdNp259aNS4GcsXf5Kx2KNWumIVjbt+3apu3LUTpStqtqpLV65mxk9/zXtHnML8G/4XgPKNm6o/D7Bl4RLWvzOZlnvunqHIM2PrspU06dalertpt86ULqvZs1K6fBXTTr+Qtw84kXnX/hmA8pJNbF26go0zPk50yVZUsOLZ/9J679p/0IukltzYCpZRtYp0AxYnbS8J9tXlHOCF+s6bKjk2NrPq4+5+PXAP8AZQb4LMpIrliyhs2xFr3R4KChOtw/kzv1GuoF0nrEkzKpZ9Vr3PN66nqEc/sAIoKKCoR18q18arW7VHn4GsXrGItauWUF5exgfvvsCAIV/fN2varCXX3fMWV9/xElff8RK9+g7inEvvoGefgaxdtYSKinIA1q1exqpln9GuY6qfu9yy8YOPaLZLT5r07IYVF9H5B0ex+sXXapQpbtcGzADofdHPWfaPfwFQ1LoV1qi4ukybYfuwed6nxEnJ1Jk079uLpr26YcXFdDn5aFY+X/N+dXH7r69Pn8tGseThxGjvDVNnUty6JY06JP5w7XDo/jUG8kj8eGVl+pekxlawjN3R+Mzsx8BQ4Nb6yqa6efQscBjw3+ov7v6gma0A7tjR4CLhlWz575M0P/lcKDDKZk6icu0KGh90NBUrFlEetICKdx/MVx9Pq/HRsnkfUNirHy3OvgLcKf98TnX5uCgsLOKks67k7ht/QWVlBfsdegJdevTlhSf/Qo+dBzBwaN0DTBbMncYrz9xHYVERZgWc/NPf0qJV2zrL5xqvqGDuFTcw+PG7scJClv3jX2ye+yl9fnMeG6fPYvWLE2l74L70u+rXuDsbJk1lzujrAGjebxf2uO1qqHQoMD67474ao1zjwCsqmHXJHxg2/j4oLGDJw0/xxZz59PvdBZRM+4hVz79G++/sx25jLgaHdW9PZtavxyQ+XFnJx1fewrDnH8TMKPlgFovufzK7X0jiaCmQfD+je7CvBjM7ArgKOMTd6703ZPX16ZrZzu7+Wa19u7h7qN8CJbdeEJ+xvWn29uG3ZzuEBq34qH2yHUKDVbapPNshNGhHf/lxtkNoyCyqik+9dGHaf98/cVuvlPGaWREwDzicRFKcDJzh7rOSyuxDYiDOSHcPdV8ozNCxbT0Rrz//RESkhmwMyHH3cuB84EVgDjDO3WeZ2RgzOy4odivQAnjSzD40s/H11Vtnt6qZ7Q4MAFqb2YlJh1oBTeqNWEREJAPcfQIwoda+q5PWt3tar1T3HHcDvg+0AY5N2r8J+Pn2nkhEROItTm/lqDM5uvszwDNmdoC7v5vBmERERLIqzD3HtcF0Ox8BmNkgM/ttxHGJiEiOydb0cVEIkxzvAa4AygDcfQZwWpRBiYhI7qn0yrQv2RImOTZz9/dr7dM4chERia0wM0ivMbM+gAOY2cnA8tQfERGRfJMXA3KSnAeMBXY3s6XAZ8CPI41KREQki+pNjsFMOEeYWXOgwN3j9bJDERFJi7xqOZrZJbW2AUqAqe7+YURxiYhIjgn5iqmcEGZAzlDglyReAdIN+AUwErjHzH4TYWwiIiJZEeaeY3dgsLt/AWBm1wDPAwcDUwnxRmUREYm/ysrsPXqRbmFajjsBya/3KAM6ufuWWvtFRERiIUzL8THgPTN7Jtg+Fvh7MEBndmSRiYhITsmbATmWGH3zIPACcFCw+5fuPiVY/1F0oYmIiGRHyuTo7m5mE9x9T2BKqrIiIpLfPIvTvaVbmG7VaWa2r7tPjjwaERHJWXnTrRrYD/iRmS0ENgNGolE5KNLIREREsiRMcvxe5FGIiEjOy6uWo7svBDCznYAmkUckIiKSZWGmjzsO+CPQFVgF9ALmAAOiDU1ERHJJNt+/mG5hJgH4A7A/MM/ddwYOByZFGpWIiOQcr/S0L9kSJjmWuftaoMDMCtz9NRLzrYqIiMRSmAE5G8ysBfAG8JiZrQK+iDYsERHJNR6juVXDJMfpwJfAxSRmxGkNtIgyKBERkWwKkxxHeGLag0rgIQAzmxFpVCIiknPy4lEOM/sVcC7Qp1YybAm8HXVgIiKSW/Jl+ri/k5hw/EZgdNL+Te6+LtKoREREsqjO5OjuJUAJcHrmwhERkVxVGaNu1TCPcoiIiOSVMANyRERE6hWnRznUchQREalFLUcREUmLvHiUQ0REZHvE6VEOdauKiIjUopajiIikRZy6VdVyFBERqUUtRxERSYs4Pcph7vFpBodhZqPcfWy242iIdG1S0/Wpm65Naro+uScfu1VHZTuABkzXJjVdn7rp2qSm65Nj8jE5ioiIpKTkKCIiUks+Jkf1+9dN1yY1XZ+66dqkpuuTY/JuQI6IiEh98rHlKCIiklLGk6OZXWVms8xshpl9aGb7pbn+Q83subD703jeNmZ2bqbOlw47GqOZdTWzf9ZxbKKZDQ3Wr0za39vMPtrxaL8dMzvLzLqGKPegmZ0cdn8a4orNNQrxuV+a2f9sY3/19zazvc3s6KRj15rZpdt7rnSo/f90hOf5gZn1T9q+1cw+Dn5H/svM2kQdg3xTRpOjmR0AfB8Y7O6DgCOAxZmMIUJtgMj/R2oI3H2Zu4f55Xhl/UUy5iyg3l/8WZA318jd73L3h+sptjdwdD1lMmW7/p+2hB35nfoDoH/S9svAwOB35Dzgih2oU76lTLccuwBr3L0UwN3XuPsyADMbYmavm9lUM3vRzLoE+yea2f8GrcyPzGxYsH+Ymb1rZh+Y2TtmttuOBGRm3w3qmWZmT5pZi2D/52b2+2D/TDPbPdjf0cxeDlq/95rZQjPrANwE9AnivDWovoWZ/TP4K/AxM7PtjK25mT1vZtOD735qJq5VcM5BwfoHZnZ1sD7GzH5e6y/9pmb2uJnNMbN/AU2D/TcBTYNYHguqLjSze4Jr95KZNd2e65EUX++kazonuMbN6ro2QStnKPBYEE9TM7vazCYH12ns9vy3qef632xm75vZPDP7TrC/mZmNM7PZQUvgPTMbGqdrZGY7mdnUYH0vM3Mz6xlsfxpcg+pWYBDDdDObDpwX7GsEjAFODWI4Nai+f3BtF5jZhTtyPXZQ8v/TfzKzV+zr3wfHBzH3NrO5ZvYw8BHQw8x+F+x7y8z+kfSd+5jZf4Lr/qaZ7W5mBwLHAbcG5+nj7i+5e3kQwySgewa/s1Rx94wtQAvgQxJ/Df0VOCTYXwy8A3QMtk8F7g/WJwL3BOsHAx8F662AomD9COCpYP1Q4LltnPsb+4EOwBtA82D7cuDqYP1z4IJg/Vzg3mD9L8AVwfpIwIN6elfFlnS+EhI/2AXAu8Dw7bxeJ1V992C7dYau1WgSv7BaA5OBF4P9rwG7JX9X4JKk8w8CyoGhwfYXSXX2Do7tHWyPA368gz9HvYPrflCwfT9waYhrMzSpjnZJ648AxwbrDwInb+OcDwInhzjHH4P1o4H/BuuXAncH6wNjfI1mBT9r5wc/Nz8CegHvBsevBS4N1mcABwfrtyb9PJ0F/CWpzmuDeBuT+P9sLVC8I9dkB69hVVxFQKtgvQMwH7CgTCWwf3BsXxK/45oALYFPkr7zK0C/YH0/4NVU1zM49uyO/gxo+XZLRudWdfcvzGwI8B1gBPCEmY0GppD4pfFy8MdpIbA86aP/CD7/hpm1skQffEvgITPrR+KXQPEOhLQ/ie6Mt4PzNiKRxKo8Hfw7FTgxWB8OnBDE8x8zW5+i/vfdfQmAmX1I4n+kt7YjvpnAH83sZhJJ7E0zG0j01+pN4ELgM+B54Mig1bGzu881s95JZQ8G/i845wwzm5Gi3s/c/cNgfSqJ67GjFrv728H6o0G8/yH1tUk2wsx+AzQD2pH4xf5siPPuVs85kn9megfrw4H/BXD3j2J8jd4BDiLxM3EDiT8ejcTPU7XgZ7KNu78R7HoEOCpFvc97orep1MxWAZ2AJSnKR8GAG8zsYBLJsFsQB8BCd58UrB8EPOPuW4GtZvYsgCV6pA4EnkxqgDdOeUKzq0j8sfRYqnISjYxPPO7uFST+Qp1oZjOBn5D4JTDL3Q+o62Pb2P4D8Jq7nxD8sp64A+EY8LK7n17H8dLg3wp27FqVJq1vdx3uPs/MBpNohVxnZq8A/yL6azWZRBfbAhL3PzoAPyfx3+nbqH09dqjLMLCt72mkvjYAmFkTEj0XQ919sZldS+Iv/TDqO0e6f2Zy6Rq9QeIP317AMyR6YpzEH1jfxrf6/yhNfgR0BIa4e5mZfc7X12NziM8XABvcfe8wJzOzs0iMzzjc3fW8XRZkekDObkHrpcrewEJgLtDREgN2MLNiMxuQVK7qXttwoMTdS0h0+S0Njp/1/9u7e9CmoiiA4/+Dg6VWpLsUwaJSWgRxcxKhOPixWAcVQQoOOuuqQkF014a6KAiKowgiCJV+oKhoEa2Kgw4OIirVQq1VOQ7nPPt8xOSlzUcbzg8K5eXj3pwk79577kmywC49ALaJSKff/yoR2VDmNuPAfr9+L9Dux6exFVrViFUOzqjqVSz1tIU6xEpV57BCqT5sJT2KpeRGilx9BDjgbXZjqdXETxFZyIo+j44kBt7+GKVjk35+kpPaJ5/RV1J5WS7+xaRfM11AT+qyZorRKHAIeKP2k/BfsIndP9kSVZ0Cpvw1CjbwJKr+PlqEdF/WAB99YNyOTQCKGQd2i0iLx20XgKp+A96KSB/8Ld7ZXKQdRGQncBLYo6oz1X5QIZ96F+S0Yem9SU8tdQGn/WS8DzjnG/QTWAoiMSsiT4EC0O/HzgNn/XjemeQOEXmf/AGd2GBxzftzH9hU5j7OAL1iBSl9wAdgWlU/Y+nZ5zJfkLNYPcBDT8meAgbqGKtR7GTw3f9fSyY95gaxwqOXWDFFenU5BDyT+WKTanoNHPd224HBMrG5DBQ8lj+AS1gBxR1spZxLjvgXcxEbkCaBASw9+dUva5oYqeo7bGWaTKLGsNVSsa2HI8AFbytd6DOMFeCkC3IaIv2exibyWz3bdRh49Z/bPAJuYnuqt7GtkeS5Pgj0e9xfAHv9+HXghFjx23qsrmE1lvqeEJFCTR5gKGnJf0OOiNzDNrQfN7ovACKyEvitqr989j2YN1VSa0stVrXiqeFbqtrd4K7kIiIrsCKSWT/53QU2+kBVqzbXsYxi1ExEpM3rK1qxicJRVX3S6H6FysSPHVeuA7gh9nmmOWwvLoRSWoFhT58KcKyWA2NouCFPn7cAV2JgXJ6W/MoxhBBCqLf4btUQQgghIwbHEEIIISMGxxBCCCEjBscQSLKqnwAAABdJREFUQgghIwbHEEIIISMGxxBCCCHjD0rLxuuk+kZUAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A_FXdDMr8EEQ" + }, + "source": [ + "> Pela Análise de Correlação, vemos duas variáveis altamente correlacionadas com a variável-resposta, que são: 'Petal Width' e 'Petal Length', que são as duas variáveis mais importantes no dataframe. Lembram-se?\n", + ">> No entanto, confira a correlação entre 'Petal Width' e 'Petal Length'. Observou que a correlação entre elas é de 0.96? Estas variáveis são altamente correlacionadas..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "taei2KXSTmZ0" + }, + "source": [ + "### Usando SelectFromModel()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JLwboa9tTpBq", + "outputId": "ea927ac2-d0c4-4e10-ae72-7f9014aae8bb", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# A partir do Random Forest, seleciona features cuja importância seja maior que 0.15 e 0.45\n", + "sfm = SelectFromModel(rf, threshold = 0.15)\n", + "sfm_2 = SelectFromModel(rf, threshold = 0.45)\n", + "\n", + "# Treina o seletor\n", + "sfm.fit(X_treinamento, y_treinamento)\n", + "sfm_2.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SelectFromModel(estimator=RandomForestRegressor(bootstrap=True, ccp_alpha=0.0,\n", + " criterion='mse', max_depth=None,\n", + " max_features='auto',\n", + " max_leaf_nodes=None,\n", + " max_samples=None,\n", + " min_impurity_decrease=0.0,\n", + " min_impurity_split=None,\n", + " min_samples_leaf=1,\n", + " min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0,\n", + " n_estimators=100, n_jobs=None,\n", + " oob_score=False,\n", + " random_state=20111974,\n", + " verbose=0, warm_start=False),\n", + " max_features=None, norm_order=1, prefit=False, threshold=0.45)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2MiZrU56VzUW", + "outputId": "d64749e9-8883-4432-e68d-bfe4c1b8c7f1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Mostra as duas features mais importantes para sfm\n", + "for feature_list_index in sfm.get_support(indices = True):\n", + " print(l_iris_labels[feature_list_index])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Petal Length\n", + "Petal Width\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M0junBxr79Th", + "outputId": "e150591e-1db0-4754-8999-f5e198d3bd60", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Mostra as duas features mais importantes para sfm_2\n", + "for feature_list_index in sfm_2.get_support(indices = True):\n", + " print(l_iris_labels[feature_list_index])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Petal Width\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "neMolQ0gYtp7" + }, + "source": [ + "Selecionando somente os atributos mais importantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dXRWZgDeYxHS" + }, + "source": [ + "# Constroi um dataset contendo somente as variáveis mais importantes\n", + "# Nota: Neste caso, estamos a aplicar a transformação tanto na base de treinamento quanto de validação\n", + "X_treinamento_rfi = sfm.transform(X_treinamento)\n", + "X_teste_rfi = sfm.transform(X_teste)\n", + "\n", + "X_treinamento_rfi_2 = sfm_2.transform(X_treinamento)\n", + "X_teste_rfi_2 = sfm_2.transform(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1tmpt3YvZFvW", + "outputId": "a214e4c8-b1f9-4599-b018-757235a1aa0d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Criar um classificador Random Forest somente com as features mais importantes\n", + "clf_rfi = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50)\n", + "clf_rfi_2 = RandomForestClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50)\n", + "\n", + "# Treina o modelo com as features mais importantes\n", + "clf_rfi.fit(X_treinamento_rfi, y_treinamento)\n", + "clf_rfi_2.fit(X_treinamento_rfi_2, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=10000,\n", + " n_jobs=50, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 268 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "epVwhUeYZM7v", + "outputId": "1503fb45-653c-4c2a-9304-c3d0689b300d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "from sklearn.metrics import accuracy_score\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "\n", + "# Aplica o Classificador no dataframe teste\n", + "y_pred = clf_rfi.predict(X_teste_rfi)\n", + "\n", + "# Verifica acurácia\n", + "accuracy_score(y_teste, y_pred)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred) \n", + "index = ['setosa', 'versicolor', 'virginica'] \n", + "columns = ['setosa','versicolor', 'virginica'] \n", + "cm_df = pd.DataFrame(cm, columns, index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot = True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 269 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CA_rhTMiZbLN", + "outputId": "a1af75c9-690e-49a0-ed79-87259804b06b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Aplica o classificador na base de teste\n", + "y_pred_rfi = clf_rfi.predict(X_teste_rfi)\n", + "\n", + "# Avalia acurácia\n", + "accuracy_score(y_teste, y_pred_rfi)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred_rfi) \n", + "index = ['setosa','versicolor','virginica'] \n", + "columns = ['setosa','versicolor','virginica'] \n", + "cm_df = pd.DataFrame(cm,columns,index) \n", + "plt.figure(figsize=(10,6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 270 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lIYvP0Bq8ST_", + "outputId": "c16ef565-c421-42a2-a9c9-48fc04d4d6bc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Aplica o classificador na base de teste depois da análise de correlação\n", + "y_pred_rfi_2 = clf_rfi_2.predict(X_teste_rfi_2)\n", + "\n", + "# Avalia acurácia\n", + "accuracy_score(y_teste, y_pred_rfi_2)\n", + "\n", + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred_rfi_2) \n", + "index = ['setosa','versicolor', 'virginica'] \n", + "columns = ['setosa','versicolor', 'virginica'] \n", + "cm_df = pd.DataFrame(cm,columns, index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot = True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 271 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uWdAUMQoZtaV" + }, + "source": [ + "> Como podemos ver:\n", + "* Modelo original (com 4 atributos) presenta acurácia de 93.3%;\n", + "* Modelo reduzido (com 2 atributos) apresenta acurácia de 93%;\n", + "* Modelo reduzido 2 (com 1 atributo) apresenta acurácia de 93%.\n", + "\n", + ">> Ou seja, reduzimos o modelo de 4 para 1 atributo/variável e a acurária continua a mesma." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OfCq7UGIpSYg", + "outputId": "5bec1c14-5210-4e28-84a2-b795ef78fe5a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } + }, + "source": [ + "# Correlação dois a dois...\n", + "df_iris[['petal length', 'petal width']].corr()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
petal lengthpetal width
petal length1.0000000.962865
petal width0.9628651.000000
\n", + "
" + ], + "text/plain": [ + " petal length petal width\n", + "petal length 1.000000 0.962865\n", + "petal width 0.962865 1.000000" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 272 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BMfxK3UCbjfc" + }, + "source": [ + "## Feature Selection With XGBoost (Extreme Gradient Boosting)\n", + "> XGBoost, em geral, fornece melhores soluções do que outros algoritmos de Machine Learning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8ZYGjr0Su4y-", + "outputId": "919fa042-5b49-4378-a46b-cf33f6469e48", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "!pip install xgboost" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: xgboost in /usr/local/lib/python3.6/dist-packages (0.90)\n", + "Requirement already satisfied: scipy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.4.1)\n", + "Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.18.5)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "--vKKHVWbwGv" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "\n", + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_d5qWQmXgPIH", + "outputId": "1a2fe686-b70e-4812-d129-304cefd93611", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Cria um clasificador XGBoost\n", + "clf = XGBClassifier(n_estimators = 10000, random_state = 20111974, n_jobs = 50, max_depth = 5, learning_rate = 0.05)\n", + "\n", + "# Treina o classificador\n", + "clf.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Calcula o y_pred e avalia a qualidade do ajuste\n", + "y_pred = clf.predict(X_teste)\n", + "predictions = [round(value) for value in y_pred]\n", + "accuracy = accuracy_score(y_teste, predictions)\n", + "print(f\"Acurácia: {accuracy}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácia: 0.8666666666666667\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fTdKMOKdC2UA", + "outputId": "0421c20e-1af7-473b-f0fa-4a77c4d1d3dd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Adaptado de https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/\n", + "# Ajusta o ML usando cada importância calculada como threshold\n", + "\n", + "thresholds = sorted(clf.feature_importances_)\n", + "for thresh in thresholds:\n", + "\t# seleciona as features usando threshold\n", + "\tselection = SelectFromModel(clf, threshold=thresh, prefit=True)\n", + "\tselect_X_treinamento = selection.transform(X_treinamento)\n", + "\t\n", + " # treina o ML\n", + "\tselection_clf = XGBClassifier()\n", + "\tselection_clf.fit(select_X_treinamento, y_treinamento)\n", + "\t\n", + " # Avalia o ML\n", + "\tselect_X_teste = selection.transform(X_teste)\n", + "\ty_pred = selection_clf.predict(select_X_teste)\n", + "\tpredictions = [round(value) for value in y_pred]\n", + "\taccuracy = accuracy_score(y_teste, predictions)\n", + "\tprint(f\"Threshold= {round(thresh,2)}, n= {select_X_treinamento.shape[1]}, Acurácia: {round(accuracy*100.0,2)}\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Threshold= 0.009999999776482582, n= 4, Acurácia: 86.67\n", + "Threshold= 0.03999999910593033, n= 3, Acurácia: 86.67\n", + "Threshold= 0.44999998807907104, n= 2, Acurácia: 86.67\n", + "Threshold= 0.5, n= 1, Acurácia: 86.67\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zv2gbuc5glFJ", + "outputId": "490e0459-db4a-4406-f4f4-5f5d70519cce", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "# Calcula a importância das features\n", + "importances = clf.feature_importances_\n", + "\n", + "# Ordena as importâncias por ordem descendente\n", + "indices = np.argsort(importances)[::-1]\n", + "\n", + "# Organiza...\n", + "names = [iris.feature_names[i] for i in indices]\n", + "\n", + "# Barplot\n", + "plt.bar(range(X_treinamento.shape[1]), importances[indices])\n", + "\n", + "# Coloca o nome dos labels no eixo X\n", + "plt.xticks(range(X_treinamento.shape[1]), names, rotation=20, fontsize = 8)\n", + "\n", + "# Constroi o gráfico\n", + "plt.title(\"Feature Importance\")\n", + "\n", + "# Mostra o gráfico\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cXTwXiB_LVB3", + "outputId": "83b9f975-bd71-4604-aded-b8310da30193", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 405 + } + }, + "source": [ + "# Matriz de Confusão\n", + "from sklearn.metrics import confusion_matrix as cm\n", + "cm = cm(y_teste, y_pred) \n", + "index = ['setosa','versicolor','virginica'] \n", + "columns = ['setosa','versicolor','virginica'] \n", + "cm_df = pd.DataFrame(cm,columns,index) \n", + "plt.figure(figsize = (10, 6)) \n", + "cm_df.index.name = 'Actual'\n", + "cm_df.columns.name = 'Predicted'\n", + "sns.heatmap(cm_df, annot=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 278 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_ebv3nAzU2ac" + }, + "source": [ + "## Feature Selection using PCA (Principal Components Analysis)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8M5uO9r-Vtze" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "# Carregar as informações do dataframe Iris\n", + "carrega_df_iris()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wWS8bvXzX4Fg" + }, + "source": [ + "### Standardize the Data\n", + "* O PCA é afetado por escala, portanto, é necessário dimensionar as features/atributos antes de aplicar o PCA.\n", + "* Use o StandardScaler para padronizar os features/atributos usando com média = 0 e variância = 1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2oVG8_1HXweo" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.decomposition import PCA" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xYXnYebxclya" + }, + "source": [ + "Standardizing as features de X:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iDMzHm3mcpbs" + }, + "source": [ + "X_STD = StandardScaler().fit_transform(X_iris) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MmKMCuvMc63E" + }, + "source": [ + "pca_2c = PCA(n_components = 2)\n", + "X_PCA_2c = pca_2c.fit_transform(X_STD)\n", + "df_PCA_2c = pd.DataFrame(data = X_PCA_2c, columns = ['PCA1', 'PCA2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0Yfvb02JdV8B" + }, + "source": [ + "Vamos entender o que está acontecendo:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-PVc1vJ8d_w6" + }, + "source": [ + "Primeiramente, observe nosso array X abaixo. Cada coluna desse array representa uma coluna do dataframe df_iris. Por exemplo, a primeira coluna são os dados da variável 'Sepal Length'. Identificou?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BEp1JD0Odd3L", + "outputId": "28a25a6b-d24a-4e3d-cbf0-2f3af24b4298", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Listando as primeiras 5 linhas de X\n", + "X_iris[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[5.1, 3.5, 1.4, 0.2],\n", + " [4.9, 3. , 1.4, 0.2],\n", + " [4.7, 3.2, 1.3, 0.2],\n", + " [4.6, 3.1, 1.5, 0.2],\n", + " [5. , 3.6, 1.4, 0.2]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 286 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "41-KcSTneURx" + }, + "source": [ + "Segundo, com a standardização, construimos o array X_STD, que mostramos abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "igBQNHS5eaND", + "outputId": "93a6ece8-138e-4f56-f44a-061c45c7380e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_STD[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.90068117, 1.01900435, -1.34022653, -1.3154443 ],\n", + " [-1.14301691, -0.13197948, -1.34022653, -1.3154443 ],\n", + " [-1.38535265, 0.32841405, -1.39706395, -1.3154443 ],\n", + " [-1.50652052, 0.09821729, -1.2833891 , -1.3154443 ],\n", + " [-1.02184904, 1.24920112, -1.34022653, -1.3154443 ]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 287 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TgRD7-qPjg29" + }, + "source": [ + "Veja abaixo a média e desvio-padrão do array X_STD:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M0VL4ilZjliL", + "outputId": "cd424bdd-ef89-45b1-c965-2695797f5a87", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "np.mean(X_STD),np.std(X_STD)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(-1.4684549872375404e-15, 1.0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 288 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pyDJwNCgju0O" + }, + "source": [ + "Temos média 0 e desvio-padrão 1, certo? É isso que queríamos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KB7R7OXQemze" + }, + "source": [ + "Por fim, a partir de X_STD, construimos o array X_PCA_2c, mostrado abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lNmAskXWerqG", + "outputId": "2f417913-1e00-445e-a990-6a1cbce2b417", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_PCA_2c[0:5]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-2.26470281, 0.4800266 ],\n", + " [-2.08096115, -0.67413356],\n", + " [-2.36422905, -0.34190802],\n", + " [-2.29938422, -0.59739451],\n", + " [-2.38984217, 0.64683538]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 289 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fT2N6Ym7fBt-" + }, + "source": [ + "Portanto, reduzimos (ou resumimos) o array X_STD de 4 dimensões para um array de 2 dimensões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cA54fhYgfQuC" + }, + "source": [ + "Finalmente, o dataframe final é mostrado abaixo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kAQ4O9EBfUlN" + }, + "source": [ + "df_PCA_final_2c = pd.concat([df_PCA_2c, df_iris[['target']]], axis= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JXrOdfSZPBS_", + "outputId": "21e43aaa-c78d-4779-86e4-e4ec6864b1e9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_PCA_final_2c.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PCA1PCA2target
0-2.2647030.480027setosa
1-2.080961-0.674134setosa
2-2.364229-0.341908setosa
3-2.299384-0.597395setosa
4-2.3898420.646835setosa
\n", + "
" + ], + "text/plain": [ + " PCA1 PCA2 target\n", + "0 -2.264703 0.480027 setosa\n", + "1 -2.080961 -0.674134 setosa\n", + "2 -2.364229 -0.341908 setosa\n", + "3 -2.299384 -0.597395 setosa\n", + "4 -2.389842 0.646835 setosa" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MEbvp3RFf-zs" + }, + "source": [ + "### Visualizar reultados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GEqP-NVngBO1", + "outputId": "8ff483a3-ba1b-4579-deb2-400020f310c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 523 + } + }, + "source": [ + "fig = plt.figure(figsize = (8,8))\n", + "ax = fig.add_subplot(1,1,1) \n", + "ax.set_xlabel('PCA1', fontsize = 15)\n", + "ax.set_ylabel('PCA2', fontsize = 15)\n", + "ax.set_title('2 componentes PCA', fontsize = 20)\n", + "targets = ['setosa', 'versicolor', 'virginica']\n", + "colors = ['r', 'g', 'b']\n", + "for target, color in zip(targets,colors):\n", + " indicesToKeep = df_PCA_final_2c['target'] == target\n", + " ax.scatter(df_PCA_final_2c.loc[indicesToKeep, 'PCA1']\n", + " , df_PCA_final_2c.loc[indicesToKeep, 'PCA2']\n", + " , c = color\n", + " , s = 50)\n", + "ax.legend(targets)\n", + "ax.grid()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pZaGiGnUl6ER" + }, + "source": [ + "O que significa reduzir para 2 dimensões um array com 4 dimensões?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xF-whgBmlHN1", + "outputId": "a23c21ca-cc81-48ee-f293-067c4ea585d1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 654 + } + }, + "source": [ + "X_new = pca_2c.inverse_transform(X_PCA_2c)\n", + "plt.figure(figsize=(10, 10), dpi=80)\n", + "plt.scatter(X_STD[:, 0], X_STD[:, 1], alpha=0.2)\n", + "plt.scatter(X_new[:, 0], X_new[:, 1], alpha=0.9)\n", + "plt.axis('equal');" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XvLDQ2JF5NP8" + }, + "source": [ + "### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DK3R415_5RzY", + "outputId": "7bb27d07-dda9-4f39-ec26-39b20f49a0ca", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "# calcula a correlação entre as colunas/variáveis do dataframe\n", + "correlacao= df_iris.corr().abs()\n", + "\n", + "# Seleciona o triângulo superior da matriz de correlação\n", + "correlacao = correlacao.where(np.triu(np.ones(correlacao.shape), k=1).astype(np.bool))\n", + "correlacao" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Sepal Lengthsepal widthpetal lengthpetal widthtarget2
Sepal LengthNaN0.117570.8717540.8179410.782561
sepal widthNaNNaN0.4284400.3661260.426658
petal lengthNaNNaNNaN0.9628650.949035
petal widthNaNNaNNaNNaN0.956547
target2NaNNaNNaNNaNNaN
\n", + "
" + ], + "text/plain": [ + " Sepal Length sepal width petal length petal width target2\n", + "Sepal Length NaN 0.11757 0.871754 0.817941 0.782561\n", + "sepal width NaN NaN 0.428440 0.366126 0.426658\n", + "petal length NaN NaN NaN 0.962865 0.949035\n", + "petal width NaN NaN NaN NaN 0.956547\n", + "target2 NaN NaN NaN NaN NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 294 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uLvvzpvl5Zy9", + "outputId": "02c8c610-efe1-45a0-e5c1-7bd308513e56", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 500 + } + }, + "source": [ + "fig, ax = plt.subplots(figsize=(8, 8)) \n", + "mask = np.zeros_like(df_iris.corr().abs())\n", + "mask[np.triu_indices_from(mask)] = 1\n", + "sns.heatmap(df_iris.corr().abs(), mask= mask, ax= ax, cmap='coolwarm', annot= True, fmt= '.2f')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 295 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xo-llZpb7JfO" + }, + "source": [ + "Pela Análise de Correlação, vemos duas variáveis altamente correlacionadas com a variável-resposta, que são: 'Peta Width' e 'Petal Length', que são as duas variáveis mais importantes no dataframe. Lembram-se?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kjPawS_dgSKU" + }, + "source": [ + "### Variância explicada\n", + "* Como vimos, reduzimos um array de informações de 4 dimensões para um array com 2 dimensões. Com isso, perde-se alguma informação relativa à variância. Mas quanto perdemos?\n", + "\n", + "* A Variância Explicada (ou Explained Variance, em inglês), mede o quanto de informação (variação) foi atribuída a cada um dos componentes principais. Usando o atributo explain_variance_ratio_, é possível ver que o primeiro componente principal contém 72,77% da variação e o segundo componente principal contém 23,03% da variação. Juntos, os dois componentes contêm 95,80% das informações. Portanto, perdemos quase nada em termos de informação e o modelo não é prejudicado por esta redução.\n", + "\n", + "\n", + "A resposta à essa pergunta é:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i6gcdvtYgwpX", + "outputId": "d416ed99-d2aa-4f64-cad9-9ba37903aa3e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.72962445, 0.22850762, 0.03668922, 0.00517871])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 298 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "71ubjjflQEUf" + }, + "source": [ + "Observe que o terceiro e quarto valores são muito baixo. Ou seja, baixa variabilidade explicada... Portanto, daqui já conseguimos ver que o número ideal de componentes são 2." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m_4TqauJvIvX" + }, + "source": [ + "### Quantos componentes escolher" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2NRgjCjvUli", + "outputId": "da0675c7-c382-48d7-eccb-1f00037e5aff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 279 + } + }, + "source": [ + "pca = PCA().fit(X_STD)\n", + "plt.plot(np.cumsum(pca.explained_variance_ratio_))\n", + "plt.xlabel('number of components')\n", + "plt.ylabel('cumulative explained variance');" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AvQ6KwQdwAdC" + }, + "source": [ + "**Interpretação**: Esta curva quantifica quanto da variância total de 4 dimensões está contida nos primeiros N componentes. Por exemplo, a primeira componente principal tem aproximadamente 95% da variação, enquanto que 2 componentes (os dois primeiros) explicam quase 100% da variabilidade. Portanto, em nosso caso, 2 componentes principais são suficientes para captar grande parte da variabilidade dos dados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S151TcjQw6vc" + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2dNWrsMCyUUE" + }, + "source": [ + "### Medindo o impacto" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ueFuNN47zMd6" + }, + "source": [ + "#### Treinar o modelo com X_PCA" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yb4dpTHPyYlU" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mr3tAGbjTET8" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_PCA_2c, y_iris, test_size = 0.2, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IzCZCBSmylwZ", + "outputId": "d8218700-7b4d-40b3-be83-dd2f87c8f400", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Optamos por 2 componentes principais\n", + "classifier_2c = RandomForestClassifier(max_depth = 2, random_state = 0)\n", + "classifier_2c.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=2, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=100,\n", + " n_jobs=None, oob_score=False, random_state=0, verbose=0,\n", + " warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 307 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BiDgWh2PzYEY" + }, + "source": [ + "#### Fazer as predições" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A7V8DWW4zVPs" + }, + "source": [ + "y_pred_2c = classifier_2c.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JTm4msQy2ezQ" + }, + "source": [ + "___\n", + "# **Exercícios**\n", + "* Para cada um dos dataframes a seguir, selecione os melhores atributos utilizando as seguintes técnicas técnicas:\n", + " * Random Forest\n", + " * XGBoost\n", + " * RFE" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "caFkC6oCmUKK" + }, + "source": [ + "## Exercício 1 - Breast Cancer" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vhOM-Z9zmf-f" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "cancer = load_breast_cancer()\n", + "X= cancer['data']\n", + "y= cancer['target']\n", + "\n", + "df_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n", + "df_cancer['target'] = df_cancer['target'].map({0: 'malign', 1: 'benign'})\n", + "df_cancer.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zA395jtOfGEl" + }, + "source": [ + "## Exercício 2 - Fraud Detection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "14fV0gz0flb8" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "url= 'https://raw.githubusercontent.com/MathMachado/Python_RFB/DS_Python/Dataframes/creditcard.csv?token=AGDJQ63IAZCFP7GTSZTOMAK5QBSP6'\n", + "df_CC= pd.read_csv(url)\n", + "df_CC.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qruqUDqnvMc" + }, + "source": [ + "## Exercício 3 - Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "trxK8YXNnsam" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "boston = load_boston()\n", + "X= boston['data']\n", + "y= boston['target']\n", + "\n", + "df_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-CawPH2nb5cl" + }, + "source": [ + "## Exercício 4 - Diabetes\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lVjBS7QcZuT" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "diabetes = load_diabetes()\n", + "X= diabetes['data']\n", + "y= diabetes['target']\n", + "\n", + "df_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n", + "df_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qP1vjDdylyHr" + }, + "source": [ + "## Exercício 5 - Crimes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fqLHDXbOl0Sf" + }, + "source": [ + "url= 'https://raw.githubusercontent.com/MathMachado/Python_RFB/DS_Python/Dataframes/Crime.txt?token=AGDJQ665WUIWIEKDPK6WO625P3QUQ'\n", + "df_Crime = pd.read_table(url, sep=',', na_values='?')\n", + "df_Crime.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fxhTXj6Ll7wB" + }, + "source": [ + "df_Crime.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3b-Yv2HUmoI" + }, + "source": [ + "## Exercício 6 - Titanic" + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB11__DataViz_Matplotlib & Seaborn_hs.ipynb b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_hs.ipynb new file mode 100644 index 000000000..4ec3664e4 --- /dev/null +++ b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_hs.ipynb @@ -0,0 +1,1246 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled31.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oRokSLxEMgDN" + }, + "source": [ + "## Referência\n", + "* [Visualization](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html)\n", + "* [Python Graph Galery](https://python-graph-gallery.com/all-charts/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IFiAWdKnFS5A" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "import bokeh # Library necessária ***\n", + "\n", + "plt.rcParams[\"figure.figsize\"] = [15, 12]\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UfrAHnWpJTwD" + }, + "source": [ + "## Séries temporais simples" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_PV_kTGRMq4B" + }, + "source": [ + "#### Série/Dados simulados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_yVTB9v0KQxp" + }, + "source": [ + "from datetime import datetime\n", + "\n", + "dt_hoje = datetime.strptime('2020-10-14', '%Y-%m-%d')\n", + "dt_inicio = datetime.strptime('2020-01-01', '%Y-%m-%d')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gMQx3JSlJz0R" + }, + "source": [ + "# Quantos dias desde a data inicial?\n", + "i_quantidade_dias = abs((dt_hoje - dt_inicio).days)\n", + "i_quantidade_dias" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tb70ycS_JWvQ" + }, + "source": [ + "np.random.seed(20111974)\n", + "\n", + "i_qtd_ativos = 4\n", + "df_series_temporais = pd.DataFrame(np.random.randn(i_quantidade_dias, i_qtd_ativos), index = pd.date_range(dt_inicio, periods = i_quantidade_dias)) #, columns = list('ABCD'))\n", + "df_series_temporais.columns = ['Ativo1', 'Ativo2', 'Ativo3', 'Ativo4']\n", + "\n", + "#serie_temporal = pd.Series(np.random.randn(i_quantidade_dias), index = pd.date_range(dt_inicio, periods = i_quantidade_dias))\n", + "df_series_temporais.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hPq0XtirNMhm" + }, + "source": [ + "## Gráfico de séries temporais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kEu3wDl9L92i" + }, + "source": [ + "df_series_temporais2 = df_series_temporais.cumsum()\n", + "plt.figure()\n", + "df_series_temporais2.plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oEQQHUG8KtAv" + }, + "source": [ + "Gráfico de 1 única série temporal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xqNCkZdIKh3L" + }, + "source": [ + "df_series_temporais3 = df_series_temporais['Ativo1']\n", + "plt.figure()\n", + "df_series_temporais3.plot()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "m5rMpulVKrSe" + }, + "source": [ + "df_series_temporais3 = df_series_temporais['Ativo1'].cumsum()\n", + "plt.figure()\n", + "df_series_temporais3.plot(kind = 'line')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wa4sXjcMNkzS" + }, + "source": [ + "Experimente kind = {'line', 'box', 'hist', 'kde'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8eAETzNARsxo" + }, + "source": [ + "### Se quisermos comparar horizontalmente\n", + "* No caso abaixo, estou a comparar as colunas 'Ativo1', 'Ativo2', 'Ativo3' e 'Ativo4' quanto ao conteúdo da linha 3 --> iloc[3]." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APnKHRMSbYMO" + }, + "source": [ + "df_series_temporais2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6a0FB-SPReD9" + }, + "source": [ + "plt.figure()\n", + "df_series_temporais2.iloc[3].plot(kind = 'bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qJ8SBoT6SSu0" + }, + "source": [ + "### Comparar grupos\n", + "* Neste caso, vou selecionar (ou dar um zoom) somente em alguns dias do dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kKeby_vwTB5j" + }, + "source": [ + "df_series_temporais2_zoom = df_series_temporais2[0:10]\n", + "df_series_temporais2_zoom" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_XBwdn_Sa8h" + }, + "source": [ + "df_series_temporais2_zoom.plot(kind = 'bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zru6GuoYTuzd" + }, + "source": [ + "#### Outra forma de visualizar o mesmo resultado:\n", + "* stacked bar plot --> Basta usar o parâmetro stacked = True" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lHY7A1RLTzaT" + }, + "source": [ + "df_series_temporais2_zoom.plot(kind = 'bar', stacked = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UWP6hLn8US1M" + }, + "source": [ + "### Se quiser visualizar o gráfico na horizontal..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7dtzx-vOUWNG" + }, + "source": [ + "df_series_temporais2_zoom.plot(kind = 'barh', stacked = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z22k7IOyU6la" + }, + "source": [ + "### Histogramas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LKLWYWYeU8UV" + }, + "source": [ + "df_series_temporais2.plot(kind = 'hist', bins = 30) # O que são bins?" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MjLO8BqUeQvP" + }, + "source": [ + "#### O que são bins?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dG4zhQExVbY1" + }, + "source": [ + "#### Histograma individual" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZNGWjh9LVdb7" + }, + "source": [ + "plt.figure()\n", + "df_series_temporais2['Ativo3'].diff().hist() # Veja abaixo melhores explicações sobre o método diff(axis, periods) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3LQlM_qjWd7g" + }, + "source": [ + "df_series_temporais2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "x3N6q_fTWl60" + }, + "source": [ + "df_series_temporais2.diff(axis = 0, periods = 1).head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LGknpyFaWqcZ" + }, + "source": [ + "df_series_temporais2.iloc[1][0] - df_series_temporais2.iloc[0][0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdjsYr4Wer73" + }, + "source": [ + "df_series_temporais2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Yq6TtAU2XAHL" + }, + "source": [ + "#### diff(axis = 1, periods = 1) aplica a diferença nas colunas! Veja abaixo:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6QRBLyBQXKq8" + }, + "source": [ + "df_series_temporais2.diff(axis = 1, periods = 1).head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "niDjEkSpYgAj" + }, + "source": [ + "### Histogramas em múltiplos gráficos" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4ie8toFUYlF-" + }, + "source": [ + "plt.figure()\n", + "df_series_temporais2.diff(axis = 0, periods = 1).hist(color ='g', alpha = 0.5, bins = 50)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r7W97FztGTMl" + }, + "source": [ + "## Boxplot" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q-19pTLZZKVj" + }, + "source": [ + "plt.figure()\n", + "boxplot = df_series_temporais2.boxplot(vert = True) # Observe o parâmetro vert = True" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aQ2qQetiGU8f" + }, + "source": [ + "plt.figure()\n", + "boxplot = df_series_temporais2.boxplot(vert = False) # Observe o parâmetro vert = False" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wo6AFzOPMvMf" + }, + "source": [ + "#### Dados sobre a qualidade de vinhos - White vs Red\n", + "\n", + "* O objetivo é avaliar a qualidade dos vinhos (tinto vs branco), numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aO9K8R9Qa9Uj" + }, + "source": [ + "url_tinto = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/Wine_red.csv'\n", + "url_branco = 'https://raw.githubusercontent.com/Hayltons/DSWP/master/Dataframes/Wine_white.csv'\n", + "df_vinho_tinto = pd.read_csv(url_tinto)\n", + "df_vinho_tinto[\"color\"] = 1 # --> Vinho Tinto\n", + "\n", + "df_vinho_branco = pd.read_csv(url_branco)\n", + "df_vinho_branco[\"color\"] = 0 # --> Vinho Branco" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "owdOjksbg7Dc" + }, + "source": [ + "# Empilhando os dataframes df_vinho_tinto e df_vinho_branco:\n", + "df_vinhos = pd.concat([df_vinho_tinto, df_vinho_branco], axis = 0)\n", + "df_vinhos.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zYniNn5PfGx9" + }, + "source": [ + "df_vinho_tinto.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KL7iW5mtgCre" + }, + "source": [ + "df_vinhos['quality'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "G_yOZ-Gqmscv" + }, + "source": [ + "df_vinhos['color'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IKTEbTW2jMVv" + }, + "source": [ + "#### Tratamento do nome das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JeXjuKNIm39F" + }, + "source": [ + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1Oo-6k2jh3bx" + }, + "source": [ + "df_vinhos.columns = [col.lower() for col in df_vinhos.columns]\n", + "\n", + "# substituir ' ' por '_' no nome das colunas:\n", + "df_vinhos.columns = [col.replace(' ', '_') for col in df_vinhos.columns]\n", + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eiMHK6aJjoZl" + }, + "source": [ + "df_vinhos.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sUNEzoC7j0PV" + }, + "source": [ + "print(f\"Média do vinho Branco: {df_vinho_branco['quality'].mean()}\")\n", + "print(f\"Média do vinho Tinto.: {df_vinho_tinto['quality'].mean()}\")\n", + "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tIBDUBI4n78b" + }, + "source": [ + "Abaixo, o mesmo cálculo, porém usando o artificio de procurar/selecionar o tipo que queremos no dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X1Nllwpxl228" + }, + "source": [ + "print(f\"Média do vinho Branco: {df_vinhos[df_vinhos['color'] == 0]['quality'].mean()}\")\n", + "print(f\"Média do vinho Tinto.: {df_vinhos[df_vinhos['color'] == 1]['quality'].mean()}\")\n", + "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GHjfSmExmg0u" + }, + "source": [ + "df_vinhos.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3ZsHlrWmLDQ" + }, + "source": [ + "df_vinhos[df_vinhos['color'] == 1]['quality']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "a-4XRBelnKCW" + }, + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "df_vinhos['quality'].value_counts().plot(kind = 'bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7HjKZ6Z1bkct" + }, + "source": [ + "A seguir, algo mais sofisticado, contendo título do gráfico, annotations e etc" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jB9BTwBOa7UA" + }, + "source": [ + "fig, ax = plt.subplots(figsize = (10, 6))\n", + "df_vinhos['quality'].value_counts().plot(kind = 'bar')\n", + "\n", + "# Título e label dos eixos X e Y\n", + "plt.title('Avaliação da qualidade do vinho', fontsize = 25)\n", + "plt.xlabel('Atributo: quality', fontsize = 10)\n", + "plt.ylabel('Quantidade', fontsize = 10)\n", + "\n", + "# Colocar grid no gráfico\n", + "ax.grid(True)\n", + "\n", + "# Configurar a legenda\n", + "#plt.legend()\n", + "\n", + "# Configurar limites do eixo Y\n", + "#plt.ylim(0, 5000)\n", + "\n", + "# Configurar limites do eixo X\n", + "#plt.xlim(0, 3000)\n", + " \n", + "# Show graphic\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w1CyCXVkmrFV" + }, + "source": [ + "df_vinhos['color'].value_counts().plot(kind = 'bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jU1AY-_wpU2h" + }, + "source": [ + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ke8nw1nIcFpT" + }, + "source": [ + "df_vinhos['fixed_acidity'].value_counts().sort_index()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "e0ayzbRanNDq" + }, + "source": [ + "df_vinhos['fixed_acidity'].value_counts().sort_index().plot(kind = 'area')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eSxvaczjoll-" + }, + "source": [ + "### Desafio: Tornar o gráfico abaixo mais informativo\n", + "* Por exemplo, mostrar qual a variável analisada, eixo X e Y, títulos e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RjzkMuPTn0yI" + }, + "source": [ + "l_colunas = df_vinhos.columns # automatizando\n", + "for caracteristica in l_colunas:\n", + " plt.figure() # Tire esta linha e veja o resultado\n", + " df_vinhos[caracteristica].value_counts().sort_index().plot(kind = 'area')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PYIjyMkVnWnr" + }, + "source": [ + "### Correlações\n", + "* Apresentar a tabela com a interpretação das correlações." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gn7xXclM7ewN" + }, + "source": [ + "### Introdução\n", + "O código abaixo gera dataframes para avaliarmos as correlações entre variáveis/dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4un3dsyZ7fFU" + }, + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "i_simulacoes = 5000\n", + "\n", + "# Definir a semente --> Reproducibilidade\n", + "np.random.seed(19741120)\n", + "\n", + "# Array de médias das amostras:\n", + "a_media = np.array([0.0, 5.0, 10.0])\n", + "\n", + "# Array com a matriz de covariância:\n", + "a_covariancia = np.array([\n", + " [ 3.40, -2.75, -2.00],\n", + " [ -2.75, 5.50, 1.50],\n", + " [ -2.00, 1.50, 1.25]\n", + " ])\n", + "\n", + "# Geração das amostras aleatórias usando f_media e eGenerate the random samples.\n", + "a_amostras = np.random.multivariate_normal(a_media, a_covariancia, size = i_simulacoes)\n", + "a_amostras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "akHw3Mym_FgQ" + }, + "source": [ + "A seguir, gráfico que mostra a correlação entre a_amostras[:, 0] e a_amostras[:, 1]:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTLIn1uwJoVi" + }, + "source": [ + "plt.figure(figsize= (12, 8))\n", + "ax = sns.regplot(x = a_amostras[:,0], y = a_amostras[:,1], color = 'g')\n", + "plt.xlabel('a_amostras[0]')\n", + "plt.ylabel('a_amostras[1]')\n", + "#plt.axis('equal')\n", + "plt.grid(True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JcermWt-Ar5c" + }, + "source": [ + "np.corrcoef(a_amostras[:, 0], a_amostras[:, 1])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ryLXMQ66_fce" + }, + "source": [ + "Gráfico da correlação entre a_amostras[:, 0] e a_amostras[:, 2]:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8Xp69Xgg9iRV" + }, + "source": [ + "plt.figure(figsize= (12, 8))\n", + "ax = sns.regplot(x = a_amostras[:,0], y = a_amostras[:,2], color = 'g')\n", + "plt.xlabel('a_amostras[0]')\n", + "plt.ylabel('a_amostras[2]')\n", + "#plt.axis('equal')\n", + "plt.grid(True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gw6OpxFBA5Sp" + }, + "source": [ + "np.corrcoef(a_amostras[:, 0], a_amostras[:, 2])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GmnKTqxQ_uZ9" + }, + "source": [ + "E por fim, gráfico com as correlações entre a_amostras[:, 1] e a_amostras[:, 2]:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yjWoFPhR_t3I" + }, + "source": [ + "plt.figure(figsize= (12, 8))\n", + "ax = sns.regplot(x = a_amostras[:, 1], y = a_amostras[:, 2], color = 'g')\n", + "plt.xlabel('a_amostras[1]')\n", + "plt.ylabel('a_amostras[2]')\n", + "#plt.axis('equal')\n", + "plt.grid(True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xnJkxZ25C7kX" + }, + "source": [ + "np.corrcoef(a_amostras[:, 1], a_amostras[:, 2])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qEttRQwgDGq_" + }, + "source": [ + "E a seguir, o pairplot para avaliarmos todas as colunas ao mesmo tempo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mkAJivoPC_OM" + }, + "source": [ + "sns.pairplot(pd.DataFrame(a_amostras))\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6FVQwuNP8w6s" + }, + "source": [ + "### Análise do dataframe df_vinhos" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N-Aa8wnh6rky" + }, + "source": [ + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZhtIILrs6vUT" + }, + "source": [ + "### Correlações entre um par de variáveis X e Y" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lJh2Comx6a_k" + }, + "source": [ + "np.corrcoef(df_vinhos['fixed_acidity'], df_vinhos['alcohol'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ifZybEAE68V9" + }, + "source": [ + "### Correlações do dataframe" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOCk4vhpnYn9" + }, + "source": [ + "correlacoes = df_vinhos.corr()\n", + "\n", + "top_correlacoes_cols = correlacoes.color.sort_values(ascending = False).keys()\n", + "top_correlacoes = correlacoes.loc[top_correlacoes_cols, top_correlacoes_cols]\n", + "dropSelf = np.zeros_like(top_correlacoes)\n", + "dropSelf[np.triu_indices_from(dropSelf)] = True\n", + "plt.figure(figsize = (15, 9))\n", + "sns.heatmap(top_correlacoes, cmap=sns.diverging_palette(220, 10, as_cmap = True), annot = True, fmt = \".2f\", mask = dropSelf)\n", + "sns.set(font_scale=1.5)\n", + "plt.show()\n", + "del correlacoes, dropSelf, top_correlacoes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SFqklDJf-8le" + }, + "source": [ + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H7hKbxfdBV8w" + }, + "source": [ + "### Avaliar o comportamento bivariado\n", + "* 2D Density Plot\n", + " * Útil para avaliarmos a relação entre 2 variáveis numéricas. O gráfico no centro mostra a correlação entre as variáveis enquanto os gráficos marginais mostra a distribuição das respectivas variáveis usando histogramas ou gráficos de densidade." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LllKqLx3_IIG" + }, + "source": [ + "sns.jointplot(x = df_vinhos['alcohol'], y = df_vinhos['density'], kind = \"scatter\", color = 'm', s=50, edgecolor = \"skyblue\", linewidth = 2)\n", + "plt.savefig('minha_figura.png')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "33yTNYN2K40X" + }, + "source": [ + "Mesmos dados, gráfico diferente --> Explorem as opções disponíveis: https://python-graph-gallery.com/82-marginal-plot-with-seaborn/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BVmAt0wCK1Ob" + }, + "source": [ + "sns.jointplot(x = df_vinhos['alcohol'], y = df_vinhos['density'], kind = \"reg\", color = 'm', )\n", + "plt.savefig('minha_figura.png')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4ixcDmeXIFQ1" + }, + "source": [ + "### Pairplot\n", + "* Verificar relacionamentos entre pares no dataframe." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lWqwaZ_lArji" + }, + "source": [ + "sns.pairplot(df_vinhos)\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vAhaEgyYtfX9" + }, + "source": [ + "Abaixo, gráfico segmentado por color:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jnu-giD_tcwd" + }, + "source": [ + "sns.pairplot(df_vinhos, hue = \"color\") # Compare os gráficos com e sem a opção hue\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vtOH-mTHLGC-" + }, + "source": [ + "df_vinhos.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dcaQ8aPaHwBB" + }, + "source": [ + "sns.lmplot(\"alcohol\", \"density\", df_vinhos, hue = \"color\", fit_reg = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pWsCs585LPyn" + }, + "source": [ + "sns.lmplot(\"alcohol\", \"density\", df_vinhos, hue = \"quality\", fit_reg = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5RwOiYi3OfD5" + }, + "source": [ + "### Boxplot" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZqIP5xUOMAqL" + }, + "source": [ + "df_vinhos.boxplot(column = 'alcohol', by = 'quality', figsize = (12, 8))\n", + "plt.xlabel('Quality', fontsize = 10, color= 'blue')\n", + "plt.ylabel('alcohol', fontsize = 10, color= 'blue')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lWypAe78YQNm" + }, + "source": [ + "## Exercícios" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YD8jgEZyYSHP" + }, + "source": [ + "### Exercício 1\n", + "* Análise gráfica das variáveis do dataframe IRIS.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h0F7uXixYVqx" + }, + "source": [ + "from sklearn.datasets import load_iris\n", + "\n", + "iris = load_iris()\n", + "X= iris['data']\n", + "y= iris['target']\n", + "\n", + "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n", + "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n", + "df_iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JdPniPYQlI8X" + }, + "source": [ + "sns.pairprot(pd.DataFrame)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yV5gDSF1YdGL" + }, + "source": [ + "### Exercício 2\n", + "* Usando o dataframe FIFA, responda:\n", + " * (1) Mostre o gráfico de barras com o número de jogadores por clube;\n", + " * (2) Mostre o boxplot/histograma dos salários dos atletas para os clubes Real Madrid, Barcelona Paris Saint-Germain Bayern Munich e Juventus." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "27NbnlDkYoeH" + }, + "source": [ + "df_FIFA_2[df_FIFA_2['club'].isin(\n", + " ['Real Madrid', 'FC Barcelona','Paris Saint-Germain','FC Bayern München'])].boxplot(column = 'wage_montante', by = 'club', figsize = (12, 8))" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP_h2.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP_h2.ipynb new file mode 100644 index 000000000..0cbbbaf5f --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning___DSWP_h2.ipynb @@ -0,0 +1,4001 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n", + "* Conceitos estatísticos de bias & variance;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n", + "* Como funciona: divide o dataframe de treinamento em k partes;\n", + " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n", + " * repete este processo k vezes, sendo que em cada iteração calcula as métricas desejadas;\n", + " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n", + "\n", + " A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **valor de k**:\n", + " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n", + " * Quanto maior o valor de k, menor o viés do CV;\n", + "\n", + "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HscfN-a1V043" + }, + "source": [ + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XRukccWQSklx" + }, + "source": [ + "## Medidas para avaliarmos a variabilidade presente nos dados\n", + "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n", + "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n", + "\n", + "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância --> Principal medida para medir a variabilidade presente nos dados.\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING** (= Parâmetros ótimos dos modelos de Machine Learning)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos parâmetros dos modelos de ML)\n", + "* Encontra os parâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os parâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "X, y = make_classification(n_samples = 1000, \n", + " n_features = 18, \n", + " n_informative = 9, \n", + " n_redundant = 6, \n", + " n_repeated = 3, \n", + " n_classes = 2, \n", + " n_clusters_per_class = 1, \n", + " random_state=i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gWy2IZh3s-o3" + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccjhGnzxtAaV" + }, + "source": [ + "y[0:30] # Semelhante aos casos de fraude: {0, 1}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR" + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs" + }, + "source": [ + "df_X.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "\n", + "* Dividir os dados/amostra em:\n", + " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n", + " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n", + "* Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_train, X_test, y_train, y_test = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "3c8ab56e-2746-4310-df58-9b16986b9413", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_train.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "7e53d785-2595-4ba6-c229-ac02b99d3c55", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_train.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "00356053-c127-40d1-8bdd-d769af9ef0e2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_test.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "b4f4b728-0bee-435e-e697-27768787d43e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_test.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "b0d2ab18-7386-461b-d5f5-8e1880496244", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "Função para plotar a Confusion Matrix extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n", + "\n", + "# Instancia com os parâmetros sugeridos para se evitar overfitting:\n", + "ml_DT= DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split = 2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, \n", + " class_weight = None, \n", + " presort = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gVLZznprx2YX", + "outputId": "956487e9-beb3-4638-c305-786d7e06c0c0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 120 + } + }, + "source": [ + "# Objeto configurado\n", + "ml_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=None, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "10fed276-0cf3-4149-e5d1-784e736a2841", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 120 + } + }, + "source": [ + "# Treina o algoritmo: fit(df)\n", + "ml_DT.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=None, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ohmGCDpfyhvV", + "outputId": "fee641eb-64d0-4072-874c-f704c6a70cfe", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_CV" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "10" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6exa9D8R2fDJ", + "outputId": "5bfc98af-bd00-440d-b504-ab499254c533", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT, X_train, y_train, cv = i_CV)\n", + "\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.8899999999999997\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uxoplcea0byV", + "outputId": "578c5e51-c311-4cdf-c5ad-0de8fedd4e17", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.87142857, 0.98571429, 0.85714286, 0.91428571, 0.9 ,\n", + " 0.95714286, 0.91428571, 0.92857143, 0.87142857, 0.94285714])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y3k-PcbN0o_i", + "outputId": "0334a08d-8d2b-4687-ccda-65c6eac86759", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_scores_CV.mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9142857142857144" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "8b157dfc-f416-49d2-d185-3cf8ebfa13b0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.87142857 0.98571429 0.85714286 0.91428571 0.9 0.95714286\n", + " 0.91428571 0.92857143 0.87142857 0.94285714]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_DT.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rfapj3OG13PG", + "outputId": "af6e5144-5cdb-4017-885e-e398508d9cf5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y_pred[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n", + " 1, 0, 0, 1, 1, 0, 1, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sc88ofqh16RT", + "outputId": "4c2d7859-fa1a-4ecb-ea61-9ec399e439de", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "12eb1946-18c6-4369-af9d-916b5a0fc42d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning. Ao todo serão ajustados 2X13X5X5X7= 4.550 modelos. Contando com 10 folds no Cross-Validation, então são 45.500 modelos.\n", + "d_parametros_DT= {\"criterion\": [\"gini\", \"entropy\"]} #, \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \"max_depth\": [None, 2, 5, 9, 15], \"min_samples_leaf\": [20, 40, 60, 80, 100], \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_parametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_train, y_train)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "# Definindo a função para o GridSearchCV\n", + "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_train, y_train, X_test, y_test, cv = i_CV):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs= -1, verbose= 10, scoring= 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_train, y_train)\n", + " tempo_elapsed= time()-start\n", + " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Parâmetros que otimizam a classificação:\n", + " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os parametros otimizados...\n", + " ml_Opt.fit(X_train, y_train)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = cross_val_score(ml_Opt, X_train, y_train, cv = i_CV)\n", + " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + "\n", + " # Faz predições com os parametros otimizados...\n", + " y_pred = ml_Opt.predict(X_test)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_test, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25" + }, + "source": [ + "# Invoca a função\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0" + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vv7GKBvs6Ybf" + }, + "source": [ + "# Função desenvolvida para Selecionar COLUNAS relevantes\n", + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_train, X_test, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_train, y_train)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_train_I = sfm.transform(X_train)\n", + " X_test_I = sfm.transform(X_test)\n", + " return X_train_I, X_test_I " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf" + }, + "source": [ + "X_train_DT, X_test_DT = seleciona_colunas_relevantes(ml_DT2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt" + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_train_DT, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT2, X_train_DT, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tc7esxqtq-Og" + }, + "source": [ + "****************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3" + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_parametros_DT, X_train_DT, y_train, X_test_DT, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q" + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SbS4ZKN8s-ee" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT3, X_train_DT, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_at3XP1Bq-qb" + }, + "source": [ + "***************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_test_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier)quanto para Regressão (RandomForestRegressor).\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * É um Boosting Ensemble Method (pois constrói muitas árvores). Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como Feature Selection, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer os dados sejam normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Desvantagens**\n", + " * **Recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais parâmetros do Random Forest." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia...\n", + "ml_RF= RandomForestClassifier(n_estimators=100, min_samples_split= 2, max_features=\"auto\", random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lYa9oaZW__o6" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_RF= {'bootstrap': [True, False]} #,\n", + "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n", + "# 'max_features': ['auto', 'sqrt'],\n", + "# 'min_samples_leaf': [1, 2, 4],\n", + "# 'min_samples_split': [2, 5, 10],\n", + "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat" + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_parametros_RF, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMJcAdLlTQa0" + }, + "source": [ + "## Visualizar o resultado\n", + "> Implementar a visualização do RandomForest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "X_train_RF, X_test_RF = seleciona_colunas_relevantes(ml_RF2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF2.fit(X_train_RF, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF2, X_train_RF, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF2.predict(X_test_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos parametros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "navUWMwHi44D" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name=\"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting vc Stacking\n", + "### **Bagging**\n", + "* Objetivo é reduzir a variância;\n", + "\n", + "#### Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_train (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_train;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n", + "\n", + "#### Vantagens\n", + "* Reduz overfitting;\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "___ \n", + "### **Boosting**\n", + "* Objetivo é melhorar acurácia;\n", + "\n", + "#### Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_train (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_train;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_train e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_train a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n", + "\n", + "#### Vantagens\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + "* Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fgUrkmPk4dr" + }, + "source": [ + "___\n", + "# STACKING\n", + "\n", + "![Stacking](https://github.com/MathMachado/Materials/blob/master/Stacking.png?raw=true)\n", + "\n", + "Kd a referência desta figura???" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0jxx3ETpOdm" + }, + "source": [ + "___\n", + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Quando nada funciona, AdaBoost funciona!\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## O que é AdaBoost (Adaptive Boosting)?\n", + "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n", + "\n", + "## Parâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "No exemplo a seguir, vou usar RandomForestClassifier com os parâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Parâmetros otimizados!\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)\n", + "# Instancia AdaBoostClassifier\n", + "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_AB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A4Cs81OLD40y" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_AB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os parametros otimizados...\n", + "y_pred = ml_AB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_parametros_AB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos parâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB=GradientBoostingClassifier(n_estimators=100, min_samples_split= 2)\n", + "\n", + "# Treina...\n", + "ml_GB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-dr6dyjdXwvd" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os parâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_train.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_parametros_GB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Parametros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_train_GB, X_test_GB = seleciona_colunas_relevantes(ml_GB2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_train_GB, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB2, X_train_GB, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_test_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Parâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os parâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB= XGBClassifier(silent=False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zAhsTtwGqMkG" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos parâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de parâmetros para XGBoost:\n", + "d_parametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_parametros_XGB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Parametros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_train_XGB, X_test_XGB= seleciona_colunas_relevantes(ml_XGB2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_train_XGB, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB2, X_train_XGB, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_test_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM\n", + "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "# **IMPORTANCIA DAS COLUNAS**\n", + "Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_train, y_train=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_train and y_train are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_train (pandas DataFrame)\n", + " \n", + " y_train (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_train.values, y_train.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_train.values, y_train.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_train.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_train, y_train, top_n=X_train.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Uf1RML7xETY" + }, + "source": [ + "# WOE e IV\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TBNRfYZCyhMP" + }, + "source": [ + "## Construção do exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gIIroyyP4ZRZ" + }, + "source": [ + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PzQQdrkf1ohX" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n", + "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n", + "df_X2['target']= df_y['target']\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-OpwIpx4hXJ" + }, + "source": [ + "df_X2['target'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yZfqSvbKzeJ3" + }, + "source": [ + "def Constroi_Buckets(df, i, k= 10):\n", + " coluna= 'v'+ str(i)\n", + " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n", + " df= df.drop(columns= [coluna], axis= 1)\n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V6Nrpsx60HD3" + }, + "source": [ + "for i in np.arange(1,19):\n", + " df_X2= Constroi_Buckets(df_X2, i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2Fbh41-03OB" + }, + "source": [ + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O9r5BeWVxIr3" + }, + "source": [ + "# Função para calcular WOE e IV\n", + "def calculate_woe_iv(dataset, feature, target):\n", + "\n", + " def codethem(IV):\n", + " if IV < 0.02: return 'Useless'\n", + " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n", + " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n", + " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n", + " elif IV >= 0.5: return 'Suspicious'\n", + " else: return 'None'\n", + "\n", + " lst = []\n", + " for i in range(dataset[feature].nunique()):\n", + " val = list(dataset[feature].unique())[i]\n", + " lst.append({\n", + " 'Value': val,\n", + " 'All': dataset[dataset[feature] == val].count()[feature],\n", + " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n", + " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n", + " })\n", + " \n", + " dset = pd.DataFrame(lst)\n", + " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n", + " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n", + " dset['Mean']= dset['All']/dset['All'].sum()\n", + " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n", + " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n", + " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n", + " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n", + "\n", + " dset['Predictive_Power']= dset['IV'].map(codethem)\n", + " iv = dset['IV'].sum() \n", + " dset = dset.sort_values(by='IV') \n", + " return dset, iv" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8WGjWH63nx_" + }, + "source": [ + "df_Lab = df_X2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-N6xr1MgxTiz" + }, + "source": [ + "def calcula_Predictive_Power(df_Lab, coluna):\n", + " print('WoE and IV for column: {}'.format(coluna))\n", + " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n", + " print(df)\n", + " print('IV score: {:.2f}'.format(iv))\n", + " print('\\n')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayqN_7WnxVq9" + }, + "source": [ + "for i in np.arange(1,19):\n", + " coluna= 'v'+str(i)+'_Bucket'\n", + " calcula_Predictive_Power(df_Lab, coluna)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aZUNOgmSgAmq" + }, + "source": [ + "!pip install featuretools" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_sxdONzsh9rb" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p5_ynGo1dBJJ" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TqJRJXUhiDqf" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n", + "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n", + "df_X2['id'] = range(0,1000)\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nR56bGGngk-W" + }, + "source": [ + "# Automated feature engineering\n", + "import featuretools as ft\n", + "import featuretools.variable_types as vtypes\n", + "\n", + "es= ft.EntitySet(id = 'simulacao')\n", + "\n", + "# adding a dataframe \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n", + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOJ4Tr5Ogk6M" + }, + "source": [ + "es['df_X2'].variables" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1uXPqHDZgkys" + }, + "source": [ + "variable_types = {'idade': vtypes.Categorical}\n", + " \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n", + "\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dnbYTBqugkvm" + }, + "source": [ + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I2v_jetdgkr7" + }, + "source": [ + "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZiRBvHXgkoJ" + }, + "source": [ + "feature_matrix.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DataFrames/master/creditcard.csv)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP_hs.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP_hs.ipynb new file mode 100644 index 000000000..fac30d1e5 --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning___DSWP_hs.ipynb @@ -0,0 +1,4316 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "> Cross-validation (CV) é uma técnica na qual treinamos nosso modelo usando o subconjunto do dataframe de treinamento X e validamos noutro subconjunto do dataframe de treinamento X. A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (=Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem o dados, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch\n", + "* Encontra os parâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target;\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os parâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV= 10 # Número de Cross-Validations\n", + "i_Seed= 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size= 0.3 # Proporção do dataframe de validação" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "X, y = make_classification(n_samples = 1000, n_features = 18, n_informative = 9, n_redundant = 6, n_repeated = 3, n_classes = 2, n_clusters_per_class = 1, random_state=i_Seed)" + ], + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bXG2uEFYwZAk", + "outputId": "cc865b0f-9b3c-4df4-a783-48484a08c784", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "X[0:1]" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0.06844089, 4.21184154, -2.5583024 , 3.66548195, -3.83515815,\n", + " 3.49985104, 2.49085623, 3.66548195, 0.24511712, 0.86717207,\n", + " 2.86554551, 0.49395636, -5.14859605, 2.86554551, 3.49985104,\n", + " -0.63061895, -0.97831983, -0.88826977]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wE-IZJfGwzvE", + "outputId": "dddf7c0f-ad67-42d2-ec50-6d9d95929e0a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y[0:30]" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional;\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas= ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "44232441-3030-4dfe-bd29-fd1473b70c3a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
00.0684414.211842-2.5583023.665482-3.8351583.4998512.4908563.6654820.2451170.8671722.8655460.493956-5.1485962.8655463.499851-0.630619-0.978320-0.888270
1-4.8240210.179509-2.9844731.033618-3.8934263.428734-3.3346051.033618-0.882780-0.7532811.441522-1.395514-4.0028801.4415223.4287340.3399201.891538-6.109676
21.389530-0.2264761.8774002.7134264.6302570.516455-3.7430272.7134261.2840392.030797-1.0955361.560159-1.014211-1.0955360.516455-1.4778450.9605262.060204
31.1458092.2559460.2073644.6658172.2946786.5013060.9647704.6658170.1194103.1963541.8947873.519138-4.7578071.8947876.501306-3.7890290.5794911.397106
4-0.9366463.697163-3.3636173.805126-1.7544304.9543460.4066053.805126-0.8247381.3825911.665704-0.649758-3.5130361.6657044.9543460.2570520.904244-3.071354
\n", + "
" + ], + "text/plain": [ + " v1 v2 v3 ... v16 v17 v18\n", + "0 0.068441 4.211842 -2.558302 ... -0.630619 -0.978320 -0.888270\n", + "1 -4.824021 0.179509 -2.984473 ... 0.339920 1.891538 -6.109676\n", + "2 1.389530 -0.226476 1.877400 ... -1.477845 0.960526 2.060204\n", + "3 1.145809 2.255946 0.207364 ... -3.789029 0.579491 1.397106\n", + "4 -0.936646 3.697163 -3.363617 ... 0.257052 0.904244 -3.071354\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "79840be6-361c-424d-a6bb-0fdf9acbe222", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "beae2b96-5d53-4870-af26-01dbeac1ab40", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "77235ef7-30e5-43b1-afa6-bb2eeb202f2b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_X.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
count1000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000000
mean-0.0851591.0342270.6574081.4053170.6872791.1315600.1080531.4053171.0070231.0488010.0792480.001650-0.3654380.0792481.131560-0.0277510.9846060.633624
std2.0022471.6315073.6087722.2568574.0195984.4818321.9813072.2568571.8632881.6439001.9492731.9326414.1606681.9492734.4818322.0654551.8505933.552991
min-6.944169-4.620754-16.300139-6.235192-12.454256-14.305401-6.152747-6.235192-5.484992-3.293216-7.135349-5.705500-9.120941-7.135349-14.305401-6.009023-5.035184-11.439074
25%-1.305566-0.089052-1.623657-0.152888-1.854645-1.684751-1.216983-0.152888-0.240908-0.012710-1.209675-1.292162-3.555363-1.209675-1.684751-1.436673-0.261610-1.691346
50%0.0525230.9941500.5738491.4499310.8123641.2815040.1670911.4499311.0661251.0128990.1803440.035237-0.9666380.1803441.281504-0.0001900.9757930.844784
75%1.3838532.0719953.0385862.8871413.4139524.0081031.4387192.8871412.2881882.1872021.4391991.3153422.7458061.4391994.0081031.3653692.2565043.109330
max4.9971727.35486011.7201658.49456612.84441815.9998036.2935508.4945668.1465596.5231806.2524485.53821611.2593506.25244815.9998036.5315617.64680212.090528
\n", + "
" + ], + "text/plain": [ + " v1 v2 ... v17 v18\n", + "count 1000.000000 1000.000000 ... 1000.000000 1000.000000\n", + "mean -0.085159 1.034227 ... 0.984606 0.633624\n", + "std 2.002247 1.631507 ... 1.850593 3.552991\n", + "min -6.944169 -4.620754 ... -5.035184 -11.439074\n", + "25% -1.305566 -0.089052 ... -0.261610 -1.691346\n", + "50% 0.052523 0.994150 ... 0.975793 0.844784\n", + "75% 1.383853 2.071995 ... 2.256504 3.109330\n", + "max 4.997172 7.354860 ... 7.646802 12.090528\n", + "\n", + "[8 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 242 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "* Neste fase, devemos selecionar amostras de treinamento para treinar o modelo de Machine Learning e validação, para validar o modelo de Machine Learning.\n", + "* Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_train, X_test, y_train, y_test = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "b986cda5-98f9-4dbe-b9ab-d4a7133b8c9d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_train.shape" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "4ace28f9-1d68-4bb6-ce5a-c5cc2fd9e2a6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_train.shape" + ], + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "d841fc6a-42ec-40a7-e300-afcc4d34e75d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_test.shape" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "156e39cf-80a9-4259-961d-a14ce1252e83", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_test.shape" + ], + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "50d1a229-5e17-4be8-c9f9-54bd55bc8b08", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": 22, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV\n", + "from sklearn.model_selection import cross_val_score\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": 23, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "Função para plotar a Confusion Matrix extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split= 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier\n", + "\n", + "# Instancia com os parâmetros sugeridos para se evitar overfitting:\n", + "ml_DT= DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split=2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, class_weight = None, \n", + " presort = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "3eaa0531-beb0-4ed7-b470-457b0b2c0a63", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Treina o algoritmo\n", + "ml_DT.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 252 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6exa9D8R2fDJ", + "outputId": "9d32930b-0aec-4322-d86d-da7f08869e55", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.44\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "1197dd8b-421b-47e0-866d-0200bae53b28", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n", + " 0.92857143 0.9 0.88571429 0.92857143]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_DT.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "90af8559-6487-42a2-e497-25288ab965bb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning. Ao todo serão ajustados 2X13X5X5X7= 4.550 modelos. Contando com 10 folds no Cross-Validation, então são 45.500 modelos.\n", + "d_parametros_DT= {\"criterion\": [\"gini\", \"entropy\"]} #, \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \"max_depth\": [None, 2, 5, 9, 15], \"min_samples_leaf\": [20, 40, 60, 80, 100], \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_parametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_train, y_train)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "# Definindo a função para o GridSearchCV\n", + "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_train, y_train, X_test, y_test, cv = i_CV):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs= -1, verbose= 10, scoring= 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_train, y_train)\n", + " tempo_elapsed= time()-start\n", + " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Parâmetros que otimizam a classificação:\n", + " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os parametros otimizados...\n", + " ml_Opt.fit(X_train, y_train)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = cross_val_score(ml_Opt, X_train, y_train, cv = i_CV)\n", + " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + "\n", + " # Faz predições com os parametros otimizados...\n", + " y_pred = ml_Opt.predict(X_test)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_test, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25", + "outputId": "da9fa734-cd1d-4731-d6c6-2ff2cbc1d379", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 520 + } + }, + "source": [ + "# Invoca a função\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 2 candidates, totalling 20 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.0s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.1s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.2s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1813s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.2s\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy'}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 1.3s remaining: 0.0s\n", + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 1.3s finished\n" + ], + "name": "stderr" + }, + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Invoca a função\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mml_DT2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbest_params\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mGridSearchOptimizer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mml_DT\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'ml_DT2'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md_parametros_DT\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_train\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_train\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_test\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_test\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mi_CV\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mGridSearchOptimizer\u001b[0;34m(modelo, ml_Opt, d_Parametros, X_train, y_train, X_test, y_test, cv)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'\\nDecisionTreeClassifier *********************************************************************************************************'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n\u001b[0;32m---> 15\u001b[0;31m \u001b[0mmax_depth\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_depth'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 16\u001b[0m \u001b[0mmax_leaf_nodes\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_leaf_nodes'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0mmin_samples_split\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'min_samples_leaf'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'max_depth'" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0" + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vv7GKBvs6Ybf" + }, + "source": [ + "# Função desenvolvida para Selecionar COLUNAS relevantes\n", + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_train, X_test, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_train, y_train)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_train_I = sfm.transform(X_train)\n", + " X_test_I = sfm.transform(X_test)\n", + " return X_train_I, X_test_I " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf" + }, + "source": [ + "X_train_DT, X_test_DT = seleciona_colunas_relevantes(ml_DT2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt" + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_train_DT, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT2, X_train_DT, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tc7esxqtq-Og" + }, + "source": [ + "****************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3" + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_parametros_DT, X_train_DT, y_train, X_test_DT, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q" + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SbS4ZKN8s-ee" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT3, X_train_DT, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_at3XP1Bq-qb" + }, + "source": [ + "***************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_test_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier)quanto para Regressão (RandomForestRegressor).\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * É um Boosting Ensemble Method (pois constrói muitas árvores). Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como Feature Selection, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer os dados sejam normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Desvantagens**\n", + " * **Recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais parâmetros do Random Forest." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu" + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia...\n", + "ml_RF= RandomForestClassifier(n_estimators=100, min_samples_split= 2, max_features=\"auto\", random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lYa9oaZW__o6" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_RF= {'bootstrap': [True, False]} #,\n", + "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n", + "# 'max_features': ['auto', 'sqrt'],\n", + "# 'min_samples_leaf': [1, 2, 4],\n", + "# 'min_samples_split': [2, 5, 10],\n", + "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat" + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_parametros_RF, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMJcAdLlTQa0" + }, + "source": [ + "## Visualizar o resultado\n", + "> Implementar a visualização do RandomForest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "X_train_RF, X_test_RF = seleciona_colunas_relevantes(ml_RF2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF2.fit(X_train_RF, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF2, X_train_RF, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF2.predict(X_test_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos parametros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "navUWMwHi44D" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name=\"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_train, \n", + " y_train, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting vc Stacking\n", + "### **Bagging**\n", + "* Objetivo é reduzir a variância;\n", + "\n", + "#### Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_train (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_train;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n", + "\n", + "#### Vantagens\n", + "* Reduz overfitting;\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "___ \n", + "### **Boosting**\n", + "* Objetivo é melhorar acurácia;\n", + "\n", + "#### Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_train (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_train;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_train e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_train a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n", + "\n", + "#### Vantagens\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + "* Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fgUrkmPk4dr" + }, + "source": [ + "___\n", + "# STACKING\n", + "\n", + "![Stacking](https://github.com/MathMachado/Materials/blob/master/Stacking.png?raw=true)\n", + "\n", + "Kd a referência desta figura???" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0jxx3ETpOdm" + }, + "source": [ + "___\n", + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Quando nada funciona, AdaBoost funciona!\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## O que é AdaBoost (Adaptive Boosting)?\n", + "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n", + "\n", + "## Parâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "No exemplo a seguir, vou usar RandomForestClassifier com os parâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Parâmetros otimizados!\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)\n", + "# Instancia AdaBoostClassifier\n", + "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_AB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A4Cs81OLD40y" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_AB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os parametros otimizados...\n", + "y_pred = ml_AB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_parametros_AB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos parâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB=GradientBoostingClassifier(n_estimators=100, min_samples_split= 2)\n", + "\n", + "# Treina...\n", + "ml_GB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-dr6dyjdXwvd" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os parâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_train.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_parametros_GB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Parametros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_train_GB, X_test_GB = seleciona_colunas_relevantes(ml_GB2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_train_GB, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB2, X_train_GB, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_test_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Parâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os parâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB= XGBClassifier(silent=False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zAhsTtwGqMkG" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB, X_train, y_train, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_test, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos parâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de parâmetros para XGBoost:\n", + "d_parametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_parametros_XGB, X_train, y_train, X_test, y_test, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Parametros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_train_XGB, X_test_XGB= seleciona_colunas_relevantes(ml_XGB2, X_train, X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_train_XGB, y_train)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB2, X_train_XGB, y_train, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_test" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_test_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_test, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM\n", + "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "# **IMPORTANCIA DAS COLUNAS**\n", + "Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_train, y_train=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_train and y_train are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_train (pandas DataFrame)\n", + " \n", + " y_train (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_train.values, y_train.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_train.values, y_train.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_train.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_train, y_train, top_n=X_train.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Uf1RML7xETY" + }, + "source": [ + "# WOE e IV\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TBNRfYZCyhMP" + }, + "source": [ + "## Construção do exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gIIroyyP4ZRZ" + }, + "source": [ + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PzQQdrkf1ohX" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n", + "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n", + "df_X2['target']= df_y['target']\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-OpwIpx4hXJ" + }, + "source": [ + "df_X2['target'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yZfqSvbKzeJ3" + }, + "source": [ + "def Constroi_Buckets(df, i, k= 10):\n", + " coluna= 'v'+ str(i)\n", + " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n", + " df= df.drop(columns= [coluna], axis= 1)\n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V6Nrpsx60HD3" + }, + "source": [ + "for i in np.arange(1,19):\n", + " df_X2= Constroi_Buckets(df_X2, i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2Fbh41-03OB" + }, + "source": [ + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O9r5BeWVxIr3" + }, + "source": [ + "# Função para calcular WOE e IV\n", + "def calculate_woe_iv(dataset, feature, target):\n", + "\n", + " def codethem(IV):\n", + " if IV < 0.02: return 'Useless'\n", + " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n", + " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n", + " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n", + " elif IV >= 0.5: return 'Suspicious'\n", + " else: return 'None'\n", + "\n", + " lst = []\n", + " for i in range(dataset[feature].nunique()):\n", + " val = list(dataset[feature].unique())[i]\n", + " lst.append({\n", + " 'Value': val,\n", + " 'All': dataset[dataset[feature] == val].count()[feature],\n", + " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n", + " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n", + " })\n", + " \n", + " dset = pd.DataFrame(lst)\n", + " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n", + " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n", + " dset['Mean']= dset['All']/dset['All'].sum()\n", + " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n", + " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n", + " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n", + " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n", + "\n", + " dset['Predictive_Power']= dset['IV'].map(codethem)\n", + " iv = dset['IV'].sum() \n", + " dset = dset.sort_values(by='IV') \n", + " return dset, iv" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8WGjWH63nx_" + }, + "source": [ + "df_Lab = df_X2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-N6xr1MgxTiz" + }, + "source": [ + "def calcula_Predictive_Power(df_Lab, coluna):\n", + " print('WoE and IV for column: {}'.format(coluna))\n", + " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n", + " print(df)\n", + " print('IV score: {:.2f}'.format(iv))\n", + " print('\\n')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayqN_7WnxVq9" + }, + "source": [ + "for i in np.arange(1,19):\n", + " coluna= 'v'+str(i)+'_Bucket'\n", + " calcula_Predictive_Power(df_Lab, coluna)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aZUNOgmSgAmq" + }, + "source": [ + "!pip install featuretools" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_sxdONzsh9rb" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p5_ynGo1dBJJ" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TqJRJXUhiDqf" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n", + "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n", + "df_X2['id'] = range(0,1000)\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nR56bGGngk-W" + }, + "source": [ + "# Automated feature engineering\n", + "import featuretools as ft\n", + "import featuretools.variable_types as vtypes\n", + "\n", + "es= ft.EntitySet(id = 'simulacao')\n", + "\n", + "# adding a dataframe \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n", + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOJ4Tr5Ogk6M" + }, + "source": [ + "es['df_X2'].variables" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1uXPqHDZgkys" + }, + "source": [ + "variable_types = {'idade': vtypes.Categorical}\n", + " \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n", + "\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dnbYTBqugkvm" + }, + "source": [ + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I2v_jetdgkr7" + }, + "source": [ + "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZiRBvHXgkoJ" + }, + "source": [ + "feature_matrix.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DataFrames/master/creditcard.csv)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP_hs3.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP_hs3.ipynb new file mode 100644 index 000000000..910b16443 --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning___DSWP_hs3.ipynb @@ -0,0 +1,6645 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n", + "* Conceitos estatísticos de bias & variance;\n", + "* Ver Sklearn.optimize: https://web.telegram.org/#/im?p=g497957288" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n", + "* Como funciona: divide o dataframe de treinamento em k partes;\n", + " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n", + " * repete este processo k vezes, sendo que em cada iteração calcula as métricas desejadas (exemplo: acurácia);\n", + " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n", + "\n", + " A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **valor de k**:\n", + " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n", + " * Quanto maior o valor de k --> menor o viés do CV --> Experimento Estatístico para mostrar o efeito.\n", + "\n", + "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HscfN-a1V043" + }, + "source": [ + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XRukccWQSklx" + }, + "source": [ + "## Medidas para avaliarmos a variabilidade presente nos dados\n", + "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n", + "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n", + "\n", + "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância --> Principal medida para medir a variabilidade presente nos dados.\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING** (= Parâmetros ótimos dos modelos de Machine Learning)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos parâmetros dos modelos de ML)\n", + "* Encontra os parâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os parâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": 73, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "X, y = make_classification(n_samples = 1000, \n", + " n_features = 18, \n", + " n_informative = 9, \n", + " n_redundant = 6, \n", + " n_repeated = 3, \n", + " n_classes = 2, \n", + " n_clusters_per_class = 1, \n", + " random_state=i_Seed)" + ], + "execution_count": 74, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gWy2IZh3s-o3", + "outputId": "ad659add-4519-4c5b-c6a2-8b0f1fa98196", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 238 + } + }, + "source": [ + "X" + ], + "execution_count": 75, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0.06844089, 4.21184154, -2.5583024 , ..., -0.63061895,\n", + " -0.97831983, -0.88826977],\n", + " [-4.8240213 , 0.17950903, -2.98447332, ..., 0.33992045,\n", + " 1.89153784, -6.10967565],\n", + " [ 1.38953042, -0.226476 , 1.8774004 , ..., -1.47784549,\n", + " 0.96052606, 2.06020368],\n", + " ...,\n", + " [ 1.62548685, 0.43377848, 4.93537285, ..., -4.61990917,\n", + " 0.18310709, 6.16040231],\n", + " [-2.40619087, -1.65474635, 2.64196493, ..., -1.21427845,\n", + " 0.83745861, 0.8254619 ],\n", + " [-4.00041881, 2.52475556, -4.15290177, ..., -0.51680266,\n", + " 1.72224835, -5.59558306]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 75 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccjhGnzxtAaV", + "outputId": "d42b942e-a902-488c-d585-5ecb5a2a98bc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y[0:30] # Semelhante aos casos de fraude: {0, 1}" + ], + "execution_count": 76, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 76 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": 77, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": 78, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "ae5defe5-050e-40ab-9910-005d7abdef8d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": 79, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
00.0684414.211842-2.5583023.665482-3.8351583.4998512.4908563.6654820.2451170.8671722.8655460.493956-5.1485962.8655463.499851-0.630619-0.978320-0.888270
1-4.8240210.179509-2.9844731.033618-3.8934263.428734-3.3346051.033618-0.882780-0.7532811.441522-1.395514-4.0028801.4415223.4287340.3399201.891538-6.109676
21.389530-0.2264761.8774002.7134264.6302570.516455-3.7430272.7134261.2840392.030797-1.0955361.560159-1.014211-1.0955360.516455-1.4778450.9605262.060204
31.1458092.2559460.2073644.6658172.2946786.5013060.9647704.6658170.1194103.1963541.8947873.519138-4.7578071.8947876.501306-3.7890290.5794911.397106
4-0.9366463.697163-3.3636173.805126-1.7544304.9543460.4066053.805126-0.8247381.3825911.665704-0.649758-3.5130361.6657044.9543460.2570520.904244-3.071354
\n", + "
" + ], + "text/plain": [ + " v1 v2 v3 ... v16 v17 v18\n", + "0 0.068441 4.211842 -2.558302 ... -0.630619 -0.978320 -0.888270\n", + "1 -4.824021 0.179509 -2.984473 ... 0.339920 1.891538 -6.109676\n", + "2 1.389530 -0.226476 1.877400 ... -1.477845 0.960526 2.060204\n", + "3 1.145809 2.255946 0.207364 ... -3.789029 0.579491 1.397106\n", + "4 -0.936646 3.697163 -3.363617 ... 0.257052 0.904244 -3.071354\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 79 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "4f22d899-818b-4def-b303-d6b41343bb12", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": 80, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 80 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "1b6b47df-d61a-49cc-9a64-7ee2133adefd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": 81, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 81 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "2d17c864-a0cd-4845-f908-16329f2a2844", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 317 + } + }, + "source": [ + "df_X.describe()" + ], + "execution_count": 82, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
count1000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000000
mean-0.0851591.0342270.6574081.4053170.6872791.1315600.1080531.4053171.0070231.0488010.0792480.001650-0.3654380.0792481.131560-0.0277510.9846060.633624
std2.0022471.6315073.6087722.2568574.0195984.4818321.9813072.2568571.8632881.6439001.9492731.9326414.1606681.9492734.4818322.0654551.8505933.552991
min-6.944169-4.620754-16.300139-6.235192-12.454256-14.305401-6.152747-6.235192-5.484992-3.293216-7.135349-5.705500-9.120941-7.135349-14.305401-6.009023-5.035184-11.439074
25%-1.305566-0.089052-1.623657-0.152888-1.854645-1.684751-1.216983-0.152888-0.240908-0.012710-1.209675-1.292162-3.555363-1.209675-1.684751-1.436673-0.261610-1.691346
50%0.0525230.9941500.5738491.4499310.8123641.2815040.1670911.4499311.0661251.0128990.1803440.035237-0.9666380.1803441.281504-0.0001900.9757930.844784
75%1.3838532.0719953.0385862.8871413.4139524.0081031.4387192.8871412.2881882.1872021.4391991.3153422.7458061.4391994.0081031.3653692.2565043.109330
max4.9971727.35486011.7201658.49456612.84441815.9998036.2935508.4945668.1465596.5231806.2524485.53821611.2593506.25244815.9998036.5315617.64680212.090528
\n", + "
" + ], + "text/plain": [ + " v1 v2 ... v17 v18\n", + "count 1000.000000 1000.000000 ... 1000.000000 1000.000000\n", + "mean -0.085159 1.034227 ... 0.984606 0.633624\n", + "std 2.002247 1.631507 ... 1.850593 3.552991\n", + "min -6.944169 -4.620754 ... -5.035184 -11.439074\n", + "25% -1.305566 -0.089052 ... -0.261610 -1.691346\n", + "50% 0.052523 0.994150 ... 0.975793 0.844784\n", + "75% 1.383853 2.071995 ... 2.256504 3.109330\n", + "max 4.997172 7.354860 ... 7.646802 12.090528\n", + "\n", + "[8 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 82 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "\n", + "* Dividir os dados/amostras em:\n", + " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n", + " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n", + "* Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": 83, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "ddea49d2-f1e3-4175-9941-ba5d1ae64f58", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": 84, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 84 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "7275edce-ac1f-4bcc-b149-30b6486eaad3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_treinamento.shape" + ], + "execution_count": 85, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 85 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "35abf0d9-546e-4950-b538-cee3e57bd683", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": 86, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 86 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "4b847a2d-4c78-4bc3-a0e2-a8a38bf7c1a7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_teste.shape" + ], + "execution_count": 87, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 87 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "d1c6be41-6108-436b-d0eb-6c4f5f116cdf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": 88, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score # Para o CV (Cross-Validation)\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": 89, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "Função para plotar a Confusion Matrix extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, \n", + " figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": 90, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n", + "\n", + "# Instancia (configuração do Decision Trees) com os parâmetros sugeridos para se evitar overfitting:\n", + "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split = 2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, \n", + " class_weight = None, \n", + " presort = False)" + ], + "execution_count": 91, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gVLZznprx2YX", + "outputId": "d07ef173-ad82-4397-ced7-a75d2233be38", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Objeto/classificador configurado\n", + "ml_DT" + ], + "execution_count": 92, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 92 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "9d1806d3-ea4f-47b3-da8c-eb0cbdd4caaf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Treina o algoritmo: fit(df)\n", + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": 93, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 93 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ohmGCDpfyhvV", + "outputId": "d4556530-84b1-414f-fb81-f82b0a405628", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_CV" + ], + "execution_count": 94, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "10" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 94 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6exa9D8R2fDJ", + "outputId": "d080c556-c4f6-49e3-f938-9144c15c750b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com k = 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT, X_treinamento, y_treinamento, cv = i_CV)\n", + "\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": 95, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.44\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uxoplcea0byV", + "outputId": "1d810e2d-c12e-4432-ee0b-3628d91afa5d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": 96, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.9 , 0.98571429, 0.85714286, 0.92857143, 0.88571429,\n", + " 0.94285714, 0.92857143, 0.9 , 0.88571429, 0.92857143])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 96 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y3k-PcbN0o_i", + "outputId": "610bc0fc-ddfe-4a45-8621-3fc755a750c4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_scores_CV.mean()" + ], + "execution_count": 97, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9142857142857144" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 97 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "c2c8e0be-6ef2-433b-b940-13c91d6e48ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": 98, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n", + " 0.92857143 0.9 0.88571429 0.92857143]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "# Faz predições usando o classificador (Decision Trees) para inferir na amostra de teste:\n", + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": 99, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rfapj3OG13PG", + "outputId": "ceb65e06-5029-4aa8-cbe9-5225d66f4776", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y_pred[0:30]" + ], + "execution_count": 100, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n", + " 1, 0, 0, 1, 1, 0, 1, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 100 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sc88ofqh16RT" + }, + "source": [ + "y[0:30]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "d56ad709-c966-472d-8e11-bd73c4f977f6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": 101, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t-KyMOWgRyQ4" + }, + "source": [ + "\n", + "\n", + "---\n", + "##### ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "---\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VTT_qynaPV6-", + "outputId": "5f6af706-b5b3-4b1b-f0bd-a1886f0a9e9f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "# Preparar o array de predições\n", + "a_scores_pred_treino = ml_DT.predict(X_treinamento)\n", + "a_scores_pred_treino[0:30]" + ], + "execution_count": 30, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0,\n", + " 0, 1, 0, 1, 1, 0, 0, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NgzcGE75PVKB", + "outputId": "259de4dd-4c60-4bed-b750-e6a7f51d40db", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "accuracy_score(y_treinamento, a_scores_pred_treino)" + ], + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DL-b5ehHSeaV" + }, + "source": [ + "---\n", + "#### Criar Modelo usando classificador Naive Bayes\n", + "---" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mG3gUR4aSwD3" + }, + "source": [ + "from sklearn.naive_bayes import GaussianNB" + ], + "execution_count": 33, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "N8KXRDsSS3uQ" + }, + "source": [ + "# Criando o modelo preditivo\n", + "modelo_v1 = GaussianNB()" + ], + "execution_count": 34, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tO9zI48tS3Wy", + "outputId": "dc906ec3-5010-486e-dbd8-78493fa23d2b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Treinando o modelo\n", + "modelo_v1.fit(X_treinamento, y_treinamento)" + ], + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "GaussianNB(priors=None, var_smoothing=1e-09)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5OdlSGHWS28K", + "outputId": "0a175639-5633-4b6d-a320-e8c929468659", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_pred_treino_NB = modelo_v1.predict(X_treinamento)\n", + "a_scores_pred_treino_NB[0:30]" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0,\n", + " 0, 1, 0, 1, 0, 0, 0, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aEFkIz3wS2gm", + "outputId": "2c656f9d-ba1c-47fc-80f6-98385c7420d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "accuracy_score(y_treinamento, a_scores_pred_treino_NB)" + ], + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.8942857142857142" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vrjgRbCUT2PB", + "outputId": "8dbd3d1e-b7a7-46c1-b8d5-0e62b172a199", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TESTE\n", + "a_scores_pred_teste_NB = modelo_v1.predict(X_teste)\n", + "accuracy_score(y_teste, a_scores_pred_teste_NB)" + ], + "execution_count": 46, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.92" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1AvybYmQT2AU", + "outputId": "83397313-5911-4d70-be99-0e73645455c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO **COM** CROSS VALIDATION\n", + "# Cross-Validation com k = 10 folds\n", + "a_scores_CV_NB = cross_val_score(modelo_v1, X_treinamento, y_treinamento, cv = i_CV)\n", + "\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV_NB.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV_NB.std(),4)}')" + ], + "execution_count": 45, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 89.71000000000001\n", + "std médio das Acurácias calculadas pelo CV: 3.3099999999999996\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b-QHuY26T1g3" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning. Ao todo serão ajustados 2X15X5X5X7= 5.250 modelos. Contando com 10 folds no Cross-Validation, então são 52.500 modelos.\n", + "#d_parametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n", + "# \"min_samples_split\": [2, 5, 350, 400], \n", + "# \"max_depth\": [None, 2, 15], \n", + "# \"min_samples_leaf\": [20, 80, 100], \n", + "# \"max_leaf_nodes\": [None, 2, 15]}\n", + "\n", + "# DICIONÁRIO ORIGINAL\n", + "d_parametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n", + " \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \n", + " \"max_depth\": [None, 2, 5, 9, 15], \n", + " \"min_samples_leaf\": [20, 40, 60, 80, 100], \n", + " \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}\n" + ], + "execution_count": 102, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BtajXuuUpGwq", + "outputId": "8bb5a299-00cc-48c0-a8c3-8c47232f8bf1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 340 + } + }, + "source": [ + "d_parametros_DT" + ], + "execution_count": 103, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': ['gini', 'entropy'],\n", + " 'max_depth': [None, 2, 5, 9, 15],\n", + " 'max_leaf_nodes': [None, 2, 3, 4, 5, 10, 15],\n", + " 'min_samples_leaf': [20, 40, 60, 80, 100],\n", + " 'min_samples_split': [2,\n", + " 5,\n", + " 10,\n", + " 30,\n", + " 50,\n", + " 70,\n", + " 90,\n", + " 120,\n", + " 150,\n", + " 180,\n", + " 210,\n", + " 240,\n", + " 270,\n", + " 350,\n", + " 400]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 103 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_parametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_treinamento, y_treinamento)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "# Definindo a função para o GridSearchCV\n", + "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs= -1, verbose= 10, scoring= 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n", + " tempo_elapsed= time()-start\n", + " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Parâmetros que otimizam a classificação:\n", + " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os parametros otimizados...\n", + " ml_Opt.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = cross_val_score(ml_Opt, X_treinamento, y_treinamento, cv = i_CV)\n", + " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + "\n", + " # Faz predições com os parametros otimizados...\n", + " y_pred = ml_Opt.predict(X_teste)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_teste, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": 104, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25", + "outputId": "d2a0bad2-3989-4441-efdf-8c94bdaa0a53", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "# Invoca a função com o modelo baseline\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)" + ], + "execution_count": 105, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.3s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.4s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.4s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.5s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1747s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0593s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0885s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1811s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Done 58 tasks | elapsed: 1.9s\n", + "[Parallel(n_jobs=-1)]: Done 186 tasks | elapsed: 2.8s\n", + "[Parallel(n_jobs=-1)]: Done 330 tasks | elapsed: 3.7s\n", + "[Parallel(n_jobs=-1)]: Done 506 tasks | elapsed: 4.8s\n", + "[Parallel(n_jobs=-1)]: Done 682 tasks | elapsed: 5.8s\n", + "[Parallel(n_jobs=-1)]: Done 890 tasks | elapsed: 7.0s\n", + "[Parallel(n_jobs=-1)]: Done 1098 tasks | elapsed: 8.2s\n", + "[Parallel(n_jobs=-1)]: Done 1338 tasks | elapsed: 9.6s\n", + "[Parallel(n_jobs=-1)]: Done 1578 tasks | elapsed: 11.0s\n", + "[Parallel(n_jobs=-1)]: Done 1850 tasks | elapsed: 12.7s\n", + "[Parallel(n_jobs=-1)]: Done 2122 tasks | elapsed: 14.3s\n", + "[Parallel(n_jobs=-1)]: Done 2426 tasks | elapsed: 16.1s\n", + "[Parallel(n_jobs=-1)]: Done 2730 tasks | elapsed: 17.9s\n", + "[Parallel(n_jobs=-1)]: Done 3066 tasks | elapsed: 19.7s\n", + "[Parallel(n_jobs=-1)]: Done 3402 tasks | elapsed: 21.7s\n", + "[Parallel(n_jobs=-1)]: Done 3770 tasks | elapsed: 23.8s\n", + "[Parallel(n_jobs=-1)]: Done 4138 tasks | elapsed: 26.2s\n", + "[Parallel(n_jobs=-1)]: Done 4538 tasks | elapsed: 28.6s\n", + "[Parallel(n_jobs=-1)]: Done 4938 tasks | elapsed: 31.0s\n", + "[Parallel(n_jobs=-1)]: Done 5370 tasks | elapsed: 33.4s\n", + "[Parallel(n_jobs=-1)]: Done 5802 tasks | elapsed: 35.7s\n", + "[Parallel(n_jobs=-1)]: Done 6266 tasks | elapsed: 38.1s\n", + "[Parallel(n_jobs=-1)]: Done 6730 tasks | elapsed: 40.7s\n", + "[Parallel(n_jobs=-1)]: Done 7226 tasks | elapsed: 43.4s\n", + "[Parallel(n_jobs=-1)]: Done 7722 tasks | elapsed: 46.0s\n", + "[Parallel(n_jobs=-1)]: Done 8250 tasks | elapsed: 48.9s\n", + "[Parallel(n_jobs=-1)]: Done 8778 tasks | elapsed: 51.7s\n", + "[Parallel(n_jobs=-1)]: Done 9338 tasks | elapsed: 54.8s\n", + "[Parallel(n_jobs=-1)]: Done 9898 tasks | elapsed: 57.8s\n", + "[Parallel(n_jobs=-1)]: Done 10490 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 11082 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 11706 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 12330 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 12986 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 13642 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 14330 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 15018 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 15738 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 16458 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 17210 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 17962 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 18746 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 19530 tasks | elapsed: 1.9min\n", + "[Parallel(n_jobs=-1)]: Done 20346 tasks | elapsed: 2.0min\n", + "[Parallel(n_jobs=-1)]: Done 21162 tasks | elapsed: 2.0min\n", + "[Parallel(n_jobs=-1)]: Done 22010 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 22858 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 23738 tasks | elapsed: 2.3min\n", + "[Parallel(n_jobs=-1)]: Done 24618 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 25530 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 26442 tasks | elapsed: 2.6min\n", + "[Parallel(n_jobs=-1)]: Done 27386 tasks | elapsed: 2.7min\n", + "[Parallel(n_jobs=-1)]: Done 28330 tasks | elapsed: 2.8min\n", + "[Parallel(n_jobs=-1)]: Done 29306 tasks | elapsed: 2.9min\n", + "[Parallel(n_jobs=-1)]: Done 30282 tasks | elapsed: 3.0min\n", + "[Parallel(n_jobs=-1)]: Done 31290 tasks | elapsed: 3.1min\n", + "[Parallel(n_jobs=-1)]: Done 32298 tasks | elapsed: 3.2min\n", + "[Parallel(n_jobs=-1)]: Done 33338 tasks | elapsed: 3.3min\n", + "[Parallel(n_jobs=-1)]: Done 34378 tasks | elapsed: 3.5min\n", + "[Parallel(n_jobs=-1)]: Done 35450 tasks | elapsed: 3.6min\n", + "[Parallel(n_jobs=-1)]: Done 36522 tasks | elapsed: 3.7min\n", + "[Parallel(n_jobs=-1)]: Done 37626 tasks | elapsed: 3.8min\n", + "[Parallel(n_jobs=-1)]: Done 38730 tasks | elapsed: 4.0min\n", + "[Parallel(n_jobs=-1)]: Done 39866 tasks | elapsed: 4.1min\n", + "[Parallel(n_jobs=-1)]: Done 41002 tasks | elapsed: 4.2min\n", + "[Parallel(n_jobs=-1)]: Done 42170 tasks | elapsed: 4.4min\n", + "[Parallel(n_jobs=-1)]: Done 43338 tasks | elapsed: 4.5min\n", + "[Parallel(n_jobs=-1)]: Done 44538 tasks | elapsed: 4.6min\n", + "[Parallel(n_jobs=-1)]: Done 45738 tasks | elapsed: 4.8min\n", + "[Parallel(n_jobs=-1)]: Done 46970 tasks | elapsed: 4.9min\n", + "[Parallel(n_jobs=-1)]: Done 48202 tasks | elapsed: 5.1min\n", + "[Parallel(n_jobs=-1)]: Done 49466 tasks | elapsed: 5.2min\n", + "[Parallel(n_jobs=-1)]: Done 50730 tasks | elapsed: 5.4min\n", + "[Parallel(n_jobs=-1)]: Done 52026 tasks | elapsed: 5.6min\n", + "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 5.6min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 70}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 87.14\n", + "std médio das Acurácias calculadas pelo CV: 4.33\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "12 v13 0.735896\n", + "0 v1 0.135030\n", + "9 v10 0.090888\n", + "6 v7 0.025768\n", + "1 v2 0.012418\n", + "3 v4 0.000000\n", + "4 v5 0.000000\n", + "5 v6 0.000000\n", + "7 v8 0.000000\n", + "8 v9 0.000000\n", + "10 v11 0.000000\n", + "11 v12 0.000000\n", + "2 v3 0.000000\n", + "13 v14 0.000000\n", + "14 v15 0.000000\n", + "15 v16 0.000000\n", + "16 v17 0.000000\n", + "17 v18 0.000000\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0", + "outputId": "48a1f7da-d77d-4630-c8c6-9d02d802971a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 753 + } + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": 106, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA4MAAALgCAYAAAAugKK6AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdd1RU1/428GeGMkNTBBRFLCBRFI3GWC7FFoliixpELAHUqNFEEkUxGnvFgt0k3uSNPZGiYmzRKAoCBhA7CcReEaQMxcCAMPP+4XV+TgDpHMrzWWvWCufsvc9zcNYyX/c++4iUSqUSREREREREVJ8EioVOQERERERERNWPxSAREREREVE9xGKQiIiIiIioHtIUOgAREVFtp1Qqcf/+fdy/fx8ymQx8HJ8qwsDAAKampujQoQMkEonQcYioDmMxSEREVA4FBQU4ceIEDhw4gNOnT0MmkwkdieoYTU1N2NvbY+TIkXB3d0ejRo2EjkREdYyIu4kSERGVzdGjRzF79mzcvXsXffv2xdChw2BrawsrKysYGRlBLOZTGFR+WVlZePr0Ka5cuYLTp0/hyJEjKCgogLe3N+bOnQtdXV2hIxJR3RDIYpCIiKiU7ty5gy+++AJnzpzB2LFjsXTpMlhZWQkdi+q4rKws7NixA6tWrYShoSE2b96MkSNHCh2LiGo/vlqCiIioNIKDg9GjRw88f/4coaEXsH//zywEqVoYGBjA29sbf/99C/3794ezszO++eYbPptKRBXGYpCIiKgEP/74IwYNGgQnJydcvPgHHBwchI5E9ZCpqSl++mkndu7chQ0bNsDFxQU5OTlCxyKiWozFIBER0VscOHAAn332GebP/wb79/8MqVQqdCSq5zw8PHDmzFmcP38ebm5uUCgUQkciolqKzwwSEREVIyYmBn369MH06dOxfr2v0HGI1ISHh+PDDx0xe/ZsrFq1Sug4RFT7cAMZIiKioqSmpsLGxgY9evRAUNAR7hBKNdKePXswadJEHDx4EB9//LHQcYioduEGMkREREVZvHgxxGIx9u3bX2sLwby8PHh4uEMsFsHXt/iZzUuXLsHZ+WOYmzeHVCrBO+9Y4euv5yIrK6vKM96+fRujR7ugSZPGkEolsLZuBx8fnzItfSzNfa5fvx5isajYT35+vlr7y5cvY8iQwWjUyBA6OlJ06dIZO3furNC9VgUPDw9MmDABs2bNQnZ2ttBxiKiWqZ1/uxEREVWhP//8Ez/88AN8fNagQYMGQscpF5lMBiengbh79+5b2124cAG9e/eCtrY2wsMj8Px5MlatWo1vv/0WAwcOqNLn0RITE+HgYI+MjAxERkYhIyMTa9eug4/Panh6zijVGKW9z4yMdABAWpoMCoWy0EdTU1PVNigoCD179oC+vj4uXYpBSkoq3N09MHXqlLcW1ULx8VmDjIwMrFu3TugoRFTLsBgkIiL6l2+++QZdu3aFm5ub0FHKRSaTwcHBHr1794av74a3tl2w4Bs0btwYe/bsRevWrdGgQQOMHj0an3/+OSIjI3H58uVyZXj8+DFWrlyJ4cM/KrbNypUr8OLFC/zyywFYWlpCIpFg+PDhWLBgIXbs2IH4+PhKu8/09FfFoL6+fonZ5837GmZmZti7dx+srKygp6cHLy8vTJw4EUuXLkFaWlqJY1SnJk2a4JtvFmD9+vWQyWRCxyGiWoTFIBER0RuePHmCEydOYPbsORCJRELHUenTpzf09HTx4sWLQucWLlwAsViE0NBQAEBSUhK++momli5dVuK4zs6jsHbtOmhra6sd79DBBgDw4MGDUmfMy8tDYGAgBg8eBAuL1tix43s4OPQqtr2/vz/69u0LY2NjteMjR46EUqnEwYMH33q9stxneno6dHR01GYAiyKTyXD79m3Y2dlBIpGonXNxGY3s7GycOHGixOtVt2nTpkFDQwP79u0TOgoR1SIsBomIiN7w66+/Qk9PD8OHDxc6iho3N3fk5OTg2LFjhc75+fnBwsICvXv3BgBYW1tj6tSppRp35syZGDt2bKHjN25ch0gkgo2NTYlj3LhxA7NmzUTz5mYYP34ctLS0EBR0BA8fPoK3t3eRfR4/fozU1FR06NCh0DkrKytoaWnhypW3z0qW5T7T09NhYGBQYrvX++oV9Q8BRkZGAF79bmoaAwMDjBgxAocPHxY6ChHVIiwGiYiI3nD+/Hn069ev0EyZ0FxcXCCVShEQ4K92PDIyEvfu3YO7u0elzGQmJSXB19cX27Ztw6JFi4os1l6LiYlBjx7d0aVLZxw/fhyzZnnh4cNH+PXXoxg2bBg0NDTeeh0AMDY2KXROLBbDyMhI1aYypKenQ0tLC0uXLkHHjjbQ1dVB8+Zm8PScobbs08jICFZWVoiIiEBeXp7aGOHh4QCA58+fV1quyjRgwEBcvHgRubm5QkcholqCxSAREdEbbty4gS5d3hM6RiENGzbERx99hFOnTiEzM1N1/MCBXyASieDu7l6h8e/cuQOxWIRmzZpi+fJl8PFZg4ULF721z7Vr13D58mUsXLgQf/99C9988w2aNWtWquvl5OQAQLFFt7a2dqXujqlQKJCbmwtdXT2cPRuMZ88SsWXLVgQGBqJHj+5qO6euW7ceT548gbu7G+7evYuMjAzs3r0bO3Z8DwB4+fJlpeWqTF27dsXLly9LfNaSiOg1FoNERERvSEhIQIsWLYSOUSQ3N3fk5ubiyJEjAICCggIEBASgT58+sLCwqNDYVlZWUCiUSE1Nw549e7Fly2bY2v7nrRuSvPfee+jRowdWrlypeiXEs2fPSnU9XV1dACg0+/baq8JNt+w3UoyLF//A8+fJmDt3Lpo2bYqGDRti1KhR+O6773Hv3j2sW7dW1XbEiBE4ceIkbt26BRubDmjTxhKnTv2GgIBAACjVclMhmJubA0Cp/wyIiFgMEhERvSE7Oxt6enpCxyjSwIED0aRJEwQGBgAAzp07h6SkJHh4TKi0azRq1AgjR47EkSO/4vLly1i7dk2xbd9//3388Uckbt6MxbBhw7Bp00a0atUSI0YMx/Hjx1FQUFBs39cziCkpyYXO5efnIy0tDc2bN6/4DZXAyckJIpEIUVFRascHDRqEK1euQi7PRUpKKvz8/FXvm7SwsKzyXOXxeqfU6ng/JBHVDSwGiYiI3qBUKmvULqJv0tTUxNixY/H7778jPT0dfn4HoK+vj1GjRpVrvEePHmHy5E+xd+/eQudePyv4119/lTiOjY0NNmzYiCdPnuKXXw4gLy8PI0YMR+vWrYp9L5+ZmRmaNm2KP//8s9C5uLg45Ofno1u37mW8o6Ll5eXhypUruH37dqFzubm5UCqVkEqlJY5z8eJFAICDg0Ol5Kpsr7+3rzfBISIqCYtBIiKiWsTNzR0vX77EsWPHcOTIEYwaNarcM5mNGzeGn58ftm7dUujl8leuXAEAtGnTptTjaWtrY9SoUTh58jc8ePAQU6d+hrCwC8W2HzduHEJDQ5GcrD47GBDgD01NTYwZM6YMd1O83Nxc9OrlgKlTpxQ6d/LkSQBAv34fqI55ec1C27bvqD0bqFAo8OOPP6B9+/awt7evlFxEREJjMUhERFSLdO3aFTY2Nli+fBlkMlmFlojq6Ohg/XpfXLlyBVOnTsGDBw+QnZ2NCxcuYMqUyTA0NISn55flGtvc3ByLFi3Cr78eLbbN/PnfwMTEBGPGuOLOnTuQy+Xw8/ODr68vFixYiJYtW6ranj17FmKxCN7ec8qcxcDAAEuXLkNoaCi8vGbhyZMnyMjIQEBAAGbNmonOnTvjs88+U7UfONAJ9+7dw4wZXyA1NRWJiYn47LOpiI2NxQ8//FhjZ46JiMqKxSAREVEt88knr3a5fPPdgm/y9p4DsVgEsVgEOztbAMDcud6qY25un6jaTp8+HQcPHsKdO3fQpUtnmJgYY8qUyejWrRsiI6NgaVn883Hbt29XjVnc5733uhTb39jYGOHhETAzM4OdnS0MDRti9epV2LRpM5YsWVLi76Es9+nt7Y2AgEDExMSga9f3YGraBIsXL8KUKVNw4UKY2mY1AwcOxKFDh3Hjxg1YWLSGtXU7PH36FGFh4ZwVJKI6RaTkwnIiIiIVkUgEPz9/jB49WugoRGUmFovg78/vLxGVSiBnBomIiIiIiOohFoNERERERET1EItBIiIiIiKieojFIBERERERUT3EYpCIiIiIiKgeYjFIRERERERUD7EYJCIionolLy8PHh7uEItF8PX1LVPf27dvY/RoFzRp0hhSqQTW1u3g4+MDhUJRRWmJiKoOi0EiIqJ64smTJxCLRXjw4IHQUQQjk8ng5DQQd+/eLXPfxMREODjYIyMjA5GRUcjIyMTatevg47Manp4zqiAtEVHVYjFIRERUT4SEhAgdQVAymQwODvbo3bs3fH03lLn/ypUr8OLFC/zyywFYWlpCIpFg+PDhWLBgIXbs2IH4+PgqSE1EVHVYDBIREdVA165dw8iRI2BiYgypVII2bSzh7T0HGRkZau2GDBmMd96xwu3btzFixHAYGxvB0LAhevfuhejoaFW7QYOc4O7uBgCwtLSAjo5Udbxt23dw/fp1dO78LnR0pCgoKAAAREREYPDgQTAyagSJRButW7eCp+cMpKamqmXo06c3WrVqiatXr6Jfv74wMNCHvr4eHB374/r166p2ffv2gb6+HjIzMwvdr4+PD8RiEX7//ffK+QUWISkpCV99NRNLly4rV39/f3/07dsXxsbGasdHjhwJpVKJgwcPVkZMIqJqw2KQiIiohomJiYG9vR0UCgUiIi4iJSUVW7Zsxb59+zBw4ADk5+er2mprayMlJQXjx4/D1Kmf4dGjxwgPj8CzZ8/w8ccjIZfLAQC//XYKs2fPBgDcu3cfOTmvjkskEvzzzz/48ktPDB8+HJs2bYZYLMa5c+fQr19fNGjQAJGRUUhNTcPu3XsQFBSEDz7opxr39RjJycmYNGkilixZiqSk5/jjj0jcuXMHjo79kZKSAgCYMmUqsrOzceDAgUL37O/vh5YtW8LR0bHI30lKSgrEYlGJn7fNzllbW2Pq1Kll/NN45fHjx0hNTUWHDh0KnbOysoKWlhauXLlcrrGJiITCYpCIiKiGmT3bC0ZGRggICES7du2gr6+PoUOHYvVqH0RHRyMgIECtfUZGBmbPnoPBgwdDT08PHTt2xLRp05GQkIAbN2689VoikQjJycn46KPhWL58BaZNmwaRSIR5875Go0aNsHv3HrRt2xb6+vro27cvfHzW4ObNm/Dz81ONoaGhAblcDm/vuejbty90dXXRqVMnrF27DqmpqdizZw8AYNSoUTA2NsauXTvVMsTHx+PGjRuYOHEixOKi/9fExMQECoWyxI+1tXV5fuUlSkpKAgAYG5sUOicWi2FkZKRqQ0RUW7AYJCIiqkEyMzMRERGBfv36QSKRqJ1zcnICAERHRxXq9+8ZtWbNmgEAEhISSrxmfn4+XF1dVT/LZDLExMSgb9++kEqlRV4nJOR8oXEGDhyo9nO/fv0AADdvvipIJRIJ3N3dER0djdjYWFU7P78DEIlEmDBhYolZhZKTkwPg1UxsUbS1tZGdnV2dkYiIKozFIBERUQ2SkJAAhUKB/fv3F1oCaW7eHMCrJYtv0tDQKPQc2+sZtjeXlBZHJBKpikcAePr0KQCoHXvN1NRUrc1rWlpahTIYGRkBgNqM2ZQpr5Zpvjk76O/vD0dHR7Rq1arErELR1dUF8Oq1FEXJzc1VtSEiqi1YDBIREdVAkydPLnYp5KFDhyv1WmKxGBoaGoWOK5XKYo+JRKJCYxTX9s1z1tbW6N27N/bv34/8/HxcvXoVf//9NyZOnFShe6hqrwvjlJTkQufy8/ORlpaG5s2bV3csIqIKYTFIRERUg5ibm0MsFuPhw4eCZWjRogVEIlGRS0yfPXumavOm3NzcQjudvt519PVs4mtTp36G5ORknDlzBgcO/AIjIyOMHDnyrZkqYwOZijAzM0PTpk3x559/FjoXFxeH/Px8dOvWvUquTURUVVgMEhER1SD6+vro1asXQkJCkJiYqHYuLCwMNjYdEBMTU66xX8/QFTXj96aGDRvC1tYWISEhqmflXjt9+jQAYMCAgYX6nTlzRu3n8+dfPVfYu3cftePOzs4wNjbGzz/vxy+//ILx48cXej7y34TeQAYAxo0bh9DQUCQnq88OBgT4Q1NTE2PGjKmyaxMRVQUWg0RERDXMmjVroaGhgWHDhiI+Ph5yuRwhISHw8HCHRCJBx44dyzWumdmrZYxRUVGQy+VvfZ5w7dp1yMrKwqRJE3H//n28ePECZ8+exaJFC2Fvbw9nZ2e19jo6Oli5cgXOnDmD7Oxs3LhxA/PmfY2mTZti9OjRam0lEgk8PDzg5+eHhIQETJr0abnupyqdPXsWYrEI3t5zVMfmz/8GJiYmGDPGFXfu3IFcLoefnx98fX2xYMFCtGzZUsDERERlx2KQiIiohunZsyfCwyNgbm4OBwd7NGhgAHd3Nzg7O+Ps2eBCO3yWlpubG3r16gUPD3e0aGH+1p1G7e3tERISCplMhq5d34OxsRGmT58GDw8PnDp1GpqammrttbW1sXPnLqxZ44OmTU1hZ2eLdu3aITj4XJEbq0yZMhUKhQJdu3ZF586dy3U/ZeXtPUe1nNTOzhYAMHeut+qYm9snb+1vbGyM8PAImJmZwc7OFoaGDbF69Sps2rQZS5YsqY5bICKqVCJlSWtFiIiI6hGRSAQ/P/9Cs1lUvEGDnBAREYHMzKxS94mNjcW773bCjz/+P3z6ac2bGaytxGIR/P35/SWiUgnkzCARERFVWFn/bdnXdz2aNm2K8ePHV1EiIiIqiWbJTYiIiIgqrqCgALm5ufjvf/+LvXv3wt8/oNxLXomIqOJYDBIREVG18Pf3h7u7G8zMzLB37z64uLgIHYmIqF5jMUhEREQV8ttvp0rVbty4cRg3blwVpyEiotLiM4NERERERET1EItBIiIiKrNBg5xgYKAvdAwiIqoAFoNERERUL8jlctU7BYv7TJ06Ra3P7du3MXq0C5o0aQypVAJr63bw8fGBQqEoNH5Z2hIR1QQsBomIiKhekEqlUCiURX6Cgo4AAEaPdlW1T0xMhIODPTIyMhAZGYWMjEysXbsOPj6r4ek5Q23ssrQlIqopWAwSERFRvfbixQt8+aUnXF1d4ejoqDq+cuUKvHjxAr/8cgCWlpaQSCQYPnw4FixYiB07diA+Pr5cbYmIagoWg0RERAJIS0uDl9csWFm1ga6uDkxNm2DIkMGIjo4u1PbcuXP48ENHNGzYAHp6uujQoT1Wr16N3NxctXZDhgzGO+9Y4caNG/jgg34wMNCHkVEjuLu7ISsrC/7+/njvvS7Q09NFmzaW2Lp1q1r/Pn16o1Wrlrh69Sr69esLAwN96OvrwdGxP65fv17iPV27dg0jR46AiYkxpFIJ2rSxhLf3HGRkZJT73qvDkiWLkZ6ejg0bNqod9/f3R9++fWFsbKx2fOTIkVAqlTh48GC52hIR1RQsBomIiAQwduwYBAYGYt++/UhLkyEyMgo6OjpwdOyPW7duqdqFh4fDyWkgjI2NERcXj+fPk7FgwUIsWrQQ8+Z9rTamtrY2UlJS8MUXn8PHZw2ePUvE/PnfYP/+/fjoo2HYvXsXDh8OwtOnCbC3t8fMmV8hKipK1V8ikSA5ORmTJk3EkiVLkZT0HH/8EYk7d+7A0bE/UlJSir2fmJgY2NvbQaFQICLiIlJSUrFly1bs27cPAwcOQH5+fpnv/d9SUlJKfOZPLBaVaRbu4cOH2L59O2bOnAkzMzPV8cePHyM1NRUdOnQo1MfKygpaWlq4cuVymdsSEdUkLAaJiIiqmVwuR3BwMAYNGgRbW1tIpVJYWFhg585dkEgkOH36tKrt0aO/QiqVYt269TAzM4Oenh7Gjx+PPn36YPfu3YXGzsjIwLx589GzZ0/o6+tj1qxZ0NfXx8WLF7Fz5y5YWFjA0NAQc+e+KiTPnTun6quhoQG5XA5v77no27cvdHV10alTJ6xduw6pqanYs2dPsfc0e7YXjIyMEBAQiHbt2kFfXx9Dhw7F6tU+iI6ORkBAQJnv/d9MTEyKfebvzY+1tXWp/yxWrVoJqVSKmTNnqR1PSkoCABgbmxTqIxaLYWRkpGpTlrZERDUJi0EiIqJqpq2tjSZNmuDIkSMICgrCy5cvAQANGjRAcnIKPD09VW3XrVuPzMwstGzZUm0MCwsLZGRkQCaTFRrfwcFB9d+ampowMjJC69at0axZM9VxU1NTAEBSUmKh/gMHDlT7uV+/fgCAmzdvFHk/mZmZiIiIQL9+/SCRSNTOOTk5AQCio6PKfO9V7dGjR9izZw88PT3RqFEjtXM5OTmqvEXR1tZGdnZ2mdsSEdUkLAaJiIiqmVgsxtGjx2BkZARn54/RqJEhPvzQEb6+vkhLS1NrK5fLsXHjRjg42MPMrBmkUgm0tDSxa9cuAEBBQYFaew0NDTRs2FDtmEgkgpGRUaFjRfXX0tIq9Nzb677FzW4lJCRAoVBg//79hZZsmps3B/BqKWVZ772q7d27F/n5+Zg8eUqhc7q6ugCAvLy8Ivvm5uaq2pSlLRFRTcJikIiISADdunVDXFw8LlwIg5eXFzIzMzF3rjfatn0HV69eVbUbM8YV3t5z8OGHAxAWFo7U1DTk5MgxadKkKsklFhf+XwOlUlnsuTdNnjy52KWbhw4dVrUr7b1XtUOHDqJ79+5o3bp1oXOvZ1FTUpILncvPz0daWhqaN29e5rZERDUJi0EiIiKBiEQiODg4YPnyFYiKikZExEVkZmZi+fJlAF7NuB09ehSurq5YsmQJ2rRpAz09PWhqauLhw4dVkik3N7fQ7p+pqakA/m9p6b+Zm5tDLBaXKVNJ916UytxA5t69e7h+/Tr69+9f5HkzMzM0bdoUf/75Z6FzcXFxyM/PR7du3cvcloioJmExSEREVM1CQ0PRooV5odc12NraolmzZqri6/WrI0xM1DcmiYuLQ2hoKID/m7WrTGfOnFH7+fz58wCA3r37FNleX18fvXr1QkhICBIT1Z9BDAsLg41NB8TExAAo/b0XpTI3kImIiAAAdO7cpdg248aNQ2hoKJKT1Wf8AgL8oampiTFjxpSrLRFRTcFikIiIqJp1794dmpqamDDBA1FRUZDL5UhLS8PGjRvx+PFjTJr0KQCgVatWsLS0RFBQEGJjYyGXy3Hy5Ek4O38MFxcXAMClS5cKPfdXETo6Oli5cgXOnDmD7Oxs3LhxA/PmfY2mTZti9OjRxfZbs2YtNDQ0MGzYUMTHx0MulyMkJAQeHu6QSCTo2LFjme69qt269TcAwNLSstg28+d/AxMTE4wZ44o7d+5ALpfDz88Pvr6+WLBgodqmPmVpS0RUU7AYJCIiqma6urq4cCEM77//PkaPdoGhYUNYW7fDkSNB8PPzx4QJEwC8ekbv0KHDsLKygp2dLczMmuHbb7fDz88fK1ashLW1NUaMGI6lS5dUWjZtbW3s3LkLa9b4oGlTU9jZ2aJdu3YIDj731k1QevbsifDwCJibm8PBwR4NGhjA3d0Nzs7OOHs2GFKptEz3XtVe78LaoEGDYtsYGxsjPDwCZmZmsLOzhaFhQ6xevQqbNm3GkiVLyt2WiKimECmrYn0JERFRLSUSieDn5//WWbC6atAgJ0RERCAzM0voKFROYrEI/v718/tLRGUWyJlBIiIiUuG/ERMR1R8sBomIiIiIiOohFoNERERERET1kKbQAYiIiKhm+O23U0JHICKiasSZQSIiIiIionqIxSAREVENM2iQEwwM9IWOUS5ubp9ALBapPg8ePBA6Uq3Svr216nfXuLGJ0HGIqI5jMUhERESVSiKRQKFQQqFQonXr1gCAS5cuwdn5Y5ibN4dUKsE771jh66/nIivr7a+xyMrKQps2lhCLRYiNjS10/vLlyxgyZDAaNTKEjo4UXbp0xs6dOyuUv7RZ169fr1b4/vuTn59faOy8vDx4eLhDLBbB19e30Pm4uHgoFEoMHz68QvdARFQaLAaJiIioSl24cAG9e/eCtrY2wsMj8Px5MlatWo1vv/0WAwcOgEKhKLavl9cs3L9/v8hzQUFB6NmzB/T19XHpUgxSUlLh7u6BqVOnFFloVXbWjIx0AEBamkxV/L750dRU35pBJpPByWkg7t69W65sRESVjcUgERERVakFC75B48aNsWfPXrRu3RoNGjTA6NGj8fnnnyMyMhKXL18ust+JEyfw008/wdnZucjz8+Z9DTMzM+zduw9WVlbQ09ODl5cXJk6ciKVLlyAtLa1Ks6anvyoG9fVLXtIrk8ng4GCP3r17w9d3Q5lzERFVBRaDRERE5dSnT2/o6enixYsXhc4tXLgAYrEIoaGhqmPnzp3Dhx86omHDBtDT00WHDu2xevVq5ObmvvU6vXo5oFmzpoWOb9++HWKxCCEhIWrHr127hpEjR8DExBhSqQRt2ljC23sOMjIyynejFeTsPApr166Dtra22vEOHWwAoMjnClNTUzFlymS4urqif3/HQudlMhlu374NOzs7SCQStXMuLqORnZ2NEydOVGnW9PR06OjoFJoBLEpSUhK++momli5dVuZMRERVhcUgERFRObm5uSMnJwfHjh0rdM7Pzw8WFhbo3bs3ACA8PBxOTgNhbGyMuLh4PH+ejAULFmLRooWYN+/rSssUExMDe3s7KBQKRERcREpKKrZs2Yp9+/Zh4MABRT7H9lpKSspbn4F7/YmPjy9TppkzZ2Ls2LGFjt+4cR0ikQg2NjaFzn3++XTk5+dj69ZtRY6pVCoBACKRqNA5IyMj1fhlVZas6enpMDAwKNW41tbWmDp1apnzEBFVJRaDRERE5eTi4gKpVIqAAH+145GRkbh37x7c3T1UxcrRo79CKpVi3br1MDMzg56eHsaPH48+ffpg9+7dlZZp9mwvGBkZISAgEO3atYO+vj6GDh2K1at9EB0djYCAgGL7mpiYFPns278/1tbWFcqYlJQEX19fbNu2DYsWLUKHDh3Uzv/8888IDAzEtm3b0bhx4yLHMDIygtrCC0UAACAASURBVJWVFSIiIpCXl6d2Ljw8HADw/PnzCuUsKWt6ejq0tLSwdOkSdOxoA11dHTRvbgZPzxnlWqJKRFTdWAwSERGVU8OGDfHRRx/h1KlTyMzMVB0/cOAXiEQiuLu7q46tW7cemZlZaNmypdoYFhYWyMjIgEwmq3CezMxMREREoF+/foWWTjo5OQEAoqOjKnyd8rpz5w7EYhGaNWuK5cuXwcdnDRYuXKTW5unTp/jyS0+MGDECrq6ubx1v3br1ePLkCdzd3XD37l1kZGRg9+7d2LHjewDAy5cvqzSrQqFAbm4udHX1cPZsMJ49S8SWLVsRGBiIHj26l7hTKhGR0FgMEhERVYCbmztyc3Nx5MgRAEBBQQECAgLQp08fWFhYqNrJ5XJs3LgRDg72MDNrBqlUAi0tTezatUvVr6ISEhKgUCiwf//+Qks7zc2bAwAeP35c4euUl5WVFRQKJVJT07Bnz15s2bIZtrb/USuEJ0/+FADw3XfflzjeiBEjcOLESdy6dQs2Nh3Qpo0lTp36DQEBgQBQ6iWc5c168eIfeP48GXPnzkXTpk3RsGFDjBo1Ct999z3u3buHdevWlvv6RETVgcUgERFRBQwcOBBNmjRBYOCr5Zfnzp1DUlISPDwmqLUbM8YV3t5z8OGHAxAWFo7U1DTk5MgxadKkSs80efLkYpd4Hjp0uNKvV1aNGjXCyJEjceTIr7h8+TLWrl0DANi5cydOnz6N77/fgaZNC2+YU5RBgwbhypWrkMtzkZKSCj8/f4jFr/73xsLCssqyvo2TkxNEIhGiooSbhSUiKg0Wg0RERBWgqamJsWPH4vfff0d6ejr8/A5AX18fo0aNUrVJSEjA0aNH4erqiiVLlqBNmzbQ09ODpqYmHj58WOI1NDQ0ipw5fP48Se1nc3NziMXiUo1ZlKrYQObRo0eYPPlT7N27t9C518/f/fXXXwCAmzdvAHhVOL95vc8/nw4AePfdTsW+zP1NFy9eBAA4ODiUOmdZs+bl5eHKlSu4fft2oba5ublQKpWQSqVluj4RUXVjMUhERFRBbm7uePnyJY4dO4YjR45g1KhR0NPTU51//eoIExMTtX5xcXGqV0+83h2zKKampkhLS4NcLlc7HhwcrPazvr4+evXqhZCQECQmJqqdCwsLg41NB8TExBR7narYQKZx48bw8/PD1q1bCr1c/sqVKwCANm3aAAA2bdpc5PVeLxm9ceOm2svcvbxmoW3bd9SeDVQoFPjxxx/Qvn172NvblzpnWbPm5uaiVy8HTJ06pdA4J0+eBAD06/dBma5PRFTdWAwSERFVUNeuXWFjY4Ply5dBJpMVWiLaqlUrWFpaIigoCLGxsZDL5Th58iScnT+Gi4sLAODSpUvFPjfo5DQICoUCy5cvQ0ZGBhITEzFnzuwi3xu4Zs1aaGhoYNiwoYiPj4dcLkdISAg8PNwhkUjQsWPHSr//t9HR0cH69b64cuUKpk6dggcPHiA7OxsXLlzAlCmTYWhoCE/PL8s19sCBTrh37x5mzPgCqampSExMxGefTUVsbCx++OFHtddOhIeHQywWwdNzRqVkNTAwwNKlyxAaGgovr1l48uQJMjIyEBAQgFmzZqJz58747LPPynVfRETVhcUgERFRJfjkk1c7Wr75bsHXxGIxDh06DCsrK9jZ2cLMrBm+/XY7/Pz8sWLFSlhbW2PEiOFYunRJkWO7u7tj8eLF8PPzQ9OmprC3t4OJSWOsXLkKANReWt+zZ0+Eh0fA3NwcDg72aNDAAO7ubnB2dsbZs8GCLF2cPn06Dh48hDt37qBLl84wMTHGlCmT0a1bN0RGRsHSsnzP9g0cOBCHDh3GjRs3YGHRGtbW7fD06VOEhYUXOytY0gviy5LV29sbAQGBiImJQdeu78HUtAkWL16EKVOm4MKFMOjq6r7Rdo5q2audnS0AYO5cb9UxN7dPyvU7ICKqCJHybetSiIiI6hmRSAQ/P3+MHj1a6Ci1kpvbJzh48CBycuQlN65mX389F40aGWHevHlCRynRyJEjEB4ejuTklDL1E4tF8Pfn95eISiXw7f88RkRERFQHyGQyHDhwAMHB54SOQkRUY7AYJCIiojqvUaNGePRIuHcsEhHVRHxmkIiIiCpVbm6u6lm4Bw8eCB2nVmnf3hpisQi//vqr0FGIqB5gMUhERESVZt++/WqvhWjdurXQkWqVuLh41e+urM8LEhGVFYtBIiIiIiKieojFIBERUT03aJATDAz0hY5BRETVjMUgERER1Qt5eXnw8HCHWCyCr6+v0HGIiATH3USJiIiozpPJZHB2/hh5eXlCRyEiqjE4M0hERER1mkwmg4ODPXr37g1f3w1CxyEiqjFYDBIREdVhly5dwpAhg2Fk1AiNGhmid+9eOHXqVIn9zp07hw8/dETDhg2gp6eLDh3aY/Xq1cjNzVVrl5aWBi+vWbCyagNdXR2YmjbBkCGDER0dXa52VSEpKQlffTUTS5cuq/JrERHVJiwGiYiI6qjo6Gj06uUAa2trXLt2HXfv3kO3bt0wdOgQnDhxoth+4eHhcHIaCGNjY8TFxeP582QsWLAQixYtxLx5X6u1HTt2DAIDA7Fv336kpckQGRkFHR0dODr2x61bt8rc7t9SUlJU7yx82yc+Pr7YMaytrTF16tQy/OaIiOoHFoNERER11Ndfz0Xz5s2xfr0vWrZsCSMjI/j6boC5uTm+//67YvsdPforpFIp1q1bDzMzM+jp6WH8+PHo06cPdu/erWonl8sRHByMQYMGwdbWFlKpFBYWFti5cxckEglOnz5dpnZFMTExUXtvYXEfa2vrSvu9ERHVFywGiYiI6qAXL17gwoULsLOzg1j8f3/di8ViPHjwEMePFz8zuG7demRmZqFly5Zqxy0sLJCRkQGZTAYA0NbWRpMmTXDkyBEEBQXh5cuXAIAGDRogOTkFnp6eZWpHRETVi8UgERHRG6RSaaHn4mqjxMREKJVKNG7cuMx95XI5Nm7cCAcHe5iZNYNUKoGWliZ27doFACgoKADwqrA8evQYjIyM4Oz8MRo1MsSHHzrC19cXaWlpqvFK244qJicnBwCgo6MjcBIiqi1YDBIREb3ByMgIKSkpQseoMA0NDQAoV2E7ZowrvL3n4MMPByAsLBypqWnIyZFj0qRJhdp269YNcXHxuHAhDF5eXsjMzMTcud5o2/YdXL16tcztqPxSU1MBAMbGxgInIaLagsUgERHRG9q3b48//4wVOkaFmZubQywW49mzZ2Xql5CQgKNHj8LV1RVLlixBmzZtoKenB01NTTx8+LDIPiKRCA4ODli+fAWioqIREXERmZmZWL58WbnavakyNpCpL2JjX31v+fwkEZUWi0EiIqI32Nra4ty5c0LHqDAtLS3Y2dnh3LlzkMvlauc6d34XPXv2KLLf65lEExMTteNxcXEIDQ0FACiVSgBAaGgoWrQwx/Xr19Xa2traolmzZqqZqtK2Kwo3kCm98+fPoW3btjAyMhI6ChHVEiwGiYiI3jB06FA8ePAAMTExQkepMB+fNZDL5XBz+wRJSUlIT0/HokULcfPmTXz22bQi+7Rq1QqWlpYICgpCbGws5HI5Tp48CWfnj+Hi4gLg1bsLCwoK0L17d2hqamLCBA9ERUVBLpcjLS0NGzduxOPHjzFp0qcAUOp2VH4KhQKHDx/GsGHDhI5CRLUIi0EiIqI39OzZEzY2Nvjuu2+FjlJh9vb2CA4+B5lMhnbt2qJVq5Y4e/YsAgICi3z+D3i12cuhQ4dhZWUFOztbmJk1w7ffboefnz9WrFgJa2trjBgxHEuXLoGuri4uXAjD+++/j9GjXWBo2BDW1u1w5EgQ/Pz8MWHCBAAodbuq4u09R7Wc1M7OFgAwd6636pib2ydVev3qcOrUKdy9excTJ04UOgoR1SIi5eu1HkRERAQA2L9/PyZMmIBLl2LQpUsXoeMQvVV+fj66dn0PFhYWOHr0qNBxiKj2CGQxSERE9C9KpRJ9+vSBQqHAhQthEIlEQkciKta2bdvg7T0HN2/eRNu2bYWOQ0S1RyCXiRIREf2LSCTCpk2b8Mcff2Dbtm1CxyEqVnx8PJYsWQwvLy8WgkRUZpwZJCIiKoaPjw8WLVqEoKAjGDp0qNBxiNSkpaXB1vY/aNiwIUJDQ6Grqyt0JCKqXbhMlIiI6G0mTpyIw4cP4/ffz6BHj6Jfx0BU3TIzMzF06BA8efIEUVFRaNKkidCRiKj24TJRIiKit/nvf/8LBwcHfPBBPxw8eFDoOER48OABHBzscffuXRw/fpyFIBGVG4tBIiKit9DW1sbRo0fx6aefwtV1NJYsWVzoJe5E1eXkyZP4z396QlNTE1FRUbCxsRE6EhHVYiwGiYiISqChoYGtW7fiu+++w6ZNm9Cxow2CgoKEjkX1yO3bt/HRR8MwdOgQ9O/fH2FhYWjRooXQsYiolmMxSEREVErTpk3D33//DTs7O4wa5Yz33++K7777Dk+ePBE6GtVB2dnZOHr0KEaPdkHHjjZ4+PAhzp8/j19++QX6+vpCxyOiOoAbyBAREZVDTEwMtm7disOHD+Off/5BixYtYGVlBSMjI4jFNe/fWpVKJZRKZY3MJoSCggJoaGgIHaNImZmZePLkCW7duoWCggLY2dlh2rRpcHV1haamptDxiKju4G6iREREFSGXyxEeHo4rV67g/v37kMlkUCgUQscq5M6dO7h37x4cHR3rfUEYGxuLlJQU9O3bV+goRTIwMICpqSk6d+6Mvn37wtTUVOhIRFQ3sRgkIiKq61JTU9GuXTtMnjwZa9asETqO4C5fvowePXpg3759GDdunNBxiIiEwmKQiIiorvv0009x+vRpxMfH81mz/5k6dSqOHTuG+Ph4NGzYUOg4RERC4HsGiYiI6rKYmBjs3r0bGzZsYCH4hjVr1iA/Px8rV64UOgoRkWA4M0hERFRHKRQK2NraQiKRIDQ0FCKRSOhINcr333+PL7/8EleuXEGnTp2EjkNEVN24TJSIiKiu2rFjBzw9PVnsFON1sayvr4/g4GCh4xARVTcuEyUiIqqL0tLSsGjRInz11VcsBIshFouxfft2hISEIDAwUNAsTk5OXMZLRNWOxSAREdH/zJgxAyKRqFSf2NhYoeO+1fz586GhoYFFixYJHaVG6969O9zd3eHl5YUXL168te3mzZtL/F5YW1tXU3IioopjMUhERPQ/27dvV72cXalUIjk5GQAwfPhwteNKpRIdO3YUOG3xLl++jJ9++gkbNmzgTpmlsHbtWrx48QKrVq0qVfvAwMBC34fXn/j4+CpOS0RUeVgMEhER1SEKhQIzZsyAra0t36FXSk2aNMHy5cuxceNG/P3330LHISKqNiwGiYiIysnJyQnvvPMOrl+/jnfffRdSqRQFBQVwcHBA06ZNC7Xfvn07RCIRQkJC1I5fu3YNI0aMgLGxMSQSCSwtLTFnzhxkZGSUOdOuXbtw6dIl1bWodD7//HO0b98enp6elTruuXPn4OjoiAYNGkBXVxft27fH6tWrkZub+9Z+aWlpmDVrFtq0aQMdHR00adIEgwcPRnR0dKG2lfn9IaL6hcUgERFROUkkEvzzzz/w9PTE8OHDsXnzZojFZfurNSYmBnZ2dlAoFLh48SJSU1OxdetW7Nu3DwMGDEB+fn6px5LJZJg/fz6++OILdO7cuay3U69paGjg22+/xdmzZxEUFFQpY4aHh2PgwIEwNjZGfHw8kpOTsXDhQixcuBBff/31W/uOGTMGgYGB2L9/P2QyGaKioqCjo4P+/fvj1q1bqnaV+f0hovqHxSAREVE5iUQiJCcnY/jw4VixYgWmTZtW5tk4Ly8vGBkZITAwEO3atYO+vj6GDh0KHx8fREdHIyAgoNRjLVy4ECKRCMuWLSvrrRAAe3t7jB8/Hl999RX++eefCo/366+/QiqVYv369TAzM4Oenh7Gjx+PPn36YPfu3cX2k8vlCA4OxqBBg2BrawupVAoLCwvs2rULEokEp0+fVrWtzO8PEdU/LAaJiIgqID8/H66uruXqm5mZiYiICPTr1w8SiUTtnJOTEwAgKiqqVGPdvHkTP/zwA9atWwdDQ8Ny5SHA19cXmZmZWLt2bbFtXFxcit1NdMKECap269evR1ZWFlq2bKnW38LCAhkZGZDJZEWOr62tjSZNmuDIkSMICgrCy5cvAQANGjRASkqKailrZX5/iKh+YjFIRERUASKRCM2aNStX34SEBCgUCuzfv79QUdG8eXMAwOPHj0scR6lUYsaMGarXJFD5mZqaYvHixVi3bp3acsw3vW030Tdn/ORyOTZu3Ah7e3s0a9YMEokEmpqa2LVrFwCgoKCgyPHFYjGOHTsGIyMjfPzxxzA0NISjoyN8fX2RlpamaldZ3x8iqr9YDBIREVWAWCyGhoZGhcaYPHlyscXF4cOHS+y/d+9ehIeHY8uWLdw0phJ8+eWXaNeuHb788ssKjePq6oo5c+ZgwIABCA8PR1paGuRyOSZNmlRi327duiE+Ph5hYWHw8vJCZmYmvL298c477+Dq1atqbSv6/SGi+ovFIBERUSXT0NAoctYnKSlJ7Wdzc3OIxWI8fPiw3NfKzMzE/PnzMW3aNHTv3r3c49D/0dTUxPbt2/H777/j2LFj5RojISEBR48ehaurK5YsWYI2bdpAT08Pmpqapf7zFolEcHBwwIoVKxAdHY2LFy8iMzNT9UxoZXx/iKh+YzFIRERUyUxNTVWzQG8KDg5W+1lfXx+9evVCSEgIEhMT1c6FhYWhQ4cOiImJeeu1Fi9ejLy8PCxfvrxywhMAoFevXnB1dcWMGTOQnZ1d5v6vXx1hYmKidjwuLg6hoaEAXi3vLUpoaCjMzc1x/fp1teO2trZo1qwZUlNTAVTO94eI6jcWg0RERJVs0KBBUCgUWLZsGTIyMpCYmIjZs2cX+d63tWvXQkNDA0OHDkV8fDzkcjlCQkLg7u4OiUSCjh07FnudP//8E9999x3WrFkDY2PjqrylemnTpk1IT0+Hr69vmfu2atUKlpaWCAoKQmxsLORyOU6ePImPP/4YLi4uAIBLly4VOYPcvXt3aGpqwsPDA1FRUZDL5UhLS8PGjRvx+PFjfPrpp6q2Ffn+EBGxGCQiIqpk7u7uWLx4Mfz8/GBqago7Ozs0btwYq1atAgC1F4737NkTERERMDc3h729PQwMDODm5gZnZ2cEBwdDKpUWe50ZM2bg3XffLdUzaFR2TZs2xYIFC7BmzRrcv3+/TH3FYjEOHz4MKysr1Yze9u3b4e/vj5UrV8La2hrDhw/HkiVLCvXV1dVFWFgY3n//fbi4uKBhw4Zo164dgoKC4O/vr7ZjaUW+P0REImVxaxSIiIioxvr555/h7u6OixcvomfPnkLHqbPy8vLQpUsXtG3bFkeOHBE6DhFRZQpkMUhERFTLZGVlwdraGkOHDsV///tfoePUecHBwXB0dMSJEycwePBgoeMQEVUWFoNERES1zZw5c7Bz507cunWr0AYlVDVcXFxw7do13Lx5k0sviaiuCOQzg0RERLXIX3/9ha1bt2L16tUsBKvRxo0b8ezZM2zcuFHoKERElYYzg0RERLWIk5MTkpOTER0dXeGX3VPZrF69GitXrsRff/2F1q1bCx2HiKiiuEyUiIiotvD398fYsWMREREBW1tboePUO3l5eXj33XfRqVMnBAYGCh2HiKiiWAwSERHVBtnZ2ejQoQP69++Pn376Seg49daZM2cwYMAA/Pbbb3BychI6DhFRRbAYJCIiqg3mzZuH77//HvHx8WjWrJnQceq1ESNG4K+//sLNmzchkUiEjkNEVF7cQIaIiKimu337NjZv3oxVq1axEKwBtm7dioSEBGzZskXoKEREFcKZQSIiohpu8ODBePz4Ma5evQpNTU2h4xCA5cuXY+3atYiLi0PLli2FjkNEVB5cJkpERFSTHT58GKNGjcL58+fRp08foePQ/+Tm5qJTp054//33ceDAAaHjEBGVB4tBIiKimionJwcdOnRAr169sHfvXqHj0L8cO3YMH330EYKDg/HBBx8IHYeIqKz4zCAREZHQUlJSUNS/za5atQqpqalYs2aNAKmoJMOGDcPQoUPh6emJly9fFjqfkpIiQCoiotJjMUhERCQwHx8fODg44MaNG6pjd+/exYYNG7B8+XKYmZkJmI7eZvPmzbh37x62bdumOpaRkYGZM2eie/fuAiYjIioZl4kSEREJzM7ODpGRkRCJRPjiiy+wfPlyfPLJJ7h//z6uXbsGLS0toSPSWyxevBibN29GXFwczp49i9mzZ0Mmk0GhUCAxMRGmpqZCRyQiKgqfGSQiIhKSQqGAvr4+cnJyAACamprQ0dGBQqHA0aNH+SxaLZCdnY22bdtCIpHg/v37AKBa9nv8+HEMGTJEyHhERMXhM4NERERCiouLUxWCAJCfn4+srCxkZ2dj9uzZiIqKEjAdlSQ9PR3z58/Hs2fP8OjRIyiVSlUhqK2tjZiYGIETEhEVj8UgERGRgGJiYiAWF/7rWKlUIjY2Fra2tnBzc0NycrIA6ag4SqUSe/fuRZs2bfDdd99BoVAgPz9frc3Lly8RHR0tUEIiopKxGCQiIhLQ5cuXi32RfH5+PpRKJfbv349evXohOzu7mtNRcWbPng0PDw/IZLJCReBrSqWSM7tEVKOxGCQiIhLQH3/8gby8vGLPa2lpwcrKCsePH4eurm41JqO38fHxgbu7e4ntUlNT8eTJk2pIRERUdiwGiYiIBJKfn6/2Ool/09DQgIODAy5dugQrK6tqTEYlkUgk2LNnDzZt2gSRSFTkUl8AEIlEfG6QiGosFoNEREQCiY2NLXZWUCQSYdKkSTh9+jQMDQ2rORmV1ldffYUTJ05AKpUWudxXW1sbly9fFiAZEVHJWAwSEREJJCYmBhoaGmrHxGIxxGIxtmzZgh9++IHvGKwFBg0ahMjISJiamhb688rLy0NkZKRAyYiI3o7FIBERkUD+vZOolpYW9PT08Pvvv8PT01PAZFRWnTp1wrVr19C9e3e1Al+pVCI6Ohp8rTMR1UQsBomIiARy8eJFvHz5EsCrQtDMzAxRUVHo37+/wMmoPExMTHDu3DmMHz8eIpFIdTwzMxMPHjwQLhgRUTFYDBIREQkgLy8P8fHxAF5tFGNnZ4erV6+iffv2AiejipBIJNi9ezdWrVoFkUikKgq5iQwR1UQsBomIiARw/fp11azghAkTcObMGTRq1EjgVFQZRCIR5s+fj+PHj0NHRwcAuIkMEdVIIiUXsRMR1VlJSUkICQnB9evXkZSUhKysLKEj0f/cvXsXV69eRZcuXQR/bYSBgQFMTU3RuXNn9O3bF6ampoLmqQi5XI7w8HBcvnwZ9+/fR3p6OhQKhWB50tPTERYWhgYNGqBPnz6C5SB1UqkUjRo1QocOHfCf//wHnTt3FjoSkRACWQwSEdUx+fn58PPzw7ff70B05B8QiTVg3PId6Bg1g4ZUT+h49D+p92KhY9gYukbCF14F8n+Qk/YMqY9uQ6koQI//2OKL6dMwZsyYIl+XUBNdunQJ27ZuxeFDh/BPTg6aG+mjtbEODKViwZdByfMVuPY4Az0tGkFUcnOqBrkFgExegPhnWcjKyUVLczNMmjwV06dPR5MmTYSOR1RdWAwSEdUlISEh+MLzS/wdHw8L28Gw6ueC5p17Q1OiI3Q0+pe87Cxo6xoIHUNNfm4Onl6/gDvnA3H/j5NoZ22Nb7dtRd++fYWOVqyEhAR8PXcufv7lF3QyN8S495tiQHsTNGsoFTqamtx8BcQiEbQ0WA7WJEolcONpJo7fTILf1ed4qRRj8dJl8PT05GtdqD5gMUhEVBe8ePECk6dMhb/fAVj0HICen65AQzNLoWNRLZaRcA9RPy3C/ajf4TpmLP7fjz9AX19f6FhqduzYAe/Zs2Gsp4ElTpYYZMMZHSq/nJcF2BbyAN+HPUbr1q3gF3CQy0eprmMxSERU2z1+/BhDhn2E+4+eotdXW9Gym6PQkagOeRRzFhe2fAnLFs1x4vhRtGjRQuhIKCgowKxZs7B9+3bM/MACX/WzgERT6MWgVFc8luXA63A8rj39B7/4+WPYsGFCRyKqKiwGiYhqsz///BMfOH4IpY4hPlz4MwxMhf8fdap7spIe4/cV4yGWp+Pc2TOwsbERLEteXh5GjhiO8+eCsXVUewztJPwzl1T3vCxQYv6v8fCLScC27dsxffp0oSMRVQUWg0REtdXz58/RrUdPKAyaYsDiX2rc82dUt+RlZ+H0snHQyEpEzKUowTbZmDjBA4cC/OE/qTPea9FQkAxUf2w+dw/rz97DkSO/coaQ6qJArqkgIqqF5HI5Pho+All5SjjO381CkKqctq4BBizci38UGnAaPATZ2dnVnsHHxwf79u3Ht6PbsxCkajHzA0t80sMc48a44vr160LHIap0nBkkIqqF5s+fjy3ffo+P1v8GQ/N3hI7zVor8PIRunYVb5wLwn0lL0fnjL4psl5FwD9F7ViLhZgTysl/AwLQF2jmOQZdRX0Ikqtp/u6zotdOf3MGlfavw9Ho4CvLkMDBtCUuHj9DZeQa0/vU6j+TbV3E1YAue/30ZOZlp0G9sBgu7oXh/zGxo6fzfBi3XD21H5K5lxV5zyq/PINao/tc+pD+5jaPeg/DVF9Ph4+NTbde9fPkyevTojmVD2mKyfctqu255vSxQwOvQXzh45RkWD26L6b1bFdnu2pNMbD1/H1cfZyD1n5dobijBYBtTzOpvAX1J1f753k3+Bz6n7yD8rgy5+QVo0UgHwzqZ4vM+raGnrVGmsV7k5qP/lkg8SsvB+Vm2sDZV32yorPdZ2t9fdXhZoMS43deQIjLEjdi/uMso1SWBtePlQUREpHL37l1s3LgJPSYtq/GFYO6LdPy+agIKdPKlawAAIABJREFU8v8/e/cdV3X1P3D8dS93sKcsFREUnKDiwr0rt2mOtFJbpv0sx7dsObL6NmyYDfNbatNyb8y9FRcKCg62bJA97+WO3x/I1SsgQxCL83w8+uOez/mc8eHevO97lvq++QoyU9n2xjAaefrw5Jf7sHBwJe7CQQ59PpO8tET6zPqsztr4oHVn3rzOlnmP4djCl1Gf7sDKyY2b5w9w5KvZpIVfYuiSPw15k66cZvfCp2juP4zRywJQWtkSd+EQR5bPJjk0kNHLdhuCT1V+NgDT10egsHh0RsFsm3rhN+UtvvhiMdOnT8fb27vO69Tr9cx9/TW6NLfnhZ6PfiCYXVjM878FU6y9/+/tgdGZTFwdxNC2TuyY2RVbczmHr6czZ2MoZ2Iy2TGzK1JJ3RxFcSM1n6HfnsGniTXbXulCU1tTDl6/xZyNoQTH5/D79E7VKm/xrhvczCgs91p1+1nV5/ewyE0kfP1UG3p/Gcg333zDvHnz6rtJglBrxDRRQRCEf5jX58zFpoknbYZOre+m3JcqL4vtbwzHtX0Peryw9L55g/76Ak1hPoPeXIW1izsmcgXN/YfiN2keYXt+Jis+vEZtyLuVQNBfX/L30mfqrO4zP3+AXqvhsXd/wd69DXIzS1r0GUPbYdO5ef4ASVdOG/Ke/fVDTG0aMXD+d1g5u6Ewt6JFn9G0G/48KdfOcyvizjQ0dX4OALJ7RhYfBW2HTsO2SQvmzf/PQ6nvjz/+4NTpQP47wos6io1qTXZhMSNXnsPfw47Fw+8fKP/37wgcLBR8M7EdbnZmWClljPJ1ZlqPply4mU1IQm6N2pCYXcTyQ1FM/eVShXk+2hOORqdnzTMdaO1siaVSxmhfF6b6u3Hw+i0CozOrXN+Ba7dYdy6B4e3LX0danX5W5/k9TI1tTHmltxtLlywmNTW1vpsjCLVGBIOCIAj/IKGhoezetZMuUxfVyxTBHQtGsnqsG8VF+WWunf31I1aNcCTpyikACrPS8Bk9gy5TFlRabuSxbbj69sLUyt4o3aPHcNDriTqxs8pt1GnURJ3YQcDiiayb7kdYwFpc2/nXWd1NO/Wn+7RFmFob3+/YsuR8spzkWEOaZ69R+E9fjFSmMMpr16w1ULJrZylVfjYyhWm9/J0rIzWR0WXaInbv2kloaGid1/fxfz/kKT9X2jWun7WxY1adx2PhQfLV2jLXPtkbgetb+zkdVRI8peWpebl3M94Y0qLSckf6OLNwmBdyE+OvY61uT7GMyyx/pK08xVodOy+nMHlNEF0/OcEvgfF097CtMH9fLwfee8ILewvjKY++TawBiK1glO9emQXFzN8cymhfF/p6OZSbpzr9rM7ze9hm92+OXKJj5cqV9d0UQag1j96/MIIgCEKF1qxZg30TT5p1HlQv9XsPnEhSaCCxZ/bSst9Yo2uRx7Zi5dwM13Y9gJLphFWZxpp3K4Gi3Azs3FqVuWbd2AOpTE5aROUbN6THhHF93x+EH96EuiAHt86DeHzhrzTrMhiJtPz1T7VRd/uRL5abnp+eVFKOy521Tj6jZ5Tf9ugrIJFg1+xOO9R52cjNH61D3u/WrPMg7Bp7sHbtWj7//PM6q+fMmTOEXb3OV7O711kdlRnv58qZ6Ez2XU3jyQ4uRte2BSfTzN4Mfw87AFo6WtDSsWqjuS/1Ln/Ka2hSLhLJnWDpfsKS8vjrfAKbLiaRW6RhYKtGrH2uA4NaNcJEWvEw6gs9yz+GJjmnCAB3e7Mq9AAWbL2KRqfno9Gt2H2l/BGz6vSzOs/vYTOTmzCpkxNrf/qRxYsX13dzBKFWiGBQEAThH2Tbjl006zGC+por59l7FCdWvUXk8W1GwWDKtfPkJMfSZfKb1W5bYWYaAGb3jKwBSCRSlJa2FGalVXh/Wvgljn//Bmnhl7B2bY7vkzNpNfhpzO0rP3/uQeuusNysNC5vX4W9extc2na7b74bhzZwZedPdJ403ygYVOVnIzWRc/6PT4k6uZOc5BiUlrZ49BxB1ykLUFrZVbtdtUoiwb3HCLZu31mnweCuXbto1sjKMGJVH0b6OPPu9mvsCE42CgYv3MwmNqOQ/wxuUSsfybQ8NZuCklhzKo65Az3xdqo4KAqOz2HBtqsEx+fQ3MGMGX3cmdSlMc5Wygeq/8cTN2ntbElX94pHFUttuZjEzssp/DDZBwcLRaX5766nqv181Az3cebbo2cICQnB19e3vpsjCA9MBIOCIAj/EOnp6URF3GDYsx/UWxsUFtY07/4EMYF7UBfkGo60iDi6GSQSvAdNrHaZGnXJSIRUXv6XSROZAo2q4mMM0qOukBYRjN+keXSZsqBaO48+aN3lUeVm8vcHz6IqyOGJxevKHZXMTormr5dKgkS5qQXdpy0sO2qo16MtViEzNWfER1uQKUyJv3SUEyvfJO78AZ765ojR7qP1obFvby5t/oaMjAzs7csG1LXh1MkT9Gxef4EggLWpjMfbOvJ3WBq5Kg1Wt3e/3HopCYmkZOTwQUSnF9Bz2UkALBQmvPuEV4WjaaWuJOUSkpDDnIGevDHE84E3mskqKGbaL5fIKdLw27RO9x1VBEjOUfHOjus80c6J0b4u981bqib9fNR0aGKNlZmS06dPi2BQ+FcQawYFQRD+Ia5evQqAvXvrem2H98CJaIvVxAQGAKDXaYk8vp3G7Xti5Vz9L3YyZcl0NF1x+TuOajUqZErzCu93aOGDk7cfQX99yfqX/bm4cTkFGSkPpe575STFsPU/Q8mKD2fo4nU0auFTbj4bVw9m7Epj2l/hDJj/HZe3r2Lb/CdQ5WUZ8oz5fA9T112n47jZmNs5obCwxrPXSPrMWkZOciyXNq2ocrvqSul78dq1a3VWx9WwMFo71//I0Xi/xqg1Ov4OLRkp1ur07AhJoYeHHc2qOKWyIh4O5iR9MoRri/vzzcT2/O9ELMO/O0t2YXGF9/g0tqJTUxuWH4qi9+enWHE4mpRcVY3qj0kvZPj3Z4lIy+e3aZ1oX4W1mXM3lawV/XRMmyrXU5N+PmokEvB2sarT97wgPEwiGBQEQfiHSE9PB8DUplG9tqOp3wDMbBsReXw7AAnBxynMSqPV4Ek1Kq90OmdhdnqZazqtBlVuFhYOFY88OLbswJNf/M2E74/j3v1xQrau5I/pHdn7wbPEnt2HXld204/aqvtuKVfPsXX+4+g0akZ/tovGPr0qvUdpaYtHj+E8vvA30iKCubSx8gDPrfMgkEhIuR5UpXbVpdL34q1bt+qsjozMTBpZVn0KYl3p7+1AI0sFO0KSATgRmUFanpqJnRvXWh02ZnKGtnPil6kdCUnI4ZsjMRXm9W1ize5Xu3Fkbg+GtHFk1YlYunx8nGm/XmL/1TS0uqody3AuNovh35+hWKtn+8yu9PSsfPrxn+cTOHIjnc+ebIOTVfX/NtXp56PIwUxq+P+xIPzTiWmigiAI/xAqVcmv/iYVTGl8WKQmMlr2HUtowFrU+dlEHN2C3NQCz16jalSehb0L5nZOZN4s+0t7Vlw4Oq0GR+/Kzzyza9aaHi9+QPdpC4k5s5dr+35n7wfPYm7vjM/oGeUedl9bdadcO8/uheOxdfNm6OJ1mNmWDdjz0uK5sG4Zrj498R5oPJ22dK1gZtx1oGRH1IzYa8jNLLFp7GmUV1usAr0emaLma8NqS+l7saioqM7qUKmLy+xCWR9kUglPdnDh58A4cgo1bAtOxkJhwgifytemlichq4gvDkTRw9OuzDRTb6eS6b83Usvu2nuvVs6WvD/Cm/eGtmRvWBrrziUw7ddgnKwUvNzb/b6HtV+4mc3Tq4PwcrLgt2mdqhx0X03KA2DGuhBmrCt7fcBXJcepxP13MCk5qlrp56NEaSKp0/e8IDxMIhgUBEEQqs170EQu7/gfMWf2EhO4B8/eI5GZVn065b1a9htHaMAairLTMbW5sz195PGtt4PPJ6tcllSmwLPXSDx7jST/ViLXD/xJ0pXT5QaDtVF3bkocAYsnYdu0JSP/u6XCdXymNo2IOLaVW1FX8Bow3mht462IEACsXZoDoC1Ws/2N4Th6+zHqk+1G5dw8fwCAxr597v8ghFo33s+VH0/eZN/VNPaEpjHCxxlzRfk71VbGwULBtuBkriTlMq6Ti9Gav8uJJWdMNq/G9FO5iZQRPs6M8HEmKbuIv84nEhidWWEwGJdZyOS1QbRwtGDjS52xVFb9K+HSka1YOrLsDry/nolnwdarHJ7bg9a3dwit7X4KglC76v+nNkEQBOEfp1ELX+yatebCn8tQ5WXRavDTD1Rep4lzMLV2YP+nL5KdFI1WrSLi2FaCt3yH38R5WDo2rVG5Fo0a4zdpPk8s+r1W6k64dJRVIxw5vfrOtvInfliAtriIIW+vue+GLjKFKT1eeJ9bkSEcWzGX3JQ4NKpCkq6c5uiKOSgsbGg/6mUA5GaWdJmygKQrpzj143vk30pEnZ9D5PHtnPrfuzh4tKPt0Kk1eiZCzfk0saaVsyVfHIwku7D4gaaImsqlLB7uzeWEHP6z+SpxmYUUFmsJjM5k3qYwrM1kvNCrZpuruNqYMneQJ79M7Vhhnne2X0NVrOPHKb6VBoLHIjJwfWs/7+++Ue221GU/BUF4cGJkUBAEQagR74HjOfPzB0ZnC97t9OrFhGz93igtcM0SAtcsAcCr/1MM/E/J4c2mVvaMWbabs798xLb5T6AuyMO2SQt6vvwRbYdOu287ruz6iZM/vH3fPA4e7XjqmyPlXnuQujWqQm6e2w/Auhc6l5un9WNT6PfacgDaDpuOma0jl3f8j02z+6HVqLFs1ASnVp3pPGm+0ZmEHcb9H1Yu7lzevopNrw1AXZCHlbMbbR5/jk4TXjdsfiM8XE/5ufLRnnCjswXv9v7uG/xwPNYobWnADZYGlARSYzu58t3E9gBM9W+Ko6WCH0/eZNDyQNRaHU1sTenkZsO8QZ73Petvzak43t1x/01M2rlaceB1/zLphcVaDlwrWefZ/bMT5d47uWsTvhjX9r7lV1V1+lmd5ycIwoOT6PX6qq0wFgRBEOrVhg0bmDhxIjN2Vf/cO0GoK6tGOLJ+/XomTJhQJ+VLJBJWTfZllG/N1uYJQm17+Y8QTFv3ZcOGDfXdFEF4UBvFNFFBEARBEARBEIQGSASDgiAIgiAIgiAIDZAIBgVBEARBEARBEBogEQwKgiAIgiAIgiA0QCIYFARBEARBEARBaIBEMCgIgiAIgiAIgtAAiXMGBUEQBKEWZCdGcfaXD0m8fNJwJmCrwZPo+NRrSCSV//aq1+sI3bmasL9/IScpGqWVHe7dHsd/+iIUFjZGedMigjn3+8ekXD2HVl2EbZOWtB89g9ZDJpcptzp5BaE2RN0q4OO9EZyKyiC3SIubnSkTOzfm//o3RyqRVHr/pfgcVhyO5mJcNun5xTSxVTKsnTNzB3lgqSz71bVYq2Pe5jA2BSWxaJg3M/u6l1OqIAjlESODgiAIwgPLv5XIqhGO5KbE1XdT6kVBZirb3hiGuiCXJ7/cx/Mbo/GfvpiL65dzYuVbVSrjxMq3OPf7x3R99m2mrY9k8IKfiD69m4DFk+CuI4GjT+9m69zHkJtaMHb5Aab9GY734EkcWzGX4C3fGZVZnbxC7UjKLsL1rf3EZRbWd1PqRWqumlErz5FbpCHg1e5EvD+AhcO8WXE4mne2X6v0/sDoTEb/cA6FiZQdM7sSuqgfbz/uxdrTcUxaHYTunuOxswuLmbQ6iNj0hvm8BeFBiWBQEARBeGCJl0/WdxPqVdBfX6ApzGfQm6uwdnHHRK6guf9Q/CbNI2zPz2TFh9/3/pRr5wkLWEuPF5bi0WM4MoUpru388Z++GHVBHlkJEYa8Z9YuxdzBhYHzV2Lj6oHM1BzfMTNpNeRpzv/xKarczBrlFWrHqaiG/Uy/OhRFvlrDyqd9cLc3QyGT8kRbR+YM8uTXM/FEpOXf9/7//h2Bg4WCbya2w83ODCuljFG+zkzr0ZQLN7MJScg15M0uLGbkynP4e9ixeLh3XXdNEP6VxDRRQRCEBiY96grn131GUmggxYX5WDi44NFzBJ0nzUdhYW3IF7BkEtkJkQx7fz2BqxeTFBqIXqfFvnlbery4FCdvv5J8iyYQF3QYgHUv+GEiV/Di1gQCFk0gJymGIe+s5dAXM8lOiOSFzTeRSE1IDjtL0PovSLl2AY2qAHM7Z9y7P06XKW9iamVvaMOOBSPJTYnj8YW/cerH90iLuAR6Pc6tu9DjxQ9w8GhXku+tUaSFX+LZ30JRmFsZ9ffixuWc/eUjhn+wgaadBtTJM408tg1X315GbQfw6DGcMz9/QNSJnfhNmlfh/df3r0Nmao7XwAlG6a0GP02rwU8bXqvysshOjKJFn9GYyBVGeVv0Gc21fX8Qe24/3gMnVCtvQxWamMvnByIJjMkiX6XF1UbJsHZOzB3kibXpna9IU9ZeJOpWPn9M92NpwA0Co7PQ6fS0cbVkyXBvOrmVTON9ek0QR26kA9Dt0xMoZFJiPxzE02tKRq5+fMaX2euvEHmrgKilAzGRSjgXm8VXB6O4EJdNoVqLk5WSx9o48saQFtiZyw1tGLPqPHEZhfwytSOLdl0nOD4HvR46N7NhyQhv2rmWvO+fXHWe4Pgcgt/ri9U9UypXHI7m470R/PWCH/28HOrkmW4PTqanp71R2wGGtXPioz3h7LqcwpyBnhXeP9LHmUZWCuQmxuMVrZwtAYjLLKRj05L/T6XlqXm5dzOe6VYSKAqCUH0iGBQEQWhA0sIvsWPBSJp07MeYZQFYNHIlMeQkR1e8TnJoIKOX7UZqUvJPg4lMQVFOBgeXzaDLlAUMemMVOSmx7P3wOfZ9OJWnfzqPiULJsKUbOL16MSFbv2fy6iCsnN1K7pcrKVYVcPKHt2juPxQLB1ckEikJwccJWDQBj57DGfvlXswdXEgLv8ShZa+QdOUUY7/cj4lCCYBUrqQw5xZHls+m58sf4eTtR05SDHven8yud8YycdVpTK3tafPEcyRdOU3E0S20HTrVqM+RR7di6diUJh37lftMinIy+GVyq0qf3cQfTmHb1KtMet6tBIpyM7BzK1uGdWMPpDI5aRHB9y07+epZGnm2LxO0lWGYIld23ZXS0g6A9OjQ6udtgILjcxiz6hx9Wzqwa2ZXXGxMORWZwbzNYZyJyWLHzK7IpCXPTmEiISO/mFl/XeaNIS34fpIPNzMLmf7rJZ7/LZjAN3ujlEn583k/3t99gx+Ox3J2QW/c7MwAUMqkFKi1vLvjOo+3dcLVRolUIuFEZAZPrw5iWHsn9rzaHWdrJcHxObz612UCozPZ83/dUcpKgiKliYT0fDVzNoaydGQrOrlZE5NeyLM/X2T8jxc4Mb8X9hZynu3WhMDoTLZdSubZ7k2N+rw9JJkmtqb0aWn8o0WpjPxi2n1wpNJnd3x+T1o6WpRJT8wuIrOgGG+nsteaO5ghN5EQfNfIXnle6t2s3PTQpFwkkjtBIUBLR4ty2yEIQtWJYFAQBKEBOf3TQpRWdgx5e40h8HDv9hjdpi7k6NevE3V8Oy37jzPkV+fn0GHsqzTrMhgAe/c2tBs2ndOrF5MeE2oYHSyXREJRdjodnpyF75OzDMlnfl6KwtKGAXO/MwR9jX160W3aQg5/+SoRx7bSavAkAKRSKVq1io7jZtPYp1dJG5q3wf/5xRz49CVuHPwL3ydn4dlrFKdWvcv1/euMgsGs+HDSY8LoPPmNCjdxMbW2Z8autBo8zRKFmSX3mlmX/YItkUhRWtpSmHX/8nOTY7Hv/jg3Dq3n8vZVZMbdQKYww63LIPynLcKiUWMAlFZ22Lh6kHz1LDqNGqnsTvCYHHYGgKLsW9XO2xAt3n0DWzM5P07xRXE74BrSxpF3nmjJvE1h7AhJYWxHF0P+nCINM/u6M6hVIwBaO1sy1d+N93ffICwp1zA6WB4JkJ6v5pW+7rzS587mJh/uCcfGTM6KCe0NQV9PTzvefcKL2RuusC04mYmdS/72UqkElUbHrH7N6elZEsy3cbFk4TAvXll3mQ1BibzSx50RPs68t/M6f55PNAoGI9LyCUvKY/5gzwo3cbG3kJP0yZAaPM0Sabnq2+WU/VFDKpFgaybnVq6qemXmqdkUlMSaU3HMHehZbqApCELNiTWDgiAIDYS6IJfksLM09u1dZgTKrfNAAFJuXChzX5OOfY1em9s5A1CQkVxpnTqthhZ9xhheq/KySAu/RGOfXoZAsFTT2yN3iSEnypTTtLPx9M7GPr0BSI8OA8BErsB70ARSbwSREXvVkC/i6BaQSIymWtY2jboIAGkFo3omMgUaVUGF9+t1WjTqIhKCj3N9/5/0n/stU9ddZ/CCH0kJO8vWeY+jzr8zBc7/hSXk30rk0BezyEmKQZ2fw/UDfxEasBYAnaa4RnkbklyVhnMxWfRqYW8IBEsN8C4J9i7GlZ122Lel8dRKJ6uS93BKTuUBjkanZ7Svs+F1dmExwfE59PS0MwSCpfp4lfywcDIyo0w5A7yN29DLsyRvWFLJiJtCJmW8X2MuxmVzLSXPkG/rpWQkEpjUuUmlba2pomJtSRtMyg825SZSCot1VSorOr0A17f24/vhUb44EMm7T3gxd1DF00sFQagZMTIoCILQQBRkJKPX6wg/vJHwwxvLzZOflmj0WiI1KbMODmnJF1edVlt5pRIJ5vZ3vgDnpycBGKWVMrNzNMpjqE4mL9MGpZUtAIVZqYa0Nk88R8i2H7i+fx09XvwAgMjj22jasR9WTm6Vt7WGZMqSqYC6YnW517UaFTKleYX3SyRSJBIp6oJcHnv3Z5SWJX1r2qk/fV79nIDFEwneupKuz5TsStrcfxjDlvzFmV8/ZP3MXsjNLGjasS9D3l7Dpv/rh9zszjS66uRtSFJyVOj0ejZfTGLzxaRy8yRkFRm9NpFKyqyDuz2LFI3OeIfL8kgkd4JHgKTbAaSztbJMXkfLkh8Wku8JMuUmZdtge/t1Wt6d99+z3ZvwvxOx/HkukfdHlGyssj0khb4tHWhqZ1ppW2vKTGECgFpb/vNQa3WYyas2DuHhYE7SJ0PILizmVFQm72y/xrbgZDa86IeNmbzyAgRBqBIRDAqCIDQwrR9/hn6zv3oodUkkUiRSk7IX9OV8WSxNu2cKm6S8KW2leaV3vljaNvXCtX0PbhzeSPfpi8mIuUpWfASdJ79Z0+ZXSWlgW5idXuaaTqtBlZuFRTuXMtcMJBJMbRxQWtoaAsFSrj49QSIhPeqyUbpbl0G4dRlklFY6Imrt4l7jvA3NlK5N+Hxc24dSl1QiwURa9r2sL+ezYPgo3JNe3mfB8FG461pLRwv8PezYfDGJhcO8uJacR2RaPv8ZXLcja6XBbnp+2R9GNDo9WQXFuHjYVatMGzM5Q9s50cTWlMe/OcM3R2J4b2jZtbuCINSMCAYFQRAaCItGjZFIpOSlxtdbGywbNQGJpNwppgUZKbfzNDZK1xarUefnGO10WnT7SARzW0ejvG2fmMrBz18h4eJREkKOo7Syw6PH8Pu26UE3kLGwd8HczonMm2XPUMuKC0en1eDo3em+ZTdq6Uvq9aAy6XqtBvR6o/V+FUm5eg4Al3b+tZr338jVxhSpREL8PaN/D1NjG1MkkrKjfwCpt9fVNbY1HsVTa3TkFGmMdjrNLCiZ6ls6mljq2e5NefWvyxwLT+dEZAa25nKGtXO6b5sedAMZF2slTlYKrt81PbVUeGo+Gp3esBNoeRKyivjiQBQ9PO0Y7+dqdM3bqWQU+0bq/Y+mEAShekQwKAiC0EDITS1waedP4uWTFGSmYm5354thUmggx7+dz4B53+Ho1bHaZUsMI3T3ny6nsLDGuXUXEkNOoVEXIVPc+bJbejxF6frFu8VfOopnr5GG16XrCl3b9zLK59FrJKar3uHGkY0khZzEq/+4SnfofNANZABa9htHaMAairLTMbW5s6Yr8vhWpCYyWvZ98v739x1L3PmDxF88QtNO/Q3pCbf76dK2uyHt1I/vcfPsPiasPIlUVjJdTq/XcfXvX7Fz88alTbca5W1ILBQmdPew5VRUBqm5apys7rxHzkRn8sbWq3wzoT0d7hO4VKR0hK68we+7WZvK6NLMllNRmRQV6zC9a/rk4dvHU/T3Lnv8w7HwdEb43JlmfTKqZF1hD0/jEbcR7Z14z1zO5otJnIrKZFxHlzLrI+/1oBvIADzZ0ZWfT8eRnq/G4a6NZLaHJCOTShjToeJRcgcLBduCk7mSlMu4Ti5Go52XE3MAaG5v9kDtEwTBmNhARhAEoQHxn74IiVTK3+9PJis+HK1aReLlkxz+chZSuQJ79zY1KtfCoeRX/JTrF9CqVei0mvu0YQnqwjyOfDWb3JSbFBflk3DpKOd++y8ubbvh0XOEUX6ZwpSgPz8n/uIRNKpC0mPCSg5Tt3OiRZ/RRnlLNpKZSOTRreRnJNP6sWdq1J/q6jRxDqbWDuz/9EWyk6LRqlVEHNtK8Jbv8Js4D0vHO7s6Jlw6yqoRjpxevdiQ5tV/HK7te3Lkq9kkhQaiURWSGHKCkz+8jY2rB20ev9MPt86DyEmO5cTKBRTlZlCQmcqxb+aREXuVvrO/MppmW528Dc17Q72QSiQ8+/NFItLyUWl0nIrKZPaGUBQyKa1darae0sWmZKpkUFw2Ko3uvusJFw7zIk+lZc7GUG5mFJKv1nIsIoNP90XQ1d2W4e2N19aayqV8dSiKo+HpFBZrCUvK48OAcJysFIzyNc6rkEmZ0Lkx24JTSM5R8XTXuts45m6vD/DA3kLBjHWXiU4vQKXRsS04mZXHYpkz0JMmd412HovIwPWt/by/+4ahf4uHe3M5IYf/bL5KXGYhhcVaAqMzmbcpDGszGS/0Kv/oCUEQakaMDAqCIDQgTq06M2ZZABf+/JxtbwynuCAXMzsnWvTrKoF3AAAgAElEQVQZg9+EOWV2+Kwq7wHjiT65k8NfvspJMyvGrThYYV6Xtt0Y9cl2zv/xGZteG4BGVYilYxO8B02i86T5hnMOS0nlCvrP/YbTqxeTduMier0O5zbd6DXjv4bNW+5WspHMShq18DUcSl/XTK3sGbNsN2d/+Yht859AXZCHbZMW9Hz5I9oOnVbp/RKpCcPe/4sLf37O4S9mkZ+RjKm1Pe5dH6Prs+8YbfTi5jeAx979mYsbv2bddD8kUinObboy+rPdZUZ1q5O3ofFzs2HnzK58eTCKkSvPkVekwdFKyWhfZ14f4FFmh8+qGt/Jld1XUnltwxUslTL2v1bxVNyu7rZsndGFZfsjGbIikMJiLU1sTZng15i5gzwN5xyWUphIWf5UO94PCOdSXDY6PXR1t+HDUa0xk5ddm/tstyasOh6LTxNrw6H0dc3OXM7OmV35794IRnx/ltwiLS0amfPByFY8d8+5h+WZ6t8UR0sFP568yaDlgai1OprYmtLJzYZ5gzxxv2tksPRMx7stDbjB0oCS4HJsJ1e+m9i+djsoCP8yEn15K5cFQRCER86GDRuYOHHiA09p/CcJWDSB5LCzPL8ppsr3ZMReZeOrfen32nJaPzal7honALBqhCPr169nwoQJdVK+RCJh1WTfMiNfDc3Ta4I4F5NFxNKy06grci0ljwFfneaLcW2Z/JBGBhuCl/8IwbR1XzZs2FDfTRGEB7VRTBMVBEEQHmn6StYh3it483eY2znh1f+pOmqRINSP6v56//3RGJysFIzr5Fp5ZkEQGiQxTVQQBEH4x9PrtGiL1YTt+YUbh9Yz5K3VNZ7yKgj/ZFqdHrVWx29n4tkYlMT/pvjWeMqrIAj/fiIYFARBEP7xIo9t49AXszB3cGHg/O/x7D2qvpskCPVie0gKs9dfwdlaybcT2zPSp2FPrxUE4f5EMCgIgiA8soYtrdqanJb9x9Gy/7g6bo0g1J8/n/erUr6xHV0Y27Hi4xsEQRDuJuYNCIIgCIIgCIIgNEAiGBQEQRD+sQIWTWD1U+713QxBeGieXhNEi0WH6rsZgiD8S4hpooIgCIJQz4oL89j4f/3ITbnJ+O+OYe/epkwenUbN0RVzuXFoA/7PL6HD2FfLLSst/CIXN3xN6vULFOZkYOnYGI+eI+g8ab7ReYWC8LBFpuXz8d4ITkRmotJocbMzY6SPM7P6NcdCYXxO4uWEHD7dF8m52CwKi7U0tTVjWHsn5gz0wFJZ8vVVpdHR/L2KzzQFmNK1CZ+Pa1tnfRKEfzoRDAqCIAhCPTv143vkptys8LoqL4t9H01Dq1Hft5ykK6fZvfApmvsPY/SyAJRWtsRdOMSR5bNJDg1k9LLdSCRiUpDw8N1IzWfot2fwaWLNtle60NTWlIPXbzFnYyjB8Tn8Pr2TIW9wfA4jV55lWDtn9r/mj72FnNNRmby+MZTTUZnsnNUVqUSCUiYl6ZMh5db3d1ga03+9xKgOYv2kINyP+BdBEARBEOrRzXP7ubbvDzx7jSj3uiovi+1vDMe1fQ96vLD0vmWd/fVDTG0aMXD+d1g5u6Ewt6JFn9G0G/48KdfOcysiuC66IAiV+mhPOBqdnjXPdKC1syWWShmjfV2Y6u/Gweu3CIzONOT9eG8EJlIJX41vSzN7MyyVMoa0ceSVPu4ExWVzNibrvnXlq7W8u/0ao31d6NvSvq67Jgj/aGJkUBAEoQFT5WZy4a8viD3zN/kZycjNLHH06kiXyW/i5G28e2FC8HEublhO6o0g9FoNlk5ueA+cgO+TszCRKwz5ApZMIjshksfe/YVTq94hNfwiUhM57t0eo8+sz7h5/gAXNywnOyESMzsnfEe/QvtRLxnu37FgJLkpcTy+8DdO/fgeaRGXQK/HuXUXerz4AQ4e7e7bp/SoK5xf9xlJoYEUF+Zj4eBimCapsLCuUd/rSlFuBkdXzKFFnzE09u1F1MldZfIUZqXhM3oGbZ54jpRr5+9bnmevUZjZOiKVKYzS7Zq1BiA3JQ5Hr07l3dpgZBUU8+WhKPaFpZGco8JSKaNDU2v+M9iTTm42RnlPRGaw4nA0F+Ny0Oh0NLU14yk/V2b2cUdx19l9U9ZeJOpWPquf6cjCnde4FJ+DzETCkNaOfDKmNQev3+KbwzFE3srHyUrJS72a8WKvZob7x6w6T1xGIb9M7ciiXdcJjs9Br4fOzWxYMsKbdq5W9+1TaGIunx+IJDAmi3yVFlcbJcPaOTF3kCfWpne+6lWn77Wtr5cDvVvYY28hN0r3bVLymYzNKMTfww6AhKwiHC2VmMmNp442dzAvk7c8n+2LJKdIw5IR3rXZBUH4VxLBoCAIQgN24LOXybx5nSFvr6aRpy8FmSmcXr2YXe+MZdzXB7Fp0gKA5LAzBCyagEfP4UxcdRqluTXRgQEc+mIWhVlp9Hz5I0OZJjIFRTkZnPj+DXq8sBQ799aE7V5L4Nr3yUtLQKZQ8vh7v6K0tOHED29z8n/v4NTKD6dWnQGQypUU5tziyPLZ9Hz5I5y8/chJimHP+5PZ9c5YJq46jal1+b/2p4VfYseCkTTp2I8xywKwaORKYshJjq543TBNUmoiq1bf71WUk8Evk1tV+mwn/nAK26Ze981z/Ls30Gk19H7lE6JO7Sw3j21Tr0rLKeUzeka56enRV0Aiwa5Z5e3+t3vlz8tcT8njx2c64NPYipQcFe8H3GD8jxfY95o/no1KAo6zMVk8vTqIYe2dOD6/J9amMv4OTeX/NlwhPU/N0pF3nqXCREJGfjFvbbvKkhHetHK25JfAOD4ICCcxuwilTMqaZztgaybnnR3XWLjzOn7NbPC7HYApTSSk56uZszGUpSNb0cnNmpj0Qp79+SLjf7zAifm9ygRRpYLjcxiz6hx9Wzqwa2ZXXGxMORWZwbzNYZyJyWLHzK7IpJJq9f1eGfnFtPvgSKXP9vj8nrR0tCj32gs93cpNT84pAsDd3syQ1sbFkn1X08gp0hgFs9HpBQB4O5VfB0B8ZhFrT9/k//p74GKtrLTNgtDQiWmigiAIDZRWrSLh0jHcugzCuXVXTBRKrJyb0X/OCkzkSuKCDhvyxgTuwUSuxP/5JVjYuyAzNcer/1M0bt+T6wf/KlO2Oj+HTuPn4NSqM3JTC3zGvILc1IKUa+foP+cbrJybobCwoeNTswFICDluuFcqlaJVq+g4bjaNfXohU5ph37wN/s8vpig3gxvl1Ffq9E8LUVrZMeTtNdg2bYnc1AL3bo/RbepCUm8EEXV8e7X7fi9Ta3tm7Eqr9L/KArjwI5uIOrGD3jM/xdTG4b55a6owK43gLd9xZedPdJ40v8EHgyqNjuMRGQxq1YguzWxQyqQ0szdj+fh2KGRSDt9IN+T9OywVpUzKomHeuFgrMVeYMLaTKz087Fh/IbFM2TlFGl4b4IGfmw0WChNe7u2OhcKE87FZLB/fjmb2Zlibyfi//s0BOBGRYbhXKpWg0uiY1a85PT3tMJOb0MbFkoXDvMgsKGZDUNn6Si3efQNbMzk/TvGlhaMFFgoThrRx5J0nWnIxLpsdISnV7vu97C3kJH0ypNL/KgoEK5KWp+bHEzdp7WxJV3dbQ/rcQZ4o5VJe23CFpOwiirU6jtxIZ9XxWEb7utx3FHP5oSiUMhNm9G5WYR5BEO4QI4OCIAgNlFQux8y2ETGnA2jWZTDuXR9DKpOjMLdi6p/XjfL6P78E/+eXlCnDyrkZiZdPosrLQmlpa3TNpW33O3WZyFBa2WEiV2Bu72xIN7d1AqAgM7VM2U07DzB63dinNwDp0WHl9kddkEty2Fla9h9nNG0VwK3zQABSblygZf9x1ep7XchPT+LkD2/T3H8YLfqMqfXys5Oi+eulbgDITS3oPm1hhaOGDYncREIjSzl7wlIZ1LoRg1s7IjeRYKWUEbaov1HeRcO8WTSs7DTDZvZmnIrKJLuwGBsz49G6bs3vfAZkUgm25nKUMinOVndGqBwtS96baXllNwMa4G38o0Avz5IR8LCk3HL7k6vScC4miyc7uhhNWy0pqxEAF+OyGdvRpVp9fxiyCoqZ9sslcoo0/DatEya3Ry+hZGRwzTMdmLHuMn4f3/mhaGg7J5aNK7vTbqmErCI2BCUyq2/zMn8bQRDKJ4JBQRCEBkoikfLEoj84+Pkr7PtoGjKlGc6tu+LWeSCth0xGaXVnTY5WrSI0YA1RJ3eSmxxLUW4Wep0WvU4LgF6nMy5bamK0Pq+kPolRmbcTy71fKpNjamU8FVRpVfJFuzCrbOAIUJCRjF6vI/zwRsIPbyw3T35aYrX7XheOfv06AH1eXVYn5du4ejBjVxqqvCwSL5/k5A9vE3lsK8M/3FQmaG9IpBIJv07txKy/LvP8b8GYyU3o4m7DAO9GPN2lMbbmdwIIlUbHz6fj2H0lldiMAjILNOj0erQ6PQBa47csJlKJ0ZRGKHl7294TlEiQ3L5fb5QuN5FgZ26ct7Q95QWOACk5KnR6PZsvJrH5YlK5eRKyiqrd97oWk17IlLVB3MpT89u0TrRvbLwmclNQEvM2hzKjtztT/d1wtlZwOTGXN7dc5YlvzrBjZlccLBRlyt0YlIhGp2dKtyYPqyuC8I8ngkFBEIQGzNGrI5N+OE3y1bPEBR0i7sJhAtcs4eLGrxnx4WYatfAB4MCnLxJzdi9dnn4DrwHjMbdzQipXcPzb+Vzbv67W2yWRSMom6m9/eZbef4VD68efod/sryqto6p9r23X9q8jLugwgxf8hLmdU53UUUppaYtHj+FYOjZly5zBXNq4gu7TF9VpnY+6Dk2tOTG/F+diszh8I50jN26xNOAGK45Es/HFzobAZMa6EPZdTWP+oBaM69QeJysFCpmUN7dc5c/zCbXervLe84a3fHmfh7tU9Sy9qva9Lp2LzWLar5ewUMjYPrMrrZ2Nz77U6PS8vf0a3Zrb8e7QO1Ot/dxs+Hp8OwavCOT7o7EsHFZ2Gvauy6l0bGqDm51ZmWuCIJRPBIOCIAgNnUSCS9vuuLTtTtdn3ibl2jl2LBjFhT+X8fh7v5KfkUzMmb9p2fdJOk9+w+jW3NT4OmmStliNOj/HaHSxKLdk63lzW8dy77Fo1BiJREpeddpUSd/L86AbyGREhwIlAfaBT18sc33jq30BeGl7kmGzm6rIS4vnwrpluPr0xHvgRKNrpWsFM+PqfgrsP4FEUjKls1tzWxY81oLzN7N58odzfHEgkrXPdSQ5R8XesDTGdHBh/mBPo3vjswrrpE1qja7MhimZBcXAnaml93K1MUUqkRB/e/SvKirre3lqYwMZgAs3s3l6dRBeThb8Nq0TjcrpV3xmEXkqDV7lbBLT4nbZ4Wn5Za7FZhQSmpTLawM8Km2nIAh3iGBQEAShgUq6coqDy15h6JI/jY5rcG7dFXM7Z4pySja40BWXTFEztTZez5QZd4OkK6dKXuiNp7zVhvhLR/HsNdLwOjHkBACu7XuVm19uaoFLO38SL5+kIDPVaNQtKTSQ49/OZ8C873D06ljlvpendAOZmur58kdGu6+WCtvzM8e/e4Px3x3D3r3idVEVtsumERHHtnIr6gpeA8YbHS5/KyIEAGuX5jVu97/B6ahMZv11md+ndzI6rqFLMxucrJRk3A6+1JqSOaD37uAZnprP6aiSHyX01P57/lh4OiN87qypPRlV8j7s4Vn+tGULhQndPWw5FZVBaq4aJ6s7wdWZ6Eze2HqVbya0p0NT6yr3vTylG8g8iLjMQiavDaKFowUbX+qMpbL8r6ClI7DXkvPKXLuWUpLmZmda5tq522cPVnYMhyAIxsRuooIgCA2Uo1cnpCYyDn/5KqnXL6BVq1DlZhKybSV5txJo/dgzAFg6NcXaxZ3o07vJiL2KVq3i5vkD7PtoGp69RwGQGn7RsH6wNsgUpgT9+TnxF4+gURWSHhPGmbVLMbdzokWf0RXe5z99ERKplL/fn0xWfDhatYrEyyc5/OUspHKFIciqat//SWQKU3q88D63IkM4tmIuuSlxaFSFJF05zdEVc1BY2NB+1Mv13cx61dHNGpmJhNc3hBIUl41KoyOroJhVx2NJzC5icteStWZN7Uxxtzcj4Eoq11LyUGl0HLx+i+d/C2bk7WDtUnxOmXV/D8JULuWrQ1EcDU+nsFhLWFIeHwaE42SlYJSvc4X3vTfUC6lEwrM/XyQiLR+VRsepqExmbwhFIZPS2sWyWn2vK+9sv4aqWMePU3wrDAQBzBUmzOzrTmB0Jh/vjSAxu4jCYi0Xbmbzny1hWJvJjM5oLBVxq2S08O4jKgRBqJwYGRQEQWigZEozRn22kwt/fMb+j1+gICsNhbkltk29GLzgJ0PQJZFIeezdXzi56h22zR+KxESGc5suDH7rJ+SmFtyKvMzeD56l41Oz6frsO7XSNqlcQf+533B69WLSblxEr9fh3KYbvWb8F5my4i97Tq06M2ZZABf+/JxtbwynuCAXMzsnWvQZg9+EOZgolNXq+6Pg9OrFhGz93igtcM0SAtcsAcCr/1MM/M9KANoOm46ZrSOXd/yPTbP7odWosWzUBKdWnek8aT7WLu4Pu/mPFDO5Cdtf6crn+6N46fcQ0vLUWJma0NLRglWTfQ1Bl1QiYfWzHVi48zojvjuLiYmELs1sWTXZFwulCZcTc5n2yyVe7d+ctx5rWSttU5hIWf5UO94PCOdSXDY6PXR1t+HDUa3LHL5+Nz83G3bO7MqXB6MYufIceUUaHK2UjPZ15vUBHihv7zJa1b7XhcJiLQeu3QKg+2cnys0zuWsTvri97vGtx1ri6WDO72cTWHMqjqJiLY0sFfRuac//Jvvi4VD2PMTsQg0AVqbiq60gVIdEr6+DuT2CIAhCrduwYQMTJ058oCmK/wQBiyaQHHaW5zfF1HdThCpYNcKR9evXM2HChDopXyKR1HmwUt+eXhPEuZgsIpYOrO+mCFXw8h8hmLbuy4YNG+q7KYLwoDaKaaKCIAjCI6cu1mMJwqNMvOMFQagPIhgUBEEQBEEQBEFogEQwKAiCIAiCIAiC0ACJVbaCIAjCI2XYUrEOR2hY/nzer76bIAhCAyVGBgVBEARBEARBEBogMTIoCIIgVEvAogkkhZ3hhU2x9d2Uajv0+UzCj2wyvJ68OggrZ7d6bFH9W/9KD7LiIwAwtbJn6p/X67lFj56n1wRxNiaLyH/gbp+vrr/ClotJhtdnF/TGza5hn8XX+4tTRKaVnEtoZy4nbFH/+m2QINQjEQwKgiAIDYqJXMGLWxMA0KpVrBrheN/8rR9/hn6zvzK8vhUZwrnfPib56lk0qkKsHJvi0XMEfpPmITezrFGb0sIvcnHD16Rev0BhTgaWjo3x6DmCzpPmlymzqnmDN39L4Nr3K6zzpe1JSE1kTPzhNAB7P3yO5NAzNWq/8GhTyKTEfjjIKC0yLZ+P90ZwIjITlUaLm50ZI32cmdWvORaKknMNVRodzd87eN+yp3Rtwue3zwcsVazVMW9zGJuCklg0zJuZfR/8fMuqlqnT61lzKo7fzsQTk1GInZmcIW0cWTjUC2uzkq+9J+b3BGD6r5c4E5P1wG0ThH8yEQwKgiAIDZaJQlnhuY0xgXvY++FztOwzxpCWFn6JbW8Mw6PHcJ5acRhTa3sSL5/iyFezSbxyijGfByCRVG8FRtKV0+xe+BTN/YcxelkASitb4i4c4sjy2SSHBjJ62W5DmdXJq8rPBmD6+ggUFjY1eTzCv9SN1HyGfnsGnybWbHulC01tTTl4/RZzNoYSHJ/D79M7AaCUSUn6ZEi5Zfwdlsb0Xy8xqoOLUXp2YTHP/xZMsbb2DsuoTpnvbL/GlovJfD2hHQO8GxEcn80Lv4dwNTmXnTO7IZHUWrME4V9BrBkUBEEQhHsUF+Vz8oe3adFnDE069jOkn/31I6RSE/rPWYGVczPkZpa4d3sM37EzSb1+oUYja2d//RBTm0YMnP8dVs5uKMytaNFnNO2GP0/KtfPcigiuUV51fg4AMlOLB3gSwr/RR3vC0ej0rHmmA62dLbFUyhjt68JUfzcOXr9FYHTmfe/PV2t5d/s1Rvu60LelvSE9u7CYkSvP4e9hx+Lh3rXS1uqUeeFmNr8ExrN4hDdD2zlhKpfS3cOO94Z6kafSEnkrv1baJAj/JmJkUBAE4V9qx4KRpIVf4rl115DfExCc/fUjLm5YzqhPtuPavmTKVELwcS5uWE7qjSD0Wg2WTm54D5yA75OzMJErKqxn+5vDyU6M5rnfw4zSr+z6iZM/vM3Ij7fR2KeXIT096grn131GUmggxYX5WDi4GKY5Kiysa/EJ1Nz53z9BlZ9Nj5c+MErPS0vAzM4RmdJ4zZW1iwcAOcmxuLbvUa26PHuNwszWEanM+BnbNWsNQG5KHI5enaqdV5WfjUxhitSk4fxTP2bVeYLjs7mysL9hqmOpT/ZG8PXhaLa83IUennYAnIjMYMXhaC7G5aDR6Whqa8ZTfq7M7OOOQlbx7+WjVp4jJr2AkPf6GaWvORXHuzuusfnlLvS8XQdAaGIunx+IJDAmi3yVFlcbJcPaOTF3kCfWpg//79PXy4HeLeyxt5Abpfs2Kfn8xWYU4u9hV96tAHy2L5KcIg1LRhgHZ2l5al7u3YxnujXlws3sWmlrdcr883wC5goTxndyNUqf1KUxk7o0rpX2CMK/TcP5F0IQBKGB8R44kaTQQGLP7KVlv7FG1yKPbcXKuRmu7UoCl+SwMwQsmoBHz+FMXHUapbk10YEBHPpiFoVZafR8+aNaaVNa+CV2LBhJk479GLMsAItGriSGnOToitcN0xwrCl6KcjL4ZXKrSuuY+MMpbJt61biNualxXNm1mo5PvYaFvfEUOPvmbYg9uxd1fo5R4JqTFA2AXbPqj4b4jJ5Rbnp69BWQSLBr1qpGedV52cjNa7aG8Z9qvJ8rZ6Iz2Xc1jSfvmb64LTiZZvZmhiDnbEwWT68OYlh7J47P74m1qYy/Q1P5vw1XSM9Ts3Rk5e+1qgiOz2HMqnP0benArpldcbEx5VRkBvM2h3EmJosdM7sik5Y/dzEjv5h2HxyptI7j83vS0rHqI8Av9Cx/06TknCIA3O0r3mAmPrOItadv8n/9PXCxVhpda+loUa12VEV1yjwXk0U7V6v7BvKCIBgTwaAgCMK/lGfvUZxY9RaRx7cZBYMp186TkxxLl8lvUrqAJiZwDyZyJf7PLzEEQF79n+La3t+5fvCvWgsGT/+0EKWVHUPeXmMYbXTv9hjdpi7k6NevE3V8Oy37jyv3XlNr+wrX99WmoPVfYiJX4jvmlTLXOk/6D/EXj3L4y1fpPfNTzGwbkRBykpCtK2nRZwxO3g9+XlxhVho3Dm3gys6f6DxpvlGAV528qvxspCZyzv/xKVEnd5KTHIPS0haPniPoOmUBSquKR37+qUb6OPPu9mvsCE42CgYv3MwmNqOQ/wxuYVgz9ndYKkqZlEXDvA1BzdhOrvxxLoH1FxJrLRhcvPsGtmZyfpziawhShrRx5J0nWjJvUxg7QlIY29Gl3HvtLeQVrtmrbWl5an48cZPWzpZ0dbetMN/yQ1EoZSbM6N3sobSrOm5mFvKYiyUbg5L434lYwlPzMZWbMKiVA+8N9cLVxrS+mygIjxwRDAqCIPxLKSysad79CWIC96AuyEVhbgVAxNHNIJHgPWiiIa//80vwf35JmTKsnJuRePkkqrwslJYVf0GsCnVBLslhZ2nZf1yZaadunUu27E+5caHCYPBhyEuL58bB9XQY+2q5/bVv3obH3/2Z/Z++yO/TOhjSPXoMp+/sLx+o7uykaP56qRsAclMLuk9bWOFIYJXy6vVoi1XITM0Z8dEWZApT4i8d5cTKN4k7f4CnvjlS491PH1XWpjIeb+vI32Fp5Ko0WClLvuZsvZSERFIyclhq0TBvFg0rO5LbzN6MU1GZZBcWY2MmL3O9OnJVGs7FZPFkR5cyo1UDvBsBcDEuu8Jg8GHJKihm2i+XyCnS8Nu0TphUMFKZkFXEhqBEZvVt/sDPprZpdXqKinWciMzgVp6ar8e3x93BjPOxWfxnSxjDvjvL0bk9DTuKCoJQQnwiBEEQ/sW8B04k8vh2YgID8B44Eb1OS+Tx7TRu3xMr5zu/7GvVKkID1hB1cie5ybEU5Wah12nR67QA6HW6B25LQUYyer2O8MMbCT+8sdw8+WmJD1zPg7hxcAM6rYY2jz9X/vVDGzi6Yg6+Y2bSdtg0LOyduRV5mWPfzmfL3CGM+Ww3pjYONarbxtWDGbvSUOVlkXj5JCd/eJvIY1sZ/uGmMoFpVfKO+XxPmTo8e41EIpGw77/TubRpBV2ffadGbX2UjfdrzI6QFP4OTWO8nytanZ4dISn08LCj2V3TH1UaHT+fjmP3lVRiMwrILNCg0+vR6kp2rNQ++FuelBwVOr2ezReT2HzXWX93S8gqevCKHkBMeiFT1gZxK0/Nb9M60b6xVYV5NwYlotHpmdKtyUNsYdVIJRKkEgm5RRrWPNvBEKz283LgsyfbMnlNED+ciOXNIS3quaWC8GgRwaAgCMK/WFO/AZjZNiLy+Ha8B04kIfg4hVlp+E9fZJTvwKcvEnN2L12efgOvAeMxt3NCKldw/Nv5XNu/rlbbdO+5fY+SqJM7cPLqVO5B9DqthhMrF+DStjvdpy00pDu16syAud+y6bUBXNryLf7TFz9QG5SWtnj0GI6lY1O2zBnMpY0r6H7P36smeUu5dR4EEgkp14MeqJ2Pqv7eDjSyVLAjJJnxfq6ciMwgLU/Ne0ON15HOWBfCvqtpzB/UgnGd2uNkpUAhk/Lmlqv8eT6hVttU3ll8j4JzsVlM+/USFgoZ22d2pbXz/UeKd11OpWNTm0fy0HqJBBws5NiYycuMWvbwsEMigSuJufXUOkF4dIlgUBAE4V9MaiKjZd+xhAasRZ2fTcTRLdB5TPAAACAASURBVMhNLfDsNcqQJz8jmZgzf9Oy75N0nvyG0f25qfGV1iGRmhhGEO9WmGW8vs+iUWMkEil5VSizPHW9gUxOcizp0aF0Gj+n3Ot5qfEUF+Zh51Z2aqFN05YAZMXdqFadeWnxXFi3DFefnngPnGh0rXT9X2bc9Wrn1WnUZMReQ25miU1jT6O82mIV6PXIFMabf/xbyKQSnuzgws+BceQUatgWnIyFwoQRPs6GPMk5KvaGpTGmgwvzBxs/n/iswkrrMJFK0OrLnnmXlqc2eu1qY4pUIiG+hqN/dbWBDJSso3x6dRBeThb8Nq0TjSwr3jEYSnYYDU3K5bUBHtWq52HyaWJNUFzZHUc1Oh16PchNxCGDgnAvEQwKgiD8y3kPmsjlHf8j5sxeYgL34Nl7JDJTc8N13f+zd9/RUVVbAId/k0knIY00EnoLvZcAoYTeQpOONJWuIjwpFqSIIioaUWkCikKoUoSEjpQUeu8plNDSe8/M+yMSjEkggUwmZX9rvbUec8+9ZycM19lzzt07NeMDrGHZrNsbIx/c5vFVn4w/5PDB9xkjc2ueXDtFekoyyn8lGA8vnsgyTs+wDHZ1W/HoijcJkSEYW9hkHnt8zY8TP86g4/SfsK7RKMd5NF1A5sn1jB6BVlXr5Xjc2MIGpZ4+EfduZDsW+c9rpjb5K6phaFYO/+M7CAu8So2Og7I0rA/zvwxAWbvK+R6bnprCrg97YV2zCW6Ld2WZ8/7ZQwCUb+CSr1iLk0FN7FntfZ8DN0LxuhZK7/q2GP+r1URKWsYe0P+2VrgTEo9vYEaPPTW5v+etTfQ5fTeN5DQVBv96FvCkf3iWcWX0lbSsYo5PYAQhsSnYmD5PuE4FRfLhjhssG1yPho45t1TRVAGZB5GJDF93nmrWZdj6TlNMDF7+cfDM3SgA6trnvo1U2/o3tOPIrTCO3QmnfY3n9zPvgIy/05aVX++5ZyFKIqm9K4QQJVy5ag2wqOjEOY+vSY6LolbnYVmOm9g4UtauEkG+e4m4d4P0lGTunz3EgUVjqNo2YwUx5M6FHFf/ACo264xareKsx9ekxMeQEBmC7y9zSUmIyTa21di5KHR02Dd/OFHBd0hPSebRFW+OLp2Mjp4+lpVqF/wvII+iH/oDUNauUo7HdQ2NaThgCo+v+nL6t0XEhT0kLTmRpzfPcmzZdPTLmFGv7/jM8U+un2Jlb2tOrpid65y6+oY4vzWfsIDLHP/hA2KfPiAtOZHHV3059sO0jGu6jc/3WD0jE5qNmMXjqz74rP6E+LBHpMTHEHBiFz6rPsaqSl3q9BhdUL+6Iqe+Q1lq2Zrw7eEAohNTGdI0a485RwtDKlka4Xk1hJtP40hOU3H4Vhjjfr9En39WEC8Gx2Q+P/hfrrXKoVKr+fZQRr+9kNgU5u29TUxSWraxn/SogY5CwZu/XsA/NJ7kNBU+gZG8u+Ua+ro6ONkVfhGfj3bdJDlVxeoRDfKUCAL4/9Ow/UVtJ/Lj9N0o7Gcf5KNdNwvkegD9G9nhXNWCaVuvcSooksTUdLwDIvh4902qWBkzvHnRe9ZRCG2TlUEhhCgFaroO4tSvC7P0FnxGodCh68e/4b3yI3bO6IFCqYtt7WZ0nv0LeoZlCAu4wv6Fb9LojXdzLDhS03UwsU/vc/vIZq7sXI6xpR11uo+ixaiP2P/5aNJTn2+ds6nVlH5fe3LO4xt2ftiL1IRYjCxsqObSjyaDp2VZWSxsyXEZ28ueVV3NSfM3P8KsfFWu71vP1T2/kJ6ShJG5NQ4NXegyew1m9tm30OnoKHO40nN1eo7FyNyaK7tXse3d9qSnpWBSzgGbWk1pOnRGluQ0P2MbDpyKqV0lruxaybb3OpKSEIepbQVqdxtF48Hvo2tQ9J77KkhvNLFnkdedLL0Fn9FRKFjzZkM+/esWvX86jVKpoFlFc1YOb0AZAyVXHsUy5reLTOlQmdldq2e79qAm9jyITGTr+cesPHkfu7IGjGzhyJxu1Rn7+6XMlUeAJhXM+GtSc5YeDqTP8jPEJaVhbWpA3wa2vN+xSpaVxcKQmJrOoZthALRccjLHMcObO/Dtf55xjE7MSHRNDXP/6Dh/721WnLiX5bUFnrdZ4JmxfXpAY3t+GpJ15T23Houvck2ljoINYxuz9FAgU7dc5WlMMpbG+nSuXY7ZXavnOfEVojRRqNUv2PsjhBCiyNiyZQtDhgwplF57JdWRbyYR6L2bt3cUbIGQ3Pitm4+hiTmNBr1fKPO9jv2fj+LJtVOM9riVr/NW9rZm8+bNDB48WCNxKRQKVg5vgFsD25cPFtlM2XyVPVeecu/zTtoOJZuFnncwN9bj3Q6VtTL/2PUXOXU3iutzO+TrvPEbLmPo1I4tW7ZoJjAhCs9W2SYqhBBCaEByXBT+x/6kSps+2g5FiCInOjGVHZee0KuezcsHCyE0RtbLhRBCCA0wMDFn5K+XtB2GEEWSmZEe5+eU3CJGQhQXkgwKIYQoVdJTU1jZ2xqA4WvO59hTsDTZPNGZqOCM4jmGppZajkZoQkqaCvvZBwE4PattkewTWJjafutDQGhGQRwLY72XjBaiZJNkUAghRKnh+r/luP5vubbDKFKGrPDVdghCg34aUi9b0ZbS7uSM1toOQYgiQ54ZFEIIIYQQQohSSJJBIYQQRYLn3MGseSPnHn9ClFTD1p6n2twj2g5DCFFKyTZRIYQQohCp0lI49sMH3D6yhVbj5tFwwBRthySERgWGJfDlfn98AiOITUqngoUhQ5qWZ2qHyugoXtxnUAihWZIMCiGEEIUkOS6KA4vGkJ6Wou1QhCgUIbEpuC0/Q73ypnhOaYl9WQOO3A5n6qYrPIpOYnG/2toOUYhSTbaJCiGEEIUgOS6KXR/2wr6eM85vLdB2OEIUiu+OBBKfksbyYfWpZGmEvq4O3etYM61TVdafCsb/n6qeQgjtkJVBIYQQGhd65wJnNnzF0xtnATWWlWrTZMh0KjR1feF5Dy+d4MKW7wm5fR51ehomNhWo6TqYBv0no9TTzxyXHBvJuU3fcu/UPuIjnqBnZIJ1jUY0Gz4Tm5pN8j1OExKjQqnfdwK1u4/i6c2zGp1LFA0Xg2P4+mAAZ+9HgRqc7EyY5lqVjjWtXnjeyYAIfjgaxIUHMaSpVDiaG/FGE3smuVRCX/f59/hRCaksPRLIgeuhPIlJxsRAl4aOZflf56o0rmCW73GasOvSE1pXtczWwqFnXRsWed1hz5WnTHOtqtEYhBC5k2RQCCGERoXcPs+umX2o13sc7aZ8g55hGc5t+havecPoPvcPKjbvkuN5T66fwnPuYKq07sWQlb4YGJclyM+TI99OJjEqlNbjF2WOPbRkPJH3b9FlzhrKVW1AQuRTfNd8xp6PBjDQ/TBmDtXyNe6/kmIi+G14rZf+rENW+GDuWCPHY+aONXI9JkqeCw+i6bviLGOdK7Ckf23K6CtZeiSQkesu8NvoRnR2KpfjeafvRjFszXl61rPhxIzWlDXUZd+1EKZuuUp4XAoL+jx/H070uMKtp3GsHtmQ+uVNeRqTzHzP2wxafY4D77WiajnjfI37r4j4VOou/PulP+uJGa2pbl0m2+uPopOITEilpk32Y5WtjNBTKrj0MPal1xdCaI4kg0IIITTKb+18yljZ0eqt+SgUGasazm8vIMhnL9f2rs01Gbzr54VSz4BW4+ZRxtIOgBod3uDm/j+4dXhTZjKYnpLMw4vHqdV1OLZOzQEwta1Ih2k/4PFWMx6cP4qZQ7U8j8uJYVlLJuwJLdDfiyjZFnrdwd7MgM961cgskjKvV008r4bwq++DXJPBfddDMNDVYW7PmtiVNQBgQGN7Npx5yOZzjzKTweQ0FSf8IxjWrDzNKmas7lW0NOL7QXVp+dVJjt4Op2o54zyPy4llGT0eL87532dehMam/HMd/WzHdBQKzI30CItNfuXrCyFenySDQgghNCY1KZ7H13yp0X5gZiIIoFDoMGLdhRee22rcPFqNm5ftdVPbijy64k1yXBQGJubo6OlhZF6Ou76eVGzWmUrNu6Kjq4e+sSmjPW5lnpfXcUK8rviUdPyCIunfyD5LtUwdhYKzs11eeO7cnjWZ27NmttcrWhrhExhJdGIqZkZ66CkVlDPRw+t6CJ2cytHZyRo9pQJTA12uz+2QeV5ex2lCUmo6APrKnCuG6il1SExVaTQGIcSLSTIohBDFhOLZh0q1GopJOfaEyBBQqzE0e/EzUjlJT0nmmudaAr3/IvbJPZJio1Cr0lGrMj5gqlUZHyIVCh26z93A4W8mcmDRGHQNjLB1ak6Fpq44dRmOgalFvsaJfFCrgX+9NzVAk9fWlJDYZNRqsCqj9/LB/5GcpuJX3wfsvRrCvYgEIhPSUKnVpKsyftfp/+ROOgoF60c3ZvKmK4z7/RJGekqaVTKjY81yDGtWHvN/ntHL6zhNMNJXApCSrs7xeEq6CiO94lfLUE3xfF8KkZPi9y9QCCFKKRMTEwDSkhO1HEne6ehkfBhMT81/K4VDX72N75rPqNC4I32X7GXspju8vSMYpy7Ds421rtGIoSt86btkDw36TyIlIRa/tfPwGN+SsIAr+R4n8iYlMQ6AsmXLamwOE2MjElLSNXZ9TVD+kyikpOV/1WvCxsvM97xN+xpW7JrYgpufdeDu550Y1swh29iGjmU5OaMNuyY2Z4JLJWKT0ljgeRvnb7y5+ig23+MKmo1pxjbX8Pjs//7TVGqiElKxMzPU2PyaEp+qxtTUVNthCFEgZGVQCCGKCXt7ewDiwh4Wm0IkZazsUSh0SIh4mq/z4iOecPfUPqq360/T4R9mORYbEpzzSQoFdnVaYlenJc1HzuHpzTPsnuXGOY+v6fbJ+vyP+5eCKCBTEsWHPwbAzs5OY3PY2dnyKDpJY9fXBHszQ3QUCp7G5u9LkCcxyey/Hkq/hnbM6Jy1wmZwVM5fAikU0KKyOS0qmzOrazXO3o+m/4ozfHsogHWjGuV73L+9bgEZu7IG2Jjqc+tpXLZjd0LiSVOpaeSouS8SNOVJbCqtNfieF6IwSTIohBDFRO3atdHV0yPM/3KxSTh0dPWwrd2cR5dPkJ6SjFLfIPPY1qntUOoZMuC7A9nOU/2zkmhYNuv20sgHt3l81SfjD/9sUXx81YfDX0+kxzwPrKrUzRxr69QcYwtbkmIi8jUuJ1JAJmdhAZfR1dPDyclJY3M0aNiYK7e8NXZ9TdBTKmhWyQxv/wiS01QY/KsdhOv3vhjo6uA1tWW2856tJFr+Z3vpnZB4fAMjAVCT8b73DYxk8qYr/DG2MXXtn69SNatoho2pAREJqfkal5PXLSAD0L+RPb/6PiA8PgWrfxWS2XX5Cbo6Cvo1LF5JVUJKOv5PYqhfv762QxGiQMg2USGEKCYMDAxo5dyaB+ePaDuUfGk5Zi5pKckc+XYiiVGhpMRHc+b3L4i4e4M6PcfkeI6JjSNl7SoR5LuXiHs3SE9J5v7ZQxxYNIaqbd0ACLlzAbUqHesajdFR6nJ06RRCbp0jPSWZ5NhILu9cTlzYQ5y6jgTI8ziRd8HnjtDKuTUGBgYvH/yKOrq6cjIwktT04lVo5JMeNUhKUzFl0xVC41KISUxj8QF/bjyJY1QrxxzPcbQwpJKlEZ5XQ7j5NI7kNBWHb4Ux7vdL9KlvC2T0LkxXqWlUoSy6SgXvb7nG+QfRJKepiEpIZeWJezyKTmJ484xtpXkdpynvd6yCZRl9Jmy8QlB4AslpKnZeesLy4/eY5loVB/PitU30hH8E6WoVHTp00HYoQhQIhVqtzvmpXiGEEEWOu7s7sz76hBG/XUHPyETb4eTZk+unObthMaF3LqJWq7GoWIuGA6ZQtU2fzDGecwfz+Pop3tp2D4DwoGt4r/yIMP9LKJS62NZuRssxc9EzLIPXvGHEPA6i0Rvv0vzNj4gLe8i5DUsIvnCMhKhQ9I1NMHesQb0+71DNpW/mHHkdpwm+az7j8o6fcz1eo8MbuP5vuUZjKEipiXFsGF2fJV8u4r333tPYPMHBwVSuVImfh9bDrYGtxubRhDP3olhyIIBLwTGogZo2ZZjUrhK96z//OYatPc/pu1EELHAF4NrjWD796xaXg2NQKhU0q2jOx91rUMZAych1F7gbnsCUDpWZ3bU6j6KT+OZgIMfuhBMal4KpoZLq1mV4q3XFLL+rvI7TlIdRSXyx35+/b4cRm5ROtXLGjG1dgVEtc06Ki7J3Nl4hyqQyJ7x9tR2KEAVhqySDQghRjERGRlLewZFGQz+k4cCp2g5HlGKXtv/IxU1f8+hhMBYWmq3E2rdPHx5c8WHvxKbFpZCuKIECwxLo8L0fa9f9ysiRspNAlAhbZZuoEEIUIxYWFsya+SEXNn+b76IsQhSUxKhQLm79jlkzP9R4IgjwxeLFXAmOZuv5RxqfS4jcfLb3DjVqVGfo0KHaDkWIAiPJoBBCFDMzZ86knJUlZ35fpO1QRCl1+reFWJmbM3PmzEKZr27duoyfMIEvDt4lNjmtUOYU4t8O3wrj0I0Qfvp5Bbq6Un9RlBySDAohRDFjbGzMD99/x61Dm7h9eJO2wxGlzO3Dm7h1aBM/uH+HsbFxoc27YMEC0DNi6pbrqOQJF1GIHkQmMm37TYYNHSKFY0SJI8mgEEIUQwMGDGD27NkcXzadR5dPajscUUo8uX6KEz/9jzlz5jBgwIBCndvKyoo9nl6cDIxmoZd/oc4tSq+45DRG/34Vh8rVWLX6F22HI0SBkwIyQghRTKlUKt4YNJj9h47Q+eP12Ndtpe2QRAn2+JofhxaNoltnV7Zt3YKOjna+T/bw8GDEiBFM71SFGZ2qSUEZoTGRCamM/eMK9+OVnDpzlgoVKmg7JCEKmhSQEUKI4kpHR4cNf/xO986ueH4yULaMCo25fXgTnp8MpFtnVzb88bvWEkGAYcOGsXLlSn74+z5TtlwjOa149R8UxYN/aDy9lp/jSZoRBw8fkURQlFiyMiiEEMWcWq3m448/ZvHixdTqPJQWoz/FyNxa22GJEiAxKpTTvy3k1qFNzJ49m0WLFqEoIktxhw8fZtDAATiY6rCodw1aVDbXdkiiBEhTqVnvF8ySw0HUqdeQnbv/wsbGRtthCaEp0mdQCCFKih07dvDu+9MIj4ik0eDp1Ok5plg1phdFR2piHNc9f+XilqVYWViw7Ifv6d+/v7bDysbf358pkydx8NBh+jeyZ0anKlQtV3hFbUTJoVKrOXo7nM/3BxIUlsAH02fw2WefYWhoqO3QhNAkSQaFEKIkSUhIYMmSJXy15GvUCh0qteyBY1NXylVrgEm58pIcihylJMQSH/aIsMArBJ87wr1TXijUKmbN/JCZM2cWatXQV7F7925mfPA+AUH3cK5mRTcnS5pWNKeKlTHmxrroFJHVTFF0JKepiIhP4ebTeLwDIth7PZy7obG49e7Nt999R/Xq1bUdohCFQZJBIYQoiSIjI1m/fj3bd+zEx/sk6WnSm028nFJXl9Zt2vLGgP68+eabhdJQvqCkp6fj6enJxg0b2L/Pi8joGG2HJIqJGtWq0rf/AMaOHUudOnW0HY4QhUmSQSGEKOmSk5O5fv06T58+5ezZsyxZsgQHBwfmz59fZJ7/KmyBgYHMnj2bZcuWYWtrq+1wtM7U1BRbW1vq1KmDgYGBtsN5bWq1mrt37xIYGEhUVBQqlRSZmTVrFo0aNWLYsGHaDqXQ+fn58d1339G9e3fGjBmDQqHAwMAACwsL6tati6WlpbZDFEJbJBkUQojSYtu2bYwaNYpu3bqxYcOGIr/1T5MuXLhAkyZNuH37NjVq1NB2OEJoXKNGjejduzeff/65tkPRih07djBixAi6devGxo0bMTIy0nZIQhQF0lpCCCFKA3d3d4YMGcI777zD9u3bS3UiCGS2RpAVI1FaqFQqrbYE0bb+/ftz5MgRTp48iaurK2FhYdoOSYgiofTeFYQQohRIS0tj0qRJzJgxA3d3d9zd3Uv1B8JnJBkUpU16enqp/7ffqlUrjh07xuPHj2nXrh337t3TdkhCaF3pvisIIUQJFhsbi5ubG3/88Qc7duxg6tSp2g6pyFAqlUDGB2QhSoPSvjL4TJ06dfD19cXQ0JBWrVpx/vx5bYckhFbJXUEIIUqghw8f0q5dOy5evMjff/9Nnz59tB1SkSIrg6K0kWTwOXt7e44fP06jRo1o3749+/bt03ZIQmiN3BWEEKKEuXTpEq1atSI9PR0/Pz+aNm2q7ZCKHEkGRWkjyWBWJiYm7Nq1i759+9KnTx9++eUXbYckhFbIXUEIIUqQnTt30rp1a2rXrs2JEyeoWLGitkMqkiQZFKWNJIPZ6evr8/vvv/Pxxx8zfvx45s2bp+2QhCh0utoOQAghRMFwd3dnxowZjB07lp9//hk9PT1th1RkSTIoShtJBnOmUCiYN28e5cqV4/333yc4OJgVK1agqysfkUXpIO90IYQo5tLT0/nggw/48ccfmTt3rny7nQeSDIrSRpLBF5s6dSqOjo4MHz6csLAwPDw8pBehKBXkriCEEMVYfHw8/fv3Z/Xq1WzcuFESwTx6Vk1UkkFRWqSnp2e+70XO+vXrx5EjR/D29qZjx46EhoZqOyQhNE6SQSGEKKYeP35M+/bt8fHx4eDBgwwdOlTbIRUbz1ZIpLWEKC1kZTBvWrVqxfHjx3ny5AnOzs74+/trOyQhNEruCkIIUQxdvXqVVq1aERMTg6+vL23bttV2SMWKbBMVpY0kg3lXu3Zt/Pz8MDMzw8XFRXoRihJN7gpCCFHMHDx4kLZt21K9enVOnz5NjRo1tB1SsSPJoChtJBnMHzs7O44dO5bZi9DLy0vbIQmhEXJXEEKIYmTNmjX06tWLfv364eXlhbm5ubZDKpYkGRSljSSD+WdiYsJff/3F0KFDcXNzY/Xq1doOSYgCJ9VEhRCiGFCr1cyfP58FCxYwd+5cPvvsMxQKhbbDKrYkGRSljSSDr0ZXV5dVq1bh4ODAhAkTePjwoRTqEiWKJINCCFHEJScnM3bsWLZv38769esZOXKktkMq9qSaqChtpJroq3vWi7BChQpMnDiRBw8esHLlSulFKEoEeRcLIUQRFh4eTr9+/bh+/ToHDhygffv22g6pRJBqoqK0kZXB1/fWW29Rrlw5hg0bRnh4OBs3bsTY2FjbYQnxWuSuIIQQRZS/vz/Ozs48evQIb29vSQQLkGwTFaWNJIMFo2/fvhw9ehQfHx/pRShKBLkrCCFEEeTt7Y2zszNWVlb4+vri5OSk7ZBKFEkGRWkjyWDBadmyJb6+vkRERODs7MydO3e0HZIQr0zuCkIIUcRs3ryZzp0706FDB44cOYKNjY22QypxJBkUpY0kgwWrWrVqnDhxAjMzM9q1a8e5c+e0HZIQr0TuCkIIUUSo1WrmzZvHsGHDGD9+PJs3b8bIyEjbYZVIkgyK0kaSwYL3rBdh48aNad++PZ6entoOSYh8k7uCEEIUASkpKYwePZpFixbx008/4e7uLh/cNEiSQVHaSDVRzTAxMWH37t0MHz6cvn37Si9CUexINVEhhNCyyMhIBgwYwLlz59i1axc9e/bUdkgl3rMPxVJNVJQGarUatVotXzBpiK6uLitXrqR8+fLSi1AUO5IMCiGEFgUGBtKrVy9iY2M5fvw4jRo10nZIpYJCoUChUMjKoCgVnr3PJRnUnGe9CCtWrMiECROkF6EoNuQdKoQQWuLn50ffvn2xt7fn4MGDODo6ajukUkVHR0eSQVEqSDJYeMaNG4eVlRXDhw8nNDSUTZs2SS9CUaTJXUEIIbRg+/btuLq60qRJE06cOCGJoBZIMihKC0kGC9ezXoR+fn507NiRkJAQbYckRK7kriCEEIXM3d2dwYMH884777Bnzx5MTU21HVKpJMmgKC0kGSx8LVq0wNfXl8jISOlFKIo0uSsIIUQhSUtLY/LkycyYMYPvv/8ed3d3qe6nRZIMitLi2ftc7jeFq1q1ahw/fhwLCwucnZ3x9fXVdkhCZCPJoBBCFIK4uDj69u3L+vXr+fPPP3n33Xe1HVKpJ8mgKC2eVc2VlcHC96wXYcuWLenSpQt79+7VdkhCZCF3BSGE0LCHDx/Srl07Lly4wLFjx3Bzc9N2SIKMVRJpLSFKA9kmql1lypRh165dmb0IV61ape2QhMgk1USFEEKDLl++TK9evTA3N8fPz4+KFStqOyTxD1kZFKWFJIPa999ehIGBgSxevFjbYQkhyaAQQmjKvn37GDx4MK1atWLr1q2YmZlpOyTxL5IMitJCksGi4b+9CJ8+fcqqVavQ09PTdmiiFJNkUAghXkF6evoLizGsWrWKKVOmMHr0aJYvXy7/sdeyhQsXcuXKFSIiIkhLSwNAX1+f5cuXs2nTpsxxsbGxrFu3jgYNGmgrVCEKnCSDRcu4ceOwtrZm6NChPHr0iG3btklVaaE1kgwKIUQ+qdVq3NzcWLx4MfXr189yLD09nenTp7Ns2TLmzp3LvHnztBOkyMLU1JStW7dme/3JkydZ/mxpaUndunULKywhCoUkg0VPnz59OHr0KH369KFTp07s2bMHGxsbbYclSiG5KwghRD5t2LABT09PunfvztOnTzNfj4+PZ8CAAaxcuZINGzZIIliEDB8+/KVl9fX09PI0Toji5lmhJHlvFy3PehFGRUXh7OzM7du3tR2SKIUkGRRCiHyIj49nxowZKBQKQkND6dGjBwkJCTx+/JgOHTrg7e3NwYMHGTZsmLZDFf9iY2NDx44d0dXNfUNMamoqQ4YMKcSohCgcsjJYdFWtWhVfX19sbW1p3bo1Pj4+2g5JlDJyVxBCiHz48ssviYiIQK1Wk5qaytWrV+nWrRvOzs5ERUXh4+ODi4uLtsMUORg1atQLW0k8+zAmREkjyWDRZmVlxcGDB2nVqhVdu3Zlz5492g5J40O7tAAAIABJREFUlCJyVxBCiDx68OAB33zzTWYBEshYTfLx8UGhUHD69Glq1qypxQjFiwwYMABDQ8Mcj+nr6zNixAj5sCxKJEkGi75nvQhHjBhBv379WLFihbZDEqWE3BWEECKPpk2blmMrApVKxd27d9m4caMWohJ5VaZMGfr3759jZdeUlBTZIipKLEkGiwelUsnKlStZtGgRkyZNYvbs2ajVam2HJUo4uSsIIUQeeHt7s2PHDlJTU3Md895777F79+5CjErk18iRI3P8O3RwcKB58+ZaiEgIzZNksHiZNWsW69atY+nSpYwbN+6F/90R4nXJXUEIIV5CpVIxadKkl1biU6vVDB06lIsXLxZSZCK/unTpgpWVVZbX9PX1efPNN1EoFFqKSgjNepYMSjXR4mPMmDHs2bOH7du306tXL2JjY7UdkiihJBkUQoiXWLt2LdeuXcvyrOB/PatSaWxszPHjxwsrNJFPurq6jBw5MstWUdkiKkq6Z4WTZGWweOnatSuHDx/m0qVLdOrUKUsrIyEKikItm5GFECJXsbGxVKlSJbOC6H/p6uqSnp5Ohw4dmDRpEv369cvxmTRRdJw5c4YWLVpk/rly5coEBQVpMSIhCk5aWhodO3YkKioKAIVCgbGxMdevX6dOnTpZiiiVKVOGnTt3yj2riAsMDKRHjx6kpqbi5eVFrVq1chwXHx9PmTJlCjk6Ucxtzb3hkhBCCObPn090dHSWRFBXV5e0tDRsbGwYO3YsEydOpHLlytoLUuRL8+bNqVGjBnfu3EFPT48333xT2yEJUWB0dXWxs7PD29s72xdYp06dyvz/CoUCNzc3SQSLgapVq+Lj44ObmxutW7dm9+7dtGnTJsuYsLAw2rdvz7Zt26hdu7aWIhXFkewXEEKIXNy5cwd3d/fM7aFKpRKlUknv3r3x8vLi8ePHLF68WBLBYmjUqFEoFApSU1MZPHiwtsMRokANGzYsT+NGjx6t4UhEQbGysuLAgQO0bt2arl278tdff2UeS0xMpGfPnly/fp3p06drMUpRHMk2USGEyEWvXr3w9PQEMrYSTpo0idGjR2Nra6vlyMTrunfvHlWqVKFGjRrcunVL2+EIUaCSkpKwsrIiISEh1zGmpqaEhoZiYGBQiJGJ15Wens7UqVNZvXo1P/74I++88w79+vVj3759mV9cHj58GFdXVy1HKooJ2SYqxL8FBweze/duDh85wsWLlwh5+pS4OKngVRoZGRmRlJREhQoVGDhwINOnT6dChQraDivfEhMT8fLyYv/+/Zw+e46gwCBiY6Jy7JdYGt2+fVuqiP5D38AQM3Nz6tWtS5vWzvTu3ZuWLVtqOyzxCgwNDenfvz9btmzJsS2Bnp4ew4YNk0SwGFIqlSxfvhxbW1smT56Mh4cH3t7emUWClEol7777LleuXJGCQSJPZGVQCODy5ct8+ulc9u7dg4GRMfVbtqdanUZY2pbH2MRU2+EJLbh18TR6+gY8CLjJlVPHSE5MoFev3ixcuIAGDRpoO7yXio6O5ssvv2T5ylXExcRgWb0xJtWaYmxbBT0TcxQK+ZAQfvU4Jo61MDCXlV4AVWoyKbERxAXfJOamNzFP71Ordh0++WgOI0aMkKS5mNmzZw99+vTJ9fjx48dxcXEpxIhEQXvjjTf4888/sz0bqqOjw5o1axgzZox2AhPFyVZJBkWpFhERwaeffsrKlSupXrcxfce9T8tOvdHV09d2aKIISUtN4dThPexa647/tQtMmDCBhQsXYmlpqe3QslGpVKxbt45Zsz8iITWdCt3G49h+GPpm1toOrchRpSajoycrI7mJCbrM/YNreXRyG81btOSnH3+gadOm2g5L5FFqaipWVlY59qcrX748wcHBkuAXYxs3bmTkyJE5VrlWKBRYW1sTGBgo1UXFy2yVr4ZFqeXr60vt2nXYvO1Ppi5azleb/6ZN9wGSCIpsdPX0adN9AF9t/pupi5azeduf1K5dB19fX22HlkVUVBRdunVn/ISJmDR1o/USb6q6vSeJYC4kEXyxslUaUG/897RauJ+AaDXNW7Rg8eLF2g5L5JGenh4DBw7MVi1UT0+PsWPHSiJYjB05coTRo0fnmAgCqNVqIiIiWLp0aSFHJoojWRkUpZKHhwdjx42jYWtXPliyVraCinxJiIvlu5njuORzhHVr1+a5cp8mBQQE0KNnbx5HxNBg2q+UrVxf2yGJkkSt5t6BNdzaMI+Rb77J6lUr0deXL86Kuv3799O9e/dsr1+9epW6detqISLxui5cuEDbtm1JTEzMNRl8xsjIiMDAQOzs7AopOlEMycqgKH1Wr17NiBEj6D5sPHOWbZJEUOSbsYkpc5Ztovuw8YwYMYLVq1drNZ6AgABatHQmPN2Q5p/tlURQFDyFgkrd3qbxjPVs3rodt379MwtWiKKrU6dOWFhYZP5ZoVDQoEEDSQSLMZVKRb9+/dDV1UVX98V1INPS0vj0008LKTJRXEkyKEqVw4cPM3nKFIZMmcO4WV+io1RqOyRRTOkolYyb9SVDpsxh8pQpHD58WCtxREVF0aNnbzB3oOlH2zGwkG+AheZYN3SlyewtHDlylGkffKDtcMRL6OrqMnjw4MxVXKVSKUVFirmmTZuyYcMGQkJC+OabbzKrXOeUGKamprJ27VquXLlS2GGKYkS2iYpSw9/fn+bNW9CgbRemf71WnpcQBUKtVrP0w3FcPnmQM2dOU7169UKbW6VS0aVrN05fuk7zz/ZKIigKzZPTe7j04wR+/uknJk6cqO1wxAscPXo0s+ecjo4ODx8+lG2DJYhKpeLIkSOsWLGCnTt3olQqSUlJyTyuq6tLx44dOXDggBajFEWYVBMVpUe3bt0JePCYxZuOom9gqO1wcpSWmsKPn0zm6C4Pxsz8gv7j3tdqPI/u+fP70nlcPX2chLhYbBwq0WnASAa+PR1FHvoXBVy7wAb3Bdy44EdqcjIOVWrQZ9QUOg8c9UpzpSQnMaih1Qvn7DJoDFMX/vRqP/ArSklOYvbQjlSrYM/+/fsKbd41a9YwfsJEWs33LPZbQ1WpyRwYW/mFYxw7jKDe299oLIaEJ4Hc3vIlETd8SEuMxahcBRzaDaFKn6kvbMXxqrGr0lK5+st0Hp3cRq1hc6nSa1IB/BSF5862r3h88Bfu3L5F+fLltR2OyEV6ejq2traEh4fTqVMnDh06pO2QhIbcv3+f1atXs3z5ciIiItDR0cnczn3gwAG6dOmi5QhFESRN50XpsGvXLg4ePMCi9fuKbCIYFxPFl1OHkpZDg2BtiAx7yuxhnaji1ICvtxzDyrY8508cZOmHbxH2OJiJn33/wvP9Du5m8fsjaN21H0u3n8TC2o79m9bw46dTiI2OzJLo5nUufQNDdt2Mz3G+U4f38MWUIbj0eKPgfgl5pG9gyPi53zF7eGd2796Nm5ubxueMiYlhzkefULHL2GKfCEJGZc/ufzzO8VjIuX2c/24s9q0093tNjg7Bb4EbphXr0Wq+J4YW9oRdPsKl5VNJinhEnTG5V9F8ldhT46O58P04VGlF49/7q6jW9wNCT+/mw5mz2PDH79oOR+RCqVQybNgwfvzxR9kiWsJVrFiRhQsXMnfuXHbu3MmyZcs4efIkarWaadOmcfnyZZTyeIz4D1kZFCVeeno6NWs5UaFOE6Z/vU7b4eQoLiaKWcNcadN9AE3bdWXmkI4FsjIY9jiYIzs3cPvyWT5ZvjVf565c8AGH/vydtX/fxtT8eT+97auX8vvSufy49zyOVWvmev6kbg1JTk5k5YEr6Ok/L+H/4yeTOb5nK2uP3cbEzKJA5kpKiGNKr6Y4NW7Fh0t/y9fPWZCWfjiWB9fPc/vWTY3/B3f27Nn8sOIXWi/xRq+MmUbn0qb0pHhOzGqHRY3mNJy64pWukRT+iIcnthAdeIEm03N+f1z/dQ4Pj2+iww/n0TN5XnAj8K8fub3lC1y+Ok6Z8vnbApxb7Knx0Zya3we7ln0o19AVv3m9i+XKIMDTs15cdH+LU6dO0bx5c22Hk0VwcDC7d+/myOHDXLxwnpDQUGLjcv4ySZRspiZlsLG2plHjJrh26oSbmxuOjo7aDivfEhMT8fLyYv/+/Zw7c4qgoCCiYmJRqeSjfGmgo6PAvKwpVapUoWnzlnTr1o0ePXpgZGT0OpeVlUFR8u3du5egwABmLv+zUOedM7Ir/lfP87vPXQyNTbIc++O7eWxd+TWLft9HveYuRIWF4DZ6Kt0Gj+PWpdOvNe+zBumHtq/ngvdhLMrZ4jZ6ar6vc8JzG/VbuGRJzgCcu/Rh/bef4rN/B4Mnzcrx3LiYKB7d86dtj4FZEkGANj0GcnDbb5z5ex8d+w577bkANvzwOfExUbw1W7s90Ia9+wmTujXE09OTPn36aGyexMRElq9YRYVuE4t8InhqYT9igi7h+vNVlIZZmx/f3rKYwN3utPj4TyxrO+d4/p3tS0iLj8FpxLx8zatKSyXk3D6Cj3kQfuUY+uY2VO7+Tq7jH/vtwrJ26yyJIIBt857c3ryIJ6f3UK3ftHzFkFvsKdGhVOo+ngquI4nyP5evaxY1ts16YFGlPsuW/cj69dr7IubfLl++zNxPP2HP3r0Y6evhUsuWgfUssbcoj6mh3ssvUAKpgZ1ngujfvIq2Q9GK2KRUHkcmcCXwLLO89vLee+/Su1cvFiz8nAYNGmg7vJeKjo7myy+/ZNWK5cTExtG4ghlNHQx5o205zI3s0MlDCYSUdDV3QhOoaydN6IsrlRqiEtMIigjh/P6trPnlF8qamjB+4iTmzJmDmdmrfR6QZFCUeBs9PGjQsj32FasV6ryufYdz/aw3p4960q7X4CzHTnhuw9axMnWbtQXAsWrNF6585cXdW1c5tH09f+/2ICE2hibtuvLxT5tp2q5bvqumhj0OJjYqggrVnLIds69YDaWuHgHXLuR+gWcbDnIo0mP6z2rg3ZuXoe+w154r5NF99v6xgjfGz8DSxv4lP5lm2VesRv2W7djo4aHRZNDLy4u42Bgc22u/v+HLOLgMIvLWKUIuHMDeuX+WY0/8dmJkXRFLp1Y5npsYFsy9A+uo2mdqnovjxN6/TvCxTTzy3kZaYizWDV1p/ME6rBt1QqGT87+DpPBHpMZFUsYh+79BY9vKKJR6xARdytP8eYm9TPnq+V5lLMrs2g1n25aFrF69CgMDg5efoCERERF8+umnrFy5goaVrFn5lgvdG1ZAX1cKpwP0aOiIvq5sEUxJU7Hv0gN+PnSaJk0aM2HCRBYuXIilpeXLTy5kKpWKdevW8dHsmaQnJzChpQ1DG9fE2qR0fqkhsgqNS2XThRBW/+zOujWr+WLxEsaOHYtOHmo6/JvcIUWJplar2b9vP8069ij0udt0H4C+gSEnPbdnef3WpdM8eRCEa78RBVLR1P/qeWa84cL7fVty5m8v+o59jzV/3+KT5Vtp3rHnK7XPiAoPAaCsRblsxxQ6OpiaWRAVFpLr+SZmFthXrMaN876kpaZkOXb9nA8A0RGhBTLXluVfoW9ggNuYd1/yUxWO5h16sM9r30ubAb+O/fv3Y1m9Mfpm1hqbo6DYteiDjp4Bj/12Z3k9yv8cCSH3cHAZnOOXBgABO79HqWdA5R4TXjpPdNAlfD/tjvdHnQi9eJAqPSfQwf0sTab/hk2TrrkmggDJMRnvRX3T7B8GFQod9EzMSY4Je2kMrxp7cWfTpCuJCfGcOHFCazH4+vpSx6kW2z3W8/2bznjN7IZb00qSCP6LJIIZ9HV1cGtaCa+Z3fj+TWe2e6ynjlMtfH19tR1aFlFRUXTv2oWJE8bTp7oBJ6bU510XB0kERSZrEz3edXHgxJT69KluwMQJ4+netQtRUVH5uo7cJUWJFhgYSFRUJE6NWhb63MamZWnh2ovzJw6SEBeb+frxv7agUCjo2G94gcwTdOMyAdcuMHjSLFbsu8SgCR9iYf16ZcNTkhIB0NXL+T86uvr6JCclvPAaY2YuIvzJQ76b+TZP7geSEBvD4R1/4OXxC5DRDPd15wp9/IAjOzbQe+QkTMqav/wHKwS1GrckKiqSu3fvamwO39NnMKnWVGPXL0i6xmWxadKNsMtHSEt8/u/gsc8OUChwcBmU43lJ4Q95eGILFbu+laetsLH3rhJ99zLV+k3D5Rtvqrq9j4G5bZ5iVKUkAaCjq5/jcR1dPdKTE/N0rVeJvbgztLTHpFx5zp8/r5X5PTw8cO3YgUbljfGZ14chztVy+35BiEwKBQxxrobPvD40Km+Ma8cOeHh4aDssAAICAnBu2YJr5/3Y8049FvSojJmRbOYTOTMz0mVBj8rseace18774dyiOQEBAXk+X5JBUaIFBQUBYF+pcLeIPtOx73BSU5I5degvAFTp6Zz02k7d5m2xdaxcIHNUrdOQGg2asWX5V0zq3ohtq74hMvRJns4NDrxNX6cyWf63ZflXGBgZA+Ra2TQ1JRkDQ+MXXrtV5z7MXbWDh3fvMKVXU97pXIfzxw8wy/0PAIzKZDxH+TpzHd25EVV6Gl0Hj335D1tIylfK2P737L2nCffv3sPYtvg8++PgMghVagpPz2W03VCr0nl8ajeWTs4YWVfM8ZyHJ7aiVqVRoeOIPM1RtlJ9zKs2JmDn95z4X1sCd/9ActTTPJ2r1M94+F6VlpLjcVVqCkqDvD+gn9/YSwJju6oafc/nZvXq1YwYMYKxLtX5dWL7UvtMoHh1poZ6/DqxPWNdqjNixAhWr16t1XieJYIGiSHseas29e3lGT+RN/Xty7DnrdoYJIXi3LJFnhNC+ZpBlGgxMTFAxiqdNjR26YyZlTUn922nY7/hXD51jKjwEEZ/+HmBzVGtbmO+3vw39/1vcHDbb+xa9wMb3RfStH03ug4eS1OXrrluFXWsWjPHVg0RIRll8qMjs2+NS09PIy4qEstmL+8r1rRdV5q265rltXt3rgNg55iRzDxbxXyVuXz276B6/abYOFR6aSyF5dl7Lb/bNPIjLi4GvTLaeU+/inL1O6BfthxP/Hbj0HYQEddPkhIdisPQT3I958npPZhVbYSRdYU8zVG2SgNazd9LXPAtgo9t5K7XSu5s/xrrhp2o0HEE5Rq65rpV1MDcBoCUmPBsx9TpaaTGR2GYx2cWXyX2kkDH0FSj7/mcHD58mCmTJ/O/Xg34sE/DQp1blCxKHQXzBzXDxFCPKZMnU7VqVTp16lTocURFRdG7Z3fKG6ezbZQTxvqyZiPyx9ZUn22jnHjjt5v06tEdv9NnMDd/8c4peZeJEu3ZVkSlUjvfeyiVurTrNZgLJw8THxPN8T1bMDQ2oXW3fgU+V8XqtXlr9mLWHffnf0t/JS01hUWTB/O2qxM71rrn61qWNvZYlLPl/j+J278FB9wiPT2NGvVfbZvizQt+ANRu6vxacz15EETQzSs0bNXhleLQlGfvtWfvPU1IT0t74TNwRY1CqYu9c3/CrhwjNSGGRz47URqWwa5F7xzHJ4TcI/b+NazquuR7LhPHWjiNmE+HZRdpOGU5qrQUzi8dw7H3mxG0d3mO5xhY2GFgZkPcw1vZjsU9uoM6PQ2zqo3yNP/rxF6sKXUzm1sXBn9/fwYNHECfJhX5X29JBEXB+F/vhvRpUpFBAwfg7+9fqHOrVCoGDRxATOgj1g2pLomgeGXG+jqsG1qd2NBHvDFwACqV6oXj5Z0mhIZ17Dec9LRUTh/15NShv2jTrR+GRprb9qGrp0/rbv35bPVO1hy5Sbchb3HtzMl8X6ddnyFcO3OS6IisK3YnPLehVOri0uvFzd3XfDmLiV0bkP6vptpqlYr9m9fiWK0WtZs8byXwKnPdOJ+RVFapXfTLgouMraLq9FRCzx8g5JwXdi16ozTIeftv1O0zAJStVPeV59PR1cOuRW+azdxIe/ezVOg0ishbfrmOt2/dn4gbvtlWB5/47fonmc3bFzgFEbt4ualTJuNgboD7KGd5PlBLAkNieGvlMZxmbMZxyh84z92Ju9cVVHksnqVSq1l95AYu83bhOGUD9Wdu5X9/+BGdkH279oW7YYxZ8TcNZm3DccoftPhkB/O3nyMuKefHC1LSVExZdxKbCev5+cC1PP9MCgW4j3LGwdyAqVMm5/m8grBu3Tr+PnaMtUOqY2ua8/PLomgICk9i/Obb1P/qDJUX+OHywwWWnXhIXts9vu75eWFrqs/aodU5duwY69a9uMe2JINCaFi1Oo2oWL02m376griYKFwHjCy0ua3sHBgyeXa+G84DDJrwIaYWVnz9wZs8vh9ASnISJ/ZuZedadwZPmoW1/fMtcJd8jtLXqQzrvpqT+VoTly48CQ5ixYIPiI2KIDLsKT/Nncr9O9eZuvCnLJVU8zPXMw+DbgNgV6H4PDtXmpWtXB8Tx1r47/iW1PhoHFyG5Do2/nHGN/JGNgWz/dfQ0p5q/T7IteE8QLW+76NvasnFHyeQ8DQIVWoyj313EuS5nGp9p2Fo5ZA5NvzqcfaNtOfmxvkaj11kt2vXLg4cPMSiQU0w0NPOCvmjyARsJqznQXicVubXtpCYRHot2UdMYgr75/Qk0H0Ynw1syvdeV5jtkbdeubM9TrN410Xm9G2M//dDWf1Oe/ZevM/QZYf5dz7pe+cpfb7ej75Sh70zu3Pj2yF83K8xa/++xSD3Q9mSz6iEFIa4H+JuaCyvwkBPyVdDmnHg4CF279798hMKQExMDJ98NJuxLeyK/DOCj2NScPjMlwdRydoORStC4lLpu+Yqsclp7Blfn9sfteCTrpVYdvwhH+8N1Pj5+VHfvgxjWtgxZ/bMF27jl2cGhSgEHfoOZ/23n2bpLfhv676aw851P2R57dclH/Hrko8AaN9nCNO/XpvjtfduWMGqhTNeOH8Vp/p8vzP3VZGcmJpb8pXHYX5f+hkzh3QkIS4Wh8rVefujJXQf+vZLz2/ctjNzlnmwbdU3vO1aGx0dBU6NW7F44yGq12vy2nPFx2Tc2IxNTPP1cwntKd/mDW5vXvTC3oIAqfHRAOga5f3v9v7BtVz/7eMXjjGtWJc2XxzK8ZieiQWtPvuL21u+wG9eb9ISYzG2q0btkQup0GlUnuPIS+w3N87nrueKLK/d8ljALY8FAJRvM4AGk37K85ylSXp6Ov+b/gEDWlTFuUbeqsVqgs/tvBXpKqm+3XuZ+KRUVr3TDosyGb0luzeswPReDfh8x3necXWihl3ulXTPBYby67FbLH3TmZ6NM4pItaphw9wBTfj54HX8n0Znnr9oxwXKmRrw49i2ma1C+jarzIV74fx84BqX7oXTuHJGa6KohBR6L/HCrWklOtV1oMdXXq/08zWvZs2AFlWZ8cE0evXqhfIVWjTlxxdffEFqYhwftK+v0XkKgk9QtLZD0KrvjwUTn5LOz2/UxMI4I43q5mTJ++0d+PLQfd5qZU/1crkXHHvd8/NrensHdly9wuLFi1m8eHGOYxRqTTbDEkLLtmzZwpAhQ3IskiKEpvR1KsPmzZsZPHiwRq6vUCho9O5K7Fq6aeT6QuTXxWXjcaloyJYtWzQ6z+7du+nXrx9+C/pRxSZvXxZcfRDBkr8ucco/hPjkVOzMjenduCLTezWgrNHz7XjDlh0m4GkMm97rxLxt5/C785R0lZo6jhbMH9SMJv8kHEN+OMTRa48yz9PXVRL80wiG/JCxGrV2Qgcmrz1JwNMY7i0bjlJHwemAEJbuvcK5oFASktOwNTOiawNHZrk1ykymANy+2ceDsHjWT+nIp1vOcPFeOGo1NKtajgWDmlPX0QKAvt/s5+K9cK5+PShbBVV3ryss2nmBLe93pkOdlxf6ehW1pm+mSZVyeLybtchKwNMYnOfuZHbfRkzvmfsW/hl/+LL9dBC3lw55af/DlYdvYF3WkAHNs+4C2eQTwHu/efPL+Pa4Nc1Yib/zJBrfO08Z5VKTc4Gh9PjKi3kDmzK5a/63bQeFxNJq7k527dpFnz598n1+XiUmJuJgb8eE5ua86+Lw8hPy4dqTeL49GsypezHEp6RjX1afHrWt+KC9I6aGz3/vb/5xg4DwJDaMrM2C/Xc5dT8WlUpNbVtjPutemUYOGdW/R/x+g7/9n68w6evqEPRpS0b8foO7EUmsHlKTd//0JzA8Cf+PW6DUUXDmfizux4I5FxxHQmo6tib6dKllwf86VshMhgAGrL3Gg6gk1g1zYt6+u1x6FIdaDU0cTZnXvRJ17DJWTAeuvcalR3Fc+LAZpgZZ3zvLTjxk8aH7bBxVm/bVNNNuqt5XZ2jsYMLvI2tneT0wPAmXHy4w07UC77d31Nj5r2LZiYesOhtN8KPHGBllSzS3ysqgEEIIIYoFj40baetUPs+J4MV74bh9vY/2te3ZO6sH9ubGeN96wrT1PvjdCWHPrB7o6mRsWddT6hARl8zEX04w060RK95y4X54HKN+PsqY5X9z5vP+GOgp2fxeZ+ZtO8vPB69z7osBVLD6p02OrpKE5DTmbDpFj4YVsLcwRkeh4MTNJwxxP0ivJpXYN7sndubGXLwXxqQ1J/G9E8KBOT0zt7vq6yoJi0vivV+9+XxIc5pULsfd0FhG/HiEAUsP4LugH5YmBrzpUgPfO0/583QQo9vVzPIz7zh7F0fLMrSrbZ/j7yQiLhmnGZtf+rvznt83x9W9h5HxRMYnU8s++7EqNqboKXW4dC97Zd5/O+0fQj1Hy5cmggATOtXO8fVrwREoFFCr/PMP/TXszF64IpkfVWxMaeNUHo+NGzWaDHp5eRETG8fQxjVfPjgfLj2KY8Daa7hUNWP32/WwK6uP790YZuwM4NS9GHa9XS/rez8hlSnb7vA/V0d+eqMm96OSGOdxi3Eet/Cd1hgDXR02vFmbBfvvsdLnEX4fNKGCecYXGfpKBQmpKj7xvEs3J0vsTfXRUSjwDopm+Pob9Khjyd7x9bE11ePyo3imbLsh+U8FAAAgAElEQVSD370YPMfXx+Cf1V59pYLw+DQ+2BnAgh4ZCei9iCRGbbjJ4N+uc/zdxlga6zKimS1+22PYdSWMkc2y7g7YdSUMBzMDXKrmnAhGJKRR/6szL/3dHXu3UY6rc4+iU4hMSKOGdfbn3StbGqKrVHD5Ue6LD697/qsa2tiGr48Es2/fPvr375/tuCSDQgghhCjy1Go1+/d5Mb1brTyfM3frGSzKGLBmQvvMxKNrA0c+6d+Eaet92HX2LgNbPF9xiklMYXLXunSul7FC41TenDHtazFv21muPYzMXB3MTXhsEpO61GVylzqZry388xxmZQz4cUybzKSvTU07Pu3fhCnrTrLjzF2Gts7ohavUUZCcms7UbvVoUzOjnUltBwvmDmzK+NXH2eQbwOQudXBrWomPN5/Bw9s/SzJ450k014Mj+bB3Q3RyqaxjaWJAyMq8b33+r9CYpH+uY5jtmI5CgXkZ/cwxubkXFke3hhZs8Qtg5aEb3H4SjZGekk71HPh0QFPKW+TexzY0JomtfgH8cvQmM3o1yDEpLShd69nznZcnarU6y3PuBWn//v00rmCGtUnB9sicv+8e5ka6rBpcM3N7beeaFszpXJEZuwL462o4/Rs8fz/HJqUzsU15XGtkrD472RgzurktC/bf48bThMzVwZwoFAoi4lOZ2NqeCa2fr0YvOnAfMyNd3PtXz0z6nCuX5aMuFXn/T392XQlncGNr4J/3fpqKyW3K41w5o3WSk60xn3StxKStt9l6MYQJrcvTu44lc7108TgfkiUZ9A9L5MbTBKZ3cEQnl78qS2NdHs53zvlgHoTGp2Re5790FGBhpEtofM5FjQri/FdlbaJH4wpmuSaDUkBGCCGEEEVeYGAgkdExNK9qnafxsUmpnPYPpU0tu2wrUK51Mz6wng/K3t+0/X9W1GzNMlYInkYlvnTONJWafs0qZ/45KiGFi/fCaVPTNluxm2crdydvZX/+8Fl8z7StlZEYXg+OBDJWEIc4V+P83TBuPnq+bW/HmSAUChjWuvpLY31VSSkZLUT0dHP+CKmvVJKYkntrnXSVmqTUdE7cfIyHdwDLxrTh5rdDWD2+PacCQui+2DPHiqJBIbHYTFhP3Q+38PWeS3zavwnTe2m2rUjzqtZERsdw9+5djc1x5pQvTRyyJ9avIzY5nTP3Y2hTxSwzEXymY42MVbMLD7MXP3KpmjWxtjHJ2Eb9JDb738d/panUuNV7nlxGJ6Zx6VEczpXLZiaCz7T7Zx7vu9mfP+xQPeuqXusqGYnh9acJQMbW1DcaWnPxYRw3QxIyx+28EoZCAUMa27w01leVlJrRokFfmfN7X0+pIDE19zYOr3v+62hc3pDzZ3Mu7iQrg0IIIYQo8oKCggDyvEX0SVQCKrWabacC2XYq5yp9DyOzbslS6iiyPMMHZK6wpb2kVxdktCZ4ljw+iwHA1iz7Spd12YwE4HFUQpbX9ZQ62WIw/+fPobHPE9I3XWqw4tB1Nnr7s2BQMwB2nrlLOyd7HK00V5HS6P/snWd0VFUXhp/p6b1CCCX0EiAh9CIgvYM0KaJip4hSlC6gIiAIilJEpCiodKWo9BIg9BASAukE0tukTsnM92NIwmQmBSGifvdZaxZr7j3n3HNmzoS779773XKDUavRmv88VNpCLOVl316KRSLEIhHZ+Ro2v/UcDlYGg6NLI09WjGnLqDXHWHc0lFkDjWt71nazJXn9eDLz1ASGJ/LhziD2Xo7hl3d7FI/xtKnjbjBEoqOjqV27apSrY2NjGdGxfI/z45KUrUanh903Uth9I8VsmwdZxmqgErHIKIcPKPawFVai5oFIBG6PeDcTHhqQ5spkuBQZmUpjI1MqMZ2Dg6XhfWpOicdsbCt3Np5PYOfVZBb2rgXAgZA0OtWxx8vB+LfzNLF8+EBHXWh+76u1eixlZfvZnrT/k1DH2ZLd56LNnhOMQQEBAQEBAYF/PEqlEgBby8e78R/bsR4rx/310LDHQSwSITETo2ZOq6/oUOnoQ3PhiEX9Hw39rOdhT7t67vxyMYr5w/wJu59BRJKSGQNamPR/mhQZu2nZpqGgWp2ezFwVnuUovYpE4GyrwMFKYWLEta/vgUgEN++ll9nfwUpO35beVHeypscnB1lz5Cbzh/r/xdWUT9FeK0+W/0lRZudiZ1E1yrgv+ruxfKBPlYxdmsfb+4ZjpVubDW3WF50rOVTXxZK2Ne3YE5zK3J41uZ2UR2RqPu8/93SFV0rjbmswdtPyTEM5tTo9mfla2pRTI/JJ+z8JdhYSlErzpXAEY1BAQEBAQEDgH49Wawg9lJaVEFSKao7WiEWiZ1oLsJqjFSIRJGaZhpgmPTxW3dHYi6fWFqLMVxspnWbkGrw4Rd7EIsZ3rs9bm85wKvQBZ8ITcbRW0K+laV3WR3lSARkPByvc7Cy5nWBqIN1NyESr0xeXeigLX29nsyG62kIder3BOwoQn57Lit9u0L6+OyPaGhs1RcIxdxKqrtRB0V4r2ntVgbawEMlTzkf0tJMjFkH8M6wFWN1OgUgESdmmhk/yQy9fNXtjL55aqyO7oNBI6TQ93/DZu5TKqRzbyp1Ju+9yOjKLc9FZOFhK6dPIqdw5PamAjLutHDcbGXeSTX/PESn5aHX6cnMrn7T/kyARidAWFpo9JxiDAgICfxsPYiPYtnIhIUGnycvJxq16TboPHcuwie8hElccGhF56xo/rF5E2LULaFQqqteux4Dx7/D8MGMxhL2bvuD75WXXnNtzKwuJpOTPn16n4+AP6zjy0yYS46KxsXekdde+vDR9CdZ2VSdOIPDfIy8xijs/f0p6WCDa/GwsXWpQvfNIag+YhEhU8R7PirpO1IE1ZEZeQ5OdhoVzddxb9cVnyDSkFsY3CXq9jrg/vuPe8W3kJccgs3bEza8H9UfNQ2ZlZ9RWGR3M3V2fkXH3MjpNAdaedanZayJeXUY/1fX/k7BWSGlbz43AO0kkK/Nxsyu5ubtwN5npP5znq5c70qKm82OPXeS9q6g4l52lnFZ1XDkXnkiBphCLR/IGT4QaylN0bWJa/uFUWAID/GoWvy/KK2xfz8Oo3QA/b2bvVLDrYhTn7iQxrHXtChU6n1RABmBY69p8dyqctOwCnG1LDNR9l2OQikUMDqhVbv+hAbU5FnKfU2EJRjmaRetsU9eQ9+Via8HeSzGE3EvnhTZ1jDxHwXEGxdJarkKt2dJYyyW0qWlHYIyS5ByNUfjmxVgls36NYvXQujSv9viGR9GzmIr2vq2FBH8vWwJjsijQ6LB4JPyxqDxF6fxAgNNRmfRrXPKbLKpr2K6m8f/F/Ro7Me+wlD3BKQRGKxnq62KSH1maJxWQARjs68KWoCTScjU4W5d8rvtDUpGKRQxqVv7fkyftXxUIAjICAn8TaYn3GdTQmuT7sc96Ks+EjNQkPhjdnbzsLJb/fIqdVxKZMGMJv6xbzvrF71XY/8KfB3h/eGcsrGxYufss2y/eo9vgMXw17x32frfaqG1RQfofgx6w/3auyetRQxBg/eL3+GH1IsZOXcCPQfeZuWorF44e4KPXBpsNcREwT0F6AkfGepKfcu9ZT+WZoMpK5sKigWjysmn70SGe3xhBg9HziDywhrAtsyvsn377AhcXD0IsldN2/gG6fXOL+iM+JO7PzVxeOgq93jjPJGzLbO7uWka94R/QfX04LSavJ+nyYa4se9HoTi3p8mHOz++DxMKa9ouP0H1dGNU7jeDWt9OJPvjNU/8c/knMH+qPWCxizFfHuZuYhUpTyLk7ibyz+SxyqYRG1f5aLTJPB0MO4JXoVFSaQrTl5FQtGOZPrkrDlO/PEZeaQ65Ky+mwBD7dd43WPm70f8ToA7CQSfj8YDCnwhLIV2sJjc9g8e6ruNlZMqiVcVu5VMKodj7svRRDYmYeYzrW+0vreVze7dsMZxsFr208TXRyNipNIXsvxbD2j1Cm9fPFy6nE23k6LAG3N7aycNfl4mNDW9emfX13Jn9/jgt3k8lXazkbnsjsnUHUdrNl7MN1WMgkfPSCP8Fx6by37Tz30nLIV2s5fzeJaVvPY28l57VuDf+WNf/bmNOjJhKRiJd+CCMiNR+VVsf5GCVT90Qgl4hp6Fa2Ymt5eNgZPNbX4rNRaXXl7v25PWuSoypk2r4I4jJU5KoLOROVxbJjcQR429K3sbEnz0ImZtXJeE5HZpGv0RGWlMfHf8biZiNjQFNjI0kuFTO8hSv7b6aSlK1mtF/VCcc8ypROXjhZSXnzl7vEpBeg0urYfzOVdYEJTO3iRfVHvJ1norKovuA8i36P/Uv9/y4Ez6CAwN/EzaAzz3oKz5Sfv15Kfl4u01duwdbB8B9Am+79GfHWLLatnE//cW/jVafsOktbVszDyc2Tacu+RSY3/LEc9PIU7kXeZseaJfQYNh4be4Mkdm624UmihXXFIgrhN4I4vGMjkxavpW0PQxH3xq068NL0Jez7bjX3o++WOy+BEtLDAp/1FJ4pkXtXUViQS4tJ3yCzMexFN//e+Ax6lzs/f0LNnhOxrla2yuPdnz9BbutMsze/RCw1PDH2aDOQrKjrRB/8BmV0MPZ1DPlgmRFXiDu6haYTV+Deqg8Ajg3a0GDUXKIPrSM3IbL4WuE7l6BwdMf3za8Qyww3crX6vEHO/TtE7F6OV5fRyGyqpkDzs8avtgsHZ/ZhxW836L/sCNn5atzsLRncqhZT+zQzUfisLMPb1uG3a7FM2nwWGwsZx+b2L7Ntax839r/fi89+vUG3Jb+Rr9ZS3cmake18eL+fr0nYq1wqYc1LHVi46zLXYlLR6SHAx5VPRrY2K8wyrnN9vjkaiq+3U3FR+qrG0VrBbzP78Mm+a/T57BA5BRrquNnx8cgAk7qH5pCIReyY3J0VvwXz9uYzJGXm42SjoKevFx8OaomNRYnHZEKXBrjaWbLhWBjPLfoVdaGO6o7W+NV24f1+vtR0KfEMFtV/fJSFu6+wcPcVAF5oU4evX+n4lD6FfzYtvWzYP7Epq07GM+jbEHJUhbjayBjY1IUpnaubKHxWlheau3IoNJ0peyOwPSTh9zd9y2wb4G3LnleasOJ4PD3X3SBfo6O6vYLhLdx4t4uXyd6XSUSsGlKXRb/HcuN+Djq9nlY1bFnct7ZZYZWx/u5sCEygmad1cVH6qsbRSsr+iU1ZejSOARtvkq0qxMfZkkW9azEuoOLczyftXxUIxqCAgBmiw4LZ8dXH3Lp8joK8XJzdq9Gux0BGvv0hVrYl4VeLXh/C/ZgIFmzcy+bPZhN6+Rw6XSG1GjTjlVmfUs/XoPC2cOIgrp09CsBr3RsjkyvYFZzOwomDSIyLZtaaH1g181UexETw87UUxBIJYVfP8/M3nxF+I4iCvDycXD0I6NaXFyfPLTamAD4c25Pk+7HMWfszmz6dRUTIVfR6PQ1aBPDKB59Ru2EzAGaP60XEzat8fzYKKxvjsJpdG1awbeUCFm46QMsO3avkMz1zaBfNWncymjtAux4D2Pr5PAJ/38uIt2aZ7ZujzORBbAQd+wwrNgSL6NBnGH/u2sKlk0foOmh0cXu5haWJB9AcR3dvxcLSmucGGYfLdR86ju5Dxz3OEv9VKGNvEbFnBRnhFygsyEXh6Il7QF/qDp6G9JEQwyvLx5CbGEWrGT9w+8dFZIRfQK/TYevdiIYvLsTepyUAl5eNJjX4JACnprVGLJPTc3Msl5eNJi8plpZTNxL8zWRyEyPpsSkKkVhCxp1LRO5bRVbEFbSqfBQObrj59aTesBnFxhTAxcWDyU+9h9+0Ldz+YT5ZUTdAr8ehrj8Nxy7E1rsJAEFLhpAVdYOua28gtTTe41EH1nDn509pNWsnLs26VMlnmnBhP06N2hvNHcA9oC93fvqYxKDf8Bn8bpn93VsPQGHvUmwIFmFT3VBXLz/lXrExeP/UDiQKK6p1GG7UtnrnUVTvPKr4vSY3i7zEKDzaDCw2BIvwaDOQ+JM/knL9KNU6vvD4C/6X4OvtxNa3u1bYrqw2QwJqMaRU2KOjtYID03tXqj+Afx1Xfp76fMWTBQp1Ony9ndjzXs9Ktdc+VCZ8+bm/10Pm5WRdKcOqcyNPs2GplnIp84b6MW+oX4Vj9GvpTb+W3hW2W/hCKxa+0KrCdv8vNPO05rvRFdflLKvNoGYuDGpmnP/pYCllzytNKtUfwM/Llh/HN6rEbEGnM8z5lwmNK24MaB56JV9q7VFBy6dLdXsFXw6r2AvfqY692bDUyvb/uxDCRAUEShERcpWZo7uh0+lYtvMEP1y8x2tzV3DiwA7mvzqAwsKSRHKpTI4yI5XP33+Z3iNfZdOpOyzdcZz0lEQ+mTQKtcqgtrbw2/0MfnkKABuPhbIr2KCUJpMrKMjPZcOS92nTvT8TZy9DJBYTfOEUc8b1xsrGjhU/n+LHoHje/WwjF/48wJzxvYvHNYwhR5meyprZbzB68hy2no9h+c8nSYiNYt6EvigzDHkVvUa8gqogjzMHfzZZ85mDv+DqWYMW7czfzCgz0hjU0LrCV3zUHbP9UxPiyc5Mp4aP6c2Kp7cPEqmMyFvXyv5SypLdA2wfegNjbgcXH8vNzsLSunK5EGFXz1O7ka+JkflfJiv6Bhc/6g96HW0X/Eb3dWE0Hr+EB2d3cemzUegf2eMiqRx1djo31r5NjW7jeG7NVdouOIAqM5mrX7yCTmMQKGg1cwe1+r4JQJdVQfTcbAiLEUsVFKryCN0yBzf/XjQauxiRSExa6FmCPh6K1NKWtosO8/z6MHzfXEPS5cMEfTyseFwAsUyBWpnGzQ3vUnfodLp9E0Lbjw6SmxRN0CfDUWcbfk9eXcdRqM4n4fw+kzUnXNiPhXN1nJt2MvuZqLPTOTLWs8JX7oMIs/0L0h6gycnAurqpV8TKvRYiiQxl9I1yv5davV/Ds51pQeDsuFsgEmHjVXLDlXHnEnY1m5gYeCYUqfaZ+e0UeQOVcbfKH0Pgb+VxA9O/+v0WbnaWvNC6akofCAj8Xegfc/d/c+4BbjYyhvo+3dIc/28IxqCAQCk2Lf0AW3tHZq3eTvXa9bCwsiHguT6Mf28Rd4Mvc+7wHqP2edlKhrwyFf8uvbCwtKZmvcb0Gf0a6ckJxIaHlHstkUiEMj2VNt37M2bqfHqPmohIJGLLirnY2DswdekGqtUyzKFp606Mf38xsXducebQruIxxGIJalUBQye+R9PWnVBYWFGzfhMmzFhCdmY6x/f9AED7XoOxdXDiz91bjeYQH3WHmPAQug8bV6aIi52js9ncu9KvssIpM9OSH45j+gdbJBZja+9IZmpymZ+Tjb0jnt4+hF09j1ZjXJco9IohNDErvaSWUq4yC6lUxo9fLmFSf3+GN3dmQicf1i9+j5ysDKP+SfGxOLtX48S+H5k2tD3DmzszpnV1Pp/+MmmJ98uc07+Z29sXILN2oMXkjVh7+iCxsMa1ZQ/qj5xNVuQ1Ei8eMGqvzVNSq99buLbojkRhhY1XQ7y7v4QqI5HsuNAyrvIQkQh1dhru/r2p98IsanQfDyIRd3YsQWZtj++ba7D2qIPEwhqnRu1pMHIO2ffCjAw6kViMTqOiTv+3cWrUHoncEtsajWgweh6anAwenDE84PBo3R+ZjSPxp3YYTSH3QQTZcaF4dRlVpoiL3NaJ3tsTKnyVFeapUqYUj2P6EYiR2TigUpqqJ5aHOiuF6IPfEPvHd9QdPA2bRwzN/JQ4FI6e3D/7C4Fze/DHy7U49kZDbnz9DgXpCcXtZDYOWLnXJuNOEDqtsapfRrihALH6Mecl8Owp1OnJV2tZdzSUny9E8smo1n855FVA4N9EoU5PvkbHxvMJ7LqewuK+tf9yyKuAAeHTExB4hLycbMKunqdZm84mniK/Tj0ACL9hKkvcvH03o/dOroaQhbTkBJO2pSks1NKpz7Di9znKTCJCrtK0dWfkCmMZ8RbtDZ67mxdPmYzTsqNxCFKzNoZQuJjwm4DBC9l18BjuBl8m9m7JDfzpgz8jEomqNCRSXWCQUZbKZGbPS+VyVAV5Zs8VMWHmx6Ql3mfVzIkkxkWRl63k2N7tHN7xLWAs/a3X6dCoVVhYWrP4+0NsORvN63NXcO7IHt5/oRP5uQapeV1hIeqCfIIvnOTonq1M/XQD287HMuOLbdy+eoHpI7qQq6w62fJngTY/m8w7l3Bq3MHEq+Tqa9hfmZGmXlqXpp2N3iscDMn6BZlJFV5TX6jFo+2g4vea3Cyyom/g1Kg9Ypnx76zIc5cees50Dr7Gnmvnxh0Aig1SsUxO9U7DyYq8Rk787eJ2Cef3gkhkFD75tNGpDd56sdS8p04slVGoMpUTN0deUjRHxnpy/B1fIvZ+Tv2Rc/AZPK34vF5XSKG6gPTQs9w/tZNmr6+m+ze3aDF5PZl3gji/oC+aPGVx+wYvzqcgPYHgbyaRlxSDNk/J/dM/ce/o94bxCqtONl+gath3OYbaU3aw7mgoX7/SkYH+NSvuJCDwH+BASBr1P77I+sAHrBlal/5N/n71zf8aQs6ggMAjpCcnoNfpOHlgJycP7DTbJjUx3ui9WCIxyYMrCsnSVeImSyQS4ehaEu+elmSQG3/0WBEOzoYb8PSHbYqQSGUmc7BxMIRPPupx6zXiFQ58/yVHd2/l1Q+WAnD20C6at+uKW7WK8zH+KgpLg2qZVmNabwhAo1ahsChf2azt8wOYv2Ev21Yt4J1+/lhYWdOifTdmrd7O1EFtjMJCl/10wqR/+15DEInFLJ38Irs3fs7YdxcgEosRicXkZiv58Kud2NgZwuZatO/GWx+t4aPXBrP/+zW8OGXeX136Pw5VRhJ6vY4H53bz4Nxus20K0ow9oiKxxCQPjocetkoZEiJRsfFomIPhIYnCwTRZXm7vaphDRqLxEBKZyRxk1obvq8grB1Cj6zhiDm8g/tQOGo75CDCEiDo36YylS9UVJJbIDWULdFq12fM6jRqJwrRulTms3GvTe3sCmtws0sMCCdsym4QL+wj44Gdk1vaIRGJEIjGavGxavvsdMmuD5Lpz0y40eWUZl5e9SMyhddR7YSYA7v698Z/xA3d//oSzszojsbDGuUlnWkzZyLnZ3ZFa/D3CCwIV89OUyuUVDmtdm2FCWKjAf4gfxlUur3CIrwtDhLDQp4pgDAoImKHH8AlMWrz2b7mWSCxGLDET3mOmpIG+jNw5sbnwzodtHz3nVac+TQI6curADibMWEJs+C3uR99l9KSya/I9DYoM26wM03C0wkItOZkZOLUyrbVVGv/OPfHvbCyqUOTl9PCq+MbIr1MPRCIRd4IN3l2RSIS9ows29g7FhmARTQM6IhKJiAotP8/r34rXc2NoOnHF33ItkUiMSFy5PV5WfqjIbKHxony4kj1uXa0uTg3b8uDcbhqMmkf2vdvkJkRSd+j0vzr9SlFk7KqVaaazLNSiyc3EwvHxRA5k1va4t+qDpXN1Auf1IurXL2kwai6IRMjsnJFZ2xcbgkU4NmwHIhHKWOMQddfm3XBtbhzBUOQ9tXQTvEoCAgIC/68IxqCAwCO4eFRDJBaTcj/umc3B1cMLkUhEupkQ04wUg7fExcPYw6FRq8jLVhopnSozDaIaRd7EInqPfJXPp7/M9XPHuXnhJDb2jsUlFcpCmZHGuHYVew7XHrpmNm/Qyc0TRxd34u6a5pfFR4ZTWKilXjP/Csc3x+1rFwBo5G9Q7NJq1MTeDcXS2oZqNY3zuzRqNXq9Hrm8JPzWp0kLs6G/hYWF6PV6pBUJdPzLsHDyRCQSk58aX3HjKptDNRCJTLx/AKrM5JI2j6DTqNHmKY2UTtU5hvzPIm9iETW6jePG1++QGnKa9NCzyGwccG/Vt9w5qbPTOf5Wk3LbAHRadsZs3qDC0QOFvRs598NNzuU8uIu+UFusBGqOgrT7ROz5HMdG7aje0VghtEiUJud+iUCTfa1mZEZeNRlHr9OCXm+iSGqOjDuGum+O9dtU2Fbgn8HINUe5GJFMzJoXn/VUBASemDHbwgiKU3J3jvA36FkiGIMCAo9gYWVDE/8O3Aw6Q0ZqEo4uJWFsoZfPsXbBZKZ99i11m1YshV2aInGWioqYW9na0aBFG24GnUZdkI/coiS07OrD8hR+HU1Dia4HHqN9rxIlwqK8wiatjdUT2/UchK2DEycP7CAk6AzPDRhVoZJmkYDMk9B5wEgO/7iBrPRU7J1KQjzOHNqFRCKlU7/ype03fTqLSycOs/bQFSQPb3T1Oh2///QdXj4NaORnMAY1ajUfvPg89Zu14uNtR4zGuHLqdwB825aUFujUbwRXTv/B9cDjtHgk97Po82vsbyoL/W9GYmGNY8M2pIcFospKRmFf8rAgI/witzbNoNlbX2Jfu/ljj13ioSt/j0ut7HCo24r0sEAK1QVIHjHOU4MNIb4uvs+Z9EsNOY1H65J6bkV5hU4Njb8j94D+yGzm8uDcbtLDAqnWfliFqptFAjJPgmf7IcQd/R61Mg25XUkeS+KF/YgkUjzbDS6zr8zWmYTz+1DGhlCtwzAjb6cyxpD3a+VWq+Ra7YaQcuM4aSGncG5asp+LPpNHDbzb2+eTfO0onZadQiR5+NvR67h3Yhs21erhWD/gidYtIFBZ1Fod07YF8suFKBYO8+ftnuYfwEQlK/l47zXO3Ukkp0BDDWcbRrXzYXLvpojNKONWdlwBgaeJplDP9P2R7LqRwryeNXmzg/kIp5sJuSw7do9L95Tka3R42Svo29iJqZ29sFEYR83o9LD5YgLbLycRk6HCwVJKzwaOzOnhjZ1F1ZhtgoCMgEApXpq+GIlEwuI3hhEfdQe1qoCQoDOsmvUaMrkC73qVq39TGmd3wx+JOzcuoVYVGJWoKM2EGUvIz81h9ew3SYqPoSAvhxuBJ/jhi49o5NeOdr2MbyrlFpb89PVSrgceR1WQR0x4CFtWzEzWu/oAACAASURBVMPRxZ2OfYYatZXJFXQbMpYzh3aRnpzA8y+89JfW87gMf2MGto7OLJ82joS4SNSqAs4c/IV9361mxFuzcPWsUdz2RuAJBjW0ZvNnHxYf8+vUg8T4aNYtmkZ2ZjoZqUmsnT+JuLuhTFq8tjhP09LahhcnzyXk0hk2fTqLtMT75GUrOXt4N99+MoPaDZvRa9SrxeN26T+CpgGdWP3B64RePoeqII+bF0+zYfH7eHr70GP4y3/L5/N3Un/UXERiMVdWjCP3QQQ6jYr0sECC101GLJNj6/XX6pVZOBnCIDMjrqLTqMrNJ2wweh6FBTmEbHiX/JQ4CgtySQs5zd1fPsOxfgAeAf2M2kvkFkTuW0VayCkK1flkx4Uaiqnbu+HR1tizbRCSGUHi+X2oMhLxes64hmRV4TNoKnJbJ65/9QZ5SdHoNCoSzu8j+tA3+Ax6Fwvn6sVt00JOc2SsJ7d//Kh4fQ1eXIAy5ia3vp1Ofso9CtX5pN++QMi37yGzsqNmr5J969l+CE6N2hG8/l0ywi8a2oaeI3TLHKzca+PVtcRz5OLbjfzkWEK//xBNTgaqrGRubZpBTvxtmkz83GzJFgGBp01mnpqRq48Sk5JdbrtkZT79lh1Bma/m9w/7ErV6NAuG+fPF4Zt8sCPoL48rIPA0ycrXMnprKDHpBeW2u/Egh/4bb2KjEPPHm825NSuAj/rUYsfVZEZtDUVX6tnpnINRLD9+j5ndvQn7IIB1w+txOCydMdtum82seBoInkEBgVLUbx7A0h3H+Gntp8wa3Y38nGwcXN3p1GcYw9+caaLwWVm6DnqRwD/2s2rWa1jZ2LJqb2CZbRv5teOT7b+zY80S3h3SDlV+Pq7VatBtyBhGvP2BSTF1qUzGlE/Xs/mzD7l78yp6nY6Gfm14fc7nZoVZeo14hf2b1+DTuEVxUfqqxtbBic92HGPbygXMHNmVvJxsqteqy8TZy+g9amKF/Vt2fJ4Pv9zBrg0rmNitEWKxiIYt27L0x6Mmntohr76Lu1dNft36Ne8OaUdeTjZu1WvSc/jLvPDGDKPPRCyRMH/jHn5a+ymrZk4kLTkBO0dnArr2YezUBZWuV/hvwsHHj7YLfiVi70ouLBqANj8Hhb0rHm0H4TNwqonCZ2Wp1mE4iUEHCV43BamlDR0+/rPMto71A2g9dy8Ru5dzbk4PClX5WLpUp3rnEfgMnoao1B4XSeU0e/0Lbv/4EVlR10Gnw6F+AI3GLykWb3mUGt3GEXN4PXa1mhUXpa9qZDaOtF3wK3d+/oQLC/ujzc/GysOHRmMXG0pqVID38y+hsHcl9neDsItOq8bCuToOPi3xGfIeVo/k9onEEvxn/EDk3pUEfzOJgowk5LZOuLV8nnrDP0BqUbJvXXyfo+W7m4g68CUn3w1AJBLjUK8VbeYf+EseYAGBxyUzT03/ZYcZ6F+T7k2q0+ezw2W2/fxgMLkFGja81hlHa8Pfot7Na/BeP1+W7L3Ka90aUs/D/rHHFRB4WmTlaxm0KYT+TZzpVs+BARvLLiO29GgcUrGIlYPrYikz+OCer+/IG+2rsfRoHEFxStrWNKQ/XI3PZuulJJYP9KFPI4MoYJuadszp4c36wAQi0/Kp61I5IbLHQTAGBQTM4NO4BbPX/lRhu7LadOo3nE79jPN+bOwd+XT7H5XqD9CgeWsWbjpQ5vlH0RXq8GncgiVbKvcfofZhvbE+L75eqfZPC1fPGry3/LsK2zVv39VsWGqb7v1p072/mR6mtO81xChstjwUFlaMf38x499fXKn2/wXsajXDb9rmCtuV1caz3WCTsEeZjQNt5hkXfC/vGg51/Wk1y7xqb2n0ukLsajWj9exdFTcG9IWGPe79/IRKtX9aWDhXx/etisWnnJt2NhuW6h7QF/eA8vMbi5DILak/cg71R1YsAOXm3xs3/96VGve/TEauipUHgzlyI57ErDxsLGS0qOnMjAHN8atlrFB45nYiXxy+ybWYVLSFOmo42zC8bR3e7tEYubQktGv0l8eITFLy/ZvPMeenS1yLTUUmEdOjmRfLXmzD0ZD7rD58k8gkJW72lrzRvRGvdStRThy44gj3UnPZ+k5X5v18ieuxaej10KqOC4uGB9DEq5SSbylC7qWz7NcbXIxIJlelwcPBiv4tvXmvny92liXh0Y+z9qdNijKf17s3Ynyn+lyJSim37b5LMXRo4FFsCBbRt4U3i/dc5dersbzX1/exx/0vkpmv5YtT8fxxO4PEbDU2CgnNq1nzftcatKhu/CDzXHQWa07f5/r9HLQ6PV72CoY1d+XN9p7IH6nTN257GJFpBWwa1YB5h6K58SAHqVhMjwaOfNKvNsfvZvLlmftEpeXjZiNjYltPXm3rWdx/6He3uJdZwObRDVl4JIYbD3LQ68HPy5aFvWvS2KN89eJbibl8fiKei7FKctWFeNrJ6dPImWldvLC1KPndPc7anzYpuRomtvVkbCt3rsaX75F+kKXG1VpWbAgWUcvR4FiIS1fR9uFzvp1XU7CSi3mhufHvcWRLN0a2NNZ/eJoIxqCAwH+Bx4wd2LtpFY4u7nQZMLKKJiQg8JR5zD0e/dvXKOzdqNZhWMWNBf5veH3jae4kZLHpjS40q+FEUlY+C3ZdZtjKPzg6pz8+7oYn9Bcjkhm5+k/6+dUk8KNB2FnKOXQ9jnc2nyU1u4AlI0ryLGUSMek5Kmb+eJFFw1vRoJoD358K56PdV3iQkYtCJmHLW12xt5Lz4c4g5vx0Cf/arvjVNtzwyaUSUnMKmPL9OZaMDMCvlgsxKdmM+eo4Q1f+wflFg3GyMe+tvx6bxsDlR+jSyJODs/rg6WDFufBE3t0ayIW7yfw2qw/Sh0q8lV17adJzVDR8v+KHo+c+GlTssStNPQ/7Ms89yv2MXDJyVTTwNG1b280WmUTMjdgSxd7Kjvtf5a1f7nAnJZ8NI+rT1NOapGwNi3+PYcT3oRx505c6zgaDIygumxe3htGnsROnJ7fAViHlyO10puy5S1quho/61CoeUyYRk56n4cPfoljQqxb13SzZeimJJX/E8iBLhUIqZtOoBjhYSph7KIb5h2Pw87KlpZfBAJNLRKTlapm2L5JFfWrRoroNsekFjP/hNiO2hHJ6ckucrMybHzce5DD0u1t0qmPPgYlN8bCTcz5Gyfv7IrkYq2T/xKbF+7myay9Nep6WZp+ZisaV5tTkFmV64eq6WFbaQ9fQ3Yo/wzPILig0MmajH4aX1ncrGedSnJImHtZGxvnfgZAzKCDwf4KusBBVQR4Hvv+SE/t+5LW5K/5yyKuAwD8RQzH2fGIOb+D+2V9oNH7JXw55FfjvodIUcuZ2It2bVqdVHVcUMgneLjasmdABuVTCidCS+q2Hb9xDIZOwYJg/Hg5WWCmkvNCmDu3rebAzMNJkbGW+mql9muJX2wVrhZQ3nm+MtULKpcgU1rzUAW8XG+yt5Ezp3RSAM7dLvMISsQiVppBJvZrSob4HlnIpjao7Mn+YPxm5KnaeN71eEfN/uYSjtYJNb3Shrrsd1gopPX29mDvEj6sxqey/HPPYay+Nk42C5PXjK3w9DaMsRVnw8Jqm/zeJRSIcrOXFbf7fUWl1nI3Kols9B/xr2KKQivF2VLBySF3kUhEnIzKL2/5+Ox2FVMy8njVxt5VjJRcz1NeFtjXt+Ol6ssnY2QWFTO5UnZZeNljLJbzWzhNruYRL97JZNdgHb0cFdhZS3u5o0EI4G51V3FciFqHS6ni7QzXa1bLDUiamobsVc3vWJCNPyy9mrlfER0dicbCUsmFEfXxcLLGWS3i+viMfPu/N9fs5/BqS9thrL42TlZT7H7Wr8PW0wjGndfFCIRUzZc9dEpRqNIV6TkZksuH8AwY2dTbyYsZlqvCwk7Pregq91gVTZ/FFGi+9xKTdhr5VheAZFBD4P+Hs4d2snPkqTm6eTFu2iQ69h1bcSUDgX0Tihf0EfzMZhaM7vm99hUebAc96SgL/IGRSMS62Fhy6HsfzTavTw9cLmUSMrYWM8JXGURILh/mzcJhpuRtvFxvO3UkkM0+Ng5WxQm2buiVhXFKxCEdrBXKpBHf7kptKV1uDkZNsxqDp1sRYibBjA4MgU2h8htn1ZBdoCIpIYWjr2kZhq4+OdTU6lWGtaz/W2p8lBepCwPBdmUMukZCvLluY6v8JmUSMi7WMI2HpdKvnSI/6jkglImwVEkJmGSsEz+tZk3k9TeuJejtacD5GSVa+FntLY5OgtXeJp1gqFuFgKUUuFeFmW7LvXa0N6sQpORqTsZ+ra1y7t31tw3ihSXlm15OtKuRSnJIhvq4mnrGu9QxjXbufwxBfl8da+7OmobsVm0bV581f7tLq8yvFx/s0cmLZQJ/i94U6PQUaHeeiskjN0fDFkLp4Oyq4ci+HGQci6bfhJicnNa8SRVHBGBQQ+Jez8Nv9lWrXuf8IOvcfUcWzERB4+rSauaNS7TzbD8WzvfCQQ8A8YpGI7ZO68damM0xYdxJLuZRWdVzp3qQaozvUNcpRU2kK+e5UOL9djSU2JYfMPBWFOj2FD6X/dKUkACVikVF+HgAicLA2Plakelyo0xkdl0nEJjlyDg/fp2Tnm11PYmYeOr2eXRej2HUxymyb+xm5j732Z4ml3GDUarQ6s+dV2kIs5cKtK4BYBN+PacikXXeZuDMcS5kY/xq2dK3rwCg/NxweMe5UWh1bgpI4GJpGXEYBGfladHqK93NhqSh8iVhkFNIIBtFhh1IGY8l+Nh5AKhHhWCoUtKhvqhnDESApW41OD7tvpLD7hvn8zwdZqsde+7Nm140U3t8fyRvtqjE+wB13WzkhCbnM/DWKvuuD2fdqU5ytZYhFIsQiUKoK2TSqQbFx3tnHnqUD6jB2WxjrAxOY0a1GBVd8fP45n5aAgICAgICAQBXSoqYzgR8NJigymRO3HnAi9AELd19h9ZEQdk3rQbMaBgW/1zae5vfge0zv35zhbergZmeJXCZh+vbz/Hgu4qnPS2SmvEdRTVpzdfUeZWzHeqwcV3E91Mqu/VlS5EVNyzb1nGp1ejJzVXjWczc59/9K82o2nJ7ckkv3sjkZkcmpiEwW/xHLl2fu89NLjWnqaRBrefPnO/x5J4P3nqvBMF8XXG3kyKUiZv0axc6rZYdt/lXM7ll90bny+77o78byRzxmZVHZtT9LtDo9cw5G09rbjtk9vIuPt/Sy4YshPvT8Jphvzj1gbs+aiETgbC3D3kJq4qVtV9MOkQhCEp6s3nNZCMaggMB/nIUTBxF25Tw/XXv6f/AFBP4JXF42mozwIHpsKju3SkCgCJHIENLZpq4bHwxqweWoFAYuP8LyX2+w9e2uJGbmceTGPYYE1GJGf+PSG/fSquZmTK0tRJmvNlH/BHC1M5/bXc3RGrFIxL20nEpfp6K1m+NpCMhUFg8HK9zsLLmdYJrzdTchE61OT8sqVj79tyESQWtvW1p72zKzWw2u3Mtm6He3WHkynu9GNyApW80f4RkMaubCe895GfWNz1RVyZzUWp2JYEp6viG818VGZraPp50csejx5lTR2s3xNARkKsv9TBU5qkLquZqO4+NsOHY3pcTz38zTmqvxpr9nrU6PXm8Q56kKBGNQQEDgH41Wo+aruW9zYv8OJsz8hCGvTDVps3fTF3y/vGx5/T23soxqM0beusYPqxcRdu0CGpWK6rXrMWD8Ozw/rOJacAICT5PchEju/Pwp6aFn0WlUWLrUwKPNAGr3exuJRcmT7eiDXxO+o+zSJ7223DOpzViEtiCHcx92Jz8ljo5LT2Dj1fCpr+PfQOCdJN7adIYfJ3c3KtfQqo4r7vZWxcaX+mGIYmkRkzsJWZy/kwiUeO2eJqfCEhjgV5LXdTbccK329TzMtrdWSGlbz43AO0kkK/Nxsyu54bxwN5npP5znq5c7GjyClVy7OYoEZP4uhrWuzXenwknLLsDZtuQ72Hc5BqlYxOCAWn/bXP7JnI9RMmn3XbaNaWhUrsG/hi1utjIy8gzhmCqtYa+WVvC8m5LPhRglUDX7+XRUJv0aOxe/D3woMtOupvkHBtZyCW1q2hEYoyQ5R4PbI0bjxVgls36NYvXQujSvZlPptZujSEDm78DggRUTbiZP8nay4VgNx5IQ7UHNXDh+N5PTkVl09in5nAIffk+ta5pX/H1SBDVRAQGBfyw5ykwWvDqQhLjoctvlKg1PkX8MesD+27kmr0cNwQt/HuD94Z2xsLJh5e6zbL94j26Dx/DVvHfY+93qKl2PgMCj5Ny/Q+DcnqiVqbSZt4+uX9/EZ+j7RB/8mutfvWHUVpNruBnoviGc3tsTTF5lGYIAt7cvID8lrkrX8m+gZS1nJBIRkzaf5Wp0KipNIRm5Kr45Gsr9jFzGdKgHgJezNTVdbDl0LY7bDzJRaQo5GnKfl9edZKB/LQCuxaaZ5Ek9CRYyCZ8fDOZUWAL5ai2h8Rks3n0VNztLBrUyFf4oYv5Qf8RiEWO+Os7dxCxUmkLO3Unknc1nkUslNKrm8Fhr/yfwbt9mONsoeG3jaaKTs1FpCtl7KYa1f4QyrZ8vXk7PPvzvn0CL6jZIxSKm7o3kWnwOKq2OzHwtGwITeJClZrSfIZzWy0FBTUcLDoelczs5D5VWx/G7GUzcGU7/JgZj7caDnKe8n8WsOhnP6cgs8jU6wpLy+PjPWNxsZAxo6lxmvzk9aiIRiXjphzAiUvNRaXWcj1EydU8EcomYhm5Wj7X2Z42VXMyb7T25EKtk6dE4HmSpydfouBqfzcwDUdhZSJn4SI3GIc1caFfLjnf3RnAxVkm+RkdgdBZzD0ZTy8mC0X5VU2tQ8AwKCAj8I8lRZjJrdDc69B6Kf+eezBxpPoQJIDfb8MTRwrrim4QtK+Y9VFT9Fpnc8ERu0MtTuBd5mx1rltBj2Hhs7Msv8iwg8DS489PH6HVaWr77HXJbQ76WZ9tBZEVeI+bwetJvX8CpYVsAtHmGPS5VWD3WNVKuHyX+5I+4B/Qj6dLBp7uAfxmWcim/zujN8l9v8Or6U6Rk52NjIaOehz0bX+vMoFa1AEO+0/dvPcecn4Los/QQUomYVnVc2fhaZ6wtpNy8l874tceZ3LspHw5q+VTmJpdKWPNSBxbuusy1mFR0egjwceWTka3LFUzxq+3CwZl9WPHbDfovO0J2vho3e0sGt6rF1D7NUMgkj7X2qmLhrst8/Weo8bHdV1i426Cu+EKbOnz9SkcAHK0V/DazD5/su0afzw6RU6ChjpsdH48M4KXO9f/yuP81LGVi9r7SlM9P3uP1n8NJydFgq5BQ18WSdcPrFxtdYhF8O6o+8w/HMHBjCBKxiFY1bFg3oj5WcjEhCbm8/GM4b3esxqzu3hVctXLIJCJWDanLot9juXE/B51eT6satizuW9uk+PqjtPSyYf/Epqw6Gc+gb0PIURXiaiNjYFMXpnSujuKhymhl115VLPo9lvWBxuVYFv8Ry+I/YgEY6uvCl8MMD1hmdfemjrMl2y8nsTkokQKNDhcbGR1r27N+RH1qOZV4vyViEdvGNmLVyXim7IkgMVuNk5WMHvUdmdm9BjYKY1Gfp4VgDAoIVEBOVgY/fb2UoOMHSU9OwNLahrpN/Rg9aQ71fFsZtQ2+cIpd65dxJ/gyhYWFuFWrwXODXmTwy1OKDQ+ARa8P4X5MBB9+uYONH08n4uZVJDIpAc/14c0Fq7ly6gi7NqzgfkwEji7uDHzpHfqPe7u4/4dje5J8P5Y5a39m06eziAi5il6vp0GLAF754DNqN2xW7pqiw4LZ8dXH3Lp8joK8XJzdq9Gux0BGvv0hVrYlYQiPs/anTWZqMgNfmkSvEa8QfiOo3LY5ykzkFpZGHsCy2j2IjaBjn2FG3wdAhz7D+HPXFi6dPELXQaOfeP7/JjQ5mUTuW0ny1T8oyEhEammDfe3m1B06HXsf45vdtNCzRO1fQ1bkNfQ6LRYuXlTv+AK1+ryFWFaS73Rl+RhyE6NoOXUTYdvmkRV1HbFEimvLHjR+eSkp148RdeBL8hIjkdu7Uav3a9TsNbG4/8XFg8lPvYfftC3c/mE+WVE3QK/Hoa4/DccuxNa7SblrUsbeImLPCjLCL1BYkIvC0RP3gL7UHTwNqVXJHn+ctT9tnJt2xqlxx2JDsAj72r4A5CfHwkNjUJOnRCK3KNcDWBpNTgYhG9/Hs+0gnBq1/783BgGqO1rzxfj2FbZr4uXIvvd7mT137qNBRu/LyrW7+skwk2NlhVwW6nT4ejux572e5c7rpynPmxzz9XYqcw6PUtm1VwULX2jFwhcq/3+Gl5N1pYy4xx33v0Y1ezmfD6pYbKWxhzW7Xjb/N/PU5BZG78vKtbs4zc/kWFkhlzqdIf/tlwmNy53XD+MamRxr5mld5hwepbJrrwrm96rJ/F5le+xLM7yFK8NbuFaqraVMzOwe3kaCM1WNYAwKCFTA8mnjuRd5m5mrt1OnUXMyUhLZ/Nls5k7ox6o9Z6lWy/D0J/RKIAtfHUi7noP4+vB1rGztuHj0N1bNfJWstBQmzl5WPKZUJkeZkcq6j97llVmf4l2vEYd3fMv3y+eQmnAfmULBh1/txMbOkQ1L3mPjxzOo7xtA/eaG+jkyuRxleiprZr/BxNnLqefrT2JcNIvfGMa8CX35+vB17BzNPxmLCLnKh2N70rxdV5btPIGzuyc3g87w5Zy3uHUlkM92HCs2qiq79tIoM9IY167iP2RrD13Dq059s+e86tQv81xpcrOzsLS2qbhhUV6EGaUz24fewJjbwfB/Zgxe/+pNcu+H02LKRuxqNUOVmcTtHz8i6NPhtF/yB9YedQDICA/i8mejcW/Vl07LzyC1siPp8hGC101ClZVGo3GLiscUSeWos9MJ/f4DGoxZiG31BsQd20L4jsUUpD9ALFPgN+07pNYOhG2ZTdi2edjX9cPBx3DDIZYpUCvTuLnhXRqNW4S9T0vykmK4smIcQZ8Mp9PysyZGVBFZ0TcIWjwY56adabvgNywcPUgPC+TmxvfICL9I2/kHio2qyq69NOrsdI6/Vb5BCtBp2Rmsq9U1e65mz1fNHi/IMOSKWbqV3Gxo87KQWFRijz/Crc2z0Ou0NBr/sWAI/sN5+hlbAgLPDr2wo/9VCDmDAgLloFYVcOPCSfw696RhizbIFRa4e9ViyqfrkcnlXD17tLht0LHfkCksmDDzY5zcPLGwtKbLgJE0CejIsb3bTMbOy1bywuvTqd88AAsrGwZOmISFlQ1h1y4w9dP1uHvVwtrOnqGvvQ9A8MVTxX3FYglqVQFDJ75H09adUFhYUbN+EybMWEJ2ZjrH9/1Q5po2Lf0AW3tHZq3eTvXa9bCwsiHguT6Mf28Rd4Mvc+7wnsdee2nsHJ3N5u6VflXW2KuIXGUWUqmMH79cwqT+/gxv7syETj6sX/weOVklBZtt7B3x9PYh7Op5tBq10RihVwIByEo3X9/ov4pOoyL91hlcmnfHoV4rxDIFlq7eNHv9C8RSOanBJ4rbJl89glimoOGL81E4eiBRWFGtw1CcGrbj/hlTtUFtnpI6A6fg4OOHxMKaWr1fR2JhTcadyzR7/QssXb2RWdlRZ8AkANJvnS3uKxKL0WlU1On/Nk6N2iORW2JboxENRs9Dk5PBgzM/l7mm29sXILN2oMXkjVh7+iCxsMa1ZQ/qj5xNVuQ1Ei8eeOy1l0Zu62Q2d6/0qyxDsCzUWSnEHNmIjVdDHOuXFE/W5CoRS6RE7F7O2Vld+OPlWpyY1ILQLbPR5JgqLz44t4fEi7/S6KVPkNtVbciUgICAgMC/F8EYFBAoB5lMjoOTKxeP/sqFPw9QqDUoVFnZ2LL9wj36j32ruO2EmZ/w09UkXD2NC4K6e9UiL1tJjtL0hq2xf0nIjkQixdbeEffqNXF0LVGPc3A2JAxnpCSZ9G/Z0ThkqFmbLgDEhN80u568nGzCrp6nWZvOJmGSfp16ABB+49Jjr/1Zo9fp0KhVWFhas/j7Q2w5G83rc1dw7sge3n+hE/m5JVLNE2Z+TFrifVbNnEhiXBR52UqO7d3O4R3fAqDVap/VMp4JIqkMuZ0LyVcOk3T5MPpCw/cstbSl+7pQI+9Vg9Hz6fFtBBbO1Y3GsHT1RpunRJObZTK+Y/3WJdeSSJFZO2DpWgOFQ0mCv9zOED6jyjI1xF18jcPfnBt3ACA7LtSkLYA2P5vMO5dwatzBKGwVwPXhWJmR1x577X8HmpxMrq6cgDZPie+bXyISP5Ifoteh06qRKKwImP0L3dYG02j8EhIv/sr5+b3RFpTs8YKMRMK2zsbdvzeebQeZuZKAgICAgIABIUxUQKAcRGIxc9ft4vPpr/Dp5NEoLKxo2LI1LTv1NBEaUasKOPzjBgL/2E/SvWiyszLQ6QrRFRYCFP9bhFgiMcrPA0PhYRsHR5NjADqdcX+JVIatg3GYXFHfzFTzNQXTkxPQ63ScPLCTkwd2mm2Tmhj/2Gt/1iz7ydSD077XEERiMUsnv8jujZ8z9t0FALR9fgDzN+xl26oFvNPPHwsra1q078as1duZOqhN5cJN/0OIRGL8pm8leO3bXPviFSRySxzqtcLFtyteXUYjs3EobqvTqIg7+j2JQQfJT45Fk5uBXqdD/3Bv6kvtUZFYYpSfZ7ieCLm1A6UOmu8vkSGzMd5nsod9VUrzHlxVRhJ6vY4H53bz4Nxus20K0u4/9tqrmrykGK4sH4NKmYr/9G3Y1WpqdL7twt9M+ni07o9IJOba6leJ/vUr6g3/AICQjdMAaPzKZ1U/cYEnxlweoIDAvxVzeYAC/2wEY1BAoALqNvXj68PXCLt6nmtnj3Lt7FG+XzabXeuXs3jzQeo0NhQlXj5tPJdOHGLUO7N5buAoHFzdkckVfD1/Mkd3b33q8xKLzTj2H+bEmT33CD2GT2DS4rUVXqOya/+nTbuR/gAAIABJREFU4tepByKRiDvBxgVm/Tv3xL+zsVBD7F2Dp8nDq/bfNr9/Cva1m9Np+Vky7lwi9eYJUoNPEr5jEVG/riHgg1+KDZPrX75B8rU/qDvkfap1GIbCwQ2xVM6t72YSf2rHU5+XSGyuwK5hj4tE5e9xr+fG0HTiigqvUdm1VyWZdy9xdeUEJBbWtJ2//7HqALo07woiUbG3M/7UDlKDT9Ji8noU9lUjQy4gICAg8N9BMAYFBCqBSCSisX97Gvu3Z8zU+dy+fpHZY3qyc+0nzF77E+nJCQQdP0infsMZNWm2Ud+UB1VT30ujVpGXrTTyLioz04GS0NLSuHhUQyQWk3K/8nOqaO3meBoCMpVFq1ETezcUS2sbqtU0zs/SqNXo9Xrkcosyepdw+9oFABr5/z3FaP9xiEQ4NmiNY4PW1HthFpl3L3NxyRAi9n6O37TNqDISSb76O57tBlN36PtGXfNT46tkSjqNGm2e0si7qM4x5IDK7c0rs1k4eSISiR9vThWs3RxPQ0AGIDPiCpc+G41NtXr4T9+G3M7FpI1OqyEn/jZSC2usSgna6DRq0OsRywxh39lxYYDBcOfLN0zGOvuBIVS2vCL1AhUzcs1RLkYkE7PmxWc9lcfm7e/OsutiVPH7K58MpYbzfy8iov38fUQkGepzOlorCF858hnP6J/LmG1hBMUpuTunzbOeymMzefdd9gSnFr+/MM2PGg6Kcnr8O+n85XUiU/MBcLSSEjIroIIelUf4n0BAoBxCLp1h5fRXmLd+j1G5hoYt2uDo5kH2Q+NLo1YBYOdgLNQQHxlOSJBBFEOvf/rqWtcDj9G+15Di9zcfisw0ad3JbHsLKxua+HfgZtAZMlKTcHQpydsKvXyOtQsmM+2zb6nb1K/SazdHkYDM34FGreaDF5+nfrNWfLztiNG5K6d+B8C3bZfiY5s+ncWlE4dZe+gKEqkMMOQc/v7Td3j5NKCR3/+XMZgedp7gr9/Gf8Z2o3INDvVaoXBwQ5Nj+J51WoPgjszGODQ558Fd0m+fN7ypgj2eGnIaj9b9S+Ybeg4Ap4bmvyeJhTWODduQHhaIKivZyDuWEX6RW5tm0OytL7Gv3bzSazdHkYDMk5Cfco8ry17E2tOHgNm/IC1DLVSnVXFx0UDsfVrSes4eo3Mp148B4NzYIMPfaNwiI1XXIu4d28qtzbPouPTEY3keBf6byKUS4teOMToWHJfO0v3XCIpMIV+txcvZmn4tvXmvry82FrLidmv/uMVHD+v4mePBN+OQmvXqV4xaq2PatkB+uRDFwmH+vN3T/AMXnV7PphO32Xr6DtEpOThay+nlW4N5Q/2wtzLkCgcuGgzA+K9PcDHCfOqEwH8DuVRM9DxTQ1ZTqGf6/kh23UhhXs+avNmhmtn+NxNyWXbsHpfuGQq9e9kr6NvYiamdvUxq++n0sPliAtsvJxGTocLBUkrPBo7M6eGNncVfM6ui0wr49Ggc52OyyFYVUsNBwYiWbrzTsTpFP6XTD0uAvLIjnKA45V+6TlkIAjICAuVQr5k/EomU1R+8xp0bl1CrCsjJymD/5jWkJsTz/AsvAeBWzRuPGrW5cPQAsXdDUasKuHLqdz6dPIoOvYcCEHHzikne4JMgt7Dkp6+Xcj3wOKqCPGLCQ9iyYh6OLu507DO0zH4vTV+MRCJh8RvDiI+6g1pVQEjQGVbNeg2ZXIF3vcaPtfZnjaW1DS9OnkvIpTNs+nQWaYn3yctWcvbwbr79ZAa1Gzaj16gSIRC/Tj1IjI9m3aJpZGemk5GaxNr5k4i7G8qkxWuLczT/X7D3aYFIIiV43VQyI6+i06jQ5GQSc3g9BWkP8Opi8HxYuHhh5VaT5MuHyIm/jU6jIuX6Ma598QoerQcAkBV13STv70mQyC2I3LeKtJBTFKrzyY4LJXznEhT2bni0HVhmv/qj5iISi7myYhy5DyIMqqFhgQSvm4xYJsf2oTFU2bVXFaFbZlOoUdFyysYyDUEAqYUNdYfNID3sPLe3z6cgPQFtnpLEiwe4vX0ett5NqNF9XJXOVeC/zfXYNPosPYSNhYzjc/sTvnIki4cH8MPZCF744k90jzzoycozPBi6u2oUyevHm7z+qiGYmadm5OqjxKRkV9j2gx1BLN1/nQ8HtSTii1FsfK0LB6/HMerLY1XxTErgX0hWvpbRW0OJSS8ot92NBzn033gTG4WYP95szq1ZAXzUpxY7riYzamsoulL7ac7BKJYfv8fM7t6EfRDAuuH1OByWzphtt//S3kvO0TBoUwjZKi2/vd6MO7NbM7dnTb48fZ85B6MqHuApIHgGBQTKQWFhxac//MmOrz7+H3v3HVdV+Qdw/HPvZe+9ZQjiVtx74l64V2ZqWlrZ0NTUXJm5SivTnyO1NFfuPbLSHAgiIC4QlKHIkj0v3PH74yp44yKgIGjn/Xr18nXP+Z5zHugA53ue5/k+LP90DGmPEzEwMsapZm1mrN5G+96qRYVFYjFfrNnFz0tmMHNEFyRaEup4tWLG6u3oGRhy/04wSz4YzuBJ0woLmbwsLW1tPl66ga3LZxN+IxClQkGdpq14b+536OoZlHicZ+MWLNv1J3vWLmXWqK7kZmViZm1Lh95DGDZ5Jjq6euX62ivL1uWzObT1R7Vtv6yYwy8rVMNwO/UfwbSVWwAY9O6n2Dq5cHTbOj4d1IacrExsHF3oMWw8Q9+fofb9aNK+G7PX7GLfxm+Z2LUuYrGIOk1as2znWTwaFF9U900n0dGn1bzDRBz4luAfJ5GfnoSWvjGGDh54Td2AXStV0iUSiWnyqWoBed+F/RCLJZjVao7XRxuQ6BmSEX2DwNXjqNnvw8JCJi9LpKVDw/e+J3TnItLvB4NCgZlnC+qO/RqJjn6Jx5m5N6X1gqNEHFzFla/6I8vNQtfUGrvWPrgP+KRwSGVZv/bKIM/PJSlYtTzL+c80D81y6jyaBhO/A8Ct7wfoWzsTfXoTl+d2Q5abib5VDZy6jKHmgKnP/X4IBKVZcjAQiVjED++0RV9H9WjYo5ETH3Svx5JDQfhFJNKmlmokSXquKhk0fKa38GWl5eTTb8VJBjRzwbu+I72Xnywx9tr9JH45H8aqt9vQp4lqOkLrWjbMH9yUdX/cJiIhnVp2phXWNsHrJz1Xhs/mm/Srb0nXWmb033SzxNhlZ2PQEotYNdADfW1VH1k3T3Peb+vAsrMx+Mdk0NpFNVUh8GEm264msHKAO73rqkbJtHIxYW53ZzZcjuNeci4eVuX7Xfz9+Ydk58tZN9QTcwPVz17POhZ80smRpWdjeLe1fbnPWV5CMigQlMLK3ompS/5XapxbnYbFhik+tfZEkNrnkubabfrrTrFtJQ25VMgVuNfz4utfS/6jCbDw58PFtrnX8yqxDc8q69deGcbPWsr4WUvLHN+25yC1IbPP08q7H628+5Ue+B+hZ+lAg0mrSo0zdq5fbJjiUx1WXFD7XNJcu07fXy22raQhl0qFHBPXhrScs++57Wo+s3jxGhPXhiW24Vll/dormkRHv9zDTO1a9lMbMlseNbzHUsN77Asd+zob8O0pgqOSufPdCAx11R95vjkUxPcnb3Boek/aeqoSnQuh8Xx/8gZBUY+RyRXUsDRiWOuafNC9HjpaEk2XAKDfilNEJmVwa+Vwte2b/w5l9m5/Dk7vQTvPoiWDbj5IYcXR6/hFJJItLcDOzIB+TZyZ1rcRJvo6/z59pXuUmoO1iX5hIviUq7UxANFJWYXJYEZOPnrakhfuAdQkKSOX97zrMraDJ9fuP3+t152XIzDQ1WJ4a/X5s6PaejCqbfnW9XzdDN5yi+uPsgiZ2RxDHfX7cfmfMfz4Tyz7xtenjasqebkUmc6P/8QSHJuFTKHEyVSXIY2tmdzWHh2tkgcHDtx8k6iUPIJnNFfbvtUvni9PRKpdA+BWfDbf/f0Qv+gMsvPl2Jvo0LuuJZ91csJYr+Sfm8qSlF3AxNb2jGluS+DD5/c0P0rPx9pQuzARfMrVXPViPCZFSmsX1bbdgUkY6IgZ2lh9bveIJjaMaPJiBbuO3HxMW1eTwkTwqd51LfnmjxiO30rmk05OL3TushKSQYHgdSWMhRG86YR7XPCShrd250p4IqdDHjC4hXql4INXo3C2MipMcvwiEhnxwx/0berC5UU+mOjrcCI4hg+3XuRxZh5fD6+Ygg3B0ckMWHmKTnXtOT6rN/ZmBlwKi+fTbZe5Ep7IsVm9S0y0UrKk1Jle+ou8S4t8ytU7VtfRjNMhD8nIzVdLRiOfDNn0dCg6V3pOvtocwopQy860zO31j0ikgZPFc5PzN9XQxtb4RWfwR1gqAxuqJySHbyTjbK5b2IvlH5PJ6G136F3Pgn+memGsq8Wp0BQ+PhBOcnYBi3q7Vkibrj/KYvCWW3SoacqRiQ2wM9HBNyqD6Yfu4RedweGJDUq+n3NkNFxe/AXhv52f6lWu3jEPK/0yx9exNeCPsFQy8+RqiWvkk+GlnjZF57kak0F9O8PnJtLl8Sg9n9QcGbWsi4/mcrXQQ0siIuRR5ddfEJJBgUAgEAgEb6QBzVyYvdufQ1ej1JLBa/eTiH6cyYz+jZ8uc8nJ6w/Q1ZawYEgz7MxUD2dDW9Vkx8UIdl++V2HJ4Py9VzE31GXz+50KE5oejZz4clBTPt12mcMBUQxpqXmJGwsjXRI3VHwP7/S+jTh/J46Ptl5i2ahWWBnrcSksnv/9cZuBzV1p6lqUeKTn5qMtEbPiaDBHr0UT9TgLMwMd+jZxZtYAL8wNK7eSY/TjLHo2Nuf3K/fYcPYOd+PT0deW4N3AkXmDm+FgXvI0iddd//qWfHkikiM3k9WSwcCHmUSn5jG9S43C+/l0aAq6WmLm9XDB1liV4A9uZMXOawnsCU6ssGRw0alozPS12DjcszBJ6uZpzuxuzkw/fI+jN5MZ1Kh4lWQACwMtYhdVbdG2zzo58c+9dD4+EM43/WpiZajNpch0Nvo+YkADS7wci+Zzx6RJ6W5rwL7gJDZdiSM8KRc9bTFda5kxt7sL9ibl69VPylYNubYwKJ6OiUVgrq9FUnbBy32BZSAkgwKBQCAQCN5IJvo69Gpcg5PBD8jMK8D4SY/Wfv9IRCIY0dq9MHbhkGYsHNKs2DmcrYy4dDeetJx8zAxebghnZl4B/hFJDG7pVqxnq2t9VaXDwMjHJSaDlaWuozlbJ3dm0qZ/8PqiaFh2nybOfPe2+sO6QglSmRwDHW32T+uBnraE83fimLXTjz9vPuLvef0qvOfwKblCSV6BnAuhcTzOyGPNuHa4WBsTcD+Jz7ZfpteyE1xYMKCwouibxlhPQo865pwOTSVTKsf4SaXLgyGPEYlUPYdPzevhwrweLsXO4Wyuh29UBum5Mkz1Xy4NyJTKuRqTwaBG1sV6y7rUMgMgKDarxGSwOqhja8DmkZ5M3htO8++KquT2rmvBigFFvx9U956CS/fTeZxVwPeDPHA21+XagyxmHLlH3403OPdR43JVFM0rUACgI9Hc06gtEZH7JKYyCcmgQPAa0jQPUCB4k2iaBygQvIjhrWtyOCCKk8ExDG/tjlyh5PC1KNrWssPZquitv7RAzpbzYRwLjCY6KYu0HClyhRL5k3KCin+XFXwB8Wk5KJRK9vndV1vr71mxqa9mWZ5n7b1yn0+3XWZyt3qM71QbG1N9bj5IYfpvvvT45jjHZvTC0lg1h+rkrN7Fju/f1AWxSMT49edYc/oms32aVEo7xSIRYpGIzNwCtk7pXJicd6prz7dvtWbkj3+y/uxtZg3wqpTrVwfDGltz9GYyp++kMNTLGrlCydFbybR2McHZvKhXVipT8Kt/AsdvJxOTmkdqrgyFksL7WV4Bo/ATMvNRKGH/9ST2X9c81/NRuvTlL1SJ9l1PYvrhe7zfxoGxLWyxNdbhZlw2M4/ep8+GEA692wBLQ+0n9x5kSOVsHlm7MJHu6G7Ksv41GbP9DhsuxzGja40yX1tfW5XM58s1J3z5MmWxuYyVQUgGBQKBQCAQvLG61HfEyliPwwHRDG/tzsWweJIy8pg/2F0tbtKmfzgd8oDP+zVmWKua2Jjoo6Mt4fPffNl5KaJC2zSmfS1WvV091jSVKZTM2uVHKw8b5g0uqqjc1M2KNePa0fXrY/x05hYLNPSaPqtrfQdEIrgW+fi5cS9DJAJLY13MDHSL9dK29bRDJIIbD0peH/RN0MnDDCtDbY7cSmaolzWXIjNIyipgbnf1XsDJv9/lj7upTOtcgyGNrLA20kFHS8Sso/fZHVix6y6ObmbDygHupQdWMzKFkrnHI2npbMKc7s6F25s4GfH9IHd6/C+E/116xJc9XFT3nqE2pnpaxXpU27iYIBLBzbjyvcixNVb1oCfnFB8KKlMoScuV0cq48nu5hWRQIHhFFk704c41X/YEvX6L366aMYHzR4uKFmz68zY2jsWHn7zuPujtRWxkOADGZhb8duVBFbeo+gpYMYrUMH+6b75X1U0pt5D/fcijS0VVUTut9kffuuxvc99EF2a0JztO9f9S28gc7/W3q7hFFUdLLGJwSze2ngsjPSefA/6RGOpq0b9p0e+w+LQcTl1/wKAWrszo11jt+AfJpT/gScSiwh6XZyVlqK9x5mBuiFgk4kFy1gt9LZVRQOZhchZZeQXUsi8e7/HkHOHx6YBqUfjQR2kY6WlR08ZELVYqU6BUgp525RZ2aeRsSaCGhFMmV11fu4Qhd28KLbGIgQ2t+OVqPBl5Mg7deIyhjoS+9SwLYxIy8zkTlopPQyumdVavRPkwrfSeOomohPv5X/PX7E10EIvKdk5NKquATFnFpknJksqpZV383O6Wqm3hSbmF2xraGxL4sPjPrkyhRKkEHUn5KuzaGutgY6TN3cTcYvsiknKRKZRqcxYri5AMCgSCMtHW0WVfiPobV6VCwfEd6zm1ZzPxMZEYmZrTsksf3vn8awxN1B8sHkVHsH3VQm76/1O4DqD34DEMmTgNkfjF/njfuxXEjh++4k7QFQqkUhzdatF/7Id0G1K8wEJZYtedDAbgmw9HcPva5Rdqk+D1INbWocfW6GLbFbICbv48jUcX91F71Hzc+k7ReHxG1A3C9y0n9e5V5NJc9K2csG3RB/eBnz53AfnnyY67x93fl5Jy+yKKAin6VjWwa9Uft74fINEzVItNvx/M/SM/knYviILMZPQsHbFt3gf3QZ8Vu75SqSDmzBYe/LWdnMQotA3NsWnaHc+R89A2UD3Qd1h5EYDA1eNJDfN7ofZXZ8Nbu7PxzzucCXnIyeAY+jdzweCZpSbyZaphWhZGemrH3Y1Lx/duPADK51S3tTbRwy8iH2mBHN1nkqF/QtWXDzHU1aJ1LRsu300gMSMXG5Oih9Ar4Yl8vsOXn8a3x8vFEk0qo4CMjYk+OloSQmPTiu27E5sKQA1L1T2VL5PTb8VJmrpZcWh6T7XYszceAtC+th2VaXALN/68Gcv5O3F0qmtfuP1imOr/UyuPFyvx/zoZ6mXNz1fiOBOWyqnQFPrWt8BAp+jvqFSmulf/XZgkPCmXK1EZwPPvZysjbfxjZEhlCnSfmQt48X66WpyhjoRWLiZcjsogMasAG6OiuaJ+0RnMOnqfHwZ70NhB8+/Eqi4go+otFROWkFNsX2iialuNZ4be+jS04q/wNP65l05H96JnnMtPvqctXdRfkJTFwEZW/OqfQHJ2AZaGRd+/wzcfoyUW4dNQ8++CivRmvz4RCASVasPiaez44SvGfLKAnf6xzFy9jStnj7Bo0kC1PzSpjxP4YpQ3OZnprPz9PLuvxTNuxtfsXb+SDYunvdC1r/xxhOnDOqJnYMSq/Rf5ze8BXQe+xU/zPuTglh9eOFbw31WQnU7A8pHkJBRPEp+VHnkd3wV90dIzot2SP/DecJu6Yxbx8NxOApaOQKks/4T/rNi7XP6yB/kZj2k17xBd1t3AffB0Io+vI/in99ViU0Kv4LfYB7GWDq3nH6Hr/27hOXw2MX9sJWDZyGLXv/PrHML3raDWsC/w3hCG19QNJASc5NqK0f+Z5TsaOVtQ28GMlceuk5aTz8g26uvROVka4mJlzImgGEIfpSEtkHP2Zizj159jQDNXAIKikzX2lgB4N3BEoVSy8th1MnLzSczIZcHeADKfLND+rPmDmyEWi3jrp78Ij09HWiDn0t14Ptx6ER0tCXUdzCr8638eA10tPuxRD9/wBJYcCiI2NZvcfBnX7icx/bcrmBro8F7XugAY6Wkza4AXl+8mMO/3qzxKzSEjN5/DAVF8+ftV6juZ805Hz8Jz+0UkYvP+Nr7YVXEvGAa3dKOtpy1Tf7nElfBEcvNlXAyLZ85uf9xsjBnTvlaFXau6amhvSG0bA1ade0h6rozhXuoJsJOZLi7mepy8k0JoYg5SmYK/wlOZuDuMfvVVycX1R1kl3s9da5mhUMKqcw/JzJOTmFXAotNRZObJisXO7e6CRCTinR13iHici1SmwDcqg08ORKAjEVPHpvpWdzXQETO5rT1XojNYdjaGR+n55BYoCHyYycwj9zHR02Ji66IXDoMaWtHG1YRPD0bgF51BboGCy5HpfHk8ElcLPUY1Lfr/4B+TieMCX+Yej3xuGz7u4ISFgRaT94YTlZKHVKbg8I3HrL8cxyednHA0rdzqvCD0DAoEghcUdt2fk7s28dHitbTuPgCAes3b8c7nX3Noyw/ERobjVFP1UPD7umXk5mTz+apfMTazAFQLvw+fMovtq+bT7+0PCmPL6tdv52FhY89nK35GW0f1y9Jn/Mc8uBfKrh+/pvuQsRiZmpc7VvDfVJCdjt+i/ti16o9V465cWVjy4u539yxFLJHQ4L3VSHRUPTvWTbrj1mcyd39fSmqYPxZ1Wpfr+nf3LEGpkNHk0y3oGKt+Ruxb+5B+L4iokxtICb1SeM7w379Bx9iShpPXINZSvUm2azWA9PvBRB7/HxmRIZjWVBXQSIu4RszZX2kw8Vtsm6sKf5jXbkXtkV8SeWI92XH3MHR4sxfqfmp465osPhCotrbgU2KRiF+mdGbuHn96LzuBlkRM85rWbJrUEUM9LW48SGHs2r+Y2quBxuIow1u78yA5iz2+91l/9g52ZvqM7eDJnIFNeed/f5P/TEXApm5WHJ/Zm2+PXaffilNk5uZjY6rPwOaufNK7oVrP4qsy26cJNW1M2HbhLpv/DiUvX4a1iT7t69jx83sdcbMxLoz9sEd9nK2M2PjnHbp+fZSsvAJqWBrxdgdPPunVoNjC9QBapQzdXLgvgHV/qA9NXrj/Ggv3q6o7Dm1Vk3UT2gOqIbm7pnrz7bEQPth6gYS0XCyMdOnRyInZPk0qrZJpdTOksRXf/BGjtrbgU2IR/DzSk/knoxiw6SYSsYjmNYxYP9wTAx0xN+OyGb8zjA/aOzDL27nYuYc2tuZBmpR9wUls9I3Dzlibt5rZMqubM+/uCkMqK7qfmzgZcXhiA1afe4jPzzfJksqxNtJmQAMrPu7oqNaz+Kp8dTqaDZcfqW1bfCaaxWdUL/oGN7JizRDVS4NZ3s7UtNTnt4AEtvrHk1egwMpIm/ZupmwY7omrRdFoAYlYxPYxdVl97iEfH4ggPjMfCwNtunuaM9O7Bka6xX92S1pj8SlzAy0OT2zAsrMx9N90g0ypHHdLfb7q5crbLWyfe2xFEZJBgeBfZo/pQcTNQLZfjkLPQH1ow2+rF7J3w0qWbD9FgxYdAAi5cp59G1ZwNyQAuVyOjUMNOvuMZuD4jwsTD02+GN2NuOh7/HpJ/a3R8R3r2bh4Oku2naJByw6F2yPvhLDrpyXcCrhEXk42lrYOtOk+gBEfzMbAuPxDE17W2f3b0NM3pLPPKLXt3oPfxnvw22rbLpzYR8OWHQoTwafadO/Ptu/mcfn0QYZPmVXma2dlpPEoOoL2vYcU+x636z2EP/b9ytVzp+jiM6pcsW8iv8UDyYi8Ttd1N4sNNbz7+zLuH/mBlnMPYFFXNVQn+fZF7h/+kfR7QSgVMvSsnHBsPxTX3lMQa5c8kd3vqwFkJ0TRdW2I2vaYP7Zw+9e5tJy7H4u6bQu3Z0TfIuLAt6SGXUGel42uuT22LfrgMfAztAxe/f2cn56ES6/3qNF1DGkR154bm5cSi46pdWEi+JSBrSsAuYnRUM5k0LJBRyzqtS9MBJ8ydWtU7Jy2Lfuja2pVmAg+ZeRYWxWb9KAwGYw9vwuJrgEO7YapxTp2HIljx5HlauPrbmrPBkzt2aDE/fWdzIsNfXzq0iIftc97Pu6m9lkiFjGzvxcz+xevYqlpWGcjZwu2fdClLM1+ZUa0cWdEm7IVAenf1EVtzmVJWnnY8GGP+qWuPbhwaHMWDm1epmsD6OtoMW9wU7WCN/81H7Z35MP2jiXur2dnyL7x9TXuOz9V/T7d8XZdtc8SsYjPu9Tg8y7F51JrGtbZ0N6QLaNql6XZr8T8ni7M71n2ugbDvKwZ5mVdeiCgry1mTndntYIzmrR0NmZKOwfMyrB8h6OpbmFyWhWEZFAg+JeuPqO5HXAJ/79P0LHvcLV9F07sw9bJlfrNVW8ob1+7zMJ3B9Cmhw/rTgZjYGyC39ljrJ75LunJSUycs6JC2hRxM5DZY3rQuE0XVuz+G0tbe274X2DN3CncunaZ5bv+RCLR/OOckZrM222e/0sLYO2JoHL1zt0J9MWtbqPnJrwAj+MekpmWQg33OsX22Tu7I9HS5t6toDJfFyga2iYq/sbN+EkPX1RoCPiMKl/sG8ixwzBSw/xIDDqDfZtBavvirxxC39q5sMcpNcyfgOWjsG3ehw4rL6BlYEJCwClC1n+END2Zum9/VSFtSo+8jv/igVg26EjrBcfQM7cj5c5lbmyaRmqYH63nH0FUwv2cn5nCX1M0P+A8q8OKC+Xq8TJ08ChzvHGNuiQGnkGWk6GWuOYkqF7sGDmWr5d4mEtqAAAgAElEQVQbwKXHuxq356Wq5kHp2xQ92Lj2mqQxNjPmFohEGDkVPZSl3r2KiUv95ybyAkFlScvJ5+DVSA5M61HVTREIXqn0XFVxn73jSv97VdWEZFAg+Jd2vQaz8evpXDyxXy0ZDLvuT/yDSEZ9NBfRk8TC/89jaOvqMW7mEixsVOPKO/UfwZm9W/nz4PYKSwY3L/sCY1NzZv3wW2Hy1aJzb8ZO+4o1c6dw6eQBOvYbrvFYE3NLDodW/LpVCQ+jcelSn78P7eTItp94eC8MHV09mnbswbjPv8bSTvXGMi058Uk7ii86KxKLMTY1J+1x+SqsGpmaY+/szp1AX2QF+Wg986D7tPBLekpSuWPfRHYt+3P717nEXTmilgymRVwjJzEaj8GfFybKiYGnEGvrUmf0fHTNVUUgHNoN5uG5HcRe2FNhyWDobwvQNjTDa+qmwiTFukl3PEfM4eamacT7HcG+7WCNx+oYW9DrtziN+14V94GfkXzjPCHrP6beuKXomFiRcvsSkSc2YN/aB1P3illjLT89iahTmzByqoO5Z4vnxsVe3Ef0mS14DPxMLRnNTYrByKkHsRf3En1qI1mx4Uh09LBq7E3tkV+iZ2Ff4nkFgpdlZqBD8LKhVd0MgeCVM9XXImD685djqS6EAjICwb8YGJvQsmtfAi/8QU5WZuH2f47+jkgkosvA0YXbxs38hj2BCVjbqw+lsHVyJSczg6yM4tXZyisnK5M7gb40bNWxWC9c0w7dAQi7Xnpp5oqkkMvJz8sl5Mo5zh7YxidLN7LdN5oZ328nNPAKnw/vRHbGk1LkeaqSyVramudxaOnoIM0rXsmrNONmLiE5PpbVMycSH3OfnMwM/jz4Gyd3/QyATCZ7odg3jZaBCTZNe/I45C9kuUX3c9zlgyAS4dihaPhg7VHz6f5zBHqW6kOP9K2dkeVkUJCtXknuRchyM0m7exWLeu2K9VZZN1INm0u7V86e4lfMuEZdmny6hbSIAM593JQz45wJWDEKizqtqf/uygq5RkFWGoGrxiHLyaDR5DWIxMXnouQkRHJqjD1/fdiIiIPf4TliLu4DPyvcr1TIkefnkXL7IrHnd9PwvR/w/t8tvKZuIO2uP74L+lCQk1Eh7RW8XvJlcmze34bN+9teeJmL6q7t/EPYvL+NU9eFJYLedPkyBY4LfHFc4MuDF1zmorrruCYYxwW+nA6t+HU0hZ5BgUCDLj6juXhyP35nj9Jl4GgUcjkXT+6nfov22Dq5FsblS/M4uXMjl88cJuFBJJnpqSgUchRyOUDhvy8jJTEOpULBuSO7OXdkt8aYx/EPX/o65SESixGJxWRnZjD7p90Ymaiq33m17cqURT+yaNJADv/yI6M/noeuvqqSmKyg+KKqAAX5UnT1yl9trHW3/szfeJDtqxfwYd9m6BkY4tW2K7N++I1PfFqhb2j0QrFvIscOw4j3O0LCtVM4th+GUiEnzu8IFnXaoG9dNIRYUSAl5uwvxPsfJzcxmoLsVJQKBUqF6j5++u/LkKYmoFQqeHRpP48u7dcYk5cc+9LXqUyPLu7jxqZpuPV5nxre76BrZktG9A1ubZ6J77xetJp/BB2TFy8HnpMQxbWVbyHNeEyzz7dj4qp5npuBrRu9foujIDudlDuXufPrHOKuHKLFF7+jbWiKSCRGJBJTkJNJk0+3oG2oKoVu2aAT9SesIGDFaKJOrKfW0Jkv3FbB62fdhPaFxVjeZJe/GljVTRC8AmuG1KrS+Xavyj9Ti89HrihCMigQaNCkQzdMLa25eGo/XQaOJsTvPGnJibwz42u1uJWfjeXq3ycY+eEcOg8YiZm1Ldo6uqybP5Wz+7dVaJu6DxvHR4vXVug5X5RIJMLU3AojU7PCRPCpBi3aIxKJuH/7OgDm1qrhhumpxRcJlstlZKWlYtHc4YXa0axjD5p1VJ+LEh2uqkhn5+T2wrFvGquGndExsSL+yhEc2w8j5fZF8tOTcBz5pVpc8Jr3SQw6g8eg6Ti0G4KumQ1iLR1ubZnJw/O7KrRNTp3fosHEbyv0nK+CUi7j9i+zMa/dEs8Rcwu3m7k3peH7P3B5bjcij6+j9qh5L3T+tPCrBK4ah0TPkNbzD2PkVHyu7b9pG5pi27w3+paOXJ7Xk/tH11B75JcgEqFtYom2oWlhIviUeZ02IBKREX3zhdopEAgEgjeDkAwKBBpIJFp07DucEzs3kp2Rzj/HfkfPwIi2PYveNKYkxuH/13E69B3GyI/mqB2f9Cim1GuIJRIUGnpa/j1/zsrOAZFYTFJs6efUpLIKyLjX99I4PFUul6NUKgvn5lnY2GNuZUtM+O1isQ/vhSGXy6jVsOLG1YcGXQGgbrPSF7ItT+zrTCTRwr7NIGLO/kJBTgaPLh9ComeIXcui5ROkqfEkBp7Gvs1APAZPVzs+93HpPc8isQQ03M/SdPX5mHoW9ohE4jKdU5PKKiBTVrmPHyLLy8LIofibaEN7VSXGrEfhL3TutIhrXF0+CiOHWjT7fDs6JsXn2eYlxxJx4DvM67bBsb16hVDDJ3MFs2LvFm4zdW1I2r3AYudRKmSgVBarSCp4dUb8eBa/iESifhxderBAUM29tf0O/jEZhM9tVdVNEZSTkAwKBCXoMnA0R7etxf/vE/idPUq7ngPR0y8qzV+QrxqXbmKmPhzs4b0wbvpfBFBbeP3fzCxtuH3tMvnSPHR0i9axCfE9pxanZ2BE/WbtuOF/gdTHCZhbFa07czvgEmsXTOWz5T/j0UBzie3KKiDToe9wrv1zhuDLf+HVtmvh9ht+5wGo90yC1bH/CE7u3Eh6ymNMLYoecC+c2IdEokWHvuUvMLB56Syu/n2StSeuIXnyQKtUKDi9ZwtO7rWp27TNC8W+qRw7DCP69CaSAs+QeO0kdi37IdEtGp6rkKkWx9Y2Ul/aIOtROCmhvqoPz7mfdUytKQjzR1EgRaxdNLc1+dZFtTiJniHmdVqRcucy0vREdE2LFulNDfPj1uYZNJyyBlO3xpqvU8UFZHTNbBBr65D1MLTYvqfb9K2Kl2MvTW7SA66tGI2hvTst5uxFS0/z0GVtY0vifA+REX0Th3ZDEImKpv5nRN0AwMDGtXCbfZtBJF3/i+Sb57Fs0Klwe8rtSwCYewoPboLKcz8xgyUHg7h0N75wPcKRbdyZ2qsBYg0VngWC6iwyOY+lZ2PwjUonUyqnhpkuw5vY8GF7R0pZTrBaEwrICAQlcK/nhbNHXXav/YasjDS6Dh6jtt/GwRm7Gm5cOXuE6PDb5EvzuHb+NEunjqRdL1UlxIgb10qcN9isYw+UCgW7135DTmYGqY8T2LJ8NtlZxYt0vPP5YiQSCYvfH8LD+3fJl+Zx0/8Cq2dNQltHF+da9Sr+G1CKTv2G06BFB3744j1uB1xCmpfDDb9/2Lh4OvbO7nQfNr4wdtj7MzA2t2TlZ28TF3OPfGkeF47v5dCWHxg+ZZZaAZ7b1y7jU8eQDYunPff6TTt0J/5hJOu/+ozMtBRSHyewdv5HxITf5qPFawsrvpY39k1l4toQI6faRBz8joLsdBw7jFDbr2flhIGNC4kBJ8h6GIqiQEpS8J8EfT8Bu5b9AUi/H1zivEHrxl1RKhVEHPgOWU4G0vREQncsRKahQInnyC8RicVc+/Ztsh9FoCiQknLnMiHrpyLW1sG4DEMjq4pE1wC3PlNICb3C3d+Xkpf8CHl+LmkR17i1+XO0DUxw7TWxMD41zJ9TY+y5/euc55wVbv86B3mBlCYfbyoxEQSQ6OhRe/QCMqJucOvnz8lNeoA8P5eU0Cvc/Hka2gYmuPQsWqbCvu0gLOq2IWTDp6SG+alib1/i9q9zMbB1w6mL0CslqByJGbn0XXGKjNx8Ts/uw/0fRrFgSDO+P3mDL3b5V3XzBIJyScwqwGfzTTKlMo6915C7c1ryZQ8X1vwTy9zj96u6eS9F6BkUCJ6js89otn03T21twadEYjFfrNnFz0tmMHNEFyRaEup4tWLG6u3oGRhy/04wSz4YzuBJ0xjz6YJi5+7iM5qE2GjV0gy//ISFjT09h09gzKcLWfrRyMKeRwDPxi1YtutP9qxdyqxRXcnNysTM2pYOvYcwbPJMtZ7FV0UskTB/0wH2rF3K6pkTSU6Mw8TckhZdejPmkwVqRVmMzSxYvutPtq9awMwRXcjJysTR1YOJc1bQa+REjecvad3Ep5q078bsNbvYt/FbJnati1gsok6T1izbebZYL2l5Yt9kDu2GcnfPErW1BZ8SicQ0+XQzd7bPw3dhP8RiCWa1muP10QYkeoZkRN8gcPU4avb7kFrDvih+7vbDyE16QOzFvUSd2oCumR01uo6h1vDZBK0ej6IgvzDWzL0prRccJeLgKq581R9Zbha6ptbYtfbBfcAnaj2Lr0rozkVEnVivti1s11eE7VItp+HQbjCNpqjm7NYa9gUGdjV58NdvxJzZgrwgD10TKyzqt8dr6kYMbIvPQRWJS76f5fm5JAWfBeD8Z5p76pw6j6bBxO8AcO72Drqm1kSf3sSlOd4oZPnoWTpi5t4E90HTMHhmTUKRWEKzGTu4d3AVIf/7iLzUBHSMLbBp0o1aw754buIpELyM746HkJ1XwMZJHQsXne/VuAbT+jbi64OBTOpah1p2pqWcRSCoHr4//5DsfDnrhnpibqD6fd6zjgWfdHJk6dkY3m1tj4eVfhW38sUIyaBA8BxDJk1jyKSSe6jc6jRkyfZTGvetPaFeHn/hz4fVPoslEkZP/ZLRU9WLeAAah3W61/Nizto9ZWn2K6OrZ8DY6YsZO31xqbHW9jWYtnJLqXH1mrVl0LufYmxqUWpsK+9+tPLuV2pceWPfVDX7f0TN/h+VuN/YuT4t5x7QuK/Digtqn5vPVC8oIxJL8BgyA48hM4odq2lYp4lrQ5p+trUszX4l6oxeQJ3RxV/alMSxw3AcO2he2/NZ5rVb4tb3A7SNzEqMkejol3voq22LPti26FOmWImOPp4j5qoVvBFUrqCox6w4ep2A+0kolVDX0YzP+jSka33H5x53ITSe70/eICjqMTK5ghqWRgxrXZMPutdDR6toeZHUbCmrjodw6vpD4tNzMNLTxsvFkhn9G9PU1arccZXh0NUo2tW2K0wEn+rj5cziA4EcDYxmWp9GldoGQcUIjs3iu78fEPAgCyVK6toY8HEnJ7p4lPx7DeBSZDo//hNLcGwWMoUSJ1NdhjS2ZnJbe3S0igYnpuXK+P78Q86EphKfmY+RroTGDoZM71IDL0ejcsdVhiM3H9PW1aQwEXyqd11LvvkjhuO3kvmkk1OltqGyCMmgQCCoVrIy0vjn+F6+/vVEVTdFIHhpBdnpxPkepOWcfVXdFMErEhj1mAErTzGhcx1WvtUaQ10tVh0PYfSav9j+YRe6N9T8wOgXkciIH/6gb1MXLi/ywURfhxPBMXy49SKPM/P4eniLwtj3Nv3D3bh0Nr/fiYY1LEhIz2XBvgCGrDrD2bn9cLc1KVfcv6VkSakzvfSXj5cW+Wjs3YtNzSY1W0pt++L73GyM0ZaIuR6dXOr5BVUvODaLgZtvMq6lHcv618RQR8L35x8y9rc7/DK6Dt6e5hqP84/JZPS2O/SuZ8E/U70w1tXiVGgKHx8IJzm7gEW9XQtjp+y9y92kXDYO96SBvSEJmQUsPh3F8F9uc2pyI2pa6pUr7t9ScmQ0XF76esznp3pp7N17lJ5Pao6MWtbFl8FytdBDSyIi5FHF12Z4VYRkUCAQVCtGJmZsOXe39ECB4DWgbWhK5x+LV/MUvLm+2n8NOzMDFg5tVlgkZdGw5hwPimHrubASk8GT1x+gqy1hwZBm2JmpHjqHtqrJjosR7L58rzAZlBbIuRAaz+h2HjSvaQ2As5URP45rR/M5B/j79iPcbU3KHKeJhZEuiRvGvvD3ICkj78l5ij+ci0UizAx1CmME1dvXZ6KxN9Fhfk/XwiIp83u6cuJ2Cr/4J5SYDJ4OTUFXS8y8Hi7YGquqiw9uZMXOawnsCU4sTAalMgUX76czsqkNzWoYA+BsrsuqQR60+T6QcxFp1LS0K3OcJhYGWsQuevFCcUnZ+YXn+TexCMz1tUjK1ryW8utASAYFAkGZFORL8amjqqa66c/b2Di6lHLE6+eD3l7ERqqWBTA2K32YquD1pSjI59QYewA6rfZH37r8FUDfJBdmtCc77h4A2kaaH+4EpcuWyvANT2BIy5pq1TLFIhGBS4c899iFQ5qxcEjxZXacrYy4dDeetJx8zAx00NYSY2Wsx4ngGLo1cKR7Iye0JWKM9bQJW1VUGKqscZUhL19e2AZNdCQScvNlldoGwcvLzpdzJTqDQQ2t1KplikXgP+358+3n9XBhXo/izwnO5nr4RmWQnivDVF8LbYkYK0NtTt1JoWstc7p7mqMlEWGsK+HmrKLe8LLGVYa8AgUAOhLN97O2RETuk5jXkZAMCgSCUk1buaVM8/1ed+tOBld1EwSvQKMpawuLwQhUOqy8WHpQFdPSUj2yyBVKJNW0jntiei5KJVgalb8IkrRAzpbzYRwLjCY6KYu0HClyhRK5QrWki+LJv2KRiN8+6sqUzRcYt/4c+jpaNK9pjXd9B0a18yico1fWuMqgr6Oa31gg0/yALJXJ0dep/o+gsiff86f3XmXQkkiQP2fZnqqUlFWgup8Ny78eqVSm4Ff/BI7fTiYmNY/UXBkKJYX3s/zJlywWwS9v1eGjfeFM3B2GvraYZjWM6eJhxsimNpjpa5UrrjLoa6vu53y55vs5X6ZEX7t6L9AgVyrRkkg07qveLRcIBAKBQCAATE1V888ycvNLiaw6T5NUaQlJ0PNM2vQPC/cF0LmeA8dm9uLuqpE8WDuG0e08isV6uVhyedFAjs7oxZRu9cjKK2Dh/mu0nneIGw9Syh1X0WxNVfOukjOLDwWVKZSkZUuxNys+/6q6yXxyr5mZPb9QysswMTEiM0/zkj1V7Wnv9ovcz5N/v8tXZ6Lo5GHGoXcbcPuLltyf14qRTW2KxTZ2MOKfqU04+G4D3mvrQJZUzuIz0bT7IYibcdnljqtotsaqZDg5p/hQUJlCSVquDLsnQ2Grq4w8OSYmmovsVP/XMgKBoNDCiT7cuebLnqDEqm6KQFBpAlaMIjXMn+6b71V1UwTViJubasmO+wkZNHsyB666sTc3QCwSkZCeU67j4tNyOHX9AYNauDKjX2O1fQ+SNT/kikTQysOGVh42fOHjRcD9JAasPMXKo9fZ9kGXcsc962ULyNiZGWBjok9oXFqxfeFxacgUSppUcjXTihARr1ontWbNmpV2DTdXV+4lV8+/6Q4mOohFkJhZvvlwCZn5nAlLxaehFdM6q8+RfZgm1XiMSAQtnY1p6WzMzK41uPYgk8FbbrHq3EO2jKpd7rhnvWwBGVtjHWyMtLmbmFtsX0RSLjKFstKrmb6s+8m5uJdwHwvJoEAgqHZkBfn89OUH/H14F+NmfsOgCZ9UdZMEggqnkBVw8+dpPLq4j9qj5uPWd0pVN6lac3Nzw9zUhKv3k6ptMqgtEdPC3ZqLofFIC+ToahcNy+r01VH0tCWcnl18SZD8Jz0v/y64cjcuHd+78QAonwwlvHw3gSmbL7Bzqjf1nYrmdzavaY2tqQGp2dJyxWnysgVkAIa0dGPL+TCSM/OwNC76ug4FRKElFjGwhetLnf9VuBaZhLmpCS4ulTdHvlmLVgSe3ltp538ZWhIRzWsYcykyHalMge4zc0C9111HT0vM8fcaFjtOKlPdq/8uuBKelMuVKFWC/fR+9o3K4KP94Wx/qw717AwLY5vVMMbGWJvUJ71xZY3T5GULyAAMbGTFr/4JJGcXqA2bPXzzMVpiET4NLV/q/JUt6FEeTXtqnlspDBMVCATVSlZGGgveHUBcTGRVN0UgqDQF2ekELB9JTkJ0VTfltSESiejZqzdnbpZvTcZXbd7gpkhlcqZsuUhSRh7pOfksPRzEndhU3unoqfEYJ0tDXKyMOREUQ+ijNKQFcs7ejGX8+nMMaOYKQFB0MnKFkiaulkgkIj7aepHAyMdIC+SkZkv539nbxKZm81a7WgBljqssn/ZpiKWRLpM2/UNkYibSAjkHr0ax9sxtPuvbCCcLw9JPUsVO33hEr959EIkqb45qz549CXqQTlJW9axGOae7C3kyBVP3R5CUVUBGnozlf8YQmpDD281tNR7jZKaLi7keJ++kEJqYg1Sm4K/wVCbuDqNffVXSdP1RFvInPWpaYhGfHLxH0MMspDIFabkyNl6O41F6PqOaqq5R1rjK8nEHJywMtJi8N5yolDykMgWHbzxm/eU4PunkhKNp5c3BfVmJWQUExqTRq1cvjfuFnkGBQFBtZGWkMWtUV9r1Gkyzjj2YOULzECaB4HVWkJ2O36L+2LXqj1XjrlxZ2K+qm/TaGDV6NAN//53IxEzcbIyrujkatXS34cC0Hiw/EkzreQdRAp72pmx+vxP9m2ruYRKLRPwypTNz9/jTe9kJtCRimte0ZtOkjhjqaXHjQQpj1/7F1F4NmO3ThKMzerHy6HXe3XCepMxcjPS0qWVnyqZJHfFp7gqAvo5WmeIqi7mhLsdm9uabQ0H0Xn6CrLwCatqYsGREixKT4urkfmIGl8PimLVidKVep3fv3pgYG7E7KJGpHRwr9VovooWzMXvH1WflXw/o8GMQSqCWtT4bR3jSt57m3jCxCH4e6cn8k1EM2HQTiVhE8xpGrB/uiYGOmJtx2YzfGcYH7R2Y5e3MwQkN+O7cA977PYykrAKMdSV4WOmzfpgn/RuorqGvLS5TXGUxN9Di8MQGLDsbQ/9NN8iUynG31OerXq683aJyE9GXtScoETNTEyEZFAiqu/Ab19i15mtCg/1QKpW4ejZg2OSZNO3Q/bnHhVw5z74NK7gbEoBcLsfGoQadfUYzcPzHaOsUvanKSk9lz7pl+P91nJTEOPQNjfBo0JRRH82lVqPm5Y6rDGmPExnwzkf0HD6BsOv+lXotQdVIvx9MxP6VpIUHoASMa9TB3edTrBo9P/FPvn2R+4d/JP1eEEqFDD0rJxzbD8W19xTE2kUT9wuy0rh3aBWJgWfIS41HS98IU7fGeAz+HFP3JuWOqwz56Um49HqPGl3HkBZxrVKv9abp27cv7m6urDgWwv8mtKvq5pSopbsN+z/r8dyYPR93U/tc38mcQ9N7aoy9tMhH7bOjuSHfj21bajvKGldZnCwMWTehfZVd/2WsPHYDdzdX+vQpPqy3Iunr6/Pe5ClsWvcDY5vbYlqJVTFfVAtnY34fV++5MTverqv2uZ6dIfvG19cYe36ql9pnB1MdvvNxL7UdZY2rLI6muqwZUrk96hUtPVfGJr9EJn3wCfr6xedDgpAMCgTVQnhIAF+81Z0+b73PlEU/om9gxJ51y/jq/cF8uW4vzTtrfptz+9plFr47gDY9fFh3MhgDYxP8zh5j9cx3SU9OYuKcFYWxKz8by4N7ocz84Tdq1m1MalI8W5fP4ctxfVl94CIOrrXKFfdvGanJvN3GudSvde2JIJxqljBUqqZnifsEr7/0e0H4LfbBuft46k9YgUTXkHuHVnFt5RiaTv8Va69uGo9LDfMnYPkobJv3ocPKC2gZmJAQcIqQ9R8hTU+m7ttfFcYG/zSZ7NgwvD7ehIlrQ6RpCYTuXIT/0mG0/foMhnY1yxX3b/mZKfw1RfMDzrM6rLiAoUPxKpAAhg4eJe4TPJ9EIuG71d8zcOBAxnbwoE2t6v1GXvB6unoviQP+9zl8+DCSEsrxV6S5c+ey7ZctrDofy6Jeb94avoKq8925h4h1DZg9e3aJMcKcQYGgGvhl5ZdY2jowYeY3WNvXwMjUnAmzlmJl68iJXRtLPM7/z2No6+oxbuYSLGzs0dM3pFP/EdRv0Z4/D24vjMuX5nH9yjmaduxBHa9W6OjqYevkysdLN6Cto0PgxbPlitPExNySw6HZpf4nJHv/XWG7F6Nrbk/t0QvQs3RE28iM2m8tRNfCnpizv5R4XGLgKcTautQZPR9dczskugY4tBuMRZ02xF4oqnioKJCScusCVo29MavVHLG2LvrWzjR873vEWjo8Dvm7XHGa6Bhb0Ou3uFL/E5K9yjNgwAB6dO/G3L2BSAuqZ0l+wetLWiBn1p4AenTvRv/+/V/JNY2NjVm8ZCm/+MdzoxKXSBD8t9yIy+bXqwksXbaicGkeTYRkUCCoYnk5WdwKuEidJq0QiYt+JEViMT//Hcr8DQdKPHbczG/YE5iAtX0Nte22Tq7kZGaQlaEq662trYOZhTV+Z49y5Y8jyGWqieoGRsb8duUB/cZMKVecQFBe8rxsUkKvYO7ZHJHomftcJKbzDwE0+/y3Eo+tPWo+3X+OQM9SfT6NvrUzspwMCrLTVefS0kbHxIrEaydJCDiJUq66f7X0jfFefxuXHu+WK05Qff20dh2xaVI+2eZLNV2vW/AaUirhk22+xKZJ+Wntuld67fHjx9O5Uycm7IkgIbP6rqUpeD0kZOYzYXcEnTp1Yvz48c+NFYaJCt5oWlqqW1whlyN+BUM9XkTq4wSUSiWmFuUvlZ4vzePkzo1cPnOYhAeRZKanolDIUchVb8uf/isSi/ly/T6++3wCS6eOQlfPgDpNWtKkQw+6DxmLkal5ueIEJZPLZUDRvVcZJFpaKBWvV4+IND0RlEp0jMs/yV9RICXm7C/E+x8nNzGaguxUlApF4ffg6b8ikZimn28jZO0HBH0/AYmOPma1mmPVqAtOnUahbWRWrjhBOchlr2Q43VMeHh7s3X+A3r164W5znRn9G5d+kEBQim+PXedoYAwnT53Cw+PV9u6LxWL27j9Am1YtGL8ngn1j62CgI/TZCMovJ1/B+N0RGFs7sG//AcTi599Hwl0meKM97RbPycqo4paUTCxWPUAV5Je85lNJVm/qIZQAACAASURBVH42lq0r5tCknTfLdp5lh/9D9oWk0G1I8fWhPBo0Zd3JIJbu+AOf8VPJycrklxVzeL9HQ+7fvl7uOIFmOZmqe83MrPISCiNjU2Q5mZV2/sogenKfK2Tlf+MdvOZ9QncuwqphJ1rNP4z3hlB6bI3CqdOoYrGmbo3psPIireYdxrXP+8hyMwnb9RX/fN6GjKib5Y4TlI0iL7NS73lNvL29WbtuHd8eD2HB3gDkCqGLUPBi5AolC/YG8O3xENauW4e3t3eVtMPMzIxjJ07xKEfC0G2hQg+hoNwSMvMZui2UR7kSjp88Vabfy0LPoOCN5ubmBkBsVDi1G7es4tZoZmXniEgsJjUpvlzHpSTG4f/XcTr0HcbIj+ao7Ut6FKPxGJFIRL1mbanXrC1vfTKf0GA/5rzVg91rv2HO2j3ljntWRRSQeRPERt4FoGZNzQVIKoKbmytp8fcq7fyVQc/CHpFIjDQ1oVzHSVPjSQw8jX2bgXgMnq62L/fxQ80HiUSY126Jee2W1Bo6i7TwAPy+HkTEwe9o+tnW8sc9oyIKyLyJcuLuUbPmgFd+3UmTJmFkZMSE8eO4n5TFugntMNbTLv1AgeCJzLwCPthyifOh8ezYsYNRo4q/ZHqV3N3d8fXzp1+f3vTbfIctIzxoaF/912QUVL0bcdlM2BOBiZUDvn+fwt29bJVXhWRQ8EZzc3PDzMycsCC/apsMSrS0qdukNSFXzpEvzUNHV69w38cDWqKjq8e3e/8pdtzTnkQTM/Vhdw/vhXHT/yIAyieTaW5evcCqzycwb8MB3Oo0LIyt49UKcxs7MtNSyhWnydMCMv91d69fxczMHBeXyqsI17J5Mw6cC6y081cGkUQbM8/mJN++hKJAili7aNmTS7O7ItbWpc1XJ4sd97QnUdvIQm171qNwUkJ9VR+e3Ocpd3wJWfcBzWb8hrFzUcJmVqs5umY2FGSllCtOk6cFZARF8lLiyEqOo0mTyl2SoySjRo3C1dWVQT4DaLvwKF/6NGZ4a3cqcZ1wwRtAqYTfr9zj68PXQUuPv/4+R5s2baq6WUBRQjh86BD6bTrHOy1smd7ZqVouOyGoeum5Mr4795BfrybQpXNnft+3v1wjNYRhooI3mkgkomevnlw9V/whszoZO/0r8qVSVs94l7TkRLIz0vnt+0VE371Fr5ETNR5j4+CMXQ03rpw9QnT4bfKleVw7f5qlU0fSrtdgACJuXEMhl1OrYTMkEi1++GISd69fJV+aR1Z6Koe3/sjjuId0G/oOQJnjBCW7+vcJevXuhagSn0R79uxJSkQQ+elJlXaNyuA54ksUBXlcX/ch+elJFORkEL53GZkP7lDDu/jQZgA9KycMbFxIDDhB1sNQFAVSkoL/JOj7Cdi1VFX6S78fjFIhx9TdC5FEi5D1n5B2LxBFgZSCrDSiTm4gL/kRTp1Ui0eXNU5QNomBp9E3MKRDhw5V1oY2bdpwOzSMIaPG8ul2X3qvOM3hgCjyZYoqa5OgesqXKTgcEEXvFaf5dLsvQ0aN5XZoWLVJBJ8yMzPj1Jk/WL9hI0cjpHRYe4M1F2JJzCqo6qYJqonErALWXIilw9obHI2Qsn7DRk6d+aPcQ/ZFSqVQh0vwZjty5AgDBw7kf6evY+9cdYuVluZOoC87f1xMxM1AlEolNTzqMmjCJ7TtOagwZuFEH+5c82VPUCIAkaE3+HnJDCJuBSHRklDHqxVjpy9Gz8CQxe8PJi76PoMnTWPMpwt4HPeQXT8tIfjyX6Q9TsTAyBinmrXpO2Yy7XsPKbxGWeMqw9blszm09ccS93fqP4JpK7dUahtexqPoCD7o5cXhw4crtSR5bm4udg6O2PWYTM0BH1fadSpD6t2rROxbQXrkdVAqMXL0xLXvFOxa9iuMCVgxitQwf7pvVg2FzYy5xZ3t80iPDEEslmBWqzmeI+Yi0TPk2rdjyEmIoma/D6k17Avykh8RceBbHt88T356Elr6xhg6eODS413sWhUNYyxrXGUI3bmIqBPrS9zv0G4wjaasrdQ2VCS/eT3o174J27b9WtVNASAkJIT5877k2PHj6Oto06G2LQ1qmONgbigMIf2Pyswr4FFqNjcfpHIhLIHc/AL69e3LV4u/plGjRlXdvFKlp6ezdOlSNm1YT1p6Bk2cTWnqoE9NS31M9SRIxEI3+H+BXKEkLVdGZEoegY9yCYpJx8zUhEnvT2b27NnPXT7iOfYKyaDgjSeXy/GsXYca9ZoybaXmeUACQUVYNWM8D24HcjcstNIrK37xxRf8uP5n2q64hLbhC/0BEAheWkLASYJ/eBc/Pz9atGhR1c1R8/DhQ44cOcJff/7J9eAgEhOTyMjKqupmCaqAsZEhNtbWeDVpSldvb3x8fHB0dCz9wGomNzeXU6dOcfr0aQL8rxAZFUV6RiZyudAD/l8gFoswMzHGzc2NZi1a0atXL3r37o2enl7pB5dMSAYF/w1PeweXbDtF/Rbtq7o5gjdQaNAVvhjdrdJ7BZ/KzMzEvVZtDJv0o86Yryr9egLBvykK8rkytwv9u7bjt+3bqro5AoFAICg/IRkU/Hf07NmLew/iWLb7b7UiLQLBy8qX5vHFyC6417Dn9OlTr+y6mzdv5r33J9N60QlMXBuWfoBAUIHC9y0n7o+fCb8bhoODQ1U3RyAQCATlt1coICP4z1i79ieS4x6wZu4UhHcggoqiVCpZM3cKyXEPWLv2p1d67fHjx9O5c2dCvh+HNLV8S5MIBC8j3v8Y94/8yHffrhQSQYFAIHiNCcmg4D/Dw8ODffv2cvn0QXav/aaqmyN4Q+xe+w2XTx9k3769eHi82nXlxGIx+/ftxd7ChOvfj0cuzXml1xf8N6XfD+bWho/58MMPmTx5clU3RyAQCAQvQUgGBf8p3t7erFu7lj1rl7Jl+WwUcnlVN0nwmlLI5WxZPps9a5eybu1avL29q6QdZmZmnDxxDNJiufbNEKGHUFCpkq7/ReCy4XTt2oXvV6+u6uYIBAKB4CUJyaDgP2fSpEns2LGDU7s2snTqSHKyMqu6SYLXTE5WJkunjuTUro3s2LGDSZMmVWl73N3d8ffzxVKSx9VFfcmIulGl7RG8gZRKok//TNB3YxkxbAhHDh2s9Iq5AoFAIKh8QgEZwX+Wr68vAwcOQs7/2bvvuKjrP4Djrzs49t7LBe4tLnArTkTQ3DO1fpqaOUvTNEdmaWaa5SotLfdCc+TMBbgnoiIiIlP2OuCA+/2BYMg24RA/z8fDxyPuPt/vve+C+37e3894SxgxfRGdPYaVaaFw4e2nVCo547mNP76fjxpKDhzYX6EKFcfFxdF/4CD+OXOGKl1HU/O9maLshPCfJQT58vCPeUQ/uMTXS5Ywe/ZsVYckCIIgvBliN1Hh3RYTE8O8efNYv349NRs0w33MJzh17YO6TEPVoQkVSIYiHZ+Thzi4eTWPfG8wfvx4Fi9ejImJiapDyycrK4vNmzcza/YcUhSZVOkxDtuOQ9A0tFB1aMJbJj7wFsEnNhN6YQ8tW7XmpzWrad68uarDEgRBEN4ckQwKAsDt27eZN28+hw//haa2Do1ad8S+XhNMrWzR0dNXdXiCCqQkJRIdHsJjv1vcuXSWNHkKvXu7sXjxIho3bqzq8IoVHx/P0qVLWbd+IwkJcZjUbIa+Q3N0LO2R6RoikYopfkJemYpUFIkxJAbfJ+HBRRIjgqlbvwFzP5/N8OHDxcwJQRCEykckg4Lwb8+ePePgwYOcOn2aq1evEfIsmEyxycw7SU9PHwtLS5o2bYJLly54eHhga2ur6rBKTS6Xc+zYMf7++28uXblKYOATEhPixOZJQj4amloYGhnTsEF92rZxpk+fPrRq1UrVYQmCIAhlRySDglCQ27dv4+rqiomJCUeOHMHOzk7VIZW769ev07x5c/z9/cu9ZIIglIdmzZrh6urKkiVLVB1Kubt37x6urq7o6Ohw9OhRqlWrpuqQBEEQhPInis4LwqtOnDhB+/btqVevHhcuXHgnE0HIrmEH2WvQBKEyysrKyv09f9fUr18fb29vtLS0cHJy4vr166oOSRAEQVCBd/MqKAiF2Lx5M71796Zfv34cOXIEAwMDVYekMiIZFCq7dzkZBLC2tubcuXM0bdqUjh07cuzYMVWHJAiCIJSzd/cqKAj/olQqWbBgAWPHjmX69Ols3rwZmUym6rBUSiSDQmWXlZX1zm+Koqenh6enJx4eHvTp04dffvlF1SEJgiAI5Uhd1QEIgqplZGQwceJENm3axLp16xg/fryqQ6oQRDIoVHbv+shgDg0NDbZu3UrNmjUZN24cz549Y8GCBaoOSxAEQSgHIhkU3mlJSUkMGjSIc+fO4enpSe/evVUdUoWhppZdekAkg0JllZmZmft7/q6TSCQsWLAAMzMzpkyZwrNnz1i3bh3q6qKbIAiCUJmJb3nhnRUWFoabmxuhoaGcPXtWFFN+Rc6IiSitIVRWYmQwv48//hg7OzuGDRtGVFQU27dvR1tbW9VhCYIgCGVEXAWFd9K9e/dwcnIiISGB8+fPi0SwAGKaqFDZiWSwYH379uX06dNcvHiRzp078/z5c1WHJAiCIJQRcRUU3jleXl506NABGxsbvL29RQ29QohkUKjsRDJYOCcnJ86dO0d4eDjOzs48evRI1SEJgiAIZUBcBYV3yt69e3FxcaFDhw6cPn0aMzMzVYdUYYlkUKjsRDJYtHr16uHj44OhoSHt27cXtQgFQRAqIXEVFN4Zq1atYtCgQYwbN449e/aIdTDFEMmgUNmJZLB4VlZWnD17NrcW4dGjR1UdkiAIgvAGiaugUOllZmYyefJkpk2bxtKlS1m1apXoAJaA2E1UqOxEMlgyenp6HDp0iMGDB+Pu7s7GjRtVHZIgCILwhojdRIVKLS0tjVGjRuHp6cm2bdsYMmSIqkN6a4jdRIXKTpSWKDl1dXU2btyInZ0d48ePJyQkRNQiFARBqAREMihUWjExMXh4eODr68uJEydo3769qkN6q4hpokJlJ0YGSyenFmGVKlX46KOPCA4OZv369aIWoSAIwltMfIMLlVJgYCC9evUiLS0NLy8v6tatq+qQ3joiGRQqO5EMvp4PPvgAMzMzhg4dSnR0NNu2bUNHR0fVYQmCIAivQVwFhUrnypUrODk5oampyYULF0Qi+JpEMihUdiIZfH0eHh6cOXMGLy8vunTpImoRCoIgvKXEVVCoVP7++29cXFxo0qQJ58+fx9bWVtUhvbVEMihUdiIZ/G9at26Nl5cX0dHRODs74+/vr+qQBEEQhFISV0Gh0ti0aRNubm4MGDCAw4cPY2BgoOqQ3moiGRQqO5EM/nc1a9bk/PnzGBoa0qFDB65du6bqkARBEIRSEFdB4a2nVCpZsGABH374IXPnzmXTpk3IZDJVh/XWE6UlhMpO7Cb6ZuTUImzWrBkdO3bkyJEjqg5JEARBKCGRDApvtfT0dEaNGsWSJUtYv3692Or8DRKlJYTKTowMvjl6enocPHiQoUOH4uHhIWoRCoIgvCXEbqLCWyspKYmBAwdy4cIFDh48SK9evVQdUqUipokKlZ1IBt8sdXV1NmzYgK2trahFKAiC8JYQyaDwVgoNDaV3795ERERw9uxZHB0dVR1SpSOSQaGyE8ngm5dTi7Bq1aqMHz9e1CIUBEGo4MS3s/DW8fX1xdXVFT09Pby9valWrZqqQ6qURDIoVHYiGSw7Y8eOxdTUlGHDhhEVFcX27dtFLUJBEIQKSFwFhbfKmTNnaNu2LXZ2dpw7d04kgmVIJINCZaZUKlEqlSIZLEMeHh6cPn0ab29vOnfuTGRkpKpDEgRBEF4hroLCW2P37t24urrStWtXTp06hampqapDqtQkEgkSiUQkg0KllPN7LXYTLVutW7fG29ub2NhYUYtQEAShAhLJoPBWWLVqFUOGDGHcuHHs2rULLS0tVYf0TlBTUxO7iQqVUs7vtRgZLHsODg6cO3cOY2Nj2rdvL2oRCoIgVCDiKihUaJmZmUyaNIkZM2awatUqVq1aJTpv5UgqlYqRQaFSyvm9Ft8n5SOnFmHz5s3p2LEjhw8fVnVIgiAIAiIZFCqwlJQU+vXrx6+//sq2bdv4+OOPVR3SO0ckg0JlJZLB8qerq4unpyfDhg3Dw8ODDRs2qDokQRCEd57YTVSokKKjo/Hw8MDPz4+TJ0/Srl07VYf0ThLJoFBZiWRQNdTV1Vm/fj02NjaMHz+ex48f880336g6LEEQhHeWSAaFCufx48f06tULhUKBl5cXderUUXVI7yyRDAqVlUgGVefVWoSRkZFs2LBB1CIUBEFQAXEVFCqUy5cv4+zsjKGhId7e3iIRVDGRDAqVlUgGVW/s2LHs3buXnTt30rt3bxITE1UdkiAIwjtHXAWFCsPT05POnTvTtGlTTp06haWlpapDeueJ3USFykqUlqgY3N3dOXPmDDdu3MDFxUXUIhQEQShnIhkUKoRffvmFAQMGMGTIEA4fPoy+vr6qQxIQI4NC5fH48WNCQkKIjY0lNjaW6OhoAJKTk3Mfk8vlKo7y3dSqVSu8vb2Ji4vD2dmZhw8fqjokQRCEd4ZIBgWVUiqVLFiwgHHjxjF37lx+/fVXsW6kAhHJoFBZ9OvXDzs7O0xMTDAxMaF27doAeHh45D6mo6ODjo6OmK6oAg4ODpw/fx5jY2PatGmDl5eXqkMSBEF4J4hkUFCZ9PR0RowYwdKlS9myZQsLFixQdUjCK0QyKFQWQ4YMKXZ9oJqaGu7u7mJmgopYWlpy9uxZnJyc6N69u6hFKAiCUA5EMiioRFxcHD169ODgwYN4enoyYsQIVYckFEAkg0JlMXjwYJRKZZFtMjMzGTVqVDlFJBQkpxbh8OHD8fDwYP369aoOSRAEoVIT8/GEchcaGoqrqyuRkZGcP3+epk2bqjokoRAiGRQqC3t7e5o0acKtW7cKTQqNjIzo1q1bOUcmvEpNTY3169djb2/PRx99RGBgoKhFKAiCUEZEMiiUq7t37+Lq6oqBgQE+Pj5UrVpV1SEJRRC7iQqVyYgRI7h79y4ZGRn5npPJZIwaNQqZTKaCyISCzJo1CwsLC8aNG0dERAQbNmwQ/38EQRDeMDFNVCg3p06dol27dtSsWZOLFy+KRPAtIEYGhcpk0KBBhd7cUCgUDB8+vJwjEoozZswYDh8+zN69e0UtQkEQhDIgkkGhXGzZsoVevXrRrVs3jhw5gqGhoapDEkpAJINCZVKlShVatGiBRCLJ91y1atVo2bKlCqISitO9e3dOnTrFrVu3RC1CQRCEN0wkg0KZW7VqFaNHj2bChAns3LkTLS0tVYcklJBIBoXKZsSIEfkKzctkMsaOHVtgkihUDC1btsTb25v4+HicnJxELUJBEIQ3RCSDQpnJzMxkwoQJzJgxgzVr1rBq1apit3YXKhaRDAqVzaBBg/L9TisUCoYOHaqiiISSsre3x8vLC2tra1GLUBAE4Q0RG8gIZSI5OZkhQ4Zw+vRp9u/fT58+fVQdklCMxMTEfBtrKJVKkpOTCQsLQy6X5z5uZmaGgYFBeYcoCP+ZlZVVbiKRlZWFRCKhRYsW1KpVS9WhCSVgamrK8ePHGTx4MN27d2fHjh24ubmpOixBEIS3lhimEV7LtWvXUCgUBT4XERFBp06d8Pb25vjx4yIRfEvMnj0bExOTPP/8/f355ptvsLGxwcHBIfff3bt3VR2uILy24cOH504JVVNTY/To0aoNSCiVnFqEI0aMoG/fvqxbt67QthcuXCi2vqQgCMK7TCSDQqmlpaXRv39/Pvzww3wX2YCAANq3b09MTAxeXl60bdtWRVEKpTVixIgStbO2tsbZ2bmMoxGEstO/f//c/1YqlQwaNEiF0QivQ01NjXXr1rFkyRImTJjA7Nmz812Pzp49i4uLC3v27FFRlIIgCBWfSAaFUluzZg3BwcH88ccfLFiwIPdxHx8fnJ2dMTY2xtvbm9q1a6suSKHUnJ2dqV69epFtZDIZI0aMEBttCG81c3NzOnbsCEDPnj0xMzNTcUTC65o1axabN2/m+++/Z8yYMbkzVu7evYubmxsKhYKZM2eSnp6u4kgFQRAqJrFmUCiVmJgYFi1alLsBw6JFi7C0tMTa2prhw4fTvXt3tm3bho6OjoojFV7HqFGjWLp0aaFTgBUKBYMHDy7nqISyoFQqCQwMJDAwkNjY2HduKl2dOnU4ffo0tWvXZvfu3aoOp9xIpVKMjIyoUaMGNWrUqBQ3dkaPHo2trS39+/cnNDSUH3/8ke7du5OamopSqSQkJIQ1a9Ywffp0VYcqCIJQ4UiU71oPQPhPPv74Y9avX59noxGpVIqGhgYffPABq1atyrdtu/D2ePToEbVr1y40MahSpQpPnz4t56iENyUzM5PDhw+zbdt2jh77m4T4WFWHJKiQgaExvXr2YPjwYbi6ur71392XL1+md+/eSCQS4uLi8tzU0tfXJzAwEFNTUxVGKAiCUOHsFsmgUGIPHjygQYMGZGZm5nlcKpWirq7O2bNncXJyUlF0wpvi6OjIzZs38yWEGhoafPrpp3z11Vcqikz4Lw4ePMiUadMJCnyMSb02GDXphkHN5mhb1ECmZwSSd2/VQNS1I5g1d1V1GOVLmYUiKQ55ZCAJj64Rd+sEMX5eVKthz6qV3+Pu7q7qCF9beno6HTt2LHCDM5lMxqRJk1i5cqWKohMEQaiQRDIolJyrqysnT54scAqhuro6+vr6XL58mZo1a6ogOuFNWb16NdOnT8+X9APcvn2bRo0aqSAq4XU9evSICRMncerkCSyd+1HVYybaltVVHZZQgcgjnvD0wHIifA7QpWs31v3801v3Pa5UKhk5ciQ7d+7MVyInh7q6Ovfu3RNlRARBEF4SyaBQMmfOnKFLly5FtpHJZNjY2HDlyhXMzc3LKTLhTXv+/DnW1tb5kkF7e3sCAgJUFJXwOk6dOsV7/QciMbalxrCvMKzdStUhCRVY/MPLBG77AmVsCPv27sbFxUXVIZXYzJkzWblyZe569oKoq6vj5ubG/v37yzEyQRCECm33uzcvSCi1rKwsJk+eXOx6EoVCQVBQEAMGDCjygixUbObm5nTt2jXP/2+ZTMb777+vwqiE0tq4cSM9e/ZCp34nGs89JBJBoViGtVvReO4hdOp3omfPXmzcuFHVIZXI5s2bWbFiRbHtMjIy8PT05OLFi+UQlSAIwttBJINCsX7//Xf8/PwKnDYI2WsGJRIJJiYmzJ07l61btyKVil+tt9moUaPyJPQKhYKBAweqMCKhNLZv38748eOxdfuEOuPWIJVpqjok4S0hlWlSZ9wabN0+Yfz48Wzfvl3VIRXr/fff58SJE3h4eCCVSpHJZIW2VVNTY/Lkye/c7rmCIAiFEdNEhSIlJSVRo0YNoqOj8108ZTIZCoWC1q1bM2PGDPr27VvkRVh4e6SkpGBmZoZcLgegXr163Lt3T8VRCSVx9epV2nfoiHmnUdgPnq/qcIS32OMdC4k48zv/nDmNs7OzqsMpkYCAADZu3MiGDRuIi4tDKpXmu5EpkUjYvn27KJMjCIIgpokKxVm+fDlxcXG5iaBUKkUqlaKnp8eYMWO4e/cuPj4+DBw4UCSClYiOjg4DBgxAJpPlFpoXKr7o6Gh6ubqhX68d9oO+UHU4wlvOfvA8DBt0wN2jH9HR0aoOp0QcHBz45ptvCAsLY+fOnbRv3x7I3g05h0QiYcaMGaSlpakqTEEQhApDjAwKhQoJCcHBwYG0tLTcUcBWrVoxefJkBgwYgJaWlqpDFMrQ8ePH6dGjBwD+/v5v3e6C76KJkybx+469OC45h5q2vqrDKVJKeABP9nxDrN8FshRpaJlVwbxlH6r0moCalm6ZvrY8IpDAPUuJu+9FhjwRLbMqWLUbTNXek0pUYiMp6A6Be5eR4H+FzHQ5Wma2mDV3pZr7VNS09PK0TQy8ydO/fiQh4DqKpBi0TF609Sig7ZPbPNm3jAT/q2QpUtG2dsCu+/+waj/kjb7/0siUJ3J9TgfeH9qfn3/6SWVx/Be3bt1i7dq1bN26lbS0NLKyslAqlSxfvpyZM2eqOjxBEARVenO7iaalpeHr60tkZCSJiYlv4pSCiv3000+cPXsWTU1NOnXqRPfu3alSpUqh7fX19bG0tKR+/fpoar79a5SUSiWBgYEEBgYSGxv7zq0xycrKYty4cRgbG7N8+XJVh6MSmpqaGBsb06BBA0xMTFQdTpF8fX1p0qQptcauwLJtxV7fmRL6kOsLXdGr1ohao5aiZWZHzK3T3P91KkZ129Jo+tYye+30+EiufuGCXtUG1B79LRrG1sTcPsP9DR9j2WYAtUYtLfL4xMBb3PjKHbMWvbAfMAeZvglx97158MtUtC1r0OyLg7kJZfwDH24vH4Jp857YD5yLTNeImDtnuP/LNPSq1KfZF565baOuHcV3zf8wb9GbGgM+R8PIgrAzWwnYuRj7QXOp0mtCmX0mxYm4sIuHm2dw/do1mjRporI4ClPS/odcLuf8+fMcPXqUkJAQtLW1WbNmDfr6FfvGiVC8ytb/EIRy9N+SwdjYWLZs2cKevfvx9r5IZiG1fYR3i5q6Os7ObRnQvx+jRo3C2NhY1SGVWGZmJocPH2b7tm38/fcxYuPiVR2SUEHUrulAH4++jBkzhgYNGqg6nHz6uHtw0S+YxnP/AolE1eEU6e4P7xN79yxOK68j03+ZZAfsWMizY+tp+vk+DOs4lfq8aTGhhF/YReLjGzSc+nuBbfy3ziH8/A6cvr+GTO/ld1Pw4Z94vOdrWn59Fh3rwkfBby8fQrz/Zdqu8UWqoZ37+NO/fiRwz9I8sd9c4kFq9DNaL/NBov5yGv3jnYsJProWxy+PoF+jKQCXZ7UlS5FKq2XeSNVfTml8sGkGkT4HcF55DXVdo1J/ZMYw9wAAIABJREFUJm+EUsntJW60rVeFQwc9VRPDK3L7H/v24+0l+h9CNjV1dZzbtGXAe29f/0MQVGS3+usclZKSwrJly/h22XKyJFLMHHtS/3+r0K/eGE0TK9RfmfoivH0yUhJQ1zEo3TGpSaTFhJP45DaP75zhszlfMPvzOcz67FM+++wzdHR0yijaN+PgwYPMmDaVgMAntGtYg5l9W9Oyjh01rIwx1tdGWsE72GXhTmA4xvra2JkZqjoUlUhTZBKTmMK9oEjO333C/u2/s2LFCtz7uLHi+5UVZurss2fPOHLkMHU/+lllieDNr/uR+OQWbVbfyTfNM3DvNzw9tJoms/diVNcZ44YdMarfLk8iCKBfvTEA8udBJU4GlRkKom4cI/zcDmLunkXD0By7Hv8rtP3zS54Y1W2TJxEEMGvei8e7l/D8yl9Uc59a6PFpMaFoGJjnSQQBtC2q5YvdrKUbGgbmeRJBAB3b2gCkRgWjX6MpGcnxyCMCMW/lnicRBLBo5U74ue1E3zqJZZsBxXwaZUQiwbr7eI6sn8SzZ8+ws7NTTRzk7X8oJVKqObnSceoazBwao2tqjUy7dP2P9OQENHRLd60TKh6FPInk6DCiAm7z7PppZr1l/Q9BUKVSJ4P79+9n8idTiYqJparHDOxcRonkrxIqbSIIoK6lh7pNTXRtamLV5j0yUpN4dmoLS5d/z8ZfN7Nm9Q/069evDKL9bx49esSkiRM4cfIU/ds3YseMidhbVewpgeWlUQ0rVYegUpoyNaxN9LE20celmQNfjnDh1I1HfPnHGRo2aMC06dP58ssvVb5+1tPTE3VNHcya9VRZDJZtBxL/8BLRN09g4dQ3z3ORPp5omVfF6EWSZNt1bIHnSIsNA0DbvFqxr5cc7EfY+e1Eeu0lQ56ISaPONJyyGZPGXZBIC66JmhYTiiIpFh2b2vme07asjkRNRtKT20W+rq5dPaJvHidDnoC69svvSXnEk+zn/3Vuu+4FJ6XJT++BRIKubZ0Xj7yYoFNAHp8zGpj09B6WbYoMrUyZOfZCXUObgwcPMnHiRJXEsH//fiZPmUp0TCxNhnxK/V6jS538vUokgpWDTFsPI7taGNnVombH/ijkSdw7+hvffvc9v/y6mR8raP9DECqCEu8mqlQqmTNnDv379wf7Njgtu0j13hNFIigUSl1Lj+q9J+K87CIS+zb079+fOXPmVKi1d6dOnaJVyxaEBdzj8OL32TDFQySCQqEkEujqWJOzyz9g0agurF2zmi6dOxEZGanSuE6dPoNh3bb5RqDKk3krN6QyTZ5fzjuNMCHgGqnPg7BqO7DIUcv0hOc8+3sjunZ1MajVstB2iYG3uL6wF1fnuRBz8yR2PcbjtOIKDaf+jmnTboUmggDp8c8B8o1IAiCRItM1Ij3heZHvs5rHVKQyTe5v+IS0mDCUGQpi7vzDs7/XY97aHX37ZkW+x+Cjawk5uYlq7tNyk1J1XSO0LauT4H8FZYYizzHx/pcBUCREFRlXWZOoyzCs146Tp06X+2v/u/+hX6ctA9ddosl7H//nRFCovGTaejR572MGrruEft22FbL/IQgVRYlGBuVyOcNHjOTgoUPU/98P2LQfVNZxCZWIhqE59f+3EqO6ziz77lPuP3jIn39sRVtbu/iDy9DGjRuZNHEi7s71WDPJDU3Za82aFt5B6mpS/terJZ0a12DoN7tp3bIFfx05qrK1hDdu3UK3kYdKXjuHurYBps16EH39GJnyxNzdTCO994NEUuSmNhnJcfiuGkOmPJFG07YWmdAlPfUl8cltqrlPpXq/mSXa/TNHliIVAKlawUmzRF1GVpq8yHPo2tWjweRfuffzR/hMb577uFnzXtQZXfBGS/KIJ1yelT2sp6alS42Bc/KNGtoPno/v6rH4bZhMjQGzkembEHXtKKGns9c+KjMV+c5b3nSrNuDmrYPl+ppyuZwRL/ofHaespraL6nZWFd4+2kbmdJiyGquGbVj+3YwK0/8QhIqk2KtoVlYWw0eM5OiJ0zSbtUskgsJrs2k/iGazdnH0xGmGjxhJVlaWymLZvn0748ePZ/p7bdgwpa9IBIXXUsvWjONfj8ZKT41uXV0IDg5WSRwRYWFomtqq5LX/zbLtALIy0om6fgwAZVYmzy8fwqiOM1rmVQs8Rh75hOuL3UgJfUTDaVvQq9awyNfQq9YQA/tmBB38gcuz2/H0rx9Jj4soUXw56/yyCkmssjLSkWoW3UmM8NrD7e+GYdVhCK1XXKbDL0E0m/cXqZFBXFvYC0Vi/np82pbV6fhbKG1/8qPu/1YTcnwjNxa7kZH8coMqM8eeNJr+B/LwAK7M6cilmU7E3D5Dg0kbAfKVoVAFTRMbIiLCy+31cvofx06exnXxXpEICq+ttssQXBfv5e+Tqu9/CEJFU2wy+MUXX3Dw4EEafLwR4zqtyyMmoRIzrtOaRlN/49Chv5g3b55KYrh69SoffjCWiX2cmDW4Y0XfeFGo4Ez0tdk1ZzDGWhLc3XqTlJRU7jGkylNQ01D9BgkmDTshMzDj+eVDAMT5XSQ94TlW7Qq+iZjw6Co3FruhzFDQdO4BjOoWvyhOv3pjms37ixZLzmDatDvP/l6Pz4yW3F01muibJ1BmZRZ6rKaRJUCBCZsyM4OM5Dg0ja0LPV6ZmYH/ljkY1m6F/cC5aJnaIVGXYeDgSJ3/rUIe/pjgI2sLPV5d1xCz5r1oMOU3Ep/c5unhH/M8b9K4C80XnaDDL0G0/eke9Seuy51aq2VR/DrKsqamqYs8ufx+v3P6H11mbcKqQel3lxWEf7Nq4ETXuVs59Jfq+h+CUBEVmQzu27ePb775hrpjv8Okftvyikmo5Ixqt6LOmGUsXbqUffv2letrR0dH49bblQ4Nq7FwlEu5vrZQeelpa7Bt1kBCnj5h3P8K38myrCiVygI3HylvEjV1LJz6EnP3LBkpCUT67EdNSxezlm752iYEXOP2d0PRMquK4/zD6NrVLdVr6drWwWHoApxX3qDeRz+jzFBwd9UYLs1oSfDRghMyDSNLNAwtSAl5kO+5lDB/lJkZuaUeCpIa/YzM1CR0bGrle07HyiH3PABp0SE8+HU6ERd354/9xVrBlFD/Yt9nwqOrABjWalVs2zInodzWXOX0P9p//D02jduVy2sKlZ9V/da0m/idSvofglBRFTo3LiUlhclTpmHbYbCYGqpCKeGPebR7KTF+XmTKE9Eyq4JNh8FUd/sYSQnWyiQ8vkngodXEB9xAkRiNpoktli1dqdF3Wr7Nf5LDAni0eymx9y6QqUhD26wKlq37UN11Yr6t4ktz3oLYtB9E3H1vJk+ZRs+ePctt2+f58+cjyUxn/Sce72SpiIogICyGxX+e5qJvEIkpaVSxMGJY5yZM6demRP9Pbj0O4+vt/3DpfjDyNAVVzI1wc6rLzAHt0dPOuy3/o9BoFv95hvN3A0lNz6CqhRF9neszua8zulqv37YgVS2MWDPJjcFLtjNu/Hg6depUqs+lsrBqO5CQ478QffM4UdePYd7CDTXNvH/fqVHB3FkxHB0rB5rM2vWfpkBK1GWYt3TDvKUbaTFhhF/YQfwDn0KLtFs49yP01G8oEqOR6ZvmPh556WB2Mtu68LWXGoYWSNU1SH52P99zySHZj2mZZZddkOmbEnnJk6Snvli26Z9nbWNi0J3stv8a7QvY9iXRt07Q8uuzSHLWNCqzCPvnD3RsamFYxKY6lU1KSgqfTJlGHZchYmqoCsWHPubKlq8IvXOR9JQk9C2rUMdlCE0GfFKi/odSmYXvX7/id/R3EsID0dQ3plqrHrQePR8N3bzliqIe3eLKH0uJuH+FzPRUDG1r0sh9PHW6Dct33riQR1zZsoTQ2xfITE9Fz7Iq9m3dadL/Y2Sv9FUKUttlCOF3vfiknPsfglBRFfrX/O233xIVE4P9gNnlGU8eqTFhnBhpjTxKNetwVC09PpIri9zJSEmk9YIjdN74iNpD5xF4cDX3f59T7PGx9324stgDqboGLecfpOPPvtQa9DnBJzZz/dshKJUv58wnhzzk0rzuKBKiaPHFATr+dAf7fjN4cvhnbq8Z/9rnLUrNwXOJjo1j2bJlpftgXpOvry8b1q9n/rBO6Otolstrvio0OgGT/ot5GhmnktdXtci4JHrN2UxCShonvhlL0B+zWDjShe/3XuCzjUeLPf5GQBjdZ29CT1uTsyvGEfD7pywZ050/Tt2g38I/yPrXqMWDZ8/pNHMjUfHJHF78Pg83zWDWoA6s9vRi7Iq9ec5bmrZF6eZYkx4t6vDxxAlkvKNFsPWqNULXtg5BB74nIzkeywKmiD7aOpcsRRr1J214o2vhNE2sqeY+rdCC8wBV3T5Bpm/CvZ8/Qh7xhCxFGpGXPHl2dC3V+kzJs/Yy1vc8Z0fbELBjEQBqmjrY9ZpA/AMfAvcsJS0mlKx0OQkB13i4+VPUdQyw7ZY9MizV0MJhyHySgu7wYNNMUqOCyUqXE//Ah4ebZqCuY4Bdtw9yX8u4UWfkkU/x3zIHRVIs6fGRPNj8KcnP7lN7zHcqqx+pCjn9jxYj56oshuSoUDb0MScx8t3sf6TERuL5mSvpyYn0XXGcMbsCaT3mS27s+oGL60rWL7y4bjZX/1hKy5Gf8/6OALp+9guB3oc58uUQ+Nd39RPvw+yf3h2Zti7vrTzJ+9v8qe0yhHM/TuP2/p/ynDM2+AH7progj4+izzcHGfmHH82HfsrtfWs49e2HJX5/LUfPJzqu/PofglCRFTgyGBsby7Ll31HNY0buGgtViPXzUtlrVwSPD6wkIy2ZRpPW5hZINnfsib3HVPx3fU3V7h+ia1N40etHu79Gw8CUBuN/RPpiy3nL1u7EP75J0JG1JAbexsA+e0qU/84lKDMzaDJlU+6261ZOHiQ8vkHQ0fXE3vfBuK5Tqc9bFA0DM6r2mcK3y5YzZcoUjI2Niz3mv5jz+WyaONgwuGPjMn2dolzwDVLZa1cEy3efJyk1nV+mvYeJfvZGHa6t6jBzQHsW/XmK8b1bUcvWrNDjF/95GjU1KWsm9UFbM/t3r0eLWkxyd2bxn6fx8QumTf3sjUoWbj1NZlYWWz4biKlB9p3ffm0bcM0/lJ8P+eB17+lrtS3OV6O70mbqOnbs2MGIESNe74N6y1m2GcDj3Uvy1BbMkZUuJ/rWSQAufVrwOjCrDkOpM3ZFgc+FnNzMoz+KThL0qtSn+eKTBT4n0zOm2dyDPN6zlBtfuZEhT0THygGH4Yuw6TyquLdGjf6z0LGsQeg/fxBycjNZilQ0DMwwqteO+pM2oG1ZPbetTZf30TA059nxX7g6ryvKjHQ0TWwwcHCkmvs0tP5VT9GkUScaTP6V4MM/cmlmK5BIMazZgqZzPdGv0aTYuCqLnP5H0yGfomOiuv5H6J2LKnvtiuD6jhVkyJPp8tl6tF70Caq37kWzwdO5vOUrGvb5H0Z2+adL54h8cJV7RzbTYfJKqjv3BrLX7LUe/SW39/9MXMij3OMv/bYIHVMrOk9fi5osexZG474TiHv6gKt/fkudrsPQ1M/uH1z+bTHKzAy6z/kdLYPsuBza9+X5w+vcPrCWsLveWDd0Lvb9aRua0WTgtHLrfwhCRVZgMrhlyxayJFLsXIq/MOZIDPIlYN93xD30ITM1GU1jayxaumLvMS1PAfMb3w0nOewxjp/+ycPti4h74IMyKwu9KvWoPWwBhg7ZNZquLxtK9J1/ALgwrRVSdQ1cNgdxfdlQ5JFBNP5kI3fXTSYlLIAuvz5GIlUj7uEVHnuuJP7RNTLT5GgaWWDerDsO/T/NTaYArn7VF3lUME2n/c6DP+aTEHgLlEoMazan9vAF6FfN3h7+6pJ+JDy+RYc1t1B/sU16jsBDq3m0aymOn+3AtFHHEn9OpRHu44lJvTZ5YgewaOGK/84lRFz5C3uPqYUeb9myDxqGZrkJWw49u+xCx/Ko4NykzbRhB0zqt8tXf8ugenbiJH8elJsMlua8xbFzGUXQwZVs3bqVTz75pETHvI5nz55x+MgRfpnar8Q32O8EhvPtrnN433tKcmo61ib6uDnV5dOBHTD418jioCXbCQiNZtcXw5j/+wm8/Z6SmamkQXULvnq/O461bAAYsHgbp28GANB0wo9oytQI2zGHAYu38SQ8lt8+HcBHqw8QEBrNs22foyaVcOl+MN/tOc/VhyGkpKZjaaxPz5a1mD24U24yBdD7i995+jyOP2cPZu7m49x4FIoSaFnblq9Gd6dh9exOldu837kREMb9X6ehr513dHTlvoss/vM0e+cPp3MT+//waRdu/0Vf2jWsnid2ALfWdVj4xyk8vf2YOaB9oceHRCVgYaSXmwjmqGGV/TfyJCI2N2nr1MSe9o2q5yZ3OZo6WP+ntsVxsDbBtVVd1q9b+84mg1V6T6JK70kFPifV0Kbjb6GvfW7brmOw7TrmtY8H0DS1pd74NcW2M27QvsBYLdsNKnDEsyBmzV0xa+5asraOPTBz7FGitpXVli1bUEqk1O81usTHRD++y7Vtywi754NCnoyuqRU12rjhOHhGnqLyRxcMIT40gF4LduKz6UvCfX1QZmViUr0+Th8swqK2IwBHvhzEs+tnANj+gSNqMg0+2BfCkS8HkRD2hG6fb+bM9xOIDwlg7J6nSKRqhPtd5sbOFUTcv0ZGWgo6xpZUa9WD5sM/y02mAA7O7kNSRDDd523Fe+MXPH90E5RKLOq0wPnDxZjWyO5/HPrcnef+NxmxxRcNnbz9j5u7f+DyliW4LtqFXbPOr/lJF+3x+QNYN2qbJ3aAGs69ufz7Yh5fPITj4OmFHn//xDbUtXSo1Tnv30mdrkOp03Vo7s9pSXHEhz7Gvp1HbiKYw769B/dP/MnTqydyz2PbtBM2jdvnJoI5zGpm3zBJjAgqUTIIUL/XaG7uXFHm/Q9BqOgKTAb37NuPmWPPEheUTwi8xZWv+mLaoAMt5/+FlrEVMX5e3PtlOnEPLtFyXvZaDACJmgaKpBju/DwRh/6f0mjiz8ifP+XmyjHcWjWWdit8kMo0cfxsOw+3LyToyDrarbyMtlkVAKQyTTLTUniwZS4Wjj3QNLFGIpESc+8C15cNxaKFK60XHkXTyJKEwFvcWTuJ2Ac+tF54FKksu/MrUdckPSEa3w1TqTNiEQYOzZBHPOHGipFcWzqQtssuINM3wbbzSGLv+xDufQC7LiPzvOdwb0+0TG0xaVhwx1WRGMM/E4uvOdbm2/MFju6lRoeiSIpF17Z2vue0LasjUZORGHiryHNX7VnwRhaJT31BIkHPtk7uY1W6f1Bg29TY7G3Etf91B7s05y2OupYeZo492b1nX5l+GXt6eqKjpUmvViWL7UZAGL2/+I1Oje35e+kYrE30uXA3iE9+PoS331OOLRmDulr2LGsNdTWiE1IYt3Ifs4d0YuO09wiKiGXEt7sYsWwXN37+GE2ZOnvmDWPe7yf46aAPN9dOpqqFEQCaMjWS09KZ9csxXFvWwdpEH6lEwrk7Txiw+E/cWtfl5DdjsTLR50ZAGON+2I/Xvaec+vaD3JIYGjI1ouJT+HjNQb4e24PmNW0IDI9lyNc76LtgK5dWT8TUQIf3uznide8Ae8/7Mrq7Y573vO+CL3ZmhnRsXKPAzyQ6IYVaYwoerfm3S6snFDi6FxKVQEyinDp2+Z+rYW2CTE3KrYCwIs9dv5oFx648JCElLU9C/jgsBoC6dua5j41zLXiNVVhMIgDVLY1fq21JDOrQkJHLdhMREYGlpepGNwThbbNn336qObmWuKD8c/+bHJrdB9umHfFYfgRdU2vC7lzk7KophPv64L7sMNIX/Q81dQ1SE2I4/d14mg+bhcvM9SREBHF8ySiOL3mfoRuvoqahievCXfhsyh7BGvrrdfQtsvsfajJNMtJSuLh+NtVb90LHNLv/EXr7PEfmD6K6c2/6rfgbHVMrnvvf5PR3HxHm60W/FSdQ09DMPYc8IYqzP0zG+X9LsKjtSELYE44tGsbhue8xaJ03WgYm1OsxirC73gSc20e9nu/nec+Pzu1Hz9wO26YF34hOTYhhy/Dir3WD1noVOLqXFBVCamIMxlXzn8PApgZSdRlRj4ruf0Tcu4xZjYb5Erx8XkwXlRRwl1bzxY3w6EBfar3IeRv2KXgqaHJ09rVD37Lku+7KtPWo5uTK7r1l2/8QhIou35rB1NRUfLy8MG1U8rtND//8EpmuEY0/2YiutQNqWrqYN+tGzUFziA+4QcSlvEVqM1ISqOY6AbMmLqhp6qBnV5cqLu+TFhtO4tN7xbyahPTEaMwde+IwYBZ2XUaBRIL/jq+Q6RjScPxqdKzsUdPSxbheG2oNnktSsB/hPgdenkEqJUuRRvXeEzGu1wY1DW30qtSj1pB5KJJiCT2/CwDLVm7I9IwJPbc9TwTJoY9ICr6HTYchhS6ilumb0G1rWLH/CpvmmZ7wHAANPZN8z0kkUmR6RqTFRxXzWb1yzvjnBB1ZS/DxTdj3nVZgovlq+6d/b0TPri5GtQvfvKC0532VSaPO+Hh7kZaWVqrjSuPM6dO0b1gNDfXCi1n/2xebj2Osp83mmQOoaWOKrpYGPVrUYv6ILlz3D+WAV97f04SUND72cKabY010NGXUq2rB2B4tCI9JxPdJZJGvJZFIiE5IwbVVHeYM7cSYHs2RSGDh1pMY6Wqx9hMPHF7E0K5BNb4c0YV7QZHsveCbew41qZQ0RQaf9G1DuwbV0NaUUb+aBQtHuRCTKGfHP7cBcHeuj4m+Nn+cvpEnBv+QKHyDIhjepUmhm7iYGugQs3desf8Km+YZGZ+ce55XSSUSjPS1c9sU5tMB7dHSUGfC6gOERieQnpHJ6ZsB/HzIh35tG+SOwhbmeVwya/+6RL2qFrSuW+WNtX1Vp8Y1UJNK+Oeff0p1nCC8y1JTU/Hx9sLOsUuJj/H+dR6a+sZ0nb0JI9uayLR0qdqyO63en0fkw+s8vuCZp316cgKN+02iaouuqGvpYFKtHvV7jSElJpzoJ76FvEo2CRJS46Op3roXLUZ8nj16KZFw6bdFaOgZ0nnaTxjaOiDT0sWmUVtaj55HzBM/As7vf3kOqZTM9DSa9J+MTaO2qGtqY1K9Hq3HfElqYgwPT+0AoEZbd7T0TXhwYlueGOKe+RPz5B51ug4ttP+hZWDCuEPPi/1X2DRPeezz3PPk+wwkUjT1jJDHPS/ys0qMCELH1JqHp3eyb0oXfu1vx+9Da3H6u49Ijno52q6pb4yBdQ3C/S6TlZGe5xzh9y5lxxNXdF9HHvecO57rMalWD6v6pdt1165Z2fc/BKGiy/dN4ufnR0aGAv3qjUp0ggx5InEPr2BSvy1S9bx3gMwaZyeU8QE38h1n2rBDnp81jSwASCtB8WBlZgaWTi93fFMkx5MQeAvjem1yR/9ymDTIHrmLuZd//r9p47wJb075jMTg7I6+VF0Dm3YDiQ+4QdK/do8L99kPEgm2Hcpul7PM9FQAJOoF31WTqsvISpeX6FwpEYGcGGnN2Y8bE7B/BbUGz8XeY1qRxyiS4ri5cjQZKQk0/OhHJNL8SdTrnLcgBtUbkZGh4P79/Dv0vSm3b92kUfWSjdAkytO4dD+Y9g2roynL+75dmmZvH3/NPyTfcR0b551aaWmcfWc7LDax2NfMyMyiX9v6uT/HJaVyIyCMtg2r547+5ej04nUu3H2S7zxdXsSXo13D6gD4BmX/XWnK1BjcqTHX/UPxe/oySd173heJBIZ1Kdn03teRmp5d6LuwhFxDXQ15WsHFwHPUr2bBls8GcuXBMxqOW4XV4K8ZsHgbbepX44cJvYs8NjZJzrBvdpKQnMraTzxQkxY+X7g0bQuirSmjlp0Fd+7cKdVxgvAu8/PzI0OhwMy+ZP2P9JREIu5dxqZxu3wjUFWaZyeUkQ+u5TvOtmne/kfO2sSUmPBiXzMrMwOH9n1zf05LiuO5/01sGrXNHf3LfZ0m2SN3obcv5DuPnWPe/kdO+YyYJ9n9DzWZBrW6DCLy4XVigvxy2z06uw8kkjxTLd+0nP7Hq326HGrqGmSkpRR6vDIrk4z0VEJvn+fhye10mraGUX8+wGXWRsL9LrN/Rg/Sk+Nz2zuNXUByVCinV0wkIewJ6ckJPDy1g3tHNwOQlVn4dSEtMZa/vxpJekoCnab/VGBfpShmDo3JUJRt/0MQKrp800TDwrKH2rVMir7DniMtNgKlMouwi3sJu1jwrnupMXk7zhKpWr51cEiz81JlZgl24JNIcpPH7BiyYy5osxsNQ/MXbfJ+yUvUZPlikOlmT9tLj395x8u280iCjm0g9Ox2ag9fCECEjyemDTrkbiFeFtQ0stdUKV+5U5YjS5GOVEO7wOdepWNZg25bw1AkxxPr58X9LXMI9zmA46xdyF7Z3hlAHvmE68uHk54QRbMZW9Gv1vCNnLcwmibZ67LCwsJo0qRsNkoIDQvDzqz4absA4TGJZCmV7Dp3h13nCu7Mh0Ql5PlZTSrJtw4uZ4QtM7P43VUlErA0frkuJCwm+/xWxvmnSpkbZW+dHRadN8mUqUnzxWCsl/1zZNzLEbfR3RxZe+gSf5y+yZLR3QHYd9GXjo3tqWJe8v9vpaWtkb3OLz2j4KLg6YrMfGsBX7Xz7G0++ekQE92dGNujBZbGetwJDGfausN0+exXji4ZjVkBI4+B4bEMWrKd53FJ7Jg7lMY1rAp9jdK0LYq1iV7u96kgCMXL+XvRNbctpmW2lJhwlMos/M/sxv9M/nqOAElRedd8SqRq+dbB5YywZWUW/N30SuM8G9vkTE/UMc7f/9A2Ns/TJodUXZYvBk297P5HStzLm3T1eo7ijuc6HpzYhvOHi4HstXx2TTqiZ1G62Qqloa6Zfd14daQuR6YiDXXNwssxSCRSJBIp6SmJdJvzW+57s2vaifaPoELeAAAgAElEQVQTv+PogsHcPrCWFsOzdyWt7uRKrwU7uLzlK3ZNbItMWxfbJh3oNnsTeyZ3LHTKcELYE44uHII87jk9528r8U2Ef9M1y+7rlmX/QxAqunzJYHJydqfx1bpQxbHtNJz6H3z3ZqIqhkQiLfDuj5ICiuHmbl+c985+QfPTeXG8RPpywFTXpibGdZ0Iu7iXWkPmkfTsPslhAdi/N/N1wy+RnGQ3PTE6f5SZGSiS4zA2KV0nVaZriEWLXmiZ2nJpfg+eHPqRWkO+yNMmzv8KN1eORl1Tl5bzPNErQSHokpy3KOqa2clNYmLxI2ivK0Weik4xicarRnZtxqoJ+YtllwWpRFLg6FNBBZ4L+ZVGWtDxBTxXy9aMNvWrsvvsHRaO7Mq9p5E8Co1m9uCy2QgpR05iGxWf/45yRmYWsUlynE0K36QlIzOLTzcexaleVb4c4ZL7ePNatvz0sTsdZ27kxwNeLBzVNc9xlx88Y/g3O9HV0uDoktHUq2rx6qlfq21xdDVlJCUlvfbxgvCuyel/yErZ/6jbfQQdJq8si5DyKaz/QVH9D0kJ+h+5a+de9j+M7Gph3dAZ/39203rMl8QE+REX8ojmwz573fBLJCfZTY3P3//IyswgLSkOXdMi+h8SCVqGpmjqGeUmgjmsG7UBiYSogLw3Wqs0d6FKc5c8j+WMiBpY5V8HGOF3hb+/GoFMSxf3b//CpFq9Er23V+XUJSzL/ocgVHT5kkFlIV9ehdF6sYFLatSzNxpYaWiZ2IBEkm/0DyDtxV02LdO8I51ZGelkpCTk2elUkRQLgIaBeZ62dp1HcmftJKLvniPm3gVkekZYtCh6d7j/uoGMprEVGoYWJD17kO+55FB/lJkZRe7YmRodwuP9KzCu64x1u4F5ntN7saYvOfRhnsfjH13j+rKh6NrUotmMrWgY5F/79TrnLdaL37WCEp83RalUFnIDID8bUwOkEgnBz+OLb1xGbM0MkUggLCZ/MhHxYtqpnVneUbw0RWa+jVViE7MTLwvDvIV4R3dvzrgf9vPPrcecu/sEYz1tercuOvH/rxvIWJnoY2Gkx/3g/GtNHj6LIiMzC8eahc9ICH4eT5I8ndoFbECT83oPQ/KuLbn6MIT+i/6ktp0ZO+YMwdyw8ILEpWlbEhJJ2f5OC0JlU9r+h66ZDRKJlKRI1fU/9MxsQSIhOTp//yMlJuJFm7zfa5mKdNKTE/LsdJqamN3/0DbK2/+o1/N9Tn/3ESE3zxJy6zya+sa5pRoK8183kNExsULH2IKYp/mnTsYF+5OVmYF5rWZFntvMoTGRD6/ne1yZmQFKZfEby5Cd8AFY1c9bgibywVWOzB+IUZXa9PxyG9qGhZcjKlY59D8EoaIrcDfR0lDT0sWoTmti/LxIj49Ew/DlnfTYB5fw2/QpDT/6EYPXqJOUe4esmD9SdR0DjGq2INbPi6z0VKQaWrnPRd/J3h7atFGnfMdF3z2HZauXIz856wqN6+XdltiilRuyrV8Q5rWXWD8vrNr0L3QufY6cDWT+C+s2/Qg++RvpidFo6JvmPh5+yROJmjpWTn0LPVZD35Rw7wMkBt3Fqm3/PHcbE55k35HTtqie+5g8Kpjry4eha+1A8893F7qTbGnP+zbS1dLAuX5VLt59QmRcEhZGLz8Lb7+nTFt3mLWf9KXZi7IDpZEzdbS4y46BjiYta9tx0fcJqekZaGm8/FPNKU/RpWn+8g//3HqMu/PLO6TnX6wrbNMg753VPk71MNE/xq5zd7jgG8TADg3zrY98Vc4GMv/FgPYN+fXYVaISUvJM59x/0Rd1NSnvtSv8BoqlsR6aMrU8ax1z5DxW1fzlXeinkXEM/GobtWxN8VwwEj3twv9mS9NWEEpDHhFI4J6lxN33IkOeiJZZFazaDaZq70lQyAYgr1JmKHiwaQYRXnuwHzyPKr0mFNguKegOgXuXkeB/hcx0OVpmtpg1d6Wa+1TUSrg7+NtEpqWLVQMnQu9eJCU2Eh3jl/2PcF8fzv00g87TfsK8VunXQpe0/6Gha4Bl3RaE3fEiIz0V9X/1P4JvZPc/CtoQ59nNs9i37ZP7c+id7HWFNo3a5mlXo00ftPTn4H9mN6F3LlKrU/9iE6mcDWT+i5od++N7ZBOp8dFoGb7sfwSc349UTR2HDv2KOf49gq+d4tnNf7Br2in38Zz1k1b1W+c+5v3LFwRdPs6gny/mlqxSKrPw+3sLRlVqY1Xv5aYwiZHBHPlyCIZ2NXFbsq/Eu84KglC4kl2JilFryBdIpFJurBhJcugjshRpxPp54btuMlKZRommGhZE0zh7GkJ8wHWyFGlFriesNWQemalJ+G6civz5UzJTk4nxPcej3d9iVLslli3z3kmTamjx+MBKou+eJTNdTlLwPfx3foWGoQWWrd3ztlXXwKb9ICK8D5AWG45tx7JbuP1vNdynoKFvwp0140mJCCRLkUa4zwGCDq/F3mMqWqYv11XE+J7jxEhrHm5fmPv+ag/7koQnd/D7dSbyqGAy0+XE3vfh3q/TUdcxoOq/yknc/30OWYo0Gk/eWGRJkdKe9221YKQLUqmUIV/vwD8kijRFBhd8g5iw2hNNmTr1q5oXf5ICWJtm3wm+9jCENEUGGUWsJ1w4qitJ8nQmrTlIUGQcyanpnL0dyFfb/qF13Sr0cco7LUZLQ53lu8/zz63HyNMU+AZFsGDrKSyM9OjXpn6etpoyNYZ0asK+C76ExyQywqXou7xvyvT+7TA10OGDFXt5HB5DmiKDfRd8WXPQmxkD2ucZ7Tx7OxCT/ouZ9/sJAHQ0ZXzs7ozXvacs/vM0IVEJyNMUXH0YwtR1hzHU1WK828tOw2e/HCM1PYPNMwcUm9yVpq1QcmkxYZwdbUNqVLCqQ1GJ9PhIbnzlTkZKAo7zD9NunT/2g+bx9K/V+G+dW6JzZCTHc/u7ocgjnxTZLjHwFtcXuaGmrUvzRcdp+5MvDkMXEn5uO7eXDwFl8WuX30atR89HIpVybNEw4p75k5meRuidi5z5fiJqMo3Xnj6oa5p9sy/ywTUy09PIKqL/0XrMAtLlSZz9YTKJEU9RpCYTcvMsV7d+jVW9VtRok3e5gbqGFtd3fMezm/+QkSYn5sk9Lm9ehI6xBfbtPPK0VZNpUNtlMAHn9pMSE06dbuVTu7TpoKloGZhyctmHJIQFkpmeRsC5/dze/xPNBk9Hz/zlngkhN8+yoY85Ppu+zH2sZsf+WDdswz8rJxPu60NGmpzQ2xe4uP5zDKxrULf7y/dRxdGFxPAgLqybRWpiDCmxkZz/cTqxQX7Z03//NVJ8cd0sMhWpdJu9SSSCgvCG/OeRQQBDB0dazj/E4/3fc2VxHzLkSWgammPp5EGNPlPy7fBZUtZtBxJ55TB3132CurYeTl+dKLStUe2WtJi7n4B9y/H5ohuZaXK0TG2xaT8I+77Tcusc5pCqa9Bg3A/4b19I/OObkJWFYa2W1B31Ve7mLf9m23kkQUfXY1C9UW5R+rIm0zOm5fxDPNr1NZcXupEpT0THyoE6Ixdnl9Qohp3L+2gYmvP07434zHEhKyMdLVNbDB2aYd93OtoW2aNFmelyom6eBODC9NYFnsu24zDqf7iiVOd9mzWvZcuxr0ezfPd5es75jUR5WnZS1bY+0/u3y7fDZ0kN7tiIQ95+TFh9AH0dTf75ruCajQCt61bhr8Xvs3THP3ScsQF5mgI7c0OGdm7MpwM75NY5zKGhrsaaj/sw//eTXH8USpZSSas6dnz7Qc8CN2YZ3d2Rnw/50MTeOrcofVkz0dfm2NejWfznGXp8vpnElDQcbEz5ekwPxvRoXuzxc4d1xt7GhN+PX2fj0SukpmdgbqhLh0Y12DSjP/ZW2ZsyyNMUHL/mD0CzCT8WeK4RLs1YPdGtVG2F0om776XqEFQq6OAPZKYlU2/C2twNy8wce1Ctz1Qe7/ka224foGNdcHkhyE4Ebyxxx7xlH0wad+bG4j6Ftg3csxSJmhp1P1iZu7mYadNu2PX8iMA9S4l/eBnDOk6FHv+2sqjTHI9lR7i+/Ts8P+uNIiURbWMLHNr3pdnAqfl2+CypWp0H8tjrEGdWTkJDW5/3Vp0qtK1VvVa4f+PJ1T+XsXdKZzLS5OiZ21LbZQiOg2fk1jnMIZVp0Gnqj/hs+pLnD2+gVGZhWa8Vbcd9nbt5y7/V7TmK2wfWYubQOLcofVnT0jfBY9lhLm9ZwoGZPUlPScLI1gHn/y3JLqlRDIlUjV4LdnB9x3ec/n4iKTHhaBmYULVld1qOnJMnkbNz7Ey3ub9xc/cqto91RCKVYlmvJe7fHs4zqpuRJufplex+4PYPC75e1O02nA6f/PDf3rwgvGMkylcmSu/atYvBgwf/5ymOFdn1ZUOJ879Cl42PSnxM0rP7eH/emfofrsC24//ZO8/oKIsuAD/b0xupEAgkBEKvoXdRkd6bgIgNC0XxQ6SJgKIUEVQElCI2qjSpNqSEJJQAgfRKIL33zW52vx9LNiy7gQQSEHifc3IOO3Nn5s4m7M5955bxNajd08kfE93YsWMHo0ePrpH5RSIRm2eNYOgdN2RPCiOX/EJAWAIJP39Q6TGh11Pp+u4G1r418KHdDD5NvLxqD/I6zdi5c2eNryUSiWj61nqcOgy+t3AF5F+/Rvy+lWSHB1CqLEBh76ZzMRwyE6l5eWxT8BcTKEqOocWsn4ne/jE5EQFoNRqs6jbBa+xHWHvq/paCV40nM/iEfpxYKqf793EErxpPUWocTd/5nrAN0yhKjqbbxmhEYgk5kee4fuBLcqMvUKosQm7nTK3Wz1F/2PsG2Z8vfTqM4vQEms/YSvSvH5EXexmtVouNVzu8xi/Cqq7u//mlZcPJi71MlzWXkJiXZ+sFuP77V8TuXkbL93/FvnnNJE/ye6cZ1p5taPHeTwbtRckxBM7pRv3hs/EYPLPC8YVJUeSE++PWawK50RcIWjKoQjfRcx/2QKNS0nFlgEF7WuABQtZNpfGrq3HtNuaB9lM2V03FV5WdPx7UxfG/zOGPRpMSEsjLu+IqPSYzPpTd7/Sgx/Qv8Xn2xZpT7ill4yCnGj1/CAj8x9lVLTeDjyVV/DKLO7QOua0zbl1G1JBCAgIPRlUPaF/tP4uznRWjelQ9HbfAk0Ve7GUuLRuGfdPutFlwEIWdK9lhfoRvnkVORABt5u3Xe1eIpTJUeZmErn+L+sPep8nUdRSnXefa2ilcXTuFjiv8EcsUtJj1C9HbF3Pj6Ho6rgzAzFGXCl8klVOqLCLqx3k4tn0eub0rIpGY7NDTXFk5Hsd2/Wm78DByOxfy4i4Tuv5tcsL9afvRYb2XiVgmR5WXQfj3M/F6cTE2nm0oSo0jePUkrnw+Ct9lp5BZO1C71wRCw/1J9d+HW++JBntODdiHolYd7G/Vor0TVV4mftNMl9W5Hd9lJ03e7ikzE1HlZ2FRu5FRn7lLfUQSGflxV+46t4Vbw7veHN6OpXsTMi4dR12Ua2C8F6XE6fpN6CHwaDCZ+fwuXPntGyzsnfHuObKGNBIQEHiaqZaYwScVraaU0pIi4o9uJOn0LnwmLb1vl1cBgf8CpRotRUoV3x4MYPuJK3z+yvP37fIq8OQQ/esiZJZ2NH3nOyxcvZCYWVKr9bN4jppLXkwQaecOGsiri3Kp2+9NHFo+g0RhgaW7D7X7TKIkO4WChJC7riUSiVDlZeDY9nnqD59N7d6TQCQiZucnSC1s8XltDeaunrrkZD5d8Bw9j4IboaQG7CufQyxBo1JSd8Db2Pl0QSw3x9K9CV6jF6DKzyLljO421tF3IDIre5JObTfQoTApioKEUFy7j60wiYvM2oGeWxPv+VORsVZWr1Z2Rz25WxtAZmlHSW713YB5DJmJWKYgbON0lJlJaNUqMoNPcOPYBpw6Dtbf2Ao8Hmg1paiVRQTvX0/E3zvo8vqy+3Z5FRAQELgbgjF4F1L89/PPqw25fmQ9zad+jUuHiuM1BAQeB/aeuUbdFz/nm4P+rJ8xlCFPqNusQOUpLcojJ/Icdk26GmVJdmjRG4DcaOMU8XZ33KjJ7XRxp8rslHuuqS1V49ShPFGGuiCHvNjLOsPujgdu9k1162SHGscf2jfvZahTky4A5Cfo6pOJpXJcuo4iLyaIghvlafJT/feBSIRr9wdzm7wbGlWxTgeJ6fqmIqkMjbKo2tazdG9Cs2mbyI26gP977Tj5qgfBq8Zj27gTjSevqLZ1BB4O0af2sWVUfa7s+5be763Ds9v9u4ALCAgI3I2n8kqg7exfKyXn2mU4rl2G17A2AgIPzu4FlYtjHdm9OSO739v1TeDpQZmdAloNKX57SPHbY1omM9HgtUgsMYjhu9UIcNesz+WyIuR25WUAlFm6GPXb28qQ2+oy95ZkGcaxiyQyIx2klrrSIqrbbtzcek3gxrGNJJ/ajte4RQCkBezHvml3zGq5U1OUJXHRlKpM9mvUJYhNJAu5X1L8dhO+aRbu/V6ndp+XUNi6kBcfTOTW2Vz4+AXazNuP7LYSRQKPhv4fVy6GuGHPETTsKYSlCAgI1DxPpTEoICAgIGCIW8/xNHp55UNZSyQSIxKbqGtpIu61okLkIpOFyctky51eLNwaYtu4Eyl+e/AcPZ+CG2EUJkfjMez9+1W/Uihu3ZSq8jKMtSxVoy7IRmFfPdk9taVqIrfNxbZRBzxHlZessPFqS+PX1nBh4bMkHP4WzzHzq2U9AQEBAYEnB8EYrCQXl48jOyKQPt9HP2pVBASqjZFLfsE/9Do3fpnzqFUReEQo7N1AJKY4/caj06FWbRCJKDHhYlqSnaqTcaht0K5RlxglS1HlZwEgtzGsA1q790RC179N1rWTZIeeQWpph2O7F+6q04MmkJHbuSC3dabwZrhRX2FSJNpSNdYNql4M3RTFGTcoLc7Hora3UZ+Fq5d+TYHHk8MfjSY5JIApu+IftSoCAgJPIIIx+BSQGxdM9O7PyY48R6myCHNHd5zb96fB0JkGBebjDq0jcvuSCufpuzXBqF6jgMDDRqlS4zZ22V1lJvZtw5o3TdcFzC8qoft7G4hPzebM6jdoUs/YNfFpQmJmiV3jjmSHnaUkJxW5bfn7kRMRQMTW2fi8thbrBq2qPLeo7IbuHplupeY22Hi1IzvMD01JMWK5mb4v6+oJABya9zYal3X1JE6+5b/nsrhCWx/DGzfH9gOQWc0nxW8P2WF+uHQebhQfeSdlCWQeBOfOw0j8ayuqvAwDF83UgAOIJFKcOw65y+jKI7d1RiyVG8RFllFwU9dm5lhzLrECAndSWqJk04i7/835PDdBV1T+FjmJMZzbtpTE4DOUFOZj7VKXxs+MpdXI6eWfJQICAtWOcLJ/wsmNvUzgx4Nw8e1Pp6V/ILN2ICv0LNc2ziAr7Cy+Hx3Uf8iqC3MB6L0hHKmFzd2mFRB4ZChkUjL3LDDZdzgwnAmf72R414oLM8/dcpz41OyaUu+xpMGoeVz+bARXV0/C542vMXOsS270BcK/fxephQ2W7j73Na/C3hWA3Jgg5HYupl1Db+E5ZgGXPx9J2KaZeI6ci8y6FrnRF4nd8zm23r44tu9vIC+WmxF/YDVSCxtsvX0pSokjZudS5LbOON9Rb1EslePSbTQ3jn0HWg2uD6lWbL2B0/W1+RpNXoHCwY30i0e5ceRbPAbNQFGrjl4269oprqwYg3u/qXiNXVildSQKC9xfeJPrB9cQu3sZtfu8hMzKnvyEECJ/mIPUwoY6z75W3dsTEKgQiVxRYb3IuIAjHF86Ca/uQ/VthVmp7J/dH8cGLRi66jiWtdxIuPgX/6x8k/z0RLq9ufxhqS4g8NQhGINPOFE7lyGSSGj62moktxIaOLV5Fo/+U4nauYzs8EDsbz1FVxfmALqDhYDA40ZBcQkfbDrKsK7N6NmygUmZ4xci+emvIAZ1asJB/9CHrOF/FxuvtrSZf4D4/V8QtHQwpcX5yG2dcOowBI9B0++7pI5L15GknT9E2MbpSM2taPfx8Qplbb19af3hb8TtXcmFhc9RWlKEWa06uHQbhcfgd428EsQSOT6vfkn09sXkxV5Cq9Fg692ehi8u1SdvuR23XhO4cXQDVh4t9EXpaxqZlT1t5h0gZvcygpYORF2Uh4WrF14vLtaV1LgHZXUabydmxxJidug8OJw7D6fJG18D0GDEB1i4NCDxxE/c/HMLGlUxchtH7Jp0o+nbGzF3qV/t+xMQqCqq4gL81n+IV/eh1GndU99+cfsq1EUF9Jm9AbNb5Vjqd3yBNmPeI3DbUpoPeg07d2M3aAEBgQfnoRmDqvxsYvZ/QdrF4yizkpGaWWHj2QrPYe9j62VY/ygz5DSxB9aSGx2ERqPG3NEdt64j8ej/poFrT9DKFylIiqH1zE2E/biA3JhLiCRSnNo8i8/kz0i/9BdxB7+iIDkaha0z9fq9Rr3nXtWPP790KEXpCbR+9wfCf1pIbuxl0GqxbdiORi8uwrpexbcLAHnx14j+bSXZEf6UFhegsHfD2bc/nkPeNbhZq8req5vizJsobJz0hmAZFs71AShKi9cbg6rCXMRyM8EVtApk5RexctcpjpyLICkzD2tzOa0b1mbO6J609TaMcToZHMfqPae5EHUTdamGuk52jOnZgrcHd0YhK78xGf3Jr0QnZrBt9ig+3HSMi1GJyKQSnm/nzcrX+/PHxUhW/3aGqMQMXOysmDqwI28M6KAfP2D+D1xPy+bnOWOYt+U4QVGJaAHfRnVYOvk5mtd3ueuegmOT+XznSc6GXKeguAQ3B2sGdvLhf6N6YGNRbhRUZe8Pg0+3nyCnoJhPJj9rsj8zr4jp635nWNdmdGvmIRiDd2Dl0YJm07fcU64iGeeOQ4zcHqWWdrSeu7dS4wFsvNrR8v3KZXvWakux8mhBqw92VU5ercvqWeeZyZWSry4UteroDba7Yd+su5FbqtfYhVW6JXTpNhqXbqOrrOOTjjIvi4s7VhEfcJSCzGRk5lY4NWxNu/GzcW7U1kA28copgnZ+SWrERbSlaqyc6+LdezQth72FRFZ+/jiyaCw5idE8N/cH/DbOJTUyCLFEhkeH5+j25nKun/+TS7u+JOdmNOb2zrQYMpXmg8pvZw/MGUR+SgLPLfiRs9/NJy3qEmi1ODduT+dXl1Crwd3PHxkxV7nwy3KSQvxRFRVgWcuVBl0G0nbMLOSW5eePquz9YXD+p89QFuTQ+VXDkJSYU/twa9FVbwiW0aDzAAJ/WELMmYO0HfPew1RVQOCp4aGd+oO/mUr+zXBaTf8Oa48WKLNTiPjlYy58NopOS45j4eoJQHZEIBeXj8O5fX+6LD+F1MKG1AtHubr+HUpyM2g8YbF+TpFEjio/k9Ctc2g0fhFWdRqT8NcPRG5fQnFGImKZglYzNyOztCNs21zCf1yArVdbbL10H4AiqYKS3AyubZxJ4wmLsfFqQ1FKHEGrJnJh2Si6Lj9tumAwOvfLc0uHUqtZD3wX/o6ZvSuZoX6EfP8e2eEB+C44oDeqKrv3O1HlZXLirbt/IQB0+fwUlrVNFz62cm9CWtBx1IW5BgZqYUosAJa1G+nb1AU5BjGEAvfmlS9+Izwhja3vj6SlpyvJWfks/OEPhiz6kRMrXsWrti5OyD80gZFLfmZgRx8C176FjaUZhwLCmLp2H+k5BXw65Xn9nHKphIzcQt7feISlk5/Fp64Tm49d4KNtf3IzIxeFTMqPH4zGztKMD74/yoebj9G+UR3aeetczuQyCek5hbzz9QE+nfI87RrWJjY5i7Gfbmfooh8JWPsWtWxM3/4GRScxYP5WerX05Niyl3FzsOb01XimrzvI2dDrHP3kZaQScZX2ficZuYV4v7zqnu9twNo38a7jWKnfQ0JaDt8fPsfM4V1xdbA2KTNr42FKNRo+f7UfB88KhuBjzz3iEO8k4ci3OhfSzkK5oKeNv5a/TlZCOH3nbMLRsyWFWSn4b/6IQ/OGM/zLv7Cto0uykxwSwOGFo6nfeQBj1p9FbmFDnP9h/v7iLYpy0ujy2if6OSVSOcW5mZxe9z86vbIYew8fQg5vIWDLx+Sn3UQiV/DcvG0orGw5s+FD/DbOxblRW5wbt9ONlykoyk3n3y+n0fm1T3Bu1JbcpDiOLh7PoXnDGb3+LGY2ps8faZGXODhnEHVa92TIisNY1nIjKfgM/66ZQfI1fwYvP4T41vmjsnu/k+LcTLa92Pie7+3ob/0qfWOXn5rAtUObaD1yOhYOruXt6TcpzsvEvp7xeja1GyCWykiPulypNQQEBKrOQ4nI1aiUZF47hWOrZ7Bt2B6xTIG5Uz2avf4lYqmcjCv/6GVTLxxFLFPQaNxCFPauSBQWuHUZjr1PZxJP7TCaW12YS4NB07H1aovEzBKPfq8jMbMkO/I8zV7/EnOnekgtbKg/8B1Ad+tYhkgsRqNSUn/AW9g36YJEbo5V3SZ4j12AKj+LxFMV1wOK+PkjZJZ2tJz+HZZuXkjMLHFq8ywNR88lJzqIlIADVd77ncisHXj2x6R7/lRkCAJ4Dn0XsUzB1Q3TKc5MQqNWkRF8gvgjG3DtNMTgZlJdmItIIiX6txX4zenJX1Pqc3Jaa8J+mIsqX4ixuhOlSs3JK7H0bdsQ38buKGRSPJzt+PqdwShkEv66FKOXPXwuHIVMyuKX+uLqYI2FQsaoHi3o2tSDX/4x/pLLLVTy7vCutPOug6WZnDcHdsTSTE5gWALfvDMYD2c7bC3NmDFMV2T7ZHCcfqxELEapUjN9aBe6NfPAXCGjqYczH096hsy8IrafuFLhnuZvOY69lTlb3h9Jw9q1sDST83x7bxZO6MPFyET2+YVUee93UsvGgsw9C+75U1lDEGDl7lMo5FLeHGg6Vf+uk8Hs9wth+av9cKzAEBZ48tBqStGUFHHj2EZSzuyi4YQl9+3yKvB4Ulqi5Oblkxt7tO4AACAASURBVNRt9wwuPr5I5AqsXerRc8ZaJDIFCRfLv4Pj/I8gkSnoNGURFg6uSM0saNhrJLWbdyHir+1Gc5cU5NJ61EycG7dDZmZJiyFTkZlZkhJ2jl4zvsLapR5yS1tajZgG6G4dyxCJxZSWKGk1Yhq1W3RFqjDHoX4TOr78EcV5mSbXK+PspgUorO3pO2czdnUaIjOzpJ7vc3R4aQGpEReJOb2/ynu/EzMbB14/mHbPn6q4bl7c8QUSmYIWQ6YatBdlpenXvBORSIzCyo6ibNPxhwICAg/OQ7kZFEllyGwcSb1wBMdWz+DUpi8iiQypuTW9vg0xkG00biGNxhm7xZg71SMr1A9VQQ4yS1uDPrtG5S5yIokUmaUdYplCX+cJbitcbOIDpVZLwyx1Dk27ApCXEGIkC6AuyiM74hyuXYYZZaRzvDVXTnQQrl2GV2nvNYFV3Sa0mrGZ4K/f4NSMcpcQ5/Yv0GTKCgNZrVaDRl2CRGFB+w93IZaZkXH1JGE/fEj6lb/p9Mmfws3hbcikEhxtLTkcGM6zbRvyfPtGyCRirM0VRG01rGG2eFJfFk/qazSHh4s9p6/Fk51fjJ2VmUFfpyb19P+WSsTYW5mjkElwsS//HTjZ6f6dmp1vNHef1oZPfLs1rw/AtXjj9P0AeUVKAsISGNm9uYHbKsAzt+a6EHmTkd2bV2nvNc2N9By2/3OZaUO7GL2HAEmZeXyw6SgDOjRm2F0Sywg8eaQFHiB0wzQU9i74vP4VTr6DHrVKAg8ZsUyGuZ0jcf6Hqde+L/V8n0MslSG3sGbSL4ZlPzpNWUSnKYuM5rB2qUdi8BmU+dkorOwM+lybdixfSyJFYW2PRCbHwqH8/GFhp8vQW5iVajS3e1vD80ftlt0AyIwzfT4oKcwjJSSQhr1GGLitAtRt1weA1PALNOw5okp7r2ny024Q8fcOWg1/2+g9LC0pBqgww69EKketLKxxHQUEnlYejjEoEtNm1jaC173F5TVTkMjNsfVuj2PL3tTuMQ7ZbR8MGpWShD+3knruEIWp8agLstBqNGg1pbcESg3nFkuMM1+KRMgsDT9sROgKFGvvHC+RIbOyN2grG1uSY/pJlDIrBa1WQ9KZPSSd2WNSpjjzZpX3XhMkndnNte/ew+OFN6j7zEvI7VzIiw8mdPNsAhb2w3fhAeS3Up53+Oh3o/EuHQYiEou5vOYV4n7/moYjhXp0ZYhFIn6dO5bXv9zLpOW7MFfI6NDInWfaePHiM62xtyqP01Sq1Gw6ep4DZ0OJS8kmO7+IUo2GUo3O1a1UozGYWyIWGcTnga7mtp2VYexnWdntO8fLJGIcrA1ly/RJzS4wuZ/kzDw0Wi07Twaz82SwSZmb6blV3ntNs/3EFdQaDZP6mo6/nfbNQQBWvdHfZL/A40eLWb9USs650zCcOw2rYW0E/suIRGKeX/Azf6+ayvFPJyNVmOPi40vddn1o3Hc8Cuvy7//SEiXXDm8m1u8gecnxFOdlo9WU6s8N2js+Z0ViiUF83q0FDeYsazM1XiyVGcXIlRlKhdnGhiNAYWYyWq2GyH92EfmP6XjZ/PTEKu+9pon4eyeaUjU+zxsnTpIqdN8XGnWJybGlKiVSIbGdgECN8dBiBm0atKLr8tNkR54j48o/pAefIOLXxcQeXEu7Obuw9tAV973y9RukBR3Ha9gsmncdoa+fFLplNjf/rVxigaogEolMtOoO6CLx3b1o6/R6kaavrLznGpXde3WjLVUTtvVD7Bt3wHvMPH27rVdbmr2+Bv/5fYk/tA7vsabT9JdRq2VvEInIiQqqET0fZ9p4uRG49i0CwhL4+1I0f12KZuG2P1n92xn2LppAywa6uIgpq/Zw9HwEs0f3ZHSPFrjYWyGXSnh3/SF+/vtSteslFhv/XWvv0nc7d6vRdzuV3XtNc+BsKG0a1qaes/GDlZ//vsTfl6LZPGsEznbCrbaAwNOIk3drxnx7luTQQG5c/JuEi//gv3kRQbvWMGDpHhw9WwDw5/JXiQ88Rrtx/8O71ygs7J0Ry+Sc+mYW4X9U7gFEVTB5/rgVC3uvunp31uiriMruvaaJPXMAZ+82WDvXNeoru0Utzskw6tOUqlHmZ2NZ6+F8nwgIPI083LSRIhF2jTpg16gDXiM/ICfqPOeWDiP6t1W0fncLyqxk0i4ew7XTUDyHzTIYWpR+o0ZU0qhLjJKrqPKzAJDbOJkcY+bghkgkprgqOt1j76Z40AQyxRk3UBfnY1nb2Kff0k3n9leQGAmARq0i/0YYUjNLo4Q2GlUJaLVI5EKsjSlEIujUpC6dmtRl7rhenAu/wYAFP7B850l++mA0yZl5HDkXwfBuzfhgdA+DsTfScmpEJ6WqlNxCpWH2zzydm42zraXJMbVr2SAWiUiogk732rspqjOBTFxKFlfjUnh3eFeT/dfidC6xU1btYcoq41v8ru9uACB15zx9YhyBx4vgVePJiQik24aoR62KwH8ZkQjXph1xbdqR9hM+JCXsHAfnDObiLyt4bv42CjOTiQ84ilePYbQb9z+DofmpNXP+KFWVUFKQa3C7WJynO3+Y25k+f1g61kYkEldNp3vs3RTVmUAmNzmejNhrtB4102S/hYMrFvbOZF4PM+rLTohEU6rGybtmM68LCDzNPBRjMCvsLMHr3qLN+z8ZlGuwbdgehZ0zqvxMoNxF4M4MngWJkWSFnQVAS9UyyFWGjKsncelQfhOSGXIGAPsmnU3KS8wssWvckcxQP0pyUpHbOuv7ssIDCN38P5pP/QqbBq0qvXdTlCWQuV/KblXzbxh/wJa1mTnqntJp1ErOLRmMrWcb2s/7zUA2/fJfANg37XbfujyJnLkWz+tf7mXHvHEG5Rp8G7vjYm9F5i3jS6nWuRjVsjZ0c4m4kc6ZkHiAGvirhhOXYxjcuYn+9amrcQB0aeZhUt7STE7npvU4czWO1Ox8g5u0s6HXeXf9Ib6dPpQ2Xm6V3rspyhLIVAcBYQkAtKjgFvLTKc8bZGotY8uxC8zaeJgzq9+gST1nEyMFBB4OWrWK8M2zSPHbjeeYBdR94U2TcvnxwcTuWU5u5DldDUbHOji264/H4JlI7hLLXVqcz/kFfSlOu077pX9j6e5TU1v5T5J01Y+/V06l30e/GpRrcPHxxcLeheI83XdwqUp3/jCzMcyCnJ0QQdJVP92LKmawrQw3Lv2LZ9fyWNbEYF2Su9otTD/gkplZ4tqsE4lXz1CYlYqFffnnV/I1f05+M4ve736Dk3frSu/dFGUJZKqDlNAAABw9K/aCathzBNcOb6Y4JwMz2/LfQfSpvYglUrx6CO7eAgI1xUN5FG7j2RqRRMq1DTPIib6IRqVElZ9N/JENFGckUqfXeADMHN0xd/Yg9fxh8m+EoVEpSb/8F5fXTMGlg+7DMjfmklHc34MglpsRs281GVf/pbSkiPyEECJ3LEVu64xLx8EVjvMeOx+RWEzQqokUJEahUSnJCvXj2vppiGVyrG594VZ27zWBRGGBx4A3yQrzJ2rnMoozEiktKSIn6gIhm99HamFDved1dRelZlZ4Df8fWWFnCf95IcWZSagLc0kJOED4TwuwrtcM9z4Ta0zXx5G2DWsjlYh566v9XIi8iVKlJiu/iHUH/bmZnsuEZ3RPMus62VLfxZ7fA8IIvZ6KUqXmj4tRTFy+iyGddcWvg6IS9fGD1YGZXMqKXac4cTmGIqWKa/EpLPrxL5ztrBjWpeKC24smPoNYLGbsp9uJvJmOUqXm9LV43ly7H4VMStN6TlXae00TdVPnVuTh8vBiXwQEqgt1QQ5XVo6jKDXurnJ5sZe5uHggEnNL2i0+TtdvruE17mOST/7KlRVjQaupcGzULx9RnHa9mjV/fHDyboNIIuXE6rdJDb9AaYkSZV4WV/Z9S376TXyemwCAlbM7Nq4exJ09RGZ8KKUlSq6f/5Pjn07Gs6vuLJAaGVSt5w+p3IyL21dy49IJ1MoiMuNCCNyyGAt7Zzy7DalwXMfJCxGJxRxdPJ7sG5GUlihJDD7DP1/oaiE6eDSp0t5rmuwbult7axfTDyIBWo+eiZlNLf5c/iq5SbGUliiJPrmXK3u/oc2Y97Bycn8ougoIPI08lJtBidwc3/n7idm7kitfvUZJThoSc2ss3RrS8p0NeqNLJBLTasYmwn9cQODHAxGJJdh5t6flOxuQKCzJiw/m0urJ1B/4drUlMhFL5TR7/Usif/2YnJhLoNFg6+2Lz6SlRoXab8fWqy2+Cw8Ss/cLzi0ZhLooH4WtEy6dhtBg0Ax9+vLK7r2maDhyDhYuntz85ycS/thMqaoYuY0jDk270fKdjVi4NNDL1h/wFuZO9bh+7Dv85/eltCgPM8e6uPeaQP3B0+76fjyNmCtkHF46mc92/MvklbtJyy7A2kKBd51abJ41gqG3jC6xSKQrIL/5GM99uAWpRIxvY3c2zxqOpZmcK7HJvPjZDmYM7cK88b3vsWrlkEslfP3OIBb+8CcXoxLRaLV0aOzO56/0w1whq3BcO+86HP10Mit2naLf3K3kFSl1BmTXprw3ohsKmbRKe69psgt0WehszE1noRMQ+K+iLsgh6JPBOPkOwqFlb4KWVJzpNHb3MkQSCT6vrEZ863O4Vutnce83ldjdy8iJCMS2sXFZlYzLf5J88lec2g8g7fyhGtvLfxmpwpzBnx/kwi/L+fOzVyjMTkNuYYWduzd9P/heb3SJRGKevVVAfv/7LyCSSHHxaU/fD75HamZJekwwx5dOpNWIafhOnFstuollcnrN/Ar/zR+RFhGEVqvBpUkHur7+qT6piimcG7djyPLDXPx1JftnD0BVmIe5vTNe3YfSZtRMfUhHZfde0yjzdaEHcgvTNWABzKwdGLL8EIHbPmHf+/0oKczHro4XnV/7hKYvTH4oegoIPK2ItFpDv4edO3cyZsyYB3JPfFy4uHwc2ZHn6POdEGvyqPljohs7duxg9GjTcWYPikgkeqhGyqNk5JJfCAhLIOHnDx61Kk81L6/ag7xOM3burLheaXUhEolo+tZ6nDpU/eGSuiCb+P2rSQ86Tkl2MhIzK6wbtKL+0FlYexre8GaHnub6wbW3PDTUmNVyx6XLSNxfmGqQFj74iwkUJcfQbNomon5eQF7sJUQSKbVaP4v3pGVkXv6b67+vpTAlBrmtM+7PvUadZ1/Rj7/06TCK0xNoPmMr0b9+RF7sZbRaLTZe7fAavwiruuX/j03FDOZfv0b8vpVkhwdQqixAYe+mc6kcMhOpeXl8VlX2Xt0UJkWRE+6PW68J5EZfIGjJoArdRM992AONSknHlQEG7WmBBwhZN5XGr67GtdsYgz5Vfhbn5/XG1qcTdj5diPxhzgO7iZatp60Bd0koP39Ul3vif5nDH40mJSSQl3fFPWpVnno2DnKq0fOHgMB/nF0PN4HMf5Ea+lITEHiU1NRhTeDJI2TdVAoTI2j69ndYeTSnJDuF6O2Lubx8NO0WHcP8VkKpnIhArqwcj2O7/nT47BQSc2syLh4ldOM0SvLSaTh+sX5OsVSGKi+TyG1z8Bz7EZZ1GpP4zw/E7FiKMjMRsUxBs+mbkVraEfXTPKJ+XoC1ZxtsvHS1UMUyOaq8DMK/n4nXi4ux8WxDUWocwasnceXzUfguO2UUW15GXuxlLi0bhn3T7rRZcBCFnSvZYX6Eb55FTkQAbebtRySRVmnvd6LKy8Rv2r2zQPsuO4mFm3FyLwALt4YV9t2JpXsTMi4dR12Ua2DMFqXE6fprNzIaE/nDHLQaNd4TPnlqbwX/69REDgQBAQGBqiKkzxMQEBB4StGolGSFnMahZR9sGrZDLFNg5lQPn1dXI5bKybx6Qi+bEXQMsUyB15gFyO1ckCgscO48HLvGnUk5ZXz7qS7Kpe7Aadh4tUViZon7c68jMbMkJ/I8jV9ZjZlTPaQWNtTt/zYA2aFn9GNFYgkalZK6A97GzqcLYrk5lu5N8Bq9AFV+FilnKr5tjf51ETJLO5q+8x0Wrl5IzCyp1fpZPEfNJS8miLRzB6u89zuRWTvQc2viPX8qa+zdC48hMxHLFIRtnI4yMwmtWkVm8AluHNuAU8fBRreYqWd/I+3cQbwnfIrMulYFswoICAgICDzs0hICAgICAv8ZxFIZchtH0i8exaHlM9Rq3ReRRIbE3JouX18zkPUcswDPMcZZYM2c6pId5oe6IAeppa1Bn22jDvp/iyRSpJZ2iKVy5HblGWjltrqkRCU5xkW27Zv3Mnht16QLAPkJoSb3U1qUR07kOVw6DzNwWwVwaKGLx82Nvohzp2FV2vujxtK9Cc2mbSJk3VT832unb3ds9wKNJ68wkFVmJRP50zwc2/bDqYZj0gUEBAQEHn+eamOw7ezqL2IvIPCo2b2g5jLUCjxhiMQ0n/kDoRve5tpXryCWm2PbsB32LXrj1mMcUks7vahGpSTxr62knT9Ecdp1VAVZoNHosyvemWVRJJYYuDQCiBAhs7oz86vo1njDjJgiicxItkwfVa7pmDJldgpoNaT47SHFz7iuJIAyM7HKe3/UpPjtJnzTLNz7vU7tPi+hsHUhLz6YyK2zufDxC7SZt19/Axix+T0AvF/67FGqLHAP+n9c87HEAgICApXhqTYGBQQEBJ52rBu0osOyU+REniPr6gkyg08Qs2MJ13//ilazd2LloYuNC1n3BhmX/qD+kPdw7jJCX8c0Yutskk9tr3a9RCKRidZbMVaiu0c4uPUcT6OXV95zjcru/VGiLVUTuW0uto064Dlqnr7dxqstjV9bw4WFz5Jw+Fs8x8wn+dR2MoNP0PSt9Qb1bwUEBAQEBCrisTQGLy4fR3ZEIH2+j37UqlSZq9++TZJfeVH3bqsDMb9V+P2/jt/sbhQk6d5zmZU9vb4NecQaPZ6MXPIL/qHXufFL9ZRHeZi8sWYfu04G619f+nYa9Zz/Ozco1UWHaeuIStTVMHSwNidq6/uPWKMaRiTCtlEHbBt1oP7w2eRGXeDSsmHE719Fs+lbKMlOISPoOM4dh+AxdJbBUGXGjRpRSaMuMUqYosrPAkBu42RyjMLeDURiitOroNM99m6K6kggU1mKM25QWpyPRW1voz4LVy8ACpMiAchP0H0mh6ybCuumGsmfn98HgB6bruuT6AiY5vBHo0kOCWDKrvhHrUqV+XvVm0Sd2K1/PW7TRaydH49zRlXYObUz2Td1WYTNrB2Y9Ev4I9ZIQODxRPg2eASIpXKe2VL+BRN3aB2R25dUKN93a8J9fXHnxgUTvftzsiPPUaoswtzRHef2/WkwdCZSMysD2cLkGKJ2LSMz1E9fX7B2jzHUH/gOoltP4bssPw3ApdUvkx0RYLSewNOBQiYhaXt5na2v9p/lo21/ViifunMeUom4yrJVpURdyox1v7Pj3yssntSXd4Z0Nil3KTqJT7efIDAsAaVKTcPajkwd2IEX+7TWywR+9RYAEz7fiX/ok1uwOzvsLGEb3qb5ez8ZlGuwadgOua2z3vjSqJQARhk8CxMjyQ73v/Wq+jMjZl09iZPvwHJ9Q/0AsPUxrqkHIDGzxK5xR7LDzlKSk2pwO5YTEUDE1tn4vLYW6watKr13U5QlkHkYlN3AFtwIM+oruKlrM3PUFeRuOH6xQVbXMhL/2VYtpSUEHh8kMjmv/HbTqF2jLuHfte8S+c9OOk1ZRMthb5scnxYZRNCuNaSGX6A4NxMrp9o06DyQtmNnITO3Mjnmblz+7WsCtnxcYf+r+5IQS6SUlijZNOLuBeZ9nptAj2mrGb3+LADHl04iOUQ4kwgI3C+CMfgfQF2YC0DvDeFILWzuIV05cmMvE/jxIFx8+9Np6R/IrB3ICj3LtY0zyAo7i+9HB/VGXklOKucWD8baozkdFx1G4eBGxpW/Cf72HYozEmkyWYg9EaiYnFuF32O3/Q9bS7Nqk60K2fnFTFq+kxJ16V3lfg8IY/KK3Qzq3IS/V7yKq701W49fYMa638nKK6rQgHxSsfFsjUgsJXzjdLwnL8eqXjM0JUUkn9qBMjOR+sP/B+iMDTMnD9IvHMGt10TMXRqQHXqa6F8/xsl3IKn++8iLvYR9816IxJJq0U0sNyP+wGqkFjbYevtSlBJHzM6lyG2dcb5LPcUGo+Zx+bMRXF09CZ83vsbMsS650RcI//5dpBY2emOosnt/1EgUFri/8CbXD64hdvcyavd5CZmVPfkJIUT+MAephQ11nn3tUasp8BigzM/mj08nU6ouuatc0tWzHF44kvqd+jNkxWEUVnbcuPg3J76cRtI1f4asOKQ/P1SWkgJd4fnJ26OQ35Fo6nYkckWFdSbjAo5wfOkkvLoPrdLaAgICd0cwBv8DqAt1H5IShUW1zRm1cxkiiYSmr61GIjcHwKnNs3j0n0rUzmVkhwdif+vpesy+1aiVBbR4+1t9wgantv3wHDKTyJ2fUu+5V7GsXT0p0gWePMoMPEsz+T0kqyZbWbLzi+k3bwtDOzelb9uGPPfh5gplP/7xL1wdrFk/fSgKmc5oeWtQJ8IS0lm2419efKY19lbm1abbfx2x3JzW8/YRt3clId+8TkluGlJzayzcGhoWsReJaTZ9E9E/LyBo6SBEYgk2DdvT9K0NSMwsyI+/ytU1L1O3/9s0GPFB9egmkePz6pdEb19MXuwltBoNtt7tafjiUsTyin9HNl5taTP/APH7vyBo6WBKi/OR2zrh1GEIHoOmI5Ypqrb3GiJ6+2JuHF1v0BazYwkxO3ReIs6dh9Pkja8BaDDiAyxcGpB44idu/rkFjaoYuY0jdk260fTtjZi71K9RXQUef5T52eyfPQDProOp1/4Z9r3/QoWy57YtxczWkd7vfaPPyuvZbQipEUFc2fsN6VGXcfJuU+F40+vrHnpLzSzvS39VcQF+6z/Eq/tQ6rTueV9zCAgImKZGjcHzS4eSE3uZXt9cRXLHB0DUrs+IPbCG9vN+w95H9zQ+M+Q0sQfWkhsdhEajxtzRHbeuI/Ho/6ZRmvDbObdkMIUpcfT8+opBe8IfmwnbNo/2c/dgfyslOUBe/DWif1tJdoQ/pcUFKOzdcPbtj+eQd6vtZq4qqApzEcvNqjWGozjzJgobJ70hWIaFc30AitLi9cZgsv9+HJp0Mcrc59y+P5E7PiHl3O94DplZbbo9LgyY/wNB0YlEbpllZLws/eUfvthzmoOLJ9G1mQcAJ4PjWL3nNBeibqIu1VDXyY4xPVvw9uDOesPDFC/M20pMcibhm94zaP/uyDk++P4oBxZPotutNQCCY5P5fOdJzoZcp6C4BDcHawZ28uF/o3pgY6GoxnegcuQUFGMml1bKvbMqspUlLSefNwd25KVn23I+wtgtqozs/GKikzIZ2qWp0e9jWNem/PRXEMcvRDKmZ8tq0+1xQOFQm8avfHFPOau6TWk1x3SGTt9lJw1eVxRr13FVoFFbRS6XWm0pVh4taPXBrrvq1WLWL8a6erSoUIfbqezeawKvsQvxGruw0vIu3Ubj0m30fa1Vu/ckaveedF9j/+scmDOI9MhLTPw5DNkd54xzP35C0M4vGbRsP27NdWeAxCunCNr5JakRF9GWqrFyrot379G0HPYWElnF54wDsweQkxTLxB8NY+Wv/f49ZzZ8yMBP91G7RVd9e0bMVS78spykEH9URQVY1nKlQZeBtB0zC7nlwz9nFGWn0WLwGzTpN4nU8PN3lW3QdTDm9k7G5Vk8dLfqeSkJVTYGSwpykMrNEN/nOef8T5+hLMih86sVh9QICAjcHzVqDLp1G0VWeABpQcdx7TzMoC/Zfx/mTvWwb6wzSLIjArm4fBzO7fvTZfkppBY2pF44ytX171CSm0HjCcZxEPdDbuxlzi0dSq1mPfBd+Dtm9q5khvoR8v17ZIcH4LvgQIVGmSovkxNvNbvnGl0+P1WlmzR1QY5RDN+DYuXehLSg46gLcw0M3MKUWAAsazcCoDgjEVV+FpZ1GhnNYe5SH5FERl7s5WrV7XFhbK+WnA29ztHzEYzoZpgs4rfT1/BwtqNLU52R5h+awMglPzOwow+Ba9/CxtKMQwFhTF27j/ScAj6d8ny16BQUncSA+Vvp1dKTY8texs3BmtNX45m+7qBO109ertDQysgtxPvlVfdcI2Dtm3jXcay0TjkFxVibV84IrYpsZfGu41gpfbW3YtpMZam0u3UbeDUuhTHCQ+f/Btrqj0EUePJo1GcMydf8iQ88RsMeww36ok/uxdqlHm7NdA+ck0MCOLxwNPU7D2DM+rPILWyI8z/M31+8RVFOGl1e+6RadEqLvMTBOYOo07onQ1YcxrKWG0nBZ/h3zQySr/kzePmhCo2i4txMtr3Y+J5rjP7WDzt346RCFWHn7l1p+RZD3jDZnhF7FUQi7D3urd+dlBTk3FesIUB+agLXDm2i9cjpWDi43tccAgICFVOjxqBLh0GEbZtHsv8BA2MwJ+oCRanxeA1/H24dzFIvHEUsU9Bo3EIU9rr/7G5dhnPzxM8kntpRbcZgxM8fIbO0o+X07/RPvZzaPEvD0XMJ+f49UgIO4NpluMmxMmsHnv0xqVr0uB11YS4iiZTo31aQEvg7RanxyCztcG7fH68Rs5FZVT1bo+fQd8m4+i9XN0zH56VlyG0cyQo9Q/yRDbh2GoKtl+6pXsmtel1yKwejOUQiMTIrO5Q56Q+2wceUIV2aMvv7o+w9E2JgDJ6PuElcShYfjOlZ9ufL4XPhKGRSFr/UF1cHawBG9WjBj38G8cs/l6vNGJy/5Tj2VuZseX+k/nbr+fbeLJzQh2nfHGSfXwgju5vOcljLxoLMPcZFwx+UnIJipBIxn23/l/1nQ4lLycLOyoxBnXz4cGwvA7fLqshWN/ZW5ni6OhAQlkCJuhS5tPx2sCxJTHpOYY2tLyAgUP14dh3MmQ1ziDm5z8AYTA0/T25yPO3Gz9afKrSGxgAAIABJREFUM+L8jyCRKeg0ZZHeqGjYayRhx38i4q/t1WYMnt20AIW1PX3nbNbfNtbzfY4OLy3g37UziDm9n4Y9R5gca2bjUGHM3KOiKDuNyH92cvXg97QdMwv7ulU3BpUFOYilMs7//DmxZw6SmxKHwsqOBp0H0v7FD1BY31l/tJyLO75AIlPQYohxhlwBAYEHp/p8tUwgtbDBqe3zZFz5G3VRnr496exeEIlw6zZK39Zo3EL6fBeFWa06BnOYO9VDXZiL6lbw8YOgLsojO+IcDk27Grk/OLbsDUBOdNADr1NVtFoNGnUJEoUF7T/cRc+vr9B44lJSAg8S8FE/1MX5VZ7Tqm4TWs3YTE7keU7NaMtfL9fj4vJx2Pt0osmUFXq50hJdDJeoAjdcsVSGpqTo/jb2mGNjoeAF30b8FRRFXpFS3777VDAike7msIzFk/qS8PMHuDsaBsZ7uNiTW6gkO7/4gfXJK1ISEJZA9+b1jdwcn2mtSzF/IbJiN8maQqPVUqIuxcJMxv6PJxC++T0+f6Uf+/1CeWb2JvKLSu5Ltib4+KW+JGbkMnXNPmKTs8gtVPLLP5fZfOwCAKrSuyegERAQ+G8ht7TBo0M/Ei7+RUlh+Tkj6t89IBLRqM8YfVunKYt4eVccVk6G2SqtXepRUpCLMj/7gfUpKcwjJSSQ2i27Gbmd1m2nK+2RGn7hgdd5GOQmxbJxkBM/TmzKhV9W0HHyAtqOnXXvgSbQarSUqpTIzCwY8MlvTNwWQpfXlxFzej9733sWVZHpc05+2g0i/t5B80GvoriPB+MCAgL3psYTyNTuNoqUgAOkXTiKW7dRaDWlpAQcwN6nM+ZO9fRyGpWShD+3knruEIWp8agLstBqNGg1tw5nmgc/pCmzUtBqNSSd2UPSGdOxL8WZD/8w3eGj343aXDoMRCQWc3nNK8T9/jUNR1atJl3Smd1c++49PF54g7rPvITczoW8+GBCN88mYGE/fBceQG5dSx9TqK0gu5hGVXLXZA1POmN7tWSfXwiHAsIZ26slpRote/1C6NrUA4/b6uspVWo2HT3PgbOhxKVkk51fRKlGQ6lG5+pWqtE8sC7JmXlotFp2ngxm5221/m7nZnruA69TVY4vm2LUNrhzE0QiES+t2MWavWeYN753lWVrggEdGrNz3jiW/PIPnWd8i6WZnJ4tG7D1/RF0f28jVtXswipwf5iKAxQQqIhGfcYQc3o/cf6HadRnDFpNKdGn9lO7eResXcrPGaUlSq4d3kys30HykuMpzstGqynVnzO01fA5XZiZjFarIfKfXUT+YzreNT/94ZQleVBs3Brw+sE0lPnZJAWf4cyGD4k6uZcBS3ZX2TAbuvKIUZtn10GIRCL+WPYyl3avxXfiXCOZiL93oilV4/P8kxnzKiDwX6DGjcFaLXoht3EkOeAAbt1GkRlympKcNLzHzDeQu/L1G6QFHcdr2Cyadx2hr60UumU2N//9tVp1qtPrRZq+srJa56wJarXsDSIROVFVu63UlqoJ2/oh9o074D1mnr7d1qstzV5fg//8vsQfWof32AUo7HR1uEryMkzOoyrIxv4p9tHv09oLJ1tL9vmFMLZXS04Fx5KWXcCiic8YyE1ZtYej5yOYPbono3u0wMXeCrlUwrvrD/Hz35eqVaeJfduw5s2B9xZ8xPRt44VIBOcrcVtZFdkH1qttQ/q2NYzpDb2eCkB9F+HJs4DA44Z7296Y2zoSc3o/jfqM4eaVUxRlp9FxsmGCnj+Xv0p84DHajfsf3r1GYWHvjFgm59Q3swj/o3ofQJTVwnsSUFjZUb/zAKyc3Pnt3b5c2r3W6L29X+q2ewZEIlIjLprsjz1zAGfvNlg7162W9QQEBIypcWNQJJHi2nkYCX9uRV2YS/LZfUjMLHHpUH6YVWYlk3bxGK6dhuI5zNAFoSj9xr3XEEvKbxBvoyTH0O/ezMENkUhMcSXmNEVNJJDRqFXk3whDamaJhaunYZ+qBLRaJPKq3VYUZ9xAXZyPZW3jYHFLN507YUFiJAAKe1fkts7k3wg3ki1IjERbqsbGs7VR39OCVCJmRLdmbDp6npyCYvacvoalmZwhncuLVCdn5nHkXATDuzXjg9E9DMbfSLu3e7NELEKjMU6WkZZdYPC6di0bxCIRCZWY0xQ1kUCmRF1K6PVUrMwVeLkZxp0qVaVotWAml1ZZ9mETGK77TOjkU+8ekgIVEbxqPDkRgXTbEPWoVakyoRveIfXsb/rXHVcGYOb45B0+z83pTmFyNAAyK3u6fH3tEWtUPYglUrx6Difk8BZKCnKI/vc3ZGaWeHYtLw9SmJlMfMBRvHoMo904wxqS+amVOGdITJ8zirINzxmWjrURicSVmtMUNZVAprLkp93gwq8rcGvexcDFFsCunk6vrOvG54W7oVGXkBkfhszcCtvahuecUpVSd86RGZ9zcpPjyYi9RutRT182cwGBh8lDOXm5dRvF9WPfkRZ0nLQLR3DxHWhQU09zy0VRZm14QCxIjCQr7CxQngnQFHIbJ9ThgWhUSn0NKYCMa6cN5CRmltg17khmqB8lOanIbZ31fVnhAYRu/h/Np36FTYNWJtepiQQyGrWSc0sGY+vZhvbzfjPoS7/8FwD2TbtVac6yW9X8G2FGfWVttx903LrojPWSvAzk1rX07ckB+3XGfKenu8DrmF4tWX8okKPnIzgUGMaQzk2wUMj0/cpbhc5rWRvWiYy4kc6ZkHiAu/z1gpOdFf6hCShVahSy8v+S/wbHGshZmsnp3LQeZ67GkZqdj7NdeWa2s6HXeXf9Ib6dPpQ2Xm4m16mJBDIlqlJemLeVdt51OLjY0I3nj4u6Bw49mjeosmxNMW/LcY6dj+Ts2jeR3cq6qtFq+eGPizRyd6Sjz5NnAAhUDrFUTvfv4/SvE46sI2bH0grle2y6ft/lgLRqFeGbZ5HitxvPMQuo+8KbBv0alZJTr939/4Jbz/E0erncwyUv7gpxvy0nN/I8GlUx5m5euD/3Gq7dx+plfD87BcC1tS+TE2Fc5uNxplGfMVw9sJH4wGPE+R+hQddBSM3KP5NLVbpzhplNLYNx2QkRJF310724SwZbczsnkq8FUFqiNHhAe/PyKQM5mZklrs06kXj1DIVZqVjYl58zkq/5c/KbWfR+9xucvE0/ZH3UCWTMbB2JPrmXjJirePceZVBcPj1aV77Lxq1+leYsVZVwYPYAnBq1ZdCy/QZ9Cef/BKBOq+5G41JCAwBw9DSdFE1AQKB6qNEEMmXY1G+BVZ3GRP+2ClVBDrV7GD5tMnN0x9zZg9Tzh8m/EYZGpST98l9cXjMFlw6DAMiNuWTyqRyAY6s+aLUaoveuQl2YS0lOKhG/LEJdZBw/5T12PiKxmKBVEylIjEKjUpIV6se19dMQy+RYuftU/xtwF6RmVngN/x9ZYWcJ/3khxZlJqAtzSQk4QPhPC7Cu1wz3PhP18tkRgfwx0Y2wH4x968uQKCzwGPAmWWH+RO1cRnFGIqUlReREXSBk8/tILWyo9/yrevkGg2cgt3Yg+Os3KEyJRaNSkuy/j/hD3+I5ZKZRUp+njVaebvjUdWL5zpNk5xczrrfhw4K6TrbUd7Hn94AwQq+nolSp+eNiFBOX79LfIAZFJerjB++kbxsvNFotn+84SW6hktTsfOZv/YPcAqWR7KKJzyAWixn76XYib6ajVKk5fS2eN9fuRyGT0rSeU/W/AXfBylzOh2N7ceZaPPO2HCcxI5fcQiX7/EKYu+U4zeu7MPm5tlWWBV25DocRS5j9vXGsyf3yTBsv4lKy+N93R8jMKyI1O5+Z3x4i9Hoqa94ciImqEwJPKepC3fdH13Vh9NyaaPRzv4aguiCHKyvHUZQaV6GMWKYwuWbPrYn6+olOHYbo5dMvHOHix/2RKCxpu+goXb4JwbXraMI3v0/CkW/vS8/HDUevltjX8+HCrytQ5mfTuO84g34rZ3dsXD2IO3uIzPhQSkuUXD//J8c/nay/QUyNDKrwnFG3XV+0Wg0Xfl1BSUEuhVmp+G9aSEmB8Tmj4+SFiMRiji4eT/aNSEpLlCQGn+GfL3S1DB08mlT/G1BNSOVmdJryMenRVzj51bvkpSagVhaRdPUsJ9fORG5pS/NBr+vlk0MC2DjIiTPrK85rIDO3ot2LH5B01Y+z38+nID2RkoJcYk7vx++7edRq0Iwm/V4yGpd9Q+dlYO3iYdQnICBQfTw0nyy3biOJ3PGJQW3BMkQiMa1mbCL8xwUEfjwQkViCnXd7Wr6zAYnCkrz4YC6tnkz9gW+bTKTi1m0URekJJJ3axfUjG1DYu+LeewINR33I5S9f1t88gi5uznfhQWL2fsG5JYNQF+WjsHXCpdMQGgyaYXCz+LCoP+AtzJ3qcf3Yd/jP70tpUR5mjnVx7zWB+oOnGRWOB+55EGk4cg4WLp7c/OcnEv7YTKmqGLmNIw5Nu9HynY1YuJQ/dZZZ2eO78CBROz8l8OOBlBblYeHqReOJS3DvIwRtA4zp2ZKPf/rLoLZgGWKRiG2zR/Hh5mM89+EWpBIxvo3d2TxrOJZmcq7EJvPiZzuYMbSLyeQoY3u1IiE1h+3/XuHb3/1xtbfmpefaMv/F3kz8fCclKrVetp13HY5+OpkVu07Rb+5W8oqUONtZMaxrU94b0c3gZvFhMW1IZzyc7Vh/KICe739HXqGSus52TOrbhneHd8P8tlvUqsiWIRXf/ZnVgh/+4JsD/gZtC7f9ycJtuifOo3q0YMMM3e12n9ZebJs9itW/naHV1LWIRSI6+Lhz+JOXK7xRFXg6KTMGb/dieeA5C3II+mQwTr6DcGjZm6Alg6o0vrS4gKif5uHUcTD2zcpvUmJ2LkVh74LPG1/pM2W793uDgsQI4vauxK3HOKSWT348rHfvUQT+sMSgtmAZIpGYZ+f+gN/Guex//wVEEikuPu3p+8H3SM0sSY8J5vjSibQaMc1kIpNGfUaTl3KdyL93ELz/WywcXGnSbxK+k+Zy/JOXdGEdt3Bu3I4hyw9z8deV7J89AFVhHub2znh1H0qbUTOrHPpRHfhv/ogre9fd0bYI/82LAF2JjT6zdA8OmvZ/GXM7J64e3MieaT0pVZdg5VgH58btaDtmFjauxsaZSCIxarudVsPf+T979x2WZfUGcPz7LvZGQBTce5uKIy2zbc5yp2XaL0daWTbNrTnShpqrZUtNM3OkltpwsRREZTgBB8re4x287+8PFCVAQIEX8f5cl1cXz3PO89zQAc7NWdh71OXU9jVsef0RdFkZ2Ht40+zJF2g/+HXUloX7OdqMvCURFjb2d/IpCyFKqdJ6jvX6TKJen0nF3rev07LQNMkbui0qOA3jgXcKbiijUKpo+OzbNHy24DoAoMhpnQ71WtNuyrelCbvSePj0KbCOsjhOTXyo98xENKX4xV6rxxBq9RhSqvdbudam1YQvSlX2fvT6wG68PrBbsfdb1fMoNPXxBv9lBaeA/TJ9RIGPVUoF7w17mPeGFT7tvKhpnW0bePLju6X7/1pZ+nVtTr+upftrd2nLdmnuzeT+XXG2v/1utnNffJy5Lz5eqncD9PZpSm+fsp+TVV0c/2gg6VEhdFt2EpWVbYF7kVsWcnHHMtq+twWnZnmd6ZTwQ1zcsez67AwDVq5eeHQbhNfT4wsd0VPgPfP7kx0bRddlIQWuX9n3Led+nEbb937BqdnN76mMi6FE/7aElNP+5GozsXT2pEaH3tTt/wZqa4dy/AqUjiEzFaWF1R2PABZFlxaP1xP/w7PnSNLOl/14gaitH2PISqPR8NkF4syOjcTNp1+h/x/uPv24dmADiSH78Og26K7jr+raDXqNdoNeK/a+a/2WhaYp3jBk1ZECH/eevanAxwqlio7Pv0vH598tVLeoaZ01GrbhiQ+/L03YlaLLmNl0GTO75ILX1e/Wh/rdSu6T1GzRmbbPTsLSvuQ+SYMH+9LgwdL/AaT7hEV0n7Co1OWFEHfGPLs1iDumz0zlmu9WOrz/i7lDEaJCpWTkbdizbfaokguLUvN4cDCpZ/xJPL4X9/+sB47z24aVWx2crs/eSD0TwIklI6jRoTc+Cw+isrYnMWgP4Wsno0tPoNGIOeUSU3pkCMcXDMS5RQ/aT9+BpVNNUiKOcPqbt0g940/7aduKTcr06UkcmVzymqJOCw5g41m6jb0gb2RQZWVXcsEysPFsVKYYbpWTeJkr+76lzjOTsHDyuOXO9ennRUxxvjEamHExDI/i/5YlxB3TZqRw7sCv9Jm/1dyhCCHukCSD9xiNrSM9Pi96C2YhqhMnOytOrX3d3GFUO24+fTj34zTiA7YVSAbTzh8jJz6aegPe4sbiycTgP1BqLGk4dHp+AuLe9Vmu/rue2IObyi0ZPL9hFhpbJ1pM+jJ/dMu13eM0GPwBp79+k/jAHbh3GVhkXY29Cw+vK/9z2wxZqShVaqK2LiE+cCc58dGobZ2o0aE39Z99u9KnXV7c/hlKjSVeT75S4Lra1glrj3qknQ3EZNCjUN+cap16Nm+TGH1aQqXGKu4flnZOPP9tSMkFhRBVliSDZmA06Ng7Km99UvdPA7C+R7YwP/JOdzKv3tyWXNyftPpcXJ6bC8DxVZOp41791iL5TF7JuZi8szddSpimeq9RWzvg2v5JEoP2kJudjso6bz1OnO9WUCjweHBwftkGQ6fTYGjhqcpWbt6kRBzBkJmK2tbxruLJzU4n9WwgHl0HFprm6NI6b41t2vmgYpPBCmMyYTToUFna0PbdTSgtrEg+dYCzP3xA0om/6Dh3b7mPHBZHm3iFa4c24917QpFf7wZDZxC6bAzhaydTf9B7aOxdSDi2m5i/vsv7VHL1lRKnqDpy9TrW9s3bUGz410HV8py+TeO7knIlb5MZq//sRi+EKD1JBitZqwlf3LNr87otPlRyIVGtrXl9QP5mLNVZwPKJ5g6hQnk8OIj4gO0kBO3B48HBmIy5xAfswKlpV6zcbp61aNRridm/jvijv5MTfxF9ZjIYjfk7Lha382JZaFNiwWQk9sgWYo9sKbpMUvmP/JWk/fQdha65deqDQqkkdPnLXPz9C+o/V3j9WEW4dngzJqMBz4efL/J+jQeeovWbPxL5ywICP3gYlaUtzi0fouWrX3J0+qOVlrSKqqHXW6vyN4Opzoas9jV3CEJUC5IMCiHEfcalVU80DjWID9iBx4ODSQk/jC4tngZDphUoF7ZyHInH91Kv/5u4d3su/wzTM+ve4drBjeUa03/PzauqXFo/AgoF6Rcqb7p+QuBO7Ou3K3A+bKG42vTCpU2vAtcyb5wr6y5b8wshhChatU8GgxYPJ+VMAL2+Om/uUIQoN4Pmrscv/CKX1xd/tpMQxVGo1Lh3GUDM/u8wZKUR57cVlZUtNTrd3D1QlxJLYvCfuHfuT90BbxWor028XPJLlCpMpsIjh/q0gjsvWjp7gkJJTkIpnlmEithAxmTQk3klApWVHdYeBQ9/N+p1YDKh1FjdUbxllRMfTcalMOr0mVzmumnnjgLg2NinvMMSpbBr5hCuhfkzZnO0uUMRQohiVftk8H5hNOgJ++pNrh7+hSbDZ1C394SSKwlRhZ2/msTcn/7icGh0/nmEIx5py+sDu6GU0+HvWs0HB3Plz69IPP4nCUF7cOvYp8CZeka9FsjboOVWWTFnSTl941xHU7HPt3BwI/VMAEa9tsD5rclhBY8KUlnZ4tS0MykRvuhS47BwdM+/l3rGnzPr3qHZ/5ZhX79tke+piA1kjAYtwfP749CgPW3fKzh1NenEfgCcmj9Yru8sTurZQADs6rQstsz59TNJDNlLp4/+RaG6voGMycjVf37EplZjHBt3qoxQxX3KaNDx77IpnP17E13GzKLNwFfNHZIQogxuf5qzuCfoM1MJWjyM7Dj566OoHuJSMnj6g29Jy9Kyd+EYon98l9mjHuWTLYd458vd5g6vWrCr2xrb2k2J/u0TDJmpeHQveHalVQ0vrNzqknBsN5mXIzDqtSSd2E/o8rG4XR9BTI88Xuy6QZc2vcBkJPq3pRiy09ClxnF+42wMWemFytYfPA2FUsmpT18g6+o5jHotKRFHiFj7Gkq1BbZezcr/C3AbKis76g2cSkqEL+fXz0SbdBVDdhrxAds5t34Gdt4tqPXIzSNPUs8E8O/oWpz9Ydptnnpnsq5v2mXlVvxUT+fWj5Add5Gz33+APiMZXWocp799m8zLEXlTb+WPJ6KCaDNS2DVjCGnXIs0dihDiDsnI4D1On5lK4Jy+eHTuS402vQiYXfIhsUJUdR9vPkhGjo6vpjybv5tnb5+mTB3Ugzk/7WfcMz40rl3DzFHe+zy6DeLC5vkFzhbMp1DS8rWvOf/TdILn9UWhVOHQqCMtJq5BZWVDRvQpTn3+Et69Xy1yIxWPBweRk3CJ2MObufzHWiyca+LZcyT1B71H6LIxedMtr3No+ADtP9xO9LZPCJ7Xj9ycDCwc3XDz6U/dvq8VGFmsLN5PT8SqRh2u7P2KYzMfx5CdjlUNbzwffp46fSajtCi8y6xCpbrtM89vnMPlPasLXLvw81wu/Jy3O69712dpPm5FgfuGrFQA1Nd3fS2KS+uetJz8NZd+X47/VB9QKHFs1JF207YVO6IqxN3SZqSw7Z1naPBgP+p0fJTfpj5t7pCEEHfgnk4G0y4c5/yvH5NyNm9dhJ1XMxr0fwPXNo/ctl5S2CEity8j7XwwRqMB6xpeeD44iLq9JxTY2lyfkcKFbZ8QH/Qn2uRrqK3scGjQlgYDp+LYsH2Zy1UEXWo8dZ56Ba9HRpJ67liFvktUjuBzMSz4+V8CT1/GZDLRoq47bz3Xg0fbN7xtvQMno/h0yyGOnbuCIdeIt5sTQx9uzav9umKpudlJTc7IZsnmg+wOPMPVpHTsrS1o16gW7w15mAca1ypzuYqw9XAo3VvVK3SsQ5/OTZn94362+YYzdVCPCo3hfuD9zKt4P1P8lC477xaFpkne0GnBgQIft35rfYGPFUoV9QZOpd7AqYXqFjWt065ua1q+9m1pwq40bp365I+C3o5jEx+8n56I2u72x6w0HDaDhsNmlCmGxqM+ovGoj0osV+OBJ6nxwJNlera4c/Fngzn60yJiI44CJlzqNqf9kDfx7tDrtvViThwkeNNnxJ0JwpRrwM7dm8aPDKHNwImoNDf7H9r0ZIJ+Xkq0/x4yk66hsbbDrVE7Oox4B/cmD5S5XEXITomndb9xNH/qBeJOH63QdwkhKs49mwymng/m6Lz+eD/2Es1fWozK0pYL2z4heMlI2r35HTXaPVZkvZQzAQQtHo57x950W3wQtY0Dccf2cGr1JHRpiTQdefMQ5ZNfjCfjymnavvYl9nVbo02J5cz62RxbOJguc//EpmaDMpX7L316Ev9MLH4dyA3dFh3EtlbRGx/Y1mpU7D1x7wk6G0PvD9cx9umOfDKuN7ZWFizZfJCh8zew/v2hPNGhcZH1/MIvMWjuT/Tp3IyAZRNxsLXid/8Ixi/7jYTUTD4ac7OTOPaTXzl9KZ51UwfRpkFNriVnMOO7vfSf9QP/fPwyDWu5lqncfyWmZdH4paUlfq7+yyYUObp3JSGNpPRsmnoVvlff0wWNSknI+aslPl+IymLITCXOfytt3/3F3KGIShB3Jojt7/al5TNj6PHqEjRWtgT9vJQ9s4fz5PQfqdPp8SLrXQvzZ9eMIdTr+gxDV/tiYeNAlN8u/vpkItmp8XT73/z8svsXv0LypdM89t7X1GjQhqzkWPy+mcnv057l2c/241i7YZnK/VdOWhLfP9+0xM91yKojOHkV/XvHyatxsfeEEPeOezYZPLtxLpbOnjQeMROFIm/pY5MRs4gL3MWlfeuKTQbjju1BqbGkyfAZWDrXBMCz27Nc+ecnYg7+nJ8MGvVakkIPUuvh4Tg26giAtVsdWr7yGYfe7Eziib+xqdmg1OWKorF34fEfpFMrbpr5wz48XeyZ++Lj+ZukzB39ODv8Ivh6z9Fik8Fdgaex1KiZ8+Jj1HTJm042+KHW/LAvmPV/h+Qng1q9gQMnInn+0XZ0auoFQF13J1ZM6kf7CcvZf/wCDWu5lrpcUVwdbEjaUvig8tKKS83Mf85/KRUKnOyt88sIURWobR3p8onMzLhf+H87G1vXmnQZOzu//9Fl7Bwij/xO2K5vik0Go/x2o9JY0mXMLGxc8vofjXoOIuLPHzmzf2N+Mpir03Il5ABNHx+BR7O8zX/sPerw8OvL2PhyRy4F/Y1j7YalLlcUKwcXXtkRX+Q9IcT95Z5MBnNzMkk+7Ydn14H5P4gBFAolPT67/VSFJsNn0GR44Wk61m51SA4/gj4zFY2tIwq1Bo1DDeKO7aZG20dxa/8YCpUGtbU9PVeF3XxnKcsJUZLMHB1HwqIZ1KN1gd0ylQoFJ9a8dtu6c154jDkvFP4DSF0PZw6FRpOSkYOTnRUatYoajrbsCjjN4w804smOTdColNhbW3Ju3c3pfKUtVxFydHoALNRFr7+yUKvI1uorNAZx/zEadPw7Om/6c+cl/rc90+9eFfheD7Ku5W1Io7FzNnM09yZ9TiZXQ31p9PBzhfofI74Jvm3dLmNm0WXMrELX7T3qEHPyMNqMFCztnFBqNFg71SDKbxd1Oj5GnU5PoFRrsLCx54X1p/PrlbacEELcTqFk0Moq7+wko0FXYP1cVaJNjQOTCY1D0SMTt2PUa7m0bx1xgb+TFReNITMZk9F4c0e86/9VKJS0f+t7Tq6cSMjnY1BZWOPYuCM12jxCrYeGo7m+NqS05UTxjLocAKytC2/IUF6sLC3R6g0V9vzyEJuSgckENYoYESuJVm/g6z1H2e4bTlRsCikZ2eQajeQa87b+zzUagbzEcsMHw3jls628sHgz1pYafJp48Wj7hjz/aDuc7azLVK4iWFvkbY2vMxTMKh+SAAAgAElEQVS9S6VOn4u1pabC3l9ecnS5OFZgmxblp/m4FYU2bqmOOi08WHIhM7rR/8jV6wqsn6tKspPz+h/WjmXvf+TqtITu+obIIztIvxZNTnoKJmNufv/DdP3ntEKh5MnpP/HX0vH8+dFo1JbWeDTrhHeHXjR9bASW9s5lKieKZ6iE/ocQVV2hoyVcXfN+wOnTkyo9mNJSKPNGDG7dja60TqwYx5kNs3Ft/TA+M7bRc3UEj34TRe2Hhxcq61C/LQ8uPkSn6duo+/Q4DNnpnNkwh8NvdyU9+lSZy4mi6TKSgZttryK4ODuRlJZdYc8vDypl3rfjnSStY5ZuYfp3e3mkXUN2zx/Nhe/f5urGD3i+V7tCZds39CRg2UR2zRvNq327kJatZcb3++j46heciLxW5nLlraazHQAJqVmF7hlyjSRnZOPpUvzOilVFUkYOLi4uJRcUQgA3fwfkpCWaOZLi3eh/5N5B/2Pf4pfx+2YmXu0fod+i3xm94Sxjf71M08dHFCrr1rgdQ1f50m/RTtoMmIAuKx2/b2axcVxnEi6cLHM5UTRtWl5ftyL7H0JUdYVGBps1yzvPKeNSeP6auqrGysUThUKJLiW2TPW0ydeID/qDml0G0GDgWwXuZSdcLrqSQoFTEx+cmvjQcNC7pJ47SuC8gZz/dSntpnxb9nK3KI8NZKqDzMsRwM22VxGat2hB2MW4Cnt+eajl6oBSoSA2OaNM9a4lpbM78AzPdm/Ju0MeKnDvcnxqkXUUCujS3Jsuzb35YHhPAk9f5pnp37F40wF+fHdImcvd6m43kKnpYo+7kx0RlwqvZzlzOQFDrpEHGlXsbqZ3y2SCiEtxjK3ANl0dnVw6gtQzAXRfc87coQgzuPE7ICkqHFtXTzNHUzRb17z+R1ZS2fofWUnXiPbfQ8OHBtJh+NsF7mXEFd//qNmiMzVbdKbjyPeJjQhkx3v9CFr/MU98+H3Zy92iPDaQqQ6Soiu+/yFEVVcoGXR1daVBo8YkhR0u8YgGc1GoNDg27khS2GGMem2BM6h8P+iFUmNJ59mFD6Y2GvL+kqexL/jX+syYsyRH+AJgIm9aXXKELydXTqT91B+xr3MzYXNs1BFLJ3f0GUllKlcU2UAmT1LYIRo0alyhoyhduz3I91+uqrDnlweNSolPMy8OnIxCqzdgqbn57dn9zTVYatTsXzS2UD3t9emUrvYFp5eeuZzA4bBogOutGg6HRvPKZ1v5edpwWtXzyC/bqakXHs52JKVnlalcUe52AxmAQT1a8fWeoySkZRWYNrv1cChqlZJnu5f8RxRzOn4+hvTMbLp27WruUEQVZDLoOf3NW8Qe+YUGQ6fj/fQEc4dUJeT1P5oQc/JQiUc0mItSrcGjeSdiThwkV6dFZXGz//HL5IdQaawY+MmfherdGEm0+s/ylpRLZ7h66kjeB6a8n9RXTx3hryXjeWrmBlzr3/xZ59GsEzbOHuRcn7lV2nJFkQ1k8sScOEjDRk1kFoe4rxWaJgowoF9fEo/9nv+DqSpqPPRDjPocTq56FV1qPIasNM79spCMS+F49XqhyDpWNbywdq9L3NFdZFyOwKjXkhCyn5DPx+Dh0xfIO7vQZMzFoUE7FCo1oWteJ/V8EEa9Fn1GCtG715CTGEPtnnnTOkpbThTNZDKSeGwXA/v3q9D39OnTh4uxiQRX8SMJZo58FK3ewCuf/UZ8SiapmTnMX/83YdFxjHmyQ5F1vN0cqefhzE7/CMIvxqHVG9gbdI5RizfTv2sLIO/swlyjiQca1UKtUjJx+TaOnb2CVm8gOSOblTv8uJKQxshH887FLG25ivLmc91xdbBh7NItXLiWhFZv4NdDoazY7stbg3rgVcOxQt9/t7b5hlPX24s2bdqYOxRRxRgyUzmxZDjZcVHmDqVKGtCvDxd9d1bp/ofP6BkYdFr+Wjqe7JR4dJmpBP7wEUlR4bR4enSRdezcvXCoWZco399Jig4nV6fl4tF9/PnRaBo8mPf7L+5sMCZjLm6N26NQqfnn01eJO32MXJ0WbXoyJ35bRUbCFZo9MRKg1OVE0UwmIxf9fmdA/77mDkUIs1KYTIV/4oaGhtKqVSvaT/2RGm0fNUdcpZJyJpDzWxaTFhkCJhO2tZtQt/cEPHxuHhIctHg4KWcC6PVV3g5q6RdDOf3DdNKiTqBQqnBq3JHGQ6ehsrQleOlIsmKjqNfnVRoNeo+cxBgubF1C4ql/0aXGo7K2x9azEXWeGItH55vJS2nLVYQzG2YTvWt1sfc9uz1LqwlfVGgMdyMhZD/BS0Zy6tQpWras2NGeVi2a09bTihWvVu0f/P4Rl1iw8R+Cz13FhImmXm5M7t+Vfl2b55cZNHc9fuEXubz+PQBORcXy/jd/cPz8VdQqJZ2aejFzZC9srSwYOn8jkdeSeH1AN6aNeIQrCWks/Plf/jlxgfiUTOxtLGlc25VXevswoFuL/HeUtlxFuZyQytyf/uav4+dJz9LSsJYrLz/VkZeKSYqrimytnrYTv2DSG28xc+bMSnmnQqGgxcTVuPlU7M+bilbdp4kaMlMJnt8Pt059cWnzCMFz+95TI4PxAdsJWzmeIroN5eZG/+OpmRuo07HoI6KqgmvhARz9cSEJ545jMplwrtOUNgNfpcGDN3+/7Jo5hGth/ozZnDdDIzEylCNrPyDhXAgKlRqPZh3pPHoGaitb9sweTtrVSNo+N5lOoz4gI+EKx9Yv5krwv2SlxGNhY4eTV2Na9f0fDbr3z39HactVBL9vZnJi68pi7zfqOYheb1XdGTkXj+5jz+zhldL/EKIK21xkMgjQp28/Dp84S8c5e1Go7skTKEQVZ8o1EDjjcbq3aczOHdsr/H0//vgjo198kb8Wj6V1/aq5Hlbc+xZs/Ie1fxznzNlzuLu7V8o774VkMD3yOFFbl5B27iiYwNa7GXX6vo5L65vLEYpKBlPCD3Fxx7LrszYMWLl64dFtEF5Pjy+w47UhM4XobZ+SEPwnupRrqKzssK/flnoD3sK+Qfsyl6sIWVfPkXraD8+eI0k7f0ySwWL06duPgFPn6P/ZXyil/yEqgDHXwLY3euHTqlGl9D+EqMI2F/tT9vPPPqVFy1Zc/ut7vB8fU5lBifvE5f3fkXX1Ap/s3VYp73v++edZu2Y173z9J7vmvsAtR/kJUS4uJ6TyxY4A5n20oNISwXtB+oVggj8aQO1HX6LJi4tQWdkSve1TTn4yilZvrMO1bdEjQKlnAjixZAQ1OvTGZ+FBVNb2JAbtIXztZHTpCTQaMSe/bNjK8WTFnKHFq19iV7cVupRYzm+cQ8jiIXSY9QfWNRuUqdx/6dOTODK5VYmfa6cFB7DxLHrDLxvPRsXeEzfd6H+E715Hyz4vmzscUQ2F7VpHypXzfPLHb+YORQizK3LNIEDDhg15c8obRP66mMyY6jllR5hPZsw5Ird+zFtvvUmTJk0q5Z0KhYJPP/ucwNOXWLsroFLeKe4f+lwjk77YSZ06dZg0aZK5w6lSLmyah6WzJw2HzcDStTZqWycaDp+JpYsnMfu/K7ZeYvAfKDWWNBw6HQsnD1SWNrh3fRanpl2JPbgpv5xRryU57BAubXrh0KgDSo0lVm51aPbypyjVFiSd+qdM5YqisXfh4XUxJf6TZO/u3eh/BP20kJTLZ80djqhmUi6fJXj9wkrtfwhRlRWbDALMnDmTtq1acOKT59GlV91zf8S9RZ+RwsnPXqRFk8ZMn353u06WVYcOHZg3bx4frtvLH0elkyHKz3tf/0HQ+Wts3LQZjUZj7nCqjNycTFJO++HQqCMobvmVo1DSZWkgrd/8odi6DYZOp/vqs1i61i5w3crNG0N2GobMvKNTlGoNFg41SAjaQ8Kx3Zhy9QCorO3ptiKU2o+NKVM5YX4zZ86kTasW/DlnODmp0v8Q5UObnsy+eaNo1rTy+x9CVFW3TQatrKzYse03nCwVnFo2FkN2emXFJaopQ3Y6Jz8fjaMmlz27f8fGxqbkSuXs/fffZ9SoUbyybBtBZ2Mq/f2i+lnyy0G+2xvE+g0badu2baW/38LSKv/onKpGlxoPJhMW9mU/1Nmo13J5zxqC5/XD9/V2HHi5LgfGeHPt4M8AmIx5x6qgUNLqje9Q2zoRunwshyY048TiIVzavQpDZsrNB5a2nCiSUZeDpZV1pbzLysqK7dt+w16jYN+C0eiypP8h7o4uK52981/AVpXLnl3m6X8IURXdNhkEcHd3Z8+u31ElXyR4Xj+yEy5VRlyiGspOuETQvH4oky+yZ9fvZl1TtWbtWno89DD9Zv3Adt9ws8Uh7m36XCNvrP6dRZsOsGLFCvr2Nc9OtU7Ozuhvc6aYOSmUeb9m7iRZDVs5jvM/z8Gl1cO0m/YbD34RTo8vI6nZY1ihsvb12+Kz4CDtPvgN76fGYcjO4MLPc/F/pxsZ0afKXE4Ups9IxtHZudLe5+7uzu5dOzEkRvP7u8+QHif9D3Fn0uMusfPdZzAkRrN7105Z0y3ELUpMBgFatmzJ0UB/vJ2sODa7Nwkh+ys6LlHNJITs59js3ng7WXIs0N/s2zhbWFiwfcdOxv5vHC8t3cKCjf+g1RvMGpO4t1yMS2HwvA38eiSCrVt/Y8IE8+0I2aJ5c7IuR5jt/bdj6eIJCiW6lNgy1dOlxJIY/CfuPv2oO+AtrN3robK0QaFSo028XHQlhQLHJj7Ue/YdHpi5i/Yf7iA3J4PobUvvrNwt9OlJ/Du6Von/sq5W3zX2mVciaNm8eckFy1HLli05GuBPTUdLdkx9kotH91Xq+8W97+LRfWyf+iSeDpYcDTB//0OIqqbUezZ7e3tz5PBBXv7fK/y8ZCQeDzxOo+GzsClm5zUhALKuXeDchlnEBu1l6LDhfPXlWuzs7MwdFgAqlYply5bRokUL3p76FpsPhTFnVC/6dG5m7tBEFZat1fPZ1sOs2O5P3bp1OXT4iFmmht6q+4PdOLq2+I1YzEmh0uDYuCPJ4Ycx6rUoNZb5945++ChKjSUPzNxVqJ5RrwXyNm65VVbMWVJO+13/KO+Ig5QIXyLWvEqrN3/EzvvmGZgOjTpg4eiOPiO5TOWKcmMDmftZxukjPPjKi5X+Xm9vb44cut7/mD2cej5P0HnsXBxrSf9DFC815gL+X08nKuDPKtf/EKIqKdXI4A12dnZs3LCev//+GxftVfze78nJFf8jPugPcnXZFRWjuMfk6rKJD/qDkyv+h9/7PXHRXuXvv/9m44b1VfIH8fjx4zl95izdez3Fix//Qs93vuHrPUeJSUwzd2iiijCZIPhcDLN+2E/biV+w9o/jzPtoASdOhZo9EQTo06cPGXGXSI8MMXcoRao/eBpGfQ4RayahS4vHkJVG5JZFZF4Op1avF4qsY1XDCyu3uiQc203m5QiMei1JJ/YTunwsbp36AHlnF5qMuTg0aIdCqeb02tdIOx+EUa/FkJnC5T1r0CbFUPOh4QClLicKS488TkbcJbNNhb61/2GTdZVfXu3O/kVjifbfg0Er/Q+Rx6DNJtp/D/sXjeWXV7tjk1W1+x9CVAXFHjpfEoPBwMaNG/li1Rr8/Y6gVKpwqN0IjVNNFJbyDXc/Mmkz0CVfJT3mPEZjLp27dGPSxPEMHToUtfreODj46NGjLFv2Ob9u2UJmVjZe7s7Ur+mMk60lSjmY8L6j1eeSmJ5DxKU40jOzqevtxUtjX2bChAlVbs1JsxYtSa3RmqZjPzV3KEVKPRtI1K8fkx4VAiYTtrWb4PXU+PzEDgofOp9xKYzzP00nPeoECqUKh0YdaTB4GiorG05+MorsuCi8e79K/efeRZsUQ9TWJSSHHkCXFo/a2h4bz0bUfmwMbj798t9R2nIV4fzGOVzes7rY++5dn6X5uBUVGsOdOv31FJwSTxEeav51lTf6HytXr8Hf9wgKpQpX70ZYu3iispb+x/0oNzuDrMQYki6fx2TMpXPXbrw64d7qfwhhJpvvOBm8VWxsLP/88w8hISHExsaSni67ft2P7O3t8fDwoG3btvTs2RMPDw9zh3THcnJyOHToEEFBQURGRpKcnIzRaDR3WKKSWVlZ4ezsTIsWLejatStt2rQxd0jF+vHHH3nxxdG0n7UHuzqyJkaUn4yLoQTPeorvvlvHyJEjzR1OAdL/EFC9+h9CVLLySQaFEEKYl8lkonuPh4lI0NL6va0gI9minJxa9BwNHcDP9zAKaVdCCFGdbC7TmkEhhBBVk0KhYNnnn5J89ihX9n1j7nBENXFl79cknfZn5RfLJREUQohqSJJBIYSoJjp06MD8efO4sGEWicf3mjsccY9LOvkPFzbO5qP58+nQoYO5wxFCCFEBZJqoEEJUMy+OfomNm7fQaupG7Bu0N3c44h6UfiGYU0uGMWzwc3y37ltzhyOEEKJiyDRRIYSobr5cu4ZeD/fg5KJBxAfuNHc44h4TH7iTk4sG8cjDPfhy7RpzhyOEEKICSTIohBDVjIWFBTt3bGf8Ky8TvnIcUb9+nH+IuxDFMeq1RP36MeErxzHulZf5fcd2LCwszB2WEEKICiTTRIUQohpbvXo1b059G5WdK3WHzKBGh6fNHZKoghKO7SZ60xxyMxL5ZMnHjB8/3twhCSGEqHhytIQQQlR3MTExvP3Ou2xY/xOO9Vrh1n04ru2fxNLF09yhCTPSJl0lMfgP4g9tIDXqFMNHPM/HixdRq1Ytc4cmhBCickgyKIQQ94ujR4/y+bJlbNnyK9lZmdjVqI2VRz0U1k6gqJxVA0ZdDkqNpZyDeJ1Rl43SwrryXmjKxZSdSnZsJJkJMVjb2DJo0HO8NnkyHTt2rLw4hBBCVAWSDAohxP0mJyeHQ4cOERQURGRkJMnJyRiNxgp/r8lkYu/evbi5udG+vexymp2dze7du/Hx8cHLy6tS3qlUKnFycqJBgwY88MADdO/eHSsrq0p5txBCiCpHkkEhhBCV45NPPuH999/nxIkTNG3a1NzhVAkvvfQS+/btIzw8HDs7O3OHI4QQ4v4iR0sIIYSoeNeuXWPOnDm89957kgjeYtGiRWRkZPDRRx+ZOxQhhBD3IRkZFEIIUeGGDBlCQEAAYWFh2NjYmDucKmX58uVMnTqVkJAQmjVrZu5whBBC3D9kmqgQQoiKtXfvXp544gl27NhBnz59zB1OlZObm0unTp1wdXVl79695g5HCCHE/UOSQSGEEBVHq9XStm1bWrZsyZYtW8wdTpV15MgRunfvzs8//8zgwYPNHY4QQoj7g6wZFEIIUXEWLlzIpUuXWLp0qblDqdK6devG6NGjefPNN8nIyDB3OEIIIe4TkgwKIYSoEOfPn2fhwoXMmjWLevXqmTucKu/jjz8mOzub+fPnmzsUIYQQ9wmZJiqEEKJC9OnTh6ioKIKDg9FoNOYO557wxRdf8Oabb3L8+HGaN29u7nCEEEJUb7JmUAghRPnbsmULgwcPZv/+/TzyyCPmDueeYTQa6dKlCw4ODuzbt8/c4QghhKjeJBkUQghRvrKysmjZsiUPP/ww69atM3c495zAwEC6dOnChg0bGDJkiLnDEUIIUX1JMiiEEKJ8vf3223z55ZeEh4fj6elp7nDuSWPHjuXPP/8kPDwcOzs7c4cjhBCiepLdRIUQQpSf0NBQPv/8cxYsWCCJ4F1YvHgx2dnZzJ0719yhCCGEqMZkZFAIIUS5MJlM9OrVi/T0dPz9/VGpVOYO6Z62cuVKpkyZIpvJCCGEqCgyTVQIIUT5WLduHWPHjuXIkSN07tzZ3OHc84xGI127dsXKyop//vkHhUJh7pCEEEJULzJNVAghxN1LTk7m3XffZcKECZIIlhOlUsmKFSs4dOgQmzZtMnc4QgghqiEZGRRCCHHXJkyYwNatWwkPD8fZ2dnc4VQrL7/8Mr///junT5/GwcHB3OEIIYSoPmRkUAghxN05evQoX375JUuWLJFEsAIsWrQIg8HAvHnzzB2KEEKIakZGBoUQQtyxG+vaLC0t+ffff2VdWwVZtWoVr732GkFBQbRu3drc4QghhKgeZAMZIYQQd27FihVMmTJFkpQKJpvJCCGEqAAyTVQIIcSdiY2NZfr06UydOlUSwQqmVCr54osvOHToED///LO5wxFCCFFNyMigEEKIOzJy5EgOHDhAWFgYdnZ25g7nvvC///2PnTt3EhERgaOjo7nDEUIIcW+TkUEhhBBld+DAAdavX8+yZcskEaxEspmMEEKI8iQjg0IIIcpEp9PRrl076taty+7du80dzn1n9erVTJ48WdZpCiGEuFuygYwQQoiyWbBgAXPnzuXUqVM0aNDA3OHcd2QHVyGEEOVEpokKIYQovYsXLzJ//nymTZsmiaCZ3NhM5vDhw2zcuNHc4QghhLiHycigEEKIUhswYABhYWGcPHkSS0tLc4dzX3vllVfYsWOHbCYjhBDiTsnIoBBCiNLZs2cP27ZtY9myZZIIVgELFy7EYDAwd+5cc4cihBDiHiUjg0IIIUqUnZ1Nq1at6Ny5M+vXrzd3OOK6NWvWMGnSJI4dO0abNm3MHY4QQoh7i2wgI4QQomTTpk1j+fLlhIeHU7t2bXOHI64zGo1069YNCwsL2UxGCCFEWck0USGEELd39uxZli5dyty5cyURrGJu3Uxmw4YN5g5HCCHEPUZGBoUQQtzWY489RlxcHEFBQajVanOHI4owbtw4tm/fLpvJCCGEKAsZGRRCCAEZGRlFXl+/fj1///03a9askUSwCluwYAEGg4E5c+YUeT89Pb2SIxJCCHEvkGRQCCEEq1at4tFHH+XMmTP519LS0nj77bcZO3YsXbt2NWN0oiQuLi7Mnz+fZcuWERISkn89JiaGYcOGMWnSJDNGJ4QQoqqSZFAIIQS+vr789ddftGzZkhkzZpCdnc306dPRarV89NFH5g5PlMLLL79Mx44dmTRpEjqdjk8++YTGjRuzadMmDh8+bO7whBBCVEGyZlAIIQTu7u7Ex8cDoFarcXNzIz4+njVr1jBmzBgzRydK6+jRo3Tu3JnatWtz5coVjEYjAAqFgpSUFBwcHMwcoRBCiCpE1gwKIcT97urVq/mJIIDBYCA2NhaDwcDmzZuJiooyX3Ci1K5du8Znn32G0WgkJiYmPxEEMJlMBAUFmTE6IYQQVZEkg0IIcZ/z8/MrdD7djUTir7/+olmzZsyaNQutVmuO8EQJDAYDn3/+OQ0bNmTTpk0A5ObmFihjYWFBYGCgOcITQghRhUkyKIQQ97mAgAA0Gk2R93Q6HVqtltmzZ9OpUyfZlbKKyc3N5fHHH+eNN94gKysLvV5fZDmDwYC/v38lRyeEEKKqk2RQCCHuc4cPH0an0xV7X61W4+DgwGeffYa9vX0lRiZKolKp+Oqrr2jSpEmxCT3kjfT6+vpWYmRCCCHuBZIMCiHEfcxoNHLs2LFi76vVary9vQkICKBXr16VGJkorYYNG3L06FEef/xxlMrif63HxMQQFxdXiZEJIYSo6iQZFEKI+1hYWBhZWVlF3lOpVPTq1Yvg4GCaNm1ayZGJsrC3t2f79u28/fbbty13u8RfCCHE/UeSQSGEuI/5+/ujUqmKvDd16lR2796No6NjJUcl7oRKpWLhwoX89NNPaDSaQv9fLSwsCAgIMFN0QgghqiJJBoUQ4j7m7+9fYGqhWq1Go9Hw/fffs3DhwttOOxRV04gRI/jnn39wcnIqsI5Qr9fj5+dnxsiEEEJUNXLovBBC3MeaN29OREQEABqNBmdnZ3bu3EmnTp3MHJm4W5cvX6Z3796Eh4djMBgAcHJyIjk52cyRCSGEqCLk0HkhhLhfZWZmcvbsWSBvRLBdu3aEhIRIIlhNeHl5cfjwYZ588sn8Ed6UlBQuXrxo5siEEEJUFZIMCiHEferYsWP5h5MPGjSIf//9l5o1a5o5KlGe7O3t2bFjBx9++GH+NTl8XgghxA0yTVQIUWWEhITg5+dHaGgoycnJaLVac4dUrZ0+fZqTJ0/Stm1bGjdubNZY7O3t8fDwoG3btvTs2RMPDw+zxnM3cnJyOHToEMeOHSMyMpKUlBSMRqO5wyI6OpqjR4/SpEkTWrdube5wqj0rKyucnZ1p0aIFXbp0oW3btuYOSQgh/muzJINCCLOKi4tj1apVrP3qa2IuX8LCxh47r2YobJxAbWnu8Kq1jKgQLJxqYuFUBRIvXSaGlGukx5zDZMzFp3NXJk0cz7Bhw1Cr1eaOrlQCAwNZtmw5W379leysTOzcamPtXg+ljRMoqsZEHH1GMlmxkTg2fMDcoVR/Bi25mcmkX4pAm5VOLa86vPLyGCZMmIC7u7u5oxNCCJBkUAhhLnq9nuXLlzNz9hxyFRpcug3FpeMz2NVtAwqFucO7LxiyUlHbVK1jI4y6bFLDD5Hou4Wk4D00adqUlSuW07NnT3OHVqyYmBjeeedd1q//Caf6ran50Ajc2j+BlYunuUMrkj4jBY2dk7nDuH+YTKRFnSA2YCexhzaiNOqZPXMGkydPLrDbqxBCmIEkg0KIyhcSEsKgIcOIio6i5hPjqd17EkoLa3OHJaqYnNhILm2aTcLxvQwdNpyvvlyLnZ2ducMqYPXq1bw19W1U9q40HDoT945PmzskUYXl6rKJ3LGcS7tXUbduPX7ZtFGmjwohzEmSQSFE5dqxYwdDh4/Aum476r24BMsa3uYOSVRxySf+ImrdFBrVrc2unTvw9jZ/m8nNzWXKlCmsWLGC+v3foEG/11FqZFqzKJ3shEuEf/UmmVHH+XnDevr27WvukIQQ9ydJBoUQlWfVqlVMmjwZ9+7DqPf8RyhU98ZaMGF+2oRLnF0xGitdKn/v30vLli3NFotOp6P/gIHs/+tvWryyDA+fPmaLRdy7TLl6Ir57nysHNrJi+XImTJhg7pCEEPcfSQaFEJVjx44d9B8wAK/+U/Hq87q5wxH3oNzsdM4seyjdNosAACAASURBVAG7nFiOBQaYbROOF0e/xM+bt9DunZ9xbNjeLDGI6uPCts84/+vHbPvtNxkhFEJUNjl0XghR8UJDQxn+/EjcHxwiiaC4YyprexpP+pYUvYqnnn6GrKysSo9hwYIF/PjDD7QY/4UkgqJcNOj/Bl6PjGTo8BGEhISYOxwhxH1GRgaFEBVKr9fTolUbktQ1aPLGTzI1tIrLiY3k4q8LSI3wJTcnHUtXb9y7D6H206+W6niEu61fGtlXzxG+oB9TJk9gwYIF5fLM0jh27BidfHxo+vxs6jzxcqW9V9yUde0CZzcvICn8CLnZ6VjV8Kb2Q0Op12cSilK0r9QLx4ncsYzU88Ho0xOxcqmNe6feNBgwBbVVwc2JMq+e59zmBSSFHSJXr8W6hjc1O/elXu+JqKxsC5RNizrJuV8WkXI2kFxtNtY1vHDv2JsGA94o9NyimHL1HP94BI76BMJOnZBdRoUQlUVGBoUQFWvZsmVERUdR78UlVT4R1CVfxXdsbbQJl8wdilnoU+M4taA/hqx0Wn+4E58vzlB38Idc2bmcCz9Nq/D6pWXt2YhaA95mydJPOHPmTLk993ZMJhOvvTEFl8YdqfP42Ep553/lJF3lz1GeZN+n7VObGkfAnH4YstLpMmsXvb48R5Ph07mwfRkR331QYv3kCD8C5/ZHqbbAZ8Z2eq4MpdGQ97m091uOLRqGyWTML5tx5Qx+059Al5ZApw9/o+cXJ2k48C0if19JyIpxBZ6bFhmC/6xnUFvb0XXeXh5ZHUbT52dz5d/1HFs4tMBzi6NQaWj+v8+JvhjN8uXLy/7FEUKIOyTJoBCiwsTFxTFrzlxqPjH+ntg1NDXiiLlDMKvLOz4jV5tJk3ErsXKri1JtgUv7J6nd93Vi//mB7KvnKrR+WXj0HIVNzQZMeWtquT3zdn766Sf8jhyhyaiPzHYOZnL4/d0+L/z2KQZtJm1eXYW1e177cn/gKRr0f4NLf31PZszt29fZzR9h4eBKq3HLsa7hjdranpqd++H92GhSzx0jLfLEzbI/z8eUa6Dd699g59UMtZUdNbv0x/vRF0kI2U9yhN/NspsWoFCpaPm/T7F2q4Payg639o9Tr/d4Us8HkXI6oFSfn5VrLbyfGs/M2XOIi4u7sy+SEEKUkSSDQogKs3LlSnIVGmr3nlTuz868GMrpFWMIfK0lfuPqEfRuV6I3zSE3O71AufDPRhH8fjdyYiOJWP4SgZNbEDCpGacWDiQj8vjNcp8+z7mvXgMg6N0u+I+rn389+P0HybwURsjMR/EfVx+TMReA9HOBhH86ksDJzfF7pS5Bb/sQ+dM0DBnJBWIIXfQsx97uRObFU4QuHoT/xMb4T2hE2JIhZF4Ku6Xcc/hPaFTocwC4sms5vmNrkxL6b/l8AYuQELgdh6bdUNs5F7ju+sDTYDKReOz3Cq1fFgqlmlrPTmPXzh2EhoaW23OLM++jBXh2H4R93dLtYpoeHcrxT1/i7wnN2fdSHQ6+2ZkzG2ZjyEorUC5oyfMceqsrWdcuEPzpaP4e34y/XmlCwNz+pJ4Pzi93bPFwTq7O+z46OMWHfS/Vzb9+aGo30i+GcuSDXux7qW5++0w5E0jQxyP4a1xT9o6uw4E3OhL+3Qfo/9M+A+cN4MAbHUiPPkXg/GfZ/3JD9o9twNEFg0m/ePNrGzh/IPvHNsBQRPuM3LGMP0d5kniy4trnNb9tuDTvhuY/7cujY28wmYgN3Hnb+h6d+tJk2HSU6oJTMO28mgKQc8uIq2urh2g89EM09i4FyjrUawNAdnx0/rWcpCtYOrih+s9Zqdbu9QqVLUn9vpMxKjWsWrWq1HWEEOJuVO05W0KIe5bJZOLLr7/BpdvQcj9QPiMqhNBFz+LYvAetPtiOhXNN0iJ8Ob/uLdLO+NPqg20olHk/3pRqDfr0JM6ufRWv/lNp8soX5CRc5PSKMZxeMYb2C31RaixpPuUnojfNIeaPNTywyC9/JFOhtsCozSJq/Ye4tHsSC2dPFAolqeGHCf9kBC4dnqb1h7+jcfIgM+oEZ9e+StoZP1p/uCv/3DmF2gJDeiLnv5lCveFzsKvfjpy4aCI+f4GwJUNoP/8AajsXPB5+nrQzfiQEbMPj4ZEFPucE/21YutTGqUWPIr8mhowkAl9vXeLXrt28f7H2bFToui4pBkNGMja1Ghe6Z+VeD4VKTWbUiUL3yqv+nXBu/Qh2Nevx7bffsmTJknJ99q38/f05HR5Gl+Gflqp8WmQIAfMG4NryIXxm7MTKuSZJ4UcI/epNkk/74zN9e/6UaaXKAl1GEidWTqTRc2/TZuJKsuMvcvzTlzj++Rh6LPVDqbGkwzsbOLNhNlG7VtPj0wCsr7dPpcaSXG0WEd9Pw/2BJ7F0yWufSWGHOLZ4OB4de9Nl9m4snTxIjQzh5KpXST7tR5fZu/Pbp1JtiS4tkVNr36DpyDk4NmxPdmwUQUtHcXTBYLovPoTG3gWvR0ZxMsKPa76/4dVrVIHP+ZrvNqxca+PSquj2qU9P4u+JJSfSDy46iG2twu0zJzEGfUYydrWbFLpn7VEPhUpDWuTtN1+p+9T/iryefjEUFApsazfNv1bniaKnAmuTr+W9061u/jU7r+bEB/+JISsNtY1D/vXs2EgAbGsVjrk4KgtrPLoP48uvv2XmzJmlrieEEHdKRgaFEBXixIkTxFy+hEvHZ8r92dE/z0Zt60STiWuxrtkQlaUtzm0fo85z75MReZzEwB0Fyudmp1PryfE4t+mF0tIGm9rN8Oj5IrqUWLIuh9/2XQqFAn16Es7tnsR74Dt49BwFCgUXf5mP2taRRmM/x8qjASpLWxyadqXOoA/IuhxBYsC2m89QqjDqtdR6eiIOTbuitLDGxqsZdQd/iCEjmbjDmwFw6dgHtZ0zcQc3FIgh++o5si6H49Z9aLGbsKjtXOj69ZUS/xWVCALo0uLzn1P4i6BEbeuM/nqZiqh/RxQKHNr35tdt28v3uf+xc+dO7D3q4FC/TanKn/5pJhpbJ9q+9iW2ng1RWdni1v5xGg/5gNTzwVzzLxivISuNer0nUKPto6gsbbDzaobXoy+iTb5G+sWwYt6SR4ECXXoibg88RaNB7+Ld6wVQKDizcR4aG0dajVuGTc0GqKxscWnejcZDp5FxKZxrfr/dfIhSiVGvpd4zE3Fp3g2VhTV23s1pMmw6+oxkrhzcBICHTx80ds5cOVCwfWbGnCP9Uhi1HxpW7CYuGnsXnvjhaon/ikoE4Wb70hTRvhQKJRo7J3SpCbf9WhV6Zmo8UbtWcfHPb2g4YEqRieZ/y0f/8SV2Xs1watIp/3rDAVNQaiw5ueY1cpKuYjToSTz5D1G711CzS/8y7zrr3ukZrlyK5sSJ8v3jiRBCFEWSQSFEhfD19cXCxh67uqXrQJdWbnY6aWcDcWz2IEq1RYF7Tq0eASDjQnCheo7/GVGzcMo7o06Xcq3Ed5qMBmr49Mv/2JCVSkZUSF5id3105eZ7HgIgNeJwoec4texZ4GOHZt0AyLqc1+FXqi1w6zaIjMjjZF2JyC+XEPAbKBS4dx9aYqx3yqjLyY+hKAq1BqMuu8Lq3ynHZt2IPHeWpKSkcn/2DYcOH8GhabdSlTVkp5NyJhCXFoXbZ402ee3z1umfN7i2eqjAx5bX26c2JbbEd5pyDdTs0j//Y31mKmmRITg371aofbq2zPs+SAor3D5vxHeDS4sHAci4dLN91uo+mNTzwWRcvtk+r/ltBYWCWg8NKzHWO5VbQvtSqjXklrJ9ZcVG8ucoT/6Z1IbzW5fSeOg0GvSfcts6+owUgj8djSErjdbjl6NQqvLv2Xk3p93r35B69igHXn+AfS/V4dji4Tg360KLMR+X8jO8ybF+Wyxt7PH19S1zXSGEKCuZJiqEqBDh4eHY1m5S7ptt6FJiwWQk3ncL8b5biiyjTYop8LFCqSq0ju3GCJspN7fklyoUaBxvHnCuS74KgIWTR6GiFg41rpcpmGQqVOpCMajtnADQp90c0fB4aCRX//ySuEMbqTd0FgCJAdtxbN4DS1evkmO9QyrLvKm8RoOuyPsmg+62033vtv6dsqndDICIiAi6dStdwlZWYeHhOPd6qOSCgDY5FpPJyNXDW7h6uOj2mZN0pcDHCqWq0Do4hfJG+zSU/FKFIj95zIshr31aFtU+Hd3yYijUPjWFYtDY5rVPberNEV2vR0YRvWctV/7dQNPnZwN5a/lcWz6EdY0KbJ8Wt29fRr2u0Jq94th41OeJH66iz0wlOfwI4d9/wDW/3+jw7iY0to6FymfFRRH08fPo0hJo/9YP2NdtVeB+zOFfCP3yTeo9PQ6vR1/E0smD9OiThH3zDn4znsJnxnYs7F1L/8kqFNh7NSEiIqLkskIIcZckGRRCVIjExESUdmXoAJWR+0MjaPhi2f/qficUCmWBkYAbijqmNf/af5LgIqfP3ah+yz1rz0Y4NOlCgu+v1B38IVmXI8i+dh6v/m/dcfyloXHMSxz06YmFwzQaMGSkYNGkc4XVv1Pq653shISyTREsi+SkJDyuJ/mlVbvn87QcW3HrGG9VXPu82cBuvZR3TcF/22dRf7S5XlZ5s33a1mqEc7MuXD28hSbDppNxOYLMq+dp+GzF7up6I9nVFdW+cg3oM1OwdKlZpmdqbB1x7/g0Vq618ZvxJJE7ltNk2IcFyqScDST409GoLW3xmb4NO69mhd4dse59nJv60HjozeNTHBs+QKtXPsf3w8eI+n0lTYZNL1NsKjtXEhMLf65CCFHeJBkUQlQInU4HqqKndN0NCxdPUCjRJlwu92eXlqVLbVAo0BcxhU+fGne9TK0C140GHbnZ6ais7fOvGTLypjZq/pNoePQcydm1k0gNPUBq+GHUtk64PPD0bWO62w1kLJw80Di6kx1T+Ny+7JhzmIwG7Oq1K/a5d1v/Tt2YNpiTk1Puz75Br9OiUJfuEHCr6xu45JixfVq51AKFIn+zk1tpU/Lap5Vr4fb53w1QdNd3HbVwcCtQ1uuRUZxc9SqJpw6QFHYIjZ0T7h173zamu91AxtK5JpaO7mRcPl3oXmbMWUy5BhwbFN++chKvcH7rUpybdaVW98EF7t1YK5j5n7abeu4YxxYPx65WY9q/9UP+qP+tshMvY8jJwLaIjZNsPRvmx1dmassKbdNCCHGDJINCiHuKytIWhyadSTt9BH1qXIHpm2ln/Lnw/bs0evlz7Oq1LfvD80foihhRuTUGa3vsG3Yg9fQRjLoclBZW+fdSTv0DFF4fCJASegDXWzbUuXGuoWPTrgXKuXR4BrXddOJ9fyXt9BFqdHm22LVSN9zYQOZu1Og8gNi/v0OfnojmlmltCYF5u7O6du5/m9p3X786UFnZ4tS0M0nhR9CmxmF5S/tMPu1P2Ddv03r8chzq30X7LGJE+lZqGwecGnUkKbxw+0w8+TcArq17FqqXeOoAHj59bsZ7fV2hS/OC7dPDpw8RP3zI1SNbSAo/gme350psnzc2kLkbNbsN5NK+dejSEwtMu7zmvw2FSk3NLgOKrWth78o1399Ijz6F54PPFRipT4s6Cdw8CgIgO+ESxz4ega1nQzq8vxm1lV2Rz7V0dEeptiiwhvKG9OvXrO+BM1aFEPcv2UBGCHHPqTtoGgqlivDPXyT76jmMei1pp3059/XrKDUW+evIysrCOW+aWfqFYIx6LSZj8eu16g7+kNycDM59OwVtwkVytZmkhh3k4tbF2DfqhMt/RkqUFlZc3vEpqWEHMOqyybocTvQv89E4uuPaqW/BsmoL3LoNJiFgG7qUWNx7DL+jz6esvJ55DbWdC2dXjycnLgqjXktCwDau7lmNV9/X80ZEr0sNO4jv2NpEb5pzR/WrsybDPkShVBK8dBSZMXntMyn8CKdWT0apsSg01bC0rK63z9TzQXnt8zbrCZsMm05uTganvnyD7PiL5OZkkhh6gHObF+HUpBMenQru8qu0sOLCb5+SeOpfcnXZpF8K48zP87B0dMejc7+CZdUW1OoxhGu+v6FNvkbthyunfTbo9zoW9i6cWDGOrNhIjHot1/x+I+r3VTTo/wZWrjfbV2LoAf4c5cmZDf9v787DqqrWB45/z8w8j4KAgjjPiuMtbbyZc0ZReruplZrp1frZqF6HsiwzGx3K5rpqk5plNlg5oBCOKPOkiAIynAN4gHM45/cHSiKgoiAo7+d5fIq937XWu+mVWGfvvdaCqusLfWA+hvTDHP3gKYynj1NRbqQgfg9HPpiN2s6JwPO2k4j/+DkspjK6P7GmzokggEpnR9DdUymI30PS+iWU5mVRUW5EnxzD0bVPobZzIuDOyY33TRFCiKskdwaFENcdh7Y96fLsRjI3Lyd2ySgqjMVonD3xCBuJ390zaqygeLk8B4wjP+YHkt+fgcrWkW7zf6oz1jGkL52f/obM717j4H/vwFJuROfuh9fAe/Ef8Z+qfQ7PUag0hExcTsb6hRSnHcRqteAY0oc2DyyqdWEV75vHc3LbauwDu2LfutMVXU99qR1c6fLcRo59/TKHXxxBRWkRtt7BBEUsrNxSo5Hb3yicg3sRNm8zqd++TtSiEZiNxeicPfHpP4o2I2ZecX36DrqX7OgtHF45A7WtAwMW/1xnrEtoX/o+/y3J37xK5Au3U1FmxNbdj1b/CKft6FlV+xyeo1Rr6fzoGyR+uQB96gGwWHBp15cO/1pc68Is/kMnkPHjKpyCuuIYcOnHPxuCxsGVsHmbSVr/EnsXDKfCWISdTzDtJyyq3FLjElrf+hBaZ0+O/bSGyOduxWIux8bdD+fgngSPno2tV+XegRXlRnIP/ALAjtm1v+fqd/MDdJ68DICQcc9g592WzO2fcfzntVSYStE6eeDeaTDdp6/GzrtNA30HhBCi4Smsta2AIIQQVyk8PJzf0oyETl3V1Kk0ubjlD1KUFE3YuzXfp6vLmRPxHJx3K8H/fu2a3Rm8XkVO8mPdunWEh4c3Sv8KhYJu01fhc8EdshtFzNIICpOiuXVN8mW3Kc6MZ/ezQ+k8eRl+Nz/QiNm1TAffepSbAm1Yv359U6cihLixbZDHRIUQ4hqwXuI9xAtlbX0PjbMXHv3HNlJGQpynnp8Lp295F52zF74D72mkhIQQQlwL8pioEEI0E1ZLBVZzOdm/f0bu7q8Inbrqih8pFKKhWS0VWMzlZP72KVk7N9D9idVSn0IIcZ2TyaAQQjQTedGbSFozA62LNyGT38S9z/BLNxLiGjm1ZyOxK59A5+pN1ylv4x024tKNhBBCNGsyGRRCiEbWcdbnlxXn0W8MHv3GNHI2QlTXe86XlxXnO3AsvgPlsWUhhLiRyDuDQgghhBBCCNECyWRQCCEaWNzyB9k7rV1TpyFEo4pZGsGvk4ObOg0hhBBXQR4TFUIIUY3VbCLlo6fIjfyKwPC5tLpzSq1xpdlpHPtmCfr4SCpKi9C5t8ZrcDh+dz0OipqfNV5uv0I0NkP6YZK/eoXCpOjKPRg9/PHqM4y2o/9TY5N5feoB0ja/iT5lP6aiPGzc/PDqO4y2o2dddEN6IYS4HshkUAghRBXzGT0Jb0/CWmG6aJxJn0PsklHYte5M1xe+R+vqS+Hh7SSveYKy/Czajl9yRf0K0dgMaQfZu2AE3n2HMWDxz2gc3SiIiyR29UwK4iMJm78ZxdkPMwri9xDzyn149bmLsHmb0Ni7cPrQdo6s/g8FCXsJm7epKlYIIa5H8hNMCCEEUDlhi31pFE7t+xN43/yLxmZufoOKshJCH3sXG89AlGotbj3vxG/ETLJ//xTjyb83MK9Pv0I0tqT1S1CoVHR+ZDm2ngGobRzw7Hk7QcOmoE/ZR2FC1N+xG15C6+ROl8fewtajNWpbR3z6jaT1bf9GnxyDIe1QE16JEEJcPbkzKIRodswlhWRufoOCA9soLzyFysYB+6DutB71JA5telSL1cft4sSWNylOO4DVYkbn7o/ngHvwvXMKSrW2Ki7ujQmUZqfQ/vEPSPtiLsXpB1Gq1Lh2v50241+i8NBvnPjhLYzZqWicvPC9fTK+t02qan/klbGUnj5Ohyc+JP1//6U4/SBYrTgG9yLwvv9i37rTRa+p5NgRMjctw5C4l4qyErQuvrj3vgv/EbNQ2Tpe0bU3NJM+F9/bJ+N983iKUvddNPZ09Cac2g9E7eBa7bh7r7s49tVL5MVswX/4zHr325KYigtJ3fg6Ofu2UVZwCrWNA05tuxM85imcg3tWi80/upPUTW9iSNmPxWLG1sOfVoPGEThsarU63/fag5w5mUr3/3xAwqdz0aceQKFS49nzdjr++2VOH/iVtM1vUXIqBZ2zF4H/fISAOyZXtY9ePBrj6eP0nPUx8Z/Nw5BWWefOIb1p/+B/cQzofNFrKso4Qso3r1GQuIeK0hJ0rr549x1G21GzUNs5XdG1N7TS/BPonDxRaW2rHbf1CgLAmJuBa4f+AHj3HYHO2QOlWlMt1sG/fWVfp4/j3LZx/14KIURjksmgEKLZSVw5FePJREKnrsY+oAsmfTbp6xZx9NVwus3fio13WwCKkqKIe/0B3HrfRY8X/0Rt60j+/q0kvT8DkyGPoIgFVX0q1RpMRfmkfvosQffNx9YvlOztn5CxYTFl+VkoNTraT/8AlZ0L6V+8QPqX83Bs2wuHtpW/mCrUWsxFeaSsnUVQxEIc2vSgNCeD+BX/4uhr4fR88U/UDm61Xk9x+kGOvDIW547/oMtzm9C6+mCIjyTloycxJO6ly3MbUSjV9br2C5mL84me2fWS39sei//A1jek1nO2viF1njtfeX4W5uIC7FrVXCTHxisIhUpNSfrfd0wut9+W5tA7Uyg+kUD3GWtwCuxKWWE2iV8s4K+X72XAom3Y+VT+ty5MjCJmaQTefYYxaOkO1HZO5MRs5fDK6ZQZ8ugwfmFVn0qVlvLifOI+eob2D/wXB7/2HP/1YxL/t4jSvMo67/GftWjsXYj75DniP52Lc3AvnIN7VbZX6yg35BG7+j+0H78Q5+CeGLPT2bdsAn8tuZfBS3eicay9zg1pB4laPBr3zjcRNu97bFx9yI/bzZH3Z1c+Ujl3EwqVul7XfiFTUT7bp118Qgow6JUd2LeqveYc/DuSu38b5jOGahNUY3YaAPatQquOBf7zkVr7KDp2BBQK7P3aXzIXIYRozuQxUSFEs2IxlaGP24lL11twDO6NUqND5xFAyMTXUWi0FMb+XhWbv/8nlBodgeFz0bp4o9TZ4dF/LE6h/cnZta5G3xXGIvzufgKHtj1R6ezxveMRVDp7ipKjCZ64HJ1HAGo7J1rdNQ0AffzOqrYKpQqLqYxWd03Dqf0AlFpb7Pw7EHjvC5iLC8jZtaHOa8pYtwC1vQuh01Zj6xOMSmePa/fbCLjnWYrTDpAXvbne134htYMbAz44cck/DTEpKzfkVo1Zg0KJ2t4V09kYUTuLqYz8Izvw6H4rLiF9UGp02HoG0PnRN1CqtZw+tL0qNidmK0qNjtCIeehcfVDp7PAdOBa3DgPI2lGzzs1nDLQZMQPn4F6obOwJ/OejqGzsKUz6iy6PvlH5aKSdE22GTwcq7zpWUSqxmMoIunsabh0HotLa4tC6I6H3z8VUXMCJHevrvKaEz+ejsXeh+4w12PsGo7Kxx7Pn7bQLfw59yn5O7d1U72u/kMbRjTs+PXnJP3VNBAGCR89CqdFxeNUMSvNPYjGbyDv8O+k/rsKn/6iL3pks1+eS/sN7HNu2luDRs3DwC60zVgghrgdyZ1AI0awo1Ro0Th7k79uKa9dbcO1+OwqVGpWtI31XxFaLDQyfS2D43Bp92HgGYEiIxHxGj9rOudo5p3ZhVf+uUKpR27ug0GjROntVHdc4eQKVjzdeyKXzkOr9dRgIwJnMo7VeT4WxCENSNJ79x1R7nA/ApctQAIpT9+PRb0y9rr0pWcpLAWpczzkKtQZLufFapnTdUag1aJ08yIn5Ec/ut+LZ8zYUKg1qW0eGvle9lkIj5hEaMa9GH7aeAeTH7cZUokdjX73OXUPPq3OVGo29S+WHCy7eVce1zpV1XlZYs849ug2t9rVbp0EAFB+vvc7NxiIKE6PxGVizzs/1pU/Zj+/AsfW69sbg0LojPWau5dDbj/HnzF5Vx7363EWnia/W2uZMdho7n6r8u66ysafdfc8TeGftdw2FEOJ6IpNBIUTzolDSYcZHJK2eTsI7k1FqbXEM7o1L16F4Db4ftb1LVajFVEb29o/Ji9lCae4xzCUFYLFgtVScDai4oGtVtffzKg8qqvVZeUgB8Hc/546r1DXekVM7VLY1GU7XejnlhdlgtZAb+TW5kV/XGlOWn1Xva29KKl3lu1YWc3mt563mcpQXvI8lqlMolPR88hMOvTuNAysmotLa4tyuDx7dhuJ3UwQah+p1fvyXj8iO3oIxJwNTSQHWS9T5+Y8/Vo6nQHNhnVNXnWvQXFDn59qW1fIBCUBZQTZWq4WTu77m5K7a67w0/0S9r70xZO36iiNrZhN012P43/oQOhdvijIOc3TtHPbM+ydh8zahdXSv1sbOuw13fHoSU4megrjdxH3yHKf2fEfvp9fXmIgLIcT1RCaDQohmxyGoOz1f/JOi5GgKY3+n8MgfZKxfxIktb9HpqXXYB3QBIHHlFAoO/kzrkbPx6H8PWmdPFBotqR8/Tc7O/zV4XrUuIW89d/LiT9173fQAwQ/VftfhfJd77U1J41x5d8lUlFfjnNVixlxciDa037VO67rj1KY7g5fupDApmtOHtpN3+HcSv1xI2uY36fPMBhwDK/9bH3z7MXL3byN4zJP4DroHnbMXSrWWox/O4cQfXzZ4Xuc+DKmustAVyovXud+QB+k86bVLjnG5197QrBVm4j96Ftf2YbS77/mq487Bvejy6AoiX7iN9C3vEnp/zScOADT2znj1uQsbR3cVzQAAIABJREFUdz/2zLuTtM1vEXr/C42SqxBCXAsyGRRCNE8KBY7twnBsF0brMXMoSonhyMtjydz0Ou2nr6W8MJuCA9vwCBuF/8jZ1ZqW5WU2SkoWczkVxqLqq38W5wOgcfKotY3WzRcUSspO1yOnS1x7bRpiAZnLpXXxRuPshTErscY5Y1YyVosZhyBZYfGyKBS4hIbhEhpGyLinKUz+i+jFY0j5Zhk9Zn1IWcEpcvf9hE//0QSPebJaU2N9aqoeLObyGourlBcXAKA9+wj1hWzcfFEolJTWs84vdu21udoFZIx5mZhLi7GvZfEje99gAEqykgAozTtByrfLcO0wgFaD760We+5dwZJa/g4IIcT1RCaDQohmxZAQSdKa6XSY+Wm17Rocg3ujcfHCdPaXUqu5DKi5iInxZBKGhD2VMVYrDa3wyJ+497m76mt9/G4AnNsPqDVepbPHKbQfhoTdmPQ5aM57N9GQuJfUT54mZPIKHIK6X/a11+bcAjLXike/0WRv/xhTUR6a8x6pOx1duTKqe79R1yyX61FBfCSH3p1Gr6c+q7Zdg0tIH3QuXpSf/ZDh3KO42gtW8CzJSqIgPhIAKw1f53mxf+IdNvzvfI/uAsCtYx11bmOPS/t+5Mftpkyfg+68Oi9I2MvRtf9H1ylv4dSm+2Vfe23OLSBzpc7dVS3OjK9xrujsMVuP1gBoHd05FfkdRRmx+A66p9qTAYb0w5WxZ7ejEEKI65WsJiqEaFYc2vRAoVST8sFMilP3YzGVYS4p5OS21ZTnZ+H9jwgAdO7+2HgGkr//R86ciMdiKqPg0G8kvDMZ976Vv8QWpx2s8T7U1VBqbcjcvBz90T+xlBs5kxlHxlcvonH2wr3viDrbBY57HoVSRdyKhzCeTMZiKsOQEEnyBzNRarTY+XWo17U3B/53z0Dt4EbSyimU5qRjMZVxOmojJ7euxH/ETHRufk2dYrPm1LYHSpWa2FUz0afsw2Iqw1RcSMaPqyjNy8J/yAMA2Hj4Y+sVSPZfP1CcWVnnpw/+yoEVE/EOq6w5Q+qBBq/z1O+Wkxf7BxXlRoqOHyVx3WJ0zl549xtZZ7vQ+19AoVSyf9kESrIq6zw/bjexK59AqdHi4N+hXtfeGFQ6O4LunkpB/B6S1i+hNC+LinIj+uQYjq59CrWdEwF3Tq76PoQ+MB9D+mGOfvAUxtPHqSg3UhC/hyMfzEZt50TgHZMuMaIQQjRvcmdQCNGsKLW2dHnmW45vXEbCe49iMuSisnHE1jeE0Ckr/550KZSEPv4+6V/OI/bFkShUKhyC+xA6ZSVKnR0lx2JJeOthWg2bRsCYpxskN4VKQ8jE5WSsX1g50bRacAzpQ5sHFl10wRSHtj3p8uxGMjcvJ3bJKCqMxWicPfEIG4nf3TNQanT1u/ZGkrF+IVk/rbrg2CIy1i8CwKP/WNo98hYAagdXujy3kWNfv8zhF0dQUVqErXcwQREL8R4y4Yr7bSlUWlv6vrCRlG9f4+Bbj1Cuz0Vl64i9bwjdpq/C5+ykS6FQ0mPmB8R/Ope9C4ajUKpwadeHbtNXodbZU5RxmP3L/02b4Y8TMu6ZBslNqdbS+dE3SPxyAfrUA2Cx4NKuLx3+tbjGRu3ncw7uRdi8zaR++zpRi0ZgNhajc/bEp/8o2oyYWVXnl3vtjSVk3DPYebclc/tnHP95LRWmUrROHrh3Gkz36aux825TFdv61ofQOnty7Kc1RD53KxZzOTbufjgH9yR49GxsvQIbNVchhGhsCmtjPEclhGjxwsPD+S3NSOjUVZcOvg7ELX+QoqRowt6Vd4Sam8hJfqxbt47w8PBG6V+hUFyTSUpzELM0gsKkaG5dk9zUqbRoB996lJsCbVi/vu59HYUQogFskMdEhRDiMjXGu1lCNDvyGbEQQrQYMhkUQgghhBBCiBZIJoNCCCGEEEII0QLJAjJCCHEZOs76vKlTEKLR9Z7T8JvYCyGEaL7kzqAQQgghhBBCtEByZ1AIcUOLW/4ghqQo+r2b1NSp1FvSmic4veebqq97vbIH3dkNsW8kB56/CeOpFKByy4q+K2KbOKPrT8zSCAoTo7j1/ZSmTqXeDr/3OCd3/13n/1geVbXxe3O3a85gSk5Wfs81Dq4Mfe9oE2ckhBD1I5NBIYRoxpRqLf1WpVU7VpqdxrFvlqCPj6SitAide2u8Bofjd9fjoLjyBz6sZhMpHz1FbuRXBIbPpdWdU2qNq+/4l+q3x4t/ApDw9kQMSVFXnL+4finVWm77MKPq6/Qt75L4v0V1xt/+0XEUqsv/FcZiKuOXiUEXjfEb8iCdJ71W9bUh/TDJX71CYVI0FWVGbD388eozjLaj/4PaxgGAQUt3AnBg+cMUJO697HyEEKK5kMmgEEJcR0z6HGKXjMKudWe6vvA9WldfCg9vJ3nNE5TlZ9F2/JIr6td8Rk/C25OwVpgadPzL7VeI85nOGAC4ZVUCajunq+5PqdFxx6cnaz2Xs28rB5Y/jE//v/eRNKQdZO+CEXj3HcaAxT+jcXSjIC6S2NUzKYiPJGz+ZhRX8cGLEEI0F/KTTAghriOZm9+goqyE0MfexcYzEKVai1vPO/EbMZPs3z/FeLL+m4Wbz+iJfWkUTu37E3jf/AYbvz79CnE+8xk9ACqdXaOOU1FaQvwnz+PTfxTunW+qOp60fgkKlYrOjyzH1jMAtY0Dnj1vJ2jYFPQp+yhMkDvYQogbg0wGhRDNwpFXxrJ3ajAVZSU1zh375hUiJ/lhSIisOqaP28XR1+4j6vH27J0azIEXbubEljexmMsvOk7sktH8NatHjeOnfvuwxhgAJceOkPD2RKJndGbPY0Hse3oAGesXUmEsusIrvTqnozfh1H4gagfXasfde90FVit5MVvq3adJn4vv7ZNpPeqpBh2/Pv22FNGLR/PLpDZUlNas86QNL7Ntgi8F8X/XYP7Rnfz1cji/PdKOXya1YdfT/yBt04pL1nnUopH8Pr1bjePHfl7Ltgm+5Mftrna8KOMIB5Y/zPapHfnl4QB2zO5H4pcLMJ+9Q3etmc8YUGpt6vUo6JVI/nop5hID7R/4b7Xjpfkn0Dl5otLaVjtu6xUEgDE3AyGEuBHIY6JCiGbBc8A4DIl7KTjwMx79Rlc7lxe1EZ1HAE6h/QEoSooi7vUHcOt9Fz1e/BO1rSP5+7eS9P4MTIY8giIWNEhOxekHOfLKWJw7/oMuz21C6+qDIT6SlI+exJC4ly7PbUShrP3HqLk4n+iZXS85Ro/Ff2DrG3JZ+ZTnZ2EuLsCuVbsa52y8glCo1JSkH7qsvs5n6xtyWTnUd/zL7bclaTX4XgoS9pK7fxs+A8ZUO3dqz3fYegbg2r6yzgsTo4hZGoF3n2EMWroDtZ0TOTFbObxyOmWGPDqMX9ggORnSDhK1eDTunW8ibN732Lj6kB+3myPvz6YgYS9hczfVOSkzFeWzfVrnS44x6JUd2Le6/Fowleir3strLMbTmRz7+UPajJiOztWn2jkH/47k7t+G+Yyh2mOqxuzK93ftW4U2am5CCHGtyGRQCNEsuPcdQdoXL5AXvanaZLAodR+luRm0HvUkKBQA5O//CaVGR2D4XLQu3gB49B9L9p9fkLNrXYNNBjPWLUBt70LotNUo1VoAXLvfRsA9z5Ly4ZPkRW/Go9+YWtuqHdwY8MGJBsnjnHJDblXfNSiUqO1dMZ2NaQxNPf6NwDtsBHGfPM+pPZuqTQb1yTEYczIIHvtUVZ3nxGxFqdERGjGvarLiO3AsJ37/nKwd6xpsMpjw+Xw09i50n7Gmqs49e95Ou/DnOPL+bE7t3YTvwLG1ttU4utX5Lt7VMJ8xoFCpSfnmVbKjvudMTgYaexe8+gwj5J45aBxcrnqM1I1voNLoCPznYzXOBY+eRV7sHxxeNYOODy1B6+RBQdwu0n9chU//UTgH97zq8YUQojmQx0SFEM2CytYR1x53UHh4e7VHME/v+RYUCjwHjqs6Fhg+l7B3E9G5+VXrw8YzgApjUdX7RlejwliEISka5w6Dqn5BPsely1AAilP3X/U49WEpLwWokc85CrUGS7nxhh3/RqC2c8Kr152cPvQb5vPq/GRkZZ23Gnxv1bHQiHncuiYZG/fqdW7rGYD5jAFTydXXudlYRGFiNG6data5R7fKOtenXNs6B7BaLVjM5ah0dvR+dgND3j5EhwmLyY7azJ75/8RcWnxV/ZfmnSBrx3pa3zEJjb1zjfMOrTvSY+Za9El/8efMXvzycAAxSyNw7dCfThNfvaqxhRCiOZE7g0KIZsNz4L3kRW8mf/9PeA4ch9VSQV70ZpxC+6PzCKiKs5jKyN7+MXkxWyjNPYa5pAAsFqyWirMBFVedS3lhNlgt5EZ+TW7k17XGlOVnXfU49aHSVb6/VNf7YlZzOcoL3nG6kca/UfgOvpdTezeRE7OVVoPvxWqp4NTeTbh1GICtZ/U6P/7LR2RHb8GYk4GppABrA9d5WUE2VquFk7u+5uSu2uu8NL9h73Bfjn7zv69xzDtsOCiVHFwxifTv3yZk3DNX3H/Wzg1YLWb8hz5Y+/ldX3FkzWyC7noM/1sfQufiTVHGYY6uncOeef8kbN4mtI7uVzy+EEI0FzIZFEI0Gy5dbkbj5EFe9CY8B47DEL8LkyGXwHufrxaXuHIKBQd/pvXI2Xj0vwetsycKjZbUj58mZ+f/GjQnr5seIPih5nEnQONc+UisqSivxjmrxYy5uBBtaL8bdvwbhUfXIWidPMjeu4lWg+8l/+hOyvW5tLrvhWpxB99+jNz92wge8yS+g+5B5+yFUq3l6IdzOPHHlw2a04V77DVXHt2GgkKBPvnq7lZmR32Pc9setW5ub60wE//Rs7i2D6PdfX//7HEO7kWXR1cQ+cJtpG95l9D7515VDkII0RzIZFAI0WwolGo8wkZzavtHmM8YOL33O1Q6e9x7310VU16YTcGBbXiEjcJ/5Oxq7cvyMi9jDNXfd1bOY9JXf9dN6+YLCiVlpy/dZ20aYwEZrYs3GmcvjFmJNc4Zs5KxWsw4BNVcKbWhNPX4NwqFSo3PgDEc/6Wyzk9FfofKxr7yztdZZQWnyN33Ez79RxM85slq7Y2XUZN11Xn5BXVu4+aLQqGk9ArrvDEWkLGYTRRnxqO2scfOp231c6ZysFpRanVXlC+AMSeDomNHaDNiRu3n8zIxlxZjX8tCSfa+wQCUZCVd8fhCCNGcyGRQCNGseA4cx8lf3qfg4Dby923Frc/dKM/ba8xqLgNqLmJiPJmEIWFPZYzVWmf/GicPzElRWExlKDV//0Kpj9tZLU6ls8cptB+GhN2Y9DlonL2qzhkS95L6ydOETF6BQ1D3WsdpjAVkADz6jSZ7+8eYivLQnPeY2unoypVN3fuNavAxm9P4N4pWg+/l2E9ryNm/jZyYH/HuO7zannrnHsXVOlav85KspKqtJ6zUXedaJ0/MCTXrPP/IBXVuY49L+37kx+2mTJ+D7rw6L0jYy9G1/0fXKW/h1Kb2Om+MBWQs5jKiFo3EuW1P+j7/TbVzpw/+CoBbp8FX3H9BUjQAjoG1T2LP3YEtzoyvca7o7LHa7igKIcT1SBaQEUI0K/aBXbFr1Z7MTa9jPqPHa1B4tfM6d39sPAPJ3/8jZ07EYzGVUXDoNxLemYx738o7K8VpB2u9KwLg0vUWsFrI3PQ6FcYiTPoc0tctqLaYxzmB455HoVQRt+IhjCeTsZjKMCREkvzBTJQaLXZ+HRr+G3AJ/nfPQO3gRtLKKZTmpGMxlXE6aiMnt67Ef8TMaovqFCVFETnJj7TPn79Ij403vqibU1BXHPzak/rNMkwlevxuuq/aeRsPf2y9Asn+6weKMyvr/PTBXzmwYiLeYSMAMKQeqLPOPbrfgtVqIeXbZZjPGCjT55DwxX8xG2vuGxh6/wsolEr2L5tASVZlnefH7SZ25RMoNVoc/K9tnattHAgZ+38UxEeS8Pk8SvNPVt5B3buJ+M/m4hjQGf9bJlTFFyZGsW2CL3EfP3dZ/Z85mQyAnVdgredVOjuC7p5KQfwektYvoTQvi4pyI/rkGI6ufQq1nRMBd06++gsVQohmQO4MCiGaHY+B93Dsq5eq7S1YRaEk9PH3Sf9yHrEvjkShUuEQ3IfQKStR6uwoORZLwlsP02rYNALGPF2jb8+B4yjLO07u7q84uW01GhcfvG9+kICxT5Pw9iQsprKqWIe2Peny7EYyNy8ndskoKozFaJw98Qgbid/dM6rdcblW1A6udHluI8e+fpnDL46gorQIW+9ggiIW4j1kQq1t6toL8ZyM9QvJ+mnVBccWkbF+EVC5bUe7R96q9/j16bcl8h08jqR1L1bbW/AchUJJj5kfEP/pXPYuGI5CqcKlXR+6TV+FWmdPUcZh9i//N22GP17rQiqtBt9L6enjZO3YQMaPq9C5+uA/dDwh9z7LgTcexnreIkDOwb0Im7eZ1G9fJ2rRCMzGYnTOnvj0H0WbETObpM6D7p6GrWcAGT+tIfKF26gwFmHj0Rr/IeNpM/KJGpvBA5e9Qf25VVjVto51xoSMewY777Zkbv+M4z+vpcJUitbJA/dOg+k+fTV23m2u7MKEEKKZUVgv9jyVEEJcofDwcH5LMxI6ddWlg0WtktY8Qf5f39NvVdoV95GxYTFqexf8hk1vwMwaR8LbEzEkRdF3RWy92kVO8mPdunWEh4dfOvgKKBQKuk1fhU+/kY3Sf0t3+L3HyY76nts+zLjiPhL/twiNvQttRjzRgJldvgPLH6YgcS9D3zvaIP0dfOtRbgq0Yf369Q3SnxBC1GGDPCYqhBA3KPMZPaf3fldtAR4hbjSmEj2nIr/Fu6/UuRBC1Jc8JiqEEDcotZ0zvV/7q6nTEKJRaeyduWnFvqZOQwghrksyGRRCiGbMYi4nclLloiy9XtmD7gZcxfDA8zdhPJUCVL6TKFoei7mcbRN8AfjH8qjrZrXOXXMGU3KysnY1UrtCiOuQTAaFEKKZavfIWy1igZUeL/7Z1CmIJtR16jt0nfpOU6dxRQYt3XnpICGEaMbknUEhhBBCCCGEaIFkMiiEEJcQt/xB9k5r19RpCNEgYpZG8Ovk4KZOQwghRDMgk0EhhBAAWM0mkt+fSeQkP7J+WtnU6QhxVSxmE7Ern2DbBF/Sf3ivqdMRQohmSd4ZFEIIgfmMnoS3J2GtMDV1KkJcNVOJnoMrJmIxSz0LIcTFyJ1BIYRo4cxn9MS+NAqn9v0JvG9+U6cjxFUxleiJWjgC1w79af+A1LMQQlyM3BkUQrRoxWkHOL5xGcUpf2G1WrHz74j/8Bm4dBl60Xb6uF2c2PImxWkHsFrM6Nz98RxwD753TkGp1lbFmUsKydz8BgUHtlFeeAqVjQP2Qd1pPepJHNr0qHdcYzDpc/G9fTLeN4+nKFX2a7ue6VMPkPLNqxQmVe4v6eDfgbaj/oNHt4vXc/7RnaRuehNDyn4sFjO2Hv60GjSOwGFTq9WzqbiQ1I2vk7NvG2UFp1DbOODUtjvBY57CObhnveMaQ7k+l8B/Por/0PHok2MadSwhhLjeyWRQCNFiFacdIPbl0fjc8m/a/utlVDp7Mje/Qdwb/6LDjI9w7XZrre2KkqKIe/0B3HrfRY8X/0Rt60j+/q0kvT8DkyGPoIgFVbGJK6diPJlI6NTV2Ad0waTPJn3dIo6+Gk63+Vux8W5br7gLmYvziZ7Z9ZLX2mPxH9j6htR6ztY3pM5z4vqhT9lP9OJRtL7tYTo9vBSVzp7Uja+z/7Xx9Jj9MZ49bqu1XWFiFDFLI/DuM4xBS3egtnMiJ2Yrh1dOp8yQR4fxC6tiD70zheITCXSfsQanwK6UFWaT+MUC/nr5XgYs2oadT9t6xV3IVJTP9mmdL3mtg17ZgX2r2mvWvlVIneeEEEJUJ5NBIUSLlbFhMVoXX4LC54Gi8qn5oPvmkR/zA9nb654M5u//CaVGR2D4XLQu3gB49B9L9p9fkLNrXdVk0GIqQx+3E69/3I9jcG8AdB4BhEx8nX3PDKAw9nd8vNtedlxt1A5uDPjgRIN+X8T1KfF/i9C5+hL6wHwUZ+s59IH/kh39A8d/+ajOyWBOzFaUGh2hEfPQufoA4DtwLCd+/5ysHeuqJoMWUxn5R3bQ6uYIXEL6AGDrGUDnR99gx+x+nD60nQCftpcdVxuNoxt3fHqyQb8vQggh6iaTQSFEi1RRVoIhcQ8e/cZUTQQBUCjp9WrURdsGhs8lMHxujeM2ngEYEiIxn9GjtnNGqdagcfIgf99WXLvegmv321Go1KhsHem7Iraq3eXGCVGXitISChL24DtgTNVEEEChUHLTG39dtG1oxDxCI+bVOG7rGUB+3G5MJXo09s4o1Bq0Th7kxPyIZ/db8ex5GwqVBrWtI0PfO/r3mJcZJ4QQounJZFAI0SgUCgVgbeo06mTS54LVisbRvd5tLaYysrd/TF7MFkpzj2EuKQCLBaul4mzA2X8qlHSY8RFJq6eT8M5klFpbHIN749J1KF6D70dt71K/OFGTtbLGKuutcTRm3w2lTJ8DVitapyur5+O/fER29BaMORmYSgqw1lLPCoWSnk9+wqF3p3FgxURUWluc2/XBo9tQ/G6KQOPgUq84cTHW66LuhBDXP1lNVAjRKBwcHKDc2NRp1EmhrPzxZzGX1btt4soppK9fiEvnm+nyzHeEvXmUfqtS8Rp8f41Yh6Du9HzxT7o88y2t7niUitJiMtYvYv+zgyg5FlvvOFFdRWkxAE5OTo02hq29AxVlZxqt/4agUKoAsJjK69324NuPkfDlAty73kzfeRsZujKe29am43dzRI1YpzbdGbx0J2FzNxJ412NUGItI/HIhO/9vAEUZsfWOE7WzlpXg6OjY1GkIIVoAuTMohGgUPj4+mAt3N3UaddK6tgKFElNhTr3alRdmU3BgGx5ho/AfObvaubK8zNobKRQ4tgvDsV0YrcfMoSglhiMvjyVz0+u0n762/nHnaYgFZK5n5YWngMp6ayze3j6U5mU1Wv8NwcbNF4VCSVlhdr3alRWcInffT/j0H03wmCernTOerrueXULDcAkNI2Tc0xQm/0X04jGkfLOMHrM+rH/ceRpiAZkbganwFD4+A5s6DSFECyCTQSFEo+jWrRtFWa9iKTei1No2dTo1KFRqHEP6oI/fhcVUhlKjqzp3cP6tKDU2dH1hS4121rN3EtUObtWOG08mYUjYUxlz9tFFQ0IkSWum02Hmp9i37lQV6xjcG42LF6bignrF1aalLyBTknEYtVpDhw4dGm2Mnt27sTvjcKP13xAUKg3O7fqQf7RmPe9+7hZUGh39FvxYo53FXHknUetYvZ5LspIoiI8EwHr2ce+C+EgOvTuNXk99hmPA3xM2l5A+6Fy8KC/Or1dcbWQBGagoO4PhRDJdu176Qx4hhLha8pioEKJR3HzzzVgtFeiP7mjqVOoUOO45LKZSktc8gcmQi/mMgWPfvsKZzHi8h0yotY3O3R8bz0Dy9//ImRPxWExlFBz6jYR3JuPedzgAxWkHsVoqcGjTA4VSTcoHMylO3Y/FVIa5pJCT21ZTnp+F9z8qH8O73DhRU2Hs7/QbMBCdTnfp4Ct0yy1DyY/bicVsarQxGkLofS9gMZVy+L3HKddX1nPyVy9TfDwO/1v+VWsbGw9/bL0Cyf7rB4ozK+v59MFfObBiIt5hIwAwpB7AaqnAqW0PlCo1satmok/Zh8VUhqm4kIwfV1Gal4X/kAcALjtO1C7/yA4slgqGDBnS1KkIIVoAhfXcR9hCCNHA+g8cTKrZjZApK5s6lToVJUdz/LtXKU4/BFYrtq3a0erOqbj3ubsqJm75gxiSouj3bhIAJcePkv7lPErSD6FQqXAI7kPguOdQ6uyIX/EvSrPTaTVsGgFjnqY8P4vjG5dRePRPTIZcVDaO2PqG4HvrRNz7jqga43LjGkPG+oVk/bSqzvMe/cfS7pG3GjWHK1FRWsyBp3rz6ssvMmPGjEYbJzMzk8CgILpMfReffiMbbZyGUJgYTfLXSzGkHQSrFXu/UIKGTcU7bHhVTMzSCAoTo7j1/RQAio4dIf7TuRjSD6FQqnBp14d29z2PWmfPvmXjOZOdTpvhjxMy7hlK87JI+fY18mL/oFyfi8rWEXvfEALumFTte3O5cY0h8csFpP9Q988c34Fj6Tr1nUbN4WocfvsRAlWFRO5qvh+kCSFuGBtkMiiEaDSfffYZ/354It0WbsfGu01TpyNuMFlb3yP7+9fJOpGJq6tro441YuQodscdp8+8LSCrPIpGcuZUKpHPDuGjD9cyfvz4pk5HCHHj2yCPiQohGk1ERAQdOnbk+PoFTZ2KuMGYDLmc/OFNnp7zf40+EQR4eclL6NMOk7VzQ6OPJVqupC/mE9KuHfffX3NlYiGEaAwyGRRCNBqVSsXbb67g9IGfKTj0W1OnI24gx79egoerM3PmzLkm43Xu3JnHHnuUtK9ewmwsuiZjipbl9MFfyd7/CyvffQe1Wtb3E0JcGzIZFEI0qiFDhnDf/RGkfzSLstPHmzodcQPI3b2BnF3reWvFG9jZ2V2zcRcuXIitCo6snI7Varlm44obn/H0ceLe/w/33R8hC8cIIa4pmQwKIRrd2g/ep2NIG5LenID5jKGp0xHXsaKkKNI+eZpnn32WsWPHXtOx3d3d+fGH79HH7STpf4uu6djixmUuLebw8ocIDvDj/TWrmzodIUQLI5NBIUSjs7OzY+O3X2NjLibp7YcwX2TfPCHqYkjcS9I7Exk5YjiLFjXNZKxPnz6s/eB9Mn5cRco3r4GswSaugqm4gIPLxqMtK+SH7zfj4ODQ1CkJIVoYmQwKIa6J1q1bs/3Xn3EwZhO3ZATGk8lNnZK4juTu3kD8svsZdvstfP7ZpyiVTfe/r4iICFatWkXG5jc5svJxLKayJstFXL+z2AacAAACXklEQVRKspL5a+Hd2J45xW+//kzr1q2bOiUhRAskk0EhxDXTuXNnYqKj6BToQ9ySkZz67UOsFnNTpyWaMZMhl9QPZ5OydhZz/u9Jvv5qA7a2tk2dFo888ghbt/5I0dHfiVk4nMLEqKZOSVwnrBVmjv28lr8WDadjgA8x0VF07ty5qdMSQrRQss+gEOKaKy0tZcGCBSx7fTm23m1oNfZ5XLsOAYV8PiUqVZQWk/37p5zcsgIPNxfefnMFY8aMaeq0akhOTmbqtMf59Zef8R04hrajn8TOp21TpyWaIavVQt6h7aSuX0zJqTSenD2L+fPnY2Nj09SpCSFaLtl0XgjRdJKTk5k1+0m+37wJB58gnHoOw7nDQOz8OqB2cEOp0TV1iuIaqTAWUV5wkpJjsRTG/o7+wE8osfD0nP9jzpw513TV0CuxadMmZs56koy0FDw6DsCt5524hPTGzrsNagcXFPJBR4tjMZVRXpRPcWY8+Ud3kR+zBcOpdIaPGMny15cREhLS1CkKIYRMBoUQTe/IkSN8+OGHfLtxE6nJSU2djmhCKpWaAYMGce89Y5kwYcI12VC+oVRUVPDDDz/w+edf8OPWnzDoZaEkUaltSDvGjh7Fww8/TKdOnZo6HSGEOEcmg0KI5iU/P5+jR49SUFBAaWlpU6cjrhFHR0e8vb3p1KkTOt31f0fYarWSnp5OamoqhYWFWCyyL2FLo9PpcHV1pXPnzri5uTV1OkIIURuZDAohhBBCCCFEC7RBXmIQQgghhBBCiBZIJoNCCCGEEEII0QLJZFAIIYQQQgghWqD/B23Qtq6uOhfiAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 106 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vv7GKBvs6Ybf" + }, + "source": [ + "# Função desenvolvida para Selecionar COLUNAS relevantes\n", + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_treinamento, X_teste, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_treinamento_I = sfm.transform(X_treinamento)\n", + " X_teste_I = sfm.transform(X_teste)\n", + " return X_treinamento_I, X_teste_I " + ], + "execution_count": 107, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf", + "outputId": "afd9f4fa-535f-4da0-c736-3c606ef53568", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "X_treinamento_DT, X_teste_DT = seleciona_colunas_relevantes(ml_DT2, X_treinamento, X_teste)" + ], + "execution_count": 108, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "********** COLUNAS Relevantes ******\n", + "[ 0 9 12]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm", + "outputId": "c4af1a97-2585-40ee-e144-d15260fbbef1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "best_params" + ], + "execution_count": 109, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 20,\n", + " 'min_samples_split': 70}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 109 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt", + "outputId": "bf2faa39-ed81-4f33-8b9d-9c4d10c2147b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_treinamento_DT, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT2, X_treinamento_DT, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": 110, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 88.71\n", + "std médio das Acurácias calculadas pelo CV: 2.5100000000000002\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Tc7esxqtq-Og" + }, + "source": [ + "****************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3" + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_parametros_DT, X_treinamento_DT, y_treinamento, X_teste_DT, y_teste, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q" + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SbS4ZKN8s-ee" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT3, X_treinamento_DT, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_at3XP1Bq-qb" + }, + "source": [ + "***************************************************************" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_teste_DT)" + ], + "execution_count": 111, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae", + "outputId": "1e931808-3887-4e6a-b27b-329ea9776e1e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_DT)" + ], + "execution_count": 112, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9333333333333333" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 112 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier)quanto para Regressão (RandomForestRegressor).\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * É um Boosting Ensemble Method (pois constrói muitas árvores). Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como Feature Selection, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer os dados sejam normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Desvantagens**\n", + " * **Recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais parâmetros do Random Forest." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu", + "outputId": "83f52ce2-ac65-4e96-aa5d-ce5fb204511c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia...\n", + "ml_RF= RandomForestClassifier(n_estimators=100, min_samples_split= 2, max_features=\"auto\", random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_treinamento, y_treinamento)" + ], + "execution_count": 113, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=100,\n", + " n_jobs=None, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 113 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lYa9oaZW__o6" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF, X_treinamento, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_RF= {'bootstrap': [True, False]} #,\n", + "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n", + "# 'max_features': ['auto', 'sqrt'],\n", + "# 'min_samples_leaf': [1, 2, 4],\n", + "# 'min_samples_split': [2, 5, 10],\n", + "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat" + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_parametros_RF, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMJcAdLlTQa0" + }, + "source": [ + "## Visualizar o resultado\n", + "> Implementar a visualização do RandomForest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "X_treinamento_RF, X_teste_RF = seleciona_colunas_relevantes(ml_RF2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF2.fit(X_treinamento_RF, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_RF2, X_treinamento_RF, y_treinamento, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF2.predict(X_teste_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos parametros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "navUWMwHi44D" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name=\"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting vc Stacking\n", + "### **Bagging**\n", + "* Objetivo é reduzir a variância;\n", + "\n", + "#### Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_treinamento;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n", + "\n", + "#### Vantagens\n", + "* Reduz overfitting;\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "___ \n", + "### **Boosting**\n", + "* Objetivo é melhorar acurácia;\n", + "\n", + "#### Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_treinamento;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_treinamento e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_treinamento a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n", + "\n", + "#### Vantagens\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + "* Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fgUrkmPk4dr" + }, + "source": [ + "___\n", + "# STACKING\n", + "\n", + "![Stacking](https://github.com/MathMachado/Materials/blob/master/Stacking.png?raw=true)\n", + "\n", + "Kd a referência desta figura???" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0jxx3ETpOdm" + }, + "source": [ + "___\n", + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Quando nada funciona, AdaBoost funciona!\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## O que é AdaBoost (Adaptive Boosting)?\n", + "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n", + "\n", + "## Parâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "No exemplo a seguir, vou usar RandomForestClassifier com os parâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Parâmetros otimizados!\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)\n", + "# Instancia AdaBoostClassifier\n", + "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_AB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A4Cs81OLD40y" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_AB, X_treinamento, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os parametros otimizados...\n", + "y_pred = ml_AB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_parametros_AB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos parâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB=GradientBoostingClassifier(n_estimators=100, min_samples_split= 2)\n", + "\n", + "# Treina...\n", + "ml_GB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-dr6dyjdXwvd" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB, X_treinamento, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os parâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_treinamento.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_parametros_GB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Parametros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_treinamento_GB, X_teste_GB = seleciona_colunas_relevantes(ml_GB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_treinamento_GB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_GB2, X_treinamento_GB, y_treinamento, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_teste_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Parâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os parâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB= XGBClassifier(silent=False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zAhsTtwGqMkG" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB, X_treinamento, y_treinamento, cv = i_CV)\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos parâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de parâmetros para XGBoost:\n", + "d_parametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_parametros_XGB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Parametros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_treinamento_XGB, X_teste_XGB= seleciona_colunas_relevantes(ml_XGB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_treinamento_XGB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_XGB2, X_treinamento_XGB, y_treinamento, cv = i_CV)\n", + "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n", + "print(f'std médio.....: {100*a_scores_CV.std():.2f}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_teste_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM\n", + "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "# **IMPORTANCIA DAS COLUNAS**\n", + "Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_treinamento, y_treinamento=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_treinamento and y_treinamento are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_treinamento (pandas DataFrame)\n", + " \n", + " y_treinamento (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_treinamento.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_treinamento, y_treinamento, top_n=X_treinamento.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Uf1RML7xETY" + }, + "source": [ + "# WOE e IV\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TBNRfYZCyhMP" + }, + "source": [ + "## Construção do exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gIIroyyP4ZRZ" + }, + "source": [ + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PzQQdrkf1ohX" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n", + "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n", + "df_X2['target']= df_y['target']\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-OpwIpx4hXJ" + }, + "source": [ + "df_X2['target'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yZfqSvbKzeJ3" + }, + "source": [ + "def Constroi_Buckets(df, i, k= 10):\n", + " coluna= 'v'+ str(i)\n", + " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n", + " df= df.drop(columns= [coluna], axis= 1)\n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V6Nrpsx60HD3" + }, + "source": [ + "for i in np.arange(1,19):\n", + " df_X2= Constroi_Buckets(df_X2, i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2Fbh41-03OB" + }, + "source": [ + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O9r5BeWVxIr3" + }, + "source": [ + "# Função para calcular WOE e IV\n", + "def calculate_woe_iv(dataset, feature, target):\n", + "\n", + " def codethem(IV):\n", + " if IV < 0.02: return 'Useless'\n", + " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n", + " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n", + " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n", + " elif IV >= 0.5: return 'Suspicious'\n", + " else: return 'None'\n", + "\n", + " lst = []\n", + " for i in range(dataset[feature].nunique()):\n", + " val = list(dataset[feature].unique())[i]\n", + " lst.append({\n", + " 'Value': val,\n", + " 'All': dataset[dataset[feature] == val].count()[feature],\n", + " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n", + " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n", + " })\n", + " \n", + " dset = pd.DataFrame(lst)\n", + " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n", + " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n", + " dset['Mean']= dset['All']/dset['All'].sum()\n", + " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n", + " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n", + " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n", + " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n", + "\n", + " dset['Predictive_Power']= dset['IV'].map(codethem)\n", + " iv = dset['IV'].sum() \n", + " dset = dset.sort_values(by='IV') \n", + " return dset, iv" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8WGjWH63nx_" + }, + "source": [ + "df_Lab = df_X2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-N6xr1MgxTiz" + }, + "source": [ + "def calcula_Predictive_Power(df_Lab, coluna):\n", + " print('WoE and IV for column: {}'.format(coluna))\n", + " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n", + " print(df)\n", + " print('IV score: {:.2f}'.format(iv))\n", + " print('\\n')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayqN_7WnxVq9" + }, + "source": [ + "for i in np.arange(1,19):\n", + " coluna= 'v'+str(i)+'_Bucket'\n", + " calcula_Predictive_Power(df_Lab, coluna)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aZUNOgmSgAmq" + }, + "source": [ + "!pip install featuretools" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_sxdONzsh9rb" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p5_ynGo1dBJJ" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TqJRJXUhiDqf" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n", + "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n", + "df_X2['id'] = range(0,1000)\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nR56bGGngk-W" + }, + "source": [ + "# Automated feature engineering\n", + "import featuretools as ft\n", + "import featuretools.variable_types as vtypes\n", + "\n", + "es= ft.EntitySet(id = 'simulacao')\n", + "\n", + "# adding a dataframe \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n", + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOJ4Tr5Ogk6M" + }, + "source": [ + "es['df_X2'].variables" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1uXPqHDZgkys" + }, + "source": [ + "variable_types = {'idade': vtypes.Categorical}\n", + " \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n", + "\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dnbYTBqugkvm" + }, + "source": [ + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I2v_jetdgkr7" + }, + "source": [ + "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZiRBvHXgkoJ" + }, + "source": [ + "feature_matrix.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JYVM3StS-g0E" + }, + "source": [ + "### Importar as libraries necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dyliPChh-jPk" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": 114, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lAl9ZwP_0-d0" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv'\n", + "df_cc = pd.read_csv(url)" + ], + "execution_count": 115, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w6lN8FjJ12VU", + "outputId": "f7a75b8d-f178-442f-e00b-4ed17485cd80", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 379 + } + }, + "source": [ + "df_cc.head(10)" + ], + "execution_count": 116, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TimeV1V2V3V4V5V6V7V8V9V10V11V12V13V14V15V16V17V18V19V20V21V22V23V24V25V26V27V28AmountClass
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.620.0
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.690.0
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.660.0
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.500.0
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.990.0
52-0.4259660.9605231.141109-0.1682520.420987-0.0297280.4762010.260314-0.568671-0.3714071.3412620.359894-0.358091-0.1371340.5176170.401726-0.0581330.068653-0.0331940.084968-0.208254-0.559825-0.026398-0.371427-0.2327940.1059150.2538440.0810803.670.0
641.2296580.1410040.0453711.2026130.1918810.272708-0.0051590.0812130.464960-0.099254-1.416907-0.153826-0.7510630.1673720.050144-0.4435870.002821-0.611987-0.045575-0.219633-0.167716-0.270710-0.154104-0.7800550.750137-0.2572370.0345070.0051684.990.0
77-0.6442691.4179641.074380-0.4921990.9489340.4281181.120631-3.8078640.6153751.249376-0.6194680.2914741.757964-1.3238650.686133-0.076127-1.222127-0.3582220.324505-0.1567421.943465-1.0154550.057504-0.649709-0.415267-0.051634-1.206921-1.08533940.800.0
87-0.8942860.286157-0.113192-0.2715262.6695993.7218180.3701450.851084-0.392048-0.410430-0.705117-0.110452-0.2862540.074355-0.328783-0.210077-0.4997680.1187650.5703280.052736-0.073425-0.268092-0.2042331.0115920.373205-0.3841570.0117470.14240493.200.0
99-0.3382621.1195931.044367-0.2221870.499361-0.2467610.6515830.069539-0.736727-0.3668461.0176140.8363901.006844-0.4435230.1502190.739453-0.5409800.4766770.4517730.203711-0.246914-0.633753-0.120794-0.385050-0.0697330.0941990.2462190.0830763.680.0
\n", + "
" + ], + "text/plain": [ + " Time V1 V2 V3 ... V27 V28 Amount Class\n", + "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n", + "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n", + "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n", + "5 2 -0.425966 0.960523 1.141109 ... 0.253844 0.081080 3.67 0.0\n", + "6 4 1.229658 0.141004 0.045371 ... 0.034507 0.005168 4.99 0.0\n", + "7 7 -0.644269 1.417964 1.074380 ... -1.206921 -1.085339 40.80 0.0\n", + "8 7 -0.894286 0.286157 -0.113192 ... 0.011747 0.142404 93.20 0.0\n", + "9 9 -0.338262 1.119593 1.044367 ... 0.246219 0.083076 3.68 0.0\n", + "\n", + "[10 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 116 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M47GS1cK2NdD", + "outputId": "e402576c-cee8-4d09-b776-04fdddf9c2b0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_cc.shape" + ], + "execution_count": 117, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12842, 31)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 117 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b2QBZFbR3W_q", + "outputId": "5a8ed763-f794-4bd8-b846-63d36101f9e8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "df_cc['Class'].value_counts()" + ], + "execution_count": 118, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.0 12785\n", + "1.0 56\n", + "Name: Class, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 118 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pzjW3Bf_3h7J", + "outputId": "4949014a-3f1a-4565-d7b0-213362ef9156", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "56/12842" + ], + "execution_count": 119, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.004360691481077714" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 119 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9bWDX9H12k5g" + }, + "source": [ + "### Drop NaN" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "27ob8tRR21TB", + "outputId": "ea900ea1-79f6-413e-8cb6-ae0492293547", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 561 + } + }, + "source": [ + "df_cc.isna().sum()" + ], + "execution_count": 120, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Time 0\n", + "V1 0\n", + "V2 0\n", + "V3 0\n", + "V4 0\n", + "V5 0\n", + "V6 0\n", + "V7 0\n", + "V8 0\n", + "V9 0\n", + "V10 1\n", + "V11 1\n", + "V12 1\n", + "V13 1\n", + "V14 1\n", + "V15 1\n", + "V16 1\n", + "V17 1\n", + "V18 1\n", + "V19 1\n", + "V20 1\n", + "V21 1\n", + "V22 1\n", + "V23 1\n", + "V24 1\n", + "V25 1\n", + "V26 1\n", + "V27 1\n", + "V28 1\n", + "Amount 1\n", + "Class 1\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 120 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X9k16WLI49JI", + "outputId": "3de3f96c-5f76-4763-ced1-953c0646612e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_cc2 = df_cc.copy()\n", + "df_cc2 = df_cc.dropna()\n", + "df_cc2.shape" + ], + "execution_count": 71, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12841, 31)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 71 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OY-DYRKg34ZX" + }, + "source": [ + "### Definir as variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KVhHgV_s3_5f" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": 121, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbqrF4Q2nBq" + }, + "source": [ + "### Define amostras de treinamento e teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N8CUAiA57OhS", + "outputId": "9e6169f9-9930-4c60-df3f-34e831469da8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_cc.head()" + ], + "execution_count": 122, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
TimeV1V2V3V4V5V6V7V8V9V10V11V12V13V14V15V16V17V18V19V20V21V22V23V24V25V26V27V28AmountClass
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.620.0
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.690.0
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.660.0
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.500.0
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.990.0
\n", + "
" + ], + "text/plain": [ + " Time V1 V2 V3 ... V27 V28 Amount Class\n", + "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n", + "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n", + "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 122 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LZjNUDNb7s1t", + "outputId": "c0ec58c1-72b6-4621-b96a-f1987534409d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "# Definição do dataframe contendo as variáveis preditoras:\n", + "df_X = df_cc2.copy()\n", + "df_X.drop(columns= ['Class'], axis = 1, inplace = True)\n", + "df_X.head()" + ], + "execution_count": 123, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
TimeV1V2V3V4V5V6V7V8V9V10V11V12V13V14V15V16V17V18V19V20V21V22V23V24V25V26V27V28Amount
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.62
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.69
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.66
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.50
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.99
\n", + "
" + ], + "text/plain": [ + " Time V1 V2 V3 ... V26 V27 V28 Amount\n", + "0 0 -1.359807 -0.072781 2.536347 ... -0.189115 0.133558 -0.021053 149.62\n", + "1 0 1.191857 0.266151 0.166480 ... 0.125895 -0.008983 0.014724 2.69\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.139097 -0.055353 -0.059752 378.66\n", + "3 1 -0.966272 -0.185226 1.792993 ... -0.221929 0.062723 0.061458 123.50\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.502292 0.219422 0.215153 69.99\n", + "\n", + "[5 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 123 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d3DDsN2V7IOU", + "outputId": "ac1843d4-50bb-49f6-b434-eb400ade1c38", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "df_y = df_cc2['Class'] # Variável-resposta\n", + "df_y.head()" + ], + "execution_count": 131, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 0.0\n", + "1 0.0\n", + "2 0.0\n", + "3 0.0\n", + "4 0.0\n", + "Name: Class, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 131 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aMthdXHD8vnh", + "outputId": "f2aec987-220f-4c58-9a6d-60f2c21a86ab", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_y.shape" + ], + "execution_count": 132, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12841,)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 132 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EiJRftpZ2103" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": 125, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TmSkPzNt8O6I", + "outputId": "76a362af-dbb3-4e48-e1a0-968c429e555a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": 126, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(8988, 30)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 126 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9h1PjPKh8Xb1", + "outputId": "44f90b9c-0968-40f8-bb7c-43f7bd93a8c3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": 127, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(3853, 30)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 127 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NbCN_puI2qk1" + }, + "source": [ + "### Ajusta o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hjRwSI079ADn" + }, + "source": [ + "# Importar o classificador (modelo, algoritmo, ...)\n", + "from sklearn.tree import DecisionTreeClassifier # Este é o nosso classificador" + ], + "execution_count": 128, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HuhKJOQA22bR", + "outputId": "2f648705-8bc5-4965-83d4-71005c80cd5c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "ml_DT = DecisionTreeClassifier(max_depth = 5, min_samples_split = 2, random_state = i_Seed)\n", + "ml_DT" + ], + "execution_count": 129, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=5, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 129 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zai1d6eM93VQ", + "outputId": "97e92d12-b2b5-4560-ebf8-0cd5b40567f3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Treinar o algoritmo/classificador: fit(df)\n", + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": 130, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=5, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 130 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ybbS4zHn-8BO", + "outputId": "b9c3cef3-0748-407e-8213-9f04692257b0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = cross_val_score(ml_DT, X_treinamento, y_treinamento, cv = i_CV)\n", + "\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(), 4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(), 4)}')" + ], + "execution_count": 133, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 99.9\n", + "std médio das Acurácias calculadas pelo CV: 0.09\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r_NLku7q_YT9", + "outputId": "cb2666bb-dee9-4640-a7fa-bdae648df9b8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": 134, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1. , 0.99888765, 0.99777531, 0.99777531, 1. ,\n", + " 0.99888765, 1. , 0.99888765, 0.99777283, 1. ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 134 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bCRgHxUu2s7c" + }, + "source": [ + "### Cross-Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2wMWm-p5229A" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Am_UELOg2vDh" + }, + "source": [ + "### Fine tuning dos parâmetros" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lF9mxe7y23hr" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bG31I7_n4RQg" + }, + "source": [ + "### Aplicar as transformações (principais) estudadas e reestimar o modelo novamente\n", + "* Qual o impacto das transformações?\n", + "* A conclusão muda/mudou?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP_hs4.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP_hs4.ipynb new file mode 100644 index 000000000..1025a0945 --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning___DSWP_hs4.ipynb @@ -0,0 +1,8583 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n", + "* Conceitos estatísticos de bias & variance;\n", + "* Ver Sklearn.optimize: https://web.telegram.org/#/im?p=g497957288;\n", + "* Construir a package para conter todas as funções definidas e colocar estas funções na package --> Manutenção rápida, fácil e centralizada! Desta forma, o tópico (\"Funções usadas neste tutorial\") vai totalmente para o package." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XRukccWQSklx" + }, + "source": [ + "## Medidas para avaliarmos a variabilidade presente nos dados\n", + "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n", + "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n", + "\n", + "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância --> Principal medida para medir a variabilidade presente nos dados.\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING** (= Parâmetros ótimos dos modelos de Machine Learning)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos parâmetros dos modelos de ML)\n", + "* Encontra os parâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os parâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gkCubyUCP_hn" + }, + "source": [ + "### Funções usadas neste tutorial" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZD2pH9hfTnZv" + }, + "source": [ + "#### Função para Cross-Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hr8LczrSQB0x" + }, + "source": [ + "" + ], + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "#### Função para plotar a Confusion Matrix\n", + "* Extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, \n", + " figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8J-sTUfTTdLi" + }, + "source": [ + "#### Função para o GridSearchCV" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs = -1, verbose= 10, scoring = 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n", + " tempo_elapsed = time()-start\n", + " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Parâmetros que otimizam a classificação:\n", + " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os parametros otimizados...\n", + " ml_Opt.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = funcao_cross_val_score(ml_Opt, X_treinamento, y_treinamento, i_CV)\n", + "\n", + " # Faz predições com os parametros otimizados...\n", + " y_pred = ml_Opt.predict(X_teste)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_teste, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YMnQn2XgT7Mg" + }, + "source": [ + "#### Função para selecionar COLUNAS relevantes dos dataframes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsnHcaeLUDFS" + }, + "source": [ + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_treinamento, X_teste, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_treinamento_I = sfm.transform(X_treinamento)\n", + " X_teste_I = sfm.transform(X_teste)\n", + " return X_treinamento_I, X_teste_I " + ], + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gd98JFSGUV5n" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "### Função para calcular a importância das colunas/variáveis/atributos\n", + "* Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_treinamento, y_treinamento=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_treinamento and y_treinamento are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_treinamento (pandas DataFrame)\n", + " \n", + " y_treinamento (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_treinamento.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "X, y = make_classification(n_samples = 1000, \n", + " n_features = 18, \n", + " n_informative = 9, \n", + " n_redundant = 6, \n", + " n_repeated = 3, \n", + " n_classes = 2, \n", + " n_clusters_per_class = 1, \n", + " random_state=i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gWy2IZh3s-o3", + "outputId": "7971af09-b2a0-45a4-e59b-5311f981e367", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 240 + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0.06844089, 4.21184154, -2.5583024 , ..., -0.63061895,\n", + " -0.97831983, -0.88826977],\n", + " [-4.8240213 , 0.17950903, -2.98447332, ..., 0.33992045,\n", + " 1.89153784, -6.10967565],\n", + " [ 1.38953042, -0.226476 , 1.8774004 , ..., -1.47784549,\n", + " 0.96052606, 2.06020368],\n", + " ...,\n", + " [ 1.62548685, 0.43377848, 4.93537285, ..., -4.61990917,\n", + " 0.18310709, 6.16040231],\n", + " [-2.40619087, -1.65474635, 2.64196493, ..., -1.21427845,\n", + " 0.83745861, 0.8254619 ],\n", + " [-4.00041881, 2.52475556, -4.15290177, ..., -0.51680266,\n", + " 1.72224835, -5.59558306]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccjhGnzxtAaV", + "outputId": "1e5b7a88-9c9c-4a81-ab35-251e6c0aa3df", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y[0:30] # Semelhante aos casos de fraude: {0, 1}" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "6427f328-d63c-4845-d20c-92938031305d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 223 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
00.0684414.211842-2.5583023.665482-3.8351583.4998512.4908563.6654820.2451170.8671722.8655460.493956-5.1485962.8655463.499851-0.630619-0.978320-0.888270
1-4.8240210.179509-2.9844731.033618-3.8934263.428734-3.3346051.033618-0.882780-0.7532811.441522-1.395514-4.0028801.4415223.4287340.3399201.891538-6.109676
21.389530-0.2264761.8774002.7134264.6302570.516455-3.7430272.7134261.2840392.030797-1.0955361.560159-1.014211-1.0955360.516455-1.4778450.9605262.060204
31.1458092.2559460.2073644.6658172.2946786.5013060.9647704.6658170.1194103.1963541.8947873.519138-4.7578071.8947876.501306-3.7890290.5794911.397106
4-0.9366463.697163-3.3636173.805126-1.7544304.9543460.4066053.805126-0.8247381.3825911.665704-0.649758-3.5130361.6657044.9543460.2570520.904244-3.071354
\n", + "
" + ], + "text/plain": [ + " v1 v2 v3 ... v16 v17 v18\n", + "0 0.068441 4.211842 -2.558302 ... -0.630619 -0.978320 -0.888270\n", + "1 -4.824021 0.179509 -2.984473 ... 0.339920 1.891538 -6.109676\n", + "2 1.389530 -0.226476 1.877400 ... -1.477845 0.960526 2.060204\n", + "3 1.145809 2.255946 0.207364 ... -3.789029 0.579491 1.397106\n", + "4 -0.936646 3.697163 -3.363617 ... 0.257052 0.904244 -3.071354\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "1dedf9d5-1a8d-47a3-b665-4ce84f870b0b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "faeca466-1081-47e0-bb69-1bff8c00f51e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "9ea27467-c83e-4654-9703-1947ada7f50b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 315 + } + }, + "source": [ + "df_X.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
count1000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000000
mean-0.0851591.0342270.6574081.4053170.6872791.1315600.1080531.4053171.0070231.0488010.0792480.001650-0.3654380.0792481.131560-0.0277510.9846060.633624
std2.0022471.6315073.6087722.2568574.0195984.4818321.9813072.2568571.8632881.6439001.9492731.9326414.1606681.9492734.4818322.0654551.8505933.552991
min-6.944169-4.620754-16.300139-6.235192-12.454256-14.305401-6.152747-6.235192-5.484992-3.293216-7.135349-5.705500-9.120941-7.135349-14.305401-6.009023-5.035184-11.439074
25%-1.305566-0.089052-1.623657-0.152888-1.854645-1.684751-1.216983-0.152888-0.240908-0.012710-1.209675-1.292162-3.555363-1.209675-1.684751-1.436673-0.261610-1.691346
50%0.0525230.9941500.5738491.4499310.8123641.2815040.1670911.4499311.0661251.0128990.1803440.035237-0.9666380.1803441.281504-0.0001900.9757930.844784
75%1.3838532.0719953.0385862.8871413.4139524.0081031.4387192.8871412.2881882.1872021.4391991.3153422.7458061.4391994.0081031.3653692.2565043.109330
max4.9971727.35486011.7201658.49456612.84441815.9998036.2935508.4945668.1465596.5231806.2524485.53821611.2593506.25244815.9998036.5315617.64680212.090528
\n", + "
" + ], + "text/plain": [ + " v1 v2 ... v17 v18\n", + "count 1000.000000 1000.000000 ... 1000.000000 1000.000000\n", + "mean -0.085159 1.034227 ... 0.984606 0.633624\n", + "std 2.002247 1.631507 ... 1.850593 3.552991\n", + "min -6.944169 -4.620754 ... -5.035184 -11.439074\n", + "25% -1.305566 -0.089052 ... -0.261610 -1.691346\n", + "50% 0.052523 0.994150 ... 0.975793 0.844784\n", + "75% 1.383853 2.071995 ... 2.256504 3.109330\n", + "max 4.997172 7.354860 ... 7.646802 12.090528\n", + "\n", + "[8 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "\n", + "* Dividir os dados/amostras em:\n", + " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n", + " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n", + "* **Técnica de Hold-Out**: Separar/dividir os dados em amostra de treinamento e teste. Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + " * **Desvatangem do Hold-Out**: Variância nos dados pode comprometer performance do modelo quando, por exemplo, amostra de treinamento é semelhante amostra de teste. \n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "14ff5eb3-d8a8-4475-a783-58ff2657943b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "2da233e6-1f0e-449f-ce61-8e3f9bcb3076", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "247633e0-375c-4f2c-e21b-ff394cb7850a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "efe6513a-ac85-468a-ac49-32d4ddd4266f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "13d2f619-2128-43da-b1df-e2e3253928a8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score # Para o CV (Cross-Validation)\n", + "from sklearn.model_selection import cross_validate\n", + "\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n", + "\n", + "# Instancia (configuração do Decision Trees) com os parâmetros sugeridos para se evitar overfitting:\n", + "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split = 2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, \n", + " class_weight = None, \n", + " presort = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gVLZznprx2YX", + "outputId": "c2cd5eff-b03f-4c15-f42e-8c0862e2b45f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 120 + } + }, + "source": [ + "# Objeto/classificador configurado\n", + "ml_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8CC24H-JHhlj" + }, + "source": [ + "### Treina o algoritmo: fit(df)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "c760acbb-3017-4181-cf88-118990fc43d5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 120 + } + }, + "source": [ + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oNVgVA4Bqy2m" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CNiRjmrRHVnx" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2GMCSs89HquJ", + "outputId": "722edff2-b895-4ed2-ab48-77c6763bb009", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bmv9YZobIer4" + }, + "source": [ + "### Calcula as predições usando o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2YufZaRNIkFL" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fYvMN-tvIX-p" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9iTK6pBwIZ3F", + "outputId": "2cfe7aa6-a696-4169-dfac-8cb40a9d513b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAIJCAYAAADQ9vbrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdd3gVRdvH8e+dAqF3EEGkKlVpIlXpAiJFpAmKgiIiAooF1MfuK3YsFFFQEEERQbHQRBFB6RY6IkhvEnoIpMz7xznE5NDCmpDk5Pd5r3NxdnZ3ZjaPb+7cM7uz5pxDRERE/hWS1h0QERFJbxQcRUREAig4ioiIBFBwFBERCaDgKCIiEkDBUUREJEBYalSarVo/PR8iGd6Bpe+kdRdEUkREGJZadafG7/vjv76Tav1NLmWOIiIiAVIlcxQRkUzCgjPHCs6rEhER+Q+UOYqIiHeW5tODqUKZo4iISABljiIi4l2QzjkqOIqIiHcaVhUREckclDmKiIh3QTqsGpxXJSIi8h8ocxQREe+CdM5RwVFERLzTsKqIiEjmoMxRRES8C9JhVWWOIiKS4ZjZWDPba2arzrBvkJk5Myvo3zYze8vMNprZH2ZW/Xz1KziKiIh3FpLyn+T5EGhxWnfMLgOaA1sTFbcEyvk/vYGR56tcwVFERLwzS/lPMjjn5gORZ9j1BvAIkPglzG2B8c5nEZDXzIqeq34FRxERCQpm1hbY4Zz7PWBXMWBbou3t/rKz0g05IiLiXSo8ymFmvfENf54y2jk3+jznZAcewzek+p8pOIqISLriD4TnDIZnUAYoBfxuvqHZ4sAKM6sF7AAuS3RscX/ZWSk4ioiId+nkUQ7n3Eqg8KltM/sbqOmc+8fMpgP9zOwT4FrgkHNu17nq05yjiIhkOGY2CfgFuNLMtptZr3Mc/i2wCdgIvAf0PV/9yhxFRMS7NFo+zjnX9Tz7Syb67oD7LqR+BUcREfFOa6uKiIhkDsocRUTEu5D0cUNOSlPmKCIiEkCZo4iIeBekc44KjiIi4l06ec4xpQVnyBcREfkPlDmKiIh3QTqsGpxXJSIi8h8ocxQREe+CdM5RwVFERLzTsKqIiEjmoMxRRES8C9JhVWWOIiIiAZQ5ioiId0E656jgKCIi3mlYVUREJHNQ5igiIt4F6bBqcF6ViIjIf6DMUUREvNOco4iISOagzFFERLwL0jlHBUcREfEuSINjcF6ViIjIf6DMUUREvNMNOSIiIpmDMkcREfEuSOccFRxFRMQ7DauKiIhkDsocRUTEuyAdVg3OqxIREfkPlDmKiIh3QTrnqOAoIiKeWZAGRw2rioiIBFDmKCIinilzFBERySSUOYqIiHfBmTgqcxQREQmkzFFERDwL1jlHBUcREfEsWIOjhlVFREQCKHMUERHPlDmKiIhkEsocRUTEs2DNHBUcRUTEu+CMjRpWFRERCaTMUUREPAvWYVVljiIiIgGUOYqIiGfBmjkqOIqIiGfBGhw1rCoiIhJAmaOIiHimzFFERCSTUOYoIiLeBWfiqMxRREQyHjMba2Z7zWxVorJXzGydmf1hZtPMLG+ifUPMbKOZrTezG85Xv4KjiIh4ZmYp/kmmD4EWAWVzgMrOuauADcAQfx8rAl2ASv5zRphZ6LkqV3AUERHP0io4OufmA5EBZbOdc7H+zUVAcf/3tsAnzrkTzrnNwEag1rnqV3AUEZF0xcx6m9myRJ/eHqrpCczwfy8GbEu0b7u/7Kx0Q46IiHiWGo9yOOdGA6O9nm9mjwOxwMde61BwFBGRoGFmdwCtgSbOOecv3gFcluiw4v6ys9KwqoiIeGep8PHaFbMWwCNAG+dcVKJd04EuZpbVzEoB5YAl56pLmaOIiHiWVivkmNkkoCFQ0My2A0/huzs1KzDH369Fzrk+zrnVZjYZWINvuPU+51zcuepXcBQRkQzHOdf1DMVjznH8C8ALya1fwVFERDzT2qoiIiKZhDJHERHxLFgzRwVHERHxLFiDo4ZVRUREAihzFBER74IzcVTmeCHy58nBok8Gs+iTwWye83/8Nev5hO3wsHMu8H7B1n3zDJNevSthu33Tqox+pnuKtgHQ79aGZIsIT9ie9va95MmZLcXbkfSpWpUKdLq5bcJnx47tZz22ds1qKdZurztuo82NN9CxfRt6dOvC35s3XXAd9/W5m8OHD3P48GE+nfTvKmF79+5h0MD+KdZXyZyUOV6AyEPHqN1lKACP39OKY1EnGPbR3IT9oaEhxMXFp1h71SpcRvnSl7Bu0+4UqzNQv26NmPTtUo5HxwDQ/v6RqdaWpD9Zs0YweeqXadL2iy+9SqXKVZgy+VNef/Vl3ho+6oLOHz7qPQB27NjOp59MonPXbgAULlyE14a9leL9lTPTnKOc0ehnuvPW412YP/4h/m9gOx6/pxUDb2uSsH/ZZ49Romh+ALq0uoafPnqIRZ8M5u3HuxAScu7/qN786Hse7XX6OzmzR2Rh1FPd+Omjh/hl0qO0blgFgGwR4Ux4qScrPn+cT1+7m/njH6J6xRK+uh7rzIKPH2H5lMd5ok8rAPp2vZ6ihfIwc/QAZo72/aW97ptnKJA3B8/1b8M9na5LaDPxdT1wexMWTHiYJZ8OSahLgkPUsWPc3bMHnW9pT4d2N/HD99+ddsy+fXu58/ZudLq5LTe3bc2K5csA+HnhAm67tTOdb2nPQw/0J+rYsWS1WaNmTbZt3YpzjtdffYmb27amQ7ubmDnj23O217JZYw4ciOTNN15j+7atdLq5La+/+hI7dmzn5ratAejetRMbN/6Z0FavO25j9aqVREVF8eQTQ7i18y106tDujNcpmZsyxxRQrHBeGt7xGvHxjsfvOXOwuLJUEW5pXp1Gd75ObGw8w4Z0okura5j49dmX9/t89gp6d2xA6csKJil/9K4bmLd0A32e+Zg8ObPx04SH+X7Renp3bMCBw1FU7/ACFcsUZfEngxPOefqdrzhwOIqQEGPGu/2pXO5SRkz6kf7dG9Oi95vsP5j0F9mUWSt45eEOvDt5PgAdmlejTd/hNKldnjIlClO/+yuYGVOG3UO96mVYuOIvrz8+SUMnTkTT6ea2AFxavDivvv4mb7w1nJw5c3LgQCS3de1Mw0ZNkmQH337zNXXr1efue+4lLi6O6OjjHDgQyXvvjuTd9z8ge/bsjH1/NOPHfUCfvv3O24cf5/1A2SuuYO6c2axft47Ppn7JwQMHuLXzLdSoWfOM7SU24IFBbPzzz4QMOPHQ8A0tWjF75gzK9ivHvn172bdvL5UqV+GtYa9T69raPPv8ixw+fJhuXTpybe26ZM+ePSV+rJlKsGaOCo4pYOp3vxIf7855TKNaV1K9YgkWTHgEgGxZw9kXefSc58TFx/PG+O94uGdzZi9ck1DepE4Fbry+CgNv92VyEVnCuKxoPupWK807E+cBsOavXaz8c2fCOR2aV6fnzfUICw3hkkK5qVC6KKsS7Q/0+/rtFMqXi6KF8lAwX04OHo5i+56D3HdrI5rWKc8if+DNmS0rZUsUVnDMoAKHVWNiYnhr2OusWL6UEAth79497P/nHwoWKpRwTOXKVXjqiceIjY2lUeOmlK9QgWVLf2DTXxu5o3vXhHquqlr1nG0PefQhIrJGcGmxYgx+7H98NO4DWrS6kdDQUAoULEiNa65h9cqVZ2wvuZq3aEmfu3vSt19/Zs+cQbPmvhfH//LzAub98D3jPxgLwMkTJ9i9axely5RJdt3io+AoZxV1/ETC99i4uCTDpRFZfDe7mBkTvlrMk29Pv6C6J36zhId7NmfNxl0JZQZ0feh9/tyyN1l1XH5pAQbe1oT63V/m4JHjjH6mO1mznP9/+qnf/Ur7plUpUiA3U2av8F8HvDJ2NmM+X3hB1yEZw7dff8WBA5FMmjyV8PBwWjZrzImTJ5IcU6PmNYwdP4GffvyRJx8fzG097iRX7tzUrlOPl159PdltnZpzPJ8ztXdT23bJaqNIkSLkzZuXDevXMWvmDJ548mkAnIPXh71FyVKlk91fyVw055jCtuyMpGoF32vDqpYvTsliBQD4Ycl62jetSqF8OQHIlzs7JYrmO299sbHxvD3hB+7v1iih7Ltf1tK3y/UJ21dfWRyAX37bRIfm1QEoX/oSKpe9FIDcOSM4Fn2CQ0ejKZw/F83rVUw498ixE+TMHnHGtqfMWk7HG2rQvmk1ps75FYA5P6+lR9s65MiWBYBLC+VJuCbJ+I4ePUL+/AUIDw9nyeJF7Nx5+ivvdu7cQYECBenQsRPtO3Rk7ZrVXHV1VX77dQVbt2wBICoqir//3nxBbVerUZNZM2YQFxdHZGQkK5Yto3KVq87YXmI5cuQ45/zmDS1a8cHY9zly5AhXXFkegLr16jPx4wmcet3f2rVrznq+nEc6emVVSlLmmMK+mPsb3VrXYvmUx1m68u+E7G7dpt08M/xrvhrZjxAzYmLjeGDoZLbuOnDeOj/84hcG390iYfvF92byykMdWDr5MUJCjL937KfDgFG8O/kn3n/uNlZ8/jgbNu9hzaZdHDp6nL+27uP3ddv5fdr/2L77AIt++/e2+bFTFzJ9eF927TtEi95J7/Bbu2k3ObNHsHPvQXb/cxiAuYvWUb7UJcwb9xAAx46f4M7Hx7HvwLmHiCVjaNX6Jvrfdy8d2t1ExUqVKVX69Mxq2ZIlfPjBGMLCwsiePTvPv/gS+fPn59kXXmTwww9yMuYkAP3uH0jJkqWS3XaTps344/df6XhzW8yMgYMepmChQkz/Ytpp7SWWN28+qlarzs1tW1O/QYOEu1ZPadb8Bl4e+gK9+/RNKOvdpy8vD/0/bmnfhvj4eIoVL847I969kB+VBDn790XJKSdbtX4pX6mcV0iIER4WyomTsZQqXpBvR/XjqnbPERN7zteWyVkcWPpOWndBJEVEhKVePlbi/ukp/vt+69tt0jx/VOYYRLJHZGHmewMIDwvBMAa8OFmBUURSlW7IkVQxf/xDZAm4OabXE+NZvfHsd5KezdGoE9Tv9nJKdU3kPxvY/z52bk+66s6ABx+iXv0GadQjkeRRcExj193+6hnLRz3VjZbXVWZf5BFqdvy/JPsG3NaYoQ/eTPFGjyY8n9igRjleebgD4WGh7D94lOZ3vZnqfRc5n2FvDT/rvr83b+KRQQ8kbG/fvo2+/frT/fY7LkLPJKUoc5SL6qOvFjHq0x95/7nbk5QXL5KXJrUrsHVXZEJZnpzZePOxTrS9bwTbdh/Q3aOSIZQsVTrhGcu4uDiaNbqOxk2bpXGvRHz0KEc6tXDFX0Qeijqt/OWHOvD4m1+Q+Eaqzi1r8uXc39m223fnq+4clYxm8aJfuOyyy7j00mJp3RW5QGaW4p/0QJljBtK6YRV27j3Iyg1Jnz0rd3lhwsJCmfXeAHJmz8rwSfPOuSydSHozc8Y3tGjVOq27IV6kj1iW4hQcM4hsEeE80vMGWvc9/fGCsNAQqle4jJb3vE22iHDmjRvEkj/+ZuPW5K2gI5KWYk6e5McfvmfAwEFp3RWRBAqOGUTp4oW4vFgBlnw6BPAtdv7LxEdpcNsr7Nh7kP2HjhEVfZKo6JMsWLGRq64opuAoGcKCBfMpX7ESBQoWPP/Bku6kl2HQlKY5xwxi9cadXN5kCOVvfIryNz7Fjr0HqXPrS+zZf4Sv5v1B3aplCA0NIVtEONdULsm6zan3DkiRlDTj229o2erGtO6GSBLKHNOpcS/eQYMa5SiYNycbZz7Hc6O+ZdwXv5zx2PWb9zDn5zUsnTyE+HjHh9N+Zs1fu854rEh6EhUVxaKff+Z/Tz2b1l0Rj4I1c9TycSJnoeXjJFik5vJxZQbNSPHf93+91jLNI64yRxER8SxIE0cFRxER8S5Yh1V1Q46IiEgAZY5pJCTEWPjxI+zce4gOA0bRsNYV/N/A9oSEGMeiTnD3Ux+xads/p51XudylvPNEV3LliCA+3lG/+8uEh4Xy3dh/16gsVjgvn3y7lIdf/Zx7u1xPrw712Lb7AJ0eGE1MbBx1q5amXZOqPPLa1It5yRLEdu/axeNDHiFy/34w45aOneh2W48kx/zw/XcMf/tNQiyE0LBQHn70MarXqMnOnTt4oH8/XHw8MbGxdO3WnU6du3Ly5EkG9LuXPXv20LlL14T3ND771P/o2LkLFSpWSotLlQBBmjgqOKaVfrc2Yv3mPeTKEQHAW491oeMD77J+8x56d2zA4Lta0PupCUnOCQ0NYezzPej1v/Gs3LCD/HlyEBMbx4mTsdTuMjThuIUfP8IX3/8GQJeWNbmm04s80qs5zepW4Nv5qxh8d0t6DPng4l2sBL3QsFAeemQwFSpW4tixo3Tp2IHadepRpmzZhGOuvbYODRs1wczYsH4dDw8ayJdfz6RQwUJ8NPFTsmTJQtSxY3RodxMNGzVmzapVVKteg7t696FHd19wXL9uHXHxcQqMkuo0rJoGihXOS4v6lfhg2s8JZc45cvsDZe5c2di179Bp5zWtU55Vf+5IWD4u8tAx4uOT3ihWtkRhCufPxcIVfwG++YDwsFCyR2QhJjaOrjdew+yFqzlw+PR1W0W8KlSocELAypEjJ6VLl2bv3j1JjsmeI0fC/NTx48cTvodnyUKWLFkAOBlzkvj4eADCwsOIjo4mNjY2YS3h4W8P4777B1yUa5Lk0dqqkmJeedi3eHjO7BEJZX2fnci0t/sSfeIkh49Fc/3tr512XrkShXEOpg+/j4L5cjJl1nJeH/ddkmM6tqjOlNkrErZHfvojP44fxNq/dvHLb5v47I3e3HTf2V8jJPJf7dixnXVr11LlqqtP2zf3uzm8New1IvdH8s7IdxPKd+/aRb++vdm2dSsPDHqEwoWLkD9/Ab6ePp3uXTtxx529mPf9XCpUrEThwkUu5uXIeaSTWJbiFBwvspYNKrM38gi/rt1GgxrlEsrv79aI9vePYOmqLTxwexNeGnQzfZ+dmOTcsNBQ6lYrTf3urxAVfZIZ7/ZnxdqtzFuyIeGYjjfUoNcT4xO2J32zlEnfLAVgSO8WjJj0IzfUq0S31rXYvvsAj74+jdR41lUyp6hjxxg0sD8PD36MnDlPf3Vak6bNaNK0GcuXLWX4228yesyHAFxStChTpn3F3r17GHj/fTRrfgMFChZk6Cu+PxJjYmK4t3cv3nxnBK+89CK7d+3ipjZtadi4ycW8PMlENKx6kdWpWprW11dh3TfPMH7onTS85gqmvtWHKlcUY+mqLQBMmb2C2leXOu3cHXsPsmDFX+w/eIzj0THMXLCaauUvS9hf5YpihIWG8uvabaedW7RQHmpWKslX8/5gwG2N6f7oWA4eOU6jWlem3sVKphITE8ODA/vT6sabaNqs+TmPrVHzGrZv38aBA5FJygsXLkLZcuVYsXxZkvLJn0zkpjbt+OP338mVKxcvv/YG48dp3jw9CAmxFP+kBwqOF9mTb0+nbIv/Uf7Gp7h98AfMW7qBjg+MJnfObJQtURiAxrXLs37zntPOnfPzGiqVvZRsEeGEhobQoEZZ1m76dw3VTi1qMHnmstPOA3iy7408N/JrALJlDcc5iHeO7NnCU+EqJbNxzvH0k49TunRpbr/jzjMes3XLloRRirVrVnPy5Eny5s3Hnt27iY6OBuDwoUP8umIFJUv9+8fh4UOHmP/jPG5q247o6OMJ81KnzhFJDRpWTQfi4uK577mJTHr1LuJdPAcPH+eep313qt54fRWqVyzBcyO/4eCR47w14XsWTHgE5xyzFqxm5oLVCfV0aFaddvePPK3+q68sDsBv67YD8OmMZSz77DG27z7A6x9+d9rxIhfq1xXL+Xr6l5S74go63dwWgPsHPsiuXTsB6NS5K9/NmcVX078kPCyMrBERvPzqG5gZmzb9xWuvDMUwHI4ed/Sk3BX/jmi8O3I4d/XuQ0hICHXrNeCTSRPp0O4mOnbukibXKkkF65yj1lYVOQutrSrBIjXXVq38xJwU/32/6vlmaR5yNawqIiISQMOqIiLiWbAOqypzFBERCaDMUUREPEsvK9qkNGWOIiIiAZQ5ioiIZ8GaOSo4ioiIZ0EaGzWsKiIiEkiZo4iIeBasw6rKHEVERAIocxQREc+CNHFUcBQREe80rCoiIpJJKHMUERHPgjRxVOYoIiISSMFRREQ8M7MU/ySz3bFmttfMViUqy29mc8zsT/+/+fzlZmZvmdlGM/vDzKqfr34FRxER8cws5T/J9CHQIqBsMDDXOVcOmOvfBmgJlPN/egMjz1e5gqOIiGQ4zrn5QGRAcVtgnP/7OKBdovLxzmcRkNfMip6rft2QIyIinqWzRzmKOOd2+b/vBor4vxcDtiU6bru/bBdnocxRRETSFTPrbWbLEn16X2gdzjkHOK99UOYoIiKepUbi6JwbDYz2cOoeMyvqnNvlHzbd6y/fAVyW6Lji/rKzUuYoIiLBYjrQw/+9B/BlovLb/Xet1gYOJRp+PSNljiIi4llazTma2SSgIVDQzLYDTwFDgclm1gvYAnTyH/4t0ArYCEQBd56vfgVHERHxLK3ux3HOdT3LriZnONYB911I/RpWFRERCaDMUUREPEtnj3KkGGWOIiIiAZQ5ioiIZ0GaOCo4ioiIdxpWFRERySSUOYqIiGfKHEVERDIJZY4iIuJZkCaOCo4iIuKdhlVFREQyCWWOIiLiWZAmjsocRUREAilzFBERz4J1zlHBUUREPAvS2KhhVRERkUDKHEVExLOQIE0dlTmKiIgEUOYoIiKeBWniqMxRREQkkDJHERHxTI9yiIiIBAgJztioYVUREZFAyhxFRMSzYB1WVeYoIiISQJmjiIh4FqSJo4KjiIh4ZwRndNSwqoiISABljiIi4pke5RAREckklDmKiIhnwfooh4KjiIh4FqSxUcOqIiIigZQ5ioiIZ3rZsYiISCahzFFERDwL0sRRmaOIiEggZY4iIuKZHuUQEREJEKSxUcOqIiIigZQ5ioiIZ3qUQ0REJJNQ5igiIp4FZ96o4CgiIv9BsN6tqmFVERGRAMocRUTEs2B92fFZg6OZvQ24s+13zvVPlR6JiIiksXNljssuWi9ERCRDCtY5x7MGR+fcuMTbZpbdOReV+l0SEZGMIkhj4/lvyDGzOma2Bljn377azEakes9ERETSSHLuVh0G3ADsB3DO/Q5cl5qdEhGRjMHMUvyTHiTrUQ7n3LaAorhU6IuIiEi6kJxHObaZWV3AmVk4MABYm7rdEhGRjCBYH+VITubYB7gPKAbsBKr6t0VERILSeTNH59w/QLeL0BcREclg0mqO0MweAO7C9zz+SuBOoCjwCVAAWA7c5pw76aX+5NytWtrMvjKzfWa218y+NLPSXhoTEZHgYqnwOW+bZsWA/kBN51xlIBToArwEvOGcKwscAHp5va7kDKtOBCbji8iXAp8Bk7w2KCIikgLCgGxmFgZkB3YBjYEp/v3jgHZeK09OcMzunPvIORfr/0wAIrw2KCIiwSPELMU/ZtbbzJYl+vRO3KZzbgfwKrAVX1A8hG8Y9aBzLtZ/2HZ898p4cq61VfP7v84ws8H4xnEd0Bn41muDIiIi5+KcGw2MPtt+M8sHtAVKAQfxjWi2SMk+nOuGnOX4guGpIeB7Eu1zwJCU7IiIiGQ8aXQ/TlNgs3Nun68PNhWoB+Q1szB/9lgc2OG1gXOtrVrKa6UiIpI5pNHdqluB2maWHTgONMH3sowfgFvwjXT2AL702kCy3udoZpWBiiSaa3TOjffaqIiIiFfOucVmNgVYAcQCv+Ibhv0G+MTMnveXjfHaxnmDo5k9BTTEFxy/BVoCCwAFRxGRTC6tlkJ1zj0FPBVQvAmolRL1J+du1Vvwpay7nXN3AlcDeVKicRERkfQoOcOqx51z8WYWa2a5gb3AZancLxERyQBC0slbNFJacoLjMjPLC7yH7w7Wo8AvqdorERHJEII0NiZrbdW+/q+jzGwmkNs590fqdktERCTtnGsRgOrn2uecW5E6XRIRkYwivbycOKWdK3N87Rz7HL417M5o7y9vee6QSHqRr8XQtO6CSIo4/t3gtO5ChnOuRQAaXcyOiIhIxpOcRx4yomC9LhEREc+StUKOiIjImWTGOUcREZFzCgnO2Hj+YVXz6W5mT/q3S5hZiizPIyIikh4lZ85xBFAH6OrfPgIMT7UeiYhIhhFiKf9JD5IzrHqtc666mf0K4Jw7YGZZUrlfIiIiaSY5wTHGzELxPduImRUC4lO1VyIikiFk5hty3gKmAYXN7AV8b+l4IlV7JSIiGUJ6GQZNaclZW/VjM1uO77VVBrRzzq1N9Z6JiIikkeS87LgEEAV8lbjMObc1NTsmIiLpX5COqiZrWPUbfPONBkQApYD1QKVU7JeIiEiaSc6wapXE2/63dfQ9y+EiIpKJZOaXHSfhnFthZtemRmdERCRjCdYFupMz5/hgos0QoDqwM9V6JCIiksaSkznmSvQ9Ft8c5Oep0x0REclIgnRU9dzB0f/wfy7n3EMXqT8iIiJp7qzB0czCnHOxZlbvYnZIREQyjsx4Q84SfPOLv5nZdOAz4Nipnc65qancNxERkTSRnDnHCGA/0Jh/n3d0gIKjiEgmF6SJ4zmDY2H/naqr+DconuJStVciIpIhZMa1VUOBnCQNiqcoOIqISNA6V3Dc5Zx79qL1REREMpxgvSHnXIsbBOcVi4iInMe5MscmF60XIiKSIQVp4nj24Oici7yYHRERkYwnWG/ICdY1Y0VERDy74LdyiIiInGJBenuKMkcREZEAyhxFRMSzYJ1zVHAUERHPgjU4alhVREQkgDJHERHxzIL0QUdljiIiIgGUOYqIiGeacxQREckklDmKiIhnQTrlqOAoIiLeZcZXVomIiGRKyhxFRMQz3ZAjIiKSSShzFBERz4J0ylHBUUREvAvRK6tEREQyB2WOIiLiWbAOqypzFBERCaDMUUREPNOjHCIiIgFCzFL8kxxmltfMppjZOjNba2Z1zCy/mc0xsz/9/+bzfF1eTxQREUlDbwIznXPlgauBtcBgYK5zrhww17/tiYKjiIh4Zpbyn/O3aXmA64AxAM65k865g0BbYJz/sHFAO6/XpeAoIiIZTSlgHwYQdmQAACAASURBVPCBmf1qZu+bWQ6giHNul/+Y3UARrw0oOIqIiGepMedoZr3NbFmiT++AZsOA6sBI51w14BgBQ6jOOQc4r9elu1VFRCRdcc6NBkaf45DtwHbn3GL/9hR8wXGPmRV1zu0ys6LAXq99UOYoIiKepcWco3NuN7DNzK70FzUB1gDTgR7+sh7Al16vS5mjiIh4loYZ1v3Ax2aWBdgE3OnvzmQz6wVsATp5rVzBUUREMhzn3G9AzTPsapIS9Ss4ioiIZxaki6tqzlFERCSAMkcREfEsOPNGBUcREfkPkrsWakajYVUREZEAyhxFRMSz4MwblTmKiIicRpmjiIh4FqRTjgqOIiLinZ5zFBERySSUOYqIiGfBmmEF63WJiIh4psxRREQ805yjiIhIJqHMUUREPAvOvFHBUURE/gMNq4qIiGQSyhxFRMSzYM2wgvW6REREPFPmKCIingXrnKOCo4iIeBacoVHDqiIiIqdR5igiIp4F6aiqMkcREZFAyhxFRMSzkCCddVRwFBERzzSsKiIikkkocxQREc8sSIdVlTmKiIgEUOYoIiKeBeuco4KjiIh4Fqx3q2pYVUREJIAyRxER8SxYh1WVOYqIiARQ5igiIp4pcxQREckklDkmU61qlShb7oqE7VffeIdLixU747ENatfgp0XLU6Td3r1u53hUFB9NmgLAmtWrGPb6y4weMz5F6j/lqy+nUbtOPQoVLgzAc08/Qbfb7qB0mbIp2o6kP/lzR/Dty10BKJI/B/Hxjn0HowBo0G8cMbHxKdbWugn3cuT4CZyDPZHHuOulr9lz4NgF1fHDm91pNGACJYrkoU6lYnz6/RoAql9xCd2aVWbQ8O9SrL9yfsG6CICCYzJlzRrBxMnT0qTtyMhIFi6YT73616VaG19Nn0aZsuUSguP/nn4+1dqS9CXycDS1+3wAwOO31+fY8ZMM+2xJwv7QECMu3qVYey0GTWL/4eM80/M6Hrm1zgUHs0YDJgBw+SV56NS4YkJwXLFhNys27E6xfkryhARnbFRw9Coq6hiDBvTj8OFDxMbGcm+/ATRs1CTJMf/s28uQRx7k2LFjxMbGMuSJp6hWvSaLfl7IuyPf5uTJkxS/rARPPfsC2bPnOGtbt/Xoydj33j0tOMbFxfHOm6+zfNkSTp48ScfOt9KhY2fi4+N5+cXnWLpkMUUuuYSwsDDatOtA02Y38N6o4fw0fx7R0dFcXbUaj/3vGeZ+N5u1q1fzxJCHiYiIYOz4SfS/rzcDH3yENatXsWP7NgY8+DDgyzDXrF7Fo4/9j2+/ns4nEycQGxtDpcpXMfjxJwkNDU35H7ZcdKMfvpHok7FULVuEX1Zv53DUySRBc9l7vbj5iSls3XOILk0qcV/7GoSHhbJ03U4GvDWb+GQE0wUrt9G3XU2yhofy1oAbqH7lJcTGOR4dOZf5v2+lwuUFGf1wK8LDQgkJMbo+M42/dhxg31cPUuim13n+ruu5skQBFo26k4/nrOK3jXsY2LEWt/xvCms/updr7xnLoWMnAFj5YW+aDJxAvHO8PbAFlxXODcDDI77jl9U7Uu8HKRmW5hyT6cSJaG7t1J5bO7XnoYH9yJIlK6+88TYffzqVd98fx7DXXsa5pL8QZn77DbXr1mfi5GlM+uwLrriyAgcPHGDMeyMZ8e5YPv50KhUqVuLj8R+es+2rrq5KeHg4y5YsTlL+5bTPyZEzJ+Mnfsb4iZ/xxdTP2LF9O9/PncPOnTv4bNrXPPvCS6z8/feEczp17cb4iZ8xeepXREdH89OP82ja7AYqVKrE8y++wsTJ04iIiEg4vknT5vzw/b9/2c+ZNYMbWrRi86a/mDNrBmPHfczEydMIDQ1hxrdf/YefsKQ3xQrlouGAj3h01PdnPebKEgW4pWEFGg2YQO0+HxAX7+jSpFKy6m91bVlWb95Hn7Y1cMA1d4+lxwtf8v6jN5I1PJS7b6rG8KnLqN3nA+r1/ZAd+44kOf+J939k4crt1O7zAW9/vjSh3Dn4+uc/aVPfNw1yTfmibN17mL0Ho3j1vqa8/flS6t83jq7PTGPEgy0v/AcjSVgq/F96oMwxmQKHVWNjYhj+1hv8umIZISEh7Nu7h/37/6FgwUIJx1SsXJlnn3qC2NhYGjZqwpXlK/DTsiVs2vQXve7oBkBMTAxVrrr6vO33ursPY94bxf0DByWULfplIRs3rOf772YDcPTIEbZt3cLvvy6nabMWhISEULBgIWpeUyvhnGVLlzD+gzFERx/n8KFDlClTjusaNjpru/ny56dYseKs/OM3LitxOX9v3sTV1aoz+ZOJrF27mtu7dQIgOjqafPkLJPOnKRnB1B/XnTcDbFTtcqqXK8KC4T0AyJY1LGG+8mxmvtaVuDjHqs37ePqD+Yx++EZGfOGbo9+wLZKtew5Trnh+Fq/ZwSO31qFYoVx8sWADf+04kOy+T5m3liG31eOjWSvp2KgiU+at9fe3JOVLFEw4LneOrOSICOdYdEyy65bMQcHRoxnffs3BA5FMmDSFsPBwbmrZhJMnTiY5pnqNa3hv7Ecs+Gkezzz5GLfe1oPcufJwbe26/N9Lr11Qe9dcW5uRw99k5R//ZoHOOR4e/AR16tVPcuzCBT+esY4TJ07w0gvPMn7SZ1xySVHeHfkOJ06eOG/bzVu0Ys6smZQsVZqGjZtiZjjnaH1TO/oNePCCrkMyjqhEASM2Lp6QRPfsR2Tx/eowMybMWcWTY87839yZnJpzPJ9Pv1/DkrU7aXltGb54oSP9hs3ix9+2JKuNRWt2UObSfBTMk42b6pZj6McLAQgJMa6/fzwnYuKS3V85Nz3KIUkcPXqEfPkLEOYf7ty1c+dpx+zauYP8BQrQvkMn2ra/hfVr11Dlqqv5/bdf2bbV9//kx6Oi2PL35mS12fPuPoz/cEzCdp269Zny2SfExvh+iW35ezPHo6K4ump1vv9uNvHx8ezf/w/Ll/mGnE6e8AXCvHnzERV1jLlzZiXUlSN7DqKOnfmuwUZNmvLjvO+ZNeMbmrdoBUCta2sz97tZRO7fD8ChQwfZtVNzN8Fqy+5DVC1XBICqZYtQ8pI8APyw4m/aN7iSQnmzA5AvVwQl/PN5ybVw5Ta6NKkIQNli+biscG42bI+kZNE8bN51kBFfLOfrn/+kSulCSc47GnWCXNmynLXe6Qs38FKfJqzbup/Iw9EAzF2+mb7tayQcc1WZwhfUVzmdhlUliZatbuKB/vfSuUMbKlasTMlSpU87ZvmypYz/cAxhYeFkz56dZ54fSr78+Xn62f/j8cEPcfKkL9O8t98ALi9Z6rxt1m9wPfny5UvYbnfzLezauYNuXTrgnCNfvvy8NuwdGjdtzpLFi+jYvjVFLrmE8hUqkDNnTnLlzk27DrfQuUMbChQsSKVKVRLqat22Pf/3/NMJN+Qkljt3HkqVKs3mTX9RucpVAJQuU5Z77xtAv3vvIj4+nrCwMB597H8UvfTMj7dIxvbFT+vp1qwyy9/vxdJ1u/hzeyQA67bu55kP5/PV0M6EhBgxsfE88PZstu49nOy6352+grcG3MDS93oSG+e4++VvOBkTxy3XV6Br00rExMaz58AxXp70S5LzVm7aR1y8Y/G7PZkweyW/bdyTZP+UeWtZOOIO7nrp64SyQe98x7D+zVkyuidhoSEs+GMb/d+chUggC7yJJCUciU7B+77Fk6ioY2TPnoODBw/Qo1tnxoz7OMl8qJxf4dYvp3UXRFLE8e8Gp1o6Nn9DZIr/vr/uivxpnj4qcwxSA++/l6NHjhATE8Ndve9VYBQRuQAKjunEQwP7sTNgzu7+AYNOu9kmuVJ6BR2RCzH/7dvJEp70mddeL33N6s370qhHklrSyxxhSlNwTCdeHfZOWndBJMVcd7/+OMssgvVuVQXHDOCZJx9nwfx55Mufn8lTfQ/afzd7JqNHvsPmzZsY9/FkKlaqnMa9FDmzUQ+1ouW1Zdh3MIqad/vutn7yjga0rlsuYR3X3q98w679RwFocHUJXrm3CeFhIew/dJzmgyamZfclk9KjHBnATW3b8fbI0UnKypQtx8tvvE21GjXTqFciyfPRrJW0HTI5SdkbkxdTq/dYavf5gBmLNjKkez0A8uTIypv9m9Pxyc+pcdcYuj33RVp0WS6ApcInPVDmmAFUr3ENO3cknY8sVbpMGvVG5MIsXLmNEkXyJCk7EvXvghnZs4Xj8N3w2LlJRb5csJ5t/kdBzrfajkhqUXAUkTTx9J3X0a1ZZQ4dO0GLh3xDp+WK5ScsLIRZr91KzmxZGD5tGRPnrErjnsq5hATppKOGVUUkTTz9wXzK3TqCT75fTZ+2vlVrwkJDqH7FJbR//DPaDP6UId3qUrZYvvPUJJLyFBxFJE19OncN7RpcCcCOf44wZ+lmoqJj2H/4OAtWbtMSb+lcsM45KjiKyEVXJlE22LpuOTZs863R+9XPf1K3cnFCQ4xsWcO4pvylrNu6P626KcmRhtHRzELN7Fcz+9q/XcrMFpvZRjP71MzOvvjueWjOMQN47NFBLF+2hIMHD9KqWUN639uPPHny8MrQFzhwIJKB/fpwxZXleWfU+2ndVZHTjHusDQ2uLkHBPNnYOKkvz41bQItry1CueH7inWPrnsP0HzYTgPVb9zNn2SaWvteL+HjHhzN+Z83f/6TxFUg6NgBYC5xa7f4l4A3n3CdmNgroBYz0UrHWVhU5C62tKsEiNddWXfzXoRT/fX9tmTzn7a+ZFQfGAS8ADwI3AfuAS5xzsWZWB3jaOXeDlz5oWFVERDKiYcAjQLx/uwBw0DkX69/eDnh+TZCCo4iIeGaWGh/rbWbLEn16J23TWgN7nXPLU+u6NOeYhk6cOMHdd95GTMxJ4mJjadLsBu7pe/9px82ZNYPRo4ZjQLkry/PC0FdZtmQxr786NOGYvzdv4v9eeo2GjZvyxJCH2fjnBhpc15D7+j8AwPujR1K2bDkaNm56sS5PMomQEGPhiDvY+c8ROjwxhdEP30iDqy7j0DHfy7V7v/INf/y1N8k5JQrn5pNnbibEjPCwEEZ+sZz3v/4NgC9f7MQl+XMSFmosXLmdgW/PJj7e8fxdDWleqzR//LU34R2NXZpUomCebLwzddnFvWhJkBrjtc650cDocxxSD2hjZq2ACHxzjm8Cec0szJ89Fgc8v4FdwTENZcmShVHvf0D27DmIjYmh1x3dqVu/AVWuqppwzNYtf/PBmPcYM+5jcufOQ+R+3517NWtdy8TJ0wA4dOgg7Vu3oHadevy5YT1Zs2blkylf0veenhw9coTo6OOsXvkHd/W+N02uU4Jbv/Y1Wb/1H3Jlz5pQ9tjoH5j20/qznrMr8igN+3/EyZg4ckSEs/z9u/jml43s2n+U7s99kbCCzqSn2tPhuvLMWrqJquWKUKv3WEY82JJKpQrx144D3H5DFdoELE0nwc85NwQYAmBmDYGHnHPdzOwz4BbgE6AH8KXXNjSsmobMjOzZcwAQGxtLbGzMaa9/mTb1Mzp16Uru3L7lt/IXKHBaPXPnzKZu/QZEZMtGWFgYJ06cID4+ntjYWEJCQxg14m3u6dsv9S9IMp1iBXPR4toyfPDtHxd0XkxsPCdj4gDImiWUkES/iU4FxrDQEMLDQnE44uMd4WG+V2BljwgjJjaOgR1rMfKL5cTGxZ9Wv1xE6etBx0eBB81sI745yDFeK1JwTGNxcXHc2qk9zRrV59radal81dVJ9m/dsoUtW/6mZ49buaN7Z35e+NNpdcye+S03tGgF+NZczZcvH927dOC66xqxbetW4uPjKV+h0kW5HslcXunbhMff+4H4gLven+55HUtG9+Tle5uc9l7HU4oXysWS0T35c+J9vPbJ4oS3cgBMH9qJrVP6c/T4CabOX8/R4yeZtfgvFo26k937j3H42AmuqXApX/38Z6pen6R/zrl5zrnW/u+bnHO1nHNlnXMdnXMnvNarYdU0FhoaysTJ0zhy+DAPPXA/G//cQNlyVyTsj4uNZduWLYx+fxx79uyhd8/b+GTKl+TK7Xus5599e9m4cQN16v77UuRBjzyW8P2B++/lsf89w5j3RvHnhvVcW7sO7Tt0ungXKEGr5bVl2Hswil//3EODq0sklD85Zh67I4+RJTyU4Q+0YFDn2rw4YeFp52/fd4RavcdStEBOJj9zM9Pmr2Ovf6HxNoMnkzU8lA8fa0PDqpfz/Yq/eX3yYl6fvBiAEQ+25LkPf+KOllfRtGYpVm7ax0sf/3xxLlySCNaXHStzTCdy5c5NzWtq8cvPC5KUFy5yCdc1bExYeDjFihenxOUl2bp1S8L+ObNn0qhxU8LCw0+rc94PcylfsRJRUcfYvm0bQ195g7lzZhN9/HiqX48EvzqVi9O6TlnWTbiX8Y/7gtjYwa3ZHXkMgJMxcYyftZKa5Yues55d+4+y+u9/qFflsiTlJ2Li+OrnP7mpbrkk5VeXLYIZbNgeyc3Xl6f7c19SumjeJKvuyMWTGnerpgcKjmnoQGQkRw77Xs0THR3N4kW/ULJkqSTHNGzchOXLlgBw8MABtm75m2LFiyfsnzXjG25oceNpdcfGxDBpwnh63NGLEydOJPwHFx8fR0xMTCpdkWQmT475kbJdR1C++0huf2E6837bQs+hX3NJ/hwJx7SpW441f+877dxiBXMRkcU3cJU3Z1bqVi7Ohu2R5IgITzg/NMRoeW0Z1m9Lunzck3c04NkPfyI8NIRQ/2RlvHNkz3r6H4giXmlYNQ39888+nnpiCPHxccTHx9OseQsaXN+IUcPfokKlylzfsDF16tZn0c8L6di+NSEhIfR/4CHy5vX9hbxzxw727N5N9ZrXnFb35E8n0rpNOyKyZaPcFVcSHR1N5w5tqFf/uoQhWZHU8MGQNhTMmw3D+OOvPdw/bBYA1a+4hLtaV6Pv6zO4skQBhvZpjHO+TGHYZ4tZvXkfhfNmZ8pzt5AlPJQQM+b/vpX3vvo1oe6b6pZjxYbdCfOTf2zcw9L3erJq0z5Wbtp7xv5I6koniV6K0/JxImeh5eMkWKTm8nEr/j6c4r/vq5fMneYxV5mjiIh4l+ZhLHVozlFERCSAMkcREfEsWB/lUHAUERHP0sujFylNw6oiIiIBlDmKiIhnQZo4KnMUEREJpMxRRES8C9LUUcFRREQ8C9a7VTWsKiIiEkCZo4iIeKZHOURERDIJZY4iIuJZkCaOCo4iIvIfBGl01LCqiIhIAGWOIiLimR7lEBERySSUOYqIiGd6lENERCSTUOYoIiKeBWniqOAoIiL/QZBGRw2rioiIBFDmKCIinulRDhERkUxCmaOIiHgWrI9yKDiKiIhnQRobNawqIiISSJmjiIh4F6SpozJHERGRAMocRUTEs2B9lEPBUUREPAvWu1U1rCoiIhJAmaOIiHgWpImjMkcREZFAyhxFRMS7IE0dlTmKiIgEUOYoIiKe6VEOERGRAHqUQ0REJJNQ5igiIp4FaeKozFFERCSQMkcREfEuSFNHBUcREfEsWO9W1bCqiIhIAGWOIiLimR7lEBERySSUOYqIiGdBmjgqOIqIiHcaVhUREUkHzOwyM/vBzNaY2WozG+Avz29mc8zsT/+/+by2oeAoIiL/gaXC57xigUHOuYpAbeA+M6sIDAbmOufKAXP9254oOIqISIbinNvlnFvh/34EWAsUA9oC4/yHjQPaeW1Dc44iIuJZWs85mllJoBqwGCjinNvl37UbKOK1XmWOIiKSrphZbzNblujT+yzH5QQ+BwY65w4n3uecc4Dz2gdljiIi4llqJI7OudHA6HO2axaOLzB+7Jyb6i/eY2ZFnXO7zKwosNdrH5Q5ioiIZ2Yp/zl/m2bAGGCtc+71RLumAz3833sAX3q9LmWOIiKS0dQDbgNWmtlv/rLHgKHAZDPrBWwBOnltQMFRREQ8S4u3cjjnFnD2Ed0mKdGGhlVFREQCKHMUERHvgnT5OAVHERHxLEhjo4ZVRUREAilzFBERz9J6hZzUosxRREQkgDJHERHxLC0e5bgYFBxFRMS74IyNGlYVEREJpMxRREQ8C9LEUZmjiIhIIGWOIiLimR7lEBERySSUOYqIiGd6lENERCSAhlVFREQyCQVHERGRAAqOIiIiATTnKCIingXrnKOCo4iIeBasd6tqWFVERCSAMkcREfEsWIdVlTmKiIgEUOYoIiKeBWniqOAoIiL/QZBGRw2rioiIBFDmKCIinulRDhERkUxCmaOIiHimRzlEREQyCWWOIiLiWZAmjgqOIiLyHwRpdNSwqoiISABljiIi4pke5RAREckklDmKiIhnwfoohznn0roPIiIi6YqGVUVERAIoOIqIiARQcBQREQmg4CjpipnFmdlvZrbKzD4zs+z/oa4PzewW//f3zaziOY5taGZ1PbTxt5kVTG55wDFHL7Ctp83soQvto4hcOAVHSW+OO+eqOucqAyeBPol3mpmnO6ydc3c559ac45CGwAUHRxEJTgqOkp79BJT1Z3U/mdl0YI2ZhZrZK2a21Mz+MLN7AMznHTNbb2bfAYVPVWRm88yspv97CzNbYWa/m9lcMyuJLwg/4M9aG5hZITP73N/GUjOr5z+3gJnNNrPVZvY+yVg8y8y+MLPl/nN6B+x7w18+18wK+cvKmNlM/zk/mVn5lPhhikjy6TlHSZf8GWJLYKa/qDpQ2Tm32R9gDjnnrjGzrMBCM5sNVAOuBCoCRYA1wNiAegsB7wHX+evK75yLNLNRwFHn3Kv+4yYCbzjnFphZCWAWUAF4CljgnHvWzG4EeiXjcnr628gGLDWzz51z+4EcwDLn3ANm9qS/7n7AaKCPc+5PM7sWGAE09vBjFBGPFBwlvclmZr/5v/8EjME33LnEObfZX94cuOrUfCKQBygHXAdMcs7FATvN7Psz1F8bmH+qLudc5Fn60RSoaP8+4ZzbzHL627jZf+43ZnYgGdfU38za+79f5u/rfiAe+NRfPgGY6m+jLvBZorazJqMNEUlBCo6S3hx3zlVNXOAPEscSFwH3O+dmBRzXKgX7EQLUds5Fn6EvyWZmDfEF2jrOuSgzmwdEnOVw52/3YODPQEQuLs05SkY0C7jXzMIBzOwKM8sBzAc6++ckiwKNznDuIuA6MyvlPze/v/wIkCvRcbOB+09tmNmpYDUfuNVf1hLId56+5gEO+ANjeXyZ6ykhwKns91Z8w7WHgc1m1tHfhpnZ1edpQ0RSmIKjZETv45tPXGFmq4B38Y2CTAP+9O8bD/wSeKJzbh/QG98Q5u/8O6z5FdD+1A05QH+gpv+GnzX8e9fsM/iC62p8w6tbz9PXmUCYma0FhuILzqccA2r5r6Ex8Ky/vBvQy9+/1UDbZPxMRCQFaW1VERGRAMocRUREAig4ioiIBFBwFBERCaDgKCIiEkDBUUREJICCo4iISAAFRxERkQAKjiIiIgEUHEVERAIoOIqIiARQcBQREQmg4CgiIhJAwVFERCSAgqOIiEgABUdJc2bWzsyc/2XAGZ6Z1TCzlWa20czeMjM7wzH5zGya/32RS8yscsD+UDP71cy+TlRWyswW++v91MyyXIzrEcmMFBwlPegKLPD/myrMLDS16j6DkcDdQDn/p8UZjnkM+M05dxVwO/BmwP4BwNqAspeAN5xzZYEDQK+U7LSI/EvBUdKUmeUE6uP7Rd/FXxZqZq+a2Sp/ZnW/v/waM/vZzH73Z1u5zOwOM3snUX1fm1lD//ejZvaamf0O1DGzJ81sqb/e0acyOjMra2bf+etdYWZlzGy8mbVLVO/HZtY2GddTFMjtnFvkfG8SHw+0O8OhFYHvAZxz64CSZlbEX0dx4Ebg/UT1GtAYmOIvGneWekUkBYSldQck02sLzHTObTCz/WZWA6gFlASqOudizSy/fwjxU6Czc26pmeUGjp+n7hzAYufcIAAzW+Oce9b//SOgNfAV8DEw1Dk3zcwi8P3ROAZ4APjCzPIAdYEeZnalvx9n0hAoBmxPVLbdXxbod+Bm4CczqwVcDhQH9gDDgEeAXImOLwAcdM7FnqdeEUkBCo6S1rry75DiJ/7tUsCoU4HAORdpZlWAXc65pf6ywwBnmM5LLA74PNF2IzN7BMgO5AdWm9k8oJhzbpq/3mj/sT+a2QgzKwR0AD7392c9UPVsDZ6nP4kNBd40s9+AlcCvQJyZtQb2OueWn8qAReTiU3CUNGNm+fENFVYxMweEAg5YegHVxJJ0eiAi0fdo51ycv60IYARQ0zm3zcyeDjj2TMYD3fEN997pr+d8meMOfBngKcX9ZUn4g/upOg3YDGwCOgNtzKyVv3+5zWwCcBuQ18zC/EH6jPWKSMrQnKOkpVuAj5xzlzvnSjrnLsMXJH4H7jGzMEgIouuBov/f3r0H21XWZxz/PoJiIJHQUFJHcWLFNtCIEQTUiqMSqPSCMmodFRQQK3gJNKXFtn94GTsFvEBJvSFpwE5LKWoqKpLQllsFxUAuhIQASrRYa1AuIRBhCI9/vL8ti+0+J+ecXM7J+Hxm9ux93rXetdc6M2d+513rXc+SdEi1Tanl64DZkp4maV/aKdlBeoXwp3Wd800Ath8C7uldX5S0m6Tda92LgNNrvdX1vtb27CFeD9j+MbBB0suq6L0D+Gr/zkia2pltejJwne0Ntv/a9nNtz6AV5f+2fVxdv7y6t9/AOwdtNyK2jRTHGE9vBRb1tX0ZeDbwQ2BlTaZ5m+3HaKOq+dV2Fa3gfYtWUFcD5wO3DPoi2w8AXwBWAYt56uj0eGCupJXADcBvVZ+f0GaMLhzlcb2XNpnmLuB7wDcBJJ0i6ZRaZ39glaS1wNG02albciYwT9JdtGuQC0a5XxExQmr/kEZEvxpB3gocZPvB8d6fiNhxMnKMGEDSHNqocX4KY8Svn4wcIyIi+mTkGBER0SfFMcaVpM2SlldqzWWdmaJbs82P1mnRoZafezO85gAACOdJREFUIukdW/s9w2x/q7JVJa2r/sslLe20v1nSbZKekPTS7bX/EZHTqjHOJG20Pbk+/wtws+1PdZb37uvbaUi6CZgLfAe4Ajjf9jf71vk4sNH2R9QC1z9t+4hato52P+ZP+/rsDzwBfB44w/ZSImK7yMgxJpLrgf0kvVrS9ZIuB1arZa1+vHJRV0p6T6+DpDNrlLVC0lnVdpGkN9XnsyStrn6fqLYPSzqjPs+W9O1avkjSXtV+jaSza1R3h6TDR3IA2gbZqkOxvcb22pHsR0RsnSTkxIRQN/QfDVxZTQcBs2zfLenPgAdtHyJpN+BbkpYAM2nZrIfZfqTCArrbnAYcC8y0bUlTB3z1F4EP2L5W0keBD1E3/gO72j600mo+BMzZQdmqBpZUatDnbV8wxPdFxHaS4hjjbVLli0IbOS6ghXzfZPvuaj8KOLA3GgT2pD0Kag6w0PYj0DJY+7b9IPBzYIHacxG/3l2oFig+1fa11XQxcFlnla/U+820IHRq5LbdslVr2Stt/0jSPsBVkm63fd1INxwRWy/FMcbbJttPKTZVYB7uNtFGd4v71vuD4TZcT/Q4FDiCFrv2flqW60g9Wu+bqb+VHZCtiu0f1ft6SYtokXgpjhE7UK45xs5gMXCqpKcDSPodSXvQIuRO7M1wHXBadTKwp+0raI+fenF3ed3cf3/neuLxwLUMY3tnq0raQ9KUWmcP2qh51Uh/URGxbWTkGDuDC2mnNW+pgnMv8AbbV0qaDSyV9BhtZujfdPpNAb6q9kQOAfMGbPudwOeqwH6fGs1tpffSQssn0XJVf5mtCmD7c7Rs1YvruuJttIc9A0wHFtXoeVfgX21fWf2PBeYDvwl8Q9Jy28OOniNibHIrR0RERJ+cVo2IiOiT4hgREdEnxTEmrL5oua8NcZ/i1mx/naS96/PGUfR7vqTvVDzcpZ2JNd11niFpYSeg4NXVvrukb0i6vaLgzur0OUHSvXXMyyWdvA0OMyLGIMUxJrJNNQt0FnAf8L7x3qFyNnCu7f2A+3lyMk3XuwFsvwg4EvikpN7f2ydszwReAvy+pKM7/S7tzH69cPsdQkQMJ8UxdhY3Ukkzkl4g6UpJN1fM3Mxqn14RcCvq9Ypq/49a97ZK2xmzmi37WuBL1XQxW46HWw88QMtLfcT21dX+GHALT70vMiImgNzKEROepF1oN/IvqKYLgFNs3ynpMOAztIJ1PnCt7WOrz+Ra/yTb90maBHxX0pdt/2yI75pCS+oZ5G3AeuCBThj6cPFwx0i6BNgXOLjeb+p811TgT4B/6PR7o6RXAXcAf277f4fYl4jYjlIcYyLrRcs9B1hDi1KbTIuXu6wT1bZbvb+WdtM9tjfT4uMA5tY9gtAK1AuBgcXR9kMMHw+39wj3/Z9o9zIuBX4A3MCT8XC9LNlLaE/s+H41fw24xPajauHqFzO6RJ+I2EZSHGMi22R7dt2gv5h2zfEi2shtyALWVRNh5gAvr3Dya4BnDrP+lkaOa4CpevJRWkPFwz1OS+XpbfcG2miw5wLgTtvndfp0C/aFwDnDHlxEbDe55hgTXgWLzwX+AngEuFvSm6FdA5TUi4X7L+DUat+lgsX3BO6vwjgTeNkWvuuhYeLhVtdjqK6mZbVCS9gZFA+3e8W/IelI4HHbq+vnj9V+nd7X59mdH4+hFeKIGAcpjrFTsL0MWAm8FXg78C5JK2jRa6+v1U4DXiPpVtqTNA6gPQJrV0lraE/C+PY22J0zgXmS7gKmUddCJR2j9tgrgH1ocXdrav3ja53nAn9b+3ZL3y0bc2vS0AraPwMnbIN9jYgxSHxcREREn4wcIyIi+qQ4RkRE9ElxjIiI6JPiGOOuk6Hae82QNE3S1ZI2SvrHYfr+saRllYizuu4PHDeSfkPSVZLurPe9hljv7MqMXSXpLZ32BXUsKyV9qe7rRNLz6vexrJb94Y46pohfR5mQE+NO0kbbk/va9qBlj84CZtl+/4B+T6fdYH+o7Xsk7QbMsL12K/ZFtL+LJ8bY/xzgPttnSfogsJftM/vW+SPabRxH0wIMrgGOsL1B0rNsb6j1PgWsr21dACyz/VlJBwBX2J4xxsOMiC3IyDEmJNsP2/4f4OfDrDaFFmTxs+rzaK8wDpOzOq8zYju92mZIWivpi8AqYF9JfynpuzVK+8godv31tGQbGD539Trbj9t+mHaLyuvqGHqFUcAkoPffq4Fn1ec9gf8bxT5FxCilOMZEMKlzSnXRSDvZvg+4HPiBpEskvV1PPvmil7P6YuAg4DZJBwMnAofRwgDeLekltf4Lgc/Y/j3gd+vnQ2lRcgdX3ilqQefLB7zm1Ham2/5xff5/YPqAXV8BvK6CAvYGXkOLtaO+Y2H1nQnMr+YPA8dJuge4AvjASH9PETF6iY+LiWDTSOPg+tk+WdKLaBFxZ9AeD3UCA3JWJb0SWFSjNSR9BTicKrC2ewEBR9VrWf08mVYsr7N9+Cj2zZJ+5bqF7SWSDqHlrd5Le+LI5s7yE9WC0+cDbwEW0sIPLrL9SUkvB/5Z0qyxnv6NiOFl5Bg7Pdu32j6XVhjfOMbNPNz5LODvO7Fx+9nupeBsaeT4k14MXL2vH2Kf/662fWR93x19yzcD/9Y5nncB/17LbqTlw440BD0iRinFMXZakiarBYv3zKZN0IHBOavXA2/o5J4ey+CQ8cXASZ2Zos+RtA+A7cOHyF39z+p7OS1vFYbOXd1F0rT6fCBwILBEzX7VLlq+6u3V7Ye0x3YhaX9acbx3xL+siBiVzFaNcTdotmq1r6NNQnkG7WHBR/XCu2v5FOBS4AXAJtro7zTbSyVNpz354rdppyxPtX2jpHnASbWJC22fJ2kG8HXbszrbPg3oZZ5uBI6z/b0RHMs02gjvebRC/af1LMmX0p5BebKkZ9IecgywodqX1/XS6+uYRbs2eWrNYj0A+ALtFK+Bv7K9ZEv7ExFjk+IYERHRJ6dVIyIi+qQ4RkRE9ElxjIiI6JPiGBER0SfFMSIiok+KY0RERJ8Ux4iIiD4pjhEREX1+AbLgBDCeetvLAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jOnkFBcEIVAb" + }, + "source": [ + "### Volte ao início, extraia nova amostra e calcule a acurácia\n", + "* Observou que a acurácia mudou? Isso acontece porque extraimos uma nova amostra de treinamento.\n", + "* Quais os inconvenientes de termos uma métrica diferente para cada amostra do modelo preditivo?\n", + "* Como reportar os resultados do seu modelo?\n", + "* Como se assegurar acerca do valor mais ideal da métrica?\n", + " * use a Estatística a seu favor! --> Use Cross-Validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n", + "* Como funciona: divide o dataframe de treinamento em k partes (cada parte é um fold);\n", + " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n", + " * O processo é repetido k vezes, sendo que em cada iteração calcula as métricas desejadas (exemplo: acurácia);\n", + " * Desta forma o modelo é treinado e testado com todas as partes dos dados;\n", + " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n", + "\n", + " A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **valor de k**:\n", + " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n", + " * Quanto maior o valor de k --> menor o viés do CV --> Experimento Estatístico para mostrar o efeito.\n", + "\n", + "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HscfN-a1V043" + }, + "source": [ + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8x2UPwOYQPcI", + "outputId": "b587c430-3e4d-487c-838a-ffc3b8c5864b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com k = 10 folds (= 10 partes)\n", + "a_scores_CV = funcao_cross_val_score(ml_DT, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.44\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uxoplcea0byV", + "outputId": "597530be-6e07-452c-b22e-37d1c054769e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.9 , 0.98571429, 0.85714286, 0.92857143, 0.88571429,\n", + " 0.94285714, 0.92857143, 0.9 , 0.88571429, 0.92857143])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y3k-PcbN0o_i", + "outputId": "2a4a51a9-1636-4d75-aa07-ff75a7f00ad1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_scores_CV.mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9142857142857144" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "28332397-3b99-437c-e37c-387b116e6311", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n", + " 0.92857143 0.9 0.88571429 0.92857143]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lQNyqHCiKRUh" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qb0ZPyvKKRUp", + "outputId": "dbbbe053-f3e9-4190-d88e-78c92dca7544", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iL2tEdbqKY5P" + }, + "source": [ + "### Predições com o modelo treinado\n", + "* Faz predições usando o classificador (Decision Trees) para inferir na amostra de teste:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rfapj3OG13PG", + "outputId": "0a725c57-50d1-4151-a889-19103c0aeb1d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y_pred[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n", + " 1, 0, 0, 1, 1, 0, 1, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sc88ofqh16RT", + "outputId": "a6f0823a-b1a0-41f3-e6fa-77223c2d7415", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cecv-51TKgz-" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "cf7cc4d8-8cec-4603-a561-4484b7cd235b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3ySIXWeFVDlh" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t-KyMOWgRyQ4" + }, + "source": [ + "\n", + "\n", + "---\n", + "##### ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "---\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VTT_qynaPV6-", + "outputId": "5f6af706-b5b3-4b1b-f0bd-a1886f0a9e9f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "# Preparar o array de predições\n", + "a_scores_pred_treino = ml_DT.predict(X_treinamento)\n", + "a_scores_pred_treino[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0,\n", + " 0, 1, 0, 1, 1, 0, 0, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NgzcGE75PVKB", + "outputId": "259de4dd-4c60-4bed-b750-e6a7f51d40db", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "accuracy_score(y_treinamento, a_scores_pred_treino)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DL-b5ehHSeaV" + }, + "source": [ + "---\n", + "#### Criar Modelo usando classificador Naive Bayes\n", + "---" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mG3gUR4aSwD3" + }, + "source": [ + "from sklearn.naive_bayes import GaussianNB" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "N8KXRDsSS3uQ" + }, + "source": [ + "# Criando o modelo preditivo\n", + "modelo_v1 = GaussianNB()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tO9zI48tS3Wy", + "outputId": "dc906ec3-5010-486e-dbd8-78493fa23d2b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Treinando o modelo\n", + "modelo_v1.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "GaussianNB(priors=None, var_smoothing=1e-09)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5OdlSGHWS28K", + "outputId": "0a175639-5633-4b6d-a320-e8c929468659", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_pred_treino_NB = modelo_v1.predict(X_treinamento)\n", + "a_scores_pred_treino_NB[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0,\n", + " 0, 1, 0, 1, 0, 0, 0, 0])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aEFkIz3wS2gm", + "outputId": "2c656f9d-ba1c-47fc-80f6-98385c7420d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO SEM CROSS VALIDATION\n", + "accuracy_score(y_treinamento, a_scores_pred_treino_NB)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.8942857142857142" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vrjgRbCUT2PB", + "outputId": "8dbd3d1e-b7a7-46c1-b8d5-0e62b172a199", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TESTE\n", + "a_scores_pred_teste_NB = modelo_v1.predict(X_teste)\n", + "accuracy_score(y_teste, a_scores_pred_teste_NB)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.92" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1AvybYmQT2AU", + "outputId": "83397313-5911-4d70-be99-0e73645455c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Medir ACURÁCIA com dados de TREINO **COM** CROSS VALIDATION\n", + "# Cross-Validation com k = 10 folds\n", + "a_scores_CV_NB = cross_val_score(modelo_v1, X_treinamento, y_treinamento, cv = i_CV)\n", + "\n", + "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV_NB.mean(),4)}')\n", + "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV_NB.std(),4)}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 89.71000000000001\n", + "std médio das Acurácias calculadas pelo CV: 3.3099999999999996\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning. Ao todo serão ajustados 2X13X5X5X7= 4.550 modelos. Contando com 10 folds no Cross-Validation, então são 45.500 modelos.\n", + "d_parametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n", + " \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \n", + " \"max_depth\": [None, 2, 5, 9, 15], \n", + " \"min_samples_leaf\": [20, 40, 60, 80, 100], \n", + " \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BtajXuuUpGwq", + "outputId": "47780f80-f16c-4582-de59-64272fbcbb20", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 343 + } + }, + "source": [ + "d_parametros_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': ['gini', 'entropy'],\n", + " 'max_depth': [None, 2, 5, 9, 15],\n", + " 'max_leaf_nodes': [None, 2, 3, 4, 5, 10, 15],\n", + " 'min_samples_leaf': [20, 40, 60, 80, 100],\n", + " 'min_samples_split': [2,\n", + " 5,\n", + " 10,\n", + " 30,\n", + " 50,\n", + " 70,\n", + " 90,\n", + " 120,\n", + " 150,\n", + " 180,\n", + " 210,\n", + " 240,\n", + " 270,\n", + " 350,\n", + " 400]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_parametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_treinamento, y_treinamento)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25", + "outputId": "c671315c-7109-4ff6-d0c8-c78f12ff042b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "# Invoca a função com o modelo baseline\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.5s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.7s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.7s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1730s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0582s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 1.8s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0972s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Done 58 tasks | elapsed: 2.1s\n", + "[Parallel(n_jobs=-1)]: Done 130 tasks | elapsed: 2.7s\n", + "[Parallel(n_jobs=-1)]: Done 202 tasks | elapsed: 3.3s\n", + "[Parallel(n_jobs=-1)]: Done 290 tasks | elapsed: 3.9s\n", + "[Parallel(n_jobs=-1)]: Done 378 tasks | elapsed: 4.5s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1926s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Done 490 tasks | elapsed: 5.3s\n", + "[Parallel(n_jobs=-1)]: Done 698 tasks | elapsed: 6.7s\n", + "[Parallel(n_jobs=-1)]: Done 938 tasks | elapsed: 8.0s\n", + "[Parallel(n_jobs=-1)]: Done 1178 tasks | elapsed: 9.5s\n", + "[Parallel(n_jobs=-1)]: Done 1450 tasks | elapsed: 11.1s\n", + "[Parallel(n_jobs=-1)]: Done 1722 tasks | elapsed: 12.9s\n", + "[Parallel(n_jobs=-1)]: Done 2026 tasks | elapsed: 14.7s\n", + "[Parallel(n_jobs=-1)]: Done 2330 tasks | elapsed: 16.6s\n", + "[Parallel(n_jobs=-1)]: Done 2666 tasks | elapsed: 18.8s\n", + "[Parallel(n_jobs=-1)]: Done 3002 tasks | elapsed: 20.8s\n", + "[Parallel(n_jobs=-1)]: Done 3370 tasks | elapsed: 23.2s\n", + "[Parallel(n_jobs=-1)]: Done 3738 tasks | elapsed: 25.4s\n", + "[Parallel(n_jobs=-1)]: Done 4138 tasks | elapsed: 28.2s\n", + "[Parallel(n_jobs=-1)]: Done 4538 tasks | elapsed: 30.5s\n", + "[Parallel(n_jobs=-1)]: Done 4970 tasks | elapsed: 33.4s\n", + "[Parallel(n_jobs=-1)]: Done 5402 tasks | elapsed: 35.9s\n", + "[Parallel(n_jobs=-1)]: Done 5866 tasks | elapsed: 38.6s\n", + "[Parallel(n_jobs=-1)]: Done 6330 tasks | elapsed: 41.2s\n", + "[Parallel(n_jobs=-1)]: Done 6826 tasks | elapsed: 44.1s\n", + "[Parallel(n_jobs=-1)]: Done 7322 tasks | elapsed: 47.0s\n", + "[Parallel(n_jobs=-1)]: Done 7850 tasks | elapsed: 50.1s\n", + "[Parallel(n_jobs=-1)]: Done 8378 tasks | elapsed: 53.0s\n", + "[Parallel(n_jobs=-1)]: Done 8938 tasks | elapsed: 56.2s\n", + "[Parallel(n_jobs=-1)]: Done 9498 tasks | elapsed: 59.3s\n", + "[Parallel(n_jobs=-1)]: Done 10090 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 10682 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 11306 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 11930 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 12586 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 13242 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 13930 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 14618 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 15338 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 16058 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 16810 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 17562 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 18346 tasks | elapsed: 1.9min\n", + "[Parallel(n_jobs=-1)]: Done 19130 tasks | elapsed: 2.0min\n", + "[Parallel(n_jobs=-1)]: Done 19946 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 20762 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 21610 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 22458 tasks | elapsed: 2.3min\n", + "[Parallel(n_jobs=-1)]: Done 23338 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 24218 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 25130 tasks | elapsed: 2.6min\n", + "[Parallel(n_jobs=-1)]: Done 26042 tasks | elapsed: 2.7min\n", + "[Parallel(n_jobs=-1)]: Done 26986 tasks | elapsed: 2.8min\n", + "[Parallel(n_jobs=-1)]: Done 27930 tasks | elapsed: 2.9min\n", + "[Parallel(n_jobs=-1)]: Done 28906 tasks | elapsed: 3.1min\n", + "[Parallel(n_jobs=-1)]: Done 29882 tasks | elapsed: 3.2min\n", + "[Parallel(n_jobs=-1)]: Done 30890 tasks | elapsed: 3.3min\n", + "[Parallel(n_jobs=-1)]: Done 31898 tasks | elapsed: 3.4min\n", + "[Parallel(n_jobs=-1)]: Done 32938 tasks | elapsed: 3.6min\n", + "[Parallel(n_jobs=-1)]: Done 33978 tasks | elapsed: 3.7min\n", + "[Parallel(n_jobs=-1)]: Done 35050 tasks | elapsed: 3.8min\n", + "[Parallel(n_jobs=-1)]: Done 36122 tasks | elapsed: 3.9min\n", + "[Parallel(n_jobs=-1)]: Done 37226 tasks | elapsed: 4.1min\n", + "[Parallel(n_jobs=-1)]: Done 38330 tasks | elapsed: 4.2min\n", + "[Parallel(n_jobs=-1)]: Done 39466 tasks | elapsed: 4.3min\n", + "[Parallel(n_jobs=-1)]: Done 40602 tasks | elapsed: 4.5min\n", + "[Parallel(n_jobs=-1)]: Done 41770 tasks | elapsed: 4.6min\n", + "[Parallel(n_jobs=-1)]: Done 42938 tasks | elapsed: 4.8min\n", + "[Parallel(n_jobs=-1)]: Done 44138 tasks | elapsed: 4.9min\n", + "[Parallel(n_jobs=-1)]: Done 45338 tasks | elapsed: 5.1min\n", + "[Parallel(n_jobs=-1)]: Done 46570 tasks | elapsed: 5.2min\n", + "[Parallel(n_jobs=-1)]: Done 47802 tasks | elapsed: 5.4min\n", + "[Parallel(n_jobs=-1)]: Done 49066 tasks | elapsed: 5.5min\n", + "[Parallel(n_jobs=-1)]: Done 50330 tasks | elapsed: 5.7min\n", + "[Parallel(n_jobs=-1)]: Done 51626 tasks | elapsed: 5.8min\n", + "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 6.0min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 70}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 87.14\n", + "std médio das Acurácias calculadas pelo CV: 4.33\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "12 v13 0.735896\n", + "0 v1 0.135030\n", + "9 v10 0.090888\n", + "6 v7 0.025768\n", + "1 v2 0.012418\n", + "3 v4 0.000000\n", + "4 v5 0.000000\n", + "5 v6 0.000000\n", + "7 v8 0.000000\n", + "8 v9 0.000000\n", + "10 v11 0.000000\n", + "11 v12 0.000000\n", + "2 v3 0.000000\n", + "13 v14 0.000000\n", + "14 v15 0.000000\n", + "15 v16 0.000000\n", + "16 v17 0.000000\n", + "17 v18 0.000000\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0", + "outputId": "b6511d91-c6b6-4faa-ea66-73f0b6ecca4b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 753 + } + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf", + "outputId": "8d728e73-211e-44d7-f025-be3523e21cd0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "X_treinamento_DT, X_teste_DT = seleciona_colunas_relevantes(ml_DT2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "********** COLUNAS Relevantes ******\n", + "[ 0 9 12]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm", + "outputId": "f3cdfdc8-c5f5-401f-bd4e-5cd19149e689", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 103 + } + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 20,\n", + " 'min_samples_split': 70}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt", + "outputId": "f97be011-6ddc-45c9-9c57-ea995e6309c2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 120 + } + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_treinamento_DT, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='entropy',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=70, min_samples_split=20,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M2h3EpinRD5Q", + "outputId": "1ac155a6-6003-4efe-9168-5c071cc7b917", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT2, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 87.14\n", + "std médio das Acurácias calculadas pelo CV: 4.33\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3", + "outputId": "c9f15800-e330-4cfc-ede2-afcee536b089", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_parametros_DT, X_treinamento_DT, y_treinamento, X_teste_DT, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 0.0s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0129s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 0.0s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0358s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 16 tasks | elapsed: 0.1s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0443s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0788s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Done 44 tasks | elapsed: 0.2s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1434s.) Setting batch_size=32.\n", + "[Parallel(n_jobs=-1)]: Done 156 tasks | elapsed: 0.7s\n", + "[Parallel(n_jobs=-1)]: Done 380 tasks | elapsed: 2.1s\n", + "[Parallel(n_jobs=-1)]: Done 668 tasks | elapsed: 3.6s\n", + "[Parallel(n_jobs=-1)]: Done 956 tasks | elapsed: 5.2s\n", + "[Parallel(n_jobs=-1)]: Done 1308 tasks | elapsed: 7.1s\n", + "[Parallel(n_jobs=-1)]: Done 1660 tasks | elapsed: 9.0s\n", + "[Parallel(n_jobs=-1)]: Done 2076 tasks | elapsed: 10.7s\n", + "[Parallel(n_jobs=-1)]: Done 2492 tasks | elapsed: 11.8s\n", + "[Parallel(n_jobs=-1)]: Done 2972 tasks | elapsed: 13.1s\n", + "[Parallel(n_jobs=-1)]: Done 3452 tasks | elapsed: 14.5s\n", + "[Parallel(n_jobs=-1)]: Done 3996 tasks | elapsed: 16.1s\n", + "[Parallel(n_jobs=-1)]: Done 4540 tasks | elapsed: 17.6s\n", + "[Parallel(n_jobs=-1)]: Done 5148 tasks | elapsed: 19.3s\n", + "[Parallel(n_jobs=-1)]: Done 5756 tasks | elapsed: 21.1s\n", + "[Parallel(n_jobs=-1)]: Done 6428 tasks | elapsed: 22.9s\n", + "[Parallel(n_jobs=-1)]: Done 7100 tasks | elapsed: 24.8s\n", + "[Parallel(n_jobs=-1)]: Done 7836 tasks | elapsed: 26.9s\n", + "[Parallel(n_jobs=-1)]: Done 8572 tasks | elapsed: 28.8s\n", + "[Parallel(n_jobs=-1)]: Done 9372 tasks | elapsed: 31.1s\n", + "[Parallel(n_jobs=-1)]: Done 10172 tasks | elapsed: 33.4s\n", + "[Parallel(n_jobs=-1)]: Done 11036 tasks | elapsed: 35.9s\n", + "[Parallel(n_jobs=-1)]: Done 11900 tasks | elapsed: 38.3s\n", + "[Parallel(n_jobs=-1)]: Done 12828 tasks | elapsed: 41.0s\n", + "[Parallel(n_jobs=-1)]: Done 13756 tasks | elapsed: 43.7s\n", + "[Parallel(n_jobs=-1)]: Done 14748 tasks | elapsed: 46.6s\n", + "[Parallel(n_jobs=-1)]: Done 15740 tasks | elapsed: 49.5s\n", + "[Parallel(n_jobs=-1)]: Done 16796 tasks | elapsed: 52.5s\n", + "[Parallel(n_jobs=-1)]: Done 17852 tasks | elapsed: 55.6s\n", + "[Parallel(n_jobs=-1)]: Done 18972 tasks | elapsed: 59.0s\n", + "[Parallel(n_jobs=-1)]: Done 20092 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 21276 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 22460 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 23708 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 24956 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 26268 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 27580 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 28956 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 30332 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 31772 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 33212 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 34716 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 36220 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 37788 tasks | elapsed: 1.9min\n", + "[Parallel(n_jobs=-1)]: Done 39356 tasks | elapsed: 2.0min\n", + "[Parallel(n_jobs=-1)]: Done 40988 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 42620 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 44316 tasks | elapsed: 2.3min\n", + "[Parallel(n_jobs=-1)]: Done 46012 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 47772 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 49532 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 51356 tasks | elapsed: 2.6min\n", + "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 2.7min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 60, 'min_samples_split': 2}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 89.29\n", + "std médio das Acurácias calculadas pelo CV: 2.73\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "2 v3 0.691283\n", + "0 v1 0.177569\n", + "1 v2 0.131148\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL", + "outputId": "cd1291ea-34ae-4c8a-f617-aca1daf4e5d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 103 + } + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 20,\n", + " 'min_samples_split': 70}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q", + "outputId": "782be18c-e89e-438a-fe48-8eb48a266fdc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 103 + } + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 60,\n", + " 'min_samples_split': 2}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFoK1ZGrRHf3", + "outputId": "bcdcb58f-3499-4e2d-ec50-88d117d0eeee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT3, X_treinamento_DT, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 89.29\n", + "std médio das Acurácias calculadas pelo CV: 2.73\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_teste_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae", + "outputId": "68be0407-57ec-4542-ef23-09eef53d95c9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_DT)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9333333333333333" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier)quanto para Regressão (RandomForestRegressor).\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * É um Boosting Ensemble Method (pois constrói muitas árvores). Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como Feature Selection, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer os dados sejam normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Desvantagens**\n", + " * **Recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais parâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais parâmetros do Random Forest." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu", + "outputId": "f1658397-246a-42de-99c2-4bb57166dece", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 154 + } + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia...\n", + "ml_RF= RandomForestClassifier(n_estimators=100, min_samples_split= 2, max_features=\"auto\", random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=100,\n", + " n_jobs=None, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E25BIxM0RTzs", + "outputId": "1e988b9c-76c1-41a1-d21b-9d7d1188175f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 96.28999999999999\n", + "std médio das Acurácias calculadas pelo CV: 2.94\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85", + "outputId": "9207c10f-4166-4147-8f19-8a84bf941ee9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.98571429 0.95714286 0.92857143 1.\n", + " 0.97142857 0.98571429 0.94285714 0.97142857]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw", + "outputId": "82b0a991-1af3-40ff-b22e-fc0c5829b74b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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UUREJIAyRxER8SxYH+VQcBQREc+CdbWqhlVFREQCKHMUERHPgjRxVOYoIiISSJmjiIh4F6SpozJHERGRAMocRUTEs2B9lEOZo4iIeGaW/K9zt2nFzWyema0xs9Vm9rC/PJ+ZfW9mf/n/mdfrfSk4iohIehMFPOacqwjUBB40s4pAf2COc64sMMf/2RMFRxER8cxS4HUuzrldzrkV/vdHgLVAUaA5MMp/2iighdf7UnAUEZE0xcy6m9myOK/uiZxbArgKWAwUds7t8h/aDRT22gctyBEREe9SYD2Oc244MPycTZvlAL4E+jjnDlucCUvnnDMz57UPCo4iIuJZaq1WNbNwfIFxrHNusr94j5kVcc7tMrMiwF6v9WtYVURE0hXzpYgfA2udc4PjHJoCdPW/7wp847UNZY4iIuJZKn0rR22gC7DKzH71lz0JvApMNLNuwFagndcGFBxFRCRdcc4tIOHZzobJ0YaCo4iIeBac++MoOIqIyAXQlx2LiIhkEMocRUTkAgRn6qjMUUREJIAyRxER8UxzjiIiIhmEMkcREfEsSBNHBUcREfFOw6oiIiIZhDJHERHxLLW+lSOlKXMUEREJoMxRRES8C87EUcFRRES8C9LYqGFVERGRQMocRUTEMz3KISIikkEocxQREc+C9VEOBUcREfEuOGOjhlVFREQCKXMUERHPgjRxVOYoIiISSJmjiIh4pkc5REREMghljiIi4pke5RAREQmgYVUREZEMQsFRREQkgIKjiIhIAM05ioiIZ8E656jgKCIingXralUNq4qIiARQ5igiIp4F67CqMkcREZEAyhxFRMSzIE0cFRxFROQCBGl01LCqiIhIAGWOIiLimR7lEBERySCUOYqIiGd6lENERCSDUOYoIiKeBWniqOAoIiIXIEijo4ZVRUREAihzFBERz/Qoh4iISAahzFFERDwL1kc5zDmX2n0QERFJUzSsKiIiEkDBUUREJICCo4iISAAFR0lTzCzazH41sz/M7Aszy3YBdX1qZm3870eYWcVEzq1nZrU8tLHFzAoktTzgnKPn2dazZtb3fPsoIudPwVHSmuPOuWrOucrAKaBH3INm5mmFtXPuXufcmkROqQecd3AUkeCk4Chp2U9AGX9W95OZTQHWmFmomb1uZkvN7Hczux/AfN4zs/VmNhsodLoiM/vBzGr43zc2sxVm9puZ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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_RF= {'bootstrap': [True, False]} #,\n", + "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n", + "# 'max_features': ['auto', 'sqrt'],\n", + "# 'min_samples_leaf': [1, 2, 4],\n", + "# 'min_samples_split': [2, 5, 10],\n", + "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat", + "outputId": "e43cf8dc-3af7-4726-b906-26adf07cfdd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 579 + } + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_parametros_RF, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 2 candidates, totalling 20 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 0.4s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 0.9s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 2.1s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 3.0s\n", + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 4.4s remaining: 0.0s\n", + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 4.4s finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'bootstrap': False}\n", + "\n", + "RandomForestClassifier *********************************************************************************************************\n" + ], + "name": "stdout" + }, + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Invoca a função\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mml_RF2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbest_params\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mGridSearchOptimizer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mml_RF\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'ml_RF2'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md_parametros_RF\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mi_CV\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml_colunas\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mGridSearchOptimizer\u001b[0;34m(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'\\nRandomForestClassifier *********************************************************************************************************'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n\u001b[0;32m---> 23\u001b[0;31m \u001b[0mmax_depth\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_depth'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 24\u001b[0m \u001b[0mmax_features\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_features'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[0mmin_samples_leaf\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'min_samples_leaf'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'max_depth'" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMJcAdLlTQa0" + }, + "source": [ + "## Visualizar o resultado\n", + "> Implementar a visualização do RandomForest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "X_treinamento_RF, X_teste_RF = seleciona_colunas_relevantes(ml_RF2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF2.fit(X_treinamento_RF, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF2, X_treinamento_RF, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF2.predict(X_teste_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos parametros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "navUWMwHi44D" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name=\"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting vc Stacking\n", + "### **Bagging**\n", + "* Objetivo é reduzir a variância;\n", + "\n", + "#### Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_treinamento;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n", + "\n", + "#### Vantagens\n", + "* Reduz overfitting;\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "___ \n", + "### **Boosting**\n", + "* Objetivo é melhorar acurácia;\n", + "\n", + "#### Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_treinamento;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_treinamento e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_treinamento a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n", + "\n", + "#### Vantagens\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + "* Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fgUrkmPk4dr" + }, + "source": [ + "___\n", + "# STACKING\n", + "\n", + "![Stacking](https://github.com/MathMachado/Materials/blob/master/Stacking.png?raw=true)\n", + "\n", + "Kd a referência desta figura???" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0jxx3ETpOdm" + }, + "source": [ + "___\n", + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Quando nada funciona, AdaBoost funciona!\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## O que é AdaBoost (Adaptive Boosting)?\n", + "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n", + "\n", + "## Parâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "No exemplo a seguir, vou usar RandomForestClassifier com os parâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Parâmetros otimizados!\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)\n", + "# Instancia AdaBoostClassifier\n", + "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_AB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tBOuTywWRm91" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_AB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os parametros otimizados...\n", + "y_pred = ml_AB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_parametros_AB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos parâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB = GradientBoostingClassifier(n_estimators = 100, min_samples_split = 2)\n", + "\n", + "# Treina... \n", + "ml_GB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PKOG1ugSRvLM" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os parâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de parâmetros para o parameter tunning.\n", + "d_parametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_treinamento.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_parametros_GB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Parametros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_treinamento_GB, X_teste_GB = seleciona_colunas_relevantes(ml_GB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_treinamento_GB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB2, X_treinamento_GB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_teste_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Parâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os parâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB= XGBClassifier(silent=False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S77LljiQR_16" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos parâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de parâmetros para XGBoost:\n", + "d_parametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_parametros_XGB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Parametros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_treinamento_XGB, X_teste_XGB= seleciona_colunas_relevantes(ml_XGB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_treinamento_XGB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB2, X_treinamento_XGB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_teste_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM\n", + "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_treinamento, y_treinamento, top_n=X_treinamento.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Uf1RML7xETY" + }, + "source": [ + "# WOE e IV\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TBNRfYZCyhMP" + }, + "source": [ + "## Construção do exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gIIroyyP4ZRZ" + }, + "source": [ + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PzQQdrkf1ohX" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n", + "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n", + "df_X2['target']= df_y['target']\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-OpwIpx4hXJ" + }, + "source": [ + "df_X2['target'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yZfqSvbKzeJ3" + }, + "source": [ + "def Constroi_Buckets(df, i, k= 10):\n", + " coluna= 'v'+ str(i)\n", + " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n", + " df= df.drop(columns= [coluna], axis= 1)\n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V6Nrpsx60HD3" + }, + "source": [ + "for i in np.arange(1,19):\n", + " df_X2= Constroi_Buckets(df_X2, i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2Fbh41-03OB" + }, + "source": [ + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O9r5BeWVxIr3" + }, + "source": [ + "# Função para calcular WOE e IV\n", + "def calculate_woe_iv(dataset, feature, target):\n", + "\n", + " def codethem(IV):\n", + " if IV < 0.02: return 'Useless'\n", + " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n", + " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n", + " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n", + " elif IV >= 0.5: return 'Suspicious'\n", + " else: return 'None'\n", + "\n", + " lst = []\n", + " for i in range(dataset[feature].nunique()):\n", + " val = list(dataset[feature].unique())[i]\n", + " lst.append({\n", + " 'Value': val,\n", + " 'All': dataset[dataset[feature] == val].count()[feature],\n", + " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n", + " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n", + " })\n", + " \n", + " dset = pd.DataFrame(lst)\n", + " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n", + " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n", + " dset['Mean']= dset['All']/dset['All'].sum()\n", + " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n", + " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n", + " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n", + " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n", + "\n", + " dset['Predictive_Power']= dset['IV'].map(codethem)\n", + " iv = dset['IV'].sum() \n", + " dset = dset.sort_values(by='IV') \n", + " return dset, iv" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8WGjWH63nx_" + }, + "source": [ + "df_Lab = df_X2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-N6xr1MgxTiz" + }, + "source": [ + "def calcula_Predictive_Power(df_Lab, coluna):\n", + " print('WoE and IV for column: {}'.format(coluna))\n", + " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n", + " print(df)\n", + " print('IV score: {:.2f}'.format(iv))\n", + " print('\\n')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayqN_7WnxVq9" + }, + "source": [ + "for i in np.arange(1,19):\n", + " coluna= 'v'+str(i)+'_Bucket'\n", + " calcula_Predictive_Power(df_Lab, coluna)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aZUNOgmSgAmq" + }, + "source": [ + "!pip install featuretools" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_sxdONzsh9rb" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p5_ynGo1dBJJ" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TqJRJXUhiDqf" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n", + "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n", + "df_X2['id'] = range(0,1000)\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nR56bGGngk-W" + }, + "source": [ + "# Automated feature engineering\n", + "import featuretools as ft\n", + "import featuretools.variable_types as vtypes\n", + "\n", + "es= ft.EntitySet(id = 'simulacao')\n", + "\n", + "# adding a dataframe \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n", + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOJ4Tr5Ogk6M" + }, + "source": [ + "es['df_X2'].variables" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1uXPqHDZgkys" + }, + "source": [ + "variable_types = {'idade': vtypes.Categorical}\n", + " \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n", + "\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dnbYTBqugkvm" + }, + "source": [ + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I2v_jetdgkr7" + }, + "source": [ + "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZiRBvHXgkoJ" + }, + "source": [ + "feature_matrix.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JYVM3StS-g0E" + }, + "source": [ + "### Importar as libraries necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dyliPChh-jPk" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lAl9ZwP_0-d0" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv'\n", + "df_cc = pd.read_csv(url)" + ], + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w6lN8FjJ12VU", + "outputId": "0d825f64-aa57-4d12-ca42-e3909b82e384", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 379 + } + }, + "source": [ + "df_cc.head(10)" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TimeV1V2V3V4V5V6V7V8V9V10V11V12V13V14V15V16V17V18V19V20V21V22V23V24V25V26V27V28AmountClass
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.620.0
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.690.0
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.660.0
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.500.0
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.990.0
52-0.4259660.9605231.141109-0.1682520.420987-0.0297280.4762010.260314-0.568671-0.3714071.3412620.359894-0.358091-0.1371340.5176170.401726-0.0581330.068653-0.0331940.084968-0.208254-0.559825-0.026398-0.371427-0.2327940.1059150.2538440.0810803.670.0
641.2296580.1410040.0453711.2026130.1918810.272708-0.0051590.0812130.464960-0.099254-1.416907-0.153826-0.7510630.1673720.050144-0.4435870.002821-0.611987-0.045575-0.219633-0.167716-0.270710-0.154104-0.7800550.750137-0.2572370.0345070.0051684.990.0
77-0.6442691.4179641.074380-0.4921990.9489340.4281181.120631-3.8078640.6153751.249376-0.6194680.2914741.757964-1.3238650.686133-0.076127-1.222127-0.3582220.324505-0.1567421.943465-1.0154550.057504-0.649709-0.415267-0.051634-1.206921-1.08533940.800.0
87-0.8942860.286157-0.113192-0.2715262.6695993.7218180.3701450.851084-0.392048-0.410430-0.705117-0.110452-0.2862540.074355-0.328783-0.210077-0.4997680.1187650.5703280.052736-0.073425-0.268092-0.2042331.0115920.373205-0.3841570.0117470.14240493.200.0
99-0.3382621.1195931.044367-0.2221870.499361-0.2467610.6515830.069539-0.736727-0.3668461.0176140.8363901.006844-0.4435230.1502190.739453-0.5409800.4766770.4517730.203711-0.246914-0.633753-0.120794-0.385050-0.0697330.0941990.2462190.0830763.680.0
\n", + "
" + ], + "text/plain": [ + " Time V1 V2 V3 ... V27 V28 Amount Class\n", + "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n", + "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n", + "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n", + "5 2 -0.425966 0.960523 1.141109 ... 0.253844 0.081080 3.67 0.0\n", + "6 4 1.229658 0.141004 0.045371 ... 0.034507 0.005168 4.99 0.0\n", + "7 7 -0.644269 1.417964 1.074380 ... -1.206921 -1.085339 40.80 0.0\n", + "8 7 -0.894286 0.286157 -0.113192 ... 0.011747 0.142404 93.20 0.0\n", + "9 9 -0.338262 1.119593 1.044367 ... 0.246219 0.083076 3.68 0.0\n", + "\n", + "[10 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jrHdWYBryKDQ" + }, + "source": [ + "### Normalizar os nomes das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fGMvMcmYyUtV", + "outputId": "14ce428c-6846-428b-8413-cd4a46485779", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 103 + } + }, + "source": [ + "df_cc.columns" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['Time', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6', 'V7', 'V8', 'V9', 'V10',\n", + " 'V11', 'V12', 'V13', 'V14', 'V15', 'V16', 'V17', 'V18', 'V19', 'V20',\n", + " 'V21', 'V22', 'V23', 'V24', 'V25', 'V26', 'V27', 'V28', 'Amount',\n", + " 'Class'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 62 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pMGifxs2yGPL", + "outputId": "735fc6c3-c3ba-4cba-feba-d5461d47eedf", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_cc.columns = [coluna.lower() for coluna in df_cc.columns]\n", + "df_cc.head()" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
timev1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18v19v20v21v22v23v24v25v26v27v28amountclass
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.620.0
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.690.0
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.660.0
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.500.0
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.990.0
\n", + "
" + ], + "text/plain": [ + " time v1 v2 v3 ... v27 v28 amount class\n", + "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n", + "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n", + "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M47GS1cK2NdD", + "outputId": "1aeb156c-862b-49b8-ac61-1ae7d18b8a21", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_cc.shape" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12842, 31)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b2QBZFbR3W_q", + "outputId": "66a283a2-eb4c-4b9f-fbf8-218601fbc749", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "df_cc['class'].value_counts()" + ], + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.0 12785\n", + "1.0 56\n", + "Name: class, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BpLSPuhIyjO1", + "outputId": "4cb83ec3-098f-4400-d6cb-774773526c8b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "classes2 = {0: 'nao-fraude', 1: 'fraude'}\n", + "df_classes = df_cc['class'].value_counts().rename(index = classes2)\n", + "df_classes.head()" + ], + "execution_count": 15, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "nao-fraude 12785\n", + "fraude 56\n", + "Name: class, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RnhS_KMizHbw", + "outputId": "56721a15-b9c0-440a-ae04-1df33bca7703", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 296 + } + }, + "source": [ + "sns.countplot(x = 'class', data = df_cc)" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZEAAAEGCAYAAACkQqisAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAS90lEQVR4nO3df6xf9X3f8ecrdkiaLon5ccdS26u9xupk0kyhFmGNNFV4AsO6GFUkImqLS61400h/7FcD3Va3JEzNko2FtKGyioNBaQglzfA2WmZB2uxHMFwKJfwo44o0wRaEG2xIW5qkzt774/u5yTfuvfbNx/5+v1zu8yFd3XPe53PO+RzJ4sU553M+N1WFJEk9XjHpDkiSli5DRJLUzRCRJHUzRCRJ3QwRSVK3lZPuwLidccYZtW7dukl3Q5KWlPvvv/8rVTV1dH3Zhci6deuYnp6edDckaUlJ8sX56j7OkiR1M0QkSd0MEUlSN0NEktTNEJEkdTNEJEndDBFJUjdDRJLUzRCRJHVbdl+sn6gf/tc3TboLegm6/4OXTboL0kR4JyJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqdvIQiTJ7iTPJnl4qPbBJH+S5KEkn06yamjbVUlmkjye5IKh+pZWm0ly5VB9fZL9rf7JJKeM6lokSfMb5Z3IjcCWo2r7gDdV1ZuB/wtcBZBkI3ApcFbb56NJViRZAfwGcCGwEXhXawvwAeDaqnojcBjYPsJrkSTNY2QhUlWfBQ4dVfsfVXWkrd4DrGnLW4FbqurrVfUFYAY4p/3MVNWTVfUN4BZga5IA5wG3tf33ABeP6lokSfOb5DuRnwF+ry2vBp4a2nag1Raqnw48PxRIc/V5JdmRZDrJ9Ozs7EnqviRpIiGS5N8AR4CPj+N8VbWrqjZV1aapqalxnFKSloWxz+Kb5KeBHwM2V1W18kFg7VCzNa3GAvXngFVJVra7keH2kqQxGeudSJItwC8Cb6+qF4c27QUuTfKqJOuBDcC9wH3AhjYS6xQGL9/3tvD5DHBJ238bcPu4rkOSNDDKIb6fAD4H/GCSA0m2A78OvBbYl+TBJL8JUFWPALcCjwK/D1xRVd9sdxnvAe4EHgNubW0B3gv8iyQzDN6R3DCqa5EkzW9kj7Oq6l3zlBf8D31VXQNcM0/9DuCOeepPMhi9JUmaEL9YlyR1M0QkSd0MEUlSN0NEktTNEJEkdTNEJEndDBFJUjdDRJLUzRCRJHUzRCRJ3QwRSVI3Q0SS1M0QkSR1M0QkSd0MEUlSN0NEktTNEJEkdTNEJEndDBFJUjdDRJLUzRCRJHUzRCRJ3QwRSVI3Q0SS1G1kIZJkd5Jnkzw8VDstyb4kT7Tfp7Z6klyXZCbJQ0nOHtpnW2v/RJJtQ/UfTvL5ts91STKqa5EkzW+UdyI3AluOql0J3FVVG4C72jrAhcCG9rMDuB4GoQPsBN4KnAPsnAue1ubdQ/sdfS5J0oiNLESq6rPAoaPKW4E9bXkPcPFQ/aYauAdYleQNwAXAvqo6VFWHgX3AlrbtdVV1T1UVcNPQsSRJYzLudyJnVtXTbfkZ4My2vBp4aqjdgVY7Vv3APPV5JdmRZDrJ9Ozs7IldgSTpWyb2Yr3dQdSYzrWrqjZV1aapqalxnFKSloVxh8iX26Mo2u9nW/0gsHao3ZpWO1Z9zTx1SdIYjTtE9gJzI6y2AbcP1S9ro7TOBV5oj73uBM5Pcmp7oX4+cGfb9tUk57ZRWZcNHUuSNCYrR3XgJJ8AfhQ4I8kBBqOsfg24Ncl24IvAO1vzO4CLgBngReBygKo6lOR9wH2t3dVVNfey/p8xGAH2PcDvtR9J0hiNLESq6l0LbNo8T9sCrljgOLuB3fPUp4E3nUgfJUknxi/WJUndDBFJUjdDRJLUzRCRJHUzRCRJ3QwRSVI3Q0SS1M0QkSR1M0QkSd0MEUlSN0NEktTNEJEkdTNEJEndDBFJUjdDRJLUzRCRJHUzRCRJ3QwRSVI3Q0SS1M0QkSR1M0QkSd0MEUlSN0NEktRtIiGS5J8neSTJw0k+keTVSdYn2Z9kJsknk5zS2r6qrc+07euGjnNVqz+e5IJJXIskLWdjD5Ekq4GfAzZV1ZuAFcClwAeAa6vqjcBhYHvbZTtwuNWvbe1IsrHtdxawBfhokhXjvBZJWu4m9ThrJfA9SVYCrwGeBs4Dbmvb9wAXt+WtbZ22fXOStPotVfX1qvoCMAOcM6b+S5KYQIhU1UHgQ8CXGITHC8D9wPNVdaQ1OwCsbsurgafavkda+9OH6/Ps8x2S7EgynWR6dnb25F6QJC1jk3icdSqDu4j1wPcB38vgcdTIVNWuqtpUVZumpqZGeSpJWlYm8TjrHwJfqKrZqvor4HeBtwGr2uMtgDXAwbZ8EFgL0La/HnhuuD7PPpKkMZhEiHwJODfJa9q7jc3Ao8BngEtam23A7W15b1unbb+7qqrVL22jt9YDG4B7x3QNkiQGL7jHqqr2J7kN+CPgCPAAsAv478AtSd7faje0XW4Abk4yAxxiMCKLqnokya0MAugIcEVVfXOsFyNJy9zYQwSgqnYCO48qP8k8o6uq6mvAOxY4zjXANSe9g5KkRfGLdUlSN0NEktTNEJEkdTNEJEndFhUiSe5aTE2StLwcc3RWklczmNvqjPaledqm17HAFCOSpOXjeEN8/wnwCwymJ7mfb4fIV4FfH2G/JElLwDFDpKo+DHw4yc9W1UfG1CdJ0hKxqI8Nq+ojSX4EWDe8T1XdNKJ+SZKWgEWFSJKbgR8AHgTmphYpwBCRpGVssdOebAI2tokPJUkCFv+dyMPA3xplRyRJS89i70TOAB5Nci/w9bliVb19JL2SJC0Jiw2RXxllJyRJS9NiR2f94ag7IklaehY7OuvPGIzGAjgFeCXwF1X1ulF1TJL00rfYO5HXzi23P2m7FTh3VJ2SJC0N3/UsvjXwX4ALRtAfSdISstjHWT8+tPoKBt+NfG0kPZIkLRmLHZ31j4eWjwB/yuCRliRpGVvsO5HLR90RSdLSs9g/SrUmyaeTPNt+PpVkzag7J0l6aVvsi/WPAXsZ/F2R7wP+a6tJkpaxxYbIVFV9rKqOtJ8bganekyZZleS2JH+S5LEkfz/JaUn2JXmi/T61tU2S65LMJHkoydlDx9nW2j+RZFtvfyRJfRYbIs8l+ckkK9rPTwLPncB5Pwz8flX9XeDvAY8BVwJ3VdUG4K62DnAhsKH97ACuB0hyGrATeCtwDrBzLngkSeOx2BD5GeCdwDPA08AlwE/3nDDJ64F/ANwAUFXfqKrnGYz22tOa7QEubstbgZva9yn3AKuSvIHBdyr7qupQVR0G9gFbevokSeqz2BC5GthWVVNV9TcZhMqvdp5zPTALfCzJA0l+K8n3AmdW1dOtzTPAmW15NfDU0P4HWm2huiRpTBYbIm9u/7cPQFUdAt7Sec6VwNnA9VX1FuAv+Pajq7njF9+eq+uEJdmRZDrJ9Ozs7Mk6rCQte4sNkVcMv29o7yMW+6Hi0Q4AB6pqf1u/jUGofLk9pqL9frZtPwisHdp/TastVP9rqmpXVW2qqk1TU93jASRJR1lsiPxH4HNJ3pfkfcD/Af5Dzwmr6hngqSQ/2EqbgUcZDCGeG2G1Dbi9Le8FLmujtM4FXmiPve4Ezk9yagu481tNkjQmi/1i/aYk08B5rfTjVfXoCZz3Z4GPJzkFeBK4nEGg3ZpkO/BFBi/yAe4ALgJmgBdbW6rqUAu0+1q7q9tjNknSmCz6kVQLjRMJjuFjPchgEsejbZ6nbQFXLHCc3cDuk9EnSdJ377ueCl6SpDmGiCSpmyEiSepmiEiSuhkikqRuhogkqZshIknqZohIkroZIpKkboaIJKmbISJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqZshIknqZohIkroZIpKkboaIJKmbISJJ6maISJK6TSxEkqxI8kCS/9bW1yfZn2QmySeTnNLqr2rrM237uqFjXNXqjye5YDJXIknL1yTvRH4eeGxo/QPAtVX1RuAwsL3VtwOHW/3a1o4kG4FLgbOALcBHk6wYU98lSUwoRJKsAf4R8FttPcB5wG2tyR7g4ra8ta3Ttm9u7bcCt1TV16vqC8AMcM54rkCSBJO7E/nPwC8C/6+tnw48X1VH2voBYHVbXg08BdC2v9Daf6s+zz7fIcmOJNNJpmdnZ0/mdUjSsjb2EEnyY8CzVXX/uM5ZVbuqalNVbZqamhrXaSXpZW/lBM75NuDtSS4CXg28DvgwsCrJyna3sQY42NofBNYCB5KsBF4PPDdUnzO8jyRpDMZ+J1JVV1XVmqpax+DF+N1V9RPAZ4BLWrNtwO1teW9bp22/u6qq1S9to7fWAxuAe8d0GZIkJnMnspD3ArckeT/wAHBDq98A3JxkBjjEIHioqkeS3Ao8ChwBrqiqb46/25K0fE00RKrqD4A/aMtPMs/oqqr6GvCOBfa/BrhmdD2UJB2LX6xLkroZIpKkboaIJKmbISJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqZshIknqZohIkroZIpKkboaIJKmbISJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqdvYQyTJ2iSfSfJokkeS/Hyrn5ZkX5In2u9TWz1Jrksyk+ShJGcPHWtba/9Ekm3jvhZJWu4mcSdyBPiXVbUROBe4IslG4ErgrqraANzV1gEuBDa0nx3A9TAIHWAn8FbgHGDnXPBIksZj7CFSVU9X1R+15T8DHgNWA1uBPa3ZHuDitrwVuKkG7gFWJXkDcAGwr6oOVdVhYB+wZYyXIknL3kTfiSRZB7wF2A+cWVVPt03PAGe25dXAU0O7HWi1herznWdHkukk07Ozsyet/5K03E0sRJL8DeBTwC9U1VeHt1VVAXWyzlVVu6pqU1VtmpqaOlmHlaRlbyIhkuSVDALk41X1u6385faYivb72VY/CKwd2n1Nqy1UlySNySRGZwW4AXisqv7T0Ka9wNwIq23A7UP1y9oorXOBF9pjrzuB85Oc2l6on99qkqQxWTmBc74N+Cng80kebLVfAn4NuDXJduCLwDvbtjuAi4AZ4EXgcoCqOpTkfcB9rd3VVXVoPJcgSYIJhEhV/S8gC2zePE/7Aq5Y4Fi7gd0nr3eSpO+GX6xLkroZIpKkboaIJKmbISJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqZshIknqZohIkroZIpKkboaIJKmbISJJ6maISJK6GSKSpG6GiCSpmyEiSepmiEiSuhkikqRuhogkqZshIknqtuRDJMmWJI8nmUly5aT7I0nLyZIOkSQrgN8ALgQ2Au9KsnGyvZKk5WPlpDtwgs4BZqrqSYAktwBbgUcn2itpQr509Q9Nugt6Cfrbv/z5kR17qYfIauCpofUDwFuPbpRkB7Cjrf55ksfH0Lfl4AzgK5PuxEtBPrRt0l3QX+e/zzk7czKO8v3zFZd6iCxKVe0Cdk26Hy83SaaratOk+yHNx3+f47Gk34kAB4G1Q+trWk2SNAZLPUTuAzYkWZ/kFOBSYO+E+yRJy8aSfpxVVUeSvAe4E1gB7K6qRybcreXER4R6KfPf5xikqibdB0nSErXUH2dJkibIEJEkdTNEdFzHm1omyauSfLJt359k3fh7qeUoye4kzyZ5eIHtSXJd+7f5UJKzx93HlztDRMe0yKlltgOHq+qNwLXAB8bbSy1jNwJbjrH9QmBD+9kBXD+GPi0rhoiO51tTy1TVN4C5qWWGbQX2tOXbgM1JTsonstKxVNVngUPHaLIVuKkG7gFWJXnDeHq3PBgiOp75ppZZvVCbqjoCvACcPpbeSce2mH+/OgGGiCSpmyGi41nM1DLfapNkJfB64Lmx9E46NqdGGjFDRMezmKll9gJz09heAtxdfsWql4a9wGVtlNa5wAtV9fSkO/VysqSnPdHoLTS1TJKrgemq2gvcANycZIbBS85LJ9djLSdJPgH8KHBGkgPATuCVAFX1m8AdwEXADPAicPlkevry5bQnkqRuPs6SJHUzRCRJ3QwRSVI3Q0SS1M0QkSR1M0SkMUryK0n+1aT7IZ0shogkqZshIo1Qksva37H44yQ3H7Xt3Unua9s+leQ1rf6OJA+3+mdb7awk9yZ5sB1vwySuRzqaHxtKI5LkLODTwI9U1VeSnAb8HPDnVfWhJKdX1XOt7fuBL1fVR5J8HthSVQeTrKqq55N8BLinqj7epp9ZUVV/Oalrk+Z4JyKNznnA71TVVwCq6ui/e/GmJP+zhcZPAGe1+v8GbkzybgZTzQB8DvilJO8Fvt8A0UuFISJNzo3Ae6rqh4BfBV4NUFX/FPi3DGafvb/dsfw28HbgL4E7kpw3mS5L38kQkUbnbuAdSU4HaI+zhr0WeDrJKxncidDa/UBV7a+qXwZmgbVJ/g7wZFVdB9wOvHksVyAdh7P4SiPSZju+BvjDJN8EHgD+dKjJvwP2MwiK/QxCBeCD7cV5gLuAPwbeC/xUkr8CngH+/VguQjoOX6xLkrr5OEuS1M0QkSR1M0QkSd0MEUlSN0NEktTNEJEkdTNEJEnd/j/eEDTdweaeVQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pzjW3Bf_3h7J", + "outputId": "b7bc849f-e680-4f11-e8d6-8db4a568452b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "56/12842" + ], + "execution_count": 17, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.004360691481077714" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9bWDX9H12k5g" + }, + "source": [ + "### Drop NaN" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "27ob8tRR21TB", + "outputId": "13dd0a84-505e-4e94-8e76-9fc617d58664", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 561 + } + }, + "source": [ + "df_cc.isna().sum()" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "time 0\n", + "v1 0\n", + "v2 0\n", + "v3 0\n", + "v4 0\n", + "v5 0\n", + "v6 0\n", + "v7 0\n", + "v8 0\n", + "v9 0\n", + "v10 1\n", + "v11 1\n", + "v12 1\n", + "v13 1\n", + "v14 1\n", + "v15 1\n", + "v16 1\n", + "v17 1\n", + "v18 1\n", + "v19 1\n", + "v20 1\n", + "v21 1\n", + "v22 1\n", + "v23 1\n", + "v24 1\n", + "v25 1\n", + "v26 1\n", + "v27 1\n", + "v28 1\n", + "amount 1\n", + "class 1\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HCTCnZUWzgrj" + }, + "source": [ + "### DataViz (= Data Visualization)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m9H7zUA40Arv" + }, + "source": [ + "[X1, X2, ..., Xn, y]" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x2RHoMGZzndC", + "outputId": "7637945b-cc58-4c83-961b-a8622a95bf14", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 400 + } + }, + "source": [ + "# Boxplot da variável 'v1' por variável-target (class):\n", + "sns.catplot(x = 'class', y = 'v6', kind = 'box', data = df_cc)" + ], + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0pjVw0t41Wjm", + "outputId": "ac634515-7250-4153-d501-cb4af565b1ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "len(df_cc.columns)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "31" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 77 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bwT2CdAf1Noy", + "outputId": "00a8bbe0-f2ab-475b-aefe-8cceb71df343", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 700 + } + }, + "source": [ + "figura = plt.figure(figsize= (16, 12))\n", + "\n", + "for i in range(1, 29):\n", + " plt.subplot(5, 6, i)\n", + " plt.plot(df_cc['v'+str(i)])\n", + "\n", + "plt.plot(df_cc['amount'])\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "apVkeoCl3AST", + "outputId": "77d75c8d-65f1-4d80-b6f1-eabfa01f8364", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 315 + } + }, + "source": [ + "df_cc.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
timev1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18v19v20v21v22v23v24v25v26v27v28amountclass
count12842.00000012842.00000012842.00000012842.00000012842.00000012842.00000012842.00000012842.00000012842.00000012842.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.00000012841.000000
mean8949.099984-0.2167830.2756750.8759390.280864-0.1114090.134556-0.147548-0.0312290.966379-0.3202920.842062-1.4944390.9659040.815934-0.177547-0.0364910.393921-0.012121-0.0727880.021230-0.062996-0.147793-0.0354060.0152290.1136440.0438920.0113750.00074462.2193860.004361
std6914.5883711.6533241.3387321.4534341.4955321.2321531.3073001.2020731.2436101.2176701.2098061.1898771.5449521.1713031.3317520.9810750.9495261.1585010.8330460.8237370.5719570.8944940.6212580.4960130.5892870.4266050.5639380.4016080.257426175.7801150.065897
min0.000000-27.670569-34.607649-24.667741-4.657545-32.092129-23.496714-26.548144-23.632502-7.175097-14.166795-2.595325-17.769143-3.389510-19.214325-4.152532-12.227189-18.587366-8.061208-4.932733-13.276034-11.468435-8.593642-19.254328-2.512377-4.781606-1.338556-7.976100-3.5753120.0000000.000000
25%2789.250000-0.966739-0.2802160.420540-0.631430-0.713310-0.618201-0.612138-0.1805100.252389-0.7737210.041619-2.4428600.1488750.218535-0.759873-0.525637-0.078526-0.447914-0.554832-0.159392-0.265563-0.534956-0.171847-0.334567-0.134560-0.372507-0.077529-0.0150025.4900000.000000
50%7605.500000-0.3194390.2458070.9620570.205730-0.195153-0.146859-0.1090230.0177350.944073-0.3737920.782630-1.8176301.0530441.090067-0.0417980.0341570.3923840.044854-0.069879-0.035732-0.129139-0.115690-0.0443290.0671070.153360-0.022228-0.0007870.01590715.3000000.000000
75%14441.7500001.1629830.8756731.6109081.1695840.3371920.5080400.4202980.2653111.6434430.1338311.648365-0.2487281.8364281.5446810.5044640.5342630.8733570.4855500.4488750.1407790.0205850.2340240.0711170.3979180.3886840.3913140.1015750.07150050.0000000.000000
max22549.0000001.96049710.5586004.10171611.92751234.09930921.39306934.3031778.67568510.39288912.25994912.0189133.7748374.4654137.6922093.6350424.8162529.2535264.2956484.5553598.01257422.6148894.53445413.8762213.2002015.5250933.5173468.2543764.8607697712.4300001.000000
\n", + "
" + ], + "text/plain": [ + " time v1 ... amount class\n", + "count 12842.000000 12842.000000 ... 12841.000000 12841.000000\n", + "mean 8949.099984 -0.216783 ... 62.219386 0.004361\n", + "std 6914.588371 1.653324 ... 175.780115 0.065897\n", + "min 0.000000 -27.670569 ... 0.000000 0.000000\n", + "25% 2789.250000 -0.966739 ... 5.490000 0.000000\n", + "50% 7605.500000 -0.319439 ... 15.300000 0.000000\n", + "75% 14441.750000 1.162983 ... 50.000000 0.000000\n", + "max 22549.000000 1.960497 ... 7712.430000 1.000000\n", + "\n", + "[8 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 81 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VuDjYxY359EL" + }, + "source": [ + "limite_superior_outlier = Q3+1.5*IQR" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X9k16WLI49JI", + "outputId": "b2e13475-0c22-40e6-95bf-6e099efc8585", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_cc2 = df_cc.copy()\n", + "df_cc2 = df_cc.dropna()\n", + "df_cc2.shape" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12841, 31)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OY-DYRKg34ZX" + }, + "source": [ + "### Definir as variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KVhHgV_s3_5f" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": 21, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbqrF4Q2nBq" + }, + "source": [ + "### Define amostras de treinamento e teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N8CUAiA57OhS", + "outputId": "d769cf9c-544a-4f1d-b3e0-49c1380e1a36", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_cc2.head()" + ], + "execution_count": 22, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
timev1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18v19v20v21v22v23v24v25v26v27v28amountclass
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.620.0
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.690.0
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.660.0
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.500.0
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.990.0
\n", + "
" + ], + "text/plain": [ + " time v1 v2 v3 ... v27 v28 amount class\n", + "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n", + "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n", + "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HPwapSnV6Rmu", + "outputId": "de83aafd-59a1-4e92-d731-1951288f51c4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 85 + } + }, + "source": [ + "l_preditoras = df_cc2.iloc[:, 1:30].columns\n", + "l_preditoras2 = list(df_cc2.columns)\n", + "l_preditoras" + ], + "execution_count": 23, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11',\n", + " 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18', 'v19', 'v20', 'v21',\n", + " 'v22', 'v23', 'v24', 'v25', 'v26', 'v27', 'v28', 'amount'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FqSWGYIv6i0-", + "outputId": "7d87d6f3-8b76-4455-d087-91629ca54bbb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "l_preditoras2.remove('class')\n", + "l_preditoras2" + ], + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['time',\n", + " 'v1',\n", + " 'v2',\n", + " 'v3',\n", + " 'v4',\n", + " 'v5',\n", + " 'v6',\n", + " 'v7',\n", + " 'v8',\n", + " 'v9',\n", + " 'v10',\n", + " 'v11',\n", + " 'v12',\n", + " 'v13',\n", + " 'v14',\n", + " 'v15',\n", + " 'v16',\n", + " 'v17',\n", + " 'v18',\n", + " 'v19',\n", + " 'v20',\n", + " 'v21',\n", + " 'v22',\n", + " 'v23',\n", + " 'v24',\n", + " 'v25',\n", + " 'v26',\n", + " 'v27',\n", + " 'v28',\n", + " 'amount']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NC4z51Rt6q9y", + "outputId": "51dc5065-7475-4b87-beda-103fdc186253", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_X = df_cc2[l_preditoras2]\n", + "df_X.head()" + ], + "execution_count": 25, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
timev1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18v19v20v21v22v23v24v25v26v27v28amount
00-1.359807-0.0727812.5363471.378155-0.3383210.4623880.2395990.0986980.3637870.090794-0.551600-0.617801-0.991390-0.3111691.468177-0.4704010.2079710.0257910.4039930.251412-0.0183070.277838-0.1104740.0669280.128539-0.1891150.133558-0.021053149.62
101.1918570.2661510.1664800.4481540.060018-0.082361-0.0788030.085102-0.255425-0.1669741.6127271.0652350.489095-0.1437720.6355580.463917-0.114805-0.183361-0.145783-0.069083-0.225775-0.6386720.101288-0.3398460.1671700.125895-0.0089830.0147242.69
21-1.358354-1.3401631.7732090.379780-0.5031981.8004990.7914610.247676-1.5146540.2076430.6245010.0660840.717293-0.1659462.345865-2.8900831.109969-0.121359-2.2618570.5249800.2479980.7716790.909412-0.689281-0.327642-0.139097-0.055353-0.059752378.66
31-0.966272-0.1852261.792993-0.863291-0.0103091.2472030.2376090.377436-1.387024-0.054952-0.2264870.1782280.507757-0.287924-0.631418-1.059647-0.6840931.965775-1.232622-0.208038-0.1083000.005274-0.190321-1.1755750.647376-0.2219290.0627230.061458123.50
42-1.1582330.8777371.5487180.403034-0.4071930.0959210.592941-0.2705330.8177390.753074-0.8228430.5381961.345852-1.1196700.175121-0.451449-0.237033-0.0381950.8034870.408542-0.0094310.798278-0.1374580.141267-0.2060100.5022920.2194220.21515369.99
\n", + "
" + ], + "text/plain": [ + " time v1 v2 v3 ... v26 v27 v28 amount\n", + "0 0 -1.359807 -0.072781 2.536347 ... -0.189115 0.133558 -0.021053 149.62\n", + "1 0 1.191857 0.266151 0.166480 ... 0.125895 -0.008983 0.014724 2.69\n", + "2 1 -1.358354 -1.340163 1.773209 ... -0.139097 -0.055353 -0.059752 378.66\n", + "3 1 -0.966272 -0.185226 1.792993 ... -0.221929 0.062723 0.061458 123.50\n", + "4 2 -1.158233 0.877737 1.548718 ... 0.502292 0.219422 0.215153 69.99\n", + "\n", + "[5 rows x 30 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LZjNUDNb7s1t" + }, + "source": [ + "# Definição do dataframe contendo as variáveis preditoras:\n", + "#df_X = df_cc2.copy()\n", + "#df_X.drop(columns= ['Class'], axis = 1, inplace = True)\n", + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "d3DDsN2V7IOU", + "outputId": "3e36b91a-9f84-43bb-a99f-6c8e749ed4eb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "df_y = df_cc2['class'] # Variável-resposta\n", + "df_y.head()" + ], + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 0.0\n", + "1 0.0\n", + "2 0.0\n", + "3 0.0\n", + "4 0.0\n", + "Name: class, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aMthdXHD8vnh", + "outputId": "d753dc23-6041-499d-85b8-01cb7d535e90", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_y.shape" + ], + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(12841,)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EiJRftpZ2103" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": 28, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TmSkPzNt8O6I", + "outputId": "2bf1a100-92cb-47b7-b2b2-aa306a20325e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": 29, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(8988, 30)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9h1PjPKh8Xb1", + "outputId": "b1fde667-7b52-4549-d259-0952d4dfd1b2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": 30, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(3853, 30)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NbCN_puI2qk1" + }, + "source": [ + "### Ajustar o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hjRwSI079ADn" + }, + "source": [ + "# Importar o classificador (modelo, algoritmo, ...)\n", + "from sklearn.tree import DecisionTreeClassifier # Este é o nosso classificador" + ], + "execution_count": 31, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HuhKJOQA22bR", + "outputId": "6cd87596-b4a9-4bba-9ce2-43ce6270db2c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "ml_DT = DecisionTreeClassifier(max_depth = 5, min_samples_split = 2, random_state = i_Seed)\n", + "ml_DT" + ], + "execution_count": 32, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=5, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 32 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zai1d6eM93VQ", + "outputId": "dc156d73-6d66-4a70-c4ce-5cdb037c2848", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Treinar o algoritmo/classificador: fit(df)\n", + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=5, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3OOuaVQB-AkN" + }, + "source": [ + "Y = mu + alpha1*X1 + alpha2*X2 + Erro" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ybbS4zHn-8BO", + "outputId": "460d1262-1068-4d55-f09e-821fd69a2f6b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": 34, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 99.9\n", + "std médio das Acurácias calculadas pelo CV: 0.09\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r_NLku7q_YT9", + "outputId": "46653af5-a2a2-4429-fb2a-fc02a3e01b3e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": 35, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1. , 0.99888765, 0.99777531, 0.99777531, 1. ,\n", + " 0.99888765, 1. , 0.99888765, 0.99777283, 1. ])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgX7eBNY78sa", + "outputId": "00f74266-5757-4e4f-f152-5476aae2d20f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": 36, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9994809239553595" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kDNrT7VM8IaT" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uct1z_sS8OGt", + "outputId": "b6868fd4-32f7-480f-cbf5-3d9fd7ada5e6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)\n", + "y_pred[:30]" + ], + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FmG8KiqS8tnn", + "outputId": "65d11296-2e98-4072-8f6d-986dfe010797", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 544 + } + }, + "source": [ + "y_teste[0:30]" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1224 0.0\n", + "11994 0.0\n", + "5408 0.0\n", + "4385 0.0\n", + "8164 0.0\n", + "10540 0.0\n", + "10246 0.0\n", + "10110 0.0\n", + "3787 0.0\n", + "7263 0.0\n", + "4124 0.0\n", + "12319 0.0\n", + "12573 0.0\n", + "2934 0.0\n", + "1074 0.0\n", + "8300 0.0\n", + "11444 0.0\n", + "9251 0.0\n", + "1691 0.0\n", + "10482 0.0\n", + "10295 0.0\n", + "7868 0.0\n", + "823 0.0\n", + "6021 0.0\n", + "9713 0.0\n", + "2005 0.0\n", + "10049 0.0\n", + "10364 0.0\n", + "3300 0.0\n", + "2071 0.0\n", + "Name: class, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2wMWm-p5229A", + "outputId": "16b7a184-540f-4eb1-a08c-f5048e59ccf8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": 40, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Am_UELOg2vDh" + }, + "source": [ + "### Fine tuning dos parâmetros" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lF9mxe7y23hr", + "outputId": "c8f9f8a8-8d06-4b06-87c0-272981248da4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# Hiperparâmetros para GridSearch()\n", + "d_parametros = {'criterion': ['gini', 'entropy'],\n", + " 'min_samples_split': [2, 5, 7, 9, 11, 50],\n", + " 'max_depth': [2, 9, 15],\n", + " 'min_samples_leaf': [5, 10, 15, 50, 100],\n", + " 'max_leaf_nodes': [2, 7, 11]}\n", + "\n", + "d_parametros" + ], + "execution_count": 41, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': ['gini', 'entropy'],\n", + " 'max_depth': [2, 9, 15],\n", + " 'max_leaf_nodes': [2, 7, 11],\n", + " 'min_samples_leaf': [5, 10, 15, 50, 100],\n", + " 'min_samples_split': [2, 5, 7, 9, 11, 50]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F8TGaDQvA5jJ" + }, + "source": [ + "### GridSearchOptimizer()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UvRWYAk7A-Gp", + "outputId": "21c0ea2f-f148-4bd2-84a0-d7625ec50ca7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "l_colunas = list(df_X.columns)\n", + "ml_DT2, melhor_hiperparam = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": 42, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 540 candidates, totalling 5400 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.4s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.9s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 2.2s\n", + "[Parallel(n_jobs=-1)]: Done 21 tasks | elapsed: 2.6s\n", + "[Parallel(n_jobs=-1)]: Done 28 tasks | elapsed: 3.0s\n", + "[Parallel(n_jobs=-1)]: Done 37 tasks | elapsed: 3.5s\n", + "[Parallel(n_jobs=-1)]: Done 46 tasks | elapsed: 4.0s\n", + "[Parallel(n_jobs=-1)]: Done 57 tasks | elapsed: 4.6s\n", + "[Parallel(n_jobs=-1)]: Done 68 tasks | elapsed: 5.2s\n", + "[Parallel(n_jobs=-1)]: Done 81 tasks | elapsed: 6.0s\n", + "[Parallel(n_jobs=-1)]: Done 94 tasks | elapsed: 6.7s\n", + "[Parallel(n_jobs=-1)]: Done 109 tasks | elapsed: 7.6s\n", + "[Parallel(n_jobs=-1)]: Done 124 tasks | elapsed: 8.4s\n", + "[Parallel(n_jobs=-1)]: Done 141 tasks | elapsed: 9.4s\n", + "[Parallel(n_jobs=-1)]: Done 158 tasks | elapsed: 10.4s\n", + "[Parallel(n_jobs=-1)]: Done 177 tasks | elapsed: 11.5s\n", + "[Parallel(n_jobs=-1)]: Done 196 tasks | elapsed: 12.5s\n", + "[Parallel(n_jobs=-1)]: Done 217 tasks | elapsed: 13.7s\n", + "[Parallel(n_jobs=-1)]: Done 238 tasks | elapsed: 14.8s\n", + "[Parallel(n_jobs=-1)]: Done 261 tasks | elapsed: 16.2s\n", + "[Parallel(n_jobs=-1)]: Done 284 tasks | elapsed: 17.4s\n", + "[Parallel(n_jobs=-1)]: Done 309 tasks | elapsed: 18.9s\n", + "[Parallel(n_jobs=-1)]: Done 334 tasks | elapsed: 20.3s\n", + "[Parallel(n_jobs=-1)]: Done 361 tasks | elapsed: 21.9s\n", + "[Parallel(n_jobs=-1)]: Done 388 tasks | elapsed: 23.4s\n", + "[Parallel(n_jobs=-1)]: Done 417 tasks | elapsed: 25.0s\n", + "[Parallel(n_jobs=-1)]: Done 446 tasks | elapsed: 26.6s\n", + "[Parallel(n_jobs=-1)]: Done 477 tasks | elapsed: 28.4s\n", + "[Parallel(n_jobs=-1)]: Done 508 tasks | elapsed: 30.1s\n", + "[Parallel(n_jobs=-1)]: Done 541 tasks | elapsed: 32.0s\n", + "[Parallel(n_jobs=-1)]: Done 574 tasks | elapsed: 33.8s\n", + "[Parallel(n_jobs=-1)]: Done 609 tasks | elapsed: 35.8s\n", + "[Parallel(n_jobs=-1)]: Done 644 tasks | elapsed: 37.7s\n", + "[Parallel(n_jobs=-1)]: Done 681 tasks | elapsed: 39.9s\n", + "[Parallel(n_jobs=-1)]: Done 718 tasks | elapsed: 41.9s\n", + "[Parallel(n_jobs=-1)]: Done 757 tasks | elapsed: 44.1s\n", + "[Parallel(n_jobs=-1)]: Done 796 tasks | elapsed: 46.3s\n", + "[Parallel(n_jobs=-1)]: Done 837 tasks | elapsed: 48.6s\n", + "[Parallel(n_jobs=-1)]: Done 878 tasks | elapsed: 50.9s\n", + "[Parallel(n_jobs=-1)]: Done 921 tasks | elapsed: 53.3s\n", + "[Parallel(n_jobs=-1)]: Done 964 tasks | elapsed: 55.7s\n", + "[Parallel(n_jobs=-1)]: Done 1009 tasks | elapsed: 58.3s\n", + "[Parallel(n_jobs=-1)]: Done 1054 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 1101 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 1148 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 1197 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 1246 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 1297 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 1348 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 1401 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 1454 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 1509 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 1564 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 1621 tasks | elapsed: 1.9min\n", + "[Parallel(n_jobs=-1)]: Done 1678 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 1737 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 1796 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 1857 tasks | elapsed: 2.3min\n", + "[Parallel(n_jobs=-1)]: Done 1918 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 1981 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 2044 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 2109 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 2174 tasks | elapsed: 2.7min\n", + "[Parallel(n_jobs=-1)]: Done 2241 tasks | elapsed: 2.9min\n", + "[Parallel(n_jobs=-1)]: Done 2308 tasks | elapsed: 3.0min\n", + "[Parallel(n_jobs=-1)]: Done 2377 tasks | elapsed: 3.1min\n", + "[Parallel(n_jobs=-1)]: Done 2446 tasks | elapsed: 3.2min\n", + "[Parallel(n_jobs=-1)]: Done 2517 tasks | elapsed: 3.4min\n", + "[Parallel(n_jobs=-1)]: Done 2588 tasks | elapsed: 3.5min\n", + "[Parallel(n_jobs=-1)]: Done 2661 tasks | elapsed: 3.6min\n", + "[Parallel(n_jobs=-1)]: Done 2734 tasks | elapsed: 3.7min\n", + "[Parallel(n_jobs=-1)]: Done 2809 tasks | elapsed: 3.9min\n", + "[Parallel(n_jobs=-1)]: Done 2884 tasks | elapsed: 4.0min\n", + "[Parallel(n_jobs=-1)]: Done 2961 tasks | elapsed: 4.1min\n", + "[Parallel(n_jobs=-1)]: Done 3038 tasks | elapsed: 4.2min\n", + "[Parallel(n_jobs=-1)]: Done 3117 tasks | elapsed: 4.3min\n", + "[Parallel(n_jobs=-1)]: Done 3196 tasks | elapsed: 4.4min\n", + "[Parallel(n_jobs=-1)]: Done 3277 tasks | elapsed: 4.5min\n", + "[Parallel(n_jobs=-1)]: Done 3358 tasks | elapsed: 4.6min\n", + "[Parallel(n_jobs=-1)]: Done 3441 tasks | elapsed: 4.7min\n", + "[Parallel(n_jobs=-1)]: Done 3524 tasks | elapsed: 4.9min\n", + "[Parallel(n_jobs=-1)]: Done 3609 tasks | elapsed: 5.0min\n", + "[Parallel(n_jobs=-1)]: Done 3694 tasks | elapsed: 5.1min\n", + "[Parallel(n_jobs=-1)]: Done 3781 tasks | elapsed: 5.2min\n", + "[Parallel(n_jobs=-1)]: Done 3868 tasks | elapsed: 5.3min\n", + "[Parallel(n_jobs=-1)]: Done 3957 tasks | elapsed: 5.5min\n", + "[Parallel(n_jobs=-1)]: Done 4046 tasks | elapsed: 5.6min\n", + "[Parallel(n_jobs=-1)]: Done 4137 tasks | elapsed: 5.7min\n", + "[Parallel(n_jobs=-1)]: Done 4228 tasks | elapsed: 5.9min\n", + "[Parallel(n_jobs=-1)]: Done 4321 tasks | elapsed: 6.0min\n", + "[Parallel(n_jobs=-1)]: Done 4414 tasks | elapsed: 6.2min\n", + "[Parallel(n_jobs=-1)]: Done 4509 tasks | elapsed: 6.3min\n", + "[Parallel(n_jobs=-1)]: Done 4604 tasks | elapsed: 6.4min\n", + "[Parallel(n_jobs=-1)]: Done 4701 tasks | elapsed: 6.6min\n", + "[Parallel(n_jobs=-1)]: Done 4798 tasks | elapsed: 6.7min\n", + "[Parallel(n_jobs=-1)]: Done 4897 tasks | elapsed: 6.8min\n", + "[Parallel(n_jobs=-1)]: Done 4996 tasks | elapsed: 7.0min\n", + "[Parallel(n_jobs=-1)]: Done 5097 tasks | elapsed: 7.1min\n", + "[Parallel(n_jobs=-1)]: Done 5198 tasks | elapsed: 7.3min\n", + "[Parallel(n_jobs=-1)]: Done 5301 tasks | elapsed: 7.5min\n", + "[Parallel(n_jobs=-1)]: Done 5400 out of 5400 | elapsed: 7.6min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'gini', 'max_depth': 2, 'max_leaf_nodes': 2, 'min_samples_leaf': 5, 'min_samples_split': 2}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 99.87\n", + "std médio das Acurácias calculadas pelo CV: 0.12\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "12 v12 1.0\n", + "0 time 0.0\n", + "16 v16 0.0\n", + "28 v28 0.0\n", + "27 v27 0.0\n", + "26 v26 0.0\n", + "25 v25 0.0\n", + "24 v24 0.0\n", + "23 v23 0.0\n", + "22 v22 0.0\n", + "21 v21 0.0\n", + "20 v20 0.0\n", + "19 v19 0.0\n", + "18 v18 0.0\n", + "17 v17 0.0\n", + "15 v15 0.0\n", + "1 v1 0.0\n", + "14 v14 0.0\n", + "13 v13 0.0\n", + "11 v11 0.0\n", + "10 v10 0.0\n", + "9 v9 0.0\n", + "8 v8 0.0\n", + "7 v7 0.0\n", + "6 v6 0.0\n", + "5 v5 0.0\n", + "4 v4 0.0\n", + "3 v3 0.0\n", + "2 v2 0.0\n", + "29 amount 0.0\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fdaQoeuiEgaE", + "outputId": "f60b420d-c7e6-4cf3-b896-d01eb960a66e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "120*5" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "600" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 119 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "STnFiVlCCet9" + }, + "source": [ + "### Visualizar os resultados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ufrYXAd5_8uN", + "outputId": "18d7793f-d8ac-4ac3-c1f5-de83f1a6e30c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 277 + } + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bG31I7_n4RQg" + }, + "source": [ + "### Aplicar as transformações (principais) estudadas e reestimar o modelo novamente\n", + "* Qual o impacto das transformações?\n", + "* A conclusão muda/mudou?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning_hs5.ipynb b/Notebooks/NB15_00__Machine_Learning_hs5.ipynb new file mode 100644 index 000000000..186bb35ec --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning_hs5.ipynb @@ -0,0 +1,6271 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e-VOopTKxrMs" + }, + "source": [ + "A seguir, sugestão de problemas para resolver com Regressão Linear\n", + "* https://lionbridge.ai/datasets/10-open-datasets-for-linear-regression/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTAGmmHouqQd", + "outputId": "61bb183a-d989-4d92-867d-bb6265a98717", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "!pip install azureml\n", + "!pip install azureml-opendatasets\n", + "!pip install azureml-dataset-runtime" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: azureml in /usr/local/lib/python3.6/dist-packages (0.2.7)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from azureml) (2.23.0)\n", + "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.6/dist-packages (from azureml) (2.8.1)\n", + "Requirement already satisfied: pandas in /usr/local/lib/python3.6/dist-packages (from azureml) (1.1.2)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests->azureml) (2020.6.20)\n", + "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->azureml) (3.0.4)\n", + "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests->azureml) (1.24.3)\n", + "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->azureml) (2.10)\n", + "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.6/dist-packages (from python-dateutil->azureml) (1.15.0)\n", + "Requirement already satisfied: numpy>=1.15.4 in /usr/local/lib/python3.6/dist-packages (from pandas->azureml) (1.18.5)\n", + "Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas->azureml) (2018.9)\n", + "Collecting azureml-opendatasets\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/50/80/9cdbe1f2574e03ca9292a4db5de98b958f817d79fc50b556c09e98378b98/azureml_opendatasets-1.16.0-py3-none-any.whl (1.3MB)\n", + "\u001b[K |████████████████████████████████| 1.3MB 3.2MB/s \n", + "\u001b[?25hCollecting pandas<=1.0.0,>=0.21.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/12/d1/a6502c2f5c15b50f5dd579fc1c52b47edf6f2e9f682aed917dd7565b3e60/pandas-1.0.0-cp36-cp36m-manylinux1_x86_64.whl (10.1MB)\n", + "\u001b[K |████████████████████████████████| 10.1MB 806kB/s \n", + "\u001b[?25hCollecting azureml-dataset-runtime[fuse,pandas]~=1.16.0\n", + " Downloading https://files.pythonhosted.org/packages/31/b8/88abfd9d5fe86ed3eeed4dc7736eca9ad264026b6744e42ca25b557a78d4/azureml_dataset_runtime-1.16.0-py3-none-any.whl\n", + "Requirement already satisfied: numpy<=1.19.0,>=1.16.0 in /usr/local/lib/python3.6/dist-packages (from azureml-opendatasets) (1.18.5)\n", + "Collecting pyarrow>=0.16.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/d7/e1/27958a70848f8f7089bff8d6ebe42519daf01f976d28b481e1bfd52c8097/pyarrow-2.0.0-cp36-cp36m-manylinux2014_x86_64.whl (17.7MB)\n", + "\u001b[K |████████████████████████████████| 17.7MB 228kB/s \n", + "\u001b[?25hCollecting azureml-core~=1.16.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/3b/5b/c7f67ec1ac8066eba75a4cbaa9631bb8713585e56f6487fdda9dd55db8a9/azureml_core-1.16.0.post1-py3-none-any.whl (2.0MB)\n", + "\u001b[K |████████████████████████████████| 2.0MB 42.0MB/s \n", + "\u001b[?25hCollecting azureml-telemetry~=1.16.0\n", + " Downloading https://files.pythonhosted.org/packages/a5/04/130242589a85a55e16aebf0c38f5b735d7fa1cd385e3ac741f69fca8295c/azureml_telemetry-1.16.0-py3-none-any.whl\n", + "Requirement already satisfied: scipy<=1.4.1,>=1.0.0 in /usr/local/lib/python3.6/dist-packages (from azureml-opendatasets) (1.4.1)\n", + "Collecting pyspark\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/f0/26/198fc8c0b98580f617cb03cb298c6056587b8f0447e20fa40c5b634ced77/pyspark-3.0.1.tar.gz (204.2MB)\n", + "\u001b[K |████████████████████████████████| 204.2MB 60kB/s \n", + "\u001b[?25hRequirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas<=1.0.0,>=0.21.0->azureml-opendatasets) (2018.9)\n", + "Requirement already satisfied: python-dateutil>=2.6.1 in /usr/local/lib/python3.6/dist-packages (from pandas<=1.0.0,>=0.21.0->azureml-opendatasets) (2.8.1)\n", + "Collecting azureml-dataprep<2.4.0a,>=2.3.0a\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/27/86/648d3ec3feddf41187a4ed25551293d0480239a920fef00fb979034dc3e1/azureml_dataprep-2.3.4-py3-none-any.whl (28.2MB)\n", + "\u001b[K |████████████████████████████████| 28.2MB 151kB/s \n", + "\u001b[?25hCollecting fusepy<4.0.0,>=3.0.1; extra == \"fuse\"\n", + " Downloading https://files.pythonhosted.org/packages/04/0b/4506cb2e831cea4b0214d3625430e921faaa05a7fb520458c75a2dbd2152/fusepy-3.0.1.tar.gz\n", + "Collecting azure-mgmt-authorization<1.0.0,>=0.40.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/b4/50/7a923f58bf053280fe1890f3332c08f6a82a208c92035ad8f7888c87b786/azure_mgmt_authorization-0.61.0-py2.py3-none-any.whl (94kB)\n", + "\u001b[K |████████████████████████████████| 102kB 7.8MB/s \n", + "\u001b[?25hRequirement already satisfied: urllib3>=1.23 in /usr/local/lib/python3.6/dist-packages (from azureml-core~=1.16.0->azureml-opendatasets) (1.24.3)\n", + "Requirement already satisfied: requests>=2.19.1 in /usr/local/lib/python3.6/dist-packages (from azureml-core~=1.16.0->azureml-opendatasets) (2.23.0)\n", + "Collecting PyJWT\n", + " Downloading https://files.pythonhosted.org/packages/87/8b/6a9f14b5f781697e51259d81657e6048fd31a113229cf346880bb7545565/PyJWT-1.7.1-py2.py3-none-any.whl\n", + "Collecting ruamel.yaml>=0.15.35\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/7e/39/186f14f3836ac5d2a6a042c8de69988770e8b9abb537610edc429e4914aa/ruamel.yaml-0.16.12-py2.py3-none-any.whl (111kB)\n", + "\u001b[K |████████████████████████████████| 112kB 34.4MB/s \n", + "\u001b[?25hCollecting jmespath\n", + " Downloading https://files.pythonhosted.org/packages/07/cb/5f001272b6faeb23c1c9e0acc04d48eaaf5c862c17709d20e3469c6e0139/jmespath-0.10.0-py2.py3-none-any.whl\n", + "Collecting azure-mgmt-storage<16.0.0,>=1.5.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/33/cc/8ace313fd151af6663b1e1778f216532eab0258133ef21498c0e2caefad6/azure_mgmt_storage-11.2.0-py2.py3-none-any.whl (547kB)\n", + "\u001b[K |████████████████████████████████| 552kB 25.2MB/s \n", + "\u001b[?25hCollecting ndg-httpsclient\n", + " Downloading https://files.pythonhosted.org/packages/fb/67/c2f508c00ed2a6911541494504b7cac16fe0b0473912568df65fd1801132/ndg_httpsclient-0.5.1-py3-none-any.whl\n", + "Collecting backports.tempfile\n", + " Downloading https://files.pythonhosted.org/packages/b4/5c/077f910632476281428fe254807952eb47ca78e720d059a46178c541e669/backports.tempfile-1.0-py2.py3-none-any.whl\n", + "Collecting msrest>=0.5.1\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/fa/f5/9e315fe8cb985b0ce052b34bcb767883dc739f46fadb62f05a7e6d6eedbe/msrest-0.6.19-py2.py3-none-any.whl (84kB)\n", + "\u001b[K |████████████████████████████████| 92kB 6.6MB/s \n", + "\u001b[?25hCollecting pathspec\n", + " Downloading https://files.pythonhosted.org/packages/5d/d0/887c58853bd4b6ffc7aa9cdba4fc57d7b979b45888a6bd47e4568e1cf868/pathspec-0.8.0-py2.py3-none-any.whl\n", + "Collecting azure-common>=1.1.12\n", + " Downloading https://files.pythonhosted.org/packages/e5/4d/d000fc3c5af601d00d55750b71da5c231fcb128f42ac95b208ed1091c2c1/azure_common-1.1.25-py2.py3-none-any.whl\n", + "Collecting docker\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/9e/8c/8d42dbd83679483db207535f4fb02dc84325fa78b290f057694b057fcd21/docker-4.3.1-py2.py3-none-any.whl (145kB)\n", + "\u001b[K |████████████████████████████████| 153kB 41.0MB/s \n", + "\u001b[?25hRequirement already satisfied: contextlib2 in /usr/local/lib/python3.6/dist-packages (from azureml-core~=1.16.0->azureml-opendatasets) (0.5.5)\n", + "Collecting adal>=1.2.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/e9/51/5081e3705fdc4bf56fe26990b959b3379c9db38c6a0a0cd6b66508d161db/adal-1.2.5-py2.py3-none-any.whl (55kB)\n", + "\u001b[K |████████████████████████████████| 61kB 4.7MB/s \n", + "\u001b[?25hCollecting azure-graphrbac<1.0.0,>=0.40.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/3e/93/02056aca45162f9fc275d1eaad12a2a07ef92375afb48eabddc4134b8315/azure_graphrbac-0.61.1-py2.py3-none-any.whl (141kB)\n", + "\u001b[K |████████████████████████████████| 143kB 37.9MB/s \n", + "\u001b[?25hCollecting azure-mgmt-containerregistry>=2.0.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/97/70/8c2d0509db466678eba16fa2b0a539499f3b351b1f2993126ad843d5be13/azure_mgmt_containerregistry-2.8.0-py2.py3-none-any.whl (718kB)\n", + "\u001b[K |████████████████████████████████| 727kB 35.2MB/s \n", + "\u001b[?25hCollecting SecretStorage\n", + " Downloading https://files.pythonhosted.org/packages/c3/50/8a02cad020e949e6d7105f5f4530d41e3febcaa5b73f8f2148aacb3aeba5/SecretStorage-3.1.2-py3-none-any.whl\n", + "Collecting azure-mgmt-keyvault<7.0.0,>=0.40.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/f1/af/1ba15e7176bcf6b1531b453e410ae41a983c09f834d8700dfce739451b53/azure_mgmt_keyvault-2.2.0-py2.py3-none-any.whl (89kB)\n", + "\u001b[K |████████████████████████████████| 92kB 6.9MB/s \n", + "\u001b[?25hCollecting msrestazure>=0.4.33\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/5e/3a/7adb08fd2f0ee6fdfd03685fac38477b64f184943dcf6ea0cbffb205f22d/msrestazure-0.6.4-py2.py3-none-any.whl (40kB)\n", + "\u001b[K |████████████████████████████████| 40kB 4.0MB/s \n", + "\u001b[?25hCollecting cryptography!=1.9,!=2.0.*,!=2.1.*,!=2.2.*\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/33/62/30f6936941d87a5ed72efb24249437824f6b2c953901245b58c91fde2f27/cryptography-3.1.1-cp35-abi3-manylinux2010_x86_64.whl (2.6MB)\n", + "\u001b[K |████████████████████████████████| 2.6MB 33.9MB/s \n", + "\u001b[?25hCollecting jsonpickle\n", + " Downloading https://files.pythonhosted.org/packages/af/ca/4fee219cc4113a5635e348ad951cf8a2e47fed2e3342312493f5b73d0007/jsonpickle-1.4.1-py2.py3-none-any.whl\n", + "Collecting pyopenssl<20.0.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/9e/de/f8342b68fa9e981d348039954657bdf681b2ab93de27443be51865ffa310/pyOpenSSL-19.1.0-py2.py3-none-any.whl (53kB)\n", + "\u001b[K |████████████████████████████████| 61kB 7.6MB/s \n", + "\u001b[?25hCollecting azure-mgmt-resource<15.0.0,>=1.2.1\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/af/b3/8009c149d7d162b7a2a22a5007f984aa090f089bf8dc09e7e84bd354b868/azure_mgmt_resource-10.2.0-py2.py3-none-any.whl (968kB)\n", + "\u001b[K |████████████████████████████████| 972kB 40.6MB/s \n", + "\u001b[?25hCollecting applicationinsights\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/a1/53/234c53004f71f0717d8acd37876e0b65c121181167057b9ce1b1795f96a0/applicationinsights-0.11.9-py2.py3-none-any.whl (58kB)\n", + "\u001b[K |████████████████████████████████| 61kB 6.9MB/s \n", + "\u001b[?25hCollecting py4j==0.10.9\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/9e/b6/6a4fb90cd235dc8e265a6a2067f2a2c99f0d91787f06aca4bcf7c23f3f80/py4j-0.10.9-py2.py3-none-any.whl (198kB)\n", + "\u001b[K |████████████████████████████████| 204kB 31.5MB/s \n", + "\u001b[?25hRequirement already satisfied: six>=1.5 in /usr/local/lib/python3.6/dist-packages (from python-dateutil>=2.6.1->pandas<=1.0.0,>=0.21.0->azureml-opendatasets) (1.15.0)\n", + "Collecting azure-identity<2.0.0,>=1.2.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/93/97/0e57f9d0bb0e9aee5cce0007616f6d3c2e09931fd24ad140c9cc3b06b7ef/azure_identity-1.4.1-py2.py3-none-any.whl (86kB)\n", + "\u001b[K |████████████████████████████████| 92kB 9.9MB/s \n", + "\u001b[?25hCollecting azureml-dataprep-native<24.0.0,>=23.0.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/50/a8/7c85148c3cc1bbcba9476fee04079899ba8dd0b6b49fed4a685926e3bcdc/azureml_dataprep_native-23.0.0-cp36-cp36m-manylinux1_x86_64.whl (1.3MB)\n", + "\u001b[K |████████████████████████████████| 1.3MB 38.8MB/s \n", + "\u001b[?25hCollecting dotnetcore2<3.0.0,>=2.1.14\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/57/a3/43ee595226ae611c2077da17f6ae0df5694aac04429733fb40608c54f83c/dotnetcore2-2.1.17-py3-none-manylinux1_x86_64.whl (28.7MB)\n", + "\u001b[K |████████████████████████████████| 28.7MB 144kB/s \n", + "\u001b[?25hRequirement already satisfied: cloudpickle<2.0.0,>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from azureml-dataprep<2.4.0a,>=2.3.0a->azureml-dataset-runtime[fuse,pandas]~=1.16.0->azureml-opendatasets) (1.3.0)\n", + "Collecting azureml-dataprep-rslex<1.2.0a,>=1.1.0dev0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/7c/2c/e26558af094a5c63611bbee20d118c320db8841ac4dfe75c602804611834/azureml_dataprep_rslex-1.1.3-cp36-cp36m-manylinux2010_x86_64.whl (7.9MB)\n", + "\u001b[K |████████████████████████████████| 7.9MB 16.4MB/s \n", + "\u001b[?25hRequirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests>=2.19.1->azureml-core~=1.16.0->azureml-opendatasets) (2.10)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests>=2.19.1->azureml-core~=1.16.0->azureml-opendatasets) (2020.6.20)\n", + "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests>=2.19.1->azureml-core~=1.16.0->azureml-opendatasets) (3.0.4)\n", + "Collecting ruamel.yaml.clib>=0.1.2; platform_python_implementation == \"CPython\" and python_version < \"3.9\"\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/88/ff/ec25dc01ef04232a9e68ff18492e37dfa01f1f58172e702ad4f38536d41b/ruamel.yaml.clib-0.2.2-cp36-cp36m-manylinux1_x86_64.whl (549kB)\n", + "\u001b[K |████████████████████████████████| 552kB 44.3MB/s \n", + "\u001b[?25hRequirement already satisfied: pyasn1>=0.1.1 in /usr/local/lib/python3.6/dist-packages (from ndg-httpsclient->azureml-core~=1.16.0->azureml-opendatasets) (0.4.8)\n", + "Collecting backports.weakref\n", + " Downloading https://files.pythonhosted.org/packages/88/ec/f598b633c3d5ffe267aaada57d961c94fdfa183c5c3ebda2b6d151943db6/backports.weakref-1.0.post1-py2.py3-none-any.whl\n", + "Requirement already satisfied: requests-oauthlib>=0.5.0 in /usr/local/lib/python3.6/dist-packages (from msrest>=0.5.1->azureml-core~=1.16.0->azureml-opendatasets) (1.3.0)\n", + "Collecting isodate>=0.6.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/9b/9f/b36f7774ff5ea8e428fdcfc4bb332c39ee5b9362ddd3d40d9516a55221b2/isodate-0.6.0-py2.py3-none-any.whl (45kB)\n", + "\u001b[K |████████████████████████████████| 51kB 6.3MB/s \n", + "\u001b[?25hCollecting websocket-client>=0.32.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/4c/5f/f61b420143ed1c8dc69f9eaec5ff1ac36109d52c80de49d66e0c36c3dfdf/websocket_client-0.57.0-py2.py3-none-any.whl (200kB)\n", + "\u001b[K |████████████████████████████████| 204kB 43.8MB/s \n", + "\u001b[?25hCollecting jeepney>=0.4.2\n", + " Downloading https://files.pythonhosted.org/packages/79/31/2e8d42727595faf224c6dbb748c32b192e212f25495fe841fb7ce8e168b8/jeepney-0.4.3-py3-none-any.whl\n", + "Requirement already satisfied: cffi!=1.11.3,>=1.8 in /usr/local/lib/python3.6/dist-packages (from cryptography!=1.9,!=2.0.*,!=2.1.*,!=2.2.*->azureml-core~=1.16.0->azureml-opendatasets) (1.14.3)\n", + "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.6/dist-packages (from jsonpickle->azureml-core~=1.16.0->azureml-opendatasets) (2.0.0)\n", + "Collecting msal-extensions~=0.2.2\n", + " Downloading https://files.pythonhosted.org/packages/33/da/eed514cb6902405c5c11a03f1e65adbd95e2c26d9b22eae390eddb561201/msal_extensions-0.2.2-py2.py3-none-any.whl\n", + "Collecting azure-core<2.0.0,>=1.0.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/4c/fa/46974f4a7ad78b27e3eda8a573cc0c2508849f0d7d360b61c07cc5b46014/azure_core-1.8.2-py2.py3-none-any.whl (122kB)\n", + "\u001b[K |████████████████████████████████| 122kB 49.9MB/s \n", + "\u001b[?25hCollecting msal<2.0.0,>=1.3.0\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/47/84/72f350389f24a3127c8d4d8da0d0d73adb14f04dadca296575ca2ad20d42/msal-1.5.1-py2.py3-none-any.whl (50kB)\n", + "\u001b[K |████████████████████████████████| 51kB 6.1MB/s \n", + "\u001b[?25hCollecting distro>=1.2.0\n", + " Downloading https://files.pythonhosted.org/packages/25/b7/b3c4270a11414cb22c6352ebc7a83aaa3712043be29daa05018fd5a5c956/distro-1.5.0-py2.py3-none-any.whl\n", + "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.6/dist-packages (from requests-oauthlib>=0.5.0->msrest>=0.5.1->azureml-core~=1.16.0->azureml-opendatasets) (3.1.0)\n", + "Requirement already satisfied: pycparser in /usr/local/lib/python3.6/dist-packages (from cffi!=1.11.3,>=1.8->cryptography!=1.9,!=2.0.*,!=2.1.*,!=2.2.*->azureml-core~=1.16.0->azureml-opendatasets) (2.20)\n", + "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.6/dist-packages (from importlib-metadata->jsonpickle->azureml-core~=1.16.0->azureml-opendatasets) (3.2.0)\n", + "Collecting portalocker~=1.0; platform_system != \"Windows\"\n", + " Downloading https://files.pythonhosted.org/packages/3b/e7/ceef002a300a98a208232fab593183249b6964b306ee7dabb29908419cca/portalocker-1.7.1-py2.py3-none-any.whl\n", + "Building wheels for collected packages: pyspark, fusepy\n", + " Building wheel for pyspark (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for pyspark: filename=pyspark-3.0.1-py2.py3-none-any.whl size=204612243 sha256=4c5104794485520f1b81919c0c0ca277ae8ea760b3935ca45aeb0354de5d5c99\n", + " Stored in directory: /root/.cache/pip/wheels/5e/bd/07/031766ca628adec8435bb40f0bd83bb676ce65ff4007f8e73f\n", + " Building wheel for fusepy (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for fusepy: filename=fusepy-3.0.1-cp36-none-any.whl size=10504 sha256=6ed5e9d7be0a259083f02d32dbf37fea9cc48dc8e8aa628d37952fafa4ebf2bd\n", + " Stored in directory: /root/.cache/pip/wheels/4c/a5/91/7772af9e21c461f07bb40f26d928d7d231d224977dd8353bab\n", + "Successfully built pyspark fusepy\n", + "\u001b[31mERROR: google-colab 1.0.0 has requirement pandas~=1.1.0; python_version >= \"3.0\", but you'll have pandas 1.0.0 which is incompatible.\u001b[0m\n", + "\u001b[31mERROR: fbprophet 0.7.1 has requirement pandas>=1.0.4, but you'll have pandas 1.0.0 which is incompatible.\u001b[0m\n", + "\u001b[31mERROR: azureml-dataset-runtime 1.16.0 has requirement pyarrow<2.0.0,>=0.17.0, but you'll have pyarrow 2.0.0 which is incompatible.\u001b[0m\n", + "Installing collected packages: pandas, pyarrow, PyJWT, msal, portalocker, msal-extensions, azure-core, cryptography, azure-identity, azureml-dataprep-native, distro, dotnetcore2, azureml-dataprep-rslex, azureml-dataprep, fusepy, azureml-dataset-runtime, azure-common, isodate, msrest, adal, msrestazure, azure-mgmt-authorization, ruamel.yaml.clib, ruamel.yaml, jmespath, azure-mgmt-storage, pyopenssl, ndg-httpsclient, backports.weakref, backports.tempfile, pathspec, websocket-client, docker, azure-graphrbac, azure-mgmt-containerregistry, jeepney, SecretStorage, azure-mgmt-keyvault, jsonpickle, azure-mgmt-resource, azureml-core, applicationinsights, azureml-telemetry, py4j, pyspark, azureml-opendatasets\n", + " Found existing installation: pandas 1.1.2\n", + " Uninstalling pandas-1.1.2:\n", + " Successfully uninstalled pandas-1.1.2\n", + " Found existing installation: pyarrow 0.14.1\n", + " Uninstalling pyarrow-0.14.1:\n", + " Successfully uninstalled pyarrow-0.14.1\n", + "Successfully installed PyJWT-1.7.1 SecretStorage-3.1.2 adal-1.2.5 applicationinsights-0.11.9 azure-common-1.1.25 azure-core-1.8.2 azure-graphrbac-0.61.1 azure-identity-1.4.1 azure-mgmt-authorization-0.61.0 azure-mgmt-containerregistry-2.8.0 azure-mgmt-keyvault-2.2.0 azure-mgmt-resource-10.2.0 azure-mgmt-storage-11.2.0 azureml-core-1.16.0.post1 azureml-dataprep-2.3.4 azureml-dataprep-native-23.0.0 azureml-dataprep-rslex-1.1.3 azureml-dataset-runtime-1.16.0 azureml-opendatasets-1.16.0 azureml-telemetry-1.16.0 backports.tempfile-1.0 backports.weakref-1.0.post1 cryptography-3.1.1 distro-1.5.0 docker-4.3.1 dotnetcore2-2.1.17 fusepy-3.0.1 isodate-0.6.0 jeepney-0.4.3 jmespath-0.10.0 jsonpickle-1.4.1 msal-1.5.1 msal-extensions-0.2.2 msrest-0.6.19 msrestazure-0.6.4 ndg-httpsclient-0.5.1 pandas-1.0.0 pathspec-0.8.0 portalocker-1.7.1 py4j-0.10.9 pyarrow-2.0.0 pyopenssl-19.1.0 pyspark-3.0.1 ruamel.yaml-0.16.12 ruamel.yaml.clib-0.2.2 websocket-client-0.57.0\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "application/vnd.colab-display-data+json": { + "pip_warning": { + "packages": [ + "azureml", + "pandas" + ] + } + } + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "74DHjOrSuOwd" + }, + "source": [ + "from azureml import Datasets" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uIMB3a9EuQ9h" + }, + "source": [ + "from azureml.core import Dataset\n", + "from azureml.opendatasets import NycTlcYellow, NycTlcGreen\n", + "from dateutil import parser\n", + "from datetime import datetime\n", + "from dateutil.relativedelta import relativedelta" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oV-ETadXvsuG", + "outputId": "61ceff13-4640-4fad-ddc1-810132ee4b5a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 766 + } + }, + "source": [ + "end_date = parser.parse('2018-06-06')\n", + "start_date = parser.parse('2018-05-01')\n", + "nyc_tlc = NycTlcYellow(start_date=start_date, end_date=end_date)\n", + "nyc_tlc_df = nyc_tlc.to_pandas_dataframe() " + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.6/dist-packages/azureml/opendatasets/dataaccess/_blob_accessor.py:526: Warning: Please install azureml-dataset-runtimeusing pip install azureml-dataset-runtime\n", + " Warning)\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00000-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426339-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00001-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426336-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00002-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426334-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00003-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426340-115.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00004-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426331-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00005-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426324-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00006-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426326-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00007-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426332-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00008-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426341-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00009-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426325-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00010-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426335-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00011-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426338-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00012-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426337-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00013-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426327-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00014-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426330-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00015-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426342-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00016-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426328-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00017-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426323-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00018-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426329-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=5/part-00019-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426333-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00000-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426339-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00001-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426336-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00002-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426334-120.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00003-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426340-116.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00004-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426331-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00005-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426324-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00006-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426326-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00007-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426332-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00008-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426341-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00009-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426325-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00010-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426335-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00011-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426338-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00012-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426337-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00013-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426327-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00014-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426330-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00015-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426342-118.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00016-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426328-117.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00017-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426323-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00018-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426329-119.c000.snappy.parquet\n", + "[Info] read from /tmp/tmpmgax2urz/https%3A/%2Fazureopendatastorage.azurefd.net/nyctlc/yellow/puYear=2018/puMonth=6/part-00019-tid-8898858832658823408-a1de80bd-eed3-4d11-b9d4-fa74bfbd47bc-426333-117.c000.snappy.parquet\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-zwPxoLxVgp" + }, + "source": [ + "Link: https://docs.microsoft.com/pt-pt/azure/machine-learning/tutorial-auto-train-models" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tUwpNHtbwn41", + "outputId": "f7a9e926-5e4c-49d0-9fc8-2797121bd120", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + " nyc_tlc_df.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
vendorIDtpepPickupDateTimetpepDropoffDateTimepassengerCounttripDistancepuLocationIddoLocationIdstartLonstartLatendLonendLatrateCodeIdstoreAndFwdFlagpaymentTypefareAmountextramtaTaximprovementSurchargetipAmounttollsAmounttotalAmount
022018-05-27 17:50:342018-05-27 17:56:4130.82161100NaNNaNNaNNaN1N26.00.00.50.30.000.06.80
122018-05-23 08:20:412018-05-23 08:37:0611.69142162NaNNaNNaNNaN1N111.50.00.50.33.080.015.38
322018-05-23 09:02:542018-05-23 09:17:5926.6414087NaNNaNNaNNaN1N219.50.00.50.30.000.020.30
522018-05-23 13:28:482018-05-23 13:35:1510.61170234NaNNaNNaNNaN1N16.00.00.50.31.000.07.80
722018-05-23 07:05:502018-05-23 07:07:4020.484850NaNNaNNaNNaN1N23.50.00.50.30.000.04.30
\n", + "
" + ], + "text/plain": [ + " vendorID tpepPickupDateTime ... tollsAmount totalAmount\n", + "0 2 2018-05-27 17:50:34 ... 0.0 6.80\n", + "1 2 2018-05-23 08:20:41 ... 0.0 15.38\n", + "3 2 2018-05-23 09:02:54 ... 0.0 20.30\n", + "5 2 2018-05-23 13:28:48 ... 0.0 7.80\n", + "7 2 2018-05-23 07:05:50 ... 0.0 4.30\n", + "\n", + "[5 rows x 21 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oflehhy7wtde", + "outputId": "b62418c1-5469-4c9c-d693-20af6c87b48b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "nyc_tlc_df.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(10695823, 21)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C1-G9EajxFbJ" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n", + "* Conceitos estatísticos de bias & variance;\n", + "* Ver Sklearn.optimize: https://web.telegram.org/#/im?p=g497957288;\n", + "* Construir a package para conter todas as funções definidas e colocar estas funções na package --> Manutenção rápida, fácil e centralizada! Desta forma, o tópico (\"Funções usadas neste tutorial\") vai totalmente para o package." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XRukccWQSklx" + }, + "source": [ + "## Medidas para avaliarmos a variabilidade presente nos dados\n", + "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n", + "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n", + "\n", + "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância --> Principal medida para medir a variabilidade presente nos dados.\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING** (= Hiperparâmetros ótimos dos modelos de Machine Learning)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos hiperparâmetros dos modelos de ML)\n", + "* Encontra os hiperparâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os hiperparâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gkCubyUCP_hn" + }, + "source": [ + "### Funções usadas neste tutorial" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZD2pH9hfTnZv" + }, + "source": [ + "#### Função para Cross-Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hr8LczrSQB0x" + }, + "source": [ + "def funcao_cross_val_score(modelo, X_treinamento, y_treinamento, CV):\n", + " # versão com sklearn.model_selection.cross_validate:\n", + " #a_scores_CV = cross_validate(modelo, X_treinamento, y_treinamento, cv = CV, scoring = metodo)\n", + " #print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " #print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + " #return a_scores_CV\n", + "\n", + " #versão com cross_val_score::\n", + " a_scores_CV = cross_val_score(modelo, X_treinamento, y_treinamento, cv = CV)\n", + " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + " return a_scores_CV" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "#### Função para plotar a Confusion Matrix\n", + "* Extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, \n", + " figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8J-sTUfTTdLi" + }, + "source": [ + "#### Função para o GridSearchCV" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "def GridSearchOptimizer(modelo, ml_Opt, d_hiperparametros, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_hiperparametros, cv = i_CV, n_jobs = -1, verbose= 10, scoring = 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n", + " tempo_elapsed = time()-start\n", + " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Hiperparâmetros que otimizam a classificação:\n", + " print(f'\\nHiperparâmetros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os hiperparâmetros otimizados...\n", + " ml_Opt.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = funcao_cross_val_score(ml_Opt, X_treinamento, y_treinamento, i_CV)\n", + "\n", + " # Faz predições com os hiperparâmetros otimizados...\n", + " y_pred = ml_Opt.predict(X_teste)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_teste, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YMnQn2XgT7Mg" + }, + "source": [ + "#### Função para selecionar COLUNAS relevantes dos dataframes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsnHcaeLUDFS" + }, + "source": [ + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_treinamento, X_teste, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_treinamento_I = sfm.transform(X_treinamento)\n", + " X_teste_I = sfm.transform(X_teste)\n", + " return X_treinamento_I, X_teste_I " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gd98JFSGUV5n" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "### Função para calcular a importância das colunas/variáveis/atributos\n", + "* Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_treinamento, y_treinamento=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_treinamento and y_treinamento are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_treinamento (pandas DataFrame)\n", + " \n", + " y_treinamento (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_treinamento.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "X, y = make_classification(n_samples = 1000, \n", + " n_features = 18, \n", + " n_informative = 9, \n", + " n_redundant = 6, \n", + " n_repeated = 3, \n", + " n_classes = 2, \n", + " n_clusters_per_class = 1, \n", + " random_state=i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gWy2IZh3s-o3", + "outputId": "9ddd6f9a-cfa1-4421-f25b-5e61297a966f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 235 + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0.06844089, 4.21184154, -2.5583024 , ..., -0.63061895,\n", + " -0.97831983, -0.88826977],\n", + " [-4.8240213 , 0.17950903, -2.98447332, ..., 0.33992045,\n", + " 1.89153784, -6.10967565],\n", + " [ 1.38953042, -0.226476 , 1.8774004 , ..., -1.47784549,\n", + " 0.96052606, 2.06020368],\n", + " ...,\n", + " [ 1.62548685, 0.43377848, 4.93537285, ..., -4.61990917,\n", + " 0.18310709, 6.16040231],\n", + " [-2.40619087, -1.65474635, 2.64196493, ..., -1.21427845,\n", + " 0.83745861, 0.8254619 ],\n", + " [-4.00041881, 2.52475556, -4.15290177, ..., -0.51680266,\n", + " 1.72224835, -5.59558306]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 73 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccjhGnzxtAaV", + "outputId": "f756e8a1-baba-42e0-c358-660fd16b5017", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "y[0:30] # Semelhante aos casos de fraude: {0, 1}" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 74 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais Hiperparâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "eefcee87-d906-4d9e-ddf4-b6c969601263", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
00.0684414.211842-2.5583023.665482-3.8351583.4998512.4908563.6654820.2451170.8671722.8655460.493956-5.1485962.8655463.499851-0.630619-0.978320-0.888270
1-4.8240210.179509-2.9844731.033618-3.8934263.428734-3.3346051.033618-0.882780-0.7532811.441522-1.395514-4.0028801.4415223.4287340.3399201.891538-6.109676
21.389530-0.2264761.8774002.7134264.6302570.516455-3.7430272.7134261.2840392.030797-1.0955361.560159-1.014211-1.0955360.516455-1.4778450.9605262.060204
31.1458092.2559460.2073644.6658172.2946786.5013060.9647704.6658170.1194103.1963541.8947873.519138-4.7578071.8947876.501306-3.7890290.5794911.397106
4-0.9366463.697163-3.3636173.805126-1.7544304.9543460.4066053.805126-0.8247381.3825911.665704-0.649758-3.5130361.6657044.9543460.2570520.904244-3.071354
\n", + "
" + ], + "text/plain": [ + " v1 v2 v3 ... v16 v17 v18\n", + "0 0.068441 4.211842 -2.558302 ... -0.630619 -0.978320 -0.888270\n", + "1 -4.824021 0.179509 -2.984473 ... 0.339920 1.891538 -6.109676\n", + "2 1.389530 -0.226476 1.877400 ... -1.477845 0.960526 2.060204\n", + "3 1.145809 2.255946 0.207364 ... -3.789029 0.579491 1.397106\n", + "4 -0.936646 3.697163 -3.363617 ... 0.257052 0.904244 -3.071354\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 77 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "1a828ec6-51fa-4e8e-f081-c43f8e74b55b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 78 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "750797e1-f1c0-4da6-bc32-33d91a8770e4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 79 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "5ecb44eb-d7ba-46cf-c460-c48cbe02dbea", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "df_X.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
count1000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000000
mean-0.0851591.0342270.6574081.4053170.6872791.1315600.1080531.4053171.0070231.0488010.0792480.001650-0.3654380.0792481.131560-0.0277510.9846060.633624
std2.0022471.6315073.6087722.2568574.0195984.4818321.9813072.2568571.8632881.6439001.9492731.9326414.1606681.9492734.4818322.0654551.8505933.552991
min-6.944169-4.620754-16.300139-6.235192-12.454256-14.305401-6.152747-6.235192-5.484992-3.293216-7.135349-5.705500-9.120941-7.135349-14.305401-6.009023-5.035184-11.439074
25%-1.305566-0.089052-1.623657-0.152888-1.854645-1.684751-1.216983-0.152888-0.240908-0.012710-1.209675-1.292162-3.555363-1.209675-1.684751-1.436673-0.261610-1.691346
50%0.0525230.9941500.5738491.4499310.8123641.2815040.1670911.4499311.0661251.0128990.1803440.035237-0.9666380.1803441.281504-0.0001900.9757930.844784
75%1.3838532.0719953.0385862.8871413.4139524.0081031.4387192.8871412.2881882.1872021.4391991.3153422.7458061.4391994.0081031.3653692.2565043.109330
max4.9971727.35486011.7201658.49456612.84441815.9998036.2935508.4945668.1465596.5231806.2524485.53821611.2593506.25244815.9998036.5315617.64680212.090528
\n", + "
" + ], + "text/plain": [ + " v1 v2 ... v17 v18\n", + "count 1000.000000 1000.000000 ... 1000.000000 1000.000000\n", + "mean -0.085159 1.034227 ... 0.984606 0.633624\n", + "std 2.002247 1.631507 ... 1.850593 3.552991\n", + "min -6.944169 -4.620754 ... -5.035184 -11.439074\n", + "25% -1.305566 -0.089052 ... -0.261610 -1.691346\n", + "50% 0.052523 0.994150 ... 0.975793 0.844784\n", + "75% 1.383853 2.071995 ... 2.256504 3.109330\n", + "max 4.997172 7.354860 ... 7.646802 12.090528\n", + "\n", + "[8 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 80 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "\n", + "* Dividir os dados/amostras em:\n", + " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n", + " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n", + "* **Técnica de Hold-Out**: Separar/dividir os dados em amostra de treinamento e teste. Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + " * **Desvatangem do Hold-Out**: Variância nos dados pode comprometer performance do modelo quando, por exemplo, amostra de treinamento é semelhante amostra de teste. \n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "257ee423-a06a-47ad-b865-bbc2078a305f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 82 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "bdf4bde9-fb11-4b98-e9ce-14c23fa75e11", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 83 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "271793ff-abc0-4295-bac6-b5125e7a8528", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 84 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "3d9f27a2-ae55-4448-d59e-059fc80cb37c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 85 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "d4435fc5-9916-4abb-d2c8-ad320c867eee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 67 + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os hiperparâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score # Para o CV (Cross-Validation)\n", + "from sklearn.model_selection import cross_validate\n", + "\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n", + "\n", + "# Instancia (configuração do Decision Trees) com os hiperparâmetros sugeridos para se evitar overfitting:\n", + "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split = 2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, \n", + " class_weight = None, \n", + " presort = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gVLZznprx2YX", + "outputId": "a4c2b726-2902-4d0f-a048-fb83a0beee72", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 118 + } + }, + "source": [ + "# Objeto/classificador configurado\n", + "ml_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 90 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8CC24H-JHhlj" + }, + "source": [ + "### Treina o algoritmo: fit(df)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "06683422-3e33-4643-8283-8ba0cebd7980", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 118 + } + }, + "source": [ + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 91 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CNiRjmrRHVnx" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2GMCSs89HquJ", + "outputId": "82a67cd4-033e-484f-9209-7d434380b074", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 92 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bmv9YZobIer4" + }, + "source": [ + "### Calcula as predições usando o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2YufZaRNIkFL" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fYvMN-tvIX-p" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9iTK6pBwIZ3F", + "outputId": "20492dbd-48e7-46c2-d724-931ce2cd9e98", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jOnkFBcEIVAb" + }, + "source": [ + "### Volte ao início, extraia nova amostra e calcule a acurácia\n", + "* Observou que a acurácia mudou? Isso acontece porque extraimos uma nova amostra de treinamento.\n", + "* Quais os inconvenientes de termos uma métrica diferente para cada amostra do modelo preditivo?\n", + "* Como reportar os resultados do seu modelo?\n", + "* Como se assegurar acerca do valor mais ideal da métrica?\n", + " * use a Estatística a seu favor! --> Use Cross-Validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n", + "* Como funciona: divide o dataframe de treinamento em k partes (cada parte é um fold);\n", + " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n", + " * O processo é repetido k vezes, sendo que em cada iteração calcula as métricas desejadas (exemplo: acurácia);\n", + " * Desta forma o modelo é treinado e testado com todas as partes dos dados;\n", + " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n", + "\n", + " A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **valor de k**:\n", + " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n", + " * Quanto maior o valor de k --> menor o viés do CV --> Experimento Estatístico para mostrar o efeito.\n", + "\n", + "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HscfN-a1V043" + }, + "source": [ + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8x2UPwOYQPcI", + "outputId": "9fe6a0f2-c7e9-48b4-a2bc-4f4e7bd09672", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cross-Validation com k = 10 folds (= 10 partes)\n", + "a_scores_CV = funcao_cross_val_score(ml_DT, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.44\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uxoplcea0byV", + "outputId": "19aa7a0d-59c6-432c-bf8b-ae7672d68f27", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.9 , 0.98571429, 0.85714286, 0.92857143, 0.88571429,\n", + " 0.94285714, 0.92857143, 0.9 , 0.88571429, 0.92857143])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 96 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y3k-PcbN0o_i", + "outputId": "9f821901-32a6-4ce2-884c-4cbda1f1b774", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_scores_CV.mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9142857142857144" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 97 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "5a54bca4-47e0-4077-de1c-1b88fae4afdd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n", + " 0.92857143 0.9 0.88571429 0.92857143]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lQNyqHCiKRUh" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qb0ZPyvKKRUp", + "outputId": "fa17085f-fc2d-4323-b046-873b0d14c391", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 99 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iL2tEdbqKY5P" + }, + "source": [ + "### Predições com o modelo treinado\n", + "* Faz predições usando o classificador (Decision Trees) para inferir na amostra de teste:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rfapj3OG13PG", + "outputId": "330e27c8-c056-4161-c668-a26b27fee148", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "y_pred[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n", + " 1, 0, 0, 1, 1, 0, 1, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 101 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sc88ofqh16RT", + "outputId": "b404e488-1f50-4157-dfba-7db67a45f328", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "y[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 102 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cecv-51TKgz-" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "77c1a652-fcd6-400d-db0e-323a37024c55", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário com hiperparâmetros para o parameter tunning. Ao todo serão ajustados 2X13X5X5X7= 4.550 modelos. Contando com 10 folds no Cross-Validation, então são 45.500 modelos.\n", + "d_hiperparametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n", + " \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \n", + " \"max_depth\": [None, 2, 5, 9, 15], \n", + " \"min_samples_leaf\": [20, 40, 60, 80, 100], \n", + " \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BtajXuuUpGwq", + "outputId": "0a395fb9-2b86-4baf-c06f-87562bdd55c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 336 + } + }, + "source": [ + "d_hiperparametros_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': ['gini', 'entropy'],\n", + " 'max_depth': [None, 2, 5, 9, 15],\n", + " 'max_leaf_nodes': [None, 2, 3, 4, 5, 10, 15],\n", + " 'min_samples_leaf': [20, 40, 60, 80, 100],\n", + " 'min_samples_split': [2,\n", + " 5,\n", + " 10,\n", + " 30,\n", + " 50,\n", + " 70,\n", + " 90,\n", + " 120,\n", + " 150,\n", + " 180,\n", + " 210,\n", + " 240,\n", + " 270,\n", + " 350,\n", + " 400]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 105 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_hiperparametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_treinamento, y_treinamento)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25", + "outputId": "40ce711e-9258-432d-c327-30d92900dc5c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "# Invoca a função com o modelo baseline\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_hiperparametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.0s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.0s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.1s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1908s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.1s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0439s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 28 tasks | elapsed: 1.2s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0734s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1218s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Done 72 tasks | elapsed: 1.5s\n", + "[Parallel(n_jobs=-1)]: Done 216 tasks | elapsed: 2.2s\n", + "[Parallel(n_jobs=-1)]: Done 360 tasks | elapsed: 2.9s\n", + "[Parallel(n_jobs=-1)]: Done 536 tasks | elapsed: 3.6s\n", + "[Parallel(n_jobs=-1)]: Done 712 tasks | elapsed: 4.3s\n", + "[Parallel(n_jobs=-1)]: Done 920 tasks | elapsed: 5.1s\n", + "[Parallel(n_jobs=-1)]: Done 1128 tasks | elapsed: 6.0s\n", + "[Parallel(n_jobs=-1)]: Done 1368 tasks | elapsed: 6.9s\n", + "[Parallel(n_jobs=-1)]: Done 1608 tasks | elapsed: 7.9s\n", + "[Parallel(n_jobs=-1)]: Done 1880 tasks | elapsed: 9.0s\n", + "[Parallel(n_jobs=-1)]: Done 2152 tasks | elapsed: 10.0s\n", + "[Parallel(n_jobs=-1)]: Done 2456 tasks | elapsed: 11.2s\n", + "[Parallel(n_jobs=-1)]: Done 2760 tasks | elapsed: 12.4s\n", + "[Parallel(n_jobs=-1)]: Done 3096 tasks | elapsed: 13.8s\n", + "[Parallel(n_jobs=-1)]: Done 3432 tasks | elapsed: 15.3s\n", + "[Parallel(n_jobs=-1)]: Done 3800 tasks | elapsed: 16.7s\n", + "[Parallel(n_jobs=-1)]: Done 4168 tasks | elapsed: 18.4s\n", + "[Parallel(n_jobs=-1)]: Done 4568 tasks | elapsed: 20.3s\n", + "[Parallel(n_jobs=-1)]: Done 4968 tasks | elapsed: 22.4s\n", + "[Parallel(n_jobs=-1)]: Done 5400 tasks | elapsed: 24.1s\n", + "[Parallel(n_jobs=-1)]: Done 5832 tasks | elapsed: 25.7s\n", + "[Parallel(n_jobs=-1)]: Done 6296 tasks | elapsed: 27.5s\n", + "[Parallel(n_jobs=-1)]: Done 6760 tasks | elapsed: 29.2s\n", + "[Parallel(n_jobs=-1)]: Done 7256 tasks | elapsed: 31.2s\n", + "[Parallel(n_jobs=-1)]: Done 7752 tasks | elapsed: 33.1s\n", + "[Parallel(n_jobs=-1)]: Done 8280 tasks | elapsed: 35.2s\n", + "[Parallel(n_jobs=-1)]: Done 8808 tasks | elapsed: 37.2s\n", + "[Parallel(n_jobs=-1)]: Done 9368 tasks | elapsed: 39.4s\n", + "[Parallel(n_jobs=-1)]: Done 9928 tasks | elapsed: 41.5s\n", + "[Parallel(n_jobs=-1)]: Done 10520 tasks | elapsed: 43.7s\n", + "[Parallel(n_jobs=-1)]: Done 11112 tasks | elapsed: 46.2s\n", + "[Parallel(n_jobs=-1)]: Done 11736 tasks | elapsed: 48.6s\n", + "[Parallel(n_jobs=-1)]: Done 12360 tasks | elapsed: 51.1s\n", + "[Parallel(n_jobs=-1)]: Done 13016 tasks | elapsed: 53.8s\n", + "[Parallel(n_jobs=-1)]: Done 13672 tasks | elapsed: 56.8s\n", + "[Parallel(n_jobs=-1)]: Done 14360 tasks | elapsed: 59.6s\n", + "[Parallel(n_jobs=-1)]: Done 15048 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 15768 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 16488 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 17240 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 17992 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 18776 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 19560 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 20376 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 21192 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 22040 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 22888 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 23768 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 24648 tasks | elapsed: 1.7min\n", + "[Parallel(n_jobs=-1)]: Done 25560 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 26472 tasks | elapsed: 1.8min\n", + "[Parallel(n_jobs=-1)]: Done 27416 tasks | elapsed: 1.9min\n", + "[Parallel(n_jobs=-1)]: Done 28360 tasks | elapsed: 2.0min\n", + "[Parallel(n_jobs=-1)]: Done 29336 tasks | elapsed: 2.1min\n", + "[Parallel(n_jobs=-1)]: Done 30312 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 31320 tasks | elapsed: 2.2min\n", + "[Parallel(n_jobs=-1)]: Done 32328 tasks | elapsed: 2.3min\n", + "[Parallel(n_jobs=-1)]: Done 33368 tasks | elapsed: 2.4min\n", + "[Parallel(n_jobs=-1)]: Done 34408 tasks | elapsed: 2.5min\n", + "[Parallel(n_jobs=-1)]: Done 35480 tasks | elapsed: 2.6min\n", + "[Parallel(n_jobs=-1)]: Done 36552 tasks | elapsed: 2.7min\n", + "[Parallel(n_jobs=-1)]: Done 37656 tasks | elapsed: 2.8min\n", + "[Parallel(n_jobs=-1)]: Done 38760 tasks | elapsed: 2.8min\n", + "[Parallel(n_jobs=-1)]: Done 39896 tasks | elapsed: 2.9min\n", + "[Parallel(n_jobs=-1)]: Done 41032 tasks | elapsed: 3.0min\n", + "[Parallel(n_jobs=-1)]: Done 42200 tasks | elapsed: 3.1min\n", + "[Parallel(n_jobs=-1)]: Done 43368 tasks | elapsed: 3.2min\n", + "[Parallel(n_jobs=-1)]: Done 44568 tasks | elapsed: 3.3min\n", + "[Parallel(n_jobs=-1)]: Done 45768 tasks | elapsed: 3.4min\n", + "[Parallel(n_jobs=-1)]: Done 47000 tasks | elapsed: 3.6min\n", + "[Parallel(n_jobs=-1)]: Done 48232 tasks | elapsed: 3.7min\n", + "[Parallel(n_jobs=-1)]: Done 49496 tasks | elapsed: 3.8min\n", + "[Parallel(n_jobs=-1)]: Done 50760 tasks | elapsed: 3.9min\n", + "[Parallel(n_jobs=-1)]: Done 52056 tasks | elapsed: 4.0min\n", + "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 4.0min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 70}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 87.14\n", + "std médio das Acurácias calculadas pelo CV: 4.33\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "12 v13 0.735896\n", + "0 v1 0.135030\n", + "9 v10 0.090888\n", + "6 v7 0.025768\n", + "1 v2 0.012418\n", + "3 v4 0.000000\n", + "4 v5 0.000000\n", + "5 v6 0.000000\n", + "7 v8 0.000000\n", + "8 v9 0.000000\n", + "10 v11 0.000000\n", + "11 v12 0.000000\n", + "2 v3 0.000000\n", + "13 v14 0.000000\n", + "14 v15 0.000000\n", + "15 v16 0.000000\n", + "16 v17 0.000000\n", + "17 v18 0.000000\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0", + "outputId": "281d1c7d-0104-4575-bb27-88e98e590ee2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 753 + } + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 108 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf", + "outputId": "81c17f60-7890-4f2a-8946-56a443d3306c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 67 + } + }, + "source": [ + "X_treinamento_DT, X_teste_DT = seleciona_colunas_relevantes(ml_DT2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "********** COLUNAS Relevantes ******\n", + "[ 0 9 12]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm", + "outputId": "3e5e4663-dfae-46f6-d037-92dd028bc834", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 101 + } + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 20,\n", + " 'min_samples_split': 70}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 111 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt", + "outputId": "31e88125-b928-4910-8536-19f922dc1ee1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 118 + } + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_treinamento_DT, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='entropy',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=70, min_samples_split=20,\n", + " min_weight_fraction_leaf=0.0, presort='deprecated',\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 112 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M2h3EpinRD5Q", + "outputId": "1345e3c8-460f-4cbc-df74-2d84140df2bb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT2, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 87.14\n", + "std médio das Acurácias calculadas pelo CV: 4.33\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3", + "outputId": "7b7b71c8-89cd-4d91-ea70-81f8d57fc7b3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_hiperparametros_DT, X_treinamento_DT, y_treinamento, X_teste_DT, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 0.0s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0088s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0088s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 0.0s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0256s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Done 28 tasks | elapsed: 0.1s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0537s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0830s.) Setting batch_size=32.\n", + "[Parallel(n_jobs=-1)]: Done 84 tasks | elapsed: 0.2s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1519s.) Setting batch_size=64.\n", + "[Parallel(n_jobs=-1)]: Done 308 tasks | elapsed: 0.8s\n", + "[Parallel(n_jobs=-1)]: Done 756 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Done 1332 tasks | elapsed: 2.6s\n", + "[Parallel(n_jobs=-1)]: Done 1908 tasks | elapsed: 3.6s\n", + "[Parallel(n_jobs=-1)]: Done 2612 tasks | elapsed: 4.9s\n", + "[Parallel(n_jobs=-1)]: Done 3316 tasks | elapsed: 6.1s\n", + "[Parallel(n_jobs=-1)]: Done 4148 tasks | elapsed: 7.7s\n", + "[Parallel(n_jobs=-1)]: Done 4980 tasks | elapsed: 9.1s\n", + "[Parallel(n_jobs=-1)]: Done 5940 tasks | elapsed: 10.7s\n", + "[Parallel(n_jobs=-1)]: Done 6900 tasks | elapsed: 12.4s\n", + "[Parallel(n_jobs=-1)]: Done 7988 tasks | elapsed: 14.3s\n", + "[Parallel(n_jobs=-1)]: Done 9076 tasks | elapsed: 16.2s\n", + "[Parallel(n_jobs=-1)]: Done 10292 tasks | elapsed: 18.2s\n", + "[Parallel(n_jobs=-1)]: Done 11508 tasks | elapsed: 20.6s\n", + "[Parallel(n_jobs=-1)]: Done 12852 tasks | elapsed: 23.3s\n", + "[Parallel(n_jobs=-1)]: Done 14196 tasks | elapsed: 25.6s\n", + "[Parallel(n_jobs=-1)]: Done 15668 tasks | elapsed: 28.3s\n", + "[Parallel(n_jobs=-1)]: Done 17140 tasks | elapsed: 30.9s\n", + "[Parallel(n_jobs=-1)]: Done 18740 tasks | elapsed: 33.6s\n", + "[Parallel(n_jobs=-1)]: Done 20340 tasks | elapsed: 36.6s\n", + "[Parallel(n_jobs=-1)]: Done 22068 tasks | elapsed: 39.7s\n", + "[Parallel(n_jobs=-1)]: Done 23796 tasks | elapsed: 42.8s\n", + "[Parallel(n_jobs=-1)]: Done 25652 tasks | elapsed: 46.1s\n", + "[Parallel(n_jobs=-1)]: Done 27508 tasks | elapsed: 49.5s\n", + "[Parallel(n_jobs=-1)]: Done 29492 tasks | elapsed: 53.3s\n", + "[Parallel(n_jobs=-1)]: Done 31476 tasks | elapsed: 57.6s\n", + "[Parallel(n_jobs=-1)]: Done 33588 tasks | elapsed: 1.0min\n", + "[Parallel(n_jobs=-1)]: Done 35700 tasks | elapsed: 1.1min\n", + "[Parallel(n_jobs=-1)]: Done 37940 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 40180 tasks | elapsed: 1.2min\n", + "[Parallel(n_jobs=-1)]: Done 42548 tasks | elapsed: 1.3min\n", + "[Parallel(n_jobs=-1)]: Done 44916 tasks | elapsed: 1.4min\n", + "[Parallel(n_jobs=-1)]: Done 47412 tasks | elapsed: 1.5min\n", + "[Parallel(n_jobs=-1)]: Done 49908 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 52406 tasks | elapsed: 1.6min\n", + "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 1.6min finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 60, 'min_samples_split': 2}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 89.29\n", + "std médio das Acurácias calculadas pelo CV: 2.73\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "2 v3 0.691283\n", + "0 v1 0.177569\n", + "1 v2 0.131148\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAIJCAYAAADQ9vbrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdeZxP1R/H8ddnjH0fW0JZS5IQpahshZAlZCkVJdlLKfHTvm9S2SlkzZYKKXvKlmSvJMkSMrYsY5bz+2O+ppkvs7hmzMx33s8e9+F7zz33nHPn5zcfn3PuvV9zziEiIiL/CUrtAYiIiKQ1Co4iIiJ+FBxFRET8KDiKiIj4UXAUERHxo+AoIiLiJzglGs1epYeeD5F07/CaD1N7CCLJIlswllJtp8Tv+1M/fZhi400qZY4iIiJ+UiRzFBGRDMICM8cKzKsSERG5CMocRUTEO0v15cEUocxRRETEj4KjiIh4Z0HJvyWlW7OxZnbAzDad51hfM3NmVtC3b2Y2xMy2m9kGM6uaWPsKjiIi4p1Z8m9J8wnQ8NzhWAngTmBXrOJGQDnf1gUYlljjCo4iIpLuOOeWAaHnOfQe0A+I/fxlM2C8i7YSyGdmRRNqXzfkiIiId2noUQ4zawbscc79bHEz0GLAX7H2d/vK9sXXloKjiIikKWbWhejpz7NGOudGJnJODuBZoqdUL5qCo4iIeJcCj3L4AmGCwfA8ygClgLNZY3FgnZndCOwBSsSqW9xXFi8FRxER8S6NTKs65zYChc/um9lOoJpz7h8zmwP0MLMpwE3AUedcvFOqoBtyREQkHTKzycAPwNVmttvMOidQfS6wA9gOjAK6Jda+MkcREfEuld6Q45xrl8jxkrE+O6D7hbSvzFFERMSPMkcREfEujaw5JjcFRxER8U4vHhcREckYlDmKiIh3ATqtGphXJSIichGUOYqIiHdacxQREckYlDmKiIh3AbrmqOAoIiLeBWhwDMyrEhERuQjKHEVExLsg3ZAjIiKSIShzFBER7wJ0zVHBUUREvNNzjiIiIhmDMkcREfEuQKdVA/OqRERELoIyRxER8S5A1xwVHEVExDtNq4qIiGQMyhxFRMS7AJ1WVeYoIiLiR5mjiIh4F6BrjgqOIiLinaZVRUREMgZljiIi4l2ATqsG5lWJiIhcBGWOIiLindYcRUREMgZljiIi4l2ArjkqOIqIiHcBGhwD86pEREQugjJHERHxTjfkiIiIZAzKHEVExLsAXXNUcBQREe80rSoiIpIxKHMUERHvAnRaNTCvSkRE5CIocxQREe8CdM1RwVFERDyzAA2OmlYVERHxo8xRREQ8U+YoIiKSQShzFBER7wIzcVTmKCIi4k+Zo4iIeBaoa44KjiIi4lmgBkdNq4qIiPhR5igiIp4pcxQREckglDmKiIhngZo5KjiKiIh3gRkbNa0qIiLiT5mjiIh4FqjTqsocRUQk3TGzsWZ2wMw2xSp7y8y2mdkGM5tlZvliHetvZtvN7Bcza5BY+wqOIiLimZkl+5ZEnwAN/cq+ASo65yoBvwL9fWOsALQFrvWdM9TMMiXUuIKjiIh4llrB0Tm3DAj1K1vgnIvw7a4Eivs+NwOmOOfCnHN/ANuBGxNqX8FRREQCUSdgnu9zMeCvWMd2+8ripRtyRETEs5S4IcfMugBdYhWNdM6NvIDzBwARwESvY1BwFBGRNMUXCJMcDGMzsweBJkA955zzFe8BSsSqVtxXFi9Nq4qIiHeWApvXoZg1BPoBdzvnTsY6NAdoa2ZZzawUUA5YnVBbyhxFRCTdMbPJQG2goJntBp4j+u7UrMA3vunelc65rs65zWY2DdhC9HRrd+dcZELtKziKiIhnqfUSAOdcu/MUj0mg/ivAK0ltX8FRREQ80xtyREREMghljiIi4pkyRxERkQxCmaOIiHgXmImjgqOIiHinaVUREZEMQpmjiIh4psxRREQkg1DmKCIingVq5qjgKCIingVqcNS0qoiIiB9ljiIi4l1gJo7KHC9ESN6crJzyDCunPMMf37zK71+/HLOfOThTsva17asXmPz2wzH7LepXZuQL9yVrHwA92tcme7bMMfuzPniMvLmyJ3s/kjZVue4a2rRsFrPt2bM73ro1qlVJtn47P3g/dzduQOsWd/NAh7bs/GPHBbfRvesjHDt2jGPHjjF18n9f+H7gwH769umVbGOVjEmZ4wUIPXqCGm1fB2DAo3dx4mQYgycsjDmeKVMQkZFRydZflWtKUL70ZWzb8XeytemvR4c6TJ67hlOnwwFo0XNYivUlaU/WrNmYNvPzVOn7tTfe5tqK1zF92lTefftNhnw0/ILO/2j4KAD27NnN1CmTubddBwAKFy7CO4OHJPt45fy05ijnNfKF+xgyoC3Lxj/Jq32aM+DRu+hzf72Y42s/e5YrioYA0Pau6iyf8CQrpzzDBwPaEhSU8F+q9ycs4unODc4pz5EtC8Of68DyCU/yw+SnaVL7OgCyZ8vMp290Yt2MAUx95xGWjX+SqhWuiG7r2Xv5bmI/fpw+gIFd7wKgW7vbKVooL/NH9mb+yOh/aW/76gUK5MvJS73u5tE2t8X0Gfu6Hu9Yj+8+fYrVU/vHtCWB4eSJEzzS6QHubdWCe5o3ZfGib8+pc/DgAR7q2IE2LZvRslkT1v24FoDvV3zH/e3v5d5WLXjy8V6cPHEiSX3eUK0af+3ahXOOd99+g5bNmnBP86bMnzc3wf4a3VGXw4dDef+9d9j91y7atGzGu2+/wZ49u2nZrAkA97Vrw/btv8X01fnB+9m8aSMnT55k0MD+tL+3FW3uaX7e65SMTZljMihWOB+1H3yHqCjHgEfPHyyuLlWEVndWpc5D7xIREcXg/m1oe1d1Jn25Ot52ZyxYR5fWt1K6RME45U8/3IAla36l6wsTyZsrO8s/fYpFK3+hS+tbOXzsJFXveYUKZYqyasozMec8/+EXHD52kqAgY96IXlQsdzlDJy+l1311adjlfQ4difuLbPrX63jrqXsYMW0ZAPfcWYW7u31EvRrlKXNFYWrd9xZmxvTBj1KzahlWrPvd649PUlFY2GnatGwGwOXFi/P2u+/z3pCPyJUrF4cPh3J/u3upXadenOxg7ldfckvNWjzy6GNERkZy+vQpDh8OZdSIYYwY/TE5cuRg7OiRjB/3MV279Uh0DEuXLKbsVVex8JsF/LJtG5/N/Jwjhw/T/t5W3FCt2nn7i633433Z/ttvMRlw7KnhBg3vYsH8eZTtUY6DBw9w8OABrq14HUMGv8uNN9XgxZdf49ixY3Ro25qbatxCjhw5kuPHmqEEauao4JgMZn77E1FRLsE6dW68mqoVruC7T/sBkD1rZg6G/pvgOZFRUbw3/lue6nQnC1ZsiSmvd/M1NL79Ovp0jM7ksmUJpkTR/NxSpTQfTloCwJbf97Hxt70x59xzZ1U6taxJcKYgLiuUh2tKF2VTrOP+fv5lN4Xy56ZoobwUzJ+LI8dOsnv/Ebq3r0P9m8uz0hd4c2XPStkrCis4plP+06rh4eEMGfwu635cQ5AFceDAfg798w8FCxWKqVOx4nU8N/BZIiIiqFO3PuWvuYa1axaz4/ftPHhfu5h2KlWunGDf/Z9+kmxZs3F5sWI88+z/mDDuYxre1ZhMmTJRoGBBbqhenc0bN563v6S6s2Ejuj7SiW49erFg/jzuuLMhAD98/x1LFi9i/MdjATgTFsbf+/ZRukyZJLct0RQcJV4nT4XFfI6IjIwzXZotS/TNLmbGp1+sYtAHcy6o7UlfreapTneyZfu+mDID2j05mt/+PJCkNq68vAB97q9Hrfve5MjxU4x84T6yZkn8f/qZ3/5Ei/qVKVIgD9MXrPNdB7w1dgFjZqy4oOuQ9GHul19w+HAok6fNJHPmzDS6oy5hZ8Li1LmhWnXGjv+U5UuXMmjAM9z/wEPkzpOHGjfX5I23301yX2fXHBNzvv6aNmuepD6KFClCvnz5+PWXbXw9fx4DBz0PgHPw7uAhlCxVOsnjlYxFa47J7M+9oVS+pgQAlcsXp2SxAgAsXv0LLepXplD+XADkz5ODK4rmT7S9iIgoPvh0MT071Ikp+/aHrXRre3vM/vVXFwfgh/U7uOfOqgCUL30ZFcteDkCeXNk4cTqMo/+epnBIbu6sWSHm3OMnwsiVI9t5+57+9Y+0bnADLepXYeY3PwHwzfdbeaDZzeTMngWAywvljbkmSf/+/fc4ISEFyJw5M6tXrWTv3j3n1Nm7dw8FChTkntZtaHFPa7Zu2Uyl6yuz/qd17PrzTwBOnjzJzp1/XFDfVW6oxtfz5hEZGUloaCjr1q6l4nWVzttfbDlz5kxwfbNBw7v4eOxojh8/zlVXlwfglpq1mDTxU5yLnvHZunVLvOdLIiwFtjRAmWMym71wPR2a3MiP0wewZuPOmOxu246/eeGjL/liWA+CzAiPiOTx16exa9/hRNv8ZPYPPPNIw5j910bN560n72HNtGcJCjJ27jnEPb2HM2Lacka/dD/rZgzg1z/2s2XHPo7+e4rfdx3k5227+XnW/9j992FWrv/vtvmxM1cw56Nu7Dt4lIZd4t7ht3XH3+TKkY29B47w9z/HAFi4chvlS13GknFPAnDiVBgPDRjHwcMJTxFL+nBXk6b06v4Y9zRvSoVrK1Kq9LmZ1drVq/nk4zEEBweTI0cOXn7tDUJCQnjxldd45qknOBN+BoAePftQsmSpJPddr/4dbPj5J1q3bIaZ0afvUxQsVIg5s2ed019s+fLlp3KVqrRs1oRat94ac9fqWXfc2YA3X3+FLl27xZR16dqNN19/lVYt7iYqKopixYvz4dARF/KjkgBnZ//llJyyV+mR/I1KooKCjMzBmQg7E0Gp4gWZO7wHlZq/RHhEZGoPLV06vObD1B6CSLLIFpxy+dgVPeck++/7XR/cner5ozLHAJIjWxbmj+pN5uAgDKP3a9MUGEUkRemGHEkRy8Y/SRa/m2M6DxzP5u3x30kan39PhlGrw5vJNTSRi9anV3f27o771p3eTzxJzVq3ptKIRJJGwTGV3dbx7fOWD3+uA41uq8jB0ONUa/1qnGO976/L60+0pHidpzl05ARNal/HoMeaEOUcEZFR9HtrOt+vv/DXcYkkt8FDPoqzP2hgfwb070dISAFmfv4lAEePHKHfk4+zd88eLi9WjLfeGUyevHlTY7jiQaBmjrpbNY2a8MVKmnX/6Jzy4kXyUa/GNezaFxpTtnjVL9x472vUaPs6XZ//lKGD2l/KoYokWbPmLRk2YnScsrGjR3LjTTfzxbwF3HjTzYwZPTKVRifyHwXHNGrFut8JPXrynPI3n7yHAe/PJvaNVCdOnYn5nDN7VlLgHiuRZHFDternZIWLFy/k7ubRzy3e3VyvcktvzCzZt7RA06rpSJPa17H3wBE2/nrus2d316nEiz3vplBIblr2urAXOIukptBDhyhUqDAABQsWIvTQoVQekVyQtBHLkp0yx3Qie7bM9OvUgBeHfXXe43MWb6Byy5dp88RIBnVrfIlHJ5I8zCz6NUwiqUzBMZ0oXbwQVxYrwOqp/dn21QsUK5yPHyY9TZECuePUW7Hud0oVK0iBfDlTaaQiFyakQAEOHox+WcbBgwcICQlJ5RHJhQjUaVUFx3Ri8/a9XFmvP+UbP0f5xs+x58ARbm7/BvsPHY/zrR2Vyxcna5bgc75lQyStql2nLnNmzwZgzuzZ1KlTL5EzRFKe1hzTqHGvPcitN5SjYL5cbJ//Ei8Nn8u42T+ct26LepVp3+QmwiMiOR0Wzv1Pj73EoxVJmqeffIK1a1Zz5Mhh7qh7G49170mnh7vw1BN9mD1zOkUvv5y33hmc2sOUC5BWMr3kptfHicRDr4+TQJGSr48r03desv++//2dRqkecZU5ioiIZwGaOCo4ioiId4E6raobckRERPwoc0wlQUHGion92HvgKPf0Hs63Y/qQK2f0lw4XDsnN2k07afPEqHPOK3FZfoYOak/xIvlxOJr3GMaufaHxnt+8XmX+91hjDh89QZsnRhF69ASlihfkxR5Nuf+Zjy/pNUvgCgsL46GOHQg/c4aIyEjuuLMB3Xr0ilNn2tTJTJ08iUxBQWTPkYNBz79EmbJl2bhhAy89/z8AnHN07d6TevXvIDQ0lMd7def48eP06NWHuvXqA9C7x2MMGPQ8hQsXueTXKecK0MRRwTG19Ghfh1/+2E9uX0Cr3/m/O/Qmv/0wXyzZcN7zRr/UkTdGf82iVdvImT0LUb4bquI7/7G2t1PrvjdpVrcy9zaqxrApS3m+exOeH/plSl2aZEBZsmRh9Nhx5MiZk/DwcB68vz21br2NStdXjqlzV+OmtLm3HQBLFi3k7TdfY9jIMZQtV45J02YQHBzMwYMHaN2yGbfXrsO8uV/S+t621Kt/Jz0e60LdevVZsngR5a+poMAoKU7TqqmgWOF8NKx1LR/P+v6cY7lzZuP26lfxxeJzg2P50pcRnCmIRau2AdHvVD11OjzB86OiosiaOZgc2bIQHhFJzSpl2P/PMX7fdTAFrkwyKjMjR87oF09EREQQERFxTkqRK1eumM+nTp2KWavKnj07wcHR/04PCwuLKc8cHMzpU6cJP3OGoKAgIiIimDhhHA92evhSXJIkUaC+BECZYyp466nol4fnypHtnGNN61RiyepfOH7i9DnHyl1RmCPHTzHl7Ye5slgBFq/6hYFDPicqysV7/ltjv+Gr4T3Zd/AonQaOY+Kbnemo6VRJAZGRkbRr3ZJdu3Zxb7v2VKp0/Tl1pkyayITxHxMeHs6oseNiyjds+JnnBj7Lvr17eeX1NwkODqZR46b079eXGdOn0ueJp5g6ZRJNmjYje/bsl/KyJBFpJJYlO2WOl1ijWytyIPQ4P23967zH2zS8gWnzfzzvseDgIGpWKcMz782i1n1vUap4Qe6/u0aC5y9atY2aHd6kVZ8RNKldia+/20y5Kwsz6a3OfPS/dmTPljn5Lk4ytEyZMjFt5ucsWLSUTRs38Ntvv55Tp237Dnw1/1v6PP4ko4YPiymvVOl6Zs35iklTpzNm1AjCwsLInTs3Hw4byeRpM7nmmgosW7KYO+5swAuDBtK3Ty9+Xv/Tpbw8yWAUHC+xmyuXpsnt17HtqxcY//pD1K5+FWNf7ghAgXw5qXZtSeYt33Tec/fsP8KGX3ezc88hIiOjmLP4ZyqXLxFzPKHzs2fLzP1Nb2L4tGUM7NqYh/83ge/X76Bto+opc6GSYeXJk4fqN97E998tj7dOw7san/erqUqXKUOOHDnY7hdYRwwfysNdujJv7ldUqXoDL736OsM+0ksa0oKgIEv2LS1QcLzEBn0wh7IN/0f5xs/R8ZmPWbLmVzoNHA9Ai/pVmLd8E2FnIs577trNf5I3d3YK5o9eu6ld/Wq27fg75nhC5z/esT5DJy8lIiKK7Nky43BERUWRI1uWFLhKyWhCQ0M5duwYAKdPn2blD99TslTpOHX+/HNnzOdlS5dwxZVXArB791/Ra5TA3r172PnHDi4vVizOeQf2/031G2/i9OlTWFD0ulRY2LlLDyLJRWuOaUjrBjfw9scL4pRVrXAFD7eqRbcXJxEV5ej/7mzmDu+JmfHT1l2MnbkiwfMBihbKS7WKV/LqyHkADJu8lO8+7cfR4yfP+7iIyIX65+ABBj77DFFRkURFOe5s0JDba9fhow/e59prK1K7bj2mTPqUlT/8QObgYHLnycNLr74BwE/rfmTs6FFkDg7GgoJ49n/Pkz//f9/M8eH779Gj9+MANLyrCY/36s7Y0aPo7veoiKSOQF1z1LtVReKhd6tKoEjJd6tWHPhNsv++3/TyHakecjWtKiIi4kfTqiIi4lmgTqsqcxQREfGjzFFERDxLK2+0SW7KHEVERPwocxQREc8CNXNUcBQREc8CNDZqWlVERMSfMkcREfEsUKdVlTmKiIj4UeYoIiKeBWjiqOAoIiLeaVpVREQkjTCzsWZ2wMw2xSoLMbNvzOw335/5feVmZkPMbLuZbTCzqom1r+AoIiKemSX/lkSfAA39yp4BFjrnygELffsAjYByvq0LMCyxxhUcRUQk3XHOLQNC/YqbAeN8n8cBzWOVj3fRVgL5zKxoQu1rzVFERDxLY2uORZxz+3yf/waK+D4XA/6KVW+3r2wf8VDmKCIinqXEtKqZdTGztbG2Lhc6LuecAzx/EbMyRxERSVOccyOBkR5O3W9mRZ1z+3zTpgd85XuAErHqFfeVxUuZo4iIeGZmyb5dhDnAA77PDwCfxyrv6LtrtQZwNNb063kpcxQRkXTHzCYDtYGCZrYbeA54HZhmZp2BP4E2vupzgbuA7cBJ4KHE2ldwFBERz1LrfhznXLt4DtU7T10HdL+Q9jWtKiIi4keZo4iIeJbGHuVINgqOIiLiWYDGRk2rioiI+FPmKCIingXqtKoyRxERET/KHEVExLMATRwVHEVExDtNq4qIiGQQyhxFRMQzZY4iIiIZhDJHERHxLEATRwVHERHxTtOqIiIiGYQyRxER8SxAE0dljiIiIv6UOYqIiGeBuuao4CgiIp4FaGzUtKqIiIg/ZY4iIuJZUICmjsocRURE/ChzFBERzwI0cVTmKCIi4k+Zo4iIeKZHOURERPwEBWZs1LSqiIiIP2WOIiLiWaBOqypzFBER8aPMUUREPAvQxFHBUUREvDMCMzpqWlVERMSPMkcREfFMj3KIiIhkEMocRUTEs0B9lEPBUUREPAvQ2KhpVREREX/KHEVExDN92bGIiEgGocxRREQ8C9DEUZmjiIiIP2WOIiLimR7lEBER8ROgsVHTqiIiIv6UOYqIiGd6lENERCSDUOYoIiKeBWbeqOAoIiIXIVDvVtW0qoiIiB9ljiIi4lmgftlxvMHRzD4AXHzHnXO9UmREIiIiqSyhzHHtJRuFiIikS4G65hhvcHTOjYu9b2Y5nHMnU35IIiKSXgRobEz8hhwzu9nMtgDbfPvXm9nQFB+ZiIhIKknK3aqDgQbAIQDn3M/AbSk5KBERSR/MLNm3tCBJj3I45/7yK4pMgbGIiIikCUl5lOMvM7sFcGaWGegNbE3ZYYmISHoQqI9yJCVz7Ap0B4oBe4HKvn0REZFUYWaPm9lmM9tkZpPNLJuZlTKzVWa23cymmlkWr+0nGhydc/845zo454o45wo55+5zzh3y2qGIiASO1FhzNLNiQC+gmnOuIpAJaAu8AbznnCsLHAY6e72upNytWtrMvjCzg2Z2wMw+N7PSXjsUEZHAYSmwJVEwkN3MgoEcwD6gLjDdd3wc0NzrdSVlWnUSMA0oClwOfAZM9tqhiIjIxXDO7QHeBnYRHRSPAj8CR5xzEb5qu4leDvQkKcExh3NugnMuwrd9CmTz2qGIiASOILNk38ysi5mtjbV1id2nmeUHmgGliE7acgINk/O6Enq3aojv4zwzewaYQvS7Vu8F5ibnIERERM5yzo0ERiZQpT7wh3PuIICZzQRqAvnMLNiXPRYH9ngdQ0KPcvxIdDA8OwX8aOyxA/29dioiIoEhlZ7Z3wXUMLMcwCmgHtHvA18MtCI6mXsA+NxrBwm9W7WU10ZFRCRjSI032jjnVpnZdGAdEAH8RHSm+RUwxcxe9pWN8dpHkr7P0cwqAhWItdbonBvvtVMREZGL4Zx7DnjOr3gHcGNytJ9ocDSz54DaRAfHuUAj4DtAwVFEJINLI69CTXZJuVu1FdHzuX875x4CrgfypuioREREUlFSplVPOeeizCzCzPIAB4ASKTwuERFJB4ICNHVMSnBca2b5gFFE38H6L/BDio5KRETShQCNjYkHR+dcN9/H4WY2H8jjnNuQssMSERFJPQm9BKBqQsecc+tSZkgiIpJepJUvJ05uCWWO7yRwzBH9gtfzOrjyA88DEkkr8jd4NbWHIJIsTi18NrWHkO4k9BKAOpdyICIikv4k5ZGH9ChQr0tERMSzJL0hR0RE5Hwy4pqjiIhIgoICMzYmPq1q0e4zs0G+/SvMLFneXSciIpIWJWXNcShwM9DOt38c+CjFRiQiIulGkCX/lhYkZVr1JudcVTP7CcA5d9jMsqTwuERERFJNUoJjuJllIvrZRsysEBCVoqMSEZF0ISPfkDMEmAUUNrNXiP6WjoEpOioREUkX0so0aHJLyrtVJ5rZj0R/bZUBzZ1zW1N8ZCIiIqkkKV92fAVwEvgidplzbldKDkxERNK+AJ1VTdK06ldErzcakA0oBfwCXJuC4xIREUk1SZlWvS72vu/bOrrFU11ERDKQjPxlx3E459aZ2U0pMRgREUlfAvUF3UlZc3wi1m4QUBXYm2IjEhERSWVJyRxzx/ocQfQa5IyUGY6IiKQnATqrmnBw9D38n9s59+QlGo+IiEiqizc4mlmwcy7CzGpeygGJiEj6kRFvyFlN9PriejObA3wGnDh70Dk3M4XHJiIikiqSsuaYDTgE1OW/5x0doOAoIpLBBWjimGBwLOy7U3UT/wXFs1yKjkpERNKFjPhu1UxALuIGxbMUHEVEJGAlFBz3OedevGQjERGRdCdQb8hJ6OUGgXnFIiIiiUgoc6x3yUYhIiLpUoAmjvEHR+dc6KUciIiIpD+BekNOoL4zVkRExLML/lYOERGRsyxAb09R5igiIuJHmaOIiHgWqGuOCo4iIuJZoAZHTauKiIj4UeYoIiKeWYA+6KjMUURExI8yRxER8UxrjiIiIhmEMkcREfEsQJccFRxFRMS7jPiVVSIiIhmSMkcREfFMN+SIiIhkEMocRUTEswBdclRwFBER74L0lVUiIiIZgzJHERHxLFCnVZU5ioiI+FHmKCIingXqoxwKjiIi4pnekCMiIpJBKHMUERHPAjRxVOYoIiLpj5nlM7PpZrbNzLaa2c1mFmJm35jZb74/83ttX8FRREQ8CzJL9i2J3gfmO+fKA9cDW4FngIXOuXLAQt++t+vyeqKIiEhqMLO8wG3AGADn3Bnn3BGgGTDOV20c0NxrHwqOIiLimVlKbNbFzNbG2rr4dVsKOAh8bGY/mdloM8sJFHHO7fPV+Rso4vW6dEOOiIh4lhIZlnNuJDAygSrBQFWgp3NulZm9j98Uqg2XKwIAACAASURBVHPOmZnzOgZljiIikt7sBnY751b59qcTHSz3m1lRAN+fB7x2oOAoIiKemVmyb4lxzv0N/GVmV/uK6gFbgDnAA76yB4DPvV6XplVFRCQ96glMNLMswA7gIaITvmlm1hn4E2jjtXEFRxER8Sy13gHgnFsPVDvPoXrJ0b6Co4iIeKZ3q4qIiGQQyhxFRMSzwMwblTmKiIicQ5mjiIh4FqBLjgqOIiLiXVKeS0yPNK0qIiLiR5mjiIh4FqgZVqBel4iIiGfKHEVExDOtOYqIiGQQyhxFRMSzwMwbFRxFROQiaFpVREQkg1DmKCIingVqhhWo1yUiIuKZMkcREfEsUNccFRxFRMSzwAyNmlYVERE5hzJHERHxLEBnVZU5ioiI+FPmKCIingUF6KqjgqOIiHimaVUREZEMQpmjiIh4ZgE6rarMUURExI8yRxER8SxQ1xwVHEVExLNAvVtV06oiIiJ+lDmKiIhngTqtqsxRRETEjzJHERHxTJmjiIhIBqHMMYmqV65A2XJXxey/M/hDLi9W/Lx1a91Ule9WrUuWfrt0up+TJ0/y6ZQZAGzZvJHB77zJyLETkqX9s+Z8PpObb65JocJFAHjxuYHc1/FBSpcpm6z9SNoTkic7c99qD0CRkJxERTkOHjkJwK3dPyY8IirZ+to2sRvHT57BAftD/+Xh179g/+ETF9TG4iEdqdNrPFcUycvN1xZj6qItAFS96jI63HEdfT/6JtnGK4kL1JcAKDgmUdas2Zj82exU6Ts0NJQVy5dR89bbUqyPLz+fRdmy5WKC46AXXk6xviRtCT12ihqPjgFgQMdbOXHqDIM/WxVzPFOQERnlkq2/hn0ncujYKV7ofDv92t9ywcGsTq/xAFx5WV7a1Ls2Jjiu+/Vv1v36d7KNU5ImKDBjo4KjVydPnuCJXt05duwYERHhdOvZh9p16sWpc/DgAfo/9QQnTvxLZEQk/Qc+R5UbqvHD998xYugHnDkTTvESJXj+pVfJkSNnvH11fLATY0YPPyc4RkZG8sHgd/hx7WrOnDlDm7btuad1W6Kionjj1ZdYs3oll11WlODgYO5u3pL6dzZk5PCPWL50MWGnw6hUuTIDBr3Iwm++ZsvmzQx85imyZsvGxxOm0KvbI/Tp248tmzez+69d9OnbD4jOMLdu3sTTzw5i7pdzmDJpAuHh4VS8rhLPDHiOTJkyJf8PWy65kf2acPpMBJXLFuGHzbs5duJMnKC5dvQjtBwwjV37j9K2/rV0b1GdzMGZWLNtL73fn09UEoLpdxv+oluLamTNnIkhfRpS9aqiRERG8fTwhSxb/yfXXFmQkf2akDk4E0FBRrvnZ/D7nsMc/PJJCjV5m5cfrsPVVxRg5YjOTFywgfXb99OnzU20GvgZWz/txk1dxnD0RBgAG8d1pV6fCURFOT7o05AShfMA8NTQb/lh8+6U+0FKuqU1xyQKCztNu9bNade6OX379CBLlqy8PfhDJk2byYgx43nv7TdwLu4vhPlzv+TmW2ox+bPZTJ4+m6vKl+fw4cOMGTmcYSM/ZtK0mVS4tiKfjv8kwb4rXV+ZzMGZWbN6ZZzyz2dNJ1fu3EyYPJ0Jk6cza8Zn7Nm9m0XfLmDf3j1Mn/0VL776Bht+Xh9zzr3tOjBh8nSmzfqCsLAwli9dTP07G1Lh2mt5+fW3mPzZbLJlyxZTv179O1m86NuY/W/mz+POho35Y8fvLJg/lzHjJjH5s9kEBWVi3ldfXMRPWNKaYoVyU7vXeJ4etjDeOldfUYBWtStQp9d4ajw6hsjIKNrWuzZJ7d9Voyyb/zhI1+Y34BxUf2Q0D7zyOaP7NSFr5kw80rQqH81cQ41Hx1DzsbHsOXg8zvkDRy9mxaa/qPHoGD6YsSam3Dn48vvfuLvW1QBUL385u/Yf5cDhE7zd/Q4+mLGaWt0/od0LMxna9y4PPxmJzVLgv7RAmWMS+U+rhoeH89GQd1n341qCgoI4eGA/hw79Q8GChWLqXHvtdbzw3AAiIsKpXbc+V5e/hh/XLmbHju10eqB9TDuVrq+caP+duzzGmJHD6fV435iyld+v4LfffmHhN18D8O/x4+zatZP1P62j/p0NCAoKomDBQlS78aaYc9auXsW4j8dw+vQpjh07SukyZbmtdt14+80fEkKx4sXZ+PN6Slx5JTv/2EHlKlWZNmUiW7dupmP71gCEnT5NSEhIEn+akh7MXLot0QywTpWSVC13Gd8NfQiA7FmDY9Yr4zP/nQ5ERjk27TjA82OXMrJfE4bOWgvAr38dYteBY5QrEcKqLbvp16EmxQrlZvbyX/h9z+Ekj3364i30v78WE77eQOs6FZi+ZGv0eKuWpPyVBWPq5cmZlZzZMnPidHiS25aMQcHRo3lzv+Dw4cN8OmUGmTNnpknDupwJC4tTp2q16oz+eALLly3l+f/1p8P9D5InTx5q1LiFV99894L6u/GmGgz7cDAbN/wcU+ac46lnBnJLzVvj1F2xfNl52wgLC+P1V15kwpTpXHZZ0eipXb8xn0+Dho35ZsE8SpYqTZ169TEznHM0ubs5PXv3TfR8SZ9OxgoYEZFRBMVaXMqWJXr63Mz4dMFGBo1ZkuR2z645Jmbqoi2s3rqXRjXKMvvVe+nx3jyWrv8zSX2s3LKHMsXyUzBvDprWvIrXJ64AICjIuL3HJ4SFRyZ5vJIwPcohcfx7/F9CQkLInDl6unPf3r3n1Nm3dw8hBQrSslUbmrdsxbatW7iuUmXWr/+Jv3ZF/5/81MmT/LnzjyT12bnLY4z7eEzM/s01azF92hTCw6N/if258w9OnTzJ9VWqsvDbBURFRXHo0D/8uGY1QEwgzJcvPydPnmDhNwti2sqRIycnTpz/rsE69eqzZPEi5s/7ijsbNgbgxptuZuE3Cwg9dAiAo0ePsG/vniRdh6Q/f+4/QuVylwFQuVwRSl6WD4DFP+2kxW3lKZQvBwD5c2fjCt96XlKt2PgXbetHT8WWLR5CicJ5+PWvUEoWzccf+44wdNZavvz+V64rXTjOef+ePEPu7FnjbXfOd7/yxmP12LbrH0J9wXjh2j/o1qJaTJ1KZQrHd7okkaZVJY5GjZvyeM+utGnZlArXVqRkqdLn1Fm7ZjUTPhlLcOZgsmfPwYuvvEH+kBCef+k1nn26L2fOnAGgW48+XFmyVKJ91rr1dvLnzx+z37xla/bu2UOHe1uCg3wh+Xln8EfUq38na1b9QKvmjbnssqKUv6YCuXLnJneePLS4pzVtWjalYMGCVKhYMaatps1a8NpLz8fckBNbnjx5KVW6NH/8/jsVr6sEQOkyZenWozfdu3YmKiqK4OBgnnl2EEUvL+bp5ylp2+xlv9Dhjuv4ccwjrNm6l992hwKw7c9/eOHjpXzxRjuCgozwiEgeH/I1uw4cS3LbIz7/kSF9GrJm1MNEREbxyJtfciY8kla3X0O7OyoSHhHF/tB/eXPS93HO27jjAJFRUawa2ZlPv46+ISe26Uu2sGJYJx5+47+18L4fLmBwrwasHvUwwZmC+G7DLnoNnn8RPxkJVOZ/E0ly+DcsBRqVC3Ly5Aly5MjJkSOH6di+DWPHT4qzHiqJK3TXa6k9BJFkcWrhsymWji37NTTZf9/fdlVIqqePyhwDVJ8eXTl+/Djh4eE8/OhjCowiIhdAwTGN6NunB3v3xH3eqmefvufcbJNUyf0GHZELsezDB8iSOe6vl86vz2HzHwdTaUSSUtLKGmFyU3BMI94Z/GFqD0Ek2dzWY1xqD0EukUC9W1XBMR14YdCzLF+6hJCQAkybFX1zwdAP32fp4oUEBQWRPySEF156LebVbyJpyfAnG9OoRlkOHjlJtYdHATDowdtoUvMq33tcT9DlzS/Zd+jfmHNuuLooSz54gI4vz2bWsm2pNXTJwPQoRzrQ9O4WfDBsVJyyjg92ZuqMOUz+bDa33labUSOGptLoRBI24esNNOsf9w7o96at5MZHRlPj0THMW7md/vfXijkWFGS8/Egdvl2741IPVTywFNjSAgXHdKBqterkzZs3TlmuXLliPp86dYq081dKJK4VG/8i9NjpOGXHT56J+ZwjW2Zi39/erXk1Zi//JdE37YikJE2rpmMfDXmPr774nFy5cjNijNZ4JH15vtPtdLjjOo6eCKNh34kAXF4wF3fXupoGfT9lxFNNUnmEkhRBAbroqMwxHeve63HmfrOEho2bMHXyp6k9HJEL8vzYpZRr9yFTFm6ia/MbAHir2x0MHLUIPSktqU3BMQA0atyURd/qC14lfZq6cDPNby0PQNWrijJ+YHO2TexGi9vKM7hXA5rWvCqRFiQ1Beqao6ZV06ldf+7kiitLArB08UJKlkr89XMiaUWZYvljvmWjyS1X8etf0e/ovea+/24sG9mvCfNWbueLFb+myhglidJKNEtmCo7pwLP9nmDt2jUcOXKYRvVv59FuPVmxfCl/7tyJBRlFi17Os/97IbWHKXJe4wY049brr6Rg3uxsn9KDl8Ytp+GNZShXogBRzrFr/1F6DZ6X2sMUiUPvVhWJh96tKoEiJd+tuur3o8n++/6mMnlTPR/VmqOIiIgfTauKiIhnAfokhzLHtCAyMpL2bVrQu8ej5xybPm0KbVo2pV3r5nR6oD07ft8OwKaNG2jXujntWjenbatmLFoYfbfq4dBQOj3QnjYtmrJ40bcx7TzRqxsHD+w/p32RixUUZPwwvBMzXmkdp/yd7ndw8Msn4z2vYulCLPmgY/R3RI56mKyZM5ErexZWjugcs/01sw9vdasPwGPNq7F29CPMerUNmYOjf3XdUrE4bz5WP+UuThKVmnermlkmM/vJzL707Zcys1Vmtt3MpppZFq/XpcwxDZg8cTwlS5XmxIl/zznW8K4mtGrTFoClixfx7luv8+Hw0ZQpW44Jk6cTHBzMwYMHaNeqObfdXof5876kVeu21Kl3B727d6FO3fosW7KIq8tfo3evSoro0bI6v+w6RO6c//0eqnrVZeTLnS3eczIFGWP7N6Pza3PYuOMAIXmyEx4ZRVh4JDUeHRNTb8Wwh5i9/BcA2ta7luqPjKJf+5rcUb00c3/YzjP31eKBV2an3MVJWtcb2Ark8e2/AbznnJtiZsOBzsAwLw0rc0xl+//+m++WLaV5y9bnPR73NXEnMd8cRvbs2QkOjv63zZmwMzHlwcGZOX36FOHhZwgKykRERASTPh1Px4ceTuErkYyoWMHcNLypLB/PXR9TFhRkvPpoPQaMXBTvefWrlWbTjgNs3HEAgNBjp4iKintfR9niIRTOl5MVG/8CoqfvMgdnIke2YMIjomhXvyILVv/O4eOnz2lfLqFUSh3NrDjQGBjt2zegLjDdV2Uc0NzrZSk4prJ33nyV3k88SVBQ/H8jpk2ZyN133cGQ997mqWcGxJRv3PAzrVs04d577qb//54nODiYhnc1YcniRXTr0olODz/KZ1MncVfTu8mePfuluBzJYN7qfgcDRi4iKtYN6o81r8ZX3//K36En4j2vXPEQnHPMeb0t3w/vxBP31jinTus6FZi+ZEvM/rDZP7L0gwcoUTgvP2zaTceGlRj++Y/Je0GSngwG+gFRvv0CwBHnXIRvfzdQzGvjCo6paNnSxeQPKcA1FSomWK9N2w7MmfsNPfv0ZfTI/2YIrqt0PZ/N+pIJkz/jkzEjCQsLI3fu3Az5aASfTplB+QoVWL50CfXvaMBLz/+Pfk/0YsPPP6X0ZUkG0ahGWQ4cPsFPv/0dU1a0QC5a3laeobPWJnhucKYgbqlYgode/Zx6vcdzd62rqF2lZJw6retUYNqi/4Lj5G83cXPXsXR6bQ49W93I0FlraXBjGSY915I3H6sfsDeGpHWWEv+ZdTGztbG2LnH6NGsCHHDOpdi/jhQcU9HP69exbMkimjSsy7P9+rJm9SoG9n8q3voNGjVmyeKF55SXKl2G7Nlz8Pv2uG8SGT1iKJ0eeZT5c7+icpWqvPDy64wYpi9VluRx87XFaXJLObZN7Mb4gc2pXbkkP455hNLF8rN5wmNsm9iNHFkzs2l813PO3fPPcb7buItDx05xKiyC+at+p0q5/9bErytdmOBMFifwnlW0QC6qlS/KFyt+pXfrm7jvpVkc+fc0daqWTMnLlXiYJf/mnBvpnKsWaxvp121N4G4z2wlMIXo69X0gn5mdvZemOLDH63XphpxU1LN3X3r27gvA2jWrmDBuLC+/9lacOrFfE/fdsiVcccWVAOzZvZsil11GcHAw+/buYefOHRS9vHic8/bv30+16jfx6y+/kDVrVjAj7HTYpbk4CXiDxixh0JglANx6/RX0aXMT9wz4LE6dg18+ScWOw88595s1O3j83hpkzxrMmfBIbq10BR/MWB1zvE3duFljnH4fuo2XPlkGQPaswTjniHKOHFkzJ9OVSVrnnOsP9Acws9rAk865Dmb2GdCK6ID5APC51z4UHNOgYR8NoUKFitxepy5TJ09k9aofCA4OJneePLzw8usArP/pRz4ZO4rg4GDMgnhmwHPkz58/po2PPhhM9559AGjYqDF9+3Tnk7Gj6NqtZ6pck0jjm8tR9eqivPTJMo78e5oh01fx3dCHcA6+Xr2d+at+j6l7z+3X0PzZaee0cX3Z6Oxy/W/RjyVNXbiZtaMfYfeBY7w7deWluRCJI43NZj8NTDGzl4GfgDGJ1I+XXh8nEg+9Pk4CRUq+Pm7dzmPJ/vu+ask8qR5zlTmKiIh3qR7GUoZuyBEREfGjzFFERDyzAE0dFRxFRMSzQH2+VNOqIiIifpQ5ioiIZwGaOCpzFBER8afMUUREvAvQ1FHBUUREPAvUu1U1rSoiIuJHmaOIiHimRzlEREQyCGWOIiLiWYAmjgqOIiJyEQI0OmpaVURExI8yRxER8UyPcoiIiGQQyhxFRMQzPcohIiKSQShzFBERzwI0cVRwFBGRixCg0VHTqiIiIn6UOYqIiGd6lENERCSDUOYoIiKeBeqjHAqOIiLiWYDGRk2rioiI+FPmKCIi3gVo6qjMUURExI8yRxER8SxQH+VQcBQREc8C9W5VTauKiIj4UeYoIiKeBWjiqMxRRETEnzJHERHxLkBTR2WOIiIifpQ5ioiIZ3qUQ0RExI8e5RAREckglDmKiIhnAZo4KnMUERHxp8xRRES8C9DUUcFRREQ8C9S7VTWtKiIi4keZo4iIeKZHOURERDIIZY4iIuJZgCaOCo4iIuKdplVFREQyCGWOIiJyEQIzdVTmKCIi4keZo4iIeKY1RxERkQxCmaOIiHgWoImjgqOIiHinaVUREZEMQsFRREQ8sxT4L9E+zUqY2WIz22Jmm82st688xMy+MbPffH/m93pdCo4iIpLeRAB9nXMVgBpAdzOrADwDLHTOlQMW+vY9UXAUERHvLAW2RDjn9jnn1vk+Hwe2AsWAZsA4X7VxQHOvl6UbckRExLPUvh/HzEoCVYBVQBHn3D7fob+BIl7bVeYoIiJpipl1MbO1sbYu8dTLBcwA+jjnjsU+5pxzgPM6BmWOIiLiWUo8yuGcGwmMTLhfy0x0YJzonJvpK95vZkWdc/vMrChwwOsYlDmKiEi6YmYGjAG2OufejXVoDvCA7/MDwOde+1DmKCIiniXl0YsUUBO4H9hoZut9Zc8CrwPTzKwz8CfQxmsHCo4iIuJdKsRG59x3CfRcLzn60LSqiIiIH2WOIiLiWWo/ypFSlDmKiIj4UeYoIiKe6Vs5REREMghljiIi4lkqPcqR4hQcRUTEM02rioiIZBAKjiIiIn4UHEVERPxozVFERDwL1DVHBUcREfEsUO9W1bSqiIiIH2WOIiLiWaBOqypzFBER8aPMUUREPAvQxFHBUURELkKARkdNq4qIiPhR5igiIp7pUQ4REZEMQpmjiIh4pkc5REREMghljiIi4lmAJo4KjiIichECNDpqWlVERMSPMkcREfFMj3KIiIhkEMocRUTEs0B9lMOcc6k9BhERkTRF06oiIiJ+FBxFRET8KDiKiIj4UXCUNMXMIs1svZltMrPPzCzHRbT1iZm18n0ebWYVEqhb28xu8dDHTjMrmNRyvzr/XmBfz5vZkxc6RhG5cAqOktaccs5Vds5VBM4AXWMfNDNPd1g75x52zm1JoEpt4IKDo4gEJgVHScuWA2V9Wd1yM5sDbDGzTGb2lpmtMbMNZvYogEX70Mx+MbNvgcJnGzKzJWZWzfe5oZmtM7OfzWyhmZUkOgg/7stabzWzQmY2w9fHGjOr6Tu3gJktMLPNZjaaJLw8y8xmm9mPvnO6+B17z1e+0MwK+crKmNl83znLzax8cvwwRSTp9JyjpEm+DLERMN9XVBWo6Jz7wxdgjjrnqptZVmCFmS0AqgBXAxWAIsAWYKxfu4WAUcBtvrZCnHOhZjYc+Nc597av3iTgPefcd2Z2BfA1cA3wHPCdc+5FM2sMdE7C5XTy9ZEdWGNmM5xzh4CcwFrn3ONmNsjXdg9gJNDVOfebmd0EDAXqevgxiohHCo6S1mQ3s/W+z8uBMURPd652zv3hK78TqHR2PRHIC5QDbgMmO+cigb1mtug87dcAlp1tyzkXGs846gMV7L8nnPOYWS5fHy19535lZoeTcE29zKyF73MJ31gPAVHAVF/5p8BMXx+3AJ/F6jtrEvoQkWSk4ChpzSnnXOXYBb4gcSJ2EdDTOfe1X727knEcQUAN59zp84wlycysNtGB9mbn3EkzWwJki6e68/V7xP9nICKXltYcJT36GnjMzDIDmNlVZpYTWAbc61uTLArUOc+5K4HbzKyU79wQX/lxIHeseguAnmd3zOxssFoGtPeVNQLyJzLWvMBhX2AsT3TmelYQcDb7bU/0dO0x4A8za+3rw8zs+kT6EJFkpuAo6dFootcT15nZJmAE0bMgs4DffMfGAz/4n+icOwh0IXoK82f+m9b8Amhx9oYcoBdQzXfDzxb+u2v2BaKD62aip1d3JTLW+UCwmW0FXic6OJ91ArjRdw11gRd95R2Azr7xbQaaJeFnIiLJSO9WFRER8aPMUURExI+Co4iIiB8FRxERET8KjiIiIn4UHEVERPwoOIqIiPhRcBQREfGj4CgiIuJHwVFERMSPgqOIiIgfBUcRERE/Co4iIiJ+FBxFRET8KDiKiIj4UXCUVGdmzc3M+b4MON0zsxvMbKOZbTezIWZm56mT38xm+b4vcrWZVfSVlzCzxWa2xcw2m1nvWOe85Ku/3swWmNnll/K6RDISBUdJC9oB3/n+TBFmliml2j6PYcAjQDnf1vA8dZ4F1jvnKgEdgfd95RFAX+dcBaAG0N3MKviOveWcq+Scqwx8CQxKwWsQydAUHCVVmVkuoBbQGWjrK8tkZm+b2SZfptTTV17dzL43s5992VZuM3vQzD6M1d6XZlbb9/lfM3vHzH4GbjazQWa2xtfuyLMZnZmVNbNvfe2uM7MyZjbezJrHaneimTVLwvUUBfI451a66G8SHw80P0/VCsAiAOfcNqCkmRVxzu1zzq3zlR8HtgLFfPvHYp2fE9A3lYukkODUHoBkeM2A+c65X83skJndANwIlAQqO+cizCzEzLIAU4F7nXNrzCwPcCqRtnMCq5xzfQHMbItz7kXf5wlAE+ALYCLwunNulpllI/ofjWOAx4HZZpYXuAV4wMyu9o3jfGoTHch2xyrb7Svz9zPQElhuZjcCVwLFgf1nK5hZSaAKsCpW2StEZ5pHgTqJXL+IeKTMUVJbO2CK7/MU3359YIRzLgLAORcKXA3sc86t8ZUdO3s8AZHAjFj7dcxslZltBOoC15pZbqCYc26Wr93TzrmTzrmlQDkzK+Qb0wznXIRz7hfnXOV4tiMXcN2vA/nMbD3QE/jJN14gJqOeAfSJnTE65wY450oQHdB7XEB/InIBlDlKqjGzEKKD1HVm5oBMRE8VrrmAZiKI+4+8bLE+n3bORfr6ygYMBao55/4ys+f96p7PeOA+oqd7H/K1k1jmuIfoDPCs4r6yOHwB72ybBvwB7PDtZyY6ME50zs2Mp6+JwFzguUSuQUQ8UOYoqakVMME5d6VzrqQvI/qD6CnHR80sGGKC6C9AUTOr7ivL7Tu+E6hsZkFmVoLoKdnzORsI//FlZa0gZl1v99n1RTPLamY5fHU/Afr46m3x/Zlg5uic2wccM7MavqDXEfjcfzBmls83VQzwMLDMOXfMd84YYKtz7l2/c8rF2m0GbEvohysi3ik4SmpqB8zyK5sBFAV2ARt8N9O0d86dAe4FPvCVfUN0wFtBdEDdAgwB1p2vI9+U5yhgE/A1cbPT+4FeZrYB+B64zHfOfqJviPn4Aq+rGzAa2A78DswDMLOuZtbVV+caYJOZ/QI0As4+slHTN566vkc21pvZXf9v785j7CrrMI5/H0GgUKBYoBJEUVAbLKVsBYmVrRSMCjRxCQIqUAQUW1KrEI1hSYhlMSoqAcJWDBKoUi2kUpa0UISylNKFNoDaEklUkEJhSqkWfv7x/m45HO/M3PZOZ6bp80lu7r3nnuU9k0x+ec857/Pmb5MbDykBYyrbmFkPU3mgzszqsge5CDggIlb2dXvMrPe452jWhKTRlF7jL10YzTY/7jmamZnVuOdoZmZW4+JofUrS2/nQyWJJUytPirazz0vysmhnv58t6evtHqeL/beTrbpNfl+Q2aoXV7Y5N/cZknbeWO03M19WtT4mqSMiBubnW4F51SEMkrZsYbB/vyLpcWA8JdlmBnBVRPypts4VQEdEXKwSuP7riDg6C+l2EdGR4x0fBiZExFxJ+wOvArMp4zX/3YunZbZZcc/R+pM5wN6SjpA0R9J0YIlK1uoVmYu6UNJZjQ0knZ+9tAWSJueymyV9KT9PVpnhYqGkK3PZRZIm5ecRkubm79Mk7ZTLZ0u6LHtxz0ka1coJqP1s1YiIjlzn/fmKXG9+RCxfnz+oOUKqegAAB71JREFUmW0YJ+RYv5AD+j8H3JOLDgCGRcQySd8CVkbEwZK2Bv4s6V5gKGUw/CER8WaGBVT3ORgYCwyNiJA0qMmhbwG+GxEPSrqEkjhzXv62ZUSMzHGGFwKjW0jIaTtbVWUGkXnA3pQe5WNNtjezjcjF0fragMwXhdJzvIES8v14RCzL5WOA4Y3eILAjZSqo0cBNEfEmrMtgrVoJvAXcIOluyjRP66gEig/KHFWAKcDUyiqN6LZ5lCB0IuJZYERnJ9Pk9mJnJgO/yHNfRCVbNSPvRmQxnyZpWEQsbnXHZtY+F0fra6tzfsJ1ssCsqi6i9O5m1tY7tqsd54weI4GjKXFx51KyXFu1Jt/fJv9XWug5tp2tWlnnNUmzKPNBujia9SLfc7RNwUzgnHxABUmfkLQdJULutMYTrk0uqw4EdoyIGZTpp/ar/p6D+1+t3E88FXiQLvRCtuoujcu/kgYAx+AMVbNe556jbQqup1zWfCoLzsvAiRFxj6QRwJOS/kN5MvSHle22B/6oMiOHgIlN9v0N4JossH8je3Nt+jYltHwAJVd1XbYqQERcQ8lWnaIyG8kzlMmeoeTKTsn7ju8D7oiIu3P78cAPKNmvCyXNiIhxPdBeM6vxUA4zM7MaX1Y1MzOrcXE0MzOrcXG0fkvvjZa7q5Nxiu3sf3kjhk1SR3frV7b7qKTHMsrt9sqDNdV1tpJ0UyWg4IjKb5dK+nv9mJImVgILHpD0kTZOz8za4OJo/dnqfAp0GLAC+E5fNyhdBvwsIvamxLmd0WSdMwEiYl/KE6c/ldT4f7sLGNlkm/mUWLjhwO+Ay3u64WbWGhdH21Q8SibNSNpL0j2S5mXM3NBcPiQj4Bbk67Bc/odc95lM29lg+bTsUZTiBSU4oLt4uJeA14CD8vvcHPLxHhExqxFoAMzlveMlzawXeSiH9Xs5rOFoSnoOwHXA2RHxvKRDgKspBesq4MGIGJvbDMz1T4+IFTlu8AlJv4+IVzo51vaUpJ5mvga8BLxWCUPvKh7ueEm3AXsAB+b74y2e9hnkEBAz630ujtafNaLldgeWAvflwP7DgKmVqLat8/0oyqD7RgTbylw+XtLY/LwHJXquaXGMiDfoOh6u1amibqSMZXwSeAF4hIyH646kUyi9zMNbPJaZ9TAXR+vPVkfEiBygP5Nyz/FmSs+t0wJWlQ/CjAY+neHks4Ftuli/u57jUmCQ3p1Kq7N4uLWUVJ7Gfh8BnmuhvaOBHwGHR8Sa7tY3s43D9xyt38v7cOOB7wFvAsskfRnKPUBJjVi4B4BzcvkWGSy+I/BqFsahwKHdHOuNLuLhluQ0VLMoWa1QEnaaxcNtmxF3SDoGWBsRS7o6tsp8jdcCx+d9SjPrIy6OtkmIiPnAQuAk4GTgDEkLKNFrJ+RqE4AjJS2izKSxD2UKrC0lLaXMhDG3B5pzPjBR0l+AweS9UEnHq0x7BbArJe5uaa5/amNjSZdLehHYVtKLki7Kn66g3CedmkNYpvdAW81sAzg+zszMrMY9RzMzsxoXRzMzsxoXRzMzsxoXR+tzlQzVxmtPSYMlzZLUIelXXWz7BUnzMxFniaSzerPtTdrzAUn3SXo+33fqZL3LMjN2saSvVpbfKunZXH6j3p3geaikRyWtkTSpt87HbHPl4mj9werakInlwFvAj4FOC0EWjuuAL0bEfsD+wOx2GpJDQ9r5v7gAeCAiPk4ZWnJBk2N8HjiAEjZwCDBJ0g75863AUGBfymTJjcmMV1CGs1zZRtvMrEUujtYvRcSqiHiYUiQ7sz0lyOKV3GZNRDwLXeasTqz02M7LZXtmb+0WYDGwh6TvS3oiZ8i4eD2afgIlbxW6zl19KCLWRsQqyhCV4/IcZkSiRM19KJe/FBFPAP9dj7aY2QZycbT+YEDlkuq0VjeKiBXAdOAFSbdJOrnS62vkrO5H6aU9I+lA4DRKb+1Q4MwceA8lUu7qiPgU8Mn8PpLSuztQ0mcBMuj86Sav0bmfIZVQ8X8CQ5o0fQFwXAYF7AwcSYm1Wyd7xadSxmmaWS9zfJz1B6tbjYOri4hxkvalRMRNokwP9U2a5KxK+gwwLXtrSLoTGEUW2IhoBASMydf8/D6QUiwfiohR69G2kPR/A4kj4l5JB1PyVl+mzDhSz129Oo/XWZSdmW1ELo62yYuIRcAiSb8BllGK4/paVfks4CcRcW19JUlzKJdz6yZFxP3AvyTtFhH/kLQbZRaPZm2+FLg09/lbKrmrki4EdgH69OEis82ZL6vaJkvSwAwWbxhBmQEDmueszgFOrOSejqV5yPhM4HSVGUCQtLukXQEiYlQnuav357bTKXmr0Hnu6haSBufn4cBw4N78Pg44FjgpIt7ZgD+LmfUAx8dZn5PUEREDmyxfDuwAbEWZLHhMNbxbZQaN24G9gNWU3t+EiHhS0hDKk6wfo1yyPCciHpU0ETg9d3F9RPxc0p7A3RExrLLvCbz7pGgHcEpE/LWFcxkM3AF8mFKov5JzSR5EmYNynKRtgKdyk9dz+dO5/drc7o38/c6IuETSBynTX+0AvJNt2iciXu+uTWa2/lwczczManxZ1czMrMbF0czMrMbF0czMrMbF0czMrMbF0czMrMbF0czMrMbF0czMrMbF0czMrOZ/mTVxR8MNrhEAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL", + "outputId": "c971d5d4-56b4-4945-ce9e-d5175b721e6a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 101 + } + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 20,\n", + " 'min_samples_split': 70}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 115 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q", + "outputId": "2c5d1f1e-ef01-4734-debf-2a8aa1598616", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 101 + } + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': 'entropy',\n", + " 'max_depth': None,\n", + " 'max_leaf_nodes': None,\n", + " 'min_samples_leaf': 60,\n", + " 'min_samples_split': 2}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 116 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFoK1ZGrRHf3", + "outputId": "78b2d27c-0831-419b-cdd0-f7d43bf5c72b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT3, X_treinamento_DT, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 89.29\n", + "std médio das Acurácias calculadas pelo CV: 2.73\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_teste_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae", + "outputId": "e2e56b21-9412-4c85-f713-c9ebcd1eb8c9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_DT)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9333333333333333" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 119 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier) quanto para Regressão (RandomForestRegressor);\n", + "* Os nós da árvore são criados a partir das variáveis do dataframe;\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * Apresenta bons resultados em diversos tipos de problema;\n", + " * Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Ensemble é a combinação de diferentes modelos preditivos;\n", + " * Torna os algoritmos/resultados mais robustos e complexos, levando a um maior custo computacional que costuma ser acompanhando de melhores resultados.\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como **Feature Selection**, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer dados normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo;\n", + "\n", + "* **Desvantagens**\n", + " * **Recomenda-se balancear o dataframe previamente**.\n", + "\n", + "* **Principais Hiperparâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais hiperparâmetros do Random Forest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMQt5wiw1tt8" + }, + "source": [ + "### Como funciona?\n", + "\n", + "O algoritmo possui 4 passos:\n", + "1. Seleção aleatória de algumas features;\n", + "2. Seleção da feature mais adequada para a posição de nó raiz;\n", + "3. Geração dos nós filhos\n", + "4. Repete os passos acima até que se atinja a quantidade de árvores desejada.\n", + "\n", + "**Observação**: Depois que o modelo é gerado, as previsões são feitas a partir de “votações” das várias árvores. A decisão mais votada é a resposta do algoritmo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VLGqtjs42zkN" + }, + "source": [ + "![DecisionTree](https://github.com/MathMachado/Materials/blob/master/DecisionTree.PNG?raw=true)\n", + "\n", + "Fonte: [Um tutorial completo sobre modelagem baseada em árvores de decisão (códigos R e Python)](https://www.vooo.pro/insights/um-tutorial-completo-sobre-a-modelagem-baseada-em-tree-arvore-do-zero-em-r-python/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HaUjVgEd2rzU" + }, + "source": [ + "![](![image.png](data:image/png;base64,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))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r0s2vixBzFAR" + }, + "source": [ + "### Principais hiperparâmetros\n", + "* " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu", + "outputId": "09ec89b8-4cd3-4773-9b3f-bae1c49d51a6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 151 + } + }, + "source": [ + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia...\n", + "ml_RF = RandomForestClassifier(n_estimators = 100, min_samples_split = 2, max_features = \"auto\", random_state = i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=100,\n", + " n_jobs=None, oob_score=False, random_state=20111974,\n", + " verbose=0, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 120 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "E25BIxM0RTzs", + "outputId": "7827d97f-c63b-4b02-af65-1dcac773b83d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 96.28999999999999\n", + "std médio das Acurácias calculadas pelo CV: 2.94\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85", + "outputId": "b3393d84-e6a6-47f7-93a8-61a3cc8bdb8f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 50 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.98571429 0.95714286 0.92857143 1.\n", + " 0.97142857 0.98571429 0.94285714 0.97142857]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw", + "outputId": "40c83739-5055-4d1a-8e8a-5abce6de6cc8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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UUREJIAyRxER8SxYH+VQcBQREc+CdbWqhlVFREQCKHMUERHPgjRxVOYoIiISSJmjiIh4F6SpozJHERGRAMocRUTEs2B9lEOZo4iIeGaW/K9zt2nFzWyema0xs9Vm9rC/PJ+ZfW9mf/n/mdfrfSk4iohIehMFPOacqwjUBB40s4pAf2COc64sMMf/2RMFRxER8cxS4HUuzrldzrkV/vdHgLVAUaA5MMp/2iighdf7UnAUEZE0xcy6m9myOK/uiZxbArgKWAwUds7t8h/aDRT22gctyBEREe9SYD2Oc244MPycTZvlAL4E+jjnDlucCUvnnDMz57UPCo4iIuJZaq1WNbNwfIFxrHNusr94j5kVcc7tMrMiwF6v9WtYVURE0hXzpYgfA2udc4PjHJoCdPW/7wp847UNZY4iIuJZKn0rR22gC7DKzH71lz0JvApMNLNuwFagndcGFBxFRCRdcc4tIOHZzobJ0YaCo4iIeBac++MoOIqIyAXQlx2LiIhkEMocRUTkAgRn6qjMUUREJIAyRxER8UxzjiIiIhmEMkcREfEsSBNHBUcREfFOw6oiIiIZhDJHERHxLLW+lSOlKXMUEREJoMxRRES8C87EUcFRRES8C9LYqGFVERGRQMocRUTEMz3KISIikkEocxQREc+C9VEOBUcREfEuOGOjhlVFREQCKXMUERHPgjRxVOYoIiISSJmjiIh4pkc5REREMghljiIi4pke5RAREQmgYVUREZEMQsFRREQkgIKjiIhIAM05ioiIZ8E656jgKCIingXralUNq4qIiARQ5igiIp4F67CqMkcREZEAyhxFRMSzIE0cFRxFROQCBGl01LCqiIhIAGWOIiLimR7lEBERySCUOYqIiGd6lENERCSDUOYoIiKeBWniqOAoIiIXIEijo4ZVRUREAihzFBERz/Qoh4iISAahzFFERDwL1kc5zDmX2n0QERFJUzSsKiIiEkDBUUREJICCo4iISAAFR0lTzCzazH41sz/M7Aszy3YBdX1qZm3870eYWcVEzq1nZrU8tLHFzAoktTzgnKPn2dazZtb3fPsoIudPwVHSmuPOuWrOucrAKaBH3INm5mmFtXPuXufcmkROqQecd3AUkeCk4Chp2U9AGX9W95OZTQHWmFmomb1uZkvN7Hczux/AfN4zs/VmNhsodLoiM/vBzGr43zc2sxVm9puZ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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de Hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_RF= {'bootstrap': [True, False]} #,\n", + "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n", + "# 'max_features': ['auto', 'sqrt'],\n", + "# 'min_samples_leaf': [1, 2, 4],\n", + "# 'min_samples_split': [2, 5, 10],\n", + "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat", + "outputId": "1cb740d8-20c4-4255-d2f1-5303efb546ee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_hiperparametros_RF, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 2 candidates, totalling 20 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 0.3s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 0.6s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.4s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 2.0s\n", + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 2.9s remaining: 0.0s\n", + "[Parallel(n_jobs=-1)]: Done 20 out of 20 | elapsed: 2.9s finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "Parametros otimizados: {'bootstrap': False}\n", + "\n", + "RandomForestClassifier *********************************************************************************************************\n" + ], + "name": "stdout" + }, + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Invoca a função\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mml_RF2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbest_params\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mGridSearchOptimizer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mml_RF\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'ml_RF2'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md_parametros_RF\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mi_CV\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mGridSearchOptimizer\u001b[0;34m(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, cv)\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'\\nRandomForestClassifier *********************************************************************************************************'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\u001b[0m ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n\u001b[0;32m---> 24\u001b[0;31m \u001b[0mmax_depth\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_depth'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 25\u001b[0m \u001b[0mmax_features\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'max_features'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0mmin_samples_leaf\u001b[0m\u001b[0;34m=\u001b[0m \u001b[0mml_GridSearchCV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_params_\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'min_samples_leaf'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'max_depth'" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMJcAdLlTQa0" + }, + "source": [ + "## Visualizar o resultado\n", + "> Implementar a visualização do RandomForest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "X_treinamento_RF, X_teste_RF = seleciona_colunas_relevantes(ml_RF2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF2.fit(X_treinamento_RF, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF2, X_treinamento_RF, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "flyxvhIA1B8l" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF2.predict(X_teste_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos hiperparâmetros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "navUWMwHi44D" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name=\"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting vc Stacking\n", + "### **Bagging**\n", + "* Objetivo é reduzir a variância;\n", + "\n", + "#### Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_treinamento;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n", + "\n", + "#### Vantagens\n", + "* Reduz overfitting;\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "___ \n", + "### **Boosting**\n", + "* Objetivo é melhorar acurácia;\n", + "\n", + "#### Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_treinamento;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_treinamento e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_treinamento a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n", + "\n", + "#### Vantagens\n", + "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + "* Lida automaticamente com Missing Values;\n", + "\n", + "#### Desvantagem\n", + "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + "* Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9fgUrkmPk4dr" + }, + "source": [ + "___\n", + "# STACKING\n", + "\n", + "![Stacking](https://github.com/MathMachado/Materials/blob/master/Stacking.png?raw=true)\n", + "\n", + "Kd a referência desta figura???" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "B0jxx3ETpOdm" + }, + "source": [ + "___\n", + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Quando nada funciona, AdaBoost funciona!\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## O que é AdaBoost (Adaptive Boosting)?\n", + "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n", + "\n", + "## Hiperparâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "No exemplo a seguir, vou usar RandomForestClassifier com os hiperparâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Hiperparâmetros otimizados!\n", + "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)\n", + "# Instancia AdaBoostClassifier\n", + "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n", + "\n", + "# Treina...\n", + "ml_AB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tBOuTywWRm91" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_AB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os hiperparâmetros otimizados...\n", + "y_pred = ml_AB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_hiperparametros_AB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos hiperparâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB = GradientBoostingClassifier(n_estimators = 100, min_samples_split = 2)\n", + "\n", + "# Treina... \n", + "ml_GB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PKOG1ugSRvLM" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os hiperparâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_treinamento.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_hiperparametros_GB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Hiperparâmetros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_treinamento_GB, X_teste_GB = seleciona_colunas_relevantes(ml_GB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_treinamento_GB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB2, X_treinamento_GB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_teste_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Hiperparâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os hiperparâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB= XGBClassifier(silent=False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S77LljiQR_16" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos hiperparâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de Hiperparâmetros para XGBoost:\n", + "d_hiperparametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_hiperparametros_XGB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Hiperparâmetros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_treinamento_XGB, X_teste_XGB= seleciona_colunas_relevantes(ml_XGB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_treinamento_XGB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB2, X_treinamento_XGB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_teste_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM\n", + "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_treinamento, y_treinamento, top_n=X_treinamento.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3Uf1RML7xETY" + }, + "source": [ + "# WOE e IV\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TBNRfYZCyhMP" + }, + "source": [ + "## Construção do exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gIIroyyP4ZRZ" + }, + "source": [ + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PzQQdrkf1ohX" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n", + "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n", + "df_X2['target']= df_y['target']\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v-OpwIpx4hXJ" + }, + "source": [ + "df_X2['target'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yZfqSvbKzeJ3" + }, + "source": [ + "def Constroi_Buckets(df, i, k= 10):\n", + " coluna= 'v'+ str(i)\n", + " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n", + " df= df.drop(columns= [coluna], axis= 1)\n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "V6Nrpsx60HD3" + }, + "source": [ + "for i in np.arange(1,19):\n", + " df_X2= Constroi_Buckets(df_X2, i)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J2Fbh41-03OB" + }, + "source": [ + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "O9r5BeWVxIr3" + }, + "source": [ + "# Função para calcular WOE e IV\n", + "def calculate_woe_iv(dataset, feature, target):\n", + "\n", + " def codethem(IV):\n", + " if IV < 0.02: return 'Useless'\n", + " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n", + " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n", + " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n", + " elif IV >= 0.5: return 'Suspicious'\n", + " else: return 'None'\n", + "\n", + " lst = []\n", + " for i in range(dataset[feature].nunique()):\n", + " val = list(dataset[feature].unique())[i]\n", + " lst.append({\n", + " 'Value': val,\n", + " 'All': dataset[dataset[feature] == val].count()[feature],\n", + " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n", + " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n", + " })\n", + " \n", + " dset = pd.DataFrame(lst)\n", + " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n", + " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n", + " dset['Mean']= dset['All']/dset['All'].sum()\n", + " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n", + " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n", + " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n", + " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n", + "\n", + " dset['Predictive_Power']= dset['IV'].map(codethem)\n", + " iv = dset['IV'].sum() \n", + " dset = dset.sort_values(by='IV') \n", + " return dset, iv" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y8WGjWH63nx_" + }, + "source": [ + "df_Lab = df_X2.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-N6xr1MgxTiz" + }, + "source": [ + "def calcula_Predictive_Power(df_Lab, coluna):\n", + " print('WoE and IV for column: {}'.format(coluna))\n", + " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n", + " print(df)\n", + " print('IV score: {:.2f}'.format(iv))\n", + " print('\\n')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ayqN_7WnxVq9" + }, + "source": [ + "for i in np.arange(1,19):\n", + " coluna= 'v'+str(i)+'_Bucket'\n", + " calcula_Predictive_Power(df_Lab, coluna)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aZUNOgmSgAmq" + }, + "source": [ + "!pip install featuretools" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_sxdONzsh9rb" + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p5_ynGo1dBJJ" + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TqJRJXUhiDqf" + }, + "source": [ + "from random import choices\n", + "\n", + "df_X2= df_X.copy()\n", + "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n", + "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n", + "df_X2['id'] = range(0,1000)\n", + "df_X2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nR56bGGngk-W" + }, + "source": [ + "# Automated feature engineering\n", + "import featuretools as ft\n", + "import featuretools.variable_types as vtypes\n", + "\n", + "es= ft.EntitySet(id = 'simulacao')\n", + "\n", + "# adding a dataframe \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n", + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IOJ4Tr5Ogk6M" + }, + "source": [ + "es['df_X2'].variables" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1uXPqHDZgkys" + }, + "source": [ + "variable_types = {'idade': vtypes.Categorical}\n", + " \n", + "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n", + "\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n", + "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dnbYTBqugkvm" + }, + "source": [ + "es" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I2v_jetdgkr7" + }, + "source": [ + "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZiRBvHXgkoJ" + }, + "source": [ + "feature_matrix.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JYVM3StS-g0E" + }, + "source": [ + "### Importar as libraries necessárias" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dyliPChh-jPk" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os hiperparâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lAl9ZwP_0-d0" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv'\n", + "df_cc = pd.read_csv(url)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w6lN8FjJ12VU" + }, + "source": [ + "df_cc.head(10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M47GS1cK2NdD" + }, + "source": [ + "df_cc.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "b2QBZFbR3W_q" + }, + "source": [ + "df_cc['Class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pzjW3Bf_3h7J" + }, + "source": [ + "56/12842" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9bWDX9H12k5g" + }, + "source": [ + "### Drop NaN" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "27ob8tRR21TB" + }, + "source": [ + "df_cc.isna().sum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X9k16WLI49JI" + }, + "source": [ + "df_cc2 = df_cc.copy()\n", + "df_cc2 = df_cc.dropna()\n", + "df_cc2.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OY-DYRKg34ZX" + }, + "source": [ + "### Definir as variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KVhHgV_s3_5f" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbqrF4Q2nBq" + }, + "source": [ + "### Define amostras de treinamento e teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N8CUAiA57OhS" + }, + "source": [ + "df_cc.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LZjNUDNb7s1t" + }, + "source": [ + "# Definição do dataframe contendo as variáveis preditoras:\n", + "df_X = df_cc2.copy()\n", + "df_X.drop(columns= ['Class'], axis = 1, inplace = True)\n", + "df_X.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "d3DDsN2V7IOU" + }, + "source": [ + "df_y = df_cc2['Class'] # Variável-resposta\n", + "df_y.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aMthdXHD8vnh" + }, + "source": [ + "df_y.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EiJRftpZ2103" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TmSkPzNt8O6I" + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9h1PjPKh8Xb1" + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NbCN_puI2qk1" + }, + "source": [ + "### Ajusta o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hjRwSI079ADn" + }, + "source": [ + "# Importar o classificador (modelo, algoritmo, ...)\n", + "from sklearn.tree import DecisionTreeClassifier # Este é o nosso classificador" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HuhKJOQA22bR" + }, + "source": [ + "ml_DT = DecisionTreeClassifier(max_depth = 5, min_samples_split = 2, random_state = i_Seed)\n", + "ml_DT" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zai1d6eM93VQ" + }, + "source": [ + "# Treinar o algoritmo/classificador: fit(df)\n", + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ybbS4zHn-8BO" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT, X_treinamento, y_treinamento, cv = i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "r_NLku7q_YT9" + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bCRgHxUu2s7c" + }, + "source": [ + "### Cross-Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2wMWm-p5229A" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Am_UELOg2vDh" + }, + "source": [ + "### Fine tuning dos Hiperparâmetros" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lF9mxe7y23hr" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bG31I7_n4RQg" + }, + "source": [ + "### Aplicar as transformações (principais) estudadas e reestimar o modelo novamente\n", + "* Qual o impacto das transformações?\n", + "* A conclusão muda/mudou?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_00__Machine_Learning_hs6.ipynb b/Notebooks/NB15_00__Machine_Learning_hs6.ipynb new file mode 100644 index 000000000..a63d6f900 --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning_hs6.ipynb @@ -0,0 +1,4996 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "colab": { + "name": "NB15_00__Machine_Learning.ipynb", + "provenance": [], + "include_colab_link": true + }, + "accelerator": "TPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e-VOopTKxrMs" + }, + "source": [ + "A seguir, sugestão de problemas para resolver com Regressão Linear\n", + "* https://lionbridge.ai/datasets/10-open-datasets-for-linear-regression/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTAGmmHouqQd" + }, + "source": [ + "#!pip install azureml\n", + "#!pip install azureml-opendatasets\n", + "#!pip install azureml-dataset-runtime" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "74DHjOrSuOwd" + }, + "source": [ + "#from azureml import Datasets" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uIMB3a9EuQ9h" + }, + "source": [ + "#from azureml.core import Dataset\n", + "#from azureml.opendatasets import NycTlcYellow, NycTlcGreen\n", + "#from dateutil import parser\n", + "#from datetime import datetime\n", + "#from dateutil.relativedelta import relativedelta" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oV-ETadXvsuG" + }, + "source": [ + "#end_date = parser.parse('2018-06-06')\n", + "#start_date = parser.parse('2018-05-01')\n", + "#nyc_tlc = NycTlcYellow(start_date=start_date, end_date=end_date)\n", + "#nyc_tlc_df = nyc_tlc.to_pandas_dataframe() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-zwPxoLxVgp" + }, + "source": [ + "Link: https://docs.microsoft.com/pt-pt/azure/machine-learning/tutorial-auto-train-models" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tUwpNHtbwn41" + }, + "source": [ + "#nyc_tlc_df.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oflehhy7wtde" + }, + "source": [ + "#nyc_tlc_df.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "C1-G9EajxFbJ" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "* Abordar o impacto do desbalanceamento da amostra;\n", + "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n", + "* Conceitos estatísticos de bias & variance;\n", + "* Ver Sklearn.optimize: https://web.telegram.org/#/im?p=g497957288;\n", + "* Construir a package para conter todas as funções definidas e colocar estas funções na package --> Manutenção rápida, fácil e centralizada! Desta forma, o tópico (\"Funções usadas neste tutorial\") vai totalmente para o package." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YvhLC_uf4_G" + }, + "source": [ + "___\n", + "# **AGENDA**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n", + "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n", + "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n", + "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n", + "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n", + "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n", + "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO**\n", + "\n", + "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n", + "\n", + "\n", + ">O foco deste capítulo será:\n", + "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n", + "* Entender como resolver problemas de classificação e Regressão;\n", + "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n", + "* Como medir a acurácia dos modelos de Machine Learning;\n", + "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "___\n", + "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n", + "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n", + "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P961GcguXFFA" + }, + "source": [ + "![EvolutionOfAI](https://github.com/MathMachado/Materials/blob/master/Evolution%20of%20AI.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://github.com/MathMachado/P4ML/blob/DS_Python/Material/Evolution%20of%20AI.PNG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkqGtO88ZkPr" + }, + "source": [ + "![AI_vs_ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/AI_vs_ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xesQpzfmaqj6" + }, + "source": [ + "![ML_vs_DL](https://github.com/MathMachado/Materials/blob/master/ML_vs_DL.PNG?raw=true)\n", + "\n", + "Source: [Artificial Intelligence vs. Machine Learning vs. Deep Learning](https://towardsdatascience.com/artificial-intelligence-vs-machine-learning-vs-deep-learning-2210ba8cc4ac)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KeIVR59IIS7f" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING - TECHNIQUES**\n", + "\n", + "* Supervised Learning\n", + "* Unsupervised Learning\n", + "\n", + "![MachineLearning](https://github.com/MathMachado/Materials/blob/master/MachineLearningTechniques.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rvwp5UHdBiup" + }, + "source": [ + "___\n", + "# **NOSSO FOCO AQUI SERÁ...**\n", + "\n", + "![ClassicalML](https://github.com/MathMachado/Materials/blob/master/ClassicalML.jpg?raw=true)\n", + "\n", + "Source: [Machine Learning for Everyone](https://vas3k.com/blog/machine_learning/?source=post_page-----885aa35db58b----------------------)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBLSvJTXHBjK" + }, + "source": [ + "___\n", + "# **CHEETSHEET**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZdjR3nahUuKq" + }, + "source": [ + "\n", + "![Scikit-Learn](https://github.com/MathMachado/Materials/blob/master/scikit-learn-1.png?raw=true)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XRukccWQSklx" + }, + "source": [ + "## Medidas para avaliarmos a variabilidade presente nos dados\n", + "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n", + "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n", + "\n", + "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yBR8tWV_lhQq" + }, + "source": [ + "___\n", + "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n", + "* Métodos\n", + " * **Bagging** (Bootstrap AGGregatING)\n", + " * **Boosting**\n", + " * Stacking --> Não é muito utilizado\n", + "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n", + "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n", + "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n", + " * ruído;\n", + " * bias (viés);\n", + " * variância --> Principal medida para medir a variabilidade presente nos dados.\n", + "\n", + "# Referências\n", + "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25RW8u-Sj780" + }, + "source": [ + "### Leitura Adicional\n", + "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n", + "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n", + "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n", + "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n", + "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FugME1HSl4jJ" + }, + "source": [ + "___\n", + "# **PARAMETER TUNNING** (= Hiperparâmetros ótimos dos modelos de Machine Learning)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_147cIRl9F1" + }, + "source": [ + "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos hiperparâmetros dos modelos de ML)\n", + "* Encontra os hiperparâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n", + "* Necessita dos seguintes inputs:\n", + " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n", + " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n", + " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n", + " * Um dicionário com os hiperparâmetros a serem otimizados;\n", + " * O número de folds para o método de Cross-validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "39Sg77fbTWCO" + }, + "source": [ + "___\n", + "# **MODEL SELECTION & EVALUATION**\n", + "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n", + ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n", + "\n", + "* Leitura Adicional\n", + " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n", + " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oQQVzZ2ZTYrB" + }, + "source": [ + "## Confusion Matrix\n", + "* Termos associados à Confusion Matrix:\n", + " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n", + " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n", + " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n", + " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n", + " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n", + " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n", + "\n", + "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n", + "\n", + "![ConfusionMatrix](https://github.com/MathMachado/Materials/blob/master/ConfusionMatrix.PNG?raw=true)\n", + "\n", + "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ci-6eiqBTgbL" + }, + "source": [ + "## Accuracy\n", + "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n", + "```\n", + "\n", + "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7YI8X5TRx-R" + }, + "source": [ + "## Precision (ou Specificity)\n", + "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "\n", + "$$Precision= \\frac{TP}{TP+FP}$$\n", + "\n", + "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n", + "\n", + "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zO39n8x_Sz3L" + }, + "source": [ + "## Recall (ou Sensitivity)\n", + "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n", + "\n", + "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n", + "\n", + "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htS6rdHVVXRG" + }, + "source": [ + "## Specificity\n", + "> **Specificity** - proporção de TN por TN+FP.\n", + "\n", + "Responde à seguinte pergunta:\n", + "\n", + "```\n", + "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n", + "```\n", + "\n", + "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n", + "\n", + "$$Specificity= \\frac{TN}{TN+FP}$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mNn0twadTacc" + }, + "source": [ + "## F1-Score\n", + "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n", + "\n", + "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gkCubyUCP_hn" + }, + "source": [ + "### Funções usadas neste tutorial" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZD2pH9hfTnZv" + }, + "source": [ + "#### Função para Cross-Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hr8LczrSQB0x" + }, + "source": [ + "def funcao_cross_val_score(modelo, X_treinamento, y_treinamento, CV):\n", + " # versão com sklearn.model_selection.cross_validate:\n", + " #a_scores_CV = cross_validate(modelo, X_treinamento, y_treinamento, cv = CV, scoring = metodo)\n", + " #print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " #print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + " #return a_scores_CV\n", + "\n", + " #versão com cross_val_score::\n", + " a_scores_CV = cross_val_score(modelo, X_treinamento, y_treinamento, cv = CV)\n", + " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n", + " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n", + " return a_scores_CV" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ROlyvgij2yl" + }, + "source": [ + "#### Função para plotar a Confusion Matrix\n", + "* Extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klQ0FLOIgeX1" + }, + "source": [ + "def mostra_confusion_matrix(cf, \n", + " group_names = None, \n", + " categories = 'auto', \n", + " count = True, \n", + " percent = True, \n", + " cbar = True, \n", + " xyticks = False, \n", + " xyplotlabels = True, \n", + " sum_stats = True, \n", + " figsize = (8, 8), \n", + " cmap = 'Blues'):\n", + " '''\n", + " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n", + " Arguments\n", + " ---------\n", + " cf: confusion matrix to be passed in\n", + " group_names: List of strings that represent the labels row by row to be shown in each square.\n", + " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n", + " count: If True, show the raw number in the confusion matrix. Default is True.\n", + " normalize: If True, show the proportions for each category. Default is True.\n", + " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n", + " Default is True.\n", + " xyticks: If True, show x and y ticks. Default is True.\n", + " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n", + " sum_stats: If True, display summary statistics below the figure. Default is True.\n", + " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n", + " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n", + " See http://matplotlib.org/examples/color/colormaps_reference.html\n", + " '''\n", + "\n", + " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n", + " blanks = ['' for i in range(cf.size)]\n", + "\n", + " if group_names and len(group_names)==cf.size:\n", + " group_labels = [\"{}\\n\".format(value) for value in group_names]\n", + " else:\n", + " group_labels = blanks\n", + "\n", + " if count:\n", + " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n", + " else:\n", + " group_counts = blanks\n", + "\n", + " if percent:\n", + " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n", + " else:\n", + " group_percentages = blanks\n", + "\n", + " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n", + " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n", + "\n", + " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n", + " if sum_stats:\n", + " #Accuracy is sum of diagonal divided by total observations\n", + " accuracy = np.trace(cf) / float(np.sum(cf))\n", + "\n", + " #if it is a binary confusion matrix, show some more stats\n", + " if len(cf)==2:\n", + " #Metrics for Binary Confusion Matrices\n", + " precision = cf[1,1] / sum(cf[:,1])\n", + " recall = cf[1,1] / sum(cf[1,:])\n", + " f1_score = 2*precision*recall / (precision + recall)\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n", + " else:\n", + " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n", + " else:\n", + " stats_text = \"\"\n", + "\n", + " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n", + " if figsize==None:\n", + " #Get default figure size if not set\n", + " figsize = plt.rcParams.get('figure.figsize')\n", + "\n", + " if xyticks==False:\n", + " #Do not show categories if xyticks is False\n", + " categories=False\n", + "\n", + " # MAKE THE HEATMAP VISUALIZATION\n", + " plt.figure(figsize=figsize)\n", + " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n", + "\n", + " if xyplotlabels:\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label' + stats_text)\n", + " else:\n", + " plt.xlabel(stats_text)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8J-sTUfTTdLi" + }, + "source": [ + "#### Função para o GridSearchCV" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ap3WMXqDthu9" + }, + "source": [ + "def GridSearchOptimizer(modelo, ml_Opt, d_hiperparametros, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas):\n", + " ml_GridSearchCV = GridSearchCV(modelo, d_hiperparametros, cv = i_CV, n_jobs = -1, verbose= 10, scoring = 'accuracy')\n", + " start = time()\n", + " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n", + " tempo_elapsed = time()-start\n", + " print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n", + "\n", + " # Hiperparâmetros que otimizam a classificação:\n", + " print(f'\\nHiperparâmetros otimizados: {ml_GridSearchCV.best_params_}')\n", + " \n", + " if ml_Opt == 'ml_DT2':\n", + " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n", + " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_RF2':\n", + " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n", + " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n", + " max_features= ml_GridSearchCV.best_params_['max_features'],\n", + " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n", + " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n", + " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n", + " random_state= i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_AB2':\n", + " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n", + " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n", + " base_estimator=RandomForestClassifier(bootstrap = False, \n", + " max_depth = 10, \n", + " max_features = 'auto', \n", + " min_samples_leaf = 1, \n", + " min_samples_split = 2, \n", + " n_estimators = 400), \n", + " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " random_state = i_Seed)\n", + " \n", + " elif ml_Opt == 'ml_GB2':\n", + " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n", + " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n", + " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n", + " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n", + " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n", + " max_features = ml_GridSearchCV.best_params_['max_features'])\n", + " \n", + " elif ml_Opt == 'ml_XGB2':\n", + " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n", + " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n", + " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n", + " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n", + " subsample= ml_GridSearchCV.best_params_['subsample'], \n", + " gamma= ml_GridSearchCV.best_params_['gamma'], \n", + " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n", + " \n", + " # Treina novamente usando os hiperparâmetros otimizados...\n", + " ml_Opt.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Cross-Validation com 10 folds\n", + " print(f'\\n********* CROSS-VALIDATION ***********')\n", + " a_scores_CV = funcao_cross_val_score(ml_Opt, X_treinamento, y_treinamento, i_CV)\n", + "\n", + " # Faz predições com os hiperparâmetros otimizados...\n", + " y_pred = ml_Opt.predict(X_teste)\n", + " \n", + " # Importância das COLUNAS\n", + " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n", + " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n", + " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n", + " print(df_importancia_variaveis)\n", + "\n", + " # Matriz de Confusão\n", + " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n", + " cf_matrix = confusion_matrix(y_teste, y_pred)\n", + " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + " cf_categories = ['Zero', 'One']\n", + " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n", + "\n", + " return ml_Opt, ml_GridSearchCV.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YMnQn2XgT7Mg" + }, + "source": [ + "#### Função para selecionar COLUNAS relevantes dos dataframes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsnHcaeLUDFS" + }, + "source": [ + "from sklearn.feature_selection import SelectFromModel\n", + "\n", + "def seleciona_colunas_relevantes(modelo, X_treinamento, X_teste, threshold = 0.05):\n", + " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n", + " sfm = SelectFromModel(modelo, threshold)\n", + " \n", + " # Treina o seletor\n", + " sfm.fit(X_treinamento, y_treinamento)\n", + "\n", + " # Mostra o indice das COLUNAS mais importantes\n", + " print(f'\\n********** COLUNAS Relevantes ******')\n", + " print(sfm.get_support(indices=True))\n", + "\n", + " # Seleciona somente as COLUNAS relevantes\n", + " X_treinamento_I = sfm.transform(X_treinamento)\n", + " X_teste_I = sfm.transform(X_teste)\n", + " return X_treinamento_I, X_teste_I " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gd98JFSGUV5n" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3e0m7lEnYOV9" + }, + "source": [ + "### Função para calcular a importância das colunas/variáveis/atributos\n", + "* Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fjco0HnNYr-N" + }, + "source": [ + "def mostra_feature_importances(clf, X_treinamento, y_treinamento=None, \n", + " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n", + " '''\n", + " plot feature importances of a tree-based sklearn estimator\n", + " \n", + " Note: X_treinamento and y_treinamento are pandas DataFrames\n", + " \n", + " Note: Scikit-plot is a lovely package but I sometimes have issues\n", + " 1. flexibility/extendibility\n", + " 2. complicated models/datasets\n", + " But for many situations Scikit-plot is the way to go\n", + " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n", + " \n", + " Parameters\n", + " ----------\n", + " clf (sklearn estimator) if not fitted, this routine will fit it\n", + " \n", + " X_treinamento (pandas DataFrame)\n", + " \n", + " y_treinamento (pandas DataFrame) optional\n", + " required only if clf has not already been fitted \n", + " \n", + " top_n (int) Plot the top_n most-important features\n", + " Default: 10\n", + " \n", + " figsize ((int,int)) The physical size of the plot\n", + " Default: (8,8)\n", + " \n", + " print_table (boolean) If True, print out the table of feature importances\n", + " Default: False\n", + " \n", + " Returns\n", + " -------\n", + " the pandas dataframe with the features and their importance\n", + " \n", + " Author\n", + " ------\n", + " George Fisher\n", + " '''\n", + " \n", + " __name__ = \"mostra_feature_importances\"\n", + " \n", + " import pandas as pd\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + " \n", + " from xgboost.core import XGBoostError\n", + " from lightgbm.sklearn import LightGBMError\n", + " \n", + " try: \n", + " if not hasattr(clf, 'feature_importances_'):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + "\n", + " if not hasattr(clf, 'feature_importances_'):\n", + " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n", + " format(clf.__class__.__name__))\n", + " \n", + " except (XGBoostError, LightGBMError, ValueError):\n", + " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n", + " \n", + " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n", + " feat_imp['feature'] = X_treinamento.columns\n", + " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n", + " feat_imp = feat_imp.iloc[:top_n]\n", + " \n", + " feat_imp.sort_values(by='importance', inplace = True)\n", + " feat_imp = feat_imp.set_index('feature', drop = True)\n", + " feat_imp.plot.barh(title=title, figsize=figsize)\n", + " plt.xlabel('Feature Importance Score')\n", + " plt.show()\n", + " \n", + " if print_table:\n", + " from IPython.display import display\n", + " print(\"Top {} features in descending order of importance\".format(top_n))\n", + " display(feat_imp.sort_values(by = 'importance', ascending = False))\n", + " \n", + " return feat_imp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rsH9dMxazWCg" + }, + "source": [ + "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n", + "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n", + "\n", + "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GEyDo_EIV_jV" + }, + "source": [ + "## Definir variáveis globais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TdwgpZ76WFaT" + }, + "source": [ + "i_CV = 10 # Número de Cross-Validations\n", + "i_Seed = 20111974 # semente por questões de reproducibilidade\n", + "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gJTJfpwWzykS" + }, + "source": [ + "from sklearn.datasets import make_classification\n", + "\n", + "X, y = make_classification(n_samples = 1000, \n", + " n_features = 18, \n", + " n_informative = 9, \n", + " n_redundant = 6, \n", + " n_repeated = 3, \n", + " n_classes = 2, \n", + " n_clusters_per_class = 1, \n", + " random_state=i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gWy2IZh3s-o3", + "outputId": "e72d1b18-fca3-4352-9ea3-0009377505b3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 0.06844089, 4.21184154, -2.5583024 , ..., -0.63061895,\n", + " -0.97831983, -0.88826977],\n", + " [-4.8240213 , 0.17950903, -2.98447332, ..., 0.33992045,\n", + " 1.89153784, -6.10967565],\n", + " [ 1.38953042, -0.226476 , 1.8774004 , ..., -1.47784549,\n", + " 0.96052606, 2.06020368],\n", + " ...,\n", + " [ 1.62548685, 0.43377848, 4.93537285, ..., -4.61990917,\n", + " 0.18310709, 6.16040231],\n", + " [-2.40619087, -1.65474635, 2.64196493, ..., -1.21427845,\n", + " 0.83745861, 0.8254619 ],\n", + " [-4.00041881, 2.52475556, -4.15290177, ..., -0.51680266,\n", + " 1.72224835, -5.59558306]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccjhGnzxtAaV", + "outputId": "82144bbd-78c7-4bc5-b0e1-9457ca30f421", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y[0:30] # Semelhante aos casos de fraude: {0, 1}" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OHO2befKJxR3" + }, + "source": [ + "___\n", + "# **DECISION TREE**\n", + "> Decision Trees possuem estrutura em forma de árvores.\n", + "\n", + "![DecisionTree](https://github.com/MathMachado/Materials/blob/master/DecisionTree.PNG?raw=true)\n", + "\n", + "Fonte: [Um tutorial completo sobre modelagem baseada em árvores de decisão (códigos R e Python)](https://www.vooo.pro/insights/um-tutorial-completo-sobre-a-modelagem-baseada-em-tree-arvore-do-zero-em-r-python/)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J4fRargyX_1M" + }, + "source": [ + "* **Principais Vantagens**:\n", + " * São algoritmos fáceis de entender, visualizar e interpretar;\n", + " * Captura facilmente padrões não-lineares presentes nos dados;\n", + " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n", + " * Lida bem com COLUNAS numéricas ou categóricas;\n", + " * Não requer os dados sejam normalizados;\n", + " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n", + " * Pode ser utilizado como Feature Selection;\n", + " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n", + "\n", + "* **Principais desvantagens**\n", + " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n", + " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n", + "\n", + "* **Principais Hiperparâmetros**\n", + " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n", + " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n", + " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n", + " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n", + "\n", + "## **Referências**:\n", + "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n", + "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n", + "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n", + "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n", + "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FrMkPN5aLp0Y" + }, + "source": [ + "## Carregar as bibliotecas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FVU1CM0PKgO4" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "15clh4XrISpz" + }, + "source": [ + "## Carregar/Ler os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UMPL46w2IWJw" + }, + "source": [ + "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n", + "\n", + "df_X = pd.DataFrame(X, columns = l_colunas)\n", + "df_y = pd.DataFrame(y, columns = ['target'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "8fbd0af4-559f-49fc-d9cf-4e39a64b9b30", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
00.0684414.211842-2.5583023.665482-3.8351583.4998512.4908563.6654820.2451170.8671722.8655460.493956-5.1485962.8655463.499851-0.630619-0.978320-0.888270
1-4.8240210.179509-2.9844731.033618-3.8934263.428734-3.3346051.033618-0.882780-0.7532811.441522-1.395514-4.0028801.4415223.4287340.3399201.891538-6.109676
21.389530-0.2264761.8774002.7134264.6302570.516455-3.7430272.7134261.2840392.030797-1.0955361.560159-1.014211-1.0955360.516455-1.4778450.9605262.060204
31.1458092.2559460.2073644.6658172.2946786.5013060.9647704.6658170.1194103.1963541.8947873.519138-4.7578071.8947876.501306-3.7890290.5794911.397106
4-0.9366463.697163-3.3636173.805126-1.7544304.9543460.4066053.805126-0.8247381.3825911.665704-0.649758-3.5130361.6657044.9543460.2570520.904244-3.071354
\n", + "
" + ], + "text/plain": [ + " v1 v2 v3 ... v16 v17 v18\n", + "0 0.068441 4.211842 -2.558302 ... -0.630619 -0.978320 -0.888270\n", + "1 -4.824021 0.179509 -2.984473 ... 0.339920 1.891538 -6.109676\n", + "2 1.389530 -0.226476 1.877400 ... -1.477845 0.960526 2.060204\n", + "3 1.145809 2.255946 0.207364 ... -3.789029 0.579491 1.397106\n", + "4 -0.936646 3.697163 -3.363617 ... 0.257052 0.904244 -3.071354\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "f85b02f9-1289-4347-ecf5-d0b2ba73a845", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "db612d0d-7ec6-495c-ed69-4b48d653fd84", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "8d06dab9-86f2-447a-ad02-4e03a714cad1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 304 + } + }, + "source": [ + "df_X.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16v17v18
count1000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000000
mean-0.0851591.0342270.6574081.4053170.6872791.1315600.1080531.4053171.0070231.0488010.0792480.001650-0.3654380.0792481.131560-0.0277510.9846060.633624
std2.0022471.6315073.6087722.2568574.0195984.4818321.9813072.2568571.8632881.6439001.9492731.9326414.1606681.9492734.4818322.0654551.8505933.552991
min-6.944169-4.620754-16.300139-6.235192-12.454256-14.305401-6.152747-6.235192-5.484992-3.293216-7.135349-5.705500-9.120941-7.135349-14.305401-6.009023-5.035184-11.439074
25%-1.305566-0.089052-1.623657-0.152888-1.854645-1.684751-1.216983-0.152888-0.240908-0.012710-1.209675-1.292162-3.555363-1.209675-1.684751-1.436673-0.261610-1.691346
50%0.0525230.9941500.5738491.4499310.8123641.2815040.1670911.4499311.0661251.0128990.1803440.035237-0.9666380.1803441.281504-0.0001900.9757930.844784
75%1.3838532.0719953.0385862.8871413.4139524.0081031.4387192.8871412.2881882.1872021.4391991.3153422.7458061.4391994.0081031.3653692.2565043.109330
max4.9971727.35486011.7201658.49456612.84441815.9998036.2935508.4945668.1465596.5231806.2524485.53821611.2593506.25244815.9998036.5315617.64680212.090528
\n", + "
" + ], + "text/plain": [ + " v1 v2 ... v17 v18\n", + "count 1000.000000 1000.000000 ... 1000.000000 1000.000000\n", + "mean -0.085159 1.034227 ... 0.984606 0.633624\n", + "std 2.002247 1.631507 ... 1.850593 3.552991\n", + "min -6.944169 -4.620754 ... -5.035184 -11.439074\n", + "25% -1.305566 -0.089052 ... -0.261610 -1.691346\n", + "50% 0.052523 0.994150 ... 0.975793 0.844784\n", + "75% 1.383853 2.071995 ... 2.256504 3.109330\n", + "max 4.997172 7.354860 ... 7.646802 12.090528\n", + "\n", + "[8 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_QhFqyZOKFB" + }, + "source": [ + "## Selecionar as amostras de treinamento e validação\n", + "\n", + "* Dividir os dados/amostras em:\n", + " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n", + " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n", + "* **Técnica de Hold-Out**: Separar/dividir os dados em amostra de treinamento e teste. Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n", + " * **Desvatangem do Hold-Out**: Variância nos dados pode comprometer performance do modelo quando, por exemplo, amostra de treinamento é semelhante amostra de teste. \n", + "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8sKBgs-QOOfn" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "2948cf55-c38b-499e-f584-ba102fb84d5c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "98cf2d71-40b5-474c-e30d-cfe7468f8920", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_treinamento.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "ada5d946-e73d-4fcd-e4da-5287b463a875", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "06ef3a8f-929f-42cf-d538-bcefa254fac0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_teste.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "npgoBSX2dd4l" + }, + "source": [ + "## Treinar o algoritmo com os dados de treinamento\n", + "### Carregar os algoritmos/libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcvzrtolGfnQ", + "outputId": "7994c7f4-c644-4ffe-ea58-d27f522e9576", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "!pip install graphviz\n", + "!pip install pydotplus" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n", + "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n", + "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_pF-HH3JKL2" + }, + "source": [ + "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n", + "#from sklearn.model_selection import train_test_split\n", + "#from sklearn.metrics import classification_report\n", + "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n", + "\n", + "from sklearn.model_selection import GridSearchCV # para otimizar os hiperparâmetros dos modelos preditivos\n", + "from sklearn.model_selection import cross_val_score # Para o CV (Cross-Validation)\n", + "from sklearn.model_selection import cross_validate\n", + "\n", + "from time import time\n", + "from operator import itemgetter\n", + "from scipy.stats import randint\n", + "\n", + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "np.set_printoptions(suppress=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJMS9ePQ6B6t" + }, + "source": [ + "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nNeRHYePJc-r" + }, + "source": [ + "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n", + "\n", + "# Instancia (configuração do Decision Trees) com os hiperparâmetros sugeridos para se evitar overfitting:\n", + "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n", + " splitter = 'best', \n", + " max_depth = None, \n", + " min_samples_split = 2, \n", + " min_samples_leaf = 1, \n", + " min_weight_fraction_leaf = 0.0, \n", + " max_features = None, \n", + " random_state = i_Seed, \n", + " max_leaf_nodes = None, \n", + " min_impurity_decrease = 0.0, \n", + " min_impurity_split = None, \n", + " class_weight = None, \n", + " presort = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gVLZznprx2YX", + "outputId": "6266f184-5949-4f2d-eb76-7215f87f1b3a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Objeto/classificador configurado\n", + "ml_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8CC24H-JHhlj" + }, + "source": [ + "### Treina o algoritmo: fit(df)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "a2c20323-1ef2-4491-fb19-4b96c370e04b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "ml_DT.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n", + " max_depth=None, max_features=None, max_leaf_nodes=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, presort=False,\n", + " random_state=20111974, splitter='best')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CNiRjmrRHVnx" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2GMCSs89HquJ", + "outputId": "cde08303-2def-4401-ecf7-dd3c45c393c1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 32 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bmv9YZobIer4" + }, + "source": [ + "### Calcula as predições usando o modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2YufZaRNIkFL" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fYvMN-tvIX-p" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9iTK6pBwIZ3F", + "outputId": "9345ea23-6691-446f-dead-d5c893bcc6c8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jOnkFBcEIVAb" + }, + "source": [ + "### Volte ao início, extraia nova amostra e calcule a acurácia\n", + "* Observou que a acurácia mudou? Isso acontece porque extraimos uma nova amostra de treinamento.\n", + "* Quais os inconvenientes de termos uma métrica diferente para cada amostra do modelo preditivo?\n", + "* Como reportar os resultados do seu modelo?\n", + "* Como se assegurar acerca do valor mais ideal da métrica?\n", + " * use a Estatística a seu favor! --> Use Cross-Validation." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MkBSvyorGXQz" + }, + "source": [ + "___\n", + "# **CROSS-VALIDATION**\n", + "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n", + "* Como funciona: divide o dataframe de treinamento em k partes (cada parte é um fold);\n", + " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n", + " * O processo é repetido k vezes, sendo que em cada iteração calcula as métricas desejadas (exemplo: acurácia);\n", + " * Desta forma o modelo é treinado e testado com todas as partes dos dados;\n", + " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n", + "\n", + " A figura abaixo nos ajuda a entender como funciona CV:\n", + "\n", + "![Cross-Validation](https://github.com/MathMachado/Materials/blob/master/CV2.PNG?raw=true)\n", + "\n", + "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + "\n", + "* **valor de k**:\n", + " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n", + " * Quanto maior o valor de k --> menor o viés do CV --> Experimento Estatístico para mostrar o efeito.\n", + "\n", + "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HscfN-a1V043" + }, + "source": [ + "* **Vantagens do uso de CV**:\n", + " * Modelos com melhor acurácia;\n", + " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n", + "\n", + "* **Leitura Adicional**\n", + " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n", + " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n", + " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8x2UPwOYQPcI", + "outputId": "7b9c4045-2257-4795-a54f-3305d2e97ab2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Cross-Validation com k = 10 folds (= 10 partes)\n", + "a_scores_CV = funcao_cross_val_score(ml_DT, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Média das Acurácias calculadas pelo CV....: 91.43\n", + "std médio das Acurácias calculadas pelo CV: 3.44\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uxoplcea0byV", + "outputId": "0acecb3b-565d-4356-c46b-4c48da8268fb", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "a_scores_CV # array com os scores a cada iteração do CV" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.9 , 0.98571429, 0.85714286, 0.92857143, 0.88571429,\n", + " 0.94285714, 0.92857143, 0.9 , 0.88571429, 0.92857143])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y3k-PcbN0o_i", + "outputId": "0d4222a7-dee5-4468-8e58-9e3dccd8def1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "a_scores_CV.mean()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.9142857142857144" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6_rYker2gzeG" + }, + "source": [ + "**Interpretação**: Nosso classificador (DecisionTreeClassifier) tem uma acurácia média de 91,43% (base de treinamento). Além disso, o std é da ordem de 3,66%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tkwchmkP3p_A", + "outputId": "11804dfc-d593-4d00-8b6b-b37d162d0bd6", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n", + " 0.92857143 0.9 0.88571429 0.92857143]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lQNyqHCiKRUh" + }, + "source": [ + "### Valida o modelo com a amostra de treinamento" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qb0ZPyvKKRUp", + "outputId": "1785679f-fa54-4fe9-82f4-e9847374f950", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "ml_DT.score(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.94" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iL2tEdbqKY5P" + }, + "source": [ + "### Predições com o modelo treinado\n", + "* Faz predições usando o classificador (Decision Trees) para inferir na amostra de teste:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sI31WkZs2ht_" + }, + "source": [ + "y_pred = ml_DT.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rfapj3OG13PG", + "outputId": "367c435b-c3b9-49a5-b78f-7c03042e7da0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_pred[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n", + " 1, 0, 0, 1, 1, 0, 1, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sc88ofqh16RT", + "outputId": "05a0fb74-4512-445b-9d76-0f6589d18541", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n", + " 1, 1, 0, 1, 0, 1, 0, 1])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cecv-51TKgz-" + }, + "source": [ + "### Matriz de Confusão" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "053c1abb-ef0b-479e-a770-738d4691538f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 538 + } + }, + "source": [ + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p8D975NqsGtj" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bfdq5zEhlVsk" + }, + "source": [ + "# Dicionário com hiperparâmetros para o parameter tunning:\n", + "d_hiperparametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n", + " \"min_samples_split\": [2, 5, 10, 270, 350, 400], \n", + " \"max_depth\": [None, 2, 5, 9, 15], \n", + " \"min_samples_leaf\": [20, 40, 100], \n", + " \"max_leaf_nodes\": [None, 2, 3, 15]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BtajXuuUpGwq", + "outputId": "020d97bf-4940-406e-8fb3-23c8b09018a5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_hiperparametros_DT" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'criterion': ['gini', 'entropy'],\n", + " 'max_depth': [None, 2, 5, 9, 15],\n", + " 'max_leaf_nodes': [None, 2, 3, 15],\n", + " 'min_samples_leaf': [20, 40, 100],\n", + " 'min_samples_split': [2, 5, 10, 270, 350, 400]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H8gNSs0G0A-L" + }, + "source": [ + "```\n", + "grid_search = GridSearchCV(ml_DT, param_grid= d_hiperparametros_DT, cv = i_CV, n_jobs= -1)\n", + "start = time()\n", + "grid_search.fit(X_treinamento, y_treinamento)\n", + "tempo_elapsed= time()-start\n", + "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n", + "\n", + "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "44-BRnNjBT25", + "outputId": "e8547d4f-1eff-42e2-aa2a-9e8735f2a997", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "# Invoca a função com o modelo baseline\n", + "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_hiperparametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Fitting 10 folds for each of 720 candidates, totalling 7200 fits\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n", + "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.5s\n", + "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.6s\n", + "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.7s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1995s.) Setting batch_size=2.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0662s.) Setting batch_size=4.\n", + "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 1.8s\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0940s.) Setting batch_size=8.\n", + "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1391s.) Setting batch_size=16.\n", + "[Parallel(n_jobs=-1)]: Done 58 tasks | elapsed: 2.0s\n", + "[Parallel(n_jobs=-1)]: Done 186 tasks | elapsed: 2.9s\n", + "[Parallel(n_jobs=-1)]: Done 330 tasks | elapsed: 3.8s\n", + "[Parallel(n_jobs=-1)]: Done 506 tasks | elapsed: 4.9s\n", + "[Parallel(n_jobs=-1)]: Done 682 tasks | elapsed: 6.0s\n", + "[Parallel(n_jobs=-1)]: Done 890 tasks | elapsed: 7.3s\n", + "[Parallel(n_jobs=-1)]: Done 1098 tasks | elapsed: 8.5s\n", + "[Parallel(n_jobs=-1)]: Done 1338 tasks | elapsed: 10.0s\n", + "[Parallel(n_jobs=-1)]: Done 1578 tasks | elapsed: 11.5s\n", + "[Parallel(n_jobs=-1)]: Done 1850 tasks | elapsed: 13.2s\n", + "[Parallel(n_jobs=-1)]: Done 2122 tasks | elapsed: 15.0s\n", + "[Parallel(n_jobs=-1)]: Done 2426 tasks | elapsed: 16.7s\n", + "[Parallel(n_jobs=-1)]: Done 2730 tasks | elapsed: 18.5s\n", + "[Parallel(n_jobs=-1)]: Done 3066 tasks | elapsed: 20.4s\n", + "[Parallel(n_jobs=-1)]: Done 3402 tasks | elapsed: 22.3s\n", + "[Parallel(n_jobs=-1)]: Done 3770 tasks | elapsed: 24.8s\n", + "[Parallel(n_jobs=-1)]: Done 4138 tasks | elapsed: 27.4s\n", + "[Parallel(n_jobs=-1)]: Done 4538 tasks | elapsed: 30.2s\n", + "[Parallel(n_jobs=-1)]: Done 4938 tasks | elapsed: 32.9s\n", + "[Parallel(n_jobs=-1)]: Done 5370 tasks | elapsed: 35.8s\n", + "[Parallel(n_jobs=-1)]: Done 5802 tasks | elapsed: 38.9s\n", + "[Parallel(n_jobs=-1)]: Done 6266 tasks | elapsed: 42.2s\n", + "[Parallel(n_jobs=-1)]: Done 6730 tasks | elapsed: 45.5s\n", + "[Parallel(n_jobs=-1)]: Done 7181 tasks | elapsed: 48.8s\n", + "[Parallel(n_jobs=-1)]: Done 7200 out of 7200 | elapsed: 49.0s finished\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "\n", + "GridSearchCV levou 49.12 segundos.\n", + "\n", + "Hiperparâmetros otimizados: {'criterion': 'entropy', 'max_depth': 5, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 2}\n", + "\n", + "DecisionTreeClassifier *********************************************************************************************************\n", + "\n", + "********* CROSS-VALIDATION ***********\n", + "Média das Acurácias calculadas pelo CV....: 91.14\n", + "std médio das Acurácias calculadas pelo CV: 3.25\n", + "\n", + "********* IMPORTÂNCIA DAS COLUNAS ***********\n", + " coluna importancia\n", + "12 v13 0.552335\n", + "0 v1 0.116321\n", + "6 v7 0.074047\n", + "9 v10 0.069885\n", + "11 v12 0.058293\n", + "1 v2 0.040086\n", + "8 v9 0.028917\n", + "16 v17 0.020542\n", + "2 v3 0.017079\n", + "7 v8 0.011940\n", + "13 v14 0.010556\n", + "4 v5 0.000000\n", + "5 v6 0.000000\n", + "3 v4 0.000000\n", + "10 v11 0.000000\n", + "14 v15 0.000000\n", + "15 v16 0.000000\n", + "17 v18 0.000000\n", + "\n", + "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmCkjGjPJMLr" + }, + "source": [ + "### Visualizar o resultado" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cIc3ZgaISEd0", + "outputId": "2e2b5d3c-2aea-4c2f-ec7a-1d37b4f41eb7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 623 + } + }, + "source": [ + "from sklearn.tree import export_graphviz\n", + "from sklearn.externals.six import StringIO \n", + "from IPython.display import Image \n", + "import pydotplus\n", + "\n", + "dot_data = StringIO()\n", + "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n", + "\n", + "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n", + "graph.write_png('DecisionTree.png')\n", + "Image(graph.create_png())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": "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sZ6enqxcuZIGDRrQp08f/Pz8qFq1KrNnz+a7777jwQcfLIi92r+nIiIiIjcag/N8fatERERERERERETkhnTkyBE6depEdnY2P/30E9WqVXN1SiJFLFmyhN69e1OtWjXmzZtHUFCQq1MSERERkX9IHRRERERERERERERuIrt27aJly5aYzWZWrlyp4gS5brVt25bVq1cTFxdH06ZN2b9/v6tTEhEREZF/SAUKIiIiIiIiIiIiN4mlS5fSokULqlSpwqpVqwgPD3d1SiIXVKNGDdatW0dAQADNmjVj5cqVrk5JRERERP4BFSiIiIiIiIiIiIjcBH744Qc6d+5M+/btWbhwIX5+fq5OSeSShIaGsmzZMpo3b06HDh2YPn26q1MSERERkSukAgUREREREREREZEb3Icffkjfvn157LHHmDFjBu7u7q5OSeSyeHl5MWvWLB599FHuvvtuxowZ4+qUREREROQKmF2dgIiIiIiIiIiIiJQMp9PJ888/z1tvvcXrr7/OyJEjXZ2SyBUzmUxMmDCBypUrM3z4cE6ePMnEiRMxm/U1t4iIiMi/hcHpdDpdnYSIiIiIiIiIiIhcXTabjQEDBvD9998zZcoU7rrrLlenJHLVzJ49m3vvvZeWLVsyY8YMfH19XZ2SiIiIiFwCFSiIiIiIiIiIiIjcYDIyMrjzzjtZvXo133//PR07dnR1SiJX3fr16+nevTuhoaEsWLCA8PBwV6ckIiIiIhdhdHUCIiIiIiIiIiIicvXEx8fTqlUrtm/fzooVK1ScIDesJk2asG7dOmw2G9HR0Wzbts3VKYmIiIjIRahAQURERERERERE5AYRExNDy5YtSUtLY+XKldSrV8/VKYmUqIiICFavXk3lypVp1aoVP//8s6tTEhEREZELUIGCiIiIiIiIiIjIDWDDhg00bdqUwMBA1q5dS+XKlV2dksg1ERgYyC+//EL37t3p1q0b//vf/1ydkoiIiIichwoURERERERERERE/uV+/PFH2rRpQ3R0NEuXLiUoKMjVKYlcU1arla+//poXX3yRgQMH8vTTT+N0Ol2dloiIiIj8jdnVCYiIiIiIiIiIiMiVmzJlCo8++ij33nsvn376KWazvvKTm5PBYGDMmDGUL1+eQYMGkZKSwqeffoqbm5urUxMRERGRP6iDgoiIiIiIiIiIyL/Um2++yYABAxgx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ERERERERkasqZsUclrw7GM9SobQd8QmRLbq7OiUREbmAuTtOMeS7XYT4WvmoXy261b65t8YQERGRkqMCBRERERERERERuSSdx13avtmVW/emcuveJZyNiIhczLcP1b+kuF51Q+lVN7SEsxEREREB9WgSERERERERERERERERERGREqcCBRERERERERERuSoWjurL53dWcHUaIiLyN3d9sYVKo5a4Og0RERERbfEgIiIiIiIiIiLyV7lZGcx88lbSTx2jz8crCKxQvUiMw25j+fhh7F8yg+iHxnBLryeKnSvhwFa2zviQ0/s2k5WWhHdQGSKadaVB/xFYPLxL+lZERP71YhIyef2Xg6yKSSbHnke5AA+61Q5h8K0V8XIzFYrdeTKNN3+NYePRFLJy8wj396BzrWCGto3A25r/OCTH7qDiS4sveM17GpXlnd41SuyeREREbmYqUBAREREREREREfmLNZ++RPqpY+c9n5ORwq+vPUie3XbBeeJ2rWXBy3dSMbozPd5eiNXHn+Obl7DsgyHE715Hj7cXYDCowamIyPnsP51Jp4/WU7usL3MGNSTc353F+84wdOZutp9I4/8G1CuI3X4ijW4TN9C5ZgiLnoom0MvC2kPJPD1zN2sPJfPj4EYYDQasZiNxb3Qo9no/70lgwFfb6H5L6LW6RRERkZuO/gckIiIiIiIiIiLyh2MbF7H312+IbN612PM5GSnMfaYLYbWa0vThcReca8NXr+LuV5q2Iz7GJ6Qcbp4+VGrZg5pdHuLU3k2cObi9JG5BROSG8dpPB7A7nHxx7y1UC/HG22qmR51QHogux+J9Z1h3OLkg9vVfDmIyGni/Tw3KB3rgbTXToXoQg1pWYMvxVDYcSbngtTJtebw4dy896oTSqnJgSd+aiIjITUsdFERERERERERErhM56clsnv4uR9f/TGZSPBYPb4Kq1KXh3c8SHFW/UOzJ7SvZOuMDTu/fgjPPjndwOaLa9qXOHYMxWdwK4haO6U/qyRhue3Eqaya/wOkDWzGaLFRofBstB7/FsU2/sXXGB6SejMEjIJg6PQZRq/ujBePnjexG+qnjdHz5a9Z8+hIJB7eB00lItYY0feQVSkXUvOA9JR7axaZpbxG3ex25WZl4lQot2OLAzcv3iu69pGSnJ7F8/FAqtexJmTrNObR6fpGYrJQEavcYSPXb7+fU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RERERK5AXFwcb775Jr1796ZZs2Y8/fTTACxcuJAzZ84QExNDSEgIjRo1snBSEREREbkR1a9fnyVLlvDLL7+QmZlJ586dCQkJITc319LRREREzqMCBREREREREZFqMBqNFUUHjRs3pl27drz77rv4+/sTHh5OVlYWERERTJgwAXd3d0vHFREREZGbRN++fdm5cyeLFi3im2++oVWrVnz88ceYTCZLRxMREamgAgURERERERGRiygsLKwoOqhbty59+vQhOjqacePGsWHDBlJTU1myZAnBwcHY2dlZOq6IiIiI3KSsrKyYMGEChw4dYtSoUUydOpXu3buzZcsWS0cTEREBVKAgIiIiIiIiUqX09PSKogMvLy9GjBhBQkICM2fO5PDhw8TFxTFnzhx69+6NwWCwdFwRERERkQpeXl7MmzePbdu2YW9vT8+ePZkwYQLp6emWjiYiIjc5FSiIiIiIiIiI/C4uLo4333yT3r174+vry5QpUwCYP38+p06dIiYmhhkzZtCyZUsLJxURERERubjOnTvz22+/8e233/LLL7/QqlUr5s2bR3l5uaWjiYjITUoFCiIiIiIiInLTMhqNxMTEMHPmTFq1akW7du2YO3cu/v7+fPfdd6SnpxMREcGkSZPw8fGxdFwRERERkWozGAyMGjWKgwcP8sQTTzBjxgwCAwPZsGGDpaOJiMhNSAUKIiIiIiIiclMpKioiIiKCyZMn06BBA/r06UNYWBiDBw9mw4YNpKamsmTJEkaNGoWzs7Ol44qIiIiI1AhnZ2dCQ0PZt28fDRo0oG/fvgQHB5OUlGTpaCIichNRgYKIiIiIiIjc8DIzM1myZAmjR4+mXr163HPPPezYsYPHHnuMAwcOEB8fz7x58+jduzdWVvpVWURERERuXAEBAaxYsYLly5dz4MAB2rRpQ2hoKMXFxZaOJiIiNwH91UVERERERERuSAkJCRVFBz4+Pjz22GMUFRXx7rvvkpyczPbt2wkNDaV169aWjioiIiIics0FBwdz8OBB/vWvfzF37lzat29PZGSkpWOJiMgNTgUKIiIiIiIickMwmUzs2LGD0NBQ2rZtS/PmzXn11Vfx9/fn22+/JT09nYiICCZNmoSfn5+l44qIiIiIWJydnR0hISEcOnSIHj16MGzYMAYNGsTBgwctHU1ERG5QKlAQERERERGR61ZxcTHR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\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e1R2GBkbnV37" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ukMLoEr7nbUf", + "outputId": "4fc221e2-0c35-4669-ddf4-7cba982106c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_treinamento_DT, X_teste_DT = seleciona_colunas_relevantes(ml_DT2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "********** COLUNAS Relevantes ******\n", + "[ 0 6 9 11 12]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xSDB20yWOrH1" + }, + "source": [ + "### Importância das variáveis pelo modelo.feature_importances_" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WJbGcEeqOFRQ", + "outputId": "ce97e5d9-f6ec-48f0-f214-e01f5b24c471", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "ml_RF3.feature_importances_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mml_RF3\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfeature_importances_\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'ml_RF3' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JjePRQAoqkk" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gt3aCPpfKRxm" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq6uCVtzovMt" + }, + "source": [ + "# Treina usando as COLUNAS relevantes...\n", + "ml_DT2.fit(X_treinamento_DT, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M2h3EpinRD5Q" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT2, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "znWy3LE1q-Z3" + }, + "source": [ + "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_hiperparametros_DT, X_treinamento_DT, y_treinamento, X_teste_DT, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IhCC6pfq-jL" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qw6Dk3kesT0q" + }, + "source": [ + "best_params2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFoK1ZGrRHf3" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_DT3, X_treinamento_DT, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MZ1-vGRcxJoN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ig9GiUAEw9jr" + }, + "source": [ + "y_pred_DT = ml_DT2.predict(X_teste_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7UZz4UzHDqae" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_DT)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K3EUMAxxKBur" + }, + "source": [ + "___\n", + "# **RANDOM FOREST**\n", + "* Decision Trees possuem estrutura em forma de árvores.\n", + "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier) quanto para Regressão (RandomForestRegressor);\n", + "* Os nós da árvore são criados a partir das variáveis do dataframe;\n", + "\n", + "* **Vantagens**:\n", + " * Não requer tanto data preprocessing;\n", + " * Lida bem com COLUNAS categóricas e numéricas;\n", + " * Apresenta bons resultados em diversos tipos de problema;\n", + " * Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n", + " * Ensemble é a combinação de diferentes modelos preditivos;\n", + " * Torna os algoritmos/resultados mais robustos e complexos, levando a um maior custo computacional que costuma ser acompanhando de melhores resultados.\n", + " * Mais robusta que uma simples Decision Tree. **Porque?**\n", + " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n", + " * Pode ser utilizado como **Feature Selection**, pois gera a matriz de importância dos atributos (importance sample). \n", + " * A soma das importâncias das variáveis soma 100;\n", + " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n", + " * Não requer dados normalizados;\n", + " * Lida bem com Missing Values;\n", + " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo;\n", + "\n", + "* **Desvantagens/Cuidados**\n", + " * **Recomenda-se balancear o dataframe previamente**.\n", + "\n", + "* **Principais Hiperparâmetros**\n", + "\n", + "## **Referências**:\n", + "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n", + "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n", + "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n", + "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n", + "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n", + "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n", + "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais hiperparâmetros do Random Forest." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMQt5wiw1tt8" + }, + "source": [ + "### Como funciona?\n", + "\n", + "O algoritmo possui 4 passos:\n", + "1. Seleção aleatória de algumas features;\n", + "2. Seleção da feature mais adequada para a posição de nó raiz;\n", + "3. Geração dos nós filhos\n", + "4. Repete os passos acima até que se atinja a quantidade de árvores desejada.\n", + "\n", + "**Observação**: Depois que o modelo é gerado, as previsões são feitas a partir de “votações” das várias árvores. A decisão mais votada é a resposta do algoritmo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VLGqtjs42zkN" + }, + "source": [ + "![DecisionTree](https://github.com/MathMachado/Materials/blob/master/DecisionTree.PNG?raw=true)\n", + "\n", + "Fonte: [Um tutorial completo sobre modelagem baseada em árvores de decisão (códigos R e Python)](https://www.vooo.pro/insights/um-tutorial-completo-sobre-a-modelagem-baseada-em-tree-arvore-do-zero-em-r-python/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HaUjVgEd2rzU" + }, + "source": [ + "![](![image.png](data:image/png;base64,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))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r0s2vixBzFAR" + }, + "source": [ + "### Principais hiperparâmetros\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais hiperparâmetros do Random Forest.\n", + "\n", + " * n_estimators: especifica o número de árvores. O valor default é 10, o que significa que 10 diferentes modelos de DecisionTrees serão ajustadas;\n", + " * max_depth: especifica a profundidade máxima de cada árvore. O valor default é None, o que significa que cada árvore se expandirá até que cada folha esteja pura. Uma folha pura é aquela em que todos os dados da folha vêm da mesma classe;\n", + " * min_samples_split: especifica o número mínimo de amostras necessárias para dividir um nó filho. O valor default é 2, o que significa que um nó filho deve ter pelo menos duas amostras antes de ser dividido;\n", + " * min_samples_leaf: especifica o número mínimo de amostras necessárias para estar em um nó folha. O valor default é 1, o que significa que cada folha deve ter pelo menos 1 amostra para classificar." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rp1e0atD_gXN" + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KxIGuaRZ_ivJ" + }, + "source": [ + "X_treinamento.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cnfDw_GEKBuu" + }, + "source": [ + "# Carregamento da library:\n", + "from sklearn.ensemble import RandomForestClassifier # Para resolver problemas de classificação\n", + "\n", + "# Instancia...\n", + "ml_RF = RandomForestClassifier(n_estimators = 100, min_samples_split = 2, max_features = \"auto\", random_state = i_Seed)\n", + "\n", + "# Treina...\n", + "ml_RF.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E25BIxM0RTzs" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FDsj9bJ0BCk6" + }, + "source": [ + "### Avaliar a distribuição da variável-resposta: $y$\n", + "* A classe minoritária é muito abaixo da classe majoritária?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SSDy4vwoBx8H" + }, + "source": [ + "X_treinamento.shape[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "68-p5HaHARqY" + }, + "source": [ + "y_treinamento['target'].value_counts() # Apresentar em forma %" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "23Zv-Oc-CQIj" + }, + "source": [ + "### Avaliar quantas linhas para cada preditora" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8F2ELvqdCXAR" + }, + "source": [ + "X_treinamento.shape[0]/X_treinamento.shape[1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x7Ql5N4gCm5u" + }, + "source": [ + "Temos 38 linhas para cada preditora do X_treinamento. O ideal são 50 linhas/observações para cada preditora." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AouWUu8vANdb" + }, + "source": [ + "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vbducxlgAa85" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQIRO_LpGAkw" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yKLHZ5_C6FJ8" + }, + "source": [ + "## Parameter tunning\n", + "### Referência\n", + "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n", + "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n", + "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura!\n", + "* [A Beginner’s Guide to Random Forest Hyperparameter Tuning](https://www.analyticsvidhya.com/blog/2020/03/beginners-guide-random-forest-hyperparameter-tuning/) " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XOa9naju6FKA" + }, + "source": [ + "# Dicionário de Hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_RF= {'bootstrap': [True, False],\n", + " 'max_depth': [10, 20, 30, 40, 50, 70, 90, 100, None],\n", + " 'max_features': ['auto', 'sqrt'],\n", + " 'min_samples_leaf': [1, 2, 4],\n", + " 'min_samples_split': [2, 5, 10],\n", + " 'n_estimators': [200, 400, 600, 800, 1000, 1500, 2000]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KP5oHFGjF3ii" + }, + "source": [ + "d_hiperparametros_RF" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6__f2jZaTQat" + }, + "source": [ + "# Invoca a função\n", + "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_hiperparametros_RF, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "crfn-n--KG4n" + }, + "source": [ + "### Resultado da execução do Random Forest\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SGTOe5PaRw59" + }, + "source": [ + "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "\n", + "ml_RF3= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2HwM8hbuRSx_" + }, + "source": [ + "ml_RF3.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWNiy7Z0TQa3" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* 2 formas:\n", + " * Usando a função seleciona_colunas_relevantes() que seleciona baseado no threshold;\n", + " * Usando modelo.feature_importances_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qqXvO7wePWRg" + }, + "source": [ + "### Preditoras mais importantes pelo modelo.feature_importances_" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "l3m6QfTiQ0E8" + }, + "source": [ + "sum(ml_RF3.feature_importances_) # Soma das importâncias das colunas = 100%" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mczpm2-NRmAr" + }, + "source": [ + "ml_RF3.feature_importances_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fRPuq2g3PtmN" + }, + "source": [ + "df_importantes = pd.DataFrame(zip(X_treinamento.columns, ml_RF3.feature_importances_), columns = ['coluna', 'importancia'])\n", + "df_importantes.sort_values(by = 'importancia', ascending = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vgxPCnphc6r_" + }, + "source": [ + "Vamos selecionar as 7 preditoras mais importantes: v13, v11, v7, v12, v14, v16 e v1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOi11YOKTQa4" + }, + "source": [ + "# Deletar as preditoras que não são importantes:\n", + "X_treinamento_RF = X_treinamento.drop(columns = ['v5', 'v2', 'v15', 'v3', 'v17', 'v9', 'v10', 'v6', 'v8', 'v4', 'v18'], axis = 1)\n", + "X_teste_RF = X_teste.drop(columns = ['v5', 'v2', 'v15', 'v3', 'v17', 'v9', 'v10', 'v6', 'v8', 'v4', 'v18'], axis = 1)\n", + "X_treinamento_RF.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zn_O7c_DTQbE" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UwEOwzSGTQbF" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Rr8qDrgvTQbL" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_RF3.fit(X_treinamento_RF, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_RF3, X_treinamento_RF, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-mYfQLlsTQbQ" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sSD5o1JQTQbR" + }, + "source": [ + "y_pred_RF = ml_RF3.predict(X_teste_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wywF6LymDzKr" + }, + "source": [ + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_RF)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hJJsL0IJb6iO" + }, + "source": [ + "## Estudo do comportamento dos hiperparâmetros do algoritmo\n", + "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ytRCEWjrjEQd" + }, + "source": [ + "from sklearn.model_selection import validation_curve" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YhY94cKcjnny" + }, + "source": [ + "### Efeito em n_estimators" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_1--fbI7fQR_" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name = \"n_estimators\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n", + "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc = \"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U60YOyRLjYsE" + }, + "source": [ + "#### Efeito de max_depth" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rv7TIM9kjsud" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name = \"max_depth\", \n", + " param_range = param_range, \n", + " cv = i_CV, \n", + " scoring = \"accuracy\", \n", + " n_jobs = -1)\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hyqgm6GzjUd5" + }, + "source": [ + "#### Efeito de min_samples_leaf" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lm_fPGYwkJYc" + }, + "source": [ + "param_range = np.arange(1, 250, 2)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_leaf', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Ox_t7NljNmq" + }, + "source": [ + "#### Efeito de min_samples_split" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CAqdiSaVlAB8" + }, + "source": [ + "param_range = np.arange(0.05, 1, 0.05)\n", + "\n", + "# Calculate accuracy on training and test set using range of parameter values\n", + "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n", + " X_treinamento, \n", + " y_treinamento, \n", + " param_name='min_samples_split', \n", + " param_range=param_range,\n", + " cv = i_CV, \n", + " scoring=\"accuracy\", \n", + " n_jobs=-1)\n", + "\n", + "\n", + "# Calculate mean and standard deviation for training set a_scores_CV\n", + "train_mean = np.mean(train_a_scores_CV, axis = 1)\n", + "train_std = np.std(train_a_scores_CV, axis = 1)\n", + "\n", + "# Calculate mean and standard deviation for test set a_scores_CV\n", + "test_mean = np.mean(test_a_scores_CV, axis = 1)\n", + "test_std = np.std(test_a_scores_CV, axis = 1)\n", + "\n", + "# Plot mean accuracy a_scores_CV for training and test sets\n", + "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n", + "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n", + "\n", + "# Plot accurancy bands for training and test sets\n", + "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n", + "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n", + "\n", + "# Create plot\n", + "plt.title(\"Validation Curve With Random Forest\")\n", + "plt.xlabel(\"Number Of Trees\")\n", + "plt.ylabel(\"Accuracy Score\")\n", + "plt.tight_layout()\n", + "plt.legend(loc=\"best\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y1q5cOJHV3HI" + }, + "source": [ + "### Exercício: LabData\n", + "* https://www.kaggle.com/c/labdata-churn-challenge-2020" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NeCCAwqVVmKA" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N_1A6lC9SF53" + }, + "source": [ + "# **BOOTSTRAPPING METHODS**\n", + "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n", + "\n", + "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cX_gfsbQSdNd" + }, + "source": [ + "___\n", + "# **BOOSTING MODELS**\n", + "* São algoritmos muito utilizados nas competições do Kaggle;\n", + "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n", + "* Modelos:\n", + " - [X] AdaBoost\n", + " - [X] XGBoost\n", + " - [X] LightGBM\n", + " - [X] GradientBoosting\n", + " - [X] CatBoost\n", + "\n", + "## Bagging vs Boosting\n", + "### **Bagging**\n", + "* **Objetivo**: é reduzir a variância;\n", + "* **Vantagens**:\n", + " * Reduz overfitting;\n", + " * Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + " * Lida automaticamente com Missing Values;\n", + "* **Desvantagens**:\n", + " * A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n", + "\n", + "### **Boosting**\n", + "* **Objetivo**: é melhorar acurácia;\n", + "* **Vantagens**:\n", + " * Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n", + " * Lida automaticamente com Missing Values;\n", + "* **Desvantagens**:\n", + " * Propenso a overfitting. Recomenda-se tratar outliers previamente.\n", + " * Requer ajuste cuidadoso dos hyperparameters;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FqJV-QGFQx90" + }, + "source": [ + "#### **Bagging**: Como funciona\n", + "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n", + "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n", + "\n", + "![Bagging](https://github.com/MathMachado/Materials/blob/master/Bagging.png?raw=true)\n", + "\n", + "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_treinamento;\n", + " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n", + " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n", + " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EysHMsU9Q6nQ" + }, + "source": [ + "___\n", + "#### **Boosting**: Como funciona\n", + "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n", + "\n", + "![Boosting](https://github.com/MathMachado/Materials/blob/master/Boosting.png?raw=true)\n", + "\n", + "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n", + ".\n", + "\n", + "#### Steps\n", + "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n", + " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_treinamento;\n", + " 2. Boosting treina o classificador C1;\n", + " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_treinamento e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n", + " 4. Boosting encontra em X_treinamento a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n", + " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SyqazmUuifkE" + }, + "source": [ + "___\n", + "# **ADABOOST(Adaptive Boosting)**\n", + "* Foi um dos primeiros algoritmos de Boosting (1995);\n", + "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n", + "* AdaBoost usam algoritmos DecisionTree como base_estimator;\n", + "* É um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n", + " * AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n", + "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RU-vzkXqrFVw" + }, + "source": [ + "## Referências\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n", + "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n", + "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n", + "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n", + "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6EMrjQDZIMl_" + }, + "source": [ + "## Hiperparâmetros mais importantes do AdaBoost:\n", + "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Pode-se utilizar diferentes algoritmos para esse fim.\n", + "* n_estimators - Número de base_estimator para treinar iterativamente.\n", + "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TzLtHzWNJBix" + }, + "source": [ + "## Usando diferentes algoritmos para base_estimator\n", + "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n", + "\n", + "\n", + "```\n", + "# Importar a biblioteca base_estimator\n", + "from sklearn.svm import SVC\n", + "\n", + "# Treina o classificador (algoritmo)\n", + "ml_SVC= SVC(probability=True, kernel='linear')\n", + "\n", + "# Constroi o modelo AdaBoost\n", + "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hrj4a4s6hMMB" + }, + "source": [ + "## Vantagens\n", + "* AdaBoost é fácil de implementar;\n", + "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n", + "* Faz o Feature Selection automaticamente (**Porque**?);\n", + "* Pode-se usar muitos algoritos como base_estimator ;\n", + "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n", + "\n", + "## Desvantagens\n", + "* AdaBoost é sensível a ruídos nos dados;\n", + "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n", + "* AdaBoost é mais lento que XGBoost;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bgJmu7YLiyv7" + }, + "source": [ + "O exemplo a seguir usa RandomForestClassifier com os hiperparâmetros otimizados, ou seja:\n", + "\n", + "```\n", + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5VCRNyZT3qvc" + }, + "source": [ + "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1gIboJdriq61" + }, + "source": [ + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "\n", + "# Instancia RandomForestClassifier - Hiperparâmetros otimizados!\n", + "ml_RF4 = RandomForestClassifier(bootstrap= best_params['bootstrap'], \n", + " max_depth= best_params['max_depth'], \n", + " max_features= best_params['max_features'], \n", + " min_samples_leaf= best_params['min_samples_leaf'], \n", + " min_samples_split= best_params['min_samples_split'], \n", + " n_estimators= best_params['n_estimators'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2v9F-N2STPes" + }, + "source": [ + "# Instancia AdaBoostClassifier\n", + "ml_AB = AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF4, random_state = i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sdvkTlxkTRS_" + }, + "source": [ + "# Treina...\n", + "ml_AB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tBOuTywWRm91" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_AB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7Ce5L38ECoC" + }, + "source": [ + "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento) com std na ordem dos 2,54%. A seguir, tentativa de melhorar o modelo com GridSearch." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t5GfnBwEifkO" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q9rSpuXyEPA5" + }, + "source": [ + "# Faz predições com os hiperparâmetros otimizados...\n", + "y_pred = ml_AB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2F9k-_eXGDLa" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XweWTjQ9EXLw" + }, + "source": [ + "## Parameter tunning" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fcrKzse9EbL_" + }, + "source": [ + "# Dicionário de hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_AB = {'n_estimators': [50, 100, 200], 'learning_rate': [.001, 0.01, 0.05, 0.1, 0.3,1]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Susc3I7mFDQX" + }, + "source": [ + "# Invoca a função\n", + "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_hiperparametros_AB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4JjWsusjNS8" + }, + "source": [ + "___\n", + "# **GRADIENT BOOSTING**\n", + "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n", + "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n", + "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. \n", + " * Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n", + " * O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n", + " * Gradient boosting usam algoritmos DecisionTree como base_estimator;\n", + "\n", + "## Vantagens\n", + "* Não há necessidade de pre-processing;\n", + "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n", + "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n", + "\n", + "## Desvantagens\n", + "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n", + " * Tratar os outliers previamente OU\n", + " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n", + "* Computacionalmene caro: geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n", + "* Devido à flexibilidade (muitos hiperparâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hiperparâmetros;\n", + "\n", + "## Referências\n", + "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n", + "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n", + "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n", + "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n", + "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n", + "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q4bUCZs2jNTA" + }, + "source": [ + "from sklearn.ensemble import GradientBoostingClassifier\n", + "\n", + "# Instancia...\n", + "ml_GB = GradientBoostingClassifier(n_estimators = 100, min_samples_split = 2)\n", + "\n", + "# Treina... \n", + "ml_GB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "PKOG1ugSRvLM" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VlC3y3M5YaGG" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vnLvQ0ZDYNjB" + }, + "source": [ + "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento) e std na ordem dos 2,52%. A seguir, tentativa de melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D2n1RKZuXq3D" + }, + "source": [ + "# Faz precições...\n", + "y_pred = ml_GB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8r6JCzQRGFa0" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFv-Q2AD5uCk" + }, + "source": [ + "## Parameter tunning\n", + "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os hiperparâmetros, significado e etc." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wgU040AcjNTF" + }, + "source": [ + "# Dicionário de hiperparâmetros para o parameter tunning.\n", + "d_hiperparametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n", + "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n", + "# 'max_depth': [5, 10, 15, 20, 25, 30],\n", + "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n", + "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n", + "# 'max_features': list(range(1, X_treinamento.shape[1]))}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v5KLFlpTjNTH" + }, + "source": [ + "# Invoca a função\n", + "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_hiperparametros_GB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQ6ERz3fi9i2" + }, + "source": [ + "### Resultado da execução do Gradient Boosting" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RSa7uKw13mKG" + }, + "source": [ + "```\n", + "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n", + "\n", + "Hiperparâmetros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wiJpA2PyjDjR" + }, + "source": [ + "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n", + "\n", + "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + "# max_depth= best_params['max_depth'],\n", + "# max_features= best_params['max_features'],\n", + "# min_samples_leaf= best_params['min_samples_leaf'],\n", + "# min_samples_split= best_params['min_samples_split'],\n", + "# n_estimators= best_params['n_estimators'],\n", + "# random_state= i_Seed)\n", + "\n", + "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n", + " max_depth= best_params['max_depth'],\n", + " min_samples_leaf= best_params['min_samples_leaf'],\n", + " min_samples_split= best_params['min_samples_split'],\n", + " n_estimators= best_params['n_estimators'],\n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mb14gJ7-jbVM" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TAqGZIFYm2sU" + }, + "source": [ + "X_treinamento_GB, X_teste_GB = seleciona_colunas_relevantes(ml_GB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yiu6dahnBvC" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "APrtWN18nc4t" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VS0mLdOmnXAY" + }, + "source": [ + "# Treina com as COLUNAS relevantes\n", + "ml_GB2.fit(X_treinamento_GB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_GB2, X_treinamento_GB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vmc9PP_Rn1TN" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e3mnIALvnzP2" + }, + "source": [ + "y_pred_GB = ml_GB2.predict(X_teste_GB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_GB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwP9Z2GnkV7r" + }, + "source": [ + "___\n", + "# **XGBOOST (eXtreme Gradient Boosting)**\n", + "* XGBoost é uma melhoria de Gradient Boosting. \n", + " * As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n", + "* Um dos algoritmo preferido pelos Kaggle Grandmasters;\n", + "* Paralelizável;\n", + "* Estado-da-arte em termos de Machine Learning;\n", + "\n", + "## Hiperparâmetros relevantes e seus valores iniciais\n", + "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os hiperparâmetros, significado e etc.\n", + "\n", + "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n", + "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n", + "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n", + "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n", + "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n", + "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n", + "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n", + "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n", + "* objective: Define a \"loss function\". As opções são:\n", + " * reg:linear - Para resolver problemas de regressão;\n", + " * reg:logistic - Para resolver problemas de classificação;\n", + " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n", + "\n", + "# Referências\n", + "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n", + "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n", + "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n", + "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n", + "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n", + "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n", + "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n", + "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n", + "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n", + "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n", + "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n", + "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n", + "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iMM_R4_ukV7x" + }, + "source": [ + "from xgboost import XGBClassifier\n", + "import xgboost as xgb\n", + "\n", + "# Instancia...\n", + "ml_XGB = XGBClassifier(silent = False, \n", + " scale_pos_weight=1,\n", + " learning_rate=0.01, \n", + " colsample_bytree = 1,\n", + " subsample = 0.8,\n", + " objective='binary:logistic', \n", + " n_estimators=1000, \n", + " reg_alpha = 0.3,\n", + " max_depth= 3, \n", + " gamma=1, \n", + " max_delta_step=5)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E4wQMlDEFINR" + }, + "source": [ + "# Treina...\n", + "ml_XGB.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S77LljiQR_16" + }, + "source": [ + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB, X_treinamento, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JNyKX6PkrXOk" + }, + "source": [ + "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento) e std na ordem dos 2,02%. Na sequência, tentativa de melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_h0QYv3FkV73" + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AKhhAZLjkV76" + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_XGB.predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ir2Kd1PqGHgz" + }, + "source": [ + "# Confusion Matrix\n", + "cf_matrix = confusion_matrix(y_teste, y_pred)\n", + "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n", + "cf_categories = ['Zero', 'One']\n", + "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jEC7gW4qYpWw" + }, + "source": [ + "## Parameter tunning\n", + "### Leitura Adicional:\n", + "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n", + "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n", + "\n", + "> Olhando para os resultados acima, qual o melhor modelo?\n", + "\n", + "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos hiperparâmetros do modelo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n3MsUONPwIV9" + }, + "source": [ + "# Dicionário de Hiperparâmetros para XGBoost:\n", + "d_hiperparametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n", + "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n", + "# 'subsample': [0.6, 0.8, 1.0],\n", + "# 'colsample_bytree': [0.6, 0.8, 1.0],\n", + "# 'max_depth': [3, 4, 5, 7, 9],\n", + "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CX27FCKmwSni" + }, + "source": [ + "# Invoca a função\n", + "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_hiperparametros_XGB, X_treinamento, y_treinamento, X_teste, y_teste, i_CV, l_colunas)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9b7uCuF74Hjv" + }, + "source": [ + "### Resultado da execução do XGBoostClassifier\n", + "\n", + "```\n", + "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n", + "\n", + "Hiperparâmetros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n7E0oyxEtbGi" + }, + "source": [ + "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n", + "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n", + "\n", + "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n", + " gamma= best_params['gamma'], \n", + " subsample= best_params['subsample'], \n", + " colsample_bytree= best_params['colsample_bytree'], \n", + " max_depth= best_params['max_depth'], \n", + " learning_rate= best_params['learning_rate'], \n", + " random_state= i_Seed)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CuqyLHTU5Z-j" + }, + "source": [ + "## Selecionar as COLUNAS importantes/relevantes\n", + "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QPG3JZIpRZ-T" + }, + "source": [ + "# plot feature importance\n", + "from xgboost import plot_importance\n", + "\n", + "xgb.plot_importance(ml_XGB2, color = 'red')\n", + "plt.title('importance', fontsize = 20)\n", + "plt.yticks(fontsize = 10)\n", + "plt.ylabel('features', fontsize = 20)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EmpRC2lHW-KP" + }, + "source": [ + "ml_XGB2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4f9MIEBiyq-5" + }, + "source": [ + "X_treinamento_XGB, X_teste_XGB= seleciona_colunas_relevantes(ml_XGB2, X_treinamento, X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F6EayWaY5nMm" + }, + "source": [ + "## Treina o classificador com as COLUNAS relevantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Huy18gKI5qad" + }, + "source": [ + "best_params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "E3-PaTdc5vZk" + }, + "source": [ + "# Treina com as COLUNAS relevantes...\n", + "ml_XGB2.fit(X_treinamento_XGB, y_treinamento)\n", + "\n", + "# Cross-Validation com 10 folds\n", + "a_scores_CV = funcao_cross_val_score(ml_XGB2, X_treinamento_XGB, y_treinamento, i_CV)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBdYikDU6NhD" + }, + "source": [ + "## Valida o modelo usando o dataframe X_teste" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GcvY-VdL6VIZ" + }, + "source": [ + "y_pred_XGB = ml_XGB2.predict(X_teste_XGB)\n", + "\n", + "# Calcula acurácia\n", + "accuracy_score(y_teste, y_pred_XGB)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8oLtdH-vTSbC" + }, + "source": [ + "xgb.to_graphviz(ml_XGB2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czXQG3MCHfHM" + }, + "source": [ + "# KNN - KNEIGHBORSCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "llTTXNeyHiwx" + }, + "source": [ + "# BAGGINGCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fbkekd4QHoZO" + }, + "source": [ + "# EXTRATREESCLASSIFIER" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "widavwR4HzwE" + }, + "source": [ + "# SVM" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "id_Ubulns6We" + }, + "source": [ + "# NAIVE BAYES" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwWkjfC8KEZH" + }, + "source": [ + "# ENSEMBLE METHODS\n", + "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n", + "\n", + "![Ensemble](https://github.com/MathMachado/Materials/blob/master/Ensemble.png?raw=true)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ycu_EIGlYUYn" + }, + "source": [ + "import pandas as pd\n", + "\n", + "from xgboost import XGBClassifier\n", + "from sklearn.ensemble import ExtraTreesClassifier\n", + "from sklearn.tree import ExtraTreeClassifier\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.ensemble import GradientBoostingClassifier\n", + "from sklearn.ensemble import BaggingClassifier\n", + "from sklearn.ensemble import AdaBoostClassifier\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "clfs = [XGBClassifier(), LGBMClassifier(), \n", + " ExtraTreesClassifier(), ExtraTreeClassifier(),\n", + " BaggingClassifier(), DecisionTreeClassifier(),\n", + " GradientBoostingClassifier(), LogisticRegression(),\n", + " AdaBoostClassifier(), RandomForestClassifier()]\n", + "\n", + "for clf in clfs:\n", + " try:\n", + " _ = mostra_feature_importances(clf, X_treinamento, y_treinamento, top_n = X_treinamento.shape[1], title=clf.__class__.__name__)\n", + " except AttributeError as e:\n", + " print(e)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtoJVI4Pyx3I" + }, + "source": [ + "# **IMBALANCED SAMPLE**\n", + "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n", + "\n", + "## Exemplo: Detectar fraude\n", + "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n", + "\n", + "## Necessidade de se usar outras métricas \n", + "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n", + "\n", + "## Como lidar com a amostra desbalanceada?\n", + "* Under-sampling\n", + "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n", + "\n", + "* Over-sampling\n", + "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2o45zx8zw-aB" + }, + "source": [ + "## EFEITOS DA AMOSTRA DESBALANCEADA" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCVTPCB-Xkbd" + }, + "source": [ + "# TPOT\n", + "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ulXii6JXpWd" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_TWUq-z4X4yZ" + }, + "source": [ + "___\n", + "# FEATURETOOLS\n", + "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n", + "\n", + "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n", + "\n", + "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "igHfzeA1Y90p" + }, + "source": [ + "# Picaret" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWiahwKe2d6U" + }, + "source": [ + "# **EXERCÍCIOS**\n", + "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XbSLkbDB2mzK" + }, + "source": [ + "## Exercício 1 - Credit Card Fraud Detection\n", + "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n", + "\n", + "### Leitura suporte\n", + "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n", + "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n", + "\n", + "### Dataframe\n", + "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lAl9ZwP_0-d0" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv'\n", + "df_cc = pd.read_csv(url)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oYgK6JXd3MgA" + }, + "source": [ + "## Exercício 2 - Predicting species on IRIS dataset\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "si0rsJvu3O6O" + }, + "source": [ + "from sklearn import datasets\n", + "import xgboost as xgb\n", + "\n", + "iris = datasets.load_iris()\n", + "X_iris = iris.data\n", + "y_iris = iris.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zom8t4yWC_UC" + }, + "source": [ + "## Exercício 3 - Predict Wine Quality\n", + "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n", + "\n", + "* 95–100 Classic: a great wine\n", + "* 90–94 Outstanding: a wine of superior character and style\n", + "* 85–89 Very good: a wine with special qualities\n", + "* 80–84 Good: a solid, well-made wine\n", + "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n", + "* 50–74 Not recommended\n", + "\n", + "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "klL2Q9Ria96n" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Wine = datasets.load_wine()\n", + "X_vinho = Wine.data\n", + "y_vinho = Wine.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lhVhSWBgGijq" + }, + "source": [ + "## Exercício 4 - Predict Parkinson\n", + "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SVCxHqv0VBJn" + }, + "source": [ + "## Exercício 5 - Predict survivors from Titanic tragedy\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CwvB8us4eKNi" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "df_titanic = sns.load_dataset('titanic')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZJrT9YIXVdtx" + }, + "source": [ + "## Exercício 6 - Predict Loan\n", + "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n", + "\n", + "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R8-GVu7ZWeA8" + }, + "source": [ + "## Exercício 7 - Predict the sales of a store.\n", + "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n", + "* Dataframes\n", + " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n", + " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fv9w86j4Wnwj" + }, + "source": [ + "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n", + "> Predict the median value of owner occupied homes." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5HYRt8-ug1BT" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn import datasets\n", + "\n", + "Boston = datasets.load_boston()\n", + "X_boston = Boston.data\n", + "y_boston = Boston.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UDIaqmtXQ0T" + }, + "source": [ + "## Exercício 9 - Predict the height or weight of a person.\n", + "\n", + "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-7R146nIXmMT" + }, + "source": [ + "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n", + "\n", + "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n", + "\n", + "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mQ8FPbuLZlIh" + }, + "source": [ + "## Exercício 11 - Predict the income class of US population.\n", + "\n", + "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Af4NRrchgPlM" + }, + "source": [ + "## Exercício 12 - Predicting Cancer\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c4LOlgZW3P40" + }, + "source": [ + "from sklearn import datasets\n", + "cancer = datasets.load_breast_cancer()\n", + "X_cancer = cancer.data\n", + "y_cancer = cancer.target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "74PmpT8Ix0tD" + }, + "source": [ + "## Exercício 13\n", + "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WY8GZMixZ9W9" + }, + "source": [ + "## Exercício 14 - Predict Diabetes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y92t6tbOge0S" + }, + "source": [ + "from sklearn import datasets\n", + "Diabetes= datasets.load_diabetes()\n", + "\n", + "X_diabetes = Diabetes.data\n", + "y_diabetes = Diabetes.target" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git "a/Notebooks/NB15_02__Regress\303\243o Linear_hs.ipynb" "b/Notebooks/NB15_02__Regress\303\243o Linear_hs.ipynb" new file mode 100644 index 000000000..011db45d3 --- /dev/null +++ "b/Notebooks/NB15_02__Regress\303\243o Linear_hs.ipynb" @@ -0,0 +1,5928 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "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.1" + }, + "colab": { + "name": "NB15_02__Regressão Linear.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwQDhId7N6_r" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

\n", + "

APRENDIZAGEM SUPERVISIONADA

\n", + "

MODELOS DE REGRESSÃO (LINEAR E LOGÍSTICA)

\n", + "\n", + "Fonte: https://realpython.com/linear-regression-in-python/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PN-dQFJcM1UV" + }, + "source": [ + "Passos para implementação da Regressão Linear:\n", + "\n", + "* (1) Importar as libraries necessárias;\n", + "* (2) Carregar os dados;\n", + "* (3) Aplicar as transformações necessárias: outliers, NaN's, normalização (MinMaxScaler, RobustScaler, StandarScaler, Log, Box-Cox e etc);\n", + "* (4) DataViz dos dados: entender os relacionamentos, distribuições e etc presente nos dados;\n", + "* (5) Construir e treinar o modelo preditivo (neste caso, modelo de regressão);\n", + "* (6) Validar/verificar as métricas para avaliação do(s) modelo(s);\n", + "* (7) Predições." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8TldGZxAFV5E" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0QRbxlqaq7pr" + }, + "source": [ + "# Melhorias da sessão:\n", + "* " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P4sAIblOgFyL" + }, + "source": [ + "# Modelos de Regressão com Regularization para Classificação e Regressão" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7Y7cuJNgFyU" + }, + "source": [ + "## Regressão Linear Simples (usando OLS - Ordinary Least Squares)\n", + "\n", + "* Features $X_{np}$: é uma matriz de dimensão nxp contendo os atributos/variáveis preditoras do dataframe (variáveis independentes);\n", + "* Variável target/dependente representada por y;\n", + "* Relação entre X e y é representado pela equação abaixo, onde $w_{i}$ representa os pesos de cada coeficiente e $w_{0}$ representa o intercepto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NpJ580y9gFyU" + }, + "source": [ + "\n", + "\n", + "![X_y](https://github.com/MathMachado/Materials/blob/master/Architecture.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rhbVGJ0gFyY" + }, + "source": [ + "* Soma de Quadrados dos Resíduos (RSS) - Soma de Quadrados das diferenças entre os valores observados e preditos.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u8gA0YkbgFyp" + }, + "source": [ + "## Principais parâmetros do algoritmo:\n", + "* fit_intercept - Indica se o intercepto $w_{0}$ deve ou não ser ajustado. Se os dados estão normalizados, então não faz sentido ajustar o intercepto $w_{0}$.\n", + "\n", + "* normalize - $X$ será automaticamente normalizada (subtrai a média e divide pelo desvio-padrão);\n", + "\n", + "## Atributos do modelo de Machine Learning para Regressão\n", + "* coef - peso/fator de cada variável independente do modelo de ML;\n", + "\n", + "* intercepto $w_{0}$ - intercepto ou viés de $y$;\n", + "\n", + "## Funções para ajuste do ML:\n", + "* fit - treina o modelo com as matrizes $X$ e $y$;\n", + "* predict - Uma vez que o modelo foi treinado, para um dado $X$, use $y$ para calcular os valores preditos de $y$ (y_pred).\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A-JG8El1gFy7" + }, + "source": [ + "# Limitações do OLS (Ordinary Least Squares):\n", + "* Impactado/sensível à Outliers;\n", + "* Multicolinearidade; \n", + "* Heterocedasticidade - apresenta-se como uma forte dispersão dos dados em torno de uma reta;\n", + "\n", + "* References" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xylMYR8COyrw" + }, + "source": [ + "### Importar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2BGgrILlPK6Z" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "263GgbwhO2kQ" + }, + "source": [ + "### Carregar os dados\n", + "* Vamos carregar o dataset [Boston House Pricing](https://archive.ics.uci.edu/ml/datasets/housing)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1h66x_-rXGhi" + }, + "source": [ + "from sklearn.datasets import load_boston, load_iris" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rWniNkMpXQFU", + "outputId": "4fd6cce0-22dc-43e0-b31a-effc991c8c69", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "boston = load_boston()\n", + "boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'DESCR': \".. _boston_dataset:\\n\\nBoston house prices dataset\\n---------------------------\\n\\n**Data Set Characteristics:** \\n\\n :Number of Instances: 506 \\n\\n :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\\n\\n :Attribute Information (in order):\\n - CRIM per capita crime rate by town\\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\\n - INDUS proportion of non-retail business acres per town\\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\\n - NOX nitric oxides concentration (parts per 10 million)\\n - RM average number of rooms per dwelling\\n - AGE proportion of owner-occupied units built prior to 1940\\n - DIS weighted distances to five Boston employment centres\\n - RAD index of accessibility to radial highways\\n - TAX full-value property-tax rate per $10,000\\n - PTRATIO pupil-teacher ratio by town\\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\\n - LSTAT % lower status of the population\\n - MEDV Median value of owner-occupied homes in $1000's\\n\\n :Missing Attribute Values: None\\n\\n :Creator: Harrison, D. and Rubinfeld, D.L.\\n\\nThis is a copy of UCI ML housing dataset.\\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\\n\\n\\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\\n\\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\\nprices and the demand for clean air', J. Environ. Economics & Management,\\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\\n...', Wiley, 1980. N.B. Various transformations are used in the table on\\npages 244-261 of the latter.\\n\\nThe Boston house-price data has been used in many machine learning papers that address regression\\nproblems. \\n \\n.. topic:: References\\n\\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\\n\",\n", + " 'data': array([[0.01, 18.00, 2.31, ..., 15.30, 396.90, 4.98],\n", + " [0.03, 0.00, 7.07, ..., 17.80, 396.90, 9.14],\n", + " [0.03, 0.00, 7.07, ..., 17.80, 392.83, 4.03],\n", + " ...,\n", + " [0.06, 0.00, 11.93, ..., 21.00, 396.90, 5.64],\n", + " [0.11, 0.00, 11.93, ..., 21.00, 393.45, 6.48],\n", + " [0.05, 0.00, 11.93, ..., 21.00, 396.90, 7.88]]),\n", + " 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n", + " 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTAT
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... RAD TAX PTRATIO B LSTAT\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 75 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQzFW7DUX_KW", + "outputId": "39ff2f0a-75ef-41c8-eba0-01f2fd56ac73", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Variável target/resposta\n", + "df_boston['preco'] = load_boston().target\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 76 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H71da4bIO4kI" + }, + "source": [ + "### Data Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K-6YOdsTfciO" + }, + "source": [ + "#### Normalização/padronização dos nomes das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L8OJEapufhq4" + }, + "source": [ + "# Renomear as colunas do dataframe\n", + "df_boston.columns = [col.lower() for col in df_boston.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uRinX-5ofol_", + "outputId": "b3b4003c-7f76-4779-8b53-23ca25c1d38d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... tax ptratio b lstat preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 78 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMDh5jyqekmr" + }, + "source": [ + "#### Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJIG0jJQf6em" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgYPzlvfemFc" + }, + "source": [ + "#### Missing values" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BAjw7UhJen0D", + "outputId": "9159a3f6-ef34-4507-91c3-19f8138230af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 272 + } + }, + "source": [ + "# Missing values por colunas/variáveis\n", + "df_boston.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "crim 0\n", + "zn 0\n", + "indus 0\n", + "chas 0\n", + "nox 0\n", + "rm 0\n", + "age 0\n", + "dis 0\n", + "rad 0\n", + "tax 0\n", + "ptratio 0\n", + "b 0\n", + "lstat 0\n", + "preco 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 79 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jo3UWNpbYnNF", + "outputId": "13a0c7e1-219f-42d1-ef65-d8603a2af1e0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Número de atributos\n", + "len(load_boston().feature_names)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "13" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 80 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0Yp8g7hxfQli", + "outputId": "6296d35e-e488-489d-bfad-489884473d40", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49 + } + }, + "source": [ + "# Missing Values por linhas\n", + "df_boston[df_boston.isnull().any(axis = 1)]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat, preco]\n", + "Index: []" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 81 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5qmkTFLrf9MT" + }, + "source": [ + "#### Estatísticas Descritivas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nprn3p_Wf_bn", + "outputId": "ac3fe2f6-7255-4257-9a6d-42ae210854f4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_boston.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
count506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000
mean3.61352411.36363611.1367790.0691700.5546956.28463468.5749013.7950439.549407408.23715418.455534356.67403212.65306322.532806
std8.60154523.3224536.8603530.2539940.1158780.70261728.1488612.1057108.707259168.5371162.16494691.2948647.1410629.197104
min0.0063200.0000000.4600000.0000000.3850003.5610002.9000001.1296001.000000187.00000012.6000000.3200001.7300005.000000
25%0.0820450.0000005.1900000.0000000.4490005.88550045.0250002.1001754.000000279.00000017.400000375.3775006.95000017.025000
50%0.2565100.0000009.6900000.0000000.5380006.20850077.5000003.2074505.000000330.00000019.050000391.44000011.36000021.200000
75%3.67708312.50000018.1000000.0000000.6240006.62350094.0750005.18842524.000000666.00000020.200000396.22500016.95500025.000000
max88.976200100.00000027.7400001.0000000.8710008.780000100.00000012.12650024.000000711.00000022.000000396.90000037.97000050.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "count 506.000000 506.000000 506.000000 ... 506.000000 506.000000 506.000000\n", + "mean 3.613524 11.363636 11.136779 ... 356.674032 12.653063 22.532806\n", + "std 8.601545 23.322453 6.860353 ... 91.294864 7.141062 9.197104\n", + "min 0.006320 0.000000 0.460000 ... 0.320000 1.730000 5.000000\n", + "25% 0.082045 0.000000 5.190000 ... 375.377500 6.950000 17.025000\n", + "50% 0.256510 0.000000 9.690000 ... 391.440000 11.360000 21.200000\n", + "75% 3.677083 12.500000 18.100000 ... 396.225000 16.955000 25.000000\n", + "max 88.976200 100.000000 27.740000 ... 396.900000 37.970000 50.000000\n", + "\n", + "[8 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 82 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JimyY3SgECE" + }, + "source": [ + "#### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jScHq7eTgIpm", + "outputId": "17d9046b-b44c-40f9-9cd6-7a0a602d26e3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 483 + } + }, + "source": [ + "correlacoes = df_boston.corr()\n", + "correlacoes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
crim1.000000-0.2004690.406583-0.0558920.420972-0.2192470.352734-0.3796700.6255050.5827640.289946-0.3850640.455621-0.388305
zn-0.2004691.000000-0.533828-0.042697-0.5166040.311991-0.5695370.664408-0.311948-0.314563-0.3916790.175520-0.4129950.360445
indus0.406583-0.5338281.0000000.0629380.763651-0.3916760.644779-0.7080270.5951290.7207600.383248-0.3569770.603800-0.483725
chas-0.055892-0.0426970.0629381.0000000.0912030.0912510.086518-0.099176-0.007368-0.035587-0.1215150.048788-0.0539290.175260
nox0.420972-0.5166040.7636510.0912031.000000-0.3021880.731470-0.7692300.6114410.6680230.188933-0.3800510.590879-0.427321
rm-0.2192470.311991-0.3916760.091251-0.3021881.000000-0.2402650.205246-0.209847-0.292048-0.3555010.128069-0.6138080.695360
age0.352734-0.5695370.6447790.0865180.731470-0.2402651.000000-0.7478810.4560220.5064560.261515-0.2735340.602339-0.376955
dis-0.3796700.664408-0.708027-0.099176-0.7692300.205246-0.7478811.000000-0.494588-0.534432-0.2324710.291512-0.4969960.249929
rad0.625505-0.3119480.595129-0.0073680.611441-0.2098470.456022-0.4945881.0000000.9102280.464741-0.4444130.488676-0.381626
tax0.582764-0.3145630.720760-0.0355870.668023-0.2920480.506456-0.5344320.9102281.0000000.460853-0.4418080.543993-0.468536
ptratio0.289946-0.3916790.383248-0.1215150.188933-0.3555010.261515-0.2324710.4647410.4608531.000000-0.1773830.374044-0.507787
b-0.3850640.175520-0.3569770.048788-0.3800510.128069-0.2735340.291512-0.444413-0.441808-0.1773831.000000-0.3660870.333461
lstat0.455621-0.4129950.603800-0.0539290.590879-0.6138080.602339-0.4969960.4886760.5439930.374044-0.3660871.000000-0.737663
preco-0.3883050.360445-0.4837250.175260-0.4273210.695360-0.3769550.249929-0.381626-0.468536-0.5077870.333461-0.7376631.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "crim 1.000000 -0.200469 0.406583 ... -0.385064 0.455621 -0.388305\n", + "zn -0.200469 1.000000 -0.533828 ... 0.175520 -0.412995 0.360445\n", + "indus 0.406583 -0.533828 1.000000 ... -0.356977 0.603800 -0.483725\n", + "chas -0.055892 -0.042697 0.062938 ... 0.048788 -0.053929 0.175260\n", + "nox 0.420972 -0.516604 0.763651 ... -0.380051 0.590879 -0.427321\n", + "rm -0.219247 0.311991 -0.391676 ... 0.128069 -0.613808 0.695360\n", + "age 0.352734 -0.569537 0.644779 ... -0.273534 0.602339 -0.376955\n", + "dis -0.379670 0.664408 -0.708027 ... 0.291512 -0.496996 0.249929\n", + "rad 0.625505 -0.311948 0.595129 ... -0.444413 0.488676 -0.381626\n", + "tax 0.582764 -0.314563 0.720760 ... -0.441808 0.543993 -0.468536\n", + "ptratio 0.289946 -0.391679 0.383248 ... -0.177383 0.374044 -0.507787\n", + "b -0.385064 0.175520 -0.356977 ... 1.000000 -0.366087 0.333461\n", + "lstat 0.455621 -0.412995 0.603800 ... -0.366087 1.000000 -0.737663\n", + "preco -0.388305 0.360445 -0.483725 ... 0.333461 -0.737663 1.000000\n", + "\n", + "[14 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 83 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AxQp7xqdgTJP" + }, + "source": [ + "##### Gráfico das correlações entre as features/variáveis/colunas\n", + "Source: https://seaborn.pydata.org/examples/many_pairwise_correlations.html\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KOiH2X-WgqmN", + "outputId": "31174dc1-d09b-4efc-a9be-96a72c98a8d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 557 + } + }, + "source": [ + "import seaborn as sns\n", + "from string import ascii_letters\n", + "import matplotlib.pyplot as plt\n", + "\n", + "sns.set_theme(style = \"white\")\n", + "\n", + "d = df_boston\n", + "\n", + "# Compute the correlation matrix\n", + "corr = d.corr()\n", + "\n", + "# Generate a mask for the upper triangle\n", + "mask = np.triu(np.ones_like(corr, dtype=bool))\n", + "\n", + "# Set up the matplotlib figure\n", + "f, ax = plt.subplots(figsize=(11, 9))\n", + "\n", + "# Generate a custom diverging colormap\n", + "cmap = sns.diverging_palette(230, 20, as_cmap=True)\n", + "\n", + "# Draw the heatmap with the mask and correct aspect ratio\n", + "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n", + " square=True, linewidths=.5, cbar_kws={\"shrink\": .5})" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 84 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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+PCqjgcAAGCEKv+cury8PAUEBKhhw4Y6f/68Vq9eLUnq2rWrPvjgA507d06lpaV69913XY+JiIhQamqqcnJyJElOp1NfffVVVUcFAACGsyyrUrfapMpH6sLDw/Xuu+8qMjJSjRo10p133qndu3frwQcf1I4dO/TII4+oQYMGCg0N1enTpyVJd911l37/+9/rt7/9rZxOp4qLi9WrVy/deuutVR0XAAAYjK8Juw433HCDXn311Qrv+81vfqPRo0ertLRUEydOVGhoqOu+Rx55RI888khVxwMAADCCrZ9TN3bsWB06dEiFhYXq3Lmzhg4damccAABgOIMH6uwtdX/+85/tPDwAAPAwdk2/njt3TuPHj9fXX38tb29vjR07Vt27dy+33T//+U/Nnz9f58+fd104GhcXd03H4BslAACAx7Dr4oeFCxcqICBAH374obKysjR48GBt2LBB/v7+ZbZr0qSJ/vKXv6hZs2Y6c+aMHn30Ud1+++268847r3qMKr/6FQAAwNOtX79eAwcOlCS1bdtWt956qzZt2lRuuy5duqhZs2aSpPr16ys4OFiHDh26pmMwUgcAADxGZQfq8vLyKvwChMDAQAUGBl7zfg4fPqybbrrJtdy8eXPXR7ddTmZmpnbu3KnExMRrOgalDgAAeIzKnlO3ePFizZs3r9z6+Ph4DRs2zLUcExOjw4cPV7iPzZs3Vy6kpGPHjun5559XQkKCa+Tuaih1AADAY1iqXKkbMmSIYmJiyq2/dJQuJSXlivtp0aKFDh06pKCgIEnSkSNHFBYWVuG2J0+e1K9+9Ss9++yz6t279zVnpdQBAACPUdnp18pOs15Or169tGLFCt12223KysrS7t279corr5Tb7ocfftCvfvUrDR48WLGxsZU6BhdKAAAAVLFnnnlGeXl56tmzp5577jklJSUpICBAkvTaa69p+fLlkqQ33nhDWVlZWrFihaKjoxUdHe36itWrYaQOAAB4DLs+p87Pz09z5syp8L7hw4e7fh47dqzGjh37k45BqQMAAB7Drs+pqw5MvwIAABjAyzK5sgIAAFzknzu/qdT2PUI7VFES9zN2+vWND7bZHUGS9OvIMB1Yt8ruGJKkNlGx6jt1id0xJElp4/9H3x48ancMSdLPWzZT94SFdseQJH2c+IyObP3U7hiSpOZ3d1PPpLfsjiFJ+nDSr+yO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KlaSFPmnt2xOIn3w4q/sjoBqwPQrAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAAaq81JWUlFT1IQAAADyez099YEhIiF544QV99NFHKiws1MiRIxUZGem6Lz4+Xp988onCw8P17LPPaurUqcrIyFBRUZHCwsI0fvx4eXt76+jRo3rppZeUlZUlSerTp4+ee+45nThxQgkJCfr+++8lSc8884z69et3/b8xAACAgX5yqZMkh8Oh1NRUfffdd3r88cd15513qnHjxpKkOnXqaPXq1ZKkiRMn6q677tL//u//qrS0VKNHj9bq1as1YMAAjR49Wt26ddPcuXMlSbm5uZKkl156ST//+c/15z//WceOHdOjjz6qTp06qUOHDtcTGQAAwEjXVepiY2MlSe3bt1enTp20c+dOPfjgg5KkmJgY13YbN27Url279NZbb0mSCgsL1axZMxUUFGjHjh2u9ZIUFBQkSdqyZYvGjRsnSWratKm6deumbdu2UeoAAAAqcF2l7kr8/PxcP1uWpfnz56tVq1ZltikoKKiqwwMAAHiU67pQ4sL0alZWlvbs2aPQ0NAKt4uIiNAbb7whp9Mp6ccp1uzsbPn7++sXv/iFFi1a5Nr2wvTrPffco5UrV0qSjh8/rk8//VR333339cQFAAAw1nWVOqfTqX79+um5555TUlKS63y6S02YMEEOh0PR0dHq27evnn32WR09elSSNHPmTH3xxRfq06ePHnnkEb3zzjuSpD/+8Y9KT09X3759FRcXp9GjR+vnP//59cQFAAAw1nVNv8bFxWnYsGHl1mdkZJRZDggIUGJiYoX7aNasmebPn19u/c9+9rMK1wMAAKA8PnwYAADAAD95pO7S0TgAAADYh5E6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAM4GVZlmV3CAAAAFwfRuoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqavA7t27NWrUKLtjVLno6GgVFhZW+nERERH65ptvqiBRzTomzBASEqKCgoKf/H63w7hx47R06VK37W/u3Lk6f/682/ZXncc/ePCgVqxYUWbd0KFD9f3337sjWjkX3i9V7WrHycvL04IFC655f3a/xqgZKHWXKCkp0W233aZXXnnF7ihVLjU1VXXr1rU7BtygpKTE7gg1np3vd7tfn3nz5qm4uLhGHv9qz82hQ4fKlboFCxaodevWbstXE+Xl5enNN9+85u2r6jW2+72LyvGxO0B127Fjh2bMmOH6L6QxY8Zo0qRJioqK0tatW9WhQwdFR0dr+vTpWrNmjQ4ePKj+/ftrwIAB+uyzz1RYWKiZM2cqOTlZX375perWrav58+erSZMmbsn36aefatasWa7lzMxMvfrqq5o7d666dOmiHTt2yMvLS7Nnz1ZwcPB1HSskJERffPGF/P39FRERoejoaG3evFnHjx9XXFycnnzySUnS9u3blZiYKEm66667dPHXBV+8j4uXHQ6Hxo4dq3379snHx0ft2rXTa6+9dk25KnqNJGn9+vV68cUXy+WbPn26Pv/8cxUXF6tRo0aaMmWKbrrpJp08eVKjRo3SyZMnJUn33HOPJkyY8JOfqxEjRujDDz/UqVOnNGbMGEVGRkqSNm3apFmzZsnpdCooKEhJSUlq1aqVnn32WXXr1k1DhgzRvn37NHToUC1fvlw33njjT8pQUab4+Hh98sknCg8PV05Ojnx9fZWVlaXs7Gz17NlT3bt319y5c5WTk6MhQ4ZoyJAhbjn2BaNGjdL+/ftVXFys1q1ba8qUKWrQoIFmz56tdevWqWHDhuratau2bNmiNWvWSJJSUlK0bNkyOZ1OBQQEaPLkyWrfvr3bMm3YsEGzZs1SnTp19NBDD7nWX3hv1qtXT0lJSdq6dat8fX3l5+en5ORktx3/4uNd/Pr07t1biYmJOnfunIqKijRgwAA9/fTTkqSjR49qzJgxOn78uG666SY5HO777+0Lf7uDBg2Sw+HQs88+q7fffttVAMaOHat77rlHJ0+eVGxsrF577TXddtttSklJ0cqVK7VkyRL5+Fz9/ypCQkL0wgsv6KOPPlJhYaFGjhypyMjIcsdfsmSJpkyZIm9vb+3fv18FBQVKTU297HspKSlJBw8eVHR0tNq0aaM5c+YoIiJCf/3rX9WhQwcdOHBAkyZNUm5urnx8fDRixAjdf//91/WcLVy4sNzvUVVKS0srfD8mJSXpzJkzio6OVr169ZScnKy//e1veu+99+R0OlWnTh1NnjxZHTt2rPA5DgwMvOJxL/d6Xbjv4vfus88+q6lTpyojI0NFRUUKCwvT+PHj5e3traNHj+qll15SVlaWJKlPnz567rnndOLECSUkJLhGVJ955hn169evyp5H/D+WB/nhhx+s//N//o/13//+17IsyyopKbFOnTplde/e3UpISHBtt3XrVismJsayLMvKzs62OnToYH388ceWZVnWggULrF/+8pfWnj17LMuyrISEBGvWrFlVknfFihXWwIEDrU8//dTq1KmT9fXXX1uWZVnz58+3Ro4ced3779Chg5Wfn29ZlmV1797dmjZtmmVZP/7OoaGhVn5+vlVUVGTdd9991tatWy3Lsqz33nvP6tChg5WRkVFuHxcvb9iwwYqLi3OtP3Xq1DVlutJrVFE+y7KskydPuh6/cuVK6/e//71lWZb11ltvWS+++GKlM1SkQ4cO1pIlSyzLsqzt27db9913n2VZlnXixAkrLCzM+vbbb13Hf+yxx1z3de/e3frPf/5j9enTx/UecpcOHTpYr7/+umt57Nix1qBBg6yioiLr7Nmz1t13322NGzfOcjqdVk5OTpnnzF0ufu5nzZplvfzyy9ZHH31k9e3b1yooKLCcTqf1wgsvuP6e/vOf/1hDhw61ioqKLMuyrE8++cQaOHCg2/IcP37c6tq1q5WZmWlZlmW98cYbrvfkhf/9+uuvrV69ellOp9OyrOt7X1zJpa/PmTNnXL93fn6+1bt3b2vfvn2WZVlWfHy8NXfuXMuyLOv777+3QkNDXe83d2W58Nrn5uZapaWllmVZVmZmphUeHu7abuvWrdZDDz1k7dixw3rggQesw4cPV+oYF36HzMxMq2vXrtaJEyfKHd+yfnyvxsTEWAUFBa51Fb2XLmS68P65oHv37q5/Bz322GPWypUrLcuyrG+//dbq2rVrmX1V1pV+D3e62vsxOzvb6tq1a5nHXPx7/fvf/7ZiY2PL7a8yx7/S63Xxe3fChAlWSkqKZVmW5XQ6rREjRlgrVqywLMuynnzySWvBggXlMg4fPtyaPXu2ZVmWdfToUevee+91vWaoOh41Urdz504FBwfrjjvukCR5e3urQYMGknTF/4Lw8/PTAw88IEnq3LmzbrzxRnXs2NG1vHnzZrdn/eyzz/TWW2/p73//u7799lu1a9dOnTp1kiSFhobq448/dvsxo6KiJEktW7ZUYGCgcnJyVFxcrHr16iksLMy1zaRJk666r1tuuUWZmZlKTExU165dXc/f1VzpNaooX3BwsDZt2qRly5bp7NmzZaYKunTpokWLFmn69Onq2rWr7rvvvmt+Lipy4fihoaE6duyYioqK9OWXX+qWW27RzTffLEnq37+/EhMTlZ+fr8aNG2vKlCkaMmSI/ud//uean4PKiImJKbPco0cP+fr6SpLatWunbt26yeFwqFmzZmWeM3dJTU1VWlqaiouLdfbsWbVt21bFxcXq3bu3/Pz8JP34tzV//nxJ0saNG5Wenq7Y2FhJkmVZysvLc1ueL7/8Up06dXKN/A0cOFAzZ84ss02rVq1UUlKiiRMnKiwsTN27d3fb8S918etTWFioyZMnKyMjQ15eXjp27JjS09MVHBysbdu26Y9//KMr3z333FNlmbKzszVq1CgdPXpUPj4+OnHihI4fP64mTZooLCxMffr00RNPPKF58+apefPmldr3hde1ffv26tSpk3bu3KkHH3ywwm179erleo9IFb+XriY/P1979+5V//79JUk333yzOnbsqJ07dyoiIqJS2X/q73G9KvN+/Oqrr/T666/r9OnT8vLyco2O/VRX+j0vfu9u3LhRu3bt0ltvvSXpx/dys2bNVFBQoB07drjWS1JQUJAkacuWLRo3bpwkqWnTpurWrZu2bdumDh06XFdmXJlHlborufhfLpe68H+SkuRwOMose3t7y+l0ujVLenq6EhIStHDhQtcfyKUZquI8hzp16rh+vtLv5eXlVWY76/9NxxYVFbnWt2rVSmvXrtXWrVu1adMmzZ49W2lpaWWO4Y58hw4d0tSpU/XOO++oVatW+uKLLzR69GhJ0i9+8QulpKRo8+bNSk1N1RtvvKHly5df9/G9vb0lXdu5Jnv37lWjRo2Uk5Pzk497JZe+by99jq71Nf0ptm/fruXLlys5OVlBQUFKS0vTypUrr/gYy7LUv39/DR8+3G05Kqt+/fp67733tG3bNm3evFkzZ85USkqK206huNjFr8+sWbPUpEkTTZs2TT4+PoqLiyvzN1NdRo4cqXHjxqlHjx4qLS1Vly5dyuTYs2ePgoKCquw9e8HFz81PeS+Z4nLvx0udP39ew4cP19KlS9W5c2cdPXr0uqeZr+Ti18eyLM2fP1+tWrUqs011XFCCyvGoCyVCQ0OVmZmpHTt2SJKcTqdOnz5tc6qyjh49qmHDhunll19Wu3bt7I6j9u3bq7CwUNu3b5ckvf/++2VGVlq3bq3du3dLktLS0lzrc3Jy5O3trR49emj8+PHKzc3VqVOnrnq8yr5G+fn5uuGGG9SkSROVlpaWOTcqOztbAQEBevjhhzV+/Hh9/fXXKi0trdwTcA1509PTlZmZKenH88U6deqkgIAA7dq1S0uXLlVqaqpyc3Ovq1DWRHl5eQoICFDDhg11/vx5rV69WpLUtWtXffDBBzp37pxKS0v17rvvuh4TERGh1NRUV2FwOp366quv3JYpNDRUe/bscY1grFq1qtw2ubm5OnfunMLDwzV69GjVr19f2dnZbstwOWfOnNGNN94oHx8fffPNN66/KUm6++67Xc9fdna2tmzZ4tZj+/v7Kz8/35WjZcuWkqTVq1eXuWJy0aJFKikp0Zo1a/Tmm29q7969lTrOhd8hKytLe/bsUWhoaLnjV+Ry7yVJCggIuOxjAwIC1LFjx//bvv27tK6GcQD/WlQKRpK2oCA6VBAHHSpYcKmCDgZJ1UFwcxAs1kEslkpaDbRdSlscdHMqCiKYSfwHXF0EXXRwEnEQOoho0TTnDmK4Pd5e9Vw9nhu/nzEheX/kDXnyvu9jBUHn5+c4PT21yv1V1drxGaqNR0EQUCqVrJ/Hh4cHGIZhzZ5ub29X3Oe1Pv4nb23n4OAgNjY2rJ/CYrGIi4sLNDQ0oKenB4VCoaI9wNMe5ufA/Pr6GgcHB+jr63tX/ej9vtVMnSRJWF9fRyaTwd3dnbWZ/0+yu7uLYrGIVCplHVNV9cvqU19fj9XV1YpEiZaWFuu8qqrQNA2NjY2QZdk6fnZ2ZmUQm6aJUCiE5ubmV8t77zPq7OyELMsYGRmBy+XCwMCA9bE8PDxEoVCAw+GAaZpIJpMfugEdeFpqyGaziEajMAwDbrcbuVwONzc3WFxcRCaTgcfjQT6fx+TkJHw+n7V0/38XCASwt7eH4eFhuFwu9Pb24uTkBENDQzg6OsLo6ChEUYTP57MCc7/fj4WFBYTDYZTLZTw+PkKWZXR3d39InTweD9LpNGZnZ+F0OisSJZ5dXV1hZWUFhmGgXC6jv7//Uz/az8LhMGKxGHRdh9frhd/vt84lEgnEYjHs7++jtbXV2u7wUaanpzE1NQWn0wlVVTE3NwdRFBEIBCBJEgDg+PgYm5ub0HUdbrcb6XQakUgEuq5DEIQ3lVMulzE+Po77+3ukUil4PJ4X5W9tbb24rtpYAp7eca/XC0VR0N7ejrW1tYpr8/k8NE1DoVBAbW0tstmstcLxq6q14zNUG48OhwPBYBDBYBCiKGJnZwfz8/OYmJiAJEkvkjd+7uPXEiWAt7czHo8jl8thbGwMNTU1qKurQzweR1tbG/L5PJLJJBRFgcPhgKIoCIVCWF5ehqZpCAaDAIBoNIqOjo7/3mH0r2p+/PhbKiMR0Qe4vb2FIAgwTROJRAJNTU2IRCJfXS36RD9nwtOfjc/Lnr7VTB0R/R5LS0u4vLxEqVRCV1cXZmZmvrpKRES2x5k6IiIiIhv4VokSRERERHbFoI6IiIjIBhjUEREREdkAgzoiIiIiG2BQR0RERGQDDOqIiIiIbOAvF2TfJBn+6VQAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nogPhyfVO70G" + }, + "source": [ + "### Construir e treinar o(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HxYpfyvQaIe1" + }, + "source": [ + "$X = [X_{1}, X_{2}, X_{p}]$ = X_boston abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BhLZJhibVNG" + }, + "source": [ + "X_boston = df_boston.drop(columns = ['preco'], axis = 1) # todas as variáveis/atributos, exceto 'preco'\n", + "y_boston = df_boston['preco'] # variável-target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_nC_RGva1Z6", + "outputId": "de1647e4-f836-40a5-a49a-a9a21dd5edca", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "X_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstat
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... rad tax ptratio b lstat\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 86 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nlVJM--Ya5fS", + "outputId": "6007a0f6-9709-4c93-a65a-85f16c578b71", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "y_boston[0:10] # Series (coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 24.0\n", + "1 21.6\n", + "2 34.7\n", + "3 33.4\n", + "4 36.2\n", + "5 28.7\n", + "6 22.9\n", + "7 27.1\n", + "8 16.5\n", + "9 18.9\n", + "Name: preco, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 87 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b50_6tv5h1kY" + }, + "source": [ + "# Definindo os dataframes de treinamento e teste:\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, \n", + " y_boston, \n", + " test_size = 0.2, \n", + " random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U3hpdkDbYTv", + "outputId": "5e71907d-eb8c-44f0-ce98-3c1ac56e6f82", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f\"Dataframe de treinamento: {X_treinamento.shape[0]} linhas\")\n", + "print(f\"Dataframe de teste......: {X_teste.shape[0]} linhas\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Dataframe de treinamento: 404 linhas\n", + "Dataframe de teste......: 102 linhas\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SvevXulFiJj1" + }, + "source": [ + "#### Treinamento do modelo de Regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GVwF3vp8iNff" + }, + "source": [ + "# Importa a library LinearRegression --> Para treinamento da Regressão Linear\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Library para statmodels\n", + "import statsmodels.api as sm" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ibX6bCbViW-v" + }, + "source": [ + "# Instancia o objeto\n", + "regressao_linear = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M-5wRGUribY0", + "outputId": "fde40bc7-3f51-4e11-bdba-978d7e3c3710", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Treina o modelo usando as amostras/dataset de treinamento: X_treinamento e y_treinamento \n", + "regressao_linear.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 92 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jri-jA1VjmUl", + "outputId": "e95d7477-f836-47d1-b300-a573d30c9cfd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Valor do intercepto\n", + "regressao_linear.intercept_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.9020918753502" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 93 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOjadxdxjqtT", + "outputId": "bf2f3507-81cd-4f2b-b0cc-27b043ff15b3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 452 + } + }, + "source": [ + "# Coeficientes do modelo de Regressão Linear\n", + "coeficientes_regressao_linear = pd.DataFrame([X_treinamento.columns, regressao_linear.coef_]).T\n", + "coeficientes_regressao_linear = coeficientes_regressao_linear.rename(columns={0: 'Feature/variável/coluna', 1: 'Coeficientes'})\n", + "coeficientes_regressao_linear" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Feature/variável/colunaCoeficientes
0crim-0.0822083
1zn0.0428002
2indus0.0756011
3chas3.16348
4nox-19.4945
5rm3.98161
6age0.00480929
7dis-1.37396
8rad0.298883
9tax-0.0123962
10ptratio-0.984657
11b0.008949
12lstat-0.526478
\n", + "
" + ], + "text/plain": [ + " Feature/variável/coluna Coeficientes\n", + "0 crim -0.0822083\n", + "1 zn 0.0428002\n", + "2 indus 0.0756011\n", + "3 chas 3.16348\n", + "4 nox -19.4945\n", + "5 rm 3.98161\n", + "6 age 0.00480929\n", + "7 dis -1.37396\n", + "8 rad 0.298883\n", + "9 tax -0.0123962\n", + "10 ptratio -0.984657\n", + "11 b 0.008949\n", + "12 lstat -0.526478" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 94 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwnkhPwDjkhS" + }, + "source": [ + "#### Usando statmodels" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ltbekHd_k3PH", + "outputId": "c1265a64-74b3-492d-8d13-04eaee9ade8b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 680 + } + }, + "source": [ + "X2_treinamento = sm.add_constant(X_treinamento)\n", + "lm_sm = sm.OLS(y_treinamento, X2_treinamento).fit()\n", + "print(lm_sm.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 78.97\n", + "Date: Tue, 27 Oct 2020 Prob (F-statistic): 1.48e-100\n", + "Time: 18:36:57 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2458.\n", + "Df Residuals: 390 BIC: 2514.\n", + "Df Model: 13 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.9021 6.037 5.947 0.000 24.033 47.771\n", + "crim -0.0822 0.045 -1.824 0.069 -0.171 0.006\n", + "zn 0.0428 0.016 2.638 0.009 0.011 0.075\n", + "indus 0.0756 0.072 1.054 0.292 -0.065 0.217\n", + "chas 3.1635 0.997 3.174 0.002 1.204 5.123\n", + "nox -19.4945 4.539 -4.295 0.000 -28.418 -10.571\n", + "rm 3.9816 0.510 7.802 0.000 2.978 4.985\n", + "age 0.0048 0.015 0.312 0.755 -0.025 0.035\n", + "dis -1.3740 0.236 -5.827 0.000 -1.838 -0.910\n", + "rad 0.2989 0.079 3.760 0.000 0.143 0.455\n", + "tax -0.0124 0.004 -2.814 0.005 -0.021 -0.004\n", + "ptratio -0.9847 0.156 -6.309 0.000 -1.292 -0.678\n", + "b 0.0089 0.003 2.796 0.005 0.003 0.015\n", + "lstat -0.5265 0.060 -8.764 0.000 -0.645 -0.408\n", + "==============================================================================\n", + "Omnibus: 140.799 Durbin-Watson: 2.083\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 591.650\n", + "Skew: 1.484 Prob(JB): 3.35e-129\n", + "Kurtosis: 8.132 Cond. No. 1.51e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.51e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kpt3A4Q0guHv" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVUJkfg4gSh7", + "outputId": "a620d85e-38ae-49a5-f5ea-bac502964bac", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 663 + } + }, + "source": [ + "X3 = X_treinamento.drop(columns = 'age', axis = 1)\n", + "X3_treinamento = sm.add_constant(X3)\n", + "lm_sm2 = sm.OLS(y_treinamento, X3_treinamento).fit()\n", + "print(lm_sm2.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 85.75\n", + "Date: Tue, 27 Oct 2020 Prob (F-statistic): 1.64e-101\n", + "Time: 18:36:57 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 391 BIC: 2508.\n", + "Df Model: 12 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.7325 6.006 5.950 0.000 23.925 47.540\n", + "crim -0.0815 0.045 -1.812 0.071 -0.170 0.007\n", + "zn 0.0422 0.016 2.623 0.009 0.011 0.074\n", + "indus 0.0750 0.072 1.048 0.295 -0.066 0.216\n", + "chas 3.1794 0.994 3.198 0.001 1.225 5.134\n", + "nox -19.1299 4.381 -4.367 0.000 -27.742 -10.517\n", + "rm 4.0153 0.498 8.059 0.000 3.036 4.995\n", + "dis -1.3963 0.224 -6.223 0.000 -1.837 -0.955\n", + "rad 0.2958 0.079 3.755 0.000 0.141 0.451\n", + "tax -0.0123 0.004 -2.802 0.005 -0.021 -0.004\n", + "ptratio -0.9812 0.156 -6.310 0.000 -1.287 -0.675\n", + "b 0.0090 0.003 2.825 0.005 0.003 0.015\n", + "lstat -0.5202 0.057 -9.203 0.000 -0.631 -0.409\n", + "==============================================================================\n", + "Omnibus: 142.363 Durbin-Watson: 2.081\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 608.694\n", + "Skew: 1.496 Prob(JB): 6.67e-133\n", + "Kurtosis: 8.216 Cond. No. 1.48e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.48e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lcp7m5FmZvG" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'indus'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jEiBywx4hGNB", + "outputId": "c283ddc3-1c44-4d53-e483-11c9034c1533", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 646 + } + }, + "source": [ + "X4 = X3_treinamento.drop(columns = 'indus', axis = 1)\n", + "X4_treinamento = sm.add_constant(X4)\n", + "lm_sm3 = sm.OLS(y_treinamento, X4_treinamento).fit()\n", + "print(lm_sm3.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.724\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 93.42\n", + "Date: Tue, 27 Oct 2020 Prob (F-statistic): 2.86e-102\n", + "Time: 18:36:57 Log-Likelihood: -1215.4\n", + "No. Observations: 404 AIC: 2455.\n", + "Df Residuals: 392 BIC: 2503.\n", + "Df Model: 11 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.4757 6.001 5.911 0.000 23.677 47.275\n", + "crim -0.0840 0.045 -1.871 0.062 -0.172 0.004\n", + "zn 0.0407 0.016 2.539 0.012 0.009 0.072\n", + "chas 3.2924 0.989 3.330 0.001 1.349 5.236\n", + "nox -17.9558 4.235 -4.239 0.000 -26.283 -9.629\n", + "rm 3.9674 0.496 7.996 0.000 2.992 4.943\n", + "dis -1.4553 0.217 -6.699 0.000 -1.882 -1.028\n", + "rad 0.2744 0.076 3.606 0.000 0.125 0.424\n", + "tax -0.0103 0.004 -2.603 0.010 -0.018 -0.003\n", + "ptratio -0.9609 0.154 -6.227 0.000 -1.264 -0.658\n", + "b 0.0089 0.003 2.778 0.006 0.003 0.015\n", + "lstat -0.5151 0.056 -9.145 0.000 -0.626 -0.404\n", + "==============================================================================\n", + "Omnibus: 142.123 Durbin-Watson: 2.073\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 605.868\n", + "Skew: 1.494 Prob(JB): 2.74e-132\n", + "Kurtosis: 8.202 Cond. No. 1.47e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.47e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFejox5XmrEE" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'crim'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DOehOql8hZWr", + "outputId": "12f9c9a0-b10f-4ad2-fcbd-c010eaea95bb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 629 + } + }, + "source": [ + "X5 = X4_treinamento.drop(columns = 'crim', axis = 1)\n", + "X5_treinamento = sm.add_constant(X5)\n", + "lm_sm4 = sm.OLS(y_treinamento, X5_treinamento).fit()\n", + "print(lm_sm4.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.721\n", + "Model: OLS Adj. R-squared: 0.714\n", + "Method: Least Squares F-statistic: 101.8\n", + "Date: Tue, 27 Oct 2020 Prob (F-statistic): 1.55e-102\n", + "Time: 18:36:57 Log-Likelihood: -1217.2\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 393 BIC: 2500.\n", + "Df Model: 10 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 33.9950 5.968 5.696 0.000 22.262 45.728\n", + "zn 0.0375 0.016 2.349 0.019 0.006 0.069\n", + "chas 3.3959 0.990 3.430 0.001 1.449 5.343\n", + "nox -17.1637 4.228 -4.060 0.000 -25.475 -8.852\n", + "rm 4.0365 0.496 8.132 0.000 3.061 5.012\n", + "dis -1.3999 0.216 -6.484 0.000 -1.824 -0.975\n", + "rad 0.2278 0.072 3.158 0.002 0.086 0.370\n", + "tax -0.0100 0.004 -2.513 0.012 -0.018 -0.002\n", + "ptratio -0.9493 0.155 -6.137 0.000 -1.253 -0.645\n", + "b 0.0101 0.003 3.217 0.001 0.004 0.016\n", + "lstat -0.5315 0.056 -9.523 0.000 -0.641 -0.422\n", + "==============================================================================\n", + "Omnibus: 140.245 Durbin-Watson: 2.070\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 609.563\n", + "Skew: 1.464 Prob(JB): 4.32e-133\n", + "Kurtosis: 8.257 Cond. No. 1.46e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.46e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UafIUrpZB0YP" + }, + "source": [ + "### Conclusão\n", + "* Quais variáveis/colunas/atributos ficam no modelo?\n", + "* **Muito importante (exercício)**: normalizar (MinMaxScaler) as covariáveis e refazer a análise.\n", + "* Nesta iteração (depois de excluirmos (nesta ordem) as variáveis age, indus e crim, não surge nenhuma outra variável insignificante ao nível de 5 (na verdade, o maior valor é 1.9%)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jx7sOzrrm-H_" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXeiFtnJO_1u" + }, + "source": [ + "### Validação do(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlGVFA6uPDvr" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PE3aKJ6mPDyJ" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3nGiyX8jadH" + }, + "source": [ + "### Deployment da solução **analítica**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YQF4NIlGSLH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UQfpoo1igFy8" + }, + "source": [ + "# Regularized Regression Methods \n", + "## Ridge Regression - Penalized Regression\n", + "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando (valor de $\\alpha$) os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n", + "* Menor impacto dos outliers.\n", + "\n", + "### Exemplo" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rVCtuvztS6gk" + }, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o00xH2MvxvgP" + }, + "source": [ + "# Matriz de covariáveis do modelo:\n", + "X_new = [[0, 0], [0, 0], [1, 1]]\n", + "y_new = [0, .1, 1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v9U7c03NzW_c", + "outputId": "5ac868a1-3985-4b81-e0c7-906dd6a28f37", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[[0, 0], [0, 0], [1, 1]]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 100 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iiVEAPpUzXyN", + "outputId": "1c600dce-e3f2-4720-a526-827f2698aa0d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 0.1, 1]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 101 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8mWj2GbPOkHx", + "outputId": "d98acd27-e45f-4a27-c726-7abef730474c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new, y_new)\n", + "ridge.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.44, 0.44])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 102 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0kD7Bsq_OkH1", + "outputId": "3101e945-41cb-4bd3-eefe-c374f6654982", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# treinando a regressão Ridge\n", + "ridge.fit(X_new, y_new)\n", + "\n", + "# treinando a regressão linear simples (OLS)\n", + "lr.fit(X_new, y_new)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 103 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "v9SNxnj42k6Y", + "outputId": "5973fa6f-f754-4e9f-b573-0afc861cce59", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[[0, 0], [0, 0], [1, 1]]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 104 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "utc-f86d2ne_", + "outputId": "28e5a75b-ad1d-42d4-fb79-e292d0475a2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 0.1, 1]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 105 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aUEyK4lygFy_", + "outputId": "cbbdae3b-741c-41c1-8c97-ac2becf713aa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ridge.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.44, 0.44])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 106 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qYRLUwIugFzC", + "outputId": "eb51b510-4979-49f6-ba9a-e1d85514ae18", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "lr.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.47, 0.47])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 107 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u5jsTkUmS9wK" + }, + "source": [ + "### Aplicação da Regressão Ridge no dataframe Boston Housing Price." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kp4VIJWxgFy8" + }, + "source": [ + "from sklearn.linear_model import Ridge\n", + "ridge = Ridge(alpha = 0.1) # Definição do valor de alpha da regressão ridge\n", + "lr = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cmRMoOwV6FMt", + "outputId": "2b81c12b-2be6-490e-f642-10565d18b99e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Ao inves de: regressao_linear.fit(X_treinamento, y_treinamento)\n", + "ridge.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Ridge(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=None,\n", + " normalize=False, random_state=None, solver='auto', tol=0.001)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 109 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VPnekyUbK6Xg" + }, + "source": [ + "#### Peso/contribuição das variáveis para a regressão usando RIDGE" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k83RDArjsUrj", + "outputId": "aa386a9b-8595-4fa7-fb9a-643828bb78c7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "df_boston.columns" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Index(['crim', 'zn', 'indus', 'chas', 'nox', 'rm', 'age', 'dis', 'rad', 'tax',\n", + " 'ptratio', 'b', 'lstat', 'preco'],\n", + " dtype='object')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 110 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vMCb0CFjK973", + "outputId": "92d03811-fb34-47f1-927c-6486e5bee39a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "ridge.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.08, 0.04, 0.07, 3.14, -18.00, 3.99, 0.00, -1.35, 0.30, -0.01,\n", + " -0.97, 0.01, -0.53])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 111 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZqksuIjXypRJ", + "outputId": "24457c5e-5a22-405b-835c-8b36b7619295", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# treinando a regressão Ridge\n", + "ridge.fit(X_treinamento, y_treinamento)\n", + "\n", + "# treinando a regressão linear simples (OLS)\n", + "lr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 112 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7r28PBsWLtjA", + "outputId": "c63f1b7c-c635-4de2-c97d-e032ab4f1e8b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "ridge.alpha" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 113 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dDZ_TJnhuZno" + }, + "source": [ + "#### $\\alpha = 0.01$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hRMK_QTmNgc1", + "outputId": "835a8daa-8efc-4927-c1d1-25024b859384", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# maior alpha --> mais restrição aos coeficientes; \n", + "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS; Se alpha = 0 ==> Ridge = OLS.\n", + "rr = Ridge(alpha = 0.01) # Quanto mais próximo de 0 ==> Ridge = OLS\n", + "rr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Ridge(alpha=0.01, copy_X=True, fit_intercept=True, max_iter=None,\n", + " normalize=False, random_state=None, solver='auto', tol=0.001)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 114 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRuWmBE7Ngc7" + }, + "source": [ + "# MSE = Erro Quadrático Médio\n", + "from sklearn.metrics import mean_squared_error\n", + "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n", + "lr_model=(mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "L4an-zHetafI", + "outputId": "9012a92d-44f0-4f70-cda8-fe27bca50233", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "print(rr_model)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "23.94639697817076\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QsLVzk3EtbGs", + "outputId": "4baf36bd-a557-4965-fbac-5d1343879a70", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "23.946319854597377\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K2sjngo1QhY2" + }, + "source": [ + "### Coeficientes da Ridge:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5i87o3quByz", + "outputId": "0560bb2c-fe7c-4961-d254-4305a10465dd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 238 + } + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('crim', 0.08087280884194979),\n", + " ('zn', 0.0431105323320636),\n", + " ('indus', 0.06967744483334821),\n", + " ('chas', 3.144789492713716),\n", + " ('nox', 17.9983019701622),\n", + " ('rm', 3.9867565296916703),\n", + " ('age', 0.0035446489044452497),\n", + " ('dis', 1.3530395756206453),\n", + " ('rad', 0.29504291572154007),\n", + " ('tax', 0.012511527307639232),\n", + " ('ptratio', 0.9682821087614826),\n", + " ('b', 0.009027440635645128),\n", + " ('lstat', 0.5291356457993021)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 118 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s44vo9IjQonE" + }, + "source": [ + "### Expreimente vários outros valores para $\\alpha$ como, por exemplo, $\\alpha = 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CDv5fGPbuUq5" + }, + "source": [ + "#### $\\alpha = 100$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEaj4QRrNgdA" + }, + "source": [ + "rr100 = Ridge(alpha = 100)\n", + "rr100.fit(X_treinamento, y_treinamento)\n", + "train_score=lr.score(X_treinamento, y_treinamento)\n", + "test_score=lr.score(X_teste, y_teste)\n", + "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zhcfoTEENgdE" + }, + "source": [ + "# MSE\n", + "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n", + "lr_model = (mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NGDBpfiquxoc", + "outputId": "654af80a-5188-4e8c-c7ea-4bcbcd8cfd66", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "print(rr100_model)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "26.460105089888508\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Owami5MVureW", + "outputId": "c571e71f-f2cf-41c6-b746-f6669c9ad401", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "23.946319854597377\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xk5dN3Owu6Kw" + }, + "source": [ + "### Próximo passo: fazer o statmodel dos modelos ridge." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEF_3GgUgF0Q" + }, + "source": [ + "# LASSO (Least Absolute Shrinkage And Selection Operator regularization)\n", + "* Método mais comum e usado para Regularization; \n", + "* Reduz overfitting;\n", + "* Se encarrega do **Feature Selection**, pois descarta variáveis altamente correlacionadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YiKb9reQdI4" + }, + "source": [ + "* Usado no processo de Regularization - processo de penalizar as variáveis para manter somente os atributos mais importantes. Pense na utilidade disso diante de um dataframe com muitas variáveis;\n", + "* A regressão Lasso vem com um parâmetro ($\\alpha$), e quanto maior o alfa, a maioria dos coeficientes de recurso é zero. Ou seja, quando $\\alpha = 0$, a regressão Lasso produz os mesmos coeficientes que uma regressão linear. Quando alfa é muito grande, todos os coeficientes são zero." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5p_ZPZ4tTUX1" + }, + "source": [ + "### Exemplo LASSO" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5JZTnkTOkI9", + "outputId": "287e4f8c-e6f0-459d-fd88-bfb829e6cc95", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,\n", + " normalize=False, positive=False, precompute=False, random_state=None,\n", + " selection='cyclic', tol=0.0001, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 123 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gEUxSlThOkJD", + "outputId": "7a5cfd51-4c2c-48a2-de0b-5d0292636ef2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.50, 0.00])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 124 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EQaGWzzLT9qP" + }, + "source": [ + "### Aplicação do LASSO no Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ME6v6LFlgF0Q", + "outputId": "3852532d-56fa-40a9-b2aa-c8893f4e4bb4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,\n", + " normalize=False, positive=False, precompute=False, random_state=None,\n", + " selection='cyclic', tol=0.0001, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 125 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h6DSEHc1gF0V", + "outputId": "f057ebcb-1604-42d7-86ef-cc2fefa1e104", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.07, 0.05, 0.00, 1.57, -0.00, 3.78, -0.01, -1.06, 0.26, -0.01,\n", + " -0.78, 0.01, -0.59])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 126 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8SzYnpVGy4cy" + }, + "source": [ + "### Coeficientes do LASSO:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2w2QDmdxxVe", + "outputId": "04cf1b03-7cc0-496a-ed56-b58c8caadcb1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 238 + } + }, + "source": [ + "list(zip(X_treinamento.columns, abs(lasso.coef_)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('crim', 0.06530501689285828),\n", + " ('zn', 0.04699294932304524),\n", + " ('indus', 0.002030456305853612),\n", + " ('chas', 1.5663885184641415),\n", + " ('nox', 0.0),\n", + " ('rm', 3.779546713514268),\n", + " ('age', 0.006404324032734558),\n", + " ('dis', 1.0612931166345525),\n", + " ('rad', 0.2580730613206583),\n", + " ('tax', 0.014270830653978057),\n", + " ('ptratio', 0.7817739916684686),\n", + " ('b', 0.009950918490594119),\n", + " ('lstat', 0.5874528237350962)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 127 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UBOCg1H9zn6A" + }, + "source": [ + "### Coeficientes do RIDGE:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g1fF-mEZzXpH", + "outputId": "ff52cc03-8289-47f1-9609-97830355a798", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 238 + } + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('crim', 0.08087280884194979),\n", + " ('zn', 0.0431105323320636),\n", + " ('indus', 0.06967744483334821),\n", + " ('chas', 3.144789492713716),\n", + " ('nox', 17.9983019701622),\n", + " ('rm', 3.9867565296916703),\n", + " ('age', 0.0035446489044452497),\n", + " ('dis', 1.3530395756206453),\n", + " ('rad', 0.29504291572154007),\n", + " ('tax', 0.012511527307639232),\n", + " ('ptratio', 0.9682821087614826),\n", + " ('b', 0.009027440635645128),\n", + " ('lstat', 0.5291356457993021)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 128 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xP1fX1Bi6VdX" + }, + "source": [ + "**Conclusão**: Coeficientes zero podem ser excluídos da Análise/modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TbtxIWyGSXkH" + }, + "source": [ + "### Efeito dos valores de $\\alpha$\n", + "* Função adaptada de https://chrisalbon.com/machine_learning/linear_regression/effect_of_alpha_on_lasso_regression/." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B4AuWA4LRBE3" + }, + "source": [ + "# Create a function called lasso,\n", + "def lasso(alphas):\n", + " '''\n", + " Takes in a list of alphas. Outputs a dataframe containing the coefficients of lasso regressions from each alpha.\n", + " '''\n", + " # Create an empty data frame\n", + " df = pd.DataFrame()\n", + " \n", + " # Create a column of feature names\n", + " df['Feature Name'] = names\n", + " \n", + " # For each alpha value in the list of alpha values,\n", + " for alpha in alphas:\n", + " # Create a lasso regression with that alpha value,\n", + " lasso = Lasso(alpha = alpha)\n", + " \n", + " # Fit the lasso regression\n", + " lasso.fit(X_treinamento, y_treinamento)\n", + " \n", + " # Create a column name for that alpha value\n", + " column_name = 'Alpha = %f' % alpha\n", + "\n", + " # Create a column of coefficient values\n", + " df[column_name] = lasso.coef_\n", + " \n", + " # Return the datafram \n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VEDvXvuNRK0C", + "outputId": "829e9736-e54f-4059-8da3-89e353d59263", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 452 + } + }, + "source": [ + "names = X_treinamento.columns\n", + "lasso([.0001, .001, .01, .1, 1, 10, 1000, 1000])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Feature NameAlpha = 0.000100Alpha = 0.001000Alpha = 0.010000Alpha = 0.100000Alpha = 1.000000Alpha = 10.000000Alpha = 1000.000000
0crim-0.082177-0.081898-0.079113-0.065305-0.043175-0.000000-0.0
1zn0.0428070.0428700.0435010.0469930.0465110.0229070.0
2indus0.0754670.0742630.0622170.0020300.000000-0.000000-0.0
3chas3.1618173.1468792.9974911.5663890.0000000.0000000.0
4nox-19.459924-19.148839-16.038598-0.000000-0.0000000.000000-0.0
5rm3.9815023.9805423.9709003.7795470.7671230.0000000.0
6age0.0047840.0045580.002299-0.0064040.0277000.000000-0.0
7dis-1.373444-1.368773-1.322091-1.061293-0.603672-0.0000000.0
8rad0.2988000.2980600.2906670.2580730.2630290.000000-0.0
9tax-0.012399-0.012425-0.012688-0.014271-0.014111-0.007210-0.0
10ptratio-0.984286-0.980948-0.947575-0.781774-0.754648-0.000000-0.0
11b0.0089510.0089670.0091300.0099510.0082250.0076680.0
12lstat-0.526561-0.527311-0.534805-0.587453-0.800866-0.600753-0.0
\n", + "
" + ], + "text/plain": [ + " Feature Name Alpha = 0.000100 ... Alpha = 10.000000 Alpha = 1000.000000\n", + "0 crim -0.082177 ... -0.000000 -0.0\n", + "1 zn 0.042807 ... 0.022907 0.0\n", + "2 indus 0.075467 ... -0.000000 -0.0\n", + "3 chas 3.161817 ... 0.000000 0.0\n", + "4 nox -19.459924 ... 0.000000 -0.0\n", + "5 rm 3.981502 ... 0.000000 0.0\n", + "6 age 0.004784 ... 0.000000 -0.0\n", + "7 dis -1.373444 ... -0.000000 0.0\n", + "8 rad 0.298800 ... 0.000000 -0.0\n", + "9 tax -0.012399 ... -0.007210 -0.0\n", + "10 ptratio -0.984286 ... -0.000000 -0.0\n", + "11 b 0.008951 ... 0.007668 0.0\n", + "12 lstat -0.526561 ... -0.600753 -0.0\n", + "\n", + "[13 rows x 8 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 130 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jSYw6SdcXa0q" + }, + "source": [ + "### Cross-Validation & GridSearch para LASSO" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "irFZAkvVXfya" + }, + "source": [ + "from sklearn.linear_model import LassoCV\n", + "from sklearn.model_selection import RepeatedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T3Jjom8RYdly" + }, + "source": [ + "# define model evaluation method\n", + "cv = RepeatedKFold(n_splits = 5, n_repeats = 3, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cw3lAvRPYgJe" + }, + "source": [ + "# define model\n", + "model = LassoCV(alphas = np.arange(0.001, 10, 0.001), cv = cv, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLX3CpThXvkJ", + "outputId": "e5b49993-c7a8-49d7-f11b-2c7ea63d6cba", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# fit model\n", + "model.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LassoCV(alphas=array([0.00, 0.00, 0.00, ..., 10.00, 10.00, 10.00]), copy_X=True,\n", + " cv=RepeatedKFold(n_repeats=3, n_splits=10, random_state=1), eps=0.001,\n", + " fit_intercept=True, max_iter=1000, n_alphas=100, n_jobs=-1,\n", + " normalize=False, positive=False, precompute='auto', random_state=None,\n", + " selection='cyclic', tol=0.0001, verbose=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 180 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U1ubd5huYQ7u", + "outputId": "a847a297-a66c-449b-feeb-491827b16bd3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# summarize chosen configuration\n", + "print('alpha: %f' % model.alpha_)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "alpha: 0.001000\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9P7hYoo4gF0Z" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yChNUYs7gF0b" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4mbIaAUAF4N6", + "outputId": "3a7bd712-d468-46bf-ca8a-bf783249e5af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "en.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "ElasticNet(alpha=0.1, copy_X=True, fit_intercept=True, l1_ratio=0.5,\n", + " max_iter=1000, normalize=False, positive=False, precompute=False,\n", + " random_state=None, selection='cyclic', tol=0.0001, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 132 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MaUkZw8ngF0h", + "outputId": "9e417454-b4c6-4c50-8029-afee0cd8020b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "en.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.07, 0.05, 0.00, 1.32, -0.12, 3.29, -0.00, -1.08, 0.28, -0.02,\n", + " -0.81, 0.01, -0.62])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 133 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xl-Qh9caDyCp" + }, + "source": [ + "# Instancia o objeto:\n", + "en = ElasticNet(normalize = True)\n", + "\n", + "# Otimização dos hiperparâmetros:\n", + "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n", + " 'l1_ratio': [.2, .4, .6, .8]}\n", + "\n", + "search = GridSearchCV(estimator = en, \n", + " param_grid = d_hiperparametros, \n", + " scoring = 'neg_mean_squared_error', \n", + " n_jobs = 1,\n", + " refit = True, \n", + " cv = 10)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c3_XCQCPGlr3", + "outputId": "7407462c-8b3a-472b-e9d4-3878344970e3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "search.fit(X_treinamento, y_treinamento)\n", + "search.best_params_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'alpha': 0.0001, 'l1_ratio': 0.4}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 135 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq0_ugQfGrdb", + "outputId": "317e8866-1996-40a2-f7df-698d196a5f67", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n", + "en2.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Métrica\n", + "ml2 = (mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))\n", + "print(ml2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "15.410850398354441\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5geUMgC6ztxE" + }, + "source": [ + "### Coeficientes do Elastic Net:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LyLdASRqzwCq", + "outputId": "647de634-be15-4164-8dad-014b735de1af", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 238 + } + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[('crim', 0.08087280884194979),\n", + " ('zn', 0.0431105323320636),\n", + " ('indus', 0.06967744483334821),\n", + " ('chas', 3.144789492713716),\n", + " ('nox', 17.9983019701622),\n", + " ('rm', 3.9867565296916703),\n", + " ('age', 0.0035446489044452497),\n", + " ('dis', 1.3530395756206453),\n", + " ('rad', 0.29504291572154007),\n", + " ('tax', 0.012511527307639232),\n", + " ('ptratio', 0.9682821087614826),\n", + " ('b', 0.009027440635645128),\n", + " ('lstat', 0.5291356457993021)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 137 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "90pfP9-3OkJG" + }, + "source": [ + "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILCXvYKDOkJH" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaQPDCR2OkJI" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xVp16Eu_OkJL", + "outputId": "e1152c6f-9129-4ac6-90ea-d48280820550", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "ElasticNet(alpha=0.1, copy_X=True, fit_intercept=True, l1_ratio=0.5,\n", + " max_iter=1000, normalize=False, positive=False, precompute=False,\n", + " random_state=None, selection='cyclic', tol=0.0001, warm_start=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 139 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwj018U8OkJO", + "outputId": "9261a5fb-80c1-4623-dd6f-42ad3a5f16fa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "en.coef_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.33, 0.33])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 140 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rJRWBzSQCcss" + }, + "source": [ + "# Regressão Logística" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwuMfMD1gFyd" + }, + "source": [ + "# Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efF3st3sHxPG" + }, + "source": [ + "# Carrega as bibliotecas\n", + "import numpy as np\n", + "np.set_printoptions(formatter = {'float': lambda x: \"{0:0.2f}\".format(x)})\n", + "\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "import statsmodels.api as sm\n", + "\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bk9F6JO0IELv", + "outputId": "1e85bafb-5da0-4b1e-e95f-ac65df8388a5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Carregar/ler o banco de dados - Dataframe Diabetes\n", + "from sklearn import datasets\n", + "#Diabetes = datasets.load_diabetes()\n", + "\n", + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/diabetes.csv'\n", + "diabetes = pd.read_csv(url)\n", + "diabetes.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunctionAgeOutcome
061487235033.60.627501
11856629026.60.351310
28183640023.30.672321
318966239428.10.167210
40137403516843.12.288331
\n", + "
" + ], + "text/plain": [ + " Pregnancies Glucose BloodPressure ... DiabetesPedigreeFunction Age Outcome\n", + "0 6 148 72 ... 0.627 50 1\n", + "1 1 85 66 ... 0.351 31 0\n", + "2 8 183 64 ... 0.672 32 1\n", + "3 1 89 66 ... 0.167 21 0\n", + "4 0 137 40 ... 2.288 33 1\n", + "\n", + "[5 rows x 9 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 142 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tjRmpaPIDknb", + "outputId": "f6b56d34-1ebb-4dd4-e92b-06846299edf3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Definir as matrizes X e y\n", + "X_diabetes = diabetes.copy()\n", + "X_diabetes.drop(columns = ['Outcome'], axis = 1, inplace = True)\n", + "y_diabetes = diabetes['Outcome']\n", + "\n", + "X_diabetes.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunctionAge
061487235033.60.62750
11856629026.60.35131
28183640023.30.67232
318966239428.10.16721
40137403516843.12.28833
\n", + "
" + ], + "text/plain": [ + " Pregnancies Glucose BloodPressure ... BMI DiabetesPedigreeFunction Age\n", + "0 6 148 72 ... 33.6 0.627 50\n", + "1 1 85 66 ... 26.6 0.351 31\n", + "2 8 183 64 ... 23.3 0.672 32\n", + "3 1 89 66 ... 28.1 0.167 21\n", + "4 0 137 40 ... 43.1 2.288 33\n", + "\n", + "[5 rows x 8 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 143 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jLrx69TH-Mad", + "outputId": "b090efbf-e878-4e97-b6bb-6eaa74f942f5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_diabetes.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(768, 8)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 144 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mdFBioP6-Ply", + "outputId": "029ee89e-63be-444e-c28f-da5abafcc73e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_diabetes.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(768,)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 145 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fhLySN65IaDF" + }, + "source": [ + "# Definir as matrizes de treinamento e validação\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_diabetes, y_diabetes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J5R8HlnuIGpL", + "outputId": "366b8993-ba2e-4cc2-a4c8-d4785645bc23", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + } + }, + "source": [ + "# Usando statmodels:\n", + "x = sm.add_constant(X_treinamento)\n", + "lr_sm = sm.Logit(y_treinamento, X_treinamento) # Atenção: aqui é o contrário: [y, x]\n", + "\n", + "# Treinar o modelo\n", + "lr.fit(X_treinamento, y_treinamento)\n", + "resultado_sm = lr_sm.fit()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Optimization terminated successfully.\n", + " Current function value: 0.605992\n", + " Iterations 5\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GlbCaPp1ETNa", + "outputId": "8e1be25a-2500-4432-d4e1-21d94cd3adbb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 374 + } + }, + "source": [ + "resultado_sm.summary()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Logit Regression Results
Dep. Variable: Outcome No. Observations: 576
Model: Logit Df Residuals: 568
Method: MLE Df Model: 7
Date: Tue, 27 Oct 2020 Pseudo R-squ.: 0.06151
Time: 18:36:59 Log-Likelihood: -349.05
converged: True LL-Null: -371.93
Covariance Type: nonrobust LLR p-value: 9.756e-08
\n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "
coef std err z P>|z| [0.025 0.975]
Pregnancies 0.1260 0.034 3.719 0.000 0.060 0.192
Glucose 0.0129 0.003 4.135 0.000 0.007 0.019
BloodPressure -0.0320 0.005 -6.038 0.000 -0.042 -0.022
SkinThickness 0.0074 0.007 1.043 0.297 -0.007 0.021
Insulin -0.0001 0.001 -0.125 0.900 -0.002 0.002
BMI -0.0074 0.012 -0.596 0.551 -0.032 0.017
DiabetesPedigreeFunction 0.1565 0.270 0.580 0.562 -0.373 0.686
Age -0.0096 0.010 -0.962 0.336 -0.029 0.010
" + ], + "text/plain": [ + "\n", + "\"\"\"\n", + " Logit Regression Results \n", + "==============================================================================\n", + "Dep. Variable: Outcome No. Observations: 576\n", + "Model: Logit Df Residuals: 568\n", + "Method: MLE Df Model: 7\n", + "Date: Tue, 27 Oct 2020 Pseudo R-squ.: 0.06151\n", + "Time: 18:36:59 Log-Likelihood: -349.05\n", + "converged: True LL-Null: -371.93\n", + "Covariance Type: nonrobust LLR p-value: 9.756e-08\n", + "============================================================================================\n", + " coef std err z P>|z| [0.025 0.975]\n", + "--------------------------------------------------------------------------------------------\n", + "Pregnancies 0.1260 0.034 3.719 0.000 0.060 0.192\n", + "Glucose 0.0129 0.003 4.135 0.000 0.007 0.019\n", + "BloodPressure -0.0320 0.005 -6.038 0.000 -0.042 -0.022\n", + "SkinThickness 0.0074 0.007 1.043 0.297 -0.007 0.021\n", + "Insulin -0.0001 0.001 -0.125 0.900 -0.002 0.002\n", + "BMI -0.0074 0.012 -0.596 0.551 -0.032 0.017\n", + "DiabetesPedigreeFunction 0.1565 0.270 0.580 0.562 -0.373 0.686\n", + "Age -0.0096 0.010 -0.962 0.336 -0.029 0.010\n", + "============================================================================================\n", + "\"\"\"" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 148 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-FJaSnJLKICU", + "outputId": "bf103788-6bb8-4755-a4ea-f06fc8bd8514", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# EQM - Erro Quadrático Médio\n", + "np.mean((resultado_sm.predict(X_teste) - y_teste) ** 2) " + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.2153796977006658" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 149 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bVEUSTUPzOj" + }, + "source": [ + "### Calcular y_pred - os valores preditos de y" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OjGrNhTNLcr-" + }, + "source": [ + "y_pred = resultado_sm.predict(X_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfS5RCx_VnGT", + "outputId": "05b0e59b-60ce-4bbe-d582-f983ea39d7a1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 527 + } + }, + "source": [ + "compara = list(zip(np.array(diabetes['Outcome']), resultado_sm.predict()))\n", + "compara[0:30]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[(1, 0.4964813717283173),\n", + " (0, 0.43813015739999056),\n", + " (1, 0.3351229393597726),\n", + " (0, 0.4170598535890674),\n", + " (1, 0.33525360127159953),\n", + " (0, 0.33954024324811855),\n", + " (1, 0.7161856828807713),\n", + " (0, 0.30737583540608177),\n", + " (1, 0.7463860219809548),\n", + " (1, 0.5224158390283206),\n", + " (0, 0.6617811831292351),\n", + " (1, 0.28390512013813257),\n", + " (0, 0.30820517679884585),\n", + " (1, 0.4402216426898358),\n", + " (1, 0.5364393605837372),\n", + " (1, 0.20147010634149431),\n", + " (1, 0.3084811467691899),\n", + " (1, 0.549873161998823),\n", + " (0, 0.3078243845960755),\n", + " (1, 0.3943683761693644),\n", + " (0, 0.32026940349835475),\n", + " (0, 0.49754641616990125),\n", + " (1, 0.6901893365750147),\n", + " (1, 0.6287550079979413),\n", + " (1, 0.42408221478347446),\n", + " (1, 0.3478297305544648),\n", + " (1, 0.31084157363014775),\n", + " (0, 0.23512026465552527),\n", + " (0, 0.21009588386462008),\n", + " (0, 0.428293478648919)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 151 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUxasncIFaw4", + "outputId": "91683144-9981-4319-9747-d5711c223640", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "resultado_sm.pred_table()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[326.00, 50.00],\n", + " [127.00, 73.00]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 152 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_liLYinwFgch", + "outputId": "fd843722-cc87-4435-b232-fdeeb269dbf5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 111 + } + }, + "source": [ + "confusion_matrix = pd.DataFrame(resultado_sm.pred_table())\n", + "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n", + "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n", + "confusion_matrix" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Predicted No DiabetesPredicted Diabetes
Actual No Diabetes326.050.0
Actual Diabetes127.073.0
\n", + "
" + ], + "text/plain": [ + " Predicted No Diabetes Predicted Diabetes\n", + "Actual No Diabetes 326.0 50.0\n", + "Actual Diabetes 127.0 73.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 153 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ceH3MODWFm7S", + "outputId": "d8352417-9d66-49c3-ed3f-d12cb0d89dc3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "cm = np.array(confusion_matrix)\n", + "training_accuracy = (cm[0,0] + cm[1,1])/ cm.sum()\n", + "training_accuracy" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.6927083333333334" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 154 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH_iEuzhO109" + }, + "source": [ + "# Exercício 1 - Mall_Customers.csv\n", + "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n", + "\n", + "* Experimente:\n", + " * Lasso(alpha = 0.01, max_iter = 10e5);\n", + " * Lasso(alpha = 0.0001, max_iter = 10e5);\n", + " * Ridge(alpha = 0.01);\n", + " * Ridge(alpha = 100);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZfRDEaaRYxFQ" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt \n", + "plt.rc(\"font\", size=14)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "import seaborn as sns\n", + "sns.set(style=\"white\")\n", + "sns.set(style=\"whitegrid\", color_codes=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nulrLzUqYxFY" + }, + "source": [ + "## Dados\n", + "\n", + "The data is related with direct marketing campaigns (phone calls) of a Portuguese banking institution. The classification goal is to predict if the client will subscribe (1/0) a term deposit (variable y)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LdrQCwxYxFY" + }, + "source": [ + "This dataset provides the customer information. It includes 41188 records and 21 fields." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qoT6zkoFYxFZ", + "outputId": "517870d0-203d-48b1-dbd2-74dfeab2b8ec", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "df_bank = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/bank-full.csv', header = 0)\n", + "df_bank = df_bank.dropna()\n", + "print(df_bank.shape)\n", + "print(list(df_bank.columns))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(45211, 1)\n", + "['age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZD23hMCeYxFc", + "outputId": "56468732-3d3c-4cb0-d5f5-1753495f2d31", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_bank.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"
058;\"management\";\"married\";\"tertiary\";\"no\";2143...
144;\"technician\";\"single\";\"secondary\";\"no\";29;\"...
233;\"entrepreneur\";\"married\";\"secondary\";\"no\";2...
347;\"blue-collar\";\"married\";\"unknown\";\"no\";1506...
433;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n...
\n", + "
" + ], + "text/plain": [ + " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"\n", + "0 58;\"management\";\"married\";\"tertiary\";\"no\";2143... \n", + "1 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... \n", + "2 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... \n", + "3 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... \n", + "4 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... " + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 157 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CtGbim_EYxFh" + }, + "source": [ + "#### Input variables" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0pJ7ai5ZYxFh" + }, + "source": [ + "1 - age (numeric)\n", + "\n", + "2 - job : type of job (categorical: 'admin.','blue-collar','entrepreneur','housemaid','management','retired','self-employed','services','student','technician','unemployed','unknown')\n", + "\n", + "3 - marital : marital status (categorical: 'divorced','married','single','unknown'; note: 'divorced' means divorced or widowed)\n", + "\n", + "4 - education (categorical: 'basic.4y','basic.6y','basic.9y','high.school','illiterate','professional.course','university.degree','unknown')\n", + "\n", + "5 - default: has credit in default? (categorical: 'no','yes','unknown')\n", + "\n", + "6 - housing: has housing loan? (categorical: 'no','yes','unknown')\n", + "\n", + "7 - loan: has personal loan? (categorical: 'no','yes','unknown')\n", + "\n", + "8 - contact: contact communication type (categorical: 'cellular','telephone')\n", + "\n", + "9 - month: last contact month of year (categorical: 'jan', 'feb', 'mar', ..., 'nov', 'dec')\n", + "\n", + "10 - day_of_week: last contact day of the week (categorical: 'mon','tue','wed','thu','fri')\n", + "\n", + "11 - duration: last contact duration, in seconds (numeric). Important note: this attribute highly affects the output target (e.g., if duration=0 then y='no'). Yet, the duration is not known before a call is performed. Also, after the end of the call y is obviously known. Thus, this input should only be included for benchmark purposes and should be discarded if the intention is to have a realistic predictive model.\n", + "\n", + "12 - campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)\n", + "\n", + "13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)\n", + "\n", + "14 - previous: number of contacts performed before this campaign and for this client (numeric)\n", + "\n", + "15 - poutcome: outcome of the previous marketing campaign (categorical: 'failure','nonexistent','success')\n", + "\n", + "16 - emp.var.rate: employment variation rate - (numeric)\n", + "\n", + "17 - cons.price.idx: consumer price index - (numeric)\n", + "\n", + "18 - cons.conf.idx: consumer confidence index - (numeric) \n", + "\n", + "19 - euribor3m: euribor 3 month rate - (numeric)\n", + "\n", + "20 - nr.employed: number of employees - (numeric)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YwsaBV_OYxFi" + }, + "source": [ + "#### Predict variable (desired target):\n", + "\n", + "y - has the client subscribed a term deposit? (binary: '1','0')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2SsNWV_SYxFj" + }, + "source": [ + "The education column of the dataset has many categories and we need to reduce the categories for a better modelling. The education column has the following categories:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6TFbgh3vYxFk", + "outputId": "dbc5f647-726c-4951-e037-ce0ba2c0b5fd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 561 + } + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2894\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2895\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'education'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf_bank\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'education'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2901\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2902\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2903\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2904\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2895\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2897\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2898\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2899\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtolerance\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'education'" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "luv7Bdf_YxFn" + }, + "source": [ + "Let us group \"basic.4y\", \"basic.9y\" and \"basic.6y\" together and call them \"basic\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gkOlUOs2YxFn" + }, + "source": [ + "df_bank['education']=np.where(df_bank['education'] =='basic.9y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.6y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.4y', 'Basic', df_bank['education'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-X1WMv2YxFq" + }, + "source": [ + "After grouping, this is the columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r9LlgpkjYxFq" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fcnJy3KYYxFt" + }, + "source": [ + "### Data exploration" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qUrTMR8BYxFt" + }, + "source": [ + "df_bank['y'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rpzHnzJKYxFx" + }, + "source": [ + "sns.countplot(x='y',data=df_bank, palette='hls')\n", + "plt.show()\n", + "plt.savefig('count_plot')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C99nOe3mYxF0" + }, + "source": [ + "There are 36548 no's and 4640 yes's in the outcome variables." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8nGaox_kYxF1" + }, + "source": [ + "Let's get a sense of the numbers across the two classes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sQvzA60bYxF1" + }, + "source": [ + "df_bank.groupby('y').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u3xjoceKYxF3" + }, + "source": [ + "Observations:\n", + "\n", + "The average age of customers who bought the term deposit is higher than that of the customers who didn't.\n", + "The pdays (days since the customer was last contacted) is understandably lower for the customers who bought it. The lower the pdays, the better the memory of the last call and hence the better chances of a sale.\n", + "Surprisingly, campaigns (number of contacts or calls made during the current campaign) are lower for customers who bought the term deposit." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jvzGMePPYxF4" + }, + "source": [ + "We can calculate categorical means for other categorical variables such as education and marital status to get a more detailed sense of our data." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RqLVMjoxYxF5" + }, + "source": [ + "df_bank.groupby('job').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GTUeRJAtYxF7" + }, + "source": [ + "df_bank.groupby('marital').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsxdFumiYxF9" + }, + "source": [ + "df_bank.groupby('education').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3i1DCWV-YxGA" + }, + "source": [ + "Visualizations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OEArHQPbYxGB" + }, + "source": [ + "%matplotlib inline\n", + "pd.crosstab(df_bank.job,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Job Title')\n", + "plt.xlabel('Job')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('purchase_fre_job')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNwo5du_YxGD" + }, + "source": [ + "The frequency of purchase of the deposit depends a great deal on the job title. Thus, the job title can be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eM7CWfAZYxGE" + }, + "source": [ + "table=pd.crosstab(df_bank.marital,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Marital Status vs Purchase')\n", + "plt.xlabel('Marital Status')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('mariral_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWBLh7toYxGG" + }, + "source": [ + "Hard to see, but the marital status does not seem a strong predictor for the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vh_u4QphYxGH" + }, + "source": [ + "table=pd.crosstab(df_bank.education,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Education vs Purchase')\n", + "plt.xlabel('Education')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('edu_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d9AgJroYYxGK" + }, + "source": [ + "Education seems a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dHI2LT-IYxGL" + }, + "source": [ + "pd.crosstab(df_bank.day_of_week,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Day of Week')\n", + "plt.xlabel('Day of Week')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_dayofweek_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3A2jmS4MYxGR" + }, + "source": [ + "Day of week may not be a good predictor of the outcome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bzafDBHpYxGS" + }, + "source": [ + "pd.crosstab(df_bank.month,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Month')\n", + "plt.xlabel('Month')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_month_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x5CBtquEYxGW" + }, + "source": [ + "Month might be a good predictor of the outcome variable" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tgF_3SqWYxGY" + }, + "source": [ + "df_bank.age.hist()\n", + "plt.title('Histogram of Age')\n", + "plt.xlabel('Age')\n", + "plt.ylabel('Frequency')\n", + "plt.savefig('hist_age')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y0FhKYDsYxGc" + }, + "source": [ + "The most of the customers of the bank in this dataset are in the age range of 30-40." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Nd3yV7DYxGd" + }, + "source": [ + "pd.crosstab(df_bank.poutcome,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Poutcome')\n", + "plt.xlabel('Poutcome')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_pout_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oRKUAGrjYxGh" + }, + "source": [ + "Poutcome seems to be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "63RLRI9uYxGi" + }, + "source": [ + "### Create dummy variables" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V8S4WUKmYxGj" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "for var in cat_vars:\n", + " cat_list='var'+'_'+var\n", + " cat_list = pd.get_dummies(df_bank[var], prefix=var)\n", + " df_bank1=df_bank.join(cat_list)\n", + " data=df_bank1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uX3w9i9WYxGl" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "df_bank_vars=df_bank.columns.values.tolist()\n", + "to_keep=[i for i in df_bank_vars if i not in cat_vars]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cMX_82xaYxGq" + }, + "source": [ + "df_bank_final=df_bank[to_keep]\n", + "df_bank_final.columns.values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LkTjpxYoYxGr" + }, + "source": [ + "df_bank_final_vars=df_bank_final.columns.values.tolist()\n", + "y=['y']\n", + "X=[i for i in df_bank_final_vars if i not in y]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2QbKaRcsYxGt" + }, + "source": [ + "### Feature Selection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EkxjW1AQYxGu" + }, + "source": [ + "from sklearn import datasets\n", + "from sklearn.feature_selection import RFE\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "logreg = LogisticRegression()\n", + "\n", + "rfe = RFE(logreg, 18)\n", + "rfe = rfe.fit(df_bank_final[X], df_bank_final[y] )\n", + "print(rfe.support_)\n", + "print(rfe.ranking_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2P9hd4jHYxGw" + }, + "source": [ + "The Recursive Feature Elimination (RFE) has helped us select the following features: \"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PW8WZX_YxGx" + }, + "source": [ + "cols=[\"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \n", + " \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \n", + " \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"] \n", + "X=df_bank_final[cols]\n", + "y=df_bank_final['y']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ix0mN9qxYxG0" + }, + "source": [ + "### Implementing the model" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hbx2bwtiYxG0" + }, + "source": [ + "import statsmodels.api as sm\n", + "logit_model=sm.Logit(y,X)\n", + "result=logit_model.fit()\n", + "print(result.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HR1ui-UcYxG2" + }, + "source": [ + "The p-values for most of the variables are very small, therefore, most of them are significant to the model." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9GHhrsaeYxG3" + }, + "source": [ + "### Logistic Regression Model Fitting" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFQnH5MzYxG3" + }, + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn import metrics\n", + "logreg = LogisticRegression()\n", + "logreg.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YUa3QL7tYxG6" + }, + "source": [ + "#### Predicting the test set results and caculating the accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SD-y2e33YxG6" + }, + "source": [ + "y_pred = logreg.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kkPWzos7YxG-" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwC3rt_6YxHA" + }, + "source": [ + "### Cross Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Muw50oqSYxHB" + }, + "source": [ + "from sklearn import model_selection\n", + "from sklearn.model_selection import cross_val_score\n", + "kfold = model_selection.KFold(n_splits=10, random_state=7)\n", + "modelCV = LogisticRegression()\n", + "scoring = 'accuracy'\n", + "results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)\n", + "print(\"10-fold cross validation average accuracy: %.3f\" % (results.mean()))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4y8XCTqoYxHE" + }, + "source": [ + "### Confusion Matrix" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BCza9NkVYxHE" + }, + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "confusion_matrix = confusion_matrix(y_test, y_pred)\n", + "print(confusion_matrix)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9SapwS2YxHG" + }, + "source": [ + "The result is telling us that we have 10872+254 correct predictions and 1122+109 incorrect predictions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bEWvWScYxHG" + }, + "source": [ + "#### Accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NaH2nESwYxHH" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(classifier.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C6oxlhbpYxHJ" + }, + "source": [ + "#### Compute precision, recall, F-measure and support\n", + "\n", + "The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.\n", + "\n", + "The recall is the ratio tp / (tp + fn) where tp is the number of true positives and fn the number of false negatives. The recall is intuitively the ability of the classifier to find all the positive samples.\n", + "\n", + "The F-beta score can be interpreted as a weighted harmonic mean of the precision and recall, where an F-beta score reaches its best value at 1 and worst score at 0.\n", + "\n", + "The F-beta score weights recall more than precision by a factor of beta. beta == 1.0 means recall and precision are equally important.\n", + "\n", + "The support is the number of occurrences of each class in y_test." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mhN5_p4yYxHK" + }, + "source": [ + "from sklearn.metrics import classification_report\n", + "print(classification_report(y_test, y_pred))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xzSFVEnAYxHP" + }, + "source": [ + "#### Interpretation: \n", + "\n", + "Of the entire test set, 88% of the promoted term deposit were the term deposit that the customers liked. Of the entire test set, 90% of the customer's preferred term deposit were promoted." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NGXJ6g2nYxHQ" + }, + "source": [ + "### ROC Curvefrom sklearn import metrics\n", + "from ggplot import *\n", + "\n", + "prob = clf1.predict_proba(X_test)[:,1]\n", + "fpr, sensitivity, _ = metrics.roc_curve(Y_test, prob)\n", + "\n", + "df = pd.DataFrame(dict(fpr=fpr, sensitivity=sensitivity))\n", + "ggplot(df, aes(x='fpr', y='sensitivity')) +\\\n", + " geom_line() +\\\n", + " geom_abline(linetype='dashed')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u9QKDuS0YxHQ" + }, + "source": [ + "from sklearn.metrics import roc_auc_score\n", + "from sklearn.metrics import roc_curve\n", + "logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))\n", + "fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])\n", + "plt.figure()\n", + "plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)\n", + "plt.plot([0, 1], [0, 1],'r--')\n", + "plt.xlim([0.0, 1.0])\n", + "plt.ylim([0.0, 1.05])\n", + "plt.xlabel('False Positive Rate')\n", + "plt.ylabel('True Positive Rate')\n", + "plt.title('Receiver operating characteristic')\n", + "plt.legend(loc=\"lower right\")\n", + "plt.savefig('Log_ROC')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git "a/Notebooks/NB15_02__Regress\303\243o Linear_hs2.ipynb" "b/Notebooks/NB15_02__Regress\303\243o Linear_hs2.ipynb" new file mode 100644 index 000000000..837f0d6a5 --- /dev/null +++ "b/Notebooks/NB15_02__Regress\303\243o Linear_hs2.ipynb" @@ -0,0 +1,10651 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "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.1" + }, + "colab": { + "name": "NB15_02__Regressão Linear.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwQDhId7N6_r" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

\n", + "

APRENDIZAGEM SUPERVISIONADA

\n", + "

MODELOS DE REGRESSÃO (LINEAR E LOGÍSTICA)

\n", + "\n", + "Fonte: https://realpython.com/linear-regression-in-python/\n", + "https://towardsdatascience.com/predicting-the-survival-of-titanic-passengers-30870ccc7e8" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PN-dQFJcM1UV" + }, + "source": [ + "Passos para implementação da Regressão Linear:\n", + "\n", + "* (1) Importar as libraries necessárias;\n", + "* (2) Carregar os dados;\n", + "* (3) Aplicar as transformações necessárias: outliers, NaN's, normalização (MinMaxScaler, RobustScaler, StandarScaler, Log, Box-Cox e etc);\n", + "* (4) DataViz dos dados: entender os relacionamentos, distribuições e etc presente nos dados;\n", + "* (5) Construir e treinar o modelo preditivo (neste caso, modelo de regressão);\n", + "* (6) Validar/verificar as métricas para avaliação do(s) modelo(s);\n", + "* (7) Predições." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8TldGZxAFV5E" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0QRbxlqaq7pr" + }, + "source": [ + "# Melhorias da sessão:\n", + "* Calcular as correlações antes e depois da RIDGE e LASSO para mostrar a multicolinearidade e explicar porque determinadas colunas \"deixam\" de ser importantes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P4sAIblOgFyL" + }, + "source": [ + "# Modelos de Regressão com Regularization para Classificação e Regressão" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7Y7cuJNgFyU" + }, + "source": [ + "## Regressão Linear Simples (usando OLS - Ordinary Least Squares)\n", + "\n", + "* Features $X_{np}$: é uma matriz de dimensão nxp contendo os atributos/variáveis preditoras do dataframe (variáveis independentes);\n", + "* Variável target/dependente representada por y;\n", + "* Relação entre X e y é representado pela equação abaixo, onde $w_{i}$ representa os pesos de cada coeficiente e $w_{0}$ representa o intercepto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NpJ580y9gFyU" + }, + "source": [ + "\n", + "\n", + "![X_y](https://github.com/MathMachado/Materials/blob/master/Architecture.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rhbVGJ0gFyY" + }, + "source": [ + "* Soma de Quadrados dos Resíduos (RSS) - Soma de Quadrados das diferenças entre os valores observados e preditos.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u8gA0YkbgFyp" + }, + "source": [ + "## Principais parâmetros do algoritmo:\n", + "* fit_intercept - Indica se o intercepto $w_{0}$ deve ou não ser ajustado. Se os dados estão normalizados, então não faz sentido ajustar o intercepto $w_{0}$.\n", + "\n", + "* normalize - $X$ será automaticamente normalizada (subtrai a média e divide pelo desvio-padrão);\n", + "\n", + "## Atributos do modelo de Machine Learning para Regressão\n", + "* coef - peso/fator de cada variável independente do modelo de ML;\n", + "\n", + "* intercepto $w_{0}$ - intercepto ou viés de $y$;\n", + "\n", + "## Funções para ajuste do ML:\n", + "* fit - treina o modelo com as matrizes $X$ e $y$;\n", + "* predict - Uma vez que o modelo foi treinado, para um dado $X$, use $y$ para calcular os valores preditos de $y$ (y_pred).\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A-JG8El1gFy7" + }, + "source": [ + "# Limitações do OLS (Ordinary Least Squares):\n", + "* Impactado/sensível à Outliers;\n", + "* Multicolinearidade; \n", + "* Heterocedasticidade - apresenta-se como uma forte dispersão dos dados em torno de uma reta;\n", + "\n", + "* References" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xylMYR8COyrw" + }, + "source": [ + "### Importar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2BGgrILlPK6Z" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "263GgbwhO2kQ" + }, + "source": [ + "### Carregar os dados\n", + "* Vamos carregar o dataset [Boston House Pricing](https://archive.ics.uci.edu/ml/datasets/housing)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1h66x_-rXGhi" + }, + "source": [ + "from sklearn.datasets import load_boston, load_iris" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rWniNkMpXQFU", + "outputId": "5096d239-2c8c-4327-dbf5-f9128faa589c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "boston = load_boston()\n", + "boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'DESCR': \".. _boston_dataset:\\n\\nBoston house prices dataset\\n---------------------------\\n\\n**Data Set Characteristics:** \\n\\n :Number of Instances: 506 \\n\\n :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\\n\\n :Attribute Information (in order):\\n - CRIM per capita crime rate by town\\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\\n - INDUS proportion of non-retail business acres per town\\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\\n - NOX nitric oxides concentration (parts per 10 million)\\n - RM average number of rooms per dwelling\\n - AGE proportion of owner-occupied units built prior to 1940\\n - DIS weighted distances to five Boston employment centres\\n - RAD index of accessibility to radial highways\\n - TAX full-value property-tax rate per $10,000\\n - PTRATIO pupil-teacher ratio by town\\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\\n - LSTAT % lower status of the population\\n - MEDV Median value of owner-occupied homes in $1000's\\n\\n :Missing Attribute Values: None\\n\\n :Creator: Harrison, D. and Rubinfeld, D.L.\\n\\nThis is a copy of UCI ML housing dataset.\\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\\n\\n\\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\\n\\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\\nprices and the demand for clean air', J. Environ. Economics & Management,\\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\\n...', Wiley, 1980. N.B. Various transformations are used in the table on\\npages 244-261 of the latter.\\n\\nThe Boston house-price data has been used in many machine learning papers that address regression\\nproblems. \\n \\n.. topic:: References\\n\\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\\n\",\n", + " 'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,\n", + " 4.9800e+00],\n", + " [2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,\n", + " 9.1400e+00],\n", + " [2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,\n", + " 4.0300e+00],\n", + " ...,\n", + " [6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 5.6400e+00],\n", + " [1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,\n", + " 6.4800e+00],\n", + " [4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 7.8800e+00]]),\n", + " 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n", + " 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTAT
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... RAD TAX PTRATIO B LSTAT\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 136 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQzFW7DUX_KW", + "outputId": "dcf288db-d99d-4d17-c22c-ceb8a9ba4841", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Variável target/resposta\n", + "df_boston['preco'] = load_boston().target\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 137 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H71da4bIO4kI" + }, + "source": [ + "### Data Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K-6YOdsTfciO" + }, + "source": [ + "#### Normalização/padronização dos nomes das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L8OJEapufhq4" + }, + "source": [ + "# Renomear as colunas do dataframe\n", + "df_boston.columns = [col.lower() for col in df_boston.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uRinX-5ofol_", + "outputId": "2e67bbbd-792f-4786-8c7e-2d0bd16fd249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... tax ptratio b lstat preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 139 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMDh5jyqekmr" + }, + "source": [ + "#### Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJIG0jJQf6em" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgYPzlvfemFc" + }, + "source": [ + "#### Missing values" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BAjw7UhJen0D", + "outputId": "917a8f23-ec31-4f22-9a46-c3a15c1e4563", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Missing values por colunas/variáveis\n", + "df_boston.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "crim 0\n", + "zn 0\n", + "indus 0\n", + "chas 0\n", + "nox 0\n", + "rm 0\n", + "age 0\n", + "dis 0\n", + "rad 0\n", + "tax 0\n", + "ptratio 0\n", + "b 0\n", + "lstat 0\n", + "preco 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 140 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jo3UWNpbYnNF", + "outputId": "aeefc57a-f1b7-41ac-aa2e-53f828b9be14", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Número de atributos\n", + "len(load_boston().feature_names)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "13" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 141 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0Yp8g7hxfQli", + "outputId": "43795436-0366-4427-ed5a-2deacedf567f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49 + } + }, + "source": [ + "# Missing Values por linhas\n", + "df_boston[df_boston.isnull().any(axis = 1)]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat, preco]\n", + "Index: []" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 142 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5qmkTFLrf9MT" + }, + "source": [ + "#### Estatísticas Descritivas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nprn3p_Wf_bn", + "outputId": "16f46af6-ab9a-4d7b-a875-295817b9bf9c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_boston.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
count506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000
mean3.61352411.36363611.1367790.0691700.5546956.28463468.5749013.7950439.549407408.23715418.455534356.67403212.65306322.532806
std8.60154523.3224536.8603530.2539940.1158780.70261728.1488612.1057108.707259168.5371162.16494691.2948647.1410629.197104
min0.0063200.0000000.4600000.0000000.3850003.5610002.9000001.1296001.000000187.00000012.6000000.3200001.7300005.000000
25%0.0820450.0000005.1900000.0000000.4490005.88550045.0250002.1001754.000000279.00000017.400000375.3775006.95000017.025000
50%0.2565100.0000009.6900000.0000000.5380006.20850077.5000003.2074505.000000330.00000019.050000391.44000011.36000021.200000
75%3.67708312.50000018.1000000.0000000.6240006.62350094.0750005.18842524.000000666.00000020.200000396.22500016.95500025.000000
max88.976200100.00000027.7400001.0000000.8710008.780000100.00000012.12650024.000000711.00000022.000000396.90000037.97000050.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "count 506.000000 506.000000 506.000000 ... 506.000000 506.000000 506.000000\n", + "mean 3.613524 11.363636 11.136779 ... 356.674032 12.653063 22.532806\n", + "std 8.601545 23.322453 6.860353 ... 91.294864 7.141062 9.197104\n", + "min 0.006320 0.000000 0.460000 ... 0.320000 1.730000 5.000000\n", + "25% 0.082045 0.000000 5.190000 ... 375.377500 6.950000 17.025000\n", + "50% 0.256510 0.000000 9.690000 ... 391.440000 11.360000 21.200000\n", + "75% 3.677083 12.500000 18.100000 ... 396.225000 16.955000 25.000000\n", + "max 88.976200 100.000000 27.740000 ... 396.900000 37.970000 50.000000\n", + "\n", + "[8 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 143 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JimyY3SgECE" + }, + "source": [ + "#### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jScHq7eTgIpm", + "outputId": "50696c9d-c19a-4937-9189-368be5fb291c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 483 + } + }, + "source": [ + "correlacoes = df_boston.corr()\n", + "correlacoes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
crim1.000000-0.2004690.406583-0.0558920.420972-0.2192470.352734-0.3796700.6255050.5827640.289946-0.3850640.455621-0.388305
zn-0.2004691.000000-0.533828-0.042697-0.5166040.311991-0.5695370.664408-0.311948-0.314563-0.3916790.175520-0.4129950.360445
indus0.406583-0.5338281.0000000.0629380.763651-0.3916760.644779-0.7080270.5951290.7207600.383248-0.3569770.603800-0.483725
chas-0.055892-0.0426970.0629381.0000000.0912030.0912510.086518-0.099176-0.007368-0.035587-0.1215150.048788-0.0539290.175260
nox0.420972-0.5166040.7636510.0912031.000000-0.3021880.731470-0.7692300.6114410.6680230.188933-0.3800510.590879-0.427321
rm-0.2192470.311991-0.3916760.091251-0.3021881.000000-0.2402650.205246-0.209847-0.292048-0.3555010.128069-0.6138080.695360
age0.352734-0.5695370.6447790.0865180.731470-0.2402651.000000-0.7478810.4560220.5064560.261515-0.2735340.602339-0.376955
dis-0.3796700.664408-0.708027-0.099176-0.7692300.205246-0.7478811.000000-0.494588-0.534432-0.2324710.291512-0.4969960.249929
rad0.625505-0.3119480.595129-0.0073680.611441-0.2098470.456022-0.4945881.0000000.9102280.464741-0.4444130.488676-0.381626
tax0.582764-0.3145630.720760-0.0355870.668023-0.2920480.506456-0.5344320.9102281.0000000.460853-0.4418080.543993-0.468536
ptratio0.289946-0.3916790.383248-0.1215150.188933-0.3555010.261515-0.2324710.4647410.4608531.000000-0.1773830.374044-0.507787
b-0.3850640.175520-0.3569770.048788-0.3800510.128069-0.2735340.291512-0.444413-0.441808-0.1773831.000000-0.3660870.333461
lstat0.455621-0.4129950.603800-0.0539290.590879-0.6138080.602339-0.4969960.4886760.5439930.374044-0.3660871.000000-0.737663
preco-0.3883050.360445-0.4837250.175260-0.4273210.695360-0.3769550.249929-0.381626-0.468536-0.5077870.333461-0.7376631.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "crim 1.000000 -0.200469 0.406583 ... -0.385064 0.455621 -0.388305\n", + "zn -0.200469 1.000000 -0.533828 ... 0.175520 -0.412995 0.360445\n", + "indus 0.406583 -0.533828 1.000000 ... -0.356977 0.603800 -0.483725\n", + "chas -0.055892 -0.042697 0.062938 ... 0.048788 -0.053929 0.175260\n", + "nox 0.420972 -0.516604 0.763651 ... -0.380051 0.590879 -0.427321\n", + "rm -0.219247 0.311991 -0.391676 ... 0.128069 -0.613808 0.695360\n", + "age 0.352734 -0.569537 0.644779 ... -0.273534 0.602339 -0.376955\n", + "dis -0.379670 0.664408 -0.708027 ... 0.291512 -0.496996 0.249929\n", + "rad 0.625505 -0.311948 0.595129 ... -0.444413 0.488676 -0.381626\n", + "tax 0.582764 -0.314563 0.720760 ... -0.441808 0.543993 -0.468536\n", + "ptratio 0.289946 -0.391679 0.383248 ... -0.177383 0.374044 -0.507787\n", + "b -0.385064 0.175520 -0.356977 ... 1.000000 -0.366087 0.333461\n", + "lstat 0.455621 -0.412995 0.603800 ... -0.366087 1.000000 -0.737663\n", + "preco -0.388305 0.360445 -0.483725 ... 0.333461 -0.737663 1.000000\n", + "\n", + "[14 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 144 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AxQp7xqdgTJP" + }, + "source": [ + "##### Gráfico das correlações entre as features/variáveis/colunas\n", + "Source: https://seaborn.pydata.org/examples/many_pairwise_correlations.html\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KOiH2X-WgqmN", + "outputId": "f72007dc-7c99-4ce1-b6bb-b86a9bf617c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 557 + } + }, + "source": [ + "import seaborn as sns\n", + "from string import ascii_letters\n", + "import matplotlib.pyplot as plt\n", + "\n", + "sns.set_theme(style = \"white\")\n", + "\n", + "d = df_boston\n", + "\n", + "# Compute the correlation matrix\n", + "corr = d.corr()\n", + "\n", + "# Generate a mask for the upper triangle\n", + "mask = np.triu(np.ones_like(corr, dtype=bool))\n", + "\n", + "# Set up the matplotlib figure\n", + "f, ax = plt.subplots(figsize=(11, 9))\n", + "\n", + "# Generate a custom diverging colormap\n", + "cmap = sns.diverging_palette(230, 20, as_cmap=True)\n", + "\n", + "# Draw the heatmap with the mask and correct aspect ratio\n", + "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n", + " square=True, linewidths=.5, cbar_kws={\"shrink\": .5})" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 145 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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+PCqjgcAAGCEKv+cury8PAUEBKhhw4Y6f/68Vq9eLUnq2rWrPvjgA507d06lpaV69913XY+JiIhQamqqcnJyJElOp1NfffVVVUcFAACGsyyrUrfapMpH6sLDw/Xuu+8qMjJSjRo10p133qndu3frwQcf1I4dO/TII4+oQYMGCg0N1enTpyVJd911l37/+9/rt7/9rZxOp4qLi9WrVy/deuutVR0XAAAYjK8Juw433HCDXn311Qrv+81vfqPRo0ertLRUEydOVGhoqOu+Rx55RI888khVxwMAADCCrZ9TN3bsWB06dEiFhYXq3Lmzhg4damccAABgOIMH6uwtdX/+85/tPDwAAPAwdk2/njt3TuPHj9fXX38tb29vjR07Vt27dy+33T//+U/Nnz9f58+fd104GhcXd03H4BslAACAx7Dr4oeFCxcqICBAH374obKysjR48GBt2LBB/v7+ZbZr0qSJ/vKXv6hZs2Y6c+aMHn30Ud1+++268847r3qMKr/6FQAAwNOtX79eAwcOlCS1bdtWt956qzZt2lRuuy5duqhZs2aSpPr16ys4OFiHDh26pmMwUgcAADxGZQfq8vLyKvwChMDAQAUGBl7zfg4fPqybbrrJtdy8eXPXR7ddTmZmpnbu3KnExMRrOgalDgAAeIzKnlO3ePFizZs3r9z6+Ph4DRs2zLUcExOjw4cPV7iPzZs3Vy6kpGPHjun5559XQkKCa+Tuaih1AADAY1iqXKkbMmSIYmJiyq2/dJQuJSXlivtp0aKFDh06pKCgIEnSkSNHFBYWVuG2J0+e1K9+9Ss9++yz6t279zVnpdQBAACPUdnp18pOs15Or169tGLFCt12223KysrS7t279corr5Tb7ocfftCvfvUrDR48WLGxsZU6BhdKAAAAVLFnnnlGeXl56tmzp5577jklJSUpICBAkvTaa69p+fLlkqQ33nhDWVlZWrFihaKjoxUdHe36itWrYaQOAAB4DLs+p87Pz09z5syp8L7hw4e7fh47dqzGjh37k45BqQMAAB7Drs+pqw5MvwIAABjAyzK5sgIAAFzknzu/qdT2PUI7VFES9zN2+vWND7bZHUGS9OvIMB1Yt8ruGJKkNlGx6jt1id0xJElp4/9H3x48ancMSdLPWzZT94SFdseQJH2c+IyObP3U7hiSpOZ3d1PPpLfsjiFJ+nDSr+yO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KlaSFPmnt2xOIn3w4q/sjoBqwPQrAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAAaq81JWUlFT1IQAAADyez099YEhIiF544QV99NFHKiws1MiRIxUZGem6Lz4+Xp988onCw8P17LPPaurUqcrIyFBRUZHCwsI0fvx4eXt76+jRo3rppZeUlZUlSerTp4+ee+45nThxQgkJCfr+++8lSc8884z69et3/b8xAACAgX5yqZMkh8Oh1NRUfffdd3r88cd15513qnHjxpKkOnXqaPXq1ZKkiRMn6q677tL//u//qrS0VKNHj9bq1as1YMAAjR49Wt26ddPcuXMlSbm5uZKkl156ST//+c/15z//WceOHdOjjz6qTp06qUOHDtcTGQAAwEjXVepiY2MlSe3bt1enTp20c+dOPfjgg5KkmJgY13YbN27Url279NZbb0mSCgsL1axZMxUUFGjHjh2u9ZIUFBQkSdqyZYvGjRsnSWratKm6deumbdu2UeoAAAAqcF2l7kr8/PxcP1uWpfnz56tVq1ZltikoKKiqwwMAAHiU67pQ4sL0alZWlvbs2aPQ0NAKt4uIiNAbb7whp9Mp6ccp1uzsbPn7++sXv/iFFi1a5Nr2wvTrPffco5UrV0qSjh8/rk8//VR333339cQFAAAw1nWVOqfTqX79+um5555TUlKS63y6S02YMEEOh0PR0dHq27evnn32WR09elSSNHPmTH3xxRfq06ePHnnkEb3zzjuSpD/+8Y9KT09X3759FRcXp9GjR+vnP//59cQFAAAw1nVNv8bFxWnYsGHl1mdkZJRZDggIUGJiYoX7aNasmebPn19u/c9+9rMK1wMAAKA8PnwYAADAAD95pO7S0TgAAADYh5E6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAM4GVZlmV3CAAAAFwfRuoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqavA7t27NWrUKLtjVLno6GgVFhZW+nERERH65ptvqiBRzTomzBASEqKCgoKf/H63w7hx47R06VK37W/u3Lk6f/682/ZXncc/ePCgVqxYUWbd0KFD9f3337sjWjkX3i9V7WrHycvL04IFC655f3a/xqgZKHWXKCkp0W233aZXXnnF7ihVLjU1VXXr1rU7BtygpKTE7gg1np3vd7tfn3nz5qm4uLhGHv9qz82hQ4fKlboFCxaodevWbstXE+Xl5enNN9+85u2r6jW2+72LyvGxO0B127Fjh2bMmOH6L6QxY8Zo0qRJioqK0tatW9WhQwdFR0dr+vTpWrNmjQ4ePKj+/ftrwIAB+uyzz1RYWKiZM2cqOTlZX375perWrav58+erSZMmbsn36aefatasWa7lzMxMvfrqq5o7d666dOmiHTt2yMvLS7Nnz1ZwcPB1HSskJERffPGF/P39FRERoejoaG3evFnHjx9XXFycnnzySUnS9u3blZiYKEm66667dPHXBV+8j4uXHQ6Hxo4dq3379snHx0ft2rXTa6+9dk25KnqNJGn9+vV68cUXy+WbPn26Pv/8cxUXF6tRo0aaMmWKbrrpJp08eVKjRo3SyZMnJUn33HOPJkyY8JOfqxEjRujDDz/UqVOnNGbMGEVGRkqSNm3apFmzZsnpdCooKEhJSUlq1aqVnn32WXXr1k1DhgzRvn37NHToUC1fvlw33njjT8pQUab4+Hh98sknCg8PV05Ojnx9fZWVlaXs7Gz17NlT3bt319y5c5WTk6MhQ4ZoyJAhbjn2BaNGjdL+/ftVXFys1q1ba8qUKWrQoIFmz56tdevWqWHDhuratau2bNmiNWvWSJJSUlK0bNkyOZ1OBQQEaPLkyWrfvr3bMm3YsEGzZs1SnTp19NBDD7nWX3hv1qtXT0lJSdq6dat8fX3l5+en5ORktx3/4uNd/Pr07t1biYmJOnfunIqKijRgwAA9/fTTkqSjR49qzJgxOn78uG666SY5HO777+0Lf7uDBg2Sw+HQs88+q7fffttVAMaOHat77rlHJ0+eVGxsrF577TXddtttSklJ0cqVK7VkyRL5+Fz9/ypCQkL0wgsv6KOPPlJhYaFGjhypyMjIcsdfsmSJpkyZIm9vb+3fv18FBQVKTU297HspKSlJBw8eVHR0tNq0aaM5c+YoIiJCf/3rX9WhQwcdOHBAkyZNUm5urnx8fDRixAjdf//91/WcLVy4sNzvUVVKS0srfD8mJSXpzJkzio6OVr169ZScnKy//e1veu+99+R0OlWnTh1NnjxZHTt2rPA5DgwMvOJxL/d6Xbjv4vfus88+q6lTpyojI0NFRUUKCwvT+PHj5e3traNHj+qll15SVlaWJKlPnz567rnndOLECSUkJLhGVJ955hn169evyp5H/D+WB/nhhx+s//N//o/13//+17IsyyopKbFOnTplde/e3UpISHBtt3XrVismJsayLMvKzs62OnToYH388ceWZVnWggULrF/+8pfWnj17LMuyrISEBGvWrFlVknfFihXWwIEDrU8//dTq1KmT9fXXX1uWZVnz58+3Ro4ced3779Chg5Wfn29ZlmV1797dmjZtmmVZP/7OoaGhVn5+vlVUVGTdd9991tatWy3Lsqz33nvP6tChg5WRkVFuHxcvb9iwwYqLi3OtP3Xq1DVlutJrVFE+y7KskydPuh6/cuVK6/e//71lWZb11ltvWS+++GKlM1SkQ4cO1pIlSyzLsqzt27db9913n2VZlnXixAkrLCzM+vbbb13Hf+yxx1z3de/e3frPf/5j9enTx/UecpcOHTpYr7/+umt57Nix1qBBg6yioiLr7Nmz1t13322NGzfOcjqdVk5OTpnnzF0ufu5nzZplvfzyy9ZHH31k9e3b1yooKLCcTqf1wgsvuP6e/vOf/1hDhw61ioqKLMuyrE8++cQaOHCg2/IcP37c6tq1q5WZmWlZlmW98cYbrvfkhf/9+uuvrV69ellOp9OyrOt7X1zJpa/PmTNnXL93fn6+1bt3b2vfvn2WZVlWfHy8NXfuXMuyLOv777+3QkNDXe83d2W58Nrn5uZapaWllmVZVmZmphUeHu7abuvWrdZDDz1k7dixw3rggQesw4cPV+oYF36HzMxMq2vXrtaJEyfKHd+yfnyvxsTEWAUFBa51Fb2XLmS68P65oHv37q5/Bz322GPWypUrLcuyrG+//dbq2rVrmX1V1pV+D3e62vsxOzvb6tq1a5nHXPx7/fvf/7ZiY2PL7a8yx7/S63Xxe3fChAlWSkqKZVmW5XQ6rREjRlgrVqywLMuynnzySWvBggXlMg4fPtyaPXu2ZVmWdfToUevee+91vWaoOh41Urdz504FBwfrjjvukCR5e3urQYMGknTF/4Lw8/PTAw88IEnq3LmzbrzxRnXs2NG1vHnzZrdn/eyzz/TWW2/p73//u7799lu1a9dOnTp1kiSFhobq448/dvsxo6KiJEktW7ZUYGCgcnJyVFxcrHr16iksLMy1zaRJk666r1tuuUWZmZlKTExU165dXc/f1VzpNaooX3BwsDZt2qRly5bp7NmzZaYKunTpokWLFmn69Onq2rWr7rvvvmt+Lipy4fihoaE6duyYioqK9OWXX+qWW27RzTffLEnq37+/EhMTlZ+fr8aNG2vKlCkaMmSI/ud//uean4PKiImJKbPco0cP+fr6SpLatWunbt26yeFwqFmzZmWeM3dJTU1VWlqaiouLdfbsWbVt21bFxcXq3bu3/Pz8JP34tzV//nxJ0saNG5Wenq7Y2FhJkmVZysvLc1ueL7/8Up06dXKN/A0cOFAzZ84ss02rVq1UUlKiiRMnKiwsTN27d3fb8S918etTWFioyZMnKyMjQ15eXjp27JjS09MVHBysbdu26Y9//KMr3z333FNlmbKzszVq1CgdPXpUPj4+OnHihI4fP64mTZooLCxMffr00RNPPKF58+apefPmldr3hde1ffv26tSpk3bu3KkHH3ywwm179erleo9IFb+XriY/P1979+5V//79JUk333yzOnbsqJ07dyoiIqJS2X/q73G9KvN+/Oqrr/T666/r9OnT8vLyco2O/VRX+j0vfu9u3LhRu3bt0ltvvSXpx/dys2bNVFBQoB07drjWS1JQUJAkacuWLRo3bpwkqWnTpurWrZu2bdumDh06XFdmXJlHlborufhfLpe68H+SkuRwOMose3t7y+l0ujVLenq6EhIStHDhQtcfyKUZquI8hzp16rh+vtLv5eXlVWY76/9NxxYVFbnWt2rVSmvXrtXWrVu1adMmzZ49W2lpaWWO4Y58hw4d0tSpU/XOO++oVatW+uKLLzR69GhJ0i9+8QulpKRo8+bNSk1N1RtvvKHly5df9/G9vb0lXdu5Jnv37lWjRo2Uk5Pzk497JZe+by99jq71Nf0ptm/fruXLlys5OVlBQUFKS0vTypUrr/gYy7LUv39/DR8+3G05Kqt+/fp67733tG3bNm3evFkzZ85USkqK206huNjFr8+sWbPUpEkTTZs2TT4+PoqLiyvzN1NdRo4cqXHjxqlHjx4qLS1Vly5dyuTYs2ePgoKCquw9e8HFz81PeS+Z4nLvx0udP39ew4cP19KlS9W5c2cdPXr0uqeZr+Ti18eyLM2fP1+tWrUqs011XFCCyvGoCyVCQ0OVmZmpHTt2SJKcTqdOnz5tc6qyjh49qmHDhunll19Wu3bt7I6j9u3bq7CwUNu3b5ckvf/++2VGVlq3bq3du3dLktLS0lzrc3Jy5O3trR49emj8+PHKzc3VqVOnrnq8yr5G+fn5uuGGG9SkSROVlpaWOTcqOztbAQEBevjhhzV+/Hh9/fXXKi0trdwTcA1509PTlZmZKenH88U6deqkgIAA7dq1S0uXLlVqaqpyc3Ovq1DWRHl5eQoICFDDhg11/vx5rV69WpLUtWtXffDBBzp37pxKS0v17rvvuh4TERGh1NRUV2FwOp366quv3JYpNDRUe/bscY1grFq1qtw2ubm5OnfunMLDwzV69GjVr19f2dnZbstwOWfOnNGNN94oHx8fffPNN66/KUm6++67Xc9fdna2tmzZ4tZj+/v7Kz8/35WjZcuWkqTVq1eXuWJy0aJFKikp0Zo1a/Tmm29q7969lTrOhd8hKytLe/bsUWhoaLnjV+Ry7yVJCggIuOxjAwIC1LFjx//bvv27tK6GcQD/WlQKRpK2oCA6VBAHHSpYcKmCDgZJ1UFwcxAs1kEslkpaDbRdSlscdHMqCiKYSfwHXF0EXXRwEnEQOoho0TTnDmK4Pd5e9Vw9nhu/nzEheX/kDXnyvu9jBUHn5+c4PT21yv1V1drxGaqNR0EQUCqVrJ/Hh4cHGIZhzZ5ub29X3Oe1Pv4nb23n4OAgNjY2rJ/CYrGIi4sLNDQ0oKenB4VCoaI9wNMe5ufA/Pr6GgcHB+jr63tX/ej9vtVMnSRJWF9fRyaTwd3dnbWZ/0+yu7uLYrGIVCplHVNV9cvqU19fj9XV1YpEiZaWFuu8qqrQNA2NjY2QZdk6fnZ2ZmUQm6aJUCiE5ubmV8t77zPq7OyELMsYGRmBy+XCwMCA9bE8PDxEoVCAw+GAaZpIJpMfugEdeFpqyGaziEajMAwDbrcbuVwONzc3WFxcRCaTgcfjQT6fx+TkJHw+n7V0/38XCASwt7eH4eFhuFwu9Pb24uTkBENDQzg6OsLo6ChEUYTP57MCc7/fj4WFBYTDYZTLZTw+PkKWZXR3d39InTweD9LpNGZnZ+F0OisSJZ5dXV1hZWUFhmGgXC6jv7//Uz/az8LhMGKxGHRdh9frhd/vt84lEgnEYjHs7++jtbXV2u7wUaanpzE1NQWn0wlVVTE3NwdRFBEIBCBJEgDg+PgYm5ub0HUdbrcb6XQakUgEuq5DEIQ3lVMulzE+Po77+3ukUil4PJ4X5W9tbb24rtpYAp7eca/XC0VR0N7ejrW1tYpr8/k8NE1DoVBAbW0tstmstcLxq6q14zNUG48OhwPBYBDBYBCiKGJnZwfz8/OYmJiAJEkvkjd+7uPXEiWAt7czHo8jl8thbGwMNTU1qKurQzweR1tbG/L5PJLJJBRFgcPhgKIoCIVCWF5ehqZpCAaDAIBoNIqOjo7/3mH0r2p+/PhbKiMR0Qe4vb2FIAgwTROJRAJNTU2IRCJfXS36RD9nwtOfjc/Lnr7VTB0R/R5LS0u4vLxEqVRCV1cXZmZmvrpKRES2x5k6IiIiIhv4VokSRERERHbFoI6IiIjIBhjUEREREdkAgzoiIiIiG2BQR0RERGQDDOqIiIiIbOAvF2TfJBn+6VQAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nogPhyfVO70G" + }, + "source": [ + "### Construir e treinar o(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HxYpfyvQaIe1" + }, + "source": [ + "$X = [X_{1}, X_{2}, X_{p}]$ = X_boston abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BhLZJhibVNG" + }, + "source": [ + "X_boston = df_boston.drop(columns = ['preco'], axis = 1) # todas as variáveis/atributos, exceto 'preco'\n", + "y_boston = df_boston['preco'] # variável-target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_nC_RGva1Z6", + "outputId": "6a5946c8-62b3-424f-a809-9a2bbc34f191", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "X_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstat
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... rad tax ptratio b lstat\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 147 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nlVJM--Ya5fS", + "outputId": "58037983-175f-47ed-ad47-5826589358b0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_boston[0:10] # Series (coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 24.0\n", + "1 21.6\n", + "2 34.7\n", + "3 33.4\n", + "4 36.2\n", + "5 28.7\n", + "6 22.9\n", + "7 27.1\n", + "8 16.5\n", + "9 18.9\n", + "Name: preco, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 148 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b50_6tv5h1kY" + }, + "source": [ + "# Definindo os dataframes de treinamento e teste:\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, \n", + " y_boston, \n", + " test_size = 0.2, \n", + " random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U3hpdkDbYTv", + "outputId": "35e8cee1-201a-4a65-a6ec-8fa9e8c7c0a8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(f\"Dataframe de treinamento: {X_treinamento.shape[0]} linhas\")\n", + "print(f\"Dataframe de teste......: {X_teste.shape[0]} linhas\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Dataframe de treinamento: 404 linhas\n", + "Dataframe de teste......: 102 linhas\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SvevXulFiJj1" + }, + "source": [ + "#### Treinamento do modelo de Regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GVwF3vp8iNff" + }, + "source": [ + "# Importa a library LinearRegression --> Para treinamento da Regressão Linear\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Library para statmodels\n", + "import statsmodels.api as sm" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ibX6bCbViW-v" + }, + "source": [ + "# Instancia o objeto\n", + "regressao_linear = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M-5wRGUribY0", + "outputId": "a67d7355-3d9e-43fc-edf6-8ebd71911935", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Treina o modelo usando as amostras/dataset de treinamento: X_treinamento e y_treinamento \n", + "regressao_linear.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 153 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jri-jA1VjmUl", + "outputId": "3150261d-c264-4273-9c5f-95229529881b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Valor do intercepto\n", + "regressao_linear.intercept_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.9020918753502" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 154 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOjadxdxjqtT", + "outputId": "49d06bd9-e375-403f-e257-863967f10fd3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 452 + } + }, + "source": [ + "# Coeficientes do modelo de Regressão Linear\n", + "coeficientes_regressao_linear = pd.DataFrame([X_treinamento.columns, regressao_linear.coef_]).T\n", + "coeficientes_regressao_linear = coeficientes_regressao_linear.rename(columns={0: 'Feature/variável/coluna', 1: 'Coeficientes'})\n", + "coeficientes_regressao_linear" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Feature/variável/colunaCoeficientes
0crim-0.0822083
1zn0.0428002
2indus0.0756011
3chas3.16348
4nox-19.4945
5rm3.98161
6age0.00480929
7dis-1.37396
8rad0.298883
9tax-0.0123962
10ptratio-0.984657
11b0.008949
12lstat-0.526478
\n", + "
" + ], + "text/plain": [ + " Feature/variável/coluna Coeficientes\n", + "0 crim -0.0822083\n", + "1 zn 0.0428002\n", + "2 indus 0.0756011\n", + "3 chas 3.16348\n", + "4 nox -19.4945\n", + "5 rm 3.98161\n", + "6 age 0.00480929\n", + "7 dis -1.37396\n", + "8 rad 0.298883\n", + "9 tax -0.0123962\n", + "10 ptratio -0.984657\n", + "11 b 0.008949\n", + "12 lstat -0.526478" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 155 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwnkhPwDjkhS" + }, + "source": [ + "#### Usando statmodels" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ltbekHd_k3PH", + "outputId": "a69b057e-75a6-446e-8b7c-ad37604114a5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2_treinamento = sm.add_constant(X_treinamento)\n", + "lm_sm = sm.OLS(y_treinamento, X2_treinamento).fit()\n", + "print(lm_sm.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 78.97\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.48e-100\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2458.\n", + "Df Residuals: 390 BIC: 2514.\n", + "Df Model: 13 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.9021 6.037 5.947 0.000 24.033 47.771\n", + "crim -0.0822 0.045 -1.824 0.069 -0.171 0.006\n", + "zn 0.0428 0.016 2.638 0.009 0.011 0.075\n", + "indus 0.0756 0.072 1.054 0.292 -0.065 0.217\n", + "chas 3.1635 0.997 3.174 0.002 1.204 5.123\n", + "nox -19.4945 4.539 -4.295 0.000 -28.418 -10.571\n", + "rm 3.9816 0.510 7.802 0.000 2.978 4.985\n", + "age 0.0048 0.015 0.312 0.755 -0.025 0.035\n", + "dis -1.3740 0.236 -5.827 0.000 -1.838 -0.910\n", + "rad 0.2989 0.079 3.760 0.000 0.143 0.455\n", + "tax -0.0124 0.004 -2.814 0.005 -0.021 -0.004\n", + "ptratio -0.9847 0.156 -6.309 0.000 -1.292 -0.678\n", + "b 0.0089 0.003 2.796 0.005 0.003 0.015\n", + "lstat -0.5265 0.060 -8.764 0.000 -0.645 -0.408\n", + "==============================================================================\n", + "Omnibus: 140.799 Durbin-Watson: 2.083\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 591.650\n", + "Skew: 1.484 Prob(JB): 3.35e-129\n", + "Kurtosis: 8.132 Cond. No. 1.51e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.51e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kpt3A4Q0guHv" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVUJkfg4gSh7", + "outputId": "eeff1e8f-8ac7-44e8-e0fe-caf0d4a641c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X3 = X_treinamento.drop(columns = 'age', axis = 1)\n", + "X3_treinamento = sm.add_constant(X3)\n", + "lm_sm2 = sm.OLS(y_treinamento, X3_treinamento).fit()\n", + "print(lm_sm2.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 85.75\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.64e-101\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 391 BIC: 2508.\n", + "Df Model: 12 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.7325 6.006 5.950 0.000 23.925 47.540\n", + "crim -0.0815 0.045 -1.812 0.071 -0.170 0.007\n", + "zn 0.0422 0.016 2.623 0.009 0.011 0.074\n", + "indus 0.0750 0.072 1.048 0.295 -0.066 0.216\n", + "chas 3.1794 0.994 3.198 0.001 1.225 5.134\n", + "nox -19.1299 4.381 -4.367 0.000 -27.742 -10.517\n", + "rm 4.0153 0.498 8.059 0.000 3.036 4.995\n", + "dis -1.3963 0.224 -6.223 0.000 -1.837 -0.955\n", + "rad 0.2958 0.079 3.755 0.000 0.141 0.451\n", + "tax -0.0123 0.004 -2.802 0.005 -0.021 -0.004\n", + "ptratio -0.9812 0.156 -6.310 0.000 -1.287 -0.675\n", + "b 0.0090 0.003 2.825 0.005 0.003 0.015\n", + "lstat -0.5202 0.057 -9.203 0.000 -0.631 -0.409\n", + "==============================================================================\n", + "Omnibus: 142.363 Durbin-Watson: 2.081\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 608.694\n", + "Skew: 1.496 Prob(JB): 6.67e-133\n", + "Kurtosis: 8.216 Cond. No. 1.48e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.48e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lcp7m5FmZvG" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'indus'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jEiBywx4hGNB", + "outputId": "fb2abfd1-9019-4e37-f6e1-cf5e54ae1276", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X4 = X3_treinamento.drop(columns = 'indus', axis = 1)\n", + "X4_treinamento = sm.add_constant(X4)\n", + "lm_sm3 = sm.OLS(y_treinamento, X4_treinamento).fit()\n", + "print(lm_sm3.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.724\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 93.42\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 2.86e-102\n", + "Time: 11:00:14 Log-Likelihood: -1215.4\n", + "No. Observations: 404 AIC: 2455.\n", + "Df Residuals: 392 BIC: 2503.\n", + "Df Model: 11 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.4757 6.001 5.911 0.000 23.677 47.275\n", + "crim -0.0840 0.045 -1.871 0.062 -0.172 0.004\n", + "zn 0.0407 0.016 2.539 0.012 0.009 0.072\n", + "chas 3.2924 0.989 3.330 0.001 1.349 5.236\n", + "nox -17.9558 4.235 -4.239 0.000 -26.283 -9.629\n", + "rm 3.9674 0.496 7.996 0.000 2.992 4.943\n", + "dis -1.4553 0.217 -6.699 0.000 -1.882 -1.028\n", + "rad 0.2744 0.076 3.606 0.000 0.125 0.424\n", + "tax -0.0103 0.004 -2.603 0.010 -0.018 -0.003\n", + "ptratio -0.9609 0.154 -6.227 0.000 -1.264 -0.658\n", + "b 0.0089 0.003 2.778 0.006 0.003 0.015\n", + "lstat -0.5151 0.056 -9.145 0.000 -0.626 -0.404\n", + "==============================================================================\n", + "Omnibus: 142.123 Durbin-Watson: 2.073\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 605.868\n", + "Skew: 1.494 Prob(JB): 2.74e-132\n", + "Kurtosis: 8.202 Cond. No. 1.47e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.47e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFejox5XmrEE" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'crim'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DOehOql8hZWr", + "outputId": "cbb71827-f44e-4688-93c4-98a3ec5e3257", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X5 = X4_treinamento.drop(columns = 'crim', axis = 1)\n", + "X5_treinamento = sm.add_constant(X5)\n", + "lm_sm4 = sm.OLS(y_treinamento, X5_treinamento).fit()\n", + "print(lm_sm4.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.721\n", + "Model: OLS Adj. R-squared: 0.714\n", + "Method: Least Squares F-statistic: 101.8\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.55e-102\n", + "Time: 11:00:14 Log-Likelihood: -1217.2\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 393 BIC: 2500.\n", + "Df Model: 10 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 33.9950 5.968 5.696 0.000 22.262 45.728\n", + "zn 0.0375 0.016 2.349 0.019 0.006 0.069\n", + "chas 3.3959 0.990 3.430 0.001 1.449 5.343\n", + "nox -17.1637 4.228 -4.060 0.000 -25.475 -8.852\n", + "rm 4.0365 0.496 8.132 0.000 3.061 5.012\n", + "dis -1.3999 0.216 -6.484 0.000 -1.824 -0.975\n", + "rad 0.2278 0.072 3.158 0.002 0.086 0.370\n", + "tax -0.0100 0.004 -2.513 0.012 -0.018 -0.002\n", + "ptratio -0.9493 0.155 -6.137 0.000 -1.253 -0.645\n", + "b 0.0101 0.003 3.217 0.001 0.004 0.016\n", + "lstat -0.5315 0.056 -9.523 0.000 -0.641 -0.422\n", + "==============================================================================\n", + "Omnibus: 140.245 Durbin-Watson: 2.070\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 609.563\n", + "Skew: 1.464 Prob(JB): 4.32e-133\n", + "Kurtosis: 8.257 Cond. No. 1.46e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.46e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UafIUrpZB0YP" + }, + "source": [ + "### Conclusão\n", + "* Quais variáveis/colunas/atributos ficam no modelo?\n", + "* **Muito importante (exercício)**: normalizar (MinMaxScaler) as covariáveis e refazer a análise.\n", + "* Nesta iteração (depois de excluirmos (nesta ordem) as variáveis age, indus e crim, não surge nenhuma outra variável insignificante ao nível de 5 (na verdade, o maior valor é 1.9%)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jx7sOzrrm-H_" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXeiFtnJO_1u" + }, + "source": [ + "### Validação do(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlGVFA6uPDvr" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PE3aKJ6mPDyJ" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3nGiyX8jadH" + }, + "source": [ + "### Deployment da solução **analítica**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YQF4NIlGSLH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UQfpoo1igFy8" + }, + "source": [ + "# Regularized Regression Methods \n", + "## Ridge Regression - Penalized Regression\n", + "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando (valor de $\\alpha$) os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n", + "* Menor impacto dos outliers.\n", + "\n", + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o00xH2MvxvgP" + }, + "source": [ + "# Matriz de covariáveis do modelo:\n", + "X_new = [[0, 0], [0, 0], [1, 1]]\n", + "X_new2 = [[0, 0], [0, 1.5], [1, 1]]\n", + "\n", + "y_new = [0, .1, 1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v9U7c03NzW_c", + "outputId": "2652bd10-e6b4-4200-f7f0-a07806564a1d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_new # 2 variáveis/colunas no dataframe" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[[0, 0], [0, 0], [1, 1]]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 161 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iiVEAPpUzXyN", + "outputId": "a69fe575-57da-459c-f482-41d3185ab76f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 0.1, 1]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 162 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDljolA95Hw5" + }, + "source": [ + "### Sem outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8mWj2GbPOkHx", + "outputId": "3b433090-a588-449a-af69-5f2da53a9b60", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new, y_new)\n", + "ridge.coef_ # Coeficientes da Ridge" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mridge\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mRidge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0malpha\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_new\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_new\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoef_\u001b[0m \u001b[0;31m# Coeficientes da Ridge\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'Ridge' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8yvd4ABY5JjC" + }, + "source": [ + "### Com outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O3sJZ_pe5GQ7" + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new2, y_new)\n", + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zZxdCLU_5kKh" + }, + "source": [ + "#### Conseguiram visualizar o impacto dos outliers?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u5jsTkUmS9wK" + }, + "source": [ + "### Aplicação da Regressão Ridge no dataframe Boston Housing Price." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kp4VIJWxgFy8" + }, + "source": [ + "from sklearn.linear_model import Ridge\n", + "ridge = Ridge(alpha = 0.1) # Definição do valor de alpha da regressão ridge\n", + "lr = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cmRMoOwV6FMt" + }, + "source": [ + "# Ao inves de: regressao_linear.fit(X_treinamento, y_treinamento)\n", + "ridge.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VPnekyUbK6Xg" + }, + "source": [ + "#### Peso/contribuição das variáveis para a regressão usando RIDGE" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k83RDArjsUrj" + }, + "source": [ + "df_boston.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vMCb0CFjK973" + }, + "source": [ + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZqksuIjXypRJ" + }, + "source": [ + "# treinando a regressão Ridge\n", + "ridge.fit(X_treinamento, y_treinamento)\n", + "\n", + "# treinando a regressão linear simples (OLS)\n", + "lr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7r28PBsWLtjA" + }, + "source": [ + "ridge.alpha" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dDZ_TJnhuZno" + }, + "source": [ + "#### $\\alpha = 0.01$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hRMK_QTmNgc1" + }, + "source": [ + "# maior alpha --> mais restrição aos coeficientes; \n", + "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS; Se alpha = 0 ==> Ridge = OLS.\n", + "rr = Ridge(alpha = 0.01) # Quanto mais próximo de 0 ==> Ridge = OLS\n", + "rr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRuWmBE7Ngc7" + }, + "source": [ + "# MSE = Erro Quadrático Médio\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n", + "lr_model=(mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "L4an-zHetafI" + }, + "source": [ + "print(rr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QsLVzk3EtbGs" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K2sjngo1QhY2" + }, + "source": [ + "### Coeficientes da Ridge:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5i87o3quByz" + }, + "source": [ + "# Lista das variáveis + coeficientes da Ridge:\n", + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s44vo9IjQonE" + }, + "source": [ + "### Experimente vários outros valores para $\\alpha$ como, por exemplo, $\\alpha = 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CDv5fGPbuUq5" + }, + "source": [ + "#### $\\alpha = 100$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEaj4QRrNgdA" + }, + "source": [ + "rr100 = Ridge(alpha = 100)\n", + "rr100.fit(X_treinamento, y_treinamento)\n", + "train_score=lr.score(X_treinamento, y_treinamento)\n", + "test_score=lr.score(X_teste, y_teste)\n", + "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zhcfoTEENgdE" + }, + "source": [ + "# MSE\n", + "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n", + "lr_model = (mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NGDBpfiquxoc" + }, + "source": [ + "print(rr100_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Owami5MVureW" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xk5dN3Owu6Kw" + }, + "source": [ + "### Próximo passo: fazer o statmodel dos modelos ridge." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEF_3GgUgF0Q" + }, + "source": [ + "# LASSO (Least Absolute Shrinkage And Selection Operator regularization)\n", + "* Método mais comum e usado para Regularization; \n", + "* Reduz overfitting;\n", + "* Se encarrega do **Feature Selection**, pois descarta variáveis altamente correlacionadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YiKb9reQdI4" + }, + "source": [ + "* Usado no processo de Regularization - processo de penalizar as variáveis para manter somente os atributos mais importantes. Pense na utilidade disso diante de um dataframe com muitas variáveis;\n", + "* A regressão Lasso vem com um parâmetro ($\\alpha$), e quanto maior o alfa, a maioria dos coeficientes de recurso é zero. Ou seja, quando $\\alpha = 0$, a regressão Lasso produz os mesmos coeficientes que uma regressão linear. Quando alfa é muito grande, todos os coeficientes são zero." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5p_ZPZ4tTUX1" + }, + "source": [ + "### Exemplo LASSO" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JD1_M2uw6q0W" + }, + "source": [ + "X_new" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5JZTnkTOkI9" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_new, y_new)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gEUxSlThOkJD" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EQaGWzzLT9qP" + }, + "source": [ + "### Aplicação do LASSO no Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ME6v6LFlgF0Q" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h6DSEHc1gF0V" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8SzYnpVGy4cy" + }, + "source": [ + "### Coeficientes do LASSO:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2w2QDmdxxVe" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(lasso.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UBOCg1H9zn6A" + }, + "source": [ + "### Comparação com os coeficientes do RIDGE:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g1fF-mEZzXpH" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xP1fX1Bi6VdX" + }, + "source": [ + "**Conclusão**: Coeficientes zero podem ser excluídos da Análise/modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TbtxIWyGSXkH" + }, + "source": [ + "### Efeito dos valores de $\\alpha$\n", + "* Função adaptada de https://chrisalbon.com/machine_learning/linear_regression/effect_of_alpha_on_lasso_regression/." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B4AuWA4LRBE3" + }, + "source": [ + "# Create a function called lasso,\n", + "def lasso(alphas):\n", + " '''\n", + " Takes in a list of alphas. Outputs a dataframe containing the coefficients of lasso regressions from each alpha.\n", + " '''\n", + " # Create an empty data frame\n", + " df = pd.DataFrame()\n", + " \n", + " # Create a column of feature names\n", + " df['Feature Name'] = names\n", + " \n", + " # For each alpha value in the list of alpha values,\n", + " for alpha in alphas:\n", + " # Create a lasso regression with that alpha value,\n", + " lasso = Lasso(alpha = alpha)\n", + " \n", + " # Fit the lasso regression\n", + " lasso.fit(X_treinamento, y_treinamento)\n", + " \n", + " # Create a column name for that alpha value\n", + " column_name = 'Alpha = %f' % alpha\n", + "\n", + " # Create a column of coefficient values\n", + " df[column_name] = lasso.coef_\n", + " \n", + " # Return the datafram \n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VEDvXvuNRK0C" + }, + "source": [ + "names = X_treinamento.columns\n", + "\n", + "# Valores de alpha:\n", + "lasso([.0001, .001, 0, .01, .1, 1, 10, 100])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xFlvTUJKhwgW" + }, + "source": [ + "### Capturando os elementos mais importantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4_-sUgMIhzmE" + }, + "source": [ + "r_squared = model.rsquared\n", + "r_squared_adj = model.rsquared_adj\n", + "coeficientes_regressao = model.params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "apGv5ytnimsM" + }, + "source": [ + "VEJA: https://stackoverflow.com/questions/27928275/find-p-value-significance-in-scikit-learn-linearregression" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uhokzxtcil8w" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jSYw6SdcXa0q" + }, + "source": [ + "### Cross-Validation & GridSearch para LASSO" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E14i4Y3rqEX2" + }, + "source": [ + "### Colocar aqui a fórmula do RMSE." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "irFZAkvVXfya" + }, + "source": [ + "from sklearn.linear_model import LassoCV\n", + "from sklearn.model_selection import RepeatedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T3Jjom8RYdly" + }, + "source": [ + "# define model evaluation method\n", + "cv = RepeatedKFold(n_splits = 5, n_repeats = 3, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cw3lAvRPYgJe" + }, + "source": [ + "# define model\n", + "model = LassoCV(alphas = np.arange(0.001, 10, 0.001), cv = cv, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLX3CpThXvkJ" + }, + "source": [ + "# fit model\n", + "model.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U1ubd5huYQ7u" + }, + "source": [ + "# summarize chosen configuration\n", + "print('alpha: %f' % model.alpha_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9P7hYoo4gF0Z" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yChNUYs7gF0b" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "S1m3SL2avMbd" + }, + "source": [ + "transformacao.fit(dados_que_eu_quero_transformar)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4mbIaAUAF4N6" + }, + "source": [ + "en.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MaUkZw8ngF0h" + }, + "source": [ + "list(zip(X_treinamento, en.coef_))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K7LuPhCtvouJ" + }, + "source": [ + "### GridSearch para encontrar o $\\alpha$ para Elastic Net" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xl-Qh9caDyCp" + }, + "source": [ + "# Instancia o objeto:\n", + "en = ElasticNet(normalize = True)\n", + "\n", + "# Otimização dos hiperparâmetros:\n", + "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n", + " 'l1_ratio': [.2, .4, .6, .8]}\n", + "\n", + "search = GridSearchCV(estimator = en, # Elastic Net\n", + " param_grid = d_hiperparametros, # Dicionário com os hiperparâmetros\n", + " scoring = 'mean_squared_error', # MSE (Erro Quadrático Médio) - Métrica para avaliação da performance do modelo\n", + " #scoring = 'neg_mean_squared_error',\n", + " n_jobs = -1, # Usar todos os processadores/computação\n", + " refit = True, \n", + " cv = 10) # Número de Cross-Valitations" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JvNQyUW_2QLr" + }, + "source": [ + "### Exercício (Estatística): Sugestão de ajuste manual\n", + "* Estudar estatisticamente a distribuição de frequência em que a variável é significante (ao nível de 5%) em 100 fits." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hp1hV5YahsJb" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ng0rPXfA1DgS" + }, + "source": [ + "for i in range(0, 100):\n", + " X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X, y, 0.2)\n", + " modeloi = fit(X_treinamento, y_treinamento)\n", + " intercepto\n", + " coeficientes da regressão\n", + " validação dos parâmetros (significância)\n", + " y_predict = predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c3_XCQCPGlr3" + }, + "source": [ + "search.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Retorna os melhores hiperparâmetros do algoritmo:\n", + "search.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq0_ugQfGrdb" + }, + "source": [ + "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n", + "en2.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ILA5lScUx-Ub" + }, + "source": [ + "\n", + "# Métrica\n", + "ml2 = (mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))\n", + "# Encontrar a métrica neg_squared_error --> ml3 = (neg_mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BzO_dHRixd_L" + }, + "source": [ + "print(f\"MSE: {ml2}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zaEwh3t3zwFc" + }, + "source": [ + "**Conclusão**:\n", + "* Comparação dos MSE - A Regressão sem Regularization produziu MSE de 23.94. Como podemos ver, Elastic Net produz MSE: 15.4." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5geUMgC6ztxE" + }, + "source": [ + "### Coeficientes do Elastic Net:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LyLdASRqzwCq" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "90pfP9-3OkJG" + }, + "source": [ + "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILCXvYKDOkJH" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaQPDCR2OkJI" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xVp16Eu_OkJL" + }, + "source": [ + "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwj018U8OkJO" + }, + "source": [ + "en.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rJRWBzSQCcss" + }, + "source": [ + "# Regressão Logística\n", + "\n", + "* Na regressão linear nós tentamos modelar a relação linear entre as features ($X_{np} = [X_{1}, X_{2}, ..., X_{p}]$) através de uma reta dada pela equação:\n", + "\n", + "$$\\hat{y}= \\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p}$$\n", + "\n", + "Para classificação, a Regressão Logística vai nos retornar probabilidades (entre 0 e 1), dada pela equação logística ( também conhecida **função sigmoid**):\n", + "\n", + "$$P[y = 1]= \\frac{1}{1+e^{-(\\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p})}}$$\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vj83Altwdni7" + }, + "source": [ + "![SigmoidFunction](https://github.com/MathMachado/Materials/blob/master/SigmoidFunction.PNG?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LS1QjQnknqe5" + }, + "source": [ + "## Pressupostos da Regressão Logística\n", + "* Não há valores nulos no banco de dados;\n", + "* A variável-resposta $y$ é binária (0 ou 1) ou ordinal (variável categórica com valores ordenados (por exemplo, estimar a qualidade do vinho));\n", + "* Todas as variáveis preditoras $X$ são independentes;\n", + "* Há (pelo menos) 50 observações para cada variável preditora no modelo preditivo --> Quanto mais, melhor. Isso visa garantir a confiabilidade dos resultados);\n", + "* As classes da variável-resposta estejam equilibradas;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YGvpGTAd4jO" + }, + "source": [ + "# Exemplo 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-LBYRG__e_Zv" + }, + "source": [ + "### Carregar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XX2GNYWue-iA" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "import statsmodels.api as sm\n", + "import statsmodels.formula.api as smf\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.metrics import roc_auc_score, roc_curve, classification_report, accuracy_score, confusion_matrix, auc" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpNu-JjJfBYe" + }, + "source": [ + "### Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dWVj8SmUeBZB", + "outputId": "ddb92623-228d-4621-90f9-b80b1a0d06c9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n", + "df_titanic = pd.read_csv(url)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " PassengerId Survived Pclass ... Fare Cabin Embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 289 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9vZGvU5qbsQ", + "outputId": "6ad44206-7129-4e4e-a03d-cec7aeab3449", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic.columns = [coluna.lower() for coluna in df_titanic.columns]\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 290 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fAYAg5tofDgQ" + }, + "source": [ + "### Entendendo os dados\n", + "* sibsp - número of siblings/esposas abordo do Titanic;\n", + "* parch - número de parentes/crianças abordo do Titanic;\n", + "* embarked - Cidade/Portão de embarque: C = Cherbourg, Q = Queenstown, S = Southampton." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZbijPdpFxdZy" + }, + "source": [ + "#### A variável-target é do tipo binária ou categórica ordinal?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7hspb3IMe5tx", + "outputId": "684c59df-d788-400f-a179-0774a39e4303", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['survived'].value_counts()/df_titanic.shape[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 0.616162\n", + "1 0.383838\n", + "Name: survived, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tsp4t7oxx3zC" + }, + "source": [ + "A seguir, o gráfico da variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vm0BDjw-xrGI", + "outputId": "443def8e-dee6-40f5-8bcf-b33a43bb5c15", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 296 + } + }, + "source": [ + "sns.countplot(x = 'survived', data = df_titanic)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 292 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XfhFG6Axxj6F" + }, + "source": [ + "Como podemos ver, a variável-resposta 'survived' é binária. Portanto, tudo ok até agora." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zRKhDX6ZraGU" + }, + "source": [ + "### Tratamento dos Missing Values\n", + "* Substituir os NaN's por mediana da variável" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qPbILjZyrhRZ", + "outputId": "52f34626-1875-4632-cce3-8a694863ea6c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 293 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uJUPufRossTo" + }, + "source": [ + "Cálculo da mediana da variável/preditora 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WGW9bW5x4JdT", + "outputId": "c0ce5e66-70fe-4195-c637-2ac8a4cf9d37", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 294 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DgAwrR8msYv_" + }, + "source": [ + "mediana_age = df_titanic['age'].median()\n", + "mediana_fare = df_titanic['fare'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yqIgckarzwdB", + "outputId": "a190a691-e377-42ba-a8f8-98d430ccabbd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_age" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 297 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "czdSVeLjzxAX", + "outputId": "48bdfb0b-a153-482e-9fa6-6706bd44b88d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_fare" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14.4542" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 298 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4vcCshcsv6w" + }, + "source": [ + "Substituição dos NaN's da variável 'age' e 'fare' pela respetiva mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tnOOsaqLsg03", + "outputId": "81837607-f6b7-4bc2-e295-443679d3deb2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age'].fillna(mediana_age, inplace = True)\n", + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 299 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VqAnNxnO0Ghn" + }, + "source": [ + "Dado que fare não possui NaN's, então nada a fazer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Hi2zG_ms6n-" + }, + "source": [ + "#### Usando Imputer\n", + "* Método para tratamento de Missing Values." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvCnGfCOri9Y", + "outputId": "6d8b7f52-ca60-4bbd-bc50-9e55f3b9bd17", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'median')\n", + "imputer_mv.fit(df_titanic_copia[['age', 'fare']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 300 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SokJ8HM61FcK", + "outputId": "65052934-48c4-4c6d-b206-b14d8fa10dc3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "imputer_mv" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 301 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X-qx8QsQthyU", + "outputId": "469c2591-1ea2-4dfd-8395-df11821f5951", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "# transform()\n", + "df_titanic_mediana = pd.DataFrame(imputer_mv.transform(df_titanic[['age', 'fare']]), columns = ['age2', 'fare2'])\n", + "df_titanic_mediana.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age2fare2
022.07.2500
138.071.2833
226.07.9250
335.053.1000
435.08.0500
\n", + "
" + ], + "text/plain": [ + " age2 fare2\n", + "0 22.0 7.2500\n", + "1 38.0 71.2833\n", + "2 26.0 7.9250\n", + "3 35.0 53.1000\n", + "4 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 302 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KS-xYf5BuwEt", + "outputId": "c7e01602-c917-48b7-a7f1-33ce365f21ac", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_mediana.median()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "age2 28.0000\n", + "fare2 14.4542\n", + "dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 303 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lggbmAD2vN42", + "outputId": "55134b01-f993-4f01-b053-7600c45eec21", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_copia.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 304 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8fQ6a7RSvUOp", + "outputId": "75770554-a802-4012-a068-76b2e1ba1578", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic['age'] = df_titanic_mediana['age2']\n", + "\n", + "# Não há NaN's na variável fare. Portanto, nenhuma alteração\n", + "#df_titanic['fare'] = df_titanic_mediana['fare']\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 305 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HSncMlT51oM5", + "outputId": "85057833-9c05-4805-d2d0-ad6a3af0d140", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 306 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c48gJg0q4zgj" + }, + "source": [ + "Exclui as colunas que não são mais necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7OzK7DnDg2WY", + "outputId": "462a1c3e-d2b3-4d5d-b745-945706522481", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 307 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLpWbzz84ykm", + "outputId": "cdb706ed-5395-47d0-8f52-7887edcde8ee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 308 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NZei3VxSxR6g" + }, + "source": [ + "Alternativamente, poderíamos concatenar os dois dataframes usando pd.concat()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ek2qBdOFw2p5", + "outputId": "7777706c-55e4-4bfd-822f-cf3843922f3e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic = df_titanic_copia.copy()\n", + "\n", + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin', 'fare', 'age'], axis = 1, inplace = True)\n", + "df_titanic = pd.concat([df_titanic, df_titanic_mediana], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchembarkedage2fare2
003male10S22.07.2500
111female10C38.071.2833
213female00S26.07.9250
311female10S35.053.1000
403male00S35.08.0500
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch embarked age2 fare2\n", + "0 0 3 male 1 0 S 22.0 7.2500\n", + "1 1 1 female 1 0 C 38.0 71.2833\n", + "2 1 3 female 0 0 S 26.0 7.9250\n", + "3 1 1 female 1 0 S 35.0 53.1000\n", + "4 0 3 male 0 0 S 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6omsobg77tRv" + }, + "source": [ + "#### Tratamento dos NaN's da variável 'embarked'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YjeivMbz85gg" + }, + "source": [ + "A seguir, listamos as linhas em que embarked = NaN:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mc03_AnI8QgV", + "outputId": "ebe1ecc6-2c40-429d-d608-3b72ef10acd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
6111female38.00080.0NaN
82911female62.00080.0NaN
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "61 1 1 female 38.0 0 0 80.0 NaN\n", + "829 1 1 female 62.0 0 0 80.0 NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 309 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsbeFBFp7zRM", + "outputId": "58859c46-d711-4558-aadf-70480e67c98b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'most_frequent')\n", + "imputer_mv.fit(df_titanic[['embarked']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='most_frequent', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 310 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f2kDtHVN761L" + }, + "source": [ + "# transform()\n", + "df_embarked_freq = pd.DataFrame(imputer_mv.transform(df_titanic[['embarked']]), columns = ['embarked2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JmoLrzD8NwW", + "outputId": "d8ac60c0-a440-42b1-d7d5-c00168c3956f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic = pd.concat([df_titanic, df_embarked_freq], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
003male22.0107.2500SS
111female38.01071.2833CC
213female26.0007.9250SS
311female35.01053.1000SS
403male35.0008.0500SS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S S\n", + "1 1 1 female 38.0 1 0 71.2833 C C\n", + "2 1 3 female 26.0 0 0 7.9250 S S\n", + "3 1 1 female 35.0 1 0 53.1000 S S\n", + "4 0 3 male 35.0 0 0 8.0500 S S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 312 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FRxX9c4--TCg" + }, + "source": [ + "COMPARE o ANTES e o DEPOIS: Veja a seguir que os valores de [embarked] = NaN foram substituidos por..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oQFDqatz9bMv", + "outputId": "45d6ab98-b832-4844-8d66-6d47cbcee08e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
6111female38.00080.0NaNS
82911female62.00080.0NaNS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "61 1 1 female 38.0 0 0 80.0 NaN S\n", + "829 1 1 female 62.0 0 0 80.0 NaN S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 313 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jgCuXei2ZTQl" + }, + "source": [ + "Como podemos ver, os NaN's da variável embarked foram todos substituídos pelo valor 'S'. Tudo bem para vocês esta substituição?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r3r8ObKn-nBt" + }, + "source": [ + "df_titanic.drop(columns = ['embarked'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OacQvrYeAPBR" + }, + "source": [ + "Verificação final dos NaN's:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OHBv7CrjARol", + "outputId": "df1e556b-21dd-42a2-df08-4c0046f1f3b1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 0\n", + "pclass 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "fare 0\n", + "embarked2 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 315 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ITFMsiBSyAHY" + }, + "source": [ + "### O dataframe sob análise possui (pelo menos) 50 observações para cada preditora?\n", + "* Variáveis preditoras: pclass, sex, age, sibsp, parch, fare, embarked2 --> 7 variáveis preditoras.\n", + "* Portanto, nosso dataframe precisa de, no mínimo 7 x 50 = 350 linhas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4lgVp2N8yE1C", + "outputId": "2dbea822-609b-4576-c3e2-f89b3527db1c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.info()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 891 entries, 0 to 890\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 survived 891 non-null int64 \n", + " 1 pclass 891 non-null int64 \n", + " 2 sex 891 non-null object \n", + " 3 age 891 non-null float64\n", + " 4 sibsp 891 non-null int64 \n", + " 5 parch 891 non-null int64 \n", + " 6 fare 891 non-null float64\n", + " 7 embarked2 891 non-null object \n", + "dtypes: float64(2), int64(4), object(2)\n", + "memory usage: 55.8+ KB\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rFwtnAcw23gQ", + "outputId": "2b9b006b-3dee-493a-e9a6-adcf90923373", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "891/7" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "127.28571428571429" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 317 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wLqz2V7SytPU" + }, + "source": [ + "Pressuposto atendido?\n", + "Se sim, podemos prosseguir com as análises..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wm0VycfhovW8" + }, + "source": [ + "#### Avaliação do pressuposto de variáveis preditoras independentes\n", + "* Coeficiente de Spearman (desenvolvido por Charles Spearman). Também conhecido como Coeficiente de Correlação de Spearman e denotado pela letra greaga $\\rho(p)$.\n", + "* É um método estatístico para avaliar/medir a correlação entre 2 variáveis ordinais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "29knlUdcztb1", + "outputId": "adb2e1a5-2436-4327-8eff-4a65b66d4e0b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchfareage2ambarked2
003male107.250022.0S
111female1071.283338.0C
213female007.925026.0S
311female1053.100035.0S
403male008.050035.0S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch fare age2 ambarked2\n", + "0 0 3 male 1 0 7.2500 22.0 S\n", + "1 1 1 female 1 0 71.2833 38.0 C\n", + "2 1 3 female 0 0 7.9250 26.0 S\n", + "3 1 1 female 1 0 53.1000 35.0 S\n", + "4 0 3 male 0 0 8.0500 35.0 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 102 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J5EEcU7l0E2B" + }, + "source": [ + "A seguir, a hipótese de independência que queremos testar:\n", + "\n", + "$H_{0}$: variáveis são independentes --> Se o p-value < 5% --> Há evidências para rejeitar $H_{0}$." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tj8A_Kp0qxp_" + }, + "source": [ + "from scipy.stats import spearmanr" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kFxVGHPUpKLi" + }, + "source": [ + "coef, p = spearmanr(df_titanic['pclass'], df_titanic['age'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fvzvyvK7qzib", + "outputId": "d1e8d723-5048-4360-bad4-9ce0b8172bbf", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print('Coeficiente de Correlação de Spearman: %.3f' % coef)\n", + "\n", + "# Interpretação da significância:\n", + "alpha = 0.05\n", + "if p > alpha:\n", + "\tprint('Amostras NÃO correlacionadas (falha em rejeitar H0) p = %.3f' %p)\n", + "else:\n", + "\tprint('Amostras correlacionadas (Rejeita H0) p = %.3f' %p)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Coeficiente de Correlação de Spearman: -0.317\n", + "Amostras correlacionadas (Rejeita H0) p = 0.000\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yespibmf1WVh" + }, + "source": [ + "## Data Transformation\n", + "* MinMaxScaler e RobustScaler\n", + "* Binning (categorização de variáveis/preditoras numéricas): fare e age\n", + "* Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UwLpj8PXKFuL" + }, + "source": [ + "### Tratamento dos Outliers\n", + "* variáveis: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sTTgUx9oiWdJ", + "outputId": "fd14b9f5-7e25-4416-bfc7-e318e79d3249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 321 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-7v8WaB4aEKv" + }, + "source": [ + "from scipy import stats \n", + "\n", + "def trata_outliers(df, coluna):\n", + " sns.boxplot(x = coluna, data = df)\n", + "\n", + " # Cálculo de Q1, Q3 e IQR:\n", + " Q1 = np.percentile(df[coluna], 25)\n", + " Q3 = np.percentile(df[coluna], 75)\n", + " IQR = Q3 - Q1\n", + " print(f\"IQR: {IQR}\")\n", + "\n", + " # Jeito mais fácil (menos trabalhoso).\n", + " #IQR2 = stats.iqr(df[coluna]) \n", + " #IQR2 \n", + "\n", + " # Cálculo dos limites inferiores e superiores para detecção de outliers:\n", + " limite_inferior_outliers = Q1 - 1.5*IQR\n", + " limite_superior_outliers = Q3 + 1.5*IQR\n", + " print(f\"Limite inferior para outlier: {limite_inferior_outliers}; Limite superior para outliers: {limite_superior_outliers}\")\n", + "\n", + " # Cálculo da mediana\n", + " mediana = df[coluna].median()\n", + " print(f\"Mediana: {mediana}\")\n", + "\n", + " # Substituição dos outliers:\n", + " df[coluna+'_o'] = df[coluna]\n", + "\n", + " df.loc[df[coluna] > limite_superior_outliers, coluna+'_o'] = np.nan\n", + " df[coluna+'_o'].fillna(mediana, inplace = True) # 'o' significa tratamento outlier --> indicação para mostrar que a coluna passou pelo tratamento dos outliers.\n", + "\n", + " return df, limite_superior_outliers" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pwAExKTWaOSf", + "outputId": "089cba96-b805-4eef-d504-f8c81551c938", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'age')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 13.0\n", + "Limite inferior para outlier: 2.5; Limite superior para outliers: 54.5\n", + "Mediana: 28.0\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rB3Wh7jldcl-", + "outputId": "34e01f99-642a-45aa-ebd3-bda160d7be2e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 665 + } + }, + "source": [ + "df_titanic.head(20)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
503male28.0008.4583Q28.0
601male54.00051.8625S54.0
703male2.03121.0750S2.0
813female27.00211.1333S27.0
912female14.01030.0708C14.0
1013female4.01116.7000S4.0
1111female58.00026.5500S28.0
1203male20.0008.0500S20.0
1303male39.01531.2750S39.0
1403female14.0007.8542S14.0
1512female55.00016.0000S28.0
1603male2.04129.1250Q2.0
1712male28.00013.0000S28.0
1803female31.01018.0000S31.0
1913female28.0007.2250C28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0\n", + "5 0 3 male 28.0 0 0 8.4583 Q 28.0\n", + "6 0 1 male 54.0 0 0 51.8625 S 54.0\n", + "7 0 3 male 2.0 3 1 21.0750 S 2.0\n", + "8 1 3 female 27.0 0 2 11.1333 S 27.0\n", + "9 1 2 female 14.0 1 0 30.0708 C 14.0\n", + "10 1 3 female 4.0 1 1 16.7000 S 4.0\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "12 0 3 male 20.0 0 0 8.0500 S 20.0\n", + "13 0 3 male 39.0 1 5 31.2750 S 39.0\n", + "14 0 3 female 14.0 0 0 7.8542 S 14.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "16 0 3 male 2.0 4 1 29.1250 Q 2.0\n", + "17 1 2 male 28.0 0 0 13.0000 S 28.0\n", + "18 0 3 female 31.0 1 0 18.0000 S 31.0\n", + "19 1 3 female 28.0 0 0 7.2250 C 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 324 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x6YRvSf5SRR4" + }, + "source": [ + "### Quem são os outliers de 'age'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2y9BeUnoSU4W", + "outputId": "85968b30-7903-465b-eddf-27d4604acb58", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "age_outlier = df_titanic[df_titanic['age'] > limite_superior_outliers]\n", + "age_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
1111female58.00026.5500S28.0
1512female55.00016.0000S28.0
3302male66.00010.5000S28.0
5401male65.00161.9792C28.0
9403male59.0007.2500S28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "33 0 2 male 66.0 0 0 10.5000 S 28.0\n", + "54 0 1 male 65.0 0 1 61.9792 C 28.0\n", + "94 0 3 male 59.0 0 0 7.2500 S 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 327 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0dHnei1TBFc" + }, + "source": [ + "### Tratamento dos outliers da variável 'fare'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i8YM25uKm8g1", + "outputId": "00e04c37-82d8-4aca-c250-36a4a045df2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 328 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4Gnr9AEfTSj6", + "outputId": "40a23226-68bd-4288-dbf2-5fabfd4fd32b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'fare')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 23.0896\n", + "Limite inferior para outlier: -26.724; Limite superior para outliers: 65.6344\n", + "Mediana: 14.4542\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uh7f7nNATSkT" + }, + "source": [ + "### Quem são os outliers de 'fare'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdzaUaD0nQnv", + "outputId": "c05a1d46-c91a-4542-92a8-bfb121b44174", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "limite_superior_outliers" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "65.6344" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 330 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P3SAGnYnnQn4", + "outputId": "424347d6-d243-48df-8c3d-4c2a014c0cd9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "fare_outlier = df_titanic[df_titanic['fare'] > limite_superior_outliers]\n", + "fare_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_ofare_o
111female38.01071.2833C38.014.4542
2701male19.032263.0000S19.014.4542
3111female28.010146.5208C28.014.4542
3401male28.01082.1708C28.014.4542
5211female49.01076.7292C49.014.4542
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o fare_o\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 14.4542\n", + "27 0 1 male 19.0 ... 263.0000 S 19.0 14.4542\n", + "31 1 1 female 28.0 ... 146.5208 C 28.0 14.4542\n", + "34 0 1 male 28.0 ... 82.1708 C 28.0 14.4542\n", + "52 1 1 female 49.0 ... 76.7292 C 49.0 14.4542\n", + "\n", + "[5 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 331 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Jh83WTrZDeM_" + }, + "source": [ + "### Binning variáveis numéricas: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JVNVCd7aDjkz", + "outputId": "21f91b71-cfe5-445b-cf2c-8f4bf0de9825", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "#df_titanic_copia = df_titanic.copy()\n", + "df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 332 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pUspmjPWFP06" + }, + "source": [ + "#### Usando cut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NBVoCBe_2Zmp" + }, + "source": [ + "#df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90])\n", + "df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], labels = [10, 20, 30, 40, 50, 60, 70, 80, 90])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i1jombNDrEO", + "outputId": "7c96358b-3023-4706-813a-3e3e594cc45e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 264 + } + }, + "source": [ + "df_titanic.head(7)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_oage_bins
003male22.0107.2500S22.030
111female38.01071.2833C38.040
213female26.0007.9250S26.030
311female35.01053.1000S35.040
403male35.0008.0500S35.040
503male28.0008.4583Q28.030
601male54.00051.8625S54.060
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o age_bins\n", + "0 0 3 male 22.0 ... 7.2500 S 22.0 30\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 40\n", + "2 1 3 female 26.0 ... 7.9250 S 26.0 30\n", + "3 1 1 female 35.0 ... 53.1000 S 35.0 40\n", + "4 0 3 male 35.0 ... 8.0500 S 35.0 40\n", + "5 0 3 male 28.0 ... 8.4583 Q 28.0 30\n", + "6 0 1 male 54.0 ... 51.8625 S 54.0 60\n", + "\n", + "[7 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 340 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "davIt0UT9tTr" + }, + "source": [ + "#### **Desafio**: Qual seria o corte ótimo para 'age' usando DecisionTree?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5aAYl2ZDu1f", + "outputId": "0f1d7a99-6cb0-4484-b12b-7907b70feb8a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_cut1'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20, 30] 449\n", + "(30, 40] 155\n", + "(10, 20] 115\n", + "(40, 50] 86\n", + "(0, 10] 64\n", + "(50, 60] 22\n", + "(80, 90] 0\n", + "(70, 80] 0\n", + "(60, 70] 0\n", + "Name: age_bins_cut1, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 276 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VAUshOiLFT9-" + }, + "source": [ + "#### Usando qcut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RKnb-bI7FL3F", + "outputId": "59742803-dcee-4525-8fd1-2cecff379cab", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic['age_bins_qcut'] = pd.qcut(x = df_titanic['age'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 277 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "boSGroSYN7cP", + "outputId": "9304540f-1a20-41cb-c4a4-70633be1a071", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.dtypes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived int64\n", + "pclass int64\n", + "sex object\n", + "age float64\n", + "sibsp int64\n", + "parch int64\n", + "fare float64\n", + "embarked2 object\n", + "age_o float64\n", + "age_bins category\n", + "dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 344 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P8s3LzfpNdUz", + "outputId": "b0e4b638-32de-4295-984e-ba207e195661", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "l_colunas_numericas = list(df_titanic.select_dtypes('int').columns)\n", + "l_colunas_numericas\n", + "\n", + "for coluna in l_colunas_numericas:\n", + " trata_outliers(df, coluna)\n", + " trata_missing_values(df, coluna)\n", + " aplica_MMS(df, coluna)\n", + " aplica_RS(df, coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['survived', 'pclass', 'sibsp', 'parch']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 346 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ov2_l39mn3FH", + "outputId": "122869f8-018f-4176-b2df-c249efa222b7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_qcut'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20.0, 28.0] 360\n", + "(0.419, 20.0] 179\n", + "(38.0, 80.0] 177\n", + "(28.0, 38.0] 175\n", + "Name: age_bins_qcut, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 261 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J60XwHUOGwbr" + }, + "source": [ + "### MinMaxScaler() e RobustScaler()\n", + "* age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GRY84U4HHxoQ" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler, RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IQC7Bo-DH71s" + }, + "source": [ + "mms = MinMaxScaler()\n", + "rs = RobustScaler()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8O2oM9XdIYF5", + "outputId": "9812b76b-dffc-406b-fcd9-0a7c1b01a61b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B-qglHy6NZlg", + "outputId": "96a154a8-678e-48eb-93b2-ce93b7e0258f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 265 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dp9jYZ1OoA9i" + }, + "source": [ + "A seguir, deletar as variáveis que desnecessárias..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zSSViPY5XokW" + }, + "source": [ + "df_titanic.drop(columns = ['age', 'fare'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MNq5a0eUIBGV", + "outputId": "d692f608-f511-46e6-d101-bd9443647b94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 282 + } + }, + "source": [ + "# fit\n", + "df_titanic_mms = pd.DataFrame(mms.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_mms', 'fare_mms'])\n", + "df_titanic_rs = pd.DataFrame(rs.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_rs', 'fare_rs'])\n", + "\n", + "df_titanic['age_mms'] = df_titanic_mms['age_mms']\n", + "df_titanic['age_rs'] = df_titanic_rs['age_rs']\n", + "\n", + "df_titanic['fare_mms'] = df_titanic_mms['fare_mms']\n", + "df_titanic['fare_rs'] = df_titanic_rs['fare_rs']\n", + "\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rsage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.111538-0.443619(0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C38.014.4542(30, 40]40(28.0, 38.0]0.7013810.9090910.2223720.000000(0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.121923-0.402054(0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S35.053.1000(30, 40]40(28.0, 38.0]0.6453900.6363640.8169232.379726(0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S35.08.0500(30, 40]40(28.0, 38.0]0.6453900.6363640.123846-0.394357(0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 19 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 268 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UzrdPNO3rIg5", + "outputId": "aaa31937-081d-4af8-f3ec-07002886d2a6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 555 + } + }, + "source": [ + "# Categorizando as variáveis transformadas\n", + "df_titanic['age_bins_mms'] = pd.qcut(x = df_titanic['age_mms'], q = 5, duplicates = 'drop', labels = [1, 2, 3, 4])\n", + "df_titanic['age_bins_rs'] = pd.qcut(x = df_titanic['age_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "\n", + "df_titanic['fare_bins_mms'] = pd.qcut(x = df_titanic['fare_mms'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic['fare_bins_rs'] = pd.qcut(x = df_titanic['fare_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2894\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2895\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Categorizando as variáveis transformadas\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_rs'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_rs'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2901\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2902\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2903\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2904\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2895\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2897\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2898\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2899\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtolerance\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7smfXya5pmNq", + "outputId": "a942223f-e9b6-4758-c453-73c5c55f91bd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.drop(columns = ['age_o', 'fare_o', 'age_bins_cut2', 'age_mms', 'age_rs', 'fare_mms', 'fare_rs'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_bins_cut1age_bins_qcutage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C(30, 40](28.0, 38.0](0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 269 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SFPNLDMcU339" + }, + "source": [ + "### Variáveis Dummy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L_Fx1iy7snjF", + "outputId": "24c70d23-5a35-41aa-8a30-04fcc146b7c6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 279 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X6aHaJodX0Hi", + "outputId": "f7a26db1-81d3-47f5-dcd3-bbde2b2b6440", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 402 + } + }, + "source": [ + "dummy = pd.get_dummies(df_titanic[['sex', 'ambarked2']])\n", + "dummy" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
001001
110100
210001
310001
401001
..................
88601001
88710001
88810001
88901100
89001010
\n", + "

891 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " sex_female sex_male ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 1 0 0 1\n", + "1 1 0 1 0 0\n", + "2 1 0 0 0 1\n", + "3 1 0 0 0 1\n", + "4 0 1 0 0 1\n", + ".. ... ... ... ... ...\n", + "886 0 1 0 0 1\n", + "887 1 0 0 0 1\n", + "888 1 0 0 0 1\n", + "889 0 1 1 0 0\n", + "890 0 1 0 1 0\n", + "\n", + "[891 rows x 5 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 282 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZhLW0lEbs28E", + "outputId": "c772c290-4394-409a-ded7-1eb57b7ac0db", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 215 + } + }, + "source": [ + "df_titanic2 = pd.concat([df_titanic, dummy], axis = 1)\n", + "df_titanic2.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutsex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
003male22.0107.2500S22.07.2500(20, 30]30201001
111female38.01071.2833C38.014.4542(30, 40]40310100
213female26.0007.9250S26.07.9250(20, 30]30210001
311female35.01053.1000S35.053.1000(30, 40]40310001
403male35.0008.0500S35.08.0500(30, 40]40301001
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 3 male ... 0 0 1\n", + "1 1 1 female ... 1 0 0\n", + "2 1 3 female ... 0 0 1\n", + "3 1 1 female ... 0 0 1\n", + "4 0 3 male ... 0 0 1\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 283 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_bOYD4gWwGt", + "outputId": "b33c5076-6d0b-4c8f-8e5b-d87cb3e4544d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts() # Quem será a referência?" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 64 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xFKdsFDihApP" + }, + "source": [ + "df_titanic['pclass'] = df_titanic['pclass'].astype('category')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D_mWCqM1ZOgU" + }, + "source": [ + "### Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UPnCuCsLZSjQ", + "outputId": "95b92d55-a895-4c2e-9655-07a3bd753f6d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mX_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_teste\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_test_split\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'train_test_split' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rk-Zuh5RXJbp", + "outputId": "47c3c005-795d-406d-984a-b0094cd5718c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age3fare3age_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rs
00.03.0male1.00.0S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.014151-0.323505
11.01.0female1.00.0C38.071.2833(30, 40]40(36.0, 54.0]0.7013810.9090910.1391362.696934
21.03.0female0.00.0S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.015469-0.291665
31.01.0female1.00.0S35.053.1000(30, 40]40(28.0, 36.0]0.6453900.6363640.1036441.839231
40.03.0male0.00.0S35.08.0500(30, 40]40(28.0, 36.0]0.6453900.6363640.015713-0.285769
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp ... age_mms age_rs fare_mms fare_rs\n", + "0 0.0 3.0 male 1.0 ... 0.402762 -0.545455 0.014151 -0.323505\n", + "1 1.0 1.0 female 1.0 ... 0.701381 0.909091 0.139136 2.696934\n", + "2 1.0 3.0 female 0.0 ... 0.477417 -0.181818 0.015469 -0.291665\n", + "3 1.0 1.0 female 1.0 ... 0.645390 0.636364 0.103644 1.839231\n", + "4 0.0 3.0 male 0.0 ... 0.645390 0.636364 0.015713 -0.285769\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 69 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XtdQc49LXTfk", + "outputId": "696c23be-e9d0-4ba9-b4f5-0dcba0ffe8ec", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 74 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbvB30S5hRxH", + "outputId": "e872fe50-fcad-4b33-9456-182b1ca7e62c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "modelo = smf.glm(formula = 'survived ~ age3 + pclass + sex', data = df_titanic, family = sm.families.Binomial()).fit()\n", + "print(modelo.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " Generalized Linear Model Regression Results \n", + "==============================================================================\n", + "Dep. Variable: survived No. Observations: 849\n", + "Model: GLM Df Residuals: 844\n", + "Model Family: Binomial Df Model: 4\n", + "Link Function: logit Scale: 1.0000\n", + "Method: IRLS Log-Likelihood: -386.42\n", + "Date: Thu, 29 Oct 2020 Deviance: 772.85\n", + "Time: 17:17:09 Pearson chi2: 890.\n", + "No. Iterations: 5 \n", + "Covariance Type: nonrobust \n", + "=================================================================================\n", + " coef std err z P>|z| [0.025 0.975]\n", + "---------------------------------------------------------------------------------\n", + "Intercept 3.5515 0.382 9.297 0.000 2.803 4.300\n", + "pclass[T.2.0] -1.1389 0.264 -4.315 0.000 -1.656 -0.622\n", + "pclass[T.3.0] -2.3581 0.245 -9.613 0.000 -2.839 -1.877\n", + "sex[T.male] -2.5618 0.189 -13.522 0.000 -2.933 -2.191\n", + "age3 -0.0344 0.009 -4.035 0.000 -0.051 -0.018\n", + "=================================================================================\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p7_gfQXciFs1" + }, + "source": [ + "Qual a significância dos coeficientes (p-value abaixo de 0.05 adotando confiança de 95%)?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xtrh_bYNikTk" + }, + "source": [ + "### Interpretação dos coeficientes:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzlGDyeLgL11" + }, + "source": [ + "* Pessoas que viajavam na segunda classe possuem menos chances de sobrevivência do que quem viajava na primeira.\n", + "* Quem viajava na terceira classe possui menos chances ainda.\n", + "* Homens possuem menos chances de sobrevivência do que mulheres. Quanto mais velho, menores as chances de sobrevivência." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CJNgEYY9ioVM" + }, + "source": [ + "### Coeficientes mais interpretáveis - Chances relativas de Sobrevivência" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "q0vLh1v3irCz" + }, + "source": [ + "print(np.exp(modelo.params[1:]))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a2fJIOOzi3VF" + }, + "source": [ + "* Pessoas que viajavam na segunda classe tinham 0.27 das chances de sobrevivência que as pessoas da primeira classe tinham. \n", + "* Pessoas da terceira classe tinham 0.076 das chances que as pessoas da primeira classe tinham. \n", + "* Homens tinham 0.08 das chances das mulheres." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dYRkdqNujHFA" + }, + "source": [ + "### Comparando com a regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mKW-aODfjLbm" + }, + "source": [ + "(np.exp(modelo.params[1:]) - 1) * 100" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ODOqZpAgjQ2q" + }, + "source": [ + "* Pessoas da segunda classe tem 73% menos chances de sobrevivência do que pessoas da primeira classe.\n", + "* Pessoas da terceira classe tem 92% menos chances de sobrevivência que pessoas da primeira classe.\n", + "* Homens tem 92% menos chances de sobrevivência do que mulheres.\n", + "* Para cada ano a mais de idade, as chances diminuem 3.63%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fxnutoD7jp94" + }, + "source": [ + "### Qualidade do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-oW8Kg5Ij3Av", + "outputId": "d56cd7ce-e5c0-493d-ccfe-27cd5a6899c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 354 + } + }, + "source": [ + "modelo2 = LogisticRegression(penalty='none', solver='newton-cg')\n", + "df_titanic2 = df_titanic[['Survived', 'Pclass', 'Sex', 'Age']].dropna()\n", + "y = df_titanic2['Survived']\n", + "X = pd.get_dummies(df_titanic2[['Pclass', 'Sex', 'Age']], drop_first=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmodelo2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mLogisticRegression\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpenalty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'none'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'newton-cg'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdropna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mX\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_dummies\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdrop_first\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2906\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_iterator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2907\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2908\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_listlike_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2909\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2910\u001b[0m \u001b[0;31m# take() does not accept boolean indexers\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_get_listlike_indexer\u001b[0;34m(self, key, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1252\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew_indexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reindex_non_unique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1253\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1254\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_read_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mraise_missing\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1255\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_validate_read_indexer\u001b[0;34m(self, key, indexer, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1296\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmissing\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1297\u001b[0m \u001b[0maxis_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_axis_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1298\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"None of [{key}] are in the [{axis_name}]\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1299\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1300\u001b[0m \u001b[0;31m# We (temporarily) allow for some missing keys with .loc, except in\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: \"None of [Index(['Survived', 'Pclass', 'Sex', 'Age'], dtype='object')] are in the [columns]\"" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YK9nIiz_kQQl" + }, + "source": [ + "modelo2.fit(X, y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FPhHe4SmkZoE" + }, + "source": [ + "y_pred = modelo2.predict_proba(X)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dPrXU0GSknGJ" + }, + "source": [ + "confusion_matrix(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_-Wweiq7kruH" + }, + "source": [ + "acuracia = accuracy_score(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bqcT8XYJkuwH" + }, + "source": [ + "print(classification_report(y, model.predict(X)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4fSN-vLOjseh" + }, + "source": [ + "confusion_matrix(y, modelo.predict(X)) # usando a função do sklearn" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A0408gbPkywR" + }, + "source": [ + "def plot_roc_curve(y_true, y_score, figsize=(10,6)):\n", + " fpr, tpr, _ = roc_curve(y_true, y_score)\n", + " plt.figure(figsize=figsize)\n", + " auc_value = roc_auc_score(y_true, y_score)\n", + " plt.plot(fpr, tpr, color='orange', label='ROC curve (area = %0.2f)' % auc_value)\n", + " plt.plot([0, 1], [0, 1], color='darkblue', linestyle='--')\n", + " plt.xlabel('False Positive Rate')\n", + " plt.ylabel('True Positive Rate')\n", + " plt.title('Receiver Operating Characteristic (ROC) Curve')\n", + " plt.legend()\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5T4P90hQk1ug" + }, + "source": [ + "plot_roc_curve(y, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CANyMIgIjgSb" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pWJgVcQRlESq" + }, + "source": [ + "eu = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':1, 'Sex_male':1}, index=[0])\n", + "minha_prob = model.predict_proba(eu)\n", + "print('Eu teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(minha_prob[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kgpdgkgrlJ-w" + }, + "source": [ + "Eu teria 7.52% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "91GShU9ClMiY" + }, + "source": [ + "coleguinha = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':0, 'Sex_male':1}, index=[0])\n", + "prob_do_coleguinha = model.predict_proba(coleguinha)\n", + "print('Meu coleguinha teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(prob_do_coleguinha[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c2EHn8volOil" + }, + "source": [ + "Meu coleguinha teria 51.77% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C2PvJoZQlH6u" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwuMfMD1gFyd" + }, + "source": [ + "# Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kFY0TQVgOlvT" + }, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efF3st3sHxPG" + }, + "source": [ + "# Carrega as bibliotecas\n", + "import numpy as np\n", + "np.set_printoptions(formatter = {'float': lambda x: \"{0:0.2f}\".format(x)})\n", + "\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "import statsmodels.api as sm\n", + "\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bk9F6JO0IELv" + }, + "source": [ + "# Carregar/ler o banco de dados - Dataframe Diabetes\n", + "from sklearn import datasets\n", + "#Diabetes = datasets.load_diabetes()\n", + "\n", + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/diabetes.csv'\n", + "diabetes = pd.read_csv(url)\n", + "diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tjRmpaPIDknb" + }, + "source": [ + "# Definir as matrizes X e y\n", + "X_diabetes = diabetes.copy()\n", + "X_diabetes.drop(columns = ['Outcome'], axis = 1, inplace = True)\n", + "y_diabetes = diabetes['Outcome']\n", + "\n", + "X_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jLrx69TH-Mad" + }, + "source": [ + "X_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mdFBioP6-Ply" + }, + "source": [ + "y_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fhLySN65IaDF" + }, + "source": [ + "# Definir as matrizes de treinamento e validação\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_diabetes, y_diabetes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J5R8HlnuIGpL" + }, + "source": [ + "# Usando statmodels:\n", + "x = sm.add_constant(X_treinamento)\n", + "lr_sm = sm.Logit(y_treinamento, X_treinamento) # Atenção: aqui é o contrário: [y, x]\n", + "\n", + "# Treinar o modelo\n", + "lr.fit(X_treinamento, y_treinamento)\n", + "resultado_sm = lr_sm.fit()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GlbCaPp1ETNa" + }, + "source": [ + "resultado_sm.summary()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-FJaSnJLKICU" + }, + "source": [ + "# EQM - Erro Quadrático Médio\n", + "np.mean((resultado_sm.predict(X_teste) - y_teste) ** 2) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bVEUSTUPzOj" + }, + "source": [ + "### Calcular y_pred - os valores preditos de y" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OjGrNhTNLcr-" + }, + "source": [ + "y_pred = resultado_sm.predict(X_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfS5RCx_VnGT" + }, + "source": [ + "compara = list(zip(np.array(diabetes['Outcome']), resultado_sm.predict()))\n", + "compara[0:30]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUxasncIFaw4" + }, + "source": [ + "resultado_sm.pred_table()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_liLYinwFgch" + }, + "source": [ + "confusion_matrix = pd.DataFrame(resultado_sm.pred_table())\n", + "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n", + "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n", + "confusion_matrix" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ceH3MODWFm7S" + }, + "source": [ + "cm = np.array(confusion_matrix)\n", + "training_accuracy = (cm[0,0] + cm[1,1])/ cm.sum()\n", + "training_accuracy" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH_iEuzhO109" + }, + "source": [ + "# Exercício 1 - Mall_Customers.csv\n", + "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n", + "\n", + "* Experimente:\n", + " * Lasso(alpha = 0.01, max_iter = 10e5);\n", + " * Lasso(alpha = 0.0001, max_iter = 10e5);\n", + " * Ridge(alpha = 0.01);\n", + " * Ridge(alpha = 100);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZfRDEaaRYxFQ" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt \n", + "plt.rc(\"font\", size=14)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "import seaborn as sns\n", + "sns.set(style=\"white\")\n", + "sns.set(style=\"whitegrid\", color_codes=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nulrLzUqYxFY" + }, + "source": [ + "## Dados\n", + "\n", + "The data is related with direct marketing campaigns (phone calls) of a Portuguese banking institution. The classification goal is to predict if the client will subscribe (1/0) a term deposit (variable y)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LdrQCwxYxFY" + }, + "source": [ + "This dataset provides the customer information. It includes 41188 records and 21 fields." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qoT6zkoFYxFZ", + "outputId": "b04874af-bf4d-409f-cd1c-ad8c473004e6", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_bank = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/bank-full.csv', header = 0)\n", + "df_bank = df_bank.dropna()\n", + "print(df_bank.shape)\n", + "print(list(df_bank.columns))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(45211, 1)\n", + "['age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZD23hMCeYxFc", + "outputId": "f347c846-5f92-4e4f-b468-2bfbc608777c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_bank.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"
058;\"management\";\"married\";\"tertiary\";\"no\";2143...
144;\"technician\";\"single\";\"secondary\";\"no\";29;\"...
233;\"entrepreneur\";\"married\";\"secondary\";\"no\";2...
347;\"blue-collar\";\"married\";\"unknown\";\"no\";1506...
433;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n...
\n", + "
" + ], + "text/plain": [ + " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"\n", + "0 58;\"management\";\"married\";\"tertiary\";\"no\";2143... \n", + "1 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... \n", + "2 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... \n", + "3 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... \n", + "4 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... " + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 285 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CtGbim_EYxFh" + }, + "source": [ + "#### Input variables" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0pJ7ai5ZYxFh" + }, + "source": [ + "1 - age (numeric)\n", + "\n", + "2 - job : type of job (categorical: 'admin.','blue-collar','entrepreneur','housemaid','management','retired','self-employed','services','student','technician','unemployed','unknown')\n", + "\n", + "3 - marital : marital status (categorical: 'divorced','married','single','unknown'; note: 'divorced' means divorced or widowed)\n", + "\n", + "4 - education (categorical: 'basic.4y','basic.6y','basic.9y','high.school','illiterate','professional.course','university.degree','unknown')\n", + "\n", + "5 - default: has credit in default? (categorical: 'no','yes','unknown')\n", + "\n", + "6 - housing: has housing loan? (categorical: 'no','yes','unknown')\n", + "\n", + "7 - loan: has personal loan? (categorical: 'no','yes','unknown')\n", + "\n", + "8 - contact: contact communication type (categorical: 'cellular','telephone')\n", + "\n", + "9 - month: last contact month of year (categorical: 'jan', 'feb', 'mar', ..., 'nov', 'dec')\n", + "\n", + "10 - day_of_week: last contact day of the week (categorical: 'mon','tue','wed','thu','fri')\n", + "\n", + "11 - duration: last contact duration, in seconds (numeric). Important note: this attribute highly affects the output target (e.g., if duration=0 then y='no'). Yet, the duration is not known before a call is performed. Also, after the end of the call y is obviously known. Thus, this input should only be included for benchmark purposes and should be discarded if the intention is to have a realistic predictive model.\n", + "\n", + "12 - campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)\n", + "\n", + "13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)\n", + "\n", + "14 - previous: number of contacts performed before this campaign and for this client (numeric)\n", + "\n", + "15 - poutcome: outcome of the previous marketing campaign (categorical: 'failure','nonexistent','success')\n", + "\n", + "16 - emp.var.rate: employment variation rate - (numeric)\n", + "\n", + "17 - cons.price.idx: consumer price index - (numeric)\n", + "\n", + "18 - cons.conf.idx: consumer confidence index - (numeric) \n", + "\n", + "19 - euribor3m: euribor 3 month rate - (numeric)\n", + "\n", + "20 - nr.employed: number of employees - (numeric)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YwsaBV_OYxFi" + }, + "source": [ + "#### Predict variable (desired target):\n", + "\n", + "y - has the client subscribed a term deposit? (binary: '1','0')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2SsNWV_SYxFj" + }, + "source": [ + "The education column of the dataset has many categories and we need to reduce the categories for a better modelling. The education column has the following categories:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6TFbgh3vYxFk" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "luv7Bdf_YxFn" + }, + "source": [ + "Let us group \"basic.4y\", \"basic.9y\" and \"basic.6y\" together and call them \"basic\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gkOlUOs2YxFn" + }, + "source": [ + "df_bank['education']=np.where(df_bank['education'] =='basic.9y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.6y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.4y', 'Basic', df_bank['education'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-X1WMv2YxFq" + }, + "source": [ + "After grouping, this is the columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r9LlgpkjYxFq" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fcnJy3KYYxFt" + }, + "source": [ + "### Data exploration" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qUrTMR8BYxFt" + }, + "source": [ + "df_bank['y'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rpzHnzJKYxFx" + }, + "source": [ + "sns.countplot(x='y',data=df_bank, palette='hls')\n", + "plt.show()\n", + "plt.savefig('count_plot')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C99nOe3mYxF0" + }, + "source": [ + "There are 36548 no's and 4640 yes's in the outcome variables." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8nGaox_kYxF1" + }, + "source": [ + "Let's get a sense of the numbers across the two classes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sQvzA60bYxF1" + }, + "source": [ + "df_bank.groupby('y').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u3xjoceKYxF3" + }, + "source": [ + "Observations:\n", + "\n", + "The average age of customers who bought the term deposit is higher than that of the customers who didn't.\n", + "The pdays (days since the customer was last contacted) is understandably lower for the customers who bought it. The lower the pdays, the better the memory of the last call and hence the better chances of a sale.\n", + "Surprisingly, campaigns (number of contacts or calls made during the current campaign) are lower for customers who bought the term deposit." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jvzGMePPYxF4" + }, + "source": [ + "We can calculate categorical means for other categorical variables such as education and marital status to get a more detailed sense of our data." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RqLVMjoxYxF5" + }, + "source": [ + "df_bank.groupby('job').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GTUeRJAtYxF7" + }, + "source": [ + "df_bank.groupby('marital').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsxdFumiYxF9" + }, + "source": [ + "df_bank.groupby('education').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3i1DCWV-YxGA" + }, + "source": [ + "Visualizations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OEArHQPbYxGB" + }, + "source": [ + "%matplotlib inline\n", + "pd.crosstab(df_bank.job,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Job Title')\n", + "plt.xlabel('Job')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('purchase_fre_job')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNwo5du_YxGD" + }, + "source": [ + "The frequency of purchase of the deposit depends a great deal on the job title. Thus, the job title can be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eM7CWfAZYxGE" + }, + "source": [ + "table=pd.crosstab(df_bank.marital,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Marital Status vs Purchase')\n", + "plt.xlabel('Marital Status')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('mariral_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWBLh7toYxGG" + }, + "source": [ + "Hard to see, but the marital status does not seem a strong predictor for the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vh_u4QphYxGH" + }, + "source": [ + "table=pd.crosstab(df_bank.education,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Education vs Purchase')\n", + "plt.xlabel('Education')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('edu_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d9AgJroYYxGK" + }, + "source": [ + "Education seems a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dHI2LT-IYxGL" + }, + "source": [ + "pd.crosstab(df_bank.day_of_week,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Day of Week')\n", + "plt.xlabel('Day of Week')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_dayofweek_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3A2jmS4MYxGR" + }, + "source": [ + "Day of week may not be a good predictor of the outcome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bzafDBHpYxGS" + }, + "source": [ + "pd.crosstab(df_bank.month,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Month')\n", + "plt.xlabel('Month')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_month_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x5CBtquEYxGW" + }, + "source": [ + "Month might be a good predictor of the outcome variable" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tgF_3SqWYxGY" + }, + "source": [ + "df_bank.age.hist()\n", + "plt.title('Histogram of Age')\n", + "plt.xlabel('Age')\n", + "plt.ylabel('Frequency')\n", + "plt.savefig('hist_age')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y0FhKYDsYxGc" + }, + "source": [ + "The most of the customers of the bank in this dataset are in the age range of 30-40." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Nd3yV7DYxGd" + }, + "source": [ + "pd.crosstab(df_bank.poutcome,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Poutcome')\n", + "plt.xlabel('Poutcome')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_pout_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oRKUAGrjYxGh" + }, + "source": [ + "Poutcome seems to be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "63RLRI9uYxGi" + }, + "source": [ + "### Create dummy variables" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V8S4WUKmYxGj" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "for var in cat_vars:\n", + " cat_list='var'+'_'+var\n", + " cat_list = pd.get_dummies(df_bank[var], prefix=var)\n", + " df_bank1=df_bank.join(cat_list)\n", + " data=df_bank1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uX3w9i9WYxGl" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "df_bank_vars=df_bank.columns.values.tolist()\n", + "to_keep=[i for i in df_bank_vars if i not in cat_vars]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cMX_82xaYxGq" + }, + "source": [ + "df_bank_final=df_bank[to_keep]\n", + "df_bank_final.columns.values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LkTjpxYoYxGr" + }, + "source": [ + "df_bank_final_vars=df_bank_final.columns.values.tolist()\n", + "y=['y']\n", + "X=[i for i in df_bank_final_vars if i not in y]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2QbKaRcsYxGt" + }, + "source": [ + "### Feature Selection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EkxjW1AQYxGu" + }, + "source": [ + "from sklearn import datasets\n", + "from sklearn.feature_selection import RFE\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "logreg = LogisticRegression()\n", + "\n", + "rfe = RFE(logreg, 18)\n", + "rfe = rfe.fit(df_bank_final[X], df_bank_final[y] )\n", + "print(rfe.support_)\n", + "print(rfe.ranking_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2P9hd4jHYxGw" + }, + "source": [ + "The Recursive Feature Elimination (RFE) has helped us select the following features: \"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PW8WZX_YxGx" + }, + "source": [ + "cols=[\"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \n", + " \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \n", + " \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"] \n", + "X=df_bank_final[cols]\n", + "y=df_bank_final['y']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ix0mN9qxYxG0" + }, + "source": [ + "### Implementing the model" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hbx2bwtiYxG0" + }, + "source": [ + "import statsmodels.api as sm\n", + "logit_model=sm.Logit(y,X)\n", + "result=logit_model.fit()\n", + "print(result.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HR1ui-UcYxG2" + }, + "source": [ + "The p-values for most of the variables are very small, therefore, most of them are significant to the model." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9GHhrsaeYxG3" + }, + "source": [ + "### Logistic Regression Model Fitting" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFQnH5MzYxG3" + }, + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn import metrics\n", + "logreg = LogisticRegression()\n", + "logreg.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YUa3QL7tYxG6" + }, + "source": [ + "#### Predicting the test set results and caculating the accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SD-y2e33YxG6" + }, + "source": [ + "y_pred = logreg.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kkPWzos7YxG-" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwC3rt_6YxHA" + }, + "source": [ + "### Cross Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Muw50oqSYxHB" + }, + "source": [ + "from sklearn import model_selection\n", + "from sklearn.model_selection import cross_val_score\n", + "kfold = model_selection.KFold(n_splits=10, random_state=7)\n", + "modelCV = LogisticRegression()\n", + "scoring = 'accuracy'\n", + "results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)\n", + "print(\"10-fold cross validation average accuracy: %.3f\" % (results.mean()))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4y8XCTqoYxHE" + }, + "source": [ + "### Confusion Matrix" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BCza9NkVYxHE" + }, + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "confusion_matrix = confusion_matrix(y_test, y_pred)\n", + "print(confusion_matrix)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9SapwS2YxHG" + }, + "source": [ + "The result is telling us that we have 10872+254 correct predictions and 1122+109 incorrect predictions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bEWvWScYxHG" + }, + "source": [ + "#### Accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NaH2nESwYxHH" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(classifier.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C6oxlhbpYxHJ" + }, + "source": [ + "#### Compute precision, recall, F-measure and support\n", + "\n", + "The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.\n", + "\n", + "The recall is the ratio tp / (tp + fn) where tp is the number of true positives and fn the number of false negatives. The recall is intuitively the ability of the classifier to find all the positive samples.\n", + "\n", + "The F-beta score can be interpreted as a weighted harmonic mean of the precision and recall, where an F-beta score reaches its best value at 1 and worst score at 0.\n", + "\n", + "The F-beta score weights recall more than precision by a factor of beta. beta == 1.0 means recall and precision are equally important.\n", + "\n", + "The support is the number of occurrences of each class in y_test." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mhN5_p4yYxHK" + }, + "source": [ + "from sklearn.metrics import classification_report\n", + "print(classification_report(y_test, y_pred))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xzSFVEnAYxHP" + }, + "source": [ + "#### Interpretation: \n", + "\n", + "Of the entire test set, 88% of the promoted term deposit were the term deposit that the customers liked. Of the entire test set, 90% of the customer's preferred term deposit were promoted." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NGXJ6g2nYxHQ" + }, + "source": [ + "### ROC Curvefrom sklearn import metrics\n", + "from ggplot import *\n", + "\n", + "prob = clf1.predict_proba(X_test)[:,1]\n", + "fpr, sensitivity, _ = metrics.roc_curve(Y_test, prob)\n", + "\n", + "df = pd.DataFrame(dict(fpr=fpr, sensitivity=sensitivity))\n", + "ggplot(df, aes(x='fpr', y='sensitivity')) +\\\n", + " geom_line() +\\\n", + " geom_abline(linetype='dashed')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u9QKDuS0YxHQ" + }, + "source": [ + "from sklearn.metrics import roc_auc_score\n", + "from sklearn.metrics import roc_curve\n", + "logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))\n", + "fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])\n", + "plt.figure()\n", + "plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)\n", + "plt.plot([0, 1], [0, 1],'r--')\n", + "plt.xlim([0.0, 1.0])\n", + "plt.ylim([0.0, 1.05])\n", + "plt.xlabel('False Positive Rate')\n", + "plt.ylabel('True Positive Rate')\n", + "plt.title('Receiver operating characteristic')\n", + "plt.legend(loc=\"lower right\")\n", + "plt.savefig('Log_ROC')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git "a/Notebooks/NB15_02__Regress\303\243o Linear_hs3.ipynb" "b/Notebooks/NB15_02__Regress\303\243o Linear_hs3.ipynb" new file mode 100644 index 000000000..ffca82972 --- /dev/null +++ "b/Notebooks/NB15_02__Regress\303\243o Linear_hs3.ipynb" @@ -0,0 +1,10651 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "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.1" + }, + "colab": { + "name": "NB15_02__Regressão Linear.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwQDhId7N6_r" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

\n", + "

APRENDIZAGEM SUPERVISIONADA

\n", + "

MODELOS DE REGRESSÃO (LINEAR E LOGÍSTICA)

\n", + "\n", + "Fonte: https://realpython.com/linear-regression-in-python/\n", + "https://towardsdatascience.com/predicting-the-survival-of-titanic-passengers-30870ccc7e8" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PN-dQFJcM1UV" + }, + "source": [ + "Passos para implementação da Regressão Linear:\n", + "\n", + "* (1) Importar as libraries necessárias;\n", + "* (2) Carregar os dados;\n", + "* (3) Aplicar as transformações necessárias: outliers, NaN's, normalização (MinMaxScaler, RobustScaler, StandarScaler, Log, Box-Cox e etc);\n", + "* (4) DataViz dos dados: entender os relacionamentos, distribuições e etc presente nos dados;\n", + "* (5) Construir e treinar o modelo preditivo (neste caso, modelo de regressão);\n", + "* (6) Validar/verificar as métricas para avaliação do(s) modelo(s);\n", + "* (7) Predições." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8TldGZxAFV5E" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0QRbxlqaq7pr" + }, + "source": [ + "# Melhorias da sessão:\n", + "* Calcular as correlações antes e depois da RIDGE e LASSO para mostrar a multicolinearidade e explicar porque determinadas colunas \"deixam\" de ser importantes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P4sAIblOgFyL" + }, + "source": [ + "# Modelos de Regressão com Regularization para Classificação e Regressão" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7Y7cuJNgFyU" + }, + "source": [ + "## Regressão Linear Simples (usando OLS - Ordinary Least Squares)\n", + "\n", + "* Features $X_{np}$: é uma matriz de dimensão nxp contendo os atributos/variáveis preditoras do dataframe (variáveis independentes);\n", + "* Variável target/dependente representada por y;\n", + "* Relação entre X e y é representado pela equação abaixo, onde $w_{i}$ representa os pesos de cada coeficiente e $w_{0}$ representa o intercepto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NpJ580y9gFyU" + }, + "source": [ + "\n", + "\n", + "![X_y](https://github.com/MathMachado/Materials/blob/master/Architecture.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rhbVGJ0gFyY" + }, + "source": [ + "* Soma de Quadrados dos Resíduos (RSS) - Soma de Quadrados das diferenças entre os valores observados e preditos.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u8gA0YkbgFyp" + }, + "source": [ + "## Principais parâmetros do algoritmo:\n", + "* fit_intercept - Indica se o intercepto $w_{0}$ deve ou não ser ajustado. Se os dados estão normalizados, então não faz sentido ajustar o intercepto $w_{0}$.\n", + "\n", + "* normalize - $X$ será automaticamente normalizada (subtrai a média e divide pelo desvio-padrão);\n", + "\n", + "## Atributos do modelo de Machine Learning para Regressão\n", + "* coef - peso/fator de cada variável independente do modelo de ML;\n", + "\n", + "* intercepto $w_{0}$ - intercepto ou viés de $y$;\n", + "\n", + "## Funções para ajuste do ML:\n", + "* fit - treina o modelo com as matrizes $X$ e $y$;\n", + "* predict - Uma vez que o modelo foi treinado, para um dado $X$, use $y$ para calcular os valores preditos de $y$ (y_pred).\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A-JG8El1gFy7" + }, + "source": [ + "# Limitações do OLS (Ordinary Least Squares):\n", + "* Impactado/sensível à Outliers;\n", + "* Multicolinearidade; \n", + "* Heterocedasticidade - apresenta-se como uma forte dispersão dos dados em torno de uma reta;\n", + "\n", + "* References" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xylMYR8COyrw" + }, + "source": [ + "### Importar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2BGgrILlPK6Z" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "263GgbwhO2kQ" + }, + "source": [ + "### Carregar os dados\n", + "* Vamos carregar o dataset [Boston House Pricing](https://archive.ics.uci.edu/ml/datasets/housing)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1h66x_-rXGhi" + }, + "source": [ + "from sklearn.datasets import load_boston, load_iris" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rWniNkMpXQFU", + "outputId": "5096d239-2c8c-4327-dbf5-f9128faa589c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "boston = load_boston()\n", + "boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'DESCR': \".. _boston_dataset:\\n\\nBoston house prices dataset\\n---------------------------\\n\\n**Data Set Characteristics:** \\n\\n :Number of Instances: 506 \\n\\n :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\\n\\n :Attribute Information (in order):\\n - CRIM per capita crime rate by town\\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\\n - INDUS proportion of non-retail business acres per town\\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\\n - NOX nitric oxides concentration (parts per 10 million)\\n - RM average number of rooms per dwelling\\n - AGE proportion of owner-occupied units built prior to 1940\\n - DIS weighted distances to five Boston employment centres\\n - RAD index of accessibility to radial highways\\n - TAX full-value property-tax rate per $10,000\\n - PTRATIO pupil-teacher ratio by town\\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\\n - LSTAT % lower status of the population\\n - MEDV Median value of owner-occupied homes in $1000's\\n\\n :Missing Attribute Values: None\\n\\n :Creator: Harrison, D. and Rubinfeld, D.L.\\n\\nThis is a copy of UCI ML housing dataset.\\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\\n\\n\\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\\n\\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\\nprices and the demand for clean air', J. Environ. Economics & Management,\\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\\n...', Wiley, 1980. N.B. Various transformations are used in the table on\\npages 244-261 of the latter.\\n\\nThe Boston house-price data has been used in many machine learning papers that address regression\\nproblems. \\n \\n.. topic:: References\\n\\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\\n\",\n", + " 'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,\n", + " 4.9800e+00],\n", + " [2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,\n", + " 9.1400e+00],\n", + " [2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,\n", + " 4.0300e+00],\n", + " ...,\n", + " [6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 5.6400e+00],\n", + " [1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,\n", + " 6.4800e+00],\n", + " [4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 7.8800e+00]]),\n", + " 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n", + " 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTAT
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... RAD TAX PTRATIO B LSTAT\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 136 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQzFW7DUX_KW", + "outputId": "dcf288db-d99d-4d17-c22c-ceb8a9ba4841", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Variável target/resposta\n", + "df_boston['preco'] = load_boston().target\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 137 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H71da4bIO4kI" + }, + "source": [ + "### Data Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K-6YOdsTfciO" + }, + "source": [ + "#### Normalização/padronização dos nomes das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L8OJEapufhq4" + }, + "source": [ + "# Renomear as colunas do dataframe\n", + "df_boston.columns = [col.lower() for col in df_boston.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uRinX-5ofol_", + "outputId": "2e67bbbd-792f-4786-8c7e-2d0bd16fd249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... tax ptratio b lstat preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 139 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMDh5jyqekmr" + }, + "source": [ + "#### Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJIG0jJQf6em" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgYPzlvfemFc" + }, + "source": [ + "#### Missing values" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BAjw7UhJen0D", + "outputId": "917a8f23-ec31-4f22-9a46-c3a15c1e4563", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Missing values por colunas/variáveis\n", + "df_boston.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "crim 0\n", + "zn 0\n", + "indus 0\n", + "chas 0\n", + "nox 0\n", + "rm 0\n", + "age 0\n", + "dis 0\n", + "rad 0\n", + "tax 0\n", + "ptratio 0\n", + "b 0\n", + "lstat 0\n", + "preco 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 140 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jo3UWNpbYnNF", + "outputId": "aeefc57a-f1b7-41ac-aa2e-53f828b9be14", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Número de atributos\n", + "len(load_boston().feature_names)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "13" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 141 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0Yp8g7hxfQli", + "outputId": "43795436-0366-4427-ed5a-2deacedf567f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49 + } + }, + "source": [ + "# Missing Values por linhas\n", + "df_boston[df_boston.isnull().any(axis = 1)]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat, preco]\n", + "Index: []" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 142 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5qmkTFLrf9MT" + }, + "source": [ + "#### Estatísticas Descritivas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nprn3p_Wf_bn", + "outputId": "16f46af6-ab9a-4d7b-a875-295817b9bf9c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_boston.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
count506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000
mean3.61352411.36363611.1367790.0691700.5546956.28463468.5749013.7950439.549407408.23715418.455534356.67403212.65306322.532806
std8.60154523.3224536.8603530.2539940.1158780.70261728.1488612.1057108.707259168.5371162.16494691.2948647.1410629.197104
min0.0063200.0000000.4600000.0000000.3850003.5610002.9000001.1296001.000000187.00000012.6000000.3200001.7300005.000000
25%0.0820450.0000005.1900000.0000000.4490005.88550045.0250002.1001754.000000279.00000017.400000375.3775006.95000017.025000
50%0.2565100.0000009.6900000.0000000.5380006.20850077.5000003.2074505.000000330.00000019.050000391.44000011.36000021.200000
75%3.67708312.50000018.1000000.0000000.6240006.62350094.0750005.18842524.000000666.00000020.200000396.22500016.95500025.000000
max88.976200100.00000027.7400001.0000000.8710008.780000100.00000012.12650024.000000711.00000022.000000396.90000037.97000050.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "count 506.000000 506.000000 506.000000 ... 506.000000 506.000000 506.000000\n", + "mean 3.613524 11.363636 11.136779 ... 356.674032 12.653063 22.532806\n", + "std 8.601545 23.322453 6.860353 ... 91.294864 7.141062 9.197104\n", + "min 0.006320 0.000000 0.460000 ... 0.320000 1.730000 5.000000\n", + "25% 0.082045 0.000000 5.190000 ... 375.377500 6.950000 17.025000\n", + "50% 0.256510 0.000000 9.690000 ... 391.440000 11.360000 21.200000\n", + "75% 3.677083 12.500000 18.100000 ... 396.225000 16.955000 25.000000\n", + "max 88.976200 100.000000 27.740000 ... 396.900000 37.970000 50.000000\n", + "\n", + "[8 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 143 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JimyY3SgECE" + }, + "source": [ + "#### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jScHq7eTgIpm", + "outputId": "50696c9d-c19a-4937-9189-368be5fb291c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 483 + } + }, + "source": [ + "correlacoes = df_boston.corr()\n", + "correlacoes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
crim1.000000-0.2004690.406583-0.0558920.420972-0.2192470.352734-0.3796700.6255050.5827640.289946-0.3850640.455621-0.388305
zn-0.2004691.000000-0.533828-0.042697-0.5166040.311991-0.5695370.664408-0.311948-0.314563-0.3916790.175520-0.4129950.360445
indus0.406583-0.5338281.0000000.0629380.763651-0.3916760.644779-0.7080270.5951290.7207600.383248-0.3569770.603800-0.483725
chas-0.055892-0.0426970.0629381.0000000.0912030.0912510.086518-0.099176-0.007368-0.035587-0.1215150.048788-0.0539290.175260
nox0.420972-0.5166040.7636510.0912031.000000-0.3021880.731470-0.7692300.6114410.6680230.188933-0.3800510.590879-0.427321
rm-0.2192470.311991-0.3916760.091251-0.3021881.000000-0.2402650.205246-0.209847-0.292048-0.3555010.128069-0.6138080.695360
age0.352734-0.5695370.6447790.0865180.731470-0.2402651.000000-0.7478810.4560220.5064560.261515-0.2735340.602339-0.376955
dis-0.3796700.664408-0.708027-0.099176-0.7692300.205246-0.7478811.000000-0.494588-0.534432-0.2324710.291512-0.4969960.249929
rad0.625505-0.3119480.595129-0.0073680.611441-0.2098470.456022-0.4945881.0000000.9102280.464741-0.4444130.488676-0.381626
tax0.582764-0.3145630.720760-0.0355870.668023-0.2920480.506456-0.5344320.9102281.0000000.460853-0.4418080.543993-0.468536
ptratio0.289946-0.3916790.383248-0.1215150.188933-0.3555010.261515-0.2324710.4647410.4608531.000000-0.1773830.374044-0.507787
b-0.3850640.175520-0.3569770.048788-0.3800510.128069-0.2735340.291512-0.444413-0.441808-0.1773831.000000-0.3660870.333461
lstat0.455621-0.4129950.603800-0.0539290.590879-0.6138080.602339-0.4969960.4886760.5439930.374044-0.3660871.000000-0.737663
preco-0.3883050.360445-0.4837250.175260-0.4273210.695360-0.3769550.249929-0.381626-0.468536-0.5077870.333461-0.7376631.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "crim 1.000000 -0.200469 0.406583 ... -0.385064 0.455621 -0.388305\n", + "zn -0.200469 1.000000 -0.533828 ... 0.175520 -0.412995 0.360445\n", + "indus 0.406583 -0.533828 1.000000 ... -0.356977 0.603800 -0.483725\n", + "chas -0.055892 -0.042697 0.062938 ... 0.048788 -0.053929 0.175260\n", + "nox 0.420972 -0.516604 0.763651 ... -0.380051 0.590879 -0.427321\n", + "rm -0.219247 0.311991 -0.391676 ... 0.128069 -0.613808 0.695360\n", + "age 0.352734 -0.569537 0.644779 ... -0.273534 0.602339 -0.376955\n", + "dis -0.379670 0.664408 -0.708027 ... 0.291512 -0.496996 0.249929\n", + "rad 0.625505 -0.311948 0.595129 ... -0.444413 0.488676 -0.381626\n", + "tax 0.582764 -0.314563 0.720760 ... -0.441808 0.543993 -0.468536\n", + "ptratio 0.289946 -0.391679 0.383248 ... -0.177383 0.374044 -0.507787\n", + "b -0.385064 0.175520 -0.356977 ... 1.000000 -0.366087 0.333461\n", + "lstat 0.455621 -0.412995 0.603800 ... -0.366087 1.000000 -0.737663\n", + "preco -0.388305 0.360445 -0.483725 ... 0.333461 -0.737663 1.000000\n", + "\n", + "[14 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 144 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AxQp7xqdgTJP" + }, + "source": [ + "##### Gráfico das correlações entre as features/variáveis/colunas\n", + "Source: https://seaborn.pydata.org/examples/many_pairwise_correlations.html\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KOiH2X-WgqmN", + "outputId": "f72007dc-7c99-4ce1-b6bb-b86a9bf617c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 557 + } + }, + "source": [ + "import seaborn as sns\n", + "from string import ascii_letters\n", + "import matplotlib.pyplot as plt\n", + "\n", + "sns.set_theme(style = \"white\")\n", + "\n", + "d = df_boston\n", + "\n", + "# Compute the correlation matrix\n", + "corr = d.corr()\n", + "\n", + "# Generate a mask for the upper triangle\n", + "mask = np.triu(np.ones_like(corr, dtype=bool))\n", + "\n", + "# Set up the matplotlib figure\n", + "f, ax = plt.subplots(figsize=(11, 9))\n", + "\n", + "# Generate a custom diverging colormap\n", + "cmap = sns.diverging_palette(230, 20, as_cmap=True)\n", + "\n", + "# Draw the heatmap with the mask and correct aspect ratio\n", + "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n", + " square=True, linewidths=.5, cbar_kws={\"shrink\": .5})" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 145 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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+PCqjgcAAGCEKv+cury8PAUEBKhhw4Y6f/68Vq9eLUnq2rWrPvjgA507d06lpaV69913XY+JiIhQamqqcnJyJElOp1NfffVVVUcFAACGsyyrUrfapMpH6sLDw/Xuu+8qMjJSjRo10p133qndu3frwQcf1I4dO/TII4+oQYMGCg0N1enTpyVJd911l37/+9/rt7/9rZxOp4qLi9WrVy/deuutVR0XAAAYjK8Juw433HCDXn311Qrv+81vfqPRo0ertLRUEydOVGhoqOu+Rx55RI888khVxwMAADCCrZ9TN3bsWB06dEiFhYXq3Lmzhg4damccAABgOIMH6uwtdX/+85/tPDwAAPAwdk2/njt3TuPHj9fXX38tb29vjR07Vt27dy+33T//+U/Nnz9f58+fd104GhcXd03H4BslAACAx7Dr4oeFCxcqICBAH374obKysjR48GBt2LBB/v7+ZbZr0qSJ/vKXv6hZs2Y6c+aMHn30Ud1+++268847r3qMKr/6FQAAwNOtX79eAwcOlCS1bdtWt956qzZt2lRuuy5duqhZs2aSpPr16ys4OFiHDh26pmMwUgcAADxGZQfq8vLyKvwChMDAQAUGBl7zfg4fPqybbrrJtdy8eXPXR7ddTmZmpnbu3KnExMRrOgalDgAAeIzKnlO3ePFizZs3r9z6+Ph4DRs2zLUcExOjw4cPV7iPzZs3Vy6kpGPHjun5559XQkKCa+Tuaih1AADAY1iqXKkbMmSIYmJiyq2/dJQuJSXlivtp0aKFDh06pKCgIEnSkSNHFBYWVuG2J0+e1K9+9Ss9++yz6t279zVnpdQBAACPUdnp18pOs15Or169tGLFCt12223KysrS7t279corr5Tb7ocfftCvfvUrDR48WLGxsZU6BhdKAAAAVLFnnnlGeXl56tmzp5577jklJSUpICBAkvTaa69p+fLlkqQ33nhDWVlZWrFihaKjoxUdHe36itWrYaQOAAB4DLs+p87Pz09z5syp8L7hw4e7fh47dqzGjh37k45BqQMAAB7Drs+pqw5MvwIAABjAyzK5sgIAAFzknzu/qdT2PUI7VFES9zN2+vWND7bZHUGS9OvIMB1Yt8ruGJKkNlGx6jt1id0xJElp4/9H3x48ancMSdLPWzZT94SFdseQJH2c+IyObP3U7hiSpOZ3d1PPpLfsjiFJ+nDSr+yO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KlaSFPmnt2xOIn3w4q/sjoBqwPQrAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAAaq81JWUlFT1IQAAADyez099YEhIiF544QV99NFHKiws1MiRIxUZGem6Lz4+Xp988onCw8P17LPPaurUqcrIyFBRUZHCwsI0fvx4eXt76+jRo3rppZeUlZUlSerTp4+ee+45nThxQgkJCfr+++8lSc8884z69et3/b8xAACAgX5yqZMkh8Oh1NRUfffdd3r88cd15513qnHjxpKkOnXqaPXq1ZKkiRMn6q677tL//u//qrS0VKNHj9bq1as1YMAAjR49Wt26ddPcuXMlSbm5uZKkl156ST//+c/15z//WceOHdOjjz6qTp06qUOHDtcTGQAAwEjXVepiY2MlSe3bt1enTp20c+dOPfjgg5KkmJgY13YbN27Url279NZbb0mSCgsL1axZMxUUFGjHjh2u9ZIUFBQkSdqyZYvGjRsnSWratKm6deumbdu2UeoAAAAqcF2l7kr8/PxcP1uWpfnz56tVq1ZltikoKKiqwwMAAHiU67pQ4sL0alZWlvbs2aPQ0NAKt4uIiNAbb7whp9Mp6ccp1uzsbPn7++sXv/iFFi1a5Nr2wvTrPffco5UrV0qSjh8/rk8//VR333339cQFAAAw1nWVOqfTqX79+um5555TUlKS63y6S02YMEEOh0PR0dHq27evnn32WR09elSSNHPmTH3xxRfq06ePHnnkEb3zzjuSpD/+8Y9KT09X3759FRcXp9GjR+vnP//59cQFAAAw1nVNv8bFxWnYsGHl1mdkZJRZDggIUGJiYoX7aNasmebPn19u/c9+9rMK1wMAAKA8PnwYAADAAD95pO7S0TgAAADYh5E6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAM4GVZlmV3CAAAAFwfRuoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqavA7t27NWrUKLtjVLno6GgVFhZW+nERERH65ptvqiBRzTomzBASEqKCgoKf/H63w7hx47R06VK37W/u3Lk6f/682/ZXncc/ePCgVqxYUWbd0KFD9f3337sjWjkX3i9V7WrHycvL04IFC655f3a/xqgZKHWXKCkp0W233aZXXnnF7ihVLjU1VXXr1rU7BtygpKTE7gg1np3vd7tfn3nz5qm4uLhGHv9qz82hQ4fKlboFCxaodevWbstXE+Xl5enNN9+85u2r6jW2+72LyvGxO0B127Fjh2bMmOH6L6QxY8Zo0qRJioqK0tatW9WhQwdFR0dr+vTpWrNmjQ4ePKj+/ftrwIAB+uyzz1RYWKiZM2cqOTlZX375perWrav58+erSZMmbsn36aefatasWa7lzMxMvfrqq5o7d666dOmiHTt2yMvLS7Nnz1ZwcPB1HSskJERffPGF/P39FRERoejoaG3evFnHjx9XXFycnnzySUnS9u3blZiYKEm66667dPHXBV+8j4uXHQ6Hxo4dq3379snHx0ft2rXTa6+9dk25KnqNJGn9+vV68cUXy+WbPn26Pv/8cxUXF6tRo0aaMmWKbrrpJp08eVKjRo3SyZMnJUn33HOPJkyY8JOfqxEjRujDDz/UqVOnNGbMGEVGRkqSNm3apFmzZsnpdCooKEhJSUlq1aqVnn32WXXr1k1DhgzRvn37NHToUC1fvlw33njjT8pQUab4+Hh98sknCg8PV05Ojnx9fZWVlaXs7Gz17NlT3bt319y5c5WTk6MhQ4ZoyJAhbjn2BaNGjdL+/ftVXFys1q1ba8qUKWrQoIFmz56tdevWqWHDhuratau2bNmiNWvWSJJSUlK0bNkyOZ1OBQQEaPLkyWrfvr3bMm3YsEGzZs1SnTp19NBDD7nWX3hv1qtXT0lJSdq6dat8fX3l5+en5ORktx3/4uNd/Pr07t1biYmJOnfunIqKijRgwAA9/fTTkqSjR49qzJgxOn78uG666SY5HO777+0Lf7uDBg2Sw+HQs88+q7fffttVAMaOHat77rlHJ0+eVGxsrF577TXddtttSklJ0cqVK7VkyRL5+Fz9/ypCQkL0wgsv6KOPPlJhYaFGjhypyMjIcsdfsmSJpkyZIm9vb+3fv18FBQVKTU297HspKSlJBw8eVHR0tNq0aaM5c+YoIiJCf/3rX9WhQwcdOHBAkyZNUm5urnx8fDRixAjdf//91/WcLVy4sNzvUVVKS0srfD8mJSXpzJkzio6OVr169ZScnKy//e1veu+99+R0OlWnTh1NnjxZHTt2rPA5DgwMvOJxL/d6Xbjv4vfus88+q6lTpyojI0NFRUUKCwvT+PHj5e3traNHj+qll15SVlaWJKlPnz567rnndOLECSUkJLhGVJ955hn169evyp5H/D+WB/nhhx+s//N//o/13//+17IsyyopKbFOnTplde/e3UpISHBtt3XrVismJsayLMvKzs62OnToYH388ceWZVnWggULrF/+8pfWnj17LMuyrISEBGvWrFlVknfFihXWwIEDrU8//dTq1KmT9fXXX1uWZVnz58+3Ro4ced3779Chg5Wfn29ZlmV1797dmjZtmmVZP/7OoaGhVn5+vlVUVGTdd9991tatWy3Lsqz33nvP6tChg5WRkVFuHxcvb9iwwYqLi3OtP3Xq1DVlutJrVFE+y7KskydPuh6/cuVK6/e//71lWZb11ltvWS+++GKlM1SkQ4cO1pIlSyzLsqzt27db9913n2VZlnXixAkrLCzM+vbbb13Hf+yxx1z3de/e3frPf/5j9enTx/UecpcOHTpYr7/+umt57Nix1qBBg6yioiLr7Nmz1t13322NGzfOcjqdVk5OTpnnzF0ufu5nzZplvfzyy9ZHH31k9e3b1yooKLCcTqf1wgsvuP6e/vOf/1hDhw61ioqKLMuyrE8++cQaOHCg2/IcP37c6tq1q5WZmWlZlmW98cYbrvfkhf/9+uuvrV69ellOp9OyrOt7X1zJpa/PmTNnXL93fn6+1bt3b2vfvn2WZVlWfHy8NXfuXMuyLOv777+3QkNDXe83d2W58Nrn5uZapaWllmVZVmZmphUeHu7abuvWrdZDDz1k7dixw3rggQesw4cPV+oYF36HzMxMq2vXrtaJEyfKHd+yfnyvxsTEWAUFBa51Fb2XLmS68P65oHv37q5/Bz322GPWypUrLcuyrG+//dbq2rVrmX1V1pV+D3e62vsxOzvb6tq1a5nHXPx7/fvf/7ZiY2PL7a8yx7/S63Xxe3fChAlWSkqKZVmW5XQ6rREjRlgrVqywLMuynnzySWvBggXlMg4fPtyaPXu2ZVmWdfToUevee+91vWaoOh41Urdz504FBwfrjjvukCR5e3urQYMGknTF/4Lw8/PTAw88IEnq3LmzbrzxRnXs2NG1vHnzZrdn/eyzz/TWW2/p73//u7799lu1a9dOnTp1kiSFhobq448/dvsxo6KiJEktW7ZUYGCgcnJyVFxcrHr16iksLMy1zaRJk666r1tuuUWZmZlKTExU165dXc/f1VzpNaooX3BwsDZt2qRly5bp7NmzZaYKunTpokWLFmn69Onq2rWr7rvvvmt+Lipy4fihoaE6duyYioqK9OWXX+qWW27RzTffLEnq37+/EhMTlZ+fr8aNG2vKlCkaMmSI/ud//uean4PKiImJKbPco0cP+fr6SpLatWunbt26yeFwqFmzZmWeM3dJTU1VWlqaiouLdfbsWbVt21bFxcXq3bu3/Pz8JP34tzV//nxJ0saNG5Wenq7Y2FhJkmVZysvLc1ueL7/8Up06dXKN/A0cOFAzZ84ss02rVq1UUlKiiRMnKiwsTN27d3fb8S918etTWFioyZMnKyMjQ15eXjp27JjS09MVHBysbdu26Y9//KMr3z333FNlmbKzszVq1CgdPXpUPj4+OnHihI4fP64mTZooLCxMffr00RNPPKF58+apefPmldr3hde1ffv26tSpk3bu3KkHH3ywwm179erleo9IFb+XriY/P1979+5V//79JUk333yzOnbsqJ07dyoiIqJS2X/q73G9KvN+/Oqrr/T666/r9OnT8vLyco2O/VRX+j0vfu9u3LhRu3bt0ltvvSXpx/dys2bNVFBQoB07drjWS1JQUJAkacuWLRo3bpwkqWnTpurWrZu2bdumDh06XFdmXJlHlborufhfLpe68H+SkuRwOMose3t7y+l0ujVLenq6EhIStHDhQtcfyKUZquI8hzp16rh+vtLv5eXlVWY76/9NxxYVFbnWt2rVSmvXrtXWrVu1adMmzZ49W2lpaWWO4Y58hw4d0tSpU/XOO++oVatW+uKLLzR69GhJ0i9+8QulpKRo8+bNSk1N1RtvvKHly5df9/G9vb0lXdu5Jnv37lWjRo2Uk5Pzk497JZe+by99jq71Nf0ptm/fruXLlys5OVlBQUFKS0vTypUrr/gYy7LUv39/DR8+3G05Kqt+/fp67733tG3bNm3evFkzZ85USkqK206huNjFr8+sWbPUpEkTTZs2TT4+PoqLiyvzN1NdRo4cqXHjxqlHjx4qLS1Vly5dyuTYs2ePgoKCquw9e8HFz81PeS+Z4nLvx0udP39ew4cP19KlS9W5c2cdPXr0uqeZr+Ti18eyLM2fP1+tWrUqs011XFCCyvGoCyVCQ0OVmZmpHTt2SJKcTqdOnz5tc6qyjh49qmHDhunll19Wu3bt7I6j9u3bq7CwUNu3b5ckvf/++2VGVlq3bq3du3dLktLS0lzrc3Jy5O3trR49emj8+PHKzc3VqVOnrnq8yr5G+fn5uuGGG9SkSROVlpaWOTcqOztbAQEBevjhhzV+/Hh9/fXXKi0trdwTcA1509PTlZmZKenH88U6deqkgIAA7dq1S0uXLlVqaqpyc3Ovq1DWRHl5eQoICFDDhg11/vx5rV69WpLUtWtXffDBBzp37pxKS0v17rvvuh4TERGh1NRUV2FwOp366quv3JYpNDRUe/bscY1grFq1qtw2ubm5OnfunMLDwzV69GjVr19f2dnZbstwOWfOnNGNN94oHx8fffPNN66/KUm6++67Xc9fdna2tmzZ4tZj+/v7Kz8/35WjZcuWkqTVq1eXuWJy0aJFKikp0Zo1a/Tmm29q7969lTrOhd8hKytLe/bsUWhoaLnjV+Ry7yVJCggIuOxjAwIC1LFjx//bvv27tK6GcQD/WlQKRpK2oCA6VBAHHSpYcKmCDgZJ1UFwcxAs1kEslkpaDbRdSlscdHMqCiKYSfwHXF0EXXRwEnEQOoho0TTnDmK4Pd5e9Vw9nhu/nzEheX/kDXnyvu9jBUHn5+c4PT21yv1V1drxGaqNR0EQUCqVrJ/Hh4cHGIZhzZ5ub29X3Oe1Pv4nb23n4OAgNjY2rJ/CYrGIi4sLNDQ0oKenB4VCoaI9wNMe5ufA/Pr6GgcHB+jr63tX/ej9vtVMnSRJWF9fRyaTwd3dnbWZ/0+yu7uLYrGIVCplHVNV9cvqU19fj9XV1YpEiZaWFuu8qqrQNA2NjY2QZdk6fnZ2ZmUQm6aJUCiE5ubmV8t77zPq7OyELMsYGRmBy+XCwMCA9bE8PDxEoVCAw+GAaZpIJpMfugEdeFpqyGaziEajMAwDbrcbuVwONzc3WFxcRCaTgcfjQT6fx+TkJHw+n7V0/38XCASwt7eH4eFhuFwu9Pb24uTkBENDQzg6OsLo6ChEUYTP57MCc7/fj4WFBYTDYZTLZTw+PkKWZXR3d39InTweD9LpNGZnZ+F0OisSJZ5dXV1hZWUFhmGgXC6jv7//Uz/az8LhMGKxGHRdh9frhd/vt84lEgnEYjHs7++jtbXV2u7wUaanpzE1NQWn0wlVVTE3NwdRFBEIBCBJEgDg+PgYm5ub0HUdbrcb6XQakUgEuq5DEIQ3lVMulzE+Po77+3ukUil4PJ4X5W9tbb24rtpYAp7eca/XC0VR0N7ejrW1tYpr8/k8NE1DoVBAbW0tstmstcLxq6q14zNUG48OhwPBYBDBYBCiKGJnZwfz8/OYmJiAJEkvkjd+7uPXEiWAt7czHo8jl8thbGwMNTU1qKurQzweR1tbG/L5PJLJJBRFgcPhgKIoCIVCWF5ehqZpCAaDAIBoNIqOjo7/3mH0r2p+/PhbKiMR0Qe4vb2FIAgwTROJRAJNTU2IRCJfXS36RD9nwtOfjc/Lnr7VTB0R/R5LS0u4vLxEqVRCV1cXZmZmvrpKRES2x5k6IiIiIhv4VokSRERERHbFoI6IiIjIBhjUEREREdkAgzoiIiIiG2BQR0RERGQDDOqIiIiIbOAvF2TfJBn+6VQAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nogPhyfVO70G" + }, + "source": [ + "### Construir e treinar o(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HxYpfyvQaIe1" + }, + "source": [ + "$X = [X_{1}, X_{2}, X_{p}]$ = X_boston abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BhLZJhibVNG" + }, + "source": [ + "X_boston = df_boston.drop(columns = ['preco'], axis = 1) # todas as variáveis/atributos, exceto 'preco'\n", + "y_boston = df_boston['preco'] # variável-target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_nC_RGva1Z6", + "outputId": "6a5946c8-62b3-424f-a809-9a2bbc34f191", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "X_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstat
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... rad tax ptratio b lstat\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 147 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nlVJM--Ya5fS", + "outputId": "58037983-175f-47ed-ad47-5826589358b0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_boston[0:10] # Series (coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 24.0\n", + "1 21.6\n", + "2 34.7\n", + "3 33.4\n", + "4 36.2\n", + "5 28.7\n", + "6 22.9\n", + "7 27.1\n", + "8 16.5\n", + "9 18.9\n", + "Name: preco, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 148 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b50_6tv5h1kY" + }, + "source": [ + "# Definindo os dataframes de treinamento e teste:\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, \n", + " y_boston, \n", + " test_size = 0.2, \n", + " random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U3hpdkDbYTv", + "outputId": "35e8cee1-201a-4a65-a6ec-8fa9e8c7c0a8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(f\"Dataframe de treinamento: {X_treinamento.shape[0]} linhas\")\n", + "print(f\"Dataframe de teste......: {X_teste.shape[0]} linhas\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Dataframe de treinamento: 404 linhas\n", + "Dataframe de teste......: 102 linhas\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SvevXulFiJj1" + }, + "source": [ + "#### Treinamento do modelo de Regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GVwF3vp8iNff" + }, + "source": [ + "# Importa a library LinearRegression --> Para treinamento da Regressão Linear\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Library para statmodels\n", + "import statsmodels.api as sm" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ibX6bCbViW-v" + }, + "source": [ + "# Instancia o objeto\n", + "regressao_linear = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M-5wRGUribY0", + "outputId": "a67d7355-3d9e-43fc-edf6-8ebd71911935", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Treina o modelo usando as amostras/dataset de treinamento: X_treinamento e y_treinamento \n", + "regressao_linear.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 153 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jri-jA1VjmUl", + "outputId": "3150261d-c264-4273-9c5f-95229529881b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Valor do intercepto\n", + "regressao_linear.intercept_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.9020918753502" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 154 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOjadxdxjqtT", + "outputId": "49d06bd9-e375-403f-e257-863967f10fd3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 452 + } + }, + "source": [ + "# Coeficientes do modelo de Regressão Linear\n", + "coeficientes_regressao_linear = pd.DataFrame([X_treinamento.columns, regressao_linear.coef_]).T\n", + "coeficientes_regressao_linear = coeficientes_regressao_linear.rename(columns={0: 'Feature/variável/coluna', 1: 'Coeficientes'})\n", + "coeficientes_regressao_linear" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Feature/variável/colunaCoeficientes
0crim-0.0822083
1zn0.0428002
2indus0.0756011
3chas3.16348
4nox-19.4945
5rm3.98161
6age0.00480929
7dis-1.37396
8rad0.298883
9tax-0.0123962
10ptratio-0.984657
11b0.008949
12lstat-0.526478
\n", + "
" + ], + "text/plain": [ + " Feature/variável/coluna Coeficientes\n", + "0 crim -0.0822083\n", + "1 zn 0.0428002\n", + "2 indus 0.0756011\n", + "3 chas 3.16348\n", + "4 nox -19.4945\n", + "5 rm 3.98161\n", + "6 age 0.00480929\n", + "7 dis -1.37396\n", + "8 rad 0.298883\n", + "9 tax -0.0123962\n", + "10 ptratio -0.984657\n", + "11 b 0.008949\n", + "12 lstat -0.526478" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 155 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwnkhPwDjkhS" + }, + "source": [ + "#### Usando statmodels" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ltbekHd_k3PH", + "outputId": "a69b057e-75a6-446e-8b7c-ad37604114a5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2_treinamento = sm.add_constant(X_treinamento)\n", + "lm_sm = sm.OLS(y_treinamento, X2_treinamento).fit()\n", + "print(lm_sm.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 78.97\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.48e-100\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2458.\n", + "Df Residuals: 390 BIC: 2514.\n", + "Df Model: 13 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.9021 6.037 5.947 0.000 24.033 47.771\n", + "crim -0.0822 0.045 -1.824 0.069 -0.171 0.006\n", + "zn 0.0428 0.016 2.638 0.009 0.011 0.075\n", + "indus 0.0756 0.072 1.054 0.292 -0.065 0.217\n", + "chas 3.1635 0.997 3.174 0.002 1.204 5.123\n", + "nox -19.4945 4.539 -4.295 0.000 -28.418 -10.571\n", + "rm 3.9816 0.510 7.802 0.000 2.978 4.985\n", + "age 0.0048 0.015 0.312 0.755 -0.025 0.035\n", + "dis -1.3740 0.236 -5.827 0.000 -1.838 -0.910\n", + "rad 0.2989 0.079 3.760 0.000 0.143 0.455\n", + "tax -0.0124 0.004 -2.814 0.005 -0.021 -0.004\n", + "ptratio -0.9847 0.156 -6.309 0.000 -1.292 -0.678\n", + "b 0.0089 0.003 2.796 0.005 0.003 0.015\n", + "lstat -0.5265 0.060 -8.764 0.000 -0.645 -0.408\n", + "==============================================================================\n", + "Omnibus: 140.799 Durbin-Watson: 2.083\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 591.650\n", + "Skew: 1.484 Prob(JB): 3.35e-129\n", + "Kurtosis: 8.132 Cond. No. 1.51e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.51e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kpt3A4Q0guHv" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVUJkfg4gSh7", + "outputId": "eeff1e8f-8ac7-44e8-e0fe-caf0d4a641c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X3 = X_treinamento.drop(columns = 'age', axis = 1)\n", + "X3_treinamento = sm.add_constant(X3)\n", + "lm_sm2 = sm.OLS(y_treinamento, X3_treinamento).fit()\n", + "print(lm_sm2.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 85.75\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.64e-101\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 391 BIC: 2508.\n", + "Df Model: 12 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.7325 6.006 5.950 0.000 23.925 47.540\n", + "crim -0.0815 0.045 -1.812 0.071 -0.170 0.007\n", + "zn 0.0422 0.016 2.623 0.009 0.011 0.074\n", + "indus 0.0750 0.072 1.048 0.295 -0.066 0.216\n", + "chas 3.1794 0.994 3.198 0.001 1.225 5.134\n", + "nox -19.1299 4.381 -4.367 0.000 -27.742 -10.517\n", + "rm 4.0153 0.498 8.059 0.000 3.036 4.995\n", + "dis -1.3963 0.224 -6.223 0.000 -1.837 -0.955\n", + "rad 0.2958 0.079 3.755 0.000 0.141 0.451\n", + "tax -0.0123 0.004 -2.802 0.005 -0.021 -0.004\n", + "ptratio -0.9812 0.156 -6.310 0.000 -1.287 -0.675\n", + "b 0.0090 0.003 2.825 0.005 0.003 0.015\n", + "lstat -0.5202 0.057 -9.203 0.000 -0.631 -0.409\n", + "==============================================================================\n", + "Omnibus: 142.363 Durbin-Watson: 2.081\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 608.694\n", + "Skew: 1.496 Prob(JB): 6.67e-133\n", + "Kurtosis: 8.216 Cond. No. 1.48e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.48e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lcp7m5FmZvG" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'indus'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jEiBywx4hGNB", + "outputId": "fb2abfd1-9019-4e37-f6e1-cf5e54ae1276", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X4 = X3_treinamento.drop(columns = 'indus', axis = 1)\n", + "X4_treinamento = sm.add_constant(X4)\n", + "lm_sm3 = sm.OLS(y_treinamento, X4_treinamento).fit()\n", + "print(lm_sm3.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.724\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 93.42\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 2.86e-102\n", + "Time: 11:00:14 Log-Likelihood: -1215.4\n", + "No. Observations: 404 AIC: 2455.\n", + "Df Residuals: 392 BIC: 2503.\n", + "Df Model: 11 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.4757 6.001 5.911 0.000 23.677 47.275\n", + "crim -0.0840 0.045 -1.871 0.062 -0.172 0.004\n", + "zn 0.0407 0.016 2.539 0.012 0.009 0.072\n", + "chas 3.2924 0.989 3.330 0.001 1.349 5.236\n", + "nox -17.9558 4.235 -4.239 0.000 -26.283 -9.629\n", + "rm 3.9674 0.496 7.996 0.000 2.992 4.943\n", + "dis -1.4553 0.217 -6.699 0.000 -1.882 -1.028\n", + "rad 0.2744 0.076 3.606 0.000 0.125 0.424\n", + "tax -0.0103 0.004 -2.603 0.010 -0.018 -0.003\n", + "ptratio -0.9609 0.154 -6.227 0.000 -1.264 -0.658\n", + "b 0.0089 0.003 2.778 0.006 0.003 0.015\n", + "lstat -0.5151 0.056 -9.145 0.000 -0.626 -0.404\n", + "==============================================================================\n", + "Omnibus: 142.123 Durbin-Watson: 2.073\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 605.868\n", + "Skew: 1.494 Prob(JB): 2.74e-132\n", + "Kurtosis: 8.202 Cond. No. 1.47e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.47e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFejox5XmrEE" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'crim'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DOehOql8hZWr", + "outputId": "cbb71827-f44e-4688-93c4-98a3ec5e3257", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X5 = X4_treinamento.drop(columns = 'crim', axis = 1)\n", + "X5_treinamento = sm.add_constant(X5)\n", + "lm_sm4 = sm.OLS(y_treinamento, X5_treinamento).fit()\n", + "print(lm_sm4.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.721\n", + "Model: OLS Adj. R-squared: 0.714\n", + "Method: Least Squares F-statistic: 101.8\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.55e-102\n", + "Time: 11:00:14 Log-Likelihood: -1217.2\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 393 BIC: 2500.\n", + "Df Model: 10 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 33.9950 5.968 5.696 0.000 22.262 45.728\n", + "zn 0.0375 0.016 2.349 0.019 0.006 0.069\n", + "chas 3.3959 0.990 3.430 0.001 1.449 5.343\n", + "nox -17.1637 4.228 -4.060 0.000 -25.475 -8.852\n", + "rm 4.0365 0.496 8.132 0.000 3.061 5.012\n", + "dis -1.3999 0.216 -6.484 0.000 -1.824 -0.975\n", + "rad 0.2278 0.072 3.158 0.002 0.086 0.370\n", + "tax -0.0100 0.004 -2.513 0.012 -0.018 -0.002\n", + "ptratio -0.9493 0.155 -6.137 0.000 -1.253 -0.645\n", + "b 0.0101 0.003 3.217 0.001 0.004 0.016\n", + "lstat -0.5315 0.056 -9.523 0.000 -0.641 -0.422\n", + "==============================================================================\n", + "Omnibus: 140.245 Durbin-Watson: 2.070\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 609.563\n", + "Skew: 1.464 Prob(JB): 4.32e-133\n", + "Kurtosis: 8.257 Cond. No. 1.46e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.46e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UafIUrpZB0YP" + }, + "source": [ + "### Conclusão\n", + "* Quais variáveis/colunas/atributos ficam no modelo?\n", + "* **Muito importante (exercício)**: normalizar (MinMaxScaler) as covariáveis e refazer a análise.\n", + "* Nesta iteração (depois de excluirmos (nesta ordem) as variáveis age, indus e crim, não surge nenhuma outra variável insignificante ao nível de 5 (na verdade, o maior valor é 1.9%)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jx7sOzrrm-H_" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXeiFtnJO_1u" + }, + "source": [ + "### Validação do(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlGVFA6uPDvr" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PE3aKJ6mPDyJ" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3nGiyX8jadH" + }, + "source": [ + "### Deployment da solução **analítica**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YQF4NIlGSLH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UQfpoo1igFy8" + }, + "source": [ + "# Regularized Regression Methods \n", + "## Ridge Regression - Penalized Regression\n", + "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando (valor de $\\alpha$) os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n", + "* Menor impacto dos outliers.\n", + "\n", + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o00xH2MvxvgP" + }, + "source": [ + "# Matriz de covariáveis do modelo:\n", + "X_new = [[0, 0], [0, 0], [1, 1]]\n", + "X_new2 = [[0, 0], [0, 1.5], [1, 1]]\n", + "\n", + "y_new = [0, .1, 1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v9U7c03NzW_c", + "outputId": "2652bd10-e6b4-4200-f7f0-a07806564a1d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_new # 2 variáveis/colunas no dataframe" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[[0, 0], [0, 0], [1, 1]]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 161 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iiVEAPpUzXyN", + "outputId": "a69fe575-57da-459c-f482-41d3185ab76f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 0.1, 1]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 162 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDljolA95Hw5" + }, + "source": [ + "### Sem outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8mWj2GbPOkHx", + "outputId": "3b433090-a588-449a-af69-5f2da53a9b60", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new, y_new)\n", + "ridge.coef_ # Coeficientes da Ridge" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mridge\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mRidge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0malpha\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_new\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_new\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoef_\u001b[0m \u001b[0;31m# Coeficientes da Ridge\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'Ridge' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8yvd4ABY5JjC" + }, + "source": [ + "### Com outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O3sJZ_pe5GQ7" + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new2, y_new)\n", + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zZxdCLU_5kKh" + }, + "source": [ + "#### Conseguiram visualizar o impacto dos outliers?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u5jsTkUmS9wK" + }, + "source": [ + "### Aplicação da Regressão Ridge no dataframe Boston Housing Price." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kp4VIJWxgFy8" + }, + "source": [ + "from sklearn.linear_model import Ridge\n", + "ridge = Ridge(alpha = 0.1) # Definição do valor de alpha da regressão ridge\n", + "lr = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cmRMoOwV6FMt" + }, + "source": [ + "# Ao inves de: regressao_linear.fit(X_treinamento, y_treinamento)\n", + "ridge.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VPnekyUbK6Xg" + }, + "source": [ + "#### Peso/contribuição das variáveis para a regressão usando RIDGE" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k83RDArjsUrj" + }, + "source": [ + "df_boston.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vMCb0CFjK973" + }, + "source": [ + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZqksuIjXypRJ" + }, + "source": [ + "# treinando a regressão Ridge\n", + "ridge.fit(X_treinamento, y_treinamento)\n", + "\n", + "# treinando a regressão linear simples (OLS)\n", + "lr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7r28PBsWLtjA" + }, + "source": [ + "ridge.alpha" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dDZ_TJnhuZno" + }, + "source": [ + "#### $\\alpha = 0.01$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hRMK_QTmNgc1" + }, + "source": [ + "# maior alpha --> mais restrição aos coeficientes; \n", + "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS; Se alpha = 0 ==> Ridge = OLS.\n", + "rr = Ridge(alpha = 0.01) # Quanto mais próximo de 0 ==> Ridge = OLS\n", + "rr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRuWmBE7Ngc7" + }, + "source": [ + "# MSE = Erro Quadrático Médio\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n", + "lr_model=(mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "L4an-zHetafI" + }, + "source": [ + "print(rr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QsLVzk3EtbGs" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K2sjngo1QhY2" + }, + "source": [ + "### Coeficientes da Ridge:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5i87o3quByz" + }, + "source": [ + "# Lista das variáveis + coeficientes da Ridge:\n", + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s44vo9IjQonE" + }, + "source": [ + "### Experimente vários outros valores para $\\alpha$ como, por exemplo, $\\alpha = 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CDv5fGPbuUq5" + }, + "source": [ + "#### $\\alpha = 100$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEaj4QRrNgdA" + }, + "source": [ + "rr100 = Ridge(alpha = 100)\n", + "rr100.fit(X_treinamento, y_treinamento)\n", + "train_score=lr.score(X_treinamento, y_treinamento)\n", + "test_score=lr.score(X_teste, y_teste)\n", + "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zhcfoTEENgdE" + }, + "source": [ + "# MSE\n", + "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n", + "lr_model = (mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NGDBpfiquxoc" + }, + "source": [ + "print(rr100_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Owami5MVureW" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xk5dN3Owu6Kw" + }, + "source": [ + "### Próximo passo: fazer o statmodel dos modelos ridge." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEF_3GgUgF0Q" + }, + "source": [ + "# LASSO (Least Absolute Shrinkage And Selection Operator regularization)\n", + "* Método mais comum e usado para Regularization; \n", + "* Reduz overfitting;\n", + "* Se encarrega do **Feature Selection**, pois descarta variáveis altamente correlacionadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YiKb9reQdI4" + }, + "source": [ + "* Usado no processo de Regularization - processo de penalizar as variáveis para manter somente os atributos mais importantes. Pense na utilidade disso diante de um dataframe com muitas variáveis;\n", + "* A regressão Lasso vem com um parâmetro ($\\alpha$), e quanto maior o alfa, a maioria dos coeficientes de recurso é zero. Ou seja, quando $\\alpha = 0$, a regressão Lasso produz os mesmos coeficientes que uma regressão linear. Quando alfa é muito grande, todos os coeficientes são zero." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5p_ZPZ4tTUX1" + }, + "source": [ + "### Exemplo LASSO" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JD1_M2uw6q0W" + }, + "source": [ + "X_new" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5JZTnkTOkI9" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_new, y_new)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gEUxSlThOkJD" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EQaGWzzLT9qP" + }, + "source": [ + "### Aplicação do LASSO no Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ME6v6LFlgF0Q" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h6DSEHc1gF0V" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8SzYnpVGy4cy" + }, + "source": [ + "### Coeficientes do LASSO:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2w2QDmdxxVe" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(lasso.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UBOCg1H9zn6A" + }, + "source": [ + "### Comparação com os coeficientes do RIDGE:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g1fF-mEZzXpH" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xP1fX1Bi6VdX" + }, + "source": [ + "**Conclusão**: Coeficientes zero podem ser excluídos da Análise/modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TbtxIWyGSXkH" + }, + "source": [ + "### Efeito dos valores de $\\alpha$\n", + "* Função adaptada de https://chrisalbon.com/machine_learning/linear_regression/effect_of_alpha_on_lasso_regression/." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B4AuWA4LRBE3" + }, + "source": [ + "# Create a function called lasso,\n", + "def lasso(alphas):\n", + " '''\n", + " Takes in a list of alphas. Outputs a dataframe containing the coefficients of lasso regressions from each alpha.\n", + " '''\n", + " # Create an empty data frame\n", + " df = pd.DataFrame()\n", + " \n", + " # Create a column of feature names\n", + " df['Feature Name'] = names\n", + " \n", + " # For each alpha value in the list of alpha values,\n", + " for alpha in alphas:\n", + " # Create a lasso regression with that alpha value,\n", + " lasso = Lasso(alpha = alpha)\n", + " \n", + " # Fit the lasso regression\n", + " lasso.fit(X_treinamento, y_treinamento)\n", + " \n", + " # Create a column name for that alpha value\n", + " column_name = 'Alpha = %f' % alpha\n", + "\n", + " # Create a column of coefficient values\n", + " df[column_name] = lasso.coef_\n", + " \n", + " # Return the datafram \n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VEDvXvuNRK0C" + }, + "source": [ + "names = X_treinamento.columns\n", + "\n", + "# Valores de alpha:\n", + "lasso([.0001, .001, 0, .01, .1, 1, 10, 100])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xFlvTUJKhwgW" + }, + "source": [ + "### Capturando os elementos mais importantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4_-sUgMIhzmE" + }, + "source": [ + "r_squared = model.rsquared\n", + "r_squared_adj = model.rsquared_adj\n", + "coeficientes_regressao = model.params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "apGv5ytnimsM" + }, + "source": [ + "VEJA: https://stackoverflow.com/questions/27928275/find-p-value-significance-in-scikit-learn-linearregression" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uhokzxtcil8w" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jSYw6SdcXa0q" + }, + "source": [ + "### Cross-Validation & GridSearch para LASSO" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E14i4Y3rqEX2" + }, + "source": [ + "### Colocar aqui a fórmula do RMSE." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "irFZAkvVXfya" + }, + "source": [ + "from sklearn.linear_model import LassoCV\n", + "from sklearn.model_selection import RepeatedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T3Jjom8RYdly" + }, + "source": [ + "# define model evaluation method\n", + "cv = RepeatedKFold(n_splits = 5, n_repeats = 3, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cw3lAvRPYgJe" + }, + "source": [ + "# define model\n", + "model = LassoCV(alphas = np.arange(0.001, 10, 0.001), cv = cv, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLX3CpThXvkJ" + }, + "source": [ + "# fit model\n", + "model.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U1ubd5huYQ7u" + }, + "source": [ + "# summarize chosen configuration\n", + "print('alpha: %f' % model.alpha_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9P7hYoo4gF0Z" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yChNUYs7gF0b" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "S1m3SL2avMbd" + }, + "source": [ + "transformacao.fit(dados_que_eu_quero_transformar)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4mbIaAUAF4N6" + }, + "source": [ + "en.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MaUkZw8ngF0h" + }, + "source": [ + "list(zip(X_treinamento, en.coef_))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K7LuPhCtvouJ" + }, + "source": [ + "### GridSearch para encontrar o $\\alpha$ para Elastic Net" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xl-Qh9caDyCp" + }, + "source": [ + "# Instancia o objeto:\n", + "en = ElasticNet(normalize = True)\n", + "\n", + "# Otimização dos hiperparâmetros:\n", + "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n", + " 'l1_ratio': [.2, .4, .6, .8]}\n", + "\n", + "search = GridSearchCV(estimator = en, # Elastic Net\n", + " param_grid = d_hiperparametros, # Dicionário com os hiperparâmetros\n", + " scoring = 'mean_squared_error', # MSE (Erro Quadrático Médio) - Métrica para avaliação da performance do modelo\n", + " #scoring = 'neg_mean_squared_error',\n", + " n_jobs = -1, # Usar todos os processadores/computação\n", + " refit = True, \n", + " cv = 10) # Número de Cross-Valitations" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JvNQyUW_2QLr" + }, + "source": [ + "### Exercício (Estatística): Sugestão de ajuste manual\n", + "* Estudar estatisticamente a distribuição de frequência em que a variável é significante (ao nível de 5%) em 100 fits." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hp1hV5YahsJb" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ng0rPXfA1DgS" + }, + "source": [ + "for i in range(0, 100):\n", + " X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X, y, 0.2)\n", + " modeloi = fit(X_treinamento, y_treinamento)\n", + " intercepto\n", + " coeficientes da regressão\n", + " validação dos parâmetros (significância)\n", + " y_predict = predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c3_XCQCPGlr3" + }, + "source": [ + "search.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Retorna os melhores hiperparâmetros do algoritmo:\n", + "search.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq0_ugQfGrdb" + }, + "source": [ + "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n", + "en2.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ILA5lScUx-Ub" + }, + "source": [ + "\n", + "# Métrica\n", + "ml2 = (mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))\n", + "# Encontrar a métrica neg_squared_error --> ml3 = (neg_mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BzO_dHRixd_L" + }, + "source": [ + "print(f\"MSE: {ml2}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zaEwh3t3zwFc" + }, + "source": [ + "**Conclusão**:\n", + "* Comparação dos MSE - A Regressão sem Regularization produziu MSE de 23.94. Como podemos ver, Elastic Net produz MSE: 15.4." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5geUMgC6ztxE" + }, + "source": [ + "### Coeficientes do Elastic Net:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LyLdASRqzwCq" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "90pfP9-3OkJG" + }, + "source": [ + "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILCXvYKDOkJH" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaQPDCR2OkJI" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xVp16Eu_OkJL" + }, + "source": [ + "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwj018U8OkJO" + }, + "source": [ + "en.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rJRWBzSQCcss" + }, + "source": [ + "# Regressão Logística\n", + "\n", + "* Na regressão linear nós tentamos modelar a relação linear entre as features ($X_{np} = [X_{1}, X_{2}, ..., X_{p}]$) através de uma reta dada pela equação:\n", + "\n", + "$$\\hat{y}= \\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p}$$\n", + "\n", + "Para classificação, a Regressão Logística vai nos retornar probabilidades (entre 0 e 1), dada pela equação logística ( também conhecida **função sigmoid**):\n", + "\n", + "$$P[y = 1]= \\frac{1}{1+e^{-(\\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p})}}$$\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vj83Altwdni7" + }, + "source": [ + "![SigmoidFunction](https://github.com/MathMachado/Materials/blob/master/SigmoidFunction.PNG?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LS1QjQnknqe5" + }, + "source": [ + "## Pressupostos da Regressão Logística\n", + "* Não há valores nulos no banco de dados;\n", + "* A variável-resposta $y$ é binária (0 ou 1) ou ordinal (variável categórica com valores ordenados (por exemplo, estimar a qualidade do vinho));\n", + "* Todas as variáveis preditoras $X$ são independentes;\n", + "* Há (pelo menos) 50 observações para cada variável preditora no modelo preditivo --> Quanto mais, melhor. Isso visa garantir a confiabilidade dos resultados);\n", + "* As classes da variável-resposta estejam equilibradas;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YGvpGTAd4jO" + }, + "source": [ + "# Exemplo 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-LBYRG__e_Zv" + }, + "source": [ + "### Carregar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XX2GNYWue-iA" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "import statsmodels.api as sm\n", + "import statsmodels.formula.api as smf\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.metrics import roc_auc_score, roc_curve, classification_report, accuracy_score, confusion_matrix, auc" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpNu-JjJfBYe" + }, + "source": [ + "### Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dWVj8SmUeBZB", + "outputId": "ddb92623-228d-4621-90f9-b80b1a0d06c9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n", + "df_titanic = pd.read_csv(url)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " PassengerId Survived Pclass ... Fare Cabin Embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 289 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9vZGvU5qbsQ", + "outputId": "6ad44206-7129-4e4e-a03d-cec7aeab3449", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic.columns = [coluna.lower() for coluna in df_titanic.columns]\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 290 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fAYAg5tofDgQ" + }, + "source": [ + "### Entendendo os dados\n", + "* sibsp - número of siblings/esposas abordo do Titanic;\n", + "* parch - número de parentes/crianças abordo do Titanic;\n", + "* embarked - Cidade/Portão de embarque: C = Cherbourg, Q = Queenstown, S = Southampton." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZbijPdpFxdZy" + }, + "source": [ + "#### A variável-target é do tipo binária ou categórica ordinal?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7hspb3IMe5tx", + "outputId": "684c59df-d788-400f-a179-0774a39e4303", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['survived'].value_counts()/df_titanic.shape[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 0.616162\n", + "1 0.383838\n", + "Name: survived, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tsp4t7oxx3zC" + }, + "source": [ + "A seguir, o gráfico da variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vm0BDjw-xrGI", + "outputId": "443def8e-dee6-40f5-8bcf-b33a43bb5c15", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 296 + } + }, + "source": [ + "sns.countplot(x = 'survived', data = df_titanic)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 292 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XfhFG6Axxj6F" + }, + "source": [ + "Como podemos ver, a variável-resposta 'survived' é binária. Portanto, tudo ok até agora." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zRKhDX6ZraGU" + }, + "source": [ + "### Tratamento dos Missing Values\n", + "* Substituir os NaN's por mediana da variável" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qPbILjZyrhRZ", + "outputId": "52f34626-1875-4632-cce3-8a694863ea6c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 293 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uJUPufRossTo" + }, + "source": [ + "Cálculo da mediana da variável/preditora 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WGW9bW5x4JdT", + "outputId": "c0ce5e66-70fe-4195-c637-2ac8a4cf9d37", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 294 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DgAwrR8msYv_" + }, + "source": [ + "mediana_age = df_titanic['age'].median()\n", + "mediana_fare = df_titanic['fare'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yqIgckarzwdB", + "outputId": "a190a691-e377-42ba-a8f8-98d430ccabbd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_age" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 297 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "czdSVeLjzxAX", + "outputId": "48bdfb0b-a153-482e-9fa6-6706bd44b88d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_fare" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14.4542" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 298 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4vcCshcsv6w" + }, + "source": [ + "Substituição dos NaN's da variável 'age' e 'fare' pela respetiva mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tnOOsaqLsg03", + "outputId": "81837607-f6b7-4bc2-e295-443679d3deb2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age'].fillna(mediana_age, inplace = True)\n", + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 299 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VqAnNxnO0Ghn" + }, + "source": [ + "Dado que fare não possui NaN's, então nada a fazer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Hi2zG_ms6n-" + }, + "source": [ + "#### Usando Imputer\n", + "* Método para tratamento de Missing Values." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvCnGfCOri9Y", + "outputId": "6d8b7f52-ca60-4bbd-bc50-9e55f3b9bd17", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'median')\n", + "imputer_mv.fit(df_titanic_copia[['age', 'fare']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 300 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SokJ8HM61FcK", + "outputId": "65052934-48c4-4c6d-b206-b14d8fa10dc3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "imputer_mv" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 301 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X-qx8QsQthyU", + "outputId": "469c2591-1ea2-4dfd-8395-df11821f5951", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "# transform()\n", + "df_titanic_mediana = pd.DataFrame(imputer_mv.transform(df_titanic[['age', 'fare']]), columns = ['age2', 'fare2'])\n", + "df_titanic_mediana.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age2fare2
022.07.2500
138.071.2833
226.07.9250
335.053.1000
435.08.0500
\n", + "
" + ], + "text/plain": [ + " age2 fare2\n", + "0 22.0 7.2500\n", + "1 38.0 71.2833\n", + "2 26.0 7.9250\n", + "3 35.0 53.1000\n", + "4 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 302 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KS-xYf5BuwEt", + "outputId": "c7e01602-c917-48b7-a7f1-33ce365f21ac", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_mediana.median()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "age2 28.0000\n", + "fare2 14.4542\n", + "dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 303 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lggbmAD2vN42", + "outputId": "55134b01-f993-4f01-b053-7600c45eec21", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_copia.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 304 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8fQ6a7RSvUOp", + "outputId": "75770554-a802-4012-a068-76b2e1ba1578", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic['age'] = df_titanic_mediana['age2']\n", + "\n", + "# Não há NaN's na variável fare. Portanto, nenhuma alteração\n", + "#df_titanic['fare'] = df_titanic_mediana['fare']\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 305 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HSncMlT51oM5", + "outputId": "85057833-9c05-4805-d2d0-ad6a3af0d140", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 306 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c48gJg0q4zgj" + }, + "source": [ + "Exclui as colunas que não são mais necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7OzK7DnDg2WY", + "outputId": "462a1c3e-d2b3-4d5d-b745-945706522481", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 307 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLpWbzz84ykm", + "outputId": "cdb706ed-5395-47d0-8f52-7887edcde8ee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 308 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NZei3VxSxR6g" + }, + "source": [ + "Alternativamente, poderíamos concatenar os dois dataframes usando pd.concat()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ek2qBdOFw2p5", + "outputId": "7777706c-55e4-4bfd-822f-cf3843922f3e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic = df_titanic_copia.copy()\n", + "\n", + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin', 'fare', 'age'], axis = 1, inplace = True)\n", + "df_titanic = pd.concat([df_titanic, df_titanic_mediana], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchembarkedage2fare2
003male10S22.07.2500
111female10C38.071.2833
213female00S26.07.9250
311female10S35.053.1000
403male00S35.08.0500
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch embarked age2 fare2\n", + "0 0 3 male 1 0 S 22.0 7.2500\n", + "1 1 1 female 1 0 C 38.0 71.2833\n", + "2 1 3 female 0 0 S 26.0 7.9250\n", + "3 1 1 female 1 0 S 35.0 53.1000\n", + "4 0 3 male 0 0 S 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6omsobg77tRv" + }, + "source": [ + "#### Tratamento dos NaN's da variável 'embarked'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YjeivMbz85gg" + }, + "source": [ + "A seguir, listamos as linhas em que embarked = NaN:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mc03_AnI8QgV", + "outputId": "ebe1ecc6-2c40-429d-d608-3b72ef10acd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
6111female38.00080.0NaN
82911female62.00080.0NaN
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "61 1 1 female 38.0 0 0 80.0 NaN\n", + "829 1 1 female 62.0 0 0 80.0 NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 309 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsbeFBFp7zRM", + "outputId": "58859c46-d711-4558-aadf-70480e67c98b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'most_frequent')\n", + "imputer_mv.fit(df_titanic[['embarked']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='most_frequent', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 310 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f2kDtHVN761L" + }, + "source": [ + "# transform()\n", + "df_embarked_freq = pd.DataFrame(imputer_mv.transform(df_titanic[['embarked']]), columns = ['embarked2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JmoLrzD8NwW", + "outputId": "d8ac60c0-a440-42b1-d7d5-c00168c3956f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic = pd.concat([df_titanic, df_embarked_freq], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
003male22.0107.2500SS
111female38.01071.2833CC
213female26.0007.9250SS
311female35.01053.1000SS
403male35.0008.0500SS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S S\n", + "1 1 1 female 38.0 1 0 71.2833 C C\n", + "2 1 3 female 26.0 0 0 7.9250 S S\n", + "3 1 1 female 35.0 1 0 53.1000 S S\n", + "4 0 3 male 35.0 0 0 8.0500 S S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 312 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FRxX9c4--TCg" + }, + "source": [ + "COMPARE o ANTES e o DEPOIS: Veja a seguir que os valores de [embarked] = NaN foram substituidos por..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oQFDqatz9bMv", + "outputId": "45d6ab98-b832-4844-8d66-6d47cbcee08e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
6111female38.00080.0NaNS
82911female62.00080.0NaNS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "61 1 1 female 38.0 0 0 80.0 NaN S\n", + "829 1 1 female 62.0 0 0 80.0 NaN S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 313 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jgCuXei2ZTQl" + }, + "source": [ + "Como podemos ver, os NaN's da variável embarked foram todos substituídos pelo valor 'S'. Tudo bem para vocês esta substituição?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r3r8ObKn-nBt" + }, + "source": [ + "df_titanic.drop(columns = ['embarked'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OacQvrYeAPBR" + }, + "source": [ + "Verificação final dos NaN's:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OHBv7CrjARol", + "outputId": "df1e556b-21dd-42a2-df08-4c0046f1f3b1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 0\n", + "pclass 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "fare 0\n", + "embarked2 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 315 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ITFMsiBSyAHY" + }, + "source": [ + "### O dataframe sob análise possui (pelo menos) 50 observações para cada preditora?\n", + "* Variáveis preditoras: pclass, sex, age, sibsp, parch, fare, embarked2 --> 7 variáveis preditoras.\n", + "* Portanto, nosso dataframe precisa de, no mínimo 7 x 50 = 350 linhas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4lgVp2N8yE1C", + "outputId": "2dbea822-609b-4576-c3e2-f89b3527db1c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.info()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 891 entries, 0 to 890\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 survived 891 non-null int64 \n", + " 1 pclass 891 non-null int64 \n", + " 2 sex 891 non-null object \n", + " 3 age 891 non-null float64\n", + " 4 sibsp 891 non-null int64 \n", + " 5 parch 891 non-null int64 \n", + " 6 fare 891 non-null float64\n", + " 7 embarked2 891 non-null object \n", + "dtypes: float64(2), int64(4), object(2)\n", + "memory usage: 55.8+ KB\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rFwtnAcw23gQ", + "outputId": "2b9b006b-3dee-493a-e9a6-adcf90923373", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "891/7" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "127.28571428571429" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 317 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wLqz2V7SytPU" + }, + "source": [ + "Pressuposto atendido?\n", + "Se sim, podemos prosseguir com as análises..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wm0VycfhovW8" + }, + "source": [ + "#### Avaliação do pressuposto de variáveis preditoras independentes\n", + "* Coeficiente de Spearman (desenvolvido por Charles Spearman). Também conhecido como Coeficiente de Correlação de Spearman e denotado pela letra greaga $\\rho(p)$.\n", + "* É um método estatístico para avaliar/medir a correlação entre 2 variáveis ordinais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "29knlUdcztb1", + "outputId": "adb2e1a5-2436-4327-8eff-4a65b66d4e0b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchfareage2ambarked2
003male107.250022.0S
111female1071.283338.0C
213female007.925026.0S
311female1053.100035.0S
403male008.050035.0S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch fare age2 ambarked2\n", + "0 0 3 male 1 0 7.2500 22.0 S\n", + "1 1 1 female 1 0 71.2833 38.0 C\n", + "2 1 3 female 0 0 7.9250 26.0 S\n", + "3 1 1 female 1 0 53.1000 35.0 S\n", + "4 0 3 male 0 0 8.0500 35.0 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 102 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J5EEcU7l0E2B" + }, + "source": [ + "A seguir, a hipótese de independência que queremos testar:\n", + "\n", + "$H_{0}$: variáveis são independentes --> Se o p-value < 5% --> Há evidências para rejeitar $H_{0}$." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tj8A_Kp0qxp_" + }, + "source": [ + "from scipy.stats import spearmanr" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kFxVGHPUpKLi" + }, + "source": [ + "coef, p = spearmanr(df_titanic['pclass'], df_titanic['age'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fvzvyvK7qzib", + "outputId": "d1e8d723-5048-4360-bad4-9ce0b8172bbf", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print('Coeficiente de Correlação de Spearman: %.3f' % coef)\n", + "\n", + "# Interpretação da significância:\n", + "alpha = 0.05\n", + "if p > alpha:\n", + "\tprint('Amostras NÃO correlacionadas (falha em rejeitar H0) p = %.3f' %p)\n", + "else:\n", + "\tprint('Amostras correlacionadas (Rejeita H0) p = %.3f' %p)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Coeficiente de Correlação de Spearman: -0.317\n", + "Amostras correlacionadas (Rejeita H0) p = 0.000\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yespibmf1WVh" + }, + "source": [ + "## Data Transformation\n", + "* MinMaxScaler e RobustScaler\n", + "* Binning (categorização de variáveis/preditoras numéricas): fare e age\n", + "* Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UwLpj8PXKFuL" + }, + "source": [ + "### Tratamento dos Outliers\n", + "* variáveis: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sTTgUx9oiWdJ", + "outputId": "fd14b9f5-7e25-4416-bfc7-e318e79d3249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 321 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-7v8WaB4aEKv" + }, + "source": [ + "from scipy import stats \n", + "\n", + "def trata_outliers(df, coluna):\n", + " sns.boxplot(x = coluna, data = df)\n", + "\n", + " # Cálculo de Q1, Q3 e IQR:\n", + " Q1 = np.percentile(df[coluna], 25)\n", + " Q3 = np.percentile(df[coluna], 75)\n", + " IQR = Q3 - Q1\n", + " print(f\"IQR: {IQR}\")\n", + "\n", + " # Jeito mais fácil (menos trabalhoso).\n", + " #IQR2 = stats.iqr(df[coluna]) \n", + " #IQR2 \n", + "\n", + " # Cálculo dos limites inferiores e superiores para detecção de outliers:\n", + " limite_inferior_outliers = Q1 - 1.5*IQR\n", + " limite_superior_outliers = Q3 + 1.5*IQR\n", + " print(f\"Limite inferior para outlier: {limite_inferior_outliers}; Limite superior para outliers: {limite_superior_outliers}\")\n", + "\n", + " # Cálculo da mediana\n", + " mediana = df[coluna].median()\n", + " print(f\"Mediana: {mediana}\")\n", + "\n", + " # Substituição dos outliers:\n", + " df[coluna+'_o'] = df[coluna]\n", + "\n", + " df.loc[df[coluna] > limite_superior_outliers, coluna+'_o'] = np.nan\n", + " df[coluna+'_o'].fillna(mediana, inplace = True) # 'o' significa tratamento outlier --> indicação para mostrar que a coluna passou pelo tratamento dos outliers.\n", + "\n", + " return df, limite_superior_outliers" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pwAExKTWaOSf", + "outputId": "089cba96-b805-4eef-d504-f8c81551c938", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'age')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 13.0\n", + "Limite inferior para outlier: 2.5; Limite superior para outliers: 54.5\n", + "Mediana: 28.0\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rB3Wh7jldcl-", + "outputId": "34e01f99-642a-45aa-ebd3-bda160d7be2e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 665 + } + }, + "source": [ + "df_titanic.head(20)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
503male28.0008.4583Q28.0
601male54.00051.8625S54.0
703male2.03121.0750S2.0
813female27.00211.1333S27.0
912female14.01030.0708C14.0
1013female4.01116.7000S4.0
1111female58.00026.5500S28.0
1203male20.0008.0500S20.0
1303male39.01531.2750S39.0
1403female14.0007.8542S14.0
1512female55.00016.0000S28.0
1603male2.04129.1250Q2.0
1712male28.00013.0000S28.0
1803female31.01018.0000S31.0
1913female28.0007.2250C28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0\n", + "5 0 3 male 28.0 0 0 8.4583 Q 28.0\n", + "6 0 1 male 54.0 0 0 51.8625 S 54.0\n", + "7 0 3 male 2.0 3 1 21.0750 S 2.0\n", + "8 1 3 female 27.0 0 2 11.1333 S 27.0\n", + "9 1 2 female 14.0 1 0 30.0708 C 14.0\n", + "10 1 3 female 4.0 1 1 16.7000 S 4.0\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "12 0 3 male 20.0 0 0 8.0500 S 20.0\n", + "13 0 3 male 39.0 1 5 31.2750 S 39.0\n", + "14 0 3 female 14.0 0 0 7.8542 S 14.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "16 0 3 male 2.0 4 1 29.1250 Q 2.0\n", + "17 1 2 male 28.0 0 0 13.0000 S 28.0\n", + "18 0 3 female 31.0 1 0 18.0000 S 31.0\n", + "19 1 3 female 28.0 0 0 7.2250 C 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 324 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x6YRvSf5SRR4" + }, + "source": [ + "### Quem são os outliers de 'age'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2y9BeUnoSU4W", + "outputId": "85968b30-7903-465b-eddf-27d4604acb58", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "age_outlier = df_titanic[df_titanic['age'] > limite_superior_outliers]\n", + "age_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
1111female58.00026.5500S28.0
1512female55.00016.0000S28.0
3302male66.00010.5000S28.0
5401male65.00161.9792C28.0
9403male59.0007.2500S28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "33 0 2 male 66.0 0 0 10.5000 S 28.0\n", + "54 0 1 male 65.0 0 1 61.9792 C 28.0\n", + "94 0 3 male 59.0 0 0 7.2500 S 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 327 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0dHnei1TBFc" + }, + "source": [ + "### Tratamento dos outliers da variável 'fare'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i8YM25uKm8g1", + "outputId": "00e04c37-82d8-4aca-c250-36a4a045df2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 328 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4Gnr9AEfTSj6", + "outputId": "40a23226-68bd-4288-dbf2-5fabfd4fd32b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'fare')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 23.0896\n", + "Limite inferior para outlier: -26.724; Limite superior para outliers: 65.6344\n", + "Mediana: 14.4542\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uh7f7nNATSkT" + }, + "source": [ + "### Quem são os outliers de 'fare'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdzaUaD0nQnv", + "outputId": "c05a1d46-c91a-4542-92a8-bfb121b44174", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "limite_superior_outliers" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "65.6344" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 330 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P3SAGnYnnQn4", + "outputId": "424347d6-d243-48df-8c3d-4c2a014c0cd9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "fare_outlier = df_titanic[df_titanic['fare'] > limite_superior_outliers]\n", + "fare_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_ofare_o
111female38.01071.2833C38.014.4542
2701male19.032263.0000S19.014.4542
3111female28.010146.5208C28.014.4542
3401male28.01082.1708C28.014.4542
5211female49.01076.7292C49.014.4542
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o fare_o\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 14.4542\n", + "27 0 1 male 19.0 ... 263.0000 S 19.0 14.4542\n", + "31 1 1 female 28.0 ... 146.5208 C 28.0 14.4542\n", + "34 0 1 male 28.0 ... 82.1708 C 28.0 14.4542\n", + "52 1 1 female 49.0 ... 76.7292 C 49.0 14.4542\n", + "\n", + "[5 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 331 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Jh83WTrZDeM_" + }, + "source": [ + "### Binning variáveis numéricas: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JVNVCd7aDjkz", + "outputId": "21f91b71-cfe5-445b-cf2c-8f4bf0de9825", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "#df_titanic_copia = df_titanic.copy()\n", + "df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 332 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pUspmjPWFP06" + }, + "source": [ + "#### Usando cut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NBVoCBe_2Zmp" + }, + "source": [ + "#df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90])\n", + "df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], labels = [10, 20, 30, 40, 50, 60, 70, 80, 90])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i1jombNDrEO", + "outputId": "7c96358b-3023-4706-813a-3e3e594cc45e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 264 + } + }, + "source": [ + "df_titanic.head(7)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_oage_bins
003male22.0107.2500S22.030
111female38.01071.2833C38.040
213female26.0007.9250S26.030
311female35.01053.1000S35.040
403male35.0008.0500S35.040
503male28.0008.4583Q28.030
601male54.00051.8625S54.060
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o age_bins\n", + "0 0 3 male 22.0 ... 7.2500 S 22.0 30\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 40\n", + "2 1 3 female 26.0 ... 7.9250 S 26.0 30\n", + "3 1 1 female 35.0 ... 53.1000 S 35.0 40\n", + "4 0 3 male 35.0 ... 8.0500 S 35.0 40\n", + "5 0 3 male 28.0 ... 8.4583 Q 28.0 30\n", + "6 0 1 male 54.0 ... 51.8625 S 54.0 60\n", + "\n", + "[7 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 340 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "davIt0UT9tTr" + }, + "source": [ + "#### **Desafio**: Qual seria o corte ótimo para 'age' usando DecisionTree?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5aAYl2ZDu1f", + "outputId": "0f1d7a99-6cb0-4484-b12b-7907b70feb8a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_cut1'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20, 30] 449\n", + "(30, 40] 155\n", + "(10, 20] 115\n", + "(40, 50] 86\n", + "(0, 10] 64\n", + "(50, 60] 22\n", + "(80, 90] 0\n", + "(70, 80] 0\n", + "(60, 70] 0\n", + "Name: age_bins_cut1, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 276 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VAUshOiLFT9-" + }, + "source": [ + "#### Usando qcut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RKnb-bI7FL3F", + "outputId": "59742803-dcee-4525-8fd1-2cecff379cab", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic['age_bins_qcut'] = pd.qcut(x = df_titanic['age'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 277 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "boSGroSYN7cP", + "outputId": "9304540f-1a20-41cb-c4a4-70633be1a071", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.dtypes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived int64\n", + "pclass int64\n", + "sex object\n", + "age float64\n", + "sibsp int64\n", + "parch int64\n", + "fare float64\n", + "embarked2 object\n", + "age_o float64\n", + "age_bins category\n", + "dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 344 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P8s3LzfpNdUz", + "outputId": "b0e4b638-32de-4295-984e-ba207e195661", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "l_colunas_numericas = list(df_titanic.select_dtypes('int').columns)\n", + "l_colunas_numericas\n", + "\n", + "for coluna in l_colunas_numericas:\n", + " trata_outliers(df, coluna)\n", + " trata_missing_values(df, coluna)\n", + " aplica_MMS(df, coluna)\n", + " aplica_RS(df, coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['survived', 'pclass', 'sibsp', 'parch']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 346 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ov2_l39mn3FH", + "outputId": "122869f8-018f-4176-b2df-c249efa222b7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_qcut'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20.0, 28.0] 360\n", + "(0.419, 20.0] 179\n", + "(38.0, 80.0] 177\n", + "(28.0, 38.0] 175\n", + "Name: age_bins_qcut, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 261 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J60XwHUOGwbr" + }, + "source": [ + "### MinMaxScaler() e RobustScaler()\n", + "* age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GRY84U4HHxoQ" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler, RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IQC7Bo-DH71s" + }, + "source": [ + "mms = MinMaxScaler()\n", + "rs = RobustScaler()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8O2oM9XdIYF5", + "outputId": "9812b76b-dffc-406b-fcd9-0a7c1b01a61b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B-qglHy6NZlg", + "outputId": "96a154a8-678e-48eb-93b2-ce93b7e0258f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 265 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dp9jYZ1OoA9i" + }, + "source": [ + "A seguir, deletar as variáveis que desnecessárias..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zSSViPY5XokW" + }, + "source": [ + "df_titanic.drop(columns = ['age', 'fare'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MNq5a0eUIBGV", + "outputId": "d692f608-f511-46e6-d101-bd9443647b94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 282 + } + }, + "source": [ + "# fit\n", + "df_titanic_mms = pd.DataFrame(mms.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_mms', 'fare_mms'])\n", + "df_titanic_rs = pd.DataFrame(rs.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_rs', 'fare_rs'])\n", + "\n", + "df_titanic['age_mms'] = df_titanic_mms['age_mms']\n", + "df_titanic['age_rs'] = df_titanic_rs['age_rs']\n", + "\n", + "df_titanic['fare_mms'] = df_titanic_mms['fare_mms']\n", + "df_titanic['fare_rs'] = df_titanic_rs['fare_rs']\n", + "\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rsage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.111538-0.443619(0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C38.014.4542(30, 40]40(28.0, 38.0]0.7013810.9090910.2223720.000000(0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.121923-0.402054(0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S35.053.1000(30, 40]40(28.0, 38.0]0.6453900.6363640.8169232.379726(0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S35.08.0500(30, 40]40(28.0, 38.0]0.6453900.6363640.123846-0.394357(0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 19 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 268 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UzrdPNO3rIg5", + "outputId": "aaa31937-081d-4af8-f3ec-07002886d2a6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 555 + } + }, + "source": [ + "# Categorizando as variáveis transformadas\n", + "df_titanic['age_bins_mms'] = pd.qcut(x = df_titanic['age_mms'], q = 5, duplicates = 'drop', labels = [1, 2, 3, 4])\n", + "df_titanic['age_bins_rs'] = pd.qcut(x = df_titanic['age_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "\n", + "df_titanic['fare_bins_mms'] = pd.qcut(x = df_titanic['fare_mms'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic['fare_bins_rs'] = pd.qcut(x = df_titanic['fare_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2894\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2895\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Categorizando as variáveis transformadas\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_rs'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_rs'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2901\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2902\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2903\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2904\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2895\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2897\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2898\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2899\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtolerance\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7smfXya5pmNq", + "outputId": "a942223f-e9b6-4758-c453-73c5c55f91bd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.drop(columns = ['age_o', 'fare_o', 'age_bins_cut2', 'age_mms', 'age_rs', 'fare_mms', 'fare_rs'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_bins_cut1age_bins_qcutage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C(30, 40](28.0, 38.0](0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 269 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SFPNLDMcU339" + }, + "source": [ + "### Variáveis Dummy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L_Fx1iy7snjF", + "outputId": "24c70d23-5a35-41aa-8a30-04fcc146b7c6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 279 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X6aHaJodX0Hi", + "outputId": "f7a26db1-81d3-47f5-dcd3-bbde2b2b6440", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 402 + } + }, + "source": [ + "dummy = pd.get_dummies(df_titanic[['sex', 'ambarked2']])\n", + "dummy" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
001001
110100
210001
310001
401001
..................
88601001
88710001
88810001
88901100
89001010
\n", + "

891 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " sex_female sex_male ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 1 0 0 1\n", + "1 1 0 1 0 0\n", + "2 1 0 0 0 1\n", + "3 1 0 0 0 1\n", + "4 0 1 0 0 1\n", + ".. ... ... ... ... ...\n", + "886 0 1 0 0 1\n", + "887 1 0 0 0 1\n", + "888 1 0 0 0 1\n", + "889 0 1 1 0 0\n", + "890 0 1 0 1 0\n", + "\n", + "[891 rows x 5 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 282 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZhLW0lEbs28E", + "outputId": "c772c290-4394-409a-ded7-1eb57b7ac0db", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 215 + } + }, + "source": [ + "df_titanic2 = pd.concat([df_titanic, dummy], axis = 1)\n", + "df_titanic2.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutsex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
003male22.0107.2500S22.07.2500(20, 30]30201001
111female38.01071.2833C38.014.4542(30, 40]40310100
213female26.0007.9250S26.07.9250(20, 30]30210001
311female35.01053.1000S35.053.1000(30, 40]40310001
403male35.0008.0500S35.08.0500(30, 40]40301001
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 3 male ... 0 0 1\n", + "1 1 1 female ... 1 0 0\n", + "2 1 3 female ... 0 0 1\n", + "3 1 1 female ... 0 0 1\n", + "4 0 3 male ... 0 0 1\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 283 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_bOYD4gWwGt", + "outputId": "b33c5076-6d0b-4c8f-8e5b-d87cb3e4544d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts() # Quem será a referência?" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 64 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xFKdsFDihApP" + }, + "source": [ + "df_titanic['pclass'] = df_titanic['pclass'].astype('category')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D_mWCqM1ZOgU" + }, + "source": [ + "### Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UPnCuCsLZSjQ", + "outputId": "95b92d55-a895-4c2e-9655-07a3bd753f6d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mX_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_teste\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_test_split\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'train_test_split' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rk-Zuh5RXJbp", + "outputId": "47c3c005-795d-406d-984a-b0094cd5718c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age3fare3age_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rs
00.03.0male1.00.0S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.014151-0.323505
11.01.0female1.00.0C38.071.2833(30, 40]40(36.0, 54.0]0.7013810.9090910.1391362.696934
21.03.0female0.00.0S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.015469-0.291665
31.01.0female1.00.0S35.053.1000(30, 40]40(28.0, 36.0]0.6453900.6363640.1036441.839231
40.03.0male0.00.0S35.08.0500(30, 40]40(28.0, 36.0]0.6453900.6363640.015713-0.285769
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp ... age_mms age_rs fare_mms fare_rs\n", + "0 0.0 3.0 male 1.0 ... 0.402762 -0.545455 0.014151 -0.323505\n", + "1 1.0 1.0 female 1.0 ... 0.701381 0.909091 0.139136 2.696934\n", + "2 1.0 3.0 female 0.0 ... 0.477417 -0.181818 0.015469 -0.291665\n", + "3 1.0 1.0 female 1.0 ... 0.645390 0.636364 0.103644 1.839231\n", + "4 0.0 3.0 male 0.0 ... 0.645390 0.636364 0.015713 -0.285769\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 69 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XtdQc49LXTfk", + "outputId": "696c23be-e9d0-4ba9-b4f5-0dcba0ffe8ec", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 74 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbvB30S5hRxH", + "outputId": "e872fe50-fcad-4b33-9456-182b1ca7e62c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "modelo = smf.glm(formula = 'survived ~ age3 + pclass + sex', data = df_titanic, family = sm.families.Binomial()).fit()\n", + "print(modelo.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " Generalized Linear Model Regression Results \n", + "==============================================================================\n", + "Dep. Variable: survived No. Observations: 849\n", + "Model: GLM Df Residuals: 844\n", + "Model Family: Binomial Df Model: 4\n", + "Link Function: logit Scale: 1.0000\n", + "Method: IRLS Log-Likelihood: -386.42\n", + "Date: Thu, 29 Oct 2020 Deviance: 772.85\n", + "Time: 17:17:09 Pearson chi2: 890.\n", + "No. Iterations: 5 \n", + "Covariance Type: nonrobust \n", + "=================================================================================\n", + " coef std err z P>|z| [0.025 0.975]\n", + "---------------------------------------------------------------------------------\n", + "Intercept 3.5515 0.382 9.297 0.000 2.803 4.300\n", + "pclass[T.2.0] -1.1389 0.264 -4.315 0.000 -1.656 -0.622\n", + "pclass[T.3.0] -2.3581 0.245 -9.613 0.000 -2.839 -1.877\n", + "sex[T.male] -2.5618 0.189 -13.522 0.000 -2.933 -2.191\n", + "age3 -0.0344 0.009 -4.035 0.000 -0.051 -0.018\n", + "=================================================================================\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p7_gfQXciFs1" + }, + "source": [ + "Qual a significância dos coeficientes (p-value abaixo de 0.05 adotando confiança de 95%)?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xtrh_bYNikTk" + }, + "source": [ + "### Interpretação dos coeficientes:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzlGDyeLgL11" + }, + "source": [ + "* Pessoas que viajavam na segunda classe possuem menos chances de sobrevivência do que quem viajava na primeira.\n", + "* Quem viajava na terceira classe possui menos chances ainda.\n", + "* Homens possuem menos chances de sobrevivência do que mulheres. Quanto mais velho, menores as chances de sobrevivência." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CJNgEYY9ioVM" + }, + "source": [ + "### Coeficientes mais interpretáveis - Chances relativas de Sobrevivência" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "q0vLh1v3irCz" + }, + "source": [ + "print(np.exp(modelo.params[1:]))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a2fJIOOzi3VF" + }, + "source": [ + "* Pessoas que viajavam na segunda classe tinham 0.27 das chances de sobrevivência que as pessoas da primeira classe tinham. \n", + "* Pessoas da terceira classe tinham 0.076 das chances que as pessoas da primeira classe tinham. \n", + "* Homens tinham 0.08 das chances das mulheres." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dYRkdqNujHFA" + }, + "source": [ + "### Comparando com a regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mKW-aODfjLbm" + }, + "source": [ + "(np.exp(modelo.params[1:]) - 1) * 100" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ODOqZpAgjQ2q" + }, + "source": [ + "* Pessoas da segunda classe tem 73% menos chances de sobrevivência do que pessoas da primeira classe.\n", + "* Pessoas da terceira classe tem 92% menos chances de sobrevivência que pessoas da primeira classe.\n", + "* Homens tem 92% menos chances de sobrevivência do que mulheres.\n", + "* Para cada ano a mais de idade, as chances diminuem 3.63%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fxnutoD7jp94" + }, + "source": [ + "### Qualidade do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-oW8Kg5Ij3Av", + "outputId": "d56cd7ce-e5c0-493d-ccfe-27cd5a6899c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 354 + } + }, + "source": [ + "modelo2 = LogisticRegression(penalty='none', solver='newton-cg')\n", + "df_titanic2 = df_titanic[['Survived', 'Pclass', 'Sex', 'Age']].dropna()\n", + "y = df_titanic2['Survived']\n", + "X = pd.get_dummies(df_titanic2[['Pclass', 'Sex', 'Age']], drop_first=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmodelo2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mLogisticRegression\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpenalty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'none'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'newton-cg'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdropna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mX\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_dummies\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdrop_first\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2906\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_iterator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2907\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2908\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_listlike_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2909\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2910\u001b[0m \u001b[0;31m# take() does not accept boolean indexers\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_get_listlike_indexer\u001b[0;34m(self, key, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1252\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew_indexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reindex_non_unique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1253\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1254\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_read_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mraise_missing\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1255\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_validate_read_indexer\u001b[0;34m(self, key, indexer, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1296\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmissing\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1297\u001b[0m \u001b[0maxis_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_axis_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1298\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"None of [{key}] are in the [{axis_name}]\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1299\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1300\u001b[0m \u001b[0;31m# We (temporarily) allow for some missing keys with .loc, except in\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: \"None of [Index(['Survived', 'Pclass', 'Sex', 'Age'], dtype='object')] are in the [columns]\"" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YK9nIiz_kQQl" + }, + "source": [ + "modelo2.fit(X, y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FPhHe4SmkZoE" + }, + "source": [ + "y_pred = modelo2.predict_proba(X)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dPrXU0GSknGJ" + }, + "source": [ + "confusion_matrix(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_-Wweiq7kruH" + }, + "source": [ + "acuracia = accuracy_score(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bqcT8XYJkuwH" + }, + "source": [ + "print(classification_report(y, model.predict(X)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4fSN-vLOjseh" + }, + "source": [ + "confusion_matrix(y, modelo.predict(X)) # usando a função do sklearn" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A0408gbPkywR" + }, + "source": [ + "def plot_roc_curve(y_true, y_score, figsize=(10,6)):\n", + " fpr, tpr, _ = roc_curve(y_true, y_score)\n", + " plt.figure(figsize=figsize)\n", + " auc_value = roc_auc_score(y_true, y_score)\n", + " plt.plot(fpr, tpr, color='orange', label='ROC curve (area = %0.2f)' % auc_value)\n", + " plt.plot([0, 1], [0, 1], color='darkblue', linestyle='--')\n", + " plt.xlabel('False Positive Rate')\n", + " plt.ylabel('True Positive Rate')\n", + " plt.title('Receiver Operating Characteristic (ROC) Curve')\n", + " plt.legend()\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5T4P90hQk1ug" + }, + "source": [ + "plot_roc_curve(y, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CANyMIgIjgSb" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pWJgVcQRlESq" + }, + "source": [ + "eu = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':1, 'Sex_male':1}, index=[0])\n", + "minha_prob = model.predict_proba(eu)\n", + "print('Eu teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(minha_prob[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kgpdgkgrlJ-w" + }, + "source": [ + "Eu teria 7.52% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "91GShU9ClMiY" + }, + "source": [ + "coleguinha = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':0, 'Sex_male':1}, index=[0])\n", + "prob_do_coleguinha = model.predict_proba(coleguinha)\n", + "print('Meu coleguinha teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(prob_do_coleguinha[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c2EHn8volOil" + }, + "source": [ + "Meu coleguinha teria 51.77% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C2PvJoZQlH6u" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwuMfMD1gFyd" + }, + "source": [ + "# Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kFY0TQVgOlvT" + }, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efF3st3sHxPG" + }, + "source": [ + "# Carrega as bibliotecas\n", + "import numpy as np\n", + "np.set_printoptions(formatter = {'float': lambda x: \"{0:0.2f}\".format(x)})\n", + "\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "import statsmodels.api as sm\n", + "\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bk9F6JO0IELv" + }, + "source": [ + "# Carregar/ler o banco de dados - Dataframe Diabetes\n", + "from sklearn import datasets\n", + "#Diabetes = datasets.load_diabetes()\n", + "\n", + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/diabetes.csv'\n", + "diabetes = pd.read_csv(url)\n", + "diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tjRmpaPIDknb" + }, + "source": [ + "# Definir as matrizes X e y\n", + "X_diabetes = diabetes.copy()\n", + "X_diabetes.drop(columns = ['Outcome'], axis = 1, inplace = True)\n", + "y_diabetes = diabetes['Outcome']\n", + "\n", + "X_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jLrx69TH-Mad" + }, + "source": [ + "X_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mdFBioP6-Ply" + }, + "source": [ + "y_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fhLySN65IaDF" + }, + "source": [ + "# Definir as matrizes de treinamento e validação\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_diabetes, y_diabetes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J5R8HlnuIGpL" + }, + "source": [ + "# Usando statmodels:\n", + "x = sm.add_constant(X_treinamento)\n", + "lr_sm = sm.Logit(y_treinamento, X_treinamento) # Atenção: aqui é o contrário: [y, x]\n", + "\n", + "# Treinar o modelo\n", + "lr.fit(X_treinamento, y_treinamento)\n", + "resultado_sm = lr_sm.fit()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GlbCaPp1ETNa" + }, + "source": [ + "resultado_sm.summary()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-FJaSnJLKICU" + }, + "source": [ + "# EQM - Erro Quadrático Médio\n", + "np.mean((resultado_sm.predict(X_teste) - y_teste) ** 2) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bVEUSTUPzOj" + }, + "source": [ + "### Calcular y_pred - os valores preditos de y" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OjGrNhTNLcr-" + }, + "source": [ + "y_pred = resultado_sm.predict(X_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfS5RCx_VnGT" + }, + "source": [ + "compara = list(zip(np.array(diabetes['Outcome']), resultado_sm.predict()))\n", + "compara[0:30]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUxasncIFaw4" + }, + "source": [ + "resultado_sm.pred_table()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_liLYinwFgch" + }, + "source": [ + "confusion_matrix = pd.DataFrame(resultado_sm.pred_table())\n", + "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n", + "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n", + "confusion_matrix" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ceH3MODWFm7S" + }, + "source": [ + "cm = np.array(confusion_matrix)\n", + "training_accuracy = (cm[0,0] + cm[1,1])/ cm.sum()\n", + "training_accuracy" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH_iEuzhO109" + }, + "source": [ + "# Exercício 1 - Mall_Customers.csv\n", + "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n", + "\n", + "* Experimente:\n", + " * Lasso(alpha = 0.01, max_iter = 10e5);\n", + " * Lasso(alpha = 0.0001, max_iter = 10e5);\n", + " * Ridge(alpha = 0.01);\n", + " * Ridge(alpha = 100);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZfRDEaaRYxFQ" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt \n", + "plt.rc(\"font\", size=14)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "import seaborn as sns\n", + "sns.set(style=\"white\")\n", + "sns.set(style=\"whitegrid\", color_codes=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nulrLzUqYxFY" + }, + "source": [ + "## Dados\n", + "\n", + "The data is related with direct marketing campaigns (phone calls) of a Portuguese banking institution. The classification goal is to predict if the client will subscribe (1/0) a term deposit (variable y)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LdrQCwxYxFY" + }, + "source": [ + "This dataset provides the customer information. It includes 41188 records and 21 fields." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qoT6zkoFYxFZ", + "outputId": "b04874af-bf4d-409f-cd1c-ad8c473004e6", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_bank = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/bank-full.csv', header = 0)\n", + "df_bank = df_bank.dropna()\n", + "print(df_bank.shape)\n", + "print(list(df_bank.columns))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(45211, 1)\n", + "['age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZD23hMCeYxFc", + "outputId": "f347c846-5f92-4e4f-b468-2bfbc608777c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_bank.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"
058;\"management\";\"married\";\"tertiary\";\"no\";2143...
144;\"technician\";\"single\";\"secondary\";\"no\";29;\"...
233;\"entrepreneur\";\"married\";\"secondary\";\"no\";2...
347;\"blue-collar\";\"married\";\"unknown\";\"no\";1506...
433;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n...
\n", + "
" + ], + "text/plain": [ + " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"\n", + "0 58;\"management\";\"married\";\"tertiary\";\"no\";2143... \n", + "1 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... \n", + "2 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... \n", + "3 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... \n", + "4 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... " + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 285 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CtGbim_EYxFh" + }, + "source": [ + "#### Input variables" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0pJ7ai5ZYxFh" + }, + "source": [ + "1 - age (numeric)\n", + "\n", + "2 - job : type of job (categorical: 'admin.','blue-collar','entrepreneur','housemaid','management','retired','self-employed','services','student','technician','unemployed','unknown')\n", + "\n", + "3 - marital : marital status (categorical: 'divorced','married','single','unknown'; note: 'divorced' means divorced or widowed)\n", + "\n", + "4 - education (categorical: 'basic.4y','basic.6y','basic.9y','high.school','illiterate','professional.course','university.degree','unknown')\n", + "\n", + "5 - default: has credit in default? (categorical: 'no','yes','unknown')\n", + "\n", + "6 - housing: has housing loan? (categorical: 'no','yes','unknown')\n", + "\n", + "7 - loan: has personal loan? (categorical: 'no','yes','unknown')\n", + "\n", + "8 - contact: contact communication type (categorical: 'cellular','telephone')\n", + "\n", + "9 - month: last contact month of year (categorical: 'jan', 'feb', 'mar', ..., 'nov', 'dec')\n", + "\n", + "10 - day_of_week: last contact day of the week (categorical: 'mon','tue','wed','thu','fri')\n", + "\n", + "11 - duration: last contact duration, in seconds (numeric). Important note: this attribute highly affects the output target (e.g., if duration=0 then y='no'). Yet, the duration is not known before a call is performed. Also, after the end of the call y is obviously known. Thus, this input should only be included for benchmark purposes and should be discarded if the intention is to have a realistic predictive model.\n", + "\n", + "12 - campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)\n", + "\n", + "13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)\n", + "\n", + "14 - previous: number of contacts performed before this campaign and for this client (numeric)\n", + "\n", + "15 - poutcome: outcome of the previous marketing campaign (categorical: 'failure','nonexistent','success')\n", + "\n", + "16 - emp.var.rate: employment variation rate - (numeric)\n", + "\n", + "17 - cons.price.idx: consumer price index - (numeric)\n", + "\n", + "18 - cons.conf.idx: consumer confidence index - (numeric) \n", + "\n", + "19 - euribor3m: euribor 3 month rate - (numeric)\n", + "\n", + "20 - nr.employed: number of employees - (numeric)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YwsaBV_OYxFi" + }, + "source": [ + "#### Predict variable (desired target):\n", + "\n", + "y - has the client subscribed a term deposit? (binary: '1','0')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2SsNWV_SYxFj" + }, + "source": [ + "The education column of the dataset has many categories and we need to reduce the categories for a better modelling. The education column has the following categories:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6TFbgh3vYxFk" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "luv7Bdf_YxFn" + }, + "source": [ + "Let us group \"basic.4y\", \"basic.9y\" and \"basic.6y\" together and call them \"basic\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gkOlUOs2YxFn" + }, + "source": [ + "df_bank['education']=np.where(df_bank['education'] =='basic.9y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.6y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.4y', 'Basic', df_bank['education'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-X1WMv2YxFq" + }, + "source": [ + "After grouping, this is the columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r9LlgpkjYxFq" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fcnJy3KYYxFt" + }, + "source": [ + "### Data exploration" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qUrTMR8BYxFt" + }, + "source": [ + "df_bank['y'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rpzHnzJKYxFx" + }, + "source": [ + "sns.countplot(x='y',data=df_bank, palette='hls')\n", + "plt.show()\n", + "plt.savefig('count_plot')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C99nOe3mYxF0" + }, + "source": [ + "There are 36548 no's and 4640 yes's in the outcome variables." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8nGaox_kYxF1" + }, + "source": [ + "Let's get a sense of the numbers across the two classes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sQvzA60bYxF1" + }, + "source": [ + "df_bank.groupby('y').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u3xjoceKYxF3" + }, + "source": [ + "Observations:\n", + "\n", + "The average age of customers who bought the term deposit is higher than that of the customers who didn't.\n", + "The pdays (days since the customer was last contacted) is understandably lower for the customers who bought it. The lower the pdays, the better the memory of the last call and hence the better chances of a sale.\n", + "Surprisingly, campaigns (number of contacts or calls made during the current campaign) are lower for customers who bought the term deposit." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jvzGMePPYxF4" + }, + "source": [ + "We can calculate categorical means for other categorical variables such as education and marital status to get a more detailed sense of our data." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RqLVMjoxYxF5" + }, + "source": [ + "df_bank.groupby('job').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GTUeRJAtYxF7" + }, + "source": [ + "df_bank.groupby('marital').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsxdFumiYxF9" + }, + "source": [ + "df_bank.groupby('education').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3i1DCWV-YxGA" + }, + "source": [ + "Visualizations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OEArHQPbYxGB" + }, + "source": [ + "%matplotlib inline\n", + "pd.crosstab(df_bank.job,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Job Title')\n", + "plt.xlabel('Job')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('purchase_fre_job')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNwo5du_YxGD" + }, + "source": [ + "The frequency of purchase of the deposit depends a great deal on the job title. Thus, the job title can be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eM7CWfAZYxGE" + }, + "source": [ + "table=pd.crosstab(df_bank.marital,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Marital Status vs Purchase')\n", + "plt.xlabel('Marital Status')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('mariral_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWBLh7toYxGG" + }, + "source": [ + "Hard to see, but the marital status does not seem a strong predictor for the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vh_u4QphYxGH" + }, + "source": [ + "table=pd.crosstab(df_bank.education,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Education vs Purchase')\n", + "plt.xlabel('Education')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('edu_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d9AgJroYYxGK" + }, + "source": [ + "Education seems a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dHI2LT-IYxGL" + }, + "source": [ + "pd.crosstab(df_bank.day_of_week,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Day of Week')\n", + "plt.xlabel('Day of Week')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_dayofweek_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3A2jmS4MYxGR" + }, + "source": [ + "Day of week may not be a good predictor of the outcome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bzafDBHpYxGS" + }, + "source": [ + "pd.crosstab(df_bank.month,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Month')\n", + "plt.xlabel('Month')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_month_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x5CBtquEYxGW" + }, + "source": [ + "Month might be a good predictor of the outcome variable" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tgF_3SqWYxGY" + }, + "source": [ + "df_bank.age.hist()\n", + "plt.title('Histogram of Age')\n", + "plt.xlabel('Age')\n", + "plt.ylabel('Frequency')\n", + "plt.savefig('hist_age')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y0FhKYDsYxGc" + }, + "source": [ + "The most of the customers of the bank in this dataset are in the age range of 30-40." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Nd3yV7DYxGd" + }, + "source": [ + "pd.crosstab(df_bank.poutcome,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Poutcome')\n", + "plt.xlabel('Poutcome')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_pout_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oRKUAGrjYxGh" + }, + "source": [ + "Poutcome seems to be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "63RLRI9uYxGi" + }, + "source": [ + "### Create dummy variables" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V8S4WUKmYxGj" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "for var in cat_vars:\n", + " cat_list='var'+'_'+var\n", + " cat_list = pd.get_dummies(df_bank[var], prefix=var)\n", + " df_bank1=df_bank.join(cat_list)\n", + " data=df_bank1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uX3w9i9WYxGl" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "df_bank_vars=df_bank.columns.values.tolist()\n", + "to_keep=[i for i in df_bank_vars if i not in cat_vars]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cMX_82xaYxGq" + }, + "source": [ + "df_bank_final=df_bank[to_keep]\n", + "df_bank_final.columns.values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LkTjpxYoYxGr" + }, + "source": [ + "df_bank_final_vars=df_bank_final.columns.values.tolist()\n", + "y=['y']\n", + "X=[i for i in df_bank_final_vars if i not in y]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2QbKaRcsYxGt" + }, + "source": [ + "### Feature Selection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EkxjW1AQYxGu" + }, + "source": [ + "from sklearn import datasets\n", + "from sklearn.feature_selection import RFE\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "logreg = LogisticRegression()\n", + "\n", + "rfe = RFE(logreg, 18)\n", + "rfe = rfe.fit(df_bank_final[X], df_bank_final[y] )\n", + "print(rfe.support_)\n", + "print(rfe.ranking_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2P9hd4jHYxGw" + }, + "source": [ + "The Recursive Feature Elimination (RFE) has helped us select the following features: \"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PW8WZX_YxGx" + }, + "source": [ + "cols=[\"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \n", + " \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \n", + " \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"] \n", + "X=df_bank_final[cols]\n", + "y=df_bank_final['y']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ix0mN9qxYxG0" + }, + "source": [ + "### Implementing the model" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hbx2bwtiYxG0" + }, + "source": [ + "import statsmodels.api as sm\n", + "logit_model=sm.Logit(y,X)\n", + "result=logit_model.fit()\n", + "print(result.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HR1ui-UcYxG2" + }, + "source": [ + "The p-values for most of the variables are very small, therefore, most of them are significant to the model." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9GHhrsaeYxG3" + }, + "source": [ + "### Logistic Regression Model Fitting" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFQnH5MzYxG3" + }, + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn import metrics\n", + "logreg = LogisticRegression()\n", + "logreg.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YUa3QL7tYxG6" + }, + "source": [ + "#### Predicting the test set results and caculating the accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SD-y2e33YxG6" + }, + "source": [ + "y_pred = logreg.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kkPWzos7YxG-" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwC3rt_6YxHA" + }, + "source": [ + "### Cross Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Muw50oqSYxHB" + }, + "source": [ + "from sklearn import model_selection\n", + "from sklearn.model_selection import cross_val_score\n", + "kfold = model_selection.KFold(n_splits=10, random_state=7)\n", + "modelCV = LogisticRegression()\n", + "scoring = 'accuracy'\n", + "results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)\n", + "print(\"10-fold cross validation average accuracy: %.3f\" % (results.mean()))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4y8XCTqoYxHE" + }, + "source": [ + "### Confusion Matrix" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BCza9NkVYxHE" + }, + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "confusion_matrix = confusion_matrix(y_test, y_pred)\n", + "print(confusion_matrix)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9SapwS2YxHG" + }, + "source": [ + "The result is telling us that we have 10872+254 correct predictions and 1122+109 incorrect predictions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bEWvWScYxHG" + }, + "source": [ + "#### Accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NaH2nESwYxHH" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(classifier.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C6oxlhbpYxHJ" + }, + "source": [ + "#### Compute precision, recall, F-measure and support\n", + "\n", + "The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.\n", + "\n", + "The recall is the ratio tp / (tp + fn) where tp is the number of true positives and fn the number of false negatives. The recall is intuitively the ability of the classifier to find all the positive samples.\n", + "\n", + "The F-beta score can be interpreted as a weighted harmonic mean of the precision and recall, where an F-beta score reaches its best value at 1 and worst score at 0.\n", + "\n", + "The F-beta score weights recall more than precision by a factor of beta. beta == 1.0 means recall and precision are equally important.\n", + "\n", + "The support is the number of occurrences of each class in y_test." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mhN5_p4yYxHK" + }, + "source": [ + "from sklearn.metrics import classification_report\n", + "print(classification_report(y_test, y_pred))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xzSFVEnAYxHP" + }, + "source": [ + "#### Interpretation: \n", + "\n", + "Of the entire test set, 88% of the promoted term deposit were the term deposit that the customers liked. Of the entire test set, 90% of the customer's preferred term deposit were promoted." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NGXJ6g2nYxHQ" + }, + "source": [ + "### ROC Curvefrom sklearn import metrics\n", + "from ggplot import *\n", + "\n", + "prob = clf1.predict_proba(X_test)[:,1]\n", + "fpr, sensitivity, _ = metrics.roc_curve(Y_test, prob)\n", + "\n", + "df = pd.DataFrame(dict(fpr=fpr, sensitivity=sensitivity))\n", + "ggplot(df, aes(x='fpr', y='sensitivity')) +\\\n", + " geom_line() +\\\n", + " geom_abline(linetype='dashed')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u9QKDuS0YxHQ" + }, + "source": [ + "from sklearn.metrics import roc_auc_score\n", + "from sklearn.metrics import roc_curve\n", + "logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))\n", + "fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])\n", + "plt.figure()\n", + "plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)\n", + "plt.plot([0, 1], [0, 1],'r--')\n", + "plt.xlim([0.0, 1.0])\n", + "plt.ylim([0.0, 1.05])\n", + "plt.xlabel('False Positive Rate')\n", + "plt.ylabel('True Positive Rate')\n", + "plt.title('Receiver operating characteristic')\n", + "plt.legend(loc=\"lower right\")\n", + "plt.savefig('Log_ROC')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git "a/Notebooks/NB15_02__Regress\303\243o Linear_hs4.ipynb" "b/Notebooks/NB15_02__Regress\303\243o Linear_hs4.ipynb" new file mode 100644 index 000000000..fc1c3f423 --- /dev/null +++ "b/Notebooks/NB15_02__Regress\303\243o Linear_hs4.ipynb" @@ -0,0 +1,10670 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "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.1" + }, + "colab": { + "name": "NB15_02__Regressão Linear.ipynb", + "provenance": [], + "include_colab_link": true + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwQDhId7N6_r" + }, + "source": [ + "

MACHINE LEARNING WITH PYTHON

\n", + "

APRENDIZAGEM SUPERVISIONADA

\n", + "

MODELOS DE REGRESSÃO (LINEAR E LOGÍSTICA)

\n", + "\n", + "Fonte: https://realpython.com/linear-regression-in-python/\n", + "https://towardsdatascience.com/predicting-the-survival-of-titanic-passengers-30870ccc7e8" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PN-dQFJcM1UV" + }, + "source": [ + "Passos para implementação da Regressão Linear:\n", + "\n", + "* (1) Importar as libraries necessárias;\n", + "* (2) Carregar os dados;\n", + "* (3) Aplicar as transformações necessárias: outliers, NaN's, normalização (MinMaxScaler, RobustScaler, StandarScaler, Log, Box-Cox e etc);\n", + "* (4) DataViz dos dados: entender os relacionamentos, distribuições e etc presente nos dados;\n", + "* (5) Construir e treinar o modelo preditivo (neste caso, modelo de regressão);\n", + "* (6) Validar/verificar as métricas para avaliação do(s) modelo(s);\n", + "* (7) Predições." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8TldGZxAFV5E" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0QRbxlqaq7pr" + }, + "source": [ + "# Melhorias da sessão:\n", + "* Calcular as correlações antes e depois da RIDGE e LASSO para mostrar a multicolinearidade e explicar porque determinadas colunas \"deixam\" de ser importantes." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P4sAIblOgFyL" + }, + "source": [ + "# Modelos de Regressão com Regularization para Classificação e Regressão" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7Y7cuJNgFyU" + }, + "source": [ + "## Regressão Linear Simples (usando OLS - Ordinary Least Squares)\n", + "\n", + "* Features $X_{np}$: é uma matriz de dimensão nxp contendo os atributos/variáveis preditoras do dataframe (variáveis independentes);\n", + "* Variável target/dependente representada por y;\n", + "* Relação entre X e y é representado pela equação abaixo, onde $w_{i}$ representa os pesos de cada coeficiente e $w_{0}$ representa o intercepto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NpJ580y9gFyU" + }, + "source": [ + "\n", + "\n", + "![X_y](https://github.com/MathMachado/Materials/blob/master/Architecture.png?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rhbVGJ0gFyY" + }, + "source": [ + "* Soma de Quadrados dos Resíduos (RSS) - Soma de Quadrados das diferenças entre os valores observados e preditos.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u8gA0YkbgFyp" + }, + "source": [ + "## Principais parâmetros do algoritmo:\n", + "* fit_intercept - Indica se o intercepto $w_{0}$ deve ou não ser ajustado. Se os dados estão normalizados, então não faz sentido ajustar o intercepto $w_{0}$.\n", + "\n", + "* normalize - $X$ será automaticamente normalizada (subtrai a média e divide pelo desvio-padrão);\n", + "\n", + "## Atributos do modelo de Machine Learning para Regressão\n", + "* coef - peso/fator de cada variável independente do modelo de ML;\n", + "\n", + "* intercepto $w_{0}$ - intercepto ou viés de $y$;\n", + "\n", + "## Funções para ajuste do ML:\n", + "* fit - treina o modelo com as matrizes $X$ e $y$;\n", + "* predict - Uma vez que o modelo foi treinado, para um dado $X$, use $y$ para calcular os valores preditos de $y$ (y_pred).\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A-JG8El1gFy7" + }, + "source": [ + "# Limitações do OLS (Ordinary Least Squares):\n", + "* Impactado/sensível à Outliers;\n", + "* Multicolinearidade; \n", + "* Heterocedasticidade - apresenta-se como uma forte dispersão dos dados em torno de uma reta;\n", + "\n", + "* References" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xylMYR8COyrw" + }, + "source": [ + "### Importar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2BGgrILlPK6Z" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import stats" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "263GgbwhO2kQ" + }, + "source": [ + "### Carregar os dados\n", + "* Vamos carregar o dataset [Boston House Pricing](https://archive.ics.uci.edu/ml/datasets/housing)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1h66x_-rXGhi" + }, + "source": [ + "from sklearn.datasets import load_boston, load_iris" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rWniNkMpXQFU", + "outputId": "5096d239-2c8c-4327-dbf5-f9128faa589c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "boston = load_boston()\n", + "boston" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'DESCR': \".. _boston_dataset:\\n\\nBoston house prices dataset\\n---------------------------\\n\\n**Data Set Characteristics:** \\n\\n :Number of Instances: 506 \\n\\n :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\\n\\n :Attribute Information (in order):\\n - CRIM per capita crime rate by town\\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\\n - INDUS proportion of non-retail business acres per town\\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\\n - NOX nitric oxides concentration (parts per 10 million)\\n - RM average number of rooms per dwelling\\n - AGE proportion of owner-occupied units built prior to 1940\\n - DIS weighted distances to five Boston employment centres\\n - RAD index of accessibility to radial highways\\n - TAX full-value property-tax rate per $10,000\\n - PTRATIO pupil-teacher ratio by town\\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\\n - LSTAT % lower status of the population\\n - MEDV Median value of owner-occupied homes in $1000's\\n\\n :Missing Attribute Values: None\\n\\n :Creator: Harrison, D. and Rubinfeld, D.L.\\n\\nThis is a copy of UCI ML housing dataset.\\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\\n\\n\\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\\n\\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\\nprices and the demand for clean air', J. Environ. Economics & Management,\\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\\n...', Wiley, 1980. N.B. Various transformations are used in the table on\\npages 244-261 of the latter.\\n\\nThe Boston house-price data has been used in many machine learning papers that address regression\\nproblems. \\n \\n.. topic:: References\\n\\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\\n\",\n", + " 'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,\n", + " 4.9800e+00],\n", + " [2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,\n", + " 9.1400e+00],\n", + " [2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,\n", + " 4.0300e+00],\n", + " ...,\n", + " [6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 5.6400e+00],\n", + " [1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,\n", + " 6.4800e+00],\n", + " [4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n", + " 7.8800e+00]]),\n", + " 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n", + " 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTAT
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... RAD TAX PTRATIO B LSTAT\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 136 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pQzFW7DUX_KW", + "outputId": "dcf288db-d99d-4d17-c22c-ceb8a9ba4841", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "# Variável target/resposta\n", + "df_boston['preco'] = load_boston().target\n", + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 137 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H71da4bIO4kI" + }, + "source": [ + "### Data Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K-6YOdsTfciO" + }, + "source": [ + "#### Normalização/padronização dos nomes das colunas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L8OJEapufhq4" + }, + "source": [ + "# Renomear as colunas do dataframe\n", + "df_boston.columns = [col.lower() for col in df_boston.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uRinX-5ofol_", + "outputId": "2e67bbbd-792f-4786-8c7e-2d0bd16fd249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.9824.0
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.1421.6
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.0334.7
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.9433.4
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.3336.2
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... tax ptratio b lstat preco\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n", + "\n", + "[5 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 139 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CMDh5jyqekmr" + }, + "source": [ + "#### Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJIG0jJQf6em" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgYPzlvfemFc" + }, + "source": [ + "#### Missing values" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BAjw7UhJen0D", + "outputId": "917a8f23-ec31-4f22-9a46-c3a15c1e4563", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Missing values por colunas/variáveis\n", + "df_boston.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "crim 0\n", + "zn 0\n", + "indus 0\n", + "chas 0\n", + "nox 0\n", + "rm 0\n", + "age 0\n", + "dis 0\n", + "rad 0\n", + "tax 0\n", + "ptratio 0\n", + "b 0\n", + "lstat 0\n", + "preco 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 140 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jo3UWNpbYnNF", + "outputId": "aeefc57a-f1b7-41ac-aa2e-53f828b9be14", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Número de atributos\n", + "len(load_boston().feature_names)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "13" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 141 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0Yp8g7hxfQli", + "outputId": "43795436-0366-4427-ed5a-2deacedf567f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49 + } + }, + "source": [ + "# Missing Values por linhas\n", + "df_boston[df_boston.isnull().any(axis = 1)]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat, preco]\n", + "Index: []" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 142 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5qmkTFLrf9MT" + }, + "source": [ + "#### Estatísticas Descritivas" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Nprn3p_Wf_bn", + "outputId": "16f46af6-ab9a-4d7b-a875-295817b9bf9c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 297 + } + }, + "source": [ + "df_boston.describe()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
count506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000506.000000
mean3.61352411.36363611.1367790.0691700.5546956.28463468.5749013.7950439.549407408.23715418.455534356.67403212.65306322.532806
std8.60154523.3224536.8603530.2539940.1158780.70261728.1488612.1057108.707259168.5371162.16494691.2948647.1410629.197104
min0.0063200.0000000.4600000.0000000.3850003.5610002.9000001.1296001.000000187.00000012.6000000.3200001.7300005.000000
25%0.0820450.0000005.1900000.0000000.4490005.88550045.0250002.1001754.000000279.00000017.400000375.3775006.95000017.025000
50%0.2565100.0000009.6900000.0000000.5380006.20850077.5000003.2074505.000000330.00000019.050000391.44000011.36000021.200000
75%3.67708312.50000018.1000000.0000000.6240006.62350094.0750005.18842524.000000666.00000020.200000396.22500016.95500025.000000
max88.976200100.00000027.7400001.0000000.8710008.780000100.00000012.12650024.000000711.00000022.000000396.90000037.97000050.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "count 506.000000 506.000000 506.000000 ... 506.000000 506.000000 506.000000\n", + "mean 3.613524 11.363636 11.136779 ... 356.674032 12.653063 22.532806\n", + "std 8.601545 23.322453 6.860353 ... 91.294864 7.141062 9.197104\n", + "min 0.006320 0.000000 0.460000 ... 0.320000 1.730000 5.000000\n", + "25% 0.082045 0.000000 5.190000 ... 375.377500 6.950000 17.025000\n", + "50% 0.256510 0.000000 9.690000 ... 391.440000 11.360000 21.200000\n", + "75% 3.677083 12.500000 18.100000 ... 396.225000 16.955000 25.000000\n", + "max 88.976200 100.000000 27.740000 ... 396.900000 37.970000 50.000000\n", + "\n", + "[8 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 143 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1JimyY3SgECE" + }, + "source": [ + "#### Análise de Correlação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jScHq7eTgIpm", + "outputId": "50696c9d-c19a-4937-9189-368be5fb291c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 483 + } + }, + "source": [ + "correlacoes = df_boston.corr()\n", + "correlacoes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstatpreco
crim1.000000-0.2004690.406583-0.0558920.420972-0.2192470.352734-0.3796700.6255050.5827640.289946-0.3850640.455621-0.388305
zn-0.2004691.000000-0.533828-0.042697-0.5166040.311991-0.5695370.664408-0.311948-0.314563-0.3916790.175520-0.4129950.360445
indus0.406583-0.5338281.0000000.0629380.763651-0.3916760.644779-0.7080270.5951290.7207600.383248-0.3569770.603800-0.483725
chas-0.055892-0.0426970.0629381.0000000.0912030.0912510.086518-0.099176-0.007368-0.035587-0.1215150.048788-0.0539290.175260
nox0.420972-0.5166040.7636510.0912031.000000-0.3021880.731470-0.7692300.6114410.6680230.188933-0.3800510.590879-0.427321
rm-0.2192470.311991-0.3916760.091251-0.3021881.000000-0.2402650.205246-0.209847-0.292048-0.3555010.128069-0.6138080.695360
age0.352734-0.5695370.6447790.0865180.731470-0.2402651.000000-0.7478810.4560220.5064560.261515-0.2735340.602339-0.376955
dis-0.3796700.664408-0.708027-0.099176-0.7692300.205246-0.7478811.000000-0.494588-0.534432-0.2324710.291512-0.4969960.249929
rad0.625505-0.3119480.595129-0.0073680.611441-0.2098470.456022-0.4945881.0000000.9102280.464741-0.4444130.488676-0.381626
tax0.582764-0.3145630.720760-0.0355870.668023-0.2920480.506456-0.5344320.9102281.0000000.460853-0.4418080.543993-0.468536
ptratio0.289946-0.3916790.383248-0.1215150.188933-0.3555010.261515-0.2324710.4647410.4608531.000000-0.1773830.374044-0.507787
b-0.3850640.175520-0.3569770.048788-0.3800510.128069-0.2735340.291512-0.444413-0.441808-0.1773831.000000-0.3660870.333461
lstat0.455621-0.4129950.603800-0.0539290.590879-0.6138080.602339-0.4969960.4886760.5439930.374044-0.3660871.000000-0.737663
preco-0.3883050.360445-0.4837250.175260-0.4273210.695360-0.3769550.249929-0.381626-0.468536-0.5077870.333461-0.7376631.000000
\n", + "
" + ], + "text/plain": [ + " crim zn indus ... b lstat preco\n", + "crim 1.000000 -0.200469 0.406583 ... -0.385064 0.455621 -0.388305\n", + "zn -0.200469 1.000000 -0.533828 ... 0.175520 -0.412995 0.360445\n", + "indus 0.406583 -0.533828 1.000000 ... -0.356977 0.603800 -0.483725\n", + "chas -0.055892 -0.042697 0.062938 ... 0.048788 -0.053929 0.175260\n", + "nox 0.420972 -0.516604 0.763651 ... -0.380051 0.590879 -0.427321\n", + "rm -0.219247 0.311991 -0.391676 ... 0.128069 -0.613808 0.695360\n", + "age 0.352734 -0.569537 0.644779 ... -0.273534 0.602339 -0.376955\n", + "dis -0.379670 0.664408 -0.708027 ... 0.291512 -0.496996 0.249929\n", + "rad 0.625505 -0.311948 0.595129 ... -0.444413 0.488676 -0.381626\n", + "tax 0.582764 -0.314563 0.720760 ... -0.441808 0.543993 -0.468536\n", + "ptratio 0.289946 -0.391679 0.383248 ... -0.177383 0.374044 -0.507787\n", + "b -0.385064 0.175520 -0.356977 ... 1.000000 -0.366087 0.333461\n", + "lstat 0.455621 -0.412995 0.603800 ... -0.366087 1.000000 -0.737663\n", + "preco -0.388305 0.360445 -0.483725 ... 0.333461 -0.737663 1.000000\n", + "\n", + "[14 rows x 14 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 144 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AxQp7xqdgTJP" + }, + "source": [ + "##### Gráfico das correlações entre as features/variáveis/colunas\n", + "Source: https://seaborn.pydata.org/examples/many_pairwise_correlations.html\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KOiH2X-WgqmN", + "outputId": "f72007dc-7c99-4ce1-b6bb-b86a9bf617c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 557 + } + }, + "source": [ + "import seaborn as sns\n", + "from string import ascii_letters\n", + "import matplotlib.pyplot as plt\n", + "\n", + "sns.set_theme(style = \"white\")\n", + "\n", + "d = df_boston\n", + "\n", + "# Compute the correlation matrix\n", + "corr = d.corr()\n", + "\n", + "# Generate a mask for the upper triangle\n", + "mask = np.triu(np.ones_like(corr, dtype=bool))\n", + "\n", + "# Set up the matplotlib figure\n", + "f, ax = plt.subplots(figsize=(11, 9))\n", + "\n", + "# Generate a custom diverging colormap\n", + "cmap = sns.diverging_palette(230, 20, as_cmap=True)\n", + "\n", + "# Draw the heatmap with the mask and correct aspect ratio\n", + "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n", + " square=True, linewidths=.5, cbar_kws={\"shrink\": .5})" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 145 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnUAAAILCAYAAACO32rlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzde1xUdeL/8TcDoQKi4qpp3mkltZJtS+pXZJKGkoZkqGXfbCm33cJ1vazXTYTt6y3TUtfdMjdNV1FTljAt26xs10vrpmkplCSGF7yRIigIw/n90c/5ieCFHDjwmdezxzyWc+bMOW9mhvbd53POjJdlWZYAAABQqznsDgAAAIDrR6kDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAAPYVup2796tUaNG2XV4AAAAo3hZlmVV90FLSkrk4+NT3YcFAAAwVpU0qx07dmjGjBkqKCiQJI0ZM0aTJk1SVFSUtm7dqg4dOig6OlrTp0/XmjVrdPDgQfXv318DBgzQZ599psLCQs2cOVPJycn68ssvVbduXc2fP19NmjSpirgAAAC1ntunX0+dOqX4+Hj94Q9/0LvvvquUlBTddtttkqT8/Hy98847mjJlSoWP++Uvf6l//OMfeuyxx/T0009r8ODBSktLU+fOnbV06VJ3RwUAADCG20vdzp07FRwcrDvuuEOS5O3trQYNGkiS+vXrd9nH+fn56YEHHpAkde7cWTfeeKM6duzoWv7+++/dHRUAAMAY1XqhhJ+f32Xv8/X1df3scDjKLHt7e8vpdFZpNgAAgNrM7aUuNDRUmZmZ2rFjhyTJ6XTq9OnT7j4MAAAALuL2CyUaNmyouXPnatq0aTp79qwcDofGjh3r7sMAAADgIrZ8pAkAAADci2+UAAAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMICP3QGqymdfZdodQZIUfmuw3REAAIAHYKQOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA/jYHeDTTz/VrFmzXMuZmZl69dVXNXfuXHXp0kU7duyQl5eXZs+ereDgYBuTAgAA1Fy2j9R169ZNqampSk1N1eDBg3XrrbfK19dX+/bt06BBg5SWlqbevXtr/vz5dkcFAACosWwvdRd89tlneuuttzR//nzVqVNH7dq1U6dOnSRJoaGhys7OtjkhAABAzWX79KskpaenKyEhQQsXLlRQUJAkydfX13W/w+FQSUmJXfEAAABqPNtH6o4ePaphw4bp5ZdfVrt27eyOAwAAUCvZPlK3atUq5ebmKikpybVu/PjxNiYCAACofbwsy7LsDlEVPvsq0+4IkqTwW7liFwAAVD3bp18BAABw/Sh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYwNjvfgUAAPAkjNQBAAAYwMfuAFXlwLpVdkeQJLWJitXYt9fbHUOSNP2p3nZHAAAAVYSROgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwADXVeqio6NVWFhY6cdFRETom2++uZ5DAwAA4CI+1/Pg1NRUd+UAAADAdbiuUhcSEqIvvvhC/v7+ioiIUHR0tDZv3qzjx48rLi5OTz75pCRp+/btSkxMlCTdddddsiyrwn1cvOxwODR27Fjt27dPPj4+ateunV577bXriQsAAGCs6yp1lyosLNSKFSt08OBB9e3bVzExMbrhhhs0YsQIzZw5U2FhYVq3bp3+/ve/X3Vf//rXv1RQUKB169ZJkk6fPu3OqAAAAEZx64USUVFRkqSWLVsqMDBQOTk5+u6771SvXj2FhYW5tqlfv/5V93XLLbcoMzNTiYmJWr9+vXx9fd0ZFQAAwChuLXV16tRx/ezt7S2n01nhdl5eXmW2uzAdW1RU5FrfqlUrrV27Vvfee6+2bNmi6OjoMvcDAADg/6vyjzRp3769CgsLtX37dknS+++/r7y8PNf9rVu31u7duyVJaWlprvU5OTny9vZWjx49NH78eOXm5urUqVNVHRcAAKBWcus5dRXx9fXVrFmzylwo0aJFC9f948eP16RJk1S/fn316tXLtT4jI0OvvPKKJKm0tFS//vWv1axZs6qOCwAAUCt5WRdfimqQA+tW2R1BktQmKlZj315vdwxJ0vSnetsdAQAAVBG+UQIAAMAAlDoAAAADUOoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxg7He/AgAAeBJG6gAAAAzgY3eAqnLw2Em7I0iSWjZtrCMnfrA7hiSp+c8a6dThbLtjSJIatmhldwQAAIzCSB0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGCAail1ERER+uabb6rjUAAAAB6JkToAAAAD+Lh7hzt27NCMGTNUUFAgSRozZowkaf369XrxxRd1/PhxxcXF6cknn5QkTZ8+XZ9//rmKi4vVqFEjTZkyRTfddJNOnjypUaNG6eTJk5Kke+65RxMmTHB3XAAAACO4tdSdOnVK8fHxmjt3ru644w45nU7l5+dLkgoLC7VixQodPHhQffv2VUxMjPz9/TV06FCNHTtWkrRq1SrNnDlTs2fPVlpamlq3bq1FixZJkk6fPu3OqAAAwAMdWLeqUtu3iYqtoiTu59ZSt3PnTgUHB+uOO+6QJHl7e6tBgwaSpKioKElSy5YtFRgYqJycHAUHB2vTpk1atmyZzp49q5KSEte+unTpokWLFmn69Onq2rWr7rvvPndGBQAAMEq1nVNXp04d18/e3t5yOp06dOiQpk6dqldeeUVr167VlClTdP78eUnSL37xC6WkpOjWW29VamqqnnrqqeqKCgAAUOu4tdSFhoYqMzNTO3bskCQ5nc4rTpvm5+frhhtuUJMmTVRaWqrk5GTXfdnZ2QoICNDDDz+s8ePH6+uvv1Zpaak74wIAAE/j5ajcrRZx6/Rrw4YNNXfuXE2bNk1nz56Vw+FwnS9XkZCQEPXq1UtRUVFq1KiRunXrpu3bt0uSPv/8cy1atEgOh0OlpaVKTEyUw1G7nlwAAFCzeHl52R2hynhZlmXZHaIqHDx20u4IkqSWTRvryIkf7I4hSWr+s0Y6dTjb7hiSpIYtWtkdAQDggb5/f02ltm/d69EqSuJ+bv9IEwAAgBrL4Fk/Sh0AAPAYJk+/mltXAQAAPAgjdQAAwHM4vO1OUGUodQAAwGN4OZh+BQAAQA3GSB0AAPActewDhSuDUgcAADwHV78CAACgJmOkDgAAeAwvpl8BAAAMYPD0q7GlrmXTxnZHcGn+s0Z2R3DhO1cBADCTsaUOAADgUiZ/Tp2xpe7AulV2R5AktYmK1YSlH9gdQ5I05cnIGvW85O7fZ3cMSVJQu5vtjgAAqC5VeE7d/v37NW7cOJ06dUoNGzbU9OnT1bZt2zLb/PnPf9a6devkcDh0ww03aMSIEQoPD3fL8Y0tdQAAAOVU4Tl1CQkJeuKJJxQdHa3U1FRNmjRJb7/9dpltbr/9dsXFxalevXpKT0/Xk08+qX/961+qW7fudR/f3EtAAAAAqsnJkye1Z88e9enTR5LUp08f7dmzR7m5uWW2Cw8PV7169SRJISEhsixLp06dcksGRuoAAIDHqOxHmuTl5SkvL6/c+sDAQAUGBrqWjxw5ombNmsnb21uS5O3traZNm+rIkSMKCgqqcN//+Mc/1Lp1a914442VynQ5lDoAAOA5KnmhxOLFizVv3rxy6+Pj4zVs2LCfHOPzzz/Xa6+9pr/97W8/eR+XotQBAABcxpAhQxQTE1Nu/cWjdJLUvHlzHT16VE6nU97e3nI6nTp27JiaN29e7rE7duzQH/7wB82fP1/t27d3W1ZKHQAA8ByVnH69dJr1cho3bqyOHTtq7dq1io6O1tq1a9WxY8dyU6+7du3SiBEjNGfOHHXu3LlSWa6GCyUAAIDH8PLyqtStMiZPnqylS5cqMjJSS5cuVWJioiRp6NCh2r17tyQpMTFRhYWFmjRpkqKjoxUdHa2MjAy3/G6M1AEAALhBcHCwVq0q/3mwCxYscP28evXqKjs+pQ4AAHiOKvzwYbtR6gAAgMeo7JRqbUKpAwAAnoPvfgUAADAA068AAAC1n8nTr9VSV0NCQvTXv/5V/fv314MPPqgPPvjAdd+mTZvUr18/9e3bV0OGDNGBAwdUWlqquLg4LV68WJK0b98+de/eXTk5OdURFwAAoNaptjHIgIAArV69WjNmzNBLL70k6ccvvx0zZoxmzpyptLQ09enTR6NHj5bD4dDLL7+sxYsXa/v27RoxYoQSEhLc9t1oAADAQ3k5KnerRaotbVRUlCQpNDRUx44dU1FRkb788kvdcsstuvnmmyVJ/fv31969e5Wfn6/GjRtrypQpGjJkiO6991498MAD1RUVAACYyuFVuVstUm2lrk6dOpIkb29vSVJJSclVH7N37141atSIaVcAAICrsHVcMTQ0VOnp6crMzJQkpaSkqFOnTgoICNCuXbu0dOlSpaamKjc3V8uXL7czKgAAMICXl6NSt9rE1qtfg4KCNGPGDI0ePVolJSUKCgrSyy+/rLy8PI0aNUrTpk1T48aNNXPmTA0cOFChoaHq2LGjnZEBAEBtZvDVr9VS6i79otqLl++//37df//95R7z4Ycfun5u2rSpPv7446oLCAAAUMvxOXUAAMBjmPw5dZQ6AADgOWrZeXKVQakDAACeo5Z9TEllmFtXAQAAPAgjdQAAwGPUto8pqQxKHQAA8BwGXyhhbl0FAADwIIzUAQAAz8H0KwAAQO1n8ufUmVtXAQAAPAgjdQAAwHM4zB3PotQBAACPYfL0q5dlWZbdIQAAAKrDD9lZldq+Uau2VZKjKjBSBwAAPAdXv9Y+H+/61u4IkqTut/9cB9atsjuGJKlNVKzmr99idwxJ0vO971Hu/n12x5AkBbW7We/8+0u7Y0iSHru3i90RAMBoXnz3KwAAAGoyY0fqAAAAymH6FQAAwAAGX/1qbl0FAADwIIzUAQAAj+HF9CsAAIABDJ5+pdQBAACPwUeaAAAAoEZjpA4AAHgOzqkDAAAwgMHn1JlbVwEAAKrR/v37NXDgQEVGRmrgwIHKysoqt43T6VRiYqJ69Oihnj17atUq932VKKUOAAB4DC8vR6VulZGQkKAnnnhCH3zwgZ544glNmjSp3DZpaWn6/vvvtWHDBq1YsUJz587VwYMH3fK71YhSV1JSYncEAADgCRxelbtdo5MnT2rPnj3q06ePJKlPnz7as2ePcnNzy2y3bt06xcbGyuFwKCgoSD169ND777/vll/NtnPqQkJCFB8fr08++UTh4eHKycmRr6+vsrKylJ2drZ49e6p79+6aO3eucnJyNGTIEA0ZMsSuuAAAwAPl5eUpLy+v3PrAwEAFBga6lo8cOaJmzZrJ29tbkuTt7a2mTZvqyJEjCgoKKrNdixYtXMvNmzdXTk6OW7LaeqFEnTp1tHr1aknSuHHj9O2332rx4sVyOp2KiIjQmTNntHTpUh0/fly9evXSY489Jn9/fzsjAwCA2qySU6qLFy/WvHnzyq2Pj4/XsGHD3JXKLWwtdTExMWWWe/ToIV9fX0lSu3bt1K1bNzkcDjVr1kyBgYHKyclRcHCwHVEBAIABrEpe/TpkyJByfUVSmVE66ccRt6NHj8rpdMrb21tOp1PHjh1T8+bNy213+PBh3X777ZLKj9xdD1vPqfPz8yuzXKdOHdfP3t7e5ZadTme1ZQMAAOZxllbuFhgYqJYtW5a7XVrqGjdurI4dO2rt2rWSpLVr16pjx45lpl4lqVevXlq1apVKS0uVm5urf/7zn4qMjHTL71YjLpQAAACo7SZPnqylS5cqMjJSS5cuVWJioiRp6NCh2r17tyQpOjpaLVu21EMPPaQBAwbohRdeUKtWrdxyfD58GAAAeIxSy6qyfQcHB1f4uXMLFixw/ezt7e0qe+5mW6nLyMgoszxt2rQyy0uWLCmzvHHjxirPBAAAUFsxUgcAADxGVY7U2Y1SBwAAPIZlcKnjQgkAAAADMFIHAAA8BtOvAAAABjC40zH9CgAAYAJG6gAAgMcw+UIJSh0AAPAYnFMHAABgAIM7HefUAQAAmICROgAA4DE4pw4AAMAAJp9T52WZXFkBAAAuknXkeKW2b9u8SRUlcT9jR+oOrFtldwRJUpuoWA178127Y0iS5j77SI16XnIPfGd3DElSUJv2Nep52fBFut0xJEkP3XGL3REAwO1MHskyttQBAABcyuTpV65+BQAAMAAjdQAAwGOYfCkBpQ4AAHgMgzsdpQ4AAHgOzqkDAABAjcZIHQAA8BilpYzUAQAAoAZjpA4AAHgMk8+po9QBAACPYfJHmjD9CgAAYABG6gAAgMcw+DoJSh0AAPAclsxtdZQ6AADgMUw+p65aSt2oUaO0f/9+FRcXq3Xr1poyZYoaNGig2bNna926dWrYsKG6du2qLVu2aM2aNZKklJQULVu2TE6nUwEBAZo8ebLat29fHXEBAABqnWopdRMnTlRQUJAkafbs2VqwYIHuuOMOffzxx0pNTVXdunX1u9/9zrX99u3btX79ev3973+Xr6+vPv30U02YMEHJycnVERcAABiKc+quU2pqqtLS0lRcXKyzZ8+qbdu2Ki4uVu/eveXn5ydJ6tevn+bPny9J2rhxo9LT0xUbGyvpx6HSvLy86ogKAAAMxvTrddi+fbuWL1+u5ORkBQUFKS0tTStXrrziYyzLUv/+/TV8+PCqjgcAAGCEKv+cury8PAUEBKhhw4Y6f/68Vq9eLUnq2rWrPvjgA507d06lpaV69913XY+JiIhQamqqcnJyJElOp1NfffVVVUcFAACGsyyrUrfapMpH6sLDw/Xuu+8qMjJSjRo10p133qndu3frwQcf1I4dO/TII4+oQYMGCg0N1enTpyVJd911l37/+9/rt7/9rZxOp4qLi9WrVy/deuutVR0XAAAYjK8Juw433HCDXn311Qrv+81vfqPRo0ertLRUEydOVGhoqOu+Rx55RI888khVxwMAADCCrZ9TN3bsWB06dEiFhYXq3Lmzhg4damccAABgOIMH6uwtdX/+85/tPDwAAPAwdk2/njt3TuPHj9fXX38tb29vjR07Vt27dy+33T//+U/Nnz9f58+fd104GhcXd03H4BslAACAx7Dr4oeFCxcqICBAH374obKysjR48GBt2LBB/v7+ZbZr0qSJ/vKXv6hZs2Y6c+aMHn30Ud1+++268847r3qMKr/6FQAAwNOtX79eAwcOlCS1bdtWt956qzZt2lRuuy5duqhZs2aSpPr16ys4OFiHDh26pmMwUgcAADxGZQfq8vLyKvwChMDAQAUGBl7zfg4fPqybbrrJtdy8eXPXR7ddTmZmpnbu3KnExMRrOgalDgAAeIzKnlO3ePFizZs3r9z6+Ph4DRs2zLUcExOjw4cPV7iPzZs3Vy6kpGPHjun5559XQkKCa+Tuaih1AADAY1iqXKkbMmSIYmJiyq2/dJQuJSXlivtp0aKFDh06pKCgIEnSkSNHFBYWVuG2J0+e1K9+9Ss9++yz6t279zVnpdQBAACPUdnp18pOs15Or169tGLFCt12223KysrS7t279corr5Tb7ocfftCvfvUrDR48WLGxsZU6BhdKAAAAVLFnnnlGeXl56tmzp5577jklJSUpICBAkvTaa69p+fLlkqQ33nhDWVlZWrFihaKjoxUdHe36itWrYaQOAAB4DLs+p87Pz09z5syp8L7hw4e7fh47dqzGjh37k45BqQMAAB7Drs+pqw5MvwIAABjAyzK5sgIAAFzknzu/qdT2PUI7VFES9zN2+vWND7bZHUGS9OvIMB1Yt8ruGJKkNlGx6jt1id0xJElp4/9H3x48ancMSdLPWzZT94SFdseQJH2c+IyObP3U7hiSpOZ3d1PPpLfsjiFJ+nDSr+yO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KlaSFPmnt2xOIn3w4q/sjoBqwPQrAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAAaq81JWUlFT1IQAAADyez099YEhIiF544QV99NFHKiws1MiRIxUZGem6Lz4+Xp988onCw8P17LPPaurUqcrIyFBRUZHCwsI0fvx4eXt76+jRo3rppZeUlZUlSerTp4+ee+45nThxQgkJCfr+++8lSc8884z69et3/b8xAACAgX5yqZMkh8Oh1NRUfffdd3r88cd15513qnHjxpKkOnXqaPXq1ZKkiRMn6q677tL//u//qrS0VKNHj9bq1as1YMAAjR49Wt26ddPcuXMlSbm5uZKkl156ST//+c/15z//WceOHdOjjz6qTp06qUOHDtcTGQAAwEjXVepiY2MlSe3bt1enTp20c+dOPfjgg5KkmJgY13YbN27Url279NZbb0mSCgsL1axZMxUUFGjHjh2u9ZIUFBQkSdqyZYvGjRsnSWratKm6deumbdu2UeoAAAAqcF2l7kr8/PxcP1uWpfnz56tVq1ZltikoKKiqwwMAAHiU67pQ4sL0alZWlvbs2aPQ0NAKt4uIiNAbb7whp9Mp6ccp1uzsbPn7++sXv/iFFi1a5Nr2wvTrPffco5UrV0qSjh8/rk8//VR333339cQFAAAw1nWVOqfTqX79+um5555TUlKS63y6S02YMEEOh0PR0dHq27evnn32WR09elSSNHPmTH3xxRfq06ePHnnkEb3zzjuSpD/+8Y9KT09X3759FRcXp9GjR+vnP//59cQFAAAw1nVNv8bFxWnYsGHl1mdkZJRZDggIUGJiYoX7aNasmebPn19u/c9+9rMK1wMAAKA8PnwYAADAAD95pO7S0TgAAADYh5E6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAM4GVZlmV3CAAAAFwfRuoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqavA7t27NWrUKLtjVLno6GgVFhZW+nERERH65ptvqiBRzTomzBASEqKCgoKf/H63w7hx47R06VK37W/u3Lk6f/682/ZXncc/ePCgVqxYUWbd0KFD9f3337sjWjkX3i9V7WrHycvL04IFC655f3a/xqgZKHWXKCkp0W233aZXXnnF7ihVLjU1VXXr1rU7BtygpKTE7gg1np3vd7tfn3nz5qm4uLhGHv9qz82hQ4fKlboFCxaodevWbstXE+Xl5enNN9+85u2r6jW2+72LyvGxO0B127Fjh2bMmOH6L6QxY8Zo0qRJioqK0tatW9WhQwdFR0dr+vTpWrNmjQ4ePKj+/ftrwIAB+uyzz1RYWKiZM2cqOTlZX375perWrav58+erSZMmbsn36aefatasWa7lzMxMvfrqq5o7d666dOmiHTt2yMvLS7Nnz1ZwcPB1HSskJERffPGF/P39FRERoejoaG3evFnHjx9XXFycnnzySUnS9u3blZiYKEm66667dPHXBV+8j4uXHQ6Hxo4dq3379snHx0ft2rXTa6+9dk25KnqNJGn9+vV68cUXy+WbPn26Pv/8cxUXF6tRo0aaMmWKbrrpJp08eVKjRo3SyZMnJUn33HOPJkyY8JOfqxEjRujDDz/UqVOnNGbMGEVGRkqSNm3apFmzZsnpdCooKEhJSUlq1aqVnn32WXXr1k1DhgzRvn37NHToUC1fvlw33njjT8pQUab4+Hh98sknCg8PV05Ojnx9fZWVlaXs7Gz17NlT3bt319y5c5WTk6MhQ4ZoyJAhbjn2BaNGjdL+/ftVXFys1q1ba8qUKWrQoIFmz56tdevWqWHDhuratau2bNmiNWvWSJJSUlK0bNkyOZ1OBQQEaPLkyWrfvr3bMm3YsEGzZs1SnTp19NBDD7nWX3hv1qtXT0lJSdq6dat8fX3l5+en5ORktx3/4uNd/Pr07t1biYmJOnfunIqKijRgwAA9/fTTkqSjR49qzJgxOn78uG666SY5HO777+0Lf7uDBg2Sw+HQs88+q7fffttVAMaOHat77rlHJ0+eVGxsrF577TXddtttSklJ0cqVK7VkyRL5+Fz9/ypCQkL0wgsv6KOPPlJhYaFGjhypyMjIcsdfsmSJpkyZIm9vb+3fv18FBQVKTU297HspKSlJBw8eVHR0tNq0aaM5c+YoIiJCf/3rX9WhQwcdOHBAkyZNUm5urnx8fDRixAjdf//91/WcLVy4sNzvUVVKS0srfD8mJSXpzJkzio6OVr169ZScnKy//e1veu+99+R0OlWnTh1NnjxZHTt2rPA5DgwMvOJxL/d6Xbjv4vfus88+q6lTpyojI0NFRUUKCwvT+PHj5e3traNHj+qll15SVlaWJKlPnz567rnndOLECSUkJLhGVJ955hn169evyp5H/D+WB/nhhx+s//N//o/13//+17IsyyopKbFOnTplde/e3UpISHBtt3XrVismJsayLMvKzs62OnToYH388ceWZVnWggULrF/+8pfWnj17LMuyrISEBGvWrFlVknfFihXWwIEDrU8//dTq1KmT9fXXX1uWZVnz58+3Ro4ced3779Chg5Wfn29ZlmV1797dmjZtmmVZP/7OoaGhVn5+vlVUVGTdd9991tatWy3Lsqz33nvP6tChg5WRkVFuHxcvb9iwwYqLi3OtP3Xq1DVlutJrVFE+y7KskydPuh6/cuVK6/e//71lWZb11ltvWS+++GKlM1SkQ4cO1pIlSyzLsqzt27db9913n2VZlnXixAkrLCzM+vbbb13Hf+yxx1z3de/e3frPf/5j9enTx/UecpcOHTpYr7/+umt57Nix1qBBg6yioiLr7Nmz1t13322NGzfOcjqdVk5OTpnnzF0ufu5nzZplvfzyy9ZHH31k9e3b1yooKLCcTqf1wgsvuP6e/vOf/1hDhw61ioqKLMuyrE8++cQaOHCg2/IcP37c6tq1q5WZmWlZlmW98cYbrvfkhf/9+uuvrV69ellOp9OyrOt7X1zJpa/PmTNnXL93fn6+1bt3b2vfvn2WZVlWfHy8NXfuXMuyLOv777+3QkNDXe83d2W58Nrn5uZapaWllmVZVmZmphUeHu7abuvWrdZDDz1k7dixw3rggQesw4cPV+oYF36HzMxMq2vXrtaJEyfKHd+yfnyvxsTEWAUFBa51Fb2XLmS68P65oHv37q5/Bz322GPWypUrLcuyrG+//dbq2rVrmX1V1pV+D3e62vsxOzvb6tq1a5nHXPx7/fvf/7ZiY2PL7a8yx7/S63Xxe3fChAlWSkqKZVmW5XQ6rREjRlgrVqywLMuynnzySWvBggXlMg4fPtyaPXu2ZVmWdfToUevee+91vWaoOh41Urdz504FBwfrjjvukCR5e3urQYMGknTF/4Lw8/PTAw88IEnq3LmzbrzxRnXs2NG1vHnzZrdn/eyzz/TWW2/p73//u7799lu1a9dOnTp1kiSFhobq448/dvsxo6KiJEktW7ZUYGCgcnJyVFxcrHr16iksLMy1zaRJk666r1tuuUWZmZlKTExU165dXc/f1VzpNaooX3BwsDZt2qRly5bp7NmzZaYKunTpokWLFmn69Onq2rWr7rvvvmt+Lipy4fihoaE6duyYioqK9OWXX+qWW27RzTffLEnq37+/EhMTlZ+fr8aNG2vKlCkaMmSI/ud//uean4PKiImJKbPco0cP+fr6SpLatWunbt26yeFwqFmzZmWeM3dJTU1VWlqaiouLdfbsWbVt21bFxcXq3bu3/Pz8JP34tzV//nxJ0saNG5Wenq7Y2FhJkmVZysvLc1ueL7/8Up06dXKN/A0cOFAzZ84ss02rVq1UUlKiiRMnKiwsTN27d3fb8S918etTWFioyZMnKyMjQ15eXjp27JjS09MVHBysbdu26Y9//KMr3z333FNlmbKzszVq1CgdPXpUPj4+OnHihI4fP64mTZooLCxMffr00RNPPKF58+apefPmldr3hde1ffv26tSpk3bu3KkHH3ywwm179erleo9IFb+XriY/P1979+5V//79JUk333yzOnbsqJ07dyoiIqJS2X/q73G9KvN+/Oqrr/T666/r9OnT8vLyco2O/VRX+j0vfu9u3LhRu3bt0ltvvSXpx/dys2bNVFBQoB07drjWS1JQUJAkacuWLRo3bpwkqWnTpurWrZu2bdumDh06XFdmXJlHlborufhfLpe68H+SkuRwOMose3t7y+l0ujVLenq6EhIStHDhQtcfyKUZquI8hzp16rh+vtLv5eXlVWY76/9NxxYVFbnWt2rVSmvXrtXWrVu1adMmzZ49W2lpaWWO4Y58hw4d0tSpU/XOO++oVatW+uKLLzR69GhJ0i9+8QulpKRo8+bNSk1N1RtvvKHly5df9/G9vb0lXdu5Jnv37lWjRo2Uk5Pzk497JZe+by99jq71Nf0ptm/fruXLlys5OVlBQUFKS0vTypUrr/gYy7LUv39/DR8+3G05Kqt+/fp67733tG3bNm3evFkzZ85USkqK206huNjFr8+sWbPUpEkTTZs2TT4+PoqLiyvzN1NdRo4cqXHjxqlHjx4qLS1Vly5dyuTYs2ePgoKCquw9e8HFz81PeS+Z4nLvx0udP39ew4cP19KlS9W5c2cdPXr0uqeZr+Ti18eyLM2fP1+tWrUqs011XFCCyvGoCyVCQ0OVmZmpHTt2SJKcTqdOnz5tc6qyjh49qmHDhunll19Wu3bt7I6j9u3bq7CwUNu3b5ckvf/++2VGVlq3bq3du3dLktLS0lzrc3Jy5O3trR49emj8+PHKzc3VqVOnrnq8yr5G+fn5uuGGG9SkSROVlpaWOTcqOztbAQEBevjhhzV+/Hh9/fXXKi0trdwTcA1509PTlZmZKenH88U6deqkgIAA7dq1S0uXLlVqaqpyc3Ovq1DWRHl5eQoICFDDhg11/vx5rV69WpLUtWtXffDBBzp37pxKS0v17rvvuh4TERGh1NRUV2FwOp366quv3JYpNDRUe/bscY1grFq1qtw2ubm5OnfunMLDwzV69GjVr19f2dnZbstwOWfOnNGNN94oHx8fffPNN66/KUm6++67Xc9fdna2tmzZ4tZj+/v7Kz8/35WjZcuWkqTVq1eXuWJy0aJFKikp0Zo1a/Tmm29q7969lTrOhd8hKytLe/bsUWhoaLnjV+Ry7yVJCggIuOxjAwIC1LFjx//bvv27tK6GcQD/WlQKRpK2oCA6VBAHHSpYcKmCDgZJ1UFwcxAs1kEslkpaDbRdSlscdHMqCiKYSfwHXF0EXXRwEnEQOoho0TTnDmK4Pd5e9Vw9nhu/nzEheX/kDXnyvu9jBUHn5+c4PT21yv1V1drxGaqNR0EQUCqVrJ/Hh4cHGIZhzZ5ub29X3Oe1Pv4nb23n4OAgNjY2rJ/CYrGIi4sLNDQ0oKenB4VCoaI9wNMe5ufA/Pr6GgcHB+jr63tX/ej9vtVMnSRJWF9fRyaTwd3dnbWZ/0+yu7uLYrGIVCplHVNV9cvqU19fj9XV1YpEiZaWFuu8qqrQNA2NjY2QZdk6fnZ2ZmUQm6aJUCiE5ubmV8t77zPq7OyELMsYGRmBy+XCwMCA9bE8PDxEoVCAw+GAaZpIJpMfugEdeFpqyGaziEajMAwDbrcbuVwONzc3WFxcRCaTgcfjQT6fx+TkJHw+n7V0/38XCASwt7eH4eFhuFwu9Pb24uTkBENDQzg6OsLo6ChEUYTP57MCc7/fj4WFBYTDYZTLZTw+PkKWZXR3d39InTweD9LpNGZnZ+F0OisSJZ5dXV1hZWUFhmGgXC6jv7//Uz/az8LhMGKxGHRdh9frhd/vt84lEgnEYjHs7++jtbXV2u7wUaanpzE1NQWn0wlVVTE3NwdRFBEIBCBJEgDg+PgYm5ub0HUdbrcb6XQakUgEuq5DEIQ3lVMulzE+Po77+3ukUil4PJ4X5W9tbb24rtpYAp7eca/XC0VR0N7ejrW1tYpr8/k8NE1DoVBAbW0tstmstcLxq6q14zNUG48OhwPBYBDBYBCiKGJnZwfz8/OYmJiAJEkvkjd+7uPXEiWAt7czHo8jl8thbGwMNTU1qKurQzweR1tbG/L5PJLJJBRFgcPhgKIoCIVCWF5ehqZpCAaDAIBoNIqOjo7/3mH0r2p+/PhbKiMR0Qe4vb2FIAgwTROJRAJNTU2IRCJfXS36RD9nwtOfjc/Lnr7VTB0R/R5LS0u4vLxEqVRCV1cXZmZmvrpKRES2x5k6IiIiIhv4VokSRERERHbFoI6IiIjIBhjUEREREdkAgzoiIiIiG2BQR0RERGQDDOqIiIiIbOAvF2TfJBn+6VQAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nogPhyfVO70G" + }, + "source": [ + "### Construir e treinar o(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HxYpfyvQaIe1" + }, + "source": [ + "$X = [X_{1}, X_{2}, X_{p}]$ = X_boston abaixo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0BhLZJhibVNG" + }, + "source": [ + "X_boston = df_boston.drop(columns = ['preco'], axis = 1) # todas as variáveis/atributos, exceto 'preco'\n", + "y_boston = df_boston['preco'] # variável-target" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v_nC_RGva1Z6", + "outputId": "6a5946c8-62b3-424f-a809-9a2bbc34f191", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "X_boston.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
crimzninduschasnoxrmagedisradtaxptratioblstat
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33
\n", + "
" + ], + "text/plain": [ + " crim zn indus chas nox ... rad tax ptratio b lstat\n", + "0 0.00632 18.0 2.31 0.0 0.538 ... 1.0 296.0 15.3 396.90 4.98\n", + "1 0.02731 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 396.90 9.14\n", + "2 0.02729 0.0 7.07 0.0 0.469 ... 2.0 242.0 17.8 392.83 4.03\n", + "3 0.03237 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 394.63 2.94\n", + "4 0.06905 0.0 2.18 0.0 0.458 ... 3.0 222.0 18.7 396.90 5.33\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 147 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nlVJM--Ya5fS", + "outputId": "58037983-175f-47ed-ad47-5826589358b0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_boston[0:10] # Series (coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 24.0\n", + "1 21.6\n", + "2 34.7\n", + "3 33.4\n", + "4 36.2\n", + "5 28.7\n", + "6 22.9\n", + "7 27.1\n", + "8 16.5\n", + "9 18.9\n", + "Name: preco, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 148 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b50_6tv5h1kY" + }, + "source": [ + "# Definindo os dataframes de treinamento e teste:\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, \n", + " y_boston, \n", + " test_size = 0.2, \n", + " random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U3hpdkDbYTv", + "outputId": "35e8cee1-201a-4a65-a6ec-8fa9e8c7c0a8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(f\"Dataframe de treinamento: {X_treinamento.shape[0]} linhas\")\n", + "print(f\"Dataframe de teste......: {X_teste.shape[0]} linhas\")" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Dataframe de treinamento: 404 linhas\n", + "Dataframe de teste......: 102 linhas\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SvevXulFiJj1" + }, + "source": [ + "#### Treinamento do modelo de Regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GVwF3vp8iNff" + }, + "source": [ + "# Importa a library LinearRegression --> Para treinamento da Regressão Linear\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Library para statmodels\n", + "import statsmodels.api as sm" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ibX6bCbViW-v" + }, + "source": [ + "# Instancia o objeto\n", + "regressao_linear = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M-5wRGUribY0", + "outputId": "a67d7355-3d9e-43fc-edf6-8ebd71911935", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Treina o modelo usando as amostras/dataset de treinamento: X_treinamento e y_treinamento \n", + "regressao_linear.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 153 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jri-jA1VjmUl", + "outputId": "3150261d-c264-4273-9c5f-95229529881b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# Valor do intercepto\n", + "regressao_linear.intercept_" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "35.9020918753502" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 154 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VOjadxdxjqtT", + "outputId": "49d06bd9-e375-403f-e257-863967f10fd3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 452 + } + }, + "source": [ + "# Coeficientes do modelo de Regressão Linear\n", + "coeficientes_regressao_linear = pd.DataFrame([X_treinamento.columns, regressao_linear.coef_]).T\n", + "coeficientes_regressao_linear = coeficientes_regressao_linear.rename(columns={0: 'Feature/variável/coluna', 1: 'Coeficientes'})\n", + "coeficientes_regressao_linear" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
Feature/variável/colunaCoeficientes
0crim-0.0822083
1zn0.0428002
2indus0.0756011
3chas3.16348
4nox-19.4945
5rm3.98161
6age0.00480929
7dis-1.37396
8rad0.298883
9tax-0.0123962
10ptratio-0.984657
11b0.008949
12lstat-0.526478
\n", + "
" + ], + "text/plain": [ + " Feature/variável/coluna Coeficientes\n", + "0 crim -0.0822083\n", + "1 zn 0.0428002\n", + "2 indus 0.0756011\n", + "3 chas 3.16348\n", + "4 nox -19.4945\n", + "5 rm 3.98161\n", + "6 age 0.00480929\n", + "7 dis -1.37396\n", + "8 rad 0.298883\n", + "9 tax -0.0123962\n", + "10 ptratio -0.984657\n", + "11 b 0.008949\n", + "12 lstat -0.526478" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 155 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jwnkhPwDjkhS" + }, + "source": [ + "#### Usando statmodels" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ltbekHd_k3PH", + "outputId": "a69b057e-75a6-446e-8b7c-ad37604114a5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2_treinamento = sm.add_constant(X_treinamento)\n", + "lm_sm = sm.OLS(y_treinamento, X2_treinamento).fit()\n", + "print(lm_sm.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 78.97\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.48e-100\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2458.\n", + "Df Residuals: 390 BIC: 2514.\n", + "Df Model: 13 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.9021 6.037 5.947 0.000 24.033 47.771\n", + "crim -0.0822 0.045 -1.824 0.069 -0.171 0.006\n", + "zn 0.0428 0.016 2.638 0.009 0.011 0.075\n", + "indus 0.0756 0.072 1.054 0.292 -0.065 0.217\n", + "chas 3.1635 0.997 3.174 0.002 1.204 5.123\n", + "nox -19.4945 4.539 -4.295 0.000 -28.418 -10.571\n", + "rm 3.9816 0.510 7.802 0.000 2.978 4.985\n", + "age 0.0048 0.015 0.312 0.755 -0.025 0.035\n", + "dis -1.3740 0.236 -5.827 0.000 -1.838 -0.910\n", + "rad 0.2989 0.079 3.760 0.000 0.143 0.455\n", + "tax -0.0124 0.004 -2.814 0.005 -0.021 -0.004\n", + "ptratio -0.9847 0.156 -6.309 0.000 -1.292 -0.678\n", + "b 0.0089 0.003 2.796 0.005 0.003 0.015\n", + "lstat -0.5265 0.060 -8.764 0.000 -0.645 -0.408\n", + "==============================================================================\n", + "Omnibus: 140.799 Durbin-Watson: 2.083\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 591.650\n", + "Skew: 1.484 Prob(JB): 3.35e-129\n", + "Kurtosis: 8.132 Cond. No. 1.51e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.51e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kpt3A4Q0guHv" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVUJkfg4gSh7", + "outputId": "eeff1e8f-8ac7-44e8-e0fe-caf0d4a641c7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X3 = X_treinamento.drop(columns = 'age', axis = 1)\n", + "X3_treinamento = sm.add_constant(X3)\n", + "lm_sm2 = sm.OLS(y_treinamento, X3_treinamento).fit()\n", + "print(lm_sm2.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.725\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 85.75\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.64e-101\n", + "Time: 11:00:14 Log-Likelihood: -1214.8\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 391 BIC: 2508.\n", + "Df Model: 12 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.7325 6.006 5.950 0.000 23.925 47.540\n", + "crim -0.0815 0.045 -1.812 0.071 -0.170 0.007\n", + "zn 0.0422 0.016 2.623 0.009 0.011 0.074\n", + "indus 0.0750 0.072 1.048 0.295 -0.066 0.216\n", + "chas 3.1794 0.994 3.198 0.001 1.225 5.134\n", + "nox -19.1299 4.381 -4.367 0.000 -27.742 -10.517\n", + "rm 4.0153 0.498 8.059 0.000 3.036 4.995\n", + "dis -1.3963 0.224 -6.223 0.000 -1.837 -0.955\n", + "rad 0.2958 0.079 3.755 0.000 0.141 0.451\n", + "tax -0.0123 0.004 -2.802 0.005 -0.021 -0.004\n", + "ptratio -0.9812 0.156 -6.310 0.000 -1.287 -0.675\n", + "b 0.0090 0.003 2.825 0.005 0.003 0.015\n", + "lstat -0.5202 0.057 -9.203 0.000 -0.631 -0.409\n", + "==============================================================================\n", + "Omnibus: 142.363 Durbin-Watson: 2.081\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 608.694\n", + "Skew: 1.496 Prob(JB): 6.67e-133\n", + "Kurtosis: 8.216 Cond. No. 1.48e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.48e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lcp7m5FmZvG" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'indus'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jEiBywx4hGNB", + "outputId": "fb2abfd1-9019-4e37-f6e1-cf5e54ae1276", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X4 = X3_treinamento.drop(columns = 'indus', axis = 1)\n", + "X4_treinamento = sm.add_constant(X4)\n", + "lm_sm3 = sm.OLS(y_treinamento, X4_treinamento).fit()\n", + "print(lm_sm3.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.724\n", + "Model: OLS Adj. R-squared: 0.716\n", + "Method: Least Squares F-statistic: 93.42\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 2.86e-102\n", + "Time: 11:00:14 Log-Likelihood: -1215.4\n", + "No. Observations: 404 AIC: 2455.\n", + "Df Residuals: 392 BIC: 2503.\n", + "Df Model: 11 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 35.4757 6.001 5.911 0.000 23.677 47.275\n", + "crim -0.0840 0.045 -1.871 0.062 -0.172 0.004\n", + "zn 0.0407 0.016 2.539 0.012 0.009 0.072\n", + "chas 3.2924 0.989 3.330 0.001 1.349 5.236\n", + "nox -17.9558 4.235 -4.239 0.000 -26.283 -9.629\n", + "rm 3.9674 0.496 7.996 0.000 2.992 4.943\n", + "dis -1.4553 0.217 -6.699 0.000 -1.882 -1.028\n", + "rad 0.2744 0.076 3.606 0.000 0.125 0.424\n", + "tax -0.0103 0.004 -2.603 0.010 -0.018 -0.003\n", + "ptratio -0.9609 0.154 -6.227 0.000 -1.264 -0.658\n", + "b 0.0089 0.003 2.778 0.006 0.003 0.015\n", + "lstat -0.5151 0.056 -9.145 0.000 -0.626 -0.404\n", + "==============================================================================\n", + "Omnibus: 142.123 Durbin-Watson: 2.073\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 605.868\n", + "Skew: 1.494 Prob(JB): 2.74e-132\n", + "Kurtosis: 8.202 Cond. No. 1.47e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.47e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rFejox5XmrEE" + }, + "source": [ + "#### Exclusão da variável menos significativa para o modelo: 'crim'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DOehOql8hZWr", + "outputId": "cbb71827-f44e-4688-93c4-98a3ec5e3257", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X5 = X4_treinamento.drop(columns = 'crim', axis = 1)\n", + "X5_treinamento = sm.add_constant(X5)\n", + "lm_sm4 = sm.OLS(y_treinamento, X5_treinamento).fit()\n", + "print(lm_sm4.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " OLS Regression Results \n", + "==============================================================================\n", + "Dep. Variable: preco R-squared: 0.721\n", + "Model: OLS Adj. R-squared: 0.714\n", + "Method: Least Squares F-statistic: 101.8\n", + "Date: Thu, 29 Oct 2020 Prob (F-statistic): 1.55e-102\n", + "Time: 11:00:14 Log-Likelihood: -1217.2\n", + "No. Observations: 404 AIC: 2456.\n", + "Df Residuals: 393 BIC: 2500.\n", + "Df Model: 10 \n", + "Covariance Type: nonrobust \n", + "==============================================================================\n", + " coef std err t P>|t| [0.025 0.975]\n", + "------------------------------------------------------------------------------\n", + "const 33.9950 5.968 5.696 0.000 22.262 45.728\n", + "zn 0.0375 0.016 2.349 0.019 0.006 0.069\n", + "chas 3.3959 0.990 3.430 0.001 1.449 5.343\n", + "nox -17.1637 4.228 -4.060 0.000 -25.475 -8.852\n", + "rm 4.0365 0.496 8.132 0.000 3.061 5.012\n", + "dis -1.3999 0.216 -6.484 0.000 -1.824 -0.975\n", + "rad 0.2278 0.072 3.158 0.002 0.086 0.370\n", + "tax -0.0100 0.004 -2.513 0.012 -0.018 -0.002\n", + "ptratio -0.9493 0.155 -6.137 0.000 -1.253 -0.645\n", + "b 0.0101 0.003 3.217 0.001 0.004 0.016\n", + "lstat -0.5315 0.056 -9.523 0.000 -0.641 -0.422\n", + "==============================================================================\n", + "Omnibus: 140.245 Durbin-Watson: 2.070\n", + "Prob(Omnibus): 0.000 Jarque-Bera (JB): 609.563\n", + "Skew: 1.464 Prob(JB): 4.32e-133\n", + "Kurtosis: 8.257 Cond. No. 1.46e+04\n", + "==============================================================================\n", + "\n", + "Warnings:\n", + "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", + "[2] The condition number is large, 1.46e+04. This might indicate that there are\n", + "strong multicollinearity or other numerical problems.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UafIUrpZB0YP" + }, + "source": [ + "### Conclusão\n", + "* Quais variáveis/colunas/atributos ficam no modelo?\n", + "* **Muito importante (exercício)**: normalizar (MinMaxScaler) as covariáveis e refazer a análise.\n", + "* Nesta iteração (depois de excluirmos (nesta ordem) as variáveis age, indus e crim, não surge nenhuma outra variável insignificante ao nível de 5 (na verdade, o maior valor é 1.9%)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jx7sOzrrm-H_" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXeiFtnJO_1u" + }, + "source": [ + "### Validação do(s) modelo(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QlGVFA6uPDvr" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PE3aKJ6mPDyJ" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d3nGiyX8jadH" + }, + "source": [ + "### Deployment da solução **analítica**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YQF4NIlGSLH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UQfpoo1igFy8" + }, + "source": [ + "# Regularized Regression Methods \n", + "## Ridge Regression - Penalized Regression\n", + "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando (valor de $\\alpha$) os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n", + "* Menor impacto dos outliers.\n", + "\n", + "### Exemplo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o00xH2MvxvgP" + }, + "source": [ + "# Matriz de covariáveis do modelo:\n", + "X_new = [[0, 0], [0, 0], [1, 1]]\n", + "X_new2 = [[0, 0], [0, 1.5], [1, 1]]\n", + "\n", + "y_new = [0, .1, 1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v9U7c03NzW_c", + "outputId": "2652bd10-e6b4-4200-f7f0-a07806564a1d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_new # 2 variáveis/colunas no dataframe" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[[0, 0], [0, 0], [1, 1]]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 161 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iiVEAPpUzXyN", + "outputId": "a69fe575-57da-459c-f482-41d3185ab76f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_new" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 0.1, 1]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 162 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDljolA95Hw5" + }, + "source": [ + "### Sem outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8mWj2GbPOkHx", + "outputId": "3b433090-a588-449a-af69-5f2da53a9b60", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 197 + } + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new, y_new)\n", + "ridge.coef_ # Coeficientes da Ridge" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mridge\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mRidge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0malpha\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_new\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_new\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mridge\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoef_\u001b[0m \u001b[0;31m# Coeficientes da Ridge\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'Ridge' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8yvd4ABY5JjC" + }, + "source": [ + "### Com outliers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O3sJZ_pe5GQ7" + }, + "source": [ + "ridge = Ridge(alpha = .1)\n", + "ridge.fit(X_new2, y_new)\n", + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zZxdCLU_5kKh" + }, + "source": [ + "#### Conseguiram visualizar o impacto dos outliers?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u5jsTkUmS9wK" + }, + "source": [ + "### Aplicação da Regressão Ridge no dataframe Boston Housing Price." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kp4VIJWxgFy8" + }, + "source": [ + "from sklearn.linear_model import Ridge\n", + "ridge = Ridge(alpha = 0.1) # Definição do valor de alpha da regressão ridge\n", + "lr = LinearRegression()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cmRMoOwV6FMt" + }, + "source": [ + "# Ao inves de: regressao_linear.fit(X_treinamento, y_treinamento)\n", + "ridge.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VPnekyUbK6Xg" + }, + "source": [ + "#### Peso/contribuição das variáveis para a regressão usando RIDGE" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k83RDArjsUrj" + }, + "source": [ + "df_boston.columns" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vMCb0CFjK973" + }, + "source": [ + "ridge.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZqksuIjXypRJ" + }, + "source": [ + "# treinando a regressão Ridge\n", + "ridge.fit(X_treinamento, y_treinamento)\n", + "\n", + "# treinando a regressão linear simples (OLS)\n", + "lr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7r28PBsWLtjA" + }, + "source": [ + "ridge.alpha" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dDZ_TJnhuZno" + }, + "source": [ + "#### $\\alpha = 0.01$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hRMK_QTmNgc1" + }, + "source": [ + "# maior alpha --> mais restrição aos coeficientes; \n", + "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS; Se alpha = 0 ==> Ridge = OLS.\n", + "rr = Ridge(alpha = 0.01) # Quanto mais próximo de 0 ==> Ridge = OLS\n", + "rr.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IRuWmBE7Ngc7" + }, + "source": [ + "# MSE = Erro Quadrático Médio\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n", + "lr_model=(mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "L4an-zHetafI" + }, + "source": [ + "print(rr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QsLVzk3EtbGs" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K2sjngo1QhY2" + }, + "source": [ + "### Coeficientes da Ridge:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s5i87o3quByz" + }, + "source": [ + "# Lista das variáveis + coeficientes da Ridge:\n", + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s44vo9IjQonE" + }, + "source": [ + "### Experimente vários outros valores para $\\alpha$ como, por exemplo, $\\alpha = 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CDv5fGPbuUq5" + }, + "source": [ + "#### $\\alpha = 100$" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NEaj4QRrNgdA" + }, + "source": [ + "rr100 = Ridge(alpha = 100)\n", + "rr100.fit(X_treinamento, y_treinamento)\n", + "train_score=lr.score(X_treinamento, y_treinamento)\n", + "test_score=lr.score(X_teste, y_teste)\n", + "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zhcfoTEENgdE" + }, + "source": [ + "# MSE\n", + "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n", + "lr_model = (mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NGDBpfiquxoc" + }, + "source": [ + "print(rr100_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Owami5MVureW" + }, + "source": [ + "print(lr_model)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xk5dN3Owu6Kw" + }, + "source": [ + "### Próximo passo: fazer o statmodel dos modelos ridge." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEF_3GgUgF0Q" + }, + "source": [ + "# LASSO (Least Absolute Shrinkage And Selection Operator regularization)\n", + "* Método mais comum e usado para Regularization; \n", + "* Reduz overfitting;\n", + "* Se encarrega do **Feature Selection**, pois descarta variáveis altamente correlacionadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-YiKb9reQdI4" + }, + "source": [ + "* Usado no processo de Regularization - processo de penalizar as variáveis para manter somente os atributos mais importantes. Pense na utilidade disso diante de um dataframe com muitas variáveis;\n", + "* A regressão Lasso vem com um parâmetro ($\\alpha$), e quanto maior o alfa, a maioria dos coeficientes de recurso é zero. Ou seja, quando $\\alpha = 0$, a regressão Lasso produz os mesmos coeficientes que uma regressão linear. Quando alfa é muito grande, todos os coeficientes são zero." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5p_ZPZ4tTUX1" + }, + "source": [ + "### Exemplo LASSO" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JD1_M2uw6q0W" + }, + "source": [ + "X_new" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5JZTnkTOkI9" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_new, y_new)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "gEUxSlThOkJD" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EQaGWzzLT9qP" + }, + "source": [ + "### Aplicação do LASSO no Boston Housing Price" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ME6v6LFlgF0Q" + }, + "source": [ + "from sklearn.linear_model import Lasso\n", + "lasso = Lasso(alpha = .1)\n", + "lasso.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "h6DSEHc1gF0V" + }, + "source": [ + "lasso.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8SzYnpVGy4cy" + }, + "source": [ + "### Coeficientes do LASSO:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O2w2QDmdxxVe" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(lasso.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UBOCg1H9zn6A" + }, + "source": [ + "### Comparação com os coeficientes do RIDGE:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g1fF-mEZzXpH" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xP1fX1Bi6VdX" + }, + "source": [ + "**Conclusão**: Coeficientes zero podem ser excluídos da Análise/modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TbtxIWyGSXkH" + }, + "source": [ + "### Efeito dos valores de $\\alpha$\n", + "* Função adaptada de https://chrisalbon.com/machine_learning/linear_regression/effect_of_alpha_on_lasso_regression/." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B4AuWA4LRBE3" + }, + "source": [ + "# Create a function called lasso,\n", + "def lasso(alphas):\n", + " '''\n", + " Takes in a list of alphas. Outputs a dataframe containing the coefficients of lasso regressions from each alpha.\n", + " '''\n", + " # Create an empty data frame\n", + " df = pd.DataFrame()\n", + " \n", + " # Create a column of feature names\n", + " df['Feature Name'] = names\n", + " \n", + " # For each alpha value in the list of alpha values,\n", + " for alpha in alphas:\n", + " # Create a lasso regression with that alpha value,\n", + " lasso = Lasso(alpha = alpha)\n", + " \n", + " # Fit the lasso regression\n", + " lasso.fit(X_treinamento, y_treinamento)\n", + " \n", + " # Create a column name for that alpha value\n", + " column_name = 'Alpha = %f' % alpha\n", + "\n", + " # Create a column of coefficient values\n", + " df[column_name] = lasso.coef_\n", + " \n", + " # Return the datafram \n", + " return df" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VEDvXvuNRK0C" + }, + "source": [ + "names = X_treinamento.columns\n", + "\n", + "# Valores de alpha:\n", + "lasso([.0001, .001, 0, .01, .1, 1, 10, 100])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xFlvTUJKhwgW" + }, + "source": [ + "### Capturando os elementos mais importantes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4_-sUgMIhzmE" + }, + "source": [ + "r_squared = model.rsquared\n", + "r_squared_adj = model.rsquared_adj\n", + "coeficientes_regressao = model.params" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "apGv5ytnimsM" + }, + "source": [ + "VEJA: https://stackoverflow.com/questions/27928275/find-p-value-significance-in-scikit-learn-linearregression" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uhokzxtcil8w" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jSYw6SdcXa0q" + }, + "source": [ + "### Cross-Validation & GridSearch para LASSO" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E14i4Y3rqEX2" + }, + "source": [ + "### Colocar aqui a fórmula do RMSE." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "irFZAkvVXfya" + }, + "source": [ + "from sklearn.linear_model import LassoCV\n", + "from sklearn.model_selection import RepeatedKFold" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "T3Jjom8RYdly" + }, + "source": [ + "# define model evaluation method\n", + "cv = RepeatedKFold(n_splits = 5, n_repeats = 3, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cw3lAvRPYgJe" + }, + "source": [ + "# define model\n", + "model = LassoCV(alphas = np.arange(0.001, 10, 0.001), cv = cv, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLX3CpThXvkJ" + }, + "source": [ + "# fit model\n", + "model.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "U1ubd5huYQ7u" + }, + "source": [ + "# summarize chosen configuration\n", + "print('alpha: %f' % model.alpha_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9P7hYoo4gF0Z" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yChNUYs7gF0b" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "S1m3SL2avMbd" + }, + "source": [ + "transformacao.fit(dados_que_eu_quero_transformar)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4mbIaAUAF4N6" + }, + "source": [ + "en.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MaUkZw8ngF0h" + }, + "source": [ + "list(zip(X_treinamento, en.coef_))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K7LuPhCtvouJ" + }, + "source": [ + "### GridSearch para encontrar o $\\alpha$ para Elastic Net" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xl-Qh9caDyCp" + }, + "source": [ + "# Instancia o objeto:\n", + "en = ElasticNet(normalize = True)\n", + "\n", + "# Otimização dos hiperparâmetros:\n", + "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n", + " 'l1_ratio': [.2, .4, .6, .8]}\n", + "\n", + "search = GridSearchCV(estimator = en, # Elastic Net\n", + " param_grid = d_hiperparametros, # Dicionário com os hiperparâmetros\n", + " scoring = 'mean_squared_error', # MSE (Erro Quadrático Médio) - Métrica para avaliação da performance do modelo\n", + " #scoring = 'neg_mean_squared_error',\n", + " n_jobs = -1, # Usar todos os processadores/computação\n", + " refit = True, \n", + " cv = 10) # Número de Cross-Valitations" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JvNQyUW_2QLr" + }, + "source": [ + "### Exercício (Estatística): Sugestão de ajuste manual\n", + "* Estudar estatisticamente a distribuição de frequência em que a variável é significante (ao nível de 5%) em 100 fits." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hp1hV5YahsJb" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ng0rPXfA1DgS" + }, + "source": [ + "for i in range(0, 100):\n", + " X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X, y, 0.2)\n", + " modeloi = fit(X_treinamento, y_treinamento)\n", + " intercepto\n", + " coeficientes da regressão\n", + " validação dos parâmetros (significância)\n", + " y_predict = predict(X_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c3_XCQCPGlr3" + }, + "source": [ + "search.fit(X_treinamento, y_treinamento)\n", + "\n", + "# Retorna os melhores hiperparâmetros do algoritmo:\n", + "search.best_params_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zq0_ugQfGrdb" + }, + "source": [ + "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n", + "en2.fit(X_treinamento, y_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ILA5lScUx-Ub" + }, + "source": [ + "\n", + "# Métrica\n", + "ml2 = (mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))\n", + "# Encontrar a métrica neg_squared_error --> ml3 = (neg_mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BzO_dHRixd_L" + }, + "source": [ + "print(f\"MSE: {ml2}\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zaEwh3t3zwFc" + }, + "source": [ + "**Conclusão**:\n", + "* Comparação dos MSE - A Regressão sem Regularization produziu MSE de 23.94. Como podemos ver, Elastic Net produz MSE: 15.4." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5geUMgC6ztxE" + }, + "source": [ + "### Coeficientes do Elastic Net:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LyLdASRqzwCq" + }, + "source": [ + "list(zip(X_treinamento.columns, abs(ridge.coef_)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "90pfP9-3OkJG" + }, + "source": [ + "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILCXvYKDOkJH" + }, + "source": [ + "# Elastic Net \n", + "* Combina o poder de Ridge e LASSO;\n", + "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GaQPDCR2OkJI" + }, + "source": [ + "from sklearn.linear_model import ElasticNet\n", + "\n", + "# Instancia o objeto\n", + "en = ElasticNet(alpha = .1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xVp16Eu_OkJL" + }, + "source": [ + "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kwj018U8OkJO" + }, + "source": [ + "en.coef_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rJRWBzSQCcss" + }, + "source": [ + "# Regressão Logística\n", + "\n", + "* Na regressão linear nós tentamos modelar a relação linear entre as features ($X_{np} = [X_{1}, X_{2}, ..., X_{p}]$) através de uma reta dada pela equação:\n", + "\n", + "$$\\hat{y}= \\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p}$$\n", + "\n", + "Para classificação, a Regressão Logística vai nos retornar probabilidades (entre 0 e 1), dada pela equação logística ( também conhecida **função sigmoid**):\n", + "\n", + "$$P[y = 1]= \\frac{1}{1+e^{-(\\beta_{0}+\\beta_{1}x_{1}+\\beta_{2}x_{2}+...+\\beta_{p}x_{p})}}$$\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vj83Altwdni7" + }, + "source": [ + "![SigmoidFunction](https://github.com/MathMachado/Materials/blob/master/SigmoidFunction.PNG?raw=true)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LS1QjQnknqe5" + }, + "source": [ + "## Pressupostos da Regressão Logística\n", + "* Não há valores nulos no banco de dados;\n", + "* A variável-resposta $y$ é binária (0 ou 1) ou ordinal (variável categórica com valores ordenados (por exemplo, estimar a qualidade do vinho));\n", + "* Todas as variáveis preditoras $X$ são independentes;\n", + "* Há (pelo menos) 50 observações para cada variável preditora no modelo preditivo --> Quanto mais, melhor. Isso visa garantir a confiabilidade dos resultados);\n", + "* As classes da variável-resposta estejam equilibradas;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YGvpGTAd4jO" + }, + "source": [ + "# Exemplo 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-LBYRG__e_Zv" + }, + "source": [ + "### Carregar as libraries" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XX2GNYWue-iA" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt # Graficos\n", + "import seaborn as sns # Graficos\n", + "%matplotlib inline\n", + "\n", + "# Classificadores\n", + "import statsmodels.api as sm\n", + "import statsmodels.formula.api as smf\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "# Métricas\n", + "from sklearn.metrics import roc_auc_score, roc_curve, classification_report, accuracy_score, confusion_matrix, auc" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpNu-JjJfBYe" + }, + "source": [ + "### Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dWVj8SmUeBZB", + "outputId": "ddb92623-228d-4621-90f9-b80b1a0d06c9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n", + "df_titanic = pd.read_csv(url)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " PassengerId Survived Pclass ... Fare Cabin Embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 289 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T9vZGvU5qbsQ", + "outputId": "6ad44206-7129-4e4e-a03d-cec7aeab3449", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic.columns = [coluna.lower() for coluna in df_titanic.columns]\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 290 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fAYAg5tofDgQ" + }, + "source": [ + "### Entendendo os dados\n", + "* sibsp - número of siblings/esposas abordo do Titanic;\n", + "* parch - número de parentes/crianças abordo do Titanic;\n", + "* embarked - Cidade/Portão de embarque: C = Cherbourg, Q = Queenstown, S = Southampton." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZbijPdpFxdZy" + }, + "source": [ + "#### A variável-target é do tipo binária ou categórica ordinal?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7hspb3IMe5tx", + "outputId": "684c59df-d788-400f-a179-0774a39e4303", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['survived'].value_counts()/df_titanic.shape[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0 0.616162\n", + "1 0.383838\n", + "Name: survived, dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 291 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tsp4t7oxx3zC" + }, + "source": [ + "A seguir, o gráfico da variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vm0BDjw-xrGI", + "outputId": "443def8e-dee6-40f5-8bcf-b33a43bb5c15", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 296 + } + }, + "source": [ + "sns.countplot(x = 'survived', data = df_titanic)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 292 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XfhFG6Axxj6F" + }, + "source": [ + "Como podemos ver, a variável-resposta 'survived' é binária. Portanto, tudo ok até agora." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zRKhDX6ZraGU" + }, + "source": [ + "### Tratamento dos Missing Values\n", + "* Substituir os NaN's por mediana da variável" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qPbILjZyrhRZ", + "outputId": "52f34626-1875-4632-cce3-8a694863ea6c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 293 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uJUPufRossTo" + }, + "source": [ + "Cálculo da mediana da variável/preditora 'age'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WGW9bW5x4JdT", + "outputId": "c0ce5e66-70fe-4195-c637-2ac8a4cf9d37", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 357 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 294 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DgAwrR8msYv_" + }, + "source": [ + "mediana_age = df_titanic['age'].median()\n", + "mediana_fare = df_titanic['fare'].median()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "yqIgckarzwdB", + "outputId": "a190a691-e377-42ba-a8f8-98d430ccabbd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_age" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 297 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "czdSVeLjzxAX", + "outputId": "48bdfb0b-a153-482e-9fa6-6706bd44b88d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "mediana_fare" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14.4542" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 298 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4vcCshcsv6w" + }, + "source": [ + "Substituição dos NaN's da variável 'age' e 'fare' pela respetiva mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tnOOsaqLsg03", + "outputId": "81837607-f6b7-4bc2-e295-443679d3deb2", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age'].fillna(mediana_age, inplace = True)\n", + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 299 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VqAnNxnO0Ghn" + }, + "source": [ + "Dado que fare não possui NaN's, então nada a fazer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Hi2zG_ms6n-" + }, + "source": [ + "#### Usando Imputer\n", + "* Método para tratamento de Missing Values.\n", + " Scikit Learn: https://scikit-learn.org/stable/modules/impute.html" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mvCnGfCOri9Y", + "outputId": "6d8b7f52-ca60-4bbd-bc50-9e55f3b9bd17", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'median')\n", + "imputer_mv.fit(df_titanic_copia[['age', 'fare']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 300 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SokJ8HM61FcK", + "outputId": "65052934-48c4-4c6d-b206-b14d8fa10dc3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "imputer_mv" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='median', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 301 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X-qx8QsQthyU", + "outputId": "469c2591-1ea2-4dfd-8395-df11821f5951", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "# transform()\n", + "df_titanic_mediana = pd.DataFrame(imputer_mv.transform(df_titanic[['age', 'fare']]), columns = ['age2', 'fare2'])\n", + "df_titanic_mediana.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age2fare2
022.07.2500
138.071.2833
226.07.9250
335.053.1000
435.08.0500
\n", + "
" + ], + "text/plain": [ + " age2 fare2\n", + "0 22.0 7.2500\n", + "1 38.0 71.2833\n", + "2 26.0 7.9250\n", + "3 35.0 53.1000\n", + "4 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 302 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KS-xYf5BuwEt", + "outputId": "c7e01602-c917-48b7-a7f1-33ce365f21ac", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_mediana.median()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "age2 28.0000\n", + "fare2 14.4542\n", + "dtype: float64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 303 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lggbmAD2vN42", + "outputId": "55134b01-f993-4f01-b053-7600c45eec21", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic_copia.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 177\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 304 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8fQ6a7RSvUOp", + "outputId": "75770554-a802-4012-a068-76b2e1ba1578", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic['age'] = df_titanic_mediana['age2']\n", + "\n", + "# Não há NaN's na variável fare. Portanto, nenhuma alteração\n", + "#df_titanic['fare'] = df_titanic_mediana['fare']\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 305 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HSncMlT51oM5", + "outputId": "85057833-9c05-4805-d2d0-ad6a3af0d140", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "passengerid 0\n", + "survived 0\n", + "pclass 0\n", + "name 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "ticket 0\n", + "fare 0\n", + "cabin 687\n", + "embarked 2\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 306 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c48gJg0q4zgj" + }, + "source": [ + "Exclui as colunas que não são mais necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7OzK7DnDg2WY", + "outputId": "462a1c3e-d2b3-4d5d-b745-945706522481", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 498 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", + "
" + ], + "text/plain": [ + " passengerid survived pclass ... fare cabin embarked\n", + "0 1 0 3 ... 7.2500 NaN S\n", + "1 2 1 1 ... 71.2833 C85 C\n", + "2 3 1 3 ... 7.9250 NaN S\n", + "3 4 1 1 ... 53.1000 C123 S\n", + "4 5 0 3 ... 8.0500 NaN S\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 307 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oLpWbzz84ykm", + "outputId": "cdb706ed-5395-47d0-8f52-7887edcde8ee", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 308 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NZei3VxSxR6g" + }, + "source": [ + "Alternativamente, poderíamos concatenar os dois dataframes usando pd.concat()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ek2qBdOFw2p5", + "outputId": "7777706c-55e4-4bfd-822f-cf3843922f3e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic = df_titanic_copia.copy()\n", + "\n", + "df_titanic.drop(columns = ['passengerid', 'name', 'ticket', 'cabin', 'fare', 'age'], axis = 1, inplace = True)\n", + "df_titanic = pd.concat([df_titanic, df_titanic_mediana], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchembarkedage2fare2
003male10S22.07.2500
111female10C38.071.2833
213female00S26.07.9250
311female10S35.053.1000
403male00S35.08.0500
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch embarked age2 fare2\n", + "0 0 3 male 1 0 S 22.0 7.2500\n", + "1 1 1 female 1 0 C 38.0 71.2833\n", + "2 1 3 female 0 0 S 26.0 7.9250\n", + "3 1 1 female 1 0 S 35.0 53.1000\n", + "4 0 3 male 0 0 S 35.0 8.0500" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6omsobg77tRv" + }, + "source": [ + "#### Tratamento dos NaN's da variável 'embarked'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YjeivMbz85gg" + }, + "source": [ + "A seguir, listamos as linhas em que embarked = NaN:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mc03_AnI8QgV", + "outputId": "ebe1ecc6-2c40-429d-d608-3b72ef10acd2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked
6111female38.00080.0NaN
82911female62.00080.0NaN
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked\n", + "61 1 1 female 38.0 0 0 80.0 NaN\n", + "829 1 1 female 62.0 0 0 80.0 NaN" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 309 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsbeFBFp7zRM", + "outputId": "58859c46-d711-4558-aadf-70480e67c98b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from sklearn.impute import SimpleImputer\n", + "\n", + "# fit()\n", + "imputer_mv = SimpleImputer(strategy = 'most_frequent')\n", + "imputer_mv.fit(df_titanic[['embarked']])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "SimpleImputer(add_indicator=False, copy=True, fill_value=None,\n", + " missing_values=nan, strategy='most_frequent', verbose=0)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 310 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f2kDtHVN761L" + }, + "source": [ + "# transform()\n", + "df_embarked_freq = pd.DataFrame(imputer_mv.transform(df_titanic[['embarked']]), columns = ['embarked2'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0JmoLrzD8NwW", + "outputId": "d8ac60c0-a440-42b1-d7d5-c00168c3956f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic = pd.concat([df_titanic, df_embarked_freq], axis = 1)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
003male22.0107.2500SS
111female38.01071.2833CC
213female26.0007.9250SS
311female35.01053.1000SS
403male35.0008.0500SS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S S\n", + "1 1 1 female 38.0 1 0 71.2833 C C\n", + "2 1 3 female 26.0 0 0 7.9250 S S\n", + "3 1 1 female 35.0 1 0 53.1000 S S\n", + "4 0 3 male 35.0 0 0 8.0500 S S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 312 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FRxX9c4--TCg" + }, + "source": [ + "COMPARE o ANTES e o DEPOIS: Veja a seguir que os valores de [embarked] = NaN foram substituidos por..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oQFDqatz9bMv", + "outputId": "45d6ab98-b832-4844-8d66-6d47cbcee08e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 110 + } + }, + "source": [ + "embarked_NaN = df_titanic[df_titanic['embarked'].isna()]\n", + "embarked_NaN" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarkedembarked2
6111female38.00080.0NaNS
82911female62.00080.0NaNS
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked embarked2\n", + "61 1 1 female 38.0 0 0 80.0 NaN S\n", + "829 1 1 female 62.0 0 0 80.0 NaN S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 313 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jgCuXei2ZTQl" + }, + "source": [ + "Como podemos ver, os NaN's da variável embarked foram todos substituídos pelo valor 'S'. Tudo bem para vocês esta substituição?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r3r8ObKn-nBt" + }, + "source": [ + "df_titanic.drop(columns = ['embarked'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OacQvrYeAPBR" + }, + "source": [ + "Verificação final dos NaN's:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OHBv7CrjARol", + "outputId": "df1e556b-21dd-42a2-df08-4c0046f1f3b1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.isna().sum()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived 0\n", + "pclass 0\n", + "sex 0\n", + "age 0\n", + "sibsp 0\n", + "parch 0\n", + "fare 0\n", + "embarked2 0\n", + "dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 315 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ITFMsiBSyAHY" + }, + "source": [ + "### O dataframe sob análise possui (pelo menos) 50 observações para cada preditora?\n", + "* Variáveis preditoras: pclass, sex, age, sibsp, parch, fare, embarked2 --> 7 variáveis preditoras.\n", + "* Portanto, nosso dataframe precisa de, no mínimo 7 x 50 = 350 linhas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4lgVp2N8yE1C", + "outputId": "2dbea822-609b-4576-c3e2-f89b3527db1c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.info()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 891 entries, 0 to 890\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 survived 891 non-null int64 \n", + " 1 pclass 891 non-null int64 \n", + " 2 sex 891 non-null object \n", + " 3 age 891 non-null float64\n", + " 4 sibsp 891 non-null int64 \n", + " 5 parch 891 non-null int64 \n", + " 6 fare 891 non-null float64\n", + " 7 embarked2 891 non-null object \n", + "dtypes: float64(2), int64(4), object(2)\n", + "memory usage: 55.8+ KB\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rFwtnAcw23gQ", + "outputId": "2b9b006b-3dee-493a-e9a6-adcf90923373", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "891/7" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "127.28571428571429" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 317 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wLqz2V7SytPU" + }, + "source": [ + "Pressuposto atendido?\n", + "Se sim, podemos prosseguir com as análises..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wm0VycfhovW8" + }, + "source": [ + "#### Avaliação do pressuposto de variáveis preditoras independentes\n", + "* Coeficiente de Spearman (desenvolvido por Charles Spearman). Também conhecido como Coeficiente de Correlação de Spearman e denotado pela letra greaga $\\rho(p)$.\n", + "* É um método estatístico para avaliar/medir a correlação entre 2 variáveis ordinais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "29knlUdcztb1", + "outputId": "adb2e1a5-2436-4327-8eff-4a65b66d4e0b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchfareage2ambarked2
003male107.250022.0S
111female1071.283338.0C
213female007.925026.0S
311female1053.100035.0S
403male008.050035.0S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp parch fare age2 ambarked2\n", + "0 0 3 male 1 0 7.2500 22.0 S\n", + "1 1 1 female 1 0 71.2833 38.0 C\n", + "2 1 3 female 0 0 7.9250 26.0 S\n", + "3 1 1 female 1 0 53.1000 35.0 S\n", + "4 0 3 male 0 0 8.0500 35.0 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 102 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J5EEcU7l0E2B" + }, + "source": [ + "A seguir, a hipótese de independência que queremos testar:\n", + "\n", + "$H_{0}$: variáveis são independentes --> Se o p-value < 5% --> Há evidências para rejeitar $H_{0}$." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tj8A_Kp0qxp_" + }, + "source": [ + "from scipy.stats import spearmanr" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kFxVGHPUpKLi" + }, + "source": [ + "coef, p = spearmanr(df_titanic['pclass'], df_titanic['age'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fvzvyvK7qzib", + "outputId": "d1e8d723-5048-4360-bad4-9ce0b8172bbf", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print('Coeficiente de Correlação de Spearman: %.3f' % coef)\n", + "\n", + "# Interpretação da significância:\n", + "alpha = 0.05\n", + "if p > alpha:\n", + "\tprint('Amostras NÃO correlacionadas (falha em rejeitar H0) p = %.3f' %p)\n", + "else:\n", + "\tprint('Amostras correlacionadas (Rejeita H0) p = %.3f' %p)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Coeficiente de Correlação de Spearman: -0.317\n", + "Amostras correlacionadas (Rejeita H0) p = 0.000\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yespibmf1WVh" + }, + "source": [ + "## Data Transformation\n", + "* MinMaxScaler e RobustScaler\n", + "* Binning (categorização de variáveis/preditoras numéricas): fare e age\n", + "* Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UwLpj8PXKFuL" + }, + "source": [ + "### Tratamento dos Outliers\n", + "* variáveis: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sTTgUx9oiWdJ", + "outputId": "fd14b9f5-7e25-4416-bfc7-e318e79d3249", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "#df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2
003male22.0107.2500S
111female38.01071.2833C
213female26.0007.9250S
311female35.01053.1000S
403male35.0008.0500S
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2\n", + "0 0 3 male 22.0 1 0 7.2500 S\n", + "1 1 1 female 38.0 1 0 71.2833 C\n", + "2 1 3 female 26.0 0 0 7.9250 S\n", + "3 1 1 female 35.0 1 0 53.1000 S\n", + "4 0 3 male 35.0 0 0 8.0500 S" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 321 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-7v8WaB4aEKv" + }, + "source": [ + "from scipy import stats \n", + "\n", + "def trata_outliers(df, coluna):\n", + " sns.boxplot(x = coluna, data = df)\n", + "\n", + " # Cálculo de Q1, Q3 e IQR:\n", + " Q1 = np.percentile(df[coluna], 25)\n", + " Q3 = np.percentile(df[coluna], 75)\n", + " IQR = Q3 - Q1\n", + " print(f\"IQR: {IQR}\")\n", + "\n", + " # Jeito mais fácil (menos trabalhoso).\n", + " #IQR2 = stats.iqr(df[coluna]) \n", + " #IQR2 \n", + "\n", + " # Cálculo dos limites inferiores e superiores para detecção de outliers:\n", + " limite_inferior_outliers = Q1 - 1.5*IQR\n", + " limite_superior_outliers = Q3 + 1.5*IQR\n", + " print(f\"Limite inferior para outlier: {limite_inferior_outliers}; Limite superior para outliers: {limite_superior_outliers}\")\n", + "\n", + " # Cálculo da mediana\n", + " mediana = df[coluna].median()\n", + " print(f\"Mediana: {mediana}\")\n", + "\n", + " # Substituição dos outliers:\n", + " df[coluna+'_o'] = df[coluna]\n", + "\n", + " df.loc[df[coluna] > limite_superior_outliers, coluna+'_o'] = np.nan\n", + " df[coluna+'_o'].fillna(mediana, inplace = True) # 'o' significa tratamento outlier --> indicação para mostrar que a coluna passou pelo tratamento dos outliers.\n", + "\n", + " return df, limite_superior_outliers" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pwAExKTWaOSf", + "outputId": "089cba96-b805-4eef-d504-f8c81551c938", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'age')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 13.0\n", + "Limite inferior para outlier: 2.5; Limite superior para outliers: 54.5\n", + "Mediana: 28.0\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rB3Wh7jldcl-", + "outputId": "34e01f99-642a-45aa-ebd3-bda160d7be2e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 665 + } + }, + "source": [ + "df_titanic.head(20)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
503male28.0008.4583Q28.0
601male54.00051.8625S54.0
703male2.03121.0750S2.0
813female27.00211.1333S27.0
912female14.01030.0708C14.0
1013female4.01116.7000S4.0
1111female58.00026.5500S28.0
1203male20.0008.0500S20.0
1303male39.01531.2750S39.0
1403female14.0007.8542S14.0
1512female55.00016.0000S28.0
1603male2.04129.1250Q2.0
1712male28.00013.0000S28.0
1803female31.01018.0000S31.0
1913female28.0007.2250C28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0\n", + "5 0 3 male 28.0 0 0 8.4583 Q 28.0\n", + "6 0 1 male 54.0 0 0 51.8625 S 54.0\n", + "7 0 3 male 2.0 3 1 21.0750 S 2.0\n", + "8 1 3 female 27.0 0 2 11.1333 S 27.0\n", + "9 1 2 female 14.0 1 0 30.0708 C 14.0\n", + "10 1 3 female 4.0 1 1 16.7000 S 4.0\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "12 0 3 male 20.0 0 0 8.0500 S 20.0\n", + "13 0 3 male 39.0 1 5 31.2750 S 39.0\n", + "14 0 3 female 14.0 0 0 7.8542 S 14.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "16 0 3 male 2.0 4 1 29.1250 Q 2.0\n", + "17 1 2 male 28.0 0 0 13.0000 S 28.0\n", + "18 0 3 female 31.0 1 0 18.0000 S 31.0\n", + "19 1 3 female 28.0 0 0 7.2250 C 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 324 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x6YRvSf5SRR4" + }, + "source": [ + "### Quem são os outliers de 'age'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2y9BeUnoSU4W", + "outputId": "85968b30-7903-465b-eddf-27d4604acb58", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "age_outlier = df_titanic[df_titanic['age'] > limite_superior_outliers]\n", + "age_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
1111female58.00026.5500S28.0
1512female55.00016.0000S28.0
3302male66.00010.5000S28.0
5401male65.00161.9792C28.0
9403male59.0007.2500S28.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "11 1 1 female 58.0 0 0 26.5500 S 28.0\n", + "15 1 2 female 55.0 0 0 16.0000 S 28.0\n", + "33 0 2 male 66.0 0 0 10.5000 S 28.0\n", + "54 0 1 male 65.0 0 1 61.9792 C 28.0\n", + "94 0 3 male 59.0 0 0 7.2500 S 28.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 327 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0dHnei1TBFc" + }, + "source": [ + "### Tratamento dos outliers da variável 'fare'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i8YM25uKm8g1", + "outputId": "00e04c37-82d8-4aca-c250-36a4a045df2f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 328 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4Gnr9AEfTSj6", + "outputId": "40a23226-68bd-4288-dbf2-5fabfd4fd32b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 332 + } + }, + "source": [ + "df_titanic, limite_superior_outliers = trata_outliers(df = df_titanic, coluna = 'fare')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "IQR: 23.0896\n", + "Limite inferior para outlier: -26.724; Limite superior para outliers: 65.6344\n", + "Mediana: 14.4542\n" + ], + "name": "stdout" + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uh7f7nNATSkT" + }, + "source": [ + "### Quem são os outliers de 'fare'?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdzaUaD0nQnv", + "outputId": "c05a1d46-c91a-4542-92a8-bfb121b44174", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "limite_superior_outliers" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "65.6344" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 330 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P3SAGnYnnQn4", + "outputId": "424347d6-d243-48df-8c3d-4c2a014c0cd9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "fare_outlier = df_titanic[df_titanic['fare'] > limite_superior_outliers]\n", + "fare_outlier.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_ofare_o
111female38.01071.2833C38.014.4542
2701male19.032263.0000S19.014.4542
3111female28.010146.5208C28.014.4542
3401male28.01082.1708C28.014.4542
5211female49.01076.7292C49.014.4542
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o fare_o\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 14.4542\n", + "27 0 1 male 19.0 ... 263.0000 S 19.0 14.4542\n", + "31 1 1 female 28.0 ... 146.5208 C 28.0 14.4542\n", + "34 0 1 male 28.0 ... 82.1708 C 28.0 14.4542\n", + "52 1 1 female 49.0 ... 76.7292 C 49.0 14.4542\n", + "\n", + "[5 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 331 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Jh83WTrZDeM_" + }, + "source": [ + "### Binning variáveis numéricas: age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JVNVCd7aDjkz", + "outputId": "21f91b71-cfe5-445b-cf2c-8f4bf0de9825", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 203 + } + }, + "source": [ + "#df_titanic_copia = df_titanic.copy()\n", + "df_titanic = df_titanic_copia.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_o
003male22.0107.2500S22.0
111female38.01071.2833C38.0
213female26.0007.9250S26.0
311female35.01053.1000S35.0
403male35.0008.0500S35.0
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age sibsp parch fare embarked2 age_o\n", + "0 0 3 male 22.0 1 0 7.2500 S 22.0\n", + "1 1 1 female 38.0 1 0 71.2833 C 38.0\n", + "2 1 3 female 26.0 0 0 7.9250 S 26.0\n", + "3 1 1 female 35.0 1 0 53.1000 S 35.0\n", + "4 0 3 male 35.0 0 0 8.0500 S 35.0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 332 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pUspmjPWFP06" + }, + "source": [ + "#### Usando cut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NBVoCBe_2Zmp" + }, + "source": [ + "#df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90])\n", + "# Obs.: a linha de cima gera a coluna age-bins com o intervalo no seguinte formato: (início, fim], exemplo: (20, 30] -> intervalor aberto e fechado\n", + "df_titanic['age_bins'] = pd.cut(x = df_titanic['age_o'], bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], labels = [10, 20, 30, 40, 50, 60, 70, 80, 90])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2i1jombNDrEO", + "outputId": "7c96358b-3023-4706-813a-3e3e594cc45e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 264 + } + }, + "source": [ + "df_titanic.head(7)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareembarked2age_oage_bins
003male22.0107.2500S22.030
111female38.01071.2833C38.040
213female26.0007.9250S26.030
311female35.01053.1000S35.040
403male35.0008.0500S35.040
503male28.0008.4583Q28.030
601male54.00051.8625S54.060
\n", + "
" + ], + "text/plain": [ + " survived pclass sex age ... fare embarked2 age_o age_bins\n", + "0 0 3 male 22.0 ... 7.2500 S 22.0 30\n", + "1 1 1 female 38.0 ... 71.2833 C 38.0 40\n", + "2 1 3 female 26.0 ... 7.9250 S 26.0 30\n", + "3 1 1 female 35.0 ... 53.1000 S 35.0 40\n", + "4 0 3 male 35.0 ... 8.0500 S 35.0 40\n", + "5 0 3 male 28.0 ... 8.4583 Q 28.0 30\n", + "6 0 1 male 54.0 ... 51.8625 S 54.0 60\n", + "\n", + "[7 rows x 10 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 340 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "davIt0UT9tTr" + }, + "source": [ + "#### **Desafio**: Qual seria o corte ótimo para 'age' usando DecisionTree?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "i5aAYl2ZDu1f", + "outputId": "0f1d7a99-6cb0-4484-b12b-7907b70feb8a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_cut1'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20, 30] 449\n", + "(30, 40] 155\n", + "(10, 20] 115\n", + "(40, 50] 86\n", + "(0, 10] 64\n", + "(50, 60] 22\n", + "(80, 90] 0\n", + "(70, 80] 0\n", + "(60, 70] 0\n", + "Name: age_bins_cut1, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 276 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VAUshOiLFT9-" + }, + "source": [ + "#### Usando qcut()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RKnb-bI7FL3F", + "outputId": "59742803-dcee-4525-8fd1-2cecff379cab", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic['age_bins_qcut'] = pd.qcut(x = df_titanic['age'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 277 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "boSGroSYN7cP", + "outputId": "9304540f-1a20-41cb-c4a4-70633be1a071", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic.dtypes" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "survived int64\n", + "pclass int64\n", + "sex object\n", + "age float64\n", + "sibsp int64\n", + "parch int64\n", + "fare float64\n", + "embarked2 object\n", + "age_o float64\n", + "age_bins category\n", + "dtype: object" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 344 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "P8s3LzfpNdUz", + "outputId": "b0e4b638-32de-4295-984e-ba207e195661", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "# ***************************************************\n", + "# AUTOMATIZAR O TRATAMENTO DE VARIÁVEIS DO MESMO TIPO\n", + "# ***************************************************\n", + "l_colunas_numericas = list(df_titanic.select_dtypes('int').columns)\n", + "l_colunas_numericas\n", + "\n", + "for coluna in l_colunas_numericas:\n", + " trata_outliers(df, coluna)\n", + " trata_missing_values(df, coluna)\n", + " aplica_MMS(df, coluna)\n", + " aplica_RS(df, coluna)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['survived', 'pclass', 'sibsp', 'parch']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 346 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ov2_l39mn3FH", + "outputId": "122869f8-018f-4176-b2df-c249efa222b7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['age_bins_qcut'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(20.0, 28.0] 360\n", + "(0.419, 20.0] 179\n", + "(38.0, 80.0] 177\n", + "(28.0, 38.0] 175\n", + "Name: age_bins_qcut, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 261 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J60XwHUOGwbr" + }, + "source": [ + "### MinMaxScaler() e RobustScaler()\n", + "* age e fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GRY84U4HHxoQ" + }, + "source": [ + "from sklearn.preprocessing import MinMaxScaler, RobustScaler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "IQC7Bo-DH71s" + }, + "source": [ + "mms = MinMaxScaler()\n", + "rs = RobustScaler()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8O2oM9XdIYF5", + "outputId": "9812b76b-dffc-406b-fcd9-0a7c1b01a61b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 264 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B-qglHy6NZlg", + "outputId": "96a154a8-678e-48eb-93b2-ce93b7e0258f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic_copia = df_titanic.copy()\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]30(20.0, 28.0]
111female38.01071.2833C38.014.4542(30, 40]40(28.0, 38.0]
213female26.0007.9250S26.07.9250(20, 30]30(20.0, 28.0]
311female35.01053.1000S35.053.1000(30, 40]40(28.0, 38.0]
403male35.0008.0500S35.08.0500(30, 40]40(28.0, 38.0]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 (20.0, 28.0]\n", + "1 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "2 1 3 female ... (20, 30] 30 (20.0, 28.0]\n", + "3 1 1 female ... (30, 40] 40 (28.0, 38.0]\n", + "4 0 3 male ... (30, 40] 40 (28.0, 38.0]\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 265 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dp9jYZ1OoA9i" + }, + "source": [ + "A seguir, deletar as variáveis que desnecessárias..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zSSViPY5XokW" + }, + "source": [ + "df_titanic.drop(columns = ['age', 'fare'], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MNq5a0eUIBGV", + "outputId": "d692f608-f511-46e6-d101-bd9443647b94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 282 + } + }, + "source": [ + "# fit\n", + "df_titanic_mms = pd.DataFrame(mms.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_mms', 'fare_mms'])\n", + "df_titanic_rs = pd.DataFrame(rs.fit_transform(df_titanic[['age_o', 'fare_o']]), columns = ['age_rs', 'fare_rs'])\n", + "\n", + "df_titanic['age_mms'] = df_titanic_mms['age_mms']\n", + "df_titanic['age_rs'] = df_titanic_rs['age_rs']\n", + "\n", + "df_titanic['fare_mms'] = df_titanic_mms['fare_mms']\n", + "df_titanic['fare_rs'] = df_titanic_rs['fare_rs']\n", + "\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rsage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.111538-0.443619(0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C38.014.4542(30, 40]40(28.0, 38.0]0.7013810.9090910.2223720.000000(0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.121923-0.402054(0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S35.053.1000(30, 40]40(28.0, 38.0]0.6453900.6363640.8169232.379726(0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S35.08.0500(30, 40]40(28.0, 38.0]0.6453900.6363640.123846-0.394357(0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 19 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 268 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UzrdPNO3rIg5", + "outputId": "aaa31937-081d-4af8-f3ec-07002886d2a6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 555 + } + }, + "source": [ + "# Categorizando as variáveis transformadas\n", + "df_titanic['age_bins_mms'] = pd.qcut(x = df_titanic['age_mms'], q = 5, duplicates = 'drop', labels = [1, 2, 3, 4])\n", + "df_titanic['age_bins_rs'] = pd.qcut(x = df_titanic['age_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "\n", + "df_titanic['fare_bins_mms'] = pd.qcut(x = df_titanic['fare_mms'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')\n", + "df_titanic['fare_bins_rs'] = pd.qcut(x = df_titanic['fare_rs'], q = 5, labels = [1, 2, 3, 4], duplicates = 'drop')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2894\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2895\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Categorizando as variáveis transformadas\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_bins_rs'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_rs'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_bins_mms'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fare_mms'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mduplicates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'drop'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2901\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2902\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2903\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2904\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2895\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2896\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2897\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2898\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2899\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtolerance\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'age_mms'" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7smfXya5pmNq", + "outputId": "a942223f-e9b6-4758-c453-73c5c55f91bd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.drop(columns = ['age_o', 'fare_o', 'age_bins_cut2', 'age_mms', 'age_rs', 'fare_mms', 'fare_rs'], axis = 1, inplace = True)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age_bins_cut1age_bins_qcutage_bins_mmsage_bins_rsfare_bins_mmsfare_bins_rs
003male10S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](-0.001, 0.121](-0.891, -0.406]
111female10C(30, 40](28.0, 38.0](0.645, 1.0](0.636, 2.364](0.162, 0.222](-0.243, 0.0]
213female00S(20, 30](20.0, 28.0](0.365, 0.515](-0.727, 0.0](0.121, 0.162](-0.406, -0.243]
311female10S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.404, 1.0](0.726, 3.113]
403male00S(30, 40](28.0, 38.0](0.515, 0.645](0.0, 0.636](0.121, 0.162](-0.406, -0.243]
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_rs fare_bins_mms fare_bins_rs\n", + "0 0 3 male ... (-0.727, 0.0] (-0.001, 0.121] (-0.891, -0.406]\n", + "1 1 1 female ... (0.636, 2.364] (0.162, 0.222] (-0.243, 0.0]\n", + "2 1 3 female ... (-0.727, 0.0] (0.121, 0.162] (-0.406, -0.243]\n", + "3 1 1 female ... (0.0, 0.636] (0.404, 1.0] (0.726, 3.113]\n", + "4 0 3 male ... (0.0, 0.636] (0.121, 0.162] (-0.406, -0.243]\n", + "\n", + "[5 rows x 12 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 269 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SFPNLDMcU339" + }, + "source": [ + "### Variáveis Dummy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L_Fx1iy7snjF", + "outputId": "24c70d23-5a35-41aa-8a30-04fcc146b7c6", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcut
003male22.0107.2500S22.07.2500(20, 30]302
111female38.01071.2833C38.014.4542(30, 40]403
213female26.0007.9250S26.07.9250(20, 30]302
311female35.01053.1000S35.053.1000(30, 40]403
403male35.0008.0500S35.08.0500(30, 40]403
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... age_bins_cut1 age_bins_cut2 age_bins_qcut\n", + "0 0 3 male ... (20, 30] 30 2\n", + "1 1 1 female ... (30, 40] 40 3\n", + "2 1 3 female ... (20, 30] 30 2\n", + "3 1 1 female ... (30, 40] 40 3\n", + "4 0 3 male ... (30, 40] 40 3\n", + "\n", + "[5 rows x 13 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 279 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X6aHaJodX0Hi", + "outputId": "f7a26db1-81d3-47f5-dcd3-bbde2b2b6440", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 402 + } + }, + "source": [ + "dummy = pd.get_dummies(df_titanic[['sex', 'ambarked2']])\n", + "dummy" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
sex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
001001
110100
210001
310001
401001
..................
88601001
88710001
88810001
88901100
89001010
\n", + "

891 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " sex_female sex_male ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 1 0 0 1\n", + "1 1 0 1 0 0\n", + "2 1 0 0 0 1\n", + "3 1 0 0 0 1\n", + "4 0 1 0 0 1\n", + ".. ... ... ... ... ...\n", + "886 0 1 0 0 1\n", + "887 1 0 0 0 1\n", + "888 1 0 0 0 1\n", + "889 0 1 1 0 0\n", + "890 0 1 0 1 0\n", + "\n", + "[891 rows x 5 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 282 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZhLW0lEbs28E", + "outputId": "c772c290-4394-409a-ded7-1eb57b7ac0db", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 215 + } + }, + "source": [ + "df_titanic2 = pd.concat([df_titanic, dummy], axis = 1)\n", + "df_titanic2.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexagesibspparchfareambarked2age_ofare_oage_bins_cut1age_bins_cut2age_bins_qcutsex_femalesex_maleambarked2_Cambarked2_Qambarked2_S
003male22.0107.2500S22.07.2500(20, 30]30201001
111female38.01071.2833C38.014.4542(30, 40]40310100
213female26.0007.9250S26.07.9250(20, 30]30210001
311female35.01053.1000S35.053.1000(30, 40]40310001
403male35.0008.0500S35.08.0500(30, 40]40301001
\n", + "
" + ], + "text/plain": [ + " survived pclass sex ... ambarked2_C ambarked2_Q ambarked2_S\n", + "0 0 3 male ... 0 0 1\n", + "1 1 1 female ... 1 0 0\n", + "2 1 3 female ... 0 0 1\n", + "3 1 1 female ... 0 0 1\n", + "4 0 3 male ... 0 0 1\n", + "\n", + "[5 rows x 18 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 283 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I_bOYD4gWwGt", + "outputId": "b33c5076-6d0b-4c8f-8e5b-d87cb3e4544d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts() # Quem será a referência?" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 64 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xFKdsFDihApP" + }, + "source": [ + "df_titanic['pclass'] = df_titanic['pclass'].astype('category')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D_mWCqM1ZOgU" + }, + "source": [ + "### Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UPnCuCsLZSjQ", + "outputId": "95b92d55-a895-4c2e-9655-07a3bd753f6d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mX_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mX_teste\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_treinamento\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_teste\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_test_split\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'train_test_split' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rk-Zuh5RXJbp", + "outputId": "47c3c005-795d-406d-984a-b0094cd5718c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
survivedpclasssexsibspparchambarked2age3fare3age_bins_cut1age_bins_cut2age_bins_qcutage_mmsage_rsfare_mmsfare_rs
00.03.0male1.00.0S22.07.2500(20, 30]30(20.0, 28.0]0.402762-0.5454550.014151-0.323505
11.01.0female1.00.0C38.071.2833(30, 40]40(36.0, 54.0]0.7013810.9090910.1391362.696934
21.03.0female0.00.0S26.07.9250(20, 30]30(20.0, 28.0]0.477417-0.1818180.015469-0.291665
31.01.0female1.00.0S35.053.1000(30, 40]40(28.0, 36.0]0.6453900.6363640.1036441.839231
40.03.0male0.00.0S35.08.0500(30, 40]40(28.0, 36.0]0.6453900.6363640.015713-0.285769
\n", + "
" + ], + "text/plain": [ + " survived pclass sex sibsp ... age_mms age_rs fare_mms fare_rs\n", + "0 0.0 3.0 male 1.0 ... 0.402762 -0.545455 0.014151 -0.323505\n", + "1 1.0 1.0 female 1.0 ... 0.701381 0.909091 0.139136 2.696934\n", + "2 1.0 3.0 female 0.0 ... 0.477417 -0.181818 0.015469 -0.291665\n", + "3 1.0 1.0 female 1.0 ... 0.645390 0.636364 0.103644 1.839231\n", + "4 0.0 3.0 male 0.0 ... 0.645390 0.636364 0.015713 -0.285769\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 69 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XtdQc49LXTfk", + "outputId": "696c23be-e9d0-4ba9-b4f5-0dcba0ffe8ec", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_titanic['pclass'].value_counts()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "3.0 484\n", + "1.0 189\n", + "2.0 176\n", + "Name: pclass, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 74 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Construção da 1ª Versão do modelo (baseline)" + ], + "metadata": { + "id": "yTjb4CyYkktB" + } + }, + { + "cell_type": "code", + "metadata": { + "id": "fbvB30S5hRxH", + "outputId": "e872fe50-fcad-4b33-9456-182b1ca7e62c", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "modelo = smf.glm(formula = 'survived ~ age3 + pclass + sex', \n", + " data = df_titanic, \n", + " family = sm.families.Binomial()).fit()\n", + "print(modelo.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + " Generalized Linear Model Regression Results \n", + "==============================================================================\n", + "Dep. Variable: survived No. Observations: 849\n", + "Model: GLM Df Residuals: 844\n", + "Model Family: Binomial Df Model: 4\n", + "Link Function: logit Scale: 1.0000\n", + "Method: IRLS Log-Likelihood: -386.42\n", + "Date: Thu, 29 Oct 2020 Deviance: 772.85\n", + "Time: 17:17:09 Pearson chi2: 890.\n", + "No. Iterations: 5 \n", + "Covariance Type: nonrobust \n", + "=================================================================================\n", + " coef std err z P>|z| [0.025 0.975]\n", + "---------------------------------------------------------------------------------\n", + "Intercept 3.5515 0.382 9.297 0.000 2.803 4.300\n", + "pclass[T.2.0] -1.1389 0.264 -4.315 0.000 -1.656 -0.622\n", + "pclass[T.3.0] -2.3581 0.245 -9.613 0.000 -2.839 -1.877\n", + "sex[T.male] -2.5618 0.189 -13.522 0.000 -2.933 -2.191\n", + "age3 -0.0344 0.009 -4.035 0.000 -0.051 -0.018\n", + "=================================================================================\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p7_gfQXciFs1" + }, + "source": [ + "Qual a significância dos coeficientes (p-value abaixo de 0.05 adotando confiança de 95%)?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xtrh_bYNikTk" + }, + "source": [ + "### Interpretação dos coeficientes:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FzlGDyeLgL11" + }, + "source": [ + "* Pessoas que viajavam na segunda classe possuem menos chances de sobrevivência do que quem viajava na primeira.\n", + "* Quem viajava na terceira classe possui menos chances ainda.\n", + "* Homens possuem menos chances de sobrevivência do que mulheres. Quanto mais velho, menores as chances de sobrevivência." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CJNgEYY9ioVM" + }, + "source": [ + "### Coeficientes mais interpretáveis - Chances relativas de Sobrevivência" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "q0vLh1v3irCz" + }, + "source": [ + "print(np.exp(modelo.params[1:]))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a2fJIOOzi3VF" + }, + "source": [ + "* Pessoas que viajavam na segunda classe tinham 0.27 das chances de sobrevivência que as pessoas da primeira classe tinham. \n", + "* Pessoas da terceira classe tinham 0.076 das chances que as pessoas da primeira classe tinham. \n", + "* Homens tinham 0.08 das chances das mulheres." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dYRkdqNujHFA" + }, + "source": [ + "### Comparando com a regressão Linear" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mKW-aODfjLbm" + }, + "source": [ + "(np.exp(modelo.params[1:]) - 1) * 100" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ODOqZpAgjQ2q" + }, + "source": [ + "* Pessoas da segunda classe tem 73% menos chances de sobrevivência do que pessoas da primeira classe.\n", + "* Pessoas da terceira classe tem 92% menos chances de sobrevivência que pessoas da primeira classe.\n", + "* Homens tem 92% menos chances de sobrevivência do que mulheres.\n", + "* Para cada ano a mais de idade, as chances diminuem 3.63%." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fxnutoD7jp94" + }, + "source": [ + "### Qualidade do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-oW8Kg5Ij3Av", + "outputId": "d56cd7ce-e5c0-493d-ccfe-27cd5a6899c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 354 + } + }, + "source": [ + "modelo2 = LogisticRegression(penalty='none', solver='newton-cg')\n", + "df_titanic2 = df_titanic[['Survived', 'Pclass', 'Sex', 'Age']].dropna()\n", + "y = df_titanic2['Survived']\n", + "X = pd.get_dummies(df_titanic2[['Pclass', 'Sex', 'Age']], drop_first=True)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "KeyError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmodelo2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mLogisticRegression\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpenalty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'none'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'newton-cg'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf_titanic2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdropna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Survived'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mX\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_dummies\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf_titanic2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Pclass'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Sex'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdrop_first\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2906\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_iterator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2907\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2908\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_listlike_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2909\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2910\u001b[0m \u001b[0;31m# take() does not accept boolean indexers\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_get_listlike_indexer\u001b[0;34m(self, key, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1252\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew_indexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reindex_non_unique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1253\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1254\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_read_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_missing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mraise_missing\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1255\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mkeyarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindexer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py\u001b[0m in \u001b[0;36m_validate_read_indexer\u001b[0;34m(self, key, indexer, axis, raise_missing)\u001b[0m\n\u001b[1;32m 1296\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmissing\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1297\u001b[0m \u001b[0maxis_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_axis_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1298\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"None of [{key}] are in the [{axis_name}]\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1299\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1300\u001b[0m \u001b[0;31m# We (temporarily) allow for some missing keys with .loc, except in\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: \"None of [Index(['Survived', 'Pclass', 'Sex', 'Age'], dtype='object')] are in the [columns]\"" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YK9nIiz_kQQl" + }, + "source": [ + "modelo2.fit(X, y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FPhHe4SmkZoE" + }, + "source": [ + "y_pred = modelo2.predict_proba(X)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dPrXU0GSknGJ" + }, + "source": [ + "confusion_matrix(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_-Wweiq7kruH" + }, + "source": [ + "acuracia = accuracy_score(y, model.predict(X))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bqcT8XYJkuwH" + }, + "source": [ + "print(classification_report(y, model.predict(X)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "4fSN-vLOjseh" + }, + "source": [ + "confusion_matrix(y, modelo.predict(X)) # usando a função do sklearn" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "A0408gbPkywR" + }, + "source": [ + "def plot_roc_curve(y_true, y_score, figsize=(10,6)):\n", + " fpr, tpr, _ = roc_curve(y_true, y_score)\n", + " plt.figure(figsize=figsize)\n", + " auc_value = roc_auc_score(y_true, y_score)\n", + " plt.plot(fpr, tpr, color='orange', label='ROC curve (area = %0.2f)' % auc_value)\n", + " plt.plot([0, 1], [0, 1], color='darkblue', linestyle='--')\n", + " plt.xlabel('False Positive Rate')\n", + " plt.ylabel('True Positive Rate')\n", + " plt.title('Receiver Operating Characteristic (ROC) Curve')\n", + " plt.legend()\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5T4P90hQk1ug" + }, + "source": [ + "plot_roc_curve(y, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CANyMIgIjgSb" + }, + "source": [ + "### Predições" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pWJgVcQRlESq" + }, + "source": [ + "eu = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':1, 'Sex_male':1}, index=[0])\n", + "minha_prob = model.predict_proba(eu)\n", + "print('Eu teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(minha_prob[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kgpdgkgrlJ-w" + }, + "source": [ + "Eu teria 7.52% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "91GShU9ClMiY" + }, + "source": [ + "coleguinha = pd.DataFrame({'Age':32, 'Pclass_2':0, 'Pclass_3':0, 'Sex_male':1}, index=[0])\n", + "prob_do_coleguinha = model.predict_proba(coleguinha)\n", + "print('Meu coleguinha teria {}% de probabilidade de sobrevivência se estivesse no Titanic'\\\n", + " .format(round(prob_do_coleguinha[:,1][0]*100, 2)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c2EHn8volOil" + }, + "source": [ + "Meu coleguinha teria 51.77% de probabilidade de sobrevivência se estivesse no Titanic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C2PvJoZQlH6u" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XwuMfMD1gFyd" + }, + "source": [ + "# Exemplo 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kFY0TQVgOlvT" + }, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efF3st3sHxPG" + }, + "source": [ + "# Carrega as bibliotecas\n", + "import numpy as np\n", + "np.set_printoptions(formatter = {'float': lambda x: \"{0:0.2f}\".format(x)})\n", + "\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "import statsmodels.api as sm\n", + "\n", + "%matplotlib inline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bk9F6JO0IELv" + }, + "source": [ + "# Carregar/ler o banco de dados - Dataframe Diabetes\n", + "from sklearn import datasets\n", + "#Diabetes = datasets.load_diabetes()\n", + "\n", + "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/diabetes.csv'\n", + "diabetes = pd.read_csv(url)\n", + "diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tjRmpaPIDknb" + }, + "source": [ + "# Definir as matrizes X e y\n", + "X_diabetes = diabetes.copy()\n", + "X_diabetes.drop(columns = ['Outcome'], axis = 1, inplace = True)\n", + "y_diabetes = diabetes['Outcome']\n", + "\n", + "X_diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jLrx69TH-Mad" + }, + "source": [ + "X_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mdFBioP6-Ply" + }, + "source": [ + "y_diabetes.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fhLySN65IaDF" + }, + "source": [ + "# Definir as matrizes de treinamento e validação\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_diabetes, y_diabetes)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J5R8HlnuIGpL" + }, + "source": [ + "# Usando statmodels:\n", + "x = sm.add_constant(X_treinamento)\n", + "lr_sm = sm.Logit(y_treinamento, X_treinamento) # Atenção: aqui é o contrário: [y, x]\n", + "\n", + "# Treinar o modelo\n", + "lr.fit(X_treinamento, y_treinamento)\n", + "resultado_sm = lr_sm.fit()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GlbCaPp1ETNa" + }, + "source": [ + "resultado_sm.summary()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-FJaSnJLKICU" + }, + "source": [ + "# EQM - Erro Quadrático Médio\n", + "np.mean((resultado_sm.predict(X_teste) - y_teste) ** 2) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bVEUSTUPzOj" + }, + "source": [ + "### Calcular y_pred - os valores preditos de y" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OjGrNhTNLcr-" + }, + "source": [ + "y_pred = resultado_sm.predict(X_treinamento)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfS5RCx_VnGT" + }, + "source": [ + "compara = list(zip(np.array(diabetes['Outcome']), resultado_sm.predict()))\n", + "compara[0:30]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pUxasncIFaw4" + }, + "source": [ + "resultado_sm.pred_table()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_liLYinwFgch" + }, + "source": [ + "confusion_matrix = pd.DataFrame(resultado_sm.pred_table())\n", + "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n", + "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n", + "confusion_matrix" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ceH3MODWFm7S" + }, + "source": [ + "cm = np.array(confusion_matrix)\n", + "training_accuracy = (cm[0,0] + cm[1,1])/ cm.sum()\n", + "training_accuracy" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH_iEuzhO109" + }, + "source": [ + "# Exercício 1 - Mall_Customers.csv\n", + "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n", + "\n", + "* Experimente:\n", + " * Lasso(alpha = 0.01, max_iter = 10e5);\n", + " * Lasso(alpha = 0.0001, max_iter = 10e5);\n", + " * Ridge(alpha = 0.01);\n", + " * Ridge(alpha = 100);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZfRDEaaRYxFQ" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn import preprocessing\n", + "import matplotlib.pyplot as plt \n", + "plt.rc(\"font\", size=14)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "import seaborn as sns\n", + "sns.set(style=\"white\")\n", + "sns.set(style=\"whitegrid\", color_codes=True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nulrLzUqYxFY" + }, + "source": [ + "## Dados\n", + "\n", + "The data is related with direct marketing campaigns (phone calls) of a Portuguese banking institution. The classification goal is to predict if the client will subscribe (1/0) a term deposit (variable y)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4LdrQCwxYxFY" + }, + "source": [ + "This dataset provides the customer information. It includes 41188 records and 21 fields." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qoT6zkoFYxFZ", + "outputId": "b04874af-bf4d-409f-cd1c-ad8c473004e6", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_bank = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/bank-full.csv', header = 0)\n", + "df_bank = df_bank.dropna()\n", + "print(df_bank.shape)\n", + "print(list(df_bank.columns))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(45211, 1)\n", + "['age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZD23hMCeYxFc", + "outputId": "f347c846-5f92-4e4f-b468-2bfbc608777c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 195 + } + }, + "source": [ + "df_bank.head()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"
058;\"management\";\"married\";\"tertiary\";\"no\";2143...
144;\"technician\";\"single\";\"secondary\";\"no\";29;\"...
233;\"entrepreneur\";\"married\";\"secondary\";\"no\";2...
347;\"blue-collar\";\"married\";\"unknown\";\"no\";1506...
433;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n...
\n", + "
" + ], + "text/plain": [ + " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"\n", + "0 58;\"management\";\"married\";\"tertiary\";\"no\";2143... \n", + "1 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... \n", + "2 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... \n", + "3 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... \n", + "4 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... " + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 285 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CtGbim_EYxFh" + }, + "source": [ + "#### Input variables" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0pJ7ai5ZYxFh" + }, + "source": [ + "1 - age (numeric)\n", + "\n", + "2 - job : type of job (categorical: 'admin.','blue-collar','entrepreneur','housemaid','management','retired','self-employed','services','student','technician','unemployed','unknown')\n", + "\n", + "3 - marital : marital status (categorical: 'divorced','married','single','unknown'; note: 'divorced' means divorced or widowed)\n", + "\n", + "4 - education (categorical: 'basic.4y','basic.6y','basic.9y','high.school','illiterate','professional.course','university.degree','unknown')\n", + "\n", + "5 - default: has credit in default? (categorical: 'no','yes','unknown')\n", + "\n", + "6 - housing: has housing loan? (categorical: 'no','yes','unknown')\n", + "\n", + "7 - loan: has personal loan? (categorical: 'no','yes','unknown')\n", + "\n", + "8 - contact: contact communication type (categorical: 'cellular','telephone')\n", + "\n", + "9 - month: last contact month of year (categorical: 'jan', 'feb', 'mar', ..., 'nov', 'dec')\n", + "\n", + "10 - day_of_week: last contact day of the week (categorical: 'mon','tue','wed','thu','fri')\n", + "\n", + "11 - duration: last contact duration, in seconds (numeric). Important note: this attribute highly affects the output target (e.g., if duration=0 then y='no'). Yet, the duration is not known before a call is performed. Also, after the end of the call y is obviously known. Thus, this input should only be included for benchmark purposes and should be discarded if the intention is to have a realistic predictive model.\n", + "\n", + "12 - campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)\n", + "\n", + "13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)\n", + "\n", + "14 - previous: number of contacts performed before this campaign and for this client (numeric)\n", + "\n", + "15 - poutcome: outcome of the previous marketing campaign (categorical: 'failure','nonexistent','success')\n", + "\n", + "16 - emp.var.rate: employment variation rate - (numeric)\n", + "\n", + "17 - cons.price.idx: consumer price index - (numeric)\n", + "\n", + "18 - cons.conf.idx: consumer confidence index - (numeric) \n", + "\n", + "19 - euribor3m: euribor 3 month rate - (numeric)\n", + "\n", + "20 - nr.employed: number of employees - (numeric)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YwsaBV_OYxFi" + }, + "source": [ + "#### Predict variable (desired target):\n", + "\n", + "y - has the client subscribed a term deposit? (binary: '1','0')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2SsNWV_SYxFj" + }, + "source": [ + "The education column of the dataset has many categories and we need to reduce the categories for a better modelling. The education column has the following categories:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6TFbgh3vYxFk" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "luv7Bdf_YxFn" + }, + "source": [ + "Let us group \"basic.4y\", \"basic.9y\" and \"basic.6y\" together and call them \"basic\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gkOlUOs2YxFn" + }, + "source": [ + "df_bank['education']=np.where(df_bank['education'] =='basic.9y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.6y', 'Basic', df_bank['education'])\n", + "df_bank['education']=np.where(df_bank['education'] =='basic.4y', 'Basic', df_bank['education'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H-X1WMv2YxFq" + }, + "source": [ + "After grouping, this is the columns" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r9LlgpkjYxFq" + }, + "source": [ + "df_bank['education'].unique()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fcnJy3KYYxFt" + }, + "source": [ + "### Data exploration" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qUrTMR8BYxFt" + }, + "source": [ + "df_bank['y'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rpzHnzJKYxFx" + }, + "source": [ + "sns.countplot(x='y',data=df_bank, palette='hls')\n", + "plt.show()\n", + "plt.savefig('count_plot')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C99nOe3mYxF0" + }, + "source": [ + "There are 36548 no's and 4640 yes's in the outcome variables." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8nGaox_kYxF1" + }, + "source": [ + "Let's get a sense of the numbers across the two classes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sQvzA60bYxF1" + }, + "source": [ + "df_bank.groupby('y').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u3xjoceKYxF3" + }, + "source": [ + "Observations:\n", + "\n", + "The average age of customers who bought the term deposit is higher than that of the customers who didn't.\n", + "The pdays (days since the customer was last contacted) is understandably lower for the customers who bought it. The lower the pdays, the better the memory of the last call and hence the better chances of a sale.\n", + "Surprisingly, campaigns (number of contacts or calls made during the current campaign) are lower for customers who bought the term deposit." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jvzGMePPYxF4" + }, + "source": [ + "We can calculate categorical means for other categorical variables such as education and marital status to get a more detailed sense of our data." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RqLVMjoxYxF5" + }, + "source": [ + "df_bank.groupby('job').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GTUeRJAtYxF7" + }, + "source": [ + "df_bank.groupby('marital').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xsxdFumiYxF9" + }, + "source": [ + "df_bank.groupby('education').mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3i1DCWV-YxGA" + }, + "source": [ + "Visualizations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OEArHQPbYxGB" + }, + "source": [ + "%matplotlib inline\n", + "pd.crosstab(df_bank.job,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Job Title')\n", + "plt.xlabel('Job')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('purchase_fre_job')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNwo5du_YxGD" + }, + "source": [ + "The frequency of purchase of the deposit depends a great deal on the job title. Thus, the job title can be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eM7CWfAZYxGE" + }, + "source": [ + "table=pd.crosstab(df_bank.marital,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Marital Status vs Purchase')\n", + "plt.xlabel('Marital Status')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('mariral_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LWBLh7toYxGG" + }, + "source": [ + "Hard to see, but the marital status does not seem a strong predictor for the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vh_u4QphYxGH" + }, + "source": [ + "table=pd.crosstab(df_bank.education,df_bank.y)\n", + "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n", + "plt.title('Stacked Bar Chart of Education vs Purchase')\n", + "plt.xlabel('Education')\n", + "plt.ylabel('Proportion of Customers')\n", + "plt.savefig('edu_vs_pur_stack')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d9AgJroYYxGK" + }, + "source": [ + "Education seems a good predictor of the outcome variable." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dHI2LT-IYxGL" + }, + "source": [ + "pd.crosstab(df_bank.day_of_week,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Day of Week')\n", + "plt.xlabel('Day of Week')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_dayofweek_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3A2jmS4MYxGR" + }, + "source": [ + "Day of week may not be a good predictor of the outcome" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bzafDBHpYxGS" + }, + "source": [ + "pd.crosstab(df_bank.month,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Month')\n", + "plt.xlabel('Month')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_month_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x5CBtquEYxGW" + }, + "source": [ + "Month might be a good predictor of the outcome variable" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tgF_3SqWYxGY" + }, + "source": [ + "df_bank.age.hist()\n", + "plt.title('Histogram of Age')\n", + "plt.xlabel('Age')\n", + "plt.ylabel('Frequency')\n", + "plt.savefig('hist_age')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y0FhKYDsYxGc" + }, + "source": [ + "The most of the customers of the bank in this dataset are in the age range of 30-40." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5Nd3yV7DYxGd" + }, + "source": [ + "pd.crosstab(df_bank.poutcome,df_bank.y).plot(kind='bar')\n", + "plt.title('Purchase Frequency for Poutcome')\n", + "plt.xlabel('Poutcome')\n", + "plt.ylabel('Frequency of Purchase')\n", + "plt.savefig('pur_fre_pout_bar')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oRKUAGrjYxGh" + }, + "source": [ + "Poutcome seems to be a good predictor of the outcome variable." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "63RLRI9uYxGi" + }, + "source": [ + "### Create dummy variables" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "V8S4WUKmYxGj" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "for var in cat_vars:\n", + " cat_list='var'+'_'+var\n", + " cat_list = pd.get_dummies(df_bank[var], prefix=var)\n", + " df_bank1=df_bank.join(cat_list)\n", + " data=df_bank1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uX3w9i9WYxGl" + }, + "source": [ + "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n", + "df_bank_vars=df_bank.columns.values.tolist()\n", + "to_keep=[i for i in df_bank_vars if i not in cat_vars]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cMX_82xaYxGq" + }, + "source": [ + "df_bank_final=df_bank[to_keep]\n", + "df_bank_final.columns.values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LkTjpxYoYxGr" + }, + "source": [ + "df_bank_final_vars=df_bank_final.columns.values.tolist()\n", + "y=['y']\n", + "X=[i for i in df_bank_final_vars if i not in y]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2QbKaRcsYxGt" + }, + "source": [ + "### Feature Selection" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EkxjW1AQYxGu" + }, + "source": [ + "from sklearn import datasets\n", + "from sklearn.feature_selection import RFE\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "logreg = LogisticRegression()\n", + "\n", + "rfe = RFE(logreg, 18)\n", + "rfe = rfe.fit(df_bank_final[X], df_bank_final[y] )\n", + "print(rfe.support_)\n", + "print(rfe.ranking_)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2P9hd4jHYxGw" + }, + "source": [ + "The Recursive Feature Elimination (RFE) has helped us select the following features: \"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5PW8WZX_YxGx" + }, + "source": [ + "cols=[\"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \n", + " \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \n", + " \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"] \n", + "X=df_bank_final[cols]\n", + "y=df_bank_final['y']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ix0mN9qxYxG0" + }, + "source": [ + "### Implementing the model" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Hbx2bwtiYxG0" + }, + "source": [ + "import statsmodels.api as sm\n", + "logit_model=sm.Logit(y,X)\n", + "result=logit_model.fit()\n", + "print(result.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HR1ui-UcYxG2" + }, + "source": [ + "The p-values for most of the variables are very small, therefore, most of them are significant to the model." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9GHhrsaeYxG3" + }, + "source": [ + "### Logistic Regression Model Fitting" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFQnH5MzYxG3" + }, + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn import metrics\n", + "logreg = LogisticRegression()\n", + "logreg.fit(X_train, y_train)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YUa3QL7tYxG6" + }, + "source": [ + "#### Predicting the test set results and caculating the accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SD-y2e33YxG6" + }, + "source": [ + "y_pred = logreg.predict(X_test)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kkPWzos7YxG-" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kwC3rt_6YxHA" + }, + "source": [ + "### Cross Validation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Muw50oqSYxHB" + }, + "source": [ + "from sklearn import model_selection\n", + "from sklearn.model_selection import cross_val_score\n", + "kfold = model_selection.KFold(n_splits=10, random_state=7)\n", + "modelCV = LogisticRegression()\n", + "scoring = 'accuracy'\n", + "results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)\n", + "print(\"10-fold cross validation average accuracy: %.3f\" % (results.mean()))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4y8XCTqoYxHE" + }, + "source": [ + "### Confusion Matrix" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BCza9NkVYxHE" + }, + "source": [ + "from sklearn.metrics import confusion_matrix\n", + "confusion_matrix = confusion_matrix(y_test, y_pred)\n", + "print(confusion_matrix)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9SapwS2YxHG" + }, + "source": [ + "The result is telling us that we have 10872+254 correct predictions and 1122+109 incorrect predictions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bEWvWScYxHG" + }, + "source": [ + "#### Accuracy" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NaH2nESwYxHH" + }, + "source": [ + "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(classifier.score(X_test, y_test)))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C6oxlhbpYxHJ" + }, + "source": [ + "#### Compute precision, recall, F-measure and support\n", + "\n", + "The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.\n", + "\n", + "The recall is the ratio tp / (tp + fn) where tp is the number of true positives and fn the number of false negatives. The recall is intuitively the ability of the classifier to find all the positive samples.\n", + "\n", + "The F-beta score can be interpreted as a weighted harmonic mean of the precision and recall, where an F-beta score reaches its best value at 1 and worst score at 0.\n", + "\n", + "The F-beta score weights recall more than precision by a factor of beta. beta == 1.0 means recall and precision are equally important.\n", + "\n", + "The support is the number of occurrences of each class in y_test." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mhN5_p4yYxHK" + }, + "source": [ + "from sklearn.metrics import classification_report\n", + "print(classification_report(y_test, y_pred))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xzSFVEnAYxHP" + }, + "source": [ + "#### Interpretation: \n", + "\n", + "Of the entire test set, 88% of the promoted term deposit were the term deposit that the customers liked. Of the entire test set, 90% of the customer's preferred term deposit were promoted." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NGXJ6g2nYxHQ" + }, + "source": [ + "### ROC Curvefrom sklearn import metrics\n", + "from ggplot import *\n", + "\n", + "prob = clf1.predict_proba(X_test)[:,1]\n", + "fpr, sensitivity, _ = metrics.roc_curve(Y_test, prob)\n", + "\n", + "df = pd.DataFrame(dict(fpr=fpr, sensitivity=sensitivity))\n", + "ggplot(df, aes(x='fpr', y='sensitivity')) +\\\n", + " geom_line() +\\\n", + " geom_abline(linetype='dashed')" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u9QKDuS0YxHQ" + }, + "source": [ + "from sklearn.metrics import roc_auc_score\n", + "from sklearn.metrics import roc_curve\n", + "logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))\n", + "fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])\n", + "plt.figure()\n", + "plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)\n", + "plt.plot([0, 1], [0, 1],'r--')\n", + "plt.xlim([0.0, 1.0])\n", + "plt.ylim([0.0, 1.05])\n", + "plt.xlabel('False Positive Rate')\n", + "plt.ylabel('True Positive Rate')\n", + "plt.title('Receiver operating characteristic')\n", + "plt.legend(loc=\"lower right\")\n", + "plt.savefig('Log_ROC')\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15_XX__ImbalancedSample_hs.ipynb b/Notebooks/NB15_XX__ImbalancedSample_hs.ipynb new file mode 100644 index 000000000..6f28ac6ac --- /dev/null +++ b/Notebooks/NB15_XX__ImbalancedSample_hs.ipynb @@ -0,0 +1,1416 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled9.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rq9Q5HxFWLBW" + }, + "source": [ + "# Referências" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vdzGi1KTxnI2" + }, + "source": [ + "https://www.kaggle.com/saurav9786/feature-engineering-up-and-down-sampling\n", + "\n", + "https://towardsdatascience.com/dealing-with-imbalanced-data-in-churn-analysis-6ea1afba8b5e\n", + "\n", + "https://www.kdnuggets.com/2019/05/fix-unbalanced-dataset.html\n", + "\n", + "https://towardsdatascience.com/having-an-imbalanced-dataset-here-is-how-you-can-solve-it-1640568947eb\n", + "\n", + "https://medium.com/analytics-vidhya/balance-your-data-using-smote-98e4d79fcddb\n", + "\n", + "https://www.geeksforgeeks.org/ml-handling-imbalanced-data-with-smote-and-near-miss-algorithm-in-python/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eN3pXeN9ae-D" + }, + "source": [ + "## Reamostragem da classe minoritária\n", + "* Up-sampling é o processo de reamostrar observações aleatoriamente da classe minoritária." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sq0Z9FPwb2Z8" + }, + "source": [ + "#### Carregar as libraries:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YLIGeXQYj3Qn" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt # importing ploting libraries\n", + "import seaborn as sns # importing seaborn for statistical plots\n", + "from collections import Counter\n", + "\n", + "from sklearn.metrics import accuracy_score, f1_score, confusion_matrix, classification_report, recall_score # calculate accuracy measures and confusion matrix\n", + "\n", + "from imblearn.over_sampling import SMOTE" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EXOPkNK-jAwe" + }, + "source": [ + "!pip install imbalanced-learn" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qBeEcJ4lbrHi" + }, + "source": [ + "%matplotlib inline\n", + "\n", + "plt.rcParams['figure.figsize'] = [20.0, 7.0]\n", + "plt.rcParams.update({'font.size': 22,})\n", + "\n", + "sns.set_palette('viridis')\n", + "sns.set_style('white')\n", + "sns.set_context('talk', font_scale = 0.8)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PJLK5dVEb0Oe" + }, + "source": [ + "#### Carregar os dados\n", + "* Dataframe Credit Card: https://www.kaggle.com/mlg-ulb/creditcardfraud" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nZQwzb_wqFEs" + }, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DkObFs6Wdxy4" + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "0KV_cPVDbxUa" + }, + "source": [ + "url = '/content/drive/My Drive/Datasets4ML/creditcard.csv'\n", + "df_cc = pd.read_csv(url)\n", + "\n", + "df_cc.columns = [colunas.lower() for colunas in df_cc.columns]\n", + "\n", + "df_cc.drop(columns = 'time', axis = 1, inplace = True)\n", + "df_cc.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s5me2fqPqgfq" + }, + "source": [ + "### Tratamento dos Missing Values" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y98jCK55qjyR" + }, + "source": [ + "df_cc.isna().sum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QY5R8MmkdBsy" + }, + "source": [ + "### Qual a proporção de fraudes e não-fraudes?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0fNYOL_PLMMQ" + }, + "source": [ + "qtd = Counter(df_cc['class'])\n", + "qtd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S9SLjncvizFs" + }, + "source": [ + "np.round(100*qtd[1]/qtd[0], 4)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CELJp_aZy_RB" + }, + "source": [ + "### Normalização" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_2L-7fyaz0so" + }, + "source": [ + "df_cc2 = df_cc.copy()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JLwFSuLtzA9H" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n", + "\n", + "l_colunas = df_cc.columns\n", + "l_colunas = l_colunas.drop('class')\n", + "l_colunas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "htApfx0h2Rr_" + }, + "source": [ + "for coluna in l_colunas:\n", + " df_cc2[coluna+'_2'] = StandardScaler().fit_transform(np.array(df_cc2[coluna]).reshape(-1, 1))\n", + " df_cc2 = df_cc2.drop(columns = coluna, axis = 1) \n", + "\n", + "df_cc2.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HMnKnqif0wDp" + }, + "source": [ + "### Amostra de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zoivyfcs0ye3" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_cc, y_cc, test_size = 0.3, random_state = 20111974) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lceXISCC3kbC" + }, + "source": [ + "### Treinamento do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ikoTEk-W048P" + }, + "source": [ + "# Instancia:\n", + "lr = LogisticRegression() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tj4vD_qlMVkN" + }, + "source": [ + "# Treina o modelo usando a amostra de treinamento: \n", + "lr.fit(X_treinamento, y_treinamento.ravel()) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G_APl0QY3rfY" + }, + "source": [ + "### Previsão do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SJPiVCzJ3qbg" + }, + "source": [ + "y_pred = lr.predict(X_teste) \n", + " \n", + "# print classification report \n", + "print(classification_report(y_teste, y_pred)) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oBXTrmmN4IYq" + }, + "source": [ + "**Conclusão**: Temos acurácia de 100%.\n", + "\n", + "Observe o recall da classe minoritária: 0.57 ==> Isso mostra que estamos diante de uma amostra desbalanceada e que, neste caso, o modelo está inclinado/viesado pela classe majoritária." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7aEemta6lSTO" + }, + "source": [ + "## Reamostragem da classe Majoritária\n", + "* Up-sampling é o processo de reamostrar observações aleatoriamente da classe minoritária." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "26W4RzWG1Tco" + }, + "source": [ + "X_cc = df_cc2.copy()\n", + "X_cc = X_cc.drop(columns = 'class', axis = 1)\n", + "\n", + "y_cc = df_cc2['class']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sZRcM4qqllDo" + }, + "source": [ + "### Processo\n", + "1. Separar as observações de cada classe em diferentes dataframes;\n", + "2. Reamostrar a classe minoritária COM REPOSIÇÃO;\n", + "3. Combinar os dois dataframes com as classes minoritárias e majoritárias." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WB-v_VjHmH9M" + }, + "source": [ + "Abaixo, seleção das instâncias/linhas em que [class] = 0 ==> Classe Majoritária" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mcLiKkpAl30d" + }, + "source": [ + "df_cc_majo = df_cc2[df_cc2['class'] == 0]\n", + "df_cc_majo.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qc-VXhlYmcyi" + }, + "source": [ + "Abaixo, seleção das instâncias/linhas em que [class] = 1 ==> Classe Minoritária" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tbk1OrUzmcyj" + }, + "source": [ + "df_cc_mino = df_cc2[df_cc2['class'] == 1]\n", + "df_cc_mino.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UeCniZsBlYMc" + }, + "source": [ + "## Reamostragem da classe majoritária (COM REPOSIÇÃO)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TJ_I9bceqGYd" + }, + "source": [ + "np.random.seed(20111974)\n", + "df_cc_majo_s = df_cc_majo.sample(n = df_cc_mino.shape[0]+300, replace = True)\n", + "df_cc_majo_s.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1LzjX3dJqzmY" + }, + "source": [ + "#### Combinar os dois dataframes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0xNGGK-5q3Pd" + }, + "source": [ + "df_cc_s1 = pd.concat([df_cc_majo_s, df_cc_mino])\n", + "Counter(df_cc_s1['class'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EYhxJSfT56F2" + }, + "source": [ + "df_cc_s1.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8q7zxWK6ZE_B" + }, + "source": [ + "Portanto, o dataframe df_cc_s1 é uma das amostras em que tratamos o desbalanceamento." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IeGBIu_X6Pel" + }, + "source": [ + "### Amostra de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Q6TqvmQC6Peq" + }, + "source": [ + "X = df_cc_s1.copy()\n", + "X = X.drop(columns = 'class', axis = 1)\n", + "\n", + "y = df_cc_s1['class']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_dO-ASMH6Peu" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X, y, test_size = 0.3, random_state = 20111974) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qn8K_6mQ6Pew" + }, + "source": [ + "### Treinamento do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kDHE-bz46Pex" + }, + "source": [ + "# Instancia\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "lr = LogisticRegression() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "42NW2MKzMt8v" + }, + "source": [ + "# treina o modelo na amostra de treinamento \n", + "lr.fit(X_treinamento, y_treinamento.ravel()) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6bMFgHcO6Pez" + }, + "source": [ + "### Previsão do modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xp5Fb3yk6Pez" + }, + "source": [ + "y_pred = lr.predict(X_teste) \n", + " \n", + "# print classification report \n", + "print(classification_report(y_teste, y_pred)) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1DyzKGSu6Pe1" + }, + "source": [ + "**Conclusão**: Temos acurácia de 94%.\n", + "\n", + "Observe o recall da classe minoritária: 0.92 ==> Isso mostra que estamos diante de uma amostra balanceada." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1Q2-7aJTmSWJ" + }, + "source": [ + "### Verificar a quantidade de instâncias por preditoras" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SYnnu-lWmYUo" + }, + "source": [ + "X.shape[0]/X.shape[1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TQ_eu8Jyqwe7" + }, + "source": [ + "Temos 44 linhas para cada coluna/variável do dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e2tY6Xks6vOM" + }, + "source": [ + "## SMOTE (Synthetic Minority Oversampling Technique)\n", + "* Uma forma de se resolver o problema das amostras desbalanceadas é simplesmente reamostrando a classe minoritária e isso pode ser obtido através da duplicação da classe minoritária. Isso resolve o problema do desbalanceamento, mas não traz nenhuma informação adicional ao modelo.\n", + "* Uma alternativa é criar amostras sintéticas da classe minoritária e pode ser efetivo para resolver o problema do desbalanceamento.\n", + "* A estratégia mais utilizada é o SMOTE.\n", + " * Seleciona aleatoriamente amostras que estão próximos (amostras sintéticas). " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g9hW8lTGO4S_" + }, + "source": [ + "SMOTE first selects a minority class instance a at random and finds its k nearest minority class neighbors. The synthetic instance is then created by choosing one of the k nearest neighbors b at random and connecting a and b to form a line segment in the feature space. The synthetic instances are generated as a convex combination of the two chosen instances a and b.\n", + "\n", + "**Imbalanced Learning: Foundations, Algorithms, and Applications, 2013**\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bXKn7na75I_5" + }, + "source": [ + "from imblearn.over_sampling import SMOTE \n", + "sm = SMOTE(random_state = 20111974) # por questões de reproducibilidade" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "no2QQgd66-qy" + }, + "source": [ + "### Amostra de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NKHz8aWl6-qz" + }, + "source": [ + "X_cc = df_cc2.copy()\n", + "X_cc = X_cc.drop(columns = 'class', axis = 1)\n", + "\n", + "y_cc = df_cc2['class']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7Mq3x4Ej6-q3" + }, + "source": [ + "from imblearn.over_sampling import SMOTE \n", + "sm = SMOTE(random_state = 20111974) \n", + "\n", + "X, y = sm.fit_sample(X_cc, y_cc) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OBVGbDEeKaK_" + }, + "source": [ + "def antes_depois(y_cc, y):\n", + " qtd_a = Counter(y_cc)\n", + " qtd_d = Counter(y)\n", + " print(qtd_a)\n", + " print(qtd_d)\n", + "\n", + " # scatter plot: antes\n", + " for label, _ in qtd_a.items():\n", + "\t row_ix = np.where(y_cc == label)[0]\n", + "\t plt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + " plt.legend()\n", + " plt.show()\n", + "\n", + " # scatter plot: depois\n", + " for label, _ in qtd_d.items():\n", + "\t row_ix = np.where(y == label)[0]\n", + "\t plt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + " plt.legend()\n", + " plt.show()\n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GkvkEEteKsUT" + }, + "source": [ + "antes_depois(y_cc, y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "CqqwdtDRtXFu" + }, + "source": [ + "sum(y)/sum(y_cc)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6It3vQq1-qdn" + }, + "source": [ + "## Estratégia 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kbQDKCyo_RTs" + }, + "source": [ + "from imblearn.under_sampling import RandomUnderSampler" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dLuoImU9-sGx" + }, + "source": [ + "over = SMOTE(sampling_strategy = 0.1) # Reamostrar a classe minoritária para ter 10% da classe majoritária\n", + "under = RandomUnderSampler(sampling_strategy = 0.5) # Seleciona a classe majoritária para ter 50%" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o4WdMzQ6-iV1" + }, + "source": [ + "Usando um Pileline" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8Hr38-lR_WaG" + }, + "source": [ + "from imblearn.pipeline import Pipeline" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NY0quIhW5bGe" + }, + "source": [ + "steps = [('over', over), ('under', under)]\n", + "pipeline = Pipeline(steps = steps)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E57PQ3isuGGM" + }, + "source": [ + "X_cc e y_cc são nossos dataframes originais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0viVAtDs5bKs" + }, + "source": [ + "# Aplica o pipeline\n", + "X, y = pipeline.fit_resample(X_cc, y_cc)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IjqfnKY3uYeU" + }, + "source": [ + "Antes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iIMZ9UgGQEq0" + }, + "source": [ + "Counter(y_cc)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hNpOBtw5ucEh" + }, + "source": [ + "Depois:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TYMLs88_QI9k" + }, + "source": [ + "qtd_d = Counter(y)\n", + "qtd_d" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2WHEPLGeSuJL" + }, + "source": [ + "# scatter plot\n", + "for label, _ in qtd_d.items():\n", + "\trow_ix = np.where(y == label)[0]\n", + "\tplt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xl2O2ChzBuoX" + }, + "source": [ + "# Instancia o modelo\n", + "lr = LogisticRegression()\n", + "\n", + "# acrescenta o modelo ao pipeline:\n", + "steps = [('over', over), ('under', under), ('model', lr)]\n", + "pipeline = Pipeline(steps = steps)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JgbhWi-mRMkH" + }, + "source": [ + "from sklearn.model_selection import RepeatedStratifiedKFold\n", + "from sklearn.model_selection import cross_val_score" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fez37c3qB-JP" + }, + "source": [ + "# evaluate pipeline\n", + "cv = RepeatedStratifiedKFold(n_splits = 10, n_repeats = 3, random_state = 20111974)\n", + "scores = cross_val_score(pipeline, X, y, scoring = 'roc_auc', cv = cv, n_jobs = -1)\n", + "scores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1hRfhf6CJpj" + }, + "source": [ + "Avalia o Pipeline" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WKAz2D8VCI96" + }, + "source": [ + "print(f'Mean ROC AUC: {np.mean(scores)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7W9arWK0AUVJ" + }, + "source": [ + "## SMOTE para Classificação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "N2a-d3SBAfCq" + }, + "source": [ + "# define pipeline\n", + "steps = [('over', SMOTE()), ('model', LogisticRegression())]\n", + "pipeline = Pipeline(steps = steps)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "lGGZ-oReARUp" + }, + "source": [ + "# evaluate pipeline\n", + "from sklearn.model_selection import RepeatedStratifiedKFold\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "cv = RepeatedStratifiedKFold(n_splits = 10, n_repeats = 3, random_state = 20111974)\n", + "scores = cross_val_score(pipeline, X, y, scoring = 'roc_auc', cv = cv, n_jobs = -1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "q2V9qNCnvkF8" + }, + "source": [ + "scores" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ixo5dDksvmFk" + }, + "source": [ + "np.std(scores)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "N5n1lGndCA02" + }, + "source": [ + "Avalia o Pipeline:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1UlycCSeBd5L" + }, + "source": [ + "print(f'Mean ROC AUC: {np.mean(scores)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R7vgx9MUCg7F" + }, + "source": [ + "## Questões interessantes\n", + "* Qual o percentual adequado da classe minoritária e da classe majoritária com melhor performance?\n", + "* Qual o valor de k ótimo para o SMOTE (default: 5)?\n", + "```\n", + "for k in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n", + " # Defina o pipeline\n", + "```" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a7NO3Pb9DVrK" + }, + "source": [ + "l_knn = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", + "\n", + "for k in l_knn:\n", + "\t# Pipeline\n", + "\tmodel = LogisticRegression()\n", + "\tover = SMOTE(sampling_strategy = 0.1, k_neighbors = k)\n", + "\tunder = RandomUnderSampler(sampling_strategy = 0.5)\n", + "\tsteps = [('over', over), ('under', under), ('model', model)]\n", + "\tpipeline = Pipeline(steps = steps)\n", + " \n", + "\t# Avalia o pipeline\n", + "\tcv = RepeatedStratifiedKFold(n_splits = 10, n_repeats = 3, random_state = 20111974)\n", + "\tscores = cross_val_score(pipeline, X_cc, y_cc, scoring = 'roc_auc', cv = cv, n_jobs = -1)\n", + " \n", + " \ty_pred = model.predict(X_teste) \n", + " \n", + "\t# print classification report \n", + "\tprint(classification_report(y_teste, y_pred)) \n", + "\tprint(f'Valor de k: {k}; Mean ROC AUC: {np.mean(scores)}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YJt1bxijE58v" + }, + "source": [ + "## Borderline+SMOTE\n", + "* Uma extensão popular para SMOTE envolve a seleção de instâncias da classe minoritária que foram classificadas incorretamente, como com um modelo de classificação de k-vizinho mais próximo." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bp9xDm39E9Ru" + }, + "source": [ + "from imblearn.over_sampling import BorderlineSMOTE" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8ea3z02PGSly" + }, + "source": [ + "# transform the dataset\n", + "oversample = BorderlineSMOTE()\n", + "X, y = oversample.fit_resample(X_cc, y_cc)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VsYz3KUgVGa1" + }, + "source": [ + "qtd_a = Counter(y_cc)\n", + "print(qtd_a)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WxSoOawzGzzS" + }, + "source": [ + "qtd_d = Counter(y)\n", + "print(qtd_d)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "k3mnOqs4GcUM" + }, + "source": [ + "# scatter plot\n", + "for label, _ in qtd_d.items():\n", + "\trow_ix = np.where(y == label)[0]\n", + "\tplt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zHT2IVGyCTSs" + }, + "source": [ + "### BORDERLINE+SVM\n", + "* Usa SVM (ao invés do KNN);." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OTnPb0uFCbhD" + }, + "source": [ + "# Carrega a library:\n", + "from imblearn.over_sampling import SVMSMOTE\n", + "\n", + "oversample = SVMSMOTE()\n", + "X, y = oversample.fit_resample(X_cc, y_cc)\n", + "\n", + "# summarize the new class distribution\n", + "qtd_d = Counter(y)\n", + "print(qtd_d)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ltfp7_XgKCnd" + }, + "source": [ + "# scatter plot\n", + "for label, _ in qtd_d.items():\n", + "\trow_ix = np.where(y == label)[0]\n", + "\tplt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O4G71LLTJTpS" + }, + "source": [ + "### Adaptive Synthetic Sampling (ADASYN)\n", + "* Gera mais amostras sintéticas nas regiões onde a densidade da classe minoritária é baixa e MENOS (ou nenhuma) onde a densidade da classe minoritária é alta." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wdepfj4HA6wd" + }, + "source": [ + "# Carrega a library:\n", + "from imblearn.over_sampling import ADASYN\n", + "\n", + "oversample = ADASYN()\n", + "X, y = oversample.fit_resample(X_cc, y_cc)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "QUHQblBuWBJw" + }, + "source": [ + "qtd_d = Counter(y)\n", + "print(qtd_d)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RJzg9YRdJrLO" + }, + "source": [ + "# scatter plot\n", + "for label, _ in qtd_d.items():\n", + "\trow_ix = np.where(y == label)[0]\n", + "\tplt.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8bypBo3jJxHR" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mhavlcftJxFU" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "y8L-a-lbJw8x" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "08ZqlICmfGQq" + }, + "source": [ + "clf = setup(data = df_cc, \n", + " target = 'class',\n", + " session_id = 20111974,\n", + " silent = False,\n", + " fix_imbalance = False,\n", + " fix_imbalance_method = None,\n", + " ignore_features = ['time'])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "32yWqmXkfsya" + }, + "source": [ + "compare_models()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BdZk0nnZl6cb" + }, + "source": [ + "evaluate_model(dt)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qhCV7eMLl0Bs" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7iUqgofnl0QE" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c-n7LuT0l0Sy" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bGMEnl0IktNz" + }, + "source": [ + "### O melhor modelo" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VeMJ11_Jkoq8" + }, + "source": [ + "dt = create_model('dt')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LXTGruYkkfk7" + }, + "source": [ + "evaluate_model(dt)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U9xYILH2ajfe" + }, + "source": [ + "## Reamostragem da classe majoritária" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oS4R_nAcaHl1" + }, + "source": [ + "clf = setup(data = df_credit_card, target = 'Class')" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15__ML_AutoML_pycaret_hs.ipynb b/Notebooks/NB15__ML_AutoML_pycaret_hs.ipynb new file mode 100644 index 000000000..9f3b7e06a --- /dev/null +++ b/Notebooks/NB15__ML_AutoML_pycaret_hs.ipynb @@ -0,0 +1,316 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled8.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FfhCoyP98gDt" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "226lzu3i8kRp" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n", + "df_titanic = pd.read_csv(url)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6mL0RI0V9JmP" + }, + "source": [ + "#!pip install pycaret" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WL9nShOd86Fu" + }, + "source": [ + "from pycaret.classification import *" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YRtIVR7LC9nl" + }, + "source": [ + "https://www.kaggle.com/frtgnn/pycaret-introduction-classification-regression" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-dLwhmi9jTA" + }, + "source": [ + "### Set up" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jooY5VUr9sqd" + }, + "source": [ + "# Normalizar os nomes das colunas:\n", + "df_titanic.columns = [colunas.lower() for colunas in df_titanic.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "erqtZNz9yZ2T" + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf_IntG2ygtP" + }, + "source": [ + "### Tratamento da feature/variável fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "buRgX2rucrHT" + }, + "source": [ + "#fare_bins = ['Muito Baixo', 'Baixo', 'Medio', 'Alto', 'Muito Alto']\n", + "fare_bins = ['Baixo', 'Medio', 'Alto']\n", + "\n", + "df_titanic2 = df_titanic.copy()\n", + "\n", + "# Tratamentos necessários\n", + "\n", + "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = [0, .2, .4, .6, .8, 1], labels = fare_bins\n", + "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 5, labels = fare_bins)\n", + "df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 3, labels = fare_bins)\n", + "\n", + "#df_titanic2.drop(columns = [], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6AWpUmbE7p39" + }, + "source": [ + "df_titanic2['fare_bins'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "W0RtT6Xr9IVL" + }, + "source": [ + "clf = setup(data = df_titanic2,\n", + " target = 'survived', \n", + " numeric_imputation = 'mean', # para tratamento dos missing values\n", + " categorical_features = ['sex', 'embarked'], # lista das variáveis categóricas\n", + " ignore_features = ['name', 'ticket', 'cabin', 'passengerid'], \n", + " silent = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mGGubn7k-GNi" + }, + "source": [ + "compare_models()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4YdMCHT92Tij" + }, + "source": [ + "\tModel\tAccuracy\tAUC\tRecall\tPrec.\tF1\tKappa\tMCC\tTT (Sec)\n", + "catboost\tCatBoost Classifier\t0.8218\t0.8634\t0.7857\t0.8275\t0.8154\t0.5996\t0.6150\t1.026\n", + "gbc\tGradient Boosting Classifier\t0.8187\t0.8540\t0.7867\t0.8231\t0.8129\t0.5959\t0.6084\t0.111\n", + "lightgbm\tLight Gradient Boosting Machine\t0.8186\t0.8683\t0.7937\t0.8195\t0.8149\t0.6009\t0.6073\t0.052" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8rcs_jJFCjRW" + }, + "source": [ + "lgbm = create_model('lightgbm') " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5BdvRHPdCq0E" + }, + "source": [ + "tuned_lightgbm = tune_model(lgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WwCW_pDYI1hy" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'learning')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LES2FO1zI4X8" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'auc')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xxGQX3jbI4bN" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'confusion_matrix')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1O_9qDHgJJjw" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'feature')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W1xnpqD-46vh" + }, + "source": [ + "### Painel com todos os outputs" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PluFZQ8bI4hV" + }, + "source": [ + "evaluate_model(tuned_lightgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JaffgUyy4bwz" + }, + "source": [ + "!pip install shap" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uez4Gik8JwET" + }, + "source": [ + "interpret_model(tuned_lightgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9U2SnEKA41nW" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB15__ML_AutoML_pycaret_hs2.ipynb b/Notebooks/NB15__ML_AutoML_pycaret_hs2.ipynb new file mode 100644 index 000000000..aad4c6f9b --- /dev/null +++ b/Notebooks/NB15__ML_AutoML_pycaret_hs2.ipynb @@ -0,0 +1,317 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled8.ipynb", + "provenance": [], + "private_outputs": true, + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FfhCoyP98gDt" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "226lzu3i8kRp" + }, + "source": [ + "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n", + "df_titanic = pd.read_csv(url)\n", + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6mL0RI0V9JmP" + }, + "source": [ + "#!pip install pycaret" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WL9nShOd86Fu" + }, + "source": [ + "from pycaret.classification import *" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YRtIVR7LC9nl" + }, + "source": [ + "https://www.kaggle.com/frtgnn/pycaret-introduction-classification-regression" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3-dLwhmi9jTA" + }, + "source": [ + "### Set up" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jooY5VUr9sqd" + }, + "source": [ + "# Normalizar os nomes das colunas:\n", + "df_titanic.columns = [colunas.lower() for colunas in df_titanic.columns]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "erqtZNz9yZ2T" + }, + "source": [ + "df_titanic.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bf_IntG2ygtP" + }, + "source": [ + "### Tratamento da feature/variável fare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "buRgX2rucrHT" + }, + "source": [ + "#fare_bins = ['Muito Baixo', 'Baixo', 'Medio', 'Alto', 'Muito Alto']\n", + "fare_bins = ['Baixo', 'Medio', 'Alto']\n", + "\n", + "df_titanic2 = df_titanic.copy()\n", + "\n", + "# Tratamentos necessários\n", + "\n", + "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = [0, .2, .4, .6, .8, 1], labels = fare_bins\n", + "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 5, labels = fare_bins)\n", + "df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 3, labels = fare_bins)\n", + "\n", + "#df_titanic2.drop(columns = [], axis = 1, inplace = True)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "6AWpUmbE7p39" + }, + "source": [ + "df_titanic2['fare_bins'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "W0RtT6Xr9IVL" + }, + "source": [ + "clf = setup(data = df_titanic2,\n", + " target = 'survived', \n", + " numeric_imputation = 'mean', # para tratamento dos missing values\n", + " categorical_features = ['sex', 'embarked'], # lista das variáveis categóricas\n", + " ignore_features = ['name', 'ticket', 'cabin', 'passengerid'], # variáveis que serão ignoradas\n", + " session_id = 20111974, # Seed por questões de reproducibilidade\n", + " silent = False)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "mGGubn7k-GNi" + }, + "source": [ + "compare_models()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4YdMCHT92Tij" + }, + "source": [ + "\tModel\tAccuracy\tAUC\tRecall\tPrec.\tF1\tKappa\tMCC\tTT (Sec)\n", + "catboost\tCatBoost Classifier\t0.8218\t0.8634\t0.7857\t0.8275\t0.8154\t0.5996\t0.6150\t1.026\n", + "gbc\tGradient Boosting Classifier\t0.8187\t0.8540\t0.7867\t0.8231\t0.8129\t0.5959\t0.6084\t0.111\n", + "lightgbm\tLight Gradient Boosting Machine\t0.8186\t0.8683\t0.7937\t0.8195\t0.8149\t0.6009\t0.6073\t0.052" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8rcs_jJFCjRW" + }, + "source": [ + "lgbm = create_model('lightgbm') " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5BdvRHPdCq0E" + }, + "source": [ + "tuned_lightgbm = tune_model(lgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "WwCW_pDYI1hy" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'learning')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LES2FO1zI4X8" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'auc')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xxGQX3jbI4bN" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'confusion_matrix')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1O_9qDHgJJjw" + }, + "source": [ + "plot_model(estimator = tuned_lightgbm, plot = 'feature')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W1xnpqD-46vh" + }, + "source": [ + "### Painel com todos os outputs" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PluFZQ8bI4hV" + }, + "source": [ + "evaluate_model(tuned_lightgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JaffgUyy4bwz" + }, + "source": [ + "!pip install shap" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Uez4Gik8JwET" + }, + "source": [ + "interpret_model(tuned_lightgbm)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9U2SnEKA41nW" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB19_Redes_Neurais_hs.ipynb b/Notebooks/NB19_Redes_Neurais_hs.ipynb new file mode 100644 index 000000000..877e810cf --- /dev/null +++ b/Notebooks/NB19_Redes_Neurais_hs.ipynb @@ -0,0 +1,12378 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "accelerator": "TPU", + "colab": { + "name": "NB19_Redes_Neurais__V2.ipynb", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

REDES NEURAIS ARTIFICIAIS (COMPREHENSIVE GUIDE)

\n", + "\n", + "# Porque Cientistas de Dados desejam aprender e dominar Redes Neurais?\n", + "\n", + "* Redes Neurais têm a capacidade de aprender, modelar e resolver problemas não-lineares e complexos apresentados pela vida real.\n", + "* Você já deve ter ouvido falar em Inteligência Artificial, _self-drive cars_, _Deep Learning_, _Computer Vision_ e _Neural Language Processing_ (NLP). Todos estes assuntos estão estreitamente relacionados às Redes Neurais. Por exemplo, _Deep Learning_ são Redes Neurais com muitas _Hidden Layers_.\n", + "\n", + "Este curso aborda os principais tópicos para você dominar Redes Neurais. Além disso, vamos falar das melhores práticas e atacar as principais dúvidas dos alunos em relação às Redes Neurais. Portanto, ao final deste curso você será capaz de:\n", + "\n", + "* desenvolver suas próprias Redes Neurais;\n", + "* aplicar o algoritmo correto para cada tipo de problema;\n", + "* aplicar as funções de ativação corretamene para cada tipo de problema e camada;\n", + "* aprender o necessário de Tensorflow/Keras para Redes Neurais;\n", + "* Aprender os comandos necessários do Python/NumPy para desenvolvimento de Redes Neurais;\n", + "* aplicar a métrica ideal para cada tipo de problema;\n", + "* entender como as Redes Neurais aprendem (_Backpropagation_);\n", + "\n", + "# **AGENDA**\n", + "\n", + "* Introdução às Redes Neurais;\n", + "* _Activation Function_;\n", + "* _Loss Function_;\n", + "* Métricas para medir a performance das Redes Neurais;\n", + "* _Dropout_;\n", + "* _Backpropagation_;\n", + "* _Gradient Descent_;\n", + "* _Perceptron_ (Redes Neurais com 1 única camada);\n", + "* Exemplo 1: Redes Neurais _Perceptron_ para os operadores lógicos E, OU e XOR;\n", + "* Redes Neurais Multicamada;\n", + "* Exemplo prático: Rede Neural para identificar o sexo a partir de peso e altura;\n", + "* Aplicações de Rede Neural:\n", + " * Aplicação 1 - Rede Neural para identificar espécies de flores (Iris Dataframe);\n", + " * Aplicação 2 - Rede Neural para identificar o tipo do vinho (_Red or White_);\n", + " * Aplicação 3 - Rede Neural para identificar Câncer de Mama (_Breast Cancer_ Dataframe);\n", + " * Aplicação 4 - Rede Neural para identificar Diabetes (Diabetes Dataframe);\n", + " * Aplicação 5 - Rede Neural para prever os preços das casas em Boston (_Boston House Price Prediction_)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "\n", + "1. Contemplar o uso de StratifiedKFold;\n", + "2. Inserir aqui o exemplo das notas falsas, enviado pela Mónica;\n", + "3. Deixar alguma coisa que foi resolvida como exercício.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)\n", + "- [Forward propagation in neural networks — Simplified math and code version](https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250)\n", + "- [Understanding Neural Networks: From Activation Function To Back Propagation](https://medium.com/fintechexplained/neural-networks-activation-function-to-back-propagation-understanding-neural-networks-bdd036c3f29f)\n", + "- [Understanding Gradient Descent](https://medium.com/analytics-vidhya/understanding-gradient-descent-8dd88a4c60e6) - Explica detalhadamente como funciona o _Gradient Descent_ no processo de otimização dos pesos $W$;\n", + "- [Backpropagation step by step](https://medium.com/swlh/backpropagation-step-by-step-13f2b6c0b414) - Eu usei esse artigo para reajustar os pesos $W$;\n", + "- [Perceptron Learning Algorithm: A Graphical Explanation Of Why It Works](https://towardsdatascience.com/perceptron-learning-algorithm-d5db0deab975);\n", + "- [Math behind Perceptrons](https://medium.com/@iamask09/math-behind-perceptrons-7241d5dadbfc);\n", + "- [Neural Network: A Complete Beginners Guide from Scratch](https://medium.com/gadictos/neural-network-a-complete-beginners-guide-from-scratch-cf1fc9d5cd12);\n", + "- [Calculating the Backpropagation of a Network](https://medium.com/towards-artificial-intelligence/calculating-back-propagation-of-a-network-1febbcaa2b5d);\n", + "- [Let’s build a simple Neural Net!](https://becominghuman.ai/lets-build-a-simple-neural-net-f4474256647f) - O autor constroi uma Rede Neural simples, sem _Hidden Layers_;\n", + "- [Coding Neural Network — Forward Propagation and Backpropagtion](https://towardsdatascience.com/coding-neural-network-forward-propagation-and-backpropagtion-ccf8cf369f76);\n", + "- [The Simplest Neural Network: Understanding the non-linearity](https://towardsdatascience.com/the-simplest-neural-network-understanding-the-non-linearity-10846d7d0141) - Ótimo texto para entender a não-linearidade;\n", + "- [Implementing the XOR Gate using Backpropagation in Neural Networks](https://towardsdatascience.com/implementing-the-xor-gate-using-backpropagation-in-neural-networks-c1f255b4f20d) - Usei este texto para resolver o problema do XOR;\n", + "- [Neural Representation of AND, OR, NOT, XOR and XNOR Logic Gates (Perceptron Algorithm)](https://medium.com/@stanleydukor/neural-representation-of-and-or-not-xor-and-xnor-logic-gates-perceptron-algorithm-b0275375fea1) - Eu usei este material para resolver o problema dos operadores E, OU e XOR;\n", + "- [Solving XOR with a single Perceptron](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182);\n", + "- [Machine Learning 101 — Artificial Neural Networks](https://towardsdatascience.com/machine-learning-101-artificial-neural-networks-3-46ccb04cba30) - Cálculos realizados passo a passo;\n", + "- [Neural Network from scratch in Python](https://towardsdatascience.com/math-neural-network-from-scratch-in-python-d6da9f29ce65) - Este artigo mostra a matemática por trás das Redes Neurais;\n", + "- [Classical Neural Net: Why/Which Activations Functions?](https://towardsdatascience.com/classical-neural-net-why-which-activations-functions-401159ba01c4) - Artigo que discute as principais funções de ativação;\n", + "- [Understanding Activation Functions in Neural Networks](https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0);\n", + "- [Mind: How to Build a Neural Network (Part One)](https://becominghuman.ai/mind-how-to-build-a-neural-network-part-one-67b6aea4ce20);\n", + "- [How to build a simple Neural Network from scratch with Python](https://towardsdatascience.com/how-to-build-a-simple-neural-network-from-scratch-with-python-9f011896d2f3);\n", + "- [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a);\n", + "- [MAE and RMSE — Which Metric is Better?](https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d) - Ótimo artigo, pois discute qual métrica é melhor.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2StZkTpOZbYo" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING DEVELOPMENT LYFECYCLE**\n", + "\n", + "CRISP-DM significa _Cross Industry Standard Process for Data Mining_ ou processos ou fases para desenvolvimento de projetos relacionados à _Data Mining_ e que tem sido muito utilizados pelos Cientistas de Dados para desenvolvimento de modelos predictivos.\n", + "\n", + "\"Drawing\"\n", + "\n", + "Fonte: [The steps to a successful machine learning project](https://emba.epfl.ch/2018/04/10/steps-successful-machine-learning-project/)\n", + "\n", + "Sugiro a leitura do artigo [Why using CRISP-DM will make you a better Data Scientist](https://towardsdatascience.com/why-using-crisp-dm-will-make-you-a-better-data-scientist-66efe5b72686)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO ÀS REDES NEURAIS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "* Redes Neurais aprendem com as experiências passadas, imitando o funcionamento dos neurônios humanos no processo de aprendizagem;\n", + "* podem e são amplamente utilizadas nas seguintes situações (aplicações):\n", + " * Reconhecimento Facial;\n", + " * Processamento de Linguagem Natural (NLP);\n", + " * _Self-drive car_;\n", + " * Visão computacional;\n", + " * Detecção de padrões (doenças, tumores e etc) em imagens;\n", + "* Ideal para o cenário onde temos muitos dados (_Big Data_) e para resolver problemas complexos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VzylPHA7BP0x" + }, + "source": [ + "___\n", + "# **_PERCEPTRON_** (Rede Neural com 1 única camada)\n", + "\n", + "* **_PERCEPTRON_** é um algoritmo de _Machine Learning_ da classe _Supervised Learning_ para classificação binária, inventado em 1958 por Frank Rosenblatt;\n", + "* Arquitetura de Rede Neural mais simples existente, com 1 única camada;\n", + "\n", + "**Daí, uma pergunta importante**: Se _Perceptron_ é um tipo de Rede Neural simples que nasceu na década de 1950, então porque devemos estudá-la? Porque não focar no estudo de Redes Neurais mais complexas e atuais?\n", + "\n", + "*E a resposta é**: porque _Perceptron_ nos permite entender claramente os aspectos matemáticos das Redes Neurais. Com isso quero dizer que ao entendermos _Perceptrons_, fica mais fácil entender outros tipos de Redes Neurais." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M5YNraza6jum" + }, + "source": [ + "## Exemplo de Perceptron\n", + "\n", + "A seguir, arquitetura do _Perceptron_: várias entradas (_Inputs_) e 1 camada de saída (_Output Layer_) binária (0 ou 1).\n", + "\n", + "* OL significa **O**utput **L**ayer ==> Valor que queremos estimar, ou seja, $\\hat{y}$.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_5LVgImx78xY" + }, + "source": [ + "A **FUNÇÃO DE ATIVAÇÃO** $f(S)$ acima é conhecida como **_STEP FUNCTION_** e como podemos ver, retorna uma resposta binária (0 ou 1) que depende do valor de $S$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "84zFWve4FkcY" + }, + "source": [ + "A seguir, implementação usando NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htVV-GpgBnw3" + }, + "source": [ + "[**Python**] - Importar o NumPy:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xBYyZ5ZiByH4" + }, + "source": [ + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-8sR77a4B8Uf" + }, + "source": [ + "[**Python**] - Definir o número de casas decimas para 3:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gj2dioDTaZl-" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oZ6Sw4uuCggF" + }, + "source": [ + "[**Python**] - Definir os pesos $W$ e as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "z2m6BxQ_DLFV" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.1, 0.3, 0.2, 0.4])\n", + "\n", + "# Entradas X:\n", + "X = np.array([1, -3, 2, 3])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lBnZP5MKCg8m" + }, + "source": [ + "[**Python**] - Desenvolver a função soma $S$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMGuWhAhDaim" + }, + "source": [ + "def Soma(X, W):\n", + " S = X.dot(W) # Faz a seguinte operação: S = X1*W1 + X2*W2 + X3*W3 + X4*W4\n", + " return S" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EMxMJ05kDhmi" + }, + "source": [ + "[**Python**] - Desenvolver a função de ativação _Step Function_ $f(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dRLYPJl0aZmg" + }, + "source": [ + "def ativacao_StepFunction(S):\n", + " if S >= 1:\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H4g85O2jDu6S" + }, + "source": [ + "[**Python**] - Calcular $S = Soma(X, W)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zoUMvvzlaZm-", + "outputId": "07b3e65a-176f-4309-beab-24595ccb5f4d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "S = Soma(X, W)\n", + "S" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.8000000000000003" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6LzlyDNaD5yB" + }, + "source": [ + "[**Python**] - Calcular $f(S)$, ou seja, $f = ativacao_StepFunction(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IIe4vIjaZnE", + "outputId": "ba253dca-9955-4eea-8015-eaf002413935", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f = ativacao_StepFunction(S)\n", + "f" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UrRG8e8dDTc_" + }, + "source": [ + "# **EXEMPLO 1: DESENVOLVER UMA REDE NEURAL _PERCEPTRON_ PARA OS OPERADORES LÓGICOS E, OU E XOR**\n", + "\n", + "Os exemplos a seguir foram inspirados e adaptado de:\n", + "* [Perceptron: Theory and Practice](https://medium.com/data-alchemist/perceptron-theory-and-practice-e71733ed3fa5)\n", + "* [The Perceptron — A Building Block of Neural Networks](https://blog.usejournal.com/the-perceptron-the-building-block-of-neural-networks-5a428d3f451d) - Este artigo mostra detalhadamente os cálculos\n", + "* [Mind: How to Build a Neural Network (Part One)](https://becominghuman.ai/mind-how-to-build-a-neural-network-part-one-67b6aea4ce20)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qeZBP3TQN2_1" + }, + "source": [ + "## Exemplo 1.1: Rede Neural _Perceptron_ para o Operador Lógico E\n", + "\n", + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 |\n", + "| 2 | 1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "O dataframe acima representa o operador lógico E (https://en.wikipedia.org/wiki/Truth_table):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | F |\n", + "| 2 | T | F | F |\n", + "| 3 | T | T | T |\n", + "\n", + "\n", + "Considere $W= [W_{1}, W_{2}]= (0, 0)$ como pesos iniciais e a função de ativação $F(S)$ _Step Function_ dada abaixo:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "psJh-MUgFAge" + }, + "source": [ + "A seguir, os cálculos manuais da primeira iteração:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8x3EvFUQBsU" + }, + "source": [ + "Os Erros $E_{i}$ são calculados com a fórmula: $E_{i}= ValorReal_{i} - ValorCalculado_{i}= y_{i}-\\hat{Y}_{i}$. A seguir, resumo dos cálculos:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d5dryrbGBesj" + }, + "source": [ + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | Soma | ValorCalculado ($\\hat{Y}_{i}$) | Erro |\n", + "|---|---|---|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 | 0 | 0 | 0 |\n", + "| 2 | 1 | 0 | 0 | 0 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 | 0 | 0 | 1 |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkcRy2RYGLVw" + }, + "source": [ + "### Erro Total ($E_{T}$)\n", + "\n", + "$$E_{T}= \\sum_{i=1}^{n}E_{i}= E_{1}+E_{2}+...+E_{n}$$\n", + "\n", + "No nosso caso, temos que $E_{T}= 0+0+0+1= 1$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fzVxmr9OTfGB" + }, + "source": [ + "### Fórmula para ajustar os pesos $W$\n", + "A fórmula a seguir será utilizada para ajustar os pesos $W$:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z1bEDxMhToIj" + }, + "source": [ + "### Taxa de Aprendizagem ($\\alpha$)\n", + "* $\\alpha$ é a taxa de aprendizado (_Learning Rate_ em inglês) e diz respeito à velocidade de aprendizagem da Rede Neural.\n", + " * Quanto MENOR o valor de $\\alpha$ $\\Longrightarrow$ mais devagar e demorada será a convergência para o mínimo global;\n", + " * Quanto MAIOR o valor de $\\alpha$ $\\Longrightarrow$ mais rápido será a convergência para o mínimo, **mas sem a garantia de convergência para o mínimo global**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "drGfgCIZY4aV" + }, + "source": [ + "Para ajustar os pesos $W$, vamos utilizar $\\alpha= 0.1$. Fórmula:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n", + "\n", + "A seguir, os novos pesos $W$ para a próxima iteração da Rede Neural _Perceptron_:\n", + "\n", + "\\begin{align}\n", + "W_{1}&= 0+ 0.1*1*1= 0.1 \\\\\n", + "W_{2}&= 0+ 0.1*1*1= 0.1 \\\\\n", + "\\end{align}\n", + "\n", + "Portanto, na próxima iteração vamos utilizar os pesos $W= [W_{1}, W_{2}]= [0.1, 0.1]$. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "33xLPLo-Pq0Y" + }, + "source": [ + "A seguir, os cálculos manuais para a segunda iteração da Rede Neural:\n", + "\n", + "Função de ativação $f(S)$ _Step Function_:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i3EsH8pN9wJ6" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZiiOu1AyW2N" + }, + "source": [ + "A seguir resumo dos cálculos para a segunda iteração:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | Soma | ValorCalculado ($\\hat{Y}_{i}$) | Erro |\n", + "|---|---|---|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 | 0.0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 | 0.1 | 0 | 0 |\n", + "| 2 | 1 | 0 | 0 | 0.1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 | 0.2 | 0 | 1 |\n", + "\n", + "Daí, $E_{T}= 0+0+0+1= 1$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MAXO38uqUobn" + }, + "source": [ + "### Ajuste dos pesos $W$\n", + "Fórmula para ajustar $W$:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n", + "\n", + "A seguir, os novos pesos $W$ para a próxima iteração da Rede Neural _Perceptron_:\n", + "\n", + "\\begin{align}\n", + "W_{1}&= 0.1+ 0.1*1*1= 0.2 \\\\\n", + "W_{2}&= 0.1+ 0.1*1*1= 0.2 \\\\\n", + "\\end{align}\n", + "\n", + "Portanto, na próxima iteração vamos utilizar os pesos $W= [W_{1}, W_{2}]= [0.2, 0.2]$. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WX48iRa5VLyk" + }, + "source": [ + "Esse processo iterativo é realizado até que se encontre os pesos $W$ que nos dê 100% de acurácia. A título de exemplo, considere $W= [W_{1}, W_{2}]= [0.5, 0.5]$:\n", + "\n", + "Função de ativação $f(S)$ _Step Function_:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LZfroCc994oz" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McKYXohzXzzA" + }, + "source": [ + "Como podem ver, o Erro Total $E_{T}= 0$, pois temos 100% de acertos (acurácia) usando $W= [W_{1}, W_{2}]= [0.5, 0.5]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wp_tR7h0btDm" + }, + "source": [ + "### Implementar o **_PERCEPTRON_** no Python usando NumPy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3ix5vCKaEWdx" + }, + "source": [ + "[**Python**] - Importar NumPy:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x62R_y89ElPA" + }, + "source": [ + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SYvLGlgZEXWu" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yEScd0_LEtJc" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8hLz6GAEYCo" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fD66QeoqXEU3" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [0], [0], [1]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "alRRwxsUvIU6", + "outputId": "f37feaf6-e705-4afe-fae2-546423672321", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VB5n2WNUvND3", + "outputId": "65b497ff-e838-4bad-961c-2c0d761c51ab", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [0],\n", + " [0],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2jH1EMfdEYwN" + }, + "source": [ + "[**Python**] - Definir a Taxa de Aprendizagem $\\alpha$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zd2k0S-BXEU_" + }, + "source": [ + "alpha = 0.1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yvGa7d8LEZD2" + }, + "source": [ + "[**Python**] - Desenvolver a função para treinar a Rede Neural\n", + "> Esta função tenta encontrar os pesos $W$ que levem a 100% de acurácia." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JVl0XwBuXEVC" + }, + "source": [ + "def Treinar_RNA(X, Y, W, alpha):\n", + " ET= 1 # ET= Erro Total\n", + " N= 0\n", + " while ((ET != 0) and (N < 100)):\n", + " ET= 0\n", + " for i in range(len(Y)):\n", + " S = X[i].dot(W)\n", + " f = ativacao_StepFunction(S)\n", + " E= Y[i]-f\n", + " ET+= E\n", + " for j in range(len(W)):\n", + " W[j]= W[j] + alpha*(X[i][j]*E)\n", + " print(f'Peso Ajustado: {W[j]}')\n", + " print(f'Erro Total: {ET}')\n", + " N+= 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pdI7EHnFF4yo" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gHM5tXEdXEVF", + "outputId": "425fe3b6-38e3-4152-d9fb-938290be5cf1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Erro Total: [0]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TPKEML9cDD0E" + }, + "source": [ + "## Exemplo 1.2: Rede Neural _Perceptron_ para o Operador Lógico OU\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rSQnOjDWC7Ta" + }, + "source": [ + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "O dataframe acima representa o operador lógico OU (https://en.wikipedia.org/wiki/Truth_table):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | T |\n", + "| 2 | T | F | T |\n", + "| 3 | T | T | T |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kID13PxSGN6h" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CmuuIX2PGN6l" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [1], [1], [1]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UDzdS6FX2LOC", + "outputId": "f0d325ca-56ff-4a80-bfe6-391e18f69c0f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ar0dk1eQ2MOD", + "outputId": "3cfefde8-78d4-45c2-beb1-7410e61a6006", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "agZX698KGeVK" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3GF_W4u0GeVM", + "outputId": "2a58bc18-8d9f-435c-92b4-75d03270e8cc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Erro Total: [3]\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [3]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.6\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.7999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.8999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 0.9999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Erro Total: [2]\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Peso Ajustado: 1.0999999999999999\n", + "Erro Total: [0]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u2dZAVVFEpCw" + }, + "source": [ + "## Exemplo 1.3: Rede Neural _Perceptron_ para o Operador Lógico XOR\n", + "\n", + "Problema proposto e demonstrado por Rumelhart et al. (1985)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EaZIyvvEEpC5" + }, + "source": [ + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |\n", + "\n", + "O dataframe acima representa o operador lógico XOR (https://pt.wikipedia.org/wiki/Ou_exclusivo):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | T |\n", + "| 2 | T | F | T |\n", + "| 3 | T | T | F |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7rc3hc2RGneF" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u8fAgk3RGneH" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [1], [1], [0]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tFKaIhua3Mr6", + "outputId": "7c4b2fbd-e002-44bb-eedd-ae5ac76ad9bc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pm-X-dXX3NZW", + "outputId": "6add62ed-22a1-4fcd-f9b5-430b17f921de", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "znRL2XozGneM" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "j8leYHZVGneM", + "outputId": "d5fd8c92-ffe6-4a63-9019-fdedd7bb5b96", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.0\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.1\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.2\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.30000000000000004\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [2]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.5\n", + "Peso Ajustado: 0.4\n", + "Peso Ajustado: 0.4\n", + "Erro Total: [1]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1Eu5cVvxM60i" + }, + "source": [ + "## Porque conseguimos pesos $W$ para os Operadores Lógicos E e OU e não para XOR?\n", + "\n", + "* Operadores E e OR: Linearmente Separáveis;\n", + "* Operador XOR: Linearmente NÃO-Separável.\n", + "\n", + "[Lucas Araújo](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182) diz em seu artigo [Solving XOR with a single Perceptron](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182) que:\n", + "\n", + "\"Everyone who has ever studied about neural networks has probably already read that a single perceptron can’t represent the boolean XOR function. The book Artificial Intelligence: A Modern Approach, the leading textbook in AI, says: “[XOR] is not linearly separable so the perceptron cannot learn it”.\n", + "\n", + "As figuras abaixo demonstram clarmente os conceitos \"linearmente separáveis\" e \"NÃO-linearmente separável\"." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oUrFCMUjFtR1" + }, + "source": [ + "### Representação gráfica do Operador Lógico E\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 |\n", + "| 2 | 1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n9v07MdMF42e" + }, + "source": [ + "### Representação gráfica do Operador Lógico OU\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "56Qp1J6LGBe9" + }, + "source": [ + "### Representação gráfica do Operador Lógico XOR\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eaQm7zZJbNAc" + }, + "source": [ + "___\n", + "# **O QUE APRENDEMOS ATÉ AQUI?**\n", + "\n", + "* Redes Neurais tentam ajustar os pesos $W$ para tentar melhorar a taxa de acerto. Ou seja, a Rede Neural aprende com os dados através do ajuste iterativo dos pesos $W$;\n", + "* Treinar uma Rede Neural é uma tarefa computacionalmente intensivo, pois o algoritmo tenta encontrar os pesos $W$ que apresentam melhor acurácia. Para um dataframe grande, o custo conputacional do aprendizado pode ser alto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f_T35rXZOB4G" + }, + "source": [ + "___\n", + "# **REDES NEURAIS MULTICAMADA**\n", + "\n", + "* Pelo menos 1 _Hidden Layer_. Observe a Rede Neural a seguir contendo 20 neurônios distribuídos da seguinte forma:\n", + "\n", + " * Número de neurônios na camada de entrada (_Input Layer_): 4;\n", + " * 3 camadas escondidas (_Hidden Layers_) com 5 neurônios cada, totalizando 15 neurônios:\n", + " * Número de neurônios na _Hidden Layer 1_: 5;\n", + " * Número de neurônios na _Hidden Layer 2_: 5;\n", + " * Número de neurônios na _Hidden Layer 3_: 5;\n", + " * Número de neurônios na camada de saída (_Output Layer_): 1;\n", + "* _Fully connected layer_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1dXBXuh2-Tuo" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BK4O_Y_l2vev" + }, + "source": [ + "## Função _Sigmoid_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M_nn8zELXEVf" + }, + "source": [ + "\"Drawing\"\n", + "\n", + "Consulte [e (constante matemática)](https://pt.wikipedia.org/wiki/E_(constante_matem%C3%A1tica)) para saber mais sobre a constante de Euler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kOWwWR7hOmir" + }, + "source": [ + "## Número de _Hidden Layers_\n", + "\n", + "Pesquisadores apontam que 1 única _Hidden Layer_ é suficiente para a grande maioria dos problemas e que usualmente cada _Hidden Layer_ possui o mesmo número de neurônios. Experimentos mostram que mais _Hidden Layers_ implica em maior tempo para treinar a Rede Neural. No entanto, [Heaton Research](https://www.heatonresearch.com/2017/06/01/hidden-layers.html), mostra que:\n", + "\n", + "![Determinining_number_Hidden_Layers](https://github.com/MathMachado/Materials/blob/master/Determinining_number_Hidden_Layers.png?raw=true)\n", + "\n", + "Fonte: [Heaton Research](https://www.heatonresearch.com/2017/06/01/hidden-layers.html).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4_1JCbcPRrn" + }, + "source": [ + "## Número de neurônios na camada de entrada (_Input Layer_): $N_{I}$\n", + "\n", + "$N_{I}$= Número de colunas (ou variáveis) no dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fk-lhwhffUZz" + }, + "source": [ + "### Número de neurônios na camada de saída (_Output Layer_): $N_{O}$\n", + "\n", + "* Se a Rede Neural é uma regressão, então o número de neurônios na _Output Layer_ é 1, pois o _output_ de uma regressão é um valor;\n", + "* Se a Rede Neural é uma classificação e usamos uma função de ativação probabilística (como _softmax_, por exemplo), então o número de neurônios na _Output Layer_ é igual ao número de classes que queremos prever. Por exemplo, no problema de classificar espécies no dataframe IRIS temos 3 espécies (versicolor, virginica e setosa). Ao utilizarmos a função de ativação _softmax_, então teremos 3 neurônios na _Output Layer_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsrrdLpSfYm9" + }, + "source": [ + "## Número de neurônios na camada escondida (_Hidden Layer_): $N_{H}$\n", + "\n", + "Determinar o número de neurônios na _Hidden Layer_ tem sido um exercício de tentativa e erro, mas alguns experimentos tem demonstrado que o número adequado de neurônios na _Hidden Layer_ pode ser obtido através da expressão a seguir:\n", + "\n", + "$$N_{H}= \\frac{N_{I}+N_{O}}{2}$$\n", + "\n", + "No entanto, o artigo [How to choose the number of hidden layers and nodes in a feedforward neural network?](https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw) sugere o uso da seguinte expressão:\n", + "\n", + "$$N_H= \\frac{N}{\\alpha(N_{I}+N_{O})}$$\n", + "\n", + "onde $N$ é o número de instâncias (linhas) do dataframe e $\\alpha$ é um número entre 2 e 10, sendo que alguns experimentos com $\\alpha= 2$ produzem bons modelos sem _overfitting_. Para saber mais sobre esta expressão e sobre $\\alpha$, sugiro a leitura do artigo mencionado." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rj6WfilbShX3" + }, + "source": [ + "## Rede Neural Multicamada para o Operador Lógico XOR.\n", + "\n", + "Dataframe que representa o Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uURlcU78LwbH" + }, + "source": [ + "### Arquitetura da Rede Neural Multicamada que vamos desenvolver para o Operador Lógico XOR\n", + "\n", + "Os pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$ serão gerados aleatoriamente. A seguir, a arquitetura da Rede Neural com 1 _Hidden Layer_ contendo 3 neurônios:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6XKMdlZr-e9l" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AV2eUQDuLCUL" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uTWYP0V-LGHj" + }, + "source": [ + "import math\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-DG86PgxLDQA" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jsvh5DOkXEVm" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NYIMcp8TLVuq" + }, + "source": [ + "[**Python**] - Definir as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U6Mt6zTnXEVq", + "outputId": "67d81400-0c90-42c5-bb92-52421801aaba", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n", + "X" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 3 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tXLd1nZxLbXD" + }, + "source": [ + "[**Python**] - Definir os _Outputs_ $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Oauq3veAXEVu", + "outputId": "faa3a8cc-7d87-4736-973e-15c36dbcda15", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y = np.array([[0], [1], [1], [0]])\n", + "Y" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 4 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TC1y0tO1MAU9" + }, + "source": [ + "### Gerar os pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$ aleatoriamente\n", + "\n", + "Por questões de reproducibilidade de resultados, vamos usar as sementes a seguir para gerar os pesos $W_{H}$ e $W_{O}$:\n", + "\n", + "* _seed_= 20111974 para gerar $W_{H}$;\n", + "* _seed_= 19741120 para gerar $W_{O}$.\n", + "\n", + "Ao usarmos estas sementes, deveremos ter $W_{H}= \\begin{bmatrix} 0.531 & 0.570 & 0.543 \\\\ 0.655 & 0.857 & 0.602 \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} 0.240 \\\\ 0.318 \\\\ 0.142 \\end{bmatrix}$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_U3Id5XXG5tw" + }, + "source": [ + "[**Python**] - Sementes para gerar $W_{H}$ (aleatoriamente)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tVXiIpgIHId9" + }, + "source": [ + "np.random.seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XYj0NYofHKkk" + }, + "source": [ + "[**Python**] - Gerar os pesos $W_{H}$ (aleatoriamente)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o1eGsPNQXEVx", + "outputId": "12f09198-1e15-4b8b-c089-23172f243b10", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "W_H = np.array([np.random.random(3), np.random.random(3)])\n", + "W_H" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.531, 0.57 , 0.543],\n", + " [0.655, 0.857, 0.602]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cj6KJnP3Hbqf" + }, + "source": [ + "[**Python**] - Sementes para gerar $W_{O}$ (aleatoriamente):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkVw-SWSHbqh" + }, + "source": [ + "np.random.seed(19741120)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r7ZjUT4oHbqk" + }, + "source": [ + "[**Python**] - Gerar os pesos $W_{O}$ (aleatoriamente):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ebs8p8mOXEV1", + "outputId": "1d2dd115-3cbb-48a7-ff99-274747e8a0ba", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "W_O = np.array([np.random.random(1), np.random.random(1), np.random.random(1)])\n", + "W_O" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.24 ],\n", + " [0.318],\n", + " [0.142]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vg1ByKjKsWcE" + }, + "source": [ + "Confira os pesos dispostos na figura a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GiEc1DwPt7Hm" + }, + "source": [ + "### Calcular $S = \\sum_{i=1}^{4}X_{i}W_{i}$ e passar o valor de $S$ para a função de ativação $f(S)$ (_Sigmoid_)\n", + "\n", + "Função _Sigmoid_:\n", + "\n", + "$$f(x)= y= \\frac{1}{1+e^{-x}}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mCZsXjIhHqId" + }, + "source": [ + "[**Python**] - Definir a função de ativação $Sigmoid$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kB4-UnOGXEV8" + }, + "source": [ + "def FuncaoAtivacao_Sigmoid(x):\n", + " y = 1/(1+np.exp(-x))\n", + " return y" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XkvMHw1KHrjT" + }, + "source": [ + "[**Python**] - Função MostraCalculos, desenvolvida para validarmos os cálculos manuais de $S$ e $f(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsxHrthYXEWA" + }, + "source": [ + "def MostraCalculos(i):\n", + " print(f'Array W:\\n {W_H}')\n", + " print('\\n')\n", + " print(f'Array X:\\n {X[i]}')\n", + " S = X[i].dot(W_H)\n", + " f = FuncaoAtivacao_Sigmoid(S)\n", + " S2= f.dot(W_O)\n", + " f2= FuncaoAtivacao_Sigmoid(S2)\n", + " \n", + " print('\\n')\n", + " print(f'*** HIDDEN LAYER ***')\n", + " print(f'Função Soma S: {S}')\n", + " print(f'Função de Ativação Sigmoid: {f}')\n", + " \n", + " print('\\n')\n", + " print(f'*** OUTPUT LAYER ***')\n", + " print(f'Função Soma S: {S2}')\n", + " print(f'Função de Ativação Sigmoid: {f2}')\n", + " \n", + " print('\\n')\n", + " print(f'*** ERRO ***')\n", + " E= Y[i]-f2\n", + " print(f'Erro da linha i= {i}: {E}')\n", + " \n", + " return f " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s80knPTzcIBy" + }, + "source": [ + "___\n", + "O Operador A.dot(B) faz o produto matricial entre os arrays A e B. Para saber mais sobre a função dot(), assista este [vídeo](https://youtu.be/Pb1VIe9657s)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bw0p2m8mbz3C" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 0$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CelKhuoHISyS" + }, + "source": [ + "[**Python**] - Evocar a função f0= MostraCalculos(0):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ar0zOLuUIio1", + "outputId": "4391ee79-2442-4d2e-e625-246838ca7394", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f0 = MostraCalculos(0)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Array W:\n", + " [[0.531 0.57 0.543]\n", + " [0.655 0.857 0.602]]\n", + "\n", + "\n", + "Array X:\n", + " [0 0]\n", + "\n", + "\n", + "*** HIDDEN LAYER ***\n", + "Função Soma S: [0. 0. 0.]\n", + "Função de Ativação Sigmoid: [0.5 0.5 0.5]\n", + "\n", + "\n", + "*** OUTPUT LAYER ***\n", + "Função Soma S: [0.35]\n", + "Função de Ativação Sigmoid: [0.587]\n", + "\n", + "\n", + "*** ERRO ***\n", + "Erro da linha i= 0: [-0.587]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_R1LdY9QvTqb" + }, + "source": [ + "Observe na figura abaixo os cálculos manuais da Soma $S$, função de ativação $f(S)$ e Erro." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hl_RBLiaa4xS" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NOKtMLHoo_Yt" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(0, 1)} &= (0)(0.531)+(0)(0.655)= 0 \\Longrightarrow f_{H}^{(0, 1)}(S_{H}^{(0, 1)})= f_{H}^{(0, 1)}(0)= 0.5 \\\\\n", + "S_{H}^{(0, 2)} &= (0)(0.570)+(0)(0.857)= 0 \\Longrightarrow f_{H}^{(0, 2)}(S_{H}^{(0, 2)})= f_{H}^{(0, 2)}(0)= 0.5 \\\\\n", + "S_{H}^{(0, 3)} &= (0)(0.543)+(0)(0.602)= 0 \\Longrightarrow f_{H}^{(0, 3)}(S_{H}^{(0, 3)})= f_{H}^{(0, 3)}(0)= 0.5\n", + "\\end{align}\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Kw-cakYsQGp" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(0)}&= (0.5)(0.24)+(0.5)(0.318)+(0.5)(0.142)= 0.35 \\\\\n", + "f_{O}^{(0)}(S_{O}^{(0)})&= f_{O}^{(0)}(0.35)= 0.587 \\\\\n", + "E_{0}&= 0-0.587= -0.587\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TFZ8w1dUdT7A" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 1$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wTz3EfAUIoz-" + }, + "source": [ + "[**Python**] - Evocar a função f1= MostraCalculos(1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "INUDJ_aMXEWb", + "outputId": "a437faf7-fa53-4146-c2ca-5ac2c50124bc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f1 = MostraCalculos(1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Array W:\n", + " [[0.531 0.57 0.543]\n", + " [0.655 0.857 0.602]]\n", + "\n", + "\n", + "Array X:\n", + " [0 1]\n", + "\n", + "\n", + "*** HIDDEN LAYER ***\n", + "Função Soma S: [0.655 0.857 0.602]\n", + "Função de Ativação Sigmoid: [0.658 0.702 0.646]\n", + "\n", + "\n", + "*** OUTPUT LAYER ***\n", + "Função Soma S: [0.473]\n", + "Função de Ativação Sigmoid: [0.616]\n", + "\n", + "\n", + "*** ERRO ***\n", + "Erro da linha i= 1: [0.384]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I91qgS1Uh2T1" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDuyxsKSvDds" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(1, 1)} &= (0)(0.531)+(1)(0.655)= 0.655 \\Longrightarrow f_{H}^{(1, 1)}(S_{H}^{(1, 1)})= f_{H}^{(1, 1)}(0.655)= 0.658 \\\\\n", + "S_{H}^{(1, 2)} &= (0)(0.570)+(1)(0.857)= 0.857 \\Longrightarrow f_{H}^{(1, 2)}(S_{H}^{(1, 2)})= f_{H}^{(1, 2)}(0.857)= 0.702 \\\\\n", + "S_{H}^{(1, 3)} &= (0)(0.543)+(1)(0.602)= 0.602 \\Longrightarrow f_{H}^{(1, 3)}(S_{H}^{(1, 3)})= f_{H}^{(1, 3)}(0.602)= 0.646\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nKPsQA9dvDdt" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(1)}&= (0.658)(0.24)+(0.702)(0.318)+(0.646)(0.142)= 0.473 \\\\\n", + "f_{O}^{(1)}(S_{O}^{(1)})&= f_{O}^{(1)}(0.473)= 0.616 \\\\\n", + "E_{1}&= 1-0.616= 0.384\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IBfztHLfeoTR" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 2$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sjcpG53tIvHf" + }, + "source": [ + "[**Python**] - Evocar a função f2= MostraCalculos(2):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RbnG_WxdXEWg", + "outputId": "b81e7106-e5fe-4518-8852-18253ef06354", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f2 = MostraCalculos(2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Array W:\n", + " [[0.531 0.57 0.543]\n", + " [0.655 0.857 0.602]]\n", + "\n", + "\n", + "Array X:\n", + " [1 0]\n", + "\n", + "\n", + "*** HIDDEN LAYER ***\n", + "Função Soma S: [0.531 0.57 0.543]\n", + "Função de Ativação Sigmoid: [0.63 0.639 0.632]\n", + "\n", + "\n", + "*** OUTPUT LAYER ***\n", + "Função Soma S: [0.444]\n", + "Função de Ativação Sigmoid: [0.609]\n", + "\n", + "\n", + "*** ERRO ***\n", + "Erro da linha i= 2: [0.391]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9g9MegqIh-Vn" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5gES50aaxszM" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(2, 1)} &= (1)(0.531)+(0)(0.655)= 0.531 \\Longrightarrow f_{H}^{(2, 1)}(S_{H}^{(2, 1)})= f_{H}^{(2, 1)}(0.531)= 0.630 \\\\\n", + "S_{H}^{(2, 2)} &= (1)(0.570)+(0)(0.857)= 0.570 \\Longrightarrow f_{H}^{(2, 2)}(S_{H}^{(2, 2)})= f_{H}^{(2, 2)}(0.570)= 0.639 \\\\\n", + "S_{H}^{(2, 3)} &= (1)(0.543)+(0)(0.602)= 0.543 \\Longrightarrow f_{H}^{(2, 3)}(S_{H}^{(2, 3)})= f_{H}^{(2, 3)}(0.543)= 0.632\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7n4Eq-6xszP" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(2)}&= (0.630)(0.24)+(0.639)(0.318)+(0.632)(0.142)= 0.444 \\\\\n", + "f_{O}^{(2)}(S_{O}^{(2)})&= f_{O}^{(2)}(0.444)= 0.609 \\\\\n", + "E_{2}&= 1-0.609= 0.391\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cPJQKwBthCkh" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 3$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MVhEsrqJI1T7" + }, + "source": [ + "[**Python**] - Evocar a função f3= MostraCalculos(3):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qU87GWKjXEWo", + "outputId": "5df8df11-feaf-464f-af78-f0f7819f56dd", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f3 = MostraCalculos(3)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Array W:\n", + " [[0.531 0.57 0.543]\n", + " [0.655 0.857 0.602]]\n", + "\n", + "\n", + "Array X:\n", + " [1 1]\n", + "\n", + "\n", + "*** HIDDEN LAYER ***\n", + "Função Soma S: [1.186 1.427 1.144]\n", + "Função de Ativação Sigmoid: [0.766 0.806 0.758]\n", + "\n", + "\n", + "*** OUTPUT LAYER ***\n", + "Função Soma S: [0.548]\n", + "Função de Ativação Sigmoid: [0.634]\n", + "\n", + "\n", + "*** ERRO ***\n", + "Erro da linha i= 3: [-0.634]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AjUGJdaYiEH0" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lKptTBkBzysP" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(3, 1)} &= (1)(0.531)+(1)(0.655)= 1.186 \\Longrightarrow f_{H}^{(3, 1)}(S_{H}^{(3, 1)})= f_{H}^{(3, 1)}(1.186)= 0.766 \\\\\n", + "S_{H}^{(3, 2)} &= (1)(0.570)+(1)(0.857)= 1.427 \\Longrightarrow f_{H}^{(3, 2)}(S_{H}^{(3, 2)})= f_{H}^{(3, 2)}(1.427)= 0.806 \\\\\n", + "S_{H}^{(3, 3)} &= (1)(0.543)+(1)(0.602)= 1.144 \\Longrightarrow f_{H}^{(3, 3)}(S_{H}^{(3, 3)})= f_{H}^{(3, 3)}(1.144)= 0.758\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ISxS131GzysR" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(3)}&= (0.766)(0.24)+(0.806)(0.318)+(0.758)(0.142)= 0.548 \\\\\n", + "f_{O}^{(3)}(S_{O}^{(3)})&= f_{O}^{(3)}(0.548)= 0.634 \\\\\n", + "E_{3}&= 0-0.634= -0.634\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YR3X25venRv5" + }, + "source": [ + "### Resumo dos cálculos com _arrays_\n", + "\n", + "Os cálculos que foram realizados previamente com o NumPy _step by step_ aqui são feitos utilizando produto matricial." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n9D-5dE-I_IS" + }, + "source": [ + "[**Python**] - Funções de ativação da _Hidden Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efO2aSu8AzMp", + "outputId": "fbbfe562-fcc3-4535-a10b-c7a2fb03c269", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f0" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.5, 0.5, 0.5])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BoDRBC8oXEW0", + "outputId": "d9fc70ea-9f5b-4f66-8271-ad8cb375e5bc", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2 = np.array([f0, f1, f2, f3])\n", + "X2" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.5 , 0.5 , 0.5 ],\n", + " [0.658, 0.702, 0.646],\n", + " [0.63 , 0.639, 0.632],\n", + " [0.766, 0.806, 0.758]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WVIwTcF1JLIm" + }, + "source": [ + "[**Python**] - Calcular a soma $S$ da _Output Layer_, dado pelo produto matricial de $X2$ por $W_{O}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ddyC0sa6XEW5", + "outputId": "984f6fc2-2fd9-4c70-c8d9-311f3b49ab9e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "S = X2.dot(W_O)\n", + "S" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.35 ],\n", + " [0.473],\n", + " [0.444],\n", + " [0.548]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NRkyUZN7Jooz" + }, + "source": [ + "[**Python**] - Função de ativação da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jadac2Q3XEW-", + "outputId": "dfeb815e-230d-420c-a4f4-d1454bafbe2a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f = FuncaoAtivacao_Sigmoid(S)\n", + "f" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.587],\n", + " [0.616],\n", + " [0.609],\n", + " [0.634]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZuTe0mHg8Kzk" + }, + "source": [ + "Os resultados das funções de ativação acima conferem com o resumo a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r2lHqqhmM6rd" + }, + "source": [ + "[**Python**] - Calcular os Erros" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bCu8miA2XEXE", + "outputId": "01ac22ce-5da2-44a7-980e-d7333ce0847a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "E = Y - f\n", + "E" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.587],\n", + " [ 0.384],\n", + " [ 0.391],\n", + " [-0.634]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P2Q019cxotQM" + }, + "source": [ + "Os cálculos estão resumidos na tabela a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | ValorCalculado ($\\hat{Y}_{i}$) | $Erro$ | $Erro^{2}$ |\n", + "|---|---|---|---|---|:----------------------:|------------------:|\n", + "| 0 | 0 | 0 | 0 | 0.587 | -0.587 | 0.344 |\n", + "| 1 | 0 | 1 | 1 | 0.616 | 0.384 | 0.147 |\n", + "| 2 | 1 | 0 | 1 | 0.609 | 0.391 | 0.152 |\n", + "| 3 | 1 | 1 | 0 | 0.634 | -0.634 | 0.401 |\n", + "\n", + "Onde:\n", + "\n", + "$Erro= y_{i}-\\hat{Y}_{i}$= ValorReal - ValorCalculado\n", + "\n", + "O cálculo do MSE será $MSE= \\frac{0.344+0.147+0.152+0.401}{4}= \\frac{1.044}{4}= 0.261$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lHm_16jEz-kL" + }, + "source": [ + "### Métrica para avaliação da performance da Rede Neural\n", + "\n", + "* O MSE é uma das principais métricas para medir a performance das Redes Neurais. A seguir, o cálculo do MSE:\n", + "\n", + "$$MSE= \\frac{\\sum_{i=1}^{n}(y_{i}-\\hat{Y}_{i})^{2}}{n}= \\frac{(0-0.587)^{2}+(1-0.616)^{2}+(1-0.609)^{2}+(0-0.634)^{2}}{4}= \\frac{0.344+0.147+0.152+0.401}{4}=0.261$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D2Yo6TdpNIPW" + }, + "source": [ + "[**Python**] - Desenvolver função MSE para calcular o MSE = Erro Quadrático Médio:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EENpe-rbXEXL" + }, + "source": [ + "def MSE(Y, f):\n", + " return np.square(Y - f).mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ySpVD0-mNQ1s" + }, + "source": [ + "[**Python**] - Evocar a função $MSE(Y, f)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C0L5ACZnXEXP", + "outputId": "a289fe92-6adb-42b0-b8b9-22ad1b340d10", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "MSE(Y, f)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.2614527354351902" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xpzv12a48GhA" + }, + "source": [ + "### _Backpropagation_ - Ajuste dos pesos $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$\n", + "\n", + "> _Backpropagation_ (ou simplesmente _Backward_) é o processo que faz com que a Rede Neural aprenda a partir da atualização iterativa dos pesos $W$. A ideia do _Backpropagation_ é que podemos melhorar a performance da Rede Neural através da calibração dos pesos $W$ usando _Gradient Descent_, de forma que os _outputs_ ($\\hat{y}_{i}$) serão cada vez mais próximos do valor real ($y_{i}$)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vjBeg2TTcd40" + }, + "source": [ + "Como vimos anteriormente, a fórmula para atualização dos pesos $W$, dada pela expressão abaixo\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n", + "\n", + "necessita da derivada da _Loss Function_ $L$, que é a função _Sigmoid_, cuja expressão matemática é dada a seguir:\n", + "\n", + "$$y(x)= \\frac{1}{1+e^{-x}}$$\n", + "\n", + "Portanto, a derivada da função _Sigmoid_ é dada pela expressão a seguir:\n", + "\n", + "$$\\frac{dy}{dx}= y^{'}= y(1-y)$$\n", + "\n", + "Caso você tenha dúvidas sobre a derivada da função de ativação _Sigmoid_, sugiro a leitura deste artigo: [Derivative of the Sigmoid function](https://towardsdatascience.com/derivative-of-the-sigmoid-function-536880cf918e)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hDKJakFImuRp" + }, + "source": [ + "* $D_{O}$ é a Derivada do neurônio da _Output Layer_;\n", + "* $\\Delta_{H}= D_{O}* W_{O} * \\Delta_{O}$;\n", + "* $\\Delta_{O}= E_{i}*D_{O}$.\n", + "\n", + "A seguir, a Derivada da função _Sigmoid_ usando o NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kDnarWwwNZd0" + }, + "source": [ + "[**Python**] - Função Derivada_Sigmoid, que calcula a Derivada da função _Sigmoid_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qSxVsNeDXEXY" + }, + "source": [ + "def Derivada_Sigmoid(y):\n", + " return y*(1-y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CY6O0qkWNhby" + }, + "source": [ + "[**Python**] - Evocar a Derivada_Sigmoid(f), ou seja, calcular a derivada das funções de ativação da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WTpQfBTpXEXi", + "outputId": "db0a0bf9-2163-4ce8-df0f-8f7b6a23c195", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "D_O = Derivada_Sigmoid(f)\n", + "D_O" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.242],\n", + " [0.237],\n", + " [0.238],\n", + " [0.232]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jfVdgCFDf9-X" + }, + "source": [ + "Os cálculos acima foram feitos no NumPy e são reproduzidos manualmente abaixo:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TOslp3YSN70r" + }, + "source": [ + "[**Python**] - Função Backpropagation para calcular:\n", + "* _Output Layer_:\n", + " * $D_{O}$ - Derivada dos valores da _Output Layer_;\n", + " * $\\Delta_{O}$ - Delta;\n", + "* _Hidden Layer_:\n", + " * $D_{H}$ - Derivada dos valores da _Hidden Layer_;\n", + " * $\\Delta_{H}$ - Delta" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4PihyM2VXEXq" + }, + "source": [ + "def Backpropagation(i):\n", + " print(f'***** OUTPUT LAYER *****')\n", + " print(f'*** Função de ativação ***')\n", + " print(f[i])\n", + " \n", + " #print('\\n')\n", + " print(f'*** Derivada ***')\n", + " D_O= Derivada_Sigmoid(f)\n", + " print(D_O[i])\n", + "\n", + " #print('\\n') \n", + " print(f'*** Erros ***')\n", + " print(E[i])\n", + "\n", + " #print('\\n')\n", + " print(f'*** Delta ***')\n", + " Delta_O= D_O*E\n", + " print(Delta_O[i])\n", + " \n", + " print('\\n')\n", + " print(f'***** HIDDEN LAYER *****')\n", + " print(f'*** Função de ativação ***')\n", + " print(X2[i])\n", + "\n", + " #print('\\n')\n", + " print(f'*** Derivada ***')\n", + " D_H= Derivada_Sigmoid(X2)\n", + " D_H\n", + " print(D_H[i]) \n", + " \n", + " #print('\\n')\n", + " print(f'*** Delta ***')\n", + " Delta_H= D_H*W_O.T*Delta_O\n", + " print(Delta_H[i]) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eyGWGHVaFxNG" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 0$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uiOtWoNWOn24" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(0):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SiNkv_DBXEXu", + "outputId": "477f760d-e1c2-434c-9728-e5ab050f4699", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Backpropagation(0)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "***** OUTPUT LAYER *****\n", + "*** Função de ativação ***\n", + "[0.587]\n", + "*** Derivada ***\n", + "[0.242]\n", + "*** Erros ***\n", + "[-0.587]\n", + "*** Delta ***\n", + "[-0.142]\n", + "\n", + "\n", + "***** HIDDEN LAYER *****\n", + "*** Função de ativação ***\n", + "[0.5 0.5 0.5]\n", + "*** Derivada ***\n", + "[0.25 0.25 0.25]\n", + "*** Delta ***\n", + "[-0.009 -0.011 -0.005]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PqZ_CvGI0ySD" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yO4njWZb1V1w" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(0, 1)} &= D_{H}^{(0, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(0)}= (0.25)(0.24)(-0.142)= -0.009 \\\\\n", + "\\Delta_{H}^{(0, 2)} &= D_{H}^{(0, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(0)}= (0.25)(0.318)(-0.142)= -0.011 \\\\\n", + "\\Delta_{H}^{(0, 3)} &= D_{H}^{(0, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(0)}= (0.25)(0.142)(-0.142)= -0.005\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SXpozezsYFCX" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xDZYiujcHGzK" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 1$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ROzKv5VtOuy5" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S6An6CyUXEX0", + "outputId": "eed1f6c1-7731-4368-c3c1-ea5a6a8524c8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Backpropagation(1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "***** OUTPUT LAYER *****\n", + "*** Função de ativação ***\n", + "[0.616]\n", + "*** Derivada ***\n", + "[0.237]\n", + "*** Erros ***\n", + "[0.384]\n", + "*** Delta ***\n", + "[0.091]\n", + "\n", + "\n", + "***** HIDDEN LAYER *****\n", + "*** Função de ativação ***\n", + "[0.658 0.702 0.646]\n", + "*** Derivada ***\n", + "[0.225 0.209 0.229]\n", + "*** Delta ***\n", + "[0.005 0.006 0.003]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwblrxI20ygW" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "18bsrlv_4B0Q" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(1, 1)} &= D_{H}^{(1, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(1)}= (0.225)(0.24)(0.091)= 0.005 \\\\\n", + "\\Delta_{H}^{(1, 2)} &= D_{H}^{(1, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(1)}= (0.209)(0.318)(0.091)= 0.006 \\\\\n", + "\\Delta_{H}^{(1, 3)} &= D_{H}^{(1, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(1)}= (0.229)(0.142)(0.091)= 0.003\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cPfQUUUHYw4i" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e8qfA8CGHJo8" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 2$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UWxqTLsKOyoK" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(2):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "w39YvfOWXEX7", + "outputId": "bff1eb12-46f3-4713-8bfa-060bed4c88a5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Backpropagation(2)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "***** OUTPUT LAYER *****\n", + "*** Função de ativação ***\n", + "[0.609]\n", + "*** Derivada ***\n", + "[0.238]\n", + "*** Erros ***\n", + "[0.391]\n", + "*** Delta ***\n", + "[0.093]\n", + "\n", + "\n", + "***** HIDDEN LAYER *****\n", + "*** Função de ativação ***\n", + "[0.63 0.639 0.632]\n", + "*** Derivada ***\n", + "[0.233 0.231 0.232]\n", + "*** Delta ***\n", + "[0.005 0.007 0.003]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BBZuNcOC0yj9" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sZam1meY48hW" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(2, 1)} &= D_{H}^{(2, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(2)}= (0.233)(0.24)(0.093)= 0.005 \\\\\n", + "\\Delta_{H}^{(2, 2)} &= D_{H}^{(2, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(2)}= (0.231)(0.318)(0.093)= 0.007 \\\\\n", + "\\Delta_{H}^{(2, 3)} &= D_{H}^{(2, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(2)}= (0.232)(0.142)(0.093)= 0.003\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dAc8YrceY5kY" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PWrv-aRyHMPh" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 3$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MKqR3izrO15N" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(3):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1APffWq2XEYA", + "outputId": "24359257-7932-468a-d2c6-c437bab1139a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Backpropagation(3)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "***** OUTPUT LAYER *****\n", + "*** Função de ativação ***\n", + "[0.634]\n", + "*** Derivada ***\n", + "[0.232]\n", + "*** Erros ***\n", + "[-0.634]\n", + "*** Delta ***\n", + "[-0.147]\n", + "\n", + "\n", + "***** HIDDEN LAYER *****\n", + "*** Função de ativação ***\n", + "[0.766 0.806 0.758]\n", + "*** Derivada ***\n", + "[0.179 0.156 0.183]\n", + "*** Delta ***\n", + "[-0.006 -0.007 -0.004]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PGAXyDhW0ynn" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bdgIs_zP5i1y" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(3, 1)} &= D_{H}^{(3, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(3)}= (0.179)(0.24)(-0.147)= -0.006 \\\\\n", + "\\Delta_{H}^{(3, 2)} &= D_{H}^{(3, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(3)}= (0.156)(0.318)(-0.147)= -0.007 \\\\\n", + "\\Delta_{H}^{(3, 3)} &= D_{H}^{(3, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(3)}= (0.183)(0.142)(-0.147)= -0.004\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6Ie99-SqZA6z" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sndwYO-VbK1C" + }, + "source": [ + "A seguir, cálculos usando o NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ycvvhnWIO5s9" + }, + "source": [ + "[**Python**] - $D_{O}$: Derivada da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zkdw8tUKw5vo", + "outputId": "6a0af2a4-d7bd-4fb2-c810-41e90093d43b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.587],\n", + " [0.616],\n", + " [0.609],\n", + " [0.634]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "poTTrvYEXEYE", + "outputId": "c258cfb9-2c0f-4ee3-ea0b-0cf199ac659d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "D_O = Derivada_Sigmoid(f)\n", + "D_O" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.242],\n", + " [0.237],\n", + " [0.238],\n", + " [0.232]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JkdyDN6BPNZT" + }, + "source": [ + "[**Python**] - Mostrar os Erros:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AO9Qi9U0aWTx", + "outputId": "716ef77a-c70d-4a16-bb54-f83e49b1524b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "E" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.587],\n", + " [ 0.384],\n", + " [ 0.391],\n", + " [-0.634]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 32 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DPPqqxpIPRsT" + }, + "source": [ + "[**Python**] - $\\Delta_{O}$: Delta da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6fylksvtaT6h", + "outputId": "818bdad7-fa5e-4470-e02e-30743e86397f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Delta_O = D_O*E\n", + "Delta_O" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.142],\n", + " [ 0.091],\n", + " [ 0.093],\n", + " [-0.147]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E9zsXwcWPXn1" + }, + "source": [ + "[**Python**] - $D_{H}$: Derivada da _Hidden Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SCABYAGjaigm", + "outputId": "3ac18557-4a19-4b44-bb81-21ef383a1f85", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "D_H = Derivada_Sigmoid(X2)\n", + "D_H" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.25 , 0.25 , 0.25 ],\n", + " [0.225, 0.209, 0.229],\n", + " [0.233, 0.231, 0.232],\n", + " [0.179, 0.156, 0.183]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bLa9L88VPdQu" + }, + "source": [ + "[**Python**] - $D_{O}$ - Derivada da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "58r5kgNwa9xo", + "outputId": "56870605-a017-4c73-aca3-ff3ebacc8264", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Delta_H = D_H*W_O.T*Delta_O\n", + "Delta_H" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.009, -0.011, -0.005],\n", + " [ 0.005, 0.006, 0.003],\n", + " [ 0.005, 0.007, 0.003],\n", + " [-0.006, -0.007, -0.004]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 41 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "roh5SVtkQrJE" + }, + "source": [ + "### _Backpropagation_ - Atualizar os pesos da _Output Layer_ $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CQ69tO1IPsBQ" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "K991veZeXEYL", + "outputId": "514d0b94-ce57-4bd2-860f-d797bf47e335", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2.T.dot(Delta_O)[0]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.065])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 35 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hz-0fQAGd7Aw" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ovgjM8l6Np0e" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.658)\\Delta_{O}^{(1)}+(0.630)\\Delta_{O}^{(2)}+(0.766)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.658)(0.091)+(0.630)(0.093)+(0.766)(-0.147)= -0.065$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BFaNh6NEXEYO" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eomk5j12XEYT", + "outputId": "dbcc9962-07ef-46d3-a52d-e7cca3523aa4", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2.T.dot(Delta_O)[1]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.067])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M-3gk0erRpSF" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hVCFLfWGPE7W" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.702)\\Delta_{O}^{(1)}+(0.639)\\Delta_{O}^{(2)}+(0.866)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.702)(0.091)+(0.639)(0.093)+(0.806)(-0.147)= -0.067$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MK92KMHYXEYV" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D05BW8CgXEYc", + "outputId": "4cb5fd90-a2fc-444f-db0b-104e6b08098e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X2.T.dot(Delta_O)[2]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.065])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K754V1CSRtii" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q51biJ5TPkKX" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.646)\\Delta_{O}^{(1)}+(0.632)\\Delta_{O}^{(2)}+(0.758)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.646)(0.091)+(0.632)(0.093)+(0.758)(-0.147)= -0.067$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SaEVJAXGV3Xd" + }, + "source": [ + "###### Implementação com NumPy\n", + "\n", + "* Fórmula para atualização dos pesos $W_{O}$:\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a7dGpwzfRN2M" + }, + "source": [ + "[**Python**] - Calcular/atualizar os pesos $W_{O}$ através da expressão de $W_{n+1}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "er3DprzjXEYg", + "outputId": "1a75110a-8346-4769-d138-be521f4eabdf", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "M = 1\n", + "alpha = 0.1\n", + "\n", + "W_O_New = W_O*M+alpha*(X2.T.dot(Delta_O))\n", + "W_O_New" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.234],\n", + " [0.312],\n", + " [0.136]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0-2weyIriNqN" + }, + "source": [ + "Abaixo, os pesos atualizados de $W_{O}$ (antes e depois)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GLkZfXbmi9c6" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t4fHsSY3AlFi" + }, + "source": [ + "### _Backpropagation_ - Ajuste dos pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCED4NKj1_FX" + }, + "source": [ + "#### Ajuste dos pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$\n", + "\n", + "Para ajustar os pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$, precisamos dos valores de $\\Delta_{H}$, calculado anteriormente:\n", + "\n", + "* $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$;\n", + "* $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(((1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$;\n", + "* $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$;\n", + "* $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$.\n", + "\n", + "Veja abaixo no NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNHXkTXLRmzu" + }, + "source": [ + "[**Python**] - Mostrar $\\Delta_{H}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oYxrEVC7XEYn", + "outputId": "484c87ce-47a2-4628-dbdd-d96a464e6521", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Delta_H" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.009, -0.011, -0.005],\n", + " [ 0.005, 0.006, 0.003],\n", + " [ 0.005, 0.007, 0.003],\n", + " [-0.006, -0.007, -0.004]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XihSawh-1iKI" + }, + "source": [ + "##### Resumo dos valores de $(X*\\Delta_{H})$ calculados manualmente:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DNXt5DAhBiVC" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "06duXU28XEYy", + "outputId": "c4056c7a-7156-4d21-ae23-a6091cbac06d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DTCJ_5O7SeU9" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WeJOgJd5P5BS" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 1)}+(0)\\Delta_{H}^{(1, 1)}+(1)\\Delta_{H}^{(2, 1)}+(1)\\Delta_{O}^{(3, 1)}$$\n", + "$$(0)(-0.009)+(0)(0.005)+(1)(0.005)+(1)(-0.006)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8mbs0ZNTCRKL" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qF1iFyRWXEY9", + "outputId": "b67a06cf-8a2c-427e-8fc1-01290e91ef60", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xWkm7eyLSm6I" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9LQgX05Qj8M" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 2)}+(0)\\Delta_{H}^{(1, 2)}+(1)\\Delta_{H}^{(2, 2)}+(1)\\Delta_{H}^{(3, 2)}$$\n", + "$$(0)(-0.011)+(0)(0.006)+(1)(0.007)+(1)(-0.007)= 0$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oaVbGCATCd7B" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4UNZFSC5XEZE", + "outputId": "95202ea9-f594-4b74-a964-8b2cbe2a5e62", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4JHAiH5GSqr0" + }, + "source": [ + "\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DDrurArKQ5I_" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 3)}+(0)\\Delta_{H}^{(1, 3)}+(1)\\Delta_{H}^{(2, 3)}+(1)\\Delta_{H}^{(3, 3)}$$\n", + "$$(0)(-0.005)+(0)(0.003)+(1)(0.003)+(1)(-0.004)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GWwWUfiXXlom" + }, + "source": [ + "#### Ajuste dos pesos $W_{H}^{(2, 1)}, W_{H}^{(2, 2)}$ e $W_{H}^{(2, 3)}$\n", + "\n", + "Para ajustar os pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$, precisamos dos valores de $\\Delta_{H}$, calculado anteriormente:\n", + "\n", + "* $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$;\n", + "* $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$;\n", + "* $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$;\n", + "* $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DzeytNngSI08" + }, + "source": [ + "[**Python**] - Mostra $\\Delta_{H}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfiS9bFqXEZH", + "outputId": "e659b581-4c46-4ded-833a-420901f08631", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Delta_H" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.009, -0.011, -0.005],\n", + " [ 0.005, 0.006, 0.003],\n", + " [ 0.005, 0.007, 0.003],\n", + " [-0.006, -0.007, -0.004]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dSDbe8o8k9yi" + }, + "source": [ + "##### Resumo de $(X*\\Delta_{H})$ calculados manualmente:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D6e2ZoMmDLFN" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SH4yHqoYXEZP", + "outputId": "98c98e25-b3c1-4267-ef4f-b28936ae75fe", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zORHdsEiXwSw" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P11cTnsCRpwj" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 1)}+(1)\\Delta_{H}^{(1, 1)}+(0)\\Delta_{H}^{(2, 1)}+(1)\\Delta_{H}^{(3, 1)}$$\n", + "$$(0)(-0.009)+(1)(0.005)+(0)(0.005)+(1)(-0.006)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W_LMmSEVDXY7" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YE4DH6P_XEZZ", + "outputId": "da667dd2-65a7-4aa1-c45b-d7cefc3627b1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Gz7bhUuDX6Me" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OLrwPoE7SGYu" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 2)}+(1)\\Delta_{H}^{(1, 2)}+(0)\\Delta_{H}^{(2, 2)}+(1)\\Delta_{H}^{(3, 2)}$$\n", + "$$(0)(-0.011)+(1)(0.006)+(0)(0.007)+(1)(-0.007)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vzbUzC8FDhuo" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7-epl7I3XEZf", + "outputId": "402d8680-d2ec-4d9a-e77a-65085978f1d3", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[-0.001, -0. , -0.001],\n", + " [-0.001, -0.001, -0.001]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0gT8_uDQX-NT" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QLz57OEPSWjl" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 3)}+(1)\\Delta_{H}^{(1, 3)}+(0)\\Delta_{H}^{(2, 3)}+(1)\\Delta_{H}^{(3, 3)}$$\n", + "$$(0)(-0.005)+(1)(0.003)+(0)(0.003)+(1)(-0.004)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7G9gWkKWIIOL" + }, + "source": [ + "##### Implementação com NumPy\n", + "\n", + "Usando:\n", + "* M = 1;\n", + "* $\\alpha = 0.1$;\n", + "* Fórmula: $W_{n+1} = (W_{n}*M)+\\alpha*(X*\\Delta_{H})$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5C3NCWcuShqN" + }, + "source": [ + "[**Python**] - Calcular/atualizar os pesos $W_{H}$ usando a expressão $W_{n+1}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ys_y-R0BL7Iw", + "outputId": "dcb98f8d-038e-4957-9b72-4c796929a9af", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "M = 1\n", + "alpha = 0.1\n", + "\n", + "W_H_New = W_H*M+alpha*(X.T.dot(Delta_H))\n", + "W_H_New" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0.531, 0.57 , 0.542],\n", + " [0.655, 0.857, 0.602]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IvaIx_PKZEmd" + }, + "source": [ + "##### Novos Pesos $W_{H}$ e $W_{O}$ da Rede Neural (Antes x Depois)\n", + "\n", + "\"Drawing\"\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EuO2t22CffE8" + }, + "source": [ + "___\n", + "# **Como as Redes Neurais aprendem?**\n", + "\n", + "> Vimos até agora grande parte dos cálculos matemáticos que envolvem o treinamento das Redes Neurais, que envolvem a repetição dos processos _Forward_ e _Backward_:\n", + "\n", + "1. _**Forward**_: Consiste na multiplicação de matrizes entre os _arrays_ da _input layer_, pesos $W$ e, na sequência, aplicar as funções de ativação.\n", + "\n", + "2. _**Backward**_: Consiste em atualizar os pesos $W_{O}$ e $W_{H}$ para minimizar a _Loss Function_ $L$ usando _Gradient Descent_.\n", + "\n", + "* Estes 2 processos foram vistos detalhadamente em aulas anteriores.\n", + " * Cálculos matemáticos passo a passo foram mostrados. Portanto, visite nossas aulas anteriores para aprender mais sobre os aspectos teóricos e matemáticos por trás das Redes Neurais.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mpKyqSuDdbMr" + }, + "source": [ + "___\n", + "# **_GRADIENT DESCENT_**\n", + "\n", + "_Gradient Descent_ é um algoritmo interativo utilizado para otimizar (neste caso, minimizar) a _Loss Function_ $L$. \n", + "\n", + "* Minimizar a _Loss Function_ $L$ significa encontrar os pesos $W_{H}$ e $W_{O}$ que faz com que MSE seja o menor possível, pois quanto menor o MSE, melhor a performance da Rede Neural. \n", + "\n", + "* Para atualizar os pesos $W$, vamos usar a expressão a seguir:\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n", + "\n", + "onde:\n", + "\n", + "* $L$ é a _Loss Function_ a ser minimizada;\n", + "* $W_{n}$ são os pesos atuais e que deverão ser atualizados para a próxima iteração;\n", + "* $\\alpha$ é a taxa de aprendizado (_Learning Rate_ em inglês) e diz respeito à velocidade de aprendizagem da Rede Neural.\n", + " * Quanto MENOR o valor de $\\alpha$ $\\Longrightarrow$ mais devagar e demorada será a convergência para o mínimo global;\n", + " * Quanto MAIOR o valor de $\\alpha$ $\\Longrightarrow$ mais rápido será a convergência para o mínimo, mas sem a garantia de convergência para o mínimo global.\n", + "* $M$ é o _Momentum_, que é o artifício para acelerar a otimização (ou minimização) da _Loss Function_ $L$.\n", + " * Valores altos $\\Longrightarrow$ Aumenta a velocidade da aprendizagem;\n", + " * Valores baixos $\\Longrightarrow$ Mais tempo para aprendizagem, mas com maiores chances de se encontrar a solução ótima, evitando os mínimos locais.\n", + "* $\\frac{\\partial L}{\\partial W_{n}}$ é a derivada da _Loss Function_ $L$ em relação ao peso $W_{n}$. Como dito anteriormente, é a contribuição do peso $W$ no Erro. Calcular $(X*\\Delta)$ é a parte mais complicada da fórmula e fizemos estes cálculos passo a passo em aulas anteriores." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzuFSOV4eboI" + }, + "source": [ + "Observe a figura a seguir: O que o _Gradient Descent_ fará é encontrar o mínimo global da _loss function_, tentando ao máximo possível evitar os mínimos locais.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z-UbiCxUgvHg" + }, + "source": [ + "A seguir, alguns artigos sobre _Gradient Descent_ caso você queira saber um pouco mais sobre o assunto:\n", + "\n", + "* [An introduction to Gradient Descent Algorithm](https://medium.com/@montjoile/an-introduction-to-gradient-descent-algorithm-34cf3cee752b) - Abrir este artigo para mostrar os efeitos da _Learning Rate_ e os tipos de _Gradient Descent_ disponíveis para Machine Learning;\n", + "* [Machine learning : Gradient Descent](https://medium.com/@arshren/gradient-descent-5a13f385d403);\n", + "* [The Math and Intuition Behind Gradient Descent](https://medium.com/datadriveninvestor/the-math-and-intuition-behind-gradient-descent-13c45f367a11) - Mostra a matemática por trás do _Gradient Descent_;\n", + "* [An Introduction to Gradient Descent](https://towardsdatascience.com/an-introduction-to-gradient-descent-c9cca5739307);\n", + "* [Gradient Descent From Scratch](https://towardsdatascience.com/gradient-descent-from-scratch-e8b75fa986cc);\n", + "* [Gradient Descent Explanation & Implementation](https://towardsdatascience.com/gradient-descent-explanation-implementation-c74005ff7dd1) - Cálculos step-by-step;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "junvtVY4eePi" + }, + "source": [ + "___\n", + "# **_LOSS FUNCTION_ $L$**\n", + "\n", + "> Como vimos anteriormente, nosso objetivo é minimizar a _Loss function_ através do _Gradient Descent_. Em outras palavras, esse processo de otimização busca, à cada iteração (_epoch_), atualizar os pesos $W$ para reduzir a _Loss Function_. As _Loss Function_ mais comuns são:\n", + "\n", + "* **Regressão**: mse ou mae;\n", + "* **Classificação**: _cross-entropy_ (quando queremos probabilidades de cada observação pertencer à uma determinada classe).\n", + " * **Classificação binária**: tf.keras.losses.BinaryCrossentropy()\n", + ";\n", + " * **Classificação multi-classes**: tf.keras.losses.CategoricalCrossentropy()\n", + "." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6e4ULmJheePY" + }, + "source": [ + "___\n", + "# **MÉTRICAS PARA MEDIR A PERFORMANCE DAS REDES NEURAIS**\n", + "\n", + "* As métricas medem a qualidade/performance das Redes Neurais e as principais são:\n", + " * **Regressão**: Quanto mais próximo de 0 estiver MAE, MSE ou RMSE, melhor a performance da Rede Neural.\n", + " * MAE significa \"_Mean Absolute Error_\".\n", + "\n", + " * MSE - significa \"_Mean Square Error_\", que é a diferença entre os valores reais $y_{i}$ e os valores previstos (ou calculados) $\\hat{Y}_{i}$.\n", + "\n", + " * RMSE - significa \"_Root Mean Square Error_\".\n", + " \n", + " * **Classificação**: Quanto maior a accuracy, melhor a performance da Rede Neural.\n", + " * Accuracy\n", + "\n", + "* Expressões Matemáticas:\n", + "\n", + "\\begin{align}\n", + "MSE &= \\frac{\\sum_{i=1}^{n}(y_{i}-\\hat{Y}_{i})^{2}}{n} \\\\\n", + "RMSE &= \\sqrt{MSE} \\\\\n", + "MAE &= \\frac{\\sum_{i=1}^{n}|y_{i}-\\hat{Y}_{i}|}{n}\n", + "\\end{align}\n", + "\n", + "Para os alunos que estão com dúvidas sobre qual métrica usar, sugiro a leitura do artigo [MAE and RMSE — Which Metric is Better?](https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6n4QjH1WeeO8" + }, + "source": [ + "___\n", + "# **_DROPOUT_**\n", + "\n", + "> _Dropout_ significa ignorar aleatoriamente e temporariamente um percentual $p$ de neurônios durante a fase de treinamento. Ao \"ignorar\", quero dizer que tais neurônios não serão considerados durante os processos _forward_ e _backpropagation_.\n", + "\n", + "* _Dropout_ força que a Rede Neural aprenda a partir dos dados, mas usando diferentes e aleatórios neurônios;\n", + "* Recomenda-se $p = 0.20$. \n", + "* Ao se usar _Dropout_, recomenda-se mais épocas para treinar a Redes Neurais;\n", + "\n", + "* **Vantagens**:\n", + " * Evita _overfitting_ - Num \"_fully connected layer_\", neurônios desenvolvem dependência durante a fase de treinamento levando ao _overfitting_. Com _dropout_ é possível reduzir um pouco desta dependência, reduzindo as chances de _overfitting_;\n", + "\n", + "![Dropout](https://github.com/MathMachado/Materials/blob/master/Dropout.png?raw=true)\n", + "\n", + "Fonte: [Dropout in (Deep) Machine learning](https://medium.com/@amarbudhiraja/https-medium-com-amarbudhiraja-learning-less-to-learn-better-_dropout_-in-deep-machine-learning-74334da4bfc5).\n", + "\n", + "TEMPLATE: keras.layers.Dropout(rate, noise_shape=None, seed=None)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9-9Y9562kNNU" + }, + "source": [ + "___\n", + "# **Rede Neural multicamada (1 _Hidden Layer_) para o Operador Lógico XOR usando _Tensorflow_/_Keras_**\n", + "\n", + "* **Observações**:\n", + " * Há vários artigos (no _medium_, por exemplo) a discutir e desenvolver Redes Neurais para o Operador Lógico XOR. Então porque eu decidi produzir esta aula usando o dataframe do Operador Lógico XOR?\n", + " * Para explicar didaticamente e passo a passo todos os aspectos matemáticos por trás das Redes Neurais usando um dataframe pequeno e, apesar disso, complexo, pois é um problema linearmente NÃO-separável e, sendo assim, requer uma Rede Neural mais complexa (com pelo menos 1 _Hidden Layer_) para melhorar a acurácia e reduzir a _loss_;\n", + " * Para explicar como é fácil desenvolver Redes Neurais usando Tensorflow/Keras;\n", + " * Para explicar didaticamente e passo a passo os processos _Forward_ e _Backward_ para treinar Redes Neurais;\n", + " * Versão do Tensorflow usada: 2.x;\n", + " * Estou a utilizar o Google Colab;\n", + " * Nesta aula, não se preocupe demasiadamente com a sintaxe dos comandos. Porque?\n", + " * Vamos repetir tudo detalhadamente nas próximas aulas. Portanto, você terá a oportunidade de aprender e praticar muito em breve;\n", + " * O objetivo desta aula é simplesmente fazer uma introdução às Redes Neurais, Tensorflow/Keras e mostrar os passos/processos que vamos seguir aqui e no futuro para desenvolver Redes Neurais. Quando você assistir as aulas subsequentes, tudo ficará mais claro.\n", + "* Todas as aulas do curso de Redes Neurais foram cuidadosamente planejadas e preparadas para trazer conteúdos relevantes para você aprender Redes Neurais no menor tempo possível. Portanto, nesta aula você vai encontrar várias linhas como a linha adiante:\n", + "\n", + "[**Python**] - Comando ou _code_ que deve ser executado.\n", + "\n", + "Estas linhas são uma espécie de _guide_ para não nos esquecermos de nenhum detalhe da aula. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rOQbXbCgZZRL" + }, + "source": [ + "A seguir, dataframe do Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KusCpN1S4CtH" + }, + "source": [ + "Vamos obedecer os _steps_ a seguir para construir nossa Rede Neural:\n", + "\n", + "1. Carregar as bibliotecas do Python e Tensorflow;\n", + "2. Carregar os dados para treinar a Rede Neural;\n", + "3. Definir a arquitetura da Rede Neural com Tensorflow/Keras;\n", + "4. Compilar a Rede Neural;\n", + "5. Ajustar a Rede Neural;\n", + "6. Avaliar a performance da Rede Neural;\n", + "7. _Fine tuning_ da Rede Neural;\n", + "8. Fazer Predições com a Rede Neural;\n", + "9. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mq7pF8854cf6" + }, + "source": [ + "### 1. Carregar as bibliotecas do Python e Tensorflow" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Br4REluttJXH" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W-1jl_vnP7n3" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import tensorflow as tf\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UA_bHIYOrNwy" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ApSwaqVbQVGx", + "outputId": "1f2cda78-ed28-470b-e3fd-973379009795", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'2.3.0'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 54 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH37RXFLtPpB" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais = 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Pzdu5btatTom" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YbKhVkd4sm2" + }, + "source": [ + "### 2. Carregar os dados para treinar a Rede Neural\n", + "\n", + "Segue abaixo o dataframe do Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3uojCCMaWgtI" + }, + "source": [ + "[**Python**] - Definir as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nTbtpKKdQh9M", + "outputId": "0002c861-cb8d-4ebc-b98a-462c82466f8a", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X_XOR = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n", + "X_XOR" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 56 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7hc1pYW-WsCp" + }, + "source": [ + "[**Python**] - Definir os _Outputs_ $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gj4zl-JdQ0nR", + "outputId": "0f2d9383-bb95-4e6e-b8b8-2f14d4364d10", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_XOR = np.array([[0], [1], [1], [0]])\n", + "y_XOR" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 57 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2WF73gTMZtN-" + }, + "source": [ + "### 3. Conceito importante: _Fully connected layer_\n", + "\n", + "> A arquitetura da Rede Neural abaixo é dita _fully connected_, ou seja, os neurônios da camada anterior se conecta com todos os neurônios da camada subsequente. Observe a figura a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7X5eys3mxsl2" + }, + "source": [ + "#### Arquitetura da Rede Neural\n", + "\n", + "> A seguir, a arquitetura da Rede Neural que vamos desenvolver neste exemplo:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QpmtGEFgWzhk" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação:\n", + " * _Hidden Layer_: Há várias opções que podem ser usadas, mas vou tentar resolver este exemplo com a função de ativação _Sigmoid_, que foi a função de ativação que foi a opção escolhida quando explicamos Redes Neurais passo a passo.\n", + " * _Output Layer_: Os valores de $y_{i}$ do dataframe são binários. Portanto, nossa opção para função de ativação para a _Output Layer_ é usar a função de ativação _Sigmoid_." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Id_P910LRRb4" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2 # Número de variáveis/colunas da matriz de preditoras\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 3\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.sigmoid\n", + "\n", + "# Função de Ativação da Output Layer\n", + "FA_O = tf.keras.activations.sigmoid" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n6s9RcjLXqQm" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3DizOTqQR6-U" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vdcdcNncYB15" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E8KJ0f70HEwN" + }, + "source": [ + "**Observação**:\n", + "\n", + "* A opção kernel_constraint= tf.keras.constraints.UnitNorm() será utilizada para reduzir _overfitting_, conforme sugere o artigo [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/);." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-LYbXfEZYNcC", + "outputId": "1a48709a-93ad-4b5c-f679-a74d48e21f24", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "\n", + "RN = Sequential() # nome da Rede Neural\n", + "RN.add(Dense(units = N_H, \n", + " input_dim = N_I, \n", + " activation = FA_H, \n", + " kernel_constraint = tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation = FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural:\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Model: \"sequential_1\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "dense_2 (Dense) (None, 3) 9 \n", + "_________________________________________________________________\n", + "dense_3 (Dense) (None, 1) 4 \n", + "=================================================================\n", + "Total params: 13\n", + "Trainable params: 13\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n", + "None\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OoA-_8A55jMW" + }, + "source": [ + "### 4. Compilar a Rede Neural\n", + "\n", + "> Adam é um algoritmo de otimização.\n", + "\n", + "Para saber mais sobre o algoritmo de otimização 'adam', consulte o artigo [Gentle Introduction to the Adam Optimization Algorithm for Deep Learning](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ifkjrCT6Yki6" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OdIerBPAUGbY" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam() # Algoritmo de otimização\n", + "Loss_Function = tf.keras.losses.MeanSquaredError() # A métrica para cálculo do erro\n", + "Metrics_Perf = [tf.keras.metrics.binary_accuracy]\n", + "\n", + "RN.compile(optimizer = Algoritmo_Opt, \n", + " loss= Loss_Function, \n", + " metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KVx2w28c5urj" + }, + "source": [ + "### 5. Ajustar/treinar a Rede Neural\n", + "\n", + "* 1 _Epoch_ = 1 iteração da Rede Neural, passando por todo o dataframe de treinamento, sendo que 1 iteração contempla 1 processo _Forward_ e 1 processo _Backward_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZV3XwUJ8YvxE" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "45inZ8X3U0Ew", + "outputId": "ad45add5-0027-4f4a-fde0-28bba8bbce54", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "hist = RN.fit(X_XOR, y_XOR, epochs = 100)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Epoch 1/100\n", + "1/1 [==============================] - 0s 1ms/step - loss: 0.3195 - binary_accuracy: 0.5000\n", + "Epoch 2/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3201 - binary_accuracy: 0.5000\n", + "Epoch 3/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3198 - binary_accuracy: 0.5000\n", + "Epoch 4/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3195 - binary_accuracy: 0.5000\n", + "Epoch 5/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3192 - binary_accuracy: 0.5000\n", + "Epoch 6/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3188 - binary_accuracy: 0.5000\n", + "Epoch 7/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3185 - binary_accuracy: 0.5000\n", + "Epoch 8/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3182 - binary_accuracy: 0.5000\n", + "Epoch 9/100\n", + "1/1 [==============================] - 0s 5ms/step - loss: 0.3179 - binary_accuracy: 0.5000\n", + "Epoch 10/100\n", + "1/1 [==============================] - 0s 1ms/step - loss: 0.3176 - binary_accuracy: 0.5000\n", + "Epoch 11/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3173 - binary_accuracy: 0.5000\n", + "Epoch 12/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3170 - binary_accuracy: 0.5000\n", + "Epoch 13/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3166 - binary_accuracy: 0.5000\n", + "Epoch 14/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3163 - binary_accuracy: 0.5000\n", + "Epoch 15/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3160 - binary_accuracy: 0.5000\n", + "Epoch 16/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3157 - binary_accuracy: 0.5000\n", + "Epoch 17/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3154 - binary_accuracy: 0.5000\n", + "Epoch 18/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3151 - binary_accuracy: 0.5000\n", + "Epoch 19/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3148 - binary_accuracy: 0.5000\n", + "Epoch 20/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3145 - binary_accuracy: 0.5000\n", + "Epoch 21/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3142 - binary_accuracy: 0.5000\n", + "Epoch 22/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3138 - binary_accuracy: 0.5000\n", + "Epoch 23/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3135 - binary_accuracy: 0.5000\n", + "Epoch 24/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3132 - binary_accuracy: 0.5000\n", + "Epoch 25/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3129 - binary_accuracy: 0.5000\n", + "Epoch 26/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3126 - binary_accuracy: 0.5000\n", + "Epoch 27/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3123 - binary_accuracy: 0.5000\n", + "Epoch 28/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3120 - binary_accuracy: 0.5000\n", + "Epoch 29/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3117 - binary_accuracy: 0.5000\n", + "Epoch 30/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3114 - binary_accuracy: 0.5000\n", + "Epoch 31/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3111 - binary_accuracy: 0.5000\n", + "Epoch 32/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3108 - binary_accuracy: 0.5000\n", + "Epoch 33/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3105 - binary_accuracy: 0.5000\n", + "Epoch 34/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3102 - binary_accuracy: 0.5000\n", + "Epoch 35/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3099 - binary_accuracy: 0.5000\n", + "Epoch 36/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3096 - binary_accuracy: 0.5000\n", + "Epoch 37/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3093 - binary_accuracy: 0.5000\n", + "Epoch 38/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3090 - binary_accuracy: 0.5000\n", + "Epoch 39/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3087 - binary_accuracy: 0.5000\n", + "Epoch 40/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3084 - binary_accuracy: 0.5000\n", + "Epoch 41/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3081 - binary_accuracy: 0.5000\n", + "Epoch 42/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3079 - binary_accuracy: 0.5000\n", + "Epoch 43/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3076 - binary_accuracy: 0.5000\n", + "Epoch 44/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3073 - binary_accuracy: 0.5000\n", + "Epoch 45/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3070 - binary_accuracy: 0.5000\n", + "Epoch 46/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3067 - binary_accuracy: 0.5000\n", + "Epoch 47/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3064 - binary_accuracy: 0.5000\n", + "Epoch 48/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3061 - binary_accuracy: 0.5000\n", + "Epoch 49/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3058 - binary_accuracy: 0.5000\n", + "Epoch 50/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3055 - binary_accuracy: 0.5000\n", + "Epoch 51/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3053 - binary_accuracy: 0.5000\n", + "Epoch 52/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3050 - binary_accuracy: 0.5000\n", + "Epoch 53/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3047 - binary_accuracy: 0.5000\n", + "Epoch 54/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3044 - binary_accuracy: 0.5000\n", + "Epoch 55/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3041 - binary_accuracy: 0.5000\n", + "Epoch 56/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3038 - binary_accuracy: 0.5000\n", + "Epoch 57/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3036 - binary_accuracy: 0.5000\n", + "Epoch 58/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3033 - binary_accuracy: 0.5000\n", + "Epoch 59/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3030 - binary_accuracy: 0.5000\n", + "Epoch 60/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3027 - binary_accuracy: 0.5000\n", + "Epoch 61/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3025 - binary_accuracy: 0.5000\n", + "Epoch 62/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3022 - binary_accuracy: 0.5000\n", + "Epoch 63/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3019 - binary_accuracy: 0.5000\n", + "Epoch 64/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3016 - binary_accuracy: 0.5000\n", + "Epoch 65/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3014 - binary_accuracy: 0.5000\n", + "Epoch 66/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.3011 - binary_accuracy: 0.5000\n", + "Epoch 67/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.3008 - binary_accuracy: 0.5000\n", + "Epoch 68/100\n", + "1/1 [==============================] - 0s 11ms/step - loss: 0.3006 - binary_accuracy: 0.5000\n", + "Epoch 69/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3003 - binary_accuracy: 0.5000\n", + "Epoch 70/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.3000 - binary_accuracy: 0.5000\n", + "Epoch 71/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2997 - binary_accuracy: 0.5000\n", + "Epoch 72/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2995 - binary_accuracy: 0.5000\n", + "Epoch 73/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.2992 - binary_accuracy: 0.5000\n", + "Epoch 74/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2990 - binary_accuracy: 0.5000\n", + "Epoch 75/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.2987 - binary_accuracy: 0.5000\n", + "Epoch 76/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2984 - binary_accuracy: 0.5000\n", + "Epoch 77/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2982 - binary_accuracy: 0.5000\n", + "Epoch 78/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2979 - binary_accuracy: 0.5000\n", + "Epoch 79/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2976 - binary_accuracy: 0.5000\n", + "Epoch 80/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2974 - binary_accuracy: 0.5000\n", + "Epoch 81/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2971 - binary_accuracy: 0.5000\n", + "Epoch 82/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2969 - binary_accuracy: 0.5000\n", + "Epoch 83/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2966 - binary_accuracy: 0.5000\n", + "Epoch 84/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2964 - binary_accuracy: 0.5000\n", + "Epoch 85/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2961 - binary_accuracy: 0.5000\n", + "Epoch 86/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.2959 - binary_accuracy: 0.5000\n", + "Epoch 87/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2956 - binary_accuracy: 0.5000\n", + "Epoch 88/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2954 - binary_accuracy: 0.5000\n", + "Epoch 89/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2951 - binary_accuracy: 0.5000\n", + "Epoch 90/100\n", + "1/1 [==============================] - 0s 5ms/step - loss: 0.2949 - binary_accuracy: 0.5000\n", + "Epoch 91/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2946 - binary_accuracy: 0.5000\n", + "Epoch 92/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2944 - binary_accuracy: 0.5000\n", + "Epoch 93/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.2941 - binary_accuracy: 0.5000\n", + "Epoch 94/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.2939 - binary_accuracy: 0.5000\n", + "Epoch 95/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2936 - binary_accuracy: 0.5000\n", + "Epoch 96/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2934 - binary_accuracy: 0.5000\n", + "Epoch 97/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2931 - binary_accuracy: 0.5000\n", + "Epoch 98/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2929 - binary_accuracy: 0.5000\n", + "Epoch 99/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.2927 - binary_accuracy: 0.5000\n", + "Epoch 100/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.2924 - binary_accuracy: 0.5000\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i1bUiekR5q1E" + }, + "source": [ + "### 6. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wBp4ctbKY8k7" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M4HlrjjjVLjB", + "outputId": "a4efc370-b2fb-4b63-88fc-7671b7005fbe", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "RN.evaluate(X_XOR, y_XOR)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "1/1 [==============================] - 0s 1ms/step - loss: 0.2922 - binary_accuracy: 0.5000\n" + ], + "name": "stdout" + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.2921895980834961, 0.5]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 64 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iPwANO05VT5m" + }, + "source": [ + "**Resultado**: O modelo _baseline_ (modelo inicial) apresenta os seguintes resultados:\n", + "* loss= 0.2515;\n", + "* accuracy= 50%.\n", + "\n", + "* **Comentário**: A Rede Neural apresenta resultados insatisfatórios." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lD2pw9H754ZZ" + }, + "source": [ + "### 7. _Fine tuning_ da Rede Neural\n", + "\n", + "Antes de falarmos de _fine tuning_, vamos voltar a falar de CRISP-DM:\n", + "\n", + "CRISP-DM significa _Cross Industry Standard Process for Data Mining_ ou processos ou fases para desenvolvimento de projetos relacionados à _Data Mining_ e que tem sido muito utilizados pelos Cientistas de Dados para desenvolvimento de modelos predictivos.\n", + "\n", + "\"Drawing\"\n", + "\n", + "Fonte: [The steps to a successful machine learning project](https://emba.epfl.ch/2018/04/10/steps-successful-machine-learning-project/)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1ssJuKF3FNA3" + }, + "source": [ + "* CRISP-DM:\n", + " 1. _Business Understanding_ (Entendimento do Negócio)\n", + " * Concentra-se no entendimento dos objetivos e requisitos do projeto sob uma perspectiva de negócios e, em seguida, na conversão desse conhecimento em uma definição de problema de mineração de dados e em um plano preliminar.\n", + "\n", + " 2. _Data Understanding_ (Entendimento/compreensão dos dados)\n", + " * Está relacionado com as atividades de extração de amostras para se familiarizar com os dados, identificar problemas de qualidade, descobrir as primeiras idéias ou detectar subconjuntos interessantes para formar hipóteses de informações ocultas.\n", + "\n", + " 3. _Data Preparation_ (Preparação de Dados)\n", + "\n", + " * Abrange todas as atividades para construir o conjunto de dados final que será dividida entre amostra de treinamento e validação do modelo preditivo.\n", + "\n", + " 4. _Modeling_ (Modelagem)\n", + "\n", + " * Nesta fase se avalia as possíveis técnicas que podem ser aplicadas.\n", + "\n", + " 5. _Evaluation_ (Avaliação do modelo)\n", + "\n", + " * Após a construção do modelo _baseline_ (modelo inicial) e tendo _Loss Function_ pré-definidas, avalia-se ou testa-se a performance dos modelos preditivos (Redes Neurais, no nosso caso) para garantir que o modelo generaliza. De todos os modelos testados nesta fase, devemos selecionar o modelo campeão.\n", + "\n", + " 6. _Deployment_ (Implantação)\n", + "\n", + " * Significa implementar o código do modelo em um sistema operacional para pontuar/escorar ou categorizar novos dados à medida que surgem e criar um mecanismo para o uso dessas novas informações na solução do problema comercial original. Importante, a representação de código também deve incluir todas as etapas de preparação de dados que antecederam a modelagem, para que o modelo trate novos dados brutos da mesma maneira que durante o desenvolvimento do modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VrgiPmD3jw_o" + }, + "source": [ + "#### Estratégias para melhorar a acurácia da Rede Neural\n", + "\n", + "Nossas alternativas são:\n", + "\n", + "* a. Aumentar o número de neurônios na _Hidden Layer_;\n", + "* b. Aumentar o número de _Hidden Layers_;\n", + "* c. Aumentar o número de _Hidden Layers_ e o número de neurônios;\n", + "* d. Alterar a função de ativação;\n", + "* e. Aumentar o número de _epochs_;\n", + "* f. Alterar o algoritmo de otimização (_optimizer_);\n", + "\n", + "Neste exemplo, depois de várias tentativas, obtive sucesso alterando os parâmetros a seguir: \n", + "* Função de ativação: alterar para tf.keras.activations.relu;\n", + "* Número de neurônios na camada escondida (_Hidden Layer_): aumentei para 64." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V81AQ9t8IA9D" + }, + "source": [ + "#### 7.3. Definir a arquitetura da Rede Neural com Tensorflow/Keras" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yVhR55OoaWeX" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação:\n", + " * _Hidden Layer_: tf.keras.activations.relu;\n", + " * _Output Layer_: Os valores de $y_{i}$ do dataframe são binários. Portanto, nossa opção para função de ativação para a _Output Layer_ é usar a função de ativação _Sigmoid_." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "R26Rf7x_aWeZ" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2 # NÃO FOI ALTERADA!\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1 # NÃO FOI ALTERADA!\n", + "\n", + "# VARIÁVEIS ALTERADAS:\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 64\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.relu # ALTERADA!\n", + "\n", + "# Função de Ativação da Output Layer\n", + "FA_O = tf.keras.activations.sigmoid # NÃO FOI ALTERADA!" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LtQXjYnvIdJR" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WSCCZ6BcIdJZ" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MwjdTXWNawSz" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OWpJNRQjIRA4" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "khod_vL5awS2", + "outputId": "6a9845e8-bc9a-4274-d7c7-cf72da60efd1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN = Sequential()\n", + "RN.add(Dense(units = N_H, input_dim = N_I, activation = FA_H, kernel_constraint = tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units = N_O, activation = FA_O))\n", + "\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Model: \"sequential_6\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "dense_12 (Dense) (None, 64) 192 \n", + "_________________________________________________________________\n", + "dense_13 (Dense) (None, 1) 65 \n", + "=================================================================\n", + "Total params: 257\n", + "Trainable params: 257\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n", + "None\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8V5EygkgIRA8" + }, + "source": [ + "#### 7.4. Compilar a Rede Neural\n", + "\n", + "> Adam é um algoritmo de otimização.\n", + "\n", + "Para saber mais sobre 'adam', consulte o artigo [Gentle Introduction to the Adam Optimization Algorithm for Deep Learning](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aEgVJAInbFW0" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FRhAlexLW29o" + }, + "source": [ + "#Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Algoritmo_Opt = tf.keras.optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False,\n", + " name='Adam')\n", + "\n", + "Loss_Function = tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = [tf.keras.metrics.binary_accuracy]\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jxpOHzSKIRA-" + }, + "source": [ + "#### 7.5. Ajustar a Rede Neural\n", + "\n", + "1 _Epoch_ = 1 iteração da Rede Neural, passando por todo o dataframe de treinamento, sendo que 1 iteração contempla 1 processo _Forward_ e 1 processo _Backward_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o-1iqXLabR4O" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vqyeqpq5XGAm", + "outputId": "61a23fa8-3b38-44ec-d01e-b5b936b50903", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "RN.fit(X_XOR, y_XOR, epochs = 100)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Epoch 1/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0820 - binary_accuracy: 1.0000\n", + "Epoch 2/100\n", + "1/1 [==============================] - 0s 1ms/step - loss: 0.0798 - binary_accuracy: 1.0000\n", + "Epoch 3/100\n", + "1/1 [==============================] - 0s 1ms/step - loss: 0.0735 - binary_accuracy: 1.0000\n", + "Epoch 4/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0681 - binary_accuracy: 1.0000\n", + "Epoch 5/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0643 - binary_accuracy: 1.0000\n", + "Epoch 6/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0605 - binary_accuracy: 1.0000\n", + "Epoch 7/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0571 - binary_accuracy: 1.0000\n", + "Epoch 8/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0537 - binary_accuracy: 1.0000\n", + "Epoch 9/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0503 - binary_accuracy: 1.0000\n", + "Epoch 10/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0471 - binary_accuracy: 1.0000\n", + "Epoch 11/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0440 - binary_accuracy: 1.0000\n", + "Epoch 12/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0411 - binary_accuracy: 1.0000\n", + "Epoch 13/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0384 - binary_accuracy: 1.0000\n", + "Epoch 14/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0359 - binary_accuracy: 1.0000\n", + "Epoch 15/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0336 - binary_accuracy: 1.0000\n", + "Epoch 16/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0313 - binary_accuracy: 1.0000\n", + "Epoch 17/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0292 - binary_accuracy: 1.0000\n", + "Epoch 18/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0272 - binary_accuracy: 1.0000\n", + "Epoch 19/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0253 - binary_accuracy: 1.0000\n", + "Epoch 20/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0235 - binary_accuracy: 1.0000\n", + "Epoch 21/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0217 - binary_accuracy: 1.0000\n", + "Epoch 22/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0201 - binary_accuracy: 1.0000\n", + "Epoch 23/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0187 - binary_accuracy: 1.0000\n", + "Epoch 24/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0173 - binary_accuracy: 1.0000\n", + "Epoch 25/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0159 - binary_accuracy: 1.0000\n", + "Epoch 26/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0147 - binary_accuracy: 1.0000\n", + "Epoch 27/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0136 - binary_accuracy: 1.0000\n", + "Epoch 28/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0126 - binary_accuracy: 1.0000\n", + "Epoch 29/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0116 - binary_accuracy: 1.0000\n", + "Epoch 30/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0107 - binary_accuracy: 1.0000\n", + "Epoch 31/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0099 - binary_accuracy: 1.0000\n", + "Epoch 32/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0091 - binary_accuracy: 1.0000\n", + "Epoch 33/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0084 - binary_accuracy: 1.0000\n", + "Epoch 34/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0078 - binary_accuracy: 1.0000\n", + "Epoch 35/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0072 - binary_accuracy: 1.0000\n", + "Epoch 36/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0067 - binary_accuracy: 1.0000\n", + "Epoch 37/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0063 - binary_accuracy: 1.0000\n", + "Epoch 38/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0058 - binary_accuracy: 1.0000\n", + "Epoch 39/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0054 - binary_accuracy: 1.0000\n", + "Epoch 40/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0051 - binary_accuracy: 1.0000\n", + "Epoch 41/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0048 - binary_accuracy: 1.0000\n", + "Epoch 42/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0045 - binary_accuracy: 1.0000\n", + "Epoch 43/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0042 - binary_accuracy: 1.0000\n", + "Epoch 44/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0040 - binary_accuracy: 1.0000\n", + "Epoch 45/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0038 - binary_accuracy: 1.0000\n", + "Epoch 46/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0036 - binary_accuracy: 1.0000\n", + "Epoch 47/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0034 - binary_accuracy: 1.0000\n", + "Epoch 48/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0032 - binary_accuracy: 1.0000\n", + "Epoch 49/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0030 - binary_accuracy: 1.0000\n", + "Epoch 50/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0029 - binary_accuracy: 1.0000\n", + "Epoch 51/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0028 - binary_accuracy: 1.0000\n", + "Epoch 52/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0026 - binary_accuracy: 1.0000\n", + "Epoch 53/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0025 - binary_accuracy: 1.0000\n", + "Epoch 54/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0024 - binary_accuracy: 1.0000\n", + "Epoch 55/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0023 - binary_accuracy: 1.0000\n", + "Epoch 56/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0022 - binary_accuracy: 1.0000\n", + "Epoch 57/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0022 - binary_accuracy: 1.0000\n", + "Epoch 58/100\n", + "1/1 [==============================] - 0s 5ms/step - loss: 0.0021 - binary_accuracy: 1.0000\n", + "Epoch 59/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0020 - binary_accuracy: 1.0000\n", + "Epoch 60/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0019 - binary_accuracy: 1.0000\n", + "Epoch 61/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0019 - binary_accuracy: 1.0000\n", + "Epoch 62/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0018 - binary_accuracy: 1.0000\n", + "Epoch 63/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0017 - binary_accuracy: 1.0000\n", + "Epoch 64/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0017 - binary_accuracy: 1.0000\n", + "Epoch 65/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0016 - binary_accuracy: 1.0000\n", + "Epoch 66/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0016 - binary_accuracy: 1.0000\n", + "Epoch 67/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0016 - binary_accuracy: 1.0000\n", + "Epoch 68/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0015 - binary_accuracy: 1.0000\n", + "Epoch 69/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0015 - binary_accuracy: 1.0000\n", + "Epoch 70/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0014 - binary_accuracy: 1.0000\n", + "Epoch 71/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0014 - binary_accuracy: 1.0000\n", + "Epoch 72/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0014 - binary_accuracy: 1.0000\n", + "Epoch 73/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0013 - binary_accuracy: 1.0000\n", + "Epoch 74/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0013 - binary_accuracy: 1.0000\n", + "Epoch 75/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0013 - binary_accuracy: 1.0000\n", + "Epoch 76/100\n", + "1/1 [==============================] - 0s 4ms/step - loss: 0.0012 - binary_accuracy: 1.0000\n", + "Epoch 77/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0012 - binary_accuracy: 1.0000\n", + "Epoch 78/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0012 - binary_accuracy: 1.0000\n", + "Epoch 79/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0012 - binary_accuracy: 1.0000\n", + "Epoch 80/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0011 - binary_accuracy: 1.0000\n", + "Epoch 81/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0011 - binary_accuracy: 1.0000\n", + "Epoch 82/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0011 - binary_accuracy: 1.0000\n", + "Epoch 83/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 0.0011 - binary_accuracy: 1.0000\n", + "Epoch 84/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0010 - binary_accuracy: 1.0000\n", + "Epoch 85/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 0.0010 - binary_accuracy: 1.0000\n", + "Epoch 86/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 9.9890e-04 - binary_accuracy: 1.0000\n", + "Epoch 87/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 9.8004e-04 - binary_accuracy: 1.0000\n", + "Epoch 88/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 9.6182e-04 - binary_accuracy: 1.0000\n", + "Epoch 89/100\n", + "1/1 [==============================] - 0s 1ms/step - loss: 9.4389e-04 - binary_accuracy: 1.0000\n", + "Epoch 90/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 9.2633e-04 - binary_accuracy: 1.0000\n", + "Epoch 91/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 9.0949e-04 - binary_accuracy: 1.0000\n", + "Epoch 92/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 8.9346e-04 - binary_accuracy: 1.0000\n", + "Epoch 93/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 8.7824e-04 - binary_accuracy: 1.0000\n", + "Epoch 94/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 8.6300e-04 - binary_accuracy: 1.0000\n", + "Epoch 95/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 8.4822e-04 - binary_accuracy: 1.0000\n", + "Epoch 96/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 8.3342e-04 - binary_accuracy: 1.0000\n", + "Epoch 97/100\n", + "1/1 [==============================] - 0s 3ms/step - loss: 8.1917e-04 - binary_accuracy: 1.0000\n", + "Epoch 98/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 8.0674e-04 - binary_accuracy: 1.0000\n", + "Epoch 99/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 7.9473e-04 - binary_accuracy: 1.0000\n", + "Epoch 100/100\n", + "1/1 [==============================] - 0s 2ms/step - loss: 7.8255e-04 - binary_accuracy: 1.0000\n" + ], + "name": "stdout" + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 101 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C25ZV-x4IRBB" + }, + "source": [ + "#### 7.6. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tCd2S65ubg_M" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I8-Vr9lXXav4", + "outputId": "41470be9-af29-4751-a957-035de23b7eca", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "RN.evaluate(X_XOR, y_XOR)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "1/1 [==============================] - 0s 1ms/step - loss: 0.1502 - binary_accuracy: 1.0000\n" + ], + "name": "stdout" + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.1501958817243576, 1.0]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 70 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6IqEhL-2Xj-t" + }, + "source": [ + "**Resultado**: O modelo após o _fine tuning_ apresenta os seguintes resultados:\n", + "* loss= 0.1502;\n", + "* accuracy= 100%.\n", + "\n", + "* **Comentário**: A Rede Neural apresenta resultados satisfatórios." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AZjDavkO58Pu" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HV4HkNDcbmJ2" + }, + "source": [ + "[**Python**] - Comando RN.predict_classes(X_treinamento):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aum69OJENO6V", + "outputId": "cc3c4c3d-6e7e-4c16-baf9-80ed53ba8485", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_pred = RN.predict_classes(X_XOR)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From :1: Sequential.predict_classes (from tensorflow.python.keras.engine.sequential) is deprecated and will be removed after 2021-01-01.\n", + "Instructions for updating:\n", + "Please use instead:* `np.argmax(model.predict(x), axis=-1)`, if your model does multi-class classification (e.g. if it uses a `softmax` last-layer activation).* `(model.predict(x) > 0.5).astype(\"int32\")`, if your model does binary classification (e.g. if it uses a `sigmoid` last-layer activation).\n" + ], + "name": "stdout" + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [0]], dtype=int32)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 95 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rNogASabEhz8", + "outputId": "948e70f5-35fd-4932-b106-2b87950c6ca6", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "y_XOR" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [0]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 96 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8xaBkwD15-1d" + }, + "source": [ + "### 9. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UULwoI-9yPIs" + }, + "source": [ + "A Rede Neural final, após a fase de _fine tuning_ apresenta os resultados mostrados na sessão 7.6. Diante destes resultados, sugerimos avançarmos para a fase de _deployment_ da Rede Neural, conforme sugere o CRISP-DM." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uFK4SeM5TLOb" + }, + "source": [ + "### **Exercício**\n", + "\n", + "1. Experimente usar outras funções de ativação para a _Hidden Layer_, registre e reporte seus resultados. Para saber mais sobre quais funções de ativação podem ser usadas, consulte [Module: tf.keras.activations](https://www.tensorflow.org/api_docs/python/tf/keras/activations);\n", + "\n", + "2. Experimente usar outros algoritmos de otimização para treinar a Rede Neural, registre e reporte seus resultados. Para saber quais algoritmos podem ser usados, consulte [Module: tf.keras.optimizers](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers).\n", + "\n", + "3. Neste exemplo, usamos o algoritmo de otimização 'adam'. Consulte a documentação sobre o 'adam' no Tensorflow/Keras e você verá que a sintaxe do algoritmo é:\n", + "\n", + "```\n", + "tf.keras.optimizers.Adam(\n", + " learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False,\n", + " name='Adam', **kwargs\n", + ")\n", + "```\n", + "\n", + "Refaça o treinamento da Rede Neural alterando os valores da _Learning Rate_ e reporte seus resultados.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pyyiNwm6eeP4" + }, + "source": [ + "___\n", + "# **_ACTIVATION FUNCTION_**\n", + "\n", + "> As funções de ativação são uma importante parte das Redes Neurais, pois permitem às Redes Neurais a lidar com a não-linearidade existente na maioria dos problemas reais.\n", + "\n", + "As funções de ativação (_Activation Function_ em inglês) mais usadas são:\n", + "* _Sigmoid_;\n", + "* ReLU (_Rectified Linear Unit_);\n", + "* Leaky ReLU;\n", + "* _Generalized_ ReLU;\n", + "* Tanh;\n", + "* _Swish_.\n", + "\n", + "Os artigos a seguir discutem estas principais funções de ativação:\n", + "* [Classical Neural Net: Why/Which Activations Functions?](https://towardsdatascience.com/classical-neural-net-why-which-activations-functions-401159ba01c4);\n", + "* [Intermediate Topics in Neural Networks](https://towardsdatascience.com/comprehensive-introduction-to-neural-network-architecture-c08c6d8e5d98);\n", + "* [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7jF5SToOKYC" + }, + "source": [ + "### Funções de ativação para _Hidden Layers_:\n", + "\n", + "Há várias funções de ativação que podem ser utilizadas na _Hidden Layer_. As principais são:\n", + "\n", + "* ReLU\n", + " * evita e corrige o problema conhecido como _vanishing gradient problem_, que é justamente o principal ponto fraco das funções de ativação _sigmoid_ e _tanh_. Este problema acontece porque algumas derivadas são zero para metade dos valores da entrada $X = [X_{1}, X_{2}, ..., X_{n}]$, o que pode levar ao que se chama de \"neurônios mortos\";\n", + " * Quase todos os modelos de _Deep Learning_ hoje usam ReLU que **deve ser usada somente para _Hidden Layers_ das Redes Neurais**. \n", + "* Leaky ReLU\n", + " * Alternativa melhor que ReLU;\n", + "* _Swish_\n", + " * esta é outra alternativa melhor que ReLU, proposta pelo Google em 2017;\n", + " * alguns artigos apontam melhoria dos resultados das Redes Neurais com _Swish_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8dYvHeYbN_c4" + }, + "source": [ + "### Funções de ativação para _Output Layers_:\n", + "\n", + "A função de ativação da _Output Layer_ depende do problema:\n", + "\n", + "* _Sigmoid_ para problemas de classificação binária (2 classes).\n", + " * Exemplo: Dataframe: Titanic, pois queremos estimar se o passageiro morreu ou sobreviveu;\n", + "* _Softmax_ para problemas de classificação multi-classes (> 2 classes).\n", + " * Exemplo: Dataframe: Iris, pois queremos estimar a espécie das flores, que são versicolor, virginica e setosa;\n", + "* _Linear_ para problemas de regressão. \n", + " * Exemplo: Dataframe: Boston Housing Prediction, pois queremos estimar o preço das casas em Boston, que é uma variável contínua.\n", + "\n", + "\n", + "O artigo [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a) compara e discute as principais funções de ativação de forma pormenorizada." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "clQq59rPIkvB" + }, + "source": [ + "___\n", + "# **EXEMPLO 1: Rede Neural para identificar o sexo a partir de peso e altura**\n", + "\n", + "> O dataframe a seguir contem 10.000 medidas de altura (_height_) e peso (_weight_), sendo 5.000 medidas para o sexo masculino (_males_) e 5.000 para o sexo feminino (_females_).\n", + "\n", + "**Objetivo**: Estimar gênero (sexo) (_Gender_, em inglês) em função das variáveis _Height_ e _Weight_.\n", + "\n", + "Fonte do dataframe: Kaggle (weight-height.csv).\n", + "\n", + "Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dh5p2GcvLQQX" + }, + "source": [ + "### 0. Carregar as principais bibliotecas" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bhjAdXgab99r" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kChuTlPddNZv" + }, + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from tensorflow import keras\n", + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ZX00UN5cjvM" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "THWNIk_FCe_g" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PZgQAKqLcLX3" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tzKor02BCe_d" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M5V4KopjLWOL" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V_cwAUW3tseE" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_Bs87IWPtwtm" + }, + "source": [ + "# Leitura do dataframe:\n", + "df_sexo = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/weight-height.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mBUeMtV7tzw6" + }, + "source": [ + "[**Python**] - Mostrar as primeiras 5 linhas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rcH-y4amt3gs" + }, + "source": [ + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OSa161sPLcAw" + }, + "source": [ + "### Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lL2-6wpCuARF" + }, + "source": [ + "[**Python**] - Construir coluna 'sexo' da seguinte forma:\n", + "* Se Gender= 'Male' ==> sexo= 1;\n", + "* Se Gender= 'Female' ==> sexo= 0." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccImSqCqDKre" + }, + "source": [ + "def define_label(row):\n", + " if row['Gender'] == 'Male':\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NDYamauZCq77" + }, + "source": [ + "df_sexo['sexo'] = df_sexo.apply(lambda row: define_label(row), axis = 1)\n", + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hqkOrJnNuZjg" + }, + "source": [ + "[**Python**] - Renomear ou reescrever os nomes das colunas do dataframe em letras minúsculas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-dahUMI6DsBz" + }, + "source": [ + "df_sexo = df_sexo.drop(columns= 'Gender', axis= 1)\n", + "df_sexo = df_sexo.rename({'Height': 'altura', 'Weight': 'peso'}, axis= 1)\n", + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UTISVuZ4ukQO" + }, + "source": [ + "[**Python**] - Definir os arrays X_sexo e y_sexo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oMTIn6Zf5LlU" + }, + "source": [ + "X_sexo = df_sexo.copy()\n", + "X_sexo = X_sexo.drop(columns= ['sexo'])\n", + "y_sexo = df_sexo['sexo'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iSThKwhj4LsC" + }, + "source": [ + "y_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FiO_F95jc1_s" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4myPAnSzE7-l" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "\n", + "X_sexo= SS.fit_transform(X_sexo)\n", + "X_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJaJWuUqJCha" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LoO2iEimu4SQ" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hTCdm-F9JBGA" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste= train_test_split(X_sexo, y_sexo, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "th9CsQpB8VDK" + }, + "source": [ + "print(f'Y: Treinamento = {y_treinamento.shape}; Y: Teste = {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2bL-vXiULupD" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zxETX6dTfyU5" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "F_MdsLicfyU6" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 64\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.swish\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O = tf.keras.activations.swish" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SUMmDuPCcYyB" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T-echOBmceVy" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7ZceRRdinEM2" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXQsSYq2DBfI" + }, + "source": [ + "* 1 camada _dropout_ com $p= 0.1$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TRFR5Kr_nDtD" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "#RN.add(Dense(N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "#RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4JBZf4ypGO8o" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (_Male_ ou _Female_). Portanto, temos:\n", + "* optimizer= tf.keras.optimizers.Adam();\n", + "* loss= tf.keras.losses.MeanSquaredError() ou loss= tf.keras.losses.BinaryCrossentropy(). Particularmente, eu gosto de usar loss= tf.keras.losses.MeanSquaredError() porque o resultado é mais intuitivo;\n", + "* metrics= tf.keras.metrics.binary_accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "USmAuw6f00wL" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h7KEi1_e6SSF" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Loss_Function = tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer = Algoritmo_Opt, loss = Loss_Function, metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Hc90EeV_GojX" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XCCTtUh_vEFP" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EB91J6nrF0db" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 5, min_delta = 0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs = 100, validation_data = (X_teste, y_teste), callbacks = callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "71mX1iwvHMc5" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o-zJ6GIjHbY8" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J1sL_DTrKmpq" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste. A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VckQfEFPvMa7" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rUhEiqxfKmpv" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "agO4cGTqKmpz" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aLIAXu7SN7pV" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D5zYHcGuMPZe" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Para aumentar a acurácia da Rede Neural, sugiro aumentarmos o número de neurônios na _Hidden Layer_ e/ou aumentar o número de _Hidden Layers_.\n", + "\n", + "No entanto, obtivemos uma acurácia razoável com a Rede Neural _baseline_. Portanto, deixo como exercício para os alunos o desafio de melhorar a acurácia desta Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_ISodOu-Kmp3" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_xgdL1W4vUrN" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0qun1-vOKmp4" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I7sRwTWGKmp8" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AvywP0nZMtA-" + }, + "source": [ + "### 10. Conclusões\n", + "\n", + "Desenvolvemos uma Rede Neural capaz de identificar Sexo (_Gender_) com acurácia= 0.9120." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g5qOWxPczM1O" + }, + "source": [ + "___\n", + "# **EXEMPLO 2: Distinguir cédulas verdadeiras das falsas**\n", + "\n", + "* O exemplo a seguir foi extraído do site [OpenML](https://www.openml.org/home). Este é um problema interessante, que é o de distinguir cédulas verdadeiras de notas falsas. Os dados foram extraídos de imagens tiradas de cédulas verdadeiras e falsas. Para digitalização, foi usada uma câmera industrial normalmente usada para inspeção de impressão. As imagens finais têm 400x 400 pixels. Devido à lente do objeto e à distância do objeto investigado, foram obtidas imagens em escala de cinza com uma resolução de cerca de 660 dpi. Uma ferramenta Wavelet Transform foi usada para extrair recursos dessas imagens.\n", + "\n", + "* Este é o endereço do dataframe: https://www.openml.org/d/1462;\n", + "* Descrição das variáveis - [banknote authentication Data Set](https://archive.ics.uci.edu/ml/datasets/banknote+authentication).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nup7tuLc5kYy" + }, + "source": [ + "> A seguir, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ para classificar notas falsas e verdadeiras. Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YHi73Pbq5vvU" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsZW7_Ev5vvY" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U4OySJw5vvb" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lAaecKoj5vv5" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5lPEsFy45vv6" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uNvl-o5w5vvo" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VqRIBc1J5vvp" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8jo3Y9Hs5vwD" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tL7k4X--5vwE" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RTuRMwld5vwG" + }, + "source": [ + "df_cedulas= pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/Banknote-authentication-dataset.csv')\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "501b-Zv38ce7" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lBKafqZR8jFb" + }, + "source": [ + "df_cedulas.columns= df_cedulas.columns.str.lower()\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HBNIjNaT5vwM" + }, + "source": [ + "[**Python**] - Mostrar quantas classes há na variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c7mZgLDl5vwO" + }, + "source": [ + "df_cedulas['class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MG4q-8nf2GS_" + }, + "source": [ + "[**Python**] - Redefinindo a variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IA7f1C4e1zOS" + }, + "source": [ + "def Redefinir_label(row):\n", + " if row['class']== 1:\n", + " return 0\n", + " else:\n", + " return 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2DkBD1FU1zOo" + }, + "source": [ + "df_cedulas['class']= df_cedulas.apply(lambda row: Redefinir_label(row), axis= 1)\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I0j5o4Iu5vwT" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "32EZZ8eP5vwV" + }, + "source": [ + "j = sns.countplot(x=\"class\", data= df_cedulas)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dV8A71C55vwb" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Eg-4TkYSXvuo" + }, + "source": [ + "[**Python**] - Definir os arrays X_cedulas e y_cedulas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vn2yMB80Xvux" + }, + "source": [ + "X_cedulas = df_cedulas.copy()\n", + "X_cedulas = X_cedulas.drop(columns = ['class'])\n", + "y_cedulas = df_cedulas['class'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nckf3bieXvvC" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CFTlvOcRXvvE" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "\n", + "X_cedulas = SS.fit_transform(X_cedulas)\n", + "X_cedulas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q_ouZ1it5vwz" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T6NrbTvd5vw1" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação da Rede Neural:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xw3ZZ2fR5vw1" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_cedulas, y_cedulas, test_size = 0.1, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "trfqJbUg5vw8" + }, + "source": [ + "print(f'X: Treinamento = {X_treinamento.shape}; X: Teste = {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "duDt1c7i5vxB" + }, + "source": [ + "print(f'Y: Treinamento = {y_treinamento.shape}; Y: Teste = {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e4TKmGtr5vxM" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f6EQymRK5vxO" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JlUflDN3YkG7" + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bRsHYQp05vxO" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = X_treinamento.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer 1:\n", + "N_H1 = 8\n", + "\n", + "# Número de neurônios na Hidden Layer 2:\n", + "N_H2 = 8\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.swish\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O = tf.keras.activations.sigmoid" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sSOj8_9n5vxU" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wFYGSoKH5vxU" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WG1isER05vxZ" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A6IPYp8l5vxa" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sCRp8O4V5vxa" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN = Sequential()\n", + "RN.add(Dense(units = N_H1, input_dim = N_I, activation = FA_H, kernel_initializer = tf.keras.initializers.GlorotUniform(1)))#, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units = N_O, activation = FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Titw0r-d5vxh" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oVQsayDq5vxi" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u686jTkd5vxj" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Loss_Function = tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss = Loss_Function, metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BKN3oCa65vxn" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Nesta fase, precisamos informar:\n", + "* **Epoch**: O número de épocas é um hiperparâmetro do _Gradient Descent_ que define o número de iterações para atualizar os pesos $W$ usando o dataframe de treinamento. Uma época significa que cada amostra no dataframe de treinamento atualizou os pesos $W$ 1 vez.\n", + "* **Batch**: número de amostras consideradas pela Rede Neural em cada _epoch_ antes da atualização dos pesos $W$;\n", + "\n", + "#### Exemplo\n", + "Suponha que temos um dataframe com 1.000 linhas (instâncias) e optamos por _epoch_= 1.000 e _batch_= 5. Isso significa que o dataframe será dividido em $\\frac{1000}{5}= 200$ _batches_. Desta forma, os pesos $W$ serão atualizados a cada processamento de 200 instâncias (linhas).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vLHQdKsi5vxn" + }, + "source": [ + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q6UMutI45vxp" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2YhUEbTC5vxq" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 3, min_delta = 0.001)]\n", + "\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data = (X_teste, y_teste), callbacks = callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jFmtvTwd5vxu" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X8Lu0jh55vxz" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sKh0f7Mc5vx4" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste.\n", + "\n", + "A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p7nsNQoX5vx5" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B1OvhTbf5vx6" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z8v2aody5vx-" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0FQy0bZT5vx_" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n8e327A_5vx_" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TiVyZ-CG5vyE" + }, + "source": [ + "y_teste" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PawhHD_35vyI" + }, + "source": [ + "### Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RcIh4qua_eEU" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 1 - Rede Neural para identificar espécies (Iris Dataframe)**\n", + "\n", + "> A seguir, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ para classificar flores (Iris). Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eXRYOpPR4XF4" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pa0ir9C_dgOO" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yNYF_qzydgOR" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ird1VzZudgOU" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lwj9CGzEdgOV" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zmN5HGLOdgOa" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VI86wuv9dgOa" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NoKZnsJpRA8o" + }, + "source": [ + "Perfeito, estamos a usar o TensorFlow 2.x." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xkLZgdkjavO-" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b7LLQyA3vgBG" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ACzNibyKAkx_" + }, + "source": [ + "df_Iris= pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/Iris.csv', index_col= 'Id')\n", + "df_Iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T3Vy41RL-lAQ" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xN7nBQWg-lAX" + }, + "source": [ + "df_Iris.columns= df_Iris.columns.str.lower()\n", + "df_Iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Em1wLwdzvkgh" + }, + "source": [ + "[**Python**] - Mostrar quantas classes há na variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QhuoPcRuA9Do" + }, + "source": [ + "df_Iris['species'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lvWcxUvru50G" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'Species':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HMpJiMWJu50J" + }, + "source": [ + "j = sns.countplot(x=\"species\", data= df_Iris)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a55-G14aa_wG" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uos9OyewvyMo" + }, + "source": [ + "[**Python**] - Aplicar a transformação LabelEncoder() nos dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X0V0hWnBg0so" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "\n", + "LE = LabelEncoder()\n", + "\n", + "species_encoded= LE.fit_transform(df_Iris['species'])\n", + "df_Iris= df_Iris.drop(columns= ['species'], axis= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d8L-b9gZwB4L" + }, + "source": [ + "[**Python**] - Definir o array y_Iris:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zMp2_hJ1wGm3" + }, + "source": [ + "y_Iris= tf.keras.utils.to_categorical(species_encoded)\n", + "y_Iris[:5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qfFg6cWdv9El" + }, + "source": [ + "[**Python**] - Definir o array X_Iris:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7coeWhVRjiQl" + }, + "source": [ + "X_Iris= df_Iris.values\n", + "X_Iris[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cUa2sJOSbUFO" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kDOw-RHux1nS" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação da Rede Neural:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AJE_6w3KL_2O" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste= train_test_split(X_Iris, y_Iris, test_size= 0.2, random_state= 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NKHTG5IP9nVj" + }, + "source": [ + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qe2mHJhb-PIY" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wHFI_bLXPPvl" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zRYoZ7hwgejR" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mjF1haRmgejS" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X.Treinamento.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= y_Iris.shape[1]\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 32\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tGeDaB3oo02k" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zGS15afAo02n" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iT9w2tUCo5-X" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nytcmC4BkSz1" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LnLeLMmZoUjU" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3eT-EHUecTj3" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação multi-classes (> 2 classes). Portanto, temos:\n", + "* loss= tf.keras.losses.CategoricalCrossentropy()\n", + ";\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fsq0aEtwyAAM" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NDStOKqhcRf4" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.CategoricalCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hZFu65TecabN" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Nesta fase, precisamos informar:\n", + "* **Epoch**: O número de épocas é um hiperparâmetro do _Gradient Descent_ que define o número de iterações para atualizar os pesos $W$ usando o dataframe de treinamento. Uma época significa que cada amostra no dataframe de treinamento atualizou os pesos $W$ 1 vez.\n", + "* **Batch**: número de amostras consideradas pela Rede Neural em cada _epoch_ antes da atualização dos pesos $W$;\n", + "\n", + "#### Exemplo\n", + "Suponha que temos um dataframe com 1.000 linhas (instâncias) e optamos por _epoch_= 1.000 e _batch_= 5. Isso significa que o dataframe será dividido em $\\frac{1000}{5}= 200$ _batches_. Desta forma, os pesos $W$ serão atualizados a cada processamento de 200 instâncias (linhas).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "boIs266gaZt1" + }, + "source": [ + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LpR3dXRZ-jom" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9hDxEwHjca8V" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 3, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JF7EC-g82Hho" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ea0HHBsY2NZ5" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pqVJMX3xchLF" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste.\n", + "\n", + "A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hKbO1nT0yQM1" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cYqDY9V9chcZ" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qchEpyipcnbE" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9X2SZ5fx2_s5" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FR6ySksLhRvR" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LWnRgBbmmlA2" + }, + "source": [ + "y_teste" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wjCtiKieE_TT" + }, + "source": [ + "### Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LxMzVIGzzGHH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qjSoM5quog1" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 2 - Rede Neural para identificar o tipo do vinho (_Red or White_)**\n", + "\n", + "> Nesta aplicação, vamos usar o dataframe [wine quality](https://archive.ics.uci.edu/ml/datasets/wine+quality) extraído do repositório da UCI Machine Learning Repository. Nosso objetivo é prever o tipo do vinho (red ou white) baseado nas suas propriedades químicas.\n", + "\n", + "Novamente, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VuG8zbYS4jyx" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O3XD4otFd9Ht" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I5Ok5fhid9Hv" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZBXRTgnCd9Hz" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NFrOyNUgd9Hz" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cGxW2zn6q8xY" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C36Z6vGD4jy8" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kWJXP5diof5G" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJJe4r_ITDzv" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jIjqYXlH4tyG" + }, + "source": [ + "from sklearn.datasets import load_wine\n", + "Wine= load_wine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5iU33wKQGrFb" + }, + "source": [ + "df_Red= pd.read_table(\"http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv\", sep=';')\n", + "df_Red.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Liy2KSr6HJUX" + }, + "source": [ + "df_White= pd.read_table('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv', sep= ';')\n", + "df_White.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4TzUnuM4TMmJ" + }, + "source": [ + "[**Python**] - Mostrar o número de linhas e colunas de cada dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pHNwVRQyIwdv" + }, + "source": [ + "print(f'Dimensão de df_Red: {df_Red.shape}; Dimensão de df_White: {df_White.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBWzMsUHJjTU" + }, + "source": [ + "[**Python**] - Construir a variável-target 'type_wine' (tipo do vinho):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B0WmX3FYJqMR" + }, + "source": [ + "df_Red['type_wine']= 0\n", + "df_White['type_wine']= 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EVUc1vbqJ0D9" + }, + "source": [ + "[**Python**] - Empilhar os dois dataframes: df_Red e df_White:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gS9SlpvaJ2Ex" + }, + "source": [ + "df_Wine= pd.concat([df_Red, df_White], ignore_index=True)\n", + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dM19HHENKMtq" + }, + "source": [ + "df_Wine.tail()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mpoNmcqpeQxO" + }, + "source": [ + "[**Python**] - Mostrar o número de linhas e colunas do dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YJDazoMMeMet" + }, + "source": [ + "df_Wine.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tNyjXmFzo7oe" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xcV_dlHsTpiP" + }, + "source": [ + "[**Python**] - Renomear o nome das colunas usando letras minúsculas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jau2OybudGc0" + }, + "source": [ + "df_Wine.columns = df_Wine.columns.str.strip().str.lower().str.replace(' ', '_')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EzOWiaCFdq_C" + }, + "source": [ + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F1wgkLcvete8" + }, + "source": [ + "[**Python**] - Estatísticas descritivas do dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A-EbHitYepeQ" + }, + "source": [ + "df_Wine.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uRo_7tOjex3Z" + }, + "source": [ + "#### _Missing Values Handling_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wJ3K_FmCUCsk" + }, + "source": [ + "[**Python**] - Mostrar o número de _missing values_ no dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PODgu5B6e5qQ" + }, + "source": [ + "df_Wine.info()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "szH_TGJZecXp" + }, + "source": [ + "Como podem ver, o dataframe df_Wine não contem _missing values_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "64znO089vF_2" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'type_wine':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ztQ17lhWfdAu" + }, + "source": [ + "df_Wine['type_wine'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zDRVQy5avF_4" + }, + "source": [ + "j = sns.countplot(x=\"type_wine\", data= df_Wine)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PxexO1Uyeqnj" + }, + "source": [ + "Como podem ver, temos 6.497 instâncias, das quais 4.898 (75%) instâncias são type_wine= 1 (_white_) e 1.599 (25%) instâncias são type_wine= 0 (_red_). Logo, trata-se de um dataframe desbalanceado. No entanto, não vou me preocupar com este assunto neste Notebook e deixo para os alunos como exercício verificar os efeitos das amostras desbalanceadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kr_HZnF0UUh3" + }, + "source": [ + "[**Python**] - Definir os arrays X_Wine e y_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HNvImi4djc-3" + }, + "source": [ + "X_Wine= df_Wine.copy()\n", + "X_Wine= X_Wine.drop(columns= ['type_wine'])\n", + "y_Wine= df_Wine['type_wine'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ViMFMd_SlE3x" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OurlnbX3hzSb" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler()\n", + "\n", + "# Scale o dataframe\n", + "X_Wine = SS.fit_transform(X_Wine)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFkJ7b4U1x3D" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MBqzBcDL2JH4" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bCQUxbbxhVTM" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Wine, y_Wine, test_size= 0.2, random_state= 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HHmTtQ3F9A9c" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pPW0aWd4jw0o" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ea4WTsP-hCqS" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y1pVFjFThCqU" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Wine.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 7\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.leaky_relu" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "url8178EpUNO" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MU-8uWn-pUNQ" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6TLUirr6oXv1" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8HOQIkQ3beJm" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bj5uJvgaj43u" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LTs8xbKx2O3Z" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (_red_ ou _white_). Portanto, temos:\n", + "* loss= tf.keras.losses.BinaryCrossentropy();\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam().\n", + "\n", + "> **Lembre-se**: se o problema fosse de classificação de multi-classes (> 2 classes), então devemos usar loss= tf.keras.losses.CategoricalCrossentropy()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kUpBKJkl07KH" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qGZ1bKCo2L7A" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jBhkSc582ROC" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ls8FfHz0z2lX" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5mpbdiuJ2d1W" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 10, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sALJp9FQ2WGC" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cWR2rMLg2ZlQ" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ciXdkbVr2VDG" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RS4_cV5TyamK" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hkkxiqPe2gZK" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m8Vs47VV4RsV" + }, + "source": [ + "A Rede Neural tem acurácia= 0.9946." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RHQoDk533TRX" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vlWfMR-k7Qc1" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mCpp-MO0nXmj" + }, + "source": [ + "A seguir, outras medidas para avaliarmos a performance da Rede Neural:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oWF-wWfTnjQh" + }, + "source": [ + "# Import the modules from sklearn.metrics\n", + "from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, cohen_kappa_score" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MHD0CvGQnm0v" + }, + "source": [ + "# Precision \n", + "precision_score(y_teste, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ERoX4BeQnosC" + }, + "source": [ + "# Recall\n", + "recall_score(y_teste, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "l_2bS23Inq1p" + }, + "source": [ + "# F1 score\n", + "f1_score(y_teste,y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rLM1BSK2QfZm" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bGAigaBMQfZn" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H3yUb9tP2YfE" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CupPMVRo3a5q" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GePOr4EJ3mfn" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aO79VSBS3mfv" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oHlDHVp_KcLn" + }, + "source": [ + "### 10. Conclusão\n", + "\n", + "Desenvolvemos uma Rede Neural com 1 _Hidden Layer_ que atingiu acurácia de 0.998." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xr2VzmwPFRdr" + }, + "source": [ + "___\n", + "# **EXERCÍCIO 1**: Prever a qualidade do vinho\n", + "\n", + "Neste exercício, vamos considerar a variável quality como múltiplas classes.\n", + "\n", + "Novamente, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MYpF4TtpvXp4" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'quality':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WmeFj14PvXp6" + }, + "source": [ + "j = sns.countplot(x=\"quality\", data= df_Wine)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "smWNCLsMQWBI" + }, + "source": [ + "Muitas classes... Abaixo, KMeans para definirmos a quantidade de clusters." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Co4GNVexVUoP" + }, + "source": [ + "# Função adaptada de: https://www.geeksforgeeks.org/elbow-method-for-optimal-value-of-k-in-kmeans/\n", + "\n", + "from sklearn.metrics.pairwise import euclidean_distances, cosine_distances, manhattan_distances\n", + "from scipy.spatial.distance import cdist\n", + "\n", + "def Numero_Clusters_Elbow(X):\n", + " distortions = [] \n", + " inertias = [] \n", + " mapping1 = {} \n", + " mapping2 = {} \n", + " K = range(1,10) \n", + " for k in K:\n", + " #Building and fitting the model \n", + " kmeanModel = KMeans(n_clusters=k).fit(X) \n", + " kmeanModel.fit(X)\n", + " distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'),axis=1)) / X.shape[0]) \n", + " inertias.append(kmeanModel.inertia_)\n", + " mapping1[k] = sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'),axis=1)) / X.shape[0] \n", + " mapping2[k] = kmeanModel.inertia_ \n", + "\n", + " # Using the different values of Distortion\n", + " print('Cálculo da Distorção:')\n", + " for key,val in mapping1.items():\n", + " print(str(key)+' : '+str(val))\n", + "\n", + " plt.plot(K, distortions, 'bx-')\n", + " plt.xlabel('Values of K')\n", + " plt.ylabel('Distortion')\n", + " plt.title('The Elbow Method using Distortion')\n", + " plt.show() \n", + "\n", + " # Using the different values of Inertia\n", + " print('Cálculo da Inertia:')\n", + " for key,val in mapping2.items():\n", + " print(str(key)+' : '+str(val))\n", + "\n", + " plt.plot(K, inertias, 'bx-')\n", + " plt.xlabel('Values of K')\n", + " plt.ylabel('Inertia') \n", + " plt.title('The Elbow Method using Inertia')\n", + " plt.show() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eTA4O3yII-am" + }, + "source": [ + "X_WineQ= df_Wine.copy()\n", + "X_WineQ= X_WineQ.drop(columns= ['quality'])\n", + "X_WineQ= X_WineQ.values\n", + "#y_WineQ= df_Wine['quality2'].values\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJDCLdsalKvS" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7D9qCW6SYKwA" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler().fit(X_WineQ)\n", + "\n", + "# Scale o dataframe\n", + "X_WineQ = SS.transform(X_WineQ)\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "naLIn_ufIZtL" + }, + "source": [ + "Numero_Clusters_Elbow(X_WineQ)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "At5KtD-DV0f6" + }, + "source": [ + "Os gráficos acima mostram que o número de _clusters_ ótimos para o dataframe df_Wine é 3. Portanto, vamos trabalhar com n_cluster= 3 daqui para frente." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-Oz9kAvh5yPk" + }, + "source": [ + "Sugiro fazermos o seguinte agrupamento:\n", + "* Se quality= 1, 2, 3 $\\Longrightarrow$ quality2= 1 (qualidade ruim);\n", + "* Se quality= 4, 5, 6, 7 $\\Longrightarrow$ quality2= 2 (qualidade média);\n", + "* Se quality= 8, 9, 10 $\\Longrightarrow$ quality2= 3 (qualidade excelente)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nZc2OQR87E9n" + }, + "source": [ + "def define_quality2(row):\n", + " if row['quality'] <= 3:\n", + " return 1\n", + " elif row['quality'] > 3 and row['quality'] <= 7:\n", + " return 2\n", + " elif row['quality'] > 7:\n", + " return 3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f8zbLsN27E9t" + }, + "source": [ + "df_Wine['quality2']=df_Wine.apply(lambda row: define_quality2(row), axis= 1)\n", + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7ugFbdVm77wo" + }, + "source": [ + "df_Wine['quality2'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xf3RYZTwEtAD" + }, + "source": [ + "[**Python**] - Análise de Correlação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dimuJxsPEsAt" + }, + "source": [ + "corr = df_Wine.corr()['quality2'].drop('quality2')\n", + "print(corr)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "g9KALiQsEsAx" + }, + "source": [ + "plt.figure(figsize=(12,10))\n", + "cor = df_Wine.corr()\n", + "sns.heatmap(cor, annot=True, linewidths=0, vmin=-1, cmap=\"RdBu_r\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "At1XAt6AU2oh" + }, + "source": [ + "[**Python**] - Aplicar a transformação LabelEncoder:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kld7QvCaH1YQ" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "\n", + "LE = LabelEncoder()\n", + "LE.fit(df_Wine['quality2'])quality_Encoded= LE.transform(df_Wine['quality2'])\n", + "\n", + "y_WineQ= tf.keras.utils.to_categorical(quality_Encoded)\n", + "y_WineQ[:5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7qqY5vxeGEMC" + }, + "source": [ + "X_WineQ= df_Wine.copy()\n", + "X_WineQ= X.drop(columns= 'quality2', axis= 1)\n", + "X_WineQ.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oKnfuTQFlQLB" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_VSNAOQzGEMG" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler().fit(X_WineQ)\n", + "\n", + "# Scale o dataframe\n", + "X_WineQ = SS.transform(X_WineQ)\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zE5SV0ET-Zwv" + }, + "source": [ + "[**Python**] - Aplicar PCA para selecionar somente os atributos mais importantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I3IRWaIj-feA" + }, + "source": [ + "from sklearn.decomposition import PCA\n", + "\n", + "pca = PCA()\n", + "X_pca = pca.fit_transform(X_WineQ)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NbJ6NBcAVPO1" + }, + "source": [ + "[**Python**] - Proporção de variância explicada por cada componente principal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOqLh5BgVVN0" + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7j_cYnbSVGaT" + }, + "source": [ + "[**Python**] - Proporção acumulada de cada fator:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ux0lAfy2Ar6g" + }, + "source": [ + "pca.explained_variance_ratio_.cumsum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UzYqn7-A5He" + }, + "source": [ + "Como podemos ver acima, 8 componentes principais acumulam mais que 93% da variância. Portanto, vamos selecionar 8 componentes para treinar a Rede Neural." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RzekEmIMBqe1" + }, + "source": [ + "pca8 = PCA(n_components= 8)\n", + "X_pca8 = pca8.fit_transform(X)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DYDhJYdV-pSb" + }, + "source": [ + "A seguir, o gráfico com as componentes principais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_zUN_3wR-nOX" + }, + "source": [ + "plt.figure(figsize=(7, 7))\n", + "plt.plot(np.cumsum(pca.explained_variance_ratio_), 'ro-')\n", + "plt.grid()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YO3Umy7sGEMJ" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e2gXueuI2Nb4" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "giFgdIK7GEMJ" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_pca8, y_WineQ, test_size= 0.2, random_state= 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nr4sryEr-eOy" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l2KSZ8TQGEMM" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tQyKOA8Qhgtd" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "62E0wT8hhgtd" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_pca8.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= y_WineQ.shape[1]\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 32\n", + "N_H2= 32\n", + "N_H3= 32\n", + "N_H4= 32\n", + "N_H5= 32\n", + "N_H6= 32\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wT0kLyuGpZ4C" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C3Wdq7XvpZ4F" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_6ZBeC4EnZyQ" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vjUyPpoJbg20" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ry43SCP4nbvp" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H4, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H5, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H6, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Atenção à Função de Ativação!\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zQwY5qQLGEMR" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação multi-classes (> 2 classes). Portanto, temos:\n", + "* loss= tf.keras.losses.CategoricalCrossentropy();\n", + "* optimizer= tf.keras.optimizers.Adam();\n", + "* metrics= tf.keras.metrics.binary_accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HVp9pT8n1AQC" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "el86VgZ-GEMS" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.CategoricalCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qNyxbvjsGEMV" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3ZtHza72z_q9" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tikYg2CrGEMV" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), batch_size= 12, callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w6aoEBw92p86" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ei7XWVel2qNW" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tovtcp98GEMa" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DAC9nKCvyiKu" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZmhkMbmpGEMb" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjON99B1B9F0" + }, + "source": [ + "* Rede Neural com Accuracy= 0.9692 SEM PCA.\n", + "* Rede Neural com Accuracy= 0.9677 COM PCA." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_VzIx2_EGEMp" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jpLRlBTI3gvF" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1c1K5vGjGEMq" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5b-hDZ04GEMs" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h3mgEOcXu20F" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 3 - Rede Neural para identificar Câncer de Mama (_Breast Cancer Dataframe_)**\n", + "\n", + "Fonte: [Breast Cancer Wisconsin (Diagnostic) Data Set](https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+%28Diagnostic%29)\n", + "\n", + "Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QVZQ1meF9l_-" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cd4zQSkseKzv" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OzMsBroueKzx" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wJSbJx9rrBG3" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "alCVjy_JCWUo" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-Ra_PjiFeKz0" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y4I2Eh2YeKz1" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1nXjn5KM94lI" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ovtqPCcWBgfI" + }, + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "Cancer = load_breast_cancer()\n", + "X_cancer= Cancer.data\n", + "y_Cancer= Cancer.target\n", + "Col_Names= Cancer.feature_names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5qbOErH6Dkcu" + }, + "source": [ + "Col_Names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "weKuFIHqDWRX" + }, + "source": [ + "X_cancer" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kix-c9TDY_R" + }, + "source": [ + "y_Cancer[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qg_IuwHp946c" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7wnkuDnMlVe8" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uVEHT9sqG9WR" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_cancer = SS.fit_transform(X_cancer)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hNeVqHH295FA" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Rbc3MwX2RDU" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xR6XSrbsFX-P" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_cancer, y_Cancer, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NRQ8zW1m-g6l" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "775KoeQz95O6" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fFaKVel2ilZs" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aB7xcQFWilZs" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_cancer.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 16\n", + "N_H2= 16\n", + "N_H3= 16\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rm1PeihTRlgz" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U3oTC94GRlg3" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J5GBW-Ucnh9T" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "my2xjCniIb4J" + }, + "source": [ + "Vamos adicionar duas camadas _Dropout_ com $p= 0.1$ para evitarmos _overfitting_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kne06wmjnTYD" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s6x7mo4dnjlE" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "04cKraWZ9mMb" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (maligno ou benigno). Portanto, temos:\n", + "* loss= tf.keras.losses.BinaryCrossentropy();\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OGRjWcsm1FM9" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bLIoA8FrJJCx" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cnL12eaF9mU6" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nVsziJfk0FIv" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "apQY6cQjJb-z" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "avd2cXpO20cY" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FCd8xFxA25Lc" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3zToEvUs-pCt" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IqzKH7jsymwL" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pmjuk6OqJ7zD" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "04ZGPI6DKcnz" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-MZyagwaKfkM" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KasqSFWG-pTG" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Não é necessário, pois obtivemos 0.9825 de acurácia." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GLxgJP3L-pdZ" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0iXGBnNZYb4V" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nqBFwxg5Yb4b" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4CHdWhgD-plr" + }, + "source": [ + "### 10. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T2AQ4uDShdgE" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 4 - Rede Neural para identificar Diabetes (Diabetes Dataframe)**\n", + "\n", + "> Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HOEJGtAzQfX3" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mxa5UaIXeRgN" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ylfhuYeveRgO" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uG9B3WTkeRgR" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TZkm0YVoeRgR" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mDhEsSJ1rFpy" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KfKcNLZ3QfYJ" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rIT9N7jSQfYO" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r9QUJZgbSWDG" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ofSJNoyfQfYR" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "Diabetes = load_diabetes()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fo7q0BnyShVG" + }, + "source": [ + "[**Python**] - Definir os arrays X_Diabetes e y_Diabetes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UTnrDMPLQfYW" + }, + "source": [ + "X_Diabetes= Diabetes.data\n", + "y_Diabetes= Diabetes.target\n", + "Col_Names= Diabetes.feature_names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZjrdZUwp_l40" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "skgDY4Lu_l46" + }, + "source": [ + "X_Diabetes.columns= X_Diabetes.columns.str.lower()\n", + "X_Diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "a5NQO8b-QfYb" + }, + "source": [ + "X_Diabetes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "adpBpNDeQfYj" + }, + "source": [ + "y_Diabetes[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQA4fN4HQfYo" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dTnBpjwalbVG" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hS_unh4wQfYp" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_Diabetes = SS.fit_transform(X_Diabetes)\n", + "y_Diabetes= SS.fit_transform(y_Diabetes.reshape(-(1, 1))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZSviMMrISt96" + }, + "source": [ + "Y[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pWmVyMF0QfYu" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEMSNMJu2VqI" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2WUQMh2HQfYx" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Diabetes, y_Diabetes, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zvx80NPT-j0S" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wk_CG4H5QfY2" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V1bDqK5vi49C" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "por467-ci49D" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Diabetes.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 6\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.linear" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-r7VC-7lpkkC" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "43f-ZPW7pkkD" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2qv8lJmHnqi3" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Veeqccdbnks" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WMOoG_0bnsSD" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7W8VtONlQfZP" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de regressão. Portanto, temos:\n", + "* loss= tf.keras.losses.MeanSquaredError;\n", + "* metrics= 'mse';\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g97mJCSr1Kat" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cXJFtlcEQfZQ" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1s1S7Fn_QfZW" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNgR4ihA0JMy" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JUaqK4j-QfZY" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 200, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3bFg6kut1jkb" + }, + "source": [ + "A seguir, funções para plotarmos os gráficos das métricas MSE, _Loss_ e _Accuracy_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VPASVWaR1sWN" + }, + "source": [ + "def Model_Loss(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['loss'])\n", + " plt.plot(hist.history['val_loss'])\n", + " plt.title('Model Loss')\n", + " plt.ylabel('Loss')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Model_Accuracy(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['accuracy'])\n", + " plt.plot(hist.history['val_accuracy'])\n", + " plt.title('Model Accuracy')\n", + " plt.ylabel('Accuracy')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Model_MSE(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['mse'])\n", + " plt.plot(hist.history['val_mse'])\n", + " plt.title('Model MSE')\n", + " plt.ylabel('MSE')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Mostra_ConfusionMatrix():\n", + " y_pred = RN.predict_classes(X_teste)\n", + " mc = confusion_matrix(y_teste, y_pred)\n", + " #sns.heatmap(mc,annot=True, annot_kws={\"size\": 10},fmt=\"d\")\n", + " sns.heatmap(mc/np.sum(mc), annot=True, annot_kws={\"size\": 10}, fmt='.2%', cmap='Blues')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uWhJUP0v2_fm" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M8IZFKGyCvqO" + }, + "source": [ + "Model_MSE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "37_0RhXLQfZc" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8mMrIS9JyriW" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cRjEkvWzQfZe" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MA6_RkjgQfZs" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Vou deixar esta fase como exercício para o aluno." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vPJtuCzXQfZu" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p1EptFS1Yi-D" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbrvwgyvYi-I" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JOsTSHwoQfZ0" + }, + "source": [ + "### 10. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EoQ5nySZmLDP" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 5 - Rede Neural para prever os preços das casas (_Boston House Price Prediction_)**\n", + "\n", + "Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8vdRpBS8VTw_" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v629ZppSeY5T" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uVXroVLTeY5U" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qYCcNW9qeY5W" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zNn-kwlGeY5X" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YnlZU1rLrJwt" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "445U8OKgVTxW" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1Ckhzf0VTxc" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aAz0_L0e1mxX" + }, + "source": [ + "[] Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SOdpdceAVTxd" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "Boston = load_boston()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K0P23sJs1raX" + }, + "source": [ + "[**Python**] - Definir as matrizes X_Boston e y_Boston:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rPpJOsgJ1y7J" + }, + "source": [ + "X_Boston= Boston.data\n", + "y_Boston= Boston.target\n", + "Col_Names= Boston.feature_names\n", + "Col_Names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5XBRc6og_ySA" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VPGDwXSF_ySE" + }, + "source": [ + "X_Boston.columns= X_Boston.columns.str.lower()\n", + "X_Boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fKiKT-fkVTxq" + }, + "source": [ + "y_Boston[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T9uYgjz-VTxu" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rbpIU5jlgv6" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kbs-x9a2VTxw" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_Boston= SS.fit_transform(X_Boston)\n", + "y_Boston= SS.fit_transform(y_Boston.reshape(-(1, 1))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S2w2H9BOXK9u" + }, + "source": [ + "X_Boston" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "DXNIHeS2XM_k" + }, + "source": [ + "y_Boston[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gcbomDeKVTx1" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gEkX579Q2D2q" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EZyRBsfYVTx2" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Boston, y_Boston, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "g89c6edL-mBW" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GU-ebO-3VTx7" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gMVzohGHjS_p" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lf32pQtWjS_u" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Boston.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 7\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= FA_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qOI4_BPYVTyE" + }, + "source": [ + "Vamos adicionar uma camada _Dropout_ com $p= 0.1$ para evitarmos _overfitting_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yN9lxrXspp-m" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cWcQ3OS5pp-n" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "73PnOLbon3Jh" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zjKR3qgEneJr" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GnZuQZZTn4_W" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h-hyQiokVTyM" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de regressão. Portanto, temos:\n", + "* loss= tf.keras.losses.MeanSquaredError ou tf.keras.losses.MeanAbsoluteError();\n", + "* metrics= 'mse'.\n", + "* optimizer= tf.keras.optimizers.Adam() ou 'rmsprop'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JwQOPOhr1Oh0" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QY2aKnL_VTyN" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.RMSprop()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ygJi0ux5VTyT" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vz0urLrq0NPG" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9HoQZUl8VTyU" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 200, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "R_StfUsUzbto" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I1FIaMx_zzVW" + }, + "source": [ + "Model_MAE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_t3k3oqg0pXW" + }, + "source": [ + "Model_MSE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LH0llgTsVTyY" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yZZPMFXvyvtG" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iZGhNF5vVTyZ" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BkosiHm6lmww" + }, + "source": [ + "Observe que a Rede Neural _baseline_ (modelo inicial) apresenta MSE= 0.0795. Ainda assim, vamos tentar reduzir a _Loss Function_ e tentar chegar à um MSE ainda menor." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HcLONQpPVTyi" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "O que pode ser feito para melhorar a performance da Rede Neural?\n", + "* aumentar o número de _Hidden Layers_ e o número de neurônios em cada uma delas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g7Uxk3j_ndFX" + }, + "source": [ + "N_I= X_Boston.shape[1]\n", + "N_H1= 32\n", + "N_H2= 32\n", + "N_H3= 32\n", + "N_O= 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fF3Eb_5dp2PZ" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X48MWaa_p2Pb" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mHbjgPT7nP-q" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j8s-XRqdbuXP" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3HcNOQoFnR3W" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm())\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JBolPrXZnZ5i" + }, + "source": [ + "#### 8.5. Compilar a Rede Neural (_Fine tuning_ da Rede Neural)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rMBCiUTC1W2H" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YlBccXXmnZ5k" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SIOA5UFfnZ5p" + }, + "source": [ + "#### 8.6. Ajustar a Rede Neural (_Fine tuning_ da Rede Neural)\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ktlrSmGQ0Qrq" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kM5x90ArnZ5r" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 500, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AfxvOccmnZ5z" + }, + "source": [ + "#### 8.7. Avaliar a performance da Rede Neural (_Fine tuning_ da Rede Neural)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4XZmb9zIy1Xf" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "belFKJQSnZ51" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7whymUw5VTyq" + }, + "source": [ + "### 10. Conclusões\n", + "\n", + "A performance da Rede Neural melhorou um pouco com a redução do MSE." + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB19_Redes_Neurais_hs2.ipynb b/Notebooks/NB19_Redes_Neurais_hs2.ipynb new file mode 100644 index 000000000..a59ab8885 --- /dev/null +++ b/Notebooks/NB19_Redes_Neurais_hs2.ipynb @@ -0,0 +1,9977 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "accelerator": "TPU", + "colab": { + "name": "NB19_Redes_Neurais__V2.ipynb", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ShVXyGj9wkgN" + }, + "source": [ + "

REDES NEURAIS ARTIFICIAIS (COMPREHENSIVE GUIDE)

\n", + "\n", + "# Porque Cientistas de Dados desejam aprender e dominar Redes Neurais?\n", + "\n", + "* Redes Neurais têm a capacidade de aprender, modelar e resolver problemas não-lineares e complexos apresentados pela vida real.\n", + "* Você já deve ter ouvido falar em Inteligência Artificial, _self-drive cars_, _Deep Learning_, _Computer Vision_ e _Neural Language Processing_ (NLP). Todos estes assuntos estão estreitamente relacionados às Redes Neurais. Por exemplo, _Deep Learning_ são Redes Neurais com muitas _Hidden Layers_.\n", + "\n", + "Este curso aborda os principais tópicos para você dominar Redes Neurais. Além disso, vamos falar das melhores práticas e atacar as principais dúvidas dos alunos em relação às Redes Neurais. Portanto, ao final deste curso você será capaz de:\n", + "\n", + "* desenvolver suas próprias Redes Neurais;\n", + "* aplicar o algoritmo correto para cada tipo de problema;\n", + "* aplicar as funções de ativação corretamene para cada tipo de problema e camada;\n", + "* aprender o necessário de Tensorflow/Keras para Redes Neurais;\n", + "* Aprender os comandos necessários do Python/NumPy para desenvolvimento de Redes Neurais;\n", + "* aplicar a métrica ideal para cada tipo de problema;\n", + "* entender como as Redes Neurais aprendem (_Backpropagation_);\n", + "\n", + "# **AGENDA**\n", + "\n", + "* Introdução às Redes Neurais;\n", + "* _Activation Function_;\n", + "* _Loss Function_;\n", + "* Métricas para medir a performance das Redes Neurais;\n", + "* _Dropout_;\n", + "* _Backpropagation_;\n", + "* _Gradient Descent_;\n", + "* _Perceptron_ (Redes Neurais com 1 única camada);\n", + "* Exemplo 1: Redes Neurais _Perceptron_ para os operadores lógicos E, OU e XOR;\n", + "* Redes Neurais Multicamada;\n", + "* Exemplo prático: Rede Neural para identificar o sexo a partir de peso e altura;\n", + "* Aplicações de Rede Neural:\n", + " * Aplicação 1 - Rede Neural para identificar espécies de flores (Iris Dataframe);\n", + " * Aplicação 2 - Rede Neural para identificar o tipo do vinho (_Red or White_);\n", + " * Aplicação 3 - Rede Neural para identificar Câncer de Mama (_Breast Cancer_ Dataframe);\n", + " * Aplicação 4 - Rede Neural para identificar Diabetes (Diabetes Dataframe);\n", + " * Aplicação 5 - Rede Neural para prever os preços das casas em Boston (_Boston House Price Prediction_)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aYQ4cDfcPu4e" + }, + "source": [ + "___\n", + "# **NOTAS E OBSERVAÇÕES**\n", + "\n", + "1. Contemplar o uso de StratifiedKFold;\n", + "2. Inserir aqui o exemplo das notas falsas, enviado pela Mónica;\n", + "3. Deixar alguma coisa que foi resolvida como exercício.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QgX6n2VDyY1O" + }, + "source": [ + "___\n", + "# **REFERÊNCIAS**\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)\n", + "- [Forward propagation in neural networks — Simplified math and code version](https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250)\n", + "- [Understanding Neural Networks: From Activation Function To Back Propagation](https://medium.com/fintechexplained/neural-networks-activation-function-to-back-propagation-understanding-neural-networks-bdd036c3f29f)\n", + "- [Understanding Gradient Descent](https://medium.com/analytics-vidhya/understanding-gradient-descent-8dd88a4c60e6) - Explica detalhadamente como funciona o _Gradient Descent_ no processo de otimização dos pesos $W$;\n", + "- [Backpropagation step by step](https://medium.com/swlh/backpropagation-step-by-step-13f2b6c0b414) - Eu usei esse artigo para reajustar os pesos $W$;\n", + "- [Perceptron Learning Algorithm: A Graphical Explanation Of Why It Works](https://towardsdatascience.com/perceptron-learning-algorithm-d5db0deab975);\n", + "- [Math behind Perceptrons](https://medium.com/@iamask09/math-behind-perceptrons-7241d5dadbfc);\n", + "- [Neural Network: A Complete Beginners Guide from Scratch](https://medium.com/gadictos/neural-network-a-complete-beginners-guide-from-scratch-cf1fc9d5cd12);\n", + "- [Calculating the Backpropagation of a Network](https://medium.com/towards-artificial-intelligence/calculating-back-propagation-of-a-network-1febbcaa2b5d);\n", + "- [Let’s build a simple Neural Net!](https://becominghuman.ai/lets-build-a-simple-neural-net-f4474256647f) - O autor constroi uma Rede Neural simples, sem _Hidden Layers_;\n", + "- [Coding Neural Network — Forward Propagation and Backpropagtion](https://towardsdatascience.com/coding-neural-network-forward-propagation-and-backpropagtion-ccf8cf369f76);\n", + "- [The Simplest Neural Network: Understanding the non-linearity](https://towardsdatascience.com/the-simplest-neural-network-understanding-the-non-linearity-10846d7d0141) - Ótimo texto para entender a não-linearidade;\n", + "- [Implementing the XOR Gate using Backpropagation in Neural Networks](https://towardsdatascience.com/implementing-the-xor-gate-using-backpropagation-in-neural-networks-c1f255b4f20d) - Usei este texto para resolver o problema do XOR;\n", + "- [Neural Representation of AND, OR, NOT, XOR and XNOR Logic Gates (Perceptron Algorithm)](https://medium.com/@stanleydukor/neural-representation-of-and-or-not-xor-and-xnor-logic-gates-perceptron-algorithm-b0275375fea1) - Eu usei este material para resolver o problema dos operadores E, OU e XOR;\n", + "- [Solving XOR with a single Perceptron](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182);\n", + "- [Machine Learning 101 — Artificial Neural Networks](https://towardsdatascience.com/machine-learning-101-artificial-neural-networks-3-46ccb04cba30) - Cálculos realizados passo a passo;\n", + "- [Neural Network from scratch in Python](https://towardsdatascience.com/math-neural-network-from-scratch-in-python-d6da9f29ce65) - Este artigo mostra a matemática por trás das Redes Neurais;\n", + "- [Classical Neural Net: Why/Which Activations Functions?](https://towardsdatascience.com/classical-neural-net-why-which-activations-functions-401159ba01c4) - Artigo que discute as principais funções de ativação;\n", + "- [Understanding Activation Functions in Neural Networks](https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0);\n", + "- [Mind: How to Build a Neural Network (Part One)](https://becominghuman.ai/mind-how-to-build-a-neural-network-part-one-67b6aea4ce20);\n", + "- [How to build a simple Neural Network from scratch with Python](https://towardsdatascience.com/how-to-build-a-simple-neural-network-from-scratch-with-python-9f011896d2f3);\n", + "- [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a);\n", + "- [MAE and RMSE — Which Metric is Better?](https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d) - Ótimo artigo, pois discute qual métrica é melhor.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2StZkTpOZbYo" + }, + "source": [ + "___\n", + "# **MACHINE LEARNING DEVELOPMENT LYFECYCLE**\n", + "\n", + "CRISP-DM significa _Cross Industry Standard Process for Data Mining_ ou processos ou fases para desenvolvimento de projetos relacionados à _Data Mining_ e que tem sido muito utilizados pelos Cientistas de Dados para desenvolvimento de modelos predictivos.\n", + "\n", + "\"Drawing\"\n", + "\n", + "Fonte: [The steps to a successful machine learning project](https://emba.epfl.ch/2018/04/10/steps-successful-machine-learning-project/)\n", + "\n", + "Sugiro a leitura do artigo [Why using CRISP-DM will make you a better Data Scientist](https://towardsdatascience.com/why-using-crisp-dm-will-make-you-a-better-data-scientist-66efe5b72686)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TsCbZd2epfxo" + }, + "source": [ + "___\n", + "# **INTRODUÇÃO ÀS REDES NEURAIS**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HqqB2vaHXMGt" + }, + "source": [ + "* Redes Neurais aprendem com as experiências passadas, imitando o funcionamento dos neurônios humanos no processo de aprendizagem;\n", + "* podem e são amplamente utilizadas nas seguintes situações (aplicações):\n", + " * Reconhecimento Facial;\n", + " * Processamento de Linguagem Natural (NLP);\n", + " * _Self-drive car_;\n", + " * Visão computacional;\n", + " * Detecção de padrões (doenças, tumores e etc) em imagens;\n", + "* Ideal para o cenário onde temos muitos dados (_Big Data_) e para resolver problemas complexos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VzylPHA7BP0x" + }, + "source": [ + "___\n", + "# **_PERCEPTRON_** (Rede Neural com 1 única camada)\n", + "\n", + "* **_PERCEPTRON_** é um algoritmo de _Machine Learning_ da classe _Supervised Learning_ para classificação binária, inventado em 1958 por Frank Rosenblatt;\n", + "* Arquitetura de Rede Neural mais simples existente, com 1 única camada;\n", + "\n", + "**Daí, uma pergunta importante**: Se _Perceptron_ é um tipo de Rede Neural simples que nasceu na década de 1950, então porque devemos estudá-la? Porque não focar no estudo de Redes Neurais mais complexas e atuais?\n", + "\n", + "*E a resposta é**: porque _Perceptron_ nos permite entender claramente os aspectos matemáticos das Redes Neurais. Com isso quero dizer que ao entendermos _Perceptrons_, fica mais fácil entender outros tipos de Redes Neurais." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M5YNraza6jum" + }, + "source": [ + "## Exemplo de Perceptron\n", + "\n", + "A seguir, arquitetura do _Perceptron_: várias entradas (_Inputs_) e 1 camada de saída (_Output Layer_) binária (0 ou 1).\n", + "\n", + "* OL significa **O**utput **L**ayer ==> Valor que queremos estimar, ou seja, $\\hat{y}$.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_5LVgImx78xY" + }, + "source": [ + "A **FUNÇÃO DE ATIVAÇÃO** $f(S)$ acima é conhecida como **_STEP FUNCTION_** e como podemos ver, retorna uma resposta binária (0 ou 1) que depende do valor de $S$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "84zFWve4FkcY" + }, + "source": [ + "A seguir, implementação usando NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "htVV-GpgBnw3" + }, + "source": [ + "[**Python**] - Importar o NumPy:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xBYyZ5ZiByH4" + }, + "source": [ + "import numpy as np" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-8sR77a4B8Uf" + }, + "source": [ + "[**Python**] - Definir o número de casas decimas para 3:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gj2dioDTaZl-" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oZ6Sw4uuCggF" + }, + "source": [ + "[**Python**] - Definir os pesos $W$ e as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "z2m6BxQ_DLFV" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.1, 0.3, 0.2, 0.4])\n", + "\n", + "# Entradas X:\n", + "X = np.array([1, -3, 2, 3])" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lBnZP5MKCg8m" + }, + "source": [ + "[**Python**] - Desenvolver a função soma $S$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMGuWhAhDaim" + }, + "source": [ + "def Soma(X, W):\n", + " S = X.dot(W) # Faz a seguinte operação: S = X1*W1 + X2*W2 + X3*W3 + X4*W4\n", + " return S" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EMxMJ05kDhmi" + }, + "source": [ + "[**Python**] - Desenvolver a função de ativação _Step Function_ $f(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dRLYPJl0aZmg" + }, + "source": [ + "def ativacao_StepFunction(S):\n", + " if S >= 1:\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H4g85O2jDu6S" + }, + "source": [ + "[**Python**] - Calcular $S = Soma(X, W)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zoUMvvzlaZm-", + "outputId": "3d7a4be8-fe0a-4fb4-b8ce-d5a49c14bf3e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "S = Soma(X, W)\n", + "S" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0.8000000000000003" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6LzlyDNaD5yB" + }, + "source": [ + "[**Python**] - Calcular $f(S)$, ou seja, $f = ativacao_StepFunction(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6IIe4vIjaZnE", + "outputId": "25b64d72-d559-4458-8131-9d33b760e560", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "f = ativacao_StepFunction(S)\n", + "f" + ], + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UrRG8e8dDTc_" + }, + "source": [ + "# **EXEMPLO 1: DESENVOLVER UMA REDE NEURAL _PERCEPTRON_ PARA OS OPERADORES LÓGICOS E, OU E XOR**\n", + "\n", + "Os exemplos a seguir foram inspirados e adaptado de:\n", + "* [Perceptron: Theory and Practice](https://medium.com/data-alchemist/perceptron-theory-and-practice-e71733ed3fa5)\n", + "* [The Perceptron — A Building Block of Neural Networks](https://blog.usejournal.com/the-perceptron-the-building-block-of-neural-networks-5a428d3f451d) - Este artigo mostra detalhadamente os cálculos\n", + "* [Mind: How to Build a Neural Network (Part One)](https://becominghuman.ai/mind-how-to-build-a-neural-network-part-one-67b6aea4ce20)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qeZBP3TQN2_1" + }, + "source": [ + "## Exemplo 1.1: Rede Neural _Perceptron_ para o Operador Lógico E\n", + "\n", + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 |\n", + "| 2 | 1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "O dataframe acima representa o operador lógico E (https://en.wikipedia.org/wiki/Truth_table):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | F |\n", + "| 2 | T | F | F |\n", + "| 3 | T | T | T |\n", + "\n", + "\n", + "Considere $W= [W_{1}, W_{2}]= (0, 0)$ como pesos iniciais e a função de ativação $F(S)$ _Step Function_ dada abaixo:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "psJh-MUgFAge" + }, + "source": [ + "A seguir, os cálculos manuais da primeira iteração:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8x3EvFUQBsU" + }, + "source": [ + "Os Erros $E_{i}$ são calculados com a fórmula: $E_{i}= ValorReal_{i} - ValorCalculado_{i}= y_{i}-\\hat{Y}_{i}$. A seguir, resumo dos cálculos:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d5dryrbGBesj" + }, + "source": [ + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | Soma | ValorCalculado ($\\hat{Y}_{i}$) | Erro |\n", + "|---|---|---|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 | 0 | 0 | 0 |\n", + "| 2 | 1 | 0 | 0 | 0 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 | 0 | 0 | 1 |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lkcRy2RYGLVw" + }, + "source": [ + "### Erro Total ($E_{T}$)\n", + "\n", + "$$E_{T}= \\sum_{i=1}^{n}E_{i}= E_{1}+E_{2}+...+E_{n}$$\n", + "\n", + "No nosso caso, temos que $E_{T}= 0+0+0+1= 1$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fzVxmr9OTfGB" + }, + "source": [ + "### Fórmula para ajustar os pesos $W$\n", + "A fórmula a seguir será utilizada para ajustar os pesos $W$:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z1bEDxMhToIj" + }, + "source": [ + "### Taxa de Aprendizagem ($\\alpha$)\n", + "* $\\alpha$ é a taxa de aprendizado (_Learning Rate_ em inglês) e diz respeito à velocidade de aprendizagem da Rede Neural.\n", + " * Quanto MENOR o valor de $\\alpha$ $\\Longrightarrow$ mais devagar e demorada será a convergência para o mínimo global;\n", + " * Quanto MAIOR o valor de $\\alpha$ $\\Longrightarrow$ mais rápido será a convergência para o mínimo, **mas sem a garantia de convergência para o mínimo global**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "drGfgCIZY4aV" + }, + "source": [ + "Para ajustar os pesos $W$, vamos utilizar $\\alpha= 0.1$. Fórmula:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n", + "\n", + "A seguir, os novos pesos $W$ para a próxima iteração da Rede Neural _Perceptron_:\n", + "\n", + "\\begin{align}\n", + "W_{1}&= 0+ 0.1*1*1= 0.1 \\\\\n", + "W_{2}&= 0+ 0.1*1*1= 0.1 \\\\\n", + "\\end{align}\n", + "\n", + "Portanto, na próxima iteração vamos utilizar os pesos $W= [W_{1}, W_{2}]= [0.1, 0.1]$. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "33xLPLo-Pq0Y" + }, + "source": [ + "A seguir, os cálculos manuais para a segunda iteração da Rede Neural:\n", + "\n", + "Função de ativação $f(S)$ _Step Function_:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i3EsH8pN9wJ6" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mZiiOu1AyW2N" + }, + "source": [ + "A seguir resumo dos cálculos para a segunda iteração:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | Soma | ValorCalculado ($\\hat{Y}_{i}$) | Erro |\n", + "|---|---|---|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 | 0.0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 | 0.1 | 0 | 0 |\n", + "| 2 | 1 | 0 | 0 | 0.1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 | 0.2 | 0 | 1 |\n", + "\n", + "Daí, $E_{T}= 0+0+0+1= 1$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MAXO38uqUobn" + }, + "source": [ + "### Ajuste dos pesos $W$\n", + "Fórmula para ajustar $W$:\n", + "\n", + "$$W_{n+1}= W_{n} + \\alpha*(X*E_{T})$$\n", + "\n", + "A seguir, os novos pesos $W$ para a próxima iteração da Rede Neural _Perceptron_:\n", + "\n", + "\\begin{align}\n", + "W_{1}&= 0.1+ 0.1*1*1= 0.2 \\\\\n", + "W_{2}&= 0.1+ 0.1*1*1= 0.2 \\\\\n", + "\\end{align}\n", + "\n", + "Portanto, na próxima iteração vamos utilizar os pesos $W= [W_{1}, W_{2}]= [0.2, 0.2]$. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WX48iRa5VLyk" + }, + "source": [ + "Esse processo iterativo é realizado até que se encontre os pesos $W$ que nos dê 100% de acurácia. A título de exemplo, considere $W= [W_{1}, W_{2}]= [0.5, 0.5]$:\n", + "\n", + "Função de ativação $f(S)$ _Step Function_:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LZfroCc994oz" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McKYXohzXzzA" + }, + "source": [ + "Como podem ver, o Erro Total $E_{T}= 0$, pois temos 100% de acertos (acurácia) usando $W= [W_{1}, W_{2}]= [0.5, 0.5]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wp_tR7h0btDm" + }, + "source": [ + "### Implementar o **_PERCEPTRON_** no Python usando NumPy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3ix5vCKaEWdx" + }, + "source": [ + "[**Python**] - Importar NumPy:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x62R_y89ElPA" + }, + "source": [ + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SYvLGlgZEXWu" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yEScd0_LEtJc" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P8hLz6GAEYCo" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fD66QeoqXEU3" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [0], [0], [1]])" + ], + "execution_count": 36, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "alRRwxsUvIU6", + "outputId": "b82c65a6-eba4-47c9-e1c6-c40ae5b90ee4", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": 37, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VB5n2WNUvND3", + "outputId": "21cb912b-cf9e-425d-caba-27b57e71875d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [0],\n", + " [0],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2jH1EMfdEYwN" + }, + "source": [ + "[**Python**] - Definir a Taxa de Aprendizagem $\\alpha$:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zd2k0S-BXEU_" + }, + "source": [ + "alpha = 0.1" + ], + "execution_count": 40, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yvGa7d8LEZD2" + }, + "source": [ + "[**Python**] - Desenvolver a função para treinar a Rede Neural\n", + "> Esta função tenta encontrar os pesos $W$ que levem a 100% de acurácia." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JVl0XwBuXEVC" + }, + "source": [ + "def Treinar_RNA(X, Y, W, alpha):\n", + " ET= 1 # ET= Erro Total\n", + " N= 0\n", + " while ((ET != 0) and (N < 100)):\n", + " ET= 0\n", + " for i in range(len(Y)):\n", + " S = X[i].dot(W)\n", + " f = ativacao_StepFunction(S)\n", + " E= Y[i]-f\n", + " ET+= E\n", + " for j in range(len(W)):\n", + " W[j]= W[j] + alpha*(X[i][j]*E)\n", + " print(f'i: {i} | j: {j} | X: {X[i][j]} | E: {E} | Peso Ajustado W[{j}]: {W[j]}') #incluído hs\n", + " # print(f'Peso Ajustado: {W[j]}') # comentado hs\n", + " print(f'Erro Total: {ET}')\n", + " N+= 1" + ], + "execution_count": 35, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pdI7EHnFF4yo" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gHM5tXEdXEVF", + "outputId": "c2f4083a-61eb-4e8e-beea-afb748db1292", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": 41, + "outputs": [ + { + "output_type": "stream", + "text": [ + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.0\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.0\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.0\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.0\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.0\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.0\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.1\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.1\n", + "Erro Total: [1]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.1\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.1\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.1\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.1\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.1\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.1\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.2\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.2\n", + "Erro Total: [1]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.2\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.2\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.2\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.2\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.2\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.2\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.30000000000000004\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.30000000000000004\n", + "Erro Total: [1]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.30000000000000004\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.30000000000000004\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.30000000000000004\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.30000000000000004\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.30000000000000004\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.30000000000000004\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.4\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.4\n", + "Erro Total: [1]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.4\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.4\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.4\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.4\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.4\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.4\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.5\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.5\n", + "Erro Total: [1]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "Erro Total: [0]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TPKEML9cDD0E" + }, + "source": [ + "## Exemplo 1.2: Rede Neural _Perceptron_ para o Operador Lógico OU\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rSQnOjDWC7Ta" + }, + "source": [ + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "O dataframe acima representa o operador lógico OU (https://en.wikipedia.org/wiki/Truth_table):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | T |\n", + "| 2 | T | F | T |\n", + "| 3 | T | T | T |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kID13PxSGN6h" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CmuuIX2PGN6l" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [1], [1], [1]])" + ], + "execution_count": 42, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UDzdS6FX2LOC", + "outputId": "c52d5e55-3dd8-4630-92d2-e48b02ec7fc5", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "X" + ], + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 1],\n", + " [1, 0],\n", + " [1, 1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ar0dk1eQ2MOD", + "outputId": "40dbead6-ef86-4e84-f6f2-d2e78ce400a8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Y" + ], + "execution_count": 44, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[0],\n", + " [1],\n", + " [1],\n", + " [1]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "agZX698KGeVK" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3GF_W4u0GeVM", + "outputId": "ca418c8c-3117-4587-e27a-19bcaa5f38ec", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": 45, + "outputs": [ + { + "output_type": "stream", + "text": [ + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.0\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.0\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.0\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.1\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.1\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.1\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.2\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.2\n", + "Erro Total: [3]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.2\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.2\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.2\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.30000000000000004\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.30000000000000004\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.30000000000000004\n", + "i: 3 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.4\n", + "i: 3 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.4\n", + "Erro Total: [3]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.4\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.4\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.4\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.5\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.5\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.5\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.5\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.5\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.5\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.6\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.6\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.6\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.6\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.6\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.6\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.6\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.6\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.7\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.7\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.7\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.7\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.7\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.7\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.7\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.7\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.7999999999999999\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.7999999999999999\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.7999999999999999\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.7999999999999999\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.7999999999999999\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.7999999999999999\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.7999999999999999\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.7999999999999999\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.8999999999999999\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.8999999999999999\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.8999999999999999\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.8999999999999999\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.8999999999999999\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.8999999999999999\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.8999999999999999\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.8999999999999999\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 0.9999999999999999\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 0.9999999999999999\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 0.9999999999999999\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 0.9999999999999999\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 0.9999999999999999\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 0.9999999999999999\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 0.9999999999999999\n", + "i: 1 | j: 0 | X: 0 | E: [1] | Peso Ajustado W[0]: 0.9999999999999999\n", + "i: 1 | j: 1 | X: 1 | E: [1] | Peso Ajustado W[1]: 1.0999999999999999\n", + "i: 2 | j: 0 | X: 1 | E: [1] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 2 | j: 1 | X: 0 | E: [1] | Peso Ajustado W[1]: 1.0999999999999999\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 1.0999999999999999\n", + "Erro Total: [2]\n", + "i: 0 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 0 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 1.0999999999999999\n", + "i: 1 | j: 0 | X: 0 | E: [0] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 1 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 1.0999999999999999\n", + "i: 2 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 2 | j: 1 | X: 0 | E: [0] | Peso Ajustado W[1]: 1.0999999999999999\n", + "i: 3 | j: 0 | X: 1 | E: [0] | Peso Ajustado W[0]: 1.0999999999999999\n", + "i: 3 | j: 1 | X: 1 | E: [0] | Peso Ajustado W[1]: 1.0999999999999999\n", + "Erro Total: [0]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u2dZAVVFEpCw" + }, + "source": [ + "## Exemplo 1.3: Rede Neural _Perceptron_ para o Operador Lógico XOR\n", + "\n", + "Problema proposto e demonstrado por Rumelhart et al. (1985)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EaZIyvvEEpC5" + }, + "source": [ + "Considere o dataframe a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |\n", + "\n", + "O dataframe acima representa o operador lógico XOR (https://pt.wikipedia.org/wiki/Ou_exclusivo):\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | F | F | F |\n", + "| 1 | F | T | T |\n", + "| 2 | T | F | T |\n", + "| 3 | T | T | F |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7rc3hc2RGneF" + }, + "source": [ + "[**Python**] - Definir os pesos $W$, entradas (_inputs_) $X$ e Output $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u8fAgk3RGneH" + }, + "source": [ + "# Pesos W:\n", + "W = np.array([0.0, 0.0])\n", + "\n", + "# Entradas X:\n", + "X = np.array([[0, 0], [0,1], [1, 0], [1, 1]])\n", + "\n", + "# Output Y:\n", + "Y = np.array([[0], [1], [1], [0]])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tFKaIhua3Mr6" + }, + "source": [ + "X" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pm-X-dXX3NZW" + }, + "source": [ + "Y" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "znRL2XozGneM" + }, + "source": [ + "[**Python**] - Evocar a função Treinar_RNA:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "j8leYHZVGneM" + }, + "source": [ + "Treinar_RNA(X, Y, W, alpha)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1Eu5cVvxM60i" + }, + "source": [ + "## Porque conseguimos pesos $W$ para os Operadores Lógicos E e OU e não para XOR?\n", + "\n", + "* Operadores E e OR: Linearmente Separáveis;\n", + "* Operador XOR: Linearmente NÃO-Separável.\n", + "\n", + "[Lucas Araújo](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182) diz em seu artigo [Solving XOR with a single Perceptron](https://medium.com/@lucaspereira0612/solving-xor-with-a-single-perceptron-34539f395182) que:\n", + "\n", + "\"Everyone who has ever studied about neural networks has probably already read that a single perceptron can’t represent the boolean XOR function. The book Artificial Intelligence: A Modern Approach, the leading textbook in AI, says: “[XOR] is not linearly separable so the perceptron cannot learn it”.\n", + "\n", + "As figuras abaixo demonstram clarmente os conceitos \"linearmente separáveis\" e \"NÃO-linearmente separável\"." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oUrFCMUjFtR1" + }, + "source": [ + "### Representação gráfica do Operador Lógico E\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 0 |\n", + "| 2 | 1 | 0 | 0 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n9v07MdMF42e" + }, + "source": [ + "### Representação gráfica do Operador Lógico OU\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) |\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 1 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "56Qp1J6LGBe9" + }, + "source": [ + "### Representação gráfica do Operador Lógico XOR\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eaQm7zZJbNAc" + }, + "source": [ + "___\n", + "# **O QUE APRENDEMOS ATÉ AQUI?**\n", + "\n", + "* Redes Neurais tentam ajustar os pesos $W$ para tentar melhorar a taxa de acerto. Ou seja, a Rede Neural aprende com os dados através do ajuste iterativo dos pesos $W$;\n", + "* Treinar uma Rede Neural é uma tarefa computacionalmente intensivo, pois o algoritmo tenta encontrar os pesos $W$ que apresentam melhor acurácia. Para um dataframe grande, o custo conputacional do aprendizado pode ser alto." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f_T35rXZOB4G" + }, + "source": [ + "___\n", + "# **REDES NEURAIS MULTICAMADA**\n", + "\n", + "* Pelo menos 1 _Hidden Layer_. Observe a Rede Neural a seguir contendo 20 neurônios distribuídos da seguinte forma:\n", + "\n", + " * Número de neurônios na camada de entrada (_Input Layer_): 4;\n", + " * 3 camadas escondidas (_Hidden Layers_) com 5 neurônios cada, totalizando 15 neurônios:\n", + " * Número de neurônios na _Hidden Layer 1_: 5;\n", + " * Número de neurônios na _Hidden Layer 2_: 5;\n", + " * Número de neurônios na _Hidden Layer 3_: 5;\n", + " * Número de neurônios na camada de saída (_Output Layer_): 1;\n", + "* _Fully connected layer_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1dXBXuh2-Tuo" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BK4O_Y_l2vev" + }, + "source": [ + "## Função _Sigmoid_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M_nn8zELXEVf" + }, + "source": [ + "\"Drawing\"\n", + "\n", + "Consulte [e (constante matemática)](https://pt.wikipedia.org/wiki/E_(constante_matem%C3%A1tica)) para saber mais sobre a constante de Euler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kOWwWR7hOmir" + }, + "source": [ + "## Número de _Hidden Layers_\n", + "\n", + "Pesquisadores apontam que 1 única _Hidden Layer_ é suficiente para a grande maioria dos problemas e que usualmente cada _Hidden Layer_ possui o mesmo número de neurônios. Experimentos mostram que mais _Hidden Layers_ implica em maior tempo para treinar a Rede Neural. No entanto, [Heaton Research](https://www.heatonresearch.com/2017/06/01/hidden-layers.html), mostra que:\n", + "\n", + "![Determinining_number_Hidden_Layers](https://github.com/MathMachado/Materials/blob/master/Determinining_number_Hidden_Layers.png?raw=true)\n", + "\n", + "Fonte: [Heaton Research](https://www.heatonresearch.com/2017/06/01/hidden-layers.html).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u4_1JCbcPRrn" + }, + "source": [ + "## Número de neurônios na camada de entrada (_Input Layer_): $N_{I}$\n", + "\n", + "$N_{I}$= Número de colunas (ou variáveis) no dataframe." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fk-lhwhffUZz" + }, + "source": [ + "### Número de neurônios na camada de saída (_Output Layer_): $N_{O}$\n", + "\n", + "* Se a Rede Neural é uma regressão, então o número de neurônios na _Output Layer_ é 1, pois o _output_ de uma regressão é um valor;\n", + "* Se a Rede Neural é uma classificação e usamos uma função de ativação probabilística (como _softmax_, por exemplo), então o número de neurônios na _Output Layer_ é igual ao número de classes que queremos prever. Por exemplo, no problema de classificar espécies no dataframe IRIS temos 3 espécies (versicolor, virginica e setosa). Ao utilizarmos a função de ativação _softmax_, então teremos 3 neurônios na _Output Layer_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsrrdLpSfYm9" + }, + "source": [ + "## Número de neurônios na camada escondida (_Hidden Layer_): $N_{H}$\n", + "\n", + "Determinar o número de neurônios na _Hidden Layer_ tem sido um exercício de tentativa e erro, mas alguns experimentos tem demonstrado que o número adequado de neurônios na _Hidden Layer_ pode ser obtido através da expressão a seguir:\n", + "\n", + "$$N_{H}= \\frac{N_{I}+N_{O}}{2}$$\n", + "\n", + "No entanto, o artigo [How to choose the number of hidden layers and nodes in a feedforward neural network?](https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw) sugere o uso da seguinte expressão:\n", + "\n", + "$$N_H= \\frac{N}{\\alpha(N_{I}+N_{O})}$$\n", + "\n", + "onde $N$ é o número de instâncias (linhas) do dataframe e $\\alpha$ é um número entre 2 e 10, sendo que alguns experimentos com $\\alpha= 2$ produzem bons modelos sem _overfitting_. Para saber mais sobre esta expressão e sobre $\\alpha$, sugiro a leitura do artigo mencionado." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Rj6WfilbShX3" + }, + "source": [ + "## Rede Neural Multicamada para o Operador Lógico XOR.\n", + "\n", + "Dataframe que representa o Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uURlcU78LwbH" + }, + "source": [ + "### Arquitetura da Rede Neural Multicamada que vamos desenvolver para o Operador Lógico XOR\n", + "\n", + "Os pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$ serão gerados aleatoriamente. A seguir, a arquitetura da Rede Neural com 1 _Hidden Layer_ contendo 3 neurônios:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6XKMdlZr-e9l" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AV2eUQDuLCUL" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uTWYP0V-LGHj" + }, + "source": [ + "import math\n", + "import numpy as np" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-DG86PgxLDQA" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jsvh5DOkXEVm" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NYIMcp8TLVuq" + }, + "source": [ + "[**Python**] - Definir as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U6Mt6zTnXEVq" + }, + "source": [ + "X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n", + "X" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tXLd1nZxLbXD" + }, + "source": [ + "[**Python**] - Definir os _Outputs_ $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Oauq3veAXEVu" + }, + "source": [ + "Y = np.array([[0], [1], [1], [0]])\n", + "Y" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TC1y0tO1MAU9" + }, + "source": [ + "### Gerar os pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$ aleatoriamente\n", + "\n", + "Por questões de reproducibilidade de resultados, vamos usar as sementes a seguir para gerar os pesos $W_{H}$ e $W_{O}$:\n", + "\n", + "* _seed_= 20111974 para gerar $W_{H}$;\n", + "* _seed_= 19741120 para gerar $W_{O}$.\n", + "\n", + "Ao usarmos estas sementes, deveremos ter $W_{H}= \\begin{bmatrix} 0.531 & 0.570 & 0.543 \\\\ 0.655 & 0.857 & 0.602 \\end{bmatrix}$ e $W_{O}= \\begin{bmatrix} 0.240 \\\\ 0.318 \\\\ 0.142 \\end{bmatrix}$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_U3Id5XXG5tw" + }, + "source": [ + "[**Python**] - Sementes para gerar $W_{H}$ (aleatoriamente)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tVXiIpgIHId9" + }, + "source": [ + "np.random.seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XYj0NYofHKkk" + }, + "source": [ + "[**Python**] - Gerar os pesos $W_{H}$ (aleatoriamente)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "o1eGsPNQXEVx" + }, + "source": [ + "W_H = np.array([np.random.random(3), np.random.random(3)])\n", + "W_H" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cj6KJnP3Hbqf" + }, + "source": [ + "[**Python**] - Sementes para gerar $W_{O}$ (aleatoriamente):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkVw-SWSHbqh" + }, + "source": [ + "np.random.seed(19741120)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r7ZjUT4oHbqk" + }, + "source": [ + "[**Python**] - Gerar os pesos $W_{O}$ (aleatoriamente):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ebs8p8mOXEV1" + }, + "source": [ + "W_O = np.array([np.random.random(1), np.random.random(1), np.random.random(1)])\n", + "W_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vg1ByKjKsWcE" + }, + "source": [ + "Confira os pesos dispostos na figura a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GiEc1DwPt7Hm" + }, + "source": [ + "### Calcular $S = \\sum_{i=1}^{4}X_{i}W_{i}$ e passar o valor de $S$ para a função de ativação $f(S)$ (_Sigmoid_)\n", + "\n", + "Função _Sigmoid_:\n", + "\n", + "$$f(x)= y= \\frac{1}{1+e^{-x}}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mCZsXjIhHqId" + }, + "source": [ + "[**Python**] - Definir a função de ativação $Sigmoid$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kB4-UnOGXEV8" + }, + "source": [ + "def FuncaoAtivacao_Sigmoid(x):\n", + " y = 1/(1+np.exp(-x))\n", + " return y" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XkvMHw1KHrjT" + }, + "source": [ + "[**Python**] - Função MostraCalculos, desenvolvida para validarmos os cálculos manuais de $S$ e $f(S)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fsxHrthYXEWA" + }, + "source": [ + "def MostraCalculos(i):\n", + " print(f'Array W:\\n {W_H}')\n", + " print('\\n')\n", + " print(f'Array X:\\n {X[i]}')\n", + " S = X[i].dot(W_H)\n", + " f = FuncaoAtivacao_Sigmoid(S)\n", + " S2= f.dot(W_O)\n", + " f2= FuncaoAtivacao_Sigmoid(S2)\n", + " \n", + " print('\\n')\n", + " print(f'*** HIDDEN LAYER ***')\n", + " print(f'Função Soma S: {S}')\n", + " print(f'Função de Ativação Sigmoid: {f}')\n", + " \n", + " print('\\n')\n", + " print(f'*** OUTPUT LAYER ***')\n", + " print(f'Função Soma S: {S2}')\n", + " print(f'Função de Ativação Sigmoid: {f2}')\n", + " \n", + " print('\\n')\n", + " print(f'*** ERRO ***')\n", + " E= Y[i]-f2\n", + " print(f'Erro da linha i= {i}: {E}')\n", + " \n", + " return f " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s80knPTzcIBy" + }, + "source": [ + "___\n", + "O Operador A.dot(B) faz o produto matricial entre os arrays A e B. Para saber mais sobre a função dot(), assista este [vídeo](https://youtu.be/Pb1VIe9657s)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bw0p2m8mbz3C" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 0$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CelKhuoHISyS" + }, + "source": [ + "[**Python**] - Evocar a função f0= MostraCalculos(0):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ar0zOLuUIio1" + }, + "source": [ + "f0 = MostraCalculos(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_R1LdY9QvTqb" + }, + "source": [ + "Observe na figura abaixo os cálculos manuais da Soma $S$, função de ativação $f(S)$ e Erro." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hl_RBLiaa4xS" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NOKtMLHoo_Yt" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(0, 1)} &= (0)(0.531)+(0)(0.655)= 0 \\Longrightarrow f_{H}^{(0, 1)}(S_{H}^{(0, 1)})= f_{H}^{(0, 1)}(0)= 0.5 \\\\\n", + "S_{H}^{(0, 2)} &= (0)(0.570)+(0)(0.857)= 0 \\Longrightarrow f_{H}^{(0, 2)}(S_{H}^{(0, 2)})= f_{H}^{(0, 2)}(0)= 0.5 \\\\\n", + "S_{H}^{(0, 3)} &= (0)(0.543)+(0)(0.602)= 0 \\Longrightarrow f_{H}^{(0, 3)}(S_{H}^{(0, 3)})= f_{H}^{(0, 3)}(0)= 0.5\n", + "\\end{align}\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Kw-cakYsQGp" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(0)}&= (0.5)(0.24)+(0.5)(0.318)+(0.5)(0.142)= 0.35 \\\\\n", + "f_{O}^{(0)}(S_{O}^{(0)})&= f_{O}^{(0)}(0.35)= 0.587 \\\\\n", + "E_{0}&= 0-0.587= -0.587\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TFZ8w1dUdT7A" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 1$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wTz3EfAUIoz-" + }, + "source": [ + "[**Python**] - Evocar a função f1= MostraCalculos(1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "INUDJ_aMXEWb" + }, + "source": [ + "f1 = MostraCalculos(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I91qgS1Uh2T1" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JDuyxsKSvDds" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(1, 1)} &= (0)(0.531)+(1)(0.655)= 0.655 \\Longrightarrow f_{H}^{(1, 1)}(S_{H}^{(1, 1)})= f_{H}^{(1, 1)}(0.655)= 0.658 \\\\\n", + "S_{H}^{(1, 2)} &= (0)(0.570)+(1)(0.857)= 0.857 \\Longrightarrow f_{H}^{(1, 2)}(S_{H}^{(1, 2)})= f_{H}^{(1, 2)}(0.857)= 0.702 \\\\\n", + "S_{H}^{(1, 3)} &= (0)(0.543)+(1)(0.602)= 0.602 \\Longrightarrow f_{H}^{(1, 3)}(S_{H}^{(1, 3)})= f_{H}^{(1, 3)}(0.602)= 0.646\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nKPsQA9dvDdt" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(1)}&= (0.658)(0.24)+(0.702)(0.318)+(0.646)(0.142)= 0.473 \\\\\n", + "f_{O}^{(1)}(S_{O}^{(1)})&= f_{O}^{(1)}(0.473)= 0.616 \\\\\n", + "E_{1}&= 1-0.616= 0.384\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IBfztHLfeoTR" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 2$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sjcpG53tIvHf" + }, + "source": [ + "[**Python**] - Evocar a função f2= MostraCalculos(2):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RbnG_WxdXEWg" + }, + "source": [ + "f2 = MostraCalculos(2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9g9MegqIh-Vn" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5gES50aaxszM" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(2, 1)} &= (1)(0.531)+(0)(0.655)= 0.531 \\Longrightarrow f_{H}^{(2, 1)}(S_{H}^{(2, 1)})= f_{H}^{(2, 1)}(0.531)= 0.630 \\\\\n", + "S_{H}^{(2, 2)} &= (1)(0.570)+(0)(0.857)= 0.570 \\Longrightarrow f_{H}^{(2, 2)}(S_{H}^{(2, 2)})= f_{H}^{(2, 2)}(0.570)= 0.639 \\\\\n", + "S_{H}^{(2, 3)} &= (1)(0.543)+(0)(0.602)= 0.543 \\Longrightarrow f_{H}^{(2, 3)}(S_{H}^{(2, 3)})= f_{H}^{(2, 3)}(0.543)= 0.632\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o7n4Eq-6xszP" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(2)}&= (0.630)(0.24)+(0.639)(0.318)+(0.632)(0.142)= 0.444 \\\\\n", + "f_{O}^{(2)}(S_{O}^{(2)})&= f_{O}^{(2)}(0.444)= 0.609 \\\\\n", + "E_{2}&= 1-0.609= 0.391\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cPJQKwBthCkh" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 3$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MVhEsrqJI1T7" + }, + "source": [ + "[**Python**] - Evocar a função f3= MostraCalculos(3):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qU87GWKjXEWo" + }, + "source": [ + "f3 = MostraCalculos(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AjUGJdaYiEH0" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lKptTBkBzysP" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "S_{H}^{(3, 1)} &= (1)(0.531)+(1)(0.655)= 1.186 \\Longrightarrow f_{H}^{(3, 1)}(S_{H}^{(3, 1)})= f_{H}^{(3, 1)}(1.186)= 0.766 \\\\\n", + "S_{H}^{(3, 2)} &= (1)(0.570)+(1)(0.857)= 1.427 \\Longrightarrow f_{H}^{(3, 2)}(S_{H}^{(3, 2)})= f_{H}^{(3, 2)}(1.427)= 0.806 \\\\\n", + "S_{H}^{(3, 3)} &= (1)(0.543)+(1)(0.602)= 1.144 \\Longrightarrow f_{H}^{(3, 3)}(S_{H}^{(3, 3)})= f_{H}^{(3, 3)}(1.144)= 0.758\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ISxS131GzysR" + }, + "source": [ + "##### _OUTPUT LAYER_\n", + "\n", + "\\begin{align}\n", + "S_{O}^{(3)}&= (0.766)(0.24)+(0.806)(0.318)+(0.758)(0.142)= 0.548 \\\\\n", + "f_{O}^{(3)}(S_{O}^{(3)})&= f_{O}^{(3)}(0.548)= 0.634 \\\\\n", + "E_{3}&= 0-0.634= -0.634\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YR3X25venRv5" + }, + "source": [ + "### Resumo dos cálculos com _arrays_\n", + "\n", + "Os cálculos que foram realizados previamente com o NumPy _step by step_ aqui são feitos utilizando produto matricial." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n9D-5dE-I_IS" + }, + "source": [ + "[**Python**] - Funções de ativação da _Hidden Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "efO2aSu8AzMp" + }, + "source": [ + "f0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "BoDRBC8oXEW0" + }, + "source": [ + "X2 = np.array([f0, f1, f2, f3])\n", + "X2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WVIwTcF1JLIm" + }, + "source": [ + "[**Python**] - Calcular a soma $S$ da _Output Layer_, dado pelo produto matricial de $X2$ por $W_{O}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ddyC0sa6XEW5" + }, + "source": [ + "S = X2.dot(W_O)\n", + "S" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NRkyUZN7Jooz" + }, + "source": [ + "[**Python**] - Função de ativação da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jadac2Q3XEW-" + }, + "source": [ + "f = FuncaoAtivacao_Sigmoid(S)\n", + "f" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZuTe0mHg8Kzk" + }, + "source": [ + "Os resultados das funções de ativação acima conferem com o resumo a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r2lHqqhmM6rd" + }, + "source": [ + "[**Python**] - Calcular os Erros" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bCu8miA2XEXE" + }, + "source": [ + "E = Y - f\n", + "E" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P2Q019cxotQM" + }, + "source": [ + "Os cálculos estão resumidos na tabela a seguir:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$) | ValorCalculado ($\\hat{Y}_{i}$) | $Erro$ | $Erro^{2}$ |\n", + "|---|---|---|---|---|:----------------------:|------------------:|\n", + "| 0 | 0 | 0 | 0 | 0.587 | -0.587 | 0.344 |\n", + "| 1 | 0 | 1 | 1 | 0.616 | 0.384 | 0.147 |\n", + "| 2 | 1 | 0 | 1 | 0.609 | 0.391 | 0.152 |\n", + "| 3 | 1 | 1 | 0 | 0.634 | -0.634 | 0.401 |\n", + "\n", + "Onde:\n", + "\n", + "$Erro= y_{i}-\\hat{Y}_{i}$= ValorReal - ValorCalculado\n", + "\n", + "O cálculo do MSE será $MSE= \\frac{0.344+0.147+0.152+0.401}{4}= \\frac{1.044}{4}= 0.261$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lHm_16jEz-kL" + }, + "source": [ + "### Métrica para avaliação da performance da Rede Neural\n", + "\n", + "* O MSE é uma das principais métricas para medir a performance das Redes Neurais. A seguir, o cálculo do MSE:\n", + "\n", + "$$MSE= \\frac{\\sum_{i=1}^{n}(y_{i}-\\hat{Y}_{i})^{2}}{n}= \\frac{(0-0.587)^{2}+(1-0.616)^{2}+(1-0.609)^{2}+(0-0.634)^{2}}{4}= \\frac{0.344+0.147+0.152+0.401}{4}=0.261$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D2Yo6TdpNIPW" + }, + "source": [ + "[**Python**] - Desenvolver função MSE para calcular o MSE = Erro Quadrático Médio:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EENpe-rbXEXL" + }, + "source": [ + "def MSE(Y, f):\n", + " return np.square(Y - f).mean()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ySpVD0-mNQ1s" + }, + "source": [ + "[**Python**] - Evocar a função $MSE(Y, f)$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C0L5ACZnXEXP" + }, + "source": [ + "MSE(Y, f)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xpzv12a48GhA" + }, + "source": [ + "### _Backpropagation_ - Ajuste dos pesos $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$\n", + "\n", + "> _Backpropagation_ (ou simplesmente _Backward_) é o processo que faz com que a Rede Neural aprenda a partir da atualização iterativa dos pesos $W$. A ideia do _Backpropagation_ é que podemos melhorar a performance da Rede Neural através da calibração dos pesos $W$ usando _Gradient Descent_, de forma que os _outputs_ ($\\hat{y}_{i}$) serão cada vez mais próximos do valor real ($y_{i}$)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vjBeg2TTcd40" + }, + "source": [ + "Como vimos anteriormente, a fórmula para atualização dos pesos $W$, dada pela expressão abaixo\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n", + "\n", + "necessita da derivada da _Loss Function_ $L$, que é a função _Sigmoid_, cuja expressão matemática é dada a seguir:\n", + "\n", + "$$y(x)= \\frac{1}{1+e^{-x}}$$\n", + "\n", + "Portanto, a derivada da função _Sigmoid_ é dada pela expressão a seguir:\n", + "\n", + "$$\\frac{dy}{dx}= y^{'}= y(1-y)$$\n", + "\n", + "Caso você tenha dúvidas sobre a derivada da função de ativação _Sigmoid_, sugiro a leitura deste artigo: [Derivative of the Sigmoid function](https://towardsdatascience.com/derivative-of-the-sigmoid-function-536880cf918e)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hDKJakFImuRp" + }, + "source": [ + "* $D_{O}$ é a Derivada do neurônio da _Output Layer_;\n", + "* $\\Delta_{H}= D_{O}* W_{O} * \\Delta_{O}$;\n", + "* $\\Delta_{O}= E_{i}*D_{O}$.\n", + "\n", + "A seguir, a Derivada da função _Sigmoid_ usando o NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kDnarWwwNZd0" + }, + "source": [ + "[**Python**] - Função Derivada_Sigmoid, que calcula a Derivada da função _Sigmoid_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qSxVsNeDXEXY" + }, + "source": [ + "def Derivada_Sigmoid(y):\n", + " return y*(1-y)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CY6O0qkWNhby" + }, + "source": [ + "[**Python**] - Evocar a Derivada_Sigmoid(f), ou seja, calcular a derivada das funções de ativação da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WTpQfBTpXEXi" + }, + "source": [ + "D_O = Derivada_Sigmoid(f)\n", + "D_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jfVdgCFDf9-X" + }, + "source": [ + "Os cálculos acima foram feitos no NumPy e são reproduzidos manualmente abaixo:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TOslp3YSN70r" + }, + "source": [ + "[**Python**] - Função Backpropagation para calcular:\n", + "* _Output Layer_:\n", + " * $D_{O}$ - Derivada dos valores da _Output Layer_;\n", + " * $\\Delta_{O}$ - Delta;\n", + "* _Hidden Layer_:\n", + " * $D_{H}$ - Derivada dos valores da _Hidden Layer_;\n", + " * $\\Delta_{H}$ - Delta" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4PihyM2VXEXq" + }, + "source": [ + "def Backpropagation(i):\n", + " print(f'***** OUTPUT LAYER *****')\n", + " print(f'*** Função de ativação ***')\n", + " print(f[i])\n", + " \n", + " #print('\\n')\n", + " print(f'*** Derivada ***')\n", + " D_O= Derivada_Sigmoid(f)\n", + " print(D_O[i])\n", + "\n", + " #print('\\n') \n", + " print(f'*** Erros ***')\n", + " print(E[i])\n", + "\n", + " #print('\\n')\n", + " print(f'*** Delta ***')\n", + " Delta_O= D_O*E\n", + " print(Delta_O[i])\n", + " \n", + " print('\\n')\n", + " print(f'***** HIDDEN LAYER *****')\n", + " print(f'*** Função de ativação ***')\n", + " print(X2[i])\n", + "\n", + " #print('\\n')\n", + " print(f'*** Derivada ***')\n", + " D_H= Derivada_Sigmoid(X2)\n", + " D_H\n", + " print(D_H[i]) \n", + " \n", + " #print('\\n')\n", + " print(f'*** Delta ***')\n", + " Delta_H= D_H*W_O.T*Delta_O\n", + " print(Delta_H[i]) " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eyGWGHVaFxNG" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 0$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uiOtWoNWOn24" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(0):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SiNkv_DBXEXu" + }, + "source": [ + "Backpropagation(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PqZ_CvGI0ySD" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yO4njWZb1V1w" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(0, 1)} &= D_{H}^{(0, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(0)}= (0.25)(0.24)(-0.142)= -0.009 \\\\\n", + "\\Delta_{H}^{(0, 2)} &= D_{H}^{(0, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(0)}= (0.25)(0.318)(-0.142)= -0.011 \\\\\n", + "\\Delta_{H}^{(0, 3)} &= D_{H}^{(0, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(0)}= (0.25)(0.142)(-0.142)= -0.005\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SXpozezsYFCX" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xDZYiujcHGzK" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 1$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ROzKv5VtOuy5" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(1):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "S6An6CyUXEX0" + }, + "source": [ + "Backpropagation(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EwblrxI20ygW" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "18bsrlv_4B0Q" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(1, 1)} &= D_{H}^{(1, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(1)}= (0.225)(0.24)(0.091)= 0.005 \\\\\n", + "\\Delta_{H}^{(1, 2)} &= D_{H}^{(1, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(1)}= (0.209)(0.318)(0.091)= 0.006 \\\\\n", + "\\Delta_{H}^{(1, 3)} &= D_{H}^{(1, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(1)}= (0.229)(0.142)(0.091)= 0.003\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cPfQUUUHYw4i" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e8qfA8CGHJo8" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 2$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UWxqTLsKOyoK" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(2):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "w39YvfOWXEX7" + }, + "source": [ + "Backpropagation(2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BBZuNcOC0yj9" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sZam1meY48hW" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(2, 1)} &= D_{H}^{(2, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(2)}= (0.233)(0.24)(0.093)= 0.005 \\\\\n", + "\\Delta_{H}^{(2, 2)} &= D_{H}^{(2, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(2)}= (0.231)(0.318)(0.093)= 0.007 \\\\\n", + "\\Delta_{H}^{(2, 3)} &= D_{H}^{(2, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(2)}= (0.232)(0.142)(0.093)= 0.003\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dAc8YrceY5kY" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PWrv-aRyHMPh" + }, + "source": [ + "#### $\\Longrightarrow$ Para $i = 3$:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MKqR3izrO15N" + }, + "source": [ + "[**Python**] - Evocar a função Backpropagation(3):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1APffWq2XEYA" + }, + "source": [ + "Backpropagation(3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PGAXyDhW0ynn" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bdgIs_zP5i1y" + }, + "source": [ + "##### _HIDDEN LAYER_\n", + "\\begin{align}\n", + "\\Delta_{H}^{(3, 1)} &= D_{H}^{(3, 1)}.W_{O}^{(1)}.\\Delta_{O}^{(3)}= (0.179)(0.24)(-0.147)= -0.006 \\\\\n", + "\\Delta_{H}^{(3, 2)} &= D_{H}^{(3, 2)}.W_{O}^{(2)}.\\Delta_{O}^{(3)}= (0.156)(0.318)(-0.147)= -0.007 \\\\\n", + "\\Delta_{H}^{(3, 3)} &= D_{H}^{(3, 3)}.W_{O}^{(3)}.\\Delta_{O}^{(3)}= (0.183)(0.142)(-0.147)= -0.004\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6Ie99-SqZA6z" + }, + "source": [ + "Na figura acima, temos que $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sndwYO-VbK1C" + }, + "source": [ + "A seguir, cálculos usando o NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ycvvhnWIO5s9" + }, + "source": [ + "[**Python**] - $D_{O}$: Derivada da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zkdw8tUKw5vo" + }, + "source": [ + "f" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "poTTrvYEXEYE" + }, + "source": [ + "D_O = Derivada_Sigmoid(f)\n", + "D_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JkdyDN6BPNZT" + }, + "source": [ + "[**Python**] - Mostrar os Erros:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AO9Qi9U0aWTx" + }, + "source": [ + "E" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DPPqqxpIPRsT" + }, + "source": [ + "[**Python**] - $\\Delta_{O}$: Delta da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6fylksvtaT6h" + }, + "source": [ + "Delta_O = D_O*E\n", + "Delta_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E9zsXwcWPXn1" + }, + "source": [ + "[**Python**] - $D_{H}$: Derivada da _Hidden Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SCABYAGjaigm" + }, + "source": [ + "D_H = Derivada_Sigmoid(X2)\n", + "D_H" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bLa9L88VPdQu" + }, + "source": [ + "[**Python**] - $D_{O}$ - Derivada da _Output Layer_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "58r5kgNwa9xo" + }, + "source": [ + "Delta_H = D_H*W_O.T*Delta_O\n", + "Delta_H" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "roh5SVtkQrJE" + }, + "source": [ + "### _Backpropagation_ - Atualizar os pesos da _Output Layer_ $W_{O}= \\begin{bmatrix} W_{O}^{(1)} \\\\ W_{O}^{(2)} \\\\ W_{O}^{(3)} \\end{bmatrix}$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CQ69tO1IPsBQ" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "K991veZeXEYL" + }, + "source": [ + "X2.T.dot(Delta_O)[0]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hz-0fQAGd7Aw" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ovgjM8l6Np0e" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.658)\\Delta_{O}^{(1)}+(0.630)\\Delta_{O}^{(2)}+(0.766)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.658)(0.091)+(0.630)(0.093)+(0.766)(-0.147)= -0.065$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BFaNh6NEXEYO" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "eomk5j12XEYT" + }, + "source": [ + "X2.T.dot(Delta_O)[1]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M-3gk0erRpSF" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hVCFLfWGPE7W" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.702)\\Delta_{O}^{(1)}+(0.639)\\Delta_{O}^{(2)}+(0.866)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.702)(0.091)+(0.639)(0.093)+(0.806)(-0.147)= -0.067$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MK92KMHYXEYV" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{O})= (X2*\\Delta_{O})$ para atualizar $W_{O}^{(3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "D05BW8CgXEYc" + }, + "source": [ + "X2.T.dot(Delta_O)[2]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K754V1CSRtii" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q51biJ5TPkKX" + }, + "source": [ + "$$(0.5)\\Delta_{O}^{(0)}+(0.646)\\Delta_{O}^{(1)}+(0.632)\\Delta_{O}^{(2)}+(0.758)\\Delta_{O}^{(3)}$$\n", + "$$(0.5)(-0.142)+(0.646)(0.091)+(0.632)(0.093)+(0.758)(-0.147)= -0.067$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SaEVJAXGV3Xd" + }, + "source": [ + "###### Implementação com NumPy\n", + "\n", + "* Fórmula para atualização dos pesos $W_{O}$:\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a7dGpwzfRN2M" + }, + "source": [ + "[**Python**] - Calcular/atualizar os pesos $W_{O}$ através da expressão de $W_{n+1}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "er3DprzjXEYg" + }, + "source": [ + "M = 1\n", + "alpha = 0.1\n", + "\n", + "W_O_New = W_O*M+alpha*(X2.T.dot(Delta_O))\n", + "W_O_New" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0-2weyIriNqN" + }, + "source": [ + "Abaixo, os pesos atualizados de $W_{O}$ (antes e depois)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GLkZfXbmi9c6" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "t4fHsSY3AlFi" + }, + "source": [ + "### _Backpropagation_ - Ajuste dos pesos $W_{H}= \\begin{bmatrix} W_{H}^{(1, 1)} & W_{H}^{(1, 2)} & W_{H}^{(1, 3)} \\\\ W_{H}^{(2, 1)} & W_{H}^{(2, 2)} & W_{H}^{(2, 3)} \\end{bmatrix}$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cCED4NKj1_FX" + }, + "source": [ + "#### Ajuste dos pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$\n", + "\n", + "Para ajustar os pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$, precisamos dos valores de $\\Delta_{H}$, calculado anteriormente:\n", + "\n", + "* $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$;\n", + "* $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(((1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$;\n", + "* $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$;\n", + "* $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$.\n", + "\n", + "Veja abaixo no NumPy:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kNHXkTXLRmzu" + }, + "source": [ + "[**Python**] - Mostrar $\\Delta_{H}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oYxrEVC7XEYn" + }, + "source": [ + "Delta_H" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XihSawh-1iKI" + }, + "source": [ + "##### Resumo dos valores de $(X*\\Delta_{H})$ calculados manualmente:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DNXt5DAhBiVC" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "06duXU28XEYy" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DTCJ_5O7SeU9" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WeJOgJd5P5BS" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 1)}+(0)\\Delta_{H}^{(1, 1)}+(1)\\Delta_{H}^{(2, 1)}+(1)\\Delta_{O}^{(3, 1)}$$\n", + "$$(0)(-0.009)+(0)(0.005)+(1)(0.005)+(1)(-0.006)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8mbs0ZNTCRKL" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qF1iFyRWXEY9" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xWkm7eyLSm6I" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X9LQgX05Qj8M" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 2)}+(0)\\Delta_{H}^{(1, 2)}+(1)\\Delta_{H}^{(2, 2)}+(1)\\Delta_{H}^{(3, 2)}$$\n", + "$$(0)(-0.011)+(0)(0.006)+(1)(0.007)+(1)(-0.007)= 0$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oaVbGCATCd7B" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(1, 3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4UNZFSC5XEZE" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4JHAiH5GSqr0" + }, + "source": [ + "\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DDrurArKQ5I_" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 3)}+(0)\\Delta_{H}^{(1, 3)}+(1)\\Delta_{H}^{(2, 3)}+(1)\\Delta_{H}^{(3, 3)}$$\n", + "$$(0)(-0.005)+(0)(0.003)+(1)(0.003)+(1)(-0.004)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GWwWUfiXXlom" + }, + "source": [ + "#### Ajuste dos pesos $W_{H}^{(2, 1)}, W_{H}^{(2, 2)}$ e $W_{H}^{(2, 3)}$\n", + "\n", + "Para ajustar os pesos $W_{H}^{(1, 1)}, W_{H}^{(1, 2)}, W_{H}^{(1, 3)}$, precisamos dos valores de $\\Delta_{H}$, calculado anteriormente:\n", + "\n", + "* $\\Delta_{H}^{(0)}= [\\Delta_{H}^{(0, 1)}, \\Delta_{H}^{(0, 2)}, \\Delta_{H}^{(0, 3)}]= [-0.009, -0.011, -0.005]$;\n", + "* $\\Delta_{H}^{(1)}= [\\Delta_{H}^{(1, 1)}, \\Delta_{H}^{(1, 2)}, \\Delta_{H}^{(1, 3)}]= [0.005, 0.006, 0.003]$;\n", + "* $\\Delta_{H}^{(2)}= [\\Delta_{H}^{(2, 1)}, \\Delta_{H}^{(2, 2)}, \\Delta_{H}^{(2, 3)}]= [0.005, 0.007, 0.003]$;\n", + "* $\\Delta_{H}^{(3)}= [\\Delta_{H}^{(3, 1)}, \\Delta_{H}^{(3, 2)}, \\Delta_{H}^{(3, 3)}]= [-0.006, -0.007, -0.004]$." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DzeytNngSI08" + }, + "source": [ + "[**Python**] - Mostra $\\Delta_{H}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vfiS9bFqXEZH" + }, + "source": [ + "Delta_H" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dSDbe8o8k9yi" + }, + "source": [ + "##### Resumo de $(X*\\Delta_{H})$ calculados manualmente:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D6e2ZoMmDLFN" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 1)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SH4yHqoYXEZP" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zORHdsEiXwSw" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P11cTnsCRpwj" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 1)}+(1)\\Delta_{H}^{(1, 1)}+(0)\\Delta_{H}^{(2, 1)}+(1)\\Delta_{H}^{(3, 1)}$$\n", + "$$(0)(-0.009)+(1)(0.005)+(0)(0.005)+(1)(-0.006)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W_LMmSEVDXY7" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 2)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YE4DH6P_XEZZ" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Gz7bhUuDX6Me" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OLrwPoE7SGYu" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 2)}+(1)\\Delta_{H}^{(1, 2)}+(0)\\Delta_{H}^{(2, 2)}+(1)\\Delta_{H}^{(3, 2)}$$\n", + "$$(0)(-0.011)+(1)(0.006)+(0)(0.007)+(1)(-0.007)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vzbUzC8FDhuo" + }, + "source": [ + "[**Python**] - $(X*\\Delta_{H})$ para atualizar $W_{H}^{(2, 3)}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7-epl7I3XEZf" + }, + "source": [ + "X.T.dot(Delta_H)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0gT8_uDQX-NT" + }, + "source": [ + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QLz57OEPSWjl" + }, + "source": [ + "$$(0)\\Delta_{H}^{(0, 3)}+(1)\\Delta_{H}^{(1, 3)}+(0)\\Delta_{H}^{(2, 3)}+(1)\\Delta_{H}^{(3, 3)}$$\n", + "$$(0)(-0.005)+(1)(0.003)+(0)(0.003)+(1)(-0.004)= -0.001$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7G9gWkKWIIOL" + }, + "source": [ + "##### Implementação com NumPy\n", + "\n", + "Usando:\n", + "* M = 1;\n", + "* $\\alpha = 0.1$;\n", + "* Fórmula: $W_{n+1} = (W_{n}*M)+\\alpha*(X*\\Delta_{H})$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5C3NCWcuShqN" + }, + "source": [ + "[**Python**] - Calcular/atualizar os pesos $W_{H}$ usando a expressão $W_{n+1}$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ys_y-R0BL7Iw" + }, + "source": [ + "M = 1\n", + "alpha = 0.1\n", + "\n", + "W_H_New = W_H*M+alpha*(X.T.dot(Delta_H))\n", + "W_H_New" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IvaIx_PKZEmd" + }, + "source": [ + "##### Novos Pesos $W_{H}$ e $W_{O}$ da Rede Neural (Antes x Depois)\n", + "\n", + "\"Drawing\"\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EuO2t22CffE8" + }, + "source": [ + "___\n", + "# **Como as Redes Neurais aprendem?**\n", + "\n", + "> Vimos até agora grande parte dos cálculos matemáticos que envolvem o treinamento das Redes Neurais, que envolvem a repetição dos processos _Forward_ e _Backward_:\n", + "\n", + "1. _**Forward**_: Consiste na multiplicação de matrizes entre os _arrays_ da _input layer_, pesos $W$ e, na sequência, aplicar as funções de ativação.\n", + "\n", + "2. _**Backward**_: Consiste em atualizar os pesos $W_{O}$ e $W_{H}$ para minimizar a _Loss Function_ $L$ usando _Gradient Descent_.\n", + "\n", + "* Estes 2 processos foram vistos detalhadamente em aulas anteriores.\n", + " * Cálculos matemáticos passo a passo foram mostrados. Portanto, visite nossas aulas anteriores para aprender mais sobre os aspectos teóricos e matemáticos por trás das Redes Neurais.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mpKyqSuDdbMr" + }, + "source": [ + "___\n", + "# **_GRADIENT DESCENT_**\n", + "\n", + "_Gradient Descent_ é um algoritmo interativo utilizado para otimizar (neste caso, minimizar) a _Loss Function_ $L$. \n", + "\n", + "* Minimizar a _Loss Function_ $L$ significa encontrar os pesos $W_{H}$ e $W_{O}$ que faz com que MSE seja o menor possível, pois quanto menor o MSE, melhor a performance da Rede Neural. \n", + "\n", + "* Para atualizar os pesos $W$, vamos usar a expressão a seguir:\n", + "\n", + "$$W_{n+1}= W_{n}*M+\\alpha \\frac{\\partial L}{\\partial W_{n}}= W_{n}*M+\\alpha*(X*\\Delta)$$\n", + "\n", + "onde:\n", + "\n", + "* $L$ é a _Loss Function_ a ser minimizada;\n", + "* $W_{n}$ são os pesos atuais e que deverão ser atualizados para a próxima iteração;\n", + "* $\\alpha$ é a taxa de aprendizado (_Learning Rate_ em inglês) e diz respeito à velocidade de aprendizagem da Rede Neural.\n", + " * Quanto MENOR o valor de $\\alpha$ $\\Longrightarrow$ mais devagar e demorada será a convergência para o mínimo global;\n", + " * Quanto MAIOR o valor de $\\alpha$ $\\Longrightarrow$ mais rápido será a convergência para o mínimo, mas sem a garantia de convergência para o mínimo global.\n", + "* $M$ é o _Momentum_, que é o artifício para acelerar a otimização (ou minimização) da _Loss Function_ $L$.\n", + " * Valores altos $\\Longrightarrow$ Aumenta a velocidade da aprendizagem;\n", + " * Valores baixos $\\Longrightarrow$ Mais tempo para aprendizagem, mas com maiores chances de se encontrar a solução ótima, evitando os mínimos locais.\n", + "* $\\frac{\\partial L}{\\partial W_{n}}$ é a derivada da _Loss Function_ $L$ em relação ao peso $W_{n}$. Como dito anteriormente, é a contribuição do peso $W$ no Erro. Calcular $(X*\\Delta)$ é a parte mais complicada da fórmula e fizemos estes cálculos passo a passo em aulas anteriores." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzuFSOV4eboI" + }, + "source": [ + "Observe a figura a seguir: O que o _Gradient Descent_ fará é encontrar o mínimo global da _loss function_, tentando ao máximo possível evitar os mínimos locais.\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z-UbiCxUgvHg" + }, + "source": [ + "A seguir, alguns artigos sobre _Gradient Descent_ caso você queira saber um pouco mais sobre o assunto:\n", + "\n", + "* [An introduction to Gradient Descent Algorithm](https://medium.com/@montjoile/an-introduction-to-gradient-descent-algorithm-34cf3cee752b) - Abrir este artigo para mostrar os efeitos da _Learning Rate_ e os tipos de _Gradient Descent_ disponíveis para Machine Learning;\n", + "* [Machine learning : Gradient Descent](https://medium.com/@arshren/gradient-descent-5a13f385d403);\n", + "* [The Math and Intuition Behind Gradient Descent](https://medium.com/datadriveninvestor/the-math-and-intuition-behind-gradient-descent-13c45f367a11) - Mostra a matemática por trás do _Gradient Descent_;\n", + "* [An Introduction to Gradient Descent](https://towardsdatascience.com/an-introduction-to-gradient-descent-c9cca5739307);\n", + "* [Gradient Descent From Scratch](https://towardsdatascience.com/gradient-descent-from-scratch-e8b75fa986cc);\n", + "* [Gradient Descent Explanation & Implementation](https://towardsdatascience.com/gradient-descent-explanation-implementation-c74005ff7dd1) - Cálculos step-by-step;" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "junvtVY4eePi" + }, + "source": [ + "___\n", + "# **_LOSS FUNCTION_ $L$**\n", + "\n", + "> Como vimos anteriormente, nosso objetivo é minimizar a _Loss function_ através do _Gradient Descent_. Em outras palavras, esse processo de otimização busca, à cada iteração (_epoch_), atualizar os pesos $W$ para reduzir a _Loss Function_. As _Loss Function_ mais comuns são:\n", + "\n", + "* **Regressão**: mse ou mae;\n", + "* **Classificação**: _cross-entropy_ (quando queremos probabilidades de cada observação pertencer à uma determinada classe).\n", + " * **Classificação binária**: tf.keras.losses.BinaryCrossentropy()\n", + ";\n", + " * **Classificação multi-classes**: tf.keras.losses.CategoricalCrossentropy()\n", + "." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6e4ULmJheePY" + }, + "source": [ + "___\n", + "# **MÉTRICAS PARA MEDIR A PERFORMANCE DAS REDES NEURAIS**\n", + "\n", + "* As métricas medem a qualidade/performance das Redes Neurais e as principais são:\n", + " * **Regressão**: Quanto mais próximo de 0 estiver MAE, MSE ou RMSE, melhor a performance da Rede Neural.\n", + " * MAE significa \"_Mean Absolute Error_\".\n", + "\n", + " * MSE - significa \"_Mean Square Error_\", que é a diferença entre os valores reais $y_{i}$ e os valores previstos (ou calculados) $\\hat{Y}_{i}$.\n", + "\n", + " * RMSE - significa \"_Root Mean Square Error_\".\n", + " \n", + " * **Classificação**: Quanto maior a accuracy, melhor a performance da Rede Neural.\n", + " * Accuracy\n", + "\n", + "* Expressões Matemáticas:\n", + "\n", + "\\begin{align}\n", + "MSE &= \\frac{\\sum_{i=1}^{n}(y_{i}-\\hat{Y}_{i})^{2}}{n} \\\\\n", + "RMSE &= \\sqrt{MSE} \\\\\n", + "MAE &= \\frac{\\sum_{i=1}^{n}|y_{i}-\\hat{Y}_{i}|}{n}\n", + "\\end{align}\n", + "\n", + "Para os alunos que estão com dúvidas sobre qual métrica usar, sugiro a leitura do artigo [MAE and RMSE — Which Metric is Better?](https://medium.com/human-in-a-machine-world/mae-and-rmse-which-metric-is-better-e60ac3bde13d)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6n4QjH1WeeO8" + }, + "source": [ + "___\n", + "# **_DROPOUT_**\n", + "\n", + "> _Dropout_ significa ignorar aleatoriamente e temporariamente um percentual $p$ de neurônios durante a fase de treinamento. Ao \"ignorar\", quero dizer que tais neurônios não serão considerados durante os processos _forward_ e _backpropagation_.\n", + "\n", + "* _Dropout_ força que a Rede Neural aprenda a partir dos dados, mas usando diferentes e aleatórios neurônios;\n", + "* Recomenda-se $p = 0.20$. \n", + "* Ao se usar _Dropout_, recomenda-se mais épocas para treinar a Redes Neurais;\n", + "\n", + "* **Vantagens**:\n", + " * Evita _overfitting_ - Num \"_fully connected layer_\", neurônios desenvolvem dependência durante a fase de treinamento levando ao _overfitting_. Com _dropout_ é possível reduzir um pouco desta dependência, reduzindo as chances de _overfitting_;\n", + "\n", + "![Dropout](https://github.com/MathMachado/Materials/blob/master/Dropout.png?raw=true)\n", + "\n", + "Fonte: [Dropout in (Deep) Machine learning](https://medium.com/@amarbudhiraja/https-medium-com-amarbudhiraja-learning-less-to-learn-better-_dropout_-in-deep-machine-learning-74334da4bfc5).\n", + "\n", + "TEMPLATE: keras.layers.Dropout(rate, noise_shape=None, seed=None)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9-9Y9562kNNU" + }, + "source": [ + "___\n", + "# **Rede Neural multicamada (1 _Hidden Layer_) para o Operador Lógico XOR usando _Tensorflow_/_Keras_**\n", + "\n", + "* **Observações**:\n", + " * Há vários artigos (no _medium_, por exemplo) a discutir e desenvolver Redes Neurais para o Operador Lógico XOR. Então porque eu decidi produzir esta aula usando o dataframe do Operador Lógico XOR?\n", + " * Para explicar didaticamente e passo a passo todos os aspectos matemáticos por trás das Redes Neurais usando um dataframe pequeno e, apesar disso, complexo, pois é um problema linearmente NÃO-separável e, sendo assim, requer uma Rede Neural mais complexa (com pelo menos 1 _Hidden Layer_) para melhorar a acurácia e reduzir a _loss_;\n", + " * Para explicar como é fácil desenvolver Redes Neurais usando Tensorflow/Keras;\n", + " * Para explicar didaticamente e passo a passo os processos _Forward_ e _Backward_ para treinar Redes Neurais;\n", + " * Versão do Tensorflow usada: 2.x;\n", + " * Estou a utilizar o Google Colab;\n", + " * Nesta aula, não se preocupe demasiadamente com a sintaxe dos comandos. Porque?\n", + " * Vamos repetir tudo detalhadamente nas próximas aulas. Portanto, você terá a oportunidade de aprender e praticar muito em breve;\n", + " * O objetivo desta aula é simplesmente fazer uma introdução às Redes Neurais, Tensorflow/Keras e mostrar os passos/processos que vamos seguir aqui e no futuro para desenvolver Redes Neurais. Quando você assistir as aulas subsequentes, tudo ficará mais claro.\n", + "* Todas as aulas do curso de Redes Neurais foram cuidadosamente planejadas e preparadas para trazer conteúdos relevantes para você aprender Redes Neurais no menor tempo possível. Portanto, nesta aula você vai encontrar várias linhas como a linha adiante:\n", + "\n", + "[**Python**] - Comando ou _code_ que deve ser executado.\n", + "\n", + "Estas linhas são uma espécie de _guide_ para não nos esquecermos de nenhum detalhe da aula. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rOQbXbCgZZRL" + }, + "source": [ + "A seguir, dataframe do Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KusCpN1S4CtH" + }, + "source": [ + "Vamos obedecer os _steps_ a seguir para construir nossa Rede Neural:\n", + "\n", + "1. Carregar as bibliotecas do Python e Tensorflow;\n", + "2. Carregar os dados para treinar a Rede Neural;\n", + "3. Definir a arquitetura da Rede Neural com Tensorflow/Keras;\n", + "4. Compilar a Rede Neural;\n", + "5. Ajustar a Rede Neural;\n", + "6. Avaliar a performance da Rede Neural;\n", + "7. _Fine tuning_ da Rede Neural;\n", + "8. Fazer Predições com a Rede Neural;\n", + "9. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mq7pF8854cf6" + }, + "source": [ + "### 1. Carregar as bibliotecas do Python e Tensorflow" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Br4REluttJXH" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W-1jl_vnP7n3" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import tensorflow as tf\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UA_bHIYOrNwy" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ApSwaqVbQVGx" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CH37RXFLtPpB" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais = 3" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Pzdu5btatTom" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5YbKhVkd4sm2" + }, + "source": [ + "### 2. Carregar os dados para treinar a Rede Neural\n", + "\n", + "Segue abaixo o dataframe do Operador Lógico XOR:\n", + "\n", + "| i | $X_{1}$ | $X_{2}$ | ValorReal ($y_{i}$)|\n", + "|---|---|---|---|\n", + "| 0 | 0 | 0 | 0 |\n", + "| 1 | 0 | 1 | 1 |\n", + "| 2 | 1 | 0 | 1 |\n", + "| 3 | 1 | 1 | 0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3uojCCMaWgtI" + }, + "source": [ + "[**Python**] - Definir as entradas (_inputs_) $X$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nTbtpKKdQh9M" + }, + "source": [ + "X_XOR = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n", + "X_XOR" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7hc1pYW-WsCp" + }, + "source": [ + "[**Python**] - Definir os _Outputs_ $Y$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Gj4zl-JdQ0nR" + }, + "source": [ + "y_XOR = np.array([[0], [1], [1], [0]])\n", + "y_XOR" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2WF73gTMZtN-" + }, + "source": [ + "### 3. Conceito importante: _Fully connected layer_\n", + "\n", + "> A arquitetura da Rede Neural abaixo é dita _fully connected_, ou seja, os neurônios da camada anterior se conecta com todos os neurônios da camada subsequente. Observe a figura a seguir:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7X5eys3mxsl2" + }, + "source": [ + "#### Arquitetura da Rede Neural\n", + "\n", + "> A seguir, a arquitetura da Rede Neural que vamos desenvolver neste exemplo:\n", + "\n", + "\"Drawing\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QpmtGEFgWzhk" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação:\n", + " * _Hidden Layer_: Há várias opções que podem ser usadas, mas vou tentar resolver este exemplo com a função de ativação _Sigmoid_, que foi a função de ativação que foi a opção escolhida quando explicamos Redes Neurais passo a passo.\n", + " * _Output Layer_: Os valores de $y_{i}$ do dataframe são binários. Portanto, nossa opção para função de ativação para a _Output Layer_ é usar a função de ativação _Sigmoid_." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Id_P910LRRb4" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2 # Número de variáveis/colunas da matriz de preditoras\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 3\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.sigmoid\n", + "\n", + "# Função de Ativação da Output Layer\n", + "FA_O = tf.keras.activations.sigmoid" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n6s9RcjLXqQm" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3DizOTqQR6-U" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vdcdcNncYB15" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E8KJ0f70HEwN" + }, + "source": [ + "**Observação**:\n", + "\n", + "* A opção kernel_constraint= tf.keras.constraints.UnitNorm() será utilizada para reduzir _overfitting_, conforme sugere o artigo [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/);." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-LYbXfEZYNcC" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "\n", + "RN = Sequential() # nome da Rede Neural\n", + "RN.add(Dense(units = N_H, \n", + " input_dim = N_I, \n", + " activation = FA_H, \n", + " kernel_constraint = tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation = FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural:\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OoA-_8A55jMW" + }, + "source": [ + "### 4. Compilar a Rede Neural\n", + "\n", + "> Adam é um algoritmo de otimização.\n", + "\n", + "Para saber mais sobre o algoritmo de otimização 'adam', consulte o artigo [Gentle Introduction to the Adam Optimization Algorithm for Deep Learning](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ifkjrCT6Yki6" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OdIerBPAUGbY" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam() # Algoritmo de otimização\n", + "Loss_Function = tf.keras.losses.MeanSquaredError() # A métrica para cálculo do erro\n", + "Metrics_Perf = [tf.keras.metrics.binary_accuracy]\n", + "\n", + "RN.compile(optimizer = Algoritmo_Opt, \n", + " loss= Loss_Function, \n", + " metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KVx2w28c5urj" + }, + "source": [ + "### 5. Ajustar/treinar a Rede Neural\n", + "\n", + "* 1 _Epoch_ = 1 iteração da Rede Neural, passando por todo o dataframe de treinamento, sendo que 1 iteração contempla 1 processo _Forward_ e 1 processo _Backward_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZV3XwUJ8YvxE" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "45inZ8X3U0Ew" + }, + "source": [ + "hist = RN.fit(X_XOR, y_XOR, epochs = 100)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i1bUiekR5q1E" + }, + "source": [ + "### 6. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wBp4ctbKY8k7" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M4HlrjjjVLjB" + }, + "source": [ + "RN.evaluate(X_XOR, y_XOR)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iPwANO05VT5m" + }, + "source": [ + "**Resultado**: O modelo _baseline_ (modelo inicial) apresenta os seguintes resultados:\n", + "* loss= 0.2515;\n", + "* accuracy= 50%.\n", + "\n", + "* **Comentário**: A Rede Neural apresenta resultados insatisfatórios." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lD2pw9H754ZZ" + }, + "source": [ + "### 7. _Fine tuning_ da Rede Neural\n", + "\n", + "Antes de falarmos de _fine tuning_, vamos voltar a falar de CRISP-DM:\n", + "\n", + "CRISP-DM significa _Cross Industry Standard Process for Data Mining_ ou processos ou fases para desenvolvimento de projetos relacionados à _Data Mining_ e que tem sido muito utilizados pelos Cientistas de Dados para desenvolvimento de modelos predictivos.\n", + "\n", + "\"Drawing\"\n", + "\n", + "Fonte: [The steps to a successful machine learning project](https://emba.epfl.ch/2018/04/10/steps-successful-machine-learning-project/)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1ssJuKF3FNA3" + }, + "source": [ + "* CRISP-DM:\n", + " 1. _Business Understanding_ (Entendimento do Negócio)\n", + " * Concentra-se no entendimento dos objetivos e requisitos do projeto sob uma perspectiva de negócios e, em seguida, na conversão desse conhecimento em uma definição de problema de mineração de dados e em um plano preliminar.\n", + "\n", + " 2. _Data Understanding_ (Entendimento/compreensão dos dados)\n", + " * Está relacionado com as atividades de extração de amostras para se familiarizar com os dados, identificar problemas de qualidade, descobrir as primeiras idéias ou detectar subconjuntos interessantes para formar hipóteses de informações ocultas.\n", + "\n", + " 3. _Data Preparation_ (Preparação de Dados)\n", + "\n", + " * Abrange todas as atividades para construir o conjunto de dados final que será dividida entre amostra de treinamento e validação do modelo preditivo.\n", + "\n", + " 4. _Modeling_ (Modelagem)\n", + "\n", + " * Nesta fase se avalia as possíveis técnicas que podem ser aplicadas.\n", + "\n", + " 5. _Evaluation_ (Avaliação do modelo)\n", + "\n", + " * Após a construção do modelo _baseline_ (modelo inicial) e tendo _Loss Function_ pré-definidas, avalia-se ou testa-se a performance dos modelos preditivos (Redes Neurais, no nosso caso) para garantir que o modelo generaliza. De todos os modelos testados nesta fase, devemos selecionar o modelo campeão.\n", + "\n", + " 6. _Deployment_ (Implantação)\n", + "\n", + " * Significa implementar o código do modelo em um sistema operacional para pontuar/escorar ou categorizar novos dados à medida que surgem e criar um mecanismo para o uso dessas novas informações na solução do problema comercial original. Importante, a representação de código também deve incluir todas as etapas de preparação de dados que antecederam a modelagem, para que o modelo trate novos dados brutos da mesma maneira que durante o desenvolvimento do modelo." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VrgiPmD3jw_o" + }, + "source": [ + "#### Estratégias para melhorar a acurácia da Rede Neural\n", + "\n", + "Nossas alternativas são:\n", + "\n", + "* a. Aumentar o número de neurônios na _Hidden Layer_;\n", + "* b. Aumentar o número de _Hidden Layers_;\n", + "* c. Aumentar o número de _Hidden Layers_ e o número de neurônios;\n", + "* d. Alterar a função de ativação;\n", + "* e. Aumentar o número de _epochs_;\n", + "* f. Alterar o algoritmo de otimização (_optimizer_);\n", + "\n", + "Neste exemplo, depois de várias tentativas, obtive sucesso alterando os parâmetros a seguir: \n", + "* Função de ativação: alterar para tf.keras.activations.relu;\n", + "* Número de neurônios na camada escondida (_Hidden Layer_): aumentei para 64." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V81AQ9t8IA9D" + }, + "source": [ + "#### 7.3. Definir a arquitetura da Rede Neural com Tensorflow/Keras" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yVhR55OoaWeX" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação:\n", + " * _Hidden Layer_: tf.keras.activations.relu;\n", + " * _Output Layer_: Os valores de $y_{i}$ do dataframe são binários. Portanto, nossa opção para função de ativação para a _Output Layer_ é usar a função de ativação _Sigmoid_." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "R26Rf7x_aWeZ" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2 # NÃO FOI ALTERADA!\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1 # NÃO FOI ALTERADA!\n", + "\n", + "# VARIÁVEIS ALTERADAS:\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 64\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.relu # ALTERADA!\n", + "\n", + "# Função de Ativação da Output Layer\n", + "FA_O = tf.keras.activations.sigmoid # NÃO FOI ALTERADA!" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LtQXjYnvIdJR" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WSCCZ6BcIdJZ" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MwjdTXWNawSz" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OWpJNRQjIRA4" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "khod_vL5awS2" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN = Sequential()\n", + "RN.add(Dense(units = N_H, input_dim = N_I, activation = FA_H, kernel_constraint = tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units = N_O, activation = FA_O))\n", + "\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8V5EygkgIRA8" + }, + "source": [ + "#### 7.4. Compilar a Rede Neural\n", + "\n", + "> Adam é um algoritmo de otimização.\n", + "\n", + "Para saber mais sobre 'adam', consulte o artigo [Gentle Introduction to the Adam Optimization Algorithm for Deep Learning](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aEgVJAInbFW0" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FRhAlexLW29o" + }, + "source": [ + "#Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Algoritmo_Opt = tf.keras.optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False,\n", + " name='Adam')\n", + "\n", + "Loss_Function = tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = [tf.keras.metrics.binary_accuracy]\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jxpOHzSKIRA-" + }, + "source": [ + "#### 7.5. Ajustar a Rede Neural\n", + "\n", + "1 _Epoch_ = 1 iteração da Rede Neural, passando por todo o dataframe de treinamento, sendo que 1 iteração contempla 1 processo _Forward_ e 1 processo _Backward_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "o-1iqXLabR4O" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vqyeqpq5XGAm" + }, + "source": [ + "RN.fit(X_XOR, y_XOR, epochs = 100)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C25ZV-x4IRBB" + }, + "source": [ + "#### 7.6. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tCd2S65ubg_M" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I8-Vr9lXXav4" + }, + "source": [ + "RN.evaluate(X_XOR, y_XOR)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6IqEhL-2Xj-t" + }, + "source": [ + "**Resultado**: O modelo após o _fine tuning_ apresenta os seguintes resultados:\n", + "* loss= 0.1502;\n", + "* accuracy= 100%.\n", + "\n", + "* **Comentário**: A Rede Neural apresenta resultados satisfatórios." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AZjDavkO58Pu" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HV4HkNDcbmJ2" + }, + "source": [ + "[**Python**] - Comando RN.predict_classes(X_treinamento):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aum69OJENO6V" + }, + "source": [ + "y_pred = RN.predict_classes(X_XOR)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rNogASabEhz8" + }, + "source": [ + "y_XOR" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8xaBkwD15-1d" + }, + "source": [ + "### 9. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UULwoI-9yPIs" + }, + "source": [ + "A Rede Neural final, após a fase de _fine tuning_ apresenta os resultados mostrados na sessão 7.6. Diante destes resultados, sugerimos avançarmos para a fase de _deployment_ da Rede Neural, conforme sugere o CRISP-DM." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uFK4SeM5TLOb" + }, + "source": [ + "### **Exercício**\n", + "\n", + "1. Experimente usar outras funções de ativação para a _Hidden Layer_, registre e reporte seus resultados. Para saber mais sobre quais funções de ativação podem ser usadas, consulte [Module: tf.keras.activations](https://www.tensorflow.org/api_docs/python/tf/keras/activations);\n", + "\n", + "2. Experimente usar outros algoritmos de otimização para treinar a Rede Neural, registre e reporte seus resultados. Para saber quais algoritmos podem ser usados, consulte [Module: tf.keras.optimizers](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers).\n", + "\n", + "3. Neste exemplo, usamos o algoritmo de otimização 'adam'. Consulte a documentação sobre o 'adam' no Tensorflow/Keras e você verá que a sintaxe do algoritmo é:\n", + "\n", + "```\n", + "tf.keras.optimizers.Adam(\n", + " learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False,\n", + " name='Adam', **kwargs\n", + ")\n", + "```\n", + "\n", + "Refaça o treinamento da Rede Neural alterando os valores da _Learning Rate_ e reporte seus resultados.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pyyiNwm6eeP4" + }, + "source": [ + "___\n", + "# **_ACTIVATION FUNCTION_**\n", + "\n", + "> As funções de ativação são uma importante parte das Redes Neurais, pois permitem às Redes Neurais a lidar com a não-linearidade existente na maioria dos problemas reais.\n", + "\n", + "As funções de ativação (_Activation Function_ em inglês) mais usadas são:\n", + "* _Sigmoid_;\n", + "* ReLU (_Rectified Linear Unit_);\n", + "* Leaky ReLU;\n", + "* _Generalized_ ReLU;\n", + "* Tanh;\n", + "* _Swish_.\n", + "\n", + "Os artigos a seguir discutem estas principais funções de ativação:\n", + "* [Classical Neural Net: Why/Which Activations Functions?](https://towardsdatascience.com/classical-neural-net-why-which-activations-functions-401159ba01c4);\n", + "* [Intermediate Topics in Neural Networks](https://towardsdatascience.com/comprehensive-introduction-to-neural-network-architecture-c08c6d8e5d98);\n", + "* [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F7jF5SToOKYC" + }, + "source": [ + "### Funções de ativação para _Hidden Layers_:\n", + "\n", + "Há várias funções de ativação que podem ser utilizadas na _Hidden Layer_. As principais são:\n", + "\n", + "* ReLU\n", + " * evita e corrige o problema conhecido como _vanishing gradient problem_, que é justamente o principal ponto fraco das funções de ativação _sigmoid_ e _tanh_. Este problema acontece porque algumas derivadas são zero para metade dos valores da entrada $X = [X_{1}, X_{2}, ..., X_{n}]$, o que pode levar ao que se chama de \"neurônios mortos\";\n", + " * Quase todos os modelos de _Deep Learning_ hoje usam ReLU que **deve ser usada somente para _Hidden Layers_ das Redes Neurais**. \n", + "* Leaky ReLU\n", + " * Alternativa melhor que ReLU;\n", + "* _Swish_\n", + " * esta é outra alternativa melhor que ReLU, proposta pelo Google em 2017;\n", + " * alguns artigos apontam melhoria dos resultados das Redes Neurais com _Swish_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8dYvHeYbN_c4" + }, + "source": [ + "### Funções de ativação para _Output Layers_:\n", + "\n", + "A função de ativação da _Output Layer_ depende do problema:\n", + "\n", + "* _Sigmoid_ para problemas de classificação binária (2 classes).\n", + " * Exemplo: Dataframe: Titanic, pois queremos estimar se o passageiro morreu ou sobreviveu;\n", + "* _Softmax_ para problemas de classificação multi-classes (> 2 classes).\n", + " * Exemplo: Dataframe: Iris, pois queremos estimar a espécie das flores, que são versicolor, virginica e setosa;\n", + "* _Linear_ para problemas de regressão. \n", + " * Exemplo: Dataframe: Boston Housing Prediction, pois queremos estimar o preço das casas em Boston, que é uma variável contínua.\n", + "\n", + "\n", + "O artigo [Comparison of Activation Functions for Deep Neural Networks](https://towardsdatascience.com/comparison-of-activation-functions-for-deep-neural-networks-706ac4284c8a) compara e discute as principais funções de ativação de forma pormenorizada." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "clQq59rPIkvB" + }, + "source": [ + "___\n", + "# **EXEMPLO 1: Rede Neural para identificar o sexo a partir de peso e altura**\n", + "\n", + "> O dataframe a seguir contem 10.000 medidas de altura (_height_) e peso (_weight_), sendo 5.000 medidas para o sexo masculino (_males_) e 5.000 para o sexo feminino (_females_).\n", + "\n", + "**Objetivo**: Estimar gênero (sexo) (_Gender_, em inglês) em função das variáveis _Height_ e _Weight_.\n", + "\n", + "Fonte do dataframe: Kaggle (weight-height.csv).\n", + "\n", + "Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dh5p2GcvLQQX" + }, + "source": [ + "### 0. Carregar as principais bibliotecas" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bhjAdXgab99r" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kChuTlPddNZv" + }, + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from tensorflow import keras\n", + "import pandas as pd" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9ZX00UN5cjvM" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "THWNIk_FCe_g" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PZgQAKqLcLX3" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tzKor02BCe_d" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M5V4KopjLWOL" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V_cwAUW3tseE" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_Bs87IWPtwtm" + }, + "source": [ + "# Leitura do dataframe:\n", + "df_sexo = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/weight-height.csv')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mBUeMtV7tzw6" + }, + "source": [ + "[**Python**] - Mostrar as primeiras 5 linhas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rcH-y4amt3gs" + }, + "source": [ + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OSa161sPLcAw" + }, + "source": [ + "### Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lL2-6wpCuARF" + }, + "source": [ + "[**Python**] - Construir coluna 'sexo' da seguinte forma:\n", + "* Se Gender= 'Male' ==> sexo= 1;\n", + "* Se Gender= 'Female' ==> sexo= 0." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ccImSqCqDKre" + }, + "source": [ + "def define_label(row):\n", + " if row['Gender'] == 'Male':\n", + " return 1\n", + " else:\n", + " return 0" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NDYamauZCq77" + }, + "source": [ + "df_sexo['sexo'] = df_sexo.apply(lambda row: define_label(row), axis = 1)\n", + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hqkOrJnNuZjg" + }, + "source": [ + "[**Python**] - Renomear ou reescrever os nomes das colunas do dataframe em letras minúsculas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-dahUMI6DsBz" + }, + "source": [ + "df_sexo = df_sexo.drop(columns= 'Gender', axis= 1)\n", + "df_sexo = df_sexo.rename({'Height': 'altura', 'Weight': 'peso'}, axis= 1)\n", + "df_sexo.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UTISVuZ4ukQO" + }, + "source": [ + "[**Python**] - Definir os arrays X_sexo e y_sexo:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oMTIn6Zf5LlU" + }, + "source": [ + "X_sexo = df_sexo.copy()\n", + "X_sexo = X_sexo.drop(columns= ['sexo'])\n", + "y_sexo = df_sexo['sexo'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "iSThKwhj4LsC" + }, + "source": [ + "y_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FiO_F95jc1_s" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "4myPAnSzE7-l" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "\n", + "X_sexo= SS.fit_transform(X_sexo)\n", + "X_sexo" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jJaJWuUqJCha" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LoO2iEimu4SQ" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hTCdm-F9JBGA" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste= train_test_split(X_sexo, y_sexo, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "th9CsQpB8VDK" + }, + "source": [ + "print(f'Y: Treinamento = {y_treinamento.shape}; Y: Teste = {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2bL-vXiULupD" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zxETX6dTfyU5" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "F_MdsLicfyU6" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = 2\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H = 64\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.swish\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O = tf.keras.activations.swish" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SUMmDuPCcYyB" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "T-echOBmceVy" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7ZceRRdinEM2" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nXQsSYq2DBfI" + }, + "source": [ + "* 1 camada _dropout_ com $p= 0.1$:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TRFR5Kr_nDtD" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "#RN.add(Dense(N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "#RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4JBZf4ypGO8o" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (_Male_ ou _Female_). Portanto, temos:\n", + "* optimizer= tf.keras.optimizers.Adam();\n", + "* loss= tf.keras.losses.MeanSquaredError() ou loss= tf.keras.losses.BinaryCrossentropy(). Particularmente, eu gosto de usar loss= tf.keras.losses.MeanSquaredError() porque o resultado é mais intuitivo;\n", + "* metrics= tf.keras.metrics.binary_accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "USmAuw6f00wL" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h7KEi1_e6SSF" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Loss_Function = tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer = Algoritmo_Opt, loss = Loss_Function, metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Hc90EeV_GojX" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XCCTtUh_vEFP" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EB91J6nrF0db" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 5, min_delta = 0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs = 100, validation_data = (X_teste, y_teste), callbacks = callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "71mX1iwvHMc5" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o-zJ6GIjHbY8" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J1sL_DTrKmpq" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste. A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VckQfEFPvMa7" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rUhEiqxfKmpv" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "agO4cGTqKmpz" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aLIAXu7SN7pV" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D5zYHcGuMPZe" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Para aumentar a acurácia da Rede Neural, sugiro aumentarmos o número de neurônios na _Hidden Layer_ e/ou aumentar o número de _Hidden Layers_.\n", + "\n", + "No entanto, obtivemos uma acurácia razoável com a Rede Neural _baseline_. Portanto, deixo como exercício para os alunos o desafio de melhorar a acurácia desta Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_ISodOu-Kmp3" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_xgdL1W4vUrN" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "0qun1-vOKmp4" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I7sRwTWGKmp8" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AvywP0nZMtA-" + }, + "source": [ + "### 10. Conclusões\n", + "\n", + "Desenvolvemos uma Rede Neural capaz de identificar Sexo (_Gender_) com acurácia= 0.9120." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g5qOWxPczM1O" + }, + "source": [ + "___\n", + "# **EXEMPLO 2: Distinguir cédulas verdadeiras das falsas**\n", + "\n", + "* O exemplo a seguir foi extraído do site [OpenML](https://www.openml.org/home). Este é um problema interessante, que é o de distinguir cédulas verdadeiras de notas falsas. Os dados foram extraídos de imagens tiradas de cédulas verdadeiras e falsas. Para digitalização, foi usada uma câmera industrial normalmente usada para inspeção de impressão. As imagens finais têm 400x 400 pixels. Devido à lente do objeto e à distância do objeto investigado, foram obtidas imagens em escala de cinza com uma resolução de cerca de 660 dpi. Uma ferramenta Wavelet Transform foi usada para extrair recursos dessas imagens.\n", + "\n", + "* Este é o endereço do dataframe: https://www.openml.org/d/1462;\n", + "* Descrição das variáveis - [banknote authentication Data Set](https://archive.ics.uci.edu/ml/datasets/banknote+authentication).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nup7tuLc5kYy" + }, + "source": [ + "> A seguir, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ para classificar notas falsas e verdadeiras. Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YHi73Pbq5vvU" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZsZW7_Ev5vvY" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1U4OySJw5vvb" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lAaecKoj5vv5" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5lPEsFy45vv6" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uNvl-o5w5vvo" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VqRIBc1J5vvp" + }, + "source": [ + "np.set_printoptions(precision = 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8jo3Y9Hs5vwD" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tL7k4X--5vwE" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RTuRMwld5vwG" + }, + "source": [ + "df_cedulas= pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/Banknote-authentication-dataset.csv')\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "501b-Zv38ce7" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lBKafqZR8jFb" + }, + "source": [ + "df_cedulas.columns= df_cedulas.columns.str.lower()\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HBNIjNaT5vwM" + }, + "source": [ + "[**Python**] - Mostrar quantas classes há na variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c7mZgLDl5vwO" + }, + "source": [ + "df_cedulas['class'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MG4q-8nf2GS_" + }, + "source": [ + "[**Python**] - Redefinindo a variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IA7f1C4e1zOS" + }, + "source": [ + "def Redefinir_label(row):\n", + " if row['class']== 1:\n", + " return 0\n", + " else:\n", + " return 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2DkBD1FU1zOo" + }, + "source": [ + "df_cedulas['class']= df_cedulas.apply(lambda row: Redefinir_label(row), axis= 1)\n", + "df_cedulas.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I0j5o4Iu5vwT" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "32EZZ8eP5vwV" + }, + "source": [ + "j = sns.countplot(x=\"class\", data= df_cedulas)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dV8A71C55vwb" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Eg-4TkYSXvuo" + }, + "source": [ + "[**Python**] - Definir os arrays X_cedulas e y_cedulas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vn2yMB80Xvux" + }, + "source": [ + "X_cedulas = df_cedulas.copy()\n", + "X_cedulas = X_cedulas.drop(columns = ['class'])\n", + "y_cedulas = df_cedulas['class'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nckf3bieXvvC" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CFTlvOcRXvvE" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "\n", + "X_cedulas = SS.fit_transform(X_cedulas)\n", + "X_cedulas" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q_ouZ1it5vwz" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T6NrbTvd5vw1" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação da Rede Neural:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xw3ZZ2fR5vw1" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_cedulas, y_cedulas, test_size = 0.1, random_state = 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "trfqJbUg5vw8" + }, + "source": [ + "print(f'X: Treinamento = {X_treinamento.shape}; X: Teste = {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "duDt1c7i5vxB" + }, + "source": [ + "print(f'Y: Treinamento = {y_treinamento.shape}; Y: Teste = {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e4TKmGtr5vxM" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f6EQymRK5vxO" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JlUflDN3YkG7" + }, + "source": [ + "X_treinamento.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bRsHYQp05vxO" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I = X_treinamento.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O = 1\n", + "\n", + "# Número de neurônios na Hidden Layer 1:\n", + "N_H1 = 8\n", + "\n", + "# Número de neurônios na Hidden Layer 2:\n", + "N_H2 = 8\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H = tf.keras.activations.swish\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O = tf.keras.activations.sigmoid" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sSOj8_9n5vxU" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wFYGSoKH5vxU" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WG1isER05vxZ" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A6IPYp8l5vxa" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sCRp8O4V5vxa" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN = Sequential()\n", + "RN.add(Dense(units = N_H1, input_dim = N_I, activation = FA_H, kernel_initializer = tf.keras.initializers.GlorotUniform(1)))#, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units = N_O, activation = FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Titw0r-d5vxh" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oVQsayDq5vxi" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "u686jTkd5vxj" + }, + "source": [ + "Algoritmo_Opt = tf.keras.optimizers.Adam()\n", + "Loss_Function = tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss = Loss_Function, metrics = Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BKN3oCa65vxn" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Nesta fase, precisamos informar:\n", + "* **Epoch**: O número de épocas é um hiperparâmetro do _Gradient Descent_ que define o número de iterações para atualizar os pesos $W$ usando o dataframe de treinamento. Uma época significa que cada amostra no dataframe de treinamento atualizou os pesos $W$ 1 vez.\n", + "* **Batch**: número de amostras consideradas pela Rede Neural em cada _epoch_ antes da atualização dos pesos $W$;\n", + "\n", + "#### Exemplo\n", + "Suponha que temos um dataframe com 1.000 linhas (instâncias) e optamos por _epoch_= 1.000 e _batch_= 5. Isso significa que o dataframe será dividido em $\\frac{1000}{5}= 200$ _batches_. Desta forma, os pesos $W$ serão atualizados a cada processamento de 200 instâncias (linhas).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vLHQdKsi5vxn" + }, + "source": [ + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Q6UMutI45vxp" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2YhUEbTC5vxq" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 3, min_delta = 0.001)]\n", + "\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data = (X_teste, y_teste), callbacks = callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jFmtvTwd5vxu" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X8Lu0jh55vxz" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sKh0f7Mc5vx4" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste.\n", + "\n", + "A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p7nsNQoX5vx5" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B1OvhTbf5vx6" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z8v2aody5vx-" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0FQy0bZT5vx_" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste).\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "n8e327A_5vx_" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TiVyZ-CG5vyE" + }, + "source": [ + "y_teste" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PawhHD_35vyI" + }, + "source": [ + "### Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RcIh4qua_eEU" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 1 - Rede Neural para identificar espécies (Iris Dataframe)**\n", + "\n", + "> A seguir, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ para classificar flores (Iris). Nesta aplicação, vamos seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eXRYOpPR4XF4" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pa0ir9C_dgOO" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yNYF_qzydgOR" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ird1VzZudgOU" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lwj9CGzEdgOV" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zmN5HGLOdgOa" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VI86wuv9dgOa" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NoKZnsJpRA8o" + }, + "source": [ + "Perfeito, estamos a usar o TensorFlow 2.x." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xkLZgdkjavO-" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b7LLQyA3vgBG" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ACzNibyKAkx_" + }, + "source": [ + "df_Iris= pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/Iris.csv', index_col= 'Id')\n", + "df_Iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T3Vy41RL-lAQ" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xN7nBQWg-lAX" + }, + "source": [ + "df_Iris.columns= df_Iris.columns.str.lower()\n", + "df_Iris.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Em1wLwdzvkgh" + }, + "source": [ + "[**Python**] - Mostrar quantas classes há na variável-target:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QhuoPcRuA9Do" + }, + "source": [ + "df_Iris['species'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lvWcxUvru50G" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'Species':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HMpJiMWJu50J" + }, + "source": [ + "j = sns.countplot(x=\"species\", data= df_Iris)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a55-G14aa_wG" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Uos9OyewvyMo" + }, + "source": [ + "[**Python**] - Aplicar a transformação LabelEncoder() nos dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X0V0hWnBg0so" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "\n", + "LE = LabelEncoder()\n", + "\n", + "species_encoded= LE.fit_transform(df_Iris['species'])\n", + "df_Iris= df_Iris.drop(columns= ['species'], axis= 1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d8L-b9gZwB4L" + }, + "source": [ + "[**Python**] - Definir o array y_Iris:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zMp2_hJ1wGm3" + }, + "source": [ + "y_Iris= tf.keras.utils.to_categorical(species_encoded)\n", + "y_Iris[:5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qfFg6cWdv9El" + }, + "source": [ + "[**Python**] - Definir o array X_Iris:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7coeWhVRjiQl" + }, + "source": [ + "X_Iris= df_Iris.values\n", + "X_Iris[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cUa2sJOSbUFO" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kDOw-RHux1nS" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação da Rede Neural:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AJE_6w3KL_2O" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste= train_test_split(X_Iris, y_Iris, test_size= 0.2, random_state= 20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NKHTG5IP9nVj" + }, + "source": [ + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qe2mHJhb-PIY" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wHFI_bLXPPvl" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zRYoZ7hwgejR" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mjF1haRmgejS" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X.Treinamento.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= y_Iris.shape[1]\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 32\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tGeDaB3oo02k" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zGS15afAo02n" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iT9w2tUCo5-X" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nytcmC4BkSz1" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LnLeLMmZoUjU" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3eT-EHUecTj3" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação multi-classes (> 2 classes). Portanto, temos:\n", + "* loss= tf.keras.losses.CategoricalCrossentropy()\n", + ";\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fsq0aEtwyAAM" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NDStOKqhcRf4" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.CategoricalCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hZFu65TecabN" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Nesta fase, precisamos informar:\n", + "* **Epoch**: O número de épocas é um hiperparâmetro do _Gradient Descent_ que define o número de iterações para atualizar os pesos $W$ usando o dataframe de treinamento. Uma época significa que cada amostra no dataframe de treinamento atualizou os pesos $W$ 1 vez.\n", + "* **Batch**: número de amostras consideradas pela Rede Neural em cada _epoch_ antes da atualização dos pesos $W$;\n", + "\n", + "#### Exemplo\n", + "Suponha que temos um dataframe com 1.000 linhas (instâncias) e optamos por _epoch_= 1.000 e _batch_= 5. Isso significa que o dataframe será dividido em $\\frac{1000}{5}= 200$ _batches_. Desta forma, os pesos $W$ serão atualizados a cada processamento de 200 instâncias (linhas).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "boIs266gaZt1" + }, + "source": [ + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LpR3dXRZ-jom" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9hDxEwHjca8V" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 3, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JF7EC-g82Hho" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ea0HHBsY2NZ5" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pqVJMX3xchLF" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural\n", + "\n", + "Para avaliar a Rede Neural, simplesmente informamos as amostras de teste: X_teste e y_teste.\n", + "\n", + "A função evaluate() vai retornar uma lista contendo 2 valores: loss e accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hKbO1nT0yQM1" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cYqDY9V9chcZ" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qchEpyipcnbE" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9X2SZ5fx2_s5" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FR6ySksLhRvR" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LWnRgBbmmlA2" + }, + "source": [ + "y_teste" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wjCtiKieE_TT" + }, + "source": [ + "### Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LxMzVIGzzGHH" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1qjSoM5quog1" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 2 - Rede Neural para identificar o tipo do vinho (_Red or White_)**\n", + "\n", + "> Nesta aplicação, vamos usar o dataframe [wine quality](https://archive.ics.uci.edu/ml/datasets/wine+quality) extraído do repositório da UCI Machine Learning Repository. Nosso objetivo é prever o tipo do vinho (red ou white) baseado nas suas propriedades químicas.\n", + "\n", + "Novamente, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VuG8zbYS4jyx" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "O3XD4otFd9Ht" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I5Ok5fhid9Hv" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZBXRTgnCd9Hz" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NFrOyNUgd9Hz" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cGxW2zn6q8xY" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C36Z6vGD4jy8" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kWJXP5diof5G" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJJe4r_ITDzv" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jIjqYXlH4tyG" + }, + "source": [ + "from sklearn.datasets import load_wine\n", + "Wine= load_wine()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5iU33wKQGrFb" + }, + "source": [ + "df_Red= pd.read_table(\"http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv\", sep=';')\n", + "df_Red.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Liy2KSr6HJUX" + }, + "source": [ + "df_White= pd.read_table('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv', sep= ';')\n", + "df_White.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4TzUnuM4TMmJ" + }, + "source": [ + "[**Python**] - Mostrar o número de linhas e colunas de cada dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pHNwVRQyIwdv" + }, + "source": [ + "print(f'Dimensão de df_Red: {df_Red.shape}; Dimensão de df_White: {df_White.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tBWzMsUHJjTU" + }, + "source": [ + "[**Python**] - Construir a variável-target 'type_wine' (tipo do vinho):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B0WmX3FYJqMR" + }, + "source": [ + "df_Red['type_wine']= 0\n", + "df_White['type_wine']= 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EVUc1vbqJ0D9" + }, + "source": [ + "[**Python**] - Empilhar os dois dataframes: df_Red e df_White:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gS9SlpvaJ2Ex" + }, + "source": [ + "df_Wine= pd.concat([df_Red, df_White], ignore_index=True)\n", + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "dM19HHENKMtq" + }, + "source": [ + "df_Wine.tail()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mpoNmcqpeQxO" + }, + "source": [ + "[**Python**] - Mostrar o número de linhas e colunas do dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YJDazoMMeMet" + }, + "source": [ + "df_Wine.shape" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tNyjXmFzo7oe" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xcV_dlHsTpiP" + }, + "source": [ + "[**Python**] - Renomear o nome das colunas usando letras minúsculas:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Jau2OybudGc0" + }, + "source": [ + "df_Wine.columns = df_Wine.columns.str.strip().str.lower().str.replace(' ', '_')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EzOWiaCFdq_C" + }, + "source": [ + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F1wgkLcvete8" + }, + "source": [ + "[**Python**] - Estatísticas descritivas do dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A-EbHitYepeQ" + }, + "source": [ + "df_Wine.describe()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uRo_7tOjex3Z" + }, + "source": [ + "#### _Missing Values Handling_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wJ3K_FmCUCsk" + }, + "source": [ + "[**Python**] - Mostrar o número de _missing values_ no dataframe df_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PODgu5B6e5qQ" + }, + "source": [ + "df_Wine.info()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "szH_TGJZecXp" + }, + "source": [ + "Como podem ver, o dataframe df_Wine não contem _missing values_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "64znO089vF_2" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'type_wine':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ztQ17lhWfdAu" + }, + "source": [ + "df_Wine['type_wine'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zDRVQy5avF_4" + }, + "source": [ + "j = sns.countplot(x=\"type_wine\", data= df_Wine)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PxexO1Uyeqnj" + }, + "source": [ + "Como podem ver, temos 6.497 instâncias, das quais 4.898 (75%) instâncias são type_wine= 1 (_white_) e 1.599 (25%) instâncias são type_wine= 0 (_red_). Logo, trata-se de um dataframe desbalanceado. No entanto, não vou me preocupar com este assunto neste Notebook e deixo para os alunos como exercício verificar os efeitos das amostras desbalanceadas." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kr_HZnF0UUh3" + }, + "source": [ + "[**Python**] - Definir os arrays X_Wine e y_Wine:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HNvImi4djc-3" + }, + "source": [ + "X_Wine= df_Wine.copy()\n", + "X_Wine= X_Wine.drop(columns= ['type_wine'])\n", + "y_Wine= df_Wine['type_wine'].values" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ViMFMd_SlE3x" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OurlnbX3hzSb" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler()\n", + "\n", + "# Scale o dataframe\n", + "X_Wine = SS.fit_transform(X_Wine)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KFkJ7b4U1x3D" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MBqzBcDL2JH4" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bCQUxbbxhVTM" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Wine, y_Wine, test_size= 0.2, random_state= 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "HHmTtQ3F9A9c" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pPW0aWd4jw0o" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ea4WTsP-hCqS" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y1pVFjFThCqU" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Wine.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 7\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.leaky_relu" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "url8178EpUNO" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MU-8uWn-pUNQ" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6TLUirr6oXv1" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8HOQIkQ3beJm" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bj5uJvgaj43u" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LTs8xbKx2O3Z" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (_red_ ou _white_). Portanto, temos:\n", + "* loss= tf.keras.losses.BinaryCrossentropy();\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam().\n", + "\n", + "> **Lembre-se**: se o problema fosse de classificação de multi-classes (> 2 classes), então devemos usar loss= tf.keras.losses.CategoricalCrossentropy()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kUpBKJkl07KH" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qGZ1bKCo2L7A" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jBhkSc582ROC" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ls8FfHz0z2lX" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5mpbdiuJ2d1W" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 10, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "sALJp9FQ2WGC" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cWR2rMLg2ZlQ" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ciXdkbVr2VDG" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RS4_cV5TyamK" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hkkxiqPe2gZK" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "m8Vs47VV4RsV" + }, + "source": [ + "A Rede Neural tem acurácia= 0.9946." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RHQoDk533TRX" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vlWfMR-k7Qc1" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mCpp-MO0nXmj" + }, + "source": [ + "A seguir, outras medidas para avaliarmos a performance da Rede Neural:\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oWF-wWfTnjQh" + }, + "source": [ + "# Import the modules from sklearn.metrics\n", + "from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, cohen_kappa_score" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MHD0CvGQnm0v" + }, + "source": [ + "# Precision \n", + "precision_score(y_teste, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ERoX4BeQnosC" + }, + "source": [ + "# Recall\n", + "recall_score(y_teste, y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "l_2bS23Inq1p" + }, + "source": [ + "# F1 score\n", + "f1_score(y_teste,y_pred)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rLM1BSK2QfZm" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bGAigaBMQfZn" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H3yUb9tP2YfE" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CupPMVRo3a5q" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GePOr4EJ3mfn" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aO79VSBS3mfv" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oHlDHVp_KcLn" + }, + "source": [ + "### 10. Conclusão\n", + "\n", + "Desenvolvemos uma Rede Neural com 1 _Hidden Layer_ que atingiu acurácia de 0.998." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Xr2VzmwPFRdr" + }, + "source": [ + "___\n", + "# **EXERCÍCIO 1**: Prever a qualidade do vinho\n", + "\n", + "Neste exercício, vamos considerar a variável quality como múltiplas classes.\n", + "\n", + "Novamente, vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MYpF4TtpvXp4" + }, + "source": [ + "[**Python**] - Mostrar a distribuição da variável-target 'quality':" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WmeFj14PvXp6" + }, + "source": [ + "j = sns.countplot(x=\"quality\", data= df_Wine)\n", + "plt.show(j)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "smWNCLsMQWBI" + }, + "source": [ + "Muitas classes... Abaixo, KMeans para definirmos a quantidade de clusters." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Co4GNVexVUoP" + }, + "source": [ + "# Função adaptada de: https://www.geeksforgeeks.org/elbow-method-for-optimal-value-of-k-in-kmeans/\n", + "\n", + "from sklearn.metrics.pairwise import euclidean_distances, cosine_distances, manhattan_distances\n", + "from scipy.spatial.distance import cdist\n", + "\n", + "def Numero_Clusters_Elbow(X):\n", + " distortions = [] \n", + " inertias = [] \n", + " mapping1 = {} \n", + " mapping2 = {} \n", + " K = range(1,10) \n", + " for k in K:\n", + " #Building and fitting the model \n", + " kmeanModel = KMeans(n_clusters=k).fit(X) \n", + " kmeanModel.fit(X)\n", + " distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'),axis=1)) / X.shape[0]) \n", + " inertias.append(kmeanModel.inertia_)\n", + " mapping1[k] = sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'),axis=1)) / X.shape[0] \n", + " mapping2[k] = kmeanModel.inertia_ \n", + "\n", + " # Using the different values of Distortion\n", + " print('Cálculo da Distorção:')\n", + " for key,val in mapping1.items():\n", + " print(str(key)+' : '+str(val))\n", + "\n", + " plt.plot(K, distortions, 'bx-')\n", + " plt.xlabel('Values of K')\n", + " plt.ylabel('Distortion')\n", + " plt.title('The Elbow Method using Distortion')\n", + " plt.show() \n", + "\n", + " # Using the different values of Inertia\n", + " print('Cálculo da Inertia:')\n", + " for key,val in mapping2.items():\n", + " print(str(key)+' : '+str(val))\n", + "\n", + " plt.plot(K, inertias, 'bx-')\n", + " plt.xlabel('Values of K')\n", + " plt.ylabel('Inertia') \n", + " plt.title('The Elbow Method using Inertia')\n", + " plt.show() " + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eTA4O3yII-am" + }, + "source": [ + "X_WineQ= df_Wine.copy()\n", + "X_WineQ= X_WineQ.drop(columns= ['quality'])\n", + "X_WineQ= X_WineQ.values\n", + "#y_WineQ= df_Wine['quality2'].values\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IJDCLdsalKvS" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7D9qCW6SYKwA" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler().fit(X_WineQ)\n", + "\n", + "# Scale o dataframe\n", + "X_WineQ = SS.transform(X_WineQ)\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "naLIn_ufIZtL" + }, + "source": [ + "Numero_Clusters_Elbow(X_WineQ)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "At5KtD-DV0f6" + }, + "source": [ + "Os gráficos acima mostram que o número de _clusters_ ótimos para o dataframe df_Wine é 3. Portanto, vamos trabalhar com n_cluster= 3 daqui para frente." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-Oz9kAvh5yPk" + }, + "source": [ + "Sugiro fazermos o seguinte agrupamento:\n", + "* Se quality= 1, 2, 3 $\\Longrightarrow$ quality2= 1 (qualidade ruim);\n", + "* Se quality= 4, 5, 6, 7 $\\Longrightarrow$ quality2= 2 (qualidade média);\n", + "* Se quality= 8, 9, 10 $\\Longrightarrow$ quality2= 3 (qualidade excelente)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nZc2OQR87E9n" + }, + "source": [ + "def define_quality2(row):\n", + " if row['quality'] <= 3:\n", + " return 1\n", + " elif row['quality'] > 3 and row['quality'] <= 7:\n", + " return 2\n", + " elif row['quality'] > 7:\n", + " return 3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f8zbLsN27E9t" + }, + "source": [ + "df_Wine['quality2']=df_Wine.apply(lambda row: define_quality2(row), axis= 1)\n", + "df_Wine.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7ugFbdVm77wo" + }, + "source": [ + "df_Wine['quality2'].value_counts()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xf3RYZTwEtAD" + }, + "source": [ + "[**Python**] - Análise de Correlação:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dimuJxsPEsAt" + }, + "source": [ + "corr = df_Wine.corr()['quality2'].drop('quality2')\n", + "print(corr)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "g9KALiQsEsAx" + }, + "source": [ + "plt.figure(figsize=(12,10))\n", + "cor = df_Wine.corr()\n", + "sns.heatmap(cor, annot=True, linewidths=0, vmin=-1, cmap=\"RdBu_r\")\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "At1XAt6AU2oh" + }, + "source": [ + "[**Python**] - Aplicar a transformação LabelEncoder:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kld7QvCaH1YQ" + }, + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "\n", + "LE = LabelEncoder()\n", + "LE.fit(df_Wine['quality2'])quality_Encoded= LE.transform(df_Wine['quality2'])\n", + "\n", + "y_WineQ= tf.keras.utils.to_categorical(quality_Encoded)\n", + "y_WineQ[:5]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "7qqY5vxeGEMC" + }, + "source": [ + "X_WineQ= df_Wine.copy()\n", + "X_WineQ= X.drop(columns= 'quality2', axis= 1)\n", + "X_WineQ.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oKnfuTQFlQLB" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_VSNAOQzGEMG" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# Define o scaler \n", + "SS = StandardScaler().fit(X_WineQ)\n", + "\n", + "# Scale o dataframe\n", + "X_WineQ = SS.transform(X_WineQ)\n", + "X_WineQ" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zE5SV0ET-Zwv" + }, + "source": [ + "[**Python**] - Aplicar PCA para selecionar somente os atributos mais importantes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "I3IRWaIj-feA" + }, + "source": [ + "from sklearn.decomposition import PCA\n", + "\n", + "pca = PCA()\n", + "X_pca = pca.fit_transform(X_WineQ)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NbJ6NBcAVPO1" + }, + "source": [ + "[**Python**] - Proporção de variância explicada por cada componente principal" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kOqLh5BgVVN0" + }, + "source": [ + "pca.explained_variance_ratio_" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7j_cYnbSVGaT" + }, + "source": [ + "[**Python**] - Proporção acumulada de cada fator:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ux0lAfy2Ar6g" + }, + "source": [ + "pca.explained_variance_ratio_.cumsum()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1UzYqn7-A5He" + }, + "source": [ + "Como podemos ver acima, 8 componentes principais acumulam mais que 93% da variância. Portanto, vamos selecionar 8 componentes para treinar a Rede Neural." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RzekEmIMBqe1" + }, + "source": [ + "pca8 = PCA(n_components= 8)\n", + "X_pca8 = pca8.fit_transform(X)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DYDhJYdV-pSb" + }, + "source": [ + "A seguir, o gráfico com as componentes principais." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_zUN_3wR-nOX" + }, + "source": [ + "plt.figure(figsize=(7, 7))\n", + "plt.plot(np.cumsum(pca.explained_variance_ratio_), 'ro-')\n", + "plt.grid()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YO3Umy7sGEMJ" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "e2gXueuI2Nb4" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "giFgdIK7GEMJ" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_pca8, y_WineQ, test_size= 0.2, random_state= 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "nr4sryEr-eOy" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l2KSZ8TQGEMM" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tQyKOA8Qhgtd" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "62E0wT8hhgtd" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_pca8.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= y_WineQ.shape[1]\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 32\n", + "N_H2= 32\n", + "N_H3= 32\n", + "N_H4= 32\n", + "N_H5= 32\n", + "N_H6= 32\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wT0kLyuGpZ4C" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C3Wdq7XvpZ4F" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_6ZBeC4EnZyQ" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vjUyPpoJbg20" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ry43SCP4nbvp" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H4, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H5, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H6, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Atenção à Função de Ativação!\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zQwY5qQLGEMR" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação multi-classes (> 2 classes). Portanto, temos:\n", + "* loss= tf.keras.losses.CategoricalCrossentropy();\n", + "* optimizer= tf.keras.optimizers.Adam();\n", + "* metrics= tf.keras.metrics.binary_accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HVp9pT8n1AQC" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "el86VgZ-GEMS" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.CategoricalCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qNyxbvjsGEMV" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3ZtHza72z_q9" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tikYg2CrGEMV" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), batch_size= 12, callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "w6aoEBw92p86" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ei7XWVel2qNW" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tovtcp98GEMa" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DAC9nKCvyiKu" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZmhkMbmpGEMb" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjON99B1B9F0" + }, + "source": [ + "* Rede Neural com Accuracy= 0.9692 SEM PCA.\n", + "* Rede Neural com Accuracy= 0.9677 COM PCA." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_VzIx2_EGEMp" + }, + "source": [ + "### 8. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jpLRlBTI3gvF" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste);" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "1c1K5vGjGEMq" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5b-hDZ04GEMs" + }, + "source": [ + "y_teste[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h3mgEOcXu20F" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 3 - Rede Neural para identificar Câncer de Mama (_Breast Cancer Dataframe_)**\n", + "\n", + "Fonte: [Breast Cancer Wisconsin (Diagnostic) Data Set](https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+%28Diagnostic%29)\n", + "\n", + "Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QVZQ1meF9l_-" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cd4zQSkseKzv" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OzMsBroueKzx" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "import tensorflow as tf\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wJSbJx9rrBG3" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "alCVjy_JCWUo" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-Ra_PjiFeKz0" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "y4I2Eh2YeKz1" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1nXjn5KM94lI" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ovtqPCcWBgfI" + }, + "source": [ + "from sklearn.datasets import load_breast_cancer\n", + "\n", + "Cancer = load_breast_cancer()\n", + "X_cancer= Cancer.data\n", + "y_Cancer= Cancer.target\n", + "Col_Names= Cancer.feature_names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5qbOErH6Dkcu" + }, + "source": [ + "Col_Names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "weKuFIHqDWRX" + }, + "source": [ + "X_cancer" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kix-c9TDY_R" + }, + "source": [ + "y_Cancer[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qg_IuwHp946c" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7wnkuDnMlVe8" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uVEHT9sqG9WR" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_cancer = SS.fit_transform(X_cancer)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hNeVqHH295FA" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7Rbc3MwX2RDU" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xR6XSrbsFX-P" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_cancer, y_Cancer, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NRQ8zW1m-g6l" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "775KoeQz95O6" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fFaKVel2ilZs" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aB7xcQFWilZs" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_cancer.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 16\n", + "N_H2= 16\n", + "N_H3= 16\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.softmax" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rm1PeihTRlgz" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U3oTC94GRlg3" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J5GBW-Ucnh9T" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "my2xjCniIb4J" + }, + "source": [ + "Vamos adicionar duas camadas _Dropout_ com $p= 0.1$ para evitarmos _overfitting_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kne06wmjnTYD" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s6x7mo4dnjlE" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O))\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "04cKraWZ9mMb" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de classificação binária (maligno ou benigno). Portanto, temos:\n", + "* loss= tf.keras.losses.BinaryCrossentropy();\n", + "* metrics= tf.keras.metrics.binary_accuracy;\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OGRjWcsm1FM9" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bLIoA8FrJJCx" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.BinaryCrossentropy()\n", + "Metrics_Perf = tf.keras.metrics.binary_accuracy\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cnL12eaF9mU6" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nVsziJfk0FIv" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "apQY6cQjJb-z" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 100, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "avd2cXpO20cY" + }, + "source": [ + "Model_Accuracy(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FCd8xFxA25Lc" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3zToEvUs-pCt" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IqzKH7jsymwL" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pmjuk6OqJ7zD" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "04ZGPI6DKcnz" + }, + "source": [ + "A seguir, a matriz de confusão:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-MZyagwaKfkM" + }, + "source": [ + "Mostra_ConfusionMatrix()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KasqSFWG-pTG" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Não é necessário, pois obtivemos 0.9825 de acurácia." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GLxgJP3L-pdZ" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0iXGBnNZYb4V" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nqBFwxg5Yb4b" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4CHdWhgD-plr" + }, + "source": [ + "### 10. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T2AQ4uDShdgE" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 4 - Rede Neural para identificar Diabetes (Diabetes Dataframe)**\n", + "\n", + "> Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HOEJGtAzQfX3" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Mxa5UaIXeRgN" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ylfhuYeveRgO" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uG9B3WTkeRgR" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TZkm0YVoeRgR" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mDhEsSJ1rFpy" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KfKcNLZ3QfYJ" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rIT9N7jSQfYO" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "r9QUJZgbSWDG" + }, + "source": [ + "[**Python**] - Carregar os dados:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ofSJNoyfQfYR" + }, + "source": [ + "from sklearn.datasets import load_diabetes\n", + "\n", + "Diabetes = load_diabetes()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Fo7q0BnyShVG" + }, + "source": [ + "[**Python**] - Definir os arrays X_Diabetes e y_Diabetes:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UTnrDMPLQfYW" + }, + "source": [ + "X_Diabetes= Diabetes.data\n", + "y_Diabetes= Diabetes.target\n", + "Col_Names= Diabetes.feature_names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZjrdZUwp_l40" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "skgDY4Lu_l46" + }, + "source": [ + "X_Diabetes.columns= X_Diabetes.columns.str.lower()\n", + "X_Diabetes.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "a5NQO8b-QfYb" + }, + "source": [ + "X_Diabetes" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "adpBpNDeQfYj" + }, + "source": [ + "y_Diabetes[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YQA4fN4HQfYo" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dTnBpjwalbVG" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hS_unh4wQfYp" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_Diabetes = SS.fit_transform(X_Diabetes)\n", + "y_Diabetes= SS.fit_transform(y_Diabetes.reshape(-(1, 1))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZSviMMrISt96" + }, + "source": [ + "Y[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pWmVyMF0QfYu" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cEMSNMJu2VqI" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2WUQMh2HQfYx" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Diabetes, y_Diabetes, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Zvx80NPT-j0S" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wk_CG4H5QfY2" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V1bDqK5vi49C" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "por467-ci49D" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Diabetes.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 6\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= tf.nn.linear" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-r7VC-7lpkkC" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "43f-ZPW7pkkD" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2qv8lJmHnqi3" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Veeqccdbnks" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WMOoG_0bnsSD" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7W8VtONlQfZP" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de regressão. Portanto, temos:\n", + "* loss= tf.keras.losses.MeanSquaredError;\n", + "* metrics= 'mse';\n", + "* optimizer= tf.keras.optimizers.Adam()." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g97mJCSr1Kat" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cXJFtlcEQfZQ" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1s1S7Fn_QfZW" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PNgR4ihA0JMy" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JUaqK4j-QfZY" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 200, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3bFg6kut1jkb" + }, + "source": [ + "A seguir, funções para plotarmos os gráficos das métricas MSE, _Loss_ e _Accuracy_:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VPASVWaR1sWN" + }, + "source": [ + "def Model_Loss(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['loss'])\n", + " plt.plot(hist.history['val_loss'])\n", + " plt.title('Model Loss')\n", + " plt.ylabel('Loss')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Model_Accuracy(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['accuracy'])\n", + " plt.plot(hist.history['val_accuracy'])\n", + " plt.title('Model Accuracy')\n", + " plt.ylabel('Accuracy')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Model_MSE(hist):\n", + " print(hist.history.keys())\n", + " plt.plot(hist.history['mse'])\n", + " plt.plot(hist.history['val_mse'])\n", + " plt.title('Model MSE')\n", + " plt.ylabel('MSE')\n", + " plt.xlabel('Epochs')\n", + " plt.legend(['Training', 'Validation'], loc= 'upper right')\n", + " plt.show()\n", + "\n", + "def Mostra_ConfusionMatrix():\n", + " y_pred = RN.predict_classes(X_teste)\n", + " mc = confusion_matrix(y_teste, y_pred)\n", + " #sns.heatmap(mc,annot=True, annot_kws={\"size\": 10},fmt=\"d\")\n", + " sns.heatmap(mc/np.sum(mc), annot=True, annot_kws={\"size\": 10}, fmt='.2%', cmap='Blues')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "uWhJUP0v2_fm" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "M8IZFKGyCvqO" + }, + "source": [ + "Model_MSE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "37_0RhXLQfZc" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8mMrIS9JyriW" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cRjEkvWzQfZe" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MA6_RkjgQfZs" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "Vou deixar esta fase como exercício para o aluno." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vPJtuCzXQfZu" + }, + "source": [ + "### 9. Fazer Predições com a Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p1EptFS1Yi-D" + }, + "source": [ + "[**Python**] - Comando:\n", + "* RN.predict_classes(X_treinamento);\n", + "* RN.predict_classes(X_teste)." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbrvwgyvYi-I" + }, + "source": [ + "y_pred = RN.predict_classes(X_teste)\n", + "y_pred[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JOsTSHwoQfZ0" + }, + "source": [ + "### 10. Conclusões" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EoQ5nySZmLDP" + }, + "source": [ + "___\n", + "# **APLICAÇÃO 5 - Rede Neural para prever os preços das casas (_Boston House Price Prediction_)**\n", + "\n", + "Vamos desenvolver uma Rede Neural usando _Tensorflow_/_Keras_ e seguir os passos adiante:\n", + "\n", + "1. Carregar os dados;\n", + "2. Pré-processamento e transformação dos dados;\n", + "3. Definir as amostras de treinamento e validação;\n", + "4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_;\n", + "5. Compilar a Rede Neural;\n", + "6. Ajustar a Rede Neural;\n", + "7. Avaliar a performance da Rede Neural;\n", + "8. _Fine tuning_ da Rede Neural;\n", + "9. Fazer Predições com a Rede Neural;\n", + "10. Conclusões." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8vdRpBS8VTw_" + }, + "source": [ + "### 0. Carregar bibliotecas do Python" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "v629ZppSeY5T" + }, + "source": [ + "[**Python**] - Importar as bibliotecas necessárias:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uVXroVLTeY5U" + }, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from tensorflow import keras" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qYCcNW9qeY5W" + }, + "source": [ + "[**Python**] - Definir o número de casas decimais" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zNn-kwlGeY5X" + }, + "source": [ + "np.set_printoptions(precision= 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YnlZU1rLrJwt" + }, + "source": [ + "[**Python**] - Verificar a versão do Tensorflow\n", + "> Assegurar que está a utilizar a versão 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "445U8OKgVTxW" + }, + "source": [ + "tf.__version__" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1Ckhzf0VTxc" + }, + "source": [ + "### 1. Carregar os dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aAz0_L0e1mxX" + }, + "source": [ + "[] Carregar os dados" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SOdpdceAVTxd" + }, + "source": [ + "from sklearn.datasets import load_boston\n", + "\n", + "Boston = load_boston()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "K0P23sJs1raX" + }, + "source": [ + "[**Python**] - Definir as matrizes X_Boston e y_Boston:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rPpJOsgJ1y7J" + }, + "source": [ + "X_Boston= Boston.data\n", + "y_Boston= Boston.target\n", + "Col_Names= Boston.feature_names\n", + "Col_Names" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5XBRc6og_ySA" + }, + "source": [ + "[**Python**] - Corrigir ou renomear as colunas do dataframe:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "VPGDwXSF_ySE" + }, + "source": [ + "X_Boston.columns= X_Boston.columns.str.lower()\n", + "X_Boston.head()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fKiKT-fkVTxq" + }, + "source": [ + "y_Boston[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T9uYgjz-VTxu" + }, + "source": [ + "### 2. Pré-processamento e transformação dos dados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5rbpIU5jlgv6" + }, + "source": [ + "[**Python**] - Normalizar os dados - StandardScaler()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Kbs-x9a2VTxw" + }, + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "SS = StandardScaler()\n", + "X_Boston= SS.fit_transform(X_Boston)\n", + "y_Boston= SS.fit_transform(y_Boston.reshape(-(1, 1))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "S2w2H9BOXK9u" + }, + "source": [ + "X_Boston" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "DXNIHeS2XM_k" + }, + "source": [ + "y_Boston[:10]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gcbomDeKVTx1" + }, + "source": [ + "### 3. Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gEkX579Q2D2q" + }, + "source": [ + "[**Python**] - Definir as amostras de treinamento e validação" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EZyRBsfYVTx2" + }, + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_Boston, y_Boston, test_size = 0.1, random_state = 20111974)\n", + "print(f'X: Treinamento= {X_treinamento.shape}; X: Teste= {X_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "g89c6edL-mBW" + }, + "source": [ + "print(f'Y: Treinamento= {y_treinamento.shape}; Y: Teste= {y_teste.shape}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GU-ebO-3VTx7" + }, + "source": [ + "### 4. Definir a arquitetura da Rede Neural com _Tensorflow_/_Keras_" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gMVzohGHjS_p" + }, + "source": [ + "[**Python**] - Definir a arquitetura, ou seja:\n", + "* $N_{I}$: Número de neurônios na camada de entrada (_Input Layer_);\n", + "* $N_{O}$: Número de neurônios na camada de saída (_Output Layer_);\n", + "* $N_{H}$: Número de neurônios na camada escondida (_Hidden Layer_);\n", + "* FA: Função de ativação;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lf32pQtWjS_u" + }, + "source": [ + "# Número de Neurônios na Input Layer:\n", + "N_I= X_Boston.shape[1]\n", + "\n", + "# Número de neurônios na Output Layer:\n", + "N_O= 1\n", + "\n", + "# Número de neurônios na Hidden Layer:\n", + "N_H1= 7\n", + "\n", + "# Função de Ativação da Hidden Layer:\n", + "FA_H= tf.nn.leaky_relu\n", + "\n", + "# Função de Ativação da Output Layer:\n", + "FA_O= FA_O" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qOI4_BPYVTyE" + }, + "source": [ + "Vamos adicionar uma camada _Dropout_ com $p= 0.1$ para evitarmos _overfitting_." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yN9lxrXspp-m" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cWcQ3OS5pp-n" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "73PnOLbon3Jh" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zjKR3qgEneJr" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "GnZuQZZTn4_W" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h-hyQiokVTyM" + }, + "source": [ + "### 5. Compilar a Rede Neural\n", + "\n", + "Este é um problema de regressão. Portanto, temos:\n", + "* loss= tf.keras.losses.MeanSquaredError ou tf.keras.losses.MeanAbsoluteError();\n", + "* metrics= 'mse'.\n", + "* optimizer= tf.keras.optimizers.Adam() ou 'rmsprop'." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JwQOPOhr1Oh0" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QY2aKnL_VTyN" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.RMSprop()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ygJi0ux5VTyT" + }, + "source": [ + "### 6. Ajustar a Rede Neural\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Vz0urLrq0NPG" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9HoQZUl8VTyU" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 200, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "R_StfUsUzbto" + }, + "source": [ + "Model_Loss(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "I1FIaMx_zzVW" + }, + "source": [ + "Model_MAE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_t3k3oqg0pXW" + }, + "source": [ + "Model_MSE(hist)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LH0llgTsVTyY" + }, + "source": [ + "### 7. Avaliar a performance da Rede Neural" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yZZPMFXvyvtG" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iZGhNF5vVTyZ" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BkosiHm6lmww" + }, + "source": [ + "Observe que a Rede Neural _baseline_ (modelo inicial) apresenta MSE= 0.0795. Ainda assim, vamos tentar reduzir a _Loss Function_ e tentar chegar à um MSE ainda menor." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HcLONQpPVTyi" + }, + "source": [ + "### 8. _Fine tuning_ da Rede Neural\n", + "\n", + "O que pode ser feito para melhorar a performance da Rede Neural?\n", + "* aumentar o número de _Hidden Layers_ e o número de neurônios em cada uma delas." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "g7Uxk3j_ndFX" + }, + "source": [ + "N_I= X_Boston.shape[1]\n", + "N_H1= 32\n", + "N_H2= 32\n", + "N_H3= 32\n", + "N_O= 1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fF3Eb_5dp2PZ" + }, + "source": [ + "[**Python**] - Definir as sementes para NumPy e Tensorflow:\n", + "> Por questões de reproducibilidade de resultados, use as sementes abaixo:\n", + "\n", + "* NumPy: 20111974;\n", + "* Tensorflow: 20111974;" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X48MWaa_p2Pb" + }, + "source": [ + "np.random.seed(20111974)\n", + "tf.random.set_seed(20111974)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mHbjgPT7nP-q" + }, + "source": [ + "[**Python**] - Definir a Rede Neural:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j8s-XRqdbuXP" + }, + "source": [ + "**Observações**: \n", + "\n", + "Para evitar problemas relacionados ao _overfitting_ e _Vanishing or Exploding Gradients in Deep Neural Nets_, os artigos abaixo sugerem as seguintes opções para inicialização dos pesos $W$:\n", + "\n", + "* [How to Reduce Overfitting Using Weight Constraints in Keras](https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-neural-networks-with-weight-constraints-in-keras/) sugere:\n", + " * kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Deep Learning Best Practices (1) — Weight Initialization](https://medium.com/usf-msds/deep-learning-best-practices-1-weight-initialization-14e5c0295b94) sugere:\n", + " * kernel_initializer= tf.keras.initializers.he_normal() para activation= 'tf.nn.relu' ou 'tf.nn.leaky_relu' e kernel_constraint= tf.keras.constraints.UnitNorm();\n", + "* [Vanishing/ Exploding Gradients in Deep Neural Nets and solving them](https://medium.com/swlh/vanishing-exploding-gradients-in-deep-neural-nets-and-solving-them-9d6070f28b29) sugere:\n", + " * kernel_initializer= tf.keras.initializers.GlorotUniform();\n", + " * kernel_initializer= tf.keras.initializers.GlorotNormal()." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3HcNOQoFnR3W" + }, + "source": [ + "from tensorflow.keras import Sequential\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Dropout\n", + "\n", + "RN= Sequential()\n", + "RN.add(Dense(units= N_H1, input_dim= N_I, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H2, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm())\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_H3, kernel_initializer= tf.keras.initializers.GlorotNormal(), activation= FA_H, kernel_constraint= tf.keras.constraints.UnitNorm()))\n", + "RN.add(Dropout(0.1))\n", + "RN.add(Dense(units= N_O, activation= FA_O)) # Se não definirmos o parâmetro activation, então por default será 'linear'.\n", + "\n", + "# Resumo da arquitetura da Rede Neural\n", + "print(RN.summary())" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JBolPrXZnZ5i" + }, + "source": [ + "#### 8.5. Compilar a Rede Neural (_Fine tuning_ da Rede Neural)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rMBCiUTC1W2H" + }, + "source": [ + "[**Python**] - Comando modelo.compile(optimizer, loss, metrics):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YlBccXXmnZ5k" + }, + "source": [ + "Algoritmo_Opt= tf.keras.optimizers.Adam()\n", + "Loss_Function= tf.keras.losses.MeanSquaredError()\n", + "Metrics_Perf = tf.keras.metrics.MeanSquaredError()\n", + "\n", + "RN.compile(optimizer= Algoritmo_Opt, loss= Loss_Function, metrics= Metrics_Perf)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SIOA5UFfnZ5p" + }, + "source": [ + "#### 8.6. Ajustar a Rede Neural (_Fine tuning_ da Rede Neural)\n", + "\n", + "Obs.: A opção callbacks abaixo implementa o conceito de _early stopping_. Esta opção vai parar o processo de treinamento da Rede Neural antes de atingirmos o númerco de _epochs_ quando o modelo pára de melhorar, medido pela métrica val_loss. O parâmetro _patience_= k significa que o processo de otimização vai parar se tivermos k _epochs_ consecutivas sem observarmos melhoria da performance da Rede Neural." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ktlrSmGQ0Qrq" + }, + "source": [ + "[**Python**] - Comando modelo.fit(X_treinamento, y_treinamento, epochs)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kM5x90ArnZ5r" + }, + "source": [ + "callbacks = [tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5, min_delta=0.001)]\n", + "hist= RN.fit(X_treinamento, y_treinamento, epochs= 500, validation_data= (X_teste, y_teste), callbacks= callbacks)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "AfxvOccmnZ5z" + }, + "source": [ + "#### 8.7. Avaliar a performance da Rede Neural (_Fine tuning_ da Rede Neural)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4XZmb9zIy1Xf" + }, + "source": [ + "[**Python**] - Comando modelo.evaluate(X_teste, y_teste)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "belFKJQSnZ51" + }, + "source": [ + "RN.evaluate(X_teste, y_teste)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7whymUw5VTyq" + }, + "source": [ + "### 10. Conclusões\n", + "\n", + "A performance da Rede Neural melhorou um pouco com a redução do MSE." + ] + } + ] +} \ No newline at end of file diff --git a/Notebooks/NB23__Tools para DataViz_hs.ipynb b/Notebooks/NB23__Tools para DataViz_hs.ipynb new file mode 100644 index 000000000..8e38d4e1b --- /dev/null +++ b/Notebooks/NB23__Tools para DataViz_hs.ipynb @@ -0,0 +1,694 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "intro_to_fairness.ipynb", + "provenance": [], + "collapsed_sections": [ + "J8daw3YOIAXH", + "xFxZOg55lWJE", + "l-K-xqksm-X3", + "TXkkHYyJ98_k", + "91wjnZFpPWw-", + "KlF-lQ8yQ69b", + "qZ-9vJgSEpHj", + "7YVH8hYfSjer", + "2lx4JuLdi7jw", + "TF3B5h3c-7Fb" + ], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "84x4Fxc5lzFv" + }, + "source": [ + "# Entendendo os dados\n", + "***" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xFxZOg55lWJE" + }, + "source": [ + "## Objetivo\n", + "\n", + "* Explorar e entender os diferentes bias presentes nos dados;\n", + "* Explorar as features e identificar potenciais Bias antes de treinar o ML;\n", + "* Avaliar a performance por subgrupos antes de agregar." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TXkkHYyJ98_k" + }, + "source": [ + "## Sobre o dataframe\n", + "\n", + "Neste exercício nós vamos trabalhar com o dataframe...\n", + "\n", + "### Features numéricas:\n", + "Numeric Features\n", + "\n", + "### Features categóricas\n", + "\n", + "### Objetivo\n", + "O objetivo é estimar a probabilidade de churn.\n", + "\n", + "### Label (variável-target)\n", + "* `churn`: indicador se o cliente deixou ou não a empresa.\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I0RMIktKy8xX" + }, + "source": [ + "## Setup: Carregar as libraries necessárias para a análise\n", + "* Precisamos usar o Tensorflow 2.x." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XJoEoDDPIZpi" + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns\n", + "from matplotlib import pyplot as plt\n", + "from matplotlib import rcParams" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MelAK2u6d-xx", + "outputId": "21e39c12-3b80-4450-c750-30b8782b1475", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "import tensorflow as tf\n", + "from tensorflow import keras\n", + "\n", + "tf.__version__" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'2.3.0'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jUsgiVsUeKRR" + }, + "source": [ + "A seguir, vamos usar uma ferramenta opensource chamada [Facets](https://pair-code.github.io/facets/), criada pela [PAIR](https://research.google/teams/brain/pair/). Facets possui 2 importantes ferramentas para entendermos os dados e, consequentemente, nos ajudar com o Machine Learning." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wgqSegn9JQ3X" + }, + "source": [ + "### Ajustar a granularidade do report" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2e_0DJJ8zE29", + "outputId": "aa8f6b7a-bd42-45cf-e426-176a2b86541b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "pd.options.display.max_rows = 10\n", + "pd.options.display.float_format = \"{:.1f}\".format\n", + "\n", + "from google.colab import widgets\n", + "\n", + "# Facets\n", + "from IPython.core.display import display, HTML\n", + "import base64\n", + "\n", + "!pip install facets-overview==1.0.0\n", + "from facets_overview.feature_statistics_generator import FeatureStatisticsGenerator" + ], + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Collecting facets-overview==1.0.0\n", + " Downloading https://files.pythonhosted.org/packages/df/8a/0042de5450dbd9e7e0773de93fe84c999b5b078b1f60b4c19ac76b5dd889/facets_overview-1.0.0-py2.py3-none-any.whl\n", + "Requirement already satisfied: numpy>=1.16.0 in /usr/local/lib/python3.6/dist-packages (from facets-overview==1.0.0) (1.18.5)\n", + "Requirement already satisfied: pandas>=0.22.0 in /usr/local/lib/python3.6/dist-packages (from facets-overview==1.0.0) (1.1.4)\n", + "Requirement already satisfied: protobuf>=3.7.0 in /usr/local/lib/python3.6/dist-packages (from facets-overview==1.0.0) (3.12.4)\n", + "Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->facets-overview==1.0.0) (2018.9)\n", + "Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->facets-overview==1.0.0) (2.8.1)\n", + "Requirement already satisfied: six>=1.9 in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.7.0->facets-overview==1.0.0) (1.15.0)\n", + "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.7.0->facets-overview==1.0.0) (50.3.2)\n", + "Installing collected packages: facets-overview\n", + "Successfully installed facets-overview-1.0.0\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-xgIRapb5LaQ" + }, + "source": [ + "### Carregar os dados\n", + "* Vamos carregar os dados do Kaggle/LabData." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "3uu5rmeXJ0J8" + }, + "source": [ + "url_treinamento = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/adult.data'\n", + "url_teste = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/adult.test'" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "bxWbuxspWPa0" + }, + "source": [ + "nomes_colunas = [\"Age\", \"Workclass\", \"fnlwgt\", \"Education\", \"Education-Num\", \"Marital Status\",\n", + " \"Occupation\", \"Relationship\", \"Race\", \"Sex\", \"Capital Gain\", \"Capital Loss\",\n", + " \"Hours per week\", \"Country\", \"Target\"]" + ], + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kHova3CrMA35" + }, + "source": [ + "df_50T = pd.read_csv(url_treinamento, na_values=\" ?\", names = nomes_colunas)\n", + "df_50V = pd.read_csv(url_teste, na_values=\" ?\", names = nomes_colunas)" + ], + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "p2wEBPSSMSNQ", + "outputId": "8a051abe-a832-4e1b-9dd7-e9eec3fdf873", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_50T.head()" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "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", + "
AgeWorkclassfnlwgtEducationEducation-NumMarital StatusOccupationRelationshipRaceSexCapital GainCapital LossHours per weekCountryTarget
039State-gov77516Bachelors13Never-marriedAdm-clericalNot-in-familyWhiteMale2174040United-States<=50K
150Self-emp-not-inc83311Bachelors13Married-civ-spouseExec-managerialHusbandWhiteMale0013United-States<=50K
238Private215646HS-grad9DivorcedHandlers-cleanersNot-in-familyWhiteMale0040United-States<=50K
353Private23472111th7Married-civ-spouseHandlers-cleanersHusbandBlackMale0040United-States<=50K
428Private338409Bachelors13Married-civ-spouseProf-specialtyWifeBlackFemale0040Cuba<=50K
\n", + "
" + ], + "text/plain": [ + " Age Workclass fnlwgt ... Hours per week Country Target\n", + "0 39 State-gov 77516 ... 40 United-States <=50K\n", + "1 50 Self-emp-not-inc 83311 ... 13 United-States <=50K\n", + "2 38 Private 215646 ... 40 United-States <=50K\n", + "3 53 Private 234721 ... 40 United-States <=50K\n", + "4 28 Private 338409 ... 40 Cuba <=50K\n", + "\n", + "[5 rows x 15 columns]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a2ZNB8CRPhxb", + "outputId": "95edbe44-af8d-4d62-e6d2-6f78dbc100e0", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_50T.shape" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(32561, 15)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yaZt9NIenavk", + "outputId": "4f30dae8-e611-4322-9c20-f505857103f1", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "list(df_50T.dtypes)" + ], + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[dtype('int64'),\n", + " dtype('O'),\n", + " dtype('int64'),\n", + " dtype('O'),\n", + " dtype('int64'),\n", + " dtype('O'),\n", + " dtype('O'),\n", + " dtype('O'),\n", + " dtype('O'),\n", + " dtype('O'),\n", + " dtype('int64'),\n", + " dtype('int64'),\n", + " dtype('int64'),\n", + " dtype('O'),\n", + " dtype('O')]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "OvIqZeNnnibH", + "outputId": "cffb8655-1913-411e-f719-0b879022df12", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "df_50T.isna().sum()" + ], + "execution_count": 15, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Age 0\n", + "Workclass 1836\n", + "fnlwgt 0\n", + "Education 0\n", + "Education-Num 0\n", + " ... \n", + "Capital Gain 0\n", + "Capital Loss 0\n", + "Hours per week 0\n", + "Country 583\n", + "Target 0\n", + "Length: 15, dtype: int64" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "coilRN-hooja" + }, + "source": [ + "## Analisando os dados com Facets\n", + "* Como dito anteriormente, é muito importante entendermos os dados (80% do tempo) antes da fase de modelagem.\n", + "\n", + "Responda as perguntas a seguir:\n", + "\n", + "* Existem missing values?\n", + "* Há alguma variável com valor inesperado?\n", + "* Há sinais de distorção (Skewness) nos dados?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9yCIuAqWA1Pm" + }, + "source": [ + "A seguir, um pequeno overview do [Facets Overview](https://pair-code.github.io/facets/), uma ferramenta iterativa para Data Visualization para nos ajudar a explorar os dados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MW-qryqs1gig", + "outputId": "8d4ce332-ca7b-4400-e260-fc77d090be8e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + } + }, + "source": [ + "fsg = FeatureStatisticsGenerator()\n", + "dataframes = [\n", + " {'table': df_50T, 'name': 'trainData'}]\n", + "\n", + "censusProto = fsg.ProtoFromDataFrames(dataframes)\n", + "protostr = base64.b64encode(censusProto.SerializeToString()).decode(\"utf-8\")\n", + "\n", + "HTML_TEMPLATE = \"\"\"\n", + " \n", + " \n", + " \"\"\"\n", + "html = HTML_TEMPLATE.format(protostr=protostr)\n", + "display(HTML(html))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KlF-lQ8yQ69b" + }, + "source": [ + "### Ações\n", + "* O que fazer com os missing values?\n", + " * Podemos ignorar os missing values?\n", + "* O que fazer com os outliers?\n", + "* O que fazer com as variáveis que possuem distribuições muito diferentes da Normalidade?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hKj2hz-Sql7V" + }, + "source": [ + "## A Deeper Dive\n", + "\n", + "Depois das primeiras impressões acerca dos dados, é hora de darmos um mergulho mais profundo (Deeper Dive). Vamos usar a segunda ferramenta chamada [Facets Dive](https://pair-code.github.io/facets/), uma ferramenta iterativa para DataVuz que nos ajudará a entender ainda mais nossos dados." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "stlklrG_xssF", + "outputId": "a593f36f-850b-4ade-f820-38c80cf649eb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 617 + } + }, + "source": [ + "#@title Número de pontos para visualização no facets\n", + "\n", + "SAMPLE_SIZE = df_50T.shape[0] #@param\n", + "train_dive = df_50T.sample(SAMPLE_SIZE).to_json(orient = 'records')\n", + "\n", + "HTML_TEMPLATE = \"\"\"\n", + " \n", + " \n", + " \"\"\"\n", + "html = HTML_TEMPLATE.format(jsonstr = train_dive)\n", + "display(HTML(html))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LxqAPDcRDFB2" + }, + "source": [ + "## Exercícios\n", + "\n", + "1. No menu **Binning | X-Axis** selecione **education**, e no menu **Color By**, selecione 'target' e no menu **Label By** selecione **income_bracket**.\n", + "\n", + "* Como você descreveria o relacionamento entre estas variáveis?" + ] + } + ] +} \ No newline at end of file