r - 模拟每两个变量之间具有不同混合依赖结构的混合数据?

标签 r simulation mixture-model mixture

我想模拟一个混合数据,比如说 3 维数据。我想在每两个变量之间有 2 个不同的组件。

也就是说,模拟混合数据(V1 和 V2),其中它们之间的依赖关系是两个不同的法向分量。然后,在 V2 和 V3 之间还有两个法向分量。所以,我将有 3d 数据,第一个和第二个变量之间的依赖是两个法线的混合。而第二个和第三个变量之间的依赖是另外两个不同分量的混合。

另一种解释我的问题的方法:

假设我想按如下方式生成混合数据:

1- 0.3 normal(0.5,1) + 0.7 normal(2,4) # 因此这里我将得到由两个不同的法线(混合模型的两个分量)生成的双变量混合数据,混合器权重之和为 1。

然后,我想获得另一个变量,如下所示:

2- 0.5 normal(2,4) # 这是第一次模拟的第二个变量 + 0.5 normal(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)
    }
}

因此,如果我们生成混合双变量数据(两个变量),那么如何将其扩展为 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)

为了创建混合分布,我们可以使用 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

为了查看哪些值来自哪个分布,您可以执行以下操作:
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)

如果您希望混合使用两个以上的变量(分布),您可以扩展您提供的代码,如下所示:
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)
  }
}

这样,每个元素一次从每个分布中取出一个。如果您想获得相同的结果但不一次取一个元素,您可以执行以下操作:
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])

对应于 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])

这将在两种混合物中使用与 normal(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 

U 向量中 30% 的值低于 0.3。

关于r - 模拟每两个变量之间具有不同混合依赖结构的混合数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43693768/

相关文章:

R:从列表中的数据帧创建特定单元格的向量和某些列的平均值

r - 从数据框中删除列列表

objective-c - 在 macOS 上模拟鼠标滚轮(swift 或 objc)

c++ - 如何快速将元素重复插入到排序列表中

c - 如何用C语言编写GMM(高斯混合模型)?

python - python中的对数正态混合

python - 将高斯混合模型拟合到单个特征数据的正确方法是什么?

r - 使用逻辑向量从字符向量中排除 FALSE 元素

R:使用for循环将因子的水平部分匹配到字符串?

c++ - 这个洗牌算法有什么问题吗?