2017-08-21 79 views
2

尝试使用Scipy最小化来获取Std_Diff目标函数最小的d值(整数)。使用Scipy最小化函数

我的代码:

def Std_Diff(d): 
    return std(diff(df['BN'].values,d)); 

from scipy.optimize import minimize 
b=(3,) 
res = minimize(Std_Diff,(1,), method='SLSQP', bounds = b) 

The **df['BN'].values** are 
Out[72]: 
array([ 2, 2, 2, 2, 3, 2, 7, 5, 7, 11, 8, 2, 11, 7, 15, 8, 7, 
     12, 21, 19, 32, 35, 40, 35, 21, 19, 25, 20, 40, 80, 99], dtype=int64) 

Error is"IndexError: too many indices for array " 

如果我不使用:RES =最小化(Std_Diff,(1),方法= 'SLSQP'),我得到另一个错误:

> in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, 
> ftol, iprint, disp, eps, callback, **unknown_options) 
>  368     fx = float(np.asarray(func(x))) 
>  369    except: 
> --> 370     raise ValueError("Objective function must return a scalar") 
>  371    # Compute the constraints 
>  372    if cons['eq']: ValueError: Objective function must return a scalar. 

非常感谢您的建议。

回答

1

(我在一开始磕磕绊绊身边,但我会离开这里,所以你可以得到如何调试的一些想法。)


您调用minimize有:

Std_Diff,(1,) 

即初始值是一个标量(或1个数字)。 minimize需要从中找出线索,并将搜索变量设置为相同。这是d传递给你的函数,Std_Diff。但它也希望该函数也返回单个值。换句话说,最小化标量值的标量函数。

所以std(diff(df['BN'].values,1))应该返回一个标量。显然它不是。


OK,测试与所谓values

In [115]: bf 
Out[115]: 
array([ 2, 2, 2, 2, 3, 2, 7, 5, 7, 11, 8, 2, 11, 7, 15, 8, 7, 
     12, 21, 19, 32, 35, 40, 35, 21, 19, 25, 20, 40, 80, 99], dtype=int64) 
In [116]: np.std(np.diff(bf,1)) 
Out[116]: 9.9219733700285424 

所以我的第一个猜测是错误的。


仔细查看错误堆栈,我发现错误发生在您的函数中,而不是之后。它看起来像使用d的问题。

/usr/local/lib/python3.5/dist-packages/numpy/lib/function_base.py in diff(a, n, axis) 
    1913   raise ValueError(
-> 1914    "order must be non-negative but got " + repr(n)) 
    1915  a = asanyarray(a) 

ValueError: order must be non-negative but got array([-64259548.28233695]) 

在无限的情况下,搜索变量可以去负(十分左右),在np.diff引发错误。

(您显示错误是从During handling of the above exception, another exception occurred:,这不是主要的错误,但次要的。)


问题指定范围时,是该规范是不完全的。它需要每个变量的(最小,最大)元组。所以这个工程:

In [147]: minimize(Std_Diff,1, method='SLSQP', bounds=((3,None),)) 
... 
Out[147]: 
    fun: 9.921973370028542 
    jac: array([ 64259549.28233695]) 
message: 'Positive directional derivative for linesearch' 
    nfev: 3 
    nit: 5 
    njev: 1 
    status: 8 
success: False 
     x: array([ 1.]) 

Bounds for variables (only for L-BFGS-B, TNC and SLSQP). (min, max) pairs for each element in x , defining the bounds on that parameter. Use None for one of min or max when there is no bound in that direction.

看看错误行:

--> 341   bnderr = bnds[:, 0] > bnds[:, 1] 

,预计bnds是一个二维数组2列。例如:

In [153]: np.array(((3,10),)) 
Out[153]: array([[ 3, 10]]) 
In [154]: np.array((3,)) 
Out[154]: array([3]) 

我还修改了功能,有一个更清晰的认识它的价值如何变化

def Std_Diff(d): 
    print(d) 
    r = np.std(np.diff(bf,d)) 
    print(r) 
    return r 
+0

谢谢。有效。 –