diff --git a/model_manager/utils/repository/data_manager_repository.py b/model_manager/utils/repository/data_manager_repository.py index 856976f..179c3da 100644 --- a/model_manager/utils/repository/data_manager_repository.py +++ b/model_manager/utils/repository/data_manager_repository.py @@ -357,7 +357,8 @@ class DataManagerRepository(SientiaMonitoring): This helper mirrors the previous TrainingRepository.after_train_calculation behavior, assuming that predictions (y_pred/y_train_pred) are already on 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: tmr: Training result containing: @@ -368,6 +369,10 @@ class DataManagerRepository(SientiaMonitoring): Return: 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: 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' ) if not valid.all(): - self.info( - f'Ignoring {int((~valid).sum())} validation row(s) with NaN target or prediction ' - 'in the regression metrics', + n_valid = int(valid.sum()) + self.warning( + 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, ) y_true_val = y_true_val[valid] diff --git a/tests/utils/repository/test_data_manager_repository.py b/tests/utils/repository/test_data_manager_repository.py index c198efe..41d159a 100644 --- a/tests/utils/repository/test_data_manager_repository.py +++ b/tests/utils/repository/test_data_manager_repository.py @@ -323,10 +323,14 @@ def test_compute_regression_metrics_ignores_nan_pairs(): wrapper = MagicMock() 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.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():