in Uncategorized

Como escolher entre o RMSE e o RMSLE?

Existem inúmeros artigos descrevendo o RMSE e o RMSLE, mas aqui eu vou tentar ser o mais direto possível em relação ao que eu faço entre essas duas métricas.

Quando eu quero apenas ter a medida do erro em termos de viés e variância do modelo, sem considerar nenhum aspecto em relação às diferenças de magnitudes entre o que foi previsto (y_hat) e o que era o esperado na base de validação (y), eu uso o RMSE.

Exemplo: Uma previsão errada de {y=1, y_hat=2} vai entrar na média quadrática da mesma forma que {y=1000000, y_hat=1000500}; isso significa que a magnitude da segunda previsão não importa e que eu aceito que ela vai influenciar na média quadrática (no caso uma magnitude de 500x maior do que o primeiro erro).

Quando eu quero a mensuração do viés e da variância mas eu não quero penalizar erros que ocorram em magnitudes distintas, aí eu uso o RMSLE. Isto é, os erros são isolados dentro da mesma ordem de magnitude entre y_hat e y.

Usando o exemplo anterior, no caso de erro de {y=1000000, y_hat=1000500} o termo logaritmo do RMSLE vai realizar o ajuste entre y_hat e y e calcular a diferença dentro da mesma magnitude antes do cálculo da média quadrática. Isso significa que, mesmo com uma ordem de magnitude muito maior do que nos erros anteriores, o logaritmo fará a suavização desses erros desses “grandes números” retirando a magnitude na media quadrática.

Como de costume, o código está abaixo:

import pandas as pd
import math
import numpy as np
# Create dataframe
df_preds = pd.DataFrame(columns=['y', 'y_hat'])
# Fill it
df_preds.loc[len(df_preds)] = [1, 1]
df_preds.loc[len(df_preds)] = [2, 3]
df_preds.loc[len(df_preds)] = [50, 55]
df_preds.loc[len(df_preds)] = [500, 502]
df_preds.loc[len(df_preds)] = [1000000, 1000005]
# Check
df_preds
# y y_hat
# 0 1 1
# 1 2 3
# 2 50 55
# 3 500 502
# 4 1000000 1000005
# Create functions
def rmse(predictions, targets):
'''Source: https://stackoverflow.com/questions/17197492/is-there-a-library-function-for-root-mean-square-error-rmse-in-python'''
return np.sqrt(((predictions targets) ** 2).mean())
def rmsle(predict, target):
'''Source: https://towardsdatascience.com/metrics-and-python-850b60710e0c'''
total = 0
for k in range(len(predict)):
LPred= np.log1p(predict[k]+1)
LTarg = np.log1p(target[k] + 1)
if not (math.isnan(LPred)) and not (math.isnan(LTarg)):
total = total + ((LPredLTarg) **2)
total = total / len(predict)
return np.sqrt(total)
# Check data before executiion
df_preds
# y y_hat
# 0 1 1
# 1 2 3
# 2 50 55
# 3 500 502
# 4 1000000 1000005
# Get stats
print ('RMSE: ' + str(rmse(df_preds['y_hat'].values, df_preds['y'].values)))
print ('RMSLE: ' + str(rmsle(df_preds['y_hat'].values, df_preds['y'].values)))
# RMSE: 3.3166247903554
# RMSLE: 0.1079235658917167
# Increase the error in the biggest number in terms of magnitude (from 5 to 500)
# Create dataframe
df_preds = pd.DataFrame(columns=['y', 'y_hat'])
# Fill it
df_preds.loc[len(df_preds)] = [1, 1]
df_preds.loc[len(df_preds)] = [2, 3]
df_preds.loc[len(df_preds)] = [50, 55]
df_preds.loc[len(df_preds)] = [500, 502]
df_preds.loc[len(df_preds)] = [1000000, 1000500]
# Check
df_preds
# y y_hat
# 0 1 1
# 1 2 3
# 2 50 55
# 3 500 502
# 4 1000000 1000500
# The RMSE exploded, but the RMSLE stayed the same due to not penalize the error in bigger magnitude predictions
print ('RMSE: ' + str(rmse(df_preds['y_hat'].values, df_preds['y'].values)))
print ('RMSLE: ' + str(rmsle(df_preds['y_hat'].values, df_preds['y'].values)))
# RMSE: 223.6202137553759
# RMSLE: 0.10792379739703087

Write a Comment

Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Webmentions

  • Accountability, Core Machine Learning e Machine Learning Operations – Flávio Clésio

    […] o Scikit-Learn como dependência apenas para calcular o RMSE, ao invés de escrever uma função em numpy sozinho já resolveria a coisa toda. O seu code review pegaria este débito de […]