通过均值和标准差对scipy中负二项式的参数化

2024-05-18 05:13:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python中的包scipy将我的数据拟合成负二项分布。然而,我的验证似乎失败了

以下是我的步骤:

  1. 我有一些统计数据描述的需求数据:
mu = 1.4
std = 1.59
print(mu, std)
  1. 我使用下面的参数化函数来计算两个NB参数
def convert_params(mu, theta):
    """
    Convert mean/dispersion parameterization of a negative binomial to the ones scipy supports

    See https://en.wikipedia.org/wiki/Negative_binomial_distribution#Alternative_formulations
    """
    r = theta
    var = mu + 1 / r * mu ** 2
    p = (var - mu) / var
    return r, 1 - p

我传递了(希望是正确的…)我的两个统计数据-不同来源之间的命名约定在这一点上相当混乱prk

firstParam, secondParam = convert_params(mu, std)
  1. 然后,我将使用这两个参数来拟合分布:
from scipy.stats import nbinom

rv = nbinom(firstParam, secondParam)

然后我用百分比点函数.ppf(0.95)计算一个值R。我的问题上下文中的值R是一个重新排序点

R = rv.ppf(0.95)
  1. 现在,我希望验证前面的步骤,但我无法分别用meanmath.sqrt(var)检索我的原始统计数据
import math

mean, var = nbinom.stats(firstParam, secondParam, moments='mv')
print(mean, math.sqrt(var))

我错过了什么?对Scipy中实现的参数化有任何反馈吗


Tags: 数据convert参数var步骤mathscipymean
2条回答

看起来您正在使用不同的转换。引用的wikipedia section处的最后一个项目符号给出了如下公式。使用这些公式,您可以得到完全相同的mustd

import numpy as np
from scipy.stats import nbinom

def convert_mu_std_to_r_p(mu, std):
    r = mu ** 2 / (std ** 2 - mu)
    p = 1 - mu / std ** 2
    return r, 1 - p

mu = 1.4
std = 1.59
print("mu, std:", mu, std)
firstParam, secondParam = convert_mu_std_to_r_p(mu, std)
mean, var = nbinom.stats(firstParam, secondParam, moments='mv')
print("mean, sqrt(var):", mean, np.sqrt(var))

rv = nbinom(firstParam, secondParam)
print("reorder point:", rv.ppf(0.95))

输出:

mu, std: 1.4 1.59
mean, sqrt(var): 1.4 1.59
reorder point: 5.0

转换代码是错误的,我相信,SciPy不是使用Wiki约定,而是Mathematica约定

#%%
import numpy as np
from scipy.stats import nbinom

def convert_params(mean, std):
    """
    Convert mean/dispersion parameterization of a negative binomial to the ones scipy supports

    See https://mathworld.wolfram.com/NegativeBinomialDistribution.html
    """
    p = mean/std**2
    n = mean*p/(1.0 - p)
    return n, p

mean = 1.4
std  = 1.59

n, p = convert_params(mean, std)

print((n, p))

#%%

m, v = nbinom.stats(n, p, moments='mv')
print(m, np.sqrt(v))

代码打印回1.4,1.59对

和重新排序点计算为

rv = nbinom(n, p)
print("reorder point:", rv.ppf(0.95))

输出5

相关问题 更多 >