[英]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)
這是如何獲得相關統一隨機數的想法。
假設您有獨立位的來源
首先生成數組 X 位(比如 2 位)。
然后生成另一個隨機數組,其中的上(中、下、某個位置...)位從步驟 1 中替換。
再次生成另一個隨機數組,其中的上(中、下、某個位置...)位從步驟 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.