我正在尝试创建(在r中)等效于以下MATLAB函数,该函数将从N(m1,(s1)^ 2)和N(m2,(s2)^ 2)的混合生成n个样本来自第一高斯的分数α,
我有一个开始,但结果在MATLAB和R之间有显着差异(即,MATLAB结果偶尔会给出+ -8的值,但R版本甚至不会给出+ -5的值)。 请帮我解决这里的错误。谢谢: - )
例如: 绘制来自N(0,1)和N(0,36)的混合的1000个样本和来自第一高斯的95%的样本。将样本标准化为零和标准差1。
MATLAB
功能
function y = gaussmix(n,m1,m2,s1,s2,alpha)
y = zeros(n,1);
U = rand(n,1);
I = (U < alpha)
y = I.*(randn(n,1)*s1+m1) + (1-I).*(randn(n,1)*s2 + m2);
实施
P = gaussmix(1000,0,0,1,6,.95)
P = (P-mean(P))/std(P)
plot(P)
axis([0 1000 -15 15])
hist(P)
axis([-15 15 0 1000])
结果情节
结果
- [R
yn <- rbinom(1000, 1, .95)
s <- rnorm(1000, 0 + 0*yn, 1 + 36*yn)
sn <- (s-mean(s))/sd(s)
plot(sn, xlim=range(0,1000), ylim=range(-15,15))
hist(sn, xlim=range(-15,15), ylim=range(0,1000))
结果情节
结果
一如既往,谢谢!
解
gaussmix <- function(nsim,mean_1,mean_2,std_1,std_2,alpha){
U <- runif(nsim)
I <- as.numeric(U<alpha)
y <- I*rnorm(nsim,mean=mean_1,sd=std_1)+
(1-I)*rnorm(nsim,mean=mean_2,sd=std_2)
return(y)
}
z1 <- gaussmix(1000,0,0,1,6,0.95)
z1_standardized <- (z1-mean(z1))/sqrt(var(z1))
z2 <- gaussmix(1000,0,3,1,1,0.80)
z2_standardized <- (z2-mean(z2))/sqrt(var(z2))
z3 <- rlnorm(1000)
z3_standardized <- (z3-mean(z3))/sqrt(var(z3))
par(mfrow=c(2,3))
hist(z1_standardized,xlim=c(-10,10),ylim=c(0,500),
main="Histogram of 95% of N(0,1) and 5% of N(0,36)",
col="blue",xlab=" ")
hist(z2_standardized,xlim=c(-10,10),ylim=c(0,500),
main="Histogram of 80% of N(0,1) and 10% of N(3,1)",
col="blue",xlab=" ")
hist(z3_standardized,xlim=c(-10,10),ylim=c(0,500),
main="Histogram of samples of LN(0,1)",col="blue",xlab=" ")
##
plot(z1_standardized,type='l',
main="1000 samples from a mixture N(0,1) and N(0,36)",
col="blue",xlab="Samples",ylab="Mean",ylim=c(-10,10))
plot(z2_standardized,type='l',
main="1000 samples from a mixture N(0,1) and N(3,1)",
col="blue",xlab="Samples",ylab="Mean",ylim=c(-10,10))
plot(z3_standardized,type='l',
main="1000 samples from LN(0,1)",
col="blue",xlab="Samples",ylab="Mean",ylim=c(-10,10))
答案 0 :(得分:6)
我认为有两个问题......(1)你的R代码正在创建正态分布的混合,标准差为1和37 。 (2)通过在prob
调用中将rbinom()
设置为等于alpha,您将在 second 模式而不是第一个模式中获得分数alpha。所以你得到的是一个分布,主要是高斯与sd 37,被高斯与sd 1的5%混合物污染,而不是高斯与sd 1被高斯与sd 6的5%混合物污染通过混合物的标准偏差(大约36.6)进行缩放基本上将其缩小为标准高斯,并且在原点附近有轻微的凹凸...
(这里发布的其他答案可以很好地解决您的问题,但我认为您可能对诊断感兴趣......)
Matlab gaussmix
函数的更紧凑(可能更惯用)版本(我认为runif(n)<alpha
比rbinom(n,size=1,prob=alpha)
稍微高效一点)
gaussmix <- function(n,m1,m2,s1,s2,alpha) {
I <- runif(n)<alpha
rnorm(n,mean=ifelse(I,m1,m2),sd=ifelse(I,s1,s2))
}
set.seed(1001)
s <- gaussmix(1000,0,0,1,6,0.95)
答案 1 :(得分:2)
并非您要求它,但mclust
包提供了一种将问题概括为更多维度和不同协方差结构的方法。见?mclust::sim
。示例任务将以这种方式完成:
require(mclust)
simdata = sim(modelName = "V",
parameters = list(pro = c(0.95, 0.05),
mean = c(0, 0),
variance = list(modelName = "V",
d = 1,
G = 2,
sigmasq = c(0, 36))),
n = 1000)
plot(scale(simdata[,2]), type = "h")
答案 2 :(得分:1)
我最近编写了正态分布的多项式混合的密度和采样函数:
dmultiNorm <- function(x,means,sds,weights)
{
if (length(means)!=length(sds)) stop("Length of means must be equal to length of standard deviations")
N <- length(x)
n <- length(means)
if (missing(weights))
{
weights <- rep(1,n)
}
if (length(weights)!=n) stop ("Length of weights not equal to length of means and sds")
weights <- weights/sum(weights)
dens <- numeric(N)
for (i in 1:n)
{
dens <- dens + weights[i] * dnorm(x,means[i],sds[i])
}
return(dens)
}
rmultiNorm <- function(N,means,sds,weights,scale=TRUE)
{
if (length(means)!=length(sds)) stop("Length of means must be equal to length of standard deviations")
n <- length(means)
if (missing(weights))
{
weights <- rep(1,n)
}
if (length(weights)!=n) stop ("Length of weights not equal to length of means and sds")
Res <- numeric(N)
for (i in 1:N)
{
s <- sample(1:n,1,prob=weights)
Res[i] <- rnorm(1,means[s],sds[s])
}
return(Res)
}
means
是平均值的向量,sds
是标准偏差的向量,weights
是具有比例概率的向量,可以从每个分布中进行采样。这对你有用吗?
答案 3 :(得分:1)
以下是执行此任务的代码:
“例如:绘制来自N(0,1)和N(0,36)混合的1000个样本和来自第一高斯的95%样本。将样本归一化为零和标准差1。”< / p>
plot(multG <- c( rnorm(950), rnorm(50, 0, 36))[sample(1000)] , type="h")
scmulG <- scale(multG)
summary(scmulG)
#-----------
V1
Min. :-9.01845
1st Qu.:-0.06544
Median : 0.03841
Mean : 0.00000
3rd Qu.: 0.13940
Max. :12.33107