繁体   English   中英

计算非线性最小二乘拟合的 R^2

[英]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调整后的版本。 如果yyfitted走向相同的方向,这将是常规线性模型报告的R2adjusted R2值。 对我来说,这至少是完全合理的,所以我不同意完全拒绝pseudo R2值对nls模型的有用性,因为上面的答案似乎暗示了这一点。

对于非正常错误结构(例如,如果您使用具有非正常错误的 GAM), McFadden pseudo R2的定义类似

1-residual deviance/null deviance

有关一些有用的讨论,请参阅此处此处

非线性模型的另一个准 R 平方是对实际 y 值和预测 y 值之间的相关性进行平方。 对于线性模型,这是常规的 R 平方。

作为此问题的替代方案,我多次使用以下程序:

  1. 使用 nls 函数计算数据拟合
  2. 使用结果模型进行预测
  3. 根据模型预测的值跟踪(绘图...)数据(如果模型良好,点应靠近二等分线)。
  4. 计算线性回归的 R2。

向所有人致以最良好的祝愿。 帕特里克。

使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM