Czy w Pythonie istnieje funkcja biblioteczna dla błędu średniej kwadratowej (RMSE)?

157

Wiem, że mógłbym zaimplementować funkcję błędu średniej kwadratowej w następujący sposób:

def rmse(predictions, targets):
    return np.sqrt(((predictions - targets) ** 2).mean())

Czego szukam, jeśli ta funkcja rmse jest zaimplementowana gdzieś w bibliotece, być może w scipy lub scikit-learn?

siamii
źródło
5
napisałeś funkcję właśnie tam. Najprawdopodobniej, jeśli funkcja jest tak prosta do napisania, to nie będzie w bibliotece. lepiej jest stworzyć reżysera zwanego modułami i po prostu umieścić w nim przydatne funkcje i dodać go do swojej ścieżki
Ryan Saxe
14
@RyanSaxe Nie zgadzam się. Byłoby o wiele bardziej uspokajające wywołanie funkcji biblioteki niż samodzielne jej ponowne zaimplementowanie. Na przykład, .sum()zamiast .mean()pierwszego przez pomyłkę napisałem . Ponadto przypuszczam, że ta funkcja jest używana tak często, że nie widzę powodu, dla którego nie miałaby być dostępna jako funkcja biblioteczna.
siamii
1
@siamii: Rozumiem, że w 100% spekulowałem tylko na temat powodu, dla którego tego rodzaju funkcja może nie być w scipy. Jeśli tak, nie mogę tego znaleźć
Ryan Saxe
1
Dla ludzi, którzy próbowali tego i nie zadziałało: jeśli predictionsi targetssą na przykład typu, int16kwadrat może się przepełnić (dając liczby ujemne). Więc możesz potrzebować .astype('int')lub .astype('double')przed użyciem kwadratu, na przykład np.sqrt(((predictions - targets).astype('double') ** 2).mean()).
John
Kolejną zaletą posiadania tego w sklearn jest to, że implementacje sklearn mają wiele dodatkowych kodów kotłów, aby zapewnić, że tablice mają ten sam kształt i zawierają parametry wag, a także obsługują tablice wielowymiarowe i różne „polubienia tablic”. Robiąc to wszystko, staje się to znacznie bardziej złożonym problemem
David Waterworth

Odpowiedzi:

212

sklearn.metricsma mean_squared_errorfunkcję. Wartość RMSE to po prostu pierwiastek kwadratowy z tego, co zwraca.

from sklearn.metrics import mean_squared_error
from math import sqrt

rms = sqrt(mean_squared_error(y_actual, y_predicted))
Greg
źródło
2
mean_squared_errorin sklearn.metricsobsługuje teraz dodatkowy parametr: squared- "Jeśli True zwraca wartość MSE, jeśli False zwraca wartość RMSE."
Daddy
132

Co to jest RMSE? Znany również jako MSE, RMD lub RMS. Jaki problem rozwiązuje?

Jeśli rozumiesz RMSE: (błąd średniokwadratowy), MSE: (błąd średniokwadratowy) RMD (odchylenie średniej kwadratowej) i RMS: (średnia kwadratowa), to prośba o bibliotekę do obliczenia tego za Ciebie jest niepotrzebnym przeprojektowaniem . Wszystkie te wskaźniki to pojedynczy wiersz kodu Pythona o długości maksymalnie 2 cali. Trzy metryki rmse, mse, rmd i rms są w swej istocie koncepcyjnie identyczne.

RMSE odpowiada na pytanie: „Jak podobne są średnio liczby list1do list2?”. Obie listy muszą mieć ten sam rozmiar. Chcę „zmyć szum pomiędzy dowolnymi dwoma danymi elementami, zmyć rozmiar zebranych danych i uzyskać odczucie zmiany pojedynczej liczby w czasie”.

Intuicja i ELI5 dla RMSE:

Wyobraź sobie, że uczysz się rzucać lotkami w tarczę do rzutek. Codziennie ćwiczysz przez godzinę. Chcesz dowiedzieć się, czy czujesz się lepiej, czy gorzej. Więc każdego dnia wykonujesz 10 rzutów i mierzysz odległość między tarczą a miejscem, w którym uderzyła twoja strzałka.

