From e9dab5f76b560f1740776e7e3e8995cb4458c90e Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Thu, 8 Oct 2020 10:53:08 -0300
Subject: [PATCH 01/21] Criado usando o Colaboratory
---
...B09_01__Functions_Exerc\303\255cios.ipynb" | 1547 +++++++++++++++++
1 file changed, 1547 insertions(+)
create mode 100644 "Notebooks/NB09_01__Functions_Exerc\303\255cios.ipynb"
diff --git "a/Notebooks/NB09_01__Functions_Exerc\303\255cios.ipynb" "b/Notebooks/NB09_01__Functions_Exerc\303\255cios.ipynb"
new file mode 100644
index 000000000..87b3f66e8
--- /dev/null
+++ "b/Notebooks/NB09_01__Functions_Exerc\303\255cios.ipynb"
@@ -0,0 +1,1547 @@
+{
+ "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": [
+ "
"
+ ]
+ },
+ {
+ "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",
+ " 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": "PuCJNigKWir3"
+ },
+ "source": [
+ "#solução 08/10/2020\n",
+ "#\n",
+ "#função que recebe número do dia da semana e devolve semana em txt, com 3 caracteres. \n",
+ "#parametro de entrada deve estar no intervalo de 1 a 7, diferente disto, apresenta mensagem de erro\n",
+ "#\n",
+ "def f_dias_da_semana(i_dia_da_sem):\n",
+ " d_sem_num_txt = {1: \"Dom\",\n",
+ " 2: \"Seg\",\n",
+ " 3: \"Ter\",\n",
+ " 4: \"Qua\",\n",
+ " 5: \"Qui\",\n",
+ " 6: \"Sex\",\n",
+ " 7: \"Sab\" }\n",
+ " return d_sem_num_txt.get(i_dia_da_sem,'Intervalo deve ser informado entre 1(Dom) e 7(Sáb)! Valor informado: '+ str(i_dia_da_sem))\n",
+ "\n",
+ "f_dias_da_semana(0) "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6PAucd9vZxMZ"
+ },
+ "source": [
+ "f_dias_da_semana(3) "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "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": "amq_LdBBby2T"
+ },
+ "source": [
+ "#função que pesquisa palava a partir de um texto fornecido, retorna a posição encontrada e mensagem\n",
+ "#Parâmetro 1 : texto\n",
+ "#Parâmetro 2 : palavra\n",
+ "#retorno mensagem com posição\n",
+ "def fc_busca_texto(s_prm_texto, s_prm_palavra):\n",
+ " if s_prm_palavra in s_prm_texto:\n",
+ " return 'Encontrou, parabéns! Posição: ' + str(s_prm_texto.find(s_prm_palavra)) +' de '+ str(len(s_prm_texto)) + ' / Palavra pesquisada : ' + s_prm_palavra\n",
+ " else:\n",
+ " return 'Não encontrou palavra: ' + s_prm_palavra\n",
+ "\n",
+ "s_texto_informado = 'Expressão regular ou RegEx do inglês ‘Regular Expression’ é uma poderosa ferramenta para manipulação de strings. Esta ferramenta visa a identificação de padrões textuais ou padrões de caracteres que casam com um determinado padrão especificado.'\n",
+ "s_palavra_buscar = 'string'\n",
+ "fc_busca_texto(s_texto_informado,s_palavra_buscar) "
+ ],
+ "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": "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 8c95dd754d51bf1c3f7afb564b6d477bac859771 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Wed, 14 Oct 2020 15:36:13 -0300
Subject: [PATCH 02/21] Criado usando o Colaboratory
---
Notebooks/NB10_01__Pandas.ipynb | 235 +++++++++++++++++++++++++++++++-
1 file changed, 233 insertions(+), 2 deletions(-)
diff --git a/Notebooks/NB10_01__Pandas.ipynb b/Notebooks/NB10_01__Pandas.ipynb
index a2a03a488..18614be36 100644
--- a/Notebooks/NB10_01__Pandas.ipynb
+++ b/Notebooks/NB10_01__Pandas.ipynb
@@ -21,7 +21,7 @@
"colab_type": "text"
},
"source": [
- "
"
+ "
"
]
},
{
@@ -5231,7 +5231,238 @@
"id": "ldWQd9j4NhPS"
},
"source": [
- ""
+ "# Carrega a library Pandas\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pynSV0viI8CA"
+ },
+ "source": [
+ "#configuração\n",
+ "d_configuracao = {\n",
+ " 'display.max_columns': 1000,\n",
+ " 'display.expand_frame_repr': True,\n",
+ " 'display.max_rows': 10,\n",
+ " 'display.precision': 2,\n",
+ " 'display.show_dimensions': True\n",
+ " }\n",
+ "\n",
+ "for op, value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AswYS-ILI-qW"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/Celso-Omoto/DSWP/master/Dataframes/FIFA.csv'\n",
+ "#df_Fifa2018 = pd.read_csv(url, index_col = 'PassengerId')\n",
+ "df_Fifa2018 = pd.read_csv(url)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "K7xLrlPuKsAW"
+ },
+ "source": [
+ "df_Fifa2018.head()\n",
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LTZGbOHiKxsW"
+ },
+ "source": [
+ "df_Fifa2018.set_index('ID', inplace = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1y9oN-IeU7Sb"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df_Fifa2018.columns = [col.lower() for col in df.columns]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uRS02MeCVVID"
+ },
+ "source": [
+ "transformacao_lower(df_Fifa2018)\n",
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sI_2oz3uMQFF"
+ },
+ "source": [
+ "#17 - Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n",
+ "df_Fifa2018.sort_values('ShotPower', ascending=False).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-9jCfEaSNJS1"
+ },
+ "source": [
+ "df_Fifa2018.groupby('Overall').agg({'Age':'mean', 'Nationality': 'count'}).sort_values('Overall').head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PMrTNLV1Oe5P"
+ },
+ "source": [
+ "df_Fifa2018.groupby('Club').agg({'Overall':'mean'}).sort_values('Overall').head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dckaTDS9NaqG"
+ },
+ "source": [
+ "df_Fifa2018.groupby('Club').agg({'Potential':'mean', 'Overall':'mean'}).bhead(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OBuycRCzRbyG"
+ },
+ "source": [
+ "del df_Fifa2018['Photo']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1crol52URcmt"
+ },
+ "source": [
+ "del df_Fifa2018['Club Logo']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "W0X7-q1CSNfM"
+ },
+ "source": [
+ "del df_Fifa2018['Flag']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LMtzccaxSK29"
+ },
+ "source": [
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZPwu5sLnSyAc"
+ },
+ "source": [
+ "df_Fifa2018.dtypes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PBq3jr8nTUS0"
+ },
+ "source": [
+ "df_Fifa2018.select_dtypes(include=['object', 'string']).columns "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "82JaHKYATgdD"
+ },
+ "source": [
+ "df_Fifa2018[df_Fifa2018.select_dtypes(include=['object', 'string']).columns ]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NAyzCiTMW7YT"
+ },
+ "source": [
+ "df_Fifa2018.groupby('nationality').agg({'age':['count','mean']}).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eivUHr17ZiHs"
+ },
+ "source": [
+ "df_Fifa2018.sort_values('age', ascending=False).groupby('nationality').agg({'age':['count','mean']})"
],
"execution_count": null,
"outputs": []
From 9a622e97075b23bc74b208e6f2e132dbfbc35757 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Wed, 14 Oct 2020 15:53:18 -0300
Subject: [PATCH 03/21] Criado usando o Colaboratory
---
Notebooks/NB10_01__Pandas_Fifa.ipynb | 5493 ++++++++++++++++++++++++++
1 file changed, 5493 insertions(+)
create mode 100644 Notebooks/NB10_01__Pandas_Fifa.ipynb
diff --git a/Notebooks/NB10_01__Pandas_Fifa.ipynb b/Notebooks/NB10_01__Pandas_Fifa.ipynb
new file mode 100644
index 000000000..073a7477f
--- /dev/null
+++ b/Notebooks/NB10_01__Pandas_Fifa.ipynb
@@ -0,0 +1,5493 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Copy of NB10_01__Pandas.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8fpUiw8PwC7_"
+ },
+ "source": [
+ "PANDAS PARA DATA ANALYSIS
\n",
+ "\n",
+ "\n",
+ "\n",
+ "# **AGENDA**:\n",
+ "\n",
+ "> Veja o **índice** dos itens que serão abordados neste capítulo.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vo7mtiNSr_Wk"
+ },
+ "source": [
+ "___\n",
+ "# **REFERÊNCIAS**\n",
+ "* [Learn Aggregation and Data Wrangling with Python](https://data-flair.training/blogs/data-wrangling-with-python/)\n",
+ "* [Python Data Cleansing by Pandas & Numpy | Python Data Operations](https://data-flair.training/blogs/python-data-cleansing/)\n",
+ "* [Pandas from basic to advanced for Data Scientists](https://towardsdatascience.com/pandas-from-basic-to-advanced-for-data-scientists-aee4eed19cfe)\n",
+ "* [Feature engineering and ensembled models for the top 10 in Kaggle “Housing Prices Competition”](https://towardsdatascience.com/feature-engineering-and-ensembled-models-for-the-top-10-in-kaggle-housing-prices-competition-efb35828eef0)\n",
+ "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n",
+ "* [Pandas.Series Methods for Machine Learning](https://towardsdatascience.com/pandas-series-methods-for-machine-learning-fd83709368ff)\n",
+ "* [Gaining a solid understanding of Pandas series](https://towardsdatascience.com/gaining-a-solid-understanding-of-pandas-series-893fb8f785aa)\n",
+ "* [ariáveis Dummy: o que é? Quando usar? E como usar?](https://medium.com/data-hackers/vari%C3%A1veis-dummy-o-que-%C3%A9-quando-usar-e-como-usar-78de66cfcca9)\n",
+ "* [Exploratory Data Analysis Made Easy Using Pandas Profiling](https://towardsdatascience.com/exploratory-data-analysis-made-easy-using-pandas-profiling-86e347ef5b65)\n",
+ "* [Data Handling using Pandas; Machine Learning in Real Life](https://towardsdatascience.com/data-handling-using-pandas-machine-learning-in-real-life-be76a697418c)\n",
+ "* [Exploratory Data Analysis Tutorial in Python](https://towardsdatascience.com/exploratory-data-analysis-tutorial-in-python-15602b417445)\n",
+ "* [Exploring the data using python](https://towardsdatascience.com/exploring-the-data-using-python-47c4bc7b8fa2)\n",
+ "* [A better EDA with Pandas-profiling](https://towardsdatascience.com/a-better-eda-with-pandas-profiling-e842a00e1136)\n",
+ "* [Exploratory Data Analysis: Haberman’s Cancer Survival Dataset](https://towardsdatascience.com/exploratory-data-analysis-habermans-cancer-survival-dataset-c511255d62cb)\n",
+ "* [Exploring Exploratory Data Analysis](https://towardsdatascience.com/exploring-exploratory-data-analysis-1aa72908a5df)\n",
+ "* [Getting started with Data Analysis with Python Pandas](https://towardsdatascience.com/getting-started-to-data-analysis-with-python-pandas-with-titanic-dataset-a195ab043c77)\n",
+ "* [A Gentle Introduction to Exploratory Data Analysis](https://towardsdatascience.com/a-gentle-introduction-to-exploratory-data-analysis-f11d843b8184)\n",
+ "* [Exploratory Data Analysis (EDA) techniques for Kaggle competition beginners](https://towardsdatascience.com/exploratory-data-analysis-eda-techniques-for-kaggle-competition-beginners-be4237c3c3a9)\n",
+ "* [What is Exploratory Data Analysis?](https://towardsdatascience.com/exploratory-data-analysis-8fc1cb20fd15)\n",
+ "* [Exploring real estate investment opportunity in Boston and Seattle](https://towardsdatascience.com/exploring-real-estate-investment-opportunity-in-boston-and-seattle-9d89d0c9bed2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BUEbp88oD1Km"
+ },
+ "source": [
+ "___\n",
+ "# **ANÁLISE DE DADOS COM PANDAS**\n",
+ "## Highlights\n",
+ "\n",
+ "* Rápida e eficiente library para data manipulation;\n",
+ "* Ferramentas para ler e gravar todos os tipos de dados e formatos: CSV, txt, Microsoft Excel, SQL databases, JSON e HDF5 format;\n",
+ "* Pandas é a library mais popular para análise de dados. As principais ações que faremos com Pandas são:\n",
+ " * Ler/gravar diferentes formatos de dados;\n",
+ " * Selecionar subconjuntos de dados;\n",
+ " * Cálculos variados por coluna ou por linha das tabelas;\n",
+ " * Encontrar e tratar Missing Values;\n",
+ " * Combinar múltiplos dataframes;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wkxQFPPmeKLl"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eKawOG-neqaD"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TLdSmsJZwlcQ"
+ },
+ "source": [
+ "___\n",
+ "# **ATÉ QUE VOLUME DE DADOS PODEMOS USAR PANDAS?**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "O7YKF5gB2x0K"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "## Sources\n",
+ "### Dask\n",
+ "* [Pandas, Dask or PySpark? What Should You Choose for Your Dataset?](https://medium.com/datadriveninvestor/pandas-dask-or-pyspark-what-should-you-choose-for-your-dataset-c0f67e1b1d36)\n",
+ "* [Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165)\n",
+ "* [Pandas, Fast and Slow](https://medium.com/when-i-work-data/pandas-fast-and-slow-b6d8dde6862e)\n",
+ "* [Por que Parquet](https://medium.com/when-i-work-data/por-que-parquet-2a3ec42141c6)\n",
+ "* [How to Run Parallel Data Analysis in Python using Dask Dataframes](https://towardsdatascience.com/trying-out-dask-dataframes-in-python-for-fast-data-analysis-in-parallel-aa960c18a915)\n",
+ "* [Why every Data Scientist should use Dask?](https://towardsdatascience.com/why-every-data-scientist-should-use-dask-81b2b850e15b)\n",
+ "\n",
+ "### Spark, Koalas\n",
+ "* [Databricks Koalas-Python Pandas for Spark](https://medium.com/future-vision/databricks-koalas-python-pandas-for-spark-ce20fc8a7d08)\n",
+ "* [Bye Pandas, Meet Koalas: Pandas APIs on Apache Spark (Ep. 4)](https://medium.com/@kyleake/bye-pandas-meet-koalas-pandas-apis-on-apache-spark-ep-4-aedcd363cf4e)\n",
+ "* [Koalas: Easy Transition from pandas to Apache Spark](https://databricks.com/blog/2019/04/24/koalas-easy-transition-from-pandas-to-apache-spark.html?source=post_page-----aedcd363cf4e----------------------)\n",
+ "* [Use PySpark for Your Next Big Problem](https://medium.com/swlh/use-pyspark-for-your-next-big-problem-8aa288d5ecfa)\n",
+ "* [A Neanderthal’s Guide to Apache Spark in Python](https://towardsdatascience.com/a-neanderthals-guide-to-apache-spark-in-python-9ef1f156d427)\n",
+ "* [The Jungle of Koalas, Pandas, Optimus and Spark](https://towardsdatascience.com/the-jungle-of-koalas-pandas-optimus-and-spark-dd486f873aa4)\n",
+ "* [From Pandas to PySpark with Koalas](https://towardsdatascience.com/from-pandas-to-pyspark-with-koalas-e40f293be7c8)\n",
+ "\n",
+ "# O que Dask?\n",
+ "\n",
+ "\"Dask is designed to extend the numpy and pandas packages to work on data processing problems that are too large to be kept in memory. It breaks the larger processing job into many smaller tasks that are handled by numpy or pandas and then it reassembles the results into a coherent whole.\" - Eric Ness ([Processing Data with Dask](https://medium.com/when-i-work-data/processing-data-with-dask-47e4233cf165))\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yEyzjGUfG33-"
+ },
+ "source": [
+ "___\n",
+ "# **Carregar a library Pandas e verificar a versão**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oVMjT3DrG97K"
+ },
+ "source": [
+ "# Carrega a library Pandas\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "print(f'Versão do Pandas: {pd.__version__}')\n",
+ "print(f'Versão do NumPy.: {np.__version__}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OxoDsaKUVHdH"
+ },
+ "source": [
+ "# Configurações\n",
+ "> Podemos configurar o pandas de forma a tornar nosso trabalho mais produtivo. Podemos configurar, por exemplo, o número de LINHAS e COLUNAS a ser mostrado, precisão dos números float. Vamos ver com mais detalhes a seguir.\n",
+ "\n",
+ "Fonte: [5 Advanced Features of Pandas and How to Use Them](https://www.kdnuggets.com/2019/10/5-advanced-features-pandas.html)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IOdqrf7uVlhC"
+ },
+ "source": [
+ "d_configuracao = {\n",
+ " 'display.max_columns': 1000,\n",
+ " 'display.expand_frame_repr': True,\n",
+ " 'display.max_rows': 5,\n",
+ " 'display.precision': 2,\n",
+ " 'display.show_dimensions': True\n",
+ " }\n",
+ "\n",
+ "for op, value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Paz-R-FOAJ7F"
+ },
+ "source": [
+ "___\n",
+ "# **Criar um dataframe a partir de outros objetos**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "L4Jc0C2qPAQz"
+ },
+ "source": [
+ "## Criar dataframe a partir de dicionários"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Sa5rKwq6Fscj"
+ },
+ "source": [
+ "### Exemplo 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0ofIGkiSSuYq"
+ },
+ "source": [
+ "d_frutas = {'Apple': [5, 6, 6, 8, 10, 3, 2],\n",
+ " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iJCNvPlUTzTI"
+ },
+ "source": [
+ "d_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7Y_0O_tJTfm3"
+ },
+ "source": [
+ "# index=['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'] abaixo define os label.\n",
+ "df_frutas = pd.DataFrame(d_frutas, index = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'])\n",
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "l2ll8ktfUKz2"
+ },
+ "source": [
+ "O que se comprou na sexta?\n",
+ "\n",
+ "* Função df.loc[label] retorna o(s) valor(es) associados à label. Em nosso caso, os label (chaves do dicionário) são 'Seg', 'Ter', ..., 'Dom'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9Voor8_PUJum"
+ },
+ "source": [
+ "df_frutas.loc['Sex'] # Aqui, label= 'Sex'."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LMh4DTfebwAr"
+ },
+ "source": [
+ "* Ou seja, o label = 'Sex', que ocupa a posição 4, tem os valores:\n",
+ " * Apple..: 10\n",
+ " * Avocado: 3\n",
+ "\n",
+ "Da mesma forma, poderíamos utilizar a função df.iloc[index] para retornar o conteúdo/informações de index."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GJxawdh6bvJN"
+ },
+ "source": [
+ "df_frutas.iloc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "obJt9OPGcL-x"
+ },
+ "source": [
+ "Portanto, df.loc['Sex'] = df.iloc[4]. Correto?\n",
+ "\n",
+ "Para nos ajudar a memorizar, considere que:\n",
+ "\n",
+ "* pd.loc[label] --> loc começa com a letra **l**, o que remete à label da linha.\n",
+ "* pd.iloc[indice] --> iloc começa com a letra **i**, o que remete ao índice (inteiro) da linha."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "v7QlCcEorEIX"
+ },
+ "source": [
+ "#### Qual é o output do code abaixo?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kRRdQShrrKHk"
+ },
+ "source": [
+ "df_frutas.loc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EkjAtbrRF01h"
+ },
+ "source": [
+ "### Exemplo 2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2EOX5MC4E1xL"
+ },
+ "source": [
+ "Na prática, lidamos com grandes bancos de dados e, nesses casos, não temos label das LINHAS definidos. Para exemplificar, considere o mesmo exemplo que acabamos de ver, com uma pequena alteração:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RC_OXmdjrkQm"
+ },
+ "source": [
+ "d_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D6FckgDPFFs0"
+ },
+ "source": [
+ "df_frutas = pd.DataFrame(d_frutas) # Observe que aqui não definimos os indíces\n",
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tkGc4JQcFPkp"
+ },
+ "source": [
+ "Veja agora que os label são números inteiros de 0 a N."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ri-EdUYAovLG"
+ },
+ "source": [
+ "#### Qual o conteúdo da linha cujo label é 4?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5YgWG_vlFVe_"
+ },
+ "source": [
+ "df_frutas.loc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rFQxcAcVo2KD"
+ },
+ "source": [
+ "#### Qual o conteúdo da linha cujo índice é 4?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xB1j4n6HFank"
+ },
+ "source": [
+ "df_frutas.iloc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jEbCke3TFf_q"
+ },
+ "source": [
+ "Ou seja, nesses casos, tanto faz usar pd.loc[] ou pd.iloc[]. Entendeu?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bKHw_VBKjkoL"
+ },
+ "source": [
+ "### Exemplo 3 - Definir os indices do dataframe usando df.set_index()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "13ArWIhYju6s"
+ },
+ "source": [
+ "d_frutas= {'Dia_Semana': ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab', 'Dom'],\n",
+ " 'Apple': [5, 6, 6, 8, 10, 3, 2],\n",
+ " 'Avocado': [6, 6, 3, 9, 3, 2, 1]}\n",
+ "\n",
+ "d_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Evw9w16gk5h0"
+ },
+ "source": [
+ "# Cria o dataframe df_frutas:\n",
+ "df_frutas = pd.DataFrame(d_frutas) # Não apontamos o índice do dataframe. Portanto, o índice é criado automaticamente de 0.. N.\n",
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NLbbRrdYoclw"
+ },
+ "source": [
+ "#### Qual o conteúdo da linha 4?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lB-ngbutl_0c"
+ },
+ "source": [
+ "df_frutas.iloc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1aJLGapZlUFI"
+ },
+ "source": [
+ "# Definir 'Dia_Semana' como índice (label das linhas) do dataframe df_frutas\n",
+ "df_frutas.set_index('Dia_Semana', inplace = True)\n",
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "L1-U_sD-jAoO"
+ },
+ "source": [
+ "A expressão acima é equivalente a:\n",
+ "\n",
+ "```\n",
+ "df_frutas2 = df_frutas.set_index('Dia_Semana') # Observe que aqui não há 'inplace'\n",
+ "df_frutas2\n",
+ "```\n",
+ "\n",
+ "* Então, qual a função do 'inplace =True' na primeira opção?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oXeFjJonpQfB"
+ },
+ "source": [
+ "#### Qual o conteúdo da linha 4?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MMXg3vVQpUhh"
+ },
+ "source": [
+ "df_frutas.iloc[4]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "fhoYuGMlpVFj"
+ },
+ "source": [
+ "#### Qual o conteúdo da linha cujo label é 'Sex'?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fmcWbrEspdYW"
+ },
+ "source": [
+ "df_frutas.loc['Sex']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bobggpoCTRkj"
+ },
+ "source": [
+ "### Qual a diferença entre as duas próximas linhas?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SjiYgbNrsvpl"
+ },
+ "source": [
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OFhzE7hgTD0a"
+ },
+ "source": [
+ "df_frutas.mean()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V42I3807TNte"
+ },
+ "source": [
+ "df_frutas.mean(1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6iUCthsbtLV8"
+ },
+ "source": [
+ "df_frutas.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YdkmYePYtcON"
+ },
+ "source": [
+ "df_frutas.dtypes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2RmgCIC2HZFp"
+ },
+ "source": [
+ "### Exemplo 4"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kbHHuMzzAR1A"
+ },
+ "source": [
+ "d_estudantes = {'Nome': ['Jack', 'Richard', 'Tommy', 'Ana'], \n",
+ " 'Age': [25, 34, 18, 21],\n",
+ " 'City': ['Sydney', 'Rio de Janeiro', 'Lisbon', 'New York'],\n",
+ " 'Country': ['Australia', 'Brazil', 'Portugal', 'United States']}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ayKqLmHTANOu"
+ },
+ "source": [
+ "# Mostrar o conteúdo do dicionário d_estudantes...\n",
+ "d_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0ONA8QsBBP6R"
+ },
+ "source": [
+ "# Keys associadas ao dicionário d_estudantes\n",
+ "d_estudantes.keys()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "k8mmvKQ_BjO6"
+ },
+ "source": [
+ "# Itens associados ao dicionário d_estudantes\n",
+ "d_estudantes.items()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hcm8V_UmBr1Y"
+ },
+ "source": [
+ "# Valores associados ao dicionário d_estudantes\n",
+ "d_estudantes.values()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KK7IejsPDkWC"
+ },
+ "source": [
+ "Temos uma key = 'nome'. Qual o conteúdo desta key?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eHvPpeiTBwoR"
+ },
+ "source": [
+ "d_estudantes['nome']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "S1y7p8CcDsXl"
+ },
+ "source": [
+ "Qual o output da expressão a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "26WIDl-HB3Bq"
+ },
+ "source": [
+ "d_estudantes['nome'][0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gV68kQ5HCIif"
+ },
+ "source": [
+ "Criando o dataframe df_estudantes a partir do dicionário d_estudantes:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2oa808hkCSaq"
+ },
+ "source": [
+ "df_estudantes = pd.DataFrame(d_estudantes)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7HLp0FYpCiSc"
+ },
+ "source": [
+ "# Mostra o conteúdo do dataframe df_estudantes...\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "en06lfazciE0"
+ },
+ "source": [
+ "**Atenção**: Observe que nesse caso, não definimos labels para as LINHAS. Na prática, isso é o mais comum, ou seja, os label = index, que aqui são números inteiros de 0 a N."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gFaPp-S-cy1-"
+ },
+ "source": [
+ "Mais uma vez, vamos usar df.loc[] e df.iloc[]..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mT9vwRBidGXX"
+ },
+ "source": [
+ "# Mostrando o conteúdo de da linha 3 usando df.loc[]\n",
+ "df_estudantes.loc[3]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Zj88AwHUdix0"
+ },
+ "source": [
+ "OU"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SP2mG8todkMe"
+ },
+ "source": [
+ "# Mostrando o conteúdo de da linha 3 usando df.iloc[]\n",
+ "df_estudantes.iloc[3]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hzbLO0EDGWTf"
+ },
+ "source": [
+ "Ok, já discutimos isso anteriormente. Quando não temos labels para as LINHAS, então iloc[] = loc[]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VvzVg7SpeOOB"
+ },
+ "source": [
+ "___\n",
+ "## Criar dataframes a partir de listas\n",
+ "* Considere a lista de frutas a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0_PY9OROeUiT"
+ },
+ "source": [
+ "l_frutas = [('Melon', 6, 8, 5, 4 ,6, 2, 8), ('Avocado', 6, 6, 3, 8, 9, 3, 1), ('Blueberry', 7, 5, 9, 3, 1, 0, 4)]\n",
+ "l_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AfE_rHq5g4_P"
+ },
+ "source": [
+ "type(l_frutas)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZpdPSi7RgVjK"
+ },
+ "source": [
+ "l_frutas[0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NMyIpVW8gZTH"
+ },
+ "source": [
+ "l_frutas[0][0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-cyZVqQFhjjg"
+ },
+ "source": [
+ "# Lista contendo os nomes das COLUNAS do dataframe:\n",
+ "l_colunas = ['Frutas', 'Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']\n",
+ "l_colunas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wplKvgayfZm_"
+ },
+ "source": [
+ "# Convertendo as listas em dataframe\n",
+ "df_frutas = pd.DataFrame(l_frutas, columns = l_colunas) # Observe que aqui, o nome das COLUNAS é uma lista.\n",
+ "df_frutas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GojgsAXTFZmB"
+ },
+ "source": [
+ "___\n",
+ "# **Copiar dataframes**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "g_Tda4ZwjWIW"
+ },
+ "source": [
+ "O dataframe df_estudantes tem o seguinte conteúdo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "P5y0aVkdkA8o"
+ },
+ "source": [
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Cp3bvPEqj5fS"
+ },
+ "source": [
+ "se fizermos..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J2PT5L11j8O0"
+ },
+ "source": [
+ "df_estudantes2 = df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2D29pGuikBBK"
+ },
+ "source": [
+ "então df_estudantes2 tem o mesmo conteúdo de df_estudantes, ok?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_IseZEpLkGS4"
+ },
+ "source": [
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "29MpozLrkI83"
+ },
+ "source": [
+ "Agora altere o valor 'Rio de Janeiro' para 'Sao Paulo' no dataframe df_estudantes2."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TXCqFiGFkmyv"
+ },
+ "source": [
+ "df_estudantes2['city'] = df_estudantes2['city'].replace({'Rio de Janeiro': 'Sao Paulo'})\n",
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I_0mgT7-8Fsl"
+ },
+ "source": [
+ "# OU\n",
+ "alteracoes = {'Rio de Janeiro': 'Sao Paulo'}\n",
+ "df_estudantes2['city'] = df_estudantes2['city'].replace(alteracoes)\n",
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BN8ZGu2Xk6vt"
+ },
+ "source": [
+ "Ok, alteramos o valor 'Rio de Janeiro' por 'Sao Paulo', como queríamos. Vamos ver o conteúdo de df_estudantes (**que está intacto, pois fizemos a alteração no dataframe df_estudantes2**)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "thNAWoDflRoQ"
+ },
+ "source": [
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VkIS8wVmlAyq"
+ },
+ "source": [
+ "Ooooops... df_estudantes foi alterado? Como, se procedemos a alteração em df_estudantes2 e NÃO em df_estudantes???\n",
+ "\n",
+ "* **As operações que fizermos em df_estudantes2 também serão aplicadas à df_estudantes**?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "e9u-Z9NMltC9"
+ },
+ "source": [
+ "**Resposta**: SIM, pois df_estudantes2 é um ponteiro para df_estudantes. Ou seja, **qualquer operação que fizermos em df_estudantes2 será feita em df_estudantes**."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IDwvsxhhmlE4"
+ },
+ "source": [
+ "Uma forma fácil de ver isso é através dos endereços de memória dos dois (**supostos diferentes**) dataframes:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ePFwKua8mu7k"
+ },
+ "source": [
+ "id(df_estudantes2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bMvY_E0mmwQH"
+ },
+ "source": [
+ "id(df_estudantes)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "K5qC5BuzmyF0"
+ },
+ "source": [
+ "**Conclusão**: df_estudantes2 é ponteiro para df_estudantes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZZ50ejRImAQ8"
+ },
+ "source": [
+ "## Forma correta de fazer a cópia de um dataframe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oTbzxNkDmQiJ"
+ },
+ "source": [
+ "Primeiramente, vamos reconstruir df_estudantes:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DmVq0vM0mTtQ"
+ },
+ "source": [
+ "df_estudantes = pd.DataFrame(d_estudantes)\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oZrlwtqJmYB_"
+ },
+ "source": [
+ "Fazendo a cópia do dataframe (**da forma correta**):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "No5A7nHDFbsy"
+ },
+ "source": [
+ "df_estudantes_Copy = df_estudantes.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NvKNFr8RnEft"
+ },
+ "source": [
+ "Vamos verificar os endereços de memória dos dois dataframes:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0_OO90SFki4f"
+ },
+ "source": [
+ "id(df_estudantes_Copy)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "T0BibX8rkes5"
+ },
+ "source": [
+ "id(df_estudantes)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Fbm-8cCUFgJa"
+ },
+ "source": [
+ "Agora, dataframe df_estudantes_Copy é uma cópia do dataframe df_estudantes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SuL8WUxL-u6-"
+ },
+ "source": [
+ "___\n",
+ "# **Renomear COLUNAS do dataframe**\n",
+ "> **Snippet**: \n",
+ "\n",
+ " * df.rename(columns = {'Old_Name': 'New_Name'}, inplace = True)\n",
+ " * OU df = df.rename(columns = {'Old_Name': 'New_Name'})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IvpCfmQnIZKl"
+ },
+ "source": [
+ "Suponha que quero renamear a COLUNA 'nome' para 'nome_cliente', que é um nome mais sugestivo."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "o54Fa-yxnmuz"
+ },
+ "source": [
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FwzXjYJgCvGk"
+ },
+ "source": [
+ "df_estudantes= df_estudantes.rename(columns = {'nome': 'nome_cliente'})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gOolGiWt4A18"
+ },
+ "source": [
+ "O comando abaixo produz o mesmo resultado que a linha anterior:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Y6jjAFRd341e"
+ },
+ "source": [
+ "```\n",
+ "df_estudantes.rename(columns= {'nome': 'nome_cliente'}, inplace = True)\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DwVMldKiF5gS"
+ },
+ "source": [
+ "# Mostrando o conteúdo de df_estudantes após renamearmos a coluna/variável 'nome' para 'Clien_Name'...\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m-WZBLWqELOv"
+ },
+ "source": [
+ "Agora, suponha que queremos renamear 'age' para 'idade_cliente', 'city' para 'cidade_cliente' e 'country' para 'pais_cliente'..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VS6ua4u1EX5g"
+ },
+ "source": [
+ "df_estudantes.rename(columns = {'age': 'idade_cliente', 'city': 'cidade_cliente', 'country': 'pais_cliente'}, inplace = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "i_7LW07y4SvO"
+ },
+ "source": [
+ "O comando abaixo produz o mesmo resultado que a linha anterior:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9X-cv9RL4WjV"
+ },
+ "source": [
+ "```\n",
+ "df_estudante = df_estudantes.rename(columns= {'Age': 'idade_cliente', 'City': 'cidade_cliente', 'Country': 'pais_cliente'}, inplace = True)\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EOb1-TEKGM9I"
+ },
+ "source": [
+ "# Mostrando o conteúdo de df_estudantes após a múltipla operação de renamear...\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "q0IZZjLRJlU6"
+ },
+ "source": [
+ "Alguma dúvida até aqui?\n",
+ "Tudo bem até aqui?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5LwL2m5KbLYz"
+ },
+ "source": [
+ "## Challenge\n",
+ "* Aplicar lowercase() em todas as COLUNAS do dataframe df_estudantes. Como fazer isso?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MURfzmeLbUzF"
+ },
+ "source": [
+ "### Minha solução:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r-FgBY-3xBi9"
+ },
+ "source": [
+ "df_estudantes2 = df_estudantes.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hlSlfcoub8gH"
+ },
+ "source": [
+ "# Colocar o nome das COLUNAS numa lista:\n",
+ "l_colunas = df_estudantes2.columns\n",
+ "l_colunas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I_IGvEK4bdQP"
+ },
+ "source": [
+ "# Lowercase todas as COLUNAS\n",
+ "df_estudantes2.columns = [col.lower() for col in l_colunas]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0qzzAa3ycKmF"
+ },
+ "source": [
+ "# Mostrando o conteúdo do dataframe df_estudantes\n",
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "c-u-ndMPV_KX"
+ },
+ "source": [
+ "___\n",
+ "# **Adicionar/Acrescentar novas LINHAS ao dataframe**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MDkWbukBLhw7"
+ },
+ "source": [
+ "## Usando dicionários\n",
+ "* É necessário informar {'Column_Name': value} para cada inserção. Por exemplo, vou adicionar o seguinte registro ao dataframe:\n",
+ " * nome_cliente= 'Anderson';\n",
+ " * idade_cliente= 22;\n",
+ " * cidade_cliente= 'Porto';\n",
+ " * pais_cliente= 'Portugal'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GECPO7iyK9UU"
+ },
+ "source": [
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XQKqqC93LoQ_"
+ },
+ "source": [
+ "df_estudantes_Copia= df_estudantes.copy()\n",
+ "df_estudantes.append({'nome_cliente': 'Anderson', \n",
+ " 'idade_cliente': 22,\n",
+ " 'cidade_cliente': 'Porto',\n",
+ " 'pais_cliente': 'Portugal'}, ignore_index = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bdBttsHNLjd-"
+ },
+ "source": [
+ "Esse é o resultado que desejamos?\n",
+ "Saberia explicar-nos o que houve de errado?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6jDoq6CCMerp"
+ },
+ "source": [
+ "**DICA**: Lembre-se que no passo anterior, reescrevemos os nomes das COLUNAS usando o método lower()."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ffReAaUHLvEF"
+ },
+ "source": [
+ "# Definindo df_estudantes novamente usando a cópia df_estudantes_Copia\n",
+ "df_estudantes = df_estudantes_Copia.copy()\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EzTo-IvmM2Fg"
+ },
+ "source": [
+ "Ok, restabelecemos a cópia de df_estudantes. Agora vamos à forma correta:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IRhE76i4M6d6"
+ },
+ "source": [
+ "df_estudantes = df_estudantes.append({'nome_cliente': 'Anderson', \n",
+ " 'idade_cliente': 22,\n",
+ " 'cidade_cliente': 'Porto',\n",
+ " 'pais_cliente': 'Portugal'}, ignore_index= True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jAojB2MMNDRJ"
+ },
+ "source": [
+ "Bom, esse é o resultado que estávamos à espera..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5czZb-5wNp_F"
+ },
+ "source": [
+ "## Usando Series\n",
+ "* Como exemplo, considere que queremos adicionar os seguintes dados:\n",
+ " * nome_cliente= 'Bill';\n",
+ " * idade_cliente= 30;\n",
+ " * cidade_cliente= 'São Paulo';\n",
+ " * pais_cliente= 'Brazil'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J3qCydqMNtGt"
+ },
+ "source": [
+ "novo_estudante = pd.Series(['Bill', 30, 'Sao Paulo', 'Brazil'], index= df_estudantes2.columns) # Olha que interessante: estamos a usar index= df_estudantes.columns."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "g_DyMDrNPrmC"
+ },
+ "source": [
+ "Vamos ver o conteúdo de novo_estudante:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jDQUl0RBPoLB"
+ },
+ "source": [
+ "novo_estudante"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zMKRNQrsPvxp"
+ },
+ "source": [
+ "Por fim, adiciona/acrescenta novo_estudante ao dataframe df_estudantes..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5mEQg26iPw4A"
+ },
+ "source": [
+ "df_estudantes2 = df_estudantes2.append(novo_estudante, ignore_index= True)\n",
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Biwk2McAWW1Z"
+ },
+ "source": [
+ "___\n",
+ "# **Adicionar/acrescentar novas COLUNAS ao Dataframe**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EZFTH7A-Wpw5"
+ },
+ "source": [
+ "## Usando Lists\n",
+ "* Suponha que queremos adicionar a coluna/variável 'Score'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YzBKQo5epXP5"
+ },
+ "source": [
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pPoObAKJW6YF"
+ },
+ "source": [
+ "# Acrescentando ou criando a coluna/variável 'score' ao dataframe usando um objeto list\n",
+ "df_estudantes2['score'] = [500, 300, 200, 800, 700, 100]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ocbh8sZqWsoW"
+ },
+ "source": [
+ "# Mostra o conteúdo do dataframe df_estudantes...\n",
+ "df_estudantes2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZxfCMcVxYQgL"
+ },
+ "source": [
+ "> **Atenção**:\n",
+ "\n",
+ "* Se a quantidade de valores da lista forem menores que o número de LINHAS do dataframe, então o Python apresenta um erro.\n",
+ "* Se a coluna/variável que queremos inserir já existe no dataframe, então os valores serão atualizados com os novos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "34ntllD_YbNa"
+ },
+ "source": [
+ "## Usando um valor default\n",
+ "* Adicionar a coluna 'total' com o mesmo valor para todas as LINHAS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "T7QSMJMQYous"
+ },
+ "source": [
+ "df_estudantes['total'] = 500\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gll-gJt7as3C"
+ },
+ "source": [
+ "## Adicionar uma COLUNA calculada a partir de outras COLUNAS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "T_pB_isBaw-E"
+ },
+ "source": [
+ "df_estudantes['percentagem'] = 100*(df_estudantes['score']/sum(df_estudantes['score']))\n",
+ "df_estudantes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "D9TNylt84hle"
+ },
+ "source": [
+ "___\n",
+ "# **Ler/carregar dados no Python**\n",
+ "* Vários formatos de arquivos podem ser lidos:\n",
+ "\n",
+ "|Format Type | Data Description | Reader | Writer |\n",
+ "|---|---|---|---|\n",
+ "text | CSV | read_csv | to_csv |\n",
+ "text | JSON | read_json | to_json |\n",
+ "text | HTML | read_html | to_html |\n",
+ "text | Local clipboard | read_clipboard | to_clipboard |\n",
+ "binary | MS Excel | read_excel | to_excel |\n",
+ "binary | HDF5 Format | read_hdf | to_hdf |\n",
+ "binary | Stata | read_stata | to_stata |\n",
+ "binary | SAS | read_sas \n",
+ "binary | Python Pickle Format | read_pickle | to_pickle |\n",
+ "SQL | SQL | read_sql | to_sql |\n",
+ "SQL | Google Big Query | read_gbq | to_gbq |\n",
+ "\n",
+ "* Fonte: [IO tools (text, CSV, HDF5, …)](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ss8jLEUSblDm"
+ },
+ "source": [
+ "___\n",
+ "# **Ler/Carregar csv**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "n8e9aphab_oe"
+ },
+ "source": [
+ "# carregar a library Pandas\n",
+ "import pandas as pd"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R2fRd_MSQ2Xa"
+ },
+ "source": [
+ "A seguir, vamos:\n",
+ "* Ler o dataframe Titanic.csv;\n",
+ "* Definir 'PassengerId' como índice/chave da tabela através do comando index_col= 'PassengerId'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1R9YoFJ02TR7"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_With_MV.csv?token=AGDJQ67OZ36XJUJPE77Z7LC7RBCAU'\n",
+ "df_Titanic = pd.read_csv(url, index_col = 'PassengerId')\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VS7_V15u0MgR"
+ },
+ "source": [
+ "df_Titanic.iloc[4] # NÃO É A MESMA COISA QUE df_Titanic.loc[4]!!!"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WJ9RlRDSkk0_"
+ },
+ "source": [
+ "* Segue o dicionário de dados do dataframe df_Titanic:\n",
+ " * PassengerID: ID do passageiro;\n",
+ " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n",
+ " * Pclass: Classe;\n",
+ " * Age: Idade do Passageiro;\n",
+ " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n",
+ " * Parch: Número de pais/crianças a bordo;\n",
+ " * Fare: Valor pago pelo Passageiro;\n",
+ " * Cabin: Cabine do Passageiro;\n",
+ " * Embarked: A porta pelo qual o Passageiro embarcou.\n",
+ " * Name: Nome do Passageiro;\n",
+ " * sex: sexo do Passageiro."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wz7Qd9mqMrfY"
+ },
+ "source": [
+ "# Show o dataframe df_Titanic:\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nDlANdnm4iod"
+ },
+ "source": [
+ "### DICA 1\n",
+ "Suponha que o dataframe que queremos ler esteja localizado em:\n",
+ "\n",
+ "```\n",
+ "/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes\n",
+ "```\n",
+ "\n",
+ "Desta forma, para ler o dataframe (local), basta usar o comando a seguir:\n",
+ "\n",
+ "```\n",
+ "url = '/home/nsolucoes4ds/Dropbox/Data_Science/Python/Python_RFB/Python_RFB-DS_Python_020919_2244/Dataframes/creditcard.csv'\n",
+ "df_Titanic = pd.read_csv(url)\n",
+ "```\n",
+ "\n",
+ "### Dica 2\n",
+ "No Windows, o diretório aparece, por exemplo, da seguinte forma: \n",
+ "```\n",
+ "C:\\nsolucoes4ds\\Data_Science\n",
+ "```\n",
+ "Observe as '\\\\' (**barras invertidas**). Neste caso, use o comando a seguir:\n",
+ "\n",
+ "```\n",
+ "url= r'C:\\nsolucoes4ds\\Data_Science\\creditcard.csv'\n",
+ "df_Titanic = pd.read_csv(url)\n",
+ "```\n",
+ "\n",
+ "Percebeu o r'diretorio'?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HubfewY8NgUv"
+ },
+ "source": [
+ "___\n",
+ "# **Corrigir (ou uniformizar) nome das COLUNAS**\n",
+ "* Por exemplo, reescrever o nome das COLUNAS usando lowercase()."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4f_pEEOjvwjk"
+ },
+ "source": [
+ "Para facilitar nossas análises, vamos aplicar o método lower() em todos os valores das COLUNAS objects/strings. Para isso, considere a função abaixo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ft13IahH1kVX"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "G-UlaHFPv7kp"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df.columns = [col.lower() for col in df.columns]\n",
+ "\n",
+ " # Segunda transformação: Aplicar o método .str.lower() nos valores das COLUNAS object/strings:\n",
+ " l_cols_objeto = df.select_dtypes(include = ['object']).columns\n",
+ " \n",
+ " for col in l_cols_objeto:\n",
+ " df[col] = df[col].str.lower()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hNixsW8M7n1X"
+ },
+ "source": [
+ "Para saber mais sobre o método df[col].str.lower(), consulte [pandas.Series.str.lower](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.lower.html)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hz90zejtbxYj"
+ },
+ "source": [
+ "transformacao_lower(df_Titanic)\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UE5P1W-CPePM"
+ },
+ "source": [
+ "# **Selecionar um subconjunto de colunas**\n",
+ "Suponha que eu queira selecionar somente as colunas 'Name' e 'Sex'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "P7HJa4x7P0bQ"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3jLZUCfePsBs"
+ },
+ "source": [
+ "df_Titanic2 = df_Titanic[['Name', 'Sex']]\n",
+ "df_Titanic2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PyNsYTilnL2r"
+ },
+ "source": [
+ "# map()\n",
+ "> Artificio para lidar com a transformação de dados utilizando um dicionário: {'key': valor}."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6z4FcyyAiTfF"
+ },
+ "source": [
+ "# Construindo uma variável mais intuitiva para nos ajudar nas análises:\n",
+ "df_Titanic['survived2'] = df_Titanic['survived']\n",
+ "df_Titanic['survived2'] = df_Titanic['survived2'].map({0:'died', 1:'survived'})\n",
+ "df_Titanic[['survived', 'survived2']].head(3)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jwBWkaJOdhCv"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar COLUNAS do dataframe**\n",
+ "* Suponha que queremos selecionar somente as COLUNAS 'survived', 'sex' e 'embarked':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ivvj8JU2pBTq"
+ },
+ "source": [
+ "df_Titanic2 = df_Titanic[['survived', 'sex', 'embarked']]\n",
+ "df_Titanic2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Nf-Wnof_fdTR"
+ },
+ "source": [
+ "___\n",
+ "# **Criar um dicionário a partir de um dataframe**\n",
+ "> Suponha o dataframe-exemplo a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lxf6Lgp4fit8"
+ },
+ "source": [
+ "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "l7yzJu1y5huV"
+ },
+ "source": [
+ "De dataframe para Dicionário..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_6V0qFZGhEoF"
+ },
+ "source": [
+ "df.to_dict('dict')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0GIe6xtqPA1Z"
+ },
+ "source": [
+ "___\n",
+ "# **Criar uma lista a partir de um dataframe**\n",
+ "> Suponha o dataframe-exemplo a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fZxgejTtPLzX"
+ },
+ "source": [
+ "df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JoShm6oF5qLV"
+ },
+ "source": [
+ "De dataframe para Lista..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gigPpSH_hlXu"
+ },
+ "source": [
+ "df.to_dict('list')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GpJDX-5xUUC0"
+ },
+ "source": [
+ "___\n",
+ "# **Mostrar as primeiras k LINHAS do dataframe**\n",
+ "> df.head(k), onde k é o número de LINHAS que queremos visualizar. Por default, k= 10."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RwC9j_OxUbIR"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "G9cp2QrsA5M0"
+ },
+ "source": [
+ "___\n",
+ "# **Mostrar as últimas k LINHAS do dataframe**\n",
+ "> df.tail(k), onde k é o número de LINHAS que queremos ver. Por default, k= 10."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9mPxyhqoA4Wc"
+ },
+ "source": [
+ "df_Titanic.tail()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Odwm2qSLA_Ro"
+ },
+ "source": [
+ "Por default, df.tail() mostra as últimas 5 LINHAS/instâncias do dataframe. Entretando, pode ser ver qualquer número de LINHAS k, como, por exemplo, k= 10 mostrado abaixo."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pUAnR00WA8ma"
+ },
+ "source": [
+ "df_Titanic.tail(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cZ64LfWv4zxo"
+ },
+ "source": [
+ "___\n",
+ "# **Mostrar o nome das COLUNAS do dataframe**\n",
+ "* df.columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CKUUrX5n4zFW"
+ },
+ "source": [
+ "df_Titanic.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6m7ukrOu5Inv"
+ },
+ "source": [
+ "___\n",
+ "# **Mostrar os tipos das COLUNAS do dataframe**\n",
+ "* Propriedade: df.dtypes --> Não há parênteses!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "S4NIHAPPl9lc"
+ },
+ "source": [
+ "df_Titanic.dtypes # dtypes é uma propriedade, portanto não requer \"()\". Os métodos, por outro lado, requerem \"(arg1, arg2, ..., argN)\""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DGc6m-UBdHlE"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar automaticamente as COLUNAS do dataframe pelo tipo**\n",
+ "> snippet: df.select_dtypes(include=[tipo]).columns\n",
+ "\n",
+ "| Tipo | O que seleciona | Sintaxe |\n",
+ "|------|-----------------|---------|\n",
+ "| number | colunas do tipo numéricas | df.select_dtypes(include=['number]).columns |\n",
+ "| float | colunas do tipo float | df.select_dtypes(include=['float']).columns |\n",
+ "| bool | colunas do tipo booleanas | df.select_dtypes(include=['bool']).columns |\n",
+ "| object | colunas do tipo categóricas/strings | df.select_dtypes(include=['object']).columns |\n",
+ "\n",
+ "* Se quisermos selecionar mais de um tipo, basta informar a lista de tipos. \n",
+ " * Exemplo: df.select_dtypes(include=['object', 'float']).columns\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "O88YRCqIdYFL"
+ },
+ "source": [
+ "## Selecionar automaticamente as COLUNAS Numéricas do dataframe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xG4a9ZfRnxPW"
+ },
+ "source": [
+ "### Lista com as COLUNAS numéricas do dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "C87uga35dKsF"
+ },
+ "source": [
+ "l_cols_numericas = df_Titanic.select_dtypes(include = ['number']).columns # \".columns\" retorna a lista de colunas numéricas\n",
+ "l_cols_numericas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5W6kbIVNn2UA"
+ },
+ "source": [
+ "### DataFrame com as COLUNAS numéricas:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iTieUd_-eDmW"
+ },
+ "source": [
+ "df_numericas = df_Titanic.select_dtypes(include = ['number']) # Atenção: aqui não temos .columns --> Neste caso, o retorno será o dataframe.\n",
+ "df_numericas.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xh4BFs_lds80"
+ },
+ "source": [
+ "## Selecionar automaticamente as COLUNAS float do dataframe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Tw3FD74MoC6q"
+ },
+ "source": [
+ "### Lista com as COLUNAS float:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5clAUAIrd3UR"
+ },
+ "source": [
+ "l_cols_float = df_Titanic.select_dtypes(include = ['float']).columns\n",
+ "l_cols_float"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IZPROG6IoHwy"
+ },
+ "source": [
+ "### DataFrame com as COLUNAS float:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "osJDsyMHeXX4"
+ },
+ "source": [
+ "df_float = df_Titanic.select_dtypes(include = ['float']) # Atenção: aqui não temos .columns\n",
+ "df_float.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5uObezIIfuJ4"
+ },
+ "source": [
+ "## Selecionar automaticamente as COLUNAS Booleanas do dataframe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xMKP5HhgoeMg"
+ },
+ "source": [
+ "### Lista com as COLUNAS Booleanas:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3Pn2IPBkf7k-"
+ },
+ "source": [
+ "l_cols_booleanas = df_Titanic.select_dtypes(include = ['bool']).columns\n",
+ "l_cols_booleanas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "k3sdiuXYokBE"
+ },
+ "source": [
+ "### DataFrame com as COLUNAS Booleanas:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Oem-M-17f7lG"
+ },
+ "source": [
+ "df_booleanas = df_Titanic.select_dtypes(include=['bool']) # Atenção: aqui não temos .columns\n",
+ "df_booleanas.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ObHYW92-gOXz"
+ },
+ "source": [
+ "## Selecionar automaticamente as COLUNAS do tipo string (object)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IzM5CIKXoxHO"
+ },
+ "source": [
+ "### Lista com as COLUNAS do tipo object/string:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rdYThBingOX1"
+ },
+ "source": [
+ "l_cols_objeto = df_Titanic.select_dtypes(include=['object']).columns\n",
+ "l_cols_objeto"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2ZGB5d36o21t"
+ },
+ "source": [
+ "### DataFrame com as COLUNAS do tipo Object/String:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kWTtxeU4gOX4"
+ },
+ "source": [
+ "df_cols_obs = df_Titanic.select_dtypes(include=['object']) # Atenção: aqui não temos .columns\n",
+ "df_cols_obs.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SEBKHKRLkbUK"
+ },
+ "source": [
+ "___\n",
+ "# **Reordenar as COLUNAS do dataframe**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XRWfelWEkhae"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KBGDeR_JkyCc"
+ },
+ "source": [
+ "* Suponha que queremos reordenar as COLUNAS do dataframe df_Titanic em ordem alfabética, conforme abaixo:\n",
+ " * age;\n",
+ " * embarked;\n",
+ " * fare;\n",
+ " * parch;\n",
+ " * pclass;\n",
+ " * sex;\n",
+ " * sibsp;\n",
+ " * survived."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "d9jJi6qllnq_"
+ },
+ "source": [
+ "# Dataframe ordenado\n",
+ "df_Titanic = df_Titanic.reindex(sorted(df_Titanic.columns), axis = 1)\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Cj4MREti-izC"
+ },
+ "source": [
+ "___\n",
+ "# **Mostrar a dimensão do dataframe**\n",
+ "* Dimensão = Número de LINHAS e COLUNAS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "50Tij93l-n7B"
+ },
+ "source": [
+ "df_Titanic.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZQo4YeH_-qfL"
+ },
+ "source": [
+ "Qual a interpretação?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "klHcwpPEALP8"
+ },
+ "source": [
+ "## **Quebrar a dimensão em duas partes: número de LINHAS e COLUNAS**\n",
+ "* Número de linhas do dataframe.: df_Titanic.shape[0]\n",
+ "* Número de colunas do dataframe: df_Titanic.shape[1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qjR8OEdDAOog"
+ },
+ "source": [
+ "f'O dataframe df_Titanic possui {df_Titanic.shape[0]} linhas e {df_Titanic.shape[1]} colunas.'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "pIsf_nDtyAvF"
+ },
+ "source": [
+ "___\n",
+ "# **Combinar dataframes: Merge, Join & Concatenate**\n",
+ "* Fonte: [Merge, join, and concatenate](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "s1fSplrlEMHK"
+ },
+ "source": [
+ "* A seguir, três formas para combinar dataframes:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6DYtWxuIrdzF"
+ },
+ "source": [
+ "## Concatenate\n",
+ "* Une/empilha dataframes\n",
+ "* Fonte: https://github.com/aakankshaws/Pandas-exercises"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nnP5VuWkri_b"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rkJvSGYSrm8b"
+ },
+ "source": [
+ "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n",
+ " 'B': ['B4', 'B5', 'B6', 'B7'],\n",
+ " 'C': ['C4', 'C5', 'C6', 'C7'],\n",
+ " 'D': ['D4', 'D5', 'D6', 'D7']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NCgdYvJIrqx1"
+ },
+ "source": [
+ "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n",
+ " 'B': ['B8', 'B9', 'B10', 'B11'],\n",
+ " 'C': ['C8', 'C9', 'C10', 'C11'],\n",
+ " 'D': ['D8', 'D9', 'D10', 'D11']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gUoyjyjur5Zn"
+ },
+ "source": [
+ "df1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xU6Rh10Gr7NA"
+ },
+ "source": [
+ "df2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qKwmOWsQr9wA"
+ },
+ "source": [
+ "df3"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-MNn-XdlsjJS"
+ },
+ "source": [
+ "df= pd.concat([df1, df2, df3])\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BV6HgxSYtG6Z"
+ },
+ "source": [
+ "Veja que basicamente empilhamos os dataframes. No entanto, se fizermos..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Dp-oh-7ftLo5"
+ },
+ "source": [
+ "df = pd.concat([df1, df2, df3], axis = 1) # axis = 1 é uma operação de coluna\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iyDZt2XEtmVs"
+ },
+ "source": [
+ "Se, no entanto, tivermos:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5PAhjjVZtpP5"
+ },
+ "source": [
+ "df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']},\n",
+ " index=[0, 1, 2, 3])\n",
+ "\n",
+ "df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],\n",
+ " 'B': ['B4', 'B5', 'B6', 'B7'],\n",
+ " 'C': ['C4', 'C5', 'C6', 'C7'],\n",
+ " 'D': ['D4', 'D5', 'D6', 'D7']},\n",
+ " index=[4, 5, 6, 7])\n",
+ "\n",
+ "df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],\n",
+ " 'B': ['B8', 'B9', 'B10', 'B11'],\n",
+ " 'C': ['C8', 'C9', 'C10', 'C11'],\n",
+ " 'D': ['D8', 'D9', 'D10', 'D11']},\n",
+ " index=[8, 9, 10, 11])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zGDHd-kPt3-T"
+ },
+ "source": [
+ "Então..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3bTl2Nr2t5WM"
+ },
+ "source": [
+ "df = pd.concat([df1, df2, df3], axis = 1)\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "sUXjlp_Jt925"
+ },
+ "source": [
+ "Porque isso acontece?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JdKXY873HrYt"
+ },
+ "source": [
+ "## Merge\n",
+ "> Primeiramente, vamos ver todos os casos possíveis de joins.\n",
+ "\n",
+ "### Exemplo\n",
+ "> O exemplo a seguir foi inspirado no exemplo apresentado em [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins). Considere os dataframes a seguir"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g4pmhk2t3x8s"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "d_Tabela_A = {'indices': [1,2,3,6,7,5,4,10], 'valores': ['A','B','C','D','E','F','G','H']}\n",
+ "d_Tabela_B = {'indices': [1,2,3,6,7,8,9,11], 'valores': ['AA', 'BB','CC','DD','EE','FF','GG','HH']}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XxfUULxY52ns"
+ },
+ "source": [
+ "df_conjunto_A = pd.DataFrame(d_Tabela_A).set_index('indices')\n",
+ "df_conjunto_B = pd.DataFrame(d_Tabela_B).set_index('indices')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gGdU36Vi0Yso"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5w7ox7LV9cuG"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TPhmKw-F9fWX"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5AaTlCPy9FBZ"
+ },
+ "source": [
+ "df_inner_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'inner')\n",
+ "df_inner_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "U3OjFM0E0af-"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-efYd9c69k4L"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SqFbNStz9k4S"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rUpc2k729KA-"
+ },
+ "source": [
+ "df_left_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'left')\n",
+ "df_left_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WioSBHjW06Hg"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IrzPjGNp9o2n"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "tFFTp_yG9o2s"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_D4tF7E-9PCx"
+ },
+ "source": [
+ "df_right_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'right')\n",
+ "df_right_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "E9xFrurZ0ksg"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kQCBAfj_9rO_"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FTDHYsgc9rP0"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hJqyAs0U9XwO"
+ },
+ "source": [
+ "df_outer_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how = 'outer')\n",
+ "df_outer_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "fHEgLynu0vve"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZA8CcERE-RRS"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IZiAa9X6-UL0"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jdUt63rA-Vjo"
+ },
+ "source": [
+ "df_left_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"left_only\"')\n",
+ "df_left_excluding_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CShcqL-h1MqK"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ECjUDoYf_C9x"
+ },
+ "source": [
+ "df_conjunto_A"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xym7VsXi_FXa"
+ },
+ "source": [
+ "df_conjunto_B"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-zFalmly_HJ7"
+ },
+ "source": [
+ "df_right_excluding_join = pd.merge(df_conjunto_A, df_conjunto_B, on = 'indices', how =\"outer\", indicator=True).query('_merge==\"right_only\"')\n",
+ "df_right_excluding_join"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "T8v4-zUt1WQz"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Source: [Visual Representation of SQL Joins](https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins).\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8HeMgBqyAYjW"
+ },
+ "source": [
+ "### Desafio: Como resolver este?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SkCbLsoktgKl"
+ },
+ "source": [
+ "### Observações:\n",
+ "\n",
+ "* Em alguns casos a variável chave nos dois dataframes que se quer fazer o join possui nomes diferentes. Neste caso, use 'left_on' e 'right_on' para definir o nome das COLUNAS chaves no dataframe da esquerda e direita:\n",
+ " * pd.merge(df1, df2, left_on =\"employee\", right_on =\"nome\")\n",
+ " * No exemplo acima, o dataframe df1 (dataframe da esquerda) possui chave 'employee' enquanto que o dataframe df2 (dataframe da direita), possui chave 'nome'. Usando as 'left_on' e 'right_on' fica claro o nome das chaves de ligação de cada dataframe."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6Obc0fHUwIpu"
+ },
+ "source": [
+ "## Joining"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DQOa89_cwLyd"
+ },
+ "source": [
+ "df_esquerdo = pd.DataFrame({'A': ['A0', 'A1', 'A2'],\n",
+ " 'B': ['B0', 'B1', 'B2']},\n",
+ " index=['K0', 'K1', 'K2']) \n",
+ "\n",
+ "df_direito = pd.DataFrame({'C': ['C0', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D2', 'D3']},\n",
+ " index=['K0', 'K2', 'K3'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UHnX9rxzwMmx"
+ },
+ "source": [
+ "df_esquerdo"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GBc1Mr0Qwff3"
+ },
+ "source": [
+ "df_direito"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TmIk3Kjlwg-7"
+ },
+ "source": [
+ "df_esquerdo.join(df_direito)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "h609fbjjwoZ3"
+ },
+ "source": [
+ "df_esquerdo.join(df_direito, how ='outer')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Y8W2kP-VCB3E"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar LINHAS do dataframe baseado nos índices**\n",
+ "### Leitura Adicional\n",
+ "* [pandas loc vs. iloc vs. ix vs. at vs. iat?\n",
+ "](https://stackoverflow.com/questions/28757389/pandas-loc-vs-iloc-vs-ix-vs-at-vs-iat/47098873#47098873)\n",
+ "* [Indexing and selecting data](https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NN1R1ngAG61x"
+ },
+ "source": [
+ "## 1st Approach - pd.loc[]\n",
+ "* Para capturar o conteúdo da linha k, use df.loc[row_indexer,column_indexer]."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oduXMUtIUvkN"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JX9nGPWcVLgE"
+ },
+ "source": [
+ "\n",
+ "Por exemlo, o comando a seguir mostra o conteúdo da linha 0, todas as COLUNAS(:)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U5-I2NgYC2fD"
+ },
+ "source": [
+ "df2= df_Titanic.loc[1,:]\n",
+ "df2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tDSJcQLTDyJw"
+ },
+ "source": [
+ "Mostrando o conteúdo das LINHAS k= 1:2 (ou seja, LINHAS 1 e 2), todas as COLUNAS(:)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JD1TDTqAD_5r"
+ },
+ "source": [
+ "df_Titanic.loc[1:2, :]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EoAmcdfnEIho"
+ },
+ "source": [
+ "Mostrar os conteúdos da linha k= 1, coluna 'pclass':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8vjc5z3_EQfY"
+ },
+ "source": [
+ "df_Titanic.loc[1, ['pclass']]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7bC8-H-QFLgd"
+ },
+ "source": [
+ "Mostrar os conteúdos da linha k= 1 e COLUNAS ['pclass', 'sex']:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LYFTrZr_FR5g"
+ },
+ "source": [
+ "df_Titanic.loc[0, ['pclass', 'sex']]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UtUsmU8sXYTU"
+ },
+ "source": [
+ "Porque temos um erro aqui?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CRy5sDx-XbBL"
+ },
+ "source": [
+ "Versão correta abaixo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5Lfw0HEnXdn0"
+ },
+ "source": [
+ "df_Titanic.loc[1, ['pclass', 'sex']]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Tjw3vjkDZg1Z"
+ },
+ "source": [
+ "Mostrar os conteúdos da linha k= 1:5 e COLUNAS ['pclass', 'sex']:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4GuAE5MSZjNb"
+ },
+ "source": [
+ "df_Titanic.loc[1:5, ['pclass', 'sex']]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xRZxqE6RFnJI"
+ },
+ "source": [
+ "Agora suponha que queremos selecionar toda a 'sex'. Como fazer isso?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JdeD_uzfFrp5"
+ },
+ "source": [
+ "df_sex= df_Titanic.loc[:, 'sex']\n",
+ "df_sex.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "z_WUjYxsX-Av"
+ },
+ "source": [
+ "Fácil selecionarmos o que queremos usando .loc() e iloc(), certo?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RKk0zollHFbp"
+ },
+ "source": [
+ "## 2nd Approach - Usando lists\n",
+ "\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jhwoY6LmGzC0"
+ },
+ "source": [
+ "df_Titanic[0:2] # Mostrar os conteúdos das LINHAS 0:2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I6EOVIDxGiy-"
+ },
+ "source": [
+ "df_Titanic[:3] # Mostrar os conteúdos até a linha 3"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VOHp77F8H9t1"
+ },
+ "source": [
+ "df_Titanic['sex'].head() # Mostrar o conteúdo inteiro da variável 'sex'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8nvHNdhPZ040"
+ },
+ "source": [
+ "df_Titanic[0:5]['sex'].head() # Mostrar as LINHAS 0 a 5 da variável 'sex'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GMFso1jaYXgN"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar/Filtrar/Substituir LINHAS do dataframe baseado em condições**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BKljSpS5ou-i"
+ },
+ "source": [
+ "## Exemplo 1\n",
+ "> Aproveitando o exemplo anterior, queremos selecionar do dataframe somente os passageiros do sexo 'male'."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jek8Ru3Aam23"
+ },
+ "source": [
+ "### Approach 1: df.loc() e df.iloc()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eysZoBX2YKb-"
+ },
+ "source": [
+ "df_sexo_m_1 = df_Titanic.loc[df_Titanic['sex'] == 'male', 'sex']\n",
+ "df_sexo_m_1.head() "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uLDOHKGfaq-Z"
+ },
+ "source": [
+ "### Approach 2: Uso do []"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QncrZwHkasiu"
+ },
+ "source": [
+ "df_sexo_m_2 = df_Titanic[df_Titanic['sex'] == 'male']['sex']\n",
+ "df_sexo_m_2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ot6UBTYJF-AJ"
+ },
+ "source": [
+ "### Approach 3: df.isin()\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OBRF0be3VuTi"
+ },
+ "source": [
+ "#### Exemplo 1 - Filtro simples"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LeTDiGICGOzb"
+ },
+ "source": [
+ "df_sexo_m_3 = df_Titanic['sex'].isin(['male'])\n",
+ "df_sexo_m_3.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Q6emu30nGmpt"
+ },
+ "source": [
+ "#### Exemplo 2 - Filtro duplo = Duas condições\n",
+ "> Selecionar todas as LINHAS onde sexo = 'male' e Pclass = 1."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TRaiCYMRGpgl"
+ },
+ "source": [
+ "# Filtros usando df.isin() \n",
+ "filtro_m = df_Titanic[\"sex\"].isin([\"male\"]) \n",
+ "filtro_class1 = df_Titanic[\"Pclass\"].isin([1]) \n",
+ " \n",
+ "# Mostra os resutados \n",
+ "df_Titanic[filtro_m & filtro_class1].head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Sh0DDj1xcPaI"
+ },
+ "source": [
+ "df_sexo_m_class = df_Titanic[((df_Titanic['sex'] == 'male') & (df_Titanic['Pclass'] == 1))]\n",
+ "df_sexo_m_class.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ujrYHyOsfW7n"
+ },
+ "source": [
+ "### Approach 4 - Filtrar com df.str.contains('s_substr')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gntbfHgTfanx"
+ },
+ "source": [
+ "# Mostrar todas as LINHAS onde a string 'Mr' aparece no nome do passageiro:\n",
+ "df2 = df_Titanic[df_Titanic['Name'].str.contains('Mr')]\n",
+ "df2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eaRtQ8Ja8MOH"
+ },
+ "source": [
+ "Para saber mais sobre o método df[col].str.contais(), consulte https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FyJ-gEjzQI2Y"
+ },
+ "source": [
+ "## Substituir valores do dataframe\n",
+ "> Suponha que queremos substituir todos os valores de pclass da seguinte forma:\n",
+ "* Se pclass = 1 --> pclass2 = 'Classe1';\n",
+ "* Se pclass = 2 --> pclass2 = 'Classe2';\n",
+ "* Se pclass = 3 --> pclass2 = 'Classe3';\n",
+ "\n",
+ "Como fazer isso?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Pi8MFiUPQQb7"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "19mynzdfQqVf"
+ },
+ "source": [
+ "df_Titanic['pclass2'] = df_Titanic['pclass']\n",
+ "df_Titanic['pclass2'][df_Titanic['pclass'] == 1] = 'Classe1'\n",
+ "df_Titanic['pclass2'][df_Titanic['pclass'] == 2] = 'Classe2'\n",
+ "df_Titanic['pclass2'][df_Titanic['pclass'] == 3] = 'Classe3'\n",
+ "df_Titanic['pclass2'].head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KVSAYeU0KA2V"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar amostras aleatórias do dataframe**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "U502dAs3OfOH"
+ },
+ "source": [
+ "Vimos que o dataframe df_Titanic é muito grande. Então, vamos selecionar aleatoriamente 100 LINHAS."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0BrKUnAiPcAy"
+ },
+ "source": [
+ "import random \n",
+ "\n",
+ "# Biblioteca para avaliarmos o tempo de processamento de cada alternativa\n",
+ "import time"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iJ1G8lYgKGsc"
+ },
+ "source": [
+ "# Usando sample\n",
+ "t0= time.time()\n",
+ "df_Titanic_a100= df_Titanic.sample(100, replace= False, random_state= 20111974)\n",
+ "t1= time.time()\n",
+ "t= t1-t0\n",
+ "df_Titanic_a100.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8DvWOKizZQr8"
+ },
+ "source": [
+ "f'Tempo de processamento: {t}'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nAHLTjpvYKPS"
+ },
+ "source": [
+ "# Usando NumPy\n",
+ "import numpy as np\n",
+ "\n",
+ "t0 = time.time()\n",
+ "np.random.seed(20111974)\n",
+ "indices = np.random.choice(df_Titanic.shape[0], replace = False, size=100)\n",
+ "df_Titanic_a100_2 = df_Titanic.iloc[indices]\n",
+ "t1 = time.time()\n",
+ "t = t1-t0\n",
+ "df_Titanic_a100_2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U8PEDMJ4a52P"
+ },
+ "source": [
+ "f'Tempo de processamento: {t}'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wYeuJWdEdMPd"
+ },
+ "source": [
+ "df_Titanic_a100_2.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vNMiRkjCQ9Mu"
+ },
+ "source": [
+ "___\n",
+ "# **Descrever o Dataframe**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GllUFj56RHuD"
+ },
+ "source": [
+ "df_Titanic_a100.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "izbpIEi1d1sx"
+ },
+ "source": [
+ "df_Titanic_a100_2.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "H40G3QzWbG9N"
+ },
+ "source": [
+ "___\n",
+ "# **Identificar e lidar com LINHAS duplicadas**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_OoM_HS5ZgxG"
+ },
+ "source": [
+ "## Exemplo 1\n",
+ "* considera as duplicatas em todas as COLUNAS do dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5XOOdOZBbLc_"
+ },
+ "source": [
+ "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Gio08BkTbTOp"
+ },
+ "source": [
+ "# Lista as duplicações em forma booleana\n",
+ "df.duplicated()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "obgbM4d_hJ_J"
+ },
+ "source": [
+ "Observe a linha 5, onde temos a informação que esta linha está duplicada. Na verdade, a linha 5 é igual à linha 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LHhOIb-EbWfn"
+ },
+ "source": [
+ "# Mostra as LINHAS duplicadas\n",
+ "df[df.duplicated()]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IyJS70_kZ-Jk"
+ },
+ "source": [
+ "# Deleta a linha 5 que, como vimos, estava duplicada (uma cópia da linha 1).\n",
+ "df= df.drop_duplicates()\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3Q05mxOSaEjX"
+ },
+ "source": [
+ "## Exemplo 2\n",
+ "* Considera somente algumas COLUNAS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jiqyjcqdaQ1y"
+ },
+ "source": [
+ "df = pd.DataFrame({'A':[1,1,3,4,5,1], 'B':[1,1,3,7,8,1], 'C':[3,1,1,6,7,1]})\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "F_118d7vbZ9Y"
+ },
+ "source": [
+ "# Mostra as LINHAS duplicadas usando as COLUNAS 'A' e 'B'\n",
+ "df[df.duplicated(subset=['A','B'])]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_1w_ZZO4vF3A"
+ },
+ "source": [
+ "# Deleta as LINHAS 1 e 5, pois como podemos ver, são duplicatas da linha 0\n",
+ "df= df.drop_duplicates(subset = ['A', 'B'])\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qVx6p8u36jhD"
+ },
+ "source": [
+ "___\n",
+ "# **Trabalhar com dados do tipo texto**\n",
+ "* Fontes:\n",
+ " * [Working with text data](https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html)\n",
+ " * [Using String Methods](https://www.ritchieng.com/pandas-string-methods/)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JLG3cVA1e8-B"
+ },
+ "source": [
+ "Preparando os dados para o exemplo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "G_CEULoyeP8C"
+ },
+ "source": [
+ "# Definir um dicionário com os dados: \n",
+ "import numpy as np\n",
+ "\n",
+ "l_idade = []\n",
+ "for i in range(6):\n",
+ " np.random.seed(i) \n",
+ " l_idade.append(np.random.randint(10, 40))\n",
+ " \n",
+ "\n",
+ "d_exemplo = {'Nome':['Mr. Antonio dos Santos', 'Mr. Joao Pedro', 'Miss. Priscila Alvarenga', 'Mr. fagner NoVAES', 'Miss. Danielle Aparecida', 'Mr. Paullo Amarantes'], \n",
+ " 'Idade': l_idade, \n",
+ " 'Cidade':['lisboa', 'Sintra', 'Braga', 'Guimaraes', 'Mafra', 'Nazare']} \n",
+ " \n",
+ "# Converte o dicionário num dataframe\n",
+ "df = pd.DataFrame(d_exemplo) \n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "or-Kzaqmdn2b"
+ },
+ "source": [
+ "* Sugestões do que podemos fazer com relação á coluna 'nome' do dataframe df:\n",
+ " * Extrair o cumprimento do nome: Mr., Miss e etc.\n",
+ " * Construir as COLUNAS PrimeiroNome e SegundoNome.\n",
+ " * Criar a variável classe_idade."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Vd99ksvcg7uy"
+ },
+ "source": [
+ "## Extrair o cumprimento do nome"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rNsANzFAg_Kn"
+ },
+ "source": [
+ "df_Nome= df['Nome'].str.split(' ', n = 2, expand = True) \n",
+ "df_Nome"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ianqsxLol008"
+ },
+ "source": [
+ "Altere o valor de n para 3 e explique como as coisas funcionam..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5NDAkEqCl6H5"
+ },
+ "source": [
+ "# Capturando o cumprimento do nome:\n",
+ "df['tamanho_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[0]\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B1QoH4LyrpVI"
+ },
+ "source": [
+ "## Construir as COLUNAS primeiro_nome e Segundo_Nome"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cbi4eRN2mOu9"
+ },
+ "source": [
+ "# Capturando o primeiro nome:\n",
+ "df['primeiro_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[1]\n",
+ "df['ultimo_nome'] = df['Nome'].str.split(' ', n = 2, expand = True)[2]\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7eagWhgZrwOh"
+ },
+ "source": [
+ "### Construir a variável classe_idade\n",
+ "\n",
+ " | Limite Inferior | Limite Superior | Classe |\n",
+ " |-----------------|-----------------|--------|\n",
+ " | Inf | 15 | Inf_15 |\n",
+ " | 15 | 20 | 15_20 |\n",
+ " | 20 | 30 | 25_30 |\n",
+ " | 30 | 40 | 30_40 |\n",
+ " | 40 | 50 | 40_50 |\n",
+ " | 50 | Sup | 50_Sup |"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lBjRBGBWr2AH"
+ },
+ "source": [
+ "def classe_idade):\n",
+ " if (Idade <= 15):\n",
+ " return 'Inf_15'\n",
+ " if (15 < Idade <= 20):\n",
+ " return '15_20'\n",
+ " elif(20 < Idade <= 30):\n",
+ " return '20_30'\n",
+ " elif (30 < Idade <= 40):\n",
+ " return '30_40'\n",
+ " elif (40 < Idade <= 50):\n",
+ " return '40_50'\n",
+ " elif (Idade > 50):\n",
+ " return '50_Sup'\n",
+ " else:\n",
+ " return 'Outros'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OogrvjCrsdoh"
+ },
+ "source": [
+ "df['classe_idade'] = df['Idade'].map(classe_idade)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JDtxz_eaRcmi"
+ },
+ "source": [
+ "___\n",
+ "# **Agrupar Informações: pd.groupby()**\n",
+ "* Fonte: [Group By: split-apply-combine](https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html)\n",
+ "\n",
+ "* Os componentes do comando Groupby()\n",
+ " * **Grouping_Column** - Coluna Categórica pelo qual os dados serão agrupados;\n",
+ " * **Aggregating_Column** - Coluna numérica cujos valores serão agrupados;\n",
+ " * **Aggregating_Function** - Função agregadora, ou seja: sum, min, max, mean, median, etc...\n",
+ "\n",
+ "> Sintaxe: \n",
+ "\n",
+ "```\n",
+ "df.groupby('Grouping_Column').agg({'Aggregating_Column': 'Aggregating_Function'})\n",
+ "\n",
+ "OU\n",
+ "\n",
+ "df['Aggregating_Column'].groupby(df['Grouping_Column']).Function()\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bmFf-273XPXj"
+ },
+ "source": [
+ "## Exemplo 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wteEveUsd36C"
+ },
+ "source": [
+ "transformacao_lower(df_Titanic)\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "buF5DhkFfqVA"
+ },
+ "source": [
+ "# Agrupando df_Titanic por 'sex3'\n",
+ "df_Titanic.groupby(['sex', 'pclass']).agg({'fare': ['min', 'median', 'mean','max'], 'age': ['count', 'mean','max']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YP3GDwq0gR_V"
+ },
+ "source": [
+ "# Agrupando df_Titanic por 'sex3' e 'Pclass'\n",
+ "df_Titanic.groupby(['sex3','Pclass']).agg({'Fare': ['max', 'min']}).round(0)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "se4tQ3ETeUfv"
+ },
+ "source": [
+ "df_Titanic.groupby(['sex3']).agg({'Age': ['mean','min','max']}).round(0)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zUj82I7Cm220"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OrLZjm9bXTOr"
+ },
+ "source": [
+ "## Exemplo 2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "x8aPZPT6XZVP"
+ },
+ "source": [
+ "### Preparando o exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KrCe6RgOXaFx"
+ },
+ "source": [
+ "l_coluna = []\n",
+ "\n",
+ "for i in range(1,6):\n",
+ " np.random.seed(i)\n",
+ " l_coluna.append(np.random.randint(0, 10, 10))\n",
+ " \n",
+ "np.random.seed(6)\n",
+ "l_coluna.append(np.random.rand(10))\n",
+ "\n",
+ "l_coluna"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "tXaHjmfSXeCw"
+ },
+ "source": [
+ "l_coluna[0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U_aEVMTHq6ee"
+ },
+ "source": [
+ "df = pd.DataFrame({'coluna6' : ['a', 'a', 'b', 'b', 'a', 'b', 'b', 'b', 'a', 'a'],\n",
+ " 'coluna7' : ['um', 'dois', 'um', 'dois', 'um', 'dois', 'dois', 'um', 'um', 'dois'],\n",
+ " 'coluna1' : l_coluna[0],\n",
+ " 'coluna2' : l_coluna[1],\n",
+ " 'coluna3' : l_coluna[2],\n",
+ " 'coluna4' : l_coluna[3],\n",
+ " 'coluna5' : l_coluna[4],\n",
+ " 'coluna8' : l_coluna[5],\n",
+ " 'Pessoas' : ['Jose','Maria','Pedro','Carlos','Joao','Ana','Manoel','Mafalda','Antonio','Ricardo'],\n",
+ " 'sexo' : ['m','f','m','m','m','f','m','f','m','m']})\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ok4a28lGlVC5"
+ },
+ "source": [
+ "Agrupando por 'coluna6':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Vx77lyzlZIFW"
+ },
+ "source": [
+ "df.groupby('coluna6').agg({'coluna1': ['min','mean','median','max']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "T6i-R2KemadE"
+ },
+ "source": [
+ "Agora, vamos repetir o processo usando duas COLUNAS-chaves 'coluna6' e 'coluna7':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WxmHQnQSZrXA"
+ },
+ "source": [
+ "df_estatisticas_descritivas = df.groupby(['coluna6','coluna7']).agg({'coluna1': ['min','mean','median','max']})\n",
+ "df_estatisticas_descritivas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ipw5EROwaaCX"
+ },
+ "source": [
+ "Observe que df_estatisticas_descritivas é um dataframe. Portanto, podemos selecionar LINHAS e/ou COLUNAS deste dataframe da forma que quisermos."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qk5uSdVwb7dH"
+ },
+ "source": [
+ "# Índices do dataframe:\n",
+ "df_estatisticas_descritivas.index"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "brIgUFlkalix"
+ },
+ "source": [
+ "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um':\n",
+ "df_estatisticas_descritivas.loc[('a', 'um')]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fQUs2PVHc6iR"
+ },
+ "source": [
+ "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', primeiro valor:\n",
+ "df_estatisticas_descritivas.loc[('a', 'um')][0] # ou seja, selecionamos min"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zT0xiee6dDpK"
+ },
+ "source": [
+ "# Selecionando o conteúdo de coluna6= 'a' e coluna7= 'um', segundo valor:\n",
+ "df_estatisticas_descritivas.loc[('a', 'um')][1] # ou seja, selecionamos mean"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vXlcjPM6dQKi"
+ },
+ "source": [
+ "E daí por diante..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EMxFMqn9dm3g"
+ },
+ "source": [
+ "Para aprender mais sobre como trabalhar com dois índices em um dataframe, consulte [Hierarchical indices, groupby and pandas](https://www.datacamp.com/community/tutorials/pandas-multi-index)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gNHyH7M0pGDy"
+ },
+ "source": [
+ "___\n",
+ "## Exemplo 3\n",
+ "### Operações e transformações em grupo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ywl3k_l8pGD0"
+ },
+ "source": [
+ "# Mostra o dataframe-exemplo:\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AF8cbNsjpGD5"
+ },
+ "source": [
+ "# Constroi dataframe df_Medias\n",
+ "df_Medias = df.groupby('coluna6').mean().add_prefix('mean_')\n",
+ "df_Medias"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JGlA6ufLpGD9"
+ },
+ "source": [
+ "# Combina (merge) com o dataframe df:\n",
+ "pd.merge(df, df_Medias, left_on ='coluna6', right_index=True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1MjZu3sVpGEd"
+ },
+ "source": [
+ "___\n",
+ "# **Discretizar COLUNAS numéricas**\n",
+ "* pd.cut() - classes com base em valores;\n",
+ "* pd.qcut() - classes com base em quantis da amostra, ou seja teremos a mesma quantidade de itens em cada classe.\n",
+ "\n",
+ "> Este artifício é muito utilizado em Machine Learning quando queremos construir classes para variáveis numéricas (integer ou float). Acompanhe a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yK772hiSfZaE"
+ },
+ "source": [
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wi-nv6fshKIX"
+ },
+ "source": [
+ "## pd.cut()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SVExQmzDpGEe"
+ },
+ "source": [
+ "# Construir 4 classes para a variável float 'coluna8':\n",
+ "Bucket_cut = pd.cut(df['coluna8'], 4) # aqui, estamos construindo 4 buckets\n",
+ "Bucket_cut"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OOD38I6ug1AY"
+ },
+ "source": [
+ "# Quem são os Bucket's que construimos:\n",
+ "Bucket_cut.value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9s2eaZGtfsxu"
+ },
+ "source": [
+ "Como podem ver, de fato construimos 4 bucket's. **Observe que não temos a mesma quantidade de itens em cada classe!!!**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "T7u0pS64hPHC"
+ },
+ "source": [
+ "## pd.qcut()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cJTQTHA6pGEm"
+ },
+ "source": [
+ "Bucket_qcut = pd.qcut(df['coluna8'], 4, labels=False)\n",
+ "Bucket_qcut"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vM30Td_8hZre"
+ },
+ "source": [
+ "# Quem são os Bucket's que construimos:\n",
+ "Bucket_qcut.value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jhf6V5LTh4G7"
+ },
+ "source": [
+ "## Comentários\n",
+ "* pd.qcut() garante uma distribuição mais uniforme dos valores em cada classe. Isso significa que é menos provável que você tenha uma classe com muitos dados e outra com poucos dados.\n",
+ "* Eu prefiro usar pd.qcut()."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RNsR0NsS5iIU"
+ },
+ "source": [
+ "___\n",
+ "# **Distribuição conjunta - crosstabs**\n",
+ "> Suponha que queremos analisar o número de sobreviventes em relação à COLUNA embarked."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LKQv6YtSfGSU"
+ },
+ "source": [
+ "df_Titanic2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ANhb5rBffTh6"
+ },
+ "source": [
+ "pd.crosstab(df_Titanic2['survived'], df_Titanic2['embarked'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WIlHAYEVqSjT"
+ },
+ "source": [
+ "___\n",
+ "# **Deletar COLUNAS do dataframe**\n",
+ "> Deletar as COLUNAS 'coluna2' e 'coluna5' do dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YssOMF_Vqso5"
+ },
+ "source": [
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rVF_1p0Gq3gZ"
+ },
+ "source": [
+ "## Usando inplace = True"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7BjRIX1jqWQT"
+ },
+ "source": [
+ "df.drop(['coluna2','coluna5'], axis =1, inplace =True)\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "POC2fnTlq8mK"
+ },
+ "source": [
+ "## Usando atribuição"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YRSwEbnfq7s_"
+ },
+ "source": [
+ "df= df.drop(['coluna2','coluna5'], axis =1)\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bHth6KSv7k0G"
+ },
+ "source": [
+ "___\n",
+ "# **Criar COLUNAS dummies para dados categóricos**\n",
+ "> Nosso objetivo é construir variáveis dummies para nossas COLUNAS categóricas.\n",
+ "\n",
+ "* Fontes: \n",
+ " * [Categorical data](https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html)\n",
+ " * [Creating Dummy Variables](https://www.ritchieng.com/pandas-creating-dummy-variables/)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GOqcARHqjMr_"
+ },
+ "source": [
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yNqvwEu9jbuW"
+ },
+ "source": [
+ "Vamos construir variáveis dummies para as COLUNAS 'coluna6' e 'coluna7', da seguinte forma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "16osZsMEjmDh"
+ },
+ "source": [
+ "pd.get_dummies(df['coluna6'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Cb1gp_Y1jxz2"
+ },
+ "source": [
+ "Qual a interpretação do resultado acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Cic19l-Mj39q"
+ },
+ "source": [
+ "pd.get_dummies(df['coluna7'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "44FDXcoyj-tT"
+ },
+ "source": [
+ "Qual a interpretação do resultado acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cxHc6BvDkCWl"
+ },
+ "source": [
+ "df = pd.get_dummies(df, columns =['coluna6', 'coluna7', 'sexo'])\n",
+ "df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "A2m25N4znZ2O"
+ },
+ "source": [
+ "df.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "x0uXu0RRlB2a"
+ },
+ "source": [
+ "___\n",
+ "# **Calcular correlação (Análise de Correlação)**\n",
+ "> A correlação pode ser calculada usando o método df.corr(). Para mais detalhes sobre os tipos de correlação existentes bem como a aplicação de cada uma delas, consulte os links a seguir:\n",
+ "\n",
+ "* [Pearson correlation coefficient](https://en.wikipedia.org/wiki/Pearson_correlation_coefficient)\n",
+ "* [Kendall rank correlation coefficient](https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient)\n",
+ "* [Spearman's rank correlation coefficient](https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient).\n",
+ "\n",
+ "Para aprender mais sobre a geração de heatmap, consulte [Seaborn Heatmap Tutorial (Python Data Visualization)](https://likegeeks.com/seaborn-heatmap-tutorial/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AgoigF8AnYG0"
+ },
+ "source": [
+ "## Gerando o dataframe-exemplo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NsuhsZCTmqEm"
+ },
+ "source": [
+ "# Visualizar os dados\n",
+ "df_X.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D0JNMHqYoSMs"
+ },
+ "source": [
+ "# Mostra a matriz de correlação usando a correlação de Pearson\n",
+ "set_Colunas_Correlacionadas = set()\n",
+ "matriz_correlacao = df_X.corr().where(np.triu(np.ones(df_X.corr().shape), k = 1).astype(np.bool))\n",
+ "matriz_correlacao"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6scRm8kNnbby"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "# Gerando um dataframe com 15 colunas, sendo 9 informativas e 6 redundantes:\n",
+ "from sklearn.datasets import make_classification\n",
+ "X, y = make_classification(n_samples=1000, n_features=15, n_informative=9,\n",
+ " n_redundant=6, n_repeated=0, n_classes=2, n_clusters_per_class=1,\n",
+ " random_state=20111974)\n",
+ "\n",
+ "df_X = pd.DataFrame(X, columns= ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15'])\n",
+ "df_y = pd.DataFrame(y, columns= ['target'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Vnj6A8z6r7nM"
+ },
+ "source": [
+ "### Quem são as colunas altamente correlacionadas?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "a_YUD-dOr_p-"
+ },
+ "source": [
+ "for i in range(len(matriz_correlacao.columns)):\n",
+ " for j in range(i):\n",
+ " if abs(matriz_correlacao.iloc[i, j]) > 0.8:\n",
+ " colnome = matriz_correlacao.columns[i]\n",
+ " set_Colunas_Correlacionadas.add(colnome)\n",
+ "\n",
+ "set_Colunas_Correlacionadas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3-0Xe6GdozYT"
+ },
+ "source": [
+ "A seguir, a correlação mais visual:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5-_Qadx1o1U9"
+ },
+ "source": [
+ "fig, ax = plt.subplots(figsize = (12, 12)) \n",
+ "mask = np.zeros_like(df_X.corr().abs())\n",
+ "mask[np.triu_indices_from(mask)] = 1\n",
+ "sns.heatmap(df_X.corr().abs(), mask= mask, ax= ax, cmap='coolwarm', annot= True, fmt= '.2f', center= 0)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5ZOp9ZGgtqFQ"
+ },
+ "source": [
+ "# **Scatterplot**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eReJJjG8tuKV"
+ },
+ "source": [
+ "## Com regressão"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "tVmdSo6ztruA"
+ },
+ "source": [
+ "sns.pairplot(df_X, kind = \"reg\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xG9A6b32twv-"
+ },
+ "source": [
+ "## Sem regressão"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fyTOS3zVtz-O"
+ },
+ "source": [
+ "sns.pairplot(df_X, kind = \"scatter\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "f-1bpipc6bMh"
+ },
+ "source": [
+ "___\n",
+ "# **Salvar dataframe como csv**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "64CoM1aY6gf6"
+ },
+ "source": [
+ "df_X.to_csv('example.csv')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oy646p33DJV0"
+ },
+ "source": [
+ "# **Dicionário de palavras**\n",
+ "> Muito utilizado em NLP e Machine Learning.\n",
+ "* Caso de Uso: Seguradoras --> Quando um segurado aciona a Seguradora para descrever um acidente (por exemplo), há um algorítmo que transforma o áudio em texto para mineração de textos."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DQR906rVD1V-"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sHvDaztJDPP7"
+ },
+ "source": [
+ "from sklearn.feature_extraction.text import CountVectorizer\n",
+ "CountVectorizer = CountVectorizer()\n",
+ "matriz_contagens = CountVectorizer.fit_transform(df_Titanic['name']) # Informe a coluna do tipo texto/string que queremos analisar/avaliar\n",
+ "print(matriz_contagens)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jwT-56dED8VJ"
+ },
+ "source": [
+ "df_dicionario_palavras = pd.DataFrame(CountVectorizer.get_feature_names(), columns = ['palavra'])\n",
+ "df_dicionario_palavras[\"vezes_que_aparece\"] = matriz_contagens.sum(axis = 0).tolist()[0]\n",
+ "df_dicionario_palavras = df_dicionario_palavras.sort_values(\"vezes_que_aparece\", ascending = False) #.reset_index(drop = True) # Sorte ordena as linhas do dataframe\n",
+ "df_dicionario_palavras.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nx65RmEAGTvd"
+ },
+ "source": [
+ "# Desafio\n",
+ "> Transforme o code Python da sessão **Dicionário de palavras** em função para usarmos futuramente."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iwd1lhq9mrD3"
+ },
+ "source": [
+ "___\n",
+ "# **Exercícios**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o_cl0kFgQfFh"
+ },
+ "source": [
+ "## Exercício 1\n",
+ "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "s8rQUo7yHKJ1"
+ },
+ "source": [
+ "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KTun1uSLuJ-A"
+ },
+ "source": [
+ "## Exercício 2\n",
+ "Source: https://github.com/aakankshaws/Pandas-exercises\n",
+ "\n",
+ "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Soq7GVZnuREq"
+ },
+ "source": [
+ "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n",
+ " 'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3']})\n",
+ " \n",
+ "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6KEsTARfvM1C"
+ },
+ "source": [
+ "## Exercício 3\n",
+ "Source: https://github.com/aakankshaws/Pandas-exercises\n",
+ "\n",
+ "* Considere os dataframes a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hgxE5gZ9vMEg"
+ },
+ "source": [
+ "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n",
+ " 'key2': ['K0', 'K1', 'K0', 'K1'],\n",
+ " 'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3']})\n",
+ " \n",
+ "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n",
+ " 'key2': ['K0', 'K0', 'K0', 'K0'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iv7AmZ1ivm8R"
+ },
+ "source": [
+ "### Perguntas\n",
+ "* Qual o output e a interpretação dos comandos a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TWAW_1tuvvSO"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QjM7pBONvzCJ"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D1Rr3Ghsv2iS"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vXQwLjT-v3Iu"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EIdltTC-t_lF"
+ },
+ "source": [
+ "## Exercício 5\n",
+ "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bMwPLgWclWBq"
+ },
+ "source": [
+ "___\n",
+ "## Exercício 6\n",
+ "* (a) Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN).\n",
+ "\n",
+ "### Feature Engineering\n",
+ "* (b) Com a coluna 'cabin', construir as colunas:\n",
+ " * deck - Letra de Cabin;\n",
+ " * seat - Número de Cabin\n",
+ "* (c) Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n",
+ "* (d) Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário.\n",
+ "* (e) Discretizar a coluna 'fare' em 10 buckets.\n",
+ "* (f) Discretizar a coluna 'age'.\n",
+ "* (g) Capturar os títulos 'Ms', 'Mr' e etc contidos na coluna 'Title';\n",
+ "* (h) Qual a relação entre as variáveis e a variável-target?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V7KUGAX6lilP"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/MathMachado/Python4DS/DS_Python/Dataframes/Titanic_With_MV.csv?token =AGDJQ63MNPPPROFNSO2BZW25XSR72', index_col= 'PassengerId')\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m3UnAPJakCLR"
+ },
+ "source": [
+ "* Segue o dicionário de dados do dataframe Titanic:\n",
+ " * PassengerID: ID do passageiro;\n",
+ " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n",
+ " * Pclass: Classe;\n",
+ " * Age: Idade do Passageiro;\n",
+ " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n",
+ " * Parch: Número de pais/crianças a bordo;\n",
+ " * Fare: Valor pago pelo Passageiro;\n",
+ " * Cabin: Cabine do Passageiro;\n",
+ " * Embarked: A porta pelo qual o Passageiro embarcou.\n",
+ " * Name: Nome do Passageiro;\n",
+ " * sex: sexo do Passageiro\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B_3s5cgxfNKQ"
+ },
+ "source": [
+ "## Resposta do item (a)\n",
+ "### Coluna XPTO\n",
+ "\n",
+ "\n",
+ "### Coluna XPTO2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "q3oLgyhdL6xd"
+ },
+ "source": [
+ "## Resposta do item (b)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UbexhGtayV4X"
+ },
+ "source": [
+ "## Exercício 7\n",
+ "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Iia0ikd_KBtH"
+ },
+ "source": [
+ "## Exercício 8\n",
+ "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HPiLKUkWNYs3"
+ },
+ "source": [
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TUVTlE9WYW8C"
+ },
+ "source": [
+ "## Exercício 9\n",
+ "O arquivo FIFA.csv contem dados relacionados à última edição do FIFA 2018 (um dos jogos de video-game mais famosos) e traz os mais variados dados sobre os jogadores (exemplo): idade, nacionalidade, potencial, salário e etc. Faça o seguinte:\n",
+ "\n",
+ "1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);\n",
+ "2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n",
+ "3. Qual o dtype de cada variável/atributo do dataframe?\n",
+ "4. Se alguma variávável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n",
+ "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;\n",
+ "6Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n",
+ "7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição.\n",
+ "8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');\n",
+ "9. Qual a número de jogadores por idade?\n",
+ "10. Quantos jogadores possuem cada clube?\n",
+ "11. Qual a média de idade por clube?\n",
+ "12. Qual a média de salário por país?\n",
+ "13. Qual a média de salário por clube?\n",
+ "14. Qual a média de salário por idade?\n",
+ "15. Quanto cada clube gasta com pagamento de salários?\n",
+ "16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?\n",
+ "17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n",
+ "18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n",
+ "19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'.\n",
+ "20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed'=?\n",
+ "21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?\n",
+ "22. Quem são os outliers em termos de salário?\n",
+ "23. Quem são os outliers em termos de potência no chute?\n",
+ "\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ldWQd9j4NhPS"
+ },
+ "source": [
+ "# Carrega a library Pandas\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pynSV0viI8CA"
+ },
+ "source": [
+ "#configuração\n",
+ "d_configuracao = {\n",
+ " 'display.max_columns': 1000,\n",
+ " 'display.expand_frame_repr': True,\n",
+ " 'display.max_rows': 10,\n",
+ " 'display.precision': 2,\n",
+ " 'display.show_dimensions': True\n",
+ " }\n",
+ "\n",
+ "for op, value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AswYS-ILI-qW"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/Celso-Omoto/DSWP/master/Dataframes/FIFA.csv'\n",
+ "#df_Fifa2018 = pd.read_csv(url, index_col = 'PassengerId')\n",
+ "df_Fifa2018 = pd.read_csv(url)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "K7xLrlPuKsAW"
+ },
+ "source": [
+ "df_Fifa2018.head()\n",
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LTZGbOHiKxsW"
+ },
+ "source": [
+ "df_Fifa2018.set_index('ID', inplace = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1y9oN-IeU7Sb"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df_Fifa2018.columns = [col.lower() for col in df.columns]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uRS02MeCVVID"
+ },
+ "source": [
+ "transformacao_lower(df_Fifa2018)\n",
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sI_2oz3uMQFF"
+ },
+ "source": [
+ "#17 - Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n",
+ "df_Fifa2018.sort_values('shotpower', ascending=False).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-9jCfEaSNJS1"
+ },
+ "source": [
+ "df_Fifa2018.groupby('overall').agg({'age':'mean', 'nationality': 'count'}).sort_values('overall').head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PMrTNLV1Oe5P"
+ },
+ "source": [
+ "df_Fifa2018.groupby('club').agg({'overall':'mean'}).sort_values('overall').head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dckaTDS9NaqG"
+ },
+ "source": [
+ "df_Fifa2018.groupby('club').agg({'potential':'mean','overall':'mean'}).head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OBuycRCzRbyG"
+ },
+ "source": [
+ "del df_Fifa2018['photo']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1crol52URcmt"
+ },
+ "source": [
+ "del df_Fifa2018['club logo']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "W0X7-q1CSNfM"
+ },
+ "source": [
+ "del df_Fifa2018['flag']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LMtzccaxSK29"
+ },
+ "source": [
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZPwu5sLnSyAc"
+ },
+ "source": [
+ "df_Fifa2018.dtypes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PBq3jr8nTUS0"
+ },
+ "source": [
+ "df_Fifa2018.select_dtypes(include=['object', 'string']).columns "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "82JaHKYATgdD"
+ },
+ "source": [
+ "df_Fifa2018[df_Fifa2018.select_dtypes(include=['object', 'string']).columns ]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NAyzCiTMW7YT"
+ },
+ "source": [
+ "df_Fifa2018.groupby('nationality').agg({'age':['count','mean']}).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mkNA4xskc1b5"
+ },
+ "source": [
+ "df_Fifa2018.groupby('nationality').agg({'age':'mean','nationality':'count'}).sort_values('nationality').head(10)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eivUHr17ZiHs"
+ },
+ "source": [
+ "df_Fifa2018.sort_values('age', ascending=False).groupby('nationality').agg({'age':['count','mean']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FCs2gPK8ckS7"
+ },
+ "source": [
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From 7efafa0dfac3f2c1178e9309595129b897e4b742 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Wed, 14 Oct 2020 16:42:04 -0300
Subject: [PATCH 04/21] Criado usando o Colaboratory
---
...__DataViz_Matplotlib & Seaborn_aluno.ipynb | 865 ++++++++++++++++++
1 file changed, 865 insertions(+)
create mode 100644 Notebooks/NB11__DataViz_Matplotlib & Seaborn_aluno.ipynb
diff --git a/Notebooks/NB11__DataViz_Matplotlib & Seaborn_aluno.ipynb b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_aluno.ipynb
new file mode 100644
index 000000000..8e2d66760
--- /dev/null
+++ b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_aluno.ipynb
@@ -0,0 +1,865 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Untitled31.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oRokSLxEMgDN"
+ },
+ "source": [
+ "## Referência\n",
+ "* [Visualization](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IFiAWdKnFS5A"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "\n",
+ "plt.rcParams[\"figure.figsize\"] = [15, 12]\n",
+ "%matplotlib inline"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UfrAHnWpJTwD"
+ },
+ "source": [
+ "## Séries temporais simples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_PV_kTGRMq4B"
+ },
+ "source": [
+ "#### Série/Dados simulados"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_yVTB9v0KQxp"
+ },
+ "source": [
+ "from datetime import datetime\n",
+ "\n",
+ "dt_hoje = datetime.strptime('2020-10-14', '%Y-%m-%d')\n",
+ "dt_inicio = datetime.strptime('2020-01-01', '%Y-%m-%d')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gMQx3JSlJz0R"
+ },
+ "source": [
+ "# Quantos dias desde a data inicial?\n",
+ "i_quantidade_dias = abs((dt_hoje - dt_inicio).days)\n",
+ "i_quantidade_dias"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Tb70ycS_JWvQ"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "i_qtd_ativos = 4\n",
+ "df_series_temporais = pd.DataFrame(np.random.randn(i_quantidade_dias, i_qtd_ativos), index = pd.date_range(dt_inicio, periods = i_quantidade_dias)) #, columns = list('ABCD'))\n",
+ "df_series_temporais.columns = ['Ativo1', 'Ativo2', 'Ativo3', 'Ativo4']\n",
+ "\n",
+ "#serie_temporal = pd.Series(np.random.randn(i_quantidade_dias), index = pd.date_range(dt_inicio, periods = i_quantidade_dias))\n",
+ "df_series_temporais.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hPq0XtirNMhm"
+ },
+ "source": [
+ "## Gráfico de séries temporais"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kEu3wDl9L92i"
+ },
+ "source": [
+ "df_series_temporais2 = df_series_temporais.cumsum()\n",
+ "plt.figure()\n",
+ "df_series_temporais2.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oEQQHUG8KtAv"
+ },
+ "source": [
+ "Gráfico de 1 única série temporal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xqNCkZdIKh3L"
+ },
+ "source": [
+ "df_series_temporais3 = df_series_temporais['Ativo1']\n",
+ "plt.figure()\n",
+ "df_series_temporais3.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m5rMpulVKrSe"
+ },
+ "source": [
+ "df_series_temporais3 = df_series_temporais['Ativo1'].cumsum()\n",
+ "plt.figure()\n",
+ "df_series_temporais3.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Wa4sXjcMNkzS"
+ },
+ "source": [
+ "Experimente kind = {'line', 'box', 'hist', 'kde'}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8eAETzNARsxo"
+ },
+ "source": [
+ "### Se quisermos comparar horizontalmente\n",
+ "* No caso abaixo, estou a comparar as colunas 'Ativo1', 'Ativo2', 'Ativo3' e 'Ativo4' quanto ao conteúdo da linha 3 --> iloc[3]."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6a0FB-SPReD9"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2.iloc[3].plot(kind ='bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ov7fKVO3So9v"
+ },
+ "source": [
+ "df_series_temporais2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rM32swu3S046"
+ },
+ "source": [
+ "df_series_temporais2.iloc[3]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qJ8SBoT6SSu0"
+ },
+ "source": [
+ "### Comparar grupos\n",
+ "* Neste caso, vou selecionar (ou dar um zoom) somente em alguns dias do dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kKeby_vwTB5j"
+ },
+ "source": [
+ "df_series_temporais2_zoom = df_series_temporais2[0:10]\n",
+ "df_series_temporais2_zoom"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I_XBwdn_Sa8h"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Zru6GuoYTuzd"
+ },
+ "source": [
+ "#### Outra forma de visualizar o mesmo resultado:\n",
+ "* stacked bar plot --> Basta usar o parâmetro stacked = True"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lHY7A1RLTzaT"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'bar', stacked = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UWP6hLn8US1M"
+ },
+ "source": [
+ "### Se quiser visualizar o gráfico na horizontal..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7dtzx-vOUWNG"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'barh', stacked = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IqAIybxdUbOH"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'barh', stacked = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Z22k7IOyU6la"
+ },
+ "source": [
+ "### Histogramas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LKLWYWYeU8UV"
+ },
+ "source": [
+ "df_series_temporais2.plot(kind = 'hist', bins = 100) # O que são bins?"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dG4zhQExVbY1"
+ },
+ "source": [
+ "#### Histograma individual"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZNGWjh9LVdb7"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2['Ativo3'].diff().hist() # Veja abaixo melhores explicações sobre o método diff(axis, periods) "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3LQlM_qjWd7g"
+ },
+ "source": [
+ "df_series_temporais2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "x3N6q_fTWl60"
+ },
+ "source": [
+ "df_series_temporais2.diff(axis = 0, periods= 1).head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LGknpyFaWqcZ"
+ },
+ "source": [
+ "df_series_temporais2.iloc[1][0] - df_series_temporais2.iloc[0][0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Yq6TtAU2XAHL"
+ },
+ "source": [
+ "#### diff(axis = 1, periods = 1) aplica a diferença nas colunas! Veja abaixo:\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6QRBLyBQXKq8"
+ },
+ "source": [
+ "df_series_temporais2.diff(axis = 1, periods = 1).head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "niDjEkSpYgAj"
+ },
+ "source": [
+ "### Histogramas em múltiplos gráficos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4ie8toFUYlF-"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2.diff(axis = 0, periods = 1).hist(color ='k', alpha = 0.5, bins = 50)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "r7W97FztGTMl"
+ },
+ "source": [
+ "## Boxplot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Q-19pTLZZKVj"
+ },
+ "source": [
+ "plt.figure()\n",
+ "boxplot = df_series_temporais2.boxplot(vert = True) # Observe o parâmetro vert = True"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aQ2qQetiGU8f"
+ },
+ "source": [
+ "plt.figure()\n",
+ "boxplot = df_series_temporais2.boxplot(vert = False) # Observe o parâmetro vert = False"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Wo6AFzOPMvMf"
+ },
+ "source": [
+ "#### Dados sobre a qualidade de vinhos - White vs Red\n",
+ "\n",
+ "* O objetivo é avaliar a qualidade dos vinhos (tinto vs branco), numa scala de 0–100. A seguir, a qualidade em função da escala:\n",
+ "\n",
+ "* 95–100 Classic: a great wine\n",
+ "* 90–94 Outstanding: a wine of superior character and style\n",
+ "* 85–89 Very good: a wine with special qualities\n",
+ "* 80–84 Good: a solid, well-made wine\n",
+ "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n",
+ "* 50–74 Not recommended"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aO9K8R9Qa9Uj"
+ },
+ "source": [
+ "url_tinto = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Wine_red.csv?token=AGDJQ64FIW7QA6DNJTVT6JC7SACV6'\n",
+ "url_branco = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Wine_white.csv?token=AGDJQ67RPQDN45RZYZHV5SK7SACXY'\n",
+ "df_vinho_tinto = pd.read_csv(url_tinto)\n",
+ "df_vinho_tinto[\"color\"] = 1 # --> Vinho Tinto\n",
+ "\n",
+ "df_vinho_branco = pd.read_csv(url_branco)\n",
+ "df_vinho_branco[\"color\"] = 0 # --> Vinho Branco"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "owdOjksbg7Dc"
+ },
+ "source": [
+ "df_vinhos = pd.concat([df_vinho_tinto, df_vinho_branco], axis = 0)\n",
+ "df_vinhos.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zYniNn5PfGx9"
+ },
+ "source": [
+ "df_vinho_tinto.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KL7iW5mtgCre"
+ },
+ "source": [
+ "df_vinhos['quality'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "G_yOZ-Gqmscv"
+ },
+ "source": [
+ "df_vinhos['color'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IKTEbTW2jMVv"
+ },
+ "source": [
+ "#### Tratamento do nome das colunas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1Oo-6k2jh3bx"
+ },
+ "source": [
+ "df_vinhos.columns = [col.lower() for col in df_vinhos.columns]\n",
+ "\n",
+ "# substituir ' ' por '_' no nome das colunas:\n",
+ "df_vinhos.columns = [col.replace(' ', '_') for col in df_vinhos.columns]\n",
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eiMHK6aJjoZl"
+ },
+ "source": [
+ "df_vinhos.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sUNEzoC7j0PV"
+ },
+ "source": [
+ "print(f\"Média do vinho Branco: {df_vinho_branco['quality'].mean()}\")\n",
+ "print(f\"Média do vinho Tinto.: {df_vinho_tinto['quality'].mean()}\")\n",
+ "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tIBDUBI4n78b"
+ },
+ "source": [
+ "Abaixo, o mesmo cálculo, porém usando o artificio de procurar/selecionar o tipo que queremos no dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "X1Nllwpxl228"
+ },
+ "source": [
+ "print(f\"Média do vinho Branco: {df_vinhos[df_vinhos['color'] == 0]['quality'].mean()}\")\n",
+ "print(f\"Média do vinho Tinto.: {df_vinhos[df_vinhos['color'] == 1]['quality'].mean()}\")\n",
+ "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GHjfSmExmg0u"
+ },
+ "source": [
+ "df_vinhos.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J3ZsHlrWmLDQ"
+ },
+ "source": [
+ "df_vinhos[df_vinhos['color'] == 1]['quality']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7HjKZ6Z1bkct"
+ },
+ "source": [
+ "A seguir, algo mais sofisticado, contendo título do gráfico, annotations e etc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jB9BTwBOa7UA"
+ },
+ "source": [
+ "fig, ax = plt.subplots(figsize=(10, 6))\n",
+ "df_vinhos['quality'].value_counts().plot(kind = 'bar')\n",
+ "\n",
+ "# Título e label dos eixos X e Y\n",
+ "plt.title('Avaliação da qualidade do vinho', fontsize = 25)\n",
+ "plt.xlabel('Atributo: quality', fontsize = 10)\n",
+ "plt.ylabel('Quantidade', fontsize = 10)\n",
+ "\n",
+ "# Colocar grid no gráfico\n",
+ "ax.grid(True)\n",
+ "\n",
+ "# Configurar a legenda\n",
+ "plt.legend()\n",
+ "\n",
+ "# Configurar limites do eixo Y\n",
+ "plt.ylim(0, 3000)\n",
+ "\n",
+ "# Configurar limites do eixo X\n",
+ "#plt.xlim(0, 3000)\n",
+ " \n",
+ "# Show graphic\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "w1CyCXVkmrFV"
+ },
+ "source": [
+ "df_vinhos['color'].value_counts().plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jU1AY-_wpU2h"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e0ayzbRanNDq"
+ },
+ "source": [
+ "df_vinhos['fixed_acidity'].value_counts().sort_index().plot(kind = 'area')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RjzkMuPTn0yI"
+ },
+ "source": [
+ "#geração de vários gráficos \n",
+ "l_colunas = ['fixed_acidity', 'volatile_acidity', 'citric_acid', 'residual_sugar', 'chlorides', 'free_sulfur_dioxide', 'total_sulfur_dioxide', 'density', 'ph', 'sulphates', 'alcohol']\n",
+ "for caracteristica in l_colunas:\n",
+ " plt.figure() # Tire esta linha e veja o resultado\n",
+ " df_vinhos[caracteristica].value_counts().sort_index().plot(kind = 'area')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PYIjyMkVnWnr"
+ },
+ "source": [
+ "### Correlações"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IOCk4vhpnYn9"
+ },
+ "source": [
+ "correlacoes = df_vinhos.corr()\n",
+ "\n",
+ "top_correlacoes_cols = correlacoes.color.sort_values(ascending=False).keys()\n",
+ "top_correlacoes = correlacoes.loc[top_correlacoes_cols, top_correlacoes_cols]\n",
+ "dropSelf = np.zeros_like(top_correlacoes)\n",
+ "dropSelf[np.triu_indices_from(dropSelf)] = True\n",
+ "plt.figure(figsize=(18, 10))\n",
+ "sns.heatmap(top_correlacoes, cmap=sns.diverging_palette(220, 10, as_cmap=True), annot=True, fmt=\".2f\", mask=dropSelf)\n",
+ "sns.set(font_scale=1.5)\n",
+ "plt.show()\n",
+ "del correlacoes, dropSelf, top_correlacoes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SFqklDJf-8le"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "H7hKbxfdBV8w"
+ },
+ "source": [
+ "### Avaliar o comportamento bivariado ou a relação entre a variável-target e a variável preditora"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LllKqLx3_IIG"
+ },
+ "source": [
+ "sns.jointplot(df_vinhos['alcohol'], df_vinhos['fixed_acidity'], kind = \"kde\")\n",
+ "plt.savefig('minha_figura.png')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4ixcDmeXIFQ1"
+ },
+ "source": [
+ "### Pairplot\n",
+ "* Verificar relacionamentos entre pares no dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lWqwaZ_lArji"
+ },
+ "source": [
+ "#sns.pairplot(df_vinhos, hue = \"color\") # Compare os gráficos com e sem a opção hue\n",
+ "sns.pairplot(df_vinhos)\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vtOH-mTHLGC-"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dcaQ8aPaHwBB"
+ },
+ "source": [
+ "sns.lmplot(\"alcohol\", \"sulphates\", df_vinhos, hue = \"color\", fit_reg = False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pWsCs585LPyn"
+ },
+ "source": [
+ "sns.lmplot(\"alcohol\", \"sulphates\", df_vinhos, hue = \"quality\", fit_reg = False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5RwOiYi3OfD5"
+ },
+ "source": [
+ "### Boxplot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZqIP5xUOMAqL"
+ },
+ "source": [
+ "df_vinhos.boxplot(column = 'alcohol', by = 'quality', figsize = (12, 8))\n",
+ "plt.xlabel('Quality', fontsize = 10, color= 'blue')\n",
+ "plt.ylabel('alcohol', fontsize = 10, color= 'blue')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From ca6697322dbfac2596b1142734ca3aa3ea3f6cd4 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Thu, 15 Oct 2020 16:15:57 -0300
Subject: [PATCH 05/21] Criado usando o Colaboratory
---
...1__DataViz_Matplotlib & Seaborn_Fifa.ipynb | 1360 +++++++++++++++++
1 file changed, 1360 insertions(+)
create mode 100644 Notebooks/NB11__DataViz_Matplotlib & Seaborn_Fifa.ipynb
diff --git a/Notebooks/NB11__DataViz_Matplotlib & Seaborn_Fifa.ipynb b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_Fifa.ipynb
new file mode 100644
index 000000000..afae826b7
--- /dev/null
+++ b/Notebooks/NB11__DataViz_Matplotlib & Seaborn_Fifa.ipynb
@@ -0,0 +1,1360 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Untitled31.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oRokSLxEMgDN"
+ },
+ "source": [
+ "## Referência\n",
+ "* [Visualization](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html)\n",
+ "* [Python Graph Galery](https://python-graph-gallery.com/all-charts/)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IFiAWdKnFS5A"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import bokeh # Library necessária ***\n",
+ "\n",
+ "plt.rcParams[\"figure.figsize\"] = [15, 12]\n",
+ "%matplotlib inline"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UfrAHnWpJTwD"
+ },
+ "source": [
+ "## Séries temporais simples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_PV_kTGRMq4B"
+ },
+ "source": [
+ "#### Série/Dados simulados"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_yVTB9v0KQxp"
+ },
+ "source": [
+ "from datetime import datetime\n",
+ "\n",
+ "dt_hoje = datetime.strptime('2020-10-14', '%Y-%m-%d')\n",
+ "dt_inicio = datetime.strptime('2020-01-01', '%Y-%m-%d')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gMQx3JSlJz0R"
+ },
+ "source": [
+ "# Quantos dias desde a data inicial?\n",
+ "i_quantidade_dias = abs((dt_hoje - dt_inicio).days)\n",
+ "i_quantidade_dias"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Tb70ycS_JWvQ"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "i_qtd_ativos = 4\n",
+ "df_series_temporais = pd.DataFrame(np.random.randn(i_quantidade_dias, i_qtd_ativos), index = pd.date_range(dt_inicio, periods = i_quantidade_dias)) #, columns = list('ABCD'))\n",
+ "df_series_temporais.columns = ['Ativo1', 'Ativo2', 'Ativo3', 'Ativo4']\n",
+ "\n",
+ "#serie_temporal = pd.Series(np.random.randn(i_quantidade_dias), index = pd.date_range(dt_inicio, periods = i_quantidade_dias))\n",
+ "df_series_temporais.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hPq0XtirNMhm"
+ },
+ "source": [
+ "## Gráfico de séries temporais"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kEu3wDl9L92i"
+ },
+ "source": [
+ "df_series_temporais2 = df_series_temporais.cumsum()\n",
+ "plt.figure()\n",
+ "df_series_temporais2.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oEQQHUG8KtAv"
+ },
+ "source": [
+ "Gráfico de 1 única série temporal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xqNCkZdIKh3L"
+ },
+ "source": [
+ "df_series_temporais3 = df_series_temporais['Ativo1']\n",
+ "plt.figure()\n",
+ "df_series_temporais3.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m5rMpulVKrSe"
+ },
+ "source": [
+ "df_series_temporais3 = df_series_temporais['Ativo1'].cumsum()\n",
+ "plt.figure()\n",
+ "df_series_temporais3.plot(kind = 'line')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Wa4sXjcMNkzS"
+ },
+ "source": [
+ "Experimente kind = {'line', 'box', 'hist', 'kde'}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8eAETzNARsxo"
+ },
+ "source": [
+ "### Se quisermos comparar horizontalmente\n",
+ "* No caso abaixo, estou a comparar as colunas 'Ativo1', 'Ativo2', 'Ativo3' e 'Ativo4' quanto ao conteúdo da linha 3 --> iloc[3]."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "APnKHRMSbYMO"
+ },
+ "source": [
+ "df_series_temporais2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6a0FB-SPReD9"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2.iloc[3].plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qJ8SBoT6SSu0"
+ },
+ "source": [
+ "### Comparar grupos\n",
+ "* Neste caso, vou selecionar (ou dar um zoom) somente em alguns dias do dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kKeby_vwTB5j"
+ },
+ "source": [
+ "df_series_temporais2_zoom = df_series_temporais2[0:10]\n",
+ "df_series_temporais2_zoom"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I_XBwdn_Sa8h"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Zru6GuoYTuzd"
+ },
+ "source": [
+ "#### Outra forma de visualizar o mesmo resultado:\n",
+ "* stacked bar plot --> Basta usar o parâmetro stacked = True"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lHY7A1RLTzaT"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'bar', stacked = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UWP6hLn8US1M"
+ },
+ "source": [
+ "### Se quiser visualizar o gráfico na horizontal..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7dtzx-vOUWNG"
+ },
+ "source": [
+ "df_series_temporais2_zoom.plot(kind = 'barh', stacked = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Z22k7IOyU6la"
+ },
+ "source": [
+ "### Histogramas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LKLWYWYeU8UV"
+ },
+ "source": [
+ "df_series_temporais2.plot(kind = 'hist', bins = 10) # O que são bins?"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MjLO8BqUeQvP"
+ },
+ "source": [
+ "#### O que são bins?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dG4zhQExVbY1"
+ },
+ "source": [
+ "#### Histograma individual"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZNGWjh9LVdb7"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2['Ativo3'].diff().hist() # Veja abaixo melhores explicações sobre o método diff(axis, periods) "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3LQlM_qjWd7g"
+ },
+ "source": [
+ "df_series_temporais2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "x3N6q_fTWl60"
+ },
+ "source": [
+ "df_series_temporais2.diff(axis = 0, periods = 1).head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LGknpyFaWqcZ"
+ },
+ "source": [
+ "df_series_temporais2.iloc[1][0] - df_series_temporais2.iloc[0][0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TdjsYr4Wer73"
+ },
+ "source": [
+ "df_series_temporais2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Yq6TtAU2XAHL"
+ },
+ "source": [
+ "#### diff(axis = 1, periods = 1) aplica a diferença nas colunas! Veja abaixo:\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6QRBLyBQXKq8"
+ },
+ "source": [
+ "df_series_temporais2.diff(axis = 1, periods = 1).head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "niDjEkSpYgAj"
+ },
+ "source": [
+ "### Histogramas em múltiplos gráficos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4ie8toFUYlF-"
+ },
+ "source": [
+ "plt.figure()\n",
+ "df_series_temporais2.diff(axis = 0, periods = 1).hist(color ='k', alpha = 0.5, bins = 50)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "r7W97FztGTMl"
+ },
+ "source": [
+ "## Boxplot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Q-19pTLZZKVj"
+ },
+ "source": [
+ "plt.figure()\n",
+ "boxplot = df_series_temporais2.boxplot(vert = True) # Observe o parâmetro vert = True"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aQ2qQetiGU8f"
+ },
+ "source": [
+ "plt.figure()\n",
+ "boxplot = df_series_temporais2.boxplot(vert = False) # Observe o parâmetro vert = False"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Wo6AFzOPMvMf"
+ },
+ "source": [
+ "#### Dados sobre a qualidade de vinhos - White vs Red\n",
+ "\n",
+ "* O objetivo é avaliar a qualidade dos vinhos (tinto vs branco), numa scala de 0–100. A seguir, a qualidade em função da escala:\n",
+ "\n",
+ "* 95–100 Classic: a great wine\n",
+ "* 90–94 Outstanding: a wine of superior character and style\n",
+ "* 85–89 Very good: a wine with special qualities\n",
+ "* 80–84 Good: a solid, well-made wine\n",
+ "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n",
+ "* 50–74 Not recommended"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aO9K8R9Qa9Uj"
+ },
+ "source": [
+ "url_tinto = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Wine_red.csv?token=AGDJQ64FIW7QA6DNJTVT6JC7SACV6'\n",
+ "url_branco = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Wine_white.csv?token=AGDJQ67RPQDN45RZYZHV5SK7SACXY'\n",
+ "df_vinho_tinto = pd.read_csv(url_tinto)\n",
+ "df_vinho_tinto[\"color\"] = 1 # --> Vinho Tinto\n",
+ "\n",
+ "df_vinho_branco = pd.read_csv(url_branco)\n",
+ "df_vinho_branco[\"color\"] = 0 # --> Vinho Branco"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "owdOjksbg7Dc"
+ },
+ "source": [
+ "# Empilhando os dataframes df_vinho_tinto e df_vinho_branco:\n",
+ "df_vinhos = pd.concat([df_vinho_tinto, df_vinho_branco], axis = 0)\n",
+ "df_vinhos.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zYniNn5PfGx9"
+ },
+ "source": [
+ "df_vinho_tinto.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KL7iW5mtgCre"
+ },
+ "source": [
+ "df_vinhos['quality'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "G_yOZ-Gqmscv"
+ },
+ "source": [
+ "df_vinhos['color'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IKTEbTW2jMVv"
+ },
+ "source": [
+ "#### Tratamento do nome das colunas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JeXjuKNIm39F"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1Oo-6k2jh3bx"
+ },
+ "source": [
+ "df_vinhos.columns = [col.lower() for col in df_vinhos.columns]\n",
+ "\n",
+ "# substituir ' ' por '_' no nome das colunas:\n",
+ "df_vinhos.columns = [col.replace(' ', '_') for col in df_vinhos.columns]\n",
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eiMHK6aJjoZl"
+ },
+ "source": [
+ "df_vinhos.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sUNEzoC7j0PV"
+ },
+ "source": [
+ "print(f\"Média do vinho Branco: {df_vinho_branco['quality'].mean()}\")\n",
+ "print(f\"Média do vinho Tinto.: {df_vinho_tinto['quality'].mean()}\")\n",
+ "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tIBDUBI4n78b"
+ },
+ "source": [
+ "Abaixo, o mesmo cálculo, porém usando o artificio de procurar/selecionar o tipo que queremos no dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "X1Nllwpxl228"
+ },
+ "source": [
+ "print(f\"Média do vinho Branco: {df_vinhos[df_vinhos['color'] == 0]['quality'].mean()}\")\n",
+ "print(f\"Média do vinho Tinto.: {df_vinhos[df_vinhos['color'] == 1]['quality'].mean()}\")\n",
+ "print(f\"Média Geral..........: {df_vinhos['quality'].mean()}\")"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GHjfSmExmg0u"
+ },
+ "source": [
+ "df_vinhos.columns"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J3ZsHlrWmLDQ"
+ },
+ "source": [
+ "df_vinhos[df_vinhos['color'] == 1]['quality']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "a-4XRBelnKCW"
+ },
+ "source": [
+ "fig, ax = plt.subplots(figsize=(10, 6))\n",
+ "df_vinhos['quality'].value_counts().plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7HjKZ6Z1bkct"
+ },
+ "source": [
+ "A seguir, algo mais sofisticado, contendo título do gráfico, annotations e etc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jB9BTwBOa7UA"
+ },
+ "source": [
+ "fig, ax = plt.subplots(figsize = (10, 6))\n",
+ "df_vinhos['quality'].value_counts().plot(kind = 'bar')\n",
+ "\n",
+ "# Título e label dos eixos X e Y\n",
+ "plt.title('Avaliação da qualidade do vinho', fontsize = 25)\n",
+ "plt.xlabel('Atributo: quality', fontsize = 10)\n",
+ "plt.ylabel('Quantidade', fontsize = 10)\n",
+ "\n",
+ "# Colocar grid no gráfico\n",
+ "ax.grid(True)\n",
+ "\n",
+ "# Configurar a legenda\n",
+ "#plt.legend()\n",
+ "\n",
+ "# Configurar limites do eixo Y\n",
+ "#plt.ylim(0, 5000)\n",
+ "\n",
+ "# Configurar limites do eixo X\n",
+ "#plt.xlim(0, 3000)\n",
+ " \n",
+ "# Show graphic\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "w1CyCXVkmrFV"
+ },
+ "source": [
+ "df_vinhos['color'].value_counts().plot(kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jU1AY-_wpU2h"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e0ayzbRanNDq"
+ },
+ "source": [
+ "df_vinhos['fixed_acidity'].value_counts().sort_index().plot(kind = 'area')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eSxvaczjoll-"
+ },
+ "source": [
+ "### Desafio: Tornar o gráfico abaixo mais informativo\n",
+ "* Por exemplo, mostrar qual a variável analisada, eixo X e Y, títulos e etc."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RjzkMuPTn0yI"
+ },
+ "source": [
+ "l_colunas = df_vinhos.columns # automatizando\n",
+ "for caracteristica in l_colunas:\n",
+ " plt.figure() # Tire esta linha e veja o resultado\n",
+ " df_vinhos[caracteristica].value_counts().sort_index().plot(kind = 'area')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PYIjyMkVnWnr"
+ },
+ "source": [
+ "### Correlações"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gn7xXclM7ewN"
+ },
+ "source": [
+ "### Introdução\n",
+ "O código abaixo gera dataframes para avaliarmos as correlações entre variáveis/dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4un3dsyZ7fFU"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "i_simulacoes = 5000\n",
+ "\n",
+ "# Definir a semente --> Reproducibilidade\n",
+ "np.random.seed(19741120)\n",
+ "\n",
+ "# Array de médias das amostras:\n",
+ "a_media = np.array([0.0, 5.0, 10.0])\n",
+ "\n",
+ "# Array com a matriz de covariância:\n",
+ "a_covariancia = np.array([\n",
+ " [ 3.40, -2.75, -2.00],\n",
+ " [ -2.75, 5.50, 1.50],\n",
+ " [ -2.00, 1.50, 1.25]\n",
+ " ])\n",
+ "\n",
+ "# Geração das amostras aleatórias usando f_media e eGenerate the random samples.\n",
+ "a_amostras = np.random.multivariate_normal(a_media, a_covariancia, size = i_simulacoes)\n",
+ "a_amostras"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "akHw3Mym_FgQ"
+ },
+ "source": [
+ "A seguir, gráfico que mostra a correlação entre a_amostras[:, 0] e a_amostras[:, 1]:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iTLIn1uwJoVi"
+ },
+ "source": [
+ "plt.figure(figsize= (12, 8))\n",
+ "ax = sns.regplot(x = a_amostras[:,0], y = a_amostras[:,1], color = 'g')\n",
+ "plt.xlabel('a_amostras[0]')\n",
+ "plt.ylabel('a_amostras[1]')\n",
+ "#plt.axis('equal')\n",
+ "plt.grid(True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JcermWt-Ar5c"
+ },
+ "source": [
+ "np.corrcoef(a_amostras[:, 0], a_amostras[:, 1])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ryLXMQ66_fce"
+ },
+ "source": [
+ "Gráfico da correlação entre a_amostras[:, 0] e a_amostras[:, 2]:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8Xp69Xgg9iRV"
+ },
+ "source": [
+ "plt.figure(figsize= (12, 8))\n",
+ "ax = sns.regplot(x = a_amostras[:,0], y = a_amostras[:,2], color = 'g')\n",
+ "plt.xlabel('a_amostras[0]')\n",
+ "plt.ylabel('a_amostras[2]')\n",
+ "#plt.axis('equal')\n",
+ "plt.grid(True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Gw6OpxFBA5Sp"
+ },
+ "source": [
+ "np.corrcoef(a_amostras[:, 0], a_amostras[:, 2])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GmnKTqxQ_uZ9"
+ },
+ "source": [
+ "E por fim, gráfico com as correlações entre a_amostras[:, 1] e a_amostras[:, 2]:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yjWoFPhR_t3I"
+ },
+ "source": [
+ "plt.figure(figsize= (12, 8))\n",
+ "ax = sns.regplot(x = a_amostras[:, 1], y = a_amostras[:, 2], color = 'g')\n",
+ "plt.xlabel('a_amostras[1]')\n",
+ "plt.ylabel('a_amostras[2]')\n",
+ "#plt.axis('equal')\n",
+ "plt.grid(True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xnJkxZ25C7kX"
+ },
+ "source": [
+ "np.corrcoef(a_amostras[:, 1], a_amostras[:, 2])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qEttRQwgDGq_"
+ },
+ "source": [
+ "E a seguir, o pairplot para avaliarmos todas as colunas ao mesmo tempo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mkAJivoPC_OM"
+ },
+ "source": [
+ "sns.pairplot(pd.DataFrame(a_amostras))\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6FVQwuNP8w6s"
+ },
+ "source": [
+ "### Análise do dataframe df_vinhos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N-Aa8wnh6rky"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZhtIILrs6vUT"
+ },
+ "source": [
+ "### Correlações entre um par de variáveis X e Y"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lJh2Comx6a_k"
+ },
+ "source": [
+ "np.corrcoef(df_vinhos['fixed_acidity'], df_vinhos['alcohol'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ifZybEAE68V9"
+ },
+ "source": [
+ "### Correlações do dataframe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IOCk4vhpnYn9"
+ },
+ "source": [
+ "correlacoes = df_vinhos.corr()\n",
+ "\n",
+ "top_correlacoes_cols = correlacoes.color.sort_values(ascending = False).keys()\n",
+ "top_correlacoes = correlacoes.loc[top_correlacoes_cols, top_correlacoes_cols]\n",
+ "dropSelf = np.zeros_like(top_correlacoes)\n",
+ "dropSelf[np.triu_indices_from(dropSelf)] = True\n",
+ "plt.figure(figsize = (15, 9))\n",
+ "sns.heatmap(top_correlacoes, cmap=sns.diverging_palette(220, 10, as_cmap = True), annot = True, fmt = \".2f\", mask = dropSelf)\n",
+ "sns.set(font_scale=1.5)\n",
+ "plt.show()\n",
+ "del correlacoes, dropSelf, top_correlacoes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SFqklDJf-8le"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "H7hKbxfdBV8w"
+ },
+ "source": [
+ "### Avaliar o comportamento bivariado\n",
+ "* 2D Density Plot\n",
+ " * Útil para avaliarmos a relação entre 2 variáveis numéricas. O gráfico no centro mostra a correlação entre as variáveis enquanto os gráficos marginais mostra a distribuição das respectivas variáveis usando histogramas ou gráficos de densidade."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LllKqLx3_IIG"
+ },
+ "source": [
+ "sns.jointplot(x = df_vinhos['alcohol'], y = df_vinhos['density'], kind = \"scatter\", color = 'm', s=50, edgecolor = \"skyblue\", linewidth = 2)\n",
+ "plt.savefig('minha_figura.png')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "33yTNYN2K40X"
+ },
+ "source": [
+ "Mesmos dados, gráfico diferente --> Explorem as opções disponíveis: https://python-graph-gallery.com/82-marginal-plot-with-seaborn/"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BVmAt0wCK1Ob"
+ },
+ "source": [
+ "sns.jointplot(x = df_vinhos['alcohol'], y = df_vinhos['density'], kind = \"reg\", color = 'm', )\n",
+ "plt.savefig('minha_figura.png')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4ixcDmeXIFQ1"
+ },
+ "source": [
+ "### Pairplot\n",
+ "* Verificar relacionamentos entre pares no dataframe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lWqwaZ_lArji"
+ },
+ "source": [
+ "sns.pairplot(df_vinhos)\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vAhaEgyYtfX9"
+ },
+ "source": [
+ "Abaixo, gráfico segmentado por color:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jnu-giD_tcwd"
+ },
+ "source": [
+ "sns.pairplot(df_vinhos, hue = \"color\") # Compare os gráficos com e sem a opção hue\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vtOH-mTHLGC-"
+ },
+ "source": [
+ "df_vinhos.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dcaQ8aPaHwBB"
+ },
+ "source": [
+ "sns.lmplot(\"alcohol\", \"density\", df_vinhos, hue = \"color\", fit_reg = False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pWsCs585LPyn"
+ },
+ "source": [
+ "sns.lmplot(\"alcohol\", \"density\", df_vinhos, hue = \"quality\", fit_reg = False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5RwOiYi3OfD5"
+ },
+ "source": [
+ "### Boxplot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZqIP5xUOMAqL"
+ },
+ "source": [
+ "df_vinhos.boxplot(column = 'alcohol', by = 'quality', figsize = (12, 8))\n",
+ "plt.xlabel('Quality', fontsize = 10, color= 'blue')\n",
+ "plt.ylabel('alcohol', fontsize = 10, color= 'blue')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lWypAe78YQNm"
+ },
+ "source": [
+ "## Exercícios"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YD8jgEZyYSHP"
+ },
+ "source": [
+ "### Exercício 1\n",
+ "* Análise gráfica das variáveis do dataframe IRIS.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "h0F7uXixYVqx"
+ },
+ "source": [
+ "from sklearn.datasets import load_iris\n",
+ "\n",
+ "iris = load_iris()\n",
+ "X= iris['data']\n",
+ "y= iris['target']\n",
+ "\n",
+ "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n",
+ "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n",
+ "df_iris.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yV5gDSF1YdGL"
+ },
+ "source": [
+ "### Exercício 2\n",
+ "* Usando o dataframe FIFA, responda:\n",
+ " * (1) Mostre o gráfico de barras com o número de jogadores por clube;\n",
+ " * (2) Mostre o boxplot/histograma dos salários dos atletas para os clubes Real Madrid, Barcelona Paris Saint-Germain Bayern Munich e Juventus."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "27NbnlDkYoeH"
+ },
+ "source": [
+ "# Carrega a library Pandas\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "E3EVKJFRjiyA"
+ },
+ "source": [
+ "#configuração\n",
+ "d_configuracao = {\n",
+ " 'display.max_columns': 1000,\n",
+ " 'display.expand_frame_repr': True,\n",
+ " 'display.max_rows': 10,\n",
+ " 'display.precision': 2,\n",
+ " 'display.show_dimensions': True\n",
+ " }\n",
+ "\n",
+ "for op, value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r5K0504rjmum"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/Celso-Omoto/DSWP/master/Dataframes/FIFA.csv'\n",
+ "df_Fifa2018 = pd.read_csv(url)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_H9fgfk_lOIv"
+ },
+ "source": [
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zer-di19l3tf"
+ },
+ "source": [
+ "from sklearn.datasets import load_iris\n",
+ "\n",
+ "iris = load_iris()\n",
+ "X= iris['data']\n",
+ "y= iris['target']\n",
+ "\n",
+ "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n",
+ "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n",
+ "df_iris.head()\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oNMpCMIUnJAA"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df_Fifa2018.columns = [col.lower() for col in df.columns]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gHxJ5xlFnLiV"
+ },
+ "source": [
+ "transformacao_lower(df_Fifa2018)\n",
+ "df_Fifa2018.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bykPdka9jukN"
+ },
+ "source": [
+ "df_Fifa2018[['club', 'name','value']]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0zZTRJo6lYAU"
+ },
+ "source": [
+ "df_conta_jogadores = df_Fifa2018[['club', 'name','value']]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HwTYS2FmqOJP"
+ },
+ "source": [
+ "#faz gráfico do Fifa, totalizando jogadores por clue\n",
+ "df_conta_jogadores['club'].value_counts().sort_values().plot(xlabel = 'Clube',ylabel = 'Quant',kind = 'bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kkpO458zq-dG"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From d0d7604777e3aaf055849d3e22d384d118d80103 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Thu, 15 Oct 2020 16:24:48 -0300
Subject: [PATCH 06/21] Criado usando o Colaboratory
---
Notebooks/NB10_01__Pandas_Fifa.ipynb | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Notebooks/NB10_01__Pandas_Fifa.ipynb b/Notebooks/NB10_01__Pandas_Fifa.ipynb
index 073a7477f..e3813afea 100644
--- a/Notebooks/NB10_01__Pandas_Fifa.ipynb
+++ b/Notebooks/NB10_01__Pandas_Fifa.ipynb
@@ -5484,7 +5484,10 @@
"id": "FCs2gPK8ckS7"
},
"source": [
- "\n"
+ "#df_estudantes['percentagem'] = 100*(df_estudantes['score']/sum(df_estudantes['score']))\n",
+ "#lista\n",
+ "#df_Fifa2018['salario'] = df_Fifa2018['value']*.str.split('/w', n = 2, expand = True) \n",
+ "#df_Fifa2018\n"
],
"execution_count": null,
"outputs": []
From 462124c2de270ef80b97fbd799b4e3337eb86fb5 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Fri, 16 Oct 2020 09:47:40 -0300
Subject: [PATCH 07/21] Criado usando o Colaboratory
---
.../NB02__Numpy_exercicio_resolvido.ipynb | 8418 +++++++++++++++++
1 file changed, 8418 insertions(+)
create mode 100644 Notebooks/NB02__Numpy_exercicio_resolvido.ipynb
diff --git a/Notebooks/NB02__Numpy_exercicio_resolvido.ipynb b/Notebooks/NB02__Numpy_exercicio_resolvido.ipynb
new file mode 100644
index 000000000..f6fa37aea
--- /dev/null
+++ b/Notebooks/NB02__Numpy_exercicio_resolvido.ipynb
@@ -0,0 +1,8418 @@
+{
+ "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": [
+ "
"
+ ]
+ },
+ {
+ "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": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0mKvExmgUFOk"
+ },
+ "source": [
+ "# **ESCALAR, VETORES, MATRIZES E TENSORES**\n",
+ "\n",
+ "\n",
+ "\n",
+ "Source: [PyTorch for Deep Learning: A Quick Guide for Starters](https://towardsdatascience.com/pytorch-for-deep-learning-a-quick-guide-for-starters-5b60d2dbb564)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o00pYRIkXiAU"
+ },
+ "source": [
+ "## Import Statement - Primeiros exemplos\n",
+ "> Como exemplo, considere gerar uma amostra aleatória de tamanho 10 da Distribuição Normal(0, 1):"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "l_XuvcUDWNDk"
+ },
+ "source": [
+ "## Importar a library NumPy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "am_ZTIGaapCo"
+ },
+ "source": [
+ "### **Opção 1**: Importar a biblioteca NumPy COM alias"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "b4irLw6BWVVZ"
+ },
+ "source": [
+ "import numpy as np"
+ ],
+ "execution_count": 2,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JK54ga7dXnJu",
+ "outputId": "e87ad67b-79c4-4ec8-ce74-cbb12851720a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Set up o número de casas decimais para o NumPy:\n",
+ "np.set_printoptions(precision = 2, suppress = True)\n",
+ "\n",
+ "'''\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": 3,
+ "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": 3
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7GfmDF43NrHd",
+ "outputId": "a193bbbd-7711-428a-bc72-0f12801050c1",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_tab=np.random.normal(8,1,size=(3,10))\n",
+ "a_tab"
+ ],
+ "execution_count": 12,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[8.74, 8.18, 8.1 , 7.22, 7.96, 9.67, 6.93, 7.45, 6.17, 8.12],\n",
+ " [9.39, 7.71, 8.32, 7.3 , 7.56, 5.97, 7.86, 9.66, 7.42, 7.21],\n",
+ " [7.19, 8.06, 8.87, 7.65, 9.37, 8.88, 6.52, 7.59, 7.81, 8.47]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 12
+ }
+ ]
+ },
+ {
+ "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": 14,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zFYH6J5-Ydjl",
+ "outputId": "0f5ae787-4691-4e29-edb0-5912ae39d0e9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "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": 15,
+ "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": 15
+ }
+ ]
+ },
+ {
+ "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": 16,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Xj6fbpvubH_p",
+ "outputId": "00836057-014f-44c7-a6ae-f41895de17cc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Set up o número de casas decimais para o NumPy:\n",
+ "set_printoptions(precision = 2, suppress = True)\n",
+ "\n",
+ "'''\n",
+ "Define seed por questões de reproducibilidade, ou seja, \n",
+ "garante que todos vamos gerar os mesmos números aleatórios\n",
+ "'''\n",
+ "seed(seed = 20111974)\n",
+ "\n",
+ "# Gera 10 números aleatórios a partir da Distribuição Normal(mu, desvio_padrao)\n",
+ "media = 0\n",
+ "desvio_padrao = 1 \n",
+ "np.random.normal(size = 10)"
+ ],
+ "execution_count": 17,
+ "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": 17
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "00RerJPChnuP"
+ },
+ "source": [
+ "___\n",
+ "# **Estatísticas Descriticas com NumPy**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Qa6ro1VJlShd"
+ },
+ "source": [
+ "## Exemplo 1\n",
+ "> Vamos voltar ao mesmo exemplo anterior, mas desta vez, usando a opção 1 (com alias):\n",
+ "\n",
+ "* Gerar uma amostra aleatória de tamanho 10 da Distribuiçao Normal(0, 1)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "31dSBU8khvFk",
+ "outputId": "14d42b6f-1a70-4d38-b84a-7cf71e5a8a44",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Set up o número de casas decimais para o NumPy:\n",
+ "np.set_printoptions(precision = 2, suppress = True)\n",
+ "\n",
+ "# Define seed\n",
+ "np.random.seed(seed = 20111974)\n",
+ "\n",
+ "# Gera 10 números aleatórios a partir da Distribuição Normal(media, desvio_padrao)\n",
+ "media = 0\n",
+ "desvio_padrao = 1\n",
+ "\n",
+ "np.random\n",
+ "a_conjunto1 = np.random.normal(media, desvio_padrao, size = 10) # Array 1D de size = 10\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 18,
+ "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": 18
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wa2t0P3nevTh"
+ },
+ "source": [
+ "Conferindo a média e desvio-padrão do array gerado:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "drUyk3f5ekDq",
+ "outputId": "f12428fe-0c82-4595-f725-20b02a1c9138",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'Distribuição N({np.mean(a_conjunto1)}, {np.std(a_conjunto1)})'"
+ ],
+ "execution_count": 19,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Distribuição N(1.1043374540652753, 0.735246705657231)'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 19
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HUIlWDMsPFfG",
+ "outputId": "a1a90dc8-a74e-4c9b-d29f-6d77fb6001f7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "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",
+ "i_size = 100\n",
+ "\n",
+ "np.random\n",
+ "a_conjunto1 = np.random.normal(media, desvio_padrao, size = i_size) # Array 1D de size = 10\n",
+ "f'Distribuição : número de elementos: {i_size} / Média {np.mean(a_conjunto1)} / DP {np.std(a_conjunto1)})'"
+ ],
+ "execution_count": 26,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Distribuição : número de elementos: 100 / Média -0.016996335492713833 / DP 1.0055613764417128)'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 26
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wfhWpOtjPogD",
+ "outputId": "d74b48e4-0fca-4cdf-efc8-a3fc2152dff7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "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",
+ "a_elementos = [10,100,1000,10000,100000]\n",
+ "\n",
+ "for i_size in a_elementos:\n",
+ " a_conjunto1 = np.random.normal(media, desvio_padrao, size = i_size) # Array 1D de size = 10\n",
+ " print(f'Distribuição : número de elementos: {i_size} / Média {np.mean(a_conjunto1)} / DP {np.std(a_conjunto1)})')"
+ ],
+ "execution_count": 30,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Distribuição : número de elementos: 10 / Média 1.1043374540652753 / DP 0.735246705657231)\n",
+ "Distribuição : número de elementos: 100 / Média -0.14020525697186714 / DP 0.9254100654233511)\n",
+ "Distribuição : número de elementos: 1000 / Média 0.021644923462910873 / DP 1.0054417533501039)\n",
+ "Distribuição : número de elementos: 10000 / Média 0.015499353804764507 / DP 0.9970905566844254)\n",
+ "Distribuição : número de elementos: 100000 / Média 0.002039323041103302 / DP 0.9960906293570095)\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XSp7Hd-Gib67"
+ },
+ "source": [
+ "Estávamos à espera de media = 0 e sigma = 1. Certo? Porque isso não aconteceu?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HP_8VSgygXOF"
+ },
+ "source": [
+ "## **Laboratório 1**\n",
+ "> Altere os valores de [size] para 100, 1.000, 10.000, 100.000 e 1.000.000 e relate o que acontece com a média e desvio padrão."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4TbmVbdcg6iU"
+ },
+ "source": [
+ "## **Minha solução**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-qdiqBVHg-gd",
+ "outputId": "d2ea4d17-6db3-4113-d94f-91273460ebd8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 153
+ }
+ },
+ "source": [
+ "# Define a média e o desvio-padrão\n",
+ "media = 0\n",
+ "desvio_padrao = 1\n",
+ "\n",
+ "# Define seed\n",
+ "np.random.seed(seed = 20111974)\n",
+ "l_lista_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": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Size: 10--> Distribuição: N(1.1043374540652753, 0.735246705657231)\n",
+ "Size: 100--> Distribuição: N(-0.14020525697186714, 0.9254100654233511)\n",
+ "Size: 1000--> Distribuição: N(0.021644923462910873, 1.0054417533501039)\n",
+ "Size: 10000--> Distribuição: N(0.015499353804764507, 0.9970905566844254)\n",
+ "Size: 100000--> Distribuição: N(0.002039323041103302, 0.9960906293570095)\n",
+ "Size: 1000000--> Distribuição: N(-1.1062145143945444e-06, 0.999473966169304)\n",
+ "Size: 10000000--> Distribuição: N(0.0002892972723094128, 1.0001202837422036)\n",
+ "Size: 100000000--> Distribuição: N(0.00011967896623555603, 0.999944390106086)\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bp-YuviQwWqE"
+ },
+ "source": [
+ "Com relação à Distribuição Normal($\\mu, \\sigma$), temos que:\n",
+ "\n",
+ "\n",
+ "\n",
+ "Fonte: [Normal Distribution](https://towardsdatascience.com/understanding-the-68-95-99-7-rule-for-a-normal-distribution-b7b7cbf760c2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KwHBY3Enk04N"
+ },
+ "source": [
+ "## Lei Forte dos Grandes Números - LFGN\n",
+ "> Por favor, leia o que diz a [Law of large numbers](https://en.wikipedia.org/wiki/Law_of_large_numbers). --> 3 minutos.\n",
+ "\n",
+ "* O que você aprendeu com isso?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BhwmSkAjlszT"
+ },
+ "source": [
+ "## Exemplo 2\n",
+ "> Vamos nos aprofundar um pouco mais no que diz a LFGN. Para isso, vamos simular o lançamento de dados. Como sabemos, os dados possuem 6 lados numerados de 1 a 6, com igual probabilidade. Certo?\n",
+ "\n",
+ "A LFGN nos diz que à medida que N (o tamanho da amostra ou número de dados) cresce, então a média dos dados converge para o valor esperado. Isso quer dizer que:\n",
+ "\n",
+ "$$\\frac{1+2+3+4+5+6}{6}= \\frac{21}{6}= 3,5$$\n",
+ "\n",
+ "Ou seja, à medida que N (o tamanho da amostra) cresce, espera-se que a média dos dados se aproxime de 3,5. Ok?\n",
+ "\n",
+ "Vamos ver se isso é verdade..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-QcJXf6roj0D"
+ },
+ "source": [
+ "Vamos usar o método np.random.randint (= função randint definido na classe np.random), a seguir:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "A2u0RzLOrRE2"
+ },
+ "source": [
+ "O que significa ou qual é a interpretação do resultado abaixo?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "B3-X_VBerUfa",
+ "outputId": "2c0dde81-a718-4523-80cf-a8b546fc1a49",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "# Define seed\n",
+ "import numpy as np\n",
+ "np.random.seed(seed = 20111974)\n",
+ "\n",
+ "# Simular 100 lançamentos de um dado:\n",
+ "a_dados_simulados = np.random.randint(1, 7, size = 100)\n",
+ "a_dados_simulados"
+ ],
+ "execution_count": 2,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([4, 5, 3, 1, 1, 4, 3, 1, 2, 2, 1, 1, 6, 4, 5, 3, 1, 4, 1, 6, 2, 4,\n",
+ " 6, 2, 4, 3, 2, 6, 3, 6, 2, 6, 1, 3, 1, 2, 4, 2, 4, 6, 3, 2, 6, 1,\n",
+ " 4, 3, 6, 5, 2, 3, 3, 3, 3, 2, 1, 6, 2, 1, 2, 3, 1, 5, 6, 6, 6, 6,\n",
+ " 5, 6, 6, 5, 6, 3, 3, 2, 4, 2, 6, 1, 2, 3, 4, 5, 5, 3, 1, 6, 6, 5,\n",
+ " 5, 1, 4, 6, 2, 2, 4, 3, 6, 1, 5, 5])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 2
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m8Of2MMIrbF3",
+ "outputId": "dca5755e-c2bb-44e9-dc49-e7569bcbcfe2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 136
+ }
+ },
+ "source": [
+ "# Importar o pandas, pois vamos precisar do método pd.value_counts():\n",
+ "import pandas as pd\n",
+ "pd.value_counts(a_dados_simulados)"
+ ],
+ "execution_count": 3,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "6 22\n",
+ "3 18\n",
+ "2 18\n",
+ "1 17\n",
+ "4 13\n",
+ "5 12\n",
+ "dtype: int64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 3
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "54VwED8Br8rx"
+ },
+ "source": [
+ "**Interpretação**: Isso quer dizer que fizemos a simulação de lançamento de um dado 100 vezes. Acima, a frequência com que cada lado do dado aparece.\n",
+ "\n",
+ "Eu estava à espera de frequência igual para cada um dos lados, isto é, por volta dos 16 ou 17. Ou seja:\n",
+ "\n",
+ "$$\\frac{100}{6}= 16,66$$\n",
+ "\n",
+ "Mas ok, vamos continuar com nosso experimento..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HT_Dak-umC6I",
+ "outputId": "a4bcdc1f-0366-48cb-a2da-905d5751c994",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 170
+ }
+ },
+ "source": [
+ "# Definir a semente\n",
+ "np.random.seed(20111974)\n",
+ "\n",
+ "for i_size in [10, 30, 50, 75, 100, 1000, 10000, 100000, 1000000]:\n",
+ " a_dados_simulados = np.random.randint(1, 7, size = i_size)\n",
+ " print(f'Size: {i_size} --> Média: {np.mean(a_dados_simulados)}')"
+ ],
+ "execution_count": 4,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Size: 10 --> Média: 2.6\n",
+ "Size: 30 --> Média: 3.3666666666666667\n",
+ "Size: 50 --> Média: 3.72\n",
+ "Size: 75 --> Média: 3.2666666666666666\n",
+ "Size: 100 --> Média: 3.42\n",
+ "Size: 1000 --> Média: 3.461\n",
+ "Size: 10000 --> Média: 3.5259\n",
+ "Size: 100000 --> Média: 3.50794\n",
+ "Size: 1000000 --> Média: 3.50151\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "edWNNOnXtbtd"
+ },
+ "source": [
+ "E agora, como você interpreta esses resultados?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eL6gXThkYcSf"
+ },
+ "source": [
+ "## Calcular percentis\n",
+ "> Boxplot"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jlGOQfXfPf0D"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Fonte: [Understanding Boxplots](https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "grtEXG2BoNRt"
+ },
+ "source": [
+ "Considere o array de retornos (simulados) a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zgAh7gWeRews"
+ },
+ "source": [
+ "#usando dados de Fonte: Understanding Boxplots \n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "# Put dataset on my github repo \n",
+ "df = pd.read_csv('https://raw.githubusercontent.com/mGalarnyk/Python_Tutorials/master/Kaggle/BreastCancerWisconsin/data/data.csv')"
+ ],
+ "execution_count": 5,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jKjcOB_1RseM",
+ "outputId": "434f2866-7c1e-478b-b382-29ccf082104a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 241
+ }
+ },
+ "source": [
+ "df.head(5)"
+ ],
+ "execution_count": 8,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " id | \n",
+ " diagnosis | \n",
+ " radius_mean | \n",
+ " texture_mean | \n",
+ " perimeter_mean | \n",
+ " area_mean | \n",
+ " smoothness_mean | \n",
+ " compactness_mean | \n",
+ " concavity_mean | \n",
+ " concave points_mean | \n",
+ " symmetry_mean | \n",
+ " fractal_dimension_mean | \n",
+ " radius_se | \n",
+ " texture_se | \n",
+ " perimeter_se | \n",
+ " area_se | \n",
+ " smoothness_se | \n",
+ " compactness_se | \n",
+ " concavity_se | \n",
+ " concave points_se | \n",
+ " symmetry_se | \n",
+ " fractal_dimension_se | \n",
+ " radius_worst | \n",
+ " texture_worst | \n",
+ " perimeter_worst | \n",
+ " area_worst | \n",
+ " smoothness_worst | \n",
+ " compactness_worst | \n",
+ " concavity_worst | \n",
+ " concave points_worst | \n",
+ " symmetry_worst | \n",
+ " fractal_dimension_worst | \n",
+ " Unnamed: 32 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 842302 | \n",
+ " M | \n",
+ " 17.99 | \n",
+ " 10.38 | \n",
+ " 122.80 | \n",
+ " 1001.0 | \n",
+ " 0.11840 | \n",
+ " 0.27760 | \n",
+ " 0.3001 | \n",
+ " 0.14710 | \n",
+ " 0.2419 | \n",
+ " 0.07871 | \n",
+ " 1.0950 | \n",
+ " 0.9053 | \n",
+ " 8.589 | \n",
+ " 153.40 | \n",
+ " 0.006399 | \n",
+ " 0.04904 | \n",
+ " 0.05373 | \n",
+ " 0.01587 | \n",
+ " 0.03003 | \n",
+ " 0.006193 | \n",
+ " 25.38 | \n",
+ " 17.33 | \n",
+ " 184.60 | \n",
+ " 2019.0 | \n",
+ " 0.1622 | \n",
+ " 0.6656 | \n",
+ " 0.7119 | \n",
+ " 0.2654 | \n",
+ " 0.4601 | \n",
+ " 0.11890 | \n",
+ " NaN | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 842517 | \n",
+ " M | \n",
+ " 20.57 | \n",
+ " 17.77 | \n",
+ " 132.90 | \n",
+ " 1326.0 | \n",
+ " 0.08474 | \n",
+ " 0.07864 | \n",
+ " 0.0869 | \n",
+ " 0.07017 | \n",
+ " 0.1812 | \n",
+ " 0.05667 | \n",
+ " 0.5435 | \n",
+ " 0.7339 | \n",
+ " 3.398 | \n",
+ " 74.08 | \n",
+ " 0.005225 | \n",
+ " 0.01308 | \n",
+ " 0.01860 | \n",
+ " 0.01340 | \n",
+ " 0.01389 | \n",
+ " 0.003532 | \n",
+ " 24.99 | \n",
+ " 23.41 | \n",
+ " 158.80 | \n",
+ " 1956.0 | \n",
+ " 0.1238 | \n",
+ " 0.1866 | \n",
+ " 0.2416 | \n",
+ " 0.1860 | \n",
+ " 0.2750 | \n",
+ " 0.08902 | \n",
+ " NaN | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 84300903 | \n",
+ " M | \n",
+ " 19.69 | \n",
+ " 21.25 | \n",
+ " 130.00 | \n",
+ " 1203.0 | \n",
+ " 0.10960 | \n",
+ " 0.15990 | \n",
+ " 0.1974 | \n",
+ " 0.12790 | \n",
+ " 0.2069 | \n",
+ " 0.05999 | \n",
+ " 0.7456 | \n",
+ " 0.7869 | \n",
+ " 4.585 | \n",
+ " 94.03 | \n",
+ " 0.006150 | \n",
+ " 0.04006 | \n",
+ " 0.03832 | \n",
+ " 0.02058 | \n",
+ " 0.02250 | \n",
+ " 0.004571 | \n",
+ " 23.57 | \n",
+ " 25.53 | \n",
+ " 152.50 | \n",
+ " 1709.0 | \n",
+ " 0.1444 | \n",
+ " 0.4245 | \n",
+ " 0.4504 | \n",
+ " 0.2430 | \n",
+ " 0.3613 | \n",
+ " 0.08758 | \n",
+ " NaN | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 84348301 | \n",
+ " M | \n",
+ " 11.42 | \n",
+ " 20.38 | \n",
+ " 77.58 | \n",
+ " 386.1 | \n",
+ " 0.14250 | \n",
+ " 0.28390 | \n",
+ " 0.2414 | \n",
+ " 0.10520 | \n",
+ " 0.2597 | \n",
+ " 0.09744 | \n",
+ " 0.4956 | \n",
+ " 1.1560 | \n",
+ " 3.445 | \n",
+ " 27.23 | \n",
+ " 0.009110 | \n",
+ " 0.07458 | \n",
+ " 0.05661 | \n",
+ " 0.01867 | \n",
+ " 0.05963 | \n",
+ " 0.009208 | \n",
+ " 14.91 | \n",
+ " 26.50 | \n",
+ " 98.87 | \n",
+ " 567.7 | \n",
+ " 0.2098 | \n",
+ " 0.8663 | \n",
+ " 0.6869 | \n",
+ " 0.2575 | \n",
+ " 0.6638 | \n",
+ " 0.17300 | \n",
+ " NaN | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 84358402 | \n",
+ " M | \n",
+ " 20.29 | \n",
+ " 14.34 | \n",
+ " 135.10 | \n",
+ " 1297.0 | \n",
+ " 0.10030 | \n",
+ " 0.13280 | \n",
+ " 0.1980 | \n",
+ " 0.10430 | \n",
+ " 0.1809 | \n",
+ " 0.05883 | \n",
+ " 0.7572 | \n",
+ " 0.7813 | \n",
+ " 5.438 | \n",
+ " 94.44 | \n",
+ " 0.011490 | \n",
+ " 0.02461 | \n",
+ " 0.05688 | \n",
+ " 0.01885 | \n",
+ " 0.01756 | \n",
+ " 0.005115 | \n",
+ " 22.54 | \n",
+ " 16.67 | \n",
+ " 152.20 | \n",
+ " 1575.0 | \n",
+ " 0.1374 | \n",
+ " 0.2050 | \n",
+ " 0.4000 | \n",
+ " 0.1625 | \n",
+ " 0.2364 | \n",
+ " 0.07678 | \n",
+ " NaN | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " id diagnosis ... fractal_dimension_worst Unnamed: 32\n",
+ "0 842302 M ... 0.11890 NaN\n",
+ "1 842517 M ... 0.08902 NaN\n",
+ "2 84300903 M ... 0.08758 NaN\n",
+ "3 84348301 M ... 0.17300 NaN\n",
+ "4 84358402 M ... 0.07678 NaN\n",
+ "\n",
+ "[5 rows x 33 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 8
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "plyx1XniRgzD",
+ "outputId": "29317060-c75d-4e26-97de-b8df9a92d1d4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 296
+ }
+ },
+ "source": [
+ "sns.boxplot(x='diagnosis', y='area_mean', data=df)"
+ ],
+ "execution_count": 6,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 6
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OXRRKDX-R5_L",
+ "outputId": "8fc79075-ad94-4ca4-9064-fec56e6c73c2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 520
+ }
+ },
+ "source": [
+ "df_malignant = df[df['diagnosis']=='M']['area_mean']\n",
+ "df_benign = df[df['diagnosis']=='B']['area_mean']\n",
+ "fig = plt.figure()\n",
+ "ax = fig.add_subplot(111)\n",
+ "ax.boxplot([df_malignant,df_benign], labels=['M', 'B'])"
+ ],
+ "execution_count": 24,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'boxes': [,\n",
+ " ],\n",
+ " 'caps': [,\n",
+ " ,\n",
+ " ,\n",
+ " ],\n",
+ " 'fliers': [,\n",
+ " ],\n",
+ " 'means': [],\n",
+ " 'medians': [,\n",
+ " ],\n",
+ " 'whiskers': [,\n",
+ " ,\n",
+ " ,\n",
+ " ]}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 24
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oe8yTLWjR_ab",
+ "outputId": "b18523cb-2dd3-4ebf-9a4d-bbaf355cc050",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "df_malignant.head(5)"
+ ],
+ "execution_count": 11,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0 1001.0\n",
+ "1 1326.0\n",
+ "2 1203.0\n",
+ "3 386.1\n",
+ "4 1297.0\n",
+ "Name: area_mean, dtype: float64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 11
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nNlhW6FsSN8z",
+ "outputId": "f2f8a202-32cd-4e03-b75f-0c0ec398b5de",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "df_benign.head(5)\n"
+ ],
+ "execution_count": 12,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "19 566.3\n",
+ "20 520.0\n",
+ "21 273.9\n",
+ "37 523.8\n",
+ "46 201.9\n",
+ "Name: area_mean, dtype: float64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 12
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DjPKKq01YjF9",
+ "outputId": "372960aa-7d85-4514-8f12-28b3a2ec4259",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "import numpy as np\n",
+ "np.random.seed(20111974)\n",
+ "\n",
+ "# Simulando Retornos de ativos financeiros com a distribuição Normal(0, 1):\n",
+ "a_retornos = np.random.normal(0, 1, 100)\n",
+ "print(f'Média: {np.mean(a_retornos)}')"
+ ],
+ "execution_count": 13,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média: -0.016996335492713833\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ajjlfqgssLVO",
+ "outputId": "cb581b84-1c27-4c09-fee9-2d1a8ab56034",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 357
+ }
+ },
+ "source": [
+ "a_retornos"
+ ],
+ "execution_count": 14,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 2.5062768 , 1.11440422, 2.05565501, 0.56482376, 0.29897276,\n",
+ " 1.04930857, -0.12607366, 1.06227632, 1.13807032, 1.37966044,\n",
+ " -2.05995563, 0.67474814, 0.72722843, -0.33923852, 0.43613107,\n",
+ " 0.59135489, -1.29281877, 1.17712036, -0.98644163, -1.79034143,\n",
+ " -1.08913605, -0.90712825, -1.02291108, -1.36445713, -0.29429164,\n",
+ " 0.06343709, -1.14196185, -0.50706079, -0.83539436, -1.41492946,\n",
+ " -0.2159062 , -1.16519474, -0.60767518, -0.61510925, 1.0771542 ,\n",
+ " 0.5043687 , 0.02674197, 1.83494644, 0.34728874, -1.14671885,\n",
+ " -0.59841423, -0.42698353, 0.10901983, -0.75168457, 0.71689294,\n",
+ " -0.50810299, 0.47524103, -0.38248511, -1.37491973, 1.5355728 ,\n",
+ " -0.27356178, 0.68072592, -1.80454873, 1.16995833, -0.37988822,\n",
+ " 0.19305861, 1.53792436, -0.11802807, -0.97621103, -1.23463994,\n",
+ " 1.0504434 , 1.91481015, 0.80359454, 0.35869561, 1.03409992,\n",
+ " -0.37200685, 0.32947575, 0.70038627, -0.98085533, -1.21072144,\n",
+ " 0.74366412, 0.18372348, 0.10430302, -0.78160841, -0.0423915 ,\n",
+ " 1.67094293, -1.07256479, -0.5493723 , -1.83082917, 0.11510819,\n",
+ " 1.3911365 , -0.28940563, 0.31904722, -0.70009623, -0.4353552 ,\n",
+ " -2.0301258 , -0.14205882, 1.66292963, -0.57691495, -0.78963384,\n",
+ " -0.80660503, 0.05581487, 0.8715663 , -0.3499477 , 1.37366912,\n",
+ " 0.88027638, -1.47925906, -0.40657104, -0.18789895, 0.47475142])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 14
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XZ3m06gv9lei"
+ },
+ "source": [
+ "A seguir, o boxplot do array a_retornos:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QtuwJP449tBQ",
+ "outputId": "c0267932-7470-483d-daca-f1913a5f4772",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 269
+ }
+ },
+ "source": [
+ "# Import da biblioteca seaborn: Uma das principais libraries para Data Visualization (outras: matplotlib)\n",
+ "import seaborn as sns\n",
+ "\n",
+ "sns.boxplot(y = a_retornos)"
+ ],
+ "execution_count": 15,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 15
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "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": 17,
+ "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",
+ "outputId": "29c67f4b-eeb2-4072-916f-e7abaed09521",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "q3 = percentis[5]\n",
+ "\n",
+ "# ou de trás para a frente do conteúdo da lista:\n",
+ "q3_2 = percentis[-2]\n",
+ "print(q3, q3_2)"
+ ],
+ "execution_count": 18,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "0.7194768106252311 0.7194768106252311\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sWrnESPQT4JM"
+ },
+ "source": [
+ "# lim_inferior_outlier e lim_superior_outlier para detecção de outliers\n",
+ "lim_inferior_outlier = q1 - 1.5 * (q3 - q1)\n",
+ "lim_superior_outlier = q3 + 1.5 * (q3 - q1)"
+ ],
+ "execution_count": 19,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Yb4-ZJlUUYsi",
+ "outputId": "a93c3b50-4537-4a59-dd59-b5e981ed9e74",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'Limite Inferior: {lim_inferior_outlier}; Limite Superior: {lim_superior_outlier}'"
+ ],
+ "execution_count": 20,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Limite Inferior: -3.0382521297304486; Limite Superior: 2.974114174838639'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 20
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Jr6oXIHlUxOe",
+ "outputId": "fb66a413-161e-4556-b635-cff4c11b973e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.min(a_retornos)"
+ ],
+ "execution_count": 21,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "-2.0599556303504514"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 21
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UxE47cN0U54X",
+ "outputId": "a1a6bb8b-6cae-4af3-85f9-d19c9e6a7897",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.max(a_retornos)"
+ ],
+ "execution_count": 22,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "2.506276801325959"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 22
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "06107adb-7ff6-4d9e-edc8-27d82e39c8e7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.random.random(10)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 25,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.53097233, 0.56965626, 0.54252938, 0.65478409, 0.85708456,\n",
+ " 0.60174181, 0.87298309, 0.45573342, 0.67336717, 0.64300912])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 25
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cC9272GFdRln"
+ },
+ "source": [
+ "Ordenando os itens de a_conjunto1..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YUP90nBVdUeF",
+ "outputId": "b781aeb1-2418-4d6f-ddbb-a122451aab4f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.sort(a_conjunto1)"
+ ],
+ "execution_count": 26,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.45573342, 0.53097233, 0.54252938, 0.56965626, 0.60174181,\n",
+ " 0.64300912, 0.65478409, 0.67336717, 0.85708456, 0.87298309])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 26
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lG763cDGj-yB"
+ },
+ "source": [
+ "___\n",
+ "# **Obter ajuda**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ehxPlD3EkEYL",
+ "outputId": "c63a079a-285f-4c41-fe27-84630a824b58",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "help(np.random.normal)"
+ ],
+ "execution_count": 27,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Help on built-in function normal:\n",
+ "\n",
+ "normal(...) method of numpy.random.mtrand.RandomState instance\n",
+ " normal(loc=0.0, scale=1.0, size=None)\n",
+ " \n",
+ " Draw random samples from a normal (Gaussian) distribution.\n",
+ " \n",
+ " The probability density function of the normal distribution, first\n",
+ " derived by De Moivre and 200 years later by both Gauss and Laplace\n",
+ " independently [2]_, is often called the bell curve because of\n",
+ " its characteristic shape (see the example below).\n",
+ " \n",
+ " The normal distributions occurs often in nature. For example, it\n",
+ " describes the commonly occurring distribution of samples influenced\n",
+ " by a large number of tiny, random disturbances, each with its own\n",
+ " unique distribution [2]_.\n",
+ " \n",
+ " .. note::\n",
+ " New code should use the ``normal`` method of a ``default_rng()``\n",
+ " instance instead; see `random-quick-start`.\n",
+ " \n",
+ " Parameters\n",
+ " ----------\n",
+ " loc : float or array_like of floats\n",
+ " Mean (\"centre\") of the distribution.\n",
+ " scale : float or array_like of floats\n",
+ " Standard deviation (spread or \"width\") of the distribution. Must be\n",
+ " non-negative.\n",
+ " size : int or tuple of ints, optional\n",
+ " Output shape. If the given shape is, e.g., ``(m, n, k)``, then\n",
+ " ``m * n * k`` samples are drawn. If size is ``None`` (default),\n",
+ " a single value is returned if ``loc`` and ``scale`` are both scalars.\n",
+ " Otherwise, ``np.broadcast(loc, scale).size`` samples are drawn.\n",
+ " \n",
+ " Returns\n",
+ " -------\n",
+ " out : ndarray or scalar\n",
+ " Drawn samples from the parameterized normal distribution.\n",
+ " \n",
+ " See Also\n",
+ " --------\n",
+ " scipy.stats.norm : probability density function, distribution or\n",
+ " cumulative density function, etc.\n",
+ " Generator.normal: which should be used for new code.\n",
+ " \n",
+ " Notes\n",
+ " -----\n",
+ " The probability density for the Gaussian distribution is\n",
+ " \n",
+ " .. math:: p(x) = \\frac{1}{\\sqrt{ 2 \\pi \\sigma^2 }}\n",
+ " e^{ - \\frac{ (x - \\mu)^2 } {2 \\sigma^2} },\n",
+ " \n",
+ " where :math:`\\mu` is the mean and :math:`\\sigma` the standard\n",
+ " deviation. The square of the standard deviation, :math:`\\sigma^2`,\n",
+ " is called the variance.\n",
+ " \n",
+ " The function has its peak at the mean, and its \"spread\" increases with\n",
+ " the standard deviation (the function reaches 0.607 times its maximum at\n",
+ " :math:`x + \\sigma` and :math:`x - \\sigma` [2]_). This implies that\n",
+ " normal is more likely to return samples lying close to the mean, rather\n",
+ " than those far away.\n",
+ " \n",
+ " References\n",
+ " ----------\n",
+ " .. [1] Wikipedia, \"Normal distribution\",\n",
+ " https://en.wikipedia.org/wiki/Normal_distribution\n",
+ " .. [2] P. R. Peebles Jr., \"Central Limit Theorem\" in \"Probability,\n",
+ " Random Variables and Random Signal Principles\", 4th ed., 2001,\n",
+ " pp. 51, 51, 125.\n",
+ " \n",
+ " Examples\n",
+ " --------\n",
+ " Draw samples from the distribution:\n",
+ " \n",
+ " >>> mu, sigma = 0, 0.1 # mean and standard deviation\n",
+ " >>> s = np.random.normal(mu, sigma, 1000)\n",
+ " \n",
+ " Verify the mean and the variance:\n",
+ " \n",
+ " >>> abs(mu - np.mean(s))\n",
+ " 0.0 # may vary\n",
+ " \n",
+ " >>> abs(sigma - np.std(s, ddof=1))\n",
+ " 0.1 # may vary\n",
+ " \n",
+ " Display the histogram of the samples, along with\n",
+ " the probability density function:\n",
+ " \n",
+ " >>> import matplotlib.pyplot as plt\n",
+ " >>> count, bins, ignored = plt.hist(s, 30, density=True)\n",
+ " >>> plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *\n",
+ " ... np.exp( - (bins - mu)**2 / (2 * sigma**2) ),\n",
+ " ... linewidth=2, color='r')\n",
+ " >>> plt.show()\n",
+ " \n",
+ " Two-by-four array of samples from N(3, 6.25):\n",
+ " \n",
+ " >>> np.random.normal(3, 2.5, size=(2, 4))\n",
+ " array([[-4.49401501, 4.00950034, -1.81814867, 7.29718677], # random\n",
+ " [ 0.39924804, 4.68456316, 4.99394529, 4.84057254]]) # random\n",
+ "\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "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": 28,
+ "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",
+ "outputId": "75a9c3a7-2fd8-4b30-bde7-0978cebc5f69",
+ "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": 29,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 29
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DyfXbW_ZKJBS"
+ },
+ "source": [
+ "Qual a dimensão de a_conjunto1?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gbHlydALKB3R",
+ "outputId": "c15659d6-930f-4369-a015-a4830b141152",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Dimensão do array\n",
+ "a_conjunto1.ndim"
+ ],
+ "execution_count": 30,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "1"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 30
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "am9otElpKNPa"
+ },
+ "source": [
+ "Qual o shape (dimensão) do array a_conjunto1?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "juJJ74d2wale",
+ "outputId": "116b39b3-f216-4863-93c5-3b14875116ae",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Números de itens no array\n",
+ "a_conjunto1.shape"
+ ],
+ "execution_count": 31,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(10,)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 31
+ }
+ ]
+ },
+ {
+ "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": 32,
+ "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": 33,
+ "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",
+ "outputId": "33db7b05-003a-457c-f58e-dbd7458e2921",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 34,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 34
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lUNlFVKYYT9f",
+ "outputId": "f41f95ef-c618-4b58-f910-365d543978d8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 35,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 35
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Xo8Lid5fYVPW",
+ "outputId": "2d2c9a69-d58c-4878-c36c-d778b6077657",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto3"
+ ],
+ "execution_count": 36,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 36
+ }
+ ]
+ },
+ {
+ "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",
+ "\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",
+ "outputId": "23ebdf9d-aa2d-4e6a-fd90-77624f196a41",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 37,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 37
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "arROkhWXbdTW",
+ "outputId": "b104cb80-440f-4af8-8632-624a8213984c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto2 = a_conjunto1 + 2\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 38,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 38
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZJx2vG86vdVi"
+ },
+ "source": [
+ "Multiplicar por 10 cada item de a_conjunto1:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Vm7abO6Ebkun",
+ "outputId": "32f8afea-e559-4d67-e4f2-53c17b28185a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1 = a_conjunto1*10\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 39,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 39
+ }
+ ]
+ },
+ {
+ "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": "PJaLyBO5TkgM"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VDi0vIPSYR4F",
+ "outputId": "ef57de03-9fdf-420a-c3c5-cdd981c03be6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.random.randn(2, 3)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 40,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11, 2.06],\n",
+ " [0.56, 0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 40
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "ccab898f-5653-46b7-e1e1-ae78032592bf",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1.shape"
+ ],
+ "execution_count": 41,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(2, 3)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 41
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "65a25251-38bc-44b0-9cd0-53b2a35dbb92",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto2 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 42,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[1, 2, 3],\n",
+ " [4, 5, 6],\n",
+ " [7, 8, 9]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 42
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "we6ZJOICc7bQ",
+ "outputId": "05b14f8d-89b2-4eea-9e9c-c003cbdcaf7b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Número de linhas e colunas de a_conjunto1:\n",
+ "a_conjunto1.shape"
+ ],
+ "execution_count": 43,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(2, 3)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 43
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "f0ocwuI1dED6",
+ "outputId": "e438e744-a40f-4b60-8af1-062e763170ba",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Número de linhas e colunas de a_conjunto2\n",
+ "a_conjunto2.shape"
+ ],
+ "execution_count": 44,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(3, 3)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 44
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CApPtnW0YuRP",
+ "outputId": "ac8254a1-4de1-4541-ac74-90525d79463e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "# Somar 2 à cada elemento de a_conjunto2\n",
+ "a_conjunto2 = a_conjunto2+2\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 45,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 3, 4, 5],\n",
+ " [ 6, 7, 8],\n",
+ " [ 9, 10, 11]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 45
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "M87aGmxRY3RW",
+ "outputId": "be71ec2c-fd81-424c-c842-1ab347cbec8f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "# Multiplicar por 10 cada elemento de a_conjunto2\n",
+ "a_conjunto2 = a_conjunto2*10\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 46,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30, 40, 50],\n",
+ " [ 60, 70, 80],\n",
+ " [ 90, 100, 110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 46
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qZt93y1IL_v7"
+ },
+ "source": [
+ "___\n",
+ "# **Copiar arrays**\n",
+ "> Considere o array abaixo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sH2FTXj5MRRC",
+ "outputId": "9507249f-6a01-4244-898e-836b4a72f72f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.random.randn(2, 3)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 47,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11, 2.06],\n",
+ " [0.56, 0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 47
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VtgKeMt6MYrr"
+ },
+ "source": [
+ "Fazendo a cópia de a_conjunto1..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "K0hOHR3IMa-o",
+ "outputId": "998e10d1-d94b-4772-8937-05a7ed96142a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_salarios_copia = a_conjunto1.copy()\n",
+ "a_salarios_copia"
+ ],
+ "execution_count": 48,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11, 2.06],\n",
+ " [0.56, 0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 48
+ }
+ ]
+ },
+ {
+ "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": "N1ewYIYrUFFz",
+ "outputId": "a183084c-7fdc-4f7b-e1bd-85e52077b8c2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "np.random.randint(0, 100, 10)"
+ ],
+ "execution_count": 56,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([60, 42, 40, 8, 27, 2, 46, 88, 81, 88])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 56
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gEF497YLUOd7",
+ "outputId": "59ba5395-d847-4555-fbb5-c0cb2120e120",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_temperatura_farenheit = np.random.randint(0, 100, 10)\n",
+ "a_temperatura_farenheit "
+ ],
+ "execution_count": 57,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([60, 42, 40, 8, 27, 2, 46, 88, 81, 88])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 57
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VnagcUqVkLhW",
+ "outputId": "76d71142-f0cf-4fc4-ffd3-1c7790d2adcd",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "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": 55,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([60, 42, 40, 8, 27, 2, 46, 88, 81, 88])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 55
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VrjNKfXxk1yv",
+ "outputId": "2874cced-5cbf-4f04-87d5-c60f598dbfbe",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "type(a_temperatura_farenheit)"
+ ],
+ "execution_count": 58,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "numpy.ndarray"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 58
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o1STejhrk0kZ"
+ },
+ "source": [
+ "Transformando a temperatura Fahrenheit em Celsius..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "E_jXflR_lNy3",
+ "outputId": "616374ed-3843-49c9-c490-1a3d31dfb179",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_temperatura_celsius = 5*a_temperatura_farenheit/9 - 5*32/9\n",
+ "a_temperatura_celsius"
+ ],
+ "execution_count": 59,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 15.56, 5.56, 4.44, -13.33, -2.78, -16.67, 7.78, 31.11,\n",
+ " 27.22, 31.11])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 59
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U4pCv0pNqPZI",
+ "outputId": "07201a68-67f6-42ad-9023-75dcb0d00702",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "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": 60,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 15.56, 5.56, 4.44, -13.33, -2.78, -16.67, 7.78, 31.11,\n",
+ " 27.22, 31.11])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 60
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1UT4YD2FawUA"
+ },
+ "source": [
+ "___\n",
+ "# **Selecionar itens**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pqOv8P1za1m8",
+ "outputId": "977f643f-370b-4e53-d0fc-a8d7a9ac5ecc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "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": 61,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.56, 0.3 , 1.05])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 61
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TIwVKk6AyRv6"
+ },
+ "source": [
+ "Dado a_conjunto2 abaixo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zoDmbXo6bCeu",
+ "outputId": "2e1e5ac4-cd9e-4561-9d34-40f24ee665cf",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 62,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30, 40, 50],\n",
+ " [ 60, 70, 80],\n",
+ " [ 90, 100, 110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 62
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "f8265b6e-f9b7-489c-9c61-c61689ef76bc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto2[1, 2]"
+ ],
+ "execution_count": 63,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "80"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 63
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Xl5HwJIMcv2e",
+ "outputId": "7c7d7bec-c8ca-4941-8b2b-fba1c448ad52",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "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": 64,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.56, 0.3 , 1.05])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 64
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ezTH0HsyrnAl"
+ },
+ "source": [
+ "Veja..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OBv9EM54rYX3",
+ "outputId": "03083e15-bce9-4df3-aea8-3b22183d3fcd",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 65,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11, 2.06],\n",
+ " [0.56, 0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 65
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Po3WLFC-rod8",
+ "outputId": "35018018-52be-4e0f-f0df-3c2b7dd59757",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_temperatura_celsius[-1]"
+ ],
+ "execution_count": 66,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "31.111111111111114"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 66
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4qJJ2HCedW4h"
+ },
+ "source": [
+ "___\n",
+ "# **Aplicar funções como max(), min() e etc**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_meTJdUsda4e",
+ "outputId": "38b377c5-d7e6-4121-80f5-cd8e5e6e5d42",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'O máximo de a_conjunto1 é: {np.max(a_conjunto1)}'"
+ ],
+ "execution_count": 67,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O máximo de a_conjunto1 é: 2.506276801325959'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 67
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m-wiBkAidnhN",
+ "outputId": "c57d17c1-8501-4cc7-b1f2-4eb5305747f4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'O mínimo de a_conjunto1 é: {np.min(a_conjunto1)}'"
+ ],
+ "execution_count": 68,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O mínimo de a_conjunto1 é: 0.29897275739745677'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 68
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lmupnRHQdtwh",
+ "outputId": "1fb75802-b7fb-46d7-efef-d2c27492408b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'O máximo de a_conjunto2 é: {np.max(a_conjunto2)}'"
+ ],
+ "execution_count": 69,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O máximo de a_conjunto2 é: 110'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 69
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "H2z7oB6Bd786",
+ "outputId": "73dc5fb9-0d53-4e97-cd40-16d1e38d7b03",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "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": 70,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O máximo de cada LINHA de a_conjunto2 é: [ 50 80 110]'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 70
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gj2ZBDsWeMyk",
+ "outputId": "c879bbd9-d17f-4dd1-a9db-dc08b93f6735",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "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": 71,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O máximo de cada COLUNA de a_conjunto2 é: [ 90 100 110]'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 71
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7_tEfm2IecIU"
+ },
+ "source": [
+ "___\n",
+ "# **Calcular Estatísticas Descritivas: média e variância**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lIY5jx3ueh7q",
+ "outputId": "cf275100-6c2d-4278-bc0b-aeea828a9197",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'A média de a_conjunto1 é: {np.mean(a_conjunto1)}'"
+ ],
+ "execution_count": 72,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'A média de a_conjunto1 é: 1.2649068535973844'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 72
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VmqSELRReuAW",
+ "outputId": "d4d64bc2-3d95-4101-e8aa-bcb99feaaaf9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'A média de a_conjunto2 é: {np.mean(a_conjunto2)}'"
+ ],
+ "execution_count": 73,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'A média de a_conjunto2 é: 70.0'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 73
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Gxap-Wg5e2_H",
+ "outputId": "513165e1-1e98-43f5-9278-112ce6973892",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'O Desvio Padrão de a_conjunto2 é: {np.std(a_conjunto2)}'"
+ ],
+ "execution_count": 74,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'O Desvio Padrão de a_conjunto2 é: 25.81988897471611'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 74
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "16aa9de9-0959-4594-e096-472d051dd7ba",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 78,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30, 40, 50],\n",
+ " [ 60, 70, 80],\n",
+ " [ 90, 100, 110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 78
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YWN_nN-4fD7u",
+ "outputId": "a2a67789-17e1-4237-8b04-30f498f47db4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 170
+ }
+ },
+ "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": 76,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30],\n",
+ " [ 40],\n",
+ " [ 50],\n",
+ " [ 60],\n",
+ " [ 70],\n",
+ " [ 80],\n",
+ " [ 90],\n",
+ " [100],\n",
+ " [110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 76
+ }
+ ]
+ },
+ {
+ "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": "43c0fa78-3313-4ec9-eb2d-b097d6606b3e",
+ "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": 79,
+ "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": 79
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "f2405e24-36b7-48e7-a815-bb6059d5f9d8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.random.randn(2, 3)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 80,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11, 2.06],\n",
+ " [0.56, 0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 80
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "eba2e377-bdaa-4586-8512-4e5ad4f52456",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto1.reshape(-1, 2)"
+ ],
+ "execution_count": 81,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[2.51, 1.11],\n",
+ " [2.06, 0.56],\n",
+ " [0.3 , 1.05]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 81
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "f0eec83e-02a7-4931-cc33-bd72b8b73dc0",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 82,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30, 40, 50],\n",
+ " [ 60, 70, 80],\n",
+ " [ 90, 100, 110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 82
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "A3MzTVoGfiyO",
+ "outputId": "aac33a4c-a98d-4379-fba0-ce27022418c9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "# Transposta do array a_conjunto2 é dado por:\n",
+ "a_conjunto2.T"
+ ],
+ "execution_count": 83,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 30, 60, 90],\n",
+ " [ 40, 70, 100],\n",
+ " [ 50, 80, 110]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 83
+ }
+ ]
+ },
+ {
+ "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": 84,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7zmHHWWlvaYB",
+ "outputId": "ff3bd49c-1701-4b80-ec4c-6f3d85c8825a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 85,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[1, 2, 3],\n",
+ " [4, 5, 6],\n",
+ " [7, 8, 9]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 85
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3fHKyhOJvcak",
+ "outputId": "49a239c0-baa5-41af-9afd-87eaec5d9cb5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 86,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[6, 2],\n",
+ " [5, 3]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 86
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vQG7yyfjwLg9",
+ "outputId": "2acfc295-6770-48df-e5f2-c792e39498fc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "a_conjunto3"
+ ],
+ "execution_count": 87,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[1, 3, 5],\n",
+ " [2, 5, 1],\n",
+ " [2, 3, 8]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 87
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qa2Yre2rwgRk"
+ },
+ "source": [
+ "## Determinantes da matriz quadrada"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N6jwuC6twkyc",
+ "outputId": "93b6c505-1e4a-499c-cea4-5de2afe46dc2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.linalg.det(a_conjunto1)"
+ ],
+ "execution_count": 88,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.0"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 88
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QSvViNwzwnhI",
+ "outputId": "a5fa2582-734e-45c4-fc82-916e0bd8072e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.linalg.det(a_conjunto2)"
+ ],
+ "execution_count": 89,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "8.000000000000002"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 89
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "o8jwsnccw5id",
+ "outputId": "6d0fa7b3-097a-4c2d-b83c-4288f9b09886",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.linalg.det(a_conjunto3)"
+ ],
+ "execution_count": 90,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "-25.000000000000007"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 90
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kkVaTgzgw_XJ"
+ },
+ "source": [
+ "A seguir, calculamos as inversas das matrizes acima definidas..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "b9FgWvTYvpik",
+ "outputId": "c486ab74-85c9-4718-c010-83b1e9c067ca",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "np.linalg.inv(a_conjunto2)"
+ ],
+ "execution_count": 91,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 0.38, -0.25],\n",
+ " [-0.62, 0.75]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 91
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KsdEt1kIvsM_",
+ "outputId": "1872d30a-4c4e-44b2-cec4-3c6251c278ee",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 340
+ }
+ },
+ "source": [
+ "np.linalg.inv(a_conjunto1)"
+ ],
+ "execution_count": 92,
+ "outputs": [
+ {
+ "output_type": "error",
+ "ename": "LinAlgError",
+ "evalue": "ignored",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mLinAlgError\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[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlinalg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma_conjunto1\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<__array_function__ internals>\u001b[0m in \u001b[0;36minv\u001b[0;34m(*args, **kwargs)\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py\u001b[0m in \u001b[0;36minv\u001b[0;34m(a)\u001b[0m\n\u001b[1;32m 545\u001b[0m \u001b[0msignature\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'D->D'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misComplexType\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'd->d'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 546\u001b[0m \u001b[0mextobj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_linalg_error_extobj\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 547\u001b[0;31m \u001b[0mainv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_umath_linalg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msignature\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msignature\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mextobj\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mextobj\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 548\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mwrap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mainv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult_t\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\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 549\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py\u001b[0m in \u001b[0;36m_raise_linalgerror_singular\u001b[0;34m(err, flag)\u001b[0m\n\u001b[1;32m 95\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflag\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;32m---> 97\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Singular matrix\"\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 98\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_raise_linalgerror_nonposdef\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflag\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;31mLinAlgError\u001b[0m: Singular matrix"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VA_F7_7kccpn"
+ },
+ "source": [
+ "Porque não temos a inversa de a_conjunto1?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ANPBCnmVwOf4",
+ "outputId": "bea278b5-3959-47c7-e76c-216cd2c7d5cd",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "np.linalg.inv(a_conjunto3)"
+ ],
+ "execution_count": 93,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[-1.48, 0.36, 0.88],\n",
+ " [ 0.56, 0.08, -0.36],\n",
+ " [ 0.16, -0.12, 0.04]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 93
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "50af27a9-e578-4e39-882a-0d2a5e51ba8c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "A= np.array([[1, 3, 5], [2, 5, 1], [2, 3, 8]])\n",
+ "np.linalg.inv(A)"
+ ],
+ "execution_count": 94,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[-1.48, 0.36, 0.88],\n",
+ " [ 0.56, 0.08, -0.36],\n",
+ " [ 0.16, -0.12, 0.04]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 94
+ }
+ ]
+ },
+ {
+ "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",
+ "\n",
+ "\n",
+ "## Exemplo 2\n",
+ "\n",
+ "\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": 95,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UYsAqBRp--79"
+ },
+ "source": [
+ "## Método 1 - Concatenate([A, B])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HgO1ujvhObyE",
+ "outputId": "0aa2aa36-0468-434c-81fc-a9641932564a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 96,
+ "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],\n",
+ " [ 1.14, 1.38, -2.06, 0.67, 0.73, -0.34, 0.44, 0.59],\n",
+ " [-1.29, 1.18, -0.99, -1.79, -1.09, -0.91, -1.02, -1.36],\n",
+ " [-0.29, 0.06, -1.14, -0.51, -0.84, -1.41, -0.22, -1.17],\n",
+ " [-0.61, -0.62, 1.08, 0.5 , 0.03, 1.83, 0.35, -1.15]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 96
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2aQY_klZOeg9",
+ "outputId": "38317a5e-5d47-4570-af47-781f03a8dd5a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 153
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 97,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[-0.77, -1.11, 0.1 , -1.15, -2.15, -0.75, -2.15, -0.33],\n",
+ " [-1.1 , 0.33, 0.01, -1.33, -0.34, -0.01, 0.05, -0.19],\n",
+ " [ 0.39, -0.89, -0.51, -0.75, 1.84, -1.21, 1.2 , 0.51],\n",
+ " [-0.57, -0.93, -0.25, 0.98, 1.19, 2.3 , 0.17, 0.71],\n",
+ " [-0.45, 0.92, 0.73, 2.18, -0.06, 1.25, -0.37, 1.44],\n",
+ " [ 0.86, -0.11, -0.35, 0.94, -0.09, -1.49, 0.01, 0.87],\n",
+ " [ 1.63, 1.36, -0.02, -0.45, -0.37, -0.05, -2.27, 0.95],\n",
+ " [ 0.71, -0.8 , -0.32, -1.58, -0.38, -0.3 , -0.73, -0.56]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 97
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bK70vaq8_KMH",
+ "outputId": "40e9b550-ba17-4896-ffb9-8a9b72ff6055",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 238
+ }
+ },
+ "source": [
+ "np.concatenate([a_conjunto1, a_conjunto2], axis = 0) # axis= 0 diz ao NumPy para empilhar as linhas"
+ ],
+ "execution_count": 98,
+ "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],\n",
+ " [ 1.14, 1.38, -2.06, 0.67, 0.73, -0.34, 0.44, 0.59],\n",
+ " [-1.29, 1.18, -0.99, -1.79, -1.09, -0.91, -1.02, -1.36],\n",
+ " [-0.29, 0.06, -1.14, -0.51, -0.84, -1.41, -0.22, -1.17],\n",
+ " [-0.61, -0.62, 1.08, 0.5 , 0.03, 1.83, 0.35, -1.15],\n",
+ " [-0.77, -1.11, 0.1 , -1.15, -2.15, -0.75, -2.15, -0.33],\n",
+ " [-1.1 , 0.33, 0.01, -1.33, -0.34, -0.01, 0.05, -0.19],\n",
+ " [ 0.39, -0.89, -0.51, -0.75, 1.84, -1.21, 1.2 , 0.51],\n",
+ " [-0.57, -0.93, -0.25, 0.98, 1.19, 2.3 , 0.17, 0.71],\n",
+ " [-0.45, 0.92, 0.73, 2.18, -0.06, 1.25, -0.37, 1.44],\n",
+ " [ 0.86, -0.11, -0.35, 0.94, -0.09, -1.49, 0.01, 0.87],\n",
+ " [ 1.63, 1.36, -0.02, -0.45, -0.37, -0.05, -2.27, 0.95],\n",
+ " [ 0.71, -0.8 , -0.32, -1.58, -0.38, -0.3 , -0.73, -0.56]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 98
+ }
+ ]
+ },
+ {
+ "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",
+ "\n",
+ "\n",
+ "# Exemplo 2\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "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": 99,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JPxhGsaSSMk2",
+ "outputId": "d7e2784d-7896-48ce-f8d9-e81b8254102a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 187
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 100,
+ "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": 100
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9ZyUPfybTfej",
+ "outputId": "9e66a78e-3fc1-4ba1-972d-8044325d7de5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 187
+ }
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": 101,
+ "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": 101
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nS1cPG3aRug1",
+ "outputId": "1758003d-b435-4fc2-b094-6870b64039b1",
+ "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": 102,
+ "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": 102
+ }
+ ]
+ },
+ {
+ "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": "59325971-d3be-4eed-faf5-67991a242054",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1 = np.arange(10, 0, -1)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 103,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 103
+ }
+ ]
+ },
+ {
+ "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": "af66ee9d-531e-415c-b019-71a548e0b741",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 104,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 104
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "O_ZBaWxfWA9o",
+ "outputId": "3f6482f5-69b2-48a3-e21e-5300b2bd940e",
+ "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": 105,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(array([0, 1, 2]),)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 105
+ }
+ ]
+ },
+ {
+ "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": "8799d399-938f-4c69-fca8-dd355a41f42a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto2 = a_conjunto1[l_indices]\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 106,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 106
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PGsENqkaXRjh"
+ },
+ "source": [
+ "## Alternativa: Usando []"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YbdRNk1WXTLT",
+ "outputId": "370c4930-10f1-45cc-8214-a0684eb42312",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1[a_conjunto1 > 7]"
+ ],
+ "execution_count": 107,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 107
+ }
+ ]
+ },
+ {
+ "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": 108,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FYZaBsasSb3N",
+ "outputId": "c2b1a20f-b10e-4c5d-db31-ba6522a55ead",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_conjunto1 > 7"
+ ],
+ "execution_count": 109,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ True, True, True, False, False, False, False, False, False,\n",
+ " False])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 109
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mvEof-UKaaVG",
+ "outputId": "4fcc225d-d235-4a9d-dcf2-ead48e241e00",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1[a_conjunto1 > 7]"
+ ],
+ "execution_count": 110,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 110
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nO4FiBmDUZOT",
+ "outputId": "7eb0a17f-69f6-4041-a03a-561dab4fd525",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 111,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 111
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ci5lT9nmSfsX"
+ },
+ "source": [
+ "Agora, com este resultado, fica fácil entender como o Python seleciona os elementos. Consegue explicar?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1v5Lfin0GGKD"
+ },
+ "source": [
+ "# Substituir itens baseado em condições\n",
+ "> Substituir os valores negativos do array abaixo por 0."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CLY_u0ePWdN7"
+ },
+ "source": [
+ "## Gerar o exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NUANFy-fNXf5",
+ "outputId": "21a681f7-1fb6-4feb-bc24-565589292f1a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "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": 112,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 8, 8, -2, 8, 9, 1, 8, 0, -4, 2, 0, 8, 9, 3, 7, 1, 3,\n",
+ " 2, 9, 7, 7, 9, 5, 6, 8, 7, 0, -9, 3, 9, 3, 1, 8, 6,\n",
+ " 3, 5, 4, 1, 2, 9, -8, 6, -6, 1, 0, 9, -2, 0, 7, 5, 5,\n",
+ " 4, 4, 2, 7, 2, 7, 9, 3, 1, -5, 0, 1, 2, 3, 8, 7, 5,\n",
+ " 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, -1, 0, 9, 1,\n",
+ " 4, 2, 9, -7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 112
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Bo44elZsWhBN",
+ "outputId": "b2f38dac-a1a8-44d7-cae3-06e1a2e4a7ab",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 117,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 8, 8, -2, 8, 9, 1, 8, 0, -4, 2, 0, 8, 9, 3, 7, 1, 3,\n",
+ " 2, 9, 7, 7, 9, 5, 6, 8, 7, 0, -9, 3, 9, 3, 1, 8, 6,\n",
+ " 3, 5, 4, 1, 2, 9, -8, 6, -6, 1, 0, 9, -2, 0, 7, 5, 5,\n",
+ " 4, 4, 2, 7, 2, 7, 9, 3, 1, -5, 0, 1, 2, 3, 8, 7, 5,\n",
+ " 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, -1, 0, 9, 1,\n",
+ " 4, 2, 9, -7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 117
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dWVyI40uN2d2",
+ "outputId": "5d605357-c96e-471c-a870-b09616ffbb95",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Indices a serem multiplicados por -1:\n",
+ "l_indices.sort()\n",
+ "l_indices"
+ ],
+ "execution_count": 116,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 2, 8, 27, 40, 42, 46, 60, 81, 88])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 116
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3Whuu854OJDZ"
+ },
+ "source": [
+ "## Substituir os valores negativos por 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sr268Rp8b-Se",
+ "outputId": "dfb6923e-2ff2-4e92-bcbf-bc81a38cc4b9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 221
+ }
+ },
+ "source": [
+ "a_conjunto2 < 0"
+ ],
+ "execution_count": 118,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([False, False, True, False, False, False, False, False, True,\n",
+ " False, False, False, False, False, False, False, False, False,\n",
+ " False, False, False, False, False, False, False, False, False,\n",
+ " True, False, False, False, False, False, False, False, False,\n",
+ " False, False, False, False, True, False, True, False, False,\n",
+ " False, True, False, False, False, False, False, False, False,\n",
+ " False, False, False, False, False, False, True, False, False,\n",
+ " False, False, False, False, False, False, False, False, False,\n",
+ " False, False, False, False, False, False, False, False, False,\n",
+ " True, False, False, False, False, False, False, True, False,\n",
+ " False, False, False, False, False, False, False, False, False,\n",
+ " False])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 118
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iaFIC3JFWp0T",
+ "outputId": "3927203e-9cc4-48ed-9c27-eb8f684cf48e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto2[a_conjunto2 < 0]"
+ ],
+ "execution_count": 119,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([-2, -4, -9, -8, -6, -2, -5, -1, -7])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 119
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "C-eKqPrfOQF6",
+ "outputId": "27239b4f-b921-4d35-f82e-a69caac4a362",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "a_conjunto2[a_conjunto2 < 0] = 0\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 120,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([8, 8, 0, 8, 9, 1, 8, 0, 0, 2, 0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 7, 9,\n",
+ " 5, 6, 8, 7, 0, 0, 3, 9, 3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 0, 6, 0, 1,\n",
+ " 0, 9, 0, 0, 7, 5, 5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 0, 0, 1, 2, 3, 8,\n",
+ " 7, 5, 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, 0, 0, 9, 1, 4, 2, 9,\n",
+ " 0, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 120
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eDLM0_JSZlfB"
+ },
+ "source": [
+ "Observe acima que os valores negativos foram substituídos por 0, como queríamos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AEHJ0rA3dHHU"
+ },
+ "source": [
+ "## Substituir os valores negativos por 0 e os positivos por 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y32J8SRNZwRF",
+ "outputId": "ffeee753-67ba-4ccc-fa51-8c8df224b9f8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "a_conjunto2 = a_conjunto1.copy()\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 121,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 8, 8, -2, 8, 9, 1, 8, 0, -4, 2, 0, 8, 9, 3, 7, 1, 3,\n",
+ " 2, 9, 7, 7, 9, 5, 6, 8, 7, 0, -9, 3, 9, 3, 1, 8, 6,\n",
+ " 3, 5, 4, 1, 2, 9, -8, 6, -6, 1, 0, 9, -2, 0, 7, 5, 5,\n",
+ " 4, 4, 2, 7, 2, 7, 9, 3, 1, -5, 0, 1, 2, 3, 8, 7, 5,\n",
+ " 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, -1, 0, 9, 1,\n",
+ " 4, 2, 9, -7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 121
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1bSD9Fs6P5wW",
+ "outputId": "828e9490-2cd9-4e11-cd03-c26bee1562b5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "a_conjunto2 = np.where(a_conjunto2 <= 0, 0, 1)\n",
+ "a_conjunto2"
+ ],
+ "execution_count": 122,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
+ " 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,\n",
+ " 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,\n",
+ " 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,\n",
+ " 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 122
+ }
+ ]
+ },
+ {
+ "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",
+ ""
+ ]
+ },
+ {
+ "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": [
+ ""
+ ]
+ },
+ {
+ "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": "ZVexc7iwW-uz",
+ "outputId": "9578d344-bd54-48d0-81b6-78be7642347c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "import numpy as np\n",
+ "np.random.seed(202020202)\n",
+ "np.set_printoptions(precision = 2, suppress = True)\n",
+ "\n",
+ "i_media = 1045\n",
+ "i_dp = 500\n",
+ "i_size = 1000\n",
+ "i_tamanho = 1000\n",
+ "\n",
+ "\n",
+ "a_salarios = np.array(np.random.normal(i_media, i_dp, size=i_size))\n",
+ "a_salarios[:30]"
+ ],
+ "execution_count": 132,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 488.91, 1227.09, 641.47, 575.7 , 1664.34, 1254.27, 931.62,\n",
+ " 1550.25, 1242.86, 794.05, 924.31, 1184.53, 723.31, 46.76,\n",
+ " 1336.84, 1323.31, 1480.29, 754.29, 1105.24, 1254.35, 930.3 ,\n",
+ " 889.64, 954.45, 716.47, 848.33, 925.16, 1021.7 , 978.52,\n",
+ " 588.65, 1682.72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 132
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RL0Zb0fyDory",
+ "outputId": "8f932586-43c2-427a-b445-7b377c8cdb93",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 104
+ }
+ },
+ "source": [
+ "import numpy as np\n",
+ "np.random.seed(20111974)\n",
+ "np.set_printoptions(precision = 2, suppress = True)\n",
+ "\n",
+ "media = 1045\n",
+ "desvio_padrao = 100\n",
+ "i_tamanho = 1000\n",
+ "\n",
+ "a_salarios = np.array(np.random.normal(media, desvio_padrao, size = i_tamanho))\n",
+ "a_salarios[:30]"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1295.63, 1156.44, 1250.57, 1101.48, 1074.9 , 1149.93, 1032.39,\n",
+ " 1151.23, 1158.81, 1182.97, 839. , 1112.47, 1117.72, 1011.08,\n",
+ " 1088.61, 1104.14, 915.72, 1162.71, 946.36, 865.97, 936.09,\n",
+ " 954.29, 942.71, 908.55, 1015.57, 1051.34, 930.8 , 994.29,\n",
+ " 961.46, 903.51])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 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": "555936b6-9a67-4220-a78f-9abf464ad966",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Lista aleatória de índices que vou alterar\n",
+ "np.random.seed(19741120)\n",
+ "l_indices = np.random.randint(0, i_tamanho, 10)\n",
+ "\n",
+ "# Estas são as posições que serão alteradas (manualmente)\n",
+ "np.sort(l_indices)"
+ ],
+ "execution_count": 133,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 14, 105, 208, 349, 484, 567, 615, 616, 622, 847])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 133
+ }
+ ]
+ },
+ {
+ "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": "e7e6f685-4d47-49ba-e04e-4571617bd07f",
+ "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": 134,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 488.91, 1227.09, 641.47, 575.7 , 1664.34, 1254.27, 931.62,\n",
+ " 1550.25, 1242.86, 794.05, 924.31, 1184.53, 723.31, 46.76,\n",
+ " 1336.84, 1323.31, 1480.29, 754.29, 1105.24, 1254.35, 930.3 ,\n",
+ " 889.64, 954.45, 716.47, 848.33, 925.16, 1021.7 , 978.52,\n",
+ " 588.65, 1682.72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 134
+ }
+ ]
+ },
+ {
+ "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": 135,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NpvvholVxMhs",
+ "outputId": "2f23cbcd-2667-4ec7-a2b8-6d10480d2fde",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Índices a serem alterados\n",
+ "l_indices"
+ ],
+ "execution_count": 136,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([567, 14, 616, 484, 208, 105, 349, 615, 622, 847])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 136
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BqXsmMdm1yF-"
+ },
+ "source": [
+ "#### Solução 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FiiOrlnbgKOD",
+ "outputId": "9c77735d-8362-455c-830b-9f0c468d1f93",
+ "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",
+ "end = timer()\n",
+ "a_salarios_copia[:30]\n",
+ "print(timedelta(seconds=end-start))"
+ ],
+ "execution_count": 137,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "0:00:00.000071\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FgvKC-aFzWpZ"
+ },
+ "source": [
+ "#### Solução 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XWlQC5Jazt26",
+ "outputId": "8445dc45-c409-4681-de94-84a4e7ec4957",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "start = timer()\n",
+ "a_salarios_copia2[l_indices] = 2*a_salarios_copia2[l_indices] # Loop para os índices a serem alterados (manualmente)\n",
+ "end = timer()\n",
+ "a_salarios_copia2[:30]\n",
+ "\n",
+ "print(timedelta(seconds=end-start))"
+ ],
+ "execution_count": 138,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "0:00:00.000079\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "U92w03afhrmC"
+ },
+ "source": [
+ "### Compare"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ls-jCFCYhtD8",
+ "outputId": "9cbfe609-9393-428f-94df-ffdae2064bda",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Antes\n",
+ "a_salarios[l_indices]"
+ ],
+ "execution_count": 139,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 614.6 , 1336.84, 1365.54, 1112.75, 1086.39, 549.15, 2017.39,\n",
+ " 1065.89, 917.95, 1085.65])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 139
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nwwU06OahzD2",
+ "outputId": "6ca35eba-5e8d-46b1-a8ae-0b34608bae3f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Depois\n",
+ "a_salarios_copia[l_indices]"
+ ],
+ "execution_count": 140,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1229.19, 2673.67, 2731.07, 2225.51, 2172.78, 1098.31, 4034.79,\n",
+ " 2131.78, 1835.91, 2171.3 ])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 140
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qyUUdHmtisJS",
+ "outputId": "3963e188-69cc-4550-e1bf-23d17167f5a2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "# 30 primeiras elementos de a_salarios\n",
+ "a_salarios[:30]"
+ ],
+ "execution_count": 141,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 488.91, 1227.09, 641.47, 575.7 , 1664.34, 1254.27, 931.62,\n",
+ " 1550.25, 1242.86, 794.05, 924.31, 1184.53, 723.31, 46.76,\n",
+ " 1336.84, 1323.31, 1480.29, 754.29, 1105.24, 1254.35, 930.3 ,\n",
+ " 889.64, 954.45, 716.47, 848.33, 925.16, 1021.7 , 978.52,\n",
+ " 588.65, 1682.72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 141
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CJ1FEjlCi0-n",
+ "outputId": "20177975-5f0f-4b66-cf42-aa7bb2c08148",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "# 30 primeiras posições de a_salarios_copia\n",
+ "a_salarios_copia[:30]"
+ ],
+ "execution_count": 142,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 488.91, 1227.09, 641.47, 575.7 , 1664.34, 1254.27, 931.62,\n",
+ " 1550.25, 1242.86, 794.05, 924.31, 1184.53, 723.31, 46.76,\n",
+ " 2673.67, 1323.31, 1480.29, 754.29, 1105.24, 1254.35, 930.3 ,\n",
+ " 889.64, 954.45, 716.47, 848.33, 925.16, 1021.7 , 978.52,\n",
+ " 588.65, 1682.72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 142
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wKbSUgxxiOUL"
+ },
+ "source": [
+ "### Algumas Estatísticas Descritivas:\n",
+ "#### Antes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZnmykyahLWX9",
+ "outputId": "90196058-0220-45d8-d87e-ab7756131fb6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'Amostra: {i_size} Média: {np.mean(a_salarios)}; Mediana: {np.median(a_salarios)}; STD: {np.std(a_salarios)}'"
+ ],
+ "execution_count": 144,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Amostra: 1000 Média: 1044.877512524266; Mediana: 1032.846999013294; STD: 500.9747087649826'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 144
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ow7MHjgmPIty"
+ },
+ "source": [
+ "#### Depois"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5iO-BAikieHJ",
+ "outputId": "2e04ed85-08be-44b6-b75b-5d4ce2f292b7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'Amostra: {i_size} Média: {np.mean(a_salarios_copia)}; Mediana: {np.median(a_salarios_copia)}; STD: {np.std(a_salarios_copia)}'"
+ ],
+ "execution_count": 145,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Amostra: 1000 Média: 1056.0296676634293; Mediana: 1035.8622742229763; STD: 519.1113559585269'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 145
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ILhNe80xW5C6"
+ },
+ "source": [
+ "### Solução do desafio"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OyFbWs-APowd",
+ "outputId": "9dad8981-0c5b-415a-9712-b8c77f429248",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 270
+ }
+ },
+ "source": [
+ "# Import a biblioteca seaborn:\n",
+ "import seaborn as sns\n",
+ "\n",
+ "# Boxplot antes dos \"outliers\"\n",
+ "sns.boxplot(y = a_salarios)"
+ ],
+ "execution_count": 146,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 146
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U993i1GJg2hk",
+ "outputId": "ae9aa1c4-5054-40b2-9e53-54aeaeda95fe",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 269
+ }
+ },
+ "source": [
+ "# Boxplot do array a_salarios_copia depois dos \"outliers\"\n",
+ "sns.boxplot(y = a_salarios_copia)"
+ ],
+ "execution_count": 147,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 147
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VtenLK1uK1Pi"
+ },
+ "source": [
+ "Consegue identificar os outliers do array?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "e3sHuGVGFBdW"
+ },
+ "source": [
+ "## Objetivo\n",
+ "> Identificar e substituir os outliers pela mediana dos dados. \n",
+ "\n",
+ "* Como fazer isso?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RSegPNKCI-dS"
+ },
+ "source": [
+ "### Siga os passos a seguir\n",
+ "1. Calcule estatísticas descritivas antes das transformações par avaliar o impacto;\n",
+ " * Calcule média, mediana e desvio-padrão dos dados originais;\n",
+ "2. Calcule os valores a seguir:\n",
+ " * Q1, Q3\n",
+ " * IQR = Q3-Q1\n",
+ " * lim_inferior_outlier = Q1-1.5\\*IQR\n",
+ " * lim_superior_outlier = Q3+1.5\\*IQR\n",
+ "3. Proceda à substituição:\n",
+ " * Se a_salarios_copia[i] < lim_inferior_outlier então a_salarios_copia[i]= Mediana\n",
+ " * Se a_salarios_copia[i] > lim_superior_outlier então a_salarios_copia[i]= Mediana\n",
+ "4. Calcule as estatísticas descritivas após as substituições e compare com os valores antes das transformações."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9DQ7YnWaFn4v"
+ },
+ "source": [
+ "### Minha solução\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RBXJbTeGLC7Q"
+ },
+ "source": [
+ "1. Estatísticas Descritivas antes das transformações:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QueKYn7MLG12",
+ "outputId": "75489f71-3f1e-4819-b5fe-21f134bf2b1e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "# Algumas estatísticas descritivas:\n",
+ "f'Média: {np.mean(a_salarios_copia)}; Mediana: {np.median(a_salarios_copia)}; STD: {np.std(a_salarios_copia)}'"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Média: 1057.4744151862524; Mediana: 1048.089607774499; STD: 144.64306489539533'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 35
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oOBJ8INWL5fo"
+ },
+ "source": [
+ "Observe o quanto nossos dados estão distorcidos dos valores originalmente utilizados."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MX-fJeh2MBTD"
+ },
+ "source": [
+ "2. Calcular Q1, Q3 e IQR"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JlsPiQeGMGeU"
+ },
+ "source": [
+ "Q1 = np.percentile(a_salarios_copia, q = [25])\n",
+ "Q3 = np.percentile(a_salarios_copia, q = [75])\n",
+ "Q2 = np.percentile(a_salarios_copia, q = [50])\n",
+ "p99 = np.percentile(a_salarios_copia, q = [99])\n",
+ "p95 = np.percentile(a_salarios_copia, q = [95])\n",
+ "\n",
+ "IQR = Q3-Q1 # Diferença interquartílica\n",
+ "lim_inferior_outlier = Q1-1.5*IQR\n",
+ "lim_superior_outlier = Q3+1.5*IQR"
+ ],
+ "execution_count": 148,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VF2NJ3rCeI1_",
+ "outputId": "34a2097c-334f-472f-9fe0-7198ea827e47",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "f'Q1: {Q1}; Q3: {Q3}; lim_inferior_outlier: {lim_inferior_outlier}; lim_superior_outlier: {lim_superior_outlier}'"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Q1: [974.41]; Q3: [1119.81]; lim_inferior: [756.33]; lim_superior: [1337.89]'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 37
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JjnwJ7HwMxcl"
+ },
+ "source": [
+ "3. Substituir\n",
+ "* Se a_salarios[i] < lim_inferior_outlier --> a_salarios[i] = Mediana\n",
+ "* Se a_salarios[i] > lim_superior_outlier --> a_salarios[i] = Mediana"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hcAn-IwVfbcI"
+ },
+ "source": [
+ "a_salarios2 = a_salarios_copia.copy()"
+ ],
+ "execution_count": 149,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "M4UJY4vbRics",
+ "outputId": "eb6ac1e0-de5a-4545-f955-c4794c699de2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "Q2[0]"
+ ],
+ "execution_count": 150,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "1035.8622742229763"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 150
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J3SSE45oM9oh",
+ "outputId": "0396ad3e-13a7-4680-cc05-7c497fa8e754",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "a_salarios2[a_salarios2 < lim_inferior_outlier[0]] = Q2[0] # Atribuição da Mediana\n",
+ "a_salarios2[a_salarios2 > lim_superior_outlier[0]] = Q2[0] # Atribuição da Mediana\n",
+ "a_salarios2[:30]"
+ ],
+ "execution_count": 151,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 488.91, 1227.09, 641.47, 575.7 , 1664.34, 1254.27, 931.62,\n",
+ " 1550.25, 1242.86, 794.05, 924.31, 1184.53, 723.31, 46.76,\n",
+ " 1035.86, 1323.31, 1480.29, 754.29, 1105.24, 1254.35, 930.3 ,\n",
+ " 889.64, 954.45, 716.47, 848.33, 925.16, 1021.7 , 978.52,\n",
+ " 588.65, 1682.72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 151
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VEGFio0Nfj7O"
+ },
+ "source": [
+ "4. Estatísticas Descritivas para avaliarmos o impacto das alterações na amostra:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gX1LZHFqfjFQ",
+ "outputId": "5b72b7fc-d5ba-4692-c1a7-b3394004004e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "# Algumas estatísticas descritivas - Depois do trtamento de OUtliers:\n",
+ "f'Média: {np.mean(a_salarios2)}; Mediana: {np.median(a_salarios2)}; STD: {np.std(a_salarios2)}'"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Média: 1047.3019702056902; Mediana: 1048.089607774499; STD: 98.3265929249586'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 43
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cSXrg2PFSYKY",
+ "outputId": "fbde7b45-c3b6-4533-cfa8-34ee1cbc40b7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "# Algumas estatísticas descritivas - Antes do trtamento de OUtliers:\n",
+ "f'Média: {np.mean(a_salarios)}; Mediana: {np.median(a_salarios)}; STD: {np.std(a_salarios)}'"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ },
+ "text/plain": [
+ "'Média: 1047.150212238584; Mediana: 1047.631166829137; STD: 101.18708333868835'"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 44
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZVc6_nsGS_J2"
+ },
+ "source": [
+ "### Exercício: Substituir e comentar com seus respectivos colegas de grupo quando substituimos:\n",
+ "* Q2[0] pela média.\n",
+ "* Q2[0] pelo valor do percentil 95 e 99."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-xnguZ7XgyvK",
+ "outputId": "48e05f4e-1b0a-4b6f-97f6-de2d49205697",
+ "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": 152,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 152
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uEPFcBjFhETQ"
+ },
+ "source": [
+ "Como podem ver, os outliers desapareceram, como queríamos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tHfzjW_ymKuR"
+ },
+ "source": [
+ "___\n",
+ "# **Valores únicos**\n",
+ "> Considere o array de a_idades a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HzmQgWZVmUUD",
+ "outputId": "1a594c37-8240-415c-ac4f-a578bee17113",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_idades = np.random.randint(18, 100, 100)\n",
+ "a_idades"
+ ],
+ "execution_count": 153,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([78, 60, 58, 26, 45, 20, 64, 99, 98, 31, 48, 81, 97, 90, 31, 85, 51,\n",
+ " 91, 95, 60, 73, 63, 59, 39, 40, 26, 80, 28, 18, 33, 27, 85, 53, 60,\n",
+ " 26, 44, 23, 86, 92, 75, 58, 40, 63, 24, 99, 18, 43, 68, 98, 94, 47,\n",
+ " 25, 39, 23, 70, 49, 96, 79, 68, 68, 25, 59, 21, 51, 65, 23, 34, 51,\n",
+ " 37, 78, 74, 73, 71, 46, 34, 45, 40, 56, 67, 31, 22, 43, 65, 64, 36,\n",
+ " 76, 19, 82, 75, 35, 38, 68, 43, 73, 91, 92, 61, 37, 73, 72])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 153
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Dm9ky1F1mrNA"
+ },
+ "source": [
+ "Quem são os valores únicos do array?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "G-LPRqc-mS5j",
+ "outputId": "6f8e357e-066d-42f3-a09c-8733ce7fa833",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 85
+ }
+ },
+ "source": [
+ "np.unique(a_idades)"
+ ],
+ "execution_count": 154,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 33, 34, 35, 36, 37,\n",
+ " 38, 39, 40, 43, 44, 45, 46, 47, 48, 49, 51, 53, 56, 58, 59, 60, 61,\n",
+ " 63, 64, 65, 67, 68, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82,\n",
+ " 85, 86, 90, 91, 92, 94, 95, 96, 97, 98, 99])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 154
+ }
+ ]
+ },
+ {
+ "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",
+ "\n",
+ "\n",
+ "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uW6i3m9q1ZNs"
+ },
+ "source": [
+ "\n",
+ "* Vamos ver como isso funciona na prática:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vw05sfe22mfk"
+ },
+ "source": [
+ "## Exemplo 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Qqw2do90nQ7k"
+ },
+ "source": [
+ "a_conjunto1 = np.array([0, 1, 2, 4, 5, 7, 8, 8]) # array de valores que serão excluidos em a_conjunto1. Observe que '3' não pertence a a_conjunto1.\n",
+ "a_conjunto2 = np.array([1, 6, 7, 3])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zXJ00pOMorM-",
+ "outputId": "c3108557-ad55-45cc-f707-3af35cf456c1",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "np.setdiff1d(a_conjunto1, a_conjunto2)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 2, 4, 5, 8])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 50
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8GXZNgjfo8lO"
+ },
+ "source": [
+ "Observe que o resultado são os elementos de a_conjunto1 que não pertencem a x_Y. Mas como fica o '3' nesta história?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "aJSu6VKb2oc_"
+ },
+ "source": [
+ "## Exemplo 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N1wahElXTqoB"
+ },
+ "source": [
+ "a_conjunto1 = np.arange(10)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nxDpCMg7T7Rj"
+ },
+ "source": [
+ "a_conjunto2 = np.array([1, 5, 7])\n",
+ "a_conjunto2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3LU3qYyiUXqm"
+ },
+ "source": [
+ "np.setdiff1d(a_conjunto1, a_conjunto2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mzZEytrRUioU"
+ },
+ "source": [
+ "Observe que os elementos de a_conjunto2 foram deletados de a_conjunto1. Ok?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gJRcoVRUnaY9"
+ },
+ "source": [
+ "___\n",
+ "# Diferença Simétrica\n",
+ "* Em teoria de conjuntos, chamamos de Diferença Simétrica e escrevemos $(A \\cup B)- (A \\cap B)$.\n",
+ "\n",
+ "\n",
+ "\n",
+ "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2Uzzm85Kup3H"
+ },
+ "source": [
+ "* Vamos ver como isso funciona na prática:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1z5wZ8VwpsWN"
+ },
+ "source": [
+ "import numpy as np\n",
+ "a_conjunto1 = np.array([0, 1, 2, 4, 5, 7, 8]) # Observe que [1, 4, 7] pertencem a a_conjunto1, mas 3, não. Portanto:\n",
+ "a_conjunto2 = np.array([1, 4, 7, 3])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Tqd_9XO5p7bo",
+ "outputId": "d7670965-e38f-40a1-9864-8ec850143245",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "np.setxor1d(a_conjunto1, a_conjunto2)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 2, 3, 5, 8])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 52
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_meurG3mqS5Y"
+ },
+ "source": [
+ "Como explicamos ou interpretamos este resultado?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Kc8JoKe2nj2n"
+ },
+ "source": [
+ "___\n",
+ "# **União de dois arrays**\n",
+ "> Retorna os valores **únicos** dos dois arrays. Na teoria dos conjuntos, escrevemos:\n",
+ "\n",
+ "$$A \\cup B$$\n",
+ "\n",
+ "\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",
+ "\n",
+ "\n",
+ "Fonte: [Python Set](https://www.learnbyexample.org/python-set/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "n2ec2tqqR1Gw"
+ },
+ "source": [
+ "* Considere os arrays a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rXVQQvBqR4J-",
+ "outputId": "c1332edd-af01-45cb-d3e1-c6e3ba30e157",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "a_conjunto1 = np.arange(10)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 53
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pZTHhHxGSRfB",
+ "outputId": "2c93501a-3ed8-4297-d58e-990c529a5a3d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "a_conjunto2 = np.arange(8, 18)\n",
+ "a_conjunto2"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 54
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MxB2_qHpScMB"
+ },
+ "source": [
+ "Quais são os elementos comuns à X e Y?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e-rncJHtSfw0",
+ "outputId": "11f0b85d-c634-419a-cc62-e0899f9cef31",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "np.intersect1d(a_conjunto1, a_conjunto2)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 55
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3Bb39sWdfqaF"
+ },
+ "source": [
+ "___\n",
+ "# **Autovalores e Autovetores**\n",
+ "> Autovetor e Autovalor são um dos tópicos mais importantes em Machine Learning.\n",
+ "\n",
+ "Por definição, o escalar $\\lambda$ e o vetor $v$ são autovalor e autovetor da matriz $A$ se\n",
+ "\n",
+ "$$Av = \\lambda v$$\n",
+ "\n",
+ "## Leitura Adicional:\n",
+ "\n",
+ "* [Machine Learning & Linear Algebra — Eigenvalue and eigenvector](https://medium.com/@jonathan_hui/machine-learning-linear-algebra-eigenvalue-and-eigenvector-f8d0493564c9)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XZBKq8nGCUbL"
+ },
+ "source": [
+ "* O array a_conjunto2 tem a seguinte forma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iYlZGKFUfw-R"
+ },
+ "source": [
+ "a_conjunto2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6EfvIbBNf02Z"
+ },
+ "source": [
+ "# Calcula autovalores e autovetores:\n",
+ "a_autovalores, a_autovalores= np.linalg.eig(a_conjunto2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "v3GtQQvAz9QU"
+ },
+ "source": [
+ "Os autovalores do array a_conjunto2 são:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WvZGyBR1f9vP"
+ },
+ "source": [
+ "a_autovalores"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AuuDRJVh0FC8"
+ },
+ "source": [
+ "Os autovetores do array a_conjunto2 são:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6m4YFAwsf_rA"
+ },
+ "source": [
+ "a_autovalores"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DASn2Un9ZNV-"
+ },
+ "source": [
+ "___\n",
+ "# **Encontrar Missing Values (NaN)**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TKilWBsSXtR4"
+ },
+ "source": [
+ "## Gerar o exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lqLI2ER_ZUMY"
+ },
+ "source": [
+ "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": 155,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gw--poMaadv3",
+ "outputId": "115842f8-f789-4ab2-dda2-17eae01d7e70",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "l_indices_aleatorios.sort()\n",
+ "l_indices_aleatorios"
+ ],
+ "execution_count": 158,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 2, 8, 13, 27, 30, 40, 42, 46, 60, 80, 81, 82, 88, 88, 96])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 158
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2ZkbMPXMawYh",
+ "outputId": "7dc30b68-52c8-474c-c070-da8be55f2bf3",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 187
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": 157,
+ "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": 157
+ }
+ ]
+ },
+ {
+ "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": "16f7be91-47f2-4c61-dca1-6b55619f7b17",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.isnan(a_conjunto1).sum()"
+ ],
+ "execution_count": 159,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 159
+ }
+ ]
+ },
+ {
+ "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": "f9f26416-c184-4db9-b114-6521b5a28a8d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "i_indices = np.where(np.isnan(a_conjunto1))\n",
+ "i_indices"
+ ],
+ "execution_count": 160,
+ "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": 160
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "W_jHGNImok7L",
+ "outputId": "703ea6e2-0580-4cfa-9fd0-47531b686215",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Checando...\n",
+ "a_conjunto1[2]"
+ ],
+ "execution_count": 161,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "nan"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 161
+ }
+ ]
+ },
+ {
+ "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": "bc4f82a3-0212-452d-c149-10b119903d8b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 191
+ }
+ },
+ "source": [
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "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": 66
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ck1w6_Tvb72M",
+ "outputId": "c9f3469a-5fcb-4794-882b-9a882871061f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 225
+ }
+ },
+ "source": [
+ "np.isnan(a_conjunto1)"
+ ],
+ "execution_count": null,
+ "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": 67
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e497B492fFru",
+ "outputId": "03020338-a360-4f1f-b025-838b0738509d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 156
+ }
+ },
+ "source": [
+ "a_conjunto1[~np.isnan(a_conjunto1)]"
+ ],
+ "execution_count": null,
+ "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": 68
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RpvKfJU_fmA6"
+ },
+ "source": [
+ "Observe que os NaN's foram excluidos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "60-l91_ccJxt"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kywe-SmtcLpF"
+ },
+ "source": [
+ "### **Exercício**: Atribuir a mediana aos valores nan da amostra."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_Dv8MmNYg8zN"
+ },
+ "source": [
+ "___\n",
+ "# **Converter lista em array**\n",
+ "> Considere a lista a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "but6T9dVhFYb"
+ },
+ "source": [
+ "l_Lista = [np.random.randint(0, 10, 10)]\n",
+ "l_Lista"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xytj4Eo4hTh9"
+ },
+ "source": [
+ "type(l_Lista)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qrINdcruhWcH"
+ },
+ "source": [
+ "Convertendo a minha lista para array:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RoSyaX0OhZSE"
+ },
+ "source": [
+ "a_conjunto = np.asarray(l_Lista)\n",
+ "a_conjunto"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dMjTdbBUhlrk"
+ },
+ "source": [
+ "type(a_conjunto)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Mbm3ZP9DhxDI"
+ },
+ "source": [
+ "___\n",
+ "# Converter tupla em array\n",
+ "> Considere a tupla a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cZxEFYLAh3S_",
+ "outputId": "701203e5-2a45-4dd8-d9fd-ae4fe665ce7d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "t_numeros = ([np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)], [np.random.randint(0, 10, 3)])\n",
+ "t_numeros"
+ ],
+ "execution_count": 162,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "([array([8, 8, 2])], [array([8, 9, 1])], [array([8, 0, 4])])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 162
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vlTXUJviiAml",
+ "outputId": "77a7e854-37de-425e-9cd5-ccfe50702954",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "type(t_numeros)"
+ ],
+ "execution_count": 163,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "tuple"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 163
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yEaOlq8oh3oh",
+ "outputId": "287e061f-2a9f-461b-831d-b3844e301e7a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "a_conjunto = np.asarray(t_numeros)\n",
+ "a_conjunto"
+ ],
+ "execution_count": 164,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[[8, 8, 2]],\n",
+ "\n",
+ " [[8, 9, 1]],\n",
+ "\n",
+ " [[8, 0, 4]]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 164
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PSgQDmRWh3g5",
+ "outputId": "bdcf61ef-a4f5-40b2-def3-e1affcc58446",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "type(a_conjunto)"
+ ],
+ "execution_count": 165,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "numpy.ndarray"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 165
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "pH-Ht6yMiqJN"
+ },
+ "source": [
+ "___\n",
+ "# Acrescentar elementos à um array\n",
+ "> Considere o array a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dFaDZInZiwoo",
+ "outputId": "58f1f504-476b-4641-d24a-4ababdc366c5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_conjunto1 = np.arange(5)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 166,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 166
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "d3zrlf_Ci73Z",
+ "outputId": "0329a4e8-ad8e-4faa-b200-8382e7ecda3b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "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": 167,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 8, 8, 2, 8, 9, 1, 8, 0, 4])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 167
+ }
+ ]
+ },
+ {
+ "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",
+ "outputId": "92cb94a2-f2ac-4717-a4fd-b6cd3cc86f74",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.array(np.random.randint(0, 10, 6))\n",
+ "print(a_conjunto1)"
+ ],
+ "execution_count": 171,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "[8 8 2 8 9 1]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "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": "code",
+ "metadata": {
+ "id": "pfqzCfhHaxsL",
+ "outputId": "17d563dd-3c04-40b2-cc4c-aa5f280bd690",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "##alternativa para exclusão do valor 8 do array\n",
+ "np.random.seed(20113374)\n",
+ "a_conjunto1 = np.array(np.random.randint(0, 10, 6))\n",
+ "print(a_conjunto1)\n",
+ "\n",
+ "#armazena os índices que contém 8\n",
+ "i_indice_excl = np.where(a_conjunto1==8)\n",
+ "\n",
+ "#elimina elementos do array que estejam no índice\n",
+ "a_conjunto1= np.delete(a_conjunto1, i_indice_excl)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": 174,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "[3 3 8 4 5 8]\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([3, 3, 4, 5])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 174
+ }
+ ]
+ },
+ {
+ "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": "169b34a0-56d6-48ea-cffe-fbd7a757372c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 104
+ }
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.array(np.random.randint(0, 10, 100))\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([8, 8, 2, 8, 9, 1, 8, 0, 4, 2, 0, 8, 9, 3, 7, 1, 3, 2, 9, 7, 7, 9,\n",
+ " 5, 6, 8, 7, 0, 9, 3, 9, 3, 1, 8, 6, 3, 5, 4, 1, 2, 9, 8, 6, 6, 1,\n",
+ " 0, 9, 2, 0, 7, 5, 5, 4, 4, 2, 7, 2, 7, 9, 3, 1, 5, 0, 1, 2, 3, 8,\n",
+ " 7, 5, 4, 0, 5, 9, 6, 6, 1, 3, 6, 0, 4, 9, 2, 1, 0, 9, 1, 4, 2, 9,\n",
+ " 7, 9, 5, 3, 7, 6, 3, 9, 8, 4, 3, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 69
+ }
+ ]
+ },
+ {
+ "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": "JhsN15T5cm55"
+ },
+ "source": [
+ "a = np.unique()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6yIlk7pWyAtf",
+ "outputId": "31d8d842-d6c2-4955-a3ed-76ec3badac9a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "l_itens_unicos, i_count = np.unique(a_conjunto1, return_counts = True)\n",
+ "l_itens_unicos"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 70
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DyvrIwS9yZIR"
+ },
+ "source": [
+ "O que significa o output acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uO-MPMhXyV9H",
+ "outputId": "0cb620a1-d0ac-46b5-f379-9b0b563fdd71",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "source": [
+ "i_count"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([10, 10, 10, 11, 8, 8, 8, 10, 10, 15])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 71
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zwoezXrPyofK"
+ },
+ "source": [
+ "Qual a interpretação do output acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HgYycSG7yr5e",
+ "outputId": "2091104b-45db-4d13-d65e-80d8af3acd7f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 52
+ }
+ },
+ "source": [
+ "np.asarray((l_itens_unicos, i_count))"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],\n",
+ " [10, 10, 10, 11, 8, 8, 8, 10, 10, 15]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 72
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SwIZiJAiy06T"
+ },
+ "source": [
+ "Qual a interpretação do output acima?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JpNRpN2Dql3N"
+ },
+ "source": [
+ "___\n",
+ "# **Combinações possíveis de outros arrays**\n",
+ "> Considere o exemplo a seguir:\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BUr89dH4zLXD"
+ },
+ "source": [
+ "a_conjunto1 = [2, 4, 6]\n",
+ "a_conjunto2 = [0, 8]\n",
+ "a_conjunto4 = [1, 5]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cEZH6l-Czx7y"
+ },
+ "source": [
+ "np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "btvmDkEcz0tH"
+ },
+ "source": [
+ "np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Z0xhO7rGz059"
+ },
+ "source": [
+ "np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)).T"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eMv4lFnD0Enn"
+ },
+ "source": [
+ "# Resultado final\n",
+ "a_conjunto3 = np.array(np.meshgrid(a_conjunto1, a_conjunto2, a_conjunto4)).T.reshape(-1,3)\n",
+ "a_conjunto3"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Rz80YANfAh2k"
+ },
+ "source": [
+ "___\n",
+ "# **Wrap Up**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_cyhMsAVXxGC"
+ },
+ "source": [
+ "___\n",
+ "# **Exercícios**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kNjovMw3uJ3R"
+ },
+ "source": [
+ "## Exercício 1 - Selecionar os números pares\n",
+ "> Dado o 1D array abaixo, selecionar somente os números pares."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bRA8nKHBbPAD",
+ "outputId": "849729a5-2223-4118-d34d-e2529f2bce9f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 85
+ }
+ },
+ "source": [
+ "#criar array com 20 elementos variando de 2 a 100\n",
+ "a_cj1 = np.random.randint(2,100,20)\n",
+ "a_cj1.sort()\n",
+ "print(a_cj1)\n",
+ "#seleciona os índices pares\n",
+ "i_ind_pares = np.where(a_cj1 % 2 ==0)\n",
+ "print(i_ind_pares)\n",
+ "#imprime elementos com índices pares\n",
+ "print(a_cj1[i_ind_pares])\n",
+ "#executando de modo direto\n",
+ "print(a_cj1[np.where(a_cj1 % 2 ==0)])"
+ ],
+ "execution_count": 178,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "[ 3 7 8 13 14 20 20 26 32 33 39 42 43 46 57 57 61 67 85 92]\n",
+ "(array([ 2, 4, 5, 6, 7, 8, 11, 13, 19]),)\n",
+ "[ 8 14 20 20 26 32 42 46 92]\n",
+ "[ 8 14 20 20 26 32 42 46 92]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "isDzQjwjBX3V"
+ },
+ "source": [
+ "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Kq1zt-uO1HXv"
+ },
+ "source": [
+ "### **Minha solução**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YFmK_n2M1Ks9"
+ },
+ "source": [
+ "a_conjunto1[a_conjunto1 % 2 == 0]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "sScYG0hp05vb"
+ },
+ "source": [
+ "___\n",
+ "## Exercício 2 - Substituir pela mediana\n",
+ "> Dado o array 1D abaixo, substituir os números pares pela mediana de a_conjunto1."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g-Yq251IcQF9",
+ "outputId": "2e0e249e-9b4b-4178-d092-47bf85ff9cb6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "#criar array com 20 elementos variando de 2 a 100\n",
+ "a_cj1 = np.random.randint(2,100,20)\n",
+ "a_cj1.sort()\n",
+ "print(a_cj1)\n",
+ "#seleciona os índices pares\n",
+ "i_ind_pares = np.where(a_cj1 % 2 ==0)\n",
+ "print(i_ind_pares)\n",
+ "\n",
+ "#substituindo pares por mediana\n",
+ "#i_mediana = np.median(a_cj1)\n",
+ "print(f'Mediana {i_mediana}')\n",
+ "\n",
+ "#a_cj1[i_ind_pares] = i_mediana\n",
+ "\n",
+ "#imprime elementos com índices pares\n",
+ "#print(a_cj1[i_ind_pares])\n",
+ "#print(a_cj1)\n",
+ "\n",
+ "#executando de modo direto\n",
+ "a_cj1[np.where(a_cj1 % 2 ==0)] = np.median(a_cj1)\n",
+ "print(a_cj1[i_ind_pares])\n",
+ "print(a_cj1)\n"
+ ],
+ "execution_count": 182,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "[ 2 11 11 24 27 30 33 39 42 44 53 67 67 73 76 83 83 85 89 90]\n",
+ "(array([ 0, 3, 5, 8, 9, 14, 19]),)\n",
+ "Mediana 48.5\n",
+ "[48 48 48 48 48 48 48]\n",
+ "[48 11 11 48 27 48 33 39 48 48 53 67 67 73 48 83 83 85 89 48]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XLZ-DIWU1WFs"
+ },
+ "source": [
+ "a_conjunto1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9c4QWJno1WVB"
+ },
+ "source": [
+ "### **Minha solução**\n",
+ "* Primeiramente, precisamos calcular a mediana.\n",
+ "* Depois, substituimos os valores pares de a_conjunto1 pela mediana encontrada anteriormente. Ok?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rx7NGAO01Wfb"
+ },
+ "source": [
+ "a_conjunto1[a_conjunto1 % 2 == 0] = np.median(a_conjunto1)\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2c_AphX82qp8"
+ },
+ "source": [
+ "Verificando..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9kVta0Cr13Z9"
+ },
+ "source": [
+ "f'A média de a_conjunto1 é: {np.median(a_conjunto1)}'"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "L9O-Hf5x26TY"
+ },
+ "source": [
+ "___\n",
+ "## Exercício 3 - Reshape\n",
+ "> Dado o array 1D abaixo, reshape para um array 2D com 3 colunas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0_laUvtB4Wl-"
+ },
+ "source": [
+ "# Define seed\n",
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.array(np.random.randint(1, 10, size = 15))\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dKzEX8TK5b4Z"
+ },
+ "source": [
+ "### **Minha solução**\n",
+ "* O array 1D a_conjunto1 acima possui 15 elementos. Como queremos transformá-lo num array 2D com 3 colunas, então cada coluna terá 5 elementos."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I-j5yVD04249"
+ },
+ "source": [
+ "a_conjunto1.reshape(5, 3) \n",
+ "# Poderia ser a_conjunto1.reshape(-1, 3), onde \"-1\" pede para o NumPy calcular o número de linhas. "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F1vfS8jE6L0_"
+ },
+ "source": [
+ "___\n",
+ "## Exercício 4 - Reshape\n",
+ "> Dado o array 1D abaixo, reshape para um array 3D com 2 colunas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xcN-bez56L1D"
+ },
+ "source": [
+ "# Define seed\n",
+ "np.random.seed(20111974)\n",
+ "a_conjunto1 = np.array(np.random.randint(1, 10, size = 16))\n",
+ "a_conjunto1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7iICnOyG6fcj"
+ },
+ "source": [
+ "### **Minha solução**\n",
+ "* O array 1D a_conjunto1 acima possui 16 elementos. Queremos transformá-lo num array 3D com 2 colunas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vdq5ybuD6fcn"
+ },
+ "source": [
+ "a_conjunto1.reshape(-1, 2) # O valor \"-1\" na posição das linhas pede ao NumPy para calcular o número de linhas automaticamente."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "haQfWPcCs_H0"
+ },
+ "source": [
+ "## Exercício 5\n",
+ "Para mais exercícios envolvendo arrays, visite a página [Python: Array Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/array/)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LQQL0JS2tnc0"
+ },
+ "source": [
+ "## Exercício 6\n",
+ "Para mais exercícios envolvendo matemática, viste a página [Python Math: - Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/math/index.php)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qNskKFy9t4D5"
+ },
+ "source": [
+ "## Exercício 7\n",
+ "Para mais exercícios envolvendo NumPy em geral, visite a página [NumPy Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/numpy/index.php)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qqc1AiHXuKZ5"
+ },
+ "source": [
+ "## Exercício 8\n"
+ ]
+ }
+ ]
+}
\ No newline at end of file
From cb93ec3045e84eaaaf3a7069c63d5a2e4e6a3156 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Fri, 16 Oct 2020 15:02:53 -0300
Subject: [PATCH 08/21] Criado usando o Colaboratory
---
Notebooks/NB10_01__Pandas_Fifa.ipynb | 55 +++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/Notebooks/NB10_01__Pandas_Fifa.ipynb b/Notebooks/NB10_01__Pandas_Fifa.ipynb
index e3813afea..9ae31c427 100644
--- a/Notebooks/NB10_01__Pandas_Fifa.ipynb
+++ b/Notebooks/NB10_01__Pandas_Fifa.ipynb
@@ -729,7 +729,7 @@
"id": "eHvPpeiTBwoR"
},
"source": [
- "d_estudantes['nome']"
+ "d_estudantes['Nome']"
],
"execution_count": null,
"outputs": []
@@ -749,7 +749,7 @@
"id": "26WIDl-HB3Bq"
},
"source": [
- "d_estudantes['nome'][0]"
+ "d_estudantes['Nome'][0]"
],
"execution_count": null,
"outputs": []
@@ -5281,7 +5281,7 @@
"id": "K7xLrlPuKsAW"
},
"source": [
- "df_Fifa2018.head()\n",
+ "df_Fifa2018.head(5)\n",
"\n"
],
"execution_count": null,
@@ -5304,6 +5304,9 @@
"id": "1y9oN-IeU7Sb"
},
"source": [
+ "'''\n",
+ "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo; 6Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n",
+ "'''\n",
"def transformacao_lower(df):\n",
" # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
" df_Fifa2018.columns = [col.lower() for col in df.columns]\n"
@@ -5318,7 +5321,7 @@
},
"source": [
"transformacao_lower(df_Fifa2018)\n",
- "df_Fifa2018.head()"
+ "df_Fifa2018.head(5)"
],
"execution_count": null,
"outputs": []
@@ -5374,6 +5377,9 @@
"id": "OBuycRCzRbyG"
},
"source": [
+ "'''\n",
+ "02 Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n",
+ "'''\n",
"del df_Fifa2018['photo']"
],
"execution_count": null,
@@ -5418,6 +5424,9 @@
"id": "ZPwu5sLnSyAc"
},
"source": [
+ "'''\n",
+ "03. Qual o dtype de cada variável/atributo do dataframe?\n",
+ "'''\n",
"df_Fifa2018.dtypes"
],
"execution_count": null,
@@ -5429,6 +5438,9 @@
"id": "PBq3jr8nTUS0"
},
"source": [
+ "'''\n",
+ "05 Se alguma variávável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n",
+ "'''\n",
"df_Fifa2018.select_dtypes(include=['object', 'string']).columns "
],
"execution_count": null,
@@ -5440,7 +5452,40 @@
"id": "82JaHKYATgdD"
},
"source": [
- "df_Fifa2018[df_Fifa2018.select_dtypes(include=['object', 'string']).columns ]"
+ "df_Fifa2018[df_Fifa2018.select_dtypes(include=['object', 'string']).columns].head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "clV9YL8RkKI_"
+ },
+ "source": [
+ "df_Fifa2018[['name','value']].head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cbzgZuAtlXpl"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YPp5kJDhkfWt"
+ },
+ "source": [
+ ""
],
"execution_count": null,
"outputs": []
From 9c442fa7e51b2bb08116bebadc2acc291a38250f Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Fri, 16 Oct 2020 17:32:49 -0300
Subject: [PATCH 09/21] Criado usando o Colaboratory
---
...3DP_3_Data_Transformation_exercicios.ipynb | 1314 +++++++++++++++++
1 file changed, 1314 insertions(+)
create mode 100644 Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
new file mode 100644
index 000000000..0ac9de626
--- /dev/null
+++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
@@ -0,0 +1,1314 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "NB10_04__3DP_3_Data_Transformation.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5CgDLvphxfcX"
+ },
+ "source": [
+ "3DP_3 - DATA TRANSFORMATION
\n",
+ "\n",
+ "* **Objetivo**: Preparar os dados para o Machine Learning."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PvW689ZBxbxH"
+ },
+ "source": [
+ "# **AGENDA**:\n",
+ "\n",
+ "> Consulte **Table of contents**.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GNiuYCCxGe8v"
+ },
+ "source": [
+ "# **Melhorias da sessão**\n",
+ "* Desenvolver a sessão sobe WOE."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-TdSY74U0XS9"
+ },
+ "source": [
+ "___\n",
+ "# **Referências**\n",
+ "* [Why, How and When to Scale your Features](https://medium.com/greyatom/why-how-and-when-to-scale-your-features-4b30ab09db5e)\n",
+ "* [Demonstrating the different strategies of KBinsDiscretizer](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_strategies.html#sphx-glr-auto-examples-preprocessing-plot-discretization-strategies-py);\n",
+ "* [Why do we need feature scaling in Machine Learning and how to do it using SciKit Learn?](https://medium.com/@contactsunny/why-do-we-need-feature-scaling-in-machine-learning-and-how-to-do-it-using-scikit-learn-d8314206fe73)\n",
+ "* [Importance of Feature Scaling](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html#sphx-glr-auto-examples-preprocessing-plot-scaling-importance-py) --> Muito importante por demonstrar os efeitos e a importância de se transformar as colunas numéricas.\n",
+ "* [Feature discretization](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_classification.html#sphx-glr-auto-examples-preprocessing-plot-discretization-classification-py) --> Mostra o impacto na acurácia dos modelos com e sem discretização. Ou seja, discretizar faz sentido!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "l9DGifbWSmW3"
+ },
+ "source": [
+ "___\n",
+ "# **Machine Learning com Python (Scikit-Learn)**\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Vg82Iouo_Qm2"
+ },
+ "source": [
+ "# Porque dimensionar (Scale), padronizar (Standardize) e normalizar (Normalize) importa?\n",
+ "* Porque muitos algoritmos de Machine Learning performam melhor ou convergem mais rápido quando os atributos/colunas/variáveis estão na mesma escala e possuem distribuição \"próxima\" da Normal."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "q-chlATnKSza"
+ },
+ "source": [
+ "## Carregar as bibliotecas (genéricas) Python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kQGVQB18-tM_"
+ },
+ "source": [
+ "#!pip install category_encoders\n",
+ "#!pip install update"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7FJxrZckYxk6"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "%matplotlib inline\n",
+ "\n",
+ "import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n",
+ "\n",
+ "# remove warnings to keep notebook clean\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CyuWQM2NTMls"
+ },
+ "source": [
+ "pd.options.display.float_format = '{:.2f}'.format"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R0fuDyI8_UPf"
+ },
+ "source": [
+ "## Carregar os dados"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9oRWtarakgMY"
+ },
+ "source": [
+ "### Dataframe gerado aleatoriamente - variáveis com distribuição Normal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7BXPXo3k0VDI"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "i_N = 10000\n",
+ "\n",
+ "df_A1 = pd.DataFrame({\n",
+ " 'coluna1': np.random.normal(0, 2, i_N), # Observem que a média das colunas são distintas\n",
+ " 'coluna2': np.random.normal(50, 3, i_N),\n",
+ " 'coluna3': np.random.normal(-5, 5, i_N),\n",
+ " 'coluna4': np.random.normal(-10, 10, i_N)\n",
+ "})\n",
+ "\n",
+ "df_A1.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "93ST1JnoRZKm"
+ },
+ "source": [
+ "**Dica**: Podemos usar outras distribuições (se quisermos), como a Exponential (mostrada abaixo)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XUqjo5QcQH99"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "df_A2 = pd.DataFrame({\n",
+ " 'coluna1': np.random.normal(0, 2, i_N),\n",
+ " 'coluna2': np.random.normal(50, 3, i_N),\n",
+ " 'coluna3': np.random.exponential(1, i_N), # coluna3 tem distribuição Exponential\n",
+ " 'coluna4': np.random.normal(-10, 10, i_N)\n",
+ "})\n",
+ "\n",
+ "df_A2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "J8MZNLbUkp8R"
+ },
+ "source": [
+ "### Dataframe gerado aleatoriamente 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BR-fDDujcTup"
+ },
+ "source": [
+ "from sklearn.datasets import make_classification\n",
+ "\n",
+ "dados, classe = make_classification(n_samples = i_N, n_features = 4, n_informative = 3, n_redundant = 1, n_classes = 3)\n",
+ "\n",
+ "df_A3 = pd.DataFrame({'coluna1': dados[:,0],\n",
+ " 'coluna2':dados[:,1],\n",
+ " 'coluna3':dados[:,2],\n",
+ " 'coluna4':dados[:,3]}) #, 'coluna5':classe})\n",
+ "\n",
+ "df_A3.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Zq1cnpwLKvjS"
+ },
+ "source": [
+ "df_A4 = pd.DataFrame({ \n",
+ " 'coluna1': np.random.beta(5, 1, i_N) * 25, \n",
+ " 'coluna2': np.random.exponential(10, i_N),\n",
+ " 'coluna3': np.random.normal(10, 2, i_N),\n",
+ " 'coluna4': np.random.normal(10, 10, i_N), \n",
+ "})\n",
+ "\n",
+ "df_A4.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "O7sXQjvYRfhb"
+ },
+ "source": [
+ "#### Extração de amostras para compararmos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rjVHsnnHRkIo"
+ },
+ "source": [
+ "df_A1_test = df_A1.sample(n = 100)\n",
+ "df_A2_test = df_A2.sample(n = 100)\n",
+ "df_A3_test = df_A3.sample(n = 100)\n",
+ "df_A4_test = df_A4.sample(n = 100)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "t0v0uXFRl-yG"
+ },
+ "source": [
+ "___\n",
+ "# **Transformações**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "pkzTO0fdz93b"
+ },
+ "source": [
+ "## (1) StandardScaler\n",
+ "* StandardScaler é a transformação que centraliza os dados através da remoção da média (dos dados) e, na sequência, redimensiona (scale) através da divisão pelo desvio-padrão;\n",
+ "* Após a transformação, os dados terão média zero e desvio-padrão 1;\n",
+ "* Assume que os dados (as colunas a serem transformadas) são normalmente distribuidos ;\n",
+ "* Se os dados não possuem distribuição Normal, então esta não é uma boa transformação a se aplicar.\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-mean(x)}{std(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "v1UOOWeQ0R_Y"
+ },
+ "source": [
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y1Lzx3xN6wpZ"
+ },
+ "source": [
+ "df_A3.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9cPq_7Vu2HCS"
+ },
+ "source": [
+ "Histograma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZYW9WwBC3hd_"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_A1['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('Histograma da coluna3')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "h8ogcQvvT5zK"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('Histograma da coluna3')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RrgxkESc-Uaq"
+ },
+ "source": [
+ "Considere o gráfico a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U7dHTF1W-Xsn"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hMS72n14-hDO"
+ },
+ "source": [
+ "Qual a interpretação para o gráfico acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "izqGNcNILdaX"
+ },
+ "source": [
+ "df_A1.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZEkAqlZg-p0v"
+ },
+ "source": [
+ "A seguir, a transformação StandardScaler:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N4u3T_BX-oc_"
+ },
+ "source": [
+ "from sklearn.preprocessing import StandardScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "voFQ4odSzzPZ"
+ },
+ "source": [
+ "O ideal é termos um array com as preditoras, da seguinte forma:\n",
+ "X = [coluna1, coluna2, ..., colunaN]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rPa4-SCt-ynX"
+ },
+ "source": [
+ "np.set_printoptions(precision = 3)\n",
+ "\n",
+ "A1_scale = StandardScaler().fit_transform(df_A1) # Combinação dos métodos fit() + transform()\n",
+ "\n",
+ "A1_scale_fit = StandardScaler().fit(df_A1) # Aplica o fit() separadamente\n",
+ "A1_scale_transform = A1_scale_fit.transform(df_A1) # Aplica o transform() separadamente.\n",
+ "A1_scale_fit_transform = StandardScaler().fit(df_A1).transform(df_A1) # Aplica fit().transform() encadeado\n",
+ "\n",
+ "A2_scale = StandardScaler().fit_transform(df_A2)\n",
+ "\n",
+ "A3_scale = StandardScaler().fit_transform(df_A3)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SGR9-bG0q-SI"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ioZ_IN3Z6d39"
+ },
+ "source": [
+ "Observe abaixo que A1_scale = A1_scale_transform = A1_scale_fit_transform --> São arrays multidimensionais (do tipo NumPy)!\n",
+ "\n",
+ "**é importante salvar as medidas de StandardScaler e outros para não ser necessário reprocessar os valores para todo processamento.**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v4xQR4cu5D1J"
+ },
+ "source": [
+ "A1_scale"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "j6GtN2KF4E_A"
+ },
+ "source": [
+ "A1_scale_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0q2bvSqb6T4g"
+ },
+ "source": [
+ "A1_scale_fit_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WIhaErnA46Fi"
+ },
+ "source": [
+ "Transformando em dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HAhRvPze44JW"
+ },
+ "source": [
+ "df_A1_scale = pd.DataFrame(A1_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "df_A2_scale = pd.DataFrame(A2_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "df_A3_scale = pd.DataFrame(A3_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bmQp8wDO_E88"
+ },
+ "source": [
+ "Agora compare esse novo gráfico abaixo --> Vemos que os dados transformados tem distribuição Normal(0, 1):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "csfqRhDH2zUb"
+ },
+ "source": [
+ "df_A1.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-krh1pDg22RF"
+ },
+ "source": [
+ "df_A1_scale.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D2fTPWsm_Hq3"
+ },
+ "source": [
+ "df_A1_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9oN-829l3277"
+ },
+ "source": [
+ "df_A2.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Jqh8L5BeUHT-"
+ },
+ "source": [
+ "df_A2_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Yvz6O1zk4XNE"
+ },
+ "source": [
+ "df_A3.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ffU-fQxCUSmm"
+ },
+ "source": [
+ "df_A3_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "y24MOLL83w9j"
+ },
+ "source": [
+ "### Exercício: Calcular a média e o desvio-padrão."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1Aa25gVlSdOi"
+ },
+ "source": [
+ "df_A1.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EXZUiZImSmOE"
+ },
+ "source": [
+ "df_A1_scale.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uIUQw5dpRwvA"
+ },
+ "source": [
+ "#### Correlação das colunas\n",
+ "* Observe que as correlações entre as variáveis não se alteram com as transformações."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uj1UerjORq9q"
+ },
+ "source": [
+ "df_A1.corr()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jp6vPK0aR_p0"
+ },
+ "source": [
+ "df_A1_scale.corr()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4fuURrao_M0c"
+ },
+ "source": [
+ "Qual a conclusão?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "f0A9U7rs_RAT"
+ },
+ "source": [
+ "## (2) MinMaxScaler\n",
+ "* **Transformação muito popular e utilizada**.\n",
+ "* Transforma os dados para o intervalo (0, 1);\n",
+ "* Se StandardScaler não é aplicável, então essa transformação funciona bem.\n",
+ "* Sensível aos outliers. Portanto, o ideal é que os outliers sejam tratados previamente.\n",
+ "* Uma transformação similar à MinMaxScaler() é MaxAbsScaler() que redimensiona os dados no intervalo [-1, 1], centralizado em 0(zero)\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-min(x)}{max(x)-min(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "C0HbeuP-AU_p"
+ },
+ "source": [
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mgeLckzxAWaC"
+ },
+ "source": [
+ "from sklearn.preprocessing import MinMaxScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "S_W9bTO2AbEg"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PJRFbUpBAg5J"
+ },
+ "source": [
+ "A1_MinMaxScaler = MinMaxScaler().fit_transform(df_A1)\n",
+ "df_A1_MinMaxScaler = pd.DataFrame(A1_MinMaxScaler,columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_A1_MinMaxScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7g8GA4LTA40U"
+ },
+ "source": [
+ "Qual a conclusão?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4Z6D3vfnB9Nm"
+ },
+ "source": [
+ "## (3) RobustScaler\n",
+ "* Transformação ideal para dados com outliers.\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-Q_{1}(x)}{Q_{3}(x)-Q_{1}(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m3oyuxLeCW1D"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zeDF7-w_CcBy"
+ },
+ "source": [
+ "from sklearn.preprocessing import RobustScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vLoqSKijCf2v"
+ },
+ "source": [
+ "A1_RobustScaler = RobustScaler().fit_transform(df_A1)\n",
+ "df_A1_RobustScaler = pd.DataFrame(A1_RobustScaler, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_A1_RobustScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-YVMgt-WEFif"
+ },
+ "source": [
+ "## Encoding Variáveis Categóricas"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xHYvLc8T_jxQ"
+ },
+ "source": [
+ "### Encoding Variáveis Ordinais\n",
+ "* Exemplo: Variáveis com valores ordinais: baixo, médio ou alto."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "i1BgGiGdSTcG"
+ },
+ "source": [
+ "#### Gera um dataframe como exemplo."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kdVahfJAEkuO"
+ },
+ "source": [
+ "# Aqui vou usar a função randint - Retorna números inteiros aleatórios incluindo o número inferior e excluindo o superior.\n",
+ "\n",
+ "l_idade= [np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40),\n",
+ " np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40)]\n",
+ "\n",
+ "l_salario = ['baixo', 'medio', 'alto']\n",
+ "l_salario2 = np.random.choice(l_salario, 10, p = [0.6, 0.3, 0.1])\n",
+ "\n",
+ "df_A4 = pd.DataFrame({\n",
+ " 'idade': l_idade,\n",
+ " 'salario': l_salario2})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m_15P2eUHSBY"
+ },
+ "source": [
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R1g9pEuyHe2q"
+ },
+ "source": [
+ "Neste exemplo, vamos redefinir a variável categórical ordinal 'Salario' da seguinte forma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bkwFuEa8HnMV"
+ },
+ "source": [
+ "df_A4['salario_cat'] = df_A4['salario'].map({'baixo': 1, 'medio': 2, 'alto': 3})\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DlaIFiWIIPAl"
+ },
+ "source": [
+ "### Encoding Variáveis Nominais\n",
+ "* Exemplo: Variáveis com valores nominais: Sexo (Feminino, Masculino).\n",
+ "\n",
+ "* Use One-Hot Encoding ou pd.get.dummies()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ffNoJQbgJRoY"
+ },
+ "source": [
+ "Vamos utilizar o dataframe criado no passo anterior:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PMCoUWZOI7c0"
+ },
+ "source": [
+ "df_A4['salario'].unique()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bdIEyBkaJeN8"
+ },
+ "source": [
+ "from sklearn.preprocessing import LabelEncoder, OneHotEncoder"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4MwK4cUEKeK4"
+ },
+ "source": [
+ "#### Aplicar LabelEncoder()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6X6VXDsHJiII"
+ },
+ "source": [
+ "le = LabelEncoder()\n",
+ "df_A4['salario_le'] = le.fit_transform(df_A4['salario'])\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RY80x59J8Ham"
+ },
+ "source": [
+ "df_A4['salario'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Dgv2Zz07Kqfj"
+ },
+ "source": [
+ "#### Aplicar pd.get.dummies()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WSZRIEs6K5sP"
+ },
+ "source": [
+ "dummies = pd.get_dummies(df_A4['salario'])\n",
+ "df_A4 = pd.concat([df_A4, dummies], axis = 1)\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CY8GZ-HlNOgm"
+ },
+ "source": [
+ "*texto em itálico*# **Wrap Up**\n",
+ "\n",
+ "\n",
+ "* Use MinMaxScaler como transformação default, pois esta transformação não distorce os dados;\n",
+ "* Use RobustScaler se seus dados/coluna/variável possui outliers e gostaríamos de reduzir o efeito/impacto destes outliers. Entretanto, o melhor tratamento é estudar os outliers cuidadosamente e tratá-los adequadamente;\n",
+ "* Use StandardScaler se seus dados/colunas/variáveis possuem distribuição Normal (ou pelo menos se aproxima bem da distribuição Normal)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Mwh0alhdgrE3"
+ },
+ "source": [
+ "___\n",
+ "# **Exercícios**\n",
+ "> Para cada um dos dataframes a seguir, aplique os seguintes steps:\n",
+ "\n",
+ "* Padronizar o nome das colunas\n",
+ " * Eliminar espaços entre os nomes das colunas;\n",
+ " * Eliminar caracteres especiais dos nomes das colunas;\n",
+ " * Renomear as colunas com lower() (ou upper());\n",
+ "* Aplicar a trasformação StandardScaler e MinMaxScaler em cada uma das colunas do dataframe;\n",
+ "* DataViz - Mostrar a distribuição das colunas para compararmos os resultados antes e depois das transformações.\n",
+ "* As correlações das colunas mudam com as transformações?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hSTKrd992LtI"
+ },
+ "source": [
+ "## Exercício 1 - Iris --> **Resolvido**\n",
+ "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mThqvGGr2Vuk"
+ },
+ "source": [
+ "from sklearn.datasets import load_iris\n",
+ "\n",
+ "iris = load_iris()\n",
+ "X= iris['data']\n",
+ "y= iris['target']\n",
+ "\n",
+ "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n",
+ "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n",
+ "df_iris.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eU5FaJhdYblP"
+ },
+ "source": [
+ "df_iris.columns = [c.replace(' ', '_') for c in df_iris.columns]\n",
+ "df_iris.columns = [c.replace('_(cm)', '') for c in df_iris.columns]\n",
+ "df_iris.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PGmZjd_Y79lY"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "K9DPAakJZQHH"
+ },
+ "source": [
+ "df_iris.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YYYmVq68Y8bB"
+ },
+ "source": [
+ "# Aplica a transformação:\n",
+ "df_iris_MinMaxScaler = MinMaxScaler().fit_transform(df_iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']])\n",
+ "\n",
+ "# Transformando em Dataframe:\n",
+ "df_iris_MinMaxScaler = pd.DataFrame(df_iris_MinMaxScaler, columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_iris_MinMaxScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IwPH8-258JrF"
+ },
+ "source": [
+ "aplicar as outras transformações e comparar os gráficos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "caFkC6oCmUKK"
+ },
+ "source": [
+ "## Exercício 2 - Breast Cancer"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vhOM-Z9zmf-f"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from sklearn.datasets import load_breast_cancer\n",
+ "\n",
+ "cancer = load_breast_cancer()\n",
+ "X= cancer['data']\n",
+ "y= cancer['target']\n",
+ "\n",
+ "df_A1_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n",
+ "df_A1_cancer['target'] = df_A1_cancer['target'].map({0: 'malign', 1: 'benign'})\n",
+ "df_A1_cancer.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1qruqUDqnvMc"
+ },
+ "source": [
+ "## Exercício 3 - Boston Housing Price"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "trxK8YXNnsam"
+ },
+ "source": [
+ "from sklearn.datasets import load_boston\n",
+ "\n",
+ "boston = load_boston()\n",
+ "X= boston['data']\n",
+ "y= boston['target']\n",
+ "\n",
+ "df_A1_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n",
+ "df_A1_boston.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nzu0Dz33c8ds"
+ },
+ "source": [
+ "## Exercícios 4 - Diabetes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "d6ahBZmqc_-1"
+ },
+ "source": [
+ "from sklearn.datasets import load_diabetes\n",
+ "\n",
+ "diabetes = load_diabetes()\n",
+ "X= diabetes['data']\n",
+ "y= diabetes['target']\n",
+ "\n",
+ "df_A1_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n",
+ "df_A1_diabetes.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NyunIr6oaWEl"
+ },
+ "source": [
+ "## Exercícios 6 - 120 years of Olympic history: athletes and results\n",
+ "* [120 years of Olympic history: athletes and results](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)\n",
+ " * Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n",
+ " * Aplique as transformações que acabamos de estudar nos campos/colunas numéricas 'height' e 'weight'. Cuidado com os Missing Values contidos nas variáveis!\n",
+ " * Verifique/avalie o impacto dos outliers nestas colunas.\n",
+ " * Neste caso, qual transformação é mais adequado diante dos outliers?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o5fDp1Ib_Dg8"
+ },
+ "source": [
+ "# WOE - Weight Of Evidence\n",
+ "* As vantagens da transformação WOE são\n",
+ " * Lida bem com NaN's;\n",
+ " * Lida bem com outliers;\n",
+ " * A transformação é baseada no valor logarítmico das distribuições.\n",
+ " * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wXEsP96A9TSd"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "%matplotlib inline\n",
+ "\n",
+ "#import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n",
+ "\n",
+ "# remove warnings to keep notebook clean\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gGdOGDZAHu-V"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Z2W9PXAc-vHY"
+ },
+ "source": [
+ "from google.colab import drive\n",
+ "drive.mount('/content/drive', force_remount=True)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g45JU2LXHwkz"
+ },
+ "source": [
+ "import pandas as pd \n",
+ "df=pd.read_csv('gdrive/My Drive/athlete_events.zip', compression='zip')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JLxrnkJw_f7m"
+ },
+ "source": [
+ "pd.read_csv('/content/drive/My Drive/file/d/athlete_events.zip', compression='zip')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WcPQhh04E2du"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From ace6545c39971edf7798503b90f0275850dfef78 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Fri, 16 Oct 2020 17:35:07 -0300
Subject: [PATCH 10/21] Criado usando o Colaboratory
---
.../NB10_04__3DP_3_Data_Transformation_exercicios.ipynb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
index 0ac9de626..ddc2ee109 100644
--- a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
+++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
@@ -1282,8 +1282,9 @@
"id": "g45JU2LXHwkz"
},
"source": [
- "import pandas as pd \n",
- "df=pd.read_csv('gdrive/My Drive/athlete_events.zip', compression='zip')"
+ "url = '/content/drive/My Drive/athlete_events.csv'\n",
+ "import pandas as pd\n",
+ "df_olympics = pd.read_csv(url)"
],
"execution_count": null,
"outputs": []
From b9811c398dca8a47084883f53beffc5b2b3f55cb Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 19 Oct 2020 14:54:57 -0300
Subject: [PATCH 11/21] Criado usando o Colaboratory
---
...xercicios_exerc\303\255cio Olympics.ipynb" | 1478 +++++++++++++++++
1 file changed, 1478 insertions(+)
create mode 100644 "Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
diff --git "a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb" "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
new file mode 100644
index 000000000..92769c16a
--- /dev/null
+++ "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
@@ -0,0 +1,1478 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "NB10_04__3DP_3_Data_Transformation.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5CgDLvphxfcX"
+ },
+ "source": [
+ "3DP_3 - DATA TRANSFORMATION
\n",
+ "\n",
+ "* **Objetivo**: Preparar os dados para o Machine Learning."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PvW689ZBxbxH"
+ },
+ "source": [
+ "# **AGENDA**:\n",
+ "\n",
+ "> Consulte **Table of contents**.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GNiuYCCxGe8v"
+ },
+ "source": [
+ "# **Melhorias da sessão**\n",
+ "* Desenvolver a sessão sobe WOE."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-TdSY74U0XS9"
+ },
+ "source": [
+ "___\n",
+ "# **Referências**\n",
+ "* [Why, How and When to Scale your Features](https://medium.com/greyatom/why-how-and-when-to-scale-your-features-4b30ab09db5e)\n",
+ "* [Demonstrating the different strategies of KBinsDiscretizer](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_strategies.html#sphx-glr-auto-examples-preprocessing-plot-discretization-strategies-py);\n",
+ "* [Why do we need feature scaling in Machine Learning and how to do it using SciKit Learn?](https://medium.com/@contactsunny/why-do-we-need-feature-scaling-in-machine-learning-and-how-to-do-it-using-scikit-learn-d8314206fe73)\n",
+ "* [Importance of Feature Scaling](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html#sphx-glr-auto-examples-preprocessing-plot-scaling-importance-py) --> Muito importante por demonstrar os efeitos e a importância de se transformar as colunas numéricas.\n",
+ "* [Feature discretization](https://scikit-learn.org/stable/auto_examples/preprocessing/plot_discretization_classification.html#sphx-glr-auto-examples-preprocessing-plot-discretization-classification-py) --> Mostra o impacto na acurácia dos modelos com e sem discretização. Ou seja, discretizar faz sentido!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "l9DGifbWSmW3"
+ },
+ "source": [
+ "___\n",
+ "# **Machine Learning com Python (Scikit-Learn)**\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Vg82Iouo_Qm2"
+ },
+ "source": [
+ "# Porque dimensionar (Scale), padronizar (Standardize) e normalizar (Normalize) importa?\n",
+ "* Porque muitos algoritmos de Machine Learning performam melhor ou convergem mais rápido quando os atributos/colunas/variáveis estão na mesma escala e possuem distribuição \"próxima\" da Normal."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "q-chlATnKSza"
+ },
+ "source": [
+ "## Carregar as bibliotecas (genéricas) Python"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kQGVQB18-tM_"
+ },
+ "source": [
+ "#!pip install category_encoders\n",
+ "#!pip install update"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7FJxrZckYxk6"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "%matplotlib inline\n",
+ "\n",
+ "import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n",
+ "\n",
+ "# remove warnings to keep notebook clean\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CyuWQM2NTMls"
+ },
+ "source": [
+ "pd.options.display.float_format = '{:.2f}'.format"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R0fuDyI8_UPf"
+ },
+ "source": [
+ "## Carregar os dados"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9oRWtarakgMY"
+ },
+ "source": [
+ "### Dataframe gerado aleatoriamente - variáveis com distribuição Normal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7BXPXo3k0VDI"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "i_N = 10000\n",
+ "\n",
+ "df_A1 = pd.DataFrame({\n",
+ " 'coluna1': np.random.normal(0, 2, i_N), # Observem que a média das colunas são distintas\n",
+ " 'coluna2': np.random.normal(50, 3, i_N),\n",
+ " 'coluna3': np.random.normal(-5, 5, i_N),\n",
+ " 'coluna4': np.random.normal(-10, 10, i_N)\n",
+ "})\n",
+ "\n",
+ "df_A1.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "93ST1JnoRZKm"
+ },
+ "source": [
+ "**Dica**: Podemos usar outras distribuições (se quisermos), como a Exponential (mostrada abaixo)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XUqjo5QcQH99"
+ },
+ "source": [
+ "np.random.seed(20111974)\n",
+ "\n",
+ "df_A2 = pd.DataFrame({\n",
+ " 'coluna1': np.random.normal(0, 2, i_N),\n",
+ " 'coluna2': np.random.normal(50, 3, i_N),\n",
+ " 'coluna3': np.random.exponential(1, i_N), # coluna3 tem distribuição Exponential\n",
+ " 'coluna4': np.random.normal(-10, 10, i_N)\n",
+ "})\n",
+ "\n",
+ "df_A2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "J8MZNLbUkp8R"
+ },
+ "source": [
+ "### Dataframe gerado aleatoriamente 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BR-fDDujcTup"
+ },
+ "source": [
+ "from sklearn.datasets import make_classification\n",
+ "\n",
+ "dados, classe = make_classification(n_samples = i_N, n_features = 4, n_informative = 3, n_redundant = 1, n_classes = 3)\n",
+ "\n",
+ "df_A3 = pd.DataFrame({'coluna1': dados[:,0],\n",
+ " 'coluna2':dados[:,1],\n",
+ " 'coluna3':dados[:,2],\n",
+ " 'coluna4':dados[:,3]}) #, 'coluna5':classe})\n",
+ "\n",
+ "df_A3.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Zq1cnpwLKvjS"
+ },
+ "source": [
+ "df_A4 = pd.DataFrame({ \n",
+ " 'coluna1': np.random.beta(5, 1, i_N) * 25, \n",
+ " 'coluna2': np.random.exponential(10, i_N),\n",
+ " 'coluna3': np.random.normal(10, 2, i_N),\n",
+ " 'coluna4': np.random.normal(10, 10, i_N), \n",
+ "})\n",
+ "\n",
+ "df_A4.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "O7sXQjvYRfhb"
+ },
+ "source": [
+ "#### Extração de amostras para compararmos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rjVHsnnHRkIo"
+ },
+ "source": [
+ "df_A1_test = df_A1.sample(n = 100)\n",
+ "df_A2_test = df_A2.sample(n = 100)\n",
+ "df_A3_test = df_A3.sample(n = 100)\n",
+ "df_A4_test = df_A4.sample(n = 100)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "t0v0uXFRl-yG"
+ },
+ "source": [
+ "___\n",
+ "# **Transformações**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "pkzTO0fdz93b"
+ },
+ "source": [
+ "## (1) StandardScaler\n",
+ "* StandardScaler é a transformação que centraliza os dados através da remoção da média (dos dados) e, na sequência, redimensiona (scale) através da divisão pelo desvio-padrão;\n",
+ "* Após a transformação, os dados terão média zero e desvio-padrão 1;\n",
+ "* Assume que os dados (as colunas a serem transformadas) são normalmente distribuidos ;\n",
+ "* Se os dados não possuem distribuição Normal, então esta não é uma boa transformação a se aplicar.\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-mean(x)}{std(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "v1UOOWeQ0R_Y"
+ },
+ "source": [
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y1Lzx3xN6wpZ"
+ },
+ "source": [
+ "df_A3.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9cPq_7Vu2HCS"
+ },
+ "source": [
+ "Histograma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZYW9WwBC3hd_"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_A1['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('Histograma da coluna3')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "h8ogcQvvT5zK"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_A2['coluna3'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('Histograma da coluna3')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RrgxkESc-Uaq"
+ },
+ "source": [
+ "Considere o gráfico a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U7dHTF1W-Xsn"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hMS72n14-hDO"
+ },
+ "source": [
+ "Qual a interpretação para o gráfico acima?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "izqGNcNILdaX"
+ },
+ "source": [
+ "df_A1.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZEkAqlZg-p0v"
+ },
+ "source": [
+ "A seguir, a transformação StandardScaler:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N4u3T_BX-oc_"
+ },
+ "source": [
+ "from sklearn.preprocessing import StandardScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "voFQ4odSzzPZ"
+ },
+ "source": [
+ "O ideal é termos um array com as preditoras, da seguinte forma:\n",
+ "X = [coluna1, coluna2, ..., colunaN]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rPa4-SCt-ynX"
+ },
+ "source": [
+ "np.set_printoptions(precision = 3)\n",
+ "\n",
+ "A1_scale = StandardScaler().fit_transform(df_A1) # Combinação dos métodos fit() + transform()\n",
+ "\n",
+ "A1_scale_fit = StandardScaler().fit(df_A1) # Aplica o fit() separadamente\n",
+ "A1_scale_transform = A1_scale_fit.transform(df_A1) # Aplica o transform() separadamente.\n",
+ "A1_scale_fit_transform = StandardScaler().fit(df_A1).transform(df_A1) # Aplica fit().transform() encadeado\n",
+ "\n",
+ "A2_scale = StandardScaler().fit_transform(df_A2)\n",
+ "\n",
+ "A3_scale = StandardScaler().fit_transform(df_A3)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SGR9-bG0q-SI"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ioZ_IN3Z6d39"
+ },
+ "source": [
+ "Observe abaixo que A1_scale = A1_scale_transform = A1_scale_fit_transform --> São arrays multidimensionais (do tipo NumPy)!\n",
+ "\n",
+ "**é importante salvar as medidas de StandardScaler e outros para não ser necessário reprocessar os valores para todo processamento.**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v4xQR4cu5D1J"
+ },
+ "source": [
+ "A1_scale"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "j6GtN2KF4E_A"
+ },
+ "source": [
+ "A1_scale_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0q2bvSqb6T4g"
+ },
+ "source": [
+ "A1_scale_fit_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WIhaErnA46Fi"
+ },
+ "source": [
+ "Transformando em dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HAhRvPze44JW"
+ },
+ "source": [
+ "df_A1_scale = pd.DataFrame(A1_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "df_A2_scale = pd.DataFrame(A2_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "df_A3_scale = pd.DataFrame(A3_scale, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bmQp8wDO_E88"
+ },
+ "source": [
+ "Agora compare esse novo gráfico abaixo --> Vemos que os dados transformados tem distribuição Normal(0, 1):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "csfqRhDH2zUb"
+ },
+ "source": [
+ "df_A1.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-krh1pDg22RF"
+ },
+ "source": [
+ "df_A1_scale.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D2fTPWsm_Hq3"
+ },
+ "source": [
+ "df_A1_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9oN-829l3277"
+ },
+ "source": [
+ "df_A2.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Jqh8L5BeUHT-"
+ },
+ "source": [
+ "df_A2_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Yvz6O1zk4XNE"
+ },
+ "source": [
+ "df_A3.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ffU-fQxCUSmm"
+ },
+ "source": [
+ "df_A3_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "y24MOLL83w9j"
+ },
+ "source": [
+ "### Exercício: Calcular a média e o desvio-padrão."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1Aa25gVlSdOi"
+ },
+ "source": [
+ "df_A1.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EXZUiZImSmOE"
+ },
+ "source": [
+ "df_A1_scale.describe()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uIUQw5dpRwvA"
+ },
+ "source": [
+ "#### Correlação das colunas\n",
+ "* Observe que as correlações entre as variáveis não se alteram com as transformações."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uj1UerjORq9q"
+ },
+ "source": [
+ "df_A1.corr()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jp6vPK0aR_p0"
+ },
+ "source": [
+ "df_A1_scale.corr()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4fuURrao_M0c"
+ },
+ "source": [
+ "Qual a conclusão?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "f0A9U7rs_RAT"
+ },
+ "source": [
+ "## (2) MinMaxScaler\n",
+ "* **Transformação muito popular e utilizada**.\n",
+ "* Transforma os dados para o intervalo (0, 1);\n",
+ "* Se StandardScaler não é aplicável, então essa transformação funciona bem.\n",
+ "* Sensível aos outliers. Portanto, o ideal é que os outliers sejam tratados previamente.\n",
+ "* Uma transformação similar à MinMaxScaler() é MaxAbsScaler() que redimensiona os dados no intervalo [-1, 1], centralizado em 0(zero)\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-min(x)}{max(x)-min(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "C0HbeuP-AU_p"
+ },
+ "source": [
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mgeLckzxAWaC"
+ },
+ "source": [
+ "from sklearn.preprocessing import MinMaxScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "S_W9bTO2AbEg"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PJRFbUpBAg5J"
+ },
+ "source": [
+ "A1_MinMaxScaler = MinMaxScaler().fit_transform(df_A1)\n",
+ "df_A1_MinMaxScaler = pd.DataFrame(A1_MinMaxScaler,columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_A1_MinMaxScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7g8GA4LTA40U"
+ },
+ "source": [
+ "Qual a conclusão?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4Z6D3vfnB9Nm"
+ },
+ "source": [
+ "## (3) RobustScaler\n",
+ "* Transformação ideal para dados com outliers.\n",
+ "\n",
+ "$$z_{i}= \\frac{x_{i}-Q_{1}(x)}{Q_{3}(x)-Q_{1}(x)}$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m3oyuxLeCW1D"
+ },
+ "source": [
+ "df_A1.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zeDF7-w_CcBy"
+ },
+ "source": [
+ "from sklearn.preprocessing import RobustScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vLoqSKijCf2v"
+ },
+ "source": [
+ "A1_RobustScaler = RobustScaler().fit_transform(df_A1)\n",
+ "df_A1_RobustScaler = pd.DataFrame(A1_RobustScaler, columns = ['coluna1', 'coluna2', 'coluna3', 'coluna4'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_A1_RobustScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-YVMgt-WEFif"
+ },
+ "source": [
+ "## Encoding Variáveis Categóricas"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xHYvLc8T_jxQ"
+ },
+ "source": [
+ "### Encoding Variáveis Ordinais\n",
+ "* Exemplo: Variáveis com valores ordinais: baixo, médio ou alto."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "i1BgGiGdSTcG"
+ },
+ "source": [
+ "#### Gera um dataframe como exemplo."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kdVahfJAEkuO"
+ },
+ "source": [
+ "# Aqui vou usar a função randint - Retorna números inteiros aleatórios incluindo o número inferior e excluindo o superior.\n",
+ "\n",
+ "l_idade= [np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40),\n",
+ " np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40), np.random.randint(20, 40)]\n",
+ "\n",
+ "l_salario = ['baixo', 'medio', 'alto']\n",
+ "l_salario2 = np.random.choice(l_salario, 10, p = [0.6, 0.3, 0.1])\n",
+ "\n",
+ "df_A4 = pd.DataFrame({\n",
+ " 'idade': l_idade,\n",
+ " 'salario': l_salario2})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m_15P2eUHSBY"
+ },
+ "source": [
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R1g9pEuyHe2q"
+ },
+ "source": [
+ "Neste exemplo, vamos redefinir a variável categórical ordinal 'Salario' da seguinte forma:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bkwFuEa8HnMV"
+ },
+ "source": [
+ "df_A4['salario_cat'] = df_A4['salario'].map({'baixo': 1, 'medio': 2, 'alto': 3})\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DlaIFiWIIPAl"
+ },
+ "source": [
+ "### Encoding Variáveis Nominais\n",
+ "* Exemplo: Variáveis com valores nominais: Sexo (Feminino, Masculino).\n",
+ "\n",
+ "* Use One-Hot Encoding ou pd.get.dummies()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ffNoJQbgJRoY"
+ },
+ "source": [
+ "Vamos utilizar o dataframe criado no passo anterior:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PMCoUWZOI7c0"
+ },
+ "source": [
+ "df_A4['salario'].unique()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bdIEyBkaJeN8"
+ },
+ "source": [
+ "from sklearn.preprocessing import LabelEncoder, OneHotEncoder"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4MwK4cUEKeK4"
+ },
+ "source": [
+ "#### Aplicar LabelEncoder()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6X6VXDsHJiII"
+ },
+ "source": [
+ "le = LabelEncoder()\n",
+ "df_A4['salario_le'] = le.fit_transform(df_A4['salario'])\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RY80x59J8Ham"
+ },
+ "source": [
+ "df_A4['salario'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Dgv2Zz07Kqfj"
+ },
+ "source": [
+ "#### Aplicar pd.get.dummies()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WSZRIEs6K5sP"
+ },
+ "source": [
+ "dummies = pd.get_dummies(df_A4['salario'])\n",
+ "df_A4 = pd.concat([df_A4, dummies], axis = 1)\n",
+ "df_A4"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CY8GZ-HlNOgm"
+ },
+ "source": [
+ "*texto em itálico*# **Wrap Up**\n",
+ "\n",
+ "\n",
+ "* Use MinMaxScaler como transformação default, pois esta transformação não distorce os dados;\n",
+ "* Use RobustScaler se seus dados/coluna/variável possui outliers e gostaríamos de reduzir o efeito/impacto destes outliers. Entretanto, o melhor tratamento é estudar os outliers cuidadosamente e tratá-los adequadamente;\n",
+ "* Use StandardScaler se seus dados/colunas/variáveis possuem distribuição Normal (ou pelo menos se aproxima bem da distribuição Normal)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Mwh0alhdgrE3"
+ },
+ "source": [
+ "___\n",
+ "# **Exercícios**\n",
+ "> Para cada um dos dataframes a seguir, aplique os seguintes steps:\n",
+ "\n",
+ "* Padronizar o nome das colunas\n",
+ " * Eliminar espaços entre os nomes das colunas;\n",
+ " * Eliminar caracteres especiais dos nomes das colunas;\n",
+ " * Renomear as colunas com lower() (ou upper());\n",
+ "* Aplicar a trasformação StandardScaler e MinMaxScaler em cada uma das colunas do dataframe;\n",
+ "* DataViz - Mostrar a distribuição das colunas para compararmos os resultados antes e depois das transformações.\n",
+ "* As correlações das colunas mudam com as transformações?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hSTKrd992LtI"
+ },
+ "source": [
+ "## Exercício 1 - Iris --> **Resolvido**\n",
+ "* [Aqui](https://en.wikipedia.org/wiki/Iris_flower_data_set) você obterá mais informações sobre o dataframe iris. Confira."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mThqvGGr2Vuk"
+ },
+ "source": [
+ "from sklearn.datasets import load_iris\n",
+ "\n",
+ "iris = load_iris()\n",
+ "X= iris['data']\n",
+ "y= iris['target']\n",
+ "\n",
+ "df_iris = pd.DataFrame(np.c_[X, y], columns= np.append(iris['feature_names'], ['target']))\n",
+ "df_iris['target2'] = df_iris['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})\n",
+ "df_iris.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eU5FaJhdYblP"
+ },
+ "source": [
+ "df_iris.columns = [c.replace(' ', '_') for c in df_iris.columns]\n",
+ "df_iris.columns = [c.replace('_(cm)', '') for c in df_iris.columns]\n",
+ "df_iris.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PGmZjd_Y79lY"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "K9DPAakJZQHH"
+ },
+ "source": [
+ "df_iris.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YYYmVq68Y8bB"
+ },
+ "source": [
+ "# Aplica a transformação:\n",
+ "df_iris_MinMaxScaler = MinMaxScaler().fit_transform(df_iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']])\n",
+ "\n",
+ "# Transformando em Dataframe:\n",
+ "df_iris_MinMaxScaler = pd.DataFrame(df_iris_MinMaxScaler, columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])\n",
+ "\n",
+ "# Gráfico\n",
+ "df_iris_MinMaxScaler.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IwPH8-258JrF"
+ },
+ "source": [
+ "aplicar as outras transformações e comparar os gráficos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "caFkC6oCmUKK"
+ },
+ "source": [
+ "## Exercício 2 - Breast Cancer"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vhOM-Z9zmf-f"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from sklearn.datasets import load_breast_cancer\n",
+ "\n",
+ "cancer = load_breast_cancer()\n",
+ "X= cancer['data']\n",
+ "y= cancer['target']\n",
+ "\n",
+ "df_A1_cancer = pd.DataFrame(np.c_[X, y], columns= np.append(cancer['feature_names'], ['target']))\n",
+ "df_A1_cancer['target'] = df_A1_cancer['target'].map({0: 'malign', 1: 'benign'})\n",
+ "df_A1_cancer.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1qruqUDqnvMc"
+ },
+ "source": [
+ "## Exercício 3 - Boston Housing Price"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "trxK8YXNnsam"
+ },
+ "source": [
+ "from sklearn.datasets import load_boston\n",
+ "\n",
+ "boston = load_boston()\n",
+ "X= boston['data']\n",
+ "y= boston['target']\n",
+ "\n",
+ "df_A1_boston = pd.DataFrame(np.c_[X, y], columns= np.append(boston['feature_names'], ['target']))\n",
+ "df_A1_boston.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nzu0Dz33c8ds"
+ },
+ "source": [
+ "## Exercícios 4 - Diabetes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "d6ahBZmqc_-1"
+ },
+ "source": [
+ "from sklearn.datasets import load_diabetes\n",
+ "\n",
+ "diabetes = load_diabetes()\n",
+ "X= diabetes['data']\n",
+ "y= diabetes['target']\n",
+ "\n",
+ "df_A1_diabetes = pd.DataFrame(np.c_[X, y], columns= np.append(diabetes['feature_names'], ['target']))\n",
+ "df_A1_diabetes.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FOrG-8-o2qdG"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NyunIr6oaWEl"
+ },
+ "source": [
+ "## Exercícios 6 - 120 years of Olympic history: athletes and results\n",
+ "* [120 years of Olympic history: athletes and results](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)\n",
+ " * Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n",
+ " * Aplique as transformações que acabamos de estudar nos campos/colunas numéricas 'height' e 'weight'. Cuidado com os Missing Values contidos nas variáveis!\n",
+ " * Verifique/avalie o impacto dos outliers nestas colunas.\n",
+ " * Neste caso, qual transformação é mais adequado diante dos outliers?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "H94gYFj12xjW"
+ },
+ "source": [
+ "# Carrega a library Pandas\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yOknNCLW3gcg"
+ },
+ "source": [
+ "#configuração\n",
+ "d_configuracao = {\n",
+ " 'display.max_columns':1000,\n",
+ " 'display.expand_frame_repr':True,\n",
+ " 'display.max_rows':10,\n",
+ " 'display.precision':2,\n",
+ " 'display.show_dimensions':True\n",
+ " }"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qcLRA_uh35J-"
+ },
+ "source": [
+ "for op,value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2bNfE4K24OjG"
+ },
+ "source": [
+ "from google.colab import drive\n",
+ "drive.mount('/content/drive')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZkmDSUlU7JTw"
+ },
+ "source": [
+ "!ls \"/content/drive/My Drive/\""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fhajXFlq4dwm"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "url='/content/drive/My Drive/athlete_events.zip' \n",
+ "df_olympics = pd.read_csv(url, compression='zip')\n",
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xR4Hr3829zA3"
+ },
+ "source": [
+ "df_olympics.head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CQA_Wdxe-aOF"
+ },
+ "source": [
+ "df_olympics[['sex','season','team','city','sport','medal','height','weight']].head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zBRZbYAC-Jdt"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df_olympics.columns = [col.lower() for col in df.columns]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ruCg9AXN-K6l"
+ },
+ "source": [
+ "transformacao_lower(df_olympics)\n",
+ "df_olympics.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o5fDp1Ib_Dg8"
+ },
+ "source": [
+ "# WOE - Weight Of Evidence\n",
+ "* As vantagens da transformação WOE são\n",
+ " * Lida bem com NaN's;\n",
+ " * Lida bem com outliers;\n",
+ " * A transformação é baseada no valor logarítmico das distribuições.\n",
+ " * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wXEsP96A9TSd"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "%matplotlib inline\n",
+ "\n",
+ "#import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n",
+ "\n",
+ "# remove warnings to keep notebook clean\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gGdOGDZAHu-V"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Z2W9PXAc-vHY"
+ },
+ "source": [
+ "from google.colab import drive\n",
+ "drive.mount('/content/drive', force_remount=True)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g45JU2LXHwkz"
+ },
+ "source": [
+ "url = '/content/drive/My Drive/athlete_events.csv'\n",
+ "import pandas as pd\n",
+ "df_olympics = pd.read_csv(url)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JLxrnkJw_f7m"
+ },
+ "source": [
+ "pd.read_csv('/content/drive/My Drive/file/d/athlete_events.zip', compression='zip')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WcPQhh04E2du"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TlgG1t392nBY"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dl_Jma-i33XO"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From 00d3029fd0b858712ae72b96273f2a6e9f2124e5 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 19 Oct 2020 15:34:53 -0300
Subject: [PATCH 12/21] Criado usando o Colaboratory
---
...3DP_3_Data_Transformation_exercicios.ipynb | 291 ++++++++++++++++++
1 file changed, 291 insertions(+)
diff --git a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
index ddc2ee109..69fd2406a 100644
--- a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
+++ b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios.ipynb
@@ -1202,6 +1202,17 @@
"execution_count": null,
"outputs": []
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FOrG-8-o2qdG"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -1216,6 +1227,253 @@
" * Neste caso, qual transformação é mais adequado diante dos outliers?"
]
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "H94gYFj12xjW"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "%matplotlib inline\n",
+ "\n",
+ "#import category_encoders as ce # library para aplicação do WOE - Weight Of Evidence para avaliar importância dos atributos\n",
+ "\n",
+ "# remove warnings to keep notebook clean\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yOknNCLW3gcg"
+ },
+ "source": [
+ "#configuração\n",
+ "d_configuracao = {\n",
+ " 'display.max_columns':1000,\n",
+ " 'display.expand_frame_repr':True,\n",
+ " 'display.max_rows':10,\n",
+ " 'display.precision':2,\n",
+ " 'display.show_dimensions':True\n",
+ " }"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qcLRA_uh35J-"
+ },
+ "source": [
+ "for op,value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2bNfE4K24OjG"
+ },
+ "source": [
+ "from google.colab import drive\n",
+ "drive.mount('/content/drive')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZkmDSUlU7JTw"
+ },
+ "source": [
+ "!ls \"/content/drive/My Drive/athlete_events.zip\""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fhajXFlq4dwm"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "url='/content/drive/My Drive/athlete_events.zip' \n",
+ "df_olympics = pd.read_csv(url, compression='zip')\n",
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xR4Hr3829zA3"
+ },
+ "source": [
+ "df_olympics.head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CQA_Wdxe-aOF"
+ },
+ "source": [
+ "df_olympics[['sex','season','team','city','sport','medal','height','weight']].head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zBRZbYAC-Jdt"
+ },
+ "source": [
+ "def transformacao_lower(df):\n",
+ " # Primeira transformação: Aplicar lower() nos nomes das COLUNAS:\n",
+ " df_olympics.columns = [col.lower() for col in df.columns]\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ruCg9AXN-K6l"
+ },
+ "source": [
+ "transformacao_lower(df_olympics)\n",
+ "df_olympics.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "a7h-jRIiEGxr"
+ },
+ "source": [
+ "df_atleta2=df_olympics[['height','weight']]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8IRA3xp_EUA0"
+ },
+ "source": [
+ "df_atleta2.isnull().sum()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UGEqcw_7EYg0"
+ },
+ "source": [
+ "df_atleta2.dropna(inplace=True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MrvFs8s5EdqM"
+ },
+ "source": [
+ "df_atleta2.hist(bins=100)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "i8CQyOKQE6CM"
+ },
+ "source": [
+ "from sklearn.preprocessing import StandardScaler\n",
+ "atleta2_standard = StandardScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_standard = pd.DataFrame(atleta2_standard, columns=list(df_atleta2.keys()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jAlPzqM4IgN0"
+ },
+ "source": [
+ "from sklearn.preprocessing import MinMaxScaler\n",
+ "atleta2_minmax = MinMaxScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_minmax = pd.DataFrame(atleta2_minmax, columns=list(df_atleta2.keys()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "u1DCyxneIiIc"
+ },
+ "source": [
+ "from sklearn.preprocessing import RobustScaler\n",
+ "atleta2_robust = RobustScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_robust = pd.DataFrame(atleta2_robust, columns=list(df_atleta2.keys()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GQWOmU0tFDh9"
+ },
+ "source": [
+ "df_atleta2_robust['tipo'] = 'robust'\n",
+ "df_atleta2_minmax['tipo'] = 'minmax'\n",
+ "df_atleta2_standard['tipo'] = 'standard'\n",
+ "df_atletax = pd.concat([df_atleta2_minmax,df_atleta2_robust,df_atleta2_standard])\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_jo551PjHxKX"
+ },
+ "source": [
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -1310,6 +1568,39 @@
],
"execution_count": null,
"outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TlgG1t392nBY"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dl_Jma-i33XO"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GzO_OcAsEAEH"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
}
]
}
\ No newline at end of file
From 0507eb634af5a01392dfda16493e341055f09c2d Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 19 Oct 2020 15:43:46 -0300
Subject: [PATCH 13/21] Criado usando o Colaboratory
---
...ndas__Resposta_Exercicios_Aluno_Fifa.ipynb | 2788 +++++++++++++++++
1 file changed, 2788 insertions(+)
create mode 100644 Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
new file mode 100644
index 000000000..7ea9a913f
--- /dev/null
+++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
@@ -0,0 +1,2788 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "NB10_01__Pandas.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8fpUiw8PwC7_"
+ },
+ "source": [
+ "PANDAS PARA DATA ANALYSIS
\n",
+ "\n",
+ "\n",
+ "\n",
+ "# **Resposta dos Exercícios**\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wkxQFPPmeKLl"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eKawOG-neqaD"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iwd1lhq9mrD3"
+ },
+ "source": [
+ "___\n",
+ "# **Exercícios**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o_cl0kFgQfFh"
+ },
+ "source": [
+ "## Exercício 1\n",
+ "* A partir dos dataframes USA_Abbrev, USA_Area e USA_Population, construa o Dataframe USA contendo as COLUNAS state, abbreviation, area, ages, year, population.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "s8rQUo7yHKJ1"
+ },
+ "source": [
+ "* Observação: A forma mais fácil de ler um arquivo CSV (a partir do Excell por exemplo) a partir do GitHub é clicar no arquivo csv no seu repositório do GitHub e em seguida clicar em 'raw'. Depois, copie o endereço apresentado no browser e cole na variável 'url'. Qualquer dúvida, leia o documento a seguir: https://towardsdatascience.com/3-ways-to-load-csv-files-into-colab-7c14fcbdcb92."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KTun1uSLuJ-A"
+ },
+ "source": [
+ "## Exercício 2\n",
+ "Source: https://github.com/aakankshaws/Pandas-exercises\n",
+ "\n",
+ "* Considere os dataframes a seguir e faça o merge do dataframe df_esquerdo com o dataframe df_direito:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Soq7GVZnuREq"
+ },
+ "source": [
+ "df_esquerdo = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n",
+ " 'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3']})\n",
+ " \n",
+ "df_direito = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6KEsTARfvM1C"
+ },
+ "source": [
+ "## Exercício 3\n",
+ "Source: https://github.com/aakankshaws/Pandas-exercises\n",
+ "\n",
+ "* Considere os dataframes a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hgxE5gZ9vMEg"
+ },
+ "source": [
+ "df_esquerdo = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],\n",
+ " 'key2': ['K0', 'K1', 'K0', 'K1'],\n",
+ " 'A': ['A0', 'A1', 'A2', 'A3'],\n",
+ " 'B': ['B0', 'B1', 'B2', 'B3']})\n",
+ " \n",
+ "df_direito = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],\n",
+ " 'key2': ['K0', 'K0', 'K0', 'K0'],\n",
+ " 'C': ['C0', 'C1', 'C2', 'C3'],\n",
+ " 'D': ['D0', 'D1', 'D2', 'D3']})"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iv7AmZ1ivm8R"
+ },
+ "source": [
+ "### Perguntas\n",
+ "* Qual o output e a interpretação dos comandos a seguir:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TWAW_1tuvvSO"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QjM7pBONvzCJ"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'outer', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D1Rr3Ghsv2iS"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'right', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vXQwLjT-v3Iu"
+ },
+ "source": [
+ "pd.merge(df_esquerdo, df_direito, how = 'left', on = ['key1', 'key2'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EIdltTC-t_lF"
+ },
+ "source": [
+ "## Exercício 5\n",
+ "5.1. Identifique e delete os atributos do dataframe df_Titanic que podem ser excluídos inicialmente no início da análise de dados."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bMwPLgWclWBq"
+ },
+ "source": [
+ "___\n",
+ "## Exercício 6 - Resolvido\n",
+ "* Carregue o dataframe Titanic_With_MV.csv e analise o dataframe em busca de inconsistências e Missing Values (NaN)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ej6WjQX90n1E"
+ },
+ "source": [
+ "### Identificação e tratamento dos Missing Values\n",
+ "* Em geral, deletamos variáveis com mais de 50% de Missing Values."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nuaM4JKNLeSI"
+ },
+ "source": [
+ "df4.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GaYc-HXNJ1TQ"
+ },
+ "source": [
+ "pd.set_option('display.max_rows', 500)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v5s71jcHIGch"
+ },
+ "source": [
+ "df_missing_values = pd.DataFrame(df4.isnull().sum())\n",
+ "df_missing_values['mv_percent'] = 100*df_missing_values[0]/df4.shape[0]\n",
+ "df_missing_values[0].sort_values(ascending= False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V7KUGAX6lilP"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "df_Titanic = pd.read_csv('https://raw.githubusercontent.com/MathMachado/Python4DS/DS_Python/Dataframes/Titanic_With_MV.csv?token =AGDJQ63MNPPPROFNSO2BZW25XSR72', index_col= 'PassengerId')\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m3UnAPJakCLR"
+ },
+ "source": [
+ "* Segue o dicionário de dados do dataframe Titanic:\n",
+ " * PassengerID: ID do passageiro;\n",
+ " * survived: Indicador, sendo 1= Passageiro sobreviveu e 0= Passageiro morreu;\n",
+ " * Pclass: Classe;\n",
+ " * Age: Idade do Passageiro;\n",
+ " * SibSp: Número de parentes a bordo (esposa, irmãos, pais e etc);\n",
+ " * Parch: Número de pais/crianças a bordo;\n",
+ " * Fare: Valor pago pelo Passageiro;\n",
+ " * Cabin: Cabine do Passageiro;\n",
+ " * Embarked: A porta pelo qual o Passageiro embarcou.\n",
+ " * Name: Nome do Passageiro;\n",
+ " * sex: sexo do Passageiro\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_6RvRCXgwomw"
+ },
+ "source": [
+ "### Avaliando inconsistências nas COLUNAS"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PToomnfRxxI5"
+ },
+ "source": [
+ "import seaborn as sns\n",
+ "import pandas as pd\n",
+ "import numpy as np"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3nc_iuRR1Tju"
+ },
+ "source": [
+ "# Uniformizando o nome das COLUNAS\n",
+ "df_Titanic.columns= [cols.lower() for cols in df_Titanic.columns]\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "G9jteCnAxdnK"
+ },
+ "source": [
+ "### Coluna 'pclass'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wUk0YNlxsgvf"
+ },
+ "source": [
+ "df_Titanic['pclass'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9vPrB3AAx0Ym"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='pclass', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2n8s9Ad1m7od"
+ },
+ "source": [
+ "Não me parece nada estranho com a variável 'pclass'. Ou você identifica alguma coisa estranho?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m8EGM6gSxrzS"
+ },
+ "source": [
+ "### Coluna 'sex'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BRRgcLtinIRz"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8SQ8v2Wnspfb"
+ },
+ "source": [
+ "df_Titanic['sex'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wpp0iL0kyGTl"
+ },
+ "source": [
+ "Qual sua opinião sobre esse preenchimento?\n",
+ "\n",
+ "Algum problema?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jxx06kJFnNrP"
+ },
+ "source": [
+ "Oops... Aqui temos vários problemas... Olhando para estes resultados, você concorda que 'male', 'm', 'MALE', M', 'mALE' e 'Men' se trata da mesma informação?\n",
+ "\n",
+ "Da mesma forma, 'female', 'f', 'F', 'Female', 'fEMALE', 'Woman', 'w' e 'W' também se trata da mesma informação?\n",
+ "\n",
+ "Então, vamos fazer o seguinte:\n",
+ "\n",
+ "* Toda vez que eu encontrar um desses valores: ['m', 'MALE', 'M', 'mALE', 'Men'], vou substituir por 'male';\n",
+ "* Toda vez que eu encontrar um desses valores: ['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], vou substituit por 'female'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oQbEVi1t2tfR"
+ },
+ "source": [
+ "df_Titanic2= df_Titanic.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "apc-ccODyZ-d"
+ },
+ "source": [
+ "#### Corrigir com df.replace()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CwoyLBK9oME5"
+ },
+ "source": [
+ "df_Titanic['sex2'] = df_Titanic['sex'].replace(['m', 'MALE', 'M', 'mALE', 'Men'], 'male')\n",
+ "df_Titanic['sex3'] = df_Titanic['sex2'].replace(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W'], 'female') "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RC35I-Njp4vh"
+ },
+ "source": [
+ "Vamos ver a distribuição dos dados novamente no gráfico:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1eGvEhA9qAN6"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='sex3', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IY3TaKUcszTQ"
+ },
+ "source": [
+ "df_Titanic['sex3'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2nOAcv3iqEaK"
+ },
+ "source": [
+ "Ok, de fato corrigimos os problemas de preenchimento da variável 'sex'."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dqLqmrTWylY3"
+ },
+ "source": [
+ "#### Corrigir com df.map()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dRvuNo4E3Ewx"
+ },
+ "source": [
+ "df_Titanic= df_Titanic2.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3X0_ZdwCyquk"
+ },
+ "source": [
+ "d_sexo= {}\n",
+ "d_sexo.update(dict.fromkeys(['m', 'MALE', 'M', 'mALE', 'Men', 'male'], 'male'))\n",
+ "d_sexo.update(dict.fromkeys(['f', 'F', 'Female', 'fEMALE', 'Woman', 'w', 'W', 'female'], 'female'))\n",
+ "d_sexo"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YQ3lwKRKbsx0"
+ },
+ "source": [
+ "Aplica a transformação:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "idBwRNI7bvCC"
+ },
+ "source": [
+ "df_Titanic['sex2'] = df_Titanic['sex'].map(d_sexo)\n",
+ "df_Titanic['sex2'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FzDl78rfb3p5"
+ },
+ "source": [
+ "Qual a conclusão? Este preenchimento faz mais sentido que o anterior?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SvrZtKRpzIDc"
+ },
+ "source": [
+ "# Deleta as variáveis 'sex':\n",
+ "df_Titanic = df_Titanic.drop(columns = ['sex'], axis = 1).rename(columns= {'sex2': 'sex'})\n",
+ "\n",
+ "# Mostra os dados:\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6URC6h8xzfc5"
+ },
+ "source": [
+ "sns.catplot(x=\"sex\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "k_spkJbmqdRW"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='sex', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bgBNoXUNzoWZ"
+ },
+ "source": [
+ "### Feature Engineering\n",
+ "#### Coluna 'cabin'\n",
+ "* Construir as COLUNAS:\n",
+ " * deck - Letra de Cabin;\n",
+ " * seat - Número de Cabin"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8fHsLrnut6mk"
+ },
+ "source": [
+ "Sugestões:\n",
+ "1) Não descartar nenhuma informação (Fábio);\n",
+ "\n",
+ "2) Coluna com número de cabines reservadas (Thomaz)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "p0NFFxx8z-vq"
+ },
+ "source": [
+ "set(df_Titanic['cabin'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7E6yje89u7KF"
+ },
+ "source": [
+ "Como podemos ver, trata-se de uma variável categórica com vários níveis. Portanto, vamos capturar somente a primeira letra da variável 'cabin'. Para tal, vamos utilizar a função slice().\n",
+ "\n",
+ "> str.slice() - Captura (slice) partes de s_Str."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wmZLlSaArR6F"
+ },
+ "source": [
+ "A seguir, capturamos a primeira letra da variável 'cabin':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hUZTJU0MvVxP"
+ },
+ "source": [
+ "# definindo a variável 'deck' que representará a primeira letra da variável 'cabin'\n",
+ "df_Titanic[\"deck\"] = df_Titanic[\"cabin\"].str.slice(0, 1) # slice(inicio, tamanho_da_string)\n",
+ "df_Titanic['deck'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6myhrth0rZ6t"
+ },
+ "source": [
+ "A seguir, vamos extrair a parte numérica da variável 'cabin' usando Expressões Regulares:\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8UXkACPmsfwN"
+ },
+ "source": [
+ "# Importar a biblioiteca para Expressões Regulares\n",
+ "import re"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QKk-fnW4rf4o"
+ },
+ "source": [
+ "# Primeiramente, usamos a função split() para separar o conteúdo da variável em COLUNAS: \n",
+ "new = df_Titanic[\"cabin\"].str.split(\" \", n = 3, expand = True) \n",
+ "new.head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dFqoR-Xew9gX"
+ },
+ "source": [
+ "Observe acima que o comando gera quantos splits da variável eu quiser. No entanto, por simplicidade, me interessa somente o primeiro split."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_M7vA6WoVG05"
+ },
+ "source": [
+ "Agora, vou extrair o número do assento do passageiro usando Expressões Regulares:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rVH5o9KT_IH3"
+ },
+ "source": [
+ "# Aqui está o conteúdo de new[0]:\n",
+ "new[0].head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "P7NTcsGOxxSX"
+ },
+ "source": [
+ "new2= new[0].str.extract('(\\d+)')\n",
+ "new2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bf8vw2Mc18bQ"
+ },
+ "source": [
+ "Por fim, vou carregar esta informação ao dataframe df:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6l6EoRvsxRXn"
+ },
+ "source": [
+ "df_Titanic[\"seat\"] = new2\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LK4V61uy3N9s"
+ },
+ "source": [
+ "Por fim, excluir a variável 'cabin':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4uAr55J43NY7"
+ },
+ "source": [
+ "df_Titanic= df_Titanic.drop(columns= [\"cabin\"], axis =1, errors=\"ignore\")"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qZuH7YJXZCgY"
+ },
+ "source": [
+ "### Coluna 'embarked'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nTPikhrIZGya"
+ },
+ "source": [
+ "df_Titanic['embarked'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ixbZsuqOZsOc"
+ },
+ "source": [
+ "sns.catplot(x=\"embarked\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VvdU8aAwZNvG"
+ },
+ "source": [
+ "Não vejo problemas com esta variável. Vamos em frente..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "k2SLRAhrub_B"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='embarked', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YRJcWaYkuxK4"
+ },
+ "source": [
+ "sns.countplot(x = 'pclass', hue ='embarked', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rzrOUULUu6-P"
+ },
+ "source": [
+ "sns.countplot(x = 'sex', hue ='embarked', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DfSMcYYZ5yLV"
+ },
+ "source": [
+ "### Variável 'pclass'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Q2uU0k-G5yLN"
+ },
+ "source": [
+ "df_Titanic['pclass'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Gue26Y3A5yLL"
+ },
+ "source": [
+ "Algum problema com esta variável?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "q3P82wPp5yK8"
+ },
+ "source": [
+ "sns.catplot(x=\"pclass\", kind=\"count\", data = df)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Qrnc6VUKSTNp"
+ },
+ "source": [
+ "### Coluna 'parch'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2i4ed-0zSvJc"
+ },
+ "source": [
+ "df_Titanic['parch'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qd7u__6KZ6DM"
+ },
+ "source": [
+ "sns.catplot(x=\"parch\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Z9vM3vktC7BG"
+ },
+ "source": [
+ "### Feature Engineering\n",
+ "* Criar a coluna 'sozinho_parch', onde sozinho_parch= 1 significa que o passageiro viaja sozinho e 0, caso contrário."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Nd4TyOYjs-HW"
+ },
+ "source": [
+ "# Função para retornar 0 ou 1 em função dos valores de variavel\n",
+ "def sozinho(variavel):\n",
+ " if (variavel == 0):\n",
+ " return 1\n",
+ " else:\n",
+ " return 0"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5oByiBuos_B3"
+ },
+ "source": [
+ "df_Titanic['sozinho_parch'] = df_Titanic['parch'].map(sozinho)\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "C1ICby1oSd41"
+ },
+ "source": [
+ "### Coluna 'sibsp'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5n7JNEQqTNjz"
+ },
+ "source": [
+ "df_Titanic['sibsp'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NLfMhiy0x4u5"
+ },
+ "source": [
+ "* Algum problema?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nayYFRK9g8iV"
+ },
+ "source": [
+ "sns.catplot(x=\"sibsp\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KzCX2MTmE9Tw"
+ },
+ "source": [
+ "sns.countplot(x = 'survived', hue ='sibsp', data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_58rZqMaDzf-"
+ },
+ "source": [
+ "### Feature Engineering:\n",
+ "* Criar o atributo 'sozinho_sibsp', onde sozinho= 1 significa que o passageiro viaja sozinho e 0, caso contrário."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HUrJ4IywrEoA"
+ },
+ "source": [
+ "df_Titanic['sozinho_sibsp'] = df_Titanic['sibsp'].map(sozinho)\n",
+ "df_Titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0MO9jj2NvGp_"
+ },
+ "source": [
+ "### Coluna 'fare'\n",
+ "> Discretizar a coluna 'fare' em 10 buckets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4-qO2Xk76Buz"
+ },
+ "source": [
+ "df_Titanic['fare_class'] = pd.qcut(df_Titanic['fare'], 10, labels=False)\n",
+ "df_Titanic['fare_class'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "boAj64RHvQHu"
+ },
+ "source": [
+ "sns.catplot(x=\"fare_class\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3CIqHUJpvcPa"
+ },
+ "source": [
+ "### Coluna 'age'\n",
+ "> Discretizar a coluna 'age' em 10 buckets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rCRnbKX57VN-"
+ },
+ "source": [
+ "df_Titanic['age_class'] = pd.qcut(df_Titanic['age'], 10, labels=False)\n",
+ "df_Titanic['age_class'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uFsZLYDi7VOH"
+ },
+ "source": [
+ "sns.catplot(x=\"age_class\", kind=\"count\", data = df_Titanic)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DIY-sL337uje"
+ },
+ "source": [
+ "#### Alternativa para discretizar 'age'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "W66GkyuKkhFe"
+ },
+ "source": [
+ "def Age_Category(age):\n",
+ " if (age <= 1):\n",
+ " return 1\n",
+ " elif (age <= 5):\n",
+ " return 2\n",
+ " elif(age <= 10):\n",
+ " return 3\n",
+ " elif (age <= 15):\n",
+ " return 4\n",
+ " elif (age <= 20):\n",
+ " return 5\n",
+ " elif (age <= 25):\n",
+ " return 6\n",
+ " elif(age < 30):\n",
+ " return 7\n",
+ " elif(age < 35):\n",
+ " return 8\n",
+ " elif(age < 40):\n",
+ " return 9\n",
+ " elif(age < 45):\n",
+ " return 10\n",
+ " elif(age < 50):\n",
+ " return 11\n",
+ " elif(age < 60):\n",
+ " return 12\n",
+ " elif(age < 70):\n",
+ " return 13\n",
+ " elif(age < 80):\n",
+ " return 14\n",
+ " else:\n",
+ " return 15"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TnLzC6hCkuBL"
+ },
+ "source": [
+ "df_Titanic['age_class2'] = df['age'].map(Age_Category)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kG8td6HPsNlP"
+ },
+ "source": [
+ "set(df_Titanic['age_category']) # Esse comando mostra os NaN's da coluna, se houver."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B_3s5cgxfNKQ"
+ },
+ "source": [
+ "### Coluna 'title'\n",
+ "\n",
+ "* Para fins de Data Manipulation, vamos capturar o tratamento dos passageiros contido na variável 'nome'. Ou seja, 'Mr.', 'Mrs.', 'Miss' e etc...\n",
+ "\n",
+ "> Fonte: As funções get_title e title_map foram extraídas de https://www.kaggle.com/tjsauer/titanic-survival-python-solution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gslSjRdDoJFY"
+ },
+ "source": [
+ "df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XjqEVVnr8R4d"
+ },
+ "source": [
+ "Primeiramente, vamos entender como funciona, step by step..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D6gjWc3XozK7"
+ },
+ "source": [
+ "'Allen, Mr. William Henry'.split(',')[1].split('.')[0].strip()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nfIG6toGfhd5"
+ },
+ "source": [
+ "def get_title(nome):\n",
+ " if '.' in nome:\n",
+ " return nome.split(',')[1].split('.')[0].strip()\n",
+ " else:\n",
+ " return 'Unknown'\n",
+ "\n",
+ "def title_map(title):\n",
+ " if title in ['Mr', 'Ms']:\n",
+ " return 1\n",
+ " elif title in ['Master']:\n",
+ " return 2\n",
+ " elif title in ['Ms','Mlle','Miss']:\n",
+ " return 3\n",
+ " elif title in [\"Mme\", \"Ms\", \"Mrs\"]:\n",
+ " return 4\n",
+ " elif title in [\"Jonkheer\", \"Don\", \"Sir\", \"the Countess\", \"Dona\", \"Lady\"]:\n",
+ " return 5\n",
+ " elif title in [\"Capt\", \"Col\", \"Major\", \"Dr\", \"Rev\"]:\n",
+ " return 6\n",
+ " else:\n",
+ " return 7"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HLQoJwf0rjrf"
+ },
+ "source": [
+ "Exercícios\n",
+ "* Melhorar a função title_map."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7qNUwnCepe_x"
+ },
+ "source": [
+ "Captura o tratamento dos passageiros:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r-Ltf33vgJ6Q"
+ },
+ "source": [
+ "df_Titanic['title'] = df_Titanic['nome'].apply(get_title).apply(title_map) \n",
+ "set(df_Titanic['title']) # Esse comando mostra os NaN's da variável"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "D3hY0WVhpRYK"
+ },
+ "source": [
+ "Drop a coluna 'nome', pois não vamos mais precisar dela em nossas análises:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Y8i3xKCes5WF"
+ },
+ "source": [
+ "df_Titanic= df_Titanic.drop(columns= [\"nome\"], axis =1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7Sl1uFdwpW3y"
+ },
+ "source": [
+ "Apresenta o conteúdo do dataframe:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2uFnw-pZpan-"
+ },
+ "source": [
+ "df_Titanic.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B0fZMKKpdHIl"
+ },
+ "source": [
+ "## Missing Value\n",
+ "> Faça o devido tratamento de NaN's das COLUNAS do dataframe df_Titanic.\n",
+ "\n",
+ "**Pergunta**: Na coluna 'value', os valores 0 (zero) são considerados Missing Values?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UHzKFytXsNkh"
+ },
+ "source": [
+ "df_Titanic['age'].isna().sum()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZC1ULWd883t2"
+ },
+ "source": [
+ "## Relação causa --> efeito"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_WCbklv0bDlp"
+ },
+ "source": [
+ "A função a seguir nos ajudará com o Data Visualization, cruzando a variável-resposta 'survived' com qualquer outra passada à função:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "epxI-F2UbGGS"
+ },
+ "source": [
+ "def taxa_sobrevivencia(df, column):\n",
+ " title_xt = pd.crosstab(df[column], df['survived'])\n",
+ " print(pd.crosstab(df[column], df['survived'], margins=True))\n",
+ " title_xt_pct = title_xt.div(title_xt.sum(1).astype(float), axis =0)\n",
+ " \n",
+ " title_xt_pct.plot(kind='bar', stacked=True, title='Taxa de Sobrevivência dos Passageiros', \n",
+ " color= ['r', 'g'])\n",
+ " plt.xlabel(column)\n",
+ " plt.ylabel('Taxa de Sobrevivência')\n",
+ " plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),shadow=True, ncol=2)\n",
+ " plt.show()\n",
+ "\n",
+ "def grafico_catplot(x, y, hue = 'survived', col= None):\n",
+ " plt.rcdefaults()\n",
+ " g= sns.catplot(x= x, y= y, hue = hue, palette={'Died':'red','Survived':'blue'}, col= col, data = df, kind= 'bar', height=4, aspect=.7)\n",
+ " plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "34-Qbd_QrC8W"
+ },
+ "source": [
+ "Qual a relação entre a variável 'sex' e a variável-resposta?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bhY8-UjyrC8Z"
+ },
+ "source": [
+ "taxa_sobrevivencia(df_Titanic, 'sex')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UbexhGtayV4X"
+ },
+ "source": [
+ "## Exercício 7\n",
+ "Consulte a página [Pandas Exercises, Practice, Solution](https://www.w3resource.com/python-exercises/pandas/index.php) para mais exercícios relacionados á este tópico."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "P62MXm3tK8Ty"
+ },
+ "source": [
+ "## Exercício 8\n",
+ "Crie a coluna 'aleatorio' no dataframe df_Titanic em que cada linha recebe um valor aleatório usando o método np.random.random()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Du7Y8E4uFmiu"
+ },
+ "source": [
+ "i_linhas_Titanic = df_Titanic.shape[0]\n",
+ "\n",
+ "df_Titanic['aleatorio'] = np.random.random(i_linhas_Titanic)\n",
+ "df_Titanic.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LMD3HksDL0PQ"
+ },
+ "source": [
+ "## Exercício 9\n",
+ "\n",
+ "1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);\n",
+ "2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?\n",
+ "3. Qual o dtype de cada variável/atributo do dataframe?\n",
+ "4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?\n",
+ "5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;\n",
+ "6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?\n",
+ "7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição.\n",
+ "8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');\n",
+ "9. Qual a número de jogadores por idade?\n",
+ "10. Quantos jogadores possuem cada clube?\n",
+ "11. Qual a média de idade por clube?\n",
+ "12. Qual a média de salário por país?\n",
+ "13. Qual a média de salário por clube?\n",
+ "14. Qual a média de salário por idade?\n",
+ "15. Quanto cada clube gasta com pagamento de salários?\n",
+ "16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?\n",
+ "17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?\n",
+ "18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n",
+ "19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'.\n",
+ "20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed'=?\n",
+ "21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?\n",
+ "22. Quem são os outliers em termos de salário?\n",
+ "23. Quem são os outliers em termos de potência no chute?\n",
+ "24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?\n",
+ "25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "70Ml5KyZ04mk"
+ },
+ "source": [
+ "A seguir, significado da variável \"Position\":\n",
+ "* GK = Goalkeeper – Goleiro.\n",
+ "* RB = Right Back – Zagueiro Direito.\n",
+ "* CB = Central Back – Zagueiro Central.\n",
+ "* LB = Left Back – Zagueiro Esquerdo.\n",
+ "* SW = Sweeper – Líbero.\n",
+ "* RWB = Right Wing Back – Lateral Direito.\n",
+ "* LWB = Left Wing back – Lateral Esquerdo.\n",
+ "* CDM = Central Defensive Midfielder – Meio Campo Defensivo / Volante.\n",
+ "* CM = Central Midfielder – Meia Central.\n",
+ "* CAM = Center Attacking Middlefielder – Meio Campo Ofensivo / Armador.\n",
+ "* OM = Offensive Midfielder – Meia Ofensivo.\n",
+ "* LOM = Left Offensive Midfielder – Meia Esquerda Ofensivo.\n",
+ "* ROM = Right Offensive Midfielder – Meia Direita Ofensivo.\n",
+ "* LM = Left Midfielder – Meia Esquerda.\n",
+ "* RM = Right Midfielder – Meia Direita.\n",
+ "* LWM = Left Wing Midfielder – Meio Ala Esquerdo.\n",
+ "* RWM = Right Wing Midfielder – Meio Ala Direito.\n",
+ "* RW = Right Winger – Ala Direito.\n",
+ "* LW = Left Winger – Ala Esquerto.\n",
+ "* LF = Left Forward – Atacante Esquerdo.\n",
+ "* RF = Right Forward – Atacante Direito.\n",
+ "* ST = Striker – Atacante.\n",
+ "* CF = Center Forward – Centro Avante.\n",
+ "* RS = Right Striker – Atacante Direito.\n",
+ "* LS = Left Striker – Atacante Esquerdo."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tjHDjj68zawa"
+ },
+ "source": [
+ "## 1. Carregue o arquivo FIFA.csv (está na área de Dataframes do curso);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Wzosi4Ue1vDs"
+ },
+ "source": [
+ "### Carregar as libraries necessárias"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "B0fqR6rzMAa3"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vgoLTamaOC50"
+ },
+ "source": [
+ "#### Configurar ambiente"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RRwi_z8JOFrD"
+ },
+ "source": [
+ "d_configuracao = {\n",
+ " 'display.max_columns': 1000,\n",
+ " 'display.expand_frame_repr': True,\n",
+ " 'display.max_rows': 10,\n",
+ " 'display.precision': 2,\n",
+ " 'display.show_dimensions': True\n",
+ " }\n",
+ "\n",
+ "for op, value in d_configuracao.items():\n",
+ " pd.set_option(op, value)\n",
+ " print(op, value)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MdVljEbcMGU9"
+ },
+ "source": [
+ "#### Carregar os dados"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GMivDUHEMFKp"
+ },
+ "source": [
+ "df = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA.csv?token=AGDJQ63GC7SPIHTGNW73QB27RXRN6') #, index_col= 'PassengerId')\n",
+ "df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7pDUpFVLTOfl"
+ },
+ "source": [
+ "#### Definir a coluna 'ID' como index do dataframe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TEue20CbMp9U"
+ },
+ "source": [
+ "df.set_index('ID', inplace = True)\n",
+ "df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "G8CDrpI1_wMd"
+ },
+ "source": [
+ "### Função para retirar os sinais de \"+\" ou \"-\" em algumas colunas/vriáveis:\n",
+ "* Percebeste algumas colunas com o sinal de \"+\" no nome?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7zqHkNCsEDpJ"
+ },
+ "source": [
+ "A seguir, exemplo de algumas colunas com este problema:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_hUvJbCqCBBl"
+ },
+ "source": [
+ "df[['RS', 'LS', 'ST']].head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "78QhptWdEIB0"
+ },
+ "source": [
+ "A seguir, definimos um dataframe chamado df_string contendo a quantidade de colunas separadas pelo sinal \"+\". Observe que o máximo de colunas que obtemos são 2. Porque?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DzeSvQMGF4G7"
+ },
+ "source": [
+ "df_string = df['RS'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n",
+ "df_string.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PEzqRR5CEUru"
+ },
+ "source": [
+ "df_string[0] = pd.to_numeric(df_string[0])\n",
+ "df_string[1] = pd.to_numeric(df_string[1])\n",
+ "df_string['RS2'] = df_string[0]+df_string[1]\n",
+ "\n",
+ "df_string.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2t4rnjRWFPON"
+ },
+ "source": [
+ "df_string.dtypes"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MAYju4f6GFzw"
+ },
+ "source": [
+ "df_string.drop(columns= [0, 1], axis = 1, inplace = True)\n",
+ "df = pd.merge(df, df_string, how = 'left', on = 'ID')\n",
+ "df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "sm5lOGrrHoDp"
+ },
+ "source": [
+ " **Desafio**: Próximo passo: transformar isso numa função para tratar as demais variáveis!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "QtmOlKNpzbOz"
+ },
+ "source": [
+ "## 2. Que colunas podem previamente ser eliminadas da análise? Porque identificar o que pode ser eliminado é importante?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "7TzcuD2GxfBP"
+ },
+ "source": [
+ "### Colunas que poderiam previamente ser eliminadas:\n",
+ "* Photo\n",
+ "* Flag\n",
+ "* Club Logo\n",
+ "* Unnamed: 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kXDe_AdEx3DD"
+ },
+ "source": [
+ "df2 = df.copy()\n",
+ "\n",
+ "l_cols_drop = ['Unnamed: 0', 'Photo', 'Flag', 'Club Logo']\n",
+ "df2.drop(columns = l_cols_drop, axis = 1, inplace = True)\n",
+ "df2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m97dcDy9zbSO"
+ },
+ "source": [
+ "## 3. Qual o dtype de cada variável/atributo do dataframe?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GEbvITXR2U17"
+ },
+ "source": [
+ "# Função para nos mostrar o tipo das colunas:\n",
+ "def mostra_tipo(df):\n",
+ " d_tipos = dict(zip(df.columns, df.dtypes))\n",
+ " for item in d_tipos.items():\n",
+ " print(item)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3B9vxmbl9HNP"
+ },
+ "source": [
+ "mostra_tipo(df2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5XKcxC0Pzshm"
+ },
+ "source": [
+ "## 4. Se alguma variável/atributo é do tipo string (object) e supostamente deveria ser numérica, como alteramos o tipo?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "A7T31nFiPdDu"
+ },
+ "source": [
+ "### Mudar o tipo de algumas colunas\n",
+ "* Exemplo: 'Wage', 'Value' e 'Release Clause'. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VJSsvOpK71n7"
+ },
+ "source": [
+ "df4 = df2.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xyV-_MY9688C"
+ },
+ "source": [
+ "def transforma_monetarias(coluna):\n",
+ " if 'M' in coluna:\n",
+ " return int(float(coluna.replace('M', '')) * 1000000)\n",
+ "\n",
+ " elif 'K' in coluna:\n",
+ " return int(float(coluna.replace('K', '')) * 1000)\n",
+ " \n",
+ " else:\n",
+ " return int(coluna) "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AJ9-8sVS6MXj"
+ },
+ "source": [
+ "Substituindo o símbolo \"€\" por '':"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ArgK2NVe6vqz"
+ },
+ "source": [
+ "l_colunas_monetarias = ['Value', 'Wage']\n",
+ "\n",
+ "for coluna in l_colunas_monetarias:\n",
+ " df4[coluna] = df4[coluna].str.replace('€', '')\n",
+ " df4[coluna] = df4[coluna].apply(lambda x: transforma_monetarias(x))\n",
+ "\n",
+ "df4.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "c_lznTRHzbV9"
+ },
+ "source": [
+ "## 5. Normalize os nomes das colunas, ou seja, renomeie o nome das colunas para minúsculo;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "usM674sR8Gv9"
+ },
+ "source": [
+ "df5 = df4.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "N6LCmJ0QUsJo"
+ },
+ "source": [
+ "### Nome das colunas --> Substituir os \" \" por \"_\" nos nomes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NWJYqphfUxn1"
+ },
+ "source": [
+ "df5.columns = [c.replace(' ', '_') for c in df5.columns]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lXUOzLWmVTNZ"
+ },
+ "source": [
+ "### Renomear as colunas usando lower()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZwwLMOYRVXnr"
+ },
+ "source": [
+ "df5.columns = [c.lower() for c in df5.columns]\n",
+ "mostra_tipo(df5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Uc12gBThz1nD"
+ },
+ "source": [
+ "## 6. Há Missing values nos dados? Se sim, o qual sua proposta (proposta do grupo) para tratar estes Missing values?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nYgvxvcT8QIT"
+ },
+ "source": [
+ "df6 = df5.copy()\n",
+ "df6.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9STC9fsWJAHn"
+ },
+ "source": [
+ "# Fazendo uma cópia permanente do dataframe df6 para uso futuro\n",
+ "df6[['overall', 'potential', 'value', 'wage', 'nationality', 'position', 'age', 'preferred_foot']].to_csv('FIFA_algumas_features.csv')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ESFYFvOy8XOM"
+ },
+ "source": [
+ "Aqui vou substituir os Missing Values pela mediana. Fique à vontade para substituir por outras alternativas como min, max, média, limite superior de outliers e limite inferior para outliers."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "j7zDrRvi8iay"
+ },
+ "source": [
+ "l_colunas_numericas = df6.select_dtypes(np.number).columns.tolist()\n",
+ "l_colunas_numericas"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mZEM0N2f9vi7"
+ },
+ "source": [
+ "# Mediana antes da substituição:\n",
+ "df6[l_colunas_numericas].median()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dzfw0kp69dK2"
+ },
+ "source": [
+ "# Substituição pela mediana\n",
+ "for coluna in l_colunas_numericas:\n",
+ " df6[coluna].fillna(df6[coluna].median())\n",
+ "\n",
+ "# Mediana depois da substituição:\n",
+ "df6[l_colunas_numericas].median()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jpQR9zDC-nEj"
+ },
+ "source": [
+ "Abaixo, identifiquei 252 registros com value = 0 --> Nestes casos, vou atribuir a mediana também."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "s1Zj3gBJ-Z5c"
+ },
+ "source": [
+ "df6[df6['value'] == 0]['value'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HjuNw2u6-7i9"
+ },
+ "source": [
+ "# Mediana antes\n",
+ "df6['value'].median()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VWEp0Tc_-vLD"
+ },
+ "source": [
+ "# Atribuição da mediana para os valores 0 de 'value'\n",
+ "df6.loc[df6['value'] == 0, 'value'] = df6['value'].median()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HynCT_Yu_JL-"
+ },
+ "source": [
+ "# Mediana depois\n",
+ "df6['value'].median()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B4O5kw6h_z3H"
+ },
+ "source": [
+ "E se tivéssemos substituído pela média, ao invés da mediana? Teria mudado alguma coisa?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eU7ybhA2zbZh"
+ },
+ "source": [
+ "## 7. Qual a distribuição do número de jogadores por países? Apresente uma tabela com a distribuição."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "A34BwvXrXAqU"
+ },
+ "source": [
+ "df7 = df6.copy()\n",
+ "df7.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fu87YSiudcM_"
+ },
+ "source": [
+ "df7.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IQQ7AvgBYZmx"
+ },
+ "source": [
+ "df_jogadores_por_paises = pd.DataFrame(df7.groupby(by=['nationality']).size())\n",
+ "df_jogadores_por_paises.columns = ['numero_jogadores']\n",
+ "df_jogadores_por_paises.sort_values(by = ['numero_jogadores'], ascending = False, inplace= True)\n",
+ "df_jogadores_por_paises = df_jogadores_por_paises.reset_index()\n",
+ "df_jogadores_por_paises\n",
+ "\n",
+ "# Numa única linha ficaria assim:\n",
+ "df_jogadores_por_paises2 = pd.DataFrame(df7.groupby(by=['nationality']).size(), columns= ['numero_jogadores']).sort_values(by = ['numero_jogadores'], ascending = False).reset_index()\n",
+ "df_jogadores_por_paises2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JfyDUEC2zbcv"
+ },
+ "source": [
+ "## 8. Qual a média de idade dos jogadores por países (variável/atributo 'Nacionality');"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0a9MvyWPcu-C"
+ },
+ "source": [
+ "df_media_idade_por_paises = df7.groupby(by = ['nationality']).agg({'age': ['count', 'mean']}).reset_index()\n",
+ "df_media_idade_por_paises.columns = ['nationality', 'numero_joagadores', 'media_idade']\n",
+ "df_media_idade_por_paises.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n",
+ "df_media_idade_por_paises.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vNmu0xyg0CW4"
+ },
+ "source": [
+ "## 9. Qual a número de jogadores por idade?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DRVvPgpRf9vw"
+ },
+ "source": [
+ "df_jogadores_por_idade = df7.groupby(by = ['age']).agg({'age': ['count']}).reset_index()\n",
+ "df_jogadores_por_idade.columns = ['age', 'numero_joagadores']\n",
+ "df_jogadores_por_idade.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n",
+ "df_jogadores_por_idade.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8eChi2NW0CZp"
+ },
+ "source": [
+ "## 10. Quantos jogadores possuem cada clube?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JpNI3ZlHgUx1"
+ },
+ "source": [
+ "df_jogadores_por_clube = df7.groupby(by = ['club']).size().reset_index()\n",
+ "df_jogadores_por_clube.columns = ['clube', 'numero_joagadores']\n",
+ "df_jogadores_por_clube.sort_values(by = ['numero_joagadores'], ascending = False, inplace = True)\n",
+ "df_jogadores_por_clube.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gMiibNwW0Cck"
+ },
+ "source": [
+ "## 11. Qual a média de idade por clube?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D9rF9frzgqSr"
+ },
+ "source": [
+ "df_media_idade_por_clube = df7.groupby(by = ['club']).agg({'age': ['count', 'mean']}).reset_index()\n",
+ "df_media_idade_por_clube.columns = ['clube', 'numero_joagadores', 'media_idade']\n",
+ "df_media_idade_por_clube.sort_values(by = ['media_idade'], ascending = False, inplace = True)\n",
+ "df_media_idade_por_clube.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uE_o76xH0QU-"
+ },
+ "source": [
+ "## 12. Qual a média de salário por país?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "keQXqnU7hJy4"
+ },
+ "source": [
+ "df_media_salario_por_pais = df7.groupby(by = ['nationality']).agg({'wage': ['count', 'mean']}).reset_index()\n",
+ "df_media_salario_por_pais.columns = ['nationality', 'numero_joagadores', 'media_salario']\n",
+ "df_media_salario_por_pais.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n",
+ "df_media_salario_por_pais.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vqT1ozNA0Cfd"
+ },
+ "source": [
+ "## 13. Qual a média de salário por clube?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "54_Q2IGchmN-"
+ },
+ "source": [
+ "df_media_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean']}).reset_index()\n",
+ "df_media_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario']\n",
+ "df_media_salario_por_clube.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n",
+ "df_media_salario_por_clube.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4eflozOo0Cif"
+ },
+ "source": [
+ "## 14. Qual a média de salário por idade?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Xtq9Am60hwGr"
+ },
+ "source": [
+ "df_media_salario_por_idade = df7.groupby(by = ['age']).agg({'wage': ['count', 'mean']}).reset_index()\n",
+ "df_media_salario_por_idade.columns = ['age', 'numero_joagadores', 'media_salario']\n",
+ "df_media_salario_por_idade.sort_values(by = ['media_salario'], ascending = False, inplace = True)\n",
+ "df_media_salario_por_idade.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "L0yRSSIb0WYj"
+ },
+ "source": [
+ "## 15. Quanto cada clube gasta com pagamento de salários?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "C9N7_pLfh_uq"
+ },
+ "source": [
+ "df_soma_salario_por_clube = df7.groupby(by = ['club']).agg({'wage': ['count', 'mean', 'sum']}).reset_index()\n",
+ "df_soma_salario_por_clube.columns = ['clube', 'numero_joagadores', 'media_salario', 'soma_salario']\n",
+ "df_soma_salario_por_clube.sort_values(by = ['soma_salario'], ascending = False, inplace = True)\n",
+ "df_soma_salario_por_clube.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1c7NGMg90YMi"
+ },
+ "source": [
+ "## 16. Quais são os insight (o que você consegue descobrir) em relação à variável 'Potential' (mede o potencial dos jogadores)?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RAU41Iyaihvc"
+ },
+ "source": [
+ "df7.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bM_ePTWfiTFq"
+ },
+ "source": [
+ "df_potential_por_clube = df7.groupby(by = ['potential', 'club', 'nationality']).agg({'potential': ['count']}).reset_index()\n",
+ "df_potential_por_clube.columns = ['potential', 'club', 'nationality', 'numero_joagadores']\n",
+ "df_potential_por_clube.sort_values(by = ['potential'], ascending = False, inplace = True)\n",
+ "df_potential_por_clube.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HytWPvfvjTON"
+ },
+ "source": [
+ "#### Quem é o jogador com potential = 95?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Fk2X1q7LjWJE"
+ },
+ "source": [
+ "df7.loc[df7['potential'] == 95]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "W2o4oLzujnHj"
+ },
+ "source": [
+ "#### Quem são os jogadores com potencial = 94?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GOCyMr-qjsL7"
+ },
+ "source": [
+ "df7.loc[df7['potential'] == 94]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LHDJimdw0ClU"
+ },
+ "source": [
+ "## 17. Quais os insights em relação à variável overall (nota média do atleta) por idade, clube e país?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FXFp5nxrj9Yc"
+ },
+ "source": [
+ "df_overall = df7.groupby(by = ['overall', 'club', 'nationality']).agg({'overall': ['count']}).reset_index()\n",
+ "df_overall.columns = ['overall', 'club', 'nationality', 'numero_joagadores']\n",
+ "df_overall.sort_values(by = ['overall'], ascending = False, inplace = True)\n",
+ "df_overall.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4LTooiIdk1XV"
+ },
+ "source": [
+ "#### Quem é o jogador com overall = 94?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QieAKyi7k5Bb"
+ },
+ "source": [
+ "df7.loc[df7['overall'] == 94]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JFH54d1D0b5B"
+ },
+ "source": [
+ "## 18. Quais são os melhores clubes se levarmos em consideração as variáveis Potential e Overall?\n",
+ "* Para responder esta questão, tirei a média de overall e potential."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0JZ7PTFTle_d"
+ },
+ "source": [
+ "df18 = df7.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "s25u8RoplMZ8"
+ },
+ "source": [
+ "df18['overall_potential'] = ((df18['potential']+df18['overall'])/2)\n",
+ "df18[['name', 'overall', 'potential', 'overall_potential']].head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8gJFzhhIlDCH"
+ },
+ "source": [
+ "df_overall_potential = df18.groupby(by = ['club', 'nationality', 'age']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n",
+ "df_overall_potential.columns = ['club', 'nationality', 'age', 'numero_jogadores', 'media_overall_potential']\n",
+ "df_overall_potential.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n",
+ "df_overall_potential.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "adpxQpWlmvac"
+ },
+ "source": [
+ "De forma geral:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fzn_81eomrj2"
+ },
+ "source": [
+ "df_overall_potential2 = df18.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n",
+ "df_overall_potential2.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n",
+ "df_overall_potential2.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n",
+ "df_overall_potential2.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dM8FehYC0df7"
+ },
+ "source": [
+ "## 19. Apresente o ranking dos goleiros (use a variável/atributo 'Preferred Positions') por Potencial, Overall. Estamos à procura de 'GK'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_967BF6MnD4U"
+ },
+ "source": [
+ "df19 = df18.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wXPah5zOmkXc"
+ },
+ "source": [
+ "df_goleiros = df19[df19['position'] == 'GK']\n",
+ "df_goleiros.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "77ehyNmSnTIB"
+ },
+ "source": [
+ "df_overall_potential_goleiros = df_goleiros.groupby(by = ['club']).agg({'overall_potential': ['count', 'mean']}).reset_index()\n",
+ "df_overall_potential_goleiros.columns = ['club', 'numero_jogadores', 'media_overall_potential']\n",
+ "df_overall_potential_goleiros.sort_values(by = ['media_overall_potential'], ascending = False, inplace = True)\n",
+ "df_overall_potential_goleiros.head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-dEtuBtF0fiZ"
+ },
+ "source": [
+ "## 20. Quem são os jogadores mais rápidos (variável/atributo 'Sprint speed')?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KWMU1hMMnxTI"
+ },
+ "source": [
+ "df20 = df19.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sezEQIjqnwCZ"
+ },
+ "source": [
+ "df20.sort_values(by = 'sprintspeed', ascending = False).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "aEg0eaFO0lF6"
+ },
+ "source": [
+ "## 21. Quem são os 5 melhores jogadores em termos de chute (força para chutar) (use a variável/atributo 'Shot power')?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xXuj-dc7oA-0"
+ },
+ "source": [
+ "df21 = df20.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8HGT_dM2oEES"
+ },
+ "source": [
+ "df21.sort_values(by = 'shotpower', ascending = False).head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bRk42JIf0moZ"
+ },
+ "source": [
+ "## 22. Quem são os outliers em termos de salário?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qRNaog7y0qI4"
+ },
+ "source": [
+ "### Identificação e tratamento dos Outliers\n",
+ "* Qual o Overall médio do Barcelona, Juventus e Real Madrid?\n",
+ "* E qual o overall médio depois do tratamento dos outliers?\n",
+ "* Quem são os atletas que estão influenciando a média?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_bIxG1Sw9OUB"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Fonte: [Understanding Boxplots](https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qEiikIxNoZkl"
+ },
+ "source": [
+ "df22 = df21.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lGYYvE0BoOoV"
+ },
+ "source": [
+ "q1_salario, q3_salario = df22['wage'].quantile([0.25,0.75]).to_list()\n",
+ "iqr_salario = q3_salario - q1_salario\n",
+ "print(q1_salario, q3_salario)\n",
+ "print(iqr_salario)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PB44VV9pogT1"
+ },
+ "source": [
+ "outlier_salario_inferior = q1_salario - 1.5 * iqr_salario\n",
+ "outlier_salario_superior = q3_salario + 1.5 * iqr_salario\n",
+ "\n",
+ "df_outliers_salario = df22[['name', 'club', 'nationality', 'wage', 'overall', 'potential']]\n",
+ "\n",
+ "# Salários outliers inferiores\n",
+ "df_outliers_salario[df_outliers_salario['wage'] < outlier_salario_inferior]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9867KNNBqG7Z"
+ },
+ "source": [
+ "# Top 10 Salários outliers superior\n",
+ "df_outliers_salario[df_outliers_salario['wage'] > outlier_salario_superior].sort_values(by = ['wage'], ascending = False).head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gT2zGwq90oQ5"
+ },
+ "source": [
+ "## 23. Quem são os outliers em termos de potência no chute?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "05uYj7cwqrdW"
+ },
+ "source": [
+ "df23 = df22.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GzbVRU9HqrdZ"
+ },
+ "source": [
+ "q1_chute, q3_chute = df23['shotpower'].quantile([0.25,0.75]).to_list()\n",
+ "iqr_chute = q3_chute - q1_chute\n",
+ "print(q1_chute, q3_chute)\n",
+ "print(iqr_chute)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V5TQX_yGqrda"
+ },
+ "source": [
+ "outlier_chute_inferior = q1_chute - 1.5 * iqr_chute\n",
+ "outlier_chute_superior = q3_chute + 1.5 * iqr_chute\n",
+ "\n",
+ "df_outliers_chute = df23[['name', 'club', 'nationality', 'shotpower', 'overall', 'potential']]\n",
+ "\n",
+ "# Salários outliers inferiores\n",
+ "df_outliers_chute[df_outliers_chute['shotpower'] < outlier_chute_inferior]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "URj1SYXxqrdc"
+ },
+ "source": [
+ "# Top 10 outliers superiores - shotpower\n",
+ "df_outliers_chute[df_outliers_chute['shotpower'] > outlier_chute_superior].sort_values(by = ['shotpower'], ascending = False).head(10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eHm1qeHx0pza"
+ },
+ "source": [
+ "## 24. Qual a correlação e a interpretação entre as variáveis 'value' e as demais variáveis numéricas do dataframe?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OR6MD2GQ0rNq"
+ },
+ "source": [
+ "## 25. Construa variáveis dummy para as colunas preferred_foot e work_rate. preferred_foot_left;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Z2RTzTxbLzW_"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From 40557e076dcdc9e9d917858ef657899fc7745574 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 19 Oct 2020 17:35:29 -0300
Subject: [PATCH 14/21] Criado usando o Colaboratory
---
...xercicios_exerc\303\255cio Olympics.ipynb" | 371 +++++++++++++++++-
1 file changed, 367 insertions(+), 4 deletions(-)
diff --git "a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb" "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
index 92769c16a..e434f3bb5 100644
--- "a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
+++ "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
@@ -108,8 +108,8 @@
"id": "kQGVQB18-tM_"
},
"source": [
- "#!pip install category_encoders\n",
- "#!pip install update"
+ "!pip install category_encoders\n",
+ "!pip install update"
],
"execution_count": null,
"outputs": []
@@ -1291,7 +1291,7 @@
"id": "ZkmDSUlU7JTw"
},
"source": [
- "!ls \"/content/drive/My Drive/\""
+ "!ls \"/content/drive/My Drive/athlete_events.zip\""
],
"execution_count": null,
"outputs": []
@@ -1327,7 +1327,7 @@
"id": "CQA_Wdxe-aOF"
},
"source": [
- "df_olympics[['sex','season','team','city','sport','medal','height','weight']].head(5)"
+ ""
],
"execution_count": null,
"outputs": []
@@ -1357,6 +1357,347 @@
"execution_count": null,
"outputs": []
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fg929P3DblPr"
+ },
+ "source": [
+ "df_olympics[['sex','season','team','city','sport','medal','height','weight']].head(5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hJ7lAgAPcZ-J"
+ },
+ "source": [
+ "df_atleta2=df_olympics[['height','weight']]\n",
+ "df_atleta2.isnull().sum()\n",
+ "df_atleta2.dropna(inplace=True)\n",
+ "#gráfico\n",
+ "df_atleta2.hist(bins=100)\n",
+ "\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zlka9jjlfmgJ"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_atleta2['height'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('height - Distribuição Normal')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AW4xWnuVf235"
+ },
+ "source": [
+ "plt.figure(figsize = (12, 8))\n",
+ "plt.hist(df_atleta2['weight'], color = 'blue', edgecolor = 'black', bins = int(180/5))\n",
+ "\n",
+ "# Adiciona títulos e labels\n",
+ "plt.title('weight - Distribuição Normal')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QRXHQJ9DfEzr"
+ },
+ "source": [
+ "df_atleta2.plot(kind = 'kde') # KDE (= kernel Density Estimate) ajuda-nos a visualizar a distribuição dos dados, análogo ao histograma."
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jbsJR08RgFOx"
+ },
+ "source": [
+ "df_atleta2.plot()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wThfuOfwgNDY"
+ },
+ "source": [
+ "#padroniza StandardScaler\n",
+ "from sklearn.preprocessing import StandardScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vHTiFkm_gTjw"
+ },
+ "source": [
+ "np.set_printoptions(precision = 3)\n",
+ "# usa alternativa 1 ou alternativa 2\n",
+ "# alternativa 1\n",
+ "atleta2_scale = StandardScaler().fit_transform(df_atleta2) # Combinação dos métodos fit() + transform()\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PmpW2Ny9hoH4"
+ },
+ "source": [
+ "# alternativa 2\n",
+ "atleta2_scale_fit = StandardScaler().fit(df_atleta2) # Aplica o fit() separadamente\n",
+ "atleta2_scale_transform = atleta2_scale_fit.transform(df_atleta2) # Aplica o transform() separadamente.\n",
+ "atleta2_scale_fit_transform = StandardScaler().fit(df_atleta2).transform(df_atleta2) # Aplica fit().transform() encadeado\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "S1OltLNZhvHw"
+ },
+ "source": [
+ "#atleta2_scale\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "i7A4nquHhy8J"
+ },
+ "source": [
+ "#atleta2_scale_fit\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y-hJ8ofQh3lB"
+ },
+ "source": [
+ "#atleta2_scale_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xj_lxSTOh7gI"
+ },
+ "source": [
+ "#atleta2_scale_fit_transform"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0mLy9gKliCRA"
+ },
+ "source": [
+ "#alternativa 1\n",
+ "df_atleta2_scale = atleta2_scale = pd.DataFrame(atleta2_scale, columns = ['height', 'weight'])\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1TWjsfDrihii"
+ },
+ "source": [
+ "#alternativa 2\n",
+ "df_atleta2_scale = pd.DataFrame(atleta2_scale, columns=list(df_atleta2.keys()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hHzx5QQvitVv"
+ },
+ "source": [
+ "df_atleta2_scale.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VZsaqzfjdvLS"
+ },
+ "source": [
+ "#Resolução StandardScaler em comandos concentrados\n",
+ "from sklearn.preprocessing import StandardScaler\n",
+ "atleta2_standard = StandardScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_standard = pd.DataFrame(atleta2_standard, columns=list(df_atleta2.keys()))\n",
+ "df_atleta2_standard.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WJLETmD9jN1w"
+ },
+ "source": [
+ "#padroniza MinMaxScaler\n",
+ "from sklearn.preprocessing import MinMaxScaler"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I73dw7TgjZhg"
+ },
+ "source": [
+ "# usa alternativa 1 ou alternativa 2\n",
+ "# alternativa 1\n",
+ "atleta2_MinMax = MinMaxScaler().fit_transform(df_atleta2) # Combinação dos métodos fit() + transform()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4cEc-1CRjj2H"
+ },
+ "source": [
+ "# alternativa 2\n",
+ "atleta2_MinMax_fit = MinMaxScaler().fit(df_atleta2) # Aplica o fit() separadamente\n",
+ "atleta2_MinMax_transform = atleta2_scale_fit.transform(df_atleta2) # Aplica o transform() separadamente.\n",
+ "atleta2_MinMax_fit_transform = MinMaxScaler().fit(df_atleta2).transform(df_atleta2) # Aplica fit().transform() encadeado"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eW5t52NCj8qv"
+ },
+ "source": [
+ "#alternativa 1\n",
+ "df_atleta2_MinMax = atleta2_MinMax = pd.DataFrame(atleta2_MinMax, columns = ['height', 'weight'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Fe6KupnMkFGg"
+ },
+ "source": [
+ "#alternativa 2\n",
+ "df_atleta2_MinMax = pd.DataFrame(atleta2_MinMax, columns=list(df_atleta2.keys()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y9XHXj0Ujyan"
+ },
+ "source": [
+ "df_atleta2_MinMax.plot(kind = 'kde')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "omhfhcOKdxVh"
+ },
+ "source": [
+ "#Resolução MinMaxScaler em comandos concentrados\n",
+ "from sklearn.preprocessing import MinMaxScaler\n",
+ "atleta2_MinMax = MinMaxScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_MinMax = pd.DataFrame(atleta2_MinMax, columns=list(df_atleta2.keys()))\n",
+ "df_atleta2_MinMax.plot(kind = 'kde')\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rr7mMCqdjLVg"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6JwKjpiRd2Oh"
+ },
+ "source": [
+ "#Resolução RobustScaler em comandos concentrados\n",
+ "from sklearn.preprocessing import RobustScaler\n",
+ "atleta2_Robust = RobustScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_Robust = pd.DataFrame(atleta2_Robust, columns=list(df_atleta2.keys()))\n",
+ "df_atleta2_MinMax.plot(kind = 'kde')\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m2lU3aJIeDvR"
+ },
+ "source": [
+ "df_atleta2_robust['tipo'] = robust\n",
+ "df_atleta2_robust = RobustScaler().fit_transform(df_atleta2)\n",
+ "df_atleta2_robust = pd.DataFrame(atleta2_RobustScaler, columns = ['height', 'wright'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -1371,6 +1712,17 @@
" * Usando a técnica de binning apropriada, pode estabelecer uma relação monotônica (aumentar ou diminuir) entre a variável dependente e independente."
]
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hEnjv-AleB6R"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "code",
"metadata": {
@@ -1473,6 +1825,17 @@
],
"execution_count": null,
"outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2PWN5TF2jv_I"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
}
]
}
\ No newline at end of file
From ab0233acdc7af24f693ba89e409e3c6673916407 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 19 Oct 2020 17:53:57 -0300
Subject: [PATCH 15/21] Criado usando o Colaboratory
---
...xercicios_exerc\303\255cio Olympics.ipynb" | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git "a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb" "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
index e434f3bb5..e0b482ff6 100644
--- "a/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
+++ "b/Notebooks/NB10_04__3DP_3_Data_Transformation_exercicios_exerc\303\255cio Olympics.ipynb"
@@ -1368,6 +1368,65 @@
"execution_count": null,
"outputs": []
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZZw7Nm1EmEEi"
+ },
+ "source": [
+ "#Trate adequadamente as variáveis 'sex', 'season', 'team', 'city', 'sport' e 'medal';\n",
+ "#Encoding Variáveis Categóricas\n",
+ "df_atleta1=df_olympics[['sex','season','team','city','sport','medal']]\n",
+ "\n",
+ "l_atributos = ['sex','season','team','city','sport','medal']\n",
+ "for s_atributo in l_atributos:\n",
+ " s_result = df_atleta1[s_atributo].unique()\n",
+ " print(f'{s_atributo} {s_result}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JJFDaCguoj-X"
+ },
+ "source": [
+ "from sklearn.preprocessing import LabelEncoder, OneHotEncoder"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-nvvR_5doIsR"
+ },
+ "source": [
+ "#l_atributos = ['sex','season','medal']\n",
+ "le = LabelEncoder()\n",
+ "df_atleta1['sex-cat'] = le.fit_transform(df_atleta1['sex'])\n",
+ "df_atleta1['season-cat'] = le.fit_transform(df_atleta1['season'])\n",
+ "#df_atleta1['medal-cat'] = le.fit_transform(df_atleta1['medal'])\n",
+ "df_atleta1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "w204Is8ipdDq"
+ },
+ "source": [
+ "#l_atributos = ['sex','season','medal']\n",
+ "le = LabelEncoder()\n",
+ "df_atleta1['medal-cat'] = le.fit_transform(df_atleta1['medal'])\n",
+ "df_atleta1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "code",
"metadata": {
From ae2dd56db24f64c2942ff75344feeeae02740405 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Tue, 20 Oct 2020 14:14:51 -0300
Subject: [PATCH 16/21] Criado usando o Colaboratory
---
.../NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
index 7ea9a913f..468408c32 100644
--- a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
+++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
@@ -1556,7 +1556,8 @@
"id": "vgoLTamaOC50"
},
"source": [
- "#### Configurar ambiente"
+ " \n",
+ " #### Configurar ambiente"
]
},
{
@@ -1595,7 +1596,7 @@
"id": "GMivDUHEMFKp"
},
"source": [
- "df = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/FIFA.csv?token=AGDJQ63GC7SPIHTGNW73QB27RXRN6') #, index_col= 'PassengerId')\n",
+ "df = pd.read_csv('https://raw.githubusercontent.com/Celso-Omoto/DSWP/master/Dataframes/FIFA.csv') #, index_col= 'PassengerId')\n",
"df.head()"
],
"execution_count": null,
From c0db1f15988ada695f4ab0c9a823e017997b8389 Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Tue, 20 Oct 2020 14:39:29 -0300
Subject: [PATCH 17/21] Criado usando o Colaboratory
---
...ndas__Resposta_Exercicios_Aluno_Fifa.ipynb | 21 +++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
index 468408c32..cb7b4c537 100644
--- a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
+++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
@@ -1648,7 +1648,7 @@
"id": "_hUvJbCqCBBl"
},
"source": [
- "df[['RS', 'LS', 'ST']].head()"
+ "df[['LS','ST','RS','LW','LF','CF','RF','RW','LAM','CAM','RAM','LM','LCM','CM','RCM','RM','LWB','LDM','CDM','RDM','RWB','LB','LCB','CB','RCB','RB']].head()"
],
"execution_count": null,
"outputs": []
@@ -1819,7 +1819,8 @@
"id": "VJSsvOpK71n7"
},
"source": [
- "df4 = df2.copy()"
+ "df4 = df2.copy()\n",
+ "df4.head()"
],
"execution_count": null,
"outputs": []
@@ -1858,9 +1859,10 @@
"id": "ArgK2NVe6vqz"
},
"source": [
- "l_colunas_monetarias = ['Value', 'Wage']\n",
+ "l_colunas_monetarias = ['Value','Wage']\n",
"\n",
"for coluna in l_colunas_monetarias:\n",
+ " print(coluna)\n",
" df4[coluna] = df4[coluna].str.replace('€', '')\n",
" df4[coluna] = df4[coluna].apply(lambda x: transforma_monetarias(x))\n",
"\n",
@@ -2123,7 +2125,18 @@
"\n",
"# Numa única linha ficaria assim:\n",
"df_jogadores_por_paises2 = pd.DataFrame(df7.groupby(by=['nationality']).size(), columns= ['numero_jogadores']).sort_values(by = ['numero_jogadores'], ascending = False).reset_index()\n",
- "df_jogadores_por_paises2"
+ "df_jogadores_por_paises2\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Y_h9sFgiFaCJ"
+ },
+ "source": [
+ ""
],
"execution_count": null,
"outputs": []
From 8fb038cec89d93c2671bd7800507d2a9b1aca2dd Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Fri, 23 Oct 2020 17:22:35 -0300
Subject: [PATCH 18/21] Criado usando o Colaboratory
---
...0__Machine_Learning___DSWP_exercicio.ipynb | 8349 +++++++++++++++++
1 file changed, 8349 insertions(+)
create mode 100644 Notebooks/NB15_00__Machine_Learning___DSWP_exercicio.ipynb
diff --git a/Notebooks/NB15_00__Machine_Learning___DSWP_exercicio.ipynb b/Notebooks/NB15_00__Machine_Learning___DSWP_exercicio.ipynb
new file mode 100644
index 000000000..5264c6e3b
--- /dev/null
+++ b/Notebooks/NB15_00__Machine_Learning___DSWP_exercicio.ipynb
@@ -0,0 +1,8349 @@
+{
+ "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": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ShVXyGj9wkgN"
+ },
+ "source": [
+ "MACHINE LEARNING WITH PYTHON
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "aYQ4cDfcPu4e"
+ },
+ "source": [
+ "___\n",
+ "# **NOTAS E OBSERVAÇÕES**\n",
+ "* Abordar o impacto do desbalanceamento da amostra;\n",
+ "* Colocar AUROC no material e mostrar o cut off para classificação entre 0 e 1;\n",
+ "* Conceitos estatísticos de bias & variance;\n",
+ "* Ver Sklearn.optimize: https://web.telegram.org/#/im?p=g497957288"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5YvhLC_uf4_G"
+ },
+ "source": [
+ "___\n",
+ "# **AGENDA**\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "QgX6n2VDyY1O"
+ },
+ "source": [
+ "___\n",
+ "# **REFERÊNCIAS**\n",
+ "* [scikit-learn - Machine Learning With Python](https://scikit-learn.org/stable/);\n",
+ "* [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n",
+ "* [The Difference Between Artificial Intelligence, Machine Learning, and Deep Learning](https://medium.com/iotforall/the-difference-between-artificial-intelligence-machine-learning-and-deep-learning-3aa67bff5991)\n",
+ "* [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n",
+ "* [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n",
+ "* [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n",
+ "* [The 10 Statistical Techniques Data Scientists Need to Master](https://medium.com/cracking-the-data-science-interview/the-10-statistical-techniques-data-scientists-need-to-master-1ef6dbd531f7)\n",
+ "* [Tune: a library for fast hyperparameter tuning at any scale](https://towardsdatascience.com/fast-hyperparameter-tuning-at-scale-d428223b081c)\n",
+ "* [How to lie with Data Science](https://towardsdatascience.com/how-to-lie-with-data-science-5090f3891d9c)\n",
+ "* [5 Reasons “Logistic Regression” should be the first thing you learn when becoming a Data Scientist](https://towardsdatascience.com/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4)\n",
+ "* [Machine learning on categorical variables](https://towardsdatascience.com/machine-learning-on-categorical-variables-3b76ffe4a7cb)\n",
+ "\n",
+ "## Deep Learning & Neural Networks\n",
+ "\n",
+ "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n",
+ "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n",
+ "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TsCbZd2epfxo"
+ },
+ "source": [
+ "___\n",
+ "# **INTRODUÇÃO**\n",
+ "\n",
+ "* \"__Information is the oil of the 21st century, and analytics is the combustion engine__.\" - Peter Sondergaard, SVP, Garner Research;\n",
+ "\n",
+ "\n",
+ ">O foco deste capítulo será:\n",
+ "* Linear, Logistic Regression, Decision Tree, Random Forest, Support Vector Machine and XGBoost algorithms for building Machine Learning models;\n",
+ "* Entender como resolver problemas de classificação e Regressão;\n",
+ "* Aplicar técnicas de Ensemble como Bagging e Boosting;\n",
+ "* Como medir a acurácia dos modelos de Machine Learning;\n",
+ "* Aprender os principais algoritmos de Machine Learning tanto das técnicas de aprendizagem supervisionada quanto da não-supervisionada.\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HqqB2vaHXMGt"
+ },
+ "source": [
+ "___\n",
+ "# **ARTIFICIAL INTELLIGENCE VS MACHINE LEARNING VS DEEP LEARNING**\n",
+ "* **Machine Learning** - dá aos computadores a capacidade de aprender sem serem explicitamente programados. Os computadores podem melhorar sua capacidade de aprendizagem através da prática de uma tarefa, geralmente usando grandes conjuntos de dados.\n",
+ "* **Deep Learning** - é um método de Machine Learning que depende de redes neurais artificiais, permitindo que os sistemas de computadores aprendam pelo exemplo, assim como nós humanos aprendemos."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "P961GcguXFFA"
+ },
+ "source": [
+ "\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": [
+ "\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": [
+ "\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",
+ "\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",
+ "\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",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MkBSvyorGXQz"
+ },
+ "source": [
+ "___\n",
+ "# **CROSS-VALIDATION**\n",
+ "* K-fold é o método de Cross-Validation (CV) mais conhecido e utilizado;\n",
+ "* Como funciona: divide o dataframe de treinamento em k partes;\n",
+ " * Usa k-1 partes para treinar o modelo e o restante para validar o modelo;\n",
+ " * repete este processo k vezes, sendo que em cada iteração calcula as métricas desejadas (exemplo: acurácia);\n",
+ " * Ao final das k iterações, teremos k métricas das quais calculamos média e desvio-padrão.\n",
+ "\n",
+ " A figura abaixo nos ajuda a entender como funciona CV:\n",
+ "\n",
+ "\n",
+ "\n",
+ "Source: [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n",
+ "\n",
+ "* **valor de k**:\n",
+ " * valor de k (folds): entre 5 e 10 --> Não há regra geral para a escolha de k;\n",
+ " * Quanto maior o valor de k --> menor o viés do CV --> Experimento Estatístico para mostrar o efeito.\n",
+ "\n",
+ "[Applied Predictive Modeling, 2013](https://www.amazon.com/Applied-Predictive-Modeling-Max-Kuhn/dp/1461468485/ref=as_li_ss_tl?ie=UTF8&qid=1520380699&sr=8-1&keywords=applied+predictive+modeling&linkCode=sl1&tag=inspiredalgor-20&linkId=1af1f3de89c11e4a7fd49de2b05e5ebf)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HscfN-a1V043"
+ },
+ "source": [
+ "* **Vantagens do uso de CV**:\n",
+ " * Modelos com melhor acurácia;\n",
+ " * Melhor uso dos dados, pois todos os dados são utilizados como treinamento e validação. Portanto, qualquer problema com os dados serão encontrados nesta fase.\n",
+ "\n",
+ "* **Leitura Adicional**\n",
+ " * [Cross-Validation in Machine Learning](https://towardsdatascience.com/cross-validation-in-machine-learning-72924a69872f)\n",
+ " * [5 Reasons why you should use Cross-Validation in your Data Science Projects](https://towardsdatascience.com/5-reasons-why-you-should-use-cross-validation-in-your-data-science-project-8163311a1e79)\n",
+ " * [Cross-validation: evaluating estimator performance](https://scikit-learn.org/stable/modules/cross_validation.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XRukccWQSklx"
+ },
+ "source": [
+ "## Medidas para avaliarmos a variabilidade presente nos dados\n",
+ "* As principais medidas para medirmos a variabilidade dos dados são amplitude, variância, desvio padrão e coeficiente de variação;\n",
+ "* Estas medidas nos permite concluir se os dados são homogêneos (menor dispersão/variabilidade) ou heterogêneos (maior variabilidade/dispersão).\n",
+ "\n",
+ "* **Na próxima versão, trazer estes conceitos para o Notebook e usar o Python para calcular estas medidas**."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yBR8tWV_lhQq"
+ },
+ "source": [
+ "___\n",
+ "# **ENSEMBLE METHODS** (= Combinar modelos preditivos)\n",
+ "* Métodos\n",
+ " * **Bagging** (Bootstrap AGGregatING)\n",
+ " * **Boosting**\n",
+ " * Stacking --> Não é muito utilizado\n",
+ "* Evita overfitting (Overfitting é quando o modelo/função se ajusta muito bem ao dados de treinamento, sendo ineficiente para generalizar para outras amostras/população).\n",
+ "* Constroi meta-classificadores: combinar os resultados de vários algoritmos para produzir previsões mais precisas e robustas do que as previsões de cada classificador individual.\n",
+ "* Ensemble reduz/minimiza os efeitos das principais causas de erros nos modelos de Machine Learning:\n",
+ " * ruído;\n",
+ " * bias (viés);\n",
+ " * variância --> Principal medida para medir a variabilidade presente nos dados.\n",
+ "\n",
+ "# Referências\n",
+ "* [Simple guide for ensemble learning methods](https://towardsdatascience.com/simple-guide-for-ensemble-learning-methods-d87cc68705a2) - Explica didaticamente como funcionam ensembes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "25RW8u-Sj780"
+ },
+ "source": [
+ "### Leitura Adicional\n",
+ "* [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205)\n",
+ "* [Ensemble Methods in Machine Learning: What are They and Why Use Them?](https://towardsdatascience.com/ensemble-methods-in-machine-learning-what-are-they-and-why-use-them-68ec3f9fef5f)\n",
+ "* [Ensemble Learning Using Scikit-learn](https://towardsdatascience.com/ensemble-learning-using-scikit-learn-85c4531ff86a)\n",
+ "* [Let’s Talk About Machine Learning Ensemble Learning In Python](https://medium.com/fintechexplained/lets-talk-about-machine-learning-ensemble-learning-in-python-382747e5fba8)\n",
+ "* [Boosting, Bagging, and Stacking — Ensemble Methods with sklearn and mlens](https://medium.com/@rrfd/boosting-bagging-and-stacking-ensemble-methods-with-sklearn-and-mlens-a455c0c982de)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FugME1HSl4jJ"
+ },
+ "source": [
+ "___\n",
+ "# **PARAMETER TUNNING** (= Parâmetros ótimos dos modelos de Machine Learning)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "u_147cIRl9F1"
+ },
+ "source": [
+ "## GridSearch (Ferramenta ou meio que vamos utilizar para otimização dos parâmetros dos modelos de ML)\n",
+ "* Encontra os parâmetros ótimos (hyperparameter tunning) que melhoram a acurácia dos modelos.\n",
+ "* Necessita dos seguintes inputs:\n",
+ " * A matrix $X_{p}$ com as $p$ COLUNAS (variáveis ou atributos) do dataframe;\n",
+ " * A matriz $y_{p}$ com a COLUNA-target (vaiável resposta);\n",
+ " * Exemplo: DecisionTree, RandomForestClassifier, XGBoostClassificer e etc;\n",
+ " * Um dicionário com os parâmetros a serem otimizados;\n",
+ " * O número de folds para o método de Cross-validation."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "39Sg77fbTWCO"
+ },
+ "source": [
+ "___\n",
+ "# **MODEL SELECTION & EVALUATION**\n",
+ "> Nesta fase identificamos e aplicamos as melhores métricas (Accuracy, Sensitivity, Specificity, F-Score, AUC, R-Sq, Adj R-SQ, RMSE (Root Mean Square Error)) para avaliar o desempenho/acurácia/performance dos modelos de ML.\n",
+ ">> Treinamos os modelos de ML usando a amostra de treinamento e avaliamos o desempenho/acurácia/performance na amostra de teste/validação.\n",
+ "\n",
+ "* Leitura Adicional\n",
+ " * [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)\n",
+ " * [Confusion matrix and other metrics in machine learning](https://medium.com/hugo-ferreiras-blog/confusion-matrix-and-other-metrics-in-machine-learning-894688cb1c0a)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oQQVzZ2ZTYrB"
+ },
+ "source": [
+ "## Confusion Matrix\n",
+ "* Termos associados à Confusion Matrix:\n",
+ " * **Verdadeiro Positivo** (TP = True Positive): Quando o valor observado é True e o modelo estima como True. Ou seja, o modelo acertou na estimativa.\n",
+ " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: Fraude (Positive) --> Modelo acertou!\n",
+ " * **Verdadeiro Negativo** (TN = True Negative): Quando o valor observado é False e o modelo estima como False. Ou seja, o modelo acertou na estimativa;\n",
+ " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: NÃO-Fraude (Negative) --> Modelo acertou!\n",
+ " * **Falso Positivo** (FP = False Positive): Quando o valor observado é False e o modelo estima como True. Ou seja, o modelo errou na estimativa. \n",
+ " * Exemplo: **Observado**: NÃO-Fraude (Negative); **Modelo**: Fraude (Positive) --> Modelo errou!\n",
+ " * **Falso Negativo** (FN = False Negative): Quando o valor observado é True e o modelo estima como False.\n",
+ " * Exemplo: **Observado**: Fraude (Positive); **Modelo**: NÃO-Fraude (Negative) --> Modelo errou!\n",
+ "\n",
+ "* Consulte [Confusion matrix](https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)\n",
+ "\n",
+ "\n",
+ "\n",
+ "Source: [Confusion Matrix](https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781838555078/6/ch06lvl1sec34/confusion-matrix)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ci-6eiqBTgbL"
+ },
+ "source": [
+ "## Accuracy\n",
+ "> Accuracy - é o número de previsões corretas feitas pelo modelo.\n",
+ "\n",
+ "Responde à seguinte pergunta:\n",
+ "\n",
+ "```\n",
+ "Com que frequência o classificador (modelo preditivo) classifica corretamente?\n",
+ "```\n",
+ "\n",
+ "$$Accuracy= \\frac{TP+TN}{TP+TN+FP+FN}$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F7YI8X5TRx-R"
+ },
+ "source": [
+ "## Precision (ou Specificity)\n",
+ "> **Precision** - fornece informações sobre o desempenho em relação a Falsos Positivos (quantos capturamos).\n",
+ "\n",
+ "Responde à seguinte pergunta:\n",
+ "\n",
+ "```\n",
+ "Com relação ao resultado Positivo, com que frequência o classificador está correto?\n",
+ "```\n",
+ "\n",
+ "\n",
+ "$$Precision= \\frac{TP}{TP+FP}$$\n",
+ "\n",
+ "**Exemplo**: Precison nos dirá a proporção de clientes que o modelo estimou como sendo Fraude quando, na verdade, são fraude.\n",
+ "\n",
+ "**Comentário**: Se nosso foco é minimizar Falso Negativos (FN), então precisamos nos esforçar para termos Recall próximo de 100%."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zO39n8x_Sz3L"
+ },
+ "source": [
+ "## Recall (ou Sensitivity)\n",
+ "> **Recall** - nos fornece informações sobre o desempenho de um classificador em relação a Falsos Negativos (quantos perdemos).\n",
+ "\n",
+ "Responde à seguinte pergunta:\n",
+ "\n",
+ "```\n",
+ "Quando o valor observado é Positivo, com que frequência o classificador está correto?\n",
+ "```\n",
+ "\n",
+ "$$Recall = Sensitivity = \\frac{TP}{TP+FN}$$\n",
+ "\n",
+ "**Exemplo**: Recall é a proporção de clientes observados como Fraude e que o modelo estima como Fraude.\n",
+ "\n",
+ "**Comentário**: Se nosso foco for minimizar Falso Positivos (FP), então precisamos nos esforçar para fazer Precision mais próximo de 100% possível."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "htS6rdHVVXRG"
+ },
+ "source": [
+ "## Specificity\n",
+ "> **Specificity** - proporção de TN por TN+FP.\n",
+ "\n",
+ "Responde à seguinte pergunta:\n",
+ "\n",
+ "```\n",
+ "Quando o valor observado é Negativo, com que frequência o classificador está correto?\n",
+ "```\n",
+ "\n",
+ "**Exemplo**: Specificity é a proporção de clientes NÃO-Fraude que o modelo estima como NÃO-Fraude.\n",
+ "\n",
+ "$$Specificity= \\frac{TN}{TN+FP}$$\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mNn0twadTacc"
+ },
+ "source": [
+ "## F1-Score\n",
+ "> F1-Score é a média harmônica entre Recall e Precision e é um número entre 0 e 1. Quanto mais próximo de 1, melhor. Quanto mais próximo de 0, pior. Ou seja, é um equilíbrio entre Recall e Precision.\n",
+ "\n",
+ "$$F1\\_Score= 2\\left(\\frac{Recall*Precision}{Recall+Precision}\\right)$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rsH9dMxazWCg"
+ },
+ "source": [
+ "# **DATAFRAME-EXEMPLO USADO NESTE TUTORIAL**\n",
+ "> Gerar um dataframe com 18 colunas, sendo 9 informativas, 6 redundantes e 3 repetidas:\n",
+ "\n",
+ "Para saber mais sobre a geração de dataframes-exemplo (toy), consulte [Synthetic data generation — a must-have skill for new data scientists](https://towardsdatascience.com/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GEyDo_EIV_jV"
+ },
+ "source": [
+ "## Definir variáveis globais"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TdwgpZ76WFaT"
+ },
+ "source": [
+ "i_CV = 10 # Número de Cross-Validations'\n",
+ "i_Seed = 20111974 # semente por questões de reproducibilidade\n",
+ "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)"
+ ],
+ "execution_count": 3,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gJTJfpwWzykS"
+ },
+ "source": [
+ "from sklearn.datasets import make_classification\n",
+ "\n",
+ "X, y = make_classification(n_samples = 1000, \n",
+ " n_features = 18, \n",
+ " n_informative = 9, \n",
+ " n_redundant = 6, \n",
+ " n_repeated = 3, \n",
+ " n_classes = 2, \n",
+ " n_clusters_per_class = 1, \n",
+ " random_state=i_Seed)"
+ ],
+ "execution_count": 4,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gWy2IZh3s-o3",
+ "outputId": "d64728be-3319-42df-aa1a-4feab2728aa4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 238
+ }
+ },
+ "source": [
+ "X"
+ ],
+ "execution_count": 5,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[ 0.06844089, 4.21184154, -2.5583024 , ..., -0.63061895,\n",
+ " -0.97831983, -0.88826977],\n",
+ " [-4.8240213 , 0.17950903, -2.98447332, ..., 0.33992045,\n",
+ " 1.89153784, -6.10967565],\n",
+ " [ 1.38953042, -0.226476 , 1.8774004 , ..., -1.47784549,\n",
+ " 0.96052606, 2.06020368],\n",
+ " ...,\n",
+ " [ 1.62548685, 0.43377848, 4.93537285, ..., -4.61990917,\n",
+ " 0.18310709, 6.16040231],\n",
+ " [-2.40619087, -1.65474635, 2.64196493, ..., -1.21427845,\n",
+ " 0.83745861, 0.8254619 ],\n",
+ " [-4.00041881, 2.52475556, -4.15290177, ..., -0.51680266,\n",
+ " 1.72224835, -5.59558306]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 5
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ccjhGnzxtAaV",
+ "outputId": "9e86bfa9-321d-4d94-8e07-1be6453beb79",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "y[0:30] # Semelhante aos casos de fraude: {0, 1}"
+ ],
+ "execution_count": 6,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n",
+ " 1, 1, 0, 1, 0, 1, 0, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 6
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OHO2befKJxR3"
+ },
+ "source": [
+ "___\n",
+ "# **DECISION TREE**\n",
+ "> Decision Trees possuem estrutura em forma de árvores.\n",
+ "\n",
+ "* **Principais Vantagens**:\n",
+ " * São algoritmos fáceis de entender, visualizar e interpretar;\n",
+ " * Captura facilmente padrões não-lineares presentes nos dados;\n",
+ " * Requer pouco poder computacional --> Treinar Decision Trees não requer tanto recurso computacional!\n",
+ " * Lida bem com COLUNAS numéricas ou categóricas;\n",
+ " * Não requer os dados sejam normalizados;\n",
+ " * Pode ser utilizado como Feature Engineering ao lidar com Missing Values;\n",
+ " * Pode ser utilizado como Feature Selection;\n",
+ " * Não requer suposições sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n",
+ "\n",
+ "* **Principais desvantagens**\n",
+ " * Propenso a Overfitting, pois Decision Trees podem construir árvores complexas que não sejam capazes de generalizar bem os dados. As coisas complicam muito se a amostra de treinamento possuir outliers. Portanto, **recomenda-se fortemente a tratar os outliers previamente**.\n",
+ " * Pode criar árvores viesadas se tivermos um dataframe não-balanceado ou que alguma classe seja dominante. Por conta disso, **recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n",
+ "\n",
+ "* **Principais parâmetros**\n",
+ " * **Gini Index** - é uma métrica que mede a frequência com que um ponto/observação aleatoriamente selecionado seria incorretamente identificado.\n",
+ " * Portanto, quanto menor o valor de Gini Index, melhor a COLUNA;\n",
+ " * **Entropy** - é uma métrica que mede aleatoriedade da informação presente nos dados.\n",
+ " * Portanto, quanto maior a entropia da COLUNA, pior ela se torna para nos ajudar a tomar uma conclusão (classificar, por exemplo).\n",
+ "\n",
+ "## **Referências**:\n",
+ "* [1.10. Decision Trees](https://scikit-learn.org/stable/modules/tree.html).\n",
+ "* [Decision Tree Algorithm With Hands On Example](https://medium.com/datadriveninvestor/decision-tree-algorithm-with-hands-on-example-e6c2afb40d38) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n",
+ "* [Intuitive Guide to Understanding Decision Trees](https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7) - ótimo tutorial para aprender, entender, interpretar e calcular os índices de Gini e entropia.\n",
+ "* [The Complete Guide to Decision Trees](https://towardsdatascience.com/the-complete-guide-to-decision-trees-28a4e3c7be14)\n",
+ "* [Creating and Visualizing Decision Tree Algorithm in Machine Learning Using Sklearn](https://intellipaat.com/blog/decision-tree-algorithm-in-machine-learning/) - Muito didático!\n",
+ "* [Decision Trees in Machine Learning](https://towardsdatascience.com/decision-trees-in-machine-learning-641b9c4e8052)\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FrMkPN5aLp0Y"
+ },
+ "source": [
+ "## Carregar as bibliotecas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FVU1CM0PKgO4"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "import warnings\n",
+ "warnings.filterwarnings(\"ignore\")"
+ ],
+ "execution_count": 7,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "15clh4XrISpz"
+ },
+ "source": [
+ "## Carregar/Ler os dados"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UMPL46w2IWJw"
+ },
+ "source": [
+ "l_colunas = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13', 'v14', 'v15', 'v16', 'v17', 'v18']\n",
+ "\n",
+ "df_X = pd.DataFrame(X, columns = l_colunas)\n",
+ "df_y = pd.DataFrame(y, columns = ['target'])"
+ ],
+ "execution_count": 8,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MFaQF2MGFl_M",
+ "outputId": "b0ac8b65-3fe7-47b0-e120-bcf2b21e441b",
+ "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",
+ " v1 | \n",
+ " v2 | \n",
+ " v3 | \n",
+ " v4 | \n",
+ " v5 | \n",
+ " v6 | \n",
+ " v7 | \n",
+ " v8 | \n",
+ " v9 | \n",
+ " v10 | \n",
+ " v11 | \n",
+ " v12 | \n",
+ " v13 | \n",
+ " v14 | \n",
+ " v15 | \n",
+ " v16 | \n",
+ " v17 | \n",
+ " v18 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0.068441 | \n",
+ " 4.211842 | \n",
+ " -2.558302 | \n",
+ " 3.665482 | \n",
+ " -3.835158 | \n",
+ " 3.499851 | \n",
+ " 2.490856 | \n",
+ " 3.665482 | \n",
+ " 0.245117 | \n",
+ " 0.867172 | \n",
+ " 2.865546 | \n",
+ " 0.493956 | \n",
+ " -5.148596 | \n",
+ " 2.865546 | \n",
+ " 3.499851 | \n",
+ " -0.630619 | \n",
+ " -0.978320 | \n",
+ " -0.888270 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " -4.824021 | \n",
+ " 0.179509 | \n",
+ " -2.984473 | \n",
+ " 1.033618 | \n",
+ " -3.893426 | \n",
+ " 3.428734 | \n",
+ " -3.334605 | \n",
+ " 1.033618 | \n",
+ " -0.882780 | \n",
+ " -0.753281 | \n",
+ " 1.441522 | \n",
+ " -1.395514 | \n",
+ " -4.002880 | \n",
+ " 1.441522 | \n",
+ " 3.428734 | \n",
+ " 0.339920 | \n",
+ " 1.891538 | \n",
+ " -6.109676 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1.389530 | \n",
+ " -0.226476 | \n",
+ " 1.877400 | \n",
+ " 2.713426 | \n",
+ " 4.630257 | \n",
+ " 0.516455 | \n",
+ " -3.743027 | \n",
+ " 2.713426 | \n",
+ " 1.284039 | \n",
+ " 2.030797 | \n",
+ " -1.095536 | \n",
+ " 1.560159 | \n",
+ " -1.014211 | \n",
+ " -1.095536 | \n",
+ " 0.516455 | \n",
+ " -1.477845 | \n",
+ " 0.960526 | \n",
+ " 2.060204 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1.145809 | \n",
+ " 2.255946 | \n",
+ " 0.207364 | \n",
+ " 4.665817 | \n",
+ " 2.294678 | \n",
+ " 6.501306 | \n",
+ " 0.964770 | \n",
+ " 4.665817 | \n",
+ " 0.119410 | \n",
+ " 3.196354 | \n",
+ " 1.894787 | \n",
+ " 3.519138 | \n",
+ " -4.757807 | \n",
+ " 1.894787 | \n",
+ " 6.501306 | \n",
+ " -3.789029 | \n",
+ " 0.579491 | \n",
+ " 1.397106 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " -0.936646 | \n",
+ " 3.697163 | \n",
+ " -3.363617 | \n",
+ " 3.805126 | \n",
+ " -1.754430 | \n",
+ " 4.954346 | \n",
+ " 0.406605 | \n",
+ " 3.805126 | \n",
+ " -0.824738 | \n",
+ " 1.382591 | \n",
+ " 1.665704 | \n",
+ " -0.649758 | \n",
+ " -3.513036 | \n",
+ " 1.665704 | \n",
+ " 4.954346 | \n",
+ " 0.257052 | \n",
+ " 0.904244 | \n",
+ " -3.071354 | \n",
+ "
\n",
+ " \n",
+ "
\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": "07b35596-7af9-4594-d74e-2d5fb6a0826c",
+ "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": "9a4bcdd2-1ed2-4d82-c470-d6fe7d640726",
+ "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": "9348f412-5000-427a-a5ed-addbc0f53bd8",
+ "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",
+ " v1 | \n",
+ " v2 | \n",
+ " v3 | \n",
+ " v4 | \n",
+ " v5 | \n",
+ " v6 | \n",
+ " v7 | \n",
+ " v8 | \n",
+ " v9 | \n",
+ " v10 | \n",
+ " v11 | \n",
+ " v12 | \n",
+ " v13 | \n",
+ " v14 | \n",
+ " v15 | \n",
+ " v16 | \n",
+ " v17 | \n",
+ " v18 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ " 1000.000000 | \n",
+ "
\n",
+ " \n",
+ " | mean | \n",
+ " -0.085159 | \n",
+ " 1.034227 | \n",
+ " 0.657408 | \n",
+ " 1.405317 | \n",
+ " 0.687279 | \n",
+ " 1.131560 | \n",
+ " 0.108053 | \n",
+ " 1.405317 | \n",
+ " 1.007023 | \n",
+ " 1.048801 | \n",
+ " 0.079248 | \n",
+ " 0.001650 | \n",
+ " -0.365438 | \n",
+ " 0.079248 | \n",
+ " 1.131560 | \n",
+ " -0.027751 | \n",
+ " 0.984606 | \n",
+ " 0.633624 | \n",
+ "
\n",
+ " \n",
+ " | std | \n",
+ " 2.002247 | \n",
+ " 1.631507 | \n",
+ " 3.608772 | \n",
+ " 2.256857 | \n",
+ " 4.019598 | \n",
+ " 4.481832 | \n",
+ " 1.981307 | \n",
+ " 2.256857 | \n",
+ " 1.863288 | \n",
+ " 1.643900 | \n",
+ " 1.949273 | \n",
+ " 1.932641 | \n",
+ " 4.160668 | \n",
+ " 1.949273 | \n",
+ " 4.481832 | \n",
+ " 2.065455 | \n",
+ " 1.850593 | \n",
+ " 3.552991 | \n",
+ "
\n",
+ " \n",
+ " | min | \n",
+ " -6.944169 | \n",
+ " -4.620754 | \n",
+ " -16.300139 | \n",
+ " -6.235192 | \n",
+ " -12.454256 | \n",
+ " -14.305401 | \n",
+ " -6.152747 | \n",
+ " -6.235192 | \n",
+ " -5.484992 | \n",
+ " -3.293216 | \n",
+ " -7.135349 | \n",
+ " -5.705500 | \n",
+ " -9.120941 | \n",
+ " -7.135349 | \n",
+ " -14.305401 | \n",
+ " -6.009023 | \n",
+ " -5.035184 | \n",
+ " -11.439074 | \n",
+ "
\n",
+ " \n",
+ " | 25% | \n",
+ " -1.305566 | \n",
+ " -0.089052 | \n",
+ " -1.623657 | \n",
+ " -0.152888 | \n",
+ " -1.854645 | \n",
+ " -1.684751 | \n",
+ " -1.216983 | \n",
+ " -0.152888 | \n",
+ " -0.240908 | \n",
+ " -0.012710 | \n",
+ " -1.209675 | \n",
+ " -1.292162 | \n",
+ " -3.555363 | \n",
+ " -1.209675 | \n",
+ " -1.684751 | \n",
+ " -1.436673 | \n",
+ " -0.261610 | \n",
+ " -1.691346 | \n",
+ "
\n",
+ " \n",
+ " | 50% | \n",
+ " 0.052523 | \n",
+ " 0.994150 | \n",
+ " 0.573849 | \n",
+ " 1.449931 | \n",
+ " 0.812364 | \n",
+ " 1.281504 | \n",
+ " 0.167091 | \n",
+ " 1.449931 | \n",
+ " 1.066125 | \n",
+ " 1.012899 | \n",
+ " 0.180344 | \n",
+ " 0.035237 | \n",
+ " -0.966638 | \n",
+ " 0.180344 | \n",
+ " 1.281504 | \n",
+ " -0.000190 | \n",
+ " 0.975793 | \n",
+ " 0.844784 | \n",
+ "
\n",
+ " \n",
+ " | 75% | \n",
+ " 1.383853 | \n",
+ " 2.071995 | \n",
+ " 3.038586 | \n",
+ " 2.887141 | \n",
+ " 3.413952 | \n",
+ " 4.008103 | \n",
+ " 1.438719 | \n",
+ " 2.887141 | \n",
+ " 2.288188 | \n",
+ " 2.187202 | \n",
+ " 1.439199 | \n",
+ " 1.315342 | \n",
+ " 2.745806 | \n",
+ " 1.439199 | \n",
+ " 4.008103 | \n",
+ " 1.365369 | \n",
+ " 2.256504 | \n",
+ " 3.109330 | \n",
+ "
\n",
+ " \n",
+ " | max | \n",
+ " 4.997172 | \n",
+ " 7.354860 | \n",
+ " 11.720165 | \n",
+ " 8.494566 | \n",
+ " 12.844418 | \n",
+ " 15.999803 | \n",
+ " 6.293550 | \n",
+ " 8.494566 | \n",
+ " 8.146559 | \n",
+ " 6.523180 | \n",
+ " 6.252448 | \n",
+ " 5.538216 | \n",
+ " 11.259350 | \n",
+ " 6.252448 | \n",
+ " 15.999803 | \n",
+ " 6.531561 | \n",
+ " 7.646802 | \n",
+ " 12.090528 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ "\n",
+ "* Dividir os dados/amostras em:\n",
+ " * **Amostra de treinamento**: usado para treinar o modelo e otimizar os hiperparâmetros;\n",
+ " * **Amostra de teste**: usado para verificar se o modelo otimizado funciona em dados totalmente desconhecidos. É nesta amostra de teste que avaliamos a performance do modelo em termos de generalização (trabalhar com dados que não lhe foi apresentado);\n",
+ "* Geralmente usamos 70% da amostra para treinamento e 30% validação. Outras opções são usar os percentuais 80/20 ou 75/25 (default).\n",
+ "* Consulte [sklearn.model_selection.train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) para mais detalhes.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8sKBgs-QOOfn"
+ },
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)"
+ ],
+ "execution_count": 13,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TPTKBBHgOpoA",
+ "outputId": "8f521310-6ec5-49f2-fdfb-1acb336a3dd1",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "X_treinamento.shape"
+ ],
+ "execution_count": 14,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(700, 18)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 14
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lEn_LLs2OtRI",
+ "outputId": "163839bc-7ff2-4fb8-c217-4752d857eb3e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "y_treinamento.shape"
+ ],
+ "execution_count": 15,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(700, 1)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 15
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_uAw8EcyOvrG",
+ "outputId": "9ecadc3e-2370-438b-ff14-9fdff53733aa",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "X_teste.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": "6ecf6284-b13f-4816-bb63-d5afd536d92e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "y_teste.shape"
+ ],
+ "execution_count": 17,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(300, 1)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 17
+ }
+ ]
+ },
+ {
+ "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": "07e2ad08-50ab-4bd0-a586-d47c3f46833e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "!pip install graphviz\n",
+ "!pip install pydotplus"
+ ],
+ "execution_count": 18,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: graphviz in /usr/local/lib/python3.6/dist-packages (0.10.1)\n",
+ "Requirement already satisfied: pydotplus in /usr/local/lib/python3.6/dist-packages (2.0.2)\n",
+ "Requirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pydotplus) (2.4.7)\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v_pF-HH3JKL2"
+ },
+ "source": [
+ "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n",
+ "#from sklearn.model_selection import train_test_split\n",
+ "#from sklearn.metrics import classification_report\n",
+ "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n",
+ "\n",
+ "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n",
+ "from sklearn.model_selection import cross_val_score # Para o CV (Cross-Validation)\n",
+ "from time import time\n",
+ "from operator import itemgetter\n",
+ "from scipy.stats import randint\n",
+ "\n",
+ "from sklearn.tree import export_graphviz\n",
+ "from sklearn.externals.six import StringIO \n",
+ "from IPython.display import Image \n",
+ "import pydotplus\n",
+ "\n",
+ "np.set_printoptions(suppress=True)"
+ ],
+ "execution_count": 19,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9ROlyvgij2yl"
+ },
+ "source": [
+ "Função para plotar a Confusion Matrix extraído de [Confusion Matrix Visualization](https://medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "klQ0FLOIgeX1"
+ },
+ "source": [
+ "def mostra_confusion_matrix(cf, \n",
+ " group_names = None, \n",
+ " categories = 'auto', \n",
+ " count = True, \n",
+ " percent = True, \n",
+ " cbar = True, \n",
+ " xyticks = False, \n",
+ " xyplotlabels = True, \n",
+ " sum_stats = True, \n",
+ " figsize = (8, 8), \n",
+ " cmap = 'Blues'):\n",
+ " '''\n",
+ " This function will make a pretty plot of an sklearn Confusion Matrix cm using a Seaborn heatmap visualization.\n",
+ " Arguments\n",
+ " ---------\n",
+ " cf: confusion matrix to be passed in\n",
+ " group_names: List of strings that represent the labels row by row to be shown in each square.\n",
+ " categories: List of strings containing the categories to be displayed on the x,y axis. Default is 'auto'\n",
+ " count: If True, show the raw number in the confusion matrix. Default is True.\n",
+ " normalize: If True, show the proportions for each category. Default is True.\n",
+ " cbar: If True, show the color bar. The cbar values are based off the values in the confusion matrix.\n",
+ " Default is True.\n",
+ " xyticks: If True, show x and y ticks. Default is True.\n",
+ " xyplotlabels: If True, show 'True Label' and 'Predicted Label' on the figure. Default is True.\n",
+ " sum_stats: If True, display summary statistics below the figure. Default is True.\n",
+ " figsize: Tuple representing the figure size. Default will be the matplotlib rcParams value.\n",
+ " cmap: Colormap of the values displayed from matplotlib.pyplot.cm. Default is 'Blues'\n",
+ " See http://matplotlib.org/examples/color/colormaps_reference.html\n",
+ " '''\n",
+ "\n",
+ " # CODE TO GENERATE TEXT INSIDE EACH SQUARE\n",
+ " blanks = ['' for i in range(cf.size)]\n",
+ "\n",
+ " if group_names and len(group_names)==cf.size:\n",
+ " group_labels = [\"{}\\n\".format(value) for value in group_names]\n",
+ " else:\n",
+ " group_labels = blanks\n",
+ "\n",
+ " if count:\n",
+ " group_counts = [\"{0:0.0f}\\n\".format(value) for value in cf.flatten()]\n",
+ " else:\n",
+ " group_counts = blanks\n",
+ "\n",
+ " if percent:\n",
+ " group_percentages = [\"{0:.2%}\".format(value) for value in cf.flatten()/np.sum(cf)]\n",
+ " else:\n",
+ " group_percentages = blanks\n",
+ "\n",
+ " box_labels = [f\"{v1}{v2}{v3}\".strip() for v1, v2, v3 in zip(group_labels,group_counts,group_percentages)]\n",
+ " box_labels = np.asarray(box_labels).reshape(cf.shape[0],cf.shape[1])\n",
+ "\n",
+ " # CODE TO GENERATE SUMMARY STATISTICS & TEXT FOR SUMMARY STATS\n",
+ " if sum_stats:\n",
+ " #Accuracy is sum of diagonal divided by total observations\n",
+ " accuracy = np.trace(cf) / float(np.sum(cf))\n",
+ "\n",
+ " #if it is a binary confusion matrix, show some more stats\n",
+ " if len(cf)==2:\n",
+ " #Metrics for Binary Confusion Matrices\n",
+ " precision = cf[1,1] / sum(cf[:,1])\n",
+ " recall = cf[1,1] / sum(cf[1,:])\n",
+ " f1_score = 2*precision*recall / (precision + recall)\n",
+ " stats_text = \"\\n\\nAccuracy={:0.3f}\\nPrecision={:0.3f}\\nRecall={:0.3f}\\nF1 Score={:0.3f}\".format(accuracy,precision,recall,f1_score)\n",
+ " else:\n",
+ " stats_text = \"\\n\\nAccuracy={:0.3f}\".format(accuracy)\n",
+ " else:\n",
+ " stats_text = \"\"\n",
+ "\n",
+ " # SET FIGURE PARAMETERS ACCORDING TO OTHER ARGUMENTS\n",
+ " if figsize==None:\n",
+ " #Get default figure size if not set\n",
+ " figsize = plt.rcParams.get('figure.figsize')\n",
+ "\n",
+ " if xyticks==False:\n",
+ " #Do not show categories if xyticks is False\n",
+ " categories=False\n",
+ "\n",
+ " # MAKE THE HEATMAP VISUALIZATION\n",
+ " plt.figure(figsize=figsize)\n",
+ " sns.heatmap(cf,annot=box_labels,fmt=\"\",cmap=cmap,cbar=cbar,xticklabels=categories,yticklabels=categories)\n",
+ "\n",
+ " if xyplotlabels:\n",
+ " plt.ylabel('True label')\n",
+ " plt.xlabel('Predicted label' + stats_text)\n",
+ " else:\n",
+ " plt.xlabel(stats_text)"
+ ],
+ "execution_count": 20,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YJMS9ePQ6B6t"
+ },
+ "source": [
+ "**Atenção**: Para evitar overfitting nos algoritmos DecisionTreeClassifier, considere min_samples_split = 2 como default."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nNeRHYePJc-r"
+ },
+ "source": [
+ "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n",
+ "\n",
+ "# Instancia (configuração do Decision Trees) com os parâmetros sugeridos para se evitar overfitting:\n",
+ "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n",
+ " splitter = 'best', \n",
+ " max_depth = None, \n",
+ " min_samples_split = 2, \n",
+ " min_samples_leaf = 1, \n",
+ " min_weight_fraction_leaf = 0.0, \n",
+ " max_features = None, \n",
+ " random_state = i_Seed, \n",
+ " max_leaf_nodes = None, \n",
+ " min_impurity_decrease = 0.0, \n",
+ " min_impurity_split = None, \n",
+ " class_weight = None, \n",
+ " presort = False)"
+ ],
+ "execution_count": 21,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gVLZznprx2YX",
+ "outputId": "c0aa7ba6-132c-4b36-844a-703c1e5facf4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "# Objeto/classificador configurado\n",
+ "ml_DT"
+ ],
+ "execution_count": 22,
+ "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": 22
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OgAHfXVo-Nw8",
+ "outputId": "e312d5ca-a17e-46a7-bbc4-f0e7c7d92e5a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "# Treina o algoritmo: fit(df)\n",
+ "ml_DT.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 23,
+ "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": 23
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ohmGCDpfyhvV",
+ "outputId": "e57e03a4-b85d-4fd0-879b-d905f65b8168",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "i_CV"
+ ],
+ "execution_count": 24,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "10"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 24
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6exa9D8R2fDJ",
+ "outputId": "d5f76459-4c2c-4d06-d77e-195913cbb16f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Cross-Validation com k = 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_DT, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": 25,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média das Acurácias calculadas pelo CV....: 91.43\n",
+ "std médio das Acurácias calculadas pelo CV: 3.44\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Uxoplcea0byV",
+ "outputId": "9cea4e91-5b15-4323-9a20-6edbbd7d9637",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_scores_CV # array com os scores a cada iteração do CV"
+ ],
+ "execution_count": 26,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.9 , 0.98571429, 0.85714286, 0.92857143, 0.88571429,\n",
+ " 0.94285714, 0.92857143, 0.9 , 0.88571429, 0.92857143])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 26
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y3k-PcbN0o_i",
+ "outputId": "c844a899-f07e-4db6-e35b-38ec468497ce",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "a_scores_CV.mean()"
+ ],
+ "execution_count": 27,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.9142857142857144"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 27
+ }
+ ]
+ },
+ {
+ "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": "732065c8-85f0-4169-9526-0c68123c6ee8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "print(f'Acurácias: {a_scores_CV}')"
+ ],
+ "execution_count": 29,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Acurácias: [0.9 0.98571429 0.85714286 0.92857143 0.88571429 0.94285714\n",
+ " 0.92857143 0.9 0.88571429 0.92857143]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sI31WkZs2ht_"
+ },
+ "source": [
+ "# Faz predições usando o classificador (Decision Trees) para inferir na amostra de teste:\n",
+ "y_pred = ml_DT.predict(X_teste)"
+ ],
+ "execution_count": 30,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rfapj3OG13PG",
+ "outputId": "6f217d76-774a-4b20-8b75-e40e0eeb27d8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "y_pred[0:30]"
+ ],
+ "execution_count": 31,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,\n",
+ " 1, 0, 0, 1, 1, 0, 1, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 31
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sc88ofqh16RT",
+ "outputId": "d1261312-3bd7-414f-cfb0-9a2a6d44788e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "y[0:30]"
+ ],
+ "execution_count": 32,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,\n",
+ " 1, 1, 0, 1, 0, 1, 0, 1])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 32
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fSaVzJ9xFpwW",
+ "outputId": "0317eccb-2f78-484c-c383-24950f8e5a72",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 538
+ }
+ },
+ "source": [
+ "# Confusion Matrix\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)"
+ ],
+ "execution_count": 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\"], \n",
+ " \"min_samples_split\": [2, 5, 10, 30, 50, 70, 90, 120, 150, 180, 210, 240, 270, 350, 400], \n",
+ " \"max_depth\": [None, 2, 5, 9, 15], \n",
+ " \"min_samples_leaf\": [20, 40, 60, 80, 100], \n",
+ " \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10, 15]}"
+ ],
+ "execution_count": 34,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BtajXuuUpGwq",
+ "outputId": "57b0fe72-b999-4d1c-d9e3-2a48dc9c28ad",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 340
+ }
+ },
+ "source": [
+ "d_parametros_DT"
+ ],
+ "execution_count": 35,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'criterion': ['gini', 'entropy'],\n",
+ " 'max_depth': [None, 2, 5, 9, 15],\n",
+ " 'max_leaf_nodes': [None, 2, 3, 4, 5, 10, 15],\n",
+ " 'min_samples_leaf': [20, 40, 60, 80, 100],\n",
+ " 'min_samples_split': [2,\n",
+ " 5,\n",
+ " 10,\n",
+ " 30,\n",
+ " 50,\n",
+ " 70,\n",
+ " 90,\n",
+ " 120,\n",
+ " 150,\n",
+ " 180,\n",
+ " 210,\n",
+ " 240,\n",
+ " 270,\n",
+ " 350,\n",
+ " 400]}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 35
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "H8gNSs0G0A-L"
+ },
+ "source": [
+ "```\n",
+ "grid_search = GridSearchCV(ml_DT, param_grid= d_parametros_DT, cv = i_CV, n_jobs= -1)\n",
+ "start = time()\n",
+ "grid_search.fit(X_treinamento, y_treinamento)\n",
+ "tempo_elapsed= time()-start\n",
+ "print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos para estimar {len(grid_search.cv_results_)} modelos candidatos\")\n",
+ "\n",
+ "GridSearchCV levou 1999.12 segundos para estimar 23 modelos candidatos\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ap3WMXqDthu9"
+ },
+ "source": [
+ "# Definindo a função para o GridSearchCV\n",
+ "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV):\n",
+ " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs= -1, verbose= 10, scoring= 'accuracy')\n",
+ " start = time()\n",
+ " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n",
+ " tempo_elapsed= time()-start\n",
+ " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n",
+ "\n",
+ " # Parâmetros que otimizam a classificação:\n",
+ " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n",
+ " \n",
+ " if ml_Opt == 'ml_DT2':\n",
+ " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n",
+ " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n",
+ " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n",
+ " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n",
+ " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n",
+ " random_state= i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_RF2':\n",
+ " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n",
+ " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n",
+ " max_features= ml_GridSearchCV.best_params_['max_features'],\n",
+ " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n",
+ " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n",
+ " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n",
+ " random_state= i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_AB2':\n",
+ " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n",
+ " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n",
+ " base_estimator=RandomForestClassifier(bootstrap = False, \n",
+ " max_depth = 10, \n",
+ " max_features = 'auto', \n",
+ " min_samples_leaf = 1, \n",
+ " min_samples_split = 2, \n",
+ " n_estimators = 400), \n",
+ " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n",
+ " random_state = i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_GB2':\n",
+ " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n",
+ " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n",
+ " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n",
+ " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n",
+ " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n",
+ " max_features = ml_GridSearchCV.best_params_['max_features'])\n",
+ " \n",
+ " elif ml_Opt == 'ml_XGB2':\n",
+ " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n",
+ " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n",
+ " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n",
+ " subsample= ml_GridSearchCV.best_params_['subsample'], \n",
+ " gamma= ml_GridSearchCV.best_params_['gamma'], \n",
+ " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n",
+ " \n",
+ " # Treina novamente usando os parametros otimizados...\n",
+ " ml_Opt.fit(X_treinamento, y_treinamento)\n",
+ "\n",
+ " # Cross-Validation com 10 folds\n",
+ " print(f'\\n********* CROSS-VALIDATION ***********')\n",
+ " a_scores_CV = cross_val_score(ml_Opt, X_treinamento, y_treinamento, cv = i_CV)\n",
+ " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n",
+ "\n",
+ " # Faz predições com os parametros otimizados...\n",
+ " y_pred = ml_Opt.predict(X_teste)\n",
+ " \n",
+ " # Importância das COLUNAS\n",
+ " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n",
+ " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n",
+ " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n",
+ " print(df_importancia_variaveis)\n",
+ "\n",
+ " # Matriz de Confusão\n",
+ " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n",
+ " cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n",
+ " cf_categories = ['Zero', 'One']\n",
+ " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n",
+ "\n",
+ " return ml_Opt, ml_GridSearchCV.best_params_"
+ ],
+ "execution_count": 36,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "44-BRnNjBT25",
+ "outputId": "a73bf3b0-2831-4396-f98e-fa67b06c9835",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "# Invoca a função com o modelo baseline\n",
+ "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": 37,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n",
+ "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 1.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 1.6s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1796s.) Setting batch_size=2.\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0489s.) Setting batch_size=4.\n",
+ "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 1.7s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0863s.) Setting batch_size=8.\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1844s.) Setting batch_size=16.\n",
+ "[Parallel(n_jobs=-1)]: Done 58 tasks | elapsed: 2.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 186 tasks | elapsed: 2.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 330 tasks | elapsed: 3.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 506 tasks | elapsed: 4.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 682 tasks | elapsed: 5.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 890 tasks | elapsed: 7.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 1098 tasks | elapsed: 8.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 1338 tasks | elapsed: 9.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 1578 tasks | elapsed: 10.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 1850 tasks | elapsed: 12.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 2122 tasks | elapsed: 13.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 2426 tasks | elapsed: 15.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 2730 tasks | elapsed: 17.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 3066 tasks | elapsed: 19.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 3402 tasks | elapsed: 21.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 3770 tasks | elapsed: 23.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 4138 tasks | elapsed: 25.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 4538 tasks | elapsed: 27.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 4938 tasks | elapsed: 30.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 5370 tasks | elapsed: 32.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 5802 tasks | elapsed: 35.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 6266 tasks | elapsed: 37.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 6730 tasks | elapsed: 39.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 7226 tasks | elapsed: 42.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 7722 tasks | elapsed: 45.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 8250 tasks | elapsed: 47.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 8778 tasks | elapsed: 50.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 9338 tasks | elapsed: 53.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 9898 tasks | elapsed: 56.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 10490 tasks | elapsed: 1.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 11082 tasks | elapsed: 1.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 11706 tasks | elapsed: 1.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 12330 tasks | elapsed: 1.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 12986 tasks | elapsed: 1.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 13642 tasks | elapsed: 1.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 14330 tasks | elapsed: 1.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 15018 tasks | elapsed: 1.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 15738 tasks | elapsed: 1.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 16458 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 17210 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 17962 tasks | elapsed: 1.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 18746 tasks | elapsed: 1.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 19530 tasks | elapsed: 1.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 20346 tasks | elapsed: 1.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 21162 tasks | elapsed: 2.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 22010 tasks | elapsed: 2.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 22858 tasks | elapsed: 2.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 23738 tasks | elapsed: 2.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 24618 tasks | elapsed: 2.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 25530 tasks | elapsed: 2.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 26442 tasks | elapsed: 2.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 27386 tasks | elapsed: 2.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 28330 tasks | elapsed: 2.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 29306 tasks | elapsed: 2.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 30282 tasks | elapsed: 2.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 31290 tasks | elapsed: 3.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 32298 tasks | elapsed: 3.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 33338 tasks | elapsed: 3.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 34378 tasks | elapsed: 3.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 35450 tasks | elapsed: 3.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 36522 tasks | elapsed: 3.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 37626 tasks | elapsed: 3.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 38730 tasks | elapsed: 3.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 39866 tasks | elapsed: 4.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 41002 tasks | elapsed: 4.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 42170 tasks | elapsed: 4.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 43338 tasks | elapsed: 4.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 44538 tasks | elapsed: 4.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 45738 tasks | elapsed: 4.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 46970 tasks | elapsed: 4.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 48202 tasks | elapsed: 5.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 49466 tasks | elapsed: 5.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 50730 tasks | elapsed: 5.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 52026 tasks | elapsed: 5.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 5.5min finished\n"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 70}\n",
+ "\n",
+ "DecisionTreeClassifier *********************************************************************************************************\n",
+ "\n",
+ "********* CROSS-VALIDATION ***********\n",
+ "Média das Acurácias calculadas pelo CV....: 87.14\n",
+ "std médio das Acurácias calculadas pelo CV: 4.33\n",
+ "\n",
+ "********* IMPORTÂNCIA DAS COLUNAS ***********\n",
+ " coluna importancia\n",
+ "12 v13 0.735896\n",
+ "0 v1 0.135030\n",
+ "9 v10 0.090888\n",
+ "6 v7 0.025768\n",
+ "1 v2 0.012418\n",
+ "3 v4 0.000000\n",
+ "4 v5 0.000000\n",
+ "5 v6 0.000000\n",
+ "7 v8 0.000000\n",
+ "8 v9 0.000000\n",
+ "10 v11 0.000000\n",
+ "11 v12 0.000000\n",
+ "2 v3 0.000000\n",
+ "13 v14 0.000000\n",
+ "14 v15 0.000000\n",
+ "15 v16 0.000000\n",
+ "16 v17 0.000000\n",
+ "17 v18 0.000000\n",
+ "\n",
+ "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gmCkjGjPJMLr"
+ },
+ "source": [
+ "### Visualizar o resultado"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cIc3ZgaISEd0",
+ "outputId": "db25ff3b-7957-438b-9a1d-c8327cf1b71c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 753
+ }
+ },
+ "source": [
+ "from sklearn.tree import export_graphviz\n",
+ "from sklearn.externals.six import StringIO \n",
+ "from IPython.display import Image \n",
+ "import pydotplus\n",
+ "\n",
+ "dot_data = StringIO()\n",
+ "export_graphviz(ml_DT2, out_file = dot_data, filled = True, rounded = True, special_characters = True, feature_names = l_colunas, class_names = ['0','1'])\n",
+ "\n",
+ "graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) \n",
+ "graph.write_png('DecisionTree.png')\n",
+ "Image(graph.create_png())"
+ ],
+ "execution_count": 40,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 40
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "e1R2GBkbnV37"
+ },
+ "source": [
+ "## Selecionar as COLUNAS importantes/relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vv7GKBvs6Ybf"
+ },
+ "source": [
+ "# Função desenvolvida para Selecionar COLUNAS relevantes\n",
+ "from sklearn.feature_selection import SelectFromModel\n",
+ "\n",
+ "def seleciona_colunas_relevantes(modelo, X_treinamento, X_teste, threshold = 0.05):\n",
+ " # Cria um seletor para selecionar as COLUNAS com importância > threshold\n",
+ " sfm = SelectFromModel(modelo, threshold)\n",
+ " \n",
+ " # Treina o seletor\n",
+ " sfm.fit(X_treinamento, y_treinamento)\n",
+ "\n",
+ " # Mostra o indice das COLUNAS mais importantes\n",
+ " print(f'\\n********** COLUNAS Relevantes ******')\n",
+ " print(sfm.get_support(indices=True))\n",
+ "\n",
+ " # Seleciona somente as COLUNAS relevantes\n",
+ " X_treinamento_I = sfm.transform(X_treinamento)\n",
+ " X_teste_I = sfm.transform(X_teste)\n",
+ " return X_treinamento_I, X_teste_I "
+ ],
+ "execution_count": 41,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ukMLoEr7nbUf",
+ "outputId": "482ef28c-0ce4-4c0b-cdfa-c27970870520",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "X_treinamento_DT, X_teste_DT = seleciona_colunas_relevantes(ml_DT2, X_treinamento, X_teste)"
+ ],
+ "execution_count": 42,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "********** COLUNAS Relevantes ******\n",
+ "[ 0 9 12]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8JjePRQAoqkk"
+ },
+ "source": [
+ "## Treina o classificador com as COLUNAS relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Gt3aCPpfKRxm",
+ "outputId": "42773aa9-2e3e-48b4-8ca6-f1e3b7bdc0c7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "best_params"
+ ],
+ "execution_count": 43,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'criterion': 'entropy',\n",
+ " 'max_depth': None,\n",
+ " 'max_leaf_nodes': None,\n",
+ " 'min_samples_leaf': 20,\n",
+ " 'min_samples_split': 70}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 43
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zq6uCVtzovMt",
+ "outputId": "273a2602-243a-41d8-ebea-48f8808dada0",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Treina usando as COLUNAS relevantes...\n",
+ "ml_DT2.fit(X_treinamento_DT, y_treinamento)\n",
+ "\n",
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_DT2, X_treinamento_DT, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": 44,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média das Acurácias calculadas pelo CV....: 88.71\n",
+ "std médio das Acurácias calculadas pelo CV: 2.5100000000000002\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Tc7esxqtq-Og",
+ "outputId": "d1b27e41-5785-4d81-b96e-241b1cc10c9b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 129
+ }
+ },
+ "source": [
+ "****************************************************************"
+ ],
+ "execution_count": 45,
+ "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 ****************************************************************\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": "znWy3LE1q-Z3",
+ "outputId": "b32aaec0-77e2-4347-ec14-1d5dd852a8e9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "ml_DT3, best_params2 = GridSearchOptimizer(ml_DT2, 'ml_DT2', d_parametros_DT, X_treinamento_DT, y_treinamento, X_teste_DT, y_teste, cv = i_CV)"
+ ],
+ "execution_count": 46,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Fitting 10 folds for each of 5250 candidates, totalling 52500 fits\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n",
+ "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 0.0s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0151s.) Setting batch_size=2.\n",
+ "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 0.0s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0266s.) Setting batch_size=4.\n",
+ "[Parallel(n_jobs=-1)]: Done 16 tasks | elapsed: 0.1s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0472s.) Setting batch_size=8.\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.0610s.) Setting batch_size=16.\n",
+ "[Parallel(n_jobs=-1)]: Done 44 tasks | elapsed: 0.2s\n",
+ "[Parallel(n_jobs=-1)]: Batch computation too fast (0.1373s.) Setting batch_size=32.\n",
+ "[Parallel(n_jobs=-1)]: Done 156 tasks | elapsed: 0.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 380 tasks | elapsed: 1.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 668 tasks | elapsed: 2.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 956 tasks | elapsed: 2.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 1308 tasks | elapsed: 3.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 1660 tasks | elapsed: 4.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 2076 tasks | elapsed: 5.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 2492 tasks | elapsed: 6.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 2972 tasks | elapsed: 7.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 3452 tasks | elapsed: 9.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 3996 tasks | elapsed: 10.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 4540 tasks | elapsed: 12.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 5148 tasks | elapsed: 13.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 5756 tasks | elapsed: 15.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 6428 tasks | elapsed: 17.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 7100 tasks | elapsed: 18.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 7836 tasks | elapsed: 20.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 8572 tasks | elapsed: 22.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 9372 tasks | elapsed: 24.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 10172 tasks | elapsed: 26.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 11036 tasks | elapsed: 29.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 11900 tasks | elapsed: 31.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 12828 tasks | elapsed: 33.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 13756 tasks | elapsed: 36.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 14748 tasks | elapsed: 38.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 15740 tasks | elapsed: 41.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 16796 tasks | elapsed: 44.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 17852 tasks | elapsed: 46.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 18972 tasks | elapsed: 49.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 20092 tasks | elapsed: 52.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 21276 tasks | elapsed: 56.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 22460 tasks | elapsed: 59.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 23708 tasks | elapsed: 1.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 24956 tasks | elapsed: 1.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 26268 tasks | elapsed: 1.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 27580 tasks | elapsed: 1.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 28956 tasks | elapsed: 1.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 30332 tasks | elapsed: 1.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 31772 tasks | elapsed: 1.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 33212 tasks | elapsed: 1.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 34716 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 36220 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 37788 tasks | elapsed: 1.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 39356 tasks | elapsed: 1.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 40988 tasks | elapsed: 1.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 42620 tasks | elapsed: 1.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 44316 tasks | elapsed: 2.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 46012 tasks | elapsed: 2.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 47772 tasks | elapsed: 2.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 49532 tasks | elapsed: 2.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 51356 tasks | elapsed: 2.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 52500 out of 52500 | elapsed: 2.4min finished\n"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Parametros otimizados: {'criterion': 'entropy', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 60, 'min_samples_split': 2}\n",
+ "\n",
+ "DecisionTreeClassifier *********************************************************************************************************\n",
+ "\n",
+ "********* CROSS-VALIDATION ***********\n",
+ "Média das Acurácias calculadas pelo CV....: 89.29\n",
+ "std médio das Acurácias calculadas pelo CV: 2.73\n",
+ "\n",
+ "********* IMPORTÂNCIA DAS COLUNAS ***********\n",
+ " coluna importancia\n",
+ "2 v3 0.691283\n",
+ "0 v1 0.177569\n",
+ "1 v2 0.131148\n",
+ "\n",
+ "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6IhCC6pfq-jL",
+ "outputId": "eeec1e49-71fa-44ce-b9f0-05d4f83245bd",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "best_params"
+ ],
+ "execution_count": 47,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'criterion': 'entropy',\n",
+ " 'max_depth': None,\n",
+ " 'max_leaf_nodes': None,\n",
+ " 'min_samples_leaf': 20,\n",
+ " 'min_samples_split': 70}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 47
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qw6Dk3kesT0q",
+ "outputId": "771c6d2a-364d-45a5-ded1-935d556d9fde",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "best_params2"
+ ],
+ "execution_count": 48,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'criterion': 'entropy',\n",
+ " 'max_depth': None,\n",
+ " 'max_leaf_nodes': None,\n",
+ " 'min_samples_leaf': 60,\n",
+ " 'min_samples_split': 2}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 48
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SbS4ZKN8s-ee",
+ "outputId": "804f7297-dd42-4573-8c56-b882c11de1de",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_DT3, X_treinamento_DT, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": 49,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média das Acurácias calculadas pelo CV....: 89.29\n",
+ "std médio das Acurácias calculadas pelo CV: 2.73\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_at3XP1Bq-qb"
+ },
+ "source": [
+ "***************************************************************"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MZ1-vGRcxJoN"
+ },
+ "source": [
+ "## Valida o modelo usando o dataframe X_teste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ig9GiUAEw9jr"
+ },
+ "source": [
+ "y_pred_DT = ml_DT2.predict(X_teste_DT)"
+ ],
+ "execution_count": 50,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7UZz4UzHDqae",
+ "outputId": "9ddde91a-ce92-4ad2-e0e1-eda71009c9da",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Calcula acurácia\n",
+ "accuracy_score(y_teste, y_pred_DT)"
+ ],
+ "execution_count": 51,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.9333333333333333"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 51
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "K3EUMAxxKBur"
+ },
+ "source": [
+ "___\n",
+ "# **RANDOM FOREST**\n",
+ "* Decision Trees possuem estrutura em forma de árvores.\n",
+ "* Random Forest pode ser utilizado tanto para classificação (RandomForestClassifier)quanto para Regressão (RandomForestRegressor).\n",
+ "\n",
+ "* **Vantagens**:\n",
+ " * Não requer tanto data preprocessing;\n",
+ " * Lida bem com COLUNAS categóricas e numéricas;\n",
+ " * É um Boosting Ensemble Method (pois constrói muitas árvores). Estes modelos aprendem com os próprios erros e ajustam as árvores de modo a fazer melhores classificações;\n",
+ " * Mais robusta que uma simples Decision Tree. **Porque?**\n",
+ " * Controla automaticamente overfitting (**porque?**) e frequentemente produz modelos muito robustos e de alta-performance.\n",
+ " * Pode ser utilizado como Feature Selection, pois gera a matriz de importância dos atributos (importance sample). A soma das importâncias soma 100;\n",
+ " * Assim como as Decision Trees, esses modelos capturam facilmente padrões não-lineares presentes nos dados;\n",
+ " * Não requer os dados sejam normalizados;\n",
+ " * Lida bem com Missing Values;\n",
+ " * Não requer suposições (assumptions) sobre a distribuição dos dados por causa da natureza não-paramétrica do algoritmo\n",
+ "\n",
+ "* **Desvantagens**\n",
+ " * **Recomenda-se balancear o dataframe previamente para se evitar esse problema**.\n",
+ "\n",
+ "* **Principais parâmetros**\n",
+ "\n",
+ "## **Referências**:\n",
+ "* [Running Random Forests? Inspect the feature importances with this code](https://towardsdatascience.com/running-random-forests-inspect-the-feature-importances-with-this-code-2b00dd72b92e)\n",
+ "* [Feature importances with forests of trees](https://scikit-learn.org/stable/auto_examples/ensemble/plot_forest_importances.html)\n",
+ "* [Understanding Random Forests Classifiers in Python](https://www.datacamp.com/community/tutorials/random-forests-classifier-python)\n",
+ "* [Understanding Random Forest](https://towardsdatascience.com/understanding-random-forest-58381e0602d2)\n",
+ "* [An Implementation and Explanation of the Random Forest in Python](https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76)\n",
+ "* [Random Forest Simple Explanation](https://medium.com/@williamkoehrsen/random-forest-simple-explanation-377895a60d2d)\n",
+ "* [Random Forest Explained](https://www.youtube.com/watch?v=eM4uJ6XGnSM)\n",
+ "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74) - Explica os principais parâmetros do Random Forest."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cnfDw_GEKBuu"
+ },
+ "source": [
+ "from sklearn.ensemble import RandomForestClassifier\n",
+ "\n",
+ "# Instancia...\n",
+ "ml_RF= RandomForestClassifier(n_estimators=100, min_samples_split= 2, max_features=\"auto\", random_state= i_Seed)\n",
+ "\n",
+ "# Treina...\n",
+ "ml_RF.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lYa9oaZW__o6"
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_RF, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AouWUu8vANdb"
+ },
+ "source": [
+ "**Interpretação**: Nosso classificador (RandomForestClassifier) tem uma acurácia média de 96,44% (base de treinamento). Além disso, o std é da ordem de 2,77%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vbducxlgAa85"
+ },
+ "source": [
+ "print(f'Acurácias: {a_scores_CV}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_lxx-LUw_5sd"
+ },
+ "source": [
+ "# Faz predições...\n",
+ "y_pred = ml_RF.predict(X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pQIRO_LpGAkw"
+ },
+ "source": [
+ "# Confusion Matrix\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yKLHZ5_C6FJ8"
+ },
+ "source": [
+ "## Parameter tunning\n",
+ "### Referência\n",
+ "* [Hyperparameter Tuning the Random Forest in Python](https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74)\n",
+ "* [Decision Tree Adventures 2 — Explanation of Decision Tree Classifier Parameters](https://medium.com/datadriveninvestor/decision-tree-adventures-2-explanation-of-decision-tree-classifier-parameters-84776f39a28) - Explica didaticamente e step by step como fazer parameter tunning.\n",
+ "* [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) - Outro approach para entender parameter tunning. Recomendo fortemente a leitura! "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "XOa9naju6FKA"
+ },
+ "source": [
+ "# Dicionário de parâmetros para o parameter tunning.\n",
+ "d_parametros_RF= {'bootstrap': [True, False]} #,\n",
+ "# 'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],\n",
+ "# 'max_features': ['auto', 'sqrt'],\n",
+ "# 'min_samples_leaf': [1, 2, 4],\n",
+ "# 'min_samples_split': [2, 5, 10],\n",
+ "# 'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6__f2jZaTQat"
+ },
+ "source": [
+ "# Invoca a função\n",
+ "ml_RF2, best_params = GridSearchOptimizer(ml_RF, 'ml_RF2', d_parametros_RF, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "crfn-n--KG4n"
+ },
+ "source": [
+ "### Resultado da execução do Random Forest\n",
+ "\n",
+ "```\n",
+ "[Parallel(n_jobs=-1)]: Done 7920 out of 7920 | elapsed: 194.0min finished\n",
+ "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SGTOe5PaRw59"
+ },
+ "source": [
+ "# Como o procedimento acima levou 194 minutos para executar, então vou estimar ml_RF2 abaixo usando os parâmetros acima estimados\n",
+ "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n",
+ "\n",
+ "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n",
+ " max_depth= best_params['max_depth'], \n",
+ " max_features= best_params['max_features'], \n",
+ " min_samples_leaf= best_params['min_samples_leaf'], \n",
+ " min_samples_split= best_params['min_samples_split'], \n",
+ " n_estimators= best_params['n_estimators'], \n",
+ " random_state= i_Seed)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HMJcAdLlTQa0"
+ },
+ "source": [
+ "## Visualizar o resultado\n",
+ "> Implementar a visualização do RandomForest."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WWNiy7Z0TQa3"
+ },
+ "source": [
+ "## Selecionar as COLUNAS importantes/relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kOi11YOKTQa4"
+ },
+ "source": [
+ "X_treinamento_RF, X_teste_RF = seleciona_colunas_relevantes(ml_RF2, X_treinamento, X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Zn_O7c_DTQbE"
+ },
+ "source": [
+ "## Treina o classificador com as COLUNAS relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UwEOwzSGTQbF"
+ },
+ "source": [
+ "best_params"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Rr8qDrgvTQbL"
+ },
+ "source": [
+ "# Treina com as COLUNAS relevantes...\n",
+ "ml_RF2.fit(X_treinamento_RF, y_treinamento)\n",
+ "\n",
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_RF2, X_treinamento_RF, y_treinamento, cv = i_CV)\n",
+ "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n",
+ "print(f'std médio.....: {100*a_scores_CV.std():.2f}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-mYfQLlsTQbQ"
+ },
+ "source": [
+ "## Valida o modelo usando o dataframe X_teste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sSD5o1JQTQbR"
+ },
+ "source": [
+ "y_pred_RF = ml_RF2.predict(X_teste_RF)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wywF6LymDzKr"
+ },
+ "source": [
+ "# Calcula acurácia\n",
+ "accuracy_score(y_teste, y_pred_RF)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hJJsL0IJb6iO"
+ },
+ "source": [
+ "## Estudo do comportamento dos parametros do algoritmo\n",
+ "> Consulte [Optimizing Hyperparameters in Random Forest Classification](https://towardsdatascience.com/optimizing-hyperparameters-in-random-forest-classification-ec7741f9d3f6) para mais detalhes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "navUWMwHi44D"
+ },
+ "source": [
+ "param_range = np.arange(1, 250, 2)\n",
+ "\n",
+ "# Calculate accuracy on training and test set using range of parameter values\n",
+ "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n",
+ " X_treinamento, \n",
+ " y_treinamento, \n",
+ " param_name=\"n_estimators\", \n",
+ " param_range = param_range, \n",
+ " cv = i_CV, \n",
+ " scoring = \"accuracy\", \n",
+ " n_jobs = -1)\n",
+ "\n",
+ "\n",
+ "# Calculate mean and standard deviation for training set a_scores_CV\n",
+ "train_mean = np.mean(train_a_scores_CV, axis = 1)\n",
+ "train_std = np.std(train_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Calculate mean and standard deviation for test set a_scores_CV\n",
+ "test_mean = np.mean(test_a_scores_CV, axis = 1)\n",
+ "test_std = np.std(test_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Plot mean accuracy a_scores_CV for training and test sets\n",
+ "plt.plot(param_range, train_mean, label = \"Training score\", color = \"black\")\n",
+ "plt.plot(param_range, test_mean, label = \"Cross-validation score\", color = \"dimgrey\")\n",
+ "\n",
+ "# Plot accurancy bands for training and test sets\n",
+ "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color = \"gray\")\n",
+ "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color = \"gainsboro\")\n",
+ "\n",
+ "# Create plot\n",
+ "plt.title(\"Validation Curve With Random Forest\")\n",
+ "plt.xlabel(\"Number Of Trees\")\n",
+ "plt.ylabel(\"Accuracy Score\")\n",
+ "plt.tight_layout()\n",
+ "plt.legend(loc = \"best\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rv7TIM9kjsud"
+ },
+ "source": [
+ "param_range = np.arange(1, 250, 2)\n",
+ "\n",
+ "# Calculate accuracy on training and test set using range of parameter values\n",
+ "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n",
+ " X_treinamento, \n",
+ " y_treinamento, \n",
+ " param_name = \"max_depth\", \n",
+ " param_range = param_range, \n",
+ " cv = i_CV, \n",
+ " scoring = \"accuracy\", \n",
+ " n_jobs = -1)\n",
+ "\n",
+ "# Calculate mean and standard deviation for training set a_scores_CV\n",
+ "train_mean = np.mean(train_a_scores_CV, axis = 1)\n",
+ "train_std = np.std(train_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Calculate mean and standard deviation for test set a_scores_CV\n",
+ "test_mean = np.mean(test_a_scores_CV, axis = 1)\n",
+ "test_std = np.std(test_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Plot mean accuracy a_scores_CV for training and test sets\n",
+ "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n",
+ "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n",
+ "\n",
+ "# Plot accurancy bands for training and test sets\n",
+ "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n",
+ "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n",
+ "\n",
+ "# Create plot\n",
+ "plt.title(\"Validation Curve With Random Forest\")\n",
+ "plt.xlabel(\"Number Of Trees\")\n",
+ "plt.ylabel(\"Accuracy Score\")\n",
+ "plt.tight_layout()\n",
+ "plt.legend(loc=\"best\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lm_fPGYwkJYc"
+ },
+ "source": [
+ "param_range = np.arange(1, 250, 2)\n",
+ "\n",
+ "# Calculate accuracy on training and test set using range of parameter values\n",
+ "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n",
+ " X_treinamento, \n",
+ " y_treinamento, \n",
+ " param_name='min_samples_leaf', \n",
+ " param_range=param_range,\n",
+ " cv = i_CV, \n",
+ " scoring=\"accuracy\", \n",
+ " n_jobs=-1)\n",
+ "\n",
+ "\n",
+ "# Calculate mean and standard deviation for training set a_scores_CV\n",
+ "train_mean = np.mean(train_a_scores_CV, axis = 1)\n",
+ "train_std = np.std(train_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Calculate mean and standard deviation for test set a_scores_CV\n",
+ "test_mean = np.mean(test_a_scores_CV, axis = 1)\n",
+ "test_std = np.std(test_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Plot mean accuracy a_scores_CV for training and test sets\n",
+ "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n",
+ "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n",
+ "\n",
+ "# Plot accurancy bands for training and test sets\n",
+ "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n",
+ "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n",
+ "\n",
+ "# Create plot\n",
+ "plt.title(\"Validation Curve With Random Forest\")\n",
+ "plt.xlabel(\"Number Of Trees\")\n",
+ "plt.ylabel(\"Accuracy Score\")\n",
+ "plt.tight_layout()\n",
+ "plt.legend(loc=\"best\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CAqdiSaVlAB8"
+ },
+ "source": [
+ "param_range = np.arange(0.05, 1, 0.05)\n",
+ "\n",
+ "# Calculate accuracy on training and test set using range of parameter values\n",
+ "train_a_scores_CV, test_a_scores_CV = validation_curve(RandomForestClassifier(), \n",
+ " X_treinamento, \n",
+ " y_treinamento, \n",
+ " param_name='min_samples_split', \n",
+ " param_range=param_range,\n",
+ " cv = i_CV, \n",
+ " scoring=\"accuracy\", \n",
+ " n_jobs=-1)\n",
+ "\n",
+ "\n",
+ "# Calculate mean and standard deviation for training set a_scores_CV\n",
+ "train_mean = np.mean(train_a_scores_CV, axis = 1)\n",
+ "train_std = np.std(train_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Calculate mean and standard deviation for test set a_scores_CV\n",
+ "test_mean = np.mean(test_a_scores_CV, axis = 1)\n",
+ "test_std = np.std(test_a_scores_CV, axis = 1)\n",
+ "\n",
+ "# Plot mean accuracy a_scores_CV for training and test sets\n",
+ "plt.plot(param_range, train_mean, label=\"Training score\", color=\"black\")\n",
+ "plt.plot(param_range, test_mean, label=\"Cross-validation score\", color=\"dimgrey\")\n",
+ "\n",
+ "# Plot accurancy bands for training and test sets\n",
+ "plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, color=\"gray\")\n",
+ "plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, color=\"gainsboro\")\n",
+ "\n",
+ "# Create plot\n",
+ "plt.title(\"Validation Curve With Random Forest\")\n",
+ "plt.xlabel(\"Number Of Trees\")\n",
+ "plt.ylabel(\"Accuracy Score\")\n",
+ "plt.tight_layout()\n",
+ "plt.legend(loc=\"best\")\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cX_gfsbQSdNd"
+ },
+ "source": [
+ "___\n",
+ "# **BOOSTING MODELS**\n",
+ "* São algoritmos muito utilizados nas competições do Kaggle;\n",
+ "* São algoritmos utilizados para melhorar a performance dos algoritmos de Machine Learning;\n",
+ "* Modelos:\n",
+ " - [X] AdaBoost\n",
+ " - [X] XGBoost\n",
+ " - [X] LightGBM\n",
+ " - [X] GradientBoosting\n",
+ " - [X] CatBoost\n",
+ "\n",
+ "## Bagging vs Boosting vc Stacking\n",
+ "### **Bagging**\n",
+ "* Objetivo é reduzir a variância;\n",
+ "\n",
+ "#### Como funciona\n",
+ "* Seleciona várias amostras **COM REPOSIÇÃO** do dataframe de treinamento. Cada amostra é usada para treinar um modelo usando Decision Trees. Como resultado, temos um ensemble de muitas e diferentes modelos (Decision Trees). A média de desses muitos e diferentes modelos (Decision Trees) são usados para produzir o resultado final;\n",
+ "* O resultado final é mais robusto do que usarmos uma simples Decision Tree.\n",
+ "\n",
+ "\n",
+ "\n",
+ "Souce: [Boosting and Bagging: How To Develop A Robust Machine Learning Algorithm](https://hackernoon.com/how-to-develop-a-robust-algorithm-c38e08f32201).\n",
+ "\n",
+ "#### Steps\n",
+ "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n",
+ " 1. Bagging seleciona aleatoriamente uma amostra **COM REPOSIÇÃO** de X_treinamento;\n",
+ " 2. Bagging seleciona aleatoriamente M2 (M2 < M) COLUNAS do dataframe extraído do passo (1);\n",
+ " 3. Constroi uma Decision Tree com as M2 COLUNAS do passo (2) e o dataframe obtido no passo (1) e as COLUNAS são avaliadas pela sua habilidade de classificar as observações;\n",
+ " 4. Os passos (1)--> (2)-- (3) são repetidos K vezes (ou seja, K Decision Trees), de forma que as COLUNAS são ranqueadas pelo seu poder preditivo e o resultado final (acurácia, por exemplo) é obtido pela agregação das predições dos K Decision Trees.\n",
+ "\n",
+ "#### Vantagens\n",
+ "* Reduz overfitting;\n",
+ "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n",
+ "* Lida automaticamente com Missing Values;\n",
+ "\n",
+ "#### Desvantagem\n",
+ "* A predição final é baseada na média das K Decision Trees, o que pode comprometer a acurácia final.\n",
+ "\n",
+ "___ \n",
+ "### **Boosting**\n",
+ "* Objetivo é melhorar acurácia;\n",
+ "\n",
+ "#### Como funciona\n",
+ "* Os classificadores são usados sequencialmente, de forma que o classificador no passo N aprende com os erros do classificador do passo N-1. Ou seja, o objetivo é melhorar a precisão/acurácia à cada passo aprendendo com o passado.\n",
+ "\n",
+ "\n",
+ "\n",
+ "Source: [Ensemble methods: bagging, boosting and stacking](https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205), Joseph Rocca\n",
+ ".\n",
+ "\n",
+ "#### Steps\n",
+ "* Suponha um dataframe X_treinamento (dataframe de treinamento) contendo N observações (instâncias, pontos, linhas) e M COLUNAS (features, atributos).\n",
+ " 1. Boosting seleciona aleatoriamente uma amostra D1 SEM reposição de X_treinamento;\n",
+ " 2. Boosting treina o classificador C1;\n",
+ " 3. Boosting seleciona aleatoriamente a SEGUNDA amostra D2 SEM reposição de X_treinamento e acrescenta à D2 50% das observações que foram classificadas incorretamente para treinar o classificador C2;\n",
+ " 4. Boosting encontra em X_treinamento a amostra D3 que os classificadores C1 e C2 discordam em classificar e treina C3;\n",
+ " 5. Combina (voto) as predições de C1, C2 e C3 para produzir o resultado final.\n",
+ "\n",
+ "#### Vantagens\n",
+ "* Lida bem com dataframes com muitas COLUNAS (high dimensionality);\n",
+ "* Lida automaticamente com Missing Values;\n",
+ "\n",
+ "#### Desvantagem\n",
+ "* Propenso a overfitting. Recomenda-se tratar outliers previamente.\n",
+ "* Requer ajuste cuidadoso dos hyperparameters;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9fgUrkmPk4dr"
+ },
+ "source": [
+ "___\n",
+ "# STACKING\n",
+ "\n",
+ "\n",
+ "\n",
+ "Kd a referência desta figura???"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "B0jxx3ETpOdm"
+ },
+ "source": [
+ "___\n",
+ "# **BOOTSTRAPPING METHODS**\n",
+ "> Antes de falarmos de Boosting ou Bagging, precisamos entender primeiro o que é Bootstrap, pois ambos (Boosting e Bagging) são baseados em Bootstrap.\n",
+ "\n",
+ "* Em Estatística (e em Machine Learning), Bootstrap se refere à extrair amostras aleatórias COM reposição da população X."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SyqazmUuifkE"
+ },
+ "source": [
+ "___\n",
+ "# **ADABOOST(Adaptive Boosting)**\n",
+ "* Quando nada funciona, AdaBoost funciona!\n",
+ "* Foi um dos primeiros algoritmos de Boosting (1995);\n",
+ "* AdaBoost pode ser utilizado tanto para classificação (AdaBoostClassifier) quanto para Regressão (AdaBoostRegressor);\n",
+ "* AdaBoost usam algoritmos DecisionTree como base_estimator;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RU-vzkXqrFVw"
+ },
+ "source": [
+ "## Referências\n",
+ "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464) - Didático e explica exatamente como o AdaBoost funciona.\n",
+ "* [Adaboost for Dummies: Breaking Down the Math (and its Equations) into Simple Terms](https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf) - Para quem quer entender a matemática por trás do algoritmo.\n",
+ "* [Gradient Boosting and XGBoost](https://medium.com/hackernoon/gradient-boosting-and-xgboost-90862daa6c77)\n",
+ "* [Understanding AdaBoost](https://towardsdatascience.com/understanding-adaboost-2f94f22d5bfe), Akash Desarda.\n",
+ "* [AdaBoost Classifier Example In Python](https://towardsdatascience.com/machine-learning-part-17-boosting-algorithms-adaboost-in-python-d00faac6c464)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6EMrjQDZIMl_"
+ },
+ "source": [
+ "## O que é AdaBoost (Adaptive Boosting)?\n",
+ "* é um dos classificadores do tipo ensemble (combina vários classificadores para aumentar a precisão).\n",
+ "* AdaBoost é um classificador iterativo e forte que combina (ensemble) vários classificadores fracos para melhorar a precisão.\n",
+ "* Qualquer algoritmo de aprendizado de máquina pode ser usado como um classificador de base (parâmetro base_estimator);\n",
+ "\n",
+ "## Parâmetros mais importantes do AdaBoost:\n",
+ "* base_estimator - É um classificador usado para treinar o modelo. Como default, AdaBoost usa o DecisionTreeClassifier. Como dito anteriormente, pode-se utilizar diferentes algoritmos para esse fim.\n",
+ "* n_estimators - Número de base_estimator para treinar iterativamente.\n",
+ "* learning_rate - Controla a contribuição do base_estimator na solução/combinação final;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TzLtHzWNJBix"
+ },
+ "source": [
+ "## Usando diferentes algoritmos para base_estimator\n",
+ "> Como dito anteriormente, pode-se utilizar vários tipos de base_estimator em AdaBoost. Por exemplo, se quisermos usar SVM (Support Vector Machines), devemos proceder da seguinte forma:\n",
+ "\n",
+ "\n",
+ "```\n",
+ "# Importar a biblioteca base_estimator\n",
+ "from sklearn.svm import SVC\n",
+ "\n",
+ "# Treina o classificador (algoritmo)\n",
+ "ml_SVC= SVC(probability=True, kernel='linear')\n",
+ "\n",
+ "# Constroi o modelo AdaBoost\n",
+ "ml_AB = AdaBoostClassifier(n_estimators= 50, base_estimator=ml_SVC, learning_rate=1)\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hrj4a4s6hMMB"
+ },
+ "source": [
+ "## Vantagens\n",
+ "* AdaBoost é fácil de implementar;\n",
+ "* AdaBoost corrige os erros do base_estimator iterativamente e melhora a acurácia;\n",
+ "* Faz o Feature Selection automaticamente (**Porque**?);\n",
+ "* Pode-se usar muitos algoritos como base_estimator ;\n",
+ "* Como é um método ensemble, então o modelo final é pouco propenso à overfitting.\n",
+ "\n",
+ "## Desvantagens\n",
+ "* AdaBoost é sensível a ruídos nos dados;\n",
+ "* Altamente impactado por outliers (contribui para overfitting), pois o algoritmo tenta se ajustr a cada ponto da mehor forma possível;\n",
+ "* AdaBoost é mais lento que XGBoost;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bgJmu7YLiyv7"
+ },
+ "source": [
+ "No exemplo a seguir, vou usar RandomForestClassifier com os parâmetros otimizados, ou seja:\n",
+ "\n",
+ "```\n",
+ "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5VCRNyZT3qvc"
+ },
+ "source": [
+ "best_params= {'bootstrap': False, 'max_depth': 10, 'max_features': 'auto', 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 400}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1gIboJdriq61"
+ },
+ "source": [
+ "from sklearn.ensemble import AdaBoostClassifier\n",
+ "from sklearn.ensemble import RandomForestClassifier\n",
+ "\n",
+ "# Instancia RandomForestClassifier - Parâmetros otimizados!\n",
+ "ml_RF2= RandomForestClassifier(bootstrap= best_params['bootstrap'], \n",
+ " max_depth= best_params['max_depth'], \n",
+ " max_features= best_params['max_features'], \n",
+ " min_samples_leaf= best_params['min_samples_leaf'], \n",
+ " min_samples_split= best_params['min_samples_split'], \n",
+ " n_estimators= best_params['n_estimators'], \n",
+ " random_state= i_Seed)\n",
+ "# Instancia AdaBoostClassifier\n",
+ "ml_AB= AdaBoostClassifier(n_estimators=100, base_estimator= ml_RF2, random_state= i_Seed)\n",
+ "\n",
+ "# Treina...\n",
+ "ml_AB.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "A4Cs81OLD40y"
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_AB, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F7Ce5L38ECoC"
+ },
+ "source": [
+ "**Interpretação**: Nosso classificador (AdaBoostClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,54%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "t5GfnBwEifkO"
+ },
+ "source": [
+ "print(f'Acurácias: {a_scores_CV}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Q9rSpuXyEPA5"
+ },
+ "source": [
+ "# Faz predições com os parametros otimizados...\n",
+ "y_pred = ml_AB.predict(X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2F9k-_eXGDLa"
+ },
+ "source": [
+ "# Confusion Matrix\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XweWTjQ9EXLw"
+ },
+ "source": [
+ "## Parameter tunning"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fcrKzse9EbL_"
+ },
+ "source": [
+ "# Dicionário de parâmetros para o parameter tunning.\n",
+ "d_parametros_AB = {'n_estimators':[50, 100, 200], 'learning_rate':[.001, 0.01, 0.05, 0.1, 0.3,1]}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Susc3I7mFDQX"
+ },
+ "source": [
+ "# Invoca a função\n",
+ "ml_AB2, best_params= GridSearchOptimizer(ml_AB, 'ml_AB2', d_parametros_AB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "w4JjWsusjNS8"
+ },
+ "source": [
+ "___\n",
+ "# **GRADIENT BOOSTING**\n",
+ "* Gradient boosting pode ser usado para resolver problemas de classificação (GradientBoostingClassifier) e Regressão (GradientBoostingRegressor);\n",
+ "* Gradient boosting são um refinamento do AdaBoost (lembra que AdaBoost foi um dos primeiros métodos de Boosting - criado em 1995). O que Gradient Boosting faz adicionalmente ao AdaBoost é minimizar a loss (função perda), ie, minimizar a diferença entre os valores observados de y e os valores preditos.\n",
+ "* Usa Gradient Descent para encontrar as deficiências nas previsões do passo anterior. Gradient Descent é um algoritmo popular e poderoso e usado em Redes Neurais;\n",
+ "* O objetivo do Gradient Boosting é minimizar 'loss function'. Portanto, Gradient Boosting depende da \"loss function\".\n",
+ "* Gradient boosting usam algoritmos DecisionTree como base_estimator;\n",
+ "\n",
+ "## Vantagens\n",
+ "* Não há necessidade de pre-processing;\n",
+ "* Trabalha normalmente com COLUNAS numéricas ou categóricas;\n",
+ "* Trata automaticamente os Missing Values. Ou seja, não é necessário aplicar métodos de Missing Value Imputation;\n",
+ "\n",
+ "## Desvantagens\n",
+ "* Como Gradient Boosting tenta continuamente minimizar os erros à cada iteração, isso pode enfatizar os outliers e causar overfitting. Portanto, deve-se:\n",
+ " * Tratar os outliers previamente OU\n",
+ " * Usar Cross-Validation para neutralizar os efeitos dos outliers (**Eu prefiro este método, pois toma menos tempo**);\n",
+ "* Computacionalmene caro. Geralmente são necessários muitas árvores (> 1000) para se obter bons resultados;\n",
+ "* Devido à flexibilidade (muitos parâmetros para ajustar), então é necessário usar GridSearchCV para encontrar a combinação ótima dos hyperparameters;\n",
+ "\n",
+ "## Referências\n",
+ "* [Gradient Boosting Decision Tree Algorithm Explained](https://towardsdatascience.com/machine-learning-part-18-boosting-algorithms-gradient-boosting-in-python-ef5ae6965be4) - Didático e detalhista.\n",
+ "* [Predicting Wine Quality with Gradient Boosting Machines](https://towardsdatascience.com/predicting-wine-quality-with-gradient-boosting-machines-a-gmb-tutorial-d950b1542065)\n",
+ "* [Parameter Tuning in Gradient Boosting (GBM) with Python](https://www.datacareer.de/blog/parameter-tuning-in-gradient-boosting-gbm/)\n",
+ "* [Tune Learning Rate for Gradient Boosting with XGBoost in Python](https://machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/)\n",
+ "* [In Depth: Parameter tuning for Gradient Boosting](https://medium.com/all-things-ai/in-depth-parameter-tuning-for-gradient-boosting-3363992e9bae) - Muito bom\n",
+ "* [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Q4bUCZs2jNTA"
+ },
+ "source": [
+ "from sklearn.ensemble import GradientBoostingClassifier\n",
+ "\n",
+ "# Instancia...\n",
+ "ml_GB=GradientBoostingClassifier(n_estimators=100, min_samples_split= 2)\n",
+ "\n",
+ "# Treina...\n",
+ "ml_GB.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-dr6dyjdXwvd"
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_GB, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VlC3y3M5YaGG"
+ },
+ "source": [
+ "print(f'Acurácias: {a_scores_CV}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vnLvQ0ZDYNjB"
+ },
+ "source": [
+ "**Interpretação**: Nosso classificador (GradientBoostingClassifier) tem uma acurácia média de 96,86% (base de treinamento). Além disso, o std é da ordem de 2,52%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D2n1RKZuXq3D"
+ },
+ "source": [
+ "# Faz precições...\n",
+ "y_pred = ml_GB.predict(X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8r6JCzQRGFa0"
+ },
+ "source": [
+ "# Confusion Matrix\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KFv-Q2AD5uCk"
+ },
+ "source": [
+ "## Parameter tunning\n",
+ "> Consulte [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/) para detalhes sobre os parâmetros, significado e etc."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wgU040AcjNTF"
+ },
+ "source": [
+ "# Dicionário de parâmetros para o parameter tunning.\n",
+ "d_parametros_GB= {'learning_rate': [1, 0.5, 0.25, 0.1, 0.05, 0.01]} #,\n",
+ "# 'n_estimators': [1, 2, 4, 8, 16, 32, 64, 100, 200],\n",
+ "# 'max_depth': [5, 10, 15, 20, 25, 30],\n",
+ "# 'min_samples_split': [0.1, 0.3, 0.5, 0.7, 0.9],\n",
+ "# 'min_samples_leaf': [0.1, 0.2, 0.3, 0.4, 0.5],\n",
+ "# 'max_features': list(range(1, X_treinamento.shape[1]))}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v5KLFlpTjNTH"
+ },
+ "source": [
+ "# Invoca a função\n",
+ "ml_GB2, best_params= GridSearchOptimizer(ml_GB, 'ml_GB2', d_parametros_GB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YQ6ERz3fi9i2"
+ },
+ "source": [
+ "### Resultado da execução do Gradient Boosting"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RSa7uKw13mKG"
+ },
+ "source": [
+ "```\n",
+ "[Parallel(n_jobs=-1)]: Done 275400 out of 275400 | elapsed: 93.7min finished\n",
+ "\n",
+ "Parametros otimizados: {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "wiJpA2PyjDjR"
+ },
+ "source": [
+ "# Como o procedimento acima levou 93 minutos para executar, então vou estimar ml_GB2 abaixo usando os parâmetros acima estimados\n",
+ "best_params= {'learning_rate': 1, 'max_depth': 30, 'max_features': 11, 'min_samples_leaf': 0.1, 'min_samples_split': 0.1, 'n_estimators': 100}\n",
+ "\n",
+ "#ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n",
+ "# max_depth= best_params['max_depth'],\n",
+ "# max_features= best_params['max_features'],\n",
+ "# min_samples_leaf= best_params['min_samples_leaf'],\n",
+ "# min_samples_split= best_params['min_samples_split'],\n",
+ "# n_estimators= best_params['n_estimators'],\n",
+ "# random_state= i_Seed)\n",
+ "\n",
+ "ml_GB2= GradientBoostingClassifier(learning_rate= best_params['learning_rate'], \n",
+ " max_depth= best_params['max_depth'],\n",
+ " min_samples_leaf= best_params['min_samples_leaf'],\n",
+ " min_samples_split= best_params['min_samples_split'],\n",
+ " n_estimators= best_params['n_estimators'],\n",
+ " random_state= i_Seed)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mb14gJ7-jbVM"
+ },
+ "source": [
+ "## Selecionar as COLUNAS importantes/relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TAqGZIFYm2sU"
+ },
+ "source": [
+ "X_treinamento_GB, X_teste_GB = seleciona_colunas_relevantes(ml_GB2, X_treinamento, X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6yiu6dahnBvC"
+ },
+ "source": [
+ "## Treina o classificador com as COLUNAS relevantes "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "APrtWN18nc4t"
+ },
+ "source": [
+ "best_params"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VS0mLdOmnXAY"
+ },
+ "source": [
+ "# Treina com as COLUNAS relevantes\n",
+ "ml_GB2.fit(X_treinamento_GB, y_treinamento)\n",
+ "\n",
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_GB2, X_treinamento_GB, y_treinamento, cv = i_CV)\n",
+ "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n",
+ "print(f'std médio.....: {100*a_scores_CV.std():.2f}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vmc9PP_Rn1TN"
+ },
+ "source": [
+ "## Valida o modelo usando o dataframe X_teste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e3mnIALvnzP2"
+ },
+ "source": [
+ "y_pred_GB = ml_GB2.predict(X_teste_GB)\n",
+ "\n",
+ "# Calcula acurácia\n",
+ "accuracy_score(y_teste, y_pred_GB)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kwP9Z2GnkV7r"
+ },
+ "source": [
+ "___\n",
+ "# **XGBOOST (eXtreme Gradient Boosting)**\n",
+ "* XGBoost é uma melhoria de Gradient Boosting. As melhorias são em velocidade e performace, além de corrigir as ineficiências do GradientBoosting.\n",
+ "* Algoritmo preferido pelos Kaggle Grandmasters;\n",
+ "* Paralelizável;\n",
+ "* Estado-da-arte em termos de Machine Learning;\n",
+ "\n",
+ "## Parâmetros relevantes e seus valores iniciais\n",
+ "Consulte [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/) para detalhes completos sobre os parâmetros, significado e etc.\n",
+ "\n",
+ "* n_estimators = 100 (100 caso o dataframe for grande. Se o dataframe for médio/pequeno, então 1000) - É o número de árvores desejamos construir;\n",
+ "* max_depth= 3 - Determina quão profundo cada árvore pode crescer durante qualquer round de treinamento. Valores típicos no intervalo [3, 10];\n",
+ "* learning rate= 0.01 - Usado para evitar overfitting, intervalo: [0, 1];\n",
+ "* alpha (somente para problemas de Regressão) - L1 regularization nos pesos. Valores altos resulta em mais regularization;\n",
+ "* lambda (somente para problemas de Regressão) - L2 regularization nos pesos.\n",
+ "* colsample_bytree: 1 - porcentagem de COLUNAS usados por cada árvore. Alto valor pode causar overfitting;\n",
+ "* subsample: 0.8 - porcentagem de amostras usadas por árvore. Um valor baixo pode levar a overfitting;\n",
+ "* gamma: 1 - Controla se um determinado nó será dividido com base na redução esperada na perda após a divisão. Um valor mais alto leva a menos divisões.\n",
+ "* objective: Define a \"loss function\". As opções são:\n",
+ " * reg:linear - Para resolver problemas de regressão;\n",
+ " * reg:logistic - Para resolver problemas de classificação;\n",
+ " * binary:logistic - Para resolver problemas de classificação com cálculo de probabilidades;\n",
+ "\n",
+ "# Referências\n",
+ "* [How exactly XGBoost Works?](https://medium.com/@pushkarmandot/how-exactly-xgboost-works-a320d9b8aeef)\n",
+ "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n",
+ "* [Gentle Introduction of XGBoost Library](https://medium.com/@imoisharma/gentle-introduction-of-xgboost-library-2b1ac2669680)\n",
+ "* [A Beginner’s guide to XGBoost](https://towardsdatascience.com/a-beginners-guide-to-xgboost-87f5d4c30ed7)\n",
+ "* [Exploring XGBoost](https://towardsdatascience.com/exploring-xgboost-4baf9ace0cf6)\n",
+ "* [Feature Importance and Feature Selection With XGBoost in Python](https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/)\n",
+ "* [Ensemble Learning case study: Running XGBoost on Google Colab free GPU](https://towardsdatascience.com/running-xgboost-on-google-colab-free-gpu-a-case-study-841c90fef101) - Recomendo\n",
+ "* [Predicting movie revenue with AdaBoost, XGBoost and LightGBM](https://towardsdatascience.com/predicting-movie-revenue-with-adaboost-xgboost-and-lightgbm-262eadee6daa)\n",
+ "* [Tuning XGBoost Hyperparameters with Scikit Optimize](https://towardsdatascience.com/how-to-improve-the-performance-of-xgboost-models-1af3995df8ad)\n",
+ "* [An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt](https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e) - Interessante\n",
+ "* [XGBOOST vs LightGBM: Which algorithm wins the race !!!](https://towardsdatascience.com/lightgbm-vs-xgboost-which-algorithm-win-the-race-1ff7dd4917d) - LightGBM tem se mostrado interessante.\n",
+ "* [From Zero to Hero in XGBoost Tuning](https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58) - Gostei\n",
+ "* [Build XGBoost / LightGBM models on large datasets — what are the possible solutions?](https://towardsdatascience.com/build-xgboost-lightgbm-models-on-large-datasets-what-are-the-possible-solutions-bf882da2c27d)\n",
+ "* [Selecting Optimal Parameters for XGBoost Model Training](https://towardsdatascience.com/selecting-optimal-parameters-for-xgboost-model-training-c7cd9ed5e45e) - Muito bom!\n",
+ "* [CatBoost vs. Light GBM vs. XGBoost](https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iMM_R4_ukV7x"
+ },
+ "source": [
+ "from xgboost import XGBClassifier\n",
+ "import xgboost as xgb\n",
+ "\n",
+ "# Instancia...\n",
+ "ml_XGB= XGBClassifier(silent=False, \n",
+ " scale_pos_weight=1,\n",
+ " learning_rate=0.01, \n",
+ " colsample_bytree = 1,\n",
+ " subsample = 0.8,\n",
+ " objective='binary:logistic', \n",
+ " n_estimators=1000, \n",
+ " reg_alpha = 0.3,\n",
+ " max_depth= 3, \n",
+ " gamma=1, \n",
+ " max_delta_step=5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "E4wQMlDEFINR"
+ },
+ "source": [
+ "# Treina...\n",
+ "ml_XGB.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zAhsTtwGqMkG"
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_XGB, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JNyKX6PkrXOk"
+ },
+ "source": [
+ "**Interpretação**: Nosso classificador (XGBClassifier) tem uma acurácia média de 96,72% (base de treinamento). Além disso, o std é da ordem de 2,02%, ou seja, pequena. Vamos tentar melhorar a acurácia do classificador usando parameter tunning (GridSearchCV)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_h0QYv3FkV73"
+ },
+ "source": [
+ "print(f'Acurácias: {a_scores_CV}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AKhhAZLjkV76"
+ },
+ "source": [
+ "# Faz predições...\n",
+ "y_pred = ml_XGB.predict(X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ir2Kd1PqGHgz"
+ },
+ "source": [
+ "# Confusion Matrix\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative','False_Positive','False_Negative','True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names= cf_labels, categories= cf_categories)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jEC7gW4qYpWw"
+ },
+ "source": [
+ "## Parameter tunning\n",
+ "### Leitura Adicional:\n",
+ "* [Fine-tuning XGBoost in Python like a boss](https://towardsdatascience.com/fine-tuning-xgboost-in-python-like-a-boss-b4543ed8b1e)\n",
+ "* [Complete Guide to Parameter Tuning in XGBoost with codes in Python](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)\n",
+ "\n",
+ "> Olhando para os resultados acima, qual o melhor modelo?\n",
+ "\n",
+ "XGBoost? Supondo que sim, agora vamos fazer o fine-tuning dos parâmetros do modelo."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "n3MsUONPwIV9"
+ },
+ "source": [
+ "# Dicionário de parâmetros para XGBoost:\n",
+ "d_parametros_XGB = {'min_child_weight': [i for i in np.arange(1, 13)]} #,\n",
+ "# 'gamma': [i for i in np.arange(0, 5, 0.5)],\n",
+ "# 'subsample': [0.6, 0.8, 1.0],\n",
+ "# 'colsample_bytree': [0.6, 0.8, 1.0],\n",
+ "# 'max_depth': [3, 4, 5, 7, 9],\n",
+ "# 'learning_rate': [i for i in np.arange(0.01, 1, 0.1)]}"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CX27FCKmwSni"
+ },
+ "source": [
+ "# Invoca a função\n",
+ "ml_XGB, best_params= GridSearchOptimizer(ml_XGB, 'ml_XGB2', d_parametros_XGB, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9b7uCuF74Hjv"
+ },
+ "source": [
+ "### Resultado da execução do XGBoostClassifier\n",
+ "\n",
+ "```\n",
+ "[Parallel(n_jobs=-1)]: Done 108000 out of 108000 | elapsed: 372.0min finished\n",
+ "\n",
+ "Parametros otimizados: {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "n7E0oyxEtbGi"
+ },
+ "source": [
+ "# Como o procedimento acima levou 372 minutos para executar, então vou estimar ml_XGB2 abaixo usando os parâmetros acima estimados\n",
+ "best_params= {'colsample_bytree': 0.8, 'gamma': 0.5, 'learning_rate': 0.51, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.6}\n",
+ "\n",
+ "ml_XGB2= XGBClassifier(min_child_weight= best_params['min_child_weight'], \n",
+ " gamma= best_params['gamma'], \n",
+ " subsample= best_params['subsample'], \n",
+ " colsample_bytree= best_params['colsample_bytree'], \n",
+ " max_depth= best_params['max_depth'], \n",
+ " learning_rate= best_params['learning_rate'], \n",
+ " random_state= i_Seed)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CuqyLHTU5Z-j"
+ },
+ "source": [
+ "## Selecionar as COLUNAS importantes/relevantes\n",
+ "* [The Multiple faces of ‘Feature importance’ in XGBoost](https://towardsdatascience.com/be-careful-when-interpreting-your-features-importance-in-xgboost-6e16132588e7)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QPG3JZIpRZ-T"
+ },
+ "source": [
+ "# plot feature importance\n",
+ "from xgboost import plot_importance\n",
+ "\n",
+ "xgb.plot_importance(ml_XGB2, color = 'red')\n",
+ "plt.title('importance', fontsize = 20)\n",
+ "plt.yticks(fontsize = 10)\n",
+ "plt.ylabel('features', fontsize = 20)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EmpRC2lHW-KP"
+ },
+ "source": [
+ "ml_XGB2"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4f9MIEBiyq-5"
+ },
+ "source": [
+ "X_treinamento_XGB, X_teste_XGB= seleciona_colunas_relevantes(ml_XGB2, X_treinamento, X_teste)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F6EayWaY5nMm"
+ },
+ "source": [
+ "## Treina o classificador com as COLUNAS relevantes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Huy18gKI5qad"
+ },
+ "source": [
+ "best_params"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "E3-PaTdc5vZk"
+ },
+ "source": [
+ "# Treina com as COLUNAS relevantes...\n",
+ "ml_XGB2.fit(X_treinamento_XGB, y_treinamento)\n",
+ "\n",
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_XGB2, X_treinamento_XGB, y_treinamento, cv = i_CV)\n",
+ "print(f'Acurácia Media: {100*a_scores_CV.mean():.2f}')\n",
+ "print(f'std médio.....: {100*a_scores_CV.std():.2f}')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tBdYikDU6NhD"
+ },
+ "source": [
+ "## Valida o modelo usando o dataframe X_teste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GcvY-VdL6VIZ"
+ },
+ "source": [
+ "y_pred_XGB = ml_XGB2.predict(X_teste_XGB)\n",
+ "\n",
+ "# Calcula acurácia\n",
+ "accuracy_score(y_teste, y_pred_XGB)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8oLtdH-vTSbC"
+ },
+ "source": [
+ "xgb.to_graphviz(ml_XGB2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "czXQG3MCHfHM"
+ },
+ "source": [
+ "# KNN - KNEIGHBORSCLASSIFIER"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "llTTXNeyHiwx"
+ },
+ "source": [
+ "# BAGGINGCLASSIFIER"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Fbkekd4QHoZO"
+ },
+ "source": [
+ "# EXTRATREESCLASSIFIER"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "widavwR4HzwE"
+ },
+ "source": [
+ "# SVM\n",
+ "https://data-flair.training/blogs/svm-support-vector-machine-tutorial/"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "id_Ubulns6We"
+ },
+ "source": [
+ "# NAIVE BAYES"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3e0m7lEnYOV9"
+ },
+ "source": [
+ "# **IMPORTANCIA DAS COLUNAS**\n",
+ "Source: [Plotting Feature Importances](https://www.kaggle.com/grfiv4/plotting-feature-importances)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fjco0HnNYr-N"
+ },
+ "source": [
+ "def mostra_feature_importances(clf, X_treinamento, y_treinamento=None, \n",
+ " top_n=10, figsize=(8,8), print_table=False, title=\"Feature Importances\"):\n",
+ " '''\n",
+ " plot feature importances of a tree-based sklearn estimator\n",
+ " \n",
+ " Note: X_treinamento and y_treinamento are pandas DataFrames\n",
+ " \n",
+ " Note: Scikit-plot is a lovely package but I sometimes have issues\n",
+ " 1. flexibility/extendibility\n",
+ " 2. complicated models/datasets\n",
+ " But for many situations Scikit-plot is the way to go\n",
+ " see https://scikit-plot.readthedocs.io/en/latest/Quickstart.html\n",
+ " \n",
+ " Parameters\n",
+ " ----------\n",
+ " clf (sklearn estimator) if not fitted, this routine will fit it\n",
+ " \n",
+ " X_treinamento (pandas DataFrame)\n",
+ " \n",
+ " y_treinamento (pandas DataFrame) optional\n",
+ " required only if clf has not already been fitted \n",
+ " \n",
+ " top_n (int) Plot the top_n most-important features\n",
+ " Default: 10\n",
+ " \n",
+ " figsize ((int,int)) The physical size of the plot\n",
+ " Default: (8,8)\n",
+ " \n",
+ " print_table (boolean) If True, print out the table of feature importances\n",
+ " Default: False\n",
+ " \n",
+ " Returns\n",
+ " -------\n",
+ " the pandas dataframe with the features and their importance\n",
+ " \n",
+ " Author\n",
+ " ------\n",
+ " George Fisher\n",
+ " '''\n",
+ " \n",
+ " __name__ = \"mostra_feature_importances\"\n",
+ " \n",
+ " import pandas as pd\n",
+ " import numpy as np\n",
+ " import matplotlib.pyplot as plt\n",
+ " \n",
+ " from xgboost.core import XGBoostError\n",
+ " from lightgbm.sklearn import LightGBMError\n",
+ " \n",
+ " try: \n",
+ " if not hasattr(clf, 'feature_importances_'):\n",
+ " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n",
+ "\n",
+ " if not hasattr(clf, 'feature_importances_'):\n",
+ " raise AttributeError(\"{} does not have feature_importances_ attribute\".\n",
+ " format(clf.__class__.__name__))\n",
+ " \n",
+ " except (XGBoostError, LightGBMError, ValueError):\n",
+ " clf.fit(X_treinamento.values, y_treinamento.values.ravel())\n",
+ " \n",
+ " feat_imp = pd.DataFrame({'importance':clf.feature_importances_}) \n",
+ " feat_imp['feature'] = X_treinamento.columns\n",
+ " feat_imp.sort_values(by ='importance', ascending = False, inplace = True)\n",
+ " feat_imp = feat_imp.iloc[:top_n]\n",
+ " \n",
+ " feat_imp.sort_values(by='importance', inplace = True)\n",
+ " feat_imp = feat_imp.set_index('feature', drop = True)\n",
+ " feat_imp.plot.barh(title=title, figsize=figsize)\n",
+ " plt.xlabel('Feature Importance Score')\n",
+ " plt.show()\n",
+ " \n",
+ " if print_table:\n",
+ " from IPython.display import display\n",
+ " print(\"Top {} features in descending order of importance\".format(top_n))\n",
+ " display(feat_imp.sort_values(by = 'importance', ascending = False))\n",
+ " \n",
+ " return feat_imp"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ycu_EIGlYUYn"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "from xgboost import XGBClassifier\n",
+ "from sklearn.ensemble import ExtraTreesClassifier\n",
+ "from sklearn.tree import ExtraTreeClassifier\n",
+ "from sklearn.tree import DecisionTreeClassifier\n",
+ "from sklearn.ensemble import GradientBoostingClassifier\n",
+ "from sklearn.ensemble import BaggingClassifier\n",
+ "from sklearn.ensemble import AdaBoostClassifier\n",
+ "from sklearn.ensemble import RandomForestClassifier\n",
+ "from sklearn.linear_model import LogisticRegression\n",
+ "from lightgbm import LGBMClassifier\n",
+ "\n",
+ "clfs = [XGBClassifier(), LGBMClassifier(), \n",
+ " ExtraTreesClassifier(), ExtraTreeClassifier(),\n",
+ " BaggingClassifier(), DecisionTreeClassifier(),\n",
+ " GradientBoostingClassifier(), LogisticRegression(),\n",
+ " AdaBoostClassifier(), RandomForestClassifier()]\n",
+ "\n",
+ "for clf in clfs:\n",
+ " try:\n",
+ " _ = mostra_feature_importances(clf, X_treinamento, y_treinamento, top_n=X_treinamento.shape[1], title=clf.__class__.__name__)\n",
+ " except AttributeError as e:\n",
+ " print(e)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "EwWkjfC8KEZH"
+ },
+ "source": [
+ "# ENSEMBLE METHODS\n",
+ "https://towardsdatascience.com/using-bagging-and-boosting-to-improve-classification-tree-accuracy-6d3bb6c95e5b\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3Uf1RML7xETY"
+ },
+ "source": [
+ "# WOE e IV\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TBNRfYZCyhMP"
+ },
+ "source": [
+ "## Construção do exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gIIroyyP4ZRZ"
+ },
+ "source": [
+ "df_y.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PzQQdrkf1ohX"
+ },
+ "source": [
+ "from random import choices\n",
+ "\n",
+ "df_X2= df_X.copy()\n",
+ "df_X2['tipo']= choices(['A', 'B', 'C', 'D'], k= 1000)\n",
+ "df_X2['idade']= np.random.randint(10, 15, size= 1000)\n",
+ "df_X2['target']= df_y['target']\n",
+ "df_X2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v-OpwIpx4hXJ"
+ },
+ "source": [
+ "df_X2['target'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yZfqSvbKzeJ3"
+ },
+ "source": [
+ "def Constroi_Buckets(df, i, k= 10):\n",
+ " coluna= 'v'+ str(i)\n",
+ " df[coluna+'_Bucket']= pd.cut(df[coluna], bins= k, labels= np.arange(1, k+1))\n",
+ " df= df.drop(columns= [coluna], axis= 1)\n",
+ " return df"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V6Nrpsx60HD3"
+ },
+ "source": [
+ "for i in np.arange(1,19):\n",
+ " df_X2= Constroi_Buckets(df_X2, i)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J2Fbh41-03OB"
+ },
+ "source": [
+ "df_X2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "O9r5BeWVxIr3"
+ },
+ "source": [
+ "# Função para calcular WOE e IV\n",
+ "def calculate_woe_iv(dataset, feature, target):\n",
+ "\n",
+ " def codethem(IV):\n",
+ " if IV < 0.02: return 'Useless'\n",
+ " elif IV >= 0.02 and IV < 0.1: return 'Weak'\n",
+ " elif IV >= 0.1 and IV < 0.3: return 'Medium'\n",
+ " elif IV >= 0.3 and IV < 0.5: return 'Strong'\n",
+ " elif IV >= 0.5: return 'Suspicious'\n",
+ " else: return 'None'\n",
+ "\n",
+ " lst = []\n",
+ " for i in range(dataset[feature].nunique()):\n",
+ " val = list(dataset[feature].unique())[i]\n",
+ " lst.append({\n",
+ " 'Value': val,\n",
+ " 'All': dataset[dataset[feature] == val].count()[feature],\n",
+ " 'Good': dataset[(dataset[feature] == val) & (dataset[target] == 0)].count()[feature],\n",
+ " 'Bad': dataset[(dataset[feature] == val) & (dataset[target] == 1)].count()[feature]\n",
+ " })\n",
+ " \n",
+ " dset = pd.DataFrame(lst)\n",
+ " dset['Distr_Good'] = dset['Good']/dset['Good'].sum()\n",
+ " dset['Distr_Bad'] = dset['Bad']/dset['Bad'].sum()\n",
+ " dset['Mean']= dset['All']/dset['All'].sum()\n",
+ " dset['WoE'] = np.log(dset['Distr_Good']/dset['Distr_Bad'])\n",
+ " dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})\n",
+ " dset['IV'] = (dset['Distr_Good'] - dset['Distr_Bad']) * dset['WoE']\n",
+ " #dset= dset.drop(columns= ['Distr_Good', 'Distr_Bad'], axis= 1)\n",
+ "\n",
+ " dset['Predictive_Power']= dset['IV'].map(codethem)\n",
+ " iv = dset['IV'].sum() \n",
+ " dset = dset.sort_values(by='IV') \n",
+ " return dset, iv"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Y8WGjWH63nx_"
+ },
+ "source": [
+ "df_Lab = df_X2.copy()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-N6xr1MgxTiz"
+ },
+ "source": [
+ "def calcula_Predictive_Power(df_Lab, coluna):\n",
+ " print('WoE and IV for column: {}'.format(coluna))\n",
+ " df, iv = calculate_woe_iv(df_Lab, coluna, 'target')\n",
+ " print(df)\n",
+ " print('IV score: {:.2f}'.format(iv))\n",
+ " print('\\n')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ayqN_7WnxVq9"
+ },
+ "source": [
+ "for i in np.arange(1,19):\n",
+ " coluna= 'v'+str(i)+'_Bucket'\n",
+ " calcula_Predictive_Power(df_Lab, coluna)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qtoJVI4Pyx3I"
+ },
+ "source": [
+ "# **IMBALANCED SAMPLE**\n",
+ "> Alguns objetivos como detectar fraude em transações bancárias ou detecção de intrusão em network tem em comum o fato que a classe de interesse (o que queremos detectar), geralmente é um evento raro\n",
+ "\n",
+ "## Exemplo: Detectar fraude\n",
+ "A proporção de fraudes diante de NÃO-FRAUDES são mais ou menos 1%/99%. Neste caso, ao desenvovermos um modelo para detectar fraudes e o modelo classificar todas as instâncias como NÃO-FRAUDE, então o modelo terá uma acurácia de 99%. No entanto, este modelo não nos ajudará em nada.\n",
+ "\n",
+ "## Necessidade de se usar outras métricas \n",
+ "> Recomenda-se utilizar outras métricas (na verdade, é boa prática usar mais de 1 métrica para medir a performance dos modelos) como, por exemplo, F1-Score, Precision/Specificity, Recall/Sensitivity e AUROC.\n",
+ "\n",
+ "## Como lidar com a amostra desbalanceada?\n",
+ "* Under-sampling\n",
+ "> Seleciona aleatoriamente a classe MAJORITÁRIA (em nosso exemplo, NÃO-FRAUDE) até o número de instâncias da classe MINORITÁRIA (FRAUDE);\n",
+ "\n",
+ "* Over-sampling\n",
+ "> Resample aleatoriamente a classe MINORITÁRIA (em nosso exemplo, FRAUDE) até o número de instâncias da classe MAJORITÁRIA (NÃO-FRAUDE), ou uma proporção da classe MAJORITÁRIA. Veja a bibliotea SMOTE (Synthetic Minority Over-Sampling Techniques);\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2o45zx8zw-aB"
+ },
+ "source": [
+ "## EFEITOS DA AMOSTRA DESBALANCEADA"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cCVTPCB-Xkbd"
+ },
+ "source": [
+ "# TPOT\n",
+ "https://towardsdatascience.com/tpot-automated-machine-learning-in-python-4c063b3e5de9"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2ulXii6JXpWd"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_TWUq-z4X4yZ"
+ },
+ "source": [
+ "___\n",
+ "# FEATURETOOLS\n",
+ "https://medium.com/@rrfd/simple-automatic-feature-engineering-using-featuretools-in-python-for-classification-b1308040e183\n",
+ "\n",
+ "https://www.analyticsvidhya.com/blog/2018/08/guide-automated-feature-engineering-featuretools-python/\n",
+ "\n",
+ "https://mlwhiz.com/blog/2019/05/19/feature_extraction/\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aZUNOgmSgAmq"
+ },
+ "source": [
+ "!pip install featuretools"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_sxdONzsh9rb"
+ },
+ "source": [
+ "df_X.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "p5_ynGo1dBJJ"
+ },
+ "source": [
+ "df_X.shape"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TqJRJXUhiDqf"
+ },
+ "source": [
+ "from random import choices\n",
+ "\n",
+ "df_X2= df_X.copy()\n",
+ "df_X2['tipo'] = choices(['A', 'B', 'C', 'D'], k = 1000)\n",
+ "df_X2['idade'] = np.random.randint(10, 15, size = 1000)\n",
+ "df_X2['id'] = range(0,1000)\n",
+ "df_X2.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nR56bGGngk-W"
+ },
+ "source": [
+ "# Automated feature engineering\n",
+ "import featuretools as ft\n",
+ "import featuretools.variable_types as vtypes\n",
+ "\n",
+ "es= ft.EntitySet(id = 'simulacao')\n",
+ "\n",
+ "# adding a dataframe \n",
+ "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id')\n",
+ "es"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IOJ4Tr5Ogk6M"
+ },
+ "source": [
+ "es['df_X2'].variables"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1uXPqHDZgkys"
+ },
+ "source": [
+ "variable_types = {'idade': vtypes.Categorical}\n",
+ " \n",
+ "es.entity_from_dataframe(entity_id = 'df_X2', dataframe = df_X2, index = 'id', variable_types= variable_types)\n",
+ "\n",
+ "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'tipo', index='id')\n",
+ "es = es.normalize_entity(base_entity_id='df_X2', new_entity_id= 'idade', index='id')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dnbYTBqugkvm"
+ },
+ "source": [
+ "es"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "I2v_jetdgkr7"
+ },
+ "source": [
+ "feature_matrix, feature_names = ft.dfs(entityset=es, target_entity = 'df_X2', max_depth = 3, verbose = 3, n_jobs= 1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zZiRBvHXgkoJ"
+ },
+ "source": [
+ "feature_matrix.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "aWiahwKe2d6U"
+ },
+ "source": [
+ "# **EXERCÍCIOS**\n",
+ "> Encontre algoritmos adequados para ser aplicados aos seguintes problemas:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XbSLkbDB2mzK"
+ },
+ "source": [
+ "## Exercício 1 - Credit Card Fraud Detection\n",
+ "Source: [Credit Card Fraud Detection](https://www.kaggle.com/mlg-ulb/creditcardfraud)\n",
+ "\n",
+ "### Leitura suporte\n",
+ "* [Detecting Credit Card Fraud Using Machine Learning](https://towardsdatascience.com/detecting-credit-card-fraud-using-machine-learning-a3d83423d3b8)\n",
+ "* [Credit Card Fraud Detection](https://towardsdatascience.com/credit-card-fraud-detection-a1c7e1b75f59)\n",
+ "\n",
+ "### Dataframe\n",
+ "* [Creditcard.csv](https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JYVM3StS-g0E"
+ },
+ "source": [
+ "### Importar as libraries necessárias"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dyliPChh-jPk"
+ },
+ "source": [
+ "from sklearn.metrics import accuracy_score # para medir a acurácia do modelo preditivo\n",
+ "#from sklearn.model_selection import train_test_split\n",
+ "#from sklearn.metrics import classification_report\n",
+ "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix\n",
+ "\n",
+ "from sklearn.model_selection import GridSearchCV # para otimizar os parâmetros dos modelos preditivos\n",
+ "from sklearn.model_selection import cross_val_score\n",
+ "from time import time\n",
+ "from operator import itemgetter\n",
+ "from scipy.stats import randint\n",
+ "\n",
+ "from sklearn.tree import export_graphviz\n",
+ "from sklearn.externals.six import StringIO \n",
+ "from IPython.display import Image \n",
+ "import pydotplus\n",
+ "\n",
+ "np.set_printoptions(suppress=True)"
+ ],
+ "execution_count": 52,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kpy5coZZ-BLx"
+ },
+ "source": [
+ "from sklearn.metrics import confusion_matrix # para plotar a confusion matrix"
+ ],
+ "execution_count": 91,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lAl9ZwP_0-d0"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/creditcard.csv'\n",
+ "df_cc = pd.read_csv(url)"
+ ],
+ "execution_count": 53,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "w6lN8FjJ12VU",
+ "outputId": "eee4d215-282a-44e7-b4a8-2123e6d391c8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 379
+ }
+ },
+ "source": [
+ "df_cc.head(10)"
+ ],
+ "execution_count": 54,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Time | \n",
+ " V1 | \n",
+ " V2 | \n",
+ " V3 | \n",
+ " V4 | \n",
+ " V5 | \n",
+ " V6 | \n",
+ " V7 | \n",
+ " V8 | \n",
+ " V9 | \n",
+ " V10 | \n",
+ " V11 | \n",
+ " V12 | \n",
+ " V13 | \n",
+ " V14 | \n",
+ " V15 | \n",
+ " V16 | \n",
+ " V17 | \n",
+ " V18 | \n",
+ " V19 | \n",
+ " V20 | \n",
+ " V21 | \n",
+ " V22 | \n",
+ " V23 | \n",
+ " V24 | \n",
+ " V25 | \n",
+ " V26 | \n",
+ " V27 | \n",
+ " V28 | \n",
+ " Amount | \n",
+ " Class | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0 | \n",
+ " -1.359807 | \n",
+ " -0.072781 | \n",
+ " 2.536347 | \n",
+ " 1.378155 | \n",
+ " -0.338321 | \n",
+ " 0.462388 | \n",
+ " 0.239599 | \n",
+ " 0.098698 | \n",
+ " 0.363787 | \n",
+ " 0.090794 | \n",
+ " -0.551600 | \n",
+ " -0.617801 | \n",
+ " -0.991390 | \n",
+ " -0.311169 | \n",
+ " 1.468177 | \n",
+ " -0.470401 | \n",
+ " 0.207971 | \n",
+ " 0.025791 | \n",
+ " 0.403993 | \n",
+ " 0.251412 | \n",
+ " -0.018307 | \n",
+ " 0.277838 | \n",
+ " -0.110474 | \n",
+ " 0.066928 | \n",
+ " 0.128539 | \n",
+ " -0.189115 | \n",
+ " 0.133558 | \n",
+ " -0.021053 | \n",
+ " 149.62 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0 | \n",
+ " 1.191857 | \n",
+ " 0.266151 | \n",
+ " 0.166480 | \n",
+ " 0.448154 | \n",
+ " 0.060018 | \n",
+ " -0.082361 | \n",
+ " -0.078803 | \n",
+ " 0.085102 | \n",
+ " -0.255425 | \n",
+ " -0.166974 | \n",
+ " 1.612727 | \n",
+ " 1.065235 | \n",
+ " 0.489095 | \n",
+ " -0.143772 | \n",
+ " 0.635558 | \n",
+ " 0.463917 | \n",
+ " -0.114805 | \n",
+ " -0.183361 | \n",
+ " -0.145783 | \n",
+ " -0.069083 | \n",
+ " -0.225775 | \n",
+ " -0.638672 | \n",
+ " 0.101288 | \n",
+ " -0.339846 | \n",
+ " 0.167170 | \n",
+ " 0.125895 | \n",
+ " -0.008983 | \n",
+ " 0.014724 | \n",
+ " 2.69 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1 | \n",
+ " -1.358354 | \n",
+ " -1.340163 | \n",
+ " 1.773209 | \n",
+ " 0.379780 | \n",
+ " -0.503198 | \n",
+ " 1.800499 | \n",
+ " 0.791461 | \n",
+ " 0.247676 | \n",
+ " -1.514654 | \n",
+ " 0.207643 | \n",
+ " 0.624501 | \n",
+ " 0.066084 | \n",
+ " 0.717293 | \n",
+ " -0.165946 | \n",
+ " 2.345865 | \n",
+ " -2.890083 | \n",
+ " 1.109969 | \n",
+ " -0.121359 | \n",
+ " -2.261857 | \n",
+ " 0.524980 | \n",
+ " 0.247998 | \n",
+ " 0.771679 | \n",
+ " 0.909412 | \n",
+ " -0.689281 | \n",
+ " -0.327642 | \n",
+ " -0.139097 | \n",
+ " -0.055353 | \n",
+ " -0.059752 | \n",
+ " 378.66 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " -0.966272 | \n",
+ " -0.185226 | \n",
+ " 1.792993 | \n",
+ " -0.863291 | \n",
+ " -0.010309 | \n",
+ " 1.247203 | \n",
+ " 0.237609 | \n",
+ " 0.377436 | \n",
+ " -1.387024 | \n",
+ " -0.054952 | \n",
+ " -0.226487 | \n",
+ " 0.178228 | \n",
+ " 0.507757 | \n",
+ " -0.287924 | \n",
+ " -0.631418 | \n",
+ " -1.059647 | \n",
+ " -0.684093 | \n",
+ " 1.965775 | \n",
+ " -1.232622 | \n",
+ " -0.208038 | \n",
+ " -0.108300 | \n",
+ " 0.005274 | \n",
+ " -0.190321 | \n",
+ " -1.175575 | \n",
+ " 0.647376 | \n",
+ " -0.221929 | \n",
+ " 0.062723 | \n",
+ " 0.061458 | \n",
+ " 123.50 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2 | \n",
+ " -1.158233 | \n",
+ " 0.877737 | \n",
+ " 1.548718 | \n",
+ " 0.403034 | \n",
+ " -0.407193 | \n",
+ " 0.095921 | \n",
+ " 0.592941 | \n",
+ " -0.270533 | \n",
+ " 0.817739 | \n",
+ " 0.753074 | \n",
+ " -0.822843 | \n",
+ " 0.538196 | \n",
+ " 1.345852 | \n",
+ " -1.119670 | \n",
+ " 0.175121 | \n",
+ " -0.451449 | \n",
+ " -0.237033 | \n",
+ " -0.038195 | \n",
+ " 0.803487 | \n",
+ " 0.408542 | \n",
+ " -0.009431 | \n",
+ " 0.798278 | \n",
+ " -0.137458 | \n",
+ " 0.141267 | \n",
+ " -0.206010 | \n",
+ " 0.502292 | \n",
+ " 0.219422 | \n",
+ " 0.215153 | \n",
+ " 69.99 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 2 | \n",
+ " -0.425966 | \n",
+ " 0.960523 | \n",
+ " 1.141109 | \n",
+ " -0.168252 | \n",
+ " 0.420987 | \n",
+ " -0.029728 | \n",
+ " 0.476201 | \n",
+ " 0.260314 | \n",
+ " -0.568671 | \n",
+ " -0.371407 | \n",
+ " 1.341262 | \n",
+ " 0.359894 | \n",
+ " -0.358091 | \n",
+ " -0.137134 | \n",
+ " 0.517617 | \n",
+ " 0.401726 | \n",
+ " -0.058133 | \n",
+ " 0.068653 | \n",
+ " -0.033194 | \n",
+ " 0.084968 | \n",
+ " -0.208254 | \n",
+ " -0.559825 | \n",
+ " -0.026398 | \n",
+ " -0.371427 | \n",
+ " -0.232794 | \n",
+ " 0.105915 | \n",
+ " 0.253844 | \n",
+ " 0.081080 | \n",
+ " 3.67 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 4 | \n",
+ " 1.229658 | \n",
+ " 0.141004 | \n",
+ " 0.045371 | \n",
+ " 1.202613 | \n",
+ " 0.191881 | \n",
+ " 0.272708 | \n",
+ " -0.005159 | \n",
+ " 0.081213 | \n",
+ " 0.464960 | \n",
+ " -0.099254 | \n",
+ " -1.416907 | \n",
+ " -0.153826 | \n",
+ " -0.751063 | \n",
+ " 0.167372 | \n",
+ " 0.050144 | \n",
+ " -0.443587 | \n",
+ " 0.002821 | \n",
+ " -0.611987 | \n",
+ " -0.045575 | \n",
+ " -0.219633 | \n",
+ " -0.167716 | \n",
+ " -0.270710 | \n",
+ " -0.154104 | \n",
+ " -0.780055 | \n",
+ " 0.750137 | \n",
+ " -0.257237 | \n",
+ " 0.034507 | \n",
+ " 0.005168 | \n",
+ " 4.99 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 7 | \n",
+ " -0.644269 | \n",
+ " 1.417964 | \n",
+ " 1.074380 | \n",
+ " -0.492199 | \n",
+ " 0.948934 | \n",
+ " 0.428118 | \n",
+ " 1.120631 | \n",
+ " -3.807864 | \n",
+ " 0.615375 | \n",
+ " 1.249376 | \n",
+ " -0.619468 | \n",
+ " 0.291474 | \n",
+ " 1.757964 | \n",
+ " -1.323865 | \n",
+ " 0.686133 | \n",
+ " -0.076127 | \n",
+ " -1.222127 | \n",
+ " -0.358222 | \n",
+ " 0.324505 | \n",
+ " -0.156742 | \n",
+ " 1.943465 | \n",
+ " -1.015455 | \n",
+ " 0.057504 | \n",
+ " -0.649709 | \n",
+ " -0.415267 | \n",
+ " -0.051634 | \n",
+ " -1.206921 | \n",
+ " -1.085339 | \n",
+ " 40.80 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " 7 | \n",
+ " -0.894286 | \n",
+ " 0.286157 | \n",
+ " -0.113192 | \n",
+ " -0.271526 | \n",
+ " 2.669599 | \n",
+ " 3.721818 | \n",
+ " 0.370145 | \n",
+ " 0.851084 | \n",
+ " -0.392048 | \n",
+ " -0.410430 | \n",
+ " -0.705117 | \n",
+ " -0.110452 | \n",
+ " -0.286254 | \n",
+ " 0.074355 | \n",
+ " -0.328783 | \n",
+ " -0.210077 | \n",
+ " -0.499768 | \n",
+ " 0.118765 | \n",
+ " 0.570328 | \n",
+ " 0.052736 | \n",
+ " -0.073425 | \n",
+ " -0.268092 | \n",
+ " -0.204233 | \n",
+ " 1.011592 | \n",
+ " 0.373205 | \n",
+ " -0.384157 | \n",
+ " 0.011747 | \n",
+ " 0.142404 | \n",
+ " 93.20 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " 9 | \n",
+ " -0.338262 | \n",
+ " 1.119593 | \n",
+ " 1.044367 | \n",
+ " -0.222187 | \n",
+ " 0.499361 | \n",
+ " -0.246761 | \n",
+ " 0.651583 | \n",
+ " 0.069539 | \n",
+ " -0.736727 | \n",
+ " -0.366846 | \n",
+ " 1.017614 | \n",
+ " 0.836390 | \n",
+ " 1.006844 | \n",
+ " -0.443523 | \n",
+ " 0.150219 | \n",
+ " 0.739453 | \n",
+ " -0.540980 | \n",
+ " 0.476677 | \n",
+ " 0.451773 | \n",
+ " 0.203711 | \n",
+ " -0.246914 | \n",
+ " -0.633753 | \n",
+ " -0.120794 | \n",
+ " -0.385050 | \n",
+ " -0.069733 | \n",
+ " 0.094199 | \n",
+ " 0.246219 | \n",
+ " 0.083076 | \n",
+ " 3.68 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Time V1 V2 V3 ... V27 V28 Amount Class\n",
+ "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n",
+ "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n",
+ "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n",
+ "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n",
+ "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n",
+ "5 2 -0.425966 0.960523 1.141109 ... 0.253844 0.081080 3.67 0.0\n",
+ "6 4 1.229658 0.141004 0.045371 ... 0.034507 0.005168 4.99 0.0\n",
+ "7 7 -0.644269 1.417964 1.074380 ... -1.206921 -1.085339 40.80 0.0\n",
+ "8 7 -0.894286 0.286157 -0.113192 ... 0.011747 0.142404 93.20 0.0\n",
+ "9 9 -0.338262 1.119593 1.044367 ... 0.246219 0.083076 3.68 0.0\n",
+ "\n",
+ "[10 rows x 31 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 54
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "M47GS1cK2NdD",
+ "outputId": "91cb28e1-5fd6-4ce4-b733-db59fcace09e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "df_cc.shape"
+ ],
+ "execution_count": 55,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(12842, 31)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 55
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NFlXj1OAzvPS",
+ "outputId": "228e6a58-8a52-4f1c-944b-ebe25b89b339",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 102
+ }
+ },
+ "source": [
+ "df_cc.columns"
+ ],
+ "execution_count": 58,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Index(['Time', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6', 'V7', 'V8', 'V9', 'V10',\n",
+ " 'V11', 'V12', 'V13', 'V14', 'V15', 'V16', 'V17', 'V18', 'V19', 'V20',\n",
+ " 'V21', 'V22', 'V23', 'V24', 'V25', 'V26', 'V27', 'V28', 'Amount',\n",
+ " 'Class'],\n",
+ " dtype='object')"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 58
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vpVRbkTV0AI_"
+ },
+ "source": [
+ "#df_cc.columns() = (coluna.lower() for coluna in df_cc.columns)"
+ ],
+ "execution_count": 60,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "b2QBZFbR3W_q",
+ "outputId": "b2076b85-21cc-49ea-a603-586036f5fae5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "df_cc['Class'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.0 12785\n",
+ "1.0 56\n",
+ "Name: Class, dtype: int64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 126
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pzjW3Bf_3h7J",
+ "outputId": "c87f7be2-0bf6-4dea-b77a-26bee019992a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "56/12842"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.004360691481077714"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 129
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9bWDX9H12k5g"
+ },
+ "source": [
+ "### Drop NaN"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "27ob8tRR21TB",
+ "outputId": "59e26e44-a89c-4af8-9129-2452b3483ae9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 561
+ }
+ },
+ "source": [
+ "df_cc.isna().sum()\n"
+ ],
+ "execution_count": 61,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Time 0\n",
+ "V1 0\n",
+ "V2 0\n",
+ "V3 0\n",
+ "V4 0\n",
+ "V5 0\n",
+ "V6 0\n",
+ "V7 0\n",
+ "V8 0\n",
+ "V9 0\n",
+ "V10 1\n",
+ "V11 1\n",
+ "V12 1\n",
+ "V13 1\n",
+ "V14 1\n",
+ "V15 1\n",
+ "V16 1\n",
+ "V17 1\n",
+ "V18 1\n",
+ "V19 1\n",
+ "V20 1\n",
+ "V21 1\n",
+ "V22 1\n",
+ "V23 1\n",
+ "V24 1\n",
+ "V25 1\n",
+ "V26 1\n",
+ "V27 1\n",
+ "V28 1\n",
+ "Amount 1\n",
+ "Class 1\n",
+ "dtype: int64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 61
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "o1yH1ve00Y1P",
+ "outputId": "ca196cce-a22e-4229-d3b6-fb9d99a3a0fc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 400
+ }
+ },
+ "source": [
+ "#DataViz \n",
+ "sns.catplot(x = 'Class', y='V1', data= df_cc, kind='box' )"
+ ],
+ "execution_count": 64,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 64
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8tiBGhSX1tKn",
+ "outputId": "71fb07d6-e90f-4195-a52a-55c5810c201f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 400
+ }
+ },
+ "source": [
+ "#DataViz \n",
+ "sns.catplot(x = 'Class', y='V2', data= df_cc, kind='box' )"
+ ],
+ "execution_count": 65,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 65
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HNZd3Ha0104H",
+ "outputId": "6434a04d-1679-4a27-b31f-cba37402bede",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 400
+ }
+ },
+ "source": [
+ "#DataViz \n",
+ "sns.catplot(x = 'Class', y='V3', data= df_cc, kind='box' )"
+ ],
+ "execution_count": 66,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 66
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eYf95Muj2CB_",
+ "outputId": "890172a9-faa2-4ecb-d55c-4a6dce44e6a0",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "figura = plt.figure(figsize = (16,20))\n",
+ "for i in range(1,29):\n",
+ " plt.subplot(5,6,i)\n",
+ " plt.plot(df_cc['V'+str(i)])\n",
+ "plt.plot(df_cc['Amount']) "
+ ],
+ "execution_count": 68,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "[]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 68
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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ALZ4Pd9qLLOTApgsIvNFZLCxrImq7jAe7wTQxHgcKH47fi6rYmxuPPZd7lY8x6zDc8wczzHr8Bwzx3PMOjzHzPEcsw7PMXM8x6zj6nOscrwPkITOV9VtItIYQI6IrPJeqaoqIo6en8cNMaY4nmMUbzzHKN54jlG88RyjeOM5ZgOnt5xuA9DS63kLY5ltVHWb8X03gDHwdEPYZTR9w/i+29g8UPx2/FxWxbjNeOy73K14jlmH55g5nmPW4TlmjueYdXiOmeM5Zh2eY+Z4jlnH1eeY05PTuQDai0gbEakCYBCAsXYFIyI1RaR26WMAlwJYZsRUWtnqDgDfG4/HArjdqI51DoBDRjP7JACXikh9o4LWpcayeLIkRmPdYRE5x6jYdbvXvtyI55h1eI6Z4zlmHZ5j5niOWYfnmDmeY9bhOWaO55h13H2OqQMqdAX7gqey1Bp4KngNszmWU+GpHrYYwPLSeAA0BDAFwFoAuQAaGMsFwBtG7EsBZHnt624A64yvuyyO83MAOwAUwtM//B4rYwSQBc8/6HoArwMQu88TnmM8x5z8xXOM5xjPMZ5jPMd4jvEc4znGcyz0lxgHJiIiIiIiIrKN07v1EhERERERUQpgckpERERERES2Y3JKREREREREtmNySkRERERERLZjckpERERERES2Y3JKREREREREtmNySkRERERERLZjckpERERERES2Y3JKREREREREtmNySkRERERERLZjckpERERERES2Y3JKREREREREtmNySkRERERERLZjckpERERERES2Y3JKREREREREtmNySkRERERERLZjckpERERERES2Y3JKREREREREtmNySkRERERERLZjckquICLvi8huEVnmtayBiOSIyFrje307YyQiIiIiougxOSW3+BDAAJ9lQwFMUdX2AKYYz4mIiIiIyIVEVe2OoUyjRo00MzPT7jDIJvPnz9+rqhmB1otIJoAfVLWL8Xw1gItUdYeINAXwo6p2DHYMnmOpLdQ5ZgWeY6mN5xjFWyLOMYDnWSrjOUbxFuwcq5zoYILJzMzEvHnz7A6DbCIimyJ8SRNV3WE83gmgSYD9DgYwGABatWrFcyyFRXGORYzvY6mN5xjFWyLOMYDnWSrjOUbxFuwcY7deSgrq6QJg2g1AVUepapaqZmVkxP1GIBERERERRYHJKbnZLqM7L4zv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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rhsQe_Tc3yLy",
+ "outputId": "b002ee2b-4859-4206-c102-d1367b015ce6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 317
+ }
+ },
+ "source": [
+ "df_cc.describe()"
+ ],
+ "execution_count": 70,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Time | \n",
+ " V1 | \n",
+ " V2 | \n",
+ " V3 | \n",
+ " V4 | \n",
+ " V5 | \n",
+ " V6 | \n",
+ " V7 | \n",
+ " V8 | \n",
+ " V9 | \n",
+ " V10 | \n",
+ " V11 | \n",
+ " V12 | \n",
+ " V13 | \n",
+ " V14 | \n",
+ " V15 | \n",
+ " V16 | \n",
+ " V17 | \n",
+ " V18 | \n",
+ " V19 | \n",
+ " V20 | \n",
+ " V21 | \n",
+ " V22 | \n",
+ " V23 | \n",
+ " V24 | \n",
+ " V25 | \n",
+ " V26 | \n",
+ " V27 | \n",
+ " V28 | \n",
+ " Amount | \n",
+ " Class | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12842.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ " 12841.000000 | \n",
+ "
\n",
+ " \n",
+ " | mean | \n",
+ " 8949.099984 | \n",
+ " -0.216783 | \n",
+ " 0.275675 | \n",
+ " 0.875939 | \n",
+ " 0.280864 | \n",
+ " -0.111409 | \n",
+ " 0.134556 | \n",
+ " -0.147548 | \n",
+ " -0.031229 | \n",
+ " 0.966379 | \n",
+ " -0.320292 | \n",
+ " 0.842062 | \n",
+ " -1.494439 | \n",
+ " 0.965904 | \n",
+ " 0.815934 | \n",
+ " -0.177547 | \n",
+ " -0.036491 | \n",
+ " 0.393921 | \n",
+ " -0.012121 | \n",
+ " -0.072788 | \n",
+ " 0.021230 | \n",
+ " -0.062996 | \n",
+ " -0.147793 | \n",
+ " -0.035406 | \n",
+ " 0.015229 | \n",
+ " 0.113644 | \n",
+ " 0.043892 | \n",
+ " 0.011375 | \n",
+ " 0.000744 | \n",
+ " 62.219386 | \n",
+ " 0.004361 | \n",
+ "
\n",
+ " \n",
+ " | std | \n",
+ " 6914.588371 | \n",
+ " 1.653324 | \n",
+ " 1.338732 | \n",
+ " 1.453434 | \n",
+ " 1.495532 | \n",
+ " 1.232153 | \n",
+ " 1.307300 | \n",
+ " 1.202073 | \n",
+ " 1.243610 | \n",
+ " 1.217670 | \n",
+ " 1.209806 | \n",
+ " 1.189877 | \n",
+ " 1.544952 | \n",
+ " 1.171303 | \n",
+ " 1.331752 | \n",
+ " 0.981075 | \n",
+ " 0.949526 | \n",
+ " 1.158501 | \n",
+ " 0.833046 | \n",
+ " 0.823737 | \n",
+ " 0.571957 | \n",
+ " 0.894494 | \n",
+ " 0.621258 | \n",
+ " 0.496013 | \n",
+ " 0.589287 | \n",
+ " 0.426605 | \n",
+ " 0.563938 | \n",
+ " 0.401608 | \n",
+ " 0.257426 | \n",
+ " 175.780115 | \n",
+ " 0.065897 | \n",
+ "
\n",
+ " \n",
+ " | min | \n",
+ " 0.000000 | \n",
+ " -27.670569 | \n",
+ " -34.607649 | \n",
+ " -24.667741 | \n",
+ " -4.657545 | \n",
+ " -32.092129 | \n",
+ " -23.496714 | \n",
+ " -26.548144 | \n",
+ " -23.632502 | \n",
+ " -7.175097 | \n",
+ " -14.166795 | \n",
+ " -2.595325 | \n",
+ " -17.769143 | \n",
+ " -3.389510 | \n",
+ " -19.214325 | \n",
+ " -4.152532 | \n",
+ " -12.227189 | \n",
+ " -18.587366 | \n",
+ " -8.061208 | \n",
+ " -4.932733 | \n",
+ " -13.276034 | \n",
+ " -11.468435 | \n",
+ " -8.593642 | \n",
+ " -19.254328 | \n",
+ " -2.512377 | \n",
+ " -4.781606 | \n",
+ " -1.338556 | \n",
+ " -7.976100 | \n",
+ " -3.575312 | \n",
+ " 0.000000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " | 25% | \n",
+ " 2789.250000 | \n",
+ " -0.966739 | \n",
+ " -0.280216 | \n",
+ " 0.420540 | \n",
+ " -0.631430 | \n",
+ " -0.713310 | \n",
+ " -0.618201 | \n",
+ " -0.612138 | \n",
+ " -0.180510 | \n",
+ " 0.252389 | \n",
+ " -0.773721 | \n",
+ " 0.041619 | \n",
+ " -2.442860 | \n",
+ " 0.148875 | \n",
+ " 0.218535 | \n",
+ " -0.759873 | \n",
+ " -0.525637 | \n",
+ " -0.078526 | \n",
+ " -0.447914 | \n",
+ " -0.554832 | \n",
+ " -0.159392 | \n",
+ " -0.265563 | \n",
+ " -0.534956 | \n",
+ " -0.171847 | \n",
+ " -0.334567 | \n",
+ " -0.134560 | \n",
+ " -0.372507 | \n",
+ " -0.077529 | \n",
+ " -0.015002 | \n",
+ " 5.490000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " | 50% | \n",
+ " 7605.500000 | \n",
+ " -0.319439 | \n",
+ " 0.245807 | \n",
+ " 0.962057 | \n",
+ " 0.205730 | \n",
+ " -0.195153 | \n",
+ " -0.146859 | \n",
+ " -0.109023 | \n",
+ " 0.017735 | \n",
+ " 0.944073 | \n",
+ " -0.373792 | \n",
+ " 0.782630 | \n",
+ " -1.817630 | \n",
+ " 1.053044 | \n",
+ " 1.090067 | \n",
+ " -0.041798 | \n",
+ " 0.034157 | \n",
+ " 0.392384 | \n",
+ " 0.044854 | \n",
+ " -0.069879 | \n",
+ " -0.035732 | \n",
+ " -0.129139 | \n",
+ " -0.115690 | \n",
+ " -0.044329 | \n",
+ " 0.067107 | \n",
+ " 0.153360 | \n",
+ " -0.022228 | \n",
+ " -0.000787 | \n",
+ " 0.015907 | \n",
+ " 15.300000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " | 75% | \n",
+ " 14441.750000 | \n",
+ " 1.162983 | \n",
+ " 0.875673 | \n",
+ " 1.610908 | \n",
+ " 1.169584 | \n",
+ " 0.337192 | \n",
+ " 0.508040 | \n",
+ " 0.420298 | \n",
+ " 0.265311 | \n",
+ " 1.643443 | \n",
+ " 0.133831 | \n",
+ " 1.648365 | \n",
+ " -0.248728 | \n",
+ " 1.836428 | \n",
+ " 1.544681 | \n",
+ " 0.504464 | \n",
+ " 0.534263 | \n",
+ " 0.873357 | \n",
+ " 0.485550 | \n",
+ " 0.448875 | \n",
+ " 0.140779 | \n",
+ " 0.020585 | \n",
+ " 0.234024 | \n",
+ " 0.071117 | \n",
+ " 0.397918 | \n",
+ " 0.388684 | \n",
+ " 0.391314 | \n",
+ " 0.101575 | \n",
+ " 0.071500 | \n",
+ " 50.000000 | \n",
+ " 0.000000 | \n",
+ "
\n",
+ " \n",
+ " | max | \n",
+ " 22549.000000 | \n",
+ " 1.960497 | \n",
+ " 10.558600 | \n",
+ " 4.101716 | \n",
+ " 11.927512 | \n",
+ " 34.099309 | \n",
+ " 21.393069 | \n",
+ " 34.303177 | \n",
+ " 8.675685 | \n",
+ " 10.392889 | \n",
+ " 12.259949 | \n",
+ " 12.018913 | \n",
+ " 3.774837 | \n",
+ " 4.465413 | \n",
+ " 7.692209 | \n",
+ " 3.635042 | \n",
+ " 4.816252 | \n",
+ " 9.253526 | \n",
+ " 4.295648 | \n",
+ " 4.555359 | \n",
+ " 8.012574 | \n",
+ " 22.614889 | \n",
+ " 4.534454 | \n",
+ " 13.876221 | \n",
+ " 3.200201 | \n",
+ " 5.525093 | \n",
+ " 3.517346 | \n",
+ " 8.254376 | \n",
+ " 4.860769 | \n",
+ " 7712.430000 | \n",
+ " 1.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Time V1 ... Amount Class\n",
+ "count 12842.000000 12842.000000 ... 12841.000000 12841.000000\n",
+ "mean 8949.099984 -0.216783 ... 62.219386 0.004361\n",
+ "std 6914.588371 1.653324 ... 175.780115 0.065897\n",
+ "min 0.000000 -27.670569 ... 0.000000 0.000000\n",
+ "25% 2789.250000 -0.966739 ... 5.490000 0.000000\n",
+ "50% 7605.500000 -0.319439 ... 15.300000 0.000000\n",
+ "75% 14441.750000 1.162983 ... 50.000000 0.000000\n",
+ "max 22549.000000 1.960497 ... 7712.430000 1.000000\n",
+ "\n",
+ "[8 rows x 31 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 70
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fnqd6WKc62z7"
+ },
+ "source": [
+ "limite_superior_outlier = q3+1.5*iqr\n"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "X9k16WLI49JI",
+ "outputId": "63775512-a869-46b2-a566-53059de569ce",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "df_cc2 = df_cc.copy()\n",
+ "df_cc2 = df_cc.dropna()\n",
+ "df_cc2.shape"
+ ],
+ "execution_count": 71,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(12841, 31)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 71
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IM_qvu0G7DDg",
+ "outputId": "1b7b1084-75d4-4b0e-fb0b-aa669c4d9e3e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 439
+ }
+ },
+ "source": [
+ "l_preditoras = df_cc2.iloc[:,1:30]\n",
+ "l_preditoras"
+ ],
+ "execution_count": 72,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " V1 | \n",
+ " V2 | \n",
+ " V3 | \n",
+ " V4 | \n",
+ " V5 | \n",
+ " V6 | \n",
+ " V7 | \n",
+ " V8 | \n",
+ " V9 | \n",
+ " V10 | \n",
+ " V11 | \n",
+ " V12 | \n",
+ " V13 | \n",
+ " V14 | \n",
+ " V15 | \n",
+ " V16 | \n",
+ " V17 | \n",
+ " V18 | \n",
+ " V19 | \n",
+ " V20 | \n",
+ " V21 | \n",
+ " V22 | \n",
+ " V23 | \n",
+ " V24 | \n",
+ " V25 | \n",
+ " V26 | \n",
+ " V27 | \n",
+ " V28 | \n",
+ " Amount | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " -1.359807 | \n",
+ " -0.072781 | \n",
+ " 2.536347 | \n",
+ " 1.378155 | \n",
+ " -0.338321 | \n",
+ " 0.462388 | \n",
+ " 0.239599 | \n",
+ " 0.098698 | \n",
+ " 0.363787 | \n",
+ " 0.090794 | \n",
+ " -0.551600 | \n",
+ " -0.617801 | \n",
+ " -0.991390 | \n",
+ " -0.311169 | \n",
+ " 1.468177 | \n",
+ " -0.470401 | \n",
+ " 0.207971 | \n",
+ " 0.025791 | \n",
+ " 0.403993 | \n",
+ " 0.251412 | \n",
+ " -0.018307 | \n",
+ " 0.277838 | \n",
+ " -0.110474 | \n",
+ " 0.066928 | \n",
+ " 0.128539 | \n",
+ " -0.189115 | \n",
+ " 0.133558 | \n",
+ " -0.021053 | \n",
+ " 149.62 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1.191857 | \n",
+ " 0.266151 | \n",
+ " 0.166480 | \n",
+ " 0.448154 | \n",
+ " 0.060018 | \n",
+ " -0.082361 | \n",
+ " -0.078803 | \n",
+ " 0.085102 | \n",
+ " -0.255425 | \n",
+ " -0.166974 | \n",
+ " 1.612727 | \n",
+ " 1.065235 | \n",
+ " 0.489095 | \n",
+ " -0.143772 | \n",
+ " 0.635558 | \n",
+ " 0.463917 | \n",
+ " -0.114805 | \n",
+ " -0.183361 | \n",
+ " -0.145783 | \n",
+ " -0.069083 | \n",
+ " -0.225775 | \n",
+ " -0.638672 | \n",
+ " 0.101288 | \n",
+ " -0.339846 | \n",
+ " 0.167170 | \n",
+ " 0.125895 | \n",
+ " -0.008983 | \n",
+ " 0.014724 | \n",
+ " 2.69 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " -1.358354 | \n",
+ " -1.340163 | \n",
+ " 1.773209 | \n",
+ " 0.379780 | \n",
+ " -0.503198 | \n",
+ " 1.800499 | \n",
+ " 0.791461 | \n",
+ " 0.247676 | \n",
+ " -1.514654 | \n",
+ " 0.207643 | \n",
+ " 0.624501 | \n",
+ " 0.066084 | \n",
+ " 0.717293 | \n",
+ " -0.165946 | \n",
+ " 2.345865 | \n",
+ " -2.890083 | \n",
+ " 1.109969 | \n",
+ " -0.121359 | \n",
+ " -2.261857 | \n",
+ " 0.524980 | \n",
+ " 0.247998 | \n",
+ " 0.771679 | \n",
+ " 0.909412 | \n",
+ " -0.689281 | \n",
+ " -0.327642 | \n",
+ " -0.139097 | \n",
+ " -0.055353 | \n",
+ " -0.059752 | \n",
+ " 378.66 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " -0.966272 | \n",
+ " -0.185226 | \n",
+ " 1.792993 | \n",
+ " -0.863291 | \n",
+ " -0.010309 | \n",
+ " 1.247203 | \n",
+ " 0.237609 | \n",
+ " 0.377436 | \n",
+ " -1.387024 | \n",
+ " -0.054952 | \n",
+ " -0.226487 | \n",
+ " 0.178228 | \n",
+ " 0.507757 | \n",
+ " -0.287924 | \n",
+ " -0.631418 | \n",
+ " -1.059647 | \n",
+ " -0.684093 | \n",
+ " 1.965775 | \n",
+ " -1.232622 | \n",
+ " -0.208038 | \n",
+ " -0.108300 | \n",
+ " 0.005274 | \n",
+ " -0.190321 | \n",
+ " -1.175575 | \n",
+ " 0.647376 | \n",
+ " -0.221929 | \n",
+ " 0.062723 | \n",
+ " 0.061458 | \n",
+ " 123.50 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " -1.158233 | \n",
+ " 0.877737 | \n",
+ " 1.548718 | \n",
+ " 0.403034 | \n",
+ " -0.407193 | \n",
+ " 0.095921 | \n",
+ " 0.592941 | \n",
+ " -0.270533 | \n",
+ " 0.817739 | \n",
+ " 0.753074 | \n",
+ " -0.822843 | \n",
+ " 0.538196 | \n",
+ " 1.345852 | \n",
+ " -1.119670 | \n",
+ " 0.175121 | \n",
+ " -0.451449 | \n",
+ " -0.237033 | \n",
+ " -0.038195 | \n",
+ " 0.803487 | \n",
+ " 0.408542 | \n",
+ " -0.009431 | \n",
+ " 0.798278 | \n",
+ " -0.137458 | \n",
+ " 0.141267 | \n",
+ " -0.206010 | \n",
+ " 0.502292 | \n",
+ " 0.219422 | \n",
+ " 0.215153 | \n",
+ " 69.99 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 12836 | \n",
+ " 1.216532 | \n",
+ " -0.314522 | \n",
+ " 1.134570 | \n",
+ " 0.302071 | \n",
+ " -1.047467 | \n",
+ " -0.226341 | \n",
+ " -0.808963 | \n",
+ " 0.011571 | \n",
+ " 2.484110 | \n",
+ " -0.749128 | \n",
+ " -0.113215 | \n",
+ " -2.463177 | \n",
+ " 1.217232 | \n",
+ " 1.078202 | \n",
+ " -0.353184 | \n",
+ " 0.264467 | \n",
+ " 0.560170 | \n",
+ " 0.070299 | \n",
+ " 0.162726 | \n",
+ " -0.101807 | \n",
+ " -0.289677 | \n",
+ " -0.451358 | \n",
+ " 0.021372 | \n",
+ " 0.025676 | \n",
+ " 0.112433 | \n",
+ " 0.974426 | \n",
+ " -0.067625 | \n",
+ " 0.007633 | \n",
+ " 23.27 | \n",
+ "
\n",
+ " \n",
+ " | 12837 | \n",
+ " -1.730579 | \n",
+ " 2.510772 | \n",
+ " -3.816998 | \n",
+ " 1.981314 | \n",
+ " -0.013296 | \n",
+ " -2.005823 | \n",
+ " -0.761365 | \n",
+ " 1.439695 | \n",
+ " 1.029358 | \n",
+ " -1.507332 | \n",
+ " 0.574218 | \n",
+ " -3.026862 | \n",
+ " 1.041710 | \n",
+ " -0.878371 | \n",
+ " 0.412419 | \n",
+ " 1.463627 | \n",
+ " 4.071892 | \n",
+ " 2.149217 | \n",
+ " -0.544000 | \n",
+ " 0.013777 | \n",
+ " -0.256248 | \n",
+ " -0.705186 | \n",
+ " 0.012378 | \n",
+ " -0.531591 | \n",
+ " -0.260890 | \n",
+ " -0.398332 | \n",
+ " 0.078616 | \n",
+ " -0.176480 | \n",
+ " 1.00 | \n",
+ "
\n",
+ " \n",
+ " | 12838 | \n",
+ " 0.092413 | \n",
+ " 0.707487 | \n",
+ " 1.468534 | \n",
+ " 0.835819 | \n",
+ " 0.077369 | \n",
+ " 0.319184 | \n",
+ " -0.309622 | \n",
+ " -0.926561 | \n",
+ " 1.308510 | \n",
+ " -0.798995 | \n",
+ " -0.374541 | \n",
+ " -1.944870 | \n",
+ " 2.612574 | \n",
+ " 1.113404 | \n",
+ " -0.813064 | \n",
+ " -0.454353 | \n",
+ " 0.802003 | \n",
+ " -0.030830 | \n",
+ " 0.925470 | \n",
+ " -0.062606 | \n",
+ " 0.440212 | \n",
+ " -0.720211 | \n",
+ " -0.648152 | \n",
+ " -0.415473 | \n",
+ " 1.544434 | \n",
+ " 0.696797 | \n",
+ " 0.053918 | \n",
+ " 0.133374 | \n",
+ " 10.00 | \n",
+ "
\n",
+ " \n",
+ " | 12839 | \n",
+ " 1.105940 | \n",
+ " -0.093522 | \n",
+ " 0.775855 | \n",
+ " 0.797238 | \n",
+ " -0.601505 | \n",
+ " -0.372565 | \n",
+ " -0.332458 | \n",
+ " -0.138450 | \n",
+ " 1.685372 | \n",
+ " -0.491947 | \n",
+ " 0.192390 | \n",
+ " -2.428955 | \n",
+ " 1.946760 | \n",
+ " 1.473073 | \n",
+ " 0.616349 | \n",
+ " 0.699512 | \n",
+ " 0.009298 | \n",
+ " 0.317635 | \n",
+ " -0.366135 | \n",
+ " 0.052355 | \n",
+ " -0.220249 | \n",
+ " -0.562235 | \n",
+ " -0.029329 | \n",
+ " -0.164029 | \n",
+ " 0.174923 | \n",
+ " 0.197386 | \n",
+ " -0.048843 | \n",
+ " 0.029153 | \n",
+ " 87.00 | \n",
+ "
\n",
+ " \n",
+ " | 12840 | \n",
+ " 1.169834 | \n",
+ " 0.017381 | \n",
+ " 0.836739 | \n",
+ " 1.035206 | \n",
+ " -0.671919 | \n",
+ " -0.362198 | \n",
+ " -0.373648 | \n",
+ " -0.005412 | \n",
+ " 1.745210 | \n",
+ " -0.393025 | \n",
+ " 1.911392 | \n",
+ " -1.687593 | \n",
+ " 0.686310 | \n",
+ " 1.605153 | \n",
+ " -1.768634 | \n",
+ " -0.221949 | \n",
+ " 0.689228 | \n",
+ " 0.232808 | \n",
+ " 0.201811 | \n",
+ " -0.210741 | \n",
+ " -0.182634 | \n",
+ " -0.105628 | \n",
+ " -0.054807 | \n",
+ " 0.527694 | \n",
+ " 0.479663 | \n",
+ " 0.371689 | \n",
+ " -0.051277 | \n",
+ " -0.005160 | \n",
+ " 6.99 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
12841 rows × 29 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " V1 V2 V3 ... V27 V28 Amount\n",
+ "0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62\n",
+ "1 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69\n",
+ "2 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66\n",
+ "3 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50\n",
+ "4 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99\n",
+ "... ... ... ... ... ... ... ...\n",
+ "12836 1.216532 -0.314522 1.134570 ... -0.067625 0.007633 23.27\n",
+ "12837 -1.730579 2.510772 -3.816998 ... 0.078616 -0.176480 1.00\n",
+ "12838 0.092413 0.707487 1.468534 ... 0.053918 0.133374 10.00\n",
+ "12839 1.105940 -0.093522 0.775855 ... -0.048843 0.029153 87.00\n",
+ "12840 1.169834 0.017381 0.836739 ... -0.051277 -0.005160 6.99\n",
+ "\n",
+ "[12841 rows x 29 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 72
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4kZIJ9iN7OTJ",
+ "outputId": "9f2ebae9-940c-4619-91bd-9f68f324afe2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 544
+ }
+ },
+ "source": [
+ "l_preditoras = df_cc2.iloc[:,1:30].columns\n",
+ "l_preditoras2 = list(df_cc2.columns)\n",
+ "l_preditoras2"
+ ],
+ "execution_count": 73,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "['Time',\n",
+ " 'V1',\n",
+ " 'V2',\n",
+ " 'V3',\n",
+ " 'V4',\n",
+ " 'V5',\n",
+ " 'V6',\n",
+ " 'V7',\n",
+ " 'V8',\n",
+ " 'V9',\n",
+ " 'V10',\n",
+ " 'V11',\n",
+ " 'V12',\n",
+ " 'V13',\n",
+ " 'V14',\n",
+ " 'V15',\n",
+ " 'V16',\n",
+ " 'V17',\n",
+ " 'V18',\n",
+ " 'V19',\n",
+ " 'V20',\n",
+ " 'V21',\n",
+ " 'V22',\n",
+ " 'V23',\n",
+ " 'V24',\n",
+ " 'V25',\n",
+ " 'V26',\n",
+ " 'V27',\n",
+ " 'V28',\n",
+ " 'Amount',\n",
+ " 'Class']"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 73
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Sg9IN-m27kbY",
+ "outputId": "e61bea7a-70c0-4bd8-db4b-2d562e497a87",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 163
+ }
+ },
+ "source": [
+ "l_preditoras2.remove['Class']"
+ ],
+ "execution_count": 76,
+ "outputs": [
+ {
+ "output_type": "error",
+ "ename": "TypeError",
+ "evalue": "ignored",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\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[0ml_preditoras2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Class'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m: 'builtin_function_or_method' object is not subscriptable"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ttD6UhA27YNB"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "OY-DYRKg34ZX"
+ },
+ "source": [
+ "### Definir as variáveis globais"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KVhHgV_s3_5f"
+ },
+ "source": [
+ "i_CV = 10 # Número de Cross-Validations\n",
+ "i_Seed = 20111974 # semente por questões de reproducibilidade\n",
+ "f_Test_Size = 0.3 # Proporção do dataframe de validação (outros valores poderiam ser 0.15, 0.20 ou 0.25)"
+ ],
+ "execution_count": 74,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wKbqrF4Q2nBq"
+ },
+ "source": [
+ "### Define amostras de treinamento e teste"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "N8CUAiA57OhS",
+ "outputId": "12824dd9-f1d6-4627-e602-d438047196d1",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 224
+ }
+ },
+ "source": [
+ "df_cc.head()"
+ ],
+ "execution_count": 75,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Time | \n",
+ " V1 | \n",
+ " V2 | \n",
+ " V3 | \n",
+ " V4 | \n",
+ " V5 | \n",
+ " V6 | \n",
+ " V7 | \n",
+ " V8 | \n",
+ " V9 | \n",
+ " V10 | \n",
+ " V11 | \n",
+ " V12 | \n",
+ " V13 | \n",
+ " V14 | \n",
+ " V15 | \n",
+ " V16 | \n",
+ " V17 | \n",
+ " V18 | \n",
+ " V19 | \n",
+ " V20 | \n",
+ " V21 | \n",
+ " V22 | \n",
+ " V23 | \n",
+ " V24 | \n",
+ " V25 | \n",
+ " V26 | \n",
+ " V27 | \n",
+ " V28 | \n",
+ " Amount | \n",
+ " Class | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0 | \n",
+ " -1.359807 | \n",
+ " -0.072781 | \n",
+ " 2.536347 | \n",
+ " 1.378155 | \n",
+ " -0.338321 | \n",
+ " 0.462388 | \n",
+ " 0.239599 | \n",
+ " 0.098698 | \n",
+ " 0.363787 | \n",
+ " 0.090794 | \n",
+ " -0.551600 | \n",
+ " -0.617801 | \n",
+ " -0.991390 | \n",
+ " -0.311169 | \n",
+ " 1.468177 | \n",
+ " -0.470401 | \n",
+ " 0.207971 | \n",
+ " 0.025791 | \n",
+ " 0.403993 | \n",
+ " 0.251412 | \n",
+ " -0.018307 | \n",
+ " 0.277838 | \n",
+ " -0.110474 | \n",
+ " 0.066928 | \n",
+ " 0.128539 | \n",
+ " -0.189115 | \n",
+ " 0.133558 | \n",
+ " -0.021053 | \n",
+ " 149.62 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0 | \n",
+ " 1.191857 | \n",
+ " 0.266151 | \n",
+ " 0.166480 | \n",
+ " 0.448154 | \n",
+ " 0.060018 | \n",
+ " -0.082361 | \n",
+ " -0.078803 | \n",
+ " 0.085102 | \n",
+ " -0.255425 | \n",
+ " -0.166974 | \n",
+ " 1.612727 | \n",
+ " 1.065235 | \n",
+ " 0.489095 | \n",
+ " -0.143772 | \n",
+ " 0.635558 | \n",
+ " 0.463917 | \n",
+ " -0.114805 | \n",
+ " -0.183361 | \n",
+ " -0.145783 | \n",
+ " -0.069083 | \n",
+ " -0.225775 | \n",
+ " -0.638672 | \n",
+ " 0.101288 | \n",
+ " -0.339846 | \n",
+ " 0.167170 | \n",
+ " 0.125895 | \n",
+ " -0.008983 | \n",
+ " 0.014724 | \n",
+ " 2.69 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1 | \n",
+ " -1.358354 | \n",
+ " -1.340163 | \n",
+ " 1.773209 | \n",
+ " 0.379780 | \n",
+ " -0.503198 | \n",
+ " 1.800499 | \n",
+ " 0.791461 | \n",
+ " 0.247676 | \n",
+ " -1.514654 | \n",
+ " 0.207643 | \n",
+ " 0.624501 | \n",
+ " 0.066084 | \n",
+ " 0.717293 | \n",
+ " -0.165946 | \n",
+ " 2.345865 | \n",
+ " -2.890083 | \n",
+ " 1.109969 | \n",
+ " -0.121359 | \n",
+ " -2.261857 | \n",
+ " 0.524980 | \n",
+ " 0.247998 | \n",
+ " 0.771679 | \n",
+ " 0.909412 | \n",
+ " -0.689281 | \n",
+ " -0.327642 | \n",
+ " -0.139097 | \n",
+ " -0.055353 | \n",
+ " -0.059752 | \n",
+ " 378.66 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " -0.966272 | \n",
+ " -0.185226 | \n",
+ " 1.792993 | \n",
+ " -0.863291 | \n",
+ " -0.010309 | \n",
+ " 1.247203 | \n",
+ " 0.237609 | \n",
+ " 0.377436 | \n",
+ " -1.387024 | \n",
+ " -0.054952 | \n",
+ " -0.226487 | \n",
+ " 0.178228 | \n",
+ " 0.507757 | \n",
+ " -0.287924 | \n",
+ " -0.631418 | \n",
+ " -1.059647 | \n",
+ " -0.684093 | \n",
+ " 1.965775 | \n",
+ " -1.232622 | \n",
+ " -0.208038 | \n",
+ " -0.108300 | \n",
+ " 0.005274 | \n",
+ " -0.190321 | \n",
+ " -1.175575 | \n",
+ " 0.647376 | \n",
+ " -0.221929 | \n",
+ " 0.062723 | \n",
+ " 0.061458 | \n",
+ " 123.50 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2 | \n",
+ " -1.158233 | \n",
+ " 0.877737 | \n",
+ " 1.548718 | \n",
+ " 0.403034 | \n",
+ " -0.407193 | \n",
+ " 0.095921 | \n",
+ " 0.592941 | \n",
+ " -0.270533 | \n",
+ " 0.817739 | \n",
+ " 0.753074 | \n",
+ " -0.822843 | \n",
+ " 0.538196 | \n",
+ " 1.345852 | \n",
+ " -1.119670 | \n",
+ " 0.175121 | \n",
+ " -0.451449 | \n",
+ " -0.237033 | \n",
+ " -0.038195 | \n",
+ " 0.803487 | \n",
+ " 0.408542 | \n",
+ " -0.009431 | \n",
+ " 0.798278 | \n",
+ " -0.137458 | \n",
+ " 0.141267 | \n",
+ " -0.206010 | \n",
+ " 0.502292 | \n",
+ " 0.219422 | \n",
+ " 0.215153 | \n",
+ " 69.99 | \n",
+ " 0.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Time V1 V2 V3 ... V27 V28 Amount Class\n",
+ "0 0 -1.359807 -0.072781 2.536347 ... 0.133558 -0.021053 149.62 0.0\n",
+ "1 0 1.191857 0.266151 0.166480 ... -0.008983 0.014724 2.69 0.0\n",
+ "2 1 -1.358354 -1.340163 1.773209 ... -0.055353 -0.059752 378.66 0.0\n",
+ "3 1 -0.966272 -0.185226 1.792993 ... 0.062723 0.061458 123.50 0.0\n",
+ "4 2 -1.158233 0.877737 1.548718 ... 0.219422 0.215153 69.99 0.0\n",
+ "\n",
+ "[5 rows x 31 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 75
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LZjNUDNb7s1t",
+ "outputId": "ede96084-76d8-47e0-e88e-8a2827ecd2e2",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 224
+ }
+ },
+ "source": [
+ "# Definição do dataframe contendo as variáveis preditoras:\n",
+ "df_X = df_cc2.copy()\n",
+ "df_X.drop(columns= ['Class'], axis = 1, inplace = True)\n",
+ "df_X.head()"
+ ],
+ "execution_count": 77,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Time | \n",
+ " V1 | \n",
+ " V2 | \n",
+ " V3 | \n",
+ " V4 | \n",
+ " V5 | \n",
+ " V6 | \n",
+ " V7 | \n",
+ " V8 | \n",
+ " V9 | \n",
+ " V10 | \n",
+ " V11 | \n",
+ " V12 | \n",
+ " V13 | \n",
+ " V14 | \n",
+ " V15 | \n",
+ " V16 | \n",
+ " V17 | \n",
+ " V18 | \n",
+ " V19 | \n",
+ " V20 | \n",
+ " V21 | \n",
+ " V22 | \n",
+ " V23 | \n",
+ " V24 | \n",
+ " V25 | \n",
+ " V26 | \n",
+ " V27 | \n",
+ " V28 | \n",
+ " Amount | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0 | \n",
+ " -1.359807 | \n",
+ " -0.072781 | \n",
+ " 2.536347 | \n",
+ " 1.378155 | \n",
+ " -0.338321 | \n",
+ " 0.462388 | \n",
+ " 0.239599 | \n",
+ " 0.098698 | \n",
+ " 0.363787 | \n",
+ " 0.090794 | \n",
+ " -0.551600 | \n",
+ " -0.617801 | \n",
+ " -0.991390 | \n",
+ " -0.311169 | \n",
+ " 1.468177 | \n",
+ " -0.470401 | \n",
+ " 0.207971 | \n",
+ " 0.025791 | \n",
+ " 0.403993 | \n",
+ " 0.251412 | \n",
+ " -0.018307 | \n",
+ " 0.277838 | \n",
+ " -0.110474 | \n",
+ " 0.066928 | \n",
+ " 0.128539 | \n",
+ " -0.189115 | \n",
+ " 0.133558 | \n",
+ " -0.021053 | \n",
+ " 149.62 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0 | \n",
+ " 1.191857 | \n",
+ " 0.266151 | \n",
+ " 0.166480 | \n",
+ " 0.448154 | \n",
+ " 0.060018 | \n",
+ " -0.082361 | \n",
+ " -0.078803 | \n",
+ " 0.085102 | \n",
+ " -0.255425 | \n",
+ " -0.166974 | \n",
+ " 1.612727 | \n",
+ " 1.065235 | \n",
+ " 0.489095 | \n",
+ " -0.143772 | \n",
+ " 0.635558 | \n",
+ " 0.463917 | \n",
+ " -0.114805 | \n",
+ " -0.183361 | \n",
+ " -0.145783 | \n",
+ " -0.069083 | \n",
+ " -0.225775 | \n",
+ " -0.638672 | \n",
+ " 0.101288 | \n",
+ " -0.339846 | \n",
+ " 0.167170 | \n",
+ " 0.125895 | \n",
+ " -0.008983 | \n",
+ " 0.014724 | \n",
+ " 2.69 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1 | \n",
+ " -1.358354 | \n",
+ " -1.340163 | \n",
+ " 1.773209 | \n",
+ " 0.379780 | \n",
+ " -0.503198 | \n",
+ " 1.800499 | \n",
+ " 0.791461 | \n",
+ " 0.247676 | \n",
+ " -1.514654 | \n",
+ " 0.207643 | \n",
+ " 0.624501 | \n",
+ " 0.066084 | \n",
+ " 0.717293 | \n",
+ " -0.165946 | \n",
+ " 2.345865 | \n",
+ " -2.890083 | \n",
+ " 1.109969 | \n",
+ " -0.121359 | \n",
+ " -2.261857 | \n",
+ " 0.524980 | \n",
+ " 0.247998 | \n",
+ " 0.771679 | \n",
+ " 0.909412 | \n",
+ " -0.689281 | \n",
+ " -0.327642 | \n",
+ " -0.139097 | \n",
+ " -0.055353 | \n",
+ " -0.059752 | \n",
+ " 378.66 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " -0.966272 | \n",
+ " -0.185226 | \n",
+ " 1.792993 | \n",
+ " -0.863291 | \n",
+ " -0.010309 | \n",
+ " 1.247203 | \n",
+ " 0.237609 | \n",
+ " 0.377436 | \n",
+ " -1.387024 | \n",
+ " -0.054952 | \n",
+ " -0.226487 | \n",
+ " 0.178228 | \n",
+ " 0.507757 | \n",
+ " -0.287924 | \n",
+ " -0.631418 | \n",
+ " -1.059647 | \n",
+ " -0.684093 | \n",
+ " 1.965775 | \n",
+ " -1.232622 | \n",
+ " -0.208038 | \n",
+ " -0.108300 | \n",
+ " 0.005274 | \n",
+ " -0.190321 | \n",
+ " -1.175575 | \n",
+ " 0.647376 | \n",
+ " -0.221929 | \n",
+ " 0.062723 | \n",
+ " 0.061458 | \n",
+ " 123.50 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2 | \n",
+ " -1.158233 | \n",
+ " 0.877737 | \n",
+ " 1.548718 | \n",
+ " 0.403034 | \n",
+ " -0.407193 | \n",
+ " 0.095921 | \n",
+ " 0.592941 | \n",
+ " -0.270533 | \n",
+ " 0.817739 | \n",
+ " 0.753074 | \n",
+ " -0.822843 | \n",
+ " 0.538196 | \n",
+ " 1.345852 | \n",
+ " -1.119670 | \n",
+ " 0.175121 | \n",
+ " -0.451449 | \n",
+ " -0.237033 | \n",
+ " -0.038195 | \n",
+ " 0.803487 | \n",
+ " 0.408542 | \n",
+ " -0.009431 | \n",
+ " 0.798278 | \n",
+ " -0.137458 | \n",
+ " 0.141267 | \n",
+ " -0.206010 | \n",
+ " 0.502292 | \n",
+ " 0.219422 | \n",
+ " 0.215153 | \n",
+ " 69.99 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Time V1 V2 V3 ... V26 V27 V28 Amount\n",
+ "0 0 -1.359807 -0.072781 2.536347 ... -0.189115 0.133558 -0.021053 149.62\n",
+ "1 0 1.191857 0.266151 0.166480 ... 0.125895 -0.008983 0.014724 2.69\n",
+ "2 1 -1.358354 -1.340163 1.773209 ... -0.139097 -0.055353 -0.059752 378.66\n",
+ "3 1 -0.966272 -0.185226 1.792993 ... -0.221929 0.062723 0.061458 123.50\n",
+ "4 2 -1.158233 0.877737 1.548718 ... 0.502292 0.219422 0.215153 69.99\n",
+ "\n",
+ "[5 rows x 30 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 77
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "d3DDsN2V7IOU",
+ "outputId": "1b7041e4-631a-47db-bbe3-27d6df2d923d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "df_y = df_cc2['Class'] # Variável-resposta\n",
+ "df_y.head()"
+ ],
+ "execution_count": 78,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0 0.0\n",
+ "1 0.0\n",
+ "2 0.0\n",
+ "3 0.0\n",
+ "4 0.0\n",
+ "Name: Class, dtype: float64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 78
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aMthdXHD8vnh",
+ "outputId": "df66e9bc-b2b8-4902-ad05-defb09aad589",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "df_y.shape"
+ ],
+ "execution_count": 79,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(12841,)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 79
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EiJRftpZ2103"
+ },
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "\n",
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(df_X, df_y, test_size = f_Test_Size, random_state = i_Seed)"
+ ],
+ "execution_count": 80,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TmSkPzNt8O6I",
+ "outputId": "c9da0fd9-379e-4550-e983-83f8a09e8722",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "X_treinamento.shape"
+ ],
+ "execution_count": 81,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(8988, 30)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 81
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9h1PjPKh8Xb1",
+ "outputId": "5a1e7d6b-c646-43d7-d52a-0372e3292085",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "X_teste.shape\n"
+ ],
+ "execution_count": 82,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(3853, 30)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 82
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "b1w3NuJ5-mKK",
+ "outputId": "1836686d-230c-46f8-93e8-e0d79e667eef",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 221
+ }
+ },
+ "source": [
+ "y_teste"
+ ],
+ "execution_count": 95,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "1224 0.0\n",
+ "11994 0.0\n",
+ "5408 0.0\n",
+ "4385 0.0\n",
+ "8164 0.0\n",
+ " ... \n",
+ "2944 0.0\n",
+ "10949 0.0\n",
+ "12248 0.0\n",
+ "7380 0.0\n",
+ "12327 0.0\n",
+ "Name: Class, Length: 3853, dtype: float64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 95
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NbCN_puI2qk1"
+ },
+ "source": [
+ "### Ajusta o modelo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hjRwSI079ADn"
+ },
+ "source": [
+ "# Importar o classificador (modelo, algoritmo, ...)\n",
+ "from sklearn.tree import DecisionTreeClassifier # Este é o nosso classificador"
+ ],
+ "execution_count": 83,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "HuhKJOQA22bR",
+ "outputId": "b4c73a73-3d0c-4f75-abb5-5f3c8d66a38a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "ml_DT = DecisionTreeClassifier(max_depth = 5, min_samples_split = 2, random_state = i_Seed)\n",
+ "ml_DT"
+ ],
+ "execution_count": 84,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n",
+ " max_depth=5, max_features=None, max_leaf_nodes=None,\n",
+ " min_impurity_decrease=0.0, min_impurity_split=None,\n",
+ " min_samples_leaf=1, min_samples_split=2,\n",
+ " min_weight_fraction_leaf=0.0, presort='deprecated',\n",
+ " random_state=20111974, splitter='best')"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 84
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Zai1d6eM93VQ",
+ "outputId": "cfe02da8-397a-4a0f-8fe5-424dbcdf0282",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "# Treinar o algoritmo/classificador: fit(df)\n",
+ "ml_DT.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 85,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',\n",
+ " max_depth=5, max_features=None, max_leaf_nodes=None,\n",
+ " min_impurity_decrease=0.0, min_impurity_split=None,\n",
+ " min_samples_leaf=1, min_samples_split=2,\n",
+ " min_weight_fraction_leaf=0.0, presort='deprecated',\n",
+ " random_state=20111974, splitter='best')"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 85
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ybbS4zHn-8BO",
+ "outputId": "6a1206b9-1afe-4336-eb6f-08b492b0a7e4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": 86,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média das Acurácias calculadas pelo CV....: 99.9\n",
+ "std médio das Acurácias calculadas pelo CV: 0.09\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r_NLku7q_YT9",
+ "outputId": "bbdf1793-9a9a-47f2-94d9-165fc383f5aa",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": 87,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1. , 0.99888765, 0.99777531, 0.99777531, 1. ,\n",
+ " 0.99888765, 1. , 0.99888765, 0.99777283, 1. ])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 87
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bCRgHxUu2s7c"
+ },
+ "source": [
+ "### Cross-Validation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2wMWm-p5229A",
+ "outputId": "290582fe-a2e4-4bb8-fed1-7638a8442c0d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# Cross-Validation com 10 folds\n",
+ "a_scores_CV = cross_val_score(ml_DT, X_treinamento, y_treinamento, cv = i_CV)\n",
+ "\n",
+ "print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(), 4)}')\n",
+ "print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(), 4)}')"
+ ],
+ "execution_count": 88,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Média das Acurácias calculadas pelo CV....: 99.9\n",
+ "std médio das Acurácias calculadas pelo CV: 0.09\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m0Jbi5XQ8OZb",
+ "outputId": "ea01e17d-c5b9-4f7f-ce3f-55f317c1aaf5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "a_scores_CV # array com os scores a cada iteração do CV"
+ ],
+ "execution_count": 89,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1. , 0.99888765, 0.99777531, 0.99777531, 1. ,\n",
+ " 0.99888765, 1. , 0.99888765, 0.99777283, 1. ])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 89
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g83qQ9RW-Lox",
+ "outputId": "e86d65f5-47cd-4faa-befc-feab86b05378",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "y_pred = ml_DT.predict(X_teste)\n",
+ "y_pred[0:30]"
+ ],
+ "execution_count": 98,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+ " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 98
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CPGhZKJf84F5",
+ "outputId": "dbf436ce-12b0-497b-a3d8-053e044dd023",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 572
+ }
+ },
+ "source": [
+ "#Matriz de confusão xxxxxxx\n",
+ "# Matriz de Confusão\n",
+ "print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n",
+ "cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ "cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n",
+ "cf_categories = ['Zero', 'One']\n",
+ "mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n",
+ "\n",
+ "#return ml_Opt, ml_GridSearchCV.best_params_"
+ ],
+ "execution_count": 99,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OFnXPNxQ-JHh"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_Uez8lk09lV6"
+ },
+ "source": [
+ "# Invoca a função com o modelo baseline\n",
+ "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Am_UELOg2vDh"
+ },
+ "source": [
+ "### Fine tuning dos parâmetros"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "lF9mxe7y23hr"
+ },
+ "source": [
+ "from sklearn.tree import DecisionTreeClassifier # Library para Decision Tree (Classificação)\n",
+ "\n",
+ "# Instancia (configuração do Decision Trees) com os parâmetros sugeridos para se evitar overfitting:\n",
+ "ml_DT = DecisionTreeClassifier(criterion = 'gini', \n",
+ " splitter = 'best', \n",
+ " max_depth = None, \n",
+ " min_samples_split = 2, \n",
+ " min_samples_leaf = 1, \n",
+ " min_weight_fraction_leaf = 0.0, \n",
+ " max_features = None, \n",
+ " random_state = i_Seed, \n",
+ " max_leaf_nodes = None, \n",
+ " min_impurity_decrease = 0.0, \n",
+ " min_impurity_split = None, \n",
+ " class_weight = None, \n",
+ " presort = False)"
+ ],
+ "execution_count": 100,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8nDOkHnf_AsB",
+ "outputId": "aeceed17-6365-428f-e88a-67c59bba857a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 119
+ }
+ },
+ "source": [
+ "# Treina o algoritmo: fit(df)\n",
+ "ml_DT.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 101,
+ "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": 101
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ftIRtZph_f3R"
+ },
+ "source": [
+ "# Dicionário de parâmetros para o parameter tunning. Ao todo serão ajustados 2X13X5X5X7= 4.550 modelos. Contando com 10 folds no Cross-Validation, então são 45.500 modelos.\n",
+ "d_parametros_DT = {\"criterion\": [\"gini\", \"entropy\"], \n",
+ " \"min_samples_split\": [2, 5, 10, 30, 50], \n",
+ " \"max_depth\": [None, 2, 5, 9, 15], \n",
+ " \"min_samples_leaf\": [20, 40, 60, 80, 100], \n",
+ " \"max_leaf_nodes\": [None, 2, 3, 4, 5, 10]}\n"
+ ],
+ "execution_count": 105,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Fkn7vDRe_igh"
+ },
+ "source": [
+ "# Definindo a função para o GridSearchCV\n",
+ "def GridSearchOptimizer(modelo, ml_Opt, d_Parametros, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV):\n",
+ " ml_GridSearchCV = GridSearchCV(modelo, d_Parametros, cv = i_CV, n_jobs= -1, verbose= 10, scoring= 'accuracy')\n",
+ " start = time()\n",
+ " ml_GridSearchCV.fit(X_treinamento, y_treinamento)\n",
+ " tempo_elapsed= time()-start\n",
+ " #print(f\"\\nGridSearchCV levou {tempo_elapsed:.2f} segundos.\")\n",
+ "\n",
+ " # Parâmetros que otimizam a classificação:\n",
+ " print(f'\\nParametros otimizados: {ml_GridSearchCV.best_params_}')\n",
+ " \n",
+ " if ml_Opt == 'ml_DT2':\n",
+ " print(f'\\nDecisionTreeClassifier *********************************************************************************************************')\n",
+ " ml_Opt = DecisionTreeClassifier(criterion= ml_GridSearchCV.best_params_['criterion'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n",
+ " max_leaf_nodes= ml_GridSearchCV.best_params_['max_leaf_nodes'],\n",
+ " min_samples_split= ml_GridSearchCV.best_params_['min_samples_leaf'],\n",
+ " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_split'], \n",
+ " random_state= i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_RF2':\n",
+ " print(f'\\nRandomForestClassifier *********************************************************************************************************')\n",
+ " ml_Opt = RandomForestClassifier(bootstrap= ml_GridSearchCV.best_params_['bootstrap'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'],\n",
+ " max_features= ml_GridSearchCV.best_params_['max_features'],\n",
+ " min_samples_leaf= ml_GridSearchCV.best_params_['min_samples_leaf'],\n",
+ " min_samples_split= ml_GridSearchCV.best_params_['min_samples_split'],\n",
+ " n_estimators= ml_GridSearchCV.best_params_['n_estimators'],\n",
+ " random_state= i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_AB2':\n",
+ " print(f'\\nAdaBoostClassifier *********************************************************************************************************')\n",
+ " ml_Opt = AdaBoostClassifier(algorithm='SAMME.R', \n",
+ " base_estimator=RandomForestClassifier(bootstrap = False, \n",
+ " max_depth = 10, \n",
+ " max_features = 'auto', \n",
+ " min_samples_leaf = 1, \n",
+ " min_samples_split = 2, \n",
+ " n_estimators = 400), \n",
+ " learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n",
+ " random_state = i_Seed)\n",
+ " \n",
+ " elif ml_Opt == 'ml_GB2':\n",
+ " print(f'\\nGradientBoostingClassifier *********************************************************************************************************')\n",
+ " ml_Opt = GradientBoostingClassifier(learning_rate = ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " n_estimators = ml_GridSearchCV.best_params_['n_estimators'], \n",
+ " max_depth = ml_GridSearchCV.best_params_['max_depth'], \n",
+ " min_samples_split = ml_GridSearchCV.best_params_['min_samples_split'], \n",
+ " min_samples_leaf = ml_GridSearchCV.best_params_['min_samples_leaf'], \n",
+ " max_features = ml_GridSearchCV.best_params_['max_features'])\n",
+ " \n",
+ " elif ml_Opt == 'ml_XGB2':\n",
+ " print(f'\\nXGBoostingClassifier *********************************************************************************************************')\n",
+ " ml_Opt = XGBoostingClassifier(learning_rate= ml_GridSearchCV.best_params_['learning_rate'], \n",
+ " max_depth= ml_GridSearchCV.best_params_['max_depth'], \n",
+ " colsample_bytree= ml_GridSearchCV.best_params_['colsample_bytree'], \n",
+ " subsample= ml_GridSearchCV.best_params_['subsample'], \n",
+ " gamma= ml_GridSearchCV.best_params_['gamma'], \n",
+ " min_child_weight= ml_GridSearchCV.best_params_['min_child_weight'])\n",
+ " \n",
+ " # Treina novamente usando os parametros otimizados...\n",
+ " ml_Opt.fit(X_treinamento, y_treinamento)\n",
+ "\n",
+ " # Cross-Validation com 10 folds\n",
+ " print(f'\\n********* CROSS-VALIDATION ***********')\n",
+ " a_scores_CV = cross_val_score(ml_Opt, X_treinamento, y_treinamento, cv = i_CV)\n",
+ " print(f'Média das Acurácias calculadas pelo CV....: {100*round(a_scores_CV.mean(),4)}')\n",
+ " print(f'std médio das Acurácias calculadas pelo CV: {100*round(a_scores_CV.std(),4)}')\n",
+ "\n",
+ " # Faz predições com os parametros otimizados...\n",
+ " y_pred = ml_Opt.predict(X_teste)\n",
+ " \n",
+ " # Importância das COLUNAS\n",
+ " print(f'\\n********* IMPORTÂNCIA DAS COLUNAS ***********')\n",
+ " df_importancia_variaveis = pd.DataFrame(zip(l_colunas, ml_Opt.feature_importances_), columns= ['coluna', 'importancia'])\n",
+ " df_importancia_variaveis = df_importancia_variaveis.sort_values(by= ['importancia'], ascending=False)\n",
+ " print(df_importancia_variaveis)\n",
+ "\n",
+ " # Matriz de Confusão\n",
+ " print(f'\\n********* CONFUSION MATRIX - PARAMETER TUNNING ***********')\n",
+ " cf_matrix = confusion_matrix(y_teste, y_pred)\n",
+ " cf_labels = ['True_Negative', 'False_Positive', 'False_Negative', 'True_Positive']\n",
+ " cf_categories = ['Zero', 'One']\n",
+ " mostra_confusion_matrix(cf_matrix, group_names = cf_labels, categories = cf_categories)\n",
+ "\n",
+ " return ml_Opt, ml_GridSearchCV.best_params_\n",
+ "\n"
+ ],
+ "execution_count": 106,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IOp0SmbC_l7h",
+ "outputId": "d9cf147e-a5d9-451d-98c2-563fa129e11c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "# Invoca a função com o modelo baseline\n",
+ "ml_DT2, best_params = GridSearchOptimizer(ml_DT, 'ml_DT2', d_parametros_DT, X_treinamento, y_treinamento, X_teste, y_teste, cv = i_CV)\n"
+ ],
+ "execution_count": 107,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Fitting 10 folds for each of 1500 candidates, totalling 15000 fits\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.\n",
+ "[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 1.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 4 tasks | elapsed: 1.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 9 tasks | elapsed: 2.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 14 tasks | elapsed: 2.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 21 tasks | elapsed: 3.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 28 tasks | elapsed: 4.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 37 tasks | elapsed: 5.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 46 tasks | elapsed: 6.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 57 tasks | elapsed: 7.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 68 tasks | elapsed: 8.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 81 tasks | elapsed: 10.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 94 tasks | elapsed: 11.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 109 tasks | elapsed: 12.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 124 tasks | elapsed: 14.3s\n",
+ "[Parallel(n_jobs=-1)]: Done 141 tasks | elapsed: 15.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 158 tasks | elapsed: 17.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 177 tasks | elapsed: 19.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 196 tasks | elapsed: 21.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 217 tasks | elapsed: 23.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 238 tasks | elapsed: 25.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 261 tasks | elapsed: 26.8s\n",
+ "[Parallel(n_jobs=-1)]: Done 284 tasks | elapsed: 28.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 309 tasks | elapsed: 29.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 334 tasks | elapsed: 31.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 361 tasks | elapsed: 32.5s\n",
+ "[Parallel(n_jobs=-1)]: Done 388 tasks | elapsed: 34.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 417 tasks | elapsed: 35.7s\n",
+ "[Parallel(n_jobs=-1)]: Done 446 tasks | elapsed: 37.2s\n",
+ "[Parallel(n_jobs=-1)]: Done 477 tasks | elapsed: 39.0s\n",
+ "[Parallel(n_jobs=-1)]: Done 508 tasks | elapsed: 40.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 541 tasks | elapsed: 43.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 574 tasks | elapsed: 46.1s\n",
+ "[Parallel(n_jobs=-1)]: Done 609 tasks | elapsed: 48.9s\n",
+ "[Parallel(n_jobs=-1)]: Done 644 tasks | elapsed: 51.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 681 tasks | elapsed: 54.6s\n",
+ "[Parallel(n_jobs=-1)]: Done 718 tasks | elapsed: 57.4s\n",
+ "[Parallel(n_jobs=-1)]: Done 757 tasks | elapsed: 1.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 796 tasks | elapsed: 1.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 837 tasks | elapsed: 1.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 878 tasks | elapsed: 1.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 921 tasks | elapsed: 1.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 964 tasks | elapsed: 1.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 1009 tasks | elapsed: 1.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 1054 tasks | elapsed: 1.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 1101 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 1148 tasks | elapsed: 1.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 1197 tasks | elapsed: 1.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 1246 tasks | elapsed: 1.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 1297 tasks | elapsed: 1.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 1348 tasks | elapsed: 2.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 1401 tasks | elapsed: 2.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 1454 tasks | elapsed: 2.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 1509 tasks | elapsed: 2.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 1564 tasks | elapsed: 2.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 1621 tasks | elapsed: 2.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 1678 tasks | elapsed: 2.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 1737 tasks | elapsed: 2.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 1796 tasks | elapsed: 2.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 1857 tasks | elapsed: 2.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 1918 tasks | elapsed: 2.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 1981 tasks | elapsed: 2.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 2044 tasks | elapsed: 2.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 2109 tasks | elapsed: 2.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 2174 tasks | elapsed: 2.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 2241 tasks | elapsed: 2.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 2308 tasks | elapsed: 3.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 2377 tasks | elapsed: 3.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 2446 tasks | elapsed: 3.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 2517 tasks | elapsed: 3.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 2588 tasks | elapsed: 3.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 2661 tasks | elapsed: 3.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 2734 tasks | elapsed: 3.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 2809 tasks | elapsed: 3.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 2884 tasks | elapsed: 3.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 2961 tasks | elapsed: 3.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 3038 tasks | elapsed: 3.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 3117 tasks | elapsed: 3.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 3196 tasks | elapsed: 3.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 3277 tasks | elapsed: 4.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 3358 tasks | elapsed: 4.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 3441 tasks | elapsed: 4.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 3524 tasks | elapsed: 4.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 3609 tasks | elapsed: 4.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 3694 tasks | elapsed: 4.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 3781 tasks | elapsed: 4.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 3868 tasks | elapsed: 4.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 3957 tasks | elapsed: 4.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 4046 tasks | elapsed: 5.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 4137 tasks | elapsed: 5.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 4228 tasks | elapsed: 5.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 4321 tasks | elapsed: 5.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 4414 tasks | elapsed: 5.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 4509 tasks | elapsed: 5.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 4604 tasks | elapsed: 6.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 4701 tasks | elapsed: 6.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 4798 tasks | elapsed: 6.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 4897 tasks | elapsed: 6.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 4996 tasks | elapsed: 6.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 5097 tasks | elapsed: 6.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 5198 tasks | elapsed: 6.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 5301 tasks | elapsed: 6.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 5404 tasks | elapsed: 7.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 5509 tasks | elapsed: 7.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 5614 tasks | elapsed: 7.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 5721 tasks | elapsed: 7.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 5828 tasks | elapsed: 7.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 5937 tasks | elapsed: 7.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 6046 tasks | elapsed: 8.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 6157 tasks | elapsed: 8.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 6268 tasks | elapsed: 8.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 6381 tasks | elapsed: 8.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 6494 tasks | elapsed: 8.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 6609 tasks | elapsed: 8.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 6724 tasks | elapsed: 8.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 6841 tasks | elapsed: 9.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 6958 tasks | elapsed: 9.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 7077 tasks | elapsed: 9.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 7196 tasks | elapsed: 9.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 7317 tasks | elapsed: 9.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 7438 tasks | elapsed: 10.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 7561 tasks | elapsed: 10.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 7684 tasks | elapsed: 10.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 7809 tasks | elapsed: 10.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 7934 tasks | elapsed: 10.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 8061 tasks | elapsed: 11.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 8188 tasks | elapsed: 11.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 8317 tasks | elapsed: 11.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 8446 tasks | elapsed: 11.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 8577 tasks | elapsed: 11.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 8708 tasks | elapsed: 12.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 8841 tasks | elapsed: 12.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 8974 tasks | elapsed: 12.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 9109 tasks | elapsed: 12.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 9244 tasks | elapsed: 12.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 9381 tasks | elapsed: 13.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 9518 tasks | elapsed: 13.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 9657 tasks | elapsed: 13.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 9796 tasks | elapsed: 13.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 9937 tasks | elapsed: 13.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 10078 tasks | elapsed: 13.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 10221 tasks | elapsed: 14.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 10364 tasks | elapsed: 14.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 10509 tasks | elapsed: 14.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 10654 tasks | elapsed: 14.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 10801 tasks | elapsed: 15.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 10948 tasks | elapsed: 15.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 11097 tasks | elapsed: 15.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 11246 tasks | elapsed: 15.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 11397 tasks | elapsed: 15.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 11548 tasks | elapsed: 16.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 11701 tasks | elapsed: 16.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 11854 tasks | elapsed: 16.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 12009 tasks | elapsed: 16.7min\n",
+ "[Parallel(n_jobs=-1)]: Done 12164 tasks | elapsed: 17.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 12321 tasks | elapsed: 17.2min\n",
+ "[Parallel(n_jobs=-1)]: Done 12478 tasks | elapsed: 17.4min\n",
+ "[Parallel(n_jobs=-1)]: Done 12637 tasks | elapsed: 17.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 12796 tasks | elapsed: 17.9min\n",
+ "[Parallel(n_jobs=-1)]: Done 12957 tasks | elapsed: 18.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 13118 tasks | elapsed: 18.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 13281 tasks | elapsed: 18.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 13444 tasks | elapsed: 18.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 13609 tasks | elapsed: 19.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 13774 tasks | elapsed: 19.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 13941 tasks | elapsed: 19.6min\n",
+ "[Parallel(n_jobs=-1)]: Done 14108 tasks | elapsed: 19.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 14277 tasks | elapsed: 20.0min\n",
+ "[Parallel(n_jobs=-1)]: Done 14446 tasks | elapsed: 20.3min\n",
+ "[Parallel(n_jobs=-1)]: Done 14617 tasks | elapsed: 20.5min\n",
+ "[Parallel(n_jobs=-1)]: Done 14788 tasks | elapsed: 20.8min\n",
+ "[Parallel(n_jobs=-1)]: Done 14961 tasks | elapsed: 21.1min\n",
+ "[Parallel(n_jobs=-1)]: Done 15000 out of 15000 | elapsed: 21.1min finished\n"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Parametros otimizados: {'criterion': 'gini', 'max_depth': None, 'max_leaf_nodes': None, 'min_samples_leaf': 20, 'min_samples_split': 2}\n",
+ "\n",
+ "DecisionTreeClassifier *********************************************************************************************************\n",
+ "\n",
+ "********* CROSS-VALIDATION ***********\n",
+ "Média das Acurácias calculadas pelo CV....: 99.83999999999999\n",
+ "std médio das Acurácias calculadas pelo CV: 0.06999999999999999\n",
+ "\n",
+ "********* IMPORTÂNCIA DAS COLUNAS ***********\n",
+ " coluna importancia\n",
+ "12 v13 0.834026\n",
+ "17 v18 0.110131\n",
+ "4 v5 0.015970\n",
+ "14 v15 0.007955\n",
+ "15 v16 0.000761\n",
+ "10 v11 0.000000\n",
+ "16 v17 0.000000\n",
+ "13 v14 0.000000\n",
+ "11 v12 0.000000\n",
+ "0 v1 0.000000\n",
+ "1 v2 0.000000\n",
+ "8 v9 0.000000\n",
+ "7 v8 0.000000\n",
+ "6 v7 0.000000\n",
+ "5 v6 0.000000\n",
+ "3 v4 0.000000\n",
+ "2 v3 0.000000\n",
+ "9 v10 0.000000\n",
+ "\n",
+ "********* CONFUSION MATRIX - PARAMETER TUNNING ***********\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": [],
+ "needs_background": "light"
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QfordmeT_uxi",
+ "outputId": "4fd2292f-378d-4ee4-9cd5-44f96686e610",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 391
+ }
+ },
+ "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": 110,
+ "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[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mdot_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mStringIO\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;32m----> 7\u001b[0;31m \u001b[0mexport_graphviz\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mml_DT2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdot_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrounded\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mspecial_characters\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeature_names\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ml_colunas\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_names\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'0'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'1'\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 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpydotplus\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph_from_dot_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdot_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetvalue\u001b[0m\u001b[0;34m(\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;32m/usr/local/lib/python3.6/dist-packages/sklearn/tree/_export.py\u001b[0m in \u001b[0;36mexport_graphviz\u001b[0;34m(decision_tree, out_file, max_depth, feature_names, class_names, label, filled, leaves_parallel, impurity, node_ids, proportion, rotate, rounded, special_characters, precision)\u001b[0m\n\u001b[1;32m 762\u001b[0m \u001b[0mrounded\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrounded\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mspecial_characters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mspecial_characters\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 763\u001b[0m precision=precision)\n\u001b[0;32m--> 764\u001b[0;31m \u001b[0mexporter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexport\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdecision_tree\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 765\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 766\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mreturn_string\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/sklearn/tree/_export.py\u001b[0m in \u001b[0;36mexport\u001b[0;34m(self, decision_tree)\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[0;34m\"does not match number of features, %d\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 398\u001b[0m % (len(self.feature_names),\n\u001b[0;32m--> 399\u001b[0;31m decision_tree.n_features_))\n\u001b[0m\u001b[1;32m 400\u001b[0m \u001b[0;31m# each part writes to out_file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\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;31mValueError\u001b[0m: Length of feature_names, 18 does not match number of features, 30"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bG31I7_n4RQg"
+ },
+ "source": [
+ "### Aplicar as transformações (principais) estudadas e reestimar o modelo novamente\n",
+ "* Qual o impacto das transformações?\n",
+ "* A conclusão muda/mudou?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oYgK6JXd3MgA"
+ },
+ "source": [
+ "## Exercício 2 - Predicting species on IRIS dataset\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "si0rsJvu3O6O"
+ },
+ "source": [
+ "from sklearn import datasets\n",
+ "import xgboost as xgb\n",
+ "\n",
+ "iris = datasets.load_iris()\n",
+ "X_iris = iris.data\n",
+ "y_iris = iris.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zom8t4yWC_UC"
+ },
+ "source": [
+ "## Exercício 3 - Predict Wine Quality\n",
+ "> Estimar a qualidade dos vinhos, numa scala de 0–100. A seguir, a qualidade em função da escala:\n",
+ "\n",
+ "* 95–100 Classic: a great wine\n",
+ "* 90–94 Outstanding: a wine of superior character and style\n",
+ "* 85–89 Very good: a wine with special qualities\n",
+ "* 80–84 Good: a solid, well-made wine\n",
+ "* 75–79 Mediocre: a drinkable wine that may have minor flaws\n",
+ "* 50–74 Not recommended\n",
+ "\n",
+ "Source: [Wine Reviews](https://www.kaggle.com/zynicide/wine-reviews)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "klL2Q9Ria96n"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from sklearn import datasets\n",
+ "\n",
+ "Wine = datasets.load_wine()\n",
+ "X_vinho = Wine.data\n",
+ "y_vinho = Wine.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lhVhSWBgGijq"
+ },
+ "source": [
+ "## Exercício 4 - Predict Parkinson\n",
+ "Source: https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SVCxHqv0VBJn"
+ },
+ "source": [
+ "## Exercício 5 - Predict survivors from Titanic tragedy\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CwvB8us4eKNi"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "\n",
+ "df_titanic = sns.load_dataset('titanic')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZJrT9YIXVdtx"
+ },
+ "source": [
+ "## Exercício 6 - Predict Loan\n",
+ "> Os dados devem ser obtidos diretamente da fonte: [Loan Default Prediction - Imperial College London](https://www.kaggle.com/c/loan-default-prediction/data)\n",
+ "\n",
+ "* [Bank Loan Default Prediction](https://medium.com/@wutianhao910/bank-loan-default-prediction-94d4902db740)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "R8-GVu7ZWeA8"
+ },
+ "source": [
+ "## Exercício 7 - Predict the sales of a store.\n",
+ "* [Predicting expected sales for Bigmart’s stores](https://medium.com/diogo-menezes-borges/project-1-bigmart-sale-prediction-fdc04f07dc1e)\n",
+ "* Dataframes\n",
+ " * [Treinamento](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_train.txt)\n",
+ " * [Validação](https://raw.githubusercontent.com/MathMachado/DataFrames/master/Big_Mart_Sales_III_test.txt)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "fv9w86j4Wnwj"
+ },
+ "source": [
+ "## Exercício 8 - [The Boston Housing Dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html)\n",
+ "> Predict the median value of owner occupied homes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5HYRt8-ug1BT"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from sklearn import datasets\n",
+ "\n",
+ "Boston = datasets.load_boston()\n",
+ "X_boston = Boston.data\n",
+ "y_boston = Boston.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1UDIaqmtXQ0T"
+ },
+ "source": [
+ "## Exercício 9 - Predict the height or weight of a person.\n",
+ "\n",
+ "http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_020108_HeightsWeights"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-7R146nIXmMT"
+ },
+ "source": [
+ "## Exercício 10 - Black Friday Sales Prediction - Predict purchase amount.\n",
+ "\n",
+ "This dataset comprises of sales transactions captured at a retail store. It’s a classic dataset to explore and expand your feature engineering skills and day to day understanding from multiple shopping experiences. This is a regression problem. The dataset has 550,069 rows and 12 columns.\n",
+ "\n",
+ "https://github.com/MathMachado/DataFrames/blob/master/blackfriday.zip\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "mQ8FPbuLZlIh"
+ },
+ "source": [
+ "## Exercício 11 - Predict the income class of US population.\n",
+ "\n",
+ "http://archive.ics.uci.edu/ml/machine-learning-databases/census-income-mld/"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Af4NRrchgPlM"
+ },
+ "source": [
+ "## Exercício 12 - Predicting Cancer\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "c4LOlgZW3P40"
+ },
+ "source": [
+ "from sklearn import datasets\n",
+ "cancer = datasets.load_breast_cancer()\n",
+ "X_cancer = cancer.data\n",
+ "y_cancer = cancer.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "74PmpT8Ix0tD"
+ },
+ "source": [
+ "## Exercício 13\n",
+ "Source: [Complete Machine Learning Guide to Parameter Tuning in Gradient Boosting (GBM) in Python](https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/).\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WY8GZMixZ9W9"
+ },
+ "source": [
+ "## Exercício 14 - Predict Diabetes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "y92t6tbOge0S"
+ },
+ "source": [
+ "from sklearn import datasets\n",
+ "Diabetes= datasets.load_diabetes()\n",
+ "\n",
+ "X_diabetes = Diabetes.data\n",
+ "y_diabetes = Diabetes.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From 2b6779711bfe5ded5add4317c6bc8b8d758a299f Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Mon, 26 Oct 2020 18:12:25 -0300
Subject: [PATCH 19/21] Criado usando o Colaboratory
---
...egress\303\243o Linear_apontamentos.ipynb" | 5943 +++++++++++++++++
1 file changed, 5943 insertions(+)
create mode 100644 "Notebooks/NB15_02__Regress\303\243o Linear_apontamentos.ipynb"
diff --git "a/Notebooks/NB15_02__Regress\303\243o Linear_apontamentos.ipynb" "b/Notebooks/NB15_02__Regress\303\243o Linear_apontamentos.ipynb"
new file mode 100644
index 000000000..6c070dd81
--- /dev/null
+++ "b/Notebooks/NB15_02__Regress\303\243o Linear_apontamentos.ipynb"
@@ -0,0 +1,5943 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.1"
+ },
+ "colab": {
+ "name": "NB15_02__Regressão Linear.ipynb",
+ "provenance": [],
+ "include_colab_link": true
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XwQDhId7N6_r"
+ },
+ "source": [
+ "MACHINE LEARNING WITH PYTHON
\n",
+ "APRENDIZAGEM SUPERVISIONADA
\n",
+ "MODELOS DE REGRESSÃO (LINEAR E LOGÍSTICA)
\n",
+ "\n",
+ "Fonte: https://realpython.com/linear-regression-in-python/"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PN-dQFJcM1UV"
+ },
+ "source": [
+ "Passos para implementação da Regressão Linear:\n",
+ "\n",
+ "* (1) Importar as libraries necessárias;\n",
+ "* (2) Carregar os dados;\n",
+ "* (3) Aplicar as transformações necessárias: outliers, NaN's, normalização (MinMaxScaler, RobustScaler, StandarScaler, Log, Box-Cox e etc);\n",
+ "* (4) Construir e treinar o modelo preditivo (neste caso, modelo de regressão);\n",
+ "* (5) Validar/verificar as métricas para avaliação do(s) modelo(s);\n",
+ "* (6) Predições."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8TldGZxAFV5E"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0QRbxlqaq7pr"
+ },
+ "source": [
+ "# Melhorias da sessão:\n",
+ "* "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "P4sAIblOgFyL"
+ },
+ "source": [
+ "# Modelos de Regressão com Regularization para Classificação e Regressão"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "o7Y7cuJNgFyU"
+ },
+ "source": [
+ "## Regressão Linear Simples (usando OLS - Ordinary Least Squares)\n",
+ "\n",
+ "* Features $X_{np}$: é uma matriz de dimensão nxp;\n",
+ "* Variável target/dependente representada por y;\n",
+ "* Relação entre X e y é representado pela equação abaixo, onde $w_{i}$ representa os pesos de cada coeficiente e $w_{0}$ representa o intercepto."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NpJ580y9gFyU"
+ },
+ "source": [
+ "
\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5rhbVGJ0gFyY"
+ },
+ "source": [
+ "* Soma de Quadrados dos Resíduos (RSS) - Soma de Quadrados das diferenças entre os valores observados e preditos.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "u8gA0YkbgFyp"
+ },
+ "source": [
+ "## Principais parâmetros do algoritmo:\n",
+ "* fit_intercept - Indica se o intercepto $w_{0}$ deve ou não ser ajustado. Se os dados estão normalizados, então não faz sentido ajustar o intercepto $w_{0}$.\n",
+ "\n",
+ "* normalize - $X$ será automaticamente normalizada (subtrai a média e divide pelo desvio-padrão);\n",
+ "\n",
+ "## Atributos do modelo de Machine Learning para Regressão\n",
+ "* coef - peso/fator de cada variável independente do modelo de ML;\n",
+ "\n",
+ "* intercepto $w_{0}$ - intercepto ou viés de $y$;\n",
+ "\n",
+ "## Funções para ajuste do ML:\n",
+ "* fit - treina o modelo com as matrizes $X$ e $y$;\n",
+ "* predict - Uma vez que o modelo foi treinado, para um dado $X$, use $y$ para calcular os valores preditos de $y$ (y_pred).\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "A-JG8El1gFy7"
+ },
+ "source": [
+ "# Limitações do OLS:\n",
+ "* Impactado/sensível à Outliers;\n",
+ "* Multicolinearidade; \n",
+ "* Heterocedasticidade - apresenta-se como uma forte dispersão dos dados em torno de uma reta;\n",
+ "\n",
+ "* References"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xylMYR8COyrw"
+ },
+ "source": [
+ "### Importar as libraries"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2BGgrILlPK6Z"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from scipy import stats"
+ ],
+ "execution_count": 1,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "263GgbwhO2kQ"
+ },
+ "source": [
+ "### Carregar os dados\n",
+ "* Vamos carregar o dataset [Boston House Pricing](https://archive.ics.uci.edu/ml/datasets/housing)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "g2WoVKwkPYEd",
+ "outputId": "2e4ea40b-33b5-4214-cc6b-d768d5d948e9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 204
+ }
+ },
+ "source": [
+ "from sklearn.datasets import load_boston\n",
+ "#url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/housing.csv'\n",
+ "# Variáveis preditoras\n",
+ "df_boston = pd.DataFrame(load_boston().data, columns = load_boston().feature_names)\n",
+ "df_boston['preco'] = load_boston().target\n",
+ "df_boston.head()\n"
+ ],
+ "execution_count": 7,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " CRIM | \n",
+ " ZN | \n",
+ " INDUS | \n",
+ " CHAS | \n",
+ " NOX | \n",
+ " RM | \n",
+ " AGE | \n",
+ " DIS | \n",
+ " RAD | \n",
+ " TAX | \n",
+ " PTRATIO | \n",
+ " B | \n",
+ " LSTAT | \n",
+ " preco | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0.00632 | \n",
+ " 18.0 | \n",
+ " 2.31 | \n",
+ " 0.0 | \n",
+ " 0.538 | \n",
+ " 6.575 | \n",
+ " 65.2 | \n",
+ " 4.0900 | \n",
+ " 1.0 | \n",
+ " 296.0 | \n",
+ " 15.3 | \n",
+ " 396.90 | \n",
+ " 4.98 | \n",
+ " 24.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0.02731 | \n",
+ " 0.0 | \n",
+ " 7.07 | \n",
+ " 0.0 | \n",
+ " 0.469 | \n",
+ " 6.421 | \n",
+ " 78.9 | \n",
+ " 4.9671 | \n",
+ " 2.0 | \n",
+ " 242.0 | \n",
+ " 17.8 | \n",
+ " 396.90 | \n",
+ " 9.14 | \n",
+ " 21.6 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 0.02729 | \n",
+ " 0.0 | \n",
+ " 7.07 | \n",
+ " 0.0 | \n",
+ " 0.469 | \n",
+ " 7.185 | \n",
+ " 61.1 | \n",
+ " 4.9671 | \n",
+ " 2.0 | \n",
+ " 242.0 | \n",
+ " 17.8 | \n",
+ " 392.83 | \n",
+ " 4.03 | \n",
+ " 34.7 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 0.03237 | \n",
+ " 0.0 | \n",
+ " 2.18 | \n",
+ " 0.0 | \n",
+ " 0.458 | \n",
+ " 6.998 | \n",
+ " 45.8 | \n",
+ " 6.0622 | \n",
+ " 3.0 | \n",
+ " 222.0 | \n",
+ " 18.7 | \n",
+ " 394.63 | \n",
+ " 2.94 | \n",
+ " 33.4 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 0.06905 | \n",
+ " 0.0 | \n",
+ " 2.18 | \n",
+ " 0.0 | \n",
+ " 0.458 | \n",
+ " 7.147 | \n",
+ " 54.2 | \n",
+ " 6.0622 | \n",
+ " 3.0 | \n",
+ " 222.0 | \n",
+ " 18.7 | \n",
+ " 396.90 | \n",
+ " 5.33 | \n",
+ " 36.2 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT preco\n",
+ "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n",
+ "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n",
+ "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n",
+ "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n",
+ "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n",
+ "\n",
+ "[5 rows x 14 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 7
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kinipZB4Yq4f",
+ "outputId": "53d258d1-1b82-4fe9-b3af-c4b324e86971",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 799
+ }
+ },
+ "source": [
+ "load_boston().target"
+ ],
+ "execution_count": 8,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,\n",
+ " 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,\n",
+ " 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,\n",
+ " 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,\n",
+ " 21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,\n",
+ " 35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,\n",
+ " 19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,\n",
+ " 20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,\n",
+ " 23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,\n",
+ " 33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,\n",
+ " 21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,\n",
+ " 20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,\n",
+ " 23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,\n",
+ " 15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,\n",
+ " 17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,\n",
+ " 25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,\n",
+ " 23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,\n",
+ " 32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,\n",
+ " 34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,\n",
+ " 20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,\n",
+ " 26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,\n",
+ " 31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,\n",
+ " 22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,\n",
+ " 42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,\n",
+ " 36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,\n",
+ " 32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,\n",
+ " 20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,\n",
+ " 20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,\n",
+ " 22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,\n",
+ " 21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,\n",
+ " 19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,\n",
+ " 32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,\n",
+ " 18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,\n",
+ " 16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,\n",
+ " 13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3, 8.8,\n",
+ " 7.2, 10.5, 7.4, 10.2, 11.5, 15.1, 23.2, 9.7, 13.8, 12.7, 13.1,\n",
+ " 12.5, 8.5, 5. , 6.3, 5.6, 7.2, 12.1, 8.3, 8.5, 5. , 11.9,\n",
+ " 27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3, 7. , 7.2, 7.5, 10.4,\n",
+ " 8.8, 8.4, 16.7, 14.2, 20.8, 13.4, 11.7, 8.3, 10.2, 10.9, 11. ,\n",
+ " 9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4, 9.6, 8.7, 8.4, 12.8,\n",
+ " 10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,\n",
+ " 15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,\n",
+ " 19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,\n",
+ " 29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,\n",
+ " 20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,\n",
+ " 23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 8
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4cYeEC6tYnFC",
+ "outputId": "0e936cda-5853-4ead-99e5-2c61080ddda9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "load_boston().feature_names"
+ ],
+ "execution_count": 9,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n",
+ " 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='\n",
+ "\n",
+ "\n",
+ " \n",
+ " \n",
+ " | \n",
+ " crim | \n",
+ " zn | \n",
+ " indus | \n",
+ " chas | \n",
+ " nox | \n",
+ " rm | \n",
+ " age | \n",
+ " dis | \n",
+ " rad | \n",
+ " tax | \n",
+ " ptratio | \n",
+ " b | \n",
+ " lstat | \n",
+ " preco | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0.00632 | \n",
+ " 18.0 | \n",
+ " 2.31 | \n",
+ " 0.0 | \n",
+ " 0.538 | \n",
+ " 6.575 | \n",
+ " 65.2 | \n",
+ " 4.0900 | \n",
+ " 1.0 | \n",
+ " 296.0 | \n",
+ " 15.3 | \n",
+ " 396.90 | \n",
+ " 4.98 | \n",
+ " 24.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 0.02731 | \n",
+ " 0.0 | \n",
+ " 7.07 | \n",
+ " 0.0 | \n",
+ " 0.469 | \n",
+ " 6.421 | \n",
+ " 78.9 | \n",
+ " 4.9671 | \n",
+ " 2.0 | \n",
+ " 242.0 | \n",
+ " 17.8 | \n",
+ " 396.90 | \n",
+ " 9.14 | \n",
+ " 21.6 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 0.02729 | \n",
+ " 0.0 | \n",
+ " 7.07 | \n",
+ " 0.0 | \n",
+ " 0.469 | \n",
+ " 7.185 | \n",
+ " 61.1 | \n",
+ " 4.9671 | \n",
+ " 2.0 | \n",
+ " 242.0 | \n",
+ " 17.8 | \n",
+ " 392.83 | \n",
+ " 4.03 | \n",
+ " 34.7 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 0.03237 | \n",
+ " 0.0 | \n",
+ " 2.18 | \n",
+ " 0.0 | \n",
+ " 0.458 | \n",
+ " 6.998 | \n",
+ " 45.8 | \n",
+ " 6.0622 | \n",
+ " 3.0 | \n",
+ " 222.0 | \n",
+ " 18.7 | \n",
+ " 394.63 | \n",
+ " 2.94 | \n",
+ " 33.4 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 0.06905 | \n",
+ " 0.0 | \n",
+ " 2.18 | \n",
+ " 0.0 | \n",
+ " 0.458 | \n",
+ " 7.147 | \n",
+ " 54.2 | \n",
+ " 6.0622 | \n",
+ " 3.0 | \n",
+ " 222.0 | \n",
+ " 18.7 | \n",
+ " 396.90 | \n",
+ " 5.33 | \n",
+ " 36.2 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ ""
+ ],
+ "text/plain": [
+ " crim zn indus chas nox ... tax ptratio b lstat preco\n",
+ "0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0\n",
+ "1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6\n",
+ "2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7\n",
+ "3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4\n",
+ "4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2\n",
+ "\n",
+ "[5 rows x 14 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 12
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CMDh5jyqekmr"
+ },
+ "source": [
+ "#### Outliers"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jJIG0jJQf6em"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FgYPzlvfemFc"
+ },
+ "source": [
+ "#### Missing values"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BAjw7UhJen0D",
+ "outputId": "d4adbe43-869a-4f90-f65a-1606db0d5768",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 272
+ }
+ },
+ "source": [
+ "# Missing values por colunas/variáveis\n",
+ "df_boston.isna().sum()"
+ ],
+ "execution_count": 13,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "crim 0\n",
+ "zn 0\n",
+ "indus 0\n",
+ "chas 0\n",
+ "nox 0\n",
+ "rm 0\n",
+ "age 0\n",
+ "dis 0\n",
+ "rad 0\n",
+ "tax 0\n",
+ "ptratio 0\n",
+ "b 0\n",
+ "lstat 0\n",
+ "preco 0\n",
+ "dtype: int64"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 13
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0Yp8g7hxfQli",
+ "outputId": "51d084ad-f980-4c58-8614-3cd93e122728",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 49
+ }
+ },
+ "source": [
+ "# Missing Values por linhas\n",
+ "df_boston[df_boston.isnull().any(axis = 1)]"
+ ],
+ "execution_count": 14,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " crim | \n",
+ " zn | \n",
+ " indus | \n",
+ " chas | \n",
+ " nox | \n",
+ " rm | \n",
+ " age | \n",
+ " dis | \n",
+ " rad | \n",
+ " tax | \n",
+ " ptratio | \n",
+ " b | \n",
+ " lstat | \n",
+ " preco | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ "Empty DataFrame\n",
+ "Columns: [crim, zn, indus, chas, nox, rm, age, dis, rad, tax, ptratio, b, lstat, preco]\n",
+ "Index: []"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 14
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5qmkTFLrf9MT"
+ },
+ "source": [
+ "#### Estatísticas Descritivas"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Nprn3p_Wf_bn",
+ "outputId": "e3654337-020d-4109-9c9f-9dd65b3a10e8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 317
+ }
+ },
+ "source": [
+ "df_boston.describe()"
+ ],
+ "execution_count": 15,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " crim | \n",
+ " zn | \n",
+ " indus | \n",
+ " chas | \n",
+ " nox | \n",
+ " rm | \n",
+ " age | \n",
+ " dis | \n",
+ " rad | \n",
+ " tax | \n",
+ " ptratio | \n",
+ " b | \n",
+ " lstat | \n",
+ " preco | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ " 506.000000 | \n",
+ "
\n",
+ " \n",
+ " | mean | \n",
+ " 3.613524 | \n",
+ " 11.363636 | \n",
+ " 11.136779 | \n",
+ " 0.069170 | \n",
+ " 0.554695 | \n",
+ " 6.284634 | \n",
+ " 68.574901 | \n",
+ " 3.795043 | \n",
+ " 9.549407 | \n",
+ " 408.237154 | \n",
+ " 18.455534 | \n",
+ " 356.674032 | \n",
+ " 12.653063 | \n",
+ " 22.532806 | \n",
+ "
\n",
+ " \n",
+ " | std | \n",
+ " 8.601545 | \n",
+ " 23.322453 | \n",
+ " 6.860353 | \n",
+ " 0.253994 | \n",
+ " 0.115878 | \n",
+ " 0.702617 | \n",
+ " 28.148861 | \n",
+ " 2.105710 | \n",
+ " 8.707259 | \n",
+ " 168.537116 | \n",
+ " 2.164946 | \n",
+ " 91.294864 | \n",
+ " 7.141062 | \n",
+ " 9.197104 | \n",
+ "
\n",
+ " \n",
+ " | min | \n",
+ " 0.006320 | \n",
+ " 0.000000 | \n",
+ " 0.460000 | \n",
+ " 0.000000 | \n",
+ " 0.385000 | \n",
+ " 3.561000 | \n",
+ " 2.900000 | \n",
+ " 1.129600 | \n",
+ " 1.000000 | \n",
+ " 187.000000 | \n",
+ " 12.600000 | \n",
+ " 0.320000 | \n",
+ " 1.730000 | \n",
+ " 5.000000 | \n",
+ "
\n",
+ " \n",
+ " | 25% | \n",
+ " 0.082045 | \n",
+ " 0.000000 | \n",
+ " 5.190000 | \n",
+ " 0.000000 | \n",
+ " 0.449000 | \n",
+ " 5.885500 | \n",
+ " 45.025000 | \n",
+ " 2.100175 | \n",
+ " 4.000000 | \n",
+ " 279.000000 | \n",
+ " 17.400000 | \n",
+ " 375.377500 | \n",
+ " 6.950000 | \n",
+ " 17.025000 | \n",
+ "
\n",
+ " \n",
+ " | 50% | \n",
+ " 0.256510 | \n",
+ " 0.000000 | \n",
+ " 9.690000 | \n",
+ " 0.000000 | \n",
+ " 0.538000 | \n",
+ " 6.208500 | \n",
+ " 77.500000 | \n",
+ " 3.207450 | \n",
+ " 5.000000 | \n",
+ " 330.000000 | \n",
+ " 19.050000 | \n",
+ " 391.440000 | \n",
+ " 11.360000 | \n",
+ " 21.200000 | \n",
+ "
\n",
+ " \n",
+ " | 75% | \n",
+ " 3.677083 | \n",
+ " 12.500000 | \n",
+ " 18.100000 | \n",
+ " 0.000000 | \n",
+ " 0.624000 | \n",
+ " 6.623500 | \n",
+ " 94.075000 | \n",
+ " 5.188425 | \n",
+ " 24.000000 | \n",
+ " 666.000000 | \n",
+ " 20.200000 | \n",
+ " 396.225000 | \n",
+ " 16.955000 | \n",
+ " 25.000000 | \n",
+ "
\n",
+ " \n",
+ " | max | \n",
+ " 88.976200 | \n",
+ " 100.000000 | \n",
+ " 27.740000 | \n",
+ " 1.000000 | \n",
+ " 0.871000 | \n",
+ " 8.780000 | \n",
+ " 100.000000 | \n",
+ " 12.126500 | \n",
+ " 24.000000 | \n",
+ " 711.000000 | \n",
+ " 22.000000 | \n",
+ " 396.900000 | \n",
+ " 37.970000 | \n",
+ " 50.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " crim zn indus ... b lstat preco\n",
+ "count 506.000000 506.000000 506.000000 ... 506.000000 506.000000 506.000000\n",
+ "mean 3.613524 11.363636 11.136779 ... 356.674032 12.653063 22.532806\n",
+ "std 8.601545 23.322453 6.860353 ... 91.294864 7.141062 9.197104\n",
+ "min 0.006320 0.000000 0.460000 ... 0.320000 1.730000 5.000000\n",
+ "25% 0.082045 0.000000 5.190000 ... 375.377500 6.950000 17.025000\n",
+ "50% 0.256510 0.000000 9.690000 ... 391.440000 11.360000 21.200000\n",
+ "75% 3.677083 12.500000 18.100000 ... 396.225000 16.955000 25.000000\n",
+ "max 88.976200 100.000000 27.740000 ... 396.900000 37.970000 50.000000\n",
+ "\n",
+ "[8 rows x 14 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 15
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1JimyY3SgECE"
+ },
+ "source": [
+ "#### Análise de Correlação"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jScHq7eTgIpm",
+ "outputId": "554ca659-b49c-4a12-9dea-cf910c558dbd",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 483
+ }
+ },
+ "source": [
+ "correlacoes = df_boston.corr()\n",
+ "correlacoes"
+ ],
+ "execution_count": 16,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " crim | \n",
+ " zn | \n",
+ " indus | \n",
+ " chas | \n",
+ " nox | \n",
+ " rm | \n",
+ " age | \n",
+ " dis | \n",
+ " rad | \n",
+ " tax | \n",
+ " ptratio | \n",
+ " b | \n",
+ " lstat | \n",
+ " preco | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | crim | \n",
+ " 1.000000 | \n",
+ " -0.200469 | \n",
+ " 0.406583 | \n",
+ " -0.055892 | \n",
+ " 0.420972 | \n",
+ " -0.219247 | \n",
+ " 0.352734 | \n",
+ " -0.379670 | \n",
+ " 0.625505 | \n",
+ " 0.582764 | \n",
+ " 0.289946 | \n",
+ " -0.385064 | \n",
+ " 0.455621 | \n",
+ " -0.388305 | \n",
+ "
\n",
+ " \n",
+ " | zn | \n",
+ " -0.200469 | \n",
+ " 1.000000 | \n",
+ " -0.533828 | \n",
+ " -0.042697 | \n",
+ " -0.516604 | \n",
+ " 0.311991 | \n",
+ " -0.569537 | \n",
+ " 0.664408 | \n",
+ " -0.311948 | \n",
+ " -0.314563 | \n",
+ " -0.391679 | \n",
+ " 0.175520 | \n",
+ " -0.412995 | \n",
+ " 0.360445 | \n",
+ "
\n",
+ " \n",
+ " | indus | \n",
+ " 0.406583 | \n",
+ " -0.533828 | \n",
+ " 1.000000 | \n",
+ " 0.062938 | \n",
+ " 0.763651 | \n",
+ " -0.391676 | \n",
+ " 0.644779 | \n",
+ " -0.708027 | \n",
+ " 0.595129 | \n",
+ " 0.720760 | \n",
+ " 0.383248 | \n",
+ " -0.356977 | \n",
+ " 0.603800 | \n",
+ " -0.483725 | \n",
+ "
\n",
+ " \n",
+ " | chas | \n",
+ " -0.055892 | \n",
+ " -0.042697 | \n",
+ " 0.062938 | \n",
+ " 1.000000 | \n",
+ " 0.091203 | \n",
+ " 0.091251 | \n",
+ " 0.086518 | \n",
+ " -0.099176 | \n",
+ " -0.007368 | \n",
+ " -0.035587 | \n",
+ " -0.121515 | \n",
+ " 0.048788 | \n",
+ " -0.053929 | \n",
+ " 0.175260 | \n",
+ "
\n",
+ " \n",
+ " | nox | \n",
+ " 0.420972 | \n",
+ " -0.516604 | \n",
+ " 0.763651 | \n",
+ " 0.091203 | \n",
+ " 1.000000 | \n",
+ " -0.302188 | \n",
+ " 0.731470 | \n",
+ " -0.769230 | \n",
+ " 0.611441 | \n",
+ " 0.668023 | \n",
+ " 0.188933 | \n",
+ " -0.380051 | \n",
+ " 0.590879 | \n",
+ " -0.427321 | \n",
+ "
\n",
+ " \n",
+ " | rm | \n",
+ " -0.219247 | \n",
+ " 0.311991 | \n",
+ " -0.391676 | \n",
+ " 0.091251 | \n",
+ " -0.302188 | \n",
+ " 1.000000 | \n",
+ " -0.240265 | \n",
+ " 0.205246 | \n",
+ " -0.209847 | \n",
+ " -0.292048 | \n",
+ " -0.355501 | \n",
+ " 0.128069 | \n",
+ " -0.613808 | \n",
+ " 0.695360 | \n",
+ "
\n",
+ " \n",
+ " | age | \n",
+ " 0.352734 | \n",
+ " -0.569537 | \n",
+ " 0.644779 | \n",
+ " 0.086518 | \n",
+ " 0.731470 | \n",
+ " -0.240265 | \n",
+ " 1.000000 | \n",
+ " -0.747881 | \n",
+ " 0.456022 | \n",
+ " 0.506456 | \n",
+ " 0.261515 | \n",
+ " -0.273534 | \n",
+ " 0.602339 | \n",
+ " -0.376955 | \n",
+ "
\n",
+ " \n",
+ " | dis | \n",
+ " -0.379670 | \n",
+ " 0.664408 | \n",
+ " -0.708027 | \n",
+ " -0.099176 | \n",
+ " -0.769230 | \n",
+ " 0.205246 | \n",
+ " -0.747881 | \n",
+ " 1.000000 | \n",
+ " -0.494588 | \n",
+ " -0.534432 | \n",
+ " -0.232471 | \n",
+ " 0.291512 | \n",
+ " -0.496996 | \n",
+ " 0.249929 | \n",
+ "
\n",
+ " \n",
+ " | rad | \n",
+ " 0.625505 | \n",
+ " -0.311948 | \n",
+ " 0.595129 | \n",
+ " -0.007368 | \n",
+ " 0.611441 | \n",
+ " -0.209847 | \n",
+ " 0.456022 | \n",
+ " -0.494588 | \n",
+ " 1.000000 | \n",
+ " 0.910228 | \n",
+ " 0.464741 | \n",
+ " -0.444413 | \n",
+ " 0.488676 | \n",
+ " -0.381626 | \n",
+ "
\n",
+ " \n",
+ " | tax | \n",
+ " 0.582764 | \n",
+ " -0.314563 | \n",
+ " 0.720760 | \n",
+ " -0.035587 | \n",
+ " 0.668023 | \n",
+ " -0.292048 | \n",
+ " 0.506456 | \n",
+ " -0.534432 | \n",
+ " 0.910228 | \n",
+ " 1.000000 | \n",
+ " 0.460853 | \n",
+ " -0.441808 | \n",
+ " 0.543993 | \n",
+ " -0.468536 | \n",
+ "
\n",
+ " \n",
+ " | ptratio | \n",
+ " 0.289946 | \n",
+ " -0.391679 | \n",
+ " 0.383248 | \n",
+ " -0.121515 | \n",
+ " 0.188933 | \n",
+ " -0.355501 | \n",
+ " 0.261515 | \n",
+ " -0.232471 | \n",
+ " 0.464741 | \n",
+ " 0.460853 | \n",
+ " 1.000000 | \n",
+ " -0.177383 | \n",
+ " 0.374044 | \n",
+ " -0.507787 | \n",
+ "
\n",
+ " \n",
+ " | b | \n",
+ " -0.385064 | \n",
+ " 0.175520 | \n",
+ " -0.356977 | \n",
+ " 0.048788 | \n",
+ " -0.380051 | \n",
+ " 0.128069 | \n",
+ " -0.273534 | \n",
+ " 0.291512 | \n",
+ " -0.444413 | \n",
+ " -0.441808 | \n",
+ " -0.177383 | \n",
+ " 1.000000 | \n",
+ " -0.366087 | \n",
+ " 0.333461 | \n",
+ "
\n",
+ " \n",
+ " | lstat | \n",
+ " 0.455621 | \n",
+ " -0.412995 | \n",
+ " 0.603800 | \n",
+ " -0.053929 | \n",
+ " 0.590879 | \n",
+ " -0.613808 | \n",
+ " 0.602339 | \n",
+ " -0.496996 | \n",
+ " 0.488676 | \n",
+ " 0.543993 | \n",
+ " 0.374044 | \n",
+ " -0.366087 | \n",
+ " 1.000000 | \n",
+ " -0.737663 | \n",
+ "
\n",
+ " \n",
+ " | preco | \n",
+ " -0.388305 | \n",
+ " 0.360445 | \n",
+ " -0.483725 | \n",
+ " 0.175260 | \n",
+ " -0.427321 | \n",
+ " 0.695360 | \n",
+ " -0.376955 | \n",
+ " 0.249929 | \n",
+ " -0.381626 | \n",
+ " -0.468536 | \n",
+ " -0.507787 | \n",
+ " 0.333461 | \n",
+ " -0.737663 | \n",
+ " 1.000000 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " crim zn indus ... b lstat preco\n",
+ "crim 1.000000 -0.200469 0.406583 ... -0.385064 0.455621 -0.388305\n",
+ "zn -0.200469 1.000000 -0.533828 ... 0.175520 -0.412995 0.360445\n",
+ "indus 0.406583 -0.533828 1.000000 ... -0.356977 0.603800 -0.483725\n",
+ "chas -0.055892 -0.042697 0.062938 ... 0.048788 -0.053929 0.175260\n",
+ "nox 0.420972 -0.516604 0.763651 ... -0.380051 0.590879 -0.427321\n",
+ "rm -0.219247 0.311991 -0.391676 ... 0.128069 -0.613808 0.695360\n",
+ "age 0.352734 -0.569537 0.644779 ... -0.273534 0.602339 -0.376955\n",
+ "dis -0.379670 0.664408 -0.708027 ... 0.291512 -0.496996 0.249929\n",
+ "rad 0.625505 -0.311948 0.595129 ... -0.444413 0.488676 -0.381626\n",
+ "tax 0.582764 -0.314563 0.720760 ... -0.441808 0.543993 -0.468536\n",
+ "ptratio 0.289946 -0.391679 0.383248 ... -0.177383 0.374044 -0.507787\n",
+ "b -0.385064 0.175520 -0.356977 ... 1.000000 -0.366087 0.333461\n",
+ "lstat 0.455621 -0.412995 0.603800 ... -0.366087 1.000000 -0.737663\n",
+ "preco -0.388305 0.360445 -0.483725 ... 0.333461 -0.737663 1.000000\n",
+ "\n",
+ "[14 rows x 14 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 16
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AxQp7xqdgTJP"
+ },
+ "source": [
+ "##### Gráfico das correlações entre as features/variáveis/colunas\n",
+ "Source: https://seaborn.pydata.org/examples/many_pairwise_correlations.html\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KOiH2X-WgqmN",
+ "outputId": "ef9b58f8-e9fd-4019-92c7-151bfaf4f58f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 557
+ }
+ },
+ "source": [
+ "import seaborn as sns\n",
+ "from string import ascii_letters\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "sns.set_theme(style = \"white\")\n",
+ "\n",
+ "d = df_boston\n",
+ "\n",
+ "# Compute the correlation matrix\n",
+ "corr = d.corr()\n",
+ "\n",
+ "# Generate a mask for the upper triangle\n",
+ "mask = np.triu(np.ones_like(corr, dtype=bool))\n",
+ "\n",
+ "# Set up the matplotlib figure\n",
+ "f, ax = plt.subplots(figsize=(11, 9))\n",
+ "\n",
+ "# Generate a custom diverging colormap\n",
+ "cmap = sns.diverging_palette(230, 20, as_cmap=True)\n",
+ "\n",
+ "# Draw the heatmap with the mask and correct aspect ratio\n",
+ "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n",
+ " square=True, linewidths=.5, cbar_kws={\"shrink\": .5})"
+ ],
+ "execution_count": 17,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 17
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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+PCqjgcAAGCEKv+cury8PAUEBKhhw4Y6f/68Vq9eLUnq2rWrPvjgA507d06lpaV69913XY+JiIhQamqqcnJyJElOp1NfffVVVUcFAACGsyyrUrfapMpH6sLDw/Xuu+8qMjJSjRo10p133qndu3frwQcf1I4dO/TII4+oQYMGCg0N1enTpyVJd911l37/+9/rt7/9rZxOp4qLi9WrVy/deuutVR0XAAAYjK8Juw433HCDXn311Qrv+81vfqPRo0ertLRUEydOVGhoqOu+Rx55RI888khVxwMAADCCrZ9TN3bsWB06dEiFhYXq3Lmzhg4damccAABgOIMH6uwtdX/+85/tPDwAAPAwdk2/njt3TuPHj9fXX38tb29vjR07Vt27dy+33T//+U/Nnz9f58+fd104GhcXd03H4BslAACAx7Dr4oeFCxcqICBAH374obKysjR48GBt2LBB/v7+ZbZr0qSJ/vKXv6hZs2Y6c+aMHn30Ud1+++268847r3qMKr/6FQAAwNOtX79eAwcOlCS1bdtWt956qzZt2lRuuy5duqhZs2aSpPr16ys4OFiHDh26pmMwUgcAADxGZQfq8vLyKvwChMDAQAUGBl7zfg4fPqybbrrJtdy8eXPXR7ddTmZmpnbu3KnExMRrOgalDgAAeIzKnlO3ePFizZs3r9z6+Ph4DRs2zLUcExOjw4cPV7iPzZs3Vy6kpGPHjun5559XQkKCa+Tuaih1AADAY1iqXKkbMmSIYmJiyq2/dJQuJSXlivtp0aKFDh06pKCgIEnSkSNHFBYWVuG2J0+e1K9+9Ss9++yz6t279zVnpdQBAACPUdnp18pOs15Or169tGLFCt12223KysrS7t279corr5Tb7ocfftCvfvUrDR48WLGxsZU6BhdKAAAAVLFnnnlGeXl56tmzp5577jklJSUpICBAkvTaa69p+fLlkqQ33nhDWVlZWrFihaKjoxUdHe36itWrYaQOAAB4DLs+p87Pz09z5syp8L7hw4e7fh47dqzGjh37k45BqQMAAB7Drs+pqw5MvwIAABjAyzK5sgIAAFzknzu/qdT2PUI7VFES9zN2+vWND7bZHUGS9OvIMB1Yt8ruGJKkNlGx6jt1id0xJElp4/9H3x48ancMSdLPWzZT94SFdseQJH2c+IyObP3U7hiSpOZ3d1PPpLfsjiFJ+nDSr+yO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KlaSFPmnt2xOIn3w4q/sjoBqwPQrAACAASh1AAAABqDUAQAAGIBSBwAAYABKHQAAgAEodQAAAAag1AEAABiAUgcAAGAASh0AAIABKHUAAAAGoNQBAAAYgFIHAABgAEodAACAAaq81JWUlFT1IQAAADyez099YEhIiF544QV99NFHKiws1MiRIxUZGem6Lz4+Xp988onCw8P17LPPaurUqcrIyFBRUZHCwsI0fvx4eXt76+jRo3rppZeUlZUlSerTp4+ee+45nThxQgkJCfr+++8lSc8884z69et3/b8xAACAgX5yqZMkh8Oh1NRUfffdd3r88cd15513qnHjxpKkOnXqaPXq1ZKkiRMn6q677tL//u//qrS0VKNHj9bq1as1YMAAjR49Wt26ddPcuXMlSbm5uZKkl156ST//+c/15z//WceOHdOjjz6qTp06qUOHDtcTGQAAwEjXVepiY2MlSe3bt1enTp20c+dOPfjgg5KkmJgY13YbN27Url279NZbb0mSCgsL1axZMxUUFGjHjh2u9ZIUFBQkSdqyZYvGjRsnSWratKm6deumbdu2UeoAAAAqcF2l7kr8/PxcP1uWpfnz56tVq1ZltikoKKiqwwMAAHiU67pQ4sL0alZWlvbs2aPQ0NAKt4uIiNAbb7whp9Mp6ccp1uzsbPn7++sXv/iFFi1a5Nr2wvTrPffco5UrV0qSjh8/rk8//VR333339cQFAAAw1nWVOqfTqX79+um5555TUlKS63y6S02YMEEOh0PR0dHq27evnn32WR09elSSNHPmTH3xxRfq06ePHnnkEb3zzjuSpD/+8Y9KT09X3759FRcXp9GjR+vnP//59cQFAAAw1nVNv8bFxWnYsGHl1mdkZJRZDggIUGJiYoX7aNasmebPn19u/c9+9rMK1wMAAKA8PnwYAADAAD95pO7S0TgAAADYh5E6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqQMAADAApQ4AAMAAlDoAAAADUOoAAAAM4GVZlmV3CAAAAFwfRuoAAAAMQKkDAAAwAKUOAADAAJQ6AAAAA1DqAAAADECpAwAAMAClDgAAwACUOgAAAANQ6gAAAAxAqavA7t27NWrUKLtjVLno6GgVFhZW+nERERH65ptvqiBRzTomzBASEqKCgoKf/H63w7hx47R06VK37W/u3Lk6f/682/ZXncc/ePCgVqxYUWbd0KFD9f3337sjWjkX3i9V7WrHycvL04IFC655f3a/xqgZKHWXKCkp0W233aZXXnnF7ihVLjU1VXXr1rU7BtygpKTE7gg1np3vd7tfn3nz5qm4uLhGHv9qz82hQ4fKlboFCxaodevWbstXE+Xl5enNN9+85u2r6jW2+72LyvGxO0B127Fjh2bMmOH6L6QxY8Zo0qRJioqK0tatW9WhQwdFR0dr+vTpWrNmjQ4ePKj+/ftrwIAB+uyzz1RYWKiZM2cqOTlZX375perWrav58+erSZMmbsn36aefatasWa7lzMxMvfrqq5o7d666dOmiHTt2yMvLS7Nnz1ZwcPB1HSskJERffPGF/P39FRERoejoaG3evFnHjx9XXFycnnzySUnS9u3blZiYKEm66667dPHXBV+8j4uXHQ6Hxo4dq3379snHx0ft2rXTa6+9dk25KnqNJGn9+vV68cUXy+WbPn26Pv/8cxUXF6tRo0aaMmWKbrrpJp08eVKjRo3SyZMnJUn33HOPJkyY8JOfqxEjRujDDz/UqVOnNGbMGEVGRkqSNm3apFmzZsnpdCooKEhJSUlq1aqVnn32WXXr1k1DhgzRvn37NHToUC1fvlw33njjT8pQUab4+Hh98sknCg8PV05Ojnx9fZWVlaXs7Gz17NlT3bt319y5c5WTk6MhQ4ZoyJAhbjn2BaNGjdL+/ftVXFys1q1ba8qUKWrQoIFmz56tdevWqWHDhuratau2bNmiNWvWSJJSUlK0bNkyOZ1OBQQEaPLkyWrfvr3bMm3YsEGzZs1SnTp19NBDD7nWX3hv1qtXT0lJSdq6dat8fX3l5+en5ORktx3/4uNd/Pr07t1biYmJOnfunIqKijRgwAA9/fTTkqSjR49qzJgxOn78uG666SY5HO777+0Lf7uDBg2Sw+HQs88+q7fffttVAMaOHat77rlHJ0+eVGxsrF577TXddtttSklJ0cqVK7VkyRL5+Fz9/ypCQkL0wgsv6KOPPlJhYaFGjhypyMjIcsdfsmSJpkyZIm9vb+3fv18FBQVKTU297HspKSlJBw8eVHR0tNq0aaM5c+YoIiJCf/3rX9WhQwcdOHBAkyZNUm5urnx8fDRixAjdf//91/WcLVy4sNzvUVVKS0srfD8mJSXpzJkzio6OVr169ZScnKy//e1veu+99+R0OlWnTh1NnjxZHTt2rPA5DgwMvOJxL/d6Xbjv4vfus88+q6lTpyojI0NFRUUKCwvT+PHj5e3traNHj+qll15SVlaWJKlPnz567rnndOLECSUkJLhGVJ955hn169evyp5H/D+WB/nhhx+s//N//o/13//+17IsyyopKbFOnTplde/e3UpISHBtt3XrVismJsayLMvKzs62OnToYH388ceWZVnWggULrF/+8pfWnj17LMuyrISEBGvWrFlVknfFihXWwIEDrU8//dTq1KmT9fXXX1uWZVnz58+3Ro4ced3779Chg5Wfn29ZlmV1797dmjZtmmVZP/7OoaGhVn5+vlVUVGTdd9991tatWy3Lsqz33nvP6tChg5WRkVFuHxcvb9iwwYqLi3OtP3Xq1DVlutJrVFE+y7KskydPuh6/cuVK6/e//71lWZb11ltvWS+++GKlM1SkQ4cO1pIlSyzLsqzt27db9913n2VZlnXixAkrLCzM+vbbb13Hf+yxx1z3de/e3frPf/5j9enTx/UecpcOHTpYr7/+umt57Nix1qBBg6yioiLr7Nmz1t13322NGzfOcjqdVk5OTpnnzF0ufu5nzZplvfzyy9ZHH31k9e3b1yooKLCcTqf1wgsvuP6e/vOf/1hDhw61ioqKLMuyrE8++cQaOHCg2/IcP37c6tq1q5WZmWlZlmW98cYbrvfkhf/9+uuvrV69ellOp9OyrOt7X1zJpa/PmTNnXL93fn6+1bt3b2vfvn2WZVlWfHy8NXfuXMuyLOv777+3QkNDXe83d2W58Nrn5uZapaWllmVZVmZmphUeHu7abuvWrdZDDz1k7dixw3rggQesw4cPV+oYF36HzMxMq2vXrtaJEyfKHd+yfnyvxsTEWAUFBa51Fb2XLmS68P65oHv37q5/Bz322GPWypUrLcuyrG+//dbq2rVrmX1V1pV+D3e62vsxOzvb6tq1a5nHXPx7/fvf/7ZiY2PL7a8yx7/S63Xxe3fChAlWSkqKZVmW5XQ6rREjRlgrVqywLMuynnzySWvBggXlMg4fPtyaPXu2ZVmWdfToUevee+91vWaoOh41Urdz504FBwfrjjvukCR5e3urQYMGknTF/4Lw8/PTAw88IEnq3LmzbrzxRnXs2NG1vHnzZrdn/eyzz/TWW2/p73//u7799lu1a9dOnTp1kiSFhobq448/dvsxo6KiJEktW7ZUYGCgcnJyVFxcrHr16iksLMy1zaRJk666r1tuuUWZmZlKTExU165dXc/f1VzpNaooX3BwsDZt2qRly5bp7NmzZaYKunTpokWLFmn69Onq2rWr7rvvvmt+Lipy4fihoaE6duyYioqK9OWXX+qWW27RzTffLEnq37+/EhMTlZ+fr8aNG2vKlCkaMmSI/ud//uean4PKiImJKbPco0cP+fr6SpLatWunbt26yeFwqFmzZmWeM3dJTU1VWlqaiouLdfbsWbVt21bFxcXq3bu3/Pz8JP34tzV//nxJ0saNG5Wenq7Y2FhJkmVZysvLc1ueL7/8Up06dXKN/A0cOFAzZ84ss02rVq1UUlKiiRMnKiwsTN27d3fb8S918etTWFioyZMnKyMjQ15eXjp27JjS09MVHBysbdu26Y9//KMr3z333FNlmbKzszVq1CgdPXpUPj4+OnHihI4fP64mTZooLCxMffr00RNPPKF58+apefPmldr3hde1ffv26tSpk3bu3KkHH3ywwm179erleo9IFb+XriY/P1979+5V//79JUk333yzOnbsqJ07dyoiIqJS2X/q73G9KvN+/Oqrr/T666/r9OnT8vLyco2O/VRX+j0vfu9u3LhRu3bt0ltvvSXpx/dys2bNVFBQoB07drjWS1JQUJAkacuWLRo3bpwkqWnTpurWrZu2bdumDh06XFdmXJlHlborufhfLpe68H+SkuRwOMose3t7y+l0ujVLenq6EhIStHDhQtcfyKUZquI8hzp16rh+vtLv5eXlVWY76/9NxxYVFbnWt2rVSmvXrtXWrVu1adMmzZ49W2lpaWWO4Y58hw4d0tSpU/XOO++oVatW+uKLLzR69GhJ0i9+8QulpKRo8+bNSk1N1RtvvKHly5df9/G9vb0lXdu5Jnv37lWjRo2Uk5Pzk497JZe+by99jq71Nf0ptm/fruXLlys5OVlBQUFKS0vTypUrr/gYy7LUv39/DR8+3G05Kqt+/fp67733tG3bNm3evFkzZ85USkqK206huNjFr8+sWbPUpEkTTZs2TT4+PoqLiyvzN1NdRo4cqXHjxqlHjx4qLS1Vly5dyuTYs2ePgoKCquw9e8HFz81PeS+Z4nLvx0udP39ew4cP19KlS9W5c2cdPXr0uqeZr+Ti18eyLM2fP1+tWrUqs011XFCCyvGoCyVCQ0OVmZmpHTt2SJKcTqdOnz5tc6qyjh49qmHDhunll19Wu3bt7I6j9u3bq7CwUNu3b5ckvf/++2VGVlq3bq3du3dLktLS0lzrc3Jy5O3trR49emj8+PHKzc3VqVOnrnq8yr5G+fn5uuGGG9SkSROVlpaWOTcqOztbAQEBevjhhzV+/Hh9/fXXKi0trdwTcA1509PTlZmZKenH88U6deqkgIAA7dq1S0uXLlVqaqpyc3Ovq1DWRHl5eQoICFDDhg11/vx5rV69WpLUtWtXffDBBzp37pxKS0v17rvvuh4TERGh1NRUV2FwOp366quv3JYpNDRUe/bscY1grFq1qtw2ubm5OnfunMLDwzV69GjVr19f2dnZbstwOWfOnNGNN94oHx8fffPNN66/KUm6++67Xc9fdna2tmzZ4tZj+/v7Kz8/35WjZcuWkqTVq1eXuWJy0aJFKikp0Zo1a/Tmm29q7969lTrOhd8hKytLe/bsUWhoaLnjV+Ry7yVJCggIuOxjAwIC1LFjx//bvv27tK6GcQD/WlQKRpK2oCA6VBAHHSpYcKmCDgZJ1UFwcxAs1kEslkpaDbRdSlscdHMqCiKYSfwHXF0EXXRwEnEQOoho0TTnDmK4Pd5e9Vw9nhu/nzEheX/kDXnyvu9jBUHn5+c4PT21yv1V1drxGaqNR0EQUCqVrJ/Hh4cHGIZhzZ5ub29X3Oe1Pv4nb23n4OAgNjY2rJ/CYrGIi4sLNDQ0oKenB4VCoaI9wNMe5ufA/Pr6GgcHB+jr63tX/ej9vtVMnSRJWF9fRyaTwd3dnbWZ/0+yu7uLYrGIVCplHVNV9cvqU19fj9XV1YpEiZaWFuu8qqrQNA2NjY2QZdk6fnZ2ZmUQm6aJUCiE5ubmV8t77zPq7OyELMsYGRmBy+XCwMCA9bE8PDxEoVCAw+GAaZpIJpMfugEdeFpqyGaziEajMAwDbrcbuVwONzc3WFxcRCaTgcfjQT6fx+TkJHw+n7V0/38XCASwt7eH4eFhuFwu9Pb24uTkBENDQzg6OsLo6ChEUYTP57MCc7/fj4WFBYTDYZTLZTw+PkKWZXR3d39InTweD9LpNGZnZ+F0OisSJZ5dXV1hZWUFhmGgXC6jv7//Uz/az8LhMGKxGHRdh9frhd/vt84lEgnEYjHs7++jtbXV2u7wUaanpzE1NQWn0wlVVTE3NwdRFBEIBCBJEgDg+PgYm5ub0HUdbrcb6XQakUgEuq5DEIQ3lVMulzE+Po77+3ukUil4PJ4X5W9tbb24rtpYAp7eca/XC0VR0N7ejrW1tYpr8/k8NE1DoVBAbW0tstmstcLxq6q14zNUG48OhwPBYBDBYBCiKGJnZwfz8/OYmJiAJEkvkjd+7uPXEiWAt7czHo8jl8thbGwMNTU1qKurQzweR1tbG/L5PJLJJBRFgcPhgKIoCIVCWF5ehqZpCAaDAIBoNIqOjo7/3mH0r2p+/PhbKiMR0Qe4vb2FIAgwTROJRAJNTU2IRCJfXS36RD9nwtOfjc/Lnr7VTB0R/R5LS0u4vLxEqVRCV1cXZmZmvrpKRES2x5k6IiIiIhv4VokSRERERHbFoI6IiIjIBhjUEREREdkAgzoiIiIiG2BQR0RERGQDDOqIiIiIbOAvF2TfJBn+6VQAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nogPhyfVO70G"
+ },
+ "source": [
+ "### Construir e treinar o(s) modelo(s)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0BhLZJhibVNG"
+ },
+ "source": [
+ "X_boston = df_boston.drop(columns = ['preco'], axis = 1)\n",
+ "y_boston = df_boston['preco']\n"
+ ],
+ "execution_count": 18,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "b50_6tv5h1kY"
+ },
+ "source": [
+ "# Definindo os dataframes de treinamento e teste:\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "\n",
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, y_boston, test_size = 0.2, random_state = 20111974)"
+ ],
+ "execution_count": 19,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SvevXulFiJj1"
+ },
+ "source": [
+ "#### Treinamento do modelo de Regressão Linear"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GVwF3vp8iNff",
+ "outputId": "5157316e-d00f-4ceb-f930-1643e673fd70",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 71
+ }
+ },
+ "source": [
+ "# Importa a library LinearRegression --> Para treinamento da Regressão Linear\n",
+ "from sklearn.linear_model import LinearRegression\n",
+ "\n",
+ "# Library para statmodels\n",
+ "import statsmodels.api as sm"
+ ],
+ "execution_count": 20,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
+ " import pandas.util.testing as tm\n"
+ ],
+ "name": "stderr"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ibX6bCbViW-v"
+ },
+ "source": [
+ "# Instancia o objeto\n",
+ "regressao_linear = LinearRegression()"
+ ],
+ "execution_count": 21,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "M-5wRGUribY0",
+ "outputId": "2e94fc43-b82c-44fd-9580-e8eb0eb325ba",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Treina o modelo usando as amostras/dataset de treinamento: X_treinamento e y_treinamento \n",
+ "regressao_linear.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 22,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 22
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jri-jA1VjmUl",
+ "outputId": "4ff22bd7-5308-482f-a601-f9946ac5106c",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Valor do intercepto\n",
+ "regressao_linear.intercept_"
+ ],
+ "execution_count": 23,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "35.9020918753502"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 23
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VOjadxdxjqtT",
+ "outputId": "eb581dc3-3c7a-4b23-f0e9-77b17e2f0153",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 452
+ }
+ },
+ "source": [
+ "# Coeficientes do modelo de Regressão Linear\n",
+ "coeficientes_regressao_linear = pd.DataFrame([X_treinamento.columns, regressao_linear.coef_]).T\n",
+ "coeficientes_regressao_linear = coeficientes_regressao_linear.rename(columns={0: 'Feature/variável/coluna', 1: 'Coeficientes'})\n",
+ "coeficientes_regressao_linear"
+ ],
+ "execution_count": 24,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Feature/variável/coluna | \n",
+ " Coeficientes | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " crim | \n",
+ " -0.0822083 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " zn | \n",
+ " 0.0428002 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " indus | \n",
+ " 0.0756011 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " chas | \n",
+ " 3.16348 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " nox | \n",
+ " -19.4945 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " rm | \n",
+ " 3.98161 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " age | \n",
+ " 0.00480929 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " dis | \n",
+ " -1.37396 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " rad | \n",
+ " 0.298883 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " tax | \n",
+ " -0.0123962 | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " ptratio | \n",
+ " -0.984657 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " b | \n",
+ " 0.008949 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " lstat | \n",
+ " -0.526478 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Feature/variável/coluna Coeficientes\n",
+ "0 crim -0.0822083\n",
+ "1 zn 0.0428002\n",
+ "2 indus 0.0756011\n",
+ "3 chas 3.16348\n",
+ "4 nox -19.4945\n",
+ "5 rm 3.98161\n",
+ "6 age 0.00480929\n",
+ "7 dis -1.37396\n",
+ "8 rad 0.298883\n",
+ "9 tax -0.0123962\n",
+ "10 ptratio -0.984657\n",
+ "11 b 0.008949\n",
+ "12 lstat -0.526478"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 24
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jwnkhPwDjkhS"
+ },
+ "source": [
+ "#### Usando statmodels"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ltbekHd_k3PH",
+ "outputId": "8df0e302-86fa-425d-ee12-c73460e69a8d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 680
+ }
+ },
+ "source": [
+ "X2_treinamento = sm.add_constant(X_treinamento)\n",
+ "lm_sm = sm.OLS(y_treinamento, X2_treinamento).fit()\n",
+ "print(lm_sm.summary())"
+ ],
+ "execution_count": 25,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " OLS Regression Results \n",
+ "==============================================================================\n",
+ "Dep. Variable: preco R-squared: 0.725\n",
+ "Model: OLS Adj. R-squared: 0.716\n",
+ "Method: Least Squares F-statistic: 78.97\n",
+ "Date: Mon, 26 Oct 2020 Prob (F-statistic): 1.48e-100\n",
+ "Time: 19:31:57 Log-Likelihood: -1214.8\n",
+ "No. Observations: 404 AIC: 2458.\n",
+ "Df Residuals: 390 BIC: 2514.\n",
+ "Df Model: 13 \n",
+ "Covariance Type: nonrobust \n",
+ "==============================================================================\n",
+ " coef std err t P>|t| [0.025 0.975]\n",
+ "------------------------------------------------------------------------------\n",
+ "const 35.9021 6.037 5.947 0.000 24.033 47.771\n",
+ "crim -0.0822 0.045 -1.824 0.069 -0.171 0.006\n",
+ "zn 0.0428 0.016 2.638 0.009 0.011 0.075\n",
+ "indus 0.0756 0.072 1.054 0.292 -0.065 0.217\n",
+ "chas 3.1635 0.997 3.174 0.002 1.204 5.123\n",
+ "nox -19.4945 4.539 -4.295 0.000 -28.418 -10.571\n",
+ "rm 3.9816 0.510 7.802 0.000 2.978 4.985\n",
+ "age 0.0048 0.015 0.312 0.755 -0.025 0.035\n",
+ "dis -1.3740 0.236 -5.827 0.000 -1.838 -0.910\n",
+ "rad 0.2989 0.079 3.760 0.000 0.143 0.455\n",
+ "tax -0.0124 0.004 -2.814 0.005 -0.021 -0.004\n",
+ "ptratio -0.9847 0.156 -6.309 0.000 -1.292 -0.678\n",
+ "b 0.0089 0.003 2.796 0.005 0.003 0.015\n",
+ "lstat -0.5265 0.060 -8.764 0.000 -0.645 -0.408\n",
+ "==============================================================================\n",
+ "Omnibus: 140.799 Durbin-Watson: 2.083\n",
+ "Prob(Omnibus): 0.000 Jarque-Bera (JB): 591.650\n",
+ "Skew: 1.484 Prob(JB): 3.35e-129\n",
+ "Kurtosis: 8.132 Cond. No. 1.51e+04\n",
+ "==============================================================================\n",
+ "\n",
+ "Warnings:\n",
+ "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
+ "[2] The condition number is large, 1.51e+04. This might indicate that there are\n",
+ "strong multicollinearity or other numerical problems.\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YM4pbCw_iMKX",
+ "outputId": "79b06023-8d21-4791-fae7-decb5a82ddc6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 663
+ }
+ },
+ "source": [
+ "X3 = X2_treinamento.drop(columns = 'age', axis = 1)\n",
+ "X3_treinamento = sm.add_constant(X3)\n",
+ "lm_sm3 = sm.OLS(y_treinamento, X3_treinamento).fit()\n",
+ "print(lm_sm3.summary())\n"
+ ],
+ "execution_count": 29,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " OLS Regression Results \n",
+ "==============================================================================\n",
+ "Dep. Variable: preco R-squared: 0.725\n",
+ "Model: OLS Adj. R-squared: 0.716\n",
+ "Method: Least Squares F-statistic: 85.75\n",
+ "Date: Mon, 26 Oct 2020 Prob (F-statistic): 1.64e-101\n",
+ "Time: 20:10:30 Log-Likelihood: -1214.8\n",
+ "No. Observations: 404 AIC: 2456.\n",
+ "Df Residuals: 391 BIC: 2508.\n",
+ "Df Model: 12 \n",
+ "Covariance Type: nonrobust \n",
+ "==============================================================================\n",
+ " coef std err t P>|t| [0.025 0.975]\n",
+ "------------------------------------------------------------------------------\n",
+ "const 35.7325 6.006 5.950 0.000 23.925 47.540\n",
+ "crim -0.0815 0.045 -1.812 0.071 -0.170 0.007\n",
+ "zn 0.0422 0.016 2.623 0.009 0.011 0.074\n",
+ "indus 0.0750 0.072 1.048 0.295 -0.066 0.216\n",
+ "chas 3.1794 0.994 3.198 0.001 1.225 5.134\n",
+ "nox -19.1299 4.381 -4.367 0.000 -27.742 -10.517\n",
+ "rm 4.0153 0.498 8.059 0.000 3.036 4.995\n",
+ "dis -1.3963 0.224 -6.223 0.000 -1.837 -0.955\n",
+ "rad 0.2958 0.079 3.755 0.000 0.141 0.451\n",
+ "tax -0.0123 0.004 -2.802 0.005 -0.021 -0.004\n",
+ "ptratio -0.9812 0.156 -6.310 0.000 -1.287 -0.675\n",
+ "b 0.0090 0.003 2.825 0.005 0.003 0.015\n",
+ "lstat -0.5202 0.057 -9.203 0.000 -0.631 -0.409\n",
+ "==============================================================================\n",
+ "Omnibus: 142.363 Durbin-Watson: 2.081\n",
+ "Prob(Omnibus): 0.000 Jarque-Bera (JB): 608.694\n",
+ "Skew: 1.496 Prob(JB): 6.67e-133\n",
+ "Kurtosis: 8.216 Cond. No. 1.48e+04\n",
+ "==============================================================================\n",
+ "\n",
+ "Warnings:\n",
+ "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
+ "[2] The condition number is large, 1.48e+04. This might indicate that there are\n",
+ "strong multicollinearity or other numerical problems.\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jVXj1Cz7i7yy",
+ "outputId": "870d1a70-bc73-4fae-f96d-97dedf69763f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 646
+ }
+ },
+ "source": [
+ "X4 = X3_treinamento.drop(columns = 'indus', axis = 1)\n",
+ "X4_treinamento = sm.add_constant(X4)\n",
+ "lm_sm4 = sm.OLS(y_treinamento, X4_treinamento).fit()\n",
+ "print(lm_sm4.summary())"
+ ],
+ "execution_count": 31,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " OLS Regression Results \n",
+ "==============================================================================\n",
+ "Dep. Variable: preco R-squared: 0.724\n",
+ "Model: OLS Adj. R-squared: 0.716\n",
+ "Method: Least Squares F-statistic: 93.42\n",
+ "Date: Mon, 26 Oct 2020 Prob (F-statistic): 2.86e-102\n",
+ "Time: 20:11:16 Log-Likelihood: -1215.4\n",
+ "No. Observations: 404 AIC: 2455.\n",
+ "Df Residuals: 392 BIC: 2503.\n",
+ "Df Model: 11 \n",
+ "Covariance Type: nonrobust \n",
+ "==============================================================================\n",
+ " coef std err t P>|t| [0.025 0.975]\n",
+ "------------------------------------------------------------------------------\n",
+ "const 35.4757 6.001 5.911 0.000 23.677 47.275\n",
+ "crim -0.0840 0.045 -1.871 0.062 -0.172 0.004\n",
+ "zn 0.0407 0.016 2.539 0.012 0.009 0.072\n",
+ "chas 3.2924 0.989 3.330 0.001 1.349 5.236\n",
+ "nox -17.9558 4.235 -4.239 0.000 -26.283 -9.629\n",
+ "rm 3.9674 0.496 7.996 0.000 2.992 4.943\n",
+ "dis -1.4553 0.217 -6.699 0.000 -1.882 -1.028\n",
+ "rad 0.2744 0.076 3.606 0.000 0.125 0.424\n",
+ "tax -0.0103 0.004 -2.603 0.010 -0.018 -0.003\n",
+ "ptratio -0.9609 0.154 -6.227 0.000 -1.264 -0.658\n",
+ "b 0.0089 0.003 2.778 0.006 0.003 0.015\n",
+ "lstat -0.5151 0.056 -9.145 0.000 -0.626 -0.404\n",
+ "==============================================================================\n",
+ "Omnibus: 142.123 Durbin-Watson: 2.073\n",
+ "Prob(Omnibus): 0.000 Jarque-Bera (JB): 605.868\n",
+ "Skew: 1.494 Prob(JB): 2.74e-132\n",
+ "Kurtosis: 8.202 Cond. No. 1.47e+04\n",
+ "==============================================================================\n",
+ "\n",
+ "Warnings:\n",
+ "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
+ "[2] The condition number is large, 1.47e+04. This might indicate that there are\n",
+ "strong multicollinearity or other numerical problems.\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MRKRHcsqjGlc",
+ "outputId": "0215400b-657b-4c9c-cd11-0159e2ca5f6a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 629
+ }
+ },
+ "source": [
+ "X5 = X4_treinamento.drop(columns = 'crim', axis = 1)\n",
+ "X5_treinamento = sm.add_constant(X5)\n",
+ "lm_sm5 = sm.OLS(y_treinamento, X5_treinamento).fit()\n",
+ "print(lm_sm5.summary())"
+ ],
+ "execution_count": 33,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " OLS Regression Results \n",
+ "==============================================================================\n",
+ "Dep. Variable: preco R-squared: 0.721\n",
+ "Model: OLS Adj. R-squared: 0.714\n",
+ "Method: Least Squares F-statistic: 101.8\n",
+ "Date: Mon, 26 Oct 2020 Prob (F-statistic): 1.55e-102\n",
+ "Time: 20:11:56 Log-Likelihood: -1217.2\n",
+ "No. Observations: 404 AIC: 2456.\n",
+ "Df Residuals: 393 BIC: 2500.\n",
+ "Df Model: 10 \n",
+ "Covariance Type: nonrobust \n",
+ "==============================================================================\n",
+ " coef std err t P>|t| [0.025 0.975]\n",
+ "------------------------------------------------------------------------------\n",
+ "const 33.9950 5.968 5.696 0.000 22.262 45.728\n",
+ "zn 0.0375 0.016 2.349 0.019 0.006 0.069\n",
+ "chas 3.3959 0.990 3.430 0.001 1.449 5.343\n",
+ "nox -17.1637 4.228 -4.060 0.000 -25.475 -8.852\n",
+ "rm 4.0365 0.496 8.132 0.000 3.061 5.012\n",
+ "dis -1.3999 0.216 -6.484 0.000 -1.824 -0.975\n",
+ "rad 0.2278 0.072 3.158 0.002 0.086 0.370\n",
+ "tax -0.0100 0.004 -2.513 0.012 -0.018 -0.002\n",
+ "ptratio -0.9493 0.155 -6.137 0.000 -1.253 -0.645\n",
+ "b 0.0101 0.003 3.217 0.001 0.004 0.016\n",
+ "lstat -0.5315 0.056 -9.523 0.000 -0.641 -0.422\n",
+ "==============================================================================\n",
+ "Omnibus: 140.245 Durbin-Watson: 2.070\n",
+ "Prob(Omnibus): 0.000 Jarque-Bera (JB): 609.563\n",
+ "Skew: 1.464 Prob(JB): 4.32e-133\n",
+ "Kurtosis: 8.257 Cond. No. 1.46e+04\n",
+ "==============================================================================\n",
+ "\n",
+ "Warnings:\n",
+ "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
+ "[2] The condition number is large, 1.46e+04. This might indicate that there are\n",
+ "strong multicollinearity or other numerical problems.\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UafIUrpZB0YP"
+ },
+ "source": [
+ "### Conclusão\n",
+ "* Quais variáveis/colunas/atributos ficam no modelo?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nXeiFtnJO_1u"
+ },
+ "source": [
+ "### Validação do(s) modelo(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "QlGVFA6uPDvr"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PE3aKJ6mPDyJ"
+ },
+ "source": [
+ "### Predições"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5YQF4NIlGSLH"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "UQfpoo1igFy8"
+ },
+ "source": [
+ "# Regularized Regression Methods \n",
+ "## Ridge Regression - Penalized Regression\n",
+ "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando (valor de $\\alpha$) os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n",
+ "* Menor impacto dos outliers.\n",
+ "\n",
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "p1BKT6sRu-1p"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Kp4VIJWxgFy8"
+ },
+ "source": [
+ "from sklearn.linear_model import Ridge\n",
+ "ridge = Ridge(alpha = .1)\n",
+ "lr = LinearRegression()"
+ ],
+ "execution_count": 34,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cmRMoOwV6FMt",
+ "outputId": "8029d6ca-7c6e-4c63-ae18-53ecfad97ada",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "ridge = Ridge(alpha = .1)\n",
+ "ridge.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 35,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Ridge(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=None,\n",
+ " normalize=False, random_state=None, solver='auto', tol=0.001)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 35
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VPnekyUbK6Xg"
+ },
+ "source": [
+ "#### Peso/contribuição das variáveis para a regressão usando RIDGE"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-VxmbdkHtPWb",
+ "outputId": "750557fc-e0af-4cc5-bc8f-43970645e901",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 68
+ }
+ },
+ "source": [
+ "df_boston.columns"
+ ],
+ "execution_count": 42,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Index(['crim', 'zn', 'indus', 'chas', 'nox', 'rm', 'age', 'dis', 'rad', 'tax',\n",
+ " 'ptratio', 'b', 'lstat', 'preco'],\n",
+ " dtype='object')"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 42
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vMCb0CFjK973",
+ "outputId": "930f717d-a475-479b-b738-47bb36e965c8",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 85
+ }
+ },
+ "source": [
+ "ridge.coef_"
+ ],
+ "execution_count": 36,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([-8.08728088e-02, 4.31105323e-02, 6.96774448e-02, 3.14478949e+00,\n",
+ " -1.79983020e+01, 3.98675653e+00, 3.54464890e-03, -1.35303958e+00,\n",
+ " 2.95042916e-01, -1.25115273e-02, -9.68282109e-01, 9.02744064e-03,\n",
+ " -5.29135646e-01])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 36
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZqksuIjXypRJ",
+ "outputId": "81ed8a07-36c4-49c8-c99a-b1cb219e744b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# treinando a regressão Ridge\n",
+ "ridge.fit(X_treinamento, y_treinamento)\n",
+ "\n",
+ "# treinando a regressão linear simples (OLS)\n",
+ "lr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 37,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 37
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7r28PBsWLtjA",
+ "outputId": "45ab4dc6-4090-4ab1-bfe8-9f750ba2e85a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "ridge.alpha"
+ ],
+ "execution_count": 38,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.1"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 38
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "hRMK_QTmNgc1",
+ "outputId": "67d8e823-fabb-42d2-ad45-6b4a9b37e5b7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 51
+ }
+ },
+ "source": [
+ "# maior alpha --> mais restrição aos coeficientes; \n",
+ "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS\n",
+ "#rr = Ridge(alpha = 0.01)\n",
+ "rr = Ridge(alpha = 0.01)\n",
+ "rr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": 58,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Ridge(alpha=0.01, copy_X=True, fit_intercept=True, max_iter=None,\n",
+ " normalize=False, random_state=None, solver='auto', tol=0.001)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 58
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IRuWmBE7Ngc7"
+ },
+ "source": [
+ "# MSE\n",
+ "from sklearn.metrics import mean_squared_error\n",
+ "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n",
+ "lr_model=(mean_squared_error(y_true = y_treinamento, y_pred = lr.predict(X_treinamento)))\n"
+ ],
+ "execution_count": 59,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "B9pzuxOlukoJ",
+ "outputId": "4fa3f913-32f4-4024-a8c0-3502d94c1eb7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "print(rr_model)"
+ ],
+ "execution_count": 60,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "23.94639697817076\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RXg_PAaGubh7",
+ "outputId": "9f20b504-fcfd-4f0d-b217-907dbeec84de",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "print(lr_model)"
+ ],
+ "execution_count": 61,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "23.946319854597377\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NEaj4QRrNgdA"
+ },
+ "source": [
+ "rr100 = Ridge(alpha=100)\n",
+ "rr100.fit(X_treinamento, y_treinamento)\n",
+ "train_score=lr.score(X_treinamento, y_treinamento)\n",
+ "test_score=lr.score(X_teste, y_teste)\n",
+ "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)"
+ ],
+ "execution_count": 44,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zhcfoTEENgdE",
+ "outputId": "cfc27d00-a0b6-4cde-9e96-2fa541bea2ce",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# MSE\n",
+ "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n",
+ "print(rr100_model)"
+ ],
+ "execution_count": 45,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "26.460105089888508\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cEF_3GgUgF0Q"
+ },
+ "source": [
+ "# Lasso\n",
+ "* Reduz overfitting;\n",
+ "* Se encarrega do Feature Selection, pois descarta variáveis altamente correlacionadas."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "-YiKb9reQdI4"
+ },
+ "source": [
+ "* Usado no processo de Regularization - processo de penalizar as variáveis para manter somente os atributos mais importantes. Pense na utilidade disso diante de um dataframe com muitas variáveis;\n",
+ "* A regressão Lasso vem com um parâmetro ($\\alpha$), e quanto maior o alfa, a maioria dos coeficientes de recurso é zero. Ou seja, quando $\\alpha = 0$, a regressão Lasso produz os mesmos coeficientes que uma regressão linear. Quando alfa é muito grande, todos os coeficientes são zero."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ME6v6LFlgF0Q",
+ "outputId": "dcfa9e54-ffe1-476a-f236-77d92193c7b6",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 67
+ }
+ },
+ "source": [
+ "from sklearn.linear_model import Lasso\n",
+ "lasso = Lasso(alpha = .1)\n",
+ "lasso.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,\n",
+ " normalize=False, positive=False, precompute=False, random_state=None,\n",
+ " selection='cyclic', tol=0.0001, warm_start=False)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 197
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "h6DSEHc1gF0V",
+ "outputId": "03e88d83-e311-4fc6-fadc-db9483c4092f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 84
+ }
+ },
+ "source": [
+ "lasso.coef_"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([-6.53050169e-02, 4.69929493e-02, 2.03045631e-03, 1.56638852e+00,\n",
+ " -0.00000000e+00, 3.77954671e+00, -6.40432403e-03, -1.06129312e+00,\n",
+ " 2.58073061e-01, -1.42708307e-02, -7.81773992e-01, 9.95091849e-03,\n",
+ " -5.87452824e-01])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 198
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xP1fX1Bi6VdX"
+ },
+ "source": [
+ "Coeficientes zero podem ser excluídos da Análise/modelo."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9P7hYoo4gF0Z"
+ },
+ "source": [
+ "# Elastic Net \n",
+ "* Combina o poder de Ridge e LASSO;\n",
+ "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yChNUYs7gF0b"
+ },
+ "source": [
+ "from sklearn.linear_model import ElasticNet\n",
+ "from sklearn.model_selection import GridSearchCV\n",
+ "\n",
+ "# Instancia o objeto\n",
+ "en = ElasticNet(alpha = .1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4mbIaAUAF4N6",
+ "outputId": "0a0b7576-7240-419d-d7b3-871f34f141f4",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 67
+ }
+ },
+ "source": [
+ "en.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "ElasticNet(alpha=0.1, copy_X=True, fit_intercept=True, l1_ratio=0.5,\n",
+ " max_iter=1000, normalize=False, positive=False, precompute=False,\n",
+ " random_state=None, selection='cyclic', tol=0.0001, warm_start=False)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 203
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MaUkZw8ngF0h",
+ "outputId": "5d6db1e6-1d99-46da-bdb8-c4e1054dc2df",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 84
+ }
+ },
+ "source": [
+ "en.coef_"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([-7.14375105e-02, 4.98062892e-02, 3.25764298e-03, 1.32398367e+00,\n",
+ " -1.16648025e-01, 3.29040345e+00, -3.09984870e-03, -1.07673872e+00,\n",
+ " 2.80823236e-01, -1.50703816e-02, -8.13376450e-01, 9.70397656e-03,\n",
+ " -6.21886279e-01])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 204
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xl-Qh9caDyCp"
+ },
+ "source": [
+ "# Instancia o objeto:\n",
+ "en = ElasticNet(normalize = True)\n",
+ "\n",
+ "# Otimização dos hiperparâmetros:\n",
+ "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n",
+ " 'l1_ratio': [.2, .4, .6, .8]}\n",
+ "\n",
+ "search = GridSearchCV(estimator = en, \n",
+ " param_grid = d_hiperparametros, \n",
+ " scoring = 'neg_mean_squared_error', \n",
+ " n_jobs = 1,\n",
+ " refit = True, \n",
+ " cv = 10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "c3_XCQCPGlr3",
+ "outputId": "bd72fa59-54a2-43f0-fc29-536fbb41cf99",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "search.fit(X_treinamento, y_treinamento)\n",
+ "search.best_params_"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'alpha': 0.0001, 'l1_ratio': 0.4}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 181
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "zq0_ugQfGrdb",
+ "outputId": "9965249d-2280-4d0c-c568-0d7c892f6c3b",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n",
+ "en2.fit(X_treinamento, y_treinamento)\n",
+ "\n",
+ "# Métrica\n",
+ "ml2 = (mean_squared_error(y_true = y_teste, y_pred = en2.predict(X_teste)))\n",
+ "print(ml2)"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "15.410850398354446\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "aoxf9KKYOjEd"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "sUUrajAxOkHg"
+ },
+ "source": [
+ "# Regularized Regression Methods \n",
+ "## Ridge Regression - Penalized Regression\n",
+ "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n",
+ "* Menor impacto dos outliers.\n",
+ "\n",
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VVBd5g8NOkHh"
+ },
+ "source": [
+ "from sklearn.linear_model import Ridge\n",
+ "ridge = Ridge(alpha = .1)\n",
+ "lr = LinearRegression()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "o00xH2MvxvgP"
+ },
+ "source": [
+ "# Matriz de covariáveis do modelo:\n",
+ "X_new = [[0, 0], [0, 0], [1, 1]]\n",
+ "y_new = [0, .1, 1]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "v9U7c03NzW_c"
+ },
+ "source": [
+ "X_new"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "iiVEAPpUzXyN"
+ },
+ "source": [
+ "y_new"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8mWj2GbPOkHx"
+ },
+ "source": [
+ "ridge = Ridge(alpha = .1)\n",
+ "ridge.fit(X_new, y_new)\n",
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0kD7Bsq_OkH1"
+ },
+ "source": [
+ "# treinando a regressão Ridge\n",
+ "ridge.fit(X, y)\n",
+ "\n",
+ "# treinando a regressão linear simples (OLS)\n",
+ "lr.fit(X, y)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aUEyK4lygFy_"
+ },
+ "source": [
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qYRLUwIugFzC"
+ },
+ "source": [
+ "lr.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "URcHb6uggFzF"
+ },
+ "source": [
+ "# Adicionar alguns outliers aos dados\n",
+ "outliers = y[950:] - 600\n",
+ "outliers"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "AqA2dFQWgFzH"
+ },
+ "source": [
+ "import numpy as np\n",
+ "y_outlier = np.append(y[:950], outliers)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3YRDzmZkgFzL"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier, s=5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_wFZ_AX1gFzU"
+ },
+ "source": [
+ "lr = LinearRegression()\n",
+ "lr.fit(X, y_outlier)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7NYzB9nEgFze"
+ },
+ "source": [
+ "y_pred_outliers= lr.predict(X)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "E7aaUXzDgFzh"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier,s=5,label='actual')\n",
+ "plt.scatter(X, y_pred_outliers,s=5,label='prediction with outliers')\n",
+ "plt.scatter(X, y_pred,s=5,c='k', label='prediction sem outlier')\n",
+ "plt.legend()\n",
+ "plt.title('Linear Regression')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LON9hAomgFzl"
+ },
+ "source": [
+ "lr.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m3Yu7pAigFzt"
+ },
+ "source": [
+ "ridge = Ridge(alpha = 1000)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xB9fKEImgFzw"
+ },
+ "source": [
+ "ridge.fit(X, y_outlier)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U4DxOv8EgFzz"
+ },
+ "source": [
+ "y_pred_ridge = ridge.predict(X)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vVWQuFVegFz2"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier, s = 5,label = 'actual')\n",
+ "plt.scatter(X, y_pred_outliers, s = 5, c = 'r' ,label = 'LinearRegression with outliers')\n",
+ "plt.scatter(X, y_pred_ridge, s = 5, c = 'k', label = 'RidgeRegression with outlier')\n",
+ "plt.legend()\n",
+ "plt.title('Linear Regression')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "seq5MCvDgFz5"
+ },
+ "source": [
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0d0DL3YYgFz-"
+ },
+ "source": [
+ "## Efeito de $\\alpha$ na Regressão Ridge\n",
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vCA4BvRkgFz_"
+ },
+ "source": [
+ "X, y, w = make_regression(n_samples = 10, \n",
+ " n_features = 10, \n",
+ " coef = True, \n",
+ " random_state = 1, \n",
+ " bias = 3.5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2l2zCIX6gF0D"
+ },
+ "source": [
+ "w"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BSXLQl5COkI8"
+ },
+ "source": [
+ "# Lasso\n",
+ "* Reduz overfitting;\n",
+ "* Se encarrega do Feature Selection, pois descarta variáveis altamente correlacionadas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "i5JZTnkTOkI9"
+ },
+ "source": [
+ "from sklearn.linear_model import Lasso\n",
+ "lasso = Lasso(alpha = .1)\n",
+ "lasso.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gEUxSlThOkJD"
+ },
+ "source": [
+ "lasso.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "90pfP9-3OkJG"
+ },
+ "source": [
+ "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ILCXvYKDOkJH"
+ },
+ "source": [
+ "# Elastic Net \n",
+ "* Combina o poder de Ridge e LASSO;\n",
+ "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GaQPDCR2OkJI"
+ },
+ "source": [
+ "from sklearn.linear_model import ElasticNet\n",
+ "\n",
+ "# Instancia o objeto\n",
+ "en = ElasticNet(alpha = .1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xVp16Eu_OkJL"
+ },
+ "source": [
+ "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kwj018U8OkJO"
+ },
+ "source": [
+ "en.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XTvoKmbY_uXM"
+ },
+ "source": [
+ "# Exemplo completo: Ridge\n",
+ "* Adaptado de [Ridge and Lasso Regression: A Complete Guide with Python Scikit-Learn](https://towardsdatascience.com/ridge-and-lasso-regression-a-complete-guide-with-python-scikit-learn-e20e34bcbf0b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "If7A_ceC_wW4"
+ },
+ "source": [
+ "from sklearn.datasets import load_boston\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "from sklearn.linear_model import LinearRegression\n",
+ "from sklearn.linear_model import Ridge\n",
+ "\n",
+ "from sklearn.metrics import mean_squared_error"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "93n7uz0X_367"
+ },
+ "source": [
+ "boston = load_boston()\n",
+ "df_Boston = pd.DataFrame(boston.data, columns = boston.feature_names)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EqRuXuzB_8Ge"
+ },
+ "source": [
+ "X_boston = boston.data\n",
+ "y_boston = boston.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NztUeubIACuA"
+ },
+ "source": [
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, y_boston, test_size = 0.2, random_state = 20111974)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "QNwBSc1FAEoB"
+ },
+ "source": [
+ "lr = LinearRegression()\n",
+ "lr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r9BrlLSIAHS3"
+ },
+ "source": [
+ "# maior alpha --> mais restrição aos coeficientes; \n",
+ "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS\n",
+ "rr = Ridge(alpha = 0.01)\n",
+ "rr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dchr1UwjEn-A"
+ },
+ "source": [
+ "# MSE\n",
+ "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n",
+ "print(rr_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Fnic6PY-CV-P"
+ },
+ "source": [
+ "rr100 = Ridge(alpha=100)\n",
+ "rr100.fit(X_treinamento, y_treinamento)\n",
+ "train_score=lr.score(X_treinamento, y_treinamento)\n",
+ "test_score=lr.score(X_teste, y_teste)\n",
+ "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "TIe76z26EdG5"
+ },
+ "source": [
+ "# MSE\n",
+ "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n",
+ "print(rr100_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dAuvhdNdAJ7C"
+ },
+ "source": [
+ "Ridge_teste_score = rr.score(X_teste, y_teste)\n",
+ "Ridge_treinamento_score100 = rr100.score(X_treinamento, y_treinamento)\n",
+ "Ridge_teste_score100 = rr100.score(X_teste, y_teste)\n",
+ "print(\"linear regression train score:\", train_score)\n",
+ "print(\"linear regression test score:\", test_score)\n",
+ "print(\"ridge regression train score low alpha:\", Ridge_treinamento_score)\n",
+ "print(\"ridge regression test score low alpha:\", Ridge_teste_score)\n",
+ "print(\"ridge regression train score high alpha:\", Ridge_treinamento_score100)\n",
+ "print(\"ridge regression test score high alpha:\", Ridge_teste_score100)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "a0OaweJrCchd"
+ },
+ "source": [
+ "plt.plot(rr.coef_, \n",
+ " alpha = 0.7, \n",
+ " linestyle = 'none', \n",
+ " marker = '*', \n",
+ " markersize = 5, \n",
+ " color = 'red', \n",
+ " label = r'Ridge; \n",
+ " $\\alpha = 0.01$', \n",
+ " zorder = 7) # zorder for ordering the markers\n",
+ "\n",
+ "plt.plot(rr100.coef_,alpha = 0.5, \n",
+ " linestyle = 'none', \n",
+ " marker = 'd', \n",
+ " markersize = 6, \n",
+ " color = 'blue', \n",
+ " label = r'Ridge; \n",
+ " $\\alpha = 100$') # alpha here is for transparency\n",
+ "\n",
+ "plt.plot(lr.coef_, \n",
+ " alpha = 0.4, \n",
+ " linestyle = 'none', \n",
+ " marker = 'o', \n",
+ " markersize = 7, \n",
+ " color = 'green', \n",
+ " label = 'Linear Regression')\n",
+ "\n",
+ "plt.xlabel('Coefficient Index', fontsize = 16)\n",
+ "plt.ylabel('Coefficient Magnitude',fontsize = 16)\n",
+ "plt.legend(fontsize = 13, loc = 4)\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PEtGRcl-EHaF"
+ },
+ "source": [
+ "from sklearn.metrics import mean_squared_error\n",
+ "rr_model=(mean_squared_error(y_true= y, y_pred=regression.predict(X)))\n",
+ "print(first_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_dwlPByHDipf"
+ },
+ "source": [
+ "# Exemplo completo - Elastic Net"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yhbIfGnfOkKF"
+ },
+ "source": [
+ "from sklearn.linear_model import ElasticNet\n",
+ "from sklearn.model_selection import GridSearchCV\n",
+ "\n",
+ "# Instancia o objeto:\n",
+ "en = ElasticNet(normalize = True)\n",
+ "\n",
+ "# Otimização dos hiperparâmetros:\n",
+ "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n",
+ " 'l1_ratio': [.2, .4, .6, .8]}\n",
+ "\n",
+ "search = GridSearchCV(estimator = en, \n",
+ " param_grid = d_hiperparametros, \n",
+ " scoring = 'neg_mean_squared_error', \n",
+ " n_jobs = 1,\n",
+ " refit = True, \n",
+ " cv = 10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "yDPkRazPOkKJ"
+ },
+ "source": [
+ "search.fit(X, y)\n",
+ "search.best_params_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "D_K-f8KCOkKM"
+ },
+ "source": [
+ "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n",
+ "en2.fit(X, y)\n",
+ "\n",
+ "ml2 = (mean_squared_error(y_true = y, y_pred = en2.predict(X)))\n",
+ "print(ml2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "a5o7FiRm9_vb"
+ },
+ "source": [
+ "# Exercício 1 - Regressão Linear - Mall_Customers.csv\n",
+ "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n",
+ "\n",
+ "* Experimente:\n",
+ " * Lasso(alpha = 0.01, max_iter = 10e5);\n",
+ " * Lasso(alpha = 0.0001, max_iter = 10e5);\n",
+ " * Ridge(alpha = 0.01);\n",
+ " * Ridge(alpha = 100);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rJRWBzSQCcss"
+ },
+ "source": [
+ "# Regressão Logística"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Ucn0pQThO1eN"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XwuMfMD1gFyd"
+ },
+ "source": [
+ "# Exemplo para regressão LOGÍSTICA!!!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "efF3st3sHxPG"
+ },
+ "source": [
+ "# Carrega as bibliotecas\n",
+ "import numpy as np\n",
+ "np.set_printoptions(formatter = {'float': lambda x: \"{0:0.2f}\".format(x)})\n",
+ "\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "import statsmodels.api as sm\n",
+ "\n",
+ "%matplotlib inline"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Bk9F6JO0IELv",
+ "outputId": "71d6cdf3-6eb8-4e0a-9829-67d301b60b97",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 195
+ }
+ },
+ "source": [
+ "# Carregar/ler o banco de dados - Dataframe Diabetes\n",
+ "from sklearn import datasets\n",
+ "#Diabetes = datasets.load_diabetes()\n",
+ "\n",
+ "url = 'https://raw.githubusercontent.com/MathMachado/DSWP/master/Dataframes/diabetes.csv'\n",
+ "diabetes = pd.read_csv(url)\n",
+ "diabetes.head()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Pregnancies | \n",
+ " Glucose | \n",
+ " BloodPressure | \n",
+ " SkinThickness | \n",
+ " Insulin | \n",
+ " BMI | \n",
+ " DiabetesPedigreeFunction | \n",
+ " Age | \n",
+ " Outcome | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 6 | \n",
+ " 148 | \n",
+ " 72 | \n",
+ " 35 | \n",
+ " 0 | \n",
+ " 33.6 | \n",
+ " 0.627 | \n",
+ " 50 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1 | \n",
+ " 85 | \n",
+ " 66 | \n",
+ " 29 | \n",
+ " 0 | \n",
+ " 26.6 | \n",
+ " 0.351 | \n",
+ " 31 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 8 | \n",
+ " 183 | \n",
+ " 64 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 23.3 | \n",
+ " 0.672 | \n",
+ " 32 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " 89 | \n",
+ " 66 | \n",
+ " 23 | \n",
+ " 94 | \n",
+ " 28.1 | \n",
+ " 0.167 | \n",
+ " 21 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 0 | \n",
+ " 137 | \n",
+ " 40 | \n",
+ " 35 | \n",
+ " 168 | \n",
+ " 43.1 | \n",
+ " 2.288 | \n",
+ " 33 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Pregnancies Glucose BloodPressure ... DiabetesPedigreeFunction Age Outcome\n",
+ "0 6 148 72 ... 0.627 50 1\n",
+ "1 1 85 66 ... 0.351 31 0\n",
+ "2 8 183 64 ... 0.672 32 1\n",
+ "3 1 89 66 ... 0.167 21 0\n",
+ "4 0 137 40 ... 2.288 33 1\n",
+ "\n",
+ "[5 rows x 9 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 21
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "tjRmpaPIDknb",
+ "outputId": "b5102f14-cfa1-4354-9167-e6d8fbf313cc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 195
+ }
+ },
+ "source": [
+ "# Definir as matrizes X e y\n",
+ "X_diabetes = diabetes.copy()\n",
+ "X_diabetes.drop(columns = ['Outcome'], axis = 1, inplace = True)\n",
+ "y_diabetes = diabetes['Outcome']\n",
+ "\n",
+ "X_diabetes.head()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Pregnancies | \n",
+ " Glucose | \n",
+ " BloodPressure | \n",
+ " SkinThickness | \n",
+ " Insulin | \n",
+ " BMI | \n",
+ " DiabetesPedigreeFunction | \n",
+ " Age | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 6 | \n",
+ " 148 | \n",
+ " 72 | \n",
+ " 35 | \n",
+ " 0 | \n",
+ " 33.6 | \n",
+ " 0.627 | \n",
+ " 50 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1 | \n",
+ " 85 | \n",
+ " 66 | \n",
+ " 29 | \n",
+ " 0 | \n",
+ " 26.6 | \n",
+ " 0.351 | \n",
+ " 31 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 8 | \n",
+ " 183 | \n",
+ " 64 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 23.3 | \n",
+ " 0.672 | \n",
+ " 32 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1 | \n",
+ " 89 | \n",
+ " 66 | \n",
+ " 23 | \n",
+ " 94 | \n",
+ " 28.1 | \n",
+ " 0.167 | \n",
+ " 21 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 0 | \n",
+ " 137 | \n",
+ " 40 | \n",
+ " 35 | \n",
+ " 168 | \n",
+ " 43.1 | \n",
+ " 2.288 | \n",
+ " 33 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Pregnancies Glucose BloodPressure ... BMI DiabetesPedigreeFunction Age\n",
+ "0 6 148 72 ... 33.6 0.627 50\n",
+ "1 1 85 66 ... 26.6 0.351 31\n",
+ "2 8 183 64 ... 23.3 0.672 32\n",
+ "3 1 89 66 ... 28.1 0.167 21\n",
+ "4 0 137 40 ... 43.1 2.288 33\n",
+ "\n",
+ "[5 rows x 8 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 24
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jLrx69TH-Mad",
+ "outputId": "0f802232-d17b-4803-fe0f-ef87135f0e01",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "X_diabetes.shape"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(768, 8)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 25
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mdFBioP6-Ply",
+ "outputId": "ffdc7ca3-045c-46ff-e70a-5f26a7157bca",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "y_diabetes.shape"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "(442,)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 6
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "fhLySN65IaDF"
+ },
+ "source": [
+ "# Definir as matrizes de treinamento e validação\n",
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_diabetes, y_diabetes)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J5R8HlnuIGpL",
+ "outputId": "27dbf904-24e8-4013-93b8-007bc1fe36aa",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 67
+ }
+ },
+ "source": [
+ "# Carregar a library LinearRegression()\n",
+ "from sklearn.linear_model import LinearRegression\n",
+ "\n",
+ "# Instanciar o objeto\n",
+ "lr = LinearRegression()\n",
+ "\n",
+ "# Usando statmodels:\n",
+ "x = sm.add_constant(X_treinamento)\n",
+ "lr_sm = sm.Logit(y_treinamento, X_treinamento) # Atenção: aqui é o contrário: [y, x]\n",
+ "\n",
+ "# Treinar o modelo\n",
+ "lr.fit(X_treinamento, y_treinamento)\n",
+ "resultado_sm = lr_sm.fit()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Optimization terminated successfully.\n",
+ " Current function value: 0.596920\n",
+ " Iterations 5\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GlbCaPp1ETNa",
+ "outputId": "93b95119-9395-4677-87db-6a41dc27b940",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 357
+ }
+ },
+ "source": [
+ "resultado_sm.summary()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "Logit Regression Results\n",
+ "\n",
+ " | Dep. Variable: | Outcome | No. Observations: | 576 | \n",
+ "
\n",
+ "\n",
+ " | Model: | Logit | Df Residuals: | 568 | \n",
+ "
\n",
+ "\n",
+ " | Method: | MLE | Df Model: | 7 | \n",
+ "
\n",
+ "\n",
+ " | Date: | Mon, 26 Oct 2020 | Pseudo R-squ.: | 0.05860 | \n",
+ "
\n",
+ "\n",
+ " | Time: | 13:23:03 | Log-Likelihood: | -343.83 | \n",
+ "
\n",
+ "\n",
+ " | converged: | True | LL-Null: | -365.23 | \n",
+ "
\n",
+ "\n",
+ " | Covariance Type: | nonrobust | LLR p-value: | 3.632e-07 | \n",
+ "
\n",
+ "
\n",
+ "\n",
+ "\n",
+ " | coef | std err | z | P>|z| | [0.025 | 0.975] | \n",
+ "
\n",
+ "\n",
+ " | Pregnancies | 0.1447 | 0.033 | 4.364 | 0.000 | 0.080 | 0.210 | \n",
+ "
\n",
+ "\n",
+ " | Glucose | 0.0116 | 0.003 | 3.614 | 0.000 | 0.005 | 0.018 | \n",
+ "
\n",
+ "\n",
+ " | BloodPressure | -0.0318 | 0.006 | -5.574 | 0.000 | -0.043 | -0.021 | \n",
+ "
\n",
+ "\n",
+ " | SkinThickness | 0.0022 | 0.007 | 0.300 | 0.764 | -0.012 | 0.017 | \n",
+ "
\n",
+ "\n",
+ " | Insulin | 0.0014 | 0.001 | 1.476 | 0.140 | -0.000 | 0.003 | \n",
+ "
\n",
+ "\n",
+ " | BMI | -0.0012 | 0.013 | -0.094 | 0.925 | -0.027 | 0.025 | \n",
+ "
\n",
+ "\n",
+ " | DiabetesPedigreeFunction | 0.0411 | 0.283 | 0.145 | 0.885 | -0.514 | 0.596 | \n",
+ "
\n",
+ "\n",
+ " | Age | -0.0145 | 0.010 | -1.474 | 0.140 | -0.034 | 0.005 | \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ "\n",
+ "\"\"\"\n",
+ " Logit Regression Results \n",
+ "==============================================================================\n",
+ "Dep. Variable: Outcome No. Observations: 576\n",
+ "Model: Logit Df Residuals: 568\n",
+ "Method: MLE Df Model: 7\n",
+ "Date: Mon, 26 Oct 2020 Pseudo R-squ.: 0.05860\n",
+ "Time: 13:23:03 Log-Likelihood: -343.83\n",
+ "converged: True LL-Null: -365.23\n",
+ "Covariance Type: nonrobust LLR p-value: 3.632e-07\n",
+ "============================================================================================\n",
+ " coef std err z P>|z| [0.025 0.975]\n",
+ "--------------------------------------------------------------------------------------------\n",
+ "Pregnancies 0.1447 0.033 4.364 0.000 0.080 0.210\n",
+ "Glucose 0.0116 0.003 3.614 0.000 0.005 0.018\n",
+ "BloodPressure -0.0318 0.006 -5.574 0.000 -0.043 -0.021\n",
+ "SkinThickness 0.0022 0.007 0.300 0.764 -0.012 0.017\n",
+ "Insulin 0.0014 0.001 1.476 0.140 -0.000 0.003\n",
+ "BMI -0.0012 0.013 -0.094 0.925 -0.027 0.025\n",
+ "DiabetesPedigreeFunction 0.0411 0.283 0.145 0.885 -0.514 0.596\n",
+ "Age -0.0145 0.010 -1.474 0.140 -0.034 0.005\n",
+ "============================================================================================\n",
+ "\"\"\""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 37
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "e7hWIjr0J8fd",
+ "outputId": "0c1247dd-d6d3-4d38-b9c5-c90a83458580",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 67
+ }
+ },
+ "source": [
+ "# Coeficientes do modelo\n",
+ "lr.coef_ "
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([ 10.50312025, -263.32615982, 516.66778363, 356.84510148,\n",
+ " -1037.40954808, 731.51011113, 121.62332809, 163.11261651,\n",
+ " 780.54426871, 66.11245968])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 11
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5DVjyWUUKH4t",
+ "outputId": "a58aca10-7682-4ccd-97d7-11e19b6d7604",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# Intercepto do modelo\n",
+ "lr.intercept_"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "155.02945244919295"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 12
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-FJaSnJLKICU",
+ "outputId": "4daf587a-5c70-48bc-b563-f14a23b49d0a",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "# EQM - Erro Quadrático Médio\n",
+ "np.mean((lr.predict(X_teste) - y_teste) ** 2) "
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "2998.4466244258106"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 13
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6bVEUSTUPzOj"
+ },
+ "source": [
+ "### Calcular y_pred - os valores preditos de y"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OjGrNhTNLcr-",
+ "outputId": "5577e115-8c38-4451-d10a-d25065e3b9cc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 907
+ }
+ },
+ "source": [
+ "y_pred = lr.predict(X_treinamento)\n",
+ "\n",
+ "# Predit com statmodels\n",
+ "resultado_sm.predict()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.41, 0.34, 0.41, 0.35, 0.18, 0.16, 0.34, 0.56, 0.48, 0.26, 0.16,\n",
+ " 0.34, 0.19, 0.44, 0.23, 0.32, 0.29, 0.11, 0.59, 0.31, 0.33, 0.46,\n",
+ " 0.83, 0.42, 0.16, 0.83, 0.17, 0.40, 0.37, 0.37, 0.35, 0.38, 0.29,\n",
+ " 0.57, 0.37, 0.30, 0.53, 0.37, 0.13, 0.42, 0.93, 0.22, 0.32, 0.52,\n",
+ " 0.23, 0.49, 0.34, 0.20, 0.10, 0.27, 0.28, 0.35, 0.37, 0.27, 0.42,\n",
+ " 0.41, 0.32, 0.54, 0.32, 0.46, 0.32, 0.24, 0.62, 0.49, 0.26, 0.34,\n",
+ " 0.84, 0.60, 0.23, 0.44, 0.48, 0.22, 0.19, 0.23, 0.55, 0.35, 0.13,\n",
+ " 0.38, 0.27, 0.09, 0.44, 0.18, 0.23, 0.35, 0.30, 0.23, 0.36, 0.30,\n",
+ " 0.72, 0.25, 0.24, 0.25, 0.45, 0.75, 0.05, 0.20, 0.67, 0.34, 0.43,\n",
+ " 0.35, 0.32, 0.20, 0.15, 0.17, 0.33, 0.44, 0.52, 0.41, 0.49, 0.27,\n",
+ " 0.20, 0.33, 0.31, 0.41, 0.49, 0.46, 0.82, 0.68, 0.54, 0.30, 0.19,\n",
+ " 0.15, 0.23, 0.38, 0.41, 0.37, 0.32, 0.34, 0.44, 0.17, 0.10, 0.56,\n",
+ " 0.50, 0.32, 0.25, 0.24, 0.27, 0.36, 0.69, 0.40, 0.30, 0.55, 0.49,\n",
+ " 0.35, 0.44, 0.36, 0.30, 0.18, 0.41, 0.15, 0.23, 0.71, 0.17, 0.15,\n",
+ " 0.28, 0.83, 0.56, 0.37, 0.35, 0.32, 0.29, 0.24, 0.27, 0.31, 0.28,\n",
+ " 0.35, 0.30, 0.43, 0.25, 0.23, 0.73, 0.26, 0.35, 0.43, 0.22, 0.32,\n",
+ " 0.33, 0.47, 0.30, 0.82, 0.19, 0.55, 0.54, 0.19, 0.30, 0.27, 0.23,\n",
+ " 0.41, 0.21, 0.61, 0.16, 0.29, 0.34, 0.32, 0.28, 0.24, 0.45, 0.20,\n",
+ " 0.26, 0.24, 0.25, 0.17, 0.28, 0.44, 0.32, 0.42, 0.39, 0.31, 0.25,\n",
+ " 0.35, 0.20, 0.37, 0.54, 0.32, 0.37, 0.41, 0.31, 0.22, 0.09, 0.27,\n",
+ " 0.36, 0.42, 0.19, 0.38, 0.48, 0.42, 0.50, 0.54, 0.31, 0.22, 0.46,\n",
+ " 0.32, 0.22, 0.26, 0.42, 0.35, 0.20, 0.22, 0.18, 0.50, 0.46, 0.25,\n",
+ " 0.48, 0.20, 0.19, 0.16, 0.49, 0.30, 0.70, 0.24, 0.20, 0.33, 0.15,\n",
+ " 0.34, 0.37, 0.14, 0.26, 0.21, 0.91, 0.35, 0.24, 0.20, 0.22, 0.39,\n",
+ " 0.43, 0.50, 0.30, 0.83, 0.21, 0.31, 0.51, 0.35, 0.39, 0.42, 0.30,\n",
+ " 0.48, 0.76, 0.28, 0.19, 0.26, 0.85, 0.30, 0.26, 0.18, 0.17, 0.18,\n",
+ " 0.30, 0.79, 0.57, 0.41, 0.25, 0.27, 0.70, 0.48, 0.56, 0.30, 0.23,\n",
+ " 0.23, 0.49, 0.74, 0.36, 0.31, 0.31, 0.44, 0.39, 0.73, 0.41, 0.36,\n",
+ " 0.91, 0.19, 0.31, 0.29, 0.55, 0.58, 0.47, 0.53, 0.35, 0.51, 0.29,\n",
+ " 0.13, 0.35, 0.52, 0.64, 0.19, 0.24, 0.72, 0.31, 0.42, 0.37, 0.50,\n",
+ " 0.26, 0.23, 0.47, 0.56, 0.31, 0.40, 0.56, 0.37, 0.35, 0.32, 0.36,\n",
+ " 0.65, 0.43, 0.41, 0.28, 0.57, 0.42, 0.22, 0.47, 0.63, 0.15, 0.58,\n",
+ " 0.10, 0.59, 0.16, 0.28, 0.17, 0.43, 0.21, 0.22, 0.22, 0.29, 0.37,\n",
+ " 0.76, 0.73, 0.24, 0.64, 0.45, 0.14, 0.34, 0.44, 0.85, 0.29, 0.45,\n",
+ " 0.63, 0.35, 0.21, 0.38, 0.45, 0.36, 0.19, 0.62, 0.72, 0.29, 0.46,\n",
+ " 0.44, 0.50, 0.26, 0.22, 0.64, 0.26, 0.32, 0.61, 0.67, 0.27, 0.28,\n",
+ " 0.22, 0.36, 0.56, 0.24, 0.36, 0.23, 0.37, 0.50, 0.26, 0.59, 0.15,\n",
+ " 0.29, 0.35, 0.09, 0.09, 0.29, 0.29, 0.43, 0.44, 0.23, 0.20, 0.42,\n",
+ " 0.30, 0.22, 0.19, 0.37, 0.43, 0.29, 0.19, 0.47, 0.26, 0.19, 0.23,\n",
+ " 0.26, 0.42, 0.24, 0.30, 0.38, 0.81, 0.88, 0.44, 0.22, 0.33, 0.29,\n",
+ " 0.51, 0.23, 0.22, 0.48, 0.35, 0.25, 0.45, 0.28, 0.52, 0.32, 0.45,\n",
+ " 0.34, 0.48, 0.46, 0.32, 0.61, 0.26, 0.12, 0.50, 0.48, 0.22, 0.28,\n",
+ " 0.61, 0.35, 0.60, 0.31, 0.44, 0.37, 0.29, 0.87, 0.09, 0.41, 0.50,\n",
+ " 0.29, 0.16, 0.34, 0.29, 0.24, 0.38, 0.32, 0.39, 0.25, 0.56, 0.28,\n",
+ " 0.08, 0.27, 0.37, 0.24, 0.26, 0.35, 0.48, 0.24, 0.33, 0.20, 0.61,\n",
+ " 0.14, 0.31, 0.60, 0.53, 0.62, 0.53, 0.54, 0.35, 0.14, 0.31, 0.42,\n",
+ " 0.21, 0.64, 0.19, 0.38, 0.41, 0.11, 0.27, 0.26, 0.22, 0.36, 0.28,\n",
+ " 0.38, 0.51, 0.08, 0.27, 0.68, 0.38, 0.55, 0.57, 0.49, 0.50, 0.46,\n",
+ " 0.20, 0.28, 0.38, 0.44, 0.37, 0.45, 0.45, 0.22, 0.31, 0.33, 0.26,\n",
+ " 0.21, 0.25, 0.17, 0.33, 0.30, 0.46, 0.26, 0.36, 0.53, 0.52, 0.27,\n",
+ " 0.28, 0.33, 0.27, 0.81, 0.47, 0.27, 0.20, 0.10, 0.27, 0.26, 0.33,\n",
+ " 0.66, 0.58, 0.25, 0.25, 0.29, 0.31, 0.24, 0.35, 0.35, 0.29, 0.24,\n",
+ " 0.69, 0.22, 0.29, 0.55])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 39
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FolXBGbFFUnE",
+ "outputId": "b4e5039d-4e71-40e2-8549-b4bb5f21a7dc",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 605
+ }
+ },
+ "source": [
+ "np.array(diabetes['Outcome'])"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0,\n",
+ " 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,\n",
+ " 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0,\n",
+ " 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,\n",
+ " 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,\n",
+ " 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1,\n",
+ " 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,\n",
+ " 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1,\n",
+ " 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1,\n",
+ " 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1,\n",
+ " 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,\n",
+ " 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0,\n",
+ " 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0,\n",
+ " 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0,\n",
+ " 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0,\n",
+ " 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n",
+ " 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,\n",
+ " 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0,\n",
+ " 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1,\n",
+ " 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,\n",
+ " 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,\n",
+ " 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,\n",
+ " 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,\n",
+ " 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,\n",
+ " 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0,\n",
+ " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n",
+ " 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,\n",
+ " 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0,\n",
+ " 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,\n",
+ " 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,\n",
+ " 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n",
+ " 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0,\n",
+ " 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,\n",
+ " 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0,\n",
+ " 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 40
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pUxasncIFaw4",
+ "outputId": "e799ed76-bcbd-4620-fc98-11b2b998f67f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 50
+ }
+ },
+ "source": [
+ "resultado_sm.pred_table()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([[343.00, 43.00],\n",
+ " [129.00, 61.00]])"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 41
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_liLYinwFgch",
+ "outputId": "6f5743ab-ae7b-4d4e-d23b-5779be359113",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 106
+ }
+ },
+ "source": [
+ "confusion_matrix = pd.DataFrame(resultado_sm.pred_table())\n",
+ "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n",
+ "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n",
+ "confusion_matrix"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Predicted No Diabetes | \n",
+ " Predicted Diabetes | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | Actual No Diabetes | \n",
+ " 343.0 | \n",
+ " 43.0 | \n",
+ "
\n",
+ " \n",
+ " | Actual Diabetes | \n",
+ " 129.0 | \n",
+ " 61.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Predicted No Diabetes Predicted Diabetes\n",
+ "Actual No Diabetes 343.0 43.0\n",
+ "Actual Diabetes 129.0 61.0"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 42
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ceH3MODWFm7S",
+ "outputId": "52c6473a-7a20-4eed-ee46-05d1bf460f84",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 34
+ }
+ },
+ "source": [
+ "cm = np.array(confusion_matrix)\n",
+ "training_accuracy = (cm[0,0] + cm[1,1])/ cm.sum()\n",
+ "training_accuracy"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "0.7013888888888888"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 43
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kfRda6kWFzHZ"
+ },
+ "source": [
+ "### Testando o modelo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "R0n-pdnkF3MC"
+ },
+ "source": [
+ "test_cleaned = test_data['Outcome']\n",
+ "test_data = test_data.drop(['Outcome'], axis = 1)\n",
+ "test_data = sm.add_constant(test_data)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "x5hTgpelF5Pu"
+ },
+ "source": [
+ "def confusion_matrix(data, actual_values, model):\n",
+ " predicted_values = model.predict(data)\n",
+ " bins = np.array ([0, 0.5, 1])\n",
+ " cm = np.histogram2d(actual_values, predicted_values, bins = bins)[0]\n",
+ " accuracy = (cm[0,0] + cm[1,1])/cm.sum()\n",
+ " return cm, accuracy"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9PBK6M8yF7JE"
+ },
+ "source": [
+ "conf_matrix = confusion_matrix(test_data, test_cleaned, result)\n",
+ "conf_matrix"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EQz6ys7EF854"
+ },
+ "source": [
+ "confusion_matrix = pd.DataFrame(conf_matrix[0])\n",
+ "confusion_matrix.columns = ['Predicted No Diabetes', 'Predicted Diabetes']\n",
+ "confusion_matrix = confusion_matrix.rename(index = {0 : 'Actual No Diabetes', 1 : 'Actual Diabetes'})\n",
+ "confusion_matrix"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4MeuBR4QO1x3"
+ },
+ "source": [
+ "# Regularized Regression Methods \n",
+ "## Ridge Regression - Penalized Regression\n",
+ "> Reduz a complexidade do modelo através do uso de todas as variáveis de $X$, mas penalizando os coeficientes $w_{i}$ quando estiverem muito longe de zero, forçando-os a serem pequenos de maneira contínua. Dessa forma, diminuímos a complexidade do modelo enquanto mantemos todas as variáveis no modelo.\n",
+ "* Menor impacto dos outliers.\n",
+ "\n",
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "J1gLVnjXO1x6"
+ },
+ "source": [
+ "from sklearn.linear_model import Ridge\n",
+ "ridge = Ridge(alpha = .1)\n",
+ "lr = LinearRegression()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "0neeicWaO1yA"
+ },
+ "source": [
+ "# Matriz de covariáveis do modelo:\n",
+ "X_new = [[0, 0], [0, 0], [1, 1]]\n",
+ "y_new = [0, .1, 1]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CnDB5Bd0O1yE"
+ },
+ "source": [
+ "X_new"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "UldOGKA6O1yJ"
+ },
+ "source": [
+ "y_new"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GRzwxGWpO1yO"
+ },
+ "source": [
+ "ridge = Ridge(alpha = .1)\n",
+ "ridge.fit(X_new, y_new)\n",
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FXas7SfCO1yR"
+ },
+ "source": [
+ "# treinando a regressão Ridge\n",
+ "ridge.fit(X, y)\n",
+ "\n",
+ "# treinando a regressão linear simples (OLS)\n",
+ "lr.fit(X, y)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gvQY7qzBO1yV"
+ },
+ "source": [
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Wg1Z4h5tO1yY"
+ },
+ "source": [
+ "lr.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Puj1I_8CO1yd"
+ },
+ "source": [
+ "# Adicionar alguns outliers aos dados\n",
+ "outliers = y[950:] - 600\n",
+ "outliers"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Tw4Q3q6lO1yg"
+ },
+ "source": [
+ "import numpy as np\n",
+ "y_outlier = np.append(y[:950], outliers)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "pq7ufBP_O1yk"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier, s=5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Nx07u9aLO1yo"
+ },
+ "source": [
+ "lr = LinearRegression()\n",
+ "lr.fit(X, y_outlier)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5U_5Oc3TO1ys"
+ },
+ "source": [
+ "y_pred_outliers= lr.predict(X)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KsZ_jwBgO1yz"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier,s=5,label='actual')\n",
+ "plt.scatter(X, y_pred_outliers,s=5,label='prediction with outliers')\n",
+ "plt.scatter(X, y_pred,s=5,c='k', label='prediction sem outlier')\n",
+ "plt.legend()\n",
+ "plt.title('Linear Regression')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4ZJghaE-O1y4"
+ },
+ "source": [
+ "lr.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dMYaRMZxO1y8"
+ },
+ "source": [
+ "ridge = Ridge(alpha = 1000)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8swmMWrWO1zA"
+ },
+ "source": [
+ "ridge.fit(X, y_outlier)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FbrgmNIhO1zE"
+ },
+ "source": [
+ "y_pred_ridge = ridge.predict(X)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZLEEbFHYO1zI"
+ },
+ "source": [
+ "plt.scatter(X, y_outlier, s = 5,label = 'actual')\n",
+ "plt.scatter(X, y_pred_outliers, s = 5, c = 'r' ,label = 'LinearRegression with outliers')\n",
+ "plt.scatter(X, y_pred_ridge, s = 5, c = 'k', label = 'RidgeRegression with outlier')\n",
+ "plt.legend()\n",
+ "plt.title('Linear Regression')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "KL_0cZilO1zO"
+ },
+ "source": [
+ "ridge.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5Q146_AyO1zS"
+ },
+ "source": [
+ "## Efeito de $\\alpha$ na Regressão Ridge\n",
+ "### Exemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ydZvyvJ3O1zT"
+ },
+ "source": [
+ "X, y, w = make_regression(n_samples = 10, \n",
+ " n_features = 10, \n",
+ " coef = True, \n",
+ " random_state = 1, \n",
+ " bias = 3.5)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "z187ZGCqO1zY"
+ },
+ "source": [
+ "w"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "h4UEPOD6O1zd"
+ },
+ "source": [
+ "# Lasso\n",
+ "* Reduz overfitting;\n",
+ "* Se encarrega do Feature Selection, pois descarta variáveis altamente correlacionadas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "nv4t9GlkO1ze"
+ },
+ "source": [
+ "from sklearn.linear_model import Lasso\n",
+ "lasso = Lasso(alpha = .1)\n",
+ "lasso.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uLIbSdeSO1zj"
+ },
+ "source": [
+ "lasso.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_3AZohS2O1zq"
+ },
+ "source": [
+ "Observe acima que o segundo coeficiente foi estimado como 0 e, desta forma, podemos excluí-lo do ML."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dazegSrTO1zr"
+ },
+ "source": [
+ "# Elastic Net \n",
+ "* Combina o poder de Ridge e LASSO;\n",
+ "* Remove variáveis de pouco poder preditivo (LASSO) ou as penaliza (Ridge)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SmfRQ4QKO1zs"
+ },
+ "source": [
+ "from sklearn.linear_model import ElasticNet\n",
+ "\n",
+ "# Instancia o objeto\n",
+ "en = ElasticNet(alpha = .1)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IwWarH8BO1zv"
+ },
+ "source": [
+ "en.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "R2017DAXO1zz"
+ },
+ "source": [
+ "en.coef_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zz2uKTAJO1z6"
+ },
+ "source": [
+ "# Exemplo completo: Ridge\n",
+ "* Adaptado de [Ridge and Lasso Regression: A Complete Guide with Python Scikit-Learn](https://towardsdatascience.com/ridge-and-lasso-regression-a-complete-guide-with-python-scikit-learn-e20e34bcbf0b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mLUs3Y4lO1z7"
+ },
+ "source": [
+ "from sklearn.datasets import load_boston\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "from sklearn.linear_model import LinearRegression\n",
+ "from sklearn.linear_model import Ridge\n",
+ "\n",
+ "from sklearn.metrics import mean_squared_error"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "IPVmVN83O1z_"
+ },
+ "source": [
+ "boston = load_boston()\n",
+ "df_Boston = pd.DataFrame(boston.data, columns = boston.feature_names)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Wyf2IO9fO10D"
+ },
+ "source": [
+ "X_boston = boston.data\n",
+ "y_boston = boston.target"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mddJC9UyO10K"
+ },
+ "source": [
+ "X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(X_boston, y_boston, test_size = 0.2, random_state = 20111974)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "7GoluU_cO10S"
+ },
+ "source": [
+ "lr = LinearRegression()\n",
+ "lr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kA603LoWO10W"
+ },
+ "source": [
+ "# maior alpha --> mais restrição aos coeficientes; \n",
+ "# Menor alpha --> mais generalização, e Ridge se assemelha da OLS\n",
+ "rr = Ridge(alpha = 0.01)\n",
+ "rr.fit(X_treinamento, y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-MvzKjBuO10a"
+ },
+ "source": [
+ "# MSE\n",
+ "rr_model=(mean_squared_error(y_true = y_treinamento, y_pred = rr.predict(X_treinamento)))\n",
+ "print(rr_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Hjg0XJPWO10g"
+ },
+ "source": [
+ "rr100 = Ridge(alpha=100)\n",
+ "rr100.fit(X_treinamento, y_treinamento)\n",
+ "train_score=lr.score(X_treinamento, y_treinamento)\n",
+ "test_score=lr.score(X_teste, y_teste)\n",
+ "Ridge_treinamento_score = rr.score(X_treinamento,y_treinamento)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6XpGG2_xO10j"
+ },
+ "source": [
+ "# MSE\n",
+ "rr100_model = (mean_squared_error(y_true = y_treinamento, y_pred = rr100.predict(X_treinamento)))\n",
+ "print(rr100_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "F9YF1Jc0O10m"
+ },
+ "source": [
+ "Ridge_teste_score = rr.score(X_teste, y_teste)\n",
+ "Ridge_treinamento_score100 = rr100.score(X_treinamento, y_treinamento)\n",
+ "Ridge_teste_score100 = rr100.score(X_teste, y_teste)\n",
+ "print(\"linear regression train score:\", train_score)\n",
+ "print(\"linear regression test score:\", test_score)\n",
+ "print(\"ridge regression train score low alpha:\", Ridge_treinamento_score)\n",
+ "print(\"ridge regression test score low alpha:\", Ridge_teste_score)\n",
+ "print(\"ridge regression train score high alpha:\", Ridge_treinamento_score100)\n",
+ "print(\"ridge regression test score high alpha:\", Ridge_teste_score100)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qoHzgC53O10q"
+ },
+ "source": [
+ "plt.plot(rr.coef_, \n",
+ " alpha = 0.7, \n",
+ " linestyle = 'none', \n",
+ " marker = '*', \n",
+ " markersize = 5, \n",
+ " color = 'red', \n",
+ " label = r'Ridge; \n",
+ " $\\alpha = 0.01$', \n",
+ " zorder = 7) # zorder for ordering the markers\n",
+ "\n",
+ "plt.plot(rr100.coef_,alpha = 0.5, \n",
+ " linestyle = 'none', \n",
+ " marker = 'd', \n",
+ " markersize = 6, \n",
+ " color = 'blue', \n",
+ " label = r'Ridge; \n",
+ " $\\alpha = 100$') # alpha here is for transparency\n",
+ "\n",
+ "plt.plot(lr.coef_, \n",
+ " alpha = 0.4, \n",
+ " linestyle = 'none', \n",
+ " marker = 'o', \n",
+ " markersize = 7, \n",
+ " color = 'green', \n",
+ " label = 'Linear Regression')\n",
+ "\n",
+ "plt.xlabel('Coefficient Index', fontsize = 16)\n",
+ "plt.ylabel('Coefficient Magnitude',fontsize = 16)\n",
+ "plt.legend(fontsize = 13, loc = 4)\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GCwp0QRBO10u"
+ },
+ "source": [
+ "from sklearn.metrics import mean_squared_error\n",
+ "rr_model=(mean_squared_error(y_true= y, y_pred=regression.predict(X)))\n",
+ "print(first_model)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tPw-VP63O10x"
+ },
+ "source": [
+ "# Exemplo completo - Elastic Net"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dLu6v8HkO10y"
+ },
+ "source": [
+ "from sklearn.linear_model import ElasticNet\n",
+ "from sklearn.model_selection import GridSearchCV\n",
+ "\n",
+ "# Instancia o objeto:\n",
+ "en = ElasticNet(normalize = True)\n",
+ "\n",
+ "# Otimização dos hiperparâmetros:\n",
+ "d_hiperparametros = {'alpha': np.logspace(-5, 2, 8), \n",
+ " 'l1_ratio': [.2, .4, .6, .8]}\n",
+ "\n",
+ "search = GridSearchCV(estimator = en, \n",
+ " param_grid = d_hiperparametros, \n",
+ " scoring = 'neg_mean_squared_error', \n",
+ " n_jobs = 1,\n",
+ " refit = True, \n",
+ " cv = 10)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DzirI7FJO101"
+ },
+ "source": [
+ "search.fit(X, y)\n",
+ "search.best_params_"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jqPPkVP5O105"
+ },
+ "source": [
+ "en2 = ElasticNet(normalize = True, alpha = 0.001, l1_ratio = 0.6)\n",
+ "en2.fit(X, y)\n",
+ "\n",
+ "ml2 = (mean_squared_error(y_true = y, y_pred = en2.predict(X)))\n",
+ "print(ml2)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CH_iEuzhO109"
+ },
+ "source": [
+ "# Exercício 1 - Mall_Customers.csv\n",
+ "> A variável-target deste dataframe é 'Annual Income'. Desenvolva um modelo de regressão utilizando OLS, Ridge e LASSO e compare os resultados.\n",
+ "\n",
+ "* Experimente:\n",
+ " * Lasso(alpha = 0.01, max_iter = 10e5);\n",
+ " * Lasso(alpha = 0.0001, max_iter = 10e5);\n",
+ " * Ridge(alpha = 0.01);\n",
+ " * Ridge(alpha = 100);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZfRDEaaRYxFQ"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from sklearn import preprocessing\n",
+ "import matplotlib.pyplot as plt \n",
+ "plt.rc(\"font\", size=14)\n",
+ "from sklearn.linear_model import LogisticRegression\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "import seaborn as sns\n",
+ "sns.set(style=\"white\")\n",
+ "sns.set(style=\"whitegrid\", color_codes=True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "nulrLzUqYxFY"
+ },
+ "source": [
+ "## Data\n",
+ "\n",
+ "The data is related with direct marketing campaigns (phone calls) of a Portuguese banking institution. The classification goal is to predict if the client will subscribe (1/0) a term deposit (variable y)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4LdrQCwxYxFY"
+ },
+ "source": [
+ "This dataset provides the customer information. It includes 41188 records and 21 fields."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qoT6zkoFYxFZ",
+ "outputId": "2a1561ef-28cd-445f-d8ec-a2dd8e8e8c20",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 50
+ }
+ },
+ "source": [
+ "df_bank = pd.read_csv('https://raw.githubusercontent.com/MathMachado/DataFrames/master/bank-full.csv', header = 0)\n",
+ "df_bank = df_bank.dropna()\n",
+ "print(df_bank.shape)\n",
+ "print(list(df_bank.columns))"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "(45211, 1)\n",
+ "['age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"']\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZD23hMCeYxFc",
+ "outputId": "f3f4434d-428c-46fb-d15e-96cf2fa4ad8d",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 195
+ }
+ },
+ "source": [
+ "df_bank.head()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\" | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 58;\"management\";\"married\";\"tertiary\";\"no\";2143... | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " age;\"job\";\"marital\";\"education\";\"default\";\"balance\";\"housing\";\"loan\";\"contact\";\"day\";\"month\";\"duration\";\"campaign\";\"pdays\";\"previous\";\"poutcome\";\"y\"\n",
+ "0 58;\"management\";\"married\";\"tertiary\";\"no\";2143... \n",
+ "1 44;\"technician\";\"single\";\"secondary\";\"no\";29;\"... \n",
+ "2 33;\"entrepreneur\";\"married\";\"secondary\";\"no\";2... \n",
+ "3 47;\"blue-collar\";\"married\";\"unknown\";\"no\";1506... \n",
+ "4 33;\"unknown\";\"single\";\"unknown\";\"no\";1;\"no\";\"n... "
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 185
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CtGbim_EYxFh"
+ },
+ "source": [
+ "#### Input variables"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0pJ7ai5ZYxFh"
+ },
+ "source": [
+ "1 - age (numeric)\n",
+ "\n",
+ "2 - job : type of job (categorical: 'admin.','blue-collar','entrepreneur','housemaid','management','retired','self-employed','services','student','technician','unemployed','unknown')\n",
+ "\n",
+ "3 - marital : marital status (categorical: 'divorced','married','single','unknown'; note: 'divorced' means divorced or widowed)\n",
+ "\n",
+ "4 - education (categorical: 'basic.4y','basic.6y','basic.9y','high.school','illiterate','professional.course','university.degree','unknown')\n",
+ "\n",
+ "5 - default: has credit in default? (categorical: 'no','yes','unknown')\n",
+ "\n",
+ "6 - housing: has housing loan? (categorical: 'no','yes','unknown')\n",
+ "\n",
+ "7 - loan: has personal loan? (categorical: 'no','yes','unknown')\n",
+ "\n",
+ "8 - contact: contact communication type (categorical: 'cellular','telephone')\n",
+ "\n",
+ "9 - month: last contact month of year (categorical: 'jan', 'feb', 'mar', ..., 'nov', 'dec')\n",
+ "\n",
+ "10 - day_of_week: last contact day of the week (categorical: 'mon','tue','wed','thu','fri')\n",
+ "\n",
+ "11 - duration: last contact duration, in seconds (numeric). Important note: this attribute highly affects the output target (e.g., if duration=0 then y='no'). Yet, the duration is not known before a call is performed. Also, after the end of the call y is obviously known. Thus, this input should only be included for benchmark purposes and should be discarded if the intention is to have a realistic predictive model.\n",
+ "\n",
+ "12 - campaign: number of contacts performed during this campaign and for this client (numeric, includes last contact)\n",
+ "\n",
+ "13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)\n",
+ "\n",
+ "14 - previous: number of contacts performed before this campaign and for this client (numeric)\n",
+ "\n",
+ "15 - poutcome: outcome of the previous marketing campaign (categorical: 'failure','nonexistent','success')\n",
+ "\n",
+ "16 - emp.var.rate: employment variation rate - (numeric)\n",
+ "\n",
+ "17 - cons.price.idx: consumer price index - (numeric)\n",
+ "\n",
+ "18 - cons.conf.idx: consumer confidence index - (numeric) \n",
+ "\n",
+ "19 - euribor3m: euribor 3 month rate - (numeric)\n",
+ "\n",
+ "20 - nr.employed: number of employees - (numeric)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YwsaBV_OYxFi"
+ },
+ "source": [
+ "#### Predict variable (desired target):\n",
+ "\n",
+ "y - has the client subscribed a term deposit? (binary: '1','0')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2SsNWV_SYxFj"
+ },
+ "source": [
+ "The education column of the dataset has many categories and we need to reduce the categories for a better modelling. The education column has the following categories:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6TFbgh3vYxFk",
+ "outputId": "ce01e46e-d11a-4192-a4c7-ea57039f185f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 555
+ }
+ },
+ "source": [
+ "df_bank['education'].unique()"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "error",
+ "ename": "KeyError",
+ "evalue": "ignored",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2890\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2891\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2892\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'education'",
+ "\nThe above exception was the direct cause of the following exception:\n",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf_bank\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'education'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnlevels\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2901\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2902\u001b[0;31m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2903\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2904\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mindexer\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2891\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcasted_key\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2892\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2893\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2894\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2895\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtolerance\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'education'"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "luv7Bdf_YxFn"
+ },
+ "source": [
+ "Let us group \"basic.4y\", \"basic.9y\" and \"basic.6y\" together and call them \"basic\"."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "gkOlUOs2YxFn"
+ },
+ "source": [
+ "df_bank['education']=np.where(df_bank['education'] =='basic.9y', 'Basic', df_bank['education'])\n",
+ "df_bank['education']=np.where(df_bank['education'] =='basic.6y', 'Basic', df_bank['education'])\n",
+ "df_bank['education']=np.where(df_bank['education'] =='basic.4y', 'Basic', df_bank['education'])"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "H-X1WMv2YxFq"
+ },
+ "source": [
+ "After grouping, this is the columns"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "r9LlgpkjYxFq"
+ },
+ "source": [
+ "df_bank['education'].unique()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "fcnJy3KYYxFt"
+ },
+ "source": [
+ "### Data exploration"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "qUrTMR8BYxFt"
+ },
+ "source": [
+ "df_bank['y'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "rpzHnzJKYxFx"
+ },
+ "source": [
+ "sns.countplot(x='y',data=df_bank, palette='hls')\n",
+ "plt.show()\n",
+ "plt.savefig('count_plot')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "C99nOe3mYxF0"
+ },
+ "source": [
+ "There are 36548 no's and 4640 yes's in the outcome variables."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8nGaox_kYxF1"
+ },
+ "source": [
+ "Let's get a sense of the numbers across the two classes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "sQvzA60bYxF1"
+ },
+ "source": [
+ "df_bank.groupby('y').mean()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "u3xjoceKYxF3"
+ },
+ "source": [
+ "Observations:\n",
+ "\n",
+ "The average age of customers who bought the term deposit is higher than that of the customers who didn't.\n",
+ "The pdays (days since the customer was last contacted) is understandably lower for the customers who bought it. The lower the pdays, the better the memory of the last call and hence the better chances of a sale.\n",
+ "Surprisingly, campaigns (number of contacts or calls made during the current campaign) are lower for customers who bought the term deposit."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jvzGMePPYxF4"
+ },
+ "source": [
+ "We can calculate categorical means for other categorical variables such as education and marital status to get a more detailed sense of our data."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "RqLVMjoxYxF5"
+ },
+ "source": [
+ "df_bank.groupby('job').mean()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "GTUeRJAtYxF7"
+ },
+ "source": [
+ "df_bank.groupby('marital').mean()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xsxdFumiYxF9"
+ },
+ "source": [
+ "df_bank.groupby('education').mean()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3i1DCWV-YxGA"
+ },
+ "source": [
+ "Visualizations"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "OEArHQPbYxGB"
+ },
+ "source": [
+ "%matplotlib inline\n",
+ "pd.crosstab(df_bank.job,df_bank.y).plot(kind='bar')\n",
+ "plt.title('Purchase Frequency for Job Title')\n",
+ "plt.xlabel('Job')\n",
+ "plt.ylabel('Frequency of Purchase')\n",
+ "plt.savefig('purchase_fre_job')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PNwo5du_YxGD"
+ },
+ "source": [
+ "The frequency of purchase of the deposit depends a great deal on the job title. Thus, the job title can be a good predictor of the outcome variable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eM7CWfAZYxGE"
+ },
+ "source": [
+ "table=pd.crosstab(df_bank.marital,df_bank.y)\n",
+ "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n",
+ "plt.title('Stacked Bar Chart of Marital Status vs Purchase')\n",
+ "plt.xlabel('Marital Status')\n",
+ "plt.ylabel('Proportion of Customers')\n",
+ "plt.savefig('mariral_vs_pur_stack')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LWBLh7toYxGG"
+ },
+ "source": [
+ "Hard to see, but the marital status does not seem a strong predictor for the outcome variable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "vh_u4QphYxGH"
+ },
+ "source": [
+ "table=pd.crosstab(df_bank.education,df_bank.y)\n",
+ "table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)\n",
+ "plt.title('Stacked Bar Chart of Education vs Purchase')\n",
+ "plt.xlabel('Education')\n",
+ "plt.ylabel('Proportion of Customers')\n",
+ "plt.savefig('edu_vs_pur_stack')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "d9AgJroYYxGK"
+ },
+ "source": [
+ "Education seems a good predictor of the outcome variable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dHI2LT-IYxGL"
+ },
+ "source": [
+ "pd.crosstab(df_bank.day_of_week,df_bank.y).plot(kind='bar')\n",
+ "plt.title('Purchase Frequency for Day of Week')\n",
+ "plt.xlabel('Day of Week')\n",
+ "plt.ylabel('Frequency of Purchase')\n",
+ "plt.savefig('pur_dayofweek_bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3A2jmS4MYxGR"
+ },
+ "source": [
+ "Day of week may not be a good predictor of the outcome"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bzafDBHpYxGS"
+ },
+ "source": [
+ "pd.crosstab(df_bank.month,df_bank.y).plot(kind='bar')\n",
+ "plt.title('Purchase Frequency for Month')\n",
+ "plt.xlabel('Month')\n",
+ "plt.ylabel('Frequency of Purchase')\n",
+ "plt.savefig('pur_fre_month_bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "x5CBtquEYxGW"
+ },
+ "source": [
+ "Month might be a good predictor of the outcome variable"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "tgF_3SqWYxGY"
+ },
+ "source": [
+ "df_bank.age.hist()\n",
+ "plt.title('Histogram of Age')\n",
+ "plt.xlabel('Age')\n",
+ "plt.ylabel('Frequency')\n",
+ "plt.savefig('hist_age')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "y0FhKYDsYxGc"
+ },
+ "source": [
+ "The most of the customers of the bank in this dataset are in the age range of 30-40."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5Nd3yV7DYxGd"
+ },
+ "source": [
+ "pd.crosstab(df_bank.poutcome,df_bank.y).plot(kind='bar')\n",
+ "plt.title('Purchase Frequency for Poutcome')\n",
+ "plt.xlabel('Poutcome')\n",
+ "plt.ylabel('Frequency of Purchase')\n",
+ "plt.savefig('pur_fre_pout_bar')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oRKUAGrjYxGh"
+ },
+ "source": [
+ "Poutcome seems to be a good predictor of the outcome variable."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "63RLRI9uYxGi"
+ },
+ "source": [
+ "### Create dummy variables"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "V8S4WUKmYxGj"
+ },
+ "source": [
+ "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n",
+ "for var in cat_vars:\n",
+ " cat_list='var'+'_'+var\n",
+ " cat_list = pd.get_dummies(df_bank[var], prefix=var)\n",
+ " df_bank1=df_bank.join(cat_list)\n",
+ " data=df_bank1"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "uX3w9i9WYxGl"
+ },
+ "source": [
+ "cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']\n",
+ "df_bank_vars=df_bank.columns.values.tolist()\n",
+ "to_keep=[i for i in df_bank_vars if i not in cat_vars]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cMX_82xaYxGq"
+ },
+ "source": [
+ "df_bank_final=df_bank[to_keep]\n",
+ "df_bank_final.columns.values"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LkTjpxYoYxGr"
+ },
+ "source": [
+ "df_bank_final_vars=df_bank_final.columns.values.tolist()\n",
+ "y=['y']\n",
+ "X=[i for i in df_bank_final_vars if i not in y]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2QbKaRcsYxGt"
+ },
+ "source": [
+ "### Feature Selection"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EkxjW1AQYxGu"
+ },
+ "source": [
+ "from sklearn import datasets\n",
+ "from sklearn.feature_selection import RFE\n",
+ "from sklearn.linear_model import LogisticRegression\n",
+ "\n",
+ "logreg = LogisticRegression()\n",
+ "\n",
+ "rfe = RFE(logreg, 18)\n",
+ "rfe = rfe.fit(df_bank_final[X], df_bank_final[y] )\n",
+ "print(rfe.support_)\n",
+ "print(rfe.ranking_)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2P9hd4jHYxGw"
+ },
+ "source": [
+ "The Recursive Feature Elimination (RFE) has helped us select the following features: \"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5PW8WZX_YxGx"
+ },
+ "source": [
+ "cols=[\"previous\", \"euribor3m\", \"job_blue-collar\", \"job_retired\", \"job_services\", \"job_student\", \"default_no\", \n",
+ " \"month_aug\", \"month_dec\", \"month_jul\", \"month_nov\", \"month_oct\", \"month_sep\", \"day_of_week_fri\", \"day_of_week_wed\", \n",
+ " \"poutcome_failure\", \"poutcome_nonexistent\", \"poutcome_success\"] \n",
+ "X=df_bank_final[cols]\n",
+ "y=df_bank_final['y']"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ix0mN9qxYxG0"
+ },
+ "source": [
+ "### Implementing the model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Hbx2bwtiYxG0"
+ },
+ "source": [
+ "import statsmodels.api as sm\n",
+ "logit_model=sm.Logit(y,X)\n",
+ "result=logit_model.fit()\n",
+ "print(result.summary())"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HR1ui-UcYxG2"
+ },
+ "source": [
+ "The p-values for most of the variables are very small, therefore, most of them are significant to the model."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9GHhrsaeYxG3"
+ },
+ "source": [
+ "### Logistic Regression Model Fitting"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "MFQnH5MzYxG3"
+ },
+ "source": [
+ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n",
+ "from sklearn.linear_model import LogisticRegression\n",
+ "from sklearn import metrics\n",
+ "logreg = LogisticRegression()\n",
+ "logreg.fit(X_train, y_train)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YUa3QL7tYxG6"
+ },
+ "source": [
+ "#### Predicting the test set results and caculating the accuracy"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "SD-y2e33YxG6"
+ },
+ "source": [
+ "y_pred = logreg.predict(X_test)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "kkPWzos7YxG-"
+ },
+ "source": [
+ "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kwC3rt_6YxHA"
+ },
+ "source": [
+ "### Cross Validation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Muw50oqSYxHB"
+ },
+ "source": [
+ "from sklearn import model_selection\n",
+ "from sklearn.model_selection import cross_val_score\n",
+ "kfold = model_selection.KFold(n_splits=10, random_state=7)\n",
+ "modelCV = LogisticRegression()\n",
+ "scoring = 'accuracy'\n",
+ "results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)\n",
+ "print(\"10-fold cross validation average accuracy: %.3f\" % (results.mean()))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4y8XCTqoYxHE"
+ },
+ "source": [
+ "### Confusion Matrix"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BCza9NkVYxHE"
+ },
+ "source": [
+ "from sklearn.metrics import confusion_matrix\n",
+ "confusion_matrix = confusion_matrix(y_test, y_pred)\n",
+ "print(confusion_matrix)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "X9SapwS2YxHG"
+ },
+ "source": [
+ "The result is telling us that we have 10872+254 correct predictions and 1122+109 incorrect predictions."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "6bEWvWScYxHG"
+ },
+ "source": [
+ "#### Accuracy"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "NaH2nESwYxHH"
+ },
+ "source": [
+ "print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(classifier.score(X_test, y_test)))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "C6oxlhbpYxHJ"
+ },
+ "source": [
+ "#### Compute precision, recall, F-measure and support\n",
+ "\n",
+ "The precision is the ratio tp / (tp + fp) where tp is the number of true positives and fp the number of false positives. The precision is intuitively the ability of the classifier not to label as positive a sample that is negative.\n",
+ "\n",
+ "The recall is the ratio tp / (tp + fn) where tp is the number of true positives and fn the number of false negatives. The recall is intuitively the ability of the classifier to find all the positive samples.\n",
+ "\n",
+ "The F-beta score can be interpreted as a weighted harmonic mean of the precision and recall, where an F-beta score reaches its best value at 1 and worst score at 0.\n",
+ "\n",
+ "The F-beta score weights recall more than precision by a factor of beta. beta == 1.0 means recall and precision are equally important.\n",
+ "\n",
+ "The support is the number of occurrences of each class in y_test."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mhN5_p4yYxHK"
+ },
+ "source": [
+ "from sklearn.metrics import classification_report\n",
+ "print(classification_report(y_test, y_pred))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "xzSFVEnAYxHP"
+ },
+ "source": [
+ "#### Interpretation: \n",
+ "\n",
+ "Of the entire test set, 88% of the promoted term deposit were the term deposit that the customers liked. Of the entire test set, 90% of the customer's preferred term deposit were promoted."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NGXJ6g2nYxHQ"
+ },
+ "source": [
+ "### ROC Curvefrom sklearn import metrics\n",
+ "from ggplot import *\n",
+ "\n",
+ "prob = clf1.predict_proba(X_test)[:,1]\n",
+ "fpr, sensitivity, _ = metrics.roc_curve(Y_test, prob)\n",
+ "\n",
+ "df = pd.DataFrame(dict(fpr=fpr, sensitivity=sensitivity))\n",
+ "ggplot(df, aes(x='fpr', y='sensitivity')) +\\\n",
+ " geom_line() +\\\n",
+ " geom_abline(linetype='dashed')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "u9QKDuS0YxHQ"
+ },
+ "source": [
+ "from sklearn.metrics import roc_auc_score\n",
+ "from sklearn.metrics import roc_curve\n",
+ "logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))\n",
+ "fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])\n",
+ "plt.figure()\n",
+ "plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)\n",
+ "plt.plot([0, 1], [0, 1],'r--')\n",
+ "plt.xlim([0.0, 1.0])\n",
+ "plt.ylim([0.0, 1.05])\n",
+ "plt.xlabel('False Positive Rate')\n",
+ "plt.ylabel('True Positive Rate')\n",
+ "plt.title('Receiver operating characteristic')\n",
+ "plt.legend(loc=\"lower right\")\n",
+ "plt.savefig('Log_ROC')\n",
+ "plt.show()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From e7cfb05bc262d20ebdbec1f3cf5aee7c0a4a464f Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Thu, 5 Nov 2020 16:03:09 -0300
Subject: [PATCH 20/21] Criado usando o Colaboratory
---
.../NB15__ML_AutoML_pycaret_testes.ipynb | 374 ++++++++++++++++++
1 file changed, 374 insertions(+)
create mode 100644 Notebooks/NB15__ML_AutoML_pycaret_testes.ipynb
diff --git a/Notebooks/NB15__ML_AutoML_pycaret_testes.ipynb b/Notebooks/NB15__ML_AutoML_pycaret_testes.ipynb
new file mode 100644
index 000000000..45178a675
--- /dev/null
+++ b/Notebooks/NB15__ML_AutoML_pycaret_testes.ipynb
@@ -0,0 +1,374 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Untitled8.ipynb",
+ "provenance": [],
+ "private_outputs": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FfhCoyP98gDt"
+ },
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "226lzu3i8kRp"
+ },
+ "source": [
+ "url = 'https://raw.githubusercontent.com/MathMachado/DataFrames/master/Titanic_Original.csv'\n",
+ "df_titanic = pd.read_csv(url)\n",
+ "df_titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6mL0RI0V9JmP"
+ },
+ "source": [
+ "!pip install pycaret"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WL9nShOd86Fu"
+ },
+ "source": [
+ "from pycaret.classification import *"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YRtIVR7LC9nl"
+ },
+ "source": [
+ "https://www.kaggle.com/frtgnn/pycaret-introduction-classification-regression"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "3-dLwhmi9jTA"
+ },
+ "source": [
+ "### Set up"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "jooY5VUr9sqd"
+ },
+ "source": [
+ "# Normalizar os nomes das colunas:\n",
+ "df_titanic.columns = [colunas.lower() for colunas in df_titanic.columns]"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "erqtZNz9yZ2T"
+ },
+ "source": [
+ "df_titanic.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bf_IntG2ygtP"
+ },
+ "source": [
+ "### Tratamento da feature/variável fare"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "buRgX2rucrHT"
+ },
+ "source": [
+ "#fare_bins = ['Muito Baixo', 'Baixo', 'Medio', 'Alto', 'Muito Alto']\n",
+ "fare_bins = ['Baixo', 'Medio', 'Alto']\n",
+ "\n",
+ "df_titanic2 = df_titanic.copy()\n",
+ "\n",
+ "# Tratamentos necessários\n",
+ "\n",
+ "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = [0, .2, .4, .6, .8, 1], labels = fare_bins)\n",
+ "#df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 5, labels = fare_bins)\n",
+ "df_titanic2['fare_bins'] = pd.qcut(df_titanic2['fare'], q = 3, labels = fare_bins)\n",
+ "\n",
+ "#df_titanic2.drop(columns = [], axis = 1, inplace = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CZ87ERxzjluM"
+ },
+ "source": [
+ "#pd.qcut(df_titanic2['fare'], q = [0, .2, .4, .6, .8, 1], labels = fare_bins)\n",
+ "pd.qcut(df_titanic2['fare'], q = 3, labels = fare_bins)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6AWpUmbE7p39"
+ },
+ "source": [
+ "df_titanic2['fare_bins'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JyoQGTrqlWzp"
+ },
+ "source": [
+ "df_titanic2['sex'].value_counts()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ZKgXAUMcvr63"
+ },
+ "source": [
+ "df_titanic2.drop(columns = ['name', 'ticket'], axis = 1, inplace = True)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "FJwl0RrZvfDn"
+ },
+ "source": [
+ "for colunas in df_titanic2.columns:\n",
+ " print ( colunas, df_titanic2[colunas].value_counts())"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "W0RtT6Xr9IVL"
+ },
+ "source": [
+ "clf = setup(data = df_titanic2,\n",
+ " target = 'survived', \n",
+ " numeric_imputation = 'mean', # para tratamento dos missing values\n",
+ " categorical_features = ['sex', 'embarked'], # lista das variáveis categóricas\n",
+ " ignore_features = ['name', 'ticket', 'cabin', 'passengerid'], # variáveis que serão ignoradas\n",
+ " session_id = 20111974, # Seed por questões de reproducibilidade\n",
+ " silent = False)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mGGubn7k-GNi"
+ },
+ "source": [
+ "compare_models()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4YdMCHT92Tij"
+ },
+ "source": [
+ "\tModel\tAccuracy\tAUC\tRecall\tPrec.\tF1\tKappa\tMCC\tTT (Sec)\n",
+ "catboost\tCatBoost Classifier\t0.8218\t0.8634\t0.7857\t0.8275\t0.8154\t0.5996\t0.6150\t1.026\n",
+ "gbc\tGradient Boosting Classifier\t0.8187\t0.8540\t0.7867\t0.8231\t0.8129\t0.5959\t0.6084\t0.111\n",
+ "lightgbm\tLight Gradient Boosting Machine\t0.8186\t0.8683\t0.7937\t0.8195\t0.8149\t0.6009\t0.6073\t0.052"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "8rcs_jJFCjRW"
+ },
+ "source": [
+ "lgbm = create_model('lightgbm') "
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5BdvRHPdCq0E"
+ },
+ "source": [
+ "tuned_lightgbm = tune_model(lgbm)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "WwCW_pDYI1hy"
+ },
+ "source": [
+ "plot_model(estimator = tuned_lightgbm, plot = 'learning')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LES2FO1zI4X8"
+ },
+ "source": [
+ "plot_model(estimator = tuned_lightgbm, plot = 'auc')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xxGQX3jbI4bN"
+ },
+ "source": [
+ "plot_model(estimator = tuned_lightgbm, plot = 'confusion_matrix')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1O_9qDHgJJjw"
+ },
+ "source": [
+ "plot_model(estimator = tuned_lightgbm, plot = 'feature')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "W1xnpqD-46vh"
+ },
+ "source": [
+ "### Painel com todos os outputs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "PluFZQ8bI4hV"
+ },
+ "source": [
+ "evaluate_model(tuned_lightgbm)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JaffgUyy4bwz"
+ },
+ "source": [
+ "!pip install shap"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Uez4Gik8JwET"
+ },
+ "source": [
+ "interpret_model(tuned_lightgbm)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "9U2SnEKA41nW"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dfiBqgkXvdHJ"
+ },
+ "source": [
+ ""
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
From e8d1d8a322f99b4f7b540aa01f4bd6e4b8c4f58e Mon Sep 17 00:00:00 2001
From: Celso-Omoto <72219725+Celso-Omoto@users.noreply.github.com>
Date: Thu, 19 Nov 2020 15:59:32 -0300
Subject: [PATCH 21/21] Criado usando o Colaboratory
---
...ndas__Resposta_Exercicios_Aluno_Fifa.ipynb | 58 ++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
index cb7b4c537..32df5a3e4 100644
--- a/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
+++ b/Notebooks/NB10_01__Pandas__Resposta_Exercicios_Aluno_Fifa.ipynb
@@ -4,8 +4,8 @@
"metadata": {
"colab": {
"name": "NB10_01__Pandas.ipynb",
- "provenance": [],
"private_outputs": true,
+ "provenance": [],
"include_colab_link": true
},
"kernelspec": {
@@ -1713,6 +1713,62 @@
"execution_count": null,
"outputs": []
},
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "P13kEu99zYBh"
+ },
+ "source": [
+ "df_string = df['LS'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n",
+ "#df_string.head()\n",
+ "df_string[0] = pd.to_numeric(df_string[0])\n",
+ "df_string[1] = pd.to_numeric(df_string[1])\n",
+ "df_string['LS2'] = df_string[0]+df_string[1]\n",
+ "df_string.head()\n",
+ "df_string.drop(columns= [0, 1], axis = 1, inplace = True)\n",
+ "df = pd.merge(df, df_string, how = 'left', on = 'ID')\n",
+ "df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ahXBrk1oyFcq"
+ },
+ "source": [
+ "##não consegui fazer funcionar utilizando substituição com f'{}\n",
+ "def trata_sinal_str(s_nome_coluna,s_nome_coluna2):\n",
+ " print(s_nome_coluna)\n",
+ " #df_string = df[f'{s_nome_coluna}'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n",
+ " df_string = df[f'{s_nome_coluna}'].str.split(r'\\+', n = 4, expand = True) # n representa o número de splits no output.\n",
+ " df_string[0] = pd.to_numeric(df_string[0])\n",
+ " df_string[1] = pd.to_numeric(df_string[1])\n",
+ " df_string[f'{s_nome_coluna2}'] = df_string[0]+df_string[1]\n",
+ " df_string.drop(columns= [0, 1], axis = 1, inplace = True)\n",
+ " df = pd.merge(df, df_string, how = 'left', on = 'ID')\n",
+ " df.head()"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6BE-bIcqyRR6"
+ },
+ "source": [
+ "#l_lista = ['LS','ST','RS','LW','LF','CF','RF','RW','LAM','CAM','RAM','LM','LCM','CM','RCM','RM','LWB','LDM','CDM','RDM','RWB','LB','LCB','CB','RCB','RB']\n",
+ "#l_lista = ['LS','ST','LW','LF','CF','RF','RW','LAM','CAM','RAM','LM','LCM','CM','RCM','RM','LWB','LDM','CDM','RDM','RWB','LB','LCB','CB','RCB','RB']\n",
+ "l_lista = ['LS','ST']\n",
+ "for nome_coluna in l_lista:\n",
+ " print\n",
+ " trata_sinal_str(nome_coluna,nome_coluna+'2')"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
{
"cell_type": "markdown",
"metadata": {