我正在研究一种算法,该算法依赖于观察结果s 是正态分布的,我想根据经验测试算法对这个假设的鲁棒性。
为此,我正在寻找一系列转换这将逐渐破坏正常的. 例如,如果s 是正常的 他们有偏斜和峰度,并且很高兴找到一个逐渐增加两者的转换序列。
我的想法是模拟一些正态分布的数据并测试算法。在每个转换后的数据集上测试算法,看看输出有多少变化。
请注意,我不控制模拟的分布s,所以我无法使用泛化正态分布的分布(例如偏斜的广义误差分布)来模拟它们。
我正在研究一种算法,该算法依赖于观察结果s 是正态分布的,我想根据经验测试算法对这个假设的鲁棒性。
为此,我正在寻找一系列转换这将逐渐破坏正常的. 例如,如果s 是正常的 他们有偏斜和峰度,并且很高兴找到一个逐渐增加两者的转换序列。
我的想法是模拟一些正态分布的数据并测试算法。在每个转换后的数据集上测试算法,看看输出有多少变化。
请注意,我不控制模拟的分布s,所以我无法使用泛化正态分布的分布(例如偏斜的广义误差分布)来模拟它们。
这可以使用来自的 sinh-arcsinh 变换来完成
琼斯,MC 和 Pewsey A.(2009 年)。Sinh-arcsinh 分布。生物计量学 96:761-780。
转换定义为
在哪里和. 当将此变换应用于普通 CDF 时,它产生一个单峰分布,其参数在van Zwet (1969)的意义上,分别控制偏度和峰度 (Jones and Pewsey, 2009 ) 。此外,如果和,我们得到原始的正态分布。请参阅以下 R 代码。
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")
因此,通过选择适当的参数序列,您可以生成一系列具有不同偏度和峰度的分布/变换,并使它们看起来与您想要的正态分布相似或不同。
下图显示了 R 代码产生的结果。对于(一) 和, 和(ii) 和.
这个分布的模拟很简单,因为您只需要使用 的倒数来转换一个正态样本.
这可以使用 Lambert W x F 随机变量/分布来完成。Lambert W x F 随机变量 (RV) 是具有分布 F 的非线性变换 (RV) X。
对于 F 是正态分布和,它们减少到 Tukey 的 h 分布。Lambert W x F 分布的优点是您也可以再次从非正态返回到正态;即,您可以估计参数和Gaussianize()
数据。
它们在
Lambert W x F 变换有 3 种风格:
type = 's'
带偏度参数的偏斜 ( )type = 'h'
带尾参数的重尾 ( )(和可选的)type = 'hh'
带有左/右尾参数的
倾斜和重尾 ( )在 R 中,您可以使用LambertW包模拟、估计、绘制等多个 Lambert W x F 分布。
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 = ")
对于一系列添加偏度。如果你想添加偏度和重尾然后生成一个序列和.
一个这样的序列是不同程度的指数。例如
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
你可以使用以获得中等程度的转变。
与@user10525 相同的答案,但在 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')
[