本文始发于个人公众号: TechFlow, 原创不易, 求个关注
今天的文章我们来讨论大名鼎鼎的泰勒公式, 泰勒公式 https://book.douban.com/subject/2112359/ 真的非常有名, 我相信上过高数课的一定都记得它的大名. 即使你翘掉了所有的课, 也一定会在考前重点里见过.
我对它的第一映像就是比较难, 而且感觉没有太多意思, 就是一个近似的函数而已. 最近重温了一下有了一些新的心得, 希望尽我所能讲解清楚.
泰勒公式的用途
在看具体的公式和证明之前, 我们先来了解一下它的用途, 然后带着对用途的理解再去思考它出现的背景以及原理会容易许多. 这也是我自学这么久总结出来的规律.
泰勒公式本质解决的是近似的问题, 比如说我们有一个看起来很复杂的方程, 我们直接计算方程本身的值可能非常麻烦. 所以我们希望能够找到一个近似的方法来获得一个足够近似的值.
从这里, 我们得到了两个重点, 一个是近似的方法, 另一个是近似的精度. 我们既需要找到合适的方法来近似, 同时也需要保证近似的精度是可控的. 否则一切都没有意义, 结合实际其实很好理解, 比如我们用机床造一个零件. 我们都知道世界上不存在完美的圆, 实际上我们也并不需要完美, 但是我们需要保证偏差是可控的, 并且在一定的范围内. 泰勒公式也是一样, 它既可以帮助我们完成近似, 也可以保证得到的结果是足够精确的.
泰勒公式的定义
我们下面来看看泰勒公式的定义, 我们已经知道了它的用途是求一个函数的近似值. 但是我们怎么来求呢, 其实一个比较朴素的思路是通过斜率逼近.
举个例子:
这是一张经典的导数图, 从上图我们可以看到, 随着 \(\Delta x\)的减小, 点 \(P_0\)和 \(P\)也会越来越接近, 这就带来了 \(\Delta y\)越来越接近 \(\Delta x \cdot f'(x_0)\).
当然, 当 \(\Delta x\)比较大的时候显然误差就会比较大, 为了缩小误差, 我们可以引入二阶导数, 三阶导数以及高阶导数. 由于我们并不知道函数究竟可以有多少阶导数, 我们不妨假设 f(x)在区间内一直有 (n+1) 阶导数, 我们试着写出一个多项式来逼近原函数:
\[P_n(x)=a_0+a_1(x-x_0)+a_2(x-x_0)^2+\cdots+a_n(x-x_0)^n\]
我们希望这个式子与原值的误差越小越好, 究竟要多小才算足够好呢? 数学家们给出了定义, 希望它是 \((x-x_0)^n\)的高阶无穷小. 也就是说误差比上 \((x-x_0)^n\)的极限是 0.
我们前面说了, 我们是通过导数来逼近的, 所以我们假设:
\[ \begin{aligned} P_n(x_0) &= f(x_0), P_n'(x_0) = f'(x_0) \\ P_n''(x_0) &= f''(x_0), \cdots, P_n^{(n)} = f^{(n)}(x_0) \end{aligned} \]
按照这个假设我们可以很方便地得到系数了, 其实很简单, 我们构造系数使得求导之后相乘的常数项全部约掉.
\[ \begin{aligned} a_0 = f(x_0), 1\cdot a_1 = f'(x_0) \\ 2!\cdot a_2 = f''(x_0), \cdots, n!\cdot a_n = f^n(x_0) \end{aligned} \]
我们把这两个式子带入一下, 可以得到:
\[P_n(x)=f(x_0)+f'(x_0)(x - x_0)+\frac{f''(x_0)}{2!}(x - x_0)^2+\cdots+\frac{f^{(n)}}{n!}(x-x_0)^n\]
泰勒公式的证明
其实上面的式子就是泰勒公式的内涵了, 也就是说我们通过高阶导数来逼近了原函数. 最后我们只需要证明这个式子就是我们想要的, 也就是它的误差足够小.
我们同样用一个函数 \(R(x)\)来表示 \(P_n(x)\)与原函数 \(f(x)\)的差值. 我们直接比较比较困难, 所以数学家采取了一系列花里胡哨, 叹为观止的操作.
我们带入一下可以发现,\(R(x_0)=0\), 不仅如此,\(R'(x_0)=R''(x_0)=\cdots=R^{(n)}(x_0)=0\).
以上步骤完全不需要证明, 我们直接带入求导就可以得到. 因为存在 \(x-x_0\)的项, 很明显当 \(x=x_0\)的时候, 可以得到如上的结论.
到这里, 我们需要进行一个猜测, 这里的步骤有一点跳跃. 就连课本上都没有详细的解释, 没有详细解释的原因也很简单, 因为需要用到积分的知识. 而读者在这里是还没有接触过积分的, 不过, 我们不是严谨的论文, 可以稍稍放松一些. 其实根据上面的公式, 我们是可以有些猜测的. 根据上面的规律, 以及我们的目标 -- 证明这个 \(R(x)\)函数是一个关于 \((x-x_0)^n\)的无穷小, 所以我们可以猜测它应该是一个与 \((x-x_0)^{n+1}\)相关的函数.
有了这个猜测之后, 我们套用一下柯西中值定理:
\[\frac{f(b) - f(a)}{F(b) - F(a)}=\frac{f'(\xi)}{F'(\xi)}\]
我们令 \(f(x)=R_n(x), F(x)=(x-x_0)^{n+1}\), 套用中值定理可以得到:
\[\frac{R_n(x)}{(x-x_0)^{n+1}}=\frac{R_n(x)-R_n(x_0)}{(x-x_0)^{n+1}-0}=\frac{R'_n(\xi_1)}{(n+1)(\xi_1-x_0)^n}, (\xi_1 \in (x_0, x))\]
有了这个结论之后, 我们再对函数 \(R_n'(x)\)和 \((n+1)(x-x_0)^n\)在区间 \((x_0, \xi_1)\)上再次应用柯西中值定理:
\[\frac{R_n'(\xi_1)}{(\xi_1 - x_0)^n}=\frac{R'_n(\xi_1)-R_n'(x_0)}{(n+1)(\xi_1-x_0)^n-0}=\frac{R''_n(\xi_2)}{n(n+1)(\xi_2-x_0)^{n-1}}, (\xi_2 \in (x_0, \xi_1))\]
接下来就是熟悉的套娃环节了, 经过一共 n+1 次套娃之后, 我们可以得到:
\[\frac{R_n(x)}{(x-x_0)^{n+1}}=\frac{R^{(n+1)}_n(\xi)}{(n+1)!}, (\xi \in (x_0, \xi_n))\]
我们对 \(P_n(x)\)求 n+1 次导数, 可以得到 0, 因为所有项最多只有 n 次, 求 n+1 次导数之后全部变成 0. 也就是说 \(P^{(n+1)}_n(x)=0\), 所以 \(R^{(n+1)}_n(x)=f^{(n+1)}_n(x)\), 我们把这项代入上式, 可以得到:
\[R_n(x)=\frac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1}, (\xi \in (x_0, x))\]
证明一下误差
接下来我们要证明这个误差 \(R_n(x)\)是 \((x-x_0)^{n+1}\)的高阶无穷小.
到这里, 证明就很简单了, 在固定的区间 (a, b) 中, 很明显函数 \(f^{(n+1)}(x)\)存在最大值, 我们假设这个最大值是 M. 也就是说 \(f^{(n+1)}(x) \leq M, x \in (a, b)\)
那么:
\[\lim_{x\to x_0}\frac{R_n(x)}{(x-x_0)^n} \leq \lim_{x\to x_0} \frac{\frac{M(x-x_0)^{n+1}}{(n+1)!}}{(x-x_0)^n}=\lim_{x\to x_0}\frac{M(x-x_0)}{(n+1)!}\]
由于 x 逼近 \(x_0\),M 是一个常数, 所以这个极限趋向于 0, 我们可以用极限的定义很容易证明. 于是我们证明了, 误差 \(R_n(x)\)是比 \((x-x_0)^n\)更高阶的无穷小.
所以我们可以得到:
\[f(x)=f(x_0)+f'(x_0)(x - x_0)+\frac{f''(x_0)}{2!}(x - x_0)^2+\cdots+\frac{f^{(n)}}{n!}(x-x_0)^n+R_n(x)\]
由于我们一共用到了 n 阶导数来表达原函数, 所以我们称为这是原函数 f(x)的 n 阶泰勒展开. 最后的 \(R_n(x)=\frac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1}, (\xi \in (x_0, x))\), 我们称它为拉格朗日余项. 我们也可以简写为 \(o[(x-x_0)^n]\), 它称为佩亚诺型余项, 其实和拉格朗日余项是一回事, 只是写的形式不同.
我们如果令 \(x_0=0\)的话, 还可以将式子进一步化简. 由于 \(\xi\)在 0 和 x 中间, 所以我们可以令 $\xi=\theta x, (0 < \theta < 1) $, 原公式可以写成:
\[f(x)=f(0)+f'(0)x + \frac{f''(0)}{2!}x^2+\cdots + \frac{f^{(n)}(0)}{n!}x^n+\frac{f^{(n+1)}(\theta x)}{(n+1)!}x^{n+1}, (0 < \theta < 1)\]
和上面的式子相比, 这个式子要简单许多, 它也有一个名字, 叫做麦克劳林公式. 在麦克劳林公式下的佩亚诺余项写成 \(o(x^n)\), 看起来非常简单.
如果觉得上面的式子有点多记不过来可以忽略原式, 只需要记住麦克劳林公式即可. 对于拉格朗日余项, 我们也只会在计算误差的时候用到, 在不需要考虑误差的场景下也可以忽略.
举例
下面我们来看一个实际的例子, 来感受一下泰勒公式的强大.
我们都知道有一些函数的值我们很难直接计算, 比如 \(f(x)=e^x\), 和正弦余弦函数等. 由于 e 本身就是一个无理数, 有没有想过我们怎么来求一个带 e 的函数值? 其实很多时候, 就是用的泰勒公式.
我们就用 \(f(x)=e^x\)举例, 看看怎么利用泰勒公式来计算 \(e^x\).
为了简化计算, 我们显然考虑麦克劳林公式. 由于 \(x=0\)时,\(e^x=0\), 并且 \(f'(x)=e^x\).
所以我们可以得到:
\[f'(0)=f''(0)=f'''(0)=\cdots =f^{(n)}(0)=1\]
我们代入泰勒公式, 可以得到:
\[e^x=1 + x + \frac{1}{2!}x^2+\frac{1}{3!}x^3+\cdots+\frac{1}{n!}x^n+\frac{e^{\theta x}}{(n+1)!}x^{n+1}\]
我们如果把最后一项当成误差, 那么可以得到:
\[e^x\approx 1 + x + \frac{1}{2!}x^2+\frac{1}{3!}x^3+\cdots+\frac{1}{n!}x^n\]
当 n=10 时, x=1, 产生的误差为:
\[\frac{e^{\theta x}}{(n+1)!}x^{n+1}\leq \frac{e}{11!}<\frac{3}{11!}\]
我们稍微算一下就可以知道, 这个误差小于 \(10^{-6}\), 已经足够接近了. 也就是说我们把原本不太好计算的函数转化成了若干个多项式的和, 可以非常简单地获得一个足够接近的近似值. 并且除此之外, 我们还能算出它的最大误差, 实在是非常完美了.
思考
到这里还没有结束, 看完所有的推导和计算之后, 不知道你们有没有一个疑惑, 这么一个牛叉并且复杂并且有用的公式, 泰勒是怎么灵光一闪想到的? 好像用一时的灵感很难解释. 毕竟人的灵感往往都是一瞬间对某个点的顿悟, 而这么多公式和结论是很难顿悟的.
之前上学的时候我完全没有意识到这个问题, 这次重温的时候才觉得不对. 当然你可能会说这里有这么多数学家的名字, 显然不是一个人的功劳. 但即使是这样, 我仍然好奇, 究竟是什么起因引出了这么伟大的公式?
直到我无意间看到知乎撒欢大神 https://www.zhihu.com/question/20887356 的回答才恍然大悟.
我们设想一个问题, 如果 f(x)=g(x), 那么显然 f(x)和 g(x)的各阶导数全都相等. 那么问题来了, 如果我们人为地构造一个函数 h(x), 使得它的各阶导数和 g(x)吻合, 那么是不是可以认为这个我们人为构造出来的函数也和 g(x)相等呢?
然而有些函数的高阶导数是无穷无尽的, 我们不可能人工全部拟合, 所以只能退而求其次, 拟合其中的 n 项. 显然这样会有误差, 那么我们需要知道误差的大小. 于是就有了后面的拉格朗日余项大小的推算.
泰勒公式的出现和推导过程正是基于这样的思路, 想到这里, 我又有了新的想法. 如果把各阶导数的项看成是特征, 那么这个问题其实转化成了机器学习当中的回归问题, 只不过在机器学习当中我们是设定优化目标和优化方法, 让模型自行训练来拟合逼近, 而泰勒公式其实是通过思维和数学的力量推算出了结果, 两者的目的和结果是一样的, 但是过程完全迥异, 两个看似完全风马牛不相及的问题殊途同归, 不得不说数学的魅力真的令人折服.
今天的文章就是这些, 如果觉得有所收获, 请顺手扫码点个关注吧, 你们的举手之劳对我来说很重要.
来源: https://www.cnblogs.com/techflow/p/12424803.html