Imagine que você é um médico analisando exames médicos. Um paciente tem sintomas que poderiam indicar duas condições diferentes. Em vez de dar um diagnóstico definitivo baseado em informações incompletas, você diz: “Há 75% de chance de ser a condição A, e 25% de ser a condição B.” Esta nuance é exatamente o que as previsões probabilísticas do GPC oferecem – não apenas uma resposta, mas uma medida calibrada de quão confiante é essa resposta. Diferentemente de classificadores que forçam uma decisão binária, o GPC admite quando está em território incerto.
Como isso funciona na prática?
As previsões probabilísticas do GPC vão beyond do simples “sim/não” ao fornecer probabilidades bem calibradas para cada classe. O modelo primeiro aprende uma função latente \(f(x)\) que representa o “score” não observado para cada classe. Posteriormente, esta função é mapeada para probabilidades usando uma função de ligação como a sigmoide \(\sigma(f(x)) = \frac{1}{1 + e^{-f(x)}}\). O que torna o GPC especial é que ele não apenas fornece uma probabilidade pontual, mas considera toda a distribuição possível da função latente, resultando em probabilidades que honestamente refletem a incerteza do modelo.
Mãos na massa: diagnóstico médico com probabilidades calibradas
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
""" Previsões probabilísticas com GPC para diagnóstico médico Demonstra como obter e interpretar probabilidades calibradas """ import numpy as np import matplotlib.pyplot as plt from sklearn.gaussian_process import GaussianProcessClassifier from sklearn.gaussian_process.kernels import RBF from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.calibration import calibration_curve from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier # Simulando dados de diagnóstico médico # Características: [idade, pressão_arterial, colesterol, glicose] def criar_dados_medicos(): """Cria dados simulados de pacientes com risco cardiovascular""" np.random.seed(42) n_pacientes = 800 # Gerando características médicas realistas idade = np.random.normal(55, 15, n_pacientes) pressao = np.random.normal(130, 20, n_pacientes) colesterol = np.random.normal(200, 40, n_pacientes) glicose = np.random.normal(110, 25, n_pacientes) X = np.column_stack([idade, pressao, colesterol, glicose]) # Risco cardiovascular baseado em combinação não-linear # Pacientes com múltiplos fatores de risco têm maior probabilidade risco_latente = ( 0.02 * (idade - 50) + 0.01 * (pressao - 120) + 0.005 * (colesterol - 180) + 0.008 * (glicose - 100) + 0.0001 * (idade - 50) * (pressao - 120) # Interação ) # Adicionando ruído e convertendo para binário probabilidade_risco = 1 / (1 + np.exp(-risco_latente + np.random.normal(0, 0.3, n_pacientes))) y = (probabilidade_risco > 0.5).astype(int) return X, y X, y = criar_dados_medicos() print(f"Dados médicos simulados: {X.shape[0]} pacientes") print(f"Distribuição: {np.sum(y==1)} com risco, {np.sum(y==0)} sem risco") # Dividindo os dados X_treino, X_teste, y_treino, y_teste = train_test_split( X, y, test_size=0.3, random_state=42, stratify=y ) # Criando GPC com kernel RBF kernel = 1.0 * RBF(length_scale=1.0) gpc = GaussianProcessClassifier( kernel=kernel, random_state=42, n_restarts_optimizer=5 ) print("\nTreinando GPC para diagnóstico probabilístico...") gpc.fit(X_treino, y_treino) # Obtendo previsões probabilísticas probabilidades_gpc = gpc.predict_proba(X_teste)[:, 1] # Probabilidade de risco print("\n=== ANÁLISE DAS PREVISÕES PROBABILÍSTICAS ===") # Analisando casos específicos print("\nExemplos de diagnósticos probabilísticos:") indices_exemplo = [0, 5, 10, 15, 20] for idx in indices_exemplo: prob = probabilidades_gpc[idx] diagnostico_real = "RISCO" if y_teste[idx] == 1 else "SEM RISCO" confianca_gpc = max(prob, 1-prob) print(f"Paciente {idx+1}:") print(f" Probabilidade de risco: {prob:.3f} ({prob*100:.1f}%)") print(f" Diagnóstico GPC: {'RISCO' if prob > 0.5 else 'SEM RISCO'}") print(f" Diagnóstico real: {diagnostico_real}") print(f" Confiança do modelo: {confianca_gpc:.3f}") print(f" Status: {'✓ CORRETO' if (prob > 0.5) == (y_teste[idx] == 1) else '✗ ERRADO'}") # Comparando com outros classificadores print("\n=== COMPARAÇÃO COM OUTROS MÉTODOS ===") # Regressão Logística lr = LogisticRegression(random_state=42) lr.fit(X_treino, y_treino) prob_lr = lr.predict_proba(X_teste)[:, 1] # Random Forest rf = RandomForestClassifier(n_estimators=100, random_state=42) rf.fit(X_treino, y_treino) prob_rf = rf.predict_proba(X_teste)[:, 1] # Análise de calibração def plot_calibracao(y_true, probs, labels): """Plota curvas de calibração para diferentes modelos""" plt.figure(figsize=(10, 8)) for i, (prob, label) in enumerate(zip(probs, labels)): fraction_of_positives, mean_predicted_value = calibration_curve( y_true, prob, n_bins=10, strategy='quantile' ) plt.subplot(2, 1, 1) plt.plot(mean_predicted_value, fraction_of_positives, "s-", label=label, alpha=0.8) plt.subplot(2, 1, 2) plt.hist(prob, bins=20, alpha=0.6, label=label, density=True) plt.subplot(2, 1, 1) plt.plot([0, 1], [0, 1], "k--", label="Perfeitamente calibrado") plt.xlabel("Probabilidade Prevista") plt.ylabel("Fração de Positivos") plt.title("Curvas de Calibração") plt.legend() plt.grid(True, alpha=0.3) plt.subplot(2, 1, 2) plt.xlabel("Probabilidade Prevista") plt.ylabel("Densidade") plt.title("Distribuição das Probabilidades") plt.legend() plt.grid(True, alpha=0.3) plt.tight_layout() plt.show() # Plotando comparação probabilidades = [probabilidades_gpc, prob_lr, prob_rf] labels = ['GPC', 'Regressão Logística', 'Random Forest'] plot_calibracao(y_teste, probabilidades, labels) # Análise de casos de fronteira (alta incerteza) print("\n=== CASOS DE FRONTEIRA (ALTA INCERTEZA) ===") casos_incertos = (probabilidades_gpc > 0.4) & (probabilidades_gpc < 0.6) print(f"Pacientes com diagnóstico incerto (40%-60% probabilidade): {np.sum(casos_incertos)}") if np.any(casos_incertos): print("Estes casos podem precisar de exames adicionais:") for idx in np.where(casos_incertos)[0][:3]: print(f" Paciente {idx}: probabilidade = {probabilidades_gpc[idx]:.3f}") |
Os detalhes que fazem diferença
A grande vantagem das previsões probabilísticas do GPC é sua calibração natural – quando o modelo diz “75% de chance”, isso realmente significa que em 75 de 100 casos similares a previsão estaria correta. Contudo, esta calibração depende crucialmente da escolha adequada do kernel e da qualidade dos dados de treinamento. Analogamente importante é entender que as probabilidades do GPC refletem incerteza epistêmica (devido à falta de dados) mas não necessariamente incerteza aleatória inerente ao processo. A aproximação por Laplace usada no Scikit-Learn torna o método computacionalmente viável, mas pode subestimar incertezas em problemas muito complexos.
- Calibração: Probabilidades do GPC são naturalmente bem calibradas
- Incerteza epistêmica: Reflete falta de conhecimento, não variabilidade inerente
- Casos de fronteira: Probabilidades perto de 0.5 indicam necessidade de mais informações
- Tomada de decisão: Use probabilidades para decisões baseadas em risco
Perguntas que os iniciantes fazem
Você deve estar se perguntando: “Como saber se as probabilidades do GPC são confiáveis?” Excelente questão! A curva de calibração é sua melhor ferramenta – ela mostra se probabilidades previstas correspondem a frequências observadas. Uma confusão comum é entre a “confiança” de modelos como SVM e as probabilidades do GPC – as primeiras não são probabilidades calibradas. Outra dúvida frequente: “Quando devo confiar em uma probabilidade de 60% versus 90%?” Use limiares de decisão baseados no custo de erros – em medicina, talvez queira 90% de certeza, enquanto em recomendação de filmes 60% pode ser suficiente.
Para onde ir agora?
Experimente usar as previsões probabilísticas do GPC em problemas onde diferentes tipos de erro têm custos diferentes. Implemente sistemas de decisão que usem limiares de probabilidade adaptativos. Compare a calibração do GPC com outros métodos em seus próprios dados. O momento “aha!” acontece quando você percebe que tomar decisões considerando não apenas o que é mais provável, mas quão provável é, leva a resultados muito melhores no mundo real.
Assuntos relacionados
Para dominar previsões probabilísticas, estude:
- Teoria da decisão: custos de falsos positivos vs falsos negativos
- Calibração de modelos: como avaliar e melhorar probabilidades
- Incerteza epistêmica vs aleatória: fontes diferentes de incerteza
- Curvas ROC e precisão-recall: avaliação de classificadores probabilísticos
- Teoria da informação: entropia e surpresa em previsões