Capítulo 1: Introdução e Setup do Ambiente
Configurando seu ambiente de desenvolvimento para IA no Windows 10
1.1 Objetivos deste Capítulo
- Entender o que é Inteligência Artificial e suas aplicações
- Configurar Python 3.9+ no Windows 10
- Instalar e configurar ambientes virtuais
- Configurar IDEs (VS Code, PyCharm, Jupyter)
- Instalar bibliotecas essenciais para IA
1.2 O que é Inteligência Artificial?
A Inteligência Artificial (IA) é um campo da ciência da computação que se concentra na criação de sistemas capazes de realizar tarefas que normalmente requerem inteligência humana.
Principais áreas da IA:
- Machine Learning: Algoritmos que aprendem com dados
- Deep Learning: Redes neurais artificiais profundas
- Processamento de Linguagem Natural (NLP): Compreensão e geração de texto
- Visão Computacional: Análise e interpretação de imagens
- Robótica: Sistemas autônomos físicos
1.3 Instalação do Python no Windows 10
Passo 1: Download do Python
- Acesse python.org/downloads
- Baixe Python 3.11+ (versão mais recente)
- Execute o instalador como administrador
- ⚠️ IMPORTANTE: Marque "Add Python to PATH"
- Clique em "Install Now"
# Verificar instalação do Python
python --version
# Verificar instalação do pip
pip --version
# Atualizar pip
python -m pip install --upgrade pip
1.4 Configurando Ambientes Virtuais
Por que usar ambientes virtuais?
- Isolamento de dependências entre projetos
- Evita conflitos entre versões de bibliotecas
- Facilita a reprodução do ambiente em outras máquinas
- Permite trabalhar com diferentes versões do Python
# Criar ambiente virtual
python -m venv ia_ambiente
# Ativar ambiente virtual (Windows)
ia_ambiente\Scripts\activate
# Verificar que o ambiente está ativo (deve aparecer (ia_ambiente) no prompt)
# Instalar bibliotecas básicas
pip install numpy pandas matplotlib seaborn scikit-learn jupyter
# Desativar ambiente virtual
deactivate
1.5 Instalação e Configuração de IDEs
Visual Studio Code
IDE leve e versátil, ideal para iniciantes
- Baixe do site oficial
- Instale extensões: Python, Jupyter, GitHub Copilot
- Configure o interpretador Python
Jupyter Notebook
Ambiente interativo para análise de dados
- Já instalado com pip install jupyter
- Execute: jupyter notebook
- Acesse localhost:8888 no navegador
Exercício Prático 1.1
Objetivo:
Verificar se seu ambiente está configurado corretamente e executar seu primeiro código Python para IA.
# Teste de configuração do ambiente
import sys
print(f"Versão do Python: {sys.version}")
# Teste das bibliotecas principais
try:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn
print("✅ Todas as bibliotecas foram importadas com sucesso!")
# Teste simples com NumPy
array = np.array([1, 2, 3, 4, 5])
print(f"Array NumPy: {array}")
print(f"Média: {np.mean(array)}")
# Teste simples com Pandas
df = pd.DataFrame({'numeros': [1, 2, 3, 4, 5], 'quadrados': [1, 4, 9, 16, 25]})
print("DataFrame Pandas:")
print(df)
except ImportError as e:
print(f"❌ Erro ao importar biblioteca: {e}")
print("Execute: pip install numpy pandas matplotlib scikit-learn")
Tarefa: Execute este código e capture uma screenshot mostrando que todas as bibliotecas foram importadas com sucesso. Isso confirmará que seu ambiente está configurado corretamente.
Capítulo 2: Python para Inteligência Artificial
Dominando as ferramentas Python essenciais para IA
2.1 Bibliotecas Essenciais para IA
NumPy
Computação científica e arrays multidimensionais
Pandas
Manipulação e análise de dados
Matplotlib/Seaborn
Visualização de dados
Scikit-learn
Machine Learning clássico
TensorFlow/PyTorch
Deep Learning
NLTK/SpaCy
Processamento de linguagem natural
2.2 NumPy - Fundamentos
import numpy as np
# Criação de arrays
array_1d = np.array([1, 2, 3, 4, 5])
array_2d = np.array([[1, 2, 3], [4, 5, 6]])
array_zeros = np.zeros((3, 3))
array_ones = np.ones((2, 4))
array_range = np.arange(0, 10, 2) # 0, 2, 4, 6, 8
array_linspace = np.linspace(0, 1, 5) # 5 números entre 0 e 1
print("Array 1D:", array_1d)
print("Array 2D:")
print(array_2d)
print("Shape do array 2D:", array_2d.shape)
print("Tipo de dados:", array_2d.dtype)
# Operações matemáticas
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print("Soma:", a + b)
print("Multiplicação elemento a elemento:", a * b)
print("Produto escalar:", np.dot(a, b))
print("Média:", np.mean(a))
print("Desvio padrão:", np.std(a))
# Reshaping e indexação
matriz = np.arange(12).reshape(3, 4)
print("Matriz 3x4:")
print(matriz)
print("Primeira linha:", matriz[0, :])
print("Primeira coluna:", matriz[:, 0])
print("Elemento [1,2]:", matriz[1, 2])
2.3 Pandas - Manipulação de Dados
import pandas as pd
import numpy as np
# Criando DataFrames
dados = {
'nome': ['Ana', 'João', 'Maria', 'Pedro', 'Paula'],
'idade': [25, 30, 35, 28, 32],
'salario': [5000, 6000, 7000, 5500, 6500],
'departamento': ['TI', 'RH', 'TI', 'Vendas', 'RH']
}
df = pd.DataFrame(dados)
print("DataFrame original:")
print(df)
# Informações básicas
print("\nInformações do DataFrame:")
print(df.info())
print("\nEstatísticas descritivas:")
print(df.describe())
# Seleção e filtragem
print("\nFiltro: idade > 30")
print(df[df['idade'] > 30])
print("\nApenas colunas nome e salario:")
print(df[['nome', 'salario']])
# Agrupamento
print("\nMédia de salário por departamento:")
print(df.groupby('departamento')['salario'].mean())
# Adicionando nova coluna
df['salario_anual'] = df['salario'] * 12
print("\nDataFrame com salário anual:")
print(df)
# Tratamento de dados missing
df_com_nan = df.copy()
df_com_nan.loc[2, 'salario'] = np.nan
print("\nDataFrame com valor missing:")
print(df_com_nan)
# Removendo ou preenchendo NaN
print("\nPreenchendo NaN com a média:")
df_com_nan['salario'].fillna(df_com_nan['salario'].mean(), inplace=True)
print(df_com_nan)
Exercício Prático 2.1: Análise de Vendas
Cenário Real:
Você trabalha em uma empresa de e-commerce e precisa analisar dados de vendas do último trimestre para identificar padrões e tendências.
# Simulando dados de vendas de e-commerce
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Gerando dados sintéticos de vendas
np.random.seed(42)
n_vendas = 1000
dados_vendas = {
'data': pd.date_range('2024-01-01', periods=n_vendas, freq='H'),
'produto': np.random.choice(['Smartphone', 'Laptop', 'Tablet', 'Smartwatch'], n_vendas),
'categoria': np.random.choice(['Eletrônicos', 'Acessórios'], n_vendas),
'preco': np.random.uniform(100, 2000, n_vendas),
'quantidade': np.random.randint(1, 5, n_vendas),
'regiao': np.random.choice(['Norte', 'Sul', 'Leste', 'Oeste'], n_vendas)
}
df_vendas = pd.DataFrame(dados_vendas)
df_vendas['receita'] = df_vendas['preco'] * df_vendas['quantidade']
print("=== ANÁLISE DE VENDAS ===")
print(f"Total de vendas: {len(df_vendas)}")
print(f"Receita total: R$ {df_vendas['receita'].sum():,.2f}")
# TAREFA 1: Encontre o produto mais vendido (por quantidade)
# SEU CÓDIGO AQUI
# TAREFA 2: Calcule a receita média por região
# SEU CÓDIGO AQUI
# TAREFA 3: Identifique o mês com maior faturamento
# SEU CÓDIGO AQUI
# TAREFA 4: Crie um gráfico mostrando vendas por produto
# SEU CÓDIGO AQUI
Tarefas para Resolver:
- Identifique qual produto teve mais unidades vendidas
- Calcule a receita média por região geográfica
- Determine qual mês teve o maior faturamento
- Crie um gráfico de barras mostrando vendas por produto
- Desafio: Identifique tendências de vendas por hora do dia
Projeto Real 2.1: Sistema de Análise de Logs
Aplicação no Mundo Real:
Empresas de tecnologia analisam milhões de logs diariamente para identificar problemas, otimizar performance e detectar anomalias de segurança.
import pandas as pd
import numpy as np
import re
from datetime import datetime, timedelta
class AnalisadorLogs:
def __init__(self):
self.df_logs = None
def gerar_logs_exemplo(self, n_logs=10000):
"""Gera logs sintéticos simulando servidor web Apache/Nginx"""
ips = ['192.168.1.' + str(i) for i in np.random.randint(1, 255, 1000)]
status_codes = [200, 404, 500, 301, 403]
user_agents = ['Chrome', 'Firefox', 'Safari', 'Bot']
logs = []
base_time = datetime.now() - timedelta(days=7)
for i in range(n_logs):
timestamp = base_time + timedelta(seconds=np.random.randint(0, 604800))
ip = np.random.choice(ips)
status = np.random.choice(status_codes, p=[0.7, 0.15, 0.05, 0.05, 0.05])
bytes_sent = np.random.randint(1000, 50000)
response_time = np.random.exponential(0.5) # Tempo de resposta em segundos
user_agent = np.random.choice(user_agents)
# Simular ataques DDoS (muitas requisições do mesmo IP)
if np.random.random() < 0.01: # 1% chance de ataque
for _ in range(np.random.randint(50, 200)):
logs.append({
'timestamp': timestamp,
'ip': ip,
'status_code': 429, # Too Many Requests
'bytes_sent': 0,
'response_time': 0.1,
'user_agent': 'Bot'
})
else:
logs.append({
'timestamp': timestamp,
'ip': ip,
'status_code': status,
'bytes_sent': bytes_sent,
'response_time': response_time,
'user_agent': user_agent
})
self.df_logs = pd.DataFrame(logs)
self.df_logs['timestamp'] = pd.to_datetime(self.df_logs['timestamp'])
return self.df_logs
def analisar_performance(self):
"""Análise de performance do servidor"""
print("=== ANÁLISE DE PERFORMANCE ===")
# Tempo de resposta médio
tempo_medio = self.df_logs['response_time'].mean()
print(f"Tempo de resposta médio: {tempo_medio:.3f}s")
# Requisições por segundo
req_por_segundo = len(self.df_logs) / (7 * 24 * 3600) # 7 dias
print(f"Requisições por segundo: {req_por_segundo:.2f}")
# Status codes mais frequentes
print("\nStatus codes mais frequentes:")
status_counts = self.df_logs['status_code'].value_counts()
for status, count in status_counts.head().items():
percentage = (count / len(self.df_logs)) * 100
print(f" {status}: {count} ({percentage:.1f}%)")
def detectar_anomalias(self):
"""Detecta possíveis ataques ou anomalias"""
print("\n=== DETECÇÃO DE ANOMALIAS ===")
# IPs com muitas requisições (possível DDoS)
req_por_ip = self.df_logs['ip'].value_counts()
threshold_ddos = req_por_ip.quantile(0.95) # Top 5% IPs
ips_suspeitos = req_por_ip[req_por_ip > threshold_ddos]
if len(ips_suspeitos) > 0:
print(f"🚨 {len(ips_suspeitos)} IPs suspeitos de DDoS detectados:")
for ip, count in ips_suspeitos.head().items():
print(f" {ip}: {count} requisições")
# Picos de erro 5xx
erros_servidor = self.df_logs[self.df_logs['status_code'] >= 500]
if len(erros_servidor) > 0:
erro_rate = len(erros_servidor) / len(self.df_logs) * 100
print(f"\n⚠️ Taxa de erros 5xx: {erro_rate:.2f}%")
if erro_rate > 5: # Mais de 5% de erros
print("🔥 ALERTA: Taxa de erro muito alta!")
def gerar_relatorio(self):
"""Gera relatório completo"""
if self.df_logs is None:
print("Erro: Nenhum log carregado!")
return
print("=== RELATÓRIO DE ANÁLISE DE LOGS ===")
print(f"Período analisado: {self.df_logs['timestamp'].min()} até {self.df_logs['timestamp'].max()}")
print(f"Total de requisições: {len(self.df_logs):,}")
self.analisar_performance()
self.detectar_anomalias()
# Análise temporal (requisições por hora)
self.df_logs['hora'] = self.df_logs['timestamp'].dt.hour
req_por_hora = self.df_logs['hora'].value_counts().sort_index()
hora_pico = req_por_hora.idxmax()
print(f"\n📊 Hora de maior tráfego: {hora_pico}:00 ({req_por_hora[hora_pico]} requisições)")
# Exemplo de uso
if __name__ == "__main__":
analisador = AnalisadorLogs()
# Gerar dados sintéticos
print("Gerando logs sintéticos...")
logs = analisador.gerar_logs_exemplo(50000)
# Executar análise completa
analisador.gerar_relatorio()
# Salvar relatório para arquivo
with open('relatorio_logs.txt', 'w') as f:
# Implementar salvamento do relatório
pass
Capítulo 3: Matemática e Estatística para IA
Base matemática essencial para algoritmos de IA
3.1 Fundamentos Matemáticos
Álgebra Linear
Vetores, matrizes, transformações
Cálculo
Derivadas, gradientes, otimização
Estatística
Probabilidade, distribuições, inferência
Por que a matemática é importante na IA?
- Algoritmos de aprendizado são baseados em otimização matemática
- Redes neurais usam álgebra linear e cálculo
- Análise de dados requer estatística e probabilidade
- Avaliação de modelos usa métricas estatísticas
3.2 Álgebra Linear Aplicada
import numpy as np
import matplotlib.pyplot as plt
print("=== ÁLGEBRA LINEAR PARA IA ===")
# 1. VETORES - Representam características/features
vetor_pessoa1 = np.array([25, 70, 1.75]) # idade, peso, altura
vetor_pessoa2 = np.array([30, 80, 1.80])
print("Pessoa 1 (idade, peso, altura):", vetor_pessoa1)
print("Pessoa 2:", vetor_pessoa2)
# Distância euclidiana (similaridade entre pessoas)
distancia = np.linalg.norm(vetor_pessoa1 - vetor_pessoa2)
print(f"Distância entre pessoas: {distancia:.2f}")
# 2. MATRIZES - Conjuntos de dados
# Cada linha = uma pessoa, cada coluna = uma característica
dataset = np.array([
[25, 70, 1.75], # Pessoa 1
[30, 80, 1.80], # Pessoa 2
[35, 90, 1.85], # Pessoa 3
[22, 65, 1.70] # Pessoa 4
])
print("\nDataset (4 pessoas x 3 características):")
print(dataset)
print("Shape:", dataset.shape)
# Estatísticas por característica (coluna)
print("\nMédias por característica:")
print("Idade média:", np.mean(dataset[:, 0]))
print("Peso médio:", np.mean(dataset[:, 1]))
print("Altura média:", np.mean(dataset[:, 2]))
# 3. MULTIPLICAÇÃO DE MATRIZES - Base de muitos algoritmos
# Exemplo: transformação linear (normalização)
print("\n=== TRANSFORMAÇÕES LINEARES ===")
# Matriz de transformação para normalizar dados (z-score)
media = np.mean(dataset, axis=0)
desvio = np.std(dataset, axis=0)
print("Médias:", media)
print("Desvios padrão:", desvio)
# Normalização Z-score
dataset_normalizado = (dataset - media) / desvio
print("\nDataset normalizado (z-score):")
print(dataset_normalizado)
# 4. AUTOVALORES E AUTOVETORES - PCA (Principal Component Analysis)
print("\n=== ANÁLISE DE COMPONENTES PRINCIPAIS (PCA) ===")
# Matriz de covariância
cov_matrix = np.cov(dataset_normalizado.T)
print("Matriz de covariância:")
print(cov_matrix)
# Calcular autovalores e autovetores
autovalores, autovetores = np.linalg.eig(cov_matrix)
print("\nAutovalores (importância dos componentes):", autovalores)
print("Autovetores (direções dos componentes):")
print(autovetores)
# Ordenar por importância
idx = autovalores.argsort()[::-1]
autovalores = autovalores[idx]
autovetores = autovetores[:, idx]
print("\nComponentes ordenados por importância:")
for i, val in enumerate(autovalores):
var_explicada = val / np.sum(autovalores) * 100
print(f"Componente {i+1}: {var_explicada:.1f}% da variância")
# 5. PRODUTO ESCALAR - Similaridade de cosseno
def similaridade_cosseno(v1, v2):
"""Calcula similaridade de cosseno entre dois vetores"""
return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
# Exemplo: similaridade entre preferências musicais
# 0=não gosta, 5=gosta muito
pessoa_a = np.array([5, 1, 3, 4, 2]) # rock, pop, jazz, clássica, eletrônica
pessoa_b = np.array([4, 2, 3, 5, 1])
pessoa_c = np.array([1, 5, 2, 1, 5])
sim_ab = similaridade_cosseno(pessoa_a, pessoa_b)
sim_ac = similaridade_cosseno(pessoa_a, pessoa_c)
print(f"\n=== SISTEMA DE RECOMENDAÇÃO ===")
print(f"Similaridade A-B: {sim_ab:.3f}")
print(f"Similaridade A-C: {sim_ac:.3f}")
if sim_ab > sim_ac:
print("Pessoa A tem gostos mais similares a B")
else:
print("Pessoa A tem gostos mais similares a C")
3.3 Estatística e Probabilidade
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
print("=== ESTATÍSTICA PARA INTELIGÊNCIA ARTIFICIAL ===")
# 1. DISTRIBUIÇÕES DE PROBABILIDADE
np.random.seed(42)
# Simulando dados de altura de uma população
alturas = np.random.normal(170, 10, 1000) # média=170cm, desvio=10cm
print("Estatísticas descritivas das alturas:")
print(f"Média: {np.mean(alturas):.2f} cm")
print(f"Mediana: {np.median(alturas):.2f} cm")
print(f"Desvio padrão: {np.std(alturas):.2f} cm")
print(f"Variância: {np.var(alturas):.2f}")
# 2. TESTE DE HIPÓTESES
print("\n=== TESTE DE HIPÓTESES ===")
# H0: A altura média da população é 170cm
# H1: A altura média é diferente de 170cm
t_stat, p_value = stats.ttest_1samp(alturas, 170)
print(f"Estatística t: {t_stat:.4f}")
print(f"P-valor: {p_value:.4f}")
alpha = 0.05
if p_value < alpha:
print(f"Rejeitamos H0 (p < {alpha}): A média é significativamente diferente de 170cm")
else:
print(f"Não rejeitamos H0 (p >= {alpha}): Não há evidência de diferença")
# 3. CORRELAÇÃO E REGRESSÃO
print("\n=== ANÁLISE DE CORRELAÇÃO ===")
# Simulando dados de vendas vs. temperatura
temperatura = np.random.uniform(15, 35, 100) # Temperatura em °C
# Vendas de sorvete correlacionadas com temperatura
vendas_sorvete = 50 + 3 * temperatura + np.random.normal(0, 10, 100)
correlacao = np.corrcoef(temperatura, vendas_sorvete)[0, 1]
print(f"Correlação temperatura-vendas: {correlacao:.3f}")
# Interpretação da correlação
if abs(correlacao) > 0.7:
print("Correlação forte")
elif abs(correlacao) > 0.3:
print("Correlação moderada")
else:
print("Correlação fraca")
# 4. TEOREMA DE BAYES - Fundamental para classificação
print("\n=== TEOREMA DE BAYES ===")
# Exemplo: Classificação de emails (spam vs. não-spam)
# P(Spam) = 0.3 (30% dos emails são spam)
# P(Palavra "grátis" | Spam) = 0.8
# P(Palavra "grátis" | Não-spam) = 0.1
p_spam = 0.3
p_nao_spam = 0.7
p_gratis_dado_spam = 0.8
p_gratis_dado_nao_spam = 0.1
# P(Palavra "grátis") = P(grátis|spam)*P(spam) + P(grátis|não-spam)*P(não-spam)
p_gratis = p_gratis_dado_spam * p_spam + p_gratis_dado_nao_spam * p_nao_spam
# P(Spam | Palavra "grátis") = P(grátis|spam) * P(spam) / P(grátis)
p_spam_dado_gratis = (p_gratis_dado_spam * p_spam) / p_gratis
print(f"P(Spam | palavra 'grátis'): {p_spam_dado_gratis:.3f}")
print(f"Se um email contém 'grátis', há {p_spam_dado_gratis*100:.1f}% de chance de ser spam")
# 5. INTERVALOS DE CONFIANÇA
print("\n=== INTERVALOS DE CONFIANÇA ===")
# Calculando intervalo de confiança de 95% para a média das alturas
media_amostra = np.mean(alturas)
erro_padrao = stats.sem(alturas) # Erro padrão da média
intervalo_conf = stats.t.interval(0.95, len(alturas)-1, media_amostra, erro_padrao)
print(f"Intervalo de confiança 95% para altura média: [{intervalo_conf[0]:.2f}, {intervalo_conf[1]:.2f}] cm")
print("Interpretação: Temos 95% de confiança de que a altura média da população está neste intervalo")
# 6. BOOTSTRAP - Método de reamostragem
print("\n=== BOOTSTRAP ===")
def bootstrap_media(dados, n_amostras=1000):
"""Calcula distribuição bootstrap da média"""
medias_bootstrap = []
for _ in range(n_amostras):
amostra = np.random.choice(dados, size=len(dados), replace=True)
medias_bootstrap.append(np.mean(amostra))
return np.array(medias_bootstrap)
medias_boot = bootstrap_media(alturas)
ic_bootstrap = np.percentile(medias_boot, [2.5, 97.5])
print(f"Intervalo de confiança 95% (Bootstrap): [{ic_bootstrap[0]:.2f}, {ic_bootstrap[1]:.2f}] cm")
# 7. DETECÇÃO DE OUTLIERS
print("\n=== DETECÇÃO DE OUTLIERS ===")
def detectar_outliers_iqr(dados):
"""Detecta outliers usando método IQR"""
Q1 = np.percentile(dados, 25)
Q3 = np.percentile(dados, 75)
IQR = Q3 - Q1
limite_inferior = Q1 - 1.5 * IQR
limite_superior = Q3 + 1.5 * IQR
outliers = dados[(dados < limite_inferior) | (dados > limite_superior)]
return outliers, limite_inferior, limite_superior
outliers, lim_inf, lim_sup = detectar_outliers_iqr(alturas)
print(f"Limites para outliers: [{lim_inf:.2f}, {lim_sup:.2f}] cm")
print(f"Número de outliers detectados: {len(outliers)}")
print(f"Percentual de outliers: {len(outliers)/len(alturas)*100:.1f}%")
Exercício Prático 3.1: Análise A/B Testing
Cenário Real:
Uma empresa de e-commerce quer testar se um novo design de botão de compra aumenta a taxa de conversão. Você precisa analisar os dados do teste A/B e determinar se a diferença é estatisticamente significativa.
import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt
# Dados do teste A/B
np.random.seed(42)
# Grupo A (controle): botão azul tradicional
# Grupo B (teste): novo botão verde com animação
# Simulando dados reais de conversão
n_usuarios_a = 1000 # Usuários que viram versão A
n_usuarios_b = 1000 # Usuários que viram versão B
# Taxa de conversão real (desconhecida na prática)
taxa_real_a = 0.12 # 12% conversão versão A
taxa_real_b = 0.15 # 15% conversão versão B
# Gerando dados de conversão (1=converteu, 0=não converteu)
conversoes_a = np.random.binomial(1, taxa_real_a, n_usuarios_a)
conversoes_b = np.random.binomial(1, taxa_real_b, n_usuarios_b)
# TAREFA 1: Calcule as taxas de conversão observadas
taxa_observada_a = # SEU CÓDIGO AQUI
taxa_observada_b = # SEU CÓDIGO AQUI
print(f"Taxa de conversão A: {taxa_observada_a:.3f}")
print(f"Taxa de conversão B: {taxa_observada_b:.3f}")
print(f"Diferença observada: {taxa_observada_b - taxa_observada_a:.3f}")
# TAREFA 2: Teste de hipóteses
# H0: Taxa A = Taxa B (não há diferença)
# H1: Taxa A ≠ Taxa B (há diferença)
# Usar teste z para proporções
def teste_z_proporcoes(conv_a, n_a, conv_b, n_b):
"""Realiza teste z para diferença entre proporções"""
p_a = conv_a / n_a
p_b = conv_b / n_b
# Proporção pooled (sob H0: p_a = p_b)
p_pool = (conv_a + conv_b) / (n_a + n_b)
# Erro padrão
se = np.sqrt(p_pool * (1 - p_pool) * (1/n_a + 1/n_b))
# Estatística z
z = (p_a - p_b) / se
# P-valor (teste bicaudal)
p_valor = 2 * (1 - stats.norm.cdf(abs(z)))
return z, p_valor
conv_a = np.sum(conversoes_a)
conv_b = np.sum(conversoes_b)
z_stat, p_valor = teste_z_proporcoes(conv_a, n_usuarios_a, conv_b, n_usuarios_b)
print(f"\n=== RESULTADO DO TESTE ===")
print(f"Estatística Z: {z_stat:.4f}")
print(f"P-valor: {p_valor:.4f}")
# TAREFA 3: Interpretação do resultado
alpha = 0.05
if p_valor < alpha:
print(f"Resultado: Significativo (p < {alpha})")
print("Conclusão: Há evidência de diferença entre as versões")
else:
print(f"Resultado: Não significativo (p >= {alpha})")
print("Conclusão: Não há evidência suficiente de diferença")
# TAREFA 4: Calcule o intervalo de confiança para a diferença
# SEU CÓDIGO AQUI
# TAREFA 5: Calcule o poder estatístico e tamanho de efeito
# SEU CÓDIGO AQUI
# DESAFIO: Implemente um simulador de testes A/B
Tarefas para Resolver:
- Complete o cálculo das taxas de conversão observadas
- Interprete o resultado do teste de hipóteses
- Calcule o intervalo de confiança para a diferença entre taxas
- Determine o tamanho de efeito (Cohen's h)
- Desafio: Crie um simulador que determine quantos usuários são necessários para detectar uma diferença de 2% com 80% de poder
Capítulo 4: Machine Learning
Algoritmos de aprendizado de máquina na prática
4.1 Classificação com Scikit-learn
from sklearn.datasets import load_iris, make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
import pandas as pd
import numpy as np
# Exemplo prático: Previsão de inadimplência de clientes
print("=== SISTEMA DE PREVISÃO DE INADIMPLÊNCIA ===")
# Gerando dados sintéticos de clientes
np.random.seed(42)
X, y = make_classification(n_samples=1000, n_features=10, n_classes=2,
n_redundant=2, n_informative=8, random_state=42)
# Criando nomes para as features
feature_names = ['idade', 'renda', 'score_credito', 'dividas', 'tempo_emprego',
'num_cartoes', 'limite_total', 'uso_limite', 'atrasos_anteriores', 'patrimonio']
df = pd.DataFrame(X, columns=feature_names)
df['inadimplente'] = y
print("Dataset de clientes:")
print(df.head())
print(f"\nDistribuição de classes:")
print(f"Não inadimplentes: {(y==0).sum()} ({(y==0).mean()*100:.1f}%)")
print(f"Inadimplentes: {(y==1).sum()} ({(y==1).mean()*100:.1f}%)")
# Divisão treino/teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# Testando múltiplos algoritmos
modelos = {
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'SVM': SVC(random_state=42),
'Logistic Regression': LogisticRegression(random_state=42)
}
resultados = {}
for nome, modelo in modelos.items():
# Validação cruzada
scores = cross_val_score(modelo, X_train, y_train, cv=5, scoring='f1')
resultados[nome] = {
'mean_f1': scores.mean(),
'std_f1': scores.std()
}
# Treinar modelo
modelo.fit(X_train, y_train)
y_pred = modelo.predict(X_test)
print(f"\n=== {nome} ===")
print(f"F1-Score CV: {scores.mean():.3f} ± {scores.std():.3f}")
print("Relatório de classificação:")
print(classification_report(y_test, y_pred))
# Melhor modelo
melhor_modelo = RandomForestClassifier(n_estimators=100, random_state=42)
melhor_modelo.fit(X_train, y_train)
# Importância das features
importancias = melhor_modelo.feature_importances_
feature_importance = pd.DataFrame({
'feature': feature_names,
'importance': importancias
}).sort_values('importance', ascending=False)
print("\nImportância das features:")
print(feature_importance)
Exercício 4.1: Sistema de Recomendação
# Construa um sistema de recomendação de filmes
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity
# Simular dados de avaliações de filmes
filmes = ['Matrix', 'Titanic', 'Avatar', 'Star Wars', 'Toy Story']
usuarios = range(1, 101)
# Matriz usuário-filme (ratings 1-5)
ratings = np.random.randint(1, 6, size=(100, 5))
df_ratings = pd.DataFrame(ratings, columns=filmes, index=usuarios)
# TAREFA: Implemente recomendação baseada em similaridade
# SEU CÓDIGO AQUI
Capítulo 5: Deep Learning
Redes neurais profundas com TensorFlow/Keras
5.1 Redes Neurais Artificiais
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
print("=== REDE NEURAL ARTIFICIAL BÁSICA ===")
print(f"TensorFlow versão: {tf.__version__}")
# Gerar dados sintéticos para classificação
X, y = make_classification(
n_samples=10000,
n_features=20,
n_informative=15,
n_redundant=5,
n_classes=3,
random_state=42
)
# Dividir dados
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Normalizar dados
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print(f"Dados de treino: {X_train_scaled.shape}")
print(f"Dados de teste: {X_test_scaled.shape}")
print(f"Classes: {np.unique(y)}")
# Construir modelo de rede neural
def criar_modelo_basico(input_dim, num_classes):
"""Cria uma rede neural feedforward básica"""
model = keras.Sequential([
# Camada de entrada
layers.Dense(128, activation='relu', input_shape=(input_dim,), name='camada_entrada'),
layers.Dropout(0.3), # Regularização
# Camadas ocultas
layers.Dense(64, activation='relu', name='camada_oculta_1'),
layers.Dropout(0.3),
layers.Dense(32, activation='relu', name='camada_oculta_2'),
layers.Dropout(0.2),
# Camada de saída
layers.Dense(num_classes, activation='softmax', name='camada_saida')
])
return model
# Criar modelo
modelo = criar_modelo_basico(X_train_scaled.shape[1], len(np.unique(y)))
# Compilar modelo
modelo.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Mostrar arquitetura
print("\n=== ARQUITETURA DA REDE ===")
modelo.summary()
# Treinar modelo
print("\n=== TREINAMENTO ===")
# Callbacks para melhorar treinamento
callbacks = [
keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=10,
restore_best_weights=True
),
keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=5,
min_lr=0.00001
)
]
# Treinar
history = modelo.fit(
X_train_scaled, y_train,
epochs=100,
batch_size=32,
validation_split=0.2,
callbacks=callbacks,
verbose=1
)
# Avaliar modelo
print("\n=== AVALIAÇÃO ===")
test_loss, test_accuracy = modelo.evaluate(X_test_scaled, y_test, verbose=0)
print(f"Acurácia no teste: {test_accuracy:.4f}")
print(f"Loss no teste: {test_loss:.4f}")
# Predições
y_pred = modelo.predict(X_test_scaled)
y_pred_classes = np.argmax(y_pred, axis=1)
# Relatório de classificação
from sklearn.metrics import classification_report, confusion_matrix
print("\nRelatório de classificação:")
print(classification_report(y_test, y_pred_classes))
# Função para visualizar treinamento
def plotar_historico_treinamento(history):
"""Plota curvas de loss e acurácia"""
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
# Loss
ax1.plot(history.history['loss'], label='Treino')
ax1.plot(history.history['val_loss'], label='Validação')
ax1.set_title('Loss durante treinamento')
ax1.set_xlabel('Época')
ax1.set_ylabel('Loss')
ax1.legend()
# Acurácia
ax2.plot(history.history['accuracy'], label='Treino')
ax2.plot(history.history['val_accuracy'], label='Validação')
ax2.set_title('Acurácia durante treinamento')
ax2.set_xlabel('Época')
ax2.set_ylabel('Acurácia')
ax2.legend()
plt.tight_layout()
plt.show()
# Exemplo de uso de transfer learning
def criar_modelo_pre_treinado():
"""Exemplo de transfer learning com modelo pré-treinado"""
# Carregar modelo pré-treinado (exemplo conceitual)
base_model = keras.applications.MobileNetV2(
input_shape=(224, 224, 3),
include_top=False,
weights='imagenet'
)
# Congelar camadas do modelo base
base_model.trainable = False
# Adicionar camadas personalizadas
model = keras.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(3, activation='softmax') # 3 classes
])
return model
print("\n=== CONCEITOS IMPORTANTES ===")
print("1. Ativação ReLU: f(x) = max(0, x) - evita problema do gradiente")
print("2. Dropout: desliga neurônios aleatoriamente - evita overfitting")
print("3. Batch normalization: normaliza entradas de cada camada")
print("4. Adam optimizer: combina momentum e RMSprop")
print("5. Early stopping: para treinamento quando não há melhoria")
5.2 CNN para Visão Computacional
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
print("=== CNN PARA CLASSIFICAÇÃO DE IMAGENS ===")
# Carregar dataset CIFAR-10
(X_train, y_train), (X_test, y_test) = keras.datasets.cifar10.load_data()
# Nomes das classes
class_names = ['avião', 'carro', 'pássaro', 'gato', 'cervo',
'cachorro', 'sapo', 'cavalo', 'navio', 'caminhão']
print(f"Dados de treino: {X_train.shape}")
print(f"Dados de teste: {X_test.shape}")
print(f"Classes: {len(class_names)}")
# Pré-processamento
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
# Converter labels para categorical
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
def criar_cnn_modelo():
"""Cria uma CNN para classificação de imagens"""
model = keras.Sequential([
# Primeiro bloco convolucional
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
# Segundo bloco convolucional
layers.Conv2D(64, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
# Terceiro bloco convolucional
layers.Conv2D(128, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.25),
# Camadas totalmente conectadas
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
return model
# Criar e compilar modelo
modelo_cnn = criar_cnn_modelo()
modelo_cnn.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
print("\n=== ARQUITETURA CNN ===")
modelo_cnn.summary()
# Data augmentation para melhorar generalização
datagen = keras.preprocessing.image.ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
zoom_range=0.2
)
print("\n=== TREINAMENTO CNN ===")
# Callbacks
callbacks_cnn = [
keras.callbacks.EarlyStopping(
monitor='val_accuracy',
patience=10,
restore_best_weights=True
),
keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.2,
patience=5,
min_lr=0.0001
)
]
# Treinar com data augmentation
history_cnn = modelo_cnn.fit(
datagen.flow(X_train, y_train, batch_size=32),
steps_per_epoch=len(X_train) // 32,
epochs=50,
validation_data=(X_test, y_test),
callbacks=callbacks_cnn,
verbose=1
)
# Avaliar
test_loss, test_acc = modelo_cnn.evaluate(X_test, y_test, verbose=0)
print(f"\nAcurácia final: {test_acc:.4f}")
# Exemplo de transfer learning com modelo pré-treinado
def criar_modelo_transfer_learning():
"""Transfer learning com VGG16"""
# Carregar VGG16 pré-treinado
base_model = keras.applications.VGG16(
weights='imagenet',
include_top=False,
input_shape=(32, 32, 3)
)
# Congelar camadas base
base_model.trainable = False
# Adicionar camadas customizadas
model = keras.Sequential([
# Redimensionar imagens para VGG16
layers.Lambda(lambda x: tf.image.resize(x, (224, 224))),
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
return model
print("\n=== CONCEITOS CNN ===")
print("1. Convolução: detecta features locais usando filtros")
print("2. Pooling: reduz dimensionalidade mantendo informações importantes")
print("3. Batch Normalization: normaliza ativações, acelera treinamento")
print("4. Data Augmentation: aumenta dataset artificialmente")
print("5. Transfer Learning: usa conhecimento de modelos pré-treinados")
5.3 RNN e LSTM para Sequências
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import pandas as pd
print("=== RNN/LSTM PARA SÉRIES TEMPORAIS ===")
# Gerar dados de série temporal sintética
def gerar_serie_temporal(n_pontos=1000):
"""Gera série temporal com tendência e sazonalidade"""
np.random.seed(42)
t = np.arange(n_pontos)
# Componentes da série
tendencia = 0.02 * t
sazonalidade = 10 * np.sin(2 * np.pi * t / 50)
ruido = np.random.normal(0, 1, n_pontos)
serie = 100 + tendencia + sazonalidade + ruido
return serie
# Criar série temporal
serie_dados = gerar_serie_temporal(1000)
print(f"Série temporal gerada: {len(serie_dados)} pontos")
def criar_sequencias(dados, seq_length):
"""Converte série temporal em sequências para treinamento"""
X, y = [], []
for i in range(len(dados) - seq_length):
X.append(dados[i:(i + seq_length)])
y.append(dados[i + seq_length])
return np.array(X), np.array(y)
# Preparar dados para RNN
seq_length = 30 # Usar 30 pontos anteriores para prever próximo
X, y = criar_sequencias(serie_dados, seq_length)
# Dividir em treino e teste
split_idx = int(0.8 * len(X))
X_train, X_test = X[:split_idx], X[split_idx:]
y_train, y_test = y[:split_idx], y[split_idx:]
# Normalizar dados
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train.reshape(-1, 1)).reshape(X_train.shape)
X_test_scaled = scaler.transform(X_test.reshape(-1, 1)).reshape(X_test.shape)
y_train_scaled = scaler.transform(y_train.reshape(-1, 1)).flatten()
y_test_scaled = scaler.transform(y_test.reshape(-1, 1)).flatten()
print(f"Dados treino: {X_train_scaled.shape}")
print(f"Dados teste: {X_test_scaled.shape}")
def criar_modelo_lstm():
"""Cria modelo LSTM para previsão de séries temporais"""
model = keras.Sequential([
# Primeira camada LSTM
layers.LSTM(50, return_sequences=True, input_shape=(seq_length, 1)),
layers.Dropout(0.2),
# Segunda camada LSTM
layers.LSTM(50, return_sequences=True),
layers.Dropout(0.2),
# Terceira camada LSTM
layers.LSTM(50),
layers.Dropout(0.2),
# Camadas densas
layers.Dense(25, activation='relu'),
layers.Dense(1)
])
return model
# Criar modelo LSTM
modelo_lstm = criar_modelo_lstm()
modelo_lstm.compile(
optimizer='adam',
loss='mse',
metrics=['mae']
)
print("\n=== ARQUITETURA LSTM ===")
modelo_lstm.summary()
# Reshape dados para LSTM (samples, timesteps, features)
X_train_reshaped = X_train_scaled.reshape((X_train_scaled.shape[0], X_train_scaled.shape[1], 1))
X_test_reshaped = X_test_scaled.reshape((X_test_scaled.shape[0], X_test_scaled.shape[1], 1))
print("\n=== TREINAMENTO LSTM ===")
# Callbacks
callbacks_lstm = [
keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=15,
restore_best_weights=True
),
keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=10,
min_lr=0.00001
)
]
# Treinar
history_lstm = modelo_lstm.fit(
X_train_reshaped, y_train_scaled,
epochs=100,
batch_size=32,
validation_split=0.2,
callbacks=callbacks_lstm,
verbose=1
)
# Fazer previsões
previsoes = modelo_lstm.predict(X_test_reshaped)
# Desnormalizar previsões
previsoes_desnorm = scaler.inverse_transform(previsoes)
y_test_desnorm = scaler.inverse_transform(y_test_scaled.reshape(-1, 1))
# Calcular métricas
from sklearn.metrics import mean_absolute_error, mean_squared_error
mae = mean_absolute_error(y_test_desnorm, previsoes_desnorm)
rmse = np.sqrt(mean_squared_error(y_test_desnorm, previsoes_desnorm))
print(f"\n=== MÉTRICAS DE AVALIAÇÃO ===")
print(f"MAE: {mae:.4f}")
print(f"RMSE: {rmse:.4f}")
# Exemplo de modelo bidirecional
def criar_modelo_bidirectional():
"""Modelo LSTM bidirecional"""
model = keras.Sequential([
layers.Bidirectional(
layers.LSTM(50, return_sequences=True),
input_shape=(seq_length, 1)
),
layers.Dropout(0.2),
layers.Bidirectional(layers.LSTM(50)),
layers.Dropout(0.2),
layers.Dense(25, activation='relu'),
layers.Dense(1)
])
return model
# Exemplo de classificação de texto com RNN
def criar_modelo_classificacao_texto():
"""RNN para classificação de texto"""
vocab_size = 10000
max_length = 100
model = keras.Sequential([
layers.Embedding(vocab_size, 128, input_length=max_length),
layers.LSTM(64, dropout=0.5, recurrent_dropout=0.5),
layers.Dense(1, activation='sigmoid')
])
return model
print("\n=== CONCEITOS RNN/LSTM ===")
print("1. RNN: processa sequências, mas sofre de vanishing gradient")
print("2. LSTM: resolve problema do gradiente com gates")
print("3. GRU: versão simplificada do LSTM")
print("4. Bidirectional: processa sequência nos dois sentidos")
print("5. Attention: foca em partes relevantes da sequência")
# Função para previsão futura
def prever_proximos_pontos(modelo, ultima_sequencia, n_pontos=10):
"""Prevê próximos n pontos da série temporal"""
previsoes = []
seq_atual = ultima_sequencia.copy()
for _ in range(n_pontos):
# Prever próximo ponto
seq_reshaped = seq_atual.reshape(1, seq_length, 1)
prox_ponto = modelo.predict(seq_reshaped, verbose=0)[0, 0]
previsoes.append(prox_ponto)
# Atualizar sequência (remover primeiro, adicionar previsão)
seq_atual = np.append(seq_atual[1:], prox_ponto)
return np.array(previsoes)
# Exemplo de uso
ultima_seq = X_test_scaled[-1]
previsoes_futuras = prever_proximos_pontos(modelo_lstm, ultima_seq, 10)
print(f"\nPrevisões para próximos 10 pontos: {previsoes_futuras[:5]}...")
print("\n=== APLICAÇÕES PRÁTICAS ===")
print("- Previsão de vendas")
print("- Análise de sentimentos em texto")
print("- Tradução automática")
print("- Reconhecimento de fala")
print("- Detecção de anomalias em séries temporais")
Exercício Prático 5.1: Sistema de Recomendação com Deep Learning
Cenário Real:
Construa um sistema de recomendação usando redes neurais que combina embeddings de usuários e itens para prever ratings.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import pandas as pd
class NeuralCollaborativeFiltering:
def __init__(self, num_users, num_items, embedding_size=50):
self.num_users = num_users
self.num_items = num_items
self.embedding_size = embedding_size
self.model = None
def criar_modelo(self):
"""Cria modelo de Neural Collaborative Filtering"""
# Entradas
user_input = layers.Input(shape=(), name='user_id')
item_input = layers.Input(shape=(), name='item_id')
# Embeddings
user_embedding = layers.Embedding(
self.num_users, self.embedding_size,
name='user_embedding'
)(user_input)
item_embedding = layers.Embedding(
self.num_items, self.embedding_size,
name='item_embedding'
)(item_input)
# Flatten embeddings
user_vec = layers.Flatten()(user_embedding)
item_vec = layers.Flatten()(item_embedding)
# TAREFA 1: Implemente concatenação dos embeddings
# concat = layers.Concatenate()([user_vec, item_vec])
# SEU CÓDIGO AQUI
# TAREFA 2: Adicione camadas densas
# dense1 = layers.Dense(128, activation='relu')(concat)
# dropout1 = layers.Dropout(0.2)(dense1)
# SEU CÓDIGO AQUI
# TAREFA 3: Camada de saída para rating (1-5)
# output = layers.Dense(1, activation='sigmoid')(dropout2)
# output = layers.Lambda(lambda x: x * 4 + 1)(output) # Escalar para 1-5
# SEU CÓDIGO AQUI
# Criar modelo
# model = keras.Model(inputs=[user_input, item_input], outputs=output)
# return model
pass # Remover quando implementar
def treinar(self, user_ids, item_ids, ratings, epochs=50):
"""Treina o modelo"""
# TAREFA 4: Compile o modelo e treine
# self.model.compile(optimizer='adam', loss='mse', metrics=['mae'])
# SEU CÓDIGO AQUI
pass
def prever_rating(self, user_id, item_id):
"""Prevê rating para par usuário-item"""
# TAREFA 5: Implemente predição
# SEU CÓDIGO AQUI
pass
def recomendar_items(self, user_id, num_recomendacoes=10):
"""Recomenda itens para usuário"""
# TAREFA 6: Gere recomendações
# SEU CÓDIGO AQUI
pass
# Dados sintéticos para teste
def gerar_dados_ratings(num_users=1000, num_items=500, num_ratings=50000):
"""Gera dados sintéticos de ratings"""
np.random.seed(42)
user_ids = np.random.randint(0, num_users, num_ratings)
item_ids = np.random.randint(0, num_items, num_ratings)
# Simular ratings baseados em preferências
ratings = []
for user, item in zip(user_ids, item_ids):
# Usuários têm preferências por certos tipos de itens
user_bias = np.random.normal(0, 0.5)
item_bias = np.random.normal(0, 0.5)
rating = 3 + user_bias + item_bias + np.random.normal(0, 0.3)
rating = np.clip(rating, 1, 5)
ratings.append(rating)
return user_ids, item_ids, np.array(ratings)
# Teste do sistema
print("=== SISTEMA DE RECOMENDAÇÃO NEURAL ===")
user_ids, item_ids, ratings = gerar_dados_ratings()
# Criar e treinar modelo
ncf = NeuralCollaborativeFiltering(
num_users=1000,
num_items=500,
embedding_size=64
)
# DESAFIO: Complete a implementação e teste o sistema
print("Dados gerados:")
print(f"Usuários: {len(np.unique(user_ids))}")
print(f"Itens: {len(np.unique(item_ids))}")
print(f"Ratings: {len(ratings)}")
print(f"Rating médio: {np.mean(ratings):.2f}")
Tarefas para Resolver:
- Complete a arquitetura do modelo NCF
- Implemente o treinamento do modelo
- Crie função de predição de ratings
- Desenvolva sistema de recomendações
- Desafio: Adicione features adicionais como idade do usuário, categoria do item
🧠 Conceitos Avançados de Deep Learning
Técnicas de Regularização:
- Dropout: Desativa neurônios aleatoriamente
- Batch Normalization: Normaliza ativações
- Early Stopping: Para quando performance estagna
- Weight Decay: Penaliza pesos grandes
- Data Augmentation: Aumenta diversidade dos dados
Arquiteturas Modernas:
- ResNet: Conexões residuais
- Transformer: Mecanismo de atenção
- GAN: Redes adversariais generativas
- VAE: Autoencoders variacionais
- U-Net: Segmentação de imagens
💼 Aplicações no Mercado:
Deep Learning é usado em reconhecimento facial, carros autônomos, tradução automática, diagnóstico médico, jogos (AlphaGo), assistentes virtuais e muito mais. É uma das tecnologias mais valorizadas no mercado atual.
Capítulo 6: Processamento de Linguagem Natural
Análise e compreensão de texto com Python
6.1 Análise de Sentimentos
import pandas as pd
import numpy as np
import re
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
import nltk
from nltk.corpus import stopwords
from nltk.stem import RSLPStemmer
# Sistema de análise de sentimentos para reviews de produtos
print("=== SISTEMA DE ANÁLISE DE SENTIMENTOS ===")
# Dados simulados de reviews de e-commerce
reviews_dados = [
("Produto excelente, recomendo muito!", "positivo"),
("Chegou rápido e bem embalado", "positivo"),
("Qualidade péssima, não comprem", "negativo"),
("Não gostei, muito caro pelo que oferece", "negativo"),
("Produto ok, nada excepcional", "neutro"),
("Adorei! Superou minhas expectativas", "positivo"),
("Péssimo atendimento e produto ruim", "negativo"),
("Entrega demorou mas produto é bom", "neutro"),
("Melhor compra que já fiz!", "positivo"),
("Produto com defeito, muito frustrado", "negativo")
] * 100 # Simular mais dados
# Criar DataFrame
df_reviews = pd.DataFrame(reviews_dados, columns=['texto', 'sentimento'])
print(f"Total de reviews: {len(df_reviews)}")
print(df_reviews['sentimento'].value_counts())
# Pré-processamento de texto
def preprocessar_texto(texto):
"""Limpa e prepara texto para análise"""
# Converter para minúsculas
texto = texto.lower()
# Remover pontuação e números
texto = re.sub(r'[^a-záãàâéêíóôõúç\s]', '', texto)
# Remover espaços extras
texto = re.sub(r'\s+', ' ', texto).strip()
return texto
# Aplicar pré-processamento
df_reviews['texto_limpo'] = df_reviews['texto'].apply(preprocessar_texto)
# Vectorização TF-IDF
vectorizer = TfidfVectorizer(
max_features=1000,
ngram_range=(1, 2), # Unigrams e bigrams
min_df=2
)
X = vectorizer.fit_transform(df_reviews['texto_limpo'])
y = df_reviews['sentimento']
# Divisão treino/teste
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Treinamento do modelo
modelo = LogisticRegression(random_state=42)
modelo.fit(X_train, y_train)
# Avaliação
y_pred = modelo.predict(X_test)
print("\n=== RESULTADOS ===")
print(classification_report(y_test, y_pred))
# Função para predizer sentimento de novo texto
def analisar_sentimento(texto):
"""Analisa sentimento de um texto"""
texto_limpo = preprocessar_texto(texto)
texto_vectorizado = vectorizer.transform([texto_limpo])
sentimento = modelo.predict(texto_vectorizado)[0]
probabilidades = modelo.predict_proba(texto_vectorizado)[0]
return {
'sentimento': sentimento,
'confianca': max(probabilidades),
'probabilidades': dict(zip(modelo.classes_, probabilidades))
}
# Teste com novos textos
novos_textos = [
"Este produto é fantástico, recomendo!",
"Não gostei nada, qualidade horrível",
"Produto mediano, poderia ser melhor"
]
for texto in novos_textos:
resultado = analisar_sentimento(texto)
print(f"\nTexto: {texto}")
print(f"Sentimento: {resultado['sentimento']} (confiança: {resultado['confianca']:.2f})")
# Análise das palavras mais importantes
feature_names = vectorizer.get_feature_names_out()
for classe in modelo.classes_:
idx_classe = list(modelo.classes_).index(classe)
coef = modelo.coef_[idx_classe]
top_indices = coef.argsort()[-10:][::-1]
print(f"\nPalavras mais importantes para '{classe}':")
for i in top_indices:
print(f" {feature_names[i]}: {coef[i]:.3f}")
Exercício 6.1: Chatbot de Atendimento
# Construa um chatbot simples para atendimento ao cliente
import re
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
class ChatbotAtendimento:
def __init__(self):
# Base de conhecimento com perguntas e respostas
self.base_conhecimento = {
"saudacao": [
("oi", "Olá! Como posso ajudá-lo hoje?"),
("olá", "Oi! Em que posso ser útil?"),
("bom dia", "Bom dia! Como posso ajudá-lo?")
],
"pedidos": [
("status do pedido", "Para verificar o status do seu pedido, preciso do número. Você pode fornecer?"),
("onde está meu pedido", "Vou verificar seu pedido. Qual o número do pedido?"),
("prazo de entrega", "O prazo padrão de entrega é de 3-5 dias úteis.")
],
"pagamento": [
("formas de pagamento", "Aceitamos cartão de crédito, débito, PIX e boleto."),
("problema no pagamento", "Vou te ajudar com isso. Qual problema você está enfrentando?")
]
}
# TAREFA: Implemente a lógica de matching de intenções
# SEU CÓDIGO AQUI
def processar_mensagem(self, mensagem):
# TAREFA: Implemente processamento da mensagem
# 1. Limpar o texto
# 2. Identificar intenção
# 3. Retornar resposta apropriada
pass
def treinar(self):
# TAREFA: Prepare o modelo para matching
pass
# Teste o chatbot
chatbot = ChatbotAtendimento()
chatbot.treinar()
# Exemplos de uso
mensagens_teste = [
"Oi, como vocês estão?",
"Qual o status do meu pedido?",
"Quais formas de pagamento vocês aceitam?"
]
for msg in mensagens_teste:
resposta = chatbot.processar_mensagem(msg)
print(f"Cliente: {msg}")
print(f"Bot: {resposta}\n")
Capítulo 7: Visão Computacional
Processamento e análise de imagens com Python
7.1 Processamento de Imagens com OpenCV
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
print("=== SISTEMA DE ANÁLISE DE IMAGENS ===")
# Função para criar imagem sintética para demonstração
def criar_imagem_exemplo():
"""Cria uma imagem sintética para demonstração"""
# Criar imagem com formas geométricas
img = np.zeros((400, 600, 3), dtype=np.uint8)
# Adicionar retângulo azul
cv2.rectangle(img, (50, 50), (200, 150), (255, 0, 0), -1)
# Adicionar círculo verde
cv2.circle(img, (400, 100), 80, (0, 255, 0), -1)
# Adicionar triângulo vermelho
triangle = np.array([[300, 200], [350, 300], [250, 300]], np.int32)
cv2.fillPoly(img, [triangle], (0, 0, 255))
# Adicionar ruído
noise = np.random.randint(0, 50, img.shape, dtype=np.uint8)
img = cv2.add(img, noise)
return img
# 1. CARREGAMENTO E VISUALIZAÇÃO
print("1. Criando imagem de exemplo...")
img_original = criar_imagem_exemplo()
# Conversão para diferentes espaços de cor
img_gray = cv2.cvtColor(img_original, cv2.COLOR_BGR2GRAY)
img_hsv = cv2.cvtColor(img_original, cv2.COLOR_BGR2HSV)
print(f"Dimensões da imagem: {img_original.shape}")
print(f"Tipo de dados: {img_original.dtype}")
# 2. FILTROS E SUAVIZAÇÃO
print("\n2. Aplicando filtros...")
# Filtro Gaussiano (suavização)
img_blur = cv2.GaussianBlur(img_original, (15, 15), 0)
# Filtro Mediano (remove ruído sal e pimenta)
img_median = cv2.medianBlur(img_original, 5)
# Filtro Bilateral (preserva bordas)
img_bilateral = cv2.bilateralFilter(img_original, 9, 75, 75)
# 3. DETECÇÃO DE BORDAS
print("3. Detectando bordas...")
# Detecção de bordas com Canny
edges = cv2.Canny(img_gray, 50, 150)
# Gradiente Sobel
sobelx = cv2.Sobel(img_gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img_gray, cv2.CV_64F, 0, 1, ksize=3)
sobel_combined = np.sqrt(sobelx**2 + sobely**2)
# 4. DETECÇÃO DE CONTORNOS
print("4. Detectando contornos...")
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
img_contours = img_original.copy()
cv2.drawContours(img_contours, contours, -1, (255, 255, 255), 2)
print(f"Número de contornos encontrados: {len(contours)}")
# Análise de contornos
for i, contour in enumerate(contours):
if cv2.contourArea(contour) > 500: # Filtrar contornos pequenos
# Calcular propriedades
area = cv2.contourArea(contour)
perimetro = cv2.arcLength(contour, True)
# Aproximação poligonal
epsilon = 0.02 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# Determinar forma
vertices = len(approx)
if vertices == 3:
forma = "Triângulo"
elif vertices == 4:
forma = "Retângulo"
elif vertices > 8:
forma = "Círculo"
else:
forma = f"Polígono ({vertices} lados)"
print(f"Contorno {i}: {forma}, Área: {area:.0f}, Perímetro: {perimetro:.0f}")
# 5. SEGMENTAÇÃO POR COR
print("\n5. Segmentação por cor...")
def segmentar_por_cor(img, cor_min, cor_max):
"""Segmenta imagem baseada em range de cor HSV"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, cor_min, cor_max)
resultado = cv2.bitwise_and(img, img, mask=mask)
return mask, resultado
# Definir ranges de cor (HSV)
# Azul
azul_min = np.array([100, 50, 50])
azul_max = np.array([130, 255, 255])
mask_azul, img_azul = segmentar_por_cor(img_original, azul_min, azul_max)
# Verde
verde_min = np.array([40, 50, 50])
verde_max = np.array([80, 255, 255])
mask_verde, img_verde = segmentar_por_cor(img_original, verde_min, verde_max)
# Vermelho (requer dois ranges devido ao wrap-around do Hue)
vermelho_min1 = np.array([0, 50, 50])
vermelho_max1 = np.array([10, 255, 255])
vermelho_min2 = np.array([170, 50, 50])
vermelho_max2 = np.array([180, 255, 255])
hsv = cv2.cvtColor(img_original, cv2.COLOR_BGR2HSV)
mask_vermelho1 = cv2.inRange(hsv, vermelho_min1, vermelho_max1)
mask_vermelho2 = cv2.inRange(hsv, vermelho_min2, vermelho_max2)
mask_vermelho = cv2.bitwise_or(mask_vermelho1, mask_vermelho2)
img_vermelho = cv2.bitwise_and(img_original, img_original, mask=mask_vermelho)
# 6. CLUSTERING DE CORES (K-MEANS)
print("6. Análise de paleta de cores...")
def extrair_cores_dominantes(img, k=5):
"""Extrai as k cores dominantes da imagem usando K-means"""
# Reshape da imagem para lista de pixels
pixels = img.reshape((-1, 3))
pixels = np.float32(pixels)
# Aplicar K-means
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)
_, labels, centers = cv2.kmeans(pixels, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Converter de volta para uint8
centers = np.uint8(centers)
# Contar pixels por cluster
unique_labels, counts = np.unique(labels, return_counts=True)
# Ordenar por frequência
sorted_indices = np.argsort(counts)[::-1]
cores_dominantes = centers[sorted_indices]
percentuais = counts[sorted_indices] / len(pixels) * 100
return cores_dominantes, percentuais
cores, percentuais = extrair_cores_dominantes(img_original, k=5)
print("Cores dominantes (BGR):")
for i, (cor, perc) in enumerate(zip(cores, percentuais)):
print(f" Cor {i+1}: {cor} ({perc:.1f}%)")
# 7. TEMPLATE MATCHING
print("\n7. Template Matching...")
def encontrar_template(img, template, threshold=0.8):
"""Encontra template na imagem usando correlação"""
resultado = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
locations = np.where(resultado >= threshold)
matches = []
for pt in zip(*locations[::-1]):
matches.append({
'posicao': pt,
'confianca': resultado[pt[1], pt[0]]
})
return matches
# Criar um template simples (quadrado azul)
template = img_original[50:150, 50:200] # Recortar o retângulo azul
matches = encontrar_template(img_gray, cv2.cvtColor(template, cv2.COLOR_BGR2GRAY), 0.8)
print(f"Template encontrado em {len(matches)} localizações")
# 8. TRANSFORMAÇÕES GEOMÉTRICAS
print("8. Aplicando transformações...")
# Rotação
altura, largura = img_original.shape[:2]
centro = (largura//2, altura//2)
matriz_rotacao = cv2.getRotationMatrix2D(centro, 45, 1.0)
img_rotacionada = cv2.warpAffine(img_original, matriz_rotacao, (largura, altura))
# Redimensionamento
img_redimensionada = cv2.resize(img_original, (300, 200))
# Corte de perspectiva
pts1 = np.float32([[50, 50], [550, 50], [50, 350], [550, 350]])
pts2 = np.float32([[0, 0], [400, 0], [0, 300], [400, 300]])
matriz_perspectiva = cv2.getPerspectiveTransform(pts1, pts2)
img_perspectiva = cv2.warpPerspective(img_original, matriz_perspectiva, (400, 300))
# Função para salvar resultados (simulação)
def salvar_resultados():
"""Simula salvamento dos resultados de análise"""
resultados = {
'contornos_detectados': len(contours),
'cores_dominantes': cores.tolist(),
'percentuais_cores': percentuais.tolist(),
'templates_encontrados': len(matches),
'dimensoes_originais': img_original.shape
}
print("\n=== RELATÓRIO DE ANÁLISE ===")
print(f"Contornos detectados: {resultados['contornos_detectados']}")
print(f"Templates encontrados: {resultados['templates_encontrados']}")
print("Análise concluída com sucesso!")
return resultados
# Executar análise completa
relatorio = salvar_resultados()
Exercício 7.1: Sistema de Controle de Qualidade
# Sistema de controle de qualidade para linha de produção
import cv2
import numpy as np
class ControleQualidade:
def __init__(self):
self.criterios = {
'area_min': 1000,
'area_max': 10000,
'circularidade_min': 0.7,
'cor_tolerancia': 30
}
self.produtos_aprovados = 0
self.produtos_rejeitados = 0
def analisar_produto(self, img):
"""
Analisa um produto e determina se atende aos critérios de qualidade
Critérios:
1. Área dentro do range especificado
2. Forma aproximadamente circular
3. Cor dentro da tolerância
4. Ausência de defeitos (buracos)
"""
resultado = {
'aprovado': False,
'motivos_rejeicao': [],
'metricas': {}
}
# TAREFA 1: Implementar detecção de contornos
# Converter para escala de cinza
# Aplicar threshold
# Encontrar contornos
# SEU CÓDIGO AQUI
# TAREFA 2: Analisar cada contorno
# Calcular área
# Calcular circularidade
# Verificar critérios
# SEU CÓDIGO AQUI
# TAREFA 3: Análise de cor
# Extrair cor dominante
# Comparar com padrão esperado
# SEU CÓDIGO AQUI
# TAREFA 4: Detecção de defeitos
# Procurar por buracos ou irregularidades
# SEU CÓDIGO AQUI
return resultado
def gerar_relatorio(self):
"""Gera relatório de controle de qualidade"""
total = self.produtos_aprovados + self.produtos_rejeitados
if total > 0:
taxa_aprovacao = (self.produtos_aprovados / total) * 100
print(f"Taxa de aprovação: {taxa_aprovacao:.1f}%")
print(f"Produtos aprovados: {self.produtos_aprovados}")
print(f"Produtos rejeitados: {self.produtos_rejeitados}")
# Exemplo de uso
controle = ControleQualidade()
# Simular análise de produtos
for i in range(10):
# Criar produto sintético para teste
produto = criar_produto_sintetico(defeito=np.random.random() > 0.8)
resultado = controle.analisar_produto(produto)
if resultado['aprovado']:
controle.produtos_aprovados += 1
status = "✅ APROVADO"
else:
controle.produtos_rejeitados += 1
status = "❌ REJEITADO"
motivos = ", ".join(resultado['motivos_rejeicao'])
print(f"Produto {i+1}: {status} - {motivos}")
controle.gerar_relatorio()
Capítulo 8: Projetos Práticos
Aplicações reais de IA para o mercado de trabalho
Projeto 8.1: Sistema de Detecção de Fraudes
📊 Contexto Empresarial:
Bancos e fintechs perdem bilhões anualmente com fraudes. Você desenvolverá um sistema de ML para detectar transações fraudulentas em tempo real.
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import IsolationForest, RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
import datetime as dt
class DetectorFraudes:
def __init__(self):
self.modelo_anomalia = IsolationForest(contamination=0.1, random_state=42)
self.modelo_supervisionado = RandomForestClassifier(n_estimators=100, random_state=42)
self.scaler = StandardScaler()
self.is_trained = False
def gerar_dados_transacoes(self, n_amostras=10000):
"""Gera dataset sintético de transações financeiras"""
np.random.seed(42)
# Dados de transações normais
transacoes_normais = []
for i in range(int(n_amostras * 0.95)): # 95% normais
transacao = {
'valor': np.random.lognormal(3, 1), # Valores típicos de transações
'hora': np.random.randint(6, 23), # Horário comercial
'dia_semana': np.random.randint(0, 7),
'tentativas_senha': np.random.randint(1, 2), # Geralmente acerta na primeira
'tempo_desde_ultima': np.random.exponential(60), # Minutos
'dispositivo_conhecido': 1, # Dispositivo conhecido
'localizacao_usual': 1, # Localização usual
'saldo_conta': np.random.normal(5000, 2000),
'idade_conta': np.random.randint(365, 3650), # Conta de 1-10 anos
'fraude': 0
}
transacoes_normais.append(transacao)
# Dados de transações fraudulentas
transacoes_fraude = []
for i in range(int(n_amostras * 0.05)): # 5% fraudes
transacao = {
'valor': np.random.lognormal(5, 1.5), # Valores mais altos
'hora': np.random.choice([2, 3, 4, 23, 0, 1]), # Horários suspeitos
'dia_semana': np.random.randint(0, 7),
'tentativas_senha': np.random.randint(2, 6), # Múltiplas tentativas
'tempo_desde_ultima': np.random.exponential(5), # Transações rápidas
'dispositivo_conhecido': np.random.choice([0, 1], p=[0.8, 0.2]), # Dispositivo desconhecido
'localizacao_usual': np.random.choice([0, 1], p=[0.7, 0.3]), # Localização incomum
'saldo_conta': np.random.normal(5000, 2000),
'idade_conta': np.random.randint(1, 30), # Contas novas
'fraude': 1
}
transacoes_fraude.append(transacao)
# Combinar datasets
todas_transacoes = transacoes_normais + transacoes_fraude
df = pd.DataFrame(todas_transacoes)
# Adicionar features derivadas
df['razao_valor_saldo'] = df['valor'] / df['saldo_conta']
df['transacao_noturna'] = (df['hora'] < 6) | (df['hora'] > 22)
df['fim_semana'] = df['dia_semana'].isin([5, 6])
return df.sample(frac=1).reset_index(drop=True) # Embaralhar
def preprocessar_dados(self, df):
"""Prepara dados para treinamento"""
# Features para o modelo
features = [
'valor', 'hora', 'dia_semana', 'tentativas_senha',
'tempo_desde_ultima', 'dispositivo_conhecido', 'localizacao_usual',
'idade_conta', 'razao_valor_saldo', 'transacao_noturna', 'fim_semana'
]
X = df[features]
y = df['fraude'] if 'fraude' in df.columns else None
return X, y
def treinar_modelos(self, df):
"""Treina tanto modelo não-supervisionado quanto supervisionado"""
X, y = self.preprocessar_dados(df)
# Normalizar features
X_scaled = self.scaler.fit_transform(X)
# Treinar modelo de detecção de anomalias (não-supervisionado)
self.modelo_anomalia.fit(X_scaled)
# Treinar modelo supervisionado
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42, stratify=y
)
self.modelo_supervisionado.fit(X_train, y_train)
# Avaliar modelo supervisionado
y_pred = self.modelo_supervisionado.predict(X_test)
print("=== AVALIAÇÃO DO MODELO SUPERVISIONADO ===")
print(classification_report(y_test, y_pred))
# Avaliar modelo de anomalias
anomalias = self.modelo_anomalia.predict(X_test)
anomalias_binario = [1 if x == -1 else 0 for x in anomalias]
print("\n=== AVALIAÇÃO DO MODELO DE ANOMALIAS ===")
print(classification_report(y_test, anomalias_binario))
self.is_trained = True
return X_test, y_test, y_pred
def analisar_transacao(self, transacao_data):
"""Analisa uma única transação em tempo real"""
if not self.is_trained:
raise ValueError("Modelo precisa ser treinado primeiro!")
# Converter para DataFrame
df_transacao = pd.DataFrame([transacao_data])
# Adicionar features derivadas
df_transacao['razao_valor_saldo'] = df_transacao['valor'] / df_transacao['saldo_conta']
df_transacao['transacao_noturna'] = (df_transacao['hora'] < 6) | (df_transacao['hora'] > 22)
df_transacao['fim_semana'] = df_transacao['dia_semana'].isin([5, 6])
X, _ = self.preprocessar_dados(df_transacao)
X_scaled = self.scaler.transform(X)
# Predições
prob_fraude = self.modelo_supervisionado.predict_proba(X_scaled)[0][1]
pred_fraude = self.modelo_supervisionado.predict(X_scaled)[0]
anomalia_score = self.modelo_anomalia.decision_function(X_scaled)[0]
# Score de risco combinado
risco_combinado = (prob_fraude + (1 - (anomalia_score + 1) / 2)) / 2
resultado = {
'probabilidade_fraude': prob_fraude,
'predicao_fraude': bool(pred_fraude),
'score_anomalia': anomalia_score,
'risco_combinado': risco_combinado,
'nivel_risco': self._classificar_risco(risco_combinado),
'acoes_recomendadas': self._recomendar_acoes(risco_combinado, transacao_data)
}
return resultado
def _classificar_risco(self, score):
"""Classifica nível de risco"""
if score < 0.3:
return "BAIXO"
elif score < 0.6:
return "MÉDIO"
elif score < 0.8:
return "ALTO"
else:
return "CRÍTICO"
def _recomendar_acoes(self, score, transacao):
"""Recomenda ações baseadas no score de risco"""
acoes = []
if score > 0.8:
acoes.extend([
"BLOQUEAR transação imediatamente",
"Notificar cliente via SMS/email",
"Solicitar verificação adicional"
])
elif score > 0.6:
acoes.extend([
"Solicitar autenticação adicional",
"Monitorar próximas transações",
"Verificar padrão de uso"
])
elif score > 0.3:
acoes.extend([
"Registrar para monitoramento",
"Analisar padrão histórico"
])
else:
acoes.append("Aprovar transação normalmente")
# Verificações específicas
if transacao.get('dispositivo_conhecido', 1) == 0:
acoes.append("Verificar novo dispositivo")
if transacao.get('localizacao_usual', 1) == 0:
acoes.append("Confirmar localização")
return acoes
def gerar_relatorio_monitoramento(self, transacoes_periodo):
"""Gera relatório de monitoramento para um período"""
resultados = []
for _, transacao in transacoes_periodo.iterrows():
resultado = self.analisar_transacao(transacao.to_dict())
resultados.append(resultado)
df_resultados = pd.DataFrame(resultados)
relatorio = {
'total_transacoes': len(transacoes_periodo),
'transacoes_bloqueadas': sum(df_resultados['nivel_risco'] == 'CRÍTICO'),
'transacoes_suspeitas': sum(df_resultados['nivel_risco'].isin(['ALTO', 'MÉDIO'])),
'taxa_bloqueio': sum(df_resultados['nivel_risco'] == 'CRÍTICO') / len(transacoes_periodo) * 100,
'risco_medio': df_resultados['risco_combinado'].mean(),
'distribuicao_risco': df_resultados['nivel_risco'].value_counts().to_dict()
}
return relatorio
# Exemplo de uso completo
if __name__ == "__main__":
print("=== SISTEMA DE DETECÇÃO DE FRAUDES ===")
# Inicializar detector
detector = DetectorFraudes()
# Gerar e treinar com dados históricos
print("1. Gerando dados históricos...")
dados_historicos = detector.gerar_dados_transacoes(50000)
print("2. Treinando modelos...")
detector.treinar_modelos(dados_historicos)
# Simular transação em tempo real
print("\n3. Analisando transação em tempo real...")
transacao_suspeita = {
'valor': 5000, # Valor alto
'hora': 3, # Madrugada
'dia_semana': 1,
'tentativas_senha': 3, # Múltiplas tentativas
'tempo_desde_ultima': 2, # Muito rápido
'dispositivo_conhecido': 0, # Dispositivo novo
'localizacao_usual': 0, # Localização nova
'saldo_conta': 8000,
'idade_conta': 10 # Conta muito nova
}
resultado = detector.analisar_transacao(transacao_suspeita)
print(f"Probabilidade de fraude: {resultado['probabilidade_fraude']:.3f}")
print(f"Nível de risco: {resultado['nivel_risco']}")
print(f"Ações recomendadas:")
for acao in resultado['acoes_recomendadas']:
print(f" - {acao}")
# Relatório de monitoramento
print("\n4. Gerando relatório de monitoramento...")
dados_periodo = detector.gerar_dados_transacoes(1000)
relatorio = detector.gerar_relatorio_monitoramento(dados_periodo)
print(f"Total de transações: {relatorio['total_transacoes']}")
print(f"Transações bloqueadas: {relatorio['transacoes_bloqueadas']}")
print(f"Taxa de bloqueio: {relatorio['taxa_bloqueio']:.2f}%")
print(f"Distribuição de risco: {relatorio['distribuicao_risco']}")
Projeto 8.2: Sistema de Recomendação E-commerce
🛒 Contexto Empresarial:
Sistemas de recomendação são responsáveis por 35% das vendas da Amazon. Implemente um sistema híbrido que combina filtragem colaborativa e baseada em conteúdo.
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.decomposition import TruncatedSVD
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')
class SistemaRecomendacao:
def __init__(self):
self.matriz_usuarios_itens = None
self.similaridade_itens = None
self.modelo_svd = TruncatedSVD(n_components=50, random_state=42)
self.vectorizer_conteudo = TfidfVectorizer(max_features=5000, stop_words='english')
self.produtos_df = None
self.avaliacoes_df = None
self.is_trained = False
def gerar_dados_ecommerce(self):
"""Gera dados sintéticos de e-commerce"""
np.random.seed(42)
# Gerar produtos
categorias = ['Eletrônicos', 'Roupas', 'Casa', 'Esportes', 'Livros', 'Beleza']
subcategorias = {
'Eletrônicos': ['Smartphone', 'Laptop', 'Tablet', 'Fone', 'TV'],
'Roupas': ['Camiseta', 'Calça', 'Vestido', 'Sapato', 'Acessório'],
'Casa': ['Móvel', 'Decoração', 'Cozinha', 'Banheiro', 'Jardim'],
'Esportes': ['Fitness', 'Futebol', 'Natação', 'Corrida', 'Yoga'],
'Livros': ['Ficção', 'Técnico', 'Romance', 'Biografia', 'Infantil'],
'Beleza': ['Maquiagem', 'Skincare', 'Perfume', 'Cabelo', 'Unhas']
}
produtos = []
for i in range(1000): # 1000 produtos
categoria = np.random.choice(categorias)
subcategoria = np.random.choice(subcategorias[categoria])
produto = {
'produto_id': i + 1,
'nome': f"{subcategoria} {categoria} {i+1}",
'categoria': categoria,
'subcategoria': subcategoria,
'preco': np.random.uniform(10, 1000),
'descricao': f"Excelente {subcategoria.lower()} da categoria {categoria.lower()}. "
f"Alta qualidade e ótimo custo-benefício. Ideal para uso {np.random.choice(['diário', 'especial', 'profissional'])}.",
'marca': f"Marca{np.random.randint(1, 50)}",
'avaliacao_media': np.random.uniform(3.0, 5.0),
'num_avaliacoes': np.random.randint(10, 1000)
}
produtos.append(produto)
self.produtos_df = pd.DataFrame(produtos)
# Gerar usuários e avaliações
avaliacoes = []
for user_id in range(1, 5001): # 5000 usuários
# Cada usuário avalia entre 5 e 50 produtos
num_avaliacoes = np.random.randint(5, 51)
produtos_avaliados = np.random.choice(
self.produtos_df['produto_id'].values,
size=num_avaliacoes,
replace=False
)
for produto_id in produtos_avaliados:
# Usuários tendem a avaliar produtos de categorias específicas
produto = self.produtos_df[self.produtos_df['produto_id'] == produto_id].iloc[0]
# Simular preferências do usuário por categoria
categoria_pref = {
'Eletrônicos': 0.8 if user_id % 6 == 0 else 0.2,
'Roupas': 0.8 if user_id % 6 == 1 else 0.2,
'Casa': 0.8 if user_id % 6 == 2 else 0.2,
'Esportes': 0.8 if user_id % 6 == 3 else 0.2,
'Livros': 0.8 if user_id % 6 == 4 else 0.2,
'Beleza': 0.8 if user_id % 6 == 5 else 0.2
}
# Rating baseado na preferência por categoria
base_rating = categoria_pref.get(produto['categoria'], 0.5)
rating = np.clip(
np.random.normal(base_rating * 5, 1.0),
1, 5
)
avaliacoes.append({
'usuario_id': user_id,
'produto_id': produto_id,
'rating': round(rating, 1),
'categoria': produto['categoria']
})
self.avaliacoes_df = pd.DataFrame(avaliacoes)
return self.produtos_df, self.avaliacoes_df
def treinar_sistema(self):
"""Treina tanto filtragem colaborativa quanto baseada em conteúdo"""
if self.avaliacoes_df is None:
raise ValueError("Dados não carregados. Execute gerar_dados_ecommerce() primeiro.")
print("Treinando sistema de recomendação...")
# 1. FILTRAGEM COLABORATIVA
print("1. Configurando filtragem colaborativa...")
# Criar matriz usuário-item
self.matriz_usuarios_itens = self.avaliacoes_df.pivot_table(
index='usuario_id',
columns='produto_id',
values='rating',
fill_value=0
)
# Aplicar SVD para redução de dimensionalidade
print("2. Aplicando decomposição SVD...")
self.modelo_svd.fit(self.matriz_usuarios_itens)
# 2. FILTRAGEM BASEADA EM CONTEÚDO
print("3. Configurando filtragem baseada em conteúdo...")
# Combinar features textuais dos produtos
self.produtos_df['features_combinadas'] = (
self.produtos_df['nome'] + ' ' +
self.produtos_df['categoria'] + ' ' +
self.produtos_df['subcategoria'] + ' ' +
self.produtos_df['descricao'] + ' ' +
self.produtos_df['marca']
)
# Vetorizar conteúdo usando TF-IDF
matriz_conteudo = self.vectorizer_conteudo.fit_transform(
self.produtos_df['features_combinadas']
)
# Calcular similaridade entre produtos
self.similaridade_itens = cosine_similarity(matriz_conteudo)
self.is_trained = True
print("Sistema treinado com sucesso!")
def recomendar_colaborativo(self, usuario_id, num_recomendacoes=10):
"""Recomendações baseadas em filtragem colaborativa"""
if not self.is_trained:
raise ValueError("Sistema não foi treinado!")
if usuario_id not in self.matriz_usuarios_itens.index:
# Usuário novo - retornar produtos mais populares
return self._produtos_populares(num_recomendacoes)
# Transformar perfil do usuário usando SVD
perfil_usuario = self.matriz_usuarios_itens.loc[usuario_id].values.reshape(1, -1)
perfil_reduzido = self.modelo_svd.transform(perfil_usuario)
# Reconstruir ratings preditos
ratings_preditos = self.modelo_svd.inverse_transform(perfil_reduzido)[0]
# Obter produtos que o usuário não avaliou
produtos_nao_avaliados = self.matriz_usuarios_itens.loc[usuario_id] == 0
indices_nao_avaliados = produtos_nao_avaliados[produtos_nao_avaliados].index
# Ordenar por rating predito
scores = [(idx, ratings_preditos[self.matriz_usuarios_itens.columns.get_loc(idx)])
for idx in indices_nao_avaliados]
scores.sort(key=lambda x: x[1], reverse=True)
return [produto_id for produto_id, _ in scores[:num_recomendacoes]]
def recomendar_conteudo(self, produto_id, num_recomendacoes=10):
"""Recomendações baseadas em similaridade de conteúdo"""
if not self.is_trained:
raise ValueError("Sistema não foi treinado!")
# Encontrar índice do produto
idx = self.produtos_df[self.produtos_df['produto_id'] == produto_id].index[0]
# Obter scores de similaridade
scores_similares = list(enumerate(self.similaridade_itens[idx]))
scores_similares.sort(key=lambda x: x[1], reverse=True)
# Excluir o próprio produto e retornar os mais similares
indices_similares = [i for i, _ in scores_similares[1:num_recomendacoes+1]]
produtos_similares = self.produtos_df.iloc[indices_similares]['produto_id'].tolist()
return produtos_similares
def recomendar_hibrido(self, usuario_id, produto_id=None, num_recomendacoes=10):
"""Combinação de filtragem colaborativa e baseada em conteúdo"""
recomendacoes_colaborativas = self.recomendar_colaborativo(
usuario_id, num_recomendacoes * 2
)
if produto_id:
recomendacoes_conteudo = self.recomendar_conteudo(
produto_id, num_recomendacoes * 2
)
# Combinar e dar pesos diferentes
scores_hibridos = {}
# Peso maior para colaborativo (0.7)
for i, prod_id in enumerate(recomendacoes_colaborativas):
peso = 0.7 * (1 - i / len(recomendacoes_colaborativas))
scores_hibridos[prod_id] = scores_hibridos.get(prod_id, 0) + peso
# Peso menor para conteúdo (0.3)
for i, prod_id in enumerate(recomendacoes_conteudo):
peso = 0.3 * (1 - i / len(recomendacoes_conteudo))
scores_hibridos[prod_id] = scores_hibridos.get(prod_id, 0) + peso
# Ordenar por score híbrido
recomendacoes_ordenadas = sorted(
scores_hibridos.items(),
key=lambda x: x[1],
reverse=True
)
return [prod_id for prod_id, _ in recomendacoes_ordenadas[:num_recomendacoes]]
else:
return recomendacoes_colaborativas[:num_recomendacoes]
def _produtos_populares(self, num_produtos):
"""Retorna produtos mais populares para usuários novos"""
produtos_populares = self.produtos_df.nlargest(
num_produtos,
['num_avaliacoes', 'avaliacao_media']
)
return produtos_populares['produto_id'].tolist()
def obter_detalhes_produtos(self, lista_produtos):
"""Retorna detalhes dos produtos recomendados"""
return self.produtos_df[
self.produtos_df['produto_id'].isin(lista_produtos)
][['produto_id', 'nome', 'categoria', 'preco', 'avaliacao_media']].to_dict('records')
def avaliar_sistema(self, test_size=0.2):
"""Avalia a qualidade das recomendações"""
# Dividir dados para teste
train_data, test_data = train_test_split(
self.avaliacoes_df,
test_size=test_size,
random_state=42
)
# Retreinar apenas com dados de treino
temp_avaliacoes = self.avaliacoes_df
self.avaliacoes_df = train_data
self.treinar_sistema()
# Testar recomendações
hits = 0
total_tests = 0
for _, row in test_data.head(100).iterrows(): # Testar 100 amostras
usuario = row['usuario_id']
produto_real = row['produto_id']
try:
recomendacoes = self.recomendar_hibrido(usuario, num_recomendacoes=20)
if produto_real in recomendacoes:
hits += 1
total_tests += 1
except:
continue
precision_at_20 = hits / total_tests if total_tests > 0 else 0
# Restaurar dados originais
self.avaliacoes_df = temp_avaliacoes
self.treinar_sistema()
return {
'precision_at_20': precision_at_20,
'hits': hits,
'total_tests': total_tests
}
# Exemplo de uso
if __name__ == "__main__":
print("=== SISTEMA DE RECOMENDAÇÃO E-COMMERCE ===")
# Inicializar sistema
sistema = SistemaRecomendacao()
# Gerar dados
print("1. Gerando dados de e-commerce...")
produtos_df, avaliacoes_df = sistema.gerar_dados_ecommerce()
print(f"Gerados {len(produtos_df)} produtos e {len(avaliacoes_df)} avaliações")
# Treinar sistema
print("\n2. Treinando sistema...")
sistema.treinar_sistema()
# Testar recomendações
print("\n3. Testando recomendações...")
usuario_teste = 1001
produto_interesse = 50
# Recomendações colaborativas
rec_colab = sistema.recomendar_colaborativo(usuario_teste, 5)
print(f"\nRecomendações colaborativas para usuário {usuario_teste}:")
detalhes = sistema.obter_detalhes_produtos(rec_colab)
for produto in detalhes:
print(f" - {produto['nome']} (R${produto['preco']:.2f})")
# Recomendações por conteúdo
rec_conteudo = sistema.recomendar_conteudo(produto_interesse, 5)
print(f"\nProdutos similares ao produto {produto_interesse}:")
detalhes = sistema.obter_detalhes_produtos(rec_conteudo)
for produto in detalhes:
print(f" - {produto['nome']} ({produto['categoria']})")
# Recomendações híbridas
rec_hibridas = sistema.recomendar_hibrido(usuario_teste, produto_interesse, 5)
print(f"\nRecomendações híbridas:")
detalhes = sistema.obter_detalhes_produtos(rec_hibridas)
for produto in detalhes:
print(f" - {produto['nome']} (R${produto['preco']:.2f}) - {produto['categoria']}")
# Avaliar sistema
print("\n4. Avaliando sistema...")
metricas = sistema.avaliar_sistema()
print(f"Precision@20: {metricas['precision_at_20']:.3f}")
print(f"Acertos: {metricas['hits']}/{metricas['total_tests']}")
🎯 Resumo dos Projetos Práticos
Habilidades Desenvolvidas:
- Detecção de anomalias em tempo real
- Sistemas de recomendação híbridos
- Processamento de grandes volumes de dados
- Avaliação e monitoramento de modelos
- Implementação de soluções end-to-end
Tecnologias Aplicadas:
- Scikit-learn para ML clássico
- Pandas para manipulação de dados
- NumPy para computação científica
- TF-IDF para análise de texto
- SVD para redução de dimensionalidade
💼 Valor para o Mercado:
Estes projetos demonstram habilidades essenciais para posições como Cientista de Dados, Engenheiro de ML e Analista de IA. Cada projeto resolve problemas reais enfrentados por empresas, mostrando seu valor prático no mercado de trabalho.
Capítulo 9: Deploy e Produção
Colocando modelos de IA em produção
9.1 API REST com Flask
from flask import Flask, request, jsonify
import pickle
import numpy as np
from sklearn.ensemble import RandomForestClassifier
app = Flask(__name__)
# Carregar modelo treinado
with open('modelo_credito.pkl', 'rb') as f:
modelo = pickle.load(f)
@app.route('/predict', methods=['POST'])
def predict():
try:
# Receber dados do request
data = request.json
# Extrair features
features = np.array([[
data['idade'],
data['renda'],
data['score_credito'],
data['dividas'],
data['tempo_emprego']
]])
# Fazer predição
predicao = modelo.predict(features)[0]
probabilidade = modelo.predict_proba(features)[0][1]
# Retornar resultado
return jsonify({
'inadimplente': bool(predicao),
'probabilidade': float(probabilidade),
'status': 'success'
})
except Exception as e:
return jsonify({
'error': str(e),
'status': 'error'
}), 400
@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
9.2 Containerização com Docker
FROM python:3.9-slim
WORKDIR /app
# Instalar dependências do sistema
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Copiar requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar código da aplicação
COPY . .
# Criar usuário não-root
RUN useradd --create-home --shell /bin/bash app
RUN chown -R app:app /app
USER app
# Expor porta
EXPOSE 5000
# Comando de início
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
version: '3.8'
services:
ia-api:
build: .
ports:
- "5000:5000"
environment:
- FLASK_ENV=production
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
redis:
image: redis:6-alpine
ports:
- "6379:6379"
restart: unless-stopped
9.3 Monitoramento e Logging
import logging
import time
import psutil
from datetime import datetime
import json
# Configurar logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('ia_api.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
class ModelMonitor:
def __init__(self):
self.predictions_count = 0
self.errors_count = 0
self.start_time = time.time()
def log_prediction(self, features, prediction, probability, response_time):
"""Registra uma predição para monitoramento"""
self.predictions_count += 1
log_data = {
'timestamp': datetime.now().isoformat(),
'features': features.tolist(),
'prediction': int(prediction),
'probability': float(probability),
'response_time_ms': response_time * 1000,
'prediction_id': self.predictions_count
}
logger.info(f"PREDICTION: {json.dumps(log_data)}")
def log_error(self, error_message, request_data=None):
"""Registra erros para análise"""
self.errors_count += 1
error_data = {
'timestamp': datetime.now().isoformat(),
'error_message': str(error_message),
'request_data': request_data,
'error_count': self.errors_count
}
logger.error(f"ERROR: {json.dumps(error_data)}")
def get_health_metrics(self):
"""Retorna métricas de saúde do sistema"""
uptime = time.time() - self.start_time
return {
'uptime_seconds': uptime,
'total_predictions': self.predictions_count,
'total_errors': self.errors_count,
'error_rate': self.errors_count / max(self.predictions_count, 1),
'cpu_percent': psutil.cpu_percent(),
'memory_percent': psutil.virtual_memory().percent,
'timestamp': datetime.now().isoformat()
}
# Uso no app Flask
monitor = ModelMonitor()
@app.route('/predict', methods=['POST'])
def predict():
start_time = time.time()
try:
data = request.json
features = np.array([[...]]) # Processar features
prediction = modelo.predict(features)[0]
probability = modelo.predict_proba(features)[0][1]
response_time = time.time() - start_time
monitor.log_prediction(features, prediction, probability, response_time)
return jsonify({
'inadimplente': bool(prediction),
'probabilidade': float(probability),
'status': 'success'
})
except Exception as e:
monitor.log_error(str(e), request.json)
return jsonify({'error': str(e), 'status': 'error'}), 400
@app.route('/metrics', methods=['GET'])
def metrics():
return jsonify(monitor.get_health_metrics())
Projeto Final: Sistema Completo de IA
🎯 Objetivo Final:
Criar um sistema completo de IA em produção com API, monitoramento, testes e deploy automatizado.
Componentes do Sistema:
- ✅ Modelo de ML treinado
- ✅ API REST com Flask
- ✅ Container Docker
- ✅ Sistema de monitoramento
- 🔄 Testes automatizados
- 🔄 Pipeline CI/CD
Tecnologias Utilizadas:
- 🐍 Python + Scikit-learn
- 🌐 Flask + Gunicorn
- 🐳 Docker + Docker Compose
- 📊 Logging + Métricas
- ☁️ Deploy em nuvem
- 🔧 NSSM para Windows Services
🎉 Parabéns! Você Completou a Jornada
Você agora possui todas as habilidades fundamentais para ser um especialista em IA:
Fundamentos Sólidos
Python, matemática, estatística
Experiência Prática
Projetos reais, exercícios aplicados
Produção
Deploy, monitoramento, APIs
Próximos Passos:
- Continue praticando com projetos pessoais
- Participe de competições (Kaggle, DrivenData)
- Contribua para projetos open source
- Especialize-se em uma área específica (NLP, CV, etc.)
- Mantenha-se atualizado com as últimas tecnologias