如何将数据转换为正态?

机器算法验证 数据转换 正态假设
2022-04-04 07:25:49

我们有一些财务数据(500-1000 个样本),这些数据不是正态分布的(文献中众所周知的事实)。我有一些想法可以对这些数据进行参数转换(使用其他一些数据)以生成“调整后的”系列。我的目标是找到一个使序列呈正态分布的转换(平均值为 0,标准偏差为 1)。什么是最合适的统计数据和相应的测试来优化我的参数并确定结果是否可以被认为是正态分布的?

还请指出一个实现,最好是 C/C++ 或 java。

2个回答

对于财务数据,我已成功使用重尾 Lambert W x Gaussian 变换

  • Pyhon:是Python 中算法gaussianize的 sklearn 类型实现。IGMM

  • C++lamW R 包有一个优雅的(和快速的)Lambert 的 W 函数的 C++ 实现。这可以作为用于 Lambert W x Gaussian 变换的 IGMM 或 MLE 的完整 C++ 实现的起点。

  • RLambertW R 包是 Lambert W x F 框架(模拟、估计、绘图、转换、测试)的完整实现。

作为一个例子,考虑SP500R 中的返回序列。

library(MASS)
data(SP500)
yy <- ts(SP500)
library(LambertW)
test_norm(yy)

SP 500 回报

## $seed
## [1] 516797
## 
## $shapiro.wilk
## 
##  Shapiro-Wilk normality test
## 
## data:  data.test
## W = 1, p-value <2e-16
## 
## 
## $shapiro.francia
## 
## 	Shapiro-Francia normality test
## 
## data:  data.test
## W = 1, p-value <2e-16
## 
## 
## $anderson.darling
## 
##  Anderson-Darling normality test
## 
## data:  data
## A = 20, p-value <2e-16

众所周知,财务数据通常有肥尾,有时呈负偏态。对于这种SP500情况,偏度不是太大,但它表现出高峰度 (7.7)。还有几个正态性检验清楚地拒绝了边缘高斯分布的原假设。

由于我们只需要处理重尾而不是偏度,让我们使用矩估计器的方法拟合重尾兰伯特 W x 高斯分布(也可以使用最大似然估计器 (MLE) MLE_LambertW())。

# fit a heavy tailed Lambert W x Gaussian
mod <- IGMM(yy, type = "h")
mod

## Call: IGMM(y = yy, type = "h")
## Estimation method:  IGMM 
## Input distribution:  Any distribution with finite mean & variance and kurtosis = 3. 
## mean-variance Lambert W x F type ('h' same tails; 'hh' different tails; 's' skewed):  h 
## 
##  Parameter estimates:
##    mu_x sigma_x   delta 
##    0.05    0.72    0.16 
## 
##  Obtained after 4 iterations.

重尾参数与零显着不同,意味着重尾。对于这样的矩,δ^=0.16δ1/δ^=6.29

模型检查问题当然是反向转换的数据是否确实具有高斯分布。让我们再次检查test_norm()

# transform data to input data (which presumably should have Normal distribution); use return.u = TRUE to get zero-mean, unit variance data
xx <- get_input(mod, return.u = FALSE)
test_norm(xx)

高斯化 SP 500 返回系列

## $seed
## [1] 268951
## 
## $shapiro.wilk
## 
##  Shapiro-Wilk normality test
## 
## data:  data.test
## W = 1, p-value = 0.2
## 
## 
## $shapiro.francia
## 
## 	Shapiro-Francia normality test
## 
## data:  data.test
## W = 1, p-value = 0.2
## 
## 
## $anderson.darling
## 
##  Anderson-Darling normality test
## 
## data:  data
## A = 0.7, p-value = 0.07

我认为情节和正态性测试结果不言自明。

该包还提供了一个函数,可以一次完成所有这些步骤:(Gaussianize()这也是 Python 包实现的)。

看来您只是要求进行正常性测试。如果是这样,夏皮罗-威尔克很难被击败。然而,这并不是万神殿中最容易实施的测试。

为什么不直接使用 R?shapiro.test功能将为您完成工作。