C#Math.NET Numerics中的LinearRegression代码可以更快吗?

问题描述:

我需要高效地进行多元线性回归。我试图使用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

使用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