Robisz listę tych numerów list1. Użyj średniego kwadratu błędu między odległościami w dniu 1 i a list2zawierającym wszystkie zera. Zrób to samo w drugi i n-ty dzień. Otrzymasz pojedynczą liczbę, która, miejmy nadzieję, maleje z czasem. Kiedy Twój numer RMSE wynosi zero, za każdym razem trafiasz w dziesiątkę. Jeśli liczba rmse wzrośnie, sytuacja się pogarsza.

Przykład obliczenia średniej kwadratowej błędu w Pythonie:

import numpy as np
d = [0.000, 0.166, 0.333]   #ideal target distances, these can be all zeros.
p = [0.000, 0.254, 0.998]   #your performance goes here

print("d is: " + str(["%.8f" % elem for elem in d]))
print("p is: " + str(["%.8f" % elem for elem in p]))

def rmse(predictions, targets):
    return np.sqrt(((predictions - targets) ** 2).mean())

rmse_val = rmse(np.array(d), np.array(p))
print("rms error is: " + str(rmse_val))

Które wydruki:

d is: ['0.00000000', '0.16600000', '0.33300000']
p is: ['0.00000000', '0.25400000', '0.99800000']
rms error between lists d and p is: 0.387284994115

Notacja matematyczna:

Wyjaśnienie podstawowego odchylenia od średniej kwadratowej

Glyph Legend: n to cała dodatnia liczba całkowita reprezentująca liczbę rzutów. ireprezentuje cały dodatni licznik całkowity, który wylicza sumę. doznacza idealne odległości, list2zawierające wszystkie zera w powyższym przykładzie. poznacza wydajność, list1w powyższym przykładzie. indeks górny 2 oznacza numeryczny kwadrat. d i jest i- tym indeksem d. p i jest i- tym indeksem p.

Rmse wykonano małymi krokami, aby można było je zrozumieć:

def rmse(predictions, targets):

    differences = predictions - targets                       #the DIFFERENCEs.

    differences_squared = differences ** 2                    #the SQUAREs of ^

    mean_of_differences_squared = differences_squared.mean()  #the MEAN of ^

    rmse_val = np.sqrt(mean_of_differences_squared)           #ROOT of ^

    return rmse_val                                           #get the ^

Jak działa każdy krok RMSE:

Odejmowanie jednej liczby od drugiej daje odległość między nimi.

8 - 5 = 3         #absolute distance between 8 and 5 is +3
-20 - 10 = -30    #absolute distance between -20 and 10 is +30

Jeśli pomnożymy dowolną liczbę razy siebie, wynik jest zawsze dodatni, ponieważ ujemny razy ujemny jest dodatni:

3*3     = 9   = positive
-30*-30 = 900 = positive

Dodaj je wszystkie, ale poczekaj, wtedy tablica z wieloma elementami miałaby większy błąd niż mała tablica, więc uśrednij je przez liczbę elementów.

Ale poczekaj, wyrównaliśmy je wszystkie wcześniej, aby wymusić na nich pozytywne wyniki. Cofnij szkody za pomocą pierwiastka kwadratowego!

To daje ci pojedynczą liczbę, która średnio reprezentuje odległość między każdą wartością z listy list1 a odpowiadającą jej wartością elementu list2.

Jeśli wartość RMSE spada w czasie, jesteśmy zadowoleni, ponieważ zmniejsza się wariancja .

RMSE nie jest najdokładniejszą strategią dopasowania linii, całkowita metoda najmniejszych kwadratów to:

Podstawowy błąd średniokwadratowy mierzy odległość w pionie między punktem a linią, więc jeśli dane mają kształt banana, płaskiego u dołu i stromego u góry, wówczas RMSE zgłosi większe odległości do punktów wysoko, ale małe odległości do punkty niskie, podczas gdy w rzeczywistości odległości są równoważne. Powoduje to pochylenie, w którym linia woli być bliżej punktów wyższych niż niskich.

