平滑数据拟合
smoothfit的Python项目详细描述
给定实验数据,通常需要生成值匹配的函数 数据在某种程度上。该软件包实现了一种基于 关于最小化问题
(信号处理中的数据平滑也采用了类似的思想;参见,例如, this document中的第8.3节
与polynomial regression或 Gauss-Newton, smoothfit对函数没有任何假设,只是它是平滑的。
该方法的通用性使其适用于域为 多维的。
否则就不会发生
伦格的例子
importmatplotlib.pyplotaspltimportnumpyimportsmoothfita=-1.5b=+1.5# plot original functionx=numpy.linspace(a,b,201)plt.plot(x,1/(1+25*x**2),"-",color="0.8",label="1 / (1 + 25 * x**2)")# 21 sample pointsx0=numpy.linspace(-1.0,1.0,21)y0=1/(1+25*x0**2)plt.plot(x0,y0,"xk")u=smoothfit.fit1d(x0,y0,a,b,1000,degree=1,lmbda=1.0e-6)x=numpy.linspace(a,b,201)vals=[u(xx)forxxinx]plt.plot(x,vals,"-",label="smooth fit")plt.ylim(-0.1)plt.grid()plt.show()
Runge's example function是 经典多项式回归的难点。
如果输入数据中没有噪声,参数lmbda
可以选择得很小
这样,所有的数据点都可以很好地近似。注意没有振荡
在输出函数u
中。
带有噪声的runge示例
^{ | ^{ | ^{ |
importmatplotlib.pyplotaspltimportnumpyimportsmoothfita=-1.5b=+1.5# plot original functionx=numpy.linspace(a,b,201)plt.plot(x,1/(1+25*x**2),"-",color="0.8",label="1 / (1 + 25 * x**2)")# 21 sample pointsnumpy.random.seed(0)n=51x0=numpy.linspace(-1.0,1.0,n)y0=1/(1+25*x0**2)y0+=1.0e-1*(2*numpy.random.rand(n)-1)plt.plot(x0,y0,"xk")lmbda=5.0e-2u=smoothfit.fit1d(x0,y0,a,b,1000,degree=1,lmbda=lmbda)x=numpy.linspace(a,b,201)vals=[u(xx)forxxinx]plt.plot(x,vals,"-",label="smooth fit")plt.grid()plt.show()
如果数据有噪声,则需要更仔细地选择lmbda
。如果太小,
近似试图解析所有数据点,导致许多小的振荡。
如果选择太大,则不会解决任何细节问题,即使是底层的
数据。
很少样本
importnumpyimportsmoothfitx0=numpy.array([0.038,0.194,0.425,0.626,1.253,2.500,3.740])y0=numpy.array([0.050,0.127,0.094,0.2122,0.2729,0.2665,0.3317])u=smoothfit.fit1d(x0,y0,0,4,1000,degree=1,lmbda=1.0)
从中获取的一些噪声示例数据 Wikipedia。
二维示例
importmeshzooimportnumpyimportsmoothfitn=200numpy.random.seed(123)x0=numpy.random.rand(n,2)-0.5y0=numpy.cos(numpy.pi*numpy.sqrt(x0.T[0]**2+x0.T[1]**2))# create a triangle mesh for the squarepoints,cells=meshzoo.rectangle(-1.0,1.0,-1.0,1.0,32,32)u=smoothfit.fit2d(x0,y0,points,cells,lmbda=1.0e-4,solver="dense-direct")# Write the function to a filefromdolfinimportXDMFFilexdmf=XDMFFile("temp.xdmf")xdmf.write(u)
此实例将函数从^ {EM1} $ R< SUP>2 < /SUP>< EEM >到^ {EM1}$ReEEM>(无噪声) 样品)。注意,没有噪音的数据允许我们选择一个相当小的 {< CD1> },使得所有样本点都得到很好的近似。
与其他方法的比较
多项式拟合/回归
数据拟合的经典方法是polynomial regression。多项式是 选择它们是因为它们非常简单,可以快速计算,并且can be made to fit any function very closely。
但是,还有一些基本问题:
- 你的数据可能并不符合低阶多项式。
- Runge's phenomenon。
上面的图表突出了振荡的问题。
傅里叶平滑
用平滑法拟合数据的一种方法是用所有数据创建一个函数 点,并简单地切断傅里叶变换后的高频。
这种方法很快,但只适用于均匀分布的样本。
importmatplotlib.pyplotaspltimportnumpynumpy.random.seed(0)# original functionx0=numpy.linspace(-1.0,1.0,1000)y0=1/(1+25*x0**2)plt.plot(x0,y0,color="k",alpha=0.2)# create sample pointsn=51x1=numpy.linspace(-1.0,1.0,n)# only works if samples are evenly spacedy1=1/(1+25*x1**2)+1.0e-1*(2*numpy.random.rand(x1.shape[0])-1)plt.plot(x1,y1,"xk")# Cut off the high frequencies in the transformed space and transform backX=numpy.fft.rfft(y1)X[5:]=0.0y2=numpy.fft.irfft(X,n)#plt.plot(x1,y2,"-",label="5 lowest frequencies")plt.grid()plt.show()
测试
要运行smoothfit单元测试,请签出此存储库并键入
pytest
许可证
smoothfit发布在MIT license下。