多项式近似比
Ratio of polynomials approximation
我正在尝试将多项式拟合到我的数据集,看起来像这样(完整数据集位于 post 的末尾):
理论预测曲线的公式为:
看起来像这样(x 介于 0 和 1 之间):
当我尝试通过以下方式在 R 中制作线性模型时:
mod <- lm(y ~ poly(x, 2, raw=TRUE)/poly(x, 2))
我得到以下曲线:
这与我的预期大不相同。您是否知道如何根据这些数据拟合一条新曲线,使其与理论预测的曲线相似?另外,它应该只有一个最小值。
完整数据集:
x 值向量:
x <- c(0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12,
0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25,
0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38,
0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51,
0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64,
0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77,
0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90,
0.91, 0.92, 0.93, 0.94, 0.95)
y 值向量:
y <- c(4.104, 4.444, 4.432, 4.334, 4.285, 4.058, 3.901, 4.382,
4.258, 4.158, 3.688, 3.826, 3.724, 3.867, 3.811, 3.550, 3.736, 3.591,
3.566, 3.566, 3.518, 3.581, 3.505, 3.454, 3.529, 3.444, 3.501, 3.493,
3.362, 3.504, 3.365, 3.348, 3.371, 3.389, 3.506, 3.310, 3.578, 3.497,
3.302, 3.530, 3.593, 3.630, 3.420, 3.467, 3.656, 3.644, 3.715, 3.698,
3.807, 3.836, 3.826, 4.017, 3.942, 4.208, 3.959, 3.856, 4.157, 4.312,
4.349, 4.286, 4.483, 4.599, 4.395, 4.811, 4.887, 4.885, 5.286, 5.422,
5.527, 5.467, 5.749, 5.980, 6.242, 6.314, 6.587, 6.790, 7.183, 7.450,
7.487, 8.566, 7.946, 9.078, 9.308, 10.267, 10.738, 11.922, 12.178, 13.243,
15.627, 16.308, 19.246, 22.022, 25.223, 29.752)
既然你已经有了理论上的预测,你似乎不需要新的模型,它实际上只是一个绘图任务:
png(); plot(y~x)
lines(x,mod,col="blue")
dev.off()
您不能期望 lm
对非线性问题产生很好的近似。该理论表达式中涉及 x 的分母使其具有固有的非线性。
使用nls
拟合非线性模型。请注意,模型公式并非如问题中所示那样唯一定义,因为如果我们将所有系数乘以任何数字,结果仍将给出相同的预测。为了避免这种情况,我们需要固定一个系数。第一次尝试使用问题中显示的系数作为起始值(固定一个除外)但失败了,因此尝试删除 C 并将得到的系数输入到 C = 1
的第二次拟合中。
st <- list(a = 43, b = -14, c = 25, B = 18)
fm <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x), start = st)
fm2 <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), start = c(coef(fm), C = 1))
plot(y ~ x)
lines(fitted(fm2) ~ x, col = "red")
(图表后续)
注意:这里是一个使用nls2
随机搜索获取起始值的例子。我们假设每个系数都在 -50 和 50 之间。
library(nls2)
set.seed(123) # for reproducibility
v <- c(a = 50, b = 50, c = 50, B = 50, C = 50)
st0 <- as.data.frame(rbind(-v, v))
fm0 <- nls2(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), start = st0,
alg = "random", control = list(maxiter = 1000))
fm3 <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), st = coef(fm0))
我正在尝试将多项式拟合到我的数据集,看起来像这样(完整数据集位于 post 的末尾):
理论预测曲线的公式为:
看起来像这样(x 介于 0 和 1 之间):
当我尝试通过以下方式在 R 中制作线性模型时:
mod <- lm(y ~ poly(x, 2, raw=TRUE)/poly(x, 2))
我得到以下曲线:
这与我的预期大不相同。您是否知道如何根据这些数据拟合一条新曲线,使其与理论预测的曲线相似?另外,它应该只有一个最小值。
完整数据集:
x 值向量:
x <- c(0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12,
0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25,
0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38,
0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51,
0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64,
0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77,
0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90,
0.91, 0.92, 0.93, 0.94, 0.95)
y 值向量:
y <- c(4.104, 4.444, 4.432, 4.334, 4.285, 4.058, 3.901, 4.382,
4.258, 4.158, 3.688, 3.826, 3.724, 3.867, 3.811, 3.550, 3.736, 3.591,
3.566, 3.566, 3.518, 3.581, 3.505, 3.454, 3.529, 3.444, 3.501, 3.493,
3.362, 3.504, 3.365, 3.348, 3.371, 3.389, 3.506, 3.310, 3.578, 3.497,
3.302, 3.530, 3.593, 3.630, 3.420, 3.467, 3.656, 3.644, 3.715, 3.698,
3.807, 3.836, 3.826, 4.017, 3.942, 4.208, 3.959, 3.856, 4.157, 4.312,
4.349, 4.286, 4.483, 4.599, 4.395, 4.811, 4.887, 4.885, 5.286, 5.422,
5.527, 5.467, 5.749, 5.980, 6.242, 6.314, 6.587, 6.790, 7.183, 7.450,
7.487, 8.566, 7.946, 9.078, 9.308, 10.267, 10.738, 11.922, 12.178, 13.243,
15.627, 16.308, 19.246, 22.022, 25.223, 29.752)
既然你已经有了理论上的预测,你似乎不需要新的模型,它实际上只是一个绘图任务:
png(); plot(y~x)
lines(x,mod,col="blue")
dev.off()
您不能期望 lm
对非线性问题产生很好的近似。该理论表达式中涉及 x 的分母使其具有固有的非线性。
使用nls
拟合非线性模型。请注意,模型公式并非如问题中所示那样唯一定义,因为如果我们将所有系数乘以任何数字,结果仍将给出相同的预测。为了避免这种情况,我们需要固定一个系数。第一次尝试使用问题中显示的系数作为起始值(固定一个除外)但失败了,因此尝试删除 C 并将得到的系数输入到 C = 1
的第二次拟合中。
st <- list(a = 43, b = -14, c = 25, B = 18)
fm <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x), start = st)
fm2 <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), start = c(coef(fm), C = 1))
plot(y ~ x)
lines(fitted(fm2) ~ x, col = "red")
(图表后续)
注意:这里是一个使用nls2
随机搜索获取起始值的例子。我们假设每个系数都在 -50 和 50 之间。
library(nls2)
set.seed(123) # for reproducibility
v <- c(a = 50, b = 50, c = 50, B = 50, C = 50)
st0 <- as.data.frame(rbind(-v, v))
fm0 <- nls2(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), start = st0,
alg = "random", control = list(maxiter = 1000))
fm3 <- nls(y ~ (a + b * x + c * x^2) / (9 + B * x + C * x^2), st = coef(fm0))