我将数据拟合为对数正态分布,并且在Python和R中进行了KS测试,结果却大不相同。
数据为:
series
341 291 283 155 271 270 250 272 209 236 295 214 443 632 310 334 376 305 216 339
R中的代码为:
fit = fitdistr(series, "lognormal")$estimate
fit
meanlog
5.66611754205579
sdlog
0.290617205700481
ks.test(series, "plnorm", meanlog=fit[1], sdlog=fit[2], exact=TRUE)
One-sample Kolmogorov-Smirnov test
data: series
D = 0.13421, p-value = 0.8181
alternative hypothesis: two-sided
在Python中,代码为:
distribution = stats.lognorm
args = distribution.fit(series)
args
(4.2221814852591635, 154.99999999212395, 0.45374242945626875)
stats.kstest(series, distribution.cdf, args, alternative = 'two-sided')
KstestResult(statistic=0.8211678552361514, pvalue=2.6645352591003757e-15)
您的建议将不胜感激。
答案 0 :(得分:0)
对数正态分布的SciPy实现的参数化方式与R代码中的方式不同。在stackoverflow上搜索[scipy] lognorm
,以查找许多类似的问题,并在lognorm
文档字符串中查看有关参数化的说明。另请注意,要匹配R结果,必须使用参数loc
将位置参数floc=0
固定为0。 R实现不包含位置参数。
下面是一个脚本,该脚本显示如何获取R报告的相同值:
import numpy as np
from scipy.stats import lognorm, kstest
x = [341, 291, 283, 155, 271, 270, 250, 272, 209, 236,
295, 214, 443, 632, 310, 334, 376, 305, 216, 339]
sigma, loc, scale = lognorm.fit(x, floc=0)
mu = np.log(scale)
print("mu = %9.5f" % mu)
print("sigma = %9.5f" % sigma)
stat, p = kstest(x, 'lognorm', args=(sigma, 0, scale), alternative='two-sided')
print("KS Test:")
print("stat = %9.5f" % stat)
print("p-value = %9.5f" % p)
输出:
mu = 5.66612
sigma = 0.29062
KS Test:
stat = 0.13421
p-value = 0.86403
SciPy中的kstest
函数没有计算精确p值的选项。要将其值与R进行比较,可以在exact=FALSE
中使用fitdistr
:
> ks.test(series, "plnorm", meanlog=fit[1], sdlog=fit[2], exact=FALSE)
One-sample Kolmogorov-Smirnov test
data: series
D = 0.1342, p-value = 0.864
alternative hypothesis: two-sided