Existe uma função de biblioteca para Root Mean Square Error (RMSE) em python?

158

Eu sei que eu poderia implementar uma função de erro quadrático médio raiz como esta:

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

O que estou procurando se essa função rmse for implementada em uma biblioteca em algum lugar, talvez em scipy ou scikit-learn?

siamii
fonte
5
você escreveu a função ali. Provavelmente, se a função for simples de escrever, ela não estará em uma biblioteca. é melhor criar um diretor chamado módulos e apenas colocando funções úteis nele e adicioná-lo ao seu caminho
Ryan Saxe
14
@RyanSaxe Eu discordo. Eu acharia muito mais reconfortante chamar uma função de biblioteca do que reimplementá-la. Por exemplo, escrevi em .sum()vez de .mean()primeiro por engano. Além disso, suponho que essa função seja usada tanto que não vejo razão para que ela não deva estar disponível como uma função de biblioteca.
siamii
1
@siamii: Eu entendo que 100%, eu estava apenas especulando sobre o motivo pelo qual esse tipo de função pode não estar muito enganado. Se é que eu não consigo encontrá-lo
Ryan Saxe
1
Para as pessoas que tentaram isso e não funcionou: se predictionse targetspor exemplo são do tipo, int16o quadrado pode estourar (dando números negativos). Então, você pode precisar de um .astype('int')ou .astype('double')antes de usar o quadrado, como np.sqrt(((predictions - targets).astype('double') ** 2).mean()).
John
Outra vantagem de ter isso no sklearn é que as implementações do sklearn têm muitos códigos adicionais da placa da caldeira para garantir que as matrizes tenham a mesma forma, e inclua os parâmetros de pesos e também lide com matrizes multidimensionais e diferentes 'curtidas' de matrizes. Fazendo tudo o que transforma este em um problema muito mais complexo
Waterworth David

Respostas:

214

sklearn.metricstem uma mean_squared_errorfunção O RMSE é apenas a raiz quadrada do que quer que ele retorne.

from sklearn.metrics import mean_squared_error
from math import sqrt

rms = sqrt(mean_squared_error(y_actual, y_predicted))
Greg
fonte
3
mean_squared_errorno sklearn.metricsagora suporta parâmetro extra: squared- "Se True retornar valor MSE, se False retornar valor RMSE".
Daddy32
132

O que é o RMSE? Também conhecido como MSE, RMD ou RMS. Qual problema isso resolve?

Se você entende RMSE: (erro quadrático médio da raiz), MSE: (erro quadrático médio) RMD (desvio quadrático médio da raiz) e RMS: (quadrado quadrático médio da raiz), pedir uma biblioteca para calcular isso para você é um excesso de engenharia desnecessário . Todas essas métricas são uma única linha de código python com no máximo duas polegadas de comprimento. As três métricas rmse, mse, rmd e rms são conceitualmente idênticas.

RMSE responde à pergunta: "Como semelhante, em média, são os números em list1que list2?". As duas listas devem ter o mesmo tamanho. Quero "eliminar o ruído entre dois elementos, reduzir o tamanho dos dados coletados e obter um número único de alterações ao longo do tempo".

Intuição e ELI5 para RMSE:

Imagine que você está aprendendo a jogar dardos em um dardo. Todos os dias você pratica por uma hora. Você quer descobrir se está melhorando ou piorando. Então, todos os dias, você faz 10 jogadas e mede a distância entre o alvo e o local onde o seu dardo bate.

Você faz uma lista desses números list1. Use o erro médio quadrático da raiz entre as distâncias no dia 1 e a list2contendo todos os zeros. Faça o mesmo no segundo e no nono dias. O que você obterá é um número único que, esperançosamente, diminui com o tempo. Quando seu número RMSE é zero, você sempre bate em bullseyes. Se o número rmse aumentar, você está piorando.

Exemplo no cálculo do erro quadrático médio raiz no 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

A notação matemática:

desvio médio quadrático da raiz explicado

Legenda do glifo: n é um número inteiro positivo inteiro que representa o número de jogadas. irepresenta um contador inteiro positivo inteiro que enumera soma. drepresenta as distâncias ideais, list2contendo todos os zeros no exemplo acima. psignifica desempenho, list1no exemplo acima. sobrescrito 2 significa numérico ao quadrado. d i é o i-ésimo índice de d. p i é o i-ésimo índice de p.

O rmse é feito em pequenas etapas para que possa ser entendido:

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 ^

Como todas as etapas do RMSE funcionam:

Subtrair um número de outro fornece a distância entre eles.

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

Se você multiplicar qualquer número vezes, o resultado será sempre positivo porque os negativos são negativos:

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

Adicione todos eles, mas espere, então uma matriz com muitos elementos teria um erro maior que uma matriz pequena; portanto, calcule a média pelo número de elementos.

Mas espere, nós combinamos todos eles antes para forçá-los positivos. Desfazer o dano com uma raiz quadrada!

Isso deixa você com um único número que representa, em média, a distância entre cada valor da lista1 e o valor correspondente do elemento da lista2.

Se o valor RMSE diminuir ao longo do tempo, ficaremos felizes porque a variação está diminuindo.

O RMSE não é a estratégia de ajuste de linha mais precisa, o total de mínimos quadrados é:

O erro quadrático médio da raiz mede a distância vertical entre o ponto e a linha. Portanto, se seus dados tiverem o formato de uma banana, plana perto da parte inferior e íngreme perto da parte superior, o RMSE reportará maiores distâncias para pontos altos, mas distâncias curtas para pontos baixos quando de fato as distâncias são equivalentes. Isso causa uma inclinação onde a linha prefere estar mais próxima dos pontos alto do que baixo.

