SciPy函数库在NumPy库的基础上增加了众多的数学、科学以及工程计算中常用的库函数。 例如线性代数、常微分方程数值求解、信号处理、图像处理、稀疏矩阵等等。 作为入门介绍,让我们看看如何用SciPy进行插值处理、信号滤波。
假设有一组实验数据(x[i], y[i]),我们知道它们之间的函数关系:y = f(x),通过这些已知信息,需要确定 函数中的一些参数项。例如,如果f是一个线型函数f(x) = k*x+b,那么参数k和b就是我们需要确定的 值。如果将这些参数用 p 表示的话,那么我们就是要找到一组 p 值使得如下公式中的S函数最小:
m ∑ S(p) = [y i − f (x i , p)] 2 i=1
这种算法被称之为最小二乘拟合(Least-square fitting)。 scipy中的子函数库optimize已经提供了实现最小二乘拟合算法的函数leastsq。
下面是用leastsq进行数据拟合的一个例子:
import numpy as np
from scipy.optimize import leastsq
import pylab as pl
定义数据拟合所用的函数: Asin(2pikx + theta) 。
def func(x, p):
A, k, theta = p
return A*np.sin(2*np.pi*k*x+theta)
定义函数,实验数据x, y和拟合函数之间的差,p为拟合需要找到的系数:
def residuals(p, y, x):
return y - func(x, p)
x = np.linspace(0, -2*np.pi, 100)
A, k, theta = 10, 0.34, np.pi/6 # 真实数据的函数参数
y0 = func(x, [A, k, theta]) # 真实数据
y1 = y0 + 2 * np.random.randn(len(x)) # 加入噪声之后的实验数据
p0 = [7, 0.2, 0] # 第一次猜测的函数拟合参数
调用 leastsq
进行数据拟合,
residuals
为计算误差的函数,
p0
为拟合参数的初始值,
args
为需要拟合的实验数据。
plsq = leastsq(residuals, p0, args=(y1, x))
print("真实参数:", [A, k, theta])
print("拟合参数", plsq[0]) # 实验数据拟合后的参数
真实参数: [10, 0.34, 0.5235987755982988] 拟合参数 [-10.17681323 0.34033561 -2.5945805 ]
由于在制图中会用到中文,需要先设置字体:
from matplotlib import font_manager
# font_manager.fontManager.addfont('/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc')
# font_manager.fontManager.addfont('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc')
for font in font_manager.fontManager.ttflist:
# 查看字体名以及对应的字体文件名
if 'wqy' in font.name.lower() or 'wenquanyi' in font.name.lower():
print(font.name, '-', font.fname)
pl.rcParams['font.sans-serif'] = 'WenQuanYi Zen Hei'
进行可视化制图,调用leastsq函数对噪声正弦波数据进行曲线拟合:
pl.plot(x, y0, label="真实数据")
pl.plot(x, y1, label="带噪声的实验数据")
pl.plot(x, func(x, plsq[0]), label="拟合数据")
pl.legend()
pl.show()
findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 30495 (\N{CJK UNIFIED IDEOGRAPH-771F}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 23454 (\N{CJK UNIFIED IDEOGRAPH-5B9E}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25454 (\N{CJK UNIFIED IDEOGRAPH-636E}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 24102 (\N{CJK UNIFIED IDEOGRAPH-5E26}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22122 (\N{CJK UNIFIED IDEOGRAPH-566A}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 22768 (\N{CJK UNIFIED IDEOGRAPH-58F0}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 39564 (\N{CJK UNIFIED IDEOGRAPH-9A8C}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 25311 (\N{CJK UNIFIED IDEOGRAPH-62DF}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) /opt/conda/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 21512 (\N{CJK UNIFIED IDEOGRAPH-5408}) missing from font(s) DejaVu Sans. fig.canvas.print_figure(bytes_io, **kw) findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei findfont: Generic family 'sans-serif' not found because none of the following families were found: WenQuanYi Zen Hei
这个例子中我们要拟合的函数是一个正弦波函数,它有三个参数 A, k, theta , 分别对应振幅、频率、相角。 假设我们的实验数据是一组包含噪声的数据 x, y1,其中y1是在真实数据y0的基础上加入噪声的到了。
通过leastsq函数对带噪声的实验数据x, y1进行数据拟合,可以找到x和真实数据y0之间的正弦关系的三个参数: A, k, theta。下面是程序的输出:
我们看到拟合参数虽然和真实参数完全不同,但是由于正弦函数具有周期性,实际上拟合参数得到的 函数和真实参数对应的函数是一致的。