函数最优化(局部、全局)

1、scipy.optimize
optimize.minimize() 是 Scipy 库中的一个函数,用于在给定约束条件下最小化某一目标函数。具体来说,它通过不断地迭代来逼近目标函数最小值。

scipy.optimize.minimize(fun, x0, args=(), method=None, bounds=None, constraints=())

其中各个参数的含义如下:

  • fun:目标函数,即需要最小化的函数。接受一个参数并返回一个标量,表示该参数对应的函数值。也就是最小值目标函数。

  • x0:初始值,即迭代开始时变量的初始值。

  • args:其他参数,即传递给目标函数的其他参数。默认为空元组。

  • method:优化算法(极值算法),即所采用的优化算法。默认为 BFGS 算法。常见的优化算法包括:‘CG’, ‘BFGS’, ‘Newton-CG’, ‘L-BFGS-B’ 等等。
    Nelder-Mead 算法指的是在优化过程中采用的一种搜索算法,用于寻找在多维空间中最小(或最大)目标函数值的方法。Nelder-Mead 算法也被称为下山单纯形方法 (downhill simplex method)、多面体法 (polytope method) 或变形单纯形法 (amoeba method)。相比于其他优化算法,Nelder-Mead 算法具有较强的鲁棒性,并且不要求目标函数连续可导或者求导能力较强。这使得 Nelder-Mead 算法十分适合于非线性优化问题。 在高维问题中,Nelder-Mead 算法可以在不使用梯度信息的情况下,以较快的速度收敛到局部极值点,因此被广泛应用于工程优化、信号处理以及机器学习等领域。

  • bounds:可行域,即限制变量取值的范围。默认为
    None,表示没有限制。如果需要限制变量的范围,可以将其设为一个序列,其中每个元素是一个长度为 2 的元组,表示对应变量的上下界。

  • constraints:约束条件,即对变量取值的额外限制。默认为None,表示没有其他限制。如果需要添加额外限制,可以将其设为一个序列,其中每个元素表示一条约束条件。
    需要注意的是,fun、x0 和 method 这三个参数是必需的,而 args、bounds 和 constraints 则是可选的。在使用 optimize.minimize() 函数时,我们需要自己定义好目标函数并根据实际情况设置合适的参数。
    测试代码:

import numpy as np
from scipy import optimize

# 两组监测水位数据
Y1 = np.array([...])  # 填入实际的数据
Y2 = np.array([...])  # 填入实际的数据

# 定义目标函数
def fun(b):
    return np.std(Y1 - Y2 + b)

# 对目标函数进行最小化优化
b_init = 0.0
result = optimize.minimize(fun, b_init)

# 输出结果
print(result)
print("最小化标准差为:", result.fun)
print("最小化参数 b 为:", result.x[0])

2、basinhopping 函数找到全局最优点
basinhopping() 是 Scipy 库中的一个函数,用于在给定约束条件下寻找目标函数的全局最优点。具体来说,它采用了一个基于随机化的搜索策略,通过对坐标进行随机扰动、进行局部优化和接受或拒绝新的坐标来逼近全局最优点。

Basin-hopping 是一种two-phase 方法,它将全局步进算法与每一步的局部最小相结合,会在每次随机跳跃后使用局部松弛,旨在模拟原子簇能量最小化的自然过程。

官网资料:https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html

scipy.optimize.basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5, minimizer_kwargs=None, take_step=None, accept_test=None, callback=None, interval=50, disp=False, niter_success=None, seed=None, *, target_accept_rate=0.5, stepwise_factor=0.9)
  • niter:迭代次数

代码:

import numpy as np
from scipy.optimize import basinhopping
def calc_std(y1, y2, b):
    diff = y1 - y2 + b
    std = np.std(diff)
    return std
    
# 模拟数据
y1 = np.array([1, 2, 3, 4, 5])
y2 = np.array([1.1, 2.2, 2.8, 4.5, 4.9])

# 定义目标函数
def objective_func(b):
    return calc_std(y1, y2, b)

# 定义搜索范围和步长
min_b = -10
max_b = 10
stepsize = 0.1
bounds = [(min_b, max_b)]

# 运行基于随机优化的搜索算法
result = basinhopping(objective_func, x0=0, niter=100, stepsize=stepsize, minimizer_kwargs={"bounds": bounds})
print(result)

3、利用梯度下降+最小二乘法求解极值(属于局部优化算法)

import pandas as pd
import numpy as np

# 创建DataFrame对象
df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [3, 4, 5, 6, 7]})

# 定义损失函数
def loss_function(a):
    c = df['A'] - a
    s_c = np.std(c)
    s_b = np.std(df['B'])
    return (s_c ** 2 + s_b ** 2)

# 梯度下降法
def gradient_descent(step_size=0.01, num_iter=100):
    a = 0.0 # 初始值
    for i in range(num_iter):
        gradient = 0.0
        for j in range(len(df)):
            gradient += (a - df.iloc[j]['A']) * (2 * df.iloc[j]['B']) # 求导数
        a = a - step_size * gradient # 更新a值
    return a

# 计算a值
a = gradient_descent()
print("a = ", a)

资料:
最优化:https://www.cnblogs.com/NaughtyBaby/p/5590081.html
总结非常详细的学习资料。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值