Эффективная множественная линейная регрессия в C# / .Net

кто-нибудь знает эффективный способ сделать множественную линейную регрессию в 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());
}

однако он не масштабируется хорошо до масштаба 1000-х уравнений из-за операции инверсии матрицы. Я могу назвать язык R и использовать его, однако я был надеясь, что будет чистое решение .Net, которое будет масштабироваться до этих больших наборов.

какие предложения?

правка #1:

Я решил использовать R на данный момент. С помощью предоставление (загружено здесь) я обнаружил, что это быстрый и относительно простой в использовании этот метод. Т. е. вот небольшой фрагмент кода, это действительно не так много кода, чтобы использовать библиотеки предоставление Р (Примечание: это не весь код!).

_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 ответов


для записи, я недавно нашел ALGLIB библиотека, которая, не имея много документации, имеет некоторые очень полезные функции, такие как линейная регрессия что является одной из вещей, которые я искал.

пример кода (это старый и непроверенный, просто основной пример того, как я его использовал). Я использовал линейную регрессию по временным рядам с 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]);
}

размер инвертируемой матрицы не растет с числом одновременных уравнений (выборок). X. Транспонировать () * x квадратная Матрица, где размерностью является число независимых переменных.


попробовать Meta.Numerics:

мета.Numerics-это библиотека для передовых научных вычислений в .NET Framework. Его можно использовать из C#, Visual Basic, F# или любого другого языка программирования .NET. мета.Библиотека Numerics полностью объектно-ориентирована и оптимизирована для скорости реализации и выполнения.

чтобы заполнить матрицу, см. Пример ColumnVector Constructor (IList<Double>). Он может построить ColumnVector из многих заказанных коллекции reals, включая double[] и List.


Я могу предложить использовать FinMath. Это чрезвычайно оптимизированная библиотека численных вычислений .net. Он использует библиотеку ядра Intel Math для выполнения сложных вычислений, таких как линейная регрессия или обратная матрица, но большинство классов имеют очень простые доступные интерфейсы. И, конечно же, он масштабируется до больших наборов данных. пример мрнье будет выглядеть так:

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

для линейных регрессий я обычно использую 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

Я недавно наткнулся на MathNet-Numerics - который доступен под лицензией MIT.

он утверждает, что обеспечивает более быстрые альтернативы для общего