寶寶問了我一個最小二乘法的算法,我忘記了,鞏固了之后來總結一下。
首先先理解最小二乘法:
最小二乘法(又稱最小平方法)是一種數學優化技術。它通過最小化誤差的平方和尋找數據的最佳函數匹配。利用最小二乘法可以簡便地求得未知的數據,並使得這些求得的數據與實際數據之間誤差的平方和為最小。最小二乘法還可用於曲線擬合。其他一些優化問題也可通過最小化能量或最大化熵用最小二乘法來表達。
具體可以看鏈接:https://blog.csdn.net/ccnt_2012/article/details/81127117
最小二乘法的公式為:
設擬合直線的公式為
,

其中:擬合直線的斜率為:
;計算出斜率后,根據
和已經確定的斜率k,利用待定系數法求出截距b。



具體算法為:
①根據數據,就算出平均數X,和平均數Y,后面用大寫的X和Y代表平均數
②計算(x1-X)×(y1-Y),計算(x2-X)×(y2-Y)……計算(xn-X)×(yn-Y)
③將②中計算得到的所有數據相加,作為分子
④計算(x1-X)²,計算(x2-X)²……計算(xn-X)²
⑤將④中計算得到的所有數據相加,作為分母
⑥將③中的分子和⑤中的分母相除,得到b
a用Y-bX計算。
例題:第一組
(9.84,7.72)
(7.38,8.00)
(4.92,8.13)
(2.46,8.30)
(0,8.51)
第二組
(7.18,7.90)
(5.38,7.96)
(3.52,8.16)
(1.75,8.38)
(0,8.51)
用最小二乘法求擬合曲線的斜率
對這些點(x,y),直接用最小二乘法得出斜率及常數項:
y=bx+a .
b的分子為:(x1y1+x2y2+...xnyn)-nx'y' ,x',y'分別為xi,yi的平均值
b的分母為:(x1^2+x2^2+...xn^2)-n(x')^2
求出了b之后,再用公式算出a=y'-bx'
對這兩組,分別有:
y1=-0.0764x+8.508
y2=-0.0911x+8.507
代碼為:
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 }