是否可以使用带有 scipy.stats 的 statsmodels 的分布?

Is it possible to use a distribution from statsmodels with scipy.stats?

我正在使用某个 StatsModels 分布 (Azzalini's Skew Student-t),我想用它执行(单样本)Kolmogorov-Smirnov 检验。

是否可以将 Scipy 的 kstest 与 StatsModels 分布一起使用? Scipy 的 documentation(相当模糊)表明 cdf 参数可能是字符串或 callable,没有进一步的细节或示例后者。

另一方面,我使用的 StatsModels 分布具有 Scipy 分布所具有的许多方法;因此,我假设有一些方法可以将它用作传递给 kstestcallable 参数。我错了吗?

这是我目前所掌握的。最后一行注释掉了我想要实现的目标:

import statsmodels.sandbox.distributions.extras as azt
import scipy.stats as stats

x = ([-0.2833379 , -3.05224565,  0.13236267, -0.24549146, -1.75106484,
       0.95375723,  0.28628686,  0.        , -3.82529261, -0.26714159,
       1.07142857,  2.56183746, -1.89491817, -0.3414301 ,  1.11589663,
       -0.74540174, -0.60470106, -1.93307821,  1.56093656,  1.28078818])

# This is how kstest works.
print stats.kstest(x, stats.norm.cdf) #(0.21003262911224113, 0.29814145956367311)

# This is Statsmodels' distribution I'm using. It has a cdf function as well.
ast = azt.ACSkewT_gen()

# This is what I'd want. Executing this will throw a TypeError because ast.cdf 
# needs some shape parameters etc.
# print stats.kstest(x, ast.cdf) 

注意: 如果无法实现我的期望,我会很乐意使用 two-sample KS test。只是想知道这是否可能。

这些函数是很久以前写的,考虑到 scipy 兼容性。但在此期间 scipy 发生了一些变化。

kstest 有一个 args 分布参数关键字。

要获得分布参数,我们可以尝试使用 scipy.stats 分布的 fit 方法来估计它们。但是,估计所有参数会打印一些警告,并且估计的 df 参数很大。如果我们将 df 固定为特定值,我们会在没有警告的情况下获得估计值,我们可以在 kstest.

的调用中使用这些估计值
>>> ast.fit(x)
C:\programs\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site-packages\scipy\integrate\quadpack.py:352: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.
  If increasing the limit yields no improvement it is advised to analyze 
  the integrand in order to determine the difficulties.  If the position of a 
  local difficulty can be determined (singularity, discontinuity) one will 
  probably gain from splitting up the interval and calling the integrator 
  on the subranges.  Perhaps a special-purpose integrator should be used.
  warnings.warn(msg, IntegrationWarning)
C:\programs\WinPython-64bit-3.4.3.1\python-3.4.3.amd64\lib\site-packages\scipy\integrate\quadpack.py:352: IntegrationWarning: The integral is probably divergent, or slowly convergent.
  warnings.warn(msg, IntegrationWarning)
(31834.800527154337, -2.3475921468088172, 1.3720725621594987, 2.2766515091760722)

>>> p = ast.fit(x, f0=100)
>>> print(stats.kstest(x, ast.cdf, args=p)) 
(0.13897385693057401, 0.83458552699682509)

>>> p = ast.fit(x, f0=5)
>>> print(stats.kstest(x, ast.cdf, args=p)) 
(0.097960232618178544, 0.990756154198281)

但是,Kolmogorov-Smirnov 检验的分布假设分布参数是固定的而不是估计的。如果我们像上面那样估计参数,那么 p 值将不正确,因为它不是基于正确的分布。

对于某些分布,我们可以使用具有估计均值和尺度参数的 kstest 表,例如statsmodels 中的 Lilliefors 测试 kstest_normal。如果我们估计了形状参数,那么ks检验统计量的分布将取决于模型的参数,我们可以从bootstrapping中得到pvalue。

(关于估计SkewT分布的参数以及最大似然估计是否有什么具体问题我不记得了。)