一連の値の中央値、モード、歪度、および/または尖度を推定するアルゴリズムはありますが、すべての値を一度にメモリに保存する必要はありませんか?
基本的な統計を計算したい:
- mean: 算術平均
- 分散: 平均からの二乗偏差の平均
- 標準偏差: 分散の平方根
- 中央値: 数値の大きい方の半分と小さい方の半分を分ける値
- モード: セットで見つかった最も頻繁な値
- 歪度: tl; 博士
- 尖度: tl; 博士
これらのいずれかを計算するための基本的な公式は小学校の算数であり、私はそれらを知っています. それらを実装する多くの統計ライブラリもあります。
私の問題は、私が処理しているセット内の多数 (数十億) の値です。Python で作業していると、数十億の要素でリストやハッシュを作成することはできません。これを C で書いたとしても、10 億要素の配列はあまり実用的ではありません。
データはソートされていません。他のプロセスによって、オンザフライでランダムに生成されます。各セットのサイズは非常に可変であり、サイズは事前にわかりません。
セット内の各値を任意の順序で反復して、平均と分散を適切に処理する方法をすでに理解しています。(実際、私の場合、生成された順序でそれらを取得します。) これが私が使用しているアルゴリズムです。
- 3 つの変数を初期化します: count、sum、および sum_of_squares
- 各値について:
- 増分カウント。
- 合計に値を追加します。
- 値の 2 乗を sum_of_squares に追加します。
- 合計をカウントで割り、変数の平均として保存します。
- sum_of_squares をカウントで割り、変数 mean_of_squares として格納します。
- 二乗平均、square_of_mean として保存します。
- mean_of_squares から square_of_mean を引き、分散として保存します。
- 平均と分散を出力します。
この「オンライン」アルゴリズムには弱点があります (たとえば、sum_of_squares が整数の範囲や float の精度よりも急速に大きくなるため、精度の問題が発生するなど)、基本的には、各セットにすべての値を格納する必要がなく、必要なものが得られます。
しかし、追加の統計 (中央値、モード、歪度、尖度) を推定するための同様の手法が存在するかどうかはわかりません。N 個の値を処理するために必要なメモリが O(N) よりも大幅に少ない限り、偏った推定器や、精度をある程度損なう方法を使用することもできます。
ライブラリにこれらの操作の1つ以上を「オンライン」で計算する関数がある場合、既存の統計ライブラリを指すことも役立ちます。