用于相关研究的高效数字生成器
efficient number generator for correlation studies
我的目标是在对应于大于 0.95 的 Pearson correlation coefficient 的最小和最大范围内生成 7 个数字。我已经成功地使用了 3 个数字(显然是因为这对计算要求不是很高)。但是对于 4 个数字,所需的计算量似乎非常大(即大约 10k 次迭代)。使用当前代码几乎不可能有 7 个数字。
当前代码:
def pearson_def(x, y):
assert len(x) == len(y)
n = len(x)
assert n > 0
avg_x = average(x)
avg_y = average(y)
diffprod = 0
xdiff2 = 0
ydiff2 = 0
for idx in range(n):
xdiff = x[idx] - avg_x
ydiff = y[idx] - avg_y
diffprod += xdiff * ydiff
xdiff2 += xdiff * xdiff
ydiff2 += ydiff * ydiff
return diffprod / math.sqrt(xdiff2 * ydiff2)
c1_high = 98
c1_low = 75
def corr_gen():
container =[]
x=0
while True:
c1 = c1_low
c2 = np.random.uniform(c1_low, c1_high)
c3 = c1_high
container.append(c1)
container.append(c2)
container.append(c3)
y = np.arange(len(container))
if pearson_def(container,y) >0.95:
c4 = np.random.uniform(c1_low, c1_high)
container.append(c4)
y = np.arange(len(container))
if pearson_def(container,y) >0.95:
return container
else:
continue
else:
x+=1
print(x)
continue
corrcheck = corr_gen()
print(corrcheck)
最终 objective:
*要有 4 列 linear distribution(点间距均匀)
*每一行对应一组项目(C1,C2,C3,C4),它们的总和必须等于100。
C1 C2 C3 C4 sum range
1 70 10 5 1 100 ^
2 .. |
3 .. |
4 .. |
5 .. |
6 .. |
7 90 20 15 3 _
两个理论成分的示例分布:
您可以按如下方式使用np.random.multivariate_normal
:
import numpy as np
_corr = 0.95
n = 2
size = 7
corr = np.full((n, n), _corr)
np.fill_diagonal(corr, 1.) # inplace op
# Change as you see fit; you can scale distr. later too
mu, sigma = 0., 1.
mu = np.repeat(mu, n)
sigma = np.repeat(sigma, n)
def corr2cov(corr, s):
d = np.diag(s)
return d.dot(corr).dot(d)
cov = corr2cov(corr, sigma)
# While we specified parameters, our draws are still psuedorandom.
# Loop till we meet the specified threshold for correl.
res = 0.
while res < _corr:
dist = np.random.multivariate_normal(mean=mu, cov=cov, size=size)
res = np.corrcoef(dist[:, 0], dist[:, 1])[0, 1]
您感兴趣的结果是 dist
,在本例中返回的是一个二维数组,每个数组有 2 个特征和 7 个样本。
演练:
- 创建一个具有指定相关性的相关矩阵。
- 指定平均值和标准偏差,在本例中为 ~N(0, 1),如果需要,您可以稍后缩放。
- 使用标准差将相关性转换为协方差。 (在这种特殊情况下它们是相同的)。
- 从多元正态分布中抽取随机样本。
我的目标是在对应于大于 0.95 的 Pearson correlation coefficient 的最小和最大范围内生成 7 个数字。我已经成功地使用了 3 个数字(显然是因为这对计算要求不是很高)。但是对于 4 个数字,所需的计算量似乎非常大(即大约 10k 次迭代)。使用当前代码几乎不可能有 7 个数字。
当前代码:
def pearson_def(x, y):
assert len(x) == len(y)
n = len(x)
assert n > 0
avg_x = average(x)
avg_y = average(y)
diffprod = 0
xdiff2 = 0
ydiff2 = 0
for idx in range(n):
xdiff = x[idx] - avg_x
ydiff = y[idx] - avg_y
diffprod += xdiff * ydiff
xdiff2 += xdiff * xdiff
ydiff2 += ydiff * ydiff
return diffprod / math.sqrt(xdiff2 * ydiff2)
c1_high = 98
c1_low = 75
def corr_gen():
container =[]
x=0
while True:
c1 = c1_low
c2 = np.random.uniform(c1_low, c1_high)
c3 = c1_high
container.append(c1)
container.append(c2)
container.append(c3)
y = np.arange(len(container))
if pearson_def(container,y) >0.95:
c4 = np.random.uniform(c1_low, c1_high)
container.append(c4)
y = np.arange(len(container))
if pearson_def(container,y) >0.95:
return container
else:
continue
else:
x+=1
print(x)
continue
corrcheck = corr_gen()
print(corrcheck)
最终 objective:
*要有 4 列 linear distribution(点间距均匀)
*每一行对应一组项目(C1,C2,C3,C4),它们的总和必须等于100。
C1 C2 C3 C4 sum range
1 70 10 5 1 100 ^
2 .. |
3 .. |
4 .. |
5 .. |
6 .. |
7 90 20 15 3 _
两个理论成分的示例分布:
您可以按如下方式使用np.random.multivariate_normal
:
import numpy as np
_corr = 0.95
n = 2
size = 7
corr = np.full((n, n), _corr)
np.fill_diagonal(corr, 1.) # inplace op
# Change as you see fit; you can scale distr. later too
mu, sigma = 0., 1.
mu = np.repeat(mu, n)
sigma = np.repeat(sigma, n)
def corr2cov(corr, s):
d = np.diag(s)
return d.dot(corr).dot(d)
cov = corr2cov(corr, sigma)
# While we specified parameters, our draws are still psuedorandom.
# Loop till we meet the specified threshold for correl.
res = 0.
while res < _corr:
dist = np.random.multivariate_normal(mean=mu, cov=cov, size=size)
res = np.corrcoef(dist[:, 0], dist[:, 1])[0, 1]
您感兴趣的结果是 dist
,在本例中返回的是一个二维数组,每个数组有 2 个特征和 7 个样本。
演练:
- 创建一个具有指定相关性的相关矩阵。
- 指定平均值和标准偏差,在本例中为 ~N(0, 1),如果需要,您可以稍后缩放。
- 使用标准差将相关性转换为协方差。 (在这种特殊情况下它们是相同的)。
- 从多元正态分布中抽取随机样本。