美文网首页程序员
「Scipy」样条插值在数据可视化中的运用

「Scipy」样条插值在数据可视化中的运用

作者: Stray_Wanderer | 来源:发表于2020-04-19 22:03 被阅读0次

好久没有更新文章了,学校的教材发下来了,作业一下就变多了。


最终效果

首先,把最终效果放出来:

# -*- coding: utf-8 -*-
# GitHub: AC-Stray
# Date: 2020/4/19 0019 19:34
import numpy as np
import pylab as pl
from scipy import interpolate
import matplotlib.pyplot as plt

x = list(range(1, 11))
y = [55, 8, 27, 59, 99, 68, 2, 89, 74, 44]

x_new = np.linspace(min(x), max(x), 10000)
tck = interpolate.splrep(x, y)
y_bspline = interpolate.splev(x_new, tck)

plt.plot(x, y, "o", label="Point")
plt.plot(x_new, y_bspline, label="B-spline")

pl.legend()
pl.show()
Figure_1.png

运用样条插值,即B-Spline,可以使你在图表中使用曲线连接离散数据(在插值法中,这些离散数据称为节点

在Python中使用样条插值

正如你在上面所看到的那样,在Python中插值非常简单,Scipy中的interpolate为你提供了样条插值所需要的一系列函数。

import部分就不多说了,

x = list(range(1, 11))
y = [55, 8, 27, 59, 99, 68, 2, 89, 74, 44]

这里首先定义了一系列节点,这里数据是随机的,

x_new = np.linspace(min(x), max(x), 10000)
tck = interpolate.splrep(x, y)
y_bspline = interpolate.splev(x_new, tck)

接下来,首先使用linspace为插值提供所需的x值,splrep根据节点计算了样条曲线的参数,最后将其传递给splev计算插值后的结果。

数学中的插值法

你可能是抱着想要用曲线连接节点的目的来看这篇文章,但看到这里还没搞懂插值法是个什么玩意,那么接下来的内容就是在讲数学中的插值法,与Python和Scipy已无关联。

插值法,就是在给定的节点中作出合适的函数,使得这条曲线经过每一个节点,这也就是为什么在数据可视化中使用插值而不是其他方法的原因,因为插值后仍然能够准确知道每一节点所对应的值。

那么,是不是节点越多,插值的准确性就越高呢?

貌似是这样,毕竟节点越多,对曲线的限制条件就越多,那准确性不久越高了。

但是呢,如果你使用多节点直接插值(不是在程序中插值,因为程序会使用分段样条插值),你就会发现,曲线在两段有明显的震荡,并且节点越多,震荡越明显、越大:

龙格现象

这种现象被称为Tolmé Runge现象(龙格现象),描述的就是这一问题。对此的数学证明在知乎上有,传送门

通过龙格现象,我们会发现,当节点数量趋向于无穷时,插值的误差会趋向于无穷大:
\lim_{n \to \infty} \left (\max_{a \leq x \leq b}|f(x)-P_n(x)| \right)=\infty
那么,如何避免这一情况呢,可以把我们原先的等距节点替换成Chebyshev节点,但是如果我们的离散数据确实等距,这一方法不好用,那么就可以才用分段插值,我们的程序对龙格现象也是这样处理的。

分段插值就是将高次多项式拆分成多个低次多项式,一般都拆分成三次多项式。

拟合(回归)

由于插值和拟合常常一起出现,所以这里也简单提一下拟合。

拟合是对你给出的离散数据,作出于数据差距最小的函数,另外,按照拟合的结果,拟合也分线性拟合和非线性拟合。

拟合与插值的差别就在于,插值必须过节点,但是拟合不需要,所以拟合曲线的整体效果会更好,也就是更平滑。

拟合一般都用在数据分析里,因为拟合曲线更能够看出整体的变化趋势嘛。


这篇文章写起来难度还是想当大,如果我的描述有问题的话,欢迎评论区留言。


前往我的博客查看本文

相关文章

网友评论

    本文标题:「Scipy」样条插值在数据可视化中的运用

    本文链接:https://www.haomeiwen.com/subject/dcjibhtx.html