Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/torchmetrics/functional/nominal/cramers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_drop_empty_rows_and_cols,
_handle_nan_in_data,
_nominal_input_validation,
_normalize_categorical_labels,
_unable_to_use_bias_correction_warning,
)

Expand Down Expand Up @@ -52,6 +53,7 @@ def _cramers_v_update(
preds = preds.argmax(1) if preds.ndim == 2 else preds
target = target.argmax(1) if target.ndim == 2 else target
preds, target = _handle_nan_in_data(preds, target, nan_strategy, nan_replace_value)
preds, target = _normalize_categorical_labels(preds, target)
return _multiclass_confusion_matrix_update(preds, target, num_classes)


Expand Down
2 changes: 2 additions & 0 deletions src/torchmetrics/functional/nominal/pearson.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
_drop_empty_rows_and_cols,
_handle_nan_in_data,
_nominal_input_validation,
_normalize_categorical_labels,
)


Expand All @@ -50,6 +51,7 @@ def _pearsons_contingency_coefficient_update(
preds = preds.argmax(1) if preds.ndim == 2 else preds
target = target.argmax(1) if target.ndim == 2 else target
preds, target = _handle_nan_in_data(preds, target, nan_strategy, nan_replace_value)
preds, target = _normalize_categorical_labels(preds, target)
return _multiclass_confusion_matrix_update(preds, target, num_classes)


Expand Down
2 changes: 2 additions & 0 deletions src/torchmetrics/functional/nominal/theils_u.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
_drop_empty_rows_and_cols,
_handle_nan_in_data,
_nominal_input_validation,
_normalize_categorical_labels,
)


Expand Down Expand Up @@ -75,6 +76,7 @@ def _theils_u_update(
preds = preds.argmax(1) if preds.ndim == 2 else preds
target = target.argmax(1) if target.ndim == 2 else target
preds, target = _handle_nan_in_data(preds, target, nan_strategy, nan_replace_value)
preds, target = _normalize_categorical_labels(preds, target)
return _multiclass_confusion_matrix_update(preds, target, num_classes)


Expand Down
2 changes: 2 additions & 0 deletions src/torchmetrics/functional/nominal/tschuprows.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_drop_empty_rows_and_cols,
_handle_nan_in_data,
_nominal_input_validation,
_normalize_categorical_labels,
_unable_to_use_bias_correction_warning,
)

Expand Down Expand Up @@ -52,6 +53,7 @@ def _tschuprows_t_update(
preds = preds.argmax(1) if preds.ndim == 2 else preds
target = target.argmax(1) if target.ndim == 2 else target
preds, target = _handle_nan_in_data(preds, target, nan_strategy, nan_replace_value)
preds, target = _normalize_categorical_labels(preds, target)
return _multiclass_confusion_matrix_update(preds, target, num_classes)


Expand Down
22 changes: 22 additions & 0 deletions src/torchmetrics/functional/nominal/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,28 @@ def _handle_nan_in_data(
return preds[~rows_contain_nan], target[~rows_contain_nan]


def _normalize_categorical_labels(preds: Tensor, target: Tensor) -> tuple[Tensor, Tensor]:
"""Map observed labels to contiguous 0-based IDs.

Nominal association metrics are invariant to renaming categories, but the
confusion-matrix updater uses raw label values as bin indices. Labels like
[1, 2] (instead of [0, 1]) would create an out-of-range bin.

Returns:
preds and target relabeled as contiguous 0-based IDs, or the
originals when they are already contiguous from zero.

"""
all_vals = torch.cat([preds, target])
unique_vals = all_vals.unique()
expected = torch.arange(len(unique_vals), device=unique_vals.device, dtype=unique_vals.dtype)
if torch.equal(unique_vals, expected):
return preds, target
preds = torch.searchsorted(unique_vals, preds)
target = torch.searchsorted(unique_vals, target)
return preds, target


def _unable_to_use_bias_correction_warning(metric_name: str) -> None:
rank_zero_warn(
f"Unable to compute {metric_name} using bias correction. Please consider to set `bias_correction=False`."
Expand Down