2013-04-15 75 views
5

Trong R có chức năng (cm.rnorm.cor, từ gói CreditMetrics), lấy số lượng mẫu, số lượng biến và ma trận tương quan để tạo dữ liệu tương quan.Tạo dữ liệu tương quan bằng Python (3.3)

Có tương đương với Python không?

+0

Xin lỗi, lỗi của tôi, về Python 3.3. – PascalVKooten

+0

Whaaat ... Hỗ trợ được thêm gần đây! Cảm ơn vì đã nhắc tôi. – PascalVKooten

+0

@Dualinity, với giọng kém hài hước, bên cạnh bộ sưu tập tuyệt vời các gói từ Blender, tôi thực sự đề nghị bạn thử dùng Python (X, Y). Đó là một bộ sưu tập các gói Python để phát triển khoa học + IPython + Great IDE được gọi là spyder. http://code.google.com/p/pythonxy/ – Oz123

Trả lời

9

numpy.random.multivariate_normal là hàm bạn muốn.

Ví dụ:

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() 

Kết quả:

enter image description here

Xem thêm CorrelatedRandomSamples trong scipy Cookbook.

5

Nếu bạn Cholesky-phân hủy một ma trận hiệp phương sai C vào L L^T, và tạo ra một độc lập vector ngẫu nhiên x, sau đó Lx sẽ là một véc tơ ngẫu nhiên với hiệp phương sai 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() 

enter image description here

tham khảo: Xem Cholesky decomposition


Nếu bạn muốn tạo ra hai series, XY, với một đặc biệt (Pearson) correlation coefficient (ví dụ 0.2):

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

bạn có thể chọn các ma trận hiệp phương sai là

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

Điều này làm cho cov(X,Y) = 0.2, và chênh lệch, var(X)var(Y) cả bằng 1. Vì vậy rho sẽ bằng 0,2. Ví dụ: dưới đây chúng tôi tạo ra các cặp chuỗi có liên quan, XY, 1000 lần. Sau đó, chúng tôi vẽ một biểu đồ của các hệ số tương quan:

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() 

enter image description here

Như bạn có thể thấy, hệ số tương quan nói chung là gần 0,2, nhưng đối với bất kỳ mẫu nào đó, mối tương quan sẽ hầu như không có 0.2 chính xác .

+0

Bạn có biết làm thế nào để có được dữ liệu được chính xác có một mối tương quan, nói, 0,2 (với một dung sai nhỏ)? – PascalVKooten

+0

hoặc chính xác chưa? – PascalVKooten

+0

'Numpy.random.multivariate_normal' làm gì dưới mui xe? Bởi vì tôi so sánh với phương pháp tiếp cận cholesky và tìm thấy sau này được nhanh hơn đáng kể, đặc biệt là cho dữ liệu chiều lớn hơn (như một vài nghìn). Cách tiếp cận cholesky chỉ làm việc cho một số loại ma trận hiệp phương sai? Cov-ma trận của tôi chỉ là đường chéo, hoặc rất thưa thớt. – Jason