Objetivo

Configurar e dominar o ambiente de trabalho padrão para ciência de dados e IA: o Anaconda como gerenciador de ambientes e pacotes, e o Jupyter Notebook como ferramenta de exploração, análise e documentação interativa de código.


1. Por que o Ambiente Importa em IA?

Em projetos de Machine Learning você vai lidar com:

  • Múltiplos projetos simultâneos, cada um exigindo versões diferentes de bibliotecas
  • Bibliotecas com dependências complexas (PyTorch precisa de versões específicas de CUDA)
  • Código exploratório que você quer executar em partes, ver resultados imediatamente e documentar
  • Gráficos, tabelas e equações matemáticas renderizados junto com o código
  • Compartilhamento de análises com colegas que precisam reproduzir exatamente os mesmos resultados

Anaconda resolve o gerenciamento de dependências. Jupyter Notebooks resolvem a exploração e documentação interativa. Juntos, são o ambiente padrão da indústria para ciência de dados.


2. Anaconda

Anaconda é uma distribuição Python que inclui:

  • O próprio Python
  • Mais de 250 bibliotecas científicas pré-instaladas
  • O gerenciador de pacotes conda
  • O Anaconda Navigator (interface gráfica)
  • Jupyter Notebook e JupyterLab

2.1 Instalação

Baixe o instalador em https://www.anaconda.com/download

Escolha a versão para seu sistema operacional (Windows, macOS ou Linux). Após a instalação, verifique no terminal:

conda --version
python --version

2.2 conda vs pip

Ambos são gerenciadores de pacotes, mas com diferenças importantes:

conda                          pip
─────────────────────────────────────────────────────
Gerencia Python também         Só gerencia pacotes Python
Resolve dependências C/C++     Só pacotes Python puros
Mais lento                     Mais rápido
Repositório menor              Repositório maior (PyPI)
Ideal para ML/ciência de dados Ideal para projetos Python gerais

Na prática, em projetos de ML você vai usar os dois: conda para instalar PyTorch com suporte a GPU, e pip para pacotes disponíveis apenas no PyPI.

2.3 Gerenciando ambientes conda

# Criar um novo ambiente com Python 3.11
conda create -n curso_ia python=3.11

# Listar todos os ambientes
conda env list

# Ativar um ambiente
conda activate curso_ia

# Desativar o ambiente atual
conda deactivate

# Remover um ambiente completamente
conda env remove -n curso_ia

# Exportar ambiente para arquivo (para compartilhar)
conda env export > environment.yml

# Recriar ambiente a partir do arquivo
conda env create -f environment.yml

O arquivo environment.yml exportado tem este formato:

name: curso_ia
channels:
  - defaults
  - conda-forge
dependencies:
  - python=3.11
  - numpy=1.26.0
  - pandas=2.1.0
  - matplotlib=3.8.0
  - scikit-learn=1.3.0
  - jupyter=1.0.0
  - pip:
    - torch==2.1.0
    - transformers==4.35.0

2.4 Instalando pacotes

# Instalar um pacote com conda
conda install numpy

# Instalar versão específica
conda install numpy=1.26.0

# Instalar múltiplos pacotes de uma vez
conda install numpy pandas matplotlib scikit-learn jupyter

# Instalar de um canal específico (conda-forge tem mais pacotes)
conda install -c conda-forge lightgbm

# Instalar com pip (dentro do ambiente conda ativado)
pip install torch torchvision

# Listar pacotes instalados no ambiente atual
conda list

# Atualizar um pacote
conda update numpy

# Remover um pacote
conda remove numpy

2.5 Configurando o ambiente do curso

Execute estes comandos para configurar o ambiente completo para todas as aulas:

# Criar e ativar ambiente
conda create -n curso_ia python=3.11
conda activate curso_ia

# Instalar bibliotecas de dados
conda install numpy pandas matplotlib seaborn scikit-learn jupyter

# Instalar PyTorch (CPU — para GPU veja pytorch.org/get-started)
conda install pytorch torchvision torchaudio -c pytorch

# Instalar Hugging Face
pip install transformers datasets

# Verificar instalações
python -c "import numpy; print('NumPy:', numpy.__version__)"
python -c "import pandas; print('Pandas:', pandas.__version__)"
python -c "import torch; print('PyTorch:', torch.__version__)"

3. Jupyter Notebooks

Um Jupyter Notebook é um documento interativo que combina código executável, texto formatado (Markdown), equações matemáticas (LaTeX), gráficos e outros elementos visuais em um único arquivo .ipynb.

3.1 Iniciando o Jupyter

# Ativar o ambiente primeiro
conda activate curso_ia

# Iniciar o Jupyter Notebook (abre no navegador)
jupyter notebook

# Ou iniciar o JupyterLab (interface mais moderna)
jupyter lab

O navegador abrirá automaticamente em http://localhost:8888. Você verá o explorador de arquivos do Jupyter.

3.2 Criando um notebook

No explorador de arquivos do Jupyter: - Clique em "New" → "Python 3" - Um novo notebook abre com uma célula vazia

3.3 Tipos de células

Jupyter tem três tipos principais de células:

Code cells — contêm código Python executável:

# Isso é uma code cell
x = 10
y = 20
print(x + y)  # 30

Markdown cells — contêm texto formatado:

# Título grande
## Subtítulo
### Seção menor

**negrito**, *itálico*, `código inline`

- Item 1
- Item 2

1. Numerado 1
2. Numerado 2

Raw cells — conteúdo bruto, não formatado nem executado. Raramente usadas.

3.4 Atalhos de teclado essenciais

Modo de comando (pressione Esc para entrar):

Enter       — entrar no modo de edição da célula
A           — inserir célula acima
B           — inserir célula abaixo
D D         — deletar célula (pressione D duas vezes)
M           — converter célula para Markdown
Y           — converter célula para código
Z           — desfazer deleção de célula
Shift+Enter — executar célula e ir para a próxima
Ctrl+Enter  — executar célula e ficar nela
Alt+Enter   — executar célula e inserir nova abaixo

Modo de edição (pressione Enter para entrar):

Shift+Enter  — executar célula e ir para a próxima
Ctrl+Enter   — executar célula e ficar nela
Tab          — autocompletar
Shift+Tab    — mostrar documentação da função
Ctrl+/       — comentar/descomentar linha
Esc          — voltar ao modo de comando

4. Funcionalidades Especiais do Jupyter

4.1 Magic commands

Comandos especiais que começam com % (line magic) ou %% (cell magic).

# %timeit — mede o tempo de execução de uma linha
%timeit [x**2 for x in range(1000)]

# %%timeit — mede o tempo de toda a célula
%%timeit
total = 0
for x in range(1000):
    total += x**2

# %run — executa um arquivo Python externo
%run meu_script.py

# %load — carrega o conteúdo de um arquivo na célula
%load meu_script.py

# %who — lista variáveis definidas na sessão
%who

# %whos — lista variáveis com detalhes
%whos

# %reset — limpa todas as variáveis da sessão
%reset

# %matplotlib inline — renderiza gráficos diretamente no notebook
%matplotlib inline

# %matplotlib widget — gráficos interativos
%matplotlib widget

# %%html — renderiza HTML na célula
%%html
<h1 style="color: blue">Título em HTML</h1>

# !comando — executa comando no terminal
!pip install seaborn
!ls -la
!conda list

4.2 Exibindo resultados

No Jupyter, o resultado da última expressão de uma célula é exibido automaticamente, sem precisar de print().

# Isso exibe automaticamente
2 + 2
# Isso também
import pandas as pd
df = pd.DataFrame({"a": [1,2,3], "b": [4,5,6]})
df  # exibe a tabela formatada automaticamente

4.3 Exibindo múltiplos resultados

from IPython.display import display

a = [1, 2, 3]
b = {"x": 10}

display(a)
display(b)

4.4 Equações matemáticas com LaTeX

No Jupyter você pode escrever equações matemáticas em células Markdown usando LaTeX:

