Comment créer une matrice de covariance arbitraire

21

Par exemple, dans R, la MASS::mvrnorm()fonction est utile pour générer des données pour illustrer diverses choses dans les statistiques. Il prend un Sigmaargument obligatoire qui est une matrice symétrique spécifiant la matrice de covariance des variables. Comment créer une matrice symétrique n×n avec des entrées arbitraires?

rsl
la source
3
Je pense que cette question gagnerait à être éditée pour se concentrer sur "comment puis-je créer une matrice de covariance arbitraire" et moins sur l'aspect de codage. Il y a certainement ici un problème statistique sous-jacent, comme le montre la réponse.
Silverfish

Réponses:

22

Créer une matrice A avec des valeurs arbitrairesn×nUNE

puis utilisez comme matrice de covariance. Σ=UNETUNE

Par exemple

n <- 4  
A <- matrix(runif(n^2)*2-1, ncol=n) 
Sigma <- t(A) %*% A
Henri
la source
De même, Sigma <- A + t(A).
rsl
6
@MoazzemHossen: Votre suggestion produira une matrice symétrique, mais elle peut ne pas toujours être semi-définie positive (par exemple, votre suggestion pourrait produire une matrice avec des valeurs propres négatives) et elle peut donc ne pas convenir comme matrice de covariance
Henry
Oui, j'ai remarqué que R renvoie une erreur dans le cas où ma méthode suggérée produirait une matrice inappropriée.
rsl
4
Notez que si vous préférez une matrice de corrélation pour une meilleure interprétabilité, il y a la fonction ? Cov2cor , qui peut être appliquée par la suite.
gung - Rétablir Monica
1
@ B11b: Votre matrice de covariance doit être semi-définie positive. Cela mettrait des limites aux valeurs de covariance, pas totalement évidentes lorsque n>2
Henry
24

J'aime avoir le contrôle sur les objets que je crée, même s'ils peuvent être arbitraires.

Considérez donc que possible matrices de covariance Σ peut être exprimée sous la formen×nΣ

Σ=P Diagonal(σ1,σ2,,σn) P

est une matrice orthogonale et σ 1σ 2σ n0 .Pσ1σ2σn0

Géométriquement, cela décrit une structure de covariance avec une gamme de composants principaux de tailles . Ces composants vont dans le sens des rangées de P . Voir les figures dans Comprendre l'analyse des composants principaux, les vecteurs propres et les valeurs propres pour des exemples avec n = 3 . La définition de σ i définira les amplitudes des covariances et leurs tailles relatives, déterminant ainsi toute forme ellipsoïdale souhaitée. Les rangées de P orientent les axes de la forme comme vous préférez.σiPn=3σjeP

Un avantage algébrique et informatique de cette approche est que lorsque , Σ est facilement inversé (ce qui est une opération courante sur les matrices de covariance):σn>0Σ

Σ-1=P Diagonale(1/σ1,1/σ2,,1/σn) P.

Ne se soucient pas des directions, mais seulement des plages de tailles du ? C'est très bien: vous pouvez facilement générer une matrice orthogonale aléatoire. Il suffit d'envelopper n 2 iid les valeurs normales standard dans une matrice carrée, puis de l'orthogonaliser. Cela fonctionnera presque sûrement (à condition que n ne soit pas énorme). La décomposition QR fera cela, comme dans ce codeσjen2n

n <- 5
p <- qr.Q(qr(matrix(rnorm(n^2), n)))

Cela fonctionne parce que la distribution multinormale à variables ainsi générée est "elliptique": elle est invariante sous toutes les rotations et réflexions (à travers l'origine). Ainsi, toutes les matrices orthogonales sont générées uniformément, comme expliqué dans Comment générer des points uniformément distribués sur la surface de la sphère unitaire 3D? .n

ΣPσjecrossprodRσ=(σ1,,σ5)=(5,4,3,2,1)

Sigma <- crossprod(p, p*(5:1))

σP

svd(Sigma)

Sigmaσ

Tau <- crossprod(p, p/(5:1))

zapsmall(Sigma %*% Tau)n×nσje01/σjeσje

whuber
la source
P
1
Il vaut peut-être la peine de mentionner que les valeurs singulières svd(Sigma)seront réorganisées - cela m'a dérouté pendant une minute.
FrankD
1

Vous pouvez simuler des matrices définies positives aléatoires à partir de la distribution Wishart en utilisant la fonction "rWishart" du package largement utilisé "stats".

n <- 4
rWishart(1,n,diag(n))
Carlos Llosa
la source
1

Il existe un package spécialement pour cela clusterGeneration(écrit entre autres par Harry Joe, un grand nom dans ce domaine).

Il existe deux fonctions principales:

  • genPositiveDefMat générer une matrice de covariance, 4 méthodes différentes
  • rcorrmatrix : générer une matrice de corrélation

Exemple rapide:

library(clusterGeneration)
#> Loading required package: MASS
genPositiveDefMat("unifcorrmat",dim=3)
#> $egvalues
#> [1] 15.408962  5.673916  1.228842
#> 
#> $Sigma
#>          [,1]     [,2]     [,3]
#> [1,] 6.714871 1.643449 6.530493
#> [2,] 1.643449 6.568033 2.312455
#> [3,] 6.530493 2.312455 9.028815
genPositiveDefMat("eigen",dim=3)
#> $egvalues
#> [1] 8.409136 4.076442 2.256715
#> 
#> $Sigma
#>            [,1]       [,2]      [,3]
#> [1,]  2.3217300 -0.1467812 0.5220522
#> [2,] -0.1467812  4.1126757 0.5049819
#> [3,]  0.5220522  0.5049819 8.3078880

Créé le 2019-10-27 par le package reprex (v0.3.0)

Enfin, notez qu'une autre approche consiste à faire un premier essai à partir de zéro, puis à utiliser Matrix::nearPD()pour rendre votre matrice positive-définie.

Matifou
la source