代码之家  ›  专栏  ›  技术社区  ›  mike

C/.NET中的有效多重线性回归

  •  15
  • mike  · 技术社区  · 15 年前

    有人知道在C中进行多重线性回归的有效方法吗?在C中,联立方程的数量可能在1000个(有3个或4个不同的输入)中。读后 this article 在多元线性回归中,我尝试用矩阵方程来实现它:

    Matrix y = new Matrix(
        new double[,]{{745},
                      {895},
                      {442},
                      {440},
                      {1598}});
    
    Matrix x = new Matrix(
         new double[,]{{1, 36, 66},
                     {1, 37, 68},
                     {1, 47, 64},
                     {1, 32, 53},
                     {1, 1, 101}});
    
    Matrix b = (x.Transpose() * x).Inverse() * x.Transpose() * y;
    
    for (int i = 0; i < b.Rows; i++)
    {
      Trace.WriteLine("INFO: " + b[i, 0].ToDouble());
    }
    

    然而,由于矩阵求逆运算,它不能很好地扩展到1000个方程的规模。我可以调用R语言并使用它,但是我希望有一个纯的.NET解决方案可以扩展到这些大的集合。

    有什么建议吗?

    编辑第1页:

    我已经决定暂时使用R了。通过使用statconn(下载 here )我发现使用这种方法既快又相对容易。也就是说,这里有一个小的代码片段,使用r-statconn库实际上根本不需要太多的代码(注意:这不是所有的代码!).

    _StatConn.EvaluateNoReturn(string.Format("output <- lm({0})", equation));
    object intercept = _StatConn.Evaluate("coefficients(output)['(Intercept)']");
    parameters[0] = (double)intercept;
    for (int i = 0; i < xColCount; i++)
    {
      object parameter = _StatConn.Evaluate(string.Format("coefficients(output)['x{0}']", i));
      parameters[i + 1] = (double)parameter;
    }
    
    6 回复  |  直到 7 年前
        1
  •  3
  •   mike    14 年前

    作为记录,我最近发现 ALGLIB 虽然没有太多文档,但具有一些非常有用的功能的库,如 linear regression 这是我想要的东西之一。

    示例代码(这是一个古老且未经验证的代码,只是我使用它的一个基本示例)。我在时间序列上使用线性回归,有3个条目(称为3min/2min/1min),然后是完成值(final)。

    public void Foo(List<Sample> samples)
    {
      int nAttributes = 3; // 3min, 2min, 1min
      int nSamples = samples.Count;
      double[,] tsData = new double[nSamples, nAttributes];
      double[] resultData = new double[nSamples];
    
      for (int i = 0; i < samples.Count; i++)
      {
        tsData[i, 0] = samples[i].Tminus1min;
        tsData[i, 1] = samples[i].Tminus2min;
        tsData[i, 2] = samples[i].Tminus3min;
    
        resultData[i] = samples[i].Final;
      }
    
      double[] weights = null;
      int fitResult = 0;
      alglib.lsfit.lsfitreport rep = new alglib.lsfit.lsfitreport();
      alglib.lsfit.lsfitlinear(resultData, tsData, nSamples, nAttributes, ref fitResult, ref weights, rep);
    
      Dictionary<string, double> labelsAndWeights = new Dictionary<string, double>();
      labelsAndWeights.Add("1min", weights[0]);
      labelsAndWeights.Add("2min", weights[1]);
      labelsAndWeights.Add("3min", weights[2]);
    }
    
        2
  •  2
  •   Joe H    15 年前

    被反转的矩阵的大小不会随着联立方程(样本)的数目而增长。 x.转置()*x 是一个方阵,其中维数是独立变量的数目。

        3
  •  1
  •   gimel    15 年前

    尝试 Meta.Numerics :

    meta.numerics是.NET框架中用于高级科学计算的库。它可以从C、Visual Basic、F或任何其他.NET编程语言中使用。meta.numerics库完全面向对象,并针对实现和执行速度进行了优化。

    要填充矩阵,请参见 ColumnVector Constructor (IList<Double>) . 它可以构造一个 ColumnVector 从许多有序的real集合中,包括double[]和list。

        4
  •  1
  •   Wisdom's Wind    13 年前

    我可以建议使用 FinMath . 它是非常优化的.NET数值计算库。它使用英特尔数学内核库进行复杂的计算,如线性回归或矩阵求逆,但大多数类都有非常简单的可接近接口。当然,它可以扩展为一大组数据。 Nye先生的例子如下:

    using FinMath.LeastSquares;
    using FinMath.LinearAlgebra;
    
    Vector y = new Vector(new double[]{745,
        895,
        442,
        440,
        1598});
    
    Matrix X = new Matrix(new double[,]{
        {1, 36, 66},
        {1, 37, 68},
        {1, 47, 64},
        {1, 32, 53},
        {1, 1, 101}});
    
    Vector b = OrdinaryLS.FitOLS(X, y);
    
    Console.WriteLine(b);
    
        5
  •  1
  •   FisNaN    7 年前

    做线性回归,我倾向于使用 数学.NET 数字。

    math.net numerics旨在提供数值计算的方法和算法 科学、工程和日常使用中的计算。涵盖主题 包括特殊函数、线性代数、概率模型、随机 数字、插值、积分、回归、优化问题 还有更多。

    例如,如果您想使用线性回归将数据拟合到一条直线上,可以这样简单:

    double[] xdata = new double[] { 10, 20, 30 };
    double[] ydata = new double[] { 15, 20, 25 };
    Tuple"<"double, double">" p = Fit.Line(xdata, ydata);
    double a = p.Item1; // == 10; intercept
    double b = p.Item2; // == 0.5; slope
    
        6
  •  0
  •   Nisarg Shah    7 年前

    我最近遇到 MathNet-Numerics -可在麻省理工学院许可证下使用。

    它声称为公众提供更快的选择 (X.Transpose() * X).Inverse() * (X.Transpose() * y) 过程。

    以下是一些优化 this article . 第一个是:

    X.TransposeThisAndMultiply(X).Inverse() * X.TransposeThisAndMultiply(y)
    

    或者,你可以用 Cholesky decomposition :

    X.TransposeThisAndMultiply(X).Cholesky().Solve(X.TransposeThisAndMultiply(y))