C#/ .Net中的高效多元线性回归

时间:2010-05-26 05:50:13

标签: c# .net linear-regression

有没有人知道在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 个答案:

答案 0 :(得分:3)

为了记录,我最近找到了ALGLIB库,虽然没有太多文档,但它有一些非常有用的功能,例如linear regression这是我追求的事情之一。

示例代码(这是旧的未经验证的,只是我如何使用它的一个基本示例)。我使用时间序列的线性回归,有3个条目(称为3分钟/ 2分钟/ 1分钟),然后是结束值(最终)。

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]);
}

答案 1 :(得分:2)

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

答案 2 :(得分:1)

尝试Meta.Numerics

  

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

要填充矩阵,请参阅ColumnVector Constructor (IList<Double>)的示例。它可以从许多有序的实数集合中构造ColumnVector,包括double []和List。

答案 3 :(得分:1)

我可以建议使用FinMath。它是极其优化的.net数值计算库。它使用英特尔数学核心库进行复杂的计算,如线性回归或矩阵求逆,但大多数类都有非常简单易用的接口。当然,它可以扩展到大量数据。 mrnye的例子如下:

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);

答案 4 :(得分:1)

要进行线性回归,我倾向于使用 Math.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

答案 5 :(得分:0)

我最近遇到了MathNet-Numerics - 可以在MIT许可下获得。

它声称为常见的X.TransposeThisAndMultiply(X).Inverse() * X.TransposeThisAndMultiply(y) 流程提供了更快的替代方案。

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

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

或者,您可以使用Cholesky decomposition

/*!50003 DROP PROCEDURE IF EXISTS `my_test_procedure` */;