@@ -16,7 +16,7 @@ def _check_sample_weight(sample_weight: Optional[ArrayLike]):
16
16
def _check_reg_targets (
17
17
y_true : ArrayLike , y_pred : ArrayLike , multioutput : Optional [str ]
18
18
):
19
- if multioutput != "uniform_average" :
19
+ if multioutput is not None and multioutput != "uniform_average" :
20
20
raise NotImplementedError ("'multioutput' must be 'uniform_average'" )
21
21
22
22
if y_true .ndim == 1 :
@@ -40,12 +40,12 @@ def mean_squared_error(
40
40
_check_sample_weight (sample_weight )
41
41
output_errors = ((y_pred - y_true ) ** 2 ).mean (axis = 0 )
42
42
43
- if isinstance (multioutput , str ):
43
+ if isinstance (multioutput , str ) or multioutput is None :
44
44
if multioutput == "raw_values" :
45
- return output_errors
46
- elif multioutput == "uniform_average" :
47
- # pass None as weights to np.average: uniform mean
48
- multioutput = None
45
+ if compute :
46
+ return output_errors . compute ()
47
+ else :
48
+ return output_errors
49
49
else :
50
50
raise ValueError ("Weighted 'multioutput' not supported." )
51
51
result = output_errors .mean ()
@@ -67,12 +67,75 @@ def mean_absolute_error(
67
67
_check_sample_weight (sample_weight )
68
68
output_errors = abs (y_pred - y_true ).mean (axis = 0 )
69
69
70
- if isinstance (multioutput , str ):
70
+ if isinstance (multioutput , str ) or multioutput is None :
71
71
if multioutput == "raw_values" :
72
- return output_errors
73
- elif multioutput == "uniform_average" :
74
- # pass None as weights to np.average: uniform mean
75
- multioutput = None
72
+ if compute :
73
+ return output_errors .compute ()
74
+ else :
75
+ return output_errors
76
+ else :
77
+ raise ValueError ("Weighted 'multioutput' not supported." )
78
+ result = output_errors .mean ()
79
+ if compute :
80
+ result = result .compute ()
81
+ return result
82
+
83
+
84
+ def mean_absolute_percentage_error (
85
+ y_true : ArrayLike ,
86
+ y_pred : ArrayLike ,
87
+ sample_weight : Optional [ArrayLike ] = None ,
88
+ multioutput : Optional [str ] = "uniform_average" ,
89
+ compute : bool = True ,
90
+ ) -> ArrayLike :
91
+ """Mean absolute percentage error regression loss.
92
+
93
+ Note here that we do not represent the output as a percentage in range
94
+ [0, 100]. Instead, we represent it in range [0, 1/eps]. Read more in
95
+ https://scikit-learn.org/stable/modules/model_evaluation.html#mean-absolute-percentage-error
96
+
97
+ Parameters
98
+ ----------
99
+ y_true : array-like of shape (n_samples,) or (n_samples, n_outputs)
100
+ Ground truth (correct) target values.
101
+ y_pred : array-like of shape (n_samples,) or (n_samples, n_outputs)
102
+ Estimated target values.
103
+ sample_weight : array-like of shape (n_samples,), default=None
104
+ Sample weights.
105
+ multioutput : {'raw_values', 'uniform_average'} or array-like
106
+ Defines aggregating of multiple output values.
107
+ Array-like value defines weights used to average errors.
108
+ If input is list then the shape must be (n_outputs,).
109
+ 'raw_values' :
110
+ Returns a full set of errors in case of multioutput input.
111
+ 'uniform_average' :
112
+ Errors of all outputs are averaged with uniform weight.
113
+ compute : bool
114
+ Whether to compute this result (default ``True``)
115
+
116
+ Returns
117
+ -------
118
+ loss : float or array-like of floats in the range [0, 1/eps]
119
+ If multioutput is 'raw_values', then mean absolute percentage error
120
+ is returned for each output separately.
121
+ If multioutput is 'uniform_average' or ``None``, then the
122
+ equally-weighted average of all output errors is returned.
123
+ MAPE output is non-negative floating point. The best value is 0.0.
124
+ But note the fact that bad predictions can lead to arbitarily large
125
+ MAPE values, especially if some y_true values are very close to zero.
126
+ Note that we return a large value instead of `inf` when y_true is zero.
127
+ """
128
+ _check_sample_weight (sample_weight )
129
+ epsilon = np .finfo (np .float64 ).eps
130
+ mape = abs (y_pred - y_true ) / da .maximum (y_true , epsilon )
131
+ output_errors = mape .mean (axis = 0 )
132
+
133
+ if isinstance (multioutput , str ) or multioutput is None :
134
+ if multioutput == "raw_values" :
135
+ if compute :
136
+ return output_errors .compute ()
137
+ else :
138
+ return output_errors
76
139
else :
77
140
raise ValueError ("Weighted 'multioutput' not supported." )
78
141
result = output_errors .mean ()
@@ -90,7 +153,7 @@ def r2_score(
90
153
compute : bool = True ,
91
154
) -> ArrayLike :
92
155
_check_sample_weight (sample_weight )
93
- _ , y_true , y_pred , multioutput = _check_reg_targets (y_true , y_pred , multioutput )
156
+ _ , y_true , y_pred , _ = _check_reg_targets (y_true , y_pred , multioutput )
94
157
weight = 1.0
95
158
96
159
numerator = (weight * (y_true - y_pred ) ** 2 ).sum (axis = 0 , dtype = "f8" )
0 commit comments