Numpy 如何使用 scipy.optimize.minimize
在本文中,我们将介绍 Numpy 中的优化模块 scipy.optimize.minimize 的用法。该模块主要用于寻找一个或多个输入值,使得一个给定的函数达到最小或最大值。Numpy 是 Python 中的一个强大的科学计算库,提供了高效的数组操作和广泛的数学函数,而 scipy.optimize.minimize 模块则为科学计算中的最优化问题提供了一个快捷的解决方案。
阅读更多:Numpy 教程
什么是最小化
在科学计算中,最小化指的是寻找一个或多个输入值,使得一个给定的函数达到最小值。这个问题得到广泛应用,例如线性回归、函数拟合、机器学习等领域都会用到最小化问题。
举个例子,假设我们要找到一个数组中的最小值。我们可以创建一个包含随机数的数组,并使用 Numpy 中的 min
函数找到最小值:
import numpy as np
# 创建一个包含随机数的数组
arr = np.array([1, 5, 3, 4, 2])
# 使用 Numpy 中的 min 函数找到最小值
min_value = np.min(arr)
另外,我们也可以使用 scipy.optimize.minimize 模块中的函数来找到最小值。例如,我们可以使用 minimize_scalar
函数来找到一个标量函数的最小值:
from scipy.optimize import minimize_scalar
# 定义一个函数
def f(x):
return x ** 2 + 3 * x + 1
# 使用 minimize_scalar 函数找到最小值
res = minimize_scalar(f)
min_value = res.fun # 最小值
上述代码中,我们定义了一个函数 f(x)
,并使用 minimize_scalar
函数找到了这个函数的最小值。
当然,除了找最小值之外,我们同样也可以使用 scipy.optimize.minimize 模块中的函数找到函数的最大值,例如 maximize_scalar
函数。
scipy.optimize.minimize 的常用函数
scipy.optimize.minimize 提供了多个函数,用于解决不同种类的最优化问题。下面是一些常用的函数:
minimize_scalar
:用于找到标量函数的最小值或最大值。minimize
:用于找到多元函数的最小值或最大值。curve_fit
:用于将一个给定函数拟合到一组数据上,并返回最优参数值。root
:用于解决非线性方程组的根问题。linprog
:用于解决线性规划问题。
下面将分别介绍几个常用的函数。
minimize_scalar
minimize_scalar
函数用于找到标量函数的最小值或最大值。 该函数需要一个目标函数作为输入,并返回一个 OptimizeResult
类型的对象。 下面是 minimize_scalar
函数的基本使用方法:
from scipy.optimize import minimize_scalar
# 定义一个函数
def f(x):
return x ** 2 + 3 * x + 1
# 使用 minimize_scalar 函数找到最小值
res = minimize_scalar(f)
min_value = res.fun # 最小值
在上述代码中,我们定义了一个函数 f(x)
,该函数是一个二次函数,并使用 minimize_scalar
函数找到了这个函数的最小值。
除此之外,minimize_scalar
函数还支持多种可选参数,例如:
method
:所使用的算法,默认为 Brent 方法。bracket
:一个包含三个实数参数 a、b 和 c 的元组,用于设置搜索空间。默认为 None,表示通过算法自行选择搜索空间。bounds
:一个包含两个实数参数的元组,设置搜索范围,默认为 None,表示不对搜索范围进行限制。options
:一个字典类型的参数,用于设置算法的其他参数。
例如,我们可以使用 method
参数指定使用黄金分割法:
from scipy.optimize import minimize_scalar
# 定义一个函数
def f(x):
return x ** 2 + 3 * x + 1
# 使用 minimize_scalar 函数找到最小值
res = minimize_scalar(f, method='golden')
min_value = res.fun # 最小值
minimize
minimize
函数用于找到多元函数的最小值或最大值。该函数需要一个目标函数、一个起始点和可选的参数作为输入,并返回一个包含最优参数和最小函数值的 OptimizeResult
类型的对象。下面是 minimize
函数的基本使用方法:
from scipy.optimize import minimize
import numpy as np
# 定义一个函数
def f(x):
return x[0] ** 2 + x[1] ** 2 + x[2] ** 2
# 设置初始点
x0 = np.array([1, 2, 3])
# 使用 minimize 函数找到最小值
res = minimize(f, x0)
min_value = res.fun # 最小值
在上述代码中,我们定义了一个三元函数 f(x)
,并将起始点设置为 [1, 2, 3]
,然后使用 minimize
函数找到了这个函数的最小值。
除此之外,minimize
函数也支持多种可选参数,例如:
method
:所使用的算法,默认为 BFGS 算法。bounds
:一个列表类型的参数,用于设置每个参数的搜索范围。constraints
:一个字典类型的参数,用于设置约束条件。tol
:算法的精度,即最小化限差的绝对值,默认为 1e-6。options
:一个字典类型的参数,用于设置算法的其他参数。
例如,我们可以使用 method
参数指定使用 Powell 算法:
from scipy.optimize import minimize
import numpy as np
# 定义一个函数
def f(x):
return x[0] ** 2 + x[1] ** 2 + x[2] ** 2
# 设置初始点
x0 = np.array([1, 2, 3])
# 使用 minimize 函数找到最小值
res = minimize(f, x0, method='Powell')
min_value = res.fun # 最小值
curve_fit
curve_fit
函数用于将一个给定函数拟合到一组数据上,并返回最优参数值。该函数需要一个目标函数、一组数据和一个初始参数值作为输入,并返回一个包含最优参数和协方差矩阵的元组。下面是 curve_fit
函数的基本使用方法:
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
# 定义一个函数
def f(x, a, b):
return a * np.sin(b * x)
# 生成一组数据
xdata = np.linspace(0, 2*np.pi, 100)
ydata = 1.5 * np.sin(2 * xdata) + np.random.normal(size=100)
# 设置初始参数
p0 = [1, 2]
# 使用 curve_fit 函数拟合数据
popt, pcov = curve_fit(f, xdata, ydata, p0)
# 绘制拟合曲线和原始数据
plt.plot(xdata, ydata, 'o', label='original data')
plt.plot(xdata, f(xdata, *popt), 'r-', label='fit')
plt.legend()
plt.show()
在上述代码中,我们定义了一个正弦函数 f(x, a, b)
,并生成了一组数据,然后使用 curve_fit
函数拟合了这组数据,并绘制了拟合曲线和原始数据。
除此之外,curve_fit
函数还支持多种可选参数,例如:
bounds
:一个包含两个列表类型的参数,用于设置每个参数的搜索范围。sigma
:一个包含数据噪声水平的数组类型的参数。absolute_sigma
:一个布尔类型的参数,用于指定是否使用数据噪声的绝对值。maxfev
:算法的最大迭代次数。method
:所使用的最小化算法,默认为 Levenberg-Marquardt 算法。
例如,我们可以使用 bounds
参数设置搜索范围:
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
# 定义一个函数
def f(x, a, b):
return a * np.sin(b * x)
# 生成一组数据
xdata = np.linspace(0, 2*np.pi, 100)
ydata = 1.5 * np.sin(2 * xdata) + np.random.normal(size=100)
# 设置初始参数
p0 = [1, 2]
# 使用 curve_fit 函数拟合数据
bounds = ([0, 0], [2*np.pi, np.inf]) # 设置搜索范围
popt, pcov = curve_fit(f, xdata, ydata, p0, bounds=bounds)
# 绘制拟合曲线和原始数据
plt.plot(xdata, ydata, 'o', label='original data')
plt.plot(xdata, f(xdata, *popt), 'r-', label='fit')
plt.legend()
plt.show()
上述代码中,我们使用 bounds
参数将第一个参数限制为 [0, 2π] 之间,将第二个参数限制为大于 0。
总结
scipy.optimize.minimize 模块提供了多个函数,用于解决不同种类的最优化问题。其中包括:
minimize_scalar
:用于找到标量函数的最小值或最大值。minimize
:用于找到多元函数的最小值或最大值。curve_fit
:用于将一个给定函数拟合到一组数据上,并返回最优参数值。root
:用于解决非线性方程组的根问题。linprog
:用于解决线性规划问题。
这些函数的使用方法不尽相同,需要针对具体问题选择适当的函数进行求解。本文对其中部分函数进行了详细介绍,并提供了相应的示例。