Skip to main content
 首页 » 编程设计

python之使用 fmin_slsqp 构造最小二乘函数

2025年05月04日11kevingrace

我是优化新手。我正在尝试使用 scipy.optimize 中的 fmin_slsqp 函数解决线性最小二乘问题。

我的目标函数是 |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,所以我需要一个二维数组来进行初始猜测。我不确定我是否正确地构建了问题或者我必须使用另一个函数。谢谢。

请您参考如下方法:

因此存在一个问题,它只接受一维数组作为自变量,一种骇人听闻的解决方案是将其作为一维数组传递,并在函数中 reshape 。

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)