我的问题是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')