From 30f1a4318dd4c882cf0197ba258b00dff9968e83 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Tue, 6 Oct 2020 17:29:22 -0300 Subject: [PATCH 1/9] Criado usando o Colaboratory --- ...247\303\265es maria aula 06-10-2020.ipynb" | 5789 +++++++++++++++++ 1 file changed, 5789 insertions(+) create mode 100644 "Notebooks/NB02__Numpy - altera\303\247\303\265es maria aula 06-10-2020.ipynb" diff --git "a/Notebooks/NB02__Numpy - altera\303\247\303\265es maria aula 06-10-2020.ipynb" "b/Notebooks/NB02__Numpy - altera\303\247\303\265es maria aula 06-10-2020.ipynb" new file mode 100644 index 000000000..5fe378ba1 --- /dev/null +++ "b/Notebooks/NB02__Numpy - altera\303\247\303\265es maria aula 06-10-2020.ipynb" @@ -0,0 +1,5789 @@ +{ + "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 # NM incluiu um comentário nesta linha!" + ], + "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)" + ] + }, + { + "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 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_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": "2a3d2b33-579c-406d-d662-da4458f164e6", + "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": 5, + "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": 5 + } + ] + }, + { + "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": "9cc09094-5420-4078-a387-e22a58c13f7a", + "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, 999, 10)\n", + "\n", + "# Estas são as posições que serão alteradas\n", + "np.sort(l_indices)" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 14, 105, 208, 349, 484, 567, 615, 616, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "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": "85b67195-c61a-4f05-ea8f-fc5b05d8973b", + "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": 7, + "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": 7 + } + ] + }, + { + "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": 8, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NpvvholVxMhs", + "outputId": "2dbfff71-3249-4fd8-fd48-c9e1356dde34", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Índices a serem alterados\n", + "l_indices" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([567, 14, 616, 484, 208, 105, 349, 615, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BqXsmMdm1yF-" + }, + "source": [ + "#### Solução 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FiiOrlnbgKOD", + "outputId": "82a3c137-568d-4776-d952-11d00b1e40e7", + "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": 10, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000094\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgvKC-aFzWpZ" + }, + "source": [ + "#### Solução 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XWlQC5Jazt26", + "outputId": "8640d081-99ae-4235-e2de-620d6152193b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "start = timer()\n", + "a_salarios_copia2[l_indices] = 2*a_salarios_copia2[l_indices]\n", + "a_salarios_copia2[:30]\n", + "end = timer()\n", + "print(timedelta(seconds=end-start))" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000090\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U92w03afhrmC" + }, + "source": [ + "### Compare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ls-jCFCYhtD8", + "outputId": "04b7eff2-67d0-4f8f-8812-0b4be9bb7cb7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Antes\n", + "a_salarios[l_indices]" + ], + "execution_count": 12, + "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": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nwwU06OahzD2", + "outputId": "e18448a4-97f4-452c-da95-3d1db69b1033", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Depois\n", + "a_salarios_copia[l_indices]" + ], + "execution_count": 13, + "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": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qyUUdHmtisJS", + "outputId": "779e41e6-cb77-4966-b5d5-fe4d5b4f2ab2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras elementos de a_salarios\n", + "a_salarios[:30]" + ], + "execution_count": 14, + "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": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CJ1FEjlCi0-n", + "outputId": "5c6c8845-8f83-4047-9f4f-3034d2ec2af7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras posições de a_salarios_copia\n", + "a_salarios_copia[:30]" + ], + "execution_count": 15, + "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": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbSUgxxiOUL" + }, + "source": [ + "### Algumas Estatísticas descritivas:\n", + "#### Antes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZnmykyahLWX9", + "outputId": "b2c70db1-2870-48e7-c031-94f122415bc8", + "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": 16, + "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": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "80H92CIjibYJ" + }, + "source": [ + "#### Depois" + ], + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5iO-BAikieHJ", + "outputId": "ea72b3f5-5682-4971-e1f5-26aec68bc43c", + "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": 18, + "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": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILhNe80xW5C6" + }, + "source": [ + "### Solução do desafio" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U993i1GJg2hk", + "outputId": "bf91af51-aac7-4008-8cc3-342573752205", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 271 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "sns.boxplot(y = a_salarios_copia)" + ], + "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": "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_salarios_copia[i] < lim_inferior então a_salarios_copia[i]= Mediana\n", + " * Se a_salarios_copia[i] > lim_superior 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": "11daf3fe-c4c9-446e-cb46-cf6378c02779", + "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": 20, + "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": 20 + } + ] + }, + { + "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", + "IQR = Q3-Q1\n", + "lim_inferior = Q1-1.5*IQR\n", + "lim_superior = Q3+1.5*IQR" + ], + "execution_count": 21, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VF2NJ3rCeI1_", + "outputId": "e8e38919-ee69-4d21-db00-1abb7bd4fb9b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Q1: {Q1}; Q3: {Q3}; lim_inferior: {lim_inferior}; lim_superior: {lim_superior}'" + ], + "execution_count": 22, + "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": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjnwJ7HwMxcl" + }, + "source": [ + "3. Substituir\n", + "* Se a_conjunto1[i] < lim_inferior então a_conjunto1[i] = Mediana\n", + "* Se a_conjunto1[i] > Lia_Sup então a_conjunto1[i] = Mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcAn-IwVfbcI" + }, + "source": [ + "a_salarios2 = a_salarios_copia.copy()" + ], + "execution_count": 23, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3SSE45oM9oh", + "outputId": "53db1a1d-8483-40f9-8cbc-196b79e449ff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_salarios2[a_salarios2 < lim_inferior[0]] = Q2[0]\n", + "#para todos que atendam essa condição ele vai receber o valor da mediana\n", + "a_salarios2[a_salarios2 > lim_superior[0]] = Q2[0]\n", + "a_salarios2[:30]" + ], + "execution_count": 24, + "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": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VEGFio0Nfj7O" + }, + "source": [ + "4. Estatísticas Descritivas para avaliarmos o impacto:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gX1LZHFqfjFQ", + "outputId": "31a986a8-79bd-4c04-daf2-3fa1e8ca9f44", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_salarios2)}; Mediana: {np.median(a_salarios2)}; STD: {np.std(a_salarios2)}'" + ], + "execution_count": 25, + "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": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-xnguZ7XgyvK", + "outputId": "98be8554-e55a-4d5b-e418-4712377c627e", + "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": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAADrCAYAAACFMUa7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAO5klEQVR4nO3df6zddX3H8eer90YEzQa0d40WGCxt5tC4xTVIsriw8asQsxo3DWRJ7xxZY4Klwz82jMmaYEg0Lhpo1KQJDW3iYGSbsW5dsbBl/IVSFgJFUU5QpA3K9RZxWRW57Xt/3C/x7nJv7z333PZc/Dwfycn5nvf3c77nfQj3dT/9fL/nnlQVkqQ2rBp2A5KkM8fQl6SGGPqS1BBDX5IaYuhLUkMMfUlqyOiwGziVNWvW1MUXXzzsNiTpDeWxxx77cVWNzbVvRYf+xRdfzKFDh4bdhiS9oSR5br59Lu9IUkMMfUlqiKEvSQ0x9CWpIYa+tASTk5PccsstTE5ODrsVqS+GvrQEe/bs4cknn2Tv3r3DbkXqi6Ev9WlycpIDBw5QVRw4cMDZvt5QDH2pT3v27OHkyZMAnDhxwtm+3lAMfalPDz74IFNTUwBMTU1x8ODBIXckLZ6hL/XpqquuYnR0+sPso6OjXH311UPuSFo8Q1/q0/j4OKtWTf/ojIyMsGXLliF3JC3eiv7bO1pZdu7cSa/XG3YbK0ISAN761rdy++23D7mb4Vu/fj3btm0bdhtaBGf60hKsWrWKVatWsXbt2mG3IvXFmb4WzZncL23fvh2AO++8c8idSP1xpi9JDVkw9JPsTvJiksMzap9K8kSSx5N8Pcnbu3qS3JWk1+1/z4znjCd5pruNn563I0k6lcXM9O8BNs2qfbaq3l1Vvwf8K/B3Xf06YEN32wp8CSDJ+cAO4L3AZcCOJOcN3L0kqS8Lhn5VPQwcm1X76YyHbwGq294M7K1pjwDnJnkbcC1wsKqOVdVLwEFe/4tEknSaLflEbpI7gC3Ay8AfdeV1wPMzhh3pavPVJUln0JJP5FbVJ6vqQuDLwMeWq6EkW5McSnJoYmJiuQ4rSWJ5rt75MvCn3fZR4MIZ+y7oavPVX6eqdlXVxqraODY255e5S5KWaEmhn2TDjIebgae77X3Alu4qnsuBl6vqBeAB4Jok53UncK/papKkM2jBNf0k9wJXAGuSHGH6Kpzrk/w2cBJ4DvhoN3w/cD3QA44DHwGoqmNJPgU82o27var+38lhSdLpt2DoV9WNc5TvnmdsATfPs283sLuv7iRJy8pP5EpSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWrIgqGfZHeSF5McnlH7bJKnkzyR5CtJzp2x7xNJekm+k+TaGfVNXa2X5LblfyuSpIUsZqZ/D7BpVu0g8K6qejfwXeATAEkuBW4A3tk954tJRpKMAF8ArgMuBW7sxkqSzqAFQ7+qHgaOzap9vaqmuoePABd025uB+6rqlar6HtADLutuvap6tqp+AdzXjZUknUHLsab/l8C/d9vrgOdn7DvS1earS5LOoIFCP8kngSngy8vTDiTZmuRQkkMTExPLdVhJEgOEfpK/AN4P/HlVVVc+Clw4Y9gFXW2++utU1a6q2lhVG8fGxpbaniRpDksK/SSbgL8B/qSqjs/YtQ+4IclZSS4BNgDfBB4FNiS5JMmbmD7Zu2+w1iVJ/RpdaECSe4ErgDVJjgA7mL5a5yzgYBKAR6rqo1X1VJL7gW8xvexzc1Wd6I7zMeABYATYXVVPnYb3I0k6hQVDv6punKN89ynG3wHcMUd9P7C/r+4kScvKT+RKUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1JDRYTew0u3cuZNerzfsNrTCvPb/xPbt24fciVaa9evXs23btmG3MS9DfwG9Xo/HD3+bE+ecP+xWtIKs+kUB8NizPxpyJ1pJRo4fG3YLCzL0F+HEOefzs3dcP+w2JK1wZz+9f9gtLGjBNf0ku5O8mOTwjNqHkjyV5GSSjbPGfyJJL8l3klw7o76pq/WS3La8b0OStBiLOZF7D7BpVu0w8EHg4ZnFJJcCNwDv7J7zxSQjSUaALwDXAZcCN3ZjJUln0ILLO1X1cJKLZ9W+DZBk9vDNwH1V9QrwvSQ94LJuX6+qnu2ed1839luDNC9J6s9yX7K5Dnh+xuMjXW2++usk2ZrkUJJDExMTy9yeJLVtxV2nX1W7qmpjVW0cGxsbdjuS9Ctlua/eOQpcOOPxBV2NU9QlSWfIcs/09wE3JDkrySXABuCbwKPAhiSXJHkT0yd79y3za0uSFrDgTD/JvcAVwJokR4AdwDFgJzAG/FuSx6vq2qp6Ksn9TJ+gnQJurqoT3XE+BjwAjAC7q+qp0/GGJEnzW8zVOzfOs+sr84y/A7hjjvp+YOV/ckGSfoWtuBO5kqTTx9CXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BC/GH0BR48eZeT4y2+ILzyWNFwjxyc5enRq2G2ckjN9SWqIM/0FrFu3jh++MsrP3nH9sFuRtMKd/fR+1q1bO+w2TsmZviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1JAFQz/J7iQvJjk8o3Z+koNJnunuz+vqSXJXkl6SJ5K8Z8ZzxrvxzyQZPz1vR5J0KouZ6d8DbJpVuw14qKo2AA91jwGuAzZ0t63Al2D6lwSwA3gvcBmw47VfFJKkM2fB0K+qh4Fjs8qbgT3d9h7gAzPqe2vaI8C5Sd4GXAscrKpjVfUScJDX/yKRJJ1mS13TX1tVL3TbPwRe+1ui64DnZ4w70tXmq0uSzqCBT+RWVQG1DL0AkGRrkkNJDk1MTCzXYSVJLD30f9Qt29Ddv9jVjwIXzhh3QVebr/46VbWrqjZW1caxsbEltidJmstSQ38f8NoVOOPAV2fUt3RX8VwOvNwtAz0AXJPkvO4E7jVdTZJ0Bi34dYlJ7gWuANYkOcL0VTifBu5PchPwHPDhbvh+4HqgBxwHPgJQVceSfAp4tBt3e1XNPjksSTrNFgz9qrpxnl1XzjG2gJvnOc5uYHdf3UmSlpWfyJWkhhj6ktQQQ1+SGrLgmr5g5Pgxzn56/7Db0Aqy6uc/BeDkm39tyJ1oJRk5foxfflZ1ZTL0F7B+/fpht6AVqNf7HwDW/9bK/gHXmbZ2xWeGob+Abdu2DbsFrUDbt28H4M477xxyJ1J/XNOXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDBgr9JNuTHE7yVJK/7mrnJzmY5Jnu/ryuniR3JekleSLJe5bjDUiSFm/JoZ/kXcBfAZcBvwu8P8l64DbgoaraADzUPQa4DtjQ3bYCXxqgb0nSEgwy0/8d4BtVdbyqpoD/Aj4IbAb2dGP2AB/otjcDe2vaI8C5Sd42wOtLkvo0SOgfBt6XZHWSc4DrgQuBtVX1Qjfmh8Dabnsd8PyM5x/papKkM2R0qU+sqm8n+QzwdeB/gceBE7PGVJLq57hJtjK9/MNFF1201PYkSXMY6ERuVd1dVb9fVX8IvAR8F/jRa8s23f2L3fCjTP9L4DUXdLXZx9xVVRurauPY2Ngg7UmSZhn06p3f6O4vYno9/x+AfcB4N2Qc+Gq3vQ/Y0l3Fcznw8oxlIEnSGbDk5Z3OPydZDbwK3FxVP0nyaeD+JDcBzwEf7sbuZ3rdvwccBz4y4GtLkvo0UOhX1fvmqE0CV85RL+DmQV5PkjQYP5ErSQ0x9CWpIYa+JDXE0Jekhhj6ktQQQ1+SGmLoS1JDDH1JaoihL0kNMfQlqSGGviQ1xNCXpIYY+pLUEENfkhpi6EtSQwx9SWqIoS9JDTH0Jakhhr4kNcTQl6SGGPqS1BBDX5IaYuhLUkMMfUlqiKEvSQ0x9CWpIQOFfpJbkzyV5HCSe5O8OcklSb6RpJfkH5O8qRt7Vve41+2/eDnegCRp8ZYc+knWAbcAG6vqXcAIcAPwGeDzVbUeeAm4qXvKTcBLXf3z3ThJ0hk06PLOKHB2klHgHOAF4I+Bf+r27wE+0G1v7h7T7b8ySQZ8fUlSH5Yc+lV1FPh74AdMh/3LwGPAT6pqqht2BFjXba8Dnu+eO9WNXz37uEm2JjmU5NDExMRS25MkzWGQ5Z3zmJ69XwK8HXgLsGnQhqpqV1VtrKqNY2Njgx5OkjTDIMs7VwHfq6qJqnoV+BfgD4Bzu+UegAuAo932UeBCgG7/rwOTA7y+JKlPg4T+D4DLk5zTrc1fCXwL+E/gz7ox48BXu+193WO6/f9RVTXA60uS+jTImv43mD4h+9/Ak92xdgF/C3w8SY/pNfu7u6fcDazu6h8Hbhugb0nSEowuPGR+VbUD2DGr/Cxw2Rxjfw58aJDXkyQNxk/kSlJDDH1JashAyztqy86dO+n1esNuY0V47b/D9u3bh9zJyrB+/Xq2bds27Da0CM70pSU466yzeOWVV3j11VeH3YrUF2f6WjRncr/0uc99jq997Wts2LCBW2+9ddjtSIvmTF/q0+TkJAcOHKCqOHDgAJOTfsZQbxyGvtSnPXv2cPLkSQBOnDjB3r17h9yRtHiGvtSnBx98kKmp6b8pODU1xcGDB4fckbR4hr7Up6uuuorR0enTYaOjo1x99dVD7khaPENf6tP4+DirVk3/6IyMjLBly5YhdyQtnqEv9Wn16tVs2rSJJGzatInVq1/3tRDSiuUlm9ISjI+P8/3vf99Zvt5wDH1pCVavXs1dd9017Dakvrm8I0kNMfQlqSGGviQ1xNCXpIZkJX9NbZIJ4Llh9yHNYw3w42E3Ic3hN6tqbK4dKzr0pZUsyaGq2jjsPqR+uLwjSQ0x9CWpIYa+tHS7ht2A1C/X9CWpIc70Jakhhr4kNcTQl6SGGPqS1BBDX5Ia8n+y6aH62hucLAAAAABJRU5ErkJggg==\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" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randint(0, 100, 100)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dm9ky1F1mrNA" + }, + "source": [ + "Quem são os valores únicos do array?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-LPRqc-mS5j" + }, + "source": [ + "np.unique(a_conjunto1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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-" + }, + "source": [ + "np.setdiff1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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" + }, + "source": [ + "np.setxor1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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-" + }, + "source": [ + "a_conjunto1 = np.arange(10)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pZTHhHxGSRfB" + }, + "source": [ + "a_conjunto2 = np.arange(8, 18)\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MxB2_qHpScMB" + }, + "source": [ + "Quais são os elementos comuns à X e Y?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e-rncJHtSfw0" + }, + "source": [ + "np.intersect1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": [ + "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": 27, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ZkbMPXMawYh", + "outputId": "af5865c5-95fe-4df1-8712-b77543e860c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, nan, 0.65, 0.86, 0.6 , 0.87, 0.46, nan, 0.64, 0.55,\n", + " 0.35, 0.32, nan, 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27,\n", + " 0.31, 0.36, 0.6 , 0.02, 0.36, nan, 0.28, 0.37, nan, 0.44, 0.2 ,\n", + " 0.21, 0.65, 0.82, 0.72, 0.5 , 0.17, 0.6 , nan, 0.14, nan, 0.71,\n", + " 0.07, 0.56, nan, 0.84, 0.21, 0.85, 0.63, 0.38, 0.91, 0.34, 0.07,\n", + " 0.1 , 0.85, 0.12, 0.94, 0.16, nan, 0.91, 0.59, 0.37, 0.72, 0.07,\n", + " 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98, 0.85, 0.63,\n", + " 0.57, 0.67, 0.88, nan, nan, nan, 0.68, 0.29, 0.33, 0.98, 0.17,\n", + " nan, 0.92, 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, nan, 0.49, 0.07,\n", + " 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "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": "9dc32bc4-bb41-4c02-bc64-c98461f3cefd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan(a_conjunto1).sum()\n", + "## isnan retorna um valor boleano se é nulo ou não" + ], + "execution_count": 29, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "81IoQ-EVbI5X", + "outputId": "fcddc325-8c6c-4545-cf1c-349af38ca954", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan\n", + "## é uma função" + ], + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PB-GAJ71bc7i", + "outputId": "0a9a431e-986d-40da-c841-544d25727b38", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + "array_nulos = np.isnan(a_conjunto1)\n", + "array_nulos" + ], + "execution_count": 32, + "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": 32 + } + ] + }, + { + "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": "57d4bf56-64bd-4969-9281-d311ac926119", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_indices= np.where(np.isnan(a_conjunto1))\n", + "## o where retorna a posiçao do array que é true\n", + "i_indices" + ], + "execution_count": 30, + "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": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W_jHGNImok7L", + "outputId": "cbdcf2d2-3edf-4b8a-9a42-29aa20cbcd94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Checando... que a posição 2 é nan\n", + "a_conjunto1[2]" + ], + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "nan" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "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": "eb361064-326a-451c-c4fe-0d14b861fbe8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 34, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, nan, 0.65, 0.86, 0.6 , 0.87, 0.46, nan, 0.64, 0.55,\n", + " 0.35, 0.32, nan, 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27,\n", + " 0.31, 0.36, 0.6 , 0.02, 0.36, nan, 0.28, 0.37, nan, 0.44, 0.2 ,\n", + " 0.21, 0.65, 0.82, 0.72, 0.5 , 0.17, 0.6 , nan, 0.14, nan, 0.71,\n", + " 0.07, 0.56, nan, 0.84, 0.21, 0.85, 0.63, 0.38, 0.91, 0.34, 0.07,\n", + " 0.1 , 0.85, 0.12, 0.94, 0.16, nan, 0.91, 0.59, 0.37, 0.72, 0.07,\n", + " 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98, 0.85, 0.63,\n", + " 0.57, 0.67, 0.88, nan, nan, nan, 0.68, 0.29, 0.33, 0.98, 0.17,\n", + " nan, 0.92, 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, nan, 0.49, 0.07,\n", + " 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e497B492fFru", + "outputId": "68f697f4-4778-43e9-9b4f-87d930eccc46", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "a_conjunto1[~np.isnan(a_conjunto1)]\n", + "## o til nega a condição e retorna tudo que é falso\n", + "## colo o np.isnan gera o arrau com true e false, se eu falo que quero a negação e peço as posições com o falso\n", + "## eu estou retirando os nan" + ], + "execution_count": 36, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, 0.65, 0.86, 0.6 , 0.87, 0.46, 0.64, 0.55, 0.35, 0.32,\n", + " 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27, 0.31, 0.36, 0.6 ,\n", + " 0.02, 0.36, 0.28, 0.37, 0.44, 0.2 , 0.21, 0.65, 0.82, 0.72, 0.5 ,\n", + " 0.17, 0.6 , 0.14, 0.71, 0.07, 0.56, 0.84, 0.21, 0.85, 0.63, 0.38,\n", + " 0.91, 0.34, 0.07, 0.1 , 0.85, 0.12, 0.94, 0.16, 0.91, 0.59, 0.37,\n", + " 0.72, 0.07, 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98,\n", + " 0.85, 0.63, 0.57, 0.67, 0.88, 0.68, 0.29, 0.33, 0.98, 0.17, 0.92,\n", + " 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, 0.49, 0.07, 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpvKfJU_fmA6" + }, + "source": [ + "Observe que os NaN's foram excluidos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7ereghZPcdh4" + }, + "source": [ + "EXERCÍCIO - ATRIBUIR A MEDIANA AOS VALORES DA AMOSTRA\n" + ] + }, + { + "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": "001bc55c-fe58-40ab-ff3c-3ea90d4e71d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_Lista = [np.random.randint(0, 10, 10)]\n", + "l_Lista" + ], + "execution_count": 37, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[array([8, 9, 3, 7, 1, 3, 2, 9, 7, 7])]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xytj4Eo4hTh9", + "outputId": "4c2d1778-13ec-4717-a3a8-d538cfcf896a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(l_Lista)" + ], + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "list" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qrINdcruhWcH" + }, + "source": [ + "Convertendo a minha lista para array:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RoSyaX0OhZSE", + "outputId": "8b194262-97d5-45ee-9336-3a5c0a5ad802", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto = np.asarray(l_Lista)\n", + "a_conjunto" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 9, 3, 7, 1, 3, 2, 9, 7, 7]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMjTdbBUhlrk", + "outputId": "4d140e4f-2e4c-4aa7-8e99-481cb4d1cdc3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(a_conjunto)" + ], + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "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": "0405171f-5590-434a-87be-39d44e18ce17", + "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": 41, + "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": 41 + } + ] + }, + { + "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": "01f739af-34ea-448c-992f-ee587482c359", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_itens_unicos, i_count = np.unique(a_conjunto1, return_counts=True)\n", + "## é uma função que retorna os itens unicos e a quantidade que aparecem\n", + "l_itens_unicos" + ], + "execution_count": 42, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyvrIwS9yZIR" + }, + "source": [ + "O que significa o output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uO-MPMhXyV9H", + "outputId": "4f477738-6362-4177-a6ec-dd559dc9dc71", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_count" + ], + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 10, 10, 11, 8, 8, 8, 10, 10, 15])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zwoezXrPyofK" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgYycSG7yr5e", + "outputId": "02fe1140-2976-4715-e211-20d27baf3c87", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "np.asarray((l_itens_unicos, i_count))" + ], + "execution_count": 44, + "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": 44 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SwIZiJAiy06T" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wy_tqAPgdchD" + }, + "source": [ + "é a frequencia com que cada um aparece" + ] + }, + { + "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", + "outputId": "ad54cd80-fa6e-4772-a869-1b7f98b09725", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": 45, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kq1zt-uO1HXv" + }, + "source": [ + "### **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFmK_n2M1Ks9", + "outputId": "496556f7-9ff2-40f7-8cbf-2a1588793e40", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0]" + ], + "execution_count": 46, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 4, 6, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "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", + "outputId": "aebcdfd3-b244-4cb2-f33b-a8083d241d17", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": 47, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "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", + "outputId": "575c869f-1a28-49db-9516-47c84cecacc2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0] = np.median(a_conjunto1)\n", + "a_conjunto1" + ], + "execution_count": 48, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4, 1, 4, 3, 4, 5, 4, 7, 4, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2c_AphX82qp8" + }, + "source": [ + "Verificando..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kVta0Cr13Z9", + "outputId": "cb8af387-8353-49f1-cf9e-37ee7c77b607", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'A média de a_conjunto1 é: {np.median(a_conjunto1)}'" + ], + "execution_count": 49, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A média de a_conjunto1 é: 4.0'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "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": "34954fdf-6e28-477c-ac93-03b510461a21", + "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": 50, + "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": 50 + } + ] + }, + { + "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": "r5hJ-wMwjXPR", + "outputId": "2eadc741-755c-46d2-bd8c-ad0d3cc8ad8e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_conjunto1.reshape(-1,3)" + ], + "execution_count": 51, + "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": 51 + } + ] + }, + { + "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" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jYrgc3KvtmLy" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file From b7eb0e404bb8b4b6ed419eb273f7e9410c25dc13 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 7 Oct 2020 14:42:36 -0300 Subject: [PATCH 2/9] Criado usando o Colaboratory --- Notebooks/NB02__Numpy_alterado.ipynb | 5789 ++++++++++++++++++++++++++ 1 file changed, 5789 insertions(+) create mode 100644 Notebooks/NB02__Numpy_alterado.ipynb diff --git a/Notebooks/NB02__Numpy_alterado.ipynb b/Notebooks/NB02__Numpy_alterado.ipynb new file mode 100644 index 000000000..4ea92acae --- /dev/null +++ b/Notebooks/NB02__Numpy_alterado.ipynb @@ -0,0 +1,5789 @@ +{ + "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 # NM incluiu um comentário nesta linha!" + ], + "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)" + ] + }, + { + "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 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_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": "2a3d2b33-579c-406d-d662-da4458f164e6", + "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": 5, + "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": 5 + } + ] + }, + { + "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": "9cc09094-5420-4078-a387-e22a58c13f7a", + "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, 999, 10)\n", + "\n", + "# Estas são as posições que serão alteradas\n", + "np.sort(l_indices)" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 14, 105, 208, 349, 484, 567, 615, 616, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "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": "85b67195-c61a-4f05-ea8f-fc5b05d8973b", + "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": 7, + "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": 7 + } + ] + }, + { + "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": 8, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "NpvvholVxMhs", + "outputId": "2dbfff71-3249-4fd8-fd48-c9e1356dde34", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Índices a serem alterados\n", + "l_indices" + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([567, 14, 616, 484, 208, 105, 349, 615, 622, 847])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 9 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BqXsmMdm1yF-" + }, + "source": [ + "#### Solução 1" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FiiOrlnbgKOD", + "outputId": "82a3c137-568d-4776-d952-11d00b1e40e7", + "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": 10, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000094\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FgvKC-aFzWpZ" + }, + "source": [ + "#### Solução 2" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XWlQC5Jazt26", + "outputId": "8640d081-99ae-4235-e2de-620d6152193b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "start = timer()\n", + "a_salarios_copia2[l_indices] = 2*a_salarios_copia2[l_indices]\n", + "a_salarios_copia2[:30]\n", + "end = timer()\n", + "print(timedelta(seconds=end-start))" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "text": [ + "0:00:00.000090\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U92w03afhrmC" + }, + "source": [ + "### Compare" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ls-jCFCYhtD8", + "outputId": "04b7eff2-67d0-4f8f-8812-0b4be9bb7cb7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Antes\n", + "a_salarios[l_indices]" + ], + "execution_count": 12, + "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": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nwwU06OahzD2", + "outputId": "e18448a4-97f4-452c-da95-3d1db69b1033", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Depois\n", + "a_salarios_copia[l_indices]" + ], + "execution_count": 13, + "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": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "qyUUdHmtisJS", + "outputId": "779e41e6-cb77-4966-b5d5-fe4d5b4f2ab2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras elementos de a_salarios\n", + "a_salarios[:30]" + ], + "execution_count": 14, + "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": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CJ1FEjlCi0-n", + "outputId": "5c6c8845-8f83-4047-9f4f-3034d2ec2af7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "# 30 primeiras posições de a_salarios_copia\n", + "a_salarios_copia[:30]" + ], + "execution_count": 15, + "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": 15 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wKbSUgxxiOUL" + }, + "source": [ + "### Algumas Estatísticas descritivas:\n", + "#### Antes" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZnmykyahLWX9", + "outputId": "b2c70db1-2870-48e7-c031-94f122415bc8", + "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": 16, + "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": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "80H92CIjibYJ" + }, + "source": [ + "#### Depois" + ], + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5iO-BAikieHJ", + "outputId": "ea72b3f5-5682-4971-e1f5-26aec68bc43c", + "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": 18, + "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": 18 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ILhNe80xW5C6" + }, + "source": [ + "### Solução do desafio" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "U993i1GJg2hk", + "outputId": "bf91af51-aac7-4008-8cc3-342573752205", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 271 + } + }, + "source": [ + "# Import a biblioteca seaborn:\n", + "import seaborn as sns\n", + "sns.boxplot(y = a_salarios_copia)" + ], + "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": "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_salarios_copia[i] < lim_inferior então a_salarios_copia[i]= Mediana\n", + " * Se a_salarios_copia[i] > lim_superior 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": "11daf3fe-c4c9-446e-cb46-cf6378c02779", + "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": 20, + "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": 20 + } + ] + }, + { + "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", + "IQR = Q3-Q1\n", + "lim_inferior = Q1-1.5*IQR\n", + "lim_superior = Q3+1.5*IQR" + ], + "execution_count": 21, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VF2NJ3rCeI1_", + "outputId": "e8e38919-ee69-4d21-db00-1abb7bd4fb9b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'Q1: {Q1}; Q3: {Q3}; lim_inferior: {lim_inferior}; lim_superior: {lim_superior}'" + ], + "execution_count": 22, + "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": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JjnwJ7HwMxcl" + }, + "source": [ + "3. Substituir\n", + "* Se a_conjunto1[i] < lim_inferior então a_conjunto1[i] = Mediana\n", + "* Se a_conjunto1[i] > Lia_Sup então a_conjunto1[i] = Mediana" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hcAn-IwVfbcI" + }, + "source": [ + "a_salarios2 = a_salarios_copia.copy()" + ], + "execution_count": 23, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "J3SSE45oM9oh", + "outputId": "53db1a1d-8483-40f9-8cbc-196b79e449ff", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_salarios2[a_salarios2 < lim_inferior[0]] = Q2[0]\n", + "#para todos que atendam essa condição ele vai receber o valor da mediana\n", + "a_salarios2[a_salarios2 > lim_superior[0]] = Q2[0]\n", + "a_salarios2[:30]" + ], + "execution_count": 24, + "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": 24 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VEGFio0Nfj7O" + }, + "source": [ + "4. Estatísticas Descritivas para avaliarmos o impacto:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gX1LZHFqfjFQ", + "outputId": "31a986a8-79bd-4c04-daf2-3fa1e8ca9f44", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "# Algumas estatísticas descritivas:\n", + "f'Média: {np.mean(a_salarios2)}; Mediana: {np.median(a_salarios2)}; STD: {np.std(a_salarios2)}'" + ], + "execution_count": 25, + "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": 25 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-xnguZ7XgyvK", + "outputId": "98be8554-e55a-4d5b-e418-4712377c627e", + "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": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + }, + { + "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" + }, + "source": [ + "np.random.seed(20111974)\n", + "a_conjunto1 = np.random.randint(0, 100, 100)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Dm9ky1F1mrNA" + }, + "source": [ + "Quem são os valores únicos do array?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "G-LPRqc-mS5j" + }, + "source": [ + "np.unique(a_conjunto1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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-" + }, + "source": [ + "np.setdiff1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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" + }, + "source": [ + "np.setxor1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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-" + }, + "source": [ + "a_conjunto1 = np.arange(10)\n", + "a_conjunto1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pZTHhHxGSRfB" + }, + "source": [ + "a_conjunto2 = np.arange(8, 18)\n", + "a_conjunto2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MxB2_qHpScMB" + }, + "source": [ + "Quais são os elementos comuns à X e Y?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e-rncJHtSfw0" + }, + "source": [ + "np.intersect1d(a_conjunto1, a_conjunto2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": [ + "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": 27, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2ZkbMPXMawYh", + "outputId": "af5865c5-95fe-4df1-8712-b77543e860c5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, nan, 0.65, 0.86, 0.6 , 0.87, 0.46, nan, 0.64, 0.55,\n", + " 0.35, 0.32, nan, 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27,\n", + " 0.31, 0.36, 0.6 , 0.02, 0.36, nan, 0.28, 0.37, nan, 0.44, 0.2 ,\n", + " 0.21, 0.65, 0.82, 0.72, 0.5 , 0.17, 0.6 , nan, 0.14, nan, 0.71,\n", + " 0.07, 0.56, nan, 0.84, 0.21, 0.85, 0.63, 0.38, 0.91, 0.34, 0.07,\n", + " 0.1 , 0.85, 0.12, 0.94, 0.16, nan, 0.91, 0.59, 0.37, 0.72, 0.07,\n", + " 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98, 0.85, 0.63,\n", + " 0.57, 0.67, 0.88, nan, nan, nan, 0.68, 0.29, 0.33, 0.98, 0.17,\n", + " nan, 0.92, 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, nan, 0.49, 0.07,\n", + " 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 28 + } + ] + }, + { + "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": "9dc32bc4-bb41-4c02-bc64-c98461f3cefd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan(a_conjunto1).sum()\n", + "## isnan retorna um valor boleano se é nulo ou não" + ], + "execution_count": 29, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "14" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 29 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "81IoQ-EVbI5X", + "outputId": "fcddc325-8c6c-4545-cf1c-349af38ca954", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "np.isnan\n", + "## é uma função" + ], + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PB-GAJ71bc7i", + "outputId": "0a9a431e-986d-40da-c841-544d25727b38", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + } + }, + "source": [ + "array_nulos = np.isnan(a_conjunto1)\n", + "array_nulos" + ], + "execution_count": 32, + "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": 32 + } + ] + }, + { + "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": "57d4bf56-64bd-4969-9281-d311ac926119", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_indices= np.where(np.isnan(a_conjunto1))\n", + "## o where retorna a posiçao do array que é true\n", + "i_indices" + ], + "execution_count": 30, + "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": 30 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W_jHGNImok7L", + "outputId": "cbdcf2d2-3edf-4b8a-9a42-29aa20cbcd94", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Checando... que a posição 2 é nan\n", + "a_conjunto1[2]" + ], + "execution_count": 33, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "nan" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 33 + } + ] + }, + { + "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": "eb361064-326a-451c-c4fe-0d14b861fbe8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + } + }, + "source": [ + "a_conjunto1" + ], + "execution_count": 34, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, nan, 0.65, 0.86, 0.6 , 0.87, 0.46, nan, 0.64, 0.55,\n", + " 0.35, 0.32, nan, 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27,\n", + " 0.31, 0.36, 0.6 , 0.02, 0.36, nan, 0.28, 0.37, nan, 0.44, 0.2 ,\n", + " 0.21, 0.65, 0.82, 0.72, 0.5 , 0.17, 0.6 , nan, 0.14, nan, 0.71,\n", + " 0.07, 0.56, nan, 0.84, 0.21, 0.85, 0.63, 0.38, 0.91, 0.34, 0.07,\n", + " 0.1 , 0.85, 0.12, 0.94, 0.16, nan, 0.91, 0.59, 0.37, 0.72, 0.07,\n", + " 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98, 0.85, 0.63,\n", + " 0.57, 0.67, 0.88, nan, nan, nan, 0.68, 0.29, 0.33, 0.98, 0.17,\n", + " nan, 0.92, 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, nan, 0.49, 0.07,\n", + " 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e497B492fFru", + "outputId": "68f697f4-4778-43e9-9b4f-87d930eccc46", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153 + } + }, + "source": [ + "a_conjunto1[~np.isnan(a_conjunto1)]\n", + "## o til nega a condição e retorna tudo que é falso\n", + "## colo o np.isnan gera o arrau com true e false, se eu falo que quero a negação e peço as posições com o falso\n", + "## eu estou retirando os nan" + ], + "execution_count": 36, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0.53, 0.57, 0.65, 0.86, 0.6 , 0.87, 0.46, 0.64, 0.55, 0.35, 0.32,\n", + " 0.85, 0.76, 0.66, 0.33, 0.35, 0.42, 0.31, 0.27, 0.31, 0.36, 0.6 ,\n", + " 0.02, 0.36, 0.28, 0.37, 0.44, 0.2 , 0.21, 0.65, 0.82, 0.72, 0.5 ,\n", + " 0.17, 0.6 , 0.14, 0.71, 0.07, 0.56, 0.84, 0.21, 0.85, 0.63, 0.38,\n", + " 0.91, 0.34, 0.07, 0.1 , 0.85, 0.12, 0.94, 0.16, 0.91, 0.59, 0.37,\n", + " 0.72, 0.07, 0.48, 0.78, 0.97, 0.72, 0.29, 0.33, 0.95, 0.24, 0.98,\n", + " 0.85, 0.63, 0.57, 0.67, 0.88, 0.68, 0.29, 0.33, 0.98, 0.17, 0.92,\n", + " 0.98, 0.76, 0.31, 0.97, 0.08, 0.56, 0.49, 0.07, 0.11])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 36 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RpvKfJU_fmA6" + }, + "source": [ + "Observe que os NaN's foram excluidos." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7ereghZPcdh4" + }, + "source": [ + "EXERCÍCIO - ATRIBUIR A MEDIANA AOS VALORES DA AMOSTRA\n" + ] + }, + { + "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": "001bc55c-fe58-40ab-ff3c-3ea90d4e71d7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_Lista = [np.random.randint(0, 10, 10)]\n", + "l_Lista" + ], + "execution_count": 37, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[array([8, 9, 3, 7, 1, 3, 2, 9, 7, 7])]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xytj4Eo4hTh9", + "outputId": "4c2d1778-13ec-4717-a3a8-d538cfcf896a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(l_Lista)" + ], + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "list" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qrINdcruhWcH" + }, + "source": [ + "Convertendo a minha lista para array:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RoSyaX0OhZSE", + "outputId": "8b194262-97d5-45ee-9336-3a5c0a5ad802", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto = np.asarray(l_Lista)\n", + "a_conjunto" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[8, 9, 3, 7, 1, 3, 2, 9, 7, 7]])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dMjTdbBUhlrk", + "outputId": "4d140e4f-2e4c-4aa7-8e99-481cb4d1cdc3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "type(a_conjunto)" + ], + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 40 + } + ] + }, + { + "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": "0405171f-5590-434a-87be-39d44e18ce17", + "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": 41, + "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": 41 + } + ] + }, + { + "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": "01f739af-34ea-448c-992f-ee587482c359", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "l_itens_unicos, i_count = np.unique(a_conjunto1, return_counts=True)\n", + "## é uma função que retorna os itens unicos e a quantidade que aparecem\n", + "l_itens_unicos" + ], + "execution_count": 42, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 42 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DyvrIwS9yZIR" + }, + "source": [ + "O que significa o output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uO-MPMhXyV9H", + "outputId": "4f477738-6362-4177-a6ec-dd559dc9dc71", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "i_count" + ], + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([10, 10, 10, 11, 8, 8, 8, 10, 10, 15])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 43 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zwoezXrPyofK" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HgYycSG7yr5e", + "outputId": "02fe1140-2976-4715-e211-20d27baf3c87", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "np.asarray((l_itens_unicos, i_count))" + ], + "execution_count": 44, + "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": 44 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SwIZiJAiy06T" + }, + "source": [ + "Qual a interpretação do output acima?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wy_tqAPgdchD" + }, + "source": [ + "é a frequencia com que cada um aparece" + ] + }, + { + "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", + "outputId": "ad54cd80-fa6e-4772-a869-1b7f98b09725", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": 45, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kq1zt-uO1HXv" + }, + "source": [ + "### **Minha solução**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YFmK_n2M1Ks9", + "outputId": "496556f7-9ff2-40f7-8cbf-2a1588793e40", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0]" + ], + "execution_count": 46, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 2, 4, 6, 8])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 46 + } + ] + }, + { + "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", + "outputId": "aebcdfd3-b244-4cb2-f33b-a8083d241d17", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "a_conjunto1" + ], + "execution_count": 47, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 47 + } + ] + }, + { + "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", + "outputId": "575c869f-1a28-49db-9516-47c84cecacc2", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "a_conjunto1[a_conjunto1 % 2 == 0] = np.median(a_conjunto1)\n", + "a_conjunto1" + ], + "execution_count": 48, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([4, 1, 4, 3, 4, 5, 4, 7, 4, 9])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2c_AphX82qp8" + }, + "source": [ + "Verificando..." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9kVta0Cr13Z9", + "outputId": "cb8af387-8353-49f1-cf9e-37ee7c77b607", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "f'A média de a_conjunto1 é: {np.median(a_conjunto1)}'" + ], + "execution_count": 49, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A média de a_conjunto1 é: 4.0'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "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": "34954fdf-6e28-477c-ac93-03b510461a21", + "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": 50, + "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": 50 + } + ] + }, + { + "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": "r5hJ-wMwjXPR", + "outputId": "2eadc741-755c-46d2-bd8c-ad0d3cc8ad8e", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + } + }, + "source": [ + "a_conjunto1.reshape(-1,3)" + ], + "execution_count": 51, + "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": 51 + } + ] + }, + { + "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" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "jYrgc3KvtmLy" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file From a568ce97c04618fae60156c588d5f3bea7a057a1 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 7 Oct 2020 15:45:59 -0300 Subject: [PATCH 3/9] Criado usando o Colaboratory --- Notebooks/NB07__Dictionaries_alterado.ipynb | 2270 +++++++++++++++++++ 1 file changed, 2270 insertions(+) create mode 100644 Notebooks/NB07__Dictionaries_alterado.ipynb diff --git a/Notebooks/NB07__Dictionaries_alterado.ipynb b/Notebooks/NB07__Dictionaries_alterado.ipynb new file mode 100644 index 000000000..aeea3db03 --- /dev/null +++ b/Notebooks/NB07__Dictionaries_alterado.ipynb @@ -0,0 +1,2270 @@ +{ + "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" + }, + "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']" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jJyxuMQc9Ewy" + }, + "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]" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "a8badcb1-7f11-4b2e-8629-48a36cc95f9d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "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": 36 + } + ] + }, + { + "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": "54ca32b8-7dda-4907-8aa5-b327444bd458", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 134 + } + }, + "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": 1 + } + ] + }, + { + "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": "87fabef2-0891-4994-a4ce-cdd1e23218b1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_dia_semana['Seg']" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Segunda'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 2 + } + ] + }, + { + "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": "7925813c-77e2-4651-bdb2-f0e1144aecdb", + "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": 4 + } + ] + }, + { + "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": "7fab37f5-8ed1-46d8-b47b-62a100ee2196", + "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": 5 + } + ] + }, + { + "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": "bacf6377-b5cc-4f29-f6c0-347516550f37", + "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": 6 + } + ] + }, + { + "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": "94f7e900-0452-4908-c0fe-2783a735bd01", + "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": 7 + } + ] + }, + { + "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": "7863cccb-b0aa-47b2-901b-ba72a5574d4f", + "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": 8 + } + ] + }, + { + "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": "f02c2c47-e5aa-43cd-886b-345c52ed31bd", + "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": 9 + } + ] + }, + { + "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": "ALwbHwi4iwky", + "outputId": "bb0d57fb-2742-4eb1-9d82-9309142d21f5", + "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": 10 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FIvi0Li1Hng5" + }, + "source": [ + "___\n", + "# **OBTER VALORES DO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "cp0PPtl3jEKo", + "outputId": "c7b8739a-caa9-4e58-e6d3-0f86ccd2d950", + "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": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JUblZBMjHrwl" + }, + "source": [ + "___\n", + "# **OBTER ITENS (key, value) DO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LraTwXjdjG3m", + "outputId": "b3d6d55e-20ad-4f88-a783-9ba1c4fd8654", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 162 + } + }, + "source": [ + "d_paises.items()" + ], + "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[0md_Paises\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\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 'd_Paises' is not defined" + ] + } + ] + }, + { + "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": "678ab629-6cff-4fe1-e03f-d90709a98f26", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_paises.get(1)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Italy'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tyJ0KsloIBoD" + }, + "source": [ + "___\n", + "# **COPIAR DICIONÁRIO**\n", + "* d_dicionario.copy()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XL17EmvMkkky", + "outputId": "65846bc2-87a2-42cf-eb17-e3fccb00c9a4", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "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": 28 + } + ] + }, + { + "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": "a2c2a25b-40ef-4842-f2f7-3ac85404d195", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "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": "5af38cf4-aaf8-4efa-f682-502bfb5022a6", + "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": 8 + } + ] + }, + { + "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": "cee4be2d-7980-4a3d-85fb-17561d1bb1ff", + "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": 21 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JBMf8SbAJmiq" + }, + "source": [ + "## Iterar pelas keys do dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rMro_tY8kepo", + "outputId": "4488c243-6792-4efa-b271-e546270b129d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for key in d_frutas.keys():\n", + " print(key)" + ], + "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": "yDkOLvRFJxco" + }, + "source": [ + "## Iterar pelos itens (key, value) do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DpFB1g-3kDSt", + "outputId": "7ac51581-edfa-418d-a1e0-d297ebdffca7", + "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": "8z6qO74fJ6Q1" + }, + "source": [ + "## Iterar pelos valores do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "tjJ6qRF8nr4v", + "outputId": "3e75843b-2d45-4b4c-a3f2-24ffc0e60a7a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, + "source": [ + "for value in d_frutas.values():\n", + " print(value)" + ], + "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": "-LmEUroVKDUA" + }, + "source": [ + "## Iterar pela key e valor do dicionário" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "oRhZ_Zq9oQIg", + "outputId": "be168183-30b4-4f96-ae2c-3f313acbc558", + "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": "3540aadd-996a-4abd-cfcb-c22e49b75aaa", + "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": 75 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fMzBeFMIusv7" + }, + "source": [ + "A fruta 'Coconut' pertence ao dicionário d_frutas?" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SKtEwmBCuxyi", + "outputId": "1df7263c-a64f-4eaf-8d4d-a55cac03d2bc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "'Coconut' in fruits.keys()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 77 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rrH8ArqsK6Bd" + }, + "source": [ + "___\n", + "# **VERIFICAR SE VALOR PERTENCE AO DICIONÁRIO**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DbWpbuLTK9sn", + "outputId": "e9fafa6d-284e-4862-8f25-9419ff702dec", + "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": 14 + } + ] + }, + { + "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" + }, + "source": [ + "d_frutas2 = {'Grapefruit': 1.0 }" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "2b185546-255e-4ad0-e8c9-10564fcbe2b0", + "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": 79 + } + ] + }, + { + "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" + }, + "source": [ + "d_frutas.update(d_frutas3)\n", + "d_frutas" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "ZziGmKGmwqwn" + }, + "source": [ + "for key, value in d_frutas.items():\n", + " d_frutas[key] = round(value * 0.9, 2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "b910699c-9729-4a27-bd78-3a283c82ac39", + "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": 86 + } + ] + }, + { + "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.4." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EwqxWiVlyvgH" + }, + "source": [ + "d_frutas_filtro = {}\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": [ + "Mostra o resultado do dicionário d_frutas_Selected:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SsStWM5k1s-Q", + "outputId": "f6af5b61-2333-41c7-a28a-0f6a67b0a949", + "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": 89 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u1ve6xIGOjrE" + }, + "source": [ + " Como se pode ver, somente a fruta 'Blackberry' satifaz esta 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": "8221b07b-610d-4a7c-cb14-86d6f63e5be3", + "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.450000000000001" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 22 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "a5MBNCF-C5-4" + }, + "source": [ + "Quantos itens existem no dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "AkvygR0PC9bT", + "outputId": "254eff41-8336-4fe6-d6ad-4d52544d74a9", + "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": "b9cea719-637e-40a5-9e79-eb67aeb47887", + "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.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": 12 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T4Li1Q2d-pnZ" + }, + "source": [ + "Ordem reversa (por key):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PoBOmfpM_A_a", + "outputId": "4cd9a21c-a2ad-462c-acb0-26ba7a0a4e5d", + "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.45),\n", + " ('Strawberry', 0.5),\n", + " ('Raspberry', 0.4),\n", + " ('Plum', 0.6),\n", + " ('Pineapple', 0.55),\n", + " ('Peach', 0.55),\n", + " ('Passion Fruit', 0.45),\n", + " ('Papaya', 0.3),\n", + " ('Orange', 0.25),\n", + " ('Nectarine', 0.75),\n", + " ('Mango', 0.8),\n", + " ('Lemon', 0.15),\n", + " ('Kiwi', 0.2),\n", + " ('Grape', 0.65),\n", + " ('Fig', 0.6),\n", + " ('Coconut', 0.75),\n", + " ('Cherry', 0.5),\n", + " ('Blueberry', 0.45),\n", + " ('Blackcurrant', 0.7),\n", + " ('Blackberry', 0.55),\n", + " ('Banana', 0.3),\n", + " ('Avocado', 0.35),\n", + " ('Apricot', 0.25),\n", + " ('Apple', 0.4)]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "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": "16a779ef-48c9-497c-8c7c-a1612aa9aa03", + "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": 2 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qtTKvNeJNycl" + }, + "source": [ + "### Filtrando por key:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uIDW5FhwAiSs", + "outputId": "52599d3f-ff13-4894-f697-ce7290bff9d5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "d_frutas2 = {k: v for k, v 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": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nUMGIzxeNt_U" + }, + "source": [ + "### Filtrando por valor:" + ] + }, + { + "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": "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" + }, + "source": [ + "d_colaboradores= {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TNiJSG_uiePb" + }, + "source": [ + "Como acessar o Gerente 'A'?" + ] + }, + { + "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." + ] + } + ] +} \ No newline at end of file From 27328b97f577baf578c03c9f20f6c635ab609551 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 7 Oct 2020 16:52:23 -0300 Subject: [PATCH 4/9] Criado usando o Colaboratory --- Notebooks/NB07__Dictionaries_alterado.ipynb | 692 ++++++++++++++------ 1 file changed, 494 insertions(+), 198 deletions(-) diff --git a/Notebooks/NB07__Dictionaries_alterado.ipynb b/Notebooks/NB07__Dictionaries_alterado.ipynb index aeea3db03..96c177534 100644 --- a/Notebooks/NB07__Dictionaries_alterado.ipynb +++ b/Notebooks/NB07__Dictionaries_alterado.ipynb @@ -109,15 +109,28 @@ { "cell_type": "code", "metadata": { - "id": "FxuJ7Awd8f5a" + "id": "FxuJ7Awd8f5a", + "outputId": "2b09e013-655c-492e-8902-c0706b3f7b4d", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "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']" + " 'Orange', 'Papaya','Passion Fruit','Peach','Pineapple','Plum','Raspberry','Strawberry','Watermelon']\n", + "print(l_frutas)" ], - "execution_count": null, - "outputs": [] + "execution_count": 2, + "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", @@ -128,7 +141,7 @@ "# 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]" ], - "execution_count": null, + "execution_count": 3, "outputs": [] }, { @@ -144,17 +157,16 @@ "cell_type": "code", "metadata": { "id": "qT_4sYxA9dyn", - "outputId": "a8badcb1-7f11-4b2e-8629-48a36cc95f9d", + "outputId": "e8276718-3d1c-4dc2-c4ee-0ac975b7ff18", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas = dict(zip(l_frutas, l_precos_frutas))\n", "d_frutas" ], - "execution_count": null, + "execution_count": 4, "outputs": [ { "output_type": "execute_result", @@ -189,7 +201,7 @@ "metadata": { "tags": [] }, - "execution_count": 36 + "execution_count": 4 } ] }, @@ -251,17 +263,16 @@ "cell_type": "code", "metadata": { "id": "N_2J839X4lps", - "outputId": "54ca32b8-7dda-4907-8aa5-b327444bd458", + "outputId": "56ab2a1f-4c41-4335-9697-38bce1eb51f6", "colab": { - "base_uri": "https://localhost:8080/", - "height": 134 + "base_uri": "https://localhost:8080/" } }, "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, + "execution_count": 5, "outputs": [ { "output_type": "execute_result", @@ -279,7 +290,7 @@ "metadata": { "tags": [] }, - "execution_count": 1 + "execution_count": 5 } ] }, @@ -297,20 +308,23 @@ "cell_type": "code", "metadata": { "id": "eHuvY7BWQKhQ", - "outputId": "87fabef2-0891-4994-a4ce-cdd1e23218b1", + "outputId": "649df9a0-587f-4e6c-a19a-4654e919bd93", "colab": { "base_uri": "https://localhost:8080/", - "height": 34 + "height": 35 } }, "source": [ "d_dia_semana['Seg']" ], - "execution_count": null, + "execution_count": 6, "outputs": [ { "output_type": "execute_result", "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, "text/plain": [ "'Segunda'" ] @@ -318,7 +332,7 @@ "metadata": { "tags": [] }, - "execution_count": 2 + "execution_count": 6 } ] }, @@ -345,17 +359,16 @@ "cell_type": "code", "metadata": { "id": "2iPWXPBLfOlr", - "outputId": "7925813c-77e2-4651-bdb2-f0e1144aecdb", + "outputId": "550e6ef2-9a6a-41b1-8b36-95c3e2e5efbe", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "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, + "execution_count": 7, "outputs": [ { "output_type": "execute_result", @@ -367,7 +380,7 @@ "metadata": { "tags": [] }, - "execution_count": 4 + "execution_count": 7 } ] }, @@ -386,16 +399,15 @@ "cell_type": "code", "metadata": { "id": "voPYpGIGff3o", - "outputId": "7fab37f5-8ed1-46d8-b47b-62a100ee2196", + "outputId": "d0748385-60a7-4b87-b7e2-794fbb8e9abe", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "type(d_paises)" ], - "execution_count": null, + "execution_count": 8, "outputs": [ { "output_type": "execute_result", @@ -407,7 +419,7 @@ "metadata": { "tags": [] }, - "execution_count": 5 + "execution_count": 8 } ] }, @@ -434,29 +446,28 @@ "cell_type": "code", "metadata": { "id": "EXZ7eEZofnza", - "outputId": "bacf6377-b5cc-4f29-f6c0-347516550f37", + "outputId": "fcbde537-da11-4573-ed38-bd4d48a96f60", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises[1] = 'Italy'\n", "d_paises" ], - "execution_count": null, + "execution_count": 12, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "{1: 'Italy'}" + "{1: 'Italy', 2: 'Denmark', 3: 'Brazil'}" ] }, "metadata": { "tags": [] }, - "execution_count": 6 + "execution_count": 12 } ] }, @@ -473,29 +484,28 @@ "cell_type": "code", "metadata": { "id": "GAXSzSiufv1u", - "outputId": "94f7e900-0452-4908-c0fe-2783a735bd01", + "outputId": "ba60506d-647b-4d40-b316-dc2c693c6f8c", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises[2] = 'Denmark'\n", "d_paises" ], - "execution_count": null, + "execution_count": 13, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "{1: 'Italy', 2: 'Denmark'}" + "{1: 'Italy', 2: 'Denmark', 3: 'Brazil'}" ] }, "metadata": { "tags": [] }, - "execution_count": 7 + "execution_count": 13 } ] }, @@ -512,17 +522,16 @@ "cell_type": "code", "metadata": { "id": "FN7km8C9gAjM", - "outputId": "7863cccb-b0aa-47b2-901b-ba72a5574d4f", + "outputId": "9927805c-54bf-4a7b-8e1e-134353f3ff40", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises[3]= 'Brazil'\n", "d_paises" ], - "execution_count": null, + "execution_count": 14, "outputs": [ { "output_type": "execute_result", @@ -534,7 +543,7 @@ "metadata": { "tags": [] }, - "execution_count": 8 + "execution_count": 14 } ] }, @@ -561,10 +570,9 @@ "cell_type": "code", "metadata": { "id": "Rr6DtJnDgU5I", - "outputId": "f02c2c47-e5aa-43cd-886b-345c52ed31bd", + "outputId": "763dc0a4-de82-428c-d9d8-940412330956", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ @@ -572,7 +580,7 @@ "d_paises[3]= 'France'\n", "d_paises" ], - "execution_count": null, + "execution_count": 15, "outputs": [ { "output_type": "execute_result", @@ -584,7 +592,7 @@ "metadata": { "tags": [] }, - "execution_count": 9 + "execution_count": 15 } ] }, @@ -613,16 +621,16 @@ "cell_type": "code", "metadata": { "id": "ALwbHwi4iwky", - "outputId": "bb0d57fb-2742-4eb1-9d82-9309142d21f5", + "outputId": "8aa9b44e-313b-42a6-e885-523185c0f4c5", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ - "d_paises.keys()" + "d_paises.keys()\n", + "d_paises." ], - "execution_count": null, + "execution_count": 16, "outputs": [ { "output_type": "execute_result", @@ -634,7 +642,7 @@ "metadata": { "tags": [] }, - "execution_count": 10 + "execution_count": 16 } ] }, @@ -691,27 +699,27 @@ "cell_type": "code", "metadata": { "id": "LraTwXjdjG3m", - "outputId": "b3d6d55e-20ad-4f88-a783-9ba1c4fd8654", + "outputId": "f7e69608-c6bf-45c2-a08a-f7e76e1c4b2f", "colab": { - "base_uri": "https://localhost:8080/", - "height": 162 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises.items()" ], - "execution_count": null, + "execution_count": 17, "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[0md_Paises\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\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 'd_Paises' is not defined" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "dict_items([(1, 'Italy'), (2, 'Denmark'), (3, 'France')])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 } ] }, @@ -739,20 +747,23 @@ "cell_type": "code", "metadata": { "id": "FUfTjqktjW60", - "outputId": "678ab629-6cff-4fe1-e03f-d90709a98f26", + "outputId": "acf5b8d0-7b30-4f3d-87ef-a1c9d259652b", "colab": { "base_uri": "https://localhost:8080/", - "height": 34 + "height": 35 } }, "source": [ "d_paises.get(1)" ], - "execution_count": null, + "execution_count": 18, "outputs": [ { "output_type": "execute_result", "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, "text/plain": [ "'Italy'" ] @@ -760,7 +771,7 @@ "metadata": { "tags": [] }, - "execution_count": 11 + "execution_count": 18 } ] }, @@ -779,17 +790,16 @@ "cell_type": "code", "metadata": { "id": "XL17EmvMkkky", - "outputId": "65846bc2-87a2-42cf-eb17-e3fccb00c9a4", + "outputId": "9aea7f6c-bc39-4d39-bbf7-78c2ff4d7c8c", "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises2 = d_paises.copy()\n", "d_paises2" ], - "execution_count": null, + "execution_count": 19, "outputs": [ { "output_type": "execute_result", @@ -801,7 +811,7 @@ "metadata": { "tags": [] }, - "execution_count": 28 + "execution_count": 19 } ] }, @@ -824,23 +834,22 @@ "source": [ "d_paises.clear()" ], - "execution_count": null, + "execution_count": 20, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ro_42gzDjsdV", - "outputId": "a2c2a25b-40ef-4842-f2f7-3ac85404d195", + "outputId": "355082b3-19d2-4d8b-8347-c2a6b08d6487", "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_paises" ], - "execution_count": null, + "execution_count": 21, "outputs": [ { "output_type": "execute_result", @@ -852,7 +861,7 @@ "metadata": { "tags": [] }, - "execution_count": 13 + "execution_count": 21 } ] }, @@ -967,7 +976,7 @@ " 'Strawberry': 0.50,\n", " 'Watermelon': 0.45}" ], - "execution_count": null, + "execution_count": 22, "outputs": [] }, { @@ -983,16 +992,15 @@ "cell_type": "code", "metadata": { "id": "bI7Ctf0ohyz8", - "outputId": "5af38cf4-aaf8-4efa-f682-502bfb5022a6", + "outputId": "f9aa2e05-8a41-45c0-a32e-22b1b8976c69", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas" ], - "execution_count": null, + "execution_count": 23, "outputs": [ { "output_type": "execute_result", @@ -1027,7 +1035,7 @@ "metadata": { "tags": [] }, - "execution_count": 8 + "execution_count": 23 } ] }, @@ -1044,16 +1052,15 @@ "cell_type": "code", "metadata": { "id": "JpreyE_LtCcU", - "outputId": "cee4be2d-7980-4a3d-85fb-17561d1bb1ff", + "outputId": "f2f7d1e4-51ff-40ff-af58-5577a34dd137", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas['Apple']" ], - "execution_count": null, + "execution_count": 24, "outputs": [ { "output_type": "execute_result", @@ -1065,7 +1072,7 @@ "metadata": { "tags": [] }, - "execution_count": 21 + "execution_count": 24 } ] }, @@ -1082,17 +1089,16 @@ "cell_type": "code", "metadata": { "id": "rMro_tY8kepo", - "outputId": "4488c243-6792-4efa-b271-e546270b129d", + "outputId": "dec61759-d1b5-4379-8846-cce26973209d", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "for key in d_frutas.keys():\n", " print(key)" ], - "execution_count": null, + "execution_count": 25, "outputs": [ { "output_type": "stream", @@ -1139,17 +1145,16 @@ "cell_type": "code", "metadata": { "id": "DpFB1g-3kDSt", - "outputId": "7ac51581-edfa-418d-a1e0-d297ebdffca7", + "outputId": "a0b41867-9ca7-414d-a451-34aa0f6e4232", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "for item in d_frutas.items():\n", " print(item) " ], - "execution_count": null, + "execution_count": 26, "outputs": [ { "output_type": "stream", @@ -1183,6 +1188,17 @@ } ] }, + { + "cell_type": "code", + "metadata": { + "id": "KxGaOrYSdLxp" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, { "cell_type": "markdown", "metadata": { @@ -1196,17 +1212,16 @@ "cell_type": "code", "metadata": { "id": "tjJ6qRF8nr4v", - "outputId": "3e75843b-2d45-4b4c-a3f2-24ffc0e60a7a", + "outputId": "6798f545-3f24-40b9-83d9-8c4a5e073389", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "for value in d_frutas.values():\n", " print(value)" ], - "execution_count": null, + "execution_count": 27, "outputs": [ { "output_type": "stream", @@ -1297,6 +1312,34 @@ } ] }, + { + "cell_type": "code", + "metadata": { + "id": "bDb1IHuddfwH", + "outputId": "b66c5df5-6028-4cad-e480-60c92cdaa9f8", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_frutas.items()" + ], + "execution_count": 28, + "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": 28 + } + ] + }, { "cell_type": "markdown", "metadata": { @@ -1397,16 +1440,15 @@ "cell_type": "code", "metadata": { "id": "DbWpbuLTK9sn", - "outputId": "e9fafa6d-284e-4862-8f25-9419ff702dec", + "outputId": "f10aeaa8-4cd7-41a9-b9f9-7e7bbe6a7fd5", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ "0.4 in d_frutas.values()" ], - "execution_count": null, + "execution_count": 29, "outputs": [ { "output_type": "execute_result", @@ -1418,7 +1460,7 @@ "metadata": { "tags": [] }, - "execution_count": 14 + "execution_count": 29 } ] }, @@ -1440,7 +1482,7 @@ "source": [ "d_frutas2 = {'Grapefruit': 1.0 }" ], - "execution_count": null, + "execution_count": 30, "outputs": [] }, { @@ -1456,17 +1498,16 @@ "cell_type": "code", "metadata": { "id": "7BD_mYMM5O5o", - "outputId": "2b185546-255e-4ad0-e8c9-10564fcbe2b0", + "outputId": "39cdea31-d4ff-4064-e59f-adf178840a82", "colab": { - "base_uri": "https://localhost:8080/", - "height": 442 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas.update(d_frutas2)\n", "d_frutas" ], - "execution_count": null, + "execution_count": 31, "outputs": [ { "output_type": "execute_result", @@ -1502,7 +1543,7 @@ "metadata": { "tags": [] }, - "execution_count": 79 + "execution_count": 31 } ] }, @@ -1523,7 +1564,7 @@ "source": [ "d_frutas3 = {'Apple': 0.70}" ], - "execution_count": null, + "execution_count": 32, "outputs": [] }, { @@ -1540,14 +1581,55 @@ { "cell_type": "code", "metadata": { - "id": "E4GKdTw76PXI" + "id": "E4GKdTw76PXI", + "outputId": "6a14210d-d1e4-4dce-9465-72af35a60671", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ "d_frutas.update(d_frutas3)\n", "d_frutas" ], - "execution_count": null, - "outputs": [] + "execution_count": 33, + "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": 33 + } + ] }, { "cell_type": "markdown", @@ -1587,7 +1669,7 @@ "for key, value in d_frutas.items():\n", " d_frutas[key] = round(value * 0.9, 2)" ], - "execution_count": null, + "execution_count": 34, "outputs": [] }, { @@ -1603,16 +1685,15 @@ "cell_type": "code", "metadata": { "id": "zZLa85knxBtY", - "outputId": "2c7c12f8-8885-4f34-a0d1-1323e98a9437", + "outputId": "ee34b820-6961-4d88-d0e2-628efd922e70", "colab": { - "base_uri": "https://localhost:8080/", - "height": 442 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas" ], - "execution_count": null, + "execution_count": 35, "outputs": [ { "output_type": "execute_result", @@ -1648,7 +1729,7 @@ "metadata": { "tags": [] }, - "execution_count": 84 + "execution_count": 35 } ] }, @@ -1683,7 +1764,7 @@ " if key == 'Avocado':\n", " del d_frutas[key] # Deleta key = 'Avocado'" ], - "execution_count": null, + "execution_count": 36, "outputs": [] }, { @@ -1699,16 +1780,15 @@ "cell_type": "code", "metadata": { "id": "IwnsHejhyT4l", - "outputId": "b910699c-9729-4a27-bd78-3a283c82ac39", + "outputId": "e5029d7e-9c8d-4e37-940e-a375ba57c78d", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas" ], - "execution_count": null, + "execution_count": 37, "outputs": [ { "output_type": "execute_result", @@ -1743,7 +1823,7 @@ "metadata": { "tags": [] }, - "execution_count": 86 + "execution_count": 37 } ] }, @@ -1770,7 +1850,21 @@ " if value > 0.5:\n", " d_frutas_filtro.update({key: value})" ], - "execution_count": null, + "execution_count": 38, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fu1jgbfUhPRD" + }, + "source": [ + "d_frutas_filtro = {}\n", + "for key, value in d_frutas.items():\n", + " if value == 0.5:\n", + " d_frutas_filtro.update({key: value})" + ], + "execution_count": 40, "outputs": [] }, { @@ -1786,36 +1880,27 @@ "cell_type": "code", "metadata": { "id": "SsStWM5k1s-Q", - "outputId": "f6af5b61-2333-41c7-a28a-0f6a67b0a949", + "outputId": "3fc3a8ef-4627-40d7-e24e-f2bee8e22e66", "colab": { - "base_uri": "https://localhost:8080/", - "height": 170 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas_filtro" ], - "execution_count": null, + "execution_count": 41, "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}" + "{'Blackberry': 0.5, 'Peach': 0.5, 'Pineapple': 0.5}" ] }, "metadata": { "tags": [] }, - "execution_count": 89 + "execution_count": 41 } ] }, @@ -2071,51 +2156,50 @@ "cell_type": "code", "metadata": { "id": "iJq1clvOHVG2", - "outputId": "16a779ef-48c9-497c-8c7c-a1612aa9aa03", + "outputId": "2c89ba89-3377-4337-87f1-050360788da9", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ "d_frutas" ], - "execution_count": null, + "execution_count": 42, "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}" + "{'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": 2 + "execution_count": 42 } ] }, @@ -2171,38 +2255,36 @@ "cell_type": "code", "metadata": { "id": "tvHcQatANltL", - "outputId": "8feaf5b1-1db8-4391-8950-248ba8ab46c5", + "outputId": "6ca05107-f13c-4175-9d60-41a7615fd233", "colab": { - "base_uri": "https://localhost:8080/", - "height": 187 + "base_uri": "https://localhost:8080/" } }, "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, + "execution_count": 43, "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}" + "{'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": 7 + "execution_count": 43 } ] }, @@ -2239,13 +2321,33 @@ { "cell_type": "code", "metadata": { - "id": "0BBWO9Zth_mc" + "id": "0BBWO9Zth_mc", + "outputId": "6f948288-be8e-4541-94b9-b067c17f13e4", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ - "d_colaboradores= {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}" + "d_colaboradores= {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}\n", + "d_colaboradores" ], - "execution_count": null, - "outputs": [] + "execution_count": 45, + "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": 45 + } + ] }, { "cell_type": "markdown", @@ -2256,6 +2358,182 @@ "Como acessar o Gerente 'A'?" ] }, + { + "cell_type": "code", + "metadata": { + "id": "XH3BgvYfi01G", + "outputId": "d2fe69fa-5c0b-47b9-9413-e9c2019c19d1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 129 + } + }, + "source": [ + "d_colaboradores{'Gerentes'[0]}" + ], + "execution_count": 46, + "outputs": [ + { + "output_type": "error", + "ename": "SyntaxError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m d_colaboradores{'Gerentes'[0]}\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kCILrtFPjBTe", + "outputId": "4d8c8aca-341d-4528-8ba2-53a898683c49", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_colaboradores.get('Gerentes')\n" + ], + "execution_count": 50, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['A', 'B', 'C']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "emYGFLuJk65D", + "outputId": "8fe63e1f-8421-4d10-916e-58520b8d71fe", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "list_gerentes=d_colaboradores.get('Gerentes')\n", + "list_gerentes[0]" + ], + "execution_count": 53, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 53 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B8ZbnSYNlZgt", + "outputId": "06d1ea72-8a6d-49fd-9d1d-83cf8a080b24", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "source": [ + "d_colaboradores.get('Gerentes')[0]\n", + "\n" + ], + "execution_count": 57, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, + "text/plain": [ + "'A'" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 57 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4JnYRazemjq5" + }, + "source": [ + "retornar os cargos que o funcionario !A! ocupa\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SX2h28bXj33b", + "outputId": "8be812f8-d86a-4a47-d439-55c229c216c9", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_colaboradores['Gerentes']" + ], + "execution_count": 51, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['A', 'B', 'C']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XCkq6tN9mqgn" + }, + "source": [ + "retornar do dicinario d_colaboradores somente o progarmador cujo nome seja 'E'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BSXBKuQvm0y0" + }, + "source": [ + "quais são os colaboradores que \n", + "a)são ao mesmo tempo gerente e gerente de projeto\n", + "b) gerentes de projetos e programadores" + ] + }, { "cell_type": "markdown", "metadata": { @@ -2265,6 +2543,24 @@ "## 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": "ZWRUI3Q0m0GQ" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eKwYMbxymyai" + }, + "source": [ + "" + ] } ] } \ No newline at end of file From 40a63768549d78be4d8544162889e06e0beae38c Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 7 Oct 2020 21:59:25 -0300 Subject: [PATCH 5/9] Criado usando o Colaboratory --- Notebooks/NB09_01__Functions_alterado.ipynb | 1549 +++++++++++++++++++ 1 file changed, 1549 insertions(+) create mode 100644 Notebooks/NB09_01__Functions_alterado.ipynb diff --git a/Notebooks/NB09_01__Functions_alterado.ipynb b/Notebooks/NB09_01__Functions_alterado.ipynb new file mode 100644 index 000000000..5859a10e7 --- /dev/null +++ b/Notebooks/NB09_01__Functions_alterado.ipynb @@ -0,0 +1,1549 @@ +{ + "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": "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", + " \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": "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\n", + " \n", + " return x" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZuIzwitWk7by" + }, + "source": [ + "print(multiplicar_numeros2(1, 2, 3, 4, 5))" + ], + "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": "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": "eUCum4JPEcxD" + }, + "source": [ + "imprime_frutas(**d_frutas)" + ], + "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]" + ], + "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": "H17JO6sLOrG7" + }, + "source": [ + "### Minha solução" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wX_7XDyB0XSy" + }, + "source": [ + "def dia_da_semana(dia):\n", + " d_palavra= {1: 'Segunda',\n", + " 2: 'Terça',\n", + " 3: 'Quarta',\n", + " 4: 'Quinta',\n", + " 5: 'Sexta',\n", + " 6: 'Sabado',\n", + " 7: 'Domingo' }\n", + " return d_palavra.get(dia,\"Dia da semana inválido. Informe um número de 1 a 7\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "39toyCRU1Q5T" + }, + "source": [ + "dia_da_semana(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wt5hQq__1UEd" + }, + "source": [ + "dia_da_semana(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7j-HHsxFrX5t" + }, + "source": [ + "def palavra_está_string (s_palavra, s_string):\n", + " if s_palavra in s_string:\n", + " return True\n", + " else:\n", + " return False\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EOTAE-oMrYJW" + }, + "source": [ + "s_string = '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_string" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tfzOT6w0thZg" + }, + "source": [ + "s_palavra = 'fogo'\n", + "palavra_está_string (s_palavra, s_string)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xxunBr3ttnji" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vrBZ_68-PBWl" + }, + "source": [ + "### Minha solução:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m4Pi4S8hPC_u" + }, + "source": [ + "def check_palavra(s_frase, s_palavra):\n", + " if s_palavra in s_frase:\n", + " return True\n", + " else:\n", + " return False" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "code", + "metadata": { + "id": "2tlravrMQXn2" + }, + "source": [ + "check_palavra(s_frase, s_palavra)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XFBVXsW_rVG2" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "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 From 3c6e45809d6d65537cd280ff84c1557dc497c7bd Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 7 Oct 2020 22:56:24 -0300 Subject: [PATCH 6/9] Criado usando o Colaboratory --- Notebooks/NB07__Dictionaries_alterado.ipynb | 1266 +++++++++++++------ 1 file changed, 874 insertions(+), 392 deletions(-) diff --git a/Notebooks/NB07__Dictionaries_alterado.ipynb b/Notebooks/NB07__Dictionaries_alterado.ipynb index 96c177534..49d128332 100644 --- a/Notebooks/NB07__Dictionaries_alterado.ipynb +++ b/Notebooks/NB07__Dictionaries_alterado.ipynb @@ -110,7 +110,7 @@ "cell_type": "code", "metadata": { "id": "FxuJ7Awd8f5a", - "outputId": "2b09e013-655c-492e-8902-c0706b3f7b4d", + "outputId": "aa77d55b-989e-4472-c3cb-6865e05fb0f3", "colab": { "base_uri": "https://localhost:8080/" } @@ -118,10 +118,11 @@ "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", + " 'Orange', 'Papaya', 'Passion Fruit', 'Peach', 'Pineapple', 'Plum', 'Raspberry', 'Strawberry', 'Watermelon']\n", + "\n", "print(l_frutas)" ], - "execution_count": 2, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -135,14 +136,55 @@ { "cell_type": "code", "metadata": { - "id": "jJyxuMQc9Ewy" + "id": "jJyxuMQc9Ewy", + "outputId": "fc4b18d6-b85b-4ad8-e41d-c53f6314a31d", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "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]" + "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": 3, - "outputs": [] + "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": 4 + } + ] }, { "cell_type": "markdown", @@ -157,16 +199,17 @@ "cell_type": "code", "metadata": { "id": "qT_4sYxA9dyn", - "outputId": "e8276718-3d1c-4dc2-c4ee-0ac975b7ff18", + "outputId": "1952df07-193f-4827-dc41-5f9068b96436", "colab": { "base_uri": "https://localhost:8080/" } }, "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": 4, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -201,7 +244,7 @@ "metadata": { "tags": [] }, - "execution_count": 4 + "execution_count": 5 } ] }, @@ -263,7 +306,7 @@ "cell_type": "code", "metadata": { "id": "N_2J839X4lps", - "outputId": "56ab2a1f-4c41-4335-9697-38bce1eb51f6", + "outputId": "ddfb58dd-dcd8-4a57-b886-6eed048a6b2f", "colab": { "base_uri": "https://localhost:8080/" } @@ -272,7 +315,7 @@ "d_dia_semana = {'Seg': 'Segunda', 'Ter': 'Terça', 'Qua': 'Quarta', 'Qui': 'Quinta', 'Sex': 'Sexta', 'Sab': 'Sabado', 'Dom': 'Domingo'}\n", "d_dia_semana" ], - "execution_count": 5, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -290,7 +333,7 @@ "metadata": { "tags": [] }, - "execution_count": 5 + "execution_count": 6 } ] }, @@ -308,16 +351,16 @@ "cell_type": "code", "metadata": { "id": "eHuvY7BWQKhQ", - "outputId": "649df9a0-587f-4e6c-a19a-4654e919bd93", + "outputId": "aabce6c1-1914-435e-b21b-4f845f82d53f", "colab": { "base_uri": "https://localhost:8080/", "height": 35 } }, "source": [ - "d_dia_semana['Seg']" + "d_dia_semana['Seg'] # A chave aqui é 'Seg'" ], - "execution_count": 6, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -332,7 +375,7 @@ "metadata": { "tags": [] }, - "execution_count": 6 + "execution_count": 7 } ] }, @@ -359,7 +402,7 @@ "cell_type": "code", "metadata": { "id": "2iPWXPBLfOlr", - "outputId": "550e6ef2-9a6a-41b1-8b36-95c3e2e5efbe", + "outputId": "dfe22769-059e-4e95-8dad-85c1654530de", "colab": { "base_uri": "https://localhost:8080/" } @@ -368,7 +411,7 @@ "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": 7, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -380,7 +423,7 @@ "metadata": { "tags": [] }, - "execution_count": 7 + "execution_count": 8 } ] }, @@ -399,7 +442,7 @@ "cell_type": "code", "metadata": { "id": "voPYpGIGff3o", - "outputId": "d0748385-60a7-4b87-b7e2-794fbb8e9abe", + "outputId": "d28c315e-b0a3-46e8-e7e8-4392f5525e94", "colab": { "base_uri": "https://localhost:8080/" } @@ -407,7 +450,7 @@ "source": [ "type(d_paises)" ], - "execution_count": 8, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -419,7 +462,7 @@ "metadata": { "tags": [] }, - "execution_count": 8 + "execution_count": 9 } ] }, @@ -446,7 +489,7 @@ "cell_type": "code", "metadata": { "id": "EXZ7eEZofnza", - "outputId": "fcbde537-da11-4573-ed38-bd4d48a96f60", + "outputId": "1716826d-e92b-4d21-a56e-1fa6b1df6663", "colab": { "base_uri": "https://localhost:8080/" } @@ -455,19 +498,19 @@ "d_paises[1] = 'Italy'\n", "d_paises" ], - "execution_count": 12, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "{1: 'Italy', 2: 'Denmark', 3: 'Brazil'}" + "{1: 'Italy'}" ] }, "metadata": { "tags": [] }, - "execution_count": 12 + "execution_count": 10 } ] }, @@ -484,7 +527,7 @@ "cell_type": "code", "metadata": { "id": "GAXSzSiufv1u", - "outputId": "ba60506d-647b-4d40-b316-dc2c693c6f8c", + "outputId": "0a3ab152-c82b-41d4-e6b8-ec4adf30493f", "colab": { "base_uri": "https://localhost:8080/" } @@ -493,19 +536,19 @@ "d_paises[2] = 'Denmark'\n", "d_paises" ], - "execution_count": 13, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "{1: 'Italy', 2: 'Denmark', 3: 'Brazil'}" + "{1: 'Italy', 2: 'Denmark'}" ] }, "metadata": { "tags": [] }, - "execution_count": 13 + "execution_count": 11 } ] }, @@ -522,7 +565,7 @@ "cell_type": "code", "metadata": { "id": "FN7km8C9gAjM", - "outputId": "9927805c-54bf-4a7b-8e1e-134353f3ff40", + "outputId": "fabb845b-cdff-423c-ef51-2d1f6cd2ee30", "colab": { "base_uri": "https://localhost:8080/" } @@ -531,7 +574,7 @@ "d_paises[3]= 'Brazil'\n", "d_paises" ], - "execution_count": 14, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -543,7 +586,7 @@ "metadata": { "tags": [] }, - "execution_count": 14 + "execution_count": 12 } ] }, @@ -570,7 +613,7 @@ "cell_type": "code", "metadata": { "id": "Rr6DtJnDgU5I", - "outputId": "763dc0a4-de82-428c-d9d8-940412330956", + "outputId": "9d79ee40-e0a6-4f47-dfc0-fe0010102b73", "colab": { "base_uri": "https://localhost:8080/" } @@ -580,7 +623,7 @@ "d_paises[3]= 'France'\n", "d_paises" ], - "execution_count": 15, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -592,7 +635,7 @@ "metadata": { "tags": [] }, - "execution_count": 15 + "execution_count": 13 } ] }, @@ -617,20 +660,47 @@ "# **OBTER KEYS DO DICIONÁRIO**" ] }, + { + "cell_type": "code", + "metadata": { + "id": "FQtAHjJdb0xK", + "outputId": "db5582e2-d3cf-47b6-fa62-c503bca4c05b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "d_paises" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{1: 'Italy', 2: 'Denmark', 3: 'France'}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, { "cell_type": "code", "metadata": { "id": "ALwbHwi4iwky", - "outputId": "8aa9b44e-313b-42a6-e885-523185c0f4c5", + "outputId": "ddc7b4c8-5c59-44a3-8ae7-fdc21524b043", "colab": { "base_uri": "https://localhost:8080/" } }, "source": [ - "d_paises.keys()\n", - "d_paises." + "d_paises.keys()" ], - "execution_count": 16, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -642,7 +712,7 @@ "metadata": { "tags": [] }, - "execution_count": 16 + "execution_count": 15 } ] }, @@ -660,14 +730,13 @@ "cell_type": "code", "metadata": { "id": "cp0PPtl3jEKo", - "outputId": "c7b8739a-caa9-4e58-e6d3-0f86ccd2d950", + "outputId": "68a71557-c44a-4a0f-89c6-ffd9db6421b3", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ - "d_paises.values()" + "d_paises.items()" ], "execution_count": null, "outputs": [ @@ -675,13 +744,13 @@ "output_type": "execute_result", "data": { "text/plain": [ - "dict_values(['Italy', 'Denmark', 'France'])" + "dict_items([(1, 'Italy'), (2, 'Denmark'), (3, 'France')])" ] }, "metadata": { "tags": [] }, - "execution_count": 11 + "execution_count": 16 } ] }, @@ -699,27 +768,27 @@ "cell_type": "code", "metadata": { "id": "LraTwXjdjG3m", - "outputId": "f7e69608-c6bf-45c2-a08a-f7e76e1c4b2f", + "outputId": "b3d6d55e-20ad-4f88-a783-9ba1c4fd8654", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 162 } }, "source": [ "d_paises.items()" ], - "execution_count": 17, + "execution_count": null, "outputs": [ { - "output_type": "execute_result", - "data": { - "text/plain": [ - "dict_items([(1, 'Italy'), (2, 'Denmark'), (3, 'France')])" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 17 + "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[0md_Paises\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\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 'd_Paises' is not defined" + ] } ] }, @@ -747,23 +816,20 @@ "cell_type": "code", "metadata": { "id": "FUfTjqktjW60", - "outputId": "acf5b8d0-7b30-4f3d-87ef-a1c9d259652b", + "outputId": "678ab629-6cff-4fe1-e03f-d90709a98f26", "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 34 } }, "source": [ "d_paises.get(1)" ], - "execution_count": 18, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - }, "text/plain": [ "'Italy'" ] @@ -771,7 +837,7 @@ "metadata": { "tags": [] }, - "execution_count": 18 + "execution_count": 11 } ] }, @@ -790,16 +856,17 @@ "cell_type": "code", "metadata": { "id": "XL17EmvMkkky", - "outputId": "9aea7f6c-bc39-4d39-bbf7-78c2ff4d7c8c", + "outputId": "65846bc2-87a2-42cf-eb17-e3fccb00c9a4", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 35 } }, "source": [ "d_paises2 = d_paises.copy()\n", "d_paises2" ], - "execution_count": 19, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -811,7 +878,7 @@ "metadata": { "tags": [] }, - "execution_count": 19 + "execution_count": 28 } ] }, @@ -834,22 +901,23 @@ "source": [ "d_paises.clear()" ], - "execution_count": 20, + "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ro_42gzDjsdV", - "outputId": "355082b3-19d2-4d8b-8347-c2a6b08d6487", + "outputId": "a2c2a25b-40ef-4842-f2f7-3ac85404d195", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 35 } }, "source": [ "d_paises" ], - "execution_count": 21, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -861,7 +929,7 @@ "metadata": { "tags": [] }, - "execution_count": 21 + "execution_count": 13 } ] }, @@ -976,7 +1044,7 @@ " 'Strawberry': 0.50,\n", " 'Watermelon': 0.45}" ], - "execution_count": 22, + "execution_count": null, "outputs": [] }, { @@ -992,7 +1060,7 @@ "cell_type": "code", "metadata": { "id": "bI7Ctf0ohyz8", - "outputId": "f9aa2e05-8a41-45c0-a32e-22b1b8976c69", + "outputId": "909b3b73-00da-487e-b981-a62073c78fda", "colab": { "base_uri": "https://localhost:8080/" } @@ -1000,7 +1068,7 @@ "source": [ "d_frutas" ], - "execution_count": 23, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -1035,7 +1103,7 @@ "metadata": { "tags": [] }, - "execution_count": 23 + "execution_count": 18 } ] }, @@ -1052,7 +1120,7 @@ "cell_type": "code", "metadata": { "id": "JpreyE_LtCcU", - "outputId": "f2f7d1e4-51ff-40ff-af58-5577a34dd137", + "outputId": "8b2e9f8f-66f9-4fa1-eae9-95b8e6df1abb", "colab": { "base_uri": "https://localhost:8080/" } @@ -1060,7 +1128,7 @@ "source": [ "d_frutas['Apple']" ], - "execution_count": 24, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -1072,7 +1140,35 @@ "metadata": { "tags": [] }, - "execution_count": 24 + "execution_count": 19 + } + ] + }, + { + "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'" + ] } ] }, @@ -1088,17 +1184,17 @@ { "cell_type": "code", "metadata": { - "id": "rMro_tY8kepo", - "outputId": "dec61759-d1b5-4379-8846-cce26973209d", + "id": "i-6-pNQCcyXY", + "outputId": "a8408cf3-3e7f-4cb5-d19a-2e8e243dba6b", "colab": { "base_uri": "https://localhost:8080/" } }, "source": [ - "for key in d_frutas.keys():\n", - " print(key)" + "for chave in d_frutas.keys():\n", + " print(chave)" ], - "execution_count": 25, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -1132,29 +1228,114 @@ } ] }, + { + "cell_type": "markdown", + "metadata": { + "id": "9u4xJ0FfdCxm" + }, + "source": [ + "## Iterar pelos valores do dicionário:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vrFPwQPDdFP3", + "outputId": "cb739da2-4407-47fe-8495-9c86247bffad", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "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 (key, value) do dicionário" + "## Iterar pelos itens (chave, valor) do dicionário" ] }, { "cell_type": "code", "metadata": { - "id": "DpFB1g-3kDSt", - "outputId": "a0b41867-9ca7-414d-a451-34aa0f6e4232", + "id": "H8BCC6qodU6o", + "outputId": "9744058d-976e-4309-d878-679af58013aa", "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)])" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "DpFB1g-3kDSt", + "outputId": "7ac51581-edfa-418d-a1e0-d297ebdffca7", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 425 + } + }, "source": [ "for item in d_frutas.items():\n", " print(item) " ], - "execution_count": 26, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -1188,17 +1369,6 @@ } ] }, - { - "cell_type": "code", - "metadata": { - "id": "KxGaOrYSdLxp" - }, - "source": [ - "" - ], - "execution_count": null, - "outputs": [] - }, { "cell_type": "markdown", "metadata": { @@ -1212,16 +1382,17 @@ "cell_type": "code", "metadata": { "id": "tjJ6qRF8nr4v", - "outputId": "6798f545-3f24-40b9-83d9-8c4a5e073389", + "outputId": "3e75843b-2d45-4b4c-a3f2-24ffc0e60a7a", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 425 } }, "source": [ "for value in d_frutas.values():\n", " print(value)" ], - "execution_count": 27, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -1313,35 +1484,7 @@ ] }, { - "cell_type": "code", - "metadata": { - "id": "bDb1IHuddfwH", - "outputId": "b66c5df5-6028-4cad-e480-60c92cdaa9f8", - "colab": { - "base_uri": "https://localhost:8080/" - } - }, - "source": [ - "d_frutas.items()" - ], - "execution_count": 28, - "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": 28 - } - ] - }, - { - "cell_type": "markdown", + "cell_type": "markdown", "metadata": { "id": "Fotx7XUquAo8" }, @@ -1363,10 +1506,9 @@ "cell_type": "code", "metadata": { "id": "-gkEKNZPTeMp", - "outputId": "3540aadd-996a-4abd-cfcb-c22e49b75aaa", + "outputId": "6c248a84-4912-446e-a197-7dc8ea670b85", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ @@ -1384,7 +1526,7 @@ "metadata": { "tags": [] }, - "execution_count": 75 + "execution_count": 25 } ] }, @@ -1401,14 +1543,13 @@ "cell_type": "code", "metadata": { "id": "SKtEwmBCuxyi", - "outputId": "1df7263c-a64f-4eaf-8d4d-a55cac03d2bc", + "outputId": "cf52b903-90e0-432f-8b7e-bc878d5c5f5f", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ - "'Coconut' in fruits.keys()" + "'Coconut' in d_frutas.keys()" ], "execution_count": null, "outputs": [ @@ -1422,7 +1563,7 @@ "metadata": { "tags": [] }, - "execution_count": 77 + "execution_count": 29 } ] }, @@ -1440,7 +1581,7 @@ "cell_type": "code", "metadata": { "id": "DbWpbuLTK9sn", - "outputId": "f10aeaa8-4cd7-41a9-b9f9-7e7bbe6a7fd5", + "outputId": "97999d69-9bce-463c-f980-e5a447ccf7a4", "colab": { "base_uri": "https://localhost:8080/" } @@ -1448,7 +1589,7 @@ "source": [ "0.4 in d_frutas.values()" ], - "execution_count": 29, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -1460,7 +1601,7 @@ "metadata": { "tags": [] }, - "execution_count": 29 + "execution_count": 30 } ] }, @@ -1477,13 +1618,31 @@ { "cell_type": "code", "metadata": { - "id": "5Rwq4-UG4--u" + "id": "5Rwq4-UG4--u", + "outputId": "4b157602-fd78-41a9-ae5b-de42c189d805", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ - "d_frutas2 = {'Grapefruit': 1.0 }" + "d_frutas2 = {'Grapefruit': 1.0}\n", + "d_frutas2" ], - "execution_count": 30, - "outputs": [] + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Grapefruit': 1.0}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 32 + } + ] }, { "cell_type": "markdown", @@ -1498,7 +1657,7 @@ "cell_type": "code", "metadata": { "id": "7BD_mYMM5O5o", - "outputId": "39cdea31-d4ff-4064-e59f-adf178840a82", + "outputId": "ea96653d-04e7-4809-a24f-ff97ecdf4a81", "colab": { "base_uri": "https://localhost:8080/" } @@ -1507,7 +1666,7 @@ "d_frutas.update(d_frutas2)\n", "d_frutas" ], - "execution_count": 31, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -1543,7 +1702,7 @@ "metadata": { "tags": [] }, - "execution_count": 31 + "execution_count": 33 } ] }, @@ -1564,7 +1723,7 @@ "source": [ "d_frutas3 = {'Apple': 0.70}" ], - "execution_count": 32, + "execution_count": null, "outputs": [] }, { @@ -1581,55 +1740,14 @@ { "cell_type": "code", "metadata": { - "id": "E4GKdTw76PXI", - "outputId": "6a14210d-d1e4-4dce-9465-72af35a60671", - "colab": { - "base_uri": "https://localhost:8080/" - } + "id": "E4GKdTw76PXI" }, "source": [ "d_frutas.update(d_frutas3)\n", "d_frutas" ], - "execution_count": 33, - "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": 33 - } - ] + "execution_count": null, + "outputs": [] }, { "cell_type": "markdown", @@ -1663,14 +1781,113 @@ { "cell_type": "code", "metadata": { - "id": "ZziGmKGmwqwn" + "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": "30ba046d-0815-4df5-d36b-1459fae1bb9a", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ "for key, value in d_frutas.items():\n", - " d_frutas[key] = round(value * 0.9, 2)" + " d_frutas[key] = round((value * 0.9), 2) # Isso representa um desconto de 10% no valor das frutas\n", + "\n", + "d_frutas" ], - "execution_count": 34, - "outputs": [] + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'Apple': 0.32,\n", + " 'Apricot': 0.21,\n", + " 'Avocado': 0.29,\n", + " 'Banana': 0.24,\n", + " 'Blackberry': 0.45,\n", + " 'Blackcurrant': 0.57,\n", + " 'Blueberry': 0.37,\n", + " 'Cherry': 0.41,\n", + " 'Coconut': 0.61,\n", + " 'Fig': 0.49,\n", + " 'Grape': 0.53,\n", + " 'Grapefruit': 0.81,\n", + " 'Kiwi': 0.16,\n", + " 'Lemon': 0.13,\n", + " 'Mango': 0.65,\n", + " 'Nectarine': 0.61,\n", + " 'Orange': 0.21,\n", + " 'Papaya': 0.24,\n", + " 'Passion Fruit': 0.37,\n", + " 'Peach': 0.45,\n", + " 'Pineapple': 0.45,\n", + " 'Plum': 0.49,\n", + " 'Raspberry': 0.32,\n", + " 'Strawberry': 0.41,\n", + " 'Watermelon': 0.37}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] }, { "cell_type": "markdown", @@ -1685,15 +1902,16 @@ "cell_type": "code", "metadata": { "id": "zZLa85knxBtY", - "outputId": "ee34b820-6961-4d88-d0e2-628efd922e70", + "outputId": "2c7c12f8-8885-4f34-a0d1-1323e98a9437", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 442 } }, "source": [ "d_frutas" ], - "execution_count": 35, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -1729,7 +1947,7 @@ "metadata": { "tags": [] }, - "execution_count": 35 + "execution_count": 84 } ] }, @@ -1764,7 +1982,7 @@ " if key == 'Avocado':\n", " del d_frutas[key] # Deleta key = 'Avocado'" ], - "execution_count": 36, + "execution_count": null, "outputs": [] }, { @@ -1780,7 +1998,7 @@ "cell_type": "code", "metadata": { "id": "IwnsHejhyT4l", - "outputId": "e5029d7e-9c8d-4e37-940e-a375ba57c78d", + "outputId": "f0f819ca-117e-4a52-8458-196476c52aad", "colab": { "base_uri": "https://localhost:8080/" } @@ -1788,42 +2006,42 @@ "source": [ "d_frutas" ], - "execution_count": 37, + "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}" + "{'Apple': 0.32,\n", + " 'Apricot': 0.21,\n", + " 'Banana': 0.24,\n", + " 'Blackberry': 0.45,\n", + " 'Blackcurrant': 0.57,\n", + " 'Blueberry': 0.37,\n", + " 'Cherry': 0.41,\n", + " 'Coconut': 0.61,\n", + " 'Fig': 0.49,\n", + " 'Grape': 0.53,\n", + " 'Grapefruit': 0.81,\n", + " 'Kiwi': 0.16,\n", + " 'Lemon': 0.13,\n", + " 'Mango': 0.65,\n", + " 'Nectarine': 0.61,\n", + " 'Orange': 0.21,\n", + " 'Papaya': 0.24,\n", + " 'Passion Fruit': 0.37,\n", + " 'Peach': 0.45,\n", + " 'Pineapple': 0.45,\n", + " 'Plum': 0.49,\n", + " 'Raspberry': 0.32,\n", + " 'Strawberry': 0.41,\n", + " 'Watermelon': 0.37}" ] }, "metadata": { "tags": [] }, - "execution_count": 37 + "execution_count": 41 } ] }, @@ -1846,25 +2064,12 @@ }, "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": 38, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "fu1jgbfUhPRD" - }, - "source": [ - "d_frutas_filtro = {}\n", - "for key, value in d_frutas.items():\n", - " if value == 0.5:\n", - " d_frutas_filtro.update({key: value})" - ], - "execution_count": 40, + "execution_count": null, "outputs": [] }, { @@ -1880,7 +2085,7 @@ "cell_type": "code", "metadata": { "id": "SsStWM5k1s-Q", - "outputId": "3fc3a8ef-4627-40d7-e24e-f2bee8e22e66", + "outputId": "a473e0a5-1ece-47ff-b8ae-2a460d0b3dc2", "colab": { "base_uri": "https://localhost:8080/" } @@ -1888,19 +2093,28 @@ "source": [ "d_frutas_filtro" ], - "execution_count": 41, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "{'Blackberry': 0.5, 'Peach': 0.5, 'Pineapple': 0.5}" + "{'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": 41 + "execution_count": 3 } ] }, @@ -2031,10 +2245,9 @@ "cell_type": "code", "metadata": { "id": "SH0WIKZ8-Ylr", - "outputId": "b9cea719-637e-40a5-9e79-eb67aeb47887", + "outputId": "0352afbe-7189-4b41-9428-7980a76c8442", "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 + "base_uri": "https://localhost:8080/" } }, "source": [ @@ -2047,36 +2260,36 @@ "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)]" + "[('Apple', 0.32),\n", + " ('Apricot', 0.21),\n", + " ('Banana', 0.24),\n", + " ('Blackberry', 0.45),\n", + " ('Blackcurrant', 0.57),\n", + " ('Blueberry', 0.37),\n", + " ('Cherry', 0.41),\n", + " ('Coconut', 0.61),\n", + " ('Fig', 0.49),\n", + " ('Grape', 0.53),\n", + " ('Grapefruit', 0.81),\n", + " ('Kiwi', 0.16),\n", + " ('Lemon', 0.13),\n", + " ('Mango', 0.65),\n", + " ('Nectarine', 0.61),\n", + " ('Orange', 0.21),\n", + " ('Papaya', 0.24),\n", + " ('Passion Fruit', 0.37),\n", + " ('Peach', 0.45),\n", + " ('Pineapple', 0.45),\n", + " ('Plum', 0.49),\n", + " ('Raspberry', 0.32),\n", + " ('Strawberry', 0.41),\n", + " ('Watermelon', 0.37)]" ] }, "metadata": { "tags": [] }, - "execution_count": 12 + "execution_count": 46 } ] }, @@ -2156,7 +2369,7 @@ "cell_type": "code", "metadata": { "id": "iJq1clvOHVG2", - "outputId": "2c89ba89-3377-4337-87f1-050360788da9", + "outputId": "66747a5b-c319-4b99-eda0-afcb187ea867", "colab": { "base_uri": "https://localhost:8080/" } @@ -2164,42 +2377,42 @@ "source": [ "d_frutas" ], - "execution_count": 42, + "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}" + "{'Apple': 0.32,\n", + " 'Apricot': 0.21,\n", + " 'Banana': 0.24,\n", + " 'Blackberry': 0.45,\n", + " 'Blackcurrant': 0.57,\n", + " 'Blueberry': 0.37,\n", + " 'Cherry': 0.41,\n", + " 'Coconut': 0.61,\n", + " 'Fig': 0.49,\n", + " 'Grape': 0.53,\n", + " 'Grapefruit': 0.81,\n", + " 'Kiwi': 0.16,\n", + " 'Lemon': 0.13,\n", + " 'Mango': 0.65,\n", + " 'Nectarine': 0.61,\n", + " 'Orange': 0.21,\n", + " 'Papaya': 0.24,\n", + " 'Passion Fruit': 0.37,\n", + " 'Peach': 0.45,\n", + " 'Pineapple': 0.45,\n", + " 'Plum': 0.49,\n", + " 'Raspberry': 0.32,\n", + " 'Strawberry': 0.41,\n", + " 'Watermelon': 0.37}" ] }, "metadata": { "tags": [] }, - "execution_count": 42 + "execution_count": 47 } ] }, @@ -2216,14 +2429,13 @@ "cell_type": "code", "metadata": { "id": "uIDW5FhwAiSs", - "outputId": "52599d3f-ff13-4894-f697-ce7290bff9d5", + "outputId": "b266365b-417a-4f9f-9fda-c033446472e8", "colab": { - "base_uri": "https://localhost:8080/", - "height": 34 + "base_uri": "https://localhost:8080/" } }, "source": [ - "d_frutas2 = {k: v for k, v in filter(lambda t: t[0] == 'Apple', d_frutas.items())}\n", + "d_frutas2 = {chave: valor for chave, valor in filter(lambda t: t[0] == 'Apple', d_frutas.items())}\n", "d_frutas2" ], "execution_count": null, @@ -2238,7 +2450,50 @@ "metadata": { "tags": [] }, - "execution_count": 6 + "execution_count": 4 + } + ] + }, + { + "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 } ] }, @@ -2248,43 +2503,55 @@ "id": "nUMGIzxeNt_U" }, "source": [ - "### Filtrando por valor:" + "### 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": "6ca05107-f13c-4175-9d60-41a7615fd233", + "outputId": "8feaf5b1-1db8-4391-8950-248ba8ab46c5", "colab": { - "base_uri": "https://localhost:8080/" + "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": 43, + "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}" + "{'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": 43 + "execution_count": 7 } ] }, @@ -2322,16 +2589,16 @@ "cell_type": "code", "metadata": { "id": "0BBWO9Zth_mc", - "outputId": "6f948288-be8e-4541-94b9-b067c17f13e4", + "outputId": "18783570-d8b5-4fa1-9f19-747b0db288da", "colab": { "base_uri": "https://localhost:8080/" } }, "source": [ - "d_colaboradores= {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}\n", + "d_colaboradores = {'Gerentes': ['A', 'B', 'C'], 'Programadores': ['B', 'D', 'E', 'F', 'G'], 'Gerentes_Projeto': ['A', 'E']}\n", "d_colaboradores" ], - "execution_count": 45, + "execution_count": 2, "outputs": [ { "output_type": "execute_result", @@ -2345,7 +2612,7 @@ "metadata": { "tags": [] }, - "execution_count": 45 + "execution_count": 2 } ] }, @@ -2361,71 +2628,74 @@ { "cell_type": "code", "metadata": { - "id": "XH3BgvYfi01G", - "outputId": "d2fe69fa-5c0b-47b9-9413-e9c2019c19d1", + "id": "rGvVgyz7jxwn", + "outputId": "c4e02509-6910-46c5-d906-b7d6f542dfb3", "colab": { - "base_uri": "https://localhost:8080/", - "height": 129 + "base_uri": "https://localhost:8080/" } }, "source": [ - "d_colaboradores{'Gerentes'[0]}" + "d_colaboradores['Gerentes']" ], - "execution_count": 46, + "execution_count": null, "outputs": [ { - "output_type": "error", - "ename": "SyntaxError", - "evalue": "ignored", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m d_colaboradores{'Gerentes'[0]}\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "['A', 'B', 'C']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 } ] }, { "cell_type": "code", "metadata": { - "id": "kCILrtFPjBTe", - "outputId": "4d8c8aca-341d-4528-8ba2-53a898683c49", + "id": "c-VwXvdij3QQ", + "outputId": "f4344858-8ebf-4e0c-b336-e7a6ed4a43a2", "colab": { "base_uri": "https://localhost:8080/" } }, "source": [ - "d_colaboradores.get('Gerentes')\n" + "d_colaboradores['Programadores']" ], - "execution_count": 50, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "['A', 'B', 'C']" + "['B', 'D', 'E', 'F', 'G']" ] }, "metadata": { "tags": [] }, - "execution_count": 50 + "execution_count": 51 } ] }, { "cell_type": "code", "metadata": { - "id": "emYGFLuJk65D", - "outputId": "8fe63e1f-8421-4d10-916e-58520b8d71fe", + "id": "WV0WaGB4kCiP", + "outputId": "171e4ea0-c66f-49c2-f4ea-deb44b315d43", "colab": { "base_uri": "https://localhost:8080/", "height": 35 } }, "source": [ - "list_gerentes=d_colaboradores.get('Gerentes')\n", - "list_gerentes[0]" + "s_gerentes = d_colaboradores['Gerentes']\n", + "s_gerentes[0]" ], - "execution_count": 53, + "execution_count": null, "outputs": [ { "output_type": "execute_result", @@ -2440,127 +2710,339 @@ "metadata": { "tags": [] }, - "execution_count": 53 + "execution_count": 62 } ] }, { "cell_type": "code", "metadata": { - "id": "B8ZbnSYNlZgt", - "outputId": "06d1ea72-8a6d-49fd-9d1d-83cf8a080b24", + "id": "yRrG7wUgkf6K", + "outputId": "122c0ff9-47af-4a50-874e-42779aa3c068", "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 + "base_uri": "https://localhost:8080/" } }, "source": [ - "d_colaboradores.get('Gerentes')[0]\n", - "\n" + "s_gerente_A = d_colaboradores.values()\n", + "s_gerente_A" ], - "execution_count": 57, + "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { - "application/vnd.google.colaboratory.intrinsic+json": { - "type": "string" - }, "text/plain": [ - "'A'" + "dict_values([['A', 'B', 'C'], ['B', 'D', 'E', 'F', 'G'], ['A', 'E']])" ] }, "metadata": { "tags": [] }, - "execution_count": 57 + "execution_count": 55 } ] }, { "cell_type": "markdown", "metadata": { - "id": "4JnYRazemjq5" + "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": [ - "retornar os cargos que o funcionario !A! ocupa\n" + "## **Exercício 4**\n", + "\n", + "Retornar do dicionário d_colaboradores somente o Programador cujo nome seja 'E'. " ] }, { "cell_type": "code", "metadata": { - "id": "SX2h28bXj33b", - "outputId": "8be812f8-d86a-4a47-d439-55c229c216c9", + "id": "W97EV00T1ejw", + "outputId": "f043e621-a387-4db4-bd19-a1410af98f46", "colab": { - "base_uri": "https://localhost:8080/" + "base_uri": "https://localhost:8080/", + "height": 35 } }, "source": [ - "d_colaboradores['Gerentes']" + "chave='Gerentes'\n", + "d_colaboradores['Gerentes'][0]\n", + "d_colaboradores[chave][0]" ], - "execution_count": 51, + "execution_count": 24, "outputs": [ { "output_type": "execute_result", "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + }, "text/plain": [ - "['A', 'B', 'C']" + "'A'" ] }, "metadata": { "tags": [] }, - "execution_count": 51 + "execution_count": 24 } ] }, { - "cell_type": "markdown", + "cell_type": "code", "metadata": { - "id": "XCkq6tN9mqgn" + "id": "1CGVsatkzuu4", + "outputId": "d6beb963-ec37-4f40-944b-4b9a5bf264b0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 129 + } }, "source": [ - "retornar do dicinario d_colaboradores somente o progarmador cujo nome seja 'E'" + "for key in d_colaboradores.keys():\n", + " i_posição=0\n", + " for i_indice in d_colaboradores[key][i_indice]:\n", + " if 'E' in d_colaboradores.get(key):\n", + " valor = d_colaboradores.get(key)\n", + " for i_posição < valor:\n", + " d_colaboradores.get(key)[i_posição]\n", + " print(d_colaboradores.get(key)[i_posição])\n", + " valor = d_colaboradores.get(key)\n", + " tamanho=len(valor)\n", + " print(tamanho)\n", + " print(valor)\n", + " valor[valor == 'E']\n", + " print(valor)\n", + " print(key)\n", + " print(i_indice)\n", + " #print(d_colaboradores[key][i_indice])\n", + " print(d_colaboradores.values())" + ], + "execution_count": 42, + "outputs": [ + { + "output_type": "error", + "ename": "SyntaxError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m6\u001b[0m\n\u001b[0;31m for i_posição < valor:\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } ] }, { "cell_type": "markdown", "metadata": { - "id": "BSXBKuQvm0y0" + "id": "zfnP-CArmPb4" }, "source": [ - "quais são os colaboradores que \n", - "a)são ao mesmo tempo gerente e gerente de projeto\n", - "b) gerentes de projetos e programadores" + "## **Exercício 5**\n", + "\n", + "Retornar qual é o cargo do funcionário (todas as pessoas da organização) que se chama 'A'." ] }, { "cell_type": "markdown", "metadata": { - "id": "ntVcr_3XwaQ-" + "id": "qc6xDbMGvwX9" }, "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." + "'A' in " ] }, { - "cell_type": "markdown", + "cell_type": "code", "metadata": { - "id": "ZWRUI3Q0m0GQ" + "id": "zIUF3u6Bv7r5", + "outputId": "8d5657c7-71d9-452e-ea1e-1e6a24f212a9", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ - "" + "for key in d_colaboradores.keys():\n", + " if 'A' in d_colaboradores[key]:\n", + " print(key)\n" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Gerentes\n", + "Gerentes_Projeto\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "O0QqPmYdxDHY", + "outputId": "bb30b080-9356-4238-d33c-9a8222963096", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "cargos = []\n", + "for key in d_colaboradores.keys():\n", + " if 'A' in d_colaboradores[key]:\n", + " cargos.append(key)\n", + "print(cargos)" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['Gerentes', 'Gerentes_Projeto']\n" + ], + "name": "stdout" + } ] }, { "cell_type": "markdown", "metadata": { - "id": "eKwYMbxymyai" + "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": "4a9f4bdd-6e59-494f-c4bb-e093c409f842", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + " import numpy as np\n", + " gerente_e_gerenteproj=[]\n", + " gerente_e_gerenteproj=np.intersect1d(d_colaboradores['Gerentes'],d_colaboradores['Gerentes_Projeto'])\n", + " print(gerente_e_gerenteproj, 'são gerentes e gerentes de projeto')" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['A'] são gerentes e gerentes de projeto\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "hKS4X7c2zfX9", + "outputId": "ecf5c9cd-2c86-4cb9-9060-b517c37ddd7f", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(np.intersect1d(d_colaboradores['Gerentes'],d_colaboradores['Gerentes_Projeto']), 'são gerentes e gerentes de projeto')" + ], + "execution_count": 15, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['A'] são gerentes e gerentes de projeto\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k1N4T6fVyMCR", + "outputId": "f11a1554-ef09-49f7-a0ef-0618e1112dbe", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "gerente_e_programador=np.intersect1d(d_colaboradores['Gerentes'],d_colaboradores['Programadores'])\n", + "print(gerente_e_programador, 'são gerentes e programadores')" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['B'] são gerentes e programadores\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PmJHD32dzeV2" }, "source": [ "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GT82fPS0zGJ0", + "outputId": "69184b7c-6027-4bd0-ee64-5e7962608c14", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "source": [ + "print(np.intersect1d(d_colaboradores['Gerentes'],d_colaboradores['Programadores']), 'são gerentes e programadores')" + ], + "execution_count": 14, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['B'] são gerentes e programadores\n" + ], + "name": "stdout" + } ] + }, + { + "cell_type": "code", + "metadata": { + "id": "smjv-gaKzaUl" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 497bf8229fec9c3732e3a4ddfc5a13e951216a0f Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Thu, 8 Oct 2020 15:39:56 -0300 Subject: [PATCH 7/9] Criado usando o Colaboratory --- Notebooks/NB09_01__Functions_alterado2.ipynb | 1662 ++++++++++++++++++ 1 file changed, 1662 insertions(+) create mode 100644 Notebooks/NB09_01__Functions_alterado2.ipynb diff --git a/Notebooks/NB09_01__Functions_alterado2.ipynb b/Notebooks/NB09_01__Functions_alterado2.ipynb new file mode 100644 index 000000000..092a9649b --- /dev/null +++ b/Notebooks/NB09_01__Functions_alterado2.ipynb @@ -0,0 +1,1662 @@ +{ + "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": "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", + " \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": "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\n", + " \n", + " return x" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZuIzwitWk7by" + }, + "source": [ + "print(multiplicar_numeros2(1, 2, 3, 4, 5))" + ], + "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": "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():#o .itens()devolve dois valores chave e valor\n", + " print(f'O valor de {key} é {value}')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_FaKEXk_d9jQ" + }, + "source": [ + "[15:25] Vinicius Fabri Brenck\n", + "Isso aqui tb funciona normalmente\n", + "\n", + "[15:25] Vinicius Fabri Brenck\n", + "def imprimir_normal(dicionario):  for key, value in dicionario.items():    print('O valor de {} é {}'.format(key, value))imprimir_normal(d_frutas)\n", + "\n", + "[15:25] Vinicius Fabri Brenck\n", + "O resultado é exatamente o mesmo\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sdGIG-c-cuOW" + }, + "source": [ + "##\n", + "##o próprio construtor de dicionário pode ser chamado assim.\n", + "\n", + "##dict(a=1, b=2) >>> {​​'a':1, 'b':2}​​" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "eYI0dxKyeBZJ" + }, + "source": [ + "##[15:25] Vinicius Fabri Brenck\n", + "##Isso aqui tb funciona normalmente\n", + "\n", + "##[15:25] Vinicius Fabri Brenck\n", + "def imprimir_normal(dicionario):  for key, value in dicionario.items():    print('O valor de {} é {}'.format(key, value))imprimir_normal(d_frutas)\n", + "\n", + "##[15:25] Vinicius Fabri Brenck\n", + "##O resultado é exatamente o mesmo\n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "jFrnCnJWdJjw" + }, + "source": [ + "d_frutas['blblba'] = 0.1\n", + "d_frutas" + ], + "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)## essa coisa esquisita é uma forma de passar o dicionario" + ], + "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": "eUCum4JPEcxD" + }, + "source": [ + "imprime_frutas(**d_frutas) ## a sintaxe é ** nome do dicionário" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3VuoDBftdnfi" + }, + "source": [ + "Cristiano:\n", + "eu fazia a seguinte analogia:\n", + "\n", + "*iterable explode um iterável em argumentos posicionias.\n", + "\n", + "**mapper explode um mapaeamento (dicionário) em argumentos nomeados." + ] + }, + { + "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(): ## dentro de exemplo4 eu não defini a variavel i_valor, para dar certo tenho que colocar o global i_valor\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": "code", + "metadata": { + "id": "WvA2CjOGfPr9" + }, + "source": [ + "i_valor = 20\n", + "\n", + "def exemplo4(): ## dentro de exemplo4 eu não defini a variavel i_valor, para dar certo tenho que colocar o global i_valor\n", + " glocal i_valor += 1\n", + " print(i_valor)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qyl5gKHEfTZN" + }, + "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]" + ], + "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)) ### o map precisa de dois parametro :a função é o parametro e um iterable (tupla,array)\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "ckT2g4CcgNKV" + }, + "source": [ + "map(quadrado_do_numero, l_numeros) ## se eu não der o list ele deixa o resultado na memoria que é um iteravel" + ], + "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": "H17JO6sLOrG7" + }, + "source": [ + "### Minha solução" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wX_7XDyB0XSy" + }, + "source": [ + "def dia_da_semana(dia):\n", + " d_palavra= {1: 'Segunda',\n", + " 2: 'Terça',\n", + " 3: 'Quarta',\n", + " 4: 'Quinta',\n", + " 5: 'Sexta',\n", + " 6: 'Sabado',\n", + " 7: 'Domingo' }\n", + " return d_palavra.get(dia,\"Dia da semana inválido. Informe um número de 1 a 7\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "39toyCRU1Q5T" + }, + "source": [ + "dia_da_semana(1)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "wt5hQq__1UEd" + }, + "source": [ + "dia_da_semana(0)" + ], + "execution_count": null, + "outputs": [] + }, + { + "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." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7j-HHsxFrX5t" + }, + "source": [ + "def palavra_está_string (s_palavra, s_string):\n", + " if s_palavra in s_string:\n", + " return True\n", + " else:\n", + " return False\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EOTAE-oMrYJW" + }, + "source": [ + "s_string = '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_string" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "tfzOT6w0thZg" + }, + "source": [ + "s_palavra = 'fogo'\n", + "palavra_está_string (s_palavra, s_string)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xxunBr3ttnji" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vrBZ_68-PBWl" + }, + "source": [ + "### Minha solução:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "m4Pi4S8hPC_u" + }, + "source": [ + "def check_palavra(s_frase, s_palavra):\n", + " if s_palavra in s_frase:\n", + " return True\n", + " else:\n", + " return False" + ], + "execution_count": null, + "outputs": [] + }, + { + "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": "code", + "metadata": { + "id": "2tlravrMQXn2" + }, + "source": [ + "check_palavra(s_frase, s_palavra)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "XFBVXsW_rVG2" + }, + "source": [ + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "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 From 5c20b86b727ad16f8b875d54bc8b407001a65315 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 21 Oct 2020 07:34:55 -0300 Subject: [PATCH 8/9] Criado usando o Colaboratory --- ...0_04__3DP_4_Anomaly_Detection mexido.ipynb | 4445 +++++++++++++++++ 1 file changed, 4445 insertions(+) create mode 100644 Notebooks/NB10_04__3DP_4_Anomaly_Detection mexido.ipynb diff --git a/Notebooks/NB10_04__3DP_4_Anomaly_Detection mexido.ipynb b/Notebooks/NB10_04__3DP_4_Anomaly_Detection mexido.ipynb new file mode 100644 index 000000000..43cdff8b9 --- /dev/null +++ b/Notebooks/NB10_04__3DP_4_Anomaly_Detection mexido.ipynb @@ -0,0 +1,4445 @@ +{ + "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", + "ANÁLISE DE OUTLIERS\n", + "significa que estou no passo 3 do data preparation. e 4 é a ordem dentro dessa fase\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": "a5238044-16ea-47c3-c2d5-ef8054a493aa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 663 + } + }, + "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 14.5MB/s eta 0:00:01\r\u001b[K |██████▊ | 20kB 1.9MB/s eta 0:00:01\r\u001b[K |██████████▏ | 30kB 2.5MB/s eta 0:00:01\r\u001b[K |█████████████▌ | 40kB 2.7MB/s eta 0:00:01\r\u001b[K |█████████████████ | 51kB 2.1MB/s eta 0:00:01\r\u001b[K |████████████████████▎ | 61kB 2.4MB/s eta 0:00:01\r\u001b[K |███████████████████████▊ | 71kB 2.6MB/s eta 0:00:01\r\u001b[K |███████████████████████████ | 81kB 2.9MB/s eta 0:00:01\r\u001b[K |██████████████████████████████▍ | 92kB 3.1MB/s eta 0:00:01\r\u001b[K |████████████████████████████████| 102kB 2.7MB/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 8.6MB/s \n", + "\u001b[?25hRequirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (0.10.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: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->pyod) (1.2.0)\n", + "Requirement 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: setuptools in /usr/local/lib/python3.6/dist-packages (from numba>=0.35->pyod) (50.3.0)\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: 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=8a3d12b45521f4215a1a25ab5641035110c2e231b63217ef8d77d5f4b37e9f9e\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=98b1e51b50dfc241776ed56aec23e7bbe693938654b828ea7a7720fcf4ec3c0f\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=1caa776362bcbb19af861f1d849b5885230a55792d5d4ac1ad0ec6df9433d7d0\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 ### interessante para detecção de outliers\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 ### interessante para detecção de outliers\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": "35857212-e5e8-4065-a37f-e83958c34819", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + } + }, + "source": [ + "df_titanic = sns.load_dataset('titanic')### LOAD.dataset é da biblioteca sns.\n", + "df_titanic = df_titanic.dropna() ## isso é um simplificação, não é assim que seja o ideal\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": 6, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rAKnKtil9Oz1", + "outputId": "99989e0f-a80b-4eda-d0b9-6016114dca67", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Linhas do df_titanic\n", + "df_titanic_ss.shape" + ], + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(182, 15)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 7 + } + ] + }, + { + "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": 8, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o9-VgcNnFNb1", + "outputId": "9f5cd781-1066-43ff-dfb9-4167ac817895", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 426 + } + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'fare') ## versao univariada \n", + "##quem pagou mais pela tarifa, quem morreu ou quem sobreviveu ? foi o 1 quem sobreviveu\n", + "###o tamanho da caixinha laranja é maior, a mediana também é maior\n", + "###olhando para os outliers podemos dizer que , " + ], + "execution_count": 9, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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Zqbafv/99+ORRx5BRkYGbDYbdu/ejZqaGmzYsAEAcPvtt6Oqqgr33nsvnn76aTgcDjz22GPYtWsXjEbjrL8mIiIioonSdGL+1Tz77LMQRRHbtm1DIBDA5s2b8cILL6jbJUnCW2+9hZ07d6KmpgZWqxU7duzAvn37NOw1ERER0dUJiqIoWndCax6PB3a7HW63m/PDiIiIaFZoXieMiIiI6FrEEEZERESkAYYwIiIiIg0whBERERFpgCGMiIiISAMMYUREREQaYAgjIiIi0gBDGBEREZEGGMKIiIiINMAQRkRERKQBhjAiIiIiDTCEEREREWmAIYyIiIhIAwxhRERERBpgCCMiIiLSAEMYERERkQYYwoiIiIg0wBBGREREpAGGMCIiIiINMIQRERERaYAhjIiIiEgDDGFEREREGmAIIyIiItIAQxgRERGRBhjCiIiIiDTAEEZERESkAYYwIiIiIg0whBERERFpgCGMiIiISAMMYUREREQaYAgjIiIi0gBDGBEREZEGGMKIiIiINMAQRkRERKQBhjAiIiIiDTCEEREREWmAIYyIiIhIAwxhRERERBpgCCMiIiLSAEMYERERkQYYwoiIiIg0wBBGREREpAGGMCIiIiINMIQRERERaYAhjIiIiEgDDGFEREREGmAIIyIiItIAQxgRERGRBhjCiIiIiDTAEEZERESkAYYwIiIiIg1oGsJ+/vOfo7q6GjabDTabDTU1NXj77bfV7X6/H7t27UJmZiZSUlKwbds2OJ3OqH20t7dj69atsFgsyMnJwaOPPopwODzbL4WIiIhoUjQNYUVFRfjRj36EI0eOoKGhARs3bsTnPvc5nDx5EgDw8MMP480338Trr7+O9957D52dnbjzzjvV50ciEWzduhXBYBCHDx/Gq6++ildeeQV79+7V6iURERERTYigKIqidScul5GRgWeeeQZ33XUXsrOzceDAAdx1110AgDNnzmDJkiWora3Fhg0b8Pbbb+OOO+5AZ2cncnNzAQAvvvgivvOd76CnpwcGg2FCx/R4PLDb7XC73bDZbDP22oiIiIhGJc2csEgkgl/96lcYHh5GTU0Njhw5glAohE2bNqmPqaysRElJCWprawEAtbW1WL58uRrAAGDz5s3weDzqaFosgUAAHo8n6ouIiIhoNmkewhobG5GSkgKj0Yivf/3r+N3vfoeqqio4HA4YDAakpaVFPT43NxcOhwMA4HA4ogLY6PbRbfE89dRTsNvt6ldxcXGCXxURERHR+DQPYYsXL8axY8dQV1eHnTt3YseOHTh16tSMHnPPnj1wu93q14ULF2b0eERERERX0mndAYPBgEWLFgEA1qxZg/r6ejz33HP44he/iGAwCJfLFTUa5nQ6kZeXBwDIy8vDBx98ELW/0bsnRx8Ti9FohNFoTPRLISIiIpowzUfCriTLMgKBANasWQO9Xo93331X3dbU1IT29nbU1NQAAGpqatDY2Iju7m71Me+88w5sNhuqqqpmve9EREREE6XpSNiePXuwZcsWlJSUYHBwEAcOHMChQ4fwxz/+EXa7Hffffz8eeeQRZGRkwGazYffu3aipqcGGDRsAALfffjuqqqpw77334umnn4bD4cBjjz2GXbt2caSLiIiIkpqmIay7uxtf/vKX0dXVBbvdjurqavzxj3/Epz71KQDAs88+C1EUsW3bNgQCAWzevBkvvPCC+nxJkvDWW29h586dqKmpgdVqxY4dO7Bv3z6tXhIRERHRhCRdnTAtsE4YERERzbakmxNGREREdC1gCCMiIiLSAEMYERERkQYYwoiIiIg0wBBGREREpAGGMCIiIiINMIQRERERaYAhjIiIiEgDDGFEREREGphSCHvttddw4403oqCgAG1tbQCAn/70p/j973+f0M4RERERzVeTDmE///nP8cgjj+Azn/kMXC4XIpEIACAtLQ0//elPE95BIi289NJL2LhxI1566SWtu0JESYznCpqOSYewn/3sZ/jFL36B733ve5AkSW1fu3YtGhsbE9o5oskKhUKQZXla+3C5XNi/fz9kWcb+/fvhcrkS1LvEiUQiCIfDWneDKCkk4n0vyzJCodCknuNyufDaa69BlmW89tprSXmuoOSmm+wTWlpasGrVqjHtRqMRw8PDCekU0WQ5nU6cPn0ag4OD0Ol0KC0tRWVlJURx8lfcH3/8cfWELssy9u7di+effz7RXZ4Sv9+PxsZGOJ1OKIqC7OxsLF++HFarVeuuEc2acDiM9vZ2NDc34+LFizCZTEhNTUVRURGWLl0KnW7if9oURUFTUxNaW1sRCoVgtVpRWVmJgoKCqz53z549Ud9/97vfxQsvvBDzGJ2dnXA4HBAEAYWFhcjNzZ1wH2n+mnQIKysrw7Fjx1BaWhrVfvDg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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8FIo9tD1FQ0u", + "outputId": "b8761d55-6258-405e-934f-97d477538e9b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 426 + } + }, + "source": [ + "boxplot_sobreviveu(df_titanic, 'age')" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fCqj102y9Kfo", + "outputId": "e3580cba-ce0b-4a2b-cdaf-e3421d9ef741", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "# Descrever o dataframe, variável 'fare'\n", + "df_titanic_ss['fare'].describe()" + ], + "execution_count": 11, + "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": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SMcvIb1K_69n", + "outputId": "975fc065-ffdd-4e67-f3c0-103d02276998", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + } + }, + "source": [ + "plt.scatter(range(df_titanic_ss.shape[0]), np.sort(df_titanic_ss['fare'].values)) ## está mexendo com o dataframe normalizado\n", + "plt.xlabel('index')\n", + "plt.ylabel('Fares')\n", + "plt.title(\"Distribuição da variável Fare\")\n", + "\n", + "sns.despine()" + ], + "execution_count": 12, + "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+/PFHtWrVyq0FAgCAulVQaLQtJUNpjlPKyD2tiJBARYUESjYpPSvPuS06LEi92kbI38/m6ZIlVTPUPP/885oyZYqWL1+uBQsWqGXLlpKkjz/+WEOHDnVrgQAAoPYUDzBHM0/p/d2/KCP3dKXeH2MP0uwRCRraOaaWK62YzRhjPF1EXcnKypLdbpfD4VBYWJinywEAwKNWJ6Vq7sq9SnXk1eg4NkkLburh8WBT7XlqkpOT9cADD2js2LFKT0+X9HtLzZ49e9xWHAAAqB2rk1I1ecmuGgeaInNX7lVBoWfbSaoVajZu3KguXbroq6++0ooVK5STkyNJ+uabbzR79my3FggAANyroNBo7sq9clcEMZJSHXnalpLhpiNWT7VCzcyZM/XII49o7dq1CggIcG4fPHiwtm7d6rbiAACA+21LyXBbC8250rPdf8yqqFao+e677zRq1KgS26OionT8+PEaFwUAAGpPbYWPqNCgWjluZVUr1ISHhys1NbXE9q+//tp5JxQAAPBO7g4fNv1+F1SvthFuPW5VVSvUjBkzRjNmzFBaWppsNpsKCwu1efNm3XvvvbrlllvcXSMAAHCjXm0jFGN3b7CZPSLB4/PVVCvUzJs3T506dVJsbKxycnKUkJCggQMHqm/fvnrggQfcXSMAAHAjfz+bZo9IkDsiSIw9yCtu55aqMU+NMUZHjhxRZGSkjh8/ru+++045OTnq3r27OnToUFt1ugXz1AAA8F/lzVMTEdxQV3VroVZNGvvMjMJVDjWFhYUKCgrSnj17vD7EFEeoAQDUZ766/EFlVXmZBD8/P3Xo0EEnTpzwuVADAEB9VV6rTNFSB7f1iPdAZe5TrTE1jz32mO677z4lJSW5ux4AAOBmFc0enOrI0+Qlu7Q6qeSdzb6kWms/NWnSRCdPntTZs2cVEBCgRo0aubyekeHZGQXLQvcTAKC+KSg06v+3dRVOtmeTFG0P0hczBvtct1ORaq3S/cwzz7i7DgAAUAsqO3vwuUsd9GnXtPYLqwXVCjXjxo1zdx0AAKAWVHX2YE8vdVAT1Qo158rLy9Pp06ddttG1AwCAd6jq7MGeXuqgJqo1UDg3N1d33nmnoqKiFBwcrCZNmrg8AACAd6js7MHestRBTVQr1PzlL3/RunXrtGDBAgUGBurll1/W3Llz1aJFC73++uvurhEAAFRTVWYP9oalDmqiWnc/tW7dWq+//roGDRqksLAw7dq1S+3bt9cbb7yht956Sx999FFt1Fpj3P0EAKivKjNPjTcsdVAT1RpTk5GRofj43yfoCQsLc97C3b9/f02ePNl91QEAALcY2jlGf0yILjGjsK/OHlyaanU/xcfHKyUlRZLUqVMnLVu2TJK0cuVKhYeHu6+6c8yfP18XX3yxQkNDFRUVpZEjR2rfvn218lkAAFiRv59Nfdo11agerXTbgHiN6t5Sfdo1tUSgkaoYan766ScVFhZqwoQJ+uabbyRJM2fO1AsvvKCgoCDdc889uu+++2ql0I0bN2rq1KnaunWr1q5dqzNnzuiyyy5Tbm5urXweAADwLVUaU+Pv76/U1FRFRUVJkpz9JE0AAB9YSURBVEaPHq1nn31WeXl52rlzp9q3b6+uXbvWWrHn+vXXXxUVFaWNGzdq4MCBlXoPY2oAAPVFaYtXWqmrqTRVGlNTPP989NFHmj9/vuLj4xUXF+fWwiricDgkSRERZd96lp+fr/z8fOfzrKysWq8LAABPqw+DgktTrTE1nlZYWKhp06apX79+6ty5c5n7zZ8/X3a73fmIjY2twyoBAKh79WXxytJUKdTYbDbZbLYS2+ra1KlTlZSUpLfffrvc/WbNmiWHw+F8HDlypI4qBACg7hUUGs1duVeVGVcyd+VeFRRWeVYXr1bl7qfx48crMDBQ0u9LJNxxxx0KDg522W/FihXuq7CYO++8Ux9++KE2bdqkVq1albtvYGCgs1YAAKyuPi1eWZoqhZriC1nedNNNbi2mPMYY3XXXXXr33Xe1YcMGtW3bts4+GwAAX1CfFq8sTZVCzaJFi2qrjgpNnTpVb775pt5//32FhoYqLS1NkmS329WoUSOP1QUAgLeoT4tXlsZnBgovWLBADodDgwYNUkxMjPOxdOlST5cGAIBXqE+LV5amWsskeEI1lqgCAKBeKVq8cvKSXRUOFvb1xStL4zMtNQAAoGJDO8dowU09ymyxibEHacFNPSw5T021Vun2VcwoDADwdaXNFBwVEijZpPSsvHK3MaMwAADwCuXNFFyaotmDb+sRX8uVeQe6nwAA8AEVzRRcGivPHlwaQg0AAF6uKjMFl8aKsweXhlADAICXq+xMwaU5d/ZgqyPUAADg5dwx86/VZg8uDaEGAAAv546Zf602e3BpCDUAAHi5ys4UXBqrzh5cGkINAABermim4OrOLmPF2YNLQ6gBAMAHVDRTcGmsPHtwaZhRGAAAH1LZGYWtPntwaZhRGAAAH+LvZ1Ofdk09XYZXovsJAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYAqEGAABYQgNPFwAAAMpXUGi0LSVD6dl5igoNUq+2EfL3s3m6LK9DqAEAwIutTkrV3JV7lerIc26LsQdp9ogEDe0c48HKvA/dTwAAeKnVSamavGSXS6CRpDRHniYv2aXVSakeqsw7EWoAAPBCBYVGc1fulSnltaJtc1fuVUFhaXvUT4QaAAC80LaUjBItNOcyklIdedqWklF3RXk5Qg0AAF4oPbvsQFOd/eoDQg0AAF4oKjTIrfvVBz4VajZt2qQRI0aoRYsWstlseu+99zxdEgAAblFQaLQl+YTe3XVUr3z+k37JPKWI4IAy97fp97ugerWNqLsivZxP3dKdm5urbt266dZbb9XVV1/t6XIAAHCL0m7bLk/RDDWzRyQwX805fCrUDBs2TMOGDfN0GQAAVNm5E+g1Cw6UbFJ6Vp42Hziu5bt+rtKxwhs31PyruzBPTTE+FWqqKj8/X/n5+c7nWVlZHqwGAFBfVbUlpiKBDfz0x4RotxzLSnxqTE1VzZ8/X3a73fmIjY31dEkAgHqmrAn0aiItK59buUth6VAza9YsORwO5+PIkSOeLgkAUI8UFBrN+aD0CfRqilu5S7J091NgYKACAwM9XQYAoJ56ft1+pWXVTvjgVu6SLB1qAADwlNVJqXr60/1uP65NUjS3cpfKp0JNTk6ODhw44HyekpKi3bt3KyIiQq1bt/ZgZQAA/FfRuk3uxq3c5fOpULNjxw794Q9/cD6fPn26JGncuHFavHixh6oCAMBVRes2VVe0PUizRyRwK3cZfCrUDBo0SMawGikAwLvVdBDvtT1aql+HSEWF/D6fzfGcfEWF/t7lRAtN2Xwq1AAA4AuqO4g3hpaYGiHUAADgJkWzBv/y20mFBjVQdt7ZMvdt0rihHhieoMyTpxUREqjoMFpiaopQAwBANRQFmDTHKWXkntbRzFN6f/cvysg9Xe77iiILyxy4H6EGAIAqqsmyBwz2rT2EGgAAqqBo2YPq3LYSEdxQG+/7gwIaWHpCf4/hWwUAoJKK5p+p7n24GblntPPQb26tCf9FqAEAoJLcMf8MazbVHkINAACV5I5AwppNtYcxNQAAVFJNAglrNtU+WmoAAKikXm0jFGOvfrBhzabaRagBAKCS/P1smj0iQVWNJTH2IC24qQe3cdcyup8AADhH8Un1IkICnWswpWflKSP3tMb3a1PmRHsRwQ11VbcWatWkMTMF1zFCDQAA/6eqk+oRYLyLzdSjZa+zsrJkt9vlcDgUFhbm6XIAAF6kupPq2SS6lrwEY2oAAPVeTSfVm7tyrwoK600bgdci1AAA6r2aTKpnJKU68rQtJcO9RaHKGFMDAKh3ig8GPnjiZI2PyUzBnkeoAQBYTlFoSc/OU7Ng1zuXjmaeKvPOpZpgpmDPI9QAACylqncw1RQzBXsPQg0AwKed2yqT8muunvlsf53XwEzB3oFQAwDwSQWFRs+vO6BFm1OUeeqMR2qIsQdp9ogEbuf2EoQaAIDPWZ2UqpkrvlPmyboJM1MGxatf+0jnuBwm2vNOhBoAgE9ZnZSqO5bsqtPPHNAhSn3aNa3Tz0TVEWoAAD6jaJK8usIgYN/C5HsAAJ9Rk0nyqqqoU4lBwL6DlhoAgM+oywnuohkE7HMINQAAn+HOCe6Kr7AdFfL7JH3Hc/IVFcogYF9EqAEA+IxebSMUYw9SmiOvSotPTru0veKaBnPnksURagAAPsPfz6bZIxI0ecku2aQKgw3zyNQvhBoAgNcrvgDl+H5tSqzfFN6oocb1jVOvtk3pQqqnCDUAAK9SPMCUtwBlRHBDjbqwpRITogkwINQAAGpPeatlnzs4t7oraGfkntGrmw/qYgINRKgBANSSulwte+7KvfpjQjTBpp4j1AAAaqR4d1FESKAOHa+71bKNpFRHnralZLCUQT1HqAEAVFtdtsZUpC4n5oN3ItQAAJyqMgZm84HjWr7rZ0+X7OTOifngmwg1AAAVFBo9v+6AFm1OUeapM54up0pYdBJFCDUAUM+tTkrVzBXfKfOkb4WZc7HoJCRCDQD4tKreMu3tXUhVxYzBOJfPhZoXXnhBTzzxhNLS0tStWzc999xz6tWrl6fLAoAqK+2uoYpCyLnbth/M0OIvD/pcd1F1FV+AkvWbUJxPhZqlS5dq+vTpevHFF9W7d28988wzGjJkiPbt26eoqChPlwcAkioXVqo6yVx9Q4BBddiMMVVZ6NSjevfurYsvvljPP/+8JKmwsFCxsbG66667NHPmzArfn5WVJbvdLofDobCwsNouF0A9UhRk1u5N03uElTIVXy27tFYoAgyqy2daak6fPq2dO3dq1qxZzm1+fn5KTEzUli1bSn1Pfn6+8vPznc+zsrJqvU4A9Y83zdXirRj7grrgM6Hm+PHjKigoUPPmzV22N2/eXD/88EOp75k/f77mzp1bF+UBqAc8PXOuL7i2R0v16xDpbIFhtWzUJZ8JNdUxa9YsTZ8+3fk8KytLsbGxHqwIgK+oykrRoCUG3sFnQk2zZs3k7++vY8eOuWw/duyYoqOjS31PYGCgAgMD66I8ABZCd5IU3qihxvWNU6+2TSu8E4sxMPAWPhNqAgICdNFFF+mzzz7TyJEjJf0+UPizzz7TnXfe6eHqAPiyc1tlfH3eFne4J7GD7hzcgZACn+MzoUaSpk+frnHjxqlnz57q1auXnnnmGeXm5mrChAmeLg2Aj6JV5r/oQoKv86lQM3r0aP3666966KGHlJaWpgsvvFCrV68uMXgYACpStNbR05/+6OlS3KIq3UV0IcGqfGqemppinhoARWHm1S9+kiPvrKfLKTHJXFVmFObuIsCVT7XUAEB1nDsx3rIdR5WTX/thxibplj5xah1RdlihdQRwL0INAEvz1JiZF27orsu7tqjTzwTqO0INAMspapn5ZE+qFn15qE4/m8G2gOcQagB4pequYF3bk+SVNQaGsS2A5xFqAHict8/eWzT1P2NgAO9GqAFQZdVtRfFEy0pN0JUE+BZCDVDPFQWU9Ow8NQv27RDiDrTKAL6LUAPUA2W1rGw/mKHFXx5U5qkzni7R45o0bqj5V3ehVQbwYYQawOJYBqB84Y0aakK/Nqx1BFgAoQawsNVJqZq8ZJfqzbThlWSTNL5vG112QTRdTICFEGoAiyooNJq7ci+BphRMjAdYE6EGsKhtKRl0ORXD3UyAtRFqAItKz67fgab4JHnczQRYH6EGsKio0CBPl1Bj1V3BmgAD1E+EGsDHVHZembTMUwoNaqDsvNpfkdodaFkBUFOEGsBHFBQaPb/ugBZtTvGKeWWq24pCywqA2kKoAXzA6qRUzVzxnTJP1l6YCW/UUOP6xqlX26aEEAA+iVADeImyupU2Hziu5bt+dtvnhAb5a+6IzmoeFsTq0gAshVADeEDxAFOXyxVk5xUoJryR+rRrWuufBQB1iVAD1CFvGRdT32/3BmBNhBrUa1Vdobom245mntI7O44qJ9/zdyNZ4XZvACiOUIN6w5NdPt7CJina/vv4GQCwGkINLIkAU7bZIxIYEAzAkgg1qJSikJDmOFUrXTOV3RbeOECZJ8vfnwBTOtY9AmB1hBpUaHVSquau3MviiF6GeWUAwBWhBuVanZSqyUt2yXi6ELi4J7GD7hzcgZACAOcg1KBMBYVGc1fuJdB4EbqQAKBshBqUaVtKBl1OHlBWtxJdSABQPkINysQEbbXv3ADDcgUAUDOEGpRQdKfTj2nZni7FkiKCG2rUhS2VmBBNgAEANyLUwEV9vdOpKncS1WQbXUgAUHsINRZVnXll3L0atLeiywcArIlQYwHFA8zRzFN6f/cvysg97enSPI4AAwD1B6HGS1R3xl5PBZipg9qpb7tmXjmjsGwiwABAPUSo8QK+OI7lvOhQ9evQzNNlAADgRKipZRW1wPjqOJao0CBPlwAAgAtCTS3yxRaYitgkRdt/79YBAMCbEGpqQUGh0fPrDujpT3/0dCm1YvaIBMapAAC8DqHGzVYnpWrOB3uUlpXv6VLcjnWHAADezGdCzaOPPqpVq1Zp9+7dCggIUGZmpqdLKsGKK1pf26Ol+nWIZNI4AIDX85lQc/r0aV133XXq06ePXnnlFU+X43TuQOD/XfW9ZQINrTIAAF/jM6Fm7ty5kqTFixd7tpBzePtA4IjghrqqWwu1atKYqfwBAJbnM6GmOvLz85Wf/9+xLVlZWW47trd1NRUPMAQTAEB9Y+lQM3/+fGcLjzsVFBrNXbm31gJN0TgWWlYAAKg8j4aamTNn6m9/+1u5+3z//ffq1KlTtY4/a9YsTZ8+3fk8KytLsbGx1TrWubalZNRKlxPjWAAAqD6Phpo///nPGj9+fLn7xMfHV/v4gYGBCgwMrPb7y5KeXb1AU14LDK0tAADUjEdDTWRkpCIjIz1ZQrVUZ4mAexLP058SO9RCNQAAQPKhMTWHDx9WRkaGDh8+rIKCAu3evVuS1L59e4WEhNRpLb3aRijGHqQ0R16lxtVEhwXqzsHta70uAADqMz9PF1BZDz30kLp3767Zs2crJydH3bt3V/fu3bVjx446r8Xfz6bZIxIk/b4WUlls//eYc+UFdCsBAFDLbMYYb7krudZlZWXJbrfL4XAoLCysxseraJ4aBv4CAFB3CDU1VDSjcHp2npoF/z4A+HhOvqJCGfgLAEBd8pkxNd7K38+mPu2aeroMAADqPZ8ZUwMAAFAeQg0AALAEQg0AALAEQg0AALAEQg0AALAEQg0AALAEQg0AALAEQg0AALAEQg0AALCEejWjcNGKEFlZWR6uBAAAVFVoaKhstrKXH6pXoSY7O1uSFBsb6+FKAABAVVW0dmO9WtCysLBQv/zyS4VJr6qysrIUGxurI0eOuG2hTF9RX8+d8+a864v6eu6ct3eeNy015/Dz81OrVq1q7fhhYWFe+UtQF+rruXPe9Ut9PW+p/p475+1bGCgMAAAsgVADAAAswX/OnDlzPF2EFfj7+2vQoEFq0KBe9ehJqr/nznlz3vVFfT13ztv3zrteDRQGAADWRfcTAACwBEINAACwBEINAACwBEINAACwBEKNG7zwwgtq06aNgoKC1Lt3b23bts3TJbnV/PnzdfHFFys0NFRRUVEaOXKk9u3b57LPoEGDZLPZXB533HGHhyp2jzlz5pQ4p06dOjlfz8vL09SpU9W0aVOFhITommuu0bFjxzxYsfu0adOmxLnbbDZNnTpVknWu96ZNmzRixAi1aNFCNptN7733nsvrxhg99NBDiomJUaNGjZSYmKj9+/e77JORkaEbb7xRYWFhCg8P12233aacnJy6PI0qK++8z5w5oxkzZqhLly4KDg5WixYtdMstt+iXX35xOUZpvyOPPfZYXZ9KlVR0vcePH1/inIYOHeqyjy9eb6nicy/t791ms+mJJ55w7uML15xQU0NLly7V9OnTNXv2bO3atUvdunXTkCFDlJ6e7unS3Gbjxo2aOnWqtm7dqrVr1+rMmTO67LLLlJub67LfxIkTlZqa6nw8/vjjHqrYfS644AKXc/riiy+cr91zzz1auXKl3nnnHW3cuFG//PKLrr76ag9W6z7bt293Oe+1a9dKkq677jrnPla43rm5uerWrZteeOGFUl9//PHH9eyzz+rFF1/UV199peDgYA0ZMkR5eXnOfW688Ubt2bNHa9eu1YcffqhNmzZp0qRJdXUK1VLeeZ88eVK7du3Sgw8+qF27dmnFihXat2+frrzyyhL7Pvzwwy6/A3fddVddlF9tFV1vSRo6dKjLOb311lsur/vi9ZYqPvdzzzk1NVWvvvqqbDabrrnmGpf9vP6aG9RIr169zNSpU53PCwoKTIsWLcz8+fM9WFXtSk9PN5LMxo0bndsuueQS86c//cmDVbnf7NmzTbdu3Up9LTMz0zRs2NC88847zm3ff/+9kWS2bNlSVyXWmT/96U+mXbt2prCw0Bhjzestybz77rvO54WFhSY6Oto88cQTzm2ZmZkmMDDQvPXWW8YYY/bu3Wskme3btzv3+fjjj43NZjM///xz3RVfA8XPuzTbtm0zksyhQ4ec2+Li4szTTz9d2+XVmtLOe9y4ceaqq64q8z1WuN7GVO6aX3XVVWbw4MEu23zhmtNSUwOnT5/Wzp07lZiY6Nzm5+enxMREbdmyxYOV1S6HwyFJioiIcNn+73//W82aNVPnzp01a9YsnTx50hPludX+/fvVokULxcfH68Ybb9Thw4clSTt37tSZM2dcrn2nTp3UunVry13706dPa8mSJbr11ltdFpKz4vU+V0pKitLS0lyusd1uV+/evZ3XeMuWLQoPD1fPnj2d+yQmJsrPz09fffVVnddcWxwOh2w2m8LDw122P/bYY2ratKm6d++uJ554QmfPnvVQhe6zYcMGRUVFqWPHjpo8ebJOnDjhfK2+XO9jx45p1apVuu2220q85u3X3PemC/Qix48fV0FBgZo3b+6yvXnz5vrhhx88VFXtKiws1LRp09SvXz917tzZuf2GG25QXFycWrRooW+//VYzZszQvn37tGLFCg9WWzO9e/fW4sWL1bFjR6Wmpmru3LkaMGCAkpKSlJaWpoCAgBL/yDdv3lxpaWkeqrh2vPfee8rMzNT48eOd26x4vYsruo6l/X0XvZaWlqaoqCiX1xs0aKCIiAjL/B7k5eVpxowZGjt2rMsCh3fffbd69OihiIgIffnll5o1a5ZSU1P11FNPebDamhk6dKiuvvpqtW3bVsnJybr//vs1bNgwbdmyRf7+/vXiekvSa6+9ptDQ0BLd6b5wzQk1qJKpU6cqKSnJZWyJJJc+5S5duigmJkaXXnqpkpOT1a5du7ou0y2GDRvm/Llr167q3bu34uLitGzZMjVq1MiDldWtV155RcOGDVOLFi2c26x4vVHSmTNndP3118sYowULFri8Nn36dOfPXbt2VUBAgP7nf/5H8+fPV2BgYF2X6hZjxoxx/tylSxd17dpV7dq104YNG3TppZd6sLK69eqrr+rGG29UUFCQy3ZfuOZ0P9VAs2bN5O/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": "15cc9af9-d48d-4354-b409-26a0b3446f7b", + "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": null, + "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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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "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": "dcd9091c-3c1d-4388-caaf-efb28f8eba55", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 170 + } + }, + "source": [ + "# Distribuição da variável 'age'\n", + "df_titanic_ss['age'].describe()" + ], + "execution_count": 13, + "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": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "h9ZmvO1b_4sF", + "outputId": "a5ca3bfd-2d10-4f88-88c0-01d58d543c16", + "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": 14, + "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": "7355ec62-b4d1-4586-d92c-3f7f2b16f222", + "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": 15, + "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": "3abad211-8b21-4a78-ea46-0e3587866c92", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "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": 16, + "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": "7ea4f291-c983-4736-b0c7-2b18a65c17e8", + "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": 17, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2IAAAFzCAYAAABcurqFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdd3hUZfbA8e/UTHohHQIhEAi9KoJldWEFWRWUVcSCIOhPBFFxRWGxgYKLiCBiL6grttVFQUUBRRERFAGpkRIgpENIz2Ta/f0xJQkpZJKZ1PN5nnkkd255bxLwnjnnPa9KURQFIYQQQgghhBCNRt3UAxBCCCGEEEKItkYCMSGEEEIIIYRoZBKICSGEEEIIIUQjk0BMCCGEEEIIIRqZBGJCCCGEEEII0cgkEBNCCCGEEEKIRiaBmBBCCCGEEEI0MgnEhBBCCCGEEKKRaZt6AK2BzWYjPT2dwMBAVCpVUw9HCCGEEEII0UQURaGwsJDY2FjU6przXhKIeUB6ejpxcXFNPQwhhBBCCCFEM5GamkqHDh1qfF8CMQ8IDAwE7N/soKCgJh6NEEIIIYQQoqkUFBQQFxfnihFqIoGYBzjLEYOCgiQQE0IIIYQQQpx3ypI06xBCCCGEEEKIRiaBmBBCCCGEEEI0MgnEhBBCCCGEEKKRyRwxIYQQQgjRaimKgsViwWq1NvVQRCuh0WjQarUNXrZKAjEhhBBCCNEqmUwmMjIyKCkpaeqhiFbGz8+PmJgY9Hp9vc8hgZgQQgghhGh1bDYbKSkpaDQaYmNj0ev1Dc5gCKEoCiaTiZycHFJSUkhMTKx10ebaSCAmhBBCCCFaHZPJhM1mIy4uDj8/v6YejmhFfH190el0nDhxApPJhMFgqNd5pFmHEEIIIYRoteqbrRCiNp74vZLfTCGEEEIIIYRoZBKICQGYLDYURWmSax/JLiKnsKxJri2EEEIIIZqGzBFrjfLzwWyu+/46HQQH1+9ctR3rbeeOrR5jMVlsvLT5CC9tPsrNF3bkiWt7eXiQtdt54iw3vrqNblGBfH3fpZ45qbs/fyGEEKI1MpvBarX/V6Np6tG0GZePGEH/fv1Y9txzjXthlQq0LSu0aVmjFeeXnw+vvmr/b10FB8P//V/VIKYu56rpWG+rbmxujmV3ah4P//cPkrMKAfhmf2ajBmJmq41//W8vVpvCocwCyixWfLQN/B9FfX7+QgghRGsUEACXXw65uS3uAb1FM5mgpASysxv3uhoNhIe3qJ91yxmpqBuz2f4Q7usLdekQVFJScwblfOeq7VhvO3dsbo7l2W8O8fLmo9gUCPPXk1tsIiPfSH6JmWA/nZcHb7dq63EOZdqDQEWBjDwj8eH+DTupuz9/IYQQorXy9QW12v6SjFjjUansr8b8ntts9uxnPaaZmM1mdLrGefY7lwRirZWfn/2ToLooLa3/uc53rLdVHFsdx7IvLZ+V3x8F4PoB7Xn06p78/YUtpOcbOZRZwJCEdt4arUt6XinPb/wTALUKbAqk5ZU2PBBzcufnL4QQQrRGPj7lAYEjKFAUhVKLrdGH4qtV13kNs/XffcdTS5ey79AhNBoNQwcPZvlTT9Glc2cAjp88SefBg/n0rbdY8eabbP/9dxI7d+aVZ59l6AUXuM7z6dq1PLZ4MUdSUoiJiuLeKVN48J57XO/HDxrE1Ftu4c+jR/nsyy9pFxbGioULGTp4MFNnzWLTjz+S0KkTby1fzuD+/QE4k5vLjDlz+HHbNs7m59MlPp65993HhOuvL78BlcoV/M5fsoSPv/iCfT/+WOke+19xBdeMHMmCRx6pcv9n8/KY8cgjfPvDDxQVF9MhJoa599/P5AkTADiVns5DTz7JN99/T5nJRI/ERFYuXMiQfv0AePnll1myZAmpqal07tyZefPmcdttt1UYnoqXXnqJr7/+mk2bNvHQQw/xxBNP8Pnnn/Pkk09y4MABYmNjuf322/nXv/6F1osZNgnERJvjzEINTWjH0vH2f1iSYoJIzzeSnFXYKIHYk2v3U2KyckF8KAadhi2HT5N2tomDWiGEEKKVK7XY6PnCzka/7oGZg/DT1S1DVFxczKy776Zvz54UFRfz2OLFXDdpEru//75Sy/R/LVrEkieeIDEhgX8tXMiEu+/myPbtaLVadu7Zw4133skTDz3E+LFj+fnXX7nn4YdpFxbGpJtucp3j+VdfZeHcuTz64IM8/8or3DZ9OsMuuIA7br6ZZx9/nIfnz2fijBns37IFlUqFsayMQX378vCMGQQFBvLlxo3cNn06XeLjuXDgwCr3csfNN/PkkiX8umsXFwwYAMCuvXv548ABPnv77Wrv/9FnnuHAn3/y9QcfEB4WxpGUFEqNRgCKior4y5gxtI+J4Yt33yU6MpLf9+7FZrMH1/9bs4b77ruPZcuWMWLECNatW8fkyZPp0KEDV1xxhesaTzzxBM888wzLli1Dq9WyZcsWJk6cyAsvvMCll17K0aNHueuuuwB4/PHH6/Rzqw8JxESbk3K6CIAukeXZp+7RgXx3KNsVpHnTxgNZfLM/C61axVNj+/DOtuMAnDpb4vVrCyGEEKJ5G3fNNZW+fmvZMiJ69OBAcjK9e/Rwbf/nPffw97/9DYAnZ8+m16WXciQlhaTERJa+/DLDL72URx98EIBuXbpwIDmZZ1eurBSIjR4+nP+7/XYAHnvwQV5etYoL+vfnhmuvBeDhe+9l6OjRZGVnEx0VRfuYGP45fbrr+HunTuWb77/n488/rzYQ6xAby8grruDtDz5wBWJvf/ABfxk2jIT4+Grv/2RaGgP69HFl4eI7dnS9t/qzz8g5c4Zfv/2WsNBQALomJNjLEq1Wljz/PJMmTeIeR+Zv1qxZ/PLLLyxZsqRSIHbzzTczefJk19d33HEHjzzyCLc7vhcJCQksWLCA2bNnSyAmhCelnC4GoHN4eeleUnQgAMleDsSsNoUn1u4HYMqlnekeHUj7EF8ATuVJRkwIIYTwJl+tmgMzBzXJdevq8LFjPPbvf7N9505O5+a6sj0n09IqBWJ9e/Z0/TkmKgqA7NOnSUpM5ODhw4wZNarSeS++8EKWvfYaVqsVjaNUs+I5oiIjAehTcVtEhOu80VFRWK1WFi5bxsdffEFaRgYmk4kykwk/X98a7+fOW2/ljvvvZ+n8+ajValZ/9hnPz59f4/7TJk1i3B138Psff3Dl5Zcz9qqrGHbhhQDs3rePAX36uIKwcx08dIi7/u//Kt/3xRezfPnyStsGDx5c6es9e/awdetWnn76adc2q9WK0WikpKQEPy/Nu5dATLQ5x3LsgVhCRHlGLCk6CLAHYoqi1LmO210nc0s4dbYUg07NfcMTAegQav/HS0oThRBCCO9SqVR1LhFsKtfceiudOnTg9aVLiY2Oxmaz0fuyyzCZTJX201WYu+R8bnEGbXVVsUmF8xy1nffZlStZ/vrrLFuwgD49euDv58f9jz5aZWyV7mfkSHz0ev731VfodTrMZjP/OCfrV9FVw4dzYudOvtq4kQ0//MDwf/yD6ZMns+TJJ/E1GNy6v5r4+1eek19UVMSTTz7J9RXnujkYPHTN6siCzqJNsdkUV0YsoUJjjIQIf3QaFUVlFk55MSA6fsZ+7fh2/vjp7f/QOQMxb15XCCGEEM3fmdxcko8cYd6sWQy/7DJ6dOvG2bw8t8/TIzGRrTt2VNq2dccOunXp4sqG1cfWHTsYM2oUt95wA/169yYhPp4/jx6t9RitVsvt48fz9gcf8PaHH3LT2LH41pJBA4gID+f2m27iPy+/zLIFC3jtvfcAewZv97595J49W+1xPZKS2Lp1a+Uxb91KzwpZvuoMHDiQ5ORkunbtWuVVcV6ep0lGTLQpGQVGyiw2dBqVqyQQQKdR0yUigEOZhSRnFhIX5p0U9PHT5YGYU/sQ+7UyC4xYrDa0Gvl8RAghhGiLQkNCaBcWxmvvvktMZCQn09J45Kmn3D7Pg/fcwwVXXsmC555j/NixbPv1V1586y1e+ve/GzS+xM6d+e+6dfy8YwehISEsfeUVsnJy6NmtW63HTb31VnpcfDEAW9etq3Xfx555hkH9+tGre3fKTCbWbdhAD8f5J1x/PQuXL2fs7bez6F//IiYqil179xIbGcnQAQN4aNYsbrz5ZgYMGMCIESNYu3Ytn332GRs3bqz9mo89xtVXX03Hjh35xz/+gVqtZs+ePezbt4+n6vH9ryt54hNtSoqjLLFjmF+VgMc1TyzLe/PEnIFYp/DyQC8y0AedRoXVppBVWOa1awshhBCieVOr1Xz46qvs/OMPev/lLzzw6KM8W49mEQP79uXj11/nwzVr6H3ZZTy2eDHzZ8+u1KijPubNmsXAPn0YOX48l48dS3RkJGOvuuq8xyUmJDDsggtISkxkyKDa5+jp9XrmPP00fa+4gsvGjEHj+J443/v244+JDA9n9M030+fyy3lmxQpXlm/smDEsX76cJUuW0KtXL1599VXefvttLr/88lqvOXLkSNatW8e3337LBRdcwEUXXcTzzz9Pp06d6vaNqSfJiIk25ZijY2JCRNU1trpHBwHpHMwo8Nr1j5+xd0bsXCEjplariA3x5cSZEk7lllTK1AkhhBCibRnxl79w4KefKm1TsrNdf47v2LHS1wAhwcFVto275poqHRgrOr6zahv/c89x7rXCQkNZ8+67tY5/85o1Vc+rKKRnZnJPhU6FNZk3axbzZs2q8f1OcXH89623Km90dE0EmDZtGtOmTavxeKWGRZ9HjhzJyJEjzzs+T5KMmGhTXI06qlk4OSnG+50TXXPEzrm+M/hKk86JQgghhGhFck6f5sU33yQzO9u1KLOwk4yYaFPKW9dXE4g5ShOPnS6mzGLFR+vZrkpmq83VkKPiHDGQzolCCCGEaJ0ie/YkvF07XnvuOUJDQpp6OM2KBGKiTaktEIsOMhBk0FJgtHAku4hescEevfaps6VYbQoGnZqoIJ9K7zkbdkjnRCGEEEK0JueWO4pyUpoo2owyi5VTZ+1ztKqbI6ZSqUiKKV9PzNMqdkw8d52y9qFSmiiEEEII0ZZIICbajJNnSrApEOijJTxAX+0+rs6J3gjEzlRtXe9UvpZYicevK4QQQgghmp8WF4itXLmS+Ph4DAYDQ4YMYcc5i9Wd65NPPiEpKQmDwUCfPn346quvKr0/adIkVCpVpdeoUaO8eQuiiRxzliVGVM1IOXV3BGKHvJkRq6Ys0tmsIz3PiM1WfTcfIYQQQgjRerSoOWIfffQRs2bN4pVXXmHIkCEsW7aMkSNHkpycTGRkZJX9f/75ZyZMmMCiRYu4+uqrWb16NWPHjuX333+nd+/erv1GjRrF22+/7frax8enyrlEw206mMXetHwy841k5BvJKzEx9dIErukX2yjXd3ZMrG5+mFNStL008VCm51vYpzha18e3q7pYdHSwAbUKTFYbp4vKiAwyePz6QgghhBCi+WhRGbGlS5dy5513MnnyZHr27Mkrr7yCn58fb527loDD8uXLGTVqFA899BA9evRgwYIFDBw4kBdffLHSfj4+PkRHR7teoaGhjXE7bcq+tHymvPMbyzYe5sNfU/nhzxz2nMrn5c1HG20MKc41xMKrzg9zcmbEsgrKyCsxefT6J2poXQ+g06iJCbZnxVKlYYcQQgghRKvXYgIxk8nEzp07GTFihGubWq1mxIgRbNu2rdpjtm3bVml/sC/Wdu7+mzdvJjIyku7duzNt2jTOnDlT61jKysooKCio9BK125WaB9izQQ+M6Mbc0UkAHMkuwmK1NcoYUiqUJtYkwEfrmq/lyfLE2lrXO8laYkIIIUQjKSqCM2ca51VU1NR366KKjGSNY5rO8ZMnUUVGsnvv3iYelXsuHzuW++fNa+pheESLKU08ffo0VquVqKioStujoqI4dOhQtcdkZmZWu39mZqbr61GjRnH99dfTuXNnjh49yty5c7nqqqvYtm0bGk3160gtWrSIJ598soF31LYkO0r9RvWO4b4RidhsCss3HqbYZCXldDGJUYFeH4MzEKtuMeeKkqKDOHW2lEMZBVyU0M4j107NLcFqU/DVaaq0rnfqEOrLjuOylpgQQgjhVUVF8N57cPZs41wvNBRuuw0Caq7I8bQnFi9mzddfs/v772vcJ659ezL27iW8nWeedRrLZ2+/jU6na+pheESLCcS85aabbnL9uU+fPvTt25cuXbqwefNmhg8fXu0xc+bMYdasWa6vCwoKiIuL8/pYWzJnF0JnV0K1WkX36EB+P5nHwcxCrwdi+aVmThfZSw2rKw2sKCk6kI0HszyaETvhmB/WqZ1fjY1C2kvnRCGEEML7ysrsQZjBAL6+3r1Waan9WmVljRqI1YVGoyH6nISFu0wmE3p99Z2o67NfXYS1oilELaY0MTw8HI1GQ1ZWVqXtWVlZREdHV3tMdHS0W/sDJCQkEB4ezpEjR2rcx8fHh6CgoEovUTNFUVxBTVJMecDlXLPrUIb3Szud2bDIQB8CfGr//KFXrH1cf5zK9/j1aypLBClNFEIIIRqVry/4+3v3VY9Ar6ysjJlz5xLZsyeGuDguufpqft21y/X+qg8/JKRr10rHrPnqK1SOxnWrPvyQJ5csYc/+/agiI1FFRrLqww+rXKe60sR9Bw9y1U03ERAfT1TPntx2zz2crjBl5/KxY5nxyCPcP28e4UlJjBw/vtp7mHTvvYydOJGnn3+e2D596D5sGACpaWncOHUqIV27EtatG2MmTuT4yZOu4ywWCzPnziWka1fade/Ow/Pnc/uMGYydOLHSGCqWJp7Ny2PivfcS2qsXfsHBXHXVVRw+fLj8+7VqFSEhIXzzzTf06NGDgIAARo0aRUZGRu0/iEbQYgIxvV7PoEGD2LRpk2ubzWZj06ZNDB06tNpjhg4dWml/gA0bNtS4P8CpU6c4c+YMMTExnhm4ID3fSKHRglatqtQoo4cXW8Wfy9Woo5b5YU79O4YAkJxVSKnJ6pHr19aow6lDqL2bopQmCiGEEG3X7Pnz+XTdOt5ZsYLfN26ka+fOjBw/ntw6llKOHzOGB6dNo1dSEhl795Kxdy/jx4w573F5+fn8ddw4BvTpw28bNrD+o4/IysnhxjvvrLTfOx99hF6nY+u6dbzy7LM1nm/Tli0kHznChk8+Yd1//oPZbGbk+PEEBgSw5Ysv2LpuHQF+foy66SZMJnvV0r9XrOD9Tz/l7eXL2bpuHQWFhaz5+utaxz1p5kx+27OHL956i20//oiiKIwePRqz2ezap6SkhCVLlvDee+/x448/cvLkSf75z3+e93vibS0mEAOYNWsWr7/+Ou+88w4HDx5k2rRpFBcXM3nyZAAmTpzInDlzXPvfd999rF+/nueee45Dhw7xxBNP8NtvvzFjxgwAioqKeOihh/jll184fvw4mzZtYsyYMXTt2pWRI0c2yT22Rs6MV9fIAPTa8l+57o5W8d5YPPlcKa7W9ecvC4gJ9iUqyAerTWFvmvtZsexCI3sczUlc16+ldb1TeWliKYpSt7XEPv4tlQue3sivx3PdHqcQQgghmpfi4mJeXrWKZx9/nKuGD6dn9+68vnQpvgYDb77/fp3O4evrS4C/P1pH6WF0VBS+dcjMvfjmmwzo3ZuF//oXSYmJDOjTh7eWL+f7n37iz6PlXa4TExJY/PjjdO/ale7nZOYq8vfz443nn6dXUhK9kpL4aM0abDYbbzz/PH169qRHt268/cILnExLY/PWrQCseOMN5sycyXV//ztJiYm8+MwzhAQH13iNw8eO8cX69bzx3HNcOmQI/fr14/333yctLY01a9a49jObzbzyyisMHjyYgQMHMmPGjCrJmqbQouaIjR8/npycHB577DEyMzPp378/69evdzXkOHnyJGp1+YP+sGHDWL16NfPmzWPu3LkkJiayZs0a1xpiGo2GP/74g3feeYe8vDxiY2O58sorWbBggawl5kHOjJezNbyT8+u0vFLyS80E+3pv4uXROjbqcOofF8I3+7PYnXqWCzuH1fk6JSYL417+mdTcUlZPHcKwruFA7Ys5O8UE29cOKzVbOVtiJsxfj9Fs5cs/MhjWtZ2rvb1TWl4pj3++n1KzlY0Hsrggvu7jFEIIIUTzc/T4ccxmMxdfeKFrm06n48IBAzhYodzOG/bs38/3W7cSEB9f7bi6dekCwKB+/ep0vj49elSaF7Zn/36OpKQQ2Llzpf2MRiNHjx8nv6CArJwcLhw40PWeRqNhUN++2GzVd9g++OefaLVahlQ4pl27dnTv3p2DBw+6tvn5+dHFMX6AmJgYsrOz63Qf3tSiAjGAGTNmuDJa59q8eXOVbTfccAM33HBDtfv7+vryzTffeHJ4ohqu+WHRlefSBfvqaB/iS1peKcmZhW4FPO5KqcNizhX1jwt1BGJ559+5guUbD5Oaay8tfPbbZD7r0g6zVXE14Kjt+gadhshAH7ILy0g7W0qon46HP/2Dz3en0z7Ely9mXEy7gPIPCJ78wh6Egb38UwghhBCtn1qlqlI5Y7ZYGnzeouJirrnySv796KNV3oup0NTD36/m6p6Kzt2vqLiYQf368f5LL1XZNyI83M3RuufcLouqar6HTaFFlSaKlsnZuj4pumpnxCTXPDHvNexQFKW8dX0d5ogB9Iuzp8F3n6x7IHYgvYA3fkoBQKtWsetkHt8nZ3PqbAk2BXwdgVZtKnZOXPXzcT7fnQ7Ys1/TV/+O2bHm2qaDWXx7oLwRTWa+zCsTQgghWrou8fHo9Xq27tjh2mY2m/l19256dusG2IOWwqIiiouLXfvs3rev0nn0ej3WGrJINRnYty/7k5OJ79iRrgkJlV7+/nV7fjrf+Q8fO0ZkRESV8wcHBREcFERURESlxiRWq5Xfa1nnrEe3blgsFrb//rtr25kzZ0hOTqZnz54NHrO3SSAmvKrMYuWoIxtVsWOik3PbwQzvzRNLzzdSaraiVauIC6vbpzh9O4SgUtmPzS44f7bJalOY+7+9WG0Ko/tEM+VSe9r9uW//dAWBtbWud3I27Ph8dzpPf2lPqU8aFo+/XsMvx3J5+suDlJqsPP7FfgBXFjE9TzJiQgghREvn7+/PtEmTeOjJJ1n/3XccSE7mzlmzKCktZcottwAwZOBA/Hx9mbtwIUdTUlj96adVuiLGx8WRcuIEu/fu5fSZM5SVlZ332tPvuIPcvDwm/N//8euuXRxNSeGb775j8syZWK0Nb152y7hxhIeFMWbiRLb88gspJ06weetWZs6dy6l0+wfP906dyqIXXuDzr78m+cgR7vvXvzibl1fj81NiQgJjRo3izn/+k5927GDPnj3ceuuttG/fnjF1aFDS1CQQE151NLsYq00hyKAlOshQ5f3yhh3ey4gdSC9vFqLT1O1XPsBHS7dIe5C4qw7liat3nGR3ah4BPloev6YXd1/WhQAfLfvTC3j1x2NA7a3rnZwt7Nfvz8RiU7imXyyPX9OTpeP7A7Dq5+Pc9uZ2Tp0tJTbYwMLr+gCQVWDEZmv6FLsQQgjRYpSWQnGxd1+l7lesPDNvHuOuvprbpk9n4IgRHElJ4ZuPPiI0xN7VOSw0lP+89BJfbdxIn8sv54P//Y8nHnqo0jnGXX01o/76V664/noievTgg//977zXjY2OZuu6dVitVq688Ub6XH459z/6KCHBwZV6MNSXn58fP37+OR3bt+f6yZPpccklTLn/foxlZQQF2p+5Hr73XiZcdx0TZ8xg6OjRBPj7M/KKKzAYqj5DOr39wgsM6tuXqydNYuhll6EoCl999VWLWPS5xc0REy1LcpazLDGo2k8znC3skzMLsdkU1OraM0b1sT/d3vmwZ6x76731jwshOauQ3al5jOxV89pz2QVGFn99CICHRnYnyhFw3nFJZ17YdJgdKfaOhudbSBrKSxMBukcF8u9xfVCpVIzsFc19wxNZvukwv52wt699/NpexLfzQ60Ci03hdFEZkW7doRBCCNEG+fhAaKh9oWVjI1SUhIbar1lHBoOBFxYu5IWFC2vcZ+zo0YwdPbrStjtvu831Zx8fH/771ltVjlMqNKiI79ix0tdgzzB9tmpVjdfdXKETYW1WrVhR7fboqCjeefHFGo/TarWsWLSIFYsWAfalqnpcfDE3VshunTuG0JAQ3l2xAqxWiIyEcwKwSZMmMWnSpErbxo4d2yzmiEkgJrzqUEbVhZwr6hzuj16jpthk5dTZUjrW0t69vpwZsV6xNbc/rU7/jiF89FtqrfPEjGYrD36yh8IyC/06BHPrRZ1c7025pDPv/Hyc/FL7Ohadw89/b10cc9gCDVpevW0Qfvryv6L3DU9kf3oBGw9mMTwpkit7RqFSqYgMNJBZYCQj30ik++tGCiGEEG1LQADcdhvUoVzPI3x87NcU53UiNZVvN2/mL8OGUVZWxotvvknKyZPcfP31TT00r5BATLjkFJbx9b4MrhvQnkCDZ9K5NbWud9Jq1CRGBbA/vYCDmQVeCcT2OwKxnjHuZ8QA/jiVh9WmoDknW2c0W7n7PzvZcvg0Bp2aRdf3rbRPsK+Ouy5L4NlvkgHoVIfSxKEJ7Xjm+j707xhSJYOmVqt48eYBfLM/k78mRboyjDEhzkCslH5eXAJACCGEaDUCAiQ4aobUajWrPvyQfz7xBIqi0DspiY3//S89HI1KWhsJxITLS5uP8PbW4xQaLUy/ouYF+txxKLO8NLEmSdFB7E8v4FBGYa0lgPWRV2IiLc9en+1uaWK3qED89BqKTVaOZBdVCibLLFam/Wcnm5NzMOjUvD3pwmrPP2lYPP/55QSFRku1XSPPpVKpuOnCjjW+b9BpGNO/faVtMcEGdgEZ+UaIlkBMCCGEEC1TXPv2bP3yy6YeRqORQEy4nDxjX+vKmcVqqLPFJrIK7Gn/mjJiUN7C3jmfzJMOZNjPGRfm6/aC0Rq1ij7tg9meksvu1LOueyizWLn7vZ187wjC3pp0AUO7tKv2HP4+WtbeewlGs5UQP321+zSUc6HnjHwjcP5gTwghhBBCND3pmihcsgrtE1aP5RR55HzOgC4uzJcAn5pjfuf8sUNeaGHvmh8W4978MKf+He3lic6FnS1WG4Ed/yIAACAASURBVPeu3lUehN1+AcO61L4IYXiAj6stvTfEBNubg2TIos5CCCGEEC2GBGLCxZm9OpZT7JFW6M6W9N2jai8JdJYtppwpptTU8HUqKnLND3OzLNFpgGOe2K6TeSiKfa2wbw9kodeqefP2CxjW1bsrwdeFKyOWJ4s6CyGEEOdqDt3xROvjid8rCcQEUN7+HKDUbCWzDosYn48zI9ajho6JThGBPoQH6FEU+DPLs1mx8o6J9QvE+seFAvZxPbn2AB//dgq1ClZMGMDFzSAIA4iWjJgQQghRhc5sBpuNEpOpqYciWqGSEvuUnoasVyZzxAQAp4vNVAzsj+UUExvasHOer2NiRUnRQfx05DSHMgvo58hCNZTRbOWIo8zS3db1TtHBBqKD7F0JV/18HIBnxvX1eFORhogNsQdiWQVGe3fHJh6PEEII0RxobDZCsrPJ1tofd/30+mrXNBWtgNUKNpt9XTirZ6urzqUoCiUlJWRnZxMSEoJGU/8nLwnEBABZRZU/LTp2uohLQuvf1tVmU1zZrbp0C0yKDuSnI6fZnZrP+AvqfdlKkjMLsdoUwvz1RAXVfSHFc/WPC2H9/kwA5lyVxI2D4zwzQA+JCPBxLep8psQsizoLIYQQDtGZ9v9/Z1ssoJZCsFZLUeyBWGEhNCAwckdISAjR0Q37YF4CMQFAVvE5gVhOMSTWPxA7drqYEpMVvVZNfB3Wz7okMZw3fkrh099Pcc/lXYgLa3hzC2fHxF6xQQ36BOyqPtF8eyCTaZd34f/+0qXB4/I0rUZNVJCBjHwj6YUmCcSEEEIIBxUQk5lJZHY25gaUkIlmrqQE8vJg0iQIbWBJVx3odLoGZcKcJBATAGQVmSt9fTSnCIiq9/l+PnoagMGdQtFqzv8J1F+6RTA0oR3bjp1h8TfJrJgwoN7Xdtqfng/Uv1GH05j+7RnZKxqDrvkW/UUH2wOxzEKpgxdCCCHOpbHZ0JSVNfUwhLeUlkJREeh0YDA09WjqTHK0AoBsR2mis4zwWE5xg87302F7IFbXhhYqlYp5V/dApYK1e9LZeeJsg64P5Y06esY0LBADmnUQBhDr6JyYLoGYEEIIIUSLIIGYAMozYs6FidPySik112+yo8VqY9vRMwBc4kZnwV6xwdw4yD7/asG6Aw1qoW+1KRx0rEtW30YdLYmzc6JkxIQQQgghWgYJxARQ3qyjR3QQIX72GuqUs/Vrh/5HWj6FZRaCfXX0bu9eEPTgyG746zXsTs1j7R/pAKTnlbJ0w59MX/07OYV1KytIOV1MqdmKr05D5/Dzz1Fr6ZyLOqfX8fsjhBBCCCGalswREwBkFdszYpFBPiSE+/P7yTyO5RrpWY9zOcsSh3Vph0btXpOMyEAD91zRlWe/SeaZrw+xdk8G3x3KwpkcSwj358Eru5/3PM5GHT1iAt0eQ0vkXNQ5s0gyYkIIIYQQLYFkxARQPkcsKshAQoS9W+KxembEfjpiD8QuSazfgsdTLulM+xBfMvKNbDxoD8LiwuyBxs+Oksfz8VSjjpYixrGWWEaBBGJCCCGEEC2BBGKCMkVFbqkFcAZi9lK+o7mlbp+ruMzCrpP2RhvuzA+ryKDT8O9xfekRE8QdF3dm46y/sHrqRQDsSc2jqMxy3nM4G3W0hflhUF6amFVsxlr/qXVCCCGEEKKRSGmiIAc9ADqNilA/HQnhjoxYrvsZsR0puZitCnFhvnSqw/phNbkkMZyv77u00ra4MF9Sc0v5NSWXK8Jr/gzBalPYl2bPiPVqIxmxyEADGrUKi03htFrXgIUHhBBCCCFEY5CMmCALe3OOyEADKpWKLo6M2LHcUhQ3syuussR6ZsNqc3EX+zm3Oq5Rk6/2ZnC2xEyIn47ujnb8rZ1GrSIy0AeADHyaeDRCCCGEEOJ8JBATZDsyYlFB9gf4ju380KhVFJttZOPeKvTurh/mDmdr/a21zBNTFIWXNx8FYNKweHy0zXv9L09ylidmOH6eQgghhBCi+WpxgdjKlSuJj4/HYDAwZMgQduzYUev+n3zyCUlJSRgMBvr06cNXX31V6X1FUXjssceIiYnB19eXESNGcPjwYW/eQrOTpdgf3J1rUfloNcSF2ptjHMW3zufJLjSSnFWISgXDung+EHOe82BGAbkl5mr3+eF4PgcyCvDTa7h9aLzHx9CcOTsnZiiSERNCCCGEaO5aVCD20UcfMWvWLB5//HF+//13+vXrx8iRI8nOzq52/59//pkJEyYwZcoUdu3axdixYxk7diz79u1z7bN48WJeeOEFXnnlFbZv346/vz8jR47EaKxfx8CWKMuRQYkMNLi2uTonKnUPxJwlg71igwjz93xWJiLQh+5R9lLDbakF1e7z8nb72mMTLuxIqBfG0Jw5M2KZkhETQgghhGj2WlQgtnTpUu68804mT55Mz549eeWVV/Dz8+Ott96qdv/ly5czatQoHnroIXr06MGCBQsYOHAgL774ImDPhi1btox58+YxZswY+vbty7vvvkt6ejpr1qxpzFtrUlmu0sQKgZhjEWR3MmI/HbaXDF7SNcKDo6vMWZ7488mqgdhOJYDtpwrRaVRMvbSz18bQXDkzmukyR0wIIYQQotlrMYGYyWRi586djBgxwrVNrVYzYsQItm3bVu0x27Ztq7Q/wMiRI137p6SkkJmZWWmf4OBghgwZUuM5W6NspfIcMXA/I6Yoiisj5o1GHU7OuWfVBWIv2zoAcN2A9q4yvbYkNsSxqLMiGTEhhBBCiOauxbSvP336NFarlaioyo25o6KiOHToULXHZGZmVrt/Zmam633ntpr2qU5ZWRllZWWurwsKqi+TaymqzYg5OyfWMSP2y7FcMguM+Os1DI4P9fwgHS7sHIZaBSlnjaSr9cQ6tidb9GwkDBXwf3/p4rXrN2fRrmYdkhETQgghhGjuWkxGrDlZtGgRwcHBrldcXFxTD6lBsqiaEeviyIidwgejojrvOT7YcRKAMQPaY9B5r1NhsK+OPh1CAPhZsS/WbFZgSZE9UzYqMdQ19rYm1pEFzEInizoLIYQQQjRzLSYQCw8PR6PRkJWVVWl7VlYW0dHR1R4THR1d6/7O/7pzToA5c+aQn5/veqWmprp9P81FqaKiwJEYjayQEQsP0BPoo0FBxQlr7S3sc0vMrN9nzyDefGFH7w3WYZhznhjBZFq13JwRzgZTICoU7hnS3uvXb64iAn3QqMCCmtO2ttO2XwghhBCiJWoxgZher2fQoEFs2rTJtc1ms7Fp0yaGDh1a7TFDhw6ttD/Ahg0bXPt37tyZ6OjoSvsUFBSwffv2Gs8J4OPjQ1BQUKVXS5VttQdhvlo1gT7llaoqlYqEUHtgdtRS+5yjzw6cxmS10ad9ML3bB3tvsA7OhZ2/U0K5OrcTvxp9CFRZeVmdTJ9of69fv7nSqFVEBdh/Vhk299Z/E0IIIYQQjavFBGIAs2bN4vXXX+edd97h4MGDTJs2jeLiYiZPngzAxIkTmTNnjmv/++67j/Xr1/Pcc89x6NAhnnjiCX777TdmzJgB2ION+++/n6eeeoovvviCvXv3MnHiRGJjYxk7dmyT3GNjy7LZg6+oAB0qVeUSxK7t7KVuR6w1zzlSFPjgD/vyARMaIRsGMKhTKHqNijx0nFa09NCbWBt6glGq3Ea5fnMWHWgPxA6fJ3gWQgghhBBNq8U06wAYP348OTk5PPbYY2RmZtK/f3/Wr1/varZx8uRJ1Ory2HLYsGGsXr2aefPmMXfuXBITE1mzZg29e/d27TN79myKi4u56667yMvL45JLLmH9+vUYDIYq12+NnIFYZEDVB/dERyBmf6gvq/I+wK8EcjTXiJ9ew7X9Y6vdx9N89Rouiw9m49E8bjLk8UR0MYYaFnhuay6KC+L39CL+XRzB5aE5RGhtHj1/qllDhMaKoUV9hCOEEEII0fy0qEAMYMaMGa6M1rk2b95cZdsNN9zADTfcUOP5VCoV8+fPZ/78+Z4aYotSnhGrJRCz1pxd+UCxB8HX9oslwKfxfp2W/b0rp158g6QgX1C3zeYc1Zl5UXs2bT9Mss2fWTmhvBN9BvX5e63UyY5SPTdmRBCtsTIrtIBxgSVoPHRuIYQQQoi2Rj7XbuOynYGYf9U5Rc5A7JhFj6WaLnx5NjVfKvb5Wo1VlugUoNeQpCpp1Gu2BAadmhfVf2LAxpZSA6/ley5I3WG0B+SZVg2zT4dy1alINhUbUKRDoxBCCCGE2yQQa+OyrDVnxDoE+2DAigk1qZaqXfg+MwZhQk3PSD/6dvB+kw5RN4mqUh4PtM/bW5IbxC6jZxp3HDbbz3OhoYxgtY0/zTqmZLXjpTzJSAohhBBCuEsCsTaufI5Y1Yd1tUpFV0oB+NNU9f2Pjfbga0LfyCqNPkTTusmQz9/9S7CgYmZ2GEW2hv98Dpvsvyt3BRfxY1wmk4OKAFiZF0iuVf4pEUIIIYRwhzw9tXHZtcwRA0h0lP8dMVWe/3XWquaQxd7Q5OruYV4coagPlQoWhufRXmsh1aJldUHD2vpbFTjqyIgl6s0EaxQea5dPb72JEkXNa5IVE0IIIYRwiwRibVxtzToAV0bMWZbmtKvM/nUCJYT6yppVzVGwRuG+kEIA3soPwNSAuVynLBrKFBU+KoUOWitgD/buD7Wf/90Cf85IVkwIIYQQos7kyakNK7KpKFbsvwKR1TTrgPKM2OFzMmK7HI0bBqqKvDhC0VBjAkuI0FjJtGpYV+Rb7/McdpSmdtGZK3VKHO5npI9kxYQQQggh3CaBWBuW5WjAEYgFf33VZhwAiY6M2BGzDmuFjMrvZfZAbACF3h2kaBAfFUxyzOV6LT+w3h0O/zTbA/FEvaXSdsmKCSGEEELUjzw1tWFZjofmSEw17tMRI3pslCkqTjkCN6sCe1wZMQnEmrtbg4rxU9k4ZNKxpdSnXuc44siIJeqqLpz9Vz8jfX1MlEpWTAghhBCiziQQa8OyHYFVVC2BmEYFXbT2953laYfNWooUNX4qG92Qtbyau2CNwvhA+8+pvuuKOUtTu56TEQNnVqwAsGfFUs3VZ1eFEEIIIUQ5CcTasCyrIxBT1RyIASRqHIGYozzNOT+sn7a00nwh0XxNCS5Cg8JPpQb2l7nXXMWmwBHHz76brmogBnCFb5krK3ZpajTXpkWw7GwgB8q01e4vhBBCCNHWSSDWhjnniEVStdysokRtGVCeEdvlmB82UGf04uiEJ3XQWfm7v32+3+tuZsXSLBpKFTV6FDrWEIipVPBsxFn6+diD9j/K9Cw7G8TotChelXJFIYQQQogqJBBrw5xzxGorTQRIdJQmOrMivzsyYgN0pV4cnfC0u0LsTTvWFvmSban7X33nzz1Bb0FbSwa0u97C5+1z2NExg8XhZxnuZ//9WJQbzAcFfvUfuBBCCCFEKySBWBuWXefSRGdGTEueVcURx5piAyQj1qL09jEz0KcMKyq+Lq57K3tnJrRrNY06qhOptXFjUAlvRucyzbGO2dzTIXxZZHB/0EIIIYQQrZQEYm1YVh2adQB00pjRoVCqqPnS8QDfSWuhndrq9TEKzxrtKE/80q1ArPrW9XUxO7SACYHFKKi4PzuMH0vq17VRCCGEEKK1kUCsjVKUCs06zhOIaVWQ4Jgb9HGhPwADDLUfI5qn0QH2LOavRn2dyxMPm2tuXX8+KhU8FZ7H3/1LMKNialY7pmWF8WmhL7my5pgQQggh2jB5EmqjCmwqyhT7hJ+I8wRiAF319ofwPc5GHT4SiLVEsVorA3xMKKhYX4esmKLAkQZkxMC+BMLzkfY5YybFXhb5YE4Yg09EMyE9nHVFvpjrudC0EEIIIURLJYFYG+XMhoWorBhU538K7nbOQ7hkxFquv7tRnphpVVOkqNGi0KmGjol1oVfBG1G5fB6bzb0hBSTpzdhQsc3ow4zsMC4+Gc3zuYFuNRERQgghhGjJ5KmnjXLND1PX7eG6YlmaQWUjSe9+mZpoHkY5ArEdRj055wl8nI064nUW9A1cM06lgn4GMw+GFbK+QzZb4jKZGVJAuMZKtlXD8rwghqdG8ZujK6cQQgghRGsmgVgb5cyIRWrqGIhVyIj19TGjk4WcW6wOOiv9nOWJJbVnxZyLeNe3LLE2cTors8IK+bljJi9E5tJTb6JQUXNbRjt+Lm26YExR4OGcEKZmhknJpBBCCCG8RgKxNirLkQmpa0ask86CFvtT6QCZH9biOcsTvyqqPRA7Yqp/o4660qvg2oBSPo09zaW+RkoVNZMyw/m+iTosbi714aNCfzaW+LK7TLJzQgghhPAOCcTaKNcaYnUMxPQq6OrIigyW+WEt3lWOQGy7Uc/pWroXOlvXd/VCRuxcvmqFN6LPMMLR1OOuzHZ8XOCH0eb1S7soCiw7G+T6ekcTZuaEEEII0bpJINZGuTtHDOCZ8LM82i6P4X6ykHNLF6ez0tfHhA0V3xRXv9CyojSsdX19+Kjg5ahcV7v72adDGXwihvuyQ/mm2ECpzbs1sd+VGFydQQF+Ncq6Z0IIIYTwDm1TD0A0jUw354gB9DeY6W+QJh2txWj/Uv4o0/NVsS+3BJVUeT/HqibfpkaNQucGdEx0l04FyyPP0uWshY8L/cm0avi8yI/Pi/zQodDbx8yFhjIuMJi41M+Ij4diM0WBpWcDAbjU18iWUgM7jXqsir0FvxBCCCGEJ0lGrI3KdnOOmGh9nPPEtpX6cMxU9TOZ70vsmbJ4nQVDI/9LoVXhauTxaWwOU4KLaK+1YEbFrjI9r+YHMjWrHTOzwjx2zW9LDOw36fFX2VgacRZ/lY1CRc0hxzw5IYQQQghPkkCsDbIp7s8RE61PnM7KX/2M2FDxnCMT5GS0wXLHtpsDq2bLGotaBYMMJh5tl89PcVlsicvkuYhcbgwsBmBDicHVeKYhbAo875gbNjm4iAitjYGOuZC/Sjt9IYQQQnhBiwnEcnNzueWWWwgKCiIkJIQpU6ZQVFRU6zFGo5Hp06fTrl07AgICGDduHFlZWZX2UalUVV4ffvihN2+lyeXa1Fiw11pFSCDWps0Oy0eFwpfFfuwxlmd+/lPgT7pVS4zGwq1Btf89aywqlT14HBdYyuKIPAb6lGFDxZoivwafe32xgUMmHYEqG1OD7fd7oQRiQgghhPCiFhOI3XLLLezfv58NGzawbt06fvzxR+66665aj3nggQdYu3Ytn3zyCT/88APp6elcf/31VfZ7++23ycjIcL3Gjh3rrdtoFpyNOsI1VlkPrI1L0lu4LsBeovhMbjCKAoU2FSvz7Nmw+0MLG70ssa7GOTJ1nxb6oTRwva9X8+33Ozm4iBCN/WQXGMoAe8OOhp5fCCGEEOJcLaJZx8GDB1m/fj2//vorgwcPBmDFihWMHj2aJUuWEBsbW+WY/Px83nzzTVavXs1f//pXwB5w9ejRg19++YWLLrrItW9ISAjR0dGNczPNQLajXXmkxtrEIxHNwazQAtYV+bLN6MOPpT7sNOo5a9OQoDO7gp3m6Gr/Up48E8KfZh37TDr6+NSvkYxJgf1l9mzgDRXut7+PCR0K2VYNJy0aOunk74sQQgghPKdBn3UbjY3Txnzbtm2EhIS4gjCAESNGoFar2b59e7XH7Ny5E7PZzIgRI1zbkpKS6NixI9u2bau07/Tp0wkPD+fCCy/krbfeQjnPx99lZWUUFBRUerUkrtb1mkZcoEk0Wx10ViY6yvGeOhPMG/kBAPwztABtM86YBmsUrvSzZ/M+Lax/eeIxsxYLKgJVNjpoy4Mtgxr6OhYv3yFt7IUQQgjhYW4HYjabjQULFtC+fXsCAgI4duwYAI8++ihvvvmmxwcIkJmZSWRkZKVtWq2WsLAwMjMzazxGr9cTEhJSaXtUVFSlY+bPn8/HH3/Mhg0bGDduHPfccw8rVqyodTyLFi0iODjY9YqLi6vnnTWNLGejDq18wi/spocUEaiycdiso0RR00dv4ir/5r9enDNj93mRL6Z6lg8mO7oidtObUZ0TeF4g88SEEEII4SVuB2JPPfUUq1atYvHixej15Q8nvXv35o033nDrXI888ki1zTIqvg4dOuTuEN3y6KOPcvHFFzNgwAAefvhhZs+ezbPPPlvrMXPmzCE/P9/1Sk1N9eoYPc2ZEZPSROEUqrFxd0ih6+vZYQVVgpLm6FLfMiI0Vs7aNK52++5yBmLd9VUb15QHYpIRE0IIIYRnuT1H7N133+W1115j+PDh3H333a7t/fr1cztoevDBB5k0aVKt+yQkJBAdHU12dnal7RaLhdzc3BrndkVHR2MymcjLy6uUFcvKyqp1PtiQIUNYsGABZWVl+PhU//Dl4+NT43stgXOOmGTEREV3BBezs8yHDloLl/iWNfVw6kSrgusCSngtP5BPC/0YWY8sXrJjDbUkfdU5ZoMNZahQSDFrybaoidRKOa8QQgghPMPtQCwtLY2uXbtW2W6z2TCb3ZssHxERQURExHn3Gzp0KHl5eezcuZNBgwYB8N1332Gz2RgyZEi1xwwaNAidTsemTZsYN24cAMnJyZw8eZKhQ4fWeK3du3cTGhraogOt83FmxKI1NpBucMLBV63wVvSZph6G28YF2gOx70sM5FrVhLk59/FQhdLEcwVrFLrrLRwy6dhp1HNVQPMv1xRCCCFEy+B2aWLPnj3ZsmVLle3//e9/GTBggEcGda4ePXowatQo7rzzTnbs2MHWrVuZMWMGN910k6tjYlpaGklJSezYsQOA4OBgpkyZwqxZs/j+++/ZuXMnkydPZujQoa6OiWvXruWNN95g3759HDlyhJdffpmFCxdy7733euU+mguZIyZak+56C731Jsyo+KzQ161jC20q0iw1Z8SgvI29NOwQQgghhCe5nRF77LHHuP3220lLS8Nms/HZZ5+RnJzMu+++y7p167wxRgDef/99ZsyYwfDhw1Gr1YwbN44XXnjB9b7ZbCY5OZmSkvL2088//7xr37KyMkaOHMlLL73kel+n07Fy5UoeeOABFEWha9euLF26lDvvvNNr99HULAqcrti+vn4dv4VoVsYHlrDvjJ7nzgYxxNdU51b2fzqyYVEaq2v9sHNdYDDxXoE07BBCCCGEZ7kdiI0ZM4a1a9cyf/58/P39eeyxxxg4cCBr167lb3/7mzfGCEBYWBirV6+u8f34+PgqbecNBgMrV65k5cqV1R4zatQoRo0a5dFxNndnrGpsqNCg0E7a14tW4qagYr4tMbCl1MCUzHasaZ9DbB0yvs75YdWVJTo5M2IHTDpKbCr81FLPK4QQQoiGc6s00WKxMH/+fDp37syGDRvIzs6mpKSEn376iSuvvNJbYxQe5CxLjNDY0LSArnhC1IVOBSujcumuM5Nt1XBHZjuKbOf/BXd2TKypLBEgRmsjXGPFhsoVuAkhhBBCNJRbgZhWq2Xx4sVYLFXbPIuWwbWYs8wPE61MkFrhzegzhGusHDLpmJEVhuU8yavaWtdX1NMRqO137C+EEEII0VBuN+sYPnw4P/zwgzfGIhpBVsX5YUK0Mh10Vt6MOoNBZWNzqYGVeYE17qsotbeur6iXY87ZgTKZJyaEEEIIz3C7zuaqq67ikUceYe/evQwaNAh/f/9K71977bUeG5zwvGzJiIlWrp/BzDPhedyfE8areQFMCCyudv2vHKuaszYNahS66moPxJwZsQOSERNCCCGEh7gdiN1zzz0ALF26tMp7KpUKq1Ue8JszV+t6adQhWrExAaW8XWBiT5meFXmBLAjPr7KPc/2weJ0Fw3lqA5yB2CGTFquCzK8UQgghRIO5XZpos9lqfEkQ1vy55ohJaaJoxVQqmBNmD74+KPAnxaypss+fdZwfBvZgzVdlw6ioSTFLww4hhBBCNJzbgZho2VxzxKQ0UbRyF/ma+KufEQsqns0NrvL+Icf8sO7nmR8G9gxYD2nYIYQQQggPqlcg9sMPP3DNNdfQtWtXunbtyrXXXsuWLVs8PTbhBdmSERNtyOywfFQofFXsyy5j5QDK1THxPPPDnHq6GnZIICaEEEKIhnM7EPvPf/7DiBEj8PPzY+bMmcycORNfX1+GDx9e64LLoumZFDhjczbrkDliovVL0lsYF1ACwDO5wTjXfLcqcNjszIjVbTkOadghhBBCCE9ye7LD008/zeLFi3nggQdc22bOnMnSpUtZsGABN998s0cHKDwnx9GoQ4dCqFoCMdE2PBBWyBfFfmw3+vBGfgBTg4s4adFgVNQYVDY66eoWiPXSl2fEFMU+D00IIYQQor7czogdO3aMa665psr2a6+9lpSUFI8MSnhHlqV8fpg8RIq2or3Wyt3BhQA8nRvMAzmh7Dba1wNL1Fnq3AGxu96MGoUzNg3ZVpleK4QQQoiGcftpIi4ujk2bNlXZvnHjRuLi4jwyKOEd2VaZHybapgdCC5kXlocGhTVFfszOCQWgWx0adTgZ1NDFkT2T8kQhhBBCNJTbpYkPPvggM2fOZPfu3QwbNgyArVu3smrVKpYvX+7xAQrPSXc06oiW+WGijVGpYGpIMb19zMzIDuO040OJpDrOD3Pq5WPmsFnH/jIdV/iVeWOoQgghhGgj3A7Epk2bRnR0NM899xwff/wxAD169OCjjz5izJgxHh+g8JxTjuYEcVr3Hj6FaC0u8jWxrn0292aHsduo5xJfo1vH99SbWQMcMOm9M0AhhBBCtBn1Wpn0uuuu47rrrvP0WISXpToyYh1kDTHRhkVrbXwcc5oSRYW/WnHr2J56aWEvhBBCCM9we47Yr7/+yvbt26ts3759O7/99ptHBiW845QzEKtjlzghWiuVCreDMChfS+y4RUuhTTreCCGEEKL+3A7Epk+fTmpqapXtaWlpTJ8+3SODEt5xyuIsTZSMmBD1EaaxEaOxf5BxSBp2CCGEEKIB3A7EDhw4wMCBA6tsHzBgAAcOHPDIoITn5VtVFNrs/unYkwAAIABJREFUP+72EogJUW/OrJiUJwohhBCiIdwOxHx8fMjKyqqyPSMjA622XlPORCNIdWTDwjVWfOtRkiWEsHPNE5OMmBBCCCEawO1A7Morr2TOnDnk5+e7tuXl5TF37lz+9re/eXRwwnOc88MkGyZEw/RyZMT2S0ZMCCGEEA3gdgpryZIlXHbZZXTq1IkBAwYAsHv3bqKionjvvfc8PkDhGafM9kBMWtcL0TDdHRmxI2YtNgXU0rPDpcimQouCwe2P+NqWwyYtRkVFL71Zfn+EEKINczsQa9++PX/88Qfvv/8+e/bswdfXl8mTJzNhwgR0OvmEuLlyNuqQ1vVCNEyc1ooWBaOiJtOqIVb+TpFq1vBqfgAfF/qTqDPzZYecph5Ss5VtUfP3tEhMiopIjZW/+hkZ7mekY4VutlogQWdBJUGaEEK0avWa1OXv789dd93l6bEIL5LW9UJ4hlYFHXUWjpl1HDNp23QglmLWsOJsEJ8X+WLFHjXsN+kptalkLmoN9pt0mBT79yrbquHDQn8+LPSvst9FhjJeiz5DkHwfhRCi1XK7gOSdd97hyy+/dH09e/ZsQkJCGDZsGCdOnPDo4ITnSOt6ITwnwfGBRoq57TYoOmTScs2pSD4r8sOKikt9jRhUNgAyrVKbWBPn78wIv1LejT7N7UFFdNZZCNdYXS89Cr8YfbgpPZwci3wvhRCitXL7X/iFCxfi6+sLwLZt23jxxRdZvHgx4eHhPPDAAx4foFNubi633HILQUFBhISEMGXKFIqKimo95rXXXuPyyy8nKCgIlUpFXl6eR87b0iiKvXQIpDRRCE/o7AjEjrXRQCzHomZKZjuKFDX9fUx8HpvNezFnXM2AMhwZeFGVMxDrprdwmV8ZT4bn831cFr91ynS9/tc+h3CNlQMmPf9Ij+CkWb6fQgjRGrkdiKWmptK1a1cA1qxZwz/+8Q/uuusuFi1axJYtWzw+QKdbbrmF/fv3s2HDBtatW8ePP/543vLIkpISRo0axdy5cz163pYmz6amWHGuISaliUI0VOc2nBEz2uDOrHakWbQk6Mysij5NP4O9gUmMIxDLlECsRs7fmc61lIn38jHzaWwOcVoLJyxaxqVHsNsoc7CFEKK1cTsQCwgI4MyZMwB8++23rpb1BoOB0tJSz47O4eDBg6xfv5433niDIUOGcMkll7BixQo+/PBD0tPTazzu/vvv55FHHuGiiy7y6HlbGuf8sEiNVbqZCeEBbTUQsynwz5xQdpfpCVHbeDP6DCGa8jlMURrJiJ2P83cm4TzzdTvprHwam0OS3kyOVcO49Aiezw3ELFPGhBCi1XD7sfxvf/sbU6dOZerUqfz555+MHj0agP379xMfH+/p8QH2EsiQkBAGDx7s2jZixAjUajXbt29v9POWlZVRUFBQ6dWcnXKVJUo2TAhP6OJ4iE61aDC1oQfjF/ICWVfshw6FV6LO0FlXudTZmRHLskogVh2jDdIs58+IOUVqbXwUk8PV/iVYUbE8L4jr0yI4bGpbHwAIIURr5XYgtnLlSoYOHUpOTg6ffvop7dq1A2Dnzp1MmDDB4wMEyMzMJDIystI2rVZLWFgYmZmZjX7eRYsWERwc7HrFxcXVewyNIVVa1wvhUREaG/4qGzZUnGwjWbE/TVpWnA0E4OmIPC7yNVXZJ1rmiNXquOPf4mC1jVC1rU7HBGsUXow6ywuRuQSr/5+9O4+Pqrz7//86s0+SSSaTFRQEREUUFKHGoFVb+AqFVm/FtbiAFkoFUeS2QqsVtYity/0TtKLVar1d0Gpp1bqhKCogIO4K3C4oSBKyZ5JMZj+/PwKjEQgEkkwmeT8fj/N4kHOuOfM54UpyPnNd53PF+TjsYOy3+Qz5uldi++nWfNYHHR0ZuoiIdIA2J2Jer5e7776bf//734wdOzax/8Ybb+T3v/99m841Z84cDMNoddu4cWNbQ+xwc+fOpa6uLrFt3bo12SG1aufUxD52JWIi7cEwetb0RNOEm6uyiGEwJq2Jcz2B3bbrZd1RNVGJ2G5t3jGS1W8/1gg7PaOJVw7ezqnuIDEM6uOWxPZVxM6vynxsVlEPEZGUktQ7iNmzZzNp0qRW2wwYMIDCwkLKy8tb7I9Go1RXV1NYWLjf77+/53U6nTidzv1+38723WLOmpoo0l7626N8Enb0iERsecDFW00uHJj8Lqduj+0Kdo6IaWribm2O7tvzYXtSYIvzcK8qSqJWQjumxMZMg9kV2XwYcjC5NJd/HlSBz7pvo20iIpJcSb2DyMvLIy8vb6/tiouLqa2tZf369QwfPhyA5cuXE4/HKSoq2u/376jzdjUqXS/S/nrKiFjYhPnVmQBMzmrgkFZG1nc+I1YVsxA2wdHGUZ/ubueI2L48H9aaHy4i/kBBFWeW5PF11MbUMh+P9qpUYSYRkRSQEncQRx55JGPHjmXKlCksXryYSCTCjBkzOP/88+nduzcA27ZtY9SoUTzyyCMcf/zxQPMzYGVlZXzxxRcAfPzxx3g8Hvr27YvP59un86Y60/xuauLBB/jHX0S+s3NU48tunog9UpfOVxE7udYYM7LrW23rs8RxYBLGoDxq5WBNh25hX0rX7488W5yHCqs4qySPd0NOppf7ONEd2mP7AfYop7hDbZ4eKSIi7Stl7iAee+wxZsyYwahRo7BYLEyYMIGFCxcmjkciETZt2kQg8N2zC4sXL+bGG29MfH3yyScD8NBDDyWmRO7tvKmuOm6hybRgYO7yKaqI7L+eMCJWFbNwV23zaNh/Z/vxWFovEWkYzdMTt0ZtlMWUiP1QRyViAIc5otxXUMXFpbm8FnDzWsDdavtjnWHm+Op2W3RFREQ6R5vvIG644QYuvfRSDjnkkI6IZ498Ph+PP/74Ho/369cP02x5kzBv3jzmzZt3QOdNdTtL1xdY4zj16adIu+m342a6ImalPm7sNUlJBV+EbTzb4KY0aqUsZuWriI36uIXBjjDn7KFAxw/12pGIqXJiS3Uxg6p48/ekIxIxgJHuMA8XVvFMQxqxPXTHGPB6wMUHIQfnl+ZxqjvIf2UEsOzh74Mdk5PTQqR3g/4tItLVtDkR+/e//838+fM55ZRTuOyyy5gwYUJKFa7oabaqUIdIh8iymuRaY1TGrHwdsTHEGUl2SPstbMLiWg9313gI0/KO3IrJvJw6rPv4QU7hjkWdtysRa2HnaFi+NdahSc1JaSFOStvztESA8qiFRbUenvCn80aTizeaXK22P9Qe4Z+9K8iyKhkTEWlPbU7EPvjgA95//30eeughrrzySqZPn87555/PpZdeyo9+9KOOiFEOgErXi3Sc/vYolTtGjlI1EfswaOfaymw2hu0A/NgdpMgVosAWp5c1xgBHtE3TmnupcuJudeS0xLbKt8W5ObeOy7IaWFzrYUsrZe83he18GbFzebmPhwursGtmhYhIu9mvhxuGDRvGsGHDuOOOO3juued46KGHOPHEExk0aBCXXXYZkyZNIisrq71jlf2QKNShETGRdtffHmVd0Jmyz4k9XJfOTVVZxDHwWWLckFvH6elNB1TEYWcJ+7KoyvZ9384+sr+l6ztCP3uMW/NqW23zWcjGOSV5rGxycX2llwW5tSryISLSTg7oL6VpmkQiEcLhMKZpkp2dzd13302fPn148skn2ytGOQBbIzunJmpETKS9pXLBjv+tS2delZc4BqenB1jWp5wzMg4sCQPoZd2ZiGlE7Pu60ohYWwx2RlmYX4MFkyX16fy1LiPZIYmIdBv7lYitX7+eGTNm0KtXL2bNmsWwYcPYsGEDK1as4PPPP2f+/PnMnDmzvWOV/fDd1MTU+uMvkgpSNRF70p/G9VVeAKZl1XNXfg057bQIcOHOETFNTWwhVRMxgFHpQa7bsZD3gupM7qnJoCGuYTERkQPV5kRsyJAhnHDCCWzevJkHH3yQrVu3cuuttzJw4MBEmwsuuICKiop2DVTarnkNMY2IiXSUQ3cmYmEbZorUMfhnvZs5lc1J2KWZDVzr87frVLOdidj2qHWPlft6GtNM7UQMYHJmIxdlNmBicFtNFiduKeTOag81MU1BFRHZX23+GPfcc8/l0ksv5aCDDtpjm9zcXOLx9vl0VfZfRcxCyDSwYCYeoBeR9tPXHsXApN60UBmzkGfrur/3NoVtPFyXwZP1aZgYXJTZwPU5de3+vE+eNY4FkygGVTEL+V34e9JZKmIWGk0LFsyUnZ1gGHBjTh1DnBEW12bwVcTOwtpMHqjL4BcZTZzrCXCcM6znx0RE2qDNidj111/fEXFIB9hZur6XLaZKVyIdwGk0jzZvjdrYHLGRZ+tai+OaJrwacPG3ugxWB79bZuQCTyM3dkASBmAzIN8apyzWvBaZEjH46nvP6qbyeo4WA871BJiQEeClRhf31Hr4LOzgyfp0nqxPZ6A9wrmeAOd5GlXqXkRkH+xTInb11Vfv8wnvvPPO/Q5G2tfGcNer0iXS3fS3R9katfFVxMbx7q6TiEVNuL7SyxP16UDzemCnpQe5JLOBIlfHjlwU2mKUxayURq0MTdGy/u0p1acl/pDVgPEZQcalB1kTdPBUfTovNLr4ImLnluosFtV4uCirkUuzGshtp2cPRUS6o31KxN5///19OpmhOQldyschB4BuhEQ60AB7lDebulbBjqa4wRXl2bwacGPB5FdZDVyS1chBnTRFuVCVE1v4upslYjsZBpzgDnOCO8yNcYPnGtw8XJfB/0Xs/KXWw9/q0vl5ehOZ31vAOt8W41xPAJ8SNBGRfUvEXn/99Y6OQzrAh6HmBVqHOLvOp/Qi3c3Om+uvukgiVh2zcGlZDh+EHDgNk4X51YxJD3ZqDDsLdpQqEQO+6xvdLRH7Po/F5JeZAc73BHg10Dxt8cOQg6cb0ndpu7DGw8TMRqZkNWjqqoj0aF3jzkHaXZNp8H/h5kTsGCViIh1moKP55vrTkB3TJKnFCt4OOLmu0svXURtZljgPFlYxwtX5P/87iwNtVwl7oPtNTWyNxYDT0oP8v7QgK5ucrA462ZlqmSa81eTk07CDv9Z5+Ls/gws9jfzWV4dLxRdFpAfar0Ts3Xff5amnnmLLli2Ewy3/yP/zn/9sl8DkwHwWdRLDIM8ao1BTQEQ6zDBnGDsmJTEbW6JWDrF3foXSz0I2bq3O4s0mFwAH2aL8vbAqkSR2No2INTNNeKnRxTc9KBHbyTDgpLQQJ6WFWuy/1oQ3mpzcU+Ph3ZCTv/kzWB9ysLigil4aHRORHqbNn0EtWbKEkSNHsmHDBpYuXUokEuHTTz9l+fLlZGVldUSMsh8+ijTfkA1VOWGRDpVmMRm2Y9RpVZNzL63bR0XUwpsBJ/fVZvDrMh/jt+XzZpMLOyaTMxt4/qCKpCVhoGfEAN4P2jmnJJfflOcQwWCoM9xpz+h1ZYYBP0kL8Y/elTxUWInXEufDkINfbMtnXdCR7PBERDpVm0fEbrnlFv7nf/6H6dOn4/F4uOuuu+jfvz+//vWv6dWrV0fEKPvhu0RMhTpEOlqxK8TaoJNVTU4uyAx02PtsjViZUe7jw9CuN6zj0wP81udPyojcD+2cmlgasyZ9umZna4obXF+ZlXg2ymXEmZrVwK+9DVh60Pdhb3YmZM8dVM6U7TlsDNu5oCSXK7PrOcsTUNIqIj1Cm0fEvvzyS8aPHw+Aw+GgsbERwzCYNWsW999/f7sHKPvnw+h3I2Ii0rFGupunX60OOjE7aPmk94N2zizJ48OQAwOTAfYI49MD/Hd2Hc8dVM49BTVdIgkDyN8xIhYyDeriPSf7+DZi5eySXJ5uSMfA5JyMRt7os52rffWkW7Su1u70scf4Z+8Kfp4eIIrBHTWZnLilkNO35XFPTQYlPXhUVUS6vzaPiGVnZ1NfXw/AQQcdxCeffMKQIUOora0lEOi4T4Jl39WbVr6KN0+R0oiYSMc71hXGZcSpjFn5PGLj8HaeFvifBhdXV/gImQZHOsI8WFhN7y48YuCygM8SozrevJaY13rg34/3gnZWNTkZn9FE/y6ScH7fO00OLt/uozpuJccS456Cak7oQuvKdWVpFpNF+TWcXB/i6YY01gUdfBRq3u6u9TA728/krEasPSenF5Eeos0jYieffDLLli0D4JxzzuHKK69kypQpXHDBBYwaNardA5S2+5jmKTEH2aLkqFCHSIdzGvCjDnhOrCJqYUFVJtPLcwiZBqPSmni6d2WXTsJ22lmwo+wAKyfGTbinJoOzS/K4vSaLn2wt5KLSHF5pdBFN8iCTacLGsI1bqzK5sDSX6riVox1hnj24QklYGxkGnJsZ4KnelaztW8aC3BqOc4ZoMi38sdrLWSV5bAyr0LOIdC9t/q129913Eww2r0nz+9//HrvdzqpVq5gwYQLXXXdduwcobfeRmQHAMRoNE+k0xe4QbzW5WNXkZFJW4wGd65OQnb/VZfB8g5swzcMAkzMbuC6nLmVGBXrZYnwWPrCCHVUxC1eXZ7NiRzXIQY4Im8I23mpy8VaTi4NtUeb66hiXHuzU59DKoxYe9afzfKObryL2xP7T0wP8Ka8Wt6YhHpA8W5wLMgOc5wmwpD6NBVVZfBhy8PNv87ncW8/07HqcKfJzICLSmjYnYj6fL/Fvi8XCnDlz2jUgOXA7EzEt5CzSeUa6mp8TeyfoJGayXwnT9qiF31V6eS3gTuw71hnm11n1/CyjcxdlPlAFO0bj97WEfcyE90IOSqJWKqJWymMWnm1IoyxmxWmY3JxTyzmeAFujVh7zp/NUfRrfRm1ML8+h2BViXm4tR3RCpcjyqIWzS/LYEm3+8+kwTE5xBzkzI8DPOjkh7O4sBvwyM8BP04JcX+llWcDNwtpMXmh086e8WoYnYY08EZH2tN/j/OXl5ZSXlxOPt5z6NnTo0AMOSg7MR+wcEdMfKZHOcrQzgseI449b+CxsZ0gbRqRNE/7V4OaGKi/+uAUbJuMzmpiU2cAwV2qObPdqw9TE9UEH11dm8Vl412qQA+wR/lJQzaAdSVZfe4y5OX6uyq5ncW0Gi+s8rA46GfdtPmdlBPhJWpAT3GF8HTAtuy5mcElZDluiNvrYoszO9jMqPYhHI2AdqtAW5/6Cal5odHFDlZcvInbOLsnlksxGrvH5VQhFRFJWmxOx9evXc8kll7BhwwbMH5QHMwyDWKzrP7vQnVUFInxL8zSeozU1UaTT2Awocod4NeBmZZNznxOxypiF31V4eWXHKNhQZ5g78mo4LInrgLWHnc+IfRB08KfqTD4P29gcsXGQLcYJ7hDFrhAH2WLcVp3JP3aUevcYcY5yRsizxsi3xelrizLBEyBjNzfabovJLF89Z3sCzK/K4qWAm380pCfONcgRYZgzzOGOCIc7ohxmj5Bnje/3iFUwDlO257Ah7CDXGuPRXpVdpkplT2AYMD4jyEh3OX+syuSZhnQe9mewosnFovxq/b0TkZTU5kTs0ksv5fDDD+fBBx+koKAAQ/MwupSPypqfTRlgDZOpTwlFOlXxjkRsVZOTad6GvbaviFo4rzSXryJ27JjMzK7nN956bN3g12qvHSXs/y9i5/9qv3uO6suInTd3PPP1fed6GrnW529zgaE+9hiLC6tZ0+TgxUY3q5ucbIrY2Rhu3r7PaZjkWmP4LHF81jhO47vfkRbgBHeIMzMCZFlb/u6MmjCz3MfaoBOPEefvhVVKwpIk2xrnjvxazsho4toKL5sjNs7alsfcnDomZTZqaqiIpJQ2J2JfffUVzzzzDAMHDuyIeOQAfVTWfPM31JZaz5OIdAc7nxNbF3QQNsHRyk1hTczCRWXNSVhva5S/FlZzVDf6VH+EK8TotCb8cQuH2SMc4YjSzx7li4iNd5qcrAk6qYtbGOwIc3Nu3QE/71PkDlO0o1JhVczC2iYHn4btbArb+Txs55uolZBpsC1qY9sezvFSwM2C6izGpzdxekaALREbq4NO3mlyUBO34jBM7i+s6lb/T6nq5LQQLxxcwTUVXl4NuLmxysvKJifzcuo4WEmyiKSINidio0aN4sMPP+z0RKy6uporrriC5557DovFwoQJE7jrrrvIyMjY42vuv/9+Hn/8cd577z3q6+upqanB6/W2aNOvXz+++eabFvsWLFiQskVIPt7ePCI21N6U5EhEep4jHNHE+lkfhhyJkvY/5I8bXFyaw8awnTxrjMd7V9Kvm908uizwQGH1LvtPJsSlWY3ETKiIWci3xrG08yhGjjXOzzKC/IzvPpAKxqEiZqUqZqEqZqUqbmlR/r4ubuFf9Wlsitj5Z0Ma/2xIa3FOjyXOHXk1FKssfZeRbY3z14Jq/u5P55aqLF4NuFkecPHTtCAXZjZysjvU7n1LRKQ9tTkRe+CBB7jkkkv45JNPOProo7HbW079OP3009stuO+bOHEipaWlLFu2jEgkwuTJk5k6dSqPP/74Hl8TCAQYO3YsY8eOZe7cuXtsd9NNNzFlypTE1x6Pp11j7yymafLhjqmJQ20h4MDW7xGRtrEYzdMT/9OYxtsB524TsUDc4NLSHD4OO/BZYjzeq/slYfvCajQXYegsLgv0scToY48Bux/RmpbVwPshO0/403mrycWhjgjFrhDF7jBDnWHsuqnvcgwDJmU1MsIVZkF1JiubXLwacPNqwE1fW5Sbc2s5JS2U7DBFRHarzYnY6tWrWblyJS+++OIuxzqqWMeGDRt46aWXWLduHSNGjABg0aJFjBs3jttvv53evXvv9nVXXXUVAG+88Uar5/d4PBQWFrZrzMlQ5g9S0RjBislR9iDsWNhZRDrPj3ckYg/WZTAmvYnBzu+KbjQXfPDxbshJpiXOI72qUr4oR3diGHCcK8JxrtpkhyJtdLQzwmO9qvgybOMxfzpPN6SxJWrjkrJcfuOt5+psvxJpEelyLG19wRVXXMGFF15IaWkp8Xi8xdZRFRNXr16N1+tNJGEAo0ePxmKxsGbNmgM+/6233kpOTg7Dhg3jtttuIxpt/cYoFArh9/tbbF3Bdn+IPllODieA21ChDpFkOMsT4ARXiAbTwuSyXEp2rKMVNuHy8hxWNrlIN+I8XFipSm8i7exQR5Q/5NbxTt8yLspsfmb63loP55d897MoItJVtDkRq6qqYtasWRQUFHREPLtVVlZGfn5+i302mw2fz0dZWdkBnXvmzJksWbKE119/nV//+tfccsst/Pa3v231NQsWLCArKyux9enT54BiaC/H9vHy1pRjWWr5ONmhiPRYDgPuK6jiMHuE7TErk0tzqIlZuKrcx/KAC6dh8mBhFcel6PpgIqkgzWJyc24df8mvwmPEWR9yMubbfH5X0VzUI6rPKkWkC2hzInbWWWfx+uuvt8ubz5kzB8MwWt02btzYLu+1J1dffTWnnnoqQ4cOZdq0adxxxx0sWrSIUGjPc8rnzp1LXV1dYtu6dWuHxthWLqPznrsQkV1lWU0e7lVFvjXGpoidn2wt4IVGNw5M7i+o4gQVfBDpFOMygvzn4HKOcYapj1t4vD6diaW5/OibQuZVZhHUn0sRSaI2PyN2+OGHM3fuXN5++22GDBmyS7GOmTNn7vO5Zs+ezaRJk1ptM2DAAAoLCykvL2+xPxqNUl1d3e7PdhUVFRGNRvn666854ogjdtvG6XTidDrb9X1FpHs5yBbjb4VVnFeSS23cghWTuwuqVThApJP1tcd4pncFq5qcvNjo5uVGF9VxKw/7M6iKWbgrv0bVFUUkKfaramJGRgYrVqxgxYoVLY4ZhtGmRCwvL4+8vLy9tisuLqa2tpb169czfPhwAJYvX048HqeoqKhtF7AXH3zwARaLZZepkCIibXW0M8JfC6v4/2oyuTSrgdPStb6fSDLYjOa1x05OC3FzLrzc6OLKch/PNabRrybKbF99skMUkR6ozYnY5s2bOyKOVh155JGMHTuWKVOmsHjxYiKRCDNmzOD8889PVEzctm0bo0aN4pFHHuH4448Hmp8tKysr44svvgDg448/xuPx0LdvX3w+H6tXr2bNmjX85Cc/wePxsHr1ambNmsWFF15IdnZ2p1+niHQ/I91hRrorkx2GiOxgM2B8RpBGs5bfVmSzqDaTQ+wxzvYEkh2aiPQwbX5G7PtM08Q0O+eJ18cee4xBgwYxatQoxo0bx0knncT999+fOB6JRNi0aROBwHe/SBcvXsywYcMSa4SdfPLJDBs2jGeffRZonmK4ZMkSTjnlFI466ijmz5/PrFmzWpxXREREup9zPQEu9zaPhM2t8LK6yZHkiESkp2nziBjAI488wm233cbnn38OND83ds0113DRRRe1a3Df5/P5Wl28uV+/frskhfPmzWPevHl7fM1xxx3HO++8014hioiISAr572w/30Ss/KcxjcllOZyV0cTFWQ0M0vp+ItIJ2pyI3XnnnVx//fXMmDGDE088EYC3336badOmUVlZyaxZs9o9SBEREZH2ZjHgjrwaamIWVgVdPF6fzuP16RS5QpySFuT7K48NdYY5wRXGUGEPEWknbU7EFi1axL333svFF1+c2Hf66adz1FFHMW/ePCViIiIikjJcFnisVxXvBB084s/glUYXa4JO1gR3rY58vCvE7Gw/RVqCQkTaQZsTsdLSUkaOHLnL/pEjR1JaWtouQYmIiIh0FsOAYneYYnc1pVELT9ansyXy3S1S0DR4NeBibdDJeaV5nOgOMtIVSoyO2YGx6U30sceScwEikpLanIgNHDiQp556it/97nct9j/55JMcdthh7RaYiIiISGfrZYtzVfau5exLoxbuqfXwpD+dlU0uVja5WhxfVOthcUEVIzVaJiL7qM2J2I033sh5553Hm2++mXhGbOXKlbz22ms89dRT7R6giIiISLL1ssX5Y24d07IaeNSfTnX8u8LTn4TsfBZ2cHFpLrfk1nJupkrhi8jetTkRmzBhAmvWrOF//ud/+Ne//gXqwdZNAAAgAElEQVQ0r/O1du1ahg0b1u4BioiIiHQVB9tjzMnxt9gXjMM1Fdk815jGbyuz+TJi45zvrUvmMkwO1rRFEfmB/SpfP3z4cB599NH2jkVEREQk5bgssDC/hv41URbWZnJfnYf76jwt2szLqWVSVmOSIhSRrmi/ErF4PM4XX3xBeXk58Xi8xbGTTz65XQITERERSRWGAVf76hlgj3J7TSYNO6YuxgF/3MIt1Vmc5A4xUGuUicgObU7E3nnnHX75y1/yzTff7LKAsmEYxGIaehcREZGe6b88TfyXpynxtWnCpLIcVjS5uLoim2d6V2DXWmQiAlj23qSladOmMWLECD755BOqq6upqalJbNXV1R0Ro4iIiEhKMgz4U14NmZY4H4Uc/KXWs/cXiUiP0OYRsc8//5ynn36agQMHdkQ8IiIiIt1KoS3Ozbm1XFnuY1GNh5+mBRnijCQ7LBFJsjaPiBUVFfHFF190RCwiIiIi3dLp6U2MS28iisHV5dlsjViTHZKIJFmbR8SuuOIKZs+eTVlZGUOGDMFut7c4PnTo0HYLTkRERKQ7MAz4Y24ta4MOPo/Y+fHWQo5zhvhFRhPj05vIt8X3fhIR6Vb2ax0xgEsvvTSxzzAMTNNUsQ4RERGRPfBZ4zxYUMWt1Vm8E3TwXsjJeyEnf6rO5KHCKord4WSHKCKdqM2J2ObNmzsiDhEREZFu7xhXhCd6V1IetfCfRjf/qE/js7CDy7f7+PdBFfTVws8iPUabE7FDDjmkI+IQERER6THybXEmZzVygaeRc0vz+CjkYEpZDs8cVEGGxdz7CUQk5e3Xgs4An332GVu2bCEcbjmMfvrppx9wUCIiIiI9gcsC9xdUcfq2fDZF7FxVns39BdVYtNaYSLfX5kTsq6++4swzz+Tjjz9OPBsGzc+JAXpGTERERKQNCm1x7iuo4rzSPF4NuJlb6eU453cfdB/miHCcS+XuRbqbNpevv/LKK+nfvz/l5eWkpaXx6aef8uabbzJixAjeeOONDghRREREpHsb5orwp9waAJ6sT+fayuzEdlZJPldsz6Y82ubbNhHpwto8IrZ69WqWL19Obm4uFosFi8XCSSedxIIFC5g5cybvv/9+R8QpIiIi0q2d6WkiRg0vNroS+8KmwcomJ881pvFGk4vfZvv5ZWYjVk1dFEl5bU7EYrEYHo8HgNzcXEpKSjjiiCM45JBD2LRpU7sHKCIiItJTnO0JcLYn0GLfxyE7v6/08lHIwfVVXuZVZe3zlCaLAUc5wox0hxjpDnGcM4xLA2siXUKbE7Gjjz6aDz/8kP79+1NUVMSf//xnHA4H999/PwMGDOiIGEVERER6rCHOCEt7V/CoP53bqzOpNy3s8xP5Jon1yu6uBbcR53c5fi7KbOzIkEVkH7Q5EbvuuutobGz+4b3pppv4+c9/zo9//GNycnJ48skn2z1AERERkZ7OasAlWY2c52mkJr7vQ1pNcQvvhhysbnKysslJeczK9ZVetkWs/NbnV3VGkSRqcyI2ZsyYxL8HDhzIxo0bqa6uJjs7O1E5UURERETan8sCvSzxNrwizgBHlHM9AUwTFtV6uLMmk8V1HspiVv6cV4NDt28iSdEus4R9Pp+SMBEREZEuzDBgZnY9t+XVYMPkXw1pXFKay1sBJ01x3ceJdLaUeVyzurqaiRMnkpmZidfr5bLLLqOhoaHV9ldccQVHHHEEbrebvn37MnPmTOrq6lq027JlC+PHjyctLY38/HyuueYaotFoR1+OiIiISFKc4wnwYGEV6Uac1UEnF5XlcszXvTi/JJd7ajL4OmJNdogiPUKbpyYmy8SJEyktLWXZsmVEIhEmT57M1KlTefzxx3fbvqSkhJKSEm6//XYGDx7MN998w7Rp0ygpKeHpp58GmitAjh8/nsLCQlatWkVpaSkXX3wxdrudW265pTMvT0RERKTTnJIW4p8HVXB/bQarmpyUxmy8E3TyTtDJbTVZHOMMc0ZGgJPdIeyGmXhdoS2GU4NnIu0iJRKxDRs28NJLL7Fu3TpGjBgBwKJFixg3bhy33347vXv33uU1Rx99NM8880zi60MPPZT58+dz4YUXEo1GsdlsvPLKK3z22We8+uqrFBQUcOyxx3LzzTdz7bXXMm/ePBwOR6ddo4iIiEhnOsIR5Y78WkwTNkdsrAw6Wdbo4u0mJx+GHHwY2vU+qMAa44lelQxwaPaQyIFKiamJq1evxuv1JpIwgNGjR2OxWFizZs0+n6euro7MzExsNlvivEOGDKGgoCDRZsyYMfj9fj799NM9nicUCuH3+1tsIiIiIqnIMGCAI8pFmY080quKNX3LmJdTyzBnmHQjntgcmGyPWZlclkNVLCVuIUW6tJQYESsrKyM/P7/FPpvNhs/no6ysbJ/OUVlZyc0338zUqVNbnPf7SRiQ+Lq18y5YsIAbb7xxX8MXERERSRl5tjiTshqZlNVyrbGKqIUzS/L4JmpjapmPx3pVanFokQOQ1B+fOXPmYBhGq9vGjRsP+H38fj/jx49n8ODBzJs374DPN3fuXOrq6hLb1q1bD/icIiIiIl1Zni3Ow4VVZFrirA85mV2RTdzc++tEZPeSOiI2e/ZsJk2a1GqbAQMGUFhYSHl5eYv90WiU6upqCgsLW319fX09Y8eOxePxsHTpUux2e+JYYWEha9eubdF++/btiWN74nQ6cTqdrb6viIiISHcz0BFlcUEVl5Tm8p/GNPxlFvKtscTxY5wRJngCpFuUoYnsTVITsby8PPLy8vbarri4mNraWtavX8/w4cMBWL58OfF4nKKioj2+zu/3M2bMGJxOJ88++ywul2uX886fP5/y8vLE1Mdly5aRmZnJ4MGDD+DKRERERLqnke4wC/Jq+e+KbN5qanlv9UwD3FGTycTMRiZlNpBva8vi0yI9S0o8I3bkkUcyduxYpkyZwuLFi4lEIsyYMYPzzz8/UTFx27ZtjBo1ikceeYTjjz8ev9/PaaedRiAQ4NFHH21RVCMvLw+r1cppp53G4MGDueiii/jzn/9MWVkZ1113HdOnT9eIl4iIiMgenO0J0NsW5aPvVVYMmgb/qk/j66iNv9R6+GttBud4AlyV7VdCJrIbKZGIATz22GPMmDGDUaNGYbFYmDBhAgsXLkwcj0QibNq0iUAgAMB7772XqKg4cODAFufavHkz/fr1w2q18vzzz/Ob3/yG4uJi0tPTueSSS7jppps678JEREREUtBId5iR7nCLfVd463k14OKBugzWBZ08Xp/OvxrcTMlqYIq3gQxNWRRJSJlEzOfz7XHxZoB+/fphmt/9cJ966qktvt6TQw45hBdeeKFdYhQRERHpyawGjEkPMiY9yJomBwuqs/gg5OCu2kwe9adzWCvrj2VZ4lyV7edIp9Yok54hZRIxEREREUkdRe4wS3tX8GKjiz9XZ/F11EZV0Nrqa1Y1ObmvsGqXkTaR7kiJmIiIiIh0CMOAcRlB/l96kLebnDTG97xy0iP+dNYGnUwqzeXO/Bp+ntHUiZGKdD4lYiIiIiLSoewG/CQt1Gqb0WlNzKrw8WKjmyvKsymLWrk4qwGH0UlBinQyrYcuIiIiIknnssDd+dVcktmAicEfq7M49uteXFqWw4N16WyJtD6tUSTVKBETERERkS7BasC8nDqu89WSY4kRMC0sD7i4ucrL6K0FvNPk2PtJRFKEEjERERER6TIMA37lbWTdIWW8cNB2fuer4xhnmDAGs8qzqYnp9lW6B/VkEREREelyLAYMdkaZ6m3giV6VDLBHKI3ZuLbCyz6sUCTS5SkRExEREZEuLc1isjC/BgcmrwTcPFafluyQRA6YEjERERER6fKOdkb4ra8OgJurvGwKq/i3pDYlYiIiIiKSEi7NauRUd5CQaTBzu49gPNkRiew/JWIiIiIikhIsBtyeX0OuNcamiJ351VnJDklkvykRExEREZGUkWuNc2deDQD/68/glUZXkiMS2T9KxEREREQkpZycFmJqVj0Av63IpiyqW1pJPeq1IiIiIpJy/tvnZ4gjTG3cwlXlPmIqaS8pRomYiIiIiKQchwELC6pJM+K8E3RyW3WmindISlEiJiIiIiIpqb89xk25zSXtF9d5+NGWXsyt8PJu0KFFn6XL0wIMIiIiIpKyJmQE8McNHqzLYFvUxhP16TxRn06WJc4gRySxneQO0cceS3a4IglKxEREREQkZRlG8/pikzIbeSfo4Jn6NF5sdFMXt7Am6GRN0JloW+QKMcETYFx6ExkWDZlJcikRExEREZGUZzFgpDvMSHeYW8xavgjb2Ri2sTFs58OQg3VBRyIx+0NlFjnW7x4ocxhwna+OUenBJF6B9DRKxERERESkW3EacJQzwlHOCNAEQEnUytJ6N880pPFVxM62H5S8v7bSy6uu7XitGimTzqFETERERES6vd62GNOzG7jc28AXERuBuAGACVxTkc3nETt/qs5iQV5tcgOVHkNVE0VERESkxzAMOMwR5RhXhGNcEY51RZif25x8PVGfzrqgI8kRSk+hRExEREREerTj3WHO9zQC8LsKL2HNTpROoERMRERERHq8Ob46ciwxPo/Y+WttRrLDkR4gZRKx6upqJk6cSGZmJl6vl8suu4yGhoZW219xxRUcccQRuN1u+vbty8yZM6mrq2vRzjCMXbYlS5Z09OWIiIiISBfitZpcn9N8n7iwNpOZ27O5snz32w2VWaxt0qLRcmBSpljHxIkTKS0tZdmyZUQiESZPnszUqVN5/PHHd9u+pKSEkpISbr/9dgYPHsw333zDtGnTKCkp4emnn27R9qGHHmLs2LGJr71eb4dei4iIiIh0PWdkNPF0Q5C3m1w825jWatu/+zPoZ4tytqeRU9NC2I19z8oOsUVxpcxwiHSUlEjENmzYwEsvvcS6desYMWIEAIsWLWLcuHHcfvvt9O7de5fXHH300TzzzDOJrw899FDmz5/PhRdeSDQaxWb77tK9Xi+FhYUdfyEiIiIi0mUZBizKr+H5BjfhVtptDNl5odHN11Ebt9dkcXtN297HY8T5eUYT53gaGeaMYBgHFLakqJRIxFavXo3X600kYQCjR4/GYrGwZs0azjzzzH06T11dHZmZmS2SMIDp06fzq1/9igEDBjBt2jQmT56M0cpPRCgUIhQKJb72+/1tvCIRERER6YqyrXEuymrca7t58TpebHTzdH0aX0T2/ZY6ZBrUxy08UZ/OE/XpHGqP0N8e3e94C20xrs6ux/e9BaolNaREIlZWVkZ+fn6LfTabDZ/PR1lZ2T6do7KykptvvpmpU6e22H/TTTfx05/+lLS0NF555RUuv/xyGhoamDlz5h7PtWDBAm688ca2X4iIiIiIdAvpFpOzPQHO9gTa9Lq4Ce8EHTxdn84LjS6+jNj5MmI/oFjWNTn5316V5NuUjKWSpCZic+bM4U9/+lOrbTZs2HDA7+P3+xk/fjyDBw9m3rx5LY5df/31iX8PGzaMxsZGbrvttlYTsblz53L11Ve3OH+fPn0OOE4RERER6d4sBox0hxnpDnNj3GBFwEVjfP/mJkaBhTWZbIrYOb80l8d6VdJLyVjKSGoiNnv2bCZNmtRqmwEDBlBYWEh5eXmL/dFolOrq6r0+21VfX8/YsWPxeDwsXboUu731TxyKioq4+eabCYVCOJ3O3bZxOp17PCYiIiIisi88FpOfZzQd0DlOcof4ZWkuX0XsnFOSxxO9Kuljj7VThNKRkpqI5eXlkZeXt9d2xcXF1NbWsn79eoYPHw7A8uXLicfjFBUV7fF1fr+fMWPG4HQ6efbZZ3G5XHt9rw8++IDs7GwlWiIiIiLS5R1ij/FU70omluTyddTGuSW5LD2ogkKNjHV5KVE488gjj2Ts2LFMmTKFtWvXsnLlSmbMmMH555+fqJi4bds2Bg0axNq1a4HmJOy0006jsbGRBx98EL/fT1lZGWVlZcRizZ8SPPfcczzwwAN88sknfPHFF9x7773ccsstXHHFFUm7VhERERGRtjjIFuOp3hUMtEcojdmYtj2HkNY46/JSolgHwGOPPcaMGTMYNWoUFouFCRMmsHDhwsTxSCTCpk2bCASaH5h87733WLNmDQADBw5sca7NmzfTr18/7HY799xzD7NmzcI0TQYOHMidd97JlClTOu/CREREREQOUL4tzt8Kq/jFtnw+CDn4Q6WXW3NrVRq/C0uZRMzn8+1x8WaAfv36YX5vefNTTz21xde7M3bs2BYLOYuIiIiIpKq+9hiL8quZVJbDk/XpDHWGmZjZtqqO0nlSYmqiiIiIiIjs3clpIa7xNa9xO6/Sy8omJ9Uxyx63vYxbSAdKmRExERERERHZu2lZDXwccvBCo5uJpbmttu1vj/Ibbz1nZgSwaxpjp9KImIiIiIhIN2IYcFteDT92B/fadnPExm8rsvnJ1gIe86cR1ghZp9GImIiIiIhIN5NuMfnfXlWtTj0MmAaP+9O5ry6Db6M2fl+ZzRsBF/cXVKvIRyfQiJiIiIiISDdlGHve0i0mU7wNvN2njHk5tTgwWRZwsyyw97V35cApERMRERER6cFcFpiU1civvA0A3FSVRVDrQXc4JWIiIiIiIsIMbz29rVG+jdq4t9aT7HC6PSViIiIiIiJCmsXkupw6AO6t87AlYk1yRN2bEjEREREREQHgZ+lBTnIHCZsGN1VlJTucbk1VE0VEREREBGgu4jEvp46x3zp5NeDmV2U+XMbuSy9mWEyuzvaTb9MDZftDiZiIiIiIiCQMdES5LKuB++o8vBpwt9q2ImbhAZW73y9KxEREREREpIXZPj8DHVEa47vPsMKmwW3VmbwWcPNCo4vxGXtfPFpaUiImIiIiIiItOAw4xxNotU1j3OCu2kxuqPJykns7WdZWVo+WXahYh4iIiIiItNnl2fUMsEeojFm5tVqFPdpKiZiIiIiIiLSZ04Bbc2sBeKI+nbVNjiRHlFqUiImIiIiIyH453h3mAk8jAHMrvTTt4Zky2ZUSMRERERER2W9zfHXkWWN8GbFzdkkuW7UQ9D5RIiYiIiIiIvsty2pyb0E1OZYYn4YdnL4tj7cDzmSH1eUpERMRERERkQMywhXmuYMrGOoMUxO3cnFZDvfVZhBXIcU9UiImIiIiIiIHrLctxlO9Kjg7o5E4Bguqs7ikLIeyqFKO3dF3RURERERE2oXLArfl1fLH3BqchslbTS7GfFvA8w3uZIfW5SgRExERERGRdmMYcGFmgP8cVM5QZ5i6uIUZ5T6uLs8mrKmKCUrERERERESk3Q10RHmmdwUzvX4smPyzIY0rtvuIKBkDlIiJiIiIiEgHsRtwta+ehwqrcBgmLwfczCxXMgYplIhVV1czceJEMjMz8Xq9XHbZZTQ0NLT6ml//+tcceuihuN1u8vLyOOOMM9i4cWOLNlu2bGH8+PGkpaWRn5/PNddcQzQa7chLERERERHpUU5JC3FfQRUOTF5sdHNVeTbRHp6MpUwiNnHiRD799FOWLVvG888/z5tvvsnUqVNbfc3w4cN56KGH2LBhAy+//DKmaXLaaacRi8UAiMVijB8/nnA4zKpVq/j73//Oww8/zB/+8IfOuCQRERERkR7jJ2kh7i2oxo7JfxrTmLbdx5YevPhzSiRiGzZs4KWXXuKBBx6gqKiIk046iUWLFrFkyRJKSkr2+LqpU6dy8skn069fP4477jj++Mc/snXrVr7++msAXnnlFT777DMeffRRjj32WH72s59x8803c8899xAOhzvp6kREREREeoZR6UH+siMZezXg5qdbC5hb4eXbHpiQpUQitnr1arxeLyNGjEjsGz16NBaLhTVr1uzTORobG3nooYfo378/ffr0SZx3yJAhFBQUJNqNGTMGv9/Pp59+usdzhUIh/H5/i01ERERERPbu/6UH+edBFZzsDhLF4In6dH6ytYB7ajKSHVqnSolErKysjPz8/Bb7bDYbPp+PsrKyVl/7l7/8hYyMDDIyMnjxxRdZtmwZDocjcd7vJ2FA4uvWzrtgwQKysrIS287ETkRERERE9m6IM8Ijvap4uncFJ7qDRDC4rSaLlU3OZIfWaZKaiM2ZMwfDMFrdflhco60mTpzI+++/z4oVKzj88MM599xzCQaDB3TOuXPnUldXl9i2bt16QOcTEREREemJRrjCPNarigszm4vwza3wEogbSY6qc9iS+eazZ89m0qRJrbYZMGAAhYWFlJeXt9gfjUaprq6msLCw1dfvHLU67LDDOOGEE8jOzmbp0qVccMEFFBYWsnbt2hbtt2/fDtDqeZ1OJ05nz8nWRUREREQ60rU+P8sbXWyJ2rijJpPrc+qSHVKHS2oilpeXR15e3l7bFRcXU1tby/r16xk+fDgAy5cvJx6PU1RUtM/vZ5ompmkSCoUS550/fz7l5eWJqY/Lli0jMzOTwYMH78cViYiIiIhIW3ksJvPzaplclsvf6tIZnx7gOFck2WF1qJR4RuzII49k7NixTJkyhbVr17Jy5UpmzJjB+eefT+/evQHYtm0bgwYNSoxwffXVVyxYsID169ezZcsWVq1axTnnnIPb7WbcuHEAnHbaaQwePJiLLrqIDz/8kJdffpnrrruO6dOna8RLRERERKQT/SQtxFkZAUwMrq3IJtTN1xlLiUQM4LHHHmPQoEGMGjWKcePGcdJJJ3H//fcnjkciETZt2kQgEADA5XLx1ltvMW7cOAYOHMh5552Hx+Nh1apVidEvq9XK888/j9Vqpbi4mAsvvJCLL76Ym266KSnXKCIiIiLSk12fU0euNcbnETt3VGdiduNkLKlTE9vC5/Px+OOP7/F4v379ML/3P9W7d29eeOGFvZ73kEMO2ad2IiIiIiLSsbKtcW7MqWV6eQ7313kwgd/5/BjdsH5HyoyIiYiIiIhI9zc+I8h1vloA/lrn4dpKL9FuODKWMiNiIiIiIiLSM/zK20iW1eTaCi9P1adTF7NwZbafnQNjLotJP1sspUfKlIiJiIiIiEiXc44nQKYlzhXbfbwccPNywN3i+CnuIHfk15CbpPgOlKYmioiIiIhIlzQmPcjDvSo5wh4hzxpLbHZMVjS5+Nm3+awMpyU7zP2iETEREREREemyRrrDvNynvMW+TWEbV2z38X8ROxfWHsx0A66KmymV3KRSrNIWO8r4t0u7PbXZ1/foSDtj6AqxdCX6foiIiEg3dgTwb28dN9Xn80TQy91mH8pe/orbL8pLdmj7TIlYd2O3Q1YW1NVBU9O+vSYrq/l1+3OuPb22o+0utmTF0pXsz/+/iIiISApyAwuoZKSRw40cymUn9El2SG1imGZ3Xiatc/j9frKysqirqyMzMzPZ4TTfhEci+95+5837/pyrtdd2tB/GlsxYupK2/v+LiIiIpLggFly5vmSHAex7bqARse6oPZORrpzYdOXYkknfFxEREelhXMkOYD+oaqKIiIiIiEgnUyImIiIiIiLSyZSIiYiIiIiIdDIlYiIiIiIiIp1MiZiIiIiIiEgnUyImIiIiIiLSyZSIiYiIiIiIdDIlYiIiIiIiIp1MiZiIiIiIiEgnUyImIiIiIiLSyWzJDqA7ME0TAL/fn+RIREREREQkmXbmBDtzhD1RItYO6uvrAejTp0+SIxERERERka6gvr6erKysPR43zL2larJX8XickpISPB4PhmEkNRa/30+fPn3YunUrmZmZSY1Fuib1EdkX6ieyN+ojsi/UT2RvumMfMU2T+vp6evfujcWy5yfBNCLWDiwWCwcffHCyw2ghMzOz23Rm6RjqI7Iv1E9kb9RHZF+on8jedLc+0tpI2E4q1iEiIiIiItLJlIiJiIiIiIh0Muu8efPmJTsIaV9Wq5VTTz0Vm00zT2X31EdkX6ifyN6oj8i+UD+RvempfUTFOkRERERERDqZpiaKiIiIiIh0MiViIiIiIiIinUyJmIiIiIiISCdTIiYiIiIiItLJlIh1I/fccw/9+vXD5XJRVFTE2rVrkx2SdKI333yTX/ziF/Tu3RvDMPjXv/7V4rhpmvzhD3+gV69euN1uRo8ezeeff96iTXV1NRMnTiQzMxOv18tll11GQ0NDZ16GdKAFCxbwox/9CI/HQ35+Pv/1X//Fpk2bWrQJBoNMnz6dnJwcMjIymDBhAtu3b2/RZsuWLYwfP560tDTy8/O55ppriEajnXkp0kHuvfdehg4dmlhYtbi4mBdffDFxXP1DdufWW2/FMAyuuuqqxD71lZ5t3rx5GIbRYhs0aFDiuPpHMyVi3cSTTz7J1VdfzQ033MB7773HMcccw5gxYygvL092aNJJGhsbOeaYY7jnnnt2e/zPf/4zCxcuZPHixaxZs4b09HTGjBlDMBhMtJk4cSKffvopy5Yt4/nnn+fNN99k6tSpnXUJ0sFWrFjB9OnTeeedd1i2bBmRSITTTjuNxsbGRJtZs2bx3HPP8Y9//IMVK1ZQUlLCWWedlTgei8UYP3484XCYVatW8fe//52HH36YP/zhD8m4JGlnBx98MLfeeivr16/n3Xff5ac//SlnnHEGn376KaD+Ibtat24d9913H0OHDm2xX31FjjrqKEpLSxPb22+/nTim/rGDKd3C8ccfb06fPj3xdSwWM3v37m0uWLAgiVFJsgDm0qVLE1/H43GzsLDQvO222xL7amtrTafTaT7xxBOmaZrmZ599ZgLmunXrEm1efPFF0zAMc9u2bZ0XvHSa8vJyEzBXrFhhmmZzn7Db7eY//vGPRJsNGzaYgLl69WrTNE3zhRdeMC0Wi1lWVpZoc++995qZmZlmKBTq3AuQTpGdnW0+8MAD6h+yi/r6evOwww4zly1bZp5yyinmlVdeaZqmfpeIad5www3mMcccs9tj6h/f0YhYNxAOh1m/fj2jR49O7LNYLIwePZrVq1cnMTLpKjZv3kxZWVmLPpKVlUVRUVGijywpk4QAAAhJSURBVKxevRqv18uIESMSbUaPHo3FYmHNmjWdHrN0vLq6OgB8Ph8A69evJxKJtOgngwYNom/fvi36yZAhQygoKEi0GTNmDH6/PzFqIt1DLBZjyZIlNDY2UlxcrP4hu5g+fTrjx49v0SdAv0uk2eeff07v3r0ZMGAAEydOZMuWLYD6x/f1rOWru6nKykpisViLzgpQUFDAxo0bkxSVdCVlZWUAu+0jO4+VlZWRn5/f4rjNZsPn8yXaSPcRj8e56qqrOPHEEzn66KOB5j7gcDjwer0t2v6wn+yuH+08Jqnv448/pri4mGAwSEZGBkuXLmXw4MF88MEH6h+SsGTJEt577z3WrVu3yzH9LpGioiIefvhhjjjiCEpLS7nxxhv58Y9/zCeffKL+8T1KxEREeqDp06fzySeftJizLwJwxBFH8MEHH1BXV8fTTz/NJZdcwooVK5IdlnQhW7du5corr2TZsmW4XK5khyNd0M9+9rPEv4cOHUpRURGHHHIITz31FG63O4mRdS2amtgN5ObmYrVad6k2s337dgoLC5MUlXQlO/tBa32ksLBwl+Iu0WiU6upq9aNuZsaMGTz//PO8/vrrHHzwwYn9hYWFhMNhamtrW7T/YT/ZXT/aeUxSn8PhYODAgQwfPpwFCxZwzDHHcNddd6l/SML69espLy/nuOOOw2azYbPZWLFiBQsXLsRms1FQUKC+Ii14vV4OP/xwvvjiC/0u+R4lYt2Aw+Fg+PDhvPbaa4l98Xic1157jeLi4iRGJl1F//79KSwsbNFH/H4/a9asSfSR4uJiamtrWb9+faLN8uXLicfjFBUVdXrM0v5M02TGjBksXbqU5cuX079//xbHhw8fjt1ub9FPNm3axJYtW1r0k48//rhF0r5s2TIyMzMZPHhw51yIdKp4PE4oFFL/kIRRo0bx8ccf88EHHyS2ESNGMHHixMS/1Vfk+xoaGvjyyy/p1auXfpd8X7KrhUj7WLJkiel0Os2HH37Y/Oyzz8ypU6eaXq+3RbUZ6d7q6+vN999/33z//fdNwLzzzjvN999/3/zmm29M0zTNW2+91fR6vea///1v86OPPjLPOOMMs3///mZTU1PiHGPHjjWHDRtmrlmzxnz77bfNww47zLzggguSdUnSzn7zm9+YWVlZ5htvvGGWlpYmtkAgkGgzbdo0s2/fvuby5cvNd9991ywuLjaLi4sTx6PRqHn00Uebp512mvnBBx+YL730kpmXl2fOnTs3GZck7WzOnDnmihUrzM2bN5sfffSROWfOHNMwDPOVV14xTVP9Q/bs+1UTTVN9paebPXu2+cYbb5ibN282V65caY4ePdrMzc01y8vLTdNU/9hJiVg3smjRIrNv376mw+Ewjz/+ePOdd95JdkjSiV5//XUT2GW75JJLTNNsLmF//fXXmwUFBabT6TRHjRplbtq0qcU5qqqqzAsuuMDMyMgwMzMzzcmTJ5v19fVJuBrpCLvrH4D50EMPJdo0NTWZl19+uZmdnW2mpaWZZ555pllaWtriPF9//fX/397du0ax/XEA/mxWQ8SXqEnQxCKbVAqrEBAEUVLYKCiCFkEsFN86xRcEK0Wwk1iICGaD2gj6F2glInYqpgqIroT0IkIsNODc4sJCfii/cLmZePV5YGF29pzhe+DA8OGcmS327NlTLFu2rOju7i4uXLhQzM7OljwaFsKxY8eK/v7+or29vejp6Sl27drVCmFFYX7wc/8bxMyVP9vIyEjR29tbtLe3Fxs2bChGRkaK9+/ft343P/5WKYqiWJy1OAAAgD+TZ8QAAABKJogBAACUTBADAAAomSAGAABQMkEMAACgZIIYAABAyQQxAACAkgliAPATRVHk1KlTWbt2bSqVSiYmJha7JAB+E/7QGQB+4vHjx9m/f3+ePXuWwcHBdHd3Z8mSJYtdFgC/AXcTAPiJZrOZ3t7ebN++/R9fY3Z2NkuXLv0XqwLgd2BrIgD8wNGjR3P69OlMT0+nUqmkVqvlyZMn2bFjR1avXp2urq7s3bs3zWaz1WdqaiqVSiWPHj3K8PBwOjo68uDBgyTJ+Ph4Nm3alI6OjmzcuDG3b99erKEB8AuwNREAfuDz58+5efNmxsbG8vLly1Sr1Tx//jyVSiVbtmzJzMxMLl++nKmpqUxMTKStrS1TU1MZGBhIrVbL6OhohoaG0tHRkadPn+bixYu5detWhoaG8ubNm5w8eTI3btzIkSNHFnuoACwCWxMB4Ac6OzuzcuXKVKvVrF+/Pkly8ODBOW3u3r2bnp6eTE5Opl6vt86fPXs2Bw4caH2/cuVKRkdHW+cGBgYyOTmZO3fuCGIAfyhbEwFgnt69e5dDhw5lcHAwq1atSq1WS5JMT0/Pabd169bW8ZcvX9JsNnP8+PGsWLGi9bl27dqcbY0A/FmsiAHAPO3bty/9/f1pNBrp6+vL9+/fU6/X8+3btzntli9f3jqemZlJkjQajWzbtm1Ou2q1uvBFA/BLEsQAYB4+fvyYt2/fptFoZOfOnUmSFy9e/N9+69atS19fXz58+JDDhw8vdJkA/EcIYgAwD2vWrElXV1fGxsbS29ub6enpXLp0aV59r169mjNnzqSzszO7d+/O169f8+rVq3z69Cnnz59f4MoB+BV5RgwA5qGtrS0PHz7M69evU6/Xc+7cuVy/fn1efU+cOJHx8fHcu3cvmzdvzvDwcO7fv5+BgYEFrhqAX5XX1wMAAJTMihgAAEDJBDEAAICSCWIAAAAlE8QAAABKJogBAACUTBADAAAomSAGAABQMkEMAACgZIIYAABAyQQxAACAkgliAAAAJRPEAAAASvYXZbOZPOaPIM8AAAAASUVORK5CYII=\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/6K3W6nZcuWbtefeeaZJd6uIn799Vdat27tGptT27ZtXdeDY6FJw4YN3UJLST799FOmTp3K559/TnZ2ttt1WVlZxMXFeTw2Zygo6/3pacDwtW3btgEwatSoUvfJyspyC2OnrwovT8eOHYvN44TCucILFiwgIyOD/Px813V16tRx/T89PZ0zzzzT67maUPi6l/Rea9u2LStXriy2YMrb52ecNj2gor+PLrjgAreFTMOHD+ecc85hwoQJDB482KNODZ6814pef/r77fQxlMT5fMv7I0HElxRUJajFxsbSsGFDfvjhhwrfR2m/dIt+eDr3e+edd/jiiy9YsmQJK1eu5MYbb+SZZ57hiy++KLPpvrMydddddzFgwIAS92nVqpXb5aKVvc8++4y+ffu6XZ+RkeFVq5+NGzcydOhQevfuzYIFC2jQoAHh4eEsWrSI1157ze1xN2zYwLp161i6dCkrVqzgzTff5KKLLmLVqlWEhYVRUFBAx44dmTlzZomP1bhxY4/HZSXp6en069ePs846i5kzZ9K4cWMiIiJYtmwZs2bNKrXCXBpnWN6yZQudO3cucZ8tW7YA0K5dO8Dz92NlOZ/LjBkzSh3b6e/pou/Jynj88cd58MEHufHGG3nkkUeIj4/Hbrdz++23e/099iVPn58zTB88eNBtYdRZZ50FwPfff1/q99QTdrudvn378uyzz7Jt2zbat29f7m3i4uJo0KCB6/1Umi1bttCoUSNXqPbGwYMHgeJzV0X8SUFVgt7gwYN54YUX+Pzzz+nWrZvXt3dWjA4dOuTWi9JZkTndhRdeyIUXXshjjz3Ga6+9RnJyMm+88Qbjxo0rNWQ4q53h4eElVpjKc/bZZxc7FJeYmOj6f0FBATt27HBVUQHS0tKAwr6V7777LlFRUaxcudKtArxo0aJij2e32+nXrx/9+vVj5syZPP7449x///2sW7eOiy++mJYtW/Ldd9/Rr1+/MqsrTZs2paCgwFUZc/rll1+8+waUoWnTpmzZsoWCggK3qurPP//suh6gZcuWrFy5kgMHDpRaVV2yZAknT57kgw8+oEmTJq7tzqkM3ho4cCBhYWH861//KnVB1auvvkq1atW49NJLAff3Y1ElvR8rU9lyVrljY2Mr9J6sjHfeeYe+ffvy8ssvu20/dOiQWwhq2bIlX375Jbm5uYSHh5d4X6V9D5yve0nvtZ9//pm6detWuOWbM5BmZGTQsWNH13bn652amur1gqrT5eXlAXh11qvBgwfz4osv8sknn5TYtWDjxo1kZmZyyy23VGhMGRkZQOEfYCKBoDmqEvTuueceYmJiGDduHHv27Cl2fXp6Os8++2ypt3d+YG/YsMG17dixY8XaGx08eLDYoT5n1cR5GL169epA8ZBRr149+vTpw/PPP8+ff/5ZbAx//fVXqeMDR3i5+OKL3b5O74k5b9481/8Nw2DevHmEh4fTr18/wNEax2azuVXmMjMz3VboAyW2njn9eV533XX8/vvvvPjii8X2PX78uKtLwcCBAwGYM2eO2z6zZ88u8/l647LLLmP37t28+eabrm15eXnMnTuXGjVqkJSUBMDVV1+NYRiu5vBFOV9X51SKoq9zVlZWiWHeE40bN2bMmDGsXr26xBZXCxcuZO3atYwdO9ZVmYuNjaVu3bpu70egxNNXOoNWRc5M1aVLF1q2bMnTTz9dYhgq7z1ZGWFhYcV+lt5+++1i87Svvvpq9u3b5/bednLevrSfuQYNGtC5c2deeeUVt+t++OEHVq1axWWXXVbh8Xfp0oWIiAi3tmbgeL1vuukmVq1axdy5c4vdrqCggGeeeabc9my5ubmsWrWKiIgIr0Lh3XffTXR0NLfccotrHq3TgQMHuPXWW6levbqrrZm3vvnmG2w2W4UKAiIVpYqqBL2WLVvy2muvcf3119O2bVu3M1N99tlnrlZFpenfvz9NmjRh7Nix3H333YSFhfHPf/6ThIQEdu7c6drvlVdeYcGCBVx55ZW0bNmSI0eO8OKLLxIbG+v60IuOjqZdu3a8+eabtGnThvj4eDp06ECHDh2YP38+PXv2pGPHjtx00020aNGCPXv28Pnnn/Pbb7+V2EPSU1FRUaxYsYJRo0bRtWtXli9fztKlS7nvvvtc80gHDRrEzJkzufTSSxkxYgR79+5l/vz5tGrVyu1w4fTp09mwYQODBg2iadOm7N27lwULFnDGGWe4qjQpKSm89dZb3Hrrraxbt44ePXqQn5/Pzz//zFtvvcXKlSs577zz6Ny5M8OHD2fBggVkZWXRvXt31qxZw/bt2716fmvWrCnx1I1XXHEFN998M88//zyjR4/mm2++oVmzZrzzzjt8+umnzJ492zUXr2/fvqSkpDBnzhy2bdvGpZdeSkFBARs3bqRv375MmDCB/v37ExERwZAhQ7jllls4evQoL774IvXq1SvxDwxPzJo1i59//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": "iVBORw0KGgoAAAANSUhEUgAAAqoAAALRCAYAAACTYIFoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdeVxU5f4H8M8MO8OuAgooi/tuuJQLYGZUXpeyTCPc8mIloLm0XEvFXDKX6KZlVmZXqpt1M3/lgjumtrhQlJqKoCAJKqsMsgjn9wfOyGFmmBm2c4DP+/Wal55nznPO9xwG5jvPec53FIIgCCAiIiIikhml1AEQEREREenDRJWIiIiIZImJKhERERHJEhNVIiIiIpIlJqpEREREJEtMVImIiIhIlpioEhEREZEsMVElIiIiIlliokpEREREssRElVo8X19fTJ06VeowmqQtW7ZAoVDg5MmTUocie5pzdfnyZW1bSEgIQkJCJIupuTh8+DAUCgUOHz4syf4rKirQs2dPLF++XJL917c9e/bAwcEBN27ckDoUIiaq1LwYS5xCQkLQs2fPOu9n165dWLJkSZ23Q9I5c+YMnn32WXh5ecHGxgbt2rVDWFgYzpw5U6ftrlixAt999109RVl/QkJCoFAooFAooFQq4eTkhC5duiA8PBz79u2r07a/+OILxMbG1lOkhr3//vvYsmVLg+/HXF9++SXS09MRGRmpbavN3yJfX1/tz0ihUMDW1hadOnXCggULkJOTo7MNQRCwdetWBAUFwcXFBfb29ujVqxeWLl0KtVqts35FRQX+85//YNCgQXBzc4OjoyM6d+6MyZMn4+eff9au98gjj6Bjx45YuXJlbU8JUb2xlDoAIqmdP38eSqV5n9l27dqFDRs2MFltor799ltMmjQJbm5ueO655+Dn54fLly/jk08+wTfffIP//ve/ePzxx2u17RUrVuDJJ5/EuHHjjK67d+/eWu2jtry9vbXJh1qtRnJyMr799lvExcVhwoQJiIuLg5WVldnb/eKLL/Dnn39izpw59R2yyPvvv4/WrVvrXAEJCgrC7du3YW1t3aD7N2T16tWYOHEinJ2d67ytvn37Yt68eQCA4uJinDp1CrGxsUhISMCvv/6qXa+8vBzPPPMMtm3bhmHDhmHJkiWwt7fHjz/+iJiYGHz99dfYv38/PDw8tH2io6OxYcMGjB07FmFhYbC0tMT58+exe/du+Pv74/7779euO3PmTMyfPx8xMTFwdHSs83ER1RYTVWrxbGxspA7BbGq1GiqVSuowmqRLly4hPDwc/v7+OHLkCNq0aaN9bvbs2Rg2bBjCw8ORlJQEf3//Bo2lPhOriooKlJaWwtbW1uA6zs7OePbZZ0Vtb731FqKjo/H+++/D19cXq1atqreYGotSqazxuBtSYmIifv/9d6xdu7Zetufl5SX6Gc2YMQMODg5Ys2YNLl68iE6dOgEA3n77bWzbtg3z58/H6tWrtetHRERgwoQJGDduHKZOnYrdu3cDALKysvD+++/jn//8JzZt2iTaZ2xsrM5l/vHjxyMqKgpff/01pk+fXi/HRlQbvPRPLV71OaplZWWIiYlBp06dYGtri1atWmHo0KHay6NTp07Fhg0bAEB0mU5DrVZj3rx58PHxgY2NDbp06YI1a9ZAEATRfm/fvo3o6Gi0bt0ajo6OGDNmDDIyMqBQKEQjtUuWLIFCocDZs2fxzDPPwNXVFUOHDgUAJCUlYerUqfD394etrS08PT0xffp0ZGdni/al2caFCxfw7LPPwtnZGW3atMEbb7wBQRCQnp6OsWPHwsnJCZ6enma/6RYVFWHmzJlo1aoVnJycMHnyZOTm5orW2bFjB0aNGoV27drBxsYGAQEBePPNN1FeXi5a7+LFixg/fjw8PT1ha2sLb29vTJw4Efn5+aL14uLiEBgYCDs7O7i5uWHixIlIT083Guvq1atRVFSETZs2iZJUAGjdujU+/PBDqNVqvP3229r2qVOnwtfXV2dbmvOqoVAooFar8dlnn2lfFzXNf9Y3R7WkpASLFy9Gx44dYWNjAx8fH7z88ssoKSkRradQKBAZGYnPP/8cPXr0gI2NDfbs2WP0+KuzsLDAv//9b3Tv3h3r1683+zyHhIRg586duHLlivaYq54rU49Hs6+BAwfC3t4erq6uCAoK0o46+/r64syZM0hISNDuR3PuDM1R/frrr7Wxt27dGs8++ywyMjJE60ydOhUODg7IyMjAuHHj4ODggDZt2mD+/Pk6r019vvvuO1hbWyMoKMjourXl6ekJALC0rBxbun37NlavXo3OnTvrvTw/evRoTJkyBXv27NFe0k9NTYUgCBgyZIjO+gqFAu7u7qI2d3d39O7dGzt27KjvwyEyC0dUqVnKz8/HzZs3ddrLysqM9l2yZAlWrlyJGTNmYODAgSgoKMDJkydx+vRpjBw5EjNnzsTff/+Nffv2YevWraK+giBgzJgxOHToEJ577jn07dsX8fHxWLBgATIyMvDOO+9o1506dSq2bduG8PBw3H///UhISMCoUaMMxvXUU0+hU6dOWLFihTbp3bdvH1JSUjBt2jR4enrizJkz2LRpE86cOYOff/5ZlEQBwNNPP41u3brhrbfews6dO7Fs2TK4ubnhww8/xIMPPohVq1bh888/x/z58zFgwACT33wjIyPh4uKCJUuW4Pz58/jggw9w5coVbQIBVM7Zc3BwwNy5c+Hg4ICDBw9i0aJFKCgo0I4IlZaWIjQ0FCUlJYiKioKnpycyMjLwww8/IC8vT3tpdfny5XjjjTcwYcIEzJgxAzdu3MB7772HoKAgJCYmwsXFxWCs33//PXx9fTFs2DC9zwcFBcHX1xc7d+406dir2rp1q/Z1ExERAQAICAgwuX9FRQXGjBmDo0ePIiIiAt26dcMff/yBd955BxcuXNCZ+3rw4EFs27YNkZGRaN26td5k2hQWFhaYNGkS3njjDRw9elT7OjTlPC9cuBD5+fm4evWq9vXt4OBg9vHExMRgyZIlGDx4MJYuXQpra2v88ssvOHjwIB5++GHExsYiKioKDg4OWLhwIQCILmtXt2XLFkybNg0DBgzAypUrkZWVhXfffRfHjh3TeY2Ul5cjNDQUgwYNwpo1a7B//36sXbsWAQEBeOGFF2o8d8ePH0fPnj0NTpkw929RWVmZdv3i4mIkJiZi3bp1CAoKgp+fHwDg6NGjyM3NxezZs7XJa3WTJ0/Gp59+ih9++AH3338/OnToAKAyeX/qqadgb29f43EBQGBgoCznW1MLIxA1I59++qkAoMZHjx49RH06dOggTJkyRbvcp08fYdSoUTXuZ9asWYK+X5/vvvtOACAsW7ZM1P7kk08KCoVCSE5OFgRBEE6dOiUAEObMmSNab+rUqQIAYfHixdq2xYsXCwCESZMm6eyvqKhIp+3LL78UAAhHjhzR2UZERIS27c6dO4K3t7egUCiEt956S9uem5sr2NnZic6JIZrzHRgYKJSWlmrb3377bQGAsGPHjhpjnTlzpmBvby8UFxcLgiAIiYmJAgDh66+/NrjPy5cvCxYWFsLy5ctF7X/88YdgaWmp015VXl6eAEAYO3Zsjcc1ZswYAYBQUFAgCIIgTJkyRejQoYPOeprzWpVKpdJ77jTnKjU1VdsWHBwsBAcHa5e3bt0qKJVK4ccffxT13bhxowBAOHbsmLYNgKBUKoUzZ87UeCxV91X9tV/V9u3bBQDCu+++KwiCeed51KhRes+Pqcdz8eJFQalUCo8//rhQXl4uWreiokL7/x49eojOl8ahQ4cEAMKhQ4cEQRCE0tJSwd3dXejZs6dw+/Zt7Xo//PCDAEBYtGiRtm3KlCkCAGHp0qWibfbr108IDAzU2Vd13t7ewvjx43Xaa/u3SN96Q4YMEW7evKldLzY2VgAgbN++3WBcOTk5AgDhiSee0LZNnjxZACC4uroKjz/+uLBmzRrh3LlzBrexYsUKAYCQlZVl9DwQNRRe+qdmacOGDdi3b5/Oo3fv3kb7uri44MyZM7h48aLZ+921axcsLCwQHR0tap83bx4EQdDOF9Ncon3xxRdF60VFRRnc9vPPP6/TZmdnp/1/cXExbt68qb0h4vTp0zrrz5gxQ/t/CwsL9O/fH4Ig4LnnntO2u7i4oEuXLkhJSTEYS3URERGiEaUXXngBlpaW2LVrl95Yb926hZs3b2LYsGEoKirCX3/9BQDaEdP4+HgUFRXp3de3336LiooKTJgwATdv3tQ+PD090alTJxw6dMhgnLdu3QIAozeHaJ4vKCiocb369vXXX6Nbt27o2rWr6NgefPBBANA5tuDgYHTv3r1e9q0ZBdWco7qcZ3OP57vvvkNFRQUWLVqkc2Nj9asCpjh58iSuX7+OF198UTR3ddSoUejatave0fLqv1/Dhg0z6XcgOzsbrq6uBp8392/RoEGDtOv88MMPWL58Oc6cOYMxY8bg9u3bAEx7Het7DX/66adYv349/Pz8sH37dsyfPx/dunXDiBEjdKZEANAel74RYaLGwkv/1CwNHDgQ/fv312l3dXU1+kd36dKlGDt2LDp37oyePXvikUceQXh4uElJ7pUrV9CuXTudN5Bu3bppn9f8q1QqtZfyNDp27Ghw29XXBYCcnBzExMTgv//9L65fvy56rvpcQwBo3769aNnZ2Rm2trZo3bq1TnvVea6ZmZk6z1dNPDU3eGg4ODigbdu2opqhZ86cweuvv46DBw/qJICaWP38/DB37lysW7cOn3/+OYYNG4YxY8Zo59UClXNYBUHQ2adGTXeta34umjd6Q0xNaOvbxYsXce7cOZ25sxrVf8b6XhO1VVhYCODeMdflPGuYejyXLl2CUqmst6Rb83vWpUsXnee6du2Ko0ePitpsbW11YnR1ddWZZ22IUG3+eVXm/i1q3bo1HnroIe3yqFGj0KVLFzz55JP4+OOPERUVZdLrWN9rWKlUYtasWZg1axays7Nx7NgxbNy4Ebt378bEiRPx448/6j2u2nxYIKovTFSJqgkKCsKlS5ewY8cO7N27Fx9//DHeeecdbNy4UTQi2diqJoYaEyZMwPHjx7FgwQL07dsXDg4OqKiowCOPPIKKigqd9S0sLExqA8Rvvm3bthU99+mnn5r1JQl5eXkIDg6Gk5MTli5dioCAANja2uL06dN45ZVXRLGuXbsWU6dO1Z7/6OhorFy5Ej///DO8vb1RUVEBhUKB3bt3641dMzKoj7OzM9q2bYukpKQa401KSoKXlxecnJwAGH6jNuVmG3NUVFSgV69eWLdund7nfXx8RMv6XhO19eeffwK492GpLudZw9zjkYqh3wFTtGrVyuSEtrZGjBgBADhy5AiioqK0H3yTkpIMlkHTvMYNJf+tWrXCmDFjMGbMGISEhCAhIQFXrlzRzmUFoD2u6h9kiRoTE1UiPdzc3DBt2jRMmzYNhYWFCAoKwpIlS7SJqqHEpUOHDti/fz9u3bolGsnQXNrWvAl06NABFRUVSE1NFY1YJScnmxxjbm4uDhw4gJiYGCxatEjbXpspC8ZULwjfo0cP0fLFixcxfPhw7XJhYSGuXbuGxx57DEDlXdnZ2dn49ttvRTdopaam6t1fr1690KtXL7z++us4fvw4hgwZgo0bN2LZsmUICAiAIAjw8/ND586dzT6Wf/zjH/joo49w9OhRbfWEqn788UdcvnwZM2fO1La5uroiLy9PZ13NyF1VdRl9CggIwO+//44RI0Y06ihWeXk5vvjiC9jb22vPiTnn2VCsph5PQEAAKioqcPbsWfTt29fs/VSn+T07f/68dpqBxvnz50XJWF117drV4Ou4vty5cwfAvVHvoUOHwsXFBV988QUWLlyoN9H+z3/+A6Dy9W5M//79kZCQgGvXronOTWpqKlq3bm1wRJyoMXCOKlE11Us7OTg4oGPHjqJyOpoaptWTl8ceewzl5eVYv369qP2dd96BQqHAo48+CgAIDQ0FUFnAvKr33nvP5Dg1b07VLzs2xDcEPfTQQ6JH9RHWTZs2ie5i/uCDD3Dnzh3t8eqLtbS0VOf4CwoKtG/KGr169YJSqdSe/yeeeAIWFhaIiYnROXZBEHR+ftUtWLAAdnZ2mDlzps66OTk5eP7552Fvb48FCxZo2wMCApCfny8aib127Rq2b9+us32VSqU3qTXFhAkTkJGRgY8++kjnudu3b+v9tqG6Ki8vR3R0NM6dO4fo6GjtKLI551mlUumdamLq8YwbNw5KpRJLly7VuRJQdd+mntv+/fvD3d0dGzduFP3e7t69G+fOnauxuoa5HnjgAfz55596y23Vl++//x4A0KdPHwCAvb095s+fj/Pnz2srIFS1c+dObNmyBaGhodo565mZmTh79qzOuqWlpThw4ACUSqXO1KNTp07hgQceqO/DITILR1SJqunevTtCQkIQGBgINzc3nDx5Et98843o6xEDAwMBVH7TS2hoKCwsLDBx4kSMHj0aw4cPx8KFC3H58mX06dMHe/fuxY4dOzBnzhxtqaLAwECMHz8esbGxyM7O1panunDhAgDTRo6cnJwQFBSEt99+G2VlZfDy8sLevXsbfHRHn9LSUowYMQITJkzA+fPn8f7772Po0KEYM2YMAGDw4MFwdXXFlClTEB0dDYVCga1bt+okQAcPHkRkZCSeeuopdO7cGXfu3MHWrVthYWGB8ePHA6hMGpctW4bXXnsNly9fxrhx4+Do6IjU1FRs374dERERmD9/vsFYO3XqhM8++wxhYWHo1auXzjdT3bx5E19++aWorNTEiRPxyiuv4PHHH0d0dDSKiorwwQcfoHPnzjo3rQUGBmL//v1Yt24d2rVrBz8/PwwaNMik8xgeHo5t27bh+eefx6FDhzBkyBCUl5fjr7/+wrZt2xAfH693vqOp8vPzERcXB6Cy9q3mm6kuXbqEiRMn4s0339Sua855DgwMxFdffYW5c+diwIABcHBwwOjRo00+no4dO2LhwoV48803MWzYMDzxxBOwsbHBiRMn0K5dO22t0MDAQHzwwQdYtmwZOnbsCHd3d50RU6By/uyqVaswbdo0BAcHY9KkSdryVL6+vnjppZdqfQ6rGzt2LN58800kJCTg4YcfrvP2MjIytD+j0tJS/P777/jwww/RunVr0c2Wr776KhITE7Fq1Sr89NNPGD9+POzs7HD06FHExcWhW7du+Oyzz7TrX716FQMHDsSDDz6IESNGwNPTE9evX8eXX36J33//HXPmzBFd4r9+/TqSkpIwa9asOh8TUZ00ep0BogakKQlz4sQJvc/rK9FTvTzVsmXLhIEDBwouLi6CnZ2d0LVrV2H58uWi8kt37twRoqKihDZt2ggKhUJUoujWrVvCSy+9JLRr106wsrISOnXqJKxevVpUZkcQBEGtVguzZs0S3NzcBAcHB2HcuHHC+fPnBQCiclGaEkg3btzQOZ6rV68Kjz/+uODi4iI4OzsLTz31lPD3338bLHFVfRtTpkwRVCqVSedJH835TkhIECIiIgRXV1fBwcFBCAsLE7Kzs0XrHjt2TLj//vsFOzs7oV27dsLLL78sxMfHi8oKpaSkCNOnTxcCAgIEW1tbwc3NTRg+fLiwf/9+nX3/73//E4YOHSqoVCpBpVIJXbt2FWbNmiWcP3/eaNyCIAhJSUnCpEmThLZt2wpWVlaCp6enMGnSJOGPP/7Qu/7evXuFnj17CtbW1kKXLl2EuLg4veWp/vrrLyEoKEiws7MTAGhfW6aUpxKEytJKq1atEnr06CHY2NgIrq6uQmBgoBATEyPk5+dr1wMgzJo1y6Rj1ewLVUoeOTg4CJ06dRKeffZZYe/evQb7mXKeCwsLhWeeeUZwcXERAIhKVZl6PIIgCJs3bxb69eunXS84OFjYt2+f9vnMzExh1KhRgqOjowBAe+6ql6fS+Oqrr7Tbc3NzE8LCwoSrV6+K1jH0O6DvZ2tI7969heeee07UVtu/RVV/RkqlUnB3dxcmTZqkLW1XVXl5ufDpp58KQ4YMEZycnARbW1uhR48eQkxMjFBYWChat6CgQHj33XeF0NBQwdvbW7CyshIcHR2FBx54QPjoo490/j598MEHgr29vbZEG5FUFIJQw+2KRNSofvvtN/Tr1w9xcXEICwuTOhwiMsHWrVsxa9YspKWl1fhlE01Jv379EBISIvqSEiIpcI4qkUQ0NRGrio2NhVKpbNCvYySi+hUWFob27dtrv1q5qduzZw8uXryI1157TepQiMARVSKJxMTE4NSpUxg+fDgsLS2xe/du7N69GxEREfjwww+lDo+IiEhyTFSJJLJv3z7ExMTg7NmzKCwsRPv27REeHo6FCxca/P5uIiKilsTsS/9HjhzB6NGj0a5dOygUCnz33XdG+xw+fBj33XcfbGxs0LFjR2zZsqU2sRI1KyNHjsTRo0eRk5OD0tJSJCcnY/HixUxSiYiI7jI7UVWr1ejTp4/Jc3FSU1MxatQoDB8+HL/99hvmzJmDGTNmID4+3uxgiYiIiKjlqNOlf4VCge3btxv8CjcAeOWVV7Bz507t1/MBlTUJ8/LysGfPntrumoiIiIiauQa/xvjTTz/hoYceErWFhoZizpw5BvuUlJSIvuWjoqICOTk5aNWqVaN+rSARERERmUYQBNy6dQvt2rWDUlk/haUaPFHNzMyEh4eHqM3DwwMFBQW4ffs27OzsdPqsXLkSMTExDR0aEREREdWz9PR0eHt718u2ZHnXxmuvvYa5c+dql/Pz89G+fXvsOPInVA6OksSUfiUF0x4fjk2bNuHpp5/Wtn/11VeIiIjAlu8Ow7u9X73s65fM3HrZTlMxyNNV+39fFKHNfd0qF/oAiNTfh6jJ+wnA5sr/5i9bheLJz0kaDjWutJtqqUNoVNXf144lt6z3uTN/3ZQ6hEZRUVqE9I+nwNGx/nK1Bk9UPT09kZWVJWrLysqCk5OT3tFUALCxsYGNjY1Ou8rBESpHpwaJ05iuPfticMhIvPLqq7Czs0NwcDASEhLwyquvYnDISHTp0afe9mV76069baspqPozdYQFtEsWAOyliIioEVjf+69gawcrJ2n+tpE0VCUWUofQqKq/r1nZlUkUiTSUNkVSh9Co6nOaZoMnqg888AB27dolatu3bx8eeOCBht51vVu8ZhNi5kcgPDxc2zY4ZCQWr9kkYVREREREzZPZiWphYSGSk5O1y6mpqfjtt9/g5uaG9u3b47XXXkNGRgb+85//AACef/55rF+/Hi+//DKmT5+OgwcPYtu2bdi5c2f9HUUjcXJ2wdqPtiH98iVcvZIC7w7+8PENkDosIiIiombJ7ET15MmTGD58uHZZM5d0ypQp2LJlC65du4a0tDTt835+fti5cydeeuklvPvuu/D29sbHH3+M0NDQeghfGj6+AUxQiYiIiBqY2YlqSEgIaiq9qu9bp0JCQpCYmGjuroiImi93AEMq/1vesZOkoRARyZUs7/onImr2utx9ACgNGSFpKEREclU/1ViJiIiIiOoZE1UiIiIikiUmqiQrFSoHFLwdC0wB8KDU0RAREZGUmKiSvNjboyjiReBhAP2kDoaoAf0M4PnKh93WLRIHQ0QkT7yZiohICmUAbt39f0mxlJEQEckWR1SJiIiISJaYqJK8lJfD4nIKcB1AntTBEBERkZR46Z9kRZmTjTZ9u1Yu3AdgnqThEBERkYQ4okpEREREssRElYiIiIhkiYkqEREREckSE1UiIiIikiUmqkREREQkS7zrn4hICl0AvFD539Lg4ZKGQkQkV0xUiYik4H73AaC8UxdJQyEikite+iciIiIiWWKiSkRERESyxEv/JCsVrm64ceoM2hzuAdhIHQ1RA7oF4GblfxU3b0Bo3UbScIiI5IiJKsmLpSXKAzoBf0kdCFED+w3Axsr/2tr+D7dnPC9pOEREcsRL/0REREQkS0xUiYiIiEiWeOmf5KWoCHZfbgX+BNAaQF+pAyIiIiKpMFElWVGqC+E8L6py4T4wUSUiImrBeOmfiIiIiGSJiSoRERERyRITVSIiIiKSJSaqRERERCRLTFSJiIiISJZ41z8RkRQGAehT+d/b46ZIGgoRkVwxUSUikoL13QcA2NlJGQkRkWzx0j8RERERyRITVZIVQanEnQ5+QBsAzlJHQ0RERFLipX+SFaFVa9z8/Tw8d1obX5moKUsHcLryv5Zep3Gn732ShkNEJEccUSUiksJlANsqH1Ynf5U4GCIieWKiSkRERESyxESViIiIiGSJc1RJVhR5eXB+8TkgC0AAgLFSR0RERERSYaJKsqIoK4Xtru8rFwRpYyEiIiJp8dI/EREREckSE1UiIiIikiUmqkREREQkS0xUiYiIiEiWeDMVEZEUHAD4Vv5XaNVKykiIiGSLiSoRkRT63X0AKB71lKShEBHJFS/9ExEREZEsMVElIiIiIlliokqyItjaoWh6BDACQB+poyEiIiIpcY4qyYrg6IiCdethv3OT1KE0vr8AZAO4hZq/lcsfQJcqy+UA9pq4j4EAqt63kwXgtAn9lABCq7WdAZBmQl93AIHV2nJQeTORtQn9m6NyAP8GkAvAGrARdqDkH/y+YCKi6piokrx9BuC4CesFAoio1vYygHwT+k4GMKTKcgaApSZFB7wFwLXK8l4A/zOhX1sAS6q1xQFINaHvaIgT1Yq7fU3RAeJE9aqJfS2hm6j+CmC/CX3vg26iugXAOQCDAAwD0BmAwoRtNQdZAD4AcFHqQIiI5I+Jqowc/ztH6hAkcfzvHAxu56b/yRIAhSZspFhPW5GJfcuqLVeY2A/QHfksM7HvbT1tjqbtsrDjAhSOWn6voaQEniZ2zrl/H0qHBWuXbRTfwxXjjfYTlNbIGiU+MMdD0VBho9G+xe6jkDdqu3ZZkX0THr+1qxxVPHT34Y7KDwv9AdhW6ewBcQJbgMqfqzFWECfkAHADlfs0xhGAqspy+d2+pmh1d98aRaiMWeMsKj8YlFQuCkol1Av+hZJRY0zcATV1l2+opQ5BckcutKz3uqSz16UOoUlrUonqL5m5sL11R+owqAFdvqGGbxsVMkeVAgAcTi6E7dXtRnoBJf0exVGQBg4AACAASURBVK1Ra0Vtbu+FQHnD+B+IW0PfRMmoe8maRfIFuAaMMynenNBDqHD30C7b5WyB6pe3jfa7E9AJeaN2iNps7vwPFn//jQo3N8DKykBP4E7nruIGS0vkbTZtSPVO126i5bK+95nUV1DqTme//exUlA0earRvuWc70bKiqAi3J4TD5v++hVJ99037OoDtdx9VbYU4Uf0ewC6juwR6APhXtbY1qBxBNuYZAKOqLBcAmGdCPwBYCaB9leUTAAzMYrnjF4D8TVtQNmCQiRunpq6lJqlVB2GYpJK5FIIg1DQbThYKCgrg7OyM5bt+g63KxGGnZqCl/EIHda4cTdWMqvq2UdW0OjUTCrUaNj98B7v/fg7rwweg0PenaCvEt3x+jtonqq+gdolqLoBIE/oBuolqAvQmqkWTp+PWijUQHBxM3DA1ZS01QQWYpFZ37cxZCSJpPMKdYpQcfAP5+flwcnKql202qRHVlqKl/TJXpxlVpeZNUKlQ/HQYip8Og/LvDNj+7ytY/fkHUCVhzR+1Gagymmtb9CVsHOKNbvtOt+5Qj3pZ1OZwciEsMjKM9r097mmUPvyodlmRlwunIy+Zcki4NfpNVHj7aJetXH6Efd4n2mXB2hrFjz+J0hEPi/q15ESmpWqpU700WuJIY3NPUhsKR1RlpCUnqBxVpZaKSWrL0xKT1Krvb0xSm68WP6J6LDkXVnbV73yh5ohv3i1DS/5Awtd4y9MSE1SASWpLSVIbSpNKVFuq5vyL3bu7u2i5xgoA1OxwmgcRNWdMUuuO30xFRERERLLERJWIiIiIZImX/utRYeYVqG9chcrdBw4e7Y13ICIiIiKDmKjWg1J1PhI3L0Zm0jFtm2fvIeg3fSmsVfVz1xsRERFRS8NL//UgcfNiFKefQ1xcHNLS0hAXF4fi9HNI3LxI6tCIiIiImiyOqNZRYeYVZCYdQ1xcHMLCwgAAYWFhEAQB4eHhKMxK4zQAIiIiolrgiGodqW9UfidjUFCQqD04OLjy+evpjR4TERERUXPARLWOVG28AQBHjhwRtSckJFQ+7+6j04eIiIiIjOOl/zpy8OwAz95DEBkVDUEQEBwcjISEBERFz4Zn7yG87E9ERERUS0xU60G/6UuRuHkRwsPDtW2au/6JiIiIqHaYqNYDa5UTBkXFojArDerr6U2mjmpZbgbK8q7ByqUtrFy9pA6HiIiISISJaj1y8GjfJBLU8uJbyI5fC3XKCW2byn8AWoXOg4Wto4SREREREd3Dm6laoOz4tbDMSRbVfbXMSUZ2/FqpQyMiIiLS4ohqC1OWmwF1ygmDdV/LcjM4DYCIiIhkgSOqLUxZ3jUAhuu+ap4nIiIikhoT1RbGyqUtAMN1XzXPExEREUmNl/5bGCtXL6j8B2BWZJSo7mtkVDRU/gN42Z+IiIhkg4lqC9QqdB6y49eK6r5q7vonIiIikgsmqi2Qha0j3McuYR1VIiIikjUmqi2YlasXE1QiIiKSLd5MRURERESyxESViIiIiGSJiSoRERERyRITVSIiIiKSJSaqRERERCRLTFSJiIiISJaYqBIRERGRLDFRJSIiIiJZYqJKRERERLLERJWIiIiIZImJKhERERHJEhNVIiIiIpIlJqpEREREJEtMVImIiIhIlpioEhEREZEsMVElIiIiIlliokpEREREssRElYiIiIhkiYkqEREREckSE1UiIiIikiUmqkREREQkS0xUiYiIiEiWmKgSERERkSwxUSUiIiIiWWKiSkRERESyxESViIiIiGSJiSoRERERyRITVSIiIiKSJSaqRERERCRLllIH0BQUZl6B+sZVqNx94ODRXupwalSWm4GyvGuwcmkLK1cvqcMhIiIiqjUmqjUoVecjcfNiZCYd07Z59h6CftOXwlrlJGFkusqLbyE7fi3UKSe0bSr/AWgVOg8Wto4SRkZERERUO7z0X4PEzYtRnH4OcXFxSEtLQ1xcHIrTzyFx8yKpQ9ORHb8WljnJolgtc5KRHb9W6tCIiIiIaoUjqgYUZl5BZtIxxMXFISwsDAAQFhYGQRAQHh6Owqw02UwDKMvNgDrlhMFYy3IzOA2AiIiImhyOqBqgvnEVABAUFCRqDw4Ornz+enqjx2RIWd41AIZj1TxPRERE1JQwUTVA1cYbAHDkyBFRe0JCQuXz7j6NHpMhVi5tARiOVfM8ERERUVNSq0R1w4YN8PX1ha2tLQYNGoRff/21xvVjY2PRpUsX2NnZwcfHBy+99BKKi4trFXBjcfDsAM/eQxAZFY24uDikp6cjLi4OUdGz4dl7iGwu+wOAlasXVP4DMCsyShRrZFQ0VP4DeNmfiIiImiSz56h+9dVXmDt3LjZu3IhBgwYhNjYWoaGhOH/+PNzd3XXW/+KLL/Dqq69i8+bNGDx4MC5cuICpU6dCoVBg3bp19XIQDaXf9KVI3LwI4eHh2jbNXf9y0yp0HrLj14pi1dz1T0RERNQUmZ2orlu3Dv/85z8xbdo0AMDGjRuxc+dObN68Ga+++qrO+sePH8eQIUPwzDPPAAB8fX0xadIk/PLLL3UMveFZq5wwKCoWhVlpUF9Pl3UdVQtbR7iPXcI6qkTNRFpqMjLSUuHdwR8+vgFSh0NEJAmzEtXS0lKcOnUKr732mrZNqVTioYcewk8//aS3z+DBgxEXF4dff/0VAwcOREpKCnbt2iUa+auupKQEJSUl2uWCggJzwqx3Dh7tZZugVmfl6sUElagJy8/LxdIFM3H88D5t2+CQkVi8ZhOcnF0kjIyIqPGZNUf15s2bKC8vh4eHh6jdw8MDmZmZevs888wzWLp0KYYOHQorKysEBAQgJCQE//rXvwzuZ+XKlXB2dtY+fHzkc+MSEVFDWrpgJs4lnRLVRD6XdAox8yOkDo2IqNE1+F3/hw8fxooVK/D+++/j9OnT+Pbbb7Fz5068+eabBvu89tpryM/P1z7S0+VTCoqIqKGkpSbj+OF9eO/f/0ZYWBh8fHwQFhaGf7/7Lo4f3of0y5ekDpGIqFGZdem/devWsLCwQFZWlqg9KysLnp6eevu88cYbCA8Px4wZMwAAvXr1glqtRkREBBYuXAilUjdXtrGxgY2NjTmhERE1eRlpqQAM10S+eiWF81WJqEUxa0TV2toagYGBOHDggLatoqICBw4cwAMPPKC3T1FRkU4yamFhAQAQBMHceImImi2v9n4ADNdE9u7g3+gxERFJyey7/ufOnYspU6agf//+GDhwIGJjY6FWq7VVACZPngwvLy+sXLkSADB69GisW7cO/fr1w6BBg5CcnIw33ngDo0eP1iasREQEtPfriMEhIxEVHQ1BEBAcHIyEhAREz56NwSEjOZpKRC2O2Ynq008/jRs3bmDRokXIzMxE3759sWfPHu0NVmlpaaIR1Ndffx0KhQKvv/46MjIy0KZNG4wePRrLly+vv6MgImomFq/ZhJj5EaLKKJq7/omIWhqF0ASuvxcUFMDZ2RmP/fsQrOwcpA6n0SWdvS7JfhujJmvv7pVfEhHU2U3bNridm6HVqRnybaOSOgRJXL6hrvH59MuXcPVKCuuoNiPH/86ROgRJHLlw77ilej+TyrUzZ6UOoVEJd4pRcvAN5Ofnw8nJqV62afaIKjV/5cW3kB2/FuqUE9o2zbdcWdg6ShgZUcvh4xvABJWIWrwGL09FTU92/FpY5iSL6jha5iQjO36t1KERERFRC8IRVRIpy82AOuUE4uLiEBYWBgAICwuDIAgIDw9HWW4Gv/mKiIiIGgVHVEmkLO8aAMN1HDXPExERETU0JqokYuXSFoDhOo6a54mIiIgaGi/9k4iVqxdU/gMwKzJKVMcxMioaKv8BvOxPREREjYaJqgkKM69AfeMqVO4+cPBoL3U4Da5V6Dxkx68V1XHU3PVPRERE1FiYqNagVJ2PxM2LkZl0TNvm2XsI+k1fCmtV/dQHkyMLW0e4j13SKHVUiYiIiAzhHNUaJG5ejOL0c6IyTcXp55C4eZHUoTUKK1cv2Pv1Z5JKREREkuCIqgGFmVeQmXTMYJmmwqy0FjENgIiIiEgqHFE1QH3jKgDDZZrU19MbPSYiIiKiloSJqgGqNt4ADJdpUrn7NHpMRERERC0JL/0b4ODZAZ69hyAyKlpUpikqejY8ew/hZX8iIiKiBsZEtQb9pi9F4uZFojJNmrv+iYiIiKhhMVGtgbXKCYOiYlGYlQb19XS9dVQLM6/g5oXTgEKB1p3v40grERERUT1homoCB4/2OgloqTofpz9aiKwzv2jblEolWncdgMCIFc26zioRERFRY+DNVLWUuHkxiq/+Jaqx6uzsjPxLv7WYOqtEREREDYkjqrVgrMZqZtIx1lklIiIiqiOOqNaCsRqrAOusEhEREdUVE9VaMFZjFWCdVSIiIqK64qX/WtDUWJ01a5aoxmp0dDRsbGzg2qU/L/sTERER1RET1VrqN30pTn/0L1GNVc1d/6yzSkRERFR3TFRryVrlhPvnrEdhVlplHVWgWdRRLcvNQFneNVi5tIWVq5fBNiIiIqKGxkS1jvTVWG2KyotvITt+LdQpJ7Rt9h36QaEA1JcTtW0q/wFoFToPFraOUoRJRERELQhvpiIAQHb8WljmJIvqwpZnnoVlboqozTInGdnxa6UOl4iIiFoAjqgSynIzoE45IaoLO2DAAJSUlOCTTz7RWyu2LDeD0wCIiIioQXFElVCWdw2AuC7spUuXdNqAe7ViNX2IiIiIGgoTVYKVS1sA4rqwAQEBOm3AvVqxmj5EREREDYWX/glWrl5Q+Q/ArMgobV3YX3/9FTY2Njq1YiOjoqHyH8DL/kRERNTgmKgSAKBV6Dxkx68V1YW179APdxQQtWnu+iciIiJqaExUCQBgYesI97FLWEeViIiIZIOJKolYuXrpJKP62oiIiIgaGm+mIiIiIiJZYqJKRERERLLERJWIiIiIZImJKhERERHJEhNVIiIiIpIlJqpEREREJEssT2WCwswrUN+4CpW7Dxw82ussk/TSUpORkZYK7w7+8PENkDocHcbik3v8REREUmCiWoNSdT4SNy9GZtIxbZudcyvczs/WLnv2HoJ+05fCWuUkRYgtXn5eLpYumInjh/dp2waHjMTiNZvg5OwiYWSVjMUn9/iJiIikxEv/NUjcvBjF6ecQFxeHtLQ09O3bF9a4o12Oi4tDcfo5JG5eJHWoLdbSBTNxLumU6GdyLukUYuZHSB0aAOPxyT1+IiIiKXFE1YDCzCvITDqGuLg4hIWF4cKFC/jtt9+0ywAQFhYGQRAQHh6Owqw0TgNoZGmpyTh+eJ/Bn0n65UuSXkY3Ft8vRw/KOn4iIiKpcUTVAPWNqwCAoKAgAMClS5dEyxrBwcGV619Pb8ToCAAy0lIBGP6ZXL2S0ugxVWUsvjO/nazxeanjJyIikhoTVQNUbbwBAEeOHAEABAQEiJY1EhISKtd392nE6AgAvNr7ATD8M/Hu4N/oMVVlLL4effvX+LzU8RMREUmNl/4NcPDsAM/eQxAZFQ1BEBAcHIy+ffti1qxZ2uWEhARERc+GZ+8hvOwvgfZ+HTE4ZCSioqNFP5Po2bMxOGSk5JfNjcU3aOiDso6fiIhIas0yUa2v8lH9pi9F4uZFCA8P17bZObcSLWvu+idpLF6zCTHzI0Q/E81d83JgLD65x09ERCSlZpWo6isnVZfyUdYqJwyKikVhVhrU19Pv1VGttkzScXJ2wdqPtiH98iVcvZIiuzqkxuKTe/xERERSalaJatVyUkFBQThy5Agio6KRuHkRBkXF1nq7Dh7tRQlp9WWSno9vgKwTPGPxyT1+IiIiKTSbRLV6OSmA5aOIiIiImrJmc9d/9XJSGiwfRURERNQ0NZtEtXo5KQ2WjyIiIiJqmprNpX995aRYPoqIiIio6Wo2iSqgv5wUy0cRERERNU3NKlE1VE6qIRiq1VpfNVzlrCw3A2V512Dl0hZWrl5Sh0NERETNVLNKVDUasnyUoVqtPZ6ejzNfram3Gq5yVF58C9nxa6FOOaFtU/kPQKvQebCwdZQwMiIiImqOms3NVI2laq3WtLQ0xMXFoTj9HI6/PUNve+LmRVKHXG+y49fCMidZdIyWOcnIjl8rdWhERETUDDXLEdWGYqhW699//42XX34ZHzXjGq5luRlQp5wwWKe2LDeD0wCIiIioXnFE1QyGarV6eHjobW9ONVzL8q4BMHyMmueJiIiI6gsTVTMYqtWalZWlt7051XC1cmkLwPAxap4nIiIiqi+89G8GQ7VaV6x8C3bOrZp1DVcrVy+o/AdgVmSU6Bgjo6Kh8h/Ay/5ERERU75iomslQrdb+Exfgz/+ubtY1XFuFzkN2/FrRMWru+iciIiKqb0xUzaSp1Xr9zM/ISfkDbv694N7jfgBotBquUrGwdYT72CWso0pERESNgomqmQzVUdXUS23IGq5yYeXqxQSViIiIGhxvpjKToTqqzaleKhEREZEccETVDIbqqDaneqlEREREcsERVTMYqqPanOqlEhEREckFE1UzGKqj2pzqpRIRERHJBS/9m8FQHdXmVC+ViIiISC6YqJrJUB3V5lQvlYiIiEgOmKiaSVNHtTHqpRZmXoH6xlWUFdg3ejmostwM3L76BwDAzrsXy1ERERFRo2OiWksNWS9VX61WzTdAWdg6Nsg+NcqLb+HmrlUoTv8dFRUV9/bv2w+tHn2lwfdPREREpMGbqWRIX61Wy5xkZMevbfB9Z8evRXnmWTg7O4v3n5vSKPsnIiIi0uCIqswYq9ValpvRYJfhy3IzoE45AQD45JNPGn3/RERERFVxRFVmjNVqLcu71mD7rrptKfZPREREVBUTVZkxVqvVyqVtg+276ral2D8RERFRVbz0LzOGarVGRkVD5T+gQS+7W7l6QeU/AHcykhAVFSXef2Rkg++fiIiIqComqjKkr1ar5q7/htYqdB5u7lqF/PTfxfv37dco+yciIiLSYKIqS4Jke7awdYTHE8vu1lH9E4DAOqpEREQkCc5RlSEpy1NpWLl6walXKJx6PcIklYiIiCTBEVWZkbI8FREREZGccERVZqQsT0VEREQkJ0xUZUbK8lREREREcsJL/zIjZXkqIiIiIjlhoipDUpanIiIiIpILJqq1VJh5BeobV6Fy94GDR/t63ba1ygmDomJRmJUG9fV0XC2wl2QktSw3o3JOrFIJVFTAyqVtrePQbKsu2yAiIqKWhYmqmUrV+UjcvBiZSce0bZ69h6Df9KWwVjnV674cPNrDwaM9ss5er9ftGlNefAvZ8WuhTjmhbVMqlaioqNCO7FrYOtZ6W+Zug4iIiFom3kxlJn01TovTzyFx8yKpQ6s32fFrYZmTLDpGFxcX9O3b1+x6rvq21dg1YYmIiKhp4oiqGYzVOC3MSqv3aQCNrSw3A+qUEwaPcfXq1ViwYIFJ9VyNbassNwOAe0MfEhERETVRHFE1g7Eap+rr6Y0eU33T1Gk1dIzu7u6i9eqyLdaEJSIiopowUTWDsRqnKnefRo+pvmnqtBo6xuvXr4vWq8u2WBOWiIiIasJL/2YwVOM0Kno2PHsPafKX/QHAytULKv8BmBUZJTrG2bNno2/fvli2fIXJ9VwNbYs1YYmIiMgUTFTNpK/Gqeau/+aiVeg8ZMevFR2jUqlETk6O2fVc9W2LNWGJiIjIFExUTVC9ZmrVGqcNUUdVaha2jnAfuwRFl0+jJPM8LBxbw9LetVY1UDXbYh1VIiIiMhcT1RrUVDNVU+O0Oaqp9mltWbl6MUElIiIis/Bmqhq0hJqp+rD2KREREckBR1QNaAk1U/UxpfYpR0aJiIioMXBE1YCWUDNVH9Y+JSIiIrlgompAS6iZqg9rnxIREZFc8NK/AS2hZqo+rH1KREREcsFEtQYtoWaqPqx9SkRERHLARLUG1ionUc1UhdICQkU5SgvzYK1ykiSmxqhHKsfap2mpychIS4V3B3/4+AZIGguRIZeSL+Byagr8/APgH9BJ6nCIiJo8JqomsHZwxplt6/TWU22shLWm2qYWto4Nsk851D7Nz8vF0gUzcfzwPm3b4JCRWLxmE5ycXSSMjOie3NwcRM2chgN7d2vbRjz8KNZv2gIXF1cJIyMiatp4M5UJ5FBPtaXWNl26YCbOJZ0SHfe5pFOImR8hdWhEWlEzpyHx5C+i12niyV8QGTFV6tCIiJo0jqgaIYd6qi21tmlaajKOH95n8LjTL1/iNACS3KXkCziwd7fB12nKpYucBkBEVEscUTVCDvVUW2pt04y0VACGj/vqlZRGj4mousupla9DQ6/T1JRLjR4TEVFzwUTVCDnUU22ptU292vsBMHzc3h38Gz0moup8/Spfh4Zep37+HPUnIqotXvo3Qg71VFtqbdP2fh0xOGQkoqLF5z569mwMDhnJy/4kCwEdO2PEw48iutrrdPbs2Rjx8KO87E9EVAdMVE0gh3qqLbW26eI1mxAzP0J03Jq7/onkYv2mLYiMmCp6nWru+iciotpjompEYeYVqG9cRY8Jc9Fjwlyor6dD5e7T6N9MVb22KRRKQKhAxe2CBilPVZcaqvVZf9XJ2QVrP9qG9MuXcPVKiqiOKmurkly4uLgibtsOpFy6iNSUS6yjSkRUT5ioGlCqzkfi5sWS1k7VR2nnhMIjHzVYPdW61GttyFqvPr4B2mSUtVVJrvwDOjFBJSKqR7yZygA51E7Vp6HrqdZl+41V65W1VYmIiFoGjqjqIYfaqfo0dD3Vumy/sWq9srYqERFRy1GrRHXDhg1YvXo1MjMz0adPH7z33nsYOHCgwfXz8vKwcOFCfPvtt8jJyUGHDh0QGxuLxx57rNaBNyRTaqc2ZqLau7s7ACDrj4u4WkNc3k5F8Li7bm3UZfv1Fdvgdm41Pm9KbVUmqk2HbxuV1CEQETWYtj2649qZs1KH0aSZnah+9dVXmDt3LjZu3IhBgwYhNjYWoaGhOH/+PNzddROR0tJSjBw5Eu7u7vjmm2/g5eWFK1euwMXF/LmEQzq6wlbVMN9rX9UNu574GZV1ETWjdsC9uoghg3qijXfNCVVdHLmQo7e9ak1XfXHVtaZrXbZfl75BnSvPZdUk1dfNFsqcbFSoHAB7e217ea8uaAPgl++/h8+TT2rbf/6//0MbAEM7eKID1ACAClc3wLLKS/z2bSgLbxmMQ0NQKiG0ai1qU+TnQ1FaYryvjS0EJ/EcZsXNG1AIgu66CgVgZw/Bzg5QtuxZOPbvrYPqww1QZlytcb073boj+3iiqM31iVGwPrTf6D6KZs3BrWWr7jUIAjzcbE2KL/d/P6D0wZHaZev98XB9aoxJfbNyxa8biwt/wfr4UfiNfQKCa+Vr/vINtUnboqat6t+443/r/zvfHGn+xh+5kKMdeEk6e13KkBpV2x7dAYAJay2ZnaiuW7cO//znPzFt2jQAwMaNG7Fz505s3rwZr776qs76mzdvRk5ODo4fPw4rKysAgK+vb92ibmBtfPzQ/f4QRFWrnRodPRvd7w9BG2+/Bt2/5pdaQ5O4NnRN17psv7Z99SWpnS4mwiViKiyupqFg+WoUzZp97zmVA64DwKxZlY+7nrr7wMh7I603fv4N5V27a5ftvv4SztHPGz0P5V7euHFG/K1XztEzYbvjW6N9i8KnoeC9D0Vtbfp1hfJWzQlyhb09Ct77EMXjn9a2Wf6eCOcXphvdJwBk7z8mSujtN70Puy0fGe13p2cf5FcroeQ8IxyWZ/802rdoxgu4Pf3evGBFQQHcHgk2Ld4DxwE7OwCA505r4AyAmnNUAIBVwZnK9au6DkD3c4AO1aV3oNr5zr0GwbR+AOD2yyjgdpWG303vqxPv5wB2AU4LZqNk5CO4PWESfENHac8HNV9VP5AYu3rUnGiS8qDObtr3s951uPrXlFRNyDUJa3NWUVKEKwfrd5sKQdAz1GNAaWkp7O3t8c0332DcuHHa9ilTpiAvLw87duzQ6fPYY4/Bzc0N9vb22LFjB9q0aYNnnnkGr7zyCiwsLEzab0FBAZydnbH/9BWoHBvnjvuC/DzEzI8Q3Vl+36AhWLkhzuw7y80po1T9U/aN9FTczLiC1t4d0MbbD0W38vHlsrk4+/Nh7Trd7w/BpNfXwd7R2ay49KnL9mvbV5SkXjgN1wljoFTf/YP+LIBHq6ycDSDaxINZBcC7yvIhAB+b0M8NwHvV2t4F8KsJfUMA/LNa23MAik3oGw1gUJXl8wBMLdX7CYCqg4PfANhuQr9OAJZUa1sEwJRv/RwP4Ikqy2oApt7PthRA1V+FJAD/BuABoKY/C+4AIqu1fQbT4h0M4JEqywKAxSb0A4DJADpWWb4IYKuJfav+DCtQ+XPOFa9S4eiIO917AgqFtq3wtcUoDR6uXbY8+yec5lY/eP1y/7cTguretAq7rVtg9/kWo/3udO2Ogtj3RW1Oc16E5V/GR4Juh03F7fCp2mWFWg3X8aNMirdg3frK47/LOuEQHFbGGO0n2Nkjd/suUZvqnbdhE7/LQI97SocGo/B18T5cnn0Kyps3jPZVz56Pkkf/oV22uJwK5+enGVz/TqcuKB4/AaXDQoC773stbRS9+nuboSuHzVVLGUGuKCnClfefQn5+Ppyc6idfM2tE9ebNmygvL4eHh4eo3cPDA3/99ZfePikpKTh48CDCwsKwa9cuJCcn48UXX0RZWRkWL9b/LlFSUoKSknuXywoKCswJs14IgoA7ZXdEbb+d+AlvzJ6GN9/91KRktTZllDRJm76+mqTvuVWf4MbVVNy8ei+BrTemf27RYe/obHZsNSap9gDaVOtgBeC+yv8WlgDqEkBlAzjY6Nl49au6re71rZG+2SX+AO7oaa+ug562vgBK9bRX3G0vufuo/jutBKDvuExhYWJfawNtpvTVl1CaGm8mxIlqTwAfAVDoX71GU2rRB3f3Vdvv7OhUy74K3vTtvwAAIABJREFUAPMAHAPwE4C8ymblrVuw/uUn0apuB0KBwioNFwH8bNpuPHa5Vv7+aBwyra/1zeOw31nt09xRAMkm9G13HM5uVT6pFJm2TwBovfc+ILVKwy8m9rXVM2KdYFpf64rjcNi5Utx4HIAJ+ZN1zycqf381rta8T+ufj8N+66co9/BE7lc7cKdvvxYzP1uTkGv+1lcdXW0Jqo8gt5SEtT41+F3/FRUVcHd3x6ZNm2BhYYHAwEBkZGRg9erVBhPVlStXIiZG99N0+9YqODo1zi/3s7OewYUziYiLi0NQUBCOHDmCqKgo/H7yJ7z9rxcRt0139FjfNv66W0ZJs43o6Oga+2t+qauWYNLuPzoau9e8grUfbQPauQEDA+v1mAFg3uLnce1CkuH9mqIWsekkqX0AzIFuIuWEyjd6AA53HybrffdRG6Nr2Q8AomrZrxOAzbXs+/jdR228Xst+KtQ+3pYyRVcBwO/u4xkAZ1GZHJ1AZWJHzZpFXiZaXxqEzL73PrmqYldDmZlptG/Jo/8QjbAr8vPhsNK0T0vq2fNQ0baddtnq1AnYfv1fo/0ER0cULlwiarP9ciusfv/NaN+ywP4ofmqSNiGvmrC21Pm5QPOf8lB2uxBX6nmbDX7pPzg4GFZWVti//97NDrt378Zjjz2GkpISWFvrDunoG1H18fHBhbSbcKynoeSaXEq+gKH9e4pKIAFAXFyc9isSj506U2Nhb2PbqKm/sb7b9p1skDvb01KT8fTDAxp9v75OlmjTMwAWN+5+0jSUpBI1VwLEI3RAZVKrNLKOIUqIR6crYPKcWp2R8nIT+8klXlP7Vo8XaJhjLUPlnObjqPwwV316zKsA0k3Y5yQA/6iynAvdaTCGrARQ9TaBBACmfAu1C4AN1drWo/JqgDHDADwPZI4SX07ilIfmnaSX3S7Erujh9Xrp36xxDGtrawQGBuLAgQPatoqKChw4cAAPPPCA3j5DhgxBcnIyKiru/RZfuHABbdu21ZukAoCNjQ2cnJxEj8Z0ObXyRhpDJZAAIDWl5klxxrZRU39jfa9eSdHpUx9MKf3UECzSLt9LUv3BJJVaHgUqE66qj+p/nfWtY+hRfQqF0oy+1ZnaTy7xmtpX37tfQxyrLSrnnr8E3fnrRGSU2Zf+586diylTpqB///4YOHAgYmNjoVartVUAJk+eDC8vL6xcWTn354UXXsD69esxe/ZsREVF4eLFi1ixYgWio029I6bx+fr5AzBcagkA/PxrHlk0to2a+hvr693B36TjMJdXez9J9isOAkxSiah50jcH+0Xon8NeXatqy44AjN9vVsmj2nI/E/vq+yDwJMQ3JRrS8JUkqYUwO1F9+umncePGDSxatAiZmZno27cv9uzZo73BKi0tDcoqNSF9fHwQHx+Pl156Cb1794aXlxdmz56NV155pf6Oop4FdOyMEQ8/isjIyGrlqaJhY2ODocEPGv0+b802oqPF5Zpmz56NEQ8/WmN/Q32jZ8/G4JCRDVbQvr1fRwwOGYmoRt4vEVGLVduqgpYQV6IwhxN0b940lWct+xHVkllzVKWiKU/VWHNUASAvLxfPTwtDQpVC4kqlEkODH8SHn34OFxdXk7YRGTEVB/bu1raNePhRrN+0xWh/fX2NVQyoD/rKcjX0fv2FQqjWroLq8vrKS/9DG2Q3RETUWHYCOA2Uug1D/voPUe5fmVVzjirnqJqLiaoRhw/uw/69u9G6dRuMefzJGm+AupyaAj//AO06mjZLS0vcuXNH9Jyp3vvgQ5z++UcE3h+EfzwZZrxDPUm/fAlXr6SYVPu1rjR3heqUmSEioqbpEwB3C7/f/PEE7vTqA4CJKhNV8zV4eaqmKjc3B1Ezp4lGNE/++rPOaKi+9YKGjwCgwJEqo7GakVRTpaZewtjQENy4ngUA2LNjGz5YuxSbtu2Fl4++Yp31y8c3gJf6iYiISFItpXqh2aJmTkPiyV8QFxeHtLQ0xMXFIfHkL4iMmGp0vaTEU/jl+I9G+9ZkbGgISkuKRdsoLytBxISH6/dAiYiIiGSKI6p6XEq+gAN7d4vqif4/e3ceH1V973/8lQkkQMiGQBBFlgAqLkC1uFVQECzQ3trbxVpIC1qhSBJaxVpvrVxtrWutGwWxUvtzWrcu2luwoiiEquAWxAXNTkBJABMSEpZAZn5/HCbJJDOZk2Rmzjkz7+fjMY9kTuac8znDhPnke873PXPmzMHr9ZKTk0NZaTGjsseEfNykSZMYNmxYwHU789r6dezdUx10u2/95zUmfeXSTrchIiIi4nQaUQ3AbAZqqMeVlJQEXbczhe++3el2P9z6tomjcI7E4k/JykyGucBKq6sRERERu1CjGkDbHNO22meghnrc6NGjg67bmYnnfLnT7Z454csmjsJZErxe859EIyIiInFBp/4DMJuBGuxxeXl5JCcns2XLFvr06WM6P9Xn0mkzGDQ4i8WLF/ttNzc3lwEDB+u0v4iIiMQFNapBPLLqCXIXzCMnJ6dlWaCZ+4EeN+XSy/BCyHU7838vF/D16ZP9tjFg4GBWPbuuy8ciIiIi4kRqVIPIyMjE/ewLlJUWU15WGjQDtbPHhVq3M8OHj2Rb0U6e/ce/+HDr25w54cshR1Iry0v4rLI87NmnkdquiIiISGfUqIYwKnuMqSYz0OPMrtuZSV+5NGSDWre/lttvXBj2T5OK1HZFRCTGjQf6Q8Pon+EZNNjqasTBNJkqBtx+40K2b3vXL3N1+7Z3uW3pAltuV0REYty5wJXQcOuv8Qw50epqxME0oupwleUlvLHh5aCZqzsrSrt1uj5S2xURERExSyOqXVBaUsT6l/9NWWmx1aW0+KyyHAieubprR5mttisiIiJilhpVE2pra5j73W/wlXPPZO53/ouLzjmDud/9Bvv311pdGiedMhIInrl68vBRttquiIjEgWNAE3D4MHg8VlcjDqZT/ybkLZxP4TtbcLvdTJ48mYKCAvLz88ldMA/3sy9YWtspI0dz4SXTyWuX5Zq/ZAkXXjK926fnI7XdQDwnnkTNsy8w4O1vQGbYNisiIlb5E/AqDCGNfZve5thZ462uSBxKjWoIpSVFrF/3YtBrNctKi3s8s7+nlt23ituWLvDLXPXNzrfjdtvz9u9P04yZcDSsmxURERGHU6MaQkW5cS1mc3MzxcXFjBljNKW+azXLy0otb1TT0jP47WPPsrOilF07ysKWd9rZdpWtKiIiIpGmRrUTtbU1LH/gPgB++MMfAjBr1izcbnfLtZojR9mnSRs2IjsiTWPb7SpbVURERKJFk6k6kbdwPp9u/9AvR3Tz5s1MnTqVJUuWMG3GTMtHU6MtEtmqCY2NJL32CnwA7AxfrSIiIuJsGlENItS1qRdcNJlHVj1hbZFRFqlsVdfnuxjwzVnGnYuBH4exaBEREXEsjagG4bs2NViO6OKfLCUjI76mqCtbVURERKJJjWoQI0YaOaHBckTtdG1qtChbVURERKJJp/6DyB49lmkzZpLfLkc0Xq9Nhehmq4qIiIioUe3EI6ueIHfBPL8c0WkzZsbdtaltRStbVURERESNaicyMjJxP/sCZaXFvPGfAhISErjgoottc22qFVmmZjNblbMqIhLHZgEXwhfnv0LzSL0HSPepUQ2htraGW29eyvp1L7Ys842qWtWw2iHLNFhmqx1qExERi51o3I5+ZXLIh4p0RpOpQshbOJ/Cd7b45YYWvrOF3AXzLKspElmm8VCbiIiIOItGVDsRKku1rLQ46pOqIpVlGuu1iYiIiPNoRLUTobJUy8tKo16TnbNM7VybiIhE0Q7gHUhe808S6uqsrkYcTI1qJ+yYpWrnLNPu1tY8eixVNYfhSUBXCIiION8rwO8gc863SayssLoacTCd+u+EHbNU7Zxl2u3aEhKMm/5sEhERkTbUqIZgxyxVO2eZ2rk2cZ6i3VBaDaOHwJghVlcjIiLRpkY1hLZZquVlpYwclW35p1KZzTK1gp1rE+eoaYCclS7WFnpals2a6MK9yENmioWFiYhIVKlRNWlU9hjLG9T2gmWZ2kFXanPt3UPKg7+FMmAkcGFESxMHyFnpYnNFKm73ciZPnkxBQQH5eYuZu+IAa5Z6Qm9ARERighpVsVzC/lpSHvmdcedi1KjGuaLdsLbQg9u9PGDMWXGVLgMQEYkXmr4iIrZSWm18DRZzVlIV7YpERMQqalRFxFays4yvwWLORms0VUQkbujUv4jYytgTjYlT+XmL/WPh8nOZNdHFmCG6RlVEJF6oURUR23Ev8jB3xQG/mDPfrH8RcYBEoDd4XclGTrZIN8VMo1paUkRFeVlE4qMiue1QKstL+KyyXDFPElcyU2DNUg/FVcY1qUaOqppUEceYZ9yqZx+wuBBxOsc3qrW1NeQtnM/6dS+2LPMF8mdkZNp2293Zty84Py09I6L7FrGLMQr6FxGJa46fTJW3cD6F72zB7XZTWVmJ2+2m8J0t5C6YZ+ttd2ff27e9y21LF0R83yIiIiJ24OgR1dKSItavexG32x0wb7GstLjbp+ojue2e7ntnRakuAxAREZGY5+gR1YryMiB43mJ5Waktt93Tfe/aURaxfVvB27cfRy6ZBmcCJ1ldjYiI9NjrwB8h7YY8XJ/tsroacTBHN6ojRo4CguctjhzV/VHHSG67p/s+efioiO3bCp6Th1H7/ItwM/B1q6sREZEe+wR4Bfo9/iiumi+srkYczNGn/rNHj2XajJnk5+f75y0uWcK0GTN7dGo+ktvu7r7zlyzhwkum67S/iIiIxAVHN6oAj6x6gtwF8/zyFn0z8+287e7s2zfrX0RERCQeOL5RzcjIxP3sC5SVFlNeVhrWrNNIbtvsvje9vY1dO8qUo2oDRbuNz6EfrcgkERGRqHB8o+ozKntMxJrISG47lGEjsmO+QU2sKCfj+/8N9cA5wHetrshfTQPkrHSxtrA1cN73KUmZKRYWJiIiEuMcPZlKYsTRJnp//BHsAmqsLqajnJUuNlek+mXabq5IZe4K/fqIiIhEUsyMqIpEQtFuWFvowe1eHjDTtrhKlwGIiIhEioaExHper9UVBFVabXwNlmlbUhXtikREHMbG/8eL/alRFUuNGJSCa8+e1gV9raslkOws42uwTNvRGk0VEekotfXbXiVF1tUhjqdT/zY3YlAKFXsbrS4jonoVf9p6x2afTDX2RGPiVH7eYv883fxcZk10MWaIJ/RGRETizWnAVuPrMYsmI9vR5LEDKCiy4WQMG1Oj6gAjBsX21PJeRW0a1ROtqyMY9yIPc1cc8Mu09c36FxGRAM4+fgOOjZ9oaSlWunDoAN743L8xnTx2gEXVRN7hxt6sDfM2HdWoHv3lTfTPCnyu1ZOewcHFS/yW9fnr0/5NULDtTjyHIzO/5rcs5d7fkHD0aNB1amq/YH/tfpq/931OvOyrLctdlTvo534i5D4BGpbeDElJph4by/xGVIdaV0cwmSmwZqmHddtgcwlcMAamnxXeJlUZrSISD+LhLKGEl6Ma1ZP/9Dj9g/1wEKSNuNF/2UrgHRMbngq07zvuBZqCr9IfOAX45l+fpqltpuYnwD0m9gn0P+0OSG69XzW7kx3GsETfHxN9gQxLSwkokjmqymgVEREJTpOpeugnS5aEJ1PTC8lr/4+E+vrwFOYUBw+SuHOH8f1QIMHSagKKZI6qMlpFJNYNeTKJXlvfs7oMy1w4NHZP9UeDo0ZU+fvfWb95M3ffcw9/XAAnZbb5WaAz6N8EppnYbqDX0A10GGXdVQNXPwY33XQT06ZOBWDK+PE8eO65rZmaw4CbzBwM0Pv41xLgacjc/i2+eGkjR8+7wOQGnC/B46H+4VWkb7sWBlpdTUeRzFFVRquIxLSDwC+APdB/xm3sf/YFqysSB3JWozptGmPPPZeX77mHbelw0tkhHj+iB/s6s+OiD7bCy8DjixfDsGEty9tmao4ZQssF5Ka9BWw//r0nviboePv359DcH5K+5lqrSwnITI5qd5vJSG5bRMRyXuB4+mCCslSlmxx3ftHK/EplasafSP6b6/UkIiLSOUeNqD7zzDP8/KYbLcuvVKZm/Inkv7leTyIiIp1zVKO6YMECy/MrlakZZk1NRjxVJdAPW16nGsl/c72eREREgnNUo/qPn8IV51r7Bu7L1CyuMq4hNHIvo1dTaUkRFeVljByVzagofdpH+32Gs4bE3Z8z8KJzjDsXALnm141W9mgk/82tfj2JiIjYmaMa1W/+zj4Zk2OiHMxeW1tD3sL5rF/3YsuyaTNm8siqJ8jIyOxkzfDuc9DgLPbuqY5aDYFYlT0ayX/zaL+eREREnMBRk6lWrVoVtxmTeQvnU/jOFr+8zcJ3tpC7YF7U9jlhwgSajhyOag2BKHtUREQkPjhqRPXKK6+kb9++cZcxWVpSxPp1L+J2uwPmbZaVFof9MoD2+ywqKmLr1q1RrSEQZY+KiIjED8cNQbXNmIwXFeVlQPC8zfKy0ojvs7S0NOo1BGIme1RERERig+Ma1ZjMmLwA+DHsX7ma5tEdRyVHjBwFBM/bHDkqO+wltd9ndnZ21GsIRNmjIiIO0Qe41bjV/+ouq6sRh3LUqX+rc1QjZqRxOzx7bsAfZ48ey7QZM8nPz/fP21yyhGkzZkbklHugfU6YMIHFixdHrYZAlD0qIuIQicCpxrfNp42ztBRxrgSv1/6fa1ZfX096ejpgn1n/kVA1uynoz/bvryV3wbywzvoPFTMVaJ9mZ/2bjbBK3FHBoPFjjTsm46lqG2HuiujP+o+kaEVtxTs9zyLWaPv+VrG30cJKrPHG5zVWlxAVhxsP8ItZE6irqyMtLS0s23TUiOp7d8DEEfE5YpaRkYn72RcoKy2mvKy0RxmmZqOugu2zsxqiEaMVS9mjVkVtxRs9zyIizuSoa1SzB1tdQYTUABXQ6/1CEhoaOn3oqOwxTJv+1R6dau9q1FX7fXZWQzRjtMYMgZkTnD0ypqit6NDzLGKBY8AW49b7zdetrkYcylEjqjHr38AaGMh5fPHiaxy94KKI7SqSUVfd2XbzSSezZ3sFg9ePgKQeHZrjKGorOvQ8i1jkCPCQ8W3/7XdT+9w/LS1HnEnDCXEmklFX3dp2r154ThwKmUCcnYJV1FZ06HkWEXEuNapxJpJRV1bEaDmZoraiQ8+ziIhz6dR/nIlk1JUVMVpOpqit6NDzLCLiXGpU49Ajq54gd8E8cnJyWpb5ZuZHe9sJdXX0/dMfYDswFPhSj0twFPciD3NXHPB7vnyz0SV89DyLiDiTGtVuiGYWY2lJEW++vomEhAQuuOjisIxKhjPqqqfbdu2vJe3Wm407FxB3jWosRW3ZmZ5nERFnUqPaBdHMYqytreHHV8+h4LX1LctcLhdfmTKVR//457Bkko7KHhOx0/GR3HYsGqMA+qjQ8ywi4iyaTNUF0cxizFs4n22F7/rtKz09nS1vbIpIJqmIiIiI3WhE1aRoZjGGyiNdv+7FHuWdioiIiDiBRlRDKNoNL26Fgk+M+9HIYgyVRwo9yzsVERGJimTj5k1OtroScSiNqAYR6HpUMLIYfaOcEKYsxv8GZsOe6bvwpGcworKi032BMklFRMTmUoDVxrf7Zz9naSniXGpUg2i9HnU5kydPpqCggGuuuYbcxRHIYuxj3DyDBgOteaS5ubl++8rPzyc5OZmvTJmq0/4iIiIS89SoBhDsetSGhgauu+66qGQxPrLqCX48f47fvnyz/sORdyoiIiJidzHfqL60DbaUwAVjYPpZ5tZp/9ngL730Elu2bGH06NF4PB4e+xGclGk+i7E7uasZGZk8/Y+1lJUW8+brmwDClqPqU1pSREV5WadZp2Ye4wTdeR0EE80cXREREafYt2tH2LcZs41qaTVcdHsi1fubW5ZlZSTy5rJmRg7ufF3fZ4M/99xz3HPPPVRXV7f8LDExkVGDm5l6RugaTOeufgSUQkrRPRz6zlV4Th7W8qNI5JHW1taQt3A+69e92LLM9+lRvnxWM48JB2/v3hwddwa96z+CAWHbbIuevA7ai2aOroiI4x0GnjS+7Vf5MAcX5VlajkTOwfr9PHXHDXy8eUPYtx2zs/4vuj2Rw97+fjmkh739ueC2xJDr+j4b/KabbuLw4cN+2+jfvz/f/33obUAXclffB56B1NtuIXFnZTeOtmvyFs6n8J0tfnUVvrPFL5/VzGPCwTP0JL54oxDuBr4f1k0DPXsdtBfNHF0REcdrBjYYt+RXX7a2Fomop+64gd2fbmPVqlVh33ZMjqi+tA2q9zcHzTx9+YPQp3/nT/awttDD8uXd20Y0c1e7IlRGa1lpMV6vN+RjnHAZQDheBz52/fcUERGx0t6d5Xy8eQNut5uvf/3rLFiwIKzbj8mhoC0lxtdgOaRvFofexse7eraN9te5tl8/nLmrXREqo7W8rNTUY5wgHK8DH7v+e4qIiFhp32fGdant3x/DJSYb1fNGG18LCgr8lvtySC8wMRjY0234rnMNtn6Pcld7YMTIUUDwukaOyjb1GCcIx+vAx67/niIiIlYaeNJwoOP7Y7jE5Kn/y882Jswsbpd5mpubS1ZGItPPao74NnzXuebnRSB3tQd8Ga35+fn+dS1ZwrQZM1tO6Zt5TDi4qqtIXzAP9gHjgCvCtumwvA587PrvKSIiYqVBw0Yy7vxLyMvL5+DBg2HffoLX6/WGfathVl9fT3p6OnWPQVo/c+uU74ELbuvZbO+ebqO2EeauMDFL/C/AGuPbL158jaMXXGSuwG7av7+W3AXzOp3Rb+Yx4ZC4o4JB48cady4AcsO2aSA8rwMf0/+eIiICjcDxyxWPTP8qtc/9E4CKvY3W1WSRNz6vsbqEiDp4oI6nfn19y6z/uro60tLSwrLtmG1UfV7+wLgWsSf5mX/cCK9+BNPOgHlTur5+cZVxDWPQ3M0QjWqkskzLSospLyvtdLvBHhOqJrM1R7pR9QnH68Bn3TbYHKZMVhGRmKVGtUWsN6o+H2xaxxO3LAproxqTp/7bmn5W95uJ9rmZ7tfhube7PoI2ppvB8JHOMjWT0dr+MaFqilb+alf15HXgoxxVERGRjpSjahGrczOjlWUazprsWHO4WP16EBERsSPlqFogqrmZmcBwOJo2Hm8/49oGM3mn0c4yDVXThldftl3N4aIcVRGRLkoEvmx823TeBZaWIpGjHFWLRDU3cybwG/hi09scGz8RMJd3Gm2hanrvnbc6/blT8lcDUY6qiEgX9QF+Ytwal95sdTUSIcpRtYjVuZl2zDINVdOXzp3U6c+dkr8aiNWvBxERETtSjqpFrM7NNJt3Gk2harpk6nTb1RwuVr8eRERE7Eg5qnQ9nqpot3GqdvQQ8Hpbv+/qNYTRzs2smt3kdz9aWaZdEaqmrtYcrXiqcFCOqohI97R9f1M8VexRjqrJRjVQfJDL5cLjMe53t6kImYPaU68Am+HICVM4cPf9HDvDP0fJTN5ptIWqyWzNCbU19L//HlLK7ofhQGQ/6yAsIv56EBGJBY3A8UtTD02fS93K1YAa1Vi2q+hDfnftN9SoBjP7PiM+6KGHlzN58mQKCgrIy8tj4sSJXH311eTnLeb8EQdYs9Rmp2mj/MlUdjRkTZLVJYiISDgp8L9FvDSqhxsP8ItZExT4H0io+KCVK1fy4EOPKEpIRERExCFiZtZ/yPigkhJFCYmIiIg4SMw0qiHjg0aPVpSQHXm90NwMHoybiIiIyHExc+o/WHxQfn4+U6dOZcuWLYoSsqHEyh2OmfUvIiIi0RUzjSqAe5GHuSsOkJOT07LM5XLx6quv8uqrr7bM+hcRERER+3N0o9o2L3XMEMhMgTVLPX7xQeBpEyXkzCa1tKSIivIyW8VTtRWoPrvXLCIiIvbnyEY1UF5q24zUMe3yLZ06w7+2toa8hfNtFfjfVqD6Jl86DUig4LVXWpbZqWYRERFxDkdOpspZaeSlut1uKisrcbvdbK5IZe4KRx5OUHkL51P4zha/4yx8Zwu5C+ZZXRoQuL5the+y5Y1Ntq1ZREREnKNbI6rLly/n3nvvpaqqivHjx/Pwww8zadKkkOs9/fTTXHXVVXzjG9/g+eef786uQ+alOjIjdRzggobspXiGngQYp87Xr3sRt9sd8DjLSostPaUeqr5JkyYxbNgwW9UsIiJRlARcY3zbOHOxpaWIc3W5UX3mmWe4/vrrWblyJeeddx4PPPAAl19+OZ9++imDBw8Oul5FRQVLly7l4osv7n61P4Nhx2AHMPRnP4Obb2750feam5kMfNSuUd33J0h5E3olQu/ETrZ9GnBdu2W/Acxkrl4BTG1zvxZYZmI9MD5eboJxa5j9m5bFFeVlQPBc2PKyUkubvlD1lZSUMGbMGL9lIWs+GoFCRUTEGr1peW9suuxyS0sR5+pyo3r//fdz7bXXMn/+fABWrlzJmjVrWL16NT//+c8DrtPc3MycOXO47bbb2LRpE/v37+9etbXQFzgF4PPP/X7U6/jyI8ebVN91rNMKPVxvZtv1AZbtB74wse7hdvc9JtcDaA68eMTIUYCRC+sbsYTWXNiRo7JN7iAyQtU3evToDssC1ezJHIA3KYmEpiZ4F3gHODdydYuI2EoF8KTJx96M/7v2q8DrJtYbDvyg3bJVQLWJdS8FvtLmfiNwv4n1AK4FnHaGU2ynS41qU1MT7777Lje3Gcl0uVxcdtllvPnmm0HXu/322xk8eDDXXHMNmzZt6naxzVlDaHa5qK35gqNNTaRnZJCUlERTUxN1+/fTOymJ1GsOUAXM/e43KNyxhTu/OYVjb7zh95jMASd0PLZTL6Zutv//FpkrptPLUxyyroYv38Kh2T9que/a/TknnHihqWOqmfoSzWNO7bA8e/RYps2YSX5+vn8u7JIlXHjJdFxpQy39vOTE9JO48JLp5LWrLzcvj+TkZLa9gVAoAAAgAElEQVRs2UKfPn1C1jxiUBoN199E6l2/Ai+wAngASLXiqEREIuQw8CYwCUhps/wg8InJbXjb3d9jct2EAMsqME5PhnJ2u/vHTO4TWgZxqmY3te7WwvctK7zxeY3VJThelxrVffv20dzcTFZWlt/yrKwsPvkk8Cv3P//5D48//jhbt241vZ8jR45w5MiRlvv19cZw5763P+RIWhr799eSu2Be4Nnw+F8/efbx0b5ewN/dbnJycnj9Xy+bOm1e+6+XTdfclufEoezdXtGtdX0q9jbys9/8ntuWLvDLhb3wkuksu29Vj7YdLsvuW9WhvkkXXQp4TddcsbeRETfdQq+yUvo+/xdYhJpUiT81wIEAy4fhP+W1lsBnf9pLpuNI1m6gKcBj28sA0tvcbwZ2mViP4/tMbnO/EdhnYj0XxrG2te/4+qH0Awa1W7aLoGer/JwA9G9zvwnjeTLjJPzfQeswzsK11wS8AfwHoyk9AnzV+FHV7CaS0jYygOmmdlk18wAktz7B/d/5Bf25N+R6TQMmUzP7Fb9lJ9z1ZXrzfsh1D5z2Kxpn39Ry37V3D4M52VS9+76yhWPjJ7bcj/cmtaAo9pvWo4cawr7NiMZTHThghO8/9thjDBw40PR6d955J7fddlvQn2dkZOJ+9gXKSospLytl5KhsvF4v7769hZGjsqNyfWckckLb/xKnpWfw28eeZWdFKbt2lHHy8FEMGxH5U/6V5SV8Vlkecn+d1deVmiv2HWTEw4/SuOQGBlacE9ZjEbGtY8B7wMvAx0Ee80eMCSk+64B/mtj2qcCt7ZY9gjGKFsp3gW+0uX8Q+B8T6wH8GhjZ5v5W4Pcm1usPPNpu2XMYzV0oFwLt5+ncgbmG/sdA22kTnwO/MLEeGMfVtqEvAJ4OvdqxzWPZ99AHkGAMczZddDFVe0y+uffu7Xe34Re30XCziQkRCR2HVL949Q3jI6xDSfSf3OEZOMh8vb2MFqP9e1u8jTLGQ4MaSV1qVAcOHEhiYiLV1f4XtlRXVzNkSMcLUUpLS6moqODrX/96yzKPx8g+7dWrF59++inZ2R2bmJtvvpnrr2+9srS+vp5hw4ZRua+RlCOtvzSutKEMHNGXG29YyBsbWkc/vzTpIiD49ZNJGd0/bV63v5bbb/Tfn2/EMC09o1vbDKbllzkpE8acw05gZwR/wQ/W7+epO27g480bWpaNO/8SrrrlfvqlpgdfMVB9Xaj5wqEDqKg/xogzzqLqjCaGrDn+zvws5kZjzgPa9rcHgSdMrAfwbaDtHMBPgfUm1usDXN1u2StAkYl1x0CHAZRlGKNHh4/fgr1//Ajjo2Z9yjGaAzPaX1LxL+AfJtYbAfyy3bK7MXess4H/bnO/CWPUPB3IBkYfvw3HoanO3XAAozl9FWOEVOKCt29fDv33dzl4zUL/xtHlgqSk4Ct2plcPfmnaNb2mJSR0qV41qf7Hu+3jPRZVEh2eIwfDvs0uvcqTkpI455xzWL9+PVdccYVRlMfD+vXryc3t+CHtp512Gh988IHfsltuuYUDBw7w4IMPMmxY+3M9huTkZJKTkwP+rL3bb1zI9m3v4na7mTx5MgUFBeTl5zNg4OAO10/6rpXsyahksP3dtnQBv33s2W5v18fKX+Kn7riB3Z9u8z+2vHye+vX1XHP34xHb7xuf1xjN6t5GRgxKoWr28Wb1fcyNAJ2Ef6N6DHMTDABmtru/1+S6qXRsVIu6sN/2jepuzJ3mbP/hal46TuYz65jJdY8EWWZm3WMBlvma8WqMU6JgzA6eAXzfxDadrhH4m/+iY9mjabr4kg4jX/Wzf+fXFCR7XyD5hHUhd3FsVDYHZ/tPI0355C4Sd+0Mue7hWV+nafpXW+4nNDSQOv+mTtZo1fBfP8NzyvCW+72z3qLvoT+FXM/bL4UDs+/xW9a39k/0HvNWyHWPfunLHJo9z29Z6g9/TkJDoGsp/B361g84+uXzWu67du2kf8ldIdcDOPC1O/GmpbXcT+qzjj59Xwj42GOnn8Gh716F9/iHnsTbKXCIz9PgbcV6gxpJCV6vmbH/Vs888ww//OEPefTRR5k0aRIPPPAAzz77LJ988glZWVn84Ac/4KSTTuLOO+8MuP68efPYv39/l3JU6+vrSU9P5461W+mT0joktHdnOXfNvcwvyxPAffxa1Ozxkyh9v/U/OlOjg50Itb+f//kVBp08spMt2JfVx3bh0AEt348YZMw0OGHyJHpvC31t84Fbf0Xj9a1vpAn79pI1+iRT+923YQvHJrReQ9XnmT+TsXB+yPU8JwxkT6l/8kT6gnn0ffYvIdc99N2rqFvl/+Y9cPypuGpr8Kam4u3XD29i4Cy1hv/9DUe+Orvlfq+PPyT96jkBH9tezb83tLxRAvT942P0e/SRkOsdO20cdU885bcsfeF8er3/Xsh1D/3wRxxclNe64PBhBk6ZROKOChIOB+h0H8X/msFYdTd4P3RxZObXOPijH9M0ZaoxsiYxLR4bVPBvUuOtQYX4alI9Rw6y4/ffoa6ujrQ2f8j1RJfPG1x55ZXs3buXW2+9laqqKiZMmMC///3vlglWlZWVuKL0H+6+z4wpi8GuRb30+wv5zs9+w75dOxh48vAeN1qh9rdv146wN3PR+qWu/uBDIPixbdjyIVkHu9fghzJ57ICWUdW2av/yNxKOhp794cn0X8+bOYC9hdtN7bt5qP+kgCOz/svcugkdX+MHfn03DTe3P0fekTelYye2b+snAa8jC+XYuDP5YnPoCRGBHJp/LYfmX9utdese/WO31qNPH/Zt2QZHj9Lrow9IensL/X7/EL3KS42fx0mW7t5VW/Gm9Mcz7BSrS5EoUZMan9o3qbs/CnZBemzwHuvuKb7gunWBS25ubsBT/QAbNmzodN0nnniiO7sMaOBJximmYNei+prTcDWPZvbnVCmDjIYt2LGlDA58mUYkeU7u5j4TE2ke2b3LO7ypqTSndi92wDM4C8gK+biAutGkOlrv3hyb8CWOTfgSSQWvtTaqcaL5tHFWlyAi4giOnr4waNhIxp1/CXl57a5FzV/CuPMvCfvoZrT3F039hwxnyNkXkdvu2PLylzDk7Ivon6WRHxEREYkuRzeqAFfdcj9P/fp6v9xO37WosbC/aJp49e0Urr7V79iGnH0RE6++3cKqJNZ5MgeA79LZWB5Y9gLHT0Rl/L8r2P+M+ev0RUTileMb1X6p6Vxz9+Ps3VUetmtR7bC/vTvL2ffZDvbsPojX00zK4GF+o5oNVTto3Lurw/KeSEpJ47y8B2iorqRxz86wbjvSIpFr6wSxcNz1D62k3+WrrS4jOo4Hwrtq4/u6PRERsxzfqPqE81pUK/cXKMvU5XLh8XgYcvZFnHHlUj565j6qtrXmIPlGPZNSwjPDrn/WKY5pUGtra8hbOD/wp5S1meEea2pra7juRz9gw/rWqKJLps1gxeNPxvRxi4hIfFEeis20zTKtrKzE7XaTkZHBhAkTOLxzO2/c8yMO79zu9/PDO7dTuLr9x9DEh7yF8yl8Z4vf81H4zhZyF8yzurSIuu5HP2DTBv9PJti0YT2LrskJsoaIiIjzxMyIaizYu7Ocjzdv8MsynTNnDl6vl5ycHG688UbuvfdeHgvy84bqSseMhIZDaUkR69e9GPT5Kistduzp8M6UlhT5jaT6NDc3s2H9upg9bhERiT8aUbWRUDmtzc3Nnf68cU/oT52JJRXlZUDw56O8LDYjj3zHHYzTjrvfw7+DhzBuJj9CXERE4oMaVRtpm9Pali/LNPH4pxUF+7kVWadWGjFyFBD8+Rg5qvsflWtnvuMOxmnHnfTWm7AF4xYngf8iImKOTv3bSLCc1iVLljBhwgQe+8Pj9E0/QVmnx2WPHsu0GTPJz+/4fE2bMTNmT39njx7LJdNmsGnD+pZRdjD+kLn4kmkxe9wiIhJ/1KjaTKCcVpfLRU1NDUPOvohzv3cjHz59r7JOj3tk1RPkLpjn93z4Zv3HshWPP8mia3L8rlW9+JJprHj8SQurEhERCS81qib5ck2jndP6UYAc1fPyHmDPR5upKfuAAaPOYvAZ50esHjPMZLpGIvcVICMjE/ezL1BWWkx5Wamj80S7IiMjk6f+9q+4O24REYkvalRDCJRr6vskqn6p6RHbry+ndW+RfzB4U2MdhauXRTRH1SwztUSr3lHZY+KyUYvX43asBcaXxmk/t7YOERGH0GSqEALlmu7+dBtP/fp6S+opXL3MNjmqZmqxU70ilkoAphi3I5fPsroaERFH0IhqJ0Llmu7dVR7VT8NqqNpB1bbXg9YTzRxVM7Xg9dqmXhEREXEejah2IlSu6b5dO6JaT+PeXZ3WE80cVTO12KleERERcR41qp0IlWs68OThUa0nZdDJndYTzRxVM7XYqV4Ry3mBSuOWWFZidTUiIo6gU/+dCJZrmp+/hHHnXxLV0/4A/YcMZ8jZF9kiR9VsLXapV+yrafKl9Kl/3riTZG0tEXez8SX9H1dTs66g88eKiEhsNqqfvrWJHR9vZfiZEzj13It7tK1AuabZ4ydxzle/FfVrVAEmXn07hatv7VKOaqSioczU0p16Jb4cvHYRaUOXBPxZ0W4orYbRQ2DMkCgXJiIiloupRnXfZztYnvtd6mv2tSxLGzCQ3N//lRNO7N5p5ra5pruKPmLzP/9CSeEWSt9/C4hOVFVbSSlpnJf3AA3VlTTu2dlp8xnpaCgztXSlXhGfmgbIWelibaGnZdmsiS7cizxkplhYmIiIRFVMXaO6PPe7JDQf9YtCSmg+yiPXfbvH2x508kjee+kffFFRbIuoqv5Zp5B1Vuenz6MVDWWmFjOPEfHJWelic0Wq32t3c0Uqc1fE1H9ZIiISQsyMqH761ibqa/YFjUL69J1NPboMwG5RVaHYKcpKpCuKdsPaQg9u9/KAr93iKl0GICISL2JmeGLHx1uB4FFIOz7c2qPt2y2qKhRFQ4lTpC+YB9di3GqNa1Ih+Gu3pCqq5YmIiIViplEdPm4CEDwKafiZE3q0fbtFVYWiaChxioRDB+Egxg3IzjK+BnvtjtZoqohI3IiZU/+nTrqYtAEDWbx4sV8UUm5uLmkDBvZ49r/doqpCsVOUlUhXjD3RmDiVn+f/u7wkP5dZE12MGeIJvREREYkJMdOoAuT+/q88ct23/aKQfLP+wyFQVJVv1r8dKRpKnMq9yMPcFQf8Xru+Wf8iIhI/YqpRPeHEYSz7xxY+fWcTOz4MT44qGBOp9n22g4EnD2+Jqtq3y7jffiS17WOtHmVVNJQ4VWYKrFnqobjKuCbVyFFVkyoiEm9iqlH1OfXci8PSoB6s389Td9zAx5s3tCzzjaC2b0I7e2y0MlaD6Z91ihpUcaQxsRb0/4jxpXbm362tQ0TEIWJmMlUkPHXHDez+dJup3NSuPFZE4lACkGncvCcMtLoaERFHiMkR1XDoSm6q0zJWRURERJxAI6pBdCU31WkZqyIiIiJOoEY1iK7kpjotY1VELOAF/s+49Xnmz1ZXIyLiCDr1H0RXclOdlrEqYieNi39Cn+HPG3dSrK0l4p42vvQre5TDV86xthYREQdQo9qJruSmOi1jVcQujp5/IXxhdRUiImJHMdmots0yxUu3c037paaHzE3tzmO7qqFqB417d0U1B9WKfYoEUrQbSqt9WapWVyMiItEUU41q+yxTl8uFx9MaEt7dXNNBJ4803XR25bGhHKzfz5aHf0LVttdblvk+WSopJS0s+2ivqbGOwtXLorpPkUBqGiBnpYu1ha2/w75Pp8qM9UsEREQEiLHJVG2zTKdOnUp6erqjc02fuuMGDu/c7ncMh3dup3D1rRHbZ+HqZVHfp8S3xJIiKMG4HWtdnrPSxeaKVL/X4uaKVOauiKn/tkREpBMxM6LaNsv0y1/+MnPnznV0rmmobNaG6sqwn5JvqNpB1bbXo7pPkdTbbjFmw4PxyU2Zxun+tYUe3O7lAV+LxVW6DEBEJB7EzNBE2yzT0tLSlu/bclKuaahs1sY9O8O+z8a9u6K+T5FASquNr8FeiyVV0a5IRESsEDONatss0+zs7Jbv23JSrmmobNaUwcPCvs+UQSdHfZ8igWRnGV+DvRZHazRVRCQuxMyp/7ZZpg899CBTp04lLy/PsbmmvuPJbZfNmpe/hCFnXxSRU/D9hwxnyNkXRXWfIoGMPdGYOJWft9jvtbgkP5dZE12MGeIJvREREXG8mGlUoWOWqcvlcnSu6VW33M/y/8nzOwbfDPxImXj17RSuvjWq+xQJxL3Iw9wVB/xei75Z/451/KRE84hR1tYhIuIQMdWoBsoyBcKea9o2pzWSo7P9UtM5L+8BGqoradyzMyqZpkkpaVHfp0ggmSmwZqmH4irjmlQjR9XBTWoCcJfxbd3sJ6ysRETEMWKqUfVpn2UazlzTtjmt0P1s1q7on3VK1JtFK/YpEsgYBf2LiMStmJlMFQ1tc1qdms0qIiIi4hQxOaIaCaFyTZ2QzSoiIiLiJBpRNSlUrqkTsllFxEJe4DfGLfXGn1hdjYiII6hRNSlUrqkTsllF7Khu5R9hFcYtcpd628NHxq33++9ZXYmIiCPo1L9JbXNanZrNKmJH3pQUSLG6ChERsSM1ql3QPqcVnJfNKiIiIuIUMdOoRiPbNFBOa7RHUhuqdtC4d5cj8k2dVKtVSkuKqCgvY+SobEZlj7G6HBEREVtxfKNqRbZp+5zWaGhqrKNw9TKqtr3essz3iVFJKWlRrSUUJ9VqldraGvIWzmf9uhdblk2bMZNHVj1BRkamhZVFX59/PAf/On5nJtDXympERMROHD+ZKl6yTQtXL+Pwzu1+x3l453YKV99qdWkdOKlWq+QtnE/hO1v8nqPCd7aQu2Ce1aVFXZ+/Pwd/w7gdtroaERGxE0ePqMZLtmlD1Q6qtr0e9Dgbqittc2o9LLUeO0affzxHr5LiTh/mTU6m8fqb/JYlr/knvbdtDVnnsdNO5/A3v+O3rN8jD+A6UB9y3cMzv86xCRNb7rv27qHfH1aGXA+gcfFPKNlTxfp1LxrP0bhx8NxzzElOJvub32T5449Tt+JhBg8d6reeNzWNpqnT/Zb1fn0Trn17Qu6zedRojp01vs3GvCT/8++m6j16wVfwDM5que+qrqL35tc7WaPVkW98y+9+rw/eJ7GsBLxeXDU1JFZWkLizkt5vmtteLEksLyP5+b9y5IpvW12KiIitOapRPW9IJimpraeO3yx+FwiebTr4UA0XDD0negX20Buf13RYNnnsALbXbDO+D3KcI3vv5/SxEyJfoAndrfXCoQMAGDEohfSF8+n7zJ9D76wPpJ76S/9lq4CNJgqdBCTN8V/2W6A29Kr9a34Nn7VZsAu428Q+gf4n/Zr3dhrfT548Gf72N7jhBgDOP37j5hs6rHf0tNP5YvP7/tu6706SX3sl5D4br1vCgbaNKpD5w6tM1Vvz9zV+DXKvD943vW7V/ia/+33/8iQpKx4KvkICkGRq086VDByBxL17yPzn96lq06gmfvIx/R+4z9Rm6h5ZBb1a//vu8/dnSV7375DrHTv1NBp/+jO/Zf1/vYzEXTtDrnv4m9/myOWzWu4n1NWRdtNPTdV74H+W4TmlNcKv95uv0+9Pj4dcz5OaxoF7H/Bb1nf1KpLe2hxy3abzL+TQvB/5LUtdmo+roSHkugfnX8vR8y5ouZ9YUU7/u34Vcj2A+nsfxJua2nI/ee3/0fu9txl73oUc/fL5lB/tbWo7seLCoQP83tsmjx1AQVHH97pYdfa4wWz7uHVA4cQzxllYTeR5jhxkx6vh3aajGtX2TjrFGC0tKChoGb2D1mzTk4ePsqSu7vI1a2298XmNX4ZroOO0U4Zrd2pt26QC9D3jz0bT4o1wsRbJPj5AWVBQwJwjR0yt0/vAdoasadfF7TW3v5TyB0lZ82Drgi48rwO2zIZDbRa8H/ShHXSot7yTB2cA04ntmKoE4HvAX4FG4NR2z9FHwNPmNtV3ptv/f++/03qdb2fGQerYW/yXPQtUmtgnbjjWZkEd5us9yw0j2izYZHLdNEi55Pf+y/4KvGFin7vcpA+6zn/h00DoPpW+A9ywr82Ccswf6yVuSG2z4HngOeNbb0ICA04fx9HzLqTpvAs4dtoZkGhcgefJyMQzzP9sU6+PP4Tm5pD7bB52Ct6217YfPEiv0s7PSPkcO/0Mvz96XHuqcVVXhVzP27cvzaPH+i1LLCshobGx9THJyZSmn+T33vbG5zVMHtvxvS5WFRTVcPa4wS332zatYo6jGtVxK+8mZdRoDv44F4ARg8YzbcZMPliwgI///GdOHjaMXTt3sv+113hm+EhmveA/Knfk0mk0TZvRuuDwYVJ/vczUvg9eu4jm4SNa7vf6cBt9nw496udNTqLhl/5/iSc//1eS3nnbb5knNZVjZ5zFsbPG03zKcCr2HQSON3FDB1BwyXTy8ttluC5ZwoWXTOcbk2w0atyNWkdkJkOvXq1v2tnAXIxJNZ3NKwp0hfVMjg9LhhBoTtd1+L8RB3NSu/sDgZsCPTCAVBibBLMmusjPW0zqzb/gwuXL+XTbNp598v9x6oDDXDfF27GZ7B9gW1OBs03sM9DVL983We+JAe6bXbe9LwG+96d+GM/bQOAEYn8k1WcGcBnwOTA4xGMl5iR4vfT++CN6f/wR/f74mN/PDl05h7pH/+i3bMDXpuOq+SLkdveveoLD3239xexV9AkDLzHzHyFUl36O94SBLff7PvlHUn8Vej7B0fET+WLjFr9l6bkLSXpjk9+yzBGjOHjNAg7NnUf5seSAAzKxqn1T3r5pjUVHDzUQ7s/pTPB6vbYft6qvryc9PZ06IC0buL31Z7WNUPVTOL0x2NptfBP4NhTthtJqGJMBo39hsohlQNs/HrcAnZzFbNEHaH+G6zFgQ/BVjvVP5Ythp3Bo+uX0uf0uAPbvryV3wTyGt5klfvq4M5nzw6vp17fjMNSRqZfhOXlYy33X55+R/Mo6AD7Z/hGVO8oZPnIUp57a8TTEoZx5kJDQcr/6+b9yaPMbDBw0mEGDstizp4ov9u1tue/TfOKJNE3/akut69e9yDcxes1gtfb6dDu933qTpLwtkBj8OYk1tY0wd4WLtYWelmWzJrpwL/KQGcujijHO93/L6CEwZkgXVz4CtDkjWr4XKvfB8EEwYmC7xw7BGKH1qccYpQ0lCeMPg7b2Yu4PtFT8/2BqBswODrX/Y+QgxohsKC4gq92yWsxNuutDxz90qzB3RiEd448pnyYgdL9oyML/j+g6YDtQdPy2A/AEWO8rwKJ2yxZiagSY64CL2twvB24J8tj2VuI/AvwCxih7KCOAO9ot+xXwSeCHe/v04dC3v8fBHy2i5KSxgR8UwwJd2heLDjce4BezJlBXV0daWnhSfhzfqALwv4CJsxxPDoYns1y8/IHxv0R/4IDZIqLYqPq4gacmuvjtP3a3RBZlZSaTYOKfrOa5f9I0/ast95Nee4UB35zVyRqtqmoOg8vVEqH01XUvstTEekcumUbt862NdFlpMeOumEXGThN/X30P+Lqp8mJKcRWUVHWzsRHbqGmAnJXh+cMjnNsSGzoMlGC8Z7XtXUYDU9o91o3xB0woU46v77MX+KfJeuZgvE/5bAXeNbHeCcAV7ZatwfhjwKca45KWduoeXMGhH17Tcj/5Xy+Q9MZ/Qu7y2NhTO1x3nPK7e3DtDX0d1OFZX+foV1rnTiTsr6X/Pb8JuR5A40+W+k0q7f3WZvo8/7dO1/EMHMiRr86mZOAIv4GfWPdq8Y44b1RvgrR0oP1ljpX4X0cHLH0qgY+q+vHTn97A+PHjef/991l8113s69uXR5YvZ/LkyWzasIEnFy/ijCEHue+qEE/DMPz/wj6AcfouFBfQPse9io6jCfvh6Wcgs6YXX0lNI6Wmhve+9z2mv/Qi5484wJqlx9+05mJuROBGoO2cpQ+Au0ysB/CkUffs+1xsrkhl0wUXMW7t2tDrnQnc3G7ZTRiTjTqTCHyHuGxUJTb4flceetj4v6WgoID8vMX+v7sWbEvEcp8DrwAFGO/TiRiDPBltHvMkEHouoHGpU/vLrG7E3HvxXIxLw3z2AUtMrAdwD/6XfL1KxwGoALwJCez9tLKlya3Ya+a0h7M1Hqjnsi8ND2uj6qhrVBmNf7Po0y7tqGg3/LbYi9v9KDOOT+gZceaZlNx+O+7Vq1sm+Xw/JwdPQgI5OTksTO/iiFYqcGp3DgLjtF27fRXthquqwe1+gpQ5c+CLL/hSQgIPrl1LTk4OxVXH67sm0AYDGOZ/d0O98cf5j665hvPPb712afPmzfzh8ce5fiaM8/0iJhj1rC304HYvZ9zo0VRdeCG33HJL0PXv+A5kjQhQx7fo/JSkCzgdXa8njtX2dyVQJFvL726UtyViC0OBHwDfBV7HuIQio9M1YkbCWC+D3x5G1WwjAcU3YTiWHUgOPfmvq5zVqJpUWm18bRuRVFpa2mEZtMYmlVj8BtCh5hOMC8k61Hdp97ZfUG38Abhs2TIY1trFnnT55Tz++OOc0g9ubbNtv3qGDaOwpqbT9b81AmYGSsia1L16RZwi0P830L3/W8K5LRFb6QNMC/KzyzE3CTbQQNVi4KiJddtf552OcdmgGe3XPYcOg0F+vBjXCcfPvLGIcvwnUwXSNv6nZVl2dodl0BqbNNri//wD1Qzhq++80Z1v/4J2lye0r8fuz5+IVcL5uxvp/wdEbGkwxiVyoW7tE1fAmNRlZt32E+t6m1xvDEb+cVvpIR4/FqP5/nKXngUJIiZHVMee2Br/44tIeuutt0hOTiZ38WK/2KQl+bnMmuhizBBrr/0KVHM467v8bMjKSGRxu+PPzc0lKyOR6Wf5D9cHqmfChAkd1rfL8ydilXD+7kb6/wEREadx1mSqxyAt0NB/ABKjb2MAACAASURBVIHif6aflQAktMz6B3vNpo10ZFH5HrjgtkSq97c2pVkZiby5rJmRAa4RDVRPVob/+nZ6/kSsEs7fXUWXicQIN/AOHOs7gtp//pvmEc76EKLuOFBfz9hTBsbxrP8uNKo+xVWw4WMjHWLK6cb1XXaPBOppfaGyHF/+AN4sNk73Tz+r6/XY8fnrUX6lSJiE83dj3TbYXGL+91REbGYlxqewAXvf/oDmMd2dge0ckWhUY/LUv09NA/zEHXhkws7NzJhuvsmZzV+cflbX3vja19Pd+iJBmZNiJ+H43dBrWkSkVUxOpvLJWWnkEbrdbiorK3G73WyuSGXuitg87Hg7XojPY5bYpte0iEirmB1Rjbc8wng7XojPY5bYpte0iIi/mP0T3UweYSyJt+OF+DxmiW16TYuI+IvZRjXe8gjj7XghPo9ZYpte0yIi/mL21H+85RHG2/FCfB6zxDa9pkVE/MV0PFW85RHG2/FCfB6zxDa9pkVihOKpwrLNmG5UfeyY+9mZYJmgZrNC2x9vPGSMOu3fWCQUvaZFHE6Nali2GbOn/tuyU+5nZ4LlJz6c4yHvSfMjLL7jrWmA2ffFx8iMU/6NRczSa1rE4S4GRkPdWY/gGZRldTWOFbOTqZwoWH7ihbcnditXUXmMIiIiFjkDuAwOXb0Ab0aG1dU4VlyMqDpBqPzE++77ZZdyFZXHKCIiIk6noTWbCJWfOGjQoIDLg+UqKo9RREREnE6Nqk2Eyk/cu3dvwOXBchWVxygiImKh/cBuSCwpgqYmq6txLJ36t4nO8hOzMhL5zR2/Iisry3SuovIYRURELPQ0sAkGcWbczPqPBDWqNuJe5GHuigPk5OS0LJs10cUjP/CQ+/86Lncv6rzZDLa9UOuJiIiI2IEaVRvJTIE1Sz3t8hONpjLY8u5uL5Si3bBxOyQkwJTTNfFKJJriIftYRMQMNao2FCw/sbu5il1Zr6YBrnwkgVc/SsDjaW1qp5/l4pm82MtfFbGTYFnKsZh9LCJihiZTiZ+clS42FSWRnp7ul7/6dqXyV0UiTdnHIiL+NKIqLXzZq3CExx9/XPmrIlGk7GMRkY70Z7q08GWvgvJXRaJN2cciIh2pUZUW2W0+ilj5qyLRpexjEZGOdOpfWviyV9d/3Ju8vDy//NW8XOWvikSSso9FRDpSoyp+3Is8XPlwE+s/OuqXvzr9LOWvikSaso9FRPwleL1er9VFhFJfX096ejp1j0FaP6uriQ/FVUaOKihHVSTa/LOPra5GRLqlHjgMey/9lOahJ0FSktUVRdyB+nrGnjKQuro60tLSwrJNjahKQN3NbBWRntPvn0gMSDNuzSNGWl2Jo2kylYiIiIjYkhpVEREREbElNaoiIiIi4fYB8BL0e3Q5Cftrra7GsXSNqoiIiEi4vQ5sgjR+ypGpl9GckWl1RY6kEVURERERsaWYGVEt2m18BGEk4lzabzuS+zKzf6dwat0idqDfHxGRGGhUaxogZ6WLtYWtgdi+gOzMlPBvOysjker9zWHfl9n9R3J/4eLUukXsQL8/IiKtHH/qP2eli80VqbjdbiorK3G73WyuSGXuip4fWvttT5gwgcPe/hHZl5n9R3p/4eLUukXsQL8/IiKtHD2iWrQb1hZ6cLuXM2fOHADmzJmD1+slJyeH4qrunzJrv+2ioiK2bt2K2+0O+77M7D/S+wsXp9YtYgf6/RER8efoP9FLq42vkydP9ls+ZcoUwPgIwnBtu7S0NGL7MrP/SO8vXJxat4gd6PdHRMSfoxvV7Czja0FBgd/yjRs3AsYkhHBtOzs7O2L7MrP/SO8vXJxat4gd6PdHRMSfo0/9jz3RmGSQn7cYr9fLlClT2LhxI0vyc5k10cWYIZ7QG+nCtidMmMDixeHfl9n9R3J/4eLUukXsQL8/IiL+Erxer9fqIkKpr68nPT2duscgrZ//z2obYe6KyMyQDbTtaM76j+SxRZJT6xaxA/3+iMSIvwDvwrGU0dT+7V80jxhldUURd6C+nrGnDKSuro60tLSwbNPxjapPcZVx/VYkMgfbbzuS+zKz/2jrbp5jpOpWvqR0l1NeO0W7oeAT4/spp9u7VhHpXNXsJqtLiBo1qp00qhJ+dstztFs94hxOee04pU4RMU+Nas84ejKVRJbd8hztVo84h1NeO06pU0QkWhw9mUoix255jnarR5zDKa8dp9QpIhJN+jNdArJbnqPd6hHncMprxyl1iohJa4F7IePKK3B9tsvqahxLjaoEZLc8R7vVI87hlNeOU+oUEZMqga3Q56W1JBxstLoax9KpfwnIbnmOdqtHnMMprx2n1CkiEk2a9S9B2S3P0W71iHM45bXjlDpFxISVwCbj271vf0DzmFMtLScaFE+lRrVFNPMgrc5xbW/dNthcAsNOgCHp9qlL7M9ur+VgnFKniHRCjWpYtqlT/w5jRc7iGJu8WbY9dpfLhcejUSfpGru8lkNxSp0iIpHWrclUy5cvZ8SIEfTp04fzzjuPt956K+hjH3vsMS6++GIyMzPJzMzksssu6/Tx0rl4zln0HfuECRPIyMiIy+dAREQknnT5nf2ZZ57h+uuvZ9myZbz33nuMHz+eyy+/nD179gR8/IYNG7jqqqt47bXXePPNNxk2bBgzZszgs88+63Hx8caXs/jQw0bO4rBhw5gzZw4PPvQIaws9FMdwfI3v2G/+n1vYunUrDz30UNw9ByIi4lD2v8rStrrcqN5///1ce+21zJ8/n3HjxrFy5Ur69evH6tWrAz7+z3/+M9dddx0TJkzgtNNO4w9/+AMej4f169f3uPh4E885i75jHzx4MBCfz4GIiDhIQuu3adfnQXOzdbU4WJeuUW1qauLdd9/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 From f5d9812ae9f7d5994eddd05221b7e93e900093a1 Mon Sep 17 00:00:00 2001 From: MariaJacobs70 <72224154+MariaJacobs70@users.noreply.github.com> Date: Wed, 21 Oct 2020 19:12:45 -0300 Subject: [PATCH 9/9] Criado usando o Colaboratory --- ...5_00__Machine_Learning___DSWP mexido.ipynb | 4311 +++++++++++++++++ 1 file changed, 4311 insertions(+) create mode 100644 Notebooks/NB15_00__Machine_Learning___DSWP mexido.ipynb diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP mexido.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP mexido.ipynb new file mode 100644 index 000000000..d894862e9 --- /dev/null +++ b/Notebooks/NB15_00__Machine_Learning___DSWP mexido.ipynb @@ -0,0 +1,4311 @@ +{ + "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**\n", + "* Métodos\n", + " * Bagging (Bootstrap AGGregatING)\n", + " * Boosting\n", + " * Stacking\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", + " aquela linha do dataframe foi rotulado como fraude. \n", + " quando desenvolve o modelo preditivo e o seu modelo estimou como fraude\n", + " é tudo que a gente quer. nesse caso o modelo acertou\n", + " \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 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": 2, + "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;\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": 6, + "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": 8, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFaQF2MGFl_M", + "outputId": "0b90cdfd-888e-43f6-d020-a6c7b296acf5", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 224 + } + }, + "source": [ + "df_X.head()" + ], + "execution_count": 9, + "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": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s-ibdD2ZG7tm", + "outputId": "85710f30-784a-4157-8122-2ceb89b66525", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "df_X.shape" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(1000, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9cqRaywa_TR", + "outputId": "50b3b58a-6717-4459-dc21-9d79a699d56b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "set(df_y['target'])" + ], + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{0, 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BN6jbpn6Iwmu" + }, + "source": [ + "## Estatísticas Descritivas básicas do dataframe - df.describe()" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "KlwhxxUNIyYs", + "outputId": "df125f8e-1c1d-4225-8e2b-1b59033864d9", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 317 + } + }, + "source": [ + "df_X.describe()" + ], + "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", + "
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": 12 + } + ] + }, + { + "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": 18, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPTKBBHgOpoA", + "outputId": "57bc1b9b-58fb-4cf5-e9cb-7d13beeb2a49", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_train.shape" + ], + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lEn_LLs2OtRI", + "outputId": "2076fb6c-1c03-4fa9-dadc-556957aaa75b", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "y_train.shape" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(700, 1)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_uAw8EcyOvrG", + "outputId": "3a6d8556-0fcf-4e00-a884-4cc53470f4f0", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "X_test.shape" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(300, 18)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "A2LYI-9hOyXI", + "outputId": "12582890-711b-4200-ffbf-e431931818f7", + "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": "95e01ab3-f0e1-4715-939e-22045236925f", + "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": 24, + "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": 27, + "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 é um objeto. e ele está configurando este objeto\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": 28, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "OgAHfXVo-Nw8", + "outputId": "f422e8b3-9aff-40db-a5a8-ac5cf8b10680", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + } + }, + "source": [ + "# Treina o algoritmo\n", + "##o fit pega o objeto que ele configurou e vai aplicar um fit e passa a amostra de treinamento e as correspondentes respostas (y)\n", + "ml_DT.fit(X_train, y_train)" + ], + "execution_count": 29, + "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": 29 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6exa9D8R2fDJ", + "outputId": "debe52a1-3ecc-4ec9-fc67-2c162e28b375", + "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": 30, + "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": "9d2f51c5-d500-4508-a756-f0863aa36bf1", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": 31, + "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": 34, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fSaVzJ9xFpwW", + "outputId": "f60635b5-1a3a-41eb-aec9-9985eef28b42", + "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": 33, + "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", + "outputId": "ba94936d-6a1d-49d4-9bb0-23cb56f7fa49", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 214 + } + }, + "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": 3, + "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# Cross-Validation com 10 folds\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[0ma_scores_CV\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcross_val_score\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mml_RF\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[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[1;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}'\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[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'cross_val_score' is not defined" + ] + } + ] + }, + { + "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": "a916adc2-7038-4d7b-8ac5-96f41f971340", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 163 + } + }, + "source": [ + "print(f'Acurácias: {a_scores_CV}')" + ], + "execution_count": 4, + "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[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'Acurácias: {a_scores_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;31mNameError\u001b[0m: name 'a_scores_CV' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_lxx-LUw_5sd", + "outputId": "c7cccd43-813b-4765-f396-1a70540b3f05", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 180 + } + }, + "source": [ + "# Faz predições...\n", + "y_pred = ml_RF.predict(X_test)" + ], + "execution_count": 5, + "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# Faz predições...\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[0my_pred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mml_RF\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_test\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 'ml_RF' is not defined" + ] + } + ] + }, + { + "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