7 simulation r mixture-model mixture
我想模拟混合数据,比如三维数据.我想在每两个变量之间有两个不同的组件.
也就是说,模拟混合数据(V1和V2),其中它们之间的依赖关系是两个不同的正常分量.然后,在V2和V3之间另外两个正常组件.所以,我将得到3d数据,第一个和第二个变量之间的依赖关系是两个法线的混合.并且第二和第三变量之间的依赖性是另外两个不同组分的混合.
另一种解释我问题的方法:
假设我想生成如下混合数据:
1- 0.3正常(0.5,1)+ 0.7正常(2,4)#因此在这里我将获得由两个不同法线(混合模型的两个分量)生成的双变量混合数据,混合器重量的总和为1.
然后,我想得到另一个变量如下:
2- 0.5 normal(2,4)#这是第一个模拟的第二个变量+ 0.5法线(2,6)
所以在这里,我得到了3d模拟混合数据,其中V1和V2由两个不同的混合成分生成,V2和V3由另一个不同的混合成分生成.
这是如何在r中生成数据:(我相信它不会生成双变量数据)
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,1,3)
} else {
rand.samples[i] <- rnorm(1,2,5)
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我们生成混合双变量数据(两个变量),那么如何将其扩展为具有4个或5个变量,其中V1和V2由两个不同的法线生成(它们之间的依赖关系结构是两个法线的混合)然后V3将从另一个不同的法线生成,然后用V2进行复习.也就是说,当我们绘制V2~V3时,我们会发现它们之间的依赖关系结构是两个法线的混合,依此类推.
我不太确定我是否正确理解了这个问题,但我会尝试一下。您有 3 个发行版 D1、D2 和 D3。从这三个分布中,您希望创建使用这 3 个中的 2 个但不相同的变量。
因为我不知道应该如何组合分布,所以我使用二项式分布的标志(其长度等于 200 且有 0 和 1 的向量)来确定从哪个分布中选取每个值(如果是这样,您可以更改它)不是你想要的方式)。
D1 = rnorm(200,2,1)
D2 = rnorm(200,3,1)
D3= rnorm(200,1.5,2)
Run Code Online (Sandbox Code Playgroud)
为了创建混合分布,我们可以使用 rbinom 函数根据选定的概率创建 1 和 0 的向量。这是一种从两个分布中获取一些值的方法。
var_1_flag <- rbinom(200, size=1, prob = 0.3)
var_1 <- var_1_flag*D1 + (1 - var_1_flag)*D2
var_2_flag <- rbinom(200, size=1, prob = 0.7)
var_2 <- var_2_flag*D2 + (1 - var_2_flag)*D3
var_3_flag <- rbinom(200, size=1, prob = 0.6)
var_3 <- var_3_flag*D1 + (1 - var_3_flag)*D3
Run Code Online (Sandbox Code Playgroud)
为了查看哪些值来自哪个分布,您可以执行以下操作:
var_1[var_1_flag]#这为您提供了来自第一个分布 (D1) 的混合分布中的值
var1[!var_1_flag]#这为您提供了来自第二个分布 (D2) 的混合分布中的值
因为我发现这有点手动,并且我猜您可能想要更改变量,所以您可能想要使用下面的函数来获得相同的结果
create_distr <- function(observations, mean1, sd1, mean2, sd2, flag_prob) {
flag <- rbinom(observations, size=1, prob = flag_prob)
my_distribution <- flag * rnorm(observations, mean1, sd1) + (1 - flag) * rnorm(observations, mean2, sd2)
}
var_1 <- create_distr(200, 2, 1, 3, 1, 0.5)
var_2 <- create_distr(200, 3, 1, 1.5, 2, 0.7)
var_3 <- create_distr(200, 2, 1, 1.5, 2, 0.6)
Run Code Online (Sandbox Code Playgroud)
如果您想要混合两个以上的变量(分布),您可以扩展您提供的代码,如下所示:
N <- 100000
#Sample N random uniforms U
U <- runif(N)
#Variable to store the samples from the mixture distribution
rand.samples <- rep(NA,N)
for(i in 1:N) {
if(U[i] < 0.3) {
rand.samples[i] <- rnorm(1,1,3)
} else if (U[i] < 0.5){
rand.samples[i] <- rnorm(1,2,5)
} else if (U[i] < 0.8) {
rand.samples[i] <- rnorm(1,5,2)
} else {
rand.samples[i] <- rt(1, 2)
}
}
Run Code Online (Sandbox Code Playgroud)
这样,每个元素一次从每个分布中取出一个。如果您想获得相同的结果,但不想一次获取每个元素,您可以执行以下操作:
N <- 100000
#Sample N random uniforms U
U <- runif(N)
#Variable to store the samples from the mixture distribution
rand.samples <- rep(NA,N)
D1 = rnorm(N,1,3)
D2 = rnorm(N,2,5)
D3= rnorm(N,5,2)
D4 = rt(N, 2)
rand.samples <- c(D1[U < 0.3], D2[U >= 0.3 & U < 0.5], D3[U >= 0.5 & U < 0.8], D4[U >= 0.8])
Run Code Online (Sandbox Code Playgroud)
对应于 0.3*normal(1,3) + 0.2*normal(2,5) + 0.3*normal(5,2) + 0.2*student(2 个自由度)
如果您想创建两个混合物,但在第二个混合物中保持正态分布中的相同值,您可以执行以下操作:
mixture_1 <- c(D1[U < 0.3], D2[U >= 0.3 ])
mixture_2 <- c(D1[U < 0.3], D3[U >= 0.3])
Run Code Online (Sandbox Code Playgroud)
这将在两种混合物中使用与法线 (1,3) 完全相同的元素。诀窍是不要在每次使用 rnorm(N,1,3) 时重新计算它。在这两种情况下,样本均由 30% 大致来自第一正态分布 (D1) 和 70% 大致来自第二分布组成。例如:
set.seed(1)
N <- 100000
U <- runif(N)
> prop.table(table(U < 0.3))
FALSE TRUE
0.6985 0.3015
Run Code Online (Sandbox Code Playgroud)
U 向量中 30% 的值低于 0.3。