格納するには大きすぎるデータセットの中央値を推定するための優れたアルゴリズム(最小限の計算、最小限のストレージ要件を意味する)を探しています。想定できるデータに制限はありません。
精度がわかっている限り、近似は問題ありません。
ポインタはありますか?
格納するには大きすぎるデータセットの中央値を推定するための優れたアルゴリズム(最小限の計算、最小限のストレージ要件を意味する)を探しています。想定できるデータに制限はありません。
精度がわかっている限り、近似は問題ありません。
ポインタはありますか?
回答:
各グループの中央値を計算した場合、データセットを非常に小さなデータセット(100または1000または10,000データポイントなど)にグループ化できますか。十分なデータセットでこれを行った場合、十分な小さなデータセットを実行して「平均」ソリューションに収束することにより、各小さなセットの結果の平均やこの結果をプロットできます。
ビニング手順のようなものはどうですか?(説明のために)値が100万から100万の間であることを知っていると仮定します。サイズSのN個のビンを設定します。したがって、S = 10000の場合、値[1:10000、10001:20000、...、990001:1000000]に対応する100個のビンがあります。
次に、値をステップ実行します。各値を保存する代わりに、適切なビンのカウンターをインクリメントするだけです。各ビンの中間点を推定値として使用して、中央値の合理的な近似値を作成できます。ビンのサイズを変更することで、必要に応じて解像度を微調整または粗調整できます。使用できるメモリの量によってのみ制限されます。
値がどれだけ大きくなるか分からないので、簡単なエンベロープ計算を使用して、メモリ不足になりそうにない十分な大きさのビンサイズを選択してください。また、値を含むビンのみを追加するように、ビンをまばらに保存することもできます。
編集:
ryfmが提供するリンクは、これを行う例を示しており、単に中間点を使用するのではなく、累積パーセンテージを使用して中央値ビン内の点をより正確に推定する追加のステップがあります。これは素晴らしい改善です。
リベスト- Tarjan-選択アルゴリズム(時々 、中央値の中央値-アルゴリズムと呼ばれる)を使用すると、任意の並べ替えなしに線形時間で中央値の要素を計算できるようになります。大規模なデータセットの場合、これは対数線形ソートよりもかなり高速です。ただし、メモリストレージの問題は解決しません。
LiveStatsと呼ばれるきちんとしたPythonモジュールに観測値を保存せずに、分位点とヒストグラムの動的計算のためのP-Squareアルゴリズムを実装しました。問題を非常に効果的に解決するはずです。
私はこれをする必要がなかったので、これは単なる提案です。
2つの(他の)可能性があります。
ハーフデータ
標本分布
もう1つのオプションは、サンプリング分布を含む近似を使用することです。データが正常な場合、中程度のnの標準誤差は次のとおりです。
1.253 * sd / sqrt(n)
満足できるnのサイズを決定するために、Rで簡単なモンテカルロシミュレーションを実行しました。
n = 10000
outside.ci.uni = 0
outside.ci.nor = 0
N=1000
for(i in 1:N){
#Theoretical median is 0
uni = runif(n, -10, 10)
nor = rnorm(n, 0, 10)
if(abs(median(uni)) > 1.96*1.253*sd(uni)/sqrt(n))
outside.ci.uni = outside.ci.uni + 1
if(abs(median(nor)) > 1.96*1.253*sd(nor)/sqrt(n))
outside.ci.nor = outside.ci.nor + 1
}
outside.ci.uni/N
outside.ci.nor/N
n = 10000の場合、均一な中央値の推定値の15%がCIの外側にありました。
グループ化された頻度分布に基づいて中央値を見つけようとすることができます。ここにいくつかの詳細があります
ここにstackoverflowで尋ねられた質問への答えがあります:https : //stackoverflow.com/questions/1058813/on-line-iterator-algorithms-for-estimating-statistical-median-mode-skewness/2144754#2144754
反復更新の中央値+ = eta * sgn(sample-median)は、進むべき道のように思えます。
Remedianアルゴリズム(PDF)は、低いストレージ要件と明確に定義された精度で一通過メジアン推定を与えます。
基数bのレメディアンは、b個の観測値のグループの中央値を計算し、次にこれらの中央値の中央値を、単一の推定値のみが残るまで計算します。このメソッドは、サイズbのk個の配列(n = b ^ k)を必要とします...
場合の値を使用しているが、一定の範囲内にある、あなたが効率的に(BSDから撮影したこのコードは、EAのライセンスを取得した整数バケツと、値(たとえば、エントリ数兆)の非常に大きな数に中央値を計算することができ、100000に1を言います-utils / sam-stats.cpp)
class ibucket {
public:
int tot;
vector<int> dat;
ibucket(int max) {dat.resize(max+1);tot=0;}
int size() const {return tot;};
int operator[] (int n) const {
assert(n < size());
int i;
for (i=0;i<dat.size();++i) {
if (n < dat[i]) {
return i;
}
n-=dat[i];
}
}
void push(int v) {
assert(v<dat.size());
++dat[v];
++tot;
}
};
template <class vtype>
double quantile(const vtype &vec, double p) {
int l = vec.size();
if (!l) return 0;
double t = ((double)l-1)*p;
int it = (int) t;
int v=vec[it];
if (t > (double)it) {
return (v + (t-it) * (vec[it+1] - v));
} else {
return v;
}
}