Pour une étude de simulation , je dois générer des variables aléatoires qui montrent une corrélation prefined (population) à une variable existante .
J'ai examiné les R
packages copula
et ceux CDVine
qui peuvent produire des distributions multivariées aléatoires avec une structure de dépendance donnée. Cependant, il n'est pas possible de fixer l'une des variables résultantes à une variable existante.
Toutes les idées et les liens vers des fonctions existantes sont appréciés!
Conclusion: Deux réponses valables ont été trouvées, avec des solutions différentes:
- Un
R
script de caracal, qui calcule une variable aléatoire avec une corrélation exacte (échantillon) avec une variable prédéfinie - Une
R
fonction que je me suis trouvée, qui calcule une variable aléatoire avec une corrélation de population définie à une variable prédéfinie
[Ajout de @ttnphns: j’ai pris la liberté d’élargir le titre de la question d’un cas à une variable fixe à un nombre arbitraire de variables fixes; comment générer une variable ayant une ou plusieurs corrections prédéfinies avec une ou plusieurs variables fixes, existantes]
la source
Réponses:
En voici un autre: pour les vecteurs de moyenne 0, leur corrélation est égale au cosinus de leur angle. Donc, une façon de trouver un vecteur avec exactement la corrélation souhaitée r , correspondant à un angle θ :X r θ
Voici le code:
Pour la projection orthogonale , j'ai utilisé la décomposition Q R pour améliorer la stabilité numérique, puis simplement P = Q Q ′ .P Q R P=QQ′
la source
P <- X %*% solve(t(X) %*% X) %*% t(X)
ne produit pas r = 0,6, ce n'est donc pas la solution de rechange . Je suis encore confus. (Je serais heureux d'imiter votre expressionQ <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))
dans SPSS mais je ne sais pas comment.)Xctr[ , 1] %*% solve(t(Xctr[ , 1]) %*% Xctr[ , 1]) %*% t(Xctr[ , 1])
Xctr
rho=1
je l' ai trouvé utile de faire quelque chose comme ceci:if (isTRUE(all.equal(rho, 1))) rho <- 1-10*.Machine$double.eps
, sinon je devenaisNaN
sJe décrirai la solution la plus générale possible. Résoudre le problème dans cette généralité nous permet de réaliser une implémentation logicielle remarquablement compacte: deux lignes de
R
code suffisent.Choisissez un vecteur , de la même longueur que Y , selon la distribution de votre choix . Soit Y ⊥ soit les résidus de la régression des moindres carrés de X contre Y : cet extrait le Y composant de X . En ajoutant de nouveau un multiple approprié de Y à Y ⊥ , on peut produire un vecteur ayant une corrélation souhaitée ρ avec Y . Jusqu'à une constante additive arbitraire et une constante multiplicative positive - que vous êtes libre de choisir, de toute façon que ce soit - la solution est:X Y Y⊥ X Y Y X Y Y⊥ ρ Y
R
Il y a une similitude remarquable entre les parcelles, n'est-ce pas :-).
Si vous souhaitez expérimenter, voici le code qui a généré ces données et la figure. (Je n'ai pas pris la peine d'utiliser la liberté de modifier et d'ajuster les résultats, ce qui est une opération facile.)
R
y
Ce qui suit est une implémentation plus complète pour ceux qui souhaitent expérimenter.
la source
BTW, this method readily generalizes to more... Just use ordinary least squares... and form a suitable linear combination
x
et que je veux générer un nouveau vecteur eny
corrélation avecx
ley
vecteur mais que je veuille aussi que le vecteur soit uniformément distribué.Voici une autre approche informatique (la solution est adaptée d’un post de forum d’Enrico Schumann). Selon Wolfgang (voir commentaires), il s’agit d’un calcul identique à la solution proposée par tnphns.
x
La fonction peut également utiliser des distributions marginales non normales en ajustant le paramètre
mar.fun
. Notez cependant que fixer une variable ne semble fonctionner qu'avec une variable normalement distribuéex
! (qui pourrait se rapporter au commentaire de Macro).Notez également que le "petit facteur de correction" de la publication d'origine a été supprimé car il semble biaiser les corrélations résultantes, du moins dans le cas des distributions gaussiennes et des corrélations de Pearson (voir également les commentaires).
la source
rho
.X2 <- mar.fun(n)
pourX2 <- mar.fun(n,mean(x),sd(x))
obtenir la corrélation souhaitée entre x1 et x2Mise à jour du 11 novembre 2017. J'ai rencontré cet ancien fil de discussion aujourd'hui et décidé d'élargir ma réponse en montrant l'algorithme de l'ajustement itératif dont je parlais initialement.
Disclamer: Cette solution itérative que j'ai trouvée est inférieure à l'excellente solution basée sur la recherche de la double base et proposée par @whuber dans ce fil de discussion aujourd'hui. La solution de @Wuber n'est pas itérative et, plus important encore pour moi, elle semble affecter les valeurs de la variable d'entrée "pig" un peu moins que "mon" algorithme (ce serait alors un atout si la tâche est de "corriger" la variable existante et ne pas générer une variable aléatoire à partir de zéro). Néanmoins, je publie le mien par curiosité et parce que cela fonctionne (voir aussi la note en bas de page).
(le dénominateur ne change pas lors des itérations, calculez-le à l'avance)
la source
J'avais envie de faire de la programmation, alors j'ai pris la réponse supprimée de @ Adam et j'ai décidé d'écrire une belle implémentation en R. Je me suis concentré sur un style orienté fonctionnellement (c'est-à-dire une boucle de style lapply). L'idée générale est de prendre deux vecteurs, permuter de façon aléatoire l'un des vecteurs jusqu'à ce qu'une certaine corrélation soit atteinte entre eux. Cette approche est très brutale, mais simple à mettre en œuvre.
Tout d'abord, nous créons une fonction qui permute de manière aléatoire le vecteur d'entrée:
... et créer des exemples de données
... écrivez une fonction qui permute le vecteur d'entrée et le corrèle à un vecteur de référence:
... et itérer mille fois:
Notez que les règles de portée de R garantissent que
vec1
etvec2
se trouvent dans l'environnement global, en dehors de la fonction anonyme utilisée ci-dessus. Ainsi, les permutations sont toutes relatives aux jeux de données de test d'origine que nous avons générés.Ensuite, nous trouvons la corrélation maximale:
... ou trouvez la valeur la plus proche d'une corrélation de 0.2:
Pour obtenir une corrélation plus élevée, vous devez augmenter le nombre d'itérations.
la source
Solution:
Code Python:
Test de sortie:
la source
Générer des variables normales avec la matrice de covariance SAMPLING telle que donnée
Générer des variables normales avec la matrice de covariance de POPULATION telle que donnée
la source
Il suffit de créer un vecteur aléatoire et de trier jusqu'à obtenir le résultat souhaité r.
la source