先上代码:

 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    }

 算法解释:

  曲线拟合的常用方法:

    偏差绝对值之和最小:

    

    偏差绝对值最大的最小:

    

    偏差平方和最小:

    

  其中使偏差平方和最小的方法称为最小二乘法

  以直线拟合为例。设xy之间的函数关系为:

    

  上式中有两个待定参数,a代表截距,b代表斜率。对于等精度测量所得到的N组数据(xiyi),i=1,2……,N,xi值被认为是准确的,所有的误差只联系着yi;

  用最小二乘法估计参数时,要求观测值yi的偏差的加权平方和为最小。对于等精度观测值的直线拟合来说,可使下式的值最小:

    

  令上式等于D,并对a,b分别求一阶偏导数:

    

  再求二阶偏导数:

    

  显然二阶偏导数均为非负数。令一阶偏导数为0:

    

  解得:

    

  相关系数r:

    最小二乘法处理数据除给出a、b外,常常还给出相关系数r,r定义为:

    

(完)