Inline (dentro do texto): $E = mc^2$

Em bloco separado:

$$
\frac{\partial L}{\partial w} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i) x_i
$$

Isso renderiza como equações formatadas, extremamente útil para documentar fórmulas de ML como gradiente descendente, funções de perda e métricas.

4.5 Inspecionando objetos

import numpy as np

arr = np.array([1, 2, 3, 4, 5])

# ? mostra a documentação
arr?

# ?? mostra o código-fonte
np.sum??

# help() mostra documentação completa
help(np.array)

# Tab após ponto mostra os métodos disponíveis
# (só funciona no Jupyter, não em texto estático)
arr.  # pressione Tab aqui

5. Boas Práticas em Jupyter Notebooks

5.1 Estrutura recomendada de um notebook

1. Título e descrição (Markdown)
2. Imports e configurações
3. Carregamento de dados
4. Exploração inicial (EDA)
5. Pré-processamento
6. Modelagem
7. Avaliação
8. Conclusões

5.2 Mantenha células pequenas e focadas

# Célula 1 — carregamento
import pandas as pd
df = pd.read_csv("dados.csv")

# Célula 2 — inspeção inicial (célula separada)
print(df.shape)
print(df.dtypes)
df.head()

# Célula 3 — estatísticas (célula separada)
df.describe()

Células grandes que fazem muitas coisas são difíceis de debugar. Se uma célula falha no meio, você não sabe qual parte causou o erro.

5.3 Reinicie e execute tudo periodicamente

Um erro comum em Jupyter é ter células executadas fora de ordem, criando dependências invisíveis. Periodicamente:

  • Kernel → Restart & Run All

Isso garante que o notebook funciona do início ao fim em ordem sequencial.

5.4 Use Markdown generosamente

## 3. Análise Exploratória

Nesta seção vamos explorar a distribuição das variáveis e identificar
possíveis outliers e valores ausentes.

### 3.1 Distribuição da variável alvo

O gráfico abaixo mostra que o dataset está levemente desbalanceado,
com 60% de exemplos da classe 0 e 40% da classe 1.

5.5 Salve com frequência

O Jupyter tem autosave, mas não confie cegamente:

# Ctrl+S — salva o notebook
# Ou: File → Save and Checkpoint

5.6 Nomeie os notebooks com clareza

# Ruim
Untitled.ipynb
notebook1.ipynb

# Bom
01_exploracao_dataset_vendas.ipynb
02_preprocessamento_e_feature_engineering.ipynb
03_treinamento_modelo_classificacao.ipynb

6. JupyterLab vs Jupyter Notebook

JupyterLab é a evolução do Jupyter Notebook clássico, com interface mais moderna:

Jupyter Notebook         JupyterLab
───────────────────────────────────────────────────────
Interface simples        Interface tipo IDE
Um notebook por vez      Múltiplos arquivos lado a lado
Sem explorador lateral   Explorador de arquivos lateral
Menos extensões          Suporte rico a extensões
Mais estável             Mais funcionalidades

Para o curso, ambos funcionam perfeitamente. Se você está começando, Jupyter Notebook clássico é mais simples. Se quiser uma experiência mais completa, use JupyterLab.


7. Alternativas ao Jupyter Local

Google Colab

Jupyter Notebook hospedado no Google. Completamente gratuito, não precisa instalar nada, oferece GPU gratuita.

Acesse em: https://colab.research.google.com

# No Colab, instale pacotes assim
!pip install transformers

# Montar Google Drive para acessar seus arquivos
from google.colab import drive
drive.mount('/content/drive')

Vantagens do Colab: - GPU gratuita (T4 ou melhor) - Colaboração em tempo real - Zero configuração local - Integração com Google Drive

Desvantagens: - Sessão expira após inatividade - Armazenamento temporário - Velocidade de internet importa

Kaggle Notebooks

Jupyter hospedado no Kaggle. Também gratuito com GPU, mas com acesso direto a datasets do Kaggle.

Acesse em: https://www.kaggle.com/code


