带权重的参数优化
Parameter optimization with weights
对于此函数:
import numpy as np
def my_function(param1 , param2 , param3 , param4) :
return param1 + 3*param2 + 5*param3 + np.power(5 , 3) + np.sqrt(param4)
print(my_function(1,2,3,4))
这会打印 134.0
如何 return 100 而不是 134.0 或尽可能接近 6 的值,并满足以下 my_function 参数条件:param1 必须在 10-20 范围内,param2 必须在范围内20-30,param3 必须在 30-40 范围内,param4 必须在 40-50
范围内
我不是要针对此问题寻求具体的解决方案,但它属于哪个领域?阅读 https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html & Parameter Optimization in Python 表明这可以通过开箱即用的解决方案(低维度)实现。遗传编程可以应用于这个问题吗?
基本上,您希望最小化估计值与实际函数之间的误差。
编辑:这里明显的选择是对 4 个参数使用梯度下降。如果你不想那样做,而是想问一个更实用的解决方案,就在这里。
这里的主要问题是有4个参数。要解决这个问题,你可以这样做:
- 修正任意 3 个参数,保留最后一个参数。我们将尝试找到这个值。
- 找到反函数,并显式或使用求解器(可以是 Newton-Raphson 或 Brent 方法等数值方法)求解
我将描述一个过程来证明这个想法。我们将使用 scipy 的 scalar_minimizer,它采用布伦特方法。
为了便于讨论,让我们让您的函数由 2 个参数组成,并假设您的函数是:
def f(p1, p2):
return p1 + np.sqrt(p2)
你基本上是在问如何找到 f(p1, p2) = 100 的 p1, p2 值。
假设范围如下:
- p1 的范围:10-20
- p2 的范围:20-30
让我们将 p1 固定为 10(您可以自由固定为该范围内的任何值)。现在函数变成
def g(p2):
return 10 + np.sqrt(p2)
我们希望它尽可能接近 100,所以让我们创建一个误差函数来衡量我们的估计与 100 的差距。
def error(p2):
return 100 - (10 + np.sqrt(p2)) # we want to minimize this
你可以找到最小化这个错误的值,这样你就可以通过
尽可能接近100
from scipy import optimize
optimize.minimize_scalar(error, bounds = (10,20), method = "bounded")
给出的值 x = 19.9 作为最小化误差的值。
只是为了好玩,julia中的一个小演示(正如某人所说:没有具体的解决方案)。
这是一个 全局 open-source 求解器 ,它将处理 small-scale 类似的问题(并转移到更复杂的问题)。请记住,您的示例有些微不足道(两个目标都会导致所有变量的 lower-bounds ,无需优化即可看到;代码将按预期输出)并且我在那里使用了其他一些值实际上是要优化的东西!
当模型变得更复杂时,global-optimization 将变得不可行(理论上非常困难;有时是不可能的)。您只需将求解器切换到 Ipopt 即可获得 local-optimum.
这也可以在 python 中使用 pyomo 完成,但不太好。可以使用模型和求解器。仅更改代码。
代码
using JuMP, AmplNLWriter
TARGET = 387
m = Model(solver=AmplNLSolver(CoinOptServices.couenne))
@variable(m, 10 <= param1 <= 20, start=10)
@variable(m, 20 <= param2 <= 30, start=20)
@variable(m, 30 <= param3 <= 40, start=30)
@variable(m, 40 <= param4 <= 50, start=40)
@variable(m, aux)
@NLconstraint(m, aux == TARGET - (param1 + 3*param2 + 5*param3 + 5^3 + sqrt(param4)))
@NLobjective(m, Min, aux^2)
solve(m)
println("objective: ", getobjectivevalue(m))
println("param1 = ", getvalue(param1))
println("param2 = ", getvalue(param2))
println("param3 = ", getvalue(param3))
println("param4 = ", getvalue(param4))
出
Mailing list: couenne@list.coin-or.org
Instructions: http://www.coin-or.org/Couenne
couenne:
ANALYSIS TEST: Couenne: new cutoff value 0.0000000000e+000 (0.016 seconds)
NLP0012I
Num Status Obj It time Location
NLP0014I 1 OPT 0 7 0.003
Loaded instance "C:\Users\Sascha\.julia\v0.5\AmplNLWriter\.solverdata\jl_21AE.tmp.nl"
Constraints: 1
Variables: 5 (0 integer)
Auxiliaries: 2 (0 integer)
Coin0506I Presolve 11 (0) rows, 4 (-3) columns and 22 (-3) elements
Clp0006I 0 Obj 0 Primal inf 0.0023740886 (2)
Clp0006I 1 Obj -4.0767235e-022
Clp0000I Optimal - objective value 0
Clp0032I Optimal objective 0 - 1 iterations time 0.012, Presolve 0.00
Clp0000I Optimal - objective value 0
NLP Heuristic: NLP0014I 2 OPT 0 3 0.001
no solution.
Cbc0010I After 0 nodes, 0 on tree, 1e+050 best solution, best possible 0 (0.01 seconds)
Clp0000I Optimal - objective value 3.90625e-007
Clp0006I 0 Obj 0 Primal inf 0.00098181331 (1)
Clp0006I 1 Obj -3.2730444e-022
Clp0000I Optimal - objective value 0
Optimality Based BT: 0 improved bounds
Cbc0004I Integer solution of 0 found after 2 iterations and 2 nodes (0.03 seconds)
Cbc0001I Search completed - best objective 0, took 2 iterations and 2 nodes (0.04 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
"Finished"
Linearization cuts added at root node: 11
Linearization cuts added in total: 11 (separation time: 0s)
Total solve time: 0.065s (0.065s in branch-and-bound)
Lower bound: 0
Upper bound: 0 (gap: 0.00%)
Branch-and-bound nodes: 2
WARNING: Nonlinear solver does not provide dual solutions
objective: 0.0
param1 = 10.0
param2 = 20.0
param3 = 37.13508893593264
param4 = 40.0
创建新函数以通过对违反约束的行为增加惩罚来优化。
param1 必须在 10-20 范围内,因此要满足 param1 的约束,只有要优化的新函数是
f(p1,p2,p3,p4)=my_function(p1,p2,p3,p4)+1000*(p1-30)*2
param1=20+p1
改变变量来优化 p1=param1-20
您可以在约束之前使用系数的大小,这取决于使用的优化方法。
需要正方形以便所有 p1 都存在梯度
根据需要为新的优化函数添加其他惩罚
对于此函数:
import numpy as np
def my_function(param1 , param2 , param3 , param4) :
return param1 + 3*param2 + 5*param3 + np.power(5 , 3) + np.sqrt(param4)
print(my_function(1,2,3,4))
这会打印 134.0
如何 return 100 而不是 134.0 或尽可能接近 6 的值,并满足以下 my_function 参数条件:param1 必须在 10-20 范围内,param2 必须在范围内20-30,param3 必须在 30-40 范围内,param4 必须在 40-50
范围内我不是要针对此问题寻求具体的解决方案,但它属于哪个领域?阅读 https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html & Parameter Optimization in Python 表明这可以通过开箱即用的解决方案(低维度)实现。遗传编程可以应用于这个问题吗?
基本上,您希望最小化估计值与实际函数之间的误差。
编辑:这里明显的选择是对 4 个参数使用梯度下降。如果你不想那样做,而是想问一个更实用的解决方案,就在这里。
这里的主要问题是有4个参数。要解决这个问题,你可以这样做:
- 修正任意 3 个参数,保留最后一个参数。我们将尝试找到这个值。
- 找到反函数,并显式或使用求解器(可以是 Newton-Raphson 或 Brent 方法等数值方法)求解
我将描述一个过程来证明这个想法。我们将使用 scipy 的 scalar_minimizer,它采用布伦特方法。
为了便于讨论,让我们让您的函数由 2 个参数组成,并假设您的函数是:
def f(p1, p2):
return p1 + np.sqrt(p2)
你基本上是在问如何找到 f(p1, p2) = 100 的 p1, p2 值。 假设范围如下:
- p1 的范围:10-20
- p2 的范围:20-30
让我们将 p1 固定为 10(您可以自由固定为该范围内的任何值)。现在函数变成
def g(p2):
return 10 + np.sqrt(p2)
我们希望它尽可能接近 100,所以让我们创建一个误差函数来衡量我们的估计与 100 的差距。
def error(p2):
return 100 - (10 + np.sqrt(p2)) # we want to minimize this
你可以找到最小化这个错误的值,这样你就可以通过
尽可能接近100from scipy import optimize
optimize.minimize_scalar(error, bounds = (10,20), method = "bounded")
给出的值 x = 19.9 作为最小化误差的值。
只是为了好玩,julia中的一个小演示(正如某人所说:没有具体的解决方案)。
这是一个 全局 open-source 求解器 ,它将处理 small-scale 类似的问题(并转移到更复杂的问题)。请记住,您的示例有些微不足道(两个目标都会导致所有变量的 lower-bounds ,无需优化即可看到;代码将按预期输出)并且我在那里使用了其他一些值实际上是要优化的东西!
当模型变得更复杂时,global-optimization 将变得不可行(理论上非常困难;有时是不可能的)。您只需将求解器切换到 Ipopt 即可获得 local-optimum.
这也可以在 python 中使用 pyomo 完成,但不太好。可以使用模型和求解器。仅更改代码。
代码
using JuMP, AmplNLWriter
TARGET = 387
m = Model(solver=AmplNLSolver(CoinOptServices.couenne))
@variable(m, 10 <= param1 <= 20, start=10)
@variable(m, 20 <= param2 <= 30, start=20)
@variable(m, 30 <= param3 <= 40, start=30)
@variable(m, 40 <= param4 <= 50, start=40)
@variable(m, aux)
@NLconstraint(m, aux == TARGET - (param1 + 3*param2 + 5*param3 + 5^3 + sqrt(param4)))
@NLobjective(m, Min, aux^2)
solve(m)
println("objective: ", getobjectivevalue(m))
println("param1 = ", getvalue(param1))
println("param2 = ", getvalue(param2))
println("param3 = ", getvalue(param3))
println("param4 = ", getvalue(param4))
出
Mailing list: couenne@list.coin-or.org
Instructions: http://www.coin-or.org/Couenne
couenne:
ANALYSIS TEST: Couenne: new cutoff value 0.0000000000e+000 (0.016 seconds)
NLP0012I
Num Status Obj It time Location
NLP0014I 1 OPT 0 7 0.003
Loaded instance "C:\Users\Sascha\.julia\v0.5\AmplNLWriter\.solverdata\jl_21AE.tmp.nl"
Constraints: 1
Variables: 5 (0 integer)
Auxiliaries: 2 (0 integer)
Coin0506I Presolve 11 (0) rows, 4 (-3) columns and 22 (-3) elements
Clp0006I 0 Obj 0 Primal inf 0.0023740886 (2)
Clp0006I 1 Obj -4.0767235e-022
Clp0000I Optimal - objective value 0
Clp0032I Optimal objective 0 - 1 iterations time 0.012, Presolve 0.00
Clp0000I Optimal - objective value 0
NLP Heuristic: NLP0014I 2 OPT 0 3 0.001
no solution.
Cbc0010I After 0 nodes, 0 on tree, 1e+050 best solution, best possible 0 (0.01 seconds)
Clp0000I Optimal - objective value 3.90625e-007
Clp0006I 0 Obj 0 Primal inf 0.00098181331 (1)
Clp0006I 1 Obj -3.2730444e-022
Clp0000I Optimal - objective value 0
Optimality Based BT: 0 improved bounds
Cbc0004I Integer solution of 0 found after 2 iterations and 2 nodes (0.03 seconds)
Cbc0001I Search completed - best objective 0, took 2 iterations and 2 nodes (0.04 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
"Finished"
Linearization cuts added at root node: 11
Linearization cuts added in total: 11 (separation time: 0s)
Total solve time: 0.065s (0.065s in branch-and-bound)
Lower bound: 0
Upper bound: 0 (gap: 0.00%)
Branch-and-bound nodes: 2
WARNING: Nonlinear solver does not provide dual solutions
objective: 0.0
param1 = 10.0
param2 = 20.0
param3 = 37.13508893593264
param4 = 40.0
创建新函数以通过对违反约束的行为增加惩罚来优化。
param1 必须在 10-20 范围内,因此要满足 param1 的约束,只有要优化的新函数是
f(p1,p2,p3,p4)=my_function(p1,p2,p3,p4)+1000*(p1-30)*2
param1=20+p1
改变变量来优化 p1=param1-20 您可以在约束之前使用系数的大小,这取决于使用的优化方法。
需要正方形以便所有 p1 都存在梯度
根据需要为新的优化函数添加其他惩罚