(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como criar um detector de falsos positivos em Machine Learning

João Barros 31 de October de 2026 5 min de leitura

Este tutorial mostra como criar um detector de falsos positivos em Machine Learning para reduzir alarmes excessivos num sistema de classificação. Saber identificar falsos positivos é útil para melhorar a eficiência operacional e priorizar alertas reais.

Pré-requisitos

  • Python 3.8+ e pip instalados
  • Bibliotecas: pandas, scikit-learn, numpy, matplotlib (instalação mostrada)
  • Conhecimentos básicos de classificação e avaliação (precision, recall, ROC)

Passo 1: Entender o problema e preparar os dados

Um detector de falsos positivos aprende a prever quando uma previsão de classe positiva do modelo principal é provavelmente incorreta. Precisamos de um conjunto onde cada exemplo tem: features originais, a previsão do modelo primário (pred_label) e o rótulo real (true_label). Vamos criar um exemplo sintético para seguir o fluxo.

# instalar dependências (executar no terminal, se necessário)  # pip install pandas scikit-learn numpy matplotlib    import numpy as np  import pandas as pd  from sklearn.model_selection import train_test_split    # exemplo sintético  rng = np.random.RandomState(42)  n = 2000  X = pd.DataFrame({'f1': rng.normal(size=n), 'f2': rng.uniform(size=n)})  # rótulo verdadeiro: evento raro dependente de f1  y = (X['f1'] + 0.5 * X['f2'] + rng.normal(scale=0.5, size=n) > 0.5).astype(int)    # simulamos um modelo primário com algumas previsões (com erros)  from sklearn.ensemble import RandomForestClassifier  m_primary = RandomForestClassifier(n_estimators=50, random_state=1)  X_train, X_rest, y_train, y_rest = train_test_split(X, y, test_size=0.5, random_state=1)  m_primary.fit(X_train, y_train)  pred_prob = m_primary.predict_proba(X_rest)[:, 1]  pred_label = (pred_prob > 0.4).astype(int)  # threshold do modelo primário

Passo 2: Construir o dataset do detector de falsos positivos

O detector é um segundo modelo que recebe como input: features originais, probabilidades ou decisões do modelo primário e pretende prever se uma previsão positiva é um falso positivo (pred_label=1 & true_label=0). Filtramos para casos em que o primário previu positivo.

# montar dataset para o detector  X_det = X_rest.copy().reset_index(drop=True)  y_det = ((pred_label == 1) & (y_rest.reset_index(drop=True) == 0)).astype(int)  # 1 = falso positivo  X_det['pred_prob'] = pred_prob  X_det['pred_label'] = pred_label    # consideramos só os exemplos em que o primário previu positivo (casos a decidir)  mask = X_det['pred_label'] == 1  X_det_pos = X_det[mask].reset_index(drop=True)  y_det_pos = y_det[mask].reset_index(drop=True)    X_det_pos.shape, y_det_pos.value_counts().to_dict()

Passo 3: Treinar um modelo detector simples

Usamos um classificador leve (ex.: LogisticRegression) para prever falsos positivos. Isto permite estimar a probabilidade de ser falso positivo e aplicar um threshold para filtrar alarmes.

from sklearn.linear_model import LogisticRegression  from sklearn.metrics import precision_score, recall_score, roc_auc_score    X_train_d, X_test_d, y_train_d, y_test_d = train_test_split(X_det_pos, y_det_pos, test_size=0.3, random_state=2)    features = ['f1', 'f2', 'pred_prob']  detector = LogisticRegression(max_iter=1000)  detector.fit(X_train_d[features], y_train_d)    y_pred_prob = detector.predict_proba(X_test_d[features])[:, 1]  y_pred = (y_pred_prob > 0.5).astype(int)    print('AUC detector:', round(roc_auc_score(y_test_d, y_pred_prob), 3))  print('Precision:', round(precision_score(y_test_d, y_pred), 3))  print('Recall:', round(recall_score(y_test_d, y_pred), 3))

Passo 4: Integrar o detector na pipeline de inferência

Em produção, quando o modelo primário faz uma previsão positiva, chamamos o detector. Se o detector indicar alto risco de falso positivo, marcamos o alerta como baixa prioridade ou suprimimos. Exemplo de aplicação em batch sobre X_rest.

# aplicar detector a todo o conjunto onde primário previu positivo  all_df = X_rest.reset_index(drop=True).copy()  all_df['pred_prob'] = pred_prob  all_df['pred_label'] = pred_label    mask_pos = all_df['pred_label'] == 1  probs_fp = np.zeros(len(all_df))  probs_fp[mask_pos] = detector.predict_proba(all_df[mask_pos][features])[:, 1]    # decidir suprimir se probabilidade de falso positivo > 0.6  suppress = probs_fp > 0.6  all_df['suppress_alert'] = suppress.astype(int)    all_df[['f1','f2','pred_prob','pred_label','suppress_alert']].head()

Verificar o resultado

Confirmar que o detector reduz falsos positivos sem eliminar muitos verdadeiros positivos. Medimos métricas antes e depois: taxa de falsos positivos (FPR) e recall do modelo primário sobre positivos reais.

from sklearn.metrics import confusion_matrix    # métricas sem detector (considerando threshold primário)  tp = ((all_df['pred_label']==1) & (y_rest.reset_index(drop=True)==1)).sum()  fp = ((all_df['pred_label']==1) & (y_rest.reset_index(drop=True)==0)).sum()  fn = ((all_df['pred_label']==0) & (y_rest.reset_index(drop=True)==1)).sum()  print('Antes - TP, FP, FN:', tp, fp, fn)    # aplicar supressão  pred_after = all_df['pred_label'].copy()  pred_after[all_df['suppress_alert']==1] = 0  # suprimido vira negativo    tp_a = ((pred_after==1) & (y_rest.reset_index(drop=True)==1)).sum()  fp_a = ((pred_after==1) & (y_rest.reset_index(drop=True)==0)).sum()  fn_a = ((pred_after==0) & (y_rest.reset_index(drop=True)==1)).sum()  print('Depois - TP, FP, FN:', tp_a, fp_a, fn_a)    print('Redução de FP:', fp - fp_a)

Conclusão

Um detector de falsos positivos é um modelo complementar que reduz alarmes desnecessários. Próximos passos: calibrar thresholds, usar features do contexto (tempo, utilizador), experimentar modelos mais robustos (XGBoost) e validar o impacto em produção. Dica: comece por medir o custo de cada falso positivo antes de definir o threshold.