发布日期:2024-11-09 05:24 点击次数:142
Scipy优化模块(scipy.optimize)用于责罚各式数学优化问题,它提供了多种优化算法,具体包括:
无照应优化:寻找倡导函数在不研究截止条目下的最小值或最大值。
照应优化:在得志特定条目的前提下,找到倡导函数的最优解。
全局优化:针对复杂的多峰函数,寻找全局最优解。
非线性最小二乘:用于拟合非线性模子到数据。
无照应优化算法
无照应优化问题是指惟有优化倡导,而不存在照应条目的问题。用数学模子可示意为:寻求多元函数f(x)的极小值点,其中x为n维实数空间Rn中的一个向量。这类问题在数据拟合、机器学习、适度表面等多个领域持续出现。
无照应优化常用算法包括:梯度下落法(Gradient Descent)、牛顿法(Newton's Method)、共轭梯度法(Conjugate Gradient Method)、拟牛顿法(Quasi-Newton Methods)等。
在聘用无照应优化算法时,需要研究问题的界限、数据的稀少性、对商量精度的要求以及算法的照应速率等成分。不同的算法在不同的场景下具有各自的上风和局限性。
举例,在机器学习中,关于大界限数据集和需要快速迭代更新的场景,无为会聘用梯度下落法或其考订版块(如动量法、Adam算法等)。而关于需要高精度解的场景(如数值优化问题),则可能会聘用牛顿法或拟牛顿法。
使用梯度下落法优化案例
假定咱们要优化一个二次函数 f(x, y) = (x - 2)^2 + (y - 3)^2,这是一个肤浅的凸函数,其最小值在点 (2, 3) 处。
import numpy as np
from scipy.optimize import minimize
# 界说倡导函数
def objective_function(x):
return (x[0] - 2)**2 + (x[1] - 3)**2
# 界说梯度函数
def gradient_function(x):
grad = np.zeros_like(x)
grad[0] = 2 * (x[0] - 2)
grad[1] = 2 * (x[1] - 3)
return grad
# 启动想到
x0 = np.array([0.0, 0.0])
# 使用 minimize 函数进行优化,指定梯度函数
result = minimize(objective_function, x0, jac=gradient_function, method='BFGS')
# 精致:这里method='BFGS'是一个拟牛顿法,但咱们不错诈欺jac参数传入梯度函数
# 本色上,关于肤浅的二次函数,咱们不错告成使用'CG'(共轭梯度法),它更接近于纯梯度下落的一种变体,但这里为了展示若何使用梯度函数,咱们仍然使用BFGS。
# 淌若要更迫临梯度下落,不错聘用'SGD'(就地梯度下落)的变种,但SciPy的minimize并不告成营救SGD,这无为需要在深度学习框架中收尾。
# 不外,关于本例,咱们不错忽略method参数的具体聘用,因为重心是展示若何使用梯度函数。
# 打印优化罢了
print("Optimal values:", result.x)
print("Optimal function value:", result.fun)
示例代码界说了gradient_function来商量倡导函数的梯度。尽管上头的代码莫得告成使用纯梯度下落法(因为SciPy的minimize函数莫得提供告成的梯度下落收尾),但它展示了若何使用自界说的梯度函数与SciPy的优化函数相纠合来责罚问题。关于更复杂的优化问题,这种智商相同适用。
照应优化算法
照应优化问题是在自变量得志照应条目的情况下倡导函数最小化(或最大化)的问题。其中,照应条目既不错是等式照应,也不错是不等式照应。
照应优化通过将照应条目纳入优化模子,不错有用地责罚本色问题中的复杂照应研究,从而普及决议的后果和准确性。举例,在坐褥换取问题中,照应优化算法不错求解具有线性或非线性倡导函数和照应条目的坐褥筹划,以最大化坐褥后果或最小化坐褥本钱。在物发配送问题中,则不错求解具有车辆容量、时刻窗等照应条目的配送门路策画问题,以最小化配送本钱或时刻。
求解带照应的最优化问题
假定咱们要最小化的倡导函数是:
f(x) = 0.5 * (x[0]^2 + x[1]^2)
照应条目:
3 * x[0] + 3 * x[1] + x[2] - 1 <= 0
4 * x[0] + 3 * x[1] + x[2] - 1 <= 0
-x[0] - x[1] - x[2] - 1 <= 0
示例代码
from scipy.optimize import minimize
import numpy as np
# 界说倡导函数
fun = lambda x: 0.5 * (x[0]** 2 + x[1] **2)
# 界说照应条目
cons = ({'type': 'ineq', 'fun': lambda x: 3 * x[0] + 3 * x[1] + x[2] - 1},
{'type': 'ineq', 'fun': lambda x: 4 * x[0] + 3 * x[1] + x[2] - 1},
{'type': 'ineq', 'fun': lambda x: -x[0] - x[1] - x[2] - 1})
# 界说启动值
x0 = np.array([0, 0, 0])
# 使用minimize函数求解
res = minimize(fun, x0, method='SLSQP', constraints=cons)
# 输出罢了
print('最小值:', res.fun)
print('最优解:', res.x)
print('迭代拆开是否收效:', res.success)
print('迭代拆开原因:', res.message)
输出:
最小值: 0.25000000000000056
最优解: [0.5 0.5 -2. ]
迭代拆开是否收效: True
迭代拆开原因: Optimization terminated successfully。
代码解读
界说照应条目时,type字段指定了照应的类型,ineq示意不等式照应,eq示意等式照应。minimize函数的method参数指定了求解算法,这里使用了SLSQP(轨则最小二乘编程)算法。Scipy还营救其他多种算法,如BFGS、L-BFGS-B等,使用者不错确认具体问题聘用稳健的算法。启动值x0的设定对算法的照应性和求解罢了有垂危影响,因此在本色应用中需要严慎聘用。
全局优化算法
全局优化算法是在一定照应条目下寻求优化问题的全局最优解或肖似全局最优解。
全局优化算法案例
假定咱们有一个复杂的多峰函数,倡导是找到它的全局最小值。多峰函数是指具有多个局部最小值的函数,这使得局部优化算法难以找到全局最小值。因此,咱们需要使用全局优化算法来搜索扫数这个词参数空间,并找到全局最优解。
示例代码
import numpy as np
from scipy.optimize import differential_evolution
import matplotlib.pyplot as plt
#界说倡导函数
def multimodal_function(x):
# 添加一些噪声使函数更复杂
return np.sin(x) + 0.1 * np.random.randn()
#画图函数图像
x_values = np.linspace(-10, 10, 1000)
y_values = multimodal_function(x_values)
plt.plot(x_values, y_values, label='Multimodal Function')
plt.legend()
plt.title('Multimodal Function')
plt.show()
# 界说搜索范围
bounds = [(-10, 10)]
# 使用differential_evolution进行全局优化
result = differential_evolution(multimodal_function, bounds)
# 打印全局最小值过火对应的x值
print(f'Global Minimum: {result.fun} at x = {result.x}')
运行示例代码后,differential_evolution函数将复返全局最小值过火对应的x值。由于倡导函数中添加了噪声,是以每次运行代码时得到的罢了可能会有所不同。然而,通过屡次运行并比拟罢了,不错发现differential_evolution函数或者贯通地找到全局最小值隔邻的解。
非线性最小二乘
非线性最小二乘法是一种垂危的参数测度智商,它通过最小化裂缝平日和来测度非线性模子的参数。模子无为示意为y=f(x,θ),其中y是系统的输出,x是输入,θ是参数(它们不错是向量)。这里的非线性是指对参数θ的非线性模子,不包括输入输出变量随时刻的变化研究。
在测度参数时,模子的形状f是已知的。通过N次施行取得数据(x1,y1),(x2,y2),…,(xn,yn),然后聘用一个准则(或称倡导函数)来评估模子的猛烈。这个准则无为选为模子的裂缝平日和。非线性最小二乘法的倡导便是找到使裂缝平日和达到极小的参数测度值θ。
非线性最小二乘法案例
假定有一组施行数据,数据包括自变量x和因变量y。咱们但愿找到一个非线性函数来拟合这些数据,并测度该函数的参数。
示例代码
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# 准备施行数据
# 自变量x
x_data = np.array([1, 2, 3, 4, 5])
# 因变量y,假定这些数据带有一些噪声
y_data = np.array([2.1, 3.8, 6.5, 9.2, 11.9])
# 界说非线性模子函数
# 假定模子函数为 a * (x**2) + b * x + c
def func(x, a, b, c):
return a * (x**2) + b * x + c
# 调用curve_fit函数进行拟合
popt, pcov = curve_fit(func, x_data, y_data)
# 分析拟合结构
# 获得拟合的参数值
a_fit, b_fit, c_fit = popt
# 商量拟合值
y_fit = func(x_data, a_fit, b_fit, c_fit)
# 商量均方根裂缝(RMSE)
rmse = np.sqrt(np.mean((y_data - y_fit)**2))
print("拟合罢了:")
print("a =", a_fit)
print("b =", b_fit)
print("c =", c_fit)
print("RMSE =", rmse)
拟合罢了如下图所示:kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载
Powered by kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载 @2013-2022 RSS地图 HTML地图