Python 如何实现最大似然估计类型2?

Python 如何实现最大似然估计类型2?,python,scipy,sympy,bayesian,pymc3,Python,Scipy,Sympy,Bayesian,Pymc3,我试图实现一种经验贝叶斯ML-II(最大似然估计II型)方法,用于从历史数据估计先验分布参数 其中: π(θ)是先验分布的表达式 p(x |θ)是数据分布的表达式 m(x)是边际分布的表达式 根据这些步骤,我需要先积分找到边际分布的表达式,然后找到这个表达式的极值来估计先验分布的参数。 可以使用scipy.optimize等方法获得极值。所以问题是我们如何整合这一点 现在可以使用symfit进行此操作。作为一个例子,我选择从没有协方差的二元正态分布中取样 import numpy as np i

我试图实现一种经验贝叶斯ML-II(最大似然估计II型)方法,用于从历史数据估计先验分布参数

其中:

  • π(θ)是先验分布的表达式
  • p(x |θ)是数据分布的表达式
  • m(x)是边际分布的表达式
  • 根据这些步骤,我需要先积分找到边际分布的表达式,然后找到这个表达式的极值来估计先验分布的参数。 可以使用
    scipy.optimize
    等方法获得极值。所以问题是我们如何整合这一点


    现在可以使用
    symfit
    进行此操作。作为一个例子,我选择从没有协方差的二元正态分布中取样

    import numpy as np
    import matplotlib.pyplot as plt
    from symfit import Model, Fit, Parameter, Variable, integrate, oo
    from symfit.distributions import Gaussian
    from symfit.core.objectives import LogLikelihood
    
    # Make variables and parameters
    x = Variable('x')
    y = Variable('y')
    m = Variable('m')
    x0 = Parameter('x0', value=0.6, min=0.5, max=0.7)
    sig_x = Parameter('sig_x', value=0.1)
    y0 = Parameter('y0', value=0.7, min=0.6, max=0.9)
    sig_y = Parameter('sig_y', value=0.05)
    
    pdf = Gaussian(x=x, mu=x0, sig=sig_x) * Gaussian(x=y, mu=y0, sig=sig_y)
    marginal = integrate(pdf, (y, -oo, oo), conds='none')
    print(pdf)
    print(marginal)
    
    model = Model({m: marginal})
    
    # Draw 10000 samples from a bivariate distribution
    mean = [0.59, 0.8]
    cov = [[0.11**2, 0], [0, 0.23**2]]
    xdata, ydata = np.random.multivariate_normal(mean, cov, 10000).T
    
    # We provide only xdata to the model
    fit = Fit(model, xdata, objective=LogLikelihood)
    fit_result = fit.execute()
    print(fit_result)
    
    xaxis = np.linspace(0, 1.0)
    plt.hist(xdata, bins=100, density=True)
    plt.plot(xaxis, model(x=xaxis, **fit_result.params).m)
    plt.show()
    
    这将打印pdf和边际分布的以下内容:

    >>> exp(-(-x0 + x)**2/(2*sig_x**2))*exp(-(-y0 + y)**2/(2*sig_y**2))/(2*pi*Abs(sig_x)*Abs(sig_y))
    >>> sqrt(2)*sig_y*exp(-(-x0 + x)**2/(2*sig_x**2))/(2*sqrt(pi)*Abs(sig_x)*Abs(sig_y))
    
    对于拟合结果:

    Parameter Value        Standard Deviation
    sig_x     1.089585e-01 7.704533e-04
    sig_y     5.000000e-02 nan
    x0        5.905688e-01 -0.000000e+00
    Fitting status message: b'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
    Number of iterations:   9
    Regression Coefficient: nan
    
    参数值标准偏差
    sig_x 1.089585e-01 7.704533e-04
    sig__y 5.000000e-02 nan
    x0 5.905688e-01-0.000000e+00
    
    拟合状态信息:b'CONVERGENCE:REL_REDUCTION___@merv我们亲爱的merv,谢谢。我知道类似pymc3的贝叶斯模型包。我问过他们,他们说经验贝叶斯不是通用的方法,他们没有实现ML-II。特别是,这个ML-II不是地图。看起来pymc3的地图方法不做ML-II。也许
    symfit
    可以帮助你,看看文档中的例子。然后,您将能够使用
    sympy
    样式的分析表达式,并使用
    scipy
    将它们与您的数据相匹配,而无需与
    scipy
    交互。免责声明:我是
    symfit
    @tBuLi的作者,我已经阅读了你的链接,似乎我还需要自己编写模型的公式,这正是我遇到的问题,我需要先积分来找到边际分布的表达式。如果我要用我的大脑积分来计算这个表达式,这就是我遇到麻烦的地方,我希望能够编写一些通用代码来集成这个表达式。我纠正了我的想法,你有一个模型的分析表达式,但是希望有一些自动化的方法来将它集成到一个边际分布中,然后你需要适应一个数据集?如果是这样的话,请告诉我,然后我将为您写一个如何使用symfit实现此目的的示例。@tBuLi您的理解给我留下了深刻的印象!事实上,估计先验分布参数的方法是将先验分布乘以似然函数进行积分,然后在获得边际分布表达式后,找出哪种先验分布参数可以使边际分布的值最大化。然后,这些参数将作为先验分布的参数来进行最大后验估计亲爱的李先生,你给我留下了深刻的印象!但这里有一些区别:如果y0是一个数据分布,那么它的平均值服从高斯分布。似乎y0的平均值是一个固定参数,而不是服从高斯分布的随机变量。我怎样才能修改你的代码来达到这个目的?住手,你让我脸红了。是的,你是对的,在我的例子中,我使用了两个不相关的高斯,因此
    y0
    对拟合没有影响,因为它不出现在边缘分布中。但是如果它们相互依赖,
    y0
    它将不会被集成。因此,为了建立您的模型,您必须调整我的
    pdf
    ,以反映您的问题。所以:
    pdf=pi*p
    ,然后积分出
    theta
    。这应该给你
    m