Para un estudio de simulación tengo para generar variables aleatorias que muestran un (población) de correlación prefined a una variable existente .
Miré en los R
paquetes copula
y CDVine
que pueden producir distribuciones aleatorias multivariadas con una estructura de dependencia dada. Sin embargo, no es posible arreglar una de las variables resultantes a una variable existente.
Cualquier idea y enlaces a las funciones existentes son apreciados!
Conclusión: surgieron dos respuestas válidas, con diferentes soluciones:
- Un
R
guión de caracal, que calcula una variable aleatoria con una correlación exacta (muestra) con una variable predefinida - Una
R
función que encontré yo mismo, que calcula una variable aleatoria con una correlación de población definida con una variable predefinida
[Adición de @ttnphns: me tomé la libertad de ampliar el título de la pregunta de un caso de variable fija única a un número arbitrario de variables fijas; es decir, cómo generar una variable que tenga correcciones predefinidas con algunas variables fijas y existentes]
fuente
Respuestas:
Aquí hay otro: para los vectores con media 0, su correlación es igual al coseno de su ángulo. Entonces, una forma de encontrar un vector con exactamente la correlación deseada , correspondiente a un ángulo :r θX r θ
Aquí está el código:
Para la proyección ortogonal , utilicé la descomposición para mejorar la estabilidad numérica, desde entonces simplemente .Q R P = Q Q ′P QR P=QQ′
fuente
P <- X %*% solve(t(X) %*% X) %*% t(X)
no produce r = 0.6, así que esa no es la solución . Todavía estoy confundido. (Estaré encantado de imitar su expresiónQ <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))
en SPSS pero no sé cómo.)Xctr[ , 1] %*% solve(t(Xctr[ , 1]) %*% Xctr[ , 1]) %*% t(Xctr[ , 1])
Xctr
rho=1
me pareció útil hacer algo como esto: de loif (isTRUE(all.equal(rho, 1))) rho <- 1-10*.Machine$double.eps
contrario, estaba recibiendoNaN
sDescribiré la solución más general posible. Resolver el problema en esta generalidad nos permite lograr una implementación de software notablemente compacta: solo
R
bastan dos líneas cortas de código.Elija un vector , de la misma longitud que , de acuerdo con la distribución que desee. Deje que ser los residuos de la regresión de mínimos cuadrados de contra : este extrae el componente de . Mediante la adición de nuevo un múltiplo adecuado de a , podemos producir un vector que tiene cualquier correlación deseada con . Hasta una constante aditiva arbitraria y una constante multiplicativa positiva, que puede elegir de cualquier manera, la solución esY Y ⊥ X Y Y X Y Y ⊥ ρ YX Y Y⊥ X Y Y X Y Y⊥ ρ Y
(" " representa cualquier cálculo proporcional a una desviación estándar).SD
Aquí está elX
R
código de trabajo . Si no proporciona , el código extraerá sus valores de la distribución Normal estándar multivariante.Para ilustrar, me genera un aleatoria con componentes y produje que tiene diversas correlaciones especificado con esta . Todos fueron creados con el mismo vector inicial . Aquí están sus diagramas de dispersión. Los "rugplots" en la parte inferior de cada panel muestran el vector común .50 X Y ; ρ Y X = ( 1 , 2 , … , 50 ) YY 50 XY;ρ Y X=(1,2,…,50) Y
Hay una notable similitud entre las parcelas, no está allí :-).
Si desea experimentar, aquí está el código que produjo estos datos y la figura. (No me molesté en usar la libertad de cambiar y escalar los resultados, que son operaciones fáciles).
Por cierto, este método se generaliza fácilmente a más de una : si es matemáticamente posible, encontrará una con correlaciones específicas conjunto de . Simplemente use los mínimos cuadrados ordinarios para eliminar los efectos de todos los de y forme una combinación lineal adecuada de y los residuos. (Ayuda hacer esto en términos de una base dual para , que se obtiene calculando un pseudo-inverso. El siguiente código usa la SVD de para lograr eso).X Y 1 , Y 2 , ... , Y k ; ρ 1 , ρ 2 , … , ρ k Y i Y i X Y i Y YY XY1,Y2,…,Yk;ρ1,ρ2,…,ρk Yi Yi X Yi Y Y
Aquí hay un boceto del algoritmoYi
R
, donde se dan como columnas de una matriz :y
La siguiente es una implementación más completa para aquellos que deseen experimentar.
fuente
BTW, this method readily generalizes to more... Just use ordinary least squares... and form a suitable linear combination
x
y quiero generar un nuevo vectory
correlacionadox
pero también quiero que ely
vector se distribuya uniformemente.Aquí hay otro enfoque computacional (la solución está adaptada de una publicación del foro de Enrico Schumann). Según Wolfgang (ver comentarios), esto es computacionalmente idéntico a la solución propuesta por ttnphns.
A diferencia de la solución de caracal, no produce una muestra con la correlación exacta de , sino dos vectores cuya correlación de población es igual a .ρρ ρ
La siguiente función puede calcular una distribución de muestra bivariada extraída de una población con un determinado . Calcula dos variables aleatorias o toma una variable existente (pasada como parámetro ) y crea una segunda variable con la correlación deseada:ρ
x
La función también puede usar distribuciones marginales no normales ajustando el parámetro
mar.fun
. Tenga en cuenta, sin embargo, que arreglar una variable solo parece funcionar con una variable normalmente distribuidax
. (que podría estar relacionado con el comentario de Macro).También tenga en cuenta que el "pequeño factor de corrección" de la publicación original se eliminó, ya que parece sesgar las correlaciones resultantes, al menos en el caso de las distribuciones gaussianas y las correlaciones de Pearson (también ver comentarios).
fuente
rho
.X2 <- mar.fun(n)
aX2 <- mar.fun(n,mean(x),sd(x))
obtener la correlación deseada entre x1 y x2Deje que sea su variable fija y desee generar una variable que se correlacione con en la cantidad . Si está estandarizado, entonces (porque es el coeficiente beta en regresión simple) , donde es una variable aleatoria de la distribución normal que tiene media y . La correlación observada entre los datos e será aproximadamente ; e pueden verse como muestras aleatorias de población normal bivariada (siX Y X r X r Y=rX+E E 0 sd=1−r2−−−−−√ X Y r X Y X es de lo normal) con .ρ=r
Ahora bien, si se quiere alcanzar la correlación de dos variables en la muestra exactamente , es necesario disponer que tiene cero correlación con . Este ajuste a cero se puede alcanzar modificando iterativamente. Bueno, con solo dos variables, una dada ( ) y otra para generar ( ), el número suficiente de iteraciones es en realidad 1, pero con múltiples variables dadas ( ) se necesitarán iteraciones.r E X E X Y X1,X2,X3,...
Cabe señalar que si es normal, en el primer procedimiento ("aproximado ") también será normal; sin embargo, en el ajuste iterativo de a la " exacta " es probable que pierda normalidad porque el ajuste explota los valores de los casos de forma selectiva.X r Y Y r Y
Actualización 11 de noviembre de 2017. Hoy me he encontrado con este viejo hilo y decidí ampliar mi respuesta mostrando el algoritmo del ajuste iterativo sobre el que estaba hablando inicialmente.
Aquí hay una solución iterativa sobre cómo entrenar una variable aleatoriamente simulada o preexistente para correlacionar o covariar exactamente como lo deseamos (o muy cerca de eso, dependiendo del número de iteraciones) con un conjunto de variables dadas s (estas no pueden modificarse).Y X
Descargo de responsabilidad: esta solución iterativa que he encontrado es inferior a la excelente basada en encontrar la base dual y propuesta por @whuber en este hilo hoy. La solución de @ whuber no es iterativa y, lo que es más importante para mí, parece estar afectando los valores de la variable de entrada "pig" algo menos que el algoritmo "my" (sería una ventaja si la tarea es "corregir" la variable existente y no generar una variable aleatoria desde cero). Aún así, estoy publicando el mío por curiosidad y porque funciona (véase también la nota al pie).
Entonces, hemos dado las variables (fijas) , y la variable que es un "cerdo" de valores generado aleatoriamente o es una variable de datos existente cuyos valores necesitamos "corregir" - para obtener exactamente a las correlaciones (o pueden ser covarianzas) con las s. Todos los datos deben ser continuos; en otras palabras, debe haber una gran cantidad de valores únicos.X1,X2,...,Xm Y Y r1,r2,...,rm X
La idea: realizar un ajuste iterativo de residuos. Conociendo las correlaciones / covarianzas deseadas (objetivo), podemos calcular los valores pronosticados para la utilizando las s como predictores lineales múltiples. Después de obtener los residuos iniciales (de la actual y la predicción ideal), entrénelos iterativamente para que no se correlacionen con los predictores. Al final, recupere con los residuos. (El procedimiento fue mi propio invento experimental de la rueda hace muchos años cuando no conocía nada de la teoría; luego lo codifiqué en SPSS).Y X Y Y
Convierta el objetivo s en sumas de productos cruzados multiplicándolos por : . ( es un índice variable ).r df=n−1 Sj=rjdf j X
Estandarizar en Z todas las variables (centrar cada una, luego dividir por la desviación st. Calculada en el anterior ). y s son, por lo tanto, estándar. Las sumas de cuadrados observadas son ahora = .df Y X df
Calcular los coeficientes de predicción de regressional por s de acuerdo con el objetivo s: .Y X r b=(X′X)−1S
Calcule los valores pronosticados para : .Y Y^=Xb
Calcule los residuos .E=Y−Y^
Calcule la suma de cuadrados (objetivo) necesaria para los residuos: .SSS=df−SSY^
(Comience a repetir.) Calcule las sumas observadas de productos cruzados entre actual y cada :E Xj Cj=∑ni=1EiXij
Corrija los valores de con el objetivo de acercar todos los s a ( es un índice de caso):E C 0 i
(el denominador no cambia en las iteraciones, calcule por adelantado)
O, alternativamente, una fórmula más eficiente asegura además que la media de convierte en . Primero, centre en cada cálculo previo de la s en el paso 7, luego en este paso 8 corrija como:E 0 E C
(de nuevo, los denominadores se conocen de antemano)1
Traiga a su valor objetivo:SSE Ei[corrected]=EiSSS/SSE−−−−−−−−√
Vaya al paso 7. (Haga, digamos, 10-20 iteraciones; cuanto mayor sea más iteraciones podrían necesitarse. Si el objetivo s fuera realista, es positivo, y si el tamaño de la muestra no es demasiado pequeño, las iteraciones siempre directo a la convergencia. Fin de iteración.)m r SSS n
Listo: Todos los s son casi cero ahora, lo que significa que los residuos han sido entrenados para restaurar objetivo . Calcular el ajuste : .E r Y Y [ corregido ] = Y + EC E r Y Y[corrected]=Y^+E
La obtenida está casi estandarizada. Como último golpe, es posible que desee estandarizarlo con precisión, de nuevo como lo hizo en el paso 2.Y
Puede suministrar a cualquier variación y decir lo que quiera. En realidad, entre las cuatro estadísticas: min , max , mean , st. dev . - puede seleccionar cualquiera de los dos valores y transformar linealmente la variable para que los posea sin alterar las s (correlaciones) que ha alcanzado (todo se llama reescalamiento lineal).rY r
Para advertir nuevamente lo que se dijo anteriormente. Con ese tirón de exactamente a la , la salida no tiene que distribuirse normalmente.r YY r Y
Y X1 La fórmula de corrección puede ser aún más sofisticada, por ejemplo, para asegurar una mayor homocedasticidad (en términos de sumas de cuadrados) de con cada también, simultáneamente con el logro de las correlaciones, - he implementado un código para eso también. (No sé si esa tarea "doble" se puede resolver a través de un enfoque más ordenado, no narrativo, como el de Whuber ).Y X
fuente
Sentí ganas de programar un poco, así que tomé la respuesta eliminada de @ Adam y decidí escribir una buena implementación en R. Me concentro en usar un estilo funcionalmente orientado (es decir, un bucle de estilo rápido). La idea general es tomar dos vectores, permutar aleatoriamente uno de los vectores hasta que se haya alcanzado una cierta correlación entre ellos. Este enfoque es de fuerza bruta, pero es simple de implementar.
Primero creamos una función que permuta aleatoriamente el vector de entrada:
... y crea algunos datos de ejemplo
... escriba una función que permute el vector de entrada y lo correlacione con un vector de referencia:
... e iterar mil veces:
Tenga en cuenta que reglas de alcance de R asegurar que
vec1
yvec2
se encuentran en el medio ambiente mundial, fuera de la función anónima utilizado anteriormente. Entonces, las permutaciones son todas relativas a los conjuntos de datos de prueba originales que generamos.A continuación, encontramos la correlación máxima:
... o encuentre el valor más cercano a una correlación de 0.2:
Para obtener una mayor correlación, debe aumentar el número de iteraciones.
fuente
un problema más general: dada la variable ¿cómo generar las variables aleatorias con la matriz de correlación ?Y 2 , … , Y n RY1 Y2,…,Yn R
Solución:
Código de Python:
Prueba de salida:
fuente
Genere variables normales con la matriz de covarianza de MUESTREO como se indica
Genere variables normales con la matriz de covarianza de POBLACIÓN como se indica
fuente
Simplemente cree un vector aleatorio y ordene hasta obtener el r deseado.
fuente