Se este for um problema, o método dos mínimos quadrados total corrige isso: https://mubaris.com/posts/linear-regression

Pegadinhas que podem quebrar essa função RMSE:

Se houver nulos ou infinito em qualquer lista de entrada, o valor rmse de saída não fará sentido. Existem três estratégias para lidar com valores nulos / valores ausentes / infinitos nas duas listas: ignore esse componente, zere-o ou adicione uma melhor estimativa ou um ruído aleatório uniforme a todos os timesteps. Cada remédio tem seus prós e contras, dependendo do significado dos seus dados. Em geral, é preferível ignorar qualquer componente com um valor ausente, mas isso leva o RMSE a zero, fazendo com que você pense que o desempenho melhorou quando realmente não. Adicionar ruído aleatório com uma melhor estimativa pode ser preferido se houver muitos valores ausentes.

Para garantir a relativa correção da saída do RMSE, você deve eliminar todos os nulos / infinitos da entrada.

O RMSE tem tolerância zero para pontos de dados externos que não pertencem

Os quadrados dos erros quadráticos médios da raiz baseiam-se em todos os dados corretos e todos são contados como iguais. Isso significa que um ponto perdido no campo esquerdo vai arruinar totalmente todo o cálculo. Para lidar com pontos de dados discrepantes e descartar sua tremenda influência após um certo limite, consulte Estimadores robustos que criam um limite para a discrepância de discrepantes.

Eric Leschinski
fonte
3
Sim, função simples. Mas se você precisar no dia-a-dia, é bom ter apenas uma solução correta disponível em algum lugar, para que você não precise reimplementá-la sempre; )
logic x 2
@ eric-leschinski, eu apreciaria se você pudesse dar uma olhada nisto: stackoverflow.com/questions/45173451/…
Desta Haileselassie Hagos
1
É definitivamente um sinal dessa geração que as pessoas solicitam e apontam para bibliotecas de tamanho de vários gigabytes; exigindo um download de rede de 3 a 20 minutos e a instalação completa da CPU, quando tudo o que você realmente precisa é de cerca de 3 linhas de código que cabem em 400 bytes. Se você solicitar uma biblioteca para um trabalho que possa ser compactado em uma linha de código 1, com cerca de 90 caracteres de largura, estará dando licença para as pessoas abusarem de você com instalações de 3, 10 e em breve 50 GB, com 99,9999 % inchaço. Isso não é cirurgia de foguete. Sua calculadora movida a energia solar, fabricada em 1978 com processador de 740hz, pode executar o RMSE.
Eric Leschinski 9/07/19
22

Provavelmente é mais rápido ?:

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

No scikit-learn 0.22.0, você pode passar mean_squared_error()o argumento squared=Falsepara retornar o RMSE.

from sklearn.metrics import mean_squared_error

mean_squared_error(y_actual, y_predicted, squared=False)
jeffhale
fonte
2
Este é um novo recurso e seria melhor se o usarmos.
Ravi G
9

Caso alguém encontre esse segmento em 2019, existe uma biblioteca chamada ml_metricsque está disponível sem pré-instalação nos kernels do Kaggle, bastante leve e acessível através pypi(pode ser instalada com facilidade e rapidez pip install ml_metrics):

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

Tem poucas outras métricas interessantes que não estão disponíveis no sklearn, como mapk.

Referências:

dataista
fonte
4

Na verdade, eu escrevi várias delas como funções utilitárias para o 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, um ou dois liners, sem pouca verificação de entrada, e principalmente destinado a obter facilmente algumas estatísticas ao comparar matrizes. Mas eles têm testes de unidade para os argumentos do eixo, porque é aí que às vezes eu cometo erros desleixados.

Josef
fonte
3

Ou simplesmente usando apenas as funções NumPy:

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

Onde:

  • y é meu alvo
  • y_pred é a minha previsão

Observe que, rmse(y, y_pred)==rmse(y_pred, y)devido à função quadrada.

KeyMaker00
fonte
3

Você não pode encontrar a função RMSE diretamente no SKLearn. Mas, em vez de executar manualmente o sqrt, existe outra maneira padrão de usar o sklearn. Aparentemente, o próprio mean_squared_error do Sklearn contém um parâmetro chamado "quadrado" com o valor padrão como true. Se o definirmos como false, a mesma função retornará RMSE em vez 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)
user12999612
fonte
0

Aqui está um código de exemplo que calcula o RMSE entre dois formatos de arquivo de polígono PLY. Ele usa a ml_metricslib e a 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
fonte
-1
  1. Não, existe uma biblioteca Scikit Learn para aprendizado de máquina e pode ser facilmente empregada usando a linguagem Python. Ele tem a função a para o erro médio quadrático, que estou compartilhando no link abaixo:

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

  1. A função é denominada mean_squared_error, conforme indicado abaixo, onde y_true seria valores reais de classe para as tuplas de dados e y_pred seriam os valores previstos, previstos pelo algoritmo de aprendizado de máquina que você está usando:

mean_squared_error (y_true, y_pred)

  1. Você deve modificá-lo para obter o RMSE (usando a função sqrt usando Python). Este processo é descrito neste link: https://www.codeastar.com/regression-model-rmsd/

Portanto, o código final seria algo como:

de sklearn.metrics import mean_squared_error de math import sqrt

RMSD = sqrt (mean_squared_error (testing_y, prediction))

impressão (RMSD)

Usman Zafar
fonte