【问题标题】:efficient number generator for correlation studies用于相关研究的高效数字生成器
【发布时间】:2017-12-07 16:25:08
【问题描述】:

我的目标是在最小和最大范围内生成 7 个数字,它们对应于大于 0.95 的 Pearson correlation coefficient。我已经成功使用了 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)

最终目标:

*有 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           _

两个理论组件的示例传播:

【问题讨论】:

  • 我真的很想看到pearson_def。相关性是在两个系列之间计算的,但其中一个似乎是数字 0, 1, 2, ...
  • 相关性涉及两组数字。怎样才能得到一组具有一定最小相关性的七个数字?
  • 优化代码的第一件事是避免从对象调用方法。因此,例如将您的容器添加到变量append = container.append 中。在 while 循环中,您不必从现在开始调用整个引用,这样更快 |编辑:同样适用于您的统一或范围声明
  • 编程中的第一件事就是避免早期优化。首先确保您正在计算您打算计算的内容。
  • 您可以使用pearson_def,而不是scipy.stats.pearsonr

标签: python loops numpy pearson-correlation


【解决方案1】:

你可以使用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),如果需要,您可以稍后对其进行缩放。
  • 使用标准差将相关性转换为协方差。 (在这种特殊情况下它们是相同的)。
  • 从多元正态分布中抽取随机样本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2023-03-11
    • 2018-04-29
    相关资源
    最近更新 更多