There was a recent blog post on plotting estimated values \((\hat{y})\) versus actual values \((y)\) here.
The premise is to plot the residuals as a function of model prediction, and comparing them to the line \(y = 0\), using a smoothing curve through the residuals. The idea is that for a well-fit model, the smoothing curve should approximately lie on the line \(y = 0\). This is true not only for linear models, but for any model that captures most of the explainable variance, and for which the unexplainable variance (the noise) is IID and zero mean.
If the residuals aren’t zero mean independently of the model’s predictions, then either you are missing some explanatory variables, or your model does not have the correct structure, or an appropriate inductive bias.
The following examples demonstrate NNS.reg() residuals to have 0 mean as an artifact of the quadrant partitioning method. We compare NNS to a basic linear regression and a nonlinear kernel regression.
#require(devtools); install_github('OVVO-Financial/NNS', ref = "NNS-Beta-Version")
library(NNS)
library(ggplot2)
library(np)
options(np.messages = FALSE)
set.seed(34524)
N = 100
x1 = runif(N)
x2 = runif(N)
noise = 0.25*rnorm(N)
y = x1 + x2 + noise
qf = data.frame(x1=x1, x2=x2, y=y)
model = lm(y~x1+x2, data=qf)
qf$pred = predict(model, newdata=qf)
qf$residual = with(qf, y-pred)
nns_model = NNS.reg(qf[, 1:2], qf$y, residual.plot = FALSE, dist = "L2")$Fitted.xy
nns_cross_val = NNS.stack(qf[, 1:2], qf$y, IVs.test = qf[, 1:2], method = 1, dist = "L2")$stack
nns_cv_resid = nns_cross_val - qf$y
nns_cv = cbind.data.frame(y.hat = nns_cross_val, residuals = nns_cv_resid, y = qf$y)
bw = npregbw(xdat=qf[,1:2],ydat=qf$y)
np_model = npreg(bws = bw, residuals = TRUE)
np = data.frame(cbind(mean=np_model$mean, resid=np_model$resid))
# standard residual plot
ggplot(qf, aes(x=pred, y=residual)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "linear model and process")
ggplot(nns_model, aes(x=y.hat, y=residuals)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "NNS model and process")
ggplot(nns_cv, aes(x=y.hat, y=residuals)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "NNS CV model and process")
ggplot(np, aes(x=mean, y=resid)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "np model and process")
ggplot(qf, aes(x=pred, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard prediction plot")
ggplot(nns_model, aes(x=y.hat, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("NNS Standard prediction plot")
ggplot(nns_cv, aes(x=y.hat, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("NNS CV Standard prediction plot")
ggplot(np, aes(x=mean, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("np Standard prediction plot")
x3 = runif(N)
y = x1 + x2 + 2*x3^2 + 0.25*noise
qf = data.frame(x1=x1, x2=x2, x3=x3, y=y)
# Fit a linear regression model
model2 = lm(y~x1+x2+x3, data=qf)
# summary(model2)
qf$pred = predict(model2, newdata=qf)
qf$residual = with(qf, y-pred)
nns_model2 = NNS.reg(qf[,1:3], qf$y, residual.plot = FALSE, dist = "L2")$Fitted.xy
nns_cross_val_2 = NNS.stack(qf[, 1:3], qf$y, IVs.test = qf[, 1:3], method = 1, dist = "L2")$stack
nns_cv_resid_2 = nns_cross_val_2 - qf$y
nns_cv_2 = cbind.data.frame(y.hat = nns_cross_val_2, residuals = nns_cv_resid_2, y = qf$y)
bw = npregbw(xdat=qf[,1:3],ydat=qf$y)
np_model2 = npreg(bws = bw, residuals = TRUE)
np2 = data.frame(cbind(mean=np_model2$mean, resid=np_model2$resid))
ggplot(qf, aes(x=pred, y=residual)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "linear model, quadratic process")
ggplot(nns_model2, aes(x=y.hat, y=residuals)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("NNS Standard residual plot",
subtitle = "NNS model and process")
ggplot(nns_cv_2, aes(x=y.hat, y=residuals)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard residual plot",
subtitle = "NNS CV model and process")
ggplot(np2, aes(x=mean, y=resid)) +
geom_point(alpha=0.5) + geom_hline(yintercept=0, color="red") +
geom_smooth(se=FALSE) +
ggtitle("np Standard residual plot",
subtitle = "np model and process")
ggplot(qf, aes(x=pred, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("Standard prediction plot")
ggplot(nns_model2, aes(x=y.hat, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("NNS Standard prediction plot")
ggplot(nns_cv_2, aes(x=y.hat, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("NNS CV Standard prediction plot")
ggplot(np2, aes(x=mean, y=y)) +
geom_point(alpha=0.5) + geom_abline(color="red") +
geom_smooth(se=FALSE) +
ggtitle("np Standard prediction plot")
4 Comments
NNS.regis not a black-box ML solution, rather,NNSprovides a theoretically sound solution to dynamically partitioning regressors, and finding conditional outputs from those partitions.NNSis not a one-trick pony, as it has been demonstrated to excel in time-series forecasting, nonlinear continuous regressions, and provide solutions for econometric applications. See the following examples:Classification Using NNS Clustering Analysishttps://ssrn.com/abstract=2864711NNS.boost vs. xgboosthttps://htmlpreview.github.io/?https://github.com/OVVO-Financial/NNS/blob/NNS-Beta-Version/examples/xgboost_example.htmlNNSForecasting Presentation Download the .pdf file here: https://ssrn.com/abstract=3382300NNSForecasting vs. KERAS LSTM Deep Learning View and download the .html file here: https://htmlpreview.github.io/?https://github.com/OVVO-Financial/NNS/blob/NNS-Beta-Version/examples/Sunspots_example.htmlThe 7 Reasons Most Econometric Investments Fail - NNS Contributions Towards SolutionsView and download the .html file here: https://htmlpreview.github.io/?https://github.com/OVVO-Financial/NNS/blob/NNS-Beta-Version/examples/7_Econometic_Reasons.htmlI look forward to further discussions and collaboration with those equally as passionate about these issues, and open to embracing alternative solutions. If you found this presentation interesting or useful, please feel free to reach out via e-mail: ovvo.financial.systems@gmail.com
Thanks for your interest!