Dla badań symulacyjnych mam do generowania zmiennych losowych, które wykazują prefined (populacji) korelację do istniejącej zmiennej .
I spojrzał w R
opakowaniach copula
, a CDVine
które mogą powodować przypadkowe wielowymiarowych rozkładów danej struktury zależności. Nie można jednak naprawić jednej z powstałych zmiennych do istniejącej zmiennej.
Wszelkie pomysły i linki do istniejących funkcji są mile widziane!
Wniosek: pojawiły się dwie ważne odpowiedzi, z różnymi rozwiązaniami:
R
Scenariusz według caracal, co wylicza zmienną losową z dokładnym (próbki) korelacji ustalonej zmiennejR
Funkcja znalazłem się, co wylicza zmienną losową o określonej populacji korelacji do predefiniowanej zmiennej
[Dodanie @ttnphns: Zezwoliłem na rozszerzenie tytułu pytania z pojedynczej stałej zmiennej na dowolną liczbę stałych zmiennych; tj. jak wygenerować zmienną mającą predefiniowane korelacje z pewnymi stałymi, istniejącymi zmiennymi]
r
correlation
random-variable
random-generation
independence
assumptions
random-variable
unbiased-estimator
regression
hypothesis-testing
heteroscedasticity
generalized-least-squares
distributions
networks
data-visualization
sas
reproducible-research
philosophical
time-series
variance
outliers
quality-control
mean
multilevel-analysis
average
weighted-mean
regression
confidence-interval
prediction-interval
correlation
matlab
matrix
data-mining
maximum-likelihood
r
time-series
survival
predictive-models
Felix S.
źródło
źródło
Odpowiedzi:
Oto kolejny: dla wektorów ze średnią 0 ich korelacja jest równa cosinus ich kąta. Zatem jednym sposobem na znalezienie wektora o dokładnie pożądanej korelacji , odpowiadającej kątowi :r θx r θ
Oto kod:
Na rzut prostopadły , to używany Q R -decomposition poprawić stabilność liczbową, gdyż wtedy po prostu P = Q, Q ' .P. Q R. P.= Q Q′
źródło
P <- X %*% solve(t(X) %*% X) %*% t(X)
nie produkuje r = 0,6, więc to nie jest obejście. Wciąż jestem zdezorientowany. (Z przyjemnością naśladuję twój wyrazQ <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))
w SPSS, ale nie wiem jak.)Xctr[ , 1] %*% solve(t(Xctr[ , 1]) %*% Xctr[ , 1]) %*% t(Xctr[ , 1])
Xctr
rho=1
uznałem za użyteczne zrobić coś takiego:if (isTRUE(all.equal(rho, 1))) rho <- 1-10*.Machine$double.eps
w przeciwnym razie dostawałemNaN
sOpiszę najogólniejsze możliwe rozwiązanie. Rozwiązanie problemu w tej ogólności pozwala nam osiągnąć niezwykle kompaktową implementację oprogramowania: wystarczy tylko dwie krótkie linie
R
kodu.Wybierz wektor o tej samej długości co , zgodnie z dowolnym rozkładem. Niech być pozostałości z regresji metodą najmniejszych kwadratów z z : ten wyodrębnia elementu z . Przez ponowne dodanie odpowiedniego wielokrotność do możemy wytworzenia wektora posiadającego dowolną korelacji z . Rozwiązaniem jest dowolna dowolna stała addytywna i dodatnia stała mnożąca - którą możesz dowolnie wybraćY Y ⊥ X Y Y X Y Y ⊥ ρ YX Y Y⊥ X Y Y X Y Y⊥ ρ Y
(„ nazwa ” oznacza wszelkie obliczenia proporcjonalne do odchylenia standardowego.)SD
Oto działającyX
R
kod. Jeśli nie podasz , kod pobierze swoje wartości ze standardowego rozkładu normalnego na wielu odmianach.W celu zilustrowania, że generowane losowo z elementów, a wytwarzane o różnych określonych korelacji z tym . Wszystkie zostały utworzone przy użyciu tego samego wektora początkowego . Oto ich wykresy rozrzutu. „Wykresy rugowe” u dołu każdego panelu pokazują wspólny wektor50 X Y ; ρ Y X = ( 1 , 2 , … , 50 ) YY 50 XY;ρ Y X=(1,2,…,50) Y
Istnieje niezwykłe podobieństwo między fabułami, czyż nie :-).
Jeśli chcesz eksperymentować, oto kod, który wygenerował te dane i rysunek. (Nie zawracałem sobie głowy skorzystaniem ze swobody, aby przesuwać i skalować wyniki, które są łatwymi operacjami).
BTW, ta metoda z łatwością uogólnia na więcej niż jedno : jeśli jest to matematycznie możliwe, znajdzie po określeniu korelacji z całością zestaw . Wystarczy użyć zwykłych najmniejszych kwadratów, aby wyjąć efekty wszystkich z i utworzyć odpowiednią liniową kombinację i reszt. (Pomaga to zrobić w kategoriach podwójnej podstawy dla , która jest uzyskiwana przez obliczenie pseudo-odwrotności. Poniższy kod używa SVD dla osiągnięcia tego.)X Y 1 , Y 2 , … , Y k ; ρ 1 , ρ 2 , … , ρ k Y i Y i X Y i Y YY XY1,Y2,…,Yk;ρ1,ρ2,…,ρk Yi Yi X Yi Y Y
Oto szkic algorytmu, wYi
R
którym są podane jako kolumny macierzy :y
Poniżej znajduje się pełniejsza implementacja dla tych, którzy chcieliby eksperymentować.
źródło
BTW, this method readily generalizes to more... Just use ordinary least squares... and form a suitable linear combination
x
i chcę wygenerować nowy wektory
skorelowany z,x
ale także chcę, abyy
wektor był równomiernie rozłożony.Oto inne podejście obliczeniowe (rozwiązanie zostało zaadaptowane z postu na forum Enrico Schumanna). Według Wolfganga (patrz komentarze) jest to obliczeniowo identyczne z rozwiązaniem zaproponowanym przez ttnphns.
W przeciwieństwie do rozwiązania karakala nie wytwarza próbki o dokładnej korelacji , ale dwa wektory, których korelacja populacji jest równa .ρρ ρ
Poniższa funkcja może obliczyć dwuwymiarowy rozkład próbek pobranych z populacji o danym . Oblicza dwie zmienne losowe lub pobiera jedną istniejącą zmienną (przekazaną jako parametr ) i tworzy drugą zmienną o pożądanej korelacji:ρ
x
Funkcja może również wykorzystywać niestandardowe rozkłady brzeżne poprzez dostosowanie parametru
mar.fun
. Należy jednak pamiętać, że ustalenie jednej zmiennej tylko wydaje się działać z zmiennej o rozkładzie normalnymx
! (co może odnosić się do komentarza Makra).Należy również zauważyć, że „mały współczynnik korygujący” z pierwotnego postu został usunięty, ponieważ wydaje się, że przesądza powstałe korelacje, przynajmniej w przypadku rozkładów Gaussa i korelacji Pearsona (patrz także komentarze).
źródło
rho
.X2 <- mar.fun(n)
doX2 <- mar.fun(n,mean(x),sd(x))
zdobycia pożądanego korelację między x1 i x2Zaktualizuj 11 listopada 2017 r. Dzisiaj spotkałem ten stary wątek i postanowiłem rozszerzyć moją odpowiedź, pokazując algorytm iteracyjnego dopasowania, o którym mówiłem na początku.
Disclamer: To iteracyjne rozwiązanie, które znalazłem gorsze od doskonałego, oparte na znalezieniu podwójnej podstawy i zaproponowane przez @whuber w tym wątku dzisiaj. @ rozwiązanie Whubera nie jest iteracyjne i, co ważniejsze, wydaje mi się, że wpływa na wartości wejściowej zmiennej „świnia” nieco mniej niż algorytm „mój” (byłoby to atutem, gdyby zadaniem było „poprawić” istniejąca zmienna i nie generować losowych zmiennych od zera). Nadal publikuję moje z ciekawości i dlatego, że to działa (patrz także przypis).
(mianownik nie zmienia się w iteracjach, oblicz go wcześniej)
źródło
Miałem ochotę trochę programować, więc wziąłem usuniętą odpowiedź @ Adama i postanowiłem napisać fajną implementację w języku R. Skupiam się na używaniu stylu zorientowanego funkcjonalnie (tj. Pętli stylu lapply). Ogólna idea polega na pobraniu dwóch wektorów, losowym permutacji jednego z wektorów, dopóki nie zostanie osiągnięta pewna korelacja między nimi. To podejście jest bardzo brutalne, ale łatwe do wdrożenia.
Najpierw tworzymy funkcję, która losowo permutuje wektor wejściowy:
... i utwórz przykładowe dane
... napisz funkcję, która permutuje wektor wejściowy i koreluje go z wektorem referencyjnym:
... i iteruj tysiąc razy:
Zauważ, że reguły określania zakresu R zapewniają
vec1
ivec2
znajdują się w środowisku globalnym, poza anonimową funkcją używaną powyżej. Zatem permutacje są względne w stosunku do oryginalnych zestawów danych testowych, które wygenerowaliśmy.Następnie znajdujemy maksymalną korelację:
... lub znajdź wartość najbliższą korelacji 0,2:
Aby uzyskać wyższą korelację, musisz zwiększyć liczbę iteracji.
źródło
Rozwiązanie:
Kod Python:
Wyjście testowe:
źródło
Wygeneruj zmienne normalne z podaną macierzą kowariancji SAMPLING
Wygeneruj zmienne normalne z podaną macierzą kowariancji LUDNOŚCI
źródło
Po prostu utwórz losowy wektor i sortuj, aż uzyskasz pożądane r.
źródło