2016-12-14 6 views
0

Ich versuche einen Vektor zu finden, der die Restsumme der Quadrate minimiert, wenn eine Matrix multipliziert wird.Finde den optimalen Vektor, der die Funktion minimiert

Ich kenne scipy's optimize-Paket (das eine Minimierungsfunktion hat). Es gibt jedoch eine zusätzliche Einschränkung für meinen Code. Die Summe aller Einträge von w (siehe Funktion unten) muss gleich 1 sein, und kein Eintrag von w darf kleiner als 0 sein. Gibt es ein Paket, das das für mich tut? Wenn nicht, wie kann ich das tun?

Der Versuch, zu minimieren w:

def w_rss(w,x0,x1): 
    predictions = np.dot(x0,w) 
    errors = x1 - predictions 
    rss = np.dot(errors.transpose(),errors).item(0) 

    return rss 

X0 = np.array([[3,4,5,3], 
       [1,2,2,4], 
       [6,5,3,7], 
       [1,0,5,2]]) 

X1 = np.array([[4], 
       [2], 
       [4], 
       [2]]) 

W = np.array([[.0], 
       [.5], 
       [.5], 
       [.0]]) 

print w_rss(W,X0,X1) 

Bisher dies bei Durchschleifen möglichen Werte von w mein bester Versuch ist, aber es ist nicht richtig funktioniert.

def get_w(x0,x1): 

J = x0.shape[1] 
W0 = np.matrix([[1.0/J]*J]).transpose() 
rss0 = w_rss(W0,x0,x1) 
loop = range(J) 
for i in loop: 
    W1 = W0 
    rss1 = rss0 
    while rss0 == rss1: 
     den = len(loop)-1 
     W1[i][0] += 0.01 
     for j in loop: 
      if i == j: 
       continue 
      W1[j][0] -= 0.01/den 
      if W1[j][0] <= 0: 
       loop.remove(j) 
     rss1 = w_rss(W1,x0,x1) 
     if rss1 < rss0: 
      #print W1 
      W0 = W1 
      rss0 = rss1 
     print '--' 
     print rss0 
     print W0 

return W0,rss0 
+0

Sie können Verwenden Sie dafür einen QP-Löser (quadratische Programmierung). –

+0

Ich habe dies in scipy.optimize versucht: Cons = ({'Typ': 'eq', 'Spaß': Lambda x: 1 - Summe (x)}) {{NEW LINE}} bnds = Tupel ((0,1) für x in W) {{NEUE LINIE}} minimieren (w_rss, W1, args = (V, X0, X1), Methode = 'SLSQP', Grenzen = Bnds, Einschränkungen = Nachteile). Lösung war falsch. –

+0

Dies ist ein Allzweck-NLP-Löser. Es sollte mit einem ordnungsgemäßen Setup-Problem funktionieren, aber ich würde empfehlen, einen echten QP-Solver zu verwenden. –

Antwort

2

Der SLSQP-Code in scipy kann dies tun. Sie können scipy.optimize.minimize mit method='SLSQP verwenden, oder Sie können die Funktion fmin_slsqp direkt verwenden. Im Folgenden verwende ich fmin_slsqp.

Die scipy Lösern allgemeinen einen eindimensionales Array zur objektiven Funktion übergeben, so konsistent zu sein, und ich werde WX1 ändern 1-d-Arrays zu sein, und ich werde die Zielfunktion schreiben (jetzt genannt w_rss1) ein 1-d-Argument zu erwarten w.

Die Bedingung, dass alle Elemente in w müssen 0 und 1 liegen zwischen den bounds Argument angegeben wird, und die Bedingung, dass die Summe der 1 f_eqcons Argument angegeben sein muss. Die Einschränkung Funktion gibt np.sum(w) - 1, so ist es 0, wenn die Summe der Elemente ist 1.

Hier ist der Code:

import numpy as np 
from scipy.optimize import fmin_slsqp 


def w_rss1(w, x0, x1): 
    predictions = np.dot(x0, w) 
    errors = x1 - predictions 
    rss = (errors**2).sum() 
    return rss 


def sum1constraint(w, x0, x1): 
    return np.sum(w) - 1 


X0 = np.array([[3,4,5,3], 
       [1,2,2,4], 
       [6,5,3,7], 
       [1,0,5,2]]) 

X1 = np.array([4, 2, 4, 2]) 

W = np.array([.0, .5, .5, .0]) 

result = fmin_slsqp(w_rss1, W, f_eqcons=sum1constraint, bounds=[(0.0, 1.0)]*len(W), 
        args=(X0, X1), disp=False, full_output=True) 
Wopt, fW, its, imode, smode = result 

if imode != 0: 
    print("Optimization failed: " + smode) 
else: 
    print(Wopt) 

Als ich dies ausführen, ist der Ausgang

[ 0.05172414 0.55172414 0.39655172 0.  ] 
Verwandte Themen