我有一个函数 findMaxEval
,我以以下方式调用它:
eMax0,var0=findMaxEval(np.diag(eVal0),q,bWidth=.01)
其中 np.diag(eVal0)
是一个形状为 (1000,)
的 ndarray,q
是一个数字(10)。
findMaxEval
的定义如下:
def findMaxEval(eVal,q,bWidth): out=minimize(lambda *x:errPDFs(*x),.5,args= (eVal,q,bWidth),bounds=((1E-5,1-1E-5),)) if out['success']:var=out['x'][0] else:var=1 eMax=var*(1+(1./q)**.5)**2 return eMax,var
这个函数试图最小化 errPDFs
,其定义如下:
def errPDFs(var,eVal,q,bWidth,pts=1000): pdf0=mpPDF(var,q,pts) pdf1=fitKDE(eVal,bWidth,x=pdf0.index.values) sse=np.sum((pdf1-pdf0)**2) return sse
var
是一个数字,我在 findMaxEval
函数中的 minimize
中传递它,初始值为 0.5。
此外,mpPDF
和 fitKDE
定义如下:
def mpPDF(var,q,pts): eMin,eMax=var*(1-(1./q)**.5)**2,var*(1+(1./q)**.5)**2 eVal=np.linspace(eMin,eMax,pts) pdf=q/(2*np.pi*var*eVal)*((eMax-eVal)*(eVal-eMin))**.5 pdf=pd.Series(pdf,index=eVal) return pdf
def fitKDE(obs,bWidth=.25,kernel='gaussian',x=None): if len(obs.shape)==1:obs=obs.reshape(-1,1) kde=KernelDensity(kernel=kernel,bandwidth=bWidth).fit(obs) if x is None:x=np.unique(obs).reshape(-1,1) if len(x.shape)==1:x=x.reshape(-1,1) logProb=kde.score_samples(x) # log(density) pdf=pd.Series(np.exp(logProb),index=x.flatten()) return pdf
当我调用 findMaxEval
(描述中的第一行)时,我得到了以下错误:
---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-25-abd7cf64e843> in <module>----> 1 eMax0,var0=findMaxEval(np.diag(eVal0),q,bWidth=.01) 2 nFacts0=eVal0.shape[0]-np.diag(eVal0)[::-1].searchsorted(eMax0)<ipython-input-24-f44a1e9d84b1> in findMaxEval(eVal, q, bWidth) 1 def findMaxEval(eVal,q,bWidth): 2 # Find max random eVal by fitting Marcenko’s dist----> 3 out=minimize(lambda *x:errPDFs(*x),.5,args= (eVal,q,bWidth),bounds=((1E-5,1-1E-5),)) 4 if out['success']:var=out['x'][0] 5 else:var=1/opt/anaconda3/lib/python3.7/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options) 598 return _minimize_neldermead(fun, x0, args, callback, **options) 599 elif meth == 'powell':--> 600 return _minimize_powell(fun, x0, args, callback, **options) 601 elif meth == 'cg': 602 return _minimize_cg(fun, x0, args, jac, callback, **options)/opt/anaconda3/lib/python3.7/site-packages/scipy/optimize/lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options) 333 334 while 1:--> 335 # x, f, g, wa, iwa, task, csave, lsave, isave, dsave = \ 336 _lbfgsb.setulb(m, x, low_bnd, upper_bnd, nbd, f, g, factr, 337 pgtol, wa, iwa, task, iprint, csave, lsave,/opt/anaconda3/lib/python3.7/site-packages/scipy/optimize/lbfgsb.py in func_and_grad(x) 278 # unbounded variables must use None, not +-inf, for optimizer to work properly 279 bounds = [(None if l == -np.inf else l, None if u == np.inf else u) for l, u in bounds]--> 280 281 if disp is not None: 282 if disp == 0:/opt/anaconda3/lib/python3.7/site-packages/scipy/optimize/optimize.py in function_wrapper(*wrapper_args) 324 325 def function_wrapper(*wrapper_args):--> 326 ncalls[0] += 1 327 return function(*(wrapper_args + args)) 328 <ipython-input-24-f44a1e9d84b1> in <lambda>(*x) 1 def findMaxEval(eVal,q,bWidth): 2 # Find max random eVal by fitting Marcenko’s dist----> 3 out=minimize(lambda *x:errPDFs(*x),.5,args= (eVal,q,bWidth),bounds=((1E-5,1-1E-5),)) 4 if out['success']:var=out['x'][0] 5 else:var=1<ipython-input-23-24070a331535> in errPDFs(var, eVal, q, bWidth, pts) 1 def errPDFs(var,eVal,q,bWidth,pts=1000): 2 # Fit error----> 3 pdf0=mpPDF(var,q,pts) # theoretical pdf 4 pdf1=fitKDE(eVal,bWidth,x=pdf0.index.values) # empirical pdf 5 sse=np.sum((pdf1-pdf0)**2)<ipython-input-17-565d70018af2> in mpPDF(var, q, pts) 10 eVal=np.linspace(eMin,eMax,pts) 11 pdf=q/(2*np.pi*var*eVal)*((eMax-eVal)*(eVal-eMin))**.5---> 12 pdf=pd.Series(pdf,index=eVal) 13 return pdf/opt/anaconda3/lib/python3.7/site-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath) 312 313 def _init_dict(self, data, index=None, dtype=None):--> 314 """ 315 Derive the "_data" and "index" attributes of a new Series from a 316 dictionary input./opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/construction.py in sanitize_array(data, index, dtype, copy, raise_cast_failure)Exception: Data must be 1-dimensional
我不明白什么应该是“一维的”。np.diag(eVal0)
的形状是 (1000,)
。
我查看了所有其他类似的问题,但似乎没有一个能帮助我解决这个问题。
谢谢。
回答:
这个错误与边界无关。
由于某些原因,minimize()
调用了自定义函数 errPDFs()
,并传递了要优化的参数 – minimize()
调用此参数为 x0
,这是一个数组。因此,如果你重新定义函数 errPDFs()
来提取数组的第一个元素:
def errPDFs(var, eVal, q, bWidth, pts=1000): print("var:"+var) pdf0 = mpPDF(var[0], q, pts) #理论PDF pdf1 = fitKDE(eVal, bWidth, x=pdf0.index.values) #经验PDF sse = np.sum((pdf1-pdf0)**2) print("sse:"+str(sse)) return sse
它应该能工作。
示例输出:
>>> out = minimize(lambda *x: errPDFs(*x), .5, args=(eVal, q, bWidth),bounds= ((1E-5, 1-1E-5),)) var:[0.5] sse:743.6200749295413 var:[0.50000001] sse:743.6199819531047 var:[0.99999] sse:289.1462047531385 ...