2013-05-11 59 views
2

我需要高效地進行多元線性迴歸。我試圖使用Math.NET Numerics軟件包,但它看起來很慢 - 也許這是我編寫它的方式?對於這個例子,我只有簡單的(1 x值)迴歸。C#Math.NET Numerics中的LinearRegression代碼可以更快嗎?

我有這樣的片段:

 public class barData 
     { 
      public double[] Xs; 
      public double Mid; 
      public double Value; 

     } 

     public List<barData> B; 


     var xdata = B.Select(x=>x.Xs[0]).ToArray(); 
     var ydata = B.Select(x => x.Mid).ToArray(); 

     var X = DenseMatrix.CreateFromColumns(new[] { new DenseVector(xdata.Length, 1), new DenseVector(xdata) }); 
     var y = new DenseVector(ydata); 

     var p = X.QR().Solve(y); 
     var b = p[0]; 
     var a = p[1]; 
     B[0].Value = (a * (B[0].Xs[0])) + b; 

這運行約20倍比這個純C#慢:

 double xAvg = 0; 
     double yAvg = 0; 

     int n = -1; 
     for (int x = Length - 1; x >= 0; x--) 
     { 
      n++; 
      xAvg += B[x].Xs[0]; 
      yAvg += B[x].Mid; 
     } 

     xAvg = xAvg/B.Count; 
     yAvg = yAvg/B.Count; 

     double v1 = 0; 
     double v2 = 0; 

     n = -1; 
     for (int x = Length - 1; x >= 0; x--) 
     { 
      n++; 
      v1 += (B[x].Xs[0] - xAvg) * (B[x].Mid - yAvg); 
      v2 += (B[x].Xs[0] - xAvg) * (B[x].Xs[0] - xAvg); 
     } 

     double a = v1/v2; 
     double b = yAvg - a * xAvg; 

     B[0].Value = (a * B[Length - 1].Xs[0]) + b; 

此外,如果Math.NET是問題,那麼如果有誰知道簡單的方法來改變我的多個X的純代碼我會感謝一些幫助

+0

您是否確定要在任何調試器之外運行發佈版本? – 2013-05-11 09:25:17

+0

什麼是慢鏡頭? 'var p = X.QR()。Solve(y)'? – 2013-05-11 11:11:09

回答

2

使用QR分解是一種非常通用的方法,可以將最小二乘迴歸解決方案提供給任何帶有linea的函數r參數,不管它有多複雜。因此,它不能與一個非常具體的直接實現(在計算時間上)競爭,尤其不是在y:x->a+b*x的簡單情況下。不幸的是,Math.NET Numerics不提供直接的迴歸例程,但您可以使用它。

然而,仍有一對夫婦的事情,你可以嘗試更好的速度:

  • 使用薄的,而不是全面QR decompositon,即通過QRMethod.ThinQR方法
  • 使用我們的native MKL provider(快得多QR ,但不再是純粹的託管代碼)
  • 調整線程,例如嘗試完全禁用(Control.ConfigureSingleThread())多線程或調整其參數

如果數據集非常大,也有更有效的方式來建立矩陣,但是這可能不是QR旁非常相關的( - > perf分析!)。

+0

我會嘗試你的建議 - 謝謝你。 – ManInMoon 2013-05-14 08:54:42

相關問題