¿Existe una función de biblioteca para Root mean square error (RMSE) en python?

158

Sé que podría implementar una función de error cuadrático medio así:

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

¿Qué estoy buscando si esta función rmse se implementa en una biblioteca en algún lugar, tal vez en scipy o scikit-learn?

siamii
fuente
55
escribiste la función allí mismo. Lo más probable es que si la función es tan simple de escribir, no va a estar en una biblioteca. es mejor crear un director llamado módulos y simplemente ponerle funciones útiles y agregarlo a su camino
Ryan Saxe
14
@RyanSaxe No estoy de acuerdo. Me resultaría mucho más tranquilizador llamar a una función de biblioteca que volver a implementarla yo mismo. Por ejemplo, escribí en .sum()lugar de .mean()primero por error. Además, supongo que esta función se usa tanto que no veo ninguna razón por la que no debería estar disponible como función de biblioteca.
siamii
1
@siamii: Entiendo que 100%, solo estaba especulando sobre la razón por la cual este tipo de función puede no ser descuidada. Si es así, parece que no puedo encontrarlo
Ryan Saxe
1
Para las personas que intentaron esto y no funcionó: si predictionsy targetsson, por ejemplo, de tipo, int16el cuadrado podría desbordarse (dando números negativos). Por lo tanto, es posible que necesite un .astype('int')o .astype('double')antes de usar el cuadrado, como np.sqrt(((predictions - targets).astype('double') ** 2).mean()).
John
Otra ventaja de tener esto en sklearn es que las implementaciones de sklearn tienen mucho código de placa de caldera adicional para garantizar que las matrices tengan la misma forma, e incluye los parámetros de pesos y también maneja matrices multidimensionales y diferentes 'me gusta' de matrices. Hacer todo lo que convierte esto en un problema mucho más complejo
David Waterworth

Respuestas:

214

sklearn.metricsTiene una mean_squared_errorfunción. El RMSE es solo la raíz cuadrada de lo que devuelve.

from sklearn.metrics import mean_squared_error
from math import sqrt

rms = sqrt(mean_squared_error(y_actual, y_predicted))
Greg
fuente
3
mean_squared_erroren sklearn.metricsahora soporta parámetro adicional: squared- "Si devuelve True MSE valor, si se devuelve False valor RMSE."
Daddy32
132

¿Qué es el RMSE? También conocido como MSE, RMD o RMS. ¿Qué problema soluciona?

Si comprende RMSE: (error cuadrático medio cuadrático), MSE: (error cuadrático medio) RMD (desviación cuadrática media cuadrática) y RMS: (cuadrático medio cuadrático), entonces solicitar una biblioteca para calcular esto es una ingeniería innecesaria . Todas estas métricas son una sola línea de código de Python con un máximo de 2 pulgadas de largo. Las tres métricas rmse, mse, rmd y rms son, en su núcleo, conceptualmente idénticas.

RMSE responde a la pregunta: "¿Qué tan similares, en promedio, son los números en list1a list2?". Las dos listas deben ser del mismo tamaño. Quiero "eliminar el ruido entre cualquiera de los dos elementos dados, eliminar el tamaño de los datos recopilados y obtener una sensación única de cambio en el tiempo".

Intuición y ELI5 para RMSE:

Imagina que estás aprendiendo a lanzar dardos a un tablero de dardos. Todos los días practicas durante una hora. Desea saber si está mejorando o empeorando. Entonces, cada día haces 10 tiros y mides la distancia entre la diana y donde golpeó tu dardo.

Haces una lista de esos números list1. Use el error cuadrático medio entre las distancias en el día 1 y que list2contenga todos los ceros. Haga lo mismo en el segundo y enésimo día. Lo que obtendrá es un número único que, con suerte, disminuirá con el tiempo. Cuando su número RMSE es cero, siempre le da a la diana. Si el número rmse aumenta, empeora.

Ejemplo al calcular el error cuadrático medio en 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))

Que imprime:

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 notación matemática:

raíz de la desviación cuadrática media explicada

Leyenda de glifo: n es un entero positivo completo que representa el número de lanzamientos. irepresenta un contador entero positivo completo que enumera la suma. drepresenta las distancias ideales, que list2contienen todos los ceros en el ejemplo anterior. psignifica rendimiento, el list1en el ejemplo anterior. superíndice 2 significa numérico al cuadrado. d i es el i- ésimo índice de d. p i es el i- ésimo índice de p.

La respuesta se realiza en pequeños pasos para que se pueda entender:

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 ^

Cómo funciona cada paso de RMSE:

Restar un número de otro te da la distancia entre ellos.

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

Si multiplica cualquier número por sí mismo, el resultado siempre es positivo porque negativo por negativo es positivo:

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

Súmelos todos, pero espere, entonces una matriz con muchos elementos tendría un error mayor que una matriz pequeña, así que promítelos por la cantidad de elementos.

Pero espera, los cuadramos todos antes para forzarlos a ser positivos. Deshacer el daño con una raíz cuadrada!

Eso te deja con un solo número que representa, en promedio, la distancia entre cada valor de list1 a su valor de elemento correspondiente de list2.

Si el valor RMSE disminuye con el tiempo, estamos contentos porque la varianza está disminuyendo.

RMSE no es la estrategia de ajuste de línea más precisa, los mínimos cuadrados totales son:

El error cuadrático medio de la raíz mide la distancia vertical entre el punto y la línea, por lo que si sus datos tienen forma de plátano, plano cerca de la parte inferior y empinado cerca de la parte superior, el RMSE informará distancias mayores a puntos altos, pero distancias cortas a puntos bajos cuando en realidad las distancias son equivalentes. Esto provoca un sesgo donde la línea prefiere estar más cerca de los puntos altos que bajos.

