如何有效地生成随机正-半正相关矩阵?


38

我希望能够有效地生成正半定(PSD)相关矩阵。随着我增加要生成的矩阵的大小,我的方法大大降低了速度。

  1. 您能提出任何有效的解决方案吗?如果您知道Matlab中的任何示例,我将非常感谢。
  2. 生成PSD相关矩阵时,如何选择参数来描述要生成的矩阵?平均相关性,相关性的标准偏差,特征值?

Answers:


16

您可以向后执行此操作:每个矩阵 (所有对称 PSD矩阵的集合)都可以分解为 p × pCR++pp×p

OC=OTDO其中是正交矩阵O

为了获得,首先生成一个随机基(其中是随机向量,通常在)。从那里开始,使用Gram-Schmidt正交化过程获得v 1v pv - 1 1 Ú 1Ù p= ÕO(v1,...,vp)vi(1,1)(u1,....,up)=O

R具有许多可以有效地随机进行GS正交化的包,甚至对于较大尺寸的包,例如“远”包。尽管您会在Wiki上找到GS算法,但最好不要重新发明轮子并进行Matlab实现(肯定存在,我不能推荐任何一种)。

最后,是一个对角矩阵,其元素都是正数(这又很容易生成:生成随机数,对其进行平方,对其进行排序,然后通过矩阵将它们放置在同一性的对角线上)。p p pDppp


