Generar datos correlacionados en Python (3.3)

En R hay una función ( cm.rnorm.cor , del paquete CreditMetrics ), que toma la cantidad de muestras, la cantidad de variables y una matriz de correlación para crear datos correlacionados.

¿Hay un equivalente en Python?

numpy.random.multivariate_normal es la función que desea.

Ejemplo:

 import numpy as np import matplotlib.pyplot as plt num_samples = 400 # The desired mean values of the sample. mu = np.array([5.0, 0.0, 10.0]) # The desired covariance matrix. r = np.array([ [ 3.40, -2.75, -2.00], [ -2.75, 5.50, 1.50], [ -2.00, 1.50, 1.25] ]) # Generate the random samples. y = np.random.multivariate_normal(mu, r, size=num_samples) # Plot various projections of the samples. plt.subplot(2,2,1) plt.plot(y[:,0], y[:,1], 'b.') plt.plot(mu[0], mu[1], 'ro') plt.ylabel('y[1]') plt.axis('equal') plt.grid(True) plt.subplot(2,2,3) plt.plot(y[:,0], y[:,2], 'b.') plt.plot(mu[0], mu[2], 'ro') plt.xlabel('y[0]') plt.ylabel('y[2]') plt.axis('equal') plt.grid(True) plt.subplot(2,2,4) plt.plot(y[:,1], y[:,2], 'b.') plt.plot(mu[1], mu[2], 'ro') plt.xlabel('y[1]') plt.axis('equal') plt.grid(True) plt.show() 

Resultado:

introduzca la descripción de la imagen aquí

Vea también CorrelatedRandomSamples en el Libro de cocina SciPy.

Si descompones Cholesky una matriz de covarianza C en LL^T , y generas un vector aleatorio independiente x , entonces Lx será un vector aleatorio con covarianza C

 import numpy as np import matplotlib.pyplot as plt linalg = np.linalg np.random.seed(1) num_samples = 1000 num_variables = 2 cov = [[0.3, 0.2], [0.2, 0.2]] L = linalg.cholesky(cov) # print(L.shape) # (2, 2) uncorrelated = np.random.standard_normal((num_variables, num_samples)) mean = [1, 1] correlated = np.dot(L, uncorrelated) + np.array(mean).reshape(2, 1) # print(correlated.shape) # (2, 1000) plt.scatter(correlated[0, :], correlated[1, :], c='green') plt.show() 

introduzca la descripción de la imagen aquí

Referencia: Ver descomposición de Cholesky.


Si desea generar dos series, X e Y , con un coeficiente de correlación particular (Pearson) (por ejemplo, 0.2):

 rho = cov(X,Y) / sqrt(var(X)*var(Y)) 

Podrías elegir la matriz de covarianza para ser

 cov = [[1, 0.2], [0.2, 1]] 

Esto hace que cov(X,Y) = 0.2 , y las varianzas, var(X) y var(Y) igual a 1. Entonces rho sería igual a 0.2.

Por ejemplo, a continuación generamos pares de series correlacionadas, X e Y , 1000 veces. Luego trazamos un histogtwig de los coeficientes de correlación:

 import numpy as np import matplotlib.pyplot as plt import scipy.stats as stats linalg = np.linalg np.random.seed(1) num_samples = 1000 num_variables = 2 cov = [[1.0, 0.2], [0.2, 1.0]] L = linalg.cholesky(cov) rhos = [] for i in range(1000): uncorrelated = np.random.standard_normal((num_variables, num_samples)) correlated = np.dot(L, uncorrelated) X, Y = correlated rho, pval = stats.pearsonr(X, Y) rhos.append(rho) plt.hist(rhos) plt.show() 

introduzca la descripción de la imagen aquí

Como puede ver, los coeficientes de correlación son generalmente cerca de 0.2, pero para cualquier muestra dada, lo más probable es que la correlación no sea 0.2 exactamente.