Answers:
您可以向后执行此操作:每个矩阵 (所有对称 PSD矩阵的集合)都可以分解为 p × p
O其中是正交矩阵
为了获得,首先生成一个随机基(其中是随机向量,通常在)。从那里开始,使用Gram-Schmidt正交化过程获得(v 1,。。。,v p)v 我(- 1 ,1 )(Ú 1,。。。。,Ù p)= Õ
具有许多可以有效地随机进行GS正交化的包,甚至对于较大尺寸的包,例如“远”包。尽管您会在Wiki上找到GS算法,但最好不要重新发明轮子并进行Matlab实现(肯定存在,我不能推荐任何一种)。
最后,是一个对角矩阵,其元素都是正数(这又很容易生成:生成随机数,对其进行平方,对其进行排序,然后通过矩阵将它们放置在同一性的对角线上)。p p p
Lewandowski,Kurowicka和Joe(LKJ)在2009年发表了一篇基于藤本植物和扩展洋葱方法生成随机相关矩阵的论文,对生成随机相关矩阵的两种有效方法进行了统一处理和阐述。两种方法都可以从下面定义的某种精确意义上的均匀分布中生成矩阵,实现简单,快速,并具有使用有趣名称的附加优点。
大小的实对称矩阵在对角线上有唯一的非对角元素,因此可以将其参数化为。该空间中的每个点都对应一个对称矩阵,但并不是所有的点都是正定的(因为必须要有相关矩阵)。因此,相关矩阵形成子集(实际上是一个连接的凸子集),并且两种方法都可以根据该子集上的均匀分布生成点。d (d - 1 )/ 2 R d (d - 1 )/ 2 R d (d - 1 )/ 2
我将为每种方法提供自己的MATLAB实现,并用。
洋葱方法来自另一篇论文(LKJ中的参考文献#3),并以其相关矩阵从矩阵开始并逐列和逐行增长的事实而得名。结果分布是均匀的。我不太了解该方法背后的数学原理(无论如何还是更喜欢第二种方法),但是结果如下:
在每个子图的标题下方和下方显示了最小和最大的特征值,以及行列式(所有特征值的乘积)。这是代码:
%// ONION METHOD to generate random correlation matrices distributed randomly
function S = onion(d)
S = 1;
for k = 2:d
y = betarnd((k-1)/2, (d-k)/2); %// sampling from beta distribution
r = sqrt(y);
theta = randn(k-1,1);
theta = theta/norm(theta);
w = r*theta;
[U,E] = eig(S);
R = U*E.^(1/2)*U'; %// R is a square root of S
q = R*w;
S = [S q; q' 1]; %// increasing the matrix size
end
end
LKJ修改此方法稍中,为了能够样品相关矩阵从分发成正比。的较大,将越大行列式,这意味着产生的相关矩阵将越来越接近单位矩阵。值对应于均匀分布。在下图中,使用生成矩阵。 [ d ë 吨 η η = 1 η = 1 ,10 ,100 ,1000 ,10
由于某种原因,要获得与香草洋葱方法相同数量级的行列式,我需要输入而不是(如LKJ所述)。不知道错误在哪里。
%// EXTENDED ONION METHOD to generate random correlation matrices
%// distributed ~ det(S)^eta [or maybe det(S)^(eta-1), not sure]
function S = extendedOnion(d, eta)
beta = eta + (d-2)/2;
u = betarnd(beta, beta);
r12 = 2*u - 1;
S = [1 r12; r12 1];
for k = 3:d
beta = beta - 1/2;
y = betarnd((k-1)/2, beta);
r = sqrt(y);
theta = randn(k-1,1);
theta = theta/norm(theta);
w = r*theta;
[U,E] = eig(S);
R = U*E.^(1/2)*U';
q = R*w;
S = [S q; q' 1];
end
end
藤蔓方法最初由Joe(LKJ中的J)提出,并由LKJ改进。我更喜欢它,因为从概念上讲它更容易修改。这个想法是生成部分相关(它们是独立的,可以具有任何值而没有任何约束),然后通过递归公式将它们转换为原始相关性。以一定顺序组织计算很方便,该图称为“藤蔓”。重要的是,如果从特定的beta分布(矩阵中的不同单元格不同)采样了部分相关性,则所得矩阵将均匀分布。LKJ再次在此处引入一个附加参数以从与。结果与扩展洋葱相同:
%// VINE METHOD to generate random correlation matrices
%// distributed ~ det(S)^eta [or maybe det(S)^(eta-1), not sure]
function S = vine(d, eta)
beta = eta + (d-1)/2;
P = zeros(d); %// storing partial correlations
S = eye(d);
for k = 1:d-1
beta = beta - 1/2;
for i = k+1:d
P(k,i) = betarnd(beta,beta); %// sampling from beta
P(k,i) = (P(k,i)-0.5)*2; %// linearly shifting to [-1, 1]
p = P(k,i);
for l = (k-1):-1:1 %// converting partial correlation to raw correlation
p = p * sqrt((1-P(l,i)^2)*(1-P(l,k)^2)) + P(l,i)*P(l,k);
end
S(k,i) = p;
S(i,k) = p;
end
end
end
从上面可以看到,均匀分布导致几乎对角的相关矩阵。但是,可以很容易地将vine方法修改为具有更强的相关性(LKJ论文中没有对此进行描述,但是很简单):为此,应该从集中在附近的分布中采样部分相关性。下面我用 50,20,10,5,2,1从beta分布(从缩放到)中对它们进行采样。Beta分布的参数越小,它越集中在边缘附近。
请注意,在这种情况下,不能保证该分布是置换不变的,因此我在生成后还随机置换了行和列。
%// VINE METHOD to generate random correlation matrices
%// with all partial correlations distributed ~ beta(betaparam,betaparam)
%// rescaled to [-1, 1]
function S = vineBeta(d, betaparam)
P = zeros(d); %// storing partial correlations
S = eye(d);
for k = 1:d-1
for i = k+1:d
P(k,i) = betarnd(betaparam,betaparam); %// sampling from beta
P(k,i) = (P(k,i)-0.5)*2; %// linearly shifting to [-1, 1]
p = P(k,i);
for l = (k-1):-1:1 %// converting partial correlation to raw correlation
p = p * sqrt((1-P(l,i)^2)*(1-P(l,k)^2)) + P(l,i)*P(l,k);
end
S(k,i) = p;
S(i,k) = p;
end
end
%// permuting the variables to make the distribution permutation-invariant
permutation = randperm(d);
S = S(permutation, permutation);
end
以下是非对角元素的直方图如何查找上述矩阵(分布变化单调增加):
@shabbychef的答案中使用了一种非常简单的方法来生成具有一些强相关性的随机相关矩阵,我也想在这里进行说明。这个想法是随机生成几个()因子负载(随机矩阵大小),形成协方差矩阵(当然这不会是满秩的) )并添加一个带有对正元素的随机对角矩阵,使满秩。通过使,可以将所得的协方差矩阵归一化为相关矩阵。W,其中是与具有相同对角线的对角矩阵。这很简单,可以解决问题。这是 100,50,20,10,5,1一些示例相关矩阵:
和代码:
%// FACTOR method
function S = factor(d,k)
W = randn(d,k);
S = W*W' + diag(rand(1,d));
S = diag(1./sqrt(diag(S))) * S * diag(1./sqrt(diag(S)));
end
这是用于生成图形的包装代码:
d = 100; %// size of the correlation matrix
figure('Position', [100 100 1100 600])
for repetition = 1:6
S = onion(d);
%// etas = [1 10 100 1000 1e+4 1e+5];
%// S = extendedOnion(d, etas(repetition));
%// S = vine(d, etas(repetition));
%// betaparams = [50 20 10 5 2 1];
%// S = vineBeta(d, betaparams(repetition));
subplot(2,3,repetition)
%// use this to plot colormaps of S
imagesc(S, [-1 1])
axis square
title(['Eigs: ' num2str(min(eig(S)),2) '...' num2str(max(eig(S)),2) ', det=' num2str(det(S),2)])
%// use this to plot histograms of the off-diagonal elements
%// offd = S(logical(ones(size(S))-eye(size(S))));
%// hist(offd)
%// xlim([-1 1])
end
甚至更简单的特征是,对于实矩阵,是正半定的。要了解为什么会这样,只需证明所有向量(当然大小合适。这很简单:这是非负的。因此,在Matlab中,只需尝试甲Ť甲Ý Ť(甲Ť甲)ý ≥ 0 Ý Ý Ť(甲Ť甲)Ý = (甲Ý )Ť甲ÿ = | | 一个ÿ | |
A = randn(m,n); %here n is the desired size of the final matrix, and m > n
X = A' * A;
根据应用程序的不同,这可能无法为您提供所需的特征值分布。在这方面,郭某的答案要好得多。X
此代码段产生的特征值应遵循Marchenko-Pastur分布。
例如,要模拟股票的相关矩阵,您可能需要一个稍微不同的方法:
k = 7; % # of latent dimensions;
n = 100; % # of stocks;
A = 0.01 * randn(k,n); % 'hedgeable risk'
D = diag(0.001 * randn(n,1)); % 'idiosyncratic risk'
X = A'*A + D;
ascii_hist(eig(X)); % this is my own function, you do a hist(eig(X));
-Inf <= x < -0.001 : **************** (17)
-0.001 <= x < 0.001 : ************************************************** (53)
0.001 <= x < 0.002 : ******************** (21)
0.002 <= x < 0.004 : ** (2)
0.004 <= x < 0.005 : (0)
0.005 <= x < 0.007 : * (1)
0.007 <= x < 0.008 : * (1)
0.008 <= x < 0.009 : *** (3)
0.009 <= x < 0.011 : * (1)
0.011 <= x < Inf : * (1)
您尚未指定矩阵的分布。两种常见的是Wishart和逆Wishart分布。所述巴特利特分解给出了一个随机威沙特矩阵(其也可以有效地解决以获得随机逆矩阵威沙特)的乔列斯基因式分解。
实际上,Cholesky空间是生成其他类型的随机PSD矩阵的便捷方式,因为您只需确保对角线为非负数即可。
如果您想对生成的对称PSD矩阵进行更多控制,例如生成合成验证数据集,则可以使用许多参数。对称PSD矩阵对应于N维空间中的超椭圆,具有所有相关的自由度:
因此,对于二维矩阵(即2d椭圆),您将有1个旋转+ 2个轴= 3个参数。
figure;
mu = [0,0];
for i=1:16
subplot(4,4,i)
theta = (i/16)*2*pi; % theta = rand*2*pi;
U=[cos(theta), -sin(theta); sin(theta) cos(theta)];
% The diagonal's elements control the lengths of the axes
D = [10, 0; 0, 1]; % D = diag(rand(2,1));
sigma = U*D*U';
data = mvnrnd(mu,sigma,1000);
plot(data(:,1),data(:,2),'+'); axis([-6 6 -6 6]); hold on;
end
我用于测试的一种便宜而愉快的方法是生成m个N(0,1)n个向量V [k],然后使用P = d * I + Sum {V [k] * V [k]'}作为nxn psd矩阵。当m <n时,对于d = 0,它将是奇异的;对于小的d,它将具有高的条件数。