Озабоченность вопроса , как генерировать случайные из случайных величин многомерного нормального распределения с (возможно) единственным числом ковариационной матрицей . Этот ответ объясняет один способ, который будет работать для любой ковариационной матрицы. Это обеспечивает реализацию, которая проверяет его точность.CR
Алгебраический анализ ковариационной матрицы
Поскольку является ковариационной матрицей, она обязательно является симметричной и положительно-полуопределенной. Чтобы дополнить справочную информацию, пусть µ будет вектором желаемого среднего.Cμ
Поскольку симметричен, его разложение по сингулярному значению (SVD) и его собственное разложение автоматически будут иметь видC
C=VD2V′
для некоторой ортогональной матрицы и диагональной матрицы D 2 . В целом, диагональные элементы D 2 неотрицательны (подразумевая, что все они имеют реальные квадратные корни: выберите положительные, чтобы сформировать диагональную матрицу D ). Информация о C, которую мы имеем, говорит о том, что один или несколько из этих диагональных элементов равны нулю, но это не повлияет ни на одну из последующих операций и не помешает вычислению SVD.VD2D2DC
Генерация многомерных случайных значений
Пусть есть стандартное многомерное нормальное распределение: каждый компонент имеет нулевое среднее, единичную дисперсии, и все ковариации равны нуль: ее ковариационная матрица является тождественным я . Тогда случайная величина Y = V D X имеет ковариационную матрицуИксяY= V D X
Cov( Y) = E ( YY') = E ( V D XИкс'D'В') = V D E ( XИкс') D V'= V D I D V'= V D2В'= С .
Следовательно, случайная величина имеет многомерное нормальное распределение со средним ц и ковариационной матрицей С .μ + YμС
Расчет и пример кода
Следующий R
код генерирует ковариационную матрицу заданных измерений и ранга, анализирует ее с помощью SVD (или, в закомментированном коде, с собственным разложением), использует этот анализ для генерации заданного числа реализаций (со средним вектором 0 ) и затем сравнивает ковариационную матрицу этих данных с предполагаемой ковариационной матрицей как в числовом, так и в графическом виде. Как показано, он генерирует 10 , 000 реализаций , где размерность Y является 100 и ранг C составляет 50 . ВыходY010 , 000Y100С50
rank L2
5.000000e+01 8.846689e-05
То есть, ранг данных также и ковариационная матрица по оценкам из данных находится в пределах расстояния 8 × 10 - 5 из C --which близко. В качестве более подробной проверки, коэффициенты C построены по сравнению с его оценкой. Все они лежат близко к линии равенства:508 × 10- 5СС
Код точно соответствует предыдущему анализу и поэтому не требует пояснений (даже для не R
пользователей, которые могут эмулировать его в своей любимой прикладной среде). Одна вещь, которую он показывает, - это необходимость соблюдать осторожность при использовании алгоритмов с плавающей точкой: записи могут легко быть отрицательными (но крошечными) из-за неточности. Такие записи должны быть обнулены перед вычислением квадратного корня, чтобы найти сам D.D2D
n <- 100 # Dimension
rank <- 50
n.values <- 1e4 # Number of random vectors to generate
set.seed(17)
#
# Create an indefinite covariance matrix.
#
r <- min(rank, n)+1
X <- matrix(rnorm(r*n), r)
C <- cov(X)
#
# Analyze C preparatory to generating random values.
# `zapsmall` removes zeros that, due to floating point imprecision, might
# have been rendered as tiny negative values.
#
s <- svd(C)
V <- s$v
D <- sqrt(zapsmall(diag(s$d)))
# s <- eigen(C)
# V <- s$vectors
# D <- sqrt(zapsmall(diag(s$values)))
#
# Generate random values.
#
X <- (V %*% D) %*% matrix(rnorm(n*n.values), n)
#
# Verify their covariance has the desired rank and is close to `C`.
#
s <- svd(Sigma <- cov(t(X)))
(c(rank=sum(zapsmall(s$d) > 0), L2=sqrt(mean(Sigma - C)^2)))
plot(as.vector(C), as.vector(Sigma), col="#00000040",
xlab="Intended Covariances",
ylab="Estimated Covariances")
abline(c(0,1), col="Gray")