[Sur des questions récentes, je cherchais à générer des vecteurs aléatoires dans R , et je voulais partager cette "recherche" en tant que Q&A indépendante sur un point spécifique.]
La génération de données aléatoires avec corrélation peut être effectuée en utilisant la décomposition de Cholesky de la matrice de corrélation ici , comme reflété dans les articles précédents ici et ici .
La question que je veux aborder est comment utiliser la distribution uniforme pour générer des nombres aléatoires décorrélés de différentes distributions marginales en R .
r
correlation
sampling
random-variable
random-generation
Antoni Parellada
la source
la source
Réponses:
La question étant
et pas seulement des variables aléatoires normales, la réponse ci-dessus ne produit pas de simulations avec la corrélation voulue pour une paire arbitraire de distributions marginales dans .R
La raison en est que, pour la plupart des cdfs et , lorsque où désigne le cdf normal standard.GX GY
À savoir, voici un contre-exemple avec un Exp (1) et un Gamma (.2,1) comme ma paire de distributions marginales dans .R
Un autre contre-exemple évident est quand est le cdf de Cauchy, auquel cas la corrélation n'est pas définie.GX
Pour donner une image plus large, voici un code R où et sont arbitraires:GX GY
Jouer avec différents cdfs m'a amené à distinguer ce cas particulier d'une pour et d'une distribution log-Normal pour :χ23 GX GY
ce qui montre à quelle distance de la diagonale la corrélation peut être.
la source
J'ai écrit le
correlate
paquet. Les gens ont dit que c'était prometteur (digne d'une publication dans le Journal of Statistical Software), mais je n'ai jamais écrit l'article pour cela parce que j'ai choisi de ne pas poursuivre une carrière universitaire.Je crois que le
correlate
package non maintenu est toujours sur CRAN.Lorsque vous l'installez, vous pouvez effectuer les opérations suivantes:
Le résultat est que les nouvelles données auront une corrélation de 0,5, sans changer les distributions univariées de
a
etb
(les mêmes valeurs sont là, elles sont simplement déplacées jusqu'à ce que la corrélation multivariée 0,5 soit atteinte.Je répondrai aux questions ici, désolé pour le manque de documentation.
la source
Générez deux échantillons de données corrélées à partir d'une distribution aléatoire normale standard suite à une corrélation prédéterminée .
Par exemple, prenons une corrélation r = 0,7 et codons une matrice de corrélation telle que:
(C <- matrix(c(1,0.7,0.7,1), nrow = 2)) [,1] [,2] [1,] 1.0 0.7 [2,] 0.7 1.0
Nous pouvons utiliser
mvtnorm
pour générer maintenant ces deux échantillons comme un vecteur aléatoire bivarié:set.seed(0)
SN <- rmvnorm(mean = c(0,0), sig = C, n = 1e5)
résultant en deux composantes vectorielles distribuées comme ~ et avec a . Les deux composants peuvent être extraits comme suit:cor(SN[,1],SN[,2])= 0.6996197 ~ 0.7
X1 <- SN[,1]; X2 <- SN[,2]
Voici l'intrigue avec la ligne de régression qui se chevauche:
Utilisez la transformation intégrale de probabilité ici pour obtenir un vecteur aléatoire bivarié avec des distributions marginales ~ et la même corrélation :U(0,1)
U <- pnorm(SN)
- donc nous alimentonspnorm
leSN
vecteur pour trouver (ou ). Ce faisant, nous préservons le .cor(U[,1], U[,2]) = 0.6816123 ~ 0.7
Encore une fois, nous pouvons décomposer le vecteur
U1 <- U[,1]; U2 <- U[,2]
et produire un diagramme de dispersion avec des distributions marginales sur les bords, montrant clairement leur nature uniforme:Appliquez ici la méthode d'échantillonnage par transformée inverse pour finalement obtenir le bivecteur de points également corrélés appartenant à la famille de distribution que nous nous proposons de reproduire.
De là, nous pouvons simplement générer deux vecteurs distribués normalement et avec des variances égales ou différentes . Par exemple:
Y1 <- qnorm(U1, mean = 8,sd = 10)
etY2 <- qnorm(U2, mean = -5, sd = 4)
qui maintiendra la corrélation désirée,cor(Y1,Y2) = 0.6996197 ~ 0.7
.Ou optez pour différentes distributions. Si les distributions choisies sont très différentes, la corrélation peut ne pas être aussi précise. Par exemple,t λ
U1
suivons une distribution avec 3 df, et une exponentielle avec a = 1: et The . Voici les histogrammes respectifs:U2
Z1 <- qt(U1, df = 3)
Z2 <- qexp(U2, rate = 1)
cor(Z1,Z2) [1] 0.5941299 < 0.7
Voici un exemple de code pour tout le processus et les marginaux normaux:
À titre de comparaison, j'ai mis en place une fonction basée sur la décomposition de Cholesky:
En essayant les deux méthodes pour générer des échantillons corrélés (disons ) distribués ~ et nous obtenons, en définissant :r=0.7 N(97,23) N(32,8)
set.seed(99)
Utilisation de l'uniforme:
et utilisation du Cholesky:
la source