mape.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # Copyright The Lightning team.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from typing import Union
  15. import torch
  16. from torch import Tensor
  17. from torchmetrics.utilities.checks import _check_same_shape
  18. def _mean_absolute_percentage_error_update(
  19. preds: Tensor,
  20. target: Tensor,
  21. epsilon: float = 1.17e-06,
  22. ) -> tuple[Tensor, int]:
  23. """Update and returns variables required to compute Mean Percentage Error.
  24. Check for same shape of input tensors.
  25. Args:
  26. preds: Predicted tensor
  27. target: Ground truth tensor
  28. epsilon: Specifies the lower bound for target values. Any target value below epsilon
  29. is set to epsilon (avoids ``ZeroDivisionError``).
  30. """
  31. _check_same_shape(preds, target)
  32. abs_diff = torch.abs(preds - target)
  33. abs_per_error = abs_diff / torch.clamp(torch.abs(target), min=epsilon)
  34. sum_abs_per_error = torch.sum(abs_per_error)
  35. num_obs = target.numel()
  36. return sum_abs_per_error, num_obs
  37. def _mean_absolute_percentage_error_compute(sum_abs_per_error: Tensor, num_obs: Union[int, Tensor]) -> Tensor:
  38. """Compute Mean Absolute Percentage Error.
  39. Args:
  40. sum_abs_per_error: Sum of absolute value of percentage errors over all observations
  41. ``(percentage error = (target - prediction) / target)``
  42. num_obs: Number of predictions or observations
  43. Example:
  44. >>> target = torch.tensor([1, 10, 1e6])
  45. >>> preds = torch.tensor([0.9, 15, 1.2e6])
  46. >>> sum_abs_per_error, num_obs = _mean_absolute_percentage_error_update(preds, target)
  47. >>> _mean_absolute_percentage_error_compute(sum_abs_per_error, num_obs)
  48. tensor(0.2667)
  49. """
  50. return sum_abs_per_error / num_obs
  51. def mean_absolute_percentage_error(preds: Tensor, target: Tensor) -> Tensor:
  52. """Compute mean absolute percentage error.
  53. Args:
  54. preds: estimated labels
  55. target: ground truth labels
  56. Return:
  57. Tensor with MAPE
  58. Note:
  59. The epsilon value is taken from `scikit-learn's implementation of MAPE`_.
  60. Example:
  61. >>> from torchmetrics.functional.regression import mean_absolute_percentage_error
  62. >>> target = torch.tensor([1, 10, 1e6])
  63. >>> preds = torch.tensor([0.9, 15, 1.2e6])
  64. >>> mean_absolute_percentage_error(preds, target)
  65. tensor(0.2667)
  66. """
  67. sum_abs_per_error, num_obs = _mean_absolute_percentage_error_update(preds, target)
  68. return _mean_absolute_percentage_error_compute(sum_abs_per_error, num_obs)