One interpretation of what r2 is telling us about our regression models is how much better our model is from a simple statistical average. Since averages are not robust, we can potentially reformulate a robust r2 using medians (in the same way we use median absolute deviation as a robust measure of variability instead of standard deviation). If we do this, we get similar r2 values for normal behaving data and a better goodness-of-fit metric for robust models:
import numpy as np
def robust_r2_score(obs, exps):
"""
Formulation of a robust r2. in this case, we have a metric that tells us how
much better our model is than a median of our observations using median squared
deviation rather than variance.
Args:
obs: a sequence of observations
exps: a sequence of expected values from a model
"""
msdtot = lambda x: np.median((x-np.median(x))**2) # median squared deviation total
msderr = lambda x, x_hat: np.median((x-x_hat)**2) # median squared deviation err (or residual)
obs = np.asarray(obs)
exp = np.asarray(exps)
msd_res = msderr(obs, exp)
msd_tot = msdtot(obs)
return 1-(msd_res/msd_tot)
Just a thought. Wondering if other have tried something similar in practice? I have a similar pattern in this paper