将分布拟合到数据

数据挖掘 统计数据 分配 scipy
2022-02-09 16:31:42

我在两个时间点有大量的属性值数据集。我已经计算了这两点之间的价值变化。我想评估哪种分布与属性值变化的变化最接近。选择最接近的分布类型有哪些可能的方法?

我计划使用 python、scipy 和 pandas 来做到这一点,尽管我的问题更多是关于如何进行正确的统计测试来确定一种分布是否比另一种更适合数据。

2个回答

我对您的问题的理解:您已经意识到X(第一个时间点的财产价值)和(第二个时间点的值)。想要适合的分布-X——更一般地说,“数据模型”。

一种方法是绘制这些值的直方图,然后得出可能适合数据的合理分布,然后使用最大似然估计来找到最佳参数。如果模型是嵌套的,那么您可以使用例如似然比检验来确定哪个模型更适合数据。

如果不是,那么事情就变得更棘手了。一个不错的选择是保留一些数据进行测试,在训练数据上拟合模型,使用每个模型预测测试数据,然后看看哪个模型表现更好。

很酷的问题。我的理解是,Kolmogorov Smirnov 测试就是您所追求的。您可以使用 scipy 中的分布函数来生成各种分布,并使用 KS 测试来评估值方差分布与您为测试选择的每个分布之间的相似性。

KS 测试文档在这里:https ://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.kstest.html

这是一个例子:

import scipy.stats as stats
import numpy as np

target = stats.norm.rvs(0, 1, size=1000) # The target has standard normal distribution

a = stats.kstest(target, stats.norm(0, 1).cdf) # Testing target against a standard normal distribution)
b = stats.kstest(target, stats.chi2(1).cdf) # Testing target against a chi2 distribution

print("""
Target x Normal Distribution: test-stat {0}, p-value {1}
Target x Chi2 Distribution: test-stat {2}, p-value {3}
""".format(a[0], a[1], b[0], b[1]))

输出是:

目标 x 正态分布:测试统计 0.022869389923164785,p 值 0.6723583002262676
目标 x Chi2 分布:测试统计 0.488,p 值 5.343066131071921e-220

原假设是两个分布相同,因此您可以看到,在针对 Chi2 分布而非正态分布进行测试时,我们可以自信地拒绝该假设。

我可以用这种方法看到的一个潜在问题是,改变目标或 b 的均值和标准差参数确实会导致测试统计量改变到 KS 测试不再认为它们相同的程度:

stats.kstest(target, stats.norm(10, 1).cdf))

KstestResult(统计=0.9999999999962224,pvalue=0.0)

这在某种程度上是公平的,因为它们不再有丝毫重叠:

在此处输入图像描述

这里应该发生什么取决于我猜你是否希望这两个分布被认为是相似的。如果是这样,您必须在测试之前执行一些转换,或者使用目标分布的均值和标准差作为stats.norm(). 例如,我们可以通过去除均值并除以标准差来缩放这两个分布,这样 KS 测试就会再次看到它们的相似性。

test = stats.norm.rvs(10, 1, size=1000)

sns.distplot((target - target.mean() / target.std()))
sns.distplot((test - test.mean()) / test.std())

print(stats.ks_2samp((target - target.mean() / target.std()), (test2 - test2.mean()) / test2.std()))

在此处输入图像描述

Ks_2sampResult(统计=0.03200000000000003,pvalue=0.6785103823828891)