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

Cómo crear un detector de falsos positivos en Machine Learning

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

Este tutorial muestra cómo crear un detector de falsos positivos en Machine Learning para reducir alarmas excesivas en un sistema de clasificación. Saber identificar falsos positivos es útil para mejorar la eficiencia operacional y priorizar alertas reales.

Requisitos previos

  • Python 3.8+ y pip instalados
  • Bibliotecas: pandas, scikit-learn, numpy, matplotlib (instalación mostrada)
  • Conocimientos básicos de clasificación y evaluación (precision, recall, ROC)

Paso 1: Entender el problema y preparar los datos

Un detector de falsos positivos aprende a predecir cuándo una predicción de clase positiva del modelo principal es probablemente incorrecta. Necesitamos un conjunto donde cada ejemplo tenga: features originales, la predicción del modelo primario (pred_label) y la etiqueta real (true_label). Vamos a crear un ejemplo sintético para seguir el flujo.

# 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

Paso 2: Construir el dataset del detector de falsos positivos

El detector es un segundo modelo que recibe como input: features originales, probabilidades o decisiones del modelo primario y pretende predecir si una predicción positiva es un falso positivo (pred_label=1 & true_label=0). Filtramos para casos en los que el primario predijo 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()

Paso 3: Entrenar un modelo detector simple

Usamos un clasificador ligero (ej.: LogisticRegression) para predecir falsos positivos. Esto permite estimar la probabilidad de ser falso positivo y aplicar un umbral para filtrar alarmas.

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))

Paso 4: Integrar el detector en la pipeline de inferencia

En producción, cuando el modelo primario hace una predicción positiva, llamamos al detector. Si el detector indica alto riesgo de falso positivo, marcamos la alerta como baja prioridad o la suprimimos. Ejemplo de aplicación en batch sobre X_rest.

# aplicar detector a todo el conjunto donde 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 el resultado

Confirmar que el detector reduce falsos positivos sin eliminar muchos verdaderos positivos. Medimos métricas antes y después: tasa de falsos positivos (FPR) y recall del modelo primario sobre positivos reales.

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)

Conclusión

Un detector de falsos positivos es un modelo complementario que reduce alertas innecesarias. Próximos pasos: calibrar thresholds, usar features del contexto (tiempo, usuario), probar modelos más robustos (XGBoost) y validar el impacto en producción. Consejo: empiece por medir el coste de cada falso positivo antes de definir el threshold.