Chciałbym wygenerować losową macierz korelacji o wielkości n × n, tak aby występowały pewne umiarkowanie silne korelacje:
- kwadratowa rzeczywista macierz symetryczna o rozmiarze , np. n = 100 ;
- pozytywnie określone, tj. ze wszystkimi wartościami własnymi rzeczywistymi i dodatnimi;
- pełna ranga;
- wszystkie elementy ukośne równe ;
- elementy o przekątnej powinny być odpowiednio równomiernie rozmieszczone na . Dokładny rozkład nie ma znaczenia, ale chciałbym mieć jakąś umiarkowanie dużą ilość (np. 10 % ) umiarkowanie dużych wartości (np. O wartości bezwzględnej 0,5 lub wyższej). Zasadniczo chcę się upewnić, że C nie jest prawie przekątna ze wszystkimi elementami nie przekątnymi ≈ 0 .
Czy istnieje prosty sposób to zrobić?
Celem jest wykorzystanie takich losowych macierzy do porównania niektórych algorytmów pracujących z macierzami korelacji (lub kowariancji).
Metody, które nie działają
Oto kilka sposobów generowania losowych macierzy korelacji, o których wiem, ale które tutaj nie działają:
Wygeneruj losowy o rozmiarze s × n , wyśrodkuj, standaryzuj i utwórz macierz korelacji C = 1. Jeślis>n, spowoduje to na ogół, że wszystkie korelacje poza przekątną będą wynosić około0. Jeślis≪n, niektóre korelacje będą silne, aleCnie będzie pełnej rangi.
Wygeneruj losową dodatnią określoną macierz na jeden z następujących sposobów:
Wygeneruj losowy kwadrat i zrób symetryczny dodatni określony B = A A ⊤ .
Wygeneruj losowy kwadrat , zrób symetryczny E = A + A ⊤ i ustaw go jako dodatni, wykonując rozkład własny E = U S U ⊤ i ustawiając wszystkie ujemne wartości własne na zero: B = U . Uwaga: spowoduje to macierz z niedoborem rang.
Generuj losowy ortogonalny (np. Generując losowy kwadrat A i dokonując jego rozkładu QR lub w procesie Grama-Schmidta) i losową przekątną D ze wszystkimi dodatnimi elementami; forma B = Q D Q ⊤ .
Otrzymany macierz może być łatwo znormalizowane, aby wszystkie te diagonalne: C = D - 1 / 2 B D - 1 / 2 , gdzie D = d i g jest macierzą diagonalną o tej samej przekątnej jako B . Wszystkie trzy wymienione powyżej sposoby generowania B powodują,że C ma elementy o przekątnej zamkniętej 0 .
Aktualizacja: starsze wątki
Po opublikowaniu pytania znalazłem w przeszłości dwa prawie duplikaty:
- Jak wygenerować macierz losowej korelacji, która ma w przybliżeniu normalnie rozmieszczone wpisy o przekątnej przy danym odchyleniu standardowym?
- Jak efektywnie generować losowe macierze korelacji dodatnio-półpokrytych?
Niestety żaden z tych wątków nie zawiera satysfakcjonującej odpowiedzi (do tej pory :)
źródło
nXk
macierz ładującą W, nie w pełni losową, ale taką, jakiej chcemy (WW'+diag(noise)
zdefiniuje ona szukaną macierz kowariancji. Jedynym zadaniem jest poprawienie znormalizowanej kolumny W (tj. „wektory własne”), aby stać się ortogonalne. Każda metoda dekorelacji zmiennych skorelowanych (tutaj zmienne są wektorami własnymi) prawdopodobnie zrobi. (To surowy pomysł.)Odpowiedzi:
Inne odpowiedzi wymyśliły fajne sztuczki, aby rozwiązać mój problem na różne sposoby. Jednak znalazłem podejście oparte na zasadach, które moim zdaniem ma dużą zaletę, ponieważ jest koncepcyjnie bardzo jasne i łatwe do dostosowania.
W tym wątku: Jak efektywnie generować losowe macierze korelacji dodatnich i półkolistych? - Opisałem i podałem kod dwóch wydajnych algorytmów generowania macierzy losowej korelacji. Oba pochodzą z artykułu Lewandowskiego, Kurowickiej i Joe (2009), do którego @ssdecontrol przywołał w powyższych komentarzach (wielkie dzięki!).
Proszę zobaczyć moją odpowiedź tam dla wielu liczb, wyjaśnień i kodu Matlab. Tak zwana metoda „winorośli” pozwala na generowanie losowych macierzy korelacji z dowolnym rozkładem korelacji cząstkowych i może być stosowana do generowania macierzy korelacji o dużych wartościach nie przekątnych. Oto przykładowa postać z tego wątku:
Jedyną rzeczą, która zmienia się między wykresami podrzędnymi, jest jeden parametr, który kontroluje, o ile rozkład korelacji cząstkowych jest skoncentrowany wokół .± 1
Kopiuję mój kod, aby również wygenerować te macierze, aby pokazać, że nie jest on dłuższy niż inne sugerowane tutaj metody. Proszę zobaczyć moją linkowaną odpowiedź dla niektórych wyjaśnień. Wartości50 , 20 , 10 , 5 , 2 , 1 100
betaparam
powyższego rysunku wynosiły (a wymiarowość wynosiła 100 ).d
Aktualizacja: wartości własne
@psarka pyta o wartości własne tych matryc. Na poniższym rysunku wykreślam widma wartości własnych tych samych sześciu macierzy korelacji jak powyżej. Zauważ, że zmniejszają się stopniowo; przeciwnie, metoda sugerowana przez @psarka generalnie daje w wyniku macierz korelacji z jedną dużą wartością własną, ale reszta jest dość jednolita.
Aktualizacja. Naprawdę prosta metoda: kilka czynników
Oto kod:
źródło
W
są ortogonalne (tj. Cosinus między nimi wynosi 0). Po prostu generowanie losoweW
oczywiście tego nie zapewnia. Jeśli nie są one prostopadłe - czyli czynniki są skośne (call następnieW
jakoW_
) - czynnik twierdzenie nie jestWW'
jednakW_CW_'
zC
bycia „korelacji” (cosinus) pomiędzy czynnikami. TerazC=Q'Q
zQ
będąc nonorthogonal macierz obrotu obrotuW_=inv(Q)'W
(a więcW=W_Q'
). Wygeneruj trochęQ
- macierz z kolumną ss = 1 i macierz ss = rozmiar macierzy.W_=inv(Q)'W
oczywiście nieW_= W inv(Q)'
.W = replicate(k, rnorm(d)); S = W%*%t(W) + diag(rnorm(d),nrow=d); S = diag(1/sqrt(diag(S)))%*%S%*%diag(1/sqrt(diag(S)))
S <- matrix(nearPD(S, corr = TRUE, keepDiag = TRUE)$mat@x,ncol(S),ncol(S))
źródło
crs
Hmm, po zrobieniu przykładu w moim języku MatMate widzę, że istnieje już odpowiedź python, co może być preferowane, ponieważ python jest powszechnie używany. Ale ponieważ wciąż masz pytania, pokazuję ci moje podejście przy użyciu języka Matmate-Matrix, być może jest to bardziej samokomunikujące.
Metoda 1
(przy użyciu MatMate):
Problemem może być tutaj to, że definiujemy bloki podmacierzy, które mają wysokie korelacje wewnątrz, z małą korelacją między nimi, i to nie jest programowo, ale przez ciągłe wyrażenia konkatenacji. Być może to podejście można by modelować bardziej elegancko w Pythonie.
Metoda 2 (a)
Następnie istnieje zupełnie inne podejście, w którym wypełniamy możliwą pozostałą kowariancję losowymi ilościami 100 procent w macierzy ładunków czynnikowych. Odbywa się to w Pari / GP:
a wytworzoną macierzą korelacji jest
Być może generuje to macierz korelacji z dominującymi składnikami głównymi z powodu skumulowanej reguły generowania dla macierzy ładunków czynnikowych. Może być również lepiej zapewnić pozytywną definitywność, czyniąc ostatnią część wariancji unikalnym czynnikiem. Zostawiłem to w programie, aby skupić się na ogólnej zasadzie.
Macierz korelacji 100 x 100 miała następujące częstotliwości korelacji (w zaokrągleniu do 1 dec)
[aktualizacja]. Hmm, matryca 100 x 100 jest źle kondycjonowana; Pari / GP nie może poprawnie określić wartości własnych za pomocą polroots (charpoly ()) - funkcja nawet z dokładnością do 200 cyfr. Zrobiłem obrót Jacobiego, aby utworzyć formę pca na macierzy obciążeń L i znajdowałem głównie bardzo małe wartości własne, wydrukowałem je w logarytmach do podstawy 10 (które podają z grubsza pozycję punktu dziesiętnego). Czytaj od lewej do prawej, a następnie wiersz po rzędzie:
[aktualizacja 2]
Metoda 2 (b)
Ulepszenie może polegać na zwiększeniu wariancji specyficznej dla przedmiotu do pewnego nie-marginalnego poziomu i zredukowaniu do rozsądnie mniejszej liczby wspólnych czynników (na przykład liczba całkowita-kwadratowa numeru pozycji):
Struktura wyniku
pod względem rozkładu korelacji:
pozostaje podobny (również nieprzyjemny brak rozkładu przez PariGP), ale wartości własne, gdy zostały znalezione przez rotację jacobi macierzy loadings, mają teraz lepszą strukturę, dla nowo obliczonego przykładu otrzymałem wartości własne jako
źródło
źródło
R ma pakiet (klasterGeneration), który implementuje metodę w:
Przykład:
Niestety nie wydaje się możliwe symulowanie korelacji, które następują po tym rozkładzie równomiernym. Wydaje się, że silniej koreluje, kiedy
alphad
są ustawione na bardzo małe wartości, ale nawet przy1/100000000000000
tym zakres korelacji wzrósłby tylko do około 1,40.Niemniej jednak mam nadzieję, że może to komuś się przydać.
źródło