Рассмотрим следующее:
import numpy as np
from scipy.optimize import minimize
data = np.array([ 59. , 59.5, 61. , 61.5, 62.5, 63. , 63. , 65.5, 66.5,
67. , 68. , 69. , 69.5, 70.5, 70.5, 70.5, 71. , 72. ,
72. , 73.5, 73.5, 74. , 75. , 75.5, 78. , 79. , 79. ,
79. , 79.5, 80.5, 80.5, 80.5, 80.5, 80.5, 82.5, 82.5,
82.5, 83. , 83. , 83. , 83. , 83. , 83.5, 83.5, 84. ,
84.5, 84.5, 84.5, 86. , 86. , 86. , 86.5, 86.5, 87.5,
88. , 88. , 88.5, 89. , 90. , 90.5, 90.5, 90.5, 91. ,
91.5, 91.5, 92. , 92. , 93. , 93. , 93. , 93.5, 93.5,
94. , 94. , 94. , 94. , 94. , 94. , 94.5, 94.5, 94.5,
94.5, 95.5, 95.5, 95.5, 95.5, 95.5, 95.5, 96. , 96. ,
96. , 96.5, 96.5, 96.5, 98. , 98. , 98. , 98. , 98. ,
98. , 98. , 98. , 98.5, 98.5, 98.5, 98.5, 98.5, 100. ,
100. , 100. , 100. ])
def scale(data, coeffs):
m,b = coeffs
return (m * data) + b
def score(coeffs):
scaled = scale(data, coeffs)
# Penalty components
p_1 = abs(np.mean(scaled) - 65)
p_2 = max(0, (50 - np.min(scaled)))
return p_1 + p_2
res = minimize(score, (0.85, 0.0), method = 'Powell')
#np.set_printoptions(suppress=True)
print(res)
post = scale(data, res.x)
print(np.mean(post))
print(np.min(post))
print(score(res.x))
Выходы:
direc: array([[ -3.05475495e-02, 2.62047576e+00],
[ 7.54828106e-07, -6.47892698e-05]])
fun: 1.4210854715202004e-14
message: 'Optimization terminated successfully.'
nfev: 360
nit: 8
status: 0
success: True
x: array([ 0.55914442, 17.02691959])
print(np.mean(post)) # 65.0
print(np.min(post)) # 50.0164406291
print(score(res.x)) # 1.42108547152e-14
Несколько вещей:
- Я добавил
scale
помощникфункция, чтобы немного очистить код, так как я использую его в функции score
, а также в конце, чтобы показать масштабированные данные. - Функция
score
была исправлена и разбита на два отдельныхштрафы (по одному на каждое требование) для ясности.Он вычисляет масштабированный вектор один раз (и вызывает его scaled
), а затем вычисляет компоненты штрафа. - Примечание: эта функция оценки имеет нечетную негладкую область около min (data) = 50 из-за
max
звонок.Это может вызвать проблемы с некоторыми методами оптимизации. Я использовал алгоритм Пауэлла, потому что я использовал его раньше, и он работал в аналогичной проблеме с использованием оператора min / max.Википедия говорит :
Этот метод полезен для вычисления локального минимума непрерывной, но сложной функции, особенно без базового математического определения, поскольку нет необходимости брать производные
Кто-то, более знакомый с методами оптимизации, может предложить лучшую альтернативу.
(Правка) Наконец, в связи с вашим вопросом о граничных условиях,Обычно, когда мы говорим о граничных условиях, мы говорим о границе независимой переменной, вектора, который мы оптимизируем (здесь, элементы coeffs
или x
) - например, "x [0] долженбыть меньше 0 ", или" x [1] должен быть между 0 и 1 "- не то, что вы, похоже, ищете.