[英]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.