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

时间:2013-05-11 07:26:36

标签: c# regression mathdotnet

我需要有效地进行多元线性回归。我正在尝试使用Math.NET Numerics包,但它似乎很慢 - 也许它是我编码的方式?对于这个例子,我只有简单的(1 x值)回归。

我有这个片段:

        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;

这比纯粹的C#运行大约20倍SLOWER:

       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的纯代码的简单方法,我会感激一些帮助

1 个答案:

答案 0 :(得分:2)

使用QR分解是一种非常通用的方法,可以为具有线性参数的任何函数提供最小二乘回归解决方案,无论它有多复杂。因此,它不能与非常具体的直接实现(计算时间)竞争,特别是在y:x->a+b*x的简单情况下,这并不奇怪。不幸的是,Math.NET Numerics不提供直接的回归例程,而是可以使用。

然而,您仍可以尝试一些更好的速度:

  • 使用瘦而不是完整的QR分解,即将QRMethod.Thin传递给QR方法
  • 使用我们的native MKL provider(更快的QR,但不再是纯托管代码)
  • 调整线程,例如尝试完全禁用多线程(Control.ConfigureSingleThread())或调整其参数

如果数据集非常大,那么构建矩阵的方法也更为有效,但除了QR之外,这可能不太相关(&gt;性能分析!)。