Як ефективно генерувати випадкові позитивні-семідефінітні кореляційні матриці?


38

Я хотів би мати можливість ефективно генерувати кореляційні матриці з позитивним семідефінітом (PSD). Мій метод різко сповільнюється, оскільки я збільшую розмір матриць, які потрібно генерувати.

  1. Чи можете ви запропонувати якісь ефективні рішення? Якщо вам відомі будь-які приклади в Matlab, я буду дуже вдячний.
  2. Коли ви генеруєте кореляційну матрицю PSD, як би ви вибрали параметри для опису матриць, які потрібно створити? Середня кореляція, стандартне відхилення кореляцій, власні значення?

Відповіді:


16

Ви можете зробити це назад: кожну матрицю (набір усіх симетричних матриць PSD p × p ) можна розкласти якСR++pp×p

де O - ортонормальна матрицяС=ОТDОО

Щоб отримати , спочатку генерувати випадковий базис ( V 1 , . . . , V р ) (де v я випадкові вектори, як правило , в ( - 1 , 1 ) ). Звідти, використовувати процес ортогоналізації Грама-Шмідта , щоб отримати ( у 1 , . . . . , У р ) = ПроО(v1,...,vp)vi(-1,1)(у1,....,уp)=О

має ряд пакетів, які можуть зробити ортогоналізацію GS випадковою основою ефективно, тобто навіть для великих розмірів, наприклад, "далекий" пакет. Хоча ви знайдете алгоритм GS на wiki, напевно, краще не вигадувати колесо і не піти на реалізацію matlab (одна, безумовно, існує, я просто не можу рекомендувати жодного).R

Нарешті, - діагональні матриці, елементи яких усі позитивні (це, знову ж таки, легко генерувати: генерувати p випадкові числа, квадратувати їх, сортувати їх та розміщувати до діагоналі тотожності p за матрицею p ).Dppp


3
(1) Зауважте, що отриманий не буде кореляційною матрицею (як цього вимагає ОП), оскільки не буде таких на діагоналі. Звичайно , це може бути перераховані , щоб ті , на діагоналі, встановивши його на Е - 1 / 2 C E - +1 / +2 , де E являє собою діагональну матрицю з тієї ж діагоналі , як C . (2) Якщо я не помиляюся, це призведе до кореляційних матриць, де всі недіагональні елементи зосереджені навколо 0 , тому немає гнучкості, яку шукав ОП (ОП хотів мати можливість встановити "середню кореляцію , стандартне відхилення кореляцій, власних значень "CE1/2CE1/2EC0)
амеба каже, що повернеться Моніка

@amoeba: Я звернуся до (2), оскільки, як ви зазначаєте, рішення (1) є тривіальним. Характеристика 'форми' (співвідношення між діагональними елементами в і поза) матриці PSD (і, отже, коваріації, а також кореляційної матриці) є її номером умови. І, описаний вище метод дозволяє повністю контролювати це. "Концентрація відключених діагональних елементів навколо 0" не є особливістю методу, що використовується для генерування матриць PSD, а, скоріше, наслідком обмежень, необхідних для забезпечення матриці PSD та факту великим. p
user603

Ви хочете сказати, що всі великі матриці PSD мають недіагональні елементи, близькі до нуля? Я не згоден, це не так. Ознайомтесь з моєю відповіддю на кілька прикладів: Як генерувати випадкову матрицю кореляції, яка має приблизно нормально розподілені позадіагональні записи із заданим стандартним відхиленням? Але безпосередньо можна побачити, що це не так, оскільки квадратна матриця, що має всі діагоналі та фіксоване значення скрізь поза діагоналі, є PSD, а ρ може бути довільно великим (але, звичайно, нижче 1 ). ρρ1
Амеба каже: Відновити Моніку

@amoeba: тоді я помилявся, вважаючи, що за необхідності діагональ вимкнення великих кореляційних матриць, коли їм дозволяється бути як позитивними, так і негативними, близька до 0. Дякую за просвічуючий приклад.
user603

1
Я прочитав дуже приємний документ про генерування випадкових матриць кореляції та надав тут свою власну відповідь (а також іншу відповідь у тій зв’язаній темі). Я думаю, вам це може бути цікавим.
Амеба каже: Відновити Моніку

27

