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

mik*_*ike 16 .net c# linear-regression

有没有人知道在C#中进行多元线性回归的有效方法,其中联立方程的数量可能在1000(有3或4个不同的输入).在阅读了关于多元线性回归的这篇文章之后,我尝试用矩阵方程实现它:

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());
}
Run Code Online (Sandbox Code Playgroud)

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

有什么建议?

编辑#1:

我暂时使用R定居.通过使用statconn(在这里下载),我发现它既快又相对容易使用这种方法.即这里是一个小代码片段,使用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;
}
Run Code Online (Sandbox Code Playgroud)

mik*_*ike 3

作为记录,我最近发现了ALGLIB库,虽然没有太多文档,但有一些非常有用的功能,例如线性回归,这是我所追求的功能之一。

示例代码(这是旧的且未经验证的,只是我如何使用它的基本示例)。我对时间序列使用线性回归,包含 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]);
}
Run Code Online (Sandbox Code Playgroud)