Python异常:数据必须是一维的

5

我有一个名为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是我在minimize函数中传递给findMaxEval函数的数字,初始值为0.5。

此外,mpPDFfitKDE已定义:

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

我查看了其他类似的问题,但似乎没有帮助我解决这个问题。

谢谢。

2个回答

2

更新于6/29 ... 我按照以下方式运行它,这很奇怪,因为它是相同的东西,可能是库中的一个错误或者显式转换可以将其转换为所需的精确格式:

import numpy as np
import pandas as pd
from scipy.optimize import minimize
from sklearn.neighbors import KernelDensity

def findMaxEval(eVal, q, bWidth):
    bnds = ((float(1e5/10000000000), float(0.99999*-1)),)

    print(bnds)
    out = minimize(lambda *x: errPDFs(*x), .5, args=(eVal, q, bWidth), bounds=bnds)
    if out['success']: var = out['x'][0]
    else: var = 1
    eMax = var*(1+(1./q)**.5)**2
    return eMax, var

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

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)
    pdf=pd.Series(np.exp(logProb), index=x.flatten())
    return pdf

eMax0, var0 = findMaxEval((1000,), 10, bWidth=.01)

print(eMax0)
print(var0)

以下是在 PyCharm Community 中使用 Macbook,Python 版本 3.8.1 的更新输出结果:

enter image description here


1
我会在今晚稍晚些的时间查看并回复。 - FisheyJay
1
我知道了... 我现在正在工作,但今晚会看一下并回复。有趣,我们会解决的,不用担心。 - FisheyJay
1
谢谢。我也遇到了这个问题。你也在研究《资产管理的机器学习(量化金融元素)》吗?我已经开始在这里实现代码片段和练习:https://github.com/emoen/Machine-Learning-for-Asset-Managers - Endre Moen
1
在mlfinlab的github上还有代码片段等实现。在那里,他们对数组进行了拆包:https://github.com/hudson-and-thames/mlfinlab/blob/master/mlfinlab/portfolio_optimization/risk_estimators.py#L449 - Endre Moen
1
感谢您的努力,Jeanpierre。@EndreMoen在他的回答中展示的内容解决了我的问题。我发布这个标题的问题是因为我一直得到这个错误,无法继续前进。结果发现与我们想象的定义边界没有任何关系。 你们两个都认为我应该编辑问题吗?我觉得评论中已经有很好的流程,让未来的读者理解。 - Jovan
显示剩余7条评论

2

这个错误与边界无关。

由于某种原因,minimize()使用要优化的参数调用自定义函数errPDFs() - minimize()在x0上调用此函数 - 这是一个数组。因此,如果重新定义errPDFs()函数以提取数组的第一个元素:

def errPDFs(var, eVal, q, bWidth, pts=1000):
    print("var:"+var)
    pdf0 = mpPDF(var[0], q, pts) #theoretical pdf
    pdf1 = fitKDE(eVal, bWidth, x=pdf0.index.values) #empirical 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
 ...

谢谢!这解决了我的问题。实际上,如果你在最小化过程中打印出“var”,你会发现它是一个数组,而我一直没有以正确的方式访问它。你正确指出了mlfinlab的实现方式。 我还在实现《资产管理的机器学习》中的代码片段,这就是问题的根源。 - Jovan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接