从 R 中的 dnorm 估计正态分布

机器算法验证 r 正态分布 多变的
2022-03-20 18:23:56

R 中的函数为您提供某个正态分布的点xdnorm(x)中的概率密度函数值(默认情况下均值 = 0 和 SD = 1),返回与x长度相同的向量。

但是,我想做相反的事情:给定一个近似概率密度函数的向量(如 dnorm 的结果),我想获得由给定概率密度表示的正态分布的均值和标准差。我想做的代码示例:

pdf = dnorm(seq(-3,3,0.1), mean = 0, sd=1)
## get_normal would be supposes to return an list/vector containing the mean and SD, which in this particular case should be close to 0 and 1 respectively.
var_parameters = get_normal(pdf)
2个回答

一个非常简单的通用解决方案:首先,编写一个将参数作为输入的函数,并返回这些参数的预测 PDF 与实际 PDF 之间的差异(我在这里使用了平方差之和)。然后,使用optim()找到参数而不是最小化这个函数。

x = seq(-3,3,0.1)
pdf = dnorm(x, mean = -.5, sd = .2)
f = function(pars){
  pred_pdf = dnorm(x, mean = pars[1], sd = pars[2])
  err = sum((pdf - pred_pdf)^2)
}
result = optim(c(0, 1), f) # c(0, 1) are initial values
round(result$par, 3)
# [1] -0.5  0.2

对于正态密度函数f,如果你有一个点网格X和相应的密度值y=f(x), 那么你可以使用数值积分来找到μσ.[见最后注(2)。]

如果你有很多认识Xi从分布中,您可以估计总体均值μ由样本均值X¯和人口 SDσ由样本 SDS.

另一种可能性是使用核密度估计器 (KDE)f基于足够大的样本。在 R 中,程序density给出分数(x,y)可用于绘制密度估计器。

set.seed(718)
x = rnorm(100, 50, 7)
mean(x);  sd(x)
[1] 50.62287
[1] 6.443036

hist(x, prob=T, col="skyblue2")
 rug(x);  lines(density(x), col="red")

在此处输入图像描述

在 R 中,KDE 由 512 个点组成,其值总结如下:

density(x)

Call:
        density.default(x = x)

Data: x (100 obs.);     Bandwidth 'bw' = 2.309

       x               y            
 Min.   :31.36   Min.   :1.974e-05  
 1st Qu.:41.69   1st Qu.:3.239e-03  
 Median :52.03   Median :2.371e-02  
 Mean   :52.03   Mean   :2.417e-02  
 3rd Qu.:62.36   3rd Qu.:4.378e-02  
 Max.   :72.70   Max.   :5.566e-02  

你可以估计μσ对应的KDE如下:

xx = density(x)$x
yy = density(x)$y              # (xx, yy) is KDE plot point
sum(xx*yy)/sum(yy)
[1] 50.62329                   # aprx pop mean = 50
sum((xx-50.62)^2 * yy)/sum(yy)
[1] 46.42294                   # aprx pop variance = 49
sqrt(sum((xx-50.62)^2 * yy)/sum(yy))
[1] 6.813438                   # aprx pop SD = 7

因为X¯S是足够的统计数据μσ, 很难想象μ^σ^从 KDE 中回收(基于数据)将系统地优于样本均值X¯=50.62和标清S=6.44. 我提到 KDE 方法是因为它似乎可能与您的问题有关。

注:(1)当然也有估算的方法X¯S来自直方图,但对于小样本,它们可能非常不准确。

(2) 这里是一个数值评估μ0100xφ(x,50,7)dx, 使用 1000 个矩形的面积之和。

m = 1000
w = (100-0)/m
x = seq(0+w/2, 100-w/2, len=m) 
f = x*dnorm(x, 50, 7)
sum(w*f)
[1] 50   # mu
f2 = (x-50)^2*dnorm(x,50,7)
sum(w*f2)
[1] 49   # sigma^2