使用nls2包优化含嵌套函数的复杂公式参数问题求助
解决nls2中使用自定义嵌套函数求解参数的问题
看起来你在尝试用nls2的暴力搜索算法拟合带有嵌套逻辑的模型,但代码里有几个关键问题导致无法正常运行,我来帮你修正并解释:
问题分析
- 模型定义错误:
nls2需要的是模型公式(格式为y ~ 包含参数的表达式),但你定义的f1是一个无参函数,内部直接赋值y,这完全不符合nls2的输入要求。 - 嵌套函数未关联参数:你的
a()函数没有接收参数d,导致nls2无法识别d是需要优化的参数,运行时会报错找不到d这个变量。 - 起始参数范围不合理:你设置的
d和b范围从-100到100,不仅包含负数(会导致分母b+x可能为0或负数,不符合米氏模型的实际意义),而且范围太宽会大幅降低暴力搜索的效率。
修正方案
我提供两种方案,第一种是最简单的直接整合逻辑,第二种是保留自定义嵌套函数的写法:
方案一:直接将嵌套逻辑写入模型公式(推荐)
不需要额外定义函数,直接把d+1的逻辑写进模型表达式里,这样nls2能清晰识别待优化参数:
library(nls2) set.seed(20160227) x <- seq(0,50,1) # 生成数据时先固定真实参数,方便后续验证拟合效果 true_d <- runif(1,10,20) - 1 # 因为a()=d+1,所以真实d的范围是9-19 true_b <- runif(1,0,10) y <- ((true_d + 1)*x)/(true_b + x) + rnorm(51,0,1) # 设置合理的起始参数范围(匹配真实参数的大致区间) st <- data.frame(d = c(9, 19), b = c(0, 10)) # 直接使用模型公式调用nls2 fit <- nls2(y ~ (d+1)*x/(b + x), start = st, algorithm = "brute-force") # 查看拟合结果 summary(fit)
方案二:保留自定义嵌套函数
如果你一定要用嵌套函数,需要让函数明确接收待优化的参数,这样nls2才能识别并传递参数进行优化:
library(nls2) set.seed(20160227) x <- seq(0,50,1) true_d <- runif(1,10,20) - 1 true_b <- runif(1,0,10) y <- ((true_d + 1)*x)/(true_b + x) + rnorm(51,0,1) # 定义带参数的嵌套函数,接收d作为输入 a <- function(d) { d + 1 } # 模型公式中调用a(d),明确关联参数d model_formula <- y ~ a(d)*x/(b + x) st <- data.frame(d = c(9, 19), b = c(0, 10)) fit <- nls2(model_formula, start = st, algorithm = "brute-force") summary(fit)
运行效果
两种方案运行后,你会看到拟合的d和b值非常接近我们预先设置的真实参数,说明模型拟合成功。缩小参数范围后,暴力搜索的速度也会快很多。
内容的提问来源于stack exchange,提问作者Patrick Glettig
相关产品推荐
相关产品推荐

