使用Python的约束最小二乘法

使用Python的约束最小二乘法,python,scipy,constraints,linear-algebra,least-squares,Python,Scipy,Constraints,Linear Algebra,Least Squares,我正在尝试使用Python/Scipy进行最小二乘拟合,使用一些约束条件,使所有系数都在(0,1)范围内,并且它们的总和小于或等于1 有人对如何解决这个问题有什么建议吗 这就是我试图做的: 将numpy导入为np 将numpy.linalg作为LA导入 导入scipy.optimize作为优化 def fmin(x、A、b): y=np.dot(A,x)-b 返回np.点(y,y) A=np.array( [8.00901083e-03、6.00592597e-03、2.88275795e-03

我正在尝试使用Python/Scipy进行最小二乘拟合,使用一些约束条件,使所有系数都在(0,1)范围内,并且它们的总和小于或等于1

有人对如何解决这个问题有什么建议吗

这就是我试图做的:

将numpy导入为np
将numpy.linalg作为LA导入
导入scipy.optimize作为优化
def fmin(x、A、b):
y=np.dot(A,x)-b
返回np.点(y,y)
A=np.array(
[8.00901083e-03、6.00592597e-03、2.88275795e-03、1.43159580e-03、,
7.22346553e-04,3.80569910e-04],
[6.00592597e-03、4.80578475e-03、2.37175308e-03、1.17547202e-03、,
6.02063819e-04,3.23039326e-04],
[2.88275795e-03、2.37175308e-03、1.32021653e-03、6.88251743e-04、,
3.70218608e-04,2.13992623e-04],
[1.43159580e-03、1.17547202e-03、6.88251743e-04、4.0001678E-04、,
2.35134567e-04,1.46587630e-04],
[7.22346553e-04、6.02063819e-04、3.70218608e-04、2.35134567e-04、,
1.58475329e-04、1.08484079e-04],
[3.80569910e-04、3.23039326e-04、2.13992623e-04、1.46587630e-04、,
1.08484079e-04,8.33150747e-05]]
b=[0.00497762,0.00391093,0.00197284,0.00100026,0.0005192,0.0002871]
args=(A,b)
bnds=((0,无),(0,无),(0,无),(0,无),(0,无),(0,无),(0,无))
res=优化。最小化(fmin,[0.11,0.13,0.14,0.15,0.16,0.17],参数,方法='SLSQP',
边界=bnds,约束=cons,tol=1e-10,选项={'disp':False})
打印(“\n res\n”,res)
我注意到代码中有两个问题:

1) 系数之和总是加1

2) 答案取决于最初的猜测。它就像一个随机发生器


如果有任何帮助,我将不胜感激

我注意到两件事:

  • 你的边界是(0,无),但你明确地说你希望你的系数在0和1之间,所以我会把它改为(0,1)
  • 我们看不到您的约束(您在optimize.minimize调用中引用了它们),但它们没有在您编写的代码中定义。您的约束是否正确定义
  • 我运行了您的代码(进行了上述调整),它似乎对我有效:

    import numpy as np
    import numpy.linalg as LA
    import scipy.optimize as optimize
    
    def fmin(x,A,b):
        y = np.dot(A, x) - b
        return np.dot(y, y)
    
    A = np.array(
    [[8.00901083e-03, 6.00592597e-03, 2.88275795e-03, 1.43159580e-03,
      7.22346553e-04, 3.80569910e-04],
     [6.00592597e-03, 4.80578475e-03, 2.37175308e-03, 1.17547202e-03,
      6.02063819e-04, 3.23039326e-04],
     [2.88275795e-03, 2.37175308e-03, 1.32021653e-03, 6.88251743e-04,
      3.70218608e-04, 2.13992623e-04],
     [1.43159580e-03, 1.17547202e-03, 6.88251743e-04, 4.00016878e-04,
      2.35134567e-04, 1.46587630e-04],
     [7.22346553e-04, 6.02063819e-04, 3.70218608e-04, 2.35134567e-04,
      1.58475329e-04, 1.08484079e-04],
     [3.80569910e-04, 3.23039326e-04, 2.13992623e-04, 1.46587630e-04,
      1.08484079e-04, 8.33150747e-05]])
    
    
    b = [0.00497762, 0.00391093, 0.00197284, 0.00100026, 0.0005192,  0.0002871 ]
    
    args = (A,b)
    
    bnds = ((0, 1), (0, 1),(0, 1), (0, 1), (0, 1), (0, 1))
    cons = ({'type': 'ineq', 'fun': lambda x: 1.0-np.sum(x) })
    res = optimize.minimize(fmin, [0.11, 0.5, 0.14,0.15,0.16,0.17],args, method='SLSQP',
    bounds=bnds,constraints=cons,tol=1e-10,options={'disp': False})
    
    print ("\n res\n", res)
    print("Sum of coefficients {}".format(np.sum(res.x)))
    print("Difference vector:\n{}".format(np.dot(A,res.x) - b))
    
    结果是:

     res
          fun: 1.01628082156861e-09
         jac: array([-9.22056775e-09, -1.17219215e-08, -1.75126229e-08, -1.36469735e-08,
           -9.97111414e-09, -7.49388410e-09])
     message: 'Optimization terminated successfully.'
        nfev: 72
         nit: 9
        njev: 9
      status: 0
     success: True
           x: array([0.17233894, 0.52326708, 0.09570958, 0.07287169, 0.06681423,
           0.06899848])
    Sum of coefficients 0.9999999999999999
    Difference vector:
    [ 9.98723723e-08  1.40076137e-05 -1.89557823e-05 -1.76076427e-05
     -9.02962303e-06 -8.31701569e-06]
    
    结果很好,满足了约束条件,你确定有问题吗