【问题标题】:What's the equivalent of fitdist and histfit in Python?Python 中 fitdist 和 histfit 的等价物是什么?
【发布时间】:2019-06-17 07:27:25
【问题描述】:

--- 示例 ---

我有一个数据集(样本),它在一维数组 (see the attached .json file) 中包含 1000 个损坏值(这些值非常小)。样本似乎遵循对数正态分布:

---问题和我已经尝试过的---

我尝试了这篇文章Fitting empirical distribution to theoretical ones with Scipy (Python)? 和这篇文章Scipy: lognormal fitting 中的建议,以通过对数正态分布拟合我的数据。这些都不起作用。 :(

我总是在 Y 轴上得到非常大的东西,如下所示:

这是我在 Python 中使用的代码(data.json 文件可以从here 下载):

from matplotlib import pyplot as plt
from scipy import stats as scistats
import json
with open("data.json", "r") as f:
  sample = json.load(f) # load data: a 1000 * 1 array with many small values( < 1e-6)
fig, axis = plt.subplots() # initiate a figure
N, nbins, patches = axis.hist(sample, bins = 40) # plot sample by histogram
axis.ticklabel_format(style = 'sci', scilimits = (-3, 4), axis = 'x') # make X-axis to use scitific numbers
axis.set_xlabel("Value")
axis.set_ylabel("Count")    
plt.show()

fig, axis = plt.subplots()
param = scistats.lognorm.fit(sample) # fit data by Lognormal distribution
pdf_fitted = scistats.lognorm.pdf(nbins, * param[: -2], loc = param[-2], scale = param[-1]) # prepare data for ploting fitted distribution
axis.plot(nbins, pdf_fitted) # draw fitted distribution on the same figure
plt.show()

我尝试了另一种分布,但是当我尝试绘制结果时,Y 轴总是太大,我无法用我的直方图绘制。我哪里失败了???

我还尝试了另一个问题中的建议:Use scipy lognormal distribution to fit data with small values, then show in matplotlib。但是变量pdf_fitted的值总是太大。

--- 期待结果---

基本上我想要的是这样的:

这是我在上面截图中使用的 Matlab 代码:

fname = 'data.json';
sample = jsondecode(fileread(fname));

% fitting distribution
pd = fitdist(sample, 'lognormal')

% A combined command for plotting histogram and distribution
figure();
histfit(sample,40,"lognormal")

所以如果你对 Python/Scipy/Numpy/Matplotlib 中 fitdisthistfit 的等效命令有任何想法,请发布!

非常感谢!

【问题讨论】:

    标签: python matlab matplotlib scipy


    【解决方案1】:

    试试 distfit(或 fitdist)库。

    https://erdogant.github.io/distfit/

    pip install distfit
    
    import numpy as np
    
    # Example data
    X = np.random.normal(10, 3, 2000)
    y = [3,4,5,6,10,11,12,18,20]
    
    # From the distfit library import the class distfit
    from distfit import distfit
    
    # Initialize
    dist = distfit()
    
    # Search for best theoretical fit on your emperical data
    dist.fit_transform(X)
    
    # Plot
    dist.plot()
    
    # summay plot
    dist.plot_summary()
    

    所以你的情况是:

    dist = distfit(distr='lognorm')
    dist.fit_transform(X)
    

    【讨论】:

    • 如何使用 distfit 设置 floc = 0?我在文档中找不到。
    • 没有输入参数强制将其设为指定值。在正态分布的情况下,位置 (loc) 关键字指定平均值。 scale 关键字指定标准偏差。但其他发行版使用它来转移和/或扩展分布。所以手动设置这些可能不是那么简单。有趣的是,您不必担心这些参数,而是使用 distfit 为您估算。
    【解决方案2】:

    试试seaborn:

    import seaborn as sns, numpy as np
    sns.set(); np.random.seed(0)
    x = np.random.randn(100)
    ax = sns.distplot(x)
    

    【讨论】:

    • 嗨,有没有只使用“更常见”模块的解决方案,比如 scipy 或 numpy ?
    【解决方案3】:

    我使用 Openturns 库尝试了您的数据集

    x 是 json 文件中给出的列表。

    import openturns as ot
    from openturns.viewer import View
    import matplotlib.pyplot as plt
    
    # first format your list x as a sample of dimension 1
    sample = ot.Sample(x,1) 
    
    # use the LogNormalFactory to build a Lognormal distribution according to your sample
    distribution = ot.LogNormalFactory().build(sample)
    
    # draw the pdf of the obtained distribution
    graph = distribution.drawPDF()
    graph.setLegends(["LogNormal"])
    View(graph)
    plt.show()
    

    如果你想要分布的参数

    print(distribution)
    >>> LogNormal(muLog = -16.5263, sigmaLog = 0.636928, gamma = 3.01106e-08)
    

    您可以通过调用 HistogramFactory 以相同的方式构建直方图,然后您可以将一个图表添加到另一个图表:

    graph2 = ot.HistogramFactory().build(sample).drawPDF()
    graph2.setColors(['blue'])
    graph2.setLegends(["Histogram"])
    graph2.add(graph)
    View(graph2)
    

    如果要缩放,请设置边界值

    axes = view.getAxes()
    _ = axes[0].set_xlim(-0.6e-07, 2.8e-07)
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 1970-01-01
      • 2011-09-03
      • 2011-03-07
      • 2021-06-19
      • 2017-04-20
      • 2012-09-26
      • 2011-04-13
      • 2017-10-26
      相关资源
      最近更新 更多