Si esto es un problema, el método de mínimos cuadrados totales arregla esto: https://mubaris.com/posts/linear-regression

Gotchas que pueden romper esta función RMSE:

Si hay valores nulos o infinitos en cualquiera de las listas de entrada, entonces el valor de salida rmse no tendrá sentido. Hay tres estrategias para lidiar con nulos / valores perdidos / infinitos en cualquiera de las listas: ignore ese componente, ajústelo a cero o agregue una mejor suposición o un ruido aleatorio uniforme a todos los pasos de tiempo. Cada remedio tiene sus ventajas y desventajas, según lo que signifiquen sus datos. En general, se prefiere ignorar cualquier componente con un valor perdido, pero esto sesga el RMSE hacia cero, lo que hace pensar que el rendimiento ha mejorado cuando realmente no lo ha hecho. Se podría preferir agregar ruido aleatorio en una mejor aproximación si faltan muchos valores.

Para garantizar la corrección relativa de la salida RMSE, debe eliminar todos los nulos / infinitos de la entrada.

RMSE tiene tolerancia cero para los puntos de datos atípicos que no pertenecen

La raíz cuadrática del error cuadrático medio se basa en que todos los datos son correctos y todos se cuentan como iguales. Eso significa que un punto perdido en el campo izquierdo arruinará totalmente todo el cálculo. Para manejar puntos de datos atípicos y descartar su tremenda influencia después de cierto umbral, vea Estimadores robustos que incorporan un umbral para el descarte de valores atípicos.

Eric Leschinski
fuente
3
Sí, función simple. Pero si lo necesita en el día a día, es bueno tener una solución correcta disponible en algún lugar para que no tenga que volver a implementarla en todo momento; )
lógico x 2
@ eric-leschinski, agradecería que pudieras echar un vistazo a esto: stackoverflow.com/questions/45173451/…
Desta Haileselassie Hagos
1
Definitivamente es una señal de esta generación que la gente pide y señala bibliotecas de varios gigabytes; requiere una descarga de red de 3 a 20 minutos y luego la instalación de la CPU de inclinación completa, cuando todo lo que realmente necesita es aproximadamente 3 líneas de código que caben en 400 bytes. Si solicita una biblioteca para un trabajo que se puede comprimir en una línea de código de aproximadamente 90 caracteres de ancho, entonces está otorgando licencia para que las personas abusen de usted con instalaciones de 3, 10 y pronto de 50 GB que son 99.9999 % hinchazón Esto no es cirugía de cohetes. Su calculadora con energía solar fabricada en 1978 con un procesador de 740 hz puede hacer RMSE.
Eric Leschinski
22

¿Esto es probablemente más rápido ?:

n = len(predictions)
rmse = np.linalg.norm(predictions - targets) / np.sqrt(n)
Coca-Cola
fuente
18

En scikit-learn 0.22.0 puede pasar mean_squared_error()el argumento squared=Falsepara devolver el RMSE.

from sklearn.metrics import mean_squared_error

mean_squared_error(y_actual, y_predicted, squared=False)
jeffhale
fuente
2
Esta es una nueva característica y sería mejor si la usáramos.
Ravi G
9

En caso de que alguien encuentre este hilo en 2019, hay una biblioteca llamada ml_metricsque está disponible sin preinstalación en los núcleos de Kaggle, bastante liviana y accesible pypi(se puede instalar fácil y rápidamente con pip install ml_metrics):

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

Tiene algunas otras métricas interesantes que no están disponibles en sklearn, como mapk.

Referencias

dataista
fuente
4

En realidad, escribí un montón de esos como funciones de utilidad para statsmodels

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

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

Principalmente uno o dos revestimientos y poca verificación de entrada, y principalmente destinados a obtener fácilmente algunas estadísticas al comparar matrices. Pero tienen pruebas unitarias para los argumentos del eje, porque ahí es donde a veces cometo errores descuidados.

Josef
fuente
3

O simplemente usando solo las funciones NumPy:

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

Dónde:

  • y es mi objetivo
  • y_pred es mi predicción

Tenga en cuenta que rmse(y, y_pred)==rmse(y_pred, y)debido a la función cuadrada.

KeyMaker00
fuente
3

No puede encontrar la función RMSE directamente en SKLearn. Pero, en lugar de hacer sqrt manualmente, hay otra forma estándar de usar sklearn. Aparentemente, el propio mean_squared_error de Sklearn contiene un parámetro llamado "cuadrado" con el valor predeterminado como verdadero. Si lo configuramos como falso, la misma función devolverá RMSE en lugar de MSE.

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

Aquí hay un código de ejemplo que calcula el RMSE entre dos formatos de archivo de polígono PLY. Utiliza tanto la ml_metricslib como la 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
fuente
-1
  1. No, hay una biblioteca Scikit Learn para el aprendizaje automático y puede emplearse fácilmente utilizando el lenguaje Python. Tiene la función de error cuadrático medio que estoy compartiendo el siguiente enlace:

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

  1. La función se denomina mean_squared_error como se indica a continuación, donde y_true serían valores de clase reales para las tuplas de datos y y_pred serían los valores predichos, predichos por el algoritmo de aprendizaje automático que está utilizando:

mean_squared_error (y_true, y_pred)

  1. Tiene que modificarlo para obtener RMSE (usando la función sqrt usando Python). Este proceso se describe en este enlace: https://www.codeastar.com/regression-model-rmsd/

Entonces, el código final sería algo como:

de sklearn.metrics import mean_squared_error de math import sqrt

RMSD = sqrt (mean_squared_error (testing_y, predicción))

imprimir (RMSD)

Usman Zafar
fuente