《用Python学习数值分析-- 最优化》

2017-09-13

  最优化对应的术语是”optimization“。是工科的基础课程。数值分析与最优化是高度相关的,都大概在四年级或者研一时教授。最优化课程更加基础一些,覆盖了理论基础,想要把课程里的算法实现出来,需要深入的线性代数、矩阵计算、数值计算的知识。最优化就是机器学习的核心,在图形学方向也是基础的课程。这也是我这两三年来用固定的业余时间来补充数学课程的原因。NA 和 Optimization本就是一体的,相当于实践与理论的关系,有一本教材甚至就叫Numercial Optimization[1],太厚。在这里稍微提一下optimization,就相当于提纲挈领的做一下总结吧。 
  optimization指寻找现实世界实值函数(objective function f (x))的最大值或者最小值。把函数翻转,最大值就变成了最小值,所以,只有一个问题。优化问题一般分为“无约束”与“约束”两类。与直觉相反,有约束条件的问题,反而更难以求解一些。所以,我们可以把注意力集中在无约束优化上,这是基础。Timothy的书中也只提到了这一部分。无约束优化也分为两种:是否依赖于f的导数。我们应该尽量的使用导数,NA问题中都是如此。人脑对一个函数降维较为容易,第三四代编程语言写的程序对函数降维可没那么简单,对于高维复杂函数,我们人脑也无能为力。维度,是困难的始祖,是深渊。即使高维中的线性规划问题,都需要海量的计算。单纯形法复杂度为O( 2n )。高维非线性问题,更是困难。
  optimization问题比解方程困难。解方程组,我们只是求解一个一个或者几个确定解。而求解optimization问题,我们求解的结果是一个集合。用数值计算的方法解optimization问题,一般按照是否有导数来分为两类。 
  一,没有导数

  1. 黄金分割搜索
  2. Successive parabolic interpolation(SPI) 
  3. Nelder-Mead search

  我们很少见到这类方法,是因为我们很少用。这里只需要简单了解一下即可。解方程的方法中也有不依赖于的导数的方法:割线法、Brent's Method。
  黄金分割搜索类似于解方程用的“包围法”,如熟知的解单变量方程的二分法。前者寻找函数曲线的最低点,后者寻找曲线与y轴的交点,为什么分割比例不一样呢?因为二分法在最糟糕的情况下表现的比其他比例要好。
  Nelder-Mead 方法是更常用的方法,1965年提出。这个方法使用了单纯形的概念,是n维空间n+1个顶点的多边形。导数是带有解析信息的,不用导数必然会有代价。这里的代价就是这个方法可能收敛到一个非驻点(非驻点对于我们来说是没有意义的),除非求解的问题满足很强烈的要求。常见的改良算法是再利用梯度下降的信息。这种改良依然会遇到其他问题。
  二,有导数

  1. Newton's Method
  2. Steepest Method
  3. Conjugate Gradient Search(CG)

  这三个方法就更常见了,在解方程(组)中就开始使用。Newton–Raphson Method,需要我们提供求解的区间。类似于解方程时需要提供距离根足够近的初始点,这里提供的求解区间也需要足够的小。
  最速下降法,并不是指从山峰下降到谷底的速度最快,而是指每一步迈出,都是朝着坡度最大的方向下去,但是,没有长远的目光。牛顿法,每迈一部前,向后多看几步。所以,目光长远的,反而能以最短的路径下到谷底。wiki的图很形象。
  共轭梯度法通常和前面的梯度下降法比较,两个算法都针对对称正定矩阵。本方法一般用来解决无约束凸二次规划问题。这个问题稍微复杂一些。以后单独总结一下吧。
  scipy提供的算法以Nelder-Mead,Newton, CG,Trust Region方法为主。衍生方法可能是结合了其他的方法。单变量函数使用minimize_scalar(),多变量使用minimize()。使用方式参看链接[4],基本上就能够明白如何使用了。在这里,我觉得,如果不做算法研究,前期只需要了解这些数学概念的基础,在了解一下lib的使用方法与限制。等用到工作中后,如果发现有问题,再来深入。

 

  1. Numercial Optimization, 2nd Edition,Jorge Nocedal
  2. Numerical Analysis,  Timothy Sauer
  3. https://docs.scipy.org/doc/scipy/reference/optimize.html
  4. https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html

2017-09-13  后记
  这段时间,把我学习数值分析时做的杂乱的笔记、练习整理了一下,贴了出来,再不整理就怕丢了。算是一个阶段性的总结了。完成了一个里程碑,还有下一个。我在大学期间没有好好学习这些东西,需要花费时间补回来--实在令人悲伤。转眼已毕业四年,我也能对自己问心无愧的说,这时间,没有白过。在未来还有很多困难,慢慢解决吧。

