Створення нормально розподілених випадкових чисел з матрицею коваріації, яка не є позитивно визначеною


15

Я оцінив зразок ковариационной матриці С зразка і отримати симетричну матрицю. З С , я хотів би створити н -мірного нормальний розподілений гп , але тому мені потрібно розкладання Холецкого С . Що робити, якщо С не є позитивним?


1
Яка різниця у цьому питанні stackoverflow.com/questions/17295627/… ?
dickoa

1
Матриці з позитивними напівдефінітами мають кілька квадратних коренів (див. Пояснення, наприклад, наприкінці stats.stackexchange.com/a/71303/919 ). Вам не обов'язково потрібен той, що утворюється при розкладанні Чолеського. У цьому полягає суть проблеми: знайти метод обчислення квадратних коренів, який працює навіть тоді, коли матриця є сингулярною. @amoeba Назва говорить про те, що ваше тлумачення є правильним.
whuber

Відповіді:


8

Заклопотаність питання , як генерувати випадкові з випадкових величин багатовимірного нормального розподілу з (можливо) єдиним числом ковариационной матрицею . Ця відповідь пояснює один із способів роботи будь-якої матриці коваріації. Він забезпечує реалізацію, яка перевіряє його точність.СR


Алгебраїчний аналіз коваріаційної матриці

Оскільки - матриця коваріації, вона обов'язково є симетричною і позитивно-напівдефінітною. Щоб завершити довідкову інформацію, нехай μ буде вектор бажаних коштів.Смк

Оскільки є симетричним, його сингулярне розкладання величини (SVD) та його eigendecomposition автоматично матимуть виглядС

С=VD2V'

для деякої ортогональної матриці та діагональної матриці D 2 . Загалом діагональні елементи D 2VD2D2 невід'ємні (мається на увазі, що всі вони мають реальні квадратні корені: виберіть позитивні для формування діагональної матриці ). Інформація, яку ми маємо про СDС говорить те, що один або декілька з цих діагональних елементів дорівнюють нулю, але це не вплине на жодну з наступних операцій, а також не завадить обчислити SVD.

Генерація багатоваріантних випадкових значень

Нехай є стандартне багатовимірне нормальний розподіл: кожен компонент має нульове середнє, одиничну дисперсії, і все ковариации рівні нуль: її ковариационная матриця є тотожним я . Тоді випадкова величинаХЯ має матрицю коваріаціїY=VDХ

