Comment estimer la densité d'un paramètre gonflé à zéro dans R?


10

J'ai un ensemble de données avec beaucoup de zéros qui ressemble à ceci:

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

Je voudrais tracer une ligne pour sa densité, mais la density()fonction utilise une fenêtre mobile qui calcule les valeurs négatives de x.

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

Il y a des density(... from, to)arguments, mais ceux-ci semblent seulement tronquer le calcul, pas modifier la fenêtre afin que la densité à 0 soit cohérente avec les données comme le montre le graphique suivant:

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

(si l'interpolation était modifiée, je m'attendrais à ce que la ligne noire ait une densité plus élevée à 0 que la ligne grise)

Existe-t-il des alternatives à cette fonction qui fourniraient un meilleur calcul de la densité à zéro?

entrez la description de l'image ici

Réponses:


14

La densité est infinie à zéro car elle comprend un pic discret. Vous devez estimer la pointe en utilisant la proportion de zéros, puis estimer la partie positive de la densité en supposant qu'elle est lisse. KDE causera des problèmes à l'extrémité gauche car il mettra un peu de poids sur les valeurs négatives. Une approche utile consiste à se transformer en journaux, à estimer la densité à l'aide de KDE, puis à retransformer. Voir Wand, Marron & Ruppert (JASA 1991) pour une référence.

La fonction R suivante fera la densité transformée:

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)
}

Ensuite, ce qui suit donnera l'intrigue que vous voulez:

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.

entrez la description de l'image ici


P(X=0)

P(X=0)

cela est utile. fyi: il semble que, bien que bw = "SJ" affecte la densité dans l'espace non transformé, la densité logarithmique est la même en utilisant "SJ" et la valeur par défaut "nrd0" ... Je suis sur le point de lire la référence SJ: "Sheather and Jones (1991) Une méthode fiable de sélection de la bande passante basée sur des données pour l'estimation de la densité du noyau. " jstor.org/stable/2345597
Abe

4

Je suis d'accord avec Rob Hyndman que vous devez traiter les zéros séparément. Il existe quelques méthodes pour traiter une estimation de densité de noyau d'une variable avec un support borné, y compris la «réflexion», la «rernormalisation» et la «combinaison linéaire». Ceux-ci ne semblent pas avoir été implémentés dans la densityfonction de R , mais sont disponibles dans le kdenspackage de Benn Jann pour Stata .


1

Une autre option lorsque vous avez des données avec une limite inférieure logique (comme 0, mais pourrait être d'autres valeurs) que vous savez que les données n'iront pas en dessous et que l'estimation de densité de noyau régulière place des valeurs en dessous de cette limite (ou si vous avez une limite supérieure , ou les deux) consiste à utiliser des estimations de la courbe de consignation. Le package logspline pour R implémente ces derniers et les fonctions ont des arguments pour spécifier les limites de sorte que l'estimation ira à la limite, mais pas au-delà et sera toujours mise à l'échelle à 1.

Il existe également des méthodes (la oldlogsplinefonction) qui prendront en compte la censure des intervalles, donc si ces 0 ne sont pas des 0 exacts, mais sont arrondis pour que vous sachiez qu'ils représentent des valeurs comprises entre 0 et un autre nombre (une limite de détection par exemple), alors vous peut donner ces informations à la fonction d'ajustement.

Si les 0 supplémentaires sont de vrais 0 (non arrondis), l'estimation du pic ou de la masse ponctuelle est la meilleure approche, mais peut également être combinée avec une estimation de la courbe de log.


0

Vous pouvez essayer de réduire la bande passante (la ligne bleue est pour adjust=0.5), entrez la description de l'image ici

mais KDE n'est probablement pas la meilleure méthode pour gérer ces données.


existe-t-il une autre méthode que vous recommanderiez?
Abe

@Abe Eh bien, cela dépend de ce que vous voulez faire ...
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.