Frage

Ich bin neu in der Optimierung. Ich versuche, ein lineares Problem mit der kleinsten Quadrate zu lösen fmin_slsqp Funktion in scipy.optimize.

Ich habe die objektive Funktion als Frobenius -Norm von |q0_T*P-q1_T| Quadrat, wo q0_T ist die Transponierung von a nX1 Vektor und P ist nXn Matrix und q1_T ist eine Transponierung von a nX1 Vektor. Dies ist im Grunde ein Markov -Prozess mit q Vektoren als Wahrscheinlichkeit, in einem Zustand zu sein und P die Matrix der Übergangswahrscheinlichkeiten sein.

Die objektive Funktion wäre minimiert WRT P wo die Einschränkungen sind:

1) Alle Elemente in P muss nicht negativ sein

2) Alle Reihen in P muss zu 1 summieren

Ich habe diese objektive Funktion definiert, die ich nicht sicher bin, ist richtig:

def func(P, q):
  return (np.linalg.norm(np.dot(transpose(q[0,]),P)-transpose(q[1,])))**2

Das zweite Argument in FMIN_SLSQP fragt nach einem 1D NDarray X0, was die anfängliche Vermutung für eine unabhängige Variable ist. Aber hier, da meine unabhängige Variable P sein würde, würde ich ein 2D -Array für meine erste Vermutung benötigen. Ich bin mir nicht sicher, ob ich das Problem richtig umrahme oder ich muss eine andere Funktion verwenden. Vielen Dank.

War es hilfreich?

Lösung

Es gibt also ein Problem, dass es nur ein 1D -Array als unabhängige Variable akzeptiert, eine hackische Lösung wäre es, es als 1D zu bestehen und in der Funktion umzugestalten.

import numpy as np
from scipy.optimize import fmin_slsqp

# some fake data
d = 3 # dimensionality of the problem
P0 = np.arange(d*d).reshape(d, d)
P0 /= P0.sum(1, keepdims=True) # so that each row sums to 1
q = np.random.rand(2, d)       # assuming this is the structure of your q
q /= q.sum(1, keepdims=True)

# the function to minimize
def func(P, q):
    n = q.shape[-1] # or n = np.sqrt(P.size)
    P = P.reshape(n, n)
    return np.linalg.norm(np.dot(q[0], P) - q[1])**2  # no changes here, just simplified syntax

def row_sum(P0, q):
    """ row sums - 1 are zero """
    n = np.sqrt(P0.size)
    return P0.reshape(n,n).sum(1) - 1.

def non_neg(P0, q):
    """ all elements >= 0 """
    return P0

P_opt = fmin_slsqp(func, P0.ravel(), args=(q,), f_eqcons=row_sum, f_ieqcons=non_neg).reshape(d, d)

assert np.allclose(P_opt.sum(1), 1)
assert np.all(P_opt >= 0)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top