为什么Nelder Mead优化的这种实现无法收敛

时间:2019-10-04 16:39:48

标签: python python-3.x optimization scipy mathematical-optimization

我正在尝试使用Nelder Mead优化程序来估计成功收敛到Logistic回归模型的最大似然估计的概率。我正在测试各种参数值(即协变量的数量以及信号强度),使用这些参数值生成许多数据集,并尝试对每个参数进行优化。

我的问题是Nelder Mead不断说它无法收敛,因为“已经超过了迭代的最大数量”;但是输出参数似乎不错。

因此,我开始怀疑该算法的实现是否正在不合理地进行大量迭代,以确保算法尚未收敛。我对优化的形式知识了解有限,尽管我怀疑问题出在算法的“跳跃大小”上,算法需要用它来找到要测试的新单纯形以及参数空间中的梯度。我已经读过the answer in this related Cross Valiated post,但似乎暗示没有一个成功终止的标准。因此,我仍然不知如何解决科学难题。

我的代码如下。目前,它正在打印出很多值,因为我试图找出问题出在哪里。

#Script for probability of success of finding maximum likelihood estimator

#Load modules
from scipy.optimize import minimize, root
import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt
import math
import scipy
from scipy.special import erf
from scipy import stats
from matplotlib import cm
import pandas as pd
import matplotlib as mpl
norm = mpl.colors.Normalize(vmin=-1.,vmax=1.)
import time

epsilon = np.finfo(float).eps
df=500


#Define logistic function
def h(beta,X):
    beta = np.reshape(beta, (len(beta),1))
    try:
        a = X @ beta
    except:
        print('beta, X dimensions not aligned')

    h = 1/(1+np.exp(-a))
    return h

def data(p,n,beta):
    #Perhaps put all of the distributions here
    X = scipy.stats.t.rvs(df, size=(n,p))

    #X = scipy.random.normal(0,1, size=(n,p))
    #X = scipy.random.uniform(-5,5, size=(n,p))
    f=h(beta,X)
    y=np.zeros(n)
    for i,val in enumerate(f):
        r=np.random.uniform(0,1)
        if r>val:
            y[i]=1
    return X,y





def successprob(beta0,gamma0,Ncov,n,N,VN):

    Ncov,n,N = np.int(Ncov),np.int(n),np.int(N)
    s=0
    betatries={}
    times=[]
    for sample in range(N):
        beta = np.random.normal(1, 1, Ncov)
        beta = beta * gamma0/VN
        X,y = data(Ncov,n,beta)

        def negloglikelihood(beta_est):
            hlist = h(beta_est,X)
            hlist = np.reshape(hlist, (n,))
            denom = 1-hlist
            hlist = list(hlist)
            denom = list(denom)
            hlist = [val if val>2*epsilon else 2*epsilon for val in hlist]
            denom = [val if val>2*epsilon else 2*epsilon for val in denom]
            hlist = list(hlist)

            denom = list(denom)
            loglist = np.log(2*epsilon + np.divide(hlist,denom))

            negl = np.dot(y,loglist)-np.sum(np.log(2*epsilon + denom))
            return negl

        def negjac(beta_est):
            hlist = h(beta_est,X)
            njac = -1*((np.subtract(y,hlist).transpose()@X))
            return njac


        beta_est = np.zeros(Ncov)
        #betatries = np.append(betatries)minimize(negloglikelihood,beta_est,method='Nelder-Mead')['x']
        #betatries[sample]=minimize(negloglikelihood,beta_est,method='Newton-CG', jac=negjac)['x']
        start_time = time.time()
        output = minimize(negloglikelihood,beta_est,method='Nelder-Mead')
        bTF = output['success']
        print(output)
        print('true beta is ', beta)
        print('ouput is', output['x'])
        print(bTF)
        elapsed_time = time.time()-start_time
        times.append([elapsed_time])
        if bTF == True:
            s=s+1

    probconv=s/N
    print(probconv, times)
    return probconv,betatries



#Gamma values to test
gamma = np.arange(0,10.4,0.4)

#Number of samples per square
N=1

#Number of observations per sample
n=400

#Distribution of gamma0/beta0. Set both to zero here. Change others' value appropriately in the loop.
beta0 = 0
gamma0 = 0

#Kappa value up to 0.6 inclusive and number of covariates:
kappa=np.arange(0,0.65,0.05)
p=n*kappa

#Array to store hMLE values
A=np.zeros((len(p),len(gamma)))
betadata={}
VN=scipy.stats.t.var(df)
countdown=len(kappa)*len(gamma)

#Obtain data
for j in range(len(gamma)):
    gamma0 = gamma[j]
    for i,Ncov in enumerate(p):
        print(countdown, gamma0, Ncov)
        countdown=countdown-1
        A[i,j], betatries = successprob(beta0,gamma0,Ncov,n,N,VN)
        kap=kappa[i]
#        bet = betatries
#        bet= pd.DataFrame(bet)
#        for i in range(np.shape(bet)[1]):
#            plt.plot(bet[:,i])
#            plt.show()



#Plot
pd.DataFrame(A).to_csv("array_NM_tn400_%d.csv" %N, header=None, index=None)
estimates=pd.DataFrame(betadata)
estimates.to_csv("betaestimates_NM_t400_%d.csv" %N)


plt.plot(betadata['kappa0.50_gamma4.0'])

#Save
plt.savefig('s')

0 个答案:

没有答案