#> UE Cirurgia: 8.40
#> UE Medicamento: 7.00
#> Escolha: Cirurgia
Decisão, Lógica e Incerteza — MINTER/DINTER
PPGMDS - UFPB - Programa de Pós-Graduação em Modelos de Decisão e Saúde
julho, 2026
“A boa decisão não é a que garante o melhor resultado, mas a que é tomada da melhor forma possível com a informação disponível.”
— adaptado de H. A. Simon
O que vocês já viram
O que faremos hoje
Se em algum momento a notação matemática travar o raciocínio, me interrompam. O objetivo não é decorar fórmula — é entender o que ela diz.
| Ambiente | O que sei sobre os desfechos | Exemplo em saúde |
|---|---|---|
| Certeza | Sei exatamente o que vai acontecer | Preço e prazo de seringas em contrato |
| Risco | Não sei o desfecho, mas conheço as probabilidades | Cirurgia com 5% de mortalidade tabelada |
| Incerteza | Não conheço nem as probabilidades | Início de uma epidemia nova |
Importante
O bloco de hoje mora no risco. É o único ambiente em que conseguimos calcular — e é onde a Medicina Baseada em Evidências opera, porque ela nos entrega as probabilidades.
| Aspecto | Normativa | Descritiva | Prescritiva |
|---|---|---|---|
| Pergunta | Como decidir idealmente? | Como as pessoas de fato decidem? | Como ajudar a decidir melhor? |
| Base | Racionalidade matemática | Psicologia, observação | Síntese das duas |
| Limitação | Ignora a cognição humana | Não prescreve melhorias | Depende de boas evidências |
O modelo racional e os modelos não-racionais que vocês viram são, respectivamente, o lado normativo e o lado descritivo. A teoria prescritiva é a ponte — e é ela que justifica a existência de um Sistema de Apoio à Decisão.
Importante
Um médico que prescreve corretamente segundo toda a evidência disponível, e ainda assim o paciente tem uma reação rara e adversa, não tomou uma decisão ruim. Confundir as duas coisas tem nome: viés de resultado (outcome bias).
Quando conheço as probabilidades, posso calcular qual alternativa é melhor:
\[EU(A) = \sum_{i} P(O_i \mid A) \cdot U(O_i)\]
Lendo em português: a utilidade esperada de uma ação \(A\) é a soma, sobre todos os desfechos possíveis, do valor de cada desfecho multiplicado pela chance dele acontecer.
Cirurgia: 80% de cura plena (\(U=10\)), 20% de falha (\(U=2\)) Medicamento: 100% de cura parcial (\(U=7\))
Na mão, passo a passo:
\(EU(\text{cirurgia})\) \(= 0{,}80 \times 10 + 0{,}20 \times 2\) \(= 8{,}0 + 0{,}4 = \mathbf{8{,}4}\)
\(EU(\text{medicamento})\) \(= 1{,}00 \times 7 = \mathbf{7{,}0}\)
Escolha prescritiva: cirurgia
#> UE Cirurgia: 8.40
#> UE Medicamento: 7.00
#> Escolha: Cirurgia
Importante
Se o paciente é um pianista profissional e a falha da cirurgia implica perda de função fina da mão, talvez \(U(\text{falha})\) não seja 2 — seja 0. Refaça a conta: \(0{,}80 \times 10 + 0{,}20 \times 0 = 8{,}0\). Ainda ganha, mas a margem cai. Se a falha valesse \(-5\), o medicamento passaria à frente.
Exercício: um protocolo de triagem oferece duas condutas. Calcule a utilidade esperada de cada uma e decida.
#> UE Internar: 9.65
#> UE Observar: 8.80
#> Conduta prescritiva: Internar
| Aspecto | Orientado a Dados | Orientado a Modelos |
|---|---|---|
| Pergunta central | O que aconteceu? | Qual a melhor ação? |
| Insumo principal | Grande volume de dados históricos | Lógica matemática e restrições |
| Técnicas típicas | Painéis, mineração, OLAP | Otimização, simulação, árvores de decisão |
| Olhar | Retrospectivo | Prospectivo |
| Exemplo em saúde | Identificar comorbidades recorrentes | Definir escala ótima de plantões |
A Profª. Kátya/Juliana já definiu o que é um SAD e quais são seus componentes. Esta distinção é o acréscimo de hoje — e é ela que vai reaparecer no fim da aula, quando ligarmos tudo à Aprendizagem de Máquina.
Exercício: classifique cada cenário como SAD orientado a dados ou a modelos.
Resposta: 1 — Dados · 2 — Modelos · 3 — Dados · 4 — Modelos
Exemplo: se \(P(\text{diabetes}) = 0{,}08\) em adultos brasileiros, então \(P(\text{não ter diabetes}) = 0{,}92\). Só isso.
\[P(A \mid B) = \frac{P(A \cap B)}{P(B)}\]
Lendo em português: a probabilidade de \(A\) dado que \(B\) já aconteceu.
Importante
\(P(A \mid B) \neq P(B \mid A)\) — a falácia da transposição, o erro mais comum na leitura de exames.
Importante
Na saúde, eventos raramente são independentes. A probabilidade de hipertensão e diabetes coexistirem não é \(P(\text{HAS}) \times P(\text{DM})\) — as duas condições andam juntas.
\[P(D \mid +) = \frac{P(+ \mid D) \cdot P(D)}{P(+)}\]
| Termo | Nome técnico | Significado clínico |
|---|---|---|
| \(P(D)\) | Probabilidade a priori | Prevalência da doença |
| \(P(+ \mid D)\) | Verossimilhança | Sensibilidade do teste |
| \(P(+)\) | Evidência | Chance total de dar positivo |
| \(P(D \mid +)\) | Probabilidade a posteriori | Valor Preditivo Positivo (VPP) |
Bayes é uma máquina de atualizar crença: entra o que eu achava antes do exame, sai o que devo achar depois dele.
Características do teste (não mudam com a população)
Características do contexto (mudam com a população)
Importante
VPP e VPN dependem da prevalência. O mesmo teste pode ter VPP de 8% num rastreamento populacional e de 85% numa clínica especializada.
Teste com sensibilidade 95% e especificidade 90%. Imagine 1.000 pessoas rastreadas numa população onde a doença atinge 1%.
| Doentes | Sadios | Total | |
|---|---|---|---|
| Teste + | 10 | 99 | 109 |
| Teste − | 0 | 891 | 891 |
| Total | 10 | 990 | 1.000 |
De onde vêm os números:
\[VPP = \frac{10}{109} \approx \mathbf{9\%}\]
vpp_vpn <- function(prev, sens, espec) {
p_pos <- sens * prev + (1 - espec) * (1 - prev) # regra da probabilidade total
c(VPP = 100 * (sens * prev) / p_pos,
VPN = 100 * (espec * (1 - prev)) / (1 - p_pos))
}
round(rbind(`Rastreamento (prev. 1%)` = vpp_vpn(0.01, 0.95, 0.90),
`Clínica espec. (prev. 30%)` = vpp_vpn(0.30, 0.95, 0.90)), 1)#> VPP VPN
#> Rastreamento (prev. 1%) 8.8 99.9
#> Clínica espec. (prev. 30%) 80.3 97.7
Mesmo teste, duas populações: VPP de ~8,8% vs. ~80,3%. O teste não mudou — o contexto mudou.
library(ggplot2)
library(scales)
prev_seq <- seq(0.001, 0.50, by = 0.001)
sens <- 0.95; espec <- 0.90
vpp_seq <- (sens * prev_seq) / (sens * prev_seq + (1 - espec) * (1 - prev_seq))
df_vpp <- data.frame(prevalencia = prev_seq, vpp = vpp_seq)
ggplot(df_vpp, aes(x = prevalencia, y = vpp)) +
geom_line(color = "#7ecff7", linewidth = 1.3) +
geom_vline(xintercept = 0.01, color = "#f07050", linetype = "dashed") +
geom_vline(xintercept = 0.30, color = "#a8f77e", linetype = "dashed") +
annotate("text", x = 0.01, y = 0.15, label = "1%\n(rastreamento)",
color = "#f07050", size = 3.5, hjust = -0.1) +
annotate("text", x = 0.30, y = 0.50, label = "30%\n(clínica especializada)",
color = "#a8f77e", size = 3.5, hjust = -0.05) +
scale_x_continuous(labels = percent_format()) +
scale_y_continuous(labels = percent_format()) +
labs(title = "Valor Preditivo Positivo em função da prevalência",
subtitle = "Sensibilidade = 95%, Especificidade = 90%",
x = "Prevalência da doença", y = "VPP") +
theme_minimal(base_size = 13)\[P(D \mid +_A, +_B) \;\propto\; P(+_B \mid D) \cdot \underbrace{P(D \mid +_A)}_{\text{nova priori}}\]
Exercício: um teste para sepse tem sensibilidade 85% e especificidade 80%. Numa UTI com prevalência estimada de 25%, calcule o VPP e o VPN e interprete clinicamente.
Comece imaginando 1.000 pacientes: quantos têm sepse? Desses, quantos o teste pega? E quantos falsos positivos vêm dos demais?
#> VPP: 58.6%
#> VPN: 94.1%
VPN ~94% dá boa segurança para excluir. VPP ~59%: cerca de 4 em cada 10 positivos são falso alarme — positivo isolado não confirma sepse.
A Profª. Kátya/Juliana classificou os tipos de raciocínio — dedutivo, indutivo, abdutivo, probabilístico. Hoje vamos ao maquinário formal do raciocínio dedutivo.
| Tipo de lógica | Lida com | Exemplo em saúde |
|---|---|---|
| Clássica | Verdadeiro ou falso | “O paciente tem febre” |
| Não monotônica | Revisão de conclusões | “Já não parece mais gripe” |
| Fuzzy | Graus de verdade | “A febre é alta” |
| Probabilística | Incerteza quantificada | “85% de chance de infecção” |
Esta tabela é o roteiro do resto do dia: as duas últimas linhas são o Turno 2.
São proposições:
Não são proposições:
A lógica clássica exige que toda afirmação seja precisamente V ou F. É exatamente essa rigidez que a lógica fuzzy vai suavizar à tarde.
Sejam \(p\) e \(q\) proposições.
| Conectivo | Símbolo | Nome | Significado |
|---|---|---|---|
| Negação | \(\neg p\) | NÃO | inverte o valor de \(p\) |
| Conjunção | \(p \wedge q\) | E | V somente se ambos V |
| Disjunção | \(p \vee q\) | OU | V se ao menos um V |
| OU exclusivo | \(p \oplus q\) | XOR | V somente se exatamente um V |
| Condicional | \(p \rightarrow q\) | SE…ENTÃO | F apenas se \(p\) V e \(q\) F |
| Bicondicional | \(p \leftrightarrow q\) | SE E SOMENTE SE | V se ambos iguais |
Exemplo clínico: “SE febre \(\wedge\) tosse \(\wedge\) dispneia ENTÃO suspeitar de pneumonia”
Negação \(\neg p\)
| \(p\) | \(\neg p\) |
|---|---|
| V | F |
| F | V |
Conjunção \(p \wedge q\)
| \(p\) | \(q\) | \(p \wedge q\) |
|---|---|---|
| V | V | V |
| V | F | F |
| F | V | F |
| F | F | F |
Exemplo clínico — critérios SIRS:
A regra SIRS exige ao menos dois dos critérios:
\[\text{SIRS} \equiv (p \wedge q) \vee (p \wedge r) \vee (q \wedge r)\]
Se \(p = V\), \(q = V\), \(r = F\): \(\text{SIRS} = V\) ✓
Disjunção \(p \vee q\)
| \(p\) | \(q\) | \(p \vee q\) |
|---|---|---|
| V | V | V |
| V | F | V |
| F | V | V |
| F | F | F |
Condicional \(p \rightarrow q\)
| \(p\) | \(q\) | \(p \rightarrow q\) |
|---|---|---|
| V | V | V |
| V | F | F |
| F | V | V |
| F | F | V |
Importante
O condicional só é falso quando a premissa é V e a conclusão é F — ou seja, quando a regra mente.
| \(p\) | \(q\) | \(\neg p\) | \(p \wedge q\) | \(p \vee q\) | \(p \oplus q\) | \(p \rightarrow q\) | \(p \leftrightarrow q\) |
|---|---|---|---|---|---|---|---|
| V | V | F | V | V | F | V | V |
| V | F | F | F | V | V | F | F |
| F | V | V | F | V | V | V | F |
| F | F | V | F | F | F | V | V |
A segunda linha é a mais reveladora: é a única em que o condicional é falso (a premissa valeu, a conclusão não veio) e é também onde o XOR é verdadeiro.
| Conectivo | Símbolo lógico | R (vetorizado) | R (escalar) |
|---|---|---|---|
| Negação | \(\neg p\) | !x |
!x |
| Conjunção | \(p \wedge q\) | x & y |
x && y |
| Disjunção | \(p \vee q\) | x | y |
x || y |
| OU exclusivo | \(p \oplus q\) | xor(x, y) |
xor(x, y) |
Importante
& e | operam elemento a elemento (paciente a paciente, numa base de dados). && e || avaliam apenas o primeiro elemento — use-os só em condições de if.
#> Alerta SIRS (febre E taquicardia):
#> [1] TRUE FALSE FALSE TRUE FALSE
Cada operação devolve um valor por paciente — é assim que um sistema de alerta varre a base inteira de uma vez.
#> taquicardia OU dispneia:
#> [1] TRUE TRUE TRUE TRUE FALSE
#> febre E (taquic. OU dispneia):
#> [1] TRUE TRUE FALSE TRUE FALSE
Os parênteses importam: febre & (taquicardia | dispneia) não é o mesmo que (febre & taquicardia) | dispneia.
Modus Ponens (afirmar afirmando)
\[\frac{p \rightarrow q \;;\; p}{\therefore \; q}\]
SE febre E tosse ENTÃO suspeitar de gripe.
O paciente tem febre e tosse.
\(\therefore\) Suspeitar de gripe. ✓
Modus Tollens (negar negando)
\[\frac{p \rightarrow q \;;\; \neg q}{\therefore \; \neg p}\]
SE pneumonia ENTÃO raio-X alterado.
O raio-X está normal.
\(\therefore\) Provavelmente não é pneumonia. ✓
São os dois padrões de inferência que sustentam o raciocínio automático de qualquer sistema especialista clínico.
Em R (e em qualquer banco de dados): \(\forall\) vira all(), \(\exists\) vira any(). É assim que um prontuário eletrônico verifica regras clínicas sobre toda a população internada.
Exemplo — triagem no pronto-socorro:
Exemplo — investigação de pneumonia:
O MYCIN foi o primeiro sistema especialista médico de sucesso (infecções bacterianas). Em testes cegos, igualou o desempenho de especialistas humanos em cerca de 65% dos casos — nos anos 1970.
Importante
A linguagem médica é inerentemente vaga e gradual. A lógica clássica força uma precisão artificial que os dados reais muitas vezes não têm.
Exercício: classifique o risco de desidratação em pacientes pediátricos pelos critérios da OMS (turgor cutâneo reduzido, olhos fundos, mucosas secas): grave se os 3 sinais, leve se 1 ou 2, sem desidratação se nenhum.
classificar_desidratacao <- function(turgor, olhos, mucosas) {
n_sinais <- as.integer(turgor) + as.integer(olhos) + as.integer(mucosas)
ifelse(n_sinais == 3, "GRAVE",
ifelse(n_sinais >= 1, "Leve", "Sem desidratação"))
}
dados <- data.frame(
turgor = c(TRUE, TRUE, FALSE, FALSE),
olhos = c(TRUE, TRUE, FALSE, TRUE),
mucosas = c(TRUE, FALSE, FALSE, FALSE)
)
dados$classificacao <- classificar_desidratacao(dados$turgor, dados$olhos, dados$mucosas)
print(dados)#> turgor olhos mucosas classificacao
#> 1 TRUE TRUE TRUE GRAVE
#> 2 TRUE TRUE FALSE Leve
#> 3 FALSE FALSE FALSE Sem desidratação
#> 4 FALSE TRUE FALSE Leve
Discussão: este sistema trata os três sinais como igualmente importantes. Isso é clinicamente correto?
| Marcelo | Juliana | Conclusão |
|---|---|---|
| Errado | Certa | Juliana está certa |
| Certo | Certa | Juliana está certa |
| Certo | Errada | Juliana está certa |
| Errado | Errada | Marcelo está errado |
“Qualquer semelhança com a realidade é mera coincidência.”
No Turno 2: as duas ferramentas que resolvem o que ficou em aberto — a lógica fuzzy (para a imprecisão) e as redes bayesianas (para a incerteza) — e o fechamento com Aprendizagem de Máquina.
Importante
Um paciente com PAS = 139 mmHg está “normal”. Com 140 mmHg está “hipertenso”. 1 mmHg mudou o diagnóstico — mas mudou o risco clínico?
Conjunto crisp (clássico)
Pertence ou não pertence: 0 ou 1
“Febre” se temperatura > 38°C:
| Temp (°C) | Pertence? |
|---|---|
| 37,9 | 0 (não) |
| 38,0 | 1 (sim) |
| 39,5 | 1 (sim) |
| 41,0 | 1 (sim) |
Salto abrupto em 38°C — irreal.
Conjunto fuzzy
Pertence em algum grau: qualquer valor de 0 a 1
“Febre alta”:
| Temp (°C) | Grau \(\mu\) |
|---|---|
| 37,5 | 0,00 |
| 38,5 | 0,33 |
| 39,5 | 0,83 |
| 40,5 | 1,00 |
| 41,0 | 1,00 |
Transição suave — realista. ✓
Um conjunto fuzzy \(A\) atribui a cada elemento \(x\) um número entre 0 e 1:
\[\mu_A(x) \in [0, 1]\]
Lendo em português: \(\mu_A(x)\) é o quanto \(x\) pertence ao conjunto \(A\).
Importante
“\(\mu_{\text{febre alta}}(39{,}2) = 0{,}7\)” não significa 70% de chance de ter febre alta.
O mesmo paciente pode ter grau 0,4 de “febre moderada” e grau 0,7 de “febre alta” ao mesmo tempo.
library(ggplot2)
x <- seq(35, 42, by = 0.05)
tri <- pmax(0, pmin((x - 37.5)/1, (39.5 - x)/1)) # triangular
trap <- pmax(0, pmin((x - 38.5)/1, 1, (42 - x)/0.5)) # trapezoidal
gauss <- exp(-0.5 * ((x - 36.8)/0.4)^2) # gaussiana
df <- data.frame(
x = rep(x, 3), mu = c(tri, trap, gauss),
tipo = rep(c("Triangular — Febre Moderada",
"Trapezoidal — Febre Alta",
"Gaussiana — Temperatura Normal"), each = length(x))
)
ggplot(df, aes(x = x, y = mu, color = tipo)) +
geom_line(linewidth = 1.3) +
scale_color_manual(values = c("#7ecff7", "#f07050", "#a8f77e")) +
labs(title = "Funções de pertinência para temperatura corporal",
x = "Temperatura (°C)", y = "Grau de pertinência μ(x)", color = "") +
theme_minimal(base_size = 13) + theme(legend.position = "bottom")Variável: Temperatura → Valores: “Normal”, “Subfebril”, “Febre Moderada”, “Febre Alta”
Variável: Dor → Valores: “Leve”, “Moderada”, “Intensa”, “Insuportável”
library(ggplot2)
dor <- seq(0, 10, by = 0.05)
mu_leve <- pmax(0, pmin(1, (3 - dor)/2))
mu_mod <- pmax(0, pmin((dor - 1)/2, (6 - dor)/2, 1))
mu_intensa <- pmax(0, pmin((dor - 4)/2, (9 - dor)/2, 1))
mu_insup <- pmax(0, pmin((dor - 7)/2, 1))
df <- data.frame(
x = rep(dor, 4), mu = c(mu_leve, mu_mod, mu_intensa, mu_insup),
cat = rep(c("Leve","Moderada","Intensa","Insuportável"), each = length(dor))
)
df$cat <- factor(df$cat, levels = c("Leve","Moderada","Intensa","Insuportável"))
ggplot(df, aes(x = x, y = mu, color = cat)) +
geom_line(linewidth = 1.3) +
geom_vline(xintercept = 5, linetype = "dashed", color = "#aaa") +
scale_color_manual(values = c("#a8f77e","#7ecff7","#f7c87e","#f07050")) +
labs(title = "Escala Visual Analógica de dor (0–10)",
x = "Intensidade referida pelo paciente", y = "Grau de pertinência μ(x)",
color = "Categoria") +
theme_minimal(base_size = 13)| Operação | Fórmula | Equivalente clássico |
|---|---|---|
| E (interseção) | \(\min(\mu_A,\ \mu_B)\) | \(p \wedge q\) |
| OU (união) | \(\max(\mu_A,\ \mu_B)\) | \(p \vee q\) |
| NÃO (complemento) | \(1 - \mu_A\) | \(\neg p\) |
Exemplo: paciente com \(\mu_{\text{febre alta}} = 0{,}7\) e \(\mu_{\text{taquicardia}} = 0{,}5\)
Base de regras para triagem de dor:
| Regra | SE (dor) | E (duração) | ENTÃO (prioridade) |
|---|---|---|---|
| R1 | leve | curta | baixa |
| R2 | leve | longa | moderada |
| R3 | moderada | qualquer | moderada |
| R4 | intensa | qualquer | alta |
| R5 | insuportável | qualquer | emergência |
Paciente: temperatura = 39,5°C, SpO₂ = 91%. Qual a urgência?
temp <- 39.5; spo2 <- 91.0
# o `1` dentro do pmin garante que nenhum grau ultrapasse 1
mu_t_febre <- pmax(0, pmin((temp - 37.5)/1, (40.5 - temp)/1, 1))
mu_t_alta <- pmax(0, pmin((temp - 39.0)/0.8, 1))
mu_s_leve <- pmax(0, pmin((spo2 - 89)/2, (96 - spo2)/2, 1))
mu_s_grave <- pmax(0, pmin((92 - spo2)/2, 1))
cat(sprintf("μ(febre)=%.2f μ(febre alta)=%.2f\n", mu_t_febre, mu_t_alta))
cat(sprintf("μ(hipox. leve)=%.2f μ(hipox. grave)=%.2f\n", mu_s_leve, mu_s_grave))#> μ(febre)=1.00 μ(febre alta)=0.62
#> μ(hipox. leve)=1.00 μ(hipox. grave)=0.50
# 2. REGRAS — o "E" é o mínimo
R2 <- min(mu_t_febre, mu_s_leve) # moderada
R3 <- min(mu_t_alta, mu_s_leve) # alta
R4 <- min(mu_t_febre, mu_s_grave) # crítica
# 3-4. AGREGAÇÃO E DEFUZZIFICAÇÃO — média ponderada dos centros
centros <- c(moderada = 4.0, alta = 7.0, critica = 9.5)
escore <- sum(centros * c(R2, R3, R4)) / sum(c(R2, R3, R4))
cat(sprintf("Ativação: R2=%.3f R3=%.3f R4=%.3f\n", R2, R3, R4))
cat(sprintf("Escore: %.2f / 10 -> LARANJA (urgente)\n", escore))#> Ativação: R2=1.000 R3=0.625 R4=0.500
#> Escore: 6.18 / 10 -> LARANJA (urgente)
Três regras disparam ao mesmo tempo, com forças diferentes (1,00 · 0,625 · 0,50). É esse “várias ao mesmo tempo” que um protocolo de limiares não faz.
library(ggplot2)
temp_grid <- seq(36.5, 41, by = 0.2)
spo2_grid <- seq(88, 100, by = 0.5)
grade <- expand.grid(temp = temp_grid, spo2 = spo2_grid)
calcular_urgencia <- function(t, s) {
mu_tf <- pmax(0, pmin((t - 37.5)/1, 1)); mu_ta <- pmax(0, pmin((t - 39.0)/0.8, 1))
mu_sn <- pmax(0, pmin((s - 94)/2, 1)); mu_sl <- pmax(0, pmin((s - 89)/2, (96 - s)/2, 1))
mu_sg <- pmax(0, pmin((92 - s)/2, 1))
ativacao <- c(min(1 - mu_tf, mu_sn), # baixa
min(mu_tf, mu_sl), # moderada
min(mu_ta, mu_sl), # alta
min(mu_tf, mu_sg), # crítica
min(mu_ta, mu_sg)) # emergência
centros <- c(1.5, 4.0, 7.0, 8.5, 9.5)
if (sum(ativacao) == 0) return(1)
sum(centros * ativacao) / sum(ativacao) # mesma média ponderada de antes
}
grade$urgencia <- mapply(calcular_urgencia, grade$temp, grade$spo2)
ggplot(grade, aes(x = temp, y = spo2, fill = urgencia)) +
geom_tile() +
scale_fill_gradient2(low = "#a8f77e", mid = "#f7c87e", high = "#f07050",
midpoint = 5, limits = c(0, 10), name = "Urgência") +
labs(title = "Superfície de urgência — sistema de triagem fuzzy",
subtitle = "Verde: baixa urgência | Vermelho: emergência",
x = "Temperatura (°C)", y = "SpO₂ (%)") +
theme_minimal(base_size = 13)Um hospital usa dois sistemas para classificar risco de readmissão em insuficiência cardíaca:
Importante
Paciente: 68 anos, FE = 36%, 2 internações no último ano.
Como cada sistema classifica este paciente?
idade <- 68; fe <- 36; intern <- 2
risco_a <- (idade > 70) & (fe < 35) & (intern > 2)
cat(sprintf("Sistema A (clássico): %s\n\n", ifelse(risco_a, "RISCO ALTO", "risco baixo")))
mu_idoso <- pmax(0, pmin((idade - 60)/15, 1))
mu_fe <- pmax(0, pmin((40 - fe)/10, 1))
mu_int <- pmax(0, pmin((intern - 1)/3, 1))
cat("Sistema B (fuzzy):\n")
cat(sprintf(" μ(idoso): %.2f\n", mu_idoso))
cat(sprintf(" μ(FE muito reduzida): %.2f\n", mu_fe))
cat(sprintf(" μ(múltiplas intern.): %.2f\n", mu_int))
cat(sprintf(" Grau de risco (mín): %.2f\n", min(mu_idoso, mu_fe, mu_int)))#> Sistema A (clássico): risco baixo
#>
#> Sistema B (fuzzy):
#> μ(idoso): 0.53
#> μ(FE muito reduzida): 0.40
#> μ(múltiplas intern.): 0.33
#> Grau de risco (mín): 0.33
Importante
A: risco baixo — o paciente sai sem nenhum sinalizador. B: pertinência positiva nos três critérios (0,53 · 0,40 · 0,33) — grau de risco 0,33, pequeno mas não zero.
A lógica fuzzy já está em equipamentos que vocês usam — normalmente sem esse nome no manual.
Importante
Com 4 variáveis binárias, a tabela completa tem \(2^4 = 16\) combinações. Com 20 variáveis, mais de 1 milhão. Nenhum hospital tem dados para preencher isso.
1. Um desenho (grafo)
2. Tabelas de probabilidade
Rede bayesiana = desenho + tabelas. O desenho vem do conhecimento clínico (ou é aprendido dos dados); as tabelas vêm dos dados (ou da opinião do especialista).
Fator de Risco (sem pais)
| FR | P |
|---|---|
| sim | 0,30 |
| não | 0,70 |
Doença (pai: FR)
| FR = sim | FR = não | |
|---|---|---|
| D = sim | 0,35 | 0,05 |
| D = não | 0,65 | 0,95 |
ECG (pai: D)
| D = sim | D = não | |
|---|---|---|
| ECG + | 0,75 | 0,10 |
| ECG − | 0,25 | 0,90 |
Troponina (pai: D)
| D = sim | D = não | |
|---|---|---|
| Tn + | 0,85 | 0,06 |
| Tn − | 0,15 | 0,94 |
As tabelas de ECG e Troponina são exatamente sensibilidade e especificidade — as mesmas quantidades da manhã, agora dentro da rede.
\[P(FR, D, ECG, Tn) = P(FR)\cdot P(D \mid FR)\cdot P(ECG \mid D)\cdot P(Tn \mid D)\]
Lendo em português: para saber a chance de qualquer combinação, basta multiplicar, para cada variável, a chance dela dado os seus pais.
Pergunta: paciente chega com dor torácica. Como a probabilidade de SCA muda conforme os exames chegam?
# As tabelas da rede, em código
p_FR <- 0.30
p_D_dado <- c(sim = 0.35, nao = 0.05) # P(D=sim | FR)
p_ECG <- c(sim = 0.75, nao = 0.10) # P(ECG=+ | D)
p_Tn <- c(sim = 0.85, nao = 0.06) # P(Tn=+ | D)
# Probabilidade da doença ANTES de qualquer exame
p_D <- p_FR * p_D_dado["sim"] + (1 - p_FR) * p_D_dado["nao"]
cat(sprintf("P(SCA) antes dos exames: %.1f%%\n", p_D * 100))#> P(SCA) antes dos exames: 14.0%
num1 <- p_D * p_ECG["sim"] # ECG +
p_D_ecg <- num1 / (num1 + (1 - p_D) * p_ECG["nao"])
num2 <- p_D * p_ECG["sim"] * p_Tn["sim"] # ECG + e Tn +
p_D_ecg_tn <- num2 / (num2 + (1 - p_D) * p_ECG["nao"] * p_Tn["nao"])
cat(sprintf("Antes dos exames: %.1f%%\n", p_D * 100))
cat(sprintf("Com ECG alterado: %.1f%%\n", p_D_ecg * 100))
cat(sprintf("Com ECG + troponina: %.1f%%\n", p_D_ecg_tn * 100))#> Antes dos exames: 14.0%
#> Com ECG alterado: 55.0%
#> Com ECG + troponina: 94.5%
Importante
14% → 55% → 94% — o raciocínio clínico de vocês, com números e auditável.
Vocês já viram este nome em Aprendizagem de Máquina — é o mesmo objeto, de outro ângulo.
Classificadores mais flexíveis
Todos relaxam progressivamente a suposição “ingênua”, ao custo de mais parâmetros.
Aprender o grafo dos dados
Ambos usam listas de permissão e bloqueio para incorporar conhecimento clínico.
Estes nomes ficam como mapa para leitura futura — o essencial é saber que existem duas escolhas: desenhar a rede com o especialista ou aprendê-la dos dados. E que dá para fazer as duas coisas juntas.
Importante
Encontrar uma seta entre duas variáveis não é provar uma relação de causa e efeito. Este é o erro mais grave e mais comum no uso de redes bayesianas em pesquisa clínica.
É essa combinação — interpretabilidade, tratamento explícito da incerteza e tolerância a dados incompletos — que mantém as redes bayesianas relevantes mais de trinta anos depois de propostas por Judea Pearl.
Exercício: um posto de saúde tem dados de 300 pacientes triados para suspeita de dengue, com quatro variáveis: Idade, Fator de Risco, Resultado do Teste Rápido e Confirmação Laboratorial.
| Abordagem | Quem escreve a regra | Que incerteza trata | Interpretabilidade |
|---|---|---|---|
| Lógica clássica | O especialista | Nenhuma (tudo V/F) | Total |
| Lógica fuzzy | O especialista | Imprecisão da linguagem | Total |
| Rede bayesiana (grafo desenhado) | O especialista | Incerteza probabilística | Alta |
| Rede bayesiana (grafo aprendido) | Os dados | Incerteza probabilística | Alta |
| Aprendizagem de Máquina | Os dados | Incerteza + padrões complexos | Variável |
Importante
O eixo central é: o conhecimento vem da cabeça do especialista ou vem do banco de dados? Tudo o mais é consequência.
1. Naïve Bayes Apareceu em ML como classificador. Hoje: uma rede bayesiana de estrutura fixa. Mesmo objeto, dois olhares.
2. Árvores de decisão Em ML, aprendidas dos dados. Aqui: a mesma estrutura de regras SE-ENTÃO encadeadas dos sistemas especialistas — só que ninguém as escreveu à mão.
3. Probabilidade predita Todo classificador devolve uma probabilidade. Escolher o ponto de corte para agir não é questão estatística — é a utilidade esperada do Bloco 1.
Um corte que minimiza erro total pode ser péssimo se falso negativo custa vidas e falso positivo custa um exame a mais.
Importante
Um modelo treinado num hospital terciário (alta prevalência) e aplicado na atenção primária (baixa prevalência) terá VPP muito pior, mesmo com sensibilidade e especificidade idênticas. Isso não é falha do algoritmo — é o efeito da prevalência que calculamos hoje de manhã.
Viés algorítmico: um modelo aprende os padrões dos dados que recebeu — inclusive as desigualdades de acesso já embutidas neles. É o alerta que a Profª. Kátya/Juliana fez sobre os SIS, agora do lado do modelo.
Para entregar (máximo duas páginas): escolha uma decisão recorrente da sua prática profissional e analise-a:
Decisão e Sistemas de Apoio à Decisão
Lógica clássica e sistemas especialistas
Lógica fuzzy
Redes bayesianas
Obrigado!
Métodos de Tomada de Decisão · PPGMDS · UFPB
Turma MINTER/DINTER
Prof. Marcelo R.P. Ferreira/Prof. Hemílio F.C. Coelho · DE-UFPB
Métodos de Tomada de Decisão - PPGMDS - UFPB - MINTER/DINTER