¿La curtosis de la muestra está sesgada irremediablemente?

8

Estoy viendo la muestra de curtosis de una variable aleatoria bastante sesgada, y los resultados parecen inconsistentes. Para ilustrar simplemente el problema, miré la curtosis de muestra de un RV log-normal. En R (que estoy aprendiendo lentamente):

library(moments); 

samp_size = 2048;
n_trial = 4096;

kvals <- rep(NA,1,n_trial); #preallocate
for (iii in 1:n_trial) {
    kvals[iii] <- kurtosis(exp(rnorm(samp_size)));
}
print(summary(kvals));

El resumen que obtengo es

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  11.87   28.66   39.32   59.17   61.70 1302.00 

Según Wikipedia , la curtosis para este RV logarítmico normal debería estar alrededor de 114. Claramente, la curtosis de la muestra está sesgada.

Al investigar un poco, descubrí que la curtosis de la muestra está sesgada para tamaños de muestra pequeños. Utilicé el estimador 'G2' provisto por el e1071paquete en CRAN, y obtuve resultados muy similares para este tamaño de muestra.

La pregunta : cuál de los siguientes caracteriza lo que está sucediendo:

  1. El error estándar de la curtosis de muestra es simplemente muy grande para este RV (aunque la estimación común del error estándar es del orden ). Alternativamente, utilicé muy pocas muestras (2048) en este estudio.1/ /norte
  2. Estas implementaciones de la curtosis de la muestra adolecen de problemas numéricos que pueden corregirse, por ejemplo, con el método de Terriberry (de la misma manera que el método de Welford da mejores resultados que el método ingenuo para la varianza de la muestra).
  3. Calculé la curtosis de la población de forma incorrecta. (Ay)
  4. La curtosis de muestra está sesgada de forma inherente y nunca se puede arreglar para tamaños de muestra tan pequeños.
shabbychef
fuente
Por cierto, como soy un principiante en R, agradecería cualquier comentario sobre mi código, por breve que sea, tanto en cuanto a estilo como a fondo. En particular, esperaba que hubiera una forma más elegante de expresar el ciclo for.
shabbychef
1
en el estilo R, no necesita ;en los extremos de sus declaraciones. Hiciste bien en la preasignación, pero no hay necesidad de llenar NA, kvals <- numeric(length = n_trial)habría sido suficiente. Con rep, solo necesita argumentos 1 y 3 de su llamada (por ejemplo rep(NA, 10)). En la forconfiguración del bucle, 1:n_trialpuede ser peligroso si se programa; mejor es seq_along(kvals)o seq_len(n_trial)en este caso. Finalmente, si no necesita forzar la impresión, suelte la print()ronda summary(); solo la necesitaría si no estuviera trabajando interactivamente con R. HTH.
Gavin Simpson
¡Gracias! Definitivamente lo que estaba buscando. Estaba ejecutando esto desde un archivo, así que necesitaba el print. Los argumentos a reperan ciertamente erróneos.
shabbychef

Respuestas:

6

Hay una corrección de sesgo . No es enorme Creo que la varianza muestral de la curtosis es proporcional al octavo (!) Momento central, que puede ser enorme para una distribución lognormal. Necesitaría millones de pruebas (o mucho más) en una simulación para detectar sesgos a menos que el CV sea pequeño. (Trace un histograma de kvals para ver cuán extraordinariamente sesgadas están).

La curtosis correcta es de hecho alrededor de 113.9364.

En lo que respecta al estilo R, puede ser conveniente encapsular la simulación en una función para que pueda modificar fácilmente el tamaño de la muestra o el número de ensayos.

whuber
fuente
2
El estimador G2 de e1071da la corrección de sesgo 'estándar'; ver cran.r-project.org/web/packages/e1071/e1071.pdf . El uso de este estimador en lugar de g2, implementado por el momentspaquete, tuvo poco efecto, como señalé en la Q. La dependencia del octavo momento implicaría que el tamaño de la muestra es demasiado pequeño aquí.
shabbychef
5

[Solo en el estilo R - @whuber ha respondido la Kurtsosis Q]

Esto fue un poco complicado para dejar un comentario. Para bucles tan simples como el que usa, podemos combinar la sugerencia de @ whuber de encapsular la simulación en una función con la replicate()función. replicate()se encarga de la asignación y ejecuta el ciclo por usted. A continuación se da un ejemplo:

require(moments)
foo <- function(size, trials, meanlog = 0, sdlog = 1) {
    replicate(trials,
              kurtosis(rlnorm(size, meanlog = meanlog, 
                              sdlog = sdlog)))
}

Lo usamos así:

> set.seed(1)
> out <- foo(2048, 10000)
> summary(out)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.93   28.77   39.99   62.53   62.58 1557.00

Tenga en cuenta que uso la rlnorm()función para generar la variable aleatoria log-normal. Es equivalente a exp(rnorm())en su ciclo pero usa la herramienta correcta, y permitimos que nuestra función pase los parámetros especificados por el usuario de la distribución log-normal.

> set.seed(123)
> exp(rnorm(1))
[1] 0.5709374
> set.seed(123)
> rlnorm(1)
[1] 0.5709374
Gavin Simpson
fuente
+1 para set.seed, lo que ayudaría en ejemplos como este. ¿Hay alguna razón sustancial para encapsular en una función ( por ejemplo, el intérprete R precompilará funciones, por lo tanto, hay una aceleración), o es estilística ( por ejemplo, encapsular funciones, como el brócoli, es bueno para usted), o en algún punto intermedio ( por ejemplo, hay muchos operadores en R que actúan sobre las funciones, por lo que uno debería acostumbrarse a la programación funcional).
shabbychef
@shabbychef: Creo que el principal es el esfuerzo. Puede ejecutar su código con el bucle, etc. repetidamente y estaría bien, pero debe seguir ejecutando todas las líneas de su código. Al encapsularlo, ejecuta 1 línea de código R para cada simulación que desea ejecutar. No hay aceleración ya que R no compila nada antes del IIRC.
Gavin Simpson
1
gracias por la aclaración. Como todo esto está en un archivo pequeño, de todos modos es una línea source('foo.r')
:;