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

如何用fitdistr或fitdistrplus从截断数据恢复原正态分布参数?

拟合截断数据以恢复原始正态分布参数

直接用fitdistr拟合得到的不是原始N(3,1)的参数,是因为它默认拟合的是未截断的正态分布,而你的数据是原分布截断到x≤2后的样本,自然会得到截断后分布的均值和标准差(也就是你看到的1.48和0.43左右)。要恢复原始分布参数,必须告诉拟合函数数据是截断的,两种方法可以实现:

方法一:用MASS::fitdistr自定义截断正态密度函数

我们需要手动构造截断正态的对数似然函数,让拟合过程考虑截断条件:

library(MASS)

# 生成截断数据
N <- 10000
trunc <- rnorm(N, mean = 3, sd = 1)
trunc <- trunc[trunc <= 2]

# 定义截断正态的对数密度函数(截断上限为2)
dnorm_trunc_log <- function(x, mean, sd) {
  # 原始正态密度的对数,减去截断点的累积概率对数,得到截断分布的对数密度
  log(dnorm(x, mean, sd)) - log(pnorm(2, mean, sd))
}

# 拟合,设置合理初始值
fit_result <- fitdistr(trunc, densfun = dnorm_trunc_log, start = list(mean = 2, sd = 1))
print(fit_result)

运行后你会发现拟合出的均值和标准差会接近原始的3和1,因为我们在似然计算中加入了截断的校正项。

方法二:用fitdistrplus便捷拟合截断分布

fitdistrplus包专门针对分布拟合做了扩展,支持直接指定截断范围,不需要手动写密度函数:

library(fitdistrplus)

# 生成截断数据
N <- 10000
trunc <- rnorm(N, mean = 3, sd = 1)
trunc <- trunc[trunc <= 2]

# 拟合截断正态分布,指定截断上限为2
fit_result <- fitdist(trunc, distr = "norm", method = "mle",
                      fix.arg = list(upper = 2), start = list(mean = 2, sd = 1))
summary(fit_result)

fix.arg参数明确告诉函数数据是从正态分布截断到x≤2的样本,拟合过程会自动校正似然,得到接近原始参数的结果。

关键注意点

  • 初始值要合理:如果初始值和真实参数相差太大,可能导致拟合不收敛,建议根据数据的大致范围设置(比如示例中用mean=2、sd=1作为初始值)。
  • 样本量足够:你的示例中截断后样本量约1500+,已经足够让拟合结果接近真实参数,样本量越大精度越高。

内容的提问来源于stack exchange,提问作者vtuna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:33:33