2017-08-21 119 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

謝謝。有效。 –