Encuentra la factura rara
Dos reglas que puedes explicar a tu gestoría antes de tocar un modelo: z-score e IQR. Verás por qué una sola errata esconde a otra.
AMOUNTS son los importes de 36 facturas de material de oficina (datos sintéticos, en EUR). Hay dos raras: una errata de 4250 por 425 y un pedido duplicado de 980. Escribe cinco funciones pequeñas:
zScores(xs): (x - media) / desviación, con la desviación dividida entre n. Si todos los valores son iguales, devuelve ceros.
quantile(sorted, p): recibe una lista ordenada. Calcula la posición (n - 1) * p e interpola entre los dos vecinos (es el método por defecto de NumPy).
iqrFences(xs): devuelve { q1, q3, iqr, low, high }, con low = q1 - 1.5 * iqr y high = q3 + 1.5 * iqr.
flagZ(xs, limit) y flagIQR(xs): los índices de las facturas marcadas, en orden. La vista previa pinta lo que marca cada regla y mueve el límite de z.
Retos 0/4
- z-score con la desviación entre n, y ceros si no hay dispersión
- Cuartiles con interpolación y vallas a 1,5 IQR
- Con límite 3, el z-score solo ve la errata de 4250
- El IQR marca la errata y el pedido duplicado
function zScores(xs) {
// (x - media) / desviación, dividiendo entre n; todo ceros si todos los valores son iguales
return xs.map(() => 0);
}
function quantile(sorted, p) {
// posición (n - 1) * p y luego interpola entre los dos vecinos
return sorted[0];
}
function iqrFences(xs) {
// vallas: q1, q3, iqr = q3 - q1, low = q1 - 1,5 * iqr, high = q3 + 1,5 * iqr
return { q1: 0, q3: 0, iqr: 0, low: 0, high: 0 };
}
function flagZ(xs, limit) {
// índices cuyo |z| supera limit
return [];
}
function flagIQR(xs) {
// índices por debajo de low o por encima de high
return [];
}
console.log('z:', flagZ(AMOUNTS, 3), 'IQR:', flagIQR(AMOUNTS));La idea
Antes de entrenar nada, prueba una regla que puedas explicar en una frase. «Esta factura está a más de tres desviaciones de la media» o «está por encima de la valla del IQR» se entienden en una revisión con tu gestoría, y eso vale más que un modelo que nadie sabe justificar.
El z-score tiene un fallo conocido: la media y la desviación se calculan con todos los datos, también con los raros. La errata de 4250 infla tanto la desviación que el pedido duplicado de 980 se queda con un z por debajo de 1 y pasa desapercibido. A eso se le llama enmascaramiento.
El IQR usa cuartiles, y a los cuartiles un valor extremo les mueve poco. Por eso marca las dos facturas. La idea de aislamiento va un paso más allá: corta el rango al azar hasta que la factura se queda sola. Una factura rara se aísla en pocos cortes. Es la base del Isolation Forest, y la vista previa la calcula con 100 árboles.
Ninguna regla decide por ti. Marcan qué revisar primero, y una persona confirma.
Hazlo en tu máquina
Con Python y pandas, sobre el CSV de este ejercicio (CC BY 4.0):
curl -O https://vorluxai.com/data/labs/invoices-office-supplies.csv
python3 -c "
import pandas as pd
df = pd.read_csv('invoices-office-supplies.csv')
q1, q3 = df.amount.quantile([0.25, 0.75])
high = q3 + 1.5 * (q3 - q1)
print(df[df.amount > high])
" Para profundizar: la referencia de scikit-learn (en inglés) →
¿Esto en producción, con tus datos? Hablemos 15 minutos →