r - 收敛失败 : Iteration limit reached without convergence (10)

标签 r function curve-fitting nls

我在获取特定曲线以将数据拟合到 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

您没有设置 lowerupper绑定(bind) nls ,所以你没有得到收敛的结果。如果您设置它们,您将在边界附近获得结果。 请参阅我在上一段中编写的代码。

实际上,即使你设置了边界,由于 数据质量差 (样本量小,不符合您的公式),很难在您的真实 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)

输出:
enter image description here

如果我们从您的公式中生成数据,我们可以很容易地拟合它们,如下所示:
## 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.技术原因

阅读 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)
    


    正如我们所看到的,它收敛到边界,这意味着您的数据与您的设置(公式或边界)不一致。

    关于r - 收敛失败 : Iteration limit reached without convergence (10),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59550999/

    相关文章:

    c++ - 在C++中动态创建指针函数

    curve-fitting - 给定三个点如何计算抛物线的顶点

    python - 如何强制曲线拟合中的特定点

    r - 我的 aggregate() 输出和 tidyverse 输出之间的区别

    r - 多个变量的自定义函数

    r - 比较 R 与 Matlab 的数据挖掘

    python - 在 struct.pack 中使用 *args

    重新安装 R linux ubuntu : unmet dependencies R

    PHP 使用变量将多个参数传递给函数

    r - 如何让我的线条更合身、更整洁?