我有一个数据包丢失的CDF分布图。因此,我没有原始数据或CDF模型本身,但有CDF曲线的样本。 (数据摘自文献中发表的地块。)
我想找到哪种分布和哪些参数最适合CDF样本。
我已经看到Scipy统计信息分布提供了fit(data)方法,但是所有示例都适用于原始数据点。随后从拟合参数中提取PDF / CDF。与我的CDF样本配合使用不会产生明智的结果。
我是否正确认为fit()无法直接应用于经验CDF的数据样本?
我可以使用哪些替代方法来找到匹配的已知分布?
答案 0 :(得分:2)
我不确定您要做什么。当您说自己有CDF时,这是什么意思?您是否有一些数据点或函数本身?如果您可以发布更多信息或一些示例数据,将会很有帮助。
如果您有一些数据点并且知道分布,则使用scipy并不难。如果您不知道发行版,则可以遍历所有发行版,直到找到一个运行良好的发行版。
我们可以定义scipy.optimize.curve_fit
所需形式的函数。也就是说,第一个参数应为x
,然后其他参数为参数。
我使用此功能基于正常随机变量的CDF生成一些测试数据,并增加了一些噪声。
n = 100
x = np.linspace(-4,4,n)
f = lambda x,mu,sigma: scipy.stats.norm(mu,sigma).cdf(x)
data = f(x,0.2,1) + 0.05*np.random.randn(n)
现在,使用curve_fit
查找参数。
mu,sigma = scipy.optimize.curve_fit(f,x,data)[0]
这给出了输出
>> mu,sigma
0.1828320963531838, 0.9452044983927278
我们可以绘制原始CDF(橙色),嘈杂的数据,并拟合CDF(蓝色),并观察其效果很好。
请注意,curve_fit
可以使用一些其他参数,并且输出将提供有关该函数拟合度的其他信息。
答案 1 :(得分:-1)
@tch谢谢您的回答。我阅读了该技术并成功应用了它。我想将拟合应用于scipy.stats支持的所有连续分布,所以我最终做了以下事情:
fitted = []
failed = []
for d in dist_list:
dist_name = d[0] #fetch the distribution name
dist_object = getattr(ss, dist_name) #fetch the distribution object
param_default = d[1] #fetch the default distribution parameters
# For distributions with only location and scale set those to the default loc=0 and scale=1
if not param_default:
param_default = (0,1)
# Computed parameters of fitted distribution
try:
param,cov = curve_fit(dist_object.cdf,data_in,data_out,p0=param_default,method='trf')
# Only take distributions which do not result in zero covariance as those are not a valid fit
if np.any(cov):
fitted.append((dist_name,param),)
# Capture which distributions are not possible to be fitted (variety of reasons)
except (NotImplementedError,RuntimeError) as e:
failed.append((dist_name,e),)
pass
上面,在data_out
中捕获了经验cdf分布,该分布保存了data_in
个数据点范围内的采样cdf值。列表dist_list
对scipy.stats.rv_continuous
中的每个分布都有该分布的名称作为第一个元素,而默认参数的列表则作为第二个元素。我从scipy.stats._distr_params
中提取了默认参数。
某些分布无法拟合并引发错误。我保留这些是failed
列表。
最后,我生成一个列表fitted
,其中包含每个成功拟合的分布的估计参数。