Документ , що генерує випадкові кореляційні матриці на основі лоз та методу розширеного лука, зроблені Левандовським, Куровіккою та Джо (LKJ), 2009, забезпечує уніфіковану обробку та експозицію двох ефективних методів генерації випадкових кореляційних матриць. Обидва способи дозволяють генерувати матриці з рівномірного розподілу в певному точному значенні, визначеному нижче, прості у здійсненні, швидкі та мають додаткову перевагу від забавних імен.

Справжня симетрична матриця розміром з діагоналлю має d ( d - 1 ) / 2 унікальних позадіагональних елементів і тому може бути параметризована як точка в R d ( d - 1 ) / 2 . Кожна точка в цьому просторі відповідає симетричній матриці, але не всі вони є позитивно визначеними (як мають бути кореляційні матриці). Отже, кореляційні матриці утворюють підмножину R d ( d - 1 ) / 2г×гг(г-1)/2Rг(г-1)/2Rг(г-1)/2 (фактично підключений опуклий підмножина), і обидва способи можуть генерувати точки з рівномірного розподілу по цій підмножині.

Я забезпечу власну реалізацію кожного методу MATLAB і проілюструю їх .г=100


Цибульний метод

Метод цибулі походить з іншого паперу (посилання №3 в LKJ) і належить його назві тому, що генеруються кореляційні матриці, починаючи з матриці і збільшуючи її стовпцем за стовпцем та рядком за рядком. Результат розподілу рівномірний. Я не дуже розумію математику за методом (і все одно віддаю перевагу другому методу), але ось результат: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 e tС . Чим більший η , тим більшим буде визначник, тобто генеровані кореляційні матриці все більше і більше наближаються до матриці ідентичності. Значення η = 1 відповідає рівномірному розподілу. На малюнку нижче матриці формуються з η = 1 , 10 , 100 , 1000 , 10[гетС]η-1ηη=1 .η=1,10,100,1000,10000,100000

Розширений метод цибулі

Чомусь для отримання визначника того ж порядку величини, що і у методі цибулі ванілі, мені потрібно поставити а не η = 1 (як стверджує 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

Виноградний метод

Спочатку метод лози був запропонований Джо (J в LKJ) і вдосконалений LKJ. Мені це подобається більше, тому що це концептуально простіше, а також простіше змінювати. Ідея полягає у створенні часткових кореляцій (вони незалежні і можуть мати будь-які значення з [ - 1 , 1 ]г(г-1)/2[-1,1]без будь-яких обмежень), а потім перетворити їх у необроблені кореляції за допомогою рекурсивної формули. Зручно організувати обчислення в певному порядку, і цей графік відомий як "лоза". Важливо, якщо часткові кореляції відібрані з конкретних бета-розподілів (різних для різних клітин у матриці), то отримана матриця розподілиться рівномірно. Тут знову ж таки LKJ вводить додатковий параметр для вибірки з розподілу, пропорційного [ d e tη . Результат ідентичний розширеній цибулі:[гетС]η-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

Виноградний метод з ручним відбором часткових кореляцій

±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

Ось як шукають гістограми позадіагональних елементів для матриць вище (дисперсія розподілу монотонно зростає):

Позадіагональні елементи


Оновлення: використання випадкових факторів

к<гWк×гWWDБ=WW+DС=Е-1/2БЕ-1/2ЕБк=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
Це фантастичний пробіг, я радий, що я щось сказав!
тіньтакер

Коли я перекладав код matlab для матриці кореляції на основі лози в R і перевіряв його, щільність кореляцій у колонці 1 завжди відрізнялася від пізніших стовпців. Можливо, я щось неправильно переклав, але, можливо, ця примітка комусь допомагає.
Чарлі

3
Для користувачів R функція rcorrmatrix в пакеті clusterGeneration (написана W Qui та H. Joe) реалізує метод винограду.
RNM

15

ААТАуТ(АТА)у0ууТ(АТА)у=(Ау)ТАу=||Ау||що є негативним. Тож у Matlab просто спробуйте

A = randn(m,n);   %here n is the desired size of the final matrix, and m > n
X = A' * A;

Залежно від програми, це може не дати вам розподілу власних значень, які ви хочете; Відповідь Квака в цьому плані набагато краща. Власні значення, Xвироблені цим фрагментом коду, повинні відповідати розподілу Марченко-Пастур.

Скажімо, для моделювання кореляційних матриць запасів, можливо, ви хочете дещо інший підхід:

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

@btown маржа занадто мала, щоб її містити!
shabbychef

1
уТ(АТА)у=(Ау)ТАу=||Ау||

8

DА=QDQТQ


М.: Хороша довідка: це, здається, є найбільш ефективним рішенням (асимптотично).
whuber

3
@whuber: Хе, я забрав це у Голуба та Ван Позики (звичайно); Я використовую це весь час, щоб допомогти у створенні тестових матриць для рутинних тестувань власного значення / сингулярного значення. Як видно з статті, вона по суті еквівалентна QR-декомпозиції випадкової матриці на зразок того, що запропонував kwak, за винятком того, що це робиться більш ефективно. Існує реалізація цього MATLAB в Панелі інструментів текстової матриці Хігема, BTW.
JM не є статистиком

М .:> Дякую за реалізацію matlab. Чи дізнаєтесь ви про випадковий генератор псевдовипадкових матриць Хаара в R?
користувач603

@kwak: Немає ідеї, але якщо ще немає реалізації, це не повинно бути занадто важким для перекладу коду MATLAB в R (я можу спробувати збити його, якщо насправді його немає); Єдина необхідна умова - гідний генератор для псевдовипадкових нормальних змінних, який, я впевнений, має R.
JM не є статистиком

М .:> так, я, мабуть, перекладу це сам. Дякую за посилання, Найкраще.
user603

4

Ви не вказали розподіл для матриць. Два поширених - розподіл Вішарта та зворотний розподіл Вішарта. Розкладання Бартлетта дає Холецкого факторизации матриці випадкових Уішарт (які також можуть бути ефективно вирішені , щоб отримати випадкову зворотний Уішарт матрицю).

Насправді простір Чолеського - це зручний спосіб генерування інших типів випадкових матриць PSD, оскільки вам потрібно лише переконатися, що діагональ невід’ємна.


> Не випадково: дві матриці, сформовані від одного і того ж Whishard, не будуть незалежними одна від одної. Якщо ви плануєте змінити Whishart у кожному поколінні, то як ви збираєтесь створити ці Whishart в першу чергу?
user603

@kwak: Я не розумію вашого запитання: розпад Бартлетта дасть незалежні малюнки від того ж розподілу Вішарта.
Simon Byrne

> Дозвольте перефразувати це, звідки ви берете матрицю масштабу вашого розподілу whhart?
user603

1
@kwak: це параметр розподілу, і так виправлено. Ви вибираєте його на початку, виходячи з бажаних характеристик вашого розподілу (наприклад, середньої).
Саймон Берн

3

UТSU


Якщо записи генеруються із звичайного розподілу, а не рівномірного, розклад, який ви згадуєте, повинен бути SO (n) інваріантним (і, отже, рівнорозподіленим відносно міри Хаара).
whuber

Цікаво. Чи можете ви надати посилання на це?
гаппі

1
> Проблема цього методу полягає в тому, що ви не можете контролювати співвідношення найменшого до найбільшого власного значення (і я думаю, що оскільки розмір вашого випадково сформованого набору даних переходить до нескінченності, це співвідношення зблизиться до 1).
user603

1

Якщо ви хочете мати більше контролю над сформованою симетричною матрицею PSD, наприклад, генерувати набір даних синтетичної перевірки, у вас є ряд параметрів. Симетрична матриця PSD відповідає гіпер-еліпсу в N-мірному просторі з усіма пов'язаними ступенями свободи:

  1. Обертання.
  2. Довжини осей.

Отже, для двовимірної матриці (тобто 2d еліпса) у вас буде 1 обертання + 2 осі = 3 параметри.

Σ=ОDОТΣОD

Σ

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 + суму {V [k] * V [k] '} як матриця nxn psd. З m <n це буде сингулярно для d = 0, а для малого d матиме високе число умови.


2
> Проблема цього методу полягає в тому, що ви не можете контролювати співвідношення найменшого до найбільшого власного значення (і я думаю, що оскільки розмір вашого випадково сформованого набору даних переходить до нескінченності, це співвідношення зблизиться до 1).
user603

> окрім того, метод не дуже ефективний (з обчислювальної точки зору)
user603

1
Ваша "випадкова матриця" - це спеціально структурована назва, яка називається "діагональна плюс матриця рангу-1" (матриця DR1), тому насправді не є доброю репрезентативною випадковою матрицею.
JM не є статистиком
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.