間隔内の分布に従って乱数を生成する


17

間隔内の正規分布に従って乱数を生成する必要があります。(私はRで働いています。)(a,b)

関数rnorm(n,mean,sd)は正規分布に従って乱数を生成しますが、その範囲内で間隔制限を設定するにはどうすればよいですか?そのために使用可能な特定のR関数はありますか?


なぜこれをしたいのですか?境界が設定されている場合、実際には正常ではありません。何を達成しようとしていますか?
グン-モニカの復職

x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
ヒュー14

3
@Hughそれは素晴らしいです...あなたが得るランダムな値の数を気にしない限り。
-Glen_b-モニカーの復活2014

回答:


31

切り捨てられた分布、および特定の例では切り捨てられた正規分布からシミュレートしたいようです。

そのためにはさまざまな方法がありますが、簡単な方法と比較的効率的な方法があります。

通常の例でいくつかのアプローチを説明します。

  1. 一度に1つずつ(ある種の擬似コードで)生成するための非常に簡単な方法を1つ示します。

    repeat N(mean、sd)からを生成 lower upperxiuntilxi

    ここに画像の説明を入力してください

    分布の大部分が境界内にある場合、これはかなり合理的ですが、ほぼ常に制限の範囲外で生成すると、かなり遅くなる可能性があります。

    Rでは、境界内の面積を計算し、境界外の値を捨てた後も必要な数の値が残っていることをほぼ確実に確認できる十分な値を生成することで、一度に1つのループを回避できます。

  2. 間隔にわたって、適切なメジャー化関数を使用してaccept-rejectを使用できます(場合によっては、均一で十分です)。sdに比べて制限が適度に狭いが、テールにそれほど遠くない場合は、たとえば、通常のメジャーリングで問題なく動作します。

    ここに画像の説明を入力してください

  3. あなたは合理的、効率的な累積分布関数と(のような逆CDFがある場合pnorm及びqnormRで正規分布のために)あなたがのシミュレートセクションの最初の段落で説明した逆CDF法を使用することができます切り捨て、通常のWikipediaのページを。[実際には、これは切り捨てられたユニフォーム(必要な分位で切り捨てられ、実際にはまったく別のユニフォームであるため、まったく拒否を必要としない)を取り、それに逆正規cdfを適用するのと同じです。あなたが尾にいる場合、これは失敗する可能性があることに注意してください]

    ここに画像の説明を入力してください

  4. 他のアプローチがあります。同じウィキペディアのページには、さまざまなディストリビューションで機能するはずのzigguratメソッドの適応が記載されています。

同じWikipediaのリンクは切り捨て法線を生成するための機能を備えた2つの特定のパッケージ(CRANの両方)を言及します:

MSMR のパッケージにはrtnorm、切り捨てられた法線から描画を計算する関数があります。truncnormR のパッケージには、切り捨てられた法線から描画する関数もあります。


周りを見ると、これの多くは他の質問の回答でカバーされています(ただし、この質問は切り捨てられた法線よりも一般的であるため、正確には重複していません)...

a。この答え

b。ここでの西安の答えは、彼のarXiv論文へのリンクを持っています(他の価値のある応答と一緒に)。


2

手っ取り早い方法は、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し、pminminまたはmaxで、境界値との範囲外の値を交換します。私はかなり少量のデータを生成しているので、これは私の目的のために機能しますが、より大きな量では、最小値と最大値で顕著なバンプが得られます。そのため、目的に応じて、これらの値を破棄するNAか、sに置き換えるか、インバウンドになるまで「再ロール」する方が良い場合があります。


なぜこれをやるのですか?通常の乱数を生成し、切り捨てが必要なものを削除するのは非常に簡単なので、必要な切り捨てが密度の面積の100%に近い場合を除き、複雑にする必要はありません。
カール

2
おそらく、元の質問を間違って解釈しているのでしょう。Rで直接統計に関連しないプログラミングタスクを達成する方法を見つけようとしたときにこの質問に出会いましたが、このページはプログラミングスタック交換ではなく、統計スタック交換であることに気づきました。:)私の場合、特定の量のランダムな整数を生成し、値の範囲は0〜100であり、生成された値はその範囲全体で素晴らしいベル曲線に収まるようにしました。これを書いて以来、私はそれsample(x=min:max, prob=dnorm(...))が多分それをするより簡単な方法であることに気づきました。
アーロンウェルズ

@Glen_bアーロンウェルズはsample(x=min:max, prob=dnorm(...))、あなたの答えよりも少し短いと述べています。
カール

ただし、このsample()手法は、ランダムな整数、または他の離散的な事前定義された値のセットを選択する場合にのみ有用であることに注意してください。
アーロンウェルズ

1

ここでの答えはどれも、任意の数の生成された値の拒否を伴わない切り捨てられた正規変数を生成する効率的な方法を提供しません。下限および上限を指定して、切り捨てられた正規分布から値を生成する場合は、切り捨てで許可された分位範囲で均一な分位を生成し、を使用することで、拒否なしでこれを実行できます対応する正常値を取得するための変換サンプリングa<b

してみましょう標準正規分布のCDFを示します。切り捨てられた正規分布(平均パラメーターおよび分散パラメーター)からを生成し下限と上限がです。これは次のように実行できます。ΦX1,...,XNμσ2a<b

Xi=μ+σΦ1(Ui)U1,...,UNIID U[Φ(aμσ),Φ(bμσ)].

切り捨てられた分布から生成された値に対する組み込み関数はありませんが、ランダム変数を生成するための通常の関数を使用してこのメ​​ソッドをプログラムすることは簡単です。数行のコードでこのメソッドを実装する簡単な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ランダム変数を生成するベクトル化された関数です。同じ方法で、他の切り捨てられた分布の関数を簡単にプログラムできます。また、切り捨てられた分布に関連する密度および分位関数をプログラムすることもそれほど難しくありません。


切り捨ては分布の平均と分散を変更するため、とは切り捨てられた分布の平均と分散ではないことに注意してください。μσ2

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.