Ограниченные наименьших квадратов с использованием Python - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь выполнить подгонку методом наименьших квадратов, используя Python / Scipy, с некоторыми ограничениями, чтобы все коэффициенты находились в диапазоне (0,1), а их сумма была меньше или равна 1.

У кого-нибудь есть предложения, как решить эту проблему?

Вот что я пытался сделать:

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, None), (0, None),(0, None), (0, None), (0, None), (0, None))
res = optimize.minimize(fmin, [0.11, 0.13, 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)

Я заметил две проблемы в моем коде:

1) сумма коэффициентов всегда прибавляет к 1,

2) решение зависит от первоначального предположения. Это работает как генератор случайных чисел.

Буду благодарен за любую помощь.

1 Ответ

0 голосов
/ 14 октября 2019

Я заметил две вещи:

  1. Ваши оценки равны (0, нет), но вы специально сказали, что хотите, чтобы ваши коэффициенты были между 0 и 1, поэтому я бы изменил это на (0, 1).
  2. Мы не можем видеть ваши ограничения (вы ссылаетесь на них в вызове 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]

Результат довольно хороший, и ограничения выполнены, вы уверены, что есть проблема ...?

...