scipy.stats.

fit#

scipy.stats.fit(dist, data, bounds=None, *, guess=None, method='mle', optimizer=<function differential_evolution>)[源代码]#

为数据拟合离散或连续分布

给定一个分布、数据以及分布参数的范围,返回参数的最大似然估计。

参数:
distscipy.stats.rv_continuousscipy.stats.rv_discrete

表示要拟合数据的分布的对象。

data1D array_like

将分布拟合到的数据。如果数据包含任何 np.nannp.inf 或 -np.inf,fit 方法将引发 ValueError

boundsdict 或元组序列,可选

如果是一个字典,每个键是分布的参数名称,而对应值是一个包含该参数的上限和下限的元组。如果分布仅为该参数值的有限范围定义,则无需该参数的条目;例如,一些分布具有必须在区间 [0, 1] 内的参数。参数位置 (loc) 和比例 (scale) 的边框是可选的;默认情况下,它们分别固定为 0 和 1。

如果是一个序列,元素 i 是包含分布的第 i 个参数的上限和下限的元组。在这种情况下,必须提供 所有 分布形状参数的边框。另外,可以将位置和比例的边框放在分布形状参数之后。

如果形状保持固定(例如,如果已知),则上限和下限可能相同。如果用户提供的上限或下限超出了定义分布的域的边框,则分布域的边框将替换用户提供的值。同样,必须为整数的参数约束在用户提供的边框内的整数值。

guessdict 或 array_like,可选

如果是一个字典,每个键是分布的参数名称,而对应值是参数值的一个猜测。

如果是一个序列,元素 i 是分布的第 i 个参数的一个猜测。在这种情况下,必须提供 所有 分布形状参数的猜测。

如果未提供 guess,则不会将决策变量的猜测传递给优化器。如果提供了 guess,则会将任何缺失参数的猜测设置为上限和下限的均值。必须将整数参数的猜测四舍五入为整数,而位于用户提供的边框和分布域的交集之外的猜测将被剪切。

method{‘mle’,‘mse’}

使用 method="mle"(默认值),拟合是通过最小化负对数似然函数来计算的。对于超出现在分布支持之外的观测将应用一个较大的有限处罚(而不是无限的负对数似然)。使用 method="mse",拟合是通过最小化负对数产品距离函数来计算的。对超出现在支持之外的观测应用相同的处罚。我们遵循方法 [1],该方法针对具有重复观测的样本进行了概括。

optimizer可调用,可选

optimizer 是接受以下位置参数的可调用:

函数可调用

要优化的目标函数。fun 接受一个参数 x,分布的候选形状参数,并且返回给定 xdist 和提供的 data 的目标函数值。optimizer 的工作是查找决策变量的值,使 fun 最小化。

optimizer 还必须接受以下关键字参数。

约束一元组序列

决策变量值上的约束;每个元素都是一个包含决策变量的下界和上界的元组。

如果提供了 guessoptimizer 还必须接受以下关键字参数。

x0类似数组

每个决策变量的猜测。

如果分布有任何形状参数必须是整数,或者如果分布是离散的并且位置参数未固定,optimizer 还必须接受以下关键字参数。

完整性bool 的类似数组

对于每个决策变量,如果决策变量必须约束为整数值,则为 True;如果决策变量是连续的,则为 False。

optimizer 必须返回一个对象,例如 scipy.optimize.OptimizeResult 的一个实例,它在一个属性 x 中包含决策变量的最优值。如果提供了 funstatusmessage 属性,它们将包含在 fit 返回的结果对象中。

返回:
结果FitResult

具有以下字段的对象。

参数命名元组

包含形状参数的最大似然估计值、位置和(如果适用)分布范围的命名元组。

成功布尔值或无

优化器是否认为优化已成功终止。

消息字符串或无

优化器提供的任何状态消息。

该对象具有以下方法

nllf(params=None, data=None)

默认情况下, 对于给定的 data, 是拟合的 params 中负的对数似然函数。接受包含分布的备选形状、位置和比例的元组以及备选数据的数组。

plot(ax=None)

在数据的归一化柱状图上叠加拟合分布的 PDF/PMF。

注释

当用户提供包含极大似然估计的紧限界限时, 优化更有可能收敛到极大似然估计。例如, 当将二项分布拟合到数据时, 每个样本潜在的实验次数可能是已知的, 在这种情况下, 相应的形状参数 n 可以固定。

参考文献

[1]

肖永召和玛乔丽·G·哈恩。“最大间隔乘积方法: 强一致性示例的统一公式。”伊利诺斯数学杂志 43.3 (1999): 489-499。

示例

假设我们希望为以下数据拟合分布。

>>> import numpy as np
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> dist = stats.nbinom
>>> shapes = (5, 0.5)
>>> data = dist.rvs(*shapes, size=1000, random_state=rng)

假设我们不知道数据是如何生成的, 但我们怀疑它服从具有参数 np 的负二项分布。(参阅 scipy.stats.nbinom。)我们认为参数 n 小于 30, 并且我们知道参数 p 必须在 [0, 1] 区间内。我们将此信息记录在变量 bounds 中, 并将该信息传递给 fit

>>> bounds = [(0, 30), (0, 1)]
>>> res = stats.fit(dist, data, bounds)

fit 在用户指定的 bounds 中搜索与数据最匹配的值(出于极大似然估计的考虑)。在这种情况下, 它找到了与实际生成数据的形状值相似的形状值。

>>> res.params
FitParams(n=5.0, p=0.5028157644634368, loc=0.0)  # may vary

我们可以通过在数据的归一化柱状图上叠加分布的概率质量函数(形状拟合到数据) 来可视化结果。

>>> import matplotlib.pyplot as plt  # matplotlib must be installed to plot
>>> res.plot()
>>> plt.show()
../../_images/scipy-stats-fit-1_00_00.png

请注意,n 的估计是完全积分的;这是因为 nbinom PMF 的域仅包含积分 n,而 nbinom 对象“知道”这一点。 nbinom 也知道形状 p 必须是介于 0 和 1 之间的值。在这种情况下 - 即关于某个参数的分布域有限时 - 我们不需要为该参数指定边界。

>>> bounds = {'n': (0, 30)}  # omit parameter p using a `dict`
>>> res2 = stats.fit(dist, data, bounds)
>>> res2.params
FitParams(n=5.0, p=0.5016492009232932, loc=0.0)  # may vary

如果我们希望强制将分布拟合为 n 固定在 6,我们可以将 n 的上下界都设置为 6。但是,请注意,在这种情况下,正在优化的目标函数的值通常会更差(更高)。

>>> bounds = {'n': (6, 6)}  # fix parameter `n`
>>> res3 = stats.fit(dist, data, bounds)
>>> res3.params
FitParams(n=6.0, p=0.5486556076755706, loc=0.0)  # may vary
>>> res3.nllf() > res.nllf()
True  # may vary

请注意,先前示例的数值结果是典型的,但它们可能会因 fit 所使用的默认优化器 scipy.optimize.differential_evolution 是随机的。但是,我们可以自定义优化器使用的设置以确保可重现性 - 或使用完全不同的优化器 - 使用 optimizer 参数。

>>> from scipy.optimize import differential_evolution
>>> rng = np.random.default_rng()
>>> def optimizer(fun, bounds, *, integrality):
...     return differential_evolution(fun, bounds, strategy='best2bin',
...                                   seed=rng, integrality=integrality)
>>> bounds = [(0, 30), (0, 1)]
>>> res4 = stats.fit(dist, data, bounds, optimizer=optimizer)
>>> res4.params
FitParams(n=5.0, p=0.5015183149259951, loc=0.0)