16

連立方程式の数が1000(3つまたは4つの異なる入力)になる可能性があるC#で重回帰を実行する効率的な方法を知っている人はいますか?重回帰に関するこの記事を読んだ後、行列方程式を使用して実装してみました。

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

ただし、行列の反転操作のため、数千の方程式のスケールにうまくスケーリングできません。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;
}
4

6 に答える 6

3

記録のために、私は最近、ALGLIBライブラリを見つけました。これは、ドキュメントはあまりありませんが、私が求めていたものの1つである線形回帰などの非常に便利な機能を備えています。

サンプルコード(これは古くて検証されていません。私がどのように使用していたかの基本的な例です)。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]);
}
于 2010-10-19T22:51:14.970 に答える
2

反転される行列のサイズは、連立方程式(サンプル)の数に応じて大きくなりません。x.Transpose()* xは正方行列であり、次元は独立変数の数です。

于 2010-05-26T10:12:28.580 に答える
1

試してみてくださいMeta.Numerics

Meta.Numericsは、.NETFrameworkの高度な科学計算用のライブラリです。C#、Visual Basic、F#、またはその他の.NETプログラミング言語から使用できます。Meta.Numericsライブラリは完全にオブジェクト指向であり、実装と実行の速度が最適化されています。

マトリックスにデータを入力するには、の例を参照してくださいColumnVector Constructor (IList<Double>)ColumnVectordouble []やListなど、順序付けられた実数のコレクションからを構築できます。

于 2010-05-26T06:24:13.193 に答える
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);
于 2011-10-20T18:20:38.433 に答える
1

線形回帰を行うには、Math.NetNumericsを使用する傾向があります。

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
于 2018-03-21T11:21:57.920 に答える
0

私は最近、MITライセンスの下で利用可能なMathNet-Numericsに出くわしました。

それは、一般的なプロセスのためのより速い代替案を提供すると主張してい(X.Transpose() * X).Inverse() * (X.Transpose() * y)ます。

これがこの記事からのいくつかの最適化です。最初のものは:

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

または、コレスキー分解を使用できます:

X.TransposeThisAndMultiply(X).Cholesky().Solve(X.TransposeThisAndMultiply(y))
于 2017-09-22T05:52:54.520 に答える