使用mle2拟合y=exp(-a*x)函数报错求助及替代方法咨询
解决mle2拟合指数函数时的报错及替代拟合方法
首先来看你遇到的报错:Error in dnorm(find1, mean = G, sd = sigma, log = TRUE) : Non-numeric argument to mathematical function,核心原因有几个:
dnorm()参数错误:你把整个数据框find1传给了dnorm的第一个参数,但这个位置需要的是观测到的响应变量(也就是你的实际G值),不是整个数据框,这就导致了非数值参数的错误。- 变量名冲突:函数内部定义的
G和全局环境里的G向量重名了,容易让R混淆到底用哪个值。 - 未明确引用数据列:函数里没有指定要使用数据框中的
G和K列,导致变量引用混乱。
修正后的mle2代码
我调整了变量命名和函数逻辑,确保参数传递正确:
# 定义原始数据,把观测G改名为G_obs避免冲突 G_obs <- c(1, 0.86, 0.72, 0.56, 0.33, 0.09) K <- c(0.53, 1.11, 1.5, 2.01, 3.3, 5.1) find1 <- data.frame(G = G_obs, K) library(bbmle) # 修改后的似然函数:明确区分观测值和预测值 functie1 <- function(a, sigma) { # 根据参数a计算预测的G值 G_pred <- exp(-a * find1$K) # 计算负对数似然(mle2默认最小化这个值) -sum(dnorm(find1$G, mean = G_pred, sd = sigma, log = TRUE)) } # 拟合模型 mle2.model <- mle2(functie1, start = list(a=1, sigma=1)) # 查看拟合结果 summary(mle2.model)
运行这段代码应该就能正常得到MLE的参数估计了。
其他合适的参数拟合方法
除了bbmle的MLE,还有几种常用的方法可以拟合这个单参数指数函数:
- 非线性最小二乘(NLS):如果你的数据误差符合正态分布,NLS和MLE是等价的,而且
nls()函数更简洁直观,不需要手动写似然函数:
nls_model <- nls(G ~ exp(-a*K), data = find1, start = list(a=1)) summary(nls_model)
- 贝叶斯拟合(brms):如果你需要参数的后验分布和不确定性估计,贝叶斯方法是更好的选择,用brms包可以轻松实现:
library(brms) # 定义先验,拟合模型 brm_model <- brm( formula = G ~ exp(-a*K), data = find1, prior = prior(normal(1, 1), class = a), family = gaussian(), chains = 4, iter = 2000 ) summary(brm_model)
- 可视化快速拟合:如果只是需要快速可视化拟合结果,ggplot2的
geom_smooth可以直接调用NLS拟合:
library(ggplot2) ggplot(find1, aes(x = K, y = G)) + geom_point(size = 2) + geom_smooth( method = "nls", formula = y ~ exp(-a*x), method.args = list(start = list(a=1)), se = FALSE, color = "red" )
内容的提问来源于stack exchange,提问作者Gido
相关产品推荐
相关产品推荐

