简体   繁体   English

受Python约束的MLE

[英]Constrained MLE with Python

I'm doing a MLE implementation with Python. 我正在使用Python执行MLE实现。 My log-likelihood function has 5 parameters to be estimated and two of them has the constraint that they must be between 0 and 1. I'm able to implement a MLE using GenericLikelihoodModel module from the statsmodels package but I don't know how to do this with the constraint. 我的对数似然函数有5个要估计的参数,其中两个具有必须在0到1之间的约束。我能够使用statsmodels包中的GenericLikelihoodModel模块来实现MLE,但我不知道如何用约束来做到这一点。 To be specific, my negative log-likelihood function is 具体来说,我的负面对数似然函数是

def ekop_ll(bs,alpha,mu,sigma,epsilon_b,epsilon_s):
    ll=[]
    for bsi in bs:
        b=bsi[0]
        s=bsi[1]
        part1 = (1-alpha)*stats.poisson.pmf(b,epsilon_b)*stats.poisson.pmf(s,epsilon_s)
        part2 = alpha*sigma*stats.poisson.pmf(b,epsilon_b)*stats.poisson.pmf(s,mu+epsilon_s)
        part3 = alpha*(1-sigma)*stats.poisson.pmf(b,mu+epsilon_b)*stats.poisson.pmf(s,epsilon_s)
        li = part1+part2+part3
        if part1+part2+part3 == 0:
            li = 10**(-100)
        lli = np.log(li)
        ll.append(lli)
    llsum = -sum(ll)
    return llsum 

and the MLE optimization class is MLE优化类是

class ekop(GenericLikelihoodModel):
    def __init__(self,endog,exog=None,**kwds):
        if exog is None:
            exog = np.zeros_like(endog)
        super(ekop,self).__init__(endog,exog,**kwds)
    def nloglikeobs(self,params):
        alpha = params[0]
        mu = params[1]
        sigma = params[2]
        epsilon_b = params[3]
        epsilon_s = params[4]
        ll = ekop_ll(self.endog,alpha=alpha,mu=mu,sigma=sigma,epsilon_b=epsilon_b,epsilon_s=epsilon_s)
        return ll
    def fit(self, start_params=None, maxiter=10000, maxfun=5000, **kwds):
         if start_params == None:
             # Reasonable starting values
             alpha_default = 0.5
             mu_default = np.mean(self.endog)
             sigma_default = 0.5
             epsilon_b_default = np.mean(self.endog)
             epsilon_s_default = np.mean(self.endog)
             start_params =[alpha_default,mu_default,sigma_default,epsilon_b_default,epsilon_s_default]
         return super(ekop, self).fit(start_params=start_params,
                                      maxiter=maxiter, maxfun=maxfun,
                                      **kwds) 

And the main is 主要是

if __name__ == '__main__':
    bs = #my data#
    mod = ekop(bs)
    res = mod.fit() 

I don't know how to modify my code to incorporate the constraint. 我不知道如何修改我的代码以合并约束。 I would like alpha and sigma to be between 0 and 1. 我希望alpha和sigma在0和1之间。

One common approach to get an interior solution that satisfies the constraints is to transform the parameters so the optimization is unconstrained. 获得满足约束条件的内部解决方案的一种常用方法是对参数进行转换,以使优化不受约束。

For example: A constraint to be in the open interval (0, 1) can be transformed using the Logit function, used for example here: 例如:可以使用Logit函数转换在开放时间间隔(0,1)中的约束,例如在这里使用:

https://github.com/statsmodels/statsmodels/blob/master/statsmodels/miscmodels/count.py#L243 https://github.com/statsmodels/statsmodels/blob/master/statsmodels/miscmodels/count.py#L243

We can use a mulinomial logit for probabilities, parameters that are in (0, 1) and add up to one. 我们可以使用多项式logit表示概率,这些参数在(0,1)中,并且加起来等于1。

In generalized linear models we use the link functions to impose similar restriction for the predicted mean, see statsmodels/genmod/families/links.py. 在广义线性模型中,我们使用链接函数对预测平均值施加类似的限制,请参见statsmodels / genmod / families / links.py。

If constraints can be binding, then this does not work. 如果约束可以绑定,那么这是行不通的。 Scipy has constrained optimizers but those are not yet connected to the statsmodels LikelihoodModel classes. Scipy限制了优化器,但尚未将其连接到statsmodels LikelihoodModel类。

Related aside: scipy has a global optimizer, basinhopping, that works pretty well if there are multiple local minima, and it is connected to the LikelihoodModels and can be chosen using the method argument in fit. 撇开相关内容:scipy有一个全局优化器,basichopping,如果存在多个局部最小值,则效果很好,并且它与LikelihoodModels连接,可以使用fit参数进行选择。

IMHO this is a math question and the simple answer is that you should remodel your question. 恕我直言,这是一个数学问题,简单的答案是您应该重塑问题。

To address the problem specifically - you should create a special case model derived from your original model with the constraints inherently defined in it. 为了专门解决该问题,您应该创建一个从原始模型派生的特殊情况模型,并在其中固有地定义约束。 Then the calculated MLE for the special case model would give you the estimation you're looking for. 然后,针对特殊情况模型计算出的MLE将为您提供所需的估计。

BUT - the estimation would be swell for the derived model with the constraints AND NOT for the general case model as in the original model two parameters were not constrained. 但是-对于具有约束条件的派生模型,估计会膨胀,而对于一般情况模型,则不会如此,因为在原始模型中,两个参数均不受约束。

Actually, any method you'll use for parameter estimation like MCMC, ANNs, Newton-based's iterative methods, and others they all shall give you an estimation for the derived and constrained model. 实际上,您将用于参数估计的任何方法(例如MCMC,ANN,基于牛顿的迭代方法,以及其他所有方法)都将为您提供派生和受约束模型的估计。

Indeed this is a math question rather than programming question. 确实,这是一个数学问题,而不是编程问题。 I managed to solve this question by transforming the parameters with constraints,ie alpha and sigma into alpha_hat and sigma_hat, 我设法通过将约束条件即alpha和sigma转换为alpha_hat和sigma_hat来解决了这个问题,

    alpha = 1/(1+np.exp(-alpha_hat))
    sigma = 1/(1+np.exp(-sigma_hat))

so that we can estimate alpha_hat and sigma_hat with no constraints. 这样我们就可以不受限制地估计alpha_hat和sigma_hat。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM