2017-08-21 12 views
2

Der Versuch, den Wert d (Ganzzahl) zu erhalten, für den die Zielfunktion Std_Diff minimal ist, mit Scipy minimieren.Funktion minimieren mit Scipy minimieren

Mein Code:

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 " 

Falls ich nicht verwenden Grenzen: res = minimieren (Std_Diff, (1,), method = 'SLSQP'), erhalte ich einen anderen Fehler:

> 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. 

Vielen Dank im Voraus für Ihren Rat.

Antwort

1

(I stolpern um am Anfang, aber ich werde hier lassen, so dass Sie ein paar Ideen, wie bekommen zu debuggen.)


Sie rufen minimize mit:

Std_Diff,(1,) 

Das ist der Anfangswert ist ein Skalar (oder 1 Zahl). minimize nimmt davon eine Ahnung und setzt die Suchvariable gleich. Das ist die d übergibt es an Ihre Funktion, Std_Diff. Es erwartet aber auch, dass die Funktion einen einzelnen Wert zurückgibt. Mit anderen Worten, eine Skalarfunktion eines Skalarwerts minimieren.

So std(diff(df['BN'].values,1)) sollte einen Skalar zurückgeben. Offensichtlich nicht.


OK, Prüfung mit dem vermeintlichen 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 

Also meine erste Vermutung ist falsch.

Blick auf den Fehler-Stack, sehe ich, dass der Fehler in Ihrer Funktion auftritt, nicht nach. Es sieht aus wie ein Problem mit der Verwendung von 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]) 

Im unbeschränkten Fall kann die Suchvariable negativ gehen (sehr viel so), in np.diff einen Fehler zu erhöhen.

(der Fehler, den Sie zeigen, ist von During handling of the above exception, another exception occurred:. Es ist nicht das primäre Fehler, sondern eine sekundäre.)


Das Problem, wenn Grenzen spezifiziert, ist, dass Spezifikation unvollständig ist. Es erfordert ein (min, max) Tupel für jede Variable. So funktioniert das:

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.

Blick auf die Fehlerzeile:

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

es erwartet bnds mit 2 Spalten ein 2D-Array zu sein.Zum Beispiel:

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

I modifiziert auch die Funktion eine klarere Vorstellung davon, wie ihre Werte

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

Danke. Es funktionierte. –

Verwandte Themen