Cov(Y)=E(YY)=E(VDXXDV)=VDE(XX')DV'=VDЯDV'=VD2V'=С.

Отже, випадкова величина має багатовимірне нормальний розподіл із середнім ц і ковариационной матрицею С .мк+YмкС

Обчислення та приклад коду

Наступний Rкод формує коваріаційну матрицю заданих розмірів і рангів, аналізує її за допомогою SVD (або, у коментованому коді, з ейгендекомпозицією), використовує цей аналіз для отримання заданої кількості реалізацій (із середнім вектором 0 ) , а потім порівнює матрицю коваріації цих даних з передбачуваною матрицею коваріації як чисельно, так і графічно. Як показано, він генерує 10 , 000 реалізацій , де розмірність Y є 100 і ранг C становить 50 . Вихід єY010,000Y100C50

        rank           L2 
5.000000e+01 8.846689e-05 

Тобто, ранг даних також і ковариационная матриця за оцінками з даних знаходиться в межах відстані 8 × 10 - 5 з C508×105С --which близько. Як детальніша перевірка, коефіцієнти будують проти коефіцієнтів його оцінки. Всі вони лежать близько до лінії рівності:С

Малюнок

Код точно паралельний попередньому аналізу, і тому він повинен бути пояснювальним (навіть для некористувачів R, які могли би імітувати його в улюбленому середовищі додатків). Одне, що виявляється, - це необхідність обережності при використанні алгоритмів з плаваючою комою: записи можуть бути негативними (але крихітними) через неточність. Такі записи потрібно знецілити, перш ніж обчислити квадратний корінь, щоб знайти DD2D сам.

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")

2
+1, але коли ви говорите "невизначений" у своєму першому реченні, що саме ви маєте на увазі? Я перевірив у Вікіпедії, і там сказано, що позитивний семідефініт не є невизначеним, тобто невизначений означає, що C має як позитивні, так і негативні власні значення. Це ти там маєш на увазі?
амеба каже, що повернеться до Моніки

2
@amoeba Так, це було ковзанням. Дякуємо, що помітили. "Невизначений" означає, що підпис матриці має як позитивні, так і негативні знаки, тоді як "напівдефінітний" означає, що підпис має лише один знак.
whuber

6

Спосіб рішення A :

  1. 0,5(С+СТ)
  2. D+(м-мiн(еiгенvалуе(D)))Я , де I - матриця тотожності. D містить бажану позитивну певну коваріантну матрицю.

У MATLAB код був би

D = 0.5 * (C + C');
D =  D + (m - min(eig(CD)) * eye(size(D));

Метод рішення B : Сформулюйте та розв’яжіть опуклу СДП (семідефінітну програму), щоб знайти найближчу матрицю D до C відповідно до норми фробеніуса їх різниці, такою, що D є позитивно визначеним, задавши мінімальне власне значення m.

Використовуючи CVX під MATLAB, код буде таким:

n = size(C,1);
cvx_begin
variable D(n,n)
minimize(norm(D-C,'fro'))
D -m *eye(n) == semidefinite(n)
cvx_end

Порівняння методів рішення : Крім симетризації початкової матриці, метод розчину A коригує (збільшує) лише діагональні елементи на деяку загальну кількість і залишає недіагональні елементи незмінними. Метод рішення B знаходить найближчу (до початкової матриці) позитивну певну матрицю, що має вказане мінімальне власне значення, у значенні мінімальної норми фробеніуса різниці позитивної визначеної матриці D та вихідної матриці C, яка заснована на сумах різниці у квадраті всіх елементів D - C, включаючи недіагональні елементи. Таким чином, коригуючи недіагональні елементи, це може зменшити величину, на яку потрібно збільшити діагональні елементи, а діагоальні елементи не обов'язково всі збільшити на однакову кількість.


2

Я б почав з роздумів про модель, яку ви оцінюєте.

Якщо матриця коваріації не є напіввизначеною позитивною ознакою, це може означати, що у вас є проблема колінеарності у ваших змінних, яка вказувала б на проблему з моделлю і не обов'язково повинна бути вирішена числовими методами.

Якщо матриця з числових причин не є позитивною напівкінцевою, то деякі рішення, про які можна прочитати тут


1
Припущення полягає в тому, що модель - лінійна змішана модель. І для цього випадку не важливо знайти правильну модель для даних, скоріше дані наведені як приклад для деякого розрахунку. Тепер існує можливість, що ви отримаєте непозитивну напівдефінітну матрицю як оцінку для коваренції. Що робити звідти, якщо я хочу розібратися в коваріації від нормальної розподіленої сукупності, звідки беруться дані. Про те, що зразок нормально розподілений, є припущенням.
Клаус

1

Одним із способів було б обчислити матрицю з розкладання власного значення. Тепер я визнаю, що я не знаю занадто багато математики, що стоїть за цими процесами, але з моїх досліджень здається, що цей файл довідки здається корисним:

http://stat.ethz.ch/R-manual/R-patched/library/Matrix/html/chol.html

та деякі інші споріднені команди в Р.

Також перегляньте "NearPD" в пакеті Matrix.

Вибачте, що я не міг би допомогти, але сподіваюся, що мій пошук може допомогти підштовхнути вас у правильному напрямку.


Привіт, THX для посилань. Залежно від декомпозиції власного значення, це розкладання не допомагає, оскільки звідти ви отримуєте складні власні значення для квадратної кореневої матриці, але мені потрібна перезаписана цінна матриця.
Клаус

1

Результати можна отримати за допомогою функції NearPD в пакеті Matrix в Р. Це дозволить повернути реальну матрицю з цінністю.

library(Matrix)
A <- matrix(1, 3,3); A[1,3] <- A[3,1] <- 0
n.A <- nearPD(A, corr=T, do2eigen=FALSE)
n.A$mat

# 3 x 3 Matrix of class "dpoMatrix"
#           [,1]      [,2]      [,3]
# [1,] 1.0000000 0.7606899 0.1572981
# [2,] 0.7606899 1.0000000 0.7606899
# [3,] 0.1572981 0.7606899 1.0000000

Для користувачів R .. це може бути не поганою версією "бідного чоловіка" (з меншим контролем) методу рішення B в моїй відповіді.
Марк Л. Стоун

Я погоджуюсь, що це не оптимально, але іноді це робить трюк.
Доктор Майк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.