題:
生成與現有變量具有定義的相關性的隨機變量
Felix S
2011-08-31 14:18:37 UTC
view on stackexchange narkive permalink

對於模擬研究,我必須生成隨機變量,這些變量顯示與現有變量 $ Y $ span>的預定義(填充)相關性。

我研究了 R 軟件包 copula CDVine ,它們可以產生具有給定依賴關係結構的隨機多變量分佈。但是,不可能將結果變量之一固定為現有變量。

任何想法和指向現有功能的鏈接都將受到讚賞!

結論:提出了兩個有效答案,但有不同的解決方案:

  1. caracal的 R script,其中計算與預定義變量具有精確(樣本)相關性的隨機變量
  2. 我發現自己的 R 函數,它計算出一個與預定義變量相關的,定義為 population 的隨機變量
  3. ol>

    [@ ttnphns':我可以自由擴展從單個固定變量大小寫到任意數量的固定變量的問題標題;即如何生成具有預定義的改正和一些固定的現有變量的變量]

請參閱此相關問題http://stats.stackexchange.com/questions/13382/how-to-define-a-distribution-that-c​​orrelates-with-a-draw-from-another-distributio/13384#13384您的問題(至少是理論方面的問題)。
以下Q也密切相關且將引起關注:[如何生成相關的隨機數(給定均值和相關程度)](http://stats.stackexchange.com/questions/38856/)。
八 答案:
caracal
2011-09-01 00:45:45 UTC
view on stackexchange narkive permalink

這裡是另一個:對於均值為0的向量,它們的相關性等於其角度的餘弦值。因此,找到具有恰好所需的相關度$ r $的向量$ x $的一種方法,對應於角度$ \ theta $:

  1. 獲得固定向量$ x_1 $和隨機向量$ x_2 $
  2. 將兩個向量居中(均值為0),給向量$ \ dot {x} _ {1} $,$ \ dot {x} _ {2} $
  3. make $ \ dot {x} _ {2} $與$ \ dot {x} _ {1} $(投影投影正交子空間)正交,給出$ \ dot {x} _ {2} ^ {\ perp} $
  4. 將$ \ dot {x} _ {1} $和$ \ dot {x} _ {2} ^ {\ perp} $縮放到長度1,得到$ \ bar {x} _ {1} $和$ \ bar {x} _ {2} ^ {\ perp} $
  5. $ \ bar {x} _ {2} ^ {\ perp} +(1 / \ tan(\ theta))\ cdot \ bar {x} _ {1} $是向量,其與$ \ bar {x} _ {1} $的夾角為$ \ theta $,並且與$ \ bar {x} _ {1} $的相關性為$ r $。這也是與$ x_1 $的相關性,因為線性變換使相關性保持不變。
  6. ol>

    這是代碼:

      n <- 20#vectorrho的長度<- 0.6#所需相關性= cos(角度)θ<- acos(rho)#對應角度x1 <- rnorm(n,1,1)#固定給定數據x2 <- rnorm(n,2,0.5)#新隨機數據X < -cbind(x1,x2)#matrixXctr <- scale(X,center = TRUE,scale = FALSE)#居中列(平均0)Id <- diag(n)#單位矩陣Q <- qr.Q(qr(Xctr [ ,1,drop = FALSE]))#QR分解,僅矩陣QP <- tcrossprod(Q)#= QQ'#投影到由x1x2o定義的空間<-(Id-P)%*%Xctr [,2]#使x2ctr正交於x1ctrXc2 <- cbind(Xctr [,1],x2o)#綁定到matrixY <- Xc2%*%diag(1 / sqrt(colSums(Xc2 ^ 2)))#將列縮放為長度1x <- Y [,2] +(1 / tan(theta))* Y [,1 ]#最終新向量
    cor(x1,x)#檢查相關性= rho  

    enter image description here

    對於正交投影$ P $,我使用了$ QR $分解來改進數值穩定性,從那時起,只需$ P = Q Q'$。

我試圖將代碼重寫為SPSS語法。我偶然發現您的QR分解會返回20x1列。在SPSS中,我具有Gram-Schmidt正交歸一化(也是QR分解),但是無法複製所得的Q列。請問您對我的QR行為是否滿意。或指出一些解決方法以獲取投影。謝謝。
@caracal,`P <-X%*%solve(t(X)%*%X)%*%t(X)`不會產生r = 0.6,因此這不是解決方法。我還是很困惑。 (我很樂意在SPSS中模仿您的表達式`Q <-qr.Q(qr(Xctr [,1,drop = FALSE]))`,但不知道如何。)
-1
誰能澄清兩個以上的樣本如何執行類似的操作?說,如果我想要3個通過rho成對關聯的樣本,我該如何轉換此解決方案以實現目標?
對於極限情況``rho = 1``,我發現執行以下操作很有用:``if(isTRUE(all.equal(rho,1)))rho <-1-10 * .Machine $ double.eps``,否則我得到的是``NaN''
我還對X進行縮放後立即添加了Xc <-attr(X,'scaled:center'),並在末尾將其重新添加,以使我的輸入和輸出具有相似的比例。
whuber
2017-11-11 04:03:13 UTC
view on stackexchange narkive permalink

I將描述最通用的解決方案。解決這種普遍性的問題使我們可以實現非常緊湊的軟件實現:僅需兩行 R 代碼即可。

選擇向量 $ X $ span>,其長度與 $ Y $ span>,根據您喜歡的任何分佈。 $ Y ^ \ perp $ span>是 $ X $ span>對 $ Y $ span>:這會從 $ Y $ span>組件span class =“ math-container”> $ X $ span>。通過將 $ Y $ span>的適當倍數加回 $ Y ^ \ perp $ span>,我們可以生成一個向量具有 $ \ rho $ span>與 $ Y $ span>的任何期望的相關性。最多可以有一個任意的加法常數和正乘法常數(您可以通過任何方式自由選擇),解決方案是

$$ X_ {Y; \ rho} = \ rho \,\ operatorname {SD}(Y ^ \ perp)Y + \ sqrt {1- \ rho ^ 2} \,\ operatorname {SD}(Y)Y ^ \ perp。$$ span>

(“ $ \操作員名稱{SD} $ span>”表示與標準偏差成比例的任何計算。)


這裡是有效的 R 代碼。如果您不提供 $ X $ span>,則代碼將從多元標準正態分佈中提取其值。

 互補<-函數(y,rho,x){
  if(missing(x))x <- rnorm(length(y))#可選:如果未指定`x',則提供默認值
  y.perp <-殘差(lm(x〜y))
  rho * sd(y.perp)* y + y.perp * sd(y)* sqrt(1-rho ^ 2)
}
 

為了說明,我生成了一個隨機的 $ Y $ span>和 $ 50 $ span>組件,並生成了 $ X_ {Y; \ rho} $ span>與此 $ Y $ span>具有各種指定的相關性。它們都是使用相同的起始向量 $ X =(1,2,\ ldots,50)$ span>創建的。這是他們的散點圖。每個面板底部的“地毯”顯示常見的 $ Y $ span>向量。

Figure

劇情之間有明顯的相似之處,不是:-)。


如果您想嘗試,這裡是產生這些數據和圖形的代碼。 (我並不在意自由地移動和縮放結果,這很容易操作。)

  y <- rnorm(50,sd = 10)
x <- 1:50#可選
rho <- seq(0,1,length.out = 6)* rep(c(-1,1),3)
X <- data.frame(z = as.vector(sapply(rho,function(rho)complement(y,rho,x))),
                rho = ordered(rep(signif(rho,2),each = length(y))),
                y = rep(y,length(rho)))

庫(ggplot2)
ggplot(X,aes(y,z,group = rho))+
  geom_smooth(method =“ lm”,color =“ Black”)+
  geom_rug(sides =“ b”)+
  geom_point(aes(fill = rho),alpha = 1/2,shape = 21)+
  facet_wrap(〜rho,scales =“ free”)
 

順便說一句,此方法很容易推廣到多個 $ Y $ span>:如果在數學上可行,它將找到一個 $ X_ {Y_1,Y_2,\ ldots,Y_k; \ rho_1,\ rho_2,\ ldots,\ rho_k} $ span>已指定與整個 $ Y_i $的關聯 span>。只需使用普通最小二乘法從 $ X $ span>和形式中取出所有 $ Y_i $ span>的效果 $ Y_i $ span>和殘差的合適線性組合。 (這有助於對 $ Y $ span>進行對偶運算,這是通過計算偽逆獲得的。下面的代碼使用 $ Y $ span>即可實現。)

這是 R 中算法的草圖,其中 $ Y_i $ span>作為矩陣 y

  y <- scale(y)#使計算更簡單
e <-residuals(lm(x〜y))#取出矩陣y的列
y.dual <- with(svd(y),(n-1)* u%*%diag(ifelse(d > 0,1 / d,0))%*%t(v))
sigma2 <- c((1- rho%*%cov(y.dual)%*%rho)/ var(e))
返回(y.dual%*%rho + sqrt(sigma2)* e)
 

另一個線程提供了每行代碼的詳細說明。對於想嘗試的人來說,以下是更完整的實現。

 互補<-函數(y,rho,x,threshold = 1e-12){
  #
  #處理參數。
  #
  if(!is.matrix(y))y <- matrix(y,ncol = 1)
  d <col(y)
  n <-row(y)
  y <- scale(y,center = FALSE)#使計算更簡單
  如果(missing(x))x <- rnorm(n)
  #
  #刪除y對x的影響。
  #
  e <-殘差(lm(x〜y))
  #
#計算e的係數sigma,使
  #線性組合為y的y.dual是%*%rho + sigma * e
  #矢量。
  #
  y.dual <- with(svd(y),(n-1)* u%*%diag(ifelse(d > threshold,1 / d,0))%*%t(v))
  sigma2 <- c((1- rho%*%cov(y.dual)%*%rho)/ var(e))
  #
  #返回此線性組合。
  #
  如果(sigma2 > = 0){
    sigma <- sqrt(sigma2)
    z <- y.dual%*%rho + sigma * e
  }其他{
    警告(“無法進行關聯。”)
    z <- rep(0,n)
  }
  返回(z)
}
#
#設置問題。
#
d <- 3#給定變量的數量
n <- 50#所有向量的維數
x <- 1:n#可選:指定`x`或從任何分佈中繪製
y <- matrix(rnorm(d * n),ncol = d)#以任何方式創建`d`原始變量
rho <- c(0.5,-0.5,0)#指定相關性
#
#驗證結果。
#
z <-補碼(y,rho,x)
cbind('實際相關'= cor(y,z),
      “目標相關性” = rho)
#
#顯示它們。
#
colnames(y)<- paste0(“ y。”,1:d)
colnames(z)<-“ z”
對(cbind(z,y))
 
這確實是一個不錯的解決方案。但是,我自己無法將其擴展為多個$ Y $變量(答案中為固定變量)。“順便說一句,這種方法很容易推廣到更多...只需使用普通的最小二乘...即可形成合適的線性組合”。你能示範一下嗎?請使用非R用戶可讀的帶註釋的代碼?
@ttnphns我已經這樣做了。
十分感謝!我知道了,今天我已經為自己編寫了SPSS中的方法。您的提案真是太好了。我從沒想到雙重基礎的概念適用於解決任務。
是否可以使用類似的方法得出均勻分佈的矢量?也就是說,我已有一個向量“ x”,並且想要生成一個與“ x”相關的新向量“ y”,而且還希望“ y”向量要均勻分佈。
@Skumin考慮為此使用copula,以便您可以控制兩個向量之間的關係。
@whuber謝謝。但是我不完全確定,如果已經給出其中一個向量,該怎麼辦。
給定向量等於指定經驗分佈函數。
Felix S
2011-08-31 22:51:20 UTC
view on stackexchange narkive permalink

這是另一種計算方法(該解決方案摘自Enrico Schumann的論壇帖子)。根據Wolfgang(參見註釋),這在計算上與ttnphns提出的解決方案相同。

與caracal的解決方案相反,它不會產生具有$ \ rho $確切相關性的樣本,而是產生兩個人口相關性等於$ \ rho $的向量。 / p>

以下函數可以計算從具有給定$ \ rho $的總體得出的雙變量樣本分佈。它要么計算兩個隨機變量,要么使用一個現有變量(作為參數 x 傳遞)並創建具有所需相關性的第二個變量:

 #返回數據與rho#的總體相關性相關的兩個變量的框架。如果需要,可以通過指定xgetBiCop <-function(n,rho,mar.fun = rnorm,x = NULL,..將兩個變量之一固定到現有變量。 。){if(!is.null(x)){X1 <- x}否則{X1 <- mar.fun(n,...)} if(!is.null(x)& length(x)! = n)警告(“變量x與n的長度不同!”)C <-matrix(rho,nrow = 2,ncol = 2)diag(C)<-1 C <- chol(C)X2 < -mar.fun(n)X <- cbind(X1,X2)#誘導相關性(不改變X1)df <- X%*%C ##如果需要的話:檢查結果#all.equal(X1,X [, 1])#cor(X)return(df)}  

該函數還可以通過調整參數 mar.fun 來設置非正態的邊際分佈。但是請注意,僅修復一個變量 似乎可以與正態分佈的變量 x 一起使用! (可能與Macro的評論有關)。

還請注意,原始帖子中的“小修正因子”已被刪除,因為它似乎使所產生的相關性產生偏差,至少在高斯分佈和Pearson相關的情況(另請參見註釋)。

似乎這只是一個近似解,即經驗相關性並不完全等於$ \ rho $。還是我錯過了什麼?
很容易證明,除了“對rho的小修正”(在此情況下其目的無法理解我)之外,這與ttnphns先前所建議的完全相同。該方法僅基於相關矩陣的Choleski分解以獲得所需的變換矩陣。參見,例如:http://en.wikipedia.org/wiki/Cholesky_decomposition#Monte_Carlo_simulation。是的,這只會給您兩個向量,它們的“種群”相關性等於“ rho”。
“對rho的小修正”在原始帖子中,並在[此處](http://www.mathworks.de/products/demos/statistics/copulademo.html#23)中進行了描述。實際上,我不太了解。但是對50000個模擬相關性(rho = 0.3)的調查顯示,不進行“小校正”,r的平均值為0.299,而對校正的平均值為0.312(校正後的rho的值)為生產的。因此,我從功能中刪除了該部分。
我知道這很老了,但我也想指出,這種方法不適用於非正定相關矩陣。例如-相關係數為-1。
謝謝;我注意到,如果x1不是標準化的均值= 0,標準差= 1,並且您不希望對其進行縮放,則需要修改以下行:'X2 <-mar.fun(n)`到`X2 <-mar.fun(n,mean(x),sd(x))`獲得x1和x2之間的所需相關性
ttnphns
2011-08-31 15:10:38 UTC
view on stackexchange narkive permalink

讓$ X $為您的固定變量,並且您想生成與$ X $相關的$ Y $變量,金額為$ r $。如果$ X $是標準化的,則(因為$ r $是簡單回歸中的beta係數)$ Y = rX + E $,其中$ E $是來自正態分佈的均值$ 0 $和$ \ text {sd} = \的隨機變量sqrt {1-r ^ 2} $。在$ X $和$ Y $數據之間觀察到的相關性約為$ r $;現在,可以將$ X $和$ Y $視為來自具有$ \ rho = r $的雙變量正常人口(如果$ X $來自正常)的隨機樣本。

現在,如果要在二元樣本恰好 $ r $中獲得相關性,則需要提供$ E $與$ X $具有相關性。可以通過迭代修改$ E $來將其收緊為零。好吧,只有兩個變量,一個給定($ X $)和一個要生成($ Y $),足夠的迭代次數實際上是1,但是有多個給定變量($ X_1,X_2,X_3,... $

應注意,如果$ X $正常,則在第一個過程(“近似$ r $”)中,$ Y $也將正常。但是,將$ Y $迭代擬合為“精確的$ r $” $ Y $可能會失去正態性,因為該擬合有選擇地利用了案例值。


更新 2017年11月11日。我今天遇到了這個老話題,並決定通過顯示最初討論的迭代擬合算法來擴大答案。

這是一個迭代解決方案,如何訓練一個隨機模擬的或已有的變量 $ Y $ 以精確地關聯或協變量(或非常接近,具體取決於迭代次數)給定變量 $ X $ s(無法修改)。

Disclamer:我發現此迭代解決方案不如優秀解決方案,它基於今天在此線程中找到@whuber的雙重基礎提議。 @whuber的解決方案不是迭代的,對我來說更重要的是,它似乎對輸入的“ pig”變量的值產生的影響要比“ my”算法的影響小(如果任務是“更正”,這將是一種資產)現有變量,而不是從頭開始生成隨機變量)。儘管如此,我還是出於好奇而發布我的,因為它可以工作(另請參見腳註)。

因此,我們給了(固定的)變量$ X_1,X_2,...,X_m $ ,以及變量$ Y $,它要么是隨機生成的“豬”值,要么是一個存在的數據變量,需要對其進行“校正”,以使$ Y $準確地用於相關性(或可以是協方差)$ r_1, r_2,...,r_m $和$ X $ s。所有數據必須連續;換句話說,應該有很多唯一值。

這個想法:對殘差進行迭代擬合。知道了想要的(目標)相關性/協方差後,我們可以使用$ X $ s作為多個線性預測變量來計算$ Y $的預測值。在獲得初始殘差(根據當前的$ Y $和理想的預測)後,迭代地訓練它們,使其不與預測變量相關。最後,用殘差重新獲得$ Y $。 (該程序是我多年以前對車輪的實驗性發明,當時我不了解該原理;然後在SPSS中對其進行了編碼。)

  1. 轉換目標$ r $ s將乘積乘以$ \ text {df} = n-1 $可以得出乘積和:$ S_j = r_j \ text {df} $。 ($ j $是$ X $變量索引。)

  2. Z對所有變量進行Z標準化(每個變量居中,然後除以對$ \之上的值計算的st。偏差。文字{df} $)。因此,$ Y $和$ X $ s是標準的。現在,可觀察到的平方和為= $ \ text {df} $。

  3. 根據目標$ r $ s計算預測$ Y $ x $$的回歸係數: $ \ bf b =(X'X)^ {-1} S $。

  4. 計算$ Y $的預測值:$ \ hat {Y} = \ bf Xb $。

  5. 計算殘差$ E = Y- \ hat { Y} $。

  6. 計算殘差所需的(目標)平方和:$ SS_S = \ text {df} -SS _ {\ hat {Y}} $。

  7. (開始迭代。)計算觀察到的當前$ E $與每個$ X_j $之間的叉積之和:$ C_j = \ sum_ {i = 1} ^ n E_i X_ { ij} $

  8. 正確的$ E $值,目的是使所有$ C $接近$ 0 $($ i $是一個案例索引):

    $$ E_i [\ text {corrected}] = E_i- \ frac {\ sum_ {j = 1} ^ m C_j X_ {ij}} {n \ sum_ {j = 1} ^ m X_ {ij} ^ 2} $$

    (分母在迭代中不會改變,需要預先計算)

    或者,更有效的公式還可以確保$ E $的均值變成$ 0 $。首先,在步驟7中在每次迭代之前對$ C $ s進行 center $ E $的計算,然後在步驟8上更正為: {corrected}] = E_i- \ frac {\ sum_ {j = 1} ^ m \ frac {C_j X_ {ij} ^ 3} {\ sum_ {i = 1} ^ n X_ {ij} ^ 2}} {\ sum_ {j = 1} ^ m X_ {ij} ^ 2} $$

    (同樣,分母是已知的)$ ^ 1 $

  9. 將$ SS_E $設為目標值:$ E_i [\ text {corrected}] = E_i \ sqrt {SS_S / SS_E} $

    轉到步驟7。(例如,執行10-20次迭代如果目標$ r $ s是現實的,則$ SS_S $是正數,並且如果樣本量$ n $不是太少,則迭代總是直接收斂。 。)

  10. 就緒:現在所有$ C $ s幾乎都為零,這意味著已經訓練了殘差$ E $以恢復目標$ r $ s。計算擬合的$ Y $:$ Y [\ text {corrected}] = \ hat {Y} + E $。

  11. 獲得的$ Y $幾乎是標準化的。最後,您可能希望對其進行精確的標準化,就像在步驟2一樣。

  12. 您可以為$ Y $提供任何您喜歡的方差平均值。實際上,在四個統計數據中- min max 平均值 st。 dev 。 -您可以選擇任意兩個值,並對變量進行線性變換,以使其在不改變您獲得的$ r $ s(相關性)的情況下進行擺放(這全稱為線性縮放)。

  13. ol >

    再次警告上述內容。通過將$ Y $精確地拉到$ r $,輸出$ Y $不必正態分佈。


    $ ^ 1 $校正公式可以更複雜,例如例如,在每一個$ X $上同時確保$ Y $的更大的純正隨機性(以平方和表示),同時獲得相關性,-I也為此實現了代碼。 (我不知道這種“雙重”任務是否可以通過更整潔的,非迭代的方法,例如 whuber的方法來解決。)

感謝您的回答。那也是我一直在考慮的經驗/迭代解決方案。但是,對於我的仿真,我需要一種無需昂貴的擬合過程的更具分析性的解決方案。幸運的是,我剛剛找到了一個解決方案,我將在不久後發布...
這適用於生成雙變量正態,但不適用於任意分佈(或任何非“加法”分佈)
這確實適用於各種發行版。但是,由於縮放,$ X $不再具有原始分佈。同樣,$ Y $將是$ X $的重新縮放分佈與獨立正態分佈的某種混合。無論如何,$ X $和$ Y $之間的真實相關性將是$ r $。
@Felix,確實值得發布您找到的解決方案。將其發佈為您問題的答案。
@Wolfgang,的確是正確的-我假設ttnphns在談論生成雙變量法線,因為$ E $被指定為法線(通常沒有必要)。我只是指出,就像您所做的那樣,$ X $的邊際分佈與$ Y $的邊際分佈將不同,除了(在上述規範下)在特殊情況下$ X,Y,\ sim N (0,1)$。通常,這將是$ r X $和$ E $的密度的捲積。
@Macro,不,我不是暗示要生成雙變量法線,並且從法線生成E的確不是必需的(我之所以提到法線是因為我的宏使用法線)。
@ttnphns:我將在2個小時內發布答案-因為這是我的第一個問題,我必須等待8個小時才能回答自己的問題...
我不明白為什麼可以直接產生整個圓錐形解決方案時建議您進行迭代。這種方法有什麼特殊目的嗎?
@whuber,我已經編輯了答案,以感謝您(更好)的選擇。
關於您的最新編輯:由於我為* all *解決方案提供了一個簡單的公式,因此可以通過將所有解決方案集上的適當目標函數最小化來實現任何期望的目標,例如“更大的同調”。該方法是完全通用的。通過將變量(或變量)$ Y $擴展到正交基礎並利用相關的比例不變性,問題就成為優化在歐幾里得空間中的球面上定義的函數之一。
@whuber,您的評論是我一直在等待的;實際上,我的答案(我鏈接到的關於異方差性)原本是對您的挑戰:也許是邀請您發布解決方案-像往常一樣徹底和出色。
Paul Hiemstra
2013-08-04 16:05:41 UTC
view on stackexchange narkive permalink

我想做一些編程工作,所以我接受了@Adam刪除的答案,並決定在R中編寫一個不錯的實現。我專注於使用面向函數的樣式(即lapply樣式循環)。總體思路是採用兩個向量,將其中一個向量隨機置換,直到它們之間達到一定的相關性為止。這種方法蠻力的,但是易於實現。

首先我們創建一個隨機排列輸入向量的函數:

  randomly_permute = function(vec)vec [sample.int(length(vec))] randomly_permute(1:100)[1] 71 34 8 98 3 86 28 37 5 47 88 35 43 100 68 58 67 82 [19] 13 9 61 10 94 29 81 63 14 48 76 6 78 91 74 69 18 12 [37] 1 97 49 66 44 40 65 59 31 54 90 36 41 93 24 11 77 85 [55] 32 79 84 15 89 45 53 22 17 16 92 55 83 42 96 72 21 95 [73] 33 20 87 60 38 7 4 52 27 2 80 99 26 70 50 75 57 19 [91] 73 62 23 25 64 51 30 46 56 39  

...和創建一些示例數據

  vec1 = runif(100)vec2 = runif(100) 

...編寫一個置換輸入向量的函數,然後將其與參考向量相關聯:

  permute_and_correlate = function(vec,reference_vec){perm_vec = random_permute(vec)cor_value = cor(perm_ vec,reference_vec)return(list(vec = perm_vec,cor = cor_value))} permute_and_correlate(vec2,vec1)$ vec [1] 0.79072381 0.23440845 0.35554970 0.95114398 0.77785348 0.74418811 [7] 0.47871491 0.55981826 0.08801319 0.360.339760 0.14830718 0.40796732 0.67532970 [19] 0.71901990 0.5203​​1017 0.41357545 0.91780357 0.82437619 0.89799621 [25] 0.07077250 0.12056045 0.46456652 0.21050067 0.30868672 0.55623242 [31] 0.84776853 0.57217746 0.08626022 0.71740151 0.87959539 0.82931652 3983 0.93980.99 389.00
[43] 0.29254936 0.02674156 0.77182339 0.30047034 0.91790830 0.45862163 [49] 0.27077191 0.74445997 0.34622648 0.58727094 0.92285322 0.83244284 [55] 0.61397396 0.40616274 0.32203732 0.84003379 0.81109473 0.50573325 [61] 0.86719899 0.4303 0.80.10.12 09840.9160.88983 0.86170.38940.11 12803998 0.123826901 0.882938940.11 293869098162431280 0.83349287 0.46724807 0.15345334 0.60854785 [79] 0.78854984 0.95770015 0.89193212 0.18885955 0.34303707 0.87332019 [85] 0.08890968 0.22376395 0.02641979 0.43377516 0.58667068 0.22736077 [91] 0.75948043 0.49734797 0.25235660 0.40125309 0.72147500 0.979230.7772> pre> 

...並重複一千次:

  n_iterations = lapply(1:1000,function(x)permute_and_correlate(vec2,vec1)) 
>

請注意,R的作用域規則確保在全局環境中匿名fu之外找到 vec1 vec2 上面使用的功能。因此,排列都與我們生成的原始測試數據集有關。

接下來,我們找到最大的相關性:

  cor_values = sapply(n_iterations,'[[','cor')n_iterations [[which.max(cor_values)] ] $ vec [1] 0.89799621 0.67532970 0.46456652 0.75948043 0.30868672 0.83244284 [7] 0.86719899 0.55623242 0.63877904 0.73996913 0.71901990 0.85240338 [13] 0.81109473 0.52571331 0.82931652 0.60854785 0.19701975 0.26986325 [19] 0.58667068 0.32140366 0.40770.93213 29749603972 ] 0.07729027 0.11796154 0.69356590 0.95770015 0.74418811 0.43377516 [37] 0.55981826 0.93903143 0.30047034 0.84776853 0.32203732 0.25235660 [43] 0.79072381 0.58727094 0.99006038 0.01581969 0.41357545 0.52590383 [49] 0.27980561 0.50573325 0.924230.1 0.1602 0.86543 0.94573 0.84570.34 0.44573 0.44573 0.44573 0.9457345 0.34723 0.84573 0345365 74573456 3 3651 03451 034534563 0345938345 0.24 34563 1345 03456334561 034534563 0345179345 0.43453 34561(3)1 0345 0345345(2)0,0,9352,3,4,5,5,5,0,7,5,7,5
[61] 0.23440845 0.05244047 0.25931398 0.57217746 0.35554970 0.34622648 [67] 0.21050067 0.08890968 0.84003379 0.95114398 0.83349287 0.82437619 [73] 0.46724807 0.02641979 0.71740151 0.74439384 0.14830718 0.82685046 [79] 0.33821824 0.71627101 0.77182339 0.72147500 0.08801319 0.08626022 [85] 0.87332019 0.34303707 0.45393971 0.47871491 0.29254936 0.08939812 [91] 0.35698405 0.67369873 0.27087693 0.78854984 0.87959539 0.22376395 [97] 0.02674156 0.07077250 0.57461506 0.40616274 $ cor [1] 0.3166681  

...或找到最接近0.2的值:

  n_iterations [[which.min(abs(cor_values-0.2))]] $ vec [1] 0.02641979 0.49734797 0.32203732 0.95770015 0.82931652 0.52571331 [7] 0.25931398 0.30047034 0.55981826 0.08801319 0.29254936 0.23440845 [13] 0.12056045 0.89799621 0.22602602 0.14830718 0.45393971 0.22376395 0.89840404 0.08890968 0.15345334 [25] 0.87332019 0.92285322 0.50573325 0.40796732 0.91780357 0.57217746 [31] 0.52590383 0 0.84003379 0.5203​​1017 0.67532970 0.83244284 0.95114398 [37] 0.81109473 0.35554970 0.92423638 0.83349287 0.34622648 0.18885955 [43] 0.61397396 0.89193212 0.74445997 0.46724807 0.72147500 0.33821824 [49] 0.71740151 0.75948043 0.52140366 0.69356590 0.41357545 0.21050067 [55] 0.87959539 0.11796154 0.73996913 0.30868672 0.47871491 0.63877904 [61] 0.22736077 0.40125309 0.02674156 0.26986325 0.43377516 0.07077250 [67] 0.79072381 0.08939812 0.86719899 0.55623242 0.60854785 0.71627101 [73] 0.40616274 0.35698405 0.67369873 0.82437619 0.27980561 0.77182339 [79] 0.19701975 0.82685046 0.74418811 0.58667068 0.93903143 0.74439384 [85] 0.43 68739783 0.89877843 97839847898685798 9783685984 9783978637 5863978637 5863978637 8685437 685827 3782498637 5863978637 5863978637 85685437 0.71901990 0.25235660 0.11261002 $ cor [1] 0.2000199 

要獲得更高的相關性,您需要增加迭代次數。

Aksakal
2017-11-11 05:03:28 UTC
view on stackexchange narkive permalink

讓我們解決一個更普遍的問題:給定變量$ Y_1 $如何生成具有相關矩陣$ R $的隨機變量$ Y_2,\ dots,Y_n $?

解決方案:

  1. 獲取相關矩陣$ CC ^ T = R $的cholesky分解
  2. 創建與$ Y_1 $長度相同的獨立隨機向量$ X_2,\ dots,X_n $
  3. 使用$ Y_1 $作為第一列,並將生成的隨機數附加到該列中
  4. $ Y = CX $,其中$ Y_i $-所需的新隨機相關數字,請注意,$ Y_1 $不會改變
  5. ol>

    Python代碼:

     將numpy導入為np
    導入數學
    從scipy.linalg導入toeplitz,cholesky
    從statsmodels.stats.moment_helpers導入cov2corr
    
    #創建大的相關矩陣R
    p = 4
    h = 2 /人
    v = np.linspace(1,-1 + h,p)
    R = cov2corr(toeplitz(v))
    
    #創建第一個變量
    T = 1000;
    y = np.random.randn(T)
    
    #生成p-1個相關隨機數
    X = np.random.randn(T,p)
    X [:,0] = y
    C = cholesky(R)
    Y = np.matmul(X,C)
    
    #檢查Y是否保持不變
    打印(np.max(np.abs(Y [:,0] -y)))
    
    #檢查相關矩陣
    打印(R)
    打印(np.corrcoef(np.transpose(Y)))
     

    測試輸出:

      0.0
    [[1. 0.5 0. -0.5]
     [0.5 1. 0.5 0.]
     [0. 0.5 1. 0.5]
     [-0.5 0. 0.5 1.]
    [[1. 0.50261766 0.02553882 -0.46259665]
     [0.50261766 1. 0.51162821 0.05748082]
     [0.02553882 0.51162821 1. 0.51403266]
     [-0.46259665 0.05748082 0.51403266 1.]。
     
您能否說明“不是$ Y_1 $不會改變”是什麼意思?
@whuber這是一個錯字
user3635627
2017-02-06 16:19:20 UTC
view on stackexchange narkive permalink

使用給定的SAMPLING協方差矩陣生成正態變量

  covsam <- function(nobs,covm,seed = 1237){;
          庫(expm);
          #nons =觀察數,covm =給定的協方差矩陣;
          nvar <- ncol(covm);
          tot <- nvar * nobs;
          dat <- matrix(rnorm(tot),ncol = nvar);
          covmat <- cov(dat);
          a2 <- sqrtm(solve(covmat));
          m2 <- sqrtm(covm);
          dat2 <- dat%*%a2%*%m2;
          rc <- cov(dat2);};
          cm <-矩陣(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol = 3);
          厘米;
          res <- covsam(10,cm);
          RES;
 

使用給定的POPULATION協方差矩陣生成正態變量

  covpop <- function(nobs,covm,seed = 1237){;
          庫(expm);
          #nons =觀察數,covm =給定的協方差矩陣;
          nvar <- ncol(covm);
          tot <- nvar * nobs;
          dat <- matrix(rnorm(tot),ncol = nvar);
          m2 <- sqrtm(covm);
          dat2 <- dat%*%m2;
          rc <- cov(dat2); };
          cm <-矩陣(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol = 3);
          厘米;
          res <- covpop(10,cm);
          資源
 
您需要學習格式化答案中的代碼!有一個特定的選項可以將文本標記為代碼片段,請使用它!
Adam
2011-10-05 16:18:37 UTC
view on stackexchange narkive permalink

只需創建一個隨機向量並進行排序,直到獲得所需的r。

在什麼情況下這比上述解決方案更好?
用戶想要簡單答案的情況。我在r論壇上讀過類似的問題,並給出了答案。
不幸的是,除非首先進行一些分析來確定“隨機向量”的適當分佈,否則該解決方案不僅計算效率低且近似,而且常常會完全失敗。我認為基本* idea *的優點是,只需在問題上拋出一些隨機數,然後*隨機置換*它們(*不*“對它們進行排序!”),直到獲得大約$ r $(因為這是快速且易於編程),但在此簡短回復中並未明確表達該想法。
如果在r-help論壇上給出了這個答案,我懷疑它是(a)具有諷刺意味的(即是在開玩笑),還是(b)由統計學上不太熟練的人提供的。簡而言之,這個問題的答案很差。 -1


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...