gpt4 book ai didi

python - 如何将约束包含在 Scipy NNLS 函数解中,使其总和为 1

转载 作者:太空狗 更新时间:2023-10-30 00:44:10 24 4
gpt4 key购买 nike

我有以下代码来求解非负最小二乘法。使用scipy.nnls.

import numpy as np
from scipy.optimize import nnls

A = np.array([[60, 90, 120],
[30, 120, 90]])

b = np.array([67.5, 60])

x, rnorm = nnls(A,b)

print x
#[ 0. 0.17857143 0.42857143]
# Now need to have this array sum to 1.

我想做的是对 x 解决方案应用约束,使其总和为 1。我该怎么做?

最佳答案

我认为您不能将nnls 直接用作Fortran code它调用不允许额外的约束。但是,方程总和为 1 的约束可以作为第三个方程引入,因此您的示例系统的形式为,

60 x1 + 90  x2 + 120 x3 = 67.5
30 x1 + 120 x2 + 90 x3 = 60
x1 + x2 + x3 = 1

因为现在这是一组线性方程,可以从 x=np.dot(np.linalg.inv(A),b) 获得精确解,这样 x =[0.6875, 0.3750, -0.0625]。这要求 x3 为负数。因此,当x对这个问题为正时,没有确切的解法。

对于 x 被限制为正值的近似解,可以使用以下方法获得,

import numpy as np
from scipy.optimize import nnls

#Define minimisation function
def fn(x, A, b):
return np.sum(A*x,1) - b

#Define problem
A = np.array([[60., 90., 120.],
[30., 120., 90.],
[1., 1., 1. ]])

b = np.array([67.5, 60., 1.])

x, rnorm = nnls(A,b)

print(x,x.sum(),fn(x,A,b))

给出 x=[0.60003332, 0.34998889, 0.]x.sum()=0.95

我认为,如果您想要一个更通用的解决方案,包括总和约束,您需要使用具有以下形式的显式约束/边界的最小化,

import numpy as np
from scipy.optimize import minimize
from scipy.optimize import nnls

#Define problem
A = np.array([[60, 90, 120],
[30, 120, 90]])

b = np.array([67.5, 60])

#Use nnls to get initial guess
x0, rnorm = nnls(A,b)

#Define minimisation function
def fn(x, A, b):
return np.linalg.norm(A.dot(x) - b)

#Define constraints and bounds
cons = {'type': 'eq', 'fun': lambda x: np.sum(x)-1}
bounds = [[0., None],[0., None],[0., None]]

#Call minimisation subject to these values
minout = minimize(fn, x0, args=(A, b), method='SLSQP',bounds=bounds,constraints=cons)
x = minout.x

print(x,x.sum(),fn(x,A,b))

给出 x=[0.674999366, 0.325000634, 0.]x.sum()=1。从最小化来看,总和是正确的,但 x 的值与 np.dot(A,x)=[ 69.75001902, 59.25005706] 不太正确。

关于python - 如何将约束包含在 Scipy NNLS 函数解中,使其总和为 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33385898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com