Question

Je suis nouveau dans l'optimisation. J'essaie de résoudre un problème de moindre carrés linéaire en utilisant le fmin_slsqp fonctionner dans scipy.optimize.

J'ai la fonction objective comme la norme frobenius de |q0_T*P-q1_T| au carré, où q0_T est la transposition d'un nX1 vecteur et P est nXn matrice et q1_T est une transposition d'un nX1 vecteur. Il s'agit essentiellement d'un processus de Markov avec q vecteurs comme probabilité d'être dans un état et P étant la matrice des probabilités de transition.

La fonction objectif serait minimisée wrt P où sont les contraintes:

1) Tous les éléments de P Doit être non négatif

2) toutes les lignes de P doit résumer à 1

J'ai défini cette fonction objectif qui, je ne suis pas sûr, est correcte:

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

Le deuxième argument dans FMIN_SLSQP demande un 1D NDARRAY X0 qui est la supposition initiale pour la variable indépendante. Mais ici, comme ma variable indépendante serait P, j'aurais besoin d'un tableau 2D pour ma supposition initiale. Je ne sais pas si je cadais correctement le problème ou si je devrai utiliser une autre fonction. Merci.

Était-ce utile?

La solution

Il y a donc un problème en ce sens qu'il n'accepte qu'un tableau 1D en tant que variable indépendante, une solution piratante serait de la passer en 1D et de remodeler dans la fonction.

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top