如何估算R中零膨胀参数的密度?


10

我有一个很多零的数据集,看起来像这样:

set.seed(1)
x <- c(rlnorm(100),rep(0,50))
hist(x,probability=TRUE,breaks = 25)

我想为其密度画一条线,但是该density()函数使用一个移动窗口来计算x的负值。

lines(density(x), col = 'grey')

有一个density(... from, to)参数,但是这些参数似乎只会截断计算,而不会更改窗口,因此0处的密度与数据一致,如以下图所示:

lines(density(x, from = 0), col = 'black')

(如果插值被更改,我希望黑线在0处的密度比灰线高)

此功能是否有替代方法可以更好地计算零密度?

在此处输入图片说明

Answers:


14

密度为零是无限的,因为它包含离散的尖峰。您需要使用零的比例来估计尖峰,然后假设密度是平滑的,然后估计密度的正部分。KDE将在左手端引起问题,因为它将使负值有些偏重。一种有用的方法是转换为日志,使用KDE估计密度,然后转换回原值。参见Wand,Marron和Ruppert(JASA 1991)作为参考。

以下R函数将执行转换后的密度:

logdensity <- function (x, bw = "SJ") 
{
    y <- log(x)
    g <- density(y, bw = bw, n = 1001)
    xgrid <- exp(g$x)
    g$y <- c(0, g$y/xgrid)
    g$x <- c(0, xgrid)
    return(g)
}

然后,以下内容将给出您想要的图:

set.seed(1)
x <- c(rlnorm(100),rep(0,50))
hist(x,probability=TRUE,breaks = 25)
fit <- logdensity(x[x>0]) # Only take density of positive part
lines(fit$x,fit$y*mean(x>0),col="red") # Scale density by proportion positive
abline(v=0,col="blue") # Add spike at zero.

在此处输入图片说明


PX=0

PX=0

这很方便。fyi:看来,尽管bw =“ SJ”影响未变换空间中的密度,但是使用“ SJ”和默认值“ nrd0”的对数密度是相同的...我将要阅读SJ参考:“ Sheather and Jones(1991)一种可靠的基于数据的带宽选择方法,用于内核密度估计。” jstor.org/stable/2345597
倍晋三

4

我同意Rob Hyndman的观点,您需要分别处理零。有几种处理带有有限支持的变量的内核密度估计的方法,包括“反射”,“重归一化”和“线性组合”。这些似乎未在R的density函数中实现,但在Benn Jann的kdensStata软件包中可用。


1

当您的数据具有逻辑下限(例如0,但可能是其他值)时,另一种选择是您知道数据将不会低于此值,并且常规内核密度估计会将值置于该值以下(或者如果您具有上限) ,或两者都使用)。R的logspline程序包实现了这些功能,并且函数具有用于指定界限的参数,因此估算值将到达界限,但不会超出界限,并且仍会缩放为1。

还有一些方法(该oldlogspline函数)将考虑间隔检查,因此,如果那些0不是精确的0,而是四舍五入,以使您知道它们表示的值介于0和其他数字(例如检测极限)之间,那么您可以将该信息提供给拟合函数。

如果多余的0为真0(未四舍五入),则估计峰值或点质量是更好的方法,但也可以与对数线估计结合使用。


0

您可以尝试降低带宽(蓝线代表adjust=0.5), 在此处输入图片说明

但是可能KDE并不是处理此类数据的最佳方法。


您还有其他建议的方法吗?
日安倍晋三

@Abe好吧,这取决于您想做什么...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.