Как генерировать коррелированные случайные числа в Python?

#python #numpy #random #statistics #correlation

Вопрос:

Как создать набор из n векторов размерности d, чтобы элементы имели корреляцию c (т. Е., Если вектор содержит один большой элемент, другие элементы, вероятно, будут большими)?

Для демонстрации предположим, что n=5, d=3 и c=0,7.

Есть ли какой-нибудь способ настроить conv здесь: https://numpy.org/doc/stable/reference/random/generated/numpy.random.multivariate_normal.html

Возможно, я прошу слишком многого, но что, если я хочу, чтобы числа были взяты из нормального распределения?

Спасибо!

Редактировать: В основном я пытаюсь создать синтетическую популяцию, особи которой отличаются некоторой скрытой переменной, и в идеале эта скрытая переменная будет соответствовать нормальному распределению. Например, психометрический g-фактор суммирует результаты нескольких тестов и объясняет определенное количество различий между людьми в данном тесте. Поэтому я хотел бы создать n векторов (размер популяции) размерности d (количество задач), но, может быть, c должен быть вектором чисел d? И мне, возможно, потребуется указать вектор чисел d для оценок скрытых переменных (например, g), или, может быть, это следует из того, как создаются векторы для отдельных людей?

Комментарии:

1. Из вашей формулировки неясно, ищете ли вы корреляцию между векторами или последовательную корреляцию с каждым вектором. Вы говорите: «если вектор содержит один большой элемент, другие элементы, скорее всего, будут большими», что звучит так, как будто вы говорите о последовательной корреляции, но последовательная корреляция обычно определяется как функция запаздывания (расстояния между элементами), и вы даете только одно значение корреляции.

2. См. также: stats.stackexchange.com/questions/15011/…

Ответ №1:

Может быть, это то, что вы ищете?

 import numpy as np


def gen_random(n: int, d: int, covar: float) -> np.ndarray:
    """
    Paramters
    ---------
    n : int
        number of samples generated
    d : int
        dimensionality of samples
    covar : float
        uniform covariance for samples
    
    Returns
    -------
    samples : np.ndarray
        samples in as (n, d)-matrix
    """
    cov_mat = np.ones((d, d)) * covar; np.fill_diagonal(cov_mat, 1)
    offset = np.zeros(d)

    return np.random.multivariate_normal(offset, cov_mat, size=n)


v = gen_random(n=10_000, d=3, covar=0.7)
print(v)
# [[ 0.03031736  0.18227023 -0.1302022 ]
#  [-0.17770689  0.70979971 -0.74631702]
#  [-0.78485455 -0.73942846 -0.04819704]
#  ...
#  [ 2.5928135   2.43727782  1.59459156]
#  [ 0.33443158 -0.74126937 -0.7542286 ]
#  [ 0.11238505 -0.1940429   0.7397402 ]]

# sanity check
print(np.corrcoef(v, rowvar=False))
# [[1.         0.6985444  0.69802535]
#  [0.6985444  1.         0.70168241]
#  [0.69802535 0.70168241 1.        ]]