8. Convertendo Notebooks

Notebooks podem ser exportados para outros formatos:

# Exportar para HTML
jupyter nbconvert --to html meu_notebook.ipynb

# Exportar para PDF
jupyter nbconvert --to pdf meu_notebook.ipynb

# Exportar para script Python
jupyter nbconvert --to script meu_notebook.ipynb

# Executar notebook do terminal (útil em pipelines de CI/CD)
jupyter nbconvert --to notebook --execute meu_notebook.ipynb

9. Exemplo Completo: Primeiro Notebook de Análise

Este é o conteúdo de um notebook completo de introdução. Cada bloco representa uma célula separada.

Célula 1 — Markdown:

# Análise Exploratória — Dataset de Notas

Neste notebook vamos explorar um dataset simples de notas de alunos
para praticar as funcionalidades do Jupyter e das bibliotecas de dados.

Célula 2 — Code:

# Imports e configurações
import random
import math
%matplotlib inline

# Reprodutibilidade
random.seed(42)

print("Ambiente configurado!")

Célula 3 — Markdown:

## 1. Gerando o Dataset

Vamos simular um dataset de 100 alunos com notas em três disciplinas.

Célula 4 — Code:

# Gerando dados simulados
n_alunos = 100

nomes = [f"Aluno_{i:03d}" for i in range(1, n_alunos + 1)]
matematica = [round(random.gauss(7.0, 1.5), 1) for _ in range(n_alunos)]
portugues  = [round(random.gauss(6.5, 1.8), 1) for _ in range(n_alunos)]
ciencias   = [round(random.gauss(7.2, 1.3), 1) for _ in range(n_alunos)]

# Limitar notas entre 0 e 10
matematica = [max(0.0, min(10.0, n)) for n in matematica]
portugues  = [max(0.0, min(10.0, n)) for n in portugues]
ciencias   = [max(0.0, min(10.0, n)) for n in ciencias]

print(f"Dataset gerado: {n_alunos} alunos")
print(f"Primeiras notas de matemática: {matematica[:5]}")

Célula 5 — Code:

# Calculando médias individuais
medias = [
    round((matematica[i] + portugues[i] + ciencias[i]) / 3, 2)
    for i in range(n_alunos)
]

# Situação de cada aluno
situacoes = ["Aprovado" if m >= 6.0 else "Reprovado" for m in medias]

aprovados = situacoes.count("Aprovado")
reprovados = situacoes.count("Reprovado")

print(f"Aprovados:  {aprovados} ({aprovados/n_alunos*100:.1f}%)")
print(f"Reprovados: {reprovados} ({reprovados/n_alunos*100:.1f}%)")

Célula 6 — Code:

# Estatísticas por disciplina
disciplinas = {
    "Matemática": matematica,
    "Português": portugues,
    "Ciências": ciencias
}

print(f"{'Disciplina':<15} {'Média':>8} {'Mín':>6} {'Máx':>6} {'Desvio':>8}")
print("-" * 45)

for nome, notas in disciplinas.items():
    media = sum(notas) / len(notas)
    minimo = min(notas)
    maximo = max(notas)
    variancia = sum((n - media)**2 for n in notas) / len(notas)
    desvio = math.sqrt(variancia)
    print(f"{nome:<15} {media:>8.2f} {minimo:>6.1f} {maximo:>6.1f} {desvio:>8.2f}")

Saída:

Disciplina        Média    Mín    Máx   Desvio
─────────────────────────────────────────────
Matemática         6.98    2.8   10.0     1.48
Português          6.51    1.9   10.0     1.76
Ciências           7.19    3.5   10.0     1.28

Célula 7 — Markdown:

## 2. Conclusões

- A turma tem desempenho levemente melhor em Ciências
- Português apresenta maior variação nas notas
- Aproximadamente 75% dos alunos foram aprovados
- Os dados seguem uma distribuição aproximadamente normal, como esperado

Na próxima etapa, usaremos Pandas e Matplotlib para análises mais sofisticadas.

