Skip to content

Guías

Clasificadores y regresores

Un modelo predictivo se evalúa como cualquier otro sistema: una función invocable devuelve una predicción para cada caso, y los evaluadores la leen. Lo que cambia son los denominadores. Exactitud (accuracy), exhaustividad (recall) y precisión son tres tasas sobre tres conjuntos distintos de filas, y un modelo puede verse bien en una mientras falla en la pregunta que se plantea el negocio.

examples/churn_model/ es el proyecto que ejecuta esta página: doscientas cuentas, un modelo determinista de abandono (churn) y ninguna credencial de proveedor.

La predicción

El sistema devuelve una etiqueta y, si el modelo la tiene, la puntuación que la respalda:

from oloproof import system


@system(name="churn-model", version="slice-f-example")
def run(account):
    score = churn_score(account)
    return {"label": score >= 0.5, "score": round(score, 4)}

Un caso declara el valor real bajo expected:

{"expected": {"label": false}, "id": "account_000", "input": {"recent_upgrade": true, "support_contacts": 0, "tenure_months": 0}, "metadata": {"plan": "enterprise"}}

El bloque `predictive:`

Dónde se encuentran la predicción, su puntuación y el valor real se declara una sola vez, para todo el proyecto:

predictive:
  label_field: label
  score_field: score
  expected_field: label
  positive: true
  calibration_bins: 10
  thresholds: [0.3, 0.4, 0.5, 0.6, 0.7]
CampoValor por defectoSignificado
label_fieldlabelel campo de salida que contiene la etiqueta predicha
score_fieldscoreel campo de salida que contiene la puntuación que la respalda
expected_fieldlabelel campo bajo expected que contiene el valor real
positivetruequé valor de etiqueta cuenta como positivo; refund, 1 o true
calibration_bins10cuántas bandas de puntuación usa la tabla de calibración
thresholdsningunoumbrales de corte a recorrer; cada uno es evidencia, nunca una recomendación
averageningunomacro o micro, para un agregado sobre varias clases

Todo evaluador predictivo que no declare por sí mismo field, expected_field o positive los toma de este bloque, de modo que una suite tiene una sola clase positiva. El bloque es también lo que produce los recuentos de confusión, la tabla de calibración y el barrido de umbrales; un proyecto sin él obtiene las métricas y nada más.

Una clase positiva que no coincide con la etiqueta de ningún caso se rechaza antes de ejecutar nada, porque el recall sobre ella sería una tasa sobre nada. El mismo proyecto con positive: churned:

Configuration error: evaluator 'recall' counts 'churned' as the positive class, and no case's 'label' is 'churned' (labels: False, True); declare `positive:` on the evaluator or in the `predictive:` block

Los evaluadores

evaluators:
  - {type: predictive_correct, criterion: accuracy}
  - {type: predictive_recall, criterion: recall}
  - {type: predictive_precision, criterion: precision}
  - {type: predictive_brier, criterion: brier}
  - {type: predictive_log_loss, criterion: log_loss, clip: 0.02}
  - {type: predictive_ranking, criterion: rank}
metrics:
  - {id: roc_auc, type: ranking, criterion: rank, statistic: roc_auc}
  - {id: pr_auc, type: ranking, criterion: rank, statistic: average_precision}
slices: [metadata.plan, "confidence:0.5"]
min_slice_support: 20

predictive_log_loss requiere clip, porque de lo contrario un solo error cometido con alta confianza es infinito. predictive_ranking es el criterio por el que una métrica de ranking ordena las filas, y necesita una entrada en metrics: que nombre el estadístico: ROC-AUC y la precisión promedio responden a preguntas distintas, y el motor no elegirá una por usted.

oloproof run
│ accuracy  │ 88.5%    │ [83.2%, 92.6%]  │ 177 / 200 observed · 0 missing · 0 excluded                                │
│ recall    │ 81.2%    │ [69.5%, 90.0%]  │ 52 / 64 observed · 0 missing · 136 excluded                                │
│ precision │ 82.5%    │ [70.9%, 91.0%]  │ 52 / 63 observed · 0 missing · 137 excluded                                │
│ brier     │ 0.120    │ [0.094, 0.154]  │ mean of 200 observed · 0 missing · 0 excluded                              │
│ log_loss  │ 0.389    │ [0.323, 0.499]  │ mean of 200 observed · 0 missing · 0 excluded                              │
│ roc_auc   │ 92.3%    │ [69.3%, 100.0%] │ roc_auc over 64 positive · 136 negative · 0 missing · 0 excluded           │
│ pr_auc    │ 86.5%    │                 │ average_precision over 64 positive · 136 negative · 0 missing · 0 excluded │

Lea la columna excluded. El recall se mide sobre las 64 cuentas que abandonaron, así que las otras 136 quedan excluidas de él; la precisión, sobre las 63 que el modelo marcó. El treinta y dos por ciento de estas cuentas abandona, así que un modelo que predice que nadie abandona tiene un 68% de exactitud y no detecta a nadie. Un umbral mínimo solo sobre la exactitud lo aprobaría, y por eso la política del ejemplo pone un mínimo a cada tasa.

pr_auc tiene una estimación y ningún intervalo. Con doscientas filas, su intervalo es realmente más débil que el de ROC-AUC, y el motor retiene una cota que no puede sostener en lugar de mostrarla. Una regla sobre ella se lee así:

pr: INSUFFICIENT_EVIDENCE (interval_unavailable)

Además de las métricas

Los recuentos de confusión son recuentos, no tasas:

│ actually positive │ 52                 │ 12                 │
│ actually negative │ 11                 │ 125                │

Una regla de publicación que nombre uno de ellos es un error de configuración, porque un recuento no es una métrica:

Configuration error: release rule 'fp' refers to unknown metric 'false_positives'

La tabla de calibración contrasta lo que el modelo afirmó con lo que ocurrió, por banda de puntuación:

│ 0.2-0.3 │ 26.7%   │ 0.0%     │ 34 rows │
│ 0.5-0.6 │ 53.4%   │ 81.0%    │ 21 rows │

Y el barrido de umbrales muestra lo que habría medido cada umbral de corte declarado:

│ 0.3     │ 57.4%     │ 96.9%  │ 62/108 predicted positive · 62/64 actual positive │
│ 0.5     │ 82.5%     │ 81.2%  │ 52/63 predicted positive · 52/64 actual positive  │
│ 0.7     │ 100.0%    │ 37.5%  │ 24/24 predicted positive · 24/64 actual positive  │

El barrido se titula Thresholds (exploratory; recommends nothing). Qué umbral es el correcto depende de lo que cueste un falso positivo frente a un falso negativo, y eso no es algo que el motor pueda saber.

Regresión

Un regresor se puntúa por el error absoluto, que necesita el rango en el que se encuentran sus objetivos:

evaluators:
  - type: predictive_absolute_error
    criterion: days_error
    field: days
    expected_field: days
    target_range: [0, 20]
rules:
  - id: error-budget
    metric: days_error
    max: 1.5
│ days_error │ 1.02     │ [0.78, 1.88] │ mean of 120 observed · 0 missing · 0 excluded │
error-budget: INSUFFICIENT_EVIDENCE (interval_overlaps_threshold)

target_range es obligatorio, no tiene valor por defecto. Un error absoluto es una media acotada, y su intervalo solo es válido dentro de un rango en el que se encuentren todos los valores. Un rango más amplio da un intervalo más amplio, así que declare el rango que los objetivos pueden tomar realmente. La regla no puede decidir: la estimación está dentro del presupuesto, y 120 pedidos todavía no bastan para mostrar que el error medio real también lo está.

Siguientes pasos