R:找到产生最大 R 平方值的表达式的系数?
R: Finding the coefficients of an expression which produce the largest R-squared value?
假设我已经将数据输入到数据框中,如下所示:
df = data.frame(x = c(1,2,3,4,5,10,15,25,50),
y = c(.57,.75,.82,0.87,.89,.95,.97,.98,.99))
df
我希望适合表达式:
y = ((x/a)^b)/(1+(x/a)^b)
其中 a 和 b 是未知参数。
我通过猜测 a 和 b 的值绘制了点并画了一条拟合线:
library(ggplot2)
graph <- ggplot(df, aes(x=x, y=y))
graph <- graph + geom_point()
a = 0.50
b = 1.00
guesstimate <- function(x){((x/a)^b)/(1+(x/a)^b)}
graph <- graph + stat_function(fun = guesstimate)
graph
但是,我想找到 a 和 b 的值,它们创建了一个产生最高 R^2 平方值的表达式;即对数据的最佳数学拟合。
问题:
除了手动猜测 a 和 b 的值并用肉眼检查哪个最合适,有没有办法让 R 找到 'best' a 和 b 值以及提供 R 平方值向我确认所选的 a 和 b 值确实是最合适的?
您可以使用 nls
(non-linear 最小二乘)函数:
m1 = nls(y ~ (x/a)^b/(1+(x/a)^b), list(a=1, b=1), data=df)
summary(m1)
Formula: y ~ (x/a)^b/(1 + (x/a)^b)
Parameters:
Estimate Std. Error t value Pr(>|t|)
a 0.779291 0.009444 82.51 1.01e-11 ***
b 1.145174 0.012733 89.94 5.53e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.003086 on 7 degrees of freedom
Number of iterations to convergence: 4
Achieved convergence tolerance: 5.949e-08
ggplot(df, aes(x,y)) +
geom_point() +
geom_line(data=data.frame(x=seq(1,50,0.1), y=predict(m1, newdata=list(x=seq(1,50,0.1)))),
aes(x,y), colour="red")
nls
不提供 r-squared 值,因为如 this thread on R-help 中所述,r-squared 对于 non-linear 模型不一定有意义。然而,nls
确实找到了使残差最小化的参数值 sum-of-squares,因此从这个意义上说,这些参数为给定的数据和模型提供了最佳拟合。这并不意味着没有其他模型规格可以提供更好的拟合度,尽管在这种情况下模型拟合度几乎是完美的。
即使不明显,也可以在这里应用线性模型,只需使用基本代数即可。事实上,从 1/y = (1+(x/a)^b)/(x/a)^b
开始,稍加操作,您可以到达:
log(1/y - 1) = -b*log(x) + b*log(a)
这基本上是变量 Y = log(1/y - 1)
和 X = log(x)
的线性模型。从这里,您可以使用 lm
:
df2<-data.frame(Y = log(1/df$y - 1), X = log(df$x))
coeffs<-lm(Y ~ X, data=df2)$coefficients
a <- exp(-model[1]/model[2])
# 0.7491387
b <- -model[2]
#1.116111
与nls
.
获得的结果相似
假设我已经将数据输入到数据框中,如下所示:
df = data.frame(x = c(1,2,3,4,5,10,15,25,50),
y = c(.57,.75,.82,0.87,.89,.95,.97,.98,.99))
df
我希望适合表达式:
y = ((x/a)^b)/(1+(x/a)^b)
其中 a 和 b 是未知参数。
我通过猜测 a 和 b 的值绘制了点并画了一条拟合线:
library(ggplot2)
graph <- ggplot(df, aes(x=x, y=y))
graph <- graph + geom_point()
a = 0.50
b = 1.00
guesstimate <- function(x){((x/a)^b)/(1+(x/a)^b)}
graph <- graph + stat_function(fun = guesstimate)
graph
但是,我想找到 a 和 b 的值,它们创建了一个产生最高 R^2 平方值的表达式;即对数据的最佳数学拟合。
问题: 除了手动猜测 a 和 b 的值并用肉眼检查哪个最合适,有没有办法让 R 找到 'best' a 和 b 值以及提供 R 平方值向我确认所选的 a 和 b 值确实是最合适的?
您可以使用 nls
(non-linear 最小二乘)函数:
m1 = nls(y ~ (x/a)^b/(1+(x/a)^b), list(a=1, b=1), data=df)
summary(m1)
Formula: y ~ (x/a)^b/(1 + (x/a)^b) Parameters: Estimate Std. Error t value Pr(>|t|) a 0.779291 0.009444 82.51 1.01e-11 *** b 1.145174 0.012733 89.94 5.53e-12 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.003086 on 7 degrees of freedom Number of iterations to convergence: 4 Achieved convergence tolerance: 5.949e-08
ggplot(df, aes(x,y)) +
geom_point() +
geom_line(data=data.frame(x=seq(1,50,0.1), y=predict(m1, newdata=list(x=seq(1,50,0.1)))),
aes(x,y), colour="red")
nls
不提供 r-squared 值,因为如 this thread on R-help 中所述,r-squared 对于 non-linear 模型不一定有意义。然而,nls
确实找到了使残差最小化的参数值 sum-of-squares,因此从这个意义上说,这些参数为给定的数据和模型提供了最佳拟合。这并不意味着没有其他模型规格可以提供更好的拟合度,尽管在这种情况下模型拟合度几乎是完美的。
即使不明显,也可以在这里应用线性模型,只需使用基本代数即可。事实上,从 1/y = (1+(x/a)^b)/(x/a)^b
开始,稍加操作,您可以到达:
log(1/y - 1) = -b*log(x) + b*log(a)
这基本上是变量 Y = log(1/y - 1)
和 X = log(x)
的线性模型。从这里,您可以使用 lm
:
df2<-data.frame(Y = log(1/df$y - 1), X = log(df$x))
coeffs<-lm(Y ~ X, data=df2)$coefficients
a <- exp(-model[1]/model[2])
# 0.7491387
b <- -model[2]
#1.116111
与nls
.