如果有任何意见,欢迎留言讨论。 


[ 主页 ]
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 数值分析是一种广泛应用于科学计算和工程计算中的重要方法。利用Python编程语言进行数值分析计算非常方便和高效。下面是一个例子介绍如何使用Python编写数值分析计算的实习题。 假设我们有一个实习题,要求计算一个函数f(x)在区间[a, b]上的定积分。我们可以使用数值积分方法来近似计算这个定积分。例如,可以使用梯形规则来计算: 1. 首先,我们需要定义函数f(x)。例如,假设我们要计算函数f(x) = x^2在区间[0, 1]上的定积分。 ``` def f(x): return x**2 ``` 2. 然后,我们需要实现梯形规则的算法。梯形规则的计算公式如下: ``` integral = 0 h = (b - a) / n # 将区间[a, b]等分为n个子区间,h为每个子区间的宽度 for i in range(1, n): x = a + i * h integral += (f(x) + f(x - h)) * h / 2 ``` 3. 最后,我们可以调用该函数来计算积分。假设我们希望将区间[0, 1]等分为100个子区间来逼近积分值: ``` a = 0 b = 1 n = 100 integral = trapezoidal_rule(f, a, b, n) print(integral) ``` 通过上述步骤,我们可以编写一个使用Python进行数值分析计算的实习题。实习题中使用的数值方法可以根据需要进行调整和扩展,而Python具有丰富的数值计算库(例如NumPy和SciPy),可以提供更多强大的数值分析函数和工具,帮助我们完成更复杂的数值计算任务。 ### 回答2: 数值分析是一门应用数学的学科,致力于使用数值方法来近似解决数学问题。Python是一种高级编程语言,具有简单易学、功能强大、开源免费等特点,非常适合用于数值计算和科学计算。 在Python中,可以使用诸如NumPy、SciPy和matplotlib等库来进行数值分析的计算。首先,NumPy提供了丰富的数值和矩阵操作函数,可以方便地进行向量和矩阵的运算。接着,SciPy库提供了各种数值优化、插值、积分、拟合等功能,可以满足各种数值分析的需求。最后,matplotlib库可以用于绘制各种图形和图表,用于可视化数值分析的结果。 在解决实习题时,可以使用Python的函数和库来实现各种数值方法,例如用于求解非线性方程的牛顿法、用于解线性方程组的高斯消元法或LU分解法、用于数值积分的梯形法或辛普森法等。通过编写相应的函数和调用库函数,可以实现这些数值方法的计算。 在编写代码时,需要注意选择合适的数值方法,并考虑数值误差和收敛性等问题。此外,也可以利用Python的数据结构和控制语句,编写代码来进行实验数据的处理和结果的分析。 总之,使用Python编写数值分析计算实习题可以充分利用Python的优势和强大的数值计算库,实现各种数值方法的计算,并得到准确的结果。同时,Python编程语言的易学性和灵活性,也使得数值分析计算的编写过程更加简单和高效。 ### 回答3: 数值分析是一门应用数学的学科,其主要目的是通过使用计算机来解决数学问题。Python是一种功能强大且易于学习的编程语言,它提供了丰富的数值计算库和工具,非常适合用于数值分析计算。 在使用Python进行数值分析计算时,我们可以使用NumPy库来处理数组和数值操作。它提供了各种基本的数值运算函数和线性代数函数,方便进行数值计算。 例如,假设我们有一个数学问题需要通过迭代方法求解方程的根。我们可以使用Python编写一个函数,使用迭代方法来逼近根的值。代码可能如下所示: ```python import numpy as np def iterative_method(f, x0, tolerance, max_iterations): x = x0 for i in range(max_iterations): delta_x = f(x) / f_prime(x) # 根据迭代公式计算增量 x = x - delta_x # 更新解 if abs(delta_x) < tolerance: return x # 如果迭代未收敛,则返回None return None # 使用迭代方法求解方程x^2 - 2 = 0的根 f = lambda x: x**2 - 2 f_prime = lambda x: 2*x x0 = 1 # 初始猜测 tolerance = 1e-5 # 允许误差 max_iterations = 100 # 最大迭代次数 root = iterative_method(f, x0, tolerance, max_iterations) print("方程的根为:", root) ``` 此代码使用迭代方法来逼近方程x^2 - 2 = 0的根。它将函数和函数的导数作为输入参数,并根据指定的迭代次数和容差来计算逼近根的值。最终,它打印出方程的根。 总结而言,通过使用Python和相应的数值计算库,我们可以使用迭代方法、插值、数值积分等技术来解决各种数值分析问题。 Python提供了强大而灵活的工具,使得数值计算变得简单和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值