Średni bezwzględny błąd procentowy (MAPE) w Scikit-learn [zamknięty]

24

Jak obliczyć średni bezwzględny błąd procentowy (MAPE) naszych prognoz za pomocą Pythona i scikit-learn?

Z dokumentów mamy tylko te 4 funkcje metryczne dla Regresji:

  • metrics.explained_variance_score (y_true, y_pred)
  • metrics.mean_absolute_error (y_true, y_pred)
  • metrics.mean_squared_error (y_true, y_pred)
  • metrics.r2_score (y_true, y_pred)
Nyxynyx
źródło
Patrz odpowiedz na stackOverflow- stackoverflow.com/questions/42250958/...
Arpit Sisodia

Odpowiedzi:

24

Jak wspomniano (na przykład w Wikipedii ), MAPE może powodować problemy. Przede wszystkim może powodować błędy dzielenia przez zero. Domyślam się, że właśnie dlatego nie jest uwzględniony w metrykach sklearn.

Jest jednak prosty do wdrożenia.

from sklearn.utils import check_arrays
def mean_absolute_percentage_error(y_true, y_pred): 
    y_true, y_pred = check_arrays(y_true, y_pred)

    ## Note: does not handle mix 1d representation
    #if _is_1d(y_true): 
    #    y_true, y_pred = _check_1d_array(y_true, y_pred)

    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100

Używaj jak każdej innej metryki ...:

> y_true = [3, -0.5, 2, 7]; y_pred = [2.5, -0.3, 2, 8]
> mean_absolute_percentage_error(y_true, y_pred)
Out[19]: 17.738095238095237

(Pamiętaj, że mnożę przez 100 i zwracam wartość procentową).

... ale ostrożnie:

> y_true = [3, 0.0, 2, 7]; y_pred = [2.5, -0.3, 2, 8]
> #Note the zero in y_pred
> mean_absolute_percentage_error(y_true, y_pred)
-c:8: RuntimeWarning: divide by zero encountered in divide
Out[21]: inf
Mężczyzna
źródło
1
W tej odpowiedzi jest błąd. Powinny być (wymienić y_predze y_truew mianowniku):return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
404pio
1
check_arrayszostał porzucony przez Scipy. Jest check_arrayw obecnej sklearn, ale nie wygląda na to, żeby działało w ten sam sposób.
kilodżule
metoda check_arrays została usunięta z .16.
Arpit Sisodia
17

oto zaktualizowana wersja:

import numpy as np

def mean_absolute_percentage_error(y_true, y_pred): 
    y_true, y_pred = np.array(y_true), np.array(y_pred)
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
Antonín Hoskovec
źródło