{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Capítulo 2: Machine Learning" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Fundamentos Matemáticos\n", "\n", "Para entender redes neurais artificiais, é essencial ter uma boa base em álgebra linear e cálculo {cite}`zhang2023dive`. Esses conceitos são fundamentais para compreender como os modelos processam e transformam dados. A seguir, abordaremos os principais tópicos com exemplos práticos usando a biblioteca NumPy.\n", "\n", "### Álgebra Linear\n", "\n", "Álgebra linear lida com estruturas matemáticas como vetores, matrizes e tensores. Essas ferramentas são fundamentais para manipular e entender os dados que alimentam redes neurais.\n", "\n", "- **Escalares:** Um escalar é simplesmente um número único. Em redes neurais, eles costumam representar valores como pesos ou vieses — pequenos ajustes usados para ajudar o modelo a aprender.\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Exemplo de escalar\n", "escalar = 3.5\n", "print(escalar)\n", "```\n", "```\n", "3.5\n", "```\n", "\n", "- **Vetores:** Um vetor é uma lista de números. Ele pode ser usado para representar entradas de um modelo, saídas ou até mesmo parâmetros. Imagine um vetor como um conjunto de características, como altura, peso e idade de uma pessoa, usados como entrada para um modelo.\n", "\n", "```python\n", "# Exemplo de vetor\n", "vetor = np.array([1.0, 2.0, 3.0])\n", "print(vetor)\n", "```\n", "```\n", "[1. 2. 3.]\n", "```\n", "\n", "- **Matrizes:** Quando temos múltiplos vetores organizados, formamos uma matriz — uma grade de duas dimensões. Em redes neurais, matrizes podem armazenar grandes conjuntos de dados ou representar as conexões (pesos) entre as camadas de um modelo.\n", "\n", "```python\n", "# Exemplo de matriz\n", "matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", "print(matriz)\n", "```\n", "```\n", "[[1 2 3]\n", " [4 5 6]\n", " [7 8 9]]\n", "```\n", "\n", "- **Tensores:** Quando trabalhamos com mais de duas dimensões, estamos lidando com tensores. Redes neurais frequentemente utilizam tensores para representar dados complexos, como imagens coloridas (onde cada pixel tem valores de cor em três canais: vermelho, verde e azul).\n", "\n", "```python\n", "# Exemplo de tensor 3D\n", "tensor = np.random.rand(3, 3, 3)\n", "print(tensor)\n", "```\n", "```\n", "[[[0.86092583 0.68803215 0.33311945]\n", " [0.77149024 0.42643031 0.90005941]\n", " [0.22764019 0.35644062 0.75584702]]\n", "\n", " [[0.96963316 0.17407432 0.3921849 ]\n", " [0.34985739 0.67728245 0.72868431]\n", " [0.91673118 0.59129186 0.74605684]]\n", "\n", " [[0.05373217 0.37182579 0.93597411]\n", " [0.32529004 0.25533829 0.6914945 ]\n", " [0.02873603 0.27376316 0.30636661]]]\n", "```\n", "\n", "Essas operações são o alicerce do machine learning (redes neurais), permitindo que os modelos manipulem dados de forma eficiente e processem informações complexas em múltiplas dimensões.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercício: Álgebra Linear com NumPy\n", "\n", "O objetivo deste exercício é praticar a manipulação de escalares, vetores, matrizes e tensores usando a biblioteca NumPy. Esses conceitos são fundamentais para entender como os dados são processados em redes neurais artificiais.\n", "\n", "**Instruções:**\n", "\n", "- **Escalares**: Crie um escalar e imprima seu valor.\n", "- **Vetores**: Crie um vetor com 3 elementos e imprima seu valor.\n", "- **Matrizes**: Crie uma matriz 3x3 e imprima seu valor.\n", "- **Tensores**: Crie um tensor 3D de dimensões 2x2x2 e imprima seu valor.\n", "\n", "Complete o código abaixo para criar e imprimir um escalar, um vetor, uma matriz e um tensor usando a biblioteca NumPy.\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Escalares\n", "# Crie um escalar e imprima seu valor\n", "escalar = ...\n", "print(\"Escalar:\", escalar)\n", "\n", "# Vetores\n", "# Crie um vetor com 3 elementos e imprima seu valor\n", "vetor = ...\n", "print(\"Vetor:\", vetor)\n", "\n", "# Matrizes\n", "# Crie uma matriz 3x3 e imprima seu valor\n", "matriz = ...\n", "print(\"Matriz:\\n\", matriz)\n", "\n", "# Tensores\n", "# Crie um tensor 3D de dimensões 1x3x2 e imprima seu valor\n", "tensor = ...\n", "print(\"Tensor:\\n\", tensor)\n", "```\n", "\n", "**Saída Esperada**\n", "\n", "```\n", "Escalar: 10.5\n", "Vetor: [1.0, 2.0, 3.0, 20.1, 30.1]\n", "Matriz:\n", " [[1, 1, 1], [2, 2, 2], [3, 3, 3]]\n", "Tensor:\n", " [[[0.85809185 0.24814785]\n", " [0.14401491 0.11771045]\n", "```\n", "\n", "**Dicas:**\n", "\n", "- Use a função `np.array` para criar vetores e matrizes.\n", "- Use a função `np.random.rand` para criar tensores com valores aleatórios.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operações entre Escalares, Vetores e Matrizes\n", "\n", "- **Produto Interno (Produto Escalar)**\n", "\n", "O produto interno de dois vetores é uma operação que multiplica seus elementos correspondentes e soma os resultados. Matematicamente, para dois vetores $ \\mathbf{a} $ e $ \\mathbf{b} $ de dimensão $ n $:\n", "\n", "$ \\mathbf{a} \\cdot \\mathbf{b} = \\sum_{i=1}^{n} a_i b_i $\n", "\n", "```python\n", "# Produto Interno\n", "import numpy as np\n", "\n", "vetor1 = np.array([1, 2, 3])\n", "vetor2 = np.array([4, 5, 6])\n", "produto_interno = np.dot(vetor1, vetor2)\n", "print(produto_interno)\n", "```\n", "\n", "```\n", "32\n", "```\n", "\n", "- **Multiplicação Matriz-Vetor**\n", "\n", "A multiplicação de uma matriz por um vetor resulta em um novo vetor. Matematicamente, para uma matriz $ \\mathbf{A} $ de dimensão $ m \\times n $ e um vetor $ \\mathbf{x} $ de dimensão $ n $:\n", "\n", "$ \\mathbf{y} = \\mathbf{A} \\mathbf{x} $\n", "\n", "onde $ \\mathbf{y} $ é um vetor de dimensão $ m $.\n", "\n", "```python\n", "# Multiplicação Matriz-Vetor\n", "matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", "vetor = np.array([1, 2, 3])\n", "resultado = np.dot(matriz, vetor)\n", "print(resultado)\n", "```\n", "\n", "```\n", "[14 32 50]\n", "```\n", "\n", "- **Multiplicação Matriz-Matriz**\n", "\n", "A multiplicação de duas matrizes resulta em uma nova matriz. Matematicamente, para uma matriz $ \\mathbf{A} $ de dimensão $ m \\times n $ e uma matriz $ \\mathbf{B} $ de dimensão $ n \\times p $:\n", "\n", "$ \\mathbf{C} = \\mathbf{A} \\mathbf{B} $\n", "\n", "onde $ \\mathbf{C} $ é uma matriz de dimensão $ m \\times p $.\n", "\n", "Para que a multiplicação de matrizes seja válida, o número de colunas da primeira matriz deve ser igual ao número de linhas da segunda matriz. Se isso não ocorrer, uma das matrizes pode precisar ser transposta.\n", "\n", "```python\n", "# Multiplicação Matriz-Matriz\n", "matriz1 = np.array([[1, 2], [3, 4], [5, 6]])\n", "matriz2 = np.array([[7, 8], [9, 10]])\n", "resultado = np.dot(matriz1, matriz2)\n", "print(resultado)\n", "```\n", "\n", "```\n", "[[ 25 28]\n", " [ 57 64]\n", " [ 89 100]]\n", "```\n", "\n", "- **Transposição de Matrizes**\n", "\n", "A transposição de uma matriz inverte suas linhas e colunas. Matematicamente, a transposta de uma matriz $ \\mathbf{A} $ de dimensão $ m \\times n $ é uma matriz $ \\mathbf{A}^T $ de dimensão $ n \\times m $.\n", "\n", "```python\n", "# Transposição de Matriz\n", "matriz = np.array([[1, 2, 3], [4, 5, 6]])\n", "matriz_transposta = matriz.T\n", "print(matriz_transposta)\n", "```\n", "\n", "```\n", "[[1 4]\n", " [2 5]\n", " [3 6]]\n", "```\n", "\n", "- **Calculando a Norma Euclidiana**\n", "\n", "A norma euclidiana de um vetor é uma medida de sua magnitude (ou comprimento). Matematicamente, para um vetor $ \\mathbf{v} $ de dimensão $ n $:\n", "\n", "$ \\| \\mathbf{v} \\| = \\sqrt{\\sum_{i=1}^{n} v_i^2} $\n", "\n", "```python\n", "# Norma Euclidiana\n", "vetor = np.array([1, 2, 3])\n", "norma_euclidiana = np.linalg.norm(vetor)\n", "print(norma_euclidiana)\n", "```\n", "\n", "```\n", "3.7416573867739413\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercício: Operações entre Escalares, Vetores e Matrizes com NumPy\n", "\n", "O objetivo deste exercício é praticar operações fundamentais entre escalares, vetores e matrizes usando a biblioteca NumPy. Esses conceitos são essenciais para entender como os dados são processados em redes neurais artificiais.\n", "\n", "**Instruções:**\n", "\n", "- **Produto Interno (Produto Escalar)**: Calcule o produto interno de dois vetores.\n", "- **Multiplicação Matriz-Vetor**: Calcule a multiplicação de uma matriz por um vetor.\n", "- **Multiplicação Matriz-Matriz**: Calcule a multiplicação de duas matrizes.\n", "- **Transposição de Matrizes**: Calcule a transposição de uma matriz.\n", "- **Norma Euclidiana**: Calcule a norma euclidiana de um vetor.\n", "\n", "Complete o código abaixo para realizar as operações descritas usando a biblioteca NumPy.\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Produto Interno (Produto Escalar)\n", "vetor1 = np.array([1, 2, 3])\n", "vetor2 = np.array([4, 5, 6])\n", "produto_interno = ...\n", "print(\"Produto Interno:\", produto_interno)\n", "\n", "# Multiplicação Matriz-Vetor\n", "matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", "vetor = np.array([1, 2, 3])\n", "resultado_mv = ...\n", "print(\"Multiplicação Matriz-Vetor:\\n\", resultado_mv)\n", "\n", "# Multiplicação Matriz-Matriz\n", "matriz1 = np.array([[1, 2], [3, 4], [5, 6]])\n", "matriz2 = np.array([[7, 8], [9, 10]])\n", "resultado_mm = ...\n", "print(\"Multiplicação Matriz-Matriz:\\n\", resultado_mm)\n", "\n", "# Transposição de Matrizes\n", "matriz = np.array([[1, 2, 3], [4, 5, 6]])\n", "matriz_transposta = ...\n", "print(\"Transposição de Matriz:\\n\", matriz_transposta)\n", "\n", "# Norma Euclidiana\n", "vetor = np.array([1, 2, 3])\n", "norma_euclidiana = ...\n", "print(\"Norma Euclidiana:\", norma_euclidiana)\n", "```\n", "**Saída Esperada**\n", "\n", "```\n", "Produto Interno: 32\n", "Multiplicação Matriz-Vetor:\n", " [14 32 50]\n", "Multiplicação Matriz-Matriz:\n", " [[ 25 28]\n", " [ 57 64]\n", " [ 89 100]]\n", "Transposição de Matriz:\n", " [[1 4]\n", " [2 5]\n", " [3 6]]\n", "Norma Euclidiana: 3.7416573867739413\n", "```\n", "\n", "**Dicas:**\n", "\n", "- Use a função `np.dot` para calcular o produto interno e a multiplicação de matrizes.\n", "- Use o atributo `.T` para calcular a transposição de uma matriz.\n", "- Use a função `np.linalg.norm` para calcular a norma euclidiana de um vetor." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cálculo\n", "\n", "O cálculo é uma ferramenta essencial em machine learning, especialmente para a otimização de modelos. Ele é utilizado para ajustar os parâmetros dos modelos para minimizar a função de custo e melhorar a precisão. Aqui, exploraremos alguns dos conceitos fundamentais de cálculo que são mais relevantes em machine learning: derivadas parciais (gradientes), a regra da cadeia e o conceito de backpropagation.\n", "\n", "### Derivadas Parciais (Gradientes)\n", "\n", "Em machine learning, os modelos são frequentemente ajustados para minimizar uma função de custo $ J(\\theta) $, que mede o erro das previsões do modelo. Para minimizar essa função de custo, utilizamos gradientes, que são vetores de derivadas parciais da função de custo em relação a cada um dos parâmetros do modelo.\n", "\n", "**Definição de Derivadas Parciais**\n", "\n", "Se temos uma função $ f(x_1, x_2, \\ldots, x_n) $, a derivada parcial de $ f $ em relação a $ x_i $ é denotada por $ \\frac{\\partial f}{\\partial x_i} $ e é definida como:\n", "\n", "$\n", "\\frac{\\partial f}{\\partial x_i} = \\lim_{\\Delta x_i \\to 0} \\frac{f(x_1, \\ldots, x_i + \\Delta x_i, \\ldots, x_n) - f(x_1, \\ldots, x_i, \\ldots, x_n)}{\\Delta x_i}\n", "$\n", "\n", "**Gradiente**\n", "\n", "O gradiente de uma função $ J(\\theta) $ com respeito aos seus parâmetros $ \\theta $ é um vetor de derivadas parciais:\n", "\n", "$\n", "\\nabla J(\\theta) = \\left[ \\frac{\\partial J}{\\partial \\theta_1}, \\frac{\\partial J}{\\partial \\theta_2}, \\ldots, \\frac{\\partial J}{\\partial \\theta_n} \\right]\n", "$\n", "\n", "Vamos reorganizar o material apresentado, mantendo o foco em explicar a **regra da cadeia** no contexto do cálculo de gradientes em **Machine Learning**.\n", "\n", "### Regra da Cadeia\n", "\n", "A **regra da cadeia** é uma ferramenta do cálculo diferencial utilizada para calcular a derivada de funções compostas. Ela é amplamente aplicada no treinamento de **redes neurais**, principalmente no cálculo de gradientes durante o processo de **retropropagação** (ou *backpropagation*). Esse cálculo é crucial para ajustar os pesos das redes neurais com base no erro cometido nas previsões.\n", "\n", "#### Derivadas de Funções Compostas\n", "\n", "A regra da cadeia nos ajuda a encontrar a derivada de uma função composta. Por exemplo, para duas funções $ f(g(x)) $, a derivada em relação a $ x $ é dada por:\n", "\n", "$\n", "\\frac{d}{dx} f(g(x)) = f'(g(x)) \\cdot g'(x)\n", "$\n", "\n", "#### Aplicação no Treinamento de Redes Neurais\n", "\n", "Em redes neurais, o objetivo é minimizar uma **função de perda** que mede o erro entre as previsões do modelo e os valores reais. Esse processo envolve calcular os **gradientes** da função de perda em relação aos pesos da rede, para ajustá-los de modo a reduzir o erro nas iterações seguintes.\n", "\n", "No treinamento, a função de perda $ L $ depende dos valores calculados por várias camadas de neurônios. A regra da cadeia é utilizada para propagar o erro de volta por todas essas camadas. Assim, o gradiente da perda em relação aos pesos $ w $ de uma camada é:\n", "\n", "$\n", "\\frac{\\partial L}{\\partial w} = \\frac{\\partial L}{\\partial f} \\cdot \\frac{\\partial f}{\\partial w}\n", "$\n", "\n", "Isso nos permite ajustar os pesos da rede usando algoritmos de otimização, como o **gradiente descendente**, que movem os pesos na direção oposta ao gradiente para minimizar o erro.\n", "\n", "#### Exemplo Prático\n", "\n", "Vamos ver como a regra da cadeia pode ser aplicada para calcular a derivada de uma função composta. Considere a função $ f(x) = (x^2 + 1)^3 $. Vamos calcular a derivada dessa função em relação a $ x $ aplicando a regra da cadeia.\n", "\n", "**Passos:**\n", "1. Definimos a função interna $ g(x) = x^2 + 1 $ e a função externa $ f(u) = u^3 $, onde $ u = g(x) $.\n", "2. Calculamos as derivadas de $ g(x) $ e $ f(u) $.\n", "3. Aplicamos a regra da cadeia para obter a derivada de $ f(x) $ em relação a $ x $.\n", "\n", "**Implementação em Python**\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Função interna g(x) = x^2 + 1\n", "def g(x):\n", " return x**2 + 1\n", "\n", "# Função externa f(u) = u^3\n", "def f(u):\n", " return u**3\n", "\n", "# Derivada de g(x), ou seja, dg/dx = 2x\n", "def dg_dx(x):\n", " return 2 * x\n", "\n", "# Derivada de f(u), ou seja, df/du = 3u^2\n", "def df_du(u):\n", " return 3 * u**2\n", "\n", "# Aplicação da regra da cadeia para calcular dy/dx\n", "def dy_dx(x):\n", " u = g(x) # Calcula g(x)\n", " return df_du(u) * dg_dx(x) # Aplica a regra da cadeia\n", "\n", "# Testando com x = 2\n", "x = 2\n", "print(f\"Derivada de f(x) em relação a x quando x = {x}: {dy_dx(x)}\")\n", "```\n", "\n", "**Saída:**\n", "\n", "```\n", "Derivada de f(x) em relação a x quando x = 2: 300.0\n", "```\n", "\n", "**Cálculo Manual**\n", "\n", "1. **Calcule $ u = g(x) $ para $ x = 2 $:**\n", "\n", " $\n", " u = g(2) = 2^2 + 1 = 5\n", " $\n", "\n", "2. **Calcule $ \\frac{du}{dx} $ para $ x = 2 $:**\n", "\n", " $\n", " \\frac{du}{dx} = 2x = 4\n", " $\n", "\n", "3. **Calcule $ \\frac{dy}{du} $ para $ u = 5 $:**\n", "\n", " $\n", " \\frac{dy}{du} = 3u^2 = 75\n", " $\n", "\n", "4. **Aplique a regra da cadeia:**\n", "\n", " $\n", " \\frac{dy}{dx} = \\frac{dy}{du} \\cdot \\frac{du}{dx} = 75 \\cdot 4 = 300\n", " $\n", "\n", "Portanto, tanto o cálculo manual quanto a implementação em Python resultam no mesmo valor: **300**.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercício de Cálculo\n", "\n", "**Derivar uma Função Composta Usando a Regra da Cadeia**\n", "\n", "Considere a função $ h(x) = \\sin(x^2) $. Calcule a derivada de $ h(x) $ em relação a $ x $.\n", "\n", "A regra da cadeia nos diz que:\n", "\n", "$ \\frac{dh}{dx} = \\frac{dh}{du} \\cdot \\frac{du}{dx} $\n", "\n", "Vamos calcular a derivada de $ h(x) $ em relação a $ x $ para $ x = 1 $ matematicamente:\n", "\n", "- Calcule $ u = g(x) $ para $ x = 1 $:\n", "\n", " $ u = g(1) = 1^2 = 1 $\n", "\n", "- Calcule $ \\frac{du}{dx} $ para $ x = 1 $:\n", "\n", " $ \\frac{du}{dx} = 2x = 2 \\cdot 1 = 2 $\n", "\n", "- Calcule $ \\frac{dh}{du} $ para $ u = 1 $:\n", "\n", " $ \\frac{dh}{du} = \\cos(u) = \\cos(1) $\n", "\n", "- Aplique a regra da cadeia:\n", "\n", " $ \\frac{dh}{dx} = \\frac{dh}{du} \\cdot \\frac{du}{dx} = \\cos(1) \\cdot 2 $\n", "\n", "Implemente estes cálculos em Python:\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Definindo a função interna g(x) = x^2\n", "\n", "\n", "# Definindo a função externa f(u) = sin(u)\n", "\n", "\n", "# Definindo a derivada da função interna dg/dx = 2x\n", "\n", "\n", "# Definindo a derivada da função externa df/du = cos(u)\n", "\n", "\n", "# Aplicando a regra da cadeia para calcular dh/dx\n", "\n", " \n", "# Testando a função com x = 1\n", "x = 1\n", "print(f\"Derivada de h(x) em relação a x em x = {x}: {dh_dx(x)}\")\n", "```\n", "\n", "**Verifique a Saída:**\n", "```\n", "Derivada de h(x) em relação a x em x = 1: 1.0806046117362795\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Probabilidade e Estatística\n", "\n", "### **Probabilidade**\n", "\n", "Probabilidade é o estudo da incerteza e é essencial em Machine Learning para modelar eventos futuros com base em dados observados. Muitos algoritmos utilizam probabilidade para prever a ocorrência de eventos, classificar dados e inferir padrões a partir de exemplos.\n", "\n", "#### Definições básicas:\n", "\n", "- **Espaço Amostral (S):** Em Machine Learning, o espaço amostral representa o conjunto de todos os possíveis resultados ou categorias de uma variável. Por exemplo, ao classificar imagens de gatos e cães, o espaço amostral seria $ S = \\{\\text{gato}, \\text{cão}\\} $.\n", "\n", "- **Evento (A):** Um evento pode ser a ocorrência de uma classe específica no modelo, como \"A = imagem classificada como gato\".\n", "\n", "#### Fórmula da Probabilidade:\n", "\n", "A probabilidade de um evento $A$ ocorrer, como a classificação correta de uma imagem, é dada por:\n", "\n", "$\n", "P(A) = \\frac{\\text{Número de resultados favoráveis}}{\\text{Número total de resultados possíveis}}\n", "$\n", "\n", "Exemplo: Se um modelo acerta 80 classificações corretas em 100 tentativas, a probabilidade de uma classificação correta seria:\n", "\n", "$\n", "P(\\text{correto}) = \\frac{80}{100} = 0.8\n", "$\n", "\n", "```python\n", "# Cálculo básico de probabilidade\n", "resultados_favoraveis = 80\n", "total_resultados = 100\n", "probabilidade = resultados_favoraveis / total_resultados\n", "print(f'Probabilidade de acerto: {probabilidade}')\n", "```\n", "```\n", "Probabilidade de acerto: 0.8\n", "```\n", "\n", "### Teorema de Bayes\n", "O Teorema de Bayes nos dá uma maneira de calcular a probabilidade de um evento $ A $ ocorrer, dado que outro evento $ B $ já ocorreu. É expressado como:\n", "\n", "$\n", "P(A|B) = \\frac{P(B|A) \\cdot P(A)}{P(B)}\n", "$\n", "\n", "Onde:\n", "- $ P(A|B) $ é a probabilidade de $ A $ dado $ B $.\n", "- $ P(B|A) $ é a probabilidade de $ B $ dado $ A $.\n", "- $ P(A) $ é a probabilidade de $ A $ ocorrer independentemente.\n", "- $ P(B) $ é a probabilidade de $ B $ ocorrer independentemente.\n", "\n", "Este teorema é essencial em várias áreas de aprendizado de máquina, pois permite a atualização de probabilidades com base em novas informações, como no **Naive Bayes Classifier**.\n", "\n", "\n", "#### Aplicação em Algoritmos:\n", "- **Naive Bayes Classifier:** Um algoritmo de classificação que utiliza a probabilidade condicional para classificar dados. Ele assume que as características são independentes e usa o Teorema de Bayes para calcular a probabilidade de cada classe.\n", "\n", "```python\n", "from sklearn.naive_bayes import GaussianNB\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.datasets import load_iris\n", "from sklearn.metrics import accuracy_score\n", "\n", "# Exemplo com o dataset Iris\n", "data = load_iris()\n", "X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=42)\n", "\n", "# Treinando o classificador Naive Bayes\n", "clf = GaussianNB()\n", "clf.fit(X_train, y_train)\n", "\n", "# Fazendo previsões\n", "y_pred = clf.predict(X_test)\n", "\n", "# Saída do Código:\n", "print(f'Previsões: {y_pred}')\n", "\n", "# Avaliando a precisão do modelo\n", "accuracy = accuracy_score(y_test, y_pred)\n", "\n", "# Saída do Código:\n", "print(f'Precisão do modelo: {accuracy:.2f}')\n", "```\n", "\n", "```plaintext\n", "Previsões: [1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0]\n", "Precisão do modelo: 1.00\n", "```\n", "\n", "### **Variável Aleatória**\n", "\n", "Uma variável aleatória mapeia os resultados de um experimento em valores numéricos e pode ser discreta ou contínua. Em Machine Learning, variáveis aleatórias ajudam a modelar incertezas e lidar com dados ruidosos ou incompletos.\n", "\n", "#### Função de Probabilidade (discreta):\n", "\n", "A probabilidade de uma variável aleatória $X$ assumir um valor específico $x$ é:\n", "\n", "$\n", "P(X = x) = p(x)\n", "$\n", "\n", "Exemplo: Em um modelo de classificação de spam, a probabilidade de um email ser spam ($X = \\text{spam}$) pode ser calculada com base nas características do email.\n", "\n", "```python\n", "import numpy as np\n", "\n", "# Probabilidade discreta para classificação binária (exemplo de email ser spam)\n", "# Supomos que 40 emails de 100 são spam\n", "total_emails = 100\n", "spam_emails = 40\n", "P_spam = spam_emails / total_emails\n", "print(f'Probabilidade de um email ser spam: {P_spam}')\n", "```\n", "```\n", "Probabilidade de um email ser spam: 0.4\n", "```\n", "### Função Densidade de Probabilidade (contínua):\n", "\n", "A **função densidade de probabilidade (PDF)** é uma função matemática que descreve a probabilidade relativa de uma variável contínua assumir um determinado valor. Em outras palavras, a PDF nos diz a probabilidade de uma variável contínua estar em um intervalo específico.\n", "\n", "Para uma variável contínua $ X $, a PDF $ f(x) $ é definida de tal forma que a probabilidade de $ X $ estar entre dois valores $ a $ e $ b $ é dada pela integral da PDF entre esses valores:\n", "\n", "$ P(a \\leq X \\leq b) = \\int_{a}^{b} f(x) \\, dx $\n", "\n", "### Exemplo de PDF de uma Variável Contínua Normal:\n", "\n", "Uma das PDFs mais comuns é a da distribuição normal (ou gaussiana), que é frequentemente usada em modelos de regressão. A PDF de uma variável normal $ X $ com média $ \\mu $ e desvio padrão $ \\sigma $ é dada por:\n", "\n", "$ f(x) = \\frac{1}{\\sigma \\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}} $\n", "\n", "### Aplicação em Modelos de Regressão:\n", "\n", "Em modelos de regressão, como a regressão linear, a PDF é usada para modelar a distribuição dos erros (resíduos) entre os valores observados e os valores preditos. A suposição comum é que os erros seguem uma distribuição normal com média zero e desvio padrão constante. Isso permite que os modelos de regressão façam inferências estatísticas sobre os parâmetros do modelo e a precisão das previsões.\n", "\n", "### Exemplo em Python:\n", "\n", "```python\n", "import scipy.stats as stats\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "# Exemplo de função densidade de probabilidade (PDF) de uma variável contínua normal\n", "mu = 0 # média\n", "sigma = 1 # desvio padrão\n", "x = np.linspace(-5, 5, 100)\n", "pdf = stats.norm.pdf(x, mu, sigma)\n", "\n", "# Plotando a PDF\n", "plt.plot(x, pdf)\n", "plt.title('Função Densidade de Probabilidade (PDF) de uma Variável Contínua Normal')\n", "plt.xlabel('Valor de x')\n", "plt.ylabel('Densidade de Probabilidade')\n", "plt.show()\n", "```\n", "\n", "### Saída Esperada:\n", "\n", "O gráfico gerado mostrará a curva da PDF de uma variável normal com média $ \\mu = 0 $ e desvio padrão $ \\sigma = 1 $. A curva terá um pico no valor da média e decairá simetricamente em ambos os lados, representando a distribuição dos valores da variável contínua.\n", "\n", "### **Estatística Descritiva**\n", "\n", "A estatística descritiva é crucial para entender os dados antes de construir modelos de Machine Learning. Ela resume as principais características do conjunto de dados.\n", "\n", "#### Medidas de Tendência Central:\n", "\n", "- **Média ($\\mu$):** Representa o valor médio dos dados. Em algoritmos de regressão, a média pode ser usada para calcular o erro médio, como no **Erro Quadrático Médio (MSE)**.\n", "\n", "$\n", "\\mu = \\frac{1}{n}\\sum_{i=1}^n x_i\n", "$\n", "\n", "```python\n", "# Calcular a média\n", "dados = [10, 15, 23, 42, 12, 5, 67]\n", "media = np.mean(dados)\n", "print(f'Média: {media}')\n", "```\n", "\n", "#### Medidas de Dispersão:\n", "\n", "- **Variância ($\\sigma^2$):** Mede a dispersão dos dados ao redor da média. Algoritmos como **PCA (Análise de Componentes Principais)** usam variância para identificar quais características são mais relevantes.\n", "\n", "$\n", "\\sigma^2 = \\frac{1}{n}\\sum_{i=1}^n (x_i - \\mu)^2\n", "$\n", "\n", "```python\n", "# Calcular a variância\n", "variancia = np.var(dados)\n", "print(f'Variância: {variancia}')\n", "```\n", "\n", "- **Desvio Padrão ($\\sigma$):** Muito usado para identificar o grau de dispersão nos dados.\n", "\n", "```python\n", "# Calcular o desvio padrão\n", "desvio_padrao = np.std(dados)\n", "print(f'Desvio Padrão: {desvio_padrao}')\n", "```\n", "### Inferência Estatística\n", "\n", "**Inferência estatística** é o processo de fazer generalizações ou previsões sobre uma população maior com base em uma amostra de dados. Em outras palavras, é a prática de usar dados de uma amostra para fazer conclusões sobre a população da qual a amostra foi extraída. Isso é fundamental em muitas áreas, incluindo ciências sociais, medicina, economia e, claro, Machine Learning.\n", "\n", "Em Machine Learning, a inferência estatística é usada para:\n", "\n", "1. **Validar Modelos**: Avaliar o desempenho de um modelo em dados de teste para garantir que ele generaliza bem para novos dados.\n", "2. **Testar Hipóteses**: Verificar se as relações encontradas nos dados são estatisticamente significativas e não ocorreram por acaso.\n", "3. **Estimar Parâmetros**: Estimar os parâmetros de um modelo (como coeficientes de regressão) e determinar a incerteza associada a essas estimativas.\n", "\n", "\n", "O **intervalo de confiança** é uma ferramenta estatística que indica a faixa de valores em que acreditamos que o valor verdadeiro de um parâmetro está, com um certo nível de confiança. Por exemplo, um intervalo de confiança de 95% para a média de uma população significa que temos 95% de confiança de que o valor verdadeiro da média está dentro desse intervalo.\n", "\n", "\n", "Em modelos de regressão, o intervalo de confiança para os coeficientes ajuda a determinar se uma variável é estatisticamente significativa. Se o intervalo de confiança para um coeficiente não inclui zero, isso sugere que a variável tem um efeito significativo no modelo.\n", "\n", "**Exemplo Básico de Intervalo de Confiança**\n", "\n", "Vamos calcular um intervalo de confiança de 95% para a média de uma amostra de dados fictícios.\n", "\n", "```python\n", "import numpy as np\n", "from scipy import stats\n", "\n", "# Dados fictícios\n", "dados = np.random.randn(100)\n", "media_dados = np.mean(dados)\n", "desvio_padrao_dados = np.std(dados)\n", "\n", "# Intervalo de confiança 95%\n", "intervalo = stats.norm.interval(0.95, loc=media_dados, scale=desvio_padrao_dados/np.sqrt(len(dados)))\n", "print(f'Intervalo de Confiança: {intervalo}')\n", "```\n", "\n", "**Saída Esperada Aproximada devido ao random**\n", "\n", "```\n", "Intervalo de Confiança: (-0.08619762174596416, 0.08619762174596416)\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercício: Probabilidade e Estatística\n", "\n", "O objetivo deste exercício é praticar conceitos fundamentais de probabilidade e estatística usando Python. Esses conceitos são essenciais para entender e aplicar algoritmos de Machine Learning.\n", "\n", "**Instruções:**\n", "\n", "- **Cálculo de Probabilidade**: Calcule a probabilidade de um evento com base no número de resultados favoráveis e no número total de resultados possíveis.\n", "- **Probabilidade Discreta**: Calcule a probabilidade de uma variável aleatória discreta.\n", "- **Função Densidade de Probabilidade (PDF)**: Plote a função densidade de probabilidade de uma variável contínua normal.\n", "- **Medidas de Tendência Central**: Calcule a média de um conjunto de dados.\n", "- **Medidas de Dispersão**: Calcule a variância e o desvio padrão de um conjunto de dados.\n", "- **Distribuição Normal**: Plote uma distribuição normal.\n", "- **Intervalo de Confiança**: Calcule o intervalo de confiança para a média de um conjunto de dados.\n", "\n", "Complete o código abaixo para realizar as operações descritas usando Python.\n", "\n", "```python\n", "import numpy as np\n", "import scipy.stats as stats\n", "import matplotlib.pyplot as plt\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.datasets import load_iris\n", "\n", "# Cálculo de Probabilidade\n", "resultados_favoraveis = 80\n", "total_resultados = 100\n", "probabilidade = ...\n", "print(f'Probabilidade de acerto: {probabilidade}')\n", "\n", "# Probabilidade Discreta\n", "total_emails = 100\n", "spam_emails = 40\n", "P_spam = ...\n", "print(f'Probabilidade de um email ser spam: {P_spam}')\n", "\n", "# Função Densidade de Probabilidade (PDF)\n", "mu = 0 # média\n", "sigma = 1 # desvio padrão\n", "x = np.linspace(-5, 5, 100)\n", "pdf = ...\n", "plt.plot(x, pdf)\n", "plt.title('Função Densidade de Probabilidade (PDF)')\n", "plt.show()\n", "\n", "# Medidas de Tendência Central\n", "dados = [10, 15, 23, 42, 12, 5, 67]\n", "media = ...\n", "print(f'Média: {media}')\n", "\n", "# - Medidas de Dispersão\n", "variancia = ...\n", "desvio_padrao = ...\n", "print(f'Variância: {variancia}')\n", "print(f'Desvio Padrão: {desvio_padrao}')\n", "\n", "# Distribuição Normal\n", "plt.plot(x, stats.norm.pdf(x, mu, sigma))\n", "plt.title('Distribuição Normal')\n", "plt.show()\n", "\n", "# - Intervalo de Confiança\n", "dados = np.random.randn(100)\n", "media_dados = np.mean(dados)\n", "desvio_padrao_dados = np.std(dados)\n", "\n", "intervalo = ...\n", "print(f'Intervalo de Confiança: {intervalo}')\n", "```\n", "\n", "**Saída Esperada**\n", "\n", "```\n", "Probabilidade de acerto: 0.8\n", "Probabilidade de um email ser spam: 0.4\n", "Média: 24.857142857142858\n", "Variância: 421.55102040816325\n", "Desvio Padrão: 20.531707683681923\n", "Intervalo de Confiança: (-0.16913820580756977, 0.22402578926619593)\n", "```\n", "\n", "**Dicas:**\n", "\n", "- Use operações aritméticas básicas para calcular a probabilidade.\n", "- Use a função `np.mean` para calcular a média.\n", "- Use a função `np.var` para calcular a variância.\n", "- Use a função `np.std` para calcular o desvio padrão.\n", "- Use a função `stats.norm.pdf` para calcular a função densidade de probabilidade.\n", "- Use a função `stats.norm.interval` para calcular o intervalo de confiança.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Manipulação e Pré-processamento de Dados \n", "\n", "### Limpeza de Dados\n", "\n", "A limpeza de dados é uma fase crucial no pré-processamento de dados, sendo necessária para garantir que os dados sejam consistentes, completos e livres de erros antes de realizar análises ou construir modelos de aprendizado de máquina. A seguir, exploraremos os principais aspectos da limpeza de dados, com exemplos e códigos em Python.\n", "\n", "- **Remoção de Dados Ausentes (Missing Data)**\n", "\n", "Em datasets reais, a presença de valores ausentes é comum. Esses valores podem estar ausentes por diversas razões, como erros na coleta ou falhas no sensor. Para lidar com eles, podemos usar as seguintes abordagens:\n", "\n", "**Exclusão de dados ausentes:** Eliminar as linhas ou colunas onde os valores ausentes estão presentes.\n", "\n", "**Substituição de valores ausentes:** Também chamada de imputação, envolve preencher os valores ausentes com estimativas, como a média ou a mediana dos dados existentes.\n", "\n", "Exemplo prático: Substituição com a média\n", "\n", "Vamos analisar um conjunto de dados sobre pacientes, onde alguns valores de idade estão ausentes.\n", "\n", "```python\n", "import pandas as pd\n", "import numpy as np\n", "\n", "# Criando um DataFrame de exemplo\n", "data = {'Nome': ['Ana', 'Bruno', 'Carlos', 'Daniela'],\n", " 'Idade': [25, np.nan, 30, np.nan],\n", " 'Peso': [70, 82, 65, 55]}\n", "\n", "df = pd.DataFrame(data)\n", "print(\"Dados originais:\\n\", df)\n", "\n", "# Substituição de valores ausentes pela média sem usar inplace\n", "df['Idade'] = df['Idade'].fillna(df['Idade'].mean())\n", "\n", "# Arredondando a coluna Idade para duas casas decimais\n", "df['Idade'] = df['Idade'].round(2)\n", "print(\"\\nApós substituição da média (com 2 casas decimais) na coluna Idade:\\n\", df)\n", "\n", "```\n", "\n", "**Saída:**\n", "\n", "```\n", "Dados originais:\n", " Nome Idade Peso\n", "0 Ana 25.0 70\n", "1 Bruno NaN 82\n", "2 Carlos 30.0 65\n", "3 Daniela NaN 55\n", "\n", "Após substituição da média (com 2 casas decimais) na coluna Idade:\n", " Nome Idade Peso\n", "0 Ana 25.00 70\n", "1 Bruno 27.50 82\n", "2 Carlos 30.00 65\n", "3 Daniela 27.50 55\n", "\n", "```\n", "\n", "Neste exemplo, substituímos os valores ausentes na coluna `Idade` pela média das idades conhecidas. A média foi calculada como $ \\frac{25 + 30}{2} = 27.5 $.\n", "\n", "- **Tratamento de Dados Duplicados**\n", "\n", "Os dados duplicados podem distorcer a análise e devem ser removidos para garantir a integridade do dataset. Duplicatas podem surgir devido a erros na coleta ou processamento dos dados.\n", "\n", "Exemplo prático: Remoção de duplicados\n", "\n", "```python\n", "# Criando um DataFrame com valores duplicados\n", "data_dup = {'Nome': ['Ana', 'Bruno', 'Carlos', 'Bruno'],\n", " 'Idade': [25, 22, 30, 22],\n", " 'Peso': [70, 82, 65, 82]}\n", "\n", "df_dup = pd.DataFrame(data_dup)\n", "print(\"\\nDados com duplicatas:\\n\", df_dup)\n", "\n", "# Removendo duplicados\n", "df_clean = df_dup.drop_duplicates()\n", "print(\"\\nApós remoção de duplicatas:\\n\", df_clean)\n", "```\n", "\n", "**Saída:**\n", "\n", "```\n", "Dados com duplicatas:\n", " Nome Idade Peso\n", "0 Ana 25 70\n", "1 Bruno 22 82\n", "2 Carlos 30 65\n", "3 Bruno 22 82\n", "\n", "Após remoção de duplicatas:\n", " Nome Idade Peso\n", "0 Ana 25 70\n", "1 Bruno 22 82\n", "2 Carlos 30 65\n", "```\n", "\n", "Aqui, o registro duplicado de \"Bruno\" foi removido. O método `drop_duplicates()` garantiu que apenas uma instância de cada entrada permanecesse no dataset.\n", "\n", "- **Correção de Erros**\n", "\n", "Erros nos dados podem surgir devido a vários fatores, como entradas incorretas ou falhas em sensores. Um exemplo típico é encontrar valores fora do intervalo esperado, como idades negativas ou excessivamente altas.\n", "\n", "Exemplo prático: Identificação e correção de valores fora de um intervalo esperado\n", "\n", "Se os valores de idade devem estar entre 0 e 120 anos, valores fora desse intervalo são considerados erros.\n", "\n", "```python\n", "# Criando um DataFrame com possíveis erros\n", "data_err = {'Nome': ['Ana', 'Bruno', 'Carlos', 'Daniela'],\n", " 'Idade': [25, 22, 150, -5],\n", " 'Peso': [70, 82, 65, 55]}\n", "\n", "df_err = pd.DataFrame(data_err)\n", "print(\"\\nDados com possíveis erros:\\n\", df_err)\n", "\n", "# Corrigindo valores fora do intervalo esperado\n", "df_err.loc[df_err['Idade'] > 120, 'Idade'] = np.nan # Substituindo por NaN idades > 120\n", "df_err.loc[df_err['Idade'] < 0, 'Idade'] = np.nan # Substituindo por NaN idades < 0\n", "print(\"\\nApós correção de erros na coluna Idade:\\n\", df_err)\n", "```\n", "\n", "**Saída:**\n", "\n", "```\n", "Dados com possíveis erros:\n", " Nome Idade Peso\n", "0 Ana 25 70\n", "1 Bruno 22 82\n", "2 Carlos 150 65\n", "3 Daniela -5 55\n", "\n", "Após correção de erros na coluna Idade:\n", " Nome Idade Peso\n", "0 Ana 25.0 70\n", "1 Bruno 22.0 82\n", "2 Carlos NaN 65\n", "3 Daniela NaN 55\n", "```\n", "\n", "Os valores inválidos de idade (150 e -5) foram substituídos por `NaN` para posterior tratamento. Essa abordagem é útil quando não se pode determinar um valor correto e é necessário eliminar ou substituir o erro.\n", "\n", "A limpeza de dados é essencial para garantir a qualidade de qualquer análise ou modelo de aprendizado de máquina. Métodos como a substituição de valores ausentes, remoção de duplicatas e correção de erros são fundamentais para transformar dados brutos em dados utilizáveis. O uso de bibliotecas como `pandas` facilita o processo, tornando possível lidar de forma eficiente com grandes quantidades de dados e garantir sua consistência e precisão." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Normalização e Padronização**\n", "\n", "Normalização e padronização são técnicas fundamentais para ajustar os dados em uma escala comum, garantindo que as variáveis sejam tratadas igualmente pelos modelos de aprendizado de máquina. Esses processos evitam que variáveis com magnitudes diferentes dominem a análise ou o treinamento.\n", "\n", "- **Min-Max Scaling**\n", "\n", "A normalização pelo método de **Min-Max** transforma os dados para que estejam dentro de um intervalo específico, geralmente entre [0, 1]. A fórmula para normalização Min-Max é:\n", "\n", "$\n", "X' = \\frac{X - X_{min}}{X_{max} - X_{min}}\n", "$\n", "\n", "Onde:\n", "- $X'$ é o valor normalizado,\n", "- $X$ é o valor original,\n", "- $X_{min}$ é o valor mínimo da variável,\n", "- $X_{max}$ é o valor máximo da variável.\n", "\n", "Essa técnica é útil em modelos como redes neurais, onde valores muito grandes podem dificultar o treinamento.\n", "\n", "**Exemplo:**\n", "\n", "```python\n", "from sklearn.preprocessing import MinMaxScaler\n", "import pandas as pd\n", "\n", "data = {'Salario': [50000, 62000, 70000, 56000]}\n", "df = pd.DataFrame(data)\n", "\n", "scaler = MinMaxScaler()\n", "df['Salario_normalizado'] = scaler.fit_transform(df[['Salario']])\n", "print(df)\n", "```\n", "\n", "Saida:\n", "```\n", " Salario Salario_normalizado\n", "0 50000 0.0\n", "1 62000 0.6\n", "2 70000 1.0\n", "3 56000 0.3\n", "```\n", "\n", "- **Z-score Normalization (Padronização)**\n", "\n", "A padronização pelo **Z-score** transforma os dados para que tenham uma média de 0 e desvio padrão 1. A fórmula é:\n", "\n", "$\n", "Z = \\frac{X - \\mu}{\\sigma}\n", "$\n", "\n", "Onde:\n", "- $Z$ é o valor padronizado,\n", "- $X$ é o valor original,\n", "- $\\mu$ é a média dos dados,\n", "- $\\sigma$ é o desvio padrão.\n", "\n", "Essa técnica é essencial para modelos baseados em distância, como KNN e SVM, garantindo que variáveis em diferentes escalas contribuam de forma equilibrada.\n", "\n", "**Exemplo:**\n", "\n", "```python\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "scaler = StandardScaler()\n", "df['Salario_padronizado'] = scaler.fit_transform(df[['Salario']])\n", "print(df)\n", "```\n", "\n", "Saída:\n", "```\n", " Salario Salario_normalizado Salario_padronizado\n", "0 50000 0.0 -1.283901\n", "1 62000 0.6 0.337869\n", "2 70000 1.0 1.419048\n", "3 56000 0.3 -0.473016\n", "```\n", "\n", "Ambas as técnicas são úteis em diferentes cenários, sendo a normalização indicada quando há limites fixos nos dados, e a padronização quando se quer remover a dependência de escala e trabalhar com média e variabilidade dos dados.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### **Tratamento de Outliers**\n", "\n", "Outliers são valores que se diferenciam significativamente da maioria dos dados e podem distorcer a análise ou o desempenho dos modelos de aprendizado de máquina. Identificar e tratar outliers é crucial para garantir a qualidade dos resultados.\n", "\n", "- **Técnicas Comuns de Detecção de Outliers:**\n", "\n", " - **Boxplot (Diagrama de Caixa):** Um método visual que utiliza o conceito de quartis. Valores além de 1.5 vezes o intervalo interquartil (IQR) são considerados outliers.\n", " - **Z-score:** Calcula quantos desvios padrão um valor está distante da média. Valores por exemplo, com um Z-score maior que 1.5 (ou menor que -1.5) podem ser considerados outliers.\n", "\n", "**Exemplo prático: Detecção de outliers usando Z-score**\n", "\n", "Neste exemplo, usamos o Z-score para identificar possíveis outliers em uma amostra de dados.\n", "\n", "```python\n", "import pandas as pd\n", "import numpy as np\n", "from scipy import stats\n", "\n", "# Criando um DataFrame de exemplo\n", "data_outliers = {'Nome': ['Ana', 'Bruno', 'Carlos', 'Daniela', 'Eduardo'],\n", " 'Idade': [25, 22, 30, 27, 100],\n", " 'Peso': [70, 82, 65, 55, 85]}\n", "\n", "df_outliers = pd.DataFrame(data_outliers)\n", "\n", "# Calculando o Z-score para a coluna 'Idade'\n", "df_outliers['Z_score_Idade'] = stats.zscore(df_outliers['Idade'])\n", "\n", "print(\"Dados originais com Z-Score\")\n", "print(df_outliers)\n", "\n", "# Filtrando os outliers com base no Z-score (> 1.5 ou < -1.5)\n", "outliers = df_outliers[(df_outliers['Z_score_Idade'] > 1.5) | (df_outliers['Z_score_Idade'] < -1.5)]\n", "print(\"\\nOutliers detectados\\n\", outliers)\n", "```\n", "\n", "**Saída:**\n", "\n", "```bash\n", "Dados originais com Z-Score\n", " Nome Idade Peso Z_score_Idade\n", "0 Ana 25 70 -0.531724\n", "1 Bruno 22 82 -0.632685\n", "2 Carlos 30 65 -0.363457\n", "3 Daniela 27 55 -0.464417\n", "4 Eduardo 100 85 1.992284\n", "\n", "Outliers detectados\n", " Nome Idade Peso Z_score_Idade\n", "4 Eduardo 100 85 1.992284\n", "```\n", "\n", "Neste exemplo, o valor de idade 100 é identificado como um outlier, já que seu Z-score é maior que 1.5. Outliers como esse podem ser tratados, seja pela remoção ou substituição por valores mais representativos.\n", "\n", "A detecção de outliers é um passo essencial para garantir a integridade dos dados antes de aplicar qualquer modelo de aprendizado de máquina. O uso de técnicas como Z-score e boxplot facilita essa tarefa e assegura que os dados estejam livres de valores anômalos que possam comprometer a análise.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercício: Limpeza de Dados**\n", "\n", "Você recebeu o seguinte conjunto de dados que contém informações sobre funcionários de uma empresa. Sua tarefa é aplicar as técnicas de limpeza de dados para preparar este dataset para análise.\n", "\n", "**Dataset de Entrada:**\n", "```python\n", "import pandas as pd\n", "import numpy as np\n", "\n", "# Dados de exemplo com problemas\n", "data = {\n", " 'Nome': ['Alice', 'Bruno', 'Carlos', 'Daniela', 'Eduardo', 'Fernanda', 'Bruno', 'Gustavo', 'Heloisa', 'Igor', \n", " 'Joana', 'Karina', 'Laura', 'Marcelo', 'Nina', 'Bruno', 'Otavio', 'Paula', 'Quintino', 'Rafaela'],\n", " 'Idade': [25, np.nan, 45, -2, 30, 31, 45, 28, np.nan, 26, 40, -1, 23, 36, np.nan, 33, 50, 29, 24, 32],\n", " 'Salario': [50000, 62000, 70000, np.nan, 52000, 51000, 62000, 45000, 48000, np.nan, 55000, 57000, 49000, \n", " 60000, np.nan, 62000, 73000, 51000, np.nan, 61000],\n", " 'Cidade': ['São Paulo', 'Rio de Janeiro', 'São Paulo', 'Rio de Janeiro', 'São Paulo', 'São Paulo', \n", " 'Rio de Janeiro', 'Brasília', 'São Paulo', 'São Paulo', 'Rio de Janeiro', 'São Paulo', \n", " 'São Paulo', 'Brasília', 'Rio de Janeiro', 'Rio de Janeiro', 'Brasília', 'São Paulo', \n", " 'São Paulo', 'Rio de Janeiro']\n", "}\n", "\n", "df = pd.DataFrame(data)\n", "print(\"Dados originais:\")\n", "print(df)\n", "\n", "```\n", "\n", "**Tarefas:**\n", "- **Tratar valores ausentes:**\n", " - Substituir os valores ausentes na coluna `Idade` pela média das idades válidas.\n", " - Substituir os valores ausentes na coluna `Salario` pela mediana dos salários.\n", "\n", "- **Corrigir valores incorretos:**\n", " - A coluna `Idade` contém valores negativos, o que é incorreto. Substitua esses valores pela média das idades válidas.\n", "\n", "- **Remover duplicatas:**\n", " - Verifique se há funcionários duplicados com base no nome e remova os registros duplicados, mantendo apenas o primeiro.\n", "\n", "**Saída esperada:**\n", "```bash\n", "Dados originais:\n", " Nome Idade Salario Cidade\n", "0 Alice 25.0 50000.0 São Paulo\n", "1 Bruno NaN 62000.0 Rio de Janeiro\n", "2 Carlos 45.0 70000.0 São Paulo\n", "3 Daniela -2.0 NaN Rio de Janeiro\n", "4 Eduardo 30.0 52000.0 São Paulo\n", "5 Fernanda 31.0 51000.0 São Paulo\n", "6 Bruno 45.0 62000.0 Rio de Janeiro\n", "7 Gustavo 28.0 45000.0 Brasília\n", "8 Heloisa NaN 48000.0 São Paulo\n", "9 Igor 26.0 NaN São Paulo\n", "10 Joana 40.0 55000.0 Rio de Janeiro\n", "11 Karina -1.0 57000.0 São Paulo\n", "12 Laura 23.0 49000.0 São Paulo\n", "13 Marcelo 36.0 60000.0 Brasília\n", "14 Nina NaN NaN Rio de Janeiro\n", "15 Bruno 33.0 62000.0 Rio de Janeiro\n", "16 Otavio 50.0 73000.0 Brasília\n", "17 Paula 29.0 51000.0 São Paulo\n", "18 Quintino 24.0 NaN São Paulo\n", "19 Rafaela 32.0 61000.0 Rio de Janeiro\n", "\n", "Dados após limpeza (com duplicatas removidas):\n", " Nome Idade Salario Cidade\n", "0 Alice 25.0 50000.0 São Paulo\n", "1 Bruno 33.1 62000.0 Rio de Janeiro\n", "2 Carlos 45.0 70000.0 São Paulo\n", "3 Daniela 33.1 56000.0 Rio de Janeiro\n", "4 Eduardo 30.0 52000.0 São Paulo\n", "5 Fernanda 31.0 51000.0 São Paulo\n", "7 Gustavo 28.0 45000.0 Brasília\n", "8 Heloisa 33.1 48000.0 São Paulo\n", "9 Igor 26.0 56000.0 São Paulo\n", "10 Joana 40.0 55000.0 Rio de Janeiro\n", "11 Karina 33.1 57000.0 São Paulo\n", "12 Laura 23.0 49000.0 São Paulo\n", "13 Marcelo 36.0 60000.0 Brasília\n", "14 Nina 33.1 56000.0 Rio de Janeiro\n", "16 Otavio 50.0 73000.0 Brasília\n", "17 Paula 29.0 51000.0 São Paulo\n", "18 Quintino 24.0 56000.0 São Paulo\n", "19 Rafaela 32.0 61000.0 Rio de Janeiro\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercício: Análise e Visualização de Dados com o [Dataset do UFC no Kaggle](https://www.kaggle.com/code/rishpande/ufc-data-analysis-visualization-beginner)\n", "\n", "Este dataset contém dados detalhados sobre lutas do UFC desde 2013, incluindo características dos lutadores, como idade, altura, peso, técnicas usadas e o método de vitória. Cada linha do dataset representa uma luta, onde o lutador posicionado no corner **azul** (Blue) e o lutador no corner **vermelho** (Red) competem. As colunas que começam com \"B_\" referem-se ao lutador do corner azul, e as colunas que começam com \"R_\" referem-se ao lutador do corner vermelho. Sua tarefa é realizar uma análise completa do dataset, criando visualizações que ajudem a interpretar os dados e, por fim, definir um ranking dos lutadores.\n", "\n", "> [Baixar arquivo CSV](ufc.csv)\n", "\n", "**Parte 1: Análise Exploratória e Visualizações**\n", "\n", "Construa as visualizações solicitadas e escreva uma análise para cada situação descrita a seguir:\n", "\n", "- **Tratamento de Valores Faltantes:**\n", " - Identifique as colunas com valores faltantes, como idade, altura e peso.\n", " - Substitua os valores faltantes pela **média** ou **mediana** dessas colunas. Imprima a quantidade de valores faltantes antes da substituição e depois, garantindo que foram devidamente corrigidos.\n", "\n", "- **Distribuição de Idades dos Lutadores:**\n", " - Crie um **histograma** que mostre a distribuição das idades dos lutadores nos corners vermelho e azul, e comente as tendências observadas.\n", " \n", " \"ufc\"\n", "\n", "- **Relação entre Altura e Peso:**\n", " - Construa um **gráfico de dispersão** para visualizar a relação entre altura e peso dos lutadores nos corners vermelho e azul.\n", " \n", " \"ufc\"\n", "\n", "- **Métodos de Vitória:**\n", " - Crie um **gráfico de barras** para mostrar os métodos mais comuns de vitória, tais como: decisão (DEC), nocaute (KO/TKO) e submissão (SUB). Comente sobre os métodos de vitória mais frequentes e o que isso pode indicar sobre o estilo dos lutadores.\n", " \n", " \"ufc\"\n", "\n", "- **Vitórias por Corner:**\n", " - Crie um **gráfico de pizza** para mostrar a quantidade de vitórias de lutadores no corner vermelho e no corner azul.\n", " \n", " \"ufc\"\n", "\n", "Comente sobre os resultados apresentados, sua importância para análise e conclusões gerais.\n", "\n", "**Parte 2: Criando um Ranking dos Lutadores**\n", "\n", "Agora, você deve criar um ranking dos lutadores utilizando a fórmula a seguir, ajustada para usar valores **normalizados** (entre 0 e 1), garantindo que todas as variáveis contribuam proporcionalmente ao cálculo do ranking:\n", "\n", "$$\n", "R = W_V \\cdot V_{norm} + W_K \\cdot K_{norm} + W_S \\cdot S_{norm}\n", "$$\n", "\n", "Onde:\n", "- $ V_{norm} $ = Número de vitórias (normalizado)\n", "- $ K_{norm} $ = Vitórias por nocaute (normalizado)\n", "- $ S_{norm} $ = Vitórias por submissão (normalizado)\n", "- $ W_V = 0.5 $, $ W_K = 0.3 $, $ W_S = 0.2 $ = Pesos que determinam a importância de cada variável no ranking.\n", "\n", "**Tarefas:**\n", "- **Normalizar** os valores de vitórias, vitórias por nocaute e vitórias por submissão.\n", "- **Implementar** a fórmula do ranking usando os dados do dataset, ajustando os pesos conforme já definidos:\n", " - $ W_V = 0.5 $ (Peso para vitórias)\n", " - $ W_K = 0.3 $ (Peso para vitórias por nocaute)\n", " - $ W_S = 0.2 $ (Peso para vitórias por submissão)\n", "- **Listar** os 10 melhores lutadores de acordo com o ranking gerado.\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true }, "source": [ "## Vídeos\n", "\n", "- [Youtube Playlist](https://www.youtube.com/playlist?list=PLgZW4krsqK2TD5vHbD8Xs5iW55SfXo9Vf) uma lista de vídeos selecionados pelo professor.\n", "\n", "\n", "## Sites Importantes\n", "\n", "- [NumPy](https://numpy.org/) é uma biblioteca fundamental para computação numérica em Python.\n", "\n", "- [SciPy](https://scipy.org/) é uma biblioteca que fornece módulos para otimização, integração, interpolação, álgebra linear, estatística e muito mais.\n", "\n", "- [Scikit-learn](https://scikit-learn.org/) é uma biblioteca de Machine Learning que fornece ferramentas simples e eficientes para análise de dados e modelagem.\n", "\n", "- [Matplotlib](https://matplotlib.org/) é uma biblioteca de plotagem que fornece uma interface orientada a objetos para incorporar gráficos em aplicações.\n", "\n", "- [Pandas](https://pandas.pydata.org/) é uma biblioteca que fornece estruturas de dados e operações de manipulação de dados de alto desempenho.\n", "\n", "- para desenhar gráficos estatísticos atraentes e informativos.\n", "[Seaborn](https://seaborn.pydata.org/) é uma biblioteca de visualização de dados baseada em Matplotlib que fornece uma interface de alto nível \n", "\n", "- [TensorFlow](https://www.tensorflow.org/) é uma biblioteca de código aberto para aprendizado de máquina desenvolvida pela Google.\n", "\n", "- [Keras](https://keras.io/) é uma API de alto nível para construir e treinar modelos de aprendizado profundo. Ele pode ser executado em cima do TensorFlow, CNTK ou Theano.\n", "\n", "- [PyTorch](https://pytorch.org/) é uma biblioteca de aprendizado profundo desenvolvida pelo Facebook.\n", "\n", "- [Plotly](https://plotly.com/) é uma biblioteca de visualização de dados que permite criar gráficos interativos e publicá-los na web.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Referências\n", "\n", "```{bibliography}\n", ":bibfiles: references.bib\n", ":filter: docname in docnames\n", "```" ] } ], "metadata": { "colab": { "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.20" } }, "nbformat": 4, "nbformat_minor": 4 }