Esiste una funzione di libreria per Errore quadratico medio radice (RMSE) in Python?


158

So che potrei implementare una funzione di errore al quadrato medio radice come questa:

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

Cosa sto cercando se questa funzione rmse è implementata in una libreria da qualche parte, forse in scipy o scikit-learn?


5
hai scritto la funzione proprio lì. Molto probabilmente se la funzione è così semplice da scrivere, non sarà in una libreria. stai meglio creando un regista chiamato moduli e semplicemente inserendo funzioni utili e aggiungendolo al tuo percorso
Ryan Saxe,

14
@RyanSaxe Non sono d'accordo. Troverei molto più rassicurante chiamare una funzione di libreria piuttosto che reimplementarla da solo. Ad esempio, ho scritto .sum()invece per .mean()primo per errore. Inoltre, suppongo che questa funzione sia utilizzata così tanto che non vedo alcun motivo per cui non dovrebbe essere disponibile come funzione di libreria.
Siamii,

1
@siamii: Capisco che al 100%, stavo solo ipotizzando il motivo per cui questo tipo di funzione potrebbe non essere in scipy. Se è così non riesco a trovarlo
Ryan Saxe,

1
Per le persone che hanno provato questo e non ha funzionato: se predictionse targetssono ad esempio di tipo, int16il quadrato potrebbe traboccare (fornendo numeri negativi). Quindi potresti aver bisogno di un .astype('int')o .astype('double')prima di usare il quadrato, come np.sqrt(((predictions - targets).astype('double') ** 2).mean()).
Giovanni,

Un altro vantaggio di avere questo in sklearn è che le implementazioni di sklearn hanno un sacco di codice aggiuntivo della piastra della caldaia per garantire che le matrici abbiano la stessa forma e includano i parametri dei pesi e gestiscano anche matrici multidimensionali e diversi "Mi piace di matrice". Fare tutto ciò trasforma questo in un problema molto più complesso
David Waterworth,

Risposte:


214

sklearn.metricsha una mean_squared_errorfunzione. RMSE è solo la radice quadrata di qualunque cosa ritorni.

from sklearn.metrics import mean_squared_error
from math import sqrt

rms = sqrt(mean_squared_error(y_actual, y_predicted))

3
mean_squared_errorin sklearn.metricsora supporta il parametro aggiuntivo: squared- "Se True restituisce il valore MSE, se False restituisce il valore RMSE."
Daddy32

132

Che cos'è RMSE? Conosciuto anche come MSE, RMD o RMS. Che problema risolve?

Se capisci RMSE: (Errore quadratico medio radice), MSE: (Errore quadrato medio) RMD (Deviazione quadrata media radice) e RMS: (Quadrato media radice), quindi richiedere una libreria per calcolare questo per te non è necessario un eccesso di ingegneria . Tutte queste metriche sono una singola riga di codice Python lunga al massimo 2 pollici. Le tre metriche rmse, mse, rmd e rms sono fondamentalmente identiche concettualmente.

RMSE risponde alla domanda: "Come simile, in media, sono i numeri list1a list2?". Le due liste devono avere le stesse dimensioni. Voglio "eliminare il rumore tra due elementi qualsiasi, eliminare la dimensione dei dati raccolti e ottenere un singolo numero per cambiare nel tempo".

Intuition ed ELI5 per RMSE:

Immagina di imparare a lanciare freccette su un bersaglio per le freccette. Ogni giorno ti alleni per un'ora. Vuoi capire se stai migliorando o peggiorando. Quindi ogni giorno fai 10 tiri e misuri la distanza tra il bersaglio e dove il tuo dardo ha colpito.

Fai un elenco di quei numeri list1. Utilizzare l'errore quadratico medio radice tra le distanze al giorno 1 e un list2contenente tutti gli zeri. Fai lo stesso il secondo e l'ennesimo giorno. Quello che otterrai è un singolo numero che si spera diminuisca nel tempo. Quando il tuo numero RMSE è zero, colpisci ogni volta bullseyes. Se il numero rmse aumenta, stai peggiorando.

