scipy.optimize.minimize快速上手

因为没有找到合适的资料,看到的很多要么用了一堆功能要么给出一堆复杂的式子直接优化,感觉不够简单,于是自己整理了一下,希望能一看就懂,也能自己轻松在草稿纸上手动算出优化结果。

1.一元无约束优化:

from scipy.optimize import minimize
import numpy as np

func = lambda x: x ** 2
x_init = np.random.random(1)
res = minimize(func, x_init)
print("最小值:", res.fun)
print("最优解:", res.x)
print("迭代终止是否成功", res.success)
print("迭代终止原因", res.message)

输出:

最小值: 1.1488908661148124e-17
最优解: [3.38952927e-09]
迭代终止是否成功 True
迭代终止原因 Optimization terminated successfully.

下文不再显式导入包,也不显式给出这4行print代码,大家自己加上。

2.一元带约束优化:

2-1.使用constraints

func = lambda x: x ** 2
cons = ({'type': 'ineq', 'fun': lambda x: x - 2})
x_init = np.array(1)
res = minimize(func, x_init, constraints=cons)  # 最优解x=2

2-2.使用bounds

func = lambda x: x ** 2
x_init = np.array(1)
res = minimize(func, x_init, bounds=((3, 5), ))  # 最优解x=3

两种约束差不多,而constrains更适合复杂情况下的约束。

3.一元带超参数优化:

def func(x, a):
    return x**2 - 4*a*x
a = 2
x_init = np.array(1)
res = minimize(func, x_init, args=(a,))  # 最优解x=4

这里也是可以用func = lambda x, a: x**2 + 4*a*x的。而因为PEP 8: E731规范,不建议将匿名函数表达式赋值给一个变量再用这个变量调用函数,因此除非需要简短的代码,此时还是更建议用def,之后也以def为主。

4.二元函数带约束和超参数优化:

def func(x, a):
    return x[0]**2 + a*x[1]
cons = ({'type': 'eq', 'fun': lambda x: x[0] * x[1] - 10},  # 约束条件:xy=10
        {'type': 'ineq', 'fun': lambda x: x[0]},  # x>0
        {'type': 'ineq', 'fun': lambda x: x[1]})  # y>0
a = 2
x_init = np.random.random(2)
res = minimize(func, x_init, args=(a,), constraints=cons)

手动验证:

更多元的函数的优化是类似的。

对于优化算法的选择可参考其他文章。

### scipy.optimize.minimize 函数的工作原理 `scipy.optimize.minimize` 是 SciPy 库中的一个重要工具,用于寻找给定目标函数的局部最小值。该函数支持多种优化算法,并返回一个 `OptimizeResult` 对象,其中包含了关于优化过程的各种信息[^1]。 #### 输入参数解析 - **fun**: 需要最小化的目标函数。 - **x0**: 初始猜测值数组,表示待优化变量的初始估计。 - **method (可选)**: 可以指定使用的具体优化方法,默认情况下会选择最适合的方法。 - **jac (可选)**: 如果提供,则为目标函数的梯度;如果未提供,某些优化器会尝试数值计算它。 - **hess (可选)**: Hessian矩阵(二阶导数),仅适用于部分优化器。 - **constraints (可选)**: 定义约束条件的对象列表。 - **bounds (可选)**: 各个变量的边界范围定义。 #### 输出解释 成功调用此函数后将会得到一个 `OptimizeResult` 类型的结果对象,其主要属性如下: - **x**: 优化后的解向量。 - **success**: 表明求解是否成功的布尔标志位。 - **status**: 整形的状态码,提供了更详细的退出原因说明。 - **message**: 描述终止情况的消息字符串。 - **fun, jac, hess**: 分别对应于最优处的目标函数值、雅克比矩阵以及黑塞矩阵。 - **nfev, njev, nhvev**: 记录了目标函数及其一阶和二阶导数被评估次数计数器。 下面是一个简单的例子来展示如何使用这个功能来进行最优化操作: ```python from scipy.optimize import minimize def objective_function(x): return x[0]**2 + x[1]**2 initial_guess = [1, 2] result = minimize(objective_function, initial_guess) print(f"Optimized parameters: {result.x}") print(f"Minimum value of the function: {result.fun}") ``` 通过上述代码片段可以观察到,当执行完毕之后不仅能够获得使目标函数达到极小值时对应的自变量取值(`result.x`),还可以得知此时所取得的具体最小值(`result.fun`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值