逆入力分布の重み付けを使用したサンプル
あはは!私は 2 番目の解決策を考えました。これはおそらく最初の解決策よりも優れていると思います。これは、以下の反復ターゲット分布の最も近い選択のセクションで保持しています。
このsample()
関数にはprob
、入力ベクトルの要素の確率の重みを指定できるパラメーターがあります。このパラメーターを使用して、入力分布のまばらなセグメント (つまり、テール) で発生する要素を選択する確率を増やし、より密なセグメント (つまり、中央) で発生する要素を選択する確率を減らすことができます。dnorm()
密度関数の単純な算術反転で十分だと思います。
テストデータ
set.seed(1L);
normSize <- 1e4L; normMean <- 0.5; normSD <- 0.25;
norm <- rnorm(normSize,normMean,normSD);
解決
unifSize <- 1e3L; unifMin <- 0; unifMax <- 1;
normForUnif <- norm[norm>=unifMin & norm<=unifMax];
d <- dnorm(normForUnif,normMean,normSD);
unif <- sample(normForUnif,unifSize,prob=1/d);
hist(unif);
反復ターゲット分布の最近傍選択
ターゲット (一様) 分布から一連のランダム偏差を生成します。偏差ごとに、それに最も近い入力 (正規) 分布から要素を見つけます。その要素をサンプルに選択することを検討してください。
一意の選択の数がサンプルの必要なサイズに達するか超えるまで、上記を繰り返します。必要なサイズを超えた場合は、正確に必要なサイズに切り捨てます。
を使用findInterval()
して、一様偏差ごとに最も近い正規偏差を見つけることができます。これを正しく行うには、いくつかの調停が必要です。ソートする必要があるため、正規分布ベクトルをソートするfindInterval()
必要vec
があります。そして、ターゲット分布の真の最小値であるゼロを に渡す最小値として使用する代わりにrunif()
、入力セットに存在するゼロ以上の最小値を渡す必要があります。それ以外の場合、その値を下回る一様偏差は、一様分布の許容最小値を下回る入力要素と一致します。また、効率のために、呼び出すループを実行する前にfindInterval()
、ターゲット分布の許容範囲 (つまり、[0,1]) 内にないすべての値を正規分布ベクトルから削除して、マッチング アルゴリズムに参加しないようにすることをお勧めします。とにかく一致させることができなかったので、それらは必要ありません。
ターゲット サンプル サイズが入力分布ベクトルよりも十分に小さい場合、結果のサンプルから入力分布の痕跡が除去されます。
テストデータ
set.seed(1L);
normSize <- 1e6L; normMean <- 0.5; normSD <- 0.25;
norm <- rnorm(normSize,normMean,normSD);
解決
unifSize <- 200L; unifMin <- 0; unifMax <- 1;
normVec <- sort(norm[norm>=unifMin & norm<=unifMax]);
inds <- integer();
repeat {
inds <- unique(c(inds,findInterval(runif(unifSize*2L,normVec[1L],unifMax),normVec)));
if (length(inds)>=unifSize) break;
};
length(inds) <- unifSize;
unif <- normVec[inds];
hist(unif);
1 つの注意点は、findInterval()
技術的に最も近い要素を見つけるのではなく、検索値以下の要素を見つけることです。これが結果に大きな影響を与えるとは思いません。せいぜい、より小さな値を優先して選択を無限にバイアスしますが、均一な方法です。本当に必要な場合は、存在するさまざまな find-nearest オプションを調べることができます。たとえば、R: findnearest indexを参照してください。