fit#
- scipy.stats.fit(dist, data, bounds=None, *, guess=None, method='mle', optimizer=<function differential_evolution>)[源代码]#
为数据拟合离散或连续分布
给定一个分布、数据以及分布参数的范围,返回参数的最大似然估计。
- 参数:
- dist
scipy.stats.rv_continuous
或scipy.stats.rv_discrete
表示要拟合数据的分布的对象。
- data1D array_like
将分布拟合到的数据。如果数据包含任何
np.nan
、np.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
,分布的候选形状参数,并且返回给定x
、dist 和提供的 data 的目标函数值。optimizer 的工作是查找决策变量的值,使 fun 最小化。
optimizer 还必须接受以下关键字参数。
- 约束一元组序列
决策变量值上的约束;每个元素都是一个包含决策变量的下界和上界的元组。
如果提供了 guess,optimizer 还必须接受以下关键字参数。
- x0类似数组
每个决策变量的猜测。
如果分布有任何形状参数必须是整数,或者如果分布是离散的并且位置参数未固定,optimizer 还必须接受以下关键字参数。
- 完整性bool 的类似数组
对于每个决策变量,如果决策变量必须约束为整数值,则为 True;如果决策变量是连续的,则为 False。
optimizer 必须返回一个对象,例如
scipy.optimize.OptimizeResult
的一个实例,它在一个属性x
中包含决策变量的最优值。如果提供了fun
、status
或message
属性,它们将包含在fit
返回的结果对象中。
- dist
- 返回:
- 结果
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)
假设我们不知道数据是如何生成的, 但我们怀疑它服从具有参数 n 和 p 的负二项分布。(参阅
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()
请注意,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)