在R Studio中绘制对数似然函数求和曲线的问题求助
修正对数似然函数与curve绘图的方案
我明白你的核心问题:当curve函数传入一系列mu值(向量形式)时,原代码中的sum(exp(mu)/(exp(x)))触发了R的循环补齐机制,导致计算逻辑完全偏离了你想要的“固定单个mu,对所有x_i计算exp(mu)/exp(x_i)后求和”的需求。
问题根源
R中向量运算会自动循环补齐长度不同的向量。比如当mu是长度为k的向量,x是长度为n的向量时,exp(mu)/(exp(x))会把较短的向量重复到和较长的一致,再逐元素相除,最后求和——这和你需要的“对每个mu,计算exp(mu)与每个1/exp(x_i)的乘积之和”完全不同。
最优修正方案(高效向量化)
我们可以利用数学变形简化计算,同时实现完全符合需求的逻辑:
对单个mu,sum(exp(mu)/exp(x_i)) = exp(mu) * sum(1/exp(x_i))。其中sum(1/exp(x_i))是与mu无关的常量,可以提前预计算,大幅提升效率。
步骤1:定义数据与预计算常量
# 你的数据子集 data = c(8.5,8.9,9.1,8.9,8.4,9.7,9.1,9.6,8.7,9.3,9.6,9.3,8.7,9.0,8.8,8.9,8.9,12.2) # 预计算与mu无关的常量:sum(1/exp(x_i)) inv_exp_sum <- sum(1 / exp(data))
步骤2:修正对数似然函数(支持向量输入)
修改后的函数可以直接处理curve传入的向量形式mu,无需循环:
loglikelihood.func <- function(mu, x) { n <- length(x) # 核心逻辑:对每个mu,计算n*mu - sum(x) - exp(mu)*inv_exp_sum n * mu - sum(x) - exp(mu) * inv_exp_sum }
步骤3:用curve函数绘图
调用curve时,注意参数顺序(把mu作为第一个参数,符合xname的要求):
curve(expr = loglikelihood.func(mu, x = data), xname = "mu", from = 0, to = 15)
备选方案(显式循环,适合理解逻辑)
如果你想更直观地看到对每个mu的遍历过程,可以用sapply实现显式循环(效率略低于预计算方案,但逻辑清晰):
loglikelihood.func <- function(mu, x) { n <- length(x) # 对每个mu单独计算求和项 sapply(mu, function(m) { n * m - sum(x) - sum(exp(m)/exp(x)) }) } # 同样调用curve绘图 curve(expr = loglikelihood.func(mu, x = data), xname = "mu", from = 0, to = 15)
验证正确性
取单个mu值(比如mu=5),手动计算与函数结果一致:
# 手动计算 manual_sum <- exp(5) * sum(1/exp(data)) manual_result <- length(data)*5 - sum(data) - manual_sum # 函数计算 func_result <- loglikelihood.func(5, data) # 验证相等 all.equal(manual_result, func_result) # 返回TRUE
内容的提问来源于stack exchange,提问作者user9817825
相关产品推荐
相关产品推荐

