簡體   English   中英

如何從相關矩陣生成隨機相關的統一數據?

[英]How to generate random correlated uniform data from a correlation matrix?

我有一個非常具體的問題要解決,這使得研究解決方案變得非常困難,因為我缺乏必要的數學技能。

我的目標:給定一個協方差/相關矩陣變量范圍,生成一些隨機數據。 該數據需要滿足3個重要條件:

  • 該數據的協方差/相關性應類似於提供的協方差/相關性矩陣。

  • 此數據(列)的變量范圍應以提供的范圍為界。

  • 每個變量都有一個均勻分布。

是否有一個 R 包或函數可以使用這些提供的參數生成這些數據條件? 也許我可以用 R 重寫一些其他語言的代碼?


編輯1:

在無法滿足一致性(條件 3)的情況下,是否有 R 包或函數可以生成僅滿足條件 1 和 2 的數據 換句話說,我不在乎變量采用什么分布。


編輯2:

這是我在這個問題上的第一次非常糟糕的嘗試。 到目前為止,它所做的只是創建正相關且統一的數據。 測試在底部:

generate_correlated_variables <- function(variable_ranges, numPoints = 100, nbins = 10) {
  
  df <- matrix(0, nrow = numPoints, ncol = length(variable_ranges))
  colnames(df) <- names(variable_ranges)

  
  for (i in 1:length(variable_ranges)) {
    
    df[,i] <- runif(numPoints, min = as.numeric(variable_ranges[[i]][1]), max = as.numeric(variable_ranges[[i]][2]))  
    
  }
  
  #Sample one variable and determine how many points fall in each bin
  #These amounts will be used to sample the rest of the variables
  df[,1] <- runif(numPoints, min = as.numeric(variable_ranges[[1]][1]), max = as.numeric(variable_ranges[[1]][2]))
  bin_width <- (variable_ranges[[1]][2] - variable_ranges[[1]][1])/nbins
  breaks_vec <- seq(variable_ranges[[1]][1], variable_ranges[[1]][2], by = bin_width)
  table <- table(cut(df[,1], breaks = breaks_vec, include.lowest = TRUE))

  binned_ranges_list <- vector(mode = "list", length = length(variable_ranges))
  names(binned_ranges_list) <- names(variable_ranges)
  
  temp <- vector(mode = "list", length = nbins)
  
  
  for (i in 1:length(variable_ranges)) {

      bin_width <- (variable_ranges[[i]][2] - variable_ranges[[i]][1])/nbins
      
      breaks_vec <- seq(variable_ranges[[i]][1], variable_ranges[[i]][2], by = bin_width)
      
      for (j in 1:nbins) {
        
        temp[[j]][1] <- breaks_vec[j]
        temp[[j]][2] <- breaks_vec[j+1]
        
      }
      
      binned_ranges_list[[i]] <- temp
      
  }
  
  print(binned_ranges_list)
    
  #sample ranges
  for (i in 1:length(variable_ranges)) {
    
    sampled_values_vec <- c()
      
      for (j in 1:nbins) {
        
        sample <- runif(n = table[j], min = binned_ranges_list[[i]][[j]][1], max = binned_ranges_list[[i]][[j]][2])
        
        sampled_values_vec <- c(sampled_values_vec, sample)
        
      }
    
    df[,i] <- sampled_values_vec
    }
   return(df) 
  }
  

#Tests
variable_ranges = list(A = c(1, 100), B = c(50, 100), C = c(1, 10))

a <- generate_correlated_variables(variable_ranges = variable_ranges, numPoints = 100, nbins = 2)
cor(a)

b <- generate_correlated_variables(variable_ranges = variable_ranges, numPoints = 100, nbins = 50)
cor(b)

這是如何獲得相關統一隨機數的想法。

假設您有獨立位的來源

  1. 首先生成數組 X 位(比如 2 位)。

  2. 然后生成另一個隨機數組,其中的上(中、下、某個位置...)位從步驟 1 中替換。

  3. 再次生成另一個隨機數組,其中的上(中、下、某個位置...)位從步驟 1 中替換。

來自第 2 步和第 3 步的數組將是統一的,但相互關聯。

說明代碼(對不起,Python)

import numpy as np

N=1000000

rng = np.random.default_rng()

m = np.empty(N, dtype=np.uint32); m.fill(2*1073741824-1) # mask 2^31-1

f = rng.integers(low = 0, high=4294967295, size=N, dtype=np.uint32, endpoint=True)
f = f - np.bitwise_and(f, m) # upper three bits

q = rng.integers(low = 0, high=4294967295, size=N, dtype=np.uint32, endpoint=True)
z = rng.integers(low = 0, high=4294967295, size=N, dtype=np.uint32, endpoint=True)

print("Uncorrelated")
print(np.corrcoef([q, z]))

q = f + np.bitwise_and(m, q)
z = f + np.bitwise_and(m, z)

print("Correlated")
print(np.corrcoef([q, z]))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM