收敛失败:达到迭代限制但未收敛 (10)
Convergence Failure: Iteration limit reached without convergence (10)
我在获取特定曲线以将数据拟合到 nls 模型时遇到一些困难。
这是数据的公式:
((b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4)))^(b3 / b4)
我使用带有随机算法的 nls2 包来查找初始值。
library(nls2)
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63)
b2 = c(0, 0.05)
b3 = c(0, 1)
b4 = c(0, 0.9)
fit <- nls2(eq,
data = .data,
start = values,
algorithm = "random",
control = mls.control(maxiter = 1000))
nls(eq, .data, start = coef(fit), alg = "port", lower = 0)
plot(.data)
值应该是:
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
然而,当我尝试 运行 代码时,我总是以错误消息结束:Convergence Failure: Iteration limit reached without convergence (10)
如何避免收敛失败错误?非常感谢任何帮助。谢谢。
0。 TLDR
你没有在nls
中设置lower
和upper
绑定,所以你没有得到收敛的结果。如果你设置它们,你会得到一个接近边界的结果。 看我上一段写的代码
其实,即使你设置了边界,由于数据质量不好(样本量小,不符合你的公式),也很难拟合出一个最优的接近真实 b1
、'b2'、'b3' 和 b4
的值。 查看非技术原因。
1。收敛失败的非技术原因
我认为您的代码是正确的,这种收敛失败是由于您的数据质量或公式指定错误造成的。
一般情况下,你很难用6个点估计出4个参数。如果您拥有非常适合您的模型的良好数据,nlm 将会收敛。在你的情况下,要么你的数据是错误的,要么你的公式规范偏差很大。
我画了一个图给你看:
代码
# generate a line using true parameters:b1,b2,b3,b4
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
x_points = seq(50,420,length.out = 200)
y_points = (b1 * ((b2 * x_points)^b4)) / (1 + ((b2 * x_points)^b4))^(b3 / b4)
# plot the function
plot(x = x_points ,y = y_points, type ='l',col ='black',lwd = 5,
xlim = c(min(yourdata$x)-5,max(yourdata$x)+5),
ylim = c(min(yourdata$y)-5,max(yourdata$y)+5))
# plot the data your got
points(yourdata$x,yourdata$y,cex = 2)
输出:
如果我们根据您的公式生成数据,我们可以很容易地拟合它们,如下所示:
## generate data
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
x <- runif(6,60,450)
y <- (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
data <- data.frame(x,y)
yourdata <- data.frame(x = c(409.56, 195.25, 60.53, 359.56, 188.79, 67.12),
y = c(39.76100, 20.11875, 7.23675, 41.01100, 20.28035, 7.07200))
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63),
b2 = c(0, 0.05),
b3 = c(0, 1),
b4 = c(0, 0.9))
fit <- nls2(eq,
data = data,
start = values,
algorithm = "random",
control = nls.control(maxiter = 1000))
nls(eq, data, start = coef(fit), alg = "port",
control = nls.control(maxiter = 1000,tol = 1e-05),
low = c(60,0,0,0),upper =c(63,0.05,1,0.9) ,trace = TRUE)
plot(x,y)
输出:
Nonlinear regression model
model: y ~ (b1 * ((b2 * x)^b4))/(1 + ((b2 * x)^b4))^(b3/b4)
data: data
b1 b2 b3 b4
62.2060 0.0438 0.9692 0.8693
residual sum-of-squares: 3.616e-24
Algorithm "port", convergence message: absolute function convergence (6)
另请注意,在上面,我只生成 6 个数字来拟合模型。如果你生成更多的数据,比如60,你会有更好的收敛性!
2.Technical原因
阅读 PORT 文档后,我认为这个错误可能意味着
- 梯度计算不正确
- 停止公差太紧
- 梯度在某些迭代附近不连续
而这些都可能与你的数据和训练任务(你的边界和公式)有关。
试试下面的代码,你会得到更好的结果:
代码:
yourdata <- data.frame(x = c(409.56, 195.25, 60.53, 359.56, 188.79, 67.12),
y = c(39.76100, 20.11875, 7.23675, 41.01100, 20.28035, 7.07200))
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63),
b2 = c(0, 0.05),
b3 = c(0, 1),
b4 = c(0, 0.9))
fit <- nls2(eq,
data = yourdata,
start = values,
algorithm = "random",
control = nls.control(maxiter = 1000))
nls(eq, yourdata, start = coef(fit), alg = "port",
control = nls.control(maxiter = 1000,tol = 1e-05),
low = c(60,0,0,0),upper =c(63,0.05,1,0.9) ,trace = TRUE)
plot(x,y)
输出:
Nonlinear regression model
model: y ~ (b1 * ((b2 * x)^b4))/(1 + ((b2 * x)^b4))^(b3/b4)
data: yourdata
b1 b2 b3 b4
63.00000 0.00155 0.00000 0.90000
residual sum-of-squares: 22.28
Algorithm "port", convergence message: both X-convergence and relative convergence (5)
我们可以看到,它收敛到边界,这意味着您的数据与您的设置(公式或边界)不一致。
我在获取特定曲线以将数据拟合到 nls 模型时遇到一些困难。
这是数据的公式:
((b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4)))^(b3 / b4)
我使用带有随机算法的 nls2 包来查找初始值。
library(nls2)
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63)
b2 = c(0, 0.05)
b3 = c(0, 1)
b4 = c(0, 0.9)
fit <- nls2(eq,
data = .data,
start = values,
algorithm = "random",
control = mls.control(maxiter = 1000))
nls(eq, .data, start = coef(fit), alg = "port", lower = 0)
plot(.data)
值应该是:
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
然而,当我尝试 运行 代码时,我总是以错误消息结束:Convergence Failure: Iteration limit reached without convergence (10)
如何避免收敛失败错误?非常感谢任何帮助。谢谢。
0。 TLDR
你没有在nls
中设置lower
和upper
绑定,所以你没有得到收敛的结果。如果你设置它们,你会得到一个接近边界的结果。 看我上一段写的代码
其实,即使你设置了边界,由于数据质量不好(样本量小,不符合你的公式),也很难拟合出一个最优的接近真实 b1
、'b2'、'b3' 和 b4
的值。 查看非技术原因。
1。收敛失败的非技术原因
我认为您的代码是正确的,这种收敛失败是由于您的数据质量或公式指定错误造成的。
一般情况下,你很难用6个点估计出4个参数。如果您拥有非常适合您的模型的良好数据,nlm 将会收敛。在你的情况下,要么你的数据是错误的,要么你的公式规范偏差很大。
我画了一个图给你看:
代码
# generate a line using true parameters:b1,b2,b3,b4
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
x_points = seq(50,420,length.out = 200)
y_points = (b1 * ((b2 * x_points)^b4)) / (1 + ((b2 * x_points)^b4))^(b3 / b4)
# plot the function
plot(x = x_points ,y = y_points, type ='l',col ='black',lwd = 5,
xlim = c(min(yourdata$x)-5,max(yourdata$x)+5),
ylim = c(min(yourdata$y)-5,max(yourdata$y)+5))
# plot the data your got
points(yourdata$x,yourdata$y,cex = 2)
输出:
如果我们根据您的公式生成数据,我们可以很容易地拟合它们,如下所示:
## generate data
b1 = 62.2060
b2 = 0.0438
b3 = 0.9692
b4 = 0.8693
x <- runif(6,60,450)
y <- (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
data <- data.frame(x,y)
yourdata <- data.frame(x = c(409.56, 195.25, 60.53, 359.56, 188.79, 67.12),
y = c(39.76100, 20.11875, 7.23675, 41.01100, 20.28035, 7.07200))
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63),
b2 = c(0, 0.05),
b3 = c(0, 1),
b4 = c(0, 0.9))
fit <- nls2(eq,
data = data,
start = values,
algorithm = "random",
control = nls.control(maxiter = 1000))
nls(eq, data, start = coef(fit), alg = "port",
control = nls.control(maxiter = 1000,tol = 1e-05),
low = c(60,0,0,0),upper =c(63,0.05,1,0.9) ,trace = TRUE)
plot(x,y)
输出:
Nonlinear regression model model: y ~ (b1 * ((b2 * x)^b4))/(1 + ((b2 * x)^b4))^(b3/b4) data: data b1 b2 b3 b4 62.2060 0.0438 0.9692 0.8693 residual sum-of-squares: 3.616e-24 Algorithm "port", convergence message: absolute function convergence (6)
另请注意,在上面,我只生成 6 个数字来拟合模型。如果你生成更多的数据,比如60,你会有更好的收敛性!
2.Technical原因
阅读 PORT 文档后,我认为这个错误可能意味着
- 梯度计算不正确
- 停止公差太紧
- 梯度在某些迭代附近不连续
而这些都可能与你的数据和训练任务(你的边界和公式)有关。
试试下面的代码,你会得到更好的结果:
代码:
yourdata <- data.frame(x = c(409.56, 195.25, 60.53, 359.56, 188.79, 67.12),
y = c(39.76100, 20.11875, 7.23675, 41.01100, 20.28035, 7.07200))
#FORMULA
eq <- y ~ (b1 * ((b2 * x)^b4)) / (1 + ((b2 * x)^b4))^(b3 / b4)
#LIMITS
values <- data.frame(
b1 = c(60, 63),
b2 = c(0, 0.05),
b3 = c(0, 1),
b4 = c(0, 0.9))
fit <- nls2(eq,
data = yourdata,
start = values,
algorithm = "random",
control = nls.control(maxiter = 1000))
nls(eq, yourdata, start = coef(fit), alg = "port",
control = nls.control(maxiter = 1000,tol = 1e-05),
low = c(60,0,0,0),upper =c(63,0.05,1,0.9) ,trace = TRUE)
plot(x,y)
输出:
Nonlinear regression model model: y ~ (b1 * ((b2 * x)^b4))/(1 + ((b2 * x)^b4))^(b3/b4) data: yourdata b1 b2 b3 b4 63.00000 0.00155 0.00000 0.90000 residual sum-of-squares: 22.28 Algorithm "port", convergence message: both X-convergence and relative convergence (5)
我们可以看到,它收敛到边界,这意味着您的数据与您的设置(公式或边界)不一致。