使用Scipy进行函数优化

      【翻译自 : Function Optimization With SciPy

      【说明:Jason Brownlee PhD大神的文章个人很喜欢,所以闲暇时间里会做一点翻译和学习实践的工作,这里是相应工作的实践记录,希望能帮到有需要的人!】

        

         优化涉及寻找目标函数的输入,从而导致函数的最小或最大输出。

         用于科学计算的开源Python库SciPy提供了一组优化算法。许多算法被用作其他算法的构建块,最著名的是scikit-learn库中的机器学习算法。

        这些优化算法可以直接以独立方式使用以优化功能。最值得注意的是,本地搜索算法和全局搜索算法是您在机器学习项目中可能遇到的两种主要优化类型。

        在本教程中,您将发现SciPy库提供的优化算法。

       完成本教程后,您将知道:

SciPy库提供了一套针对不同目的的不同优化算法。
SciPy中提供了本地搜索优化算法。
SciPy中提供了全局搜索优化算法。

教程概述

       本教程分为三个部分: 他们是:

科学的优化
使用SciPy进行本地搜索
SciPy的全球搜索

科学的优化

        用于科学计算的Python SciPy开源库提供了一套优化技术。

         许多算法被用作SciPy库以及机器学习库(例如scikit-learn)中其他算法的构建块。

         在审查特定技术之前,让我们看一下库提供的算法类型。

        他们是:

标量优化:凸单变量函数的优化。
本地搜索:优化单峰多变量函数。
全局搜索:多模式多变量函数的优化。
最小二乘:解决线性和非线性最小二乘问题。
曲线拟合:将曲线拟合到数据样本。
根查找:查找函数的根(输出为零的输入)。
线性规划:线性优化受约束。

        所有算法都假设正在优化的目标函数是最小化函数。如果您的函数正在最大化,则可以通过向目标函数返回的值添加负号来将其转换为最小化。

        除了上面的列表之外,该库还提供一些算法使用的实用程序功能以及Rosenbrock测试问题。

       有关SciPy库优化功能的概述,请参见:

                                                                              优化和根查找(scipy.optimize)API
       现在,我们对库支持的优化技术的类型有了一个高层次的了解,让我们仔细研究一下我们更可能在应用机器学习中使用的两组算法。它们是本地搜索和全局搜索。

使用SciPy进行本地搜索

          局部搜索或局部功能优化是指寻找输入到函数的算法,该算法会导致最小或最大输出,其中假定正在搜索的函数或受约束区域具有单个最优值,例如。 单峰的。

         正在优化的函数可以是凸函数,也可以不是凸函数,并且可以具有一个或多个输入变量。

        如果功能被认为或已知是单峰的,则可以直接应用局部搜索优化来优化功能。 否则,可以应用局部搜索算法来微调全局搜索算法的结果。SciPy库通过minimal()函数提供本地搜索。minimal()函数将要最小化的目标函数的名称以及开始搜索的起始点作为输入,并返回OptimizeResult,该结果概述搜索的成功或失败以及解决方案的详细信息(如果找到)。

# minimize an objective function
result = minimize(objective, point)

       如果已知,则可以提供有关目标函数的其他信息,例如输入变量的界限,用于计算函数一阶导数的函数(梯度或雅可比矩阵),用于计算函数二阶导数的函数(Hessian) 矩阵),以及对输入的任何约束。重要的是,该函数提供了“方法”参数,该参数允许指定在本地搜索中使用的特定优化。

       提供了一套流行的本地搜索算法,例如:

Nelder-Mead算法(方法=“ Nelder-Mead”)。
牛顿法(method ='Newton-CG')。
鲍威尔的方法(方法=“鲍威尔”)。
BFGS算法和扩展名(方法=“ BFGS”)。

       下面的示例演示了如何使用L-BFGS-B局部搜索算法求解二维凸函数。

# l-bfgs-b algorithm local optimization of a convex function
from scipy.optimize import minimize
from numpy.random import rand

# objective function
def objective(x):
	return x[0]**2.0 + x[1]**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# define the starting point as a random sample from the domain
pt = r_min + rand(2) * (r_max - r_min)
# perform the l-bfgs-b algorithm search
result = minimize(objective, pt, method='L-BFGS-B')
# summarize the result
print('Status : %s' % result['message'])
print('Total Evaluations: %d' % result['nfev'])
# evaluate solution
solution = result['x']
evaluation = objective(solution)
print('Solution: f(%s) = %.5f' % (solution, evaluation))

       运行示例将执行优化,并报告搜索的成功或失败,执行的功能评估的次数以及导致功能最佳化的输入。

Status : b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
Total Evaluations: 9
Solution: f([3.38059583e-07 3.70089258e-07]) = 0.00000

         既然我们熟悉将本地搜索算法与SciPy结合使用,那么让我们看一下全局搜索。

SciPy的全局搜索

        全局搜索或全局功能优化是指寻找功能输入的算法,该算法会导致最小或最大输出,其中假定正在搜索的功能或约束区域具有多个局部最优值,例如,多式联运。要优化的函数通常是非线性的,非凸的,并且可能具有一个或多个输入变量。全局搜索算法通常是随机的,这意味着它们会在搜索过程中利用随机性,并且可能会或可能不会在搜索过程中管理大量候选解决方案。

       SciPy库提供了许多随机的全局优化算法,每种算法都通过不同的功能。他们是:

通过Basinhopping()函数实现盆地跳跃优化。
通过differential_evolution()函数进行差分进化优化。
通过dual_annealing()函数进行的模拟退火。

        该库还提供用于序列优化的shgo()函数和用于网格搜索优化的brute()。每种算法都返回一个OptimizeResult对象,该对象概述搜索的成功或失败以及解决方案的详细信息(如果找到)。

         下面的示例演示了如何使用模拟退火求解二维多峰函数。

# simulated annealing global optimization for a multimodal objective function
from scipy.optimize import dual_annealing

# objective function
def objective(v):
	x, y = v
	return (x**2 + y - 11)**2 + (x + y**2 -7)**2

# define range for input
r_min, r_max = -5.0, 5.0
# define the bounds on the search
bounds = [[r_min, r_max], [r_min, r_max]]
# perform the simulated annealing search
result = dual_annealing(objective, bounds)
# summarize the result
print('Status : %s' % result['message'])
print('Total Evaluations: %d' % result['nfev'])
# evaluate solution
solution = result['x']
evaluation = objective(solution)
print('Solution: f(%s) = %.5f' % (solution, evaluation))

       运行示例将执行优化,并报告搜索的成功或失败,执行的功能评估的次数以及导致功能最佳化的输入。

Status : ['Maximum number of iteration reached']
Total Evaluations: 4028
Solution: f([-3.77931027 -3.283186 ]) = 0.00000

参考APIS

            Optimization (scipy.optimize) API.
            Optimization and root finding (scipy.optimize) API.

猜你喜欢

转载自blog.csdn.net/Together_CZ/article/details/113756441