間隔内の正規分布に従って乱数を生成する必要があります。(私はRで働いています。)
関数rnorm(n,mean,sd)
は正規分布に従って乱数を生成しますが、その範囲内で間隔制限を設定するにはどうすればよいですか?そのために使用可能な特定のR関数はありますか?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
間隔内の正規分布に従って乱数を生成する必要があります。(私はRで働いています。)
関数rnorm(n,mean,sd)
は正規分布に従って乱数を生成しますが、その範囲内で間隔制限を設定するにはどうすればよいですか?そのために使用可能な特定のR関数はありますか?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
回答:
切り捨てられた分布、および特定の例では切り捨てられた正規分布からシミュレートしたいようです。
そのためにはさまざまな方法がありますが、簡単な方法と比較的効率的な方法があります。
通常の例でいくつかのアプローチを説明します。
一度に1つずつ(ある種の擬似コードで)生成するための非常に簡単な方法を1つ示します。
N(mean、sd)からを生成 lower upper
分布の大部分が境界内にある場合、これはかなり合理的ですが、ほぼ常に制限の範囲外で生成すると、かなり遅くなる可能性があります。
Rでは、境界内の面積を計算し、境界外の値を捨てた後も必要な数の値が残っていることをほぼ確実に確認できる十分な値を生成することで、一度に1つのループを回避できます。
間隔にわたって、適切なメジャー化関数を使用してaccept-rejectを使用できます(場合によっては、均一で十分です)。sdに比べて制限が適度に狭いが、テールにそれほど遠くない場合は、たとえば、通常のメジャーリングで問題なく動作します。
あなたは合理的、効率的な累積分布関数と(のような逆CDFがある場合pnorm
及びqnorm
Rで正規分布のために)あなたがのシミュレートセクションの最初の段落で説明した逆CDF法を使用することができます切り捨て、通常のWikipediaのページを。[実際には、これは切り捨てられたユニフォーム(必要な分位で切り捨てられ、実際にはまったく別のユニフォームであるため、まったく拒否を必要としない)を取り、それに逆正規cdfを適用するのと同じです。あなたが尾にいる場合、これは失敗する可能性があることに注意してください]
他のアプローチがあります。同じウィキペディアのページには、さまざまなディストリビューションで機能するはずのzigguratメソッドの適応が記載されています。
同じWikipediaのリンクは切り捨て法線を生成するための機能を備えた2つの特定のパッケージ(CRANの両方)を言及します:
MSM
R のパッケージにはrtnorm
、切り捨てられた法線から描画を計算する関数があります。truncnorm
R のパッケージには、切り捨てられた法線から描画する関数もあります。
周りを見ると、これの多くは他の質問の回答でカバーされています(ただし、この質問は切り捨てられた法線よりも一般的であるため、正確には重複していません)...
a。この答え
b。ここでの西安の答えは、彼のarXiv論文へのリンクを持っています(他の価値のある応答と一緒に)。
手っ取り早い方法は、68-95-99.7ルールを使用することです。
正規分布では、値の99.7%が平均の3標準偏差内に収まります。そのため、平均を目的の最小値と最大値の中間に設定し、標準偏差を平均の1/3に設定すると、目的の間隔内に収まる(ほとんどの)値が得られます。その後、残りをクリーンアップできます。
minVal <- 0
maxVal <- 100
mn <- (maxVal - minVal)/2
# Generate numbers (mostly) from min to max
x <- rnorm(count, mean = mn, sd = mn/3)
# Do something about the out-of-bounds generated values
x <- pmax(minVal, x)
x <- pmin(maxVal, x)
私は最近、この同じ問題に直面し、テストデータのランダムな学生の成績を生成しようとしました。上記のコードでは、私が使ってきたpmax
し、pmin
minまたはmaxで、境界値との範囲外の値を交換します。私はかなり少量のデータを生成しているので、これは私の目的のために機能しますが、より大きな量では、最小値と最大値で顕著なバンプが得られます。そのため、目的に応じて、これらの値を破棄するNA
か、sに置き換えるか、インバウンドになるまで「再ロール」する方が良い場合があります。
sample(x=min:max, prob=dnorm(...))
が多分それをするより簡単な方法であることに気づきました。
sample(x=min:max, prob=dnorm(...))
、あなたの答えよりも少し短いと述べています。
sample()
手法は、ランダムな整数、または他の離散的な事前定義された値のセットを選択する場合にのみ有用であることに注意してください。
ここでの答えはどれも、任意の数の生成された値の拒否を伴わない切り捨てられた正規変数を生成する効率的な方法を提供しません。下限および上限を指定して、切り捨てられた正規分布から値を生成する場合は、切り捨てで許可された分位範囲で均一な分位を生成し、逆を使用することで、拒否なしでこれを実行できます対応する正常値を取得するための変換サンプリング。
してみましょう標準正規分布のCDFを示します。切り捨てられた正規分布(平均パラメーターおよび分散パラメーター)からを生成し下限と上限がです。これは次のように実行できます。
切り捨てられた分布から生成された値に対する組み込み関数はありませんが、ランダム変数を生成するための通常の関数を使用してこのメソッドをプログラムすることは簡単です。数行のコードでこのメソッドを実装する簡単なR
関数rtruncnorm
を次に示します。
rtruncnorm <- function(N, mean = 0, sd = 1, a = -Inf, b = Inf) {
if (a > b) stop('Error: Truncation range is empty');
U <- runif(N, pnorm(a, mean, sd), pnorm(b, mean, sd));
qnorm(U, mean, sd); }
これはN
、切り捨てられた正規分布からIIDランダム変数を生成するベクトル化された関数です。同じ方法で、他の切り捨てられた分布の関数を簡単にプログラムできます。また、切り捨てられた分布に関連する密度および分位関数をプログラムすることもそれほど難しくありません。
切り捨ては分布の平均と分散を変更するため、とは切り捨てられた分布の平均と分散ではないことに注意してください。