我是优化新手。我正在尝试使用fmin_slsqp
中的scipy.optimize
函数来解决线性最小二乘问题。
我的目标函数为|q0_T*P-q1_T|
平方的frobenius范数,其中q0_T
是nX1
向量的转置,P
是nXn
矩阵, q1_T
是nX1
向量的转置。这基本上是一个马尔可夫过程,q
向量作为处于状态的概率,P
是转移概率的矩阵。
目标函数将被最小化w.r.t P
,其中约束为:
1)P
中的所有元素都必须是非负的
2)P
中的所有行必须总和为1
我已经定义了这个目标函数,我不确定是否正确:
def func(P, q):
return (np.linalg.norm(np.dot(transpose(q[0,]),P)-transpose(q[1,])))**2
fmin_slsqp中的第二个参数要求1D ndarray x0,它是自变量的初始猜测。但是在这里,由于我的自变量将是P,我需要一个2D数组用于我的初始猜测。我不确定我是否正确构建问题或者我将不得不使用其他功能。谢谢。
答案 0 :(得分:1)
所以有一个问题是它只接受一个1d数组作为自变量,一个hackish解决方案是将它作为1d传递,并重塑该函数。
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)