Выборка из двумерного нормального в питоне
Я пытаюсь создать две случайные переменные, которые связаны друг с другом, и я считаю, что лучший способ - извлечь из двумерного нормального распределения с заданными параметрами (открытыми для других идей). Некоррелированная версия выглядит так:
import numpy as np
sigma = np.random.uniform(.2, .3, 80)
theta = np.random.uniform( 0, .5, 80)
Однако для каждого из 80 дро я хочу, чтобы значение сигмы было связано с тета-значением. Какие-нибудь мысли?
3 ответа
Используйте встроенный: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.multivariate_normal.html
>>> import numpy as np
>>> mymeans = [13,5]
>>> # stdevs = sqrt(5),sqrt(2)
>>> # corr = .3 / (sqrt(5)*sqrt(2) = .134
>>> mycov = [[5,.3], [.3,2]]
>>> np.cov(np.random.multivariate_normal(mymeans,mycov,500000).T)
array([[ 4.99449936, 0.30506976],
[ 0.30506976, 2.00213264]])
>>> np.corrcoef(np.random.multivariate_normal(mymeans,mycov,500000).T)
array([[ 1. , 0.09629313],
[ 0.09629313, 1. ]])
- Как показано, все становится немного сложнее, если вам приходится приспосабливаться к отклонениям, не связанным с единицей)
- дополнительная ссылка: http://www.riskglossary.com/link/correlation.htm
- Чтобы иметь смысл в реальном мире, ковариационная матрица должна быть симметричной и также должна быть положительно определенной или положительной полуопределенной (она должна быть обратимой). Конкретные антикорреляционные структуры могут быть невозможны.
import multivariate_normal
от scipy
может быть использован. Предположим, мы создаем случайные величины x
а также y
:
from scipy.stats import multivariate_normal
rv_mean = [0, 1] # mean of x and y
rv_cov = [[1.0,0.5], [0.5,2.0]] # covariance matrix of x and y
rv = multivariate_normal.rvs(rv_mean, rv_cov, size=10000)
У тебя есть x
от rv[:,0]
а также y
от rv[:,1]
, Коэффициенты корреляции могут быть получены из
import numpy as np
np.corrcoef(rv.T)
Два нормальных распределения определяются средним значением и дисперсией:
means = [0, 0] # respective means
var_xx = 1 ** 2 # var x = std x squared
var_yy = 1 ** 2
Ковариация между двумя распределениями определяется ковариационной матрицей, состоящей из дисперсий и двух ковариаций. Две ковариации x/y и y/x равны:
import numpy as np
cov_xy = 0.5
cov = np.array([[var_xx, cov_xy],
[cov_xy, var_yy]])
N пар выбираются из распределений с помощью генератора случайных чисел и функцииmultivariate_normal
. Необязательныйcheck_valid='raise'
используется для проверки того, что ковариационная матрица действительно симметрична и положительно полуопределена :
g = np.random.default_rng()
N = 100
pairs = g.multivariate_normal(means, cov, size=N, check_valid='raise')
В качестве примера построим график этих пар:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter(pairs[:,0], pairs[:,1])