Resumo da Aula

  • Anaconda gerencia ambientes Python isolados e pacotes científicos
  • conda create -n nome python=3.11 cria um ambiente novo
  • Sempre ative o ambiente antes de trabalhar: conda activate nome
  • Jupyter Notebook combina código, texto, gráficos e equações em um só lugar
  • Células podem ser de código ou Markdown
  • Shift+Enter executa uma célula e avança, Ctrl+Enter executa e fica
  • Magic commands como %timeit, %matplotlib inline e %whos são muito úteis
  • Reinicie o kernel e execute tudo periodicamente para garantir reprodutibilidade
  • Google Colab é uma alternativa gratuita com GPU quando não quiser instalar localmente
  • Organize notebooks com títulos claros, células pequenas e Markdown explicativo

Exercícios

  1. Explique a diferença entre conda install numpy e pip install numpy. Em quais situações você usaria cada um? Existe algum risco em misturar os dois no mesmo ambiente?

    ✓ Resposta:

    conda install numpy usa o gerenciador conda para baixar o pacote do repositório Anaconda (ou conda-forge). Ele resolve automaticamente dependências que incluem bibliotecas compiladas em C/C++, o que é crucial para NumPy, que usa extensões nativas para performance.

    pip install numpy usa o gerenciador pip para baixar do PyPI (Python Package Index). É mais simples e tem acesso a mais pacotes, mas não gerencia dependências de sistema.

    Use conda install para bibliotecas científicas que têm componentes compilados (NumPy, SciPy, PyTorch). Use pip install para pacotes disponíveis apenas no PyPI ou quando o pacote não tem versão conda.

    O risco de misturar: conda e pip têm resolvedores de dependências diferentes. Se você instalar o NumPy com conda e depois atualizar com pip, pip pode não saber sobre as dependências gerenciadas pelo conda e quebrar o ambiente. A boa prática é instalar tudo que puder com conda primeiro, e usar pip apenas para o que não está disponível no conda.

  2. Qual é a diferença entre os seguintes comandos no Jupyter? Descreva o que cada um faz e quando usaria cada um:

    Shift+Enter
    Ctrl+Enter
    Alt+Enter
    

    ✓ Resposta:

    Shift+Enter executa a célula atual e move o cursor para a próxima célula, criando uma nova se não existir. É o atalho mais usado no dia a dia — você executa e avança naturalmente pelo notebook.

    Ctrl+Enter executa a célula atual e mantém o cursor na mesma célula. Útil quando você está iterando na mesma célula, ajustando código e re-executando várias vezes até ficar satisfeito com o resultado.

    Alt+Enter executa a célula atual e insere uma nova célula em branco logo abaixo. Útil quando você quer adicionar código novo continuando o raciocínio da célula atual, sem precisar ir ao menu ou usar atalhos separados.

  3. Explique o que são magic commands no Jupyter. Dê três exemplos concretos de magic commands que seriam úteis em um projeto de Machine Learning e explique como cada um ajudaria.

    ✓ Resposta:

    Magic commands são comandos especiais do IPython que começam com % (aplicam a uma linha) ou %% (aplicam a toda a célula). Eles não são Python puro, mas extensões do kernel Jupyter.

    Três exemplos úteis em ML:

    %timeit mede o tempo de execução de uma expressão. Em ML, isso é útil para comparar implementações — por exemplo, verificar se uma operação vectorizada com NumPy é realmente mais rápida que um loop Python:

    %timeit sum([x**2 for x in range(10000)])
    %timeit import numpy as np; np.sum(np.arange(10000)**2)
    

    %matplotlib inline configura o Matplotlib para renderizar gráficos diretamente no notebook em vez de abrir uma janela separada. Essencial para visualizar distribuições de dados, curvas de aprendizado e resultados de modelos sem sair do notebook.

    %%time mede o tempo de execução de uma célula inteira. Útil para medir quanto demora o treinamento de um epoch ou o carregamento de um dataset grande, sem precisar escrever código de timing explicitamente.

  4. Um colega te manda um notebook com o seguinte relato: "O notebook funcionou para mim, mas quando você rodar, os resultados podem ser diferentes". Explique duas causas possíveis para esse problema e como cada uma pode ser resolvida.

    ✓ Resposta:

    Causa 1 — Ausência de seed para aleatoriedade. Se o notebook usa funções aleatórias (como embaralhar o dataset, inicializar pesos de modelos, ou dividir treino/teste) sem fixar uma seed, cada execução produz resultados diferentes.

    Solução: definir a seed no início do notebook:

    import random
    import numpy as np
    random.seed(42)
    np.random.seed(42)
    

    Causa 2 — Dependências com versões diferentes. Se o colega usa NumPy 1.24 e você usa 1.26, resultados numéricos podem diferir por mudanças internas nos algoritmos, ou certas APIs podem se comportar de forma diferente.

    Solução: compartilhar o ambiente junto com o notebook, seja via environment.yml (conda) ou requirements.txt (pip), e instruir o receptor a recriar o ambiente antes de executar:

    conda env create -f environment.yml
    conda activate curso_ia
    jupyter notebook analise.ipynb
    
  5. Descreva a estrutura recomendada para um Jupyter Notebook de análise exploratória de dados (EDA) em um projeto de ML. Quais seções ele deve ter e o que cada uma deve conter?

    ✓ Resposta:

    Estrutura recomendada para um notebook de EDA:

    Seção 1 — Título e objetivo (Markdown): descreva o dataset, o problema que está sendo investigado e o que o notebook vai responder.

    Seção 2 — Imports e configuração: todos os imports no topo, configuração de seeds, estilo dos gráficos, tamanho de figura padrão.

    Seção 3 — Carregamento dos dados: leitura do arquivo, primeiras linhas com .head(), shape, tipos de colunas com .dtypes.

    Seção 4 — Qualidade dos dados: verificar valores ausentes, duplicatas, tipos incorretos. Decidir como tratar cada problema.

    Seção 5 — Distribuições univariadas: histogramas e boxplots de cada variável numérica. Contagem de frequências de variáveis categóricas. Identificar outliers.

    Seção 6 — Relações entre variáveis: correlações, scatter plots entre features e target, análise de grupos.

    Seção 7 — Análise da variável alvo: distribuição do target, balanceamento de classes, variação ao longo do tempo se for série temporal.

    Seção 8 — Conclusões e próximos passos (Markdown): resumo das principais descobertas, features que parecem relevantes, problemas identificados, decisões de pré-processamento a tomar.

  6. Compare Google Colab e Jupyter local (via Anaconda). Quais são as vantagens e desvantagens de cada um? Em qual cenário você escolheria cada opção?

    ✓ Resposta:

    Google Colab:

    Vantagens: zero instalação, GPU gratuita (essencial para treinar modelos grandes), acessível de qualquer navegador, fácil compartilhamento como um Google Doc, integração com Google Drive para dados.

    Desvantagens: sessão expira após 90 minutos de inatividade (ou 12 horas contínuas no plano gratuito), ambiente reiniciado a cada sessão exige reinstalar pacotes, dependente de conexão com a internet, armazenamento temporário perde arquivos ao reiniciar.

    Jupyter local via Anaconda:

    Vantagens: dados ficam locais (sem upload), sessão nunca expira, controle total do ambiente, funciona offline, mais rápido para datasets grandes (sem transferência de rede).

    Desvantagens: exige instalação e configuração, GPU própria necessária para treinamento rápido (placas de GPU de consumo como RTX são caras), mais difícil de compartilhar resultados.

    Escolha Colab quando: estiver aprendendo e não quiser configurar ambiente, precisar de GPU para treinar modelos profundos, quiser compartilhar um notebook com alguém facilmente, ou estiver trabalhando de um computador sem GPU.

    Escolha Jupyter local quando: trabalhar com dados sensíveis que não devem sair da sua máquina, tiver uma GPU local, precisar de sessões longas sem interrupção, ou trabalhar com datasets muito grandes que seria lento fazer upload.

Referências