[英]Calculating R^2 for a nonlinear least squares fit
假设我有x
值、 y
值和预期 y 值f
(来自一些非线性最佳拟合曲线)。
如何在 R 中计算 R^2? 请注意,此函数不是线性模型,而是非线性最小二乘 ( nls
) 拟合,因此不是lm
拟合。
您只需使用lm
函数来拟合线性模型:
x = runif(100)
y = runif(100)
spam = summary(lm(x~y))
> spam$r.squared
[1] 0.0008532386
请注意,r 平方不是为非线性模型定义的,或者至少非常棘手,引用自 R-help :
在 R 中拟合的 nls 模型不提供 r 平方是有充分理由的 - r 平方对于一般的 nls 模型没有意义。
r 平方的一种思考方式是将拟合模型的残差平方和与仅由常数组成的平凡模型的残差平方和进行比较。 在处理 nls 模型时,您不能保证这是嵌套模型的比较。 如果模型不是嵌套的,那么这种比较就没有太大意义。
所以答案是,您可能一开始就不想这样做。
如果您需要同行评审的证据,请参阅本文示例; 并不是说您无法计算 R^2 值,只是它可能与线性模型情况下的含义不同/具有相同的理想属性。
听起来 f 是您的预测值。 所以从它们到实际值的距离除以 n * y 的方差
所以像
1-sum((yf)^2)/(length(y)*var(y))
应该给你一个准 rsquared 值,只要你的模型相当接近线性模型并且 n 非常大。
作为对所问问题的直接回答(而不是争论 R2/伪 R2 没有用), rcompanion
包中的nagelkerke
函数将报告 McFadden、Cox 和Snell 和 Nagelkerke,例如
require(nls)
data(BrendonSmall)
quadplat = function(x, a, b, clx) {
ifelse(x < clx, a + b * x + (-0.5*b/clx) * x * x,
a + b * clx + (-0.5*b/clx) * clx * clx)}
model = nls(Sodium ~ quadplat(Calories, a, b, clx),
data = BrendonSmall,
start = list(a = 519,
b = 0.359,
clx = 2304))
nullfunct = function(x, m){m}
null.model = nls(Sodium ~ nullfunct(Calories, m),
data = BrendonSmall,
start = list(m = 1346))
nagelkerke(model, null=null.model)
soilphysics
包还报告了 Efron 的伪 R2 和nls
模型的调整伪 R2 值为 1 - RSS/TSS:
pred <- predict(model)
n <- length(pred)
res <- resid(model)
w <- weights(model)
if (is.null(w)) w <- rep(1, n)
rss <- sum(w * res ^ 2)
resp <- pred + res
center <- weighted.mean(resp, w)
r.df <- summary(model)$df[2]
int.df <- 1
tss <- sum(w * (resp - center)^2)
r.sq <- 1 - rss/tss
adj.r.sq <- 1 - (1 - r.sq) * (n - int.df) / r.df
out <- list(pseudo.R.squared = r.sq,
adj.R.squared = adj.r.sq)
这也是由rcompanion
包中的accuracy
函数计算的pseudo R2
。 基本上,这个 R2 衡量的是你的合身程度比你只画一条水平线穿过它们好多少。 如果您的空模型是允许仅截取模型的模型,则这对于nls
模型是有意义的。 同样对于特定的其他非线性模型,它也有意义。 例如,对于使用严格增加的样条(样条项中的 bs="mpi")的骗局模型,最坏可能情况(例如,您的数据严格减少)的拟合模型将是一条平坦线,因此会导致R2
为零。 调整后的 R2 也会惩罚具有更高拟合参数 nrs 的模型。 使用调整后的 R2 值已经解决了上面链接的论文的许多批评, http ://www.ncbi.nlm.nih.gov/pmc/articles/PMC2892436/(除了如果有人发誓使用信息标准来做模型选择问题变成了使用哪个 - AIC、BIC、EBIC、AICc、QIC 等)。
只是使用
r.sq <- max(cor(y,yfitted),0)^2
adj.r.sq <- 1 - (1 - r.sq) * (n - int.df) / r.df
我认为如果你有正常的高斯误差也有意义 - 即观察到的和拟合的 y 之间的相关性(裁剪为零,因此负关系意味着零预测能力)平方,然后调整拟合参数的 nr调整后的版本。 如果y
和yfitted
走向相同的方向,这将是常规线性模型报告的R2
和adjusted R2
值。 对我来说,这至少是完全合理的,所以我不同意完全拒绝pseudo R2
值对nls
模型的有用性,因为上面的答案似乎暗示了这一点。
对于非正常错误结构(例如,如果您使用具有非正常错误的 GAM), McFadden pseudo R2
的定义类似
1-residual deviance/null deviance
非线性模型的另一个准 R 平方是对实际 y 值和预测 y 值之间的相关性进行平方。 对于线性模型,这是常规的 R 平方。
作为此问题的替代方案,我多次使用以下程序:
向所有人致以最良好的祝愿。 帕特里克。
modelr
包modelr::rsquare(nls_model, data)
nls_model <- nls(mpg ~ a / wt + b, data = mtcars, start = list(a = 40, b = 4))
modelr::rsquare(nls_model, mtcars)
# 0.794
这与 Tom 在rcompanion
资源中描述的更长的方式基本相同。
nagelkerke
函数的更长的路nullfunct <- function(x, m){m}
null_model <- nls(mpg ~ nullfunct(wt, m),
data = mtcars,
start = list(m = mean(mtcars$mpg)))
nagelkerke(nls_model, null_model)[2]
# 0.794 or 0.796
lm(mpg ~ predict(nls_model), data = mtcars) %>% broom::glance()
# 0.795
正如他们所说,这只是一个近似值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.