3
(1)请注意,结果将不是相关矩阵(按OP的要求),因为对角线上不会有1。当然,通过将其设置为,可以将其重新缩放为在对角线上有一个,其中是与对角线相同的对角矩阵。(2)如果我没记错的话,这将导致相关矩阵,其中所有非对角线元素都集中在附近,因此OP一直在寻找灵活性(OP希望能够设置“平均相关,相关性的标准差,特征值”E - 1 / 2 C E - 1 / 2 E C 0CE1/2CE1/2EC0
变形虫说莫妮卡(Monica

@amoeba:我将指出(2),因为正如您所指出的,(1)的解决方案很简单。PSD矩阵的“形状”(即对角元素的内外关系)的一个数字表征(因此是协方差以及相关矩阵)是其条件数。并且,上述方法允许对其进行完全控制。“非对角线元素在0附近的集中度”不是用于生成PSD矩阵的方法的特征,而是确保矩阵为PSD所需的约束条件和大的事实的结果。p
user603 2014年

您是说所有大型PSD矩阵的对角线元素都接近于零吗?我不同意,事实并非如此。在这里查看我的答案以获取一些示例:如何生成随机相关矩阵,该矩阵具有近似正态分布的非对角线项,且具有给定的标准偏差?但是人们可以直接看到情况并非如此,因为对角线上所有的对角线上都有一个固定值方阵是PSD,并且可以任意大(但当然小于)。ρ 1ρρ1
变形虫说恢复莫妮卡2014年

@amoeba:当时我认为,大的相关矩阵的正对角线和负向线的斜对角线都接近于0时,我认为是错误的。感谢启发性的示例。
user603 2014年

1
我阅读了一篇有关生成随机相关矩阵的非常好的论文,并在此提供了自己的答案(以及该链接线程中的另一个答案)。我认为您可能会发现它很有趣。
变形虫说恢复莫妮卡2014年

27

Lewandowski,Kurowicka和Joe(LKJ)在2009年发表了一篇基于藤本植物和扩展洋葱方法生成随机相关矩阵的论文,对生成随机相关矩阵的两种有效方法进行了统一处理和阐述。两种方法都可以下面定义的某种精确意义上的均匀分布中生成矩阵,实现简单,快速,并具有使用有趣名称的附加优点。

大小的实对称矩阵在对角线上有唯一的非对角元素,因此可以将其参数化为。该空间中的每个点都对应一个对称矩阵,但并不是所有的点都是正定的(因为必须要有相关矩阵)。因此,相关矩阵形成子集(实际上是一个连接的凸子集),并且两种方法都可以根据该子集上的均匀分布生成点。d d - 1 / 2 R d d - 1 / 2 R d d - 1 / 2d×dd(d1)/2Rd(d1)/2Rd(d1)/2

我将为每种方法提供自己的MATLAB实现,并用。d=100


洋葱法

洋葱方法来自另一篇论文(LKJ中的参考文献#3),并以其相关矩阵从矩阵开始并逐列和逐行增长的事实而得名。结果分布是均匀的。我不太了解该方法背后的数学原理(无论如何还是更喜欢第二种方法),但是结果如下:1×1

洋葱法

在每个子图的标题下方和下方显示了最小和最大的特征值,以及行列式(所有特征值的乘积)。这是代码:

%// 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 ë C η η = 1 η = 1 10 100 1000 10[detC]η1ηη=1η=1,10,100,1000,10000,100000

扩展洋葱法

由于某种原因,要获得与香草洋葱方法相同数量级的行列式,我需要输入而不是(如LKJ所述)。不知道错误在哪里。η=0η=1

%// 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再次在此处引入一个附加参数以从与d(d1)/2[1,1]η[detC]η1。结果与扩展洋葱相同:

藤蔓法

%// 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分布的参数越小,它越集中在边缘附近。±1[0,1][1,1]α=β=50,20,10,5,2,1

藤蔓方法与手动采样

请注意,在这种情况下,不能保证该分布是置换不变的,因此我在生成后还随机置换了行和列。

%// 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的答案中使用了一种非常简单的方法来生成具有一些强相关性的随机相关矩阵,我也想在这里进行说明。这个想法是随机生成几个()因子负载(随机矩阵大小),形成协方差矩阵(当然这不会是满秩的) )并添加一个带有对正元素的随机对角矩阵,使满秩。通过使,可以将所得的协方差矩阵归一化为相关矩阵。Wk<dWk×dWWDB=WW+DC=E1/2BE1/2,其中是与具有相同对角线的对角矩阵。这很简单,可以解决问题。这是 100,50,20,10,5,1一些示例相关矩阵:EBk=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

2
这真是一个了不起的失败,我很高兴我说了什么!
shadowtalker 2014年

当我将基于葡萄树的相关矩阵的matlab代码转换为R并进行测试时,第1列中的相关密度始终与后面的列不同。可能是我翻译不正确,但此注释可能对某人有所帮助。
查理

3
对于R用户,程序包clusterGeneration(由W Qui和H. Joe编写)中的rcorrmatrix函数实现了vine方法。
RNM

14

甚至更简单的特征是,对于实矩阵,是正半定的。要了解为什么会这样,只需证明所有向量(当然大小合适。这很简单:这是非负的。因此,在Matlab中,只需尝试ŤÝ ŤŤý 0 Ý Ý ŤŤÝ = Ý Ťÿ = | | 一个ÿ | |AATAyT(ATA)y0yyT(ATA)y=(Ay)TAy=||Ay||

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)

1
您是否愿意分享您的ascii_hist函数?
btown 2011年

@btown的边距太小而无法容纳它!
shabbychef 2011年

1
yT(ATA)y=(Ay)TAy=||Ay||

8

DA=QDQTQ


M .:很好的参考:这似乎是最有效的解决方案(渐近地)。
ub

3
@whuber:呵呵,我是从Golub和Van Loan(当然)那里拿来的;我一直使用它来帮助生成用于压力测试特征值/奇异值例程的测试矩阵。从论文中可以看出,它基本上等效于QR分解kwak所建议的随机矩阵,只是它的执行效率更高。Higham的文本矩阵工具箱BTW中有一个MATLAB实现。
JM不是统计学家

M。:>感谢您的Matlab实现。您是否有机会知道R中的Haar伪随机矩阵生成器?
user603 2010年

@kwak:不知道,但是如果还没有实现,那么将MATLAB代码转换为R也不应该太难(如果真的没有,我可以试一试);唯一的先决条件是伪随机正态变量的体面生成器,我敢肯定R具有。
JM不是统计学家

M。:>是的,我可能会自己翻译一下。感谢您的链接,最好。
user603 2010年

4

您尚未指定矩阵的分布。两种常见的是Wishart和逆Wishart分布。所述巴特利特分解给出了一个随机威沙特矩阵(其也可以有效地解决以获得随机逆矩阵威沙特)的乔列斯基因式分解。

实际上,Cholesky空间是生成其他类型的随机PSD矩阵的便捷方式,因为您只需确保对角线为非负数即可。


>不是随机的:从同一个Whishard生成的两个矩阵将不会彼此独立。如果您打算在每一代更换Whishart,那么您打算如何首先生成这些Whishart?
user603 2010年

@kwak:我不明白您的问题:Bartlett分解将根据相同的Wishart分布进行独立绘制。
西蒙·伯恩

>让我重新说明一下,您从哪里获得whishart分布的比例矩阵?
user603 2010年

1
@kwak:这是分布的参数,因此是固定的。您可以根据分布的期望特征(例如均值)在开始时选择它。
西蒙·伯恩

3

UTSU


如果条目是从正态分布而不是均匀分布生成的,则您提到的分解应该是SO(n)不变的(因此相对于Haar测度是均匀分布的)。
ub

有趣。您可以为此提供参考吗?
gappy 2010年

1
>这种方法的问题是您无法控制最小特征值与最大特征值的比率(我认为随着随机生成的数据集的大小变为无穷大,该比率将收敛为1)。
user603 2010年

1

如果您想对生成的对称PSD矩阵进行更多控制,例如生成合成验证数据集,则可以使用许多参数。对称PSD矩阵对应于N维空间中的超椭圆,具有所有相关的自由度:

  1. 旋转。
  2. 轴的长度。

因此,对于二维矩阵(即2d椭圆),您将有1个旋转+ 2个轴= 3个参数。

Σ=ODOTΣOD

Σ

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

U


0

我用于测试的一种便宜而愉快的方法是生成m个N(0,1)n个向量V [k],然后使用P = d * I + Sum {V [k] * V [k]'}作为nxn psd矩阵。当m <n时,对于d = 0,它将是奇异的;对于小的d,它将具有高的条件数。


2
>这种方法的问题是您无法控制最小特征值与最大特征值的比率(我认为随着随机生成的数据集的大小变为无穷大,该比率将收敛为1)。
user603 2010年

>此外,该方法不是非常有效(从计算角度来看)
user603 2010年

1
您的“随机矩阵”是一种特殊的结构,称为“对角加秩1矩阵”(DR1矩阵),因此并不是一个很好的代表性随机矩阵。
JM不是统计学家
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.