Bir karışım dağılımından ve özellikle Normal dağılımların bir karışımından nasıl numune alabilirim R
? Örneğin, örnek almak istersem:
bunu nasıl yapabilirim?
Bir karışım dağılımından ve özellikle Normal dağılımların bir karışımından nasıl numune alabilirim R
? Örneğin, örnek almak istersem:
bunu nasıl yapabilirim?
Yanıtlar:
Performans nedeniyle for
döngülerden kaçınmak iyi bir uygulamadır R
. Bu gerçeği kullanan alternatif bir çözüm rnorm
vektörleştirilmiştir:
N <- 100000
components <- sample(1:3,prob=c(0.3,0.5,0.2),size=N,replace=TRUE)
mus <- c(0,10,3)
sds <- sqrt(c(1,1,0.1))
samples <- rnorm(n=N,mean=mus[components],sd=sds[components])
samples <- rnorm(N)*sds[components]+mus[components]
. Okumayı daha kolay buluyorum :)
Genel olarak, bir karışım dağılımından numune almanın en kolay yollarından biri şudur:
Algoritma Adımları
1) Rastgele değişken
2) aralığı ise, burada p k karışım modelinin k t h bileşeninin olasılığına karşılık gelirse , k t h bileşeninin dağılımı
3) Karışım dağılımından istediğiniz miktarda numune alana kadar 1) ve 2) adımlarını tekrarlayın.
Şimdi yukarıda verilen genel algoritmayı kullanarak, aşağıdaki normal R
kodu kullanarak örnek normal karışımınızdan örnek alabilirsiniz :
#The number of samples from the mixture distribution
N = 100000
#Sample N random uniforms U
U =runif(N)
#Variable to store the samples from the mixture distribution
rand.samples = rep(NA,N)
#Sampling from the mixture
for(i in 1:N){
if(U[i]<.3){
rand.samples[i] = rnorm(1,0,1)
}else if(U[i]<.8){
rand.samples[i] = rnorm(1,10,1)
}else{
rand.samples[i] = rnorm(1,3,.1)
}
}
#Density plot of the random samples
plot(density(rand.samples),main="Density Estimate of the Mixture Model")
#Plotting the true density as a sanity check
x = seq(-20,20,.1)
truth = .3*dnorm(x,0,1) + .5*dnorm(x,10,1) + .2*dnorm(x,3,.1)
plot(density(rand.samples),main="Density Estimate of the Mixture Model",ylim=c(0,.2),lwd=2)
lines(x,truth,col="red",lwd=2)
legend("topleft",c("True Density","Estimated Density"),col=c("red","black"),lwd=2)
Hangi üretir:
ve akıl sağlığı kontrolü olarak:
R
set.seed(8) # this makes the example reproducible
N = 1000 # this is how many data you want
probs = c(.3,.8) # these are *cumulative* probabilities; since they
# necessarily sum to 1, the last would be redundant
dists = runif(N) # here I'm generating random variates from a uniform
# to select the relevant distribution
# this is where the actual data are generated, it's just some if->then
# statements, followed by the normal distributions you were interested in
data = vector(length=N)
for(i in 1:N){
if(dists[i]<probs[1]){
data[i] = rnorm(1, mean=0, sd=1)
} else if(dists[i]<probs[2]){
data[i] = rnorm(1, mean=10, sd=1)
} else {
data[i] = rnorm(1, mean=3, sd=.1)
}
}
# here are a couple of ways of looking at the results
summary(data)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# -3.2820 0.8443 3.1910 5.5350 10.0700 13.1600
plot(density(data))
ifelse()
, ama daha sonra çözmem gerekecek. Bu kodu bir döngü olmadan değiştirdim.
R
findInterval()
cumsum()
mu
s
p
mix <- function(n,mu,s,p) { ii <- findInterval(runif(n),cumsum(p))+1; x <- rnorm(n,mean=mu[ii],sd=sqrt(s[ii])); return(x); }
findInterval()
Komutu daha önce görmedim , ancak burada olabildiğince basit bir şekilde kod yazmayı seviyorum çünkü verimlilikten ziyade bir anlama aracı olmasını istiyorum.
Zaten mükemmel cevaplar verildi, bu yüzden Python'da bunu başarmak isteyenler için işte benim çözümüm:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
mu = [0, 10, 3]
sigma = [1, 1, 1]
p_i = [0.3, 0.5, 0.2]
n = 10000
x = []
for i in range(n):
z_i = np.argmax(np.random.multinomial(1, p_i))
x_i = np.random.normal(mu[z_i], sigma[z_i])
x.append(x_i)
def univariate_normal(x, mean, variance):
"""pdf of the univariate normal distribution."""
return ((1. / np.sqrt(2 * np.pi * variance)) *
np.exp(-(x - mean)**2 / (2 * variance)))
a = np.arange(-7, 18, 0.01)
y = p_i[0] * univariate_normal(a, mean=mu[0], variance=sigma[0]**2) + p_i[1] * univariate_normal(a, mean=mu[1], variance=sigma[0]**2)+ p_i[2] * univariate_normal(a, mean=mu[2], variance=sigma[0]**2)
fig, ax = plt.subplots(figsize=(8, 4))
ax.hist(x, bins=100, density=True)
ax.plot(a, y)