Jeśli jest to problem, metoda całkowitej najmniejszych kwadratów rozwiązuje ten problem: https://mubaris.com/posts/linear-regression

Błędy, które mogą złamać tę funkcję RMSE:

Jeśli na którejś z list wejściowych znajdują się wartości null lub nieskończoność, wyjściowa wartość rmse nie będzie miała sensu. Istnieją trzy strategie radzenia sobie z zerami / brakującymi wartościami / nieskończonościami na każdej z list: Zignoruj ​​ten składnik, wyzeruj go lub dodaj najlepsze przypuszczenie lub jednolity losowy szum do wszystkich kroków czasowych. Każdy środek zaradczy ma swoje wady i zalety w zależności od tego, co oznaczają Twoje dane. Ogólnie rzecz biorąc, preferowane jest ignorowanie dowolnego komponentu z brakującą wartością, ale powoduje to odchylenie RMSE w kierunku zera, co sprawia, że ​​myślisz, że wydajność poprawiła się, gdy tak naprawdę nie jest. Dodanie losowego szumu na podstawie najlepszego przypuszczenia może być preferowane, jeśli brakuje wielu wartości.

Aby zagwarantować względną poprawność danych wyjściowych RMSE, należy wyeliminować wszystkie wartości null / nieskończoności z danych wejściowych.

RMSE ma zerową tolerancję dla odstających punktów danych, które nie należą

Średnia kwadratowa kwadratów błędu polega na tym, że wszystkie dane są prawidłowe i wszystkie są liczone jako równe. Oznacza to, że jeden zbłąkany punkt w lewym polu całkowicie zrujnuje całe obliczenia. Aby poradzić sobie z punktami danych odstających i odrzucić ich ogromny wpływ po pewnym progu, zobacz Solidne estymatory, które tworzą próg odrzucania wartości odstających.

Eric Leschinski
źródło
3
Tak, prosta funkcja. Ale jeśli potrzebujesz go na co dzień, dobrze jest mieć gdzieś właściwe rozwiązanie, aby nie trzeba było go ponownie wdrażać za każdym razem; )
logiczne x 2
@ eric-leschinski, byłbym wdzięczny, gdybyś mógł rzucić okiem na to: stackoverflow.com/questions/45173451/…
Desta Haileselassie Hagos
1
To z pewnością znak tego pokolenia, o które ludzie proszą i wskazują na biblioteki wielogigabajtowe; wymagające od 3 do 20 minut pobierania z sieci, a następnie pełnoekranowych instalacji procesora, podczas gdy wszystko, czego naprawdę potrzebujesz, to około 3 linii kodu, które mieszczą się w 400 bajtach. Jeśli poprosisz o bibliotekę do pracy, którą można skompresować do 1 linii kodu, o szerokości około 90 znaków, dajesz ludziom licencję na wykorzystywanie Cię przy 3, 10, a wkrótce 50 GB instalacjach o wielkości 99,9999 % wzdęcia. To nie jest operacja rakietowa. Twój kalkulator zasilany energią słoneczną wyprodukowany w 1978 roku z procesorem 740 Hz może przetwarzać RMSE.
Eric Leschinski
22

To jest prawdopodobnie szybsze ?:

n = len(predictions)
rmse = np.linalg.norm(predictions - targets) / np.sqrt(n)
Koks
źródło
18

W scikit-learn 0.22.0 możesz przekazać mean_squared_error()argument squared=Falsezwracający wartość RMSE.

from sklearn.metrics import mean_squared_error

mean_squared_error(y_actual, y_predicted, squared=False)
jeffhale
źródło
2
Jest to nowa funkcja i najlepiej by było, gdybyśmy jej użyli.
Ravi G
9

Na wypadek, gdyby ktoś znalazł ten wątek w 2019 roku, istnieje biblioteka o nazwie, ml_metricsktóra jest dostępna bez wstępnej instalacji w jądrach Kaggle, dość uproszczona i dostępna przez pypi(można ją łatwo i szybko zainstalować za pomocą pip install ml_metrics):

