如何用单边数据拟合高斯分布?

Posted

技术标签:

【中文标题】如何用单边数据拟合高斯分布?【英文标题】:How to fit Gaussian distribution with one-sided data? 【发布时间】:2022-01-19 20:03:39 【问题描述】:
x <- c(-3,-2.5,-2,-1.5,-1,-0.5)
y <- c(2,2.5,2.6,2.9,3.2,3.3)

挑战在于整个数据都是从左斜率开始的,如何生成双边高斯分布?

【问题讨论】:

问题,你想让分布的平均值变化还是固定在0? 【参考方案1】:

关于该问题的信息不完整。因此可以实现多种方式。请注意,数据不足。即尝试通过nls 安装 tis 不起作用。

这是解决它的一种方法:

f <- function(par, x, y )sum((y - par[3]*dnorm(x,par[1],par[2]))^2)
a <- optim(c(0,  1, 1), f, x = x, y = y)$par
plot(x, y, xlim = c(-3,3.5), ylim = c(2, 3.5))
curve(dnorm(x, a[1], a[2])*a[3], add = TRUE, col = 2)

【讨论】:

这个分布不会合二为一,所以不是正态分布。您可以在初始拟合后重新评估 Y 值以获得适当的密度(即,将 Y 与 pars[3] 相除)。 @Baraliuh 将分布拟合到数据上并不意味着分布积分为一,而是将常数 K 乘以分布并拟合数据。分布积分到用于乘以数据的常数 K。 有点讽刺,但你明确表示的链接恰恰相反。您说的是高斯曲线,而不是分布。可以拟合曲线,但不能拟合分布。 根据定义,任何 PDF 都可以集成为一个。 mathworld.wolfram.com/ProbabilityDensityFunction.html @Baraliuh 抱歉,问题措辞不正确。应该适合高斯曲线【参考方案2】:

没有办法用这些密度拟合高斯分布。如果提供了正确的 y 值,这将是解决问题的一种方法:

# Define function to be optimized
f <- function(pars, x, y)
  mu <- pars[1]
  sigma <- pars[2]
  y_hat <- dnorm(x, mu, sigma)
  se <- (y - y_hat)^2
  sum(se)


# Define the data
x <- c(-3,-2.5,-2,-1.5,-1,-0.5)
y <- c(2,2.5,2.6,2.9,3.2,3.3)

# Find the best paramters
opt <- optim(c(-.5, .1), f, 'SANN', x = x, y = y)

plot(
  seq(-5, 5, length.out = 200),
  dnorm(seq(-5, 5, length.out = 200), opt$par[1], opt$par[2]), type = 'l', col = 'red'
)
points(c(-3,-2.5,-2,-1.5,-1,-0.5), c(2,2.5,2.6,2.9,3.2,3.3))

【讨论】:

看来你没有抓住重点。给出的数据是正确的。假设是 x 值产生给定的 y 值。请阅读有关数据拟合的更多信息。例如检查here了解更多信息) 拟合曲线和拟合分布是两件事。【参考方案3】:

使用 nls 获得 y 与 .lin.a * dnorm(x, b, c) 的最小二乘拟合,其中 .lin.a、b 和 c 是要估计的参数。

fm <- nls(y ~ cbind(a = dnorm(x, b, c)), 
  start = list(b = mean(x), c = sd(x)), algorithm = "plinear")
fm

给予:

Nonlinear regression model
  model: y ~ cbind(a = dnorm(x, b, c))
   data: parent.frame()
      b       c  .lin.a 
 0.2629  3.2513 27.7287 
 residual sum-of-squares: 0.02822

Number of iterations to convergence: 7 
Achieved convergence tolerance: 2.582e-07

dnorm 模型(黑色曲线)似乎适合这些点,尽管即使是只涉及两个参数(截距和斜率)而不是 3 的直线(蓝线)也不错。

plot(y ~ x)
lines(fitted(fm) ~ x)

fm.lin <- lm(y ~ x)
abline(fm.lin, col = "blue")

【讨论】:

以上是关于如何用单边数据拟合高斯分布?的主要内容,如果未能解决你的问题,请参考以下文章

如何用matlab生成高斯分布随机数

matlab高斯拟合的初始值问题

如何用matlab产生标准高斯噪声

这是拟合从python中的高斯分布生成的数据的正确方法吗?

如何用高斯混合模型 GMM 做聚类

GAN 拟合高斯分布数据Pytorch实现