python - 在 scipy 中基于频率数据有效拟合分布

标签 python scipy statistics

我有一些数据想要适应分布。数据由频率给出。我的意思是,我有我观察到的每一个事件以及我观察到它的次数。所以类似:

data = [(1, 34), (2, 1023), (3, 3243), (4, 879), (5, 202), (6, 10)]

其中每个元组中的第一个数字是我观察到的事件,第二个数字是该事件的总观察结果。

使用 Scipy,我可以通过调用 scipy.stats.lognorm.fit 来拟合(例如)对数正态分布。然而,这个例程期望看到所有观察结果的列表,而不是频率。我可以这样拟合分布:

import scipy
temp_data = []
for x in data:
    temp_data += [x[0]] * x[1]
params = scipy.stats.lognorm.fit(temp_data)

但是哇,这看起来效率非常低。

在 Scipy 或其他类似工具中,是否有基于频率的分布拟合?如果没有,是否有更好的方法来拟合分布,而不必创建潜在的巨大值列表?

最佳答案

不幸的是,看看 source ,数据的“物化”方面似乎是硬编码的。不过,该功能并不复杂,因此您可以制作自己的版本。 TBH 如果你的总 N 仍然可以管理,我可能会这样做 data = np.array(data); Expanded_data = np.repeat(data[:,0], data[:,1]) 尽管效率低下,但生命短暂。

另一种选择是使用 pomegranate ,支持传递权重:

import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import pomegranate as pg

data = [(1, 34), (2, 1023), (3, 3243), (4, 879), (5, 202), (6, 10)]

data = np.array(data)
expanded = np.repeat(data[:,0], data[:,1].astype(int))

scipy_shape, _, scipy_scale = scipy_params = scipy.stats.lognorm.fit(expanded, floc=0)
scipy_sigma, scipy_mu = scipy_shape, np.log(scipy_scale)

pg_dist = pg.LogNormalDistribution(0, 1)
pg_dist.fit(data[:,0], weights=data[:,1])
pg_mu, pg_sigma = pg_dist.parameters

fig = plt.figure()
ax = fig.add_subplot(111)

x = np.linspace(0.1, 10, 100)
ax.plot(data[:,0], data[:, 1] / data[:,1].sum(), label="freq")
ax.plot(x, scipy.stats.lognorm(*scipy_params).pdf(x),
        label=r"scipy: $\mu$ {:1.3f} $\sigma$ {:1.3f}".format(scipy_mu, scipy_sigma), alpha=0.5)
ax.plot(x, pg_dist.probability(x),
        label=r"pomegranate: $\mu$ {:1.3f} $\sigma$ {:1.3f}".format(pg_mu, pg_sigma), linestyle='--', alpha=0.5)
ax.legend(loc='upper right')
fig.savefig("compare.png")

给我

comparison of scipy with pg

关于python - 在 scipy 中基于频率数据有效拟合分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51857121/

相关文章:

python - scipy.stats.lognorm.interval 的倒数

statistics - 如何使用 awk 从文件中获取所有与统计相关的信息?

python - 有没有办法使 Plot.ly 图表 html 独立?

python - 根据原始字典中的 N 个键创建 N 个新字典

python - 将 Z 值(Z 值,标准分数)转换为 Python 中正态分布的 p 值

python - python中的Matlab样条函数

python /赛通 : Using SciPy with Cython

python - Pandas .apply() : How to use a formula in apply() that involves values from preceding cells in the same column?

python int( ) 函数

python - 使用 scipy.io 模块时导入错误