Análise Completa de Problemas de Regressão: Comparação de Modelos, Intervalos de Confiança e Implementação com Bootstrap

1. Introdução aos Problemas de Regressão

Problemas de regressão visam prever valores contínuos, como a resistência à compressão do concreto, temperatura ou preço de imóveis. Esta análise abrange quatro pilares: distinção entre modelos de regressão e classificação, métricas de avaliação essenciais, abordagens para regressão com múltiplas saídas, e o uso de intervalos de confiança via bootstrap.

2. Modelos de Regressão vs. Classificação

A diferença fundamental reside no objetivo: regressores preveem quantidades (ex.: "quanto"), enquanto classificadores determinam categorias (ex.: "qual"). Regressores utilizam variância para divisões, e classificadores usam medidas de pureza como o índice Gini. Modelos como LinearRegression e RandomForestRegressor são exemplos de regressores, enquanto LogisticRegression pertence à classificação, apesar do nome.

3. Métricas de Avaliação para Regressão

  • Erro Absoluto Médio (MAE): Média dos erros absolutos, sendo robusto a outliers.
  • Erro Quadrático Médio (MSE): Penaliza erros maiores, ampliando o impacto de valores atípicos.
  • Raiz do Erro Quadrático Médio (RMSE): Mantém a mesma unidade dos dados originais, comum em artigos acadêmicos.
  • Coeficiente de Determinação (R²): Varia de 0 a 1, onde valores próximos de 1 indicam melhor ajuste.

4. Regressão com Múltiplas Saídas

Para prever múltiplas variáveis contínuas simultaneamente, como temperatura e umidade, existem três estratégias principais: utilizar modelos com suporte nativo (ex.: redes neurais), aplicar wrappers como MultiOutputRegressor do scikit-learn, ou treinar modelos independentes para cada saída, perdendo possíveis correlações entre as variáveis alvo.

5. Intervalos de Confiança e Bootstrap

Intervalos de confiança fornecem uma faixa de valores prováveis para uma estiamtiva, em vez de um valor pontual. Por exemplo, um intervalo de 95% indica que, com 95% de probabilidade, o valor real está dentro daquela faixa. O bootstrap é uma técnica computacional que gera múltiplas amostras por reamostragem com reposição, permitindo a estimação desses intervalos sem suposições distributivas complexas.

6. Implementação Prática com Dados de Concreto

6.1 Preparação do Ambiente e Carregamento dos Dados


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

plt.rcParams['font.sans-serif'] = ['Arial']
plt.rcParams['axes.unicode_minus'] = False
sns.set(style="whitegrid")

# Carregar o dataset UCI Concrete Compressive Strength
url_concrete = "https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/concrete.csv"
try:
    dataframe = pd.read_csv(url_concrete)
    print("Dados carregados com sucesso.")
except Exception as erro:
    print(f"Falha ao carregar dados: {erro}")
    raise erro

# Renomear colunas para nomes descritivos em português
colunas_descritivas = [
    'Cimento', 'Escória', 'CinzaVolante', 'Água',
    'Superplastificante', 'AgregadoGrosso', 'AgregadoFino',
    'Idade', 'Resistencia'
]
dataframe.columns = colunas_descritivas

print(f"Formato dos dados: {dataframe.shape}")
print(dataframe.head())

6.2 Separação dos Dados e Treinamento de Modelos


# Dividir em características (X) e alvo (y)
caracteristicas = dataframe.iloc[:, :-1]
alvo = dataframe.iloc[:, -1]

# Separar conjuntos de treino e teste
X_treino, X_teste, y_treino, y_teste = train_test_split(
    caracteristicas, alvo, test_size=0.2, random_state=42
)

# Definir modelos de regressão para comparação
modelos_reg = {
    "Regressão Linear": LinearRegression(),
    "Árvore de Decisão": DecisionTreeRegressor(random_state=42),
    "Floresta Aleatória": RandomForestRegressor(n_estimators=100, random_state=42),
    "Gradient Boosting": GradientBoostingRegressor(n_estimators=100, random_state=42)
}

resultados_metricas = []
previsoes_armazenadas = {}

print("Iniciando treinamento e avaliação...")
for nome_modelo, modelo in modelos_reg.items():
    modelo.fit(X_treino, y_treino)
    previsoes = modelo.predict(X_teste)
    previsoes_armazenadas[nome_modelo] = previsoes
    
    r2_valor = r2_score(y_teste, previsoes)
    rmse_valor = np.sqrt(mean_squared_error(y_teste, previsoes))
    mae_valor = mean_absolute_error(y_teste, previsoes)
    
    resultados_metricas.append({
        "Modelo": nome_modelo,
        "R²": round(r2_valor, 4),
        "RMSE": round(rmse_valor, 4),
        "MAE": round(mae_valor, 4)
    })
    print(f"Modelo: {nome_modelo} | R²: {r2_valor:.4f} | RMSE: {rmse_valor:.4f}")

tabela_resultados = pd.DataFrame(resultados_metricas).sort_values(by="R²", ascending=False)
print(tabela_resultados)

6.3 Visualização de Resultados e Intervalos de Confiança


figura, eixos = plt.subplots(2, 2, figsize=(16, 14))
eixos_planos = eixos.flatten()
paleta_cores = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728"]

# Definir limites comuns para os eixos
valor_min = min(y_teste.min(), np.min(list(previsoes_armazenadas.values()))) - 5
valor_max = max(y_teste.max(), np.max(list(previsoes_armazenadas.values()))) + 5

for idx, (nome, modelo) in enumerate(modelos_reg.items()):
    eixo = eixos_planos[idx]
    preds = previsoes_armazenadas[nome]
    
    # Gráfico de dispersão com intervalo de confiança de 95%
    sns.regplot(
        x=y_teste, y=preds, ax=eixo,
        color=paleta_cores[idx],
        ci=95,
        scatter_kws={'s': 25, 'alpha': 0.6},
        line_kws={'color': 'black', 'linewidth': 2}
    )
    
    # Linha de previsão perfeita
    eixo.plot([valor_min, valor_max], [valor_min, valor_max], 
              'r--', linewidth=2, label='Previsão Ideal')
    
    r2_final = r2_score(y_teste, preds)
    rmse_final = np.sqrt(mean_squared_error(y_teste, preds))
    
    texto_metricas = f'R² = {r2_final:.3f}\nRMSE = {rmse_final:.3f}'
    eixo.text(0.05, 0.95, texto_metricas, transform=eixo.transAxes,
              fontsize=12, verticalalignment='top',
              bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
    
    eixo.set_title(nome, fontsize=14)
    eixo.set_xlabel('Resistência Real')
    eixo.set_ylabel('Resistência Prevista')
    eixo.set_xlim(valor_min, valor_max)
    eixo.set_ylim(valor_min, valor_max)
    eixo.legend()
    eixo.grid(True, linestyle='--', alpha=0.7)

plt.suptitle('Comparação de Modelos: Efeito Ajustado e Intervalos de Confiança', fontsize=18)
plt.tight_layout()
plt.subplots_adjust(top=0.93)
plt.show()

Tags: regressão aprendizado-de-máquina bootstrap Python scikit-learn

Publicado em 7-19 16:38