from ml_metrics import rmse
rmse(actual=[0, 1, 2], predicted=[1, 10, 5])
# 5.507570547286102

Zawiera kilka innych interesujących wskaźników, które nie są dostępne w sklearn, takich jak mapk.

Bibliografia:

dataista
źródło
4

Właściwie to napisałem kilka z nich jako funkcje narzędziowe dla modeli stat

http://statsmodels.sourceforge.net/devel/tools.html#measure-for-fit-performance-eval-measures

i http://statsmodels.sourceforge.net/devel/generated/statsmodels.tools.eval_measures.rmse.html#statsmodels.tools.eval_measures.rmse

Przeważnie jeden lub dwa linery i niezbyt dużo sprawdzania danych wejściowych, głównie przeznaczone do łatwego uzyskiwania niektórych statystyk podczas porównywania tablic. Ale mają testy jednostkowe dla argumentów osi, ponieważ tam czasami popełniam niechlujne błędy.

Josef
źródło
3

Lub po prostu używając tylko funkcji NumPy:

def rmse(y, y_pred):
    return np.sqrt(np.mean(np.square(y - y_pred)))

Gdzie:

  • y jest moim celem
  • y_pred to moja prognoza

Zauważ, że rmse(y, y_pred)==rmse(y_pred, y)ze względu na funkcję square.

KeyMaker00
źródło
3

Nie można znaleźć funkcji RMSE bezpośrednio w SKLearn. Ale zamiast ręcznie wykonywać sqrt, istnieje inny standardowy sposób użycia sklearn. Najwyraźniej sam błąd mean_squared_error w Sklearnie zawiera parametr o nazwie „do kwadratu” z domyślną wartością true. Jeśli ustawimy go na false, ta sama funkcja zwróci RMSE zamiast MSE.

# code changes implemented by Esha Prakash
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)
user12999612
źródło
0

Oto przykładowy kod, który oblicza RMSE między dwoma formatami plików wielokątów PLY. Wykorzystuje zarówno ml_metricsbibliotekę, jak i np.linalg.norm:

import sys
import SimpleITK as sitk
from pyntcloud import PyntCloud as pc
import numpy as np
from ml_metrics import rmse

if len(sys.argv) < 3 or sys.argv[1] == "-h" or sys.argv[1] == "--help":
    print("Usage: compute-rmse.py <input1.ply> <input2.ply>")
    sys.exit(1)

def verify_rmse(a, b):
    n = len(a)
    return np.linalg.norm(np.array(b) - np.array(a)) / np.sqrt(n)

def compare(a, b):
    m = pc.from_file(a).points
    n = pc.from_file(b).points
    m = [ tuple(m.x), tuple(m.y), tuple(m.z) ]; m = m[0]
    n = [ tuple(n.x), tuple(n.y), tuple(n.z) ]; n = n[0]
    v1, v2 = verify_rmse(m, n), rmse(m,n)
    print(v1, v2)

compare(sys.argv[1], sys.argv[2])
Georges
źródło
-1
  1. Nie, istnieje biblioteka Scikit Learn do uczenia maszynowego i można ją łatwo wykorzystać za pomocą języka Python. Ma funkcję średniego kwadratu błędu, którą udostępniam poniżej:

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html

  1. Funkcja nosi nazwę mean_squared_error, jak podano poniżej, gdzie y_true byłyby rzeczywistymi wartościami klasy dla krotek danych, a y_pred byłyby wartościami przewidywanymi, przewidywanymi przez algorytm uczenia maszynowego, którego używasz:

mean_squared_error (y_true, y_pred)

  1. Musisz go zmodyfikować, aby uzyskać RMSE (używając funkcji sqrt w Pythonie). Proces ten jest opisany w tym linku: https://www.codeastar.com/regression-model-rmsd/

Tak więc końcowy kod wyglądałby tak:

from sklearn.metrics import mean_squared_error from math import sqrt

RMSD = sqrt (mean_squared_error (testowanie_y, przewidywanie))

drukuj (RMSD)

Usman Zafar
źródło