Stichprobe aus einer Normalverteilung, aber ignorieren Sie alle Zufallswerte, die außerhalb des angegebenen Bereichs liegen, bevor Sie mit der Simulation beginnen.
Diese Methode ist richtig, aber, wie von @ Xi'an in seiner Antwort erwähnt, würde es lange dauern, wenn der Bereich klein ist (genauer gesagt, wenn sein Maß unter der Normalverteilung klein ist).
Wie bei jeder anderen Verteilung könnte man die Inversionsmethode verwenden F- 1( U)(auch inverse Transformationsabtastung genannt ), wobeiF ist die (kumulative Funktion der) Zinsverteilung und U∼ Unif ( 0 , 1 ). WannF ist die Verteilung, die durch Abschneiden einer Verteilung erhalten wird G in einem gewissen Intervall ( a , b )Dies ist äquivalent zu sample G- 1( U) mit U∼ Unif ( G ( a ) , G ( b ) ).
Und dies wird bereits von @ Xi'an in einem Kommentar erwähnt. In manchen Situationen erfordert die Inversionsmethode eine sehr genaue Bewertung der QuantilfunktionG- 1, and I would add it also requires a fast computation of G−1. When G is a normal distribution, the evaluation of G−1 is rather slow, and it is not highly precise for values of a and b outside the "range" of G.
Simulate a truncated distribution using importance sampling
A possibility is to use importance sampling. Consider the case of the standard Gaussian distribution N(0,1). Forget the previous notations, now let G be the Cauchy distribution. The two above mentionned requirements are fulfilled for G : one simply has G(q)=arctan(q)π+12 and G−1(q)=tan(π(q−12)). Therefore, the truncated Cauchy distribution is easy to sample by the inversion method and it is a good choice of the instrumental variable for importance sampling of the truncated normal distribution.
After a bit of simplifications, sampling U∼Unif(G(a),G(b)) and taking G−1(U) is equivalent to take tan(U′) with U′∼Unif(arctan(a),arctan(b)):
a <- 1
b <- 5
nsims <- 10^5
sims <- tan(runif(nsims, atan(a), atan(b)))
Now one has to calculate the weight for each sampled value xi, defined as the ratio ϕ(x)/g(x) of the two densities up to normalization, hence we can take
w(x)=exp(−x2/ 2)(1+ x2) ,
aber es könnte sicherer sein, die log-gewichte zu nehmen:
log_w <- -sims^2/2 + log1p(sims^2)
w <- exp(log_w) # unnormalized weights
w <- w/sum(w)
Die gewichtete Probe ( xich, w ( xich) ) Ermöglicht die Schätzung des Maßes für jedes Intervall [ u , v ] unter der Zielverteilung durch Summieren der Gewichte jedes in das Intervall fallenden Stichprobenwertes:
u <- 2; v<- 4
sum(w[sims>u & sims<v])
## [1] 0.1418
Dies liefert eine Schätzung der kumulativen Zielfunktion. Wir können es mit dem spatsat
Paket schnell bekommen und plotten :
F <- spatstat::ewcdf(sims,w)
# estimated F:
curve(F(x), from=a-0.1, to=b+0.1)
# true F:
curve((pnorm(x)-pnorm(a))/(pnorm(b)-pnorm(a)), add=TRUE, col="red")
# approximate probability of u<x<v:
F(v)-F(u)
## [1] 0.1418
Natürlich die Probe ( xich)ist definitiv keine Stichprobe der Zielverteilung, sondern der instrumentellen Cauchy-Verteilung, und man erhält eine Stichprobe der Zielverteilung , indem man ein gewichtetes Resampling durchführt , beispielsweise unter Verwendung der multinomialen Stichprobe:
msample <- rmultinom(1, nsims, w)[,1]
resims <- rep(sims, times=msample)
hist(resims)
mean(resims>u & resims<v)
## [1] 0.1446
Eine andere Methode: Schnelle inverse Transformationsabtastung
Olver und Townsend entwickelten eine Stichprobenmethode für eine breite Klasse kontinuierlicher Verteilungen. Es ist in der chebfun2-Bibliothek für Matlab sowie in der ApproxFun-Bibliothek für Julia implementiert . Ich habe diese Bibliothek kürzlich entdeckt und sie klingt sehr vielversprechend (nicht nur für Zufallsstichproben). Grundsätzlich ist dies die Inversionsmethode, jedoch unter Verwendung leistungsfähiger Approximationen von cdf und inversem cdf. Die Eingabe ist die Solldichtefunktion bis zur Normalisierung.
Das Beispiel wird einfach mit folgendem Code generiert:
using ApproxFun
f = Fun(x -> exp(-x.^2./2), [1,5]);
nsims = 10^5;
x = sample(f,nsims);
Wie unten geprüft, ergibt sich ein geschätztes Maß für das Intervall [ 2 , 4 ] in der Nähe der zuvor durch Stichprobenerhebung gewonnenen Bedeutung:
sum((x.>2) & (x.<4))/nsims
## 0.14191