Esempio nel calcolo dell'errore al quadrato della media radice in Python:

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))

Che stampa:

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

La notazione matematica:

spiegazione della deviazione quadrata media radice

Glyph Legend: n è un numero intero positivo che rappresenta il numero di tiri. irappresenta un intero contatore intero positivo che enumera la somma. dindica le distanze ideali, list2contenente tutti gli zeri nell'esempio sopra. psta per performance, l' list1esempio sopra. l'apice 2 indica il quadrato numerico. d i è l'indice di-esimo d. p i è l'indice di-esimo p.

Il rmse fatto in piccoli passi in modo che possa essere compreso:

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 ^

Come funziona ogni passaggio di RMSE:

Sottrarre un numero da un altro ti dà la distanza tra di loro.

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

Se moltiplichi un numero qualsiasi di volte, il risultato è sempre positivo perché i tempi negativi negativi sono positivi:

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

Aggiungili tutti, ma aspetta, quindi un array con molti elementi avrebbe un errore più grande di un array piccolo, quindi fai una media per il numero di elementi.

Ma aspetta, li abbiamo quadrati tutti prima per forzarli positivi. Annulla il danno con una radice quadrata!

Ciò ti lascia con un solo numero che rappresenta, in media, la distanza tra ogni valore di list1 e il corrispondente valore dell'elemento di list2.

Se il valore RMSE diminuisce nel tempo, siamo felici perché la varianza sta diminuendo.

RMSE non è la strategia di adattamento della linea più accurata, il totale dei minimi quadrati è:

L'errore quadratico medio di radice misura la distanza verticale tra il punto e la linea, quindi se i tuoi dati hanno la forma di una banana, piatta vicino al fondo e ripida vicino alla cima, l'RMSE segnalerà maggiori distanze ai punti alti, ma brevi distanze a punti bassi quando in effetti le distanze sono equivalenti. Ciò provoca una inclinazione in cui la linea preferisce essere più vicina ai punti più alti che più bassi.

Se questo è un problema, il metodo dei minimi quadrati risolve questo problema: https://mubaris.com/posts/linear-regression

Gotcha che possono interrompere questa funzione RMSE:

Se ci sono valori nulli o infiniti in entrambi gli elenchi di input, allora il valore di output rmse non avrà senso. Esistono tre strategie per gestire valori nulli / mancanti / infiniti in entrambi gli elenchi: ignorare quel componente, azzerarlo o aggiungere una migliore ipotesi o un rumore casuale uniforme a tutti i timestep. Ogni rimedio ha i suoi pro e contro a seconda del significato dei tuoi dati. In generale, si preferisce ignorare qualsiasi componente con un valore mancante, ma ciò orienta l'RMSE verso lo zero facendoti pensare che le prestazioni siano migliorate quando in realtà non lo sono. L'aggiunta di rumore casuale su una migliore ipotesi potrebbe essere preferita se ci sono molti valori mancanti.

Per garantire la relativa correttezza dell'uscita RMSE, è necessario eliminare tutti i valori nulli / infiniti dall'input.

RMSE ha tolleranza zero per i punti di dati anomali che non appartengono

La radice media dei quadrati di errore si basa su tutti i dati corretti e tutti vengono considerati uguali. Ciò significa che un punto randagio che si trova nel campo di sinistra rovinerà totalmente l'intero calcolo. Per gestire i punti di dati anomali e respingere la loro enorme influenza dopo una certa soglia, vedere Stimatori robusti che incorporano una soglia per il licenziamento dei valori anomali.


3
Sì, funzione semplice. Ma se ne hai bisogno di tutti i giorni, usa la sua funzionalità per avere una soluzione corretta disponibile da qualche parte in modo da non doverla reimplementare ogni volta; )
logico x 2

@ eric-Leschinski, le sarei grato se poteste dare un'occhiata a questo: stackoverflow.com/questions/45173451/...
Desta Haileselassie Hagos

1
È sicuramente un segno di questa generazione che la gente chiede e indica librerie di dimensioni multi-gigabyte; richiede da 3 a 20 minuti di download della rete, quindi l'installazione completa della CPU, quando tutto ciò di cui hai veramente bisogno sono circa 3 righe di codice che si adattano a 400 byte. Se chiedi una libreria per un lavoro che può essere compresso in una riga di codice, con una larghezza di circa 90 caratteri, stai concedendo la licenza alle persone per abusarti di installazioni da 3, 10 e presto da 50 GB che sono 99.9999 % gonfio. Questa non è chirurgia missilistica. Il tuo calcolatore ad energia solare realizzato nel 1978 con processore a 740Hz può fare RMSE.
Eric Leschinski,

22

Questo è probabilmente più veloce ?:

n = len(predictions)
rmse = np.linalg.norm(predictions - targets) / np.sqrt(n)

18

In scikit-learn 0.22.0 è possibile passare mean_squared_error()l'argomento squared=Falseper restituire RMSE.

from sklearn.metrics import mean_squared_error

mean_squared_error(y_actual, y_predicted, squared=False)


2
Questa è una nuova funzionalità e sarebbe meglio se la usiamo.
Ravi G

9

Nel caso in cui qualcuno trovi questo thread nel 2019, c'è una libreria chiamata ml_metricsche è disponibile senza preinstallazione nei kernel di Kaggle, abbastanza leggera e accessibile attraverso pypi(può essere installata facilmente e velocemente con pip install ml_metrics):

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

Ha poche altre metriche interessanti che non sono disponibili in sklearn, come mapk.

Riferimenti:


4

In realtà, ho scritto un sacco di quelli come funzioni di utilità per statsmodels

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

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

Principalmente una o due linee e non molto controllo di input, e principalmente inteso per ottenere facilmente alcune statistiche quando si confrontano le matrici. Ma hanno test unitari per gli argomenti degli assi, perché è lì che a volte commetto errori sciatti.


3

O semplicemente usando solo le funzioni NumPy:

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

Dove:

  • y è il mio obiettivo
  • y_pred è la mia previsione

Si noti che a rmse(y, y_pred)==rmse(y_pred, y)causa della funzione quadrata.


3

Non è possibile trovare la funzione RMSE direttamente in SKLearn. Ma invece di fare sqrt manualmente, c'è un altro modo standard usando sklearn. Apparentemente, lo stesso mean_squared_error di Sklearn contiene un parametro chiamato "quadrato" con il valore predefinito come vero. Se lo impostiamo su falso, la stessa funzione restituirà RMSE anziché MSE.

# code changes implemented by Esha Prakash
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)

0

Ecco un codice di esempio che calcola l'RMSE tra due formati di file poligonali PLY. Utilizza sia la ml_metricslib che il 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])

-1
  1. No, esiste una libreria Scikit Learn per l'apprendimento automatico e può essere facilmente utilizzata utilizzando il linguaggio Python. Ha una funzione per Mean Squared Error che sto condividendo il link qui sotto:

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

  1. La funzione è denominata mean_squared_error come indicato di seguito, dove y_true sarebbe valori di classe reali per le tuple di dati e y_pred sarebbero i valori previsti, previsti dall'algoritmo di apprendimento automatico che si sta utilizzando:

mean_squared_error (y_true, y_pred)

  1. Devi modificarlo per ottenere RMSE (usando la funzione sqrt usando Python). Questo processo è descritto in questo link: https://www.codeastar.com/regression-model-rmsd/

Quindi, il codice finale sarebbe qualcosa del tipo:

da sklearn.metrics import mean_squared_error dall'importazione matematica sqrt

RMSD = sqrt (mean_squared_error (testing_y, previsione))

stampare (RMSD)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.