2016-11-17 2 views
1

Ich bin eine lineare Funktion mit scipy OptimierungAttribute: ‚schweben‘ Objekt hat kein Attribut ‚Gradient‘ scipy Python

def func(weights): 
     var = ['x1', 'x2', 'x3', 'x4'] 
     if weights is None: 
      weights = np.ones(len(var))/len(var) 
     return len(set([var[i] for i in range(len(weights)) if weights[i]>0]))/len(var) 

res = minimize(lambda x: func(x), x0=[0.25,0.25,0.25,0.25],method='SLSQP', 
         jac=ad.gh(lambda x: func(x))[0], bounds=((0.,1.),)*4, 
         options = {'disp':True, 'ftol': 1e-20, 'maxiter': 1000}, 
         constraints= {'type': 'eq', 'fun': lambda x: sum(x) - 1.0}) 

ich die folgende Fehlermeldung zu bekommen.

Traceback (most recent call last): 
    File "D:/applicatio/Sub Applicatio/main.py", line 338, in <module> 
    constraints= {'type': 'eq', 'fun': lambda x: sum(x) - 1.0}) 
    File "C:\Users\hp\Downloads\WinPython-64bit-3.5.1.2\python-3.5.1.amd64\lib\site-packages\scipy\optimize\_minimize.py", line 455, in minimize 
    constraints, callback=callback, **options) 
    File "C:\Users\hp\Downloads\WinPython-64bit-3.5.1.2\python-3.5.1.amd64\lib\site-packages\scipy\optimize\slsqp.py", line 383, in _minimize_slsqp 
    g = append(fprime(x),0.0) 
    File "C:\Users\hp\Downloads\WinPython-64bit-3.5.1.2\python-3.5.1.amd64\lib\site-packages\scipy\optimize\optimize.py", line 289, in function_wrapper 
    return function(*(wrapper_args + args)) 
    File "C:\Users\hp\Downloads\WinPython-64bit-3.5.1.2\python-3.5.1.amd64\lib\site-packages\ad\__init__.py", line 1090, in grad 
    return numpy.array(ans.gradient(list(xa))) 
AttributeError: 'float' object has no attribute 'gradient' 

Wie kann ich diese einfache lineare Funktion optimieren? Irgendwelche Vorschläge ? Vielen Dank.

+1

Es sieht so aus, als ob Sie SLSQP verwenden; verlangt das * nicht, dass Sie die Jacobi in den Beschränkungen übergeben? – Prune

+1

Der Fehler sieht so aus, als ob Ihre Ableitungsdefinition 1D ist, während Ihre Funktion 4D ist. Welche Größe hat 'ad.gh (Lambda x: func (x)) [0]'? – aTben0

+1

Aufgrund der Kopplung von 'if',' set' und 'len' sind Sie sicher, dass die Ableitungen im definierten Raum existieren? – aTben0

Antwort

2

Was zur Hölle macht Ihre func?

def func(weights): 
    .... 
    return len(set())/len(var) 

Sie erhalten ein set Objekt, und dann ist es die Länge, die Anzahl der Begriffe. Was bedeutet das? Das ist nicht linear; es dauert ganzzahlige Sprünge.

In [318]: x0=[0.25,0.25,0.25,0.25] 
In [319]: def func(weights): 
    ...:   var = ['x1', 'x2', 'x3', 'x4'] 
    ...:   if weights is None: 
    ...:   weights = np.ones(len(var))/len(var) 
    ...:   return len(set([var[i] for i in range(len(weights)) if weights 
    ...: [i]>0]))/len(var) 
    ...:  
In [320]: func(x0) 
Out[320]: 1.0 
In [321]: x0=np.array(x0) 
In [322]: func(x0) 
Out[322]: 1.0 
In [323]: func(x0+.1) 
Out[323]: 1.0 
In [324]: func(x0-.1) 
Out[324]: 1.0 
In [325]: func(x0-1) 
Out[325]: 0.0 

In der Tat alles ist, wie viele der x0 Werte zählt >0 und dividieren durch 4 - so erzeugt sie 0, .25, .5, .75 oder 1.

minimize gehen wird Beginnen Sie mit x0, und finden Sie heraus, wie func(x0) mit kleinen Änderungen in x0 variiert.

Und Ihre jac, ist etwas, auf Basis dieser func auch, jac=ad.gh(lambda x: func(x))[0]

==============

Ich glaube nicht, dass Sie das verwenden müssen lambda

`lambda x: func(x)` 

Gib func als Argument. Es nimmt die richtige Anzahl von Argumenten (z. B. die ursprüngliche x0).

===================

Laufen Sie den Code, aber ohne den jac Parameter (ich weiß nicht, was ad.gh ist):

In [543]: def func(weights): 
    ...:   var = ['x1', 'x2', 'x3', 'x4'] 
    ...:   if weights is None: 
    ...:   weights = np.ones(len(var))/len(var) 
    ...:   return len(set([var[i] for i in range(len(weights)) if weights 
    ...: [i]>0]))/len(var) 
    ...:  
In [544]: optimize.minimize(lambda x: func(x), x0=[0.25,0.25,0.25,0.25],method=' 
    ...: SLSQP',bounds=((0.,1.),)*4,options = {'disp':True, 'ftol': 1e-20, 'max 
    ...: iter': 1000},constraints= {'type': 'eq', 'fun': lambda x: sum(x) - 1.0 
    ...: }) 
Optimization terminated successfully. (Exit mode 0) 
      Current function value: 1.0 
      Iterations: 1 
      Function evaluations: 6 
      Gradient evaluations: 1 
Out[544]: 
    fun: 1.0 
    jac: array([ 0., 0., 0., 0., 0.]) 
message: 'Optimization terminated successfully.' 
    nfev: 6 
    nit: 1 
    njev: 1 
    status: 0 
success: True 
     x: array([ 0.25, 0.25, 0.25, 0.25]) 

Es sieht so aus, als ob es kleine Änderungen um x0 versucht, und findet, dass es keine Variation gibt (kleine Änderungen lassen keine Elemente zu 0 gehen). Um es anders auszudrücken, Ihre func ist bereits auf einem lokalen Minimum, eine flache Region.

+0

@hpaulij Eigentlich haben Sie Recht .. Ich zähle tatsächlich die Anzahl der x0-Werte, wenn> 0. Eigentlich habe ich eine mehrzielige Optimierung und ich habe 2 andere Ziele, die perfekt funktionieren. Ich habe einfach nicht verstanden, wie ich diese Funktion minimieren kann. Ich habe Ihren Weg ohne Lambda-Funktion versucht, aber dann wirft es "TypeError: 'Methode' Objekt ist nicht einklagbar" – muazfaiz

+0

Erwarten Sie, dass die Lösung 3 0 Begriffe und eine 1, maximale Anzahl von 0s aber Summierung auf 1?Können Sie den 'jac' Parameter entfernen? – hpaulj

+0

Es läuft ohne den 'jac' Parameter. – hpaulj

Verwandte Themen