2016-06-14 33 views
1

我正在用Python進行MLE實現。我的對數似然函數有5個參數需要估計,其中兩個約束條件是它們必須在0和1之間。我能夠使用statsmodels包中的GenericLikelihoodModel模塊實現MLE,但我不知道如何用約束來做到這一點。 具體而言,我負對數似然函數是Python中的約束MLE

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 

和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) 

而且主要是

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

我不知道該怎麼修改我的代碼以包含約束。我希望alpha和sigma在0和1之間。

回答

1

獲得滿足約束條件的內部解決方案的一種常見方法是轉換參數,使優化不受約束。

例如:約束是在開區間(0,1)可以使用的Logit函數變換,例如用於這裏:

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

我們可以使用概率的mulinomial分對數,(0,1)中的參數加起來爲1。

在廣義線性模型中,我們使用鏈接函數對預測均值施加類似限制,請參閱statsmodels/genmod/families/links.py。

如果約束可以綁定,那麼這是行不通的。 Scipy限制了優化器,但這些優化器尚未連接到statsmodels LikelihoodModel類。相關除外:scipy擁有一個全局優化器basinhopping,如果存在多個局部最小值,那麼它將工作得非常好,並且它連接到LikelihoodModels,並且可以使用fit中的方法參數進行選擇。

0

恕我直言,這是一個數學問題,簡單的答案是你應該改造你的問題。

爲了解決這個問題,你應該創建一個特定的案例模型,它是從你的原始模型中派生出來的,這個模型具有固有的約束條件。然後,計算出的特殊情況模型MLE會給你你正在尋找的估計。

但是 - 對於具有約束AND NOT的一般情況模型的導出模型的估計將是膨脹的,因爲在原始模型中兩個參數不受約束。實際上,任何用於參數估計的方法(如MCMC,ANNs,基於牛頓的迭代方法)以及其他所有方法都會給出對導出和約束模型的估計。

0

事實上,這是一個數學問題,而不是編程問題。我設法通過用約束變換參數來解決這個問題, alpha和sigma轉換成alpha_hat和sigma_hat,

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

這樣我們可以估計沒有約束的alpha_hat和sigma_hat。