Question Régression linéaire multiple efficace dans C # / .Net


Est-ce que quelqu'un connaît un moyen efficace de faire une régression linéaire multiple en C #, où le nombre d'équations simultanées peut être dans les 1000 (avec 3 ou 4 entrées différentes). Après avoir lu Cet article sur la régression linéaire multiple, j'ai essayé de l'implémenter avec une équation matricielle:

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

Cependant, elle ne s'adapte pas bien à l'échelle de 1 000 équations en raison de l'opération d'inversion de la matrice. Je peux appeler le langage R et l'utiliser, mais j'espérais qu'il y aurait une solution .Net pure qui s'adapterait à ces grands ensembles.

Aucune suggestion?

EDIT # 1:

J'ai choisi d'utiliser R pour le moment. En utilisant statconn (téléchargé ici) J'ai trouvé cette méthode rapide et relativement facile à utiliser. C'est à dire. Voici un petit extrait de code, ce n'est vraiment pas beaucoup de code pour utiliser la bibliothèque R statconn (note: ce n'est pas tout le code!).

_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;
}

15
2018-05-26 05:50


origine


Réponses:


Pour mémoire, j'ai récemment trouvé le ALGLIB bibliothèque qui, sans avoir beaucoup de documentation, possède des fonctions très utiles comme la régression linéaire ce qui est l'une des choses que j'étais après.

Exemple de code (ceci est ancien et non vérifié, juste un exemple de base de mon utilisation). J'utilisais la régression linéaire sur les séries chronologiques avec 3 entrées (appelées 3min / 2min / 1min) puis la valeur finale (finale).

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

3
2017-10-19 22:51



La taille de la matrice en cours d'inversion ne croît PAS avec le nombre d'équations simultanées (échantillons).     x.Transpose () * x est une matrice carrée où la dimension est le nombre de variables indépendantes.


2
2018-05-26 10:12



Essayer Meta.Numerics:

Meta.Numerics est une bibliothèque pour le calcul scientifique avancé dans le .NET Framework. Il peut être utilisé à partir de C #, Visual Basic, F # ou tout autre langage de programmation .NET. La bibliothèque Meta.Numerics est entièrement orientée objet et optimisée pour la rapidité de mise en œuvre et d'exécution.

Pour remplir une matrice, voir un exemple de ColumnVector Constructor (IList<Double>). Il peut construire un ColumnVector de nombreuses collections ordonnées de réels, y compris double [] et liste.


1
2018-05-26 06:24



Je peux suggérer d'utiliser FinMath. C'est une bibliothèque de calcul numérique .net extrêmement optimisée. Il utilise la bibliothèque Intel Math Kernel Library pour effectuer des calculs complexes tels que la régression linéaire ou l'inverse de la matrice, mais la plupart des classes ont des interfaces accessibles très simples. Et bien sûr, il est extensible à un grand nombre de données. L'exemple de mrnye ressemblera à ceci:

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

1
2017-10-20 18:20



Pour faire des régressions linéaires, j'ai tendance à utiliser Math.Net Numérique

Math.NET Numerics vise à fournir des méthodes et des algorithmes pour le numérique   calculs en science, ingénierie et utilisation quotidienne. Sujets couverts   inclure des fonctions spéciales, algèbre linéaire, modèles de probabilité, aléatoire   nombres, interpolation, intégration, régression, problèmes d'optimisation   et plus.

Par exemple, si vous souhaitez adapter vos données à une ligne en utilisant une régression linéaire, c'est aussi simple que cela:

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

1
2018-03-21 11:21



Je suis récemment tombé sur MathNet-Numérique - qui est disponible sous licence MIT.

Il prétend fournir des alternatives plus rapides pour le commun (X.Transpose() * X).Inverse() * (X.Transpose() * y) processus.

Voici quelques optimisations de Cet article. Le premier étant:

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

Ou vous pourriez utiliser Décomposition de Cholesky:

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

0
2017-09-22 05:52