电脑
二维数据
mathematica
给一组数据f:p = Table[RandomReal[], 36];q = Table[N[3.6 Sin[x], 6], {x, 0, 2 Pi, 2 Pi/35}];f = p + q
这个数据其实是二维的:因为数据是可数的,所以,我们可以把数据排列为第一个数字,第二个数字,等等。这样,就产生了一个函数关系,其自变量是正整数,而因变量是给定数据里面的数字,如f(1)=0.807243,f(2)=1.01259,……
我们的目标,就是依靠给定的数据,找到相应的函数表达式g,使得g(n)和f(n)尽量的接近,对于所有的n=1,2,3,……。
g如果构造出来了,有什么用呢?最简单的应用,就是预测近期数据。比如,给出前10000个数字,预测第10001个数字。一般的,离得越远,预测的可靠性越低,如天气预报。
假设g(n)=a*n,那么,我们得到一组新数据:g(1)、g(2)、……
我们考虑新数据与原数据之间的差方:(g(1)-f(1))^2,(g(2)-f(2))^2,……这些差方的平均值G,就体现新数据与原数据的差别,或者叫做拟合的误差。如果这个差别过大,那么这个g就不合适了。
我们要求出G的最小值,也就是误差的最小值。我们用微积分学的理论,通过对G关于a求导函数,且导函数等于0,求出a的值,然后带入到G里面,得到G的值。这个值很可能就是最小值,但也有可能不是,有可能只是局部极小值,还有可能是极大值或最大值。
检测是否是极小值:作G关于a的图像(注意,下图的图形不合比例),或者,直接证明,二次函数如果开口朝上,就有最小值。
看看误差最小的时候,拟合效果如何?把原数据作成散点图,再画出使G最小时,g的图像,对比一下,差别一目了然。通过图像可以知道,正比例函数不能用。
考虑一次函数。不过,我们需要关心的是,误差最小的拟合,所以直接找误差最小的一次函数。g[n_] := a*n + bh = g /@ Range[36];G = Table[((h[[n]]) - (f[[n]]))^2/36, {n, 1, 36}] // Total // Simplify;jie = Solve[{D[G, a] == 0, D[G, b] == 0}, {a, b}] // Flatten;Show[ListLinePlot[f, Mesh -> All],Plot[g[n] /. jie, {n, 0, 36}, PlotStyle -> Green]]拟合效果不好。
注意,上面的G是关于a、b的函数,需要分别对a和b求偏导数。G = Table[((h[[n]]) - (f[[n]]))^2/36., {n, 1, 36}] // Total
各个偏导数都等于0,才有可能找到使G取最小值的a和b。
作出G的图像,是个开口朝上的抛物柱面,所以G是有最小值的。
其实,mathematica已经把这个拟合的过程,整合为一个内置命令了:h = a*n + b; FindFit[f, h, {a, b}, n]
先找到误差最小的二次函数:此时得到的误差函数是关于a、b、c的三元函数,需要分别求偏导数,然后所有的偏导数等于0,解这个方程组,得到a、b、c的值,代入到g里面。我们用FindFit,可以有效避免这个复杂的过程:h = a*n^2 + b*n + c;nihe = FindFit[f, h, {a, b, c}, n]Show[ ListLinePlot[f, Mesh -> All], Plot[h /. nihe, {n, 0, 36}, PlotStyle -> Green]]跟上面的一次函数,效果差不多?
再试试三次函数,G是关于a、b、c、d的四元函数。注意:此时的G的图像,已经不太可能绘制出来了。但我们仍旧可以证明,G存在最小值。这个的拟合效果,就很好啦。
跨出一大步,试试七次方程的效果。此时,G是八元函数。上面的过程,就是告诉我们,随着函数次数的增大,误差可以越来越小。
试试正弦函数与一次函数的复合函数:a*sin(b*n+c)+d
再试试指数函数与一次函数的复合:a^n + b*n^3 + c*n^2 + d*n + e
别的情形还有无线多,读者有兴趣的话,可以自己去尝试,这里就不再继续举例。
本文,通过具体的例子,介绍了把数据拟合成不同的函数的例子。
这里介绍的拟合,是各种模型(含参函数)下,最小的均方差对应的情形。而拟合的误差,除了均方差,还可以是绝对值方差等等。
拟合的模型需要大家自己尝试,或者画出散点图去看图猜测。