有效地将高斯噪声添加到矩阵行的每个元素

Adding Gaussian noise to each element of rows of a matrix efficiently

我有一个矩阵m:

set.seed(1)
m = matrix(rnorm(100), nrow = 10, ncol = 10) # my data is not a random matrix in reality, but it should not matter

我想向矩阵的每一行添加 5% Gaussian 噪声。矩阵一行的每个元素都应该得到不同的随机噪声。应根据每行的 sd 按行计算随机值。

到目前为止,我已经用 for loop 实现了它,它似乎完成了工作:

for (i in 1:nrow(m)){
        m[i, ] = m[i, ] + rnorm(n = ncol(m), mean = 0, sd = sd(m[i, ]) * 0.05)
}

但是,我的真实数据非常大,我想尽可能向量化这个实现。

这个灵魂可以解决问题:

require(tidyverse)

set.seed(1)
m = matrix(rnorm(9), nrow = 3, ncol = 3)

> m
           [,1]       [,2]      [,3]
[1,] -0.6264538  1.5952808 0.4874291
[2,]  0.1836433  0.3295078 0.7383247
[3,] -0.8356286 -0.8204684 0.5757814

按行计算sd

m_sd <- apply(m, 1, sd)

按行计算噪声并将其放入矩阵

m_noise <- map(m_sd, rnorm, n = nrow(m), mean = 0) %>% 
  unlist %>% 
  matrix(nrow = 3, ncol = 3, byrow = TRUE)

添加原始矩阵和噪声矩阵

m + m_noise * 0.05

> m + m_noise * 0.05
           [,1]       [,2]      [,3]
[1,] -0.6434161  1.6792503 0.5090823
[2,]  0.1747117  0.2976669 0.7544979
[3,] -0.8374496 -0.8211245 0.6140321

一种方法是这样的...

#calculate the sd for each row...
sds <- apply(m, 1, sd)

#generate all noise factors at once and just add to m...
m <- m + rnorm(nrow(m) * ncol(m), mean = 0, sd = sds * 0.05)

这是可行的,因为 sds 将为每一列回收。一般来说,这些矩阵运算在 R 中非常快。