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
总结非常详细的学习资料。