先上代码:
1 /// <summary> 2 /// 最小二乘法线性拟合 3 /// </summary> 4 /// <param name="x">横坐标集合</param> 5 /// <param name="y">纵坐标集合</param> 6 /// <param name="slope">返回拟合直线的斜率</param> 7 /// <param name="intercept">返回拟合直线的截距</param> 8 /// <param name="r_square">返回相关系数R²</param> 9 static void LinearFitting(double[] x, double[] y, out double slope, out double intercept, out double r_square) 10 { 11 int length = x.Length; 12 double xmean = 0.0; 13 double ymean = 0.0; 14 for (int i = 0; i < length; i++) 15 { 16 xmean += x[i]; 17 ymean += y[i]; 18 } 19 xmean /= length; 20 ymean /= length; 21 22 double sumx2 = 0.0; 23 double sumy2 = 0.0; 24 double sumxy = 0.0; 25 for (int i = 0; i < length; i++) 26 { 27 sumx2 += (x[i] - xmean) * (x[i] - xmean); 28 sumy2 += (y[i] - ymean) * (y[i] - ymean); 29 sumxy += (y[i] - ymean) * (x[i] - xmean); 30 } 31 slope = sumxy / sumx2; 32 intercept = ymean - slope * xmean; 33 r_square = sumxy * sumxy / (sumx2 * sumy2);
34 }
算法解释:
曲线拟合的常用方法:
偏差绝对值之和最小:
偏差绝对值最大的最小:
偏差平方和最小:
其中使偏差平方和最小的方法称为最小二乘法。
以直线拟合为例。设x和y之间的函数关系为:
上式中有两个待定参数,a代表截距,b代表斜率。对于等精度测量所得到的N组数据(xi,yi),i=1,2……,N,xi值被认为是准确的,所有的误差只联系着yi;
用最小二乘法估计参数时,要求观测值yi的偏差的加权平方和为最小。对于等精度观测值的直线拟合来说,可使下式的值最小:
令上式等于D,并对a,b分别求一阶偏导数:
再求二阶偏导数:
显然二阶偏导数均为非负数。令一阶偏导数为0:
解得:
相关系数r:
最小二乘法处理数据除给出a、b外,常常还给出相关系数r,r定义为:
(完)