You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mle2拟合y=exp(-a*x)函数报错求助及替代方法咨询

解决mle2拟合指数函数时的报错及替代拟合方法

首先来看你遇到的报错:Error in dnorm(find1, mean = G, sd = sigma, log = TRUE) : Non-numeric argument to mathematical function,核心原因有几个:

  1. dnorm()参数错误:你把整个数据框find1传给了dnorm的第一个参数,但这个位置需要的是观测到的响应变量(也就是你的实际G值),不是整个数据框,这就导致了非数值参数的错误。
  2. 变量名冲突:函数内部定义的G和全局环境里的G向量重名了,容易让R混淆到底用哪个值。
  3. 未明确引用数据列:函数里没有指定要使用数据框中的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:08:24