Edite as amostras (classe real e confiança) ou escolha um cenário pré-definido para visualizar a matriz de confusão, a curva P-S e o valor de mAP em tempo real.
| Limiar | Prec. | P.mono | Sensib. |
|---|
Nesta atividade, você avaliará um classificador binário (ex.: detecção de desmatamento em imagens de satélite, ver dgi.inpe.br) através da curva Precisão‑Sensibilidade e da métrica mAP (Mean Average Precision). O mAP é padrão em competições como COCO (Common Objects in Context) e PASCAL VOC (Visual Object Classes) e dos modelos YOLO (You Only Look Once).
Na EP01_02 você viu que a escolha do limiar altera significativamente a Precisão e a Sensibilidade. O mAP (Mean Average Precision) resolve isso: avalia o modelo em vários limiares (cada limiar deve gerar uma matriz de confusão diferente) e resume o desempenho pela área sob a curva Precisão‑Sensibilidade (P‑S).
Enquanto o F1‑Score olha para um único ponto de equilíbrio, o mAP considera a curva inteira. Quanto mais próximo de 1,0, melhor o detector em todos os limiares e classes (ex.: moedas de 25, 50 e 1 real).
| Métrica | O que resume | Limitação |
|---|---|---|
| F1‑Score | Equilíbrio P × S num único limiar | Depende do limiar escolhido |
| AP | Área sob a curva P‑S de uma classe | Válida apenas para uma classe |
| mAP | Média das APs sobre todas as classes | Mais complexo de implementar |
Referências: Roboflow — mAP · Vídeo explicativo
Limiares fixos (use sempre esta lista):
limiares = [0.00, 0.09, 0.21, 0.31, 0.39, 0.52, 0.60, 0.71, 0.81, 0.89, 1.00]Para cada limiar (t), classifique as amostras: predito = 1 se confiança ≥ t, senão 0.
Calcule VP, FP, FN, VN e obtenha Precisão((t)) e Sensibilidade((t)).
Monte a curva P‑S: pares (Sensibilidade((t)), Precisão((t))), ordenados por Sensibilidade crescente.
Monotonize a Precisão:
\[P_{\text{mono}}[i] = \max_{j \ge i} P[j]\]
Calcule a AP (área sob a curva monotônica) usando a regra do trapézio (aproximação mais precisa que a simples soma de Riemann):
\[AP = \sum_{i=1}^{m-1} \frac{P_{\text{mono}}[i-1] + P_{\text{mono}}[i]}{2} \cdot (S[i] - S[i-1])\]
mAP = média das APs de todas as classes. Neste EP há apenas 1 classe, portanto mAP = AP.
📐 Diferença resumida:
A soma de Riemann aproxima a área por retângulos, podendo subestimar ou superestimar. A regra do trapézio usa trapézios, reduzindo o erro ao considerar a média entre os valores nos extremos do intervalo, sendo geralmente mais precisa para funções suaves por partes, como a curva Precisão‑Sensibilidade.
Leia um inteiro n (quantidade de amostras). Em seguida leia n linhas, cada uma com: verdade (0 ou 1) e confiança (float 0.0–1.0).
Calcule e imprima, para o limiar 0.85 (índice 9 da lista):
Em seguida, para todos os limiares, imprima:
,| Entrada | Saída Esperada |
|---|---|
| 7 0 0.94 1 0.80 1 0.69 0 0.67 1 0.30 1 0.15 1 0.15 |
# MÉTRICAS PARA O LIMIAR 0.85 # Matriz de Confusão: VP = 0, FN = 5 FP = 1, VN = 1 Métricas de Avaliação: Acurácia: 0.14 Precisão: 0.00 Sensibilidade: 0.00 F1-Score: 0.00 # MÉTRICAS PARA TODOS OS LIMIARES # Precisões: 0.00, 0.00, 0.00, 0.50, 0.50, 0.50, 0.50, 0.50, 0.60, 0.71, 0.71 Precisões mon.: 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71, 0.71 Sensibilidades: 0.00, 0.00, 0.00, 0.20, 0.40, 0.40, 0.40, 0.40, 0.60, 1.00, 1.00 mAP: 0.71 |
def calcular_AP(verdades, confiancas, limiares):
m = len(limiares)
precisoes = [0.0] * m
sensibilidades = [0.0] * m
for i in range(m):
p, s = calcular_metricas(verdades, confiancas, limiares[i])
precisoes[m-1-i] = p
sensibilidades[m-1-i] = s
prec_mono = precisoes.copy()
for i in range(m-2, -1, -1):
if prec_mono[i] < prec_mono[i+1]:
prec_mono[i] = prec_mono[i+1]
AP = 0.0
for i in range(1, m):
# Regra do trapézio: média das alturas vezes a base
area_trapezio = (prec_mono[i-1] + prec_mono[i]) / 2.0
AP += area_trapezio * (sensibilidades[i] - sensibilidades[i-1])
return precisoes, prec_mono, sensibilidades, APEdite as amostras (classe real e confiança) ou escolha um cenário pré-definido para visualizar a matriz de confusão, a curva P-S e o valor de mAP em tempo real.
| Limiar | Prec. | P.mono | Sensib. |
|---|
%%writefile EP01_03.py
# sua soluçãoWriting EP01_03.py
TestSuite("EP01_03.py").run()✔️ EP01_03.cases já existe em casos/
📋 5 caso(s) carregado(s) de casos/EP01_03.cases
🔍 Testando Python: EP01_03.py
⚠️ EP01_03.py: Arquivo sem conteúdo (menos de 3 linhas). Testes ignorados.