1

私は計算を高速に実行するための最良の方法を見つけようとしており、このような状況で人々が通常どのようなアプローチを取るかを知りたいと思っていました.

の平均と標準偏差を計算したいプロパティを持つオブジェクトのリストがありますこのMath.NETライブラリを使用すると、おそらくパフォーマンスが向上し、最適化されると思いました。

残念ながら、これらの関数の入力引数は配列です。平均と STD を計算する独自の関数を作成する唯一の解決策はありますか? hereのようなラムダ関数を使用するリストの拡張メソッドを作成できますか? それとも、オブジェクト プロパティの配列を返す関数を作成し、これらを Math.NET で使用する方がよいでしょうか。

おそらく、答えはリストのサイズなどに依存しますか?議論のために、リストに 50 個の要素があるとしましょう。私の懸念は純粋にパフォーマンスです。

4

2 に答える 2

5

ArrayStatisticsこの特殊なケースに合わせて最適化されているため、実際には配列が必要です (これが ArrayStatistics と呼ばれる理由です)。同様に、StreamingStatisticsデータをメモリに保持せずに IEnumerable シーケンス ストリーミング用に最適化されています。すべての種類の入力で機能する一般的なクラスはStatisticsクラスです。

LINQ と StreamingStatistics を使用するだけでは十分に高速ではないことを確認しましたか? わずか 50 個のエントリのリストについてこれらの統計を計算することは、ループで 100 万回実行しない限り、ほとんど測定できません。

Math.NET Numerics v3.0.0-alpha7 の例で、リスト内のタプルを使用してカスタム型をエミュレートします。

using MathNet.Numerics.Statistics;

var data = new List<Tuple<string, double>>
{
    Tuple.Create("A", 1.0),
    Tuple.Create("B", 2.0),
    Tuple.Create("C", 1.5)
};

// using the normal extension methods within `Statistics`
var stdDev1 = data.Select(x => x.Item2).StandardDeviation();
var mean1 = data.Select(x => x.Item2).Mean();

// single pass variant (unfortunately there's no single pass MeanStdDev yet):
var meanVar2 = data.Select(x => x.Item2).MeanVariance();
var mean2 = meanVar2.Item1;
var stdDev2 = Math.Sqrt(meanVar2.Item2);

// directly using the `StreamingStatistics` class:
StreamingStatistics.MeanVariance(data.Select(x => x.Item2));
于 2014-02-25T16:56:57.773 に答える
1

使用できる最も簡単な解決策は、配列に変換するようにLinqを置くことですList

  List<SomeClass> list = ...

  GetMeanAndStdError(list.ToArray()); // <- Not that good performance

ただし、パフォーマンスが重要な場合は、平均と分散を明示的に計算します (独自の関数を作成します)。

  List<SomeClass> list = ...

  Double sumX = 0.0;
  Double sumXX = 0.0;

  foreach (var item in list) {
    Double x = item.SomeProperty;

    sumX += x;
    sumXX += x * x;
  }

  Double mean = sumX / list.Count;
  Double variance = (sumXX / list.Count - mean);
于 2014-02-25T11:54:17.477 に答える