将理论分布拟合到具有 scipy 统计数据的抽样经验 CDF
Fitting a theoretical distribution to a sampled empirical CDF with scipy stats
我有一个数据包丢失的 CDF 分布图。因此,我没有原始数据或 CDF 模型本身,而是来自 CDF 曲线的样本。 (数据摘自文献中发表的图表。)
我想找到哪个分布和哪些参数提供最接近 CDF 样本的拟合。
我看到 Scipy 统计分布提供 fit(data) 方法,但所有示例都适用于原始数据点。 PDF/CDF 随后从拟合参数中得出。对我的 CDF 样本使用拟合不会给出合理的结果。
我假设 fit() 不能直接应用于经验 CDF 的数据样本是否正确?
我可以使用哪些替代方法来找到匹配的已知分布?
我不确定你到底想做什么。当您说您有 CDF 时,那是什么意思?你有一些数据点,还是函数本身?如果您能 post 更多信息或一些示例数据,将会很有帮助。
如果您有一些数据点并且知道分布,那么使用 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
可以采用一些额外的参数,并且输出会提供有关函数拟合程度的额外信息。
@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
在上面,经验 cdf 分布在 data_out
中捕获,其中包含 data_in
数据点范围内的采样 cdf 值。列表 dist_list
为 scipy.stats.rv_continuous
中的每个分布保留分布名称作为第一个元素,默认参数列表作为第二个元素。我从 scipy.stats._distr_params
中提取的默认参数。
某些分布无法拟合并引发错误。我保留那些 failed
列表。
最后,我生成了一个列表 fitted
,其中包含每个成功拟合分布的估计参数。
我有一个数据包丢失的 CDF 分布图。因此,我没有原始数据或 CDF 模型本身,而是来自 CDF 曲线的样本。 (数据摘自文献中发表的图表。)
我想找到哪个分布和哪些参数提供最接近 CDF 样本的拟合。
我看到 Scipy 统计分布提供 fit(data) 方法,但所有示例都适用于原始数据点。 PDF/CDF 随后从拟合参数中得出。对我的 CDF 样本使用拟合不会给出合理的结果。
我假设 fit() 不能直接应用于经验 CDF 的数据样本是否正确?
我可以使用哪些替代方法来找到匹配的已知分布?
我不确定你到底想做什么。当您说您有 CDF 时,那是什么意思?你有一些数据点,还是函数本身?如果您能 post 更多信息或一些示例数据,将会很有帮助。
如果您有一些数据点并且知道分布,那么使用 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
可以采用一些额外的参数,并且输出会提供有关函数拟合程度的额外信息。
@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
在上面,经验 cdf 分布在 data_out
中捕获,其中包含 data_in
数据点范围内的采样 cdf 值。列表 dist_list
为 scipy.stats.rv_continuous
中的每个分布保留分布名称作为第一个元素,默认参数列表作为第二个元素。我从 scipy.stats._distr_params
中提取的默认参数。
某些分布无法拟合并引发错误。我保留那些 failed
列表。
最后,我生成了一个列表 fitted
,其中包含每个成功拟合分布的估计参数。