Transformación para aumentar la curtosis y la asimetría de la RV normal.

20

Estoy trabajando en un algoritmo que se basa en el hecho de que las observaciones s se distribuyen normalmente, y me gustaría probar empíricamente la robustez del algoritmo a este supuesto.Y

Para hacer esto, yo estaba buscando una secuencia de transformaciones que pueda interrumpir progresivamente la normalidad de Y . Por ejemplo, si las Y s son normales, tienen asimetría = 0 y curtosis = 3 , y sería bueno encontrar una secuencia de transformación que aumente progresivamente ambas.T1(),,Tn()YY=0=3

Mi idea era simular algunos datos normalmente distribuidos aproximadamente y probar el algoritmo en eso. Luego, pruebe el algoritmo en cada conjunto de datos transformado T 1 ( Y ) , ... , T n ( y ) , para ver cuánto está cambiando la salida.YT1(Y),...,Tnorte(y)

Tenga en cuenta que no controlo la distribución de las s simuladas , por lo que no puedo simularlas usando una distribución que generalice lo Normal (como la Distribución de error generalizado sesgado).Y

Matteo Fasiolo
fuente
2
El problema con una secuencia de transformaciones como esa es que su conclusión se limita a los efectos de esa secuencia en particular. En efecto, su secuencia trazará una ruta en el espacio correspondiente a una sola familia de distribuciones basada en una transformación (presumiblemente un parámetro, ya que usted dice 'secuencia') de lo normal. Suponga que la región viable ( γ 1 , γ 2 ) es 2D y que para cualquier punto dado dentro de ella hay un número infinito de distribuciones diferentes, mirar una sola familia trazando una sola curva sería algo limitante ... (ctd )(γ1,γ2)(γ1,γ2)
Glen_b -Reinstate Monica
1
(ctd) ... especialmente si la familia particular que genera no tiende a revelar problemas que de otro modo podrían ser bastante comunes.
Glen_b -Reinstala a Monica

Respuestas:

22

Esto se puede hacer usando la transformación sinh-arcsinh de

Jones, MC y Pewsey A. (2009). Distribuciones sinh-arcsinh . Biometrika 96: 761–780.

La transformación se define como

()H(X;ϵ,δ)=sinh[δsinh-1(X)-ϵ],

donde y δ R + . Cuando esta transformación se aplica al CDF normal S ( x ; ϵ , δ ) = Φ [ H ( x ; ϵ , δ ) ] , produce una distribución unimodal cuyos parámetros ( ϵ , δ ) controlan la asimetría y la curtosis, respectivamente (Jones y Pewsey, 2009), en el sentido de van Zwet (1969) . Además, si ϵ = 0 y δϵRδR+S(X;ϵ,δ)=Φ[H(X;ϵ,δ)](ϵ,δ)ϵ=0 0 , obtenemos la distribución normal original. Vea el siguiente código R.δ=1

fs = function(x,epsilon,delta) dnorm(sinh(delta*asinh(x)-epsilon))*delta*cosh(delta*asinh(x)-epsilon)/sqrt(1+x^2)

vec = seq(-15,15,0.001)

plot(vec,fs(vec,0,1),type="l")
points(vec,fs(vec,1,1),type="l",col="red")
points(vec,fs(vec,2,1),type="l",col="blue")
points(vec,fs(vec,-1,1),type="l",col="red")
points(vec,fs(vec,-2,1),type="l",col="blue")

vec = seq(-5,5,0.001)

plot(vec,fs(vec,0,0.5),type="l",ylim=c(0,1))
points(vec,fs(vec,0,0.75),type="l",col="red")
points(vec,fs(vec,0,1),type="l",col="blue")
points(vec,fs(vec,0,1.25),type="l",col="red")
points(vec,fs(vec,0,1.5),type="l",col="blue")

Por lo tanto, al elegir una secuencia apropiada de parámetros , puede generar una secuencia de distribuciones / transformaciones con diferentes niveles de asimetría y curtosis y hacer que se vean tan similares o diferentes a la distribución normal como desee.(ϵnorte,δnorte)

La siguiente gráfica muestra el resultado producido por el código R. Para (i) y δ = 1 , y (ii) ϵ = 0 y δ = ( 0.5 , 0.75 , 1 , 1.25 , 1.5 ) .ϵ=(-2,-1,0 0,1,2)δ=1 ϵ=0 0δ=(0.5 0.5,0,75,1,1,25,1,5)

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

La simulación de esta distribución es sencilla dado que solo tiene que transformar una muestra normal usando el inverso de .()

H-1(X;ϵ,δ)=sinh[δ-1(sinh-1(X)+ϵ)]

fuente
2
Muchas gracias Procrastinator! Esto es exactamente lo que estaba buscando.
Matteo Fasiolo
2
Parece que gamlss.dist::rSHASHopuede generar estas distribuciones.
Artem Klevtsov
7

Esto se puede hacer usando distribuciones / variables aleatorias Lambert W x F. Una variable aleatoria (RV) Lambert W x F es una X transformada no linealmente (RV) con distribución F.

α=1Gaussianize()

Se implementan en el

Las transformaciones Lambert W x F vienen en 3 sabores:

  • type = 's'γR
  • type = 'h'δ0 0α
  • type = 'hh'δl,δr0 0

Ver referencias en sesgo y cola (s) (Descargo de responsabilidad: soy el autor).

En R puede simular, estimar, trazar, etc. varias distribuciones Lambert W x F con el paquete LambertW .

library(LambertW)
library(RColorBrewer)
# several heavy-tail parameters
delta.v <- seq(0, 2, length = 11)
x.grid <- seq(-5, 5, length = 100)
col.v <- colorRampPalette(c("black", "orange"))(length(delta.v))

plot(x.grid, dnorm(x.grid), lwd = 2, type = "l", col = col.v[1],
     ylab = "")
for (ii in seq_along(delta.v)) {
  lines(x.grid, dLambertW(x.grid, "normal", 
                          theta = list(delta = delta.v[ii], beta = c(0, 1))),
        col = col.v[ii])
}
legend("topleft", paste(delta.v), col = col.v, lty = 1,
       title = "delta = ")

ingrese la descripción de la imagen aquí

γδlδr

Georg M. Goerg
fuente
5

Una de esas secuencias es la exponenciación en varios grados. P.ej

library(moments)
x <- rnorm(1000) #Normal data
x2 <- 2^x #One transformation
x3 <- 2^{x^2} #A stronger transformation
test <- cbind(x, x2, x3) 
apply(test, 2, skewness) #Skewness for the three distributions
apply(test, 2, kurtosis) #Kurtosis for the three distributions

X1.1,X1,2...X2

Peter Flom - Restablece a Monica
fuente
0

Misma respuesta que @ user10525 pero en python

import numpy as np
from scipy.stats import norm
def sinh_archsinh_transformation(x,epsilon,delta):
    return norm.pdf(np.sinh(delta*np.arcsinh(x)-epsilon))*delta*np.cosh(delta*np.arcsinh(x)-epsilon)/np.sqrt(1+np.power(x,2))


vec = np.arange(start=-15,stop=15+0.001,step=0.001)

import matplotlib.pyplot as plt
plt.plot(vec,sinh_archsinh_transformation(vec,0,1))
plt.plot(vec,sinh_archsinh_transformation(vec,1,1),color='red')
plt.plot(vec,sinh_archsinh_transformation(vec,2,1),color='blue')
plt.plot(vec,sinh_archsinh_transformation(vec,-1,1),color='red')
plt.plot(vec,sinh_archsinh_transformation(vec,-2,1),color='blue')

[1]

JPlatts
fuente