我有一个非常具体的问题要解决,这使得研究解决方案非常困难,因为我缺乏必要的数学技能。
我的目标:给定一个协方差/相关矩阵和变量范围,生成一些随机数据。此数据需要满足3个重要条件:
-
该数据的协方差/相关性应与提供的协方差/相关矩阵相似。
-
此数据(列)的变量范围应以所提供的范围为界。
-
各变量分布均匀。
是否可能有一个R包或函数可以使用这些提供的参数生成这些数据条件?也许用别的语言写代码,然后我可以用R重写?
EDIT1:
在一致性(条件3)不能满足的情况下,是否有一个R包或函数可以生成满足条件1和条件2的数据?换句话说,我不关心变量的分布
EDIT2:
这是我对这个问题的第一次非常糟糕的尝试。到目前为止,它所做的只是创建正相关和统一的数据。测试在底部:
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]))