在R中有一个函数(cm.rnorm.cor,来自软件包CreditMetrics),它获取样本量、变量量和相关矩阵,以创建相关数据。在Python中有等价的吗?
cm.rnorm.cor
CreditMetrics
arknldoa1#
numpy.random中Generator类的方法multivariate_normal就是您需要的函数。示例:
numpy.random
Generator
multivariate_normal
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. rng = np.random.default_rng() y = rng.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.', alpha=0.25) plt.plot(mu[0], mu[1], 'ro', ms=3.5) plt.ylabel('y[1]') plt.axis('equal') plt.grid(True) plt.subplot(2,2,3) plt.plot(y[:,0], y[:,2], 'b.', alpha=0.25) plt.plot(mu[0], mu[2], 'ro', ms=3.5) 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.', alpha=0.25) plt.plot(mu[1], mu[2], 'ro', ms=3.5) plt.xlabel('y[1]') plt.axis('equal') plt.grid(True) plt.show()
结果:
参见SciPy Cookbook中的CorrelatedRandomSamples。
wf82jlnq2#
如果你将协方差矩阵C Cholesky分解为L L^T,并生成一个独立的随机向量x,那么Lx将是一个协方差为C的随机向量。
C
L L^T
x
Lx
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()
参考:参见Cholesky分解如果要生成两个序列X和Y,并具有特定的(Pearson)相关系数(例如:0.2):
X
Y
rho = cov(X,Y) / sqrt(var(X)*var(Y))
你可以选择协方差矩阵为
cov = [[1, 0.2], [0.2, 1]]
这使得cov(X,Y) = 0.2以及方差var(X)和var(Y)都等于1。所以rho等于0.2。例如,下面我们生成相关序列对X和Y,1000次。然后我们绘制相关系数的直方图:
cov(X,Y) = 0.2
var(X)
var(Y)
rho
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()
正如您所看到的,相关系数通常接近0.2,但对于任何给定的样本,相关性很可能不是0.2。
2条答案
按热度按时间arknldoa1#
numpy.random
中Generator
类的方法multivariate_normal
就是您需要的函数。示例:
结果:
参见SciPy Cookbook中的CorrelatedRandomSamples。
wf82jlnq2#
如果你将协方差矩阵
C
Cholesky分解为L L^T
,并生成一个独立的随机向量x
,那么Lx
将是一个协方差为C
的随机向量。参考:参见Cholesky分解
如果要生成两个序列
X
和Y
,并具有特定的(Pearson)相关系数(例如:0.2):你可以选择协方差矩阵为
这使得
cov(X,Y) = 0.2
以及方差var(X)
和var(Y)
都等于1。所以rho
等于0.2。例如,下面我们生成相关序列对
X
和Y
,1000次。然后我们绘制相关系数的直方图:正如您所看到的,相关系数通常接近0.2,但对于任何给定的样本,相关性很可能不是0.2。