[C#] 使用 Excel 和 Math.Net 進行曲線擬合和數據預測

以前在工作中遇到了一個數據錯誤的問題,順便寫下 用 Math.Net 解決的思路。

1. 錯誤的數據

上圖是同一組探測器在同一天採集到的 19 次數據,總體來說重複性不錯,但很明顯最後 8 個探測器出了問題,導致採集到的數據在最後八個點一片混亂。即使把其中看起來最好的一組數據拿出來使用多項式擬合,也可以看出最後幾個點沒有落在擬合曲線上(只擬合最後 14 個點):

雖然我知道這是硬體問題,但是遇到事情不能坐以待斃,軟體方面也許可以做些什麼。既然我從上圖中得知出了最後幾個點之外,其它數據都在擬合曲線上,那我可以使用前面幾個點的擬合結果預測後面幾個點並替換掉出錯的數據,從而得到一組看起來正常的數據。

2. 曲線擬合與數據預測

曲線擬合(curve fitting)是指選擇適當的曲線類型來擬合觀測數據,以便觀察兩組數據之間的內在聯繫,了解數據之間的變化趨勢。

在數據分析時,我們有時需要通過已有數據來預測未來數據。在一些複雜的數據模型中,數據維度很多,數據之間的關係很複雜,我們可能會用到深度學習的演算法。但是在一些簡單的數據模型中,數據之間有很明顯的相關性,那我們就可以使用簡單的曲線擬合來預測未來的數據。

這些工作都可以使用 Excel 完成,先來嘗試一下。把某組數據最後14個點(只選取峰值右邊的14個點是因為容易計算)放進Excel中,插入一個散點圖,右鍵點擊其中的藍色散點,選擇添加趨勢線

然後在右側出現的設置趨勢線格式中選擇多項式,階數為 3,勾選顯示公式

可以看到,曲線圖中出現了一條虛線的曲線,並顯示了對應的公式為 y = 6E-07x3 + 0.0002x2 - 0.0072x + 0.0637

如果需要預測數據,可以修改前推數字以得到後面幾個周期的數據。

3. 使用 Math.Net 進行曲線擬合

當然我不可能對每一條數據都扔進 Excel 里進行擬合。在 C# 中我們可以使用 Math.Net 進行非線性擬合。

Math.Net 是一個開源項目,旨在構建和維護涵蓋基礎數學的工具箱,以滿足 .Net 開發人員的高級需求和日常需求。其中 Math.NET Numerics 旨在為科學、工程和日常使用中的數值計算提供方法和演算法。涵蓋的主題包括特殊函數,線性代數,概率模型,隨機數,插值,積分變換等等。

要使用 Math.NET Numerics,首先安裝它的 Nuget 包:

Install-Package MathNet.Numerics

Math.NET Numerics 提供了 Fit.Polynomial 函數用作多項式擬合,如以下程式碼所示,其中 X 是 X 軸的數組, Y 是 Y 軸的數組, 函數的第三個參數是多項式的階數,這裡用 2 作為階數。

double[] X = Enumerable.Range(1, 6).Select(r => (double)r).ToArray();
double[] Y = values.ToArray();
double[] parameters = Fit.Polynomial(X, Y, 2);

返回的結果是最佳擬合參數的數組 [p0,p1,p2,…,pk],將其帶入公式 p0 + p1×x + p2×x2 + ... + pk×xk 即可算出對應的擬合數據。完整的程式碼如下,在這個示例里,我只需要用倒數第9到14個數據,通過 Fit.Polynomial 獲得一個多項式的方程 ( f(x) = p0 + p1×x + p2×x2 ),然後用這個方程計算出後面 8 個點的數據替換原本出錯的數據:

double[] X = Enumerable.Range(1, 6).Select(r => (double)r).ToArray();
double[] Y = values.ToArray();
double[] parameters = Fit.Polynomial(X, Y, 2);


List<double> result = new List<double>();
for (int i = 1; i < 15; i++)
{
    result.Add(parameters[0] + parameters[1] * i + parameters[2] * i * i );
}

for (int i = 0; i < 8; i++)
{
    data[data.Count - 1 - i] = result[result.Count - 1 - i];
}

替換後的結果如上所示,整體符合前面數據的趨勢,使用這組數據進行運算也能得到很好的結果。

4. 最後

Math.Net 是一個強大的項目,這篇文章只介紹了它所有功能的冰山一角。想了解更多可以參考官方文檔,或參考部落格園上的文章,例如:

【目錄】開源Math.NET基礎數學類庫使用總目錄 – 數據之巔 – 部落格園

5. 參考

Math.NET Numerics

Curve Fitting Linear Regression

【目錄】開源Math.NET基礎數學類庫使用總目錄 – 數據之巔 – 部落格園

數據預測與曲線擬合 – 知乎

6. 源碼

//github.com/DinoChan/SimpleDataPrediction

Tags: