我尝试了非线性最小二乘法,但是,我想尝试通过试验和错误, 使用一个矢量的值为a,和另一个为b,然后绘制所有的替代品 混合这个值,以选择一个更好的配合。
library(readxl)
library(ggplot2)
x <- c(52.67, 46.80, 41.74, 40.45)
y <- c(1.73, 1.84, 1.79, 1.45)
df <- data.frame(x,y)
ggplot(data = df, aes(x, y))+
geom_point()+
stat_smooth(method="nls",
se=FALSE,
formula = y ~ (a*b*x)/(1+(b*x)),
method.args = list(start = c(a=2.86, b=0.032)))
不知道你是不是对输出的东西有点不信任 nls
,想着也许自己能找到更适合的?
这里有一个方法,至少可以让你更好地感受到不同价值观所创造的契合度。a
和 b
. 这个想法是,我们创建一个包含所有的 a
X轴上的所有数值,以及所有的 b
在y轴上。对于每一对 a
和 b
我们计算出所得到的曲线与我们的数据有多接近(通过取对数平方和)。如果拟合效果好,我们用亮色来表示,如果拟合效果不好,我们用深色来表示。这使我们可以看到好的拟合的组合类型--实际上是参数的热图。
# Our actual data, put in a data frame:
df <- data.frame(x = c(52.67, 46.80, 41.74, 40.45), y = c(1.73, 1.84, 1.79, 1.45))
# Create a grid of all a and b values we want to compare
a <- seq(-5, 10, length.out = 200)
b <- seq(0, 0.5, length.out = 100)
all_mixtures <- setNames(expand.grid(a, b), c("a", "b"))
# Get the sum of squares for each point:
all_mixtures$ss <- apply(all_mixtures, 1, function(i) {
log(sum((i[1] * i[2] * df$x / (1 + i[2] * df$x) - y)^2))
})
现在我们绘制热图。
p <- ggplot(all_mixtures, aes(a, b, fill = ss)) +
geom_tile() +
scale_fill_gradientn(colours = c("white", "yellow", "red", "blue"))
p
很明显,最佳的一对 a
和 b
位于白线上的某处。
现在让我们看看 nls
认为是最佳组合 a
和 b
是。
p + geom_point(aes(x= 2.8312323, y = 0.0334379), size = 5)
看起来它在白线的 "弯曲 "处找到了最佳位置,这可能是你所猜测的。
看来如果你偏离了这条白线,你的拟合度会更差,而且你在白线上也找不到更好的地方。
相信 nls
. 是的,拟合度看起来不是很好,但那只是因为数据不能很好地拟合这个特殊的公式,无论你如何设置它的参数。如果你的模型必须是这种形式,而这些是你的数据,这就是你要得到的最好的拟合。
什么才是更好的位呢?从数学上讲,最佳拟合度就是优化了一个拟合度指标。我们来获取参数 a
和 b
最小化偏差的平方和(最小二乘法)。
首先,定义你的度量 (least_squares
下)。)
x <- c(52.67, 46.80, 41.74, 40.45)
y <- c(1.73, 1.84, 1.79, 1.45)
y_hat <- function(x, a, b){
a*b*x/(1 + b*x)
}
least_squares <- function(par, y, x){
sum((y - y_hat(x, par[1], par[2]))^2)
}
在这之后,我们将度量衡最小化w.r.t a
和 b
. 人们可以使用R机械进行多变量优化(如。optim
)对其进行。
optim(c(2.86, 0.032), least_squares, y=y, x=x)
从而得到参数的最优值。
$par
[1] 2.8312323 0.0334379
这里: c(2.86, 0.032)
是对参数值的初始猜测。您可以根据您的需要自由定义您自己的度量标准(例如,绝对偏差之和,最小二乘的加权和等),并对其进行优化。您可以玩弄设置,但考虑到这个例子非常简单,您不太可能对相同的优化度量得出不同的结果。