我正在使用某个StatsModels分布(Azzalini's Skew Student-t),我想用它执行一个(单样本)Kolmogorov-Smirnov测试。
是否可以使用Scipy的kstest
与statmodels分布?Scipy的文档(相当模糊地)建议cdf
参数可以是String或可调用,没有关于后者的进一步细节或示例。
另一方面,我正在使用的statmodels的发行版有许多Scipy发行版所做的方法;因此,我假设有某种方法将其用作传递给kstest
的可调用的参数。我错了吗?
这是我到目前为止所知道的。我想要实现的是在最后一行注释掉:
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)
注意:如果我期望的是不可能的,我很乐意使用双样本KS测试。我只是想知道这是否可能。
这些函数是在很久以前编写的,考虑到scipy的兼容性。但与此同时,scipy也发生了一些变化。
kstest
有一个args
关键字作为分布参数。
为了得到分布参数,我们可以尝试使用scipy的fit
方法来估计它们。统计分布。但是,估计所有参数都会打印出一些警告,并且估计的df
参数很大。如果我们将df
固定在特定的值,我们得到的估计值没有警告,可以在调用kstest
时使用。
>>> ast.fit(x)
C:programsWinPython-64bit-3.4.3.1python-3.4.3.amd64libsite-packagesscipyintegratequadpack.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:programsWinPython-64bit-3.4.3.1python-3.4.3.amd64libsite-packagesscipyintegratequadpack.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表,例如,Lilliefors在statmodels中测试kstest_normal。如果我们估计了形状参数,那么ks检验统计量的分布将依赖于模型的参数,我们可以从bootstrapping中得到pvalue。
(我不记得任何关于估计sket分布参数的事情,也不记得最大似然估计是否有任何具体问题。)