Fråga:
Hur genererar jag korrelerade slumptal (angivna medel, avvikelser och korrelationsgrad)?
Joseph Weissman
2012-10-08 00:45:21 UTC
view on stackexchange narkive permalink

Jag är ledsen om det här verkar lite för grundläggande, men jag antar att jag bara vill bekräfta förståelsen här. Jag förstår att jag måste göra detta i två steg och jag har börjat försöka samla korrelationsmatriser, men det börjar bara verka riktigt involverat. Jag letar efter en kortfattad förklaring (helst med tips mot en pseudokodslösning) av ett bra, idealiskt snabbt sätt att generera korrelerade slumptal.

Med tanke på två pseudorandom-variabler höjd och vikt med kända medel och avvikelser, och en given korrelation, tror jag att jag i grunden försöker förstå hur detta andra steg ska se ut:

  height = gaussianPdf (height.mean, height.variance) weight = gaussianPdf (correlated_mean (height.mean, correlation_coefficient), correlated_variance (height.variance, correlation_coefficient))  
  • Hur beräknar jag det korrelerade medelvärdet och variansen? Men jag vill bekräfta att det verkligen är det relevanta problemet här.
  • Behöver jag tillgripa matrismanipulation? Eller har jag något annat mycket fel i mitt grundläggande förhållningssätt till detta problem?
Inte säker på att jag förstår dig rätt, men du behöver inte beräkna "korrelerat medelvärde och varians". Om du antar att variablerna är bivariata normala, borde det vara tillräckligt att ange de individuella medel och avvikelser och korrelationen. Finns det någon speciell programvara som du vill använda för detta?
Följande frågor är starkt relaterade och kommer att vara av intresse: [Hur man definierar en sådan distribution som drar från den korrelerar med en dragning från en annan förutbestämd distribution?] (Http://stats.stackexchange.com/questions/13382/ ) & [Generera en slumpmässig variabel med en definierad korrelation till en befintlig variabel] (http://stats.stackexchange.com/questions/15011/).
Dessutom: [Hur kan jag generera data med en förutbestämd korrelationsmatris?] (Http://stats.stackexchange.com/questions/32169/)
Fyra svar:
usεr11852
2012-10-08 01:29:03 UTC
view on stackexchange narkive permalink

För att svara på din fråga om "ett bra, idealiskt snabbt sätt att generera korrelerade slumptal": Med tanke på en önskad varians-kovariansmatris $ C $ som per definition är positiv, är Cholesky sönderdelning av den: $ C $ = $ LL ^ T $; $ L $ är lägre triangulär matris.

Om du nu använder denna matris $ L $ för att projicera en okorrelerad slumpmässig variabelvektor $ X $ blir den resulterande projektionen $ Y = LX $ den för korrelerade slumpmässiga variabler.

Du kan hitta en kortfattad förklaring till varför detta händer här.

Tack! Detta var oerhört hjälpsamt. Jag tror att jag åtminstone har en bättre känsla av vad jag behöver titta på nästa.
Gäller den här metoden endast för Gaussiska distributioner (som anges i frågan), eller kan den användas för att generera korrelerade variabler som följer andra distributioner? Om inte, är du medveten om en metod som kan användas i så fall?
Fungerar det också om jag tar någon $ L $ * inte nödvändigtvis triangulär men tillfredsställande $ C = LL ^ T $?
@Michael: Ja.Med det sagt att med tanke på $ C $ är en giltig kovariansmatris, är Cholesky-nedbrytningen det snabbaste sättet.Du kan också få (symmetrisk) kvadratrot $ X $ matris på $ C $ med SVD (så $ C = XX = XX ^ T $, där $ X = US ^ {0.5} V ^ T $ från $ C = USV ^ T $)men det skulle också bli dyrare.
Tack.Och när jag använder två olika matriser som uppfyller villkoret, låt oss säga att $ L_1 $ är Cholesky-nedbrytningen, och $ L_2 $ är kvadratroten på $ C $, som finns sedan $ C \ geq 0 $, också $ L_2 = L_2^ T $ sedan $ L_2L_2 = L_2L_2 ^ T = C $, jag får $ Y_1 = L_1X $ och $ Y_2 = L_2X $ som är olika.Är det så det ska vara?
@Michael: Naturligtvis.Deras kovarians kommer att vara (ungefär) densamma, inte själva siffrorna.
Jag ser inget svar på user000001s fråga, så om den har tagits bort, låt mig kolla igen: gäller den här metoden för någon distribution, eller gäller den bara för normal distribution?Tack.
@Sid: Eventuell kontinuerlig distribution som inte stöds på hela den verkliga linjen misslyckas omedelbart.Om vi till exempel använder en enhetlig $ U [0,1] $ kan vi inte garantera att de "korrelerade siffrorna" kommer att vara i $ [0,1] $;på samma sätt för en Poisson kommer vi att sluta med icke-diskreta siffror.Dessutom misslyckas alla distributioner där summan av distributionerna fortfarande inte är samma distribution (t.ex. att summera $ t $ -distribution inte resulterar i $ t $ -distribution).I alla nämnda fall kommer siffrorna som produceras * att korreleras * enligt $ C $ men de motsvarar inte den distribution vi startade.
@usεr11852 Tack så mycket.Jag är intresserad av beta-distributionen, som inte uppfyller två av dina kriterier eftersom den inte stöds på hela den verkliga raden och inte har summan som du beskrev.Men betyder det att det inte finns någon metod alls som fungerar för den typen av distributioner, eller bara att denna metod i synnerhet inte fungerar?
@Sid,-metoder för att generera korrelerade beta-variabler finns;se kommentarerna och svara i trådarna [här] (https://stats.stackexchange.com/questions/285142) och [här] (https://stats.stackexchange.com/questions/284996) av whuber för merinformation.
Tack så mycket.Tyvärr verkar den tidigare länken bara täcka fall med två variabler och den senare är för binomialfördelningen.Men det kan vara värt det att ställa en separat fråga.
gung - Reinstate Monica
2012-10-08 03:11:13 UTC
view on stackexchange narkive permalink

+1 till @ user11852 och @ jem77bfp, det här är bra svar. Låt mig närma mig detta från ett annat perspektiv, inte för att jag tycker att det nödvändigtvis är bättre i praktiken utan för att jag tycker att det är lärorikt. Här är några relevanta fakta som vi redan vet:

  1. $ r $ är regressionslinjens lutning när både $ X $ och $ Y $ är standardiserade , dvs $ \ mathcal N (0,1) $,
  2. $ r ^ 2 $ är andelen av variansen i $ Y $ hänförlig till variansen i $ X $,



    (även från regler för avvikelser):

  3. variansen för en slumpmässig variabel multiplicerad med en konstant är konstant kvadrat gånger den ursprungliga variansen:
    $$ \ text {Var} [aX] = a ^ 2 \ text {Var} [X] $$
  4. varians add , dvs variansen av summan av två slumpmässiga variabler (förutsatt att de är oberoende) är summan av de två varianserna:
    $$ \ text {Var} [X + \ varepsilon] = \ text {Var} [X] + \ text {Var} [\ varepsilon] $$

Nu kan vi kombinera dessa fyra fakta för att skapa två vanliga normala variabler vars populationer kommer att ha en given korrelation, $ r $ (mer korrekt, $ \ rho $), även om de prover du genererar kommer att ha provkorrelationer som varierar. Tanken är att skapa en pseudorandom-variabel, $ X $, det vill säga normal, $ \ mathcal N (0,1) $, och sedan hitta en koefficient, $ a $ och en felvarians, $ v_e $, så att $ Y \ sim \ mathcal N (0, a ^ 2 + v_e) $, där $ a ^ 2 + v_e = 1 $. (Observera att $ | a | $ måste vara $ \ le 1 $ för att detta ska fungera, och att dessutom $ a = r $.) Således börjar du med $ r $ som du vilja; det är din koefficient, $ a $. Då räknar du ut den felvarians som du behöver, det är $ 1-r ^ 2 $. (Om din programvara kräver att du använder standardavvikelsen, ta kvadratroten av det värdet.) Slutligen, för varje pseudorandom-variat, $ x_i $, som du har genererat, generera en pseudorandom-felvariat, $ e_i $, med lämplig felvarians $ v_e $, och beräkna den korrelerade pseudorandomvarianten, $ y_i $, genom att multiplicera och lägga till.

Om du vill göra detta i R kan följande kod fungera för dig:

  correlatedValue = function (x, r) {r2 = r ** 2 ve = 1-r2 SD = sqrt (ve) e = rnorm (längd (x), medelvärde = 0, sd = SD) y = r * x + e retur (y)} uppsättning .frö (5) x = rnorm (10000) y = korreleradVärde (x = x, r = .5) cor (x, y) [1] 0.4945964  

(Redigera: Jag glömde att nämna :) Som jag har beskrivit det, ger denna procedur dig två vanliga normala korrelerade variabler. Om du inte vill ha standard normaler men vill att variablerna ska ha vissa specifika medel (inte 0) och SD (inte 1) kan du transformera dem utan att påverka korrelationen. Således skulle du subtrahera det observerade medelvärdet för att säkerställa att medelvärdet är exakt $ 0 $, multiplicera variabeln med den SD du vill ha och lägg sedan till det medelvärde du vill ha. Om du vill att det observerade medelvärdet ska fluktuera normalt runt det önskade medelvärdet, skulle du lägga till den ursprungliga skillnaden tillbaka. I grund och botten är detta en omvandling av z-poäng. Eftersom detta är en linjär transformation kommer den transformerade variabeln att ha samma korrelation med den andra variabeln som tidigare.

Återigen låter det här, i sin enklaste form, bara generera ett par av korrelerade variabler (detta kan skalas upp, men blir ful snabbt), och är verkligen inte bekvämaste sättet att få jobbet gjort. I R vill du använda ? Mvrnorm i paketet MASS, både för att det är lättare och för att du kan generera många variabler med en given populationskorrelationsmatris. Ändå tycker jag att det är värt att ha gått igenom denna process för att se hur några grundläggande principer spelar ut på ett enkelt sätt.

Detta väsentligen regressionssätt är särskilt trevligt att låta en generera en slumpmässig Y korrelerad med valfritt antal _existerande_ X "prediktorer".Har jag rätt i sådan förståelse?
Det beror på exakt vilket mönster av korrelationer mellan de variabler du vill ha, @ttnphns.Du kan upprepa detta efter varandra, men det skulle bli tråkigt.För att skapa många korrelerade variabler med ett visst mönster är det bättre att använda Cholesky-nedbrytningen.
gung, vet du hur man använder Cholesky för att generera en Y-korrelerad (ungefär som i din metod) enligt en vektor av korrelationer med flera _existerande_ (ej simulerade) Xs?
@ttnphns, vill du generera en enda Y med en given populationskorrelation med en uppsättning X, inte en uppsättning p-variabler som alla har förutbestämda populationskorrelationer?Ett enkelt sätt skulle vara att skriva en regressionsekvation för att generera en enda Y-hatt från dina X: er, och använd sedan metoden ovan för att generera Y som ett samband mellan din Y-hatt.Du kan ställa en ny fråga om det, om du vill.
Detta är vad jag menade i min ursprungliga kommentar: den här metoden skulle vara en direkt förlängning av det du talar om i ditt svar: i huvudsak en regressionsmetod.
jem77bfp
2012-10-08 01:41:12 UTC
view on stackexchange narkive permalink

I allmänhet är detta inte en enkel sak att göra, men jag tror att det finns paket för multivariat normal variabel generation (åtminstone i R, se mvrnorm i MASS -paket), där du bara matar in en kovariansmatris och en medelvektor.

Det finns också en "konstruktiv" strategi. Låt oss säga att vi vill modellera en slumpmässig vektor $ (X_1, X_2) $ och vi har dess fördelningsfunktion $ F (x_1, x_2) $. Det första steget är att få marginalfördelningsfunktionen; dvs. integrera $ F $ över alla $ x_2 $: $$ F_ {X_1} (x_1) = \ int _ {- \ infty} ^ {\ infty} F (x_1, x_2) dx_2. $$ Sedan hittar vi $ F ^ {- 1} _ {X_1} $ - den inversa funktionen $ F_ {X_1} $ - och kopplar in en slumpmässig variabel $ \ xi_1 $ som fördelas jämnt på intervallet $ [0, 1] $. I det här steget genererar vi den första koordinaten $ \ hat {x} _1 = F ^ {- 1} _ {X_1} (\ xi) $.

Nu eftersom vi har en koordinat behöver vi för att ansluta den till vår ursprungliga distributionsfunktion $ F (x_1, x_2) $ och sedan få en villkorlig fördelningsfunktion med villkor $ x_1 = \ hat {x} _1 $: $$ F (x_2 | X_1 = \ hat {x} _1) = \ frac {F (\ hat {x} _1, x_2)} {f_ {X_1} (\ hat {x} _1)}, $$ där $ f_ {X_1} $ är en sannolikhetsdensitetsfunktion för marginalen $ X_1 $ distribution; dvs $ F '_ {X_1} (x_1) = f_ {X_1} (x_1) $.

Sedan genererar du igen en jämnt fördelad variabel $ \ xi_2 $ på $ [0,1] $ (oberoende av $ \ xi_1 $) och anslut den till det inverse av $ F (x_2 | X_1 = \ hat {x} _1) $. Därför får du $ \ hat {x} _2 = (F (x_2 | X_1 = \ hat {x} _1)) ^ {- 1} (\ xi) $; det vill säga $ \ hat x_2 $ uppfyller $ F (\ hat x_2 | X_1 = \ hat {x} _1) = \ xi $. Denna metod kan generaliseras till vektorer med fler dimensioner, men dess nackdel är att du måste beräkna, analytiskt eller numeriskt, många funktioner. Idén finns också i den här artikeln: http://www.econ-pol.unisi.it/dmq/pdf/DMQ_WP_34.pdf.

Om du inte förstår innebörden av att ansluta en enhetlig variabel till en invers sannolikhetsfördelningsfunktion, försök att göra en skiss av det univariata fallet och kom ihåg vad den geometriska tolkningen av den inversa funktionen är.

Smart idé!Har enkel intuitiv överklagande.Men ja verkar dyrt beräkningsmässigt.
(+1) mycket bra poäng.Det skulle vara bättre i början att säga $ f_ {X, Y} (x, y) = f_X (x) \ cdot f_ {Y | X} (y) $, då flyter det mer naturligt att först generera en mariginalfördelning ochsedan den villkorliga fördelningen.Väldigt bra!
F. Jatpil
2019-06-05 16:38:18 UTC
view on stackexchange narkive permalink

Om du är redo att ge upp effektiviteten kan du använda en kastalogoritm. Dess fördel är att den möjliggör alla typer av distributioner (inte bara Gaussiska).

Börja med att generera två okorrelerade sekvenser av slumpmässiga nummer $ \ {x_i \} _ {i = 1} ^ N $ och $ \ {y_i \} _ {i = 1} ^ N $ med önskade distributioner. Låt $ C $ med önskat värde på korrelationskoefficienten. Gör sedan följande:

1) Beräkna korrelationskoefficient $ c_ {old} = corr (\ {x_i \}, \ {y_i \}) $

2) Skapa två slumpmässiga munbers $ n_1 $ och $ n_2: 1 \ leq n_ {1,2} \ leq N $

3) Byt nummer $ x_ {n_1} $ och $ x_ {n_2} $

4) Beräkna ny korrelation $ c_ {new} = corr (\ {x_i \}, \ {y_i \}) $

5) Om $ | C-c_ {new} | < | C-c_ {gammal} | $ behåll sedan bytet. Ångra annars bytet.

6) Om $ | C-c | < \ epsilon $ stopp, annars går 1)

Slumpmässiga byten ändrar inte marginalfördelningen för $ {x_i} $ .

Lycka till!

Jag är lite förvirrad av notation.Är $ x_i $ en vektor?Om inte, vad betyder $ corr (x_i, y_i) $?
Jag är ledsen, jag är en hobbyist inom statistik - jag är inte bekant med notationer.$ x_i $ är ett tal, $ \ {x_i \} $ är ett antal tal (som kännetecknas av medelvärde, varians, sannolikhetsfördelning), och så är $ y $.$ corr (x_i, y_i) $ är inte välskrivet, det ska vara $ corr (\ {x_i \}, \ {y_i \}) = (1 / N) \ Sigma_ {i = 1} ^ {N} (x_i- \ bar x) (y_y - \ bar y) $
Jag förstår, det är vettigt.Jag ignorerade "$ \ {\} $" i $ corr (\ {x_i \}, \ {y_i \}) $


Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...