Pipeline de Test Offline¶
run_test_offline_pipeline.py evalúa modelos ya entrenados sobre archivos .parquet o .csv y genera reportes offline consolidados. Puede ejecutar, en una misma corrida:
- inferencia PFM,
- inferencia OBSERVER,
- detección física PPA / NPW,
- y fusión Bayesiana LDS por caso.
La idea es reproducir un escenario de inferencia offline, con ventanas deslizantes, extracción de features compatible con training, validación por caso y generación de artefactos de análisis.
Script¶
Overrides útiles por CLI:
--source-folder--file-glob--detection-model--size-model--location-model--leakflow-model--observer-detection-model--observer-size-model--observer-location-model--features-schema--feature-columns--output-report--window-size--step-size--min-leak-detection-rate--leak-window--plot-leak-series--target-file--parallel-workers
Qué hace el pipeline¶
En términos operativos, el script hace lo siguiente:
- carga la configuración desde
test_offline_pipeline, - resuelve modelos, schemas, mapeos y thresholds,
- lista archivos de entrada desde
source_folder, - aplica
input_column_renamessi los headers del CSV no coinciden con training, - construye ventanas deslizantes,
- extrae features con el mismo vectorizador usado en training,
- ejecuta inferencia con modelos PFM y/u OBSERVER,
- opcionalmente ejecuta PPA/NPW,
- opcionalmente combina señales con LDS Bayes,
- calcula métricas por archivo y resumen global,
- guarda JSON, Excel, plots y metadata de idempotencia.
Salidas generadas¶
En output_report_folder se guardan:
offline_report.xlsxsigenerate_excel_report=true,offline_results_summary.json,offline_results_cases.json,offline_run_metadata.json,- plots diagnósticos si
generate_diagnostic_plots=true, - plots de series de fuga si
plot_leak_series=true, - y
inference_params.ymlsisave_inference_params=true.
Además, cuando save_inference_params=true:
- se guarda
inference_params.ymljunto a los modelos de detección PFM y OBSERVER, - y si PPA/NPW participaron efectivamente en la corrida, se generan
ppa_config.ymlynpw_config.ymlenmodel_base_path.
Contenido de esos artefactos físicos:
on_delay_windowsthreshold
Configuración mínima actual en YAML¶
Después de la limpieza del YAML, la sección visible queda reducida a los parámetros que normalmente cambian entre corridas. Ejemplo:
test_offline_pipeline:
source_folder: "data/csv/supe/diesel"
output_report_folder: "reports/offline/supe/v8/1transmitter/diesel"
feature_columns:
- "PT 'POSITION:' 'POSITION_1378M' '(PA)' 'Pressure'"
- "GT 'POSITION:' 'POSITION_1378M' '(KG/S)' 'Total mass flow'"
- "PT 'POSITION:' 'POSITION_45M' '(PA)' 'Pressure'"
- "GT 'POSITION:' 'POSITION_45M' '(KG/S)' 'Total mass flow'"
- "PT 'POSITION:' 'POSITION_700M' '(PA)' 'Pressure'"
input_column_renames:
"PRESSURE_1378M": "PT 'POSITION:' 'POSITION_1378M' '(PA)' 'Pressure'"
"MASS_FLOW_1378M": "GT 'POSITION:' 'POSITION_1378M' '(KG/S)' 'Total mass flow'"
"PRESSURE_45M": "PT 'POSITION:' 'POSITION_45M' '(PA)' 'Pressure'"
"MASS_FLOW_45M": "GT 'POSITION:' 'POSITION_45M' '(KG/S)' 'Total mass flow'"
"PRESSURE_700M": "PT 'POSITION:' 'POSITION_700M' '(PA)' 'Pressure'"
model_base_path: "models/supe/v1/1transmitter/diesel"
pfm:
detection_model_path: "PFM/lgbm/model_lgbm.txt"
size_model_path: "PFM/lgbm_size/model_lgbm.txt"
location_model_path: "PFM/lgbm_location/model_lgbm.txt"
leakflow_model_path: "PFM/lgbm_leakflow/model_lgbm.txt"
on_delay_windows: 5
min_leak_detection_rate: 1.0
observer:
detection_model_path: "OBSERVER/lgbm/model_lgbm.txt"
size_model_path: "OBSERVER/lgbm_size/model_lgbm.txt"
location_model_path: "OBSERVER/lgbm_location/model_lgbm.txt"
on_delay_windows: 5
min_leak_detection_rate: 1.0
ppa:
inlet_pressure_column: "PT 'POSITION:' 'POSITION_45M' '(PA)' 'Pressure'"
outlet_pressure_column: "PT 'POSITION:' 'POSITION_1378M' '(PA)' 'Pressure'"
on_delay_windows: 5
min_leak_detection_rate: 1.0
window_size: 40
npw:
inlet_pressure_column: "PT 'POSITION:' 'POSITION_45M' '(PA)' 'Pressure'"
outlet_pressure_column: "PT 'POSITION:' 'POSITION_1378M' '(PA)' 'Pressure'"
on_delay_windows: 5
min_leak_detection_rate: 1.0
window_size: 40
lds_bayesian:
prior_leak_probability: 0.001
detection_threshold: null
step_size: 1
file_glob: "*.csv"
sample_fraction: 1.0
plot_leak_series: false
Parámetros requeridos¶
El script ahora valida explícitamente los siguientes parámetros como requeridos:
1. Entrada y salida principal¶
| Parámetro | Descripción |
|---|---|
source_folder |
Archivo o carpeta con casos .parquet / .csv a evaluar. |
output_report_folder |
Carpeta donde se escriben reportes, JSON, plots y metadata. |
model_base_path |
Ruta base para resolver modelos cuando las rutas configuradas son relativas. Requerido si no usas rutas absolutas. |
2. Columnas base para extracción de features¶
| Parámetro | Descripción |
|---|---|
feature_columns |
Lista de columnas base desde las que se generan las features. |
input_column_renames |
Mapping desde nombres reales del input hacia los nombres esperados por feature_columns. |
input_column_renames es requerido porque este pipeline está pensado para evaluar CSVs que pueden venir con headers cortos o históricos, mientras que los modelos fueron entrenados con nombres largos.
3. Secciones de algoritmos opcionales¶
El pipeline ya no obliga a definir todos los algoritmos. Cada sección es opcional:
pfmobserverppanpwlds_bayesian
Si una sección no existe, ese algoritmo no se ejecuta y sus resultados no se toman en cuenta.
Ejemplos válidos:
- solo
pfm.detection_model_path, pfm.detection_model_path+pfm.size_model_path,- solo
observer.detection_model_path, pfm+observer+ppa,ppaynpwsinobserver,lds_bayesianjunto a cualquier subconjunto de motores de detección.
Restricciones importantes:
- en
pfm, no se puede ejecutarsize,locationoleakflowsinpfm.detection_model_path; - en
observer, no se puede ejecutarsizeolocationsinobserver.detection_model_path; lds_bayesiansolo opera sobre los motores de detección que estén efectivamente configurados.
Diferencia entre feature_columns e input_column_renames¶
Aunque ambos parámetros se relacionan con las columnas del archivo de entrada, cumplen funciones distintas.
feature_columns define las columnas base canónicas que el pipeline necesita para construir las features. Es decir, representa el contrato semántico de entrada que espera el vectorizador. Estas son las señales "correctas" sobre las que luego se calculan derivadas, wavelets, correlaciones, diferencias de flujo, etc.
input_column_renames, en cambio, no define qué señales se usan, sino cómo traducir los nombres reales del archivo de entrada hacia los nombres esperados por feature_columns. Su objetivo es resolver diferencias de headers entre el archivo real y los nombres con los que se entrenaron los modelos.
Ejemplo típico:
feature_columnsespera:"PT 'POSITION:' 'POSITION_1378M' '(PA)' 'Pressure'"- pero el CSV trae:
PRESSURE_1378M
Entonces input_column_renames debe contener algo como:
Cuándo hace falta cada uno¶
feature_columns:
- es necesario tanto para
.parquetcomo para.csv; - no depende del formato;
- siempre define las señales base a partir de las cuales se construyen las features.
input_column_renames:
- normalmente se necesita sobre todo con
.csv; - se usa cuando los nombres reales del archivo no coinciden con los nombres canónicos de
feature_columns; - también puede ser útil con
.parquetsi ese.parquetviene con headers distintos a los esperados.
¿Son necesarios para archivos .parquet?¶
Para .parquet:
feature_columns: sí, sigue siendo necesario.input_column_renames: solo si las columnas del.parquetno coinciden con los nombres canónicos esperados porfeature_columns.
Si el .parquet ya trae exactamente los mismos nombres que feature_columns, el renombre no sería conceptualmente necesario.
¿Son necesarios para archivos .csv?¶
Para .csv:
feature_columns: sí, siempre.input_column_renames: en la práctica, muchas veces sí, porque los CSV suelen venir con nombres cortos, simplificados o históricos.
Matiz importante del estado actual del pipeline¶
Aunque conceptualmente input_column_renames podría ser opcional cuando los nombres ya coinciden, la implementación actual del pipeline lo valida como parámetro requerido dentro de test_offline_pipeline.
Eso significa que hoy, incluso si tu .parquet o .csv ya trae exactamente los nombres de feature_columns, debes mantener input_column_renames definido en la configuración. En ese caso, puedes usar un mapping identidad o uno mínimo que refleje explícitamente los nombres usados en la entrada.
4. Sección pfm¶
Parámetros visibles:
| Parámetro | Descripción |
|---|---|
pfm.detection_model_path |
Modelo PFM detection. |
pfm.size_model_path |
Modelo PFM size. |
pfm.location_model_path |
Modelo PFM location. |
pfm.leakflow_model_path |
Modelo PFM leakflow. |
pfm.on_delay_windows |
Ventanas adyacentes para declarar fuga en PFM. |
pfm.min_leak_detection_rate |
Tasa mínima de detección dentro del on_delay de PFM. |
Notas:
pfm.detection_model_pathhabilita PFM detection.size,locationyleakflowson opcionales y solo se ejecutan si sus modelos están definidos.window_sizede PFM no se toma del YAML: se carga desdelgbm_inference_config.jsondel modelo detection.
5. Sección observer¶
| Parámetro | Descripción |
|---|---|
observer.detection_model_path |
Modelo OBSERVER detection. |
observer.size_model_path |
Modelo OBSERVER size. |
observer.location_model_path |
Modelo OBSERVER location. |
observer.on_delay_windows |
Ventanas adyacentes para declarar fuga en OBSERVER. |
observer.min_leak_detection_rate |
Tasa mínima de detección dentro del on_delay de OBSERVER. |
Notas:
observer.detection_model_pathhabilita OBSERVER detection.observer.size_model_pathyobserver.location_model_pathson opcionales.window_sizede OBSERVER también se toma desdelgbm_inference_config.jsondel modelo detection.
6. Artefactos derivados automáticamente¶
Ya no es necesario expresar estos archivos en pipelines_config.yml:
features_schema.jsonlabel_mapping.jsonpara modelos PFM multiclass
El script los resuelve automáticamente en la misma carpeta donde vive cada model_lgbm.txt.
Ejemplo:
model_base_path = "models/supe/v1/1transmitter/diesel"pfm_size_model_path = "PFM/lgbm_size/model_lgbm.txt"
Entonces el script resuelve:
- modelo final:
models/supe/v1/1transmitter/diesel/PFM/lgbm_size/model_lgbm.txt - schema:
models/supe/v1/1transmitter/diesel/PFM/lgbm_size/features_schema.json - label mapping:
models/supe/v1/1transmitter/diesel/PFM/lgbm_size/label_mapping.json
Lo mismo aplica para los modelos OBSERVER, salvo que en regresión no se espera label_mapping.json.
Si configuras rutas de modelo absolutas, model_base_path puede omitirse. Si configuras rutas relativas, model_base_path debe existir.
Parámetros opcionales con default interno¶
Todo lo que no está en la lista anterior es opcional. El script lo completa automáticamente con los valores que antes estaban en pipelines_config.yml.
Mapeos opcionales de regresión¶
| Parámetro | Default | Uso |
|---|---|---|
leakflow_mapping_path |
null |
Post-proceso de leakflow PFM. |
observer_detection_mapping_path |
null |
Post-proceso de OBSERVER detection. |
observer_size_mapping_path |
null |
Post-proceso de OBSERVER size. |
observer_location_mapping_path |
null |
Post-proceso de OBSERVER location. |
Estos mappings permiten escalar, desplazar, tomar valor absoluto o recortar outputs de modelos de regresión.
No reemplazan el label_mapping.json de modelos PFM multiclass: ese archivo se infiere automáticamente junto al modelo.
Configuración ppa / npw¶
| Parámetro | Default |
|---|---|
sección ppa ausente |
no se ejecuta PPA |
sección npw ausente |
no se ejecuta NPW |
ppa.inlet_pressure_column |
null |
ppa.outlet_pressure_column |
null |
ppa.on_delay_windows |
5 |
ppa.min_leak_detection_rate |
1.0 |
ppa.window_size |
40 |
ppa.threshold |
50.0 |
npw.inlet_pressure_column |
null |
npw.outlet_pressure_column |
null |
npw.on_delay_windows |
5 |
npw.min_leak_detection_rate |
1.0 |
npw.window_size |
40 |
npw.threshold |
50.0 |
ppa_nominal_pressure_drop_pa |
0.0 |
ppa_sigma_nominal_h0_pa |
250.0 |
ppa_npw_stop_after_leak_detected |
true |
Interpretación:
- la presencia de la sección
ppahabilita PPA; - la presencia de la sección
npwhabilita NPW; - si defines solo
outlet_pressure_column, el modo se interpreta comooutlet_only; - si defines solo
inlet_pressure_column, el modo se interpreta comoinlet_only; - si defines ambos, el modo se interpreta como
both; thresholdes el nombre recomendado y único a usar en el YAML agrupado;threshold_percentqueda solo como alias legacy interno por compatibilidad con configuraciones antiguas;on_delay_windowsymin_leak_detection_ratecontrolan la transición prealarm → leak de cada motor físico;window_sizepuede ser distinto parappaynpw.
Sección lds_bayesian¶
Para una explicación completa del algoritmo, la formulación probabilística, la calibración de p_i / q_i / alpha_i y la optimización con Optuna, ver LDS Bayesiano.
| Parámetro | Default |
|---|---|
sección lds_bayesian ausente |
no se ejecuta LDS Bayes |
lds_bayesian.prior_leak_probability |
0.001 |
lds_bayesian.detection_threshold |
null |
lds_bayesian_params_path |
null |
Además, el script soporta estos parámetros avanzados de optimización/calibración LDS:
| Parámetro | Default |
|---|---|
lds_bayesian_min_cases_per_state_to_optimize |
5 |
lds_bayesian_score_tpr_weight |
0.50 |
lds_bayesian_score_tnr_weight |
0.35 |
lds_bayesian_score_precision_weight |
0.15 |
lds_bayesian_false_negative_penalty |
0.0 |
lds_bayesian_false_positive_penalty |
0.0 |
lds_bayesian_optimization_epochs |
3 |
lds_bayesian_optimizacion_min_improvement |
1e-4 |
lds_bayesian_optimization_patience |
0 |
lds_bayesian_optimization_metric |
"score" |
lds_bayesian_optimization_threshold_min |
0.50 |
lds_bayesian_optimization_threshold_max |
0.98 |
lds_bayesian_optimization_threshold_step |
0.02 |
lds_bayesian_optimization_pq_grid |
[0.55, 0.65, 0.75, 0.85, 0.90, 0.93, 0.95, 0.97, 0.98, 0.99] |
lds_bayesian_optimization_alpha_grid |
[0.0, 0.05, 0.10, 0.20, 0.35, 0.50, 0.65, 0.80, 0.95, 1.0] |
Ventanas y columnas reales¶
| Parámetro | Default |
|---|---|
step_size |
1 |
stop_fraction_leak_points |
0.25 |
leak_column |
"LEAK" |
leak_size_column |
"LEAK_SIZE_in" |
leak_location_column |
"LEAK_LOCATION_m" |
leak_flow_column |
"LEAK_FLOW_kg_s" |
Notas:
step_sizesigue siendo global para la generación de ventanas offline.window_sizede PFM y OBSERVER se toma delgbm_inference_config.json.window_sizede PPA y NPW se define por sección (ppa.window_size,npw.window_size).stop_fraction_leak_pointslimita cuánto se avanza cuando el caso contiene fuga.
Extracción de features¶
| Parámetro | Default |
|---|---|
wavelet |
"db2" |
wavelet_level |
3 |
include_raw_vectorization |
false |
temporal_sub_window_size |
null |
temporal_sub_window_step |
1 |
Estos valores deben mantenerse alineados con la semántica del pipeline de features.
Criterios de éxito y agregación¶
| Parámetro | Default |
|---|---|
diagnostic_aggregation_mode |
"average" |
Interpretación:
- el pipeline mantiene compatibilidad con
min_leak_detection_rateyleak_windowglobales como fallback legado; - en el formato agrupado nuevo, la lógica de detección usa
on_delay_windowsymin_leak_detection_ratedentro de cada algoritmo (pfm,observer,ppa,npw); diagnostic_aggregation_modecontrola cómo se resumen size/location/leakflow dentro de la ventana diagnóstica.
Descubrimiento de archivos y muestreo¶
| Parámetro | Default |
|---|---|
file_glob |
"*.csv" |
sample_fraction |
1.0 |
random_state |
42 |
target_file |
null |
ignored_input_filenames |
["reference.csv"] |
csv_sep |
"," |
csv_encoding |
"utf-8" |
Comportamiento:
target_filefuerza evaluación de un solo archivo y desplaza el muestreo.sample_fraction < 1.0muestrea archivos de forma reproducible usandorandom_state.
Reportes, plots y performance¶
| Parámetro | Default |
|---|---|
save_window_metrics |
false |
progress_monitoring |
true |
progress_update_interval |
1.0 |
plot_leak_series |
false |
generate_diagnostic_plots |
true |
generate_excel_report |
true |
save_inference_params |
true |
show_plots |
false |
parallel_workers |
6 |
prediction_batch_size |
256 |
Escalas de color para el Excel¶
El pipeline también tiene defaults internos para excel_report_colors:
location¶
green_threshold: 0.10yellow_threshold: 0.15red_threshold: 0.25step: 0.05is_percentage: truereference_span: 1333.0
size¶
green_threshold: 0.10yellow_threshold: 0.15red_threshold: 0.25step: 0.05is_percentage: truereference_span: 1.0
leakflow¶
green_threshold: 0.25yellow_threshold: 2.0red_threshold: 5.0step: 0.5
Comportamientos automáticos importantes¶
Thresholds cargados desde metadata de entrenamiento¶
Si no defines thresholds manuales:
detection_thresholdPFM se carga desdetraining_metadata.jsondel modelo detection.observer_detection_thresholdse carga desdetraining_metadata.jsondel modelo OBSERVER detection.- la cantidad de ventanas adyacentes para detección también puede heredarse desde metadata.
Esto evita que el offline test use thresholds distintos a los del entrenamiento.
Validaciones internas del script¶
El script valida varias combinaciones:
- debe existir al menos un stack activo: PFM, OBSERVER o física,
- si usas
pfm.size_model_path,pfm.location_model_pathopfm.leakflow_model_path, debe existirpfm.detection_model_path, - si usas
observer.size_model_pathoobserver.location_model_path, debe existirobserver.detection_model_path, - si existe
observer.detection_model_path, el threshold de detección resultante debe ser> 0, - si configuras
ppaonpw, debe existir al menos una columna de presión (inletuoutlet) en su sección, feature_columnsdebe existir y ser una lista válida,input_column_renamesdebe existir y ser un mapping no vacío.
Idempotencia¶
El pipeline calcula hashes efectivos de configuración y evita repetir la evaluación si ya existe una corrida equivalente en output_report_folder.
La metadata principal es:
offline_run_metadata.json
Si el hash de evaluación coincide, el script finaliza sin reprocesar archivos.
Recomendaciones prácticas¶
- Mantén
feature_columnseinput_column_renamessincronizados con los CSV reales. - No cambies schemas de features sin cambiar también los modelos correspondientes.
- Usa
target_filepara depuración rápida de un caso puntual. - Si la corrida es pesada, reduce
sample_fractionantes de bajarwindow_size. - Si necesitas máxima velocidad, puedes dejar
plot_leak_series=false,generate_diagnostic_plots=falseygenerate_excel_report=false.