refactor(metrics): warn with the remaining count and document NaN pairs (SIENTIAPDE-2215)

This commit is contained in:
PedroHMCosme
2026-10-21 09:11:40 -03:00
parent 9c05871fcf
commit 8c81aa68bb
2 changed files with 15 additions and 5 deletions

View File

@@ -357,7 +357,8 @@ class DataManagerRepository(SientiaMonitoring):
This helper mirrors the previous TrainingRepository.after_train_calculation This helper mirrors the previous TrainingRepository.after_train_calculation
behavior, assuming that predictions (y_pred/y_train_pred) are already on the behavior, assuming that predictions (y_pred/y_train_pred) are already on the
correct scale for metric calculation (any scaling is handled inside the correct scale for metric calculation (any scaling is handled inside the
model wrapper). model wrapper). Pairs with a NaN target or a NaN prediction are left out of
mse/mae/r2.
Args: Args:
tmr: Training result containing: tmr: Training result containing:
@@ -368,6 +369,10 @@ class DataManagerRepository(SientiaMonitoring):
Return: Return:
TrainModelResult: Same object with mse_val, mae_val and r2_val set. TrainModelResult: Same object with mse_val, mae_val and r2_val set.
Raises:
ValueError: If y_pred is not set, val_data and y_pred share no indices,
or no pair has both a valid target and a valid prediction.
""" """
if tmr.y_pred is None: if tmr.y_pred is None:
raise ValueError('y_pred must be set before computing regression metrics') raise ValueError('y_pred must be set before computing regression metrics')
@@ -414,9 +419,10 @@ class DataManagerRepository(SientiaMonitoring):
f'{len(valid)} overlapping rows have NaN' f'{len(valid)} overlapping rows have NaN'
) )
if not valid.all(): if not valid.all():
self.info( n_valid = int(valid.sum())
f'Ignoring {int((~valid).sum())} validation row(s) with NaN target or prediction ' self.warning(
'in the regression metrics', f'Ignoring {len(valid) - n_valid} of {len(valid)} validation row(s) with NaN '
f'target or prediction; regression metrics use the remaining {n_valid}',
metadata, metadata,
) )
y_true_val = y_true_val[valid] y_true_val = y_true_val[valid]

View File

@@ -323,10 +323,14 @@ def test_compute_regression_metrics_ignores_nan_pairs():
wrapper = MagicMock() wrapper = MagicMock()
wrapper.model = object() # no sklearn .regr -> equation extraction is skipped wrapper.model = object() # no sklearn .regr -> equation extraction is skipped
out = repo.compute_regression_metrics(tmr, wrapper) with patch.object(repo, 'warning') as warn:
out = repo.compute_regression_metrics(tmr, wrapper)
assert out.mse_val == 0.0 assert out.mse_val == 0.0
assert out.mae_val == 0.0 assert out.mae_val == 0.0
assert out.r2_val == 1.0
warn.assert_called_once()
assert 'Ignoring 2 of 4' in warn.call_args.args[0]
def test_compute_regression_metrics_all_nan_pairs_raises(): def test_compute_regression_metrics